implemented foreign timetable support for students, teachers, rooms, and classes, including a searchable element picker with favorites support, introduced a capabilities system for feature gating, refactored the timetable UI into a reusable TimetableCalendarView component, and redesigned the chat input field with a unified emoji picker and integrated attachment actions.
This commit is contained in:
+18
-1
@@ -30,6 +30,7 @@ import 'share_intent/share_intent_listener.dart';
|
||||
import 'state/app/modules/account/bloc/account_bloc.dart';
|
||||
import 'state/app/modules/account/bloc/account_state.dart';
|
||||
import 'state/app/modules/breaker/bloc/breaker_bloc.dart';
|
||||
import 'state/app/modules/capabilities/bloc/capabilities_cubit.dart';
|
||||
import 'state/app/modules/chat/bloc/chat_bloc.dart';
|
||||
import 'state/app/modules/chat_list/bloc/chat_list_bloc.dart';
|
||||
import 'state/app/modules/settings/bloc/settings_cubit.dart';
|
||||
@@ -159,6 +160,7 @@ Future<void> main() async {
|
||||
),
|
||||
),
|
||||
BlocProvider<BreakerBloc>(create: (_) => BreakerBloc()),
|
||||
BlocProvider<CapabilitiesCubit>(create: (_) => CapabilitiesCubit()),
|
||||
BlocProvider<ChatListBloc>(create: (_) => ChatListBloc()),
|
||||
BlocProvider<ChatBloc>(
|
||||
create: (ctx) => ChatBloc(chatListBloc: ctx.read<ChatListBloc>()),
|
||||
@@ -193,7 +195,13 @@ class _MainState extends State<Main> {
|
||||
accountBloc.setStatus(
|
||||
value ? AccountStatus.loggedIn : AccountStatus.loggedOut,
|
||||
);
|
||||
if (value) _scheduleSessionValidation(accountBloc);
|
||||
if (value) {
|
||||
_scheduleSessionValidation(accountBloc);
|
||||
// Cold start while already logged in: the account status doesn't
|
||||
// change, so the loggedIn listener below never fires — refresh
|
||||
// capabilities here.
|
||||
unawaited(context.read<CapabilitiesCubit>().load());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -262,6 +270,11 @@ class _MainState extends State<Main> {
|
||||
listenWhen: (previous, current) =>
|
||||
previous.status != current.status,
|
||||
listener: (context, accountState) {
|
||||
// Fresh login (loggedOut -> loggedIn): pull capability flags
|
||||
// for the newly authenticated user.
|
||||
if (accountState.status == AccountStatus.loggedIn) {
|
||||
unawaited(context.read<CapabilitiesCubit>().load());
|
||||
}
|
||||
if (accountState.status != AccountStatus.loggedOut) return;
|
||||
// A pending share would otherwise survive logout and be
|
||||
// re-applied after re-login with file paths the OS may
|
||||
@@ -283,6 +296,7 @@ class _MainState extends State<Main> {
|
||||
final chatListBloc = context.read<ChatListBloc>();
|
||||
final chatBloc = context.read<ChatBloc>();
|
||||
final breakerBloc = context.read<BreakerBloc>();
|
||||
final capabilitiesCubit = context.read<CapabilitiesCubit>();
|
||||
// Defer the actual wipe until after this frame so the
|
||||
// App tree (TimetableBloc/ChatListBloc watchers etc.)
|
||||
// is already torn down. Resetting blocs while App is
|
||||
@@ -295,6 +309,7 @@ class _MainState extends State<Main> {
|
||||
chatListBloc: chatListBloc,
|
||||
chatBloc: chatBloc,
|
||||
breakerBloc: breakerBloc,
|
||||
capabilitiesCubit: capabilitiesCubit,
|
||||
),
|
||||
);
|
||||
});
|
||||
@@ -339,6 +354,7 @@ Future<void> _wipeUserState({
|
||||
required ChatListBloc chatListBloc,
|
||||
required ChatBloc chatBloc,
|
||||
required BreakerBloc breakerBloc,
|
||||
required CapabilitiesCubit capabilitiesCubit,
|
||||
}) async {
|
||||
try {
|
||||
// Reset user-data blocs whose tree is no longer mounted after the
|
||||
@@ -351,6 +367,7 @@ Future<void> _wipeUserState({
|
||||
chatListBloc.reset(),
|
||||
chatBloc.reset(),
|
||||
breakerBloc.reset(),
|
||||
capabilitiesCubit.reset(),
|
||||
]);
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.clear();
|
||||
|
||||
Reference in New Issue
Block a user