From 7cb99a2490e7f4ad548ad4d9d96519d72a3bea7a Mon Sep 17 00:00:00 2001 From: "H. Kamran" Date: Sun, 19 Mar 2023 15:18:06 -0700 Subject: [PATCH 1/6] Remove unused sections, move tab bar --- lib/screens/home.dart | 286 +++++++++++-------------------- lib/screens/quran.dart | 319 +++++++++++++++++------------------ lib/screens/tasks.dart | 169 ++++++++++--------- lib/widgets/page_footer.dart | 35 ++-- 4 files changed, 359 insertions(+), 450 deletions(-) diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 8451cc7..6e43328 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -24,11 +24,13 @@ class _HomeScreenState extends State { HijriCalendar hijriCurrent = HijriCalendar.now(); Box tasks = Hive.box("tasks_${DateTime.now().toIso8601String().split("T")[0]}"); + Box quran = Hive.box("quran"); @override void initState() { super.initState(); initializeTasks(); + initializeHistory(); } void initializeTasks() { @@ -39,6 +41,13 @@ class _HomeScreenState extends State { } } + void initializeHistory() { + List? quranHistory = quran.get("history"); + if (quranHistory == null) { + quran.put("history", []); + } + } + @override Widget build(BuildContext context) { Iterable incompleteTasks = @@ -46,208 +55,109 @@ class _HomeScreenState extends State { return Material( color: backgroundColor, - child: CustomScrollView( - slivers: [ - SliverSafeArea( - sliver: SliverPadding( - padding: const EdgeInsets.only( - top: 25.0, - left: 20.0, - right: 20.0, - ), - sliver: SliverList( - delegate: SliverChildListDelegate( - [ - PageHeader( - header: appName, - title: - "${hijriCurrent.hDay} ${hijriCurrent.longMonthName} ${hijriCurrent.hYear}", - rightAlign: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Text( - current.day.toString(), - style: GoogleFonts.mPlus1p( - fontWeight: FontWeight.w500, - fontSize: 32, - letterSpacing: 0, - ), - ), - Text( - DateFormat.MMMM().format(current).toUpperCase(), - style: GoogleFonts.mPlus1p( - fontWeight: FontWeight.w300, - fontSize: 14, - letterSpacing: 0, - ), + child: Stack( + children: [ + CustomScrollView( + slivers: [ + SliverSafeArea( + sliver: SliverPadding( + padding: const EdgeInsets.only( + top: 25.0, + left: 20.0, + right: 20.0, + ), + sliver: SliverList( + delegate: SliverChildListDelegate( + [ + PageHeader( + header: appName, + title: + "${hijriCurrent.hDay} ${hijriCurrent.longMonthName} ${hijriCurrent.hYear}", + rightAlign: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + current.day.toString(), + style: GoogleFonts.mPlus1p( + fontWeight: FontWeight.w500, + fontSize: 32, + letterSpacing: 0, + ), + ), + Text( + DateFormat.MMMM().format(current).toUpperCase(), + style: GoogleFonts.mPlus1p( + fontWeight: FontWeight.w300, + fontSize: 14, + letterSpacing: 0, + ), + ), + ], ), - ], - ), - ), - const SizedBox( - height: 15, - ), - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SectionHeader( - title: "Times", - subtitle: "Lafayette, CA, U.S.", ), - const SizedBox(height: 15), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: const [ - StackedCard( - header: "Suhoor", - title: "5:55 AM", - ), - StackedCard( - header: "Iftar", - title: "7:25 PM", + const SizedBox( + height: 15, + ), + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SectionHeader( + title: "Tasks", + subtitle: + "${tasks.length - incompleteTasks.length}/${tasks.length} completed", + buttonText: "View All", + onClick: (() => + GoRouter.of(context).go("/tasks")), ), + const SizedBox(height: 15), + incompleteTasks.isNotEmpty + ? Wrap( + spacing: 10, + runSpacing: 10, + children: incompleteTasks + .take(4) + .map( + (task) => Statistic( + statistic: task.key, + ), + ) + .toList(), + ) + : const Text( + "You've completed all tasks! Congratulations!", + ), ], - ) - ], - ), - const SizedBox( - height: 25, - ), - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SectionHeader( - title: "Tasks", - subtitle: - "${tasks.length - incompleteTasks.length}/${tasks.length} completed", - buttonText: "View All", - onClick: (() => GoRouter.of(context).go("/tasks")), ), - const SizedBox(height: 15), - incompleteTasks.isNotEmpty - ? Wrap( - spacing: 10, - runSpacing: 10, - children: incompleteTasks - .take(4) - .map( - (task) => Statistic( - statistic: task.key, - ), - ) - .toList(), - ) - : const Text( - "You've completed all tasks! Congratulations!", - ), - ], - ), - const SizedBox( - height: 25, - ), - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SectionHeader( - title: "Qur'an", - subtitle: "Nothing read today", - buttonText: "Track", - onClick: (() => GoRouter.of(context).go("/quran")), + const SizedBox( + height: 25, ), - const SizedBox(height: 15), - Wrap( - spacing: 10, - runSpacing: 10, - children: const [ - Statistic(statistic: "2% read"), - Statistic(statistic: "126 ayahs"), - Statistic(statistic: "85% of Juz 1"), - ], - ) - ], - ), - const SizedBox( - height: 25, - ), - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SectionHeader( - title: "Prayers", - subtitle: "Keep up the good work!", - buttonText: "Track", - ), - const SizedBox(height: 15), - Wrap( - spacing: 10, - runSpacing: 10, - children: const [ - Statistic(statistic: "6 Fardh"), - Statistic(statistic: "10 Sunnah"), + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SectionHeader( + title: "Qur'an", + subtitle: + "${quran.get('history').length} entries", + buttonText: "Track", + onClick: (() => + GoRouter.of(context).go("/quran")), + ), ], - ) - ], - ), - const SizedBox( - height: 25, - ), - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: const [ - SectionHeader( - title: "Hadith of the Day", ), - SizedBox(height: 15), - Text( - "Whoever recites a letter from the Book of Allah, he will receive one good deed as ten good deeds like it. I do not say that Alif Lam Meem is one letter, but rather Alif is a letter, Lam is a letter, and Meem is a letter.\n\nTirmidhi", - style: TextStyle( - letterSpacing: 0, - ), - ) - ], - ), - const SizedBox( - height: 25, - ), - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: const [ - SectionHeader( - title: "Du'a of the Day", + const SizedBox( + height: 25, ), - SizedBox(height: 10), - Align( - alignment: Alignment.centerRight, - child: Text( - "رَّبِّ اغْفِرْ وَارْحَمْ وَأَنتَ خَيْرُ الرَّاحِمِينَ", - style: TextStyle( - fontSize: 20, - letterSpacing: 0, - ), - ), - ), - SizedBox(height: 10), - Text( - "My Lord! Forgive and have mercy, for You are the best of those who show mercy.\n\nAl-Mu'minun, 23:118", - style: TextStyle( - letterSpacing: 0, - ), - ) ], ), - const PageFooter(), - ], + ), ), ), - ), + ], ), + const PageFooter() ], ), ); diff --git a/lib/screens/quran.dart b/lib/screens/quran.dart index d5d273d..04db84f 100644 --- a/lib/screens/quran.dart +++ b/lib/screens/quran.dart @@ -74,192 +74,179 @@ class _QuranScreenState extends State { Widget build(BuildContext context) { return Material( color: backgroundColor, - child: CustomScrollView( - slivers: [ - SliverSafeArea( - sliver: SliverPadding( - padding: const EdgeInsets.only( - top: 25.0, - left: 20.0, - right: 20.0, - ), - sliver: SliverList( - delegate: SliverChildListDelegate( - [ - const PageHeader( - header: "Qur'an", - title: "Nothing read today", - ), - const SizedBox( - height: 15, - ), - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SectionHeader( - title: "Overview", + child: Stack( + children: [ + CustomScrollView( + slivers: [ + SliverSafeArea( + sliver: SliverPadding( + padding: const EdgeInsets.only( + top: 25.0, + left: 20.0, + right: 20.0, + ), + sliver: SliverList( + delegate: SliverChildListDelegate( + [ + PageHeader( + header: "Qur'an", + title: "${history.length} entries", ), - const SizedBox(height: 5), - Wrap( - runSpacing: 10, - children: const [ - WideCard(content: "2% read of Qur'an"), - WideCard(content: "166 ayahs read"), - WideCard(content: "85% of Juz 1 complete"), - WideCard(content: "29 juz left") - ], - ) - ], - ), - const SizedBox( - height: 25, - ), - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SectionHeader( - title: "Log Reading", - buttonText: "Help", - onClick: (() => setState(() => showHelp = !showHelp)), + const SizedBox( + height: 15, ), - showHelp - ? const Text( - "Enter the starting surah/ayah, then the ending surah/ayah. The ending input will be visible after the starting input is set, and the log button will be visible after the ending input is set.", - style: TextStyle(fontSize: 12), - ) - : const SizedBox(), - const SizedBox(height: 10), - Wrap( - runSpacing: 10, + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - QuranAdditionRow( - surahIndex: startingSurah, - ayah: startingAyah, - setSurah: (int index) { - setState(() { - startingSurah = index; - }); - }, - setAyah: (int ayah) { - setState(() { - startingAyah = ayah; - }); - }, + SectionHeader( + title: "Log Reading", + buttonText: "Help", + onClick: (() => + setState(() => showHelp = !showHelp)), ), - startingSurah != -1 && startingAyah != 0 - ? QuranAdditionRow( - surahIndex: endingSurah, - ayah: endingAyah, - setSurah: (int index) { - setState(() { - endingSurah = index; - }); - }, - setAyah: (int ayah) { - setState(() { - endingAyah = ayah; - }); - }, + showHelp + ? const Text( + "Enter the starting surah/ayah, then the ending surah/ayah. The ending input will be visible after the starting input is set, and the log button will be visible after the ending input is set.", + style: TextStyle(fontSize: 12), ) : const SizedBox(), - startingSurah != -1 && - startingAyah != 0 && - endingSurah != -1 && - endingAyah != 0 - ? WideCard( - content: "Log", - textAlign: TextAlign.center, - onTap: () => setState( - () { - final entry = [ - DateTime.now() - .toIso8601String() - .split("T")[0], - [ - "${startingSurah + 1}-$startingAyah", - "${endingSurah + 1}-$endingAyah" - ] - ]; - - history.add(entry); - quran.put("history", history); - - endingSurah = 0; - endingAyah = 0; - - final lastEntry = - (history.last[1] as List)[1] + const SizedBox(height: 10), + Wrap( + runSpacing: 10, + children: [ + QuranAdditionRow( + surahIndex: startingSurah, + ayah: startingAyah, + setSurah: (int index) { + setState(() { + startingSurah = index; + }); + }, + setAyah: (int ayah) { + setState(() { + startingAyah = ayah; + }); + }, + ), + startingSurah != -1 && startingAyah != 0 + ? QuranAdditionRow( + surahIndex: endingSurah, + ayah: endingAyah, + setSurah: (int index) { + setState(() { + endingSurah = index; + }); + }, + setAyah: (int ayah) { + setState(() { + endingAyah = ayah; + }); + }, + ) + : const SizedBox(), + startingSurah != -1 && + startingAyah != 0 && + endingSurah != -1 && + endingAyah != 0 + ? WideCard( + content: "Log", + textAlign: TextAlign.center, + onTap: () => setState( + () { + final entry = [ + DateTime.now() + .toIso8601String() + .split("T")[0], + [ + "${startingSurah + 1}-$startingAyah", + "${endingSurah + 1}-$endingAyah" + ] + ]; + + history.add(entry); + quran.put("history", history); + + endingSurah = 0; + endingAyah = 0; + + final lastEntry = (history.last[1] + as List)[1] .split("-") .map(int.parse) .toList(); - startingSurah = - surahs.length == lastEntry[0] + startingSurah = + surahs.length == lastEntry[0] + ? 1 + : lastEntry[0]; + startingAyah = int.parse( + surahs[lastEntry[0] - 1] + ["ayahs"] + .toString()) >= + lastEntry[1] ? 1 - : lastEntry[0]; - startingAyah = int.parse( - surahs[lastEntry[0] - 1] - ["ayahs"] - .toString()) >= - lastEntry[1] - ? 1 - : lastEntry[1] + 1; + : lastEntry[1] + 1; + }, + ), + ) + : const SizedBox(), + ], + ) + ], + ), + const SizedBox( + height: 25, + ), + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SectionHeader( + title: "History", + ), + SizedBox(height: history.isNotEmpty ? 10 : 5), + history.isNotEmpty + ? Wrap( + runSpacing: 10, + children: history.reversed.map( + (entry) { + final date = + DateTime.parse(entry[0].toString()); + final hijriDate = + HijriCalendar.fromDate(date); + + final starting = + (entry[1] as List)[0] + .split("-"); + final ending = + (entry[1] as List)[1] + .split("-"); + + return StackedCard( + header: + "${DateFormat.MMMMd().format(date)} / ${hijriDate.longMonthName} ${hijriDate.hDay}", + title: + "${surahs[int.parse(starting[0]) - 1]["name"].toString()} ${starting[1]} - ${surahs[int.parse(ending[0]) - 1]["name"].toString()} ${ending[1]}", + fullWidth: true, + ); }, - ), + ).toList(), ) - : const SizedBox(), + : const Text("Log some reading first!"), ], - ) - ], - ), - const SizedBox( - height: 25, - ), - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SectionHeader( - title: "History", ), - SizedBox(height: history.isNotEmpty ? 10 : 5), - history.isNotEmpty - ? Wrap( - runSpacing: 10, - children: history.reversed.map( - (entry) { - final date = - DateTime.parse(entry[0].toString()); - final hijriDate = - HijriCalendar.fromDate(date); - - final starting = - (entry[1] as List)[0] - .split("-"); - final ending = (entry[1] as List)[1] - .split("-"); - - return StackedCard( - header: - "${DateFormat.MMMMd().format(date)} / ${hijriDate.longMonthName} ${hijriDate.hDay}", - title: - "${surahs[int.parse(starting[0]) - 1]["name"].toString()} ${starting[1]} - ${surahs[int.parse(ending[0]) - 1]["name"].toString()} ${ending[1]}", - fullWidth: true, - ); - }, - ).toList(), - ) - : const Text("Log some reading first!"), + const SizedBox( + height: 25, + ), ], ), - const PageFooter(), - ], + ), ), ), - ), + ], ), + const PageFooter() ], ), ); diff --git a/lib/screens/tasks.dart b/lib/screens/tasks.dart index 747f3ad..4df568c 100644 --- a/lib/screens/tasks.dart +++ b/lib/screens/tasks.dart @@ -44,93 +44,102 @@ class _TasksScreenState extends State { Widget build(BuildContext context) { return Material( color: backgroundColor, - child: CustomScrollView( - slivers: [ - SliverSafeArea( - sliver: SliverPadding( - padding: const EdgeInsets.only( - top: 25.0, - left: 20.0, - right: 20.0, - ), - sliver: SliverList( - delegate: SliverChildListDelegate( - [ - PageHeader( - header: "Tasks", - title: "${complete.length}/${allTasks.length} completed", - hintText: "Tap an item to mark it as complete/incomplete", - ), - const SizedBox( - height: 15, - ), - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SectionHeader( - title: "Incomplete", + child: Stack( + children: [ + CustomScrollView( + slivers: [ + SliverSafeArea( + sliver: SliverPadding( + padding: const EdgeInsets.only( + top: 25.0, + left: 20.0, + right: 20.0, + ), + sliver: SliverList( + delegate: SliverChildListDelegate( + [ + PageHeader( + header: "Tasks", + title: + "${complete.length}/${allTasks.length} completed", + hintText: + "Tap an item to mark it as complete/incomplete", ), - SizedBox(height: incomplete.isNotEmpty ? 10 : 5), - incomplete.isNotEmpty - ? Wrap( - runSpacing: 10, - children: incomplete - .map( - (task) => WideCard( - content: task, - onTap: () => setState(() { - incomplete.remove(task); - complete.add(task); - tasks.put(task, true); - }), - ), - ) - .toList(), - ) - : const Text( - "You've completed all tasks! Congratulations!", - ) - ], - ), - const SizedBox( - height: 25, - ), - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SectionHeader( - title: "Complete", + const SizedBox( + height: 15, + ), + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SectionHeader( + title: "Incomplete", + ), + SizedBox(height: incomplete.isNotEmpty ? 10 : 5), + incomplete.isNotEmpty + ? Wrap( + runSpacing: 10, + children: incomplete + .map( + (task) => WideCard( + content: task, + onTap: () => setState(() { + incomplete.remove(task); + complete.add(task); + tasks.put(task, true); + }), + ), + ) + .toList(), + ) + : const Text( + "You've completed all tasks! Congratulations!", + ) + ], + ), + const SizedBox( + height: 25, + ), + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SectionHeader( + title: "Complete", + ), + SizedBox(height: complete.isNotEmpty ? 10 : 5), + complete.isNotEmpty + ? Wrap( + runSpacing: 10, + children: complete + .map( + (task) => WideCard( + content: task, + onTap: () => setState(() { + complete.remove(task); + incomplete.add(task); + tasks.put(task, false); + }), + ), + ) + .toList(), + ) + : const Text( + "No completed tasks yet. Complete tasks by tapping the card.", + ) + ], + ), + const SizedBox( + height: 25, ), - SizedBox(height: complete.isNotEmpty ? 10 : 5), - complete.isNotEmpty - ? Wrap( - runSpacing: 10, - children: complete - .map( - (task) => WideCard( - content: task, - onTap: () => setState(() { - complete.remove(task); - incomplete.add(task); - tasks.put(task, false); - }), - ), - ) - .toList(), - ) - : const Text( - "No completed tasks yet. Complete tasks by tapping the card.", - ) ], ), - const PageFooter(), - ], + ), ), ), - ), + ], ), + const PageFooter() ], ), ); diff --git a/lib/widgets/page_footer.dart b/lib/widgets/page_footer.dart index 4191e70..28b7267 100644 --- a/lib/widgets/page_footer.dart +++ b/lib/widgets/page_footer.dart @@ -15,24 +15,27 @@ class PageFooter extends StatelessWidget { ["/", LucideIcons.home], ["/tasks", LucideIcons.clipboardList], ["/quran", LucideIcons.bookOpen], - ["/prayers", LucideIcons.construction], - ["/settings", LucideIcons.cog], ]; - return Padding( - padding: const EdgeInsets.all(25), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: tabBar - .map( - (List item) => TabBarItem( - location: item[0], - icon: item[1], - active: currentLocation == item[0], - ), - ) - .toList(), + return Center( + child: Align( + alignment: Alignment.bottomCenter, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 25, horizontal: 50), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: tabBar + .map( + (List item) => TabBarItem( + location: item[0], + icon: item[1], + active: currentLocation == item[0], + ), + ) + .toList(), + ), + ), ), ); } From 1e4991abba294465c5aa076edbfbd7c980269d66 Mon Sep 17 00:00:00 2001 From: "H. Kamran" Date: Sun, 19 Mar 2023 16:30:34 -0700 Subject: [PATCH 2/6] Update app --- android/app/build.gradle | 5 +- android/app/src/debug/AndroidManifest.xml | 2 +- android/app/src/main/AndroidManifest.xml | 11 +- .../ramadantaskminder}/MainActivity.kt | 2 +- android/app/src/profile/AndroidManifest.xml | 2 +- assets/background.png | Bin 0 -> 12375 bytes assets/foreground.png | Bin 0 -> 89969 bytes assets/foreground.svg | 19 +++ assets/icon.png | Bin 0 -> 112592 bytes ios/Podfile.lock | 6 + ios/Runner/Info.plist | 4 + lib/constants.dart | 11 +- lib/main.dart | 39 ++++- lib/screens/home.dart | 18 ++- lib/screens/quran.dart | 24 +-- lib/screens/tasks.dart | 4 +- lib/theme.dart | 40 +++++ lib/widgets/quran_addition_row.dart | 6 +- lib/widgets/section_header.dart | 6 +- lib/widgets/stacked_card.dart | 4 +- lib/widgets/statistic_card.dart | 4 +- lib/widgets/tab_bar_item.dart | 4 +- lib/widgets/wide_card.dart | 6 +- pubspec.lock | 140 ++++++++++++++++++ pubspec.yaml | 109 +++++++------- 25 files changed, 362 insertions(+), 104 deletions(-) rename android/app/src/main/kotlin/com/{example/muslim_taskminder => thirteenthwillow/ramadantaskminder}/MainActivity.kt (67%) create mode 100644 assets/background.png create mode 100644 assets/foreground.png create mode 100644 assets/foreground.svg create mode 100644 assets/icon.png create mode 100644 lib/theme.dart diff --git a/android/app/build.gradle b/android/app/build.gradle index 5d4d0de..bcd2c83 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -26,7 +26,8 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion flutter.compileSdkVersion + compileSdkVersion 33 + // compileSdkVersion flutter.compileSdkVersion ndkVersion flutter.ndkVersion compileOptions { @@ -43,7 +44,7 @@ android { } defaultConfig { - applicationId "com.13willow.ramadantaskminder" + applicationId "com.thirteenthwillow.ramadantaskminder" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. minSdkVersion flutter.minSdkVersion diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index 87d2698..8370fef 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.thirteenthwillow.ramadantaskminder">