diff --git a/android/app/build.gradle b/android/app/build.gradle index f360f667e5..640d7a1fdb 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -77,6 +77,7 @@ android { // https://developer.android.com/reference/tools/gradle-api/8.5/com/android/build/api/dsl/Lint checkAllWarnings = true warningsAsErrors = true + baseline = file("lint-baseline.xml") } } diff --git a/android/app/lint-baseline.xml b/android/app/lint-baseline.xml new file mode 100644 index 0000000000..006b010637 --- /dev/null +++ b/android/app/lint-baseline.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/android/app/src/main/kotlin/com/zulip/flutter/Notifications.g.kt b/android/app/src/main/kotlin/com/zulip/flutter/Notifications.g.kt index 1776f4bab4..f4862e2b0b 100644 --- a/android/app/src/main/kotlin/com/zulip/flutter/Notifications.g.kt +++ b/android/app/src/main/kotlin/com/zulip/flutter/Notifications.g.kt @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v25.0.0), do not edit directly. +// Autogenerated from Pigeon (v25.3.1), do not edit directly. // See also: https://pub.dev/packages/pigeon @file:Suppress("UNCHECKED_CAST", "ArrayInDataClass") @@ -13,25 +13,57 @@ import io.flutter.plugin.common.StandardMethodCodec import io.flutter.plugin.common.StandardMessageCodec import java.io.ByteArrayOutputStream import java.nio.ByteBuffer +private object NotificationsPigeonUtils { -private fun wrapResult(result: Any?): List { - return listOf(result) -} + fun wrapResult(result: Any?): List { + return listOf(result) + } -private fun wrapError(exception: Throwable): List { - return if (exception is FlutterError) { - listOf( - exception.code, - exception.message, - exception.details - ) - } else { - listOf( - exception.javaClass.simpleName, - exception.toString(), - "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception) - ) + fun wrapError(exception: Throwable): List { + return if (exception is FlutterError) { + listOf( + exception.code, + exception.message, + exception.details + ) + } else { + listOf( + exception.javaClass.simpleName, + exception.toString(), + "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception) + ) + } + } + fun deepEquals(a: Any?, b: Any?): Boolean { + if (a is ByteArray && b is ByteArray) { + return a.contentEquals(b) + } + if (a is IntArray && b is IntArray) { + return a.contentEquals(b) + } + if (a is LongArray && b is LongArray) { + return a.contentEquals(b) + } + if (a is DoubleArray && b is DoubleArray) { + return a.contentEquals(b) + } + if (a is Array<*> && b is Array<*>) { + return a.size == b.size && + a.indices.all{ deepEquals(a[it], b[it]) } + } + if (a is List<*> && b is List<*>) { + return a.size == b.size && + a.indices.all{ deepEquals(a[it], b[it]) } + } + if (a is Map<*, *> && b is Map<*, *>) { + return a.size == b.size && a.all { + (b as Map).containsKey(it.key) && + deepEquals(it.value, b[it.key]) + } + } + return a == b } + } /** @@ -89,6 +121,16 @@ data class NotificationChannel ( vibrationPattern, ) } + override fun equals(other: Any?): Boolean { + if (other !is NotificationChannel) { + return false + } + if (this === other) { + return true + } + return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) } + + override fun hashCode(): Int = toList().hashCode() } /** @@ -122,6 +164,16 @@ data class AndroidIntent ( flags, ) } + override fun equals(other: Any?): Boolean { + if (other !is AndroidIntent) { + return false + } + if (this === other) { + return true + } + return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) } + + override fun hashCode(): Int = toList().hashCode() } /** @@ -156,6 +208,16 @@ data class PendingIntent ( flags, ) } + override fun equals(other: Any?): Boolean { + if (other !is PendingIntent) { + return false + } + if (this === other) { + return true + } + return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) } + + override fun hashCode(): Int = toList().hashCode() } /** @@ -180,6 +242,16 @@ data class InboxStyle ( summaryText, ) } + override fun equals(other: Any?): Boolean { + if (other !is InboxStyle) { + return false + } + if (this === other) { + return true + } + return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) } + + override fun hashCode(): Int = toList().hashCode() } /** @@ -220,6 +292,16 @@ data class Person ( name, ) } + override fun equals(other: Any?): Boolean { + if (other !is Person) { + return false + } + if (this === other) { + return true + } + return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) } + + override fun hashCode(): Int = toList().hashCode() } /** @@ -250,6 +332,16 @@ data class MessagingStyleMessage ( person, ) } + override fun equals(other: Any?): Boolean { + if (other !is MessagingStyleMessage) { + return false + } + if (this === other) { + return true + } + return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) } + + override fun hashCode(): Int = toList().hashCode() } /** @@ -283,6 +375,16 @@ data class MessagingStyle ( isGroupConversation, ) } + override fun equals(other: Any?): Boolean { + if (other !is MessagingStyle) { + return false + } + if (this === other) { + return true + } + return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) } + + override fun hashCode(): Int = toList().hashCode() } /** @@ -310,6 +412,16 @@ data class Notification ( extras, ) } + override fun equals(other: Any?): Boolean { + if (other !is Notification) { + return false + } + if (this === other) { + return true + } + return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) } + + override fun hashCode(): Int = toList().hashCode() } /** @@ -340,6 +452,16 @@ data class StatusBarNotification ( notification, ) } + override fun equals(other: Any?): Boolean { + if (other !is StatusBarNotification) { + return false + } + if (this === other) { + return true + } + return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) } + + override fun hashCode(): Int = toList().hashCode() } /** @@ -380,6 +502,16 @@ data class StoredNotificationSound ( contentUrl, ) } + override fun equals(other: Any?): Boolean { + if (other !is StoredNotificationSound) { + return false + } + if (this === other) { + return true + } + return NotificationsPigeonUtils.deepEquals(toList(), other.toList()) } + + override fun hashCode(): Int = toList().hashCode() } private open class NotificationsPigeonCodec : StandardMessageCodec() { override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { @@ -605,7 +737,7 @@ interface AndroidNotificationHostApi { api.createNotificationChannel(channelArg) listOf(null) } catch (exception: Throwable) { - wrapError(exception) + NotificationsPigeonUtils.wrapError(exception) } reply.reply(wrapped) } @@ -620,7 +752,7 @@ interface AndroidNotificationHostApi { val wrapped: List = try { listOf(api.getNotificationChannels()) } catch (exception: Throwable) { - wrapError(exception) + NotificationsPigeonUtils.wrapError(exception) } reply.reply(wrapped) } @@ -638,7 +770,7 @@ interface AndroidNotificationHostApi { api.deleteNotificationChannel(channelIdArg) listOf(null) } catch (exception: Throwable) { - wrapError(exception) + NotificationsPigeonUtils.wrapError(exception) } reply.reply(wrapped) } @@ -653,7 +785,7 @@ interface AndroidNotificationHostApi { val wrapped: List = try { listOf(api.listStoredSoundsInNotificationsDirectory()) } catch (exception: Throwable) { - wrapError(exception) + NotificationsPigeonUtils.wrapError(exception) } reply.reply(wrapped) } @@ -671,7 +803,7 @@ interface AndroidNotificationHostApi { val wrapped: List = try { listOf(api.copySoundResourceToMediaStore(targetFileDisplayNameArg, sourceResourceNameArg)) } catch (exception: Throwable) { - wrapError(exception) + NotificationsPigeonUtils.wrapError(exception) } reply.reply(wrapped) } @@ -703,7 +835,7 @@ interface AndroidNotificationHostApi { api.notify(tagArg, idArg, autoCancelArg, channelIdArg, colorArg, contentIntentArg, contentTextArg, contentTitleArg, extrasArg, groupKeyArg, inboxStyleArg, isGroupSummaryArg, messagingStyleArg, numberArg, smallIconResourceNameArg) listOf(null) } catch (exception: Throwable) { - wrapError(exception) + NotificationsPigeonUtils.wrapError(exception) } reply.reply(wrapped) } @@ -720,7 +852,7 @@ interface AndroidNotificationHostApi { val wrapped: List = try { listOf(api.getActiveNotificationMessagingStyleByTag(tagArg)) } catch (exception: Throwable) { - wrapError(exception) + NotificationsPigeonUtils.wrapError(exception) } reply.reply(wrapped) } @@ -737,7 +869,7 @@ interface AndroidNotificationHostApi { val wrapped: List = try { listOf(api.getActiveNotifications(desiredExtrasArg)) } catch (exception: Throwable) { - wrapError(exception) + NotificationsPigeonUtils.wrapError(exception) } reply.reply(wrapped) } @@ -756,7 +888,7 @@ interface AndroidNotificationHostApi { api.cancel(tagArg, idArg) listOf(null) } catch (exception: Throwable) { - wrapError(exception) + NotificationsPigeonUtils.wrapError(exception) } reply.reply(wrapped) } diff --git a/android/app/src/main/kotlin/com/zulip/flutter/ZulipPlugin.kt b/android/app/src/main/kotlin/com/zulip/flutter/ZulipPlugin.kt index eb332d786f..e91b7deafd 100644 --- a/android/app/src/main/kotlin/com/zulip/flutter/ZulipPlugin.kt +++ b/android/app/src/main/kotlin/com/zulip/flutter/ZulipPlugin.kt @@ -19,6 +19,7 @@ import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.core.graphics.drawable.IconCompat import io.flutter.embedding.engine.plugins.FlutterPlugin +import androidx.core.net.toUri private const val TAG = "ZulipPlugin" @@ -64,7 +65,7 @@ private class AndroidNotificationHost(val context: Context) channel.name?.let { setName(it) } channel.lightsEnabled?.let { setLightsEnabled(it) } channel.soundUrl?.let { - setSound(Uri.parse(it), + setSound(it.toUri(), AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build()) } channel.vibrationPattern?.let { setVibrationPattern(it) } @@ -199,7 +200,7 @@ private class AndroidNotificationHost(val context: Context) it.requestCode.toInt(), it.intent.let { intent -> Intent( intent.action, - Uri.parse(intent.dataUrl), + intent.dataUrl.toUri(), context, MainActivity::class.java ).apply { diff --git a/android/gradle.properties b/android/gradle.properties index b0202e3120..e9d14e8cb1 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -6,11 +6,11 @@ android.enableJetifier=true # Defining them here makes them available both in # settings.gradle and in the build.gradle files. -agpVersion=8.5.2 +agpVersion=8.9.1 # Generally update this to the version found in recent releases # of Android Studio, as listed in this table: # https://kotlinlang.org/docs/releases.html#release-details # A helpful discussion is at: # https://stackoverflow.com/a/74425347 -kotlinVersion=2.0.10 +kotlinVersion=2.1.20 diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 545935f33c..479cd23287 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -6,7 +6,7 @@ # the wrapper is the one from the new Gradle too.) distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/ios/Podfile.lock b/ios/Podfile.lock index ea92d3df55..c0db288bed 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -37,31 +37,31 @@ PODS: - file_picker (0.0.1): - DKImagePickerController/PhotoGallery - Flutter - - Firebase/CoreOnly (11.8.0): - - FirebaseCore (~> 11.8.0) - - Firebase/Messaging (11.8.0): + - Firebase/CoreOnly (11.10.0): + - FirebaseCore (~> 11.10.0) + - Firebase/Messaging (11.10.0): - Firebase/CoreOnly - - FirebaseMessaging (~> 11.8.0) - - firebase_core (3.12.1): - - Firebase/CoreOnly (= 11.8.0) + - FirebaseMessaging (~> 11.10.0) + - firebase_core (3.13.0): + - Firebase/CoreOnly (= 11.10.0) - Flutter - - firebase_messaging (15.2.4): - - Firebase/Messaging (= 11.8.0) + - firebase_messaging (15.2.5): + - Firebase/Messaging (= 11.10.0) - firebase_core - Flutter - - FirebaseCore (11.8.1): - - FirebaseCoreInternal (~> 11.8.0) + - FirebaseCore (11.10.0): + - FirebaseCoreInternal (~> 11.10.0) - GoogleUtilities/Environment (~> 8.0) - GoogleUtilities/Logger (~> 8.0) - - FirebaseCoreInternal (11.8.0): + - FirebaseCoreInternal (11.10.0): - "GoogleUtilities/NSData+zlib (~> 8.0)" - - FirebaseInstallations (11.8.0): - - FirebaseCore (~> 11.8.0) + - FirebaseInstallations (11.10.0): + - FirebaseCore (~> 11.10.0) - GoogleUtilities/Environment (~> 8.0) - GoogleUtilities/UserDefaults (~> 8.0) - PromisesObjC (~> 2.4) - - FirebaseMessaging (11.8.0): - - FirebaseCore (~> 11.8.0) + - FirebaseMessaging (11.10.0): + - FirebaseCore (~> 11.10.0) - FirebaseInstallations (~> 11.0) - GoogleDataTransport (~> 10.0) - GoogleUtilities/AppDelegateSwizzler (~> 8.0) @@ -124,6 +124,8 @@ PODS: - sqlite3/common - sqlite3/fts5 (3.49.1): - sqlite3/common + - sqlite3/math (3.49.1): + - sqlite3/common - sqlite3/perf-threadsafe (3.49.1): - sqlite3/common - sqlite3/rtree (3.49.1): @@ -134,6 +136,7 @@ PODS: - sqlite3 (~> 3.49.1) - sqlite3/dbstatvtab - sqlite3/fts5 + - sqlite3/math - sqlite3/perf-threadsafe - sqlite3/rtree - SwiftyGif (5.4.5) @@ -212,35 +215,35 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/wakelock_plus/ios" SPEC CHECKSUMS: - app_settings: 58017cd26b604ae98c3e65acbdd8ba173703cc82 - device_info_plus: bf2e3232933866d73fe290f2942f2156cdd10342 + app_settings: 5127ae0678de1dcc19f2293271c51d37c89428b2 + device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 - file_picker: b159e0c068aef54932bb15dc9fd1571818edaf49 - Firebase: d80354ed7f6df5f9aca55e9eb47cc4b634735eaf - firebase_core: ac395f994af4e28f6a38b59e05a88ca57abeb874 - firebase_messaging: 7e223f4ee7ca053bf4ce43748e84a6d774ec9728 - FirebaseCore: 99fe0c4b44a39f37d99e6404e02009d2db5d718d - FirebaseCoreInternal: df24ce5af28864660ecbd13596fc8dd3a8c34629 - FirebaseInstallations: 6c963bd2a86aca0481eef4f48f5a4df783ae5917 - FirebaseMessaging: 487b634ccdf6f7b7ff180fdcb2a9935490f764e8 + file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be + Firebase: 1fe1c0a7d9aaea32efe01fbea5f0ebd8d70e53a2 + firebase_core: 2d4534e7b489907dcede540c835b48981d890943 + firebase_messaging: 75bc93a4df25faccad67f6662ae872ac9ae69b64 + FirebaseCore: 8344daef5e2661eb004b177488d6f9f0f24251b7 + FirebaseCoreInternal: ef4505d2afb1d0ebbc33162cb3795382904b5679 + FirebaseInstallations: 9980995bdd06ec8081dfb6ab364162bdd64245c3 + FirebaseMessaging: 2b9f56aa4ed286e1f0ce2ee1d413aabb8f9f5cb9 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d - image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1 - integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573 + image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a + integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 - package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4 - path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 + package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 + path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 SDWebImage: f84b0feeb08d2d11e6a9b843cb06d75ebf5b8868 - share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f + share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a sqlite3: fc1400008a9b3525f5914ed715a5d1af0b8f4983 - sqlite3_flutter_libs: cc304edcb8e1d8c595d1b08c7aeb46a47691d9db + sqlite3_flutter_libs: f6acaa2172e6bb3e2e70c771661905080e8ebcf2 SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 - url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe - video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3 - wakelock_plus: 373cfe59b235a6dd5837d0fb88791d2f13a90d56 + url_launcher_ios: 694010445543906933d732453a59da0a173ae33d + video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b + wakelock_plus: 04623e3f525556020ebd4034310f20fe7fda8b49 PODFILE CHECKSUM: 7ed5116924b3be7e8fb75f7aada61e057028f5c7 diff --git a/lib/host/android_notifications.g.dart b/lib/host/android_notifications.g.dart index bc29b2d794..5f46d154e9 100644 --- a/lib/host/android_notifications.g.dart +++ b/lib/host/android_notifications.g.dart @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v25.0.0), do not edit directly. +// Autogenerated from Pigeon (v25.3.1), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers @@ -14,6 +14,20 @@ PlatformException _createConnectionError(String channelName) { message: 'Unable to establish connection on channel: "$channelName".', ); } +bool _deepEquals(Object? a, Object? b) { + if (a is List && b is List) { + return a.length == b.length && + a.indexed + .every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1])); + } + if (a is Map && b is Map) { + return a.length == b.length && a.entries.every((MapEntry entry) => + (b as Map).containsKey(entry.key) && + _deepEquals(entry.value, b[entry.key])); + } + return a == b; +} + /// Corresponds to `androidx.core.app.NotificationChannelCompat` /// @@ -44,7 +58,7 @@ class NotificationChannel { Int64List? vibrationPattern; - Object encode() { + List _toList() { return [ id, importance, @@ -55,6 +69,9 @@ class NotificationChannel { ]; } + Object encode() { + return _toList(); } + static NotificationChannel decode(Object result) { result as List; return NotificationChannel( @@ -66,6 +83,23 @@ class NotificationChannel { vibrationPattern: result[5] as Int64List?, ); } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! NotificationChannel || other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(encode(), other.encode()); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => Object.hashAll(_toList()) +; } /// Corresponds to `android.content.Intent` @@ -87,7 +121,7 @@ class AndroidIntent { /// A combination of flags from [IntentFlag]. int flags; - Object encode() { + List _toList() { return [ action, dataUrl, @@ -95,6 +129,9 @@ class AndroidIntent { ]; } + Object encode() { + return _toList(); } + static AndroidIntent decode(Object result) { result as List; return AndroidIntent( @@ -103,6 +140,23 @@ class AndroidIntent { flags: result[2]! as int, ); } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! AndroidIntent || other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(encode(), other.encode()); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => Object.hashAll(_toList()) +; } /// Corresponds to `android.app.PendingIntent`. @@ -123,7 +177,7 @@ class PendingIntent { /// with `Intent`; see Android docs for `PendingIntent.getActivity`. int flags; - Object encode() { + List _toList() { return [ requestCode, intent, @@ -131,6 +185,9 @@ class PendingIntent { ]; } + Object encode() { + return _toList(); } + static PendingIntent decode(Object result) { result as List; return PendingIntent( @@ -139,6 +196,23 @@ class PendingIntent { flags: result[2]! as int, ); } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! PendingIntent || other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(encode(), other.encode()); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => Object.hashAll(_toList()) +; } /// Corresponds to `androidx.core.app.NotificationCompat.InboxStyle` @@ -151,18 +225,38 @@ class InboxStyle { String summaryText; - Object encode() { + List _toList() { return [ summaryText, ]; } + Object encode() { + return _toList(); } + static InboxStyle decode(Object result) { result as List; return InboxStyle( summaryText: result[0]! as String, ); } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! InboxStyle || other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(encode(), other.encode()); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => Object.hashAll(_toList()) +; } /// Corresponds to `androidx.core.app.Person` @@ -189,7 +283,7 @@ class Person { String name; - Object encode() { + List _toList() { return [ iconBitmap, key, @@ -197,6 +291,9 @@ class Person { ]; } + Object encode() { + return _toList(); } + static Person decode(Object result) { result as List; return Person( @@ -205,6 +302,23 @@ class Person { name: result[2]! as String, ); } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! Person || other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(encode(), other.encode()); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => Object.hashAll(_toList()) +; } /// Corresponds to `androidx.core.app.NotificationCompat.MessagingStyle.Message` @@ -223,7 +337,7 @@ class MessagingStyleMessage { Person person; - Object encode() { + List _toList() { return [ text, timestampMs, @@ -231,6 +345,9 @@ class MessagingStyleMessage { ]; } + Object encode() { + return _toList(); } + static MessagingStyleMessage decode(Object result) { result as List; return MessagingStyleMessage( @@ -239,6 +356,23 @@ class MessagingStyleMessage { person: result[2]! as Person, ); } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! MessagingStyleMessage || other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(encode(), other.encode()); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => Object.hashAll(_toList()) +; } /// Corresponds to `androidx.core.app.NotificationCompat.MessagingStyle` @@ -260,7 +394,7 @@ class MessagingStyle { bool isGroupConversation; - Object encode() { + List _toList() { return [ user, conversationTitle, @@ -269,6 +403,9 @@ class MessagingStyle { ]; } + Object encode() { + return _toList(); } + static MessagingStyle decode(Object result) { result as List; return MessagingStyle( @@ -278,6 +415,23 @@ class MessagingStyle { isGroupConversation: result[3]! as bool, ); } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! MessagingStyle || other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(encode(), other.encode()); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => Object.hashAll(_toList()) +; } /// Corresponds to `android.app.Notification` @@ -293,13 +447,16 @@ class Notification { Map extras; - Object encode() { + List _toList() { return [ group, extras, ]; } + Object encode() { + return _toList(); } + static Notification decode(Object result) { result as List; return Notification( @@ -307,6 +464,23 @@ class Notification { extras: (result[1] as Map?)!.cast(), ); } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! Notification || other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(encode(), other.encode()); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => Object.hashAll(_toList()) +; } /// Corresponds to `android.service.notification.StatusBarNotification` @@ -325,7 +499,7 @@ class StatusBarNotification { Notification notification; - Object encode() { + List _toList() { return [ id, tag, @@ -333,6 +507,9 @@ class StatusBarNotification { ]; } + Object encode() { + return _toList(); } + static StatusBarNotification decode(Object result) { result as List; return StatusBarNotification( @@ -341,6 +518,23 @@ class StatusBarNotification { notification: result[2]! as Notification, ); } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! StatusBarNotification || other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(encode(), other.encode()); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => Object.hashAll(_toList()) +; } /// Represents details about a notification sound stored in the @@ -367,7 +561,7 @@ class StoredNotificationSound { /// A `content://…` URL pointing to the sound file. String contentUrl; - Object encode() { + List _toList() { return [ fileName, isOwned, @@ -375,6 +569,9 @@ class StoredNotificationSound { ]; } + Object encode() { + return _toList(); } + static StoredNotificationSound decode(Object result) { result as List; return StoredNotificationSound( @@ -383,6 +580,23 @@ class StoredNotificationSound { contentUrl: result[2]! as String, ); } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! StoredNotificationSound || other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(encode(), other.encode()); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => Object.hashAll(_toList()) +; } diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 83d38cb17e..dab9b53101 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -7,32 +7,32 @@ PODS: - FlutterMacOS - file_selector_macos (0.0.1): - FlutterMacOS - - Firebase/CoreOnly (11.8.1): - - FirebaseCore (~> 11.8.1) - - Firebase/Messaging (11.8.1): + - Firebase/CoreOnly (11.10.0): + - FirebaseCore (~> 11.10.0) + - Firebase/Messaging (11.10.0): - Firebase/CoreOnly - - FirebaseMessaging (~> 11.8.0) - - firebase_core (3.12.1): - - Firebase/CoreOnly (~> 11.8.0) + - FirebaseMessaging (~> 11.10.0) + - firebase_core (3.13.0): + - Firebase/CoreOnly (~> 11.10.0) - FlutterMacOS - - firebase_messaging (15.2.4): - - Firebase/CoreOnly (~> 11.8.0) - - Firebase/Messaging (~> 11.8.0) + - firebase_messaging (15.2.5): + - Firebase/CoreOnly (~> 11.10.0) + - Firebase/Messaging (~> 11.10.0) - firebase_core - FlutterMacOS - - FirebaseCore (11.8.1): - - FirebaseCoreInternal (~> 11.8.0) + - FirebaseCore (11.10.0): + - FirebaseCoreInternal (~> 11.10.0) - GoogleUtilities/Environment (~> 8.0) - GoogleUtilities/Logger (~> 8.0) - - FirebaseCoreInternal (11.8.0): + - FirebaseCoreInternal (11.10.0): - "GoogleUtilities/NSData+zlib (~> 8.0)" - - FirebaseInstallations (11.8.0): - - FirebaseCore (~> 11.8.0) + - FirebaseInstallations (11.10.0): + - FirebaseCore (~> 11.10.0) - GoogleUtilities/Environment (~> 8.0) - GoogleUtilities/UserDefaults (~> 8.0) - PromisesObjC (~> 2.4) - - FirebaseMessaging (11.8.0): - - FirebaseCore (~> 11.8.0) + - FirebaseMessaging (11.10.0): + - FirebaseCore (~> 11.10.0) - FirebaseInstallations (~> 11.0) - GoogleDataTransport (~> 10.0) - GoogleUtilities/AppDelegateSwizzler (~> 8.0) @@ -88,6 +88,8 @@ PODS: - sqlite3/common - sqlite3/fts5 (3.49.1): - sqlite3/common + - sqlite3/math (3.49.1): + - sqlite3/common - sqlite3/perf-threadsafe (3.49.1): - sqlite3/common - sqlite3/rtree (3.49.1): @@ -98,6 +100,7 @@ PODS: - sqlite3 (~> 3.49.1) - sqlite3/dbstatvtab - sqlite3/fts5 + - sqlite3/math - sqlite3/perf-threadsafe - sqlite3/rtree - url_launcher_macos (0.0.1): @@ -168,30 +171,30 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos SPEC CHECKSUMS: - app_settings: 140be3a9c0fc1f681e44afe9f549ab037b3aa3a2 - device_info_plus: 1b14eed9bf95428983aed283a8d51cce3d8c4215 - file_picker: e716a70a9fe5fd9e09ebc922d7541464289443af - file_selector_macos: cc3858c981fe6889f364731200d6232dac1d812d - Firebase: 973c28133496aab0223e9ea99f0abafb9f91ad58 - firebase_core: 1b573eac37729348cdc472516991dd7e269ae37e - firebase_messaging: 0620038ea399ceae2218c9087fca00a28f576209 - FirebaseCore: 99fe0c4b44a39f37d99e6404e02009d2db5d718d - FirebaseCoreInternal: df24ce5af28864660ecbd13596fc8dd3a8c34629 - FirebaseInstallations: 6c963bd2a86aca0481eef4f48f5a4df783ae5917 - FirebaseMessaging: 487b634ccdf6f7b7ff180fdcb2a9935490f764e8 + app_settings: cd21e176b56f8172043640ade81322a98896bff4 + device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76 + file_picker: 7584aae6fa07a041af2b36a2655122d42f578c1a + file_selector_macos: 6280b52b459ae6c590af5d78fc35c7267a3c4b31 + Firebase: 1fe1c0a7d9aaea32efe01fbea5f0ebd8d70e53a2 + firebase_core: efd50ad8177dc489af1b9163a560359cf1b30597 + firebase_messaging: acf2566068a55d7eb8cddfee5b094754070a5b88 + FirebaseCore: 8344daef5e2661eb004b177488d6f9f0f24251b7 + FirebaseCoreInternal: ef4505d2afb1d0ebbc33162cb3795382904b5679 + FirebaseInstallations: 9980995bdd06ec8081dfb6ab364162bdd64245c3 + FirebaseMessaging: 2b9f56aa4ed286e1f0ce2ee1d413aabb8f9f5cb9 FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 - package_info_plus: 12f1c5c2cfe8727ca46cbd0b26677728972d9a5b - path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 + package_info_plus: f0052d280d17aa382b932f399edf32507174e870 + path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 - share_plus: 1fa619de8392a4398bfaf176d441853922614e89 + share_plus: 510bf0af1a42cd602274b4629920c9649c52f4cc sqlite3: fc1400008a9b3525f5914ed715a5d1af0b8f4983 - sqlite3_flutter_libs: cc304edcb8e1d8c595d1b08c7aeb46a47691d9db - url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404 - video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3 - wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269 + sqlite3_flutter_libs: f6acaa2172e6bb3e2e70c771661905080e8ebcf2 + url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673 + video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b + wakelock_plus: 21ddc249ac4b8d018838dbdabd65c5976c308497 PODFILE CHECKSUM: bd6842df0dd91920553fbfacd50c921f7e63a62f diff --git a/pubspec.lock b/pubspec.lock index 19a072d370..d9b10dad5d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "7fd72d77a7487c26faab1d274af23fb008763ddc10800261abbfb2c067f183d5" + sha256: de9ecbb3ddafd446095f7e833c853aff2fa1682b017921fe63a833f9d6f0e422 url: "https://pub.dev" source: hosted - version: "1.3.53" + version: "1.3.54" analyzer: dependency: transitive description: @@ -29,10 +29,10 @@ packages: dependency: "direct main" description: name: app_settings - sha256: "476df1d85cec143c3d27dd1c7451629a59c0c5ccf70a0adcbfa92a0a2d928705" + sha256: "3e46c561441e5820d3a25339bf8b51b9e45a5f686873851a20c257a530917795" url: "https://pub.dev" source: hosted - version: "5.2.0" + version: "6.1.1" args: dependency: "direct dev" description: @@ -153,6 +153,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.0" + cli_config: + dependency: transitive + description: + name: cli_config + sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec + url: "https://pub.dev" + source: hosted + version: "0.2.0" cli_util: dependency: transitive description: @@ -206,10 +214,10 @@ packages: dependency: transitive description: name: coverage - sha256: e3493833ea012784c740e341952298f1cc77f1f01b1bbc3eb4eecf6984fb7f43 + sha256: "9086475ef2da7102a0c0a4e37e1e30707e7fb7b6d28c209f559a9c5f8ce42016" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" cross_file: dependency: transitive description: @@ -310,10 +318,10 @@ packages: dependency: "direct main" description: name: file_picker - sha256: "8d938fd5c11dc81bf1acd4f7f0486c683fe9e79a0b13419e27730f9ce4d8a25b" + sha256: "8986dec4581b4bcd4b6df5d75a2ea0bede3db802f500635d05fa8be298f9467f" url: "https://pub.dev" source: hosted - version: "9.2.1" + version: "10.1.2" file_selector_linux: dependency: transitive description: @@ -350,10 +358,10 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: f4d8f49574a4e396f34567f3eec4d38ab9c3910818dec22ca42b2a467c685d8b + sha256: "017d17d9915670e6117497e640b2859e0b868026ea36bf3a57feb28c3b97debe" url: "https://pub.dev" source: hosted - version: "3.12.1" + version: "3.13.0" firebase_core_platform_interface: dependency: transitive description: @@ -366,34 +374,34 @@ packages: dependency: transitive description: name: firebase_core_web - sha256: faa5a76f6380a9b90b53bc3bdcb85bc7926a382e0709b9b5edac9f7746651493 + sha256: "129a34d1e0fb62e2b488d988a1fc26cc15636357e50944ffee2862efe8929b23" url: "https://pub.dev" source: hosted - version: "2.21.1" + version: "2.22.0" firebase_messaging: dependency: "direct main" description: name: firebase_messaging - sha256: "5fc345c6341f9dc69fd0ffcbf508c784fd6d1b9e9f249587f30434dd8b6aa281" + sha256: "5f8918848ee0c8eb172fc7698619b2bcd7dda9ade8b93522c6297dd8f9178356" url: "https://pub.dev" source: hosted - version: "15.2.4" + version: "15.2.5" firebase_messaging_platform_interface: dependency: transitive description: name: firebase_messaging_platform_interface - sha256: a935924cf40925985c8049df4968b1dde5c704f570f3ce380b31d3de6990dd94 + sha256: "0bbea00680249595fc896e7313a2bd90bd55be6e0abbe8b9a39d81b6b306acb6" url: "https://pub.dev" source: hosted - version: "4.6.4" + version: "4.6.5" firebase_messaging_web: dependency: transitive description: name: firebase_messaging_web - sha256: fafebf6a1921931334f3f10edb5037a5712288efdd022881e2d093e5654a2fd4 + sha256: ffb392ce2a7e8439cd0a9a80e3c702194e73c927e5c7b4f0adf6faa00b245b17 url: "https://pub.dev" source: hosted - version: "3.10.4" + version: "3.10.5" fixnum: dependency: transitive description: @@ -411,10 +419,10 @@ packages: dependency: "direct dev" description: name: flutter_checks - sha256: b0a40b15d38436b7c08b83353e74b0569c1ec687bd81c9556091fbb8807c1b99 + sha256: "800acdd6973e1306f65ef3b2287d91c0e45c8e64b696d593297c0c1c1e2740bc" url: "https://pub.dev" source: hosted - version: "0.1.1" + version: "0.1.2" flutter_color_models: dependency: "direct main" description: @@ -493,10 +501,10 @@ packages: dependency: "direct main" description: name: html - sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec" + sha256: "9475be233c437f0e3637af55e7702cbbe5c23a68bd56e8a5fa2d426297b7c6c8" url: "https://pub.dev" source: hosted - version: "0.15.5" + version: "0.15.5+1" http: dependency: "direct main" description: @@ -666,10 +674,10 @@ packages: dependency: "direct dev" description: name: legacy_checks - sha256: b22e5b1ff55a14e8bd91acafbabff909e14829b73ca492dcdaf0fbbb70476079 + sha256: "1322d6f15e27c214b225d32c9802cd8d312a0373a45efccf48e5e2bb42c7611b" url: "https://pub.dev" source: hosted - version: "0.1.0" + version: "0.1.1" lints: dependency: transitive description: @@ -826,10 +834,10 @@ packages: dependency: "direct dev" description: name: pigeon - sha256: "81a70703f015a9493d3e0d3de22d23db33f8838a44312856b3749376ba45e5d2" + sha256: "3e4e6258f22760fa11f86d2a5202fb3f8367cb361d33bd9a93de85a7959e9976" url: "https://pub.dev" source: hosted - version: "25.0.0" + version: "25.3.1" platform: dependency: transitive description: @@ -1007,10 +1015,10 @@ packages: dependency: "direct main" description: name: sqlite3_flutter_libs - sha256: "7adb4cc96dc08648a5eb1d80a7619070796ca6db03901ff2b6dcb15ee30468f3" + sha256: "1a96b59227828d9eb1463191d684b37a27d66ee5ed7597fcf42eee6452c88a14" url: "https://pub.dev" source: hosted - version: "0.5.31" + version: "0.5.32" sqlparser: dependency: transitive description: @@ -1127,10 +1135,10 @@ packages: dependency: transitive description: name: url_launcher_ios - sha256: "16a513b6c12bb419304e72ea0ae2ab4fed569920d1c7cb850263fe3acc824626" + sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb" url: "https://pub.dev" source: hosted - version: "6.3.2" + version: "6.3.3" url_launcher_linux: dependency: transitive description: @@ -1191,10 +1199,10 @@ packages: dependency: "direct main" description: name: video_player - sha256: "48941c8b05732f9582116b1c01850b74dbee1d8520cd7e34ad4609d6df666845" + sha256: "7d78f0cfaddc8c19d4cb2d3bebe1bfef11f2103b0a03e5398b303a1bf65eeb14" url: "https://pub.dev" source: hosted - version: "2.9.3" + version: "2.9.5" video_player_android: dependency: transitive description: @@ -1239,10 +1247,10 @@ packages: dependency: "direct main" description: name: wakelock_plus - sha256: "36c88af0b930121941345306d259ec4cc4ecca3b151c02e3a9e71aede83c615e" + sha256: b90fbcc8d7bdf3b883ea9706d9d76b9978cb1dfa4351fcc8014d6ec31a493354 url: "https://pub.dev" source: hosted - version: "1.2.10" + version: "1.2.11" wakelock_plus_platform_interface: dependency: transitive description: @@ -1347,5 +1355,5 @@ packages: source: path version: "0.0.1" sdks: - dart: ">=3.8.0-227.0.dev <4.0.0" - flutter: ">=3.31.0-1.0.pre.274" + dart: ">=3.8.0-265.0.dev <4.0.0" + flutter: ">=3.32.0-1.0.pre.87" diff --git a/pubspec.yaml b/pubspec.yaml index c95e6fb353..7a67797fcc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,8 +14,8 @@ environment: # We use a recent version of Flutter from its main channel, and # the corresponding recent version of the Dart SDK. # Feel free to update these regularly; see README.md for instructions. - sdk: '>=3.8.0-227.0.dev <4.0.0' - flutter: '>=3.31.0-1.0.pre.274' # 3b6d9666f8e34f277d45fc9ce37080a1979b2411 + sdk: '>=3.8.0-265.0.dev <4.0.0' + flutter: '>=3.32.0-1.0.pre.87' # 427f8c8e1569e1d2dba4583ef27cc06baa744108 # To update dependencies, see instructions in README.md. dependencies: @@ -35,13 +35,13 @@ dependencies: # https://github.com/dart-lang/i18n/issues/759#issuecomment-1864316701 # https://github.com/flutter/flutter/issues/117163 - app_settings: ^5.0.0 + app_settings: ^6.1.1 collection: ^1.17.2 convert: ^3.1.1 crypto: ^3.0.3 device_info_plus: ^11.2.0 drift: ^2.23.0 - file_picker: ^9.0.2 + file_picker: ^10.1.2 firebase_core: ^3.3.0 firebase_messaging: ^15.0.1 flutter_color_models: ^1.3.3+2 @@ -96,12 +96,12 @@ dev_dependencies: clock: ^1.1.1 drift_dev: ^2.5.2 fake_async: ^1.3.1 - flutter_checks: ^0.1.1 + flutter_checks: ^0.1.2 flutter_lints: ^5.0.0 ini: ^2.1.0 json_serializable: ^6.5.4 legacy_checks: ^0.1.0 - pigeon: ^25.0.0 + pigeon: ^25.3.1 plugin_platform_interface: ^2.1.8 stack_trace: ^1.11.1 test: ^1.23.1 diff --git a/test/widgets/channel_colors_test.dart b/test/widgets/channel_colors_test.dart index 7657ffc236..46d3527def 100644 --- a/test/widgets/channel_colors_test.dart +++ b/test/widgets/channel_colors_test.dart @@ -5,7 +5,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:zulip/widgets/channel_colors.dart'; import 'channel_colors_checks.dart'; -import 'colors_checks.dart'; void main() { group('ChannelColorSwatches', () { diff --git a/test/widgets/colors_checks.dart b/test/widgets/colors_checks.dart deleted file mode 100644 index 10af11810e..0000000000 --- a/test/widgets/colors_checks.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:checks/checks.dart'; -import 'package:flutter_test/flutter_test.dart' as flutter_matcher; -import 'package:flutter/painting.dart'; -import 'package:legacy_checks/legacy_checks.dart'; - -extension ColorSwatchChecks on Subject> { - /// package:checks-style wrapper for [flutter_matcher.isSameColorSwatchAs]. - void isSameColorSwatchAs(ColorSwatch colorSwatch) { - legacyMatcher(flutter_matcher.isSameColorSwatchAs(colorSwatch)); - } -} diff --git a/test/widgets/theme_test.dart b/test/widgets/theme_test.dart index e671bce514..8510d42b7c 100644 --- a/test/widgets/theme_test.dart +++ b/test/widgets/theme_test.dart @@ -3,6 +3,7 @@ import 'dart:ui'; import 'package:checks/checks.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; +import 'package:flutter_checks/flutter_checks.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:zulip/model/settings.dart'; import 'package:zulip/widgets/channel_colors.dart'; @@ -13,7 +14,6 @@ import '../example_data.dart' as eg; import '../flutter_checks.dart'; import '../model/binding.dart'; import '../model/store_checks.dart'; -import 'colors_checks.dart'; import 'test_app.dart'; void main() {