File-Drive-App-Frontend/lib/controllers/session_controller.dart

100 lines
2.9 KiB
Dart

import 'package:flutter/foundation.dart';
import '../models/user_profile.dart';
import '../services/api_client.dart';
import '../services/token_store.dart';
enum SessionStatus { loading, signedOut, signedIn }
class SessionController extends ChangeNotifier {
SessionController(this.api, this.tokens);
final ApiClient api;
final TokenStore tokens;
SessionStatus status = SessionStatus.loading;
UserProfile? user;
String? organizationId;
OrganizationMembership? get membership {
final matches = user?.approvedMemberships.where(
(item) => item.organization.id == organizationId,
);
return matches == null || matches.isEmpty ? null : matches.first;
}
Future<void> initialize() async {
final minimumSplash = Future<void>.delayed(
const Duration(milliseconds: 1100),
);
final token = await tokens.read();
if (token == null) {
status = SessionStatus.signedOut;
} else {
try {
user = await api.me();
await _selectInitialOrganization();
if (organizationId == null) {
throw StateError('No approved organization membership');
}
status = SessionStatus.signedIn;
} catch (_) {
await tokens.clear();
status = SessionStatus.signedOut;
}
}
await minimumSplash;
notifyListeners();
}
Future<void> login(String username, String password) async {
final result = await api.login(username, password);
await tokens.write(result.token);
user = result.user;
await _selectInitialOrganization();
status = SessionStatus.signedIn;
notifyListeners();
}
Future<String> register(Map<String, dynamic> input) => api.register(input);
Future<void> _selectInitialOrganization() async {
final approved = user?.approvedMemberships ?? const [];
final saved = await tokens.readOrganization();
final selected = approved.where((item) => item.organization.id == saved);
organizationId = selected.isNotEmpty
? selected.first.organization.id
: (approved.isEmpty ? null : approved.first.organization.id);
if (organizationId != null) {
await tokens.writeOrganization(organizationId!);
}
}
Future<void> selectOrganization(String id) async {
if (!(user?.approvedMemberships.any((item) => item.organization.id == id) ??
false)) {
return;
}
organizationId = id;
await tokens.writeOrganization(id);
notifyListeners();
}
Future<void> refreshProfile() async {
user = await api.me();
await _selectInitialOrganization();
notifyListeners();
}
Future<void> logout() async {
await tokens.clear();
await tokens.clearOrganization();
user = null;
organizationId = null;
status = SessionStatus.signedOut;
notifyListeners();
}
Future<void> deleteAccount(String password) async {
await api.deleteAccount(password);
await logout();
}
}