refactor: ChatListView and enforce bootstrap

onboarding
Christian Pauly 4 years ago
parent bdae763525
commit 75e11b0c54

@ -154,6 +154,18 @@ class ChatListController extends State<ChatList> {
@override @override
void initState() { void initState() {
_initReceiveSharingIntent(); _initReceiveSharingIntent();
WidgetsBinding.instance.addPostFrameCallback((_) async {
if (!Matrix.of(context).client.encryptionEnabled) return;
final crossSigning = await crossSigningCachedFuture;
final needsBootstrap =
Matrix.of(context).client.encryption?.crossSigning?.enabled ==
false ||
crossSigning == false;
final isUnknownSession = Matrix.of(context).client.isUnknownSession;
if (needsBootstrap || isUnknownSession) {
firstRunBootstrapAction();
}
});
super.initState(); super.initState();
} }

@ -180,8 +180,66 @@ class ChatListView extends StatelessWidget {
), ),
body: Column(children: [ body: Column(children: [
ConnectionStatusHeader(), ConnectionStatusHeader(),
Expanded( Expanded(child: _ChatListViewBody(controller)),
child: StreamBuilder( ]),
floatingActionButton: selectMode == SelectMode.normal
? FloatingActionButton(
heroTag: 'main_fab',
onPressed: () =>
VRouter.of(context).to('/newprivatechat'),
child: Icon(CupertinoIcons.chat_bubble),
)
: 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),
trailing: IconButton(
icon: Icon(Icons.edit_outlined),
onPressed: () =>
controller.editSpace(context, space.id),
),
);
},
),
),
),
),
);
});
}
}
class _ChatListViewBody extends StatelessWidget {
final ChatListController controller;
const _ChatListViewBody(this.controller, {Key key}) : super(key: key);
@override
Widget build(BuildContext context) => StreamBuilder(
stream: Matrix.of(context) stream: Matrix.of(context)
.client .client
.onSync .onSync
@ -193,18 +251,14 @@ class ChatListView extends StatelessWidget {
future: controller.waitForFirstSync(), future: controller.waitForFirstSync(),
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) .where((r) => !r.isSpace)
.toList(); .toList();
if (controller.activeSpaceId != null) { if (controller.activeSpaceId != null) {
rooms.removeWhere((room) => !room.spaceParents rooms.removeWhere((room) => !room.spaceParents.any(
.any((parent) => (parent) => parent.roomId == controller.activeSpaceId));
parent.roomId ==
controller.activeSpaceId));
} }
rooms.removeWhere( rooms.removeWhere((room) => room.lastEvent == null);
(room) => room.lastEvent == null);
if (rooms.isEmpty) { if (rooms.isEmpty) {
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@ -228,76 +282,18 @@ class ChatListView extends StatelessWidget {
], ],
); );
} }
final totalCount = rooms.length + 1; final totalCount = rooms.length;
return ListView.builder( return ListView.builder(
itemCount: totalCount, itemCount: totalCount,
itemBuilder: (BuildContext context, int i) { itemBuilder: (BuildContext context, int i) {
if (i == 0) {
return FutureBuilder(
future:
controller.crossSigningCachedFuture,
builder: (context, snapshot) {
final needsBootstrap =
Matrix.of(context)
.client
.encryption
?.crossSigning
?.enabled ==
false ||
snapshot.data == false;
final isUnknownSession =
Matrix.of(context)
.client
.isUnknownSession;
final displayHeader =
needsBootstrap ||
isUnknownSession;
if (!displayHeader ||
controller.hideChatBackupBanner) {
return Container();
}
return Material(
color: Theme.of(context)
.secondaryHeaderColor,
child: ListTile(
leading: CircleAvatar(
backgroundColor: Theme.of(
context)
.scaffoldBackgroundColor,
foregroundColor:
Theme.of(context)
.colorScheme
.secondaryVariant,
child: Icon(Icons.cloud),
),
trailing: IconButton(
icon: Icon(Icons.close),
onPressed: controller
.hideChatBackupBannerAction,
),
title: Text(
L10n.of(context).chatBackup),
subtitle: Text(L10n.of(context)
.enableChatBackup),
onTap: controller
.firstRunBootstrapAction,
),
);
});
}
i--;
return ChatListItem( return ChatListItem(
rooms[i], rooms[i],
selected: controller.selectedRoomIds selected: controller.selectedRoomIds.contains(rooms[i].id),
.contains(rooms[i].id), onTap: controller.selectMode == SelectMode.select
onTap: selectMode == SelectMode.select ? () => controller.toggleSelection(rooms[i].id)
? () => controller
.toggleSelection(rooms[i].id)
: null, : null,
onLongPress: () => onLongPress: () => controller.toggleSelection(rooms[i].id),
controller.toggleSelection(rooms[i].id), activeChat: controller.activeChat == rooms[i].id,
activeChat:
controller.activeChat == rooms[i].id,
); );
}, },
); );
@ -320,59 +316,7 @@ class ChatListView extends StatelessWidget {
} }
}, },
); );
}),
),
]),
floatingActionButton: selectMode == SelectMode.normal
? FloatingActionButton(
heroTag: 'main_fab',
onPressed: () =>
VRouter.of(context).to('/newprivatechat'),
child: Icon(CupertinoIcons.chat_bubble),
)
: 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),
trailing: IconButton(
icon: Icon(Icons.edit_outlined),
onPressed: () =>
controller.editSpace(context, space.id),
),
);
},
),
),
),
),
);
}); });
}
} }
enum ChatListPopupMenuItemActions { enum ChatListPopupMenuItemActions {

Loading…
Cancel
Save