diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index e2c0a5797..020b1feef 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -13,6 +13,9 @@ + + + @@ -251,6 +254,18 @@ android:value="10" /> + + + + + + + + + + + + \ No newline at end of file diff --git a/assets b/assets index 3593e8d3b..52c061ecf 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 3593e8d3b00fb6a7a8d9ed6e55c288b1cc27be8d +Subproject commit 52c061ecfed66a01a71d5d0b1e6e9e83e28f0f8a diff --git a/lib/main.dart b/lib/main.dart index 019f19dbb..861b0d286 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -21,8 +21,10 @@ import 'package:autonomy_flutter/model/announcement/announcement_adapter.dart'; import 'package:autonomy_flutter/model/eth_pending_tx_amount.dart'; import 'package:autonomy_flutter/screen/app_router.dart'; import 'package:autonomy_flutter/service/navigation_service.dart'; +import 'package:autonomy_flutter/service/remote_config_service.dart'; import 'package:autonomy_flutter/util/au_file_service.dart'; import 'package:autonomy_flutter/util/canvas_device_adapter.dart'; +import 'package:autonomy_flutter/util/constants.dart'; import 'package:autonomy_flutter/util/custom_route_observer.dart'; import 'package:autonomy_flutter/util/device.dart'; import 'package:autonomy_flutter/util/error_handler.dart'; @@ -35,10 +37,16 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_downloader/flutter_downloader.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:onesignal_flutter/onesignal_flutter.dart'; import 'package:overlay_support/overlay_support.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; +import 'package:timezone/data/latest.dart' as tz; +import 'package:timezone/timezone.dart' as tz; + +final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = + FlutterLocalNotificationsPlugin(); void main() async { unawaited(runZonedGuarded(() async { @@ -89,6 +97,11 @@ void main() async { Future runFeralFileApp() async { WidgetsFlutterBinding.ensureInitialized(); + initializeTimeZones(); + + // Initialize notifications + await initializeNotifications(); + // feature/text_localization await EasyLocalization.ensureInitialized(); @@ -122,6 +135,72 @@ Future runFeralFileApp() async { await _setupApp(); } +void initializeTimeZones() { + tz.initializeTimeZones(); +} + +Future initializeNotifications() async { + const AndroidInitializationSettings initializationSettingsAndroid = + AndroidInitializationSettings('@mipmap/ic_launcher'); + + const DarwinInitializationSettings initializationSettingsIOS = + DarwinInitializationSettings(); + + const InitializationSettings initializationSettings = InitializationSettings( + android: initializationSettingsAndroid, + iOS: initializationSettingsIOS, + ); + + await flutterLocalNotificationsPlugin.initialize(initializationSettings); + flutterLocalNotificationsPlugin + .resolvePlatformSpecificImplementation< + AndroidFlutterLocalNotificationsPlugin>() + ?.requestNotificationsPermission(); +} + +Future scheduleDailyNotification() async { + await flutterLocalNotificationsPlugin.cancel(localNotificationScheduleID); + await flutterLocalNotificationsPlugin.zonedSchedule( + localNotificationScheduleID, + 'Daily Artwork Updated', + 'The daily artwork has been updated for today!', + _nextInstanceOfSixAM(), + const NotificationDetails( + android: AndroidNotificationDetails( + 'daily_artwork_channel_id', + 'Daily Artwork', + channelDescription: 'Channel for daily artwork notifications', + ), + iOS: DarwinNotificationDetails( + presentBadge: true, + badgeNumber: 1, + ), + ), + uiLocalNotificationDateInterpretation: + UILocalNotificationDateInterpretation.absoluteTime, + androidScheduleMode: AndroidScheduleMode.alarmClock, + matchDateTimeComponents: DateTimeComponents.time, + ); +} + +tz.TZDateTime _nextInstanceOfSixAM() { + const defaultScheduleTime = 6; + final configScheduleHour = injector().getConfig( + ConfigGroup.daily, + ConfigKey.scheduleTime, + defaultScheduleTime.toString()); + + final tz.TZDateTime now = tz.TZDateTime.now(tz.local); + tz.TZDateTime scheduledDate = tz.TZDateTime( + tz.local, now.year, now.month, now.day, int.parse(configScheduleHour)) + .subtract(DateTime.now().timeZoneOffset); + + if (scheduledDate.isBefore(now)) { + scheduledDate = scheduledDate.add(const Duration(days: 1)); + } + return scheduledDate; +} + void _registerHiveAdapter() { Hive ..registerAdapter(EthereumPendingTxAmountAdapter()) @@ -138,6 +217,7 @@ Future _setupApp() async { Sentry.captureException(e); } await setupInjector(); + await scheduleDailyNotification(); runApp( EasyLocalization( diff --git a/lib/util/constants.dart b/lib/util/constants.dart index a880d230f..d2d262233 100644 --- a/lib/util/constants.dart +++ b/lib/util/constants.dart @@ -556,3 +556,5 @@ final chatPrivateBannerMessage = SystemMessage( text: 'chat_is_private'.tr(), status: Status.delivered, ); + +const localNotificationScheduleID = 0; diff --git a/pubspec.lock b/pubspec.lock index bca38e95f..094f345eb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -82,7 +82,7 @@ packages: source: hosted version: "2.11.0" audio_session: - dependency: "direct main" + dependency: transitive description: name: audio_session sha256: "6fdf255ed3af86535c96452c33ecff1245990bb25a605bfb1958661ccc3d467f" @@ -619,6 +619,15 @@ packages: url: "https://github.com/bitmark-inc/feralfile-app-client-shared-theme" source: git version: "0.0.1+20" + feralfile_app_tv_proto: + dependency: "direct main" + description: + path: "." + ref: "5bf6bf7ee37506202e675a3c91253a036cbeb43d" + resolved-ref: "5bf6bf7ee37506202e675a3c91253a036cbeb43d" + url: "https://github.com/autonomy-system/feralfile-app-tv-proto-communication" + source: git + version: "0.0.1" ffi: dependency: transitive description: @@ -886,6 +895,15 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.8" + flutter_inline_webview_macos: + dependency: transitive + description: + path: "." + ref: "65f1aba648425aa410c6965f89f50f0120049a50" + resolved-ref: "65f1aba648425aa410c6965f89f50f0120049a50" + url: "https://github.com/autonomy-system/flutter_inline_webview_macos" + source: git + version: "0.0.7" flutter_keyboard_visibility: dependency: "direct main" description: @@ -958,6 +976,30 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.2" + flutter_local_notifications: + dependency: "direct main" + description: + name: flutter_local_notifications + sha256: "49eeef364fddb71515bc78d5a8c51435a68bccd6e4d68e25a942c5e47761ae71" + url: "https://pub.dev" + source: hosted + version: "17.2.3" + flutter_local_notifications_linux: + dependency: transitive + description: + name: flutter_local_notifications_linux + sha256: c49bd06165cad9beeb79090b18cd1eb0296f4bf4b23b84426e37dd7c027fc3af + url: "https://pub.dev" + source: hosted + version: "4.0.1" + flutter_local_notifications_platform_interface: + dependency: transitive + description: + name: flutter_local_notifications_platform_interface + sha256: "85f8d07fe708c1bdcf45037f2c0109753b26ae077e9d9e899d55971711a4ea66" + url: "https://pub.dev" + source: hosted + version: "7.2.0" flutter_localizations: dependency: transitive description: flutter @@ -983,10 +1025,10 @@ packages: dependency: "direct main" description: name: flutter_pdfview - sha256: "6b625b32a9102780236554dff42f2d798b4627704ab4a3153c07f2134a52b697" + sha256: a9055bf920c7095bf08c2781db431ba23577aa5da5a056a7152dc89a18fbec6f url: "https://pub.dev" source: hosted - version: "1.3.3" + version: "1.3.2" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -1616,7 +1658,7 @@ packages: source: hosted version: "6.7.1" just_audio: - dependency: "direct main" + dependency: transitive description: name: just_audio sha256: b607cd1a43bac03d85c3aaee00448ff4a589ef2a77104e3d409889ff079bf823 @@ -1643,18 +1685,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.4" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.3" leak_tracker_testing: dependency: transitive description: @@ -1667,8 +1709,8 @@ packages: dependency: "direct main" description: path: "." - ref: bef404d5e867941296c7e236713242f6bb0a3e5a - resolved-ref: bef404d5e867941296c7e236713242f6bb0a3e5a + ref: "9f68142e2be8f75df201633fbd9bbfc632189acc" + resolved-ref: "9f68142e2be8f75df201633fbd9bbfc632189acc" url: "https://github.com/autonomy-system/libauk-dart.git" source: git version: "0.0.1" @@ -1772,10 +1814,10 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.8.0" measured_size: dependency: "direct main" description: @@ -1796,10 +1838,10 @@ packages: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.12.0" mime: dependency: "direct main" description: @@ -1808,14 +1850,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" - mixpanel_flutter: - dependency: "direct main" - description: - name: mixpanel_flutter - sha256: "7ecd7169acfbda58d9afb35cc4fab8db57410b5f26907206e53d72a86955eb8e" - url: "https://pub.dev" - source: hosted - version: "2.3.2" mockito: dependency: "direct dev" description: @@ -1825,7 +1859,7 @@ packages: source: hosted version: "5.4.4" model_viewer_plus: - dependency: "direct main" + dependency: transitive description: name: model_viewer_plus sha256: eec6de3d1d85533dcc5a8deb4a2b961126138973d26b66cdc55b44ab4fd80f59 @@ -1873,6 +1907,15 @@ packages: url: "https://github.com/autonomy-system/nft-collection" source: git version: "0.0.1" + nft_rendering: + dependency: "direct main" + description: + path: "." + ref: "72f3eee694c66161f31ac63d0a5fc4c475130d34" + resolved-ref: "72f3eee694c66161f31ac63d0a5fc4c475130d34" + url: "https://github.com/autonomy-system/nft-rendering.git" + source: git + version: "1.0.9" nm: dependency: transitive description: @@ -2093,10 +2136,10 @@ packages: dependency: transitive description: name: platform - sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted - version: "3.1.5" + version: "3.1.4" plugin_platform_interface: dependency: transitive description: @@ -2234,7 +2277,7 @@ packages: source: hosted version: "7.0.8" retry: - dependency: transitive + dependency: "direct main" description: name: retry sha256: "822e118d5b3aafed083109c72d5f484c6dc66707885e07c0fbcb8b986bba7efc" @@ -2642,26 +2685,26 @@ packages: dependency: "direct dev" description: name: test - sha256: "7ee44229615f8f642b68120165ae4c2a75fe77ae2065b1e55ae4711f6cf0899e" + sha256: "7ee446762c2c50b3bd4ea96fe13ffac69919352bd3b4b17bac3f3465edc58073" url: "https://pub.dev" source: hosted - version: "1.25.7" + version: "1.25.2" test_api: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.0" test_core: dependency: transitive description: name: test_core - sha256: "55ea5a652e38a1dfb32943a7973f3681a60f872f8c3a05a14664ad54ef9c6696" + sha256: "2bc4b4ecddd75309300d8096f781c0e3280ca1ef85beda558d33fcbedc2eead4" url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "0.6.0" tezart: dependency: "direct main" description: @@ -2671,6 +2714,14 @@ packages: url: "https://github.com/autonomy-system/tezart.git" source: git version: "2.0.4" + timezone: + dependency: "direct main" + description: + name: timezone + sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d" + url: "https://pub.dev" + source: hosted + version: "0.9.4" timing: dependency: transitive description: @@ -2840,7 +2891,7 @@ packages: source: hosted version: "1.1.9+2" vector_graphics_compiler: - dependency: "direct main" + dependency: transitive description: name: vector_graphics_compiler sha256: "03012b0a33775c5530576b70240308080e1d5050f0faf000118c20e6463bc0ad" @@ -2879,6 +2930,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.5.6" + video_player_macos: + dependency: transitive + description: + name: video_player_macos + sha256: "038aec5bbb3789be4bc12f08e2eb730940350ce5f3ce790cee9d897c0f6aacb7" + url: "https://pub.dev" + source: hosted + version: "2.0.1" video_player_platform_interface: dependency: transitive description: @@ -2907,10 +2966,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.2.1" wakelock_plus: dependency: "direct main" description: @@ -2992,37 +3051,37 @@ packages: source: hosted version: "1.2.1" webview_flutter: - dependency: "direct main" + dependency: transitive description: name: webview_flutter - sha256: ec81f57aa1611f8ebecf1d2259da4ef052281cb5ad624131c93546c79ccc7736 + sha256: "789d52bd789373cc1e100fb634af2127e86c99cf9abde09499743270c5de8d00" url: "https://pub.dev" source: hosted - version: "4.9.0" + version: "4.2.2" webview_flutter_android: dependency: transitive description: name: webview_flutter_android - sha256: "6e64fcb1c19d92024da8f33503aaeeda35825d77142c01d0ea2aa32edc79fdc8" + sha256: d936a09fbfd08cb78f7329e0bbacf6158fbdfe24ffc908b22444c07d295eb193 url: "https://pub.dev" source: hosted - version: "3.16.7" + version: "3.9.2" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface - sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d + sha256: "564ef378cafc1a0e29f1d76ce175ef517a0a6115875dff7b43fccbef2b0aeb30" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.4.0" webview_flutter_wkwebview: dependency: transitive description: name: webview_flutter_wkwebview - sha256: "1942a12224ab31e9508cf00c0c6347b931b023b8a4f0811e5dec3b06f94f117d" + sha256: "5fa098f28b606f699e8ca52d9e4e11edbbfef65189f5f77ae92703ba5408fd25" url: "https://pub.dev" source: hosted - version: "3.15.0" + version: "3.7.2" widgets_to_image: dependency: "direct main" description: @@ -3064,7 +3123,7 @@ packages: source: hosted version: "1.0.1" xml: - dependency: "direct main" + dependency: transitive description: name: xml sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" @@ -3080,5 +3139,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.5.0 <4.0.0" - flutter: ">=3.24.0" + dart: ">=3.4.0 <4.0.0" + flutter: ">=3.22.0" diff --git a/pubspec.yaml b/pubspec.yaml index 3a72f3ac2..e3a27fdd7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -164,6 +164,8 @@ dependencies: just_audio: ^0.9.29 xml: ^6.1.0 vector_graphics_compiler: ^1.1.7 + timezone: ^0.9.4 + flutter_local_notifications: ^17.2.3 dependency_overrides: