From 339dbea1ef35a59caf89d8e3ab7d47121a53426c Mon Sep 17 00:00:00 2001 From: unknown <55922348+55nknown@users.noreply.github.com> Date: Wed, 5 Jan 2022 13:02:22 +0100 Subject: [PATCH] flutter linting --- filcnaplo/analysis_options.yaml | 29 +++++ filcnaplo/lib/api/client.dart | 34 ++--- filcnaplo/lib/api/login.dart | 2 + .../lib/api/providers/news_provider.dart | 5 +- .../lib/api/providers/status_provider.dart | 10 +- filcnaplo/lib/api/providers/sync.dart | 3 +- .../lib/api/providers/update_provider.dart | 5 +- .../lib/api/providers/user_provider.dart | 6 +- filcnaplo/lib/app.dart | 26 ++-- filcnaplo/lib/database/init.dart | 10 +- filcnaplo/lib/database/query.dart | 20 +-- filcnaplo/lib/database/store.dart | 2 +- filcnaplo/lib/database/struct.dart | 2 +- filcnaplo/lib/helpers/average_helper.dart | 7 +- filcnaplo/lib/helpers/storage_helper.dart | 2 + filcnaplo/lib/helpers/update_helper.dart | 3 +- filcnaplo/lib/icons/filc_icons.dart | 4 +- filcnaplo/lib/main.dart | 5 +- filcnaplo/lib/models/release.dart | 9 +- filcnaplo/lib/models/settings.dart | 25 ++-- filcnaplo/lib/models/user.dart | 4 +- filcnaplo/lib/theme.dart | 118 +++++++++++------- filcnaplo/lib/utils/format.dart | 30 ++--- filcnaplo/lib/utils/jwt.dart | 1 + filcnaplo/pubspec.yaml | 5 +- filcnaplo_kreta_api | 2 +- 26 files changed, 226 insertions(+), 143 deletions(-) create mode 100644 filcnaplo/analysis_options.yaml diff --git a/filcnaplo/analysis_options.yaml b/filcnaplo/analysis_options.yaml new file mode 100644 index 0000000..61b6c4d --- /dev/null +++ b/filcnaplo/analysis_options.yaml @@ -0,0 +1,29 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/filcnaplo/lib/api/client.dart b/filcnaplo/lib/api/client.dart index aa03ceb..2fabfe7 100644 --- a/filcnaplo/lib/api/client.dart +++ b/filcnaplo/lib/api/client.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + import 'dart:convert'; import 'package:filcnaplo/models/config.dart'; @@ -11,23 +13,23 @@ import 'package:connectivity_plus/connectivity_plus.dart'; class FilcAPI { // Public API - static const SCHOOL_LIST = "https://filcnaplo.hu/v2/school_list.json"; - static const NEWS = "https://filcnaplo.hu/v2/news.json"; - static const SUPPORTERS = "https://filcnaplo.hu/v2/supporters.json"; + static const schoolList = "https://filcnaplo.hu/v2/school_list.json"; + static const news = "https://filcnaplo.hu/v2/news.json"; + static const supporters = "https://filcnaplo.hu/v2/supporters.json"; // Private API - static const CONFIG = "https://api.filcnaplo.hu/config"; - static const REPORT = "https://api.filcnaplo.hu/report"; + static const config = "https://api.filcnaplo.hu/config"; + static const reportApi = "https://api.filcnaplo.hu/report"; // Updates - static const REPO = "filc/naplo"; - static const RELEASES = "https://api.github.com/repos/$REPO/releases"; + static const repo = "filc/naplo"; + static const releases = "https://api.github.com/repos/$repo/releases"; - static Future checkConnectivity() async => (await Connectivity().checkConnectivity()) != ConnectivityResult.none; + static Future checkConnectivity() async => (await Connectivity().checkConnectivity()) != ConnectivityResult.none; static Future?> getSchools() async { try { - http.Response res = await http.get(Uri.parse(SCHOOL_LIST)); + http.Response res = await http.get(Uri.parse(schoolList)); if (res.statusCode == 200) { List schools = (jsonDecode(res.body) as List).cast().map((json) => School.fromJson(json)).toList(); @@ -52,12 +54,12 @@ class FilcAPI { }; try { - http.Response res = await http.get(Uri.parse(CONFIG), headers: headers); + http.Response res = await http.get(Uri.parse(config), headers: headers); if (res.statusCode == 200) { return Config.fromJson(jsonDecode(res.body)); } else if (res.statusCode == 429) { - res = await http.get(Uri.parse(CONFIG)); + res = await http.get(Uri.parse(config)); if (res.statusCode == 200) return Config.fromJson(jsonDecode(res.body)); } throw "HTTP ${res.statusCode}: ${res.body}"; @@ -68,7 +70,7 @@ class FilcAPI { static Future?> getNews() async { try { - http.Response res = await http.get(Uri.parse(NEWS)); + http.Response res = await http.get(Uri.parse(news)); if (res.statusCode == 200) { return (jsonDecode(res.body) as List).cast().map((e) => News.fromJson(e)).toList(); @@ -82,7 +84,7 @@ class FilcAPI { static Future getSupporters() async { try { - http.Response res = await http.get(Uri.parse(SUPPORTERS)); + http.Response res = await http.get(Uri.parse(supporters)); if (res.statusCode == 200) { return Supporters.fromJson(jsonDecode(res.body)); @@ -96,7 +98,7 @@ class FilcAPI { static Future?> getReleases() async { try { - http.Response res = await http.get(Uri.parse(RELEASES)); + http.Response res = await http.get(Uri.parse(releases)); if (res.statusCode == 200) { return (jsonDecode(res.body) as List).cast().map((e) => Release.fromJson(e)).toList(); @@ -109,7 +111,7 @@ class FilcAPI { } static Future downloadRelease(Release release) { - if (release.downloads.length > 0) { + if (release.downloads.isNotEmpty) { try { var client = http.Client(); var request = http.Request('GET', Uri.parse(release.downloads.first)); @@ -124,7 +126,7 @@ class FilcAPI { static Future sendReport(ErrorReport report) async { try { - http.Response res = await http.post(Uri.parse(REPORT), body: { + http.Response res = await http.post(Uri.parse(reportApi), body: { "os": report.os, "version": report.version, "error": report.error, diff --git a/filcnaplo/lib/api/login.dart b/filcnaplo/lib/api/login.dart index 9b8abb1..bf967cc 100644 --- a/filcnaplo/lib/api/login.dart +++ b/filcnaplo/lib/api/login.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + import 'package:filcnaplo/utils/jwt.dart'; import 'package:filcnaplo_kreta_api/providers/absence_provider.dart'; import 'package:filcnaplo_kreta_api/providers/event_provider.dart'; diff --git a/filcnaplo/lib/api/providers/news_provider.dart b/filcnaplo/lib/api/providers/news_provider.dart index 312df1a..679f49a 100644 --- a/filcnaplo/lib/api/providers/news_provider.dart +++ b/filcnaplo/lib/api/providers/news_provider.dart @@ -72,10 +72,11 @@ class NewsProvider extends ChangeNotifier { Provider.of(_context, listen: false).update(_context, newsState: _state); - if (_fresh > 0) + if (_fresh > 0) { show = true; - else + } else { show = false; + } notifyListeners(); } diff --git a/filcnaplo/lib/api/providers/status_provider.dart b/filcnaplo/lib/api/providers/status_provider.dart index 8ebdc6b..c8bb94f 100644 --- a/filcnaplo/lib/api/providers/status_provider.dart +++ b/filcnaplo/lib/api/providers/status_provider.dart @@ -5,14 +5,14 @@ import 'package:http/http.dart' as http; enum Status { network, maintenance, syncing } class StatusProvider extends ChangeNotifier { - List _stack = []; + final List _stack = []; double _progress = 0.0; StatusProvider() { _handleNetworkChanges(); } - Status? getStatus() => _stack.length > 0 ? _stack[0] : null; + Status? getStatus() => _stack.isNotEmpty ? _stack[0] : null; // Status progress from 0.0 to 1.0 double get progress => _progress; @@ -64,10 +64,12 @@ class StatusProvider extends ChangeNotifier { if (_progress == 1.0) { notifyListeners(); // Wait for animation - Future.delayed(Duration(milliseconds: 250), () { + Future.delayed(const Duration(milliseconds: 250), () { _stack.remove(Status.syncing); notifyListeners(); }); - } else if (progress != prev) notifyListeners(); + } else if (progress != prev) { + notifyListeners(); + } } } diff --git a/filcnaplo/lib/api/providers/sync.dart b/filcnaplo/lib/api/providers/sync.dart index 6705f7b..fb02d58 100644 --- a/filcnaplo/lib/api/providers/sync.dart +++ b/filcnaplo/lib/api/providers/sync.dart @@ -24,6 +24,7 @@ Future syncAll(BuildContext context) { // Lock lock = true; + // ignore: avoid_print print("INFO Syncing all"); UserProvider user = Provider.of(context, listen: false); @@ -42,7 +43,7 @@ Future syncAll(BuildContext context) { _syncStatus(Provider.of(context, listen: false).fetch()), _syncStatus(Provider.of(context, listen: false).fetch(week: Week.current())), _syncStatus(Provider.of(context, listen: false).fetch()), - _syncStatus(Provider.of(context, listen: false).fetch(from: DateTime.now().subtract(Duration(days: 30)))), + _syncStatus(Provider.of(context, listen: false).fetch(from: DateTime.now().subtract(const Duration(days: 30)))), _syncStatus(Provider.of(context, listen: false).fetchAll()), _syncStatus(Provider.of(context, listen: false).fetch()), _syncStatus(Provider.of(context, listen: false).fetch()), diff --git a/filcnaplo/lib/api/providers/update_provider.dart b/filcnaplo/lib/api/providers/update_provider.dart index fc1faac..5461a9a 100644 --- a/filcnaplo/lib/api/providers/update_provider.dart +++ b/filcnaplo/lib/api/providers/update_provider.dart @@ -9,7 +9,7 @@ class UpdateProvider extends ChangeNotifier { // Private late List _releases; bool _available = false; - bool get available => _available && _releases.length > 0; + bool get available => _available && _releases.isNotEmpty; PackageInfo? _packageInfo; // Public @@ -32,8 +32,9 @@ class UpdateProvider extends ChangeNotifier { _releases.sort((a, b) => -a.version.compareTo(b.version)); // Check for new releases - if (_releases.length > 0) { + if (_releases.isNotEmpty) { _available = _packageInfo != null && _releases.first.version.compareTo(Version.fromString(currentVersion)) == 1; + // ignore: avoid_print if (_available) print("INFO: New update: ${releases.first.version}"); notifyListeners(); } diff --git a/filcnaplo/lib/api/providers/user_provider.dart b/filcnaplo/lib/api/providers/user_provider.dart index 9fbd4a1..fdd313f 100644 --- a/filcnaplo/lib/api/providers/user_provider.dart +++ b/filcnaplo/lib/api/providers/user_provider.dart @@ -3,7 +3,7 @@ import 'package:filcnaplo_kreta_api/models/student.dart'; import 'package:flutter/foundation.dart'; class UserProvider with ChangeNotifier { - Map _users = {}; + final Map _users = {}; String? _selectedUserId; User? get user => _users[_selectedUserId]; @@ -23,7 +23,9 @@ class UserProvider with ChangeNotifier { void addUser(User user) { _users[user.id] = user; - print("DEBUG: Added User: ${user.id} ${user.name}"); + if (kDebugMode) { + print("DEBUG: Added User: ${user.id} ${user.name}"); + } } void removeUser(String userId) { diff --git a/filcnaplo/lib/app.dart b/filcnaplo/lib/app.dart index aa3b099..77941cf 100644 --- a/filcnaplo/lib/app.dart +++ b/filcnaplo/lib/app.dart @@ -41,7 +41,7 @@ class App extends StatelessWidget { final DatabaseProvider database; App({Key? key, required this.database, required this.settings, required this.user}) : super(key: key) { - if (user.getUsers().length > 0) user.setUser(user.getUsers().first.id); + if (user.getUsers().isNotEmpty) user.setUser(user.getUsers().first.id); } @override @@ -99,18 +99,18 @@ class App extends StatelessWidget { theme: AppTheme.lightTheme(context), darkTheme: AppTheme.darkTheme(context), themeMode: themeMode.themeMode, - localizationsDelegates: [ + localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], - supportedLocales: [ - const Locale('en', 'EN'), - const Locale('hu', 'HU'), - const Locale('de', 'DE'), + supportedLocales: const [ + Locale('en', 'EN'), + Locale('hu', 'HU'), + Locale('de', 'DE'), ], localeListResolutionCallback: (locales, supported) { - Locale locale = Locale('hu', 'HU'); + Locale locale = const Locale('hu', 'HU'); for (var loc in locales ?? []) { if (supported.contains(loc)) { @@ -122,7 +122,7 @@ class App extends StatelessWidget { return locale; }, onGenerateRoute: (settings) => rootNavigator(settings), - initialRoute: user.getUsers().length > 0 ? "navigation" : "login"); + initialRoute: user.getUsers().isNotEmpty ? "navigation" : "login"); }, ), ), @@ -133,15 +133,15 @@ class App extends StatelessWidget { // if platform == android || platform == ios switch (route.name) { case "login_back": - return CupertinoPageRoute(builder: (context) => LoginScreen(back: true)); + return CupertinoPageRoute(builder: (context) => const LoginScreen(back: true)); case "login": - return _rootRoute(LoginScreen()); + return _rootRoute(const LoginScreen()); case "navigation": - return _rootRoute(NavigationScreen()); + return _rootRoute(const NavigationScreen()); case "login_to_navigation": - return loginRoute(NavigationScreen()); + return loginRoute(const NavigationScreen()); case "settings": - return settingsRoute(SettingsScreen()); + return settingsRoute(const SettingsScreen()); } // else if platform == windows || ... } diff --git a/filcnaplo/lib/database/init.dart b/filcnaplo/lib/database/init.dart index e4e81d5..170553f 100644 --- a/filcnaplo/lib/database/init.dart +++ b/filcnaplo/lib/database/init.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + import 'dart:io'; import 'package:filcnaplo/database/struct.dart'; @@ -69,7 +71,7 @@ Future migrateDB( ) async { var originalRows = await db.query(table); - if (originalRows.length == 0) { + if (originalRows.isEmpty) { await db.execute("drop table $table"); await create(db); return; @@ -85,7 +87,7 @@ Future migrateDB( var copy = Map.from(original); // Fill missing columns - keys.forEach((key) { + for (var key in keys) { if (!keys.contains(key)) { print("DEBUG: dropping $key"); copy.remove(key); @@ -95,13 +97,13 @@ Future migrateDB( print("DEBUG: migrating $key"); copy[key] = defaultValues[key]; } - }); + } migrated.add(copy); } }); - if (migrated.length > 0) { + if (migrated.isNotEmpty) { // Delete table await db.execute("drop table $table"); diff --git a/filcnaplo/lib/database/query.dart b/filcnaplo/lib/database/query.dart index ff776e1..8ffef72 100644 --- a/filcnaplo/lib/database/query.dart +++ b/filcnaplo/lib/database/query.dart @@ -28,9 +28,9 @@ class DatabaseQuery { Future getUsers() async { var userProvider = UserProvider(); List usersMap = await db.query("users"); - usersMap.forEach((user) { + for (var user in usersMap) { userProvider.addUser(User.fromMap(user)); - }); + } return userProvider; } } @@ -42,7 +42,7 @@ class UserDatabaseQuery { Future> getGrades({required String userId}) async { List userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]); - if (userData.length == 0) return []; + if (userData.isEmpty) return []; String? gradesJson = userData.elementAt(0)["grades"] as String?; if (gradesJson == null) return []; List grades = (jsonDecode(gradesJson) as List).map((e) => Grade.fromJson(e)).toList(); @@ -51,7 +51,7 @@ class UserDatabaseQuery { Future> getLessons({required String userId}) async { List userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]); - if (userData.length == 0) return []; + if (userData.isEmpty) return []; String? lessonsJson = userData.elementAt(0)["timetable"] as String?; if (lessonsJson == null) return []; List lessons = (jsonDecode(lessonsJson) as List).map((e) => Lesson.fromJson(e)).toList(); @@ -60,7 +60,7 @@ class UserDatabaseQuery { Future> getExams({required String userId}) async { List userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]); - if (userData.length == 0) return []; + if (userData.isEmpty) return []; String? examsJson = userData.elementAt(0)["exams"] as String?; if (examsJson == null) return []; List exams = (jsonDecode(examsJson) as List).map((e) => Exam.fromJson(e)).toList(); @@ -69,7 +69,7 @@ class UserDatabaseQuery { Future> getHomework({required String userId}) async { List userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]); - if (userData.length == 0) return []; + if (userData.isEmpty) return []; String? homeworkJson = userData.elementAt(0)["homework"] as String?; if (homeworkJson == null) return []; List homework = (jsonDecode(homeworkJson) as List).map((e) => Homework.fromJson(e)).toList(); @@ -78,7 +78,7 @@ class UserDatabaseQuery { Future> getMessages({required String userId}) async { List userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]); - if (userData.length == 0) return []; + if (userData.isEmpty) return []; String? messagesJson = userData.elementAt(0)["messages"] as String?; if (messagesJson == null) return []; List messages = (jsonDecode(messagesJson) as List).map((e) => Message.fromJson(e)).toList(); @@ -87,7 +87,7 @@ class UserDatabaseQuery { Future> getNotes({required String userId}) async { List userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]); - if (userData.length == 0) return []; + if (userData.isEmpty) return []; String? notesJson = userData.elementAt(0)["notes"] as String?; if (notesJson == null) return []; List notes = (jsonDecode(notesJson) as List).map((e) => Note.fromJson(e)).toList(); @@ -96,7 +96,7 @@ class UserDatabaseQuery { Future> getEvents({required String userId}) async { List userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]); - if (userData.length == 0) return []; + if (userData.isEmpty) return []; String? eventsJson = userData.elementAt(0)["events"] as String?; if (eventsJson == null) return []; List events = (jsonDecode(eventsJson) as List).map((e) => Event.fromJson(e)).toList(); @@ -105,7 +105,7 @@ class UserDatabaseQuery { Future> getAbsences({required String userId}) async { List userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]); - if (userData.length == 0) return []; + if (userData.isEmpty) return []; String? absebcesJson = userData.elementAt(0)["absences"] as String?; if (absebcesJson == null) return []; List absebces = (jsonDecode(absebcesJson) as List).map((e) => Absence.fromJson(e)).toList(); diff --git a/filcnaplo/lib/database/store.dart b/filcnaplo/lib/database/store.dart index ce32d26..2b93002 100644 --- a/filcnaplo/lib/database/store.dart +++ b/filcnaplo/lib/database/store.dart @@ -24,7 +24,7 @@ class DatabaseStore { Future storeUser(User user) async { List userRes = await db.query("users", where: "id = ?", whereArgs: [user.id]); - if (userRes.length > 0) { + if (userRes.isNotEmpty) { await db.update("users", user.toMap(), where: "id = ?", whereArgs: [user.id]); } else { await db.insert("users", user.toMap()); diff --git a/filcnaplo/lib/database/struct.dart b/filcnaplo/lib/database/struct.dart index cec8e48..a84a673 100644 --- a/filcnaplo/lib/database/struct.dart +++ b/filcnaplo/lib/database/struct.dart @@ -15,7 +15,7 @@ class DatabaseStruct { break; } - return "${name} ${typeName.toUpperCase()} ${name == 'id' ? 'NOT NULL' : ''}"; + return "$name ${typeName.toUpperCase()} ${name == 'id' ? 'NOT NULL' : ''}"; } @override diff --git a/filcnaplo/lib/helpers/average_helper.dart b/filcnaplo/lib/helpers/average_helper.dart index 3b43cc3..1f65934 100644 --- a/filcnaplo/lib/helpers/average_helper.dart +++ b/filcnaplo/lib/helpers/average_helper.dart @@ -6,14 +6,15 @@ class AverageHelper { List ignoreInFinal = ["5,SzorgalomErtek", "4,MagatartasErtek"]; - if (finalAvg) + if (finalAvg) { grades.removeWhere((e) => (e.value.value == 0) || (ignoreInFinal.contains(e.gradeType?.id))); + } - grades.forEach((e) { + for (var e in grades) { average += e.value.value * ((finalAvg ? 100 : e.value.weight) / 100); - }); + } average = average / grades diff --git a/filcnaplo/lib/helpers/storage_helper.dart b/filcnaplo/lib/helpers/storage_helper.dart index 1f43f4e..b8583c4 100644 --- a/filcnaplo/lib/helpers/storage_helper.dart +++ b/filcnaplo/lib/helpers/storage_helper.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + import 'dart:io'; import 'dart:typed_data'; diff --git a/filcnaplo/lib/helpers/update_helper.dart b/filcnaplo/lib/helpers/update_helper.dart index bd88b58..ef0124a 100644 --- a/filcnaplo/lib/helpers/update_helper.dart +++ b/filcnaplo/lib/helpers/update_helper.dart @@ -17,7 +17,7 @@ extension UpdateHelper on Release { updateCallback!(-1, UpdateState.preparing); String downloads = await StorageHelper.downloadsPath(); - File apk = File("$downloads/filcnaplo-${version}.apk"); + File apk = File("$downloads/filcnaplo-$version.apk"); if (!await apk.exists()) { updateCallback(-1, UpdateState.downloading); @@ -31,6 +31,7 @@ extension UpdateHelper on Release { var result = await OpenFile.open(apk.path); if (result.type != ResultType.done) { + // ignore: avoid_print print("ERROR: installUpdate.openFile: " + result.message); throw result.message; } diff --git a/filcnaplo/lib/icons/filc_icons.dart b/filcnaplo/lib/icons/filc_icons.dart index 49257e9..a1fb495 100644 --- a/filcnaplo/lib/icons/filc_icons.dart +++ b/filcnaplo/lib/icons/filc_icons.dart @@ -1,8 +1,8 @@ import 'package:flutter/widgets.dart'; class FilcIcons { - static const IconData home = const FilcIconData(0x41); - static const IconData linux = const FilcIconData(0x42); + static const IconData home = FilcIconData(0x41); + static const IconData linux = FilcIconData(0x42); } class FilcIconData extends IconData { diff --git a/filcnaplo/lib/main.dart b/filcnaplo/lib/main.dart index 61830b7..48518ee 100644 --- a/filcnaplo/lib/main.dart +++ b/filcnaplo/lib/main.dart @@ -53,10 +53,11 @@ Widget errorBuilder(FlutterErrorDetails details) { errorShown = true; lastException = details.exceptionAsString(); Navigator.of(context, rootNavigator: true).push(MaterialPageRoute(builder: (context) { - if (kReleaseMode) + if (kReleaseMode) { return ErrorReportScreen(details); - else + } else { return ErrorScreen(details); + } })).then((_) => errorShown = false); } }); diff --git a/filcnaplo/lib/models/release.dart b/filcnaplo/lib/models/release.dart index ca52bf1..5c07248 100644 --- a/filcnaplo/lib/models/release.dart +++ b/filcnaplo/lib/models/release.dart @@ -58,10 +58,11 @@ class Version { // check for valid prerelease name if (p[0] != "") { - if (prereleases.contains(p[0].toLowerCase().trim())) + if (prereleases.contains(p[0].toLowerCase().trim())) { pre = p[0]; - else + } else { throw "invalid prerelease name: ${p[0]}"; + } } // core @@ -74,6 +75,7 @@ class Version { return Version(x, y, z, prerelease: pre, prever: prev); } catch (error) { + // ignore: avoid_print print("WARNING: Failed to parse version ($o): $error"); return Version.zero; } @@ -126,4 +128,7 @@ class Version { static const zero = Version(0, 0, 0); static const List prereleases = ["dev", "pre", "alpha", "beta", "rc"]; + + @override + int get hashCode => toString().hashCode; } diff --git a/filcnaplo/lib/models/settings.dart b/filcnaplo/lib/models/settings.dart index cd6f0a5..d58d4d3 100644 --- a/filcnaplo/lib/models/settings.dart +++ b/filcnaplo/lib/models/settings.dart @@ -44,7 +44,7 @@ class SettingsProvider extends ChangeNotifier { int _notificationPollInterval; bool _developerMode; VibrationStrength _vibrate; - bool _ABweeks; + bool _abWeeks; bool _swapABweeks; UpdateChannel _updateChannel; Config _config; @@ -64,7 +64,7 @@ class SettingsProvider extends ChangeNotifier { required bool developerMode, required int notificationPollInterval, required VibrationStrength vibrate, - required bool ABweeks, + required bool abWeeks, required bool swapABweeks, required UpdateChannel updateChannel, required Config config, @@ -82,7 +82,7 @@ class SettingsProvider extends ChangeNotifier { _developerMode = developerMode, _notificationPollInterval = notificationPollInterval, _vibrate = vibrate, - _ABweeks = ABweeks, + _abWeeks = abWeeks, _swapABweeks = swapABweeks, _updateChannel = updateChannel, _config = config, @@ -113,7 +113,7 @@ class SettingsProvider extends ChangeNotifier { notificationPollInterval: map["notification_poll_interval"], developerMode: map["developer_mode"] == 1 ? true : false, vibrate: VibrationStrength.values[map["vibration_strength"]], - ABweeks: map["ab_weeks"] == 1 ? true : false, + abWeeks: map["ab_weeks"] == 1 ? true : false, swapABweeks: map["swap_ab_weeks"] == 1 ? true : false, updateChannel: UpdateChannel.values[map["update_channel"]], config: Config.fromJson(jsonDecode(map["config"] ?? "{}")), @@ -140,7 +140,7 @@ class SettingsProvider extends ChangeNotifier { "grade_color5": _gradeColors[4].value, "update_channel": _updateChannel.index, "vibration_strength": _vibrate.index, - "ab_weeks": _ABweeks ? 1 : 0, + "ab_weeks": _abWeeks ? 1 : 0, "swap_ab_weeks": _swapABweeks ? 1 : 0, "notification_poll_interval": _notificationPollInterval, "config": jsonEncode(config.json), @@ -169,11 +169,11 @@ class SettingsProvider extends ChangeNotifier { developerMode: false, notificationPollInterval: 1, vibrate: VibrationStrength.medium, - ABweeks: false, + abWeeks: false, swapABweeks: false, updateChannel: UpdateChannel.stable, config: Config.fromJson({}), - xFilcId: Uuid().v4(), + xFilcId: const Uuid().v4(), ); } @@ -191,7 +191,7 @@ class SettingsProvider extends ChangeNotifier { bool get developerMode => _developerMode; int get notificationPollInterval => _notificationPollInterval; VibrationStrength get vibrate => _vibrate; - bool get ABweeks => _ABweeks; + bool get abWeeks => _abWeeks; bool get swapABweeks => _swapABweeks; UpdateChannel get updateChannel => _updateChannel; PackageInfo? get packageInfo => _packageInfo; @@ -214,7 +214,7 @@ class SettingsProvider extends ChangeNotifier { bool? developerMode, int? notificationPollInterval, VibrationStrength? vibrate, - bool? ABweeks, + bool? abWeeks, bool? swapABweeks, UpdateChannel? updateChannel, Config? config, @@ -231,16 +231,17 @@ class SettingsProvider extends ChangeNotifier { if (notificationsEnabled != null && notificationsEnabled != _notificationsEnabled) _notificationsEnabled = notificationsEnabled; if (notificationsBitfield != null && notificationsBitfield != _notificationsBitfield) _notificationsBitfield = notificationsBitfield; if (developerMode != null && developerMode != _developerMode) _developerMode = developerMode; - if (notificationPollInterval != null && notificationPollInterval != _notificationPollInterval) + if (notificationPollInterval != null && notificationPollInterval != _notificationPollInterval) { _notificationPollInterval = notificationPollInterval; + } if (vibrate != null && vibrate != _vibrate) _vibrate = vibrate; - if (ABweeks != null && ABweeks != _ABweeks) _ABweeks = ABweeks; + if (abWeeks != null && abWeeks != _abWeeks) _abWeeks = abWeeks; if (swapABweeks != null && swapABweeks != _swapABweeks) _swapABweeks = swapABweeks; if (updateChannel != null && updateChannel != _updateChannel) _updateChannel = updateChannel; if (config != null && config != _config) _config = config; if (xFilcId != null && xFilcId != _xFilcId) _xFilcId = xFilcId; - if (database == null) database = Provider.of(context, listen: false); + database ??= Provider.of(context, listen: false); await database.store.storeSettings(this); notifyListeners(); } diff --git a/filcnaplo/lib/models/user.dart b/filcnaplo/lib/models/user.dart index 4f6d39b..8adf8a5 100644 --- a/filcnaplo/lib/models/user.dart +++ b/filcnaplo/lib/models/user.dart @@ -26,7 +26,7 @@ class User { if (id != null) { this.id = id; } else { - this.id = Uuid().v4(); + this.id = const Uuid().v4(); } } @@ -67,7 +67,7 @@ class User { "password": password, "institute_code": instituteCode, "grant_type": "password", - "client_id": KretaAPI.CLIENT_ID, + "client_id": KretaAPI.clientId, }; } } diff --git a/filcnaplo/lib/theme.dart b/filcnaplo/lib/theme.dart index da445ba..a06b519 100644 --- a/filcnaplo/lib/theme.dart +++ b/filcnaplo/lib/theme.dart @@ -11,14 +11,14 @@ class AppTheme { // Light Theme static ThemeData lightTheme(BuildContext context) { var lightColors = LightAppColors(); - Color accent = accentColorMap[Provider.of(context, listen: false).accentColor] ?? Color(0); + Color accent = accentColorMap[Provider.of(context, listen: false).accentColor] ?? const Color(0x00000000); return ThemeData( brightness: Brightness.light, fontFamily: _fontFamily, scaffoldBackgroundColor: lightColors.background, backgroundColor: lightColors.highlight, primaryColor: lightColors.filc, - dividerColor: Color(0), + dividerColor: const Color(0x00000000), colorScheme: ColorScheme.fromSwatch( accentColor: accent, backgroundColor: lightColors.background, @@ -37,14 +37,14 @@ class AppTheme { // Dark Theme static ThemeData darkTheme(BuildContext context) { var darkColors = DarkAppColors(); - Color accent = accentColorMap[Provider.of(context, listen: false).accentColor] ?? Color(0); + Color accent = accentColorMap[Provider.of(context, listen: false).accentColor] ?? const Color(0x00000000); return ThemeData( brightness: Brightness.dark, fontFamily: _fontFamily, scaffoldBackgroundColor: darkColors.background, backgroundColor: darkColors.highlight, primaryColor: darkColors.filc, - dividerColor: Color(0), + dividerColor: const Color(0x00000000), colorScheme: ColorScheme.fromSwatch( accentColor: accent, backgroundColor: darkColors.background, @@ -70,7 +70,7 @@ class AppColors { enum AccentColor { filc, blue, green, lime, yellow, orange, red, pink, purple } Map accentColorMap = { - AccentColor.filc: Color(0xff20AC9B), + AccentColor.filc: const Color(0xff20AC9B), AccentColor.blue: Colors.blue.shade300, AccentColor.green: Colors.green.shade300, AccentColor.lime: Colors.lime.shade300, @@ -82,54 +82,82 @@ Map accentColorMap = { }; abstract class ThemeAppColors { - final Color shadow = Color(0); - final Color text = Color(0); - final Color background = Color(0); - final Color highlight = Color(0); - final Color red = Color(0); - final Color orange = Color(0); - final Color yellow = Color(0); - final Color green = Color(0); - final Color filc = Color(0); - final Color teal = Color(0); - final Color blue = Color(0); - final Color indigo = Color(0); - final Color purple = Color(0); - final Color pink = Color(0); + final Color shadow = const Color(0x00000000); + final Color text = const Color(0x00000000); + final Color background = const Color(0x00000000); + final Color highlight = const Color(0x00000000); + final Color red = const Color(0x00000000); + final Color orange = const Color(0x00000000); + final Color yellow = const Color(0x00000000); + final Color green = const Color(0x00000000); + final Color filc = const Color(0x00000000); + final Color teal = const Color(0x00000000); + final Color blue = const Color(0x00000000); + final Color indigo = const Color(0x00000000); + final Color purple = const Color(0x00000000); + final Color pink = const Color(0x00000000); } class LightAppColors implements ThemeAppColors { - final shadow = Color(0xffE8E8E8); + @override + final shadow = const Color(0xffE8E8E8); + @override final text = Colors.black; - final background = Color(0xffF4F9FF); - final highlight = Color(0xffFFFFFF); - final red = Color(0xffFF3B30); - final orange = Color(0xffFF9500); - final yellow = Color(0xffFFCC00); - final green = Color(0xff34C759); - final filc = Color(0xff247665); - final teal = Color(0xff5AC8FA); - final blue = Color(0xff007AFF); - final indigo = Color(0xff5856D6); - final purple = Color(0xffAF52DE); - final pink = Color(0xffFF2D55); + @override + final background = const Color(0xffF4F9FF); + @override + final highlight = const Color(0xffFFFFFF); + @override + final red = const Color(0xffFF3B30); + @override + final orange = const Color(0xffFF9500); + @override + final yellow = const Color(0xffFFCC00); + @override + final green = const Color(0xff34C759); + @override + final filc = const Color(0xff247665); + @override + final teal = const Color(0xff5AC8FA); + @override + final blue = const Color(0xff007AFF); + @override + final indigo = const Color(0xff5856D6); + @override + final purple = const Color(0xffAF52DE); + @override + final pink = const Color(0xffFF2D55); } class DarkAppColors implements ThemeAppColors { - final shadow = Color(0); + @override + final shadow = const Color(0x00000000); + @override final text = Colors.white; - final background = Color(0xff000000); - final highlight = Color(0xff141516); - final red = Color(0xffFF453A); - final orange = Color(0xffFF9F0A); - final yellow = Color(0xffFFD60A); - final green = Color(0xff32D74B); - final filc = Color(0xff29826F); - final teal = Color(0xff64D2FF); - final blue = Color(0xff0A84FF); - final indigo = Color(0xff5E5CE6); - final purple = Color(0xffBF5AF2); - final pink = Color(0xffFF375F); + @override + final background = const Color(0xff000000); + @override + final highlight = const Color(0xff141516); + @override + final red = const Color(0xffFF453A); + @override + final orange = const Color(0xffFF9F0A); + @override + final yellow = const Color(0xffFFD60A); + @override + final green = const Color(0xff32D74B); + @override + final filc = const Color(0xff29826F); + @override + final teal = const Color(0xff64D2FF); + @override + final blue = const Color(0xff0A84FF); + @override + final indigo = const Color(0xff5E5CE6); + @override + final purple = const Color(0xffBF5AF2); + @override + final pink = const Color(0xffFF375F); } class ThemeModeObserver extends ChangeNotifier { diff --git a/filcnaplo/lib/utils/format.dart b/filcnaplo/lib/utils/format.dart index 3ec11f6..521254c 100644 --- a/filcnaplo/lib/utils/format.dart +++ b/filcnaplo/lib/utils/format.dart @@ -6,8 +6,7 @@ import 'package:html/parser.dart'; import 'format.i18n.dart'; extension StringFormatUtils on String { - String specialChars() => this - .replaceAll("é", "e") + String specialChars() => replaceAll("é", "e") .replaceAll("á", "a") .replaceAll("ó", "o") .replaceAll("ő", "o") @@ -17,9 +16,9 @@ extension StringFormatUtils on String { .replaceAll("ü", "u") .replaceAll("í", "i"); - String capital() => this.length > 0 ? this[0].toUpperCase() + this.substring(1) : ""; + String capital() => isNotEmpty ? this[0].toUpperCase() + substring(1) : ""; - String capitalize() => this.split(" ").map((w) => w.capital()).join(" "); + String capitalize() => split(" ").map((w) => w.capital()).join(" "); String escapeHtml() { String htmlString = this; @@ -38,23 +37,24 @@ extension DateFormatUtils on DateTime { if (timeOnly) return DateFormat("HH:mm").format(this); DateTime now = DateTime.now(); - if (now.year == this.year && now.month == this.month && now.day == this.day) { - if (this.hour == 0 && this.minute == 0 && this.second == 0 || forceToday) return "Today".i18n; + if (now.year == year && now.month == month && now.day == day) { + if (hour == 0 && minute == 0 && second == 0 || forceToday) return "Today".i18n; return DateFormat("HH:mm").format(this); } - if (now.year == this.year && now.month == this.month && now.subtract(Duration(days: 1)).day == this.day) return "Yesterday".i18n; - if (now.year == this.year && now.month == this.month && now.add(Duration(days: 1)).day == this.day) return "Tomorrow".i18n; + if (now.year == year && now.month == month && now.subtract(const Duration(days: 1)).day == day) return "Yesterday".i18n; + if (now.year == year && now.month == month && now.add(const Duration(days: 1)).day == day) return "Tomorrow".i18n; String formatString; // If date is current week, show only weekday - if (Week.current().start.isBefore(this) && Week.current().end.isAfter(this)) - formatString = "EEEE"; // ex. monday - else { - if (this.year == now.year) - formatString = "MMM dd."; // ex. Jan. 01. - else - formatString = "yy/MM/dd"; // ex. 21/01/01 + if (Week.current().start.isBefore(this) && Week.current().end.isAfter(this)) { + formatString = "EEEE"; + } else { + if (year == now.year) { + formatString = "MMM dd."; + } else { + formatString = "yy/MM/dd"; + } // ex. 21/01/01 if (weekday) formatString += " (EEEE)"; // ex. (monday) } diff --git a/filcnaplo/lib/utils/jwt.dart b/filcnaplo/lib/utils/jwt.dart index 0a25deb..fa6ea85 100644 --- a/filcnaplo/lib/utils/jwt.dart +++ b/filcnaplo/lib/utils/jwt.dart @@ -17,6 +17,7 @@ class JwtUtils { var payload = utf8.decode(base64Url.decode(parts[1])); return jsonDecode(payload); } catch (error) { + // ignore: avoid_print print("ERROR: JwtUtils.decodeJwt: $error"); } } diff --git a/filcnaplo/pubspec.yaml b/filcnaplo/pubspec.yaml index ecdb1c8..25c8bfe 100644 --- a/filcnaplo/pubspec.yaml +++ b/filcnaplo/pubspec.yaml @@ -6,7 +6,7 @@ publish_to: "none" version: 3.1.1+139 environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.16.0-80.1.beta <3.0.0" dependencies: flutter: @@ -32,7 +32,7 @@ dependencies: html: ^0.15.0 open_file: ^3.2.1 path_provider: ^2.0.2 - permission_handler: 8.1.2 + permission_handler: ^8.3.0 share_plus: ^3.0.4 package_info_plus: ^1.0.6 connectivity_plus: ^2.0.2 @@ -41,6 +41,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter + flutter_lints: ^1.0.0 # flutter_launcher_icons: ^0.9.0 # flutter_native_splash: ^1.2.0 sqflite_common_ffi: ^2.0.0+3 diff --git a/filcnaplo_kreta_api b/filcnaplo_kreta_api index 695ca3b..0765836 160000 --- a/filcnaplo_kreta_api +++ b/filcnaplo_kreta_api @@ -1 +1 @@ -Subproject commit 695ca3bcf9d67c3d316f08e1585fff9896d87c25 +Subproject commit 07658366419b844fbbcb68ac5da8432c313608bb