From b76e53def1cbc8b75b4ba827d97bf05e23059649 Mon Sep 17 00:00:00 2001 From: zoe Date: Sat, 1 Oct 2022 15:51:02 +0200 Subject: [PATCH] emoji in display names and post bodies --- lib/business_logic/account/account.dart | 11 ++++++++++ lib/business_logic/emoji/emoji.dart | 17 +++++++++++++++ .../follow_request/followrequest.dart | 2 -- lib/business_logic/timeline/timeline.dart | 7 +++++++ lib/dialogues/makepost.dart | 1 - lib/pages/search/search.dart | 2 -- lib/partials/post.dart | 21 +++++++++++++------ lib/partials/post_text_renderer.dart | 15 +++++++++++++ 8 files changed, 65 insertions(+), 11 deletions(-) create mode 100644 lib/business_logic/emoji/emoji.dart diff --git a/lib/business_logic/account/account.dart b/lib/business_logic/account/account.dart index 9a12378..21313f0 100644 --- a/lib/business_logic/account/account.dart +++ b/lib/business_logic/account/account.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; +import 'package:loris/business_logic/emoji/emoji.dart'; import 'package:loris/business_logic/timeline/timeline.dart'; import 'package:loris/global.dart' as global; @@ -19,6 +20,7 @@ class AccountModel { final bool? bot; final bool? suspended; final String identity; + final List emojis; AccountModel({ required this.identity, @@ -34,9 +36,17 @@ class AccountModel { required this.avatar, required this.url, required this.id, + required this.emojis, }); factory AccountModel.fromJson(Map json, String identity) { + List emoji = []; + if (json["emojis"] != null) { + for (var e in json["emojis"]) { + emoji.add(Emoji.fromJson(e)); + } + } + return AccountModel( identity: identity, id: json["id"], @@ -51,6 +61,7 @@ class AccountModel { bot: json["bot"], fields: json["fields"], suspended: json["suspended"], + emojis: emoji, ); } } diff --git a/lib/business_logic/emoji/emoji.dart b/lib/business_logic/emoji/emoji.dart new file mode 100644 index 0000000..fd8b199 --- /dev/null +++ b/lib/business_logic/emoji/emoji.dart @@ -0,0 +1,17 @@ +class Emoji { + final String shortcode; + final String url; + Emoji({required this.shortcode, required this.url}); + + factory Emoji.fromJson(Map json) { + return Emoji( + shortcode: json["shortcode"], + url: json["url"], + ); + } +} + +String insertEmojiInMd(String input, Emoji emoji) { + return input.replaceAll( + ":${emoji.shortcode}:", "![${emoji.shortcode}](${emoji.url})"); +} diff --git a/lib/business_logic/follow_request/followrequest.dart b/lib/business_logic/follow_request/followrequest.dart index f7d2694..167c826 100644 --- a/lib/business_logic/follow_request/followrequest.dart +++ b/lib/business_logic/follow_request/followrequest.dart @@ -49,8 +49,6 @@ Future handleFollowRequest(AccountModel account, ); final result = await http.post(uri, headers: headers); - print(uri); - print(result.body); if (result.statusCode != 200) { return null; } diff --git a/lib/business_logic/timeline/timeline.dart b/lib/business_logic/timeline/timeline.dart index 0af6c57..e703480 100644 --- a/lib/business_logic/timeline/timeline.dart +++ b/lib/business_logic/timeline/timeline.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:localization/localization.dart'; import 'package:loris/business_logic/account/account.dart'; +import 'package:loris/business_logic/emoji/emoji.dart'; import 'package:loris/business_logic/posting/mentions.dart'; import 'package:loris/business_logic/timeline/media.dart'; import '../../global.dart' as global; @@ -89,6 +90,7 @@ class PostModel implements Comparable { late List mentions = []; // exists if post is a reblog late String originalId; + late List emojis = []; PostModel.fromJson(Map json, this.identity) { id = json["id"] as String; @@ -125,6 +127,11 @@ class PostModel implements Comparable { for (var element in jsonMentionList) { mentions.add(MentionModel.fromJson(element)); } + List? jsonEmojiList = json["emojis"]; + if (jsonEmojiList != null) {} + for (var element in jsonEmojiList!) { + emojis.add(Emoji.fromJson(element)); + } } // get instance of account that received this post diff --git a/lib/dialogues/makepost.dart b/lib/dialogues/makepost.dart index e866ec1..106ce4a 100644 --- a/lib/dialogues/makepost.dart +++ b/lib/dialogues/makepost.dart @@ -2,7 +2,6 @@ import 'dart:convert'; import 'dart:ui'; import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; import 'package:localization/localization.dart'; import 'package:loris/business_logic/fileupload/fileupload.dart'; import 'package:loris/business_logic/instance/instance.dart'; diff --git a/lib/pages/search/search.dart b/lib/pages/search/search.dart index a012a4c..2244a92 100644 --- a/lib/pages/search/search.dart +++ b/lib/pages/search/search.dart @@ -1,5 +1,3 @@ -import 'dart:ui'; - import 'package:flutter/material.dart'; import 'package:localization/localization.dart'; import 'package:loris/business_logic/account/account.dart'; diff --git a/lib/partials/post.dart b/lib/partials/post.dart index f6bb524..b7d5574 100644 --- a/lib/partials/post.dart +++ b/lib/partials/post.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:localization/localization.dart'; import 'package:loris/business_logic/account/account.dart'; +import 'package:loris/business_logic/emoji/emoji.dart'; import 'package:loris/business_logic/timeline/media.dart'; import 'package:loris/dialogues/full_post_view.dart'; import 'package:loris/dialogues/makepost.dart'; @@ -88,6 +90,11 @@ class DisplayName extends StatelessWidget { } else { usernameStyle = Theme.of(context).textTheme.displaySmall; } + String dname = account.displayName; + for (var emoji in account.emojis) { + dname = insertEmojiInMd(dname, emoji); + } + return InkWell( borderRadius: const BorderRadius.all(themes.defaultRadius), onTap: !openInBrowser @@ -110,12 +117,13 @@ class DisplayName extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ - SelectableText( - minLines: 1, - maxLines: 2, - account.displayName, - style: usernameStyle, - ), + MarkdownBody( + data: dname, + selectable: true, + imageBuilder: (uri, title, alt) => Image.network( + uri.toString(), + height: usernameStyle?.fontSize), + styleSheet: MarkdownStyleSheet(p: usernameStyle)), SelectableText( account.acct, style: Theme.of(context).textTheme.bodySmall, @@ -295,6 +303,7 @@ class _PostBodyState extends State { PostTextRenderer( input: widget.content, identityName: widget.model.identity, + emoji: widget.model.emojis, ), MediaAttachments(models: widget.media), ], diff --git a/lib/partials/post_text_renderer.dart b/lib/partials/post_text_renderer.dart index c341be5..876fd27 100644 --- a/lib/partials/post_text_renderer.dart +++ b/lib/partials/post_text_renderer.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:html2md/html2md.dart' as html2md; +import 'package:loris/business_logic/emoji/emoji.dart'; import 'package:loris/dialogues/profile_view.dart'; import 'package:url_launcher/url_launcher.dart'; import '../business_logic/account/account.dart' as account; @@ -9,10 +10,12 @@ class PostTextRenderer extends StatelessWidget { const PostTextRenderer({ required this.identityName, required this.input, + this.emoji = const [], Key? key, }) : super(key: key); final String input; final String identityName; + final List emoji; @override Widget build(BuildContext context) { @@ -43,9 +46,19 @@ class PostTextRenderer extends StatelessWidget { ); String s = html2md.convert(input); + for (var e in emoji) { + s = insertEmojiInMd(s, e); + } return MarkdownBody( + imageBuilder: (uri, title, alt) { + return Image.network( + "${uri.scheme}://${uri.host}${uri.path}", + height: Theme.of(context).textTheme.bodyMedium?.fontSize, + ); + }, onTapLink: ((text, href, title) async { if (href != null) { + // see if this is an account and in that case search for it if (text.startsWith("@")) { final result = await account.searchModel(identityName, href); if (result.keys.first == 200) { @@ -56,6 +69,8 @@ class PostTextRenderer extends StatelessWidget { return; } } + // if this is not an account or the account couldn't be found + // then just open it in the default browser launchUrl(Uri.parse(href)); } }),