mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-08-06 02:30:12 +08:00
Compare commits
11 Commits
57c683d5d8
...
2.0.6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b6d8bef99 | ||
|
|
a2b54e50d0 | ||
|
|
887c3525a2 | ||
|
|
3a46ce2429 | ||
|
|
c0b5876d5b | ||
|
|
74c389be8b | ||
|
|
5d87361693 | ||
|
|
9752ae2f33 | ||
|
|
3a9cafaf24 | ||
|
|
5937d83aa9 | ||
|
|
6feb1c15ee |
@@ -27,6 +27,7 @@ import java.io.File
|
|||||||
|
|
||||||
class MainActivity : AudioServiceActivity() {
|
class MainActivity : AudioServiceActivity() {
|
||||||
private lateinit var methodChannel: MethodChannel
|
private lateinit var methodChannel: MethodChannel
|
||||||
|
private var isFoldable = false
|
||||||
|
|
||||||
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||||
super.configureFlutterEngine(flutterEngine)
|
super.configureFlutterEngine(flutterEngine)
|
||||||
@@ -35,6 +36,7 @@ class MainActivity : AudioServiceActivity() {
|
|||||||
methodChannel.setMethodCallHandler { call, result ->
|
methodChannel.setMethodCallHandler { call, result ->
|
||||||
when (call.method) {
|
when (call.method) {
|
||||||
"back" -> back();
|
"back" -> back();
|
||||||
|
|
||||||
"biliSendCommAntifraud" -> {
|
"biliSendCommAntifraud" -> {
|
||||||
try {
|
try {
|
||||||
val action = call.argument<Int>("action") ?: 0
|
val action = call.argument<Int>("action") ?: 0
|
||||||
@@ -174,28 +176,13 @@ class MainActivity : AudioServiceActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
"maxScreenSize" -> {
|
"maxScreenSize" -> {
|
||||||
try {
|
maxScreenSize()?.let {
|
||||||
val density = resources.displayMetrics.density
|
result.success(it)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
||||||
val maxBounds = windowManager.maximumWindowMetrics.bounds
|
|
||||||
result.success(
|
|
||||||
mapOf(
|
|
||||||
"maxWidth" to (maxBounds.width() / density).roundToInt(),
|
|
||||||
"maxHeight" to (maxBounds.height() / density).roundToInt(),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
val realSizePoint = Point()
|
|
||||||
windowManager.defaultDisplay.getRealSize(realSizePoint)
|
|
||||||
result.success(
|
|
||||||
mapOf(
|
|
||||||
"maxWidth" to (realSizePoint.x / density).roundToInt(),
|
|
||||||
"maxHeight" to (realSizePoint.y / density).roundToInt(),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"isFoldable" -> {
|
||||||
|
result.success(isFoldable)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> result.notImplemented()
|
else -> result.notImplemented()
|
||||||
@@ -203,6 +190,40 @@ class MainActivity : AudioServiceActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||||
|
super.onConfigurationChanged(newConfig)
|
||||||
|
if (isFoldable) {
|
||||||
|
maxScreenSize()?.let {
|
||||||
|
MethodChannel(
|
||||||
|
flutterEngine!!.dartExecutor.binaryMessenger,
|
||||||
|
"ScreenChannel"
|
||||||
|
).invokeMethod("onConfigChanged", it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun maxScreenSize(): Map<String, Int>? {
|
||||||
|
try {
|
||||||
|
val density = resources.displayMetrics.density
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
val maxBounds = windowManager.maximumWindowMetrics.bounds
|
||||||
|
return mapOf(
|
||||||
|
"maxWidth" to (maxBounds.width() / density).roundToInt(),
|
||||||
|
"maxHeight" to (maxBounds.height() / density).roundToInt(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
val realSizePoint = Point()
|
||||||
|
windowManager.defaultDisplay.getRealSize(realSizePoint)
|
||||||
|
return mapOf(
|
||||||
|
"maxWidth" to (realSizePoint.x / density).roundToInt(),
|
||||||
|
"maxHeight" to (realSizePoint.y / density).roundToInt(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun back() {
|
private fun back() {
|
||||||
val intent = Intent(Intent.ACTION_MAIN).apply {
|
val intent = Intent(Intent.ACTION_MAIN).apply {
|
||||||
addCategory(Intent.CATEGORY_HOME)
|
addCategory(Intent.CATEGORY_HOME)
|
||||||
@@ -217,13 +238,19 @@ class MainActivity : AudioServiceActivity() {
|
|||||||
window.attributes.layoutInDisplayCutoutMode =
|
window.attributes.layoutInDisplayCutoutMode =
|
||||||
LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
try {
|
||||||
|
isFoldable =
|
||||||
|
packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_HINGE_ANGLE)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
stopService(Intent(this, com.ryanheise.audioservice.AudioService::class.java))
|
stopService(Intent(this, com.ryanheise.audioservice.AudioService::class.java))
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
android.os.Process.killProcess(android.os.Process.myPid())
|
|
||||||
exitProcess(0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUserLeaveHint() {
|
override fun onUserLeaveHint() {
|
||||||
|
|||||||
@@ -20,13 +20,78 @@ import 'dart:math' as math;
|
|||||||
import 'package:flutter/foundation.dart' show clampDouble;
|
import 'package:flutter/foundation.dart' show clampDouble;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart'
|
import 'package:flutter/rendering.dart'
|
||||||
show RenderSliverSingleBoxAdapter, SliverGeometry;
|
show RenderSliverSingleBoxAdapter, SliverGeometry, ScrollDirection;
|
||||||
|
|
||||||
/// ref [SliverFloatingHeader]
|
/// ref [SliverFloatingHeader]
|
||||||
|
|
||||||
class SliverFloatingHeaderWidget extends SingleChildRenderObjectWidget {
|
class SliverFloatingHeaderWidget extends StatelessWidget {
|
||||||
const SliverFloatingHeaderWidget({
|
const SliverFloatingHeaderWidget({
|
||||||
super.key,
|
super.key,
|
||||||
|
required this.child,
|
||||||
|
required this.backgroundColor,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Widget child;
|
||||||
|
final Color backgroundColor;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return _SliverFloatingHeaderWidget(
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
child: _SliverFloatingHeaderScroll(child: child),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SliverFloatingHeaderScroll extends StatefulWidget {
|
||||||
|
const _SliverFloatingHeaderScroll({required this.child});
|
||||||
|
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_SliverFloatingHeaderScroll> createState() =>
|
||||||
|
_SliverFloatingHeaderScrollState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SliverFloatingHeaderScrollState
|
||||||
|
extends State<_SliverFloatingHeaderScroll> {
|
||||||
|
ScrollPosition? _position;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
if (_position != null) {
|
||||||
|
_position!.isScrollingNotifier.removeListener(_isScrollingListener);
|
||||||
|
}
|
||||||
|
_position = Scrollable.maybeOf(context)?.position;
|
||||||
|
if (_position != null) {
|
||||||
|
_position!.isScrollingNotifier.addListener(_isScrollingListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
if (_position != null) {
|
||||||
|
_position!.isScrollingNotifier.removeListener(_isScrollingListener);
|
||||||
|
}
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _isScrollingListener() {
|
||||||
|
assert(_position != null);
|
||||||
|
if (_position!.isScrollingNotifier.value) {
|
||||||
|
final RenderSliverFloatingHeader? renderer = context
|
||||||
|
.findAncestorRenderObjectOfType<RenderSliverFloatingHeader>();
|
||||||
|
renderer?.updateScrollStartDirection(_position!.userScrollDirection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => widget.child;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SliverFloatingHeaderWidget extends SingleChildRenderObjectWidget {
|
||||||
|
const _SliverFloatingHeaderWidget({
|
||||||
required Widget super.child,
|
required Widget super.child,
|
||||||
required this.backgroundColor,
|
required this.backgroundColor,
|
||||||
});
|
});
|
||||||
@@ -70,6 +135,12 @@ class RenderSliverFloatingHeader extends RenderSliverSingleBoxAdapter {
|
|||||||
effectiveScrollOffset < child!.size.height);
|
effectiveScrollOffset < child!.size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScrollDirection? _lastStartedScrollDirection;
|
||||||
|
|
||||||
|
void updateScrollStartDirection(ScrollDirection direction) {
|
||||||
|
_lastStartedScrollDirection = direction;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void performLayout() {
|
void performLayout() {
|
||||||
if (!floatingHeaderNeedsToBeUpdated) {
|
if (!floatingHeaderNeedsToBeUpdated) {
|
||||||
@@ -78,7 +149,8 @@ class RenderSliverFloatingHeader extends RenderSliverSingleBoxAdapter {
|
|||||||
double delta =
|
double delta =
|
||||||
lastScrollOffset! -
|
lastScrollOffset! -
|
||||||
constraints.scrollOffset; // > 0 when the header is growing
|
constraints.scrollOffset; // > 0 when the header is growing
|
||||||
if (constraints.userScrollDirection == .forward) {
|
if (constraints.userScrollDirection == .forward ||
|
||||||
|
_lastStartedScrollDirection == .forward) {
|
||||||
final childExtent = child!.size.height;
|
final childExtent = child!.size.height;
|
||||||
if (effectiveScrollOffset > childExtent) {
|
if (effectiveScrollOffset > childExtent) {
|
||||||
effectiveScrollOffset =
|
effectiveScrollOffset =
|
||||||
|
|||||||
@@ -100,7 +100,9 @@ class LiveRoomController extends GetxController {
|
|||||||
// dm
|
// dm
|
||||||
LiveDmInfoData? dmInfo;
|
LiveDmInfoData? dmInfo;
|
||||||
List<RichTextItem>? savedDanmaku;
|
List<RichTextItem>? savedDanmaku;
|
||||||
|
int builtLength = 0;
|
||||||
RxList<dynamic> messages = <dynamic>[].obs;
|
RxList<dynamic> messages = <dynamic>[].obs;
|
||||||
|
bool get shouldRefresh => builtLength != messages.length;
|
||||||
late final Rx<SuperChatItem?> fsSC = Rx<SuperChatItem?>(null);
|
late final Rx<SuperChatItem?> fsSC = Rx<SuperChatItem?>(null);
|
||||||
late final RxList<SuperChatItem> superChatMsg = <SuperChatItem>[].obs;
|
late final RxList<SuperChatItem> superChatMsg = <SuperChatItem>[].obs;
|
||||||
RxBool disableAutoScroll = false.obs;
|
RxBool disableAutoScroll = false.obs;
|
||||||
@@ -285,7 +287,17 @@ class LiveRoomController extends GetxController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void jumpToBottom() {
|
void handleJumpToBottom() {
|
||||||
|
disableAutoScroll.value = false;
|
||||||
|
if (shouldRefresh) {
|
||||||
|
messages.refresh();
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback(_jumpToBottom);
|
||||||
|
} else {
|
||||||
|
_jumpToBottom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _jumpToBottom([_]) {
|
||||||
if (scrollController.hasClients) {
|
if (scrollController.hasClients) {
|
||||||
scrollController.jumpTo(scrollController.position.maxScrollExtent);
|
scrollController.jumpTo(scrollController.position.maxScrollExtent);
|
||||||
}
|
}
|
||||||
@@ -349,12 +361,21 @@ class LiveRoomController extends GetxController {
|
|||||||
disableAutoScroll.value = true;
|
disableAutoScroll.value = true;
|
||||||
} else if (userScrollDirection == .reverse) {
|
} else if (userScrollDirection == .reverse) {
|
||||||
final pos = scrollController.position;
|
final pos = scrollController.position;
|
||||||
if (pos.maxScrollExtent - pos.pixels <= 100) {
|
if (pos.maxScrollExtent - pos.pixels <= 100 && disableAutoScroll.value) {
|
||||||
disableAutoScroll.value = false;
|
disableAutoScroll.value = false;
|
||||||
|
refreshMsgIfNeeded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void refreshMsgIfNeeded() {
|
||||||
|
if (shouldRefresh) {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
messages.refresh();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
closeLiveMsg();
|
closeLiveMsg();
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ class SuperChatCard extends StatefulWidget {
|
|||||||
required this.item,
|
required this.item,
|
||||||
this.onRemove,
|
this.onRemove,
|
||||||
this.persistentSC = false,
|
this.persistentSC = false,
|
||||||
required this.onReport,
|
this.onReport,
|
||||||
});
|
});
|
||||||
|
|
||||||
final SuperChatItem item;
|
final SuperChatItem item;
|
||||||
final VoidCallback? onRemove;
|
final VoidCallback? onRemove;
|
||||||
final bool persistentSC;
|
final bool persistentSC;
|
||||||
final VoidCallback onReport;
|
final VoidCallback? onReport;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<SuperChatCard> createState() => _SuperChatCardState();
|
State<SuperChatCard> createState() => _SuperChatCardState();
|
||||||
@@ -168,6 +168,7 @@ class _SuperChatCardState extends State<SuperChatCard> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
|
mainAxisSize: .min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import 'package:PiliPlus/utils/platform_utils.dart';
|
|||||||
import 'package:PiliPlus/utils/share_utils.dart';
|
import 'package:PiliPlus/utils/share_utils.dart';
|
||||||
import 'package:PiliPlus/utils/storage.dart';
|
import 'package:PiliPlus/utils/storage.dart';
|
||||||
import 'package:PiliPlus/utils/storage_key.dart';
|
import 'package:PiliPlus/utils/storage_key.dart';
|
||||||
|
import 'package:PiliPlus/utils/storage_pref.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:canvas_danmaku/canvas_danmaku.dart';
|
import 'package:canvas_danmaku/canvas_danmaku.dart';
|
||||||
@@ -65,6 +66,7 @@ class LiveRoomPage extends StatefulWidget {
|
|||||||
|
|
||||||
class _LiveRoomPageState extends State<LiveRoomPage>
|
class _LiveRoomPageState extends State<LiveRoomPage>
|
||||||
with WidgetsBindingObserver, RouteAware, RouteAwareMixin {
|
with WidgetsBindingObserver, RouteAware, RouteAwareMixin {
|
||||||
|
late final fullScreenSCWidth = Pref.fullScreenSCWidth;
|
||||||
final String heroTag = Utils.generateRandomString(6);
|
final String heroTag = Utils.generateRandomString(6);
|
||||||
late final LiveRoomController _liveRoomController;
|
late final LiveRoomController _liveRoomController;
|
||||||
late final PlPlayerController plPlayerController;
|
late final PlPlayerController plPlayerController;
|
||||||
@@ -187,7 +189,9 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
|||||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||||
if (plPlayerController.visible = state == .resumed) {
|
if (plPlayerController.visible = state == .resumed) {
|
||||||
if (!plPlayerController.showDanmaku) {
|
if (!plPlayerController.showDanmaku) {
|
||||||
_liveRoomController.startLiveTimer();
|
_liveRoomController
|
||||||
|
..refreshMsgIfNeeded()
|
||||||
|
..startLiveTimer();
|
||||||
plPlayerController.showDanmaku = true;
|
plPlayerController.showDanmaku = true;
|
||||||
}
|
}
|
||||||
} else if (state == .paused) {
|
} else if (state == .paused) {
|
||||||
@@ -320,7 +324,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
|||||||
Positioned(
|
Positioned(
|
||||||
left: padding.left + 25,
|
left: padding.left + 25,
|
||||||
bottom: 25,
|
bottom: 25,
|
||||||
width: 255,
|
width: fullScreenSCWidth,
|
||||||
child: Obx(() {
|
child: Obx(() {
|
||||||
final item = _liveRoomController.fsSC.value;
|
final item = _liveRoomController.fsSC.value;
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ class LiveRoomChatPanel extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
controller: liveRoomController.scrollController,
|
controller: liveRoomController.scrollController,
|
||||||
separatorBuilder: (_, _) => const SizedBox(height: 8),
|
separatorBuilder: (_, _) => const SizedBox(height: 8),
|
||||||
itemCount: liveRoomController.messages.length,
|
itemCount: liveRoomController.builtLength =
|
||||||
|
liveRoomController.messages.length,
|
||||||
physics: const ClampingScrollPhysics(),
|
physics: const ClampingScrollPhysics(),
|
||||||
itemBuilder: (_, index) {
|
itemBuilder: (_, index) {
|
||||||
final item = liveRoomController.messages[index];
|
final item = liveRoomController.messages[index];
|
||||||
@@ -218,17 +219,10 @@ class LiveRoomChatPanel extends StatelessWidget {
|
|||||||
right: 12,
|
right: 12,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
child: ElevatedButton.icon(
|
child: ElevatedButton.icon(
|
||||||
style: ElevatedButton.styleFrom(
|
style: const ButtonStyle(visualDensity: .comfortable),
|
||||||
visualDensity: VisualDensity.comfortable,
|
icon: const Icon(Icons.arrow_downward_rounded, size: 20),
|
||||||
),
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.arrow_downward_rounded,
|
|
||||||
size: 20,
|
|
||||||
),
|
|
||||||
label: const Text('回到底部'),
|
label: const Text('回到底部'),
|
||||||
onPressed: () => liveRoomController
|
onPressed: liveRoomController.handleJumpToBottom,
|
||||||
..disableAutoScroll.value = false
|
|
||||||
..jumpToBottom(),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: const SizedBox.shrink(),
|
: const SizedBox.shrink(),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:PiliPlus/models/common/super_chat_type.dart';
|
|||||||
import 'package:PiliPlus/models/common/video/subtitle_pref_type.dart';
|
import 'package:PiliPlus/models/common/video/subtitle_pref_type.dart';
|
||||||
import 'package:PiliPlus/pages/main/controller.dart';
|
import 'package:PiliPlus/pages/main/controller.dart';
|
||||||
import 'package:PiliPlus/pages/setting/models/model.dart';
|
import 'package:PiliPlus/pages/setting/models/model.dart';
|
||||||
|
import 'package:PiliPlus/pages/setting/pages/fullscreen_sc_size.dart';
|
||||||
import 'package:PiliPlus/pages/setting/widgets/select_dialog.dart';
|
import 'package:PiliPlus/pages/setting/widgets/select_dialog.dart';
|
||||||
import 'package:PiliPlus/plugin/pl_player/models/bottom_progress_behavior.dart';
|
import 'package:PiliPlus/plugin/pl_player/models/bottom_progress_behavior.dart';
|
||||||
import 'package:PiliPlus/plugin/pl_player/models/fullscreen_mode.dart';
|
import 'package:PiliPlus/plugin/pl_player/models/fullscreen_mode.dart';
|
||||||
@@ -145,6 +146,12 @@ List<SettingsModel> get playSettings => [
|
|||||||
getSubtitle: () => '当前:「${Pref.superChatType.title}」',
|
getSubtitle: () => '当前:「${Pref.superChatType.title}」',
|
||||||
onTap: _showSuperChatDialog,
|
onTap: _showSuperChatDialog,
|
||||||
),
|
),
|
||||||
|
NormalModel(
|
||||||
|
title: '全屏 SC 大小',
|
||||||
|
subtitle: 'SuperChat (醒目留言) 大小设置',
|
||||||
|
leading: const Icon(Icons.open_in_full),
|
||||||
|
onTap: (_, _) => Get.to(const FullScreenScSize()),
|
||||||
|
),
|
||||||
const SwitchModel(
|
const SwitchModel(
|
||||||
title: '竖屏扩大展示',
|
title: '竖屏扩大展示',
|
||||||
subtitle: '小屏竖屏视频宽高比由16:9扩大至1:1(不支持收起);横屏适配时,扩大至9:16',
|
subtitle: '小屏竖屏视频宽高比由16:9扩大至1:1(不支持收起);横屏适配时,扩大至9:16',
|
||||||
|
|||||||
141
lib/pages/setting/pages/fullscreen_sc_size.dart
Normal file
141
lib/pages/setting/pages/fullscreen_sc_size.dart
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
import 'dart:io' show Platform;
|
||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
import 'package:PiliPlus/common/widgets/extra_hittest_stack.dart';
|
||||||
|
import 'package:PiliPlus/models_new/live/live_superchat/item.dart';
|
||||||
|
import 'package:PiliPlus/pages/live_room/superchat/superchat_card.dart';
|
||||||
|
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart';
|
||||||
|
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||||
|
import 'package:PiliPlus/utils/storage.dart';
|
||||||
|
import 'package:PiliPlus/utils/storage_key.dart';
|
||||||
|
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
const kFullScreenSCWidth = 255.0;
|
||||||
|
|
||||||
|
class FullScreenScSize extends StatefulWidget {
|
||||||
|
const FullScreenScSize({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<FullScreenScSize> createState() => _FullScreenScSizeState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FullScreenScSizeState extends State<FullScreenScSize> {
|
||||||
|
double _width = Pref.fullScreenSCWidth;
|
||||||
|
final _randomSC = SuperChatItem.random;
|
||||||
|
late EdgeInsets _padding;
|
||||||
|
late ColorScheme _colorScheme;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
landscapeLeftMode();
|
||||||
|
} else if (Platform.isIOS) {
|
||||||
|
landscapeRightMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
if (PlatformUtils.isMobile) {
|
||||||
|
if (Pref.horizontalScreen) {
|
||||||
|
fullMode();
|
||||||
|
} else {
|
||||||
|
portraitUpMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
final padding = MediaQuery.viewPaddingOf(context);
|
||||||
|
_padding = .only(
|
||||||
|
right: padding.right + 17,
|
||||||
|
left: padding.left + 25,
|
||||||
|
bottom: padding.bottom + 25,
|
||||||
|
);
|
||||||
|
_colorScheme = ColorScheme.of(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onReset() {
|
||||||
|
_width = kFullScreenSCWidth;
|
||||||
|
GStorage.setting.delete(SettingBoxKey.fullScreenSCWidth);
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
resizeToAvoidBottomInset: false,
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('全屏 SC 大小设置'),
|
||||||
|
actions: [
|
||||||
|
TextButton(onPressed: _onReset, child: const Text('重置')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: Padding(padding: _padding, child: _buildBody),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget get _buildBody {
|
||||||
|
return Align(
|
||||||
|
alignment: .bottomLeft,
|
||||||
|
child: ExtraHitTestStack(
|
||||||
|
clipBehavior: .none,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: _width,
|
||||||
|
child: IgnorePointer(
|
||||||
|
child: SuperChatCard(
|
||||||
|
item: _randomSC,
|
||||||
|
persistentSC: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
right: -17,
|
||||||
|
width: 34,
|
||||||
|
child: MouseRegion(
|
||||||
|
cursor: SystemMouseCursors.resizeRight,
|
||||||
|
child: GestureDetector(
|
||||||
|
behavior: .opaque,
|
||||||
|
onHorizontalDragUpdate: _onHorizontalDragUpdate,
|
||||||
|
onHorizontalDragEnd: _onHorizontalDragEnd,
|
||||||
|
child: DecoratedBox(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: .circle,
|
||||||
|
color: _colorScheme.secondaryContainer.withValues(
|
||||||
|
alpha: .8,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Transform.rotate(
|
||||||
|
angle: math.pi / 4,
|
||||||
|
child: Icon(
|
||||||
|
size: 18,
|
||||||
|
Icons.open_in_full,
|
||||||
|
color: _colorScheme.onSecondaryContainer,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onHorizontalDragUpdate(DragUpdateDetails details) {
|
||||||
|
_width = math.max(25.0, _width + details.delta.dx);
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onHorizontalDragEnd(DragEndDetails details) {
|
||||||
|
GStorage.setting.put(SettingBoxKey.fullScreenSCWidth, _width);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -238,11 +238,10 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
|||||||
EasyThrottle.throttle('replyReply', const Duration(milliseconds: 500), () {
|
EasyThrottle.throttle('replyReply', const Duration(milliseconds: 500), () {
|
||||||
int oid = replyItem.oid.toInt();
|
int oid = replyItem.oid.toInt();
|
||||||
int rpid = replyItem.id.toInt();
|
int rpid = replyItem.id.toInt();
|
||||||
showBottomSheet(
|
Scaffold.of(context).showBottomSheet(
|
||||||
context: context,
|
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
constraints: const BoxConstraints(),
|
constraints: const BoxConstraints(),
|
||||||
builder: (context) => VideoReplyReplyPanel(
|
(context) => VideoReplyReplyPanel(
|
||||||
id: id,
|
id: id,
|
||||||
oid: oid,
|
oid: oid,
|
||||||
rpid: rpid,
|
rpid: rpid,
|
||||||
|
|||||||
87
lib/scripts/bottom_sheet_ios_flutter.patch
Normal file
87
lib/scripts/bottom_sheet_ios_flutter.patch
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
diff --git a/packages/flutter/lib/src/cupertino/route.dart b/packages/flutter/lib/src/cupertino/route.dart
|
||||||
|
index 5ce4479480e..0e6387596c5 100644
|
||||||
|
--- a/packages/flutter/lib/src/cupertino/route.dart
|
||||||
|
+++ b/packages/flutter/lib/src/cupertino/route.dart
|
||||||
|
@@ -883,7 +883,7 @@ class _CupertinoBackGestureController<T> {
|
||||||
|
} else {
|
||||||
|
if (isCurrent) {
|
||||||
|
// This route is destined to pop at this point. Reuse navigator's pop.
|
||||||
|
- navigator.pop();
|
||||||
|
+ navigator.pop(gesturePop);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The popping may have finished inline if already at the target destination.
|
||||||
|
diff --git a/packages/flutter/lib/src/material/scaffold.dart b/packages/flutter/lib/src/material/scaffold.dart
|
||||||
|
index d121d10f1d6..92fa155c168 100644
|
||||||
|
--- a/packages/flutter/lib/src/material/scaffold.dart
|
||||||
|
+++ b/packages/flutter/lib/src/material/scaffold.dart
|
||||||
|
@@ -2521,6 +2521,7 @@ class ScaffoldState extends State<Scaffold>
|
||||||
|
final LocalHistoryEntry? entry = isPersistent
|
||||||
|
? null
|
||||||
|
: LocalHistoryEntry(
|
||||||
|
+ popGestureEnabled: true,
|
||||||
|
onRemove: () {
|
||||||
|
if (!removedEntry && _currentBottomSheet?._widget == bottomSheet && !doingDispose) {
|
||||||
|
removeCurrentBottomSheet();
|
||||||
|
diff --git a/packages/flutter/lib/src/widgets/routes.dart b/packages/flutter/lib/src/widgets/routes.dart
|
||||||
|
index 5c4a8982617..d3fa530e250 100644
|
||||||
|
--- a/packages/flutter/lib/src/widgets/routes.dart
|
||||||
|
+++ b/packages/flutter/lib/src/widgets/routes.dart
|
||||||
|
@@ -709,7 +709,11 @@ class LocalHistoryEntry {
|
||||||
|
/// Creates an entry in the history of a [LocalHistoryRoute].
|
||||||
|
///
|
||||||
|
/// The [impliesAppBarDismissal] defaults to true if not provided.
|
||||||
|
- LocalHistoryEntry({this.onRemove, this.impliesAppBarDismissal = true});
|
||||||
|
+ LocalHistoryEntry({
|
||||||
|
+ this.onRemove,
|
||||||
|
+ this.impliesAppBarDismissal = true,
|
||||||
|
+ this.popGestureEnabled = false,
|
||||||
|
+ });
|
||||||
|
|
||||||
|
/// Called when this entry is removed from the history of its associated [LocalHistoryRoute].
|
||||||
|
final VoidCallback? onRemove;
|
||||||
|
@@ -722,6 +726,8 @@ class LocalHistoryEntry {
|
||||||
|
/// Defaults to true.
|
||||||
|
final bool impliesAppBarDismissal;
|
||||||
|
|
||||||
|
+ final bool popGestureEnabled;
|
||||||
|
+
|
||||||
|
/// Remove this entry from the history of its associated [LocalHistoryRoute].
|
||||||
|
void remove() {
|
||||||
|
_owner?.removeLocalHistoryEntry(this);
|
||||||
|
@@ -949,6 +955,14 @@ mixin LocalHistoryRoute<T> on Route<T> {
|
||||||
|
@override
|
||||||
|
bool didPop(T? result) {
|
||||||
|
if (_localHistory != null && _localHistory!.isNotEmpty) {
|
||||||
|
+ if (result == gesturePop) {
|
||||||
|
+ for (var e in _localHistory!) {
|
||||||
|
+ e._owner = null;
|
||||||
|
+ }
|
||||||
|
+ _localHistory!.clear();
|
||||||
|
+ _localHistory = null;
|
||||||
|
+ return super.didPop(result);
|
||||||
|
+ }
|
||||||
|
final LocalHistoryEntry entry = _localHistory!.removeLast();
|
||||||
|
assert(entry._owner == this);
|
||||||
|
entry._owner = null;
|
||||||
|
@@ -968,7 +982,9 @@ mixin LocalHistoryRoute<T> on Route<T> {
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get willHandlePopInternally {
|
||||||
|
- return _localHistory != null && _localHistory!.isNotEmpty;
|
||||||
|
+ return _localHistory != null &&
|
||||||
|
+ _localHistory!.isNotEmpty &&
|
||||||
|
+ !_localHistory!.last.popGestureEnabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2839,3 +2855,9 @@ abstract class PopEntry<T> {
|
||||||
|
return 'PopEntry canPop: ${canPopNotifier.value}, onPopInvoked: $onPopInvokedWithResult';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+class _GesturePop {
|
||||||
|
+ const _GesturePop();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const Object gesturePop = _GesturePop();
|
||||||
17
lib/scripts/bottom_sheet_ios_piliplus.patch
Normal file
17
lib/scripts/bottom_sheet_ios_piliplus.patch
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
diff --git a/lib/pages/common/slide/common_slide_page.dart b/lib/pages/common/slide/common_slide_page.dart
|
||||||
|
index 58ba68b7c..e17449ee1 100644
|
||||||
|
--- a/lib/pages/common/slide/common_slide_page.dart
|
||||||
|
+++ b/lib/pages/common/slide/common_slide_page.dart
|
||||||
|
@@ -142,6 +142,12 @@ class SlideDragGestureRecognizer extends HorizontalDragGestureRecognizer {
|
||||||
|
bool isPointerAllowed(PointerEvent event) {
|
||||||
|
return isDxAllowed(event.localPosition.dx) && super.isPointerAllowed(event);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ @override
|
||||||
|
+ void addAllowedPointer(PointerDownEvent event) {
|
||||||
|
+ super.addAllowedPointer(event);
|
||||||
|
+ resolve(.accepted);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
class TabBarDragGestureRecognizer
|
||||||
@@ -10,7 +10,11 @@ $ToolTipFix = "56956c33ef102ac0b5fc46b62bd2dd9f50a86616";
|
|||||||
# https://github.com/flutter/flutter/issues/182281
|
# https://github.com/flutter/flutter/issues/182281
|
||||||
$NewOverScrollIndicator = "362b1de29974ffc1ed6faa826e1df870d7bec75f";
|
$NewOverScrollIndicator = "362b1de29974ffc1ed6faa826e1df870d7bec75f";
|
||||||
|
|
||||||
$BottomSheetPatch = "lib/scripts/bottom_sheet.patch"
|
$BottomSheetAndroidPatch = "lib/scripts/bottom_sheet_android.patch"
|
||||||
|
|
||||||
|
# https://github.com/bggRGjQaUbCoE/PiliPlus/issues/1906
|
||||||
|
$BottomSheetIOSFlutterPatch = "lib/scripts/bottom_sheet_ios_flutter.patch"
|
||||||
|
$BottomSheetIOSPiliPlusPatch = "lib/scripts/bottom_sheet_ios_piliplus.patch"
|
||||||
|
|
||||||
$ScrollViewPatch = "lib/scripts/scroll_view.patch"
|
$ScrollViewPatch = "lib/scripts/scroll_view.patch"
|
||||||
|
|
||||||
@@ -24,6 +28,13 @@ $ModalBarrierPatch = "lib/scripts/modal_barrier.patch"
|
|||||||
# https://github.com/flutter/flutter/issues/182466
|
# https://github.com/flutter/flutter/issues/182466
|
||||||
$MouseCursorPatch = "lib/scripts/mouse_cursor.patch"
|
$MouseCursorPatch = "lib/scripts/mouse_cursor.patch"
|
||||||
|
|
||||||
|
if ($platform.ToLower() -eq "ios") {
|
||||||
|
git apply $BottomSheetIOSPiliPlusPatch
|
||||||
|
if ($LASTEXITCODE -eq 0) {
|
||||||
|
Write-Host "$BottomSheetIOSPiliPlusPatch applied"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Set-Location $env:FLUTTER_ROOT
|
Set-Location $env:FLUTTER_ROOT
|
||||||
|
|
||||||
$picks = @()
|
$picks = @()
|
||||||
@@ -33,11 +44,12 @@ $patches = @($ModalBarrierPatch, $TextSelectionPatch, $MouseCursorPatch)
|
|||||||
switch ($platform.ToLower()) {
|
switch ($platform.ToLower()) {
|
||||||
"android" {
|
"android" {
|
||||||
$reverts += $NewOverScrollIndicator
|
$reverts += $NewOverScrollIndicator
|
||||||
$patches += $BottomSheetPatch
|
$patches += $BottomSheetAndroidPatch
|
||||||
$patches += $ScrollViewPatch
|
$patches += $ScrollViewPatch
|
||||||
}
|
}
|
||||||
"ios" {
|
"ios" {
|
||||||
$patches += $ScrollViewPatch
|
$patches += $ScrollViewPatch
|
||||||
|
$patches += $BottomSheetIOSFlutterPatch
|
||||||
}
|
}
|
||||||
"linux" {
|
"linux" {
|
||||||
$picks += $ToolTipFix
|
$picks += $ToolTipFix
|
||||||
|
|||||||
@@ -1,13 +1,33 @@
|
|||||||
import 'dart:io' show Platform;
|
import 'dart:io' show Platform;
|
||||||
|
|
||||||
import 'package:PiliPlus/utils/utils.dart';
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
|
import 'package:flutter/services.dart' show MethodChannel;
|
||||||
|
|
||||||
abstract final class MaxScreenSize {
|
abstract final class MaxScreenSize {
|
||||||
static int? _maxWidth;
|
static int? _maxWidth;
|
||||||
static int? _maxHeight;
|
static int? _maxHeight;
|
||||||
|
|
||||||
static Future<void> init() async {
|
static Future<void> init() {
|
||||||
|
return Future.wait([_initFoldable(), _initScreenSize()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> _initFoldable() async {
|
||||||
|
final isFoldable = await Utils.channel.invokeMethod('isFoldable');
|
||||||
|
if (isFoldable == true) {
|
||||||
|
const MethodChannel('ScreenChannel').setMethodCallHandler((call) async {
|
||||||
|
if (call.method == 'onConfigChanged') {
|
||||||
|
_handleRes(call.arguments);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> _initScreenSize() async {
|
||||||
final res = await Utils.channel.invokeMethod('maxScreenSize');
|
final res = await Utils.channel.invokeMethod('maxScreenSize');
|
||||||
|
_handleRes(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _handleRes(dynamic res) {
|
||||||
if (res is Map) {
|
if (res is Map) {
|
||||||
_maxWidth = res['maxWidth'];
|
_maxWidth = res['maxWidth'];
|
||||||
_maxHeight = res['maxHeight'];
|
_maxHeight = res['maxHeight'];
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ abstract final class SettingBoxKey {
|
|||||||
enableAutoExit = 'enableAutoExit',
|
enableAutoExit = 'enableAutoExit',
|
||||||
enableOnlineTotal = 'enableOnlineTotal',
|
enableOnlineTotal = 'enableOnlineTotal',
|
||||||
superChatType = 'superChatType',
|
superChatType = 'superChatType',
|
||||||
|
fullScreenSCWidth = 'fullScreenSCWidth',
|
||||||
keyboardControl = 'keyboardControl',
|
keyboardControl = 'keyboardControl',
|
||||||
pauseOnMinimize = 'pauseOnMinimize',
|
pauseOnMinimize = 'pauseOnMinimize',
|
||||||
pgcSkipType = 'pgcSkipType',
|
pgcSkipType = 'pgcSkipType',
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import 'package:PiliPlus/models/common/video/video_decode_type.dart';
|
|||||||
import 'package:PiliPlus/models/common/video/video_quality.dart';
|
import 'package:PiliPlus/models/common/video/video_quality.dart';
|
||||||
import 'package:PiliPlus/models/user/danmaku_rule.dart';
|
import 'package:PiliPlus/models/user/danmaku_rule.dart';
|
||||||
import 'package:PiliPlus/models/user/info.dart';
|
import 'package:PiliPlus/models/user/info.dart';
|
||||||
|
import 'package:PiliPlus/pages/setting/pages/fullscreen_sc_size.dart'
|
||||||
|
show kFullScreenSCWidth;
|
||||||
import 'package:PiliPlus/plugin/pl_player/models/audio_output_type.dart';
|
import 'package:PiliPlus/plugin/pl_player/models/audio_output_type.dart';
|
||||||
import 'package:PiliPlus/plugin/pl_player/models/bottom_progress_behavior.dart';
|
import 'package:PiliPlus/plugin/pl_player/models/bottom_progress_behavior.dart';
|
||||||
import 'package:PiliPlus/plugin/pl_player/models/fullscreen_mode.dart';
|
import 'package:PiliPlus/plugin/pl_player/models/fullscreen_mode.dart';
|
||||||
@@ -892,6 +894,11 @@ abstract final class Pref {
|
|||||||
defaultValue: SuperChatType.valid.index,
|
defaultValue: SuperChatType.valid.index,
|
||||||
)];
|
)];
|
||||||
|
|
||||||
|
static double get fullScreenSCWidth => _setting.get(
|
||||||
|
SettingBoxKey.fullScreenSCWidth,
|
||||||
|
defaultValue: kFullScreenSCWidth,
|
||||||
|
);
|
||||||
|
|
||||||
static bool get minimizeOnExit =>
|
static bool get minimizeOnExit =>
|
||||||
_setting.get(SettingBoxKey.minimizeOnExit, defaultValue: true);
|
_setting.get(SettingBoxKey.minimizeOnExit, defaultValue: true);
|
||||||
|
|
||||||
|
|||||||
@@ -181,10 +181,10 @@ packages:
|
|||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: build_runner
|
name: build_runner
|
||||||
sha256: "22fdcc3cfeb9d974d7408718c4be15ec5e9b1b350088f3a6c88f154e74dd700d"
|
sha256: "1523ce62448ebac2c15a8ba5fbad8acac169788658a7dd2a1c2d9c2a9318b9a6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.14.1"
|
version: "2.15.0"
|
||||||
built_collection:
|
built_collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -930,10 +930,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: image_picker_android
|
name: image_picker_android
|
||||||
sha256: "66810af8e99b2657ee98e5c6f02064f69bb63f7a70e343937f70946c5f8c6622"
|
sha256: d5b3e1774af29c9ab00103afb0d4614070f924d2e0057ac867ec98800114793f
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.13+16"
|
version: "0.8.13+17"
|
||||||
image_picker_for_web:
|
image_picker_for_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
|||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
# update when release
|
# update when release
|
||||||
version: 2.0.5+1
|
version: 2.0.6+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.10.0"
|
sdk: ">=3.10.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user