Add nightly build type
@@ -1,3 +1,5 @@
|
|||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
id 'kotlin-android'
|
id 'kotlin-android'
|
||||||
@@ -37,6 +39,12 @@ android {
|
|||||||
shrinkResources true
|
shrinkResources true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
|
nightly {
|
||||||
|
initWith release
|
||||||
|
applicationIdSuffix = '.nightly'
|
||||||
|
defaultConfig.versionCode = LocalDateTime.now().format("yyMMdd").toInteger()
|
||||||
|
defaultConfig.versionName = "N" + LocalDateTime.now().format("yyMMdd")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
viewBinding true
|
viewBinding true
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.koitharu.kotatsu.core.github
|
package org.koitharu.kotatsu.core.github
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
@@ -9,6 +11,7 @@ import okhttp3.Request
|
|||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import org.koitharu.kotatsu.BuildConfig
|
import org.koitharu.kotatsu.BuildConfig
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.network.BaseHttpClient
|
import org.koitharu.kotatsu.core.network.BaseHttpClient
|
||||||
import org.koitharu.kotatsu.core.os.AppValidator
|
import org.koitharu.kotatsu.core.os.AppValidator
|
||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
@@ -22,22 +25,29 @@ import javax.inject.Inject
|
|||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
private const val CONTENT_TYPE_APK = "application/vnd.android.package-archive"
|
private const val CONTENT_TYPE_APK = "application/vnd.android.package-archive"
|
||||||
|
private const val BUILD_TYPE_RELEASE = "release"
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class AppUpdateRepository @Inject constructor(
|
class AppUpdateRepository @Inject constructor(
|
||||||
private val appValidator: AppValidator,
|
private val appValidator: AppValidator,
|
||||||
private val settings: AppSettings,
|
private val settings: AppSettings,
|
||||||
@BaseHttpClient private val okHttp: OkHttpClient,
|
@BaseHttpClient private val okHttp: OkHttpClient,
|
||||||
|
@ApplicationContext context: Context,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val availableUpdate = MutableStateFlow<AppVersion?>(null)
|
private val availableUpdate = MutableStateFlow<AppVersion?>(null)
|
||||||
|
private val releasesUrl = buildString {
|
||||||
|
append("https://api.github.com/repos/")
|
||||||
|
append(context.getString(R.string.github_updates_repo))
|
||||||
|
append("/releases?page=1&per_page=10")
|
||||||
|
}
|
||||||
|
|
||||||
fun observeAvailableUpdate() = availableUpdate.asStateFlow()
|
fun observeAvailableUpdate() = availableUpdate.asStateFlow()
|
||||||
|
|
||||||
suspend fun getAvailableVersions(): List<AppVersion> {
|
suspend fun getAvailableVersions(): List<AppVersion> {
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.get()
|
.get()
|
||||||
.url("https://api.github.com/repos/KotatsuApp/Kotatsu/releases?page=1&per_page=10")
|
.url(releasesUrl)
|
||||||
val jsonArray = okHttp.newCall(request.build()).await().parseJsonArray()
|
val jsonArray = okHttp.newCall(request.build()).await().parseJsonArray()
|
||||||
return jsonArray.mapJSONNotNull { json ->
|
return jsonArray.mapJSONNotNull { json ->
|
||||||
val asset = json.optJSONArray("assets")?.find { jo ->
|
val asset = json.optJSONArray("assets")?.find { jo ->
|
||||||
@@ -74,8 +84,9 @@ class AppUpdateRepository @Inject constructor(
|
|||||||
}.getOrNull()
|
}.getOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("KotlinConstantConditions")
|
||||||
fun isUpdateSupported(): Boolean {
|
fun isUpdateSupported(): Boolean {
|
||||||
return BuildConfig.DEBUG || appValidator.isOriginalApp
|
return BuildConfig.BUILD_TYPE != BUILD_TYPE_RELEASE || appValidator.isOriginalApp
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getCurrentVersionChangelog(): String? {
|
suspend fun getCurrentVersionChangelog(): String? {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ class AboutSettingsFragment : BasePreferenceFragment(R.string.about) {
|
|||||||
isEnabled = viewModel.isUpdateSupported
|
isEnabled = viewModel.isUpdateSupported
|
||||||
}
|
}
|
||||||
findPreference<SwitchPreferenceCompat>(AppSettings.KEY_UPDATES_UNSTABLE)?.run {
|
findPreference<SwitchPreferenceCompat>(AppSettings.KEY_UPDATES_UNSTABLE)?.run {
|
||||||
|
isVisible = viewModel.isUpdateSupported
|
||||||
isEnabled = VersionId(BuildConfig.VERSION_NAME).isStable
|
isEnabled = VersionId(BuildConfig.VERSION_NAME).isStable
|
||||||
if (!isEnabled) isChecked = true
|
if (!isEnabled) isChecked = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
<string name="url_error_report" translatable="false">https://bugs.kotatsu.app/report</string>
|
<string name="url_error_report" translatable="false">https://bugs.kotatsu.app/report</string>
|
||||||
<string name="account_type_sync" translatable="false">org.kotatsu.sync</string>
|
<string name="account_type_sync" translatable="false">org.kotatsu.sync</string>
|
||||||
<string name="sync_url_default" translatable="false">https://sync.kotatsu.app</string>
|
<string name="sync_url_default" translatable="false">https://sync.kotatsu.app</string>
|
||||||
|
<string name="github_updates_repo" translatable="false">KotatsuApp/Kotatsu</string>
|
||||||
<string name="shikimori_clientId" translatable="false">Mw6F0tPEOgyV7F9U9Twg50Q8SndMY7hzIOfXg0AX_XU</string>
|
<string name="shikimori_clientId" translatable="false">Mw6F0tPEOgyV7F9U9Twg50Q8SndMY7hzIOfXg0AX_XU</string>
|
||||||
<string name="shikimori_clientSecret" translatable="false">euBMt1GGRSDpVIFQVPxZrO7Kh6X4gWyv0dABuj4B-M8</string>
|
<string name="shikimori_clientSecret" translatable="false">euBMt1GGRSDpVIFQVPxZrO7Kh6X4gWyv0dABuj4B-M8</string>
|
||||||
<string name="anilist_clientId" translatable="false">9887</string>
|
<string name="anilist_clientId" translatable="false">9887</string>
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package org.koitharu.kotatsu
|
||||||
|
|
||||||
|
import org.koitharu.kotatsu.core.BaseApp
|
||||||
|
|
||||||
|
class KotatsuApp : BaseApp()
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package org.koitharu.kotatsu.core.network
|
||||||
|
|
||||||
|
import okhttp3.Interceptor
|
||||||
|
import okhttp3.Response
|
||||||
|
|
||||||
|
class CurlLoggingInterceptor : Interceptor {
|
||||||
|
|
||||||
|
override fun intercept(chain: Interceptor.Chain): Response {
|
||||||
|
return chain.proceed(chain.request()) // no-op implementation
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
@file:Suppress("UnusedReceiverParameter")
|
||||||
|
|
||||||
|
package org.koitharu.kotatsu.core.util.ext
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun Throwable.printStackTraceDebug() = Unit
|
||||||
|
|
||||||
|
fun assertNotInMainThread() = Unit
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.koitharu.kotatsu.settings
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuInflater
|
||||||
|
import android.view.MenuItem
|
||||||
|
import androidx.core.view.MenuProvider
|
||||||
|
|
||||||
|
@Suppress("UNUSED_PARAMETER")
|
||||||
|
class SettingsMenuProvider(context: Context) : MenuProvider {
|
||||||
|
|
||||||
|
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) = Unit
|
||||||
|
|
||||||
|
override fun onMenuItemSelected(menuItem: MenuItem): Boolean = false
|
||||||
|
}
|
||||||
16
app/src/nightly/res/drawable/ic_launcher_foreground.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="432"
|
||||||
|
android:viewportHeight="432">
|
||||||
|
<group android:scaleX="0.96"
|
||||||
|
android:scaleY="0.96"
|
||||||
|
android:translateX="8.64"
|
||||||
|
android:translateY="8.64">
|
||||||
|
<path
|
||||||
|
android:pathData="m200.16,188.47c-1.26,-0.01 -2.53,0.27 -3.72,0.85 -2.09,1.05 -20.12,11.3 -20.82,53.73 -2.47,3.69 -7.82,11.89 -14.48,23.18l-8.1,14.19c-3.22,5.83 -6.59,12.21 -10,18.98l-7.29,15.01c-17.36,37.27 -33.59,83.66 -33.59,127.04 0,67.89 57.06,125.76 59.5,128.19 0.89,0.89 1.99,1.58 3.19,1.98 1.05,0.35 26.24,8.58 67.89,8.58 2.17,0 4.24,-0.86 5.77,-2.39l5.77,-5.77h9.56l5.77,5.77c1.53,1.53 3.6,2.39 5.77,2.39 41.65,0 66.83,-8.22 67.89,-8.58 1.2,-0.4 2.3,-1.08 3.19,-1.98 2.44,-2.42 59.5,-60.3 59.5,-128.19 0,-43.38 -16.23,-89.78 -33.59,-127.04l-7.3,-15.03c-3.41,-6.76 -6.78,-13.14 -10,-18.97l-8.1,-14.18c-6.66,-11.28 -12,-19.49 -14.48,-23.18 -0.7,-42.43 -18.73,-52.68 -20.82,-53.73 -3.14,-1.55 -6.95,-0.96 -9.42,1.53 -12,12 -19.81,23.96 -23.51,30.25h-39.37c-3.7,-6.3 -11.51,-18.25 -23.51,-30.25 -1.54,-1.55 -3.61,-2.37 -5.7,-2.38zM208.26,253.76c4.51,0 4.32,7.2 4.32,11.71 4.51,0 12,0.1 12,4.61 0,9.01 -7.32,16.32 -16.32,16.32 -9.01,0 -16.32,-7.32 -16.32,-16.32 -0,-9.01 7.32,-16.32 16.32,-16.32zM289.87,253.76c4.51,0 4.32,7.2 4.32,11.71 4.51,0 12,0.1 12,4.61 0,9.01 -7.32,16.32 -16.32,16.32 -9.01,0 -16.32,-7.32 -16.32,-16.32 0,-9.01 7.32,-16.32 16.32,-16.32zM240.9,278.24h16.32c3.3,0 6.28,1.99 7.54,5.04 1.26,3.04 0.56,6.57 -1.77,8.89l-8.16,8.16c-1.59,1.59 -3.68,2.39 -5.77,2.39 -2.09,0 -4.18,-0.8 -5.77,-2.39l-8.16,-8.16c-2.33,-2.33 -3.03,-5.85 -1.77,-8.89 1.26,-3.04 4.24,-5.04 7.54,-5.04zM249.06,368.01c1.25,0 2.5,0.29 3.65,0.86l16.32,8.16c4.03,2.02 5.66,6.92 3.65,10.95 -1.43,2.85 -4.32,4.51 -7.3,4.51 -1.23,0 -2.47,-0.27 -3.65,-0.86l-12.67,-6.34 -12.67,6.34c-4.05,2.02 -8.93,0.37 -10.95,-3.65 -2.01,-4.03 -0.38,-8.93 3.65,-10.95l16.32,-8.16c1.15,-0.57 2.4,-0.86 3.65,-0.86zM191.94,392.49c1.25,0 2.5,0.29 3.65,0.86l16.32,8.16c4.03,2.02 5.66,6.92 3.65,10.95 -1.43,2.85 -4.32,4.51 -7.3,4.51 -1.23,0 -2.47,-0.27 -3.65,-0.86l-12.67,-6.34 -12.67,6.34c-4.05,2.02 -8.93,0.37 -10.95,-3.65 -2.01,-4.03 -0.38,-8.93 3.65,-10.95l16.32,-8.16c1.15,-0.57 2.4,-0.86 3.65,-0.86zM306.19,392.49c1.25,0 2.5,0.29 3.65,0.86l16.32,8.16c4.03,2.02 5.66,6.92 3.65,10.95 -1.43,2.85 -4.32,4.51 -7.3,4.51 -1.23,0 -2.47,-0.27 -3.65,-0.86l-12.67,-6.34 -12.67,6.34c-4.03,2.02 -8.93,0.37 -10.95,-3.65 -2.01,-4.03 -0.38,-8.93 3.65,-10.95l16.32,-8.16c1.15,-0.57 2.4,-0.86 3.65,-0.86z"
|
||||||
|
android:strokeWidth="0.119304"
|
||||||
|
android:fillColor="#666666"
|
||||||
|
android:strokeColor="#00000000"/>
|
||||||
|
</group>
|
||||||
|
</vector>
|
||||||
6
app/src/nightly/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/launcher_background"/>
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||||
|
<monochrome android:drawable="@drawable/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/ic_launcher_background"/>
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
||||||
BIN
app/src/nightly/res/mipmap-hdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 816 B |
BIN
app/src/nightly/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/nightly/res/mipmap-mdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 614 B |
BIN
app/src/nightly/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/nightly/res/mipmap-xhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/nightly/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/nightly/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/nightly/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
app/src/nightly/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/nightly/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
7
app/src/nightly/res/values/constants.xml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="account_type_sync" translatable="false">org.kotatsu.nightly.sync</string>
|
||||||
|
<string name="sync_authority_history" translatable="false">org.koitharu.kotatsu.nightly.history</string>
|
||||||
|
<string name="sync_authority_favourites" translatable="false">org.koitharu.kotatsu.nightly.favourites</string>
|
||||||
|
<string name="github_updates_repo" translatable="false">dragonx943/KotatsuDev</string>
|
||||||
|
</resources>
|
||||||
3
app/src/nightly/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name" translatable="false">Kotatsu Nightly</string>
|
||||||
|
</resources>
|
||||||