forked from firka/firka
feat: account switching
This commit is contained in:
@@ -327,7 +327,15 @@ class SettingsStore {
|
||||
developerOptsEnabled, null, null, "Developer", false, never),
|
||||
}),
|
||||
always);
|
||||
|
||||
items["profile_settings"] = SettingsGroup(
|
||||
0,
|
||||
LinkedHashMap.of({
|
||||
"back": SettingsBackHeader(0, l10n.s_your_account, always),
|
||||
"e_kreta_accounts": SettingsHeaderSmall(0, l10n.s_acc_kreta, always),
|
||||
"e_padding": SettingsPadding(0, 8, always),
|
||||
"e_kreta_account_picker": SettingsKretenAccountPicker(0, always),
|
||||
}),
|
||||
never);
|
||||
appIcons = {
|
||||
"ace": l10n.ic_ace,
|
||||
"ace_f": l10n.ic_ace_f,
|
||||
@@ -676,6 +684,45 @@ class SettingsAppIconPreview implements SettingsItem {
|
||||
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
|
||||
}
|
||||
|
||||
class SettingsKretenAccountPicker implements SettingsItem {
|
||||
@override
|
||||
Id key;
|
||||
@override
|
||||
FirkaIconType? iconType;
|
||||
@override
|
||||
Object? iconData;
|
||||
@override
|
||||
bool Function() visibilityProvider;
|
||||
@override
|
||||
Future<void> Function() postUpdate = () async {};
|
||||
String title = "";
|
||||
String icon = "";
|
||||
int accountIndex = 0;
|
||||
|
||||
SettingsKretenAccountPicker(this.key, this.visibilityProvider);
|
||||
|
||||
@override
|
||||
Future<void> load(IsarCollection<AppSettingsModel> model) async {
|
||||
var v = await model.get(key);
|
||||
if (v == null || v.valueIndex == null) {
|
||||
accountIndex = 0;
|
||||
} else {
|
||||
accountIndex = v.valueIndex!;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> save(IsarCollection<AppSettingsModel> model) async {
|
||||
var v = AppSettingsModel();
|
||||
v.id = key;
|
||||
v.valueIndex = accountIndex;
|
||||
|
||||
await model.put(v);
|
||||
|
||||
initData.settingsUpdateNotifier.update();
|
||||
}
|
||||
}
|
||||
|
||||
class SettingsAppIconPicker implements SettingsItem {
|
||||
@override
|
||||
Id key;
|
||||
|
||||
Submodule firka/lib/l10n updated: 1370e9bcba...5329e7efd2
@@ -63,7 +63,7 @@ class AppInitialization {
|
||||
final PackageInfo packageInfo;
|
||||
final DeviceInfo devInfo;
|
||||
late KretaClient client;
|
||||
int tokenCount;
|
||||
List<TokenModel> tokens;
|
||||
bool hasWatchListener = false;
|
||||
Uint8List? profilePicture;
|
||||
SettingsStore settings;
|
||||
@@ -74,7 +74,7 @@ class AppInitialization {
|
||||
required this.isar,
|
||||
required this.devInfo,
|
||||
required this.packageInfo,
|
||||
required this.tokenCount,
|
||||
required this.tokens,
|
||||
required this.settings,
|
||||
required this.l10n,
|
||||
});
|
||||
@@ -154,13 +154,51 @@ void initTheme(AppInitialization data) {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _initData(AppInitialization init) async {
|
||||
await init.settings.load(init.isar.appSettingsModels);
|
||||
initLang(init);
|
||||
initTheme(init);
|
||||
init.settings = SettingsStore(init.l10n);
|
||||
await init.settings.load(init.isar.appSettingsModels);
|
||||
|
||||
var dispatcher = SchedulerBinding.instance.platformDispatcher;
|
||||
|
||||
dispatcher.onPlatformBrightnessChanged = () {
|
||||
globalUpdate.update();
|
||||
initTheme(init);
|
||||
};
|
||||
|
||||
resetOldTimeTableCache(init.isar);
|
||||
resetOldHomeworkCache(init.isar);
|
||||
|
||||
if (init.tokens.isNotEmpty) {
|
||||
final i = (init.settings.group("profile_settings")["e_kreta_account_picker"]
|
||||
as SettingsKretenAccountPicker)
|
||||
.accountIndex;
|
||||
init.client = KretaClient(
|
||||
(await init.isar.tokenModels.where().findAll())[i], init.isar);
|
||||
|
||||
await WidgetCacheHelper.updateWidgetCache(appStyle, init.client);
|
||||
}
|
||||
|
||||
final dataDir = await getApplicationDocumentsDirectory();
|
||||
var pfpFile = File(p.join(dataDir.path, "profile.webp"));
|
||||
|
||||
if (await pfpFile.exists()) {
|
||||
init.profilePicture = await pfpFile.readAsBytes();
|
||||
}
|
||||
}
|
||||
|
||||
Future<AppInitialization> initializeApp() async {
|
||||
if (initDone) return initData;
|
||||
if (initDone) {
|
||||
await _initData(initData);
|
||||
return initData;
|
||||
}
|
||||
final isar = await initDB();
|
||||
final tokenCount = await isar.tokenModels.count();
|
||||
final tokens = await isar.tokenModels.where().findAll();
|
||||
|
||||
if (kDebugMode) {
|
||||
print('Token count: $tokenCount');
|
||||
print('Token count: ${tokens.length}');
|
||||
}
|
||||
|
||||
var devInfoFetched = false;
|
||||
@@ -190,46 +228,17 @@ Future<AppInitialization> initializeApp() async {
|
||||
isar: isar,
|
||||
devInfo: devInfo,
|
||||
packageInfo: await PackageInfo.fromPlatform(),
|
||||
tokenCount: tokenCount,
|
||||
tokens: tokens,
|
||||
settings: SettingsStore(AppLocalizationsHu()),
|
||||
l10n: AppLocalizationsHu(),
|
||||
);
|
||||
|
||||
await _initData(init);
|
||||
|
||||
init.settingsUpdateNotifier.addListener(() {
|
||||
debugPrint("Settings updated");
|
||||
});
|
||||
|
||||
await init.settings.load(init.isar.appSettingsModels);
|
||||
initLang(init);
|
||||
initTheme(init);
|
||||
init.settings = SettingsStore(init.l10n);
|
||||
await init.settings.load(init.isar.appSettingsModels);
|
||||
|
||||
var dispatcher = SchedulerBinding.instance.platformDispatcher;
|
||||
|
||||
dispatcher.onPlatformBrightnessChanged = () {
|
||||
globalUpdate.update();
|
||||
initTheme(init);
|
||||
};
|
||||
|
||||
resetOldTimeTableCache(isar);
|
||||
resetOldHomeworkCache(isar);
|
||||
|
||||
// TODO: Account selection
|
||||
if (tokenCount > 0) {
|
||||
init.client =
|
||||
KretaClient((await isar.tokenModels.where().findFirst())!, isar);
|
||||
|
||||
await WidgetCacheHelper.updateWidgetCache(appStyle, init.client);
|
||||
}
|
||||
|
||||
final dataDir = await getApplicationDocumentsDirectory();
|
||||
var pfpFile = File(p.join(dataDir.path, "profile.webp"));
|
||||
|
||||
if (await pfpFile.exists()) {
|
||||
init.profilePicture = await pfpFile.readAsBytes();
|
||||
}
|
||||
|
||||
return init;
|
||||
}
|
||||
|
||||
@@ -310,7 +319,7 @@ class InitializationScreen extends StatelessWidget {
|
||||
|
||||
switch (msg["id"]) {
|
||||
case "ping":
|
||||
if (initData.tokenCount > 0) {
|
||||
if (initData.tokens.isNotEmpty) {
|
||||
debugPrint("[Phone -> Watch]: pong");
|
||||
watch.sendMessage({"id": "pong"});
|
||||
navigatorKey.currentState?.push(
|
||||
@@ -324,7 +333,7 @@ class InitializationScreen extends StatelessWidget {
|
||||
});
|
||||
}
|
||||
|
||||
if (snapshot.data!.tokenCount == 0) {
|
||||
if (snapshot.data!.tokens.isEmpty) {
|
||||
screen = LoginScreen(
|
||||
initData,
|
||||
key: ValueKey('loginScreen'),
|
||||
|
||||
@@ -91,6 +91,28 @@ void showExtrasBottomSheet(BuildContext context, AppInitialization data) {
|
||||
],
|
||||
right: [],
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: SettingsScreen(
|
||||
data,
|
||||
data.settings.items
|
||||
.group("profile_settings")))));
|
||||
},
|
||||
child: FirkaCard(
|
||||
left: [
|
||||
Text(data.l10n.s_your_account,
|
||||
style: appStyle.fonts.B_16R.apply(
|
||||
color: appStyle.colors.textPrimary))
|
||||
],
|
||||
right: [],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
||||
@@ -214,7 +214,7 @@ class _DebugScreen extends FirkaState<DebugScreen> {
|
||||
await isar.tokenModels.clear();
|
||||
});
|
||||
|
||||
widget.data.tokenCount = 0;
|
||||
widget.data.tokens = List.empty(growable: true);
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
|
||||
import 'package:firka/helpers/db/models/app_settings_model.dart';
|
||||
import 'package:firka/helpers/image_preloader.dart';
|
||||
import 'package:firka/helpers/ui/firka_button.dart';
|
||||
@@ -14,6 +15,7 @@ import 'package:majesticons_flutter/majesticons_flutter.dart';
|
||||
import '../../../../helpers/firka_bundle.dart';
|
||||
import '../../../../helpers/firka_state.dart';
|
||||
import '../../../../helpers/settings/setting.dart';
|
||||
import '../../widgets/login_webview.dart';
|
||||
|
||||
class SettingsScreen extends StatefulWidget {
|
||||
final AppInitialization data;
|
||||
@@ -494,6 +496,88 @@ class _SettingsScreenState extends FirkaState<SettingsScreen> {
|
||||
|
||||
continue;
|
||||
}
|
||||
if (item is SettingsKretenAccountPicker) {
|
||||
for (var i = 0; i < widget.data.tokens.length; i++) {
|
||||
final token = widget.data.tokens[i];
|
||||
final jwt = JWT.decode(token.idToken!);
|
||||
|
||||
widgets.add(GestureDetector(
|
||||
child: SizedBox(
|
||||
height: 52,
|
||||
child: FirkaCard(
|
||||
left: [
|
||||
Text(
|
||||
jwt.payload["name"],
|
||||
style: appStyle.fonts.B_16R
|
||||
.apply(color: appStyle.colors.textPrimary),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
jwt.payload["role"],
|
||||
style: appStyle.fonts.B_16R
|
||||
.apply(color: appStyle.colors.textTertiary),
|
||||
)
|
||||
],
|
||||
right: [
|
||||
i != item.accountIndex
|
||||
? SizedBox()
|
||||
: Checkbox(
|
||||
value: true,
|
||||
fillColor: WidgetStateProperty.resolveWith<Color>(
|
||||
(Set<WidgetState> states) {
|
||||
return appStyle.colors.secondary;
|
||||
}),
|
||||
onChanged: (_) async {
|
||||
setState(() {
|
||||
// item.activeIndex = i;
|
||||
});
|
||||
|
||||
await widget.data.isar.writeTxn(() async {
|
||||
await item
|
||||
.save(widget.data.isar.appSettingsModels);
|
||||
});
|
||||
debugPrint('Settings saved');
|
||||
})
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () async {
|
||||
if (i != item.accountIndex) {
|
||||
await widget.data.isar.writeTxn(() async {
|
||||
item.accountIndex = i;
|
||||
|
||||
await item.save(widget.data.isar.appSettingsModels);
|
||||
});
|
||||
|
||||
runApp(InitializationScreen());
|
||||
}
|
||||
},
|
||||
));
|
||||
widgets.add(SizedBox(height: 8));
|
||||
}
|
||||
|
||||
widgets.add(GestureDetector(
|
||||
child: FirkaCard(left: [
|
||||
Text(
|
||||
widget.data.l10n.s_acc_add,
|
||||
style: appStyle.fonts.B_16R
|
||||
.apply(color: appStyle.colors.textPrimary),
|
||||
)
|
||||
]),
|
||||
onTap: () {
|
||||
showModalBottomSheet<void>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (BuildContext context) {
|
||||
return LoginWebviewWidget(widget.data,
|
||||
username: widget.data.client.model.studentId.toString(),
|
||||
schoolId: widget.data.client.model.iss!);
|
||||
},
|
||||
);
|
||||
},
|
||||
));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return widgets;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:firka/main.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
import '../../../helpers/api/client/kreta_client.dart';
|
||||
@@ -65,7 +66,7 @@ class _LoginWebviewWidgetState extends FirkaState<LoginWebviewWidget> {
|
||||
});
|
||||
|
||||
widget.data.client = KretaClient(tokenModel, isar);
|
||||
widget.data.tokenCount = await isar.tokenModels.count();
|
||||
widget.data.tokens = await isar.tokenModels.where().findAll();
|
||||
|
||||
if (!mounted) return NavigationDecision.prevent;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user