mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-08 20:14:51 +08:00
Compare commits
7 Commits
9752ae2f33
...
7b6d8bef99
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b6d8bef99 | ||
|
|
a2b54e50d0 | ||
|
|
887c3525a2 | ||
|
|
3a46ce2429 | ||
|
|
c0b5876d5b | ||
|
|
74c389be8b | ||
|
|
5d87361693 |
@@ -251,8 +251,6 @@ class MainActivity : AudioServiceActivity() {
|
||||
override fun onDestroy() {
|
||||
stopService(Intent(this, com.ryanheise.audioservice.AudioService::class.java))
|
||||
super.onDestroy()
|
||||
android.os.Process.killProcess(android.os.Process.myPid())
|
||||
exitProcess(0)
|
||||
}
|
||||
|
||||
override fun onUserLeaveHint() {
|
||||
|
||||
@@ -20,13 +20,78 @@ import 'dart:math' as math;
|
||||
import 'package:flutter/foundation.dart' show clampDouble;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart'
|
||||
show RenderSliverSingleBoxAdapter, SliverGeometry;
|
||||
show RenderSliverSingleBoxAdapter, SliverGeometry, ScrollDirection;
|
||||
|
||||
/// ref [SliverFloatingHeader]
|
||||
|
||||
class SliverFloatingHeaderWidget extends SingleChildRenderObjectWidget {
|
||||
class SliverFloatingHeaderWidget extends StatelessWidget {
|
||||
const SliverFloatingHeaderWidget({
|
||||
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 this.backgroundColor,
|
||||
});
|
||||
@@ -70,6 +135,12 @@ class RenderSliverFloatingHeader extends RenderSliverSingleBoxAdapter {
|
||||
effectiveScrollOffset < child!.size.height);
|
||||
}
|
||||
|
||||
ScrollDirection? _lastStartedScrollDirection;
|
||||
|
||||
void updateScrollStartDirection(ScrollDirection direction) {
|
||||
_lastStartedScrollDirection = direction;
|
||||
}
|
||||
|
||||
@override
|
||||
void performLayout() {
|
||||
if (!floatingHeaderNeedsToBeUpdated) {
|
||||
@@ -78,7 +149,8 @@ class RenderSliverFloatingHeader extends RenderSliverSingleBoxAdapter {
|
||||
double delta =
|
||||
lastScrollOffset! -
|
||||
constraints.scrollOffset; // > 0 when the header is growing
|
||||
if (constraints.userScrollDirection == .forward) {
|
||||
if (constraints.userScrollDirection == .forward ||
|
||||
_lastStartedScrollDirection == .forward) {
|
||||
final childExtent = child!.size.height;
|
||||
if (effectiveScrollOffset > childExtent) {
|
||||
effectiveScrollOffset =
|
||||
|
||||
@@ -20,13 +20,13 @@ class SuperChatCard extends StatefulWidget {
|
||||
required this.item,
|
||||
this.onRemove,
|
||||
this.persistentSC = false,
|
||||
required this.onReport,
|
||||
this.onReport,
|
||||
});
|
||||
|
||||
final SuperChatItem item;
|
||||
final VoidCallback? onRemove;
|
||||
final bool persistentSC;
|
||||
final VoidCallback onReport;
|
||||
final VoidCallback? onReport;
|
||||
|
||||
@override
|
||||
State<SuperChatCard> createState() => _SuperChatCardState();
|
||||
@@ -168,6 +168,7 @@ class _SuperChatCardState extends State<SuperChatCard> {
|
||||
}
|
||||
|
||||
return Column(
|
||||
mainAxisSize: .min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
GestureDetector(
|
||||
|
||||
@@ -46,6 +46,7 @@ import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:PiliPlus/utils/share_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
import 'package:PiliPlus/utils/storage_key.dart';
|
||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:canvas_danmaku/canvas_danmaku.dart';
|
||||
@@ -65,6 +66,7 @@ class LiveRoomPage extends StatefulWidget {
|
||||
|
||||
class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
with WidgetsBindingObserver, RouteAware, RouteAwareMixin {
|
||||
late final fullScreenSCWidth = Pref.fullScreenSCWidth;
|
||||
final String heroTag = Utils.generateRandomString(6);
|
||||
late final LiveRoomController _liveRoomController;
|
||||
late final PlPlayerController plPlayerController;
|
||||
@@ -322,7 +324,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
Positioned(
|
||||
left: padding.left + 25,
|
||||
bottom: 25,
|
||||
width: 255,
|
||||
width: fullScreenSCWidth,
|
||||
child: Obx(() {
|
||||
final item = _liveRoomController.fsSC.value;
|
||||
if (item == null) {
|
||||
|
||||
@@ -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/pages/main/controller.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/plugin/pl_player/models/bottom_progress_behavior.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/fullscreen_mode.dart';
|
||||
@@ -145,6 +146,12 @@ List<SettingsModel> get playSettings => [
|
||||
getSubtitle: () => '当前:「${Pref.superChatType.title}」',
|
||||
onTap: _showSuperChatDialog,
|
||||
),
|
||||
NormalModel(
|
||||
title: '全屏 SC 大小',
|
||||
subtitle: 'SuperChat (醒目留言) 大小设置',
|
||||
leading: const Icon(Icons.open_in_full),
|
||||
onTap: (_, _) => Get.to(const FullScreenScSize()),
|
||||
),
|
||||
const SwitchModel(
|
||||
title: '竖屏扩大展示',
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ abstract final class SettingBoxKey {
|
||||
enableAutoExit = 'enableAutoExit',
|
||||
enableOnlineTotal = 'enableOnlineTotal',
|
||||
superChatType = 'superChatType',
|
||||
fullScreenSCWidth = 'fullScreenSCWidth',
|
||||
keyboardControl = 'keyboardControl',
|
||||
pauseOnMinimize = 'pauseOnMinimize',
|
||||
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/user/danmaku_rule.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/bottom_progress_behavior.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/fullscreen_mode.dart';
|
||||
@@ -892,6 +894,11 @@ abstract final class Pref {
|
||||
defaultValue: SuperChatType.valid.index,
|
||||
)];
|
||||
|
||||
static double get fullScreenSCWidth => _setting.get(
|
||||
SettingBoxKey.fullScreenSCWidth,
|
||||
defaultValue: kFullScreenSCWidth,
|
||||
);
|
||||
|
||||
static bool get minimizeOnExit =>
|
||||
_setting.get(SettingBoxKey.minimizeOnExit, defaultValue: true);
|
||||
|
||||
|
||||
@@ -181,10 +181,10 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
sha256: "22fdcc3cfeb9d974d7408718c4be15ec5e9b1b350088f3a6c88f154e74dd700d"
|
||||
sha256: "1523ce62448ebac2c15a8ba5fbad8acac169788658a7dd2a1c2d9c2a9318b9a6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.14.1"
|
||||
version: "2.15.0"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -930,10 +930,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_android
|
||||
sha256: "66810af8e99b2657ee98e5c6f02064f69bb63f7a70e343937f70946c5f8c6622"
|
||||
sha256: d5b3e1774af29c9ab00103afb0d4614070f924d2e0057ac867ec98800114793f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.13+16"
|
||||
version: "0.8.13+17"
|
||||
image_picker_for_web:
|
||||
dependency: transitive
|
||||
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
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
# update when release
|
||||
version: 2.0.5+1
|
||||
version: 2.0.6+1
|
||||
|
||||
environment:
|
||||
sdk: ">=3.10.0"
|
||||
|
||||
Reference in New Issue
Block a user