Skip to content

Commit 5890637

Browse files
authored
chore: improve video thumbnails and message bubble shapes (#90)
1 parent cc0594e commit 5890637

10 files changed

+57
-44
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ or
3737

3838
Run scripts/prepare-web.sh
3939

40+
### macos
41+
42+
cp /Users/frederik/Downloads/libcrypto.1.1.dylib ~/Projects/nebuchadnezzar/build/macos/Build/Products/Debug/nebuchadnezzar.app/Contents/Frameworks
43+
44+
4045

4146
## Credits: Fluffy-Chat
4247

@@ -46,3 +51,4 @@ Thank you for your awesome dart sdk!
4651
## Why this name?
4752

4853
The name is inspired by the traveling vehicle from the movie Matrix, which uses the name of https://en.wikipedia.org/wiki/Nebuchadnezzar_II the second king of Babylon!
54+

lib/chat_room/timeline/chat_room_pinned_events_dialog.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class _ChatRoomPinnedEventTileState extends State<ChatRoomPinnedEventTile> {
8181
event: s.data!,
8282
timeline: widget.timeline,
8383
onReplyOriginClick: (p0) async {},
84-
eventPosition: EventPosition.top,
84+
eventPosition: EventPosition.semanticSingle,
8585
)
8686
: const Text(''),
8787
);

lib/common/event_x.dart

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -98,31 +98,37 @@ extension EventX on Event {
9898
required bool showAvatarChanges,
9999
required bool showDisplayNameChanges,
100100
}) {
101-
if (prev == null && next == null) {
102-
return EventPosition.top;
103-
}
104-
if (prev == null ||
105-
prev.hideInTimeline(
101+
final prevHidden =
102+
prev?.hideInTimeline(
106103
showAvatarChanges: showAvatarChanges,
107104
showDisplayNameChanges: showDisplayNameChanges,
108-
) ||
109-
prev.showAsBadge) {
110-
return EventPosition.top;
111-
}
105+
) ??
106+
true;
107+
final nextHidden =
108+
next?.hideInTimeline(
109+
showAvatarChanges: showAvatarChanges,
110+
showDisplayNameChanges: showDisplayNameChanges,
111+
) ??
112+
true;
112113

113-
if (prev.senderId != senderId) {
114-
return EventPosition.top;
114+
final prevVisible = !prevHidden && !(prev?.showAsBadge ?? true);
115+
final nextVisible = !nextHidden && !(next?.showAsBadge ?? true);
116+
117+
// Single event
118+
if ((!prevVisible && !nextVisible) ||
119+
(next?.senderId != senderId && prev?.senderId != senderId)) {
120+
return EventPosition.semanticSingle;
115121
}
116-
if (prev.originServerTs.toLocal().day != originServerTs.toLocal().day) {
122+
123+
// Top of group
124+
if (!prevVisible ||
125+
prev!.senderId != senderId ||
126+
prev.originServerTs.toLocal().day != originServerTs.toLocal().day) {
117127
return EventPosition.top;
118128
}
119129

120-
if (next == null ||
121-
next.hideInTimeline(
122-
showAvatarChanges: showAvatarChanges,
123-
showDisplayNameChanges: showDisplayNameChanges,
124-
) ||
125-
next.showAsBadge) {
130+
// Bottom of group
131+
if (!nextVisible || next!.senderId != senderId) {
126132
return EventPosition.bottom;
127133
}
128134

lib/common/local_image_model.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ class LocalImageModel extends SafeChangeNotifier {
2121

2222
Future<Uint8List?> downloadImage({
2323
required Event event,
24-
bool getThumbnail = true,
25-
}) async => _service.downloadImage(event: event, getThumbnail: getThumbnail);
24+
required bool cache,
25+
}) async => _service.downloadImage(event: event, cache: cache);
2626

2727
@override
2828
Future<void> dispose() async {

lib/common/local_image_service.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ class LocalImageService {
1616

1717
Future<Uint8List?> downloadImage({
1818
required Event event,
19-
required bool getThumbnail,
19+
required bool cache,
2020
}) async {
2121
final bytes = (await event.downloadAndDecryptAttachment(
22-
getThumbnail: getThumbnail,
22+
getThumbnail: event.hasThumbnail,
2323
)).bytes;
2424

25-
final cover = put(id: event.eventId, data: bytes);
25+
final cover = (event.hasThumbnail && cache)
26+
? put(id: event.eventId, data: bytes)
27+
: bytes;
2628
if (cover != null) {
2729
_propertiesChangedController.add(true);
2830
}

lib/events/view/chat_html_message.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,6 @@ class ImageExtension extends HtmlExtension {
162162
event: event,
163163
width: actualWidth,
164164
height: actualHeight,
165-
onlyThumbnail: (actualWidth * actualHeight) > (256 * 256),
166165
),
167166
),
168167
);

lib/events/view/chat_image.dart

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ class ChatImage extends StatelessWidget with WatchItMixin {
1919
this.height,
2020
this.fit,
2121
this.width = imageWidth,
22-
this.onlyThumbnail = true,
2322
this.onTap,
2423
this.showDescription = true,
2524
});
@@ -29,7 +28,6 @@ class ChatImage extends StatelessWidget with WatchItMixin {
2928
final double? height;
3029
final double width;
3130
final BoxFit? fit;
32-
final bool onlyThumbnail;
3331
final VoidCallback? onTap;
3432
final bool showDescription;
3533

@@ -83,9 +81,7 @@ class ChatImage extends StatelessWidget with WatchItMixin {
8381
width: theWidth,
8482
height: theHeight,
8583
fit: theFit,
86-
getThumbnail: event.hasThumbnail
87-
? onlyThumbnail
88-
: false,
84+
getThumbnail: event.hasThumbnail,
8985
),
9086
),
9187
if (showDescription &&
@@ -132,7 +128,7 @@ class _ChatImageFutureState extends State<ChatImageFuture> {
132128
? Future.value(image)
133129
: localImageModel.downloadImage(
134130
event: widget.event,
135-
getThumbnail: widget.getThumbnail,
131+
cache: widget.event.hasThumbnail && widget.getThumbnail,
136132
);
137133
}
138134

lib/events/view/chat_message_bubble_content.dart

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@ class ChatMessageBubbleContent extends StatelessWidget {
5353
children: [
5454
Padding(
5555
padding: const EdgeInsets.symmetric(horizontal: kSmallPadding),
56-
child: eventPosition != EventPosition.top
57-
? const SizedBox.square(dimension: kAvatarDefaultSize)
58-
: ChatAvatar(
56+
child:
57+
eventPosition == EventPosition.top ||
58+
eventPosition == EventPosition.semanticSingle
59+
? ChatAvatar(
5960
avatarUri: event.senderFromMemoryOrFallback.avatarUrl,
6061
onTap: () => showDialog(
6162
context: context,
@@ -65,7 +66,8 @@ class ChatMessageBubbleContent extends StatelessWidget {
6566
fallBackColor: avatarFallbackColor(
6667
context.colorScheme,
6768
).scale(saturation: -1),
68-
),
69+
)
70+
: const SizedBox.square(dimension: kAvatarDefaultSize),
6971
),
7072
Flexible(
7173
child: Stack(
@@ -108,7 +110,9 @@ class ChatMessageBubbleContent extends StatelessWidget {
108110
bottomRight: kBigBubbleRadius,
109111
),
110112
EventPosition.semanticSingle =>
111-
const BorderRadius.all(kBigBubbleRadius),
113+
const BorderRadius.all(
114+
kBigBubbleRadius,
115+
).copyWith(topLeft: kBubbleRadius),
112116
},
113117
),
114118
child: Column(
@@ -172,7 +176,6 @@ class ChatMessageBubbleContent extends StatelessWidget {
172176
builder: (context) =>
173177
ChatMessageImageFullScreenDialog(
174178
event: event,
175-
getThumbnail: true,
176179
),
177180
),
178181
),

lib/events/view/chat_message_image_full_screen_dialog.dart

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,9 @@ import '../../l10n/l10n.dart';
1919
import '../chat_download_model.dart';
2020

2121
class ChatMessageImageFullScreenDialog extends StatefulWidget {
22-
const ChatMessageImageFullScreenDialog({
23-
super.key,
24-
required this.event,
25-
this.getThumbnail = false,
26-
});
22+
const ChatMessageImageFullScreenDialog({super.key, required this.event});
2723

2824
final Event event;
29-
final bool getThumbnail;
3025

3126
@override
3227
State<ChatMessageImageFullScreenDialog> createState() =>
@@ -45,7 +40,7 @@ class _ChatMessageImageFullScreenDialogState
4540
_controller = PhotoViewController();
4641
_future = di<LocalImageModel>().downloadImage(
4742
event: widget.event,
48-
getThumbnail: widget.getThumbnail,
43+
cache: false,
4944
);
5045
}
5146

lib/events/view/chat_message_menu.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ class _ChatMessageMenuState extends State<ChatMessageMenu> {
107107
),
108108
child: Text(context.l10n.deleteMessage, style: style),
109109
),
110+
if (widget.event.status == EventStatus.error)
111+
MenuItemButton(
112+
trailingIcon: const Icon(YaruIcons.send),
113+
onPressed: () => widget.event.sendAgain(),
114+
child: Text(context.l10n.send, style: style),
115+
),
110116
if (kDebugMode)
111117
MenuItemButton(
112118
trailingIcon: const Icon(YaruIcons.code),

0 commit comments

Comments
 (0)