forked from firka/student-legacy
CONVERT KEY TO SUPER PARAMETER KYS
This commit is contained in:
parent
e243b5c186
commit
51a6492477
@ -63,7 +63,7 @@ class Startup {
|
||||
await flutterLocalNotificationsPlugin
|
||||
.resolvePlatformSpecificImplementation<
|
||||
AndroidFlutterLocalNotificationsPlugin>()!
|
||||
.requestPermission();
|
||||
.requestNotificationsPermission();
|
||||
} else if (Platform.isIOS) {
|
||||
await flutterLocalNotificationsPlugin
|
||||
.resolvePlatformSpecificImplementation<
|
||||
|
@ -25,26 +25,26 @@ dependencies:
|
||||
|
||||
flutter_localizations:
|
||||
sdk: flutter
|
||||
i18n_extension: ^9.0.0
|
||||
i18n_extension: ^10.0.1
|
||||
sqflite: ^2.2.0+2
|
||||
intl: ^0.18.0
|
||||
provider: ^5.0.0
|
||||
http: ^0.13.3
|
||||
uuid: ^3.0.4
|
||||
uuid: ^4.2.1
|
||||
html: ^0.15.0
|
||||
open_file:
|
||||
git:
|
||||
url: https://github.com/crazecoder/open_file
|
||||
ref: master
|
||||
path_provider: ^2.0.2
|
||||
permission_handler: ^10.2.0
|
||||
permission_handler: ^11.0.1
|
||||
share_plus: ^7.0.2
|
||||
connectivity_plus: ^4.0.1
|
||||
connectivity_plus: ^5.0.2
|
||||
flutter_displaymode: ^0.6.0
|
||||
quick_actions: ^1.0.1
|
||||
animated_list_plus: ^0.5.0
|
||||
dynamic_color: ^1.2.2
|
||||
material_color_utilities: ^0.2.0
|
||||
material_color_utilities: ^0.5.0
|
||||
crypto: ^3.0.2
|
||||
elegant_notification: ^1.6.1
|
||||
flutter_feather_icons: ^2.0.0+1
|
||||
@ -55,7 +55,7 @@ dependencies:
|
||||
animated_background: ^2.0.0
|
||||
dropdown_button2: ^1.8.9
|
||||
home_widget: ^0.1.6
|
||||
flutter_expandable_fab: ^1.8.1
|
||||
flutter_expandable_fab: ^2.0.0
|
||||
uni_links: ^0.5.1
|
||||
url_launcher: ^6.1.6
|
||||
workmanager: ^0.5.1
|
||||
@ -63,7 +63,7 @@ dependencies:
|
||||
image_picker: ^0.8.6
|
||||
animations: ^2.0.1
|
||||
background_fetch: ^1.1.5
|
||||
flutter_local_notifications: ^14.1.0
|
||||
flutter_local_notifications: ^16.2.0
|
||||
package_info_plus: ^4.0.2
|
||||
screenshot: ^2.1.0
|
||||
flutter_staggered_grid_view: ^0.7.0
|
||||
@ -73,7 +73,7 @@ dependencies:
|
||||
url: https://github.com/kimaah/image_crop.git
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^2.0.1
|
||||
flutter_lints: ^3.0.1
|
||||
flutter_launcher_icons: "^0.13.1"
|
||||
flutter_native_splash: "^2.3.0"
|
||||
sqflite_common_ffi: ^2.0.0+3
|
||||
|
@ -399,9 +399,9 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
if (v) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) =>
|
||||
WillPopScope(
|
||||
onWillPop: () async => false,
|
||||
builder: (context) => PopScope(
|
||||
onPopInvoked: (didPop) =>
|
||||
false,
|
||||
child: AlertDialog(
|
||||
shape:
|
||||
RoundedRectangleBorder(
|
||||
|
@ -21,23 +21,14 @@ class KretaAPI {
|
||||
static String groups(String iss) =>
|
||||
BaseKreta.kreta(iss) + KretaApiEndpoints.groups;
|
||||
static String groupAverages(String iss, String uid) =>
|
||||
BaseKreta.kreta(iss) +
|
||||
KretaApiEndpoints.groupAverages +
|
||||
"?oktatasiNevelesiFeladatUid=" +
|
||||
uid;
|
||||
"${BaseKreta.kreta(iss)}${KretaApiEndpoints.groupAverages}?oktatasiNevelesiFeladatUid=$uid";
|
||||
static String averages(String iss, String uid) =>
|
||||
BaseKreta.kreta(iss) +
|
||||
KretaApiEndpoints.averages +
|
||||
"?oktatasiNevelesiFeladatUid=" +
|
||||
uid;
|
||||
"${BaseKreta.kreta(iss)}${KretaApiEndpoints.averages}?oktatasiNevelesiFeladatUid=$uid";
|
||||
static String timetable(String iss, {DateTime? start, DateTime? end}) =>
|
||||
BaseKreta.kreta(iss) +
|
||||
KretaApiEndpoints.timetable +
|
||||
(start != null && end != null
|
||||
? "?datumTol=" +
|
||||
start.toUtc().toIso8601String() +
|
||||
"&datumIg=" +
|
||||
end.toUtc().toIso8601String()
|
||||
? "?datumTol=${start.toUtc().toIso8601String()}&datumIg=${end.toUtc().toIso8601String()}"
|
||||
: "");
|
||||
static String exams(String iss) =>
|
||||
BaseKreta.kreta(iss) + KretaApiEndpoints.exams;
|
||||
@ -46,7 +37,7 @@ class KretaAPI {
|
||||
KretaApiEndpoints.homework +
|
||||
(id != null ? "/$id" : "") +
|
||||
(id == null && start != null
|
||||
? "?datumTol=" + DateFormat('yyyy-MM-dd').format(start)
|
||||
? "?datumTol=${DateFormat('yyyy-MM-dd').format(start)}"
|
||||
: "");
|
||||
static String capabilities(String iss) =>
|
||||
BaseKreta.kreta(iss) + KretaApiEndpoints.capabilities;
|
||||
@ -55,9 +46,7 @@ class KretaAPI {
|
||||
BaseKreta.kreta(iss) +
|
||||
KretaApiEndpoints.downloadHomeworkAttachments(uid, type);
|
||||
static String subjects(String iss, String uid) =>
|
||||
BaseKreta.kreta(iss) +
|
||||
KretaApiEndpoints.subjects +
|
||||
"?oktatasiNevelesiFeladatUid=" + uid;
|
||||
"${BaseKreta.kreta(iss)}${KretaApiEndpoints.subjects}?oktatasiNevelesiFeladatUid=$uid";
|
||||
// Structure:
|
||||
// {
|
||||
// "Uid": 000,
|
||||
|
@ -154,9 +154,9 @@ class TimetableController extends ChangeNotifier {
|
||||
}
|
||||
|
||||
for (int i = 0; i < days.length; i++) {
|
||||
List<Lesson> _day = List.castFrom(days[i]);
|
||||
List<Lesson> day0 = List.castFrom(days[i]);
|
||||
|
||||
List<int> lessonIndexes = _getIndexes(_day);
|
||||
List<int> lessonIndexes = _getIndexes(day0);
|
||||
int minIndex = 0, maxIndex = 0;
|
||||
|
||||
if (lessonIndexes.isNotEmpty) {
|
||||
@ -170,7 +170,7 @@ class TimetableController extends ChangeNotifier {
|
||||
// Fill missing indexes with empty spaces
|
||||
for (var i in List<int>.generate(
|
||||
maxIndex - minIndex + 1, (int i) => minIndex + i)) {
|
||||
List<Lesson> indexLessons = _getLessonsByIndex(_day, i);
|
||||
List<Lesson> indexLessons = _getLessonsByIndex(day0, i);
|
||||
|
||||
// Empty lesson
|
||||
if (indexLessons.isEmpty) {
|
||||
@ -193,13 +193,13 @@ class TimetableController extends ChangeNotifier {
|
||||
}
|
||||
|
||||
// Additional lessons
|
||||
day.addAll(_day.where((l) =>
|
||||
day.addAll(day0.where((l) =>
|
||||
int.tryParse(l.lessonIndex) == null && l.subject.id != ''));
|
||||
|
||||
day.sort((a, b) => a.start.compareTo(b.start));
|
||||
|
||||
// Special Dates
|
||||
for (var l in _day) {
|
||||
for (var l in day0) {
|
||||
l.subject.id == '' ? day.insert(0, l) : null;
|
||||
}
|
||||
|
||||
|
@ -38,16 +38,16 @@ class ExamProvider with ChangeNotifier {
|
||||
|
||||
// for renamed subjects
|
||||
Future<void> convertBySettings() async {
|
||||
final _database = Provider.of<DatabaseProvider>(_context, listen: false);
|
||||
final database = Provider.of<DatabaseProvider>(_context, listen: false);
|
||||
Map<String, String> renamedSubjects =
|
||||
(await _database.query.getSettings(_database)).renamedSubjectsEnabled
|
||||
? await _database.userQuery.renamedSubjects(
|
||||
(await database.query.getSettings(database)).renamedSubjectsEnabled
|
||||
? await database.userQuery.renamedSubjects(
|
||||
userId:
|
||||
Provider.of<UserProvider>(_context, listen: false).user!.id)
|
||||
: {};
|
||||
Map<String, String> renamedTeachers =
|
||||
(await _database.query.getSettings(_database)).renamedTeachersEnabled
|
||||
? await _database.userQuery.renamedTeachers(
|
||||
(await database.query.getSettings(database)).renamedTeachersEnabled
|
||||
? await database.userQuery.renamedTeachers(
|
||||
userId:
|
||||
Provider.of<UserProvider>(_context, listen: false).user!.id)
|
||||
: {};
|
||||
|
@ -11,7 +11,10 @@ dependencies:
|
||||
path: ../filcnaplo/
|
||||
http: ^0.13.3
|
||||
provider: ^5.0.0
|
||||
file_picker: ^5.3.2
|
||||
file_picker: ^6.1.1
|
||||
intl: ^0.18.1
|
||||
i18n_extension: ^10.0.1
|
||||
uuid: ^4.2.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^1.0.0
|
||||
flutter_lints: ^3.0.1
|
||||
|
@ -2,7 +2,7 @@ import 'package:filcnaplo/theme/colors/colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class RoundedBottomSheet extends StatelessWidget {
|
||||
const RoundedBottomSheet({Key? key, this.child, this.borderRadius = 12.0, this.shrink = true, this.showHandle = true}) : super(key: key);
|
||||
const RoundedBottomSheet({super.key, this.child, this.borderRadius = 12.0, this.shrink = true, this.showHandle = true});
|
||||
|
||||
final Widget? child;
|
||||
final double borderRadius;
|
||||
|
@ -2,7 +2,7 @@ import 'package:filcnaplo/theme/colors/colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Detail extends StatelessWidget {
|
||||
const Detail({Key? key, required this.title, required this.description, this.maxLines = 3}) : super(key: key);
|
||||
const Detail({super.key, required this.title, required this.description, this.maxLines = 3});
|
||||
|
||||
final String title;
|
||||
final String description;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class DialogButton extends StatelessWidget {
|
||||
const DialogButton({Key? key, required this.label, this.onTap}) : super(key: key);
|
||||
const DialogButton({super.key, required this.label, this.onTap});
|
||||
|
||||
final String label;
|
||||
final Function()? onTap;
|
||||
|
@ -4,7 +4,7 @@ class Dot extends StatelessWidget {
|
||||
final Color color;
|
||||
final double size;
|
||||
|
||||
const Dot({Key? key, this.color = Colors.grey, this.size = 16.0}) : super(key: key);
|
||||
const Dot({super.key, this.color = Colors.grey, this.size = 16.0});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -17,7 +17,7 @@ List<String> faces = [
|
||||
];
|
||||
|
||||
class Empty extends StatelessWidget {
|
||||
const Empty({Key? key, this.subtitle}) : super(key: key);
|
||||
const Empty({super.key, this.subtitle});
|
||||
|
||||
final String? subtitle;
|
||||
|
||||
@ -38,7 +38,7 @@ class Empty extends StatelessWidget {
|
||||
children: subtitle != null
|
||||
? [
|
||||
TextSpan(
|
||||
text: "\n" + subtitle!,
|
||||
text: "\n${subtitle!}",
|
||||
style: TextStyle(
|
||||
fontSize: 18.0,
|
||||
height: 2.0,
|
||||
|
@ -5,7 +5,7 @@ import 'package:flutter/material.dart';
|
||||
|
||||
class FilterBar extends StatefulWidget implements PreferredSizeWidget {
|
||||
const FilterBar({
|
||||
Key? key,
|
||||
super.key,
|
||||
required this.items,
|
||||
required this.controller,
|
||||
this.onTap,
|
||||
@ -13,8 +13,7 @@ class FilterBar extends StatefulWidget implements PreferredSizeWidget {
|
||||
this.disableFading = false,
|
||||
this.scrollable = true,
|
||||
this.censored = false,
|
||||
}) : assert(items.length == controller.length),
|
||||
super(key: key);
|
||||
}) : assert(items.length == controller.length);
|
||||
|
||||
final List<Widget> items;
|
||||
final TabController controller;
|
||||
|
@ -4,7 +4,7 @@ import 'package:filcnaplo/utils/format.dart';
|
||||
|
||||
class HeroScrollView extends StatefulWidget {
|
||||
const HeroScrollView(
|
||||
{Key? key,
|
||||
{super.key,
|
||||
required this.child,
|
||||
required this.title,
|
||||
required this.icon,
|
||||
@ -12,8 +12,7 @@ class HeroScrollView extends StatefulWidget {
|
||||
this.navBarItems = const [],
|
||||
this.onClose,
|
||||
this.iconSize = 64.0,
|
||||
this.scrollController})
|
||||
: super(key: key);
|
||||
this.scrollController});
|
||||
|
||||
final Widget child;
|
||||
final String title;
|
||||
@ -25,10 +24,10 @@ class HeroScrollView extends StatefulWidget {
|
||||
final bool italic;
|
||||
|
||||
@override
|
||||
_HeroScrollViewState createState() => _HeroScrollViewState();
|
||||
HeroScrollViewState createState() => HeroScrollViewState();
|
||||
}
|
||||
|
||||
class _HeroScrollViewState extends State<HeroScrollView> {
|
||||
class HeroScrollViewState extends State<HeroScrollView> {
|
||||
late ScrollController _scrollController;
|
||||
|
||||
bool showBarTitle = false;
|
||||
@ -69,6 +68,7 @@ class _HeroScrollViewState extends State<HeroScrollView> {
|
||||
surfaceTintColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
title: AnimatedOpacity(
|
||||
opacity: showBarTitle ? 1.0 : 0.0,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(widget.icon,
|
||||
@ -86,8 +86,7 @@ class _HeroScrollViewState extends State<HeroScrollView> {
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
duration: const Duration(milliseconds: 200)),
|
||||
)),
|
||||
leading: BackButton(
|
||||
color: AppColors.of(context).text,
|
||||
onPressed: () {
|
||||
|
@ -4,11 +4,11 @@ import 'package:flutter/material.dart';
|
||||
|
||||
class MaterialActionButton extends StatelessWidget {
|
||||
const MaterialActionButton({
|
||||
Key? key,
|
||||
super.key,
|
||||
required this.child,
|
||||
this.onPressed,
|
||||
this.backgroundColor,
|
||||
}) : super(key: key);
|
||||
});
|
||||
|
||||
final Widget child;
|
||||
final Function()? onPressed;
|
||||
@ -19,17 +19,17 @@ class MaterialActionButton extends StatelessWidget {
|
||||
return RawMaterialButton(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
shape: const StadiumBorder(),
|
||||
child: DefaultTextStyle(
|
||||
child: child,
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: backgroundColor != null ? ColorUtils.foregroundColor(backgroundColor!) : null,
|
||||
),
|
||||
),
|
||||
fillColor: backgroundColor ?? AppColors.of(context).text.withOpacity(.15),
|
||||
elevation: 0,
|
||||
highlightElevation: 0,
|
||||
onPressed: onPressed,
|
||||
child: DefaultTextStyle(
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: backgroundColor != null ? ColorUtils.foregroundColor(backgroundColor!) : null,
|
||||
),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import 'package:filcnaplo/theme/colors/colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class NewContentIndicator extends StatelessWidget {
|
||||
const NewContentIndicator({Key? key, this.size = 64.0}) : super(key: key);
|
||||
const NewContentIndicator({super.key, this.size = 64.0});
|
||||
|
||||
final double size;
|
||||
|
||||
|
@ -5,8 +5,7 @@ import 'package:provider/provider.dart';
|
||||
|
||||
class Panel extends StatelessWidget {
|
||||
const Panel(
|
||||
{Key? key, this.child, this.title, this.padding, this.hasShadow = true})
|
||||
: super(key: key);
|
||||
{super.key, this.child, this.title, this.padding, this.hasShadow = true});
|
||||
|
||||
final Widget? child;
|
||||
final Widget? title;
|
||||
@ -48,7 +47,7 @@ class Panel extends StatelessWidget {
|
||||
}
|
||||
|
||||
class PanelTitle extends StatelessWidget {
|
||||
const PanelTitle({Key? key, required this.title}) : super(key: key);
|
||||
const PanelTitle({super.key, required this.title});
|
||||
|
||||
final Widget title;
|
||||
|
||||
@ -67,7 +66,7 @@ class PanelTitle extends StatelessWidget {
|
||||
}
|
||||
|
||||
class PanelHeader extends StatelessWidget {
|
||||
const PanelHeader({Key? key, required this.padding}) : super(key: key);
|
||||
const PanelHeader({super.key, required this.padding});
|
||||
|
||||
final EdgeInsetsGeometry padding;
|
||||
|
||||
@ -95,7 +94,7 @@ class PanelHeader extends StatelessWidget {
|
||||
}
|
||||
|
||||
class PanelBody extends StatelessWidget {
|
||||
const PanelBody({Key? key, this.child, this.padding}) : super(key: key);
|
||||
const PanelBody({super.key, this.child, this.padding});
|
||||
|
||||
final Widget? child;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
@ -123,7 +122,7 @@ class PanelBody extends StatelessWidget {
|
||||
}
|
||||
|
||||
class PanelFooter extends StatelessWidget {
|
||||
const PanelFooter({Key? key, required this.padding}) : super(key: key);
|
||||
const PanelFooter({super.key, required this.padding});
|
||||
|
||||
final EdgeInsetsGeometry padding;
|
||||
|
||||
|
@ -2,13 +2,13 @@ import 'package:flutter/material.dart';
|
||||
|
||||
class PanelActionButton extends StatelessWidget {
|
||||
const PanelActionButton({
|
||||
Key? key,
|
||||
super.key,
|
||||
this.onPressed,
|
||||
this.padding = const EdgeInsets.symmetric(horizontal: 14.0),
|
||||
this.leading,
|
||||
this.title,
|
||||
this.trailing,
|
||||
}) : super(key: key);
|
||||
});
|
||||
|
||||
final void Function()? onPressed;
|
||||
final EdgeInsetsGeometry padding;
|
||||
|
@ -5,7 +5,7 @@ import 'package:flutter/material.dart';
|
||||
|
||||
class PanelButton extends StatelessWidget {
|
||||
const PanelButton({
|
||||
Key? key,
|
||||
super.key,
|
||||
this.onPressed,
|
||||
this.padding = const EdgeInsets.symmetric(horizontal: 14.0),
|
||||
this.leading,
|
||||
@ -13,7 +13,7 @@ class PanelButton extends StatelessWidget {
|
||||
this.trailing,
|
||||
this.background = false,
|
||||
this.trailingDivider = false,
|
||||
}) : super(key: key);
|
||||
});
|
||||
|
||||
final void Function()? onPressed;
|
||||
final EdgeInsetsGeometry padding;
|
||||
|
@ -5,9 +5,9 @@ import 'package:provider/provider.dart';
|
||||
|
||||
class EmptyCard extends StatefulWidget {
|
||||
const EmptyCard({
|
||||
Key? key,
|
||||
super.key,
|
||||
required this.text,
|
||||
}) : super(key: key);
|
||||
});
|
||||
|
||||
final String text;
|
||||
|
||||
|
@ -18,9 +18,9 @@ import 'personality_card.i18n.dart';
|
||||
|
||||
class PersonalityCard extends StatefulWidget {
|
||||
const PersonalityCard({
|
||||
Key? key,
|
||||
super.key,
|
||||
required this.user,
|
||||
}) : super(key: key);
|
||||
});
|
||||
|
||||
final UserProvider user;
|
||||
|
||||
|
@ -17,7 +17,7 @@ import 'package:provider/provider.dart';
|
||||
import 'package:wtf_sliding_sheet/wtf_sliding_sheet.dart';
|
||||
|
||||
class ProfileButton extends StatelessWidget {
|
||||
const ProfileButton({Key? key, required this.child}) : super(key: key);
|
||||
const ProfileButton({super.key, required this.child});
|
||||
|
||||
final ProfileImage child;
|
||||
|
||||
|
@ -8,7 +8,7 @@ import 'package:filcnaplo/utils/color.dart';
|
||||
|
||||
class ProfileImage extends StatefulWidget {
|
||||
const ProfileImage({
|
||||
Key? key,
|
||||
super.key,
|
||||
this.onTap,
|
||||
this.onDoubleTap,
|
||||
this.onLongPress,
|
||||
@ -20,7 +20,7 @@ class ProfileImage extends StatefulWidget {
|
||||
this.role = Role.student,
|
||||
this.censored = false,
|
||||
this.profilePictureString = "",
|
||||
}) : super(key: key);
|
||||
});
|
||||
|
||||
final void Function()? onTap;
|
||||
final void Function()? onDoubleTap;
|
||||
@ -176,7 +176,7 @@ class _ProfileImageState extends State<ProfileImage> {
|
||||
children: [
|
||||
if (widget.name != null && (widget.name?.trim().length ?? 0) > 0)
|
||||
Hero(
|
||||
tag: widget.heroTag! + "background",
|
||||
tag: "${widget.heroTag!}background",
|
||||
transitionOnUserGestures: true,
|
||||
child: Material(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
@ -197,27 +197,27 @@ class _ProfileImageState extends State<ProfileImage> {
|
||||
),
|
||||
),
|
||||
Hero(
|
||||
tag: widget.heroTag! + "child",
|
||||
tag: "${widget.heroTag!}child",
|
||||
transitionOnUserGestures: true,
|
||||
child: Material(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
shape: profilePicture != null ? const CircleBorder() : null,
|
||||
child: profilePicture ?? child,
|
||||
type: MaterialType.transparency,
|
||||
child: profilePicture ?? child,
|
||||
),
|
||||
),
|
||||
|
||||
// Badge
|
||||
if (widget.badge)
|
||||
Hero(
|
||||
tag: widget.heroTag! + "new_content_indicator",
|
||||
tag: "${widget.heroTag!}new_content_indicator",
|
||||
child: NewContentIndicator(size: widget.radius * 2),
|
||||
),
|
||||
|
||||
// Role indicator
|
||||
if (widget.role == Role.parent)
|
||||
Hero(
|
||||
tag: widget.heroTag! + "role_indicator",
|
||||
tag: "${widget.heroTag!}role_indicator",
|
||||
child: FittedBox(
|
||||
fit: BoxFit.fitHeight,
|
||||
child: SizedBox(
|
||||
|
@ -2,8 +2,7 @@ import 'package:flutter/material.dart';
|
||||
|
||||
class ProgressBar extends StatelessWidget {
|
||||
const ProgressBar(
|
||||
{Key? key, required this.value, this.backgroundColor, this.height = 8.0})
|
||||
: super(key: key);
|
||||
{super.key, required this.value, this.backgroundColor, this.height = 8.0});
|
||||
|
||||
final double value;
|
||||
final Color? backgroundColor;
|
||||
|
@ -7,12 +7,11 @@ class RoundBorderIcon extends StatelessWidget {
|
||||
final Widget icon;
|
||||
|
||||
const RoundBorderIcon(
|
||||
{Key? key,
|
||||
{super.key,
|
||||
this.color = Colors.black,
|
||||
this.width = 1.5,
|
||||
this.padding = 5.0,
|
||||
required this.icon})
|
||||
: super(key: key);
|
||||
required this.icon});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -3,7 +3,7 @@ import 'package:filcnaplo_mobile_ui/common/soon_alert/soon_alert.i18n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SoonAlert extends StatelessWidget {
|
||||
const SoonAlert({Key? key}) : super(key: key);
|
||||
const SoonAlert({super.key});
|
||||
|
||||
static show({required BuildContext context}) =>
|
||||
showDialog(context: context, builder: (context) => const SoonAlert());
|
||||
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:i18n_extension/i18n_widget.dart';
|
||||
|
||||
class TrendDisplay<T extends num> extends StatelessWidget {
|
||||
const TrendDisplay({Key? key, required this.current, required this.previous, this.padding}) : super(key: key);
|
||||
const TrendDisplay({super.key, required this.current, required this.previous, this.padding});
|
||||
|
||||
final T current;
|
||||
final T previous;
|
||||
|
@ -59,12 +59,12 @@ enum _ViewableLocation {
|
||||
|
||||
class Viewable extends StatefulWidget {
|
||||
const Viewable({
|
||||
Key? key,
|
||||
super.key,
|
||||
required this.view,
|
||||
required this.tile,
|
||||
this.actions = const [],
|
||||
this.previewBuilder,
|
||||
}) : super(key: key);
|
||||
});
|
||||
|
||||
final Widget tile;
|
||||
final Widget view;
|
||||
@ -255,12 +255,11 @@ class _ViewableState extends State<Viewable> with TickerProviderStateMixin {
|
||||
|
||||
class _DecoyChild extends StatefulWidget {
|
||||
const _DecoyChild({
|
||||
Key? key,
|
||||
this.beginRect,
|
||||
required this.controller,
|
||||
this.endRect,
|
||||
this.child,
|
||||
}) : super(key: key);
|
||||
});
|
||||
|
||||
final Rect? beginRect;
|
||||
final AnimationController controller;
|
||||
@ -364,17 +363,13 @@ class _ViewableRoute<T> extends PopupRoute<T> {
|
||||
required _ViewableLocation contextMenuLocation,
|
||||
this.barrierLabel,
|
||||
_ViewablePreviewBuilderChildless? builder,
|
||||
ui.ImageFilter? filter,
|
||||
super.filter,
|
||||
required Rect previousChildRect,
|
||||
RouteSettings? settings,
|
||||
super.settings,
|
||||
}) : _actions = actions,
|
||||
_builder = builder,
|
||||
_contextMenuLocation = contextMenuLocation,
|
||||
_previousChildRect = previousChildRect,
|
||||
super(
|
||||
filter: filter,
|
||||
settings: settings,
|
||||
);
|
||||
_previousChildRect = previousChildRect;
|
||||
|
||||
static const Color _kModalBarrierColor = Color(0x6604040F);
|
||||
|
||||
@ -607,7 +602,6 @@ class _ViewableRoute<T> extends PopupRoute<T> {
|
||||
|
||||
class _ContextMenuRouteStatic extends StatefulWidget {
|
||||
const _ContextMenuRouteStatic({
|
||||
Key? key,
|
||||
this.actions,
|
||||
required this.child,
|
||||
this.childGlobalKey,
|
||||
@ -615,7 +609,7 @@ class _ContextMenuRouteStatic extends StatefulWidget {
|
||||
this.onDismiss,
|
||||
required this.orientation,
|
||||
this.sheetGlobalKey,
|
||||
}) : super(key: key);
|
||||
});
|
||||
|
||||
final List<Widget>? actions;
|
||||
final Widget child;
|
||||
@ -899,9 +893,9 @@ class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with T
|
||||
|
||||
class _ViewableSheet extends StatelessWidget {
|
||||
const _ViewableSheet({
|
||||
Key? key,
|
||||
super.key,
|
||||
required this.actions,
|
||||
}) : super(key: key);
|
||||
});
|
||||
|
||||
final List<Widget> actions;
|
||||
|
||||
|
@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
|
||||
class AbsenceDisplay extends StatelessWidget {
|
||||
const AbsenceDisplay(this.excused, this.unexcused, this.pending, {Key? key}) : super(key: key);
|
||||
const AbsenceDisplay(this.excused, this.unexcused, this.pending, {super.key});
|
||||
|
||||
final int excused;
|
||||
final int unexcused;
|
||||
|
@ -9,13 +9,12 @@ import 'package:provider/provider.dart';
|
||||
|
||||
class AbsenceSubjectTile extends StatelessWidget {
|
||||
const AbsenceSubjectTile(this.subject,
|
||||
{Key? key,
|
||||
{super.key,
|
||||
this.percentage = 0.0,
|
||||
this.excused = 0,
|
||||
this.unexcused = 0,
|
||||
this.pending = 0,
|
||||
this.onTap})
|
||||
: super(key: key);
|
||||
this.onTap});
|
||||
|
||||
final GradeSubject subject;
|
||||
final void Function()? onTap;
|
||||
@ -62,11 +61,11 @@ class AbsenceSubjectTile extends StatelessWidget {
|
||||
alignment: Alignment.centerRight,
|
||||
children: [
|
||||
const Opacity(
|
||||
opacity: 0,
|
||||
child: Text("100%",
|
||||
style: TextStyle(fontFamily: "monospace")),
|
||||
opacity: 0),
|
||||
style: TextStyle(fontFamily: "monospace"))),
|
||||
Text(
|
||||
percentage.round().toString() + "%",
|
||||
"${percentage.round()}%",
|
||||
style: TextStyle(
|
||||
// fontFamily: "monospace",
|
||||
color: getColorByPercentage(percentage, context: context),
|
||||
|
@ -10,8 +10,7 @@ import 'absence_tile.i18n.dart';
|
||||
|
||||
class AbsenceTile extends StatelessWidget {
|
||||
const AbsenceTile(this.absence,
|
||||
{Key? key, this.onTap, this.elevation = 0.0, this.padding})
|
||||
: super(key: key);
|
||||
{super.key, this.onTap, this.elevation = 0.0, this.padding});
|
||||
|
||||
final Absence absence;
|
||||
final void Function()? onTap;
|
||||
|
@ -18,8 +18,7 @@ import 'absence_view.i18n.dart';
|
||||
|
||||
class AbsenceView extends StatelessWidget {
|
||||
const AbsenceView(this.absence,
|
||||
{Key? key, this.outsideContext, this.viewable = false})
|
||||
: super(key: key);
|
||||
{super.key, this.outsideContext, this.viewable = false});
|
||||
|
||||
final Absence absence;
|
||||
final BuildContext? outsideContext;
|
||||
@ -90,9 +89,7 @@ class AbsenceView extends StatelessWidget {
|
||||
if (absence.delay > 0)
|
||||
Detail(
|
||||
title: "delay".i18n,
|
||||
description: absence.delay.toString() +
|
||||
" " +
|
||||
"minutes".i18n.plural(absence.delay),
|
||||
description: "${absence.delay} ${"minutes".i18n.plural(absence.delay)}",
|
||||
),
|
||||
if (absence.lessonIndex != null)
|
||||
Detail(
|
||||
|
@ -15,7 +15,7 @@ import 'package:filcnaplo/utils/reverse_search.dart';
|
||||
import 'absence_view.i18n.dart';
|
||||
|
||||
class AbsenceViewable extends StatelessWidget {
|
||||
const AbsenceViewable(this.absence, {Key? key, this.padding}) : super(key: key);
|
||||
const AbsenceViewable(this.absence, {super.key, this.padding});
|
||||
|
||||
final Absence absence;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AbsenceGroupContainer extends InheritedWidget {
|
||||
const AbsenceGroupContainer({Key? key, required Widget child}) : super(key: key, child: child);
|
||||
const AbsenceGroupContainer({super.key, required super.child});
|
||||
|
||||
static AbsenceGroupContainer? of(BuildContext context) => context.dependOnInheritedWidgetOfExactType<AbsenceGroupContainer>();
|
||||
|
||||
|
@ -11,8 +11,7 @@ import 'absence_group_tile.i18n.dart';
|
||||
|
||||
class AbsenceGroupTile extends StatelessWidget {
|
||||
const AbsenceGroupTile(this.absences,
|
||||
{Key? key, this.showDate = false, this.padding})
|
||||
: super(key: key);
|
||||
{super.key, this.showDate = false, this.padding});
|
||||
|
||||
final List<AbsenceViewable> absences;
|
||||
final bool showDate;
|
||||
|
@ -5,7 +5,7 @@ import 'package:filcnaplo_mobile_ui/common/panel/panel_button.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
|
||||
class AdTile extends StatelessWidget {
|
||||
const AdTile(this.ad, {Key? key, this.onTap, this.padding}) : super(key: key);
|
||||
const AdTile(this.ad, {super.key, this.onTap, this.padding});
|
||||
|
||||
final Ad ad;
|
||||
final Function()? onTap;
|
||||
|
@ -5,7 +5,7 @@ import 'package:url_launcher/url_launcher.dart';
|
||||
import 'ad_tile.dart';
|
||||
|
||||
class AdViewable extends StatelessWidget {
|
||||
const AdViewable(this.ad, {Key? key}) : super(key: key);
|
||||
const AdViewable(this.ad, {super.key});
|
||||
|
||||
final Ad ad;
|
||||
|
||||
|
@ -2,7 +2,7 @@ import 'package:filcnaplo/theme/colors/colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CardHandle extends StatelessWidget {
|
||||
const CardHandle({Key? key, this.child}) : super(key: key);
|
||||
const CardHandle({super.key, this.child});
|
||||
|
||||
final Widget? child;
|
||||
|
||||
|
@ -8,7 +8,7 @@ import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'certification_card.i18n.dart';
|
||||
|
||||
class CertificationCard extends StatelessWidget {
|
||||
const CertificationCard(this.grades, {Key? key, required this.gradeType, this.padding}) : super(key: key);
|
||||
const CertificationCard(this.grades, {super.key, required this.gradeType, this.padding});
|
||||
|
||||
final List<Grade> grades;
|
||||
final GradeType gradeType;
|
||||
|
@ -11,7 +11,7 @@ import 'package:provider/provider.dart';
|
||||
import 'certification_tile.i18n.dart';
|
||||
|
||||
class CertificationTile extends StatelessWidget {
|
||||
const CertificationTile(this.grade, {Key? key, this.onTap, this.padding}) : super(key: key);
|
||||
const CertificationTile(this.grade, {super.key, this.onTap, this.padding});
|
||||
|
||||
final Function()? onTap;
|
||||
final Grade grade;
|
||||
|
@ -8,7 +8,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
|
||||
class CertificationView extends StatelessWidget {
|
||||
const CertificationView(this.grades, {Key? key, required this.gradeType}) : super(key: key);
|
||||
const CertificationView(this.grades, {super.key, required this.gradeType});
|
||||
|
||||
final List<Grade> grades;
|
||||
final GradeType gradeType;
|
||||
@ -26,6 +26,9 @@ class CertificationView extends StatelessWidget {
|
||||
icon: FeatherIcons.award,
|
||||
iconSize: 50,
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0),
|
||||
physics: const BouncingScrollPhysics(),
|
||||
children: [
|
||||
SafeArea(
|
||||
child: Panel(
|
||||
@ -35,9 +38,6 @@ class CertificationView extends StatelessWidget {
|
||||
),
|
||||
)
|
||||
],
|
||||
shrinkWrap: true,
|
||||
padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0),
|
||||
physics: const BouncingScrollPhysics(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
@ -5,10 +5,10 @@ class CustomSwitch extends StatelessWidget {
|
||||
final bool value;
|
||||
|
||||
const CustomSwitch({
|
||||
Key? key,
|
||||
super.key,
|
||||
required this.onChanged,
|
||||
required this.value,
|
||||
}) : super(key: key);
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -4,7 +4,7 @@ import 'package:filcnaplo_mobile_ui/common/profile_image/profile_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class EventTile extends StatelessWidget {
|
||||
const EventTile(this.event, {Key? key, this.onTap, this.padding}) : super(key: key);
|
||||
const EventTile(this.event, {super.key, this.onTap, this.padding});
|
||||
|
||||
final Event event;
|
||||
final void Function()? onTap;
|
||||
|
@ -6,7 +6,7 @@ import 'package:flutter_custom_tabs/flutter_custom_tabs.dart';
|
||||
import 'package:flutter_linkify/flutter_linkify.dart';
|
||||
|
||||
class EventView extends StatelessWidget {
|
||||
const EventView(this.event, {Key? key}) : super(key: key);
|
||||
const EventView(this.event, {super.key});
|
||||
|
||||
final Event event;
|
||||
|
||||
|
@ -4,7 +4,7 @@ import 'package:filcnaplo_mobile_ui/common/widgets/event/event_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class EventViewable extends StatelessWidget {
|
||||
const EventViewable(this.event, {Key? key}) : super(key: key);
|
||||
const EventViewable(this.event, {super.key});
|
||||
|
||||
final Event event;
|
||||
|
||||
|
@ -6,8 +6,7 @@ import 'package:filcnaplo/utils/format.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
|
||||
class ExamTile extends StatelessWidget {
|
||||
const ExamTile(this.exam, {Key? key, this.onTap, this.padding})
|
||||
: super(key: key);
|
||||
const ExamTile(this.exam, {super.key, this.onTap, this.padding});
|
||||
|
||||
final Exam exam;
|
||||
final void Function()? onTap;
|
||||
|
@ -8,7 +8,7 @@ import 'package:flutter/material.dart';
|
||||
import 'exam_view.i18n.dart';
|
||||
|
||||
class ExamView extends StatelessWidget {
|
||||
const ExamView(this.exam, {Key? key}) : super(key: key);
|
||||
const ExamView(this.exam, {super.key});
|
||||
|
||||
final Exam exam;
|
||||
|
||||
|
@ -6,7 +6,7 @@ import 'package:filcnaplo_mobile_ui/common/widgets/exam/exam_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ExamViewable extends StatelessWidget {
|
||||
const ExamViewable(this.exam, {Key? key}) : super(key: key);
|
||||
const ExamViewable(this.exam, {super.key});
|
||||
|
||||
final Exam exam;
|
||||
|
||||
|
@ -9,12 +9,11 @@ import 'package:provider/provider.dart';
|
||||
|
||||
class GradeSubjectTile extends StatelessWidget {
|
||||
const GradeSubjectTile(this.subject,
|
||||
{Key? key,
|
||||
{super.key,
|
||||
this.average = 0.0,
|
||||
this.groupAverage = 0.0,
|
||||
this.onTap,
|
||||
this.averageBefore = 0.0})
|
||||
: super(key: key);
|
||||
this.averageBefore = 0.0});
|
||||
|
||||
final GradeSubject subject;
|
||||
final void Function()? onTap;
|
||||
|
@ -9,7 +9,7 @@ import 'package:provider/provider.dart';
|
||||
import 'grade_view.i18n.dart';
|
||||
|
||||
class GradeView extends StatelessWidget {
|
||||
const GradeView(this.grade, {Key? key}) : super(key: key);
|
||||
const GradeView(this.grade, {super.key});
|
||||
|
||||
static show(Grade grade, {required BuildContext context}) =>
|
||||
showBottomCard(context: context, child: GradeView(grade));
|
||||
@ -59,7 +59,7 @@ class GradeView extends StatelessWidget {
|
||||
// Grade Details
|
||||
Detail(
|
||||
title: "value".i18n,
|
||||
description: "${grade.value.valueName} " + percentText(),
|
||||
description: "${grade.value.valueName} ${percentText()}",
|
||||
),
|
||||
if (grade.description != "")
|
||||
Detail(title: "description".i18n, description: grade.description),
|
||||
|
@ -7,7 +7,7 @@ import 'package:filcnaplo_mobile_ui/pages/grades/subject_grades_container.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class GradeViewable extends StatelessWidget {
|
||||
const GradeViewable(this.grade, {Key? key, this.padding}) : super(key: key);
|
||||
const GradeViewable(this.grade, {super.key, this.padding});
|
||||
|
||||
final Grade grade;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
|
@ -10,7 +10,7 @@ import 'package:rive/rive.dart';
|
||||
import 'new_grades.i18n.dart';
|
||||
|
||||
class NewGradesSurprise extends StatelessWidget {
|
||||
const NewGradesSurprise(this.grades, {Key? key, this.censored = false}) : super(key: key);
|
||||
const NewGradesSurprise(this.grades, {super.key, this.censored = false});
|
||||
|
||||
final List<Grade> grades;
|
||||
final bool censored;
|
||||
|
@ -13,7 +13,7 @@ import 'package:rive/rive.dart' as rive;
|
||||
import 'new_grades.i18n.dart';
|
||||
|
||||
class SurpriseGrade extends StatefulWidget {
|
||||
const SurpriseGrade(this.grade, {Key? key}) : super(key: key);
|
||||
const SurpriseGrade(this.grade, {super.key});
|
||||
|
||||
final Grade grade;
|
||||
|
||||
|
@ -11,7 +11,7 @@ import 'package:flutter/material.dart';
|
||||
import 'homework_attachment_tile.i18n.dart';
|
||||
|
||||
class HomeworkAttachmentTile extends StatelessWidget {
|
||||
const HomeworkAttachmentTile(this.attachment, {Key? key}) : super(key: key);
|
||||
const HomeworkAttachmentTile(this.attachment, {super.key});
|
||||
|
||||
final HomeworkAttachment attachment;
|
||||
|
||||
@ -31,13 +31,13 @@ class HomeworkAttachmentTile extends StatelessWidget {
|
||||
builder: (context) => ImageView(snapshot.data!),
|
||||
));
|
||||
},
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
child: Ink.image(
|
||||
image: FileImage(File(snapshot.data ?? "")),
|
||||
height: 200.0,
|
||||
width: double.infinity,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -9,8 +9,7 @@ import 'package:provider/provider.dart';
|
||||
|
||||
class HomeworkTile extends StatelessWidget {
|
||||
const HomeworkTile(this.homework,
|
||||
{Key? key, this.onTap, this.padding, this.censored = false})
|
||||
: super(key: key);
|
||||
{super.key, this.onTap, this.padding, this.censored = false});
|
||||
|
||||
final Homework homework;
|
||||
final void Function()? onTap;
|
||||
|
@ -12,7 +12,7 @@ import 'package:provider/provider.dart';
|
||||
import 'homework_view.i18n.dart';
|
||||
|
||||
class HomeworkView extends StatelessWidget {
|
||||
const HomeworkView(this.homework, {Key? key}) : super(key: key);
|
||||
const HomeworkView(this.homework, {super.key});
|
||||
|
||||
final Homework homework;
|
||||
|
||||
|
@ -4,7 +4,7 @@ import 'package:filcnaplo_mobile_ui/common/widgets/homework/homework_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class HomeworkViewable extends StatelessWidget {
|
||||
const HomeworkViewable(this.homework, {Key? key}) : super(key: key);
|
||||
const HomeworkViewable(this.homework, {super.key});
|
||||
|
||||
final Homework homework;
|
||||
|
||||
|
@ -6,8 +6,7 @@ import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'changed_lesson_tile.i18n.dart';
|
||||
|
||||
class ChangedLessonTile extends StatelessWidget {
|
||||
const ChangedLessonTile(this.lesson, {Key? key, this.onTap, this.padding})
|
||||
: super(key: key);
|
||||
const ChangedLessonTile(this.lesson, {super.key, this.onTap, this.padding});
|
||||
|
||||
final Lesson lesson;
|
||||
final void Function()? onTap;
|
||||
|
@ -4,7 +4,7 @@ import 'package:filcnaplo_mobile_ui/pages/timetable/timetable_page.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ChangedLessonViewable extends StatelessWidget {
|
||||
const ChangedLessonViewable(this.lesson, {Key? key}) : super(key: key);
|
||||
const ChangedLessonViewable(this.lesson, {super.key});
|
||||
|
||||
final Lesson lesson;
|
||||
|
||||
|
@ -9,7 +9,7 @@ import 'package:provider/provider.dart';
|
||||
import 'lesson_view.i18n.dart';
|
||||
|
||||
class LessonView extends StatelessWidget {
|
||||
const LessonView(this.lesson, {Key? key}) : super(key: key);
|
||||
const LessonView(this.lesson, {super.key});
|
||||
|
||||
final Lesson lesson;
|
||||
|
||||
|
@ -6,7 +6,7 @@ import 'package:filcnaplo_mobile_ui/common/widgets/lesson/lesson_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class LessonViewable extends StatelessWidget {
|
||||
const LessonViewable(this.lesson, {Key? key, this.swapDesc = false}) : super(key: key);
|
||||
const LessonViewable(this.lesson, {super.key, this.swapDesc = false});
|
||||
|
||||
final Lesson lesson;
|
||||
final bool swapDesc;
|
||||
|
@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
|
||||
class AttachmentTile extends StatelessWidget {
|
||||
const AttachmentTile(this.attachment, {Key? key}) : super(key: key);
|
||||
const AttachmentTile(this.attachment, {super.key});
|
||||
|
||||
final Attachment attachment;
|
||||
|
||||
@ -32,13 +32,13 @@ class AttachmentTile extends StatelessWidget {
|
||||
},
|
||||
);
|
||||
},
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
child: Ink.image(
|
||||
image: FileImage(File(snapshot.data ?? "")),
|
||||
height: 200.0,
|
||||
width: double.infinity,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -7,7 +7,7 @@ import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
|
||||
class ImageView extends StatelessWidget {
|
||||
const ImageView(this.path, {Key? key}) : super(key: key);
|
||||
const ImageView(this.path, {super.key});
|
||||
|
||||
final String path;
|
||||
|
||||
|
@ -5,7 +5,7 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MessageView extends StatefulWidget {
|
||||
const MessageView(this.messages, {Key? key}) : super(key: key);
|
||||
const MessageView(this.messages, {super.key});
|
||||
|
||||
final List<Message> messages;
|
||||
|
||||
@ -13,10 +13,10 @@ class MessageView extends StatefulWidget {
|
||||
Navigator.of(context, rootNavigator: true).push(CupertinoPageRoute(builder: (context) => MessageView(messages)));
|
||||
|
||||
@override
|
||||
_MessageViewState createState() => _MessageViewState();
|
||||
MessageViewState createState() => MessageViewState();
|
||||
}
|
||||
|
||||
class _MessageViewState extends State<MessageView> {
|
||||
class MessageViewState extends State<MessageView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
@ -13,7 +13,7 @@ import 'package:provider/provider.dart';
|
||||
import 'message_view_tile.i18n.dart';
|
||||
|
||||
class MessageViewTile extends StatelessWidget {
|
||||
const MessageViewTile(this.message, {Key? key}) : super(key: key);
|
||||
const MessageViewTile(this.message, {super.key});
|
||||
|
||||
final Message message;
|
||||
|
||||
@ -76,7 +76,7 @@ class MessageViewTile extends StatelessWidget {
|
||||
maxLines: 2,
|
||||
),
|
||||
subtitle: Text(
|
||||
"to".i18n + " " + recipientLabel,
|
||||
"${"to".i18n} $recipientLabel",
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
|
@ -5,7 +5,7 @@ import 'package:filcnaplo_mobile_ui/common/widgets/message/message_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MessageViewable extends StatelessWidget {
|
||||
const MessageViewable(this.message, {Key? key}) : super(key: key);
|
||||
const MessageViewable(this.message, {super.key});
|
||||
|
||||
final Message message;
|
||||
|
||||
|
@ -5,7 +5,7 @@ import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'miss_tile.i18n.dart';
|
||||
|
||||
class MissTile extends StatelessWidget {
|
||||
const MissTile(this.note, {Key? key}) : super(key: key);
|
||||
const MissTile(this.note, {super.key});
|
||||
|
||||
final Note note;
|
||||
|
||||
|
@ -6,7 +6,7 @@ import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'missed_exam_tile.i18n.dart';
|
||||
|
||||
class MissedExamTile extends StatelessWidget {
|
||||
const MissedExamTile(this.missedExams, {Key? key, this.onTap, this.padding}) : super(key: key);
|
||||
const MissedExamTile(this.missedExams, {super.key, this.onTap, this.padding});
|
||||
|
||||
final List<Lesson> missedExams;
|
||||
final Function()? onTap;
|
||||
|
@ -39,8 +39,7 @@ import 'grades_page.i18n.dart';
|
||||
// import 'package:filcnaplo_premium/ui/mobile/goal_planner/new_goal.dart';
|
||||
|
||||
class GradeSubjectView extends StatefulWidget {
|
||||
const GradeSubjectView(this.subject, {Key? key, this.groupAverage = 0.0})
|
||||
: super(key: key);
|
||||
const GradeSubjectView(this.subject, {super.key, this.groupAverage = 0.0});
|
||||
|
||||
final GradeSubject subject;
|
||||
final double groupAverage;
|
||||
@ -110,21 +109,21 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
),
|
||||
));
|
||||
|
||||
List<Widget> _gradeTiles = [];
|
||||
List<Widget> gradeTiles = [];
|
||||
|
||||
if (!gradeCalcMode) {
|
||||
subjectGrades.sort((a, b) => -a.date.compareTo(b.date));
|
||||
for (var grade in subjectGrades) {
|
||||
if (grade.type == GradeType.midYear) {
|
||||
_gradeTiles.add(GradeViewable(grade));
|
||||
gradeTiles.add(GradeViewable(grade));
|
||||
} else {
|
||||
_gradeTiles.add(CertificationTile(grade, padding: EdgeInsets.zero));
|
||||
gradeTiles.add(CertificationTile(grade, padding: EdgeInsets.zero));
|
||||
}
|
||||
}
|
||||
} else if (subjectGrades.isNotEmpty) {
|
||||
subjectGrades.sort((a, b) => -a.date.compareTo(b.date));
|
||||
for (var grade in subjectGrades) {
|
||||
_gradeTiles.add(GradeTile(grade));
|
||||
gradeTiles.add(GradeTile(grade));
|
||||
}
|
||||
}
|
||||
tiles.add(
|
||||
@ -138,18 +137,18 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
animation: primaryAnimation,
|
||||
secondaryAnimation: secondaryAnimation,
|
||||
transitionType: SharedAxisTransitionType.vertical,
|
||||
child: child,
|
||||
fillColor: Colors.transparent,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
child: _gradeTiles.isNotEmpty
|
||||
child: gradeTiles.isNotEmpty
|
||||
? Panel(
|
||||
key: ValueKey(gradeCalcMode),
|
||||
title: Text(
|
||||
gradeCalcMode ? "Ghost Grades".i18n : "Grades".i18n,
|
||||
),
|
||||
child: Column(
|
||||
children: _gradeTiles,
|
||||
children: gradeTiles,
|
||||
))
|
||||
: const SizedBox(),
|
||||
),
|
||||
@ -230,24 +229,22 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
.where((e) => e.type == GradeType.midYear)
|
||||
.isNotEmpty,
|
||||
child: ExpandableFab(
|
||||
backgroundColor: Theme.of(context).colorScheme.secondary,
|
||||
overlayStyle: ExpandableFabOverlayStyle(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
type: ExpandableFabType.up,
|
||||
distance: 50,
|
||||
closeButtonStyle: ExpandableFabCloseButtonStyle(
|
||||
backgroundColor: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
children: [
|
||||
FloatingActionButton.small(
|
||||
heroTag: "btn_ghost_grades",
|
||||
child: const Icon(FeatherIcons.plus),
|
||||
backgroundColor: Theme.of(context).colorScheme.secondary,
|
||||
onPressed: () {
|
||||
gradeCalc(context);
|
||||
},
|
||||
child: const Icon(FeatherIcons.plus),
|
||||
),
|
||||
FloatingActionButton.small(
|
||||
heroTag: "btn_goal_planner",
|
||||
child: const Icon(FeatherIcons.flag, size: 20.0),
|
||||
backgroundColor: Theme.of(context).colorScheme.secondary,
|
||||
onPressed: () {
|
||||
if (!Provider.of<PremiumProvider>(context, listen: false)
|
||||
@ -264,6 +261,7 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
builder: (context) =>
|
||||
GoalPlannerScreen(subject: widget.subject)));
|
||||
},
|
||||
child: const Icon(FeatherIcons.flag, size: 20.0),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -348,7 +346,7 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
|
||||
_sheetController = _scaffoldKey.currentState?.showBottomSheet(
|
||||
(context) => RoundedBottomSheet(
|
||||
child: GradeCalculator(widget.subject), borderRadius: 14.0),
|
||||
borderRadius: 14.0, child: GradeCalculator(widget.subject)),
|
||||
backgroundColor: const Color(0x00000000),
|
||||
elevation: 12.0,
|
||||
);
|
||||
|
@ -12,17 +12,18 @@ import 'package:provider/provider.dart';
|
||||
import 'graph.i18n.dart';
|
||||
|
||||
class GradeGraph extends StatefulWidget {
|
||||
const GradeGraph(this.data, {Key? key, this.dayThreshold = 7, this.classAvg}) : super(key: key);
|
||||
const GradeGraph(this.data,
|
||||
{super.key, this.dayThreshold = 7, this.classAvg});
|
||||
|
||||
final List<Grade> data;
|
||||
final int dayThreshold;
|
||||
final double? classAvg;
|
||||
|
||||
@override
|
||||
_GradeGraphState createState() => _GradeGraphState();
|
||||
GradeGraphState createState() => GradeGraphState();
|
||||
}
|
||||
|
||||
class _GradeGraphState extends State<GradeGraph> {
|
||||
class GradeGraphState extends State<GradeGraph> {
|
||||
late SettingsProvider settings;
|
||||
|
||||
List<FlSpot> getSpots(List<Grade> data) {
|
||||
@ -34,7 +35,9 @@ class _GradeGraphState extends State<GradeGraph> {
|
||||
|
||||
// Sort data to points by treshold
|
||||
for (var element in data) {
|
||||
if (sortedData.last.isNotEmpty && sortedData.last.last.writeDate.difference(element.writeDate).inDays > widget.dayThreshold) {
|
||||
if (sortedData.last.isNotEmpty &&
|
||||
sortedData.last.last.writeDate.difference(element.writeDate).inDays >
|
||||
widget.dayThreshold) {
|
||||
sortedData.add([]);
|
||||
}
|
||||
for (var dataList in sortedData) {
|
||||
@ -48,7 +51,9 @@ class _GradeGraphState extends State<GradeGraph> {
|
||||
|
||||
if (dataList.isNotEmpty) {
|
||||
subjectData.add(FlSpot(
|
||||
dataList[0].writeDate.month + (dataList[0].writeDate.day / 31) + ((dataList[0].writeDate.year - data.last.writeDate.year) * 12),
|
||||
dataList[0].writeDate.month +
|
||||
(dataList[0].writeDate.day / 31) +
|
||||
((dataList[0].writeDate.year - data.last.writeDate.year) * 12),
|
||||
double.parse(average.toStringAsFixed(2)),
|
||||
));
|
||||
}
|
||||
@ -74,14 +79,19 @@ class _GradeGraphState extends State<GradeGraph> {
|
||||
.toList();
|
||||
|
||||
// Filter ghost data
|
||||
List<Grade> ghostData = widget.data.where((e) => e.value.weight != 0).where((e) => e.type == GradeType.ghost).toList();
|
||||
List<Grade> ghostData = widget.data
|
||||
.where((e) => e.value.weight != 0)
|
||||
.where((e) => e.type == GradeType.ghost)
|
||||
.toList();
|
||||
|
||||
// Calculate average
|
||||
double average = AverageHelper.averageEvals(data);
|
||||
|
||||
// Calculate graph color
|
||||
Color averageColor = average >= 1 && average <= 5
|
||||
? ColorTween(begin: settings.gradeColors[average.floor() - 1], end: settings.gradeColors[average.ceil() - 1])
|
||||
? ColorTween(
|
||||
begin: settings.gradeColors[average.floor() - 1],
|
||||
end: settings.gradeColors[average.ceil() - 1])
|
||||
.transform(average - average.floor())!
|
||||
: Theme.of(context).colorScheme.secondary;
|
||||
|
||||
@ -92,17 +102,26 @@ class _GradeGraphState extends State<GradeGraph> {
|
||||
ghostSpots = getSpots(data + ghostData);
|
||||
|
||||
// hax
|
||||
ghostSpots = ghostSpots.where((e) => e.x >= subjectSpots.map((f) => f.x).reduce(max)).toList();
|
||||
ghostSpots = ghostSpots
|
||||
.where((e) => e.x >= subjectSpots.map((f) => f.x).reduce(max))
|
||||
.toList();
|
||||
ghostSpots = ghostSpots.map((e) => FlSpot(e.x + 0.1, e.y)).toList();
|
||||
ghostSpots.add(subjectSpots.firstWhere((e) => e.x >= subjectSpots.map((f) => f.x).reduce(max), orElse: () => const FlSpot(-1, -1)));
|
||||
ghostSpots.removeWhere((element) => element.x == -1 && element.y == -1); // naplo/#74
|
||||
ghostSpots.add(subjectSpots.firstWhere(
|
||||
(e) => e.x >= subjectSpots.map((f) => f.x).reduce(max),
|
||||
orElse: () => const FlSpot(-1, -1)));
|
||||
ghostSpots.removeWhere(
|
||||
(element) => element.x == -1 && element.y == -1); // naplo/#74
|
||||
}
|
||||
|
||||
Grade halfYearGrade = widget.data.lastWhere((e) => e.type == GradeType.halfYear, orElse: () => Grade.fromJson({}));
|
||||
Grade halfYearGrade = widget.data.lastWhere(
|
||||
(e) => e.type == GradeType.halfYear,
|
||||
orElse: () => Grade.fromJson({}));
|
||||
|
||||
if (halfYearGrade.date.year != 0 && data.isNotEmpty) {
|
||||
final maxX = ghostSpots.isNotEmpty ? ghostSpots.first.x : 0;
|
||||
final x = halfYearGrade.writeDate.month + (halfYearGrade.writeDate.day / 31) + ((halfYearGrade.writeDate.year - data.last.writeDate.year) * 12);
|
||||
final x = halfYearGrade.writeDate.month +
|
||||
(halfYearGrade.writeDate.day / 31) +
|
||||
((halfYearGrade.writeDate.year - data.last.writeDate.year) * 12);
|
||||
if (x <= maxX) {
|
||||
extraLinesV.add(
|
||||
VerticalLine(
|
||||
@ -110,7 +129,7 @@ class _GradeGraphState extends State<GradeGraph> {
|
||||
strokeWidth: 3.0,
|
||||
color: AppColors.of(context).red.withOpacity(.75),
|
||||
label: VerticalLineLabel(
|
||||
labelResolver: (_) => " " + "mid".i18n + " ", // <- zwsp for padding
|
||||
labelResolver: (_) => " ${"mid".i18n} ", // <- zwsp for padding
|
||||
show: true,
|
||||
alignment: Alignment.topLeft,
|
||||
style: TextStyle(
|
||||
@ -126,7 +145,9 @@ class _GradeGraphState extends State<GradeGraph> {
|
||||
}
|
||||
|
||||
// Horizontal line displaying the class average
|
||||
if (widget.classAvg != null && widget.classAvg! > 0.0 && settings.graphClassAvg) {
|
||||
if (widget.classAvg != null &&
|
||||
widget.classAvg! > 0.0 &&
|
||||
settings.graphClassAvg) {
|
||||
extraLinesH.add(HorizontalLine(
|
||||
y: widget.classAvg!,
|
||||
color: AppColors.of(context).text.withOpacity(.75),
|
||||
@ -147,12 +168,15 @@ class _GradeGraphState extends State<GradeGraph> {
|
||||
)
|
||||
: ClipRect(
|
||||
child: SizedBox(
|
||||
height: 158,
|
||||
child: subjectSpots.length > 1
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0, right: 8.0),
|
||||
child: LineChart(
|
||||
LineChartData(
|
||||
extraLinesData: ExtraLinesData(verticalLines: extraLinesV, horizontalLines: extraLinesH),
|
||||
extraLinesData: ExtraLinesData(
|
||||
verticalLines: extraLinesV,
|
||||
horizontalLines: extraLinesH),
|
||||
lineBarsData: [
|
||||
LineChartBarData(
|
||||
preventCurveOverShooting: true,
|
||||
@ -230,7 +254,8 @@ class _GradeGraphState extends State<GradeGraph> {
|
||||
strokeWidth: 3.5,
|
||||
),
|
||||
FlDotData(
|
||||
getDotPainter: (a, b, c, d) => FlDotCirclePainter(
|
||||
getDotPainter: (a, b, c, d) =>
|
||||
FlDotCirclePainter(
|
||||
strokeWidth: 0,
|
||||
color: Colors.grey.shade900,
|
||||
radius: 10.0,
|
||||
@ -252,25 +277,45 @@ class _GradeGraphState extends State<GradeGraph> {
|
||||
showTitles: true,
|
||||
reservedSize: 24,
|
||||
getTextStyles: (context, value) => TextStyle(
|
||||
color: AppColors.of(context).text.withOpacity(.75),
|
||||
color:
|
||||
AppColors.of(context).text.withOpacity(.75),
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14.0,
|
||||
),
|
||||
margin: 12.0,
|
||||
getTitles: (value) {
|
||||
var format = DateFormat("MMM", I18n.of(context).locale.toString());
|
||||
var format = DateFormat(
|
||||
"MMM", I18n.of(context).locale.toString());
|
||||
|
||||
String title = format.format(DateTime(0, value.floor() % 12)).replaceAll(".", "");
|
||||
title = title.substring(0, min(title.length, 4));
|
||||
String title = format
|
||||
.format(DateTime(0, value.floor() % 12))
|
||||
.replaceAll(".", "");
|
||||
title =
|
||||
title.substring(0, min(title.length, 4));
|
||||
|
||||
return title.toUpperCase();
|
||||
},
|
||||
interval: () {
|
||||
List<Grade> tData = ghostData.isNotEmpty ? ghostData : data;
|
||||
tData.sort((a, b) => a.writeDate.compareTo(b.writeDate));
|
||||
return tData.first.writeDate.add(const Duration(days: 120)).isBefore(tData.last.writeDate) ? 2.0 : 1.0;
|
||||
List<Grade> tData =
|
||||
ghostData.isNotEmpty ? ghostData : data;
|
||||
tData.sort((a, b) =>
|
||||
a.writeDate.compareTo(b.writeDate));
|
||||
return tData.first.writeDate
|
||||
.add(const Duration(days: 120))
|
||||
.isBefore(tData.last.writeDate)
|
||||
? 2.0
|
||||
: 1.0;
|
||||
}(),
|
||||
checkToShowTitle: (double minValue, double maxValue, SideTitles sideTitles, double appliedInterval, double value) { if (value == maxValue || value == minValue) return false; return true; },
|
||||
checkToShowTitle: (double minValue,
|
||||
double maxValue,
|
||||
SideTitles sideTitles,
|
||||
double appliedInterval,
|
||||
double value) {
|
||||
if (value == maxValue || value == minValue) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
),
|
||||
leftTitles: SideTitles(
|
||||
showTitles: true,
|
||||
@ -289,7 +334,6 @@ class _GradeGraphState extends State<GradeGraph> {
|
||||
),
|
||||
)
|
||||
: null,
|
||||
height: 158,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -46,10 +46,13 @@ dependencies:
|
||||
rounded_expansion_tile:
|
||||
git:
|
||||
url: https://github.com/kimaah/rounded_expansion_tile.git
|
||||
go_router: ^10.1.2
|
||||
go_router: ^12.1.3
|
||||
flutter_expandable_fab: ^2.0.0
|
||||
intl: ^0.18.1
|
||||
i18n_extension: ^10.0.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^1.0.0
|
||||
flutter_lints: ^3.0.1
|
||||
|
||||
flutter:
|
||||
uses-material-design: true
|
Loading…
x
Reference in New Issue
Block a user