diff --git a/filcnaplo/lib/helpers/attachment_helper.dart b/filcnaplo/lib/helpers/attachment_helper.dart index 187bef7..24b88b1 100644 --- a/filcnaplo/lib/helpers/attachment_helper.dart +++ b/filcnaplo/lib/helpers/attachment_helper.dart @@ -9,16 +9,20 @@ import 'package:filcnaplo_kreta_api/client/client.dart'; import 'package:filcnaplo_kreta_api/models/attachment.dart'; import 'package:filcnaplo_kreta_api/models/homework.dart'; import 'package:flutter/widgets.dart'; -import 'package:open_file/open_file.dart'; +import 'package:open_filex/open_filex.dart'; import 'package:provider/provider.dart'; extension AttachmentHelper on Attachment { - Future download(BuildContext context, {bool overwrite = false}) async { + Future download(BuildContext context, + {bool overwrite = false}) async { String downloads = await StorageHelper.downloadsPath(); - if (!overwrite && await File("$downloads/$name").exists()) return "$downloads/$name"; + if (!overwrite && await File("$downloads/$name").exists()) { + return "$downloads/$name"; + } - Uint8List data = await Provider.of(context, listen: false).getAPI(downloadUrl, rawResponse: true); + Uint8List data = await Provider.of(context, listen: false) + .getAPI(downloadUrl, rawResponse: true); if (!await StorageHelper.write("$downloads/$name", data)) return ""; return "$downloads/$name"; @@ -28,19 +32,24 @@ extension AttachmentHelper on Attachment { String downloads = await StorageHelper.downloadsPath(); if (!await File("$downloads/$name").exists()) await download(context); - var result = await OpenFile.open("$downloads/$name"); + var result = await OpenFilex.open("$downloads/$name"); return result.type == ResultType.done; } } extension HomeworkAttachmentHelper on HomeworkAttachment { - Future download(BuildContext context, {bool overwrite = false}) async { + Future download(BuildContext context, + {bool overwrite = false}) async { String downloads = await StorageHelper.downloadsPath(); - if (!overwrite && await File("$downloads/$name").exists()) return "$downloads/$name"; + if (!overwrite && await File("$downloads/$name").exists()) { + return "$downloads/$name"; + } - String url = downloadUrl(Provider.of(context, listen: false).instituteCode ?? ""); - Uint8List data = await Provider.of(context, listen: false).getAPI(url, rawResponse: true); + String url = downloadUrl( + Provider.of(context, listen: false).instituteCode ?? ""); + Uint8List data = await Provider.of(context, listen: false) + .getAPI(url, rawResponse: true); if (!await StorageHelper.write("$downloads/$name", data)) return ""; return "$downloads/$name"; @@ -50,7 +59,7 @@ extension HomeworkAttachmentHelper on HomeworkAttachment { String downloads = await StorageHelper.downloadsPath(); if (!await File("$downloads/$name").exists()) await download(context); - var result = await OpenFile.open("$downloads/$name"); + var result = await OpenFilex.open("$downloads/$name"); return result.type == ResultType.done; } } diff --git a/filcnaplo/lib/helpers/update_helper.dart b/filcnaplo/lib/helpers/update_helper.dart index 0c33860..2fd604e 100644 --- a/filcnaplo/lib/helpers/update_helper.dart +++ b/filcnaplo/lib/helpers/update_helper.dart @@ -5,7 +5,7 @@ import 'dart:typed_data'; import 'package:filcnaplo/api/client.dart'; import 'package:filcnaplo/helpers/storage_helper.dart'; import 'package:filcnaplo/models/release.dart'; -import 'package:open_file/open_file.dart'; +import 'package:open_filex/open_filex.dart'; import 'package:permission_handler/permission_handler.dart'; enum UpdateState { none, preparing, downloading, installing } @@ -37,7 +37,7 @@ extension UpdateHelper on Release { (await Permission.manageExternalStorage.request().isGranted && await Permission.requestInstallPackages.request().isGranted); if (installPerms) { - var result = await OpenFile.open(apk.path); + var result = await OpenFilex.open(apk.path); if (result.type != ResultType.done) { // ignore: avoid_print diff --git a/filcnaplo/pubspec.yaml b/filcnaplo/pubspec.yaml index 9015adb..68451e6 100644 --- a/filcnaplo/pubspec.yaml +++ b/filcnaplo/pubspec.yaml @@ -3,7 +3,7 @@ description: "Nem hivatalos e-napló alkalmazás az e-Kréta rendszerhez" homepage: https://refilc.hu publish_to: "none" -version: 4.4.1+234 +version: 4.5.0+236 environment: sdk: ">=2.17.0 <3.0.0" @@ -32,10 +32,11 @@ dependencies: http: ^0.13.3 uuid: ^4.2.1 html: ^0.15.0 - open_file: - git: - url: https://github.com/crazecoder/open_file - ref: master + open_filex: ^4.3.4 + # open_file: + # git: + # url: https://github.com/crazecoder/open_file + # ref: master path_provider: ^2.0.2 permission_handler: ^11.0.1 share_plus: ^7.0.2 diff --git a/filcnaplo_desktop_ui/lib/pages/grades/grade_subject_view.dart b/filcnaplo_desktop_ui/lib/pages/grades/grade_subject_view.dart index 1b30577..a08e173 100644 --- a/filcnaplo_desktop_ui/lib/pages/grades/grade_subject_view.dart +++ b/filcnaplo_desktop_ui/lib/pages/grades/grade_subject_view.dart @@ -1,6 +1,7 @@ import 'dart:math'; import 'package:animations/animations.dart'; +import 'package:filcnaplo/models/settings.dart'; import 'package:filcnaplo/utils/format.dart'; import 'package:filcnaplo_kreta_api/providers/grade_provider.dart'; import 'package:filcnaplo/helpers/average_helper.dart'; @@ -56,6 +57,7 @@ class _GradeSubjectViewState extends State { // Providers late GradeProvider gradeProvider; late GradeCalculatorProvider calculatorProvider; + late SettingsProvider settingsProvider; late double average; late Widget gradeGraph; @@ -142,6 +144,7 @@ class _GradeSubjectViewState extends State { Widget build(BuildContext context) { gradeProvider = Provider.of(context); calculatorProvider = Provider.of(context); + settingsProvider = Provider.of(context); List subjectGrades = getSubjectGrades(widget.subject).toList(); average = AverageHelper.averageEvals(subjectGrades); @@ -244,7 +247,8 @@ class _GradeSubjectViewState extends State { subject: widget.subject, context: context), scrollController: _scrollController, title: widget.subject.renamedTo ?? widget.subject.name.capital(), - italic: widget.subject.isRenamed, + italic: widget.subject.isRenamed && + settingsProvider.renamedSubjectsItalics, child: SubjectGradesContainer( child: CupertinoScrollbar( child: ListView.builder( diff --git a/filcnaplo_kreta_api/lib/client/client.dart b/filcnaplo_kreta_api/lib/client/client.dart index 97aef58..f9a4589 100644 --- a/filcnaplo_kreta_api/lib/client/client.dart +++ b/filcnaplo_kreta_api/lib/client/client.dart @@ -156,6 +156,7 @@ class KretaClient { if (res == null) throw "Login error"; if (json) { + print(jsonDecode(res.body)); return jsonDecode(res.body); } else { return res.body; @@ -168,6 +169,69 @@ class KretaClient { } } + Future sendFilesAPI( + String url, { + Map? headers, + bool autoHeader = true, + Map? body, + }) async { + Map headerMap; + + if (headers != null) { + headerMap = headers; + } else { + headerMap = {}; + } + + try { + http.StreamedResponse? res; + + for (int i = 0; i < 3; i++) { + if (autoHeader) { + if (!headerMap.containsKey("authorization") && accessToken != null) { + headerMap["authorization"] = "Bearer $accessToken"; + } + if (!headerMap.containsKey("user-agent") && userAgent != null) { + headerMap["user-agent"] = "$userAgent"; + } + if (!headerMap.containsKey("content-type")) { + headerMap["content-type"] = "multipart/form-data"; + } + if (url.contains('kommunikacio/uzenetek')) { + headerMap["X-Uzenet-Lokalizacio"] = "hu-HU"; + } + } + + var request = http.MultipartRequest("POST", Uri.parse(url)); + + // request.files.add(value) + + request.fields.addAll(body ?? {}); + request.headers.addAll(headers ?? {}); + + res = await request.send(); + + if (res.statusCode == 401) { + await refreshLogin(); + headerMap.remove("authorization"); + } else { + break; + } + } + + if (res == null) throw "Login error"; + + print(res.statusCode); + + return res.statusCode; + } on http.ClientException catch (error) { + print( + "ERROR: KretaClient.postAPI ($url) ClientException: ${error.message}"); + } catch (error) { + print("ERROR: KretaClient.postAPI ($url) ${error.runtimeType}: $error"); + } + } + Future refreshLogin() async { if (_loginRefreshing) return; _loginRefreshing = true; diff --git a/filcnaplo_kreta_api/lib/models/message.dart b/filcnaplo_kreta_api/lib/models/message.dart index 711f7a9..e938ff5 100644 --- a/filcnaplo_kreta_api/lib/models/message.dart +++ b/filcnaplo_kreta_api/lib/models/message.dart @@ -156,8 +156,9 @@ class SendRecipient { }); factory SendRecipient.fromJson(Map json, SendRecipientType type) { + print(json); return SendRecipient( - id: int.parse(json['oktatasiAzonosito'] ?? '0'), + id: int.parse(json['kretaAzonosito'] ?? '0'), kretaId: json['kretaAzonosito'], name: json['nev'], type: type, @@ -166,7 +167,7 @@ class SendRecipient { } Object get kretaJson => { - 'azonosito': id ?? 0, + 'azonosito': kretaId ?? 0, 'kretaAzonosito': kretaId ?? 0, 'nev': name ?? 'Teszt Lajos', 'tipus': { diff --git a/filcnaplo_kreta_api/lib/providers/message_provider.dart b/filcnaplo_kreta_api/lib/providers/message_provider.dart index f704d72..a04e1a1 100644 --- a/filcnaplo_kreta_api/lib/providers/message_provider.dart +++ b/filcnaplo_kreta_api/lib/providers/message_provider.dart @@ -1,5 +1,5 @@ // ignore_for_file: use_build_context_synchronously - +import 'dart:convert'; import 'dart:math'; import 'package:filcnaplo/api/providers/user_provider.dart'; @@ -209,7 +209,7 @@ class MessageProvider with ChangeNotifier { } // send message - Future sendMessage({ + Future sendMessage({ required List recipients, String subject = "Nincs tárgy", required String messageText, @@ -235,20 +235,34 @@ class MessageProvider with ChangeNotifier { // } recipientList.addAll(recipients.map((e) => e.kretaJson)); - Object body = { + Map body = { "cimzettLista": recipientList, "csatolmanyok": [], - "azonosito": Random().nextInt(10000) + 10000, + "azonosito": (Random().nextInt(10000) + 10000), "feladoNev": user.name, "feladoTitulus": user.role == Role.parent ? "Szülő" : "Diák", "kuldesDatum": DateTime.now().toIso8601String(), "targy": subject, "szoveg": messageText, - "elozoUzenetAzonosito": 0, + // "elozoUzenetAzonosito": 0, }; - // send the message - await Provider.of(_context, listen: false) - .postAPI(KretaAPI.sendMessage, autoHeader: true, body: body); + Map headers = { + "content-type": "application/json", + }; + + var res = await Provider.of(_context, listen: false).postAPI( + KretaAPI.sendMessage, + autoHeader: true, + json: true, + body: json.encode(body), + headers: headers, + ); + + if (res!['hibakod'] == 'UzenetKuldesEngedelyRule') { + return 'send_permission_error'; + } + + return 'successfully_sent'; } } diff --git a/filcnaplo_mobile_ui/lib/common/widgets/grade/surprise_grade.dart b/filcnaplo_mobile_ui/lib/common/widgets/grade/surprise_grade.dart index 5342143..2ec8873 100755 --- a/filcnaplo_mobile_ui/lib/common/widgets/grade/surprise_grade.dart +++ b/filcnaplo_mobile_ui/lib/common/widgets/grade/surprise_grade.dart @@ -3,11 +3,13 @@ import 'dart:ui'; import 'package:animated_background/animated_background.dart' as bg; import 'package:filcnaplo/helpers/subject.dart'; +import 'package:filcnaplo/models/settings.dart'; import 'package:filcnaplo/ui/widgets/grade/grade_tile.dart'; import 'package:filcnaplo_kreta_api/models/grade.dart'; import 'package:filcnaplo_mobile_ui/pages/home/particle.dart'; import 'package:flutter/material.dart'; import 'package:filcnaplo/utils/format.dart'; +import 'package:provider/provider.dart'; import 'package:rive/rive.dart' as rive; import 'new_grades.i18n.dart'; @@ -21,20 +23,27 @@ class SurpriseGrade extends StatefulWidget { State createState() => _SurpriseGradeState(); } -class _SurpriseGradeState extends State with TickerProviderStateMixin { +class _SurpriseGradeState extends State + with TickerProviderStateMixin { late AnimationController _revealAnimFade; late AnimationController _revealAnimScale; late AnimationController _revealAnimGrade; late AnimationController _revealAnimParticle; late rive.RiveAnimationController _controller; + late SettingsProvider settingsProvider; + @override void initState() { super.initState(); - _revealAnimFade = AnimationController(vsync: this, duration: const Duration(milliseconds: 500)); - _revealAnimScale = AnimationController(vsync: this, duration: const Duration(milliseconds: 300)); - _revealAnimGrade = AnimationController(vsync: this, duration: const Duration(seconds: 1)); - _revealAnimParticle = AnimationController(vsync: this, duration: const Duration(seconds: 2)); + _revealAnimFade = AnimationController( + vsync: this, duration: const Duration(milliseconds: 500)); + _revealAnimScale = AnimationController( + vsync: this, duration: const Duration(milliseconds: 300)); + _revealAnimGrade = + AnimationController(vsync: this, duration: const Duration(seconds: 1)); + _revealAnimParticle = + AnimationController(vsync: this, duration: const Duration(seconds: 2)); _revealAnimScale.animateTo(0.7, duration: Duration.zero); _controller = rive.SimpleAnimation('Timeline 1', autoplay: false); WidgetsBinding.instance.addPostFrameCallback((_) { @@ -65,7 +74,9 @@ class _SurpriseGradeState extends State with TickerProviderStateM void reveal() async { if (!subtitle) { - _revealAnimParticle.animateBack(0.0, curve: Curves.fastLinearToSlowEaseIn, duration: const Duration(milliseconds: 300)); + _revealAnimParticle.animateBack(0.0, + curve: Curves.fastLinearToSlowEaseIn, + duration: const Duration(milliseconds: 300)); await Future.delayed(const Duration(milliseconds: 50)); _revealAnimGrade.animateBack(0.0, curve: Curves.fastLinearToSlowEaseIn); await Future.delayed(const Duration(milliseconds: 50)); @@ -78,13 +89,20 @@ class _SurpriseGradeState extends State with TickerProviderStateM setState(() => hold = false); _controller.isActive = true; await Future.delayed(const Duration(seconds: 2)); - if (mounted) _revealAnimGrade.animateTo(1.0, curve: Curves.fastLinearToSlowEaseIn); + if (mounted) { + _revealAnimGrade.animateTo(1.0, curve: Curves.fastLinearToSlowEaseIn); + } await Future.delayed(const Duration(milliseconds: 700)); - if (mounted) await _revealAnimParticle.animateTo(1.0, curve: Curves.fastLinearToSlowEaseIn); + if (mounted) { + await _revealAnimParticle.animateTo(1.0, + curve: Curves.fastLinearToSlowEaseIn); + } } @override Widget build(BuildContext context) { + settingsProvider = Provider.of(context); + return AnimatedBuilder( animation: _revealAnimFade, builder: (context, child) { @@ -136,7 +154,8 @@ class _SurpriseGradeState extends State with TickerProviderStateM mainAxisAlignment: MainAxisAlignment.center, children: [ SlideTransition( - position: _revealAnimGrade.drive(Tween(begin: Offset.zero, end: const Offset(0, 0.7))), + position: _revealAnimGrade.drive( + Tween(begin: Offset.zero, end: const Offset(0, 0.7))), child: AnimatedScale( scale: hold ? 1.1 : 1.0, curve: Curves.easeOutBack, @@ -146,7 +165,10 @@ class _SurpriseGradeState extends State with TickerProviderStateM onLongPressEnd: (_) => reveal(), onLongPressCancel: reveal, child: ScaleTransition( - scale: CurvedAnimation(curve: Curves.easeInOut, parent: _revealAnimGrade.drive(Tween(begin: 1.0, end: 0.8))), + scale: CurvedAnimation( + curve: Curves.easeInOut, + parent: _revealAnimGrade + .drive(Tween(begin: 1.0, end: 0.8))), child: Stack( alignment: Alignment.center, children: [ @@ -161,66 +183,101 @@ class _SurpriseGradeState extends State with TickerProviderStateM ), ), SlideTransition( - position: _revealAnimParticle.drive(Tween(begin: const Offset(0, 0.3), end: const Offset(0, 0.8))), + position: _revealAnimParticle.drive(Tween( + begin: const Offset(0, 0.3), + end: const Offset(0, 0.8))), child: FadeTransition( opacity: _revealAnimParticle, child: ClipRRect( borderRadius: BorderRadius.circular(24.0), child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 32.0, sigmaY: 32.0), + filter: ImageFilter.blur( + sigmaX: 32.0, sigmaY: 32.0), child: Container( width: double.infinity, - padding: const EdgeInsets.symmetric(horizontal: 32.0, vertical: 20.0), + padding: const EdgeInsets.symmetric( + horizontal: 32.0, vertical: 20.0), decoration: BoxDecoration( color: Colors.white.withOpacity(.3), - borderRadius: BorderRadius.circular(24.0), - border: Border.all(color: Colors.black.withOpacity(.3), width: 1.0), + borderRadius: + BorderRadius.circular(24.0), + border: Border.all( + color: Colors.black + .withOpacity(.3), + width: 1.0), ), child: Row( children: [ Expanded( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, + crossAxisAlignment: + CrossAxisAlignment.start, + mainAxisSize: + MainAxisSize.min, children: [ - if (widget.grade.description != "") + if (widget.grade + .description != + "") Text( - widget.grade.description, + widget + .grade.description, style: const TextStyle( color: Colors.white, - fontWeight: FontWeight.bold, + fontWeight: + FontWeight.bold, fontSize: 26.0, ), maxLines: 2, - overflow: TextOverflow.ellipsis, + overflow: TextOverflow + .ellipsis, ), Text( - widget.grade.subject.renamedTo ?? widget.grade.subject.name.capital(), + widget.grade.subject + .renamedTo ?? + widget.grade.subject + .name + .capital(), style: TextStyle( - color: Colors.white.withOpacity(.8), - fontWeight: FontWeight.bold, + color: Colors.white + .withOpacity(.8), + fontWeight: + FontWeight.bold, fontSize: 24.0, - fontStyle: widget.grade.subject.isRenamed ? FontStyle.italic : null), + fontStyle: widget + .grade + .subject + .isRenamed && + settingsProvider + .renamedSubjectsItalics + ? FontStyle.italic + : null), maxLines: 2, - overflow: TextOverflow.ellipsis, + overflow: + TextOverflow.ellipsis, ), const SizedBox(height: 2), Text( "${widget.grade.value.weight}%", style: TextStyle( - color: Colors.white.withOpacity(.7), - fontWeight: FontWeight.w600, + color: Colors.white + .withOpacity(.7), + fontWeight: + FontWeight.w600, fontSize: 20.0, ), maxLines: 2, - overflow: TextOverflow.ellipsis, + overflow: + TextOverflow.ellipsis, ), ], ), ), const SizedBox(width: 20.0), Icon( - SubjectIcon.resolveVariant(subject: widget.grade.subject, context: context), + SubjectIcon.resolveVariant( + subject: + widget.grade.subject, + context: context), color: Colors.white, size: 82.0, ), @@ -257,7 +314,10 @@ class _SurpriseGradeState extends State with TickerProviderStateM animation: _revealAnimParticle, builder: (context, child) { bool shouldPaint = false; - if (_revealAnimParticle.status == AnimationStatus.forward || _revealAnimParticle.status == AnimationStatus.reverse) { + if (_revealAnimParticle.status == + AnimationStatus.forward || + _revealAnimParticle.status == + AnimationStatus.reverse) { shouldPaint = true; } return ScaleTransition( @@ -265,25 +325,46 @@ class _SurpriseGradeState extends State with TickerProviderStateM child: FadeTransition( opacity: _revealAnimGrade, child: SlideTransition( - position: _revealAnimGrade.drive(Tween(begin: Offset.zero, end: const Offset(0, -0.6))), + position: _revealAnimGrade.drive(Tween( + begin: Offset.zero, + end: const Offset(0, -0.6))), child: Column( mainAxisSize: MainAxisSize.min, children: [ SlideTransition( - position: _revealAnimGrade.drive(Tween(begin: Offset.zero, end: const Offset(0, -0.9))), + position: _revealAnimGrade.drive(Tween( + begin: Offset.zero, + end: const Offset(0, -0.9))), child: Text( - ["legendary", "epic", "rare", "uncommon", "common"][5 - widget.grade.value.value].i18n, + [ + "legendary", + "epic", + "rare", + "uncommon", + "common" + ][5 - widget.grade.value.value] + .i18n, style: TextStyle( fontSize: 46.0, fontWeight: FontWeight.bold, - color: gradeColor(context: context, value: widget.grade.value.value), + color: gradeColor( + context: context, + value: widget.grade.value.value), shadows: [ Shadow( - color: gradeColor(context: context, value: widget.grade.value.value).withOpacity(.5), + color: gradeColor( + context: context, + value: + widget.grade.value.value) + .withOpacity(.5), blurRadius: 24.0, ), Shadow( - color: gradeColor(context: context, value: widget.grade.value.value).withOpacity(.3), + color: gradeColor( + context: context, + value: + widget.grade.value.value) + .withOpacity(.3), offset: const Offset(-3, -3), ), ], @@ -292,7 +373,10 @@ class _SurpriseGradeState extends State with TickerProviderStateM ), const SizedBox(height: 32.0), ScaleTransition( - scale: CurvedAnimation(curve: Curves.easeInOutBack, parent: _revealAnimParticle.drive(Tween(begin: 0.6, end: 1.0))), + scale: CurvedAnimation( + curve: Curves.easeInOutBack, + parent: _revealAnimParticle + .drive(Tween(begin: 0.6, end: 1.0))), child: CustomPaint( painter: PimpPainter( particle: Sprinkles(), @@ -308,8 +392,11 @@ class _SurpriseGradeState extends State with TickerProviderStateM shouldPaint: shouldPaint, ), child: RotationTransition( - turns: - CurvedAnimation(curve: Curves.easeInBack, parent: _revealAnimGrade).drive(Tween(begin: 0.95, end: 1.0)), + turns: CurvedAnimation( + curve: Curves.easeInBack, + parent: _revealAnimGrade) + .drive( + Tween(begin: 0.95, end: 1.0)), child: GradeValueWidget( widget.grade.value, fill: true, @@ -337,7 +424,12 @@ class _SurpriseGradeState extends State with TickerProviderStateM } class PimpPainter extends CustomPainter { - PimpPainter({required this.particle, required this.seed, required this.controller, required this.shouldPaint}) : super(repaint: controller); + PimpPainter( + {required this.particle, + required this.seed, + required this.controller, + required this.shouldPaint}) + : super(repaint: controller); final Particle particle; final int seed; @@ -380,7 +472,8 @@ class Sprinkles extends Particle { return AnimatedPositionedParticle( begin: const Offset(0.0, -10.0), end: const Offset(0.0, -60.0), - child: FadingRect(width: 5.0, height: 15.0, color: randomColor(n)), + child: + FadingRect(width: 5.0, height: 15.0, color: randomColor(n)), ); }, initialDistance: -pi / randomMirrorOffset), diff --git a/filcnaplo_mobile_ui/lib/common/widgets/lesson/changed_lesson_tile.dart b/filcnaplo_mobile_ui/lib/common/widgets/lesson/changed_lesson_tile.dart index 9fa3450..de5fffb 100755 --- a/filcnaplo_mobile_ui/lib/common/widgets/lesson/changed_lesson_tile.dart +++ b/filcnaplo_mobile_ui/lib/common/widgets/lesson/changed_lesson_tile.dart @@ -1,8 +1,10 @@ +import 'package:filcnaplo/models/settings.dart'; import 'package:filcnaplo/theme/colors/colors.dart'; import 'package:filcnaplo_kreta_api/models/lesson.dart'; import 'package:flutter/material.dart'; import 'package:filcnaplo/utils/format.dart'; import 'package:flutter_feather_icons/flutter_feather_icons.dart'; +import 'package:provider/provider.dart'; import 'changed_lesson_tile.i18n.dart'; class ChangedLessonTile extends StatelessWidget { @@ -14,6 +16,8 @@ class ChangedLessonTile extends StatelessWidget { @override Widget build(BuildContext context) { + SettingsProvider settingsProvider = Provider.of(context); + String lessonIndexTrailing = ""; // Only put a trailing . if its a digit @@ -56,7 +60,8 @@ class ChangedLessonTile extends StatelessWidget { ), ), title: Text( - lesson.status?.name == "Elmaradt" && lesson.substituteTeacher?.name != "" + lesson.status?.name == "Elmaradt" && + lesson.substituteTeacher?.name != "" ? "cancelled".i18n : "substituted".i18n, maxLines: 2, @@ -69,7 +74,10 @@ class ChangedLessonTile extends StatelessWidget { overflow: TextOverflow.ellipsis, style: TextStyle( fontWeight: FontWeight.w500, - fontStyle: lesson.subject.isRenamed ? FontStyle.italic : null), + fontStyle: lesson.subject.isRenamed && + settingsProvider.renamedSubjectsItalics + ? FontStyle.italic + : null), ), trailing: const Icon(FeatherIcons.arrowRight), minLeadingWidth: 0, diff --git a/filcnaplo_mobile_ui/lib/pages/messages/send_message/send_message.dart b/filcnaplo_mobile_ui/lib/pages/messages/send_message/send_message.dart index 79c520e..6e28737 100644 --- a/filcnaplo_mobile_ui/lib/pages/messages/send_message/send_message.dart +++ b/filcnaplo_mobile_ui/lib/pages/messages/send_message/send_message.dart @@ -1,7 +1,10 @@ +// ignore_for_file: use_build_context_synchronously + import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:filcnaplo/theme/colors/colors.dart'; import 'package:filcnaplo_kreta_api/models/message.dart'; import 'package:filcnaplo_kreta_api/providers/message_provider.dart'; +import 'package:filcnaplo_mobile_ui/common/custom_snack_bar.dart'; // import 'package:filcnaplo_mobile_ui/common/custom_snack_bar.dart'; import 'package:filcnaplo_mobile_ui/common/material_action_button.dart'; import 'package:filcnaplo_mobile_ui/pages/messages/send_message/send_message.i18n.dart'; @@ -190,11 +193,24 @@ class SendMessageSheetState extends State { ? _subjectController.text : 'Nincs tárgy'; - messageProvider.sendMessage( + var res = await messageProvider.sendMessage( recipients: selectedRecipients, subject: subjectText, messageText: _messageController.text, ); + + // do after send + if (res == 'send_permission_error') { + ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar( + content: Text('cant_send'.i18n), context: context)); + } + + if (res == 'successfully_sent') { + ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar( + content: Text('sent'.i18n), context: context)); + } + + Navigator.of(context).pop(); }, ), ), diff --git a/filcnaplo_mobile_ui/lib/pages/messages/send_message/send_message.i18n.dart b/filcnaplo_mobile_ui/lib/pages/messages/send_message/send_message.i18n.dart index e07fe2a..c78c64b 100644 --- a/filcnaplo_mobile_ui/lib/pages/messages/send_message/send_message.i18n.dart +++ b/filcnaplo_mobile_ui/lib/pages/messages/send_message/send_message.i18n.dart @@ -11,6 +11,7 @@ extension Localization on String { "message_subject": "Subject...", "message_text": "Message text...", "select_recipient": "Add Recipient", + "cant_send": "You can't send a message to one of the recipients!", }, "hu_hu": { "recipients": "Címzettek", @@ -20,6 +21,7 @@ extension Localization on String { "message_subject": "Tárgy...", "message_text": "Üzenet szövege...", "select_recipient": "Címzett hozzáadása", + "cant_send": "Az egyik címzettnek nem küldhetsz üzenetet!", }, "de_de": { "recipients": "Empfänger", @@ -29,6 +31,7 @@ extension Localization on String { "message_subject": "Betreff...", "message_text": "Nachrichtentext...", "select_recipient": "Empfänger hinzufügen", + "cant_send": "Neki nem küldhetsz üzenetet!", }, }; diff --git a/filcnaplo_premium b/filcnaplo_premium index 49bc951..078142a 160000 --- a/filcnaplo_premium +++ b/filcnaplo_premium @@ -1 +1 @@ -Subproject commit 49bc951fe97036cc8b3c6a41a0544356c6203bd9 +Subproject commit 078142a3dc2fce9eddb6f608923055943ec4d5e6