@@ -9,8 +9,8 @@ android {
|
|||||||
applicationId "xyz.quaver.pupil"
|
applicationId "xyz.quaver.pupil"
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
versionCode 11
|
versionCode 14
|
||||||
versionName "2.5.2"
|
versionName "2.7"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package xyz.quaver.pupil
|
|||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.graphics.drawable.Animatable
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
@@ -21,6 +22,7 @@ import androidx.core.app.ActivityCompat
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.core.view.GravityCompat
|
import androidx.core.view.GravityCompat
|
||||||
|
import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
|
||||||
import com.arlib.floatingsearchview.FloatingSearchView
|
import com.arlib.floatingsearchview.FloatingSearchView
|
||||||
import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion
|
import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion
|
||||||
import com.arlib.floatingsearchview.util.view.SearchInputView
|
import com.arlib.floatingsearchview.util.view.SearchInputView
|
||||||
@@ -31,14 +33,20 @@ import kotlinx.android.synthetic.main.activity_main_content.*
|
|||||||
import kotlinx.android.synthetic.main.dialog_galleryblock.view.*
|
import kotlinx.android.synthetic.main.dialog_galleryblock.view.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.io.IOException
|
import kotlinx.io.IOException
|
||||||
|
import kotlinx.serialization.ImplicitReflectionSerializer
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonConfiguration
|
import kotlinx.serialization.json.JsonConfiguration
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
import kotlinx.serialization.json.content
|
import kotlinx.serialization.json.content
|
||||||
|
import kotlinx.serialization.list
|
||||||
|
import kotlinx.serialization.parseList
|
||||||
|
import kotlinx.serialization.stringify
|
||||||
import ru.noties.markwon.Markwon
|
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.Tag
|
||||||
import xyz.quaver.pupil.types.TagSuggestion
|
import xyz.quaver.pupil.types.TagSuggestion
|
||||||
|
import xyz.quaver.pupil.types.Tags
|
||||||
import xyz.quaver.pupil.util.*
|
import xyz.quaver.pupil.util.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
@@ -56,7 +64,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
enum class Mode {
|
enum class Mode {
|
||||||
SEARCH,
|
SEARCH,
|
||||||
HISTORY,
|
HISTORY,
|
||||||
DOWNLOAD
|
DOWNLOAD,
|
||||||
|
FAVORITE
|
||||||
}
|
}
|
||||||
|
|
||||||
private val galleries = ArrayList<Pair<GalleryBlock, Deferred<String>>>()
|
private val galleries = ArrayList<Pair<GalleryBlock, Deferred<String>>>()
|
||||||
@@ -73,6 +82,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private lateinit var histories: Histories
|
private lateinit var histories: Histories
|
||||||
private lateinit var downloads: Histories
|
private lateinit var downloads: Histories
|
||||||
|
private lateinit var favorites: Histories
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -96,6 +106,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
with(application as Pupil) {
|
with(application as Pupil) {
|
||||||
this@MainActivity.histories = histories
|
this@MainActivity.histories = histories
|
||||||
this@MainActivity.downloads = downloads
|
this@MainActivity.downloads = downloads
|
||||||
|
this@MainActivity.favorites = favorites
|
||||||
}
|
}
|
||||||
|
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
@@ -274,6 +285,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
R.id.main_drawer_home -> {
|
R.id.main_drawer_home -> {
|
||||||
cancelFetch()
|
cancelFetch()
|
||||||
clearGalleries()
|
clearGalleries()
|
||||||
|
currentPage = 0
|
||||||
query = ""
|
query = ""
|
||||||
mode = Mode.SEARCH
|
mode = Mode.SEARCH
|
||||||
fetchGalleries(query)
|
fetchGalleries(query)
|
||||||
@@ -282,6 +294,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
R.id.main_drawer_history -> {
|
R.id.main_drawer_history -> {
|
||||||
cancelFetch()
|
cancelFetch()
|
||||||
clearGalleries()
|
clearGalleries()
|
||||||
|
currentPage = 0
|
||||||
query = ""
|
query = ""
|
||||||
mode = Mode.HISTORY
|
mode = Mode.HISTORY
|
||||||
fetchGalleries(query)
|
fetchGalleries(query)
|
||||||
@@ -290,11 +303,21 @@ class MainActivity : AppCompatActivity() {
|
|||||||
R.id.main_drawer_downloads -> {
|
R.id.main_drawer_downloads -> {
|
||||||
cancelFetch()
|
cancelFetch()
|
||||||
clearGalleries()
|
clearGalleries()
|
||||||
|
currentPage = 0
|
||||||
query = ""
|
query = ""
|
||||||
mode = Mode.DOWNLOAD
|
mode = Mode.DOWNLOAD
|
||||||
fetchGalleries(query)
|
fetchGalleries(query)
|
||||||
loadBlocks()
|
loadBlocks()
|
||||||
}
|
}
|
||||||
|
R.id.main_drawer_favorite -> {
|
||||||
|
cancelFetch()
|
||||||
|
clearGalleries()
|
||||||
|
currentPage = 0
|
||||||
|
query = ""
|
||||||
|
mode = Mode.FAVORITE
|
||||||
|
fetchGalleries(query)
|
||||||
|
loadBlocks()
|
||||||
|
}
|
||||||
R.id.main_drawer_help -> {
|
R.id.main_drawer_help -> {
|
||||||
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.help))))
|
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.help))))
|
||||||
}
|
}
|
||||||
@@ -686,6 +709,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var suggestionJob : Job? = null
|
private var suggestionJob : Job? = null
|
||||||
|
@UseExperimental(ImplicitReflectionSerializer::class)
|
||||||
private fun setupSearchBar() {
|
private fun setupSearchBar() {
|
||||||
val searchInputView = findViewById<SearchInputView>(R.id.search_bar_text)
|
val searchInputView = findViewById<SearchInputView>(R.id.search_bar_text)
|
||||||
//Change upper case letters to lower case
|
//Change upper case letters to lower case
|
||||||
@@ -707,16 +731,24 @@ class MainActivity : AppCompatActivity() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
with(main_searchview as FloatingSearchView) {
|
with(main_searchview as FloatingSearchView) {
|
||||||
|
val favoritesFile = File(ContextCompat.getDataDir(context), "favorites_tags.json")
|
||||||
|
val json = Json(JsonConfiguration.Stable)
|
||||||
|
val serializer = Tag.serializer().list
|
||||||
|
|
||||||
|
if (!favoritesFile.exists()) {
|
||||||
|
favoritesFile.createNewFile()
|
||||||
|
favoritesFile.writeText(json.stringify(Tags(listOf())))
|
||||||
|
}
|
||||||
|
|
||||||
setOnMenuItemClickListener {
|
setOnMenuItemClickListener {
|
||||||
when(it.itemId) {
|
when(it.itemId) {
|
||||||
R.id.main_menu_settings -> startActivityForResult(Intent(this@MainActivity, SettingsActivity::class.java), SETTINGS)
|
R.id.main_menu_settings -> startActivityForResult(Intent(this@MainActivity, SettingsActivity::class.java), SETTINGS)
|
||||||
R.id.main_menu_page_indicator -> {
|
R.id.main_menu_jump -> {
|
||||||
val preference = PreferenceManager.getDefaultSharedPreferences(context)
|
val preference = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
val perPage = preference.getString("per_page", "25")!!.toInt()
|
val perPage = preference.getString("per_page", "25")!!.toInt()
|
||||||
val editText = EditText(context)
|
val editText = EditText(context)
|
||||||
|
|
||||||
AlertDialog.Builder(context).apply {
|
AlertDialog.Builder(context).apply {
|
||||||
title = getString(R.string.reader_go_to_page)
|
|
||||||
setView(editText)
|
setView(editText)
|
||||||
setTitle(R.string.main_jump_title)
|
setTitle(R.string.main_jump_title)
|
||||||
setMessage(getString(
|
setMessage(getString(
|
||||||
@@ -737,6 +769,32 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
|
R.id.main_menu_id -> {
|
||||||
|
val editText = EditText(context)
|
||||||
|
|
||||||
|
AlertDialog.Builder(context).apply {
|
||||||
|
setView(editText)
|
||||||
|
setTitle(R.string.main_open_gallery_by_id)
|
||||||
|
|
||||||
|
setPositiveButton(android.R.string.ok) { _, _ ->
|
||||||
|
CoroutineScope(Dispatchers.Default).launch {
|
||||||
|
try {
|
||||||
|
val intent = Intent(this@MainActivity, ReaderActivity::class.java)
|
||||||
|
val gallery =
|
||||||
|
getGalleryBlock(editText.text.toString().toInt()) ?: throw Exception()
|
||||||
|
intent.putExtra(
|
||||||
|
"galleryblock",
|
||||||
|
Json(JsonConfiguration.Stable).stringify(GalleryBlock.serializer(), gallery)
|
||||||
|
)
|
||||||
|
|
||||||
|
startActivity(intent)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Snackbar.make(main_layout, R.string.main_open_gallery_by_id_error, Snackbar.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -751,7 +809,15 @@ class MainActivity : AppCompatActivity() {
|
|||||||
suggestionJob?.cancel()
|
suggestionJob?.cancel()
|
||||||
|
|
||||||
suggestionJob = CoroutineScope(Dispatchers.IO).launch {
|
suggestionJob = CoroutineScope(Dispatchers.IO).launch {
|
||||||
val suggestions = getSuggestionsForQuery(currentQuery).map { TagSuggestion(it) }
|
val suggestions = ArrayList(getSuggestionsForQuery(currentQuery).map { TagSuggestion(it) })
|
||||||
|
|
||||||
|
suggestions.filter {
|
||||||
|
val tag = "${it.n}:${it.s.replace(Regex("\\s"), "_")}"
|
||||||
|
Tags(json.parse(serializer, favoritesFile.readText())).contains(tag)
|
||||||
|
}.reversed().forEach {
|
||||||
|
suggestions.remove(it)
|
||||||
|
suggestions.add(0, it)
|
||||||
|
}
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
swapSuggestions(suggestions)
|
swapSuggestions(suggestions)
|
||||||
@@ -759,8 +825,9 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setOnBindSuggestionCallback { _, leftIcon, textView, item, _ ->
|
setOnBindSuggestionCallback { suggestionView, leftIcon, textView, item, _ ->
|
||||||
val suggestion = item as TagSuggestion
|
val suggestion = item as TagSuggestion
|
||||||
|
val tag = "${suggestion.n}:${suggestion.s.replace(Regex("\\s"), "_")}"
|
||||||
|
|
||||||
leftIcon.setImageDrawable(
|
leftIcon.setImageDrawable(
|
||||||
ResourcesCompat.getDrawable(
|
ResourcesCompat.getDrawable(
|
||||||
@@ -778,16 +845,52 @@ class MainActivity : AppCompatActivity() {
|
|||||||
null)
|
null)
|
||||||
)
|
)
|
||||||
|
|
||||||
val text = "${suggestion.s}\n ${suggestion.t}"
|
with(suggestionView.findViewById<ImageView>(R.id.right_icon)) {
|
||||||
|
|
||||||
val len = text.length
|
if (Tags(json.parse(serializer, favoritesFile.readText())).contains(tag))
|
||||||
val left = suggestion.s.length
|
setImageResource(R.drawable.ic_star_filled)
|
||||||
|
else
|
||||||
|
setImageResource(R.drawable.ic_star_empty)
|
||||||
|
|
||||||
textView.text = SpannableString(text).apply {
|
visibility = View.VISIBLE
|
||||||
val s = AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE)
|
rotation = 0f
|
||||||
setSpan(s, left, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
isEnabled = true
|
||||||
setSpan(SetLineOverlap(true), 1, len-2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
|
||||||
setSpan(SetLineOverlap(false), len-1, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
setColorFilter(ContextCompat.getColor(context, R.color.material_orange_500))
|
||||||
|
|
||||||
|
isClickable = true
|
||||||
|
setOnClickListener {
|
||||||
|
val favorites = Tags(json.parse(serializer, favoritesFile.readText()))
|
||||||
|
|
||||||
|
if (favorites.contains(tag)) {
|
||||||
|
setImageResource(R.drawable.ic_star_empty)
|
||||||
|
favorites.remove(tag)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setImageDrawable(AnimatedVectorDrawableCompat.create(context, R.drawable.avd_star))
|
||||||
|
(drawable as Animatable).start()
|
||||||
|
|
||||||
|
favorites.add(tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
favoritesFile.writeText(json.stringify(favorites))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (suggestion.t == -1) {
|
||||||
|
textView.text = suggestion.s
|
||||||
|
} else {
|
||||||
|
val text = "${suggestion.s}\n ${suggestion.t}"
|
||||||
|
|
||||||
|
val len = text.length
|
||||||
|
val left = suggestion.s.length
|
||||||
|
|
||||||
|
textView.text = SpannableString(text).apply {
|
||||||
|
val s = AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE)
|
||||||
|
setSpan(s, left, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
setSpan(SetLineOverlap(true), 1, len-2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
setSpan(SetLineOverlap(false), len-1, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -810,7 +913,10 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
setOnFocusChangeListener(object: FloatingSearchView.OnFocusChangeListener {
|
setOnFocusChangeListener(object: FloatingSearchView.OnFocusChangeListener {
|
||||||
override fun onFocus() {
|
override fun onFocus() {
|
||||||
//Do Nothing
|
if (searchInputView.text.isEmpty())
|
||||||
|
swapSuggestions(json.parse(serializer, favoritesFile.readText()).map {
|
||||||
|
TagSuggestion(it.tag, -1, "", it.area ?: "tag")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFocusCleared() {
|
override fun onFocusCleared() {
|
||||||
@@ -824,6 +930,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
cancelFetch()
|
cancelFetch()
|
||||||
clearGalleries()
|
clearGalleries()
|
||||||
|
currentPage = 0
|
||||||
fetchGalleries(query)
|
fetchGalleries(query)
|
||||||
loadBlocks()
|
loadBlocks()
|
||||||
}
|
}
|
||||||
@@ -910,6 +1017,19 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Mode.FAVORITE -> {
|
||||||
|
when {
|
||||||
|
query.isEmpty() -> favorites.toList().apply {
|
||||||
|
totalItems = size
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
val result = doSearch(query).sorted()
|
||||||
|
favorites.filter { result.binarySearch(it) >= 0 }.apply {
|
||||||
|
totalItems = size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,14 @@ class Pupil : ObservableApplication() {
|
|||||||
|
|
||||||
lateinit var histories: Histories
|
lateinit var histories: Histories
|
||||||
lateinit var downloads: Histories
|
lateinit var downloads: Histories
|
||||||
|
lateinit var favorites: Histories
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
val preference = PreferenceManager.getDefaultSharedPreferences(this)
|
val preference = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
|
||||||
histories = Histories(File(ContextCompat.getDataDir(this), "histories.json"))
|
histories = Histories(File(ContextCompat.getDataDir(this), "histories.json"))
|
||||||
downloads = Histories(File(ContextCompat.getDataDir(this), "downloads.json"))
|
downloads = Histories(File(ContextCompat.getDataDir(this), "downloads.json"))
|
||||||
|
favorites = Histories(File(ContextCompat.getDataDir(this), "favorites.json"))
|
||||||
|
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
Fn.init(this)
|
Fn.init(this)
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package xyz.quaver.pupil
|
package xyz.quaver.pupil
|
||||||
|
|
||||||
|
import android.graphics.drawable.Animatable
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.LinearSmoothScroller
|
import androidx.recyclerview.widget.LinearSmoothScroller
|
||||||
@@ -20,12 +22,19 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.io.IOException
|
import kotlinx.io.IOException
|
||||||
|
import kotlinx.serialization.ImplicitReflectionSerializer
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonConfiguration
|
import kotlinx.serialization.json.JsonConfiguration
|
||||||
|
import kotlinx.serialization.list
|
||||||
|
import kotlinx.serialization.stringify
|
||||||
import xyz.quaver.hitomi.GalleryBlock
|
import xyz.quaver.hitomi.GalleryBlock
|
||||||
import xyz.quaver.pupil.adapters.ReaderAdapter
|
import xyz.quaver.pupil.adapters.ReaderAdapter
|
||||||
|
import xyz.quaver.pupil.types.Tag
|
||||||
|
import xyz.quaver.pupil.types.Tags
|
||||||
import xyz.quaver.pupil.util.GalleryDownloader
|
import xyz.quaver.pupil.util.GalleryDownloader
|
||||||
|
import xyz.quaver.pupil.util.Histories
|
||||||
import xyz.quaver.pupil.util.ItemClickSupport
|
import xyz.quaver.pupil.util.ItemClickSupport
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
class ReaderActivity : AppCompatActivity() {
|
class ReaderActivity : AppCompatActivity() {
|
||||||
|
|
||||||
@@ -43,9 +52,13 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private var menu: Menu? = null
|
private var menu: Menu? = null
|
||||||
|
|
||||||
|
private lateinit var favorites: Histories
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
favorites = (application as Pupil).favorites
|
||||||
|
|
||||||
window.setFlags(
|
window.setFlags(
|
||||||
WindowManager.LayoutParams.FLAG_SECURE,
|
WindowManager.LayoutParams.FLAG_SECURE,
|
||||||
WindowManager.LayoutParams.FLAG_SECURE)
|
WindowManager.LayoutParams.FLAG_SECURE)
|
||||||
@@ -81,8 +94,17 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
super.onResume()
|
super.onResume()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UseExperimental(ImplicitReflectionSerializer::class)
|
||||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||||
menuInflater.inflate(R.menu.reader, menu)
|
menuInflater.inflate(R.menu.reader, menu)
|
||||||
|
|
||||||
|
with(menu?.findItem(R.id.reader_menu_favorite)) {
|
||||||
|
this ?: return@with
|
||||||
|
|
||||||
|
if (favorites.contains(galleryBlock.id))
|
||||||
|
(icon as Animatable).start()
|
||||||
|
}
|
||||||
|
|
||||||
this.menu = menu
|
this.menu = menu
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -106,6 +128,18 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
R.id.reader_menu_favorite -> {
|
||||||
|
val id = galleryBlock.id
|
||||||
|
val favorite = menu?.findItem(R.id.reader_menu_favorite) ?: return true
|
||||||
|
|
||||||
|
if (favorites.contains(id)) {
|
||||||
|
favorites.remove(id)
|
||||||
|
favorite.icon = AnimatedVectorDrawableCompat.create(this, R.drawable.avd_star)
|
||||||
|
} else {
|
||||||
|
favorites.add(id)
|
||||||
|
(favorite.icon as Animatable).start()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package xyz.quaver.pupil.adapters
|
package xyz.quaver.pupil.adapters
|
||||||
|
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
|
import android.graphics.drawable.Animatable
|
||||||
|
import android.util.Log
|
||||||
import android.util.SparseBooleanArray
|
import android.util.SparseBooleanArray
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -21,8 +23,10 @@ import kotlinx.serialization.json.JsonConfiguration
|
|||||||
import kotlinx.serialization.list
|
import kotlinx.serialization.list
|
||||||
import xyz.quaver.hitomi.GalleryBlock
|
import xyz.quaver.hitomi.GalleryBlock
|
||||||
import xyz.quaver.hitomi.ReaderItem
|
import xyz.quaver.hitomi.ReaderItem
|
||||||
|
import xyz.quaver.pupil.Pupil
|
||||||
import xyz.quaver.pupil.R
|
import xyz.quaver.pupil.R
|
||||||
import xyz.quaver.pupil.types.Tag
|
import xyz.quaver.pupil.types.Tag
|
||||||
|
import xyz.quaver.pupil.util.Histories
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
@@ -37,6 +41,8 @@ class GalleryBlockAdapter(private val galleries: List<Pair<GalleryBlock, Deferre
|
|||||||
PREV
|
PREV
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private lateinit var favorites: Histories
|
||||||
|
|
||||||
inner class GalleryViewHolder(private val view: CardView) : RecyclerView.ViewHolder(view) {
|
inner class GalleryViewHolder(private val view: CardView) : RecyclerView.ViewHolder(view) {
|
||||||
fun bind(item: Pair<GalleryBlock, Deferred<String>>) {
|
fun bind(item: Pair<GalleryBlock, Deferred<String>>) {
|
||||||
with(view) {
|
with(view) {
|
||||||
@@ -202,6 +208,27 @@ class GalleryBlockAdapter(private val galleries: List<Pair<GalleryBlock, Deferre
|
|||||||
|
|
||||||
galleryblock_tag_group.addView(chip)
|
galleryblock_tag_group.addView(chip)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!::favorites.isInitialized)
|
||||||
|
favorites = (context.applicationContext as Pupil).favorites
|
||||||
|
|
||||||
|
with(galleryblock_favorite) {
|
||||||
|
post {
|
||||||
|
isChecked = favorites.contains(gallery.id)
|
||||||
|
}
|
||||||
|
setOnClickListener {
|
||||||
|
when {
|
||||||
|
isChecked -> favorites.add(gallery.id)
|
||||||
|
else -> favorites.remove(gallery.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
when {
|
||||||
|
isChecked -> (background as Animatable).start()
|
||||||
|
else -> background = AnimatedVectorDrawableCompat.create(context, R.drawable.avd_star)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package xyz.quaver.pupil.adapters
|
package xyz.quaver.pupil.adapters
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package xyz.quaver.pupil.types
|
package xyz.quaver.pupil.types
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
data class Tag(val area: String?, val tag: String, val isNegative: Boolean = false) {
|
data class Tag(val area: String?, val tag: String, val isNegative: Boolean = false) {
|
||||||
companion object {
|
companion object {
|
||||||
fun parse(tag: String) : Tag {
|
fun parse(tag: String) : Tag {
|
||||||
|
|||||||
@@ -104,7 +104,13 @@ class GalleryDownloader(
|
|||||||
val cached = json.parse(serializer, cache.readText())
|
val cached = json.parse(serializer, cache.readText())
|
||||||
|
|
||||||
if (cached.isNotEmpty()) {
|
if (cached.isNotEmpty()) {
|
||||||
|
useHiyobi = when {
|
||||||
|
cached.first().url.contains("hitomi.la") -> false
|
||||||
|
else -> true
|
||||||
|
}
|
||||||
|
|
||||||
onReaderLoadedHandler?.invoke(cached)
|
onReaderLoadedHandler?.invoke(cached)
|
||||||
|
|
||||||
return@async cached
|
return@async cached
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
37
app/src/main/res/drawable/avd_star.xml
Normal file
37
app/src/main/res/drawable/avd_star.xml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<animated-vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
tools:ignore="newApi">
|
||||||
|
<aapt:attr name="android:drawable">
|
||||||
|
<vector
|
||||||
|
android:name="vector"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:name="path"
|
||||||
|
android:pathData="M 12 15.39 L 8.24 17.66 L 9.23 13.38 L 5.91 10.5 L 10.29 10.13 L 12 6.09 L 13.71 10.13 L 18.09 10.5 L 14.77 13.38 L 15.76 17.66 M 22 9.24 L 14.81 8.63 L 12 2 L 9.19 8.63 L 2 9.24 L 7.45 13.97 L 5.82 21 L 12 17.27 L 18.18 21 L 16.54 13.97 L 22 9.24 Z"
|
||||||
|
android:fillColor="#000"/>
|
||||||
|
<clip-path
|
||||||
|
android:name="clip"
|
||||||
|
android:pathData="M 2 21 L 2 21 L 22 21 L 22 21 Z"/>
|
||||||
|
<path
|
||||||
|
android:name="path_1"
|
||||||
|
android:pathData="M 12 17.27 L 18.18 21 L 16.54 13.97 L 22 9.24 L 14.81 8.62 L 12 2 L 9.19 8.62 L 2 9.24 L 7.45 13.97 L 5.82 21 L 12 17.27 Z"
|
||||||
|
android:fillColor="#000"/>
|
||||||
|
</vector>
|
||||||
|
</aapt:attr>
|
||||||
|
<target android:name="clip">
|
||||||
|
<aapt:attr name="android:animation">
|
||||||
|
<objectAnimator
|
||||||
|
android:propertyName="pathData"
|
||||||
|
android:duration="500"
|
||||||
|
android:valueFrom="M 2 21 L 2 21 L 22 21 L 22 21 Z"
|
||||||
|
android:valueTo="M 2 2 L 2 21 L 22 21 L 22 2 Z"
|
||||||
|
android:valueType="pathType"
|
||||||
|
android:interpolator="@android:interpolator/fast_out_slow_in"/>
|
||||||
|
</aapt:attr>
|
||||||
|
</target>
|
||||||
|
</animated-vector>
|
||||||
BIN
app/src/main/res/drawable/ic_hiyobi.png
Normal file
BIN
app/src/main/res/drawable/ic_hiyobi.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 159 B |
4
app/src/main/res/drawable/ic_star_empty.xml
Normal file
4
app/src/main/res/drawable/ic_star_empty.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<vector android:height="24dp" android:width="24dp"
|
||||||
|
android:viewportHeight="24.0" android:viewportWidth="24.0" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#000" android:pathData="M 12 15.39 L 8.24 17.66 L 9.23 13.38 L 5.91 10.5 L 10.29 10.13 L 12 6.09 L 13.71 10.13 L 18.09 10.5 L 14.77 13.38 L 15.76 17.66 M 22 9.24 L 14.81 8.63 L 12 2 L 9.19 8.63 L 2 9.24 L 7.45 13.97 L 5.82 21 L 12 17.27 L 18.18 21 L 16.54 13.97 L 22 9.24 Z"/>
|
||||||
|
</vector>
|
||||||
4
app/src/main/res/drawable/ic_star_filled.xml
Normal file
4
app/src/main/res/drawable/ic_star_filled.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<vector android:height="24dp" android:width="24dp"
|
||||||
|
android:viewportHeight="24.0" android:viewportWidth="24.0" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#000" android:pathData="M 12 17.27 L 18.18 21 L 16.54 13.97 L 22 9.24 L 14.81 8.62 L 12 2 L 9.19 8.62 L 2 9.24 L 7.45 13.97 L 5.82 21 L 12 17.27 Z"/>
|
||||||
|
</vector>
|
||||||
@@ -14,111 +14,145 @@
|
|||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:clickable="true">
|
android:clickable="true">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ProgressBar
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
|
||||||
android:id="@+id/galleryblock_progressbar"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="4dp"
|
android:layout_height="wrap_content">
|
||||||
android:visibility="gone"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"/>
|
|
||||||
|
|
||||||
<ImageView
|
<ProgressBar
|
||||||
android:id="@+id/galleryblock_progress_complete"
|
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/galleryblock_progressbar"
|
||||||
android:layout_height="4dp"
|
android:layout_width="match_parent"
|
||||||
android:visibility="invisible"
|
android:layout_height="4dp"
|
||||||
android:scaleType="fitXY"
|
android:visibility="gone"
|
||||||
android:contentDescription="@string/reader_imageview_description"
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
app:layout_constraintTop_toTopOf="parent"/>
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/galleryblock_thumbnail"
|
android:id="@+id/galleryblock_progress_complete"
|
||||||
android:layout_width="150dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="4dp"
|
||||||
android:contentDescription="@string/galleryblock_thumbnail_description"
|
android:visibility="invisible"
|
||||||
android:adjustViewBounds="true"
|
android:scaleType="fitXY"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
android:contentDescription="@string/reader_imageview_description"
|
||||||
app:layout_constraintTop_toBottomOf="@id/galleryblock_progressbar"
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
|
||||||
|
|
||||||
<TextView
|
<ImageView
|
||||||
style="@style/TextAppearance.AppCompat.Headline"
|
android:id="@+id/galleryblock_thumbnail"
|
||||||
android:id="@+id/galleryblock_title"
|
android:layout_width="150dp"
|
||||||
android:layout_width="0dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:contentDescription="@string/galleryblock_thumbnail_description"
|
||||||
android:layout_marginTop="8dp"
|
android:adjustViewBounds="true"
|
||||||
android:layout_marginStart="8dp"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
android:layout_marginLeft="8dp"
|
app:layout_constraintTop_toBottomOf="@id/galleryblock_progressbar"
|
||||||
app:layout_constraintLeft_toRightOf="@id/galleryblock_thumbnail"
|
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/TextAppearance.AppCompat.Medium"
|
style="@style/TextAppearance.AppCompat.Headline"
|
||||||
android:id="@+id/galleryblock_artist"
|
android:id="@+id/galleryblock_title"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginStart="8dp"
|
||||||
app:layout_constraintLeft_toRightOf="@id/galleryblock_thumbnail"
|
android:layout_marginLeft="8dp"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintLeft_toRightOf="@id/galleryblock_thumbnail"
|
||||||
app:layout_constraintTop_toBottomOf="@id/galleryblock_title"/>
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/galleryblock_series"
|
style="@style/TextAppearance.AppCompat.Medium"
|
||||||
android:layout_width="0dp"
|
android:id="@+id/galleryblock_artist"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginStart="8dp"
|
||||||
app:layout_constraintTop_toBottomOf="@id/galleryblock_artist"
|
android:layout_marginLeft="8dp"
|
||||||
app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail"
|
app:layout_constraintLeft_toRightOf="@id/galleryblock_thumbnail"
|
||||||
app:layout_constraintEnd_toEndOf="parent"/>
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/galleryblock_title"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/galleryblock_type"
|
android:id="@+id/galleryblock_series"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginLeft="8dp"
|
||||||
app:layout_constraintTop_toBottomOf="@id/galleryblock_series"
|
app:layout_constraintTop_toBottomOf="@id/galleryblock_artist"
|
||||||
app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail" />
|
app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/galleryblock_language"
|
android:id="@+id/galleryblock_type"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginLeft="8dp"
|
||||||
android:layout_marginBottom="8dp"
|
app:layout_constraintTop_toBottomOf="@id/galleryblock_series"
|
||||||
app:layout_constraintTop_toBottomOf="@id/galleryblock_type"
|
app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail" />
|
||||||
app:layout_constraintBottom_toTopOf="@id/galleryblock_padding"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail" />
|
<TextView
|
||||||
|
android:id="@+id/galleryblock_language"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/galleryblock_type"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/galleryblock_padding"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/galleryblock_padding"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/galleryblock_language"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/galleryblock_tag_group"/>
|
||||||
|
|
||||||
|
<com.google.android.material.chip.ChipGroup
|
||||||
|
android:id="@+id/galleryblock_tag_group"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/galleryblock_padding"
|
||||||
|
app:layout_constraintLeft_toRightOf="@id/galleryblock_thumbnail"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/galleryblock_padding"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="0dp"
|
android:layout_height="1dp"
|
||||||
android:layout_height="0dp"
|
android:layout_margin="8dp"
|
||||||
app:layout_constraintStart_toEndOf="@id/galleryblock_thumbnail"
|
android:background="@android:color/darker_gray"/>
|
||||||
app:layout_constraintTop_toBottomOf="@id/galleryblock_language"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/galleryblock_tag_group"/>
|
|
||||||
|
|
||||||
<com.google.android.material.chip.ChipGroup
|
<LinearLayout
|
||||||
android:id="@+id/galleryblock_tag_group"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="8dp"
|
android:orientation="horizontal"
|
||||||
android:layout_marginStart="8dp"
|
android:gravity="end">
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
app:layout_constraintLeft_toRightOf="@id/galleryblock_thumbnail"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/galleryblock_padding"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
<ToggleButton
|
||||||
|
android:id="@+id/galleryblock_favorite"
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:background="@drawable/avd_star"
|
||||||
|
android:backgroundTint="@color/material_orange_500"
|
||||||
|
android:text=""
|
||||||
|
android:textOn=""
|
||||||
|
android:textOff=""/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView>
|
</androidx.cardview.widget.CardView>
|
||||||
@@ -14,6 +14,10 @@
|
|||||||
<item android:id="@+id/main_drawer_downloads"
|
<item android:id="@+id/main_drawer_downloads"
|
||||||
android:title="@string/main_drawer_downloads"
|
android:title="@string/main_drawer_downloads"
|
||||||
android:icon="@drawable/ic_download"/>
|
android:icon="@drawable/ic_download"/>
|
||||||
|
|
||||||
|
<item android:id="@+id/main_drawer_favorite"
|
||||||
|
android:title="@string/main_drawer_favorite"
|
||||||
|
android:icon="@drawable/ic_star_filled"/>
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<item android:title="@string/main_drawer_group_contact_title">
|
<item android:title="@string/main_drawer_group_contact_title">
|
||||||
|
|||||||
@@ -2,9 +2,14 @@
|
|||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
<item android:id="@+id/main_menu_page_indicator"
|
<item android:id="@+id/main_menu_jump"
|
||||||
android:icon="@drawable/ic_jump"
|
android:icon="@drawable/ic_jump"
|
||||||
android:title="@string/page_indicator_placeholder"
|
android:title="@string/main_jump_title"
|
||||||
|
app:showAsAction="ifRoom"/>
|
||||||
|
|
||||||
|
<item android:id="@+id/main_menu_id"
|
||||||
|
android:icon="@drawable/ic_numeric"
|
||||||
|
android:title="@string/main_open_gallery_by_id"
|
||||||
app:showAsAction="ifRoom"/>
|
app:showAsAction="ifRoom"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<item android:id="@+id/reader_menu_favorite"
|
||||||
|
android:title=""
|
||||||
|
android:iconTint="@color/material_orange_500"
|
||||||
|
android:icon="@drawable/avd_star"
|
||||||
|
app:showAsAction="always"/>
|
||||||
|
|
||||||
<item android:id="@+id/reader_menu_use_hiyobi"
|
<item android:id="@+id/reader_menu_use_hiyobi"
|
||||||
android:title=""
|
android:title=""
|
||||||
android:icon="@drawable/ic_hiyobi"
|
android:icon="@drawable/ic_hiyobi"
|
||||||
|
|||||||
@@ -67,4 +67,7 @@
|
|||||||
<string name="settings_clear_downloads">ダウンロード削除</string>
|
<string name="settings_clear_downloads">ダウンロード削除</string>
|
||||||
<string name="settings_clear_downloads_alert_message">ダウンロードしたギャラリーを全て削除します。\n実行しますか?</string>
|
<string name="settings_clear_downloads_alert_message">ダウンロードしたギャラリーを全て削除します。\n実行しますか?</string>
|
||||||
<string name="settings_use_hiyobi_summary">ロード速度を向上させるため可能であればhiyobi.meからイメージロード</string>
|
<string name="settings_use_hiyobi_summary">ロード速度を向上させるため可能であればhiyobi.meからイメージロード</string>
|
||||||
|
<string name="main_drawer_favorite">お気に入り</string>
|
||||||
|
<string name="main_open_gallery_by_id">ギャラリー番号で見る</string>
|
||||||
|
<string name="main_open_gallery_by_id_error">エラーが発生しました</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -67,4 +67,7 @@
|
|||||||
<string name="settings_clear_downloads">다운로드 삭제</string>
|
<string name="settings_clear_downloads">다운로드 삭제</string>
|
||||||
<string name="settings_clear_downloads_alert_message">다운로드 된 만화를 모두 삭제합니다.\n계속하시겠습니까?</string>
|
<string name="settings_clear_downloads_alert_message">다운로드 된 만화를 모두 삭제합니다.\n계속하시겠습니까?</string>
|
||||||
<string name="settings_use_hiyobi_summary">속도 향상을 위해 가능하면 hiyobi.me에서 이미지 로드</string>
|
<string name="settings_use_hiyobi_summary">속도 향상을 위해 가능하면 hiyobi.me에서 이미지 로드</string>
|
||||||
|
<string name="main_drawer_favorite">즐겨찾기</string>
|
||||||
|
<string name="main_open_gallery_by_id">갤러리 번호로 열기</string>
|
||||||
|
<string name="main_open_gallery_by_id_error">갤러리를 찾지 못했습니다</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -8,4 +8,5 @@
|
|||||||
<color name="material_pink_600">#d81b60</color>
|
<color name="material_pink_600">#d81b60</color>
|
||||||
<color name="material_blue_700">#1976d2</color>
|
<color name="material_blue_700">#1976d2</color>
|
||||||
<color name="material_green_a700">#00c853</color>
|
<color name="material_green_a700">#00c853</color>
|
||||||
|
<color name="material_orange_500">#ff9800</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
<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="home_page" translatable="false">http://bit.ly/2ZlOjXJ</string>
|
||||||
<string name="help" translatable="false">https://tom5079.github.io/Pupil/2019/06/06/manual-kr.html</string>
|
<string name="help" translatable="false">http://bit.ly/2Z7lNZE</string>
|
||||||
<string name="github" translatable="false">https://github.com/tom5079/Pupil-issue/issues/new/choose</string>
|
<string name="github" translatable="false">https://github.com/tom5079/Pupil-issue/issues/new/choose</string>
|
||||||
<string name="email" translatable="false">mailto:pupil.hentai@gmail.com</string>
|
<string name="email" translatable="false">mailto:pupil.hentai@gmail.com</string>
|
||||||
|
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
<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_downloads">Downloads</string>
|
<string name="main_drawer_downloads">Downloads</string>
|
||||||
|
<string name="main_drawer_favorite">Favorites</string>
|
||||||
<string name="main_drawer_group_contact_title">Contact</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_help">Help</string>
|
||||||
<string name="main_drawer_group_contact_homepage">Visit homepage</string>
|
<string name="main_drawer_group_contact_homepage">Visit homepage</string>
|
||||||
@@ -43,6 +44,8 @@
|
|||||||
|
|
||||||
<string name="main_jump_title">Jump to page</string>
|
<string name="main_jump_title">Jump to page</string>
|
||||||
<string name="main_jump_message">Current page: %1$d\nMaximum page: %2$d</string>
|
<string name="main_jump_message">Current page: %1$d\nMaximum page: %2$d</string>
|
||||||
|
<string name="main_open_gallery_by_id">Open Gallery by ID</string>
|
||||||
|
<string name="main_open_gallery_by_id_error">Failed to open gallery</string>
|
||||||
|
|
||||||
<string name="main_move">Move to page %1$d</string>
|
<string name="main_move">Move to page %1$d</string>
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ fun doSearch(query: String) : List<Int> {
|
|||||||
val terms = query
|
val terms = query
|
||||||
.trim()
|
.trim()
|
||||||
.replace(Regex("""^\?"""), "")
|
.replace(Regex("""^\?"""), "")
|
||||||
.replace('_', ' ')
|
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.split(Regex("\\s+"))
|
.split(Regex("\\s+"))
|
||||||
|
.map {
|
||||||
|
it.replace('_', ' ')
|
||||||
|
}
|
||||||
|
|
||||||
val positiveTerms = LinkedList<String>()
|
val positiveTerms = LinkedList<String>()
|
||||||
val negativeTerms = LinkedList<String>()
|
val negativeTerms = LinkedList<String>()
|
||||||
@@ -42,7 +44,8 @@ fun doSearch(query: String) : List<Int> {
|
|||||||
//positive results
|
//positive results
|
||||||
positiveTerms.map {
|
positiveTerms.map {
|
||||||
launch(searchDispatcher) {
|
launch(searchDispatcher) {
|
||||||
filterPositive(getGalleryIDsForQuery(it).sorted())
|
val newResults = getGalleryIDsForQuery(it)
|
||||||
|
filterPositive(newResults.sorted())
|
||||||
}
|
}
|
||||||
}.forEach {
|
}.forEach {
|
||||||
it.join()
|
it.join()
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import java.net.URL
|
|||||||
class UnitTest {
|
class UnitTest {
|
||||||
@Test
|
@Test
|
||||||
fun test() {
|
fun test() {
|
||||||
print(File("C:\\asdf").list()?.size ?: 0)
|
val galleries = getGalleryIDsForQuery("series:touhou_project")
|
||||||
|
|
||||||
|
println(galleries.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user