Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.

Commit 75b03b9

Browse files
author
55nknown
committed
add premium backend
1 parent ac18cf6 commit 75b03b9

19 files changed

+107
-31
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# See https://www.dartlang.org/guides/libraries/private-files
22

33
termek.txt
4+
.DS_Store
45

56
# Files and directories created by pub
67
.dart_tool/

filcnaplo/android/app/src/main/AndroidManifest.xml

+10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@
66
<action android:name="android.intent.action.MAIN" />
77
<category android:name="android.intent.category.LAUNCHER" />
88
</intent-filter>
9+
<intent-filter android:autoVerify="true">
10+
<action android:name="android.intent.action.VIEW" />
11+
<category android:name="android.intent.category.DEFAULT" />
12+
<category android:name="android.intent.category.BROWSABLE" />
13+
<!-- Accepts URIs that begin with https://api.filcnaplo.hu -->
14+
<data
15+
android:scheme="https"
16+
android:host="api.filcnaplo.hu"
17+
android:pathPrefix="/callback" />
18+
</intent-filter>
919
</activity>
1020
<meta-data android:name="flutterEmbedding" android:value="2" />
1121
</application>

filcnaplo/assets/fonts/FilcIcons.ttf

160 Bytes
Binary file not shown.

filcnaplo/ios/Runner/Runner.entitlements

+4
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@
44
<dict>
55
<key>aps-environment</key>
66
<string>development</string>
7+
<key>com.apple.developer.associated-domains</key>
8+
<array>
9+
<string>applinks:api.filcnaplo.hu</string>
10+
</array>
711
</dict>
812
</plist>

filcnaplo/lib/api/client.dart

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ class FilcAPI {
2121
// Private API
2222
static const config = "https://api.filcnaplo.hu/config";
2323
static const reportApi = "https://api.filcnaplo.hu/report";
24+
static const premiumApi = "https://api.filcnaplo.hu/premium/activate";
25+
static const premiumScopesApi = "https://api.filcnaplo.hu/premium/scopes";
2426

2527
// Updates
2628
static const repo = "filc/naplo";

filcnaplo/lib/api/providers/news_provider.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class NewsProvider extends ChangeNotifier {
4141
}
4242

4343
_state = state_;
44-
Provider.of<SettingsProvider>(_context, listen: false).update(_context, newsState: _state);
44+
Provider.of<SettingsProvider>(_context, listen: false).update(newsState: _state);
4545
}
4646

4747
Future<void> fetch() async {
@@ -53,7 +53,7 @@ class NewsProvider extends ChangeNotifier {
5353

5454
if (_fresh < 0) {
5555
_state = news_.length;
56-
Provider.of<SettingsProvider>(_context, listen: false).update(_context, newsState: _state);
56+
Provider.of<SettingsProvider>(_context, listen: false).update(newsState: _state);
5757
}
5858

5959
_fresh = max(_fresh, 0);
@@ -72,7 +72,7 @@ class NewsProvider extends ChangeNotifier {
7272
_fresh--;
7373
_state++;
7474

75-
Provider.of<SettingsProvider>(_context, listen: false).update(_context, newsState: _state);
75+
Provider.of<SettingsProvider>(_context, listen: false).update(newsState: _state);
7676

7777
if (_fresh > 0) {
7878
show = true;

filcnaplo/lib/app.dart

+10-6
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import 'package:filcnaplo/api/providers/user_provider.dart';
4545
import 'package:filcnaplo/api/providers/update_provider.dart';
4646
import 'package:filcnaplo_mobile_ui/pages/grades/calculator/grade_calculator_provider.dart';
4747
import 'package:flutter_displaymode/flutter_displaymode.dart';
48+
import 'package:filcnaplo_premium/providers/premium_provider.dart';
4849

4950
class App extends StatelessWidget {
5051
final SettingsProvider settings;
@@ -62,20 +63,23 @@ class App extends StatelessWidget {
6263
// Set high refresh mode #28
6364
if (Platform.isAndroid) FlutterDisplayMode.setHighRefreshRate();
6465

65-
WidgetsBinding.instance.addPostFrameCallback((_) {
66-
FilcAPI.getConfig(settings).then((Config? config) {
67-
if (config != null) settings.update(context, database: database, config: config);
68-
});
69-
});
70-
7166
CorePalette? corePalette;
7267

7368
final status = StatusProvider();
7469
final kreta = KretaClient(user: user, settings: settings, status: status);
7570
final timetable = TimetableProvider(user: user, database: database, kreta: kreta);
71+
final premium = PremiumProvider(settings: settings);
72+
73+
WidgetsBinding.instance.addPostFrameCallback((_) {
74+
FilcAPI.getConfig(settings).then((Config? config) {
75+
if (config != null) settings.update(config: config);
76+
});
77+
premium.activate();
78+
});
7679

7780
return MultiProvider(
7881
providers: [
82+
ChangeNotifierProvider<PremiumProvider>(create: (_) => premium),
7983
ChangeNotifierProvider<SettingsProvider>(create: (_) => settings),
8084
ChangeNotifierProvider<UserProvider>(create: (_) => user),
8185
ChangeNotifierProvider<StatusProvider>(create: (_) => status),

filcnaplo/lib/database/init.dart

+5-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import 'dart:io';
44

5+
import 'package:filcnaplo/api/providers/database_provider.dart';
56
import 'package:filcnaplo/database/struct.dart';
67
import 'package:filcnaplo/models/settings.dart';
78
import 'package:sqflite/sqflite.dart';
@@ -15,7 +16,7 @@ const settingsDB = DatabaseStruct("settings", {
1516
"vibration_strength": int, "ab_weeks": int, "swap_ab_weeks": int,
1617
"notifications": int, "notifications_bitfield": int, "notification_poll_interval": int, // notifications
1718
"x_filc_id": String, "graph_class_avg": int, "presentation_mode": int, "bell_delay": int, "bell_delay_enabled": int,
18-
"grade_opening_fun": int, "icon_pack": String,
19+
"grade_opening_fun": int, "icon_pack": String, "premium_scopes": String, "premium_token": String,
1920
});
2021
const usersDB = DatabaseStruct("users", {
2122
"id": String, "name": String, "username": String, "password": String, "institute_code": String, "student": String, "role": int,
@@ -30,7 +31,7 @@ const userDataDB = DatabaseStruct("user_data", {
3031

3132
Future<void> createTable(Database db, DatabaseStruct struct) => db.execute("CREATE TABLE IF NOT EXISTS ${struct.table} ($struct)");
3233

33-
Future<Database> initDB() async {
34+
Future<Database> initDB(DatabaseProvider database) async {
3435
Database db;
3536

3637
if (Platform.isLinux || Platform.isWindows) {
@@ -46,15 +47,15 @@ Future<Database> initDB() async {
4647

4748
if ((await db.rawQuery("SELECT COUNT(*) FROM settings"))[0].values.first == 0) {
4849
// Set default values for table Settings
49-
await db.insert("settings", SettingsProvider.defaultSettings().toMap());
50+
await db.insert("settings", SettingsProvider.defaultSettings(database: database).toMap());
5051
}
5152

5253
// Migrate Databases
5354
try {
5455
await migrateDB(
5556
db,
5657
struct: settingsDB,
57-
defaultValues: SettingsProvider.defaultSettings().toMap(),
58+
defaultValues: SettingsProvider.defaultSettings(database: database).toMap(),
5859
);
5960
await migrateDB(
6061
db,

filcnaplo/lib/database/query.dart

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'dart:convert';
2+
import 'package:filcnaplo/api/providers/database_provider.dart';
23
import 'package:filcnaplo/models/subject_lesson_count.dart';
34
import 'package:filcnaplo/models/user.dart';
45
// ignore: depend_on_referenced_packages
@@ -22,9 +23,9 @@ class DatabaseQuery {
2223

2324
final Database db;
2425

25-
Future<SettingsProvider> getSettings() async {
26+
Future<SettingsProvider> getSettings(DatabaseProvider database) async {
2627
Map settingsMap = (await db.query("settings")).elementAt(0);
27-
SettingsProvider settings = SettingsProvider.fromMap(settingsMap);
28+
SettingsProvider settings = SettingsProvider.fromMap(settingsMap, database: database);
2829
return settings;
2930
}
3031

filcnaplo/lib/database/store.dart

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'dart:convert';
2+
import 'dart:developer';
23
import 'package:filcnaplo/models/subject_lesson_count.dart';
34
// ignore: depend_on_referenced_packages
45
import 'package:sqflite_common/sqlite_api.dart';

filcnaplo/lib/helpers/share_helper.dart

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:share_plus/share_plus.dart';
55

66
class ShareHelper {
77
static Future<void> shareText(String text, {String? subject}) => Share.share(text, subject: subject);
8+
// ignore: deprecated_member_use
89
static Future<void> shareFile(String path, {String? text, String? subject}) => Share.shareFiles([path], text: text, subject: subject);
910

1011
static Future<void> shareAttachment(Attachment attachment, {required BuildContext context}) async {

filcnaplo/lib/icons/filc_icons.dart

+3
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,7 @@ class FilcIcons {
1616

1717
/// downstairs
1818
static const IconData downstairs = IconData(0x03, fontFamily: iconFontFamily);
19+
20+
/// premium
21+
static const IconData premium = IconData(0x04, fontFamily: iconFontFamily);
1922
}

filcnaplo/lib/main.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ class Startup {
3232
late DatabaseProvider database;
3333

3434
Future<void> start() async {
35-
var db = await initDB();
36-
await db.close();
3735
database = DatabaseProvider();
36+
var db = await initDB(database);
37+
await db.close();
3838
await database.init();
39-
settings = await database.query.getSettings();
39+
settings = await database.query.getSettings(database);
4040
user = await database.query.getUsers();
4141
}
4242
}

filcnaplo/lib/models/settings.dart

+30-10
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import 'package:filcnaplo/models/icon_pack.dart';
77
import 'package:filcnaplo/theme/colors/accent.dart';
88
import 'package:filcnaplo/theme/colors/dark_mobile.dart';
99
import 'package:flutter/material.dart';
10-
import 'package:provider/provider.dart';
1110
import 'package:uuid/uuid.dart';
1211

1312
enum Pages { home, grades, timetable, messages, absences }
@@ -17,6 +16,8 @@ enum UpdateChannel { stable, beta, dev }
1716
enum VibrationStrength { off, light, medium, strong }
1817

1918
class SettingsProvider extends ChangeNotifier {
19+
final DatabaseProvider? _database;
20+
2021
// en_en, hu_hu, de_de
2122
String _language;
2223
Pages _startPage;
@@ -61,8 +62,11 @@ class SettingsProvider extends ChangeNotifier {
6162
Color _customAccentColor;
6263
Color _customBackgroundColor;
6364
Color _customHighlightColor;
65+
List<String> _premiumScopes;
66+
String _premiumAccessToken;
6467

6568
SettingsProvider({
69+
DatabaseProvider? database,
6670
required String language,
6771
required Pages startPage,
6872
required int rounding,
@@ -91,7 +95,10 @@ class SettingsProvider extends ChangeNotifier {
9195
required Color customAccentColor,
9296
required Color customBackgroundColor,
9397
required Color customHighlightColor,
94-
}) : _language = language,
98+
required List<String> premiumScopes,
99+
required String premiumAccessToken,
100+
}) : _database = database,
101+
_language = language,
95102
_startPage = startPage,
96103
_rounding = rounding,
97104
_theme = theme,
@@ -118,9 +125,11 @@ class SettingsProvider extends ChangeNotifier {
118125
_iconPack = iconPack,
119126
_customAccentColor = customAccentColor,
120127
_customBackgroundColor = customBackgroundColor,
121-
_customHighlightColor = customHighlightColor;
128+
_customHighlightColor = customHighlightColor,
129+
_premiumScopes = premiumScopes,
130+
_premiumAccessToken = premiumAccessToken;
122131

123-
factory SettingsProvider.fromMap(Map map) {
132+
factory SettingsProvider.fromMap(Map map, {required DatabaseProvider database}) {
124133
Map<String, Object?>? configMap;
125134

126135
try {
@@ -130,6 +139,7 @@ class SettingsProvider extends ChangeNotifier {
130139
}
131140

132141
return SettingsProvider(
142+
database: database,
133143
language: map["language"],
134144
startPage: Pages.values[map["start_page"]],
135145
rounding: map["rounding"],
@@ -164,6 +174,8 @@ class SettingsProvider extends ChangeNotifier {
164174
customAccentColor: Color(map["custom_accent_color"]),
165175
customBackgroundColor: Color(map["custom_background_color"]),
166176
customHighlightColor: Color(map["custom_highlight_color"]),
177+
premiumScopes: jsonDecode(map["premium_scopes"]).cast<String>(),
178+
premiumAccessToken: map["premium_token"],
167179
);
168180
}
169181

@@ -200,11 +212,14 @@ class SettingsProvider extends ChangeNotifier {
200212
"custom_accent_color": _customAccentColor.value,
201213
"custom_background_color": _customBackgroundColor.value,
202214
"custom_highlight_color": _customHighlightColor.value,
215+
"premium_scopes": jsonEncode(_premiumScopes),
216+
"premium_token": _premiumAccessToken,
203217
};
204218
}
205219

206-
factory SettingsProvider.defaultSettings() {
220+
factory SettingsProvider.defaultSettings({DatabaseProvider? database}) {
207221
return SettingsProvider(
222+
database: database,
208223
language: "hu",
209224
startPage: Pages.home,
210225
rounding: 5,
@@ -239,6 +254,8 @@ class SettingsProvider extends ChangeNotifier {
239254
customAccentColor: const Color(0xff20AC9B),
240255
customBackgroundColor: const Color(0xff000000),
241256
customHighlightColor: const Color(0xff222222),
257+
premiumScopes: [],
258+
premiumAccessToken: "",
242259
);
243260
}
244261

@@ -271,10 +288,10 @@ class SettingsProvider extends ChangeNotifier {
271288
Color? get customAccentColor => _customAccentColor == accentColorMap[AccentColor.custom] ? null : _customAccentColor;
272289
Color? get customBackgroundColor => _customBackgroundColor;
273290
Color? get customHighlightColor => _customHighlightColor;
291+
List<String> get premiumScopes => _premiumScopes;
292+
String get premiumAccessToken => _premiumAccessToken;
274293

275-
Future<void> update(
276-
BuildContext context, {
277-
DatabaseProvider? database,
294+
Future<void> update({
278295
bool store = true,
279296
String? language,
280297
Pages? startPage,
@@ -304,6 +321,8 @@ class SettingsProvider extends ChangeNotifier {
304321
Color? customAccentColor,
305322
Color? customBackgroundColor,
306323
Color? customHighlightColor,
324+
List<String>? premiumScopes,
325+
String? premiumAccessToken,
307326
}) async {
308327
if (language != null && language != _language) _language = language;
309328
if (startPage != null && startPage != _startPage) _startPage = startPage;
@@ -335,9 +354,10 @@ class SettingsProvider extends ChangeNotifier {
335354
if (customAccentColor != null && customAccentColor != _customAccentColor) _customAccentColor = customAccentColor;
336355
if (customBackgroundColor != null && customBackgroundColor != _customBackgroundColor) _customBackgroundColor = customBackgroundColor;
337356
if (customHighlightColor != null && customHighlightColor != _customHighlightColor) _customHighlightColor = customHighlightColor;
357+
if (premiumScopes != null && premiumScopes != _premiumScopes) _premiumScopes = premiumScopes;
358+
if (premiumAccessToken != null && premiumAccessToken != _premiumAccessToken) _premiumAccessToken = premiumAccessToken;
338359

339-
database ??= Provider.of<DatabaseProvider>(context, listen: false);
340-
if (store) await database.store.storeSettings(this);
360+
if (store) await _database?.store.storeSettings(this);
341361
notifyListeners();
342362
}
343363
}

filcnaplo/lib/ui/filter/widgets.dart

+11-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import 'package:filcnaplo/ui/filter/widgets/events.dart' as event_filter;
1212
import 'package:filcnaplo/ui/filter/widgets/lessons.dart' as lesson_filter;
1313
import 'package:filcnaplo/ui/filter/widgets/update.dart' as update_filter;
1414
import 'package:filcnaplo/ui/filter/widgets/missed_exams.dart' as missed_exam_filter;
15+
import 'package:filcnaplo/ui/filter/widgets/premium.dart' as premium_filter;
1516
import 'package:filcnaplo_kreta_api/providers/absence_provider.dart';
1617
import 'package:filcnaplo_kreta_api/providers/event_provider.dart';
1718
import 'package:filcnaplo_kreta_api/providers/exam_provider.dart';
@@ -20,14 +21,15 @@ import 'package:filcnaplo_kreta_api/providers/homework_provider.dart';
2021
import 'package:filcnaplo_kreta_api/providers/message_provider.dart';
2122
import 'package:filcnaplo_kreta_api/providers/note_provider.dart';
2223
import 'package:filcnaplo_kreta_api/providers/timetable_provider.dart';
24+
import 'package:filcnaplo_premium/providers/premium_provider.dart';
2325
import 'package:filcnaplo_mobile_ui/common/panel/panel.dart';
2426
import 'package:flutter/material.dart';
2527
import 'package:implicitly_animated_reorderable_list/transitions.dart';
2628
import 'package:provider/provider.dart';
2729

2830
const List<FilterType> homeFilters = [FilterType.all, FilterType.grades, FilterType.messages, FilterType.absences];
2931

30-
enum FilterType { all, grades, newGrades, messages, absences, homework, exams, notes, events, lessons, updates, certifications, missedExams }
32+
enum FilterType { all, grades, newGrades, messages, absences, homework, exams, notes, events, lessons, updates, certifications, missedExams, premium }
3133

3234
Future<List<DateWidget>> getFilterWidgets(FilterType activeData, {bool absencesNoExcused = false, required BuildContext context}) async {
3335
final gradeProvider = Provider.of<GradeProvider>(context);
@@ -40,6 +42,7 @@ Future<List<DateWidget>> getFilterWidgets(FilterType activeData, {bool absencesN
4042
final eventProvider = Provider.of<EventProvider>(context);
4143
final updateProvider = Provider.of<UpdateProvider>(context);
4244
final settingsProvider = Provider.of<SettingsProvider>(context);
45+
final premiumProvider = Provider.of<PremiumProvider>(context);
4346

4447
List<DateWidget> items = [];
4548

@@ -56,6 +59,7 @@ Future<List<DateWidget>> getFilterWidgets(FilterType activeData, {bool absencesN
5659
getFilterWidgets(FilterType.updates, context: context),
5760
getFilterWidgets(FilterType.certifications, context: context),
5861
getFilterWidgets(FilterType.missedExams, context: context),
62+
getFilterWidgets(FilterType.premium, context: context),
5963
]);
6064
items = all.expand((x) => x).toList();
6165

@@ -127,6 +131,12 @@ Future<List<DateWidget>> getFilterWidgets(FilterType activeData, {bool absencesN
127131
case FilterType.missedExams:
128132
items = missed_exam_filter.getWidgets(timetableProvider.lessons);
129133
break;
134+
135+
case FilterType.premium:
136+
final now = DateTime.now();
137+
final isWeekend = now.weekday == DateTime.saturday || now.weekday == DateTime.sunday;
138+
items = [if (!premiumProvider.hasPremium && isWeekend) premium_filter.getWidget()];
139+
break;
130140
}
131141
return items;
132142
}

0 commit comments

Comments
 (0)