♻️ Fab menu overhaul
This commit is contained in:
@@ -1085,8 +1085,8 @@
|
|||||||
"thoughtDefaultTopic": "寻思",
|
"thoughtDefaultTopic": "寻思",
|
||||||
"thoughtAiName": "SN 酱",
|
"thoughtAiName": "SN 酱",
|
||||||
"thoughtUserName": "您",
|
"thoughtUserName": "您",
|
||||||
"thoughtStreamingHint": "Sn-chan 正在思考...",
|
"thoughtStreamingHint": "SN 酱正在思考...",
|
||||||
"thoughtInputHint": "问 sn-chan 任何问题...",
|
"thoughtInputHint": "问 SN 酱任何问题...",
|
||||||
"thoughtNewConversation": "开始新对话",
|
"thoughtNewConversation": "开始新对话",
|
||||||
"thoughtParseError": "解析 AI 响应失败",
|
"thoughtParseError": "解析 AI 响应失败",
|
||||||
"aiThought": "寻思",
|
"aiThought": "寻思",
|
||||||
|
|||||||
@@ -10,12 +10,13 @@ import 'package:island/pods/chat/call.dart';
|
|||||||
import 'package:island/pods/chat/chat_summary.dart';
|
import 'package:island/pods/chat/chat_summary.dart';
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
import 'package:island/screens/realm/realms.dart';
|
import 'package:island/screens/realm/realms.dart';
|
||||||
|
import 'package:island/services/event_bus.dart';
|
||||||
import 'package:island/services/responsive.dart';
|
import 'package:island/services/responsive.dart';
|
||||||
import 'package:island/widgets/account/account_picker.dart';
|
|
||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
import 'package:island/widgets/content/cloud_files.dart';
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
import 'package:island/widgets/content/sheet.dart';
|
import 'package:island/widgets/content/sheet.dart';
|
||||||
|
import 'package:island/widgets/navigation/fab_menu.dart';
|
||||||
import 'package:island/widgets/response.dart';
|
import 'package:island/widgets/response.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:relative_time/relative_time.dart';
|
import 'package:relative_time/relative_time.dart';
|
||||||
@@ -333,28 +334,30 @@ class ChatListScreen extends HookConsumerWidget {
|
|||||||
tabController.addListener(() {
|
tabController.addListener(() {
|
||||||
selectedTab.value = tabController.index;
|
selectedTab.value = tabController.index;
|
||||||
});
|
});
|
||||||
return null;
|
|
||||||
|
// Listen for chat rooms refresh events
|
||||||
|
final subscription = eventBus.on<ChatRoomsRefreshEvent>().listen((event) {
|
||||||
|
ref.invalidate(chatroomsJoinedProvider);
|
||||||
|
});
|
||||||
|
|
||||||
|
return () {
|
||||||
|
subscription.cancel();
|
||||||
|
};
|
||||||
}, [tabController]);
|
}, [tabController]);
|
||||||
|
|
||||||
Future<void> createDirectMessage() async {
|
useEffect(() {
|
||||||
final result = await showModalBottomSheet(
|
// Set FAB type to chat
|
||||||
context: context,
|
final fabMenuNotifier = ref.read(fabMenuTypeProvider.notifier);
|
||||||
useRootNavigator: true,
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
isScrollControlled: true,
|
fabMenuNotifier.state = FabMenuType.chat;
|
||||||
builder: (context) => const AccountPickerSheet(),
|
});
|
||||||
);
|
return () {
|
||||||
if (result == null) return;
|
// Clean up: reset FAB type to main
|
||||||
final client = ref.read(apiClientProvider);
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
try {
|
fabMenuNotifier.state = FabMenuType.main;
|
||||||
await client.post(
|
});
|
||||||
'/sphere/chat/direct',
|
};
|
||||||
data: {'related_user_id': result.id},
|
}, []);
|
||||||
);
|
|
||||||
ref.invalidate(chatroomsJoinedProvider);
|
|
||||||
} catch (err) {
|
|
||||||
showErrorAlert(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isAside) {
|
if (isAside) {
|
||||||
return Card(
|
return Card(
|
||||||
@@ -491,43 +494,7 @@ class ChatListScreen extends HookConsumerWidget {
|
|||||||
const Gap(8),
|
const Gap(8),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: const FabMenu(),
|
||||||
onPressed: () {
|
|
||||||
showModalBottomSheet(
|
|
||||||
context: context,
|
|
||||||
useRootNavigator: true,
|
|
||||||
builder:
|
|
||||||
(context) => Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
children: [
|
|
||||||
ListTile(
|
|
||||||
title: const Text('createChatRoom').tr(),
|
|
||||||
leading: const Icon(Symbols.add),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.pop(context);
|
|
||||||
context.pushNamed('chatNew').then((value) {
|
|
||||||
if (value != null) {
|
|
||||||
ref.invalidate(chatroomsJoinedProvider);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: const Text('createDirectMessage').tr(),
|
|
||||||
leading: const Icon(Symbols.person),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.pop(context);
|
|
||||||
createDirectMessage();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Gap(MediaQuery.of(context).padding.bottom + 16),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: const Icon(Symbols.add),
|
|
||||||
),
|
|
||||||
body: ChatListBodyWidget(
|
body: ChatListBodyWidget(
|
||||||
isFloating: false,
|
isFloating: false,
|
||||||
tabController: tabController,
|
tabController: tabController,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
@@ -9,6 +10,7 @@ import 'package:island/widgets/alert.dart';
|
|||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
import 'package:island/widgets/content/cloud_files.dart';
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
import 'package:island/widgets/content/sheet.dart';
|
import 'package:island/widgets/content/sheet.dart';
|
||||||
|
import 'package:island/widgets/navigation/fab_menu.dart';
|
||||||
import 'package:island/widgets/response.dart';
|
import 'package:island/widgets/response.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
@@ -41,6 +43,20 @@ class RealmListScreen extends HookConsumerWidget {
|
|||||||
final realms = ref.watch(realmsJoinedProvider);
|
final realms = ref.watch(realmsJoinedProvider);
|
||||||
final realmInvites = ref.watch(realmInvitesProvider);
|
final realmInvites = ref.watch(realmInvitesProvider);
|
||||||
|
|
||||||
|
useEffect(() {
|
||||||
|
// Set FAB type to realm
|
||||||
|
final fabMenuNotifier = ref.read(fabMenuTypeProvider.notifier);
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
fabMenuNotifier.state = FabMenuType.realm;
|
||||||
|
});
|
||||||
|
return () {
|
||||||
|
// Clean up: reset FAB type to main
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
fabMenuNotifier.state = FabMenuType.main;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
isNoBackground: false,
|
isNoBackground: false,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
@@ -78,17 +94,7 @@ class RealmListScreen extends HookConsumerWidget {
|
|||||||
const Gap(8),
|
const Gap(8),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: const FabMenu(),
|
||||||
heroTag: const Key("realms-page-fab"),
|
|
||||||
child: const Icon(Symbols.add),
|
|
||||||
onPressed: () {
|
|
||||||
context.pushNamed('realmNew').then((value) {
|
|
||||||
if (value != null) {
|
|
||||||
ref.invalidate(realmsJoinedProvider);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
body: ExtendedRefreshIndicator(
|
body: ExtendedRefreshIndicator(
|
||||||
child: realms.when(
|
child: realms.when(
|
||||||
data:
|
data:
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ import 'dart:ui';
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:gap/gap.dart';
|
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:island/screens/notification.dart';
|
import 'package:island/screens/notification.dart';
|
||||||
import 'package:island/services/responsive.dart';
|
import 'package:island/services/responsive.dart';
|
||||||
import 'package:island/widgets/navigation/conditional_bottom_nav.dart';
|
import 'package:island/widgets/navigation/conditional_bottom_nav.dart';
|
||||||
import 'package:island/widgets/post/compose_dialog.dart';
|
import 'package:island/widgets/navigation/fab_menu.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
final currentRouteProvider = StateProvider<String?>((ref) => null);
|
final currentRouteProvider = StateProvider<String?>((ref) => null);
|
||||||
|
|
||||||
@@ -120,6 +120,10 @@ class TabsScreen extends HookConsumerWidget {
|
|||||||
.toList(),
|
.toList(),
|
||||||
selectedIndex: currentIndex,
|
selectedIndex: currentIndex,
|
||||||
onDestinationSelected: onDestinationSelected,
|
onDestinationSelected: onDestinationSelected,
|
||||||
|
trailingAtBottom: true,
|
||||||
|
trailing: const FabMenu(
|
||||||
|
elevation: 0,
|
||||||
|
).padding(bottom: MediaQuery.of(context).padding.bottom + 16),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
@@ -145,78 +149,9 @@ class TabsScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
child: child ?? const SizedBox.shrink(),
|
child: child ?? const SizedBox.shrink(),
|
||||||
),
|
),
|
||||||
floatingActionButton:
|
floatingActionButton: shouldShowFab ? const FabMenu() : null,
|
||||||
shouldShowFab
|
|
||||||
? FloatingActionButton(
|
|
||||||
child: const Icon(Symbols.menu),
|
|
||||||
onPressed: () {
|
|
||||||
showModalBottomSheet(
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
const Gap(24),
|
|
||||||
ListTile(
|
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 24,
|
|
||||||
),
|
|
||||||
leading: const Icon(Symbols.post_add_rounded),
|
|
||||||
title: Text('postCompose'.tr()),
|
|
||||||
onTap: () async {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
await PostComposeDialog.show(context);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 24,
|
|
||||||
),
|
|
||||||
leading: const Icon(Symbols.bubble_chart),
|
|
||||||
title: Text('aiThoughtTitle'.tr()),
|
|
||||||
onTap: () async {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
context.pushNamed('thought');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Consumer(
|
|
||||||
builder: (context, ref, _) {
|
|
||||||
final notificationCount = ref.watch(
|
|
||||||
notificationUnreadCountNotifierProvider,
|
|
||||||
);
|
|
||||||
return ListTile(
|
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 24,
|
|
||||||
),
|
|
||||||
leading: const Icon(Symbols.notifications),
|
|
||||||
trailing: Badge(
|
|
||||||
label: Text(notificationCount.toString()),
|
|
||||||
isLabelVisible: notificationCount.value! > 0,
|
|
||||||
),
|
|
||||||
title: Text('notifications'.tr()),
|
|
||||||
onTap: () async {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
showModalBottomSheet(
|
|
||||||
context: context,
|
|
||||||
isScrollControlled: true,
|
|
||||||
useRootNavigator: true,
|
|
||||||
builder:
|
|
||||||
(context) => const NotificationSheet(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Gap(MediaQuery.of(context).padding.bottom + 16),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
floatingActionButtonLocation:
|
floatingActionButtonLocation:
|
||||||
shouldShowFab ? TabbedFabLocation(context) : null,
|
shouldShowFab ? _DockedFabLocation(context) : null,
|
||||||
bottomNavigationBar: ConditionalBottomNav(
|
bottomNavigationBar: ConditionalBottomNav(
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
@@ -269,10 +204,10 @@ class TabsScreen extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TabbedFabLocation extends FloatingActionButtonLocation {
|
class _DockedFabLocation extends FloatingActionButtonLocation {
|
||||||
final BuildContext context;
|
final BuildContext context;
|
||||||
|
|
||||||
const TabbedFabLocation(this.context);
|
const _DockedFabLocation(this.context);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) {
|
Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) {
|
||||||
|
|||||||
@@ -11,3 +11,8 @@ class PostCreatedEvent {
|
|||||||
|
|
||||||
const PostCreatedEvent({this.postId, this.title, this.content});
|
const PostCreatedEvent({this.postId, this.title, this.content});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Event fired when chat rooms need to be refreshed
|
||||||
|
class ChatRoomsRefreshEvent {
|
||||||
|
const ChatRoomsRefreshEvent();
|
||||||
|
}
|
||||||
|
|||||||
192
lib/widgets/navigation/fab_menu.dart
Normal file
192
lib/widgets/navigation/fab_menu.dart
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:island/screens/notification.dart';
|
||||||
|
import 'package:island/services/event_bus.dart';
|
||||||
|
import 'package:island/widgets/account/account_picker.dart';
|
||||||
|
import 'package:island/widgets/alert.dart';
|
||||||
|
import 'package:island/widgets/post/compose_dialog.dart';
|
||||||
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
|
||||||
|
enum FabMenuType { main, chat, realm }
|
||||||
|
|
||||||
|
/// Global state provider for FAB menu type
|
||||||
|
final fabMenuTypeProvider = StateProvider<FabMenuType>(
|
||||||
|
(ref) => FabMenuType.main,
|
||||||
|
);
|
||||||
|
|
||||||
|
class FabMenu extends HookConsumerWidget {
|
||||||
|
final double? elevation;
|
||||||
|
const FabMenu({super.key, this.elevation});
|
||||||
|
|
||||||
|
Future<void> _createDirectMessage(BuildContext context, WidgetRef ref) async {
|
||||||
|
final result = await showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
useRootNavigator: true,
|
||||||
|
isScrollControlled: true,
|
||||||
|
builder: (context) => const AccountPickerSheet(),
|
||||||
|
);
|
||||||
|
if (result == null) return;
|
||||||
|
final client = ref.read(apiClientProvider);
|
||||||
|
try {
|
||||||
|
await client.post(
|
||||||
|
'/sphere/chat/direct',
|
||||||
|
data: {'related_user_id': result.id},
|
||||||
|
);
|
||||||
|
eventBus.fire(const ChatRoomsRefreshEvent());
|
||||||
|
} catch (err) {
|
||||||
|
showErrorAlert(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final fabType = ref.watch(fabMenuTypeProvider);
|
||||||
|
|
||||||
|
late final IconData icon;
|
||||||
|
late final bool useRootNavigator;
|
||||||
|
late final Widget menuContent;
|
||||||
|
|
||||||
|
final commonEntires = <Widget>[
|
||||||
|
ListTile(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
|
leading: const Icon(Symbols.bubble_chart),
|
||||||
|
title: Text('aiThoughtTitle').tr(),
|
||||||
|
onTap: () async {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
context.pushNamed('thought');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Consumer(
|
||||||
|
builder: (context, ref, _) {
|
||||||
|
final notificationCount = ref.watch(
|
||||||
|
notificationUnreadCountNotifierProvider,
|
||||||
|
);
|
||||||
|
return ListTile(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
|
leading: const Icon(Symbols.notifications),
|
||||||
|
trailing: Badge(
|
||||||
|
label: Text(notificationCount.toString()),
|
||||||
|
isLabelVisible: notificationCount.value! > 0,
|
||||||
|
),
|
||||||
|
title: Text('notifications').tr(),
|
||||||
|
onTap: () async {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
isScrollControlled: true,
|
||||||
|
useRootNavigator: true,
|
||||||
|
builder: (context) => const NotificationSheet(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
switch (fabType) {
|
||||||
|
case FabMenuType.chat:
|
||||||
|
icon = Symbols.chat_add_on;
|
||||||
|
useRootNavigator = true;
|
||||||
|
menuContent = Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
const Gap(24),
|
||||||
|
ListTile(
|
||||||
|
title: const Text('createChatRoom').tr(),
|
||||||
|
leading: const Icon(Symbols.add),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
context.pushNamed('chatNew').then((value) {
|
||||||
|
if (value != null) {
|
||||||
|
eventBus.fire(const ChatRoomsRefreshEvent());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: const Text('createDirectMessage').tr(),
|
||||||
|
leading: const Icon(Symbols.person),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
_createDirectMessage(context, ref);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
...commonEntires,
|
||||||
|
Gap(MediaQuery.of(context).padding.bottom + 16),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FabMenuType.realm:
|
||||||
|
icon = Symbols.group_add;
|
||||||
|
useRootNavigator = false;
|
||||||
|
menuContent = Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
const Gap(24),
|
||||||
|
ListTile(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
|
leading: const Icon(Symbols.group_add),
|
||||||
|
title: Text('createRealm').tr(),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
context.pushNamed('realmNew').then((value) {
|
||||||
|
if (value != null) {
|
||||||
|
// Fire realm refresh event if needed
|
||||||
|
// eventBus.fire(const RealmsRefreshEvent());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
...commonEntires,
|
||||||
|
Gap(MediaQuery.of(context).padding.bottom + 16),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FabMenuType.main:
|
||||||
|
icon = Symbols.menu;
|
||||||
|
useRootNavigator = false;
|
||||||
|
menuContent = Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
const Gap(24),
|
||||||
|
ListTile(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
|
leading: const Icon(Symbols.post_add_rounded),
|
||||||
|
title: Text('postCompose').tr(),
|
||||||
|
onTap: () async {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
await PostComposeDialog.show(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
...commonEntires,
|
||||||
|
Gap(MediaQuery.of(context).padding.bottom + 16),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FloatingActionButton(
|
||||||
|
elevation: elevation,
|
||||||
|
child: Icon(icon),
|
||||||
|
onPressed: () {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
useRootNavigator: useRootNavigator,
|
||||||
|
builder: (BuildContext context) => menuContent,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user