Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
Hosted Weblate 2025-06-09 18:47:14 +02:00
commit 7c72770013
No known key found for this signature in database
GPG key ID: A3FAAA06E6569B4C
12 changed files with 34 additions and 61 deletions

View file

@ -33,13 +33,13 @@ kotlin {
} }
android { android {
namespace 'deckers.thibault.aves' namespace = 'deckers.thibault.aves'
compileSdk 35 compileSdk = 36
defaultConfig { defaultConfig {
applicationId packageName applicationId packageName
minSdk flutter.minSdkVersion minSdk flutter.minSdkVersion
targetSdk 35 targetSdk 36
versionCode flutter.versionCode versionCode flutter.versionCode
versionName flutter.versionName versionName flutter.versionName
manifestPlaceholders = [googleApiKey: keystoreProperties["googleApiKey"] ?: "<NONE>"] manifestPlaceholders = [googleApiKey: keystoreProperties["googleApiKey"] ?: "<NONE>"]
@ -149,14 +149,14 @@ repositories {
} }
dependencies { dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2'
implementation "androidx.appcompat:appcompat:1.7.0" implementation "androidx.appcompat:appcompat:1.7.1"
implementation 'androidx.core:core-ktx:1.16.0' implementation 'androidx.core:core-ktx:1.16.0'
implementation 'androidx.lifecycle:lifecycle-process:2.9.0' implementation 'androidx.lifecycle:lifecycle-process:2.9.1'
implementation 'androidx.media:media:1.7.0' implementation 'androidx.media:media:1.7.0'
implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.security:security-crypto:1.1.0-alpha07' implementation 'androidx.security:security-crypto:1.1.0-beta01'
implementation 'androidx.work:work-runtime-ktx:2.10.1' implementation 'androidx.work:work-runtime-ktx:2.10.1'
implementation 'com.commonsware.cwac:document:0.5.0' implementation 'com.commonsware.cwac:document:0.5.0'
@ -164,7 +164,7 @@ dependencies {
implementation "com.github.bumptech.glide:glide:$glide_version" implementation "com.github.bumptech.glide:glide:$glide_version"
implementation 'com.google.android.material:material:1.12.0' implementation 'com.google.android.material:material:1.12.0'
// SLF4J implementation for `mp4parser` // SLF4J implementation for `mp4parser`
implementation 'org.slf4j:slf4j-simple:2.0.16' implementation 'org.slf4j:slf4j-simple:2.0.17'
// forked, built by JitPack: // forked, built by JitPack:
// - https://jitpack.io/p/deckerst/Android-TiffBitmapFactory // - https://jitpack.io/p/deckerst/Android-TiffBitmapFactory
@ -178,7 +178,7 @@ dependencies {
implementation 'com.github.deckerst:pixymeta-android:cb1cdc932e' implementation 'com.github.deckerst:pixymeta-android:cb1cdc932e'
implementation project(':exifinterface') implementation project(':exifinterface')
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.11.4' testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.13.1'
kapt 'androidx.annotation:annotation:1.9.1' kapt 'androidx.annotation:annotation:1.9.1'
ksp "com.github.bumptech.glide:ksp:$glide_version" ksp "com.github.bumptech.glide:ksp:$glide_version"

View file

@ -2,6 +2,7 @@ package deckers.thibault.aves.channel.calls
import android.app.ActivityManager import android.app.ActivityManager
import android.content.Context import android.content.Context
import androidx.core.content.edit
import androidx.work.ExistingWorkPolicy import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequestBuilder import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkInfo import androidx.work.WorkInfo
@ -18,7 +19,6 @@ import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
class AnalysisHandler(private val activity: FlutterFragmentActivity, private val onAnalysisCompleted: () -> Unit) : MethodChannel.MethodCallHandler { class AnalysisHandler(private val activity: FlutterFragmentActivity, private val onAnalysisCompleted: () -> Unit) : MethodChannel.MethodCallHandler {
private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
@ -38,9 +38,8 @@ class AnalysisHandler(private val activity: FlutterFragmentActivity, private val
} }
val preferences = activity.getSharedPreferences(AnalysisWorker.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE) val preferences = activity.getSharedPreferences(AnalysisWorker.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE)
with(preferences.edit()) { preferences.edit {
putLong(AnalysisWorker.PREF_CALLBACK_HANDLE_KEY, callbackHandle) putLong(AnalysisWorker.PREF_CALLBACK_HANDLE_KEY, callbackHandle)
apply()
} }
result.success(true) result.success(true)
} }
@ -69,9 +68,8 @@ class AnalysisHandler(private val activity: FlutterFragmentActivity, private val
// work `Data` cannot occupy more than 10240 bytes when serialized // work `Data` cannot occupy more than 10240 bytes when serialized
// so we save the possibly long list of entry IDs to shared preferences // so we save the possibly long list of entry IDs to shared preferences
val preferences = activity.getSharedPreferences(AnalysisWorker.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE) val preferences = activity.getSharedPreferences(AnalysisWorker.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE)
with(preferences.edit()) { preferences.edit {
putStringSet(AnalysisWorker.PREF_ENTRY_IDS_KEY, allEntryIds?.map { it.toString() }?.toSet()) putStringSet(AnalysisWorker.PREF_ENTRY_IDS_KEY, allEntryIds?.map { it.toString() }?.toSet())
apply()
} }
val workData = workDataOf( val workData = workDataOf(

View file

@ -1,5 +1,6 @@
package deckers.thibault.aves.channel.calls package deckers.thibault.aves.channel.calls
import android.annotation.SuppressLint
import android.app.LocaleConfig import android.app.LocaleConfig
import android.app.LocaleManager import android.app.LocaleManager
import android.content.Context import android.content.Context
@ -102,6 +103,7 @@ class DeviceHandler(private val context: Context) : MethodCallHandler {
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
@SuppressLint("WrongConstant")
val lm = context.getSystemService(Context.LOCALE_SERVICE) as? LocaleManager val lm = context.getSystemService(Context.LOCALE_SERVICE) as? LocaleManager
lm?.overrideLocaleConfig = LocaleConfig(LocaleList.forLanguageTags(locales.joinToString(","))) lm?.overrideLocaleConfig = LocaleConfig(LocaleList.forLanguageTags(locales.joinToString(",")))
} }

View file

@ -31,7 +31,7 @@ class GeocodingHandler(private val context: Context) : MethodCallHandler {
private fun getAddress(call: MethodCall, result: MethodChannel.Result) { private fun getAddress(call: MethodCall, result: MethodChannel.Result) {
val latitude = call.argument<Number>("latitude")?.toDouble() val latitude = call.argument<Number>("latitude")?.toDouble()
val longitude = call.argument<Number>("longitude")?.toDouble() val longitude = call.argument<Number>("longitude")?.toDouble()
val localeString = call.argument<String>("locale") val localeLanguageTag = call.argument<String>("localeLanguageTag")
val maxResults = call.argument<Int>("maxResults") ?: 1 val maxResults = call.argument<Int>("maxResults") ?: 1
if (latitude == null || longitude == null) { if (latitude == null || longitude == null) {
result.error("getAddress-args", "missing arguments", null) result.error("getAddress-args", "missing arguments", null)
@ -43,11 +43,8 @@ class GeocodingHandler(private val context: Context) : MethodCallHandler {
return return
} }
geocoder = geocoder ?: if (localeString != null) { geocoder = geocoder ?: if (localeLanguageTag != null) {
val split = localeString.split("_") Geocoder(context, Locale.forLanguageTag(localeLanguageTag))
val language = split[0]
val country = if (split.size > 1) split[1] else ""
Geocoder(context, Locale(language, country))
} else { } else {
Geocoder(context) Geocoder(context)
} }

View file

@ -1,6 +1,7 @@
package deckers.thibault.aves.channel.calls package deckers.thibault.aves.channel.calls
import android.content.Context import android.content.Context
import androidx.core.content.edit
import deckers.thibault.aves.SearchSuggestionsProvider import deckers.thibault.aves.SearchSuggestionsProvider
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodCall
@ -29,9 +30,8 @@ class GlobalSearchHandler(private val context: Context) : MethodCallHandler {
} }
val preferences = context.getSharedPreferences(SearchSuggestionsProvider.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE) val preferences = context.getSharedPreferences(SearchSuggestionsProvider.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE)
with(preferences.edit()) { preferences.edit {
putLong(SearchSuggestionsProvider.CALLBACK_HANDLE_KEY, callbackHandle) putLong(SearchSuggestionsProvider.CALLBACK_HANDLE_KEY, callbackHandle)
apply()
} }
result.success(true) result.success(true)
} }

View file

@ -2,6 +2,7 @@ package deckers.thibault.aves.channel.calls
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import androidx.core.content.edit
import androidx.security.crypto.EncryptedSharedPreferences import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey import androidx.security.crypto.MasterKey
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
@ -45,7 +46,7 @@ class SecurityHandler(private val context: Context) : MethodCallHandler {
} }
val preferences = getStore() val preferences = getStore()
with(preferences.edit()) { preferences.edit {
when (value) { when (value) {
is Boolean -> putBoolean(key, value) is Boolean -> putBoolean(key, value)
is Float -> putFloat(key, value) is Float -> putFloat(key, value)
@ -58,7 +59,6 @@ class SecurityHandler(private val context: Context) : MethodCallHandler {
return return
} }
} }
apply()
} }
result.success(true) result.success(true)
} }

View file

@ -81,12 +81,12 @@ object PixyMetaHelper {
output: OutputStream, output: OutputStream,
iptcDataList: List<FieldMap>?, iptcDataList: List<FieldMap>?,
) { ) {
val iptc = iptcDataList?.flatMap { val iptc: List<IPTCDataSet> = iptcDataList?.flatMap {
val record = it["record"] as Int val record = it["record"] as Int
val tag = it["tag"] as Int val tag = it["tag"] as Int
val values = it["values"] as List<*> val values = it["values"] as List<*>
values.map { data -> IPTCDataSet(IPTCRecord.fromRecordNumber(record), tag, data as ByteArray) } values.map { data -> IPTCDataSet(IPTCRecord.fromRecordNumber(record), tag, data as ByteArray) }
} ?: ArrayList<IPTCDataSet>() } ?: ArrayList()
Metadata.insertIPTC(input, output, iptc) Metadata.insertIPTC(input, output, iptc)
} }

View file

@ -5,5 +5,5 @@ import kotlin.math.pow
object MathUtils { object MathUtils {
fun highestPowerOf2(x: Int): Int = highestPowerOf2(x.toDouble()) fun highestPowerOf2(x: Int): Int = highestPowerOf2(x.toDouble())
private fun highestPowerOf2(x: Double): Int = if (x < 1) 0 else 2.toDouble().pow(log2(x).toInt()).toInt() fun highestPowerOf2(x: Double): Int = if (x < 1) 0 else 2.toDouble().pow(log2(x).toInt()).toInt()
} }

View file

@ -18,10 +18,10 @@ pluginManagement {
plugins { plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0" id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "8.8.1" apply false id("com.android.application") version "8.10.1" apply false
id("org.jetbrains.kotlin.android") version "2.1.10" apply false id("org.jetbrains.kotlin.android") version "2.1.21" apply false
id("com.google.devtools.ksp") version "2.1.10-1.0.29" apply false id("com.google.devtools.ksp") version "2.1.21-2.0.1" apply false
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
} }
include(":app") include(":app")

View file

@ -15,7 +15,7 @@ class GeocodingService {
final result = await _platform.invokeMethod('getAddress', <String, dynamic>{ final result = await _platform.invokeMethod('getAddress', <String, dynamic>{
'latitude': coordinates.latitude, 'latitude': coordinates.latitude,
'longitude': coordinates.longitude, 'longitude': coordinates.longitude,
'locale': locale.toString(), 'localeLanguageTag': locale.toLanguageTag(),
// we only really need one address, but sometimes the native geocoder // we only really need one address, but sometimes the native geocoder
// returns nothing with `maxResults` of 1, but succeeds with `maxResults` of 2+ // returns nothing with `maxResults` of 1, but succeeds with `maxResults` of 2+
'maxResults': 2, 'maxResults': 2,

View file

@ -209,7 +209,7 @@ class _EntryGoogleMapState<T> extends State<EntryGoogleMap<T>> {
bitmapScaling: MapBitmapScaling.none, bitmapScaling: MapBitmapScaling.none,
), ),
position: _toServiceLatLng(dotLocation), position: _toServiceLatLng(dotLocation),
zIndex: 1, zIndexInt: 1,
) )
}, },
polylines: { polylines: {

View file

@ -112,14 +112,6 @@ packages:
url: "https://github.com/deckerst/flutter_google_charts.git" url: "https://github.com/deckerst/flutter_google_charts.git"
source: git source: git
version: "0.12.0" version: "0.12.0"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
url: "https://pub.dev"
source: hosted
version: "2.0.3"
cli_config: cli_config:
dependency: transitive dependency: transitive
description: description:
@ -180,10 +172,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: coverage name: coverage
sha256: "4b8701e48a58f7712492c9b1f7ba0bb9d525644dd66d023b62e1fc8cdb560c8a" sha256: aa07dbe5f2294c827b7edb9a87bba44a9c15a3cc81bc8da2ca19b37322d30080
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.14.0" version: "1.14.1"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
@ -588,10 +580,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: google_maps_flutter_platform_interface name: google_maps_flutter_platform_interface
sha256: "970c8f766c02909c7be282dea923c971f83a88adaf07f8871d0aacebc3b07bb2" sha256: f8293f072ed8b068b092920a72da6693aa8b3d62dc6b5c5f0bc44c969a8a776c
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.11.1" version: "2.12.1"
google_maps_flutter_web: google_maps_flutter_web:
dependency: transitive dependency: transitive
description: description:
@ -680,14 +672,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.1" version: "0.7.1"
json_annotation:
dependency: transitive
description:
name: json_annotation
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
url: "https://pub.dev"
source: hosted
version: "4.9.0"
latlong2: latlong2:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1234,14 +1218,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.0" version: "2.2.0"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082"
url: "https://pub.dev"
source: hosted
version: "1.5.0"
qr: qr:
dependency: transitive dependency: transitive
description: description: