opt publish page

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-05-28 12:58:50 +08:00
parent cf6754db0a
commit a6b4e6360c
7 changed files with 57 additions and 76 deletions

View File

@@ -25,7 +25,8 @@ abstract class CommonPublishPage<T> extends StatefulWidget {
abstract class CommonPublishPageState<T extends CommonPublishPage>
extends State<T>
with WidgetsBindingObserver {
late final FocusNode focusNode;
late bool _paused = false;
final FocusNode focusNode = FocusNode();
late final controller = ChatBottomPanelContainerController<PanelType>();
TextEditingController get editController;
@@ -38,23 +39,19 @@ abstract class CommonPublishPageState<T extends CommonPublishPage>
bool hasPub = false;
void initPubState();
bool get handleKeyboard => Platform.isAndroid && widget.autofocus;
@override
void initState() {
super.initState();
if (Platform.isAndroid) {
if (handleKeyboard) {
WidgetsBinding.instance.addObserver(this);
}
focusNode = FocusNode();
initPubState();
if (widget.autofocus) {
Future.delayed(const Duration(milliseconds: 300), () {
if (mounted) {
focusNode.requestFocus();
}
});
_requestFocus(duration: const Duration(milliseconds: 300));
}
}
@@ -65,34 +62,41 @@ abstract class CommonPublishPageState<T extends CommonPublishPage>
}
focusNode.dispose();
editController.dispose();
if (Platform.isAndroid) {
if (handleKeyboard) {
WidgetsBinding.instance.removeObserver(this);
}
super.dispose();
}
void _requestFocus() {
Future.delayed(const Duration(microseconds: 200), focusNode.requestFocus);
void _safeRequestFocus() {
if (mounted) {
focusNode.requestFocus();
}
}
void _requestFocus({Duration duration = const Duration(microseconds: 200)}) {
Future.delayed(duration, _safeRequestFocus);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
if (mounted &&
widget.autofocus &&
(panelType.value == .keyboard || panelType.value == .none)) {
controller.restoreChatPanel();
WidgetsBinding.instance.addPostFrameCallback((_) {
if (focusNode.hasFocus) {
focusNode.unfocus();
_requestFocus();
} else {
_requestFocus();
}
});
if (state == .resumed) {
if (_paused) {
_paused = false;
final panelType = this.panelType.value;
if (panelType == .keyboard || panelType == .none) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (focusNode.hasFocus) {
focusNode.unfocus();
_requestFocus();
} else {
_requestFocus();
}
});
}
}
} else if (state == AppLifecycleState.paused) {
controller.keepChatPanel();
} else if (state == .paused) {
_paused = true;
if (focusNode.hasFocus) {
focusNode.unfocus();
}

View File

@@ -108,28 +108,24 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
clipBehavior: Clip.none,
children: [
GestureDetector(
onTap: () async {
controller.keepChatPanel();
await PageUtils.imageView(
imgList: imageList
.map(
(img) => switch (img) {
FilePicModel e => SourceModel(
url: e.path,
sourceType: .fileImage,
),
OpusPicModel e => SourceModel(
url: e.url!,
sourceType: .networkImage,
size: e.size,
),
},
)
.toList(),
initialPage: index,
);
controller.restoreChatPanel();
},
onTap: () => PageUtils.imageView(
imgList: imageList
.map(
(img) => switch (img) {
FilePicModel e => SourceModel(
url: e.path,
sourceType: .fileImage,
),
OpusPicModel e => SourceModel(
url: e.url!,
sourceType: .networkImage,
size: e.size,
),
},
)
.toList(),
initialPage: index,
),
onLongPress: () {
Feedback.forLongPress(context);
onClear();
@@ -326,7 +322,6 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
late double _mentionOffset = 0;
Future<void>? onMention([bool fromClick = false]) async {
controller.keepChatPanel();
final res = await DynMentionPanel.onDynMention(
context,
offset: _mentionOffset,
@@ -343,7 +338,6 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
res.clear();
}
}
controller.restoreChatPanel();
}
void _onInsertUser(MentionItem e, bool fromClick) {

View File

@@ -498,7 +498,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
onPressed: _isEdit || _isPrivate.value
? null
: () async {
controller.keepChatPanel();
DateTime nowDate = DateTime.now();
final selectedDate = await showDatePicker(
context: context,
@@ -544,7 +543,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
);
}
}
controller.restoreChatPanel();
},
child: const Text('定时发布'),
)
@@ -649,7 +647,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
Widget get voteBtn => ToolbarIconButton(
onPressed: () async {
controller.keepChatPanel();
final voteItem = editController.items.firstWhereOrNull(
(e) => e.type == .vote,
);
@@ -694,7 +691,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
);
}
}
controller.restoreChatPanel();
},
icon: const Icon(Icons.bar_chart_rounded, size: 24),
tooltip: '投票',
@@ -812,7 +808,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
double _topicOffset = 0;
Future<void> _onSelectTopic() async {
controller.keepChatPanel();
TopicItem? res = await SelectTopicPanel.onSelectTopic(
context,
offset: _topicOffset,
@@ -821,7 +816,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
if (res != null) {
_topic.value = Pair(first: res.id, second: res.name);
}
controller.restoreChatPanel();
}
@override
@@ -879,7 +873,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
}
Future<void> _onReserve() async {
controller.keepChatPanel();
final ReserveInfoData? reserveInfo = await Navigator.of(context).push(
GetPageRoute(
page: () => CreateReservePage(sid: _reserveCard.value?.id),
@@ -888,6 +881,5 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
if (reserveInfo != null) {
_reserveCard.value = reserveInfo;
}
controller.restoreChatPanel();
}
}

View File

@@ -281,7 +281,6 @@ class _ReplyPageState extends CommonRichTextPubPageState<ReplyPage> {
children: [
item(
onTap: () async {
controller.keepChatPanel();
final ({String title, String url})? res = await Get.to(
ReplySearchPage(type: widget.replyType, oid: widget.oid),
);
@@ -292,7 +291,6 @@ class _ReplyPageState extends CommonRichTextPubPageState<ReplyPage> {
rawText: '${res.url} ',
);
}
controller.restoreChatPanel();
},
icon: Icon(Icons.post_add, size: 28, color: color),
title: '插入内容',

View File

@@ -419,9 +419,8 @@ class _SendDanmakuPanelState extends CommonTextPubPageState<SendDanmakuPanel> {
);
}
Future<void> _showColorPicker() async {
controller.keepChatPanel();
await showDialog(
void _showColorPicker() {
showDialog(
context: context,
builder: (context) => AlertDialog(
clipBehavior: Clip.hardEdge,
@@ -437,7 +436,6 @@ class _SendDanmakuPanelState extends CommonTextPubPageState<SendDanmakuPanel> {
),
),
);
controller.restoreChatPanel();
}
@override