diff --git a/AGENTS.md b/AGENTS.md index 2be2010..43f3f61 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,6 +36,7 @@ Sensitive Areas (require explicit approval) Operational Conventions - Branch naming: `codex/-` (e.g., `codex/fix-url-matcher`). - Commits: Conventional Commits preferred (e.g., `fix: correct url matching for X`). +- Git push 후 공유하는 설명/보고는 반드시 한국어로 작성합니다. - PR description template: - Summary: what/why - Changes: key files and decisions diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 6a6a66f..c7a1458 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -45,5 +45,5 @@ flutter { } dependencies { - coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4") + coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4") } diff --git a/assets/data/text.json b/assets/data/text.json index 4d35cca..4eb092b 100644 --- a/assets/data/text.json +++ b/assets/data/text.json @@ -126,7 +126,7 @@ "repeatSubscriptionNotFound": "No repeated subscription information found.", "newSubscriptionNotFound": "No new subscription SMS found", "findRepeatSubscriptions": "Find subscriptions paid 2+ times", - "scanTextMessages": "Scan text messages to automatically find repeatedly paid subscriptions. Service names and amounts can be extracted for easy subscription addition.", + "scanTextMessages": "Scan text messages to automatically find repeatedly paid subscriptions.\nService names and amounts can be extracted for easy subscription addition.\nThis auto-detection feature is still under development, and might miss or misidentify some subscriptions.\nPlease review the detected results and add or edit subscriptions manually if needed.", "startScanning": "Start Scanning", "foundSubscription": "Found subscription", "serviceName": "Service Name", @@ -357,7 +357,7 @@ "repeatSubscriptionNotFound": "반복 결제된 구독 정보를 찾을 수 없습니다.", "newSubscriptionNotFound": "신규 구독 관련 SMS를 찾을 수 없습니다", "findRepeatSubscriptions": "2회 이상 결제된 구독 서비스 찾기", - "scanTextMessages": "문자 메시지를 스캔하여 반복적으로 결제된 구독 서비스를 자동으로 찾습니다. 서비스명과 금액을 추출하여 쉽게 구독을 추가할 수 있습니다.", + "scanTextMessages": "문자 메시지를 스캔하여 반복적으로 결제된 구독 서비스를 자동으로 찾습니다.\n서비스명과 금액을 추출하여 쉽게 구독을 추가할 수 있습니다.\n이 자동 감지 기능은 일부 구독 서비스를 놓치거나 잘못 인식할 수 있습니다.\n감지 결과를 확인하신 후 필요에 따라 수동으로 추가하거나 수정해 주세요.", "startScanning": "스캔 시작하기", "foundSubscription": "다음 구독을 찾았습니다", "serviceName": "서비스명", @@ -588,7 +588,7 @@ "repeatSubscriptionNotFound": "繰り返し決済されたサブスクリプション情報が見つかりません。", "newSubscriptionNotFound": "新規サブスクリプションSMSが見つかりません", "findRepeatSubscriptions": "2回以上決済されたサブスクリプションを検索", - "scanTextMessages": "テキストメッセージをスキャンして、繰り返し決済されたサブスクリプションを自動的に検出します。サービス名と金額を抽出して簡単にサブスクリプションを追加できます。", + "scanTextMessages": "テキストメッセージをスキャンして、繰り返し決済されたサブスクリプションを自動的に検出します。\nサービス名と金額を抽出して簡単にサブスクリプションを追加できます。\nこの自動検出機能は、一部のサブスクリプションを見落としたり誤検出する可能性があります。\n検出結果を確認し、必要に応じて手動で追加または修正してください。", "startScanning": "スキャン開始", "foundSubscription": "サブスクリプションが見つかりました", "serviceName": "サービス名", @@ -808,7 +808,7 @@ "repeatSubscriptionNotFound": "未找到重复付款的订阅信息。", "newSubscriptionNotFound": "未找到新订阅短信", "findRepeatSubscriptions": "查找支付2次以上的订阅", - "scanTextMessages": "扫描短信以自动查找重复付款的订阅。可以提取服务名称和金额,轻松添加订阅。", + "scanTextMessages": "扫描短信以自动查找重复付款的订阅。\n可以提取服务名称和金额,轻松添加订阅。\n该自动检测功能可能会遗漏或误识别某些订阅。\n请检查检测结果,并在需要时手动添加或修改。", "startScanning": "开始扫描", "foundSubscription": "找到订阅", "serviceName": "服务名称", diff --git a/lib/providers/notification_provider.dart b/lib/providers/notification_provider.dart index de6a0f5..b4ac28f 100644 --- a/lib/providers/notification_provider.dart +++ b/lib/providers/notification_provider.dart @@ -114,6 +114,23 @@ class NotificationProvider extends ChangeNotifier { // 알림이 활성화된 경우에만 알림 재예약 (비활성화 시에는 필요 없음) if (value) { + final hasPermission = await NotificationService.checkPermission(); + if (!hasPermission) { + final granted = await NotificationService.requestPermission(); + if (!granted) { + debugPrint('알림 권한이 부여되지 않았습니다. 일부 알림이 제한될 수 있습니다.'); + } + } + + final canExact = await NotificationService.canScheduleExactAlarms(); + if (!canExact) { + final exactGranted = + await NotificationService.requestExactAlarmsPermission(); + if (!exactGranted) { + debugPrint('정확 알람 권한이 없어 근사 알림으로 예약됩니다.'); + } + } + // 알림 설정 변경 시 모든 구독의 알림 재예약 // 지연 실행으로 UI 응답성 향상 Future.microtask(() => _rescheduleNotificationsIfNeeded()); diff --git a/lib/providers/subscription_provider.dart b/lib/providers/subscription_provider.dart index 7efc654..2d0d24c 100644 --- a/lib/providers/subscription_provider.dart +++ b/lib/providers/subscription_provider.dart @@ -103,6 +103,14 @@ class SubscriptionProvider extends ChangeNotifier { } } + Future _reschedulePaymentNotifications() async { + try { + await NotificationService.reschedulAllNotifications(_subscriptions); + } catch (e) { + debugPrint('결제 알림 재예약 중 오류 발생: $e'); + } + } + Future addSubscription({ required String serviceName, required double monthlyCost, @@ -145,6 +153,8 @@ class SubscriptionProvider extends ChangeNotifier { if (isEventActive && eventEndDate != null) { await _scheduleEventEndNotification(subscription); } + + await _reschedulePaymentNotifications(); } catch (e) { debugPrint('구독 추가 중 오류 발생: $e'); rethrow; @@ -176,6 +186,8 @@ class SubscriptionProvider extends ChangeNotifier { debugPrint('[SubscriptionProvider] 구독 업데이트 완료, ' '현재 총 월간 지출: ${totalMonthlyExpense.toStringAsFixed(2)}'); notifyListeners(); + + await _reschedulePaymentNotifications(); } catch (e) { debugPrint('구독 업데이트 중 오류 발생: $e'); rethrow; @@ -186,6 +198,8 @@ class SubscriptionProvider extends ChangeNotifier { try { await _subscriptionBox.delete(id); await refreshSubscriptions(); + + await _reschedulePaymentNotifications(); } catch (e) { debugPrint('구독 삭제 중 오류 발생: $e'); rethrow; @@ -213,6 +227,8 @@ class SubscriptionProvider extends ChangeNotifier { } finally { _isLoading = false; notifyListeners(); + + await _reschedulePaymentNotifications(); } } @@ -226,6 +242,7 @@ class SubscriptionProvider extends ChangeNotifier { title: '이벤트 종료 알림', body: '${subscription.serviceName}의 할인 이벤트가 종료되었습니다.', scheduledDate: subscription.eventEndDate!, + channelId: NotificationService.expirationChannelId, ); } } diff --git a/lib/screens/add_subscription_screen.dart b/lib/screens/add_subscription_screen.dart index 1ca478f..0b8d818 100644 --- a/lib/screens/add_subscription_screen.dart +++ b/lib/screens/add_subscription_screen.dart @@ -9,7 +9,7 @@ import '../widgets/add_subscription/add_subscription_save_button.dart'; /// 새로운 구독을 추가하는 화면 class AddSubscriptionScreen extends StatefulWidget { - const AddSubscriptionScreen({Key? key}) : super(key: key); + const AddSubscriptionScreen({super.key}); @override State createState() => _AddSubscriptionScreenState(); diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index 5032c1f..4c5ff4b 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter/foundation.dart' show kIsWeb; +import 'package:flutter/foundation.dart' show kIsWeb, kDebugMode; import 'package:provider/provider.dart'; import '../providers/notification_provider.dart'; import 'dart:io'; @@ -694,6 +694,25 @@ class SettingsScreen extends StatelessWidget { ), ), ), + if (kDebugMode) + Padding( + padding: + const EdgeInsets.only( + top: 16.0), + child: SizedBox( + width: double.infinity, + child: OutlinedButton.icon( + icon: const Icon(Icons + .notifications_active), + label: + const Text('테스트 알림'), + onPressed: () { + NotificationService + .showTestPaymentNotification(); + }, + ), + ), + ), ], ), ), diff --git a/lib/screens/sms_scan_screen.dart b/lib/screens/sms_scan_screen.dart index d3c1f7a..d766ee3 100644 --- a/lib/screens/sms_scan_screen.dart +++ b/lib/screens/sms_scan_screen.dart @@ -16,18 +16,21 @@ class SmsScanScreen extends StatefulWidget { class _SmsScanScreenState extends State { late SmsScanController _controller; + late final ScrollController _scrollController; @override void initState() { super.initState(); _controller = SmsScanController(); _controller.addListener(_handleControllerUpdate); + _scrollController = ScrollController(); } @override void dispose() { _controller.removeListener(_handleControllerUpdate); _controller.dispose(); + _scrollController.dispose(); super.dispose(); } @@ -93,16 +96,37 @@ class _SmsScanScreenState extends State { websiteUrlController: _controller.websiteUrlController, selectedCategoryId: _controller.selectedCategoryId, onCategoryChanged: _controller.setSelectedCategoryId, - onAdd: () => _controller.addCurrentSubscription(context), - onSkip: () => _controller.skipCurrentSubscription(context), + onAdd: _handleAddSubscription, + onSkip: _handleSkipSubscription, ), ], ); } + Future _handleAddSubscription() async { + await _controller.addCurrentSubscription(context); + if (!mounted) return; + WidgetsBinding.instance.addPostFrameCallback((_) => _scrollToTop()); + } + + void _handleSkipSubscription() { + _controller.skipCurrentSubscription(context); + WidgetsBinding.instance.addPostFrameCallback((_) => _scrollToTop()); + } + + void _scrollToTop() { + if (!_scrollController.hasClients) return; + _scrollController.animateTo( + 0, + duration: const Duration(milliseconds: 300), + curve: Curves.easeOut, + ); + } + @override Widget build(BuildContext context) { return SingleChildScrollView( + controller: _scrollController, padding: EdgeInsets.zero, child: Column( children: [ diff --git a/lib/screens/splash_screen.dart b/lib/screens/splash_screen.dart index ca1ff9c..163cb4d 100644 --- a/lib/screens/splash_screen.dart +++ b/lib/screens/splash_screen.dart @@ -186,7 +186,7 @@ class _SplashScreenState extends State ), ), ); - }).toList(), + }), // 상단 원형 장식 제거(단색 배경 유지) Positioned( diff --git a/lib/services/url_matcher/url_matcher.dart b/lib/services/url_matcher/url_matcher.dart index cc800c8..3b0691e 100644 --- a/lib/services/url_matcher/url_matcher.dart +++ b/lib/services/url_matcher/url_matcher.dart @@ -1,2 +1,2 @@ -/// URL Matcher 패키지의 export 파일 +// URL Matcher 패키지의 export 파일 export 'models/service_info.dart'; diff --git a/lib/widgets/analysis/event_analysis_card.dart b/lib/widgets/analysis/event_analysis_card.dart index 846cacc..a595262 100644 --- a/lib/widgets/analysis/event_analysis_card.dart +++ b/lib/widgets/analysis/event_analysis_card.dart @@ -298,7 +298,7 @@ class EventAnalysisCard extends StatelessWidget { ], ), ); - }).toList(), + }), ], ), ), diff --git a/lib/widgets/analysis/monthly_expense_chart_card.dart b/lib/widgets/analysis/monthly_expense_chart_card.dart index 036f43b..3566b7d 100644 --- a/lib/widgets/analysis/monthly_expense_chart_card.dart +++ b/lib/widgets/analysis/monthly_expense_chart_card.dart @@ -226,10 +226,10 @@ class MonthlyExpenseChartCard extends StatelessWidget { barTouchData: BarTouchData( enabled: true, touchTooltipData: BarTouchTooltipData( - tooltipBgColor: Theme.of(context) + tooltipBorderRadius: BorderRadius.circular(8), + getTooltipColor: (group) => Theme.of(context) .colorScheme .inverseSurface, - tooltipRoundedRadius: 8, getTooltipItem: (group, groupIndex, rod, rodIndex) { return BarTooltipItem( @@ -261,10 +261,10 @@ class MonthlyExpenseChartCard extends StatelessWidget { ), ), ), - swapAnimationDuration: ReduceMotion.isEnabled(context) - ? const Duration(milliseconds: 0) + duration: ReduceMotion.isEnabled(context) + ? Duration.zero : const Duration(milliseconds: 300), - swapAnimationCurve: Curves.easeOut, + curve: Curves.easeOut, ), ), ), diff --git a/lib/widgets/analysis/subscription_pie_chart_card.dart b/lib/widgets/analysis/subscription_pie_chart_card.dart index 3c9c27d..704d149 100644 --- a/lib/widgets/analysis/subscription_pie_chart_card.dart +++ b/lib/widgets/analysis/subscription_pie_chart_card.dart @@ -390,12 +390,10 @@ class _SubscriptionPieChartCardState extends State { }, ), ), - swapAnimationDuration: - ReduceMotion.isEnabled(context) - ? const Duration(milliseconds: 0) - : const Duration( - milliseconds: 300), - swapAnimationCurve: Curves.easeOut, + duration: ReduceMotion.isEnabled(context) + ? Duration.zero + : const Duration(milliseconds: 300), + curve: Curves.easeOut, ), ); }, diff --git a/lib/widgets/animated_wave_background.dart b/lib/widgets/animated_wave_background.dart index 12accaf..776f1af 100644 --- a/lib/widgets/animated_wave_background.dart +++ b/lib/widgets/animated_wave_background.dart @@ -10,10 +10,10 @@ class AnimatedWaveBackground extends StatelessWidget { final AnimationController pulseController; const AnimatedWaveBackground({ - Key? key, + super.key, required this.controller, required this.pulseController, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/widgets/category_header_widget.dart b/lib/widgets/category_header_widget.dart index 28ead74..97c5ee6 100644 --- a/lib/widgets/category_header_widget.dart +++ b/lib/widgets/category_header_widget.dart @@ -15,14 +15,14 @@ class CategoryHeaderWidget extends StatelessWidget { final double totalCostCNY; const CategoryHeaderWidget({ - Key? key, + super.key, required this.categoryName, required this.subscriptionCount, required this.totalCostUSD, required this.totalCostKRW, required this.totalCostJPY, required this.totalCostCNY, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/widgets/empty_state_widget.dart b/lib/widgets/empty_state_widget.dart index 0822ade..452d111 100644 --- a/lib/widgets/empty_state_widget.dart +++ b/lib/widgets/empty_state_widget.dart @@ -17,12 +17,12 @@ class EmptyStateWidget extends StatelessWidget { final VoidCallback onAddPressed; const EmptyStateWidget({ - Key? key, + super.key, required this.fadeController, required this.rotateController, required this.slideController, required this.onAddPressed, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/widgets/main_summary_card.dart b/lib/widgets/main_summary_card.dart index c22acae..c085a9a 100644 --- a/lib/widgets/main_summary_card.dart +++ b/lib/widgets/main_summary_card.dart @@ -18,13 +18,13 @@ class MainScreenSummaryCard extends StatelessWidget { final AnimationController waveController; final AnimationController slideController; const MainScreenSummaryCard({ - Key? key, + super.key, required this.provider, required this.fadeController, required this.pulseController, required this.waveController, required this.slideController, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/widgets/native_ad_widget.dart b/lib/widgets/native_ad_widget.dart index efd4e76..6407457 100644 --- a/lib/widgets/native_ad_widget.dart +++ b/lib/widgets/native_ad_widget.dart @@ -11,8 +11,7 @@ import '../theme/ui_constants.dart'; /// SRP에 따라 광고 전용 위젯으로 분리 class NativeAdWidget extends StatefulWidget { final bool useOuterPadding; // true이면 외부에서 페이지 패딩을 제공 - const NativeAdWidget({Key? key, this.useOuterPadding = false}) - : super(key: key); + const NativeAdWidget({super.key, this.useOuterPadding = false}); @override State createState() => _NativeAdWidgetState(); diff --git a/lib/widgets/sms_scan/scan_loading_widget.dart b/lib/widgets/sms_scan/scan_loading_widget.dart index 7d06259..d381748 100644 --- a/lib/widgets/sms_scan/scan_loading_widget.dart +++ b/lib/widgets/sms_scan/scan_loading_widget.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -// import '../../theme/app_colors.dart'; +import '../../widgets/native_ad_widget.dart'; import '../../widgets/themed_text.dart'; import '../../l10n/app_localizations.dart'; @@ -8,29 +8,33 @@ class ScanLoadingWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - CircularProgressIndicator( - color: Theme.of(context).colorScheme.primary, - ), - const SizedBox(height: 16), - ThemedText( - AppLocalizations.of(context).scanningMessages, - forceDark: true, - ), - const SizedBox(height: 8), - ThemedText( - AppLocalizations.of(context).findingSubscriptions, - opacity: 0.7, - forceDark: true, - ), - ], + return Column( + children: [ + const NativeAdWidget(key: ValueKey('sms_scan_loading_ad')), + const SizedBox(height: 48), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CircularProgressIndicator( + color: Theme.of(context).colorScheme.primary, + ), + const SizedBox(height: 16), + ThemedText( + AppLocalizations.of(context).scanningMessages, + forceDark: true, + ), + const SizedBox(height: 8), + ThemedText( + AppLocalizations.of(context).findingSubscriptions, + opacity: 0.7, + forceDark: true, + ), + ], + ), ), - ), + ], ); } } diff --git a/lib/widgets/subscription_list_widget.dart b/lib/widgets/subscription_list_widget.dart index 5af84a0..762ad28 100644 --- a/lib/widgets/subscription_list_widget.dart +++ b/lib/widgets/subscription_list_widget.dart @@ -20,10 +20,10 @@ class SubscriptionListWidget extends StatelessWidget { final AnimationController fadeController; const SubscriptionListWidget({ - Key? key, + super.key, required this.categorizedSubscriptions, required this.fadeController, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -188,9 +188,9 @@ class MultiSliver extends StatelessWidget { final List children; const MultiSliver({ - Key? key, + super.key, required this.children, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index d0a0d33..edcf12a 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,7 +6,7 @@ import FlutterMacOS import Foundation import flutter_local_notifications -import flutter_secure_storage_macos +import flutter_secure_storage_darwin import local_auth_darwin import path_provider_foundation import share_plus @@ -17,7 +17,7 @@ import webview_flutter_wkwebview func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) - FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) + FlutterSecureStorageDarwinPlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStorageDarwinPlugin")) LocalAuthPlugin.register(with: registry.registrar(forPlugin: "LocalAuthPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 49c6cde..19007db 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -293,10 +293,10 @@ packages: dependency: "direct main" description: name: fl_chart - sha256: "00b74ae680df6b1135bdbea00a7d1fc072a9180b7c3f3702e4b19a9943f5ed7d" + sha256: "7ca9a40f4eb85949190e54087be8b4d6ac09dc4c54238d782a34cf1f7c011de9" url: "https://pub.dev" source: hosted - version: "0.66.2" + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -314,50 +314,58 @@ packages: dependency: "direct main" description: name: flutter_dotenv - sha256: b7c7be5cd9f6ef7a78429cabd2774d3c4af50e79cb2b7593e3d5d763ef95c61b + sha256: d4130c4a43e0b13fefc593bc3961f2cb46e30cb79e253d4a526b1b5d24ae1ce4 url: "https://pub.dev" source: hosted - version: "5.2.1" + version: "6.0.0" flutter_launcher_icons: dependency: "direct main" description: name: flutter_launcher_icons - sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea" + sha256: "10f13781741a2e3972126fae08393d3c4e01fa4cd7473326b94b72cf594195e7" url: "https://pub.dev" source: hosted - version: "0.13.1" + version: "0.14.4" flutter_lints: dependency: "direct dev" description: name: flutter_lints - sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 + sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "6.0.0" flutter_local_notifications: dependency: "direct main" description: name: flutter_local_notifications - sha256: "674173fd3c9eda9d4c8528da2ce0ea69f161577495a9cc835a2a4ecd7eadeb35" + sha256: "7ed76be64e8a7d01dfdf250b8434618e2a028c9dfa2a3c41dc9b531d4b3fc8a5" url: "https://pub.dev" source: hosted - version: "17.2.4" + version: "19.4.2" flutter_local_notifications_linux: dependency: transitive description: name: flutter_local_notifications_linux - sha256: c49bd06165cad9beeb79090b18cd1eb0296f4bf4b23b84426e37dd7c027fc3af + sha256: e3c277b2daab8e36ac5a6820536668d07e83851aeeb79c446e525a70710770a5 url: "https://pub.dev" source: hosted - version: "4.0.1" + version: "6.0.0" flutter_local_notifications_platform_interface: dependency: transitive description: name: flutter_local_notifications_platform_interface - sha256: "85f8d07fe708c1bdcf45037f2c0109753b26ae077e9d9e899d55971711a4ea66" + sha256: "277d25d960c15674ce78ca97f57d0bae2ee401c844b6ac80fcd972a9c99d09fe" url: "https://pub.dev" source: hosted - version: "7.2.0" + version: "9.1.0" + flutter_local_notifications_windows: + dependency: transitive + description: + name: flutter_local_notifications_windows + sha256: "8d658f0d367c48bd420e7cf2d26655e2d1130147bca1eea917e576ca76668aaf" + url: "https://pub.dev" + source: hosted + version: "1.0.3" flutter_localizations: dependency: "direct main" description: flutter @@ -383,50 +391,50 @@ packages: dependency: "direct main" description: name: flutter_secure_storage - sha256: "9cad52d75ebc511adfae3d447d5d13da15a55a92c9410e50f67335b6d21d16ea" + sha256: f7eceb0bc6f4fd0441e29d43cab9ac2a1c5ffd7ea7b64075136b718c46954874 url: "https://pub.dev" source: hosted - version: "9.2.4" + version: "10.0.0-beta.4" + flutter_secure_storage_darwin: + dependency: transitive + description: + name: flutter_secure_storage_darwin + sha256: f226f2a572bed96bc6542198ebaec227150786e34311d455a7e2d3d06d951845 + url: "https://pub.dev" + source: hosted + version: "0.1.0" flutter_secure_storage_linux: dependency: transitive description: name: flutter_secure_storage_linux - sha256: be76c1d24a97d0b98f8b54bce6b481a380a6590df992d0098f868ad54dc8f688 + sha256: "9b4b73127e857cd3117d43a70fa3dddadb6e0b253be62e6a6ab85caa0742182c" url: "https://pub.dev" source: hosted - version: "1.2.3" - flutter_secure_storage_macos: - dependency: transitive - description: - name: flutter_secure_storage_macos - sha256: "6c0a2795a2d1de26ae202a0d78527d163f4acbb11cde4c75c670f3a0fc064247" - url: "https://pub.dev" - source: hosted - version: "3.1.3" + version: "2.0.1" flutter_secure_storage_platform_interface: dependency: transitive description: name: flutter_secure_storage_platform_interface - sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8 + sha256: "8ceea1223bee3c6ac1a22dabd8feefc550e4729b3675de4b5900f55afcb435d6" url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "2.0.1" flutter_secure_storage_web: dependency: transitive description: name: flutter_secure_storage_web - sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9 + sha256: "4c3f233e739545c6cb09286eeec1cc4744138372b985113acc904f7263bef517" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "2.0.0" flutter_secure_storage_windows: dependency: transitive description: name: flutter_secure_storage_windows - sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709 + sha256: ff32af20f70a8d0e59b2938fc92de35b54a74671041c814275afd80e27df9f21 url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "4.0.0" flutter_sms_inbox: dependency: "direct main" description: @@ -481,10 +489,10 @@ packages: dependency: "direct main" description: name: google_mobile_ads - sha256: d2ef5ec1e1f31137fc241bdeab3037c31062d387dd221fd884fb1160444c788b + sha256: a4f59019f2c32769fb6c60ed8aa321e9c21a36297e2c4f23452b3e779a3e7a26 url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "6.0.0" graphs: dependency: transitive description: @@ -617,10 +625,10 @@ packages: dependency: transitive description: name: lints - sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" + sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "6.0.0" local_auth: dependency: "direct main" description: @@ -793,18 +801,18 @@ packages: dependency: "direct main" description: name: permission_handler - sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849" + sha256: bc917da36261b00137bbc8896bf1482169cd76f866282368948f032c8c1caae1 url: "https://pub.dev" source: hosted - version: "11.4.0" + version: "12.0.1" permission_handler_android: dependency: transitive description: name: permission_handler_android - sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc + sha256: "1e3bc410ca1bf84662104b100eb126e066cb55791b7451307f9708d4007350e6" url: "https://pub.dev" source: hosted - version: "12.1.0" + version: "13.0.1" permission_handler_apple: dependency: transitive description: @@ -929,18 +937,18 @@ packages: dependency: "direct main" description: name: share_plus - sha256: "3ef39599b00059db0990ca2e30fca0a29d8b37aae924d60063f8e0184cf20900" + sha256: "3424e9d5c22fd7f7590254ba09465febd6f8827c8b19a44350de4ac31d92d3a6" url: "https://pub.dev" source: hosted - version: "7.2.2" + version: "12.0.0" share_plus_platform_interface: dependency: transitive description: name: share_plus_platform_interface - sha256: "251eb156a8b5fa9ce033747d73535bf53911071f8d3b6f4f0b578505ce0d4496" + sha256: "88023e53a13429bd65d8e85e11a9b484f49d4c190abbd96c7932b74d6927cc9a" url: "https://pub.dev" source: hosted - version: "3.4.0" + version: "6.1.0" shared_preferences: dependency: "direct main" description: @@ -1150,10 +1158,10 @@ packages: dependency: "direct main" description: name: timezone - sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d" + sha256: dd14a3b83cfd7cb19e7888f1cbc20f258b8d71b54c06f79ac585f14093a287d1 url: "https://pub.dev" source: hosted - version: "0.9.4" + version: "0.10.1" timing: dependency: transitive description: @@ -1326,18 +1334,18 @@ packages: dependency: transitive description: name: webview_flutter - sha256: ec81f57aa1611f8ebecf1d2259da4ef052281cb5ad624131c93546c79ccc7736 + sha256: c3e4fe614b1c814950ad07186007eff2f2e5dd2935eba7b9a9a1af8e5885f1ba url: "https://pub.dev" source: hosted - version: "4.9.0" + version: "4.13.0" webview_flutter_android: dependency: transitive description: name: webview_flutter_android - sha256: "47a8da40d02befda5b151a26dba71f47df471cddd91dfdb7802d0a87c5442558" + sha256: "3c4eb4fcc252b40c2b5ce7be20d0481428b70f3ff589b0a8b8aaeb64c6bed701" url: "https://pub.dev" source: hosted - version: "3.16.9" + version: "4.10.2" webview_flutter_platform_interface: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index bfb4a71..aa00680 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,40 +13,40 @@ dependencies: provider: ^6.1.1 hive: ^2.2.3 hive_flutter: ^1.1.0 - flutter_local_notifications: ^17.2.4 - flutter_secure_storage: ^9.0.0 + flutter_local_notifications: ^19.4.2 + flutter_secure_storage: ^10.0.0-beta.4 local_auth: ^2.1.6 - fl_chart: ^0.66.2 + fl_chart: ^1.1.1 http: ^1.4.0 qr_flutter: ^4.1.0 url_launcher: ^6.2.4 intl: ^0.20.2 - permission_handler: ^11.3.0 + permission_handler: ^12.0.1 uuid: ^4.2.1 - timezone: ^0.9.2 + timezone: ^0.10.1 flutter_localizations: sdk: flutter - share_plus: ^7.2.1 + share_plus: ^12.0.0 font_awesome_flutter: ^10.7.0 cached_network_image: ^3.3.1 flutter_cache_manager: ^3.3.1 shared_preferences: ^2.5.3 - flutter_launcher_icons: ^0.13.1 + flutter_launcher_icons: ^0.14.4 flutter_native_splash: ^2.3.10 flutter_sms_inbox: ^1.0.3 - flutter_dotenv: ^5.1.0 + flutter_dotenv: ^6.0.0 flutter_svg: ^2.1.0 html: ^0.15.6 octo_image: ^2.0.0 path_provider: ^2.1.5 crypto: ^3.0.6 image: ^4.5.4 - google_mobile_ads: ^4.0.0 + google_mobile_ads: ^6.0.0 dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^2.0.0 + flutter_lints: ^6.0.0 build_runner: ^2.4.6 hive_generator: ^2.0.1 diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 3bb2d90..2fd5c53 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -11,6 +11,7 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + flutter_local_notifications_windows ) set(PLUGIN_BUNDLED_LIBRARIES)