mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2024-11-23 20:49:26 +01:00
Merge branch 'krille/nicer-modal-bottom-sheet' into 'main'
style: New modal bottom sheets See merge request famedly/fluffychat!1071
This commit is contained in:
commit
8f9e1a9142
@ -61,12 +61,14 @@ void main() {
|
|||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
await tester.scrollUntilVisible(
|
await tester.scrollUntilVisible(
|
||||||
find.text('Chats'),
|
find.text('Chats').first,
|
||||||
500,
|
500,
|
||||||
scrollable: find.descendant(
|
scrollable: find
|
||||||
of: find.byType(ChatListViewBody),
|
.descendant(
|
||||||
matching: find.byType(Scrollable),
|
of: find.byType(ChatListViewBody),
|
||||||
),
|
matching: find.byType(Scrollable),
|
||||||
|
)
|
||||||
|
.first,
|
||||||
);
|
);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
await tester.tap(find.text('Chats'));
|
await tester.tap(find.text('Chats'));
|
||||||
@ -77,10 +79,12 @@ void main() {
|
|||||||
await tester.scrollUntilVisible(
|
await tester.scrollUntilVisible(
|
||||||
find.text(Users.user2.name).first,
|
find.text(Users.user2.name).first,
|
||||||
500,
|
500,
|
||||||
scrollable: find.descendant(
|
scrollable: find
|
||||||
of: find.byType(ChatListViewBody),
|
.descendant(
|
||||||
matching: find.byType(Scrollable),
|
of: find.byType(ChatListViewBody),
|
||||||
),
|
matching: find.byType(Scrollable),
|
||||||
|
)
|
||||||
|
.first,
|
||||||
);
|
);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
await tester.tap(find.text(Users.user2.name).first);
|
await tester.tap(find.text(Users.user2.name).first);
|
||||||
|
@ -22,6 +22,7 @@ import 'package:vrouter/vrouter.dart';
|
|||||||
import 'package:fluffychat/pages/chat/chat_view.dart';
|
import 'package:fluffychat/pages/chat/chat_view.dart';
|
||||||
import 'package:fluffychat/pages/chat/event_info_dialog.dart';
|
import 'package:fluffychat/pages/chat/event_info_dialog.dart';
|
||||||
import 'package:fluffychat/pages/chat/recording_dialog.dart';
|
import 'package:fluffychat/pages/chat/recording_dialog.dart';
|
||||||
|
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/ios_badge_client_extension.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/ios_badge_client_extension.dart';
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||||
@ -422,9 +423,8 @@ class ChatController extends State<Chat> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sendStickerAction() async {
|
void sendStickerAction() async {
|
||||||
final sticker = await showModalBottomSheet<ImagePackImageContent>(
|
final sticker = await showAdaptiveBottomSheet<ImagePackImageContent>(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: false,
|
|
||||||
builder: (c) => StickerPickerDialog(room: room!),
|
builder: (c) => StickerPickerDialog(room: room!),
|
||||||
);
|
);
|
||||||
if (sticker == null) return;
|
if (sticker == null) return;
|
||||||
|
@ -5,6 +5,7 @@ import 'package:vrouter/vrouter.dart';
|
|||||||
|
|
||||||
import 'package:fluffychat/pages/chat/chat.dart';
|
import 'package:fluffychat/pages/chat/chat.dart';
|
||||||
import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart';
|
import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart';
|
||||||
|
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||||
import 'package:fluffychat/widgets/avatar.dart';
|
import 'package:fluffychat/widgets/avatar.dart';
|
||||||
|
|
||||||
@ -26,7 +27,7 @@ class ChatAppBarTitle extends StatelessWidget {
|
|||||||
splashColor: Colors.transparent,
|
splashColor: Colors.transparent,
|
||||||
highlightColor: Colors.transparent,
|
highlightColor: Colors.transparent,
|
||||||
onTap: directChatMatrixID != null
|
onTap: directChatMatrixID != null
|
||||||
? () => showModalBottomSheet(
|
? () => showAdaptiveBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (c) => UserBottomSheet(
|
builder: (c) => UserBottomSheet(
|
||||||
user: room
|
user: room
|
||||||
|
@ -10,6 +10,7 @@ import 'package:fluffychat/pages/chat/events/message.dart';
|
|||||||
import 'package:fluffychat/pages/chat/seen_by_row.dart';
|
import 'package:fluffychat/pages/chat/seen_by_row.dart';
|
||||||
import 'package:fluffychat/pages/chat/typing_indicators.dart';
|
import 'package:fluffychat/pages/chat/typing_indicators.dart';
|
||||||
import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart';
|
import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart';
|
||||||
|
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/filtered_timeline_extension.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/filtered_timeline_extension.dart';
|
||||||
import 'package:fluffychat/utils/platform_infos.dart';
|
import 'package:fluffychat/utils/platform_infos.dart';
|
||||||
|
|
||||||
@ -89,7 +90,7 @@ class ChatEventList extends StatelessWidget {
|
|||||||
onSwipe: (direction) =>
|
onSwipe: (direction) =>
|
||||||
controller.replyAction(replyTo: event),
|
controller.replyAction(replyTo: event),
|
||||||
onInfoTab: controller.showEventInfo,
|
onInfoTab: controller.showEventInfo,
|
||||||
onAvatarTab: (Event event) => showModalBottomSheet(
|
onAvatarTab: (Event event) => showAdaptiveBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (c) => UserBottomSheet(
|
builder: (c) => UserBottomSheet(
|
||||||
user: event.senderFromMemoryOrFallback,
|
user: event.senderFromMemoryOrFallback,
|
||||||
|
@ -6,11 +6,12 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
|
|||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.dart';
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
|
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||||
import 'package:fluffychat/utils/date_time_extension.dart';
|
import 'package:fluffychat/utils/date_time_extension.dart';
|
||||||
import 'package:fluffychat/widgets/avatar.dart';
|
import 'package:fluffychat/widgets/avatar.dart';
|
||||||
|
|
||||||
extension EventInfoDialogExtension on Event {
|
extension EventInfoDialogExtension on Event {
|
||||||
void showInfoDialog(BuildContext context) => showModalBottomSheet(
|
void showInfoDialog(BuildContext context) => showAdaptiveBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
EventInfoDialog(l10n: L10n.of(context)!, event: this),
|
EventInfoDialog(l10n: L10n.of(context)!, event: this),
|
||||||
|
@ -5,6 +5,7 @@ import 'package:matrix/matrix.dart';
|
|||||||
import 'package:matrix_link_text/link_text.dart';
|
import 'package:matrix_link_text/link_text.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/pages/chat/events/video_player.dart';
|
import 'package:fluffychat/pages/chat/events/video_player.dart';
|
||||||
|
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||||
import 'package:fluffychat/utils/date_time_extension.dart';
|
import 'package:fluffychat/utils/date_time_extension.dart';
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||||
import 'package:fluffychat/widgets/avatar.dart';
|
import 'package:fluffychat/widgets/avatar.dart';
|
||||||
@ -52,7 +53,7 @@ class MessageContent extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
event.requestKey();
|
event.requestKey();
|
||||||
final sender = event.senderFromMemoryOrFallback;
|
final sender = event.senderFromMemoryOrFallback;
|
||||||
await showModalBottomSheet(
|
await showAdaptiveBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => Scaffold(
|
builder: (context) => Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
|
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||||
import '../../widgets/avatar.dart';
|
import '../../widgets/avatar.dart';
|
||||||
import '../user_bottom_sheet/user_bottom_sheet.dart';
|
import '../user_bottom_sheet/user_bottom_sheet.dart';
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ class ParticipantListItem extends StatelessWidget {
|
|||||||
return Opacity(
|
return Opacity(
|
||||||
opacity: user.membership == Membership.join ? 1 : 0.5,
|
opacity: user.membership == Membership.join ? 1 : 0.5,
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
onTap: () => showModalBottomSheet(
|
onTap: () => showAdaptiveBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (c) => UserBottomSheet(
|
builder: (c) => UserBottomSheet(
|
||||||
user: user,
|
user: user,
|
||||||
|
@ -9,6 +9,7 @@ import 'package:fluffychat/pages/chat_list/chat_list_item.dart';
|
|||||||
import 'package:fluffychat/pages/chat_list/search_title.dart';
|
import 'package:fluffychat/pages/chat_list/search_title.dart';
|
||||||
import 'package:fluffychat/pages/chat_list/space_view.dart';
|
import 'package:fluffychat/pages/chat_list/space_view.dart';
|
||||||
import 'package:fluffychat/pages/chat_list/stories_header.dart';
|
import 'package:fluffychat/pages/chat_list/stories_header.dart';
|
||||||
|
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/client_stories_extension.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/client_stories_extension.dart';
|
||||||
import 'package:fluffychat/utils/stream_extension.dart';
|
import 'package:fluffychat/utils/stream_extension.dart';
|
||||||
import 'package:fluffychat/widgets/avatar.dart';
|
import 'package:fluffychat/widgets/avatar.dart';
|
||||||
@ -101,7 +102,7 @@ class ChatListViewBody extends StatelessWidget {
|
|||||||
L10n.of(context)!.group,
|
L10n.of(context)!.group,
|
||||||
avatar:
|
avatar:
|
||||||
roomSearchResult.chunk[i].avatarUrl,
|
roomSearchResult.chunk[i].avatarUrl,
|
||||||
onPressed: () => showModalBottomSheet(
|
onPressed: () => showAdaptiveBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (c) => PublicRoomBottomSheet(
|
builder: (c) => PublicRoomBottomSheet(
|
||||||
roomAlias: roomSearchResult
|
roomAlias: roomSearchResult
|
||||||
@ -140,7 +141,7 @@ class ChatListViewBody extends StatelessWidget {
|
|||||||
L10n.of(context)!.unknownDevice,
|
L10n.of(context)!.unknownDevice,
|
||||||
avatar:
|
avatar:
|
||||||
userSearchResult.results[i].avatarUrl,
|
userSearchResult.results[i].avatarUrl,
|
||||||
onPressed: () => showModalBottomSheet(
|
onPressed: () => showAdaptiveBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (c) => ProfileBottomSheet(
|
builder: (c) => ProfileBottomSheet(
|
||||||
userId: userSearchResult
|
userId: userSearchResult
|
||||||
|
@ -15,6 +15,7 @@ import 'package:vrouter/vrouter.dart';
|
|||||||
import 'package:fluffychat/config/app_config.dart';
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
import 'package:fluffychat/pages/homeserver_picker/homeserver_bottom_sheet.dart';
|
import 'package:fluffychat/pages/homeserver_picker/homeserver_bottom_sheet.dart';
|
||||||
import 'package:fluffychat/pages/homeserver_picker/homeserver_picker_view.dart';
|
import 'package:fluffychat/pages/homeserver_picker/homeserver_picker_view.dart';
|
||||||
|
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
import '../../utils/localized_exception_extension.dart';
|
import '../../utils/localized_exception_extension.dart';
|
||||||
|
|
||||||
@ -71,7 +72,8 @@ class HomeserverPickerController extends State<HomeserverPicker> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showServerInfo(HomeserverBenchmarkResult server) => showModalBottomSheet(
|
void showServerInfo(HomeserverBenchmarkResult server) =>
|
||||||
|
showAdaptiveBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (_) => HomeserverBottomSheet(
|
builder: (_) => HomeserverBottomSheet(
|
||||||
homeserver: server,
|
homeserver: server,
|
||||||
|
@ -10,13 +10,13 @@ import 'package:future_loading_dialog/future_loading_dialog.dart';
|
|||||||
import 'package:matrix/encryption.dart';
|
import 'package:matrix/encryption.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
|
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||||
import 'package:fluffychat/widgets/avatar.dart';
|
import 'package:fluffychat/widgets/avatar.dart';
|
||||||
|
|
||||||
class KeyVerificationDialog extends StatefulWidget {
|
class KeyVerificationDialog extends StatefulWidget {
|
||||||
Future<void> show(BuildContext context) => showModalBottomSheet(
|
Future<void> show(BuildContext context) => showAdaptiveBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => this,
|
builder: (context) => this,
|
||||||
useRootNavigator: false,
|
|
||||||
isDismissible: false,
|
isDismissible: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import 'package:matrix/matrix.dart';
|
|||||||
|
|
||||||
import 'package:fluffychat/pages/new_private_chat/new_private_chat_view.dart';
|
import 'package:fluffychat/pages/new_private_chat/new_private_chat_view.dart';
|
||||||
import 'package:fluffychat/pages/new_private_chat/qr_scanner_modal.dart';
|
import 'package:fluffychat/pages/new_private_chat/qr_scanner_modal.dart';
|
||||||
|
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||||
import 'package:fluffychat/utils/fluffy_share.dart';
|
import 'package:fluffychat/utils/fluffy_share.dart';
|
||||||
import 'package:fluffychat/utils/platform_infos.dart';
|
import 'package:fluffychat/utils/platform_infos.dart';
|
||||||
import 'package:fluffychat/utils/url_launcher.dart';
|
import 'package:fluffychat/utils/url_launcher.dart';
|
||||||
@ -75,10 +76,8 @@ class NewPrivateChatController extends State<NewPrivateChat> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await showModalBottomSheet(
|
await showAdaptiveBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: false,
|
|
||||||
//useSafeArea: false,
|
|
||||||
builder: (_) => const QrScannerModal(),
|
builder: (_) => const QrScannerModal(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import 'package:video_player/video_player.dart';
|
|||||||
import 'package:vrouter/vrouter.dart';
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/pages/story/story_view.dart';
|
import 'package:fluffychat/pages/story/story_view.dart';
|
||||||
|
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||||
import 'package:fluffychat/utils/date_time_extension.dart';
|
import 'package:fluffychat/utils/date_time_extension.dart';
|
||||||
import 'package:fluffychat/utils/localized_exception_extension.dart';
|
import 'package:fluffychat/utils/localized_exception_extension.dart';
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/client_stories_extension.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/client_stories_extension.dart';
|
||||||
@ -58,7 +59,7 @@ class StoryPageController extends State<StoryPage> {
|
|||||||
void replyEmojiAction() async {
|
void replyEmojiAction() async {
|
||||||
if (replyLoading) return;
|
if (replyLoading) return;
|
||||||
_modalOpened = true;
|
_modalOpened = true;
|
||||||
await showModalBottomSheet(
|
await showAdaptiveBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => EmojiPicker(
|
builder: (context) => EmojiPicker(
|
||||||
onEmojiSelected: (c, e) {
|
onEmojiSelected: (c, e) {
|
||||||
@ -123,7 +124,7 @@ class StoryPageController extends State<StoryPage> {
|
|||||||
|
|
||||||
void displaySeenByUsers() async {
|
void displaySeenByUsers() async {
|
||||||
_modalOpened = true;
|
_modalOpened = true;
|
||||||
await showModalBottomSheet(
|
await showAdaptiveBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => Scaffold(
|
builder: (context) => Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
@ -10,6 +10,17 @@ import 'package:fluffychat/widgets/permission_slider_dialog.dart';
|
|||||||
import '../../widgets/matrix.dart';
|
import '../../widgets/matrix.dart';
|
||||||
import 'user_bottom_sheet_view.dart';
|
import 'user_bottom_sheet_view.dart';
|
||||||
|
|
||||||
|
enum UserBottomSheetAction {
|
||||||
|
report,
|
||||||
|
mention,
|
||||||
|
ban,
|
||||||
|
kick,
|
||||||
|
unban,
|
||||||
|
permission,
|
||||||
|
message,
|
||||||
|
ignore,
|
||||||
|
}
|
||||||
|
|
||||||
class UserBottomSheet extends StatefulWidget {
|
class UserBottomSheet extends StatefulWidget {
|
||||||
final User user;
|
final User user;
|
||||||
final Function? onMention;
|
final Function? onMention;
|
||||||
@ -27,7 +38,7 @@ class UserBottomSheet extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class UserBottomSheetController extends State<UserBottomSheet> {
|
class UserBottomSheetController extends State<UserBottomSheet> {
|
||||||
void participantAction(String action) async {
|
void participantAction(UserBottomSheetAction action) async {
|
||||||
// ignore: prefer_function_declarations_over_variables
|
// ignore: prefer_function_declarations_over_variables
|
||||||
final Function askConfirmation = () async => (await showOkCancelAlertDialog(
|
final Function askConfirmation = () async => (await showOkCancelAlertDialog(
|
||||||
useRootNavigator: false,
|
useRootNavigator: false,
|
||||||
@ -38,7 +49,7 @@ class UserBottomSheetController extends State<UserBottomSheet> {
|
|||||||
) ==
|
) ==
|
||||||
OkCancelResult.ok);
|
OkCancelResult.ok);
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'report':
|
case UserBottomSheetAction.report:
|
||||||
final event = widget.user;
|
final event = widget.user;
|
||||||
final score = await showConfirmationDialog<int>(
|
final score = await showConfirmationDialog<int>(
|
||||||
context: context,
|
context: context,
|
||||||
@ -82,11 +93,11 @@ class UserBottomSheetController extends State<UserBottomSheet> {
|
|||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text(L10n.of(context)!.contentHasBeenReported)));
|
SnackBar(content: Text(L10n.of(context)!.contentHasBeenReported)));
|
||||||
break;
|
break;
|
||||||
case 'mention':
|
case UserBottomSheetAction.mention:
|
||||||
Navigator.of(context, rootNavigator: false).pop();
|
Navigator.of(context, rootNavigator: false).pop();
|
||||||
widget.onMention!();
|
widget.onMention!();
|
||||||
break;
|
break;
|
||||||
case 'ban':
|
case UserBottomSheetAction.ban:
|
||||||
if (await askConfirmation()) {
|
if (await askConfirmation()) {
|
||||||
await showFutureLoadingDialog(
|
await showFutureLoadingDialog(
|
||||||
context: context,
|
context: context,
|
||||||
@ -95,7 +106,7 @@ class UserBottomSheetController extends State<UserBottomSheet> {
|
|||||||
Navigator.of(context, rootNavigator: false).pop();
|
Navigator.of(context, rootNavigator: false).pop();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'unban':
|
case UserBottomSheetAction.unban:
|
||||||
if (await askConfirmation()) {
|
if (await askConfirmation()) {
|
||||||
await showFutureLoadingDialog(
|
await showFutureLoadingDialog(
|
||||||
context: context,
|
context: context,
|
||||||
@ -104,7 +115,7 @@ class UserBottomSheetController extends State<UserBottomSheet> {
|
|||||||
Navigator.of(context, rootNavigator: false).pop();
|
Navigator.of(context, rootNavigator: false).pop();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'kick':
|
case UserBottomSheetAction.kick:
|
||||||
if (await askConfirmation()) {
|
if (await askConfirmation()) {
|
||||||
await showFutureLoadingDialog(
|
await showFutureLoadingDialog(
|
||||||
context: context,
|
context: context,
|
||||||
@ -113,7 +124,7 @@ class UserBottomSheetController extends State<UserBottomSheet> {
|
|||||||
Navigator.of(context, rootNavigator: false).pop();
|
Navigator.of(context, rootNavigator: false).pop();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'permission':
|
case UserBottomSheetAction.permission:
|
||||||
final newPermission = await showPermissionChooser(
|
final newPermission = await showPermissionChooser(
|
||||||
context,
|
context,
|
||||||
currentLevel: widget.user.powerLevel,
|
currentLevel: widget.user.powerLevel,
|
||||||
@ -127,7 +138,7 @@ class UserBottomSheetController extends State<UserBottomSheet> {
|
|||||||
Navigator.of(context, rootNavigator: false).pop();
|
Navigator.of(context, rootNavigator: false).pop();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'message':
|
case UserBottomSheetAction.message:
|
||||||
final roomIdResult = await showFutureLoadingDialog(
|
final roomIdResult = await showFutureLoadingDialog(
|
||||||
context: context,
|
context: context,
|
||||||
future: () => widget.user.startDirectChat(),
|
future: () => widget.user.startDirectChat(),
|
||||||
@ -137,7 +148,7 @@ class UserBottomSheetController extends State<UserBottomSheet> {
|
|||||||
.toSegments(['rooms', roomIdResult.result!]);
|
.toSegments(['rooms', roomIdResult.result!]);
|
||||||
Navigator.of(context, rootNavigator: false).pop();
|
Navigator.of(context, rootNavigator: false).pop();
|
||||||
break;
|
break;
|
||||||
case 'ignore':
|
case UserBottomSheetAction.ignore:
|
||||||
if (await askConfirmation()) {
|
if (await askConfirmation()) {
|
||||||
await showFutureLoadingDialog(
|
await showFutureLoadingDialog(
|
||||||
context: context,
|
context: context,
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/themes.dart';
|
|
||||||
import 'package:fluffychat/utils/fluffy_share.dart';
|
import 'package:fluffychat/utils/fluffy_share.dart';
|
||||||
|
import 'package:fluffychat/widgets/avatar.dart';
|
||||||
import '../../utils/matrix_sdk_extensions/presence_extension.dart';
|
import '../../utils/matrix_sdk_extensions/presence_extension.dart';
|
||||||
import '../../widgets/content_banner.dart';
|
|
||||||
import '../../widgets/m2_popup_menu_button.dart';
|
|
||||||
import '../../widgets/matrix.dart';
|
import '../../widgets/matrix.dart';
|
||||||
import 'user_bottom_sheet.dart';
|
import 'user_bottom_sheet.dart';
|
||||||
|
|
||||||
@ -23,155 +19,114 @@ class UserBottomSheetView extends StatelessWidget {
|
|||||||
final user = controller.widget.user;
|
final user = controller.widget.user;
|
||||||
final client = Matrix.of(context).client;
|
final client = Matrix.of(context).client;
|
||||||
final presence = client.presences[user.id];
|
final presence = client.presences[user.id];
|
||||||
return Center(
|
return SafeArea(
|
||||||
child: SizedBox(
|
child: Scaffold(
|
||||||
width: min(
|
appBar: AppBar(
|
||||||
MediaQuery.of(context).size.width, FluffyThemes.columnWidth * 1.5),
|
leading: CloseButton(
|
||||||
child: Material(
|
onPressed: Navigator.of(context, rootNavigator: false).pop,
|
||||||
elevation: 4,
|
|
||||||
child: SafeArea(
|
|
||||||
child: Scaffold(
|
|
||||||
extendBodyBehindAppBar: true,
|
|
||||||
appBar: AppBar(
|
|
||||||
elevation: 0,
|
|
||||||
backgroundColor:
|
|
||||||
Theme.of(context).scaffoldBackgroundColor.withOpacity(0.5),
|
|
||||||
leading: IconButton(
|
|
||||||
icon: const Icon(Icons.arrow_downward_outlined),
|
|
||||||
onPressed: Navigator.of(context, rootNavigator: false).pop,
|
|
||||||
tooltip: L10n.of(context)!.close,
|
|
||||||
),
|
|
||||||
title: Text(user.calcDisplayname()),
|
|
||||||
actions: [
|
|
||||||
if (user.id != client.userID)
|
|
||||||
M2PopupMenuButton(
|
|
||||||
itemBuilder: (_) => [
|
|
||||||
if (controller.widget.onMention != null)
|
|
||||||
PopupMenuItem(
|
|
||||||
value: 'mention',
|
|
||||||
child: _TextWithIcon(
|
|
||||||
L10n.of(context)!.mention,
|
|
||||||
Icons.alternate_email_outlined,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (user.id != client.userID && !user.room.isDirectChat)
|
|
||||||
PopupMenuItem(
|
|
||||||
value: 'message',
|
|
||||||
child: _TextWithIcon(
|
|
||||||
L10n.of(context)!.sendAMessage,
|
|
||||||
Icons.send_outlined,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (user.canChangePowerLevel)
|
|
||||||
PopupMenuItem(
|
|
||||||
value: 'permission',
|
|
||||||
child: _TextWithIcon(
|
|
||||||
L10n.of(context)!.setPermissionsLevel,
|
|
||||||
Icons.edit_attributes_outlined,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (user.canKick)
|
|
||||||
PopupMenuItem(
|
|
||||||
value: 'kick',
|
|
||||||
child: _TextWithIcon(
|
|
||||||
L10n.of(context)!.kickFromChat,
|
|
||||||
Icons.exit_to_app_outlined,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (user.canBan && user.membership != Membership.ban)
|
|
||||||
PopupMenuItem(
|
|
||||||
value: 'ban',
|
|
||||||
child: _TextWithIcon(
|
|
||||||
L10n.of(context)!.banFromChat,
|
|
||||||
Icons.warning_sharp,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
else if (user.canBan &&
|
|
||||||
user.membership == Membership.ban)
|
|
||||||
PopupMenuItem(
|
|
||||||
value: 'unban',
|
|
||||||
child: _TextWithIcon(
|
|
||||||
L10n.of(context)!.unbanFromChat,
|
|
||||||
Icons.warning_outlined,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (!client.ignoredUsers.contains(user.id))
|
|
||||||
PopupMenuItem(
|
|
||||||
value: 'ignore',
|
|
||||||
child: _TextWithIcon(
|
|
||||||
L10n.of(context)!.ignore,
|
|
||||||
Icons.block,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PopupMenuItem(
|
|
||||||
value: 'report',
|
|
||||||
child: _TextWithIcon(
|
|
||||||
L10n.of(context)!.reportUser,
|
|
||||||
Icons.shield_outlined,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
onSelected: controller.participantAction,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
body: Column(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: ContentBanner(
|
|
||||||
mxContent: user.avatarUrl,
|
|
||||||
defaultIcon: Icons.account_circle_outlined,
|
|
||||||
client: client,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text(L10n.of(context)!.username),
|
|
||||||
subtitle: Text(user.id),
|
|
||||||
trailing: Icon(Icons.adaptive.share_outlined),
|
|
||||||
onTap: () => FluffyShare.share(
|
|
||||||
user.id,
|
|
||||||
context,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (presence != null)
|
|
||||||
ListTile(
|
|
||||||
title: Text(presence.getLocalizedStatusMessage(context)),
|
|
||||||
subtitle:
|
|
||||||
Text(presence.getLocalizedLastActiveAgo(context)),
|
|
||||||
trailing: Icon(Icons.circle,
|
|
||||||
color: presence.presence == PresenceType.online
|
|
||||||
? Colors.green
|
|
||||||
: Colors.grey),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
title: Text(user.calcDisplayname()),
|
||||||
|
actions: [
|
||||||
|
if (user.id != client.userID)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: OutlinedButton.icon(
|
||||||
|
onPressed: () => controller
|
||||||
|
.participantAction(UserBottomSheetAction.message),
|
||||||
|
icon: const Icon(Icons.chat_outlined),
|
||||||
|
label: Text(L10n.of(context)!.newChat),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Avatar(
|
||||||
|
mxContent: user.avatarUrl,
|
||||||
|
name: user.calcDisplayname(),
|
||||||
|
size: Avatar.defaultSize * 2,
|
||||||
|
fontSize: 24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: ListTile(
|
||||||
|
contentPadding: const EdgeInsets.only(right: 16.0),
|
||||||
|
title: Text(user.id),
|
||||||
|
subtitle: presence == null
|
||||||
|
? null
|
||||||
|
: Text(presence.getLocalizedLastActiveAgo(context)),
|
||||||
|
trailing: IconButton(
|
||||||
|
icon: Icon(Icons.adaptive.share),
|
||||||
|
onPressed: () => FluffyShare.share(
|
||||||
|
user.id,
|
||||||
|
context,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (controller.widget.onMention != null)
|
||||||
|
ListTile(
|
||||||
|
trailing: const Icon(Icons.alternate_email_outlined),
|
||||||
|
title: Text(L10n.of(context)!.mention),
|
||||||
|
onTap: () =>
|
||||||
|
controller.participantAction(UserBottomSheetAction.mention),
|
||||||
|
),
|
||||||
|
if (user.canChangePowerLevel)
|
||||||
|
ListTile(
|
||||||
|
title: Text(L10n.of(context)!.setPermissionsLevel),
|
||||||
|
trailing: const Icon(Icons.edit_attributes_outlined),
|
||||||
|
onTap: () => controller
|
||||||
|
.participantAction(UserBottomSheetAction.permission),
|
||||||
|
),
|
||||||
|
if (user.canKick)
|
||||||
|
ListTile(
|
||||||
|
title: Text(L10n.of(context)!.kickFromChat),
|
||||||
|
trailing: const Icon(Icons.exit_to_app_outlined),
|
||||||
|
onTap: () =>
|
||||||
|
controller.participantAction(UserBottomSheetAction.kick),
|
||||||
|
),
|
||||||
|
if (user.canBan && user.membership != Membership.ban)
|
||||||
|
ListTile(
|
||||||
|
title: Text(L10n.of(context)!.banFromChat),
|
||||||
|
trailing: const Icon(Icons.warning_sharp),
|
||||||
|
onTap: () =>
|
||||||
|
controller.participantAction(UserBottomSheetAction.ban),
|
||||||
|
)
|
||||||
|
else if (user.canBan && user.membership == Membership.ban)
|
||||||
|
ListTile(
|
||||||
|
title: Text(L10n.of(context)!.unbanFromChat),
|
||||||
|
trailing: const Icon(Icons.warning_outlined),
|
||||||
|
onTap: () =>
|
||||||
|
controller.participantAction(UserBottomSheetAction.unban),
|
||||||
|
),
|
||||||
|
if (user.id != client.userID &&
|
||||||
|
!client.ignoredUsers.contains(user.id))
|
||||||
|
ListTile(
|
||||||
|
textColor: Theme.of(context).colorScheme.onErrorContainer,
|
||||||
|
iconColor: Theme.of(context).colorScheme.onErrorContainer,
|
||||||
|
title: Text(L10n.of(context)!.ignore),
|
||||||
|
trailing: const Icon(Icons.block),
|
||||||
|
onTap: () =>
|
||||||
|
controller.participantAction(UserBottomSheetAction.ignore),
|
||||||
|
),
|
||||||
|
if (user.id != client.userID)
|
||||||
|
ListTile(
|
||||||
|
textColor: Theme.of(context).colorScheme.error,
|
||||||
|
iconColor: Theme.of(context).colorScheme.error,
|
||||||
|
title: Text(L10n.of(context)!.reportUser),
|
||||||
|
trailing: const Icon(Icons.shield_outlined),
|
||||||
|
onTap: () =>
|
||||||
|
controller.participantAction(UserBottomSheetAction.report),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TextWithIcon extends StatelessWidget {
|
|
||||||
final String text;
|
|
||||||
final IconData iconData;
|
|
||||||
|
|
||||||
const _TextWithIcon(
|
|
||||||
this.text,
|
|
||||||
this.iconData, {
|
|
||||||
Key? key,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Icon(iconData),
|
|
||||||
const SizedBox(width: 16),
|
|
||||||
Text(text),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
28
lib/utils/adaptive_bottom_sheet.dart
Normal file
28
lib/utils/adaptive_bottom_sheet.dart
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
|
import 'package:fluffychat/config/themes.dart';
|
||||||
|
import 'package:fluffychat/utils/platform_infos.dart';
|
||||||
|
|
||||||
|
Future<T?> showAdaptiveBottomSheet<T>({
|
||||||
|
required BuildContext context,
|
||||||
|
required Widget Function(BuildContext) builder,
|
||||||
|
bool isDismissible = true,
|
||||||
|
}) =>
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
builder: builder,
|
||||||
|
useRootNavigator: !PlatformInfos.isMobile,
|
||||||
|
isDismissible: isDismissible,
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
maxHeight: MediaQuery.of(context).size.height - 128,
|
||||||
|
maxWidth: FluffyThemes.columnWidth * 1.5,
|
||||||
|
),
|
||||||
|
clipBehavior: Clip.hardEdge,
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(AppConfig.borderRadius),
|
||||||
|
topRight: Radius.circular(AppConfig.borderRadius),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
@ -10,6 +10,7 @@ import 'package:url_launcher/url_launcher.dart';
|
|||||||
import 'package:vrouter/vrouter.dart';
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.dart';
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
|
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
import 'package:fluffychat/widgets/profile_bottom_sheet.dart';
|
import 'package:fluffychat/widgets/profile_bottom_sheet.dart';
|
||||||
import 'package:fluffychat/widgets/public_room_bottom_sheet.dart';
|
import 'package:fluffychat/widgets/public_room_bottom_sheet.dart';
|
||||||
@ -145,7 +146,7 @@ class UrlLauncher {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
await showModalBottomSheet(
|
await showAdaptiveBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (c) => PublicRoomBottomSheet(
|
builder: (c) => PublicRoomBottomSheet(
|
||||||
roomAlias: identityParts.primaryIdentifier,
|
roomAlias: identityParts.primaryIdentifier,
|
||||||
@ -182,7 +183,7 @@ class UrlLauncher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (identityParts.primaryIdentifier.sigil == '@') {
|
} else if (identityParts.primaryIdentifier.sigil == '@') {
|
||||||
await showModalBottomSheet(
|
await showAdaptiveBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (c) => ProfileBottomSheet(
|
builder: (c) => ProfileBottomSheet(
|
||||||
userId: identityParts.primaryIdentifier,
|
userId: identityParts.primaryIdentifier,
|
||||||
|
@ -14,6 +14,7 @@ import 'package:vrouter/vrouter.dart';
|
|||||||
import 'package:fluffychat/pages/chat/cupertino_widgets_bottom_sheet.dart';
|
import 'package:fluffychat/pages/chat/cupertino_widgets_bottom_sheet.dart';
|
||||||
import 'package:fluffychat/pages/chat/edit_widgets_dialog.dart';
|
import 'package:fluffychat/pages/chat/edit_widgets_dialog.dart';
|
||||||
import 'package:fluffychat/pages/chat/widgets_bottom_sheet.dart';
|
import 'package:fluffychat/pages/chat/widgets_bottom_sheet.dart';
|
||||||
|
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||||
import 'm2_popup_menu_button.dart';
|
import 'm2_popup_menu_button.dart';
|
||||||
import 'matrix.dart';
|
import 'matrix.dart';
|
||||||
|
|
||||||
@ -185,7 +186,7 @@ class ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (context) => CupertinoWidgetsBottomSheet(room: widget.room),
|
builder: (context) => CupertinoWidgetsBottomSheet(room: widget.room),
|
||||||
)
|
)
|
||||||
: showModalBottomSheet(
|
: showAdaptiveBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => WidgetsBottomSheet(room: widget.room),
|
builder: (context) => WidgetsBottomSheet(room: widget.room),
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
@ -7,10 +5,8 @@ import 'package:future_loading_dialog/future_loading_dialog.dart';
|
|||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:vrouter/vrouter.dart';
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/themes.dart';
|
import 'package:fluffychat/widgets/avatar.dart';
|
||||||
import 'package:fluffychat/widgets/content_banner.dart';
|
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
import '../utils/localized_exception_extension.dart';
|
|
||||||
|
|
||||||
class ProfileBottomSheet extends StatelessWidget {
|
class ProfileBottomSheet extends StatelessWidget {
|
||||||
final String userId;
|
final String userId;
|
||||||
@ -37,79 +33,65 @@ class ProfileBottomSheet extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Center(
|
return SafeArea(
|
||||||
child: SizedBox(
|
child: FutureBuilder<Profile>(
|
||||||
width: min(
|
future: Matrix.of(context).client.getProfileFromUserId(userId),
|
||||||
MediaQuery.of(context).size.width, FluffyThemes.columnWidth * 1.5),
|
builder: (context, snapshot) {
|
||||||
child: Material(
|
final profile = snapshot.data;
|
||||||
elevation: 4,
|
return Scaffold(
|
||||||
child: SafeArea(
|
appBar: AppBar(
|
||||||
child: Scaffold(
|
leading: CloseButton(
|
||||||
extendBodyBehindAppBar: true,
|
onPressed: Navigator.of(context, rootNavigator: false).pop,
|
||||||
appBar: AppBar(
|
),
|
||||||
elevation: 0,
|
title: ListTile(
|
||||||
backgroundColor:
|
contentPadding: const EdgeInsets.only(right: 16.0),
|
||||||
Theme.of(context).scaffoldBackgroundColor.withOpacity(0.5),
|
title: Text(
|
||||||
leading: IconButton(
|
profile?.displayName ?? userId.localpart ?? userId,
|
||||||
icon: const Icon(Icons.arrow_downward_outlined),
|
style: const TextStyle(fontSize: 18),
|
||||||
onPressed: Navigator.of(context, rootNavigator: false).pop,
|
),
|
||||||
tooltip: L10n.of(context)!.close,
|
subtitle: Text(
|
||||||
|
userId,
|
||||||
|
style: const TextStyle(fontSize: 12),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
body: FutureBuilder<Profile>(
|
actions: [
|
||||||
future:
|
Padding(
|
||||||
Matrix.of(context).client.getProfileFromUserId(userId),
|
padding: const EdgeInsets.all(8.0),
|
||||||
builder: (context, snapshot) {
|
child: OutlinedButton.icon(
|
||||||
final profile = snapshot.data;
|
onPressed: () => _startDirectChat(context),
|
||||||
|
icon: Icon(Icons.adaptive.share_outlined),
|
||||||
return Column(
|
label: Text(L10n.of(context)!.share),
|
||||||
children: [
|
),
|
||||||
Expanded(
|
),
|
||||||
child: profile == null
|
],
|
||||||
? Container(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
color: Theme.of(context).secondaryHeaderColor,
|
|
||||||
child: snapshot.hasError
|
|
||||||
? Text(snapshot.error!
|
|
||||||
.toLocalizedString(context))
|
|
||||||
: const CircularProgressIndicator
|
|
||||||
.adaptive(strokeWidth: 2),
|
|
||||||
)
|
|
||||||
: ContentBanner(
|
|
||||||
mxContent: profile.avatarUrl,
|
|
||||||
defaultIcon: Icons.account_circle_outlined,
|
|
||||||
client: Matrix.of(context).client,
|
|
||||||
placeholder: (context) => Center(
|
|
||||||
child: Text(
|
|
||||||
userId.localpart ?? userId,
|
|
||||||
style:
|
|
||||||
Theme.of(context).textTheme.headline3,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text(
|
|
||||||
profile?.displayName ?? userId.localpart ?? ''),
|
|
||||||
subtitle: Text(userId),
|
|
||||||
trailing: const Icon(Icons.account_box_outlined),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
width: double.infinity,
|
|
||||||
padding: const EdgeInsets.all(12),
|
|
||||||
child: ElevatedButton.icon(
|
|
||||||
onPressed: () => _startDirectChat(context),
|
|
||||||
label: Text(L10n.of(context)!.newChat),
|
|
||||||
icon: const Icon(Icons.send_outlined),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
),
|
body: ListView(
|
||||||
),
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Avatar(
|
||||||
|
mxContent: profile?.avatarUrl,
|
||||||
|
name: profile?.displayName ?? userId,
|
||||||
|
size: Avatar.defaultSize * 3,
|
||||||
|
fontSize: 36,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
child: FloatingActionButton.extended(
|
||||||
|
onPressed: () => _startDirectChat(context),
|
||||||
|
label: Text(L10n.of(context)!.newChat),
|
||||||
|
icon: const Icon(Icons.send_outlined),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
@ -8,7 +6,6 @@ import 'package:matrix/matrix.dart';
|
|||||||
import 'package:matrix_link_text/link_text.dart';
|
import 'package:matrix_link_text/link_text.dart';
|
||||||
import 'package:vrouter/vrouter.dart';
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/themes.dart';
|
|
||||||
import 'package:fluffychat/utils/url_launcher.dart';
|
import 'package:fluffychat/utils/url_launcher.dart';
|
||||||
import 'package:fluffychat/widgets/content_banner.dart';
|
import 'package:fluffychat/widgets/content_banner.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
@ -72,101 +69,87 @@ class PublicRoomBottomSheet extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final roomAlias = this.roomAlias;
|
final roomAlias = this.roomAlias;
|
||||||
return Center(
|
return SafeArea(
|
||||||
child: SizedBox(
|
child: Scaffold(
|
||||||
width: min(
|
extendBodyBehindAppBar: true,
|
||||||
MediaQuery.of(context).size.width, FluffyThemes.columnWidth * 1.5),
|
appBar: AppBar(
|
||||||
child: Material(
|
elevation: 0,
|
||||||
elevation: 4,
|
titleSpacing: 0,
|
||||||
child: SafeArea(
|
backgroundColor:
|
||||||
child: Scaffold(
|
Theme.of(context).scaffoldBackgroundColor.withOpacity(0.5),
|
||||||
extendBodyBehindAppBar: true,
|
title: Text(
|
||||||
appBar: AppBar(
|
roomAlias ?? chunk!.name ?? chunk!.roomId,
|
||||||
elevation: 0,
|
overflow: TextOverflow.fade,
|
||||||
titleSpacing: 0,
|
|
||||||
backgroundColor:
|
|
||||||
Theme.of(context).scaffoldBackgroundColor.withOpacity(0.5),
|
|
||||||
title: Text(
|
|
||||||
roomAlias ?? chunk!.name ?? chunk!.roomId,
|
|
||||||
overflow: TextOverflow.fade,
|
|
||||||
),
|
|
||||||
leading: IconButton(
|
|
||||||
icon: const Icon(Icons.arrow_downward_outlined),
|
|
||||||
onPressed: Navigator.of(context, rootNavigator: false).pop,
|
|
||||||
tooltip: L10n.of(context)!.close,
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton.icon(
|
|
||||||
onPressed: () => _joinRoom(context),
|
|
||||||
label: Text(L10n.of(context)!.joinRoom),
|
|
||||||
icon: const Icon(Icons.login_outlined),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
body: FutureBuilder<PublicRoomsChunk>(
|
|
||||||
future: _search(context),
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
final profile = snapshot.data;
|
|
||||||
return ListView(
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
children: [
|
|
||||||
if (profile == null)
|
|
||||||
Container(
|
|
||||||
height: 156,
|
|
||||||
alignment: Alignment.center,
|
|
||||||
color: Theme.of(context).secondaryHeaderColor,
|
|
||||||
child: snapshot.hasError
|
|
||||||
? Text(
|
|
||||||
snapshot.error!.toLocalizedString(context))
|
|
||||||
: const CircularProgressIndicator.adaptive(
|
|
||||||
strokeWidth: 2),
|
|
||||||
)
|
|
||||||
else
|
|
||||||
ContentBanner(
|
|
||||||
mxContent: profile.avatarUrl,
|
|
||||||
height: 156,
|
|
||||||
defaultIcon: Icons.group_outlined,
|
|
||||||
client: Matrix.of(context).client,
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text(profile?.name ??
|
|
||||||
roomAlias?.localpart ??
|
|
||||||
chunk!.roomId.localpart ??
|
|
||||||
''),
|
|
||||||
subtitle: Text(
|
|
||||||
'${L10n.of(context)!.participant}: ${profile?.numJoinedMembers ?? 0}',
|
|
||||||
),
|
|
||||||
trailing: const Icon(Icons.account_box_outlined),
|
|
||||||
),
|
|
||||||
if (profile?.topic?.isNotEmpty ?? false)
|
|
||||||
ListTile(
|
|
||||||
title: Text(
|
|
||||||
L10n.of(context)!.groupDescription,
|
|
||||||
style: TextStyle(
|
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
subtitle: LinkText(
|
|
||||||
text: profile!.topic!,
|
|
||||||
linkStyle:
|
|
||||||
const TextStyle(color: Colors.blueAccent),
|
|
||||||
textStyle: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.bodyText2!
|
|
||||||
.color,
|
|
||||||
),
|
|
||||||
onLinkTap: (url) =>
|
|
||||||
UrlLauncher(context, url).launchUrl(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
leading: IconButton(
|
||||||
|
icon: const Icon(Icons.arrow_downward_outlined),
|
||||||
|
onPressed: Navigator.of(context, rootNavigator: false).pop,
|
||||||
|
tooltip: L10n.of(context)!.close,
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton.icon(
|
||||||
|
onPressed: () => _joinRoom(context),
|
||||||
|
label: Text(L10n.of(context)!.joinRoom),
|
||||||
|
icon: const Icon(Icons.login_outlined),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
|
body: FutureBuilder<PublicRoomsChunk>(
|
||||||
|
future: _search(context),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
final profile = snapshot.data;
|
||||||
|
return ListView(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
children: [
|
||||||
|
if (profile == null)
|
||||||
|
Container(
|
||||||
|
height: 156,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
color: Theme.of(context).secondaryHeaderColor,
|
||||||
|
child: snapshot.hasError
|
||||||
|
? Text(snapshot.error!.toLocalizedString(context))
|
||||||
|
: const CircularProgressIndicator.adaptive(
|
||||||
|
strokeWidth: 2),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
ContentBanner(
|
||||||
|
mxContent: profile.avatarUrl,
|
||||||
|
height: 156,
|
||||||
|
defaultIcon: Icons.group_outlined,
|
||||||
|
client: Matrix.of(context).client,
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text(profile?.name ??
|
||||||
|
roomAlias?.localpart ??
|
||||||
|
chunk!.roomId.localpart ??
|
||||||
|
''),
|
||||||
|
subtitle: Text(
|
||||||
|
'${L10n.of(context)!.participant}: ${profile?.numJoinedMembers ?? 0}',
|
||||||
|
),
|
||||||
|
trailing: const Icon(Icons.account_box_outlined),
|
||||||
|
),
|
||||||
|
if (profile?.topic?.isNotEmpty ?? false)
|
||||||
|
ListTile(
|
||||||
|
title: Text(
|
||||||
|
L10n.of(context)!.groupDescription,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: LinkText(
|
||||||
|
text: profile!.topic!,
|
||||||
|
linkStyle: const TextStyle(color: Colors.blueAccent),
|
||||||
|
textStyle: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Theme.of(context).textTheme.bodyText2!.color,
|
||||||
|
),
|
||||||
|
onLinkTap: (url) =>
|
||||||
|
UrlLauncher(context, url).launchUrl(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user