fix menu position

fix sc

opt ui

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-01-10 12:54:35 +08:00
parent f06d0605ce
commit 34a839d9e2
13 changed files with 102 additions and 68 deletions

View File

@@ -148,7 +148,7 @@ class CustomGridView extends StatelessWidget {
HapticFeedback.mediumImpact(); HapticFeedback.mediumImpact();
showMenu( showMenu(
context: context, context: context,
position: .fromLTRB(offset.dx, offset.dy, offset.dx, 0), position: PageUtils.menuPosition(offset),
items: [ items: [
if (PlatformUtils.isMobile) if (PlatformUtils.isMobile)
PopupMenuItem( PopupMenuItem(

View File

@@ -494,7 +494,7 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
void _showDesktopMenu(Offset offset, SourceModel item) { void _showDesktopMenu(Offset offset, SourceModel item) {
showMenu( showMenu(
context: context, context: context,
position: RelativeRect.fromLTRB(offset.dx, offset.dy, offset.dx, 0), position: PageUtils.menuPosition(offset),
items: [ items: [
PopupMenuItem( PopupMenuItem(
height: 42, height: 42,

View File

@@ -305,10 +305,10 @@ class MyApp extends StatelessWidget {
data: mediaQuery.copyWith( data: mediaQuery.copyWith(
// Tell child the logical size it should layout to // Tell child the logical size it should layout to
size: scaledSize, size: scaledSize,
textScaler: textScaler,
padding: mediaQuery.padding / uiScale, padding: mediaQuery.padding / uiScale,
viewPadding: mediaQuery.viewPadding / uiScale, viewPadding: mediaQuery.viewPadding / uiScale,
viewInsets: mediaQuery.viewInsets / uiScale, viewInsets: mediaQuery.viewInsets / uiScale,
textScaler: textScaler,
), ),
// Use OverflowBox to let child layout to scaledSize, // Use OverflowBox to let child layout to scaledSize,
// then FittedBox scales it to fit actualSize // then FittedBox scales it to fit actualSize

View File

@@ -527,9 +527,11 @@ class LiveRoomController extends GetxController {
} else { } else {
bool? refresh; bool? refresh;
for (final id in ids) { for (final id in ids) {
final item = superChatMsg.firstWhereOrNull((e) => e.id == id); if (superChatMsg.firstWhereOrNull((e) => e.id == id)
item?.deleted = true; case final item?) {
refresh ??= true; item.deleted = true;
refresh ??= true;
}
} }
if (refresh ?? false) { if (refresh ?? false) {
superChatMsg.refresh(); superChatMsg.refresh();

View File

@@ -3,6 +3,7 @@ import 'dart:async';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/image_type.dart'; import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models_new/live/live_superchat/item.dart'; import 'package:PiliPlus/models_new/live/live_superchat/item.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/platform_utils.dart'; import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -93,7 +94,7 @@ class _SuperChatCardState extends State<SuperChatCard> {
} }
showMenu( showMenu(
context: context, context: context,
position: RelativeRect.fromLTRB(offset.dx, offset.dy, offset.dx, 0), position: PageUtils.menuPosition(offset),
items: [ items: [
PopupMenuItem( PopupMenuItem(
height: 38, height: 38,
@@ -200,7 +201,7 @@ class _SuperChatCardState extends State<SuperChatCard> {
item.message, item.message,
style: TextStyle( style: TextStyle(
color: Utils.parseColor(item.messageFontColor), color: Utils.parseColor(item.messageFontColor),
decoration: !widget.persistentSC && item.deleted decoration: widget.persistentSC && item.deleted
? .lineThrough ? .lineThrough
: null, : null,
decorationThickness: 1.5, decorationThickness: 1.5,

View File

@@ -9,6 +9,7 @@ import 'package:PiliPlus/pages/live_room/superchat/superchat_card.dart';
import 'package:PiliPlus/pages/video/widgets/header_control.dart'; import 'package:PiliPlus/pages/video/widgets/header_control.dart';
import 'package:PiliPlus/utils/accounts.dart'; import 'package:PiliPlus/utils/accounts.dart';
import 'package:PiliPlus/utils/extension/theme_ext.dart'; import 'package:PiliPlus/utils/extension/theme_ext.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/foundation.dart' show kDebugMode; import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
@@ -294,9 +295,11 @@ class LiveRoomChatPanel extends StatelessWidget {
TapUpDetails details, TapUpDetails details,
DanmakuMsg item, DanmakuMsg item,
) { ) {
final dx = details.globalPosition.dx; final uiScale = Pref.uiScale;
final dx = details.globalPosition.dx / uiScale;
final renderBox = itemContext.findRenderObject() as RenderBox; final renderBox = itemContext.findRenderObject() as RenderBox;
final dy = renderBox.localToGlobal(renderBox.size.bottomLeft(.zero)).dy; final dy =
renderBox.localToGlobal(renderBox.size.bottomLeft(.zero)).dy / uiScale;
final autoScroll = final autoScroll =
liveRoomController.autoScroll && liveRoomController.autoScroll &&
!liveRoomController.disableAutoScroll.value; !liveRoomController.disableAutoScroll.value;

View File

@@ -805,6 +805,7 @@ void _showUiScaleDialog(
value: uiScale, value: uiScale,
min: _minUiScale, min: _minUiScale,
max: _maxUiScale, max: _maxUiScale,
secondaryTrackValue: 1.0,
divisions: ((_maxUiScale - _minUiScale) * 20).toInt(), divisions: ((_maxUiScale - _minUiScale) * 20).toInt(),
label: textController.text, label: textController.text,
onChanged: (value) => setDialogState(() { onChanged: (value) => setDialogState(() {
@@ -845,6 +846,7 @@ void _showUiScaleDialog(
TextButton( TextButton(
onPressed: () { onPressed: () {
Navigator.pop(context); Navigator.pop(context);
Pref.uiScale = 1.0;
GStorage.setting.delete(SettingBoxKey.uiScale).whenComplete(() { GStorage.setting.delete(SettingBoxKey.uiScale).whenComplete(() {
setState(); setState();
Get.appUpdate(); Get.appUpdate();
@@ -864,6 +866,7 @@ void _showUiScaleDialog(
TextButton( TextButton(
onPressed: () { onPressed: () {
Navigator.pop(context); Navigator.pop(context);
Pref.uiScale = uiScale;
GStorage.setting.put(SettingBoxKey.uiScale, uiScale).whenComplete( GStorage.setting.put(SettingBoxKey.uiScale, uiScale).whenComplete(
() { () {
setState(); setState();

View File

@@ -1885,34 +1885,39 @@ class VideoDetailController extends GetxController
final index = episodes.indexWhere( final index = episodes.indexWhere(
(e) => e.cid == (seasonCid ?? cid.value), (e) => e.cid == (seasonCid ?? cid.value),
); );
final size = context.mediaQuerySize;
final maxChildSize = PlatformUtils.isMobile && !size.isPortrait
? 1.0
: 0.7;
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
useSafeArea: true, useSafeArea: true,
isScrollControlled: true, isScrollControlled: true,
constraints: BoxConstraints(maxWidth: min(640, size.shortestSide)), constraints: BoxConstraints(
builder: (context) => DraggableScrollableSheet( maxWidth: min(640, context.mediaQueryShortestSide),
snap: true,
expand: false,
minChildSize: 0,
snapSizes: [maxChildSize],
maxChildSize: maxChildSize,
initialChildSize: maxChildSize,
builder: (context, scrollController) => DownloadPanel(
index: index,
videoDetail: videoDetail,
pgcItem: pgcItem,
episodes: episodes!,
scrollController: scrollController,
videoDetailController: this,
heroTag: heroTag,
ugcIntroController: ugcIntroController,
cidSet: cidSet,
),
), ),
builder: (context) {
final maxChildSize =
PlatformUtils.isMobile && !context.mediaQuerySize.isPortrait
? 1.0
: 0.7;
return DraggableScrollableSheet(
snap: true,
expand: false,
minChildSize: 0,
snapSizes: [maxChildSize],
maxChildSize: maxChildSize,
initialChildSize: maxChildSize,
builder: (context, scrollController) => DownloadPanel(
index: index,
videoDetail: videoDetail,
pgcItem: pgcItem,
episodes: episodes!,
scrollController: scrollController,
videoDetailController: this,
heroTag: heroTag,
ugcIntroController: ugcIntroController,
cidSet: cidSet,
),
);
},
); );
} }
} }

View File

@@ -12,6 +12,7 @@ import 'package:PiliPlus/utils/date_utils.dart';
import 'package:PiliPlus/utils/extension/iterable_ext.dart'; import 'package:PiliPlus/utils/extension/iterable_ext.dart';
import 'package:PiliPlus/utils/extension/num_ext.dart'; import 'package:PiliPlus/utils/extension/num_ext.dart';
import 'package:PiliPlus/utils/extension/theme_ext.dart'; import 'package:PiliPlus/utils/extension/theme_ext.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/platform_utils.dart'; import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:fixnum/fixnum.dart'; import 'package:fixnum/fixnum.dart';
import 'package:flutter/material.dart' hide ListTile; import 'package:flutter/material.dart' hide ListTile;
@@ -102,38 +103,35 @@ class WhisperSessionItem extends StatelessWidget {
}, },
), ),
onSecondaryTapUp: PlatformUtils.isDesktop onSecondaryTapUp: PlatformUtils.isDesktop
? (details) { ? (details) => showMenu(
final offset = details.globalPosition; context: context,
showMenu( position: PageUtils.menuPosition(details.globalPosition),
context: context, items: [
position: .fromLTRB(offset.dx, offset.dy, offset.dx, 0), PopupMenuItem(
items: [ height: 42,
onTap: () => onSetTop(item.isPinned, item.id),
child: Text(item.isPinned ? '移除置顶' : '置顶'),
),
if (item.id.privateId.hasTalkerUid())
PopupMenuItem( PopupMenuItem(
height: 42, height: 42,
onTap: () => onSetTop(item.isPinned, item.id), onTap: () =>
child: Text(item.isPinned ? '移除置顶' : '置顶'), onSetMute(item.isMuted, item.id.privateId.talkerUid),
child: Text('${item.isMuted ? '关闭' : '开启'}免打扰'),
), ),
if (item.id.privateId.hasTalkerUid()) if (item.id.privateId.hasTalkerUid())
PopupMenuItem( PopupMenuItem(
height: 42, height: 42,
onTap: () => onTap: () => showConfirmDialog(
onSetMute(item.isMuted, item.id.privateId.talkerUid), context: context,
child: Text('${item.isMuted ? '关闭' : '开启'}免打扰'), title: '确定删除该对话?',
onConfirm: () =>
onRemove(item.id.privateId.talkerUid.toInt()),
), ),
if (item.id.privateId.hasTalkerUid()) child: const Text('删除'),
PopupMenuItem( ),
height: 42, ],
onTap: () => showConfirmDialog( )
context: context,
title: '确定删除该对话?',
onConfirm: () =>
onRemove(item.id.privateId.talkerUid.toInt()),
),
child: const Text('删除'),
),
],
);
}
: null, : null,
onTap: () { onTap: () {
if (item.hasUnread()) { if (item.hasUnread()) {

View File

@@ -20,6 +20,7 @@ import 'package:PiliPlus/utils/extension/iterable_ext.dart';
import 'package:PiliPlus/utils/extension/num_ext.dart'; import 'package:PiliPlus/utils/extension/num_ext.dart';
import 'package:PiliPlus/utils/extension/widget_ext.dart'; import 'package:PiliPlus/utils/extension/widget_ext.dart';
import 'package:PiliPlus/utils/feed_back.dart'; import 'package:PiliPlus/utils/feed_back.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/platform_utils.dart'; import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart' hide TextField; import 'package:flutter/material.dart' hide TextField;
@@ -197,7 +198,7 @@ class _WhisperDetailPageState
void _showMenu(Offset offset, int index, Msg item, bool isOwner) { void _showMenu(Offset offset, int index, Msg item, bool isOwner) {
showMenu( showMenu(
context: context, context: context,
position: .fromLTRB(offset.dx, offset.dy, offset.dx, 0), position: PageUtils.menuPosition(offset),
items: [ items: [
if (isOwner) if (isOwner)
PopupMenuItem( PopupMenuItem(

View File

@@ -22,10 +22,12 @@ import 'package:PiliPlus/utils/app_scheme.dart';
import 'package:PiliPlus/utils/extension/context_ext.dart'; import 'package:PiliPlus/utils/extension/context_ext.dart';
import 'package:PiliPlus/utils/extension/extension.dart'; import 'package:PiliPlus/utils/extension/extension.dart';
import 'package:PiliPlus/utils/extension/iterable_ext.dart'; import 'package:PiliPlus/utils/extension/iterable_ext.dart';
import 'package:PiliPlus/utils/extension/size_ext.dart';
import 'package:PiliPlus/utils/extension/string_ext.dart'; import 'package:PiliPlus/utils/extension/string_ext.dart';
import 'package:PiliPlus/utils/feed_back.dart'; import 'package:PiliPlus/utils/feed_back.dart';
import 'package:PiliPlus/utils/global_data.dart'; import 'package:PiliPlus/utils/global_data.dart';
import 'package:PiliPlus/utils/id_utils.dart'; import 'package:PiliPlus/utils/id_utils.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/storage_pref.dart'; import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:PiliPlus/utils/url_utils.dart'; import 'package:PiliPlus/utils/url_utils.dart';
import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/utils.dart';
@@ -41,6 +43,13 @@ abstract final class PageUtils {
static final RouteObserver<PageRoute> routeObserver = static final RouteObserver<PageRoute> routeObserver =
RouteObserver<PageRoute>(); RouteObserver<PageRoute>();
static RelativeRect menuPosition(Offset offset) {
final uiScale = Pref.uiScale;
final dx = offset.dx / uiScale;
final dy = offset.dy / uiScale;
return .fromLTRB(dx, dy, dx, 0);
}
static Future<void> imageView({ static Future<void> imageView({
int initialPage = 0, int initialPage = 0,
required List<SourceModel> imgList, required List<SourceModel> imgList,
@@ -331,13 +340,17 @@ abstract final class PageUtils {
maxWidth: min(640, context.mediaQueryShortestSide), maxWidth: min(640, context.mediaQueryShortestSide),
), ),
builder: (BuildContext context) { builder: (BuildContext context) {
final maxChildSize =
PlatformUtils.isMobile && !context.mediaQuerySize.isPortrait
? 1.0
: 0.7;
return DraggableScrollableSheet( return DraggableScrollableSheet(
minChildSize: 0, minChildSize: 0,
maxChildSize: 1, maxChildSize: 1,
initialChildSize: 0.7,
snap: true, snap: true,
expand: false, expand: false,
snapSizes: const [0.7], snapSizes: [maxChildSize],
initialChildSize: maxChildSize,
builder: (BuildContext context, ScrollController scrollController) { builder: (BuildContext context, ScrollController scrollController) {
return FavPanel( return FavPanel(
ctr: ctr, ctr: ctr,

View File

@@ -24,6 +24,7 @@ import 'package:PiliPlus/pages/later/controller.dart';
import 'package:PiliPlus/pages/login/geetest/geetest_webview_dialog.dart'; import 'package:PiliPlus/pages/login/geetest/geetest_webview_dialog.dart';
import 'package:PiliPlus/utils/accounts.dart'; import 'package:PiliPlus/utils/accounts.dart';
import 'package:PiliPlus/utils/extension/context_ext.dart'; import 'package:PiliPlus/utils/extension/context_ext.dart';
import 'package:PiliPlus/utils/extension/size_ext.dart';
import 'package:PiliPlus/utils/extension/string_ext.dart'; import 'package:PiliPlus/utils/extension/string_ext.dart';
import 'package:PiliPlus/utils/feed_back.dart'; import 'package:PiliPlus/utils/feed_back.dart';
import 'package:PiliPlus/utils/platform_utils.dart'; import 'package:PiliPlus/utils/platform_utils.dart';
@@ -173,13 +174,18 @@ abstract final class RequestUtils {
maxWidth: min(640, context.mediaQueryShortestSide), maxWidth: min(640, context.mediaQueryShortestSide),
), ),
builder: (BuildContext context) { builder: (BuildContext context) {
final maxChildSize =
PlatformUtils.isMobile &&
!context.mediaQuerySize.isPortrait
? 1.0
: 0.7;
return DraggableScrollableSheet( return DraggableScrollableSheet(
minChildSize: 0, minChildSize: 0,
maxChildSize: 1, maxChildSize: 1,
initialChildSize: 0.7,
snap: true, snap: true,
expand: false, expand: false,
snapSizes: const [0.7], snapSizes: [maxChildSize],
initialChildSize: maxChildSize,
builder: builder:
( (
BuildContext context, BuildContext context,

View File

@@ -646,8 +646,10 @@ abstract final class Pref {
static double get defaultTextScale => static double get defaultTextScale =>
_setting.get(SettingBoxKey.defaultTextScale, defaultValue: 1.0); _setting.get(SettingBoxKey.defaultTextScale, defaultValue: 1.0);
static double get uiScale => static double uiScale = _setting.get(
_setting.get(SettingBoxKey.uiScale, defaultValue: 1.0); SettingBoxKey.uiScale,
defaultValue: 1.0,
);
static bool get dynamicsWaterfallFlow => static bool get dynamicsWaterfallFlow =>
_setting.get(SettingBoxKey.dynamicsWaterfallFlow, defaultValue: true); _setting.get(SettingBoxKey.dynamicsWaterfallFlow, defaultValue: true);