refactor: Update to Dart 3.10 with . shorthands

This commit is contained in:
Christian Kußowski 2025-11-30 12:54:06 +01:00
commit 1ea649f01e
No known key found for this signature in database
GPG key ID: E067ECD60F1A0652
167 changed files with 3351 additions and 3912 deletions

View file

@ -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,

View file

@ -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),
),
),
),
);
],
),
),
);
}

View file

@ -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)),
),
);
},

View file

@ -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,

View file

@ -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),

View file

@ -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) {

View file

@ -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,

View file

@ -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(

View file

@ -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,

View file

@ -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,
);
}

View file

@ -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,
),