Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add grades page #170

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions .github/workflows/build-preview-apk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ permissions:
repository-projects: write
security-events: write
statuses: write
on:
push:
branches:
- 'build-**'
- '!build-prerelease'
- '!build-release'
on: workflow_dispatch
jobs:
check_changes:
outputs:
Expand Down
228 changes: 226 additions & 2 deletions lib/api.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import 'dart:convert';

import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:dio/dio.dart';
import 'package:eduapge2/timetable.dart';
import 'package:firebase_remote_config/firebase_remote_config.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

Future<bool> isConnected() async {
var connectivityResult = await (Connectivity().checkConnectivity());
Expand All @@ -23,6 +24,7 @@
late User user;
late Timeline timeline;
late TimeTable timetable;
late Grades grades;

static EP2Data? _instance;

Expand Down Expand Up @@ -120,6 +122,12 @@
await timetable.loadRecentTt();
}

grades = (await Grades.loadFromCache()) ?? Grades(events: {}, notes: {});

if (isInternetAvailable && !quickstart) {
await grades.loadGrades();
}

if (quickstart && isInternetAvailable) {
loadInBackground();
}
Expand All @@ -133,6 +141,7 @@
}
await timeline.loadMessages();
await timetable.loadRecentTt();
await grades.loadGrades();
}
}

Expand Down Expand Up @@ -1132,3 +1141,218 @@
await saveToCache();
}
}

class Event {
final String provider;
final String id;
final String studentID;
final String subjectID;
final String eventID;
final String month;
final String data;
final String date;
final String teacherID;
final String signed;
final String signedAdult;
final String timestamp;
final String state;
final String color;
final String eventName;
final String firstAverage;
final dynamic eventType;
final dynamic weight;
final String classID;
final String planID;
final dynamic gradeCount;
final dynamic moreData;
final String average;

Event({
required this.provider,
required this.id,
required this.studentID,
required this.subjectID,
required this.eventID,
required this.month,
required this.data,
required this.date,
required this.teacherID,
required this.signed,
required this.signedAdult,
required this.timestamp,
required this.state,
required this.color,
required this.eventName,
required this.firstAverage,
required this.eventType,
required this.weight,
required this.classID,
required this.planID,
required this.gradeCount,
required this.moreData,
required this.average,
});

factory Event.fromJson(Map<String, dynamic> json) {
return Event(
provider: json['provider'] as String,
id: json['znamkaid'] as String,
studentID: json['studentid'] as String,
subjectID: json['predmetid'] as String,
eventID: json['udalostID'] as String,
month: json['mesiac'] as String,
data: json['data'] as String,
date: json['datum'] as String,
teacherID: json['ucitelid'] as String,
signed: json['podpisane'] as String,
signedAdult: json['podpisane_rodic'] as String,
timestamp: json['timestamp'] as String,
state: json['stav'] as String,
color: json['p_farba'] as String,
eventName: json['p_meno'] as String,
firstAverage: json['p_najskor_priemer'] as String,
eventType: json['p_typ_udalosti'],
weight: json['p_vaha'],
classID: json['TriedaID'] as String,
planID: json['planid'] as String,
gradeCount: json['p_pocet_znamok'],
moreData: json['moredata'],
average: json['priemer'] as String,
);
}

Map<String, dynamic> toJson() {
return {
'provider': provider,
'znamkaid': id,
'studentid': studentID,
'predmetid': subjectID,
'udalostID': eventID,
'mesiac': month,
'data': data,
'datum': date,
'ucitelid': teacherID,
'podpisane': signed,
'podpisane_rodic': signedAdult,
'timestamp': timestamp,
'stav': state,
'p_farba': color,
'p_meno': eventName,
'p_najskor_priemer': firstAverage,
'p_typ_udalosti': eventType,
'p_vaha': weight,
'TriedaID': classID,
'planid': planID,
'p_pocet_znamok': gradeCount,
'moredata': moreData,
'priemer': average,
};
}
}

class Note {
final String id;
final String date;
final String text;
final String type;
final String subjectID;

Note({
required this.id,
required this.date,
required this.text,
required this.type,
required this.subjectID,
});

factory Note.fromJson(Map<String, dynamic> json) {
return Note(
id: json['VcelickaID'] as String,
date: json['p_datum'] as String,
text: json['p_text'] as String,
type: json['p_typ'] as String,
subjectID: json['PredmetID'] as String,
);
}

Map<String, dynamic> toJson() {
return {
'VcelickaID': id,
'p_datum': date,
'p_text': text,
'p_typ': type,
'PredmetID': subjectID,
};
}
}

class Grades {
EP2Data data = EP2Data.getInstance();

final Map<String, Event> events;
final Map<String, Note> notes;

Grades({
required this.events,
required this.notes,
});

factory Grades.fromJson(Map<String, dynamic> json) {
return Grades(
events: (json['Events'] as Map<String, dynamic>).map(
(key, value) =>
MapEntry(key, Event.fromJson(value as Map<String, dynamic>)),

Check warning on line 1304 in lib/api.dart

View check run for this annotation

Codecov / codecov/patch

lib/api.dart#L1300-L1304

Added lines #L1300 - L1304 were not covered by tests
),
notes: (json['Notes'] as Map<String, dynamic>).map(
(key, value) =>
MapEntry(key, Note.fromJson(value as Map<String, dynamic>)),

Check warning on line 1308 in lib/api.dart

View check run for this annotation

Codecov / codecov/patch

lib/api.dart#L1306-L1308

Added lines #L1306 - L1308 were not covered by tests
),
);
}

Map<String, dynamic> toJson() {
return {
'Events': events.map((key, value) => MapEntry(key, value.toJson())),
'Notes': notes.map((key, value) => MapEntry(key, value.toJson())),
};
}

Future<void> saveToCache() async {
final timelineJson = jsonEncode(toJson());
await data.sharedPreferences.setString('grades', timelineJson);
}

static Future<Grades?> loadFromCache() async {
final prefs = await SharedPreferences.getInstance();
final timelineJson = prefs.getString('grades');
if (timelineJson != null) {
return Grades.fromJson(jsonDecode(timelineJson));

Check warning on line 1329 in lib/api.dart

View check run for this annotation

Codecov / codecov/patch

lib/api.dart#L1329

Added line #L1329 was not covered by tests
} else {
return null;
}
}

Future<void> loadGrades() async {
Response response = await data.dio.get(
"${data.baseUrl}/api/grades",
options: Options(
headers: {
"Authorization": "Bearer ${data.user.token}",
},
),
);

Map<String, dynamic> newEvents = response.data["Events"];
Map<String, dynamic> newNotes = response.data["Notes"];

newEvents.forEach((key, value) {
events[key] = Event.fromJson(value);
});

newNotes.forEach((key, value) {
notes[key] = Note.fromJson(value);
});

await saveToCache();
}
}
55 changes: 49 additions & 6 deletions lib/create_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import 'package:eduapge2/main.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:toastification/toastification.dart';

class SendMessageScreen extends StatefulWidget {
const SendMessageScreen({super.key});
Expand Down Expand Up @@ -51,7 +52,7 @@
loc = AppLocalizations.of(context);
return PopScope(
canPop: message.isEmpty,
onPopInvoked: (didPop) {
onPopInvokedWithResult: (didPop, dynamic _) {

Check warning on line 55 in lib/create_message.dart

View check run for this annotation

Codecov / codecov/patch

lib/create_message.dart#L55

Added line #L55 was not covered by tests
if (didPop) {
return;
}
Expand Down Expand Up @@ -317,6 +318,24 @@

final messageOptionsJson = jsonEncode(messageOptions);

Navigator.of(context).pop();

Check warning on line 321 in lib/create_message.dart

View check run for this annotation

Codecov / codecov/patch

lib/create_message.dart#L321

Added line #L321 was not covered by tests

toastification.show(

Check warning on line 323 in lib/create_message.dart

View check run for this annotation

Codecov / codecov/patch

lib/create_message.dart#L323

Added line #L323 was not covered by tests
type: ToastificationType.info,
style: ToastificationStyle.flat,
title: Text(loc!.createMessageNotifSending),
description: Text(loc!.createMessageNotifSendingBody),

Check warning on line 327 in lib/create_message.dart

View check run for this annotation

Codecov / codecov/patch

lib/create_message.dart#L326-L327

Added lines #L326 - L327 were not covered by tests
alignment: Alignment.bottomCenter,
autoCloseDuration: const Duration(seconds: 2),
icon: Icon(Icons.send_rounded),
borderRadius: BorderRadius.circular(12.0),

Check warning on line 331 in lib/create_message.dart

View check run for this annotation

Codecov / codecov/patch

lib/create_message.dart#L330-L331

Added lines #L330 - L331 were not covered by tests
boxShadow: highModeShadow,
showProgressBar: true,
closeButtonShowType: CloseButtonShowType.none,
closeOnClick: false,
applyBlurEffect: true,
);

data.dio
.post(
"${data.baseUrl}/api/message",
Expand All @@ -330,13 +349,37 @@
),
)
.then((response) {
Navigator.of(context).pop();
toastification.show(

Check warning on line 352 in lib/create_message.dart

View check run for this annotation

Codecov / codecov/patch

lib/create_message.dart#L352

Added line #L352 was not covered by tests
type: ToastificationType.success,
style: ToastificationStyle.flat,
title: Text(loc!.createMessageNotifSent),
description: Text(loc!.createMessageNotifSentBody),

Check warning on line 356 in lib/create_message.dart

View check run for this annotation

Codecov / codecov/patch

lib/create_message.dart#L355-L356

Added lines #L355 - L356 were not covered by tests
alignment: Alignment.bottomCenter,
autoCloseDuration: const Duration(seconds: 4),
icon: Icon(Icons.check),
borderRadius: BorderRadius.circular(12.0),

Check warning on line 360 in lib/create_message.dart

View check run for this annotation

Codecov / codecov/patch

lib/create_message.dart#L359-L360

Added lines #L359 - L360 were not covered by tests
boxShadow: highModeShadow,
showProgressBar: true,
closeButtonShowType: CloseButtonShowType.none,
closeOnClick: false,
applyBlurEffect: true,
);
}).catchError((error) {
final snackBar = SnackBar(
content: Text(error.toString()),
toastification.show(

Check warning on line 368 in lib/create_message.dart

View check run for this annotation

Codecov / codecov/patch

lib/create_message.dart#L368

Added line #L368 was not covered by tests
type: ToastificationType.error,
style: ToastificationStyle.flat,
title: Text(loc!.createMessageNotifError),
description: Text(loc!.createMessageNotifErrorBody),

Check warning on line 372 in lib/create_message.dart

View check run for this annotation

Codecov / codecov/patch

lib/create_message.dart#L371-L372

Added lines #L371 - L372 were not covered by tests
alignment: Alignment.bottomCenter,
autoCloseDuration: const Duration(seconds: 4),
icon: Icon(Icons.cancel),
borderRadius: BorderRadius.circular(12.0),

Check warning on line 376 in lib/create_message.dart

View check run for this annotation

Codecov / codecov/patch

lib/create_message.dart#L375-L376

Added lines #L375 - L376 were not covered by tests
boxShadow: highModeShadow,
showProgressBar: true,
closeButtonShowType: CloseButtonShowType.none,
closeOnClick: false,
applyBlurEffect: true,
);

ScaffoldMessenger.of(context).showSnackBar(snackBar);
});
},
child: Text(loc!.createMessageSend),
Expand Down
Loading
Loading