diff --git a/app/build.gradle b/app/build.gradle index a6c8a954..831cfba8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,7 +14,7 @@ android { minSdkVersion 16 targetSdkVersion 29 versionCode 26 - versionName "3.2" + versionName "3.2-beta" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true vectorDrawables.useSupportLibrary = true @@ -25,7 +25,7 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } buildTypes.each { - it.buildConfigField('boolean', 'PRERELEASE', 'false') + it.buildConfigField('boolean', 'PRERELEASE', 'true') } } kotlinOptions { @@ -50,12 +50,13 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.preference:preference:1.1.0-rc01' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'androidx.gridlayout:gridlayout:1.0.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'com.android.support:multidex:1.0.3' - implementation 'com.google.android.material:material:1.0.0' - implementation 'com.google.firebase:firebase-core:17.0.0' + implementation 'com.google.android.material:material:1.1.0-alpha08' + implementation 'com.google.firebase:firebase-core:17.0.1' implementation 'com.google.firebase:firebase-perf:18.0.1' implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1' implementation 'com.github.arimorty:floatingsearchview:2.1.1' diff --git a/app/src/main/java/xyz/quaver/pupil/Pupil.kt b/app/src/main/java/xyz/quaver/pupil/Pupil.kt index bb72e44f..b9363bef 100644 --- a/app/src/main/java/xyz/quaver/pupil/Pupil.kt +++ b/app/src/main/java/xyz/quaver/pupil/Pupil.kt @@ -18,13 +18,10 @@ package xyz.quaver.pupil -import android.app.DownloadManager import android.app.Notification import android.app.NotificationChannel import android.app.NotificationManager -import android.content.BroadcastReceiver import android.content.Context -import android.content.Intent import android.os.Build import androidx.appcompat.app.AppCompatDelegate import androidx.core.content.ContextCompat @@ -76,6 +73,11 @@ class Pupil : MultiDexApplication() { preference.edit().putBoolean("channel_created", true).apply() } + AppCompatDelegate.setDefaultNightMode(when (preference.getBoolean("dark_mode", false)) { + true -> AppCompatDelegate.MODE_NIGHT_YES + false -> AppCompatDelegate.MODE_NIGHT_NO + }) + super.onCreate() } diff --git a/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt b/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt index 7f515740..7fe8ef68 100644 --- a/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt +++ b/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt @@ -18,20 +18,17 @@ package xyz.quaver.pupil.adapters -import android.app.AlertDialog import android.graphics.drawable.Drawable import android.util.SparseBooleanArray import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.ArrayAdapter import android.widget.LinearLayout import androidx.cardview.widget.CardView import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import androidx.vectordrawable.graphics.drawable.Animatable2Compat import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat -import com.bumptech.glide.Glide import com.bumptech.glide.RequestManager import com.bumptech.glide.load.engine.DiskCacheStrategy import com.google.android.material.chip.Chip @@ -49,6 +46,7 @@ import xyz.quaver.pupil.R import xyz.quaver.pupil.types.Tag import xyz.quaver.pupil.util.Histories import xyz.quaver.pupil.util.getCachedGallery +import xyz.quaver.pupil.util.wordCapitalize import java.io.File import java.util.* import kotlin.collections.ArrayList @@ -168,19 +166,6 @@ class GalleryBlockAdapter(private val glide: RequestManager, private val galleri artists.isNotEmpty() -> View.VISIBLE else -> View.GONE } - setOnClickListener { - if (artists.size > 1) { - AlertDialog.Builder(context).apply { - setAdapter(ArrayAdapter(context, android.R.layout.select_dialog_item, artists)) { _, index -> - for (callback in onChipClickedHandler) - callback.invoke(Tag("artist", artists[index])) - } - }.show() - } else { - for(callback in onChipClickedHandler) - callback.invoke(Tag("artist", artists.first())) - } - } } with(galleryblock_series) { text = @@ -191,31 +176,8 @@ class GalleryBlockAdapter(private val glide: RequestManager, private val galleri series.isNotEmpty() -> View.VISIBLE else -> View.GONE } - setOnClickListener { - setOnClickListener { - if (series.size > 1) { - AlertDialog.Builder(context).apply { - setAdapter(ArrayAdapter(context, android.R.layout.select_dialog_item, series)) { _, index -> - for (callback in onChipClickedHandler) - callback.invoke(Tag("series", series[index])) - } - }.show() - } else { - for(callback in onChipClickedHandler) - callback.invoke(Tag("series", series.first())) - } - } - } - } - with(galleryblock_type) { - text = resources.getString(R.string.galleryblock_type, galleryBlock.type).wordCapitalize() - setOnClickListener { - setOnClickListener { - for(callback in onChipClickedHandler) - callback.invoke(Tag("type", galleryBlock.type)) - } - } } + galleryblock_type.text = resources.getString(R.string.galleryblock_type, galleryBlock.type).wordCapitalize() with(galleryblock_language) { text = resources.getString(R.string.galleryblock_language, languages[galleryBlock.language]) @@ -223,48 +185,37 @@ class GalleryBlockAdapter(private val glide: RequestManager, private val galleri galleryBlock.language.isNotEmpty() -> View.VISIBLE else -> View.GONE } - setOnClickListener { - setOnClickListener { - for(callback in onChipClickedHandler) - callback.invoke(Tag("language", galleryBlock.language)) - } - } } galleryblock_tag_group.removeAllViews() galleryBlock.relatedTags.forEach { - val tag = Tag.parse(it).let { tag -> - when { - tag.area != null -> tag - else -> Tag("tag", it) + galleryblock_tag_group.addView(Chip(context).apply { + val tag = Tag.parse(it).let { tag -> + when { + tag.area != null -> tag + else -> Tag("tag", it) + } } - } - val chip = LayoutInflater.from(context) - .inflate(R.layout.tag_chip, this, false) as Chip - - val icon = when(tag.area) { - "male" -> { - chip.setChipBackgroundColorResource(R.color.material_blue_700) - chip.setTextColor(ContextCompat.getColor(context, android.R.color.white)) - ContextCompat.getDrawable(context, R.drawable.ic_gender_male_white) + chipIcon = when(tag.area) { + "male" -> { + setChipBackgroundColorResource(R.color.material_blue_700) + setTextColor(ContextCompat.getColor(context, android.R.color.white)) + ContextCompat.getDrawable(context, R.drawable.ic_gender_male_white) + } + "female" -> { + setChipBackgroundColorResource(R.color.material_pink_600) + setTextColor(ContextCompat.getColor(context, android.R.color.white)) + ContextCompat.getDrawable(context, R.drawable.ic_gender_female_white) + } + else -> null } - "female" -> { - chip.setChipBackgroundColorResource(R.color.material_pink_600) - chip.setTextColor(ContextCompat.getColor(context, android.R.color.white)) - ContextCompat.getDrawable(context, R.drawable.ic_gender_female_white) + text = tag.tag.wordCapitalize() + setOnClickListener { + for (callback in onChipClickedHandler) + callback.invoke(tag) } - else -> null - } - - chip.chipIcon = icon - chip.text = tag.tag.wordCapitalize() - chip.setOnClickListener { - for (callback in onChipClickedHandler) - callback.invoke(tag) - } - - galleryblock_tag_group.addView(chip) + }) } galleryblock_id.text = galleryBlock.id.toString() @@ -316,15 +267,6 @@ class GalleryBlockAdapter(private val glide: RequestManager, private val galleri } } - private fun String.wordCapitalize() : String { - val result = ArrayList() - - for (word in this.split(" ")) - result.add(word.capitalize()) - - return result.joinToString(" ") - } - private val refreshTasks = HashMap() val completeFlag = SparseBooleanArray() diff --git a/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt b/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt index f0e789c9..c19ee6cc 100644 --- a/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt +++ b/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt @@ -18,7 +18,6 @@ package xyz.quaver.pupil.adapters -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -26,7 +25,6 @@ import android.widget.ImageView import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.RequestManager import com.bumptech.glide.load.engine.DiskCacheStrategy -import com.bumptech.glide.request.target.Target import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/xyz/quaver/pupil/adapters/ThumbnailAdapter.kt b/app/src/main/java/xyz/quaver/pupil/adapters/ThumbnailAdapter.kt new file mode 100644 index 00000000..1793af1c --- /dev/null +++ b/app/src/main/java/xyz/quaver/pupil/adapters/ThumbnailAdapter.kt @@ -0,0 +1,42 @@ +/* + * Pupil, Hitomi.la viewer for Android + * Copyright (C) 2019 tom5079 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package xyz.quaver.pupil.adapters + +import android.view.ViewGroup +import android.widget.ImageView +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.RequestManager + +class ThumbnailAdapter(private val glide: RequestManager, private val thumbnails: List) : RecyclerView.Adapter() { + + class ViewHolder(val view: ImageView) : RecyclerView.ViewHolder(view) + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder(ImageView(parent.context)) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + glide + .load(thumbnails[position]) + .into(holder.view) + } + + override fun getItemCount() = thumbnails.size + +} \ No newline at end of file diff --git a/app/src/main/java/xyz/quaver/pupil/ui/GalleryDialog.kt b/app/src/main/java/xyz/quaver/pupil/ui/GalleryDialog.kt index 5628379c..37d6ff9e 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/GalleryDialog.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/GalleryDialog.kt @@ -20,21 +20,51 @@ package xyz.quaver.pupil.ui import android.app.Dialog import android.content.Context +import android.content.Intent import android.os.Bundle +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.widget.ImageView import android.widget.LinearLayout +import android.widget.LinearLayout.LayoutParams import androidx.core.content.ContextCompat +import androidx.gridlayout.widget.GridLayout +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide -import com.bumptech.glide.request.target.Target +import com.bumptech.glide.RequestManager +import com.google.android.material.chip.Chip import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.dialog_galleryblock.* -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch +import kotlinx.android.synthetic.main.gallery_details.view.* +import kotlinx.android.synthetic.main.item_gallery_details.view.* +import kotlinx.coroutines.* +import xyz.quaver.hitomi.Gallery +import xyz.quaver.hitomi.GalleryBlock import xyz.quaver.hitomi.getGallery +import xyz.quaver.hitomi.getGalleryBlock +import xyz.quaver.pupil.Pupil import xyz.quaver.pupil.R +import xyz.quaver.pupil.adapters.GalleryBlockAdapter +import xyz.quaver.pupil.adapters.ThumbnailAdapter +import xyz.quaver.pupil.types.Tag +import xyz.quaver.pupil.util.ItemClickSupport +import xyz.quaver.pupil.util.wordCapitalize class GalleryDialog(context: Context, private val galleryID: Int) : Dialog(context) { + private val languages = context.resources.getStringArray(R.array.languages).map { + it.split("|").let { split -> + Pair(split[0], split[1]) + } + }.toMap() + + private val glide = Glide.with(context) + + val onChipClickedHandler = ArrayList<((Tag) -> (Unit))>() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.dialog_galleryblock) @@ -42,22 +72,53 @@ class GalleryDialog(context: Context, private val galleryID: Int) : Dialog(conte window?.attributes.apply { this ?: return@apply - width = LinearLayout.LayoutParams.MATCH_PARENT - height = LinearLayout.LayoutParams.MATCH_PARENT + width = LayoutParams.MATCH_PARENT + height = LayoutParams.MATCH_PARENT } - gallery_fab.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.arrow_right)) + with(gallery_fab) { + setImageDrawable(ContextCompat.getDrawable(context, R.drawable.arrow_right)) + setOnClickListener { + context.startActivity(Intent(context, ReaderActivity::class.java).apply { + putExtra("galleryID", galleryID) + }) + (context.applicationContext as Pupil).histories.add(galleryID) + } + } CoroutineScope(Dispatchers.IO).launch { try { val gallery = getGallery(galleryID) launch(Dispatchers.Main) { - gallery_toolbar.title = gallery.title + gallery_progressbar.visibility = View.GONE + gallery_title.text = gallery.title + gallery_artist.text = gallery.artists.joinToString(", ") { it.wordCapitalize() } + + with(gallery_type) { + text = gallery.type.wordCapitalize() + setOnClickListener { + gallery.type.let { + when (it) { + "artist CG" -> "artistcg" + "game CG" -> "gamecg" + else -> it + } + }.let { + onChipClickedHandler.forEach { handler -> + handler.invoke(Tag("type", it)) + } + } + } + } Glide.with(context) - .load(gallery.thumbnails[0]) + .load(gallery.thumbnails.firstOrNull()) .into(gallery_thumbnail) + + addDetails(gallery) + addThumbnails(gallery) + addRelated(gallery) } } catch (e: Exception) { Snackbar.make(gallery_layout, R.string.unable_to_connect, Snackbar.LENGTH_INDEFINITE).show() @@ -65,4 +126,151 @@ class GalleryDialog(context: Context, private val galleryID: Int) : Dialog(conte } } + private fun addDetails(gallery: Gallery) { + val inflater = LayoutInflater.from(context) + + inflater.inflate(R.layout.gallery_details, gallery_contents, false).apply { + gallery_details.setText(R.string.gallery_details) + + listOf( + R.string.gallery_artists, + R.string.gallery_groups, + R.string.gallery_language, + R.string.gallery_series, + R.string.gallery_characters, + R.string.gallery_tags + ).zip( + listOf( + gallery.artists.map { Tag("artist", it) }, + gallery.groups.map { Tag("group", it) }, + listOf(gallery.language).map { Tag("language", it) }, + gallery.series.map { Tag("series", it) }, + gallery.characters.map { Tag("character", it) }, + gallery.tags.map { + Tag.parse(it).let { tag -> + when { + tag.area != null -> tag + else -> Tag("tag", it) + } + } + } + ) + ).filter { + (_, content) -> content.isNotEmpty() + }.forEach { (title, content) -> + inflater.inflate(R.layout.item_gallery_details, gallery_details_contents, false).apply { + gallery_details_type.setText(title) + + content.forEach { tag -> + gallery_details_tags.addView( + Chip(context).apply { + chipIcon = when(tag.area) { + "male" -> { + setChipBackgroundColorResource(R.color.material_blue_700) + setTextColor(ContextCompat.getColor(context, android.R.color.white)) + ContextCompat.getDrawable(context, R.drawable.ic_gender_male_white) + } + "female" -> { + setChipBackgroundColorResource(R.color.material_pink_600) + setTextColor(ContextCompat.getColor(context, android.R.color.white)) + ContextCompat.getDrawable(context, R.drawable.ic_gender_female_white) + } + else -> null + } + + text = when (tag.area) { + "language" -> languages[tag.tag] + else -> tag.tag.wordCapitalize() + } + + setOnClickListener { + onChipClickedHandler.forEach { handler -> + handler.invoke(tag) + } + } + } + ) + } + }.let { + gallery_details_contents.addView(it) + } + } + }.let { + gallery_contents.addView(it) + } + } + + private fun addThumbnails(gallery: Gallery) { + val inflater = LayoutInflater.from(context) + + inflater.inflate(R.layout.gallery_details, gallery_contents, false).apply { + gallery_details.setText(R.string.gallery_thumbnails) + + RecyclerView(context).apply { + layoutManager = GridLayoutManager(context, 3) + adapter = ThumbnailAdapter(glide, gallery.thumbnails) + }.let { + gallery_details_contents.addView(it, LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)) + } + }.let { + gallery_contents.addView(it) + } + } + + private fun addRelated(gallery: Gallery) { + val inflater = LayoutInflater.from(context) + val galleries = ArrayList>>() + + val adapter = GalleryBlockAdapter(glide, galleries).apply { + onChipClickedHandler.add { tag -> + this@GalleryDialog.onChipClickedHandler.forEach { handler -> + handler.invoke(tag) + } + } + } + + CoroutineScope(Dispatchers.Main).launch { + gallery.related.forEachIndexed { i, galleryID -> + async(Dispatchers.IO) { + getGalleryBlock(galleryID) + }.let { + val galleryBlock = it.await() ?: return@let + + galleries.add(Pair(galleryBlock, GlobalScope.async { galleryBlock.thumbnails.first() })) + adapter.notifyItemInserted(i) + } + } + } + + inflater.inflate(R.layout.gallery_details, gallery_contents, false).apply { + gallery_details.setText(R.string.gallery_related) + + RecyclerView(context).apply { + layoutManager = LinearLayoutManager(context) + this.adapter = adapter + + ItemClickSupport.addTo(this) + .setOnItemClickListener { _, position, _ -> + context.startActivity(Intent(context, ReaderActivity::class.java).apply { + putExtra("galleryID", galleries[position].first.id) + }) + (context.applicationContext as Pupil).histories.add(galleries[position].first.id) + } + .setOnItemLongClickListener { _, position, _ -> + GalleryDialog(context, galleries[position].first.id).apply { + onChipClickedHandler.add { tag -> + this@GalleryDialog.onChipClickedHandler.forEach { it.invoke(tag) } + } + }.show() + + true + } + }.let { + gallery_details_contents.addView(it, LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)) + } + }.let { + gallery_contents.addView(it) + } + } + } \ No newline at end of file diff --git a/app/src/main/java/xyz/quaver/pupil/ui/LockActivity.kt b/app/src/main/java/xyz/quaver/pupil/ui/LockActivity.kt index e457a90f..804d9d6a 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/LockActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/LockActivity.kt @@ -58,7 +58,7 @@ class LockActivity : AppCompatActivity() { when(mode) { null -> { - if (lockManager.empty()) { + if (lockManager.isEmpty()) { setResult(RESULT_OK) finish() return diff --git a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt index 5b12a123..7ded50c8 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt @@ -127,7 +127,21 @@ class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - startActivityForResult(Intent(this, LockActivity::class.java), REQUEST_LOCK) + val lockManager = try { + LockManager(this) + } catch (e: Exception) { + android.app.AlertDialog.Builder(this).apply { + setTitle(R.string.warning) + setMessage(R.string.lock_corrupted) + setPositiveButton(android.R.string.ok) { _, _ -> + finish() + } + }.show() + return + } + + if (lockManager.isNotEmpty()) + startActivityForResult(Intent(this, LockActivity::class.java), REQUEST_LOCK) checkPermissions() @@ -524,7 +538,6 @@ class MainActivity : AppCompatActivity() { } ItemClickSupport.addTo(this) .setOnItemClickListener { _, position, v -> - if (v !is CardView) return@setOnItemClickListener @@ -543,8 +556,20 @@ class MainActivity : AppCompatActivity() { val galleryID = galleries[position].first.id - GalleryDialog(this@MainActivity, galleryID) - .show() + GalleryDialog(this@MainActivity, galleryID).apply { + onChipClickedHandler.add { + runOnUiThread { + query = it.toQuery() + currentPage = 0 + + cancelFetch() + clearGalleries() + fetchGalleries(query, sortMode) + loadBlocks() + } + dismiss() + } + }.show() true } diff --git a/app/src/main/java/xyz/quaver/pupil/ui/SettingsActivity.kt b/app/src/main/java/xyz/quaver/pupil/ui/SettingsActivity.kt index 0d0bc35c..0e28613b 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/SettingsActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/SettingsActivity.kt @@ -31,6 +31,7 @@ import android.widget.LinearLayout import android.widget.TextView import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.app.AppCompatDelegate import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceManager @@ -338,6 +339,19 @@ class SettingsActivity : AppCompatActivity() { true } } + + with(findPreference("dark_mode")) { + this!! + + onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> + AppCompatDelegate.setDefaultNightMode(when (newValue as Boolean) { + true -> AppCompatDelegate.MODE_NIGHT_YES + false -> AppCompatDelegate.MODE_NIGHT_NO + }) + + true + } + } } } diff --git a/app/src/main/java/xyz/quaver/pupil/util/lock.kt b/app/src/main/java/xyz/quaver/pupil/util/lock.kt index 15970b02..cba085c4 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/lock.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/lock.kt @@ -112,10 +112,12 @@ class LockManager(base: Context): ContextWrapper(base) { } } - fun empty(): Boolean { + fun isEmpty(): Boolean { return locks.isNullOrEmpty() } + fun isNotEmpty(): Boolean = !isEmpty() + fun contains(type: Lock.Type): Boolean { return locks?.any { it.type == type } ?: false } diff --git a/app/src/main/java/xyz/quaver/pupil/util/misc.kt b/app/src/main/java/xyz/quaver/pupil/util/misc.kt index 1c7dba9a..a8b1dbad 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/misc.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/misc.kt @@ -23,4 +23,13 @@ import android.content.pm.PackageManager import androidx.core.content.ContextCompat fun Context.hasPermission(permission: String) = - ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED \ No newline at end of file + ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED + +fun String.wordCapitalize() : String { + val result = ArrayList() + + for (word in this.split(" ")) + result.add(word.capitalize()) + + return result.joinToString(" ") +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main_content.xml b/app/src/main/res/layout/activity_main_content.xml index 8124f89b..3041a890 100644 --- a/app/src/main/res/layout/activity_main_content.xml +++ b/app/src/main/res/layout/activity_main_content.xml @@ -104,6 +104,7 @@ android:id="@+id/main_searchview" android:layout_width="match_parent" android:layout_height="match_parent" + app:floatingSearch_backgroundColor="?attr/colorSurface" app:floatingSearch_searchBarMarginLeft="8dp" app:floatingSearch_searchBarMarginRight="8dp" app:floatingSearch_searchBarMarginTop="8dp" diff --git a/app/src/main/res/layout/dialog_galleryblock.xml b/app/src/main/res/layout/dialog_galleryblock.xml index 95df1038..a7925e0b 100644 --- a/app/src/main/res/layout/dialog_galleryblock.xml +++ b/app/src/main/res/layout/dialog_galleryblock.xml @@ -17,35 +17,99 @@ ~ along with this program. If not, see . --> - - + android:layout_height="wrap_content"> + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - \ No newline at end of file + + + \ No newline at end of file diff --git a/app/src/main/res/layout/gallery_details.xml b/app/src/main/res/layout/gallery_details.xml new file mode 100644 index 00000000..3e7d4d21 --- /dev/null +++ b/app/src/main/res/layout/gallery_details.xml @@ -0,0 +1,40 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_gallery_details.xml b/app/src/main/res/layout/item_gallery_details.xml new file mode 100644 index 00000000..94223858 --- /dev/null +++ b/app/src/main/res/layout/item_gallery_details.xml @@ -0,0 +1,40 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/tag_chip.xml b/app/src/main/res/layout/item_gallery_thumbnails.xml similarity index 71% rename from app/src/main/res/layout/tag_chip.xml rename to app/src/main/res/layout/item_gallery_thumbnails.xml index 5442f0a0..2c97c88d 100644 --- a/app/src/main/res/layout/tag_chip.xml +++ b/app/src/main/res/layout/item_gallery_thumbnails.xml @@ -17,11 +17,7 @@ ~ along with this program. If not, see . --> - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/item_galleryblock.xml b/app/src/main/res/layout/item_galleryblock.xml index 4a78dcd7..5a7f0094 100644 --- a/app/src/main/res/layout/item_galleryblock.xml +++ b/app/src/main/res/layout/item_galleryblock.xml @@ -87,8 +87,6 @@ android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" - android:clickable="true" - android:focusable="true" app:layout_constraintLeft_toRightOf="@id/galleryblock_thumbnail" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/galleryblock_title"/> @@ -99,8 +97,6 @@ android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" - android:clickable="true" - android:focusable="true" app:layout_constraintTop_toBottomOf="@id/galleryblock_artist" app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail" app:layout_constraintEnd_toEndOf="parent"/> @@ -111,8 +107,6 @@ android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" - android:clickable="true" - android:focusable="true" app:layout_constraintTop_toBottomOf="@id/galleryblock_series" app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail" /> @@ -123,8 +117,6 @@ android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginBottom="8dp" - android:clickable="true" - android:focusable="true" app:layout_constraintTop_toBottomOf="@id/galleryblock_type" app:layout_constraintBottom_toTopOf="@id/galleryblock_padding" app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail" /> @@ -145,6 +137,7 @@ android:layout_marginStart="8dp" android:layout_marginTop="16dp" android:layout_marginBottom="16dp" + app:chipSpacing="2dp" app:layout_constraintTop_toBottomOf="@id/galleryblock_padding" app:layout_constraintLeft_toRightOf="@id/galleryblock_thumbnail" app:layout_constraintRight_toRightOf="parent" diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 3ea5fcfb..33c08d47 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -88,4 +88,15 @@ 無視 ロックファイルが破損されています。Pupilを再再インストールしてください。 権限がないため自動アップデートを行えません。ホームページで直接ダウンロードしてください。 + ダークモード + 夜にシコりたい方々へ + ギャラリー情報 + アーティスト + キャラクター + グループ + 言語 + シリーズ + タグ + サムネイル + おすすめ \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 46c179e4..0ed5b83f 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -88,4 +88,15 @@ 무시 잠금 파일이 손상되었습니다! 앱을 재설치 해 주시기 바랍니다. 권한이 부여되어 있지 않아 자동 업데이트를 진행할 수 없습니다. 홈페이지에서 직접 다운로드 받으시기 바랍니다. + 다크 모드 + 딥 다크한 모오드 + 갤러리 정보 + 작가 + 캐릭터 + 그룹 + 언어 + 시리즈 + 태그 + 관련 갤러리 + 미리보기 \ No newline at end of file diff --git a/app/src/main/res/values/dimen.xml b/app/src/main/res/values/dimen.xml index 69fd045d..25399db6 100644 --- a/app/src/main/res/values/dimen.xml +++ b/app/src/main/res/values/dimen.xml @@ -8,4 +8,6 @@ 16dp 8dp 176dp + + 8dp \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7a33ae67..4e397835 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -78,6 +78,16 @@ Search galleries Search galleries + Details + Thumbnails + Related Galleries + Artists + Groups + Language + Series + Characters + Tags + Series: %1$s Type: %1$s Language: %1$s @@ -112,6 +122,8 @@ Load images from hiyobi.me to improve loading speed (if available) Enable security mode Enable security mode to make the screen invisible on recent app window + Dark mode + Protect yourself against light attacks! None Pattern diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 448d30a8..07d47381 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,14 +1,14 @@ - -