feat: Light implementation of spaces drawer

This commit is contained in:
Christian Pauly 2021-08-01 07:45:34 +02:00
parent 0c0602a0a7
commit d3f87aeaad
3 changed files with 335 additions and 268 deletions

View File

@ -44,6 +44,9 @@ void main() async {
KeyVerificationMethod.emoji, KeyVerificationMethod.emoji,
}, },
importantStateEvents: <String>{ importantStateEvents: <String>{
EventTypes.spaceChild,
EventTypes.spaceParent,
EventTypes.RoomCreate,
'im.ponies.room_emotes', // we want emotes to work properly 'im.ponies.room_emotes', // we want emotes to work properly
}, },
databaseBuilder: FlutterMatrixHiveStore.hiveDatabaseBuilder, databaseBuilder: FlutterMatrixHiveStore.hiveDatabaseBuilder,

View File

@ -40,6 +40,17 @@ class ChatListController extends State<ChatList> {
StreamSubscription _intentUriStreamSubscription; StreamSubscription _intentUriStreamSubscription;
String _activeSpaceId;
String get activeSpaceId => _activeSpaceId;
void setActiveSpaceId(BuildContext context, String spaceId) {
Scaffold.of(context).openEndDrawer();
setState(() => _activeSpaceId = spaceId);
}
List<Room> get spaces =>
Matrix.of(context).client.rooms.where((r) => r.isSpace).toList();
final selectedRoomIds = <String>{}; final selectedRoomIds = <String>{};
Future<bool> crossSigningCachedFuture; Future<bool> crossSigningCachedFuture;
bool crossSigningCached; bool crossSigningCached;

View File

@ -1,3 +1,4 @@
import 'package:fluffychat/widgets/avatar.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
import 'package:fluffychat/pages/chat_list.dart'; import 'package:fluffychat/pages/chat_list.dart';
import 'package:fluffychat/widgets/connection_status_header.dart'; import 'package:fluffychat/widgets/connection_status_header.dart';
@ -31,13 +32,20 @@ class ChatListView extends StatelessWidget {
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: AppBar(
leading: selectMode == SelectMode.normal leading: selectMode == SelectMode.normal
? controller.spaces.isEmpty
? null ? null
: Builder(
builder: (context) => IconButton(
icon: Icon(Icons.group_work_outlined),
onPressed: Scaffold.of(context).openDrawer,
))
: IconButton( : IconButton(
tooltip: L10n.of(context).cancel, tooltip: L10n.of(context).cancel,
icon: Icon(Icons.close_outlined), icon: Icon(Icons.close_outlined),
onPressed: controller.cancelAction, onPressed: controller.cancelAction,
), ),
centerTitle: false, centerTitle: false,
titleSpacing: controller.spaces.isEmpty ? null : 0,
actions: selectMode == SelectMode.share actions: selectMode == SelectMode.share
? null ? null
: selectMode == SelectMode.select : selectMode == SelectMode.select
@ -152,7 +160,12 @@ class ChatListView extends StatelessWidget {
: selectMode == SelectMode.select : selectMode == SelectMode.select
? L10n.of(context).numberSelected( ? L10n.of(context).numberSelected(
controller.selectedRoomIds.length.toString()) controller.selectedRoomIds.length.toString())
: AppConfig.applicationName), : controller.activeSpaceId == null
? AppConfig.applicationName
: Matrix.of(context)
.client
.getRoomById(controller.activeSpaceId)
.displayname),
), ),
body: Column(children: [ body: Column(children: [
ConnectionStatusHeader(), ConnectionStatusHeader(),
@ -170,7 +183,15 @@ class ChatListView extends StatelessWidget {
builder: (BuildContext context, snapshot) { builder: (BuildContext context, snapshot) {
if (Matrix.of(context).client.prevBatch != null) { if (Matrix.of(context).client.prevBatch != null) {
final rooms = List<Room>.from( final rooms = List<Room>.from(
Matrix.of(context).client.rooms); Matrix.of(context).client.rooms)
.where((r) => !r.isSpace)
.toList();
if (controller.activeSpaceId != null) {
rooms.removeWhere((room) => !room.spaceParents
.any((parent) =>
parent.roomId ==
controller.activeSpaceId));
}
rooms.removeWhere( rooms.removeWhere(
(room) => room.lastEvent == null); (room) => room.lastEvent == null);
if (rooms.isEmpty) { if (rooms.isEmpty) {
@ -202,8 +223,8 @@ class ChatListView extends StatelessWidget {
itemBuilder: (BuildContext context, int i) { itemBuilder: (BuildContext context, int i) {
if (i == 0) { if (i == 0) {
return FutureBuilder( return FutureBuilder(
future: controller future:
.crossSigningCachedFuture, controller.crossSigningCachedFuture,
builder: (context, snapshot) { builder: (context, snapshot) {
final needsBootstrap = final needsBootstrap =
Matrix.of(context) Matrix.of(context)
@ -221,8 +242,7 @@ class ChatListView extends StatelessWidget {
needsBootstrap || needsBootstrap ||
isUnknownSession; isUnknownSession;
if (!displayHeader || if (!displayHeader ||
controller controller.hideChatBackupBanner) {
.hideChatBackupBanner) {
return Container(); return Container();
} }
return Material( return Material(
@ -244,8 +264,8 @@ class ChatListView extends StatelessWidget {
onPressed: controller onPressed: controller
.hideChatBackupBannerAction, .hideChatBackupBannerAction,
), ),
title: Text(L10n.of(context) title: Text(
.chatBackup), L10n.of(context).chatBackup),
subtitle: Text(L10n.of(context) subtitle: Text(L10n.of(context)
.enableChatBackup), .enableChatBackup),
onTap: controller onTap: controller
@ -263,8 +283,8 @@ class ChatListView extends StatelessWidget {
? () => controller ? () => controller
.toggleSelection(rooms[i].id) .toggleSelection(rooms[i].id)
: null, : null,
onLongPress: () => controller onLongPress: () =>
.toggleSelection(rooms[i].id), controller.toggleSelection(rooms[i].id),
activeChat: activeChat:
controller.activeChat == rooms[i].id, controller.activeChat == rooms[i].id,
); );
@ -280,8 +300,7 @@ class ChatListView extends StatelessWidget {
width: 100, width: 100,
), ),
Text( Text(
L10n.of(context) L10n.of(context).yourChatsAreBeingSynced,
.yourChatsAreBeingSynced,
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
], ],
@ -301,7 +320,41 @@ class ChatListView extends StatelessWidget {
child: Icon(CupertinoIcons.chat_bubble), child: Icon(CupertinoIcons.chat_bubble),
) )
: null, : null,
)); drawer: controller.spaces.isEmpty
? null
: Drawer(
child: SafeArea(
child: ListView.builder(
itemCount: controller.spaces.length + 1,
itemBuilder: (context, i) {
if (i == 0) {
return ListTile(
leading: CircleAvatar(
foregroundColor:
Theme.of(context).primaryColor,
backgroundColor:
Theme.of(context).secondaryHeaderColor,
radius: Avatar.defaultSize / 2,
child: Icon(Icons.home_outlined),
),
title: Text(L10n.of(context).chats),
onTap: () =>
controller.setActiveSpaceId(context, null),
);
}
final space = controller.spaces[i - 1];
return ListTile(
leading: Avatar(space.avatar, space.displayname),
title: Text(space.displayname),
onTap: () => controller.setActiveSpaceId(
context, space.id),
);
},
),
),
),
),
);
}); });
} }
} }