fixed warnings (super.key, etc)

This commit is contained in:
Kima 2023-12-12 22:57:16 +01:00
parent fc3f538e6b
commit 6bac82f7d6
46 changed files with 349 additions and 228 deletions

View File

@ -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,
), ),
), ),
], ],

View File

@ -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;

View File

@ -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;

View File

@ -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(

View File

@ -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,

View File

@ -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 = [];

View File

@ -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();

View File

@ -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(),
), ),
); );
} }

View File

@ -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),
], ],
); );
} }

View File

@ -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;

View File

@ -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),
), ),
], ],
), ),

View File

@ -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;

View File

@ -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),
), ),
); );
}, },

View File

@ -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,11 +177,11 @@ 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,
), ),
overflow: TextOverflow.clip, overflow: TextOverflow.clip,
softWrap: false, softWrap: false,

View File

@ -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

View File

@ -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;

View File

@ -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),
), ),
], ],
), ),

View File

@ -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"),
], ],

View File

@ -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(
.textTheme color: Theme.of(context)
.bodyMedium! .textTheme
.copyWith(color: Theme.of(context).textTheme.bodyMedium!.color!.withOpacity(.8), fontSize: 18), .bodyMedium!
.color!
.withOpacity(.8),
fontSize: 18),
child: description!, child: description!,
), ),
], ],

View File

@ -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!,
), ),
), ),

View File

@ -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;

View File

@ -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(),
), ),
], ],
), ),

View File

@ -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;

View File

@ -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),
), ),
], ],

View File

@ -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();

View File

@ -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) {

View File

@ -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,

View File

@ -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)))
], ],
), ),
); );

View File

@ -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"),
), ),
), ),

View File

@ -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,
),
); );
} }
} }

View File

@ -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;

View File

@ -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,

View File

@ -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(

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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