refactor: Update to Dart 3.10 with . shorthands
This commit is contained in:
parent
75a37f3f7c
commit
1ea649f01e
167 changed files with 3351 additions and 3912 deletions
|
|
@ -38,13 +38,7 @@ enum PopupMenuAction {
|
|||
archive,
|
||||
}
|
||||
|
||||
enum ActiveFilter {
|
||||
allChats,
|
||||
messages,
|
||||
groups,
|
||||
unread,
|
||||
spaces,
|
||||
}
|
||||
enum ActiveFilter { allChats, messages, groups, unread, spaces }
|
||||
|
||||
extension LocalizedActiveFilter on ActiveFilter {
|
||||
String toLocalizedString(BuildContext context) {
|
||||
|
|
@ -102,8 +96,8 @@ class ChatListController extends State<ChatList>
|
|||
}
|
||||
|
||||
void clearActiveSpace() => setState(() {
|
||||
_activeSpaceId = null;
|
||||
});
|
||||
_activeSpaceId = null;
|
||||
});
|
||||
|
||||
void onChatTap(Room room) async {
|
||||
if (room.membership == Membership.invite) {
|
||||
|
|
@ -124,9 +118,7 @@ class ChatListController extends State<ChatList>
|
|||
|
||||
if (room.membership == Membership.ban) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(L10n.of(context).youHaveBeenBannedFromThisChat),
|
||||
),
|
||||
SnackBar(content: Text(L10n.of(context).youHaveBeenBannedFromThisChat)),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -159,11 +151,9 @@ class ChatListController extends State<ChatList>
|
|||
}
|
||||
}
|
||||
|
||||
List<Room> get filteredRooms => Matrix.of(context)
|
||||
.client
|
||||
.rooms
|
||||
.where(getRoomFilterByActiveFilter(activeFilter))
|
||||
.toList();
|
||||
List<Room> get filteredRooms => Matrix.of(
|
||||
context,
|
||||
).client.rooms.where(getRoomFilterByActiveFilter(activeFilter)).toList();
|
||||
|
||||
bool isSearchMode = false;
|
||||
Future<QueryPublicRoomsResponse>? publicRoomsResponse;
|
||||
|
|
@ -222,8 +212,9 @@ class ChatListController extends State<ChatList>
|
|||
|
||||
if (searchQuery.isValidMatrixId &&
|
||||
searchQuery.sigil == '#' &&
|
||||
roomSearchResult.chunk
|
||||
.any((room) => room.canonicalAlias == searchQuery) ==
|
||||
roomSearchResult.chunk.any(
|
||||
(room) => room.canonicalAlias == searchQuery,
|
||||
) ==
|
||||
false) {
|
||||
final response = await client.getRoomIdByAlias(searchQuery);
|
||||
final roomId = response.roomId;
|
||||
|
|
@ -246,13 +237,9 @@ class ChatListController extends State<ChatList>
|
|||
);
|
||||
} catch (e, s) {
|
||||
Logs().w('Searching has crashed', e, s);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
e.toLocalizedString(context),
|
||||
),
|
||||
),
|
||||
);
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text(e.toLocalizedString(context))));
|
||||
}
|
||||
if (!isSearchMode) return;
|
||||
setState(() {
|
||||
|
|
@ -333,22 +320,17 @@ class ChatListController extends State<ChatList>
|
|||
showScaffoldDialog(
|
||||
context: context,
|
||||
builder: (context) => ShareScaffoldDialog(
|
||||
items: files.map(
|
||||
(file) {
|
||||
if ({
|
||||
SharedMediaType.text,
|
||||
SharedMediaType.url,
|
||||
}.contains(file.type)) {
|
||||
return TextShareItem(file.path);
|
||||
}
|
||||
return FileShareItem(
|
||||
XFile(
|
||||
file.path.replaceFirst('file://', ''),
|
||||
mimeType: file.mimeType,
|
||||
),
|
||||
);
|
||||
},
|
||||
).toList(),
|
||||
items: files.map((file) {
|
||||
if ({SharedMediaType.text, SharedMediaType.url}.contains(file.type)) {
|
||||
return TextShareItem(file.path);
|
||||
}
|
||||
return FileShareItem(
|
||||
XFile(
|
||||
file.path.replaceFirst('file://', ''),
|
||||
mimeType: file.mimeType,
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -370,22 +352,23 @@ class ChatListController extends State<ChatList>
|
|||
.listen(_processIncomingSharedMedia, onError: print);
|
||||
|
||||
// For sharing images coming from outside the app while the app is closed
|
||||
ReceiveSharingIntent.instance
|
||||
.getInitialMedia()
|
||||
.then(_processIncomingSharedMedia);
|
||||
ReceiveSharingIntent.instance.getInitialMedia().then(
|
||||
_processIncomingSharedMedia,
|
||||
);
|
||||
|
||||
// For receiving shared Uris
|
||||
_intentUriStreamSubscription =
|
||||
AppLinks().uriLinkStream.listen(_processIncomingUris);
|
||||
_intentUriStreamSubscription = AppLinks().uriLinkStream.listen(
|
||||
_processIncomingUris,
|
||||
);
|
||||
|
||||
if (PlatformInfos.isAndroid) {
|
||||
final shortcuts = FlutterShortcuts();
|
||||
shortcuts.initialize().then(
|
||||
(_) => shortcuts.listenAction((action) {
|
||||
if (!mounted) return;
|
||||
UrlLauncher(context, action).launchUrl();
|
||||
}),
|
||||
);
|
||||
(_) => shortcuts.listenAction((action) {
|
||||
if (!mounted) return;
|
||||
UrlLauncher(context, action).launchUrl();
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -402,8 +385,9 @@ class ChatListController extends State<ChatList>
|
|||
_hackyWebRTCFixForWeb();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
if (mounted) {
|
||||
searchServer =
|
||||
Matrix.of(context).store.getString(_serverStoreNamespace);
|
||||
searchServer = Matrix.of(
|
||||
context,
|
||||
).store.getString(_serverStoreNamespace);
|
||||
Matrix.of(context).backgroundPush?.setupPush();
|
||||
UpdateNotifier.showUpdateSnackBar(context);
|
||||
}
|
||||
|
|
@ -447,8 +431,9 @@ class ChatListController extends State<ChatList>
|
|||
Offset.zero & overlay.size,
|
||||
);
|
||||
|
||||
final displayname =
|
||||
room.getLocalizedDisplayname(MatrixLocals(L10n.of(context)));
|
||||
final displayname = room.getLocalizedDisplayname(
|
||||
MatrixLocals(L10n.of(context)),
|
||||
);
|
||||
|
||||
final spacesWithPowerLevels = room.client.rooms
|
||||
.where(
|
||||
|
|
@ -466,19 +451,17 @@ class ChatListController extends State<ChatList>
|
|||
PopupMenuItem(
|
||||
value: ChatContextAction.open,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
spacing: 12.0,
|
||||
children: [
|
||||
Avatar(
|
||||
mxContent: room.avatar,
|
||||
name: displayname,
|
||||
),
|
||||
Avatar(mxContent: room.avatar, name: displayname),
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 128),
|
||||
child: Text(
|
||||
displayname,
|
||||
style:
|
||||
TextStyle(color: Theme.of(context).colorScheme.onSurface),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
|
|
@ -491,7 +474,7 @@ class ChatListController extends State<ChatList>
|
|||
PopupMenuItem(
|
||||
value: ChatContextAction.goToSpace,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
Avatar(
|
||||
mxContent: space.avatar,
|
||||
|
|
@ -511,7 +494,7 @@ class ChatListController extends State<ChatList>
|
|||
PopupMenuItem(
|
||||
value: ChatContextAction.mute,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
Icon(
|
||||
room.pushRuleState == PushRuleState.notify
|
||||
|
|
@ -530,7 +513,7 @@ class ChatListController extends State<ChatList>
|
|||
PopupMenuItem(
|
||||
value: ChatContextAction.markUnread,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
Icon(
|
||||
room.markedUnread
|
||||
|
|
@ -549,7 +532,7 @@ class ChatListController extends State<ChatList>
|
|||
PopupMenuItem(
|
||||
value: ChatContextAction.favorite,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
Icon(
|
||||
room.isFavourite ? Icons.push_pin : Icons.push_pin_outlined,
|
||||
|
|
@ -567,7 +550,7 @@ class ChatListController extends State<ChatList>
|
|||
PopupMenuItem(
|
||||
value: ChatContextAction.addToSpace,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
const Icon(Icons.group_work_outlined),
|
||||
const SizedBox(width: 12),
|
||||
|
|
@ -579,7 +562,7 @@ class ChatListController extends State<ChatList>
|
|||
PopupMenuItem(
|
||||
value: ChatContextAction.leave,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.delete_outlined,
|
||||
|
|
@ -601,7 +584,7 @@ class ChatListController extends State<ChatList>
|
|||
PopupMenuItem(
|
||||
value: ChatContextAction.block,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.block_outlined,
|
||||
|
|
@ -684,8 +667,9 @@ class ChatListController extends State<ChatList>
|
|||
.map(
|
||||
(space) => AdaptiveModalAction(
|
||||
value: space,
|
||||
label: space
|
||||
.getLocalizedDisplayname(MatrixLocals(L10n.of(context))),
|
||||
label: space.getLocalizedDisplayname(
|
||||
MatrixLocals(L10n.of(context)),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
|
|
@ -746,8 +730,9 @@ class ChatListController extends State<ChatList>
|
|||
await client.accountDataLoading;
|
||||
await client.userDeviceKeysLoading;
|
||||
if (client.prevBatch == null) {
|
||||
await client.onSyncStatus.stream
|
||||
.firstWhere((status) => status.status == SyncStatus.finished);
|
||||
await client.onSyncStatus.stream.firstWhere(
|
||||
(status) => status.status == SyncStatus.finished,
|
||||
);
|
||||
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
|
|
@ -759,8 +744,9 @@ class ChatListController extends State<ChatList>
|
|||
waitForFirstSync = true;
|
||||
});
|
||||
|
||||
if (client.userDeviceKeys[client.userID!]?.deviceKeys.values
|
||||
.any((device) => !device.verified && !device.blocked) ??
|
||||
if (client.userDeviceKeys[client.userID!]?.deviceKeys.values.any(
|
||||
(device) => !device.verified && !device.blocked,
|
||||
) ??
|
||||
false) {
|
||||
late final ScaffoldFeatureController controller;
|
||||
final theme = Theme.of(context);
|
||||
|
|
@ -772,9 +758,7 @@ class ChatListController extends State<ChatList>
|
|||
closeIconColor: theme.colorScheme.onErrorContainer,
|
||||
content: Text(
|
||||
L10n.of(context).oneOfYourDevicesIsNotVerified,
|
||||
style: TextStyle(
|
||||
color: theme.colorScheme.onErrorContainer,
|
||||
),
|
||||
style: TextStyle(color: theme.colorScheme.onErrorContainer),
|
||||
),
|
||||
action: SnackBarAction(
|
||||
onPressed: () {
|
||||
|
|
@ -810,20 +794,21 @@ class ChatListController extends State<ChatList>
|
|||
setState(() {
|
||||
_activeSpaceId = null;
|
||||
Matrix.of(context).activeBundle = bundle;
|
||||
if (!Matrix.of(context)
|
||||
.currentBundle!
|
||||
.any((client) => client == Matrix.of(context).client)) {
|
||||
Matrix.of(context)
|
||||
.setActiveClient(Matrix.of(context).currentBundle!.first);
|
||||
if (!Matrix.of(
|
||||
context,
|
||||
).currentBundle!.any((client) => client == Matrix.of(context).client)) {
|
||||
Matrix.of(
|
||||
context,
|
||||
).setActiveClient(Matrix.of(context).currentBundle!.first);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void editBundlesForAccount(String? userId, String? activeBundle) async {
|
||||
final l10n = L10n.of(context);
|
||||
final client = Matrix.of(context)
|
||||
.widget
|
||||
.clients[Matrix.of(context).getClientIndexByMatrixId(userId!)];
|
||||
final client = Matrix.of(
|
||||
context,
|
||||
).widget.clients[Matrix.of(context).getClientIndexByMatrixId(userId!)];
|
||||
final action = await showModalActionPopup<EditBundleAction>(
|
||||
context: context,
|
||||
title: L10n.of(context).editBundlesForAccount,
|
||||
|
|
@ -868,10 +853,9 @@ class ChatListController extends State<ChatList>
|
|||
|
||||
String? get secureActiveBundle {
|
||||
if (Matrix.of(context).activeBundle == null ||
|
||||
!Matrix.of(context)
|
||||
.accountBundles
|
||||
.keys
|
||||
.contains(Matrix.of(context).activeBundle)) {
|
||||
!Matrix.of(
|
||||
context,
|
||||
).accountBundles.keys.contains(Matrix.of(context).activeBundle)) {
|
||||
return Matrix.of(context).accountBundles.keys.first;
|
||||
}
|
||||
return Matrix.of(context).activeBundle;
|
||||
|
|
@ -897,11 +881,7 @@ class ChatListController extends State<ChatList>
|
|||
|
||||
enum EditBundleAction { addToBundle, removeFromBundle }
|
||||
|
||||
enum InviteActions {
|
||||
accept,
|
||||
decline,
|
||||
block,
|
||||
}
|
||||
enum InviteActions { accept, decline, block }
|
||||
|
||||
enum ChatContextAction {
|
||||
open,
|
||||
|
|
|
|||
|
|
@ -59,9 +59,7 @@ class ChatListViewBody extends StatelessWidget {
|
|||
const dummyChatCount = 4;
|
||||
final filter = controller.searchController.text.toLowerCase();
|
||||
return StreamBuilder(
|
||||
key: ValueKey(
|
||||
client.userID.toString(),
|
||||
),
|
||||
key: ValueKey(client.userID.toString()),
|
||||
stream: client.onSync.stream
|
||||
.where((s) => s.hasRoomUpdate)
|
||||
.rateLimit(const Duration(seconds: 1)),
|
||||
|
|
@ -74,151 +72,151 @@ class ChatListViewBody extends StatelessWidget {
|
|||
slivers: [
|
||||
ChatListHeader(controller: controller),
|
||||
SliverList(
|
||||
delegate: SliverChildListDelegate(
|
||||
[
|
||||
if (controller.isSearchMode) ...[
|
||||
SearchTitle(
|
||||
title: L10n.of(context).publicRooms,
|
||||
icon: const Icon(Icons.explore_outlined),
|
||||
),
|
||||
PublicRoomsHorizontalList(publicRooms: publicRooms),
|
||||
SearchTitle(
|
||||
title: L10n.of(context).publicSpaces,
|
||||
icon: const Icon(Icons.workspaces_outlined),
|
||||
),
|
||||
PublicRoomsHorizontalList(publicRooms: publicSpaces),
|
||||
SearchTitle(
|
||||
title: L10n.of(context).users,
|
||||
icon: const Icon(Icons.group_outlined),
|
||||
),
|
||||
AnimatedContainer(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: const BoxDecoration(),
|
||||
height: userSearchResult == null ||
|
||||
userSearchResult.results.isEmpty
|
||||
? 0
|
||||
: 106,
|
||||
duration: FluffyThemes.animationDuration,
|
||||
curve: FluffyThemes.animationCurve,
|
||||
child: userSearchResult == null
|
||||
? null
|
||||
: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: userSearchResult.results.length,
|
||||
itemBuilder: (context, i) => _SearchItem(
|
||||
title:
|
||||
userSearchResult.results[i].displayName ??
|
||||
userSearchResult
|
||||
.results[i].userId.localpart ??
|
||||
L10n.of(context).unknownDevice,
|
||||
avatar: userSearchResult.results[i].avatarUrl,
|
||||
onPressed: () => UserDialog.show(
|
||||
context: context,
|
||||
profile: userSearchResult.results[i],
|
||||
),
|
||||
delegate: SliverChildListDelegate([
|
||||
if (controller.isSearchMode) ...[
|
||||
SearchTitle(
|
||||
title: L10n.of(context).publicRooms,
|
||||
icon: const Icon(Icons.explore_outlined),
|
||||
),
|
||||
PublicRoomsHorizontalList(publicRooms: publicRooms),
|
||||
SearchTitle(
|
||||
title: L10n.of(context).publicSpaces,
|
||||
icon: const Icon(Icons.workspaces_outlined),
|
||||
),
|
||||
PublicRoomsHorizontalList(publicRooms: publicSpaces),
|
||||
SearchTitle(
|
||||
title: L10n.of(context).users,
|
||||
icon: const Icon(Icons.group_outlined),
|
||||
),
|
||||
AnimatedContainer(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: const BoxDecoration(),
|
||||
height:
|
||||
userSearchResult == null ||
|
||||
userSearchResult.results.isEmpty
|
||||
? 0
|
||||
: 106,
|
||||
duration: FluffyThemes.animationDuration,
|
||||
curve: FluffyThemes.animationCurve,
|
||||
child: userSearchResult == null
|
||||
? null
|
||||
: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: userSearchResult.results.length,
|
||||
itemBuilder: (context, i) => _SearchItem(
|
||||
title:
|
||||
userSearchResult.results[i].displayName ??
|
||||
userSearchResult
|
||||
.results[i]
|
||||
.userId
|
||||
.localpart ??
|
||||
L10n.of(context).unknownDevice,
|
||||
avatar: userSearchResult.results[i].avatarUrl,
|
||||
onPressed: () => UserDialog.show(
|
||||
context: context,
|
||||
profile: userSearchResult.results[i],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
if (!controller.isSearchMode &&
|
||||
AppSettings.showPresences.value)
|
||||
GestureDetector(
|
||||
onLongPress: () => controller.dismissStatusList(),
|
||||
child: StatusMessageList(
|
||||
onStatusEdit: controller.setStatus,
|
||||
),
|
||||
),
|
||||
if (client.rooms.isNotEmpty && !controller.isSearchMode)
|
||||
SizedBox(
|
||||
height: 64,
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12.0,
|
||||
vertical: 12.0,
|
||||
),
|
||||
shrinkWrap: true,
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: [
|
||||
if (AppSettings.separateChatTypes.value)
|
||||
ActiveFilter.messages
|
||||
else
|
||||
ActiveFilter.allChats,
|
||||
ActiveFilter.groups,
|
||||
ActiveFilter.unread,
|
||||
if (spaceDelegateCandidates.isNotEmpty &&
|
||||
!AppSettings.displayNavigationRail.value &&
|
||||
!FluffyThemes.isColumnMode(context))
|
||||
ActiveFilter.spaces,
|
||||
]
|
||||
.map(
|
||||
(filter) => Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 4.0,
|
||||
),
|
||||
child: FilterChip(
|
||||
selected: filter == controller.activeFilter,
|
||||
onSelected: (_) =>
|
||||
controller.setActiveFilter(filter),
|
||||
label:
|
||||
Text(filter.toLocalizedString(context)),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
if (controller.isSearchMode)
|
||||
SearchTitle(
|
||||
title: L10n.of(context).chats,
|
||||
icon: const Icon(Icons.forum_outlined),
|
||||
),
|
||||
if (client.prevBatch != null &&
|
||||
rooms.isEmpty &&
|
||||
!controller.isSearchMode) ...[
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
const Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
DummyChatListItem(
|
||||
opacity: 0.5,
|
||||
animate: false,
|
||||
),
|
||||
DummyChatListItem(
|
||||
opacity: 0.3,
|
||||
animate: false,
|
||||
),
|
||||
],
|
||||
),
|
||||
Icon(
|
||||
CupertinoIcons.chat_bubble_text_fill,
|
||||
size: 128,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Text(
|
||||
client.rooms.isEmpty
|
||||
? L10n.of(context).noChatsFoundHere
|
||||
: L10n.of(context).noMoreChatsFound,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
if (!controller.isSearchMode &&
|
||||
AppSettings.showPresences.value)
|
||||
GestureDetector(
|
||||
onLongPress: () => controller.dismissStatusList(),
|
||||
child: StatusMessageList(
|
||||
onStatusEdit: controller.setStatus,
|
||||
),
|
||||
),
|
||||
if (client.rooms.isNotEmpty && !controller.isSearchMode)
|
||||
SizedBox(
|
||||
height: 64,
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12.0,
|
||||
vertical: 12.0,
|
||||
),
|
||||
shrinkWrap: true,
|
||||
scrollDirection: Axis.horizontal,
|
||||
children:
|
||||
[
|
||||
if (AppSettings.separateChatTypes.value)
|
||||
ActiveFilter.messages
|
||||
else
|
||||
ActiveFilter.allChats,
|
||||
ActiveFilter.groups,
|
||||
ActiveFilter.unread,
|
||||
if (spaceDelegateCandidates.isNotEmpty &&
|
||||
!AppSettings
|
||||
.displayNavigationRail
|
||||
.value &&
|
||||
!FluffyThemes.isColumnMode(context))
|
||||
ActiveFilter.spaces,
|
||||
]
|
||||
.map(
|
||||
(filter) => Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 4.0,
|
||||
),
|
||||
child: FilterChip(
|
||||
selected:
|
||||
filter == controller.activeFilter,
|
||||
onSelected: (_) =>
|
||||
controller.setActiveFilter(filter),
|
||||
label: Text(
|
||||
filter.toLocalizedString(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
if (controller.isSearchMode)
|
||||
SearchTitle(
|
||||
title: L10n.of(context).chats,
|
||||
icon: const Icon(Icons.forum_outlined),
|
||||
),
|
||||
if (client.prevBatch != null &&
|
||||
rooms.isEmpty &&
|
||||
!controller.isSearchMode) ...[
|
||||
Column(
|
||||
mainAxisAlignment: .center,
|
||||
children: [
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
const Column(
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
DummyChatListItem(opacity: 0.5, animate: false),
|
||||
DummyChatListItem(opacity: 0.3, animate: false),
|
||||
],
|
||||
),
|
||||
Icon(
|
||||
CupertinoIcons.chat_bubble_text_fill,
|
||||
size: 128,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Text(
|
||||
client.rooms.isEmpty
|
||||
? L10n.of(context).noChatsFoundHere
|
||||
: L10n.of(context).noMoreChatsFound,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
]),
|
||||
),
|
||||
if (client.prevBatch == null)
|
||||
SliverList(
|
||||
|
|
@ -257,10 +255,7 @@ class ChatListViewBody extends StatelessWidget {
|
|||
}
|
||||
|
||||
class PublicRoomsHorizontalList extends StatelessWidget {
|
||||
const PublicRoomsHorizontalList({
|
||||
super.key,
|
||||
required this.publicRooms,
|
||||
});
|
||||
const PublicRoomsHorizontalList({super.key, required this.publicRooms});
|
||||
|
||||
final List<PublishedRoomsChunk>? publicRooms;
|
||||
|
||||
|
|
@ -279,7 +274,8 @@ class PublicRoomsHorizontalList extends StatelessWidget {
|
|||
scrollDirection: Axis.horizontal,
|
||||
itemCount: publicRooms.length,
|
||||
itemBuilder: (context, i) => _SearchItem(
|
||||
title: publicRooms[i].name ??
|
||||
title:
|
||||
publicRooms[i].name ??
|
||||
publicRooms[i].canonicalAlias?.localpart ??
|
||||
L10n.of(context).group,
|
||||
avatar: publicRooms[i].avatarUrl,
|
||||
|
|
@ -310,31 +306,26 @@ class _SearchItem extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) => InkWell(
|
||||
onTap: onPressed,
|
||||
child: SizedBox(
|
||||
width: 84,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
Avatar(
|
||||
mxContent: avatar,
|
||||
name: title,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
title,
|
||||
maxLines: 2,
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
onTap: onPressed,
|
||||
child: SizedBox(
|
||||
width: 84,
|
||||
child: Column(
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
Avatar(mxContent: avatar, name: title),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
title,
|
||||
maxLines: 2,
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,19 +34,19 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget {
|
|||
title: StreamBuilder(
|
||||
stream: client.onSyncStatus.stream,
|
||||
builder: (context, snapshot) {
|
||||
final status = client.onSyncStatus.value ??
|
||||
final status =
|
||||
client.onSyncStatus.value ??
|
||||
const SyncStatusUpdate(SyncStatus.waitingForResponse);
|
||||
final hide = client.onSync.value != null &&
|
||||
final hide =
|
||||
client.onSync.value != null &&
|
||||
status.status != SyncStatus.error &&
|
||||
client.prevBatch != null;
|
||||
return TextField(
|
||||
controller: controller.searchController,
|
||||
focusNode: controller.searchFocusNode,
|
||||
textInputAction: TextInputAction.search,
|
||||
onChanged: (text) => controller.onSearchEnter(
|
||||
text,
|
||||
globalSearch: globalSearch,
|
||||
),
|
||||
onChanged: (text) =>
|
||||
controller.onSearchEnter(text, globalSearch: globalSearch),
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: theme.colorScheme.secondaryContainer,
|
||||
|
|
@ -66,19 +66,19 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget {
|
|||
),
|
||||
prefixIcon: hide
|
||||
? controller.isSearchMode
|
||||
? IconButton(
|
||||
tooltip: L10n.of(context).cancel,
|
||||
icon: const Icon(Icons.close_outlined),
|
||||
onPressed: controller.cancelSearch,
|
||||
color: theme.colorScheme.onPrimaryContainer,
|
||||
)
|
||||
: IconButton(
|
||||
onPressed: controller.startSearch,
|
||||
icon: Icon(
|
||||
Icons.search_outlined,
|
||||
? IconButton(
|
||||
tooltip: L10n.of(context).cancel,
|
||||
icon: const Icon(Icons.close_outlined),
|
||||
onPressed: controller.cancelSearch,
|
||||
color: theme.colorScheme.onPrimaryContainer,
|
||||
),
|
||||
)
|
||||
)
|
||||
: IconButton(
|
||||
onPressed: controller.startSearch,
|
||||
icon: Icon(
|
||||
Icons.search_outlined,
|
||||
color: theme.colorScheme.onPrimaryContainer,
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
margin: const EdgeInsets.all(12),
|
||||
width: 8,
|
||||
|
|
@ -97,37 +97,34 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget {
|
|||
),
|
||||
suffixIcon: controller.isSearchMode && globalSearch
|
||||
? controller.isSearching
|
||||
? const Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 10.0,
|
||||
horizontal: 12,
|
||||
),
|
||||
child: SizedBox.square(
|
||||
dimension: 24,
|
||||
child: CircularProgressIndicator.adaptive(
|
||||
strokeWidth: 2,
|
||||
? const Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 10.0,
|
||||
horizontal: 12,
|
||||
),
|
||||
),
|
||||
)
|
||||
: TextButton.icon(
|
||||
onPressed: controller.setServer,
|
||||
style: TextButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(99),
|
||||
child: SizedBox.square(
|
||||
dimension: 24,
|
||||
child: CircularProgressIndicator.adaptive(
|
||||
strokeWidth: 2,
|
||||
),
|
||||
),
|
||||
textStyle: const TextStyle(fontSize: 12),
|
||||
),
|
||||
icon: const Icon(Icons.edit_outlined, size: 16),
|
||||
label: Text(
|
||||
controller.searchServer ??
|
||||
Matrix.of(context).client.homeserver!.host,
|
||||
maxLines: 2,
|
||||
),
|
||||
)
|
||||
: SizedBox(
|
||||
width: 0,
|
||||
child: ClientChooserButton(controller),
|
||||
),
|
||||
)
|
||||
: TextButton.icon(
|
||||
onPressed: controller.setServer,
|
||||
style: TextButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(99),
|
||||
),
|
||||
textStyle: const TextStyle(fontSize: 12),
|
||||
),
|
||||
icon: const Icon(Icons.edit_outlined, size: 16),
|
||||
label: Text(
|
||||
controller.searchServer ??
|
||||
Matrix.of(context).client.homeserver!.host,
|
||||
maxLines: 2,
|
||||
),
|
||||
)
|
||||
: SizedBox(width: 0, child: ClientChooserButton(controller)),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -48,8 +48,9 @@ class ChatListItem extends StatelessWidget {
|
|||
final directChatMatrixId = room.directChatMatrixID;
|
||||
final isDirectChat = directChatMatrixId != null;
|
||||
final hasNotifications = room.notificationCount > 0;
|
||||
final backgroundColor =
|
||||
activeChat ? theme.colorScheme.secondaryContainer : null;
|
||||
final backgroundColor = activeChat
|
||||
? theme.colorScheme.secondaryContainer
|
||||
: null;
|
||||
final displayname = room.getLocalizedDisplayname(
|
||||
MatrixLocals(L10n.of(context)),
|
||||
);
|
||||
|
|
@ -64,10 +65,7 @@ class ChatListItem extends StatelessWidget {
|
|||
final space = this.space;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 1,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 1),
|
||||
child: Material(
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
|
|
@ -96,7 +94,8 @@ class ChatListItem extends StatelessWidget {
|
|||
child: Avatar(
|
||||
border: BorderSide(
|
||||
width: 2,
|
||||
color: backgroundColor ??
|
||||
color:
|
||||
backgroundColor ??
|
||||
theme.colorScheme.surface,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(
|
||||
|
|
@ -114,14 +113,15 @@ class ChatListItem extends StatelessWidget {
|
|||
child: Avatar(
|
||||
border: space == null
|
||||
? room.isSpace
|
||||
? BorderSide(
|
||||
width: 1,
|
||||
color: theme.dividerColor,
|
||||
)
|
||||
: null
|
||||
? BorderSide(
|
||||
width: 1,
|
||||
color: theme.dividerColor,
|
||||
)
|
||||
: null
|
||||
: BorderSide(
|
||||
width: 2,
|
||||
color: backgroundColor ??
|
||||
color:
|
||||
backgroundColor ??
|
||||
theme.colorScheme.surface,
|
||||
),
|
||||
borderRadius: room.isSpace
|
||||
|
|
@ -182,10 +182,7 @@ class ChatListItem extends StatelessWidget {
|
|||
if (isMuted)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(left: 4.0),
|
||||
child: Icon(
|
||||
Icons.notifications_off_outlined,
|
||||
size: 16,
|
||||
),
|
||||
child: Icon(Icons.notifications_off_outlined, size: 16),
|
||||
),
|
||||
if (room.isFavourite)
|
||||
Padding(
|
||||
|
|
@ -202,8 +199,9 @@ class ChatListItem extends StatelessWidget {
|
|||
Padding(
|
||||
padding: const EdgeInsets.only(left: 4.0),
|
||||
child: Text(
|
||||
room.latestEventReceivedTime
|
||||
.localizedTimeShort(context),
|
||||
room.latestEventReceivedTime.localizedTimeShort(
|
||||
context,
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme.colorScheme.outline,
|
||||
|
|
@ -213,8 +211,8 @@ class ChatListItem extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
subtitle: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: .start,
|
||||
mainAxisAlignment: .center,
|
||||
children: <Widget>[
|
||||
if (typingText.isEmpty &&
|
||||
ownMessage &&
|
||||
|
|
@ -240,111 +238,111 @@ class ChatListItem extends StatelessWidget {
|
|||
),
|
||||
)
|
||||
: room.lastEvent?.relationshipType ==
|
||||
RelationshipTypes.thread
|
||||
? Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
RelationshipTypes.thread
|
||||
? Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConfig.borderRadius,
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
),
|
||||
margin: const EdgeInsets.only(right: 4.0),
|
||||
child: Row(
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.message_outlined,
|
||||
size: 12,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
L10n.of(context).thread,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConfig.borderRadius,
|
||||
),
|
||||
),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
margin: const EdgeInsets.only(right: 4.0),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.message_outlined,
|
||||
size: 12,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
L10n.of(context).thread,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
],
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
Expanded(
|
||||
child: room.isSpace && room.membership == Membership.join
|
||||
? Text(
|
||||
L10n.of(context)
|
||||
.countChats(room.spaceChildren.length),
|
||||
L10n.of(
|
||||
context,
|
||||
).countChats(room.spaceChildren.length),
|
||||
style: TextStyle(color: theme.colorScheme.outline),
|
||||
)
|
||||
: typingText.isNotEmpty
|
||||
? Text(
|
||||
typingText,
|
||||
style: TextStyle(
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
maxLines: 1,
|
||||
softWrap: false,
|
||||
)
|
||||
: FutureBuilder(
|
||||
key: ValueKey(
|
||||
'${lastEvent?.eventId}_${lastEvent?.type}_${lastEvent?.redacted}',
|
||||
),
|
||||
future: needLastEventSender
|
||||
? lastEvent.calcLocalizedBody(
|
||||
MatrixLocals(L10n.of(context)),
|
||||
hideReply: true,
|
||||
hideEdit: true,
|
||||
plaintextBody: true,
|
||||
removeMarkdown: true,
|
||||
withSenderNamePrefix: (!isDirectChat ||
|
||||
directChatMatrixId !=
|
||||
room.lastEvent?.senderId),
|
||||
)
|
||||
? Text(
|
||||
typingText,
|
||||
style: TextStyle(color: theme.colorScheme.primary),
|
||||
maxLines: 1,
|
||||
softWrap: false,
|
||||
)
|
||||
: FutureBuilder(
|
||||
key: ValueKey(
|
||||
'${lastEvent?.eventId}_${lastEvent?.type}_${lastEvent?.redacted}',
|
||||
),
|
||||
future: needLastEventSender
|
||||
? lastEvent.calcLocalizedBody(
|
||||
MatrixLocals(L10n.of(context)),
|
||||
hideReply: true,
|
||||
hideEdit: true,
|
||||
plaintextBody: true,
|
||||
removeMarkdown: true,
|
||||
withSenderNamePrefix:
|
||||
(!isDirectChat ||
|
||||
directChatMatrixId !=
|
||||
room.lastEvent?.senderId),
|
||||
)
|
||||
: null,
|
||||
initialData: lastEvent?.calcLocalizedBodyFallback(
|
||||
MatrixLocals(L10n.of(context)),
|
||||
hideReply: true,
|
||||
hideEdit: true,
|
||||
plaintextBody: true,
|
||||
removeMarkdown: true,
|
||||
withSenderNamePrefix:
|
||||
(!isDirectChat ||
|
||||
directChatMatrixId !=
|
||||
room.lastEvent?.senderId),
|
||||
),
|
||||
builder: (context, snapshot) => Text(
|
||||
room.membership == Membership.invite
|
||||
? room
|
||||
.getState(
|
||||
EventTypes.RoomMember,
|
||||
room.client.userID!,
|
||||
)
|
||||
?.content
|
||||
.tryGet<String>('reason') ??
|
||||
(isDirectChat
|
||||
? L10n.of(context).newChatRequest
|
||||
: L10n.of(context).inviteGroupChat)
|
||||
: snapshot.data ??
|
||||
L10n.of(context).noMessagesYet,
|
||||
softWrap: false,
|
||||
maxLines: room.notificationCount >= 1 ? 2 : 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: unread || room.hasNewMessages
|
||||
? theme.colorScheme.onSurface
|
||||
: theme.colorScheme.outline,
|
||||
decoration: room.lastEvent?.redacted == true
|
||||
? TextDecoration.lineThrough
|
||||
: null,
|
||||
initialData:
|
||||
lastEvent?.calcLocalizedBodyFallback(
|
||||
MatrixLocals(L10n.of(context)),
|
||||
hideReply: true,
|
||||
hideEdit: true,
|
||||
plaintextBody: true,
|
||||
removeMarkdown: true,
|
||||
withSenderNamePrefix: (!isDirectChat ||
|
||||
directChatMatrixId !=
|
||||
room.lastEvent?.senderId),
|
||||
),
|
||||
builder: (context, snapshot) => Text(
|
||||
room.membership == Membership.invite
|
||||
? room
|
||||
.getState(
|
||||
EventTypes.RoomMember,
|
||||
room.client.userID!,
|
||||
)
|
||||
?.content
|
||||
.tryGet<String>('reason') ??
|
||||
(isDirectChat
|
||||
? L10n.of(context).newChatRequest
|
||||
: L10n.of(context)
|
||||
.inviteGroupChat)
|
||||
: snapshot.data ??
|
||||
L10n.of(context).noMessagesYet,
|
||||
softWrap: false,
|
||||
maxLines: room.notificationCount >= 1 ? 2 : 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: unread || room.hasNewMessages
|
||||
? theme.colorScheme.onSurface
|
||||
: theme.colorScheme.outline,
|
||||
decoration: room.lastEvent?.redacted == true
|
||||
? TextDecoration.lineThrough
|
||||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
UnreadBubble(room: room),
|
||||
|
|
@ -353,27 +351,27 @@ class ChatListItem extends StatelessWidget {
|
|||
onTap: onTap,
|
||||
trailing: onForget == null
|
||||
? room.membership == Membership.invite
|
||||
? IconButton(
|
||||
tooltip: L10n.of(context).declineInvitation,
|
||||
icon: const Icon(Icons.delete_forever_outlined),
|
||||
color: theme.colorScheme.error,
|
||||
onPressed: () async {
|
||||
final consent = await showOkCancelAlertDialog(
|
||||
context: context,
|
||||
title: L10n.of(context).declineInvitation,
|
||||
message: L10n.of(context).areYouSure,
|
||||
okLabel: L10n.of(context).yes,
|
||||
isDestructive: true,
|
||||
);
|
||||
if (consent != OkCancelResult.ok) return;
|
||||
if (!context.mounted) return;
|
||||
await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: room.leave,
|
||||
);
|
||||
},
|
||||
)
|
||||
: null
|
||||
? IconButton(
|
||||
tooltip: L10n.of(context).declineInvitation,
|
||||
icon: const Icon(Icons.delete_forever_outlined),
|
||||
color: theme.colorScheme.error,
|
||||
onPressed: () async {
|
||||
final consent = await showOkCancelAlertDialog(
|
||||
context: context,
|
||||
title: L10n.of(context).declineInvitation,
|
||||
message: L10n.of(context).areYouSure,
|
||||
okLabel: L10n.of(context).yes,
|
||||
isDestructive: true,
|
||||
);
|
||||
if (consent != OkCancelResult.ok) return;
|
||||
if (!context.mounted) return;
|
||||
await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: room.leave,
|
||||
);
|
||||
},
|
||||
)
|
||||
: null
|
||||
: IconButton(
|
||||
icon: const Icon(Icons.delete_outlined),
|
||||
onPressed: onForget,
|
||||
|
|
|
|||
|
|
@ -38,10 +38,7 @@ class ChatListView extends StatelessWidget {
|
|||
onGoToChats: controller.clearActiveSpace,
|
||||
onGoToSpaceId: controller.setActiveSpace,
|
||||
),
|
||||
Container(
|
||||
color: Theme.of(context).dividerColor,
|
||||
width: 1,
|
||||
),
|
||||
Container(color: Theme.of(context).dividerColor, width: 1),
|
||||
],
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
|
|
@ -50,8 +47,8 @@ class ChatListView extends StatelessWidget {
|
|||
behavior: HitTestBehavior.translucent,
|
||||
child: Scaffold(
|
||||
body: ChatListViewBody(controller),
|
||||
floatingActionButton: !controller.isSearchMode &&
|
||||
controller.activeSpaceId == null
|
||||
floatingActionButton:
|
||||
!controller.isSearchMode && controller.activeSpaceId == null
|
||||
? FloatingActionButton.extended(
|
||||
onPressed: () => context.go('/rooms/newprivatechat'),
|
||||
icon: const Icon(Icons.add_outlined),
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ class ClientChooserButton extends StatelessWidget {
|
|||
(a, b) => a!.isValidMatrixId == b!.isValidMatrixId
|
||||
? 0
|
||||
: a.isValidMatrixId && !b.isValidMatrixId
|
||||
? -1
|
||||
: 1,
|
||||
? -1
|
||||
: 1,
|
||||
);
|
||||
return <PopupMenuEntry<Object>>[
|
||||
PopupMenuItem(
|
||||
|
|
@ -97,8 +97,8 @@ class ClientChooserButton extends StatelessWidget {
|
|||
PopupMenuItem(
|
||||
value: null,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: .start,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
Text(
|
||||
bundle!,
|
||||
|
|
@ -123,7 +123,8 @@ class ClientChooserButton extends StatelessWidget {
|
|||
children: [
|
||||
Avatar(
|
||||
mxContent: snapshot.data?.avatarUrl,
|
||||
name: snapshot.data?.displayName ??
|
||||
name:
|
||||
snapshot.data?.displayName ??
|
||||
client.userID!.localpart,
|
||||
size: 32,
|
||||
),
|
||||
|
|
@ -193,10 +194,7 @@ class ClientChooserButton extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
void _clientSelected(
|
||||
Object object,
|
||||
BuildContext context,
|
||||
) async {
|
||||
void _clientSelected(Object object, BuildContext context) async {
|
||||
if (object is Client) {
|
||||
controller.setActiveClient(object);
|
||||
} else if (object is String) {
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ class NaviRailItem extends StatelessWidget {
|
|||
child: AnimatedContainer(
|
||||
width: isSelected
|
||||
? FluffyThemes.isColumnMode(context)
|
||||
? 8
|
||||
: 4
|
||||
? 8
|
||||
: 4
|
||||
: 0,
|
||||
duration: FluffyThemes.animationDuration,
|
||||
curve: FluffyThemes.animationCurve,
|
||||
|
|
|
|||
|
|
@ -22,14 +22,8 @@ class SearchTitle extends StatelessWidget {
|
|||
|
||||
return Material(
|
||||
shape: Border(
|
||||
top: BorderSide(
|
||||
color: theme.dividerColor,
|
||||
width: 1,
|
||||
),
|
||||
bottom: BorderSide(
|
||||
color: theme.dividerColor,
|
||||
width: 1,
|
||||
),
|
||||
top: BorderSide(color: theme.dividerColor, width: 1),
|
||||
bottom: BorderSide(color: theme.dividerColor, width: 1),
|
||||
),
|
||||
color: color ?? theme.colorScheme.surface,
|
||||
child: InkWell(
|
||||
|
|
@ -38,10 +32,7 @@ class SearchTitle extends StatelessWidget {
|
|||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 8,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
child: IconTheme(
|
||||
data: theme.iconTheme.copyWith(size: 16),
|
||||
child: Row(
|
||||
|
|
|
|||
|
|
@ -28,12 +28,7 @@ enum AddRoomType { chat, subspace }
|
|||
|
||||
enum SpaceChildAction { edit, moveToSpace, removeFromSpace }
|
||||
|
||||
enum SpaceActions {
|
||||
settings,
|
||||
invite,
|
||||
members,
|
||||
leave,
|
||||
}
|
||||
enum SpaceActions { settings, invite, members, leave }
|
||||
|
||||
class SpaceView extends StatefulWidget {
|
||||
final String spaceId;
|
||||
|
|
@ -124,8 +119,9 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
} catch (e, s) {
|
||||
Logs().w('Unable to load hierarchy', e, s);
|
||||
if (!mounted) return;
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(SnackBar(content: Text(e.toLocalizedString(context))));
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text(e.toLocalizedString(context))));
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
|
|
@ -141,9 +137,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
builder: (_) => PublicRoomDialog(
|
||||
chunk: item,
|
||||
via: space?.spaceChildren
|
||||
.firstWhereOrNull(
|
||||
(child) => child.roomId == item.roomId,
|
||||
)
|
||||
.firstWhereOrNull((child) => child.roomId == item.roomId)
|
||||
?.via,
|
||||
),
|
||||
);
|
||||
|
|
@ -224,8 +218,9 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
if (roomType == AddRoomType.subspace) {
|
||||
roomId = await client.createSpace(
|
||||
name: names,
|
||||
visibility:
|
||||
isPublicSpace ? sdk.Visibility.public : sdk.Visibility.private,
|
||||
visibility: isPublicSpace
|
||||
? sdk.Visibility.public
|
||||
: sdk.Visibility.private,
|
||||
);
|
||||
} else {
|
||||
roomId = await client.createGroupChat(
|
||||
|
|
@ -234,8 +229,9 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
preset: isPublicSpace
|
||||
? CreateRoomPreset.publicChat
|
||||
: CreateRoomPreset.privateChat,
|
||||
visibility:
|
||||
isPublicSpace ? sdk.Visibility.public : sdk.Visibility.private,
|
||||
visibility: isPublicSpace
|
||||
? sdk.Visibility.public
|
||||
: sdk.Visibility.private,
|
||||
initialState: isPublicSpace
|
||||
? null
|
||||
: [
|
||||
|
|
@ -289,7 +285,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
PopupMenuItem(
|
||||
value: SpaceChildAction.moveToSpace,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
const Icon(Icons.move_down_outlined),
|
||||
const SizedBox(width: 12),
|
||||
|
|
@ -300,7 +296,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
PopupMenuItem(
|
||||
value: SpaceChildAction.edit,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
const Icon(Icons.edit_outlined),
|
||||
const SizedBox(width: 12),
|
||||
|
|
@ -311,7 +307,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
PopupMenuItem(
|
||||
value: SpaceChildAction.removeFromSpace,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
const Icon(Icons.group_remove_outlined),
|
||||
const SizedBox(width: 12),
|
||||
|
|
@ -344,8 +340,9 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
.map(
|
||||
(space) => AdaptiveModalAction(
|
||||
value: space,
|
||||
label: space
|
||||
.getLocalizedDisplayname(MatrixLocals(L10n.of(context))),
|
||||
label: space.getLocalizedDisplayname(
|
||||
MatrixLocals(L10n.of(context)),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
|
|
@ -392,19 +389,12 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
final displayname =
|
||||
room?.getLocalizedDisplayname() ?? L10n.of(context).nothingFound;
|
||||
const avatarSize = Avatar.defaultSize / 1.5;
|
||||
final isAdmin = room?.canChangeStateEvent(
|
||||
EventTypes.SpaceChild,
|
||||
) ==
|
||||
true;
|
||||
final isAdmin = room?.canChangeStateEvent(EventTypes.SpaceChild) == true;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: FluffyThemes.isColumnMode(context)
|
||||
? null
|
||||
: Center(
|
||||
child: CloseButton(
|
||||
onPressed: widget.onBack,
|
||||
),
|
||||
),
|
||||
: Center(child: CloseButton(onPressed: widget.onBack)),
|
||||
automaticallyImplyLeading: false,
|
||||
titleSpacing: FluffyThemes.isColumnMode(context) ? null : 0,
|
||||
title: ListTile(
|
||||
|
|
@ -432,7 +422,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
PopupMenuItem(
|
||||
value: AddRoomType.chat,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
const Icon(Icons.group_add_outlined),
|
||||
const SizedBox(width: 12),
|
||||
|
|
@ -443,7 +433,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
PopupMenuItem(
|
||||
value: AddRoomType.subspace,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
const Icon(Icons.workspaces_outlined),
|
||||
const SizedBox(width: 12),
|
||||
|
|
@ -460,7 +450,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
PopupMenuItem(
|
||||
value: SpaceActions.settings,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
const Icon(Icons.settings_outlined),
|
||||
const SizedBox(width: 12),
|
||||
|
|
@ -471,7 +461,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
PopupMenuItem(
|
||||
value: SpaceActions.invite,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
const Icon(Icons.person_add_outlined),
|
||||
const SizedBox(width: 12),
|
||||
|
|
@ -482,7 +472,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
PopupMenuItem(
|
||||
value: SpaceActions.members,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
const Icon(Icons.group_outlined),
|
||||
const SizedBox(width: 12),
|
||||
|
|
@ -497,7 +487,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
PopupMenuItem(
|
||||
value: SpaceActions.leave,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
const Icon(Icons.delete_outlined),
|
||||
const SizedBox(width: 12),
|
||||
|
|
@ -510,12 +500,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
],
|
||||
),
|
||||
body: room == null
|
||||
? const Center(
|
||||
child: Icon(
|
||||
Icons.search_outlined,
|
||||
size: 80,
|
||||
),
|
||||
)
|
||||
? const Center(child: Icon(Icons.search_outlined, size: 80))
|
||||
: StreamBuilder(
|
||||
stream: room.client.onSync.stream
|
||||
.where((s) => s.hasRoomUpdate)
|
||||
|
|
@ -573,7 +558,8 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
);
|
||||
}
|
||||
final item = _discoveredChildren[i];
|
||||
final displayname = item.name ??
|
||||
final displayname =
|
||||
item.name ??
|
||||
item.canonicalAlias ??
|
||||
L10n.of(context).emptyChat;
|
||||
if (!displayname.toLowerCase().contains(filter)) {
|
||||
|
|
@ -589,27 +575,31 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
vertical: 1,
|
||||
),
|
||||
child: Material(
|
||||
borderRadius:
|
||||
BorderRadius.circular(AppConfig.borderRadius),
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConfig.borderRadius,
|
||||
),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
color: joinedRoom != null &&
|
||||
color:
|
||||
joinedRoom != null &&
|
||||
widget.activeChat == joinedRoom.id
|
||||
? theme.colorScheme.secondaryContainer
|
||||
: Colors.transparent,
|
||||
child: HoverBuilder(
|
||||
builder: (context, hovered) => ListTile(
|
||||
visualDensity:
|
||||
const VisualDensity(vertical: -0.5),
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 8),
|
||||
visualDensity: const VisualDensity(
|
||||
vertical: -0.5,
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
),
|
||||
onTap: joinedRoom != null
|
||||
? () => widget.onChatTab(joinedRoom!)
|
||||
: () => _joinChildRoom(item),
|
||||
onLongPress: isAdmin
|
||||
? () => _showSpaceChildEditMenu(
|
||||
context,
|
||||
item.roomId,
|
||||
)
|
||||
context,
|
||||
item.roomId,
|
||||
)
|
||||
: null,
|
||||
leading: hovered && isAdmin
|
||||
? SizedBox.square(
|
||||
|
|
@ -618,16 +608,18 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
splashRadius: avatarSize,
|
||||
iconSize: 14,
|
||||
style: IconButton.styleFrom(
|
||||
foregroundColor: theme.colorScheme
|
||||
foregroundColor: theme
|
||||
.colorScheme
|
||||
.onTertiaryContainer,
|
||||
backgroundColor: theme
|
||||
.colorScheme.tertiaryContainer,
|
||||
.colorScheme
|
||||
.tertiaryContainer,
|
||||
),
|
||||
onPressed: () =>
|
||||
_showSpaceChildEditMenu(
|
||||
context,
|
||||
item.roomId,
|
||||
),
|
||||
context,
|
||||
item.roomId,
|
||||
),
|
||||
icon: const Icon(Icons.edit_outlined),
|
||||
),
|
||||
)
|
||||
|
|
@ -637,11 +629,13 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
name: '#',
|
||||
backgroundColor:
|
||||
theme.colorScheme.surfaceContainer,
|
||||
textColor: item.name?.darkColor ??
|
||||
textColor:
|
||||
item.name?.darkColor ??
|
||||
theme.colorScheme.onSurface,
|
||||
border: item.roomType == 'm.space'
|
||||
? BorderSide(
|
||||
color: theme.colorScheme
|
||||
color: theme
|
||||
.colorScheme
|
||||
.surfaceContainerHighest,
|
||||
)
|
||||
: null,
|
||||
|
|
|
|||
|
|
@ -13,10 +13,7 @@ import '../../widgets/adaptive_dialogs/user_dialog.dart';
|
|||
class StatusMessageList extends StatelessWidget {
|
||||
final void Function() onStatusEdit;
|
||||
|
||||
const StatusMessageList({
|
||||
required this.onStatusEdit,
|
||||
super.key,
|
||||
});
|
||||
const StatusMessageList({required this.onStatusEdit, super.key});
|
||||
|
||||
static const double height = 116;
|
||||
|
||||
|
|
@ -24,10 +21,7 @@ class StatusMessageList extends StatelessWidget {
|
|||
final client = Matrix.of(context).client;
|
||||
if (profile.userId == client.userID) return onStatusEdit();
|
||||
|
||||
UserDialog.show(
|
||||
context: context,
|
||||
profile: profile,
|
||||
);
|
||||
UserDialog.show(context: context, profile: profile);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -56,8 +50,9 @@ class StatusMessageList extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
builder: (context, snapshot) {
|
||||
final presences =
|
||||
snapshot.data?.where(isInterestingPresence).toList();
|
||||
final presences = snapshot.data
|
||||
?.where(isInterestingPresence)
|
||||
.toList();
|
||||
|
||||
// If no other presences than the own entry is interesting, we
|
||||
// hide the presence header.
|
||||
|
|
@ -121,7 +116,8 @@ class PresenceAvatar extends StatelessWidget {
|
|||
final theme = Theme.of(context);
|
||||
|
||||
final profile = snapshot.data;
|
||||
final displayName = profile?.displayName ??
|
||||
final displayName =
|
||||
profile?.displayName ??
|
||||
presence.userid.localpart ??
|
||||
presence.userid;
|
||||
final statusMsg = presence.statusMsg;
|
||||
|
|
@ -152,8 +148,9 @@ class PresenceAvatar extends StatelessWidget {
|
|||
padding: const EdgeInsets.all(3),
|
||||
decoration: BoxDecoration(
|
||||
gradient: presence.gradient,
|
||||
borderRadius:
|
||||
BorderRadius.circular(avatarSize),
|
||||
borderRadius: BorderRadius.circular(
|
||||
avatarSize,
|
||||
),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Container(
|
||||
|
|
@ -161,8 +158,9 @@ class PresenceAvatar extends StatelessWidget {
|
|||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.surface,
|
||||
borderRadius:
|
||||
BorderRadius.circular(avatarSize),
|
||||
borderRadius: BorderRadius.circular(
|
||||
avatarSize,
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.all(3.0),
|
||||
child: Avatar(
|
||||
|
|
@ -202,9 +200,8 @@ class PresenceAvatar extends StatelessWidget {
|
|||
right: 8,
|
||||
child: Column(
|
||||
spacing: 2,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: .start,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
Material(
|
||||
elevation: statusMsgBubbleElevation,
|
||||
|
|
@ -230,8 +227,9 @@ class PresenceAvatar extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 8.0),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 8.0,
|
||||
),
|
||||
child: Material(
|
||||
color: statusMsgBubbleColor,
|
||||
elevation: statusMsgBubbleElevation,
|
||||
|
|
@ -246,8 +244,9 @@ class PresenceAvatar extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 13.0),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 13.0,
|
||||
),
|
||||
child: Material(
|
||||
color: statusMsgBubbleColor,
|
||||
elevation: statusMsgBubbleElevation,
|
||||
|
|
@ -280,9 +279,7 @@ class PresenceAvatar extends StatelessWidget {
|
|||
textAlign: TextAlign.center,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 11,
|
||||
),
|
||||
style: const TextStyle(fontSize: 11),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
@ -296,10 +293,12 @@ class PresenceAvatar extends StatelessWidget {
|
|||
|
||||
extension on Client {
|
||||
Set<String> get interestingPresences {
|
||||
final allHeroes = rooms.map((room) => room.summary.mHeroes).fold(
|
||||
<String>{},
|
||||
(previousValue, element) => previousValue..addAll(element ?? {}),
|
||||
);
|
||||
final allHeroes = rooms
|
||||
.map((room) => room.summary.mHeroes)
|
||||
.fold(
|
||||
<String>{},
|
||||
(previousValue, element) => previousValue..addAll(element ?? {}),
|
||||
);
|
||||
allHeroes.add(userID!);
|
||||
return allHeroes;
|
||||
}
|
||||
|
|
@ -317,31 +316,23 @@ extension on CachedPresence {
|
|||
|
||||
LinearGradient get gradient => presence.isOnline == true
|
||||
? LinearGradient(
|
||||
colors: [
|
||||
Colors.green,
|
||||
Colors.green.shade200,
|
||||
Colors.green.shade900,
|
||||
],
|
||||
colors: [Colors.green, Colors.green.shade200, Colors.green.shade900],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
)
|
||||
: presence.isUnavailable
|
||||
? LinearGradient(
|
||||
colors: [
|
||||
Colors.yellow,
|
||||
Colors.yellow.shade200,
|
||||
Colors.yellow.shade900,
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
)
|
||||
: LinearGradient(
|
||||
colors: [
|
||||
Colors.grey,
|
||||
Colors.grey.shade200,
|
||||
Colors.grey.shade900,
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
);
|
||||
? LinearGradient(
|
||||
colors: [
|
||||
Colors.yellow,
|
||||
Colors.yellow.shade200,
|
||||
Colors.yellow.shade900,
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
)
|
||||
: LinearGradient(
|
||||
colors: [Colors.grey, Colors.grey.shade200, Colors.grey.shade900],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ class UnreadBubble extends StatelessWidget {
|
|||
final hasNotifications = room.notificationCount > 0;
|
||||
final unreadBubbleSize = unread || room.hasNewMessages
|
||||
? room.notificationCount > 0
|
||||
? 20.0
|
||||
: 14.0
|
||||
? 20.0
|
||||
: 14.0
|
||||
: 0.0;
|
||||
return AnimatedContainer(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
|
|
@ -27,13 +27,13 @@ class UnreadBubble extends StatelessWidget {
|
|||
width: !hasNotifications && !unread && !room.hasNewMessages
|
||||
? 0
|
||||
: (unreadBubbleSize - 9) * room.notificationCount.toString().length +
|
||||
9,
|
||||
9,
|
||||
decoration: BoxDecoration(
|
||||
color: room.highlightCount > 0
|
||||
? theme.colorScheme.error
|
||||
: hasNotifications || room.markedUnread
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.primaryContainer,
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
),
|
||||
child: hasNotifications
|
||||
|
|
@ -43,8 +43,8 @@ class UnreadBubble extends StatelessWidget {
|
|||
color: room.highlightCount > 0
|
||||
? theme.colorScheme.onError
|
||||
: hasNotifications
|
||||
? theme.colorScheme.onPrimary
|
||||
: theme.colorScheme.onPrimaryContainer,
|
||||
? theme.colorScheme.onPrimary
|
||||
: theme.colorScheme.onPrimaryContainer,
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue