mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2025-01-24 19:14:13 +01:00
refactor: Reimplement flutter matrix html locally
This commit is contained in:
parent
8faba7bdf2
commit
102f3bba8e
@ -1,31 +1,26 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter_matrix_html/flutter_html.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:matrix/matrix.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
import '../../../config/app_config.dart';
|
import 'package:fluffychat/widgets/avatar.dart';
|
||||||
import '../../../config/setting_keys.dart';
|
|
||||||
import '../../../utils/matrix_sdk_extensions/matrix_locals.dart';
|
|
||||||
import '../../../utils/url_launcher.dart';
|
import '../../../utils/url_launcher.dart';
|
||||||
|
|
||||||
class HtmlMessage extends StatelessWidget {
|
class HtmlMessage extends StatelessWidget {
|
||||||
final String html;
|
final String html;
|
||||||
final int? maxLines;
|
|
||||||
final Room room;
|
final Room room;
|
||||||
final TextStyle? defaultTextStyle;
|
final Color? textColor;
|
||||||
final TextStyle? linkStyle;
|
|
||||||
final double? emoteSize;
|
|
||||||
|
|
||||||
const HtmlMessage({
|
const HtmlMessage({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.html,
|
required this.html,
|
||||||
this.maxLines,
|
|
||||||
required this.room,
|
required this.room,
|
||||||
this.defaultTextStyle,
|
this.textColor,
|
||||||
this.linkStyle,
|
|
||||||
this.emoteSize,
|
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@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
|
// 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(
|
return Html(
|
||||||
data: renderHtml,
|
data: renderHtml,
|
||||||
defaultTextStyle: defaultTextStyle,
|
style: {
|
||||||
emoteSize: emoteSize,
|
'*': Style(
|
||||||
linkStyle: linkStyle ??
|
color: textColor,
|
||||||
themeData.textTheme.bodyMedium!.copyWith(
|
margin: Margins.all(0),
|
||||||
color: themeData.colorScheme.secondary,
|
fontSize: FontSize(fontSize),
|
||||||
decoration: TextDecoration.underline,
|
),
|
||||||
decorationColor: themeData.colorScheme.secondary,
|
'a': Style(color: textColor?.withAlpha(150)),
|
||||||
),
|
'h1': Style(fontSize: FontSize(fontSize * 3)),
|
||||||
shrinkToFit: true,
|
'h2': Style(fontSize: FontSize(fontSize * 2.5)),
|
||||||
maxLines: maxLines,
|
'h3': Style(fontSize: FontSize(fontSize * 2)),
|
||||||
onLinkTap: (url) => UrlLauncher(context, url).launchUrl(),
|
'h4': Style(fontSize: FontSize(fontSize * 1.75)),
|
||||||
onPillTap: (url) => UrlLauncher(context, url).launchUrl(),
|
'h5': Style(fontSize: FontSize(fontSize * 1.5)),
|
||||||
getMxcUrl: (
|
'h6': Style(fontSize: FontSize(fontSize * 1.25)),
|
||||||
String mxc,
|
// Otherwise list tiles are all in the same row$$
|
||||||
double? width,
|
'li': Style(display: Display.block),
|
||||||
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();
|
|
||||||
},
|
},
|
||||||
onImageTap: (url) => UrlLauncher(context, url).launchUrl(),
|
extensions: [
|
||||||
setCodeLanguage: (String key, String value) async {
|
UserPillExtension(context, room),
|
||||||
await matrix.store.setItem('${SettingKeys.codeLanguage}.$key', value);
|
RoomPillExtension(context, room.client),
|
||||||
},
|
CodeExtension(fontSize: fontSize),
|
||||||
getCodeLanguage: (String key) async {
|
MatrixMathExtension(
|
||||||
return await matrix.store.getItem('${SettingKeys.codeLanguage}.$key');
|
style: TextStyle(fontSize: fontSize, color: textColor),
|
||||||
},
|
),
|
||||||
getPillInfo: (String url) async {
|
],
|
||||||
final identityParts = url.parseIdentifierIntoParts();
|
onLinkTap: (url, _, __) => UrlLauncher(context, url).launchUrl(),
|
||||||
final identifier = identityParts?.primaryIdentifier;
|
onlyRenderTheseTags: const {
|
||||||
if (identifier == null) {
|
...allowedHtmlTags,
|
||||||
return {};
|
// Needed to make it work properly
|
||||||
}
|
'body',
|
||||||
if (identifier.sigil == '@') {
|
'html',
|
||||||
// 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 {};
|
|
||||||
},
|
},
|
||||||
|
shrinkWrap: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Keep in sync with: https://spec.matrix.org/v1.6/client-server-api/#mroommessage-msgtypes
|
||||||
|
static const Set<String> 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<String> 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<StyledElement, InlineSpan> 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<String> get supportedTags => {'code'};
|
||||||
|
|
||||||
|
@override
|
||||||
|
InlineSpan build(
|
||||||
|
ExtensionContext context,
|
||||||
|
Map<StyledElement, InlineSpan> 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<String> 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<StyledElement, InlineSpan> 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<String> 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<StyledElement, InlineSpan> 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<QueryPublicRoomsResponse>(
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
import 'package:flutter_linkify/flutter_linkify.dart';
|
||||||
import 'package:matrix/matrix.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/pages/chat/events/video_player.dart';
|
||||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||||
@ -150,23 +150,10 @@ class MessageContent extends StatelessWidget {
|
|||||||
if (event.messageType == MessageTypes.Emote) {
|
if (event.messageType == MessageTypes.Emote) {
|
||||||
html = '* $html';
|
html = '* $html';
|
||||||
}
|
}
|
||||||
final bigEmotes = event.onlyEmotes &&
|
|
||||||
event.numberEmotes > 0 &&
|
|
||||||
event.numberEmotes <= 10;
|
|
||||||
return HtmlMessage(
|
return HtmlMessage(
|
||||||
html: html,
|
html: html,
|
||||||
defaultTextStyle: TextStyle(
|
textColor: textColor,
|
||||||
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),
|
|
||||||
),
|
|
||||||
room: event.room,
|
room: event.room,
|
||||||
emoteSize: bigEmotes ? fontSize * 3 : fontSize * 1.5,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// else we fall through to the normal message rendering
|
// else we fall through to the normal message rendering
|
||||||
@ -242,13 +229,13 @@ class MessageContent extends StatelessWidget {
|
|||||||
hideReply: true,
|
hideReply: true,
|
||||||
),
|
),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
return LinkText(
|
return Linkify(
|
||||||
text: snapshot.data ??
|
text: snapshot.data ??
|
||||||
event.calcLocalizedBodyFallback(
|
event.calcLocalizedBodyFallback(
|
||||||
MatrixLocals(L10n.of(context)!),
|
MatrixLocals(L10n.of(context)!),
|
||||||
hideReply: true,
|
hideReply: true,
|
||||||
),
|
),
|
||||||
textStyle: TextStyle(
|
style: TextStyle(
|
||||||
color: textColor,
|
color: textColor,
|
||||||
fontSize: bigEmotes ? fontSize * 3 : fontSize,
|
fontSize: bigEmotes ? fontSize * 3 : fontSize,
|
||||||
decoration:
|
decoration:
|
||||||
@ -260,10 +247,7 @@ class MessageContent extends StatelessWidget {
|
|||||||
decoration: TextDecoration.underline,
|
decoration: TextDecoration.underline,
|
||||||
decorationColor: textColor.withAlpha(150),
|
decorationColor: textColor.withAlpha(150),
|
||||||
),
|
),
|
||||||
beforeLaunch: (url) {
|
onOpen: (url) => UrlLauncher(context, url.url).launchUrl(),
|
||||||
UrlLauncher(context, url.toString()).launchUrl();
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -5,7 +5,6 @@ import 'package:matrix/matrix.dart';
|
|||||||
|
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||||
import '../../../config/app_config.dart';
|
import '../../../config/app_config.dart';
|
||||||
import 'html_message.dart';
|
|
||||||
|
|
||||||
class ReplyContent extends StatelessWidget {
|
class ReplyContent extends StatelessWidget {
|
||||||
final Event replyEvent;
|
final Event replyEvent;
|
||||||
@ -26,47 +25,23 @@ class ReplyContent extends StatelessWidget {
|
|||||||
final displayEvent =
|
final displayEvent =
|
||||||
timeline != null ? replyEvent.getDisplayEvent(timeline) : replyEvent;
|
timeline != null ? replyEvent.getDisplayEvent(timeline) : replyEvent;
|
||||||
final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor;
|
final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor;
|
||||||
if (AppConfig.renderHtml &&
|
|
||||||
[EventTypes.Message, EventTypes.Encrypted]
|
replyBody = Text(
|
||||||
.contains(displayEvent.type) &&
|
displayEvent.calcLocalizedBodyFallback(
|
||||||
[MessageTypes.Text, MessageTypes.Notice, MessageTypes.Emote]
|
MatrixLocals(L10n.of(context)!),
|
||||||
.contains(displayEvent.messageType) &&
|
withSenderNamePrefix: false,
|
||||||
!displayEvent.redacted &&
|
hideReply: true,
|
||||||
displayEvent.content['format'] == 'org.matrix.custom.html' &&
|
),
|
||||||
displayEvent.content['formatted_body'] is String) {
|
overflow: TextOverflow.ellipsis,
|
||||||
String? html = displayEvent.content['formatted_body'];
|
maxLines: 1,
|
||||||
if (displayEvent.messageType == MessageTypes.Emote) {
|
style: TextStyle(
|
||||||
html = '* $html';
|
color: ownMessage
|
||||||
}
|
? Theme.of(context).colorScheme.onPrimary
|
||||||
replyBody = HtmlMessage(
|
: Theme.of(context).colorScheme.onBackground,
|
||||||
html: html!,
|
fontSize: fontSize,
|
||||||
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,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
@ -4,8 +4,8 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
import 'package:flutter_linkify/flutter_linkify.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:matrix_link_text/link_text.dart';
|
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.dart';
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
import 'package:fluffychat/pages/chat/chat.dart';
|
import 'package:fluffychat/pages/chat/chat.dart';
|
||||||
@ -101,7 +101,7 @@ class PinnedEvents extends StatelessWidget {
|
|||||||
hideReply: true,
|
hideReply: true,
|
||||||
),
|
),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
return LinkText(
|
return Linkify(
|
||||||
text: snapshot.data ??
|
text: snapshot.data ??
|
||||||
event.calcLocalizedBodyFallback(
|
event.calcLocalizedBodyFallback(
|
||||||
MatrixLocals(L10n.of(context)!),
|
MatrixLocals(L10n.of(context)!),
|
||||||
@ -109,7 +109,7 @@ class PinnedEvents extends StatelessWidget {
|
|||||||
hideReply: true,
|
hideReply: true,
|
||||||
),
|
),
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
textStyle: TextStyle(
|
style: TextStyle(
|
||||||
color:
|
color:
|
||||||
Theme.of(context).colorScheme.onSurfaceVariant,
|
Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
@ -126,10 +126,8 @@ class PinnedEvents extends StatelessWidget {
|
|||||||
decorationColor:
|
decorationColor:
|
||||||
Theme.of(context).colorScheme.onSurfaceVariant,
|
Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
),
|
),
|
||||||
beforeLaunch: (url) {
|
onOpen: (url) =>
|
||||||
UrlLauncher(context, url.toString()).launchUrl();
|
UrlLauncher(context, url.url).launchUrl(),
|
||||||
return false;
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
import 'package:flutter_linkify/flutter_linkify.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:matrix_link_text/link_text.dart';
|
|
||||||
import 'package:vrouter/vrouter.dart';
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.dart';
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
@ -125,13 +125,13 @@ class ChatDetailsView extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 16.0,
|
horizontal: 16.0,
|
||||||
),
|
),
|
||||||
child: LinkText(
|
child: Linkify(
|
||||||
text: room.topic.isEmpty
|
text: room.topic.isEmpty
|
||||||
? L10n.of(context)!.addGroupDescription
|
? L10n.of(context)!.addGroupDescription
|
||||||
: room.topic,
|
: room.topic,
|
||||||
linkStyle:
|
linkStyle:
|
||||||
const TextStyle(color: Colors.blueAccent),
|
const TextStyle(color: Colors.blueAccent),
|
||||||
textStyle: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
@ -142,11 +142,8 @@ class ChatDetailsView extends StatelessWidget {
|
|||||||
.bodyMedium!
|
.bodyMedium!
|
||||||
.color,
|
.color,
|
||||||
),
|
),
|
||||||
beforeLaunch: (url) {
|
onOpen: (url) =>
|
||||||
UrlLauncher(context, url.toString())
|
UrlLauncher(context, url.url).launchUrl(),
|
||||||
.launchUrl();
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
|
@ -3,8 +3,8 @@ import 'package:flutter/services.dart';
|
|||||||
|
|
||||||
import 'package:flutter_blurhash/flutter_blurhash.dart';
|
import 'package:flutter_blurhash/flutter_blurhash.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
import 'package:flutter_linkify/flutter_linkify.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:matrix_link_text/link_text.dart';
|
|
||||||
import 'package:video_player/video_player.dart';
|
import 'package:video_player/video_player.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.dart';
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
@ -273,15 +273,13 @@ class StoryView extends StatelessWidget {
|
|||||||
controller.storyThemeData.alignmentY.toDouble() / 100,
|
controller.storyThemeData.alignmentY.toDouble() / 100,
|
||||||
),
|
),
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: LinkText(
|
child: Linkify(
|
||||||
text: controller.loadingMode
|
text: controller.loadingMode
|
||||||
? L10n.of(context)!.loadingPleaseWait
|
? L10n.of(context)!.loadingPleaseWait
|
||||||
: event.content.tryGet<String>('body') ?? '',
|
: event.content.tryGet<String>('body') ?? '',
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
beforeLaunch: (url) {
|
onOpen: (url) =>
|
||||||
UrlLauncher(context, url.toString()).launchUrl();
|
UrlLauncher(context, url.url).launchUrl(),
|
||||||
return false;
|
|
||||||
},
|
|
||||||
linkStyle: TextStyle(
|
linkStyle: TextStyle(
|
||||||
fontSize: 24,
|
fontSize: 24,
|
||||||
color: Colors.blue.shade50,
|
color: Colors.blue.shade50,
|
||||||
@ -291,7 +289,7 @@ class StoryView extends StatelessWidget {
|
|||||||
? null
|
? null
|
||||||
: textShadows,
|
: textShadows,
|
||||||
),
|
),
|
||||||
textStyle: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 24,
|
fontSize: 24,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
shadows: event.messageType == MessageTypes.Text
|
shadows: event.messageType == MessageTypes.Text
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.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:future_loading_dialog/future_loading_dialog.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:matrix_link_text/link_text.dart';
|
|
||||||
import 'package:vrouter/vrouter.dart';
|
import 'package:vrouter/vrouter.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/utils/url_launcher.dart';
|
import 'package:fluffychat/utils/url_launcher.dart';
|
||||||
@ -153,17 +153,15 @@ class PublicRoomBottomSheet extends StatelessWidget {
|
|||||||
color: Theme.of(context).colorScheme.secondary,
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: LinkText(
|
subtitle: Linkify(
|
||||||
text: profile!.topic!,
|
text: profile!.topic!,
|
||||||
linkStyle: const TextStyle(color: Colors.blueAccent),
|
linkStyle: const TextStyle(color: Colors.blueAccent),
|
||||||
textStyle: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
color: Theme.of(context).textTheme.bodyMedium!.color,
|
color: Theme.of(context).textTheme.bodyMedium!.color,
|
||||||
),
|
),
|
||||||
beforeLaunch: (url) {
|
onOpen: (url) =>
|
||||||
UrlLauncher(context, url.toString()).launchUrl();
|
UrlLauncher(context, url.url).launchUrl(),
|
||||||
return false;
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
158
pubspec.lock
158
pubspec.lock
@ -113,30 +113,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
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:
|
callkeep:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -467,14 +443,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.10.0"
|
version: "3.10.0"
|
||||||
flutter_highlight:
|
flutter_highlighter:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_highlight
|
name: flutter_highlighter
|
||||||
sha256: "7b96333867aa07e122e245c033b8ad622e4e3a42a1a2372cbb098a2541d8782c"
|
sha256: "93173afd47a9ada53f3176371755e7ea4a1065362763976d06d6adfb4d946e10"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
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:
|
flutter_keyboard_visibility:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -523,6 +507,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
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:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@ -569,22 +561,13 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.0"
|
||||||
flutter_math_fork:
|
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"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
name: flutter_math_fork
|
||||||
ref: "krille/fix-trying-modify-unmodifiable-list"
|
sha256: a143a3a89131b578043ecbdb5e759c1033a1b3e9174f5cd1b979d93f4a7fb41c
|
||||||
resolved-ref: "97ab2982ff0429167436e15c3ae3c1b23d630c05"
|
url: "https://pub.dev"
|
||||||
url: "https://github.com/Sorunome/flutter_matrix_html.git"
|
source: hosted
|
||||||
source: git
|
version: "0.7.1"
|
||||||
version: "1.1.0"
|
|
||||||
flutter_native_splash:
|
flutter_native_splash:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@ -678,10 +661,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_svg
|
name: flutter_svg
|
||||||
sha256: "6ff9fa12892ae074092de2fa6a9938fb21dbabfdaa2ff57dc697ff912fc8d4b2"
|
sha256: f991fdb1533c3caeee0cdc14b04f50f0c3916f0dbcbc05237ccbe4e3c6b93f3f
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.6"
|
version: "2.0.5"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -801,14 +784,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.9"
|
version: "0.1.9"
|
||||||
highlight:
|
highlighter:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: highlight
|
name: highlighter
|
||||||
sha256: "5353a83ffe3e3eca7df0abfb72dcf3fa66cc56b953728e7113ad4ad88497cf21"
|
sha256: "92180c72b9da8758e1acf39a45aa305a97dcfe2fdc8f3d1d2947c23f2772bfbc"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.0"
|
version: "0.1.1"
|
||||||
hive:
|
hive:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -829,10 +812,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: html
|
name: html
|
||||||
sha256: "79d498e6d6761925a34ee5ea8fa6dfef38607781d2fa91e37523474282af55cb"
|
sha256: "58e3491f7bf0b6a4ea5110c0c688877460d1a6366731155c4a4580e7ded773e8"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.15.2"
|
version: "0.15.3"
|
||||||
html_unescape:
|
html_unescape:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -934,14 +917,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.18.0"
|
version: "0.18.0"
|
||||||
isolate:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: isolate
|
|
||||||
sha256: "3554ab10fdeec965d27e0074c913ccb2229887633da080d2b35a6322da14938b"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.1"
|
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1007,6 +982,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.1"
|
version: "0.8.1"
|
||||||
|
linkify:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: linkify
|
||||||
|
sha256: "4139ea77f4651ab9c315b577da2dd108d9aa0bd84b5d03d33323f1970c645832"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.0"
|
||||||
lints:
|
lints:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1015,6 +998,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
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:
|
lists:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1071,15 +1062,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.0"
|
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:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1152,14 +1134,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.0"
|
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:
|
olm:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1200,14 +1174,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.3"
|
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:
|
path_parsing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1933,6 +1899,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.7"
|
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:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
17
pubspec.yaml
17
pubspec.yaml
@ -33,11 +33,14 @@ dependencies:
|
|||||||
flutter_blurhash: ^0.7.0
|
flutter_blurhash: ^0.7.0
|
||||||
flutter_cache_manager: ^3.3.0
|
flutter_cache_manager: ^3.3.0
|
||||||
flutter_foreground_task: ^3.10.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_local_notifications: ^12.0.2
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_map: ^3.1.0
|
flutter_map: ^3.1.0
|
||||||
flutter_matrix_html: ^1.1.0
|
flutter_math_fork: ^0.7.1
|
||||||
flutter_olm: ^1.2.0
|
flutter_olm: ^1.2.0
|
||||||
flutter_openssl_crypto: ^0.1.0
|
flutter_openssl_crypto: ^0.1.0
|
||||||
flutter_ringtone_player: ^3.1.1
|
flutter_ringtone_player: ^3.1.1
|
||||||
@ -59,7 +62,6 @@ dependencies:
|
|||||||
latlong2: ^0.8.1
|
latlong2: ^0.8.1
|
||||||
matrix: ^0.20.1
|
matrix: ^0.20.1
|
||||||
matrix_homeserver_recommendations: ^0.3.0
|
matrix_homeserver_recommendations: ^0.3.0
|
||||||
matrix_link_text: ^1.0.2
|
|
||||||
native_imaging: ^0.1.0
|
native_imaging: ^0.1.0
|
||||||
package_info_plus: ^4.0.0
|
package_info_plus: ^4.0.0
|
||||||
path_provider: ^2.0.9
|
path_provider: ^2.0.9
|
||||||
@ -143,12 +145,6 @@ msix_config:
|
|||||||
install_certificate: false
|
install_certificate: false
|
||||||
|
|
||||||
dependency_overrides:
|
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
|
# fake secure storage plugin for Windows
|
||||||
# See: https://gitlab.com/gitlab-com/gl-infra/reliability/-/issues/15161
|
# See: https://gitlab.com/gitlab-com/gl-infra/reliability/-/issues/15161
|
||||||
flutter_secure_storage_windows:
|
flutter_secure_storage_windows:
|
||||||
@ -165,11 +161,6 @@ dependency_overrides:
|
|||||||
git:
|
git:
|
||||||
url: https://github.com/TheOneWithTheBraid/keyboard_shortcuts.git
|
url: https://github.com/TheOneWithTheBraid/keyboard_shortcuts.git
|
||||||
ref: null-safety
|
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
|
# blocked upgrade of package_info_plus for null safety
|
||||||
# https://github.com/creativecreatorormaybenot/wakelock/pull/203
|
# https://github.com/creativecreatorormaybenot/wakelock/pull/203
|
||||||
wakelock_windows:
|
wakelock_windows:
|
||||||
|
Loading…
Reference in New Issue
Block a user