commit
151e97b243
@ -2,7 +2,7 @@ import 'package:connectivity_plus/connectivity_plus.dart';
|
|||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
enum Status { network, maintenance, syncing }
|
enum Status { network, maintenance, syncing, apiError }
|
||||||
|
|
||||||
class StatusProvider extends ChangeNotifier {
|
class StatusProvider extends ChangeNotifier {
|
||||||
final List<Status> _stack = [];
|
final List<Status> _stack = [];
|
||||||
@ -37,7 +37,8 @@ class StatusProvider extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void triggerRequest(http.Response res) {
|
void triggerRequest(http.Response res) {
|
||||||
if (res.headers.containsKey("x-maintenance-mode") || res.statusCode == 503) {
|
if (res.headers.containsKey("x-maintenance-mode") ||
|
||||||
|
res.statusCode == 503) {
|
||||||
if (!_stack.contains(Status.maintenance)) {
|
if (!_stack.contains(Status.maintenance)) {
|
||||||
_stack.insert(0, Status.maintenance);
|
_stack.insert(0, Status.maintenance);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@ -48,6 +49,21 @@ class StatusProvider extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res.body == "invalid_grant" ||
|
||||||
|
res.body.replaceAll(' ', '') == '' ||
|
||||||
|
res.statusCode == 400) {
|
||||||
|
if (!_stack.contains(Status.apiError)) {
|
||||||
|
_stack.insert(0, Status.apiError);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_stack.contains(Status.apiError) &&
|
||||||
|
res.request?.url.path != '/nonce') {
|
||||||
|
_stack.remove(Status.apiError);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void triggerSync({required int current, required int max}) {
|
void triggerSync({required int current, required int max}) {
|
||||||
|
@ -44,7 +44,7 @@ dependencies:
|
|||||||
quick_actions: ^1.0.1
|
quick_actions: ^1.0.1
|
||||||
animated_list_plus: ^0.5.0
|
animated_list_plus: ^0.5.0
|
||||||
dynamic_color: ^1.2.2
|
dynamic_color: ^1.2.2
|
||||||
material_color_utilities: ^0.2.0
|
material_color_utilities: ^0.5.0
|
||||||
crypto: ^3.0.2
|
crypto: ^3.0.2
|
||||||
elegant_notification: ^1.6.1
|
elegant_notification: ^1.6.1
|
||||||
flutter_feather_icons: ^2.0.0+1
|
flutter_feather_icons: ^2.0.0+1
|
||||||
|
@ -15,11 +15,11 @@ import 'login_screen.i18n.dart';
|
|||||||
|
|
||||||
const LinearGradient _backgroundGradient = LinearGradient(
|
const LinearGradient _backgroundGradient = LinearGradient(
|
||||||
colors: [
|
colors: [
|
||||||
Color.fromARGB(255, 0, 0, 0),
|
Color.fromARGB(255, 61, 122, 244),
|
||||||
Color.fromARGB(255, 23, 77, 185),
|
Color.fromARGB(255, 23, 77, 185),
|
||||||
Color.fromARGB(255, 7, 42, 112),
|
Color.fromARGB(255, 7, 42, 112),
|
||||||
],
|
],
|
||||||
begin: Alignment(-0.8, -2),
|
begin: Alignment(-0.8, -2.0),
|
||||||
end: Alignment(0.8, 1.0),
|
end: Alignment(0.8, 1.0),
|
||||||
stops: [-1.0, 0.0, 1.0],
|
stops: [-1.0, 0.0, 1.0],
|
||||||
);
|
);
|
||||||
@ -90,7 +90,7 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Container(
|
body: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
gradient: _backgroundGradient,
|
gradient: _backgroundGradient,
|
||||||
),
|
),
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
|
@ -89,6 +89,9 @@ class KretaClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (res == null) throw "Login error";
|
if (res == null) throw "Login error";
|
||||||
|
if (res.body == 'invalid_grant' || res.body.replaceAll(' ', '') == '') {
|
||||||
|
throw "Auth error";
|
||||||
|
}
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
return jsonDecode(res.body);
|
return jsonDecode(res.body);
|
||||||
|
@ -5,6 +5,7 @@ import 'package:filcnaplo/models/user.dart';
|
|||||||
import 'package:filcnaplo_kreta_api/client/api.dart';
|
import 'package:filcnaplo_kreta_api/client/api.dart';
|
||||||
import 'package:filcnaplo_kreta_api/client/client.dart';
|
import 'package:filcnaplo_kreta_api/client/client.dart';
|
||||||
import 'package:filcnaplo_kreta_api/models/homework.dart';
|
import 'package:filcnaplo_kreta_api/models/homework.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
@ -83,7 +84,10 @@ class HomeworkProvider with ChangeNotifier {
|
|||||||
// error fetcing homework (unknown error)
|
// error fetcing homework (unknown error)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (homeworkJson == null) throw "Cannot fetch Homework for User ${user.id}";
|
if (homeworkJson == null) {
|
||||||
|
if (kDebugMode) print("Cannot fetch Homework for User ${user.id}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
List<Homework> homework = [];
|
List<Homework> homework = [];
|
||||||
await Future.forEach(homeworkJson.cast<Map>(), (Map hw) async {
|
await Future.forEach(homeworkJson.cast<Map>(), (Map hw) async {
|
||||||
|
@ -67,15 +67,21 @@ class TimetableProvider with ChangeNotifier {
|
|||||||
String iss = user.instituteCode;
|
String iss = user.instituteCode;
|
||||||
List? lessonsJson = await _kreta
|
List? lessonsJson = await _kreta
|
||||||
.getAPI(KretaAPI.timetable(iss, start: week.start, end: week.end));
|
.getAPI(KretaAPI.timetable(iss, start: week.start, end: week.end));
|
||||||
if (lessonsJson == null) throw "Cannot fetch Lessons for User ${user.id}";
|
|
||||||
List<Lesson> lessonsList = lessonsJson.map((e) => Lesson.fromJson(e)).toList();
|
|
||||||
|
|
||||||
if (lessons.isEmpty && lessons.isEmpty) return;
|
if (lessonsJson == null) {
|
||||||
|
return;
|
||||||
|
// throw "Cannot fetch Lessons for User ${user.id}";
|
||||||
|
} else {
|
||||||
|
List<Lesson> lessonsList =
|
||||||
|
lessonsJson.map((e) => Lesson.fromJson(e)).toList();
|
||||||
|
|
||||||
lessons[week] = lessonsList;
|
if (lessons.isEmpty) return;
|
||||||
|
|
||||||
await store();
|
lessons[week] = lessonsList;
|
||||||
await convertBySettings();
|
|
||||||
|
await store();
|
||||||
|
await convertBySettings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stores Lessons in the database
|
// Stores Lessons in the database
|
||||||
|
@ -15,7 +15,8 @@ class MissedExamView extends StatelessWidget {
|
|||||||
|
|
||||||
final List<Lesson> missedExams;
|
final List<Lesson> missedExams;
|
||||||
|
|
||||||
static show(List<Lesson> missedExams, {required BuildContext context}) => showRoundedModalBottomSheet(context, child: MissedExamView(missedExams));
|
static show(List<Lesson> missedExams, {required BuildContext context}) =>
|
||||||
|
showRoundedModalBottomSheet(context, child: MissedExamView(missedExams));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -25,7 +26,8 @@ class MissedExamView extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MissedExamViewTile extends StatelessWidget {
|
class MissedExamViewTile extends StatelessWidget {
|
||||||
const MissedExamViewTile(this.lesson, {Key? key, this.padding}) : super(key: key);
|
const MissedExamViewTile(this.lesson, {Key? key, this.padding})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
final EdgeInsetsGeometry? padding;
|
final EdgeInsetsGeometry? padding;
|
||||||
final Lesson lesson;
|
final Lesson lesson;
|
||||||
@ -33,23 +35,36 @@ class MissedExamViewTile extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
SettingsProvider settingsProvider = Provider.of<SettingsProvider>(context);
|
SettingsProvider settingsProvider = Provider.of<SettingsProvider>(context);
|
||||||
|
|
||||||
|
String? teacherName = lesson.teacher.isRenamed
|
||||||
|
? lesson.teacher.renamedTo
|
||||||
|
: lesson.teacher.name;
|
||||||
|
|
||||||
return Material(
|
return Material(
|
||||||
type: MaterialType.transparency,
|
type: MaterialType.transparency,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: padding ?? const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
|
padding: padding ??
|
||||||
|
const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
|
shape:
|
||||||
|
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
|
||||||
leading: Icon(
|
leading: Icon(
|
||||||
SubjectIcon.resolveVariant(subject: lesson.subject, context: context),
|
SubjectIcon.resolveVariant(
|
||||||
|
subject: lesson.subject, context: context),
|
||||||
color: AppColors.of(context).text.withOpacity(.8),
|
color: AppColors.of(context).text.withOpacity(.8),
|
||||||
size: 32.0,
|
size: 32.0,
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
"${lesson.subject.renamedTo ?? lesson.subject.name.capital()} • ${lesson.date.format(context)}",
|
"${lesson.subject.renamedTo ?? lesson.subject.name.capital()} • ${lesson.date.format(context)}",
|
||||||
style: TextStyle(fontWeight: FontWeight.w600, fontStyle: lesson.subject.isRenamed && settingsProvider.renamedSubjectsItalics ? FontStyle.italic : null),
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontStyle: lesson.subject.isRenamed &&
|
||||||
|
settingsProvider.renamedSubjectsItalics
|
||||||
|
? FontStyle.italic
|
||||||
|
: null),
|
||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
"missed_exam_contact".i18n.fill([lesson.teacher]),
|
"missed_exam_contact".i18n.fill([teacherName ?? '']),
|
||||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
trailing: const Icon(FeatherIcons.arrowRight),
|
trailing: const Icon(FeatherIcons.arrowRight),
|
||||||
|
@ -39,7 +39,9 @@ class _StatusBarState extends State<StatusBar> {
|
|||||||
height: currentStatus != null ? 28.0 : 0,
|
height: currentStatus != null ? 28.0 : 0,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: backgroundColor,
|
color: backgroundColor,
|
||||||
boxShadow: [BoxShadow(color: Theme.of(context).shadowColor, blurRadius: 8.0)],
|
boxShadow: [
|
||||||
|
BoxShadow(color: Theme.of(context).shadowColor, blurRadius: 8.0)
|
||||||
|
],
|
||||||
borderRadius: BorderRadius.circular(45.0),
|
borderRadius: BorderRadius.circular(45.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -53,9 +55,12 @@ class _StatusBarState extends State<StatusBar> {
|
|||||||
height: currentStatus != null ? 28.0 : 0,
|
height: currentStatus != null ? 28.0 : 0,
|
||||||
duration: const Duration(milliseconds: 250),
|
duration: const Duration(milliseconds: 250),
|
||||||
curve: Curves.easeInOut,
|
curve: Curves.easeInOut,
|
||||||
width: MediaQuery.of(context).size.width * statusProvider.progress - 16.0,
|
width: MediaQuery.of(context).size.width *
|
||||||
|
statusProvider.progress -
|
||||||
|
16.0,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.secondary.withOpacity(0.8),
|
color:
|
||||||
|
Theme.of(context).colorScheme.secondary.withOpacity(0.8),
|
||||||
borderRadius: BorderRadius.circular(45.0),
|
borderRadius: BorderRadius.circular(45.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -82,6 +87,8 @@ class _StatusBarState extends State<StatusBar> {
|
|||||||
return "Syncing data".i18n;
|
return "Syncing data".i18n;
|
||||||
case Status.maintenance:
|
case Status.maintenance:
|
||||||
return "KRETA Maintenance".i18n;
|
return "KRETA Maintenance".i18n;
|
||||||
|
case Status.apiError:
|
||||||
|
return "KRETA API error".i18n;
|
||||||
case Status.network:
|
case Status.network:
|
||||||
return "No connection".i18n;
|
return "No connection".i18n;
|
||||||
default:
|
default:
|
||||||
@ -93,10 +100,13 @@ class _StatusBarState extends State<StatusBar> {
|
|||||||
switch (status) {
|
switch (status) {
|
||||||
case Status.maintenance:
|
case Status.maintenance:
|
||||||
return AppColors.of(context).red;
|
return AppColors.of(context).red;
|
||||||
|
case Status.apiError:
|
||||||
|
return AppColors.of(context).red;
|
||||||
case Status.network:
|
case Status.network:
|
||||||
case Status.syncing:
|
case Status.syncing:
|
||||||
default:
|
default:
|
||||||
HSLColor color = HSLColor.fromColor(Theme.of(context).scaffoldBackgroundColor);
|
HSLColor color =
|
||||||
|
HSLColor.fromColor(Theme.of(context).scaffoldBackgroundColor);
|
||||||
if (color.lightness >= 0.5) {
|
if (color.lightness >= 0.5) {
|
||||||
color = color.withSaturation(0.3);
|
color = color.withSaturation(0.3);
|
||||||
color = color.withLightness(color.lightness - 0.1);
|
color = color.withLightness(color.lightness - 0.1);
|
||||||
|
@ -6,16 +6,19 @@ extension Localization on String {
|
|||||||
"en_en": {
|
"en_en": {
|
||||||
"Syncing data": "Syncing data",
|
"Syncing data": "Syncing data",
|
||||||
"KRETA Maintenance": "KRETA Maintenance",
|
"KRETA Maintenance": "KRETA Maintenance",
|
||||||
|
"KRETA API error": "KRETA API Error",
|
||||||
"No connection": "No connection",
|
"No connection": "No connection",
|
||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
"Syncing data": "Adatok frissítése",
|
"Syncing data": "Adatok frissítése",
|
||||||
"KRETA Maintenance": "KRÉTA Karbantartás",
|
"KRETA Maintenance": "KRÉTA Karbantartás",
|
||||||
|
"KRETA API error": "KRÉTA API Hiba",
|
||||||
"No connection": "Nincs kapcsolat",
|
"No connection": "Nincs kapcsolat",
|
||||||
},
|
},
|
||||||
"de_de": {
|
"de_de": {
|
||||||
"Syncing data": "Daten aktualisieren",
|
"Syncing data": "Daten aktualisieren",
|
||||||
"KRETA Maintenance": "KRETA Wartung",
|
"KRETA Maintenance": "KRETA Wartung",
|
||||||
|
"KRETA API error": "KRETA API Fehler",
|
||||||
"No connection": "Keine Verbindung",
|
"No connection": "Keine Verbindung",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user