Merge branch 'krille/better-chat-list-page' into 'main'

Krille/better chat list page

See merge request famedly/fluffychat!653
This commit is contained in:
Krille Fear 2021-12-30 09:17:02 +00:00
commit dc62c2aaa3
4 changed files with 97 additions and 134 deletions

View File

@ -2182,7 +2182,7 @@
"senderName": {}
}
},
"startYourFirstChat": "Start your first chat right now! 🙂\n- Tap on the message button\n- Enter the username of a friend\n- Have fun chatting",
"startYourFirstChat": "Start your first chat right now! 🙂\n- Tap on 'New chat'\n- Scan the QR code of a friend\n- Have fun chatting",
"@startYourFirstChat": {
"type": "text",
"placeholders": {}

View File

@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -284,10 +283,10 @@ class _ChatListViewBodyState extends State<_ChatListViewBody> {
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Icon(
Icons.maps_ugc_outlined,
size: 80,
color: Colors.grey,
Image.asset(
'assets/private_chat_wallpaper.png',
width: 160,
height: 160,
),
Center(
child: Text(
@ -301,37 +300,90 @@ class _ChatListViewBodyState extends State<_ChatListViewBody> {
),
],
);
}
final displayStoriesHeader = widget.controller.activeSpaceId == null;
child = ListView.builder(
key: ValueKey(Matrix.of(context).client.userID.toString() +
widget.controller.activeSpaceId.toString()),
controller: widget.controller.scrollController,
itemCount: rooms.length + (displayStoriesHeader ? 1 : 0),
itemBuilder: (BuildContext context, int i) {
if (displayStoriesHeader) {
if (i == 0) {
return const StoriesHeader();
} else {
final displayStoriesHeader = widget.controller.activeSpaceId == null;
child = ListView.builder(
key: ValueKey(Matrix.of(context).client.userID.toString() +
widget.controller.activeSpaceId.toString()),
controller: widget.controller.scrollController,
itemCount: rooms.length + (displayStoriesHeader ? 1 : 0),
itemBuilder: (BuildContext context, int i) {
if (displayStoriesHeader) {
if (i == 0) {
return const StoriesHeader();
}
i--;
}
i--;
}
return ChatListItem(
rooms[i],
selected: widget.controller.selectedRoomIds.contains(rooms[i].id),
onTap: widget.controller.selectMode == SelectMode.select
? () => widget.controller.toggleSelection(rooms[i].id)
: null,
onLongPress: () => widget.controller.toggleSelection(rooms[i].id),
activeChat: widget.controller.activeChat == rooms[i].id,
);
},
);
return ChatListItem(
rooms[i],
selected: widget.controller.selectedRoomIds.contains(rooms[i].id),
onTap: widget.controller.selectMode == SelectMode.select
? () => widget.controller.toggleSelection(rooms[i].id)
: null,
onLongPress: () => widget.controller.toggleSelection(rooms[i].id),
activeChat: widget.controller.activeChat == rooms[i].id,
);
},
);
}
} else {
child = ListView(
key: const ValueKey(false),
children: List.filled(
8,
const _DummyChat(),
const dummyChatCount = 8;
final titleColor =
Theme.of(context).textTheme.bodyText1.color.withAlpha(100);
final subtitleColor =
Theme.of(context).textTheme.bodyText1.color.withAlpha(50);
child = ListView.builder(
itemCount: dummyChatCount,
itemBuilder: (context, i) => Opacity(
opacity: (dummyChatCount - i) / dummyChatCount,
child: ListTile(
leading: CircleAvatar(
backgroundColor: titleColor,
child: CircularProgressIndicator(
strokeWidth: 1,
color: Theme.of(context).textTheme.bodyText1.color,
),
),
title: Row(
children: [
Expanded(
child: Container(
height: 14,
decoration: BoxDecoration(
color: titleColor,
borderRadius: BorderRadius.circular(3),
),
),
),
const SizedBox(width: 36),
Container(
height: 14,
width: 14,
decoration: BoxDecoration(
color: subtitleColor,
borderRadius: BorderRadius.circular(14),
),
),
const SizedBox(width: 12),
Container(
height: 14,
width: 14,
decoration: BoxDecoration(
color: subtitleColor,
borderRadius: BorderRadius.circular(14),
),
),
],
),
subtitle: Container(
decoration: BoxDecoration(
color: subtitleColor,
borderRadius: BorderRadius.circular(3),
),
height: 12,
margin: const EdgeInsets.only(right: 22),
),
),
),
);
}
@ -389,100 +441,6 @@ class _ChatListViewBodyState extends State<_ChatListViewBody> {
}
}
class _DummyChat extends StatefulWidget {
const _DummyChat({Key key}) : super(key: key);
@override
State<_DummyChat> createState() => _DummyChatState();
}
class _DummyChatState extends State<_DummyChat> {
double opacity = Random().nextDouble();
Timer _timer;
static const duration = Duration(seconds: 1);
void _setRandomOpacity(_) {
if (mounted) {
setState(() => opacity = Random().nextDouble());
}
}
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback(_setRandomOpacity);
_timer ??= Timer.periodic(duration, _setRandomOpacity);
super.initState();
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
final titleColor =
Theme.of(context).textTheme.bodyText1.color.withAlpha(100);
final subtitleColor =
Theme.of(context).textTheme.bodyText1.color.withAlpha(50);
return AnimatedOpacity(
opacity: opacity,
duration: duration,
child: ListTile(
leading: CircleAvatar(
backgroundColor: titleColor,
child: CircularProgressIndicator(
strokeWidth: 1,
color: Theme.of(context).textTheme.bodyText1.color,
),
),
title: Row(
children: [
Expanded(
child: Container(
height: 14,
decoration: BoxDecoration(
color: titleColor,
borderRadius: BorderRadius.circular(3),
),
),
),
const SizedBox(width: 36),
Container(
height: 14,
width: 14,
decoration: BoxDecoration(
color: subtitleColor,
borderRadius: BorderRadius.circular(14),
),
),
const SizedBox(width: 12),
Container(
height: 14,
width: 14,
decoration: BoxDecoration(
color: subtitleColor,
borderRadius: BorderRadius.circular(14),
),
),
],
),
subtitle: Container(
decoration: BoxDecoration(
color: subtitleColor,
borderRadius: BorderRadius.circular(3),
),
height: 12,
margin: const EdgeInsets.only(right: 22),
),
),
);
}
}
enum ChatListPopupMenuItemActions {
createGroup,
createSpace,

View File

@ -112,8 +112,8 @@ class SearchController extends State<Search> {
@override
void initState() {
super.initState();
controller.text = VRouter.of(context).queryParameters['query'] ?? '';
WidgetsBinding.instance?.addPostFrameCallback((_) async {
controller.text = VRouter.of(context).queryParameters['query'] ?? '';
final server = await Store().getItem(_serverStoreNamespace) as String?;
if (server?.isNotEmpty ?? false) {
this.server = server;

View File

@ -87,10 +87,11 @@ class StoryView extends StatelessWidget {
child: PopupMenuButton<PopupStoryAction>(
onSelected: controller.onPopupStoryAction,
itemBuilder: (context) => [
PopupMenuItem(
value: PopupStoryAction.delete,
child: Text(L10n.of(context)!.delete),
),
if (controller.currentEvent?.canRedact ?? false)
PopupMenuItem(
value: PopupStoryAction.delete,
child: Text(L10n.of(context)!.delete),
),
PopupMenuItem(
value: PopupStoryAction.report,
child: Text(L10n.of(context)!.reportMessage),
@ -336,6 +337,10 @@ class StoryView extends StatelessWidget {
child: SafeArea(
child: Center(
child: OutlinedButton.icon(
style: OutlinedButton.styleFrom(
backgroundColor:
Theme.of(context).colorScheme.surface,
),
onPressed: controller.displaySeenByUsers,
icon: const Icon(
Icons.visibility_outlined,