From 6ba105f08c766cd10f43d2523de832e6ef4f4ea0 Mon Sep 17 00:00:00 2001 From: Kima Date: Wed, 1 May 2024 22:24:19 +0200 Subject: [PATCH] finished new live card during lesson part --- refilc/lib/ui/widgets/lesson/lesson_tile.dart | 154 ++++++--- .../lib/pages/home/home_page.dart | 22 +- .../lib/pages/home/live_card/live_card.dart | 313 +++++++++++++++--- .../pages/home/live_card/live_card.i18n.dart | 3 + .../home/live_card/live_card_widget.dart | 2 + 5 files changed, 380 insertions(+), 114 deletions(-) diff --git a/refilc/lib/ui/widgets/lesson/lesson_tile.dart b/refilc/lib/ui/widgets/lesson/lesson_tile.dart index 7c3df2a..272d480 100644 --- a/refilc/lib/ui/widgets/lesson/lesson_tile.dart +++ b/refilc/lib/ui/widgets/lesson/lesson_tile.dart @@ -17,16 +17,26 @@ import 'package:provider/provider.dart'; import 'lesson_tile.i18n.dart'; class LessonTile extends StatelessWidget { - const LessonTile(this.lesson, - {super.key, - this.onTap, - this.swapDesc = false, - this.subjectPageView = false}); + const LessonTile( + this.lesson, { + super.key, + this.onTap, + this.swapDesc = false, + this.subjectPageView = false, + this.swapRoom = false, + this.currentLessonIndicator = true, + this.padding, + this.contentPadding, + }); final Lesson lesson; final bool swapDesc; final void Function()? onTap; final bool subjectPageView; + final bool swapRoom; + final bool currentLessonIndicator; + final EdgeInsetsGeometry? padding; + final EdgeInsetsGeometry? contentPadding; @override Widget build(BuildContext context) { @@ -128,7 +138,7 @@ class LessonTile extends StatelessWidget { // } return Padding( - padding: const EdgeInsets.only(bottom: 4.0, top: 7.0), + padding: padding ?? const EdgeInsets.only(bottom: 4.0, top: 7.0), child: Material( color: Colors.transparent, borderRadius: BorderRadius.circular(12.0), @@ -149,7 +159,8 @@ class LessonTile extends StatelessWidget { onTap: onTap, // onLongPress: kDebugMode ? () => log(jsonEncode(lesson.json)) : null, visualDensity: VisualDensity.compact, - contentPadding: const EdgeInsets.symmetric(horizontal: 4.0), + contentPadding: contentPadding ?? + const EdgeInsets.symmetric(horizontal: 4.0), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.0)), title: !subjectPageView @@ -222,7 +233,37 @@ class LessonTile extends StatelessWidget { // const SizedBox( // height: 10.0, // ), - if (cleanDesc != '') + if (swapRoom) + Container( + width: lesson.room.length > 20 ? 111 : null, + padding: const EdgeInsets.symmetric( + horizontal: 5.5, vertical: 3.0), + decoration: BoxDecoration( + color: fill + ? accent.withOpacity(.15) + : Theme.of(context) + .colorScheme + .secondary + .withOpacity(.15), + borderRadius: BorderRadius.circular(10.0), + ), + child: Text( + lesson.room, + overflow: TextOverflow.ellipsis, + style: TextStyle( + height: 1.1, + fontSize: 12.0, + fontWeight: FontWeight.w600, + color: fill + ? accent.withOpacity(0.9) + : Theme.of(context) + .colorScheme + .secondary + .withOpacity(.9), + ), + ), + ), + if (cleanDesc != '' && !swapRoom) Text( cleanDesc, maxLines: 1, @@ -288,33 +329,35 @@ class LessonTile extends StatelessWidget { // ), // Current lesson indicator - Transform.translate( - offset: const Offset(-22.0, -1.0), - child: Container( - decoration: BoxDecoration( - color: fillLeading - ? Theme.of(context) - .colorScheme - .secondary - .withOpacity(.3) - : const Color(0x00000000), - borderRadius: BorderRadius.circular(12.0), - boxShadow: [ - if (fillLeading) - BoxShadow( - color: Theme.of(context) + if (currentLessonIndicator) + Transform.translate( + offset: const Offset(-22.0, -1.0), + child: Container( + decoration: BoxDecoration( + color: fillLeading + ? Theme.of(context) .colorScheme .secondary - .withOpacity(.25), - blurRadius: 6.0, - ) - ], + .withOpacity(.3) + : const Color(0x00000000), + borderRadius: BorderRadius.circular(12.0), + boxShadow: [ + if (fillLeading) + BoxShadow( + color: Theme.of(context) + .colorScheme + .secondary + .withOpacity(.25), + blurRadius: 6.0, + ) + ], + ), + margin: + const EdgeInsets.symmetric(vertical: 4.0), + width: 4.0, + height: double.infinity, ), - margin: const EdgeInsets.symmetric(vertical: 4.0), - width: 4.0, - height: double.infinity, - ), - ) + ) ], ), ), @@ -342,35 +385,36 @@ class LessonTile extends StatelessWidget { // ), // ), // ), - Container( - width: lesson.room.length > 20 ? 111 : null, - padding: const EdgeInsets.symmetric( - horizontal: 6.0, vertical: 3.5), - decoration: BoxDecoration( - color: fill - ? accent.withOpacity(.15) - : Theme.of(context) - .colorScheme - .secondary - .withOpacity(.15), - borderRadius: BorderRadius.circular(10.0), - ), - child: Text( - lesson.room, - overflow: TextOverflow.ellipsis, - style: TextStyle( - height: 1.1, - fontSize: 12.5, - fontWeight: FontWeight.w600, + if (!swapRoom) + Container( + width: lesson.room.length > 20 ? 111 : null, + padding: const EdgeInsets.symmetric( + horizontal: 6.0, vertical: 3.5), + decoration: BoxDecoration( color: fill - ? accent.withOpacity(0.9) + ? accent.withOpacity(.15) : Theme.of(context) .colorScheme .secondary - .withOpacity(.9), + .withOpacity(.15), + borderRadius: BorderRadius.circular(10.0), + ), + child: Text( + lesson.room, + overflow: TextOverflow.ellipsis, + style: TextStyle( + height: 1.1, + fontSize: 12.5, + fontWeight: FontWeight.w600, + color: fill + ? accent.withOpacity(0.9) + : Theme.of(context) + .colorScheme + .secondary + .withOpacity(.9), + ), ), ), - ), if (!subjectPageView) const SizedBox( width: 10, diff --git a/refilc_mobile_ui/lib/pages/home/home_page.dart b/refilc_mobile_ui/lib/pages/home/home_page.dart index 3981d45..5f45065 100644 --- a/refilc_mobile_ui/lib/pages/home/home_page.dart +++ b/refilc_mobile_ui/lib/pages/home/home_page.dart @@ -212,6 +212,10 @@ class HomePageState extends State with TickerProviderStateMixin { // currentState = LiveCardState.empty; // } + // TODO: REMOVE IN PRODUCTION BUILD!!! + print(_liveCard.currentState); + _liveCard.currentState = LiveCardState.morning; + return Scaffold( body: Stack( children: [ @@ -321,8 +325,11 @@ class HomePageState extends State with TickerProviderStateMixin { // expandedHeight: _liveCardAnimation.value * 238.0, expandedHeight: _liveCardAnimation.value * (_liveCard.currentState == LiveCardState.morning - ? 280.0 - : 238.0), + ? 274.0 + : (_liveCard.currentState == + LiveCardState.duringLesson + ? 288.0 + : 238.0)), // Live Card flexibleSpace: FlexibleSpaceBar( @@ -330,12 +337,17 @@ class HomePageState extends State with TickerProviderStateMixin { padding: EdgeInsets.only( left: 24.0, right: 24.0, - top: (_liveCard.currentState == - LiveCardState.morning + top: ((_liveCard.currentState == + LiveCardState.morning || + _liveCard.currentState == + LiveCardState.duringLesson) ? 0.0 : 62.0) + MediaQuery.of(context).padding.top, - bottom: 52.0, + bottom: _liveCard.currentState == + LiveCardState.morning + ? 44.0 + : 52.0, ), child: Transform.scale( scale: _liveCardAnimation.value, diff --git a/refilc_mobile_ui/lib/pages/home/live_card/live_card.dart b/refilc_mobile_ui/lib/pages/home/live_card/live_card.dart index 860ed6d..2b52bbf 100644 --- a/refilc_mobile_ui/lib/pages/home/live_card/live_card.dart +++ b/refilc_mobile_ui/lib/pages/home/live_card/live_card.dart @@ -1,8 +1,17 @@ +// ignore_for_file: unnecessary_null_comparison + import 'package:animations/animations.dart'; import 'package:refilc/api/providers/user_provider.dart'; import 'package:refilc/helpers/subject.dart'; import 'package:refilc/icons/filc_icons.dart'; import 'package:refilc/models/settings.dart'; +import 'package:refilc/theme/colors/colors.dart'; +import 'package:refilc/ui/widgets/lesson/lesson_tile.dart'; +import 'package:refilc_kreta_api/models/category.dart'; +import 'package:refilc_kreta_api/models/lesson.dart'; +import 'package:refilc_kreta_api/models/subject.dart'; +import 'package:refilc_kreta_api/models/teacher.dart'; +import 'package:refilc_mobile_ui/common/progress_bar.dart'; // import 'package:refilc_kreta_api/models/category.dart'; // import 'package:refilc_kreta_api/models/lesson.dart'; // import 'package:refilc_kreta_api/models/subject.dart'; @@ -60,28 +69,31 @@ class LiveCardStateA extends State { Duration bellDelay = liveCard.delay; // test - // liveCard.currentState = LiveCardState.morning; - // liveCard.nextLesson = Lesson( - // date: DateTime.now().add(Duration( - // minutes: 30, - // )), - // subject: GradeSubject( - // category: Category(id: 'asd'), id: 'asd', name: 'Matematika'), - // lessonIndex: 'lessonIndex', - // teacher: Teacher(id: 'id', name: 'name'), - // start: DateTime.now().add(Duration( - // minutes: 30, - // )), - // end: DateTime.now().add(Duration( - // minutes: 30 + 45, - // )), - // homeworkId: 'homeworkId', - // id: 'id', - // description: 'description', - // room: 'ABC69', - // groupName: 'groupName', - // name: 'name', - // ); + // TODO: REMOVE IN PRODUCTION BUILD!!! + liveCard.currentState = LiveCardState.morning; + liveCard.nextLesson = Lesson( + date: DateTime.now().add(Duration( + minutes: 30, + )), + subject: GradeSubject( + category: Category(id: 'asd'), id: 'asd', name: 'Matematika'), + lessonIndex: '1', + teacher: Teacher(id: 'id', name: 'name'), + start: DateTime.now().subtract(Duration( + minutes: 30, + )), + end: DateTime.now().add(Duration( + minutes: 15, + )), + homeworkId: 'homeworkId', + id: 'id', + description: 'description', + room: 'ABC69', + groupName: 'groupName', + name: 'name', + ); + + // liveCard.nextLesson = liveCard.currentLesson; // final dt = DateTime(2024, 3, 22, 17, 12, 1, 1, 1); @@ -323,41 +335,234 @@ class LiveCardStateA extends State { final showMinutes = maxTime - elapsedTime > 60; + // child = LiveCardWidget( + // key: const Key('livecard.duringLesson'), + // liveCardState: liveCard.currentState, + // leading: liveCard.currentLesson!.lessonIndex + + // (RegExp(r'\d').hasMatch(liveCard.currentLesson!.lessonIndex) + // ? "." + // : ""), + // title: liveCard.currentLesson!.subject.renamedTo ?? + // liveCard.currentLesson!.subject.name.capital(), + // titleItalic: liveCard.currentLesson!.subject.isRenamed && + // settingsProvider.renamedSubjectsEnabled && + // settingsProvider.renamedSubjectsItalics, + // subtitle: liveCard.currentLesson!.room, + // icon: SubjectIcon.resolveVariant( + // subject: liveCard.currentLesson!.subject, context: context), + // description: liveCard.currentLesson!.description != "" + // ? Text(liveCard.currentLesson!.description) + // : null, + // nextSubject: liveCard.nextLesson?.subject.renamedTo ?? + // liveCard.nextLesson?.subject.name.capital(), + // nextSubjectItalic: liveCard.nextLesson?.subject.isRenamed == true && + // settingsProvider.renamedSubjectsEnabled && + // settingsProvider.renamedSubjectsItalics, + // nextRoom: liveCard.nextLesson?.room, + // progressMax: showMinutes ? maxTime / 60 : maxTime, + // progressCurrent: showMinutes ? elapsedTime / 60 : elapsedTime, + // progressAccuracy: + // showMinutes ? ProgressAccuracy.minutes : ProgressAccuracy.seconds, + // onProgressTap: () { + // showDialog( + // barrierColor: Colors.black, + // context: context, + // builder: (context) => + // HeadsUpCountdown(maxTime: maxTime, elapsedTime: elapsedTime), + // ); + // }, + // ); + // var titleItalic = liveCard.currentLesson!.subject.isRenamed && + // settingsProvider.renamedSubjectsEnabled && + // settingsProvider.renamedSubjectsItalics; + var nextSubject = liveCard.nextLesson?.subject.renamedTo ?? + liveCard.nextLesson?.subject.name.capital(); + var nextSubjectItalic = + liveCard.nextLesson?.subject.isRenamed == true && + settingsProvider.renamedSubjectsEnabled && + settingsProvider.renamedSubjectsItalics; + var progressMax = showMinutes ? maxTime / 60 : maxTime; + var progressCurrent = showMinutes ? elapsedTime / 60 : elapsedTime; + var progressAccuracy = + showMinutes ? ProgressAccuracy.minutes : ProgressAccuracy.seconds; + child = LiveCardWidget( key: const Key('livecard.duringLesson'), - leading: liveCard.currentLesson!.lessonIndex + - (RegExp(r'\d').hasMatch(liveCard.currentLesson!.lessonIndex) - ? "." - : ""), - title: liveCard.currentLesson!.subject.renamedTo ?? - liveCard.currentLesson!.subject.name.capital(), - titleItalic: liveCard.currentLesson!.subject.isRenamed && - settingsProvider.renamedSubjectsEnabled && - settingsProvider.renamedSubjectsItalics, - subtitle: liveCard.currentLesson!.room, - icon: SubjectIcon.resolveVariant( - subject: liveCard.currentLesson!.subject, context: context), - description: liveCard.currentLesson!.description != "" - ? Text(liveCard.currentLesson!.description) + children: liveCard.currentLesson != null + ? [ + SplittedPanel( + hasShadow: false, + padding: EdgeInsets.zero, + cardPadding: EdgeInsets.zero, + spacing: 8.0, + children: [ + SplittedPanel( + hasShadow: false, + isTransparent: true, + padding: EdgeInsets.zero, + cardPadding: const EdgeInsets.symmetric( + horizontal: 12.0, + vertical: 0.0, + ), + spacing: 0.0, + children: [ + LessonTile( + liveCard.currentLesson!, + swapRoom: true, + currentLessonIndicator: false, + padding: + const EdgeInsets.only(top: 8.0, bottom: 4.0), + contentPadding: EdgeInsets.zero, + ), + if (!(nextSubject == null && + progressCurrent == null && + progressMax == null)) + Row( + children: [ + const SizedBox( + width: 5.0, + ), + if (progressCurrent != null && + progressMax != null) + GestureDetector( + onTap: () { + showDialog( + barrierColor: Colors.black, + context: context, + builder: (context) => HeadsUpCountdown( + maxTime: maxTime, + elapsedTime: elapsedTime), + ); + }, + child: Container( + color: Colors.transparent, + child: Text( + "remaining ${progressAccuracy == ProgressAccuracy.minutes ? 'min' : 'sec'}" + .plural( + (progressMax - progressCurrent) + .round()), + maxLines: 1, + style: TextStyle( + fontWeight: FontWeight.w500, + color: AppColors.of(context) + .text + .withOpacity(.75), + height: 1.1, + ), + ), + ), + ) + ], + ), + if (progressCurrent != null && progressMax != null) + Padding( + padding: + const EdgeInsets.only(top: 4.0, bottom: 12.0), + child: ProgressBar( + value: progressCurrent / progressMax), + ) + ], + ), + SplittedPanel( + hasShadow: false, + isTransparent: true, + padding: EdgeInsets.zero, + cardPadding: const EdgeInsets.symmetric( + horizontal: 18.0, + vertical: 11.0, + ), + spacing: 0.0, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Icon( + liveCard.nextLesson == null + ? Icons.home_outlined + : SubjectIcon.resolveVariant( + context: context, + subject: + liveCard.nextLesson!.subject, + ), + size: 23.0, + ), + const SizedBox(width: 12.0), + Text( + (liveCard.nextLesson?.subject + .isRenamed ?? + false + ? liveCard + .nextLesson?.subject.renamedTo + : liveCard + .nextLesson?.subject.name) ?? + 'go_home'.i18n, + style: TextStyle( + fontSize: 15.0, + fontWeight: FontWeight.w600, + fontStyle: nextSubjectItalic + ? FontStyle.italic + : null, + ), + ), + ], + ), + Row( + children: liveCard.nextLesson != null + ? [ + Container( + width: (liveCard.nextLesson?.room + .length ?? + 0) > + 20 + ? 111 + : null, + padding: const EdgeInsets.symmetric( + horizontal: 5.5, vertical: 3.0), + decoration: BoxDecoration( + color: Theme.of(context) + .colorScheme + .secondary + .withOpacity(.15), + borderRadius: + BorderRadius.circular(10.0), + ), + child: Text( + liveCard.nextLesson!.room, + overflow: TextOverflow.ellipsis, + style: TextStyle( + height: 1.1, + fontSize: 12.0, + fontWeight: FontWeight.w600, + color: Theme.of(context) + .colorScheme + .secondary + .withOpacity(.9), + ), + ), + ), + const SizedBox( + width: 10, + ), + Text( + '${DateFormat('H:mm').format(liveCard.nextLesson!.start)}-${DateFormat('H:mm').format(liveCard.nextLesson!.end)}', + style: const TextStyle( + fontSize: 12.5, + fontWeight: FontWeight.w500, + ), + ), + ] + : [], + ), + ], + ), + ], + ), + ], + ), + ] : null, - nextSubject: liveCard.nextLesson?.subject.renamedTo ?? - liveCard.nextLesson?.subject.name.capital(), - nextSubjectItalic: liveCard.nextLesson?.subject.isRenamed == true && - settingsProvider.renamedSubjectsEnabled && - settingsProvider.renamedSubjectsItalics, - nextRoom: liveCard.nextLesson?.room, - progressMax: showMinutes ? maxTime / 60 : maxTime, - progressCurrent: showMinutes ? elapsedTime / 60 : elapsedTime, - progressAccuracy: - showMinutes ? ProgressAccuracy.minutes : ProgressAccuracy.seconds, - onProgressTap: () { - showDialog( - barrierColor: Colors.black, - context: context, - builder: (context) => - HeadsUpCountdown(maxTime: maxTime, elapsedTime: elapsedTime), - ); - }, ); break; case LiveCardState.duringBreak: diff --git a/refilc_mobile_ui/lib/pages/home/live_card/live_card.i18n.dart b/refilc_mobile_ui/lib/pages/home/live_card/live_card.i18n.dart index 3406f28..6677ba0 100644 --- a/refilc_mobile_ui/lib/pages/home/live_card/live_card.i18n.dart +++ b/refilc_mobile_ui/lib/pages/home/live_card/live_card.i18n.dart @@ -23,6 +23,7 @@ extension Localization on String { "s": "sec(s)", // v5 "first_lesson_soon": "Your first lesson starts soon!", + "go_home": "You've no more lessons today", }, "hu_hu": { "next": "Következő", @@ -44,6 +45,7 @@ extension Localization on String { "s": "másodperc", // v5 "first_lesson_soon": "Hamarosan kezdődik az első órád!", + "go_home": "Ma már nincs több órád", }, "de_de": { "next": "Nächste", @@ -65,6 +67,7 @@ extension Localization on String { "s": "Sekunde", // v5 "first_lesson_soon": "Ihre erste Unterrichtsstunde beginnt bald!", + "go_home": "Sie haben heute keinen Unterricht mehr", }, }; diff --git a/refilc_mobile_ui/lib/pages/home/live_card/live_card_widget.dart b/refilc_mobile_ui/lib/pages/home/live_card/live_card_widget.dart index 07f3933..306c15b 100644 --- a/refilc_mobile_ui/lib/pages/home/live_card/live_card_widget.dart +++ b/refilc_mobile_ui/lib/pages/home/live_card/live_card_widget.dart @@ -1,9 +1,11 @@ +import 'package:refilc/api/providers/live_card_provider.dart'; import 'package:refilc/models/settings.dart'; import 'package:refilc/theme/colors/colors.dart'; import 'package:refilc_mobile_ui/common/progress_bar.dart'; import 'package:flutter/material.dart'; import 'package:flutter_feather_icons/flutter_feather_icons.dart'; import 'package:provider/provider.dart'; +import 'package:refilc_mobile_ui/pages/home/live_card/live_card.dart'; import 'live_card.i18n.dart'; enum ProgressAccuracy { minutes, seconds }