mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-08-05 10:10:14 +08:00
Compare commits
4 Commits
6464987437
...
2e7c80422c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e7c80422c | ||
|
|
60f800b671 | ||
|
|
1ba6983f39 | ||
|
|
6c61ff59ff |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,10 +5,13 @@
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.build/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
.swiftpm/
|
||||
migrate_working_dir/
|
||||
Package.resolved
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
|
||||
@@ -27,7 +27,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>(
|
||||
uiScale: Pref.uiScale,
|
||||
);
|
||||
@@ -42,23 +43,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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,35 +66,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 == PanelType.keyboard ||
|
||||
panelType.value == PanelType.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();
|
||||
}
|
||||
|
||||
@@ -111,27 +111,23 @@ 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,
|
||||
),
|
||||
},
|
||||
)
|
||||
.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,
|
||||
),
|
||||
},
|
||||
)
|
||||
.toList(),
|
||||
initialPage: index,
|
||||
),
|
||||
onLongPress: () {
|
||||
Feedback.forLongPress(context);
|
||||
onClear();
|
||||
@@ -328,7 +324,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,
|
||||
@@ -345,7 +340,6 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
|
||||
res.clear();
|
||||
}
|
||||
}
|
||||
controller.restoreChatPanel();
|
||||
}
|
||||
|
||||
void _onInsertUser(MentionItem e, bool fromClick) {
|
||||
|
||||
@@ -502,7 +502,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
||||
onPressed: _isEdit || _isPrivate.value
|
||||
? null
|
||||
: () async {
|
||||
controller.keepChatPanel();
|
||||
DateTime nowDate = DateTime.now();
|
||||
final selectedDate = await showDatePicker(
|
||||
context: context,
|
||||
@@ -548,7 +547,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
||||
);
|
||||
}
|
||||
}
|
||||
controller.restoreChatPanel();
|
||||
},
|
||||
child: const Text('定时发布'),
|
||||
)
|
||||
@@ -653,7 +651,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
||||
|
||||
Widget get voteBtn => ToolbarIconButton(
|
||||
onPressed: () async {
|
||||
controller.keepChatPanel();
|
||||
final voteItem = editController.items.firstWhereOrNull(
|
||||
(e) => e.type == RichTextType.vote,
|
||||
);
|
||||
@@ -698,7 +695,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
||||
);
|
||||
}
|
||||
}
|
||||
controller.restoreChatPanel();
|
||||
},
|
||||
icon: const Icon(Icons.bar_chart_rounded, size: 24),
|
||||
tooltip: '投票',
|
||||
@@ -814,7 +810,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
||||
|
||||
double _topicOffset = 0;
|
||||
Future<void> _onSelectTopic() async {
|
||||
controller.keepChatPanel();
|
||||
TopicItem? res = await SelectTopicPanel.onSelectTopic(
|
||||
context,
|
||||
offset: _topicOffset,
|
||||
@@ -823,7 +818,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
||||
if (res != null) {
|
||||
_topic.value = Pair(first: res.id, second: res.name);
|
||||
}
|
||||
controller.restoreChatPanel();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -881,7 +875,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),
|
||||
@@ -890,6 +883,5 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
||||
if (reserveInfo != null) {
|
||||
_reserveCard.value = reserveInfo;
|
||||
}
|
||||
controller.restoreChatPanel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ class MainController extends GetxController
|
||||
}
|
||||
this.navigationBars = navigationBars;
|
||||
final defPage = Pref.defaultHomePage;
|
||||
selectedIndex.value = navigationBars.indexWhere((e) => e == defPage);
|
||||
selectedIndex.value = navigationBars.indexOf(defPage);
|
||||
}
|
||||
|
||||
void checkDefaultSearch([bool shouldCheck = false]) {
|
||||
|
||||
@@ -290,7 +290,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),
|
||||
);
|
||||
@@ -301,7 +300,6 @@ class _ReplyPageState extends CommonRichTextPubPageState<ReplyPage> {
|
||||
rawText: '${res.url} ',
|
||||
);
|
||||
}
|
||||
controller.restoreChatPanel();
|
||||
},
|
||||
icon: Icon(Icons.post_add, size: 28, color: color),
|
||||
title: '插入内容',
|
||||
|
||||
@@ -428,9 +428,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,
|
||||
@@ -446,7 +445,6 @@ class _SendDanmakuPanelState extends CommonTextPubPageState<SendDanmakuPanel> {
|
||||
),
|
||||
),
|
||||
);
|
||||
controller.restoreChatPanel();
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import 'dart:async';
|
||||
// ignore_for_file: constant_identifier_names
|
||||
|
||||
import 'dart:async' show StreamSubscription;
|
||||
|
||||
import 'package:PiliPlus/common/widgets/view_safe_area.dart';
|
||||
import 'package:PiliPlus/grpc/bilibili/app/listener/v1.pbenum.dart'
|
||||
@@ -324,7 +326,7 @@ abstract final class PiliScheme {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case 'm.bilibili.com':
|
||||
case bilibili_m:
|
||||
// bilibili://m.bilibili.com/topic-detail?topic_id=1028161&frommodule=H5&h5awaken=xxx
|
||||
final id = uri.queryParameters['topic_id'];
|
||||
if (id != null) {
|
||||
@@ -434,6 +436,15 @@ abstract final class PiliScheme {
|
||||
}
|
||||
}
|
||||
|
||||
static const b23_tv = 'b23.tv';
|
||||
static const bilibili = 'bilibili.com';
|
||||
static const bilibili_m = 'm.bilibili.com';
|
||||
static const bilibili_t = 't.bilibili.com';
|
||||
static const bilibili_live = 'live.bilibili.com';
|
||||
static const bilibili_space = 'space.bilibili.com';
|
||||
static const bilibili_search = 'search.bilibili.com';
|
||||
static const bilibili_music = 'music.bilibili.com';
|
||||
|
||||
static Future<bool> _fullPathPush(
|
||||
Uri uri, {
|
||||
bool selfHandle = false,
|
||||
@@ -445,34 +456,25 @@ abstract final class PiliScheme {
|
||||
|
||||
String host = uri.host;
|
||||
|
||||
if (selfHandle &&
|
||||
!host.contains('bilibili.com') &&
|
||||
!host.contains('b23.tv')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void launchURL() {
|
||||
if (!selfHandle) {
|
||||
_toWebview(uri.toString(), off, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
// b23.tv
|
||||
// bilibili.com
|
||||
// m.bilibili.com
|
||||
// www.bilibili.com
|
||||
// space.bilibili.com
|
||||
// live.bilibili.com
|
||||
// search.bilibili.com
|
||||
if (!host.contains(bilibili) && !host.contains(b23_tv)) {
|
||||
launchURL();
|
||||
return false;
|
||||
}
|
||||
|
||||
// redirect
|
||||
if (host.contains('b23.tv')) {
|
||||
if (host.contains(b23_tv)) {
|
||||
String? redirectUrl = await UrlUtils.parseRedirectUrl(uri.toString());
|
||||
if (redirectUrl != null) {
|
||||
uri = Uri.parse(redirectUrl);
|
||||
host = uri.host;
|
||||
}
|
||||
if (!host.contains('bilibili.com')) {
|
||||
if (!host.contains(bilibili)) {
|
||||
launchURL();
|
||||
return false;
|
||||
}
|
||||
@@ -481,7 +483,7 @@ abstract final class PiliScheme {
|
||||
final String path = uri.path;
|
||||
late final queryParameters = uri.queryParameters;
|
||||
|
||||
if (host.contains('t.bilibili.com')) {
|
||||
if (host.contains(bilibili_t)) {
|
||||
if (_onPushDynDetail(uri, off)) {
|
||||
return true;
|
||||
} else if (path.startsWith('/vote')) {
|
||||
@@ -498,7 +500,7 @@ abstract final class PiliScheme {
|
||||
}
|
||||
launchURL();
|
||||
return false;
|
||||
} else if (host.contains('live.bilibili.com')) {
|
||||
} else if (host.contains(bilibili_live)) {
|
||||
String? roomId = uriDigitRegExp.firstMatch(path)?.group(1);
|
||||
if (roomId != null) {
|
||||
PageUtils.toLiveRoom(int.parse(roomId), off: off);
|
||||
@@ -506,7 +508,7 @@ abstract final class PiliScheme {
|
||||
}
|
||||
launchURL();
|
||||
return false;
|
||||
} else if (host.contains('space.bilibili.com')) {
|
||||
} else if (host.contains(bilibili_space)) {
|
||||
void toType({
|
||||
required String mid,
|
||||
required String? type,
|
||||
@@ -556,7 +558,7 @@ abstract final class PiliScheme {
|
||||
}
|
||||
launchURL();
|
||||
return false;
|
||||
} else if (host.contains('search.bilibili.com')) {
|
||||
} else if (host.contains(bilibili_search)) {
|
||||
String? keyword = uri.queryParameters['keyword'];
|
||||
if (keyword != null) {
|
||||
PageUtils.toDupNamed(
|
||||
@@ -568,7 +570,7 @@ abstract final class PiliScheme {
|
||||
}
|
||||
launchURL();
|
||||
return false;
|
||||
} else if (host.contains('music.bilibili.com')) {
|
||||
} else if (host.contains(bilibili_music)) {
|
||||
// music.bilibili.com/pc/music-detail?music_id=MA***
|
||||
// music.bilibili.com/h5-music-detail?music_id=MA***
|
||||
if (path.contains('music-detail')) {
|
||||
|
||||
@@ -28,7 +28,9 @@ abstract final class ImageUtils {
|
||||
static String get time =>
|
||||
DateFormat('yyyy-MM-dd_HH-mm-ss').format(DateTime.now());
|
||||
static bool silentDownImg = Pref.silentDownImg;
|
||||
static const _androidRelativePath = 'Pictures/${Constants.appName}';
|
||||
static final _albumPath = Platform.isAndroid
|
||||
? 'Pictures/${Constants.appName}'
|
||||
: Constants.appName;
|
||||
|
||||
// 图片分享
|
||||
static Future<void> onShareImg(String url) async {
|
||||
@@ -210,7 +212,7 @@ abstract final class ImageUtils {
|
||||
SaveFileData(
|
||||
filePath: i.filePath,
|
||||
fileName: i.name,
|
||||
androidRelativePath: _androidRelativePath,
|
||||
albumPath: _albumPath,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
@@ -302,7 +304,7 @@ abstract final class ImageUtils {
|
||||
res = await SaverGallery.saveImage(
|
||||
bytes,
|
||||
fileName: fileName,
|
||||
androidRelativePath: _androidRelativePath,
|
||||
albumPath: _albumPath,
|
||||
skipIfExists: false,
|
||||
);
|
||||
SmartDialog.dismiss();
|
||||
@@ -346,7 +348,7 @@ abstract final class ImageUtils {
|
||||
res = await SaverGallery.saveFile(
|
||||
filePath: filePath,
|
||||
fileName: fileName,
|
||||
androidRelativePath: _androidRelativePath,
|
||||
albumPath: _albumPath,
|
||||
skipIfExists: false,
|
||||
);
|
||||
if (del) file.tryDel();
|
||||
|
||||
28
pubspec.lock
28
pubspec.lock
@@ -255,11 +255,11 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "packages/chat_bottom_container"
|
||||
ref: main
|
||||
resolved-ref: dba2bf10db4a6f89564d9be63ce17b18f0f7e3e5
|
||||
ref: dev
|
||||
resolved-ref: "227fe87aeedcd53573b17d6a6e5c08834fbc4e45"
|
||||
url: "https://github.com/bggRGjQaUbCoE/flutter_chat_packages.git"
|
||||
source: git
|
||||
version: "0.3.2"
|
||||
version: "0.5.0"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -523,7 +523,7 @@ packages:
|
||||
description:
|
||||
path: "."
|
||||
ref: dev
|
||||
resolved-ref: f6c2ab82ce7539dc26e6c16e1455b435fd2ded09
|
||||
resolved-ref: "1b1197493d734c45e178c15fe665c3dcab284cb8"
|
||||
url: "https://github.com/bggRGjQaUbCoE/flutter_file_picker.git"
|
||||
source: git
|
||||
version: "12.0.0-beta.5"
|
||||
@@ -634,7 +634,7 @@ packages:
|
||||
description:
|
||||
path: flutter_inappwebview_android
|
||||
ref: "v6.1.5"
|
||||
resolved-ref: e0e82ff8492bbc77aecc37e3b4d02c0f3e3de40f
|
||||
resolved-ref: "553d323316cc1ef5d1b73077fe42be864e3e096d"
|
||||
url: "https://github.com/bggRGjQaUbCoE/flutter_inappwebview.git"
|
||||
source: git
|
||||
version: "1.1.3"
|
||||
@@ -711,10 +711,10 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_native_splash
|
||||
sha256: "4fb9f4113350d3a80841ce05ebf1976a36de622af7d19aca0ca9a9911c7ff002"
|
||||
sha256: "9db4b80b044e9af17cc4b1272137fc7ace0054d879ef8210a76adc34aaf4cdff"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.7"
|
||||
version: "2.4.8"
|
||||
flutter_plugin_android_lifecycle:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1230,7 +1230,7 @@ packages:
|
||||
description:
|
||||
path: "."
|
||||
ref: master
|
||||
resolved-ref: "2c74f4d534dfd9b8f66382f82b3540f32be9abd9"
|
||||
resolved-ref: "7be186c79adca7d3ff5abc34bc75d171c68c2694"
|
||||
url: "https://github.com/bggRGjQaUbCoE/flutter_native_device_orientation.git"
|
||||
source: git
|
||||
version: "2.0.5"
|
||||
@@ -1358,10 +1358,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: permission_handler_apple
|
||||
sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023
|
||||
sha256: "447c18bc3c5fdea5c3039f042b2b365fd51e3634f5f6e269ed22c1f00071addc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.4.7"
|
||||
version: "9.4.8"
|
||||
permission_handler_platform_interface:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -1486,10 +1486,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: saver_gallery
|
||||
sha256: "5afc7073672f6fd073ddd15118f53f59a2bceee433e586420a3548888cd40820"
|
||||
sha256: dcecd87113ffcb0eb467bb0ef5ed8f6dd894e26ff3dfd5822624281e7d2cb894
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.2"
|
||||
version: "5.1.0"
|
||||
screen_brightness_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1892,10 +1892,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics_compiler
|
||||
sha256: b9b3f391857781aa96acacef96066f2f49b4cd03cf9fce3ca4d8da2ef5ea129e
|
||||
sha256: "7ee12e6dffe0fc8e755179d6d91b3b34f5924223fc104d85572ef9180d73d172"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.3"
|
||||
version: "1.2.5"
|
||||
vector_math:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
||||
@@ -54,8 +54,8 @@ dependencies:
|
||||
chat_bottom_container:
|
||||
git:
|
||||
url: https://github.com/bggRGjQaUbCoE/flutter_chat_packages.git
|
||||
ref: main
|
||||
path: packages/chat_bottom_container
|
||||
ref: dev
|
||||
collection: ^1.19.1
|
||||
connectivity_plus: ^7.1.1
|
||||
cookie_jar: ^4.0.8
|
||||
|
||||
Reference in New Issue
Block a user