Compare commits

..

No commits in common. "55f434ff0529420ec266543c6ad61ed005984f85" and "e2027b1a32ed9382aa973938b121545c343e499e" have entirely different histories.

7 changed files with 29 additions and 81 deletions

View File

@ -206,11 +206,10 @@ class _NotificationScreenState extends State<NotificationScreen> {
style: Theme.of(context).textTheme.titleSmall, style: Theme.of(context).textTheme.titleSmall,
), ),
if (nty.subtitle != null) const Gap(4), if (nty.subtitle != null) const Gap(4),
SelectionArea( MarkdownTextContent(
child: MarkdownTextContent( content: nty.body,
content: nty.body, isAutoWarp: true,
isAutoWarp: true, isSelectable: true,
),
), ),
if ([ if ([
'interactive.feedback', 'interactive.feedback',

View File

@ -329,7 +329,7 @@ class _AttachmentZoomViewState extends State<AttachmentZoomView> {
) )
else else
Text( Text(
item.size.formatBytes(), '${item.size} Bytes',
style: metaTextStyle, style: metaTextStyle,
), ),
if (item.metadata['width'] != null && item.metadata['height'] != null) if (item.metadata['width'] != null && item.metadata['height'] != null)

View File

@ -150,12 +150,7 @@ class ChatMessage extends StatelessWidget {
), ),
)).padding(bottom: 4, top: 4), )).padding(bottom: 4, top: 4),
switch (data.type) { switch (data.type) {
'messages.new' => _ChatMessageText( 'messages.new' => _ChatMessageText(data: data),
data: data,
onReply: onReply,
onEdit: onEdit,
onDelete: onDelete,
),
_ => _ChatMessageSystemNotify(data: data), _ => _ChatMessageSystemNotify(data: data),
}, },
], ],
@ -186,72 +181,19 @@ class ChatMessage extends StatelessWidget {
class _ChatMessageText extends StatelessWidget { class _ChatMessageText extends StatelessWidget {
final SnChatMessage data; final SnChatMessage data;
final Function(SnChatMessage)? onReply;
final Function(SnChatMessage)? onEdit;
final Function(SnChatMessage)? onDelete;
const _ChatMessageText({required this.data, this.onReply, this.onEdit, this.onDelete}); const _ChatMessageText({required this.data});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ua = context.read<UserProvider>();
final isOwner = ua.isAuthorized && data.sender.accountId == ua.user?.id;
if (data.body['text'] != null && data.body['text'].isNotEmpty) { if (data.body['text'] != null && data.body['text'].isNotEmpty) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
SelectionArea( MarkdownTextContent(
contextMenuBuilder: (context, editableTextState) { content: data.body['text'],
final List<ContextMenuButtonItem> items = editableTextState.contextMenuButtonItems; isSelectable: true,
isAutoWarp: true,
if (onReply != null) {
items.insert(
0,
ContextMenuButtonItem(
label: 'reply'.tr(),
onPressed: () {
ContextMenuController.removeAny();
onReply?.call(data);
},
),
);
}
if (isOwner && onEdit != null) {
items.insert(
1,
ContextMenuButtonItem(
label: 'edit'.tr(),
onPressed: () {
ContextMenuController.removeAny();
onEdit?.call(data);
},
),
);
}
if (isOwner && onDelete != null) {
items.insert(
2,
ContextMenuButtonItem(
label: 'delete'.tr(),
onPressed: () {
ContextMenuController.removeAny();
onDelete?.call(data);
},
),
);
}
return AdaptiveTextSelectionToolbar.buttonItems(
anchors: editableTextState.contextMenuAnchors,
buttonItems: items,
);
},
child: MarkdownTextContent(
content: data.body['text'],
isAutoWarp: true,
),
), ),
if (data.updatedAt != data.createdAt) if (data.updatedAt != data.createdAt)
Text( Text(

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart'; import 'package:flutter_animate/flutter_animate.dart';
import 'package:flutter_context_menu/flutter_context_menu.dart'; import 'package:flutter_context_menu/flutter_context_menu.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:responsive_framework/responsive_framework.dart';
import 'package:surface/providers/config.dart'; import 'package:surface/providers/config.dart';
class ContextMenuArea extends StatelessWidget { class ContextMenuArea extends StatelessWidget {

View File

@ -17,6 +17,7 @@ import 'attachment/attachment_zoom.dart';
class MarkdownTextContent extends StatelessWidget { class MarkdownTextContent extends StatelessWidget {
final String content; final String content;
final bool isSelectable;
final bool isAutoWarp; final bool isAutoWarp;
final bool isEnlargeSticker; final bool isEnlargeSticker;
final TextScaler? textScaler; final TextScaler? textScaler;
@ -25,14 +26,14 @@ class MarkdownTextContent extends StatelessWidget {
const MarkdownTextContent({ const MarkdownTextContent({
super.key, super.key,
required this.content, required this.content,
this.isSelectable = false,
this.isAutoWarp = false, this.isAutoWarp = false,
this.isEnlargeSticker = false, this.isEnlargeSticker = false,
this.textScaler, this.textScaler,
this.attachments, this.attachments,
}); });
@override Widget _buildContent(BuildContext context) {
Widget build(BuildContext context) {
return Markdown( return Markdown(
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
@ -67,7 +68,8 @@ class MarkdownTextContent extends StatelessWidget {
), ),
code: GoogleFonts.robotoMono(height: 1), code: GoogleFonts.robotoMono(height: 1),
), ),
builders: {}, builders: {
},
softLineBreak: true, softLineBreak: true,
extensionSet: markdown.ExtensionSet( extensionSet: markdown.ExtensionSet(
<markdown.BlockSyntax>[ <markdown.BlockSyntax>[
@ -142,7 +144,7 @@ class MarkdownTextContent extends StatelessWidget {
); );
case 'attachments': case 'attachments':
final attachment = attachments?.firstWhere( final attachment = attachments?.firstWhere(
(ele) => ele?.rid == segments[1], (ele) => ele?.rid == segments[1],
orElse: () => null, orElse: () => null,
); );
if (attachment != null) { if (attachment != null) {
@ -200,6 +202,14 @@ class MarkdownTextContent extends StatelessWidget {
}, },
); );
} }
@override
Widget build(BuildContext context) {
if (isSelectable) {
return SelectionArea(child: _buildContent(context));
}
return _buildContent(context);
}
} }
class _UserNameCardInlineSyntax extends markdown.InlineSyntax { class _UserNameCardInlineSyntax extends markdown.InlineSyntax {

View File

@ -879,17 +879,13 @@ class _PostContentBody extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (data.body['content'] == null) return const SizedBox.shrink(); if (data.body['content'] == null) return const SizedBox.shrink();
final content = MarkdownTextContent( return MarkdownTextContent(
isSelectable: isSelectable,
isEnlargeSticker: true, isEnlargeSticker: true,
textScaler: isEnlarge ? TextScaler.linear(1.1) : null, textScaler: isEnlarge ? TextScaler.linear(1.1) : null,
content: data.body['content'], content: data.body['content'],
attachments: data.preload?.attachments, attachments: data.preload?.attachments,
); );
if (isSelectable) {
return SelectionArea(child: content);
}
return content;
} }
} }

View File

@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 2.2.2+50 version: 2.2.2+49
environment: environment:
sdk: ^3.5.4 sdk: ^3.5.4