mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2024-12-28 17:12:33 +01:00
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:
commit
dc62c2aaa3
@ -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": {}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user