♻️ Dialog based editor for normal post
This commit is contained in:
@@ -20,6 +20,7 @@ import 'package:island/widgets/check_in.dart';
|
|||||||
import 'package:island/widgets/post/post_featured.dart';
|
import 'package:island/widgets/post/post_featured.dart';
|
||||||
import 'package:island/widgets/post/post_item.dart';
|
import 'package:island/widgets/post/post_item.dart';
|
||||||
import 'package:island/widgets/post/compose_card.dart';
|
import 'package:island/widgets/post/compose_card.dart';
|
||||||
|
import 'package:island/widgets/post/compose_dialog.dart';
|
||||||
import 'package:island/screens/tabs.dart';
|
import 'package:island/screens/tabs.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
@@ -43,6 +44,7 @@ Widget notificationIndicatorWidget(
|
|||||||
shape: const RoundedRectangleBorder(
|
shape: const RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(8)),
|
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||||
),
|
),
|
||||||
|
minTileHeight: 48,
|
||||||
leading: const Icon(Symbols.notifications),
|
leading: const Icon(Symbols.notifications),
|
||||||
title: Row(
|
title: Row(
|
||||||
children: [
|
children: [
|
||||||
@@ -109,7 +111,7 @@ class ExploreScreen extends HookConsumerWidget {
|
|||||||
final isWide = isWideScreen(context);
|
final isWide = isWideScreen(context);
|
||||||
|
|
||||||
final filterBar = Card(
|
final filterBar = Card(
|
||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -122,28 +124,19 @@ class ExploreScreen extends HookConsumerWidget {
|
|||||||
Tab(
|
Tab(
|
||||||
icon: Tooltip(
|
icon: Tooltip(
|
||||||
message: 'explore'.tr(),
|
message: 'explore'.tr(),
|
||||||
child: Icon(
|
child: Icon(Symbols.explore),
|
||||||
Symbols.explore,
|
|
||||||
color: Theme.of(context).appBarTheme.foregroundColor!,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Tab(
|
Tab(
|
||||||
icon: Tooltip(
|
icon: Tooltip(
|
||||||
message: 'exploreFilterSubscriptions'.tr(),
|
message: 'exploreFilterSubscriptions'.tr(),
|
||||||
child: Icon(
|
child: Icon(Symbols.subscriptions),
|
||||||
Symbols.subscriptions,
|
|
||||||
color: Theme.of(context).appBarTheme.foregroundColor!,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Tab(
|
Tab(
|
||||||
icon: Tooltip(
|
icon: Tooltip(
|
||||||
message: 'exploreFilterFriends'.tr(),
|
message: 'exploreFilterFriends'.tr(),
|
||||||
child: Icon(
|
child: Icon(Symbols.people),
|
||||||
Symbols.people,
|
|
||||||
color: Theme.of(context).appBarTheme.foregroundColor!,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -153,10 +146,7 @@ class ExploreScreen extends HookConsumerWidget {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.pushNamed('articles');
|
context.pushNamed('articles');
|
||||||
},
|
},
|
||||||
icon: Icon(
|
icon: Icon(Symbols.auto_stories),
|
||||||
Symbols.auto_stories,
|
|
||||||
color: Theme.of(context).appBarTheme.foregroundColor!,
|
|
||||||
),
|
|
||||||
tooltip: 'webArticlesStand'.tr(),
|
tooltip: 'webArticlesStand'.tr(),
|
||||||
),
|
),
|
||||||
PopupMenuButton(
|
PopupMenuButton(
|
||||||
@@ -211,10 +201,7 @@ class ExploreScreen extends HookConsumerWidget {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
icon: Icon(
|
icon: Icon(Symbols.action_key),
|
||||||
Symbols.action_key,
|
|
||||||
color: Theme.of(context).appBarTheme.foregroundColor!,
|
|
||||||
),
|
|
||||||
tooltip: 'search'.tr(),
|
tooltip: 'search'.tr(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -227,23 +214,19 @@ class ExploreScreen extends HookConsumerWidget {
|
|||||||
isWide
|
isWide
|
||||||
? null
|
? null
|
||||||
: InkWell(
|
: InkWell(
|
||||||
onLongPress: () {
|
onLongPress: () async {
|
||||||
context
|
final result = await PostComposeDialog.show(context);
|
||||||
.pushNamed('postCompose', queryParameters: {'type': '1'})
|
if (result != null) {
|
||||||
.then((value) {
|
activitiesNotifier.forceRefresh();
|
||||||
if (value != null) {
|
}
|
||||||
activitiesNotifier.forceRefresh();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
child: FloatingActionButton(
|
child: FloatingActionButton(
|
||||||
heroTag: Key("explore-page-fab"),
|
heroTag: Key("explore-page-fab"),
|
||||||
onPressed: () {
|
onPressed: () async {
|
||||||
context.pushNamed('postCompose').then((value) {
|
final result = await PostComposeDialog.show(context);
|
||||||
if (value != null) {
|
if (result != null) {
|
||||||
activitiesNotifier.forceRefresh();
|
activitiesNotifier.forceRefresh();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
},
|
},
|
||||||
child: const Icon(Symbols.edit),
|
child: const Icon(Symbols.edit),
|
||||||
),
|
),
|
||||||
|
@@ -155,6 +155,7 @@ class PostComposeCard extends HookConsumerWidget {
|
|||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
|
useRootNavigator: true,
|
||||||
builder: (context) => ComposeSettingsSheet(state: state),
|
builder: (context) => ComposeSettingsSheet(state: state),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -278,6 +279,7 @@ class PostComposeCard extends HookConsumerWidget {
|
|||||||
final config = await showModalBottomSheet<AttachmentUploadConfig>(
|
final config = await showModalBottomSheet<AttachmentUploadConfig>(
|
||||||
context: context,
|
context: context,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
|
useRootNavigator: true,
|
||||||
builder:
|
builder:
|
||||||
(context) => AttachmentUploaderSheet(
|
(context) => AttachmentUploaderSheet(
|
||||||
ref: ref,
|
ref: ref,
|
||||||
@@ -325,6 +327,7 @@ class PostComposeCard extends HookConsumerWidget {
|
|||||||
await showModalBottomSheet<AttachmentUploadConfig>(
|
await showModalBottomSheet<AttachmentUploadConfig>(
|
||||||
context: context,
|
context: context,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
|
useRootNavigator: true,
|
||||||
builder:
|
builder:
|
||||||
(context) => AttachmentUploaderSheet(
|
(context) => AttachmentUploaderSheet(
|
||||||
ref: ref,
|
ref: ref,
|
||||||
@@ -370,6 +373,7 @@ class PostComposeCard extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
// Header with actions
|
// Header with actions
|
||||||
Container(
|
Container(
|
||||||
|
height: 65,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border(
|
border: Border(
|
||||||
@@ -393,7 +397,7 @@ class PostComposeCard extends HookConsumerWidget {
|
|||||||
tooltip: 'postSettings'.tr(),
|
tooltip: 'postSettings'.tr(),
|
||||||
visualDensity: const VisualDensity(
|
visualDensity: const VisualDensity(
|
||||||
horizontal: -4,
|
horizontal: -4,
|
||||||
vertical: -4,
|
vertical: -2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
@@ -418,7 +422,7 @@ class PostComposeCard extends HookConsumerWidget {
|
|||||||
: 'postPublish'.tr(),
|
: 'postPublish'.tr(),
|
||||||
visualDensity: const VisualDensity(
|
visualDensity: const VisualDensity(
|
||||||
horizontal: -4,
|
horizontal: -4,
|
||||||
vertical: -4,
|
vertical: -2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (onCancel != null)
|
if (onCancel != null)
|
||||||
@@ -428,7 +432,7 @@ class PostComposeCard extends HookConsumerWidget {
|
|||||||
tooltip: 'cancel'.tr(),
|
tooltip: 'cancel'.tr(),
|
||||||
visualDensity: const VisualDensity(
|
visualDensity: const VisualDensity(
|
||||||
horizontal: -4,
|
horizontal: -4,
|
||||||
vertical: -4,
|
vertical: -2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -473,6 +477,7 @@ class PostComposeCard extends HookConsumerWidget {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
|
useRootNavigator: true,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => const PublisherModal(),
|
builder: (context) => const PublisherModal(),
|
||||||
).then((value) {
|
).then((value) {
|
||||||
@@ -570,12 +575,19 @@ class PostComposeCard extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
|
|
||||||
// Bottom toolbar
|
// Bottom toolbar
|
||||||
ClipRRect(
|
SizedBox(
|
||||||
borderRadius: const BorderRadius.only(
|
height: 65,
|
||||||
bottomLeft: Radius.circular(8),
|
child: ClipRRect(
|
||||||
bottomRight: Radius.circular(8),
|
borderRadius: const BorderRadius.only(
|
||||||
|
bottomLeft: Radius.circular(8),
|
||||||
|
bottomRight: Radius.circular(8),
|
||||||
|
),
|
||||||
|
child: ComposeToolbar(
|
||||||
|
state: state,
|
||||||
|
originalPost: originalPost,
|
||||||
|
isCompact: true,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: ComposeToolbar(state: state, originalPost: originalPost),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -721,6 +733,7 @@ class PostComposeCard extends HookConsumerWidget {
|
|||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
|
useRootNavigator: true,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
builder:
|
builder:
|
||||||
(context) => DraggableScrollableSheet(
|
(context) => DraggableScrollableSheet(
|
||||||
|
@@ -12,8 +12,14 @@ import 'package:styled_widget/styled_widget.dart';
|
|||||||
class ComposeToolbar extends HookConsumerWidget {
|
class ComposeToolbar extends HookConsumerWidget {
|
||||||
final ComposeState state;
|
final ComposeState state;
|
||||||
final SnPost? originalPost;
|
final SnPost? originalPost;
|
||||||
|
final bool isCompact;
|
||||||
|
|
||||||
const ComposeToolbar({super.key, required this.state, this.originalPost});
|
const ComposeToolbar({
|
||||||
|
super.key,
|
||||||
|
required this.state,
|
||||||
|
this.originalPost,
|
||||||
|
this.isCompact = false,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
@@ -74,6 +80,160 @@ class ComposeToolbar extends HookConsumerWidget {
|
|||||||
|
|
||||||
final colorScheme = Theme.of(context).colorScheme;
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
|
|
||||||
|
if (isCompact) {
|
||||||
|
return Container(
|
||||||
|
color: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
child: Center(
|
||||||
|
child: ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(maxWidth: 560),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: pickPhotoMedia,
|
||||||
|
tooltip: 'addPhoto'.tr(),
|
||||||
|
icon: const Icon(Symbols.add_a_photo),
|
||||||
|
color: colorScheme.primary,
|
||||||
|
visualDensity: const VisualDensity(
|
||||||
|
horizontal: -4,
|
||||||
|
vertical: -2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: pickVideoMedia,
|
||||||
|
tooltip: 'addVideo'.tr(),
|
||||||
|
icon: const Icon(Symbols.videocam),
|
||||||
|
color: colorScheme.primary,
|
||||||
|
visualDensity: const VisualDensity(
|
||||||
|
horizontal: -4,
|
||||||
|
vertical: -2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: addAudio,
|
||||||
|
tooltip: 'addAudio'.tr(),
|
||||||
|
icon: const Icon(Symbols.mic),
|
||||||
|
color: colorScheme.primary,
|
||||||
|
visualDensity: const VisualDensity(
|
||||||
|
horizontal: -4,
|
||||||
|
vertical: -2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: pickGeneralFile,
|
||||||
|
tooltip: 'uploadFile'.tr(),
|
||||||
|
icon: const Icon(Symbols.file_upload),
|
||||||
|
color: colorScheme.primary,
|
||||||
|
visualDensity: const VisualDensity(
|
||||||
|
horizontal: -4,
|
||||||
|
vertical: -2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: linkAttachment,
|
||||||
|
icon: const Icon(Symbols.attach_file),
|
||||||
|
tooltip: 'linkAttachment'.tr(),
|
||||||
|
color: colorScheme.primary,
|
||||||
|
visualDensity: const VisualDensity(
|
||||||
|
horizontal: -4,
|
||||||
|
vertical: -2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Poll button with visual state when a poll is linked
|
||||||
|
ListenableBuilder(
|
||||||
|
listenable: state.pollId,
|
||||||
|
builder: (context, _) {
|
||||||
|
return IconButton(
|
||||||
|
onPressed: pickPoll,
|
||||||
|
icon: const Icon(Symbols.how_to_vote),
|
||||||
|
tooltip: 'poll'.tr(),
|
||||||
|
color: colorScheme.primary,
|
||||||
|
visualDensity: const VisualDensity(
|
||||||
|
horizontal: -4,
|
||||||
|
vertical: -2,
|
||||||
|
),
|
||||||
|
style: ButtonStyle(
|
||||||
|
backgroundColor: WidgetStatePropertyAll(
|
||||||
|
state.pollId.value != null
|
||||||
|
? colorScheme.primary.withOpacity(0.15)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
// Embed button with visual state when embed is present
|
||||||
|
ListenableBuilder(
|
||||||
|
listenable: state.embedView,
|
||||||
|
builder: (context, _) {
|
||||||
|
return IconButton(
|
||||||
|
onPressed: showEmbedSheet,
|
||||||
|
icon: const Icon(Symbols.iframe),
|
||||||
|
tooltip: 'embedView'.tr(),
|
||||||
|
color: colorScheme.primary,
|
||||||
|
visualDensity: const VisualDensity(
|
||||||
|
horizontal: -4,
|
||||||
|
vertical: -2,
|
||||||
|
),
|
||||||
|
style: ButtonStyle(
|
||||||
|
backgroundColor: WidgetStatePropertyAll(
|
||||||
|
state.embedView.value != null
|
||||||
|
? colorScheme.primary.withOpacity(0.15)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (originalPost == null && state.isEmpty)
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Symbols.draft, size: 20),
|
||||||
|
color: colorScheme.primary,
|
||||||
|
onPressed: showDraftManager,
|
||||||
|
tooltip: 'drafts'.tr(),
|
||||||
|
visualDensity: const VisualDensity(
|
||||||
|
horizontal: -4,
|
||||||
|
vertical: -4,
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
minWidth: 32,
|
||||||
|
minHeight: 32,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else if (originalPost == null)
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Symbols.save, size: 20),
|
||||||
|
color: colorScheme.primary,
|
||||||
|
onPressed: saveDraft,
|
||||||
|
onLongPress: showDraftManager,
|
||||||
|
tooltip: 'saveDraft'.tr(),
|
||||||
|
visualDensity: const VisualDensity(
|
||||||
|
horizontal: -4,
|
||||||
|
vertical: -4,
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
minWidth: 32,
|
||||||
|
minHeight: 32,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).padding(horizontal: 8, vertical: 4),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return Material(
|
return Material(
|
||||||
elevation: 4,
|
elevation: 4,
|
||||||
color: Theme.of(context).colorScheme.surfaceContainerLow,
|
color: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||||
|
@@ -102,72 +102,75 @@ class PostFeaturedList extends HookConsumerWidget {
|
|||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Row(
|
SizedBox(
|
||||||
spacing: 8,
|
height: 48,
|
||||||
children: [
|
child: Row(
|
||||||
const Icon(Symbols.highlight),
|
spacing: 8,
|
||||||
const Text('highlightPost').tr(),
|
children: [
|
||||||
Spacer(),
|
const Icon(Symbols.highlight),
|
||||||
IconButton(
|
const Text('highlightPost').tr(),
|
||||||
padding: EdgeInsets.zero,
|
Spacer(),
|
||||||
visualDensity: VisualDensity.compact,
|
IconButton(
|
||||||
constraints: const BoxConstraints(),
|
padding: EdgeInsets.zero,
|
||||||
onPressed: () {
|
visualDensity: VisualDensity.compact,
|
||||||
pageViewController.animateToPage(
|
constraints: const BoxConstraints(),
|
||||||
pageViewCurrent.value - 1,
|
onPressed: () {
|
||||||
duration: const Duration(milliseconds: 250),
|
pageViewController.animateToPage(
|
||||||
curve: Curves.easeInOut,
|
pageViewCurrent.value - 1,
|
||||||
);
|
duration: const Duration(milliseconds: 250),
|
||||||
},
|
curve: Curves.easeInOut,
|
||||||
icon: const Icon(Symbols.arrow_left),
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
visualDensity: VisualDensity.compact,
|
|
||||||
constraints: const BoxConstraints(),
|
|
||||||
onPressed: () {
|
|
||||||
pageViewController.animateToPage(
|
|
||||||
pageViewCurrent.value + 1,
|
|
||||||
duration: const Duration(milliseconds: 250),
|
|
||||||
curve: Curves.easeInOut,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
icon: const Icon(Symbols.arrow_right),
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
visualDensity: VisualDensity.compact,
|
|
||||||
constraints: const BoxConstraints(),
|
|
||||||
onPressed: () {
|
|
||||||
isCollapsed.value = !isCollapsed.value;
|
|
||||||
debugPrint(
|
|
||||||
'PostFeaturedList: Manual toggle. isCollapsed set to ${isCollapsed.value}',
|
|
||||||
);
|
|
||||||
if (isCollapsed.value &&
|
|
||||||
featuredPostsAsync.hasValue &&
|
|
||||||
featuredPostsAsync.value!.isNotEmpty) {
|
|
||||||
prefs.setString(
|
|
||||||
kFeaturedPostsCollapsedId,
|
|
||||||
featuredPostsAsync.value!.first.id,
|
|
||||||
);
|
);
|
||||||
debugPrint(
|
},
|
||||||
'PostFeaturedList: Stored collapsed ID: ${featuredPostsAsync.value!.first.id}',
|
icon: const Icon(Symbols.arrow_left),
|
||||||
);
|
|
||||||
} else {
|
|
||||||
prefs.remove(kFeaturedPostsCollapsedId);
|
|
||||||
debugPrint(
|
|
||||||
'PostFeaturedList: Removed stored collapsed ID.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
icon: Icon(
|
|
||||||
isCollapsed.value
|
|
||||||
? Symbols.expand_more
|
|
||||||
: Symbols.expand_less,
|
|
||||||
),
|
),
|
||||||
),
|
IconButton(
|
||||||
],
|
padding: EdgeInsets.zero,
|
||||||
).padding(horizontal: 16, vertical: 8),
|
visualDensity: VisualDensity.compact,
|
||||||
|
constraints: const BoxConstraints(),
|
||||||
|
onPressed: () {
|
||||||
|
pageViewController.animateToPage(
|
||||||
|
pageViewCurrent.value + 1,
|
||||||
|
duration: const Duration(milliseconds: 250),
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
icon: const Icon(Symbols.arrow_right),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
constraints: const BoxConstraints(),
|
||||||
|
onPressed: () {
|
||||||
|
isCollapsed.value = !isCollapsed.value;
|
||||||
|
debugPrint(
|
||||||
|
'PostFeaturedList: Manual toggle. isCollapsed set to ${isCollapsed.value}',
|
||||||
|
);
|
||||||
|
if (isCollapsed.value &&
|
||||||
|
featuredPostsAsync.hasValue &&
|
||||||
|
featuredPostsAsync.value!.isNotEmpty) {
|
||||||
|
prefs.setString(
|
||||||
|
kFeaturedPostsCollapsedId,
|
||||||
|
featuredPostsAsync.value!.first.id,
|
||||||
|
);
|
||||||
|
debugPrint(
|
||||||
|
'PostFeaturedList: Stored collapsed ID: ${featuredPostsAsync.value!.first.id}',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
prefs.remove(kFeaturedPostsCollapsedId);
|
||||||
|
debugPrint(
|
||||||
|
'PostFeaturedList: Removed stored collapsed ID.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: Icon(
|
||||||
|
isCollapsed.value
|
||||||
|
? Symbols.expand_more
|
||||||
|
: Symbols.expand_less,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).padding(horizontal: 16, vertical: 8),
|
||||||
|
),
|
||||||
AnimatedSize(
|
AnimatedSize(
|
||||||
duration: const Duration(milliseconds: 300),
|
duration: const Duration(milliseconds: 300),
|
||||||
curve: Curves.easeInOut,
|
curve: Curves.easeInOut,
|
||||||
|
@@ -24,6 +24,7 @@ import 'package:island/widgets/post/post_shared.dart';
|
|||||||
import 'package:island/widgets/post/embed_view_renderer.dart';
|
import 'package:island/widgets/post/embed_view_renderer.dart';
|
||||||
import 'package:island/widgets/safety/abuse_report_helper.dart';
|
import 'package:island/widgets/safety/abuse_report_helper.dart';
|
||||||
import 'package:island/widgets/share/share_sheet.dart';
|
import 'package:island/widgets/share/share_sheet.dart';
|
||||||
|
import 'package:island/widgets/post/compose_dialog.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:path_provider/path_provider.dart' show getTemporaryDirectory;
|
import 'package:path_provider/path_provider.dart' show getTemporaryDirectory;
|
||||||
import 'package:screenshot/screenshot.dart';
|
import 'package:screenshot/screenshot.dart';
|
||||||
@@ -174,14 +175,14 @@ class PostActionableItem extends HookConsumerWidget {
|
|||||||
MenuAction(
|
MenuAction(
|
||||||
title: 'edit'.tr(),
|
title: 'edit'.tr(),
|
||||||
image: MenuImage.icon(Symbols.edit),
|
image: MenuImage.icon(Symbols.edit),
|
||||||
callback: () {
|
callback: () async {
|
||||||
context
|
final result = await PostComposeDialog.show(
|
||||||
.pushNamed('postEdit', pathParameters: {'id': item.id})
|
context,
|
||||||
.then((value) {
|
originalPost: item,
|
||||||
if (value != null) {
|
);
|
||||||
onRefresh?.call();
|
if (result != null) {
|
||||||
}
|
onRefresh?.call();
|
||||||
});
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (isAuthor)
|
if (isAuthor)
|
||||||
@@ -221,21 +222,27 @@ class PostActionableItem extends HookConsumerWidget {
|
|||||||
MenuAction(
|
MenuAction(
|
||||||
title: 'reply'.tr(),
|
title: 'reply'.tr(),
|
||||||
image: MenuImage.icon(Symbols.reply),
|
image: MenuImage.icon(Symbols.reply),
|
||||||
callback: () {
|
callback: () async {
|
||||||
context.pushNamed(
|
final result = await PostComposeDialog.show(
|
||||||
'postCompose',
|
context,
|
||||||
extra: PostComposeInitialState(replyingTo: item),
|
initialState: PostComposeInitialState(replyingTo: item),
|
||||||
);
|
);
|
||||||
|
if (result != null) {
|
||||||
|
onRefresh?.call();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
MenuAction(
|
MenuAction(
|
||||||
title: 'forward'.tr(),
|
title: 'forward'.tr(),
|
||||||
image: MenuImage.icon(Symbols.forward),
|
image: MenuImage.icon(Symbols.forward),
|
||||||
callback: () {
|
callback: () async {
|
||||||
context.pushNamed(
|
final result = await PostComposeDialog.show(
|
||||||
'postCompose',
|
context,
|
||||||
extra: PostComposeInitialState(forwardingTo: item),
|
initialState: PostComposeInitialState(forwardingTo: item),
|
||||||
);
|
);
|
||||||
|
if (result != null) {
|
||||||
|
onRefresh?.call();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (isAuthor && item.pinMode == null)
|
if (isAuthor && item.pinMode == null)
|
||||||
|
Reference in New Issue
Block a user