Skip to content

Commit

Permalink
feat: new encrypted message design
Browse files Browse the repository at this point in the history
  • Loading branch information
Julian KOUNE committed Sep 29, 2023
1 parent 2d4c8b7 commit 017e924
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 120 deletions.
3 changes: 2 additions & 1 deletion assets/l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -2734,5 +2734,6 @@
"unmuteThisMessage": "Unmute this message",
"read": "Read",
"unread": "Unread",
"unmute": "Unmute"
"unmute": "Unmute",
"thisMessageHasBeenEncrypted": "This message has been encrypted"
}
45 changes: 0 additions & 45 deletions lib/pages/chat/encryption_button.dart

This file was deleted.

131 changes: 131 additions & 0 deletions lib/pages/chat/events/encrypted_content.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import 'package:fluffychat/pages/bootstrap/bootstrap_dialog.dart';
import 'package:fluffychat/pages/chat/events/encrypted_content_style.dart';
import 'package:fluffychat/pages/chat/events/message_content_style.dart';
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/widgets/avatar/avatar.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';

class EncryptedContent extends StatelessWidget {
final Event event;

const EncryptedContent({Key? key, required this.event}) : super(key: key);

@override
Widget build(BuildContext context) {
return Padding(
padding: EncryptedContentStyle.parentPadding,
child: InkWell(
onTap: () => _verifyOrRequestKey(context),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.onError,
shape: BoxShape.circle,
),
padding: EncryptedContentStyle.leadingIconPadding,
child: Icon(
Icons.delete_outline,
color: Theme.of(context).colorScheme.primary,
size: EncryptedContentStyle.leadingIconSize,
),
),
const SizedBox(width: EncryptedContentStyle.leadingAndTextGap),
Container(
constraints: const BoxConstraints(
maxWidth: EncryptedContentStyle.containerTextMaxWidth,
),
child: Text(
maxLines: 2,
L10n.of(context)!.thisMessageHasBeenEncrypted,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onSurface,
),
),
),
],
),
const SizedBox(width: EncryptedContentStyle.textAndTrailingGap),
Icon(
Icons.lock,
color: Theme.of(context).colorScheme.tertiary,
size: EncryptedContentStyle.trailingIconSize,
),
],
),
),
);
}

void _verifyOrRequestKey(BuildContext context) async {
final l10n = L10n.of(context)!;
if (event.content['can_request_session'] != true) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
event.type == EventTypes.Encrypted
? l10n.needPantalaimonWarning
: event.calcLocalizedBodyFallback(
MatrixLocals(l10n),
),
),
),
);
return;
}
final client = Matrix.of(context).client;
if (client.isUnknownSession && client.encryption!.crossSigning.enabled) {
final success = await BootstrapDialog(
client: Matrix.of(context).client,
).show(context);
if (success != true) return;
}
event.requestKey();
final sender = event.senderFromMemoryOrFallback;
await showAdaptiveBottomSheet(
context: context,
builder: (context) => Scaffold(
appBar: AppBar(
leading: CloseButton(onPressed: Navigator.of(context).pop),
title: Text(
l10n.whyIsThisMessageEncrypted,
style:
const TextStyle(fontSize: MessageContentStyle.appBarFontSize),
),
),
body: SafeArea(
child: ListView(
padding: const EdgeInsets.all(16),
children: [
ListTile(
contentPadding: EdgeInsets.zero,
leading: Avatar(
mxContent: sender.avatarUrl,
name: sender.calcDisplayname(),
),
title: Text(sender.calcDisplayname()),
subtitle: Text(event.originServerTs.localizedTime(context)),
trailing: const Icon(Icons.lock_outlined),
),
const Divider(),
Text(
event.calcLocalizedBodyFallback(
MatrixLocals(l10n),
),
)
],
),
),
),
);
}
}
13 changes: 13 additions & 0 deletions lib/pages/chat/events/encrypted_content_style.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'package:flutter/material.dart';

class EncryptedContentStyle {
static const EdgeInsets parentPadding = EdgeInsets.symmetric(
horizontal: 8,
);
static const EdgeInsets leadingIconPadding = EdgeInsets.all(5);
static const double leadingIconSize = 20;
static const double leadingAndTextGap = 8;
static const double textAndTrailingGap = 40;
static const double containerTextMaxWidth = 165.0;
static const double trailingIconSize = 16;
}
8 changes: 8 additions & 0 deletions lib/pages/chat/events/message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class Message extends StatelessWidget {
}.contains(event.messageType);
final timelineText = {
MessageTypes.Text,
MessageTypes.BadEncrypted,
}.contains(event.messageType);
final noPadding = {
MessageTypes.File,
Expand Down Expand Up @@ -211,6 +212,13 @@ class Message extends StatelessWidget {
: FutureBuilder<User?>(
future: event.fetchSenderUser(),
builder: (context, snapshot) {
// Doesn't show the sender name if the event is encrypted.
if (event.type ==
EventTypes.Encrypted) {
return const SizedBox
.shrink();
}

final displayName = snapshot
.data
?.calcDisplayname() ??
Expand Down
78 changes: 4 additions & 74 deletions lib/pages/chat/events/message_content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:fluffychat/app_state/success.dart';
import 'package:fluffychat/domain/app_state/room/chat_room_search_state.dart';
import 'package:fluffychat/pages/chat/chat.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pages/bootstrap/bootstrap_dialog.dart';
import 'package:fluffychat/pages/chat/events/encrypted_content.dart';
import 'package:fluffychat/pages/chat/events/message_content_style.dart';
import 'package:fluffychat/pages/chat/events/sending_image_info_widget.dart';
import 'package:fluffychat/pages/chat/events/sending_video_widget.dart';
Expand All @@ -20,11 +20,8 @@ import 'package:flutter_matrix_html/color_extension.dart';
import 'package:matrix/matrix.dart' hide Visibility;

import 'package:fluffychat/pages/chat/events/event_video_player.dart';
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
import 'package:fluffychat/widgets/avatar/avatar.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'audio_player.dart';
import 'cute_events.dart';
Expand Down Expand Up @@ -58,77 +55,15 @@ class MessageContent extends StatelessWidget with PlayVideoActionMixin {
required this.ownMessage,
}) : super(key: key);

void _verifyOrRequestKey(BuildContext context) async {
final l10n = L10n.of(context)!;
if (event.content['can_request_session'] != true) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
event.type == EventTypes.Encrypted
? l10n.needPantalaimonWarning
: event.calcLocalizedBodyFallback(
MatrixLocals(l10n),
),
),
),
);
return;
}
final client = Matrix.of(context).client;
if (client.isUnknownSession && client.encryption!.crossSigning.enabled) {
final success = await BootstrapDialog(
client: Matrix.of(context).client,
).show(context);
if (success != true) return;
}
event.requestKey();
final sender = event.senderFromMemoryOrFallback;
await showAdaptiveBottomSheet(
context: context,
builder: (context) => Scaffold(
appBar: AppBar(
leading: CloseButton(onPressed: Navigator.of(context).pop),
title: Text(
l10n.whyIsThisMessageEncrypted,
style:
const TextStyle(fontSize: MessageContentStyle.appBarFontSize),
),
),
body: SafeArea(
child: ListView(
padding: const EdgeInsets.all(16),
children: [
ListTile(
contentPadding: EdgeInsets.zero,
leading: Avatar(
mxContent: sender.avatarUrl,
name: sender.calcDisplayname(),
),
title: Text(sender.calcDisplayname()),
subtitle: Text(event.originServerTs.localizedTime(context)),
trailing: const Icon(Icons.lock_outlined),
),
const Divider(),
Text(
event.calcLocalizedBodyFallback(
MatrixLocals(l10n),
),
)
],
),
),
),
);
}

@override
Widget build(BuildContext context) {
final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor;
final buttonTextColor =
event.senderId == Matrix.of(context).client.userID ? textColor : null;
switch (event.type) {
case EventTypes.Message:
case EventTypes.Encrypted:
return EncryptedContent(event: event);
case EventTypes.Message:
case EventTypes.Sticker:
switch (event.messageType) {
case MessageTypes.Image:
Expand Down Expand Up @@ -241,12 +176,7 @@ class MessageContent extends StatelessWidget with PlayVideoActionMixin {
continue textmessage;
case MessageTypes.BadEncrypted:
case EventTypes.Encrypted:
return _ButtonContent(
textColor: buttonTextColor,
onPressed: () => _verifyOrRequestKey(context),
icon: const Icon(Icons.lock_outline),
label: L10n.of(context)!.encrypted,
);
return EncryptedContent(event: event);
case MessageTypes.Location:
final geoUri =
Uri.tryParse(event.content.tryGet<String>('geo_uri')!);
Expand Down

0 comments on commit 017e924

Please sign in to comment.