Bug fixed

This commit is contained in:
tom5079
2019-05-14 18:48:33 +09:00
parent efefa9e174
commit 726cdf0fae
24 changed files with 444 additions and 103 deletions

View File

@@ -1,26 +1,15 @@
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.IntentFilter
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.preference.PreferenceManager
import android.text.*
import android.text.style.AlignmentSpan
import android.view.View
import android.view.WindowManager
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
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.view.GravityCompat
import androidx.recyclerview.widget.LinearLayoutManager
@@ -38,17 +27,18 @@ import ru.noties.markwon.Markwon
import xyz.quaver.hitomi.*
import xyz.quaver.pupil.adapters.GalleryBlockAdapter
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.FileOutputStream
import java.lang.Exception
import java.util.*
import javax.net.ssl.HttpsURLConnection
import kotlin.collections.ArrayList
class MainActivity : AppCompatActivity() {
private val permissionRequestCode = 4585
private val galleries = ArrayList<Pair<GalleryBlock, Deferred<String>>>()
private var query = ""
@@ -67,8 +57,6 @@ class MainActivity : AppCompatActivity() {
setContentView(R.layout.activity_main)
checkPermission()
checkUpdate()
main_appbar_layout.addOnOffsetChangedListener(
@@ -99,17 +87,33 @@ class MainActivity : AppCompatActivity() {
CoroutineScope(Dispatchers.Main).launch {
main_drawer_layout.closeDrawers()
cancelFetch()
clearGalleries()
when(it.itemId) {
R.id.main_drawer_home -> {
cancelFetch()
clearGalleries()
query = query.replace("HISTORY", "")
fetchGalleries(query)
}
R.id.main_drawer_history -> {
cancelFetch()
clearGalleries()
query += "HISTORY"
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()
}
@@ -142,23 +146,6 @@ class MainActivity : AppCompatActivity() {
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() {
fun extractReleaseNote(update: JsonObject, locale: String) : String {
@@ -179,7 +166,7 @@ class MainActivity : AppCompatActivity() {
val result = StringBuilder()
for(line in markdown.split('\n')) {
for(line in markdown.lines()) {
if (releaseNote.matches(line)) {
releaseNoteFlag = true
continue
@@ -203,57 +190,16 @@ class MainActivity : AppCompatActivity() {
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 {
val update =
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 {
setTitle(R.string.update_title)
val msg = extractReleaseNote(update, Locale.getDefault().language)
setMessage(Markwon.create(context).toMarkdown(msg))
setPositiveButton(android.R.string.yes) { _, _ ->
Toast.makeText(
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))
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.home_page))))
}
setNegativeButton(android.R.string.no) { _, _ ->}
}
@@ -404,9 +350,11 @@ class MainActivity : AppCompatActivity() {
if (query != this@MainActivity.query) {
this@MainActivity.query = query
cancelFetch()
clearGalleries()
fetchGalleries(query)
CoroutineScope(Dispatchers.Main).launch {
cancelFetch()
clearGalleries()
fetchGalleries(query)
}
}
}
})

View File

@@ -1,6 +1,7 @@
package xyz.quaver.pupil
import android.os.Bundle
import android.util.Log
import android.view.*
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
@@ -112,13 +113,13 @@ class ReaderActivity : AppCompatActivity() {
when(item?.itemId) {
R.id.reader_menu_page_indicator -> {
val view = LayoutInflater.from(this).inflate(R.layout.dialog_numberpicker, findViewById(android.R.id.content), false)
with(view.reader_dialog_number_picker) {
minValue=1
maxValue=gallerySize
value=currentPage
}
val dialog = AlertDialog.Builder(this).apply {
setView(view)
with(view.reader_dialog_number_picker) {
minValue=1
maxValue=gallerySize
value=currentPage
}
}.create()
view.reader_dialog_ok.setOnClickListener {
(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 as LinearLayoutManager).scrollToPositionWithOffset(currentPage, 0)
(reader_recyclerview.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(currentPage-1, 0)
preferences.edit().putBoolean("reader_one_by_one", !oneByOne).apply()

View File

@@ -2,12 +2,22 @@ package xyz.quaver.pupil
import android.os.Bundle
import android.preference.PreferenceManager
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
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.AppCompatActivity
import androidx.preference.Preference
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 java.io.File
@@ -109,6 +119,120 @@ class SettingsActivity : AppCompatActivity() {
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
}
}
}
}

View 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() }
}
}

View File

@@ -18,14 +18,5 @@ fun checkUpdate(url: String, currentVersion: String) : JsonObject? {
if (currentVersion != releases[0].jsonObject["tag_name"]?.content)
return releases[0].jsonObject
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
}