Added History
This commit is contained in:
1
.idea/codeStyles/Project.xml
generated
1
.idea/codeStyles/Project.xml
generated
@@ -18,6 +18,7 @@
|
|||||||
<package name="" alias="true" withSubpackages="true" />
|
<package name="" alias="true" withSubpackages="true" />
|
||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
|
<option name="ALLOW_TRAILING_COMMA" value="true" />
|
||||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
</JetCodeStyleSettings>
|
</JetCodeStyleSettings>
|
||||||
<codeStyleSettings language="XML">
|
<codeStyleSettings language="XML">
|
||||||
|
|||||||
5
.idea/jarRepositories.xml
generated
5
.idea/jarRepositories.xml
generated
@@ -81,5 +81,10 @@
|
|||||||
<option name="name" value="maven2" />
|
<option name="name" value="maven2" />
|
||||||
<option name="url" value="https://oss.sonatype.org/content/repositories/snapshots" />
|
<option name="url" value="https://oss.sonatype.org/content/repositories/snapshots" />
|
||||||
</remote-repository>
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="MavenLocal" />
|
||||||
|
<option name="name" value="MavenLocal" />
|
||||||
|
<option name="url" value="file:/$USER_HOME$/.m2/repository/" />
|
||||||
|
</remote-repository>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -134,9 +134,9 @@ dependencies {
|
|||||||
|
|
||||||
implementation "ru.noties.markwon:core:3.1.0"
|
implementation "ru.noties.markwon:core:3.1.0"
|
||||||
|
|
||||||
implementation "xyz.quaver:libpupil:1.9.7-SNAPSHOT"
|
implementation "xyz.quaver:libpupil:1.9.7"
|
||||||
implementation "xyz.quaver:documentfilex:0.4-alpha02"
|
implementation "xyz.quaver:documentfilex:0.4-alpha02"
|
||||||
implementation "xyz.quaver:floatingsearchview:1.1.1"
|
implementation "xyz.quaver:floatingsearchview:1.1.3-SNAPSHOT"
|
||||||
|
|
||||||
implementation "com.orhanobut:logger:2.2.0"
|
implementation "com.orhanobut:logger:2.2.0"
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class MirrorAdapter(context: Context) : RecyclerView.Adapter<MirrorAdapter.ViewH
|
|||||||
val list = mirrors.keys.toMutableList().apply {
|
val list = mirrors.keys.toMutableList().apply {
|
||||||
Preferences.get<String>("mirrors")
|
Preferences.get<String>("mirrors")
|
||||||
.split(">")
|
.split(">")
|
||||||
.reversed()
|
.asReversed()
|
||||||
.forEach {
|
.forEach {
|
||||||
if (this.contains(it)) {
|
if (this.contains(it)) {
|
||||||
this.remove(it)
|
this.remove(it)
|
||||||
|
|||||||
@@ -18,15 +18,12 @@
|
|||||||
|
|
||||||
package xyz.quaver.pupil.sources
|
package xyz.quaver.pupil.sources
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import com.orhanobut.logger.Logger
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.kodein.di.DI
|
import org.kodein.di.DI
|
||||||
import org.kodein.di.DIAware
|
import org.kodein.di.DIAware
|
||||||
import org.kodein.di.android.di
|
|
||||||
import org.kodein.di.instance
|
import org.kodein.di.instance
|
||||||
import xyz.quaver.floatingsearchview.suggestions.model.SearchSuggestion
|
import xyz.quaver.floatingsearchview.suggestions.model.SearchSuggestion
|
||||||
import xyz.quaver.pupil.util.SavedSourceSet
|
import xyz.quaver.pupil.util.SavedSourceSet
|
||||||
@@ -47,9 +44,11 @@ class History(override val di: DI, source: String) : Source<DefaultSortMode, Sea
|
|||||||
val channel = Channel<ItemInfo>()
|
val channel = Channel<ItemInfo>()
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
histories.map[source.name]?.forEach {
|
histories[source.name]?.asReversed()?.forEach {
|
||||||
channel.send(source.info(it))
|
channel.send(source.info(it))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
channel.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
return Pair(channel, histories.map.size)
|
return Pair(channel, histories.map.size)
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ class MainActivity :
|
|||||||
} else {
|
} else {
|
||||||
binding.contents.progressbar.hide()
|
binding.contents.progressbar.hide()
|
||||||
if (it.isEmpty()) {
|
if (it.isEmpty()) {
|
||||||
|
binding.contents.recyclerview.adapter?.notifyDataSetChanged()
|
||||||
binding.contents.noresult.show()
|
binding.contents.noresult.show()
|
||||||
} else {
|
} else {
|
||||||
binding.contents.recyclerview.adapter?.notifyItemInserted(it.size-1)
|
binding.contents.recyclerview.adapter?.notifyItemInserted(it.size-1)
|
||||||
@@ -396,7 +397,7 @@ class MainActivity :
|
|||||||
onActionMenuItemSelected(it)
|
onActionMenuItemSelected(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
onQueryChangeListener = lambda@{ _, query ->
|
onQueryChangeListener = { _, query ->
|
||||||
model.query.value = query
|
model.query.value = query
|
||||||
|
|
||||||
model.suggestion()
|
model.suggestion()
|
||||||
@@ -404,9 +405,7 @@ class MainActivity :
|
|||||||
swapSuggestions(listOf(LoadingSuggestion(getText(R.string.reader_loading).toString())))
|
swapSuggestions(listOf(LoadingSuggestion(getText(R.string.reader_loading).toString())))
|
||||||
}
|
}
|
||||||
|
|
||||||
onSuggestionBinding = { binding, item ->
|
onSuggestionBinding = model.source.value!!::onSuggestionBind
|
||||||
model.source.value!!.onSuggestionBind(binding, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
onFocusChangeListener = object: FloatingSearchView.OnFocusChangeListener {
|
onFocusChangeListener = object: FloatingSearchView.OnFocusChangeListener {
|
||||||
override fun onFocus() {
|
override fun onFocus() {
|
||||||
@@ -450,24 +449,13 @@ class MainActivity :
|
|||||||
binding.drawer.closeDrawers()
|
binding.drawer.closeDrawers()
|
||||||
|
|
||||||
when(item.itemId) {
|
when(item.itemId) {
|
||||||
R.id.main_drawer_history -> {
|
R.id.main_drawer_home -> model.setModeAndReset(MainViewModel.MainMode.SEARCH)
|
||||||
//model.setSourceAndReset(direct.instance<String, History>(arg = source.name))
|
R.id.main_drawer_history -> model.setModeAndReset(MainViewModel.MainMode.HISTORY)
|
||||||
}
|
R.id.main_drawer_help -> startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.help))))
|
||||||
R.id.main_drawer_help -> {
|
R.id.main_drawer_github -> startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.github))))
|
||||||
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.help))))
|
R.id.main_drawer_homepage -> startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.home_page))))
|
||||||
}
|
R.id.main_drawer_email -> startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.email))))
|
||||||
R.id.main_drawer_github -> {
|
R.id.main_drawer_kakaotalk -> startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.discord))))
|
||||||
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.github))))
|
|
||||||
}
|
|
||||||
R.id.main_drawer_homepage -> {
|
|
||||||
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.home_page))))
|
|
||||||
}
|
|
||||||
R.id.main_drawer_email -> {
|
|
||||||
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.email))))
|
|
||||||
}
|
|
||||||
R.id.main_drawer_kakaotalk -> {
|
|
||||||
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.discord))))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ class ReaderActivity : BaseActivity(), DIAware {
|
|||||||
menu?.forEach {
|
menu?.forEach {
|
||||||
when (it.itemId) {
|
when (it.itemId) {
|
||||||
R.id.reader_menu_favorite -> {
|
R.id.reader_menu_favorite -> {
|
||||||
if (favorites.map[source]?.contains(itemID) == true)
|
if (favorites[source]?.contains(itemID) == true)
|
||||||
(it.icon as Animatable).start()
|
(it.icon as Animatable).start()
|
||||||
}
|
}
|
||||||
R.id.source -> {
|
R.id.source -> {
|
||||||
@@ -160,7 +160,7 @@ class ReaderActivity : BaseActivity(), DIAware {
|
|||||||
val id = itemID
|
val id = itemID
|
||||||
val favorite = menu?.findItem(R.id.reader_menu_favorite) ?: return true
|
val favorite = menu?.findItem(R.id.reader_menu_favorite) ?: return true
|
||||||
|
|
||||||
if (favorites.map[source]?.contains(id) == true) {
|
if (favorites[source]?.contains(id) == true) {
|
||||||
favorites.remove(source, id)
|
favorites.remove(source, id)
|
||||||
favorite.icon = AnimatedVectorDrawableCompat.create(this, R.drawable.avd_star)
|
favorite.icon = AnimatedVectorDrawableCompat.create(this, R.drawable.avd_star)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class TagChip(context: Context, private val source: String, _tag: Tag) : Chip(co
|
|||||||
)
|
)
|
||||||
|
|
||||||
setOnCloseIconClickListener {
|
setOnCloseIconClickListener {
|
||||||
if (favoriteTags.map[source]?.contains(tag.toString()) == true) {
|
if (favoriteTags[source]?.contains(tag.toString()) == true) {
|
||||||
favoriteTags.remove(source, tag.toString())
|
favoriteTags.remove(source, tag.toString())
|
||||||
closeIcon = ContextCompat.getDrawable(context, R.drawable.ic_star_empty)
|
closeIcon = ContextCompat.getDrawable(context, R.drawable.ic_star_empty)
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,10 @@ import kotlinx.coroutines.*
|
|||||||
import org.kodein.di.DIAware
|
import org.kodein.di.DIAware
|
||||||
import org.kodein.di.android.x.di
|
import org.kodein.di.android.x.di
|
||||||
import org.kodein.di.direct
|
import org.kodein.di.direct
|
||||||
|
import org.kodein.di.instance
|
||||||
import xyz.quaver.floatingsearchview.suggestions.model.SearchSuggestion
|
import xyz.quaver.floatingsearchview.suggestions.model.SearchSuggestion
|
||||||
import xyz.quaver.pupil.sources.AnySource
|
import xyz.quaver.pupil.sources.AnySource
|
||||||
|
import xyz.quaver.pupil.sources.History
|
||||||
import xyz.quaver.pupil.sources.ItemInfo
|
import xyz.quaver.pupil.sources.ItemInfo
|
||||||
import xyz.quaver.pupil.util.Preferences
|
import xyz.quaver.pupil.util.Preferences
|
||||||
import xyz.quaver.pupil.util.notify
|
import xyz.quaver.pupil.util.notify
|
||||||
@@ -37,7 +39,6 @@ import kotlin.random.Random
|
|||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
class MainViewModel(app: Application) : AndroidViewModel(app), DIAware {
|
class MainViewModel(app: Application) : AndroidViewModel(app), DIAware {
|
||||||
|
|
||||||
override val di by di()
|
override val di by di()
|
||||||
|
|
||||||
private val _searchResults = MutableLiveData<MutableList<ItemInfo>>()
|
private val _searchResults = MutableLiveData<MutableList<ItemInfo>>()
|
||||||
@@ -51,6 +52,10 @@ class MainViewModel(app: Application) : AndroidViewModel(app), DIAware {
|
|||||||
val query = MutableLiveData<String>()
|
val query = MutableLiveData<String>()
|
||||||
private val queryStack = mutableListOf<String>()
|
private val queryStack = mutableListOf<String>()
|
||||||
|
|
||||||
|
private val defaultSourceFactory: (String) -> AnySource = {
|
||||||
|
direct.source(it)
|
||||||
|
}
|
||||||
|
private var sourceFactory: (String) -> AnySource = defaultSourceFactory
|
||||||
private val _source = MutableLiveData<AnySource>()
|
private val _source = MutableLiveData<AnySource>()
|
||||||
val source: LiveData<AnySource> = _source
|
val source: LiveData<AnySource> = _source
|
||||||
|
|
||||||
@@ -82,7 +87,7 @@ class MainViewModel(app: Application) : AndroidViewModel(app), DIAware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setSourceAndReset(sourceName: String) {
|
fun setSourceAndReset(sourceName: String) {
|
||||||
_source.value = direct.source(sourceName).also {
|
_source.value = sourceFactory(sourceName).also {
|
||||||
sortMode.value = it.availableSortMode.first()
|
sortMode.value = it.availableSortMode.first()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,6 +102,16 @@ class MainViewModel(app: Application) : AndroidViewModel(app), DIAware {
|
|||||||
query()
|
query()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setModeAndReset(mode: MainMode) {
|
||||||
|
sourceFactory = when (mode) {
|
||||||
|
MainMode.SEARCH -> defaultSourceFactory
|
||||||
|
MainMode.HISTORY -> { { direct.instance<String, History>(arg = it) } }
|
||||||
|
else -> return
|
||||||
|
}
|
||||||
|
|
||||||
|
setSourceAndReset(source.value!!.name)
|
||||||
|
}
|
||||||
|
|
||||||
fun query() {
|
fun query() {
|
||||||
val perPage = Preferences["per_page", "25"].toInt()
|
val perPage = Preferences["per_page", "25"].toInt()
|
||||||
val source = _source.value ?: error("Source is null")
|
val source = _source.value ?: error("Source is null")
|
||||||
@@ -181,4 +196,11 @@ class MainViewModel(app: Application) : AndroidViewModel(app), DIAware {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class MainMode {
|
||||||
|
SEARCH,
|
||||||
|
HISTORY,
|
||||||
|
DOWNLOADS,
|
||||||
|
FAVORITES
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -21,81 +21,14 @@ package xyz.quaver.pupil.util
|
|||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import kotlinx.serialization.ExperimentalSerializationApi
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
|
import kotlinx.serialization.builtins.ListSerializer
|
||||||
import kotlinx.serialization.builtins.MapSerializer
|
import kotlinx.serialization.builtins.MapSerializer
|
||||||
import kotlinx.serialization.builtins.SetSerializer
|
|
||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.Json.Default.decodeFromString
|
import kotlinx.serialization.json.Json.Default.decodeFromString
|
||||||
import kotlinx.serialization.serializer
|
import kotlinx.serialization.serializer
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class SavedSet <T: Any> (private val file: File, any: T, private val set: MutableSet<T> = mutableSetOf()) : MutableSet<T> by set {
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
@OptIn(ExperimentalSerializationApi::class)
|
|
||||||
val serializer: KSerializer<Set<T>> = SetSerializer(serializer(any::class.java) as KSerializer<T>)
|
|
||||||
|
|
||||||
init {
|
|
||||||
if (!file.exists()) {
|
|
||||||
save()
|
|
||||||
}
|
|
||||||
load()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
fun load() {
|
|
||||||
set.clear()
|
|
||||||
kotlin.runCatching {
|
|
||||||
decodeFromString(serializer, file.readText())
|
|
||||||
}.onSuccess {
|
|
||||||
set.addAll(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
fun save() {
|
|
||||||
file.parentFile?.mkdirs()
|
|
||||||
if (!file.exists())
|
|
||||||
file.createNewFile()
|
|
||||||
|
|
||||||
file.writeText(Json.encodeToString(serializer, set))
|
|
||||||
}
|
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
override fun add(element: T): Boolean {
|
|
||||||
set.remove(element)
|
|
||||||
|
|
||||||
return set.add(element).also {
|
|
||||||
save()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
override fun addAll(elements: Collection<T>): Boolean {
|
|
||||||
set.removeAll(elements)
|
|
||||||
|
|
||||||
return set.addAll(elements).also {
|
|
||||||
save()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
override fun remove(element: T): Boolean {
|
|
||||||
load()
|
|
||||||
|
|
||||||
return set.remove(element).also {
|
|
||||||
save()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
override fun clear() {
|
|
||||||
set.clear()
|
|
||||||
save()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class SavedMap <K: Any, V: Any> (private val file: File, anyKey: K, anyValue: V, private val map: MutableMap<K, V> = mutableMapOf()) : MutableMap<K, V> by map {
|
class SavedMap <K: Any, V: Any> (private val file: File, anyKey: K, anyValue: V, private val map: MutableMap<K, V> = mutableMapOf()) : MutableMap<K, V> by map {
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
@@ -172,11 +105,10 @@ class SavedMap <K: Any, V: Any> (private val file: File, anyKey: K, anyValue: V,
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SavedSourceSet(private val file: File) {
|
class SavedSourceSet(private val file: File) {
|
||||||
|
private val _map = mutableMapOf<String, MutableList<String>>()
|
||||||
|
val map: Map<String, List<String>> = _map
|
||||||
|
|
||||||
private val _map = mutableMapOf<String, MutableSet<String>>()
|
private val serializer = MapSerializer(String.serializer(), ListSerializer(String.serializer()))
|
||||||
val map: Map<String, Set<String>> = _map
|
|
||||||
|
|
||||||
private val serializer = MapSerializer(String.serializer(), SetSerializer(String.serializer()))
|
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun load() {
|
fun load() {
|
||||||
@@ -185,7 +117,7 @@ class SavedSourceSet(private val file: File) {
|
|||||||
decodeFromString(serializer, file.readText())
|
decodeFromString(serializer, file.readText())
|
||||||
}.onSuccess {
|
}.onSuccess {
|
||||||
it.forEach { (k, v) ->
|
it.forEach { (k, v) ->
|
||||||
_map[k] = v.toMutableSet()
|
_map[k] = v.toMutableList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,6 +131,8 @@ class SavedSourceSet(private val file: File) {
|
|||||||
file.writeText(Json.encodeToString(serializer, _map))
|
file.writeText(Json.encodeToString(serializer, _map))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator fun get(key: String) = _map[key]
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun add(source: String, value: String) {
|
fun add(source: String, value: String) {
|
||||||
load()
|
load()
|
||||||
@@ -206,7 +140,7 @@ class SavedSourceSet(private val file: File) {
|
|||||||
_map[source]?.remove(value)
|
_map[source]?.remove(value)
|
||||||
|
|
||||||
if (!_map.containsKey(source))
|
if (!_map.containsKey(source))
|
||||||
_map[source] = mutableSetOf()
|
_map[source] = mutableListOf()
|
||||||
else
|
else
|
||||||
_map[source]!!.add(value)
|
_map[source]!!.add(value)
|
||||||
|
|
||||||
@@ -222,7 +156,7 @@ class SavedSourceSet(private val file: File) {
|
|||||||
_map[source]!!.removeAll(from[source]!!)
|
_map[source]!!.removeAll(from[source]!!)
|
||||||
_map[source]!!.addAll(from[source]!!)
|
_map[source]!!.addAll(from[source]!!)
|
||||||
} else {
|
} else {
|
||||||
_map[source] = from[source]!!.toMutableSet()
|
_map[source] = from[source]!!.toMutableList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
<!--
|
||||||
|
~ 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/>.
|
||||||
|
-->
|
||||||
|
|
||||||
<!--drawable/clock_end.xml-->
|
<!--drawable/clock_end.xml-->
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
<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="#fff" android:pathData="M12 1C8.14 1 5 4.14 5 8a7 7 0 0 0 7 7c3.86 0 7-3.13 7-7 0-3.86-3.14-7-7-7m0 2.15c2.67 0 4.85 2.17 4.85 4.85 0 2.68-2.18 4.85-4.85 4.85A4.85 4.85 0 0 1 7.15 8 4.85 4.85 0 0 1 12 3.15M11 5v3.69l3.19 1.84 0.75-1.3-2.44-1.41V5M15 16v3H3v2h12v3l4-4m0 0v4h2v-8h-2"/>
|
<path android:fillColor="#fff" android:pathData="M12 1C8.14 1 5 4.14 5 8a7 7 0 0 0 7 7c3.86 0 7-3.13 7-7 0-3.86-3.14-7-7-7m0 2.15c2.67 0 4.85 2.17 4.85 4.85 0 2.68-2.18 4.85-4.85 4.85A4.85 4.85 0 0 1 7.15 8 4.85 4.85 0 0 1 12 3.15M11 5v3.69l3.19 1.84 0.75-1.3-2.44-1.41V5M15 16v3H3v2h12v3l4-4m0 0v4h2v-8h-2"/>
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
<!--
|
||||||
|
~ 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/>.
|
||||||
|
-->
|
||||||
|
|
||||||
<!--drawable/clock_start.xml-->
|
<!--drawable/clock_start.xml-->
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
<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="#fff" android:pathData="M12 1C8.14 1 5 4.14 5 8a7 7 0 0 0 7 7c3.86 0 7-3.13 7-7 0-3.86-3.14-7-7-7m0 2.15c2.67 0 4.85 2.17 4.85 4.85 0 2.68-2.18 4.85-4.85 4.85A4.85 4.85 0 0 1 7.15 8 4.85 4.85 0 0 1 12 3.15M11 5v3.69l3.19 1.84 0.75-1.3-2.44-1.41V5M4 16v8h2v-3h12v3l4-4-4-4v3H6v-3"/>
|
<path android:fillColor="#fff" android:pathData="M12 1C8.14 1 5 4.14 5 8a7 7 0 0 0 7 7c3.86 0 7-3.13 7-7 0-3.86-3.14-7-7-7m0 2.15c2.67 0 4.85 2.17 4.85 4.85 0 2.68-2.18 4.85-4.85 4.85A4.85 4.85 0 0 1 7.15 8 4.85 4.85 0 0 1 12 3.15M11 5v3.69l3.19 1.84 0.75-1.3-2.44-1.41V5M4 16v8h2v-3h12v3l4-4-4-4v3H6v-3"/>
|
||||||
|
|||||||
@@ -19,24 +19,4 @@
|
|||||||
<item>SOCKS</item>
|
<item>SOCKS</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="cache_size">
|
|
||||||
<item>0</item>
|
|
||||||
<item>1</item>
|
|
||||||
<item>2</item>
|
|
||||||
<item>4</item>
|
|
||||||
<item>8</item>
|
|
||||||
<item>16</item>
|
|
||||||
<item>32</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<string-array name="cache_size_text">
|
|
||||||
<item>@string/settings_cache_unlimited</item>
|
|
||||||
<item>1G</item>
|
|
||||||
<item>2G</item>
|
|
||||||
<item>4G</item>
|
|
||||||
<item>8G</item>
|
|
||||||
<item>16G</item>
|
|
||||||
<item>32G</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -13,7 +13,7 @@ buildscript {
|
|||||||
classpath "com.google.gms:google-services:4.3.5"
|
classpath "com.google.gms:google-services:4.3.5"
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
classpath "com.google.firebase:firebase-crashlytics-gradle:2.4.1"
|
classpath "com.google.firebase:firebase-crashlytics-gradle:2.5.0"
|
||||||
classpath "com.google.firebase:perf-plugin:1.3.4"
|
classpath "com.google.firebase:perf-plugin:1.3.4"
|
||||||
classpath "com.google.android.gms:oss-licenses-plugin:0.10.2"
|
classpath "com.google.android.gms:oss-licenses-plugin:0.10.2"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user