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 3fef32d8..76304c9d 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 8
+ versionName "2.2"
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..d35b14b4 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,107 +40,64 @@ import java.net.URL
import java.util.*
import javax.net.ssl.HttpsURLConnection
import kotlin.collections.ArrayList
+import kotlin.math.roundToInt
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 totalItems = 0
private var loadingJob: Job? = null
+ private var currentPage = 0
+
+ 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)
- window.setFlags(
- WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
- WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
- )
+ 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
+ }
setContentView(R.layout.activity_main)
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 +106,8 @@ class MainActivity : AppCompatActivity() {
fetchGalleries(query)
loadBlocks()
}
+ else -> super.onBackPressed()
}
- else
- super.onBackPressed()
}
override fun onResume() {
@@ -165,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) {
@@ -243,11 +238,81 @@ class MainActivity : AppCompatActivity() {
}
}
+ private fun initView() {
+ var prevP1 = 0
+ main_appbar_layout.addOnOffsetChangedListener(
+ AppBarLayout.OnOffsetChangedListener { _, p1 ->
+ main_searchview.translationY = p1.toFloat()
+ main_recyclerview.scrollBy(0, prevP1 - p1)
+
+ prevP1 = p1
+ }
+ )
+
+ //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 {
onChipClickedHandler.add {
- post {
+ runOnUiThread {
query = it.toQuery()
this@MainActivity.findViewById(R.id.search_bar_text)
.setText(query, TextView.BufferType.EDITABLE)
@@ -259,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))
@@ -281,8 +337,12 @@ class MainActivity : AppCompatActivity() {
//TODO: Maybe sprinke some transitions will be nice :D
startActivity(intent)
- Histories.default.add(gallery.id)
+ histories.add(gallery.id)
}.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)
@@ -301,7 +361,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()
@@ -329,6 +389,209 @@ 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) {
+ val icon = next.findViewById(R.id.icon_next)
+ next.layoutParams.height = 1
+ icon.layoutParams.height = 1
+ icon.rotation = 180f
+ }
+
+ next?.requestLayout()
+
+ notifyItemRemoved(itemCount)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ false
+ }
}
}
@@ -357,7 +620,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()
+ }
}
}
@@ -442,7 +731,7 @@ class MainActivity : AppCompatActivity() {
if (query != this@MainActivity.query) {
this@MainActivity.query = query
- CoroutineScope(Dispatchers.Main).launch {
+ runOnUiThread {
cancelFetch()
clearGalleries()
fetchGalleries(query)
@@ -473,12 +762,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", "")!!
@@ -489,13 +778,48 @@ 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 = currentPage*perPage, count = perPage).let {
+ totalItems = it.second
+ it.first
+ }
+ }
+ else -> doSearch("$defaultQuery $query").apply {
+ totalItems = size
+ }
+ }
+ }
+ Mode.HISTORY -> {
+ when {
+ query.isEmpty() -> {
+ histories.toList().apply {
+ totalItems = size
+ }
+ }
+ else -> {
+ val result = doSearch(query).sorted()
+ histories.filter { result.binarySearch(it) >= 0 }.apply {
+ totalItems = size
+ }
+ }
+ }
+ }
+ Mode.DOWNLOAD -> {
+ when {
+ query.isEmpty() -> downloads.toList().apply {
+ totalItems = size
+ }
+ else -> {
+ val result = doSearch(query).sorted()
+ downloads.filter { result.binarySearch(it) >= 0 }.apply {
+ totalItems = size
+ }
+ }
+ }
+ }
}
}
}
@@ -517,18 +841,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 {
@@ -586,8 +903,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/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..c92e65b0 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
@@ -13,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
@@ -63,7 +64,7 @@ class ReaderActivity : AppCompatActivity() {
initView()
- if (!downloader.notify)
+ if (!downloader.download)
downloader.start()
}
@@ -90,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
@@ -98,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()
}
@@ -113,7 +114,7 @@ class ReaderActivity : AppCompatActivity() {
override fun onDestroy() {
super.onDestroy()
- if (!downloader.notify)
+ if (!downloader.download)
downloader.cancel()
}
@@ -136,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 {
@@ -159,18 +166,21 @@ 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
+ if (it is IOException)
+ Snackbar.make(reader_layout, R.string.unable_to_connect, Snackbar.LENGTH_LONG).show()
+ downloader.download = false
}
onCompleteHandler = {
CoroutineScope(Dispatchers.Main).launch {
@@ -180,32 +190,36 @@ class ReaderActivity : AppCompatActivity() {
onNotifyChangedHandler = { notify ->
val fab = reader_fab_download
- if (notify) {
- val icon = AnimatedVectorDrawableCompat.create(this, R.drawable.ic_downloading)
- icon?.registerAnimationCallback(object: Animatable2Compat.AnimationCallback() {
- override fun onAnimationEnd(drawable: Drawable?) {
- if (downloader.notify)
- fab.post {
- icon.start()
- fab.labelText = getString(R.string.reader_fab_download_cancel)
- }
- else
- fab.post {
- fab.setImageResource(R.drawable.ic_download)
- fab.labelText = getString(R.string.reader_fab_download)
- }
- }
- })
+ runOnUiThread {
+ if (notify) {
+ val icon = AnimatedVectorDrawableCompat.create(this, R.drawable.ic_downloading)
+ icon?.registerAnimationCallback(object: Animatable2Compat.AnimationCallback() {
+ override fun onAnimationEnd(drawable: Drawable?) {
+ if (downloader.download)
+ fab.post {
+ icon.start()
+ fab.labelText = getString(R.string.reader_fab_download_cancel)
+ }
+ else
+ fab.post {
+ fab.setImageResource(R.drawable.ic_download)
+ fab.labelText = getString(R.string.reader_fab_download)
+ }
+ }
+ })
- fab.setImageDrawable(icon)
- icon?.start()
- } else {
- fab.setImageResource(R.drawable.ic_download)
+ fab.setImageDrawable(icon)
+ icon?.start()
+ } else {
+ runOnUiThread {
+ fab.setImageResource(R.drawable.ic_download)
+ }
+ }
}
}
}
- if (downloader.notify) {
+ if (downloader.download) {
downloader.invokeOnReaderLoaded()
downloader.invokeOnNotifyChanged()
}
@@ -255,9 +269,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..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,14 +1,13 @@
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
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
@@ -29,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
@@ -101,7 +62,7 @@ class GalleryBlockAdapter(private val galleries: List {
@@ -234,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/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 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
@@ -67,7 +67,7 @@ class GalleryDownloader(
initNotification()
reader = CoroutineScope(Dispatchers.IO).async {
- notify = _notify
+ download = _notify
val json = Json(JsonConfiguration.Stable)
val serializer = ReaderItem.serializer().list
val preference = PreferenceManager.getDefaultSharedPreferences(this@GalleryDownloader)
@@ -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)
@@ -138,7 +139,7 @@ class GalleryDownloader(
.setProgress(reader.size, index, false)
.setContentText("$index/${reader.size}")
- if (notify)
+ if (download)
notificationManager.notify(galleryBlock.id, notificationBuilder.build())
async(Dispatchers.IO) {
@@ -162,7 +163,7 @@ class GalleryDownloader(
} catch (e: Exception) {
cache.delete()
- onErrorHandler?.invoke()
+ onErrorHandler?.invoke(e)
notificationBuilder
.setContentTitle(galleryBlock.title)
@@ -188,10 +189,10 @@ class GalleryDownloader(
.setContentText(getString(R.string.reader_notification_complete))
.setProgress(0, 0, false)
- if (notify)
+ if (download)
notificationManager.notify(galleryBlock.id, notificationBuilder.build())
- notify = false
+ download = false
}
remove(galleryBlock.id)
@@ -219,7 +220,7 @@ class GalleryDownloader(
}
fun invokeOnNotifyChanged() {
- onNotifyChangedHandler?.invoke(notify)
+ onNotifyChangedHandler?.invoke(download)
}
private fun initNotification() {
diff --git a/app/src/main/java/xyz/quaver/pupil/util/history.kt b/app/src/main/java/xyz/quaver/pupil/util/history.kt
index a7fdce46..1815b58a 100644
--- a/app/src/main/java/xyz/quaver/pupil/util/history.kt
+++ b/app/src/main/java/xyz/quaver/pupil/util/history.kt
@@ -20,10 +20,6 @@ class Histories(private val file: File) : ArrayList() {
}
}
- 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/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 @@
diff --git a/app/src/main/res/layout/item_next.xml b/app/src/main/res/layout/item_next.xml
new file mode 100644
index 00000000..ec429ad8
--- /dev/null
+++ b/app/src/main/res/layout/item_next.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_prev.xml b/app/src/main/res/layout/item_prev.xml
new file mode 100644
index 00000000..c01cc5da
--- /dev/null
+++ b/app/src/main/res/layout/item_prev.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
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/menu/main.xml b/app/src/main/res/menu/main.xml
index a204ac61..5272419e 100644
--- a/app/src/main/res/menu/main.xml
+++ b/app/src/main/res/menu/main.xml
@@ -2,10 +2,9 @@
\ No newline at end of file
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 6e723198..24689f50 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -6,12 +6,12 @@
結果なし
検索
ギャラリー検索
+ ギャラリー検索
キャッシュ
イメージキャッシュクリア
キャッシュをクリアするとイメージのロード速度に影響を与えます。実行しますか?
キャッシュサイズ: %1$d%2$s
デフォルトキーワード
- 権限を拒否すると一部の機能が利用できません
一回にロードするギャラリー数
検索設定
設定
@@ -52,4 +52,11 @@
ダウンロードエラー
バックグラウンドダウンロード中止
このギャラリーを削除
+ ダウンロード
+ ページ移動
+ 現ページ番号: %1$d\nページ数: %2$d
+ hitomi.laに接続できません
+ %1$dページへ移動
+ (Korean only)
+ (Korean only)
\ 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..003f882c 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -3,8 +3,8 @@
언어: %1$s
시리즈: %1$s
종류: %1$s
- 권한을 거부하면 일부 기능이 작동하지 않을 수 있습니다
갤러리 검색
+ 갤러리 검색
기본 검색어
이미지 캐시 정리하기
캐시를 정리하면 이미지 로딩속도가 느려질 수 있습니다. 계속하시겠습니까?
@@ -52,4 +52,11 @@
다운로드 오류
백그라운드 다운로드 취소
갤러리 삭제
+ 다운로드
+ 페이지 이동
+ 현재 페이지: %1$d\n페이지 수: %2$d
+ hitomi.la에 연결할 수 없습니다
+ %1$d 페이지로 이동
+ 접속 불가 현상 안내
+ 최근 https 차단으로 접속이 안 되는 경우가 발생하고 있습니다\n이 경우 플레이스토어에서 SNIper앱을 이용하시면 정상이용이 가능합니다.
\ No newline at end of file
diff --git a/app/src/main/res/values-v23/styles.xml b/app/src/main/res/values-v23/styles.xml
deleted file mode 100644
index 1c4f0c38..00000000
--- a/app/src/main/res/values-v23/styles.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
\ 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..1a4abd09 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -12,7 +12,7 @@
Thumbnail
Content ImageView
- -/-
+ -/-
Fab
@@ -20,22 +20,31 @@
Warning
- Denying any permission can deactivate some functions
+ (Korean only)
+ (Korean only)
Download
Shows download status
+ Unable to connect to hitomi.la
+
Search
No result
Home
History
+ Downloads
Contact
Help
Visit homepage
Visit github
Email me!
+ Jump to page
+ Current page: %1$d\nMaximum page: %2$d
+
+ Move to page %1$d
+
Delete this gallery
WIP
@@ -47,6 +56,7 @@
# Release Note(v%1$s)\n%2$s
Search galleries
+ Search galleries
Series: %1$s
Type: %1$s
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) {
diff --git a/libpupil/src/main/java/xyz/quaver/hitomi/galleryblock.kt b/libpupil/src/main/java/xyz/quaver/hitomi/galleryblock.kt
index cd4859b0..42aece05 100644
--- a/libpupil/src/main/java/xyz/quaver/hitomi/galleryblock.kt
+++ b/libpupil/src/main/java/xyz/quaver/hitomi/galleryblock.kt
@@ -10,7 +10,7 @@ import java.util.*
import javax.net.ssl.HttpsURLConnection
//galleryblock.js
-fun fetchNozomi(area: String? = null, tag: String = "index", language: String = "all", start: Int = -1, count: Int = -1) : List {
+fun fetchNozomi(area: String? = null, tag: String = "index", language: String = "all", start: Int = -1, count: Int = -1) : Pair
, Int> {
val url =
when(area) {
null -> "$protocol//$domain/$tag-$language$nozomiextension"
@@ -28,6 +28,11 @@ fun fetchNozomi(area: String? = null, tag: String = "index", language: String =
setRequestProperty("Range", "bytes=$startByte-$endByte")
}
+ connect()
+
+ val totalItems = getHeaderField("Content-Range")
+ .replace(Regex("^[Bb]ytes \\d+-\\d+/"), "").toInt() / 4
+
val nozomi = ArrayList()
val arrayBuffer = ByteBuffer
@@ -37,10 +42,10 @@ fun fetchNozomi(area: String? = null, tag: String = "index", language: String =
while (arrayBuffer.hasRemaining())
nozomi.add(arrayBuffer.int)
- return nozomi
+ return Pair(nozomi, totalItems)
}
} catch (e: Exception) {
- return emptyList()
+ return Pair(emptyList(), 0)
}
}