Bug fixed
2
.idea/misc.xml
generated
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/classes" />
|
<output url="file://$PROJECT_DIR$/classes" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -9,8 +9,8 @@ android {
|
|||||||
applicationId "xyz.quaver.pupil"
|
applicationId "xyz.quaver.pupil"
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
versionCode 3
|
versionCode 4
|
||||||
versionName "1.2"
|
versionName "1.3"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
package="xyz.quaver.pupil">
|
package="xyz.quaver.pupil">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
|
||||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
|||||||
@@ -1,26 +1,15 @@
|
|||||||
package xyz.quaver.pupil
|
package xyz.quaver.pupil
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.app.DownloadManager
|
|
||||||
import android.content.BroadcastReceiver
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
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
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.app.ActivityCompat
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.core.content.FileProvider
|
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.core.view.GravityCompat
|
import androidx.core.view.GravityCompat
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
@@ -38,17 +27,18 @@ import ru.noties.markwon.Markwon
|
|||||||
import xyz.quaver.hitomi.*
|
import xyz.quaver.hitomi.*
|
||||||
import xyz.quaver.pupil.adapters.GalleryBlockAdapter
|
import xyz.quaver.pupil.adapters.GalleryBlockAdapter
|
||||||
import xyz.quaver.pupil.types.TagSuggestion
|
import xyz.quaver.pupil.types.TagSuggestion
|
||||||
import xyz.quaver.pupil.util.*
|
import xyz.quaver.pupil.util.Histories
|
||||||
|
import xyz.quaver.pupil.util.ItemClickSupport
|
||||||
|
import xyz.quaver.pupil.util.SetLineOverlap
|
||||||
|
import xyz.quaver.pupil.util.checkUpdate
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.lang.Exception
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.net.ssl.HttpsURLConnection
|
import javax.net.ssl.HttpsURLConnection
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private val permissionRequestCode = 4585
|
|
||||||
private val galleries = ArrayList<Pair<GalleryBlock, Deferred<String>>>()
|
private val galleries = ArrayList<Pair<GalleryBlock, Deferred<String>>>()
|
||||||
|
|
||||||
private var query = ""
|
private var query = ""
|
||||||
@@ -67,8 +57,6 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
|
|
||||||
checkPermission()
|
|
||||||
|
|
||||||
checkUpdate()
|
checkUpdate()
|
||||||
|
|
||||||
main_appbar_layout.addOnOffsetChangedListener(
|
main_appbar_layout.addOnOffsetChangedListener(
|
||||||
@@ -99,17 +87,33 @@ class MainActivity : AppCompatActivity() {
|
|||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
main_drawer_layout.closeDrawers()
|
main_drawer_layout.closeDrawers()
|
||||||
|
|
||||||
cancelFetch()
|
|
||||||
clearGalleries()
|
|
||||||
when(it.itemId) {
|
when(it.itemId) {
|
||||||
R.id.main_drawer_home -> {
|
R.id.main_drawer_home -> {
|
||||||
|
cancelFetch()
|
||||||
|
clearGalleries()
|
||||||
query = query.replace("HISTORY", "")
|
query = query.replace("HISTORY", "")
|
||||||
fetchGalleries(query)
|
fetchGalleries(query)
|
||||||
}
|
}
|
||||||
R.id.main_drawer_history -> {
|
R.id.main_drawer_history -> {
|
||||||
|
cancelFetch()
|
||||||
|
clearGalleries()
|
||||||
query += "HISTORY"
|
query += "HISTORY"
|
||||||
fetchGalleries(query)
|
fetchGalleries(query)
|
||||||
}
|
}
|
||||||
|
R.id.main_drawer_help -> {
|
||||||
|
|
||||||
|
}
|
||||||
|
R.id.main_drawer_github -> {
|
||||||
|
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.github))))
|
||||||
|
}
|
||||||
|
R.id.main_drawer_homepage -> {
|
||||||
|
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.home_page))))
|
||||||
|
}
|
||||||
|
R.id.main_drawer_email -> {
|
||||||
|
AlertDialog.Builder(this@MainActivity).apply {
|
||||||
|
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
loadBlocks()
|
loadBlocks()
|
||||||
}
|
}
|
||||||
@@ -142,23 +146,6 @@ class MainActivity : AppCompatActivity() {
|
|||||||
super.onResume()
|
super.onResume()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkPermission() {
|
|
||||||
val permissions = arrayOf(
|
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
|
||||||
)
|
|
||||||
|
|
||||||
if (permissions.any { ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED }) {
|
|
||||||
if (permissions.any { ActivityCompat.shouldShowRequestPermissionRationale(this, it) })
|
|
||||||
AlertDialog.Builder(this).apply {
|
|
||||||
setTitle(R.string.warning)
|
|
||||||
setMessage(R.string.permission_explain)
|
|
||||||
setPositiveButton(android.R.string.ok) { _, _ -> }
|
|
||||||
}.show()
|
|
||||||
else
|
|
||||||
ActivityCompat.requestPermissions(this, permissions, permissionRequestCode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkUpdate() {
|
private fun checkUpdate() {
|
||||||
|
|
||||||
fun extractReleaseNote(update: JsonObject, locale: String) : String {
|
fun extractReleaseNote(update: JsonObject, locale: String) : String {
|
||||||
@@ -179,7 +166,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
val result = StringBuilder()
|
val result = StringBuilder()
|
||||||
|
|
||||||
for(line in markdown.split('\n')) {
|
for(line in markdown.lines()) {
|
||||||
if (releaseNote.matches(line)) {
|
if (releaseNote.matches(line)) {
|
||||||
releaseNoteFlag = true
|
releaseNoteFlag = true
|
||||||
continue
|
continue
|
||||||
@@ -203,57 +190,16 @@ class MainActivity : AppCompatActivity() {
|
|||||||
return getString(R.string.update_release_note, update["tag_name"]?.content, result.toString())
|
return getString(R.string.update_release_note, update["tag_name"]?.content, result.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
|
|
||||||
return
|
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.Default).launch {
|
CoroutineScope(Dispatchers.Default).launch {
|
||||||
val update =
|
val update =
|
||||||
checkUpdate(getString(R.string.release_url), BuildConfig.VERSION_NAME) ?: return@launch
|
checkUpdate(getString(R.string.release_url), BuildConfig.VERSION_NAME) ?: return@launch
|
||||||
|
|
||||||
val (url, fileName) = getApkUrl(update, getString(R.string.release_name)) ?: return@launch
|
|
||||||
|
|
||||||
val dialog = AlertDialog.Builder(this@MainActivity).apply {
|
val dialog = AlertDialog.Builder(this@MainActivity).apply {
|
||||||
setTitle(R.string.update_title)
|
setTitle(R.string.update_title)
|
||||||
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) { _, _ ->
|
||||||
Toast.makeText(
|
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.home_page))))
|
||||||
context, getString(R.string.update_download_started), Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
|
|
||||||
val dest = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName)
|
|
||||||
val desturi =
|
|
||||||
FileProvider.getUriForFile(
|
|
||||||
applicationContext,
|
|
||||||
"xyz.quaver.pupil.provider",
|
|
||||||
dest
|
|
||||||
)
|
|
||||||
|
|
||||||
if (dest.exists())
|
|
||||||
dest.delete()
|
|
||||||
|
|
||||||
val request = DownloadManager.Request(Uri.parse(url)).apply {
|
|
||||||
setDescription(getString(R.string.update_notification_description))
|
|
||||||
setTitle(getString(R.string.app_name))
|
|
||||||
setDestinationUri(Uri.fromFile(dest))
|
|
||||||
setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
|
|
||||||
}
|
|
||||||
|
|
||||||
val manager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
|
|
||||||
val id = manager.enqueue(request)
|
|
||||||
|
|
||||||
registerReceiver(object: BroadcastReceiver() {
|
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
|
||||||
val install = Intent(Intent.ACTION_VIEW).apply {
|
|
||||||
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_GRANT_READ_URI_PERMISSION
|
|
||||||
setDataAndType(desturi, manager.getMimeTypeForDownloadedFile(id))
|
|
||||||
}
|
|
||||||
|
|
||||||
startActivity(install)
|
|
||||||
unregisterReceiver(this)
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
|
|
||||||
}
|
}
|
||||||
setNegativeButton(android.R.string.no) { _, _ ->}
|
setNegativeButton(android.R.string.no) { _, _ ->}
|
||||||
}
|
}
|
||||||
@@ -404,11 +350,13 @@ class MainActivity : AppCompatActivity() {
|
|||||||
if (query != this@MainActivity.query) {
|
if (query != this@MainActivity.query) {
|
||||||
this@MainActivity.query = query
|
this@MainActivity.query = query
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
cancelFetch()
|
cancelFetch()
|
||||||
clearGalleries()
|
clearGalleries()
|
||||||
fetchGalleries(query)
|
fetchGalleries(query)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
attachNavigationDrawerToMenuButton(main_drawer_layout)
|
attachNavigationDrawerToMenuButton(main_drawer_layout)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package xyz.quaver.pupil
|
package xyz.quaver.pupil
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
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
|
||||||
@@ -112,13 +113,13 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
when(item?.itemId) {
|
when(item?.itemId) {
|
||||||
R.id.reader_menu_page_indicator -> {
|
R.id.reader_menu_page_indicator -> {
|
||||||
val view = LayoutInflater.from(this).inflate(R.layout.dialog_numberpicker, findViewById(android.R.id.content), false)
|
val view = LayoutInflater.from(this).inflate(R.layout.dialog_numberpicker, findViewById(android.R.id.content), false)
|
||||||
val dialog = AlertDialog.Builder(this).apply {
|
|
||||||
setView(view)
|
|
||||||
with(view.reader_dialog_number_picker) {
|
with(view.reader_dialog_number_picker) {
|
||||||
minValue=1
|
minValue=1
|
||||||
maxValue=gallerySize
|
maxValue=gallerySize
|
||||||
value=currentPage
|
value=currentPage
|
||||||
}
|
}
|
||||||
|
val dialog = AlertDialog.Builder(this).apply {
|
||||||
|
setView(view)
|
||||||
}.create()
|
}.create()
|
||||||
view.reader_dialog_ok.setOnClickListener {
|
view.reader_dialog_ok.setOnClickListener {
|
||||||
(reader_recyclerview.layoutManager as LinearLayoutManager?)?.scrollToPositionWithOffset(view.reader_dialog_number_picker.value-1, 0)
|
(reader_recyclerview.layoutManager as LinearLayoutManager?)?.scrollToPositionWithOffset(view.reader_dialog_number_picker.value-1, 0)
|
||||||
@@ -182,7 +183,7 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
reader_recyclerview.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
reader_recyclerview.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
(reader_recyclerview.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(currentPage, 0)
|
(reader_recyclerview.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(currentPage-1, 0)
|
||||||
|
|
||||||
preferences.edit().putBoolean("reader_one_by_one", !oneByOne).apply()
|
preferences.edit().putBoolean("reader_one_by_one", !oneByOne).apply()
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,22 @@ package xyz.quaver.pupil
|
|||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.preference.PreferenceManager
|
import android.preference.PreferenceManager
|
||||||
|
import android.text.Editable
|
||||||
|
import android.text.TextWatcher
|
||||||
|
import android.view.LayoutInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
import android.view.View
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
|
import android.widget.AdapterView
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
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.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
import kotlinx.android.synthetic.main.dialog_default_query.*
|
||||||
|
import kotlinx.android.synthetic.main.dialog_default_query.view.*
|
||||||
|
import xyz.quaver.pupil.types.Tags
|
||||||
import xyz.quaver.pupil.util.Histories
|
import xyz.quaver.pupil.util.Histories
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -109,6 +119,120 @@ class SettingsActivity : AppCompatActivity() {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
with(findPreference<Preference>("default_query")) {
|
||||||
|
this ?: return@with
|
||||||
|
|
||||||
|
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
|
|
||||||
|
summary = preferences.getString("default_query", "") ?: ""
|
||||||
|
|
||||||
|
val languages = resources.getStringArray(R.array.languages).map {
|
||||||
|
it.split("|").let { split ->
|
||||||
|
Pair(split[0], split[1])
|
||||||
|
}
|
||||||
|
}.toMap()
|
||||||
|
val reverseLanguages = languages.entries.associate { (k, v) -> v to k }
|
||||||
|
|
||||||
|
val excludeBL = "-male:yaoi"
|
||||||
|
val excludeGuro = listOf("-female:guro", "-male:guro")
|
||||||
|
|
||||||
|
setOnPreferenceClickListener {
|
||||||
|
val dialogView = LayoutInflater.from(context).inflate(
|
||||||
|
R.layout.dialog_default_query,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
|
val tags = Tags.parse(
|
||||||
|
preferences.getString("default_query", "") ?: ""
|
||||||
|
)
|
||||||
|
|
||||||
|
summary = tags.toString()
|
||||||
|
|
||||||
|
with(dialogView.default_query_dialog_language_selector) {
|
||||||
|
adapter =
|
||||||
|
ArrayAdapter<String>(
|
||||||
|
context,
|
||||||
|
android.R.layout.simple_spinner_dropdown_item,
|
||||||
|
arrayListOf(
|
||||||
|
getString(R.string.default_query_dialog_language_selector_none)
|
||||||
|
).apply {
|
||||||
|
addAll(languages.values)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (tags.any { it.area == "language" }) {
|
||||||
|
val tag = languages[tags.first { it.area == "language" }.tag]
|
||||||
|
if (tag != null) {
|
||||||
|
setSelection(
|
||||||
|
(adapter as ArrayAdapter<String>).getPosition(tag)
|
||||||
|
)
|
||||||
|
tags.removeByArea("language")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
with(dialogView.default_query_dialog_BL_checkbox) {
|
||||||
|
isChecked = tags.contains(excludeBL)
|
||||||
|
if (tags.contains(excludeBL))
|
||||||
|
tags.remove(excludeBL)
|
||||||
|
}
|
||||||
|
|
||||||
|
with(dialogView.default_query_dialog_guro_checkbox) {
|
||||||
|
isChecked = excludeGuro.all { tags.contains(it) }
|
||||||
|
if (excludeGuro.all { tags.contains(it) })
|
||||||
|
excludeGuro.forEach {
|
||||||
|
tags.remove(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
with(dialogView.default_query_dialog_edittext) {
|
||||||
|
setText(tags.toString(), TextView.BufferType.EDITABLE)
|
||||||
|
addTextChangedListener(object : TextWatcher {
|
||||||
|
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
|
||||||
|
|
||||||
|
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
|
||||||
|
|
||||||
|
override fun afterTextChanged(s: Editable?) {
|
||||||
|
s ?: return
|
||||||
|
|
||||||
|
if (s.any { it.isUpperCase() })
|
||||||
|
s.replace(0, s.length, s.toString().toLowerCase())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
val dialog = AlertDialog.Builder(context!!).apply {
|
||||||
|
setView(dialogView)
|
||||||
|
}.create()
|
||||||
|
|
||||||
|
dialogView.default_query_dialog_ok.setOnClickListener {
|
||||||
|
val newTags = Tags.parse(dialogView.default_query_dialog_edittext.text.toString())
|
||||||
|
|
||||||
|
with(dialogView.default_query_dialog_language_selector) {
|
||||||
|
if (selectedItemPosition != 0)
|
||||||
|
newTags.add("language:${reverseLanguages[selectedItem]}")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogView.default_query_dialog_BL_checkbox.isChecked)
|
||||||
|
newTags.add(excludeBL)
|
||||||
|
|
||||||
|
if (dialogView.default_query_dialog_guro_checkbox.isChecked)
|
||||||
|
excludeGuro.forEach { tag ->
|
||||||
|
newTags.add(tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
preferenceManager.sharedPreferences.edit().putString("default_query", newTags.toString()).apply()
|
||||||
|
summary = preferences.getString("default_query", "") ?: ""
|
||||||
|
tags.clear()
|
||||||
|
tags.addAll(newTags)
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.show()
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
96
app/src/main/java/xyz/quaver/pupil/types/Tags.kt
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
package xyz.quaver.pupil.types
|
||||||
|
|
||||||
|
data class Tag(val area: String?, val tag: String, val isNegative: Boolean = false) {
|
||||||
|
companion object {
|
||||||
|
fun parseTag(tag: String) : Tag {
|
||||||
|
if (tag.first() == '-') {
|
||||||
|
tag.substring(1).split(Regex(":"), 2).let {
|
||||||
|
return when(it.size) {
|
||||||
|
2 -> Tag(it[0], it[1], true)
|
||||||
|
else -> Tag(null, tag, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tag.split(Regex(":"), 2).let {
|
||||||
|
return when(it.size) {
|
||||||
|
2 -> Tag(it[0], it[1])
|
||||||
|
else -> Tag(null, tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return (if (isNegative) "-" else "") + when(area) {
|
||||||
|
null -> tag
|
||||||
|
else -> "$area:$tag"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (other !is Tag)
|
||||||
|
return false
|
||||||
|
|
||||||
|
if (other.area == area && other.tag == tag)
|
||||||
|
return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return super.hashCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Tags(tag: List<Tag?>?) : ArrayList<Tag>() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun parse(tags: String) : Tags {
|
||||||
|
return Tags(
|
||||||
|
tags.split(' ').map {
|
||||||
|
if (it.isNotEmpty())
|
||||||
|
Tag.parseTag(it)
|
||||||
|
else
|
||||||
|
null
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
tag?.forEach {
|
||||||
|
if (it != null)
|
||||||
|
add(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun contains(element: String): Boolean {
|
||||||
|
forEach {
|
||||||
|
if (it.toString() == element)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(element: String): Boolean {
|
||||||
|
return super.add(Tag.parseTag(element))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun remove(element: String) {
|
||||||
|
filter { it.toString() == element }.forEach {
|
||||||
|
remove(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeByArea(area: String) {
|
||||||
|
filter { it.area == area }.forEach {
|
||||||
|
remove(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return joinToString(" ") { it.toString() }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,12 +20,3 @@ fun checkUpdate(url: String, currentVersion: String) : JsonObject? {
|
|||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getApkUrl(releases: JsonObject, releaseName: String) : Pair<String?, String?>? {
|
|
||||||
releases["assets"]?.jsonArray?.forEach {
|
|
||||||
if (Regex(releaseName).matches(it.jsonObject["name"]?.content ?: ""))
|
|
||||||
return Pair(it.jsonObject["browser_download_url"]?.content, it.jsonObject["name"]?.content)
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
10
app/src/main/res/drawable-anydpi/ic_email.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="#333333">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M20,4L4,4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM20,8l-8,5 -8,-5L4,6l8,5 8,-5v2z"/>
|
||||||
|
</vector>
|
||||||
10
app/src/main/res/drawable-anydpi/ic_help.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="#333333">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z"/>
|
||||||
|
</vector>
|
||||||
BIN
app/src/main/res/drawable-hdpi/ic_email.png
Normal file
|
After Width: | Height: | Size: 325 B |
BIN
app/src/main/res/drawable-hdpi/ic_help.png
Normal file
|
After Width: | Height: | Size: 571 B |
BIN
app/src/main/res/drawable-mdpi/ic_email.png
Normal file
|
After Width: | Height: | Size: 235 B |
BIN
app/src/main/res/drawable-mdpi/ic_help.png
Normal file
|
After Width: | Height: | Size: 345 B |
BIN
app/src/main/res/drawable-xhdpi/ic_email.png
Normal file
|
After Width: | Height: | Size: 383 B |
BIN
app/src/main/res/drawable-xhdpi/ic_help.png
Normal file
|
After Width: | Height: | Size: 676 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_email.png
Normal file
|
After Width: | Height: | Size: 550 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_help.png
Normal file
|
After Width: | Height: | Size: 1000 B |
111
app/src/main/res/layout/dialog_default_query.xml
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/default_query_dialog_title"
|
||||||
|
style="@style/TextAppearance.AppCompat.Large"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/default_query_dialog_title"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
tools:ignore="Autofill"
|
||||||
|
android:inputType="text"
|
||||||
|
android:hint="@string/settings_default_query"
|
||||||
|
android:id="@+id/default_query_dialog_edittext"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/default_query_dialog_title"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/default_query_dialog_language_layout"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/default_query_dialog_edittext"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/default_query_dialog_language"/>
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/default_query_dialog_language_selector"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/default_query_dialog_BL_layout"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingLeft="0dp"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="8dp"
|
||||||
|
android:paddingRight="8dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/default_query_dialog_language_layout"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/default_query_dialog_filter_BL"/>
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/default_query_dialog_BL_checkbox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/default_query_dialog_guro_layout"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingLeft="0dp"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="8dp"
|
||||||
|
android:paddingRight="8dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/default_query_dialog_BL_layout"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/default_query_dialog_filter_guro"/>
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/default_query_dialog_guro_checkbox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/default_query_dialog_ok"
|
||||||
|
style="?borderlessButtonStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/default_query_dialog_guro_layout"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
android:text="@android:string/ok"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -12,4 +12,21 @@
|
|||||||
android:icon="@drawable/ic_history"/>
|
android:icon="@drawable/ic_history"/>
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
|
<item android:title="@string/main_drawer_group_contact_title">
|
||||||
|
<menu>
|
||||||
|
<item android:id="@+id/main_drawer_help"
|
||||||
|
android:title="@string/main_drawer_group_contact_help"
|
||||||
|
android:icon="@drawable/ic_help"/>
|
||||||
|
<item android:id="@+id/main_drawer_github"
|
||||||
|
android:title="@string/main_drawer_group_contact_github"
|
||||||
|
android:icon="@drawable/github_circle"/>
|
||||||
|
<item android:id="@+id/main_drawer_homepage"
|
||||||
|
android:title="@string/main_drawer_group_contact_homepage"
|
||||||
|
android:icon="@drawable/ic_home"/>
|
||||||
|
<item android:id="@+id/main_drawer_email"
|
||||||
|
android:title="@string/main_drawer_group_contact_email"
|
||||||
|
android:icon="@drawable/ic_email"/>
|
||||||
|
</menu>
|
||||||
|
</item>
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
<string name="settings_clear_image_cache">イメージキャッシュクリア</string>
|
<string name="settings_clear_image_cache">イメージキャッシュクリア</string>
|
||||||
<string name="settings_clear_cache_alert_message">キャッシュをクリアするとイメージのロード速度に影響を与えます。実行しますか?</string>
|
<string name="settings_clear_cache_alert_message">キャッシュをクリアするとイメージのロード速度に影響を与えます。実行しますか?</string>
|
||||||
<string name="settings_clear_cache_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="permission_explain">権限を拒否すると一部の機能が利用できません</string>
|
<string name="permission_explain">権限を拒否すると一部の機能が利用できません</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>
|
||||||
@@ -31,4 +31,14 @@
|
|||||||
<string name="settings_security_mode_title">セキュリティーモード</string>
|
<string name="settings_security_mode_title">セキュリティーモード</string>
|
||||||
<string name="settings_security_mode_summary">アプリ履歴でアプリの画面を表示しない</string>
|
<string name="settings_security_mode_summary">アプリ履歴でアプリの画面を表示しない</string>
|
||||||
<string name="reader_go_to_page">移動</string>
|
<string name="reader_go_to_page">移動</string>
|
||||||
|
<string name="default_query_dialog_language_selector_none">非選択</string>
|
||||||
|
<string name="default_query_dialog_filter_BL">BLフィルター</string>
|
||||||
|
<string name="default_query_dialog_filter_guro">グロフィルター</string>
|
||||||
|
<string name="default_query_dialog_language">"言語: "</string>
|
||||||
|
<string name="default_query_dialog_title">デフォルトキーワード設定</string>
|
||||||
|
<string name="main_drawer_group_contact_title">お問い合わせ先</string>
|
||||||
|
<string name="main_drawer_group_contact_homepage">ホームページ</string>
|
||||||
|
<string name="main_drawer_group_contact_help">ヘルプ</string>
|
||||||
|
<string name="main_drawer_group_contact_github">Github</string>
|
||||||
|
<string name="main_drawer_group_contact_email">メールを送る</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -31,4 +31,14 @@
|
|||||||
<string name="settings_security_mode_summary">최근 앱 목록 창에서 앱 화면을 보이지 않게 합니다</string>
|
<string name="settings_security_mode_summary">최근 앱 목록 창에서 앱 화면을 보이지 않게 합니다</string>
|
||||||
<string name="settings_security_mode_title">보안 모드 활성화</string>
|
<string name="settings_security_mode_title">보안 모드 활성화</string>
|
||||||
<string name="reader_go_to_page">이동</string>
|
<string name="reader_go_to_page">이동</string>
|
||||||
|
<string name="default_query_dialog_language_selector_none">미선택</string>
|
||||||
|
<string name="default_query_dialog_filter_BL">BL물 필터</string>
|
||||||
|
<string name="default_query_dialog_filter_guro">고어물 필터</string>
|
||||||
|
<string name="default_query_dialog_language">"언어: "</string>
|
||||||
|
<string name="default_query_dialog_title">기본 검색어 설정</string>
|
||||||
|
<string name="main_drawer_group_contact_email">메일 보내기!</string>
|
||||||
|
<string name="main_drawer_group_contact_github">Github</string>
|
||||||
|
<string name="main_drawer_group_contact_help">도움말</string>
|
||||||
|
<string name="main_drawer_group_contact_homepage">홈페이지</string>
|
||||||
|
<string name="main_drawer_group_contact_title">문의</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -4,6 +4,10 @@
|
|||||||
<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">https://tom5079.github.io/Pupil</string>
|
||||||
|
<string name="github" translatable="false">https://github.com/tom5079/Pupil-issue</string>
|
||||||
|
<string name="email" translatable="false">pupil.hentai@gmail.com</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>
|
||||||
|
|
||||||
@@ -23,6 +27,11 @@
|
|||||||
|
|
||||||
<string name="main_drawer_home">Home</string>
|
<string name="main_drawer_home">Home</string>
|
||||||
<string name="main_drawer_history">History</string>
|
<string name="main_drawer_history">History</string>
|
||||||
|
<string name="main_drawer_group_contact_title">Contact</string>
|
||||||
|
<string name="main_drawer_group_contact_help">Help</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_email">Email me!</string>
|
||||||
|
|
||||||
<string name="update_title">Update available</string>
|
<string name="update_title">Update available</string>
|
||||||
<string name="update_download_started">Download started</string>
|
<string name="update_download_started">Download started</string>
|
||||||
@@ -54,4 +63,10 @@
|
|||||||
<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>
|
||||||
|
|
||||||
|
<string name="default_query_dialog_title">Set default query</string>
|
||||||
|
<string name="default_query_dialog_language">Language: </string>
|
||||||
|
<string name="default_query_dialog_filter_BL">Filter BL</string>
|
||||||
|
<string name="default_query_dialog_filter_guro">Filter Guro</string>
|
||||||
|
<string name="default_query_dialog_language_selector_none">Any</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
app:defaultValue="25"
|
app:defaultValue="25"
|
||||||
app:useSimpleSummaryProvider="true"/>
|
app:useSimpleSummaryProvider="true"/>
|
||||||
|
|
||||||
<EditTextPreference
|
<Preference
|
||||||
app:key="default_query"
|
app:key="default_query"
|
||||||
app:title="@string/settings_default_query"
|
app:title="@string/settings_default_query"
|
||||||
app:defaultValue=""
|
app:defaultValue=""
|
||||||
|
|||||||