emoji in display names and post bodies
This commit is contained in:
parent
0caefbe4b9
commit
b76e53def1
|
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:http/http.dart' as http;
|
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/business_logic/timeline/timeline.dart';
|
||||||
import 'package:loris/global.dart' as global;
|
import 'package:loris/global.dart' as global;
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ class AccountModel {
|
||||||
final bool? bot;
|
final bool? bot;
|
||||||
final bool? suspended;
|
final bool? suspended;
|
||||||
final String identity;
|
final String identity;
|
||||||
|
final List<Emoji> emojis;
|
||||||
|
|
||||||
AccountModel({
|
AccountModel({
|
||||||
required this.identity,
|
required this.identity,
|
||||||
|
@ -34,9 +36,17 @@ class AccountModel {
|
||||||
required this.avatar,
|
required this.avatar,
|
||||||
required this.url,
|
required this.url,
|
||||||
required this.id,
|
required this.id,
|
||||||
|
required this.emojis,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory AccountModel.fromJson(Map<String, dynamic> json, String identity) {
|
factory AccountModel.fromJson(Map<String, dynamic> json, String identity) {
|
||||||
|
List<Emoji> emoji = [];
|
||||||
|
if (json["emojis"] != null) {
|
||||||
|
for (var e in json["emojis"]) {
|
||||||
|
emoji.add(Emoji.fromJson(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return AccountModel(
|
return AccountModel(
|
||||||
identity: identity,
|
identity: identity,
|
||||||
id: json["id"],
|
id: json["id"],
|
||||||
|
@ -51,6 +61,7 @@ class AccountModel {
|
||||||
bot: json["bot"],
|
bot: json["bot"],
|
||||||
fields: json["fields"],
|
fields: json["fields"],
|
||||||
suspended: json["suspended"],
|
suspended: json["suspended"],
|
||||||
|
emojis: emoji,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
class Emoji {
|
||||||
|
final String shortcode;
|
||||||
|
final String url;
|
||||||
|
Emoji({required this.shortcode, required this.url});
|
||||||
|
|
||||||
|
factory Emoji.fromJson(Map<String, dynamic> json) {
|
||||||
|
return Emoji(
|
||||||
|
shortcode: json["shortcode"],
|
||||||
|
url: json["url"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String insertEmojiInMd(String input, Emoji emoji) {
|
||||||
|
return input.replaceAll(
|
||||||
|
":${emoji.shortcode}:", "![${emoji.shortcode}](${emoji.url})");
|
||||||
|
}
|
|
@ -49,8 +49,6 @@ Future<RelationshipModel?> handleFollowRequest(AccountModel account,
|
||||||
);
|
);
|
||||||
|
|
||||||
final result = await http.post(uri, headers: headers);
|
final result = await http.post(uri, headers: headers);
|
||||||
print(uri);
|
|
||||||
print(result.body);
|
|
||||||
if (result.statusCode != 200) {
|
if (result.statusCode != 200) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:localization/localization.dart';
|
import 'package:localization/localization.dart';
|
||||||
import 'package:loris/business_logic/account/account.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/posting/mentions.dart';
|
||||||
import 'package:loris/business_logic/timeline/media.dart';
|
import 'package:loris/business_logic/timeline/media.dart';
|
||||||
import '../../global.dart' as global;
|
import '../../global.dart' as global;
|
||||||
|
@ -89,6 +90,7 @@ class PostModel implements Comparable {
|
||||||
late List<MentionModel> mentions = [];
|
late List<MentionModel> mentions = [];
|
||||||
// exists if post is a reblog
|
// exists if post is a reblog
|
||||||
late String originalId;
|
late String originalId;
|
||||||
|
late List<Emoji> emojis = [];
|
||||||
|
|
||||||
PostModel.fromJson(Map<String, dynamic> json, this.identity) {
|
PostModel.fromJson(Map<String, dynamic> json, this.identity) {
|
||||||
id = json["id"] as String;
|
id = json["id"] as String;
|
||||||
|
@ -125,6 +127,11 @@ class PostModel implements Comparable {
|
||||||
for (var element in jsonMentionList) {
|
for (var element in jsonMentionList) {
|
||||||
mentions.add(MentionModel.fromJson(element));
|
mentions.add(MentionModel.fromJson(element));
|
||||||
}
|
}
|
||||||
|
List<dynamic>? jsonEmojiList = json["emojis"];
|
||||||
|
if (jsonEmojiList != null) {}
|
||||||
|
for (var element in jsonEmojiList!) {
|
||||||
|
emojis.add(Emoji.fromJson(element));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get instance of account that received this post
|
// get instance of account that received this post
|
||||||
|
|
|
@ -2,7 +2,6 @@ import 'dart:convert';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
|
||||||
import 'package:localization/localization.dart';
|
import 'package:localization/localization.dart';
|
||||||
import 'package:loris/business_logic/fileupload/fileupload.dart';
|
import 'package:loris/business_logic/fileupload/fileupload.dart';
|
||||||
import 'package:loris/business_logic/instance/instance.dart';
|
import 'package:loris/business_logic/instance/instance.dart';
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import 'dart:ui';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:localization/localization.dart';
|
import 'package:localization/localization.dart';
|
||||||
import 'package:loris/business_logic/account/account.dart';
|
import 'package:loris/business_logic/account/account.dart';
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||||
import 'package:localization/localization.dart';
|
import 'package:localization/localization.dart';
|
||||||
import 'package:loris/business_logic/account/account.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/business_logic/timeline/media.dart';
|
||||||
import 'package:loris/dialogues/full_post_view.dart';
|
import 'package:loris/dialogues/full_post_view.dart';
|
||||||
import 'package:loris/dialogues/makepost.dart';
|
import 'package:loris/dialogues/makepost.dart';
|
||||||
|
@ -88,6 +90,11 @@ class DisplayName extends StatelessWidget {
|
||||||
} else {
|
} else {
|
||||||
usernameStyle = Theme.of(context).textTheme.displaySmall;
|
usernameStyle = Theme.of(context).textTheme.displaySmall;
|
||||||
}
|
}
|
||||||
|
String dname = account.displayName;
|
||||||
|
for (var emoji in account.emojis) {
|
||||||
|
dname = insertEmojiInMd(dname, emoji);
|
||||||
|
}
|
||||||
|
|
||||||
return InkWell(
|
return InkWell(
|
||||||
borderRadius: const BorderRadius.all(themes.defaultRadius),
|
borderRadius: const BorderRadius.all(themes.defaultRadius),
|
||||||
onTap: !openInBrowser
|
onTap: !openInBrowser
|
||||||
|
@ -110,12 +117,13 @@ class DisplayName extends StatelessWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
SelectableText(
|
MarkdownBody(
|
||||||
minLines: 1,
|
data: dname,
|
||||||
maxLines: 2,
|
selectable: true,
|
||||||
account.displayName,
|
imageBuilder: (uri, title, alt) => Image.network(
|
||||||
style: usernameStyle,
|
uri.toString(),
|
||||||
),
|
height: usernameStyle?.fontSize),
|
||||||
|
styleSheet: MarkdownStyleSheet(p: usernameStyle)),
|
||||||
SelectableText(
|
SelectableText(
|
||||||
account.acct,
|
account.acct,
|
||||||
style: Theme.of(context).textTheme.bodySmall,
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
|
@ -295,6 +303,7 @@ class _PostBodyState extends State<PostBody> {
|
||||||
PostTextRenderer(
|
PostTextRenderer(
|
||||||
input: widget.content,
|
input: widget.content,
|
||||||
identityName: widget.model.identity,
|
identityName: widget.model.identity,
|
||||||
|
emoji: widget.model.emojis,
|
||||||
),
|
),
|
||||||
MediaAttachments(models: widget.media),
|
MediaAttachments(models: widget.media),
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||||
import 'package:html2md/html2md.dart' as html2md;
|
import 'package:html2md/html2md.dart' as html2md;
|
||||||
|
import 'package:loris/business_logic/emoji/emoji.dart';
|
||||||
import 'package:loris/dialogues/profile_view.dart';
|
import 'package:loris/dialogues/profile_view.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import '../business_logic/account/account.dart' as account;
|
import '../business_logic/account/account.dart' as account;
|
||||||
|
@ -9,10 +10,12 @@ class PostTextRenderer extends StatelessWidget {
|
||||||
const PostTextRenderer({
|
const PostTextRenderer({
|
||||||
required this.identityName,
|
required this.identityName,
|
||||||
required this.input,
|
required this.input,
|
||||||
|
this.emoji = const [],
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
final String input;
|
final String input;
|
||||||
final String identityName;
|
final String identityName;
|
||||||
|
final List<Emoji> emoji;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -43,9 +46,19 @@ class PostTextRenderer extends StatelessWidget {
|
||||||
);
|
);
|
||||||
|
|
||||||
String s = html2md.convert(input);
|
String s = html2md.convert(input);
|
||||||
|
for (var e in emoji) {
|
||||||
|
s = insertEmojiInMd(s, e);
|
||||||
|
}
|
||||||
return MarkdownBody(
|
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 {
|
onTapLink: ((text, href, title) async {
|
||||||
if (href != null) {
|
if (href != null) {
|
||||||
|
// see if this is an account and in that case search for it
|
||||||
if (text.startsWith("@")) {
|
if (text.startsWith("@")) {
|
||||||
final result = await account.searchModel(identityName, href);
|
final result = await account.searchModel(identityName, href);
|
||||||
if (result.keys.first == 200) {
|
if (result.keys.first == 200) {
|
||||||
|
@ -56,6 +69,8 @@ class PostTextRenderer extends StatelessWidget {
|
||||||
return;
|
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));
|
launchUrl(Uri.parse(href));
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
Loading…
Reference in New Issue