Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@
"@allowNotifications": {
"description": "Button text to allow notifications"
},
"allowAlarms": "Allow alarms",
"@allowAlarms": {
"description": "Button text to allow alarm permission"
},
"doItLater": "I'll do it later.",
"@doItLater": {
"description": "Button text to skip a step and do it later"
Expand All @@ -63,6 +67,14 @@
"@notificationPermissionDescription": {
"description": "Description explaining why notification permission is needed"
},
"pleaseAllowAlarms": "Please allow alarms",
"@pleaseAllowAlarms": {
"description": "Title asking the user to allow alarm permission"
},
"alarmPermissionDescription": "OnTime uses alarms so preparation starts at the right moment, even when the app is closed.",
"@alarmPermissionDescription": {
"description": "Description explaining why alarm permission is needed"
},
"late": " late",
"@late": {
"description": "Appended to the time when the user is late"
Expand Down Expand Up @@ -327,6 +339,14 @@
"@allowAppNotifications": {
"description": "Setting tile for allowing app notifications"
},
"manageAppNotifications": "Manage App Notifications",
"@manageAppNotifications": {
"description": "Dialog title for opening app notification settings"
},
"manageAppNotificationsDescription": "To turn app notifications on or off, update OnTime's notification permission in Settings.",
"@manageAppNotificationsDescription": {
"description": "Dialog description for opening app notification settings"
},
"privacyPolicy": "Privacy Policy",
"@privacyPolicy": {
"description": "Setting tile for opening the privacy policy"
Expand Down
5 changes: 5 additions & 0 deletions lib/l10n/app_ko.arb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
"am": "오전",
"pm": "오후",
"allowNotifications": "알림 허용하기",
"allowAlarms": "알람 허용하기",
"doItLater": "나중에 할게요.",
"pleaseAllowNotifications": "알림을 허용해주세요",
"notificationPermissionDescription": "약속 준비 리마인더를 보내\n제시간에 준비할 수 있게 도와드려요.",
"pleaseAllowAlarms": "알람을 허용해주세요",
"alarmPermissionDescription": "앱이 닫혀 있어도 약속 준비를 제시간에 시작할 수 있도록 알람을 사용해요.",
"late": " 지각했어요",
"early": " 일찍 준비했어요",
"letsGo": "까먹지 않고 출발",
Expand Down Expand Up @@ -76,6 +79,8 @@
"accountSettings": "계정 설정",
"editDefaultPreparation": "기본 준비과정 / 여유시간 수정",
"allowAppNotifications": "앱 알림 허용",
"manageAppNotifications": "앱 알림 관리",
"manageAppNotificationsDescription": "앱 알림을 켜거나 끄려면 설정에서 온타임 알림 권한을 변경해주세요.",
"privacyPolicy": "개인정보 처리방침",
"privacyPolicyOpenError": "개인정보 처리방침을 열 수 없습니다. 잠시 후 다시 시도해주세요.",
"logOut": "로그아웃",
Expand Down
30 changes: 30 additions & 0 deletions lib/l10n/app_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@ abstract class AppLocalizations {
/// **'Allow notifications'**
String get allowNotifications;

/// Button text to allow alarm permission
///
/// In en, this message translates to:
/// **'Allow alarms'**
String get allowAlarms;

/// Button text to skip a step and do it later
///
/// In en, this message translates to:
Expand All @@ -194,6 +200,18 @@ abstract class AppLocalizations {
/// **'OnTime sends schedule preparation reminders so you can get ready on time.'**
String get notificationPermissionDescription;

/// Title asking the user to allow alarm permission
///
/// In en, this message translates to:
/// **'Please allow alarms'**
String get pleaseAllowAlarms;

/// Description explaining why alarm permission is needed
///
/// In en, this message translates to:
/// **'OnTime uses alarms so preparation starts at the right moment, even when the app is closed.'**
String get alarmPermissionDescription;

/// Appended to the time when the user is late
///
/// In en, this message translates to:
Expand Down Expand Up @@ -560,6 +578,18 @@ abstract class AppLocalizations {
/// **'Allow App Notifications'**
String get allowAppNotifications;

/// Dialog title for opening app notification settings
///
/// In en, this message translates to:
/// **'Manage App Notifications'**
String get manageAppNotifications;

/// Dialog description for opening app notification settings
///
/// In en, this message translates to:
/// **'To turn app notifications on or off, update OnTime\'s notification permission in Settings.'**
String get manageAppNotificationsDescription;

/// Setting tile for opening the privacy policy
///
/// In en, this message translates to:
Expand Down
17 changes: 17 additions & 0 deletions lib/l10n/app_localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get allowNotifications => 'Allow notifications';

@override
String get allowAlarms => 'Allow alarms';

@override
String get doItLater => 'I\'ll do it later.';

Expand All @@ -59,6 +62,13 @@ class AppLocalizationsEn extends AppLocalizations {
String get notificationPermissionDescription =>
'OnTime sends schedule preparation reminders so you can get ready on time.';

@override
String get pleaseAllowAlarms => 'Please allow alarms';

@override
String get alarmPermissionDescription =>
'OnTime uses alarms so preparation starts at the right moment, even when the app is closed.';

@override
String get late => ' late';

Expand Down Expand Up @@ -270,6 +280,13 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get allowAppNotifications => 'Allow App Notifications';

@override
String get manageAppNotifications => 'Manage App Notifications';

@override
String get manageAppNotificationsDescription =>
'To turn app notifications on or off, update OnTime\'s notification permission in Settings.';

@override
String get privacyPolicy => 'Privacy Policy';

Expand Down
17 changes: 17 additions & 0 deletions lib/l10n/app_localizations_ko.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ class AppLocalizationsKo extends AppLocalizations {
@override
String get allowNotifications => '알림 허용하기';

@override
String get allowAlarms => '알람 허용하기';

@override
String get doItLater => '나중에 할게요.';

Expand All @@ -57,6 +60,13 @@ class AppLocalizationsKo extends AppLocalizations {
String get notificationPermissionDescription =>
'약속 준비 리마인더를 보내\n제시간에 준비할 수 있게 도와드려요.';

@override
String get pleaseAllowAlarms => '알람을 허용해주세요';

@override
String get alarmPermissionDescription =>
'앱이 닫혀 있어도 약속 준비를 제시간에 시작할 수 있도록 알람을 사용해요.';

@override
String get late => ' 지각했어요';

Expand Down Expand Up @@ -251,6 +261,13 @@ class AppLocalizationsKo extends AppLocalizations {
@override
String get allowAppNotifications => '앱 알림 허용';

@override
String get manageAppNotifications => '앱 알림 관리';

@override
String get manageAppNotificationsDescription =>
'앱 알림을 켜거나 끄려면 설정에서 온타임 알림 권한을 변경해주세요.';

@override
String get privacyPolicy => '개인정보 처리방침';

Expand Down
200 changes: 200 additions & 0 deletions lib/presentation/alarm_allow/screens/alarm_allow_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';
import 'package:on_time_front/domain/entities/alarm_entities.dart';
import 'package:on_time_front/l10n/app_localizations.dart';
import 'package:on_time_front/presentation/app/cubit/alarm_gate_cubit.dart';
import 'package:on_time_front/presentation/shared/constants/app_colors.dart';

class AlarmAllowScreen extends StatefulWidget {
const AlarmAllowScreen({super.key});

@override
State<AlarmAllowScreen> createState() => _AlarmAllowScreenState();
}

class _AlarmAllowScreenState extends State<AlarmAllowScreen>
with WidgetsBindingObserver {
bool _isRequesting = false;

@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state != AppLifecycleState.resumed) return;
context.read<AlarmGateCubit>().refreshPermission(
disableAlarmsWhenPermissionMissing: true,
enableAlarmsOnGrant: true,
);
}

@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}

Future<void> _requestPermission() async {
setState(() {
_isRequesting = true;
});
final permission = await context.read<AlarmGateCubit>().requestPermission();
if (!mounted) return;
setState(() {
_isRequesting = false;
});
if (permission == AlarmPermissionState.granted ||
permission == AlarmPermissionState.unsupported) {
context.go('/home');
}
}

Future<void> _dismiss() async {
await context.read<AlarmGateCubit>().dismissPrompt();
if (!mounted) return;
context.go('/home');
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.only(bottom: 72.0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
spacing: 68.50,
children: [
Expanded(
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
spacing: 40,
children: const [_Image(), _Title()],
),
),
),
_Buttons(
isRequesting: _isRequesting,
onAllow: _requestPermission,
onDismiss: _dismiss,
),
],
),
),
);
}
}

class _Buttons extends StatelessWidget {
const _Buttons({
required this.isRequesting,
required this.onAllow,
required this.onDismiss,
});

final bool isRequesting;
final Future<void> Function() onAllow;
final Future<void> Function() onDismiss;

@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
final colorScheme = Theme.of(context).colorScheme;
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
spacing: 24,
children: [
FilledButton(
onPressed: isRequesting ? null : () => onAllow(),
child: Text(
AppLocalizations.of(context)!.allowAlarms,
textAlign: TextAlign.center,
style: textTheme.titleMedium?.copyWith(
color: colorScheme.onPrimary,
),
),
),
GestureDetector(
onTap: isRequesting ? null : () => onDismiss(),
child: SizedBox(
width: 358,
child: Text(
AppLocalizations.of(context)!.doItLater,
textAlign: TextAlign.center,
style: textTheme.bodyLarge?.copyWith(
color: AppColors.grey[400],
decoration: TextDecoration.underline,
decorationColor: AppColors.grey[400],
),
),
),
),
],
);
}
}

class _Title extends StatelessWidget {
const _Title();

@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
final colorScheme = Theme.of(context).colorScheme;
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
spacing: 12,
children: [
Text(
AppLocalizations.of(context)!.pleaseAllowAlarms,
textAlign: TextAlign.center,
style: textTheme.headlineMedium?.copyWith(color: colorScheme.primary),
),
SizedBox(
width: 282,
child: Text(
AppLocalizations.of(context)!.alarmPermissionDescription,
textAlign: TextAlign.center,
style: textTheme.titleMedium?.copyWith(color: colorScheme.outline),
),
),
],
);
}
}

class _Image extends StatelessWidget {
const _Image();

@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Container(
width: 70,
height: 70,
padding: const EdgeInsets.all(17.50),
decoration: ShapeDecoration(
color: colorScheme.primaryContainer,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(35)),
),
child: SvgPicture.asset(
'bell-ringing.svg',
package: 'assets',
colorFilter: ColorFilter.mode(colorScheme.primary, BlendMode.srcIn),
),
);
}
}
Loading
Loading