105 lines
3.0 KiB
Dart
105 lines
3.0 KiB
Dart
import 'package:dio/dio.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import 'api_client.dart';
|
|
|
|
final sessionProvider = AsyncNotifierProvider<SessionNotifier, SessionData?>(
|
|
SessionNotifier.new,
|
|
);
|
|
|
|
class SessionData {
|
|
const SessionData({
|
|
required this.userId,
|
|
required this.email,
|
|
this.defaultContextId,
|
|
this.selectedContextId,
|
|
});
|
|
|
|
final String userId;
|
|
final String email;
|
|
final String? defaultContextId;
|
|
final String? selectedContextId;
|
|
|
|
String? get effectiveContextId => selectedContextId ?? defaultContextId;
|
|
}
|
|
|
|
class SessionNotifier extends AsyncNotifier<SessionData?> {
|
|
static const _kContext = 'msn_selected_context_id';
|
|
|
|
@override
|
|
Future<SessionData?> build() async {
|
|
final storage = ref.read(tokenStorageProvider);
|
|
final token = await storage.readToken();
|
|
if (token == null || token.isEmpty) return null;
|
|
|
|
final dio = ref.read(dioProvider);
|
|
try {
|
|
final res = await dio.get<Map<String, dynamic>>('/api/auth/me');
|
|
final id = res.data!['id'] as String;
|
|
final email = res.data!['email'] as String;
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final saved = prefs.getString(_kContext);
|
|
final ctxRes = await dio.get<Map<String, dynamic>>('/api/contexts');
|
|
final list = ctxRes.data!['contexts'] as List<dynamic>? ?? [];
|
|
String? personalId;
|
|
for (final c in list) {
|
|
final m = c as Map<String, dynamic>;
|
|
if (m['kind'] == 'personal') {
|
|
personalId = m['id'] as String;
|
|
break;
|
|
}
|
|
}
|
|
final def = personalId ?? (list.isNotEmpty ? (list.first as Map)['id'] as String : null);
|
|
return SessionData(
|
|
userId: id,
|
|
email: email,
|
|
defaultContextId: def,
|
|
selectedContextId: saved ?? def,
|
|
);
|
|
} on DioException {
|
|
await storage.clear();
|
|
return null;
|
|
}
|
|
}
|
|
|
|
Future<void> applyLogin({
|
|
required String userId,
|
|
required String email,
|
|
String? defaultContextId,
|
|
}) async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final saved = prefs.getString(_kContext);
|
|
state = AsyncData(
|
|
SessionData(
|
|
userId: userId,
|
|
email: email,
|
|
defaultContextId: defaultContextId,
|
|
selectedContextId: saved ?? defaultContextId,
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> setSelectedContext(String contextId) async {
|
|
final cur = state.value;
|
|
if (cur == null) return;
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.setString(_kContext, contextId);
|
|
state = AsyncData(
|
|
SessionData(
|
|
userId: cur.userId,
|
|
email: cur.email,
|
|
defaultContextId: cur.defaultContextId,
|
|
selectedContextId: contextId,
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> logout() async {
|
|
await ref.read(tokenStorageProvider).clear();
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.remove(_kContext);
|
|
state = const AsyncData(null);
|
|
}
|
|
}
|