mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -6,15 +6,16 @@ import 'package:PiliPlus/utils/extension.dart';
|
|||||||
import 'package:PiliPlus/utils/storage.dart';
|
import 'package:PiliPlus/utils/storage.dart';
|
||||||
import 'package:PiliPlus/utils/utils.dart';
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:media_kit/media_kit.dart';
|
import 'package:media_kit/media_kit.dart';
|
||||||
import 'package:media_kit_video/media_kit_video.dart';
|
import 'package:media_kit_video/media_kit_video.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
import 'package:status_bar_control/status_bar_control.dart';
|
|
||||||
import 'interactive_viewer_boundary.dart';
|
import 'interactive_viewer_boundary.dart';
|
||||||
import 'interactive_viewer.dart' as custom;
|
import 'interactive_viewer.dart' as custom;
|
||||||
|
|
||||||
@@ -142,17 +143,21 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
|||||||
_transformationController!.value = _animation?.value ?? Matrix4.identity();
|
_transformationController!.value = _animation?.value ?? Matrix4.identity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SystemUiMode? mode;
|
||||||
setStatusBar() async {
|
setStatusBar() async {
|
||||||
if (Platform.isIOS || Platform.isAndroid) {
|
if (Platform.isIOS || Platform.isAndroid) {
|
||||||
await StatusBarControl.setHidden(
|
SystemChrome.setEnabledSystemUIMode(
|
||||||
true,
|
SystemUiMode.immersiveSticky,
|
||||||
animation: StatusBarAnimation.FADE,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (Platform.isAndroid &&
|
||||||
|
(await DeviceInfoPlugin().androidInfo).version.sdkInt < 29) {
|
||||||
|
mode = SystemUiMode.manual;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() async {
|
void dispose() {
|
||||||
widget.onClose?.call(true);
|
widget.onClose?.call(true);
|
||||||
_player?.dispose();
|
_player?.dispose();
|
||||||
_pageController?.dispose();
|
_pageController?.dispose();
|
||||||
@@ -160,7 +165,10 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
|||||||
_animationController.dispose();
|
_animationController.dispose();
|
||||||
if (widget.setStatusBar != false) {
|
if (widget.setStatusBar != false) {
|
||||||
if (Platform.isIOS || Platform.isAndroid) {
|
if (Platform.isIOS || Platform.isAndroid) {
|
||||||
StatusBarControl.setHidden(false, animation: StatusBarAnimation.FADE);
|
SystemChrome.setEnabledSystemUIMode(
|
||||||
|
mode ?? SystemUiMode.edgeToEdge,
|
||||||
|
overlays: SystemUiOverlay.values,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int index = 0; index < widget.sources.length; index++) {
|
for (int index = 0; index < widget.sources.length; index++) {
|
||||||
|
|||||||
@@ -41,134 +41,137 @@ class VideoCardH extends StatelessWidget {
|
|||||||
try {
|
try {
|
||||||
type = videoItem.type;
|
type = videoItem.type;
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
return Stack(
|
return Material(
|
||||||
children: [
|
color: Colors.transparent,
|
||||||
Semantics(
|
child: Stack(
|
||||||
label: Utils.videoItemSemantics(videoItem),
|
children: [
|
||||||
excludeSemantics: true,
|
Semantics(
|
||||||
// customSemanticsActions: <CustomSemanticsAction, void Function()>{
|
label: Utils.videoItemSemantics(videoItem),
|
||||||
// for (var item in actions)
|
excludeSemantics: true,
|
||||||
// CustomSemanticsAction(
|
// customSemanticsActions: <CustomSemanticsAction, void Function()>{
|
||||||
// label: item.title.isEmpty ? 'label' : item.title): item.onTap!,
|
// for (var item in actions)
|
||||||
// },
|
// CustomSemanticsAction(
|
||||||
child: InkWell(
|
// label: item.title.isEmpty ? 'label' : item.title): item.onTap!,
|
||||||
onLongPress: () {
|
// },
|
||||||
if (onLongPress != null) {
|
child: InkWell(
|
||||||
onLongPress!();
|
onLongPress: () {
|
||||||
} else {
|
if (onLongPress != null) {
|
||||||
imageSaveDialog(
|
onLongPress!();
|
||||||
context: context,
|
} else {
|
||||||
title: videoItem.title is String
|
imageSaveDialog(
|
||||||
? videoItem.title
|
context: context,
|
||||||
: videoItem.title is List
|
title: videoItem.title is String
|
||||||
? (videoItem.title as List)
|
? videoItem.title
|
||||||
.map((item) => item['text'])
|
: videoItem.title is List
|
||||||
.join()
|
? (videoItem.title as List)
|
||||||
: '',
|
.map((item) => item['text'])
|
||||||
cover: videoItem.pic,
|
.join()
|
||||||
);
|
: '',
|
||||||
}
|
cover: videoItem.pic,
|
||||||
},
|
);
|
||||||
onTap: () async {
|
}
|
||||||
if (onTap != null) {
|
},
|
||||||
onTap?.call();
|
onTap: () async {
|
||||||
return;
|
if (onTap != null) {
|
||||||
}
|
onTap?.call();
|
||||||
if (type == 'ketang') {
|
|
||||||
SmartDialog.showToast('课堂视频暂不支持播放');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (videoItem is HotVideoItemModel &&
|
|
||||||
videoItem.redirectUrl?.isNotEmpty == true) {
|
|
||||||
if (Utils.viewPgcFromUri(videoItem.redirectUrl!)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
if (type == 'ketang') {
|
||||||
try {
|
SmartDialog.showToast('课堂视频暂不支持播放');
|
||||||
final int cid = videoItem.cid ??
|
return;
|
||||||
await SearchHttp.ab2c(aid: aid, bvid: bvid);
|
}
|
||||||
Utils.toViewPage(
|
if (videoItem is HotVideoItemModel &&
|
||||||
'bvid=$bvid&cid=$cid',
|
videoItem.redirectUrl?.isNotEmpty == true) {
|
||||||
arguments: {
|
if (Utils.viewPgcFromUri(videoItem.redirectUrl!)) {
|
||||||
'videoItem': videoItem,
|
return;
|
||||||
'heroTag': Utils.makeHeroTag(aid)
|
}
|
||||||
},
|
}
|
||||||
);
|
try {
|
||||||
} catch (err) {
|
final int cid = videoItem.cid ??
|
||||||
SmartDialog.showToast(err.toString());
|
await SearchHttp.ab2c(aid: aid, bvid: bvid);
|
||||||
}
|
Utils.toViewPage(
|
||||||
},
|
'bvid=$bvid&cid=$cid',
|
||||||
child: Padding(
|
arguments: {
|
||||||
padding: const EdgeInsets.symmetric(
|
'videoItem': videoItem,
|
||||||
horizontal: StyleString.safeSpace,
|
'heroTag': Utils.makeHeroTag(aid)
|
||||||
vertical: 5,
|
},
|
||||||
),
|
);
|
||||||
child: Row(
|
} catch (err) {
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
SmartDialog.showToast(err.toString());
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
}
|
||||||
children: <Widget>[
|
},
|
||||||
AspectRatio(
|
child: Padding(
|
||||||
aspectRatio: StyleString.aspectRatio,
|
padding: const EdgeInsets.symmetric(
|
||||||
child: LayoutBuilder(
|
horizontal: StyleString.safeSpace,
|
||||||
builder: (BuildContext context,
|
vertical: 5,
|
||||||
BoxConstraints boxConstraints) {
|
),
|
||||||
final double maxWidth = boxConstraints.maxWidth;
|
child: Row(
|
||||||
final double maxHeight = boxConstraints.maxHeight;
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
return Stack(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: <Widget>[
|
||||||
NetworkImgLayer(
|
AspectRatio(
|
||||||
src: videoItem.pic as String,
|
aspectRatio: StyleString.aspectRatio,
|
||||||
width: maxWidth,
|
child: LayoutBuilder(
|
||||||
height: maxHeight,
|
builder: (BuildContext context,
|
||||||
),
|
BoxConstraints boxConstraints) {
|
||||||
if (videoItem is HotVideoItemModel &&
|
final double maxWidth = boxConstraints.maxWidth;
|
||||||
videoItem.pgcLabel?.isNotEmpty == true)
|
final double maxHeight = boxConstraints.maxHeight;
|
||||||
PBadge(
|
return Stack(
|
||||||
text: videoItem.pgcLabel,
|
children: [
|
||||||
top: 6.0,
|
NetworkImgLayer(
|
||||||
right: 6.0,
|
src: videoItem.pic as String,
|
||||||
|
width: maxWidth,
|
||||||
|
height: maxHeight,
|
||||||
),
|
),
|
||||||
if (videoItem.duration != 0)
|
if (videoItem is HotVideoItemModel &&
|
||||||
PBadge(
|
videoItem.pgcLabel?.isNotEmpty == true)
|
||||||
text: Utils.timeFormat(videoItem.duration!),
|
PBadge(
|
||||||
right: 6.0,
|
text: videoItem.pgcLabel,
|
||||||
bottom: 6.0,
|
top: 6.0,
|
||||||
type: 'gray',
|
right: 6.0,
|
||||||
),
|
),
|
||||||
if (type != 'video')
|
if (videoItem.duration != 0)
|
||||||
PBadge(
|
PBadge(
|
||||||
text: type,
|
text: Utils.timeFormat(videoItem.duration!),
|
||||||
left: 6.0,
|
right: 6.0,
|
||||||
bottom: 6.0,
|
bottom: 6.0,
|
||||||
type: 'primary',
|
type: 'gray',
|
||||||
),
|
),
|
||||||
// if (videoItem.rcmdReason != null &&
|
if (type != 'video')
|
||||||
// videoItem.rcmdReason.content != '')
|
PBadge(
|
||||||
// pBadge(videoItem.rcmdReason.content, context,
|
text: type,
|
||||||
// 6.0, 6.0, null, null),
|
left: 6.0,
|
||||||
],
|
bottom: 6.0,
|
||||||
);
|
type: 'primary',
|
||||||
},
|
),
|
||||||
|
// if (videoItem.rcmdReason != null &&
|
||||||
|
// videoItem.rcmdReason.content != '')
|
||||||
|
// pBadge(videoItem.rcmdReason.content, context,
|
||||||
|
// 6.0, 6.0, null, null),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(width: 10),
|
||||||
const SizedBox(width: 10),
|
videoContent(context),
|
||||||
videoContent(context),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
if (source == 'normal')
|
||||||
if (source == 'normal')
|
Positioned(
|
||||||
Positioned(
|
bottom: 0,
|
||||||
bottom: 0,
|
right: 12,
|
||||||
right: 12,
|
child: VideoPopupMenu(
|
||||||
child: VideoPopupMenu(
|
size: 29,
|
||||||
size: 29,
|
iconSize: 17,
|
||||||
iconSize: 17,
|
videoItem: videoItem,
|
||||||
videoItem: videoItem,
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ abstract class CommonPublishPageState<T extends CommonPublishPage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() async {
|
void dispose() {
|
||||||
focusNode.dispose();
|
focusNode.dispose();
|
||||||
editController.dispose();
|
editController.dispose();
|
||||||
WidgetsBinding.instance.removeObserver(this);
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ class _HomePageState extends State<HomePage>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(toolbarHeight: 0),
|
appBar: AppBar(toolbarHeight: 0),
|
||||||
body: Column(
|
body: Column(
|
||||||
@@ -45,12 +44,12 @@ class _HomePageState extends State<HomePage>
|
|||||||
if (!_homeController.useSideBar &&
|
if (!_homeController.useSideBar &&
|
||||||
context.orientation == Orientation.portrait)
|
context.orientation == Orientation.portrait)
|
||||||
customAppBar,
|
customAppBar,
|
||||||
if (_homeController.tabs.length > 1) ...[
|
if (_homeController.tabs.length > 1)
|
||||||
const SizedBox(height: 4),
|
|
||||||
Material(
|
Material(
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
child: SizedBox(
|
child: Container(
|
||||||
height: 42,
|
height: 42,
|
||||||
|
padding: const EdgeInsets.only(top: 4),
|
||||||
child: TabBar(
|
child: TabBar(
|
||||||
controller: _homeController.tabController,
|
controller: _homeController.tabController,
|
||||||
tabs: [
|
tabs: [
|
||||||
@@ -69,8 +68,8 @@ class _HomePageState extends State<HomePage>
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
] else
|
else
|
||||||
const SizedBox(height: 6),
|
const SizedBox(height: 6),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: tabBarView(
|
child: tabBarView(
|
||||||
|
|||||||
@@ -157,11 +157,10 @@ class _MainAppState extends State<MainApp>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() async {
|
void dispose() {
|
||||||
MainApp.routeObserver.unsubscribe(this);
|
MainApp.routeObserver.unsubscribe(this);
|
||||||
WidgetsBinding.instance.removeObserver(this);
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
// await GrpcClient.instance.shutdown();
|
GStorage.close();
|
||||||
await GStorage.close();
|
|
||||||
EventBus().off(EventName.loginEvent);
|
EventBus().off(EventName.loginEvent);
|
||||||
PiliScheme.listener?.cancel();
|
PiliScheme.listener?.cancel();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
|||||||
@@ -75,9 +75,9 @@ class _SearchResultPageState extends State<SearchResultPage>
|
|||||||
),
|
),
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 4),
|
|
||||||
Container(
|
Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.only(top: 4),
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
child: Theme(
|
child: Theme(
|
||||||
data: ThemeData(
|
data: ThemeData(
|
||||||
|
|||||||
@@ -213,7 +213,6 @@ List<SettingsModel> get styleSettings => [
|
|||||||
leading: Icon(Icons.fit_screen_outlined),
|
leading: Icon(Icons.fit_screen_outlined),
|
||||||
setKey: SettingBoxKey.videoPlayerRemoveSafeArea,
|
setKey: SettingBoxKey.videoPlayerRemoveSafeArea,
|
||||||
defaultVal: false,
|
defaultVal: false,
|
||||||
needReboot: true,
|
|
||||||
),
|
),
|
||||||
SettingsModel(
|
SettingsModel(
|
||||||
settingsType: SettingsType.sw1tch,
|
settingsType: SettingsType.sw1tch,
|
||||||
|
|||||||
@@ -637,7 +637,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
|||||||
toolbarHeight: 0,
|
toolbarHeight: 0,
|
||||||
),
|
),
|
||||||
if (videoDetailController.scrollRatio.value != 0 &&
|
if (videoDetailController.scrollRatio.value != 0 &&
|
||||||
videoDetailController.scrollCtr.offset != 0)
|
videoDetailController.scrollCtr.offset != 0 &&
|
||||||
|
context.orientation == Orientation.portrait)
|
||||||
AppBar(
|
AppBar(
|
||||||
backgroundColor: Theme.of(context)
|
backgroundColor: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
@@ -846,7 +847,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
return videoDetailController.scrollRatio.value == 0 ||
|
return videoDetailController.scrollRatio.value == 0 ||
|
||||||
videoDetailController.scrollCtr.offset == 0
|
videoDetailController.scrollCtr.offset == 0 ||
|
||||||
|
context.orientation != Orientation.portrait
|
||||||
? const SizedBox.shrink()
|
? const SizedBox.shrink()
|
||||||
: Positioned.fill(
|
: Positioned.fill(
|
||||||
bottom: -2,
|
bottom: -2,
|
||||||
@@ -1807,6 +1809,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
|||||||
|
|
||||||
Widget videoIntro([bool needRelated = true, bool needCtr = true]) {
|
Widget videoIntro([bool needRelated = true, bool needCtr = true]) {
|
||||||
Widget introPanel() => Scaffold(
|
Widget introPanel() => Scaffold(
|
||||||
|
resizeToAvoidBottomInset: false,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
body: CustomScrollView(
|
body: CustomScrollView(
|
||||||
key: const PageStorageKey<String>('简介'),
|
key: const PageStorageKey<String>('简介'),
|
||||||
|
|||||||
@@ -1379,7 +1379,6 @@ class PlPlayerController {
|
|||||||
bool removeSafeArea = setting.get(SettingBoxKey.videoPlayerRemoveSafeArea,
|
bool removeSafeArea = setting.get(SettingBoxKey.videoPlayerRemoveSafeArea,
|
||||||
defaultValue: false);
|
defaultValue: false);
|
||||||
if (!isFullScreen.value && status) {
|
if (!isFullScreen.value && status) {
|
||||||
// StatusBarControl.setHidden(true, animation: StatusBarAnimation.FADE);
|
|
||||||
hideStatusBar();
|
hideStatusBar();
|
||||||
|
|
||||||
/// 按照视频宽高比决定全屏方向
|
/// 按照视频宽高比决定全屏方向
|
||||||
@@ -1403,7 +1402,6 @@ class PlPlayerController {
|
|||||||
await landScape();
|
await landScape();
|
||||||
}
|
}
|
||||||
} else if (isFullScreen.value && !status) {
|
} else if (isFullScreen.value && !status) {
|
||||||
// StatusBarControl.setHidden(false, animation: StatusBarAnimation.FADE);
|
|
||||||
if (!removeSafeArea) showStatusBar();
|
if (!removeSafeArea) showStatusBar();
|
||||||
toggleFullScreen(false);
|
toggleFullScreen(false);
|
||||||
if (mode == FullScreenMode.none) {
|
if (mode == FullScreenMode.none) {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import 'package:device_info_plus/device_info_plus.dart';
|
|||||||
import 'package:auto_orientation/auto_orientation.dart';
|
import 'package:auto_orientation/auto_orientation.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:status_bar_control/status_bar_control.dart';
|
|
||||||
|
|
||||||
import '../../../utils/storage.dart';
|
import '../../../utils/storage.dart';
|
||||||
|
|
||||||
@@ -75,7 +74,6 @@ Future<void> hideStatusBar() async {
|
|||||||
await SystemChrome.setEnabledSystemUIMode(
|
await SystemChrome.setEnabledSystemUIMode(
|
||||||
SystemUiMode.immersiveSticky,
|
SystemUiMode.immersiveSticky,
|
||||||
);
|
);
|
||||||
StatusBarControl.setHidden(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//退出全屏显示
|
//退出全屏显示
|
||||||
@@ -94,7 +92,6 @@ Future<void> showStatusBar() async {
|
|||||||
mode,
|
mode,
|
||||||
overlays: SystemUiOverlay.values,
|
overlays: SystemUiOverlay.values,
|
||||||
);
|
);
|
||||||
StatusBarControl.setHidden(false);
|
|
||||||
} else if (Platform.isMacOS || Platform.isWindows || Platform.isLinux) {
|
} else if (Platform.isMacOS || Platform.isWindows || Platform.isLinux) {
|
||||||
await const MethodChannel('com.alexmercerind/media_kit_video')
|
await const MethodChannel('com.alexmercerind/media_kit_video')
|
||||||
.invokeMethod(
|
.invokeMethod(
|
||||||
|
|||||||
@@ -1741,14 +1741,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.1"
|
version: "1.11.1"
|
||||||
status_bar_control:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: status_bar_control
|
|
||||||
sha256: "7f2c1f3f7fd13b85ed284eb7ca3f74ceb8dcfdd25636d3a84186d0a687d36693"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.2.1"
|
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ dependencies:
|
|||||||
url: https://github.com/bggRGjQaUbCoE/canvas_danmaku.git
|
url: https://github.com/bggRGjQaUbCoE/canvas_danmaku.git
|
||||||
ref: main
|
ref: main
|
||||||
# 状态栏图标控制
|
# 状态栏图标控制
|
||||||
status_bar_control: ^3.2.1
|
# status_bar_control: ^3.2.1
|
||||||
# 代理
|
# 代理
|
||||||
system_proxy: ^0.1.0
|
system_proxy: ^0.1.0
|
||||||
# pip
|
# pip
|
||||||
|
|||||||
Reference in New Issue
Block a user