refactor: Design polishment and better user viewer

This commit is contained in:
Krille 2024-07-26 14:52:41 +02:00
parent 9d0cefce18
commit 16cf4e5e6c
No known key found for this signature in database
GPG key ID: E067ECD60F1A0652
11 changed files with 134 additions and 152 deletions

View file

@ -85,33 +85,16 @@ class ChatDetailsView extends StatelessWidget {
padding: const EdgeInsets.all(32.0),
child: Stack(
children: [
Material(
elevation: Theme.of(context)
.appBarTheme
.scrolledUnderElevation ??
4,
shadowColor: Theme.of(context)
.appBarTheme
.shadowColor,
shape: RoundedRectangleBorder(
side: BorderSide(
color: Theme.of(context).dividerColor,
),
borderRadius: BorderRadius.circular(
Avatar.defaultSize * 2.5,
),
),
child: Hero(
tag: controller
.widget.embeddedCloseButton !=
null
? 'embedded_content_banner'
: 'content_banner',
child: Avatar(
mxContent: room.avatar,
name: displayname,
size: Avatar.defaultSize * 2.5,
),
Hero(
tag:
controller.widget.embeddedCloseButton !=
null
? 'embedded_content_banner'
: 'content_banner',
child: Avatar(
mxContent: room.avatar,
name: displayname,
size: Avatar.defaultSize * 2.5,
),
),
if (!room.isDirectChat &&
@ -170,7 +153,7 @@ class ChatDetailsView extends StatelessWidget {
: displayname,
maxLines: 1,
overflow: TextOverflow.ellipsis,
// style: const TextStyle(fontSize: 18),
style: const TextStyle(fontSize: 18),
),
),
TextButton.icon(
@ -202,10 +185,7 @@ class ChatDetailsView extends StatelessWidget {
),
],
),
Divider(
height: 1,
color: Theme.of(context).dividerColor,
),
Divider(color: Theme.of(context).dividerColor),
if (!room.canChangeStateEvent(EventTypes.RoomTopic))
ListTile(
title: Text(
@ -261,10 +241,7 @@ class ChatDetailsView extends StatelessWidget {
),
),
const SizedBox(height: 16),
Divider(
height: 1,
color: Theme.of(context).dividerColor,
),
Divider(color: Theme.of(context).dividerColor),
ListTile(
leading: CircleAvatar(
backgroundColor:
@ -316,10 +293,7 @@ class ChatDetailsView extends StatelessWidget {
onTap: () => context
.push('/rooms/${room.id}/details/permissions'),
),
Divider(
height: 1,
color: Theme.of(context).dividerColor,
),
Divider(color: Theme.of(context).dividerColor),
ListTile(
title: Text(
L10n.of(context)!.countParticipants(

View file

@ -102,10 +102,6 @@ class NewGroupView extends StatelessWidget {
child: SizedBox(
width: double.infinity,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Theme.of(context).colorScheme.onPrimary,
backgroundColor: Theme.of(context).colorScheme.primary,
),
onPressed:
controller.loading ? null : controller.submitAction,
child: controller.loading

View file

@ -74,10 +74,6 @@ class NewSpaceView extends StatelessWidget {
child: SizedBox(
width: double.infinity,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Theme.of(context).colorScheme.onPrimary,
backgroundColor: Theme.of(context).colorScheme.primary,
),
onPressed:
controller.loading ? null : controller.submitAction,
child: controller.loading

View file

@ -28,13 +28,6 @@ class SettingsView extends StatelessWidget {
),
),
title: Text(L10n.of(context)!.settings),
actions: [
TextButton.icon(
onPressed: controller.logoutAction,
label: Text(L10n.of(context)!.logout),
icon: const Icon(Icons.logout_outlined),
),
],
),
body: ListTileTheme(
iconColor: Theme.of(context).colorScheme.onSurface,
@ -55,32 +48,17 @@ class SettingsView extends StatelessWidget {
padding: const EdgeInsets.all(32.0),
child: Stack(
children: [
Material(
elevation: Theme.of(context)
.appBarTheme
.scrolledUnderElevation ??
4,
shadowColor:
Theme.of(context).appBarTheme.shadowColor,
shape: RoundedRectangleBorder(
side: BorderSide(
color: Theme.of(context).dividerColor,
),
borderRadius: BorderRadius.circular(
Avatar.defaultSize * 2.5,
),
),
child: Avatar(
mxContent: profile?.avatarUrl,
name: displayname,
size: Avatar.defaultSize * 2.5,
),
Avatar(
mxContent: profile?.avatarUrl,
name: displayname,
size: Avatar.defaultSize * 2.5,
),
if (profile != null)
Positioned(
bottom: 0,
right: 0,
child: FloatingActionButton.small(
elevation: 2,
onPressed: controller.setAvatarAction,
heroTag: null,
child: const Icon(Icons.camera_alt_outlined),
@ -108,7 +86,9 @@ class SettingsView extends StatelessWidget {
displayname,
maxLines: 1,
overflow: TextOverflow.ellipsis,
// style: const TextStyle(fontSize: 18),
style: const TextStyle(
fontSize: 18,
),
),
),
TextButton.icon(
@ -135,10 +115,7 @@ class SettingsView extends StatelessWidget {
);
},
),
Divider(
height: 1,
color: Theme.of(context).dividerColor,
),
Divider(color: Theme.of(context).dividerColor),
if (showChatBackupBanner == null)
ListTile(
leading: const Icon(Icons.backup_outlined),
@ -154,60 +131,54 @@ class SettingsView extends StatelessWidget {
onChanged: controller.firstRunBootstrapAction,
),
Divider(
height: 1,
color: Theme.of(context).dividerColor,
),
ListTile(
leading: const Icon(Icons.format_paint_outlined),
title: Text(L10n.of(context)!.changeTheme),
onTap: () => context.go('/rooms/settings/style'),
trailing: const Icon(Icons.chevron_right_outlined),
),
ListTile(
leading: const Icon(Icons.notifications_outlined),
title: Text(L10n.of(context)!.notifications),
onTap: () => context.go('/rooms/settings/notifications'),
trailing: const Icon(Icons.chevron_right_outlined),
),
ListTile(
leading: const Icon(Icons.devices_outlined),
title: Text(L10n.of(context)!.devices),
onTap: () => context.go('/rooms/settings/devices'),
trailing: const Icon(Icons.chevron_right_outlined),
),
ListTile(
leading: const Icon(Icons.forum_outlined),
title: Text(L10n.of(context)!.chat),
onTap: () => context.go('/rooms/settings/chat'),
trailing: const Icon(Icons.chevron_right_outlined),
),
ListTile(
leading: const Icon(Icons.shield_outlined),
title: Text(L10n.of(context)!.security),
onTap: () => context.go('/rooms/settings/security'),
trailing: const Icon(Icons.chevron_right_outlined),
),
Divider(
height: 1,
color: Theme.of(context).dividerColor,
),
Divider(color: Theme.of(context).dividerColor),
ListTile(
leading: const Icon(Icons.help_outline_outlined),
title: Text(L10n.of(context)!.help),
onTap: () => launchUrlString(AppConfig.supportUrl),
trailing: const Icon(Icons.open_in_new_outlined),
),
ListTile(
leading: const Icon(Icons.shield_sharp),
title: Text(L10n.of(context)!.privacy),
onTap: () => launchUrlString(AppConfig.privacyUrl),
trailing: const Icon(Icons.open_in_new_outlined),
),
ListTile(
leading: const Icon(Icons.info_outline_rounded),
title: Text(L10n.of(context)!.about),
onTap: () => PlatformInfos.showDialog(context),
trailing: const Icon(Icons.chevron_right_outlined),
),
Divider(color: Theme.of(context).dividerColor),
ListTile(
leading: const Icon(Icons.logout_outlined),
title: Text(L10n.of(context)!.logout),
onTap: controller.logoutAction,
),
],
),

View file

@ -69,7 +69,7 @@ class Settings3PidView extends StatelessWidget {
.withTheseAddressesRecoveryDescription,
),
),
const Divider(height: 1),
const Divider(),
Expanded(
child: ListView.builder(
itemCount: identifier.length,

View file

@ -71,10 +71,7 @@ class SettingsChatView extends StatelessWidget {
storeKey: SettingKeys.swipeRightToLeftToReply,
defaultValue: AppConfig.swipeRightToLeftToReply,
),
Divider(
height: 1,
color: Theme.of(context).dividerColor,
),
Divider(color: Theme.of(context).dividerColor),
ListTile(
title: Text(
L10n.of(context)!.customEmojisAndStickers,
@ -93,10 +90,7 @@ class SettingsChatView extends StatelessWidget {
child: Icon(Icons.chevron_right_outlined),
),
),
Divider(
height: 1,
color: Theme.of(context).dividerColor,
),
Divider(color: Theme.of(context).dividerColor),
ListTile(
title: Text(
L10n.of(context)!.calls,

View file

@ -117,7 +117,7 @@ class EmotesSettingsView extends StatelessWidget {
onChanged: controller.setIsGloballyActive,
),
if (!controller.readonly || controller.room != null)
const Divider(thickness: 1),
const Divider(),
imageKeys.isEmpty
? Center(
child: Padding(

View file

@ -86,7 +86,6 @@ class SettingsSecurityView extends StatelessWidget {
),
},
Divider(
height: 1,
color: Theme.of(context).dividerColor,
),
ListTile(

View file

@ -136,7 +136,6 @@ class SettingsStyleView extends StatelessWidget {
),
const SizedBox(height: 8),
Divider(
height: 1,
color: Theme.of(context).dividerColor,
),
ListTile(
@ -167,7 +166,6 @@ class SettingsStyleView extends StatelessWidget {
onChanged: controller.switchTheme,
),
Divider(
height: 1,
color: Theme.of(context).dividerColor,
),
ListTile(
@ -192,7 +190,6 @@ class SettingsStyleView extends StatelessWidget {
defaultValue: AppConfig.separateChatTypes,
),
Divider(
height: 1,
color: Theme.of(context).dividerColor,
),
ListTile(

View file

@ -226,6 +226,45 @@ class UserBottomSheetController extends State<UserBottomSheet> {
}
}
bool isSending = false;
Object? sendError;
final TextEditingController sendController = TextEditingController();
void sendAction([_]) async {
final userId = widget.user?.id ?? widget.profile?.userId;
final client = Matrix.of(context).client;
if (userId == null) throw ('user or profile must not be null!');
final input = sendController.text.trim();
if (input.isEmpty) return;
setState(() {
isSending = true;
sendError = null;
});
try {
final roomId = await client.startDirectChat(userId);
if (!mounted) return;
final room = client.getRoomById(roomId);
if (room == null) {
throw ('DM Room found or created but room not found in client');
}
await room.sendTextEvent(input);
setState(() {
isSending = false;
sendController.clear();
});
} catch (e, s) {
Logs().d('Unable to send message', e, s);
setState(() {
isSending = false;
sendError = e;
});
}
}
void knockAccept() async {
final user = widget.user!;
final result = await showFutureLoadingDialog(

View file

@ -7,6 +7,7 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/utils/fluffy_share.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/presence_builder.dart';
@ -29,6 +30,7 @@ class UserBottomSheetView extends StatelessWidget {
final client = Matrix.of(controller.widget.outerContext).client;
final profileSearchError = controller.widget.profileSearchError;
final dmRoomId = client.getDirectChatFromUserId(userId);
return SafeArea(
child: Scaffold(
appBar: AppBar(
@ -90,19 +92,19 @@ class UserBottomSheetView extends StatelessWidget {
),
],
),
actions: [
if (userId != client.userID &&
!client.ignoredUsers.contains(userId))
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: IconButton(
icon: const Icon(Icons.block_outlined),
tooltip: L10n.of(context)!.block,
onPressed: () => controller
.participantAction(UserBottomSheetAction.ignore),
),
),
],
actions: dmRoomId == null
? null
: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: FloatingActionButton.small(
elevation: 0,
onPressed: () => controller
.participantAction(UserBottomSheetAction.message),
child: const Icon(Icons.chat_outlined),
),
),
],
),
body: StreamBuilder<Object>(
stream: user?.room.client.onSync.stream.where(
@ -169,25 +171,10 @@ class UserBottomSheetView extends StatelessWidget {
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Material(
elevation: Theme.of(context)
.appBarTheme
.scrolledUnderElevation ??
4,
shadowColor: Theme.of(context).appBarTheme.shadowColor,
shape: RoundedRectangleBorder(
side: BorderSide(
color: Theme.of(context).dividerColor,
),
borderRadius: BorderRadius.circular(
Avatar.defaultSize * 2.5,
),
),
child: Avatar(
mxContent: avatarUrl,
name: displayname,
size: Avatar.defaultSize * 2.5,
),
child: Avatar(
mxContent: avatarUrl,
name: displayname,
size: Avatar.defaultSize * 2.5,
),
),
Expanded(
@ -212,7 +199,7 @@ class UserBottomSheetView extends StatelessWidget {
displayname,
maxLines: 1,
overflow: TextOverflow.ellipsis,
// style: const TextStyle(fontSize: 18),
style: const TextStyle(fontSize: 18),
),
),
TextButton.icon(
@ -247,16 +234,35 @@ class UserBottomSheetView extends StatelessWidget {
horizontal: 16.0,
vertical: 8.0,
),
child: ElevatedButton.icon(
onPressed: () => controller
.participantAction(UserBottomSheetAction.message),
icon: const Icon(Icons.forum_outlined),
label: Text(
controller.widget.user == null
? L10n.of(context)!.startConversation
: L10n.of(context)!.sendAMessage,
),
),
child: dmRoomId == null
? ElevatedButton.icon(
onPressed: () => controller.participantAction(
UserBottomSheetAction.message,
),
icon: const Icon(Icons.chat_outlined),
label: Text(L10n.of(context)!.startConversation),
)
: TextField(
controller: controller.sendController,
readOnly: controller.isSending,
onSubmitted: controller.sendAction,
minLines: 1,
maxLines: 1,
textInputAction: TextInputAction.send,
decoration: InputDecoration(
errorText: controller.sendError
?.toLocalizedString(context),
hintText: L10n.of(context)!.sendMessages,
suffixIcon: controller.isSending
? const CircularProgressIndicator.adaptive(
strokeWidth: 2,
)
: IconButton(
icon: const Icon(Icons.send_outlined),
onPressed: controller.sendAction,
),
),
),
),
PresenceBuilder(
userId: userId,
@ -334,8 +340,8 @@ class UserBottomSheetView extends StatelessWidget {
),
),
),
Divider(color: Theme.of(context).dividerColor),
],
Divider(color: Theme.of(context).dividerColor),
if (user != null && user.canKick)
ListTile(
textColor: Theme.of(context).colorScheme.error,
@ -370,7 +376,7 @@ class UserBottomSheetView extends StatelessWidget {
textColor: Theme.of(context).colorScheme.onErrorContainer,
iconColor: Theme.of(context).colorScheme.onErrorContainer,
title: Text(L10n.of(context)!.reportUser),
leading: const Icon(Icons.report_outlined),
leading: const Icon(Icons.gavel_outlined),
onTap: () => controller
.participantAction(UserBottomSheetAction.report),
),
@ -385,6 +391,16 @@ class UserBottomSheetView extends StatelessWidget {
style: const TextStyle(color: Colors.orange),
),
),
if (userId != client.userID &&
!client.ignoredUsers.contains(userId))
ListTile(
textColor: Theme.of(context).colorScheme.onErrorContainer,
iconColor: Theme.of(context).colorScheme.onErrorContainer,
leading: const Icon(Icons.block_outlined),
title: Text(L10n.of(context)!.block),
onTap: () => controller
.participantAction(UserBottomSheetAction.ignore),
),
],
);
},