home/main: welcome card
All checks were successful
Firka/firka/pipeline/head This commit looks good

This commit is contained in:
Armand 2025-07-12 01:30:51 +02:00
parent 74c9746548
commit 4351302ca9
5 changed files with 186 additions and 10 deletions

View File

@ -23,7 +23,9 @@ extension DurationExtension on Duration {
}
}
enum FormatMode { yearly, grades }
enum FormatMode { yearly, grades, welcome }
enum Cycle { morning, day, afternoon, night }
extension DateExtension on DateTime {
String format(BuildContext context, FormatMode mode) {
@ -57,10 +59,36 @@ extension DateExtension on DateTime {
return format(context, FormatMode.yearly);
case FormatMode.yearly:
return DateFormat('MMMM dd').format(this);
default:
throw Exception("unimplemented format mode: $mode");
case FormatMode.welcome:
return DateFormat('EEE, MMM d').format(this);
}
}
DateTime getMidnight() {
return subtract(Duration(
hours: hour,
minutes: minute,
seconds: second,
milliseconds: millisecond));
}
Cycle getDayCycle() {
var midnight = getMidnight();
if (isAfter(midnight.add(Duration(hours: 7))) &&
isBefore(midnight.add(Duration(hours: 9)))) {
return Cycle.morning;
}
if (isAfter(midnight.add(Duration(hours: 7))) &&
isBefore(midnight.add(Duration(hours: 12)))) {
return Cycle.day;
}
if (isAfter(midnight.add(Duration(hours: 7))) &&
isBefore(midnight.add(Duration(hours: 20)))) {
return Cycle.afternoon;
}
return Cycle.night;
}
}
extension DateGrouper<T> on Iterable<T> {

@ -1 +1 @@
Subproject commit 47830db2237e2ab1d023482c3cf4ee41c49d2863
Subproject commit 6c4dcbda41f832e3e0f61b8430a8cf7118feed3f

View File

@ -1,9 +1,16 @@
import 'dart:async';
import 'package:firka/helpers/extensions.dart';
import 'package:firka/ui/phone/widgets/home_main_welcome.dart';
import 'package:flutter/material.dart';
import '../../../../helpers/api/model/student.dart';
import '../../../../helpers/api/model/timetable.dart';
import '../../../../main.dart';
class HomeMainScreen extends StatefulWidget {
final AppInitialization data;
const HomeMainScreen(this.data, {super.key});
@override
@ -12,10 +19,52 @@ class HomeMainScreen extends StatefulWidget {
class _HomeMainScreen extends State<HomeMainScreen> {
final AppInitialization data;
_HomeMainScreen(this.data);
DateTime now = DateTime.now();
List<Lesson>? lessons;
Student? student;
Timer? timer;
@override
void initState() {
super.initState();
now = DateTime.now();
var midnight = now.getMidnight();
(() async {
var resp = await data.client.getTimeTable(
midnight, midnight.add(Duration(hours: 23, minutes: 59)));
lessons = resp.response!;
})();
(() async {
var resp = await data.client.getStudent();
student = resp.response!;
})();
timer = Timer.periodic(Duration(seconds: 1), (timer) async {
setState(() {
now = DateTime.now();
});
});
}
@override
void dispose() {
super.dispose();
timer?.cancel();
}
@override
Widget build(BuildContext context) {
return Text("Main");
if (student != null && lessons != null) {
return HomeMainWelcome(now, student!, lessons!);
} else {
return SizedBox();
}
}
}

View File

@ -0,0 +1,99 @@
import 'package:firka/helpers/extensions.dart';
import 'package:firka/l10n/app_localizations.dart';
import 'package:firka/ui/widget/firka_icon.dart';
import 'package:flutter/material.dart';
import 'package:majesticons_flutter/majesticons_flutter.dart';
import '../../../helpers/api/model/student.dart';
import '../../../helpers/api/model/timetable.dart';
import '../../model/style.dart';
class HomeMainWelcome extends StatelessWidget {
final Student student;
final List<Lesson> lessons;
final DateTime now;
const HomeMainWelcome(this.now, this.student, this.lessons, {super.key});
getIconForCycle(Cycle dayCycle) {
switch (dayCycle) {
case Cycle.morning:
return FirkaIconWidget(FirkaIconType.MajesticonsLocal, "sunSolid",
color: appStyle.colors.accent);
case Cycle.day:
return FirkaIconWidget(
FirkaIconType.MajesticonsLocal, "parkSolidSchool",
color: appStyle.colors.accent);
case Cycle.afternoon:
return FirkaIconWidget(FirkaIconType.Majesticons, Majesticon.moonSolid,
color: appStyle.colors.accent);
case Cycle.night:
return FirkaIconWidget(FirkaIconType.Majesticons, Majesticon.moonSolid,
color: appStyle.colors.accent);
}
}
String getTitle(BuildContext context, Cycle dayCycle) {
var name = "";
try {
name = student.name.split(" ")[1];
} catch (ex) {
name = student.name;
}
if (lessons.isEmpty) {
switch (dayCycle) {
case Cycle.morning:
return AppLocalizations.of(context)!.good_morning(name);
case Cycle.day:
return AppLocalizations.of(context)!.good_day(name);
case Cycle.afternoon:
return AppLocalizations.of(context)!.good_afternoon(name);
case Cycle.night:
return AppLocalizations.of(context)!.good_night(name);
}
} else {
// TODO: impl this w/ lessons
throw UnimplementedError();
}
}
String getSubtitle(BuildContext context, Cycle dayCycle) {
if (lessons.isEmpty) {
return now.format(context, FormatMode.welcome);
} else {
// TODO: impl this w/ lessons
throw UnimplementedError();
}
}
@override
Widget build(BuildContext context) {
var dayCycle = now.getDayCycle();
return Flexible(
child: Padding(
padding: const EdgeInsets.only(
left: 16.0,
right: 16.0,
top: 24.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
getIconForCycle(dayCycle),
const SizedBox(height: 16.0),
Text(getTitle(context, dayCycle),
style: appStyle.fonts.H_H2
.copyWith(color: appStyle.colors.textPrimary)),
const SizedBox(height: 2.0),
Text(getSubtitle(context, dayCycle),
style: appStyle.fonts.B_14R
.copyWith(color: appStyle.colors.textSecondary)),
],
),
),
);
}
}

View File

@ -1,15 +1,14 @@
import 'dart:async';
import 'dart:math';
import 'package:firka/ui/widget/class_icon_widget.dart';
import 'package:flutter_arc_text/flutter_arc_text.dart';
import 'package:firka/helpers/api/model/timetable.dart';
import 'package:firka/helpers/extensions.dart';
import 'package:firka/ui/widget/class_icon_widget.dart';
import 'package:firka/wear_main.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_arc_text/flutter_arc_text.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:majesticons_flutter/majesticons_flutter.dart';
import 'package:zear_plus/wear_plus.dart';
import '../../../../l10n/app_localizations.dart';
@ -18,6 +17,7 @@ import '../../widgets/circular_progress_indicator.dart';
class WearHomeScreen extends StatefulWidget {
final WearAppInitialization data;
const WearHomeScreen(this.data, {super.key});
@override
@ -26,6 +26,7 @@ class WearHomeScreen extends StatefulWidget {
class _WearHomeScreenState extends State<WearHomeScreen> {
final WearAppInitialization data;
_WearHomeScreenState(this.data);
int? currentLessonNo;
@ -56,8 +57,7 @@ class _WearHomeScreenState extends State<WearHomeScreen> {
var kreta = data.client;
now = DateTime.now();
var todayStart = now.subtract(
Duration(hours: now.hour, minutes: now.minute, seconds: now.second));
var todayStart = now.getMidnight();
var todayEnd = todayStart.add(Duration(hours: 23, minutes: 59));
var classes = await kreta.getTimeTable(todayStart, todayEnd);