Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to select posts/comments #1272

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -662,4 +662,5 @@ For more information on this, and how to apply and follow the GNU AGPL, see

Portions of this software are copyright of their respective authors and released
under the MIT license:
- marquee_widget.dart, Copyright (c) 2018 Marcel Garus
- marquee_widget.dart, Copyright (c) 2018 Marcel Garus
- conditional_parent_widget.dart, Copyright (c) 2023 ltOgt
5 changes: 3 additions & 2 deletions lib/comment/view/create_comment_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -287,9 +287,9 @@ class _CreateCommentPageState extends State<CreateCommentPage> {
crossPosts: const [],
moderators: const [],
viewSource: false,
selectable: true,
showQuickPostActionBar: false,
showExpandableButton: false,
selectable: true,
),
),
),
Expand All @@ -314,8 +314,9 @@ class _CreateCommentPageState extends State<CreateCommentPage> {
isHidden: false,
viewSource: false,
onViewSourceToggled: () {},
disableActions: true,
selectable: true,
onSelectableToggled: () {},
disableActions: true,
),
),
),
Expand Down
8 changes: 8 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1443,6 +1443,10 @@
},
"selectSearchType": "Select Search Type",
"@selectSearchType": {},
"selectText": "Select text",
"@selectText": {
"description": "The ability to select post/comment text"
},
"sensitiveContentWarning": "May contain sensitive content. Tap to reveal.",
"@sensitiveContentWarning": {
"description": "Warning for sensitive content (e.g., from modlog)"
Expand Down Expand Up @@ -1655,6 +1659,10 @@
"@status": {
"description": "Status of the action"
},
"stopSelectingText": "Stop selecting text",
"@stopSelectingText": {
"description": "Option to disable text selection mode"
},
"submit": "Submit",
"@submit": {},
"subscribe": "Subscribe",
Expand Down
8 changes: 8 additions & 0 deletions lib/post/pages/post_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class _PostPageState extends State<PostPage> {
IconData? sortTypeIcon;
String? sortTypeLabel;
bool viewSource = false;
bool selectable = false;

@override
void initState() {
Expand Down Expand Up @@ -220,6 +221,12 @@ class _PostPageState extends State<PostPage> {
title: l10n.viewPostSource,
trailing: viewSource ? const Icon(Icons.check_box_rounded) : const Icon(Icons.check_box_outline_blank_rounded),
),
ThunderPopupMenuItem(
onTap: () => setState(() => selectable = !selectable),
icon: Icons.select_all_rounded,
title: l10n.selectText,
trailing: selectable ? const Icon(Icons.check_box_rounded) : const Icon(Icons.check_box_outline_blank_rounded),
),
],
),
],
Expand Down Expand Up @@ -446,6 +453,7 @@ class _PostPageState extends State<PostPage> {
moderators: state.moderators,
crossPosts: state.crossPosts,
viewSource: viewSource,
selectable: selectable,
),
);
}
Expand Down
3 changes: 3 additions & 0 deletions lib/post/pages/post_page_success.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class PostPageSuccess extends StatefulWidget {
final List<CommunityModeratorView>? moderators;
final List<PostView>? crossPosts;
final bool viewSource;
final bool selectable;

const PostPageSuccess({
super.key,
Expand All @@ -47,6 +48,7 @@ class PostPageSuccess extends StatefulWidget {
required this.moderators,
required this.crossPosts,
required this.viewSource,
required this.selectable,
});

@override
Expand Down Expand Up @@ -109,6 +111,7 @@ class _PostPageSuccessState extends State<PostPageSuccess> {
moderators: widget.moderators,
crossPosts: widget.crossPosts,
viewSource: widget.viewSource,
selectable: widget.selectable,
),
),
],
Expand Down
31 changes: 25 additions & 6 deletions lib/post/utils/comment_action_helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ enum CommentCardAction {
textActions,
copyText,
viewSource,
selectable,
report,
userActions,
visitProfile,
Expand All @@ -66,7 +67,7 @@ class ExtendedCommentCardActions {

final CommentCardAction commentCardAction;
final IconData icon;
final IconData Function(bool viewSource)? getTrailingIcon;
final IconData Function(bool viewSource, bool selectable)? getTrailingIcon;
final String label;
final Color? color;
final Color? Function(CommentView commentView)? getForegroundColor;
Expand All @@ -85,7 +86,7 @@ final List<ExtendedCommentCardActions> commentCardDefaultActionItems = [
icon: Icons.person_rounded,
label: l10n.user,
getSubtitleLabel: (context, commentView) => generateUserFullName(context, commentView.creator.name, fetchInstanceNameFromUrl(commentView.creator.actorId)),
getTrailingIcon: (_) => Icons.chevron_right_rounded,
getTrailingIcon: (_, __) => Icons.chevron_right_rounded,
),
ExtendedCommentCardActions(
commentCardAction: CommentCardAction.visitProfile,
Expand All @@ -103,7 +104,7 @@ final List<ExtendedCommentCardActions> commentCardDefaultActionItems = [
icon: Icons.language_rounded,
label: l10n.instance(1),
getSubtitleLabel: (context, postView) => fetchInstanceNameFromUrl(postView.creator.actorId) ?? '',
getTrailingIcon: (_) => Icons.chevron_right_rounded,
getTrailingIcon: (_, __) => Icons.chevron_right_rounded,
),
ExtendedCommentCardActions(
commentCardAction: CommentCardAction.visitInstance,
Expand All @@ -120,7 +121,7 @@ final List<ExtendedCommentCardActions> commentCardDefaultActionItems = [
commentCardAction: CommentCardAction.textActions,
icon: Icons.comment_rounded,
label: l10n.textActions,
getTrailingIcon: (_) => Icons.chevron_right_rounded,
getTrailingIcon: (_, __) => Icons.chevron_right_rounded,
),
ExtendedCommentCardActions(
commentCardAction: CommentCardAction.copyText,
Expand All @@ -131,7 +132,13 @@ final List<ExtendedCommentCardActions> commentCardDefaultActionItems = [
commentCardAction: CommentCardAction.viewSource,
icon: Icons.edit_document,
label: l10n.viewCommentSource,
getTrailingIcon: (viewSource) => viewSource ? Icons.check_box_rounded : Icons.check_box_outline_blank_rounded,
getTrailingIcon: (viewSource, _) => viewSource ? Icons.check_box_rounded : Icons.check_box_outline_blank_rounded,
),
ExtendedCommentCardActions(
commentCardAction: CommentCardAction.selectable,
icon: Icons.select_all_rounded,
label: l10n.selectText,
getTrailingIcon: (_, selectable) => selectable ? Icons.check_box_rounded : Icons.check_box_outline_blank_rounded,
),
ExtendedCommentCardActions(
commentCardAction: CommentCardAction.report,
Expand Down Expand Up @@ -218,6 +225,8 @@ void showCommentActionBottomModalSheet(
Function onReportAction,
Function onViewSourceToggled,
bool viewSource,
Function onSelectableToggled,
bool selectable,
) {
final bool isOwnComment = commentView.creator.id == context.read<AuthBloc>().state.account?.userId;
bool isDeleted = commentView.comment.deleted;
Expand Down Expand Up @@ -276,6 +285,7 @@ void showCommentActionBottomModalSheet(
.where((extendedAction) => [
CommentCardAction.copyText,
CommentCardAction.viewSource,
CommentCardAction.selectable,
].contains(extendedAction.commentCardAction))
.toList();

Expand Down Expand Up @@ -308,6 +318,8 @@ void showCommentActionBottomModalSheet(
onReportAction: onReportAction,
onViewSourceToggled: onViewSourceToggled,
viewSource: viewSource,
onSelectableToggled: onSelectableToggled,
selectable: selectable,
),
);
}
Expand Down Expand Up @@ -336,6 +348,8 @@ class CommentActionPicker extends StatefulWidget {
final Function onReportAction;
final Function onViewSourceToggled;
final bool viewSource;
final Function onSelectableToggled;
final bool selectable;

const CommentActionPicker({
super.key,
Expand All @@ -351,6 +365,8 @@ class CommentActionPicker extends StatefulWidget {
required this.onReportAction,
required this.onViewSourceToggled,
required this.viewSource,
required this.onSelectableToggled,
required this.selectable,
});

@override
Expand Down Expand Up @@ -451,7 +467,7 @@ class _CommentActionPickerState extends State<CommentActionPicker> {
label: widget.commentCardActions[page]![index].getOverrideLabel?.call(context, widget.commentView) ?? widget.commentCardActions[page]![index].label,
subtitle: widget.commentCardActions[page]![index].getSubtitleLabel?.call(context, widget.commentView),
icon: widget.commentCardActions[page]![index].getOverrideIcon?.call(widget.commentView) ?? widget.commentCardActions[page]![index].icon,
trailingIcon: widget.commentCardActions[page]![index].getTrailingIcon?.call(widget.viewSource),
trailingIcon: widget.commentCardActions[page]![index].getTrailingIcon?.call(widget.viewSource, widget.selectable),
onSelected:
(widget.commentCardActions[page]![index].shouldEnable?.call(isUserLoggedIn) ?? true) ? () => onSelected(widget.commentCardActions[page]![index].commentCardAction) : null,
);
Expand Down Expand Up @@ -509,6 +525,9 @@ class _CommentActionPickerState extends State<CommentActionPicker> {
case CommentCardAction.viewSource:
action = widget.onViewSourceToggled;
break;
case CommentCardAction.selectable:
action = widget.onSelectableToggled;
break;
case CommentCardAction.report:
action = () => widget.onReportAction(widget.commentView.comment.id);
break;
Expand Down
7 changes: 7 additions & 0 deletions lib/post/widgets/comment_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ class _CommentCardState extends State<CommentCard> with SingleTickerProviderStat
/// Whether we should display the comment's raw markdown source
bool viewSource = false;

/// Whether to allow selection of the text
bool selectable = false;

late final AnimationController _controller = AnimationController(
duration: const Duration(milliseconds: 100),
vsync: this,
Expand Down Expand Up @@ -363,6 +366,8 @@ class _CommentCardState extends State<CommentCard> with SingleTickerProviderStat
widget.onReportAction,
() => setState(() => viewSource = !viewSource),
viewSource,
() => setState(() => selectable = !selectable),
selectable,
);
},
onTap: () {
Expand All @@ -383,6 +388,8 @@ class _CommentCardState extends State<CommentCard> with SingleTickerProviderStat
moderators: widget.moderators,
viewSource: viewSource,
onViewSourceToggled: () => setState(() => viewSource = !viewSource),
selectable: selectable,
onSelectableToggled: () => setState(() => selectable = !selectable),
),
),
],
Expand Down
3 changes: 3 additions & 0 deletions lib/post/widgets/comment_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class CommentSubview extends StatefulWidget {
final List<CommunityModeratorView>? moderators;
final List<PostView>? crossPosts;
final bool viewSource;
final bool selectable;

const CommentSubview({
super.key,
Expand All @@ -61,6 +62,7 @@ class CommentSubview extends StatefulWidget {
required this.moderators,
required this.crossPosts,
required this.viewSource,
required this.selectable,
});

@override
Expand Down Expand Up @@ -150,6 +152,7 @@ class _CommentSubviewState extends State<CommentSubview> with SingleTickerProvid
moderators: widget.moderators,
crossPosts: widget.crossPosts,
viewSource: widget.viewSource,
selectable: widget.selectable,
),
if (widget.selectedCommentId != null && !_animatingIn && index != widget.comments.length + 1)
Center(
Expand Down
Loading
Loading