folder restructuring
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
|
||||
|
||||
import '../api/marianumcloud/talk/room/getRoomResponse.dart';
|
||||
import '../main.dart';
|
||||
import '../model/account_data.dart';
|
||||
import '../state/app/modules/app_modules.dart';
|
||||
import '../state/app/modules/chatList/bloc/chat_list_bloc.dart';
|
||||
import '../state/app/modules/chat/bloc/chat_bloc.dart';
|
||||
import '../state/app/modules/marianumMessage/bloc/marianum_message_state.dart';
|
||||
import '../view/pages/files/files.dart';
|
||||
import '../view/pages/marianum_message/marianum_message_view.dart';
|
||||
import '../view/pages/more/feedback/feedback_dialog.dart';
|
||||
import '../view/pages/more/roomplan/roomplan.dart';
|
||||
import '../view/pages/more/share/qr_share_view.dart';
|
||||
import '../view/pages/talk/chat_view.dart';
|
||||
import '../view/pages/talk/details/message_reactions.dart';
|
||||
import '../view/pages/talk/talk_navigator.dart';
|
||||
import '../view/pages/timetable/custom_events/custom_events_view.dart';
|
||||
import '../view/pages/settings/settings.dart';
|
||||
import '../widget/debug/cache_view.dart';
|
||||
import '../widget/file_viewer.dart';
|
||||
import '../widget/user_avatar.dart';
|
||||
|
||||
/// Single entry point for full-page navigations across the app.
|
||||
///
|
||||
/// Every full-page push in modules should go through one of these methods.
|
||||
/// Dialogs (`showDialog`), bottom sheets (`showStickyFlexibleBottomSheet`,
|
||||
/// `showAppointmentBottomSheet`), and `Navigator.pop` for closing those
|
||||
/// remain unchanged and live at the call sites.
|
||||
class AppRoutes {
|
||||
AppRoutes._();
|
||||
|
||||
/// Token of a chat that should be auto-opened in the Talk tab once
|
||||
/// the chat list view picks it up. Set by [openChatByToken] (e.g. from
|
||||
/// a tapped notification) and consumed by the `ChatList` widget.
|
||||
static final ValueNotifier<String?> pendingChatToken = ValueNotifier(null);
|
||||
|
||||
// -- Files --------------------------------------------------------------
|
||||
|
||||
static void openFolder(BuildContext context, List<String> path) {
|
||||
pushScreen(context, withNavBar: false, screen: Files(path: path));
|
||||
}
|
||||
|
||||
static void openFileViewer(BuildContext context, String localPath, {bool openExternal = false}) {
|
||||
pushScreen(
|
||||
context,
|
||||
withNavBar: false,
|
||||
screen: FileViewer(path: localPath, openExternal: openExternal),
|
||||
);
|
||||
}
|
||||
|
||||
// -- Timetable ----------------------------------------------------------
|
||||
|
||||
static void openCustomEvents(BuildContext context) {
|
||||
pushScreen(context, withNavBar: false, screen: const CustomEventsView());
|
||||
}
|
||||
|
||||
// -- Marianum Message ---------------------------------------------------
|
||||
|
||||
static void openMarianumMessage(BuildContext context, String basePath, MarianumMessage message) {
|
||||
pushScreen(
|
||||
context,
|
||||
withNavBar: false,
|
||||
screen: MessageView(basePath: basePath, message: message),
|
||||
);
|
||||
}
|
||||
|
||||
// -- Sharing / Settings / Feedback / DevTools ---------------------------
|
||||
|
||||
static void openQrShare(BuildContext context) {
|
||||
pushScreen(context, withNavBar: false, screen: const QrShareView());
|
||||
}
|
||||
|
||||
static void openSettings(BuildContext context) {
|
||||
pushScreen(context, withNavBar: false, screen: const Settings());
|
||||
}
|
||||
|
||||
static void openFeedback(BuildContext context) {
|
||||
pushScreen(context, withNavBar: false, screen: const FeedbackDialog());
|
||||
}
|
||||
|
||||
static void openCacheView(BuildContext context) {
|
||||
pushScreen(context, withNavBar: false, screen: const CacheView());
|
||||
}
|
||||
|
||||
static void openRoomplan(BuildContext context) {
|
||||
pushScreen(context, withNavBar: false, screen: const Roomplan());
|
||||
}
|
||||
|
||||
// -- Talk ---------------------------------------------------------------
|
||||
|
||||
static void openMessageReactions(BuildContext context, String token, int messageId) {
|
||||
pushScreen(
|
||||
context,
|
||||
withNavBar: false,
|
||||
screen: MessageReactions(token: token, messageId: messageId),
|
||||
);
|
||||
}
|
||||
|
||||
/// Opens a chat from a known [GetRoomResponseObject]. Delegates to
|
||||
/// [TalkNavigator.pushSplitView] so tablet split-view behaviour stays intact.
|
||||
static void openChatView(
|
||||
BuildContext context, {
|
||||
required GetRoomResponseObject room,
|
||||
required String selfId,
|
||||
required UserAvatar avatar,
|
||||
bool overrideToSingleSubScreen = true,
|
||||
}) {
|
||||
TalkNavigator.pushSplitView(
|
||||
context,
|
||||
ChatView(room: room, selfId: selfId, avatar: avatar),
|
||||
overrideToSingleSubScreen: overrideToSingleSubScreen,
|
||||
);
|
||||
context.read<ChatBloc>().setToken(room.token);
|
||||
}
|
||||
|
||||
/// Schedules a chat to be opened in the Talk tab. Use this when only the
|
||||
/// token is known (e.g. from a tapped notification) — the actual push
|
||||
/// happens inside the `ChatList` widget once the room is available.
|
||||
static void openChatByToken(BuildContext context, String token) {
|
||||
pendingChatToken.value = token;
|
||||
goToTalkTab(context);
|
||||
try {
|
||||
context.read<ChatListBloc>().refresh();
|
||||
} catch (e) {
|
||||
if (kDebugMode) debugPrint('openChatByToken: ChatListBloc refresh failed: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves a pending chat token (set via [openChatByToken]) using the
|
||||
/// [ChatListBloc]'s current rooms and the active [AccountData] credentials.
|
||||
/// Returns `null` if the token cannot yet be matched (e.g. the room is
|
||||
/// still being loaded). Callers should keep listening to [pendingChatToken]
|
||||
/// and the bloc state and retry when either changes.
|
||||
static ResolvedPendingChat? resolvePendingChat(BuildContext context) {
|
||||
final token = pendingChatToken.value;
|
||||
if (token == null) return null;
|
||||
if (!AccountData().isPopulated()) return null;
|
||||
|
||||
final rooms = context.read<ChatListBloc>().state.data?.rooms;
|
||||
final room = _findRoomByToken(rooms, token);
|
||||
if (room == null) return null;
|
||||
|
||||
final isGroup = room.type != GetRoomResponseObjectConversationType.oneToOne;
|
||||
final avatar = UserAvatar(id: isGroup ? room.token : room.name, isGroup: isGroup);
|
||||
return ResolvedPendingChat(
|
||||
room: room,
|
||||
selfId: AccountData().getUsername(),
|
||||
avatar: avatar,
|
||||
);
|
||||
}
|
||||
|
||||
static GetRoomResponseObject? _findRoomByToken(GetRoomResponse? rooms, String token) {
|
||||
if (rooms == null) return null;
|
||||
for (final room in rooms.data) {
|
||||
if (room.token == token) return room;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// -- Module / Tab navigation -------------------------------------------
|
||||
|
||||
/// Opens an [AppModule]'s root view as a full screen push (used by the
|
||||
/// "Mehr" tab list). Modules that live in the bottom bar are reached via
|
||||
/// [goToTab] instead.
|
||||
static void openModule(BuildContext context, AppModule module) {
|
||||
pushScreen(context, withNavBar: false, screen: module.create());
|
||||
}
|
||||
|
||||
/// Switches the bottom navigation to the given [module] if it is currently
|
||||
/// in the bottom bar. Returns `true` if the jump happened.
|
||||
static bool goToTab(BuildContext context, Modules module) {
|
||||
final index = AppModule.getBottomBarModules(context)
|
||||
.map((e) => e.module)
|
||||
.toList()
|
||||
.indexOf(module);
|
||||
if (index == -1) return false;
|
||||
Main.bottomNavigator.jumpToTab(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Convenience wrapper for the Talk tab — preserved for the notification
|
||||
/// handler API which only knows about Talk.
|
||||
static void goToTalkTab(BuildContext context) {
|
||||
goToTab(context, Modules.talk);
|
||||
}
|
||||
}
|
||||
|
||||
class ResolvedPendingChat {
|
||||
final GetRoomResponseObject room;
|
||||
final String selfId;
|
||||
final UserAvatar avatar;
|
||||
|
||||
const ResolvedPendingChat({
|
||||
required this.room,
|
||||
required this.selfId,
|
||||
required this.avatar,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user