diff --git a/lib/pages/chat/events/html_message.dart b/lib/pages/chat/events/html_message.dart
index 06f27a6d..adc691c7 100644
--- a/lib/pages/chat/events/html_message.dart
+++ b/lib/pages/chat/events/html_message.dart
@@ -1,31 +1,26 @@
import 'package:flutter/material.dart';
-import 'package:flutter_gen/gen_l10n/l10n.dart';
-import 'package:flutter_matrix_html/flutter_html.dart';
+import 'package:collection/collection.dart';
+import 'package:flutter_highlighter/flutter_highlighter.dart';
+import 'package:flutter_highlighter/themes/shades-of-purple.dart';
+import 'package:flutter_html/flutter_html.dart';
+import 'package:flutter_math_fork/flutter_math.dart';
import 'package:matrix/matrix.dart';
-import 'package:fluffychat/widgets/matrix.dart';
-import '../../../config/app_config.dart';
-import '../../../config/setting_keys.dart';
-import '../../../utils/matrix_sdk_extensions/matrix_locals.dart';
+import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/widgets/avatar.dart';
import '../../../utils/url_launcher.dart';
class HtmlMessage extends StatelessWidget {
final String html;
- final int? maxLines;
final Room room;
- final TextStyle? defaultTextStyle;
- final TextStyle? linkStyle;
- final double? emoteSize;
+ final Color? textColor;
const HtmlMessage({
Key? key,
required this.html,
- this.maxLines,
required this.room,
- this.defaultTextStyle,
- this.linkStyle,
- this.emoteSize,
+ this.textColor,
}) : super(key: key);
@override
@@ -46,101 +41,315 @@ class HtmlMessage extends StatelessWidget {
'',
);
+ final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor;
+
// there is no need to pre-validate the html, as we validate it while rendering
-
- final matrix = Matrix.of(context);
-
- final themeData = Theme.of(context);
return Html(
data: renderHtml,
- defaultTextStyle: defaultTextStyle,
- emoteSize: emoteSize,
- linkStyle: linkStyle ??
- themeData.textTheme.bodyMedium!.copyWith(
- color: themeData.colorScheme.secondary,
- decoration: TextDecoration.underline,
- decorationColor: themeData.colorScheme.secondary,
- ),
- shrinkToFit: true,
- maxLines: maxLines,
- onLinkTap: (url) => UrlLauncher(context, url).launchUrl(),
- onPillTap: (url) => UrlLauncher(context, url).launchUrl(),
- getMxcUrl: (
- String mxc,
- double? width,
- double? height, {
- bool? animated = false,
- }) {
- final ratio = MediaQuery.of(context).devicePixelRatio;
- return Uri.parse(mxc)
- .getThumbnail(
- matrix.client,
- width: (width ?? 800) * ratio,
- height: (height ?? 800) * ratio,
- method: ThumbnailMethod.scale,
- animated: AppConfig.autoplayImages ? animated : false,
- )
- .toString();
+ style: {
+ '*': Style(
+ color: textColor,
+ margin: Margins.all(0),
+ fontSize: FontSize(fontSize),
+ ),
+ 'a': Style(color: textColor?.withAlpha(150)),
+ 'h1': Style(fontSize: FontSize(fontSize * 3)),
+ 'h2': Style(fontSize: FontSize(fontSize * 2.5)),
+ 'h3': Style(fontSize: FontSize(fontSize * 2)),
+ 'h4': Style(fontSize: FontSize(fontSize * 1.75)),
+ 'h5': Style(fontSize: FontSize(fontSize * 1.5)),
+ 'h6': Style(fontSize: FontSize(fontSize * 1.25)),
+ // Otherwise list tiles are all in the same row$$
+ 'li': Style(display: Display.block),
},
- onImageTap: (url) => UrlLauncher(context, url).launchUrl(),
- setCodeLanguage: (String key, String value) async {
- await matrix.store.setItem('${SettingKeys.codeLanguage}.$key', value);
- },
- getCodeLanguage: (String key) async {
- return await matrix.store.getItem('${SettingKeys.codeLanguage}.$key');
- },
- getPillInfo: (String url) async {
- final identityParts = url.parseIdentifierIntoParts();
- final identifier = identityParts?.primaryIdentifier;
- if (identifier == null) {
- return {};
- }
- if (identifier.sigil == '@') {
- // we have a user pill
- final user = room.getState('m.room.member', identifier);
- if (user != null) {
- return user.content;
- }
- // there might still be a profile...
- final profile = await room.client.getProfileFromUserId(identifier);
- return {
- 'displayname': profile.displayName,
- 'avatar_url': profile.avatarUrl.toString(),
- };
- }
- if (identifier.sigil == '#') {
- // we have an alias pill
- for (final r in room.client.rooms) {
- final state = r.getState('m.room.canonical_alias');
- if (state != null &&
- ((state.content['alias'] is String &&
- state.content['alias'] == identifier) ||
- (state.content['alt_aliases'] is List &&
- state.content['alt_aliases'].contains(identifier)))) {
- // we have a room!
- return {
- 'displayname':
- r.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)),
- 'avatar_url': r.getState('m.room.avatar')?.content['url'],
- };
- }
- }
- return {};
- }
- if (identifier.sigil == '!') {
- // we have a room ID pill
- final r = room.client.getRoomById(identifier);
- if (r == null) {
- return {};
- }
- return {
- 'displayname':
- r.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)),
- 'avatar_url': r.getState('m.room.avatar')?.content['url'],
- };
- }
- return {};
+ extensions: [
+ UserPillExtension(context, room),
+ RoomPillExtension(context, room.client),
+ CodeExtension(fontSize: fontSize),
+ MatrixMathExtension(
+ style: TextStyle(fontSize: fontSize, color: textColor),
+ ),
+ ],
+ onLinkTap: (url, _, __) => UrlLauncher(context, url).launchUrl(),
+ onlyRenderTheseTags: const {
+ ...allowedHtmlTags,
+ // Needed to make it work properly
+ 'body',
+ 'html',
},
+ shrinkWrap: true,
+ );
+ }
+
+ /// Keep in sync with: https://spec.matrix.org/v1.6/client-server-api/#mroommessage-msgtypes
+ static const Set allowedHtmlTags = {
+ 'font',
+ 'del',
+ 'h1',
+ 'h2',
+ 'h3',
+ 'h4',
+ 'h5',
+ 'h6',
+ 'blockquote',
+ 'p',
+ 'a',
+ 'ul',
+ 'ol',
+ 'sup',
+ 'sub',
+ 'li',
+ 'b',
+ 'i',
+ 'u',
+ 'strong',
+ 'em',
+ 'strike',
+ 'code',
+ 'hr',
+ 'br',
+ 'div',
+ 'table',
+ 'thead',
+ 'tbody',
+ 'tr',
+ 'th',
+ 'td',
+ 'caption',
+ 'pre',
+ 'span',
+ 'img',
+ 'details',
+ 'summary'
+ };
+}
+
+class MatrixMathExtension extends HtmlExtension {
+ final TextStyle? style;
+
+ MatrixMathExtension({this.style});
+ @override
+ Set get supportedTags => {'div'};
+
+ @override
+ bool matches(ExtensionContext context) {
+ if (context.elementName != 'div') return false;
+ final mathData = context.element?.attributes['data-mx-maths'];
+ return mathData != null;
+ }
+
+ @override
+ InlineSpan build(
+ ExtensionContext context,
+ Map Function() parseChildren,
+ ) {
+ final data = context.element?.attributes['data-mx-maths'] ?? '';
+ return WidgetSpan(
+ child: Math.tex(
+ data,
+ textStyle: style,
+ onErrorFallback: (e) {
+ Logs().d('Flutter math parse error', e);
+ return Text(
+ data,
+ style: style,
+ );
+ },
+ ),
+ );
+ }
+}
+
+class CodeExtension extends HtmlExtension {
+ final double fontSize;
+
+ CodeExtension({required this.fontSize});
+ @override
+ Set get supportedTags => {'code'};
+
+ @override
+ InlineSpan build(
+ ExtensionContext context,
+ Map Function() parseChildren,
+ ) =>
+ WidgetSpan(
+ child: Material(
+ clipBehavior: Clip.hardEdge,
+ borderRadius: BorderRadius.circular(4),
+ child: SingleChildScrollView(
+ scrollDirection: Axis.horizontal,
+ child: HighlightView(
+ context.element?.text ?? '',
+ language: context.element?.className
+ .split(' ')
+ .singleWhereOrNull(
+ (className) => className.startsWith('language-'),
+ )
+ ?.split('language-')
+ .last ??
+ 'md',
+ theme: shadesOfPurpleTheme,
+ padding: const EdgeInsets.all(6),
+ textStyle: TextStyle(fontSize: fontSize),
+ ),
+ ),
+ ),
+ );
+}
+
+class UserPillExtension extends HtmlExtension {
+ final Room room;
+ final BuildContext context;
+
+ UserPillExtension(this.context, this.room);
+ @override
+ Set get supportedTags => {'a'};
+
+ @override
+ bool matches(ExtensionContext context) {
+ if (context.elementName != 'a') return false;
+ final href = context.element?.attributes['href'];
+ if (href == null) return false;
+ final uri = Uri.tryParse(href);
+ if (uri == null || uri.host != 'matrix.to') return false;
+ final userId = uri.fragment.split('/').last;
+ if (userId.sigil != '@') return false;
+ return true;
+ }
+
+ @override
+ InlineSpan build(
+ ExtensionContext context,
+ Map Function() parseChildren,
+ ) {
+ final href = context.element!.attributes['href']!;
+ final uri = Uri.parse(href);
+ final userId = uri.fragment.split('/').last;
+ final user = room.unsafeGetUserFromMemoryOrFallback(userId);
+ return WidgetSpan(
+ child: MatrixPill(
+ name: user.calcDisplayname(),
+ avatar: user.avatarUrl,
+ uri: href,
+ outerContext: this.context,
+ ),
+ );
+ }
+}
+
+class RoomPillExtension extends HtmlExtension {
+ final Client client;
+ final BuildContext context;
+
+ RoomPillExtension(this.context, this.client);
+ @override
+ Set get supportedTags => {'a'};
+
+ @override
+ bool matches(ExtensionContext context) {
+ if (context.elementName != 'a') return false;
+ final href = context.element?.attributes['href'];
+ if (href == null) return false;
+ final uri = Uri.tryParse(href);
+ if (uri == null || uri.host != 'matrix.to') return false;
+ final roomId = Uri.decodeComponent(uri.fragment.split('/').last);
+ if (!{'#', '!'}.contains(roomId.sigil)) return false;
+ return true;
+ }
+
+ @override
+ InlineSpan build(
+ ExtensionContext context,
+ Map Function() parseChildren,
+ ) {
+ final href = context.element!.attributes['href']!;
+ final uri = Uri.parse(href);
+ final roomId = Uri.decodeComponent(uri.fragment.split('/').last);
+
+ final room = roomId.sigil == '!'
+ ? client.getRoomById(roomId)
+ : client.getRoomByAlias(roomId);
+ if (room != null) {
+ return WidgetSpan(
+ child: MatrixPill(
+ name: room.getLocalizedDisplayname(),
+ avatar: room.avatar,
+ uri: href,
+ outerContext: this.context,
+ ),
+ );
+ }
+
+ return WidgetSpan(
+ child: FutureBuilder(
+ future: client.queryPublicRooms(
+ server: roomId.domain,
+ filter: PublicRoomQueryFilter(
+ genericSearchTerm: roomId,
+ ),
+ ),
+ builder: (context, snapshot) {
+ final room = snapshot.data;
+ return MatrixPill(
+ name: room?.chunk.singleOrNull?.name ?? roomId,
+ avatar: room?.chunk.singleOrNull?.avatarUrl,
+ uri: href,
+ outerContext: this.context,
+ );
+ },
+ ),
+ );
+ }
+}
+
+class MatrixPill extends StatelessWidget {
+ final String name;
+ final BuildContext outerContext;
+ final Uri? avatar;
+ final String uri;
+
+ const MatrixPill({
+ super.key,
+ required this.name,
+ required this.outerContext,
+ this.avatar,
+ required this.uri,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return InkWell(
+ onTap: UrlLauncher(outerContext, uri).launchUrl,
+ child: Material(
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(AppConfig.borderRadius),
+ side: BorderSide(
+ color: Theme.of(outerContext).colorScheme.onPrimaryContainer,
+ width: 0.5,
+ ),
+ ),
+ color: Theme.of(outerContext).colorScheme.primaryContainer,
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 6.0),
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Avatar(
+ mxContent: avatar,
+ name: name,
+ size: 16,
+ ),
+ const SizedBox(width: 6),
+ Text(
+ name,
+ style: TextStyle(
+ color: Theme.of(outerContext).colorScheme.onPrimaryContainer,
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
);
}
}
diff --git a/lib/pages/chat/events/message_content.dart b/lib/pages/chat/events/message_content.dart
index 843a7355..3186a029 100644
--- a/lib/pages/chat/events/message_content.dart
+++ b/lib/pages/chat/events/message_content.dart
@@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
+import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';
-import 'package:matrix_link_text/link_text.dart';
import 'package:fluffychat/pages/chat/events/video_player.dart';
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
@@ -150,23 +150,10 @@ class MessageContent extends StatelessWidget {
if (event.messageType == MessageTypes.Emote) {
html = '* $html';
}
- final bigEmotes = event.onlyEmotes &&
- event.numberEmotes > 0 &&
- event.numberEmotes <= 10;
return HtmlMessage(
html: html,
- defaultTextStyle: TextStyle(
- color: textColor,
- fontSize: bigEmotes ? fontSize * 3 : fontSize,
- ),
- linkStyle: TextStyle(
- color: textColor.withAlpha(150),
- fontSize: bigEmotes ? fontSize * 3 : fontSize,
- decoration: TextDecoration.underline,
- decorationColor: textColor.withAlpha(150),
- ),
+ textColor: textColor,
room: event.room,
- emoteSize: bigEmotes ? fontSize * 3 : fontSize * 1.5,
);
}
// else we fall through to the normal message rendering
@@ -242,13 +229,13 @@ class MessageContent extends StatelessWidget {
hideReply: true,
),
builder: (context, snapshot) {
- return LinkText(
+ return Linkify(
text: snapshot.data ??
event.calcLocalizedBodyFallback(
MatrixLocals(L10n.of(context)!),
hideReply: true,
),
- textStyle: TextStyle(
+ style: TextStyle(
color: textColor,
fontSize: bigEmotes ? fontSize * 3 : fontSize,
decoration:
@@ -260,10 +247,7 @@ class MessageContent extends StatelessWidget {
decoration: TextDecoration.underline,
decorationColor: textColor.withAlpha(150),
),
- beforeLaunch: (url) {
- UrlLauncher(context, url.toString()).launchUrl();
- return false;
- },
+ onOpen: (url) => UrlLauncher(context, url.url).launchUrl(),
);
},
);
diff --git a/lib/pages/chat/events/reply_content.dart b/lib/pages/chat/events/reply_content.dart
index 26c47218..6de2e592 100644
--- a/lib/pages/chat/events/reply_content.dart
+++ b/lib/pages/chat/events/reply_content.dart
@@ -5,7 +5,6 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import '../../../config/app_config.dart';
-import 'html_message.dart';
class ReplyContent extends StatelessWidget {
final Event replyEvent;
@@ -26,47 +25,23 @@ class ReplyContent extends StatelessWidget {
final displayEvent =
timeline != null ? replyEvent.getDisplayEvent(timeline) : replyEvent;
final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor;
- if (AppConfig.renderHtml &&
- [EventTypes.Message, EventTypes.Encrypted]
- .contains(displayEvent.type) &&
- [MessageTypes.Text, MessageTypes.Notice, MessageTypes.Emote]
- .contains(displayEvent.messageType) &&
- !displayEvent.redacted &&
- displayEvent.content['format'] == 'org.matrix.custom.html' &&
- displayEvent.content['formatted_body'] is String) {
- String? html = displayEvent.content['formatted_body'];
- if (displayEvent.messageType == MessageTypes.Emote) {
- html = '* $html';
- }
- replyBody = HtmlMessage(
- html: html!,
- defaultTextStyle: TextStyle(
- color: ownMessage
- ? Theme.of(context).colorScheme.onPrimary
- : Theme.of(context).colorScheme.onBackground,
- fontSize: fontSize,
- ),
- maxLines: 1,
- room: displayEvent.room,
- emoteSize: fontSize * 1.5,
- );
- } else {
- replyBody = Text(
- displayEvent.calcLocalizedBodyFallback(
- MatrixLocals(L10n.of(context)!),
- withSenderNamePrefix: false,
- hideReply: true,
- ),
- overflow: TextOverflow.ellipsis,
- maxLines: 1,
- style: TextStyle(
- color: ownMessage
- ? Theme.of(context).colorScheme.onPrimary
- : Theme.of(context).colorScheme.onBackground,
- fontSize: fontSize,
- ),
- );
- }
+
+ replyBody = Text(
+ displayEvent.calcLocalizedBodyFallback(
+ MatrixLocals(L10n.of(context)!),
+ withSenderNamePrefix: false,
+ hideReply: true,
+ ),
+ overflow: TextOverflow.ellipsis,
+ maxLines: 1,
+ style: TextStyle(
+ color: ownMessage
+ ? Theme.of(context).colorScheme.onPrimary
+ : Theme.of(context).colorScheme.onBackground,
+ fontSize: fontSize,
+ ),
+ );
+
return Row(
mainAxisSize: MainAxisSize.min,
children: [
diff --git a/lib/pages/chat/pinned_events.dart b/lib/pages/chat/pinned_events.dart
index a38d950e..88373d07 100644
--- a/lib/pages/chat/pinned_events.dart
+++ b/lib/pages/chat/pinned_events.dart
@@ -4,8 +4,8 @@ import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
+import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';
-import 'package:matrix_link_text/link_text.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pages/chat/chat.dart';
@@ -101,7 +101,7 @@ class PinnedEvents extends StatelessWidget {
hideReply: true,
),
builder: (context, snapshot) {
- return LinkText(
+ return Linkify(
text: snapshot.data ??
event.calcLocalizedBodyFallback(
MatrixLocals(L10n.of(context)!),
@@ -109,7 +109,7 @@ class PinnedEvents extends StatelessWidget {
hideReply: true,
),
maxLines: 2,
- textStyle: TextStyle(
+ style: TextStyle(
color:
Theme.of(context).colorScheme.onSurfaceVariant,
overflow: TextOverflow.ellipsis,
@@ -126,10 +126,8 @@ class PinnedEvents extends StatelessWidget {
decorationColor:
Theme.of(context).colorScheme.onSurfaceVariant,
),
- beforeLaunch: (url) {
- UrlLauncher(context, url.toString()).launchUrl();
- return false;
- },
+ onOpen: (url) =>
+ UrlLauncher(context, url.url).launchUrl(),
);
},
),
diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart
index 2f33e84a..8889e877 100644
--- a/lib/pages/chat_details/chat_details_view.dart
+++ b/lib/pages/chat_details/chat_details_view.dart
@@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
+import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';
-import 'package:matrix_link_text/link_text.dart';
import 'package:vrouter/vrouter.dart';
import 'package:fluffychat/config/app_config.dart';
@@ -125,13 +125,13 @@ class ChatDetailsView extends StatelessWidget {
padding: const EdgeInsets.symmetric(
horizontal: 16.0,
),
- child: LinkText(
+ child: Linkify(
text: room.topic.isEmpty
? L10n.of(context)!.addGroupDescription
: room.topic,
linkStyle:
const TextStyle(color: Colors.blueAccent),
- textStyle: TextStyle(
+ style: TextStyle(
fontSize: 14,
color: Theme.of(context)
.textTheme
@@ -142,11 +142,8 @@ class ChatDetailsView extends StatelessWidget {
.bodyMedium!
.color,
),
- beforeLaunch: (url) {
- UrlLauncher(context, url.toString())
- .launchUrl();
- return false;
- },
+ onOpen: (url) =>
+ UrlLauncher(context, url.url).launchUrl(),
),
),
const SizedBox(height: 8),
diff --git a/lib/pages/story/story_view.dart b/lib/pages/story/story_view.dart
index 40aae425..26af6686 100644
--- a/lib/pages/story/story_view.dart
+++ b/lib/pages/story/story_view.dart
@@ -3,8 +3,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_blurhash/flutter_blurhash.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
+import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';
-import 'package:matrix_link_text/link_text.dart';
import 'package:video_player/video_player.dart';
import 'package:fluffychat/config/app_config.dart';
@@ -273,15 +273,13 @@ class StoryView extends StatelessWidget {
controller.storyThemeData.alignmentY.toDouble() / 100,
),
child: SafeArea(
- child: LinkText(
+ child: Linkify(
text: controller.loadingMode
? L10n.of(context)!.loadingPleaseWait
: event.content.tryGet('body') ?? '',
textAlign: TextAlign.center,
- beforeLaunch: (url) {
- UrlLauncher(context, url.toString()).launchUrl();
- return false;
- },
+ onOpen: (url) =>
+ UrlLauncher(context, url.url).launchUrl(),
linkStyle: TextStyle(
fontSize: 24,
color: Colors.blue.shade50,
@@ -291,7 +289,7 @@ class StoryView extends StatelessWidget {
? null
: textShadows,
),
- textStyle: TextStyle(
+ style: TextStyle(
fontSize: 24,
color: Colors.white,
shadows: event.messageType == MessageTypes.Text
diff --git a/lib/widgets/public_room_bottom_sheet.dart b/lib/widgets/public_room_bottom_sheet.dart
index 832f33bf..12a910b8 100644
--- a/lib/widgets/public_room_bottom_sheet.dart
+++ b/lib/widgets/public_room_bottom_sheet.dart
@@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
+import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:matrix/matrix.dart';
-import 'package:matrix_link_text/link_text.dart';
import 'package:vrouter/vrouter.dart';
import 'package:fluffychat/utils/url_launcher.dart';
@@ -153,17 +153,15 @@ class PublicRoomBottomSheet extends StatelessWidget {
color: Theme.of(context).colorScheme.secondary,
),
),
- subtitle: LinkText(
+ subtitle: Linkify(
text: profile!.topic!,
linkStyle: const TextStyle(color: Colors.blueAccent),
- textStyle: TextStyle(
+ style: TextStyle(
fontSize: 14,
color: Theme.of(context).textTheme.bodyMedium!.color,
),
- beforeLaunch: (url) {
- UrlLauncher(context, url.toString()).launchUrl();
- return false;
- },
+ onOpen: (url) =>
+ UrlLauncher(context, url.url).launchUrl(),
),
),
],
diff --git a/pubspec.lock b/pubspec.lock
index 05c1fd57..b41e0e33 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -113,30 +113,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.1"
- cached_network_image:
- dependency: transitive
- description:
- name: cached_network_image
- sha256: fd3d0dc1d451f9a252b32d95d3f0c3c487bc41a75eba2e6097cb0b9c71491b15
- url: "https://pub.dev"
- source: hosted
- version: "3.2.3"
- cached_network_image_platform_interface:
- dependency: transitive
- description:
- name: cached_network_image_platform_interface
- sha256: bb2b8403b4ccdc60ef5f25c70dead1f3d32d24b9d6117cfc087f496b178594a7
- url: "https://pub.dev"
- source: hosted
- version: "2.0.0"
- cached_network_image_web:
- dependency: transitive
- description:
- name: cached_network_image_web
- sha256: b8eb814ebfcb4dea049680f8c1ffb2df399e4d03bf7a352c775e26fa06e02fa0
- url: "https://pub.dev"
- source: hosted
- version: "1.0.2"
callkeep:
dependency: "direct main"
description:
@@ -467,14 +443,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.10.0"
- flutter_highlight:
- dependency: transitive
+ flutter_highlighter:
+ dependency: "direct main"
description:
- name: flutter_highlight
- sha256: "7b96333867aa07e122e245c033b8ad622e4e3a42a1a2372cbb098a2541d8782c"
+ name: flutter_highlighter
+ sha256: "93173afd47a9ada53f3176371755e7ea4a1065362763976d06d6adfb4d946e10"
url: "https://pub.dev"
source: hosted
- version: "0.7.0"
+ version: "0.1.1"
+ flutter_html:
+ dependency: "direct main"
+ description:
+ name: flutter_html
+ sha256: "850c07bc6c1ed060d3eb3e88469a598260a13eb45d8978b197c1348e0a2b101f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.0-beta.1"
flutter_keyboard_visibility:
dependency: transitive
description:
@@ -523,6 +507,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.0"
+ flutter_linkify:
+ dependency: "direct main"
+ description:
+ name: flutter_linkify
+ sha256: "74669e06a8f358fee4512b4320c0b80e51cffc496607931de68d28f099254073"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.0.0"
flutter_lints:
dependency: "direct dev"
description:
@@ -569,22 +561,13 @@ packages:
source: hosted
version: "3.1.0"
flutter_math_fork:
- dependency: "direct overridden"
- description:
- name: flutter_math_fork
- sha256: "012ca684618b74286ab84fcc2f0e8d66b03ad623b8f79aea738f6b9c287f432c"
- url: "https://pub.dev"
- source: hosted
- version: "0.7.0"
- flutter_matrix_html:
dependency: "direct main"
description:
- path: "."
- ref: "krille/fix-trying-modify-unmodifiable-list"
- resolved-ref: "97ab2982ff0429167436e15c3ae3c1b23d630c05"
- url: "https://github.com/Sorunome/flutter_matrix_html.git"
- source: git
- version: "1.1.0"
+ name: flutter_math_fork
+ sha256: a143a3a89131b578043ecbdb5e759c1033a1b3e9174f5cd1b979d93f4a7fb41c
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.7.1"
flutter_native_splash:
dependency: "direct dev"
description:
@@ -678,10 +661,10 @@ packages:
dependency: transitive
description:
name: flutter_svg
- sha256: "6ff9fa12892ae074092de2fa6a9938fb21dbabfdaa2ff57dc697ff912fc8d4b2"
+ sha256: f991fdb1533c3caeee0cdc14b04f50f0c3916f0dbcbc05237ccbe4e3c6b93f3f
url: "https://pub.dev"
source: hosted
- version: "1.1.6"
+ version: "2.0.5"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -801,14 +784,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.1.9"
- highlight:
+ highlighter:
dependency: transitive
description:
- name: highlight
- sha256: "5353a83ffe3e3eca7df0abfb72dcf3fa66cc56b953728e7113ad4ad88497cf21"
+ name: highlighter
+ sha256: "92180c72b9da8758e1acf39a45aa305a97dcfe2fdc8f3d1d2947c23f2772bfbc"
url: "https://pub.dev"
source: hosted
- version: "0.7.0"
+ version: "0.1.1"
hive:
dependency: "direct main"
description:
@@ -829,10 +812,10 @@ packages:
dependency: transitive
description:
name: html
- sha256: "79d498e6d6761925a34ee5ea8fa6dfef38607781d2fa91e37523474282af55cb"
+ sha256: "58e3491f7bf0b6a4ea5110c0c688877460d1a6366731155c4a4580e7ded773e8"
url: "https://pub.dev"
source: hosted
- version: "0.15.2"
+ version: "0.15.3"
html_unescape:
dependency: transitive
description:
@@ -934,14 +917,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.18.0"
- isolate:
- dependency: transitive
- description:
- name: isolate
- sha256: "3554ab10fdeec965d27e0074c913ccb2229887633da080d2b35a6322da14938b"
- url: "https://pub.dev"
- source: hosted
- version: "2.1.1"
js:
dependency: transitive
description:
@@ -1007,6 +982,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.8.1"
+ linkify:
+ dependency: transitive
+ description:
+ name: linkify
+ sha256: "4139ea77f4651ab9c315b577da2dd108d9aa0bd84b5d03d33323f1970c645832"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.0.0"
lints:
dependency: transitive
description:
@@ -1015,6 +998,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.1"
+ list_counter:
+ dependency: transitive
+ description:
+ name: list_counter
+ sha256: c447ae3dfcd1c55f0152867090e67e219d42fe6d4f2807db4bbe8b8d69912237
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.2"
lists:
dependency: transitive
description:
@@ -1071,15 +1062,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.3.0"
- matrix_link_text:
- dependency: "direct main"
- description:
- path: "."
- ref: "9b4d5c28dc602c17757d0eb689aafffe02719f26"
- resolved-ref: "9b4d5c28dc602c17757d0eb689aafffe02719f26"
- url: "https://github.com/TheOneWithTheBraid/matrix_link_text.git"
- source: git
- version: "1.1.0"
meta:
dependency: transitive
description:
@@ -1152,14 +1134,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.5.0"
- octo_image:
- dependency: transitive
- description:
- name: octo_image
- sha256: "107f3ed1330006a3bea63615e81cf637433f5135a52466c7caa0e7152bca9143"
- url: "https://pub.dev"
- source: hosted
- version: "1.0.2"
olm:
dependency: transitive
description:
@@ -1200,14 +1174,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.8.3"
- path_drawing:
- dependency: transitive
- description:
- name: path_drawing
- sha256: bbb1934c0cbb03091af082a6389ca2080345291ef07a5fa6d6e078ba8682f977
- url: "https://pub.dev"
- source: hosted
- version: "1.0.1"
path_parsing:
dependency: transitive
description:
@@ -1933,6 +1899,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.7"
+ vector_graphics:
+ dependency: transitive
+ description:
+ name: vector_graphics
+ sha256: ea8d3fc7b2e0f35de38a7465063ecfcf03d8217f7962aa2a6717132cb5d43a79
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.5"
+ vector_graphics_codec:
+ dependency: transitive
+ description:
+ name: vector_graphics_codec
+ sha256: a5eaa5d19e123ad4f61c3718ca1ed921c4e6254238d9145f82aa214955d9aced
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.5"
+ vector_graphics_compiler:
+ dependency: transitive
+ description:
+ name: vector_graphics_compiler
+ sha256: "15edc42f7eaa478ce854eaf1fbb9062a899c0e4e56e775dd73b7f4709c97c4ca"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.5"
vector_math:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 3a098239..33d004df 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -33,11 +33,14 @@ dependencies:
flutter_blurhash: ^0.7.0
flutter_cache_manager: ^3.3.0
flutter_foreground_task: ^3.10.0
+ flutter_highlighter: ^0.1.1
+ flutter_html: ^3.0.0-beta.1
+ flutter_linkify: ^6.0.0
flutter_local_notifications: ^12.0.2
flutter_localizations:
sdk: flutter
flutter_map: ^3.1.0
- flutter_matrix_html: ^1.1.0
+ flutter_math_fork: ^0.7.1
flutter_olm: ^1.2.0
flutter_openssl_crypto: ^0.1.0
flutter_ringtone_player: ^3.1.1
@@ -59,7 +62,6 @@ dependencies:
latlong2: ^0.8.1
matrix: ^0.20.1
matrix_homeserver_recommendations: ^0.3.0
- matrix_link_text: ^1.0.2
native_imaging: ^0.1.0
package_info_plus: ^4.0.0
path_provider: ^2.0.9
@@ -143,12 +145,6 @@ msix_config:
install_certificate: false
dependency_overrides:
- # null safety
- flutter_math_fork: ">=0.7.0"
- flutter_matrix_html:
- git:
- url: https://github.com/Sorunome/flutter_matrix_html.git
- ref: krille/fix-trying-modify-unmodifiable-list
# fake secure storage plugin for Windows
# See: https://gitlab.com/gitlab-com/gl-infra/reliability/-/issues/15161
flutter_secure_storage_windows:
@@ -165,11 +161,6 @@ dependency_overrides:
git:
url: https://github.com/TheOneWithTheBraid/keyboard_shortcuts.git
ref: null-safety
- # https://github.com/Sorunome/matrix_link_text/pull/2
- matrix_link_text:
- git:
- url: https://github.com/TheOneWithTheBraid/matrix_link_text.git
- ref: 9b4d5c28dc602c17757d0eb689aafffe02719f26
# blocked upgrade of package_info_plus for null safety
# https://github.com/creativecreatorormaybenot/wakelock/pull/203
wakelock_windows: