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