OSSライセンス画面の書き直し

This commit is contained in:
tateisu 2024-03-18 00:54:05 +09:00
parent 15f54bdf00
commit 6cd8839bbd
14 changed files with 91 additions and 68 deletions

View File

@ -164,8 +164,8 @@ 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")

View File

@ -98,7 +98,6 @@
android:label="@string/app_name"
android:largeHeap="true"
android:localeConfig="@xml/locales_config"
android:maxAspectRatio="100"
android:resizeableActivity="true"
android:supportsRtl="true"
android:theme="@style/Theme.App.Starting"

View File

@ -22,7 +22,6 @@ import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import com.jrummyapps.android.colorpicker.ColorPickerDialogType
import com.jrummyapps.android.colorpicker.dialogColorPicker
import jp.juggler.subwaytooter.api.TootApiClient
import jp.juggler.subwaytooter.api.TootApiResult

View File

@ -36,7 +36,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.jrummyapps.android.colorpicker.ColorPickerDialogType
import com.jrummyapps.android.colorpicker.dialogColorPicker
import jp.juggler.subwaytooter.appsetting.AppDataExporter
import jp.juggler.subwaytooter.appsetting.AppSettingItem

View File

@ -7,7 +7,6 @@ import android.content.Context
import android.content.res.Configuration
import android.os.Handler
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.emoji2.bundled.BundledEmojiCompatConfig
import androidx.emoji2.text.EmojiCompat
import com.bumptech.glide.Glide
@ -29,16 +28,21 @@ 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.*
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 jp.juggler.util.ui.*
import okhttp3.*
import okhttp3.Cache
import okhttp3.CacheControl
import okhttp3.ConnectionSpec
import okhttp3.CookieJar
import okhttp3.Interceptor
import okhttp3.JavaNetCookieJar
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.conscrypt.Conscrypt
import ru.gildor.coroutines.okhttp.await
import java.io.File
@ -47,7 +51,7 @@ import java.net.CookieHandler
import java.net.CookieManager
import java.net.CookiePolicy
import java.security.Security
import java.util.*
import java.util.Collections
import java.util.concurrent.TimeUnit
import java.util.logging.Level
import java.util.logging.Logger

View File

@ -16,7 +16,6 @@ import android.view.WindowManager
import android.widget.ImageButton
import android.widget.ImageView
import androidx.annotation.DrawableRes
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SwitchCompat
import androidx.core.content.ContextCompat
import jp.juggler.subwaytooter.api.entity.TootAccount
@ -28,10 +27,14 @@ import jp.juggler.subwaytooter.pref.lazyContext
import jp.juggler.subwaytooter.span.EmojiImageSpan
import jp.juggler.subwaytooter.span.createSpan
import jp.juggler.subwaytooter.table.UserRelation
import jp.juggler.util.*
import jp.juggler.util.data.notZero
import jp.juggler.util.log.LogCategory
import jp.juggler.util.ui.*
import jp.juggler.util.ui.attrColor
import jp.juggler.util.ui.mixColor
import jp.juggler.util.ui.scan
import jp.juggler.util.ui.setIconDrawableId
import jp.juggler.util.ui.setNavigationBarColorCompat
import jp.juggler.util.ui.setStatusBarColorCompat
import org.xmlpull.v1.XmlPullParser
import kotlin.math.max
import kotlin.math.min
@ -68,6 +71,7 @@ fun TootVisibility.getVisibilityIconId(isMisskeyData: Boolean): Int {
TootVisibility.Limited -> R.drawable.ic_account_circle
TootVisibility.Mutual -> R.drawable.ic_bidirectional
}
else -> when (this) {
TootVisibility.Public -> R.drawable.ic_public
TootVisibility.UnlistedHome -> R.drawable.ic_lock_open
@ -113,6 +117,7 @@ fun TootVisibility.getVisibilityString(isMisskeyData: Boolean): String {
TootVisibility.Limited -> R.string.visibility_limited
TootVisibility.Mutual -> R.string.visibility_mutual
}
else -> when (this) {
TootVisibility.Public -> R.string.visibility_public
TootVisibility.UnlistedHome -> R.string.visibility_unlisted
@ -316,6 +321,7 @@ fun fixHorizontalPadding(v: View, dpDelta: Float = 12f) {
v.setPaddingRelative(padLr + dm.widthPixels / 2, padT, padLr, padB)
return
}
else -> Unit
}
}
@ -403,6 +409,7 @@ fun SpannableStringBuilder.appendMisskeyReaction(
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
else ->
this.append(emoji.unifiedCode)
}

View File

@ -1,6 +1,7 @@
package jp.juggler.subwaytooter.ui.ossLicense
import android.os.Bundle
import android.view.Window
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
@ -38,6 +39,9 @@ import androidx.compose.ui.unit.dp
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.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
@ -64,16 +68,20 @@ class ActOSSLicense : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestWindowFeature(Window.FEATURE_NO_TITLE)
// ステータスバーの色にattr色を使っているので、テーマの指定は必要
App1.setActivityTheme(this)
val stColorScheme = getStColorTheme()
setContent {
Screen(
stColorScheme = stColorScheme,
librariesFlow = viewModel.libraries,
isProgressShownFlow = viewModel.isProgressShown,
)
}
try {
viewModel.load()
viewModel.load(stColorScheme = stColorScheme)
} catch (ex: Throwable) {
log.e(ex, "dependency in fo loading failed.")
}
@ -83,6 +91,7 @@ class ActOSSLicense : ComponentActivity() {
@Composable
fun DefaultPreview() {
Screen(
stColorScheme = dummyStColorTheme(),
isProgressShownFlow = MutableStateFlow(false),
librariesFlow = MutableStateFlow(
listOf(
@ -109,56 +118,50 @@ class ActOSSLicense : ComponentActivity() {
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun Screen(
stColorScheme: StColorScheme,
librariesFlow: Flow<List<LibText>>,
isProgressShownFlow: Flow<Boolean>,
) {
val isProgressShown = isProgressShownFlow.collectAsState(false)
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
TopAppBar(
title = {
Text(stringResource(R.string.oss_license))
},
navigationIcon = {
IconButton(
onClick = { finish() }
) {
Icon(
// imageVector = AutoMirrored.Outlined.ArrowBack,
imageVector = Icons.Outlined.Close,
contentDescription = stringResource(R.string.close)
)
}
},
scrollBehavior = scrollBehavior,
colors = TopAppBarDefaults.topAppBarColors(
// containerColor = : Color = Color.Unspecified,
// scrolledContainerColor: Color = Color.Unspecified,
// navigationIconContentColor: Color = Color.Unspecified,
// titleContentColor: Color = Color.Unspecified,
// actionIconContentColor: Color = Color.Unspecified,
containerColor = MaterialTheme.colorScheme.primaryContainer,
titleContentColor = MaterialTheme.colorScheme.primary,
),
)
},
) { innerPadding ->
when (isProgressShown.value) {
true -> Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center,
) {
CircularProgressIndicator(
modifier = Modifier.width(64.dp),
color = MaterialTheme.colorScheme.secondary,
trackColor = MaterialTheme.colorScheme.surfaceVariant,
MaterialTheme(colorScheme = stColorScheme.materialColorScheme) {
Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
TopAppBar(
title = {
Text(stringResource(R.string.oss_license))
},
navigationIcon = {
IconButton(
onClick = { finish() }
) {
Icon(
// imageVector = AutoMirrored.Outlined.ArrowBack,
imageVector = Icons.Outlined.Close,
contentDescription = stringResource(R.string.close)
)
}
},
scrollBehavior = scrollBehavior,
colors = TopAppBarDefaults.topAppBarColors(),
)
}
},
) { innerPadding ->
when (isProgressShown.value) {
true -> Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center,
) {
CircularProgressIndicator(
modifier = Modifier.width(64.dp),
color = MaterialTheme.colorScheme.secondary,
trackColor = MaterialTheme.colorScheme.surfaceVariant,
)
}
else -> ScrollContent(innerPadding, librariesFlow)
else -> ScrollContent(innerPadding, librariesFlow)
}
}
}
}
@ -188,7 +191,9 @@ class ActOSSLicense : ComponentActivity() {
src.nameBig.notEmpty()?.let {
ClickableText(
text = it,
style = MaterialTheme.typography.headlineMedium,
style = MaterialTheme.typography.headlineSmall.copy(
color = MaterialTheme.colorScheme.onBackground,
),
) { offset ->
it.getStringAnnotations(
tag = "URL",
@ -202,7 +207,9 @@ class ActOSSLicense : ComponentActivity() {
src.nameSmall.notEmpty()?.let {
ClickableText(
text = it,
style = MaterialTheme.typography.bodySmall,
style = MaterialTheme.typography.bodySmall.copy(
color = MaterialTheme.colorScheme.onBackground,
),
) { offset ->
it.getStringAnnotations(
tag = "URL",
@ -217,7 +224,9 @@ class ActOSSLicense : ComponentActivity() {
src.desc.notEmpty()?.let {
ClickableText(
text = it,
style = MaterialTheme.typography.bodyMedium,
style = MaterialTheme.typography.bodyMedium.copy(
color = MaterialTheme.colorScheme.onBackground,
),
) { offset ->
it.getStringAnnotations(
tag = "URL",

View File

@ -63,7 +63,7 @@ class PermissionRequester(
)
}
fun hasPermissions() :Boolean{
fun hasPermissions(): Boolean {
val activity = activity ?: error("missing activity.")
val listNotGranted = spec.listNotGranded(activity)
return listNotGranted.isEmpty()

View File

@ -19,7 +19,7 @@
<color name="Light_colorColumnSettingBackground">#bbb</color>
<color name="Light_colorColumnStripBackground">#fff</color>
<color name="Light_colorConversationMainTootBg">#200088ff</color>
<color name="Light_colorLink">#00a2ff</color>
<color name="Light_colorLink">#0080ff</color>
<color name="Light_colorPostFormBackground">#eee</color>
<color name="Light_colorActionBarBg">#ccc</color>
<color name="Light_colorActionBarBgStacked">#ddd</color>

View File

@ -25,7 +25,7 @@ class ByteRangeTest {
val kotlinBase64UrlSafe = Base64.UrlSafe
// kotlin.io の Base64.UrlSafe は 末尾の = パディングを残すので後から除去する必要がある
val encodedByKotlinIo = kotlinBase64UrlSafe.encode(src).trimEnd { it=='=' }
val encodedByKotlinIo = kotlinBase64UrlSafe.encode(src).trimEnd { it == '=' }
// ByteRange().encodeBase64Url() はパディングを含まない
val encodeByByteRange = src.toByteRange().encodeBase64Url()
// StringUtils の encodeBase64Url() はパディングを含まない

View File

@ -84,11 +84,11 @@ fun AppCompatActivity.launchAndShowError(
/////////////////////////////////////////////////////////////////////////
suspend fun <T:Any?> AppCompatActivity.withProgress(
caption:String,
suspend fun <T : Any?> AppCompatActivity.withProgress(
caption: String,
progressInitializer: suspend (ProgressDialogEx) -> Unit = {},
block: suspend (progress :ProgressDialogEx)->T,
):T {
block: suspend (progress: ProgressDialogEx) -> T,
): T {
val activity = this
var progress: ProgressDialogEx? = null
try {

View File

@ -25,6 +25,7 @@ import android.widget.ImageButton
import android.widget.ImageView
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResult
import androidx.annotation.ColorRes
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
@ -53,6 +54,9 @@ fun Context.attrColor(attrId: Int): Int {
return color
}
fun Context.resColor(@ColorRes resId: Int): Int =
ContextCompat.getColor(this, resId)
fun <T> TypedArray.use(block: (TypedArray) -> T): T =
try {
block(this)
@ -352,6 +356,7 @@ fun AppCompatActivity.setNavigationBack(toolbar: Toolbar) =
toolbar.setNavigationOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
fun ComponentActivity.setNavigationBack(toolbar: Toolbar) =
toolbar.setNavigationOnClickListener {
onBackPressedDispatcher.onBackPressed()

View File

@ -12,7 +12,6 @@ import android.view.inputmethod.InputMethodManager
import android.widget.CompoundButton
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import jp.juggler.util.log.LogCategory
import kotlin.math.pow
@ -44,6 +43,7 @@ fun View.hideKeyboard() {
when (val imm = this.context?.getSystemService(Context.INPUT_METHOD_SERVICE)) {
is InputMethodManager ->
imm.hideSoftInputFromWindow(this.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
else -> log.e("hideKeyboard: can't get InputMethodManager")
}
} catch (ex: Throwable) {
@ -148,6 +148,7 @@ fun Activity.setStatusBarColorCompat(@ColorInt c: Int) {
//Dark Text to show up on your light status bar
decorView.systemUiVisibility or bit
}
else -> {
//Light Text to show up on your dark status bar
decorView.systemUiVisibility and bit.inv()

View File

@ -50,7 +50,7 @@ object Vers {
const val apng4AndroidVersion = "2.25.0"
const val conscryptVersion = "2.5.2"
const val desugarLibVersion = "2.0.4"
const val detektVersion = "1.23.4"
const val detektVersion = "1.23.5"
const val gildorkotlinCoroutinesOkhttp = "1.0"
const val googleFlexbox="3.0.0"
const val googleMaterial = "1.11.0"