From f326c6990206c2bca1ae18b116e60b4f5c693a98 Mon Sep 17 00:00:00 2001 From: tom5079 Date: Sun, 19 May 2019 16:40:28 +0900 Subject: [PATCH 1/3] Added download list Added history search --- app/build.gradle | 5 +- .../java/xyz/quaver/pupil/MainActivity.kt | 221 +++++++++++------- app/src/main/java/xyz/quaver/pupil/Pupil.kt | 12 +- .../java/xyz/quaver/pupil/ReaderActivity.kt | 20 +- .../java/xyz/quaver/pupil/SettingsActivity.kt | 3 +- .../pupil/adapters/GalleryBlockAdapter.kt | 2 - .../quaver/pupil/adapters/ReaderAdapter.kt | 4 +- .../quaver/pupil/util/GalleryDownloader.kt | 12 +- .../java/xyz/quaver/pupil/util/history.kt | 4 - .../main/java/xyz/quaver/pupil/util/update.kt | 1 - .../main/res/menu/activity_main_drawer.xml | 4 + app/src/main/res/values-ja/strings.xml | 1 + app/src/main/res/values-ko/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + build.gradle | 1 + 15 files changed, 173 insertions(+), 119 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 3fef32d8..d34d7924 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "xyz.quaver.pupil" minSdkVersion 16 targetSdkVersion 28 - versionCode 5 - versionName "1.4" + versionCode 7 + versionName "2.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -38,6 +38,7 @@ dependencies { implementation 'androidx.preference:preference:1.1.0-alpha05' implementation 'com.google.android.material:material:1.0.0' implementation 'com.github.arimorty:floatingsearchview:2.1.1' + implementation 'com.github.deano2390:MaterialShowcaseView:1.3.4' implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation "ru.noties.markwon:core:${markwonVersion}" diff --git a/app/src/main/java/xyz/quaver/pupil/MainActivity.kt b/app/src/main/java/xyz/quaver/pupil/MainActivity.kt index a355b261..94470e8f 100644 --- a/app/src/main/java/xyz/quaver/pupil/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/MainActivity.kt @@ -42,19 +42,33 @@ import kotlin.collections.ArrayList class MainActivity : AppCompatActivity() { + enum class Mode { + SEARCH, + HISTORY, + DOWNLOAD + } + private val galleries = ArrayList>>() private var query = "" + private var mode = Mode.SEARCH private val SETTINGS = 45162 private var galleryIDs: Deferred>? = null private var loadingJob: Job? = null + private lateinit var histories: Histories + private lateinit var downloads: Histories + override fun onCreate(savedInstanceState: Bundle?) { - Histories.default = Histories(File(cacheDir, "histories.json")) super.onCreate(savedInstanceState) + with(application as Pupil) { + this@MainActivity.histories = histories + this@MainActivity.downloads = downloads + } + window.setFlags( WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS @@ -64,82 +78,13 @@ class MainActivity : AppCompatActivity() { checkUpdate() - main_appbar_layout.addOnOffsetChangedListener( - AppBarLayout.OnOffsetChangedListener { _, p1 -> - main_searchview.translationY = p1.toFloat() - main_recyclerview.translationY = p1.toFloat() - } - ) - - with(main_swipe_layout) { - setProgressViewOffset( - false, - resources.getDimensionPixelSize(R.dimen.progress_view_start), - resources.getDimensionPixelSize(R.dimen.progress_view_offset) - ) - - setOnRefreshListener { - CoroutineScope(Dispatchers.Main).launch { - cancelFetch() - clearGalleries() - fetchGalleries(query) - loadBlocks() - } - } - } - - main_nav_view.setNavigationItemSelectedListener { - CoroutineScope(Dispatchers.Main).launch { - main_drawer_layout.closeDrawers() - - when(it.itemId) { - R.id.main_drawer_home -> { - cancelFetch() - clearGalleries() - query = query.replace("HISTORY", "") - fetchGalleries(query) - } - R.id.main_drawer_history -> { - cancelFetch() - clearGalleries() - query += "HISTORY" - fetchGalleries(query) - } - R.id.main_drawer_help -> { - AlertDialog.Builder(this@MainActivity).apply { - title = getString(R.string.help_dialog_title) - setMessage(R.string.help_dialog_message) - - setPositiveButton(android.R.string.ok) { _, _ -> } - }.show() - } - R.id.main_drawer_github -> { - startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.github)))) - } - R.id.main_drawer_homepage -> { - startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.home_page)))) - } - R.id.main_drawer_email -> { - startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.email)))) - } - } - loadBlocks() - } - - true - } - - setupSearchBar() - setupRecyclerView() - fetchGalleries(query) - loadBlocks() + initView() } override fun onBackPressed() { - if (main_drawer_layout.isDrawerOpen(GravityCompat.START)) - main_drawer_layout.closeDrawer(GravityCompat.START) - else if (query.isNotEmpty()) { - runOnUiThread { + when { + main_drawer_layout.isDrawerOpen(GravityCompat.START) -> main_drawer_layout.closeDrawer(GravityCompat.START) + query.isNotEmpty() -> runOnUiThread { query = "" findViewById(R.id.search_bar_text).setText(query, TextView.BufferType.EDITABLE) @@ -148,9 +93,8 @@ class MainActivity : AppCompatActivity() { fetchGalleries(query) loadBlocks() } + else -> super.onBackPressed() } - else - super.onBackPressed() } override fun onResume() { @@ -243,6 +187,91 @@ class MainActivity : AppCompatActivity() { } } + private fun initView() { + main_appbar_layout.addOnOffsetChangedListener( + AppBarLayout.OnOffsetChangedListener { _, p1 -> + main_searchview.translationY = p1.toFloat() + main_recyclerview.translationY = p1.toFloat() + } + ) + + //SwipeRefreshLayout + with(main_swipe_layout) { + setProgressViewOffset( + false, + resources.getDimensionPixelSize(R.dimen.progress_view_start), + resources.getDimensionPixelSize(R.dimen.progress_view_offset) + ) + + setOnRefreshListener { + post { + cancelFetch() + clearGalleries() + fetchGalleries(query) + loadBlocks() + } + } + } + + //NavigationView + main_nav_view.setNavigationItemSelectedListener { + runOnUiThread { + main_drawer_layout.closeDrawers() + + when(it.itemId) { + R.id.main_drawer_home -> { + cancelFetch() + clearGalleries() + query = "" + mode = Mode.SEARCH + fetchGalleries(query) + loadBlocks() + } + R.id.main_drawer_history -> { + cancelFetch() + clearGalleries() + query = "" + mode = Mode.HISTORY + fetchGalleries(query) + loadBlocks() + } + R.id.main_drawer_downloads -> { + cancelFetch() + clearGalleries() + query = "" + mode = Mode.DOWNLOAD + fetchGalleries(query) + loadBlocks() + } + R.id.main_drawer_help -> { + AlertDialog.Builder(this@MainActivity).apply { + title = getString(R.string.help_dialog_title) + setMessage(R.string.help_dialog_message) + + setPositiveButton(android.R.string.ok) { _, _ -> } + }.show() + } + R.id.main_drawer_github -> { + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.github)))) + } + R.id.main_drawer_homepage -> { + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.home_page)))) + } + R.id.main_drawer_email -> { + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.email)))) + } + } + } + + true + } + + setupSearchBar() + setupRecyclerView() + fetchGalleries(query) + loadBlocks() + } + private fun setupRecyclerView() { with(main_recyclerview) { adapter = GalleryBlockAdapter(galleries).apply { @@ -281,8 +310,8 @@ class MainActivity : AppCompatActivity() { //TODO: Maybe sprinke some transitions will be nice :D startActivity(intent) - Histories.default.add(gallery.id) - }.setOnItemLongClickListener { recyclerView, position, v -> + histories.add(gallery.id) + }.setOnItemLongClickListener { recyclerView, position, _ -> val galleryBlock = galleries[position].first val view = LayoutInflater.from(this@MainActivity) .inflate(R.layout.dialog_galleryblock, recyclerView, false) @@ -301,7 +330,7 @@ class MainActivity : AppCompatActivity() { val downloader = GalleryDownloader.get(galleryBlock.id) if (downloader == null) { GalleryDownloader(context, galleryBlock, true).start() - Histories.default.add(galleryBlock.id) + downloads.add(galleryBlock.id) } else { downloader.cancel() downloader.clearNotification() @@ -489,13 +518,33 @@ class MainActivity : AppCompatActivity() { return galleryIDs = CoroutineScope(Dispatchers.IO).async { - when { - query.contains("HISTORY") -> - Histories.default.toList() - query.isEmpty() and defaultQuery.isEmpty() -> - fetchNozomi(start = from, count = perPage) - else -> - doSearch("$defaultQuery $query") + when(mode) { + Mode.SEARCH -> { + when { + query.isEmpty() and defaultQuery.isEmpty() -> + fetchNozomi(start = from, count = perPage) + else -> + doSearch("$defaultQuery $query") + } + } + Mode.HISTORY -> { + when { + query.isEmpty() -> histories.toList() + else -> { + val result = doSearch(query).sorted() + histories.filter { result.binarySearch(it) >= 0 } + } + } + } + Mode.DOWNLOAD -> { + when { + query.isEmpty() -> downloads.toList() + else -> { + val result = doSearch(query).sorted() + downloads.filter { result.binarySearch(it) >= 0 } + } + } + } } } } diff --git a/app/src/main/java/xyz/quaver/pupil/Pupil.kt b/app/src/main/java/xyz/quaver/pupil/Pupil.kt index 8e1184dd..c4115c85 100644 --- a/app/src/main/java/xyz/quaver/pupil/Pupil.kt +++ b/app/src/main/java/xyz/quaver/pupil/Pupil.kt @@ -6,17 +6,23 @@ import android.app.NotificationManager import android.content.Context import android.os.Build import android.preference.PreferenceManager -import android.util.SparseArray +import androidx.core.content.ContextCompat import com.finotes.android.finotescore.Fn import com.finotes.android.finotescore.ObservableApplication -import com.finotes.android.finotescore.Severity -import kotlinx.coroutines.Job +import xyz.quaver.pupil.util.Histories +import java.io.File class Pupil : ObservableApplication() { + lateinit var histories: Histories + lateinit var downloads: Histories + override fun onCreate() { val preference = PreferenceManager.getDefaultSharedPreferences(this) + histories = Histories(File(ContextCompat.getDataDir(this), "histories.json")) + downloads = Histories(File(ContextCompat.getDataDir(this), "downloads.json")) + super.onCreate() Fn.init(this) diff --git a/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt b/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt index b2022c2b..542921f5 100644 --- a/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt @@ -2,7 +2,6 @@ package xyz.quaver.pupil import android.graphics.drawable.Drawable import android.os.Bundle -import android.util.Log import android.view.* import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity @@ -63,7 +62,7 @@ class ReaderActivity : AppCompatActivity() { initView() - if (!downloader.notify) + if (!downloader.download) downloader.start() } @@ -113,7 +112,7 @@ class ReaderActivity : AppCompatActivity() { override fun onDestroy() { super.onDestroy() - if (!downloader.notify) + if (!downloader.download) downloader.cancel() } @@ -159,18 +158,19 @@ class ReaderActivity : AppCompatActivity() { } } onDownloadedHandler = { + val item = it.toList() CoroutineScope(Dispatchers.Main).launch { if (images.isEmpty()) { - images.addAll(it) + images.addAll(item) reader_recyclerview.adapter?.notifyDataSetChanged() } else { - images.add(it.last()) + images.add(item.last()) reader_recyclerview.adapter?.notifyItemInserted(images.size-1) } } } onErrorHandler = { - downloader.notify = false + downloader.download = false } onCompleteHandler = { CoroutineScope(Dispatchers.Main).launch { @@ -184,7 +184,7 @@ class ReaderActivity : AppCompatActivity() { val icon = AnimatedVectorDrawableCompat.create(this, R.drawable.ic_downloading) icon?.registerAnimationCallback(object: Animatable2Compat.AnimationCallback() { override fun onAnimationEnd(drawable: Drawable?) { - if (downloader.notify) + if (downloader.download) fab.post { icon.start() fab.labelText = getString(R.string.reader_fab_download_cancel) @@ -205,7 +205,7 @@ class ReaderActivity : AppCompatActivity() { } } - if (downloader.notify) { + if (downloader.download) { downloader.invokeOnReaderLoaded() downloader.invokeOnNotifyChanged() } @@ -255,9 +255,9 @@ class ReaderActivity : AppCompatActivity() { } reader_fab_download.setOnClickListener { - downloader.notify = !downloader.notify + downloader.download = !downloader.download - if (!downloader.notify) + if (!downloader.download) downloader.clearNotification() } } diff --git a/app/src/main/java/xyz/quaver/pupil/SettingsActivity.kt b/app/src/main/java/xyz/quaver/pupil/SettingsActivity.kt index 9a3c92b0..7f941162 100644 --- a/app/src/main/java/xyz/quaver/pupil/SettingsActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/SettingsActivity.kt @@ -16,7 +16,6 @@ import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import kotlinx.android.synthetic.main.dialog_default_query.view.* import xyz.quaver.pupil.types.Tags -import xyz.quaver.pupil.util.Histories import java.io.File class SettingsActivity : AppCompatActivity() { @@ -99,7 +98,7 @@ class SettingsActivity : AppCompatActivity() { with(findPreference("clear_history")) { this ?: return@with - val histories = Histories.default + val histories = (activity!!.application as Pupil).histories summary = getString(R.string.settings_clear_history_summary, histories.size) 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 08f73716..06ccd862 100644 --- a/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt +++ b/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt @@ -1,8 +1,6 @@ package xyz.quaver.pupil.adapters import android.graphics.BitmapFactory -import android.graphics.PorterDuff -import android.util.Log import android.util.SparseArray import android.util.SparseBooleanArray import android.view.LayoutInflater 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 ea653cf4..a579865e 100644 --- a/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt +++ b/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt @@ -38,9 +38,7 @@ class ReaderAdapter(private val images: List) : RecyclerView.Adapter() { } } - companion object { - lateinit var default: Histories - } - @UseExperimental(ImplicitReflectionSerializer::class) fun load() : Histories { return apply { diff --git a/app/src/main/java/xyz/quaver/pupil/util/update.kt b/app/src/main/java/xyz/quaver/pupil/util/update.kt index 198c82a2..2c951cbe 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/update.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/update.kt @@ -1,6 +1,5 @@ package xyz.quaver.pupil.util -import kotlinx.io.IOException import kotlinx.serialization.json.* import java.net.URL diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml index 83737a33..4185cf90 100644 --- a/app/src/main/res/menu/activity_main_drawer.xml +++ b/app/src/main/res/menu/activity_main_drawer.xml @@ -10,6 +10,10 @@ + + diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 6e723198..a625b88c 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -52,4 +52,5 @@ ダウンロードエラー バックグラウンドダウンロード中止 このギャラリーを削除 + ダウンロード \ 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 ed305722..b46801e1 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -52,4 +52,5 @@ 다운로드 오류 백그라운드 다운로드 취소 갤러리 삭제 + 다운로드 \ 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 37174abc..8b5eb247 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -30,6 +30,7 @@ Home History + Downloads Contact Help Visit homepage diff --git a/build.gradle b/build.gradle index 2853a5c4..46c39173 100644 --- a/build.gradle +++ b/build.gradle @@ -20,6 +20,7 @@ allprojects { repositories { google() jcenter() + maven { url "https://jitpack.io" } maven { url "s3://finotescore-android/release" credentials(AwsCredentials) { From 530da98ec6bdf8bd44caefbaee9d0a5430a8380c Mon Sep 17 00:00:00 2001 From: tom5079 Date: Sat, 1 Jun 2019 21:42:14 +0900 Subject: [PATCH 2/3] Bug fix Add paging --- .idea/misc.xml | 2 +- app/build.gradle | 4 +- .../java/xyz/quaver/pupil/MainActivity.kt | 404 +++++++++++++++--- .../java/xyz/quaver/pupil/ReaderActivity.kt | 18 +- .../pupil/adapters/GalleryBlockAdapter.kt | 159 +++---- .../quaver/pupil/util/GalleryDownloader.kt | 21 +- app/src/main/res/drawable/ic_jump.xml | 14 + .../ic_navigate_before_black_24dp.xml | 9 + .../drawable/ic_navigate_next_black_24dp.xml | 9 + .../main/res/layout/activity_main_content.xml | 25 +- app/src/main/res/layout/activity_reader.xml | 3 +- .../main/res/layout/dialog_numberpicker.xml | 10 +- app/src/main/res/layout/item_next.xml | 35 ++ app/src/main/res/layout/item_prev.xml | 35 ++ app/src/main/res/menu/main.xml | 7 +- app/src/main/res/menu/reader.xml | 2 +- app/src/main/res/values-ja/strings.xml | 8 +- app/src/main/res/values-ko/strings.xml | 8 +- app/src/main/res/values-v23/styles.xml | 12 - app/src/main/res/values/strings.xml | 13 +- .../java/xyz/quaver/hitomi/galleryblock.kt | 11 +- 21 files changed, 605 insertions(+), 204 deletions(-) create mode 100644 app/src/main/res/drawable/ic_jump.xml create mode 100644 app/src/main/res/drawable/ic_navigate_before_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_navigate_next_black_24dp.xml create mode 100644 app/src/main/res/layout/item_next.xml create mode 100644 app/src/main/res/layout/item_prev.xml delete mode 100644 app/src/main/res/values-v23/styles.xml diff --git a/.idea/misc.xml b/.idea/misc.xml index 7631aec3..fb8c126a 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index d34d7924..76304c9d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "xyz.quaver.pupil" minSdkVersion 16 targetSdkVersion 28 - versionCode 7 - versionName "2.1" + versionCode 8 + versionName "2.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { diff --git a/app/src/main/java/xyz/quaver/pupil/MainActivity.kt b/app/src/main/java/xyz/quaver/pupil/MainActivity.kt index 94470e8f..bbe0c7d3 100644 --- a/app/src/main/java/xyz/quaver/pupil/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/MainActivity.kt @@ -6,16 +6,17 @@ import android.os.Bundle import android.preference.PreferenceManager import android.text.* import android.text.style.AlignmentSpan -import android.view.LayoutInflater -import android.view.View -import android.view.WindowManager +import android.util.Log +import android.view.* +import android.widget.EditText +import android.widget.ImageView +import android.widget.LinearLayout import android.widget.TextView import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity +import androidx.cardview.widget.CardView import androidx.core.content.res.ResourcesCompat import androidx.core.view.GravityCompat -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView import com.arlib.floatingsearchview.FloatingSearchView import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion import com.arlib.floatingsearchview.util.view.SearchInputView @@ -39,6 +40,7 @@ import java.net.URL import java.util.* import javax.net.ssl.HttpsURLConnection import kotlin.collections.ArrayList +import kotlin.math.roundToInt class MainActivity : AppCompatActivity() { @@ -56,7 +58,9 @@ class MainActivity : AppCompatActivity() { private val SETTINGS = 45162 private var galleryIDs: Deferred>? = null + private var totalItems = 0 private var loadingJob: Job? = null + private var currentPage = 0 private lateinit var histories: Histories private lateinit var downloads: Histories @@ -64,16 +68,25 @@ class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + val preference = PreferenceManager.getDefaultSharedPreferences(this) + + if (Locale.getDefault().language == "ko") { + if (!preference.getBoolean("https_block_alert", false)) { + android.app.AlertDialog.Builder(this).apply { + setTitle(R.string.https_block_alert_title) + setMessage(R.string.https_block_alert) + setPositiveButton(android.R.string.ok) { _, _ -> } + }.show() + + preference.edit().putBoolean("https_block_alert", true).apply() + } + } + with(application as Pupil) { this@MainActivity.histories = histories this@MainActivity.downloads = downloads } - window.setFlags( - WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, - WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS - ) - setContentView(R.layout.activity_main) checkUpdate() @@ -109,6 +122,44 @@ class MainActivity : AppCompatActivity() { super.onResume() } + override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { + val preference = PreferenceManager.getDefaultSharedPreferences(this) + val perPage = preference.getString("per_page", "25")!!.toInt() + val maxPage = Math.ceil(totalItems / perPage.toDouble()).roundToInt() + + return when(keyCode) { + KeyEvent.KEYCODE_VOLUME_DOWN -> { + if (currentPage < maxPage) { + runOnUiThread { + currentPage++ + + cancelFetch() + clearGalleries() + fetchGalleries(query) + loadBlocks() + } + } + + true + } + KeyEvent.KEYCODE_VOLUME_UP -> { + if (currentPage > 0) { + runOnUiThread { + currentPage-- + + cancelFetch() + clearGalleries() + fetchGalleries(query) + loadBlocks() + } + } + + true + } + else -> super.onKeyDown(keyCode, event) + } + } + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when(requestCode) { @@ -188,31 +239,16 @@ class MainActivity : AppCompatActivity() { } private fun initView() { + var prevP1 = 0 main_appbar_layout.addOnOffsetChangedListener( AppBarLayout.OnOffsetChangedListener { _, p1 -> main_searchview.translationY = p1.toFloat() - main_recyclerview.translationY = p1.toFloat() + main_recyclerview.scrollBy(0, prevP1 - p1) + + prevP1 = p1 } ) - //SwipeRefreshLayout - with(main_swipe_layout) { - setProgressViewOffset( - false, - resources.getDimensionPixelSize(R.dimen.progress_view_start), - resources.getDimensionPixelSize(R.dimen.progress_view_offset) - ) - - setOnRefreshListener { - post { - cancelFetch() - clearGalleries() - fetchGalleries(query) - loadBlocks() - } - } - } - //NavigationView main_nav_view.setNavigationItemSelectedListener { runOnUiThread { @@ -276,7 +312,7 @@ class MainActivity : AppCompatActivity() { with(main_recyclerview) { adapter = GalleryBlockAdapter(galleries).apply { onChipClickedHandler.add { - post { + runOnUiThread { query = it.toQuery() this@MainActivity.findViewById(R.id.search_bar_text) .setText(query, TextView.BufferType.EDITABLE) @@ -288,21 +324,12 @@ class MainActivity : AppCompatActivity() { } } } - addOnScrollListener( - object: RecyclerView.OnScrollListener() { - override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { - super.onScrolled(recyclerView, dx, dy) - - val layoutManager = recyclerView.layoutManager as LinearLayoutManager - - if (loadingJob?.isActive != true) - if (layoutManager.findLastCompletelyVisibleItemPosition() == galleries.size) - loadBlocks() - } - } - ) ItemClickSupport.addTo(this) - .setOnItemClickListener { _, position, _ -> + .setOnItemClickListener { _, position, v -> + + if (v !is CardView) + return@setOnItemClickListener + val intent = Intent(this@MainActivity, ReaderActivity::class.java) val gallery = galleries[position].first intent.putExtra("galleryblock", Json(JsonConfiguration.Stable).stringify(GalleryBlock.serializer(), gallery)) @@ -311,7 +338,11 @@ class MainActivity : AppCompatActivity() { startActivity(intent) histories.add(gallery.id) - }.setOnItemLongClickListener { recyclerView, position, _ -> + }.setOnItemLongClickListener { recyclerView, position, v -> + + if (v !is CardView) + return@setOnItemLongClickListener true + val galleryBlock = galleries[position].first val view = LayoutInflater.from(this@MainActivity) .inflate(R.layout.dialog_galleryblock, recyclerView, false) @@ -358,6 +389,210 @@ class MainActivity : AppCompatActivity() { true } + + var origin = 0f + var target = -1 + val preferences = PreferenceManager.getDefaultSharedPreferences(context) + val perPage = preferences.getString("per_page", "25")!!.toInt() + setOnTouchListener { _, event -> + when(event.action) { + MotionEvent.ACTION_UP -> { + origin = 0f + + with(main_recyclerview.adapter as GalleryBlockAdapter) { + if(showPrev) { + showPrev = false + + val prev = main_recyclerview.layoutManager?.getChildAt(0) + + if (prev is LinearLayout) { + val icon = prev.findViewById(R.id.icon_prev) + prev.layoutParams.height = 1 + icon.layoutParams.height = 1 + icon.rotation = 180f + } + + prev?.requestLayout() + + notifyItemRemoved(0) + } + + if(showNext) { + showNext = false + + val next = main_recyclerview.layoutManager?.let { + getChildAt(childCount-1) + } + + if (next is LinearLayout) { + val icon = next.findViewById(R.id.icon_next) + next.layoutParams.height = 1 + icon.layoutParams.height = 1 + icon.rotation = 0f + } + + next?.requestLayout() + + notifyItemRemoved(itemCount) + } + } + + if (target != -1) { + currentPage = target + + runOnUiThread { + cancelFetch() + clearGalleries() + fetchGalleries(query) + loadBlocks() + } + + target = -1 + } + } + MotionEvent.ACTION_DOWN -> origin = event.y + MotionEvent.ACTION_MOVE -> { + if (origin == 0f) + origin = event.y + + val dist = event.y - origin + + when { + !canScrollVertically(-1) -> { + //TOP + + //Scrolling UP + if (dist > 0 && currentPage != 0) { + with(main_recyclerview.adapter as GalleryBlockAdapter) { + if(!showPrev) { + showPrev = true + notifyItemInserted(0) + } + } + + val prev = main_recyclerview.layoutManager?.getChildAt(0) + + if (prev is LinearLayout) { + val icon = prev.findViewById(R.id.icon_prev) + val text = prev.findViewById(R.id.text_prev).apply { + text = getString(R.string.main_move, currentPage) + } + if (dist < 360) { + prev.layoutParams.height = (dist/2).roundToInt() + icon.layoutParams.height = (dist/2).roundToInt() + icon.rotation = dist+180 + text.layoutParams.width = dist.roundToInt() + + target = -1 + } + else { + prev.layoutParams.height = 180 + icon.layoutParams.height = 180 + icon.rotation = 180f + text.layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT + + target = currentPage-1 + } + } + + prev?.requestLayout() + + return@setOnTouchListener true + } else { + with(main_recyclerview.adapter as GalleryBlockAdapter) { + if(showPrev) { + showPrev = false + + val prev = main_recyclerview.layoutManager?.getChildAt(0) + + if (prev is LinearLayout) { + val icon = prev.findViewById(R.id.icon_prev) + prev.layoutParams.height = 1 + icon.layoutParams.height = 1 + icon.rotation = 180f + } + + prev?.requestLayout() + + notifyItemRemoved(0) + } + } + } + } + !canScrollVertically(1) -> { + //BOTTOM + + //Scrolling DOWN + if (dist < 0 && currentPage != Math.ceil(totalItems.toDouble()/perPage).roundToInt()-1) { + with(main_recyclerview.adapter as GalleryBlockAdapter) { + if(!showNext) { + showNext = true + notifyItemInserted(itemCount-1) + } + } + + val next = main_recyclerview.layoutManager?.let { + getChildAt(childCount-1) + } + + val absDist = Math.abs(dist) + + if (next is LinearLayout) { + val icon = next.findViewById(R.id.icon_next) + val text = next.findViewById(R.id.text_next).apply { + text = getString(R.string.main_move, currentPage+2) + } + if (absDist < 360) { + next.layoutParams.height = (absDist/2).roundToInt() + icon.layoutParams.height = (absDist/2).roundToInt() + icon.rotation = -absDist + text.layoutParams.width = absDist.roundToInt() + + target = -1 + } + else { + next.layoutParams.height = 180 + icon.layoutParams.height = 180 + icon.rotation = 0f + text.layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT + + target = currentPage+1 + } + } + + next?.requestLayout() + + return@setOnTouchListener true + } else { + with(main_recyclerview.adapter as GalleryBlockAdapter) { + if(showNext) { + showNext = false + + val next = main_recyclerview.layoutManager?.let { + getChildAt(childCount-1) + } + + if (next is LinearLayout) { + Log.d("Pupil", "hmm...") + val icon = next.findViewById(R.id.icon_next) + next.layoutParams.height = 1 + icon.layoutParams.height = 1 + icon.rotation = 180f + } + + next?.requestLayout() + + notifyItemRemoved(itemCount) + } + } + } + } + } + } + } + + false + } } } @@ -386,7 +621,33 @@ class MainActivity : AppCompatActivity() { setOnMenuItemClickListener { when(it.itemId) { R.id.main_menu_settings -> startActivityForResult(Intent(this@MainActivity, SettingsActivity::class.java), SETTINGS) - R.id.main_menu_search -> setSearchFocused(true) + R.id.main_menu_page_indicator -> { + val preference = PreferenceManager.getDefaultSharedPreferences(context) + val perPage = preference.getString("per_page", "25")!!.toInt() + val editText = EditText(context) + + AlertDialog.Builder(context).apply { + title = getString(R.string.reader_go_to_page) + setView(editText) + setTitle(R.string.main_jump_title) + setMessage(getString( + R.string.main_jump_message, + currentPage+1, + Math.ceil(totalItems / perPage.toDouble()).roundToInt() + )) + + setPositiveButton(android.R.string.ok) { _, _ -> + currentPage = (editText.text.toString().toIntOrNull() ?: return@setPositiveButton)-1 + + runOnUiThread { + cancelFetch() + clearGalleries() + fetchGalleries(query) + loadBlocks() + } + } + }.show() + } } } @@ -471,7 +732,7 @@ class MainActivity : AppCompatActivity() { if (query != this@MainActivity.query) { this@MainActivity.query = query - CoroutineScope(Dispatchers.Main).launch { + runOnUiThread { cancelFetch() clearGalleries() fetchGalleries(query) @@ -502,12 +763,12 @@ class MainActivity : AppCompatActivity() { this.notifyDataSetChanged() } + main_appbar_layout.setExpanded(true) main_noresult.visibility = View.INVISIBLE main_progressbar.show() - main_swipe_layout.isRefreshing = false } - private fun fetchGalleries(query: String, from: Int = 0) { + private fun fetchGalleries(query: String) { val preference = PreferenceManager.getDefaultSharedPreferences(this) val perPage = preference.getString("per_page", "25")?.toInt() ?: 25 val defaultQuery = preference.getString("default_query", "")!! @@ -521,27 +782,42 @@ class MainActivity : AppCompatActivity() { when(mode) { Mode.SEARCH -> { when { - query.isEmpty() and defaultQuery.isEmpty() -> - fetchNozomi(start = from, count = perPage) - else -> - doSearch("$defaultQuery $query") + query.isEmpty() and defaultQuery.isEmpty() -> { + fetchNozomi(start = currentPage*perPage, count = perPage).let { + totalItems = it.second + it.first + } + } + else -> doSearch("$defaultQuery $query").apply { + totalItems = size + } } } Mode.HISTORY -> { when { - query.isEmpty() -> histories.toList() + query.isEmpty() -> { + histories.toList().apply { + totalItems = size + } + } else -> { val result = doSearch(query).sorted() - histories.filter { result.binarySearch(it) >= 0 } + histories.filter { result.binarySearch(it) >= 0 }.apply { + totalItems = size + } } } } Mode.DOWNLOAD -> { when { - query.isEmpty() -> downloads.toList() + query.isEmpty() -> downloads.toList().apply { + totalItems = size + } else -> { val result = doSearch(query).sorted() - downloads.filter { result.binarySearch(it) >= 0 } + downloads.filter { result.binarySearch(it) >= 0 }.apply { + totalItems = size + } } } } @@ -566,18 +842,11 @@ class MainActivity : AppCompatActivity() { return@launch } - if (query.isEmpty() and defaultQuery.isEmpty()) - fetchGalleries("", galleries.size+perPage) - else - with(main_recyclerview.adapter as GalleryBlockAdapter) { - noMore = galleries.size + perPage >= galleryIDs.size - } - when { - query.isEmpty() and defaultQuery.isEmpty() -> + query.isEmpty() and defaultQuery.isEmpty() and (mode == Mode.SEARCH) -> galleryIDs else -> - galleryIDs.slice(galleries.size until Math.min(galleries.size+perPage, galleryIDs.size)) + galleryIDs.slice(currentPage*perPage until Math.min(currentPage*perPage+perPage, galleryIDs.size)) }.chunked(5).let { chunks -> for (chunk in chunks) chunk.map { @@ -635,8 +904,7 @@ class MainActivity : AppCompatActivity() { if (galleryBlock != null) { galleries.add(galleryBlock) - - main_recyclerview.adapter?.notifyItemInserted(galleries.size - 1) + main_recyclerview.adapter!!.notifyItemInserted(galleries.size - 1) } } } diff --git a/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt b/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt index 542921f5..a6cd8cc3 100644 --- a/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt @@ -12,12 +12,14 @@ import androidx.recyclerview.widget.PagerSnapHelper import androidx.recyclerview.widget.RecyclerView import androidx.vectordrawable.graphics.drawable.Animatable2Compat import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat +import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.activity_reader.* import kotlinx.android.synthetic.main.activity_reader.view.* import kotlinx.android.synthetic.main.dialog_numberpicker.view.* import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.io.IOException import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonConfiguration import xyz.quaver.hitomi.GalleryBlock @@ -89,7 +91,7 @@ class ReaderActivity : AppCompatActivity() { when(item?.itemId) { R.id.reader_menu_page_indicator -> { val view = LayoutInflater.from(this).inflate(R.layout.dialog_numberpicker, findViewById(android.R.id.content), false) - with(view.reader_dialog_number_picker) { + with(view.dialog_number_picker) { minValue=1 maxValue=gallerySize value=currentPage @@ -97,8 +99,8 @@ class ReaderActivity : AppCompatActivity() { val dialog = AlertDialog.Builder(this).apply { setView(view) }.create() - view.reader_dialog_ok.setOnClickListener { - (reader_recyclerview.layoutManager as LinearLayoutManager?)?.scrollToPositionWithOffset(view.reader_dialog_number_picker.value-1, 0) + view.dialog_ok.setOnClickListener { + (reader_recyclerview.layoutManager as LinearLayoutManager?)?.scrollToPositionWithOffset(view.dialog_number_picker.value-1, 0) dialog.dismiss() } @@ -135,7 +137,13 @@ class ReaderActivity : AppCompatActivity() { var d: GalleryDownloader? = GalleryDownloader.get(galleryBlock.id) if (d == null) { - d = GalleryDownloader(this, galleryBlock) + try { + d = GalleryDownloader(this, galleryBlock) + } catch (e: IOException) { + Snackbar.make(reader_layout, R.string.unable_to_connect, Snackbar.LENGTH_LONG).show() + finish() + return + } } downloader = d.apply { @@ -170,6 +178,8 @@ class ReaderActivity : AppCompatActivity() { } } onErrorHandler = { + if (it is IOException) + Snackbar.make(reader_layout, R.string.unable_to_connect, Snackbar.LENGTH_LONG).show() downloader.download = false } onCompleteHandler = { 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 06ccd862..c75529b7 100644 --- a/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt +++ b/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt @@ -1,12 +1,13 @@ package xyz.quaver.pupil.adapters import android.graphics.BitmapFactory -import android.util.SparseArray +import android.util.Log import android.util.SparseBooleanArray import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.LinearLayout +import android.widget.RelativeLayout import androidx.cardview.widget.CardView import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView @@ -27,66 +28,28 @@ import xyz.quaver.pupil.types.Tag import java.io.File import java.util.* import kotlin.collections.ArrayList +import kotlin.collections.HashMap import kotlin.concurrent.schedule class GalleryBlockAdapter(private val galleries: List>>) : RecyclerView.Adapter() { - private enum class ViewType { - VIEW_ITEM, - VIEW_PROG + enum class ViewType { + NEXT, + GALLERY, + PREV } - private fun String.wordCapitalize() : String { - val result = ArrayList() - - for (word in this.split(" ")) - result.add(word.capitalize()) - - return result.joinToString(" ") - } - - var noMore = false - private val refreshTasks = SparseArray() - val completeFlag = SparseBooleanArray() - - val onChipClickedHandler = ArrayList<((Tag) -> Unit)>() - - class ViewHolder(val view: CardView, var galleryID: Int? = null) : RecyclerView.ViewHolder(view) - class ProgressViewHolder(val view: LinearLayout) : RecyclerView.ViewHolder(view) - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - when(viewType) { - ViewType.VIEW_ITEM.ordinal -> { - val view = LayoutInflater.from(parent.context).inflate( - R.layout.item_galleryblock, parent, false - ) as CardView - - return ViewHolder(view) - } - ViewType.VIEW_PROG.ordinal -> { - val view = LayoutInflater.from(parent.context).inflate( - R.layout.item_progressbar, parent, false - ) as LinearLayout - - return ProgressViewHolder(view) - } - } - - throw Exception("Unexpected ViewType") - } - - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - if (holder is ViewHolder) { - with(holder.view) { + inner class GalleryViewHolder(private val view: CardView) : RecyclerView.ViewHolder(view) { + fun bind(item: Pair>) { + with(view) { val resources = context.resources val languages = resources.getStringArray(R.array.languages).map { it.split("|").let { split -> Pair(split[0], split[1]) } }.toMap() - val (gallery, thumbnail) = galleries[position] - holder.galleryID = gallery.id + val (gallery: GalleryBlock, thumbnail: Deferred) = item val artists = gallery.artists val series = gallery.series @@ -99,7 +62,7 @@ class GalleryBlockAdapter(private val galleries: List { @@ -232,32 +192,85 @@ class GalleryBlockAdapter(private val galleries: List View.GONE - false -> View.VISIBLE + } + class NextViewHolder(view: LinearLayout) : RecyclerView.ViewHolder(view) + class PrevViewHolder(view: LinearLayout) : RecyclerView.ViewHolder(view) + + class ViewHolderFactory { + companion object { + fun getLayoutID(type: Int): Int { + return when(ViewType.values()[type]) { + ViewType.NEXT -> R.layout.item_next + ViewType.PREV -> R.layout.item_prev + ViewType.GALLERY -> R.layout.item_galleryblock + } } } } + 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() + + val onChipClickedHandler = ArrayList<((Tag) -> Unit)>() + + var showNext = false + var showPrev = false + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + + fun getViewHolder(type: Int, view: View): RecyclerView.ViewHolder { + return when(ViewType.values()[type]) { + ViewType.NEXT -> NextViewHolder(view as LinearLayout) + ViewType.PREV -> PrevViewHolder(view as LinearLayout) + ViewType.GALLERY -> GalleryViewHolder(view as CardView) + } + } + + return getViewHolder( + viewType, + LayoutInflater.from(parent.context).inflate( + ViewHolderFactory.getLayoutID(viewType), + parent, + false + ) + ) + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + if (holder is GalleryViewHolder) + holder.bind(galleries[position-(if (showPrev) 1 else 0)]) + } + override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) { super.onViewDetachedFromWindow(holder) - if (holder is ViewHolder) { - val galleryID = holder.galleryID ?: return - val task = refreshTasks.get(galleryID) ?: return + if (holder is GalleryViewHolder) { + val task = refreshTasks[holder] ?: return - refreshTasks.remove(galleryID) task.cancel() + refreshTasks.remove(holder) } } - override fun getItemCount() = if (galleries.isEmpty()) 0 else galleries.size+1 + override fun getItemCount() = + (if (galleries.isEmpty()) 0 else galleries.size)+ + (if (showNext) 1 else 0)+ + (if (showPrev) 1 else 0) override fun getItemViewType(position: Int): Int { return when { - galleries.getOrNull(position) == null -> ViewType.VIEW_PROG.ordinal - else -> ViewType.VIEW_ITEM.ordinal - } + showPrev && position == 0 -> ViewType.PREV + showNext && position == galleries.size+(if (showPrev) 1 else 0) -> ViewType.NEXT + else -> ViewType.GALLERY + }.ordinal } } \ No newline at end of file diff --git a/app/src/main/java/xyz/quaver/pupil/util/GalleryDownloader.kt b/app/src/main/java/xyz/quaver/pupil/util/GalleryDownloader.kt index a557d222..b3657ed9 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/GalleryDownloader.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/GalleryDownloader.kt @@ -55,7 +55,7 @@ class GalleryDownloader( var onReaderLoadedHandler: ((Reader) -> Unit)? = null var onProgressHandler: ((Int) -> Unit)? = null var onDownloadedHandler: ((List) -> Unit)? = null - var onErrorHandler: (() -> Unit)? = null + var onErrorHandler: ((Exception) -> Unit)? = null var onCompleteHandler: (() -> Unit)? = null var onNotifyChangedHandler: ((Boolean) -> Unit)? = null @@ -100,15 +100,13 @@ class GalleryDownloader( } } - //Could not retrieve reader - if (reader.isEmpty()) - throw IOException("Can't retrieve Reader") + if (reader.isNotEmpty()) { + //Save cache + if (!cache.parentFile.exists()) + cache.parentFile.mkdirs() - //Save cache - if (!cache.parentFile.exists()) - cache.parentFile.mkdirs() - - cache.writeText(json.stringify(serializer, reader)) + cache.writeText(json.stringify(serializer, reader)) + } reader } @@ -120,6 +118,9 @@ class GalleryDownloader( downloadJob = CoroutineScope(Dispatchers.Default).launch { val reader = reader.await() + if (reader.isEmpty()) + onErrorHandler?.invoke(IOException("Couldn't retrieve Reader")) + val list = ArrayList() onReaderLoadedHandler?.invoke(reader) @@ -162,7 +163,7 @@ class GalleryDownloader( } catch (e: Exception) { cache.delete() - onErrorHandler?.invoke() + onErrorHandler?.invoke(e) notificationBuilder .setContentTitle(galleryBlock.title) diff --git a/app/src/main/res/drawable/ic_jump.xml b/app/src/main/res/drawable/ic_jump.xml new file mode 100644 index 00000000..e59a1a2a --- /dev/null +++ b/app/src/main/res/drawable/ic_jump.xml @@ -0,0 +1,14 @@ + + + + diff --git a/app/src/main/res/drawable/ic_navigate_before_black_24dp.xml b/app/src/main/res/drawable/ic_navigate_before_black_24dp.xml new file mode 100644 index 00000000..e6bb3ca9 --- /dev/null +++ b/app/src/main/res/drawable/ic_navigate_before_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_navigate_next_black_24dp.xml b/app/src/main/res/drawable/ic_navigate_next_black_24dp.xml new file mode 100644 index 00000000..24835127 --- /dev/null +++ b/app/src/main/res/drawable/ic_navigate_next_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_main_content.xml b/app/src/main/res/layout/activity_main_content.xml index ffebabe9..a5b3b266 100644 --- a/app/src/main/res/layout/activity_main_content.xml +++ b/app/src/main/res/layout/activity_main_content.xml @@ -1,5 +1,6 @@ - - - - - + android:paddingTop="64dp" + android:clipToPadding="false" + android:scrollbars="vertical" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/> @@ -71,7 +64,7 @@ android:layout_height="match_parent" app:floatingSearch_searchBarMarginLeft="8dp" app:floatingSearch_searchBarMarginRight="8dp" - app:floatingSearch_searchBarMarginTop="24dp" + app:floatingSearch_searchBarMarginTop="8dp" app:floatingSearch_searchHint="@string/search_hint" app:floatingSearch_suggestionsListAnimDuration="250" app:floatingSearch_showSearchKey="true" diff --git a/app/src/main/res/layout/activity_reader.xml b/app/src/main/res/layout/activity_reader.xml index 59ff93c1..9e49df68 100644 --- a/app/src/main/res/layout/activity_reader.xml +++ b/app/src/main/res/layout/activity_reader.xml @@ -1,5 +1,6 @@ diff --git a/app/src/main/res/layout/dialog_numberpicker.xml b/app/src/main/res/layout/dialog_numberpicker.xml index d9167359..943ab6ac 100644 --- a/app/src/main/res/layout/dialog_numberpicker.xml +++ b/app/src/main/res/layout/dialog_numberpicker.xml @@ -7,7 +7,7 @@