Merge branch 'dev' of github.com:refilc/naplo into dev
This commit is contained in:
41
filcnaplo_mobile_ui/lib/common/beta_chip.dart
Normal file
41
filcnaplo_mobile_ui/lib/common/beta_chip.dart
Normal file
@@ -0,0 +1,41 @@
|
||||
import 'package:filcnaplo/theme/colors/colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class BetaChip extends StatelessWidget {
|
||||
const BetaChip({Key? key, this.disabled = false}) : super(key: key);
|
||||
|
||||
final bool disabled;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 25,
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 8, right: 8),
|
||||
child: Center(
|
||||
child: Text(
|
||||
"BETA",
|
||||
softWrap: true,
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
color: disabled
|
||||
? AppColors.of(context).text.withOpacity(.5)
|
||||
: Colors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: !disabled
|
||||
? Theme.of(context).colorScheme.secondary
|
||||
: AppColors.of(context).text.withOpacity(.25),
|
||||
borderRadius: BorderRadius.circular(40),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,9 @@ import 'package:provider/provider.dart';
|
||||
import 'absence_tile.i18n.dart';
|
||||
|
||||
class AbsenceTile extends StatelessWidget {
|
||||
const AbsenceTile(this.absence, {Key? key, this.onTap, this.elevation = 0.0, this.padding}) : super(key: key);
|
||||
const AbsenceTile(this.absence,
|
||||
{Key? key, this.onTap, this.elevation = 0.0, this.padding})
|
||||
: super(key: key);
|
||||
|
||||
final Absence absence;
|
||||
final void Function()? onTap;
|
||||
@@ -37,39 +39,61 @@ class AbsenceTile extends StatelessWidget {
|
||||
child: Material(
|
||||
type: MaterialType.transparency,
|
||||
child: Padding(
|
||||
padding: padding ?? (group ? EdgeInsets.zero : const EdgeInsets.symmetric(horizontal: 8.0)),
|
||||
padding: padding ??
|
||||
(group
|
||||
? EdgeInsets.zero
|
||||
: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
)),
|
||||
child: ListTile(
|
||||
onTap: onTap,
|
||||
visualDensity: VisualDensity.compact,
|
||||
dense: group,
|
||||
contentPadding: const EdgeInsets.only(left: 8.0, right: 12.0),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(!group ? 14.0 : 12.0)),
|
||||
contentPadding: const EdgeInsets.only(
|
||||
left: 14.0, right: 12.0, top: 2.0, bottom: 2.0),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(!group ? 14.0 : 12.0)),
|
||||
leading: Container(
|
||||
width: 44.0,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: !group ? color.withOpacity(.25) : null,
|
||||
),
|
||||
child: Center(child: Icon(justificationIcon(absence.state), color: color)),
|
||||
child: Center(
|
||||
child: Icon(justificationIcon(absence.state), color: color)),
|
||||
),
|
||||
title: !group
|
||||
? Text.rich(TextSpan(
|
||||
text: "${absence.delay == 0 ? "" : absence.delay}",
|
||||
style: const TextStyle(fontWeight: FontWeight.w700, fontSize: 15.5),
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w700, fontSize: 15.5),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: absence.delay == 0
|
||||
? justificationName(absence.state).fill(["absence".i18n]).capital()
|
||||
: 'minute'.plural(absence.delay) + justificationName(absence.state).fill(["delay".i18n]),
|
||||
? justificationName(absence.state)
|
||||
.fill(["absence".i18n]).capital()
|
||||
: 'minute'.plural(absence.delay) +
|
||||
justificationName(absence.state)
|
||||
.fill(["delay".i18n]),
|
||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
||||
),
|
||||
],
|
||||
))
|
||||
: Text(
|
||||
(absence.lessonIndex != null ? "${absence.lessonIndex}. " : "") + (absence.subject.renamedTo ?? absence.subject.name.capital()),
|
||||
(absence.lessonIndex != null
|
||||
? "${absence.lessonIndex}. "
|
||||
: "") +
|
||||
(absence.subject.renamedTo ??
|
||||
absence.subject.name.capital()),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 14.0, fontStyle: absence.subject.isRenamed && settingsProvider.renamedSubjectsItalics ? FontStyle.italic : null),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14.0,
|
||||
fontStyle: absence.subject.isRenamed &&
|
||||
settingsProvider.renamedSubjectsItalics
|
||||
? FontStyle.italic
|
||||
: null),
|
||||
),
|
||||
subtitle: !group
|
||||
? Text(
|
||||
@@ -77,7 +101,12 @@ class AbsenceTile extends StatelessWidget {
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
// DateFormat("MM. dd. (EEEEE)", I18n.of(context).locale.toString()).format(absence.date),
|
||||
style: TextStyle(fontWeight: FontWeight.w500, fontStyle: absence.subject.isRenamed && settingsProvider.renamedSubjectsItalics ? FontStyle.italic : null),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontStyle: absence.subject.isRenamed &&
|
||||
settingsProvider.renamedSubjectsItalics
|
||||
? FontStyle.italic
|
||||
: null),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
@@ -97,7 +126,8 @@ class AbsenceTile extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
static Color justificationColor(Justification state, {required BuildContext context}) {
|
||||
static Color justificationColor(Justification state,
|
||||
{required BuildContext context}) {
|
||||
switch (state) {
|
||||
case Justification.excused:
|
||||
return AppColors.of(context).green;
|
||||
|
||||
@@ -17,19 +17,23 @@ import 'package:provider/provider.dart';
|
||||
import 'absence_view.i18n.dart';
|
||||
|
||||
class AbsenceView extends StatelessWidget {
|
||||
const AbsenceView(this.absence, {Key? key, this.outsideContext, this.viewable = false}) : super(key: key);
|
||||
const AbsenceView(this.absence,
|
||||
{Key? key, this.outsideContext, this.viewable = false})
|
||||
: super(key: key);
|
||||
|
||||
final Absence absence;
|
||||
final BuildContext? outsideContext;
|
||||
final bool viewable;
|
||||
|
||||
static show(Absence absence, {required BuildContext context}) {
|
||||
showBottomCard(context: context, child: AbsenceView(absence, outsideContext: context));
|
||||
showBottomCard(
|
||||
context: context, child: AbsenceView(absence, outsideContext: context));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Color color = AbsenceTile.justificationColor(absence.state, context: context);
|
||||
Color color =
|
||||
AbsenceTile.justificationColor(absence.state, context: context);
|
||||
SettingsProvider settingsProvider = Provider.of<SettingsProvider>(context);
|
||||
|
||||
return Padding(
|
||||
@@ -41,7 +45,8 @@ class AbsenceView extends StatelessWidget {
|
||||
ListTile(
|
||||
visualDensity: VisualDensity.compact,
|
||||
contentPadding: const EdgeInsets.only(left: 16.0, right: 12.0),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0)),
|
||||
leading: Container(
|
||||
width: 44.0,
|
||||
height: 44.0,
|
||||
@@ -60,10 +65,18 @@ class AbsenceView extends StatelessWidget {
|
||||
absence.subject.renamedTo ?? absence.subject.name.capital(),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(fontWeight: FontWeight.w700, fontStyle: absence.subject.isRenamed && settingsProvider.renamedSubjectsItalics ? FontStyle.italic : null),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
fontStyle: absence.subject.isRenamed &&
|
||||
settingsProvider.renamedSubjectsItalics
|
||||
? FontStyle.italic
|
||||
: null),
|
||||
),
|
||||
subtitle: Text(
|
||||
absence.teacher,
|
||||
(absence.teacher.isRenamed
|
||||
? absence.teacher.renamedTo
|
||||
: absence.teacher.name) ??
|
||||
'',
|
||||
// DateFormat("MM. dd. (EEEEE)", I18n.of(context).locale.toString()).format(absence.date),
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
),
|
||||
@@ -77,12 +90,15 @@ class AbsenceView extends StatelessWidget {
|
||||
if (absence.delay > 0)
|
||||
Detail(
|
||||
title: "delay".i18n,
|
||||
description: absence.delay.toString() + " " + "minutes".i18n.plural(absence.delay),
|
||||
description: absence.delay.toString() +
|
||||
" " +
|
||||
"minutes".i18n.plural(absence.delay),
|
||||
),
|
||||
if (absence.lessonIndex != null)
|
||||
Detail(
|
||||
title: "Lesson".i18n,
|
||||
description: "${absence.lessonIndex}. (${absence.lessonStart.format(context, timeOnly: true)}"
|
||||
description:
|
||||
"${absence.lessonIndex}. (${absence.lessonStart.format(context, timeOnly: true)}"
|
||||
" - "
|
||||
"${absence.lessonEnd.format(context, timeOnly: true)})",
|
||||
),
|
||||
@@ -91,13 +107,19 @@ class AbsenceView extends StatelessWidget {
|
||||
title: "Excuse".i18n,
|
||||
description: absence.justification?.description ?? "",
|
||||
),
|
||||
if (absence.mode != null) Detail(title: "Mode".i18n, description: absence.mode?.description ?? ""),
|
||||
Detail(title: "Submit date".i18n, description: absence.submitDate.format(context)),
|
||||
if (absence.mode != null)
|
||||
Detail(
|
||||
title: "Mode".i18n,
|
||||
description: absence.mode?.description ?? ""),
|
||||
Detail(
|
||||
title: "Submit date".i18n,
|
||||
description: absence.submitDate.format(context)),
|
||||
|
||||
// Show in timetable
|
||||
if (!viewable)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 16.0, right: 16.0, bottom: 6.0, top: 12.0),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 16.0, right: 16.0, bottom: 6.0, top: 12.0),
|
||||
child: PanelActionButton(
|
||||
leading: const Icon(FeatherIcons.calendar),
|
||||
title: Text(
|
||||
@@ -109,12 +131,15 @@ class AbsenceView extends StatelessWidget {
|
||||
Navigator.of(context).pop();
|
||||
|
||||
if (outsideContext != null) {
|
||||
ReverseSearch.getLessonByAbsence(absence, context).then((lesson) {
|
||||
ReverseSearch.getLessonByAbsence(absence, context)
|
||||
.then((lesson) {
|
||||
if (lesson != null) {
|
||||
TimetablePage.jump(outsideContext!, lesson: lesson);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar(
|
||||
content: Text("Cannot find lesson".i18n, style: const TextStyle(color: Colors.white)),
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(CustomSnackBar(
|
||||
content: Text("Cannot find lesson".i18n,
|
||||
style: const TextStyle(color: Colors.white)),
|
||||
backgroundColor: AppColors.of(context).red,
|
||||
context: context,
|
||||
));
|
||||
|
||||
@@ -5,6 +5,8 @@ import 'package:filcnaplo_mobile_ui/common/widgets/absence_group/absence_group_c
|
||||
import 'package:filcnaplo_mobile_ui/common/widgets/absence/absence_tile.dart';
|
||||
import 'package:filcnaplo/utils/format.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:rounded_expansion_tile/rounded_expansion_tile.dart';
|
||||
import 'absence_group_tile.i18n.dart';
|
||||
import 'package:rounded_expansion_tile/rounded_expansion_tile.dart';
|
||||
|
||||
@@ -31,13 +33,17 @@ class AbsenceGroupTile extends StatelessWidget {
|
||||
child: Material(
|
||||
type: MaterialType.transparency,
|
||||
child: Padding(
|
||||
padding: padding ?? const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
padding: padding ??
|
||||
const EdgeInsets.symmetric(horizontal: 0.0, vertical: 0.0),
|
||||
child: AbsenceGroupContainer(
|
||||
child: RoundedExpansionTile(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10)),
|
||||
tilePadding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
backgroundColor: Colors.transparent,
|
||||
childrenPadding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
tileColor: Colors.transparent,
|
||||
duration: const Duration(milliseconds: 250),
|
||||
trailingDuration: 0.5,
|
||||
trailing: const Icon(FeatherIcons.chevronDown),
|
||||
leading: Container(
|
||||
width: 44.0,
|
||||
height: 44.0,
|
||||
|
||||
@@ -12,7 +12,8 @@ class ExamView extends StatelessWidget {
|
||||
|
||||
final Exam exam;
|
||||
|
||||
static show(Exam exam, {required BuildContext context}) => showBottomCard(context: context, child: ExamView(exam));
|
||||
static show(Exam exam, {required BuildContext context}) =>
|
||||
showBottomCard(context: context, child: ExamView(exam));
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -27,7 +28,8 @@ class ExamView extends StatelessWidget {
|
||||
leading: Padding(
|
||||
padding: const EdgeInsets.only(left: 6.0),
|
||||
child: Icon(
|
||||
SubjectIcon.resolveVariant(subjectName: exam.subjectName, context: context),
|
||||
SubjectIcon.resolveVariant(
|
||||
subjectName: exam.subjectName, context: context),
|
||||
size: 36.0,
|
||||
color: AppColors.of(context).text.withOpacity(.75),
|
||||
),
|
||||
@@ -39,7 +41,10 @@ class ExamView extends StatelessWidget {
|
||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
||||
),
|
||||
subtitle: Text(
|
||||
exam.teacher,
|
||||
(exam.teacher.isRenamed
|
||||
? exam.teacher.renamedTo
|
||||
: exam.teacher.name) ??
|
||||
'',
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
@@ -51,9 +56,14 @@ class ExamView extends StatelessWidget {
|
||||
),
|
||||
|
||||
// Details
|
||||
if (exam.writeDate.year != 0) Detail(title: "date".i18n, description: exam.writeDate.format(context)),
|
||||
if (exam.description != "") Detail(title: "description".i18n, description: exam.description),
|
||||
if (exam.mode != null) Detail(title: "mode".i18n, description: exam.mode!.description),
|
||||
if (exam.writeDate.year != 0)
|
||||
Detail(
|
||||
title: "date".i18n,
|
||||
description: exam.writeDate.format(context)),
|
||||
if (exam.description != "")
|
||||
Detail(title: "description".i18n, description: exam.description),
|
||||
if (exam.mode != null)
|
||||
Detail(title: "mode".i18n, description: exam.mode!.description),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -11,7 +11,8 @@ import 'grade_view.i18n.dart';
|
||||
class GradeView extends StatelessWidget {
|
||||
const GradeView(this.grade, {Key? key}) : super(key: key);
|
||||
|
||||
static show(Grade grade, {required BuildContext context}) => showBottomCard(context: context, child: GradeView(grade));
|
||||
static show(Grade grade, {required BuildContext context}) =>
|
||||
showBottomCard(context: context, child: GradeView(grade));
|
||||
|
||||
final Grade grade;
|
||||
|
||||
@@ -30,10 +31,21 @@ class GradeView extends StatelessWidget {
|
||||
grade.subject.renamedTo ?? grade.subject.name.capital(),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(fontWeight: FontWeight.w600, fontStyle: grade.subject.isRenamed && settingsProvider.renamedSubjectsItalics ? FontStyle.italic : null),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontStyle: grade.subject.isRenamed &&
|
||||
settingsProvider.renamedSubjectsItalics
|
||||
? FontStyle.italic
|
||||
: null),
|
||||
),
|
||||
subtitle: Text(
|
||||
!Provider.of<SettingsProvider>(context, listen: false).presentationMode ? grade.teacher : "Tanár",
|
||||
!Provider.of<SettingsProvider>(context, listen: false)
|
||||
.presentationMode
|
||||
? (grade.teacher.isRenamed
|
||||
? grade.teacher.renamedTo
|
||||
: grade.teacher.name) ??
|
||||
''
|
||||
: "Tanár",
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
@@ -49,13 +61,20 @@ class GradeView extends StatelessWidget {
|
||||
title: "value".i18n,
|
||||
description: "${grade.value.valueName} " + percentText(),
|
||||
),
|
||||
if (grade.description != "") Detail(title: "description".i18n, description: grade.description),
|
||||
if (grade.mode.description != "") Detail(title: "mode".i18n, description: grade.mode.description),
|
||||
if (grade.writeDate.year != 0) Detail(title: "date".i18n, description: grade.writeDate.format(context)),
|
||||
if (grade.description != "")
|
||||
Detail(title: "description".i18n, description: grade.description),
|
||||
if (grade.mode.description != "")
|
||||
Detail(title: "mode".i18n, description: grade.mode.description),
|
||||
if (grade.writeDate.year != 0)
|
||||
Detail(
|
||||
title: "date".i18n,
|
||||
description: grade.writeDate.format(context)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String percentText() => grade.value.weight != 100 && grade.value.weight > 0 ? "${grade.value.weight}%" : "";
|
||||
String percentText() => grade.value.weight != 100 && grade.value.weight > 0
|
||||
? "${grade.value.weight}%"
|
||||
: "";
|
||||
}
|
||||
|
||||
@@ -51,10 +51,18 @@ class HomeworkView extends StatelessWidget {
|
||||
homework.subject.renamedTo ?? homework.subject.name.capital(),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(fontWeight: FontWeight.w600, fontStyle: homework.subject.isRenamed && settingsProvider.renamedSubjectsItalics ? FontStyle.italic : null),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontStyle: homework.subject.isRenamed &&
|
||||
settingsProvider.renamedSubjectsItalics
|
||||
? FontStyle.italic
|
||||
: null),
|
||||
),
|
||||
subtitle: Text(
|
||||
homework.teacher,
|
||||
(homework.teacher.isRenamed
|
||||
? homework.teacher.renamedTo
|
||||
: homework.teacher.name) ??
|
||||
'',
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
|
||||
@@ -54,10 +54,23 @@ class LessonView extends StatelessWidget {
|
||||
lesson.subject.renamedTo ?? lesson.subject.name.capital(),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(fontWeight: FontWeight.w600, fontStyle: lesson.subject.isRenamed && settingsProvider.renamedSubjectsItalics ? FontStyle.italic : null),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontStyle: lesson.subject.isRenamed &&
|
||||
settingsProvider.renamedSubjectsItalics
|
||||
? FontStyle.italic
|
||||
: null),
|
||||
),
|
||||
subtitle: Text(
|
||||
lesson.substituteTeacher == "" ? lesson.teacher : lesson.substituteTeacher,
|
||||
((lesson.substituteTeacher == null ||
|
||||
lesson.substituteTeacher!.name == "")
|
||||
? (lesson.teacher.isRenamed
|
||||
? lesson.teacher.renamedTo
|
||||
: lesson.teacher.name)
|
||||
: (lesson.substituteTeacher!.isRenamed
|
||||
? lesson.substituteTeacher!.renamedTo
|
||||
: lesson.substituteTeacher!.name)) ??
|
||||
'',
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
@@ -69,10 +82,18 @@ class LessonView extends StatelessWidget {
|
||||
),
|
||||
|
||||
// Details
|
||||
if (lesson.room != "") Detail(title: "Room".i18n, description: lesson.room.replaceAll("_", " ")),
|
||||
if (lesson.description != "") Detail(title: "Description".i18n, description: lesson.description),
|
||||
if (lesson.lessonYearIndex != null) Detail(title: "Lesson Number".i18n, description: "${lesson.lessonYearIndex}."),
|
||||
if (lesson.groupName != "") Detail(title: "Group".i18n, description: lesson.groupName),
|
||||
if (lesson.room != "")
|
||||
Detail(
|
||||
title: "Room".i18n,
|
||||
description: lesson.room.replaceAll("_", " ")),
|
||||
if (lesson.description != "")
|
||||
Detail(title: "Description".i18n, description: lesson.description),
|
||||
if (lesson.lessonYearIndex != null)
|
||||
Detail(
|
||||
title: "Lesson Number".i18n,
|
||||
description: "${lesson.lessonYearIndex}."),
|
||||
if (lesson.groupName != "")
|
||||
Detail(title: "Group".i18n, description: lesson.groupName),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -4,7 +4,8 @@ import 'package:filcnaplo_mobile_ui/common/profile_image/profile_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class NoteTile extends StatelessWidget {
|
||||
const NoteTile(this.note, {Key? key, this.onTap, this.padding}) : super(key: key);
|
||||
const NoteTile(this.note, {Key? key, this.onTap, this.padding})
|
||||
: super(key: key);
|
||||
|
||||
final Note note;
|
||||
final void Function()? onTap;
|
||||
@@ -20,11 +21,20 @@ class NoteTile extends StatelessWidget {
|
||||
visualDensity: VisualDensity.compact,
|
||||
contentPadding: const EdgeInsets.only(left: 8.0, right: 12.0),
|
||||
onTap: onTap,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14.0)),
|
||||
shape:
|
||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(14.0)),
|
||||
leading: ProfileImage(
|
||||
name: note.teacher,
|
||||
name: (note.teacher.isRenamed
|
||||
? note.teacher.renamedTo
|
||||
: note.teacher.name) ??
|
||||
'',
|
||||
radius: 22.0,
|
||||
backgroundColor: ColorUtils.stringToColor(note.teacher),
|
||||
backgroundColor: ColorUtils.stringToColor(
|
||||
(note.teacher.isRenamed
|
||||
? note.teacher.renamedTo
|
||||
: note.teacher.name) ??
|
||||
'',
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
note.title,
|
||||
|
||||
@@ -12,7 +12,8 @@ class NoteView extends StatelessWidget {
|
||||
|
||||
final Note note;
|
||||
|
||||
static void show(Note note, {required BuildContext context}) => showSlidingBottomSheet(context: context, child: NoteView(note));
|
||||
static void show(Note note, {required BuildContext context}) =>
|
||||
showSlidingBottomSheet(context: context, child: NoteView(note));
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -25,9 +26,17 @@ class NoteView extends StatelessWidget {
|
||||
// Header
|
||||
ListTile(
|
||||
leading: ProfileImage(
|
||||
name: note.teacher,
|
||||
name: (note.teacher.isRenamed
|
||||
? note.teacher.renamedTo
|
||||
: note.teacher.name) ??
|
||||
'',
|
||||
radius: 22.0,
|
||||
backgroundColor: ColorUtils.stringToColor(note.teacher),
|
||||
backgroundColor: ColorUtils.stringToColor(
|
||||
(note.teacher.isRenamed
|
||||
? note.teacher.renamedTo
|
||||
: note.teacher.name) ??
|
||||
'',
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
note.title,
|
||||
@@ -36,7 +45,10 @@ class NoteView extends StatelessWidget {
|
||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
||||
),
|
||||
subtitle: Text(
|
||||
note.teacher,
|
||||
(note.teacher.isRenamed
|
||||
? note.teacher.renamedTo
|
||||
: note.teacher.name) ??
|
||||
'',
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
|
||||
@@ -19,14 +19,18 @@ import 'package:filcnaplo_mobile_ui/common/widgets/absence/absence_view.i18n.dar
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class AbsenceSubjectView extends StatelessWidget {
|
||||
const AbsenceSubjectView(this.subject, {Key? key, this.absences = const []}) : super(key: key);
|
||||
const AbsenceSubjectView(this.subject, {Key? key, this.absences = const []})
|
||||
: super(key: key);
|
||||
|
||||
final Subject subject;
|
||||
final List<Absence> absences;
|
||||
|
||||
static void show(Subject subject, List<Absence> absences, {required BuildContext context}) {
|
||||
static void show(Subject subject, List<Absence> absences,
|
||||
{required BuildContext context}) {
|
||||
Navigator.of(context, rootNavigator: true)
|
||||
.push<Absence>(CupertinoPageRoute(builder: (context) => AbsenceSubjectView(subject, absences: absences)))
|
||||
.push<Absence>(CupertinoPageRoute(
|
||||
builder: (context) =>
|
||||
AbsenceSubjectView(subject, absences: absences)))
|
||||
.then((value) {
|
||||
if (value == null) return;
|
||||
|
||||
@@ -36,7 +40,8 @@ class AbsenceSubjectView extends StatelessWidget {
|
||||
TimetablePage.jump(context, lesson: lesson);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar(
|
||||
content: Text("Cannot find lesson".i18n, style: const TextStyle(color: Colors.white)),
|
||||
content: Text("Cannot find lesson".i18n,
|
||||
style: const TextStyle(color: Colors.white)),
|
||||
backgroundColor: AppColors.of(context).red,
|
||||
context: context,
|
||||
));
|
||||
@@ -54,7 +59,10 @@ class AbsenceSubjectView extends StatelessWidget {
|
||||
date: a.date,
|
||||
))
|
||||
.toList();
|
||||
List<Widget> absenceTiles = sortDateWidgets(context, dateWidgets: dateWidgets, padding: EdgeInsets.zero, hasShadow: true);
|
||||
List<Widget> absenceTiles = sortDateWidgets(context,
|
||||
dateWidgets: dateWidgets,
|
||||
padding: const EdgeInsets.symmetric(vertical: 6.0),
|
||||
hasShadow: true);
|
||||
|
||||
SettingsProvider settingsProvider = Provider.of<SettingsProvider>(context);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:math';
|
||||
import 'package:filcnaplo_kreta_api/models/category.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/grade.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/subject.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/teacher.dart';
|
||||
import 'package:filcnaplo_mobile_ui/common/custom_snack_bar.dart';
|
||||
import 'package:filcnaplo_mobile_ui/common/material_action_button.dart';
|
||||
import 'package:filcnaplo/ui/widgets/grade/grade_tile.dart';
|
||||
@@ -42,7 +43,8 @@ class _GradeCalculatorState extends State<GradeCalculator> {
|
||||
padding: const EdgeInsets.only(bottom: 8.0),
|
||||
child: Text(
|
||||
"Grade Calculator".i18n,
|
||||
style: const TextStyle(fontSize: 20.0, fontWeight: FontWeight.w600),
|
||||
style:
|
||||
const TextStyle(fontSize: 20.0, fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -63,7 +65,9 @@ class _GradeCalculatorState extends State<GradeCalculator> {
|
||||
Container(
|
||||
width: 80.0,
|
||||
padding: const EdgeInsets.only(right: 12.0),
|
||||
child: Center(child: GradeValueWidget(GradeValue(newValue.toInt(), "", "", 0))),
|
||||
child: Center(
|
||||
child: GradeValueWidget(
|
||||
GradeValue(newValue.toInt(), "", "", 0))),
|
||||
),
|
||||
]),
|
||||
|
||||
@@ -90,7 +94,8 @@ class _GradeCalculatorState extends State<GradeCalculator> {
|
||||
child: Center(
|
||||
child: TextField(
|
||||
controller: _weightController,
|
||||
style: const TextStyle(fontWeight: FontWeight.w600, fontSize: 22.0),
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600, fontSize: 22.0),
|
||||
autocorrect: false,
|
||||
textAlign: TextAlign.right,
|
||||
keyboardType: TextInputType.number,
|
||||
@@ -122,7 +127,8 @@ class _GradeCalculatorState extends State<GradeCalculator> {
|
||||
child: Text("Add Grade".i18n),
|
||||
onPressed: () {
|
||||
if (calculatorProvider.ghosts.length >= 50) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar(content: Text("limit_reached".i18n), context: context));
|
||||
ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar(
|
||||
content: Text("limit_reached".i18n), context: context));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -133,7 +139,11 @@ class _GradeCalculatorState extends State<GradeCalculator> {
|
||||
grades.sort((a, b) => -a.writeDate.compareTo(b.writeDate));
|
||||
date = grades.first.date.add(const Duration(days: 7));
|
||||
} else {
|
||||
List<Grade> grades = calculatorProvider.grades.where((e) => e.type == GradeType.midYear && e.subject == widget.subject).toList();
|
||||
List<Grade> grades = calculatorProvider.grades
|
||||
.where((e) =>
|
||||
e.type == GradeType.midYear &&
|
||||
e.subject == widget.subject)
|
||||
.toList();
|
||||
grades.sort((a, b) => -a.writeDate.compareTo(b.writeDate));
|
||||
date = grades.first.date;
|
||||
}
|
||||
@@ -143,8 +153,9 @@ class _GradeCalculatorState extends State<GradeCalculator> {
|
||||
date: date,
|
||||
writeDate: date,
|
||||
description: "Ghost Grade".i18n,
|
||||
value: GradeValue(newValue.toInt(), "", "", newWeight.toInt()),
|
||||
teacher: "Ghost",
|
||||
value:
|
||||
GradeValue(newValue.toInt(), "", "", newWeight.toInt()),
|
||||
teacher: Teacher.fromString("Ghost"),
|
||||
type: GradeType.ghost,
|
||||
form: "",
|
||||
subject: widget.subject,
|
||||
|
||||
@@ -21,6 +21,10 @@ import 'package:filcnaplo_mobile_ui/pages/grades/calculator/grade_calculator_pro
|
||||
import 'package:filcnaplo_mobile_ui/pages/grades/grades_count.dart';
|
||||
import 'package:filcnaplo_mobile_ui/pages/grades/graph.dart';
|
||||
import 'package:filcnaplo_mobile_ui/pages/grades/subject_grades_container.dart';
|
||||
import 'package:filcnaplo_premium/ui/mobile/goal_planner/test.dart';
|
||||
import 'package:filcnaplo_premium/models/premium_scopes.dart';
|
||||
import 'package:filcnaplo_premium/providers/premium_provider.dart';
|
||||
import 'package:filcnaplo_premium/ui/mobile/premium/upsell.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_expandable_fab/flutter_expandable_fab.dart';
|
||||
@@ -215,25 +219,25 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
gradeCalc(context);
|
||||
},
|
||||
),
|
||||
// FloatingActionButton.small(
|
||||
// child: const Icon(FeatherIcons.flag, size: 20.0),
|
||||
// backgroundColor: Theme.of(context).colorScheme.secondary,
|
||||
// onPressed: () {
|
||||
// if (!Provider.of<PremiumProvider>(context, listen: false)
|
||||
// .hasScope(PremiumScopes.goalPlanner)) {
|
||||
// PremiumLockedFeatureUpsell.show(
|
||||
// context: context, feature: PremiumFeature.goalplanner);
|
||||
// return;
|
||||
// }
|
||||
FloatingActionButton.small(
|
||||
child: const Icon(FeatherIcons.flag, size: 20.0),
|
||||
backgroundColor: Theme.of(context).colorScheme.secondary,
|
||||
onPressed: () {
|
||||
if (!Provider.of<PremiumProvider>(context, listen: false)
|
||||
.hasScope(PremiumScopes.goalPlanner)) {
|
||||
PremiumLockedFeatureUpsell.show(
|
||||
context: context, feature: PremiumFeature.goalplanner);
|
||||
return;
|
||||
}
|
||||
|
||||
// ScaffoldMessenger.of(context).showSnackBar(
|
||||
// const SnackBar(content: Text("Hamarosan...")));
|
||||
// ScaffoldMessenger.of(context).showSnackBar(
|
||||
// const SnackBar(content: Text("Hamarosan...")));
|
||||
|
||||
// Navigator.of(context).push(CupertinoPageRoute(
|
||||
// builder: (context) => PremiumGoalplannerNewGoalScreen(
|
||||
// subject: widget.subject)));
|
||||
// },
|
||||
// ),
|
||||
Navigator.of(context).push(CupertinoPageRoute(
|
||||
builder: (context) =>
|
||||
GoalPlannerTest(subject: widget.subject)));
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -263,7 +267,8 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
subject: widget.subject, context: context),
|
||||
scrollController: _scrollController,
|
||||
title: widget.subject.renamedTo ?? widget.subject.name.capital(),
|
||||
italic: settingsProvider.renamedSubjectsItalics && widget.subject.isRenamed,
|
||||
italic: settingsProvider.renamedSubjectsItalics &&
|
||||
widget.subject.isRenamed,
|
||||
child: SubjectGradesContainer(
|
||||
child: CupertinoScrollbar(
|
||||
child: ListView.builder(
|
||||
|
||||
@@ -356,14 +356,14 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
|
||||
// confetti 🎊
|
||||
if (_confettiController != null)
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
alignment: Alignment.topCenter,
|
||||
child: ConfettiWidget(
|
||||
confettiController: _confettiController!,
|
||||
blastDirection: -pi / 2,
|
||||
emissionFrequency: 0.01,
|
||||
numberOfParticles: 80,
|
||||
maxBlastForce: 100,
|
||||
minBlastForce: 90,
|
||||
blastDirectionality: BlastDirectionality.explosive,
|
||||
emissionFrequency: 0.02,
|
||||
numberOfParticles: 120,
|
||||
maxBlastForce: 20,
|
||||
minBlastForce: 10,
|
||||
gravity: 0.3,
|
||||
minimumSize: const Size(5, 5),
|
||||
maximumSize: const Size(20, 20),
|
||||
|
||||
@@ -139,7 +139,6 @@ class NavigationScreenState extends State<NavigationScreen>
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
|
||||
HomeWidget.setAppGroupId('hu.refilc.naplo.group');
|
||||
|
||||
_checkForWidgetLaunch();
|
||||
@@ -199,9 +198,9 @@ class NavigationScreenState extends State<NavigationScreen>
|
||||
// Show news
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (newsProvider.show) {
|
||||
newsProvider.lock();
|
||||
NewsView.show(newsProvider.news[newsProvider.state], context: context)
|
||||
NewsView.show(newsProvider.news[0], context: context)
|
||||
.then((value) => newsProvider.release());
|
||||
newsProvider.lock();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -31,23 +31,30 @@ class NewsView extends StatelessWidget {
|
||||
physics: const BouncingScrollPhysics(),
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0, right: 6.0, top: 14.0, bottom: 8.0),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 8.0, right: 6.0, top: 14.0, bottom: 8.0),
|
||||
child: Text(
|
||||
news.title,
|
||||
maxLines: 3,
|
||||
style: const TextStyle(fontWeight: FontWeight.w600, fontSize: 18.0),
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600, fontSize: 18.0),
|
||||
),
|
||||
),
|
||||
SelectableLinkify(
|
||||
text: news.content.escapeHtml(),
|
||||
options: const LinkifyOptions(looseUrl: true, removeWww: true),
|
||||
options:
|
||||
const LinkifyOptions(looseUrl: true, removeWww: true),
|
||||
onOpen: (link) {
|
||||
launch(
|
||||
link.url,
|
||||
customTabsOption: CustomTabsOption(showPageTitle: true, toolbarColor: Theme.of(context).scaffoldBackgroundColor),
|
||||
customTabsOption: CustomTabsOption(
|
||||
showPageTitle: true,
|
||||
toolbarColor:
|
||||
Theme.of(context).scaffoldBackgroundColor),
|
||||
);
|
||||
},
|
||||
style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 14.0),
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w500, fontSize: 14.0),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -59,10 +66,15 @@ class NewsView extends StatelessWidget {
|
||||
children: [
|
||||
if (news.link != "")
|
||||
DialogButton(
|
||||
label: news.openLabel != "" ? news.openLabel : "open".i18n.toUpperCase(),
|
||||
label: news.openLabel != ""
|
||||
? news.openLabel
|
||||
: "open".i18n.toUpperCase(),
|
||||
onTap: () => launch(
|
||||
news.link,
|
||||
customTabsOption: CustomTabsOption(showPageTitle: true, toolbarColor: Theme.of(context).scaffoldBackgroundColor),
|
||||
customTabsOption: CustomTabsOption(
|
||||
showPageTitle: true,
|
||||
toolbarColor:
|
||||
Theme.of(context).scaffoldBackgroundColor),
|
||||
),
|
||||
),
|
||||
DialogButton(
|
||||
@@ -78,12 +90,15 @@ class NewsView extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
static Future<T?> show<T>(News news, {required BuildContext context, bool force = false}) {
|
||||
static Future<T?> show<T>(News news,
|
||||
{required BuildContext context, bool force = false}) {
|
||||
if (news.title == "") return Future<T?>.value(null);
|
||||
|
||||
bool popup = news.platform == '' || force;
|
||||
bool popup = news.platform == 'all' || force;
|
||||
|
||||
if (Provider.of<SettingsProvider>(context, listen: false).newsEnabled || news.emergency || force) {
|
||||
if (Provider.of<SettingsProvider>(context, listen: false).newsEnabled ||
|
||||
news.emergency ||
|
||||
force) {
|
||||
switch (news.platform.trim().toLowerCase()) {
|
||||
case "android":
|
||||
if (Platform.isAndroid) popup = true;
|
||||
@@ -100,6 +115,9 @@ class NewsView extends StatelessWidget {
|
||||
case "macos":
|
||||
if (Platform.isMacOS) popup = true;
|
||||
break;
|
||||
case "all":
|
||||
popup = true;
|
||||
break;
|
||||
default:
|
||||
popup = true;
|
||||
}
|
||||
@@ -108,7 +126,10 @@ class NewsView extends StatelessWidget {
|
||||
}
|
||||
|
||||
if (popup) {
|
||||
return showDialog<T?>(context: context, builder: (context) => NewsView(news), barrierDismissible: true);
|
||||
return showDialog<T?>(
|
||||
context: context,
|
||||
builder: (context) => NewsView(news),
|
||||
barrierDismissible: true);
|
||||
} else {
|
||||
return Future<T?>.value(null);
|
||||
}
|
||||
|
||||
@@ -28,27 +28,22 @@ class PrivacyView extends StatelessWidget {
|
||||
),
|
||||
SelectableLinkify(
|
||||
text: """
|
||||
A reFilc egy kliensalkalmazás, segítségével az e-Kréta rendszeréből letöltheted és felhasználóbarát módon megjelenítheted az adataidat.
|
||||
Tanulmányi adataid csak közvetlenül az alkalmazás és a Kréta-szerverek között közlekednek, titkosított kapcsolaton keresztül.
|
||||
• A reFilc (továbbiakban alkalmazás) egy mobilos, asztali és webes kliensalkalmazás, segítségével az e-Kréta rendszeréből letöltheted és felhasználóbarát módon megjelenítheted az adataidat. Tanulmányi adataid csak közvetlenül az alkalmazás és a Kréta-szerverek között közlekednek, titkosított kapcsolaton keresztül.
|
||||
|
||||
A reFilc fejlesztői és üzemeltetői a tanulmányi adataidat semmilyen célból nem másolják, nem tárolják és harmadik félnek nem továbbítják. Ezeket így az e-Kréta Informatikai Zrt. kezeli, az ő tájékoztatójukat itt találod: https://tudasbazis.ekreta.hu/pages/viewpage.action?pageId=4065038.
|
||||
Azok törlésével vagy módosítával kapcsolatban keresd az osztályfőnöködet vagy az iskolád rendszergazdáját.
|
||||
• A reFilc fejlesztői és/vagy üzemeltetői, valamint az alkalmazás a tanulmányi és személyes adataidat semmilyen célból és semmilyen körülmények között nem másolják, nem tárolják és harmadik félnek nem továbbítják. Ezeket így az Educational Development Informatikai Zrt. kezeli, az Ő adatkezeléssel kapcsolatos tájékoztatójukat itt találod: https://tudasbazis.ekreta.hu/pages/viewpage.action?pageId=4065038
|
||||
|
||||
Az alkalmazás névtelen használati statisztikákat gyűjt, ezek alapján tudjuk meghatározni a felhasználók és a telepítések számát. Ezt a beállításokban kikapcsolhatod.
|
||||
Kérünk, hogy ha csak teheted, hagyd ezt a funkciót bekapcsolva.
|
||||
• Azok törlésével vagy módosítával kapcsolatban keresd az osztályfőnöködet vagy az iskolád rendszergazdáját.
|
||||
|
||||
Amikor az alkalmazás hibába ütközik, lehetőség van hibajelentés küldésére.
|
||||
Ez személyes- vagy tanulmányi adatokat nem tartalmaz, viszont részletes információval szolgál a hibáról és eszközödről.
|
||||
A küldés előtt megjelenő képernyőn a te felelősséged átnézni a továbbításra kerülő adatsort.
|
||||
A hibajelentéseket a reFilc fejlesztői felületén és egy privát Discord szobában tároljuk, ezekhez csak az app fejlesztői férnek hozzá.
|
||||
Az alkalmazás belépéskor a GitHub API segítségével ellenőrzi, hogy elérhető-e új verzió, és kérésre innen is tölti le a telepítőt.
|
||||
• Az alkalmazás névtelen használati statisztikákat gyűjt, ezek alapján tudjuk meghatározni a felhasználók és a telepítések számát, valamint az eszközük platformját. Ezt a beállításokban kikapcsolhatod. Kérünk, hogy ha csak teheted, hagyd ezt a funkciót bekapcsolva, hogy pontosabb információnk legyen a felhasználóink platform-megoszlásáról.
|
||||
|
||||
Ha az adataiddal kapcsolatban bármilyen kérdésed van (törlés, módosítás, adathordozás), keress minket a filcnaplo@filcnaplo.hu címen.
|
||||
• Amikor az alkalmazás hibába ütközik, lehetőség van hibajelentés küldésére. Ez személyes- és/vagy tanulmányi adatokat nem tartalmaz, viszont részletes információval szolgál a hibáról, annak okáról és eszközödről. A küldés előtt megjelenő képernyőn a te felelősséged átnézni a továbbításra kerülő adatsort. A hibajelentéseket a reFilc fejlesztői felületén és egy privát Discord szobában tároljuk, ezekhez csak az app fejlesztői férnek hozzá.
|
||||
|
||||
Az alkalmazás használatával jelzed, hogy ezt a tájékoztatót tudomásul vetted.
|
||||
• Az alkalmazás (az alábbi platformokon: Android, Linux, Windows) minden egyes indításakor a reFilc API, valamint a Github API segítségével ellenőrzi, hogy elérhető-e új verzió, és kérésre innen letölti és telepíti a frissítést.
|
||||
|
||||
Utolsó módosítás: 2023. 05. 28.
|
||||
""",
|
||||
• Amennyiben az adataiddal kapcsolatban bármilyen kérdésed van (megtekintés, törlés, módosítás, adathordozás), keress minket a social@refilc.hu e-mail címen, vagy Discord szerverünkön!
|
||||
|
||||
• A kliensalkalmazás bármely eszközön és platformon történő használatával tudomásul vetted és elfogadod a jelen adatkezelési tájékoztatót. A reFilc csapata fenntartja a jogot a tájékoztató módosítására és a módosításokról nem köteles értesíteni a felhasználóit!
|
||||
""",
|
||||
onOpen: (link) => launch(link.url,
|
||||
customTabsOption: CustomTabsOption(
|
||||
toolbarColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
|
||||
@@ -15,6 +15,7 @@ import 'package:filcnaplo/models/user.dart';
|
||||
import 'package:filcnaplo/theme/colors/colors.dart';
|
||||
import 'package:filcnaplo_kreta_api/client/client.dart';
|
||||
import 'package:filcnaplo_mobile_ui/common/action_button.dart';
|
||||
import 'package:filcnaplo_mobile_ui/common/beta_chip.dart';
|
||||
import 'package:filcnaplo_mobile_ui/common/bottom_sheet_menu/bottom_sheet_menu.dart';
|
||||
import 'package:filcnaplo_mobile_ui/common/bottom_sheet_menu/bottom_sheet_menu_item.dart';
|
||||
import 'package:filcnaplo_mobile_ui/common/panel/panel.dart';
|
||||
@@ -41,6 +42,7 @@ import 'package:filcnaplo_premium/ui/mobile/settings/nickname.dart';
|
||||
import 'package:filcnaplo_premium/ui/mobile/settings/profile_pic.dart';
|
||||
import 'package:filcnaplo_premium/ui/mobile/settings/icon_pack.dart';
|
||||
import 'package:filcnaplo_premium/ui/mobile/settings/modify_subject_names.dart';
|
||||
import 'package:filcnaplo_premium/ui/mobile/settings/modify_teacher_names.dart';
|
||||
|
||||
class SettingsScreen extends StatefulWidget {
|
||||
const SettingsScreen({Key? key}) : super(key: key);
|
||||
@@ -156,7 +158,8 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
void initState() {
|
||||
super.initState();
|
||||
Future.delayed(Duration.zero, () {
|
||||
futureRelease = Provider.of<UpdateProvider>(context, listen: false).installedVersion();
|
||||
futureRelease = Provider.of<UpdateProvider>(context, listen: false)
|
||||
.installedVersion();
|
||||
});
|
||||
_hideContainersController = AnimationController(
|
||||
vsync: this, duration: const Duration(milliseconds: 200));
|
||||
@@ -383,7 +386,10 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
},
|
||||
title: Text("language".i18n),
|
||||
leading: const Icon(FeatherIcons.globe),
|
||||
trailing: Text(languageText),
|
||||
trailing: Text(
|
||||
languageText,
|
||||
style: const TextStyle(fontSize: 14.0),
|
||||
),
|
||||
),
|
||||
PanelButton(
|
||||
onPressed: () {
|
||||
@@ -392,7 +398,10 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
},
|
||||
title: Text("startpage".i18n),
|
||||
leading: const Icon(FeatherIcons.play),
|
||||
trailing: Text(startPageTitle.capital()),
|
||||
trailing: Text(
|
||||
startPageTitle.capital(),
|
||||
style: const TextStyle(fontSize: 14.0),
|
||||
),
|
||||
),
|
||||
PanelButton(
|
||||
onPressed: () {
|
||||
@@ -401,8 +410,10 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
},
|
||||
title: Text("rounding".i18n),
|
||||
leading: const Icon(FeatherIcons.gitCommit),
|
||||
trailing:
|
||||
Text((settings.rounding / 10).toStringAsFixed(1)),
|
||||
trailing: Text(
|
||||
(settings.rounding / 10).toStringAsFixed(1),
|
||||
style: const TextStyle(fontSize: 14.0),
|
||||
),
|
||||
),
|
||||
PanelButton(
|
||||
onPressed: () {
|
||||
@@ -411,7 +422,10 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
},
|
||||
title: Text("vibrate".i18n),
|
||||
leading: const Icon(FeatherIcons.radio),
|
||||
trailing: Text(vibrateTitle),
|
||||
trailing: Text(
|
||||
vibrateTitle,
|
||||
style: const TextStyle(fontSize: 14.0),
|
||||
),
|
||||
),
|
||||
PanelButton(
|
||||
padding: const EdgeInsets.only(left: 14.0),
|
||||
@@ -445,50 +459,32 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
contentPadding: const EdgeInsets.only(left: 12.0),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12.0)),
|
||||
title: Row(children: [
|
||||
Icon(FeatherIcons.messageSquare,
|
||||
color: settings.notificationsEnabled ? Theme.of(context).colorScheme.secondary : AppColors.of(context).text.withOpacity(.25)),
|
||||
const SizedBox(width: 14.0),
|
||||
Text(
|
||||
"notifications".i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text.withOpacity(
|
||||
settings.notificationsEnabled ? 1.0 : .5),
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16.0,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 10, right: 10),
|
||||
child: Center(
|
||||
child: Text("BETA",
|
||||
style: TextStyle(
|
||||
fontSize: 9.1,
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withOpacity(
|
||||
settings.notificationsEnabled
|
||||
? 1.0
|
||||
: .5),
|
||||
fontWeight: FontWeight.w600,
|
||||
overflow: TextOverflow.ellipsis))),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: settings.notificationsEnabled
|
||||
title: Row(
|
||||
children: [
|
||||
Icon(FeatherIcons.messageSquare,
|
||||
color: settings.notificationsEnabled
|
||||
? Theme.of(context).colorScheme.secondary
|
||||
: AppColors.of(context).text.withOpacity(.25),
|
||||
borderRadius: BorderRadius.circular(40)),
|
||||
: AppColors.of(context)
|
||||
.text
|
||||
.withOpacity(.25)),
|
||||
const SizedBox(width: 14.0),
|
||||
Text(
|
||||
"notifications".i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text.withOpacity(
|
||||
settings.notificationsEnabled ? 1.0 : .5),
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16.0,
|
||||
),
|
||||
),
|
||||
)
|
||||
]),
|
||||
const SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
BetaChip(
|
||||
disabled: !settings.notificationsEnabled,
|
||||
),
|
||||
],
|
||||
),
|
||||
onChanged: (value) =>
|
||||
settings.update(notificationsEnabled: value),
|
||||
),
|
||||
@@ -636,7 +632,10 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
},
|
||||
title: Text("theme".i18n),
|
||||
leading: const Icon(FeatherIcons.sun),
|
||||
trailing: Text(themeModeText),
|
||||
trailing: Text(
|
||||
themeModeText,
|
||||
style: const TextStyle(fontSize: 14.0),
|
||||
),
|
||||
),
|
||||
PanelButton(
|
||||
onPressed: () async {
|
||||
@@ -805,6 +804,9 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
MenuRenamedSubjects(
|
||||
settings: settings,
|
||||
),
|
||||
MenuRenamedTeachers(
|
||||
settings: settings,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -817,6 +819,19 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
child: Panel(
|
||||
title: Text("about".i18n),
|
||||
child: Column(children: [
|
||||
PanelButton(
|
||||
leading: const Icon(FeatherIcons.mail),
|
||||
title: Text("news".i18n),
|
||||
onPressed: () => _openNews(context),
|
||||
),
|
||||
PanelButton(
|
||||
leading: const Icon(FeatherIcons.lock),
|
||||
title: Text("privacy".i18n),
|
||||
// onPressed: () => launchUrl(
|
||||
// Uri.parse("https://refilc.hu/privacy-policy"),
|
||||
// mode: LaunchMode.inAppWebView),
|
||||
onPressed: () => _openPrivacy(context),
|
||||
),
|
||||
PanelButton(
|
||||
leading: const Icon(FeatherIcons.atSign),
|
||||
title: const Text("Discord"),
|
||||
@@ -838,16 +853,6 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
Uri.parse("https://github.com/refilc"),
|
||||
mode: LaunchMode.externalApplication),
|
||||
),
|
||||
PanelButton(
|
||||
leading: const Icon(FeatherIcons.mail),
|
||||
title: Text("news".i18n),
|
||||
onPressed: () => _openNews(context),
|
||||
),
|
||||
PanelButton(
|
||||
leading: const Icon(FeatherIcons.lock),
|
||||
title: Text("privacy".i18n),
|
||||
onPressed: () => _openPrivacy(context),
|
||||
),
|
||||
PanelButton(
|
||||
leading: const Icon(FeatherIcons.award),
|
||||
title: Text("licenses".i18n),
|
||||
@@ -923,7 +928,8 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12.0)),
|
||||
title: Text("devmode".i18n,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500)),
|
||||
style:
|
||||
const TextStyle(fontWeight: FontWeight.w500)),
|
||||
onChanged: (v) =>
|
||||
settings.update(developerMode: false),
|
||||
value: settings.developerMode,
|
||||
@@ -998,8 +1004,8 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
if (devmodeCountdown > 0) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
content: Text(
|
||||
"devmoretaps".i18n.fill([devmodeCountdown])),
|
||||
content:
|
||||
Text("devmoretaps".i18n.fill([devmodeCountdown])),
|
||||
));
|
||||
|
||||
setState(() => devmodeCountdown--);
|
||||
|
||||
@@ -163,7 +163,7 @@ extension SettingsLocalization on String {
|
||||
"theme": "Thema",
|
||||
"color": "Farbe",
|
||||
"grade_colors": "Grad Farben",
|
||||
"notifications": "Benachrichtigungen",
|
||||
"notifications": "Mitteilung",
|
||||
"news": "Nachrichten",
|
||||
"extras": "Extras",
|
||||
"about": "Informationen",
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
name: filcnaplo_mobile_ui
|
||||
publish_to: "none"
|
||||
|
||||
environment:
|
||||
sdk: ">=2.17.0 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
cupertino_icons: ^1.0.2
|
||||
|
||||
# Filcnaplo main dep
|
||||
filcnaplo:
|
||||
path: ../filcnaplo/
|
||||
filcnaplo_kreta_api:
|
||||
path: ../filcnaplo_kreta_api/
|
||||
filcnaplo_premium:
|
||||
path: ../filcnaplo_premium/
|
||||
|
||||
flutter_feather_icons: ^2.0.0+1
|
||||
provider: ^5.0.0
|
||||
fl_chart: ^0.45.1
|
||||
url_launcher: ^6.0.9
|
||||
flutter_material_color_picker: ^1.1.0+2
|
||||
photo_view: ^0.14.0
|
||||
flutter_linkify: ^5.0.2
|
||||
flutter_custom_tabs: ^1.0.3
|
||||
flutter_markdown: ^0.6.5
|
||||
animations: ^2.0.1
|
||||
animated_list_plus: ^0.5.0
|
||||
confetti: ^0.6.0
|
||||
live_activities: ^1.0.0
|
||||
animated_flip_counter: ^0.2.5
|
||||
lottie: ^1.4.3
|
||||
rive: ^0.9.1
|
||||
animated_background: ^2.0.0
|
||||
home_widget: ^0.1.6
|
||||
dropdown_button2: ^1.8.9
|
||||
flutter_svg: ^1.1.6
|
||||
background_fetch: ^1.1.5
|
||||
wtf_sliding_sheet: ^1.0.0
|
||||
package_info_plus: ^4.0.2
|
||||
dotted_border: ^2.0.0+3
|
||||
screenshot: ^2.1.0
|
||||
image_gallery_saver: ^2.0.2
|
||||
rounded_expansion_tile: ^0.0.13
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^1.0.0
|
||||
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
Reference in New Issue
Block a user