Source settings

This commit is contained in:
tom5079
2021-05-18 10:39:35 +09:00
parent 5a19fb8336
commit dd60a1fdfb
27 changed files with 251 additions and 122 deletions

View File

@@ -237,7 +237,6 @@
android:pathPattern="/..*" />
</intent-filter>
</activity>
<activity android:name="net.rdrei.android.dirchooser.DirectoryChooserActivity" />
</application>
</manifest>

View File

@@ -65,9 +65,9 @@ class Pupil : Application(), DIAware {
import(androidXModule(this@Pupil))
import(sourceModule)
bind<OkHttpClient>() with provider { client }
bind<ImageCache>() with singleton { ImageCache(this@Pupil) }
bind<DownloadManager>() with singleton { DownloadManager(this@Pupil) }
bind { provider { client } }
bind { singleton { ImageCache(this@Pupil) } }
bind { singleton { DownloadManager(this@Pupil) } }
bind<SavedSourceSet>(tag = "histories") with singleton { SavedSourceSet(File(ContextCompat.getDataDir(this@Pupil), "histories.json")) }
bind<SavedSourceSet>(tag = "favorites") with singleton { SavedSourceSet(File(ContextCompat.getDataDir(this@Pupil), "favorites.json")) }
@@ -99,7 +99,7 @@ class Pupil : Application(), DIAware {
try {
Preferences.get<String>("download_folder").also {
if (it.startsWith("content") && Build.VERSION.SDK_INT > 19)
if (it.startsWith("content"))
contentResolver.takePersistableUriPermission(
Uri.parse(it),
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION

View File

@@ -93,16 +93,6 @@ class SearchResultsAdapter(var results: LiveData<List<ItemInfo>>) : RecyclerSwip
})
binding.tagGroup.onClickListener = onChipClickedHandler
/*
CoroutineScope(Dispatchers.Main).launch {
while (true) {
updateProgress()
delay(1000)
}
}
*/
}
private val controllerListener = object: BaseControllerListener<ImageInfo>() {
@@ -119,21 +109,6 @@ class SearchResultsAdapter(var results: LiveData<List<ItemInfo>>) : RecyclerSwip
}
}
private fun updateProgress() {
/* TODO
binding.root.max = cache.metadata.imageList?.size ?: 0
binding.root.progress = cache.metadata.imageList?.count { it != null } ?: 0
binding.root.type = if (cache.metadata.imageList?.all { it != null } == true) { // Download completed
if (DownloadManager.getInstance(itemView.context).getDownloadFolder(source, itemID) != null)
ProgressCardView.Type.DOWNLOAD
else
ProgressCardView.Type.CACHE
} else
ProgressCardView.Type.LOADING
*/
}
@SuppressLint("SetTextI18n")
fun bind(result: ItemInfo) {
source = result.source
@@ -210,7 +185,6 @@ class SearchResultsAdapter(var results: LiveData<List<ItemInfo>>) : RecyclerSwip
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
ViewHolder(SearchResultItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))
@ExperimentalTime
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
mItemManger.bindView(holder.itemView, position)
holder.bind(results.value!![position])

View File

@@ -30,6 +30,7 @@ import xyz.quaver.pupil.sources.SourceEntries
class SourceAdapter(sources: SourceEntries) : RecyclerView.Adapter<SourceAdapter.ViewHolder>() {
var onSourceSelectedListener: ((String) -> Unit)? = null
var onSourceSettingsSelectedListener: ((String) -> Unit)? = null
private val sources = sources.toList()
@@ -40,6 +41,9 @@ class SourceAdapter(sources: SourceEntries) : RecyclerView.Adapter<SourceAdapter
binding.go.setOnClickListener {
onSourceSelectedListener?.invoke(source.name)
}
binding.settings.setOnClickListener {
onSourceSettingsSelectedListener?.invoke(source.name)
}
}
fun bind(source: AnySource) {

View File

@@ -18,9 +18,6 @@
package xyz.quaver.pupil.sources
import android.content.Context
import android.graphics.drawable.Drawable
import androidx.core.content.ContextCompat
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.parcelize.Parcelize
@@ -120,6 +117,7 @@ typealias AnySource = Source<*, SearchSuggestion>
abstract class Source<Query_SortMode: Enum<Query_SortMode>, Suggestion: SearchSuggestion> {
abstract val name: String
abstract val iconResID: Int
abstract val preferenceID: Int
abstract val availableSortMode: Array<Query_SortMode>
abstract suspend fun search(query: String, range: IntRange, sortMode: Enum<*>) : Pair<Channel<ItemInfo>, Int>
@@ -138,15 +136,19 @@ abstract class Source<Query_SortMode: Enum<Query_SortMode>, Suggestion: SearchSu
typealias SourceEntry = Pair<String, AnySource>
typealias SourceEntries = Set<SourceEntry>
typealias PreferenceID = Pair<String, Int>
typealias PreferenceIDs = Set<PreferenceID>
@Suppress("UNCHECKED_CAST")
val sourceModule = DI.Module(name = "source") {
bind() from setBinding<SourceEntry>()
bindSet<SourceEntry>()
bindSet<PreferenceID>()
listOf(
Hitomi()
).forEach { source ->
bind<SourceEntry>().inSet() with multiton { _: Unit -> source.name to (source as AnySource) }
inSet { multiton { _: Unit -> source.name to (source as AnySource) } }
inSet { singleton { source.name to source.preferenceID } }
}
bind<History>() with factory { source: String -> History(di, source) }
bind { factory { source: String -> History(di, source) } }
}

View File

@@ -26,6 +26,7 @@ import org.kodein.di.DI
import org.kodein.di.DIAware
import org.kodein.di.instance
import xyz.quaver.floatingsearchview.suggestions.model.SearchSuggestion
import xyz.quaver.pupil.R
import xyz.quaver.pupil.util.SavedSourceSet
import xyz.quaver.pupil.util.source
@@ -38,6 +39,8 @@ class History(override val di: DI, source: String) : Source<DefaultSortMode, Sea
get() = source.name
override val iconResID: Int
get() = source.iconResID
override val preferenceID: Int
get() = source.preferenceID
override val availableSortMode: Array<DefaultSortMode> = DefaultSortMode.values()
override suspend fun search(query: String, range: IntRange, sortMode: Enum<*>): Pair<Channel<ItemInfo>, Int> {

View File

@@ -29,6 +29,7 @@ import xyz.quaver.floatingsearchview.suggestions.model.SearchSuggestion
import xyz.quaver.hitomi.*
import xyz.quaver.pupil.R
import xyz.quaver.pupil.sources.ItemInfo.ExtraType
import xyz.quaver.pupil.util.Preferences
import xyz.quaver.pupil.util.translations
import xyz.quaver.pupil.util.wordCapitalize
import kotlin.math.max
@@ -56,6 +57,7 @@ class Hitomi : Source<Hitomi.SortMode, Hitomi.TagSuggestion>() {
override val name: String = "hitomi.la"
override val iconResID: Int = R.drawable.hitomi
override val preferenceID: Int = R.xml.hitomi_preferences
override val availableSortMode: Array<SortMode> = SortMode.values()
var cachedQuery: String? = null
@@ -67,7 +69,7 @@ class Hitomi : Source<Hitomi.SortMode, Hitomi.TagSuggestion>() {
cachedQuery = null
cache.clear()
yield()
doSearch(query, sortMode == SortMode.POPULAR).let {
doSearch("$query ${Preferences["hitomi.default_query", ""]}", sortMode == SortMode.POPULAR).let {
yield()
cache.addAll(it)
}

View File

@@ -45,7 +45,7 @@ import com.google.android.material.snackbar.Snackbar
import com.orhanobut.logger.Logger
import kotlinx.coroutines.*
import org.kodein.di.DIAware
import org.kodein.di.android.di
import org.kodein.di.android.closestDI
import xyz.quaver.floatingsearchview.FloatingSearchView
import xyz.quaver.pupil.*
import xyz.quaver.pupil.adapters.SearchResultsAdapter
@@ -66,11 +66,13 @@ class MainActivity :
NavigationView.OnNavigationItemSelectedListener,
DIAware
{
override val di by di()
override val di by closestDI()
private lateinit var binding: MainActivityBinding
private val model: MainViewModel by viewModels()
private var refreshOnResume = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = MainActivityBinding.inflate(layoutInflater)
@@ -165,6 +167,15 @@ class MainActivity :
} }
}
override fun onResume() {
super.onResume()
if (refreshOnResume) {
model.query()
refreshOnResume = false
}
}
override fun onDestroy() {
super.onDestroy()
binding.contents.recyclerview.adapter = null
@@ -440,6 +451,13 @@ class MainActivity :
dismiss()
}
onSourceSettingsSelectedListener = {
startActivity(Intent(this@MainActivity, SettingsActivity::class.java).putExtra(SettingsActivity.SETTINGS_EXTRA, it))
refreshOnResume = true
dismiss()
}
}.show(supportFragmentManager, null)
}
}

View File

@@ -22,16 +22,27 @@ import android.os.Bundle
import android.view.MenuItem
import xyz.quaver.pupil.R
import xyz.quaver.pupil.ui.fragment.SettingsFragment
import xyz.quaver.pupil.ui.fragment.SourceSettingsFragment
class SettingsActivity : BaseActivity() {
companion object {
const val SETTINGS_EXTRA = "xyz.quaver.pupil.ui.SettingsActivity.SETTINGS_EXTRA"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.settings_activity)
val fragment = intent.getStringExtra(SETTINGS_EXTRA)?.run {
SourceSettingsFragment(this)
} ?: SettingsFragment()
supportFragmentManager
.beginTransaction()
.replace(R.id.settings, SettingsFragment())
.replace(R.id.settings, fragment)
.commit()
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}

View File

@@ -31,7 +31,7 @@ import xyz.quaver.pupil.sources.Hitomi
import xyz.quaver.pupil.types.Tags
import xyz.quaver.pupil.util.Preferences
class DefaultQueryDialogFragment() : DialogFragment() {
class DefaultQueryDialogFragment : DialogFragment() {
// TODO languageMap
private val languages = Hitomi.languageMap
private val reverseLanguages = languages.entries.associate { (k, v) -> v to k }
@@ -85,7 +85,7 @@ class DefaultQueryDialogFragment() : DialogFragment() {
private fun initView() {
val tags = Tags.parse(
Preferences["default_query"]
Preferences["hitomi.default_query"]
)
with (binding.languageSelector) {
@@ -153,7 +153,7 @@ class DefaultQueryDialogFragment() : DialogFragment() {
s.replace(
0,
s.length,
s.toString().toLowerCase(java.util.Locale.getDefault())
s.toString().lowercase()
)
}
})

View File

@@ -21,7 +21,6 @@ package xyz.quaver.pupil.ui.dialog
import android.app.Activity
import android.app.Dialog
import android.content.Intent
import android.os.Build
import android.os.Bundle
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
@@ -30,21 +29,21 @@ import androidx.core.net.toUri
import androidx.fragment.app.DialogFragment
import com.google.android.material.snackbar.Snackbar
import org.kodein.di.DIAware
import org.kodein.di.android.x.di
import org.kodein.di.android.x.closestDI
import org.kodein.di.instance
import xyz.quaver.io.FileX
import xyz.quaver.io.util.toFile
import xyz.quaver.pupil.R
import xyz.quaver.pupil.databinding.DownloadLocationDialogBinding
import xyz.quaver.pupil.databinding.DownloadLocationItemBinding
import xyz.quaver.pupil.util.DownloadManager
import xyz.quaver.pupil.util.Preferences
import xyz.quaver.pupil.util.byteToString
import xyz.quaver.pupil.util.DownloadManager
import java.io.File
class DownloadLocationDialogFragment : DialogFragment(), DIAware {
override val di by di()
override val di by closestDI()
private val downloadManager: DownloadManager by instance()

View File

@@ -41,7 +41,7 @@ import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import org.kodein.di.DIAware
import org.kodein.di.android.x.di
import org.kodein.di.android.x.closestDI
import org.kodein.di.instance
import xyz.quaver.pupil.R
import xyz.quaver.pupil.adapters.SearchResultsAdapter
@@ -60,7 +60,7 @@ import kotlin.collections.ArrayList
class GalleryDialogFragment(private val source: String, private val itemID: String) : DialogFragment(), DIAware {
override val di by di()
override val di by closestDI()
private val favoriteTags: SavedSourceSet by instance(tag = "favoriteTags")

View File

@@ -34,12 +34,14 @@ import xyz.quaver.pupil.adapters.SourceAdapter
import xyz.quaver.pupil.sources.AnySource
import xyz.quaver.pupil.sources.Source
import xyz.quaver.pupil.sources.SourceEntries
import xyz.quaver.pupil.util.ItemClickSupport
class SourceSelectDialog : DialogFragment(), DIAware {
override val di by closestDI()
var onSourceSelectedListener: ((String) -> Unit)? = null
var onSourceSettingsSelectedListener: ((String) -> Unit)? = null
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return Dialog(requireContext()).apply {
@@ -50,6 +52,7 @@ class SourceSelectDialog : DialogFragment(), DIAware {
layoutManager = LinearLayoutManager(context)
adapter = SourceAdapter(direct.instance()).apply {
onSourceSelectedListener = this@SourceSelectDialog.onSourceSelectedListener
onSourceSettingsSelectedListener = this@SourceSelectDialog.onSourceSettingsSelectedListener
}
})
}

View File

@@ -26,11 +26,8 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.*
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.kodein.di.DIAware
import org.kodein.di.android.x.di
import org.kodein.di.android.x.closestDI
import org.kodein.di.instance
import xyz.quaver.io.FileX
import xyz.quaver.io.util.getChild
@@ -39,7 +36,6 @@ import xyz.quaver.pupil.ui.LockActivity
import xyz.quaver.pupil.ui.SettingsActivity
import xyz.quaver.pupil.ui.dialog.*
import xyz.quaver.pupil.util.*
import xyz.quaver.pupil.util.DownloadManager
import java.util.*
class SettingsFragment :
@@ -49,7 +45,7 @@ class SettingsFragment :
SharedPreferences.OnSharedPreferenceChangeListener,
DIAware {
override val di by di()
override val di by closestDI()
private val downloadManager: DownloadManager by instance()
@@ -92,14 +88,6 @@ class SettingsFragment :
"download_folder" -> {
DownloadLocationDialogFragment().show(parentFragmentManager, "Download Location Dialog")
}
"default_query" -> {
DefaultQueryDialogFragment().apply {
onPositiveButtonClickListener = { newTags ->
Preferences["default_query"] = newTags.toString()
summary = newTags.toString()
}
}.show(parentFragmentManager, "Default Query Dialog")
}
"app_lock" -> {
val intent = Intent(requireContext(), LockActivity::class.java).apply {
putExtra("force", true)
@@ -127,9 +115,6 @@ class SettingsFragment :
this ?: return false
when (key) {
"tag_translation" -> {
updateTranslations()
}
"nomedia" -> {
val create = (newValue as? Boolean) ?: return false
@@ -228,11 +213,6 @@ class SettingsFragment :
onPreferenceChangeListener = this@SettingsFragment
}
"default_query" -> {
summary = Preferences.get<String>("default_query")
onPreferenceClickListener = this@SettingsFragment
}
"app_lock" -> {
val lockManager = LockManager(requireContext())
summary =
@@ -250,27 +230,6 @@ class SettingsFragment :
onPreferenceClickListener = this@SettingsFragment
}
"tag_translation" -> {
this as ListPreference
isEnabled = false
CoroutineScope(Dispatchers.IO).launch {
kotlin.runCatching {
val languages = getAvailableLanguages().distinct().toTypedArray()
entries = languages.map { Locale(it).let { loc -> loc.getDisplayLanguage(loc) } }.toTypedArray()
entryValues = languages
launch(Dispatchers.Main) {
isEnabled = true
}
}
}
onPreferenceChangeListener = this@SettingsFragment
}
"proxy" -> {
summary = getProxyInfo().type.name

View File

@@ -0,0 +1,130 @@
/*
* Pupil, Hitomi.la viewer for Android
* Copyright (C) 2021 tom5079
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package xyz.quaver.pupil.ui.fragment
import android.os.Bundle
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.kodein.di.DIAware
import org.kodein.di.android.x.closestDI
import org.kodein.di.direct
import org.kodein.di.instance
import xyz.quaver.pupil.sources.PreferenceIDs
import xyz.quaver.pupil.ui.dialog.DefaultQueryDialogFragment
import xyz.quaver.pupil.util.Preferences
import xyz.quaver.pupil.util.getAvailableLanguages
import xyz.quaver.pupil.util.updateTranslations
import java.util.*
class SourceSettingsFragment(private val source: String) :
PreferenceFragmentCompat(),
Preference.OnPreferenceClickListener,
Preference.OnPreferenceChangeListener,
DIAware {
override val di by closestDI()
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(direct.instance<PreferenceIDs>().toMap()[source]!!, rootKey)
initPreferences()
}
override fun onPreferenceClick(preference: Preference?): Boolean {
with (preference) {
this ?: return false
when (key) {
"hitomi.default_query" -> {
DefaultQueryDialogFragment().apply {
onPositiveButtonClickListener = { newTags ->
Preferences["hitomi.default_query"] = newTags.toString()
summary = newTags.toString()
}
}.show(parentFragmentManager, "Default Query Dialog")
}
}
}
return true
}
override fun onPreferenceChange(preference: Preference?, newValue: Any?): Boolean {
with (preference) {
this ?: return false
when (key) {
"hitomi.tag_translation" -> {
updateTranslations()
}
else -> return false
}
}
return true
}
private fun initPreferences() {
for (i in 0 until preferenceScreen.preferenceCount) {
preferenceScreen.getPreference(i).run {
if (this is PreferenceCategory)
(0 until preferenceCount).map { getPreference(it) }
else
listOf(this)
}.forEach { preference ->
with (preference) {
when (key) {
"hitomi.default_query" -> {
summary = Preferences.get<String>(key)
onPreferenceClickListener = this@SourceSettingsFragment
}
"hitomi.tag_translation" -> {
this as ListPreference
isEnabled = false
CoroutineScope(Dispatchers.IO).launch {
kotlin.runCatching {
val languages = getAvailableLanguages().distinct().toTypedArray()
entries = languages.map { Locale(it).let { loc -> loc.getDisplayLanguage(loc) } }.toTypedArray()
entryValues = languages
launch(Dispatchers.Main) {
isEnabled = true
}
}
}
onPreferenceChangeListener = this@SourceSettingsFragment
}
}
}
}
}
}
}

View File

@@ -74,7 +74,7 @@ class FloatingSearchView @JvmOverloads constructor(context: Context, attrs: Attr
s ?: return
if (s.any { it.isUpperCase() })
s.replace(0, s.length, s.toString().toLowerCase(Locale.getDefault()))
s.replace(0, s.length, s.toString().lowercase())
}
override fun onSuggestionClicked(searchSuggestion: SearchSuggestion?) {

View File

@@ -25,15 +25,14 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.*
import org.kodein.di.DIAware
import org.kodein.di.android.x.di
import org.kodein.di.instance
import org.kodein.di.android.x.closestDI
import xyz.quaver.pupil.sources.AnySource
import xyz.quaver.pupil.sources.ItemInfo
import xyz.quaver.pupil.util.source
class GalleryDialogViewModel(app: Application) : AndroidViewModel(app), DIAware {
override val di by di()
override val di by closestDI()
private val _info = MutableLiveData<ItemInfo>()
val info: LiveData<ItemInfo> = _info

View File

@@ -128,7 +128,7 @@ class MainViewModel(app: Application) : AndroidViewModel(app), DIAware {
queryJob = viewModelScope.launch {
val channel = withContext(Dispatchers.IO) {
val (channel, count) = source.search(
(query.value ?: "") + Preferences["default_query", ""],
query.value ?: "",
(currentPage - 1) * perPage until currentPage * perPage,
sortMode
)

View File

@@ -28,27 +28,24 @@ import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import org.kodein.di.DIAware
import org.kodein.di.android.di
import org.kodein.di.instance
import org.kodein.di.android.closestDI
import xyz.quaver.io.FileX
import xyz.quaver.io.util.*
import xyz.quaver.pupil.sources.AnySource
class DownloadManager constructor(context: Context) : ContextWrapper(context), DIAware {
override val di by di(context)
override val di by closestDI(context)
private val defaultDownloadFolder = FileX(this, getExternalFilesDir(null)!!)
val downloadFolder: FileX
get() = {
kotlin.runCatching {
FileX(this, Preferences.get<String>("download_folder"))
}.getOrElse {
Preferences["download_folder"] = defaultDownloadFolder.uri.toString()
defaultDownloadFolder
}
}.invoke()
get() = kotlin.runCatching {
FileX(this, Preferences.get<String>("download_folder"))
}.getOrElse {
Preferences["download_folder"] = defaultDownloadFolder.uri.toString()
defaultDownloadFolder
}
private var prevDownloadFolder: FileX? = null
private var downloadFolderMapInstance: MutableMap<String, String>? = null
@@ -57,21 +54,19 @@ class DownloadManager constructor(context: Context) : ContextWrapper(context), D
get() {
if (prevDownloadFolder != downloadFolder) {
prevDownloadFolder = downloadFolder
downloadFolderMapInstance = {
downloadFolderMapInstance = run {
val file = downloadFolder.getChild(".download")
val data = if (file.exists())
kotlin.runCatching {
file.readText()?.let { Json.decodeFromString<MutableMap<String, String>>(it) }
file.readText()?.let<String, MutableMap<String, String>> { Json.decodeFromString(it) }
}.onFailure { file.delete() }.getOrNull()
else
null
data ?: {
data ?: run {
file.createNewFile()
mutableMapOf<String, String>()
}.invoke()
}.invoke()
mutableMapOf()
}
}
}
return downloadFolderMapInstance ?: mutableMapOf()

View File

@@ -23,11 +23,11 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.sendBlocking
import kotlinx.coroutines.channels.trySendBlocking
import kotlinx.coroutines.coroutineScope
import okhttp3.*
import org.kodein.di.DIAware
import org.kodein.di.android.di
import org.kodein.di.android.closestDI
import org.kodein.di.instance
import java.io.File
import java.io.IOException
@@ -35,7 +35,7 @@ import java.util.*
import java.util.concurrent.ConcurrentHashMap
class ImageCache(context: Context) : DIAware {
override val di by di(context)
override val di by closestDI(context)
private val client: OkHttpClient by instance()
@@ -115,7 +115,7 @@ class ImageCache(context: Context) : DIAware {
file.createNewFile()
body.byteStream().copyTo(file.outputStream()) { bytes, _ ->
channel.sendBlocking(bytes / body.contentLength().toFloat() * 100)
channel.trySendBlocking(bytes / body.contentLength().toFloat() * 100)
}
}

View File

@@ -45,7 +45,7 @@ fun updateTranslations() = CoroutineScope(Dispatchers.IO).launch {
kotlin.runCatching {
translations = Json.decodeFromString<Map<String, String>>(client.newCall(
Request.Builder()
.url(contentURL + "${Preferences["tag_translation", ""].let { if (it.isEmpty()) Locale.getDefault().language else it }}.json")
.url(contentURL + "${Preferences["hitomi.tag_translation", ""].let { if (it.isEmpty()) Locale.getDefault().language else it }}.json")
.build()
).execute().also { if (it.code != 200) return@launch }.body?.use { it.string() } ?: return@launch).filterValues { it.isNotEmpty() }
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 B

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 B

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 311 B

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 432 B

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 605 B

After

Width:  |  Height:  |  Size: 0 B

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Pupil, Hitomi.la viewer for Android
~ Copyright (C) 2021 tom5079
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
<Preference
app:key="hitomi.default_query"
app:title="@string/settings_default_query"
app:useSimpleSummaryProvider="true"/>
<ListPreference
app:key="hitomi.tag_translation"
app:title="@string/settings_tag_translation"
app:useSimpleSummaryProvider="true"/>
</PreferenceScreen>