add premium backend

This commit is contained in:
55nknown 2022-11-20 19:25:04 +01:00
parent ac18cf62c3
commit 75b03b95bc
19 changed files with 107 additions and 31 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
# See https://www.dartlang.org/guides/libraries/private-files
termek.txt
.DS_Store
# Files and directories created by pub
.dart_tool/

View File

@ -6,6 +6,16 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with https://api.filcnaplo.hu -->
<data
android:scheme="https"
android:host="api.filcnaplo.hu"
android:pathPrefix="/callback" />
</intent-filter>
</activity>
<meta-data android:name="flutterEmbedding" android:value="2" />
</application>

Binary file not shown.

View File

@ -4,5 +4,9 @@
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:api.filcnaplo.hu</string>
</array>
</dict>
</plist>

View File

@ -21,6 +21,8 @@ class FilcAPI {
// Private API
static const config = "https://api.filcnaplo.hu/config";
static const reportApi = "https://api.filcnaplo.hu/report";
static const premiumApi = "https://api.filcnaplo.hu/premium/activate";
static const premiumScopesApi = "https://api.filcnaplo.hu/premium/scopes";
// Updates
static const repo = "filc/naplo";

View File

@ -41,7 +41,7 @@ class NewsProvider extends ChangeNotifier {
}
_state = state_;
Provider.of<SettingsProvider>(_context, listen: false).update(_context, newsState: _state);
Provider.of<SettingsProvider>(_context, listen: false).update(newsState: _state);
}
Future<void> fetch() async {
@ -53,7 +53,7 @@ class NewsProvider extends ChangeNotifier {
if (_fresh < 0) {
_state = news_.length;
Provider.of<SettingsProvider>(_context, listen: false).update(_context, newsState: _state);
Provider.of<SettingsProvider>(_context, listen: false).update(newsState: _state);
}
_fresh = max(_fresh, 0);
@ -72,7 +72,7 @@ class NewsProvider extends ChangeNotifier {
_fresh--;
_state++;
Provider.of<SettingsProvider>(_context, listen: false).update(_context, newsState: _state);
Provider.of<SettingsProvider>(_context, listen: false).update(newsState: _state);
if (_fresh > 0) {
show = true;

View File

@ -45,6 +45,7 @@ import 'package:filcnaplo/api/providers/user_provider.dart';
import 'package:filcnaplo/api/providers/update_provider.dart';
import 'package:filcnaplo_mobile_ui/pages/grades/calculator/grade_calculator_provider.dart';
import 'package:flutter_displaymode/flutter_displaymode.dart';
import 'package:filcnaplo_premium/providers/premium_provider.dart';
class App extends StatelessWidget {
final SettingsProvider settings;
@ -62,20 +63,23 @@ class App extends StatelessWidget {
// Set high refresh mode #28
if (Platform.isAndroid) FlutterDisplayMode.setHighRefreshRate();
WidgetsBinding.instance.addPostFrameCallback((_) {
FilcAPI.getConfig(settings).then((Config? config) {
if (config != null) settings.update(context, database: database, config: config);
});
});
CorePalette? corePalette;
final status = StatusProvider();
final kreta = KretaClient(user: user, settings: settings, status: status);
final timetable = TimetableProvider(user: user, database: database, kreta: kreta);
final premium = PremiumProvider(settings: settings);
WidgetsBinding.instance.addPostFrameCallback((_) {
FilcAPI.getConfig(settings).then((Config? config) {
if (config != null) settings.update(config: config);
});
premium.activate();
});
return MultiProvider(
providers: [
ChangeNotifierProvider<PremiumProvider>(create: (_) => premium),
ChangeNotifierProvider<SettingsProvider>(create: (_) => settings),
ChangeNotifierProvider<UserProvider>(create: (_) => user),
ChangeNotifierProvider<StatusProvider>(create: (_) => status),

View File

@ -2,6 +2,7 @@
import 'dart:io';
import 'package:filcnaplo/api/providers/database_provider.dart';
import 'package:filcnaplo/database/struct.dart';
import 'package:filcnaplo/models/settings.dart';
import 'package:sqflite/sqflite.dart';
@ -15,7 +16,7 @@ const settingsDB = DatabaseStruct("settings", {
"vibration_strength": int, "ab_weeks": int, "swap_ab_weeks": int,
"notifications": int, "notifications_bitfield": int, "notification_poll_interval": int, // notifications
"x_filc_id": String, "graph_class_avg": int, "presentation_mode": int, "bell_delay": int, "bell_delay_enabled": int,
"grade_opening_fun": int, "icon_pack": String,
"grade_opening_fun": int, "icon_pack": String, "premium_scopes": String, "premium_token": String,
});
const usersDB = DatabaseStruct("users", {
"id": String, "name": String, "username": String, "password": String, "institute_code": String, "student": String, "role": int,
@ -30,7 +31,7 @@ const userDataDB = DatabaseStruct("user_data", {
Future<void> createTable(Database db, DatabaseStruct struct) => db.execute("CREATE TABLE IF NOT EXISTS ${struct.table} ($struct)");
Future<Database> initDB() async {
Future<Database> initDB(DatabaseProvider database) async {
Database db;
if (Platform.isLinux || Platform.isWindows) {
@ -46,7 +47,7 @@ Future<Database> initDB() async {
if ((await db.rawQuery("SELECT COUNT(*) FROM settings"))[0].values.first == 0) {
// Set default values for table Settings
await db.insert("settings", SettingsProvider.defaultSettings().toMap());
await db.insert("settings", SettingsProvider.defaultSettings(database: database).toMap());
}
// Migrate Databases
@ -54,7 +55,7 @@ Future<Database> initDB() async {
await migrateDB(
db,
struct: settingsDB,
defaultValues: SettingsProvider.defaultSettings().toMap(),
defaultValues: SettingsProvider.defaultSettings(database: database).toMap(),
);
await migrateDB(
db,

View File

@ -1,4 +1,5 @@
import 'dart:convert';
import 'package:filcnaplo/api/providers/database_provider.dart';
import 'package:filcnaplo/models/subject_lesson_count.dart';
import 'package:filcnaplo/models/user.dart';
// ignore: depend_on_referenced_packages
@ -22,9 +23,9 @@ class DatabaseQuery {
final Database db;
Future<SettingsProvider> getSettings() async {
Future<SettingsProvider> getSettings(DatabaseProvider database) async {
Map settingsMap = (await db.query("settings")).elementAt(0);
SettingsProvider settings = SettingsProvider.fromMap(settingsMap);
SettingsProvider settings = SettingsProvider.fromMap(settingsMap, database: database);
return settings;
}

View File

@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:developer';
import 'package:filcnaplo/models/subject_lesson_count.dart';
// ignore: depend_on_referenced_packages
import 'package:sqflite_common/sqlite_api.dart';

View File

@ -5,6 +5,7 @@ import 'package:share_plus/share_plus.dart';
class ShareHelper {
static Future<void> shareText(String text, {String? subject}) => Share.share(text, subject: subject);
// ignore: deprecated_member_use
static Future<void> shareFile(String path, {String? text, String? subject}) => Share.shareFiles([path], text: text, subject: subject);
static Future<void> shareAttachment(Attachment attachment, {required BuildContext context}) async {

View File

@ -16,4 +16,7 @@ class FilcIcons {
/// downstairs
static const IconData downstairs = IconData(0x03, fontFamily: iconFontFamily);
/// premium
static const IconData premium = IconData(0x04, fontFamily: iconFontFamily);
}

View File

@ -32,11 +32,11 @@ class Startup {
late DatabaseProvider database;
Future<void> start() async {
var db = await initDB();
await db.close();
database = DatabaseProvider();
var db = await initDB(database);
await db.close();
await database.init();
settings = await database.query.getSettings();
settings = await database.query.getSettings(database);
user = await database.query.getUsers();
}
}

View File

@ -7,7 +7,6 @@ import 'package:filcnaplo/models/icon_pack.dart';
import 'package:filcnaplo/theme/colors/accent.dart';
import 'package:filcnaplo/theme/colors/dark_mobile.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:uuid/uuid.dart';
enum Pages { home, grades, timetable, messages, absences }
@ -17,6 +16,8 @@ enum UpdateChannel { stable, beta, dev }
enum VibrationStrength { off, light, medium, strong }
class SettingsProvider extends ChangeNotifier {
final DatabaseProvider? _database;
// en_en, hu_hu, de_de
String _language;
Pages _startPage;
@ -61,8 +62,11 @@ class SettingsProvider extends ChangeNotifier {
Color _customAccentColor;
Color _customBackgroundColor;
Color _customHighlightColor;
List<String> _premiumScopes;
String _premiumAccessToken;
SettingsProvider({
DatabaseProvider? database,
required String language,
required Pages startPage,
required int rounding,
@ -91,7 +95,10 @@ class SettingsProvider extends ChangeNotifier {
required Color customAccentColor,
required Color customBackgroundColor,
required Color customHighlightColor,
}) : _language = language,
required List<String> premiumScopes,
required String premiumAccessToken,
}) : _database = database,
_language = language,
_startPage = startPage,
_rounding = rounding,
_theme = theme,
@ -118,9 +125,11 @@ class SettingsProvider extends ChangeNotifier {
_iconPack = iconPack,
_customAccentColor = customAccentColor,
_customBackgroundColor = customBackgroundColor,
_customHighlightColor = customHighlightColor;
_customHighlightColor = customHighlightColor,
_premiumScopes = premiumScopes,
_premiumAccessToken = premiumAccessToken;
factory SettingsProvider.fromMap(Map map) {
factory SettingsProvider.fromMap(Map map, {required DatabaseProvider database}) {
Map<String, Object?>? configMap;
try {
@ -130,6 +139,7 @@ class SettingsProvider extends ChangeNotifier {
}
return SettingsProvider(
database: database,
language: map["language"],
startPage: Pages.values[map["start_page"]],
rounding: map["rounding"],
@ -164,6 +174,8 @@ class SettingsProvider extends ChangeNotifier {
customAccentColor: Color(map["custom_accent_color"]),
customBackgroundColor: Color(map["custom_background_color"]),
customHighlightColor: Color(map["custom_highlight_color"]),
premiumScopes: jsonDecode(map["premium_scopes"]).cast<String>(),
premiumAccessToken: map["premium_token"],
);
}
@ -200,11 +212,14 @@ class SettingsProvider extends ChangeNotifier {
"custom_accent_color": _customAccentColor.value,
"custom_background_color": _customBackgroundColor.value,
"custom_highlight_color": _customHighlightColor.value,
"premium_scopes": jsonEncode(_premiumScopes),
"premium_token": _premiumAccessToken,
};
}
factory SettingsProvider.defaultSettings() {
factory SettingsProvider.defaultSettings({DatabaseProvider? database}) {
return SettingsProvider(
database: database,
language: "hu",
startPage: Pages.home,
rounding: 5,
@ -239,6 +254,8 @@ class SettingsProvider extends ChangeNotifier {
customAccentColor: const Color(0xff20AC9B),
customBackgroundColor: const Color(0xff000000),
customHighlightColor: const Color(0xff222222),
premiumScopes: [],
premiumAccessToken: "",
);
}
@ -271,10 +288,10 @@ class SettingsProvider extends ChangeNotifier {
Color? get customAccentColor => _customAccentColor == accentColorMap[AccentColor.custom] ? null : _customAccentColor;
Color? get customBackgroundColor => _customBackgroundColor;
Color? get customHighlightColor => _customHighlightColor;
List<String> get premiumScopes => _premiumScopes;
String get premiumAccessToken => _premiumAccessToken;
Future<void> update(
BuildContext context, {
DatabaseProvider? database,
Future<void> update({
bool store = true,
String? language,
Pages? startPage,
@ -304,6 +321,8 @@ class SettingsProvider extends ChangeNotifier {
Color? customAccentColor,
Color? customBackgroundColor,
Color? customHighlightColor,
List<String>? premiumScopes,
String? premiumAccessToken,
}) async {
if (language != null && language != _language) _language = language;
if (startPage != null && startPage != _startPage) _startPage = startPage;
@ -335,9 +354,10 @@ class SettingsProvider extends ChangeNotifier {
if (customAccentColor != null && customAccentColor != _customAccentColor) _customAccentColor = customAccentColor;
if (customBackgroundColor != null && customBackgroundColor != _customBackgroundColor) _customBackgroundColor = customBackgroundColor;
if (customHighlightColor != null && customHighlightColor != _customHighlightColor) _customHighlightColor = customHighlightColor;
if (premiumScopes != null && premiumScopes != _premiumScopes) _premiumScopes = premiumScopes;
if (premiumAccessToken != null && premiumAccessToken != _premiumAccessToken) _premiumAccessToken = premiumAccessToken;
database ??= Provider.of<DatabaseProvider>(context, listen: false);
if (store) await database.store.storeSettings(this);
if (store) await _database?.store.storeSettings(this);
notifyListeners();
}
}

View File

@ -12,6 +12,7 @@ import 'package:filcnaplo/ui/filter/widgets/events.dart' as event_filter;
import 'package:filcnaplo/ui/filter/widgets/lessons.dart' as lesson_filter;
import 'package:filcnaplo/ui/filter/widgets/update.dart' as update_filter;
import 'package:filcnaplo/ui/filter/widgets/missed_exams.dart' as missed_exam_filter;
import 'package:filcnaplo/ui/filter/widgets/premium.dart' as premium_filter;
import 'package:filcnaplo_kreta_api/providers/absence_provider.dart';
import 'package:filcnaplo_kreta_api/providers/event_provider.dart';
import 'package:filcnaplo_kreta_api/providers/exam_provider.dart';
@ -20,6 +21,7 @@ import 'package:filcnaplo_kreta_api/providers/homework_provider.dart';
import 'package:filcnaplo_kreta_api/providers/message_provider.dart';
import 'package:filcnaplo_kreta_api/providers/note_provider.dart';
import 'package:filcnaplo_kreta_api/providers/timetable_provider.dart';
import 'package:filcnaplo_premium/providers/premium_provider.dart';
import 'package:filcnaplo_mobile_ui/common/panel/panel.dart';
import 'package:flutter/material.dart';
import 'package:implicitly_animated_reorderable_list/transitions.dart';
@ -27,7 +29,7 @@ import 'package:provider/provider.dart';
const List<FilterType> homeFilters = [FilterType.all, FilterType.grades, FilterType.messages, FilterType.absences];
enum FilterType { all, grades, newGrades, messages, absences, homework, exams, notes, events, lessons, updates, certifications, missedExams }
enum FilterType { all, grades, newGrades, messages, absences, homework, exams, notes, events, lessons, updates, certifications, missedExams, premium }
Future<List<DateWidget>> getFilterWidgets(FilterType activeData, {bool absencesNoExcused = false, required BuildContext context}) async {
final gradeProvider = Provider.of<GradeProvider>(context);
@ -40,6 +42,7 @@ Future<List<DateWidget>> getFilterWidgets(FilterType activeData, {bool absencesN
final eventProvider = Provider.of<EventProvider>(context);
final updateProvider = Provider.of<UpdateProvider>(context);
final settingsProvider = Provider.of<SettingsProvider>(context);
final premiumProvider = Provider.of<PremiumProvider>(context);
List<DateWidget> items = [];
@ -56,6 +59,7 @@ Future<List<DateWidget>> getFilterWidgets(FilterType activeData, {bool absencesN
getFilterWidgets(FilterType.updates, context: context),
getFilterWidgets(FilterType.certifications, context: context),
getFilterWidgets(FilterType.missedExams, context: context),
getFilterWidgets(FilterType.premium, context: context),
]);
items = all.expand((x) => x).toList();
@ -127,6 +131,12 @@ Future<List<DateWidget>> getFilterWidgets(FilterType activeData, {bool absencesN
case FilterType.missedExams:
items = missed_exam_filter.getWidgets(timetableProvider.lessons);
break;
case FilterType.premium:
final now = DateTime.now();
final isWeekend = now.weekday == DateTime.saturday || now.weekday == DateTime.sunday;
items = [if (!premiumProvider.hasPremium && isWeekend) premium_filter.getWidget()];
break;
}
return items;
}

View File

@ -0,0 +1,16 @@
import 'package:filcnaplo/ui/date_widget.dart';
import 'package:filcnaplo_premium/ui/mobile/premium/premium_banner_button.dart';
import 'package:flutter/widgets.dart';
DateWidget getWidget() {
return DateWidget(
date: DateTime.now().add(const Duration(minutes: 1)),
widget: Padding(
padding: const EdgeInsets.symmetric(horizontal: 6.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(14.0),
child: const PremiumBannerButton(),
),
),
);
}

View File

@ -57,6 +57,8 @@ dependencies:
git:
url: https://github.com/filc/flutter_expandable_fab
ref: master
uni_links: ^0.5.1
url_launcher: ^6.1.6
dev_dependencies:
flutter_lints: ^2.0.1

@ -1 +1 @@
Subproject commit beac629f88a4d7cb9b5edf696e1fe067aef84ff0
Subproject commit 8dca7bf10124b2eae89441f9defc506a7127755c

@ -1 +1 @@
Subproject commit f659db4e98390df3a46d82357b8880f2c91e379b
Subproject commit ea41ee168fc3b1cac9d3c760edc4e5fd7c391d1f