💄 Optimized post editor

This commit is contained in:
LittleSheep 2024-08-16 21:06:50 +08:00
parent af93a8386a
commit cf767a1d94
5 changed files with 132 additions and 100 deletions

View File

@ -115,7 +115,7 @@ PODS:
- TOCropViewController (~> 2.7.4)
- image_picker_ios (0.0.1):
- Flutter
- livekit_client (2.2.3):
- livekit_client (2.2.4):
- Flutter
- WebRTC-SDK (= 125.6422.04)
- media_kit_libs_ios_video (1.0.4):
@ -306,7 +306,7 @@ SPEC CHECKSUMS:
GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15
image_cropper: 37d40f62177c101ff4c164906d259ea2c3aa70cf
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
livekit_client: bad83a7776a41abc42e1f26d903eeac9164c8a9f
livekit_client: d079c5f040d4bf2b80440ff0ae997725a183e4bc
media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1
media_kit_native_event_loop: e6b2ab20cf0746eb1c33be961fcf79667304fa2a
media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e

View File

@ -260,37 +260,104 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: ListView(
child: Column(
children: [
if (_isBusy)
const LinearProgressIndicator().animate().scaleX(),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
child: TextField(
maxLines: null,
autofocus: true,
autocorrect: true,
keyboardType: TextInputType.multiline,
controller: _editorController.contentController,
focusNode: _contentFocusNode,
decoration: InputDecoration.collapsed(
hintText: 'postContentPlaceholder'.tr,
),
onTapOutside: (_) =>
FocusManager.instance.primaryFocus?.unfocus(),
Expanded(
child: ListView(
children: [
if (_isBusy)
const LinearProgressIndicator()
.animate()
.scaleX(),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
child: TextField(
maxLines: null,
autofocus: true,
autocorrect: true,
keyboardType: TextInputType.multiline,
controller:
_editorController.contentController,
focusNode: _contentFocusNode,
decoration: InputDecoration.collapsed(
hintText: 'postContentPlaceholder'.tr,
),
onTapOutside: (_) => FocusManager
.instance.primaryFocus
?.unfocus(),
),
),
const SizedBox(height: 120)
],
),
),
const SizedBox(height: 120)
Obx(() {
final textStyle = TextStyle(
fontSize: 12,
color: Theme.of(context)
.colorScheme
.onSurface
.withOpacity(0.75),
);
final showFactors = [
_editorController.isRestoreFromLocal.value,
_editorController.lastSaveTime.value != null,
];
final doShow = showFactors.any((x) => x);
return Container(
padding: const EdgeInsets.symmetric(
vertical: 4,
horizontal: 16,
),
child: Row(
children: [
if (showFactors[0])
Text('postRestoreFromLocal'.tr,
style: textStyle)
.paddingOnly(right: 4),
if (showFactors[0])
InkWell(
child: Text('clear'.tr, style: textStyle),
onTap: () {
_editorController.localClear();
_editorController.currentClear();
setState(() {});
},
),
if (showFactors.where((x) => x).length > 1)
Text(
'·',
style: textStyle,
).paddingSymmetric(horizontal: 8),
if (showFactors[1])
Text(
'postAutoSaveAt'.trParams({
'date': DateFormat('HH:mm:ss').format(
_editorController.lastSaveTime.value ??
DateTime.now(),
)
}),
style: textStyle,
),
],
),
)
.animate(
key: const Key('post-editor-hint-animation'),
target: doShow ? 1 : 0,
)
.fade(curve: Curves.easeInOut, duration: 300.ms);
}),
],
),
),
if (SolianTheme.isLargeScreen(context))
const VerticalDivider(width: 0.3, thickness: 0.3)
.paddingSymmetric(
horizontal: 8,
horizontal: 16,
),
if (SolianTheme.isLargeScreen(context))
Expanded(
@ -298,7 +365,7 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
child: MarkdownTextContent(
content: _editorController.contentController.text,
parentId: 'post-editor-preview',
).paddingOnly(top: 8),
).paddingOnly(top: 12, right: 16),
),
),
],
@ -309,85 +376,39 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Obx(() {
final textStyle = TextStyle(
fontSize: 12,
color: Theme.of(context)
.colorScheme
.onSurface
.withOpacity(0.75),
);
final showFactors = [
_editorController.isRestoreFromLocal.value,
_editorController.lastSaveTime.value != null,
];
final doShow = showFactors.any((x) => x);
return Container(
padding: const EdgeInsets.symmetric(
vertical: 4,
horizontal: 16,
),
child: Row(
children: [
if (showFactors[0])
Text('postRestoreFromLocal'.tr, style: textStyle)
.paddingOnly(right: 4),
if (showFactors[0])
InkWell(
child: Text('clear'.tr, style: textStyle),
onTap: () {
_editorController.localClear();
_editorController.currentClear();
setState(() {});
},
),
if (showFactors.where((x) => x).length > 1)
Text(
'·',
style: textStyle,
).paddingSymmetric(horizontal: 8),
if (showFactors[1])
Text(
'postAutoSaveAt'.trParams({
'date': DateFormat('HH:mm:ss').format(
_editorController.lastSaveTime.value ??
DateTime.now(),
)
}),
style: textStyle,
),
],
),
)
.animate(
key: const Key('post-editor-hint-animation'),
target: doShow ? 1 : 0,
)
.fade(curve: Curves.easeInOut, duration: 300.ms);
}),
if (_editorController.mode.value == 0)
Obx(
() => TweenAnimationBuilder<double>(
tween: Tween(
begin: 0,
end: _editorController.contentLength.value / 4096,
),
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
builder: (context, value, _) => LinearProgressIndicator(
minHeight: 2,
color: _editorController.contentLength.value > 4096
? Colors.red[900]
: Theme.of(context).colorScheme.primary,
value: value,
),
),
),
const Divider(thickness: 0.3, height: 0.3),
SizedBox(
height: 56,
child: ListView(
scrollDirection: Axis.horizontal,
children: [
if (_editorController.mode.value == 0)
Obx(
() => TweenAnimationBuilder<double>(
tween: Tween(
begin: 0,
end: _editorController.contentLength.value /
4096,
),
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
builder: (context, value, _) => SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
strokeWidth: 3,
backgroundColor: Theme.of(context)
.colorScheme
.secondaryContainer,
color: _editorController.contentLength.value >
4096
? Colors.red[900]
: Theme.of(context).colorScheme.primary,
value: value,
),
).paddingAll(10),
),
).paddingSymmetric(horizontal: 4),
Obx(() {
final isDraft = _editorController.isDraft.value;
return IconButton(

View File

@ -15,6 +15,7 @@ class AttachmentItem extends StatefulWidget {
final Attachment item;
final bool showBadge;
final bool showHideButton;
final bool autoload;
final BoxFit fit;
final String? badge;
final Function? onHide;
@ -27,6 +28,7 @@ class AttachmentItem extends StatefulWidget {
this.fit = BoxFit.cover,
this.showBadge = true,
this.showHideButton = true,
this.autoload = false,
this.onHide,
});
@ -49,7 +51,10 @@ class _AttachmentItemState extends State<AttachmentItem> {
onHide: widget.onHide,
);
case 'video':
return _AttachmentItemVideo(item: widget.item);
return _AttachmentItemVideo(
item: widget.item,
autoload: widget.autoload,
);
default:
return Center(
child: Container(

View File

@ -17,6 +17,7 @@ class AttachmentList extends StatefulWidget {
final List<int> attachmentsId;
final bool isGrid;
final bool isForceGrid;
final bool autoload;
final double flatMaxHeight;
final double? width;
@ -28,6 +29,7 @@ class AttachmentList extends StatefulWidget {
required this.attachmentsId,
this.isGrid = false,
this.isForceGrid = false,
this.autoload = false,
this.flatMaxHeight = 720,
this.width,
this.viewport,
@ -208,6 +210,7 @@ class AttachmentListEntry extends StatelessWidget {
final bool showBadge;
final bool showMature;
final bool isDense;
final bool autoload;
final Function(bool) onReveal;
const AttachmentListEntry({
@ -221,6 +224,7 @@ class AttachmentListEntry extends StatelessWidget {
this.showBadge = false,
this.showMature = false,
this.isDense = false,
this.autoload = false,
});
@override
@ -259,6 +263,7 @@ class AttachmentListEntry extends StatelessWidget {
item: item!,
badge: showBadge ? badgeContent : null,
showHideButton: !item!.isMature || showMature,
autoload: autoload,
onHide: () {
onReveal(false);
},

View File

@ -465,6 +465,7 @@ class _PostItemState extends State<PostItem> {
flatMaxHeight: MediaQuery.of(context).size.width,
parentId: widget.item.id.toString(),
attachmentsId: attachments,
autoload: true,
isGrid: attachments.length > 1,
),
if (widget.isShowReply || widget.isReactable)