chore: Follow up spaces UX
This commit is contained in:
parent
7fa7941f84
commit
765bff9e32
5 changed files with 25 additions and 89 deletions
|
|
@ -3383,5 +3383,14 @@
|
||||||
"moveToDifferentSpace": "Move to different space",
|
"moveToDifferentSpace": "Move to different space",
|
||||||
"moveUp": "Move up",
|
"moveUp": "Move up",
|
||||||
"moveDown": "Move down",
|
"moveDown": "Move down",
|
||||||
"removeFromSpaceDescription": "The chat will be removed from the space but still appear in your chat list."
|
"removeFromSpaceDescription": "The chat will be removed from the space but still appear in your chat list.",
|
||||||
|
"countChats": "{chats} chats",
|
||||||
|
"@countChats": {
|
||||||
|
"type": "String",
|
||||||
|
"placeholders": {
|
||||||
|
"chats": {
|
||||||
|
"type": "int"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,7 @@ class ChatListViewBody extends StatelessWidget {
|
||||||
spaceId: activeSpace,
|
spaceId: activeSpace,
|
||||||
onBack: controller.clearActiveSpace,
|
onBack: controller.clearActiveSpace,
|
||||||
onChatTab: (room) => controller.onChatTap(room),
|
onChatTab: (room) => controller.onChatTap(room),
|
||||||
onChatContext: (room, context) =>
|
|
||||||
controller.chatContextAction(room, context),
|
|
||||||
activeChat: controller.activeChat,
|
activeChat: controller.activeChat,
|
||||||
toParentSpace: controller.setActiveSpace,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
final spaces = client.rooms.where((r) => r.isSpace);
|
final spaces = client.rooms.where((r) => r.isSpace);
|
||||||
|
|
|
||||||
|
|
@ -242,10 +242,8 @@ class ChatListItem extends StatelessWidget {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: room.isSpace && room.membership == Membership.join
|
child: room.isSpace && room.membership == Membership.join
|
||||||
? Text(
|
? Text(
|
||||||
L10n.of(context).countChatsAndCountParticipants(
|
L10n.of(context)
|
||||||
room.spaceChildren.length,
|
.countChats(room.spaceChildren.length),
|
||||||
(room.summary.mJoinedMemberCount ?? 1),
|
|
||||||
),
|
|
||||||
style: TextStyle(color: theme.colorScheme.outline),
|
style: TextStyle(color: theme.colorScheme.outline),
|
||||||
)
|
)
|
||||||
: typingText.isNotEmpty
|
: typingText.isNotEmpty
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,7 @@ enum SpaceActions {
|
||||||
class SpaceView extends StatefulWidget {
|
class SpaceView extends StatefulWidget {
|
||||||
final String spaceId;
|
final String spaceId;
|
||||||
final void Function() onBack;
|
final void Function() onBack;
|
||||||
final void Function(String spaceId) toParentSpace;
|
|
||||||
final void Function(Room room) onChatTab;
|
final void Function(Room room) onChatTab;
|
||||||
final void Function(Room room, BuildContext context) onChatContext;
|
|
||||||
final String? activeChat;
|
final String? activeChat;
|
||||||
|
|
||||||
const SpaceView({
|
const SpaceView({
|
||||||
|
|
@ -48,8 +46,6 @@ class SpaceView extends StatefulWidget {
|
||||||
required this.onBack,
|
required this.onBack,
|
||||||
required this.onChatTab,
|
required this.onChatTab,
|
||||||
required this.activeChat,
|
required this.activeChat,
|
||||||
required this.toParentSpace,
|
|
||||||
required this.onChatContext,
|
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -525,25 +521,6 @@ class _SpaceViewState extends State<SpaceView> {
|
||||||
.where((s) => s.hasRoomUpdate)
|
.where((s) => s.hasRoomUpdate)
|
||||||
.rateLimit(const Duration(seconds: 1)),
|
.rateLimit(const Duration(seconds: 1)),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
final childrenIds = room.spaceChildren
|
|
||||||
.map((c) => c.roomId)
|
|
||||||
.whereType<String>()
|
|
||||||
.toSet();
|
|
||||||
|
|
||||||
final joinedRooms = Map.fromEntries(
|
|
||||||
room.client.rooms
|
|
||||||
.where((room) => childrenIds.remove(room.id))
|
|
||||||
.map((room) => MapEntry(room.id, room)),
|
|
||||||
);
|
|
||||||
|
|
||||||
final joinedParents = room.spaceParents
|
|
||||||
.map((parent) {
|
|
||||||
final roomId = parent.roomId;
|
|
||||||
if (roomId == null) return null;
|
|
||||||
return room.client.getRoomById(roomId);
|
|
||||||
})
|
|
||||||
.whereType<Room>()
|
|
||||||
.toList();
|
|
||||||
final filter = _filterController.text.trim().toLowerCase();
|
final filter = _filterController.text.trim().toLowerCase();
|
||||||
return CustomScrollView(
|
return CustomScrollView(
|
||||||
slivers: [
|
slivers: [
|
||||||
|
|
@ -575,47 +552,6 @@ class _SpaceViewState extends State<SpaceView> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SliverList.builder(
|
|
||||||
itemCount: joinedParents.length,
|
|
||||||
itemBuilder: (context, i) {
|
|
||||||
final displayname =
|
|
||||||
joinedParents[i].getLocalizedDisplayname();
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 8,
|
|
||||||
vertical: 1,
|
|
||||||
),
|
|
||||||
child: Material(
|
|
||||||
borderRadius:
|
|
||||||
BorderRadius.circular(AppConfig.borderRadius),
|
|
||||||
clipBehavior: Clip.hardEdge,
|
|
||||||
child: ListTile(
|
|
||||||
minVerticalPadding: 0,
|
|
||||||
leading: Icon(
|
|
||||||
Icons.adaptive.arrow_back_outlined,
|
|
||||||
size: 16,
|
|
||||||
),
|
|
||||||
title: Row(
|
|
||||||
children: [
|
|
||||||
Avatar(
|
|
||||||
mxContent: joinedParents[i].avatar,
|
|
||||||
name: displayname,
|
|
||||||
size: Avatar.defaultSize / 2,
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
AppConfig.borderRadius / 4,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
Expanded(child: Text(displayname)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
onTap: () =>
|
|
||||||
widget.toParentSpace(joinedParents[i].id),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SliverList.builder(
|
SliverList.builder(
|
||||||
itemCount: _discoveredChildren.length + 1,
|
itemCount: _discoveredChildren.length + 1,
|
||||||
itemBuilder: (context, i) {
|
itemBuilder: (context, i) {
|
||||||
|
|
@ -643,7 +579,10 @@ class _SpaceViewState extends State<SpaceView> {
|
||||||
if (!displayname.toLowerCase().contains(filter)) {
|
if (!displayname.toLowerCase().contains(filter)) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
final joinedRoom = joinedRooms[item.roomId];
|
var joinedRoom = room.client.getRoomById(item.roomId);
|
||||||
|
if (joinedRoom?.membership == Membership.leave) {
|
||||||
|
joinedRoom = null;
|
||||||
|
}
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 8,
|
horizontal: 8,
|
||||||
|
|
@ -664,7 +603,7 @@ class _SpaceViewState extends State<SpaceView> {
|
||||||
contentPadding:
|
contentPadding:
|
||||||
const EdgeInsets.symmetric(horizontal: 8),
|
const EdgeInsets.symmetric(horizontal: 8),
|
||||||
onTap: joinedRoom != null
|
onTap: joinedRoom != null
|
||||||
? () => widget.onChatTab(joinedRoom)
|
? () => widget.onChatTab(joinedRoom!)
|
||||||
: () => _joinChildRoom(item),
|
: () => _joinChildRoom(item),
|
||||||
onLongPress: isAdmin
|
onLongPress: isAdmin
|
||||||
? () => _showSpaceChildEditMenu(
|
? () => _showSpaceChildEditMenu(
|
||||||
|
|
|
||||||
|
|
@ -43,15 +43,8 @@ class SpacesNavigationRail extends StatelessWidget {
|
||||||
.where((s) => s.hasRoomUpdate)
|
.where((s) => s.hasRoomUpdate)
|
||||||
.rateLimit(const Duration(seconds: 1)),
|
.rateLimit(const Duration(seconds: 1)),
|
||||||
builder: (context, _) {
|
builder: (context, _) {
|
||||||
final allSpaces = client.rooms.where((room) => room.isSpace);
|
final allSpaces =
|
||||||
final rootSpaces = allSpaces
|
client.rooms.where((room) => room.isSpace).toList();
|
||||||
.where(
|
|
||||||
(space) => !allSpaces.any(
|
|
||||||
(parentSpace) => parentSpace.spaceChildren
|
|
||||||
.any((child) => child.roomId == space.id),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: FluffyThemes.isColumnMode(context)
|
width: FluffyThemes.isColumnMode(context)
|
||||||
|
|
@ -62,7 +55,7 @@ class SpacesNavigationRail extends StatelessWidget {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection: Axis.vertical,
|
||||||
itemCount: rootSpaces.length + 2,
|
itemCount: allSpaces.length + 2,
|
||||||
itemBuilder: (context, i) {
|
itemBuilder: (context, i) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
return NaviRailItem(
|
return NaviRailItem(
|
||||||
|
|
@ -81,7 +74,7 @@ class SpacesNavigationRail extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
i--;
|
i--;
|
||||||
if (i == rootSpaces.length) {
|
if (i == allSpaces.length) {
|
||||||
return NaviRailItem(
|
return NaviRailItem(
|
||||||
isSelected: false,
|
isSelected: false,
|
||||||
onTap: () => context.go('/rooms/newspace'),
|
onTap: () => context.go('/rooms/newspace'),
|
||||||
|
|
@ -92,9 +85,9 @@ class SpacesNavigationRail extends StatelessWidget {
|
||||||
toolTip: L10n.of(context).createNewSpace,
|
toolTip: L10n.of(context).createNewSpace,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
final space = rootSpaces[i];
|
final space = allSpaces[i];
|
||||||
final displayname =
|
final displayname =
|
||||||
rootSpaces[i].getLocalizedDisplayname(
|
allSpaces[i].getLocalizedDisplayname(
|
||||||
MatrixLocals(L10n.of(context)),
|
MatrixLocals(L10n.of(context)),
|
||||||
);
|
);
|
||||||
final spaceChildrenIds =
|
final spaceChildrenIds =
|
||||||
|
|
@ -102,11 +95,11 @@ class SpacesNavigationRail extends StatelessWidget {
|
||||||
return NaviRailItem(
|
return NaviRailItem(
|
||||||
toolTip: displayname,
|
toolTip: displayname,
|
||||||
isSelected: activeSpaceId == space.id,
|
isSelected: activeSpaceId == space.id,
|
||||||
onTap: () => onGoToSpaceId(rootSpaces[i].id),
|
onTap: () => onGoToSpaceId(allSpaces[i].id),
|
||||||
unreadBadgeFilter: (room) =>
|
unreadBadgeFilter: (room) =>
|
||||||
spaceChildrenIds.contains(room.id),
|
spaceChildrenIds.contains(room.id),
|
||||||
icon: Avatar(
|
icon: Avatar(
|
||||||
mxContent: rootSpaces[i].avatar,
|
mxContent: allSpaces[i].avatar,
|
||||||
name: displayname,
|
name: displayname,
|
||||||
border: BorderSide(
|
border: BorderSide(
|
||||||
width: 1,
|
width: 1,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue