From cbb52f3dc97ac650ad5cdcb2428b46d8c917a55b Mon Sep 17 00:00:00 2001 From: tom5079 Date: Mon, 13 May 2019 01:02:17 +0900 Subject: [PATCH 1/6] Added drawer to the main activity --- .idea/misc.xml | 2 +- .idea/vcs.xml | 1 - .../java/xyz/quaver/pupil/MainActivity.kt | 17 ++++ app/src/main/res/layout/activity_main.xml | 92 ++++--------------- .../main/res/layout/activity_main_content.xml | 83 +++++++++++++++++ app/src/main/res/layout/nav_header_main.xml | 12 +++ .../main/res/menu/activity_main_drawer.xml | 7 ++ app/src/main/res/values/dimen.xml | 5 + 8 files changed, 142 insertions(+), 77 deletions(-) create mode 100644 app/src/main/res/layout/activity_main_content.xml create mode 100644 app/src/main/res/layout/nav_header_main.xml create mode 100644 app/src/main/res/menu/activity_main_drawer.xml diff --git a/.idea/misc.xml b/.idea/misc.xml index 7631aec3..84da703c 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index c78d9f02..94a25f7f 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,5 @@ - \ No newline at end of file diff --git a/app/src/main/java/xyz/quaver/pupil/MainActivity.kt b/app/src/main/java/xyz/quaver/pupil/MainActivity.kt index dd4422e6..64284234 100644 --- a/app/src/main/java/xyz/quaver/pupil/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/MainActivity.kt @@ -24,6 +24,7 @@ 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 import androidx.recyclerview.widget.RecyclerView import com.arlib.floatingsearchview.FloatingSearchView @@ -31,6 +32,7 @@ import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion import com.arlib.floatingsearchview.util.view.SearchInputView import com.google.android.material.appbar.AppBarLayout import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.android.synthetic.main.activity_main_content.* import kotlinx.coroutines.* import xyz.quaver.hitomi.* import xyz.quaver.pupil.adapters.GalleryBlockAdapter @@ -80,11 +82,24 @@ class MainActivity : AppCompatActivity() { } } + main_nav_view.setNavigationItemSelectedListener { + Log.d("Pupil", it.itemId.toString()) + + true + } + setupRecyclerView() setupSearchBar() fetchGalleries(query) } + override fun onBackPressed() { + if (main_drawer_layout.isDrawerOpen(GravityCompat.START)) + main_drawer_layout.closeDrawer(GravityCompat.START) + else + super.onBackPressed() + } + private fun checkPermission() { val permissions = arrayOf( Manifest.permission.WRITE_EXTERNAL_STORAGE @@ -299,6 +314,8 @@ class MainActivity : AppCompatActivity() { } } }) + + attachNavigationDrawerToMenuButton(main_drawer_layout) } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 77677f3d..3d702355 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,83 +1,25 @@ - + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/main_drawer_layout" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fitsSystemWindows="true" + tools:openDrawer="start"> - + android:layout_height="match_parent"/> - - - - - - - - - - - - - - - - - - - + android:layout_gravity="start" + android:fitsSystemWindows="true" + app:headerLayout="@layout/nav_header_main" + app:menu="@menu/activity_main_drawer"/> - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main_content.xml b/app/src/main/res/layout/activity_main_content.xml new file mode 100644 index 00000000..f0d84786 --- /dev/null +++ b/app/src/main/res/layout/activity_main_content.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/nav_header_main.xml b/app/src/main/res/layout/nav_header_main.xml new file mode 100644 index 00000000..d801cf79 --- /dev/null +++ b/app/src/main/res/layout/nav_header_main.xml @@ -0,0 +1,12 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml new file mode 100644 index 00000000..71a9e813 --- /dev/null +++ b/app/src/main/res/menu/activity_main_drawer.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/dimen.xml b/app/src/main/res/values/dimen.xml index ccfb842f..e0995224 100644 --- a/app/src/main/res/values/dimen.xml +++ b/app/src/main/res/values/dimen.xml @@ -2,4 +2,9 @@ 64dp 80dp + + 16dp + 16dp + 8dp + 176dp \ No newline at end of file From 2bf0f8651095596b14a769067dd34e78b32fc4aa Mon Sep 17 00:00:00 2001 From: tom5079 Date: Mon, 13 May 2019 12:56:39 +0900 Subject: [PATCH 2/6] Add hiyobi image booster --- .../quaver/pupil/ExampleInstrumentedTest.kt | 12 +---- .../java/xyz/quaver/pupil/GalleryActivity.kt | 21 ++++++-- .../java/xyz/quaver/pupil/MainActivity.kt | 5 +- .../pupil/adapters/GalleryBlockAdapter.kt | 6 +-- app/src/main/res/drawable/side_nav_bar.png | Bin 0 -> 18250 bytes app/src/main/res/xml/root_preferences.xml | 10 ++++ .../main/java/xyz/quaver/hitomi/readers.kt | 11 +--- .../src/main/java/xyz/quaver/hiyobi/reader.kt | 47 ++++++++++++++++++ .../test/java/xyz/quaver/hitomi/UnitTest.kt | 5 ++ 9 files changed, 89 insertions(+), 28 deletions(-) create mode 100644 app/src/main/res/drawable/side_nav_bar.png create mode 100644 libpupil/src/main/java/xyz/quaver/hiyobi/reader.kt diff --git a/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt b/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt index 73714252..16060355 100644 --- a/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt +++ b/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith +import xyz.quaver.hiyobi.getReader import java.io.File /** @@ -38,16 +39,7 @@ class ExampleInstrumentedTest { } @Test - @ExperimentalUnsignedTypes fun test_doSearch() { - Log.d("TEST", "Starting...") - - runBlocking { - CoroutineScope(Dispatchers.Main).launch { - Log.d("TEST", "This is started! wow") - }.join() - } - - Log.d("TEST", "Finished! ...Really?") + getReader(1414061) } } diff --git a/app/src/main/java/xyz/quaver/pupil/GalleryActivity.kt b/app/src/main/java/xyz/quaver/pupil/GalleryActivity.kt index 3a87a040..92dfe9c5 100644 --- a/app/src/main/java/xyz/quaver/pupil/GalleryActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/GalleryActivity.kt @@ -1,17 +1,21 @@ package xyz.quaver.pupil import android.os.Bundle +import android.util.Log import android.view.View import android.view.WindowManager import androidx.appcompat.app.AppCompatActivity +import androidx.preference.PreferenceManager import kotlinx.android.synthetic.main.activity_gallery.* import kotlinx.coroutines.* import xyz.quaver.hitomi.Reader import xyz.quaver.hitomi.getReader import xyz.quaver.hitomi.getReferer +import xyz.quaver.hiyobi.hiyobi import xyz.quaver.pupil.adapters.GalleryAdapter import java.io.File import java.io.FileOutputStream +import java.lang.Exception import java.net.URL import javax.net.ssl.HttpsURLConnection @@ -32,9 +36,20 @@ class GalleryActivity : AppCompatActivity() { setContentView(R.layout.activity_gallery) + supportActionBar?.title = intent.getStringExtra("GALLERY_TITLE") + galleryID = intent.getIntExtra("GALLERY_ID", 0) CoroutineScope(Dispatchers.Unconfined).launch { reader = async(Dispatchers.IO) { + val preference = PreferenceManager.getDefaultSharedPreferences(this@GalleryActivity) + if (preference.getBoolean("use_hiyobi", false)) { + try { + xyz.quaver.hiyobi.getReader(galleryID) + Log.d("Pupil", "Using Hiyobi.me") + } catch (e: Exception) { + getReader(galleryID) + } + } getReader(galleryID) } } @@ -78,17 +93,15 @@ class GalleryActivity : AppCompatActivity() { val reader = reader.await() launch(Dispatchers.Main) { - supportActionBar?.title = reader.title - with(gallery_progressbar) { - max = reader.images.size + max = reader.size progress = 0 visibility = View.VISIBLE } } - reader.images.chunked(8).forEach { chunked -> + reader.chunked(8).forEach { chunked -> chunked.map { async(Dispatchers.IO) { val url = if (it.second?.haswebp == 1) webpUrlFromUrl(it.first) else it.first diff --git a/app/src/main/java/xyz/quaver/pupil/MainActivity.kt b/app/src/main/java/xyz/quaver/pupil/MainActivity.kt index 64284234..d24131e3 100644 --- a/app/src/main/java/xyz/quaver/pupil/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/MainActivity.kt @@ -176,9 +176,10 @@ class MainActivity : AppCompatActivity() { private fun setupRecyclerView() { with(main_recyclerview) { adapter = GalleryBlockAdapter(galleries).apply { - setClickListener { + setClickListener { galleryID, title -> val intent = Intent(this@MainActivity, GalleryActivity::class.java) - intent.putExtra("GALLERY_ID", it) + intent.putExtra("GALLERY_ID", galleryID) + intent.putExtra("GALLERY_TITLE", title) //TODO: Maybe sprinke some transitions will be nice :D startActivity(intent) diff --git a/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt b/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt index b94db781..71851505 100644 --- a/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt +++ b/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt @@ -33,8 +33,8 @@ class GalleryBlockAdapter(private val galleries: List Unit)? = null - fun setClickListener(callback: ((Int) -> Unit)?) { + private var callback: ((Int, String) -> Unit)? = null + fun setClickListener(callback: ((Int, String) -> Unit)?) { this.callback = callback } @@ -74,7 +74,7 @@ class GalleryBlockAdapter(private val galleries: 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 + + + + + + diff --git a/libpupil/src/main/java/xyz/quaver/hitomi/readers.kt b/libpupil/src/main/java/xyz/quaver/hitomi/readers.kt index 8ceb06f9..5fee483d 100644 --- a/libpupil/src/main/java/xyz/quaver/hitomi/readers.kt +++ b/libpupil/src/main/java/xyz/quaver/hitomi/readers.kt @@ -1,11 +1,9 @@ package xyz.quaver.hitomi -import kotlinx.serialization.ImplicitReflectionSerializer import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonConfiguration import kotlinx.serialization.list -import kotlinx.serialization.parseList import org.jsoup.Jsoup import java.net.URL @@ -18,10 +16,7 @@ data class GalleryInfo( val name: String, val height: Int ) -data class Reader( - val title: String, - val images: List> -) +typealias Reader = List> //Set header `Referer` to reader url to avoid 403 error fun getReader(galleryID: Int) : Reader { val readerUrl = "https://hitomi.la/reader/$galleryID.html" @@ -29,8 +24,6 @@ fun getReader(galleryID: Int) : Reader { val doc = Jsoup.connect(readerUrl).get() - val title = doc.selectFirst("title").text() - val images = doc.select(".img-url").map { URL(protocol + urlFromURL(it.text())) } @@ -49,5 +42,5 @@ fun getReader(galleryID: Int) : Reader { if (images.size > galleryInfo.size) galleryInfo.addAll(arrayOfNulls(images.size - galleryInfo.size)) - return Reader(title, images zip galleryInfo) + return images zip galleryInfo } \ No newline at end of file diff --git a/libpupil/src/main/java/xyz/quaver/hiyobi/reader.kt b/libpupil/src/main/java/xyz/quaver/hiyobi/reader.kt new file mode 100644 index 00000000..dfd289bb --- /dev/null +++ b/libpupil/src/main/java/xyz/quaver/hiyobi/reader.kt @@ -0,0 +1,47 @@ +package xyz.quaver.hiyobi + +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonConfiguration +import kotlinx.serialization.json.content +import xyz.quaver.hitomi.Reader +import java.net.URL +import javax.net.ssl.HttpsURLConnection + +const val hiyobi = "xn--9w3b15m8vo.asia" +const val user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36" + +var cookie: String = "" + +fun renewCookie() : String { + val url = "https://$hiyobi/" + + with(URL(url).openConnection() as HttpsURLConnection) { + setRequestProperty("User-Agent", user_agent) + connectTimeout = 2000 + connect() + return headerFields["Set-Cookie"]!![0] + } +} + +fun getReader(galleryId: Int) : Reader { + val url = "https://$hiyobi/data/json/${galleryId}_list.json" + + if (cookie.isEmpty()) + cookie = renewCookie() + + val json = Json(JsonConfiguration.Stable).parseJson( + with(URL(url).openConnection() as HttpsURLConnection) { + setRequestProperty("User-Agent", user_agent) + setRequestProperty("Cookie", cookie) + connectTimeout = 2000 + connect() + + inputStream.bufferedReader().use { it.readText() } + } + ) + + return json.jsonArray.map { + val name = it.jsonObject["name"]!!.content + Pair(URL("https://$hiyobi/data/$galleryId/$name"), null) + } +} \ No newline at end of file diff --git a/libpupil/src/test/java/xyz/quaver/hitomi/UnitTest.kt b/libpupil/src/test/java/xyz/quaver/hitomi/UnitTest.kt index 17ac0e39..7f13d067 100644 --- a/libpupil/src/test/java/xyz/quaver/hitomi/UnitTest.kt +++ b/libpupil/src/test/java/xyz/quaver/hitomi/UnitTest.kt @@ -61,4 +61,9 @@ class UnitTest { print(reader) } + + @Test + fun test_hiyobi() { + xyz.quaver.hiyobi.getReader(1414061) + } } \ No newline at end of file From 720149c38ab115a6c23873206e5b74d212124b11 Mon Sep 17 00:00:00 2001 From: tom5079 Date: Mon, 13 May 2019 13:03:47 +0900 Subject: [PATCH 3/6] Add hiyobi image booster translation --- app/src/main/res/values-ja/strings.xml | 4 +++- app/src/main/res/values-ko/strings.xml | 4 +++- app/src/main/res/values/strings.xml | 3 +++ app/src/main/res/xml/root_preferences.xml | 6 +++--- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 2d50f270..63576ee9 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -1,6 +1,5 @@ - Pupil 言語: %1$s シリーズ: %1$s タイプ: %1$s @@ -20,4 +19,7 @@ アップデートダウンロード中 新しいアップデートがあります 注意 + イメージロード + ロード速度を向上させるためhiyobi.meからイメージロード + hiyobi.meからロード \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index c443a4b4..85b179fd 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -1,6 +1,5 @@ - Pupil 언어: %1$s 시리즈: %1$s 종류: %1$s @@ -20,4 +19,7 @@ 결과 없음 검색 캐시 + 이미지 로딩 + 속도 향상을 위해 가능하면 hiyobi.me에서 이미지 로드 + hiyobi.me 사용 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6544d152..473541df 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -36,5 +36,8 @@ Clear cache Currently using %1$d%2$s of cache Deleting cache can affect image loading speed. Do you want to continue? + Image Loading + Use hiyobi.me + Load images from hiyobi.me to improve loading speed (if available) diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index b17e2fbc..a967b6bd 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -31,12 +31,12 @@ + app:title="@string/settings_image_loading_title"> + app:title="@string/settings_use_hiyobi_title" + app:summary="@string/settings_use_hiyobi_summary"/> From 161d1bdcdd753117f9f329e64d80a9f206c27b0c Mon Sep 17 00:00:00 2001 From: tom5079 Date: Mon, 13 May 2019 20:07:42 +0900 Subject: [PATCH 4/6] History functionality added --- .idea/misc.xml | 2 +- app/build.gradle | 3 + .../java/xyz/quaver/pupil/GalleryActivity.kt | 2 - .../java/xyz/quaver/pupil/MainActivity.kt | 184 ++++++++++-------- .../java/xyz/quaver/pupil/SettingsActivity.kt | 41 +++- .../java/xyz/quaver/pupil/util/history.kt | 74 +++++++ .../main/res/drawable-anydpi/ic_history.xml | 10 + app/src/main/res/drawable-anydpi/ic_home.xml | 10 + app/src/main/res/drawable-hdpi/ic_history.png | Bin 0 -> 585 bytes app/src/main/res/drawable-hdpi/ic_home.png | Bin 0 -> 279 bytes app/src/main/res/drawable-mdpi/ic_history.png | Bin 0 -> 366 bytes app/src/main/res/drawable-mdpi/ic_home.png | Bin 0 -> 222 bytes .../main/res/drawable-xhdpi/ic_history.png | Bin 0 -> 700 bytes app/src/main/res/drawable-xhdpi/ic_home.png | Bin 0 -> 314 bytes .../main/res/drawable-xxhdpi/ic_history.png | Bin 0 -> 1057 bytes app/src/main/res/drawable-xxhdpi/ic_home.png | Bin 0 -> 395 bytes .../main/res/menu/activity_main_drawer.xml | 12 +- app/src/main/res/values-ja/strings.xml | 7 +- app/src/main/res/values-ko/strings.xml | 7 +- app/src/main/res/values/strings.xml | 8 +- app/src/main/res/xml/root_preferences.xml | 8 +- .../java/xyz/quaver/pupil/ExampleUnitTest.kt | 5 +- 22 files changed, 274 insertions(+), 99 deletions(-) create mode 100644 app/src/main/java/xyz/quaver/pupil/util/history.kt create mode 100644 app/src/main/res/drawable-anydpi/ic_history.xml create mode 100644 app/src/main/res/drawable-anydpi/ic_home.xml create mode 100644 app/src/main/res/drawable-hdpi/ic_history.png create mode 100644 app/src/main/res/drawable-hdpi/ic_home.png create mode 100644 app/src/main/res/drawable-mdpi/ic_history.png create mode 100644 app/src/main/res/drawable-mdpi/ic_home.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_history.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_home.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_history.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_home.png diff --git a/.idea/misc.xml b/.idea/misc.xml index 84da703c..7631aec3 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 66bcddaa..405be41f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -19,6 +19,9 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + kotlinOptions { + freeCompilerArgs += '-Xuse-experimental=kotlin.Experimental' + } } dependencies { diff --git a/app/src/main/java/xyz/quaver/pupil/GalleryActivity.kt b/app/src/main/java/xyz/quaver/pupil/GalleryActivity.kt index 92dfe9c5..00cbf6e8 100644 --- a/app/src/main/java/xyz/quaver/pupil/GalleryActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/GalleryActivity.kt @@ -11,11 +11,9 @@ import kotlinx.coroutines.* import xyz.quaver.hitomi.Reader import xyz.quaver.hitomi.getReader import xyz.quaver.hitomi.getReferer -import xyz.quaver.hiyobi.hiyobi import xyz.quaver.pupil.adapters.GalleryAdapter import java.io.File import java.io.FileOutputStream -import java.lang.Exception import java.net.URL import javax.net.ssl.HttpsURLConnection diff --git a/app/src/main/java/xyz/quaver/pupil/MainActivity.kt b/app/src/main/java/xyz/quaver/pupil/MainActivity.kt index d24131e3..5e4042b2 100644 --- a/app/src/main/java/xyz/quaver/pupil/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/MainActivity.kt @@ -15,7 +15,6 @@ import android.os.Environment import android.preference.PreferenceManager import android.text.* import android.text.style.AlignmentSpan -import android.util.Log import android.view.View import android.view.WindowManager import androidx.appcompat.app.AlertDialog @@ -37,6 +36,7 @@ import kotlinx.coroutines.* import xyz.quaver.hitomi.* import xyz.quaver.pupil.adapters.GalleryBlockAdapter import xyz.quaver.pupil.types.TagSuggestion +import xyz.quaver.pupil.util.Histories import xyz.quaver.pupil.util.SetLineOverlap import xyz.quaver.pupil.util.checkUpdate import xyz.quaver.pupil.util.getApkUrl @@ -45,13 +45,16 @@ import javax.net.ssl.HttpsURLConnection class MainActivity : AppCompatActivity() { - private val PERMISSION_REQUEST_CODE = 4585 + private val permissionRequestCode = 4585 private val galleries = ArrayList>() - private var isLoading = false private var query = "" + private var galleryIDs: Deferred>? = null + private var loadingJob: Job? = null + override fun onCreate(savedInstanceState: Bundle?) { + Histories.default = Histories(File(cacheDir, "histories.json")) super.onCreate(savedInstanceState) window.setFlags( @@ -75,15 +78,33 @@ class MainActivity : AppCompatActivity() { setProgressViewOffset(false, 0, resources.getDimensionPixelSize(R.dimen.progress_view_offset)) setOnRefreshListener { - runBlocking { - cleanJob?.join() + CoroutineScope(Dispatchers.Main).launch { + cancelFetch() + clearGalleries() + fetchGalleries(query) + loadBlocks() } - fetchGalleries(query, true) } } main_nav_view.setNavigationItemSelectedListener { - Log.d("Pupil", it.itemId.toString()) + CoroutineScope(Dispatchers.Main).launch { + main_drawer_layout.closeDrawers() + + cancelFetch() + clearGalleries() + when(it.itemId) { + R.id.main_drawer_home -> { + query = query.replace("HISTORY", "") + fetchGalleries(query) + } + R.id.main_drawer_history -> { + query += "HISTORY" + fetchGalleries(query) + } + } + loadBlocks() + } true } @@ -91,6 +112,7 @@ class MainActivity : AppCompatActivity() { setupRecyclerView() setupSearchBar() fetchGalleries(query) + loadBlocks() } override fun onBackPressed() { @@ -113,7 +135,7 @@ class MainActivity : AppCompatActivity() { setPositiveButton(android.R.string.ok) { _, _ -> } }.show() else - ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE) + ActivityCompat.requestPermissions(this, permissions, permissionRequestCode) } } @@ -183,6 +205,8 @@ class MainActivity : AppCompatActivity() { //TODO: Maybe sprinke some transitions will be nice :D startActivity(intent) + + Histories.default.add(galleryID) } } addOnScrollListener( @@ -192,9 +216,9 @@ class MainActivity : AppCompatActivity() { val layoutManager = recyclerView.layoutManager as LinearLayoutManager - if (!isLoading) + if (loadingJob?.isActive != true) if (layoutManager.findLastCompletelyVisibleItemPosition() == galleries.size) - fetchGalleries(query) + loadBlocks() } } ) @@ -311,7 +335,9 @@ class MainActivity : AppCompatActivity() { if (query != this@MainActivity.query) { this@MainActivity.query = query - fetchGalleries(query, true) + cancelFetch() + clearGalleries() + fetchGalleries(query) } } }) @@ -320,94 +346,96 @@ class MainActivity : AppCompatActivity() { } } - private val cache = ArrayList() - private var currentFetchingJob: Job? = null - private var cleanJob: Job? = null - private fun cancelFetch() { - isLoading = false - runBlocking { - cleanJob?.join() - currentFetchingJob?.cancelAndJoin() + galleryIDs?.cancelAndJoin() + loadingJob?.cancelAndJoin() } } - private fun fetchGalleries(query: String, clear: Boolean = false) { + private fun clearGalleries() { + galleries.clear() + + main_recyclerview.adapter?.notifyDataSetChanged() + + main_noresult.visibility = View.INVISIBLE + main_progressbar.show() + main_swipe_layout.isRefreshing = false + } + + private fun fetchGalleries(query: String, from: Int = 0) { val preference = PreferenceManager.getDefaultSharedPreferences(this) val perPage = preference.getString("per_page", "25")?.toInt() ?: 25 val defaultQuery = preference.getString("default_query", "")!! - if (clear) { - cancelFetch() - cleanJob = CoroutineScope(Dispatchers.Main).launch { - cache.clear() - galleries.clear() + galleryIDs = null - main_recyclerview.adapter?.notifyDataSetChanged() - - main_noresult.visibility = View.INVISIBLE - main_progressbar.show() - main_swipe_layout.isRefreshing = false - } - } - - if (isLoading) + if (galleryIDs?.isActive == true) return - isLoading = true + galleryIDs = CoroutineScope(Dispatchers.IO).async { + when { + query.contains("HISTORY") -> + Histories.default.toList() + query.isEmpty() and defaultQuery.isEmpty() -> + fetchNozomi(start = from, count = perPage) + else -> + doSearch("$defaultQuery $query") + } + } + } - currentFetchingJob = CoroutineScope(Dispatchers.IO).launch { - try { - val galleryIDs: List + private fun loadBlocks() { + val preference = PreferenceManager.getDefaultSharedPreferences(this) + val perPage = preference.getString("per_page", "25")?.toInt() ?: 25 + val defaultQuery = preference.getString("default_query", "")!! - cleanJob?.join() + loadingJob = CoroutineScope(Dispatchers.IO).launch { + val galleryIDs = galleryIDs?.await() - if (query.isEmpty() && defaultQuery.isEmpty()) - galleryIDs = fetchNozomi(start = galleries.size, count = perPage) - else { - if (cache.isEmpty()) - cache.addAll(doSearch("$defaultQuery $query")) - - galleryIDs = cache.slice(galleries.size until Math.min(galleries.size + perPage, cache.size)) - - with(main_recyclerview.adapter as GalleryBlockAdapter) { - noMore = galleries.size + perPage >= cache.size - } + if (galleryIDs.isNullOrEmpty()) { //No result + withContext(Dispatchers.Main) { + main_noresult.visibility = View.VISIBLE + main_progressbar.hide() } - if (query.isNotEmpty() and defaultQuery.isNotEmpty() and cache.isNullOrEmpty()) { + return@launch + } + + if (query.isEmpty() and defaultQuery.isEmpty()) + fetchGalleries("", galleries.size+perPage) + else + with(main_recyclerview.adapter as GalleryBlockAdapter) { + noMore = galleries.size + perPage >= galleryIDs.size + } + + when { + query.isEmpty() and defaultQuery.isEmpty() -> + galleryIDs + else -> + galleryIDs.slice(galleries.size until Math.min(galleries.size+perPage, galleryIDs.size)) + }.chunked(4).forEach { chunked -> + chunked.map { + async { + val galleryBlock = getGalleryBlock(it) + val thumbnail: Bitmap + + with(galleryBlock.thumbnails[0].openConnection() as HttpsURLConnection) { + thumbnail = BitmapFactory.decodeStream(inputStream) + } + + Pair(galleryBlock, thumbnail) + } + }.forEach { + val galleryBlock = it.await() + withContext(Dispatchers.Main) { - main_noresult.visibility = View.VISIBLE main_progressbar.hide() + + galleries.add(galleryBlock) + main_recyclerview.adapter?.notifyItemInserted(galleries.size - 1) } } - - galleryIDs.chunked(4).forEach { chunked -> - chunked.map { - async { - val galleryBlock = getGalleryBlock(it) - val thumbnail: Bitmap - - with(galleryBlock.thumbnails[0].openConnection() as HttpsURLConnection) { - thumbnail = BitmapFactory.decodeStream(inputStream) - } - - Pair(galleryBlock, thumbnail) - } - }.forEach { - val galleryBlock = it.await() - - withContext(Dispatchers.Main) { - main_progressbar.hide() - - galleries.add(galleryBlock) - main_recyclerview.adapter?.notifyItemInserted(galleries.size - 1) - } - } - } - } finally { - isLoading = false } } } diff --git a/app/src/main/java/xyz/quaver/pupil/SettingsActivity.kt b/app/src/main/java/xyz/quaver/pupil/SettingsActivity.kt index 40624e27..b9d95dda 100644 --- a/app/src/main/java/xyz/quaver/pupil/SettingsActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/SettingsActivity.kt @@ -7,6 +7,8 @@ import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat +import xyz.quaver.pupil.util.Histories +import java.io.File class SettingsActivity : AppCompatActivity() { @@ -35,8 +37,8 @@ class SettingsActivity : AppCompatActivity() { "TB" //really? ) - private fun getCacheSize() : String { - var size = context!!.cacheDir.walk().map { it.length() }.sum() + private fun getCacheSize(dir: File) : String { + var size = dir.walk().map { it.length() }.sum() var suffixIndex = 0 while (size >= 1024) { @@ -50,22 +52,43 @@ class SettingsActivity : AppCompatActivity() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.root_preferences, rootKey) - with(findPreference("delete_cache")) { + with(findPreference("delete_image_cache")) { this ?: return@with - summary = getCacheSize() + val dir = File(context.cacheDir, "imageCache") + + summary = getCacheSize(dir) setOnPreferenceClickListener { AlertDialog.Builder(context).apply { setTitle(R.string.warning) setMessage(R.string.settings_clear_cache_alert_message) setPositiveButton(android.R.string.yes) { _, _ -> - with(context.cacheDir) { - if (exists()) - deleteRecursively() - } + if (dir.exists()) + dir.deleteRecursively() - summary = getCacheSize() + summary = getCacheSize(dir) + } + setNegativeButton(android.R.string.no) { _, _ -> } + }.show() + + true + } + } + with(findPreference("clear_history")) { + this ?: return@with + + val histories = Histories.default + + summary = getString(R.string.settings_clear_history_summary, histories.size) + + setOnPreferenceClickListener { + AlertDialog.Builder(context).apply { + setTitle(R.string.warning) + setMessage(R.string.settings_clear_history_alert_message) + setPositiveButton(android.R.string.yes) { _, _ -> + histories.clear() + summary = getString(R.string.settings_clear_history_summary, histories.size) } setNegativeButton(android.R.string.no) { _, _ -> } }.show() diff --git a/app/src/main/java/xyz/quaver/pupil/util/history.kt b/app/src/main/java/xyz/quaver/pupil/util/history.kt new file mode 100644 index 00000000..8ebfaad1 --- /dev/null +++ b/app/src/main/java/xyz/quaver/pupil/util/history.kt @@ -0,0 +1,74 @@ +package xyz.quaver.pupil.util + +import kotlinx.serialization.ImplicitReflectionSerializer +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonConfiguration +import kotlinx.serialization.parseList +import kotlinx.serialization.stringify +import java.io.File + + +class Histories(private val file: File) : ArrayList() { + + init { + if (!file.exists()) + file.parentFile.mkdirs() + + try { + load() + } catch (e: Exception) { + save() + } + } + + companion object { + lateinit var default: Histories + + fun load(file: File) : Histories { + return Histories(file).load() + } + } + + @UseExperimental(ImplicitReflectionSerializer::class) + fun load() : Histories { + return apply { + super.clear() + addAll( + Json(JsonConfiguration.Stable).parseList( + file.bufferedReader().use { it.readText() } + ) + ) + } + } + + @UseExperimental(ImplicitReflectionSerializer::class) + fun save() { + file.writeText(Json(JsonConfiguration.Stable).stringify(this)) + } + + override fun add(element: Int): Boolean { + load() + + if (contains(element)) + super.remove(element) + + super.add(0, element) + + save() + + return true + } + + override fun remove(element: Int): Boolean { + load() + val retval = super.remove(element) + save() + + return retval + } + + override fun clear() { + super.clear() + save() + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable-anydpi/ic_history.xml b/app/src/main/res/drawable-anydpi/ic_history.xml new file mode 100644 index 00000000..e5e6c6c8 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_history.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable-anydpi/ic_home.xml b/app/src/main/res/drawable-anydpi/ic_home.xml new file mode 100644 index 00000000..08ebbdf2 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_home.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable-hdpi/ic_history.png b/app/src/main/res/drawable-hdpi/ic_history.png new file mode 100644 index 0000000000000000000000000000000000000000..8610919f1413b616297be1e99fa10c9be2dfcc64 GIT binary patch literal 585 zcmV-P0=E5$P)ErbA+Lxp(xPOCLq27#Q*VNkbDzJJxv_q z;NZXkw4fG{*kb0;-m>D-f z=8_v#8;}h83{0SQWM%|AkbWeyHjrb8Gm-&+K~X?qIt+lC12z+6K1l`u%aqed4w_ED zGO#+J9tQ&IrX#66O^Rc5kfX}n++3U*4g#5j9CaXjh;>jklBUH(LG<{?)r*a|-d zpu~M5>!tf3^|%}a#J$?u+H4d#hy+L71C|}~I6?@yp1TDMDNl-{jDVwXItErnK-)sE zVS0d-?M9&GiWDVk9F8L77?ipX=#a@kJ-?xPzXKa<_7r7%G)LV9VmUIZ9etp_Lm>Ug zEdsI&MyR9qlj9gIUfOms%bQCWSXh(6-cBMzbC_n-L Xc|PDQ5^yx}00000NkvXXu0mjfL2&Z^ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_home.png b/app/src/main/res/drawable-hdpi/ic_home.png new file mode 100644 index 0000000000000000000000000000000000000000..caccfac02413efafdf8b724b579d244449f9b76a GIT binary patch literal 279 zcmV+y0qFjTP)wulZ(n2V~#YmULeENm?0u#tv%7eCP9X2FiWEFS^*iR zU0k4p!s~^ZU!Ws}C(ZN%jTD|V-wSj?;Yl;EKU38f%qm6e}-ZZdp1apY=aF93{-)J><8li1n_>4T2ftY3)J`yYQQTX zt}!$;)YsP5<^f?48zcsm1F3lj(nE^N-$FI6wzjtB#ibS`2T}u7`<5u5AO*{6AeWH{ zH!&hvvLCNXpx2$D3SVM#IY;0;pUKRPQW&7F>tA zLZ4I%pb-zU;5t4FK7kbBidcLWK!XWn!6)=2S&u7?qZ`t&ng9R* M07*qoM6N<$g6*$~*8l(j literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_home.png b/app/src/main/res/drawable-mdpi/ic_home.png new file mode 100644 index 0000000000000000000000000000000000000000..1eccf9f3ffdf30ff21d5eb94d6e42541f8c8fb8d GIT binary patch literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjOFdm2Ln>}1CrGe{u=E@|cFb0R zCn@-9%7TS!9QLqu{C76&IO`>Pc;&{%|gt9_YP)S*ai)ke3M(i>RfI7U}c{h^3v63)l;`f(Vu>*os9=A$E#3iij!v z0~U&nV)Pr>Vp;btcYC|%o!r0&A-6j--|Xz%>|RStEV0BA%fFIjGTEQY<(7c`Y&Kg1 z9)ULo`dy=EG=|28#_>!hvjFF+z$ftS5;V3-bN|e7M6w76EF*yy^`PJ*S4Eb?`rpsJVVG9ABGLTftNy}rL|rVgI$lz|^9{E-&(HI?CmI5Y1wTt$6$l)8nCqDUn|CDGtSa|5 zLVM8gQYuvmuoBC!!lzR2gr!>)B6008l1c>F+-o6?7FE*cKpCSKHv#Fs1SJNl@yD`o}dVjErGzR(`K#s=;bSJ2uwhX5%596 za=QY+7qABm8cQLMBrF#xGzUBh^Il+QrCFz`yop_s*mRo;ILvfn{08tY=(quj7 zjzBN+^3>r)cS9?bPN!$##Av9l7KK~7?MPnk@`5N&!stchuGb}LHP5bJJ|gvjLv{@l i$xlqN#1cy^O7a5-nKLtD!KaY`0000!a#Ze literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_home.png b/app/src/main/res/drawable-xhdpi/ic_home.png new file mode 100644 index 0000000000000000000000000000000000000000..cea7b6c519081c4d08b14b4d1c6914d52bbea88f GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezr3(Ffw|&IEGZ*dOP(XXS0KV>)C_R z=Q0m0esJ)v*rk@#2=`MSqSq4GGY@RuF4Hu#k>`oRrgwd>wf-Mwb_~DQ-a0>(qe&tC z>`{r&2|s=YJX4t~?4R`O;Q615Pfl;zGb!i0x_-$Yz09AhR^_SOI)8%Owtn)ft(qOz zoAw;IFXDOfda18pTEPTyHoM6!d$xY_b9&5GnfPRLb^PqMis}>GHQR1_?^Cs7{KWKs z@!jMFYN^}g_snd(l(zd|w1h_P7xwds3$|R8-XqGq)c41ON}efZ|C+@O0&cC5w`py> zbgcG+2)ozp4F|h*_Z;n5$iQ_(L*TW&MgtQZ8FDKC9l!jH_|yB1skM3ccz|KT;OXk; Jvd$@?2>|LQiW>j` literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_history.png b/app/src/main/res/drawable-xxhdpi/ic_history.png new file mode 100644 index 0000000000000000000000000000000000000000..c22644ebb2577f219008f552e397f7b84c1e2823 GIT binary patch literal 1057 zcmV++1m63JP)%f>^34M7+X6qvr(?B#o^Ei3BWc1Pg0P zu+kzDvEx#9B*5|p|{a*^q+WUR=lG-{)9KcjEszIfkM-o zioe4OU+M1d-j!4iy+iNP7@D%CNw=)=*`x{1JSI0}a4Qedm^vVljy`XzbxQJVtfa8q zs*vH|b`uU+rPv~#DLK%iM6y)6ICtC-*bx)0-jvJbJ+Aa2StK(ix^=kRTBDr=6CdpRiNiH*F>9%rdITA}+RBSc788_8Eit=IIh0oFSNixUXuv)u`!c%5F)f8Jc zywc+-T|iY~MWZ%z9$8gBpC*)>21uj;vOHfHG8x_{B>>fP08m}x8YW$o7Q;CJXxMt`fx(s~t8mzNfJjFPK+7fpT8$E7 zs_wE0kf_h109rK(P-G-9RoB=ANYsy!5m?s*$8DW5=uR}^-G|-)WD%r#s}>~qSyxxr zK5w>|VUX%+wpf6_gKvVjdf}uEfpoV8A9O0_{GOU%C%p*sDM6~G^c6Mm55@Q|P(B>U zJW*^Bq?)0KwjcaF<|wH?I5@aH(^4Y|NDy|%Lih3n#$Hg!{RFwEGc8tiK*BS(ZM87T zIfHM=j+g+@%goyyDv)e~6Y6HRLDtid{Ga&!kQWUz2}onEPb?twXrR}8&#RVe2qfp= z1RL_$T9+!7$_}rZ_F@GefNvE%r>u^B3WY4MlIUA{b_a*PQ|3p{x}=-LnIvy6FK9aR z58%CyEythhFPf3=3!+Wgkin~%AZ5U_n9w)Kk^54F$AZ3Ox#lAPck(k9$m<~&L8zMF)=YQF)=YQ b<%<3RpzHiO>e!Wi00000NkvXXu0mjf8;J3w literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_home.png b/app/src/main/res/drawable-xxhdpi/ic_home.png new file mode 100644 index 0000000000000000000000000000000000000000..a576a1a4e111b2191c668e5991f83e74a21d159a GIT binary patch literal 395 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2U<~qfaSW-r^>+G3&O-?TZd*5O zE^D09DB>Abz!@w|S z^O{w!7F^CQu~7^P+q8I1wa@zS8G@f|;=6mEdHO{yo_{vVFHl5U@Z!D+ldrw9Ev{W_ zbn|8J9Fx83v!~A4r1Ny<>d)*&m(EqCi50!tb?+2&JWyTP#m&L>Ys)re^IK+Cm6?ZH zR^QBRm}By{@2?2+2IIIt3u*)#u60XK$!EGy^|9$wGsBj+ISc+MF|2)VuTjmi;Oif@ zrwt5S=Ivi#!r}1xC#Tn8hAsDAIR0GC&?7&kp5wp{$DhX;dc>zFvn0$}AY;hzmwjn7 z!x!l(eM}eP1FU!)>>XcPFg#{S72!<&ch*6mNuWi6#W!%m^ZQN^wjzfk2O5(F92N|D ZJD6XEh$b&sH@gNT;OXk;vd$@?2>|rnq2mAm literal 0 HcmV?d00001 diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml index 71a9e813..1877c34f 100644 --- a/app/src/main/res/menu/activity_main_drawer.xml +++ b/app/src/main/res/menu/activity_main_drawer.xml @@ -1,7 +1,15 @@ - + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 63576ee9..eacd6842 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -7,7 +7,7 @@ 検索 ギャラリー検索 キャッシュ - キャッシュクリア + イメージキャッシュクリア キャッシュをクリアするとイメージのロード速度に影響を与えます。実行しますか? キャッシュサイズ: %1$d%2$s デフォルト検索キーワード @@ -22,4 +22,9 @@ イメージロード ロード速度を向上させるためhiyobi.meからイメージロード hiyobi.meからロード + 履歴の削除 + 履歴を削除しますか? + 履歴数: %1$d + 履歴 + トップ \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 85b179fd..e4872bb0 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -6,7 +6,7 @@ 권한을 거부하면 일부 기능이 작동하지 않을 수 있습니다 갤러리 검색 기본 검색어 - 캐시 정리하기 + 이미지 캐시 정리하기 캐시를 정리하면 이미지 로딩속도가 느려질 수 있습니다. 계속하시겠습니까? 현재 캐시 사용량: %1$d%2$s 한 번에 로드할 갤러리 수 @@ -22,4 +22,9 @@ 이미지 로딩 속도 향상을 위해 가능하면 hiyobi.me에서 이미지 로드 hiyobi.me 사용 + 히스토리 삭제 + 히스토리를 삭제하시겠습니까? + 히스토리 %1$d개 저장됨 + 히스토리 + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 473541df..1d165044 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -18,6 +18,9 @@ Search No result + Home + History + Update available Version %1$s is available!\n(current version is %2$s)\nDo you want to update? Downloading apk… @@ -33,9 +36,12 @@ Galleries per page Default query Cache - Clear cache + Clear image cache Currently using %1$d%2$s of cache Deleting cache can affect image loading speed. Do you want to continue? + Clear history + Do you want to clear histories? + %1$d histories saved Image Loading Use hiyobi.me Load images from hiyobi.me to improve loading speed (if available) diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index a967b6bd..5dbfcadf 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -25,8 +25,12 @@ app:title="@string/settings_cache_title"> + app:title="@string/settings_clear_image_cache" + app:key="delete_image_cache"/> + + diff --git a/app/src/test/java/xyz/quaver/pupil/ExampleUnitTest.kt b/app/src/test/java/xyz/quaver/pupil/ExampleUnitTest.kt index 763e19e4..fec18cac 100644 --- a/app/src/test/java/xyz/quaver/pupil/ExampleUnitTest.kt +++ b/app/src/test/java/xyz/quaver/pupil/ExampleUnitTest.kt @@ -1,7 +1,7 @@ package xyz.quaver.pupil +import kotlinx.serialization.ImplicitReflectionSerializer import org.junit.Test -import xyz.quaver.pupil.util.checkUpdate /** * Example local unit test, which will execute on the development machine (host). @@ -12,8 +12,9 @@ import xyz.quaver.pupil.util.checkUpdate class ExampleUnitTest { @Test + @ImplicitReflectionSerializer fun test() { - print(checkUpdate("https://api.github.com/repos/tom5079/Pupil-issue/releases", "0.0.1")) + } } From 48c190b449dc6131ee5476a8d6fed7bcffc7d1ba Mon Sep 17 00:00:00 2001 From: tom5079 Date: Mon, 13 May 2019 21:29:38 +0900 Subject: [PATCH 5/6] Add Release note to update --- app/build.gradle | 9 ++- .../quaver/pupil/ExampleInstrumentedTest.kt | 2 +- .../java/xyz/quaver/pupil/MainActivity.kt | 65 ++++++++++++++++++- app/src/main/res/values-ja/strings.xml | 3 +- app/src/main/res/values-ko/strings.xml | 3 +- app/src/main/res/values-v23/styles.xml | 1 - app/src/main/res/values/strings.xml | 3 +- 7 files changed, 75 insertions(+), 11 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 405be41f..396af997 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,10 +7,10 @@ android { compileSdkVersion 28 defaultConfig { applicationId "xyz.quaver.pupil" - minSdkVersion 15 + minSdkVersion 16 targetSdkVersion 28 - versionCode 2 - versionName "1.1" + versionCode 3 + versionName "1.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -25,6 +25,8 @@ android { } dependencies { + def markwonVersion = "3.0.1" + implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1' @@ -37,6 +39,7 @@ dependencies { implementation 'com.github.arimorty:floatingsearchview:2.1.1' implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation "ru.noties.markwon:core:${markwonVersion}" testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.0' androidTestImplementation 'androidx.test:runner:1.1.1' diff --git a/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt b/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt index 16060355..41211cc7 100644 --- a/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt +++ b/app/src/androidTest/java/xyz/quaver/pupil/ExampleInstrumentedTest.kt @@ -13,6 +13,7 @@ import org.junit.Test import org.junit.runner.RunWith import xyz.quaver.hiyobi.getReader import java.io.File +import java.util.* /** * Instrumented test, which will execute on an Android device. @@ -40,6 +41,5 @@ class ExampleInstrumentedTest { @Test fun test_doSearch() { - getReader(1414061) } } diff --git a/app/src/main/java/xyz/quaver/pupil/MainActivity.kt b/app/src/main/java/xyz/quaver/pupil/MainActivity.kt index 5e4042b2..1b48419e 100644 --- a/app/src/main/java/xyz/quaver/pupil/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/MainActivity.kt @@ -10,16 +10,20 @@ import android.content.pm.PackageManager import android.graphics.Bitmap import android.graphics.BitmapFactory import android.net.Uri +import android.os.Build import android.os.Bundle import android.os.Environment import android.preference.PreferenceManager import android.text.* import android.text.style.AlignmentSpan +import android.util.Log 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.app.NotificationCompat import androidx.core.content.ContextCompat import androidx.core.content.FileProvider import androidx.core.content.res.ResourcesCompat @@ -33,6 +37,9 @@ import com.google.android.material.appbar.AppBarLayout import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main_content.* import kotlinx.coroutines.* +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.content +import ru.noties.markwon.Markwon import xyz.quaver.hitomi.* import xyz.quaver.pupil.adapters.GalleryBlockAdapter import xyz.quaver.pupil.types.TagSuggestion @@ -41,7 +48,10 @@ import xyz.quaver.pupil.util.SetLineOverlap import xyz.quaver.pupil.util.checkUpdate import xyz.quaver.pupil.util.getApkUrl import java.io.File +import java.lang.StringBuilder +import java.util.* import javax.net.ssl.HttpsURLConnection +import kotlin.collections.ArrayList class MainActivity : AppCompatActivity() { @@ -65,7 +75,7 @@ class MainActivity : AppCompatActivity() { checkPermission() - update() + checkUpdate() main_appbar_layout.addOnOffsetChangedListener( AppBarLayout.OnOffsetChangedListener { _, p1 -> @@ -139,7 +149,50 @@ class MainActivity : AppCompatActivity() { } } - private fun update() { + private fun checkUpdate() { + + fun extractReleaseNote(update: JsonObject, locale: String) : String { + val markdown = update["body"]!!.content + + val target = when(locale) { + "ko" -> "한국어" + "ja" -> "日本語" + else -> "English" + } + + val releaseNote = Regex("^# Release Note.+$") + val language = Regex("^## $target$") + val end = Regex("^#.+$") + + var releaseNoteFlag = false + var languageFlag = false + + val result = StringBuilder() + + for(line in markdown.split('\n')) { + if (releaseNote.matches(line)) { + releaseNoteFlag = true + continue + } + + if (releaseNoteFlag) { + if (language.matches(line)) { + languageFlag = true + continue + } + } + + if (languageFlag) { + if (end.matches(line)) + break + + result.append(line+"\n") + } + } + + 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 @@ -151,8 +204,13 @@ class MainActivity : AppCompatActivity() { val dialog = AlertDialog.Builder(this@MainActivity).apply { setTitle(R.string.update_title) - setMessage(getString(R.string.update_message, update["tag_name"], BuildConfig.VERSION_NAME)) + 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( @@ -168,6 +226,7 @@ class MainActivity : AppCompatActivity() { 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 diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index eacd6842..f79d7c26 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -15,7 +15,6 @@ 一回にロードするギャラリー数 検索設定 設定 - 新バージョン%1$sをリリースしました\n(現バージョン: %2$s)\nアップデートしますか? アップデートダウンロード中 新しいアップデートがあります 注意 @@ -27,4 +26,6 @@ 履歴数: %1$d 履歴 トップ + ダウンロード中 + # リリースノート(v%1$s)\n%2$s \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index e4872bb0..309a4a2d 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -12,7 +12,6 @@ 한 번에 로드할 갤러리 수 검색 설정 설정 - 버전 %1$s이 출시되었습니다.\n(현재 %2$s)\n업데이트 하시겠습니까? apk 다운로드중… 업데이트가 있습니다! 경고 @@ -27,4 +26,6 @@ 히스토리 %1$d개 저장됨 히스토리 + 다운로드 중 + # 릴리즈 노트(v%1$s)\n%2$s \ No newline at end of file diff --git a/app/src/main/res/values-v23/styles.xml b/app/src/main/res/values-v23/styles.xml index 9c3f02d2..0cce6118 100644 --- a/app/src/main/res/values-v23/styles.xml +++ b/app/src/main/res/values-v23/styles.xml @@ -1,7 +1,6 @@