Merge pull request #69 from refilc/dev

69-es szamu pr haha 😏
This commit is contained in:
Márton Kiss 2023-10-08 17:00:13 +02:00 committed by GitHub
commit acbffd6d72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 271 additions and 41 deletions

View File

@ -136,7 +136,7 @@
android:layout_below="@id/iv_1"
android:layout_marginHorizontal="15dp"
android:fontFamily="@font/montserrat_medium"
android:text="A widget használatához, bejelentkezés szükséges."
android:text="A widget használatához bejelentkezés szükséges."
android:textColor="@color/black"
android:paddingTop="10dp"
android:textSize="17sp"

View File

@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '11.0'
platform :ios, '12.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
@ -39,5 +39,8 @@ end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
end
end
end

View File

@ -51,7 +51,7 @@ class LiveCardProvider extends ChangeNotifier {
_liveActivitiesPlugin.areActivitiesEnabled().then((value) {
// Console log
if (kDebugMode) {
print("Live card enabled: $value");
print("iOS LiveActivity enabled: $value");
}
if (value) {
@ -62,13 +62,13 @@ class LiveCardProvider extends ChangeNotifier {
});
}
});
_timer = Timer.periodic(const Duration(seconds: 1), (timer) => update());
_delay = settings.bellDelayEnabled
? Duration(seconds: settings.bellDelay)
: Duration.zero;
update();
}
_timer = Timer.periodic(const Duration(seconds: 1), (timer) => update());
_delay = settings.bellDelayEnabled
? Duration(seconds: settings.bellDelay)
: Duration.zero;
update();
}
@override
@ -196,7 +196,7 @@ class LiveCardProvider extends ChangeNotifier {
}
} catch (e) {
if (kDebugMode) {
print('ERROR: Unable to create or update iOS LiveCard!');
print('ERROR: Unable to create or update iOS LiveActivity!');
}
}
}

View File

@ -79,11 +79,12 @@ class StatusProvider extends ChangeNotifier {
}
}
if (_stack.contains(Status.network)) return;
if (res.body == "invalid_grant" ||
if (res.body == 'invalid_grant' ||
res.body.replaceAll(' ', '') == '' ||
res.statusCode == 400) {
if (!_stack.contains(Status.apiError)) {
if (!_stack.contains(Status.apiError) &&
!_stack.contains(Status.network)) {
if (res.statusCode == 401) return;
_stack.insert(0, Status.apiError);
notifyListeners();
}

View File

@ -131,6 +131,7 @@ class App extends StatelessWidget {
create: (context) => HomeworkProvider(
context: context,
database: database,
user: user,
),
),
ChangeNotifierProvider<MessageProvider>(

View File

@ -195,7 +195,7 @@ class NotificationsHelper {
if (userProvider.getUsers().length == 1) {
await flutterLocalNotificationsPlugin.show(
absence.id.hashCode,
"title_absence".i18n,
"title_absence".i18n, // https://discord.com/channels/1111649116020285532/1153273625206591528
"body_absence".i18n.fill(
[
DateFormat("yyyy-MM-dd").format(absence.date),
@ -210,7 +210,7 @@ class NotificationsHelper {
} else {
await flutterLocalNotificationsPlugin.show(
absence.id.hashCode,
"title_absence".i18n,
"title_absence".i18n, // https://discord.com/channels/1111649116020285532/1153273625206591528
"body_absence_multiuser".i18n.fill(
[
userProvider.displayName!,

View File

@ -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.3.0+226
version: 4.3.1+230
environment:
sdk: ">=2.17.0 <3.0.0"

View File

@ -144,8 +144,8 @@ class _GradesPageState extends State<GradesPage> {
Expanded(
child: StatisticsTile(
outline: true,
title: AutoSizeText(
"classavg".i18n,
title: AutoSizeText( // https://discord.com/channels/1111649116020285532/1153397476578050130
"classavg".i18n,
textAlign: TextAlign.center,
maxLines: 2,
wrapWords: false,

View File

@ -0,0 +1,122 @@
import 'package:filcnaplo_mobile_ui/screens/login/login_input.dart';
import 'package:filcnaplo_mobile_ui/screens/login/school_input/school_input_overlay.dart';
import 'package:filcnaplo_desktop_ui/screens/login/school_input/school_input_tile.dart';
import 'package:filcnaplo_mobile_ui/screens/login/school_input/school_search.dart';
import 'package:flutter/material.dart';
import 'package:filcnaplo_kreta_api/models/school.dart';
class SchoolInput extends StatefulWidget {
const SchoolInput({Key? key, required this.controller, required this.scroll})
: super(key: key);
final SchoolInputController controller;
final ScrollController scroll;
@override
_SchoolInputState createState() => _SchoolInputState();
}
class _SchoolInputState extends State<SchoolInput> {
final _focusNode = FocusNode();
final _layerLink = LayerLink();
late SchoolInputOverlay overlay;
@override
void initState() {
super.initState();
widget.controller.update = (fn) {
if (mounted) setState(fn);
};
overlay = SchoolInputOverlay(layerLink: _layerLink);
// Show school list when focused
_focusNode.addListener(() {
if (_focusNode.hasFocus) {
WidgetsBinding.instance
.addPostFrameCallback((_) => overlay.createOverlayEntry(context));
Future.delayed(const Duration(milliseconds: 100)).then((value) {
if (mounted && widget.scroll.hasClients) {
widget.scroll.animateTo(widget.scroll.offset + 500,
duration: const Duration(milliseconds: 500),
curve: Curves.ease);
}
});
} else {
overlay.entry?.remove();
}
});
// LoginInput TextField listener
widget.controller.textController.addListener(() {
String text = widget.controller.textController.text;
if (text.isEmpty) {
overlay.children = null;
return;
}
List<School> results =
searchSchools(widget.controller.schools ?? [], text);
setState(() {
overlay.children = results
.map((School e) => SchoolInputTile(
school: e,
onTap: () => _selectSchool(e),
))
.toList();
});
Overlay.of(context).setState(() {});
});
}
void _selectSchool(School school) {
FocusScope.of(context).requestFocus(FocusNode());
setState(() {
widget.controller.selectedSchool = school;
widget.controller.textController.text = school.name;
});
}
@override
Widget build(BuildContext context) {
return CompositedTransformTarget(
link: _layerLink,
child: widget.controller.schools == null
? Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 10.0),
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.15),
borderRadius: BorderRadius.circular(12.0),
),
child: const Center(
child: SizedBox(
height: 28.0,
width: 28.0,
child: CircularProgressIndicator(
color: Colors.white,
),
),
),
)
: LoginInput(
style: LoginInputStyle.school,
focusNode: _focusNode,
onClear: () {
widget.controller.selectedSchool = null;
FocusScope.of(context).requestFocus(_focusNode);
},
controller: widget.controller.textController,
),
);
}
}
class SchoolInputController {
final textController = TextEditingController();
School? selectedSchool;
List<School>? schools;
late void Function(void Function()) update;
}

View File

@ -0,0 +1,65 @@
import 'package:filcnaplo_kreta_api/models/school.dart';
import 'package:flutter/material.dart';
class SchoolInputTile extends StatelessWidget {
const SchoolInputTile({Key? key, required this.school, this.onTap})
: super(key: key);
final School school;
final Function()? onTap;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(4.0),
child: GestureDetector(
onPanDown: (e) {
onTap!();
},
child: InkWell(
onTapDown: (e) {},
borderRadius: BorderRadius.circular(6.0),
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// School name
Padding(
padding: const EdgeInsets.only(bottom: 4.0),
child: Text(
school.name,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontWeight: FontWeight.w600),
),
),
Row(
children: [
// School id
Expanded(
child: Text(
school.instituteCode,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
// School city
Expanded(
child: Text(
school.city,
textAlign: TextAlign.right,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
],
),
),
),
),
);
}
}

View File

@ -24,10 +24,12 @@ class HomeworkProvider with ChangeNotifier {
List<Homework> initialHomework = const [],
required BuildContext context,
required DatabaseProvider database,
required UserProvider user,
}) {
_homework = List.castFrom(initialHomework);
_context = context;
_database = database;
_user = user;
if (_homework.isEmpty) restore();
}

View File

@ -127,7 +127,7 @@ class AbsenceView extends StatelessWidget {
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
onPressed: () {
onPressed: () { // https://discord.com/channels/1111649116020285532/1149964760130002945
Navigator.of(context).pop();
if (outsideContext != null) {

View File

@ -57,7 +57,7 @@ class ChangedLessonTile extends StatelessWidget {
),
),
title: Text(
lesson.substituteTeacher?.name != ""
lesson.substituteTeacher?.name != "" || lesson.substituteTeacher?.name != null
? "substituted".i18n
: "cancelled".i18n,
maxLines: 2,

View File

@ -40,7 +40,7 @@ class AbsenceSubjectView extends StatelessWidget {
TimetablePage.jump(context, lesson: lesson);
} else {
ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar(
content: Text("Cannot find lesson".i18n,
content: Text("lesson_not_found".i18n,
style: const TextStyle(color: Colors.white)),
backgroundColor: AppColors.of(context).red,
context: context,

View File

@ -17,6 +17,7 @@ extension ScreensLocalization on String {
"Subjects": "Subjects",
"attention": "Attention!",
"attention_body": "Percentage calculations are only an approximation so they may not be accurate.",
"lesson_not_found": "Cannot find lesson",
},
"hu_hu": {
"Absences": "Hiányzások",
@ -32,6 +33,7 @@ extension ScreensLocalization on String {
"Subjects": "Tantárgyak",
"attention": "Figyelem!",
"attention_body": "A százalékos számítások csak közelítések, ezért előfordulhat, hogy nem pontosak.",
"lesson_not_found": "Nem található óra",
},
"de_de": {
"Absences": "Fehlen",
@ -47,6 +49,7 @@ extension ScreensLocalization on String {
"Subjects": "Fächer",
"attention": "Achtung!",
"attention_body": "Prozentberechnungen sind nur eine Annäherung und können daher ungenau sein.",
"lesson_not_found": "Lektion kann nicht gefunden werden",
},
};

View File

@ -102,6 +102,8 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
firstName = "János";
}
bool customWelcome = false;
if (now.isBefore(DateTime(now.year, DateTime.august, 31)) &&
now.isAfter(DateTime(now.year, DateTime.june, 14))) {
greeting = "goodrest";
@ -112,16 +114,16 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
Future.delayed(const Duration(seconds: 1))
.then((value) => mounted ? _confettiController?.play() : null);
}
// } else if (now.month == user.student?.birth.month &&
// now.day == user.student?.birth.day) {
// greeting = "happybirthday";
} else if (now.month == user.student?.birth.month &&
now.day == user.student?.birth.day) {
greeting = "happybirthday";
// if (NavigationScreen.of(context)?.init("confetti") ?? false) {
// _confettiController =
// ConfettiController(duration: const Duration(seconds: 3));
// Future.delayed(const Duration(seconds: 1))
// .then((value) => mounted ? _confettiController?.play() : null);
// }
if (NavigationScreen.of(context)?.init("confetti") ?? false) {
_confettiController =
ConfettiController(duration: const Duration(seconds: 3));
Future.delayed(const Duration(seconds: 1))
.then((value) => mounted ? _confettiController?.play() : null);
}
} else if (now.isAfter(DateTime(now.year, DateTime.may, 28)) &&
now.isBefore(DateTime(now.year, DateTime.may, 30))) {
greeting = "refilcopen";
@ -144,6 +146,8 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
settings.welcomeMessage,
[firstName],
);
customWelcome = true;
} else if (now.hour >= 18) {
greeting = "goodevening";
} else if (now.hour >= 10) {
@ -153,6 +157,8 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
} else {
greeting = "goodevening";
}
greeting = customWelcome ? greeting : greeting.i18n.fill([firstName]);
}
@override
@ -191,7 +197,7 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
title: Padding(
padding: const EdgeInsets.only(left: 24.0),
child: Text(
greeting.i18n.fill([firstName]),
greeting,
overflow: TextOverflow.fade,
style: TextStyle(
fontWeight: FontWeight.bold,

View File

@ -17,6 +17,8 @@ List<School> searchSchools(List<School> all, String pattern) {
});
if (contains == pattern.split(" ").length) results.add(item);
if (item.instituteCode.toLowerCase().specialChars().contains(pattern)) results.add(item);
}
results.sort((a, b) => a.name.compareTo(b.name));

View File

@ -87,7 +87,9 @@ class _SettingsScreenState extends State<SettingsScreen>
String _firstName;
List<String> _nameParts = account.displayName.split(" ");
List<String> _nameParts =
(account.nickname != '' ? account.nickname : account.displayName)
.split(" ");
if (!settings.presentationMode) {
_firstName = _nameParts.length > 1 ? _nameParts[1] : _nameParts[0];
} else {
@ -96,7 +98,10 @@ class _SettingsScreenState extends State<SettingsScreen>
accountTiles.add(
AccountTile(
name: Text(!settings.presentationMode ? account.name : "János",
name: Text(
!settings.presentationMode
? (account.nickname != '' ? account.nickname : account.name)
: "János",
style: const TextStyle(fontWeight: FontWeight.w500)),
username: Text(
!settings.presentationMode ? account.username : "01234567890"),
@ -275,7 +280,7 @@ class _SettingsScreenState extends State<SettingsScreen>
child: Panel(
child: Column(
children: [
// Account list
// account list
...accountTiles,
if (accountTiles.isNotEmpty)
@ -291,7 +296,7 @@ class _SettingsScreenState extends State<SettingsScreen>
),
),
// Account settings
// account settings
PanelButton(
onPressed: () {
Navigator.of(context)

View File

@ -22,7 +22,7 @@ class GoalProvider extends ChangeNotifier {
Future<void> fetchDone({required GradeProvider gradeProvider}) async {
var goalAvgs = await _db.userQuery.subjectGoalAverages(userId: _user.id!);
var beforeAvgs = await _db.userQuery.subjectGoalAverages(userId: _user.id!);
var beforeAvgs = await _db.userQuery.subjectGoalBefores(userId: _user.id!);
List<Subject> subjects = gradeProvider.grades
.map((e) => e.subject)

View File

@ -329,7 +329,7 @@ class _PremiumCustomAccentColorSettingState
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
gradient: LinearGradient(
gradient: LinearGradient( // https://discord.com/channels/1111649116020285532/1153619667848548452
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
stops: const [
@ -337,7 +337,8 @@ class _PremiumCustomAccentColorSettingState
0.75
],
colors: [
Theme.of(context).colorScheme.background,
settings.customBackgroundColor
?? Theme.of(context).colorScheme.background,
isBackgroundDifferent
? HSVColor.fromColor(Theme.of(context)
.colorScheme

View File

@ -126,8 +126,14 @@ class _WelcomeMessageEditorState extends State<WelcomeMessageEditor> {
// }
var finalText = _welcomeMsg.text
.trim()
.replaceAll('%s', '')
.replaceFirst('%name%', '%s');
.replaceFirst('%name%', '\$s')
.replaceFirst('%user%', '\$s')
.replaceFirst('%username%', '\$s')
.replaceFirst('%me%', '\$s')
.replaceFirst('%profile%', '\$s')
.replaceAll('%', '')
.replaceFirst('\$s', '%s');
// .replaceAll('\$s', 's');
widget.settingsProvider
.update(welcomeMessage: finalText, store: true);

View File

@ -1,4 +1,5 @@
import 'package:filcnaplo/helpers/subject.dart';
import 'package:filcnaplo/models/settings.dart';
import 'package:filcnaplo/theme/colors/colors.dart';
import 'package:filcnaplo_kreta_api/controllers/timetable_controller.dart';
import 'package:filcnaplo_mobile_ui/common/empty.dart';
@ -9,6 +10,7 @@ import 'package:filcnaplo/utils/format.dart';
import 'dart:math' as math;
import 'package:intl/intl.dart';
import 'package:i18n_extension/i18n_widget.dart';
import 'package:provider/provider.dart';
class PremiumFSTimetable extends StatefulWidget {
const PremiumFSTimetable({Key? key, required this.controller})
@ -21,6 +23,8 @@ class PremiumFSTimetable extends StatefulWidget {
}
class _PremiumFSTimetableState extends State<PremiumFSTimetable> {
late SettingsProvider settings;
@override
void initState() {
super.initState();
@ -37,6 +41,8 @@ class _PremiumFSTimetableState extends State<PremiumFSTimetable> {
@override
Widget build(BuildContext context) {
settings = Provider.of<SettingsProvider>(context);
if (widget.controller.days == null || widget.controller.days!.isEmpty) {
return const Center(child: Empty());
}
@ -174,7 +180,7 @@ class _PremiumFSTimetableState extends State<PremiumFSTimetable> {
style: TextStyle(
fontStyle: lessons[lessonIndex]
.subject
.isRenamed
.isRenamed && settings.renamedSubjectsItalics
? FontStyle.italic
: null,
),

7
upgrade-pub.sh Normal file
View File

@ -0,0 +1,7 @@
cd filcnaplo && flutter pub upgrade && cd ..
cd filcnaplo_kreta_api && flutter pub upgrade && cd ..
cd filcnaplo_mobile_ui && flutter pub upgrade && cd ..
cd filcnaplo_desktop_ui && flutter pub upgrade && cd ..
cd filcnaplo_premium && flutter pub upgrade && cd ..
echo Upgraded pub.