flutter linting

This commit is contained in:
unknown 2022-01-05 13:02:22 +01:00
parent 79f6ef4c50
commit 339dbea1ef
26 changed files with 226 additions and 143 deletions

View File

@ -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

View File

@ -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<bool> checkConnectivity() async => (await Connectivity().checkConnectivity()) != ConnectivityResult.none;
static Future<List<School>?> 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<School> schools = (jsonDecode(res.body) as List).cast<Map>().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<List<News>?> 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>().map((e) => News.fromJson(e)).toList();
@ -82,7 +84,7 @@ class FilcAPI {
static Future<Supporters?> 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<List<Release>?> 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>().map((e) => Release.fromJson(e)).toList();
@ -109,7 +111,7 @@ class FilcAPI {
}
static Future<http.StreamedResponse?> 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<void> 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,

View File

@ -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';

View File

@ -72,10 +72,11 @@ class NewsProvider extends ChangeNotifier {
Provider.of<SettingsProvider>(_context, listen: false).update(_context, newsState: _state);
if (_fresh > 0)
if (_fresh > 0) {
show = true;
else
} else {
show = false;
}
notifyListeners();
}

View File

@ -5,14 +5,14 @@ import 'package:http/http.dart' as http;
enum Status { network, maintenance, syncing }
class StatusProvider extends ChangeNotifier {
List<Status> _stack = [];
final List<Status> _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();
}
}
}

View File

@ -24,6 +24,7 @@ Future<void> syncAll(BuildContext context) {
// Lock
lock = true;
// ignore: avoid_print
print("INFO Syncing all");
UserProvider user = Provider.of<UserProvider>(context, listen: false);
@ -42,7 +43,7 @@ Future<void> syncAll(BuildContext context) {
_syncStatus(Provider.of<GradeProvider>(context, listen: false).fetch()),
_syncStatus(Provider.of<TimetableProvider>(context, listen: false).fetch(week: Week.current())),
_syncStatus(Provider.of<ExamProvider>(context, listen: false).fetch()),
_syncStatus(Provider.of<HomeworkProvider>(context, listen: false).fetch(from: DateTime.now().subtract(Duration(days: 30)))),
_syncStatus(Provider.of<HomeworkProvider>(context, listen: false).fetch(from: DateTime.now().subtract(const Duration(days: 30)))),
_syncStatus(Provider.of<MessageProvider>(context, listen: false).fetchAll()),
_syncStatus(Provider.of<NoteProvider>(context, listen: false).fetch()),
_syncStatus(Provider.of<EventProvider>(context, listen: false).fetch()),

View File

@ -9,7 +9,7 @@ class UpdateProvider extends ChangeNotifier {
// Private
late List<Release> _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();
}

View File

@ -3,7 +3,7 @@ import 'package:filcnaplo_kreta_api/models/student.dart';
import 'package:flutter/foundation.dart';
class UserProvider with ChangeNotifier {
Map<String, User> _users = {};
final Map<String, User> _users = {};
String? _selectedUserId;
User? get user => _users[_selectedUserId];
@ -23,8 +23,10 @@ class UserProvider with ChangeNotifier {
void addUser(User user) {
_users[user.id] = user;
if (kDebugMode) {
print("DEBUG: Added User: ${user.id} ${user.name}");
}
}
void removeUser(String userId) {
_users.removeWhere((key, value) => key == userId);

View File

@ -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 || ...
}

View File

@ -1,3 +1,5 @@
// ignore_for_file: avoid_print
import 'dart:io';
import 'package:filcnaplo/database/struct.dart';
@ -69,7 +71,7 @@ Future<void> 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<void> migrateDB(
var copy = Map<String, dynamic>.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<void> 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");

View File

@ -28,9 +28,9 @@ class DatabaseQuery {
Future<UserProvider> getUsers() async {
var userProvider = UserProvider();
List<Map> 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<List<Grade>> getGrades({required String userId}) async {
List<Map> 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<Grade> grades = (jsonDecode(gradesJson) as List).map((e) => Grade.fromJson(e)).toList();
@ -51,7 +51,7 @@ class UserDatabaseQuery {
Future<List<Lesson>> getLessons({required String userId}) async {
List<Map> 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<Lesson> lessons = (jsonDecode(lessonsJson) as List).map((e) => Lesson.fromJson(e)).toList();
@ -60,7 +60,7 @@ class UserDatabaseQuery {
Future<List<Exam>> getExams({required String userId}) async {
List<Map> 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<Exam> exams = (jsonDecode(examsJson) as List).map((e) => Exam.fromJson(e)).toList();
@ -69,7 +69,7 @@ class UserDatabaseQuery {
Future<List<Homework>> getHomework({required String userId}) async {
List<Map> 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> homework = (jsonDecode(homeworkJson) as List).map((e) => Homework.fromJson(e)).toList();
@ -78,7 +78,7 @@ class UserDatabaseQuery {
Future<List<Message>> getMessages({required String userId}) async {
List<Map> 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<Message> messages = (jsonDecode(messagesJson) as List).map((e) => Message.fromJson(e)).toList();
@ -87,7 +87,7 @@ class UserDatabaseQuery {
Future<List<Note>> getNotes({required String userId}) async {
List<Map> 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<Note> notes = (jsonDecode(notesJson) as List).map((e) => Note.fromJson(e)).toList();
@ -96,7 +96,7 @@ class UserDatabaseQuery {
Future<List<Event>> getEvents({required String userId}) async {
List<Map> 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<Event> events = (jsonDecode(eventsJson) as List).map((e) => Event.fromJson(e)).toList();
@ -105,7 +105,7 @@ class UserDatabaseQuery {
Future<List<Absence>> getAbsences({required String userId}) async {
List<Map> 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<Absence> absebces = (jsonDecode(absebcesJson) as List).map((e) => Absence.fromJson(e)).toList();

View File

@ -24,7 +24,7 @@ class DatabaseStore {
Future<void> 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());

View File

@ -15,7 +15,7 @@ class DatabaseStruct {
break;
}
return "${name} ${typeName.toUpperCase()} ${name == 'id' ? 'NOT NULL' : ''}";
return "$name ${typeName.toUpperCase()} ${name == 'id' ? 'NOT NULL' : ''}";
}
@override

View File

@ -6,14 +6,15 @@ class AverageHelper {
List<String> 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

View File

@ -1,3 +1,5 @@
// ignore_for_file: avoid_print
import 'dart:io';
import 'dart:typed_data';

View File

@ -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;
}

View File

@ -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 {

View File

@ -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);
}
});

View File

@ -58,11 +58,12 @@ 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
p = string.split(".");
@ -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<String> prereleases = ["dev", "pre", "alpha", "beta", "rc"];
@override
int get hashCode => toString().hashCode;
}

View File

@ -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<DatabaseProvider>(context, listen: false);
database ??= Provider.of<DatabaseProvider>(context, listen: false);
await database.store.storeSettings(this);
notifyListeners();
}

View File

@ -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,
};
}
}

View File

@ -11,14 +11,14 @@ class AppTheme {
// Light Theme
static ThemeData lightTheme(BuildContext context) {
var lightColors = LightAppColors();
Color accent = accentColorMap[Provider.of<SettingsProvider>(context, listen: false).accentColor] ?? Color(0);
Color accent = accentColorMap[Provider.of<SettingsProvider>(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<SettingsProvider>(context, listen: false).accentColor] ?? Color(0);
Color accent = accentColorMap[Provider.of<SettingsProvider>(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<AccentColor, Color> 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<AccentColor, Color> 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 {

View File

@ -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)
}

View File

@ -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");
}
}

View File

@ -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

@ -1 +1 @@
Subproject commit 695ca3bcf9d67c3d316f08e1585fff9896d87c25
Subproject commit 07658366419b844fbbcb68ac5da8432c313608bb