diff --git a/assets/translations/en.json b/assets/translations/en.json index d59346f2..0289097b 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -161,6 +161,11 @@ "language": "Language", "korean": "Korean", "english": "English", + "get_alarm" : "Receive notifications", + "get_alarm_desc" : "Receive notifications about various topics", + "get_promotion_alarm" : "Receive promotion notifications", + "get_information_alarm" : "Receive information notifications", + "get_subject_suggestion_alarm" : "Receive subject suggestion notification", "send_error_log": "Send error log", "send_error_log_desc": "Automatically collect logs without user reporting", "send_anonymously": "Send anonymously", diff --git a/assets/translations/ko.json b/assets/translations/ko.json index 38c71343..eb55b8d1 100644 --- a/assets/translations/ko.json +++ b/assets/translations/ko.json @@ -161,6 +161,11 @@ "language": "언어", "korean": "한국어", "english": "영어", + "get_alarm" : "알림 받기", + "get_alarm_desc" : "다양한 주제에 대한 알림을 수신합니다.", + "get_promotion_alarm" : "광고성 알림 수신", + "get_information_alarm" : "정보성 알림 수신", + "get_subject_suggestion_alarm" : "과목 제안 알림 수신", "send_error_log": "오류 로그 전송", "send_error_log_desc": "사용자의 제보 없이 자동으로 오류를 수집합니다.", "send_anonymously": "익명으로 전송", diff --git a/lib/pages/settings_page.dart b/lib/pages/settings_page.dart index 2cb41ccc..67121987 100644 --- a/lib/pages/settings_page.dart +++ b/lib/pages/settings_page.dart @@ -25,127 +25,184 @@ class SettingsPage extends StatelessWidget { color: OTLColor.grayF, child: Padding( padding: const EdgeInsets.all(16.0), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "settings.language".tr(), - style: bodyBold, - ), - Dropdown( - customButton: Container( - height: 34, - padding: const EdgeInsets.symmetric(horizontal: 16), - decoration: BoxDecoration( - color: OTLColor.pinksLight, - borderRadius: BorderRadius.circular(20), - ), - child: Row( - children: [ - Icon( - Icons.language, - color: OTLColor.pinksMain, - ), - const SizedBox(width: 8), - Text( - isEn - ? "settings.english".tr() - : "settings.korean".tr(), - style: bodyBold.copyWith( - height: 1.2, color: OTLColor.pinksMain), - ) - ], - ), + child: SingleChildScrollView( + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "settings.language".tr(), + style: bodyBold, ), - items: [ - ItemData( - value: false, - text: "settings.korean".tr(), - icon: !isEn ? Icons.check : null, - ), - ItemData( - value: true, - text: "settings.english".tr(), - icon: isEn ? Icons.check : null, + Dropdown( + customButton: Container( + height: 34, + padding: const EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + color: OTLColor.pinksLight, + borderRadius: BorderRadius.circular(20), + ), + child: Row( + children: [ + Icon( + Icons.language, + color: OTLColor.pinksMain, + ), + const SizedBox(width: 8), + Text( + isEn + ? "settings.english".tr() + : "settings.korean".tr(), + style: bodyBold.copyWith( + height: 1.2, color: OTLColor.pinksMain), + ) + ], + ), ), - ], - isIconLeft: true, - offsetY: -6, - onChanged: (value) { - if (value!) { - EasyLocalization.of(context)?.setLocale(Locale('en')); - } else { - EasyLocalization.of(context)?.setLocale(Locale('ko')); - } - }, + items: [ + ItemData( + value: false, + text: "settings.korean".tr(), + icon: !isEn ? Icons.check : null, + ), + ItemData( + value: true, + text: "settings.english".tr(), + icon: isEn ? Icons.check : null, + ), + ], + isIconLeft: true, + offsetY: -6, + onChanged: (value) { + if (value!) { + EasyLocalization.of(context) + ?.setLocale(Locale('en')); + } else { + EasyLocalization.of(context) + ?.setLocale(Locale('ko')); + } + }, + ), + ], + ), + // TODO : UI 좀 예쁘게 어떻게 안되나 + 번역 추가 + _buildListTile( + title: "settings.get_alarm".tr(), + subtitle: "settings.get_alarm_desc".tr(), + trailing: CupertinoSwitch( + value: context.watch().getSendAlarm(), + onChanged: (value) => + context.read().setSendAlarm(value), ), - ], - ), - _buildListTile( - title: "settings.send_error_log".tr(), - subtitle: "settings.send_error_log_desc".tr(), - trailing: CupertinoSwitch( - value: context.watch().getSendCrashlytics(), - onChanged: (value) => - context.read().setSendCrashlytics(value), ), - ), - Visibility( - visible: context.watch().getSendCrashlytics(), - child: _buildListTile( - title: "settings.send_anonymously".tr(), - subtitle: "settings.send_anonymously_desc".tr(), + Visibility( + visible: context.watch().getSendAlarm(), + child: _buildListTile( + title: "settings.get_subject_suggestion_alarm".tr(), + trailing: CupertinoSwitch( + value: context + .watch() + .getSubjectSuggestionAlarm(), + onChanged: (value) => context + .read() + .setSubjectSuggestionAlarm(value), + ), + ), + ), + Visibility( + visible: context.watch().getSendAlarm(), + child: _buildListTile( + title: "settings.get_promotion_alarm".tr(), + trailing: CupertinoSwitch( + value: + context.watch().getPromotionAlarm(), + onChanged: (value) => context + .read() + .setPromotionAlarm(value), + ), + ), + ), + Visibility( + visible: context.watch().getSendAlarm(), + child: _buildListTile( + title: "settings.get_information_alarm".tr(), + trailing: CupertinoSwitch( + value: + context.watch().getInfomationAlarm(), + onChanged: (value) => context + .read() + .setInformationAlarm(value), + ), + ), + ), + _buildListTile( + title: "settings.send_error_log".tr(), + subtitle: "settings.send_error_log_desc".tr(), trailing: CupertinoSwitch( - value: context - .watch() - .getSendCrashlyticsAnonymously(), + value: + context.watch().getSendCrashlytics(), onChanged: (value) => context .read() - .setSendCrashlyticsAnonymously(value), + .setSendCrashlytics(value), ), ), - ), - Visibility( - visible: kDebugMode, - child: _buildListTile( - title: "settings.throw_test".tr(), - subtitle: "settings.throw_test_desc".tr(), - onTap: () => throw Exception(), + Visibility( + visible: + context.watch().getSendCrashlytics(), + child: _buildListTile( + title: "settings.send_anonymously".tr(), + subtitle: "settings.send_anonymously_desc".tr(), + trailing: CupertinoSwitch( + value: context + .watch() + .getSendCrashlyticsAnonymously(), + onChanged: (value) => context + .read() + .setSendCrashlyticsAnonymously(value), + ), + ), ), - ), - _buildListTile( - title: "settings.reset_all".tr(), - onTap: () { - OTLNavigator.pushDialog( + Visibility( + visible: kDebugMode, + child: _buildListTile( + title: "settings.throw_test".tr(), + subtitle: "settings.throw_test_desc".tr(), + onTap: () => throw Exception(), + ), + ), + _buildListTile( + title: "settings.reset_all".tr(), + onTap: () { + OTLNavigator.pushDialog( + context: context, + builder: (_) => OTLDialog( + type: OTLDialogType.resetSettings, + onTapPos: () => + context.read().clearAllValues(), + ), + ); + }, + ), + _buildListTile( + title: "settings.about".tr(), + onTap: () => OTLNavigator.pushDialog( context: context, builder: (_) => OTLDialog( - type: OTLDialogType.resetSettings, - onTapPos: () => - context.read().clearAllValues(), - ), - ); - }, - ), - _buildListTile( - title: "settings.about".tr(), - onTap: () => OTLNavigator.pushDialog( - context: context, - builder: (_) => OTLDialog( - type: OTLDialogType.about, - onTapContent: () => - launchUrl(Uri.parse("mailto:$CONTACT")), - onTapPos: () => showLicensePage( - context: context, - applicationName: "", - applicationIcon: - Image.asset("assets/images/logo.png", height: 48.0), + type: OTLDialogType.about, + onTapContent: () => + launchUrl(Uri.parse("mailto:$CONTACT")), + onTapPos: () => showLicensePage( + context: context, + applicationName: "", + applicationIcon: Image.asset("assets/images/logo.png", + height: 48.0), + ), ), ), ), - ), - ], + ], + ), ), ), ), diff --git a/lib/providers/settings_model.dart b/lib/providers/settings_model.dart index 8f1e0499..c41efe34 100644 --- a/lib/providers/settings_model.dart +++ b/lib/providers/settings_model.dart @@ -1,12 +1,22 @@ +import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:shared_preferences/shared_preferences.dart'; final _kSendCrashlytics = 'sendCrashlytics'; final _kSendCrashlyticsAnonymously = 'sendCrashlyticsAnonymously'; +final _kSendAlarm = 'sendAlarm'; +final _kSubjectSuggestionAlarm = 'subjectSuggestionAlarm'; +final _kPromotionAlarm = 'promotionAlarm'; +final _kInformationAlarm = 'infomationAlarm'; class SettingsModel extends ChangeNotifier { late bool _sendCrashlytics; late bool _sendCrashlyticsAnonymously; + late bool _sendAlarm; + late bool _subjectSuggestionAlarm; + late bool _promotionAlarm; + late bool _informationAlarm; bool getSendCrashlytics() => _sendCrashlytics; void setSendCrashlytics(bool newValue) { @@ -24,6 +34,73 @@ class SettingsModel extends ChangeNotifier { (instance) => instance.setBool(_kSendCrashlyticsAnonymously, newValue)); } + bool getSendAlarm() => _sendAlarm; + Future setSendAlarm(bool newValue) async { + _sendAlarm = newValue; + notifyListeners(); + + if (newValue == true) { + PermissionStatus status = await Permission.notification.status; + if (!status.isGranted) { + await openAppSettings(); + } + } + + SharedPreferences.getInstance() + .then((instance) => instance.setBool(_kSendAlarm, _sendAlarm)); + + setSubjectSuggestionAlarm(_sendAlarm); + setInformationAlarm(_sendAlarm); + setPromotionAlarm(_sendAlarm); + } + + bool getSubjectSuggestionAlarm() => _subjectSuggestionAlarm; + Future setSubjectSuggestionAlarm(bool newValue) async { + _subjectSuggestionAlarm = newValue; + notifyListeners(); + SharedPreferences.getInstance().then( + (instance) => instance.setBool(_kSubjectSuggestionAlarm, newValue)); + + if (newValue == true) { + await FirebaseMessaging.instance.subscribeToTopic("subject_suggestion"); + } else { + await FirebaseMessaging.instance + .unsubscribeFromTopic("subject_suggestion"); + } + } + + bool getPromotionAlarm() => _promotionAlarm; + Future setPromotionAlarm(bool newValue) async { + _promotionAlarm = newValue; + notifyListeners(); + SharedPreferences.getInstance().then( + (instance) => instance.setBool(_kSubjectSuggestionAlarm, newValue)); + + if (newValue == true) { + await FirebaseMessaging.instance.subscribeToTopic("promotion"); + } else { + await FirebaseMessaging.instance.unsubscribeFromTopic("promotion"); + } + } + + bool getInfomationAlarm() => _informationAlarm; + Future setInformationAlarm(bool newValue) async { + try { + _informationAlarm = newValue; + notifyListeners(); + SharedPreferences.getInstance() + .then((instance) => instance.setBool(_kInformationAlarm, newValue)); + + if (newValue == true) { + await FirebaseMessaging.instance.subscribeToTopic("information"); + } else { + await FirebaseMessaging.instance.unsubscribeFromTopic("information"); + } + } catch (e) { + debugPrint('$e'); + } + } + SettingsModel({bool forTest = false}) { SharedPreferences.getInstance().then((instance) { getAllValues(instance); @@ -32,6 +109,10 @@ class SettingsModel extends ChangeNotifier { if (forTest) { _sendCrashlytics = true; _sendCrashlyticsAnonymously = false; + _sendAlarm = true; + _subjectSuggestionAlarm = true; + _promotionAlarm = true; + _informationAlarm = true; } } @@ -39,6 +120,11 @@ class SettingsModel extends ChangeNotifier { _sendCrashlytics = instance.getBool(_kSendCrashlytics) ?? true; _sendCrashlyticsAnonymously = instance.getBool(_kSendCrashlyticsAnonymously) ?? false; + _sendAlarm = instance.getBool(_kSendAlarm) ?? true; + _subjectSuggestionAlarm = + instance.getBool(_kSubjectSuggestionAlarm) ?? true; + _promotionAlarm = instance.getBool(_kPromotionAlarm) ?? true; + _informationAlarm = instance.getBool(_kInformationAlarm) ?? true; notifyListeners(); }