Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add animated emoji support #450

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions assets/l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -2484,6 +2484,8 @@
"oldDisplayName": {}
}
},
"autoplayAnimations": "Automatically play animations",
"defaultEmojiTone": "Default emoji tone",
"newSpaceDescription": "Spaces allows you to consolidate your chats and build private or public communities.",
"encryptThisChat": "Encrypt this chat",
"endToEndEncryption": "End to end encryption",
Expand Down
Binary file added fonts/NotoSansSymbols-VariableFont_wght.ttf
Binary file not shown.
4 changes: 2 additions & 2 deletions lib/config/app_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ abstract class AppConfig {
static bool hideUnknownEvents = true;
static bool hideUnimportantStateEvents = true;
static bool separateChatTypes = false;
static bool autoplayImages = true;
static bool autoplayImages = false;
static bool sendTypingNotifications = true;
static bool sendOnEnter = false;
static bool experimentalVoip = false;
Expand All @@ -60,7 +60,7 @@ abstract class AppConfig {
static const String pushNotificationsGatewayUrl =
'https://push.fluffychat.im/_matrix/push/v1/notify';
static const String pushNotificationsPusherFormat = 'event_id_only';
static const String emojiFontName = 'Noto Emoji';
static const String emojiFontName = 'Noto Color Emoji';
static const String emojiFontUrl =
'https://github.com/googlefonts/noto-emoji/';
static const double borderRadius = 16.0;
Expand Down
2 changes: 1 addition & 1 deletion lib/config/themes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ abstract class FluffyThemes {

static const fallbackTextStyle = TextStyle(
fontFamily: 'Roboto',
fontFamilyFallback: ['NotoEmoji'],
fontFamilyFallback: [AppConfig.emojiFontName],
);

static var fallbackTextTheme = const TextTheme(
Expand Down
4 changes: 2 additions & 2 deletions lib/pages/bootstrap/bootstrap_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class BootstrapDialogState extends State<BootstrapDialog> {
minLines: 2,
maxLines: 4,
readOnly: true,
style: const TextStyle(fontFamily: 'RobotoMono'),
style: const TextStyle(fontFamily: 'Roboto Mono'),
controller: TextEditingController(text: key),
decoration: const InputDecoration(
contentPadding: EdgeInsets.all(16),
Expand Down Expand Up @@ -256,7 +256,7 @@ class BootstrapDialogState extends State<BootstrapDialog> {
? null
: [AutofillHints.password],
controller: _recoveryKeyTextEditingController,
style: const TextStyle(fontFamily: 'RobotoMono'),
style: const TextStyle(fontFamily: 'Roboto Mono'),
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(16),
hintStyle: TextStyle(
Expand Down
19 changes: 7 additions & 12 deletions lib/pages/chat/chat.dart
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,6 @@ class ChatController extends State<ChatPageWithRoom> {

final int _loadHistoryCount = 100;

String inputText = '';

String pendingText = '';

bool showEmojiPicker = false;
Expand Down Expand Up @@ -295,7 +293,6 @@ class ChatController extends State<ChatPageWithRoom> {
final draft = prefs.getString('draft_$roomId');
if (draft != null && draft.isNotEmpty) {
sendController.text = draft;
setState(() => inputText = draft);
}
}

Expand Down Expand Up @@ -472,18 +469,18 @@ class ChatController extends State<ChatPageWithRoom> {

// ignore: unawaited_futures
room.sendTextEvent(
sendController.text,
sendController.text.trim(),
inReplyTo: replyEvent,
editEventId: editEvent?.eventId,
parseCommands: parseCommands,
);
// TextEditingValue required due to potential selection present
sendController.value = TextEditingValue(
text: pendingText,
selection: const TextSelection.collapsed(offset: 0),
);

setState(() {
inputText = pendingText;
replyEvent = null;
editEvent = null;
pendingText = '';
Expand Down Expand Up @@ -1051,7 +1048,7 @@ class ChatController extends State<ChatPageWithRoom> {
setState(() {
pendingText = sendController.text;
editEvent = selectedEvents.first;
inputText = sendController.text =
sendController.text =
editEvent!.getDisplayEvent(timeline!).calcLocalizedBodyFallback(
MatrixLocals(L10n.of(context)!),
withSenderNamePrefix: false,
Expand Down Expand Up @@ -1206,10 +1203,9 @@ class ChatController extends State<ChatPageWithRoom> {
if ((prefix.isNotEmpty) &&
text.toLowerCase() == '${prefix.toLowerCase()} ') {
setSendingClient(client);
setState(() {
inputText = '';
sendController.text = '';
});

sendController.text = '';

return;
}
}
Expand All @@ -1233,7 +1229,6 @@ class ChatController extends State<ChatPageWithRoom> {
);
}
}
setState(() => inputText = text);
}

bool get isArchived =>
Expand Down Expand Up @@ -1302,7 +1297,7 @@ class ChatController extends State<ChatPageWithRoom> {

void cancelReplyEventAction() => setState(() {
if (editEvent != null) {
inputText = sendController.text = pendingText;
sendController.text = pendingText;
pendingText = '';
}
replyEvent = null;
Expand Down
7 changes: 4 additions & 3 deletions lib/pages/chat/chat_input_row.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class ChatInputRow extends StatelessWidget {
duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve,
height: 56,
width: controller.inputText.isEmpty ? 56 : 0,
width: controller.sendController.text.isEmpty ? 56 : 0,
alignment: Alignment.center,
clipBehavior: Clip.hardEdge,
decoration: const BoxDecoration(),
Expand Down Expand Up @@ -268,7 +268,7 @@ class ChatInputRow extends StatelessWidget {
),
),
if (PlatformInfos.platformCanRecord &&
controller.inputText.isEmpty)
controller.sendController.text.isEmpty)
Container(
height: 56,
alignment: Alignment.center,
Expand All @@ -278,7 +278,8 @@ class ChatInputRow extends StatelessWidget {
onPressed: controller.voiceMessageAction,
),
),
if (!PlatformInfos.isMobile || controller.inputText.isNotEmpty)
if (!PlatformInfos.isMobile ||
controller.sendController.text.isNotEmpty)
Container(
height: 56,
alignment: Alignment.center,
Expand Down
47 changes: 30 additions & 17 deletions lib/pages/chat/events/cute_events.dart
Original file line number Diff line number Diff line change
@@ -1,34 +1,43 @@
import 'dart:math';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';

import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pages/settings_chat/settings_chat.dart';
import 'package:fluffychat/widgets/animated_emoji_plain_text.dart';
import 'package:fluffychat/widgets/matrix.dart';

class CuteContent extends StatefulWidget {
final Event event;
final Color color;

const CuteContent(this.event, {super.key});
const CuteContent(
this.event, {
super.key,
required this.color,
});

@override
State<CuteContent> createState() => _CuteContentState();
}

class _CuteContentState extends State<CuteContent> {
static bool _isOverlayShown = false;

@override
void initState() {
if (AppConfig.autoplayImages && !_isOverlayShown) {
addOverlay();
}
super.initState();
}
bool initialized = false;

@override
Widget build(BuildContext context) {
if (initialized == false) {
initialized = true;

if (Matrix.of(context).client.autoplayAnimatedContent ??
!kIsWeb && !_isOverlayShown) {
addOverlay();
}
}
return FutureBuilder<User?>(
future: widget.event.fetchSenderUser(),
builder: (context, snapshot) {
Expand All @@ -40,9 +49,10 @@ class _CuteContentState extends State<CuteContent> {
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
TextLinkifyEmojify(
widget.event.text,
style: const TextStyle(fontSize: 150),
fontSize: 150,
textColor: widget.color,
),
if (label != null) Text(label),
],
Expand Down Expand Up @@ -183,11 +193,14 @@ class _CuteOverlayContent extends StatelessWidget {

@override
Widget build(BuildContext context) {
return SizedBox.square(
dimension: size,
child: Text(
emoji,
style: const TextStyle(fontSize: 48),
return SizedOverflowBox(
size: const Size.square(size),
child: ClipRect(
clipBehavior: Clip.hardEdge,
child: Text(
emoji,
style: const TextStyle(fontSize: 56),
),
),
);
}
Expand Down
Loading
Loading