@@ -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
1
app/release/output.json
Normal 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":{}}]
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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 ->
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
|
||||||
val autoExport = preference.getBoolean("auto_export", false)
|
|
||||||
|
|
||||||
if (autoExport) {
|
|
||||||
export({
|
|
||||||
notificationManager.notify(galleryBlock.id, notificationBuilder.build())
|
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
14
app/src/main/java/xyz/quaver/pupil/util/file.kt
Normal file
14
app/src/main/java/xyz/quaver/pupil/util/file.kt
Normal 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
app/src/main/res/drawable/ic_message.xml
Normal file
8
app/src/main/res/drawable/ic_message.xml
Normal 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>
|
||||||
8
app/src/main/res/drawable/ic_numeric.xml
Normal file
8
app/src/main/res/drawable/ic_numeric.xml
Normal 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>
|
||||||
@@ -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"
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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=""
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user