fixed warnings (super.key, etc)
This commit is contained in:
parent
fc3f538e6b
commit
6bac82f7d6
@ -14,7 +14,7 @@ import 'package:connectivity_plus/connectivity_plus.dart';
|
|||||||
import 'updates_view.i18n.dart';
|
import 'updates_view.i18n.dart';
|
||||||
|
|
||||||
class UpdateView extends StatefulWidget {
|
class UpdateView extends StatefulWidget {
|
||||||
const UpdateView(this.release, {Key? key}) : super(key: key);
|
const UpdateView(this.release, {super.key});
|
||||||
|
|
||||||
final Release release;
|
final Release release;
|
||||||
|
|
||||||
@ -22,10 +22,10 @@ class UpdateView extends StatefulWidget {
|
|||||||
showBottomCard(context: context, child: UpdateView(release));
|
showBottomCard(context: context, child: UpdateView(release));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_UpdateViewState createState() => _UpdateViewState();
|
UpdateViewState createState() => UpdateViewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _UpdateViewState extends State<UpdateView> {
|
class UpdateViewState extends State<UpdateView> {
|
||||||
double progress = 0.0;
|
double progress = 0.0;
|
||||||
UpdateState state = UpdateState.none;
|
UpdateState state = UpdateState.none;
|
||||||
|
|
||||||
@ -90,6 +90,9 @@ class _UpdateViewState extends State<UpdateView> {
|
|||||||
// Download button
|
// Download button
|
||||||
Center(
|
Center(
|
||||||
child: MaterialActionButton(
|
child: MaterialActionButton(
|
||||||
|
backgroundColor: AppColors.of(context).filc,
|
||||||
|
onPressed:
|
||||||
|
state == UpdateState.none ? () => downloadPrecheck() : null,
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
@ -114,9 +117,6 @@ class _UpdateViewState extends State<UpdateView> {
|
|||||||
.toUpperCase()),
|
.toUpperCase()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
backgroundColor: AppColors.of(context).filc,
|
|
||||||
onPressed:
|
|
||||||
state == UpdateState.none ? () => downloadPrecheck() : null,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -19,8 +19,7 @@ import 'package:filcnaplo_mobile_ui/common/widgets/absence/absence_view.i18n.dar
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class AbsenceSubjectView extends StatelessWidget {
|
class AbsenceSubjectView extends StatelessWidget {
|
||||||
const AbsenceSubjectView(this.subject, {Key? key, this.absences = const []})
|
const AbsenceSubjectView(this.subject, {super.key, this.absences = const []});
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
final GradeSubject subject;
|
final GradeSubject subject;
|
||||||
final List<Absence> absences;
|
final List<Absence> absences;
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class AbsenceSubjectViewContainer extends InheritedWidget {
|
class AbsenceSubjectViewContainer extends InheritedWidget {
|
||||||
const AbsenceSubjectViewContainer({Key? key, required Widget child}) : super(key: key, child: child);
|
const AbsenceSubjectViewContainer({super.key, required super.child});
|
||||||
|
|
||||||
static AbsenceSubjectViewContainer? of(BuildContext context) => context.dependOnInheritedWidgetOfExactType<AbsenceSubjectViewContainer>();
|
static AbsenceSubjectViewContainer? of(BuildContext context) =>
|
||||||
|
context.dependOnInheritedWidgetOfExactType<AbsenceSubjectViewContainer>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool updateShouldNotify(AbsenceSubjectViewContainer oldWidget) => false;
|
bool updateShouldNotify(AbsenceSubjectViewContainer oldWidget) => false;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// ignore_for_file: no_leading_underscores_for_local_identifiers
|
||||||
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:animations/animations.dart';
|
import 'package:animations/animations.dart';
|
||||||
@ -42,13 +44,13 @@ class SubjectAbsence {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AbsencesPage extends StatefulWidget {
|
class AbsencesPage extends StatefulWidget {
|
||||||
const AbsencesPage({Key? key}) : super(key: key);
|
const AbsencesPage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_AbsencesPageState createState() => _AbsencesPageState();
|
AbsencesPageState createState() => AbsencesPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AbsencesPageState extends State<AbsencesPage>
|
class AbsencesPageState extends State<AbsencesPage>
|
||||||
with TickerProviderStateMixin {
|
with TickerProviderStateMixin {
|
||||||
late UserProvider user;
|
late UserProvider user;
|
||||||
late AbsenceProvider absenceProvider;
|
late AbsenceProvider absenceProvider;
|
||||||
@ -308,10 +310,10 @@ class _AbsencesPageState extends State<AbsencesPage>
|
|||||||
Animation<double> secondaryAnimation,
|
Animation<double> secondaryAnimation,
|
||||||
) {
|
) {
|
||||||
return FadeThroughTransition(
|
return FadeThroughTransition(
|
||||||
child: child,
|
|
||||||
animation: primaryAnimation,
|
animation: primaryAnimation,
|
||||||
secondaryAnimation: secondaryAnimation,
|
secondaryAnimation: secondaryAnimation,
|
||||||
fillColor: Theme.of(context).colorScheme.background,
|
fillColor: Theme.of(context).colorScheme.background,
|
||||||
|
child: child,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -359,7 +361,7 @@ class _AbsencesPageState extends State<AbsencesPage>
|
|||||||
.length;
|
.length;
|
||||||
title1 = "stat_1".i18n;
|
title1 = "stat_1".i18n;
|
||||||
title2 = "stat_2".i18n;
|
title2 = "stat_2".i18n;
|
||||||
suffix = " " + "hr".i18n;
|
suffix = " ${"hr".i18n}";
|
||||||
} else if (activeData == AbsenceFilter.delays.index) {
|
} else if (activeData == AbsenceFilter.delays.index) {
|
||||||
value1 = absenceProvider.absences
|
value1 = absenceProvider.absences
|
||||||
.where((e) =>
|
.where((e) =>
|
||||||
@ -373,7 +375,7 @@ class _AbsencesPageState extends State<AbsencesPage>
|
|||||||
.fold(0, (a, b) => a + b);
|
.fold(0, (a, b) => a + b);
|
||||||
title1 = "stat_3".i18n;
|
title1 = "stat_3".i18n;
|
||||||
title2 = "stat_4".i18n;
|
title2 = "stat_4".i18n;
|
||||||
suffix = " " + "min".i18n;
|
suffix = " ${"min".i18n}";
|
||||||
}
|
}
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
|
@ -17,16 +17,16 @@ final Map<int, String> avgDropItems = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class AverageSelector extends StatefulWidget {
|
class AverageSelector extends StatefulWidget {
|
||||||
const AverageSelector({Key? key, this.onChanged, required this.value}) : super(key: key);
|
const AverageSelector({super.key, this.onChanged, required this.value});
|
||||||
|
|
||||||
final Function(int?)? onChanged;
|
final Function(int?)? onChanged;
|
||||||
final int value;
|
final int value;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_AverageSelectorState createState() => _AverageSelectorState();
|
AverageSelectorState createState() => AverageSelectorState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AverageSelectorState extends State<AverageSelector> {
|
class AverageSelectorState extends State<AverageSelector> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
List<DropdownMenuItem<int>> dropdownItems = avgDropItems.keys.map((item) {
|
List<DropdownMenuItem<int>> dropdownItems = avgDropItems.keys.map((item) {
|
||||||
@ -47,14 +47,16 @@ class _AverageSelectorState extends State<AverageSelector> {
|
|||||||
return DropdownButton2<int>(
|
return DropdownButton2<int>(
|
||||||
items: dropdownItems,
|
items: dropdownItems,
|
||||||
onChanged: (int? value) {
|
onChanged: (int? value) {
|
||||||
if (Provider.of<PremiumProvider>(context, listen: false).hasScope(PremiumScopes.gradeStats)) {
|
if (Provider.of<PremiumProvider>(context, listen: false)
|
||||||
|
.hasScope(PremiumScopes.gradeStats)) {
|
||||||
if (widget.onChanged != null) {
|
if (widget.onChanged != null) {
|
||||||
setState(() {
|
setState(() {
|
||||||
widget.onChanged!(value);
|
widget.onChanged!(value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PremiumLockedFeatureUpsell.show(context: context, feature: PremiumFeature.gradestats);
|
PremiumLockedFeatureUpsell.show(
|
||||||
|
context: context, feature: PremiumFeature.gradestats);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
value: widget.value,
|
value: widget.value,
|
||||||
@ -84,10 +86,9 @@ class _AverageSelectorState extends State<AverageSelector> {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
avgDropItems[widget.value]!.i18n,
|
avgDropItems[widget.value]!.i18n,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context).textTheme.titleSmall!.copyWith(
|
||||||
.textTheme
|
fontWeight: FontWeight.w600,
|
||||||
.titleSmall!
|
color: AppColors.of(context).text.withOpacity(0.65)),
|
||||||
.copyWith(fontWeight: FontWeight.w600, color: AppColors.of(context).text.withOpacity(0.65)),
|
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 4,
|
width: 4,
|
||||||
|
@ -1,24 +1,18 @@
|
|||||||
import 'package:filcnaplo/api/providers/database_provider.dart';
|
// import 'package:filcnaplo/api/providers/database_provider.dart';
|
||||||
import 'package:filcnaplo/api/providers/user_provider.dart';
|
// import 'package:filcnaplo/api/providers/user_provider.dart';
|
||||||
import 'package:filcnaplo/models/settings.dart';
|
// import 'package:filcnaplo/models/settings.dart';
|
||||||
import 'package:filcnaplo_kreta_api/client/client.dart';
|
// import 'package:filcnaplo_kreta_api/client/client.dart';
|
||||||
import 'package:filcnaplo_kreta_api/providers/grade_provider.dart';
|
import 'package:filcnaplo_kreta_api/providers/grade_provider.dart';
|
||||||
import 'package:filcnaplo_kreta_api/models/grade.dart';
|
import 'package:filcnaplo_kreta_api/models/grade.dart';
|
||||||
|
|
||||||
class GradeCalculatorProvider extends GradeProvider {
|
class GradeCalculatorProvider extends GradeProvider {
|
||||||
GradeCalculatorProvider({
|
GradeCalculatorProvider({
|
||||||
List<Grade> initialGrades = const [],
|
super.initialGrades,
|
||||||
required SettingsProvider settings,
|
required super.settings,
|
||||||
required UserProvider user,
|
required super.user,
|
||||||
required DatabaseProvider database,
|
required super.database,
|
||||||
required KretaClient kreta,
|
required super.kreta,
|
||||||
}) : super(
|
});
|
||||||
initialGrades: initialGrades,
|
|
||||||
settings: settings,
|
|
||||||
database: database,
|
|
||||||
kreta: kreta,
|
|
||||||
user: user,
|
|
||||||
);
|
|
||||||
|
|
||||||
List<Grade> _grades = [];
|
List<Grade> _grades = [];
|
||||||
List<Grade> _ghosts = [];
|
List<Grade> _ghosts = [];
|
||||||
|
@ -5,13 +5,14 @@ import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
|||||||
import 'grades_page.i18n.dart';
|
import 'grades_page.i18n.dart';
|
||||||
|
|
||||||
class FailWarning extends StatelessWidget {
|
class FailWarning extends StatelessWidget {
|
||||||
const FailWarning({Key? key, required this.subjectAvgs}) : super(key: key);
|
const FailWarning({super.key, required this.subjectAvgs});
|
||||||
|
|
||||||
final Map<GradeSubject, double> subjectAvgs;
|
final Map<GradeSubject, double> subjectAvgs;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final failingSubjectCount = subjectAvgs.values.where((avg) => avg < 2.0).length;
|
final failingSubjectCount =
|
||||||
|
subjectAvgs.values.where((avg) => avg < 2.0).length;
|
||||||
|
|
||||||
if (failingSubjectCount == 0) {
|
if (failingSubjectCount == 0) {
|
||||||
return const SizedBox();
|
return const SizedBox();
|
||||||
|
@ -4,19 +4,24 @@ import 'package:filcnaplo_mobile_ui/pages/grades/grades_count_item.dart';
|
|||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
|
|
||||||
class GradesCount extends StatelessWidget {
|
class GradesCount extends StatelessWidget {
|
||||||
const GradesCount({Key? key, required this.grades}) : super(key: key);
|
const GradesCount({super.key, required this.grades});
|
||||||
|
|
||||||
final List<Grade> grades;
|
final List<Grade> grades;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
List<int> gradesCount = List.generate(5, (int index) => grades.where((e) => e.value.value == index + 1).length);
|
List<int> gradesCount = List.generate(5,
|
||||||
|
(int index) => grades.where((e) => e.value.value == index + 1).length);
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 6.0, top: 6.0, left: 12.0, right: 6.0),
|
padding:
|
||||||
|
const EdgeInsets.only(bottom: 6.0, top: 6.0, left: 12.0, right: 6.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
children: gradesCount.mapIndexed((index, e) => GradesCountItem(count: e, value: index + 1)).toList(),
|
children: gradesCount
|
||||||
|
.mapIndexed(
|
||||||
|
(index, e) => GradesCountItem(count: e, value: index + 1))
|
||||||
|
.toList(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import 'package:filcnaplo_kreta_api/models/grade.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class GradesCountItem extends StatelessWidget {
|
class GradesCountItem extends StatelessWidget {
|
||||||
const GradesCountItem({Key? key, required this.count, required this.value}) : super(key: key);
|
const GradesCountItem({super.key, required this.count, required this.value});
|
||||||
|
|
||||||
final int count;
|
final int count;
|
||||||
final int value;
|
final int value;
|
||||||
@ -26,7 +26,8 @@ class GradesCountItem extends StatelessWidget {
|
|||||||
style: const TextStyle(fontSize: 15.0),
|
style: const TextStyle(fontSize: 15.0),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 5.0),
|
const SizedBox(width: 5.0),
|
||||||
GradeValueWidget(GradeValue(value, "Value", "Value", 100), size: 19.0, fill: true, shadow: false),
|
GradeValueWidget(GradeValue(value, "Value", "Value", 100),
|
||||||
|
size: 19.0, fill: true, shadow: false),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class SubjectGradesContainer extends InheritedWidget {
|
class SubjectGradesContainer extends InheritedWidget {
|
||||||
const SubjectGradesContainer({Key? key, required Widget child}) : super(key: key, child: child);
|
const SubjectGradesContainer({super.key, required super.child});
|
||||||
|
|
||||||
static SubjectGradesContainer? of(BuildContext context) => context.dependOnInheritedWidgetOfExactType<SubjectGradesContainer>();
|
static SubjectGradesContainer? of(BuildContext context) =>
|
||||||
|
context.dependOnInheritedWidgetOfExactType<SubjectGradesContainer>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool updateShouldNotify(SubjectGradesContainer oldWidget) => false;
|
bool updateShouldNotify(SubjectGradesContainer oldWidget) => false;
|
||||||
|
@ -5,7 +5,8 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:lottie/lottie.dart';
|
import 'package:lottie/lottie.dart';
|
||||||
|
|
||||||
class HeadsUpCountdown extends StatefulWidget {
|
class HeadsUpCountdown extends StatefulWidget {
|
||||||
const HeadsUpCountdown({Key? key, required this.maxTime, required this.elapsedTime}) : super(key: key);
|
const HeadsUpCountdown(
|
||||||
|
{super.key, required this.maxTime, required this.elapsedTime});
|
||||||
|
|
||||||
final double maxTime;
|
final double maxTime;
|
||||||
final double elapsedTime;
|
final double elapsedTime;
|
||||||
@ -92,7 +93,8 @@ class _HeadsUpCountdownState extends State<HeadsUpCountdown> {
|
|||||||
AnimatedOpacity(
|
AnimatedOpacity(
|
||||||
opacity: dur.inSeconds > 0 ? 0.0 : 1.0,
|
opacity: dur.inSeconds > 0 ? 0.0 : 1.0,
|
||||||
duration: const Duration(milliseconds: 500),
|
duration: const Duration(milliseconds: 500),
|
||||||
child: Lottie.asset("assets/animations/bell-alert.json", width: 400),
|
child: Lottie.asset("assets/animations/bell-alert.json",
|
||||||
|
width: 400),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -10,7 +10,7 @@ enum ProgressAccuracy { minutes, seconds }
|
|||||||
|
|
||||||
class LiveCardWidget extends StatefulWidget {
|
class LiveCardWidget extends StatefulWidget {
|
||||||
const LiveCardWidget({
|
const LiveCardWidget({
|
||||||
Key? key,
|
super.key,
|
||||||
this.isEvent = false,
|
this.isEvent = false,
|
||||||
this.leading,
|
this.leading,
|
||||||
this.title,
|
this.title,
|
||||||
@ -26,7 +26,7 @@ class LiveCardWidget extends StatefulWidget {
|
|||||||
this.progressAccuracy = ProgressAccuracy.minutes,
|
this.progressAccuracy = ProgressAccuracy.minutes,
|
||||||
this.onProgressTap,
|
this.onProgressTap,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
final bool isEvent;
|
final bool isEvent;
|
||||||
final String? leading;
|
final String? leading;
|
||||||
|
@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:filcnaplo/utils/format.dart';
|
import 'package:filcnaplo/utils/format.dart';
|
||||||
|
|
||||||
class DayTitle extends StatefulWidget {
|
class DayTitle extends StatefulWidget {
|
||||||
const DayTitle({Key? key, required this.dayTitle, required this.controller}) : super(key: key);
|
const DayTitle({super.key, required this.dayTitle, required this.controller});
|
||||||
|
|
||||||
final String Function(int) dayTitle;
|
final String Function(int) dayTitle;
|
||||||
final TabController controller;
|
final TabController controller;
|
||||||
@ -50,7 +50,11 @@ class _DayTitleState extends State<DayTitle> {
|
|||||||
width: MediaQuery.of(context).size.width / 1.5,
|
width: MediaQuery.of(context).size.width / 1.5,
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.dayTitle(index).capital(),
|
widget.dayTitle(index).capital(),
|
||||||
style: TextStyle(color: AppColors.of(context).text.withOpacity(opacity), fontSize: 32.0, fontWeight: FontWeight.bold),
|
style: TextStyle(
|
||||||
|
color:
|
||||||
|
AppColors.of(context).text.withOpacity(opacity),
|
||||||
|
fontSize: 32.0,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -13,8 +13,7 @@ import 'package:i18n_extension/i18n_widget.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class FSTimetable extends StatefulWidget {
|
class FSTimetable extends StatefulWidget {
|
||||||
const FSTimetable({Key? key, required this.controller})
|
const FSTimetable({super.key, required this.controller});
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
final TimetableController controller;
|
final TimetableController controller;
|
||||||
|
|
||||||
@ -81,7 +80,7 @@ class _FSTimetableState extends State<FSTimetable> {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
(index).toString()+".",
|
"$index.",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Theme.of(context).colorScheme.secondary),
|
color: Theme.of(context).colorScheme.secondary),
|
||||||
@ -178,9 +177,9 @@ class _FSTimetableState extends State<FSTimetable> {
|
|||||||
lessons[lessonIndex].subject.name.capital(),
|
lessons[lessonIndex].subject.name.capital(),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontStyle: lessons[lessonIndex]
|
fontStyle:
|
||||||
.subject
|
lessons[lessonIndex].subject.isRenamed &&
|
||||||
.isRenamed && settings.renamedSubjectsItalics
|
settings.renamedSubjectsItalics
|
||||||
? FontStyle.italic
|
? FontStyle.italic
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
|
@ -32,8 +32,7 @@ import 'timetable_page.i18n.dart';
|
|||||||
// todo: "fix" overflow (priority: -1)
|
// todo: "fix" overflow (priority: -1)
|
||||||
|
|
||||||
class TimetablePage extends StatefulWidget {
|
class TimetablePage extends StatefulWidget {
|
||||||
const TimetablePage({Key? key, this.initialDay, this.initialWeek})
|
const TimetablePage({super.key, this.initialDay, this.initialWeek});
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
final DateTime? initialDay;
|
final DateTime? initialDay;
|
||||||
final Week? initialWeek;
|
final Week? initialWeek;
|
||||||
@ -58,10 +57,10 @@ class TimetablePage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_TimetablePageState createState() => _TimetablePageState();
|
TimetablePageState createState() => TimetablePageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TimetablePageState extends State<TimetablePage>
|
class TimetablePageState extends State<TimetablePage>
|
||||||
with TickerProviderStateMixin, WidgetsBindingObserver {
|
with TickerProviderStateMixin, WidgetsBindingObserver {
|
||||||
late UserProvider user;
|
late UserProvider user;
|
||||||
late TimetableProvider timetableProvider;
|
late TimetableProvider timetableProvider;
|
||||||
@ -265,8 +264,8 @@ class _TimetablePageState extends State<TimetablePage>
|
|||||||
animation: primaryAnimation,
|
animation: primaryAnimation,
|
||||||
secondaryAnimation: secondaryAnimation,
|
secondaryAnimation: secondaryAnimation,
|
||||||
transitionType: SharedAxisTransitionType.horizontal,
|
transitionType: SharedAxisTransitionType.horizontal,
|
||||||
child: child,
|
|
||||||
fillColor: Theme.of(context).scaffoldBackgroundColor,
|
fillColor: Theme.of(context).scaffoldBackgroundColor,
|
||||||
|
child: child,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
layoutBuilder: (List<Widget> entries) {
|
layoutBuilder: (List<Widget> entries) {
|
||||||
@ -319,6 +318,7 @@ class _TimetablePageState extends State<TimetablePage>
|
|||||||
),
|
),
|
||||||
shadowColor: Theme.of(context).shadowColor,
|
shadowColor: Theme.of(context).shadowColor,
|
||||||
bottom: PreferredSize(
|
bottom: PreferredSize(
|
||||||
|
preferredSize: const Size.fromHeight(50.0),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -354,29 +354,7 @@ class _TimetablePageState extends State<TimetablePage>
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
"${_controller.currentWeekId + 1}. " +
|
"${_controller.currentWeekId + 1}. ${"week".i18n} (${DateFormat("${_controller.currentWeek.start.year != DateTime.now().year ? "yy. " : ""}MMM d.", I18n.of(context).locale.languageCode).format(_controller.currentWeek.start)} - ${DateFormat("${_controller.currentWeek.start.year != DateTime.now().year ? "yy. " : ""}MMM d.", I18n.of(context).locale.languageCode).format(_controller.currentWeek.end)})",
|
||||||
"week".i18n +
|
|
||||||
" (" +
|
|
||||||
// Week start
|
|
||||||
DateFormat(
|
|
||||||
(_controller.currentWeek.start.year !=
|
|
||||||
DateTime.now().year
|
|
||||||
? "yy. "
|
|
||||||
: "") +
|
|
||||||
"MMM d.",
|
|
||||||
I18n.of(context).locale.languageCode)
|
|
||||||
.format(_controller.currentWeek.start) +
|
|
||||||
" - " +
|
|
||||||
// Week end
|
|
||||||
DateFormat(
|
|
||||||
(_controller.currentWeek.start.year !=
|
|
||||||
DateTime.now().year
|
|
||||||
? "yy. "
|
|
||||||
: "") +
|
|
||||||
"MMM d.",
|
|
||||||
I18n.of(context).locale.languageCode)
|
|
||||||
.format(_controller.currentWeek.end) +
|
|
||||||
")",
|
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
fontSize: 14.0,
|
fontSize: 14.0,
|
||||||
@ -398,7 +376,6 @@ class _TimetablePageState extends State<TimetablePage>
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
preferredSize: const Size.fromHeight(50.0),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -409,10 +386,10 @@ class _TimetablePageState extends State<TimetablePage>
|
|||||||
Animation<double> secondaryAnimation,
|
Animation<double> secondaryAnimation,
|
||||||
) {
|
) {
|
||||||
return FadeThroughTransition(
|
return FadeThroughTransition(
|
||||||
child: child,
|
|
||||||
animation: primaryAnimation,
|
animation: primaryAnimation,
|
||||||
secondaryAnimation: secondaryAnimation,
|
secondaryAnimation: secondaryAnimation,
|
||||||
fillColor: Theme.of(context).scaffoldBackgroundColor,
|
fillColor: Theme.of(context).scaffoldBackgroundColor,
|
||||||
|
child: child,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: _controller.days != null
|
child: _controller.days != null
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class AvatarStack extends StatelessWidget {
|
class AvatarStack extends StatelessWidget {
|
||||||
const AvatarStack({Key? key, required this.children}) : super(key: key);
|
const AvatarStack({super.key, required this.children});
|
||||||
|
|
||||||
final List<Widget> children;
|
final List<Widget> children;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import 'package:flutter_svg/svg.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class GithubConnectButton extends StatelessWidget {
|
class GithubConnectButton extends StatelessWidget {
|
||||||
const GithubConnectButton({Key? key}) : super(key: key);
|
const GithubConnectButton({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -26,7 +26,10 @@ class GithubConnectButton extends StatelessWidget {
|
|||||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
content: Text(
|
content: Text(
|
||||||
"Prémium deaktiválva.",
|
"Prémium deaktiválva.",
|
||||||
style: TextStyle(color: AppColors.of(context).text, fontWeight: FontWeight.bold, fontSize: 18.0),
|
style: TextStyle(
|
||||||
|
color: AppColors.of(context).text,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 18.0),
|
||||||
),
|
),
|
||||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||||
));
|
));
|
||||||
@ -74,7 +77,9 @@ class GithubConnectButton extends StatelessWidget {
|
|||||||
child: Transform.translate(
|
child: Transform.translate(
|
||||||
offset: const Offset(2.0, 2.0),
|
offset: const Offset(2.0, 2.0),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
premium.hasPremium ? FeatherIcons.minusCircle : FeatherIcons.plusCircle,
|
premium.hasPremium
|
||||||
|
? FeatherIcons.minusCircle
|
||||||
|
: FeatherIcons.plusCircle,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
size: 16.0,
|
size: 16.0,
|
||||||
),
|
),
|
||||||
@ -85,8 +90,13 @@ class GithubConnectButton extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
premium.hasPremium ? "GitHub szétkapcsolása" : "GitHub csatlakoztatása",
|
premium.hasPremium
|
||||||
style: const TextStyle(fontWeight: FontWeight.w600, fontSize: 20, color: Colors.white),
|
? "GitHub szétkapcsolása"
|
||||||
|
: "GitHub csatlakoztatása",
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontSize: 20,
|
||||||
|
color: Colors.white),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -3,7 +3,7 @@ import 'dart:ui';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class PremiumGoalCard extends StatelessWidget {
|
class PremiumGoalCard extends StatelessWidget {
|
||||||
const PremiumGoalCard({Key? key, this.progress = 100, this.target = 1}) : super(key: key);
|
const PremiumGoalCard({super.key, this.progress = 100, this.target = 1});
|
||||||
|
|
||||||
final double progress;
|
final double progress;
|
||||||
final double target;
|
final double target;
|
||||||
@ -20,7 +20,8 @@ class PremiumGoalCard extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Cél: ${target.round()} támogató",
|
"Cél: ${target.round()} támogató",
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 18.0),
|
style:
|
||||||
|
const TextStyle(fontWeight: FontWeight.bold, fontSize: 18.0),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8.0),
|
const SizedBox(height: 8.0),
|
||||||
Stack(
|
Stack(
|
||||||
@ -43,7 +44,10 @@ class PremiumGoalCard extends StatelessWidget {
|
|||||||
height: 12,
|
height: 12,
|
||||||
width: size.maxWidth * (progress / 100),
|
width: size.maxWidth * (progress / 100),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: const LinearGradient(colors: [Color(0xFFFF2A9D), Color(0xFFFF37F7)]),
|
gradient: const LinearGradient(colors: [
|
||||||
|
Color(0xFFFF2A9D),
|
||||||
|
Color(0xFFFF37F7)
|
||||||
|
]),
|
||||||
borderRadius: BorderRadius.circular(45.0),
|
borderRadius: BorderRadius.circular(45.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -52,8 +56,10 @@ class PremiumGoalCard extends StatelessWidget {
|
|||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
ImageFiltered(
|
ImageFiltered(
|
||||||
imageFilter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
|
imageFilter:
|
||||||
child: Image.asset("assets/images/heart.png", color: Colors.black.withOpacity(.3)),
|
ImageFilter.blur(sigmaX: 5, sigmaY: 5),
|
||||||
|
child: Image.asset("assets/images/heart.png",
|
||||||
|
color: Colors.black.withOpacity(.3)),
|
||||||
),
|
),
|
||||||
Image.asset("assets/images/heart.png"),
|
Image.asset("assets/images/heart.png"),
|
||||||
],
|
],
|
||||||
|
@ -4,7 +4,7 @@ import 'package:url_launcher/url_launcher.dart';
|
|||||||
|
|
||||||
class PremiumPlanCard extends StatelessWidget {
|
class PremiumPlanCard extends StatelessWidget {
|
||||||
const PremiumPlanCard({
|
const PremiumPlanCard({
|
||||||
Key? key,
|
super.key,
|
||||||
this.icon,
|
this.icon,
|
||||||
this.title,
|
this.title,
|
||||||
this.description,
|
this.description,
|
||||||
@ -12,7 +12,7 @@ class PremiumPlanCard extends StatelessWidget {
|
|||||||
this.url,
|
this.url,
|
||||||
this.gradient,
|
this.gradient,
|
||||||
this.active = false,
|
this.active = false,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
final Widget? icon;
|
final Widget? icon;
|
||||||
final Widget? title;
|
final Widget? title;
|
||||||
@ -28,7 +28,8 @@ class PremiumPlanCard extends StatelessWidget {
|
|||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
customBorder: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
|
customBorder:
|
||||||
|
RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
launchUrl(
|
launchUrl(
|
||||||
@ -51,13 +52,20 @@ class PremiumPlanCard extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
if (icon != null) ...[
|
if (icon != null) ...[
|
||||||
IconTheme(
|
IconTheme(
|
||||||
data: Theme.of(context).iconTheme.copyWith(size: 42.0),
|
data: Theme.of(context)
|
||||||
|
.iconTheme
|
||||||
|
.copyWith(size: 42.0),
|
||||||
child: icon!,
|
child: icon!,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12.0),
|
const SizedBox(height: 12.0),
|
||||||
],
|
],
|
||||||
DefaultTextStyle(
|
DefaultTextStyle(
|
||||||
style: Theme.of(context).textTheme.displaySmall!.copyWith(fontWeight: FontWeight.bold, fontSize: 25.0),
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.displaySmall!
|
||||||
|
.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 25.0),
|
||||||
child: title!,
|
child: title!,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -78,7 +86,8 @@ class PremiumPlanCard extends StatelessWidget {
|
|||||||
borderRadius: BorderRadius.circular(99.0),
|
borderRadius: BorderRadius.circular(99.0),
|
||||||
),
|
),
|
||||||
margin: const EdgeInsets.all(4.0),
|
margin: const EdgeInsets.all(4.0),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
child: const Text(
|
child: const Text(
|
||||||
"Aktív",
|
"Aktív",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
@ -95,10 +104,16 @@ class PremiumPlanCard extends StatelessWidget {
|
|||||||
TextSpan(text: "\$$price"),
|
TextSpan(text: "\$$price"),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: " / hó",
|
text: " / hó",
|
||||||
style: TextStyle(color: Theme.of(context).textTheme.bodyMedium!.color!.withOpacity(.7)),
|
style: TextStyle(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium!
|
||||||
|
.color!
|
||||||
|
.withOpacity(.7)),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 24.0),
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, fontSize: 24.0),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -108,13 +123,15 @@ class PremiumPlanCard extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
if (icon != null) ...[
|
if (icon != null) ...[
|
||||||
IconTheme(
|
IconTheme(
|
||||||
data: Theme.of(context).iconTheme.copyWith(size: 24.0, color: AppColors.of(context).text),
|
data: Theme.of(context).iconTheme.copyWith(
|
||||||
|
size: 24.0, color: AppColors.of(context).text),
|
||||||
child: icon!,
|
child: icon!,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
const SizedBox(width: 12.0),
|
const SizedBox(width: 12.0),
|
||||||
DefaultTextStyle(
|
DefaultTextStyle(
|
||||||
style: Theme.of(context).textTheme.displaySmall!.copyWith(fontWeight: FontWeight.bold, fontSize: 25.0),
|
style: Theme.of(context).textTheme.displaySmall!.copyWith(
|
||||||
|
fontWeight: FontWeight.bold, fontSize: 25.0),
|
||||||
child: title!,
|
child: title!,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -123,10 +140,13 @@ class PremiumPlanCard extends StatelessWidget {
|
|||||||
const SizedBox(height: 6.0),
|
const SizedBox(height: 6.0),
|
||||||
if (description != null)
|
if (description != null)
|
||||||
DefaultTextStyle(
|
DefaultTextStyle(
|
||||||
style: Theme.of(context)
|
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium!
|
.bodyMedium!
|
||||||
.copyWith(color: Theme.of(context).textTheme.bodyMedium!.color!.withOpacity(.8), fontSize: 18),
|
.color!
|
||||||
|
.withOpacity(.8),
|
||||||
|
fontSize: 18),
|
||||||
child: description!,
|
child: description!,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class PremiumRewardCard extends StatelessWidget {
|
class PremiumRewardCard extends StatelessWidget {
|
||||||
const PremiumRewardCard({Key? key, this.imageKey, this.icon, this.title, this.description, this.soon = false}) : super(key: key);
|
const PremiumRewardCard(
|
||||||
|
{super.key,
|
||||||
|
this.imageKey,
|
||||||
|
this.icon,
|
||||||
|
this.title,
|
||||||
|
this.description,
|
||||||
|
this.soon = false});
|
||||||
|
|
||||||
final String? imageKey;
|
final String? imageKey;
|
||||||
final Widget? icon;
|
final Widget? icon;
|
||||||
@ -24,12 +30,14 @@ class PremiumRewardCard extends StatelessWidget {
|
|||||||
labelPadding: EdgeInsets.zero,
|
labelPadding: EdgeInsets.zero,
|
||||||
padding: EdgeInsets.symmetric(horizontal: 12.0),
|
padding: EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
backgroundColor: Color(0x777645D3),
|
backgroundColor: Color(0x777645D3),
|
||||||
label: Text("Hamarosan", style: TextStyle(fontWeight: FontWeight.w500)),
|
label: Text("Hamarosan",
|
||||||
|
style: TextStyle(fontWeight: FontWeight.w500)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (imageKey != null)
|
if (imageKey != null)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 14.0).add(EdgeInsets.only(bottom: 12.0, top: soon ? 0 : 14.0)),
|
padding: const EdgeInsets.symmetric(horizontal: 14.0)
|
||||||
|
.add(EdgeInsets.only(bottom: 12.0, top: soon ? 0 : 14.0)),
|
||||||
child: Image.asset("assets/images/${imageKey!}.png"),
|
child: Image.asset("assets/images/${imageKey!}.png"),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
@ -42,7 +50,10 @@ class PremiumRewardCard extends StatelessWidget {
|
|||||||
if (title != null)
|
if (title != null)
|
||||||
Expanded(
|
Expanded(
|
||||||
child: DefaultTextStyle(
|
child: DefaultTextStyle(
|
||||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(fontWeight: FontWeight.w700, fontSize: 20),
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium!
|
||||||
|
.copyWith(fontWeight: FontWeight.w700, fontSize: 20),
|
||||||
child: title!,
|
child: title!,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -51,9 +62,13 @@ class PremiumRewardCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
if (description != null)
|
if (description != null)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12.0).add(const EdgeInsets.only(top: 4.0, bottom: 12.0)),
|
padding: const EdgeInsets.symmetric(horizontal: 12.0)
|
||||||
|
.add(const EdgeInsets.only(top: 4.0, bottom: 12.0)),
|
||||||
child: DefaultTextStyle(
|
child: DefaultTextStyle(
|
||||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(fontSize: 16),
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium!
|
||||||
|
.copyWith(fontSize: 16),
|
||||||
child: description!,
|
child: description!,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -2,7 +2,7 @@ import 'package:filcnaplo/models/supporter.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class SupporterChip extends StatelessWidget {
|
class SupporterChip extends StatelessWidget {
|
||||||
const SupporterChip({Key? key, required this.supporter}) : super(key: key);
|
const SupporterChip({super.key, required this.supporter});
|
||||||
|
|
||||||
final Supporter supporter;
|
final Supporter supporter;
|
||||||
|
|
||||||
|
@ -5,13 +5,13 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
class SupporterGroupCard extends StatelessWidget {
|
class SupporterGroupCard extends StatelessWidget {
|
||||||
const SupporterGroupCard({
|
const SupporterGroupCard({
|
||||||
Key? key,
|
super.key,
|
||||||
this.title,
|
this.title,
|
||||||
this.icon,
|
this.icon,
|
||||||
this.expanded = false,
|
this.expanded = false,
|
||||||
this.supporters = const [],
|
this.supporters = const [],
|
||||||
this.glow,
|
this.glow,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
final Widget? icon;
|
final Widget? icon;
|
||||||
final Widget? title;
|
final Widget? title;
|
||||||
@ -34,7 +34,8 @@ class SupporterGroupCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
child: Card(
|
child: Card(
|
||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
|
shape:
|
||||||
|
RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(24.0),
|
padding: const EdgeInsets.all(24.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -46,7 +47,10 @@ class SupporterGroupCard extends StatelessWidget {
|
|||||||
if (title != null)
|
if (title != null)
|
||||||
Expanded(
|
Expanded(
|
||||||
child: DefaultTextStyle(
|
child: DefaultTextStyle(
|
||||||
style: Theme.of(context).textTheme.titleLarge!.copyWith(fontWeight: FontWeight.w700),
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleLarge!
|
||||||
|
.copyWith(fontWeight: FontWeight.w700),
|
||||||
child: title!,
|
child: title!,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -55,12 +59,16 @@ class SupporterGroupCard extends StatelessWidget {
|
|||||||
const SizedBox(height: 12.0),
|
const SizedBox(height: 12.0),
|
||||||
if (expanded)
|
if (expanded)
|
||||||
Column(
|
Column(
|
||||||
children: supporters.map((e) => SupporterTile(supporter: e)).toList(),
|
children: supporters
|
||||||
|
.map((e) => SupporterTile(supporter: e))
|
||||||
|
.toList(),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
Wrap(
|
Wrap(
|
||||||
spacing: 8.0,
|
spacing: 8.0,
|
||||||
children: supporters.map((e) => SupporterChip(supporter: e)).toList(),
|
children: supporters
|
||||||
|
.map((e) => SupporterChip(supporter: e))
|
||||||
|
.toList(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -2,7 +2,7 @@ import 'package:filcnaplo/models/supporter.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class SupporterTile extends StatelessWidget {
|
class SupporterTile extends StatelessWidget {
|
||||||
const SupporterTile({Key? key, required this.supporter}) : super(key: key);
|
const SupporterTile({super.key, required this.supporter});
|
||||||
|
|
||||||
final Supporter supporter;
|
final Supporter supporter;
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import 'package:filcnaplo_mobile_ui/premium/supporters_screen.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class SupportersButton extends StatelessWidget {
|
class SupportersButton extends StatelessWidget {
|
||||||
const SupportersButton({Key? key, required this.supporters}) : super(key: key);
|
const SupportersButton({super.key, required this.supporters});
|
||||||
|
|
||||||
final Future<Supporters?> supporters;
|
final Future<Supporters?> supporters;
|
||||||
|
|
||||||
@ -19,7 +19,8 @@ class SupportersButton extends StatelessWidget {
|
|||||||
customBorder: const StadiumBorder(),
|
customBorder: const StadiumBorder(),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).push(
|
Navigator.of(context).push(
|
||||||
MaterialPageRoute(builder: (context) => SupportersScreen(supporters: supporters)),
|
MaterialPageRoute(
|
||||||
|
builder: (context) => SupportersScreen(supporters: supporters)),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -38,24 +39,35 @@ class SupportersButton extends StatelessWidget {
|
|||||||
if (!snapshot.hasData) {
|
if (!snapshot.hasData) {
|
||||||
return const SizedBox();
|
return const SizedBox();
|
||||||
}
|
}
|
||||||
final sponsors = snapshot.data!.github.where((e) => e.type == DonationType.monthly).toList();
|
final sponsors = snapshot.data!.github
|
||||||
sponsors.shuffle(Random((DateTime.now().millisecondsSinceEpoch / 1000 / 60 / 60 / 24).floor()));
|
.where((e) => e.type == DonationType.monthly)
|
||||||
|
.toList();
|
||||||
|
sponsors.shuffle(Random(
|
||||||
|
(DateTime.now().millisecondsSinceEpoch /
|
||||||
|
1000 /
|
||||||
|
60 /
|
||||||
|
60 /
|
||||||
|
24)
|
||||||
|
.floor()));
|
||||||
return AvatarStack(
|
return AvatarStack(
|
||||||
children: [
|
children: [
|
||||||
// ignore: prefer_is_empty
|
// ignore: prefer_is_empty
|
||||||
if (sponsors.length > 0 && sponsors[0].avatar != "")
|
if (sponsors.length > 0 && sponsors[0].avatar != "")
|
||||||
CircleAvatar(
|
CircleAvatar(
|
||||||
backgroundColor: Theme.of(context).colorScheme.secondary,
|
backgroundColor:
|
||||||
|
Theme.of(context).colorScheme.secondary,
|
||||||
backgroundImage: NetworkImage(sponsors[0].avatar),
|
backgroundImage: NetworkImage(sponsors[0].avatar),
|
||||||
),
|
),
|
||||||
if (sponsors.length > 1 && sponsors[1].avatar != "")
|
if (sponsors.length > 1 && sponsors[1].avatar != "")
|
||||||
CircleAvatar(
|
CircleAvatar(
|
||||||
backgroundColor: Theme.of(context).colorScheme.secondary,
|
backgroundColor:
|
||||||
|
Theme.of(context).colorScheme.secondary,
|
||||||
backgroundImage: NetworkImage(sponsors[1].avatar),
|
backgroundImage: NetworkImage(sponsors[1].avatar),
|
||||||
),
|
),
|
||||||
if (sponsors.length > 2 && sponsors[2].avatar != "")
|
if (sponsors.length > 2 && sponsors[2].avatar != "")
|
||||||
CircleAvatar(
|
CircleAvatar(
|
||||||
backgroundColor: Theme.of(context).colorScheme.secondary,
|
backgroundColor:
|
||||||
|
Theme.of(context).colorScheme.secondary,
|
||||||
backgroundImage: NetworkImage(sponsors[2].avatar),
|
backgroundImage: NetworkImage(sponsors[2].avatar),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:animations/animations.dart';
|
import 'package:animations/animations.dart';
|
||||||
|
|
||||||
class PremiumButton extends StatefulWidget {
|
class PremiumButton extends StatefulWidget {
|
||||||
const PremiumButton({Key? key}) : super(key: key);
|
const PremiumButton({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<PremiumButton> createState() => _PremiumButtonState();
|
State<PremiumButton> createState() => _PremiumButtonState();
|
||||||
|
@ -17,7 +17,7 @@ import 'package:flutter_svg/svg.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class PremiumScreen extends StatelessWidget {
|
class PremiumScreen extends StatelessWidget {
|
||||||
const PremiumScreen({Key? key}) : super(key: key);
|
const PremiumScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -6,7 +6,7 @@ import 'package:filcnaplo_mobile_ui/premium/styles/gradients.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class SupportersScreen extends StatelessWidget {
|
class SupportersScreen extends StatelessWidget {
|
||||||
const SupportersScreen({Key? key, required this.supporters}) : super(key: key);
|
const SupportersScreen({super.key, required this.supporters});
|
||||||
|
|
||||||
final Future<Supporters?> supporters;
|
final Future<Supporters?> supporters;
|
||||||
|
|
||||||
@ -15,12 +15,28 @@ class SupportersScreen extends StatelessWidget {
|
|||||||
return FutureBuilder<Supporters?>(
|
return FutureBuilder<Supporters?>(
|
||||||
future: supporters,
|
future: supporters,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
final highlightedSupporters =
|
final highlightedSupporters = snapshot.data?.github
|
||||||
snapshot.data?.github.where((e) => e.type == DonationType.monthly && e.price >= 5 && e.comment != "").toList() ?? [];
|
.where((e) =>
|
||||||
final tintaSupporters =
|
e.type == DonationType.monthly &&
|
||||||
snapshot.data?.github.where((e) => e.type == DonationType.monthly && e.price >= 5 && e.comment == "").toList() ?? [];
|
e.price >= 5 &&
|
||||||
final kupakSupporters = snapshot.data?.github.where((e) => e.type == DonationType.monthly && e.price == 2).toList() ?? [];
|
e.comment != "")
|
||||||
final onetimeSupporters = snapshot.data?.github.where((e) => e.type == DonationType.once && e.price >= 5).toList() ?? [];
|
.toList() ??
|
||||||
|
[];
|
||||||
|
final tintaSupporters = snapshot.data?.github
|
||||||
|
.where((e) =>
|
||||||
|
e.type == DonationType.monthly &&
|
||||||
|
e.price >= 5 &&
|
||||||
|
e.comment == "")
|
||||||
|
.toList() ??
|
||||||
|
[];
|
||||||
|
final kupakSupporters = snapshot.data?.github
|
||||||
|
.where((e) => e.type == DonationType.monthly && e.price == 2)
|
||||||
|
.toList() ??
|
||||||
|
[];
|
||||||
|
final onetimeSupporters = snapshot.data?.github
|
||||||
|
.where((e) => e.type == DonationType.once && e.price >= 5)
|
||||||
|
.toList() ??
|
||||||
|
[];
|
||||||
final patreonSupporters = snapshot.data?.patreon ?? [];
|
final patreonSupporters = snapshot.data?.patreon ?? [];
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@ -35,11 +51,15 @@ class SupportersScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
if (snapshot.hasData)
|
if (snapshot.hasData)
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0).add(const EdgeInsets.only(bottom: 24.0)),
|
padding: const EdgeInsets.symmetric(horizontal: 16.0)
|
||||||
|
.add(const EdgeInsets.only(bottom: 24.0)),
|
||||||
sliver: SliverToBoxAdapter(
|
sliver: SliverToBoxAdapter(
|
||||||
child: Text(
|
child: Text(
|
||||||
snapshot.data!.description,
|
snapshot.data!.description,
|
||||||
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20.0, color: AppColors.of(context).text.withOpacity(.7)),
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 20.0,
|
||||||
|
color: AppColors.of(context).text.withOpacity(.7)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -86,7 +106,8 @@ class SupportersScreen extends StatelessWidget {
|
|||||||
icon: const Icon(FilcIcons.kupak),
|
icon: const Icon(FilcIcons.kupak),
|
||||||
title: Text(
|
title: Text(
|
||||||
"Kupak",
|
"Kupak",
|
||||||
style: TextStyle(foreground: GradientStyles.kupakPaint),
|
style:
|
||||||
|
TextStyle(foreground: GradientStyles.kupakPaint),
|
||||||
),
|
),
|
||||||
glow: Colors.lightGreen,
|
glow: Colors.lightGreen,
|
||||||
supporters: kupakSupporters,
|
supporters: kupakSupporters,
|
||||||
|
@ -9,7 +9,7 @@ import 'error_report_screen.i18n.dart';
|
|||||||
class ErrorReportScreen extends StatelessWidget {
|
class ErrorReportScreen extends StatelessWidget {
|
||||||
final FlutterErrorDetails details;
|
final FlutterErrorDetails details;
|
||||||
|
|
||||||
const ErrorReportScreen(this.details, {Key? key}) : super(key: key);
|
const ErrorReportScreen(this.details, {super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -21,8 +21,8 @@ class ErrorReportScreen extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
const Align(
|
const Align(
|
||||||
child: BackButton(),
|
|
||||||
alignment: Alignment.topLeft,
|
alignment: Alignment.topLeft,
|
||||||
|
child: BackButton(),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
const Icon(
|
const Icon(
|
||||||
@ -57,7 +57,9 @@ class ErrorReportScreen extends StatelessWidget {
|
|||||||
height: 110.0,
|
height: 110.0,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
padding: const EdgeInsets.all(12.0),
|
padding: const EdgeInsets.all(12.0),
|
||||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(12.0), color: Colors.black.withOpacity(.2)),
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
color: Colors.black.withOpacity(.2)),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
physics: const BouncingScrollPhysics(),
|
physics: const BouncingScrollPhysics(),
|
||||||
child: Text(
|
child: Text(
|
||||||
@ -69,7 +71,9 @@ class ErrorReportScreen extends StatelessWidget {
|
|||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(FeatherIcons.info),
|
icon: const Icon(FeatherIcons.info),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showDialog(context: context, builder: (context) => StacktracePopup(details));
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => StacktracePopup(details));
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@ -79,10 +83,12 @@ class ErrorReportScreen extends StatelessWidget {
|
|||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
padding: MaterialStateProperty.all(const EdgeInsets.symmetric(vertical: 14.0)),
|
padding: MaterialStateProperty.all(
|
||||||
|
const EdgeInsets.symmetric(vertical: 14.0)),
|
||||||
backgroundColor: MaterialStateProperty.all(Colors.white),
|
backgroundColor: MaterialStateProperty.all(Colors.white),
|
||||||
shape: MaterialStateProperty.all(
|
shape: MaterialStateProperty.all(
|
||||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
|
RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12.0)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
@ -106,7 +112,7 @@ class ErrorReportScreen extends StatelessWidget {
|
|||||||
|
|
||||||
Future reportProblem(BuildContext context) async {
|
Future reportProblem(BuildContext context) async {
|
||||||
final report = ErrorReport(
|
final report = ErrorReport(
|
||||||
os: Platform.operatingSystem + " " + Platform.operatingSystemVersion,
|
os: "${Platform.operatingSystem} ${Platform.operatingSystemVersion}",
|
||||||
error: details.exceptionAsString(),
|
error: details.exceptionAsString(),
|
||||||
version: const String.fromEnvironment("APPVER", defaultValue: "?"),
|
version: const String.fromEnvironment("APPVER", defaultValue: "?"),
|
||||||
stack: details.stack.toString(),
|
stack: details.stack.toString(),
|
||||||
@ -119,7 +125,7 @@ class ErrorReportScreen extends StatelessWidget {
|
|||||||
class StacktracePopup extends StatelessWidget {
|
class StacktracePopup extends StatelessWidget {
|
||||||
final FlutterErrorDetails details;
|
final FlutterErrorDetails details;
|
||||||
|
|
||||||
const StacktracePopup(this.details, {Key? key}) : super(key: key);
|
const StacktracePopup(this.details, {super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -150,13 +156,20 @@ class StacktracePopup extends StatelessWidget {
|
|||||||
"error".i18n,
|
"error".i18n,
|
||||||
details.exceptionAsString(),
|
details.exceptionAsString(),
|
||||||
),
|
),
|
||||||
ErrorDetail("os".i18n, Platform.operatingSystem + " " + Platform.operatingSystemVersion),
|
ErrorDetail("os".i18n,
|
||||||
ErrorDetail("version".i18n, const String.fromEnvironment("APPVER", defaultValue: "?")),
|
"${Platform.operatingSystem} ${Platform.operatingSystemVersion}"),
|
||||||
ErrorDetail("stack".i18n, stack.substring(0, min(stack.length, 5000)))
|
ErrorDetail(
|
||||||
|
"version".i18n,
|
||||||
|
const String.fromEnvironment("APPVER",
|
||||||
|
defaultValue: "?")),
|
||||||
|
ErrorDetail(
|
||||||
|
"stack".i18n, stack.substring(0, min(stack.length, 5000)))
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
child: Text("done".i18n, style: TextStyle(color: Theme.of(context).colorScheme.secondary)),
|
child: Text("done".i18n,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.secondary)),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
})
|
})
|
||||||
@ -172,7 +185,7 @@ class ErrorDetail extends StatelessWidget {
|
|||||||
final String title;
|
final String title;
|
||||||
final String content;
|
final String content;
|
||||||
|
|
||||||
const ErrorDetail(this.title, this.content, {Key? key}) : super(key: key);
|
const ErrorDetail(this.title, this.content, {super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -186,13 +199,17 @@ class ErrorDetail extends StatelessWidget {
|
|||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 6.5, vertical: 4.0),
|
||||||
|
margin: const EdgeInsets.only(top: 4.0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.black26,
|
||||||
|
borderRadius: BorderRadius.circular(4.0)),
|
||||||
child: Text(
|
child: Text(
|
||||||
content,
|
content,
|
||||||
style: const TextStyle(fontFamily: 'SpaceMono', color: Colors.white),
|
style: const TextStyle(
|
||||||
),
|
fontFamily: 'SpaceMono', color: Colors.white),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6.5, vertical: 4.0),
|
))
|
||||||
margin: const EdgeInsets.only(top: 4.0),
|
|
||||||
decoration: BoxDecoration(color: Colors.black26, borderRadius: BorderRadius.circular(4.0)))
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
|
|
||||||
class ErrorScreen extends StatelessWidget {
|
class ErrorScreen extends StatelessWidget {
|
||||||
const ErrorScreen(this.details, {Key? key}) : super(key: key);
|
const ErrorScreen(this.details, {super.key});
|
||||||
|
|
||||||
final FlutterErrorDetails details;
|
final FlutterErrorDetails details;
|
||||||
|
|
||||||
@ -23,7 +23,8 @@ class ErrorScreen extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(12.0),
|
padding: const EdgeInsets.all(12.0),
|
||||||
child: Icon(FeatherIcons.alertTriangle, size: 48.0, color: AppColors.of(context).red),
|
child: Icon(FeatherIcons.alertTriangle,
|
||||||
|
size: 48.0, color: AppColors.of(context).red),
|
||||||
),
|
),
|
||||||
const Padding(
|
const Padding(
|
||||||
padding: EdgeInsets.all(12.0),
|
padding: EdgeInsets.all(12.0),
|
||||||
@ -47,7 +48,7 @@ class ErrorScreen extends StatelessWidget {
|
|||||||
physics: const BouncingScrollPhysics(),
|
physics: const BouncingScrollPhysics(),
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
child: SelectableText(
|
child: SelectableText(
|
||||||
(details.exceptionAsString() + '\n'),
|
('${details.exceptionAsString()}\n'),
|
||||||
style: const TextStyle(fontFamily: "monospace"),
|
style: const TextStyle(fontFamily: "monospace"),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class LoginButton extends StatelessWidget {
|
class LoginButton extends StatelessWidget {
|
||||||
const LoginButton({Key? key, required this.onPressed, required this.child}) : super(key: key);
|
const LoginButton({super.key, required this.onPressed, required this.child});
|
||||||
|
|
||||||
final void Function()? onPressed;
|
final void Function()? onPressed;
|
||||||
final Widget? child;
|
final Widget? child;
|
||||||
@ -9,12 +9,6 @@ class LoginButton extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialButton(
|
return MaterialButton(
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
vertical: 15.0,
|
|
||||||
),
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
focusElevation: 0,
|
focusElevation: 0,
|
||||||
hoverElevation: 0,
|
hoverElevation: 0,
|
||||||
@ -24,6 +18,12 @@ class LoginButton extends StatelessWidget {
|
|||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
textColor: Colors.black,
|
textColor: Colors.black,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 15.0,
|
||||||
|
),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,11 @@ enum LoginInputStyle { username, password, school }
|
|||||||
|
|
||||||
class LoginInput extends StatefulWidget {
|
class LoginInput extends StatefulWidget {
|
||||||
const LoginInput(
|
const LoginInput(
|
||||||
{Key? key,
|
{super.key,
|
||||||
required this.style,
|
required this.style,
|
||||||
this.controller,
|
this.controller,
|
||||||
this.focusNode,
|
this.focusNode,
|
||||||
this.onClear})
|
this.onClear});
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
final Function()? onClear;
|
final Function()? onClear;
|
||||||
final LoginInputStyle style;
|
final LoginInputStyle style;
|
||||||
|
@ -14,15 +14,15 @@ import 'package:flutter/services.dart';
|
|||||||
import 'login_screen.i18n.dart';
|
import 'login_screen.i18n.dart';
|
||||||
|
|
||||||
class LoginScreen extends StatefulWidget {
|
class LoginScreen extends StatefulWidget {
|
||||||
const LoginScreen({Key? key, this.back = false}) : super(key: key);
|
const LoginScreen({super.key, this.back = false});
|
||||||
|
|
||||||
final bool back;
|
final bool back;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_LoginScreenState createState() => _LoginScreenState();
|
LoginScreenState createState() => LoginScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _LoginScreenState extends State<LoginScreen> {
|
class LoginScreenState extends State<LoginScreen> {
|
||||||
final usernameController = TextEditingController();
|
final usernameController = TextEditingController();
|
||||||
final passwordController = TextEditingController();
|
final passwordController = TextEditingController();
|
||||||
final schoolController = SchoolInputController();
|
final schoolController = SchoolInputController();
|
||||||
@ -109,15 +109,19 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
child: ClipRect(
|
child: ClipRect(
|
||||||
child: Container(
|
child: Container(
|
||||||
// Png shadow *hack*
|
// Png shadow *hack*
|
||||||
|
width: MediaQuery.of(context).size.width / 4,
|
||||||
|
margin: const EdgeInsets.only(
|
||||||
|
left: 12.0, right: 12.0, bottom: 12.0),
|
||||||
|
// Png shadow *hack*
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 8.0),
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
child: Opacity(
|
child: Opacity(
|
||||||
|
opacity: 0.3,
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
"assets/icons/ic_splash.png",
|
"assets/icons/ic_splash.png",
|
||||||
color: Colors.black),
|
color: Colors.black)),
|
||||||
opacity: 0.3),
|
|
||||||
),
|
),
|
||||||
BackdropFilter(
|
BackdropFilter(
|
||||||
filter:
|
filter:
|
||||||
@ -126,9 +130,6 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
width: MediaQuery.of(context).size.width / 4,
|
|
||||||
margin: const EdgeInsets.only(
|
|
||||||
left: 12.0, right: 12.0, bottom: 12.0),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -246,6 +247,14 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 42.0),
|
padding: const EdgeInsets.only(top: 42.0),
|
||||||
child: Visibility(
|
child: Visibility(
|
||||||
|
visible: _loginState != LoginState.inProgress,
|
||||||
|
replacement: const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 6.0),
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
valueColor:
|
||||||
|
AlwaysStoppedAnimation<Color>(Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
child: LoginButton(
|
child: LoginButton(
|
||||||
child: Text("login".i18n,
|
child: Text("login".i18n,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
@ -255,14 +264,6 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
)),
|
)),
|
||||||
onPressed: () => _loginAPI(context: context),
|
onPressed: () => _loginAPI(context: context),
|
||||||
),
|
),
|
||||||
visible: _loginState != LoginState.inProgress,
|
|
||||||
replacement: const Padding(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 6.0),
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
valueColor:
|
|
||||||
AlwaysStoppedAnimation<Color>(Colors.white),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (_loginState == LoginState.missingFields ||
|
if (_loginState == LoginState.missingFields ||
|
||||||
@ -306,6 +307,7 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
return setState(() => _loginState = LoginState.missingFields);
|
return setState(() => _loginState = LoginState.missingFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignore: no_leading_underscores_for_local_identifiers
|
||||||
void _callAPI() {
|
void _callAPI() {
|
||||||
loginAPI(
|
loginAPI(
|
||||||
username: username,
|
username: username,
|
||||||
|
@ -6,16 +6,17 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:filcnaplo_kreta_api/models/school.dart';
|
import 'package:filcnaplo_kreta_api/models/school.dart';
|
||||||
|
|
||||||
class SchoolInput extends StatefulWidget {
|
class SchoolInput extends StatefulWidget {
|
||||||
const SchoolInput({Key? key, required this.controller, required this.scroll}) : super(key: key);
|
const SchoolInput(
|
||||||
|
{super.key, required this.controller, required this.scroll});
|
||||||
|
|
||||||
final SchoolInputController controller;
|
final SchoolInputController controller;
|
||||||
final ScrollController scroll;
|
final ScrollController scroll;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_SchoolInputState createState() => _SchoolInputState();
|
SchoolInputState createState() => SchoolInputState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SchoolInputState extends State<SchoolInput> {
|
class SchoolInputState extends State<SchoolInput> {
|
||||||
final _focusNode = FocusNode();
|
final _focusNode = FocusNode();
|
||||||
final _layerLink = LayerLink();
|
final _layerLink = LayerLink();
|
||||||
late SchoolInputOverlay overlay;
|
late SchoolInputOverlay overlay;
|
||||||
@ -33,10 +34,13 @@ class _SchoolInputState extends State<SchoolInput> {
|
|||||||
// Show school list when focused
|
// Show school list when focused
|
||||||
_focusNode.addListener(() {
|
_focusNode.addListener(() {
|
||||||
if (_focusNode.hasFocus) {
|
if (_focusNode.hasFocus) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) => overlay.createOverlayEntry(context));
|
WidgetsBinding.instance
|
||||||
|
.addPostFrameCallback((_) => overlay.createOverlayEntry(context));
|
||||||
Future.delayed(const Duration(milliseconds: 100)).then((value) {
|
Future.delayed(const Duration(milliseconds: 100)).then((value) {
|
||||||
if (mounted && widget.scroll.hasClients) {
|
if (mounted && widget.scroll.hasClients) {
|
||||||
widget.scroll.animateTo(widget.scroll.offset + 500, duration: const Duration(milliseconds: 500), curve: Curves.ease);
|
widget.scroll.animateTo(widget.scroll.offset + 500,
|
||||||
|
duration: const Duration(milliseconds: 500),
|
||||||
|
curve: Curves.ease);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -52,7 +56,8 @@ class _SchoolInputState extends State<SchoolInput> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<School> results = searchSchools(widget.controller.schools ?? [], text);
|
List<School> results =
|
||||||
|
searchSchools(widget.controller.schools ?? [], text);
|
||||||
setState(() {
|
setState(() {
|
||||||
overlay.children = results
|
overlay.children = results
|
||||||
.map((School e) => SchoolInputTile(
|
.map((School e) => SchoolInputTile(
|
||||||
|
@ -17,20 +17,20 @@ class SchoolInputOverlay {
|
|||||||
RenderBox renderBox = context.findRenderObject()! as RenderBox;
|
RenderBox renderBox = context.findRenderObject()! as RenderBox;
|
||||||
var size = renderBox.size;
|
var size = renderBox.size;
|
||||||
return SchoolInputOverlayWidget(
|
return SchoolInputOverlayWidget(
|
||||||
children: children,
|
|
||||||
size: size,
|
size: size,
|
||||||
layerLink: layerLink,
|
layerLink: layerLink,
|
||||||
|
children: children,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SchoolInputOverlayWidget extends StatelessWidget {
|
class SchoolInputOverlayWidget extends StatelessWidget {
|
||||||
const SchoolInputOverlayWidget({
|
const SchoolInputOverlayWidget({
|
||||||
Key? key,
|
super.key,
|
||||||
required this.children,
|
required this.children,
|
||||||
required this.size,
|
required this.size,
|
||||||
required this.layerLink,
|
required this.layerLink,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
final Size size;
|
final Size size;
|
||||||
final List<Widget>? children;
|
final List<Widget>? children;
|
||||||
@ -48,7 +48,8 @@ class SchoolInputOverlayWidget extends StatelessWidget {
|
|||||||
offset: Offset(0.0, size.height + 5.0),
|
offset: Offset(0.0, size.height + 5.0),
|
||||||
child: Material(
|
child: Material(
|
||||||
color: Theme.of(context).colorScheme.background,
|
color: Theme.of(context).colorScheme.background,
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8.0)),
|
||||||
elevation: 4.0,
|
elevation: 4.0,
|
||||||
shadowColor: Colors.black,
|
shadowColor: Colors.black,
|
||||||
child: (children?.length ?? 0) > 0
|
child: (children?.length ?? 0) > 0
|
||||||
|
@ -2,8 +2,7 @@ import 'package:filcnaplo_kreta_api/models/school.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class SchoolInputTile extends StatelessWidget {
|
class SchoolInputTile extends StatelessWidget {
|
||||||
const SchoolInputTile({Key? key, required this.school, this.onTap})
|
const SchoolInputTile({super.key, required this.school, this.onTap});
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
final School school;
|
final School school;
|
||||||
final Function()? onTap;
|
final Function()? onTap;
|
||||||
|
@ -2,7 +2,11 @@ import 'package:filcnaplo_mobile_ui/screens/navigation/navbar_item.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class Navbar extends StatelessWidget {
|
class Navbar extends StatelessWidget {
|
||||||
const Navbar({Key? key, required this.selectedIndex, required this.onSelected, required this.items}) : super(key: key);
|
const Navbar(
|
||||||
|
{super.key,
|
||||||
|
required this.selectedIndex,
|
||||||
|
required this.onSelected,
|
||||||
|
required this.items});
|
||||||
|
|
||||||
final int selectedIndex;
|
final int selectedIndex;
|
||||||
final void Function(int index) onSelected;
|
final void Function(int index) onSelected;
|
||||||
|
@ -11,11 +11,11 @@ class NavItem {
|
|||||||
|
|
||||||
class NavbarItem extends StatelessWidget {
|
class NavbarItem extends StatelessWidget {
|
||||||
const NavbarItem({
|
const NavbarItem({
|
||||||
Key? key,
|
super.key,
|
||||||
required this.item,
|
required this.item,
|
||||||
required this.active,
|
required this.active,
|
||||||
required this.onTap,
|
required this.onTap,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
final NavItem item;
|
final NavItem item;
|
||||||
final bool active;
|
final bool active;
|
||||||
|
@ -29,7 +29,7 @@ import 'package:filcnaplo_premium/providers/goal_provider.dart';
|
|||||||
import 'package:filcnaplo/api/providers/ad_provider.dart';
|
import 'package:filcnaplo/api/providers/ad_provider.dart';
|
||||||
|
|
||||||
class NavigationScreen extends StatefulWidget {
|
class NavigationScreen extends StatefulWidget {
|
||||||
const NavigationScreen({Key? key}) : super(key: key);
|
const NavigationScreen({super.key});
|
||||||
|
|
||||||
static NavigationScreenState? of(BuildContext context) =>
|
static NavigationScreenState? of(BuildContext context) =>
|
||||||
context.findAncestorStateOfType<NavigationScreenState>();
|
context.findAncestorStateOfType<NavigationScreenState>();
|
||||||
@ -234,6 +234,7 @@ class NavigationScreenState extends State<NavigationScreen>
|
|||||||
_navigatorState.currentState?.pushReplacementNamed(page);
|
_navigatorState.currentState?.pushReplacementNamed(page);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ignore: deprecated_member_use
|
||||||
return WillPopScope(
|
return WillPopScope(
|
||||||
onWillPop: () async {
|
onWillPop: () async {
|
||||||
if (_navigatorState.currentState?.canPop() ?? false) {
|
if (_navigatorState.currentState?.canPop() ?? false) {
|
||||||
|
@ -6,13 +6,13 @@ import 'package:filcnaplo/api/providers/status_provider.dart';
|
|||||||
import 'status_bar.i18n.dart';
|
import 'status_bar.i18n.dart';
|
||||||
|
|
||||||
class StatusBar extends StatefulWidget {
|
class StatusBar extends StatefulWidget {
|
||||||
const StatusBar({Key? key}) : super(key: key);
|
const StatusBar({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_StatusBarState createState() => _StatusBarState();
|
StatusBarState createState() => StatusBarState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _StatusBarState extends State<StatusBar> {
|
class StatusBarState extends State<StatusBar> {
|
||||||
late StatusProvider statusProvider;
|
late StatusProvider statusProvider;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -12,7 +12,7 @@ import 'package:provider/provider.dart';
|
|||||||
import 'package:filcnaplo/api/providers/news_provider.dart';
|
import 'package:filcnaplo/api/providers/news_provider.dart';
|
||||||
|
|
||||||
class NewsScreen extends StatelessWidget {
|
class NewsScreen extends StatelessWidget {
|
||||||
const NewsScreen({Key? key}) : super(key: key);
|
const NewsScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -3,7 +3,7 @@ import 'package:filcnaplo/models/news.dart';
|
|||||||
import 'package:filcnaplo/utils/format.dart';
|
import 'package:filcnaplo/utils/format.dart';
|
||||||
|
|
||||||
class NewsTile extends StatelessWidget {
|
class NewsTile extends StatelessWidget {
|
||||||
const NewsTile(this.news, {Key? key, this.onTap}) : super(key: key);
|
const NewsTile(this.news, {super.key, this.onTap});
|
||||||
|
|
||||||
final News news;
|
final News news;
|
||||||
final Function()? onTap;
|
final Function()? onTap;
|
||||||
|
@ -11,7 +11,7 @@ import 'package:provider/provider.dart';
|
|||||||
import 'package:filcnaplo_mobile_ui/screens/settings/settings_screen.i18n.dart';
|
import 'package:filcnaplo_mobile_ui/screens/settings/settings_screen.i18n.dart';
|
||||||
|
|
||||||
class NewsView extends StatelessWidget {
|
class NewsView extends StatelessWidget {
|
||||||
const NewsView(this.news, {Key? key}) : super(key: key);
|
const NewsView(this.news, {super.key});
|
||||||
|
|
||||||
final News news;
|
final News news;
|
||||||
|
|
||||||
|
@ -3,7 +3,13 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
|
|
||||||
class AccountTile extends StatelessWidget {
|
class AccountTile extends StatelessWidget {
|
||||||
const AccountTile({Key? key, this.onTap, this.onTapMenu, this.profileImage, this.name, this.username}) : super(key: key);
|
const AccountTile(
|
||||||
|
{super.key,
|
||||||
|
this.onTap,
|
||||||
|
this.onTapMenu,
|
||||||
|
this.profileImage,
|
||||||
|
this.name,
|
||||||
|
this.username});
|
||||||
|
|
||||||
final void Function()? onTap;
|
final void Function()? onTap;
|
||||||
final void Function()? onTapMenu;
|
final void Function()? onTapMenu;
|
||||||
@ -30,7 +36,8 @@ class AccountTile extends StatelessWidget {
|
|||||||
child: IconButton(
|
child: IconButton(
|
||||||
splashRadius: 24.0,
|
splashRadius: 24.0,
|
||||||
onPressed: onTapMenu,
|
onPressed: onTapMenu,
|
||||||
icon: Icon(FeatherIcons.moreVertical, color: AppColors.of(context).text.withOpacity(0.8)),
|
icon: Icon(FeatherIcons.moreVertical,
|
||||||
|
color: AppColors.of(context).text.withOpacity(0.8)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// ignore_for_file: no_leading_underscores_for_local_identifiers
|
||||||
|
|
||||||
import 'package:filcnaplo/models/user.dart';
|
import 'package:filcnaplo/models/user.dart';
|
||||||
import 'package:filcnaplo_mobile_ui/common/bottom_card.dart';
|
import 'package:filcnaplo_mobile_ui/common/bottom_card.dart';
|
||||||
import 'package:filcnaplo_mobile_ui/common/detail.dart';
|
import 'package:filcnaplo_mobile_ui/common/detail.dart';
|
||||||
@ -8,7 +10,7 @@ import 'package:intl/intl.dart';
|
|||||||
import 'account_view.i18n.dart';
|
import 'account_view.i18n.dart';
|
||||||
|
|
||||||
class AccountView extends StatelessWidget {
|
class AccountView extends StatelessWidget {
|
||||||
const AccountView(this.user, {Key? key}) : super(key: key);
|
const AccountView(this.user, {super.key});
|
||||||
|
|
||||||
final User user;
|
final User user;
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// ignore_for_file: no_leading_underscores_for_local_identifiers, use_build_context_synchronously
|
||||||
|
|
||||||
import 'package:filcnaplo/api/providers/update_provider.dart';
|
import 'package:filcnaplo/api/providers/update_provider.dart';
|
||||||
import 'package:filcnaplo_kreta_api/providers/absence_provider.dart';
|
import 'package:filcnaplo_kreta_api/providers/absence_provider.dart';
|
||||||
import 'package:filcnaplo_kreta_api/providers/event_provider.dart';
|
import 'package:filcnaplo_kreta_api/providers/event_provider.dart';
|
||||||
@ -46,13 +48,13 @@ import 'package:filcnaplo_premium/ui/mobile/settings/modify_teacher_names.dart';
|
|||||||
import 'package:filcnaplo_premium/ui/mobile/settings/welcome_message.dart';
|
import 'package:filcnaplo_premium/ui/mobile/settings/welcome_message.dart';
|
||||||
|
|
||||||
class SettingsScreen extends StatefulWidget {
|
class SettingsScreen extends StatefulWidget {
|
||||||
const SettingsScreen({Key? key}) : super(key: key);
|
const SettingsScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_SettingsScreenState createState() => _SettingsScreenState();
|
SettingsScreenState createState() => SettingsScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SettingsScreenState extends State<SettingsScreen>
|
class SettingsScreenState extends State<SettingsScreen>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
int devmodeCountdown = 5;
|
int devmodeCountdown = 5;
|
||||||
bool __ss = false; // secret settings
|
bool __ss = false; // secret settings
|
||||||
|
@ -51,6 +51,8 @@ dependencies:
|
|||||||
intl: ^0.18.1
|
intl: ^0.18.1
|
||||||
i18n_extension: ^10.0.1
|
i18n_extension: ^10.0.1
|
||||||
auto_size_text: ^3.0.0
|
auto_size_text: ^3.0.0
|
||||||
|
connectivity_plus: ^5.0.2
|
||||||
|
collection: ^1.18.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_lints: ^3.0.1
|
flutter_lints: ^3.0.1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user