1
0
mirror of https://github.com/tateisu/SubwayTooter synced 2025-02-01 11:26:48 +01:00

update dependencies, change IDE version to Android Studio Ladybug 2024.2.1.

This commit is contained in:
tateisu 2024-10-20 16:56:39 +09:00
parent 6871d134e1
commit dc740a5909
35 changed files with 517 additions and 403 deletions

1
.gitignore vendored
View File

@ -25,6 +25,7 @@
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
.idea/**/deploymentTargetSelector.xml
# Gradle
.idea/**/gradle.xml

14
.idea/compiler.xml generated
View File

@ -3,10 +3,18 @@
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="19">
<module name="apng" target="1.7" />
<module name="SubwayTooter.buildSrc" target="20" />
<module name="SubwayTooter.buildSrc.main" target="20" />
<module name="SubwayTooter.buildSrc.test" target="20" />
<module name="SubwayTooter.anko" target="21" />
<module name="SubwayTooter.apng_android" target="21" />
<module name="SubwayTooter.app" target="21" />
<module name="SubwayTooter.base" target="21" />
<module name="SubwayTooter.buildSrc" target="21" />
<module name="SubwayTooter.buildSrc.main" target="21" />
<module name="SubwayTooter.buildSrc.test" target="21" />
<module name="SubwayTooter.colorpicker" target="21" />
<module name="SubwayTooter.emoji" target="21" />
<module name="SubwayTooter.icon_material_symbols" target="21" />
<module name="SubwayTooter.main" target="17" />
<module name="SubwayTooter.sample_apng" target="21" />
<module name="SubwayTooter.test" target="17" />
</bytecodeTargetLevel>
</component>

3
.idea/gradle.xml generated
View File

@ -15,8 +15,9 @@
</builds>
</compositeBuild>
</compositeConfiguration>
<option name="testRunner" value="CHOOSE_PER_TEST" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#JAVA_HOME" />
<option name="gradleJvm" value="jbr-21" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />

2
.idea/kotlinc.xml generated
View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.9.22" />
<option name="version" value="2.0.21" />
</component>
</project>

View File

@ -1,8 +1,6 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
}
android {
@ -37,22 +35,17 @@ android {
kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
}
}
}
dependencies {
implementation("androidx.appcompat:appcompat:${Vers.androidxAppcompat}")
implementation("androidx.core:core-ktx:${Vers.androidxCore}")
implementation("androidx.preference:preference-ktx:${Vers.androidxPreferenceKtx}")
implementation("com.google.android.material:material:${Vers.googleMaterial}")
implementation(libs.androidx.appcompat)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.preference.ktx)
implementation(libs.google.material)
testImplementation(kotlin("test"))
testImplementation(libs.kotlin.test)
androidTestRuntimeOnly("androidx.test:runner:1.5.2")
androidTestImplementation("androidx.test:core:${Vers.androidxTestCore}")
androidTestImplementation("androidx.test.ext:junit:${Vers.androidxTestExtJunit}")
androidTestRuntimeOnly(libs.androidx.test.runner)
androidTestImplementation(libs.androidx.test.core)
androidTestImplementation(libs.androidx.test.ext.junit)
}

View File

@ -260,7 +260,7 @@ inline fun doIfSdk(version: Int, f: () -> Unit) {
* @property value the return value if code execution was finished without an exception, null otherwise.
* @property error a caught [Throwable] or null if nothing was caught.
*/
data class AttemptResult<out T> @PublishedApi internal constructor(
data class AttemptResult<out T>(
val value: T?,
val error: Throwable?,
) {

View File

@ -1,7 +1,8 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
plugins {
id("org.jetbrains.kotlin.jvm") version Vers.kotlinVersion
alias(libs.plugins.kotlin.jvm)
`java-library`
}
@ -10,23 +11,16 @@ java {
targetCompatibility = Vers.javaTargetCompatibility
}
val compileKotlin: KotlinCompile by tasks
val compileTestKotlin: KotlinCompile by tasks
compileKotlin.kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
freeCompilerArgs = listOf(
"-opt-in=kotlin.ExperimentalStdlibApi",
)
}
compileTestKotlin.kotlinOptions{
jvmTarget = Vers.kotlinJvmTarget
freeCompilerArgs = listOf(
"-opt-in=kotlin.ExperimentalStdlibApi",
)
tasks.withType<KotlinJvmCompile>().configureEach {
compilerOptions {
jvmTarget.set(JvmTarget.fromTarget(Vers.kotlinJvmTarget))
freeCompilerArgs = listOf(
"-opt-in=kotlin.ExperimentalStdlibApi",
)
}
}
dependencies {
// implementation(fileTree(mapOf("dir" to "libs", "include" to arrayOf("*.jar"))))
testImplementation(kotlin("test"))
testImplementation(libs.kotlin.test)
}

View File

@ -1,8 +1,6 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
}
android {
@ -50,25 +48,16 @@ android {
kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
}
}
}
repositories {
mavenCentral()
}
dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:${Vers.desugarLibVersion}")
coreLibraryDesugaring(libs.desugar.jdk)
api(project(":apng"))
implementation(project(":base"))
implementation("com.github.bumptech.glide:glide:${Vers.glideVersion}")
implementation("com.github.zjupure:webpdecoder:${Vers.webpDecoderVersion}")
implementation(libs.glide)
implementation(libs.webpDecoder)
// テストコードはない…
}

View File

@ -1,14 +1,17 @@
import io.gitlab.arturbosch.detekt.Detekt
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.io.FileInputStream
import java.util.Properties
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
kotlin("plugin.serialization")
id("com.google.devtools.ksp")
id("io.gitlab.arturbosch.detekt")
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.ksp)
// 以下は試験用、保守用
alias(libs.plugins.detekt)
alias(libs.plugins.gradleVersionsPlugin)
}
val keystorePropertiesFile: File = rootProject.file("keystore.properties")
@ -47,14 +50,15 @@ android {
targetCompatibility = Vers.javaTargetCompatibility
isCoreLibraryDesugaringEnabled = true
}
kotlin {
jvmToolchain(Vers.kotlinJvmToolchain)
}
kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
freeCompilerArgs = listOf(
"-opt-in=kotlin.ExperimentalStdlibApi",
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi",
"-opt-in=androidx.media3.common.util.UnstableApi",
// "-Xopt-in=androidx.compose.foundation.ExperimentalFoundationApi",
// "-Xopt-in=androidx.compose.animation.ExperimentalAnimationApi",
)
@ -141,22 +145,11 @@ android {
disable += "MissingTranslation"
}
kotlin {
jvmToolchain(Vers.kotlinJvmToolchain)
}
kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
}
}
}
dependencies {
// desugar_jdk_libs 2.0.0 は AGP 7.4.0-alpha10 以降を要求する
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:${Vers.desugarLibVersion}")
coreLibraryDesugaring(libs.desugar.jdk)
implementation(project(":base"))
implementation(project(":colorpicker"))
@ -164,73 +157,81 @@ dependencies {
implementation(project(":apng_android"))
implementation(project(":anko"))
implementation("androidx.activity:activity-compose:${Vers.androidxActivity}")
implementation("androidx.activity:activity-ktx:${Vers.androidxActivity}")
implementation("androidx.appcompat:appcompat:${Vers.androidxAppcompat}")
implementation("androidx.browser:browser:1.8.0")
implementation("androidx.compose.material3:material3:1.2.1")
implementation("androidx.compose.material:material-icons-extended-android:${Vers.androidxComposeMaterialIcons}")
implementation("androidx.compose.runtime:runtime-livedata:${Vers.androidxComposeRuntime}")
implementation("androidx.compose.ui:ui-tooling-preview:${Vers.androidxComposeUi}")
implementation("androidx.compose.ui:ui:${Vers.androidxComposeUi}")
implementation("androidx.core:core-splashscreen:1.0.1")
implementation("androidx.drawerlayout:drawerlayout:1.2.0")
implementation("androidx.emoji2:emoji2-bundled:${Vers.androidxEmoji2}")
implementation("androidx.emoji2:emoji2-views-helper:${Vers.androidxEmoji2}")
implementation("androidx.emoji2:emoji2-views:${Vers.androidxEmoji2}")
implementation("androidx.emoji2:emoji2:${Vers.androidxEmoji2}")
implementation("androidx.lifecycle:lifecycle-runtime-compose:${Vers.androidxLifecycle}")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:${Vers.androidxLifecycle}")
implementation("androidx.media3:media3-common:${Vers.androidxMedia3}")
implementation("androidx.media3:media3-datasource:${Vers.androidxMedia3}")
implementation("androidx.media3:media3-exoplayer:${Vers.androidxMedia3}")
implementation("androidx.media3:media3-session:${Vers.androidxMedia3}")
implementation("androidx.media3:media3-ui:${Vers.androidxMedia3}")
implementation("androidx.recyclerview:recyclerview:${Vers.androidxRecyclerView}")
implementation("androidx.work:work-runtime-ktx:${Vers.androidxWork}")
implementation("androidx.work:work-runtime:${Vers.androidxWork}")
implementation("com.caverock:androidsvg-aar:1.4")
implementation("com.github.UnifiedPush:android-connector:2.1.1")
implementation("com.github.alexzhirkevich:custom-qr-generator:1.6.2")
implementation("com.github.bumptech.glide:glide:${Vers.glideVersion}")
// 各種ライブラリのBoM
implementation(platform(libs.koin.bom))
implementation(platform(libs.androidx.compose.bom))
testImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(platform(libs.androidx.compose.bom))
implementation(libs.androidsvg.aar)
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.activity.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.browser)
implementation(libs.androidx.compose.material.icons.extended)
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.compose.ui)
implementation(libs.androidx.compose.ui.tooling.preview)
implementation(libs.androidx.core.splashscreen)
implementation(libs.androidx.drawerlayout)
implementation(libs.androidx.emoji2)
implementation(libs.androidx.emoji2.bundled)
implementation(libs.androidx.emoji2.views)
implementation(libs.androidx.emoji2.views.helper)
implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.androidx.lifecycle.viewmodel.compose)
implementation(libs.androidx.media3.common)
implementation(libs.androidx.media3.datasource)
implementation(libs.androidx.media3.exoplayer)
implementation(libs.androidx.media3.session)
implementation(libs.androidx.media3.ui)
implementation(libs.androidx.recyclerview)
implementation(libs.androidx.runtime.livedata)
implementation(libs.androidx.work.runtime)
implementation(libs.androidx.work.runtime.ktx)
implementation(libs.apng4Android)
implementation(libs.conscrypt.android)
implementation(libs.custom.qr.generator)
implementation(libs.draglistview)
implementation(libs.glide)
implementation(libs.google.flexbox)
implementation(libs.google.material)
implementation(libs.koin.android)
implementation(libs.koin.android.compat)
implementation(libs.koin.androidx.workmanager)
implementation(libs.kotlin.coroutines.okhttp)
implementation(libs.kotlinx.serialization.json)
implementation(libs.okhttp)
implementation(libs.okhttp.urlconnection)
implementation(libs.unifiedpush.android.connector)
implementation(libs.webpDecoder)
// AAR指定はバージョンカタログにはない…
//noinspection UseTomlInstead
implementation("com.github.omadahealth:swipy:1.2.3@aar")
implementation("com.github.penfeizhou.android.animation:apng:${Vers.apng4AndroidVersion}")
implementation("com.github.woxthebox:draglistview:1.7.3")
implementation("com.github.zjupure:webpdecoder:${Vers.webpDecoderVersion}")
implementation("com.google.android.flexbox:flexbox:${Vers.googleFlexbox}")
implementation("com.google.android.material:material:${Vers.googleMaterial}")
implementation("com.squareup.okhttp3:okhttp-urlconnection:${Vers.okhttpVersion}")
implementation("com.squareup.okhttp3:okhttp:${Vers.okhttpVersion}")
implementation("com.squareup.okhttp3:okhttp:${Vers.okhttpVersion}")
implementation("io.insert-koin:koin-android-compat:${Vers.koinVersion}")
implementation("io.insert-koin:koin-android:${Vers.koinVersion}")
implementation("io.insert-koin:koin-androidx-workmanager:${Vers.koinVersion}")
implementation("org.conscrypt:conscrypt-android:${Vers.conscryptVersion}")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:${Vers.kotlinxSerializationLibVersion}")
implementation("ru.gildor.coroutines:kotlin-coroutines-okhttp:${Vers.gildorkotlinCoroutinesOkhttp}")
////////////
implementation("com.github.bumptech.glide:okhttp3-integration:${Vers.glideVersion}") {
val glideVersion = libs.versions.glide.get()
implementation("com.github.bumptech.glide:okhttp3-integration:$glideVersion") {
exclude("com.squareup.okhttp3", "okhttp")
}
"fcmImplementation"("com.google.firebase:firebase-messaging:23.4.1")
"fcmImplementation"("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:${Vers.kotlinxCoroutinesVersion}")
"fcmImplementation"(libs.firebase.messaging)
"fcmImplementation"(libs.kotlinx.coroutines.play.services)
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:${Vers.detektVersion}")
detektPlugins(libs.detekt.formatting)
ksp("com.github.bumptech.glide:ksp:${Vers.glideVersion}")
ksp(libs.glide.ksp)
debugImplementation("androidx.compose.ui:ui-test-manifest:1.6.3")
debugImplementation("androidx.compose.ui:ui-tooling:1.6.3")
debugImplementation(libs.androidx.compose.ui.test.manifest)
debugImplementation(libs.androidx.compose.ui.tooling)
// =================================================
// UnitTest
testImplementation(kotlin("test"))
testImplementation("androidx.arch.core:core-testing:${Vers.androidxArchCoreTesting}")
testImplementation("junit:junit:${Vers.junitVersion}")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:${Vers.kotlinxCoroutinesVersion}")
// https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-test
testImplementation(libs.kotlin.test)
testImplementation(libs.androidx.arch.core.testing)
testImplementation(libs.junit)
testImplementation(libs.kotlinx.coroutines.test)
// testImplementation("com.squareup.okhttp3:mockwebserver:${Vers.okhttpVersion}") {
// exclude("com.squareup.okio", "okio")
@ -242,18 +243,19 @@ dependencies {
// ==============================================
// androidTest
androidTestRuntimeOnly("androidx.test:runner:1.5.2")
androidTestUtil("androidx.test:orchestrator:1.4.2")
androidTestRuntimeOnly(libs.androidx.test.runner)
androidTestUtil(libs.androidx.test.orchestrator)
androidTestImplementation("androidx.test.espresso:espresso-core:${Vers.androidxTestEspressoCore}")
androidTestImplementation("androidx.test.ext:junit-ktx:1.1.5")
androidTestImplementation("androidx.test.ext:junit:${Vers.androidxTestExtJunit}")
androidTestImplementation("androidx.test.ext:truth:1.5.0")
androidTestImplementation("androidx.test:core-ktx:${Vers.androidxTestCoreKtx}")
androidTestImplementation("androidx.test:core:${Vers.androidxTestCore}")
androidTestImplementation("androidx.compose.ui:ui-test-junit4:1.6.3")
androidTestImplementation(libs.androidx.test.espresso.core)
androidTestImplementation(libs.androidx.test.ext.junit.ktx)
androidTestImplementation(libs.androidx.test.ext.junit)
androidTestImplementation(libs.androidx.test.ext.truth)
androidTestImplementation(libs.androidx.test.core.ktx)
androidTestImplementation(libs.androidx.test.core)
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
androidTestImplementation("com.squareup.okhttp3:mockwebserver:${Vers.okhttpVersion}") {
val okHttpVersion = libs.versions.okhttp.get()
androidTestImplementation("com.squareup.okhttp3:mockwebserver:$okHttpVersion") {
exclude("com.squareup.okio", "okio")
exclude("com.squareup.okhttp3", "okhttp")
exclude("org.jetbrains.kotlin", "kotlin-stdlib-common")
@ -262,10 +264,6 @@ dependencies {
}
}
repositories {
mavenCentral()
}
fun willApplyGoogleService(): Boolean {
val taskRequestsString = gradle.startParameter.taskRequests.toString()
@ -340,3 +338,8 @@ tasks.register<Detekt>("detektAll") {
sarif.outputLocation.set(reportLocationByExt("sarif"))
}
}
composeCompiler {
// reportsDestination = layout.buildDirectory.dir("compose_compiler")
// stabilityConfigurationFile = rootProject.layout.projectDirectory.file("stability_config.conf")
}

View File

@ -2,7 +2,7 @@ package jp.juggler.subwaytooter.push
import android.content.Context
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
import com.google.android.gms.common.GoogleApiAvailabilityLight
import com.google.firebase.messaging.FirebaseMessaging
import jp.juggler.util.log.LogCategory
import kotlinx.coroutines.tasks.await
@ -57,9 +57,9 @@ object FcmTokenLoader {
}
fun isPlayServiceAvailavle(context: Context): Boolean {
val errorCode = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context)
if (errorCode == ConnectionResult.SUCCESS) return true
log.w("isPlayServiceAvailavle=${connectionResultString(errorCode)}")
val code = GoogleApiAvailabilityLight.getInstance().isGooglePlayServicesAvailable(context)
if (code == ConnectionResult.SUCCESS) return true
log.w("isPlayServiceAvailavle=${connectionResultString(code)}")
return false
}

View File

@ -13,7 +13,6 @@ import android.view.inputmethod.EditorInfo
import android.widget.ImageView
import android.widget.SeekBar
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import com.jrummyapps.android.colorpicker.dialogColorPicker
import jp.juggler.subwaytooter.api.TootApiResult
import jp.juggler.subwaytooter.api.runApiTask
@ -340,10 +339,9 @@ class ActColumnCustomize : AppCompatActivity(), View.OnClickListener {
views.tvColumnName.text = column.getColumnName(false)
if (column.columnBgColor != 0) {
views.flColumnBackground.setBackgroundColor(column.columnBgColor)
} else {
ViewCompat.setBackground(views.flColumnBackground, null)
when (column.columnBgColor) {
0 -> views.flColumnBackground.background = null
else -> views.flColumnBackground.setBackgroundColor(column.columnBgColor)
}
showAlpha(updateText = true, updateSeek = true)

View File

@ -465,7 +465,7 @@ class ActMain : AppCompatActivity(),
}
}
override fun onNewIntent(intent: Intent?) {
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
log.w("onNewIntent: isResumed=$isResumed")
}

View File

@ -28,12 +28,15 @@ import jp.juggler.subwaytooter.util.CustomEmojiCache
import jp.juggler.subwaytooter.util.CustomEmojiLister
import jp.juggler.subwaytooter.util.ProgressResponseBody
import jp.juggler.subwaytooter.util.getUserAgent
import jp.juggler.util.coroutine.AppDispatchers
import jp.juggler.util.coroutine.EmptyScope
import jp.juggler.util.data.notEmpty
import jp.juggler.util.log.LogCategory
import jp.juggler.util.log.initializeToastUtils
import jp.juggler.util.network.MySslSocketFactory
import jp.juggler.util.network.toPostRequestBuilder
import jp.juggler.util.os.applicationContextSafe
import kotlinx.coroutines.launch
import okhttp3.Cache
import okhttp3.CacheControl
import okhttp3.ConnectionSpec
@ -215,7 +218,23 @@ class App1 : Application() {
// Playサービスが古い端末ではEmojiCompatの初期化がまだ行われていない状態になる
// ワークアラウンドとして、アプリ内にバンドルしたデータを使うBundledEmojiCompatConfigで初期化する
// (初期化が既に行われている場合は無害である)
EmojiCompat.init(BundledEmojiCompatConfig(appContext))
EmojiCompat.init(
BundledEmojiCompatConfig(
appContext,
object : java.util.concurrent.Executor {
override fun execute(command: Runnable?) {
command ?: throw NullPointerException()
EmptyScope.launch(AppDispatchers.IO) {
try {
command.run()
} catch (ex: Throwable) {
log.w(ex, "BundledEmojiCompatConfig fontLoadExecutor failed.")
}
}
}
}
)
)
// initialize Conscrypt
Security.insertProviderAt(

View File

@ -24,9 +24,9 @@ fun Column.removeColumnViewHolderByActivity(activity: ActMain) {
// 複数のリスナがある場合、最も新しいものを返す
val Column.viewHolder: ColumnViewHolder?
get() {
if (isDispose.get()) return null
return if (listViewHolder.isEmpty()) null else listViewHolder.first
get() = when {
isDispose.get() -> null
else -> listViewHolder.firstOrNull()
}
fun Column.fireShowContent(

View File

@ -54,24 +54,22 @@ class PushMisskey(
var hasEmptySubscription = false
if (!lastEndpointUrl.isNullOrEmpty()) {
val lastSubscription = when (lastEndpointUrl) {
null, "" -> null
else -> try {
subLog.i("check current subscription…")
// Misskeyは2022/12/18に現在の購読を確認するAPIができた
api.getPushSubscription(account, lastEndpointUrl)
// 購読がない => 空オブジェクト (v13 drdr.club でそんな感じ)
} catch (ex: Throwable) {
// APIがない => 404 (v10 めいすきーのソースと動作で確認)
when ((ex as? ApiError)?.response?.code) {
in 400 until 500 -> null
else -> throw ex
}
val lastSubscription = try {
subLog.i("check current subscription…")
// Misskeyは2022/12/18に現在の購読を確認するAPIができた
api.getPushSubscription(account, lastEndpointUrl)
// 購読がない => 空オブジェクト (v13 drdr.club でそんな感じ)
} catch (ex: Throwable) {
// APIがない => 404 (v10 めいすきーのソースと動作で確認)
when ((ex as? ApiError)?.response?.code) {
in 400 until 500 -> null
else -> throw ex
}
}
if (lastSubscription != null) {
if (lastSubscription.size == 0) {
@Suppress("UsePropertyAccessSyntax")
if (lastSubscription.isEmpty()) {
// 購読がないと空レスポンスになり、アプリ側で空オブジェクトに変換される
@Suppress("UNUSED_VALUE")
hasEmptySubscription = true
@ -102,6 +100,7 @@ class PushMisskey(
subLog.i(R.string.push_subscription_app_server_hash_missing_but_ok)
null
}
else -> context.getString(
R.string.push_subscription_app_server_hash_missing_error
)
@ -231,7 +230,7 @@ class PushMisskey(
TootNotification.TYPE_FOLLOW,
TootNotification.TYPE_FOLLOW_REQUEST,
TootNotification.TYPE_FOLLOW_REQUEST_MISSKEY,
-> {
-> {
val whoAcct = a.getFullAcct(who)
if (TootStatus.favMuteSet?.contains(whoAcct) == true) {
error("muted by favMuteSet ${whoAcct.pretty}")

View File

@ -16,7 +16,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material3.CircularProgressIndicator
@ -40,12 +39,12 @@ import jp.juggler.subwaytooter.App1
import jp.juggler.subwaytooter.R
import jp.juggler.subwaytooter.databinding.ActOssLicenseBinding
import jp.juggler.subwaytooter.util.StColorScheme
import jp.juggler.subwaytooter.util.collectOnLifeCycle
import jp.juggler.subwaytooter.util.dummyStColorTheme
import jp.juggler.subwaytooter.util.getStColorTheme
import jp.juggler.subwaytooter.util.openBrowser
import jp.juggler.subwaytooter.util.provideViewModel
import jp.juggler.subwaytooter.util.toAnnotatedString
import jp.juggler.util.data.mayUri
import jp.juggler.util.data.notEmpty
import jp.juggler.util.log.LogCategory
import kotlinx.coroutines.flow.Flow
@ -80,6 +79,10 @@ class ActOSSLicense : ComponentActivity() {
)
}
collectOnLifeCycle(viewModel.linkEvent) {
openBrowser(it?.get())
}
try {
viewModel.load(stColorScheme = stColorScheme)
} catch (ex: Throwable) {
@ -189,53 +192,29 @@ class ActOSSLicense : ComponentActivity() {
.padding(vertical = 6.dp, horizontal = 12.dp)
) {
src.nameBig.notEmpty()?.let {
ClickableText(
Text(
text = it,
style = MaterialTheme.typography.headlineSmall.copy(
color = MaterialTheme.colorScheme.onBackground,
),
) { offset ->
it.getStringAnnotations(
tag = "URL",
start = offset,
end = offset,
).firstOrNull()?.let { a ->
openBrowser(a.item.mayUri())
}
}
)
}
src.nameSmall.notEmpty()?.let {
ClickableText(
Text(
text = it,
style = MaterialTheme.typography.bodySmall.copy(
color = MaterialTheme.colorScheme.onBackground,
),
) { offset ->
it.getStringAnnotations(
tag = "URL",
start = offset,
end = offset,
).firstOrNull()?.let { a ->
openBrowser(a.item.mayUri())
}
}
)
}
Spacer(modifier = Modifier.height(8.dp))
src.desc.notEmpty()?.let {
ClickableText(
Spacer(modifier = Modifier.height(8.dp))
Text(
text = it,
style = MaterialTheme.typography.bodyMedium.copy(
color = MaterialTheme.colorScheme.onBackground,
),
) { offset ->
it.getStringAnnotations(
tag = "URL",
start = offset,
end = offset,
).firstOrNull()?.let { a ->
openBrowser(a.item.mayUri())
}
}
)
)
}
}
}

View File

@ -2,12 +2,15 @@ package jp.juggler.subwaytooter.ui.ossLicense
import android.app.Application
import android.content.Context
import android.net.Uri
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import jp.juggler.subwaytooter.R
import jp.juggler.subwaytooter.util.StColorScheme
import jp.juggler.util.coroutine.AppDispatchers
import jp.juggler.util.data.decodeJsonObject
import jp.juggler.util.data.eventFlow
import jp.juggler.util.data.setEvent
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
@ -29,6 +32,11 @@ class ActOSSLicenseViewModel(
private val _isProgressShown = MutableStateFlow(false)
val isProgressShown = _isProgressShown.asStateFlow()
private val _linkEvent = eventFlow<Uri>()
val linkEvent = _linkEvent.asStateFlow()
private fun fireUriEvent(uri:Uri) = _linkEvent.setEvent(uri)
fun load(stColorScheme: StColorScheme) = viewModelScope.launch {
try {
_isProgressShown.value = true
@ -48,6 +56,7 @@ class ActOSSLicenseViewModel(
it,
licenses,
stColorScheme = stColorScheme,
linkOpener = ::fireUriEvent,
)
}
?.sortedBy { it.nameSort }

View File

@ -1,5 +1,6 @@
package jp.juggler.subwaytooter.ui.ossLicense
import android.net.Uri
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.buildAnnotatedString
import jp.juggler.subwaytooter.util.StColorScheme
@ -45,6 +46,7 @@ fun parseLibText(
lib: JsonObject,
licenses: Map<String?, JsonObject>,
stColorScheme: StColorScheme,
linkOpener: (Uri) -> Unit,
): LibText {
val colorLink = stColorScheme.colorTextLink
@ -56,10 +58,10 @@ fun parseLibText(
val nameSmall: CharSequence?
if (name.isNullOrBlank()) {
// nameがない場合はnameBigはidを大きく表示する
nameBig = (id ?: "(no name, no id)").annotateUrl(webSite, colorLink)
nameBig = (id ?: "(no name, no id)").annotateUrl(webSite, colorLink, opener = linkOpener)
nameSmall = null
} else {
nameBig = name.annotateUrl(webSite, colorLink)
nameBig = name.annotateUrl(webSite, colorLink, opener = linkOpener)
nameSmall = id
// idがない場合はnameSmallはnullとなる
}
@ -70,7 +72,7 @@ fun parseLibText(
?.map {
val uri =
it.jsonArray("urls")?.stringList()?.firstOrNull()?.toHttpUrlOrNull()?.toString()
it.string("name")!!.annotateUrl(uri, colorLink)
it.string("name")!!.annotateUrl(uri, colorLink, opener = linkOpener)
}
?.toList()?.joinAnnotatedString(AnnotatedString(", "))

View File

@ -1,10 +1,16 @@
package jp.juggler.subwaytooter.util
import android.net.Uri
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.LinkAnnotation
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextLinkStyles
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withLink
import androidx.compose.ui.unit.TextUnit
import jp.juggler.util.data.mayUri
fun CharSequence.toAnnotatedString() = when (this) {
is AnnotatedString -> this
@ -35,25 +41,26 @@ fun List<CharSequence>.joinAnnotatedString(
* @return CharSequence, 実際には Stringまたは AnnotatedString
*/
fun String.annotateUrl(
uri: String?,
url: String?,
colorLink: Color,
fontSize: TextUnit = TextUnit.Unspecified,
): CharSequence = when (uri) {
opener: (Uri) -> Unit,
): CharSequence = when (val uri = url?.mayUri()) {
null -> this
else -> AnnotatedString.Builder().apply {
append(this@annotateUrl)
addStyle(
style = SpanStyle(
color = colorLink,
fontSize = fontSize,
textDecoration = TextDecoration.Underline
), start = 0, end = length
)
addStringAnnotation(
tag = "URL",
annotation = uri.toString(),
start = 0,
end = length,
)
}.toAnnotatedString()
else -> buildAnnotatedString {
withLink(
LinkAnnotation.Clickable(
tag = "uri",
styles = TextLinkStyles(
style = SpanStyle(
color = colorLink,
textDecoration = TextDecoration.Underline,
fontSize = fontSize,
)
),
) { opener(uri) }
) {
append(this@annotateUrl)
}
}
}

View File

@ -42,10 +42,7 @@ fun <T : Any?> AppCompatActivity.collectOnLifeCycle(
block: suspend (T) -> Unit,
) = lifecycleScope.launch {
lifecycle.repeatOnLifecycle(state = state) {
flow.collect {
block(it)
// Viewの更新
}
flow.collect { block(it) }
}
}
@ -55,9 +52,6 @@ fun <T : Any?> ComponentActivity.collectOnLifeCycle(
block: suspend (T) -> Unit,
) = lifecycleScope.launch {
lifecycle.repeatOnLifecycle(state = state) {
flow.collect {
block(it)
// Viewの更新
}
flow.collect { block(it) }
}
}

View File

@ -5,7 +5,6 @@ import android.view.Gravity
import android.view.View
import android.view.animation.DecelerateInterpolator
import android.widget.Scroller
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.OrientationHelper
import androidx.recyclerview.widget.RecyclerView
@ -40,7 +39,7 @@ constructor(gravity: Int) : androidx.recyclerview.widget.LinearSnapHelper() {
override fun attachToRecyclerView(recyclerView: RecyclerView?) {
mRecyclerView = recyclerView
if (recyclerView != null) {
isRTL = ViewCompat.getLayoutDirection(recyclerView) == ViewCompat.LAYOUT_DIRECTION_RTL
isRTL = recyclerView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL
mGravityScroller = Scroller(recyclerView.context, DecelerateInterpolator())
}

View File

@ -1,8 +1,6 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
}
android {
namespace = "jp.juggler.base"
@ -39,11 +37,6 @@ android {
kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
}
}
packaging {
jniLibs {
excludes.addAll(listOf("META-INF/LICENSE*"))
@ -58,56 +51,49 @@ kotlin {
jvmToolchain(Vers.kotlinJvmToolchain)
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
}
}
dependencies {
// desugar_jdk_libs 2.0.0 は AGP 7.4.0-alpha10 以降を要求する
//noinspection GradleDependency
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:${Vers.desugarLibVersion}")
coreLibraryDesugaring(libs.desugar.jdk)
// JugglerBaseInitializer で使う
implementation("androidx.startup:startup-runtime:${Vers.androidxStartup}")
implementation(libs.androidx.startup.runtime)
// decodeP256dh で使う
implementation("org.bouncycastle:bcprov-jdk15on:1.70")
implementation(libs.bcprov.jdk15on)
// defaultSecurityProvider で使う
implementation("org.conscrypt:conscrypt-android:${Vers.conscryptVersion}")
implementation(libs.conscrypt.android)
// AudioTranscoderで使う
implementation("androidx.media3:media3-common:${Vers.androidxMedia3}")
implementation("androidx.media3:media3-transformer:${Vers.androidxMedia3}")
implementation("androidx.media3:media3-effect:${Vers.androidxMedia3}")
implementation(libs.androidx.media3.common)
implementation(libs.androidx.media3.transformer)
implementation(libs.androidx.media3.effect)
// EmptyScope.kt で使う
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:${Vers.kotlinxCoroutinesVersion}")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:${Vers.androidxLifecycle}")
implementation(libs.kotlinx.coroutines.core)
implementation(libs.androidx.lifecycle.runtime.ktx)
// Compat.kt で使う
implementation("androidx.annotation:annotation:${Vers.androidxAnnotation}")
implementation("androidx.appcompat:appcompat:${Vers.androidxAppcompat}")
implementation(libs.androidx.annotation)
implementation(libs.androidx.appcompat)
// JsonDelegate で使う
implementation(kotlin("reflect"))
// UriSerializer で使う。アカウント設定で状態の保存に kotlinx-serialization-json を使っている
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:${Vers.kotlinxSerializationLibVersion}")
implementation(libs.kotlinx.serialization.json)
// BitmapUtils で使う
implementation("androidx.exifinterface:exifinterface:1.3.7")
implementation(libs.androidx.exifinterface)
// MovieUtils で使う
implementation("com.otaliastudios:transcoder:0.10.5")
implementation(libs.otaliastudios.transcoder)
// HttpUtils で使う
implementation("com.squareup.okhttp3:okhttp:${Vers.okhttpVersion}")
implementation(libs.okhttp)
// ないとなぜかIDE上にエラーが出る
implementation("androidx.activity:activity-ktx:${Vers.androidxActivity}")
implementation(libs.androidx.activity.ktx)
// ==========================================================================
// 単体テスト
@ -116,13 +102,13 @@ dependencies {
// ==========================================================================
// AndroidTest
// 紛らわしいのでAndroidTestではkotlin.testを使わない androidTestImplementation(kotlin("test"))
androidTestRuntimeOnly("androidx.test:runner:1.5.2")
androidTestImplementation("androidx.test:core:${Vers.androidxTestCore}")
androidTestImplementation("androidx.test.ext:junit:${Vers.androidxTestExtJunit}")
androidTestImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:${Vers.kotlinxCoroutinesVersion}")
androidTestRuntimeOnly(libs.androidx.test.runner)
androidTestImplementation(libs.androidx.test.core)
androidTestImplementation(libs.androidx.test.ext.junit)
androidTestImplementation(libs.kotlinx.coroutines.test)
// DispatchersTest で使う
androidTestImplementation("androidx.lifecycle:lifecycle-viewmodel-ktx:${Vers.androidxLifecycle}")
androidTestImplementation(libs.androidx.lifecycle.viewmodel.ktx)
// implementation("androidx.core:core-ktx:${Vers.androidxCoreVersion}")
//
@ -158,7 +144,6 @@ dependencies {
// implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
// implementation("ru.gildor.coroutines:kotlin-coroutines-okhttp:${Vers.gildorkotlinCoroutinesOkhttp}")
// androidTestImplementation("androidx.test.espresso:espresso-core:${Vers.androidxTestEspressoCoreVersion}")
// androidTestImplementation("androidx.test.ext:junit-ktx:1.1.5")
// androidTestImplementation("androidx.test.ext:truth:1.5.0")

View File

@ -0,0 +1,34 @@
package jp.juggler.util.data
import kotlinx.coroutines.flow.MutableStateFlow
import java.util.Objects
/**
* one-time consumed event
*/
class Event<T : Any?>(private val data: T) {
private var isConsumed = false
fun get(): T? = when {
isConsumed -> null
else -> {
isConsumed = true
data
}
}
override fun hashCode() = Objects.hash(isConsumed, data)
override fun equals(other: Any?): Boolean = when {
this === other -> true
other !is Event<*> -> false
else -> isConsumed == other.isConsumed &&
data == other.data
}
}
fun <T : Any?> eventFlow() = MutableStateFlow<Event<T>?>(null)
fun <T : Any?> MutableStateFlow<Event<T>?>.setEvent(newValue: T?) {
value = newValue?.let { Event(it) }
}

View File

@ -242,7 +242,7 @@ fun String.sanitizeBDI(): String {
if (closer != null) {
if (stack == null) stack = LinkedList()
stack.add(closer)
} else if (stack?.isNotEmpty() == true && stack.last == c) {
} else if (stack?.lastOrNull() == c) {
stack.removeLast()
}
}

View File

@ -5,47 +5,34 @@ buildscript {
}
dependencies {
classpath("com.android.tools.build:gradle:${Vers.androidGradlePrugin}")
// room のバージョンの影響で google-services を上げられない場合がある
classpath("com.google.gms:google-services:4.4.1")
//noinspection DifferentKotlinGradleVersion
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Vers.kotlinVersion}")
// Compose Compilerの都合でkotlinを上げられない場合がある
//noinspection GradleDependency
classpath("org.jetbrains.kotlin:kotlin-serialization:${Vers.kotlinVersion}")
classpath("com.github.bjoernq:unmockplugin:0.7.6")
classpath("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:${Vers.detektVersion}")
classpath(libs.google.services)
// classpath(libs.unmockplugin)
}
}
plugins {
kotlin("jvm") version (Vers.kotlinVersion) apply false
kotlin("plugin.serialization") version (Vers.kotlinxSerializationPluginVersion) apply true // !!
id("org.jetbrains.kotlin.android") version (Vers.kotlinVersion) apply false
id("com.google.devtools.ksp") version (Vers.kspVersion) apply false
// id("com.android.library") version "8.3.0" apply false
// alias(libs.plugins.unmock) apply false
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.detekt) apply false
alias(libs.plugins.gradleVersionsPlugin) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.compose) apply false
alias(libs.plugins.kotlin.jvm) apply false
alias(libs.plugins.kotlin.serialization) apply false
alias(libs.plugins.ksp) apply false
}
allprojects {
repositories {
google()
mavenCentral()
// alexzhirkevich/custom-qr-generator
maven(url = "https://jitpack.io")
}
// configurationのリストを標準出力に出す
// usage: ./gradlew -q --no-configuration-cache :app:printConfigurations
tasks.register("printConfigurations") {
doLast {
println("project: ${project.name} configurations:")
for( c in configurations){
for (c in configurations) {
println("configuration: ${c.name}")
}
}

View File

@ -12,55 +12,13 @@ object Vers {
val javaTargetCompatibility = JavaVersion.VERSION_19
// Compose Compiler 1.5.10 は kotlin 1.9.22 を要求する
@Suppress("MemberVisibilityCanBePrivate")
const val kotlinVersion = "1.9.22"
const val kotlinVersion = "2.0.21"
@Suppress("MemberVisibilityCanBePrivate")
const val glideVersion = "4.15.1"
// Compose Compiler 1.5.10 は jvmTarget = "19" を要求する
// しかし Android Studio 自体は17で動いてるので単体テスト時に問題がでる
const val kotlinJvmTarget = "19"
const val kotlinJvmToolchain = 19
const val androidGradlePrugin = "8.3.0"
// const val ankoVersion = "0.10.8"
// const val commonsCodecVersion = "1.16.0"
// const val composeVersion = "1.0.5"
const val androidxActivity = "1.8.2"
const val androidxAnnotation = "1.7.1"
const val androidxAppcompat = "1.6.1"
const val androidxArchCoreTesting = "2.2.0"
const val androidxComposeRuntime = "1.6.3"
const val androidxComposeUi = "1.6.3"
const val androidxComposeMaterialIcons = "1.6.3"
const val androidxCore = "1.12.0"
const val androidxEmoji2 = "1.4.0"
const val androidxLifecycle = "2.7.0"
const val androidxMedia3 = "1.3.0"
const val androidxPreferenceKtx = "1.2.1"
const val androidxRecyclerView = "1.3.2"
const val androidxStartup = "1.1.1"
const val androidxTestCore = "1.5.0"
const val androidxTestCoreKtx = "1.5.0"
const val androidxTestEspressoCore = "3.5.1"
const val androidxTestExtJunit = "1.1.5"
const val androidxWork = "2.9.0"
const val apng4AndroidVersion = "2.25.0"
const val conscryptVersion = "2.5.2"
const val desugarLibVersion = "2.0.4"
const val detektVersion = "1.23.5"
const val gildorkotlinCoroutinesOkhttp = "1.0"
const val googleFlexbox="3.0.0"
const val googleMaterial = "1.11.0"
const val junitVersion = "4.13.2"
const val koinVersion = "3.5.0"
const val kotlinxCoroutinesVersion = "1.8.0"
const val kotlinxSerializationLibVersion = "1.6.3"
const val kotlinxSerializationPluginVersion = kotlinVersion
const val kspVersion = "$kotlinVersion-1.0.17"
const val okhttpVersion = "5.0.0-alpha.12"
const val webpDecoderVersion = "2.6.$glideVersion"
// Android Studio同梱のJavaツールチェインのバージョン
const val kotlinJvmToolchain = 21
}

View File

@ -1,8 +1,6 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
}
android {
@ -46,21 +44,16 @@ android {
//"-opt-in=androidx.compose.animation.ExperimentalAnimationApi",
)
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
}
}
}
dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:${Vers.desugarLibVersion}")
coreLibraryDesugaring(libs.desugar.jdk)
// dismissSafe, systemService, View.gone() など
implementation(project(":base"))
implementation("androidx.core:core-ktx:${Vers.androidxCore}")
implementation("androidx.appcompat:appcompat:${Vers.androidxAppcompat}")
implementation("androidx.annotation:annotation:${Vers.androidxAnnotation}")
implementation("com.google.android.flexbox:flexbox:${Vers.googleFlexbox}")
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.annotation)
implementation(libs.google.flexbox)
}

View File

@ -34,7 +34,6 @@ import android.widget.Toast
import androidx.annotation.ColorInt
import androidx.core.content.ContextCompat
import androidx.core.view.GravityCompat
import androidx.core.view.ViewCompat
enum class ColorShape(val attrEnum: Int) {
Square(0),
@ -268,7 +267,7 @@ class ColorPanelView @JvmOverloads constructor(
val height = height
val midy = screenPos[1] + height / 2
var referenceX = screenPos[0] + width / 2
if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_LTR) {
if (getLayoutDirection() == LAYOUT_DIRECTION_LTR) {
val screenWidth = context.resources.displayMetrics.widthPixels
referenceX = screenWidth - referenceX // mirror
}

View File

@ -1,8 +1,6 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
}
android {
@ -37,9 +35,4 @@ android {
kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
}
}
}

146
gradle/libs.versions.toml Normal file
View File

@ -0,0 +1,146 @@
[versions]
androidGradlePlugin = "8.7.1"
androidsvgAar = "1.4"
androidxActivity = "1.9.3"
androidxAnnotation = "1.9.0"
androidxAppcompat = "1.7.0"
androidxArchCoreTesting = "2.2.0"
androidxBrowser = "1.8.0"
androidxComposeBom = "2024.10.00"
androidxCoreKtx = "1.13.1"
androidxCoreSplashscreen = "1.0.1"
androidxDrawerlayout = "1.2.0"
androidxEmoji2 = "1.5.0"
androidxLifecycle = "2.8.6"
androidxMedia3 = "1.4.1"
androidxMedia3Effect = "1.4.1"
androidxMedia3Transformer = "1.4.1"
androidxPreference = "1.2.1"
androidxRecyclerView = "1.3.2"
androidxStartup = "1.2.0"
androidxTestCore = "1.6.1"
androidxTestEspressoCore = "3.6.1"
androidxTestExtJunit = "1.2.1"
androidxTestExtTruth = "1.6.0"
androidxTestOrchestrator = "1.5.1"
androidxTestRunner = "1.6.2"
androidxWork = "2.9.1"
anroidxExifInterface = "1.3.7"
apng4Android = "2.25.0"
bcprovJdk15on = "1.70"
conscryptAndroid = "2.5.2"
customQrGenerator = "1.6.2"
desugarJdk = "2.1.2"
detekt = "1.23.7"
draglistview = "1.7.3"
firebaseMessaging = "24.0.2"
glide = "4.15.1"
googleFlexbox = "3.0.0"
googleMaterial = "1.12.0"
googleServices = "4.4.2"
gradleVersionsPlugin = "0.51.0"
junit = "4.13.2"
koinBom = "4.0.0"
kotlin = "2.0.21"
kotlinCoroutinesOkhttp = "1.0"
kotlinxCoroutines = "1.8.0"
kotlinxSerialization = "1.6.3"
ksp = "2.0.21-1.0.25" # kotlinバージョンに依存している
okhttp = "5.0.0-alpha.12"
otaliastudiosTranscoder = "0.10.5"
unifiedPushAndroidConnector = "2.1.1"
# unmockPlugin = "0.8.0"
webpDecoder = "2.6.4.15.1" # glideバージョンに依存している
[libraries]
androidsvg-aar = { module = "com.caverock:androidsvg-aar", version.ref = "androidsvgAar" }
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidxActivity" }
androidx-activity-ktx = { module = "androidx.activity:activity-ktx", version.ref = "androidxActivity" }
androidx-annotation = { module = "androidx.annotation:annotation", version.ref = "androidxAnnotation" }
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidxAppcompat" }
androidx-arch-core-testing = { module = "androidx.arch.core:core-testing", version.ref = "androidxArchCoreTesting" }
androidx-browser = { module = "androidx.browser:browser", version.ref = "androidxBrowser" }
androidx-compose-bom = { module = "androidx.compose:compose-bom", version.ref = "androidxComposeBom" }
androidx-compose-material-icons-extended = { module = "androidx.compose.material:material-icons-extended" }
androidx-compose-material3 = { module = "androidx.compose.material3:material3" }
androidx-compose-ui = { module = "androidx.compose.ui:ui" }
androidx-compose-ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4" }
androidx-compose-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest" }
androidx-compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" }
androidx-compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" }
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidxCoreKtx" }
androidx-core-splashscreen = { module = "androidx.core:core-splashscreen", version.ref = "androidxCoreSplashscreen" }
androidx-drawerlayout = { module = "androidx.drawerlayout:drawerlayout", version.ref = "androidxDrawerlayout" }
androidx-emoji2 = { module = "androidx.emoji2:emoji2", version.ref = "androidxEmoji2" }
androidx-emoji2-bundled = { module = "androidx.emoji2:emoji2-bundled", version.ref = "androidxEmoji2" }
androidx-emoji2-views = { module = "androidx.emoji2:emoji2-views", version.ref = "androidxEmoji2" }
androidx-emoji2-views-helper = { module = "androidx.emoji2:emoji2-views-helper", version.ref = "androidxEmoji2" }
androidx-exifinterface = { module = "androidx.exifinterface:exifinterface", version.ref = "anroidxExifInterface" }
androidx-lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidxLifecycle" }
androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "androidxLifecycle" }
androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidxLifecycle" }
androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidxLifecycle" }
androidx-media3-common = { module = "androidx.media3:media3-common", version.ref = "androidxMedia3" }
androidx-media3-datasource = { module = "androidx.media3:media3-datasource", version.ref = "androidxMedia3" }
androidx-media3-effect = { module = "androidx.media3:media3-effect", version.ref = "androidxMedia3Effect" }
androidx-media3-exoplayer = { module = "androidx.media3:media3-exoplayer", version.ref = "androidxMedia3" }
androidx-media3-session = { module = "androidx.media3:media3-session", version.ref = "androidxMedia3" }
androidx-media3-transformer = { module = "androidx.media3:media3-transformer", version.ref = "androidxMedia3Transformer" }
androidx-media3-ui = { module = "androidx.media3:media3-ui", version.ref = "androidxMedia3" }
androidx-preference-ktx = { module = "androidx.preference:preference-ktx", version.ref = "androidxPreference" }
androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "androidxRecyclerView" }
androidx-runtime-livedata = { module = "androidx.compose.runtime:runtime-livedata" }
androidx-startup-runtime = { module = "androidx.startup:startup-runtime", version.ref = "androidxStartup" }
androidx-test-core = { module = "androidx.test:core", version.ref = "androidxTestCore" }
androidx-test-core-ktx = { module = "androidx.test:core-ktx", version.ref = "androidxTestCore" }
androidx-test-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidxTestEspressoCore" }
androidx-test-ext-junit = { module = "androidx.test.ext:junit", version.ref = "androidxTestExtJunit" }
androidx-test-ext-junit-ktx = { module = "androidx.test.ext:junit-ktx", version.ref = "androidxTestExtJunit" }
androidx-test-ext-truth = { module = "androidx.test.ext:truth", version.ref = "androidxTestExtTruth" }
androidx-test-orchestrator = { module = "androidx.test:orchestrator", version.ref = "androidxTestOrchestrator" }
androidx-test-runner = { module = "androidx.test:runner", version.ref = "androidxTestRunner" }
androidx-work-runtime = { module = "androidx.work:work-runtime", version.ref = "androidxWork" }
androidx-work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "androidxWork" }
apng4Android = { module = "com.github.penfeizhou.android.animation:apng", version.ref = "apng4Android" }
bcprov-jdk15on = { module = "org.bouncycastle:bcprov-jdk15on", version.ref = "bcprovJdk15on" }
conscrypt-android = { module = "org.conscrypt:conscrypt-android", version.ref = "conscryptAndroid" }
custom-qr-generator = { module = "com.github.alexzhirkevich:custom-qr-generator", version.ref = "customQrGenerator" }
desugar-jdk = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugarJdk" }
detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" }
draglistview = { module = "com.github.woxthebox:draglistview", version.ref = "draglistview" }
firebase-messaging = { module = "com.google.firebase:firebase-messaging", version.ref = "firebaseMessaging" }
glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
glide-ksp = { module = "com.github.bumptech.glide:ksp", version.ref = "glide" }
google-flexbox = { module = "com.google.android.flexbox:flexbox", version.ref = "googleFlexbox" }
google-material = { module = "com.google.android.material:material", version.ref = "googleMaterial" }
google-services = { module = "com.google.gms:google-services", version.ref = "googleServices" }
junit = { module = "junit:junit", version.ref = "junit" }
koin-android = { module = "io.insert-koin:koin-android" }
koin-android-compat = { module = "io.insert-koin:koin-android-compat" }
koin-androidx-workmanager = { module = "io.insert-koin:koin-androidx-workmanager" }
koin-bom = { module = "io.insert-koin:koin-bom", version.ref = "koinBom" }
kotlin-coroutines-okhttp = { module = "ru.gildor.coroutines:kotlin-coroutines-okhttp", version.ref = "kotlinCoroutinesOkhttp" }
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinxCoroutines" }
kotlinx-coroutines-play-services = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-play-services", version.ref = "kotlinxCoroutines" }
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinxCoroutines" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerialization" }
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
okhttp-urlconnection = { module = "com.squareup.okhttp3:okhttp-urlconnection", version.ref = "okhttp" }
otaliastudios-transcoder = { module = "com.otaliastudios:transcoder", version.ref = "otaliastudiosTranscoder" }
unifiedpush-android-connector = { module = "com.github.UnifiedPush:android-connector", version.ref = "unifiedPushAndroidConnector" }
# unmockPlugin = { module = "com.github.bjoernq:unmockplugin", version.ref = "unmockPlugin" }
webpDecoder = { module = "com.github.zjupure:webpdecoder", version.ref = "webpDecoder" }
[plugins]
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" }
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
gradleVersionsPlugin = { id = "com.github.ben-manes.versions", version.ref = "gradleVersionsPlugin" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
# unmockPlugin = { id = "de.mobilej.unmock" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }

View File

@ -1,6 +1,6 @@
#Mon Jun 13 20:53:58 JST 2022
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

View File

@ -1,8 +1,6 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
}
android {
@ -38,9 +36,3 @@ android {
kotlin {
jvmToolchain(Vers.kotlinJvmToolchain)
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
}
}

View File

@ -1,8 +1,6 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
}
android {
@ -56,20 +54,14 @@ android {
kotlin {
jvmToolchain(Vers.kotlinJvmToolchain)
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = Vers.kotlinJvmTarget
}
}
}
dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:${Vers.desugarLibVersion}")
coreLibraryDesugaring(libs.desugar.jdk)
implementation(project(":base"))
implementation(project(":apng_android"))
implementation("androidx.appcompat:appcompat:${Vers.androidxAppcompat}")
implementation(libs.androidx.appcompat)
// ないとなぜかIDE上にエラーが出る
implementation("androidx.activity:activity-ktx:${Vers.androidxActivity}")
implementation(libs.androidx.activity.ktx)
}

View File

@ -1,4 +0,0 @@
include ':app', ':sample_apng', ':apng_android', ':apng', ':colorpicker', ':emoji'
include ':icon_material_symbols'
include ':base'
include ':anko'

44
settings.gradle.kts Normal file
View File

@ -0,0 +1,44 @@
pluginManagement {
repositories {
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
// alexzhirkevich/custom-qr-generator
maven("https://jitpack.io")
}
}
rootProject.name = "SubwayTooter"
// base utilities
include(":base")
// old libraries
include(":anko")
include(":colorpicker")
// apng decoder
include(":apng")
include(":apng_android")
include(":sample_apng")
// emoji images
include(":emoji")
// compose icons
include(":icon_material_symbols")
// main app
include(":app")