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

View File

@ -258,12 +258,17 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
Expanded( Expanded(
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
children: [ children: [
Expanded( Expanded(
child: ListView( child: ListView(
children: [ children: [
if (_isBusy) if (_isBusy)
const LinearProgressIndicator().animate().scaleX(), const LinearProgressIndicator()
.animate()
.scaleX(),
Container( Container(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: 16, horizontal: 16,
@ -274,41 +279,21 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
autofocus: true, autofocus: true,
autocorrect: true, autocorrect: true,
keyboardType: TextInputType.multiline, keyboardType: TextInputType.multiline,
controller: _editorController.contentController, controller:
_editorController.contentController,
focusNode: _contentFocusNode, focusNode: _contentFocusNode,
decoration: InputDecoration.collapsed( decoration: InputDecoration.collapsed(
hintText: 'postContentPlaceholder'.tr, hintText: 'postContentPlaceholder'.tr,
), ),
onTapOutside: (_) => onTapOutside: (_) => FocusManager
FocusManager.instance.primaryFocus?.unfocus(), .instance.primaryFocus
?.unfocus(),
), ),
), ),
const SizedBox(height: 120) const SizedBox(height: 120)
], ],
), ),
), ),
if (SolianTheme.isLargeScreen(context))
const VerticalDivider(width: 0.3, thickness: 0.3)
.paddingSymmetric(
horizontal: 8,
),
if (SolianTheme.isLargeScreen(context))
Expanded(
child: SingleChildScrollView(
child: MarkdownTextContent(
content: _editorController.contentController.text,
parentId: 'post-editor-preview',
).paddingOnly(top: 8),
),
),
],
),
),
Material(
color: Theme.of(context).colorScheme.surface,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Obx(() { Obx(() {
final textStyle = TextStyle( final textStyle = TextStyle(
fontSize: 12, fontSize: 12,
@ -330,7 +315,8 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
child: Row( child: Row(
children: [ children: [
if (showFactors[0]) if (showFactors[0])
Text('postRestoreFromLocal'.tr, style: textStyle) Text('postRestoreFromLocal'.tr,
style: textStyle)
.paddingOnly(right: 4), .paddingOnly(right: 4),
if (showFactors[0]) if (showFactors[0])
InkWell( InkWell(
@ -365,29 +351,64 @@ class _PostPublishScreenState extends State<PostPublishScreen> {
) )
.fade(curve: Curves.easeInOut, duration: 300.ms); .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,
), ),
), ),
if (SolianTheme.isLargeScreen(context))
const VerticalDivider(width: 0.3, thickness: 0.3)
.paddingSymmetric(
horizontal: 16,
), ),
if (SolianTheme.isLargeScreen(context))
Expanded(
child: SingleChildScrollView(
child: MarkdownTextContent(
content: _editorController.contentController.text,
parentId: 'post-editor-preview',
).paddingOnly(top: 12, right: 16),
),
),
],
),
),
Material(
color: Theme.of(context).colorScheme.surface,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Divider(thickness: 0.3, height: 0.3),
SizedBox( SizedBox(
height: 56, height: 56,
child: ListView( child: ListView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
children: [ 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(() { Obx(() {
final isDraft = _editorController.isDraft.value; final isDraft = _editorController.isDraft.value;
return IconButton( return IconButton(

View File

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

View File

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

View File

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