Merge pull request #9 from tom5079/development

Pupil v2.8
This commit is contained in:
tom5079
2019-06-09 15:31:39 +09:00
committed by GitHub
21 changed files with 176 additions and 324 deletions

View File

@@ -9,8 +9,8 @@ android {
applicationId "xyz.quaver.pupil" applicationId "xyz.quaver.pupil"
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 28 targetSdkVersion 28
versionCode 14 versionCode 15
versionName "2.7" versionName "2.8"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {

1
app/release/output.json Normal file
View File

@@ -0,0 +1 @@
[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":15,"versionName":"2.8","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]

View File

@@ -6,7 +6,6 @@ import android.content.pm.PackageManager
import android.graphics.drawable.Animatable import android.graphics.drawable.Animatable
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.os.Environment
import android.preference.PreferenceManager import android.preference.PreferenceManager
import android.text.* import android.text.*
import android.text.style.AlignmentSpan import android.text.style.AlignmentSpan
@@ -32,14 +31,12 @@ import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main_content.* import kotlinx.android.synthetic.main.activity_main_content.*
import kotlinx.android.synthetic.main.dialog_galleryblock.view.* import kotlinx.android.synthetic.main.dialog_galleryblock.view.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.io.IOException
import kotlinx.serialization.ImplicitReflectionSerializer import kotlinx.serialization.ImplicitReflectionSerializer
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration import kotlinx.serialization.json.JsonConfiguration
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.content import kotlinx.serialization.json.content
import kotlinx.serialization.list import kotlinx.serialization.list
import kotlinx.serialization.parseList
import kotlinx.serialization.stringify import kotlinx.serialization.stringify
import ru.noties.markwon.Markwon import ru.noties.markwon.Markwon
import xyz.quaver.hitomi.* import xyz.quaver.hitomi.*
@@ -49,12 +46,9 @@ import xyz.quaver.pupil.types.TagSuggestion
import xyz.quaver.pupil.types.Tags import xyz.quaver.pupil.types.Tags
import xyz.quaver.pupil.util.* import xyz.quaver.pupil.util.*
import java.io.File import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
import java.net.URL import java.net.URL
import java.util.* import java.util.*
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import javax.net.ssl.HttpsURLConnection import javax.net.ssl.HttpsURLConnection
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import kotlin.math.roundToInt import kotlin.math.roundToInt
@@ -116,6 +110,13 @@ class MainActivity : AppCompatActivity() {
initView() initView()
} }
override fun onDestroy() {
super.onDestroy()
if (cacheDir.exists())
cacheDir.deleteRecursively()
}
override fun onBackPressed() { override fun onBackPressed() {
when { when {
main_drawer_layout.isDrawerOpen(GravityCompat.START) -> main_drawer_layout.closeDrawer(GravityCompat.START) main_drawer_layout.isDrawerOpen(GravityCompat.START) -> main_drawer_layout.closeDrawer(GravityCompat.START)
@@ -249,7 +250,7 @@ class MainActivity : AppCompatActivity() {
val msg = extractReleaseNote(update, Locale.getDefault().language) val msg = extractReleaseNote(update, Locale.getDefault().language)
setMessage(Markwon.create(context).toMarkdown(msg)) setMessage(Markwon.create(context).toMarkdown(msg))
setPositiveButton(android.R.string.yes) { _, _ -> setPositiveButton(android.R.string.yes) { _, _ ->
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.home_page)))) startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.update))))
} }
setNegativeButton(android.R.string.no) { _, _ ->} setNegativeButton(android.R.string.no) { _, _ ->}
} }
@@ -330,6 +331,9 @@ class MainActivity : AppCompatActivity() {
R.id.main_drawer_email -> { R.id.main_drawer_email -> {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.email)))) startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.email))))
} }
R.id.main_drawer_kakaotalk -> {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.kakaotalk))))
}
} }
} }
@@ -411,7 +415,7 @@ class MainActivity : AppCompatActivity() {
this?.clearNotification() this?.clearNotification()
} }
val cache = File(cacheDir, "imageCache/${galleryBlock.id}") val cache = File(cacheDir, "imageCache/${galleryBlock.id}")
val data = File(ContextCompat.getDataDir(this@MainActivity), "images/${galleryBlock.id}") val data = getCachedGallery(context, galleryBlock.id)
cache.deleteRecursively() cache.deleteRecursively()
data.deleteRecursively() data.deleteRecursively()
@@ -431,73 +435,6 @@ class MainActivity : AppCompatActivity() {
dialog.dismiss() dialog.dismiss()
} }
with(view.main_dialog_export) {
val images = File(ContextCompat.getDataDir(this@MainActivity), "images/${galleryBlock.id}/images").let {
when {
it.exists() -> it
else -> File(cacheDir, "imageCache/${galleryBlock.id}/images")
}
}
isEnabled = images.exists()
setOnClickListener {
CoroutineScope(Dispatchers.Default).launch {
val preference = PreferenceManager.getDefaultSharedPreferences(context)
val zip = preference.getBoolean("export_zip", false)
if (zip) {
var target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id} ${galleryBlock.title}.zip")
try {
target.createNewFile()
} catch (e: IOException) {
target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id}.zip")
try {
target.createNewFile()
} catch (e: IOException) {
Snackbar.make(main_layout, getString(R.string.main_export_error), Snackbar.LENGTH_LONG).show()
return@launch
}
}
FileOutputStream(target).use { targetStream ->
ZipOutputStream(targetStream).use {zipStream ->
images.listFiles().forEach {
zipStream.putNextEntry(ZipEntry(it.name))
FileInputStream(it).use { fileStream ->
fileStream.copyTo(zipStream)
}
}
}
}
} else {
var target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id} ${galleryBlock.title}")
try {
target.canonicalPath
} catch (e: IOException) {
target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id}")
try {
target.canonicalPath
} catch (e: IOException) {
Snackbar.make(main_layout, getString(R.string.main_export_error), Snackbar.LENGTH_LONG).show()
return@launch
}
}
images.copyRecursively(target, true)
}
Snackbar.make(main_layout, getString(R.string.main_export_complete), Snackbar.LENGTH_LONG).show()
}
dialog.dismiss()
}
}
dialog.show() dialog.show()
true true
@@ -1058,18 +995,18 @@ class MainActivity : AppCompatActivity() {
galleryIDs.slice(currentPage*perPage until Math.min(currentPage*perPage+perPage, galleryIDs.size)) galleryIDs.slice(currentPage*perPage until Math.min(currentPage*perPage+perPage, galleryIDs.size))
}.chunked(5).let { chunks -> }.chunked(5).let { chunks ->
for (chunk in chunks) for (chunk in chunks)
chunk.map { chunk.map { galleryID ->
async { async {
try { try {
val json = Json(JsonConfiguration.Stable) val json = Json(JsonConfiguration.Stable)
val serializer = GalleryBlock.serializer() val serializer = GalleryBlock.serializer()
val galleryBlock = val galleryBlock =
File(cacheDir, "imageCache/$it/galleryBlock.json").let { cache -> File(getCachedGallery(this@MainActivity, galleryID), "galleryBlock.json").let { cache ->
when { when {
cache.exists() -> json.parse(serializer, cache.readText()) cache.exists() -> json.parse(serializer, cache.readText())
else -> { else -> {
getGalleryBlock(it).apply { getGalleryBlock(galleryID).apply {
this ?: return@apply this ?: return@apply
if (!cache.parentFile.exists()) if (!cache.parentFile.exists())
@@ -1083,19 +1020,17 @@ class MainActivity : AppCompatActivity() {
val thumbnail = async { val thumbnail = async {
val ext = galleryBlock.thumbnails[0].split('.').last() val ext = galleryBlock.thumbnails[0].split('.').last()
File(cacheDir, "imageCache/$it/thumbnail.$ext").apply { File(getCachedGallery(this@MainActivity, galleryBlock.id), "thumbnail.$ext").apply {
val cache = this if (!exists())
if (!cache.exists())
try { try {
with(URL(galleryBlock.thumbnails[0]).openConnection() as HttpsURLConnection) { with(URL(galleryBlock.thumbnails[0]).openConnection() as HttpsURLConnection) {
if (!cache.parentFile.exists()) if (!this@apply.parentFile.exists())
cache.parentFile.mkdirs() this@apply.parentFile.mkdirs()
inputStream.copyTo(FileOutputStream(cache)) inputStream.copyTo(FileOutputStream(this@apply))
} }
} catch (e: Exception) { } catch (e: Exception) {
cache.delete() delete()
} }
}.absolutePath }.absolutePath
} }

View File

@@ -6,7 +6,6 @@ import android.os.Bundle
import android.view.* import android.view.*
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearSmoothScroller import androidx.recyclerview.widget.LinearSmoothScroller
@@ -25,16 +24,11 @@ import kotlinx.io.IOException
import kotlinx.serialization.ImplicitReflectionSerializer import kotlinx.serialization.ImplicitReflectionSerializer
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration import kotlinx.serialization.json.JsonConfiguration
import kotlinx.serialization.list
import kotlinx.serialization.stringify
import xyz.quaver.hitomi.GalleryBlock import xyz.quaver.hitomi.GalleryBlock
import xyz.quaver.pupil.adapters.ReaderAdapter import xyz.quaver.pupil.adapters.ReaderAdapter
import xyz.quaver.pupil.types.Tag
import xyz.quaver.pupil.types.Tags
import xyz.quaver.pupil.util.GalleryDownloader import xyz.quaver.pupil.util.GalleryDownloader
import xyz.quaver.pupil.util.Histories import xyz.quaver.pupil.util.Histories
import xyz.quaver.pupil.util.ItemClickSupport import xyz.quaver.pupil.util.ItemClickSupport
import java.io.File
class ReaderActivity : AppCompatActivity() { class ReaderActivity : AppCompatActivity() {
@@ -309,14 +303,6 @@ class ReaderActivity : AppCompatActivity() {
if (!downloader.download) if (!downloader.download)
downloader.clearNotification() downloader.clearNotification()
} }
reader_fab_export.setOnClickListener {
downloader.export( {
Snackbar.make(reader_layout, getString(R.string.main_export_complete), Snackbar.LENGTH_LONG).show()
}, {
Snackbar.make(reader_layout, getString(R.string.main_export_error), Snackbar.LENGTH_LONG).show()
})
}
} }
private fun fullscreen(isFullscreen: Boolean) { private fun fullscreen(isFullscreen: Boolean) {

View File

@@ -1,6 +1,7 @@
package xyz.quaver.pupil package xyz.quaver.pupil
import android.os.Bundle import android.os.Bundle
import android.os.Environment
import android.preference.PreferenceManager import android.preference.PreferenceManager
import android.text.Editable import android.text.Editable
import android.text.TextWatcher import android.text.TextWatcher
@@ -12,7 +13,6 @@ import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import kotlinx.android.synthetic.main.dialog_default_query.view.* import kotlinx.android.synthetic.main.dialog_default_query.view.*
@@ -67,39 +67,16 @@ class SettingsActivity : AppCompatActivity() {
suffixIndex++ suffixIndex++
} }
return getString(R.string.settings_clear_cache_summary, size, suffix[suffixIndex]) return getString(R.string.settings_clear_downloads_summary, size, suffix[suffixIndex])
} }
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey) setPreferencesFromResource(R.xml.root_preferences, rootKey)
with(findPreference<Preference>("delete_image_cache")) {
this ?: return@with
val dir = File(context.cacheDir, "imageCache")
summary = getCacheSize(dir)
setOnPreferenceClickListener {
AlertDialog.Builder(context).apply {
setTitle(R.string.warning)
setMessage(R.string.settings_clear_cache_alert_message)
setPositiveButton(android.R.string.yes) { _, _ ->
if (dir.exists())
dir.deleteRecursively()
summary = getCacheSize(dir)
}
setNegativeButton(android.R.string.no) { _, _ -> }
}.show()
true
}
}
with(findPreference<Preference>("delete_downloads")) { with(findPreference<Preference>("delete_downloads")) {
this ?: return@with this ?: return@with
val dir = File(ContextCompat.getDataDir(context), "images") val dir = File(Environment.getExternalStorageDirectory(), "Pupil")
summary = getCacheSize(dir) summary = getCacheSize(dir)

View File

@@ -1,12 +1,13 @@
package xyz.quaver.pupil.adapters package xyz.quaver.pupil.adapters
import android.app.AlertDialog
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.graphics.drawable.Animatable import android.graphics.drawable.Animatable
import android.util.Log
import android.util.SparseBooleanArray import android.util.SparseBooleanArray
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.LinearLayout import android.widget.LinearLayout
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
@@ -27,6 +28,7 @@ import xyz.quaver.pupil.Pupil
import xyz.quaver.pupil.R import xyz.quaver.pupil.R
import xyz.quaver.pupil.types.Tag import xyz.quaver.pupil.types.Tag
import xyz.quaver.pupil.util.Histories import xyz.quaver.pupil.util.Histories
import xyz.quaver.pupil.util.getCachedGallery
import java.io.File import java.io.File
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
@@ -53,10 +55,10 @@ class GalleryBlockAdapter(private val galleries: List<Pair<GalleryBlock, Deferre
} }
}.toMap() }.toMap()
val (gallery: GalleryBlock, thumbnail: Deferred<String>) = item val (galleryBlock: GalleryBlock, thumbnail: Deferred<String>) = item
val artists = gallery.artists val artists = galleryBlock.artists
val series = gallery.series val series = galleryBlock.series
CoroutineScope(Dispatchers.Default).launch { CoroutineScope(Dispatchers.Default).launch {
val cache = thumbnail.await() val cache = thumbnail.await()
@@ -72,22 +74,8 @@ class GalleryBlockAdapter(private val galleries: List<Pair<GalleryBlock, Deferre
} }
//Check cache //Check cache
val readerCache = { val readerCache = { File(getCachedGallery(context, galleryBlock.id), "reader.json") }
File(ContextCompat.getDataDir(context), "images/${gallery.id}/reader.json").let { val imageCache = { File(getCachedGallery(context, galleryBlock.id), "images") }
when {
it.exists() -> it
else -> File(context.cacheDir, "imageCache/${gallery.id}/reader.json")
}
}
}
val imageCache = {
File(ContextCompat.getDataDir(context), "images/${gallery.id}/images").let {
when {
it.exists() -> it
else -> File(context.cacheDir, "imageCache/${gallery.id}/images")
}
}
}
if (readerCache.invoke().exists()) { if (readerCache.invoke().exists()) {
val reader = Json(JsonConfiguration.Stable) val reader = Json(JsonConfiguration.Stable)
@@ -124,7 +112,7 @@ class GalleryBlockAdapter(private val galleries: List<Pair<GalleryBlock, Deferre
} }
if (progress == max) { if (progress == max) {
if (completeFlag.get(gallery.id, false)) { if (completeFlag.get(galleryBlock.id, false)) {
with(view.galleryblock_progress_complete) { with(view.galleryblock_progress_complete) {
setImageResource(R.drawable.ic_progressbar) setImageResource(R.drawable.ic_progressbar)
visibility = View.VISIBLE visibility = View.VISIBLE
@@ -136,7 +124,7 @@ class GalleryBlockAdapter(private val galleries: List<Pair<GalleryBlock, Deferre
visibility = View.VISIBLE visibility = View.VISIBLE
} }
drawable?.start() drawable?.start()
completeFlag.put(gallery.id, true) completeFlag.put(galleryBlock.id, true)
} }
} else } else
view.galleryblock_progress_complete.visibility = View.INVISIBLE view.galleryblock_progress_complete.visibility = View.INVISIBLE
@@ -150,13 +138,26 @@ class GalleryBlockAdapter(private val galleries: List<Pair<GalleryBlock, Deferre
refreshTasks[this@GalleryViewHolder] = refresh refreshTasks[this@GalleryViewHolder] = refresh
} }
galleryblock_title.text = gallery.title galleryblock_title.text = galleryBlock.title
with(galleryblock_artist) { with(galleryblock_artist) {
text = artists.joinToString(", ") { it.wordCapitalize() } text = artists.joinToString(", ") { it.wordCapitalize() }
visibility = when { visibility = when {
artists.isNotEmpty() -> View.VISIBLE artists.isNotEmpty() -> View.VISIBLE
else -> View.GONE 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) { with(galleryblock_series) {
text = text =
@@ -167,20 +168,54 @@ class GalleryBlockAdapter(private val galleries: List<Pair<GalleryBlock, Deferre
series.isNotEmpty() -> View.VISIBLE series.isNotEmpty() -> View.VISIBLE
else -> View.GONE 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, gallery.type).wordCapitalize()
with(galleryblock_language) { with(galleryblock_language) {
text = text =
resources.getString(R.string.galleryblock_language, languages[gallery.language]) resources.getString(R.string.galleryblock_language, languages[galleryBlock.language])
visibility = when { visibility = when {
gallery.language.isNotEmpty() -> View.VISIBLE galleryBlock.language.isNotEmpty() -> View.VISIBLE
else -> View.GONE else -> View.GONE
} }
setOnClickListener {
setOnClickListener {
for(callback in onChipClickedHandler)
callback.invoke(Tag("language", galleryBlock.language))
}
}
} }
galleryblock_tag_group.removeAllViews() galleryblock_tag_group.removeAllViews()
gallery.relatedTags.forEach { galleryBlock.relatedTags.forEach {
val tag = Tag.parse(it) val tag = Tag.parse(it).let { tag ->
when {
tag.area != null -> tag
else -> Tag("tag", it)
}
}
val chip = LayoutInflater.from(context) val chip = LayoutInflater.from(context)
.inflate(R.layout.tag_chip, this, false) as Chip .inflate(R.layout.tag_chip, this, false) as Chip
@@ -209,17 +244,19 @@ class GalleryBlockAdapter(private val galleries: List<Pair<GalleryBlock, Deferre
galleryblock_tag_group.addView(chip) galleryblock_tag_group.addView(chip)
} }
galleryblock_id.text = galleryBlock.id.toString()
if (!::favorites.isInitialized) if (!::favorites.isInitialized)
favorites = (context.applicationContext as Pupil).favorites favorites = (context.applicationContext as Pupil).favorites
with(galleryblock_favorite) { with(galleryblock_favorite) {
post { post {
isChecked = favorites.contains(gallery.id) isChecked = favorites.contains(galleryBlock.id)
} }
setOnClickListener { setOnClickListener {
when { when {
isChecked -> favorites.add(gallery.id) isChecked -> favorites.add(galleryBlock.id)
else -> favorites.remove(gallery.id) else -> favorites.remove(galleryBlock.id)
} }
} }
setOnCheckedChangeListener { _, isChecked -> setOnCheckedChangeListener { _, isChecked ->

View File

@@ -1,6 +1,5 @@
package xyz.quaver.pupil.adapters package xyz.quaver.pupil.adapters
import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View

View File

@@ -9,7 +9,6 @@ import android.util.SparseArray
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
import androidx.core.app.TaskStackBuilder import androidx.core.app.TaskStackBuilder
import androidx.core.content.ContextCompat
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.io.IOException import kotlinx.io.IOException
@@ -23,12 +22,9 @@ import xyz.quaver.pupil.Pupil
import xyz.quaver.pupil.R import xyz.quaver.pupil.R
import xyz.quaver.pupil.ReaderActivity import xyz.quaver.pupil.ReaderActivity
import java.io.File import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
import java.net.URL import java.net.URL
import java.util.* import java.util.*
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import javax.net.ssl.HttpsURLConnection import javax.net.ssl.HttpsURLConnection
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import kotlin.concurrent.schedule import kotlin.concurrent.schedule
@@ -48,10 +44,10 @@ class GalleryDownloader(
field = true field = true
notificationManager.notify(galleryBlock.id, notificationBuilder.build()) notificationManager.notify(galleryBlock.id, notificationBuilder.build())
val data = File(ContextCompat.getDataDir(this), "images/${galleryBlock.id}") val data = getCachedGallery(this, galleryBlock.id)
val cache = File(cacheDir, "imageCache/${galleryBlock.id}") val cache = File(cacheDir, "imageCache/${galleryBlock.id}")
if (cache.exists() && !data.exists()) { if (File(cache, "images").exists() && !data.exists()) {
cache.copyRecursively(data, true) cache.copyRecursively(data, true)
cache.deleteRecursively() cache.deleteRecursively()
} }
@@ -93,12 +89,7 @@ class GalleryDownloader(
val serializer = ReaderItem.serializer().list val serializer = ReaderItem.serializer().list
//Check cache //Check cache
val cache = File(ContextCompat.getDataDir(this@GalleryDownloader), "images/${galleryBlock.id}/reader.json").let { val cache = File(getCachedGallery(this@GalleryDownloader, galleryBlock.id), "reader.json")
when {
it.exists() -> it
else -> File(cacheDir, "imageCache/${galleryBlock.id}/reader.json")
}
}
if (cache.exists()) { if (cache.exists()) {
val cached = json.parse(serializer, cache.readText()) val cached = json.parse(serializer, cache.readText())
@@ -181,12 +172,7 @@ class GalleryDownloader(
val name = "$index".padStart(4, '0') val name = "$index".padStart(4, '0')
val ext = url.split('.').last() val ext = url.split('.').last()
val cache = File(ContextCompat.getDataDir(this@GalleryDownloader), "images/${galleryBlock.id}/images/$name.$ext").let { val cache = File(getCachedGallery(this@GalleryDownloader, galleryBlock.id), "images/$name.$ext")
when {
it.exists() -> it
else -> File(cacheDir, "/imageCache/${galleryBlock.id}/images/$name.$ext")
}
}
if (!cache.exists()) if (!cache.exists())
try { try {
@@ -234,31 +220,17 @@ class GalleryDownloader(
if (download) { if (download) {
File(cacheDir, "imageCache/${galleryBlock.id}").let { File(cacheDir, "imageCache/${galleryBlock.id}").let {
if (it.exists()) { if (it.exists()) {
it.copyRecursively( val target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id}")
File(ContextCompat.getDataDir(this@GalleryDownloader), "images/${galleryBlock.id}"),
true if (!target.exists())
) target.mkdirs()
it.copyRecursively(target, true)
it.deleteRecursively() it.deleteRecursively()
} }
} }
val preference = PreferenceManager.getDefaultSharedPreferences(this@GalleryDownloader) notificationManager.notify(galleryBlock.id, notificationBuilder.build())
val autoExport = preference.getBoolean("auto_export", false)
if (autoExport) {
export({
notificationManager.notify(galleryBlock.id, notificationBuilder.build())
}, {
notificationBuilder
.setContentTitle(galleryBlock.title)
.setContentText(getString(R.string.main_export_error))
.setProgress(0, 0, false)
notificationManager.notify(galleryBlock.id, notificationBuilder.build())
})
} else {
notificationManager.notify(galleryBlock.id, notificationBuilder.build())
}
} }
download = false download = false
@@ -314,69 +286,4 @@ class GalleryDownloader(
notificationManager = NotificationManagerCompat.from(this) notificationManager = NotificationManagerCompat.from(this)
} }
fun export(onSuccess: (() -> Unit)? = null, onError: (() -> Unit)? = null) {
val images = File(ContextCompat.getDataDir(this), "images/${galleryBlock.id}/images").let {
when {
it.exists() -> it
else -> File(cacheDir, "imageCache/${galleryBlock.id}/images")
}
}
if (!images.exists())
return
CoroutineScope(Dispatchers.Default).launch {
val preference = PreferenceManager.getDefaultSharedPreferences(this@GalleryDownloader)
val zip = preference.getBoolean("export_zip", false)
if (zip) {
var target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id} ${galleryBlock.title}.zip")
try {
target.createNewFile()
} catch (e: IOException) {
target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id}.zip")
try {
target.createNewFile()
} catch (e: IOException) {
onError?.invoke()
return@launch
}
}
FileOutputStream(target).use { targetStream ->
ZipOutputStream(targetStream).use { zipStream ->
images.listFiles().forEach {
zipStream.putNextEntry(ZipEntry(it.name))
FileInputStream(it).use { fileStream ->
fileStream.copyTo(zipStream)
}
}
}
}
} else {
var target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id} ${galleryBlock.title}")
try {
target.canonicalPath
} catch (e: IOException) {
target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id}")
try {
target.canonicalPath
} catch (e: IOException) {
onError?.invoke()
return@launch
}
}
images.copyRecursively(target, true)
}
onSuccess?.invoke()
}
}
} }

View File

@@ -0,0 +1,14 @@
package xyz.quaver.pupil.util
import android.content.Context
import android.os.Environment
import java.io.File
fun getCachedGallery(context: Context, galleryID: Int): File {
return File(Environment.getExternalStorageDirectory(), "Pupil/$galleryID").let {
when {
it.exists() -> it
else -> File(context.cacheDir, "imageCache/$galleryID")
}
}
}

View File

@@ -0,0 +1,8 @@
<!-- drawable/message.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M20,2H4A2,2 0 0,0 2,4V22L6,18H20A2,2 0 0,0 22,16V4C22,2.89 21.1,2 20,2Z" />
</vector>

View File

@@ -0,0 +1,8 @@
<!-- drawable/numeric.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M4,17V9H2V7H6V17H4M22,15C22,16.11 21.1,17 20,17H16V15H20V13H18V11H20V9H16V7H20A2,2 0 0,1 22,9V10.5A1.5,1.5 0 0,1 20.5,12A1.5,1.5 0 0,1 22,13.5V15M14,15V17H8V13C8,11.89 8.9,11 10,11H12V9H8V7H12A2,2 0 0,1 14,9V11C14,12.11 13.1,13 12,13H10V15H14Z" />
</vector>

View File

@@ -51,14 +51,6 @@
app:fab_label="@string/reader_fab_download" app:fab_label="@string/reader_fab_download"
app:fab_size="mini"/> app:fab_size="mini"/>
<com.github.clans.fab.FloatingActionButton
android:id="@+id/reader_fab_export"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_export"
app:fab_label="@string/main_dialog_export"
app:fab_size="mini"/>
<com.github.clans.fab.FloatingActionButton <com.github.clans.fab.FloatingActionButton
android:id="@+id/reader_fab_fullscreen" android:id="@+id/reader_fab_fullscreen"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@@ -20,12 +20,4 @@
android:text="@string/main_dialog_delete" android:text="@string/main_dialog_delete"
app:layout_constraintTop_toBottomOf="@id/main_dialog_download"/> app:layout_constraintTop_toBottomOf="@id/main_dialog_download"/>
<Button
android:id="@+id/main_dialog_export"
style="?borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/main_dialog_export"
app:layout_constraintTop_toBottomOf="@id/main_dialog_delete"/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -69,6 +69,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:clickable="true"
android:focusable="true"
app:layout_constraintLeft_toRightOf="@id/galleryblock_thumbnail" app:layout_constraintLeft_toRightOf="@id/galleryblock_thumbnail"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/galleryblock_title"/> app:layout_constraintTop_toBottomOf="@id/galleryblock_title"/>
@@ -79,6 +81,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:clickable="true"
android:focusable="true"
app:layout_constraintTop_toBottomOf="@id/galleryblock_artist" app:layout_constraintTop_toBottomOf="@id/galleryblock_artist"
app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail" app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail"
app:layout_constraintEnd_toEndOf="parent"/> app:layout_constraintEnd_toEndOf="parent"/>
@@ -89,6 +93,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:clickable="true"
android:focusable="true"
app:layout_constraintTop_toBottomOf="@id/galleryblock_series" app:layout_constraintTop_toBottomOf="@id/galleryblock_series"
app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail" /> app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail" />
@@ -99,6 +105,8 @@
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:clickable="true"
android:focusable="true"
app:layout_constraintTop_toBottomOf="@id/galleryblock_type" app:layout_constraintTop_toBottomOf="@id/galleryblock_type"
app:layout_constraintBottom_toTopOf="@id/galleryblock_padding" app:layout_constraintBottom_toTopOf="@id/galleryblock_padding"
app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail" /> app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail" />
@@ -135,16 +143,25 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:paddingLeft="8dp"
android:gravity="end"> android:paddingRight="8dp"
android:paddingBottom="8dp"
android:orientation="horizontal">
<TextView
android:id="@+id/galleryblock_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"/>
<ToggleButton <ToggleButton
android:id="@+id/galleryblock_favorite" android:id="@+id/galleryblock_favorite"
android:layout_width="32dp" android:layout_width="32dp"
android:layout_height="32dp" android:layout_height="32dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:background="@drawable/avd_star" android:background="@drawable/avd_star"
android:backgroundTint="@color/material_orange_500" android:backgroundTint="@color/material_orange_500"
android:text="" android:text=""

View File

@@ -34,6 +34,9 @@
<item android:id="@+id/main_drawer_email" <item android:id="@+id/main_drawer_email"
android:title="@string/main_drawer_group_contact_email" android:title="@string/main_drawer_group_contact_email"
android:icon="@drawable/ic_email"/> android:icon="@drawable/ic_email"/>
<item android:id="@+id/main_drawer_kakaotalk"
android:title="@string/main_drawer_grouop_contact_kakaotalk"
android:icon="@drawable/ic_message"/>
</menu> </menu>
</item> </item>

View File

@@ -7,10 +7,8 @@
<string name="main_search">検索</string> <string name="main_search">検索</string>
<string name="search_hint">ギャラリー検索</string> <string name="search_hint">ギャラリー検索</string>
<string name="search_hint_with_page">ギャラリー検索</string> <string name="search_hint_with_page">ギャラリー検索</string>
<string name="settings_cache_title">キャッシュ</string>
<string name="settings_clear_image_cache">イメージキャッシュクリア</string> <string name="settings_clear_image_cache">イメージキャッシュクリア</string>
<string name="settings_clear_cache_alert_message">キャッシュをクリアするとイメージのロード速度に影響を与えます。\n実行しますか</string> <string name="settings_clear_downloads_summary">サイズ: %1$d%2$s</string>
<string name="settings_clear_cache_summary">サイズ: %1$d%2$s</string>
<string name="settings_default_query">デフォルトキーワード</string> <string name="settings_default_query">デフォルトキーワード</string>
<string name="settings_galleries_per_page">一回にロードするギャラリー数</string> <string name="settings_galleries_per_page">一回にロードするギャラリー数</string>
<string name="settings_search_title">検索設定</string> <string name="settings_search_title">検索設定</string>
@@ -60,14 +58,12 @@
<string name="main_export_complete">エクスポート完了</string> <string name="main_export_complete">エクスポート完了</string>
<string name="main_export_open_folder">フォルダを開く</string> <string name="main_export_open_folder">フォルダを開く</string>
<string name="main_export_error">エクスポートエラーが発生しました</string> <string name="main_export_error">エクスポートエラーが発生しました</string>
<string name="settings_export_zip_title">zipエクスポート</string>
<string name="settings_export_zip_summary">イメージフォルダの代わりzipファイルでエクスポート</string>
<string name="settings_auto_export_title">自動エクスポート</string>
<string name="settings_auto_export_summary">ダウンロード完了後自動的にエクスポート</string>
<string name="settings_clear_downloads">ダウンロード削除</string> <string name="settings_clear_downloads">ダウンロード削除</string>
<string name="settings_clear_downloads_alert_message">ダウンロードしたギャラリーを全て削除します。\n実行しますか</string> <string name="settings_clear_downloads_alert_message">ダウンロードしたギャラリーを全て削除します。\n実行しますか</string>
<string name="settings_use_hiyobi_summary">ロード速度を向上させるため可能であればhiyobi.meからイメージロード</string> <string name="settings_use_hiyobi_summary">ロード速度を向上させるため可能であればhiyobi.meからイメージロード</string>
<string name="main_drawer_favorite">お気に入り</string> <string name="main_drawer_favorite">お気に入り</string>
<string name="main_open_gallery_by_id">ギャラリー番号で見る</string> <string name="main_open_gallery_by_id">ギャラリー番号で見る</string>
<string name="main_open_gallery_by_id_error">エラーが発生しました</string> <string name="main_open_gallery_by_id_error">エラーが発生しました</string>
<string name="settings_storage">ストレージ</string>
<string name="main_drawer_grouop_contact_kakaotalk">カカオトーク</string>
</resources> </resources>

View File

@@ -7,8 +7,7 @@
<string name="search_hint_with_page">갤러리 검색</string> <string name="search_hint_with_page">갤러리 검색</string>
<string name="settings_default_query">기본 검색어</string> <string name="settings_default_query">기본 검색어</string>
<string name="settings_clear_image_cache">이미지 캐시 정리하기</string> <string name="settings_clear_image_cache">이미지 캐시 정리하기</string>
<string name="settings_clear_cache_alert_message">캐시를 정리하면 이미지 로딩속도가 느려질 수 있습니다.\n계속하시겠습니까?</string> <string name="settings_clear_downloads_summary">사용량: %1$d%2$s</string>
<string name="settings_clear_cache_summary">사용량: %1$d%2$s</string>
<string name="settings_galleries_per_page">한 번에 로드할 갤러리 수</string> <string name="settings_galleries_per_page">한 번에 로드할 갤러리 수</string>
<string name="settings_search_title">검색 설정</string> <string name="settings_search_title">검색 설정</string>
<string name="settings_title">설정</string> <string name="settings_title">설정</string>
@@ -17,7 +16,6 @@
<string name="warning">경고</string> <string name="warning">경고</string>
<string name="main_no_result">결과 없음</string> <string name="main_no_result">결과 없음</string>
<string name="main_search">검색</string> <string name="main_search">검색</string>
<string name="settings_cache_title">캐시</string>
<string name="settings_miscellaneous_title">기타</string> <string name="settings_miscellaneous_title">기타</string>
<string name="settings_use_hiyobi_title">hiyobi.me 사용</string> <string name="settings_use_hiyobi_title">hiyobi.me 사용</string>
<string name="settings_clear_history">기록 삭제</string> <string name="settings_clear_history">기록 삭제</string>
@@ -60,14 +58,12 @@
<string name="main_export_complete">내보내기 완료</string> <string name="main_export_complete">내보내기 완료</string>
<string name="main_export_open_folder">폴더 열기</string> <string name="main_export_open_folder">폴더 열기</string>
<string name="main_export_error">내보내기 오류가 발생했습니다</string> <string name="main_export_error">내보내기 오류가 발생했습니다</string>
<string name="settings_export_zip_title">zip 파일로 내보내기</string>
<string name="settings_export_zip_summary">이미지 폴더 대신 zip 파일로 내보내기</string>
<string name="settings_auto_export_title">자동 내보내기</string>
<string name="settings_auto_export_summary">다운로드가 끝난 후 자동 내보내기</string>
<string name="settings_clear_downloads">다운로드 삭제</string> <string name="settings_clear_downloads">다운로드 삭제</string>
<string name="settings_clear_downloads_alert_message">다운로드 된 만화를 모두 삭제합니다.\n계속하시겠습니까?</string> <string name="settings_clear_downloads_alert_message">다운로드 된 만화를 모두 삭제합니다.\n계속하시겠습니까?</string>
<string name="settings_use_hiyobi_summary">속도 향상을 위해 가능하면 hiyobi.me에서 이미지 로드</string> <string name="settings_use_hiyobi_summary">속도 향상을 위해 가능하면 hiyobi.me에서 이미지 로드</string>
<string name="main_drawer_favorite">즐겨찾기</string> <string name="main_drawer_favorite">즐겨찾기</string>
<string name="main_open_gallery_by_id">갤러리 번호로 열기</string> <string name="main_open_gallery_by_id">갤러리 번호로 열기</string>
<string name="main_open_gallery_by_id_error">갤러리를 찾지 못했습니다</string> <string name="main_open_gallery_by_id_error">갤러리를 찾지 못했습니다</string>
<string name="settings_storage">저장 공간</string>
<string name="main_drawer_grouop_contact_kakaotalk">카카오톡 오픈채팅방</string>
</resources> </resources>

View File

@@ -4,10 +4,12 @@
<string name="release_url" translatable="false">https://api.github.com/repos/tom5079/Pupil-issue/releases</string> <string name="release_url" translatable="false">https://api.github.com/repos/tom5079/Pupil-issue/releases</string>
<string name="release_name" translatable="false">Pupil-v(\\d+\\.)+\\d+\\.apk</string> <string name="release_name" translatable="false">Pupil-v(\\d+\\.)+\\d+\\.apk</string>
<string name="home_page" translatable="false">http://bit.ly/2ZlOjXJ</string> <string name="home_page" translatable="false">http://bit.ly/2EZDClw</string>
<string name="update" translatable="false">http://bit.ly/2ZlOjXJ</string>
<string name="help" translatable="false">http://bit.ly/2Z7lNZE</string> <string name="help" translatable="false">http://bit.ly/2Z7lNZE</string>
<string name="github" translatable="false">https://github.com/tom5079/Pupil-issue/issues/new/choose</string> <string name="github" translatable="false">https://github.com/tom5079/Pupil-issue/issues/new/choose</string>
<string name="email" translatable="false">mailto:pupil.hentai@gmail.com</string> <string name="email" translatable="false">mailto:pupil.hentai@gmail.com</string>
<string name="kakaotalk" translatable="false">https://open.kakao.com/o/gvNrncsb</string>
<string name="main_settings" translatable="false">Settings</string> <string name="main_settings" translatable="false">Settings</string>
<string name="galleryblock_thumbnail_description" translatable="false">Thumbnail</string> <string name="galleryblock_thumbnail_description" translatable="false">Thumbnail</string>
@@ -41,6 +43,7 @@
<string name="main_drawer_group_contact_homepage">Visit homepage</string> <string name="main_drawer_group_contact_homepage">Visit homepage</string>
<string name="main_drawer_group_contact_github">Visit github</string> <string name="main_drawer_group_contact_github">Visit github</string>
<string name="main_drawer_group_contact_email">Email me!</string> <string name="main_drawer_group_contact_email">Email me!</string>
<string name="main_drawer_grouop_contact_kakaotalk">Kakaotalk</string>
<string name="main_jump_title">Jump to page</string> <string name="main_jump_title">Jump to page</string>
<string name="main_jump_message">Current page: %1$d\nMaximum page: %2$d</string> <string name="main_jump_message">Current page: %1$d\nMaximum page: %2$d</string>
@@ -80,10 +83,9 @@
<string name="settings_search_title">Search Settings</string> <string name="settings_search_title">Search Settings</string>
<string name="settings_galleries_per_page">Galleries per page</string> <string name="settings_galleries_per_page">Galleries per page</string>
<string name="settings_default_query">Default query</string> <string name="settings_default_query">Default query</string>
<string name="settings_cache_title">Cache</string> <string name="settings_storage">Storage</string>
<string name="settings_clear_image_cache">Clear image cache</string> <string name="settings_clear_image_cache">Clear image cache</string>
<string name="settings_clear_cache_summary">Currently using %1$d%2$s</string> <string name="settings_clear_downloads_summary">Currently using %1$d%2$s</string>
<string name="settings_clear_cache_alert_message">Deleting cache can affect image loading speed.\nDo you want to continue?</string>
<string name="settings_clear_downloads">Clear downloads</string> <string name="settings_clear_downloads">Clear downloads</string>
<string name="settings_clear_downloads_alert_message">Delete all downloaded galleries.\nDo you want to continue?</string> <string name="settings_clear_downloads_alert_message">Delete all downloaded galleries.\nDo you want to continue?</string>
<string name="settings_clear_history">Clear history</string> <string name="settings_clear_history">Clear history</string>
@@ -92,10 +94,6 @@
<string name="settings_miscellaneous_title">Miscellaneous</string> <string name="settings_miscellaneous_title">Miscellaneous</string>
<string name="settings_use_hiyobi_title">Use hiyobi.me</string> <string name="settings_use_hiyobi_title">Use hiyobi.me</string>
<string name="settings_use_hiyobi_summary">Load images from hiyobi.me to improve loading speed (if available)</string> <string name="settings_use_hiyobi_summary">Load images from hiyobi.me to improve loading speed (if available)</string>
<string name="settings_export_zip_title">Export zip</string>
<string name="settings_export_zip_summary">Export to zip instead of image folder</string>
<string name="settings_auto_export_title">Auto Export</string>
<string name="settings_auto_export_summary">Automatically exports galleries when download is finished</string>
<string name="settings_security_mode_title">Enable security mode</string> <string name="settings_security_mode_title">Enable security mode</string>
<string name="settings_security_mode_summary">Enable security mode to make the screen invisible on recent app window</string> <string name="settings_security_mode_summary">Enable security mode to make the screen invisible on recent app window</string>

View File

@@ -22,11 +22,7 @@
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory
app:title="@string/settings_cache_title"> app:title="@string/settings_storage">
<Preference
app:title="@string/settings_clear_image_cache"
app:key="delete_image_cache"/>
<Preference <Preference
app:title="@string/settings_clear_downloads" app:title="@string/settings_clear_downloads"
@@ -46,16 +42,6 @@
app:title="@string/settings_use_hiyobi_title" app:title="@string/settings_use_hiyobi_title"
app:summary="@string/settings_use_hiyobi_summary"/> app:summary="@string/settings_use_hiyobi_summary"/>
<SwitchPreference
app:key="export_zip"
app:title="@string/settings_export_zip_title"
app:summary="@string/settings_export_zip_summary"/>
<SwitchPreference
app:key="auto_export"
app:title="@string/settings_auto_export_title"
app:summary="@string/settings_auto_export_summary"/>
<SwitchPreference <SwitchPreference
app:key="security_mode" app:key="security_mode"
app:title="@string/settings_security_mode_title" app:title="@string/settings_security_mode_title"

View File

@@ -80,7 +80,7 @@ fun getGalleryBlock(galleryID: Int) : GalleryBlock? {
val relatedTags = doc.select(".relatedtags a").map { val relatedTags = doc.select(".relatedtags a").map {
val href = URLDecoder.decode(it.attr("href"), "UTF-8") val href = URLDecoder.decode(it.attr("href"), "UTF-8")
href.slice(5 until href.indexOf('-')) href.slice(5 until href.indexOf("-all"))
} }
return GalleryBlock(galleryID, thumbnails, title, artists, series, type, language, relatedTags) return GalleryBlock(galleryID, thumbnails, title, artists, series, type, language, relatedTags)

View File

@@ -42,7 +42,7 @@ class UnitTest {
@Test @Test
fun test_getBlock() { fun test_getBlock() {
val galleryBlock = getGalleryBlock(1405716) val galleryBlock = getGalleryBlock(1428250)
print(galleryBlock) print(galleryBlock)
} }