✨ DM groups
This commit is contained in:
@ -23,6 +23,7 @@ class _CaptchaScreenState extends ConsumerState<CaptchaScreen> {
|
||||
final message = event.data as String;
|
||||
if (message.startsWith("captcha_tk=")) {
|
||||
String token = message.replaceFirst("captcha_tk=", "");
|
||||
// ignore: use_build_context_synchronously
|
||||
if (context.mounted) Navigator.pop(context, token);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import 'package:croppy/croppy.dart' hide cropImage;
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_expandable_fab/flutter_expandable_fab.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@ -48,20 +47,27 @@ class ChatRoomListTile extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return ListTile(
|
||||
leading:
|
||||
isDirect
|
||||
? ProfilePictureWidget(
|
||||
fileId: room.members!.first.account.profile.pictureId,
|
||||
(isDirect && room.pictureId == null)
|
||||
? SplitAvatarWidget(
|
||||
filesId:
|
||||
room.members!
|
||||
.map((e) => e.account.profile.pictureId)
|
||||
.toList(),
|
||||
)
|
||||
: room.pictureId == null
|
||||
? CircleAvatar(child: Text(room.name[0].toUpperCase()))
|
||||
? CircleAvatar(child: Text(room.name![0].toUpperCase()))
|
||||
: ProfilePictureWidget(fileId: room.pictureId),
|
||||
title: Text(isDirect ? room.members!.first.account.nick : room.name),
|
||||
title: Text(
|
||||
(isDirect && room.name == null)
|
||||
? room.members!.map((e) => e.account.nick).join(', ')
|
||||
: room.name!,
|
||||
),
|
||||
subtitle:
|
||||
subtitle != null
|
||||
? subtitle!
|
||||
: isDirect
|
||||
? Text('@${room.members!.first.account.name}')
|
||||
: Text(room.description),
|
||||
: (isDirect && room.description == null)
|
||||
? Text(room.members!.map((e) => '@${e.account.name}').join(', '))
|
||||
: Text(room.description ?? 'descriptionNone'.tr()),
|
||||
trailing: trailing,
|
||||
onTap:
|
||||
onTap ??
|
||||
@ -82,8 +88,6 @@ Future<List<SnChatRoom>> chatroomsJoined(Ref ref) async {
|
||||
.toList();
|
||||
}
|
||||
|
||||
final chatFabKey = GlobalKey<ExpandableFabState>();
|
||||
|
||||
@RoutePage()
|
||||
class ChatListScreen extends HookConsumerWidget {
|
||||
const ChatListScreen({super.key});
|
||||
@ -139,69 +143,41 @@ class ChatListScreen extends HookConsumerWidget {
|
||||
const Gap(8),
|
||||
],
|
||||
),
|
||||
floatingActionButtonLocation: ExpandableFab.location,
|
||||
floatingActionButton: ExpandableFab(
|
||||
key: chatFabKey,
|
||||
distance: 75,
|
||||
type: ExpandableFabType.up,
|
||||
childrenAnimation: ExpandableFabAnimation.none,
|
||||
overlayStyle: ExpandableFabOverlayStyle(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.surface.withAlpha((255 * 0.5).round()),
|
||||
),
|
||||
openButtonBuilder: RotateFloatingActionButtonBuilder(
|
||||
child: const Icon(Icons.add),
|
||||
fabSize: ExpandableFabSize.regular,
|
||||
foregroundColor:
|
||||
Theme.of(context).floatingActionButtonTheme.foregroundColor,
|
||||
backgroundColor:
|
||||
Theme.of(context).floatingActionButtonTheme.backgroundColor,
|
||||
),
|
||||
closeButtonBuilder: DefaultFloatingActionButtonBuilder(
|
||||
child: const Icon(Icons.close),
|
||||
fabSize: ExpandableFabSize.regular,
|
||||
foregroundColor:
|
||||
Theme.of(context).floatingActionButtonTheme.foregroundColor,
|
||||
backgroundColor:
|
||||
Theme.of(context).floatingActionButtonTheme.backgroundColor,
|
||||
),
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text('createChatRoom').tr(),
|
||||
const Gap(20),
|
||||
FloatingActionButton(
|
||||
heroTag: null,
|
||||
tooltip: 'createChatRoom'.tr(),
|
||||
onPressed: () {
|
||||
chatFabKey.currentState?.toggle();
|
||||
context.pushRoute(NewChatRoute()).then((value) {
|
||||
if (value != null) {
|
||||
ref.invalidate(chatroomsJoinedProvider);
|
||||
}
|
||||
});
|
||||
},
|
||||
child: const Icon(Symbols.chat_add_on),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text('createDirectMessage').tr(),
|
||||
const Gap(20),
|
||||
FloatingActionButton(
|
||||
heroTag: null,
|
||||
tooltip: 'createDirectMessage'.tr(),
|
||||
onPressed: () {
|
||||
chatFabKey.currentState?.toggle();
|
||||
createDirectMessage();
|
||||
},
|
||||
child: const Icon(Symbols.communication),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder:
|
||||
(context) => Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text('createChatRoom').tr(),
|
||||
leading: const Icon(Symbols.add),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
context.pushRoute(NewChatRoute()).then((value) {
|
||||
if (value != null) {
|
||||
ref.invalidate(chatroomsJoinedProvider);
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: 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: chats.when(
|
||||
data:
|
||||
@ -281,8 +257,8 @@ class EditChatScreen extends HookConsumerWidget {
|
||||
|
||||
useEffect(() {
|
||||
if (chat.value != null) {
|
||||
nameController.text = chat.value!.name;
|
||||
descriptionController.text = chat.value!.description;
|
||||
nameController.text = chat.value!.name ?? '';
|
||||
descriptionController.text = chat.value!.description ?? '';
|
||||
picture.value = chat.value!.picture;
|
||||
background.value = chat.value!.background;
|
||||
currentRealm.value = joinedRealms.value?.firstWhereOrNull(
|
||||
|
@ -442,10 +442,12 @@ class ChatRoomScreen extends HookConsumerWidget {
|
||||
height: 26,
|
||||
width: 26,
|
||||
child:
|
||||
room!.type == 1
|
||||
? ProfilePictureWidget(
|
||||
fileId:
|
||||
room.members!.first.account.profile.pictureId,
|
||||
(room!.type == 1 && room.pictureId == null)
|
||||
? SplitAvatarWidget(
|
||||
filesId:
|
||||
room.members!
|
||||
.map((e) => e.account.profile.pictureId)
|
||||
.toList(),
|
||||
)
|
||||
: room.pictureId != null
|
||||
? ProfilePictureWidget(
|
||||
@ -454,15 +456,15 @@ class ChatRoomScreen extends HookConsumerWidget {
|
||||
)
|
||||
: CircleAvatar(
|
||||
child: Text(
|
||||
room.name[0].toUpperCase(),
|
||||
room.name![0].toUpperCase(),
|
||||
style: const TextStyle(fontSize: 12),
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
room.type == 1
|
||||
? room.members!.first.account.nick
|
||||
: room.name,
|
||||
(room.type == 1 && room.name == null)
|
||||
? room.members!.map((e) => e.account.nick).join(', ')
|
||||
: room.name!,
|
||||
).fontSize(19),
|
||||
],
|
||||
),
|
||||
@ -763,7 +765,7 @@ class _ChatInput extends StatelessWidget {
|
||||
? 'chatDirectMessageHint'.tr(
|
||||
args: [chatRoom.members!.first.account.nick],
|
||||
)
|
||||
: 'chatMessageHint'.tr(args: [chatRoom.name]),
|
||||
: 'chatMessageHint'.tr(args: [chatRoom.name!]),
|
||||
border: InputBorder.none,
|
||||
isDense: true,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
|
@ -54,14 +54,20 @@ class ChatDetailScreen extends HookConsumerWidget {
|
||||
leading: PageBackButton(shadows: [iconShadow]),
|
||||
flexibleSpace: FlexibleSpaceBar(
|
||||
background:
|
||||
currentRoom!.type == 1 &&
|
||||
(currentRoom!.type == 1 &&
|
||||
currentRoom.backgroundId != null)
|
||||
? CloudImageWidget(
|
||||
fileId: currentRoom.backgroundId!,
|
||||
)
|
||||
: (currentRoom.type == 1 &&
|
||||
currentRoom.members!.length == 1 &&
|
||||
currentRoom
|
||||
.members!
|
||||
.first
|
||||
.account
|
||||
.profile
|
||||
.backgroundId !=
|
||||
null
|
||||
null)
|
||||
? CloudImageWidget(
|
||||
fileId:
|
||||
currentRoom
|
||||
@ -81,9 +87,11 @@ class ChatDetailScreen extends HookConsumerWidget {
|
||||
Theme.of(context).appBarTheme.backgroundColor,
|
||||
),
|
||||
title: Text(
|
||||
currentRoom.type == 1
|
||||
? currentRoom.members!.first.account.nick
|
||||
: currentRoom.name,
|
||||
(currentRoom.type == 1 && currentRoom.name == null)
|
||||
? currentRoom.members!
|
||||
.map((e) => e.account.name)
|
||||
.join(', ')
|
||||
: currentRoom.name!,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).appBarTheme.foregroundColor,
|
||||
shadows: [iconShadow],
|
||||
@ -114,7 +122,7 @@ class ChatDetailScreen extends HookConsumerWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
currentRoom.description,
|
||||
currentRoom.description ?? 'descriptionNone'.tr(),
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
|
@ -73,7 +73,11 @@ class RealmListScreen extends HookConsumerWidget {
|
||||
heroTag: Key("realms-page-fab"),
|
||||
child: const Icon(Symbols.add),
|
||||
onPressed: () {
|
||||
context.router.push(NewRealmRoute());
|
||||
context.router.push(NewRealmRoute()).then((value) {
|
||||
if (value != null) {
|
||||
ref.invalidate(realmsJoinedProvider);
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
body: RefreshIndicator(
|
||||
|
@ -5,6 +5,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:island/models/wallet.dart';
|
||||
import 'package:island/pods/network.dart';
|
||||
import 'package:island/widgets/app_scaffold.dart';
|
||||
import 'package:island/widgets/response.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
||||
@ -149,7 +150,11 @@ class WalletScreen extends HookConsumerWidget {
|
||||
],
|
||||
);
|
||||
},
|
||||
error: (error, stackTrace) => Center(child: Text('Error: $error')),
|
||||
error:
|
||||
(error, stackTrace) => ResponseErrorWidget(
|
||||
error: error,
|
||||
onRetry: () => ref.invalidate(walletCurrentProvider),
|
||||
),
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
),
|
||||
);
|
||||
|
Reference in New Issue
Block a user