-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #37 from opxdelwin/dev
merge for version 1.1.0+6
- Loading branch information
Showing
12 changed files
with
494 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
client-app/lib/controllers/app_preferences_controller.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import 'package:get/get.dart'; | ||
import 'package:shared_preferences/shared_preferences.dart'; | ||
|
||
class AppPreferencesController extends GetxController { | ||
late SharedPreferences perfs; | ||
|
||
@override | ||
Future<void> onInit() async { | ||
perfs = await SharedPreferences.getInstance(); | ||
super.onInit(); | ||
} | ||
|
||
String? getPrimarySectionPreference() => perfs.getString('primary-section'); | ||
|
||
Future<bool> savePrimarySectionPreference(String data) async => | ||
await perfs.setString('primary-section', data); | ||
|
||
String? getPrimarySemesterPreference() => perfs.getString('primary-semester'); | ||
|
||
Future<bool> savePrimarySemesterPreference(String data) async => | ||
await perfs.setString('primary-semester', data); | ||
|
||
String? getPrimaryYearPreference() => perfs.getString('primary-year'); | ||
|
||
Future<bool> savePrimaryYearPreference(String data) async => | ||
await perfs.setString('primary-year', data); | ||
|
||
// In app tutorial | ||
/// Returns `true` if tutorial has already been completed. | ||
bool? getTutorialStatus() => perfs.getBool('app-tutorial-status'); | ||
|
||
/// Save tutorial status as `true` if completed. | ||
Future<bool> saveTutorialStatus(bool status) async => | ||
await perfs.setBool('app-tutorial-status', status); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import 'dart:ui'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:get/get.dart'; | ||
import 'package:plan_sync/controllers/app_preferences_controller.dart'; | ||
import 'package:plan_sync/util/logger.dart'; | ||
import 'package:plan_sync/widgets/bottom-sheets/bottom_sheets_wrapper.dart'; | ||
import 'package:plan_sync/widgets/tutorials/app_target_focus.dart'; | ||
import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; | ||
|
||
class AppTourController extends GetxController { | ||
late AppPreferencesController appPreferencesController; | ||
|
||
late GlobalKey _schedulePreferencesButtonKey; | ||
GlobalKey get schedulePreferencesButtonKey => _schedulePreferencesButtonKey; | ||
|
||
late GlobalKey _sectionBarKey; | ||
GlobalKey get sectionBarKey => _sectionBarKey; | ||
|
||
late GlobalKey _savePreferenceSwitchKey; | ||
GlobalKey get savePreferenceSwitchKey => _savePreferenceSwitchKey; | ||
|
||
@override | ||
void onInit() { | ||
appPreferencesController = Get.find(); | ||
super.onInit(); | ||
_schedulePreferencesButtonKey = GlobalKey(); | ||
_sectionBarKey = GlobalKey(); | ||
_savePreferenceSwitchKey = GlobalKey(); | ||
} | ||
|
||
Future<void> startAppTour(BuildContext context) async { | ||
final colorScheme = Theme.of(context).colorScheme; | ||
|
||
if (await tourAlreadyCompleted()) { | ||
return; | ||
} else if (!context.mounted) { | ||
return; | ||
} | ||
|
||
List<TargetFocus> targets = getTutorialTargets(context); | ||
|
||
TutorialCoachMark tutorial = TutorialCoachMark( | ||
targets: targets, | ||
colorShadow: colorScheme.onBackground, | ||
textSkip: "SKIP", | ||
textStyleSkip: TextStyle(color: colorScheme.background), | ||
paddingFocus: 0, | ||
focusAnimationDuration: const Duration(milliseconds: 500), | ||
unFocusAnimationDuration: const Duration(milliseconds: 500), | ||
pulseAnimationDuration: const Duration(milliseconds: 750), | ||
showSkipInLastTarget: true, | ||
imageFilter: ImageFilter.blur(sigmaX: 4, sigmaY: 4), | ||
initialFocus: 0, | ||
useSafeArea: true, | ||
onFinish: onTourComplete, | ||
onSkip: () { | ||
onTourComplete(); | ||
return true; | ||
}, | ||
onClickTargetWithTapPosition: onClickHandler, | ||
); | ||
|
||
if (!context.mounted) { | ||
return; | ||
} | ||
|
||
tutorial.show(context: context, rootOverlay: true); | ||
} | ||
|
||
Future<void> onClickHandler( | ||
TargetFocus target, TapDownDetails tapDownDetails) async { | ||
if (target.identify == schedulePreferencesButtonKey.hashCode) { | ||
Logger.i('key match with schedule button'); | ||
|
||
await Future.delayed(const Duration(milliseconds: 250)); | ||
BottomSheets.changeSectionPreference( | ||
context: schedulePreferencesButtonKey.currentContext!, | ||
); | ||
} | ||
return; | ||
} | ||
|
||
Future<bool> tourAlreadyCompleted() async { | ||
return appPreferencesController.getTutorialStatus() ?? false; | ||
} | ||
|
||
List<TargetFocus> getTutorialTargets(BuildContext context) { | ||
List<TargetFocus> targets = []; | ||
final colorScheme = Theme.of(context).colorScheme; | ||
|
||
targets.add( | ||
AppTargetFocus.schedulePreferencesButton( | ||
colorScheme: colorScheme, | ||
buttonKey: schedulePreferencesButtonKey, | ||
), | ||
); | ||
targets.add( | ||
AppTargetFocus.savePreferenceSwitch( | ||
colorScheme: colorScheme, | ||
buttonKey: savePreferenceSwitchKey, | ||
), | ||
); | ||
targets.add( | ||
AppTargetFocus.sectionBarButton( | ||
colorScheme: colorScheme, | ||
buttonKey: sectionBarKey, | ||
), | ||
); | ||
|
||
return targets; | ||
} | ||
|
||
Future<void> onTourComplete() async { | ||
final res = await appPreferencesController.saveTutorialStatus(true); | ||
if (res != true) { | ||
final err = { | ||
'origin': 'AppTourController.onTourComplete', | ||
'message': 'error saving to shared preferences' | ||
}; | ||
return Future.error(err); | ||
} | ||
return; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.