Compare commits

..

8 Commits

Author SHA1 Message Date
tom5079
b165a2308f Merge remote-tracking branch 'origin/master' into master 2020-10-13 17:13:10 +09:00
tom5079
8757b08cd2 Fixed pagecount not showing up 2020-10-13 17:12:53 +09:00
tom5079
3800543fba Update README.md 2020-10-13 13:59:02 +09:00
tom5079
02ef60c818 Update README.md 2020-10-13 13:57:23 +09:00
tom5079
88f3b30266 Merge branch 'dev' into master 2020-10-13 13:52:34 +09:00
tom5079
9203dc0112 Tag translation 2020-10-13 13:51:53 +09:00
tom5079
4c683bec68 Dependency update
Fixes concurrentmodificationexception
2020-10-13 08:34:04 +09:00
tom5079
0cfd1eb453 Update README.md 2020-10-04 23:05:30 +09:00
20 changed files with 154 additions and 65 deletions

6
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="1.8" />
</component>
</project>

2
.idea/misc.xml generated
View File

@@ -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_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">

View File

@@ -2,7 +2,7 @@
*Pupil, Hitomi.la viewer for Android* *Pupil, Hitomi.la viewer for Android*
![](https://img.shields.io/github/downloads/tom5079/Pupil/total) ![](https://img.shields.io/github/downloads/tom5079/Pupil/total)
[![](https://img.shields.io/github/downloads/tom5079/Pupil/latest/Pupil-v5.1.3.apk?color=%234fc3f7&label=DOWNLOAD%20APP&style=for-the-badge)](https://github.com/tom5079/Pupil/releases/download/5.1.3/Pupil-v5.1.3.apk) [![](https://img.shields.io/github/downloads/tom5079/Pupil/5.1.4/Pupil-v5.1.4.apk?color=%234fc3f7&label=DOWNLOAD%20APP&style=for-the-badge)](https://github.com/tom5079/Pupil/releases/download/5.1.4/Pupil-v5.1.4.apk)
[![](https://discordapp.com/api/guilds/610452916612104194/embed.png?style=banner2)](https://discord.gg/Stj4b5v) [![](https://discordapp.com/api/guilds/610452916612104194/embed.png?style=banner2)](https://discord.gg/Stj4b5v)
# Features # Features
@@ -21,3 +21,6 @@ or Build app yourself
# Contribution # Contribution
Any kind of contribution is appriciated. Feel free to leave PR! Any kind of contribution is appriciated. Feel free to leave PR!
## Tag Translation
Head over to [tags branch](https://github.com/tom5079/Pupil/tree/tags)

View File

@@ -37,8 +37,8 @@ android {
applicationId "xyz.quaver.pupil" applicationId "xyz.quaver.pupil"
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 30 targetSdkVersion 30
versionCode 62 versionCode 63
versionName "5.1.3-hotfix1" versionName "5.1.4-hotfix1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
} }
@@ -84,7 +84,7 @@ dependencies {
implementation "androidx.activity:activity-ktx:1.2.0-beta01" implementation "androidx.activity:activity-ktx:1.2.0-beta01"
implementation "androidx.fragment:fragment-ktx:1.3.0-beta01" implementation "androidx.fragment:fragment-ktx:1.3.0-beta01"
implementation "androidx.preference:preference:1.1.1" implementation "androidx.preference:preference:1.1.1"
implementation "androidx.constraintlayout:constraintlayout:2.0.1" implementation "androidx.constraintlayout:constraintlayout:2.0.2"
implementation "androidx.gridlayout:gridlayout:1.0.0" implementation "androidx.gridlayout:gridlayout:1.0.0"
implementation "androidx.biometric:biometric:1.0.1" implementation "androidx.biometric:biometric:1.0.1"
implementation "androidx.work:work-runtime-ktx:2.4.0" implementation "androidx.work:work-runtime-ktx:2.4.0"
@@ -93,8 +93,8 @@ dependencies {
implementation "com.google.android.material:material:1.3.0-alpha03" implementation "com.google.android.material:material:1.3.0-alpha03"
implementation "com.google.firebase:firebase-core:17.5.0" implementation "com.google.firebase:firebase-core:17.5.1"
implementation "com.google.firebase:firebase-analytics:17.5.0" implementation "com.google.firebase:firebase-analytics:17.6.0"
implementation "com.google.firebase:firebase-crashlytics:17.2.2" implementation "com.google.firebase:firebase-crashlytics:17.2.2"
implementation "com.google.firebase:firebase-perf:19.0.9" implementation "com.google.firebase:firebase-perf:19.0.9"

View File

@@ -11,8 +11,8 @@
"type": "SINGLE", "type": "SINGLE",
"filters": [], "filters": [],
"properties": [], "properties": [],
"versionCode": 62, "versionCode": 63,
"versionName": "5.1.3-hotfix1", "versionName": "5.1.4-hotfix1",
"enabled": true, "enabled": true,
"outputFile": "app-release.apk" "outputFile": "app-release.apk"
} }

View File

@@ -22,13 +22,18 @@ import kotlinx.android.parcel.IgnoredOnParcel
import kotlinx.android.parcel.Parcelize import kotlinx.android.parcel.Parcelize
import xyz.quaver.floatingsearchview.suggestions.model.SearchSuggestion import xyz.quaver.floatingsearchview.suggestions.model.SearchSuggestion
import xyz.quaver.hitomi.Suggestion import xyz.quaver.hitomi.Suggestion
import xyz.quaver.pupil.util.translations
@Parcelize @Parcelize
data class TagSuggestion(val s: String, val t: Int, val u: String, val n: String) : SearchSuggestion { data class TagSuggestion(val s: String, val t: Int, val u: String, val n: String) : SearchSuggestion {
constructor(s: Suggestion) : this(s.s, s.t, s.u, s.n) constructor(s: Suggestion) : this(s.s, s.t, s.u, s.n)
@IgnoredOnParcel @IgnoredOnParcel
override val body = s override val body =
if (translations[s] != null)
"${translations[s]} ($s)"
else
s
} }
@Parcelize @Parcelize

View File

@@ -28,11 +28,13 @@ import android.view.KeyEvent
import android.view.MenuItem import android.view.MenuItem
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
import android.widget.* import android.widget.EditText
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import androidx.core.text.util.LinkifyCompat
import androidx.core.view.GravityCompat import androidx.core.view.GravityCompat
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.navigation.NavigationView import com.google.android.material.navigation.NavigationView

View File

@@ -21,14 +21,16 @@ package xyz.quaver.pupil.ui.fragment
import android.app.Activity import android.app.Activity
import android.content.* import android.content.*
import android.os.Bundle import android.os.Bundle
import android.os.LocaleList
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.Preference import androidx.core.os.LocaleListCompat
import androidx.preference.PreferenceCategory import androidx.preference.*
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreferenceCompat
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import xyz.quaver.io.FileX import xyz.quaver.io.FileX
import xyz.quaver.io.util.getChild import xyz.quaver.io.util.getChild
import xyz.quaver.pupil.R import xyz.quaver.pupil.R
@@ -37,6 +39,7 @@ import xyz.quaver.pupil.ui.SettingsActivity
import xyz.quaver.pupil.ui.dialog.* import xyz.quaver.pupil.ui.dialog.*
import xyz.quaver.pupil.util.* import xyz.quaver.pupil.util.*
import xyz.quaver.pupil.util.downloader.DownloadManager import xyz.quaver.pupil.util.downloader.DownloadManager
import java.util.*
class SettingsFragment : class SettingsFragment :
PreferenceFragmentCompat(), PreferenceFragmentCompat(),
@@ -123,6 +126,9 @@ class SettingsFragment :
this ?: return false this ?: return false
when (key) { when (key) {
"tag_language" -> {
updateTranslations()
}
"nomedia" -> { "nomedia" -> {
val create = (newValue as? Boolean) ?: return false val create = (newValue as? Boolean) ?: return false
@@ -243,6 +249,25 @@ class SettingsFragment :
onPreferenceClickListener = this@SettingsFragment onPreferenceClickListener = this@SettingsFragment
} }
"tag_language" -> {
this as ListPreference
isEnabled = false
CoroutineScope(Dispatchers.IO).launch {
val languages = getAvailableLanguages().distinct().toTypedArray()
entries = languages.map { Locale(it).let { loc -> loc.getDisplayLanguage(loc) } }.toTypedArray()
entryValues = languages
launch(Dispatchers.Main) {
isEnabled = true
}
}
onPreferenceChangeListener = this@SettingsFragment
}
"mirrors" -> { "mirrors" -> {
onPreferenceClickListener = this@SettingsFragment onPreferenceClickListener = this@SettingsFragment
} }

View File

@@ -164,9 +164,7 @@ class FloatingSearchView @JvmOverloads constructor(context: Context, attrs: Attr
} }
} }
if (item.t == -1) { if (item.t > 0) {
textView?.text = item.s
} else {
(suggestionView as? LinearLayout)?.let { (suggestionView as? LinearLayout)?.let {
val count = it.findViewById<TextView>(R.id.count) val count = it.findViewById<TextView>(R.id.count)
if (count == null) if (count == null)

View File

@@ -25,6 +25,7 @@ import com.google.android.material.chip.Chip
import xyz.quaver.pupil.R import xyz.quaver.pupil.R
import xyz.quaver.pupil.favoriteTags import xyz.quaver.pupil.favoriteTags
import xyz.quaver.pupil.types.Tag import xyz.quaver.pupil.types.Tag
import xyz.quaver.pupil.util.translations
import xyz.quaver.pupil.util.wordCapitalize import xyz.quaver.pupil.util.wordCapitalize
@SuppressLint("ViewConstructor") @SuppressLint("ViewConstructor")
@@ -90,7 +91,7 @@ class TagChip(context: Context, _tag: Tag) : Chip(context) {
text = when (tag.area) { text = when (tag.area) {
"language" -> languages[tag.tag] "language" -> languages[tag.tag]
else -> tag.tag.wordCapitalize() else -> (translations[tag.tag] ?: tag.tag).wordCapitalize()
} }
setEnsureMinTouchTargetSize(false) setEnsureMinTouchTargetSize(false)

View File

@@ -1,37 +0,0 @@
package xyz.quaver.pupil.util
import android.graphics.Paint
import android.text.style.LineHeightSpan
class SetLineOverlap(private val overlap: Boolean) : LineHeightSpan {
companion object {
private var originalBottom = 15
private var originalDescent = 13
private var overlapSaved = false
}
override fun chooseHeight(
text: CharSequence?,
start: Int,
end: Int,
spanstartv: Int,
lineHeight: Int,
fm: Paint.FontMetricsInt?
) {
fm ?: return
if (overlap) {
if (overlapSaved) {
originalBottom = fm.bottom
originalDescent = fm.descent
overlapSaved = true
}
fm.bottom += fm.top
fm.descent += fm.top
} else {
fm.bottom = originalBottom
fm.descent = originalDescent
overlapSaved = false
}
}
}

View File

@@ -55,7 +55,7 @@ fun cleanCache(context: Context) = CoroutineScope(Dispatchers.IO).launch {
while (cacheSize.invoke() > limit/2) { while (cacheSize.invoke() > limit/2) {
val caches = cacheFolder.list() ?: return@withLock val caches = cacheFolder.list() ?: return@withLock
(histories.firstOrNull { (histories.toList().firstOrNull {
caches.contains(it.toString()) && !downloadManager.isDownloading(it) caches.contains(it.toString()) && !downloadManager.isDownloading(it)
} ?: return@withLock).let { } ?: return@withLock).let {
Cache.delete(context, it) Cache.delete(context, it)

View File

@@ -23,6 +23,9 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import xyz.quaver.Code import xyz.quaver.Code
@@ -128,4 +131,10 @@ fun String.ellipsize(n: Int): String =
if (this.length > n) if (this.length > n)
this.slice(0 until n) + "" this.slice(0 until n) + ""
else else
this this
operator fun JsonElement.get(index: Int) =
this.jsonArray[index]
operator fun JsonElement.get(tag: String) =
this.jsonObject[tag]

View File

@@ -0,0 +1,66 @@
/*
* Pupil, Hitomi.la viewer for Android
* Copyright (C) 2020 tom5079
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package xyz.quaver.pupil.util
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.Request
import xyz.quaver.pupil.client
import java.io.IOException
import java.util.*
private val filesURL = "https://api.github.com/repos/tom5079/Pupil/git/trees/tags"
private val contentURL = "https://raw.githubusercontent.com/tom5079/Pupil/tags/"
var translations: Map<String, String> = run {
updateTranslations()
emptyMap()
}
private set
@Suppress("BlockingMethodInNonBlockingContext")
fun updateTranslations() = CoroutineScope(Dispatchers.IO).launch {
translations = emptyMap()
translations = Json.decodeFromString<Map<String, String>>(client.newCall(
Request.Builder()
.url(contentURL + "${Preferences["tag_language", ""]}.json")
.build()
).execute().also { if (it.code() != 200) return@launch }.body()?.use { it.string() } ?: return@launch).filterValues { it.isNotEmpty() }
}
fun getAvailableLanguages(): List<String> {
val languages = Locale.getISOLanguages()
val json = Json.parseToJsonElement(client.newCall(
Request.Builder()
.url(filesURL)
.build()
).execute().also { if (it.code() != 200) throw IOException() }.body()?.use { it.string() } ?: return emptyList())
return listOf("en") + (json["tree"]?.jsonArray?.mapNotNull {
val name = it["path"]?.jsonPrimitive?.content?.takeWhile { c -> c != '.' }
languages.firstOrNull { code -> code.equals(name, ignoreCase = true) }
} ?: emptyList())
}

View File

@@ -212,8 +212,8 @@
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
app:layout_constraintTop_toBottomOf="@id/divider" app:layout_constraintTop_toBottomOf="@id/divider"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="parent" /> app:layout_constraintRight_toRightOf="parent" />
<ImageView <ImageView
android:id="@+id/galleryblock_favorite" android:id="@+id/galleryblock_favorite"

View File

@@ -152,4 +152,6 @@
<string name="error">エラー</string> <string name="error">エラー</string>
<string name="settings_cache_limit">キャッシュサイズ制限</string> <string name="settings_cache_limit">キャッシュサイズ制限</string>
<string name="settings_cache_unlimited">制限なし</string> <string name="settings_cache_unlimited">制限なし</string>
<string name="settings_tag_language">タグ言語</string>
<string name="settings_tag_language_message">Githubにて翻訳に参加できます</string>
</resources> </resources>

View File

@@ -152,4 +152,6 @@
<string name="error">오류</string> <string name="error">오류</string>
<string name="settings_cache_limit">캐시 크기 제한</string> <string name="settings_cache_limit">캐시 크기 제한</string>
<string name="settings_cache_unlimited">무제한</string> <string name="settings_cache_unlimited">무제한</string>
<string name="settings_tag_language">태그 언어</string>
<string name="settings_tag_language_message">Github에서 번역에 참여하세요</string>
</resources> </resources>

View File

@@ -175,6 +175,8 @@
<!-- SETTINGS/MISCELLANEOUS --> <!-- SETTINGS/MISCELLANEOUS -->
<string name="settings_miscellaneous_title">Miscellaneous</string> <string name="settings_miscellaneous_title">Miscellaneous</string>
<string name="settings_tag_language">Tag Language</string>
<string name="settings_tag_language_message">Participate in translation on Github</string>
<string name="settings_mirror_summary">Load images from mirrors</string> <string name="settings_mirror_summary">Load images from mirrors</string>
<string name="settings_proxy_title">Proxy</string> <string name="settings_proxy_title">Proxy</string>
<string name="settings_rtl">Turn pages Right-to-Left</string> <string name="settings_rtl">Turn pages Right-to-Left</string>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen <PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
xmlns:app="http://schemas.android.com/apk/res-auto">
<Preference <Preference
app:key="app_version" app:key="app_version"
@@ -76,6 +75,12 @@
<PreferenceCategory <PreferenceCategory
app:title="@string/settings_miscellaneous_title"> app:title="@string/settings_miscellaneous_title">
<ListPreference
app:key="tag_language"
app:title="@string/settings_tag_language"
app:defaultValue="en"
app:useSimpleSummaryProvider="true"/>
<Preference <Preference
app:key="mirrors" app:key="mirrors"
app:title="@string/settings_mirror_title" app:title="@string/settings_mirror_title"

View File

@@ -6,7 +6,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath "com.android.tools.build:gradle:4.0.1" classpath 'com.android.tools.build:gradle:4.0.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
@@ -14,7 +14,7 @@ buildscript {
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
classpath "com.google.firebase:firebase-crashlytics-gradle:2.3.0" classpath "com.google.firebase:firebase-crashlytics-gradle:2.3.0"
classpath "com.google.firebase:perf-plugin:1.3.1" classpath "com.google.firebase:perf-plugin:1.3.2"
classpath "com.google.android.gms:oss-licenses-plugin:0.10.2" classpath "com.google.android.gms:oss-licenses-plugin:0.10.2"
} }
} }