mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-07-02 15:20:18 +08:00
@@ -25,7 +25,8 @@ abstract class CommonPublishPage<T> extends StatefulWidget {
|
|||||||
abstract class CommonPublishPageState<T extends CommonPublishPage>
|
abstract class CommonPublishPageState<T extends CommonPublishPage>
|
||||||
extends State<T>
|
extends State<T>
|
||||||
with WidgetsBindingObserver {
|
with WidgetsBindingObserver {
|
||||||
late final FocusNode focusNode;
|
late bool _paused = false;
|
||||||
|
final FocusNode focusNode = FocusNode();
|
||||||
late final controller = ChatBottomPanelContainerController<PanelType>();
|
late final controller = ChatBottomPanelContainerController<PanelType>();
|
||||||
TextEditingController get editController;
|
TextEditingController get editController;
|
||||||
|
|
||||||
@@ -38,23 +39,19 @@ abstract class CommonPublishPageState<T extends CommonPublishPage>
|
|||||||
bool hasPub = false;
|
bool hasPub = false;
|
||||||
void initPubState();
|
void initPubState();
|
||||||
|
|
||||||
|
bool get handleKeyboard => Platform.isAndroid && widget.autofocus;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
if (Platform.isAndroid) {
|
if (handleKeyboard) {
|
||||||
WidgetsBinding.instance.addObserver(this);
|
WidgetsBinding.instance.addObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
focusNode = FocusNode();
|
|
||||||
|
|
||||||
initPubState();
|
initPubState();
|
||||||
|
|
||||||
if (widget.autofocus) {
|
if (widget.autofocus) {
|
||||||
Future.delayed(const Duration(milliseconds: 300), () {
|
_requestFocus(duration: const Duration(milliseconds: 300));
|
||||||
if (mounted) {
|
|
||||||
focusNode.requestFocus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,34 +62,41 @@ abstract class CommonPublishPageState<T extends CommonPublishPage>
|
|||||||
}
|
}
|
||||||
focusNode.dispose();
|
focusNode.dispose();
|
||||||
editController.dispose();
|
editController.dispose();
|
||||||
if (Platform.isAndroid) {
|
if (handleKeyboard) {
|
||||||
WidgetsBinding.instance.removeObserver(this);
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
}
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _requestFocus() {
|
void _safeRequestFocus() {
|
||||||
Future.delayed(const Duration(microseconds: 200), focusNode.requestFocus);
|
if (mounted) {
|
||||||
|
focusNode.requestFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _requestFocus({Duration duration = const Duration(microseconds: 200)}) {
|
||||||
|
Future.delayed(duration, _safeRequestFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||||
if (state == AppLifecycleState.resumed) {
|
if (state == .resumed) {
|
||||||
if (mounted &&
|
if (_paused) {
|
||||||
widget.autofocus &&
|
_paused = false;
|
||||||
(panelType.value == .keyboard || panelType.value == .none)) {
|
final panelType = this.panelType.value;
|
||||||
controller.restoreChatPanel();
|
if (panelType == .keyboard || panelType == .none) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
if (focusNode.hasFocus) {
|
if (focusNode.hasFocus) {
|
||||||
focusNode.unfocus();
|
focusNode.unfocus();
|
||||||
_requestFocus();
|
_requestFocus();
|
||||||
} else {
|
} else {
|
||||||
_requestFocus();
|
_requestFocus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (state == AppLifecycleState.paused) {
|
} else if (state == .paused) {
|
||||||
controller.keepChatPanel();
|
_paused = true;
|
||||||
if (focusNode.hasFocus) {
|
if (focusNode.hasFocus) {
|
||||||
focusNode.unfocus();
|
focusNode.unfocus();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,28 +108,24 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
|
|||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () async {
|
onTap: () => PageUtils.imageView(
|
||||||
controller.keepChatPanel();
|
imgList: imageList
|
||||||
await PageUtils.imageView(
|
.map(
|
||||||
imgList: imageList
|
(img) => switch (img) {
|
||||||
.map(
|
FilePicModel e => SourceModel(
|
||||||
(img) => switch (img) {
|
url: e.path,
|
||||||
FilePicModel e => SourceModel(
|
sourceType: .fileImage,
|
||||||
url: e.path,
|
),
|
||||||
sourceType: .fileImage,
|
OpusPicModel e => SourceModel(
|
||||||
),
|
url: e.url!,
|
||||||
OpusPicModel e => SourceModel(
|
sourceType: .networkImage,
|
||||||
url: e.url!,
|
size: e.size,
|
||||||
sourceType: .networkImage,
|
),
|
||||||
size: e.size,
|
},
|
||||||
),
|
)
|
||||||
},
|
.toList(),
|
||||||
)
|
initialPage: index,
|
||||||
.toList(),
|
),
|
||||||
initialPage: index,
|
|
||||||
);
|
|
||||||
controller.restoreChatPanel();
|
|
||||||
},
|
|
||||||
onLongPress: () {
|
onLongPress: () {
|
||||||
Feedback.forLongPress(context);
|
Feedback.forLongPress(context);
|
||||||
onClear();
|
onClear();
|
||||||
@@ -326,7 +322,6 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
|
|||||||
|
|
||||||
late double _mentionOffset = 0;
|
late double _mentionOffset = 0;
|
||||||
Future<void>? onMention([bool fromClick = false]) async {
|
Future<void>? onMention([bool fromClick = false]) async {
|
||||||
controller.keepChatPanel();
|
|
||||||
final res = await DynMentionPanel.onDynMention(
|
final res = await DynMentionPanel.onDynMention(
|
||||||
context,
|
context,
|
||||||
offset: _mentionOffset,
|
offset: _mentionOffset,
|
||||||
@@ -343,7 +338,6 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
|
|||||||
res.clear();
|
res.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
controller.restoreChatPanel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onInsertUser(MentionItem e, bool fromClick) {
|
void _onInsertUser(MentionItem e, bool fromClick) {
|
||||||
|
|||||||
@@ -498,7 +498,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
|||||||
onPressed: _isEdit || _isPrivate.value
|
onPressed: _isEdit || _isPrivate.value
|
||||||
? null
|
? null
|
||||||
: () async {
|
: () async {
|
||||||
controller.keepChatPanel();
|
|
||||||
DateTime nowDate = DateTime.now();
|
DateTime nowDate = DateTime.now();
|
||||||
final selectedDate = await showDatePicker(
|
final selectedDate = await showDatePicker(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -544,7 +543,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
controller.restoreChatPanel();
|
|
||||||
},
|
},
|
||||||
child: const Text('定时发布'),
|
child: const Text('定时发布'),
|
||||||
)
|
)
|
||||||
@@ -649,7 +647,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
|||||||
|
|
||||||
Widget get voteBtn => ToolbarIconButton(
|
Widget get voteBtn => ToolbarIconButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
controller.keepChatPanel();
|
|
||||||
final voteItem = editController.items.firstWhereOrNull(
|
final voteItem = editController.items.firstWhereOrNull(
|
||||||
(e) => e.type == .vote,
|
(e) => e.type == .vote,
|
||||||
);
|
);
|
||||||
@@ -694,7 +691,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
controller.restoreChatPanel();
|
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.bar_chart_rounded, size: 24),
|
icon: const Icon(Icons.bar_chart_rounded, size: 24),
|
||||||
tooltip: '投票',
|
tooltip: '投票',
|
||||||
@@ -812,7 +808,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
|||||||
|
|
||||||
double _topicOffset = 0;
|
double _topicOffset = 0;
|
||||||
Future<void> _onSelectTopic() async {
|
Future<void> _onSelectTopic() async {
|
||||||
controller.keepChatPanel();
|
|
||||||
TopicItem? res = await SelectTopicPanel.onSelectTopic(
|
TopicItem? res = await SelectTopicPanel.onSelectTopic(
|
||||||
context,
|
context,
|
||||||
offset: _topicOffset,
|
offset: _topicOffset,
|
||||||
@@ -821,7 +816,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
|||||||
if (res != null) {
|
if (res != null) {
|
||||||
_topic.value = Pair(first: res.id, second: res.name);
|
_topic.value = Pair(first: res.id, second: res.name);
|
||||||
}
|
}
|
||||||
controller.restoreChatPanel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -879,7 +873,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onReserve() async {
|
Future<void> _onReserve() async {
|
||||||
controller.keepChatPanel();
|
|
||||||
final ReserveInfoData? reserveInfo = await Navigator.of(context).push(
|
final ReserveInfoData? reserveInfo = await Navigator.of(context).push(
|
||||||
GetPageRoute(
|
GetPageRoute(
|
||||||
page: () => CreateReservePage(sid: _reserveCard.value?.id),
|
page: () => CreateReservePage(sid: _reserveCard.value?.id),
|
||||||
@@ -888,6 +881,5 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
|||||||
if (reserveInfo != null) {
|
if (reserveInfo != null) {
|
||||||
_reserveCard.value = reserveInfo;
|
_reserveCard.value = reserveInfo;
|
||||||
}
|
}
|
||||||
controller.restoreChatPanel();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,7 +281,6 @@ class _ReplyPageState extends CommonRichTextPubPageState<ReplyPage> {
|
|||||||
children: [
|
children: [
|
||||||
item(
|
item(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
controller.keepChatPanel();
|
|
||||||
final ({String title, String url})? res = await Get.to(
|
final ({String title, String url})? res = await Get.to(
|
||||||
ReplySearchPage(type: widget.replyType, oid: widget.oid),
|
ReplySearchPage(type: widget.replyType, oid: widget.oid),
|
||||||
);
|
);
|
||||||
@@ -292,7 +291,6 @@ class _ReplyPageState extends CommonRichTextPubPageState<ReplyPage> {
|
|||||||
rawText: '${res.url} ',
|
rawText: '${res.url} ',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
controller.restoreChatPanel();
|
|
||||||
},
|
},
|
||||||
icon: Icon(Icons.post_add, size: 28, color: color),
|
icon: Icon(Icons.post_add, size: 28, color: color),
|
||||||
title: '插入内容',
|
title: '插入内容',
|
||||||
|
|||||||
@@ -419,9 +419,8 @@ class _SendDanmakuPanelState extends CommonTextPubPageState<SendDanmakuPanel> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _showColorPicker() async {
|
void _showColorPicker() {
|
||||||
controller.keepChatPanel();
|
showDialog(
|
||||||
await showDialog(
|
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
@@ -437,7 +436,6 @@ class _SendDanmakuPanelState extends CommonTextPubPageState<SendDanmakuPanel> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
controller.restoreChatPanel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
11
pubspec.lock
11
pubspec.lock
@@ -255,12 +255,11 @@ packages:
|
|||||||
chat_bottom_container:
|
chat_bottom_container:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "packages/chat_bottom_container"
|
name: chat_bottom_container
|
||||||
ref: main
|
sha256: e9c3b9879251658e403d2a93057c5db469c99237fef62ca562ec6d223970ef41
|
||||||
resolved-ref: dba2bf10db4a6f89564d9be63ce17b18f0f7e3e5
|
url: "https://pub.dev"
|
||||||
url: "https://github.com/bggRGjQaUbCoE/flutter_chat_packages.git"
|
source: hosted
|
||||||
source: git
|
version: "0.5.0"
|
||||||
version: "0.3.2"
|
|
||||||
checked_yaml:
|
checked_yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -55,11 +55,7 @@ dependencies:
|
|||||||
url: https://github.com/My-Responsitories/catcher_2.git
|
url: https://github.com/My-Responsitories/catcher_2.git
|
||||||
ref: dev
|
ref: dev
|
||||||
characters: ^1.4.1
|
characters: ^1.4.1
|
||||||
chat_bottom_container:
|
chat_bottom_container: ^0.5.0
|
||||||
git:
|
|
||||||
url: https://github.com/bggRGjQaUbCoE/flutter_chat_packages.git
|
|
||||||
ref: main
|
|
||||||
path: packages/chat_bottom_container
|
|
||||||
collection: ^1.19.1
|
collection: ^1.19.1
|
||||||
connectivity_plus: ^7.1.1
|
connectivity_plus: ^7.1.1
|
||||||
cookie_jar: ^4.0.8
|
cookie_jar: ^4.0.8
|
||||||
|
|||||||
Reference in New Issue
Block a user