Skip to content

Commit

Permalink
feat: added permission request screen
Browse files Browse the repository at this point in the history
  • Loading branch information
rohansen856 committed Jan 12, 2025
1 parent 49bb285 commit 51ff25e
Show file tree
Hide file tree
Showing 7 changed files with 276 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class OnboardingPageStartButton extends StatelessWidget {
child: ElevatedButton(
onPressed: () {
controller.markOnboardingAsCompleted();
Get.offNamed(Routes.HOME);
Get.offNamed(Routes.PERMISSION);
},
style: ElevatedButton.styleFrom(
backgroundColor: TaskWarriorColors.black,
Expand Down
12 changes: 12 additions & 0 deletions lib/app/modules/permission/bindings/permission_binding.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import 'package:get/get.dart';

import '../controllers/permission_controller.dart';

class PermissionBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut<PermissionController>(
() => PermissionController(),
);
}
}
57 changes: 57 additions & 0 deletions lib/app/modules/permission/controllers/permission_controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';

class PermissionController extends GetxController {
final RxBool isStorageGranted = false.obs;
final RxBool isNotificationGranted = false.obs;
final RxBool isLoading = false.obs;

@override
void onInit() {
super.onInit();
checkPermissions();
}

Future<void> checkPermissions() async {
try {
isStorageGranted.value = await Permission.storage.status.isGranted;
isNotificationGranted.value =
await Permission.notification.status.isGranted;
} catch (e) {
print('Error checking permissions: $e');
}
}

Future<void> requestPermissions() async {
try {
isLoading.value = true;

PermissionStatus storageStatus;
if (GetPlatform.isAndroid) {
storageStatus = await Permission.storage.request();
} else {
storageStatus = await Permission.photos.request();
}
isStorageGranted.value = storageStatus.isGranted;

final notificationStatus = await Permission.notification.request();
isNotificationGranted.value = notificationStatus.isGranted;

if (isStorageGranted.value && isNotificationGranted.value) {
Get.offNamed('/home');
}
} catch (e) {
print('Error requesting permissions: $e');
} finally {
isLoading.value = false;
}
}

void openSettings() async {
try {
await Get.offNamed('/home');
} catch (e) {
print('Error opening settings: $e');
}
}
}
197 changes: 197 additions & 0 deletions lib/app/modules/permission/views/permission_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:taskwarrior/app/utils/app_settings/app_settings.dart';
import 'package:taskwarrior/app/utils/constants/taskwarrior_colors.dart';
import '../controllers/permission_controller.dart';

class PermissionView extends GetView<PermissionController> {
const PermissionView({super.key});

@override
Widget build(BuildContext context) {
final isDarkMode = Theme.of(context).brightness == Brightness.dark;

if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
WidgetsBinding.instance.addPostFrameCallback((_) {
Get.offAllNamed('/home');
});
return const SizedBox.shrink();
}

return Scaffold(
backgroundColor: isDarkMode
? TaskWarriorColors.kprimaryBackgroundColor
: TaskWarriorColors.kLightPrimaryBackgroundColor,
body: SafeArea(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 24),
Text(
'Why We Need Your Permission',
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.bold,
color: isDarkMode
? TaskWarriorColors.kprimaryTextColor
: TaskWarriorColors.kLightPrimaryTextColor,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 32),
Icon(
Icons.security,
size: 64,
color: AppSettings.isDarkMode
? TaskWarriorColors.black
: TaskWarriorColors.white,
),
const SizedBox(height: 32),
_buildPermissionSection(
context,
icon: Icons.folder_outlined,
title: 'Storage Permission',
description:
'We use storage access to save your tasks, preferences, '
'and app data securely on your device. This ensures that you can '
'pick up where you left off seamlessly, even offline.',
isDarkMode: isDarkMode,
),
const SizedBox(height: 24),
_buildPermissionSection(
context,
icon: Icons.notifications_outlined,
title: 'Notification Permission',
description:
'Notifications keep you updated with important reminders '
'and updates, ensuring you stay on top of your tasks effortlessly.',
isDarkMode: isDarkMode,
),
const SizedBox(height: 24),
Text(
'Your privacy is our top priority. We never access or share your '
'personal files or data without your consent.',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: AppSettings.isDarkMode
? TaskWarriorColors.black
: TaskWarriorColors.white,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 48),
Obx(() => ElevatedButton(
onPressed: controller.isLoading.value
? null
: controller.requestPermissions,
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.all(16),
backgroundColor: AppSettings.isDarkMode
? TaskWarriorColors.black
: TaskWarriorColors.white,
foregroundColor: AppSettings.isDarkMode
? TaskWarriorColors.kprimaryTextColor
: TaskWarriorColors.kLightPrimaryTextColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: controller.isLoading.value
? CircularProgressIndicator(
color: AppSettings.isDarkMode
? TaskWarriorColors.black
: TaskWarriorColors.white,
)
: Text(
'Grant Permissions',
style: TextStyle(
color: AppSettings.isDarkMode
? TaskWarriorColors.kprimaryTextColor
: TaskWarriorColors.kLightPrimaryTextColor,
fontSize: 16,
),
),
)),
const SizedBox(height: 16),
TextButton(
onPressed: () => controller.openSettings(),
style: ButtonStyle(
backgroundColor:
WidgetStateProperty.all(TaskWarriorColors.grey),
),
child: Text(
'You can manage your permissions anytime later in Settings',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: AppSettings.isDarkMode
? TaskWarriorColors.black
: TaskWarriorColors.white,
),
textAlign: TextAlign.center,
),
),
const SizedBox(height: 24),
],
),
),
),
),
);
}

Widget _buildPermissionSection(
BuildContext context, {
required IconData icon,
required String title,
required String description,
required bool isDarkMode,
}) {
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
border: Border.all(
color: isDarkMode
? TaskWarriorColors.ksecondaryBackgroundColor
: TaskWarriorColors.borderColor,
),
borderRadius: BorderRadius.circular(12),
color: isDarkMode
? TaskWarriorColors.kdialogBackGroundColor
: TaskWarriorColors.kLightDialogBackGroundColor,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(icon, color: TaskWarriorColors.black),
const SizedBox(width: 12),
Expanded(
child: Text(
title,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
color: isDarkMode
? TaskWarriorColors.kprimaryTextColor
: TaskWarriorColors.kLightPrimaryTextColor,
),
),
),
],
),
const SizedBox(height: 8),
Text(
description,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: isDarkMode
? TaskWarriorColors.ksecondaryTextColor
: TaskWarriorColors.kLightSecondaryTextColor,
),
),
],
),
);
}
}
7 changes: 7 additions & 0 deletions lib/app/routes/app_pages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import '../modules/manageTaskServer/bindings/manage_task_server_binding.dart';
import '../modules/manageTaskServer/views/manage_task_server_view.dart';
import '../modules/onboarding/bindings/onboarding_binding.dart';
import '../modules/onboarding/views/onboarding_view.dart';
import '../modules/permission/bindings/permission_binding.dart';
import '../modules/permission/views/permission_view.dart';
import '../modules/profile/bindings/profile_binding.dart';
import '../modules/profile/views/profile_view.dart';
import '../modules/reports/bindings/reports_binding.dart';
Expand Down Expand Up @@ -75,5 +77,10 @@ class AppPages {
page: () => const SettingsView(),
binding: SettingsBinding(),
),
GetPage(
name: _Paths.PERMISSION,
page: () => const PermissionView(),
binding: PermissionBinding(),
),
];
}
2 changes: 2 additions & 0 deletions lib/app/routes/app_routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ abstract class Routes {
static const ABOUT = _Paths.ABOUT;
static const REPORTS = _Paths.REPORTS;
static const SETTINGS = _Paths.SETTINGS;
static const PERMISSION = _Paths.PERMISSION;
}

abstract class _Paths {
Expand All @@ -27,4 +28,5 @@ abstract class _Paths {
static const ABOUT = '/about';
static const REPORTS = '/reports';
static const SETTINGS = '/settings';
static const PERMISSION = '/permission';
}
4 changes: 0 additions & 4 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:taskwarrior/app/utils/app_settings/app_settings.dart';
import 'package:taskwarrior/app/utils/permissions/permissions_manager.dart';
import 'app/routes/app_pages.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await AppSettings.init();

await PermissionsManager.requestAllPermissions();


runApp(
GetMaterialApp(
title: "Application",
Expand Down

0 comments on commit 51ff25e

Please sign in to comment.