Compare commits
2 Commits
5d4b896f70
...
6c48aa2356
Author | SHA1 | Date | |
---|---|---|---|
|
6c48aa2356 | ||
|
466e354679 |
@@ -841,5 +841,8 @@
|
|||||||
"messageJumpNotLoaded": "The referenced message was not loaded, unable to jump to it.",
|
"messageJumpNotLoaded": "The referenced message was not loaded, unable to jump to it.",
|
||||||
"postUnlinkRealm": "No linked realm",
|
"postUnlinkRealm": "No linked realm",
|
||||||
"postSlug": "Slug",
|
"postSlug": "Slug",
|
||||||
"postSlugHint": "The slug can be used to access your post via URL in the webpage, it should be publisher-wide unique."
|
"postSlugHint": "The slug can be used to access your post via URL in the webpage, it should be publisher-wide unique.",
|
||||||
|
"attachmentOnDevice": "On-device",
|
||||||
|
"attachmentOnCloud": "On-cloud",
|
||||||
|
"attachments": "Attachments"
|
||||||
}
|
}
|
||||||
|
@@ -816,5 +816,7 @@
|
|||||||
"messageJumpNotLoaded": "引用的消息没有被加载,无法跳转。",
|
"messageJumpNotLoaded": "引用的消息没有被加载,无法跳转。",
|
||||||
"postUnlinkRealm": "不关联领域",
|
"postUnlinkRealm": "不关联领域",
|
||||||
"postSlug": "别名",
|
"postSlug": "别名",
|
||||||
"postSlugHint": "这个别名可以用于在网页通过 URL 浏览到你的帖子,它应该在同一发布者中是唯一。"
|
"postSlugHint": "这个别名可以用于在网页通过 URL 浏览到你的帖子,它应该在同一发布者中是唯一。",
|
||||||
|
"attachmentOnDevice": "离线",
|
||||||
|
"attachmentOnCloud": "在线"
|
||||||
}
|
}
|
||||||
|
@@ -89,6 +89,9 @@ class ArticleComposeScreen extends HookConsumerWidget {
|
|||||||
}, [state]);
|
}, [state]);
|
||||||
|
|
||||||
final showPreview = useState(false);
|
final showPreview = useState(false);
|
||||||
|
final isAttachmentsExpanded = useState(
|
||||||
|
true,
|
||||||
|
); // New state for attachments section
|
||||||
|
|
||||||
// Initialize publisher once when data is available
|
// Initialize publisher once when data is available
|
||||||
useEffect(() {
|
useEffect(() {
|
||||||
@@ -297,71 +300,88 @@ class ArticleComposeScreen extends HookConsumerWidget {
|
|||||||
valueListenable: state.attachments,
|
valueListenable: state.attachments,
|
||||||
builder: (context, attachments, _) {
|
builder: (context, attachments, _) {
|
||||||
if (attachments.isEmpty) return const SizedBox.shrink();
|
if (attachments.isEmpty) return const SizedBox.shrink();
|
||||||
return Column(
|
return Theme(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
data: Theme.of(
|
||||||
children: [
|
context,
|
||||||
const Gap(16),
|
).copyWith(dividerColor: Colors.transparent),
|
||||||
Text(
|
child: ExpansionTile(
|
||||||
'articleAttachmentHint'.tr(),
|
initiallyExpanded: isAttachmentsExpanded.value,
|
||||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
onExpansionChanged: (expanded) {
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
isAttachmentsExpanded.value = expanded;
|
||||||
),
|
},
|
||||||
).padding(bottom: 8),
|
collapsedBackgroundColor:
|
||||||
ValueListenableBuilder<Map<int, double>>(
|
Theme.of(context).colorScheme.surfaceContainer,
|
||||||
valueListenable: state.attachmentProgress,
|
title: Column(
|
||||||
builder: (context, progressMap, _) {
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
return Wrap(
|
children: [
|
||||||
runSpacing: 8,
|
Text('attachments').tr(),
|
||||||
spacing: 8,
|
Text(
|
||||||
children: [
|
'articleAttachmentHint'.tr(),
|
||||||
for (var idx = 0; idx < attachments.length; idx++)
|
style: Theme.of(
|
||||||
SizedBox(
|
context,
|
||||||
width: 280,
|
).textTheme.bodySmall?.copyWith(
|
||||||
height: 280,
|
color:
|
||||||
child: AttachmentPreview(
|
Theme.of(
|
||||||
item: attachments[idx],
|
context,
|
||||||
progress: progressMap[idx],
|
).colorScheme.onSurfaceVariant,
|
||||||
onRequestUpload:
|
),
|
||||||
() => ComposeLogic.uploadAttachment(
|
),
|
||||||
ref,
|
],
|
||||||
state,
|
|
||||||
idx,
|
|
||||||
),
|
|
||||||
onUpdate:
|
|
||||||
(value) =>
|
|
||||||
ComposeLogic.updateAttachment(
|
|
||||||
state,
|
|
||||||
value,
|
|
||||||
idx,
|
|
||||||
),
|
|
||||||
onDelete:
|
|
||||||
() => ComposeLogic.deleteAttachment(
|
|
||||||
ref,
|
|
||||||
state,
|
|
||||||
idx,
|
|
||||||
),
|
|
||||||
onMove: (delta) {
|
|
||||||
state
|
|
||||||
.attachments
|
|
||||||
.value = ComposeLogic.moveAttachment(
|
|
||||||
state.attachments.value,
|
|
||||||
idx,
|
|
||||||
delta,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
onInsert:
|
|
||||||
() => ComposeLogic.insertAttachment(
|
|
||||||
ref,
|
|
||||||
state,
|
|
||||||
idx,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
],
|
children: [
|
||||||
|
ValueListenableBuilder<Map<int, double>>(
|
||||||
|
valueListenable: state.attachmentProgress,
|
||||||
|
builder: (context, progressMap, _) {
|
||||||
|
return Wrap(
|
||||||
|
runSpacing: 8,
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
for (
|
||||||
|
var idx = 0;
|
||||||
|
idx < attachments.length;
|
||||||
|
idx++
|
||||||
|
)
|
||||||
|
SizedBox(
|
||||||
|
width: 180,
|
||||||
|
height: 180,
|
||||||
|
child: AttachmentPreview(
|
||||||
|
isCompact: true,
|
||||||
|
item: attachments[idx],
|
||||||
|
progress: progressMap[idx],
|
||||||
|
onRequestUpload:
|
||||||
|
() => ComposeLogic.uploadAttachment(
|
||||||
|
ref,
|
||||||
|
state,
|
||||||
|
idx,
|
||||||
|
),
|
||||||
|
onUpdate:
|
||||||
|
(value) =>
|
||||||
|
ComposeLogic.updateAttachment(
|
||||||
|
state,
|
||||||
|
value,
|
||||||
|
idx,
|
||||||
|
),
|
||||||
|
onDelete:
|
||||||
|
() => ComposeLogic.deleteAttachment(
|
||||||
|
ref,
|
||||||
|
state,
|
||||||
|
idx,
|
||||||
|
),
|
||||||
|
onInsert:
|
||||||
|
() => ComposeLogic.insertAttachment(
|
||||||
|
ref,
|
||||||
|
state,
|
||||||
|
idx,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Gap(16),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@@ -88,6 +88,7 @@ class AttachmentPreview extends HookConsumerWidget {
|
|||||||
final Function? onInsert;
|
final Function? onInsert;
|
||||||
final Function(UniversalFile)? onUpdate;
|
final Function(UniversalFile)? onUpdate;
|
||||||
final Function? onRequestUpload;
|
final Function? onRequestUpload;
|
||||||
|
final bool isCompact;
|
||||||
|
|
||||||
const AttachmentPreview({
|
const AttachmentPreview({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -98,6 +99,7 @@ class AttachmentPreview extends HookConsumerWidget {
|
|||||||
this.onDelete,
|
this.onDelete,
|
||||||
this.onUpdate,
|
this.onUpdate,
|
||||||
this.onInsert,
|
this.onInsert,
|
||||||
|
this.isCompact = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// GlobalKey for selector
|
// GlobalKey for selector
|
||||||
@@ -361,7 +363,7 @@ class AttachmentPreview extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
).center(),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
@@ -458,11 +460,12 @@ class AttachmentPreview extends HookConsumerWidget {
|
|||||||
size: 16,
|
size: 16,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
const Gap(8),
|
if (!isCompact) const Gap(8),
|
||||||
Text(
|
if (!isCompact)
|
||||||
'On-cloud',
|
Text(
|
||||||
style: TextStyle(color: Colors.white),
|
'attachmentOnCloud'.tr(),
|
||||||
),
|
style: TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: Row(
|
: Row(
|
||||||
@@ -473,11 +476,12 @@ class AttachmentPreview extends HookConsumerWidget {
|
|||||||
size: 16,
|
size: 16,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
const Gap(8),
|
if (!isCompact) const Gap(8),
|
||||||
Text(
|
if (!isCompact)
|
||||||
'On-device',
|
Text(
|
||||||
style: TextStyle(color: Colors.white),
|
'attachmentOnDevice'.tr(),
|
||||||
),
|
style: TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Reference in New Issue
Block a user