146 lines
4.4 KiB
Dart
146 lines
4.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
const double roomGameDesignWidth = 750;
|
|
|
|
double resolveRoomGameAvailableHeight(
|
|
BuildContext context, {
|
|
double reservedTop = 12,
|
|
}) {
|
|
final mediaQuery = MediaQuery.maybeOf(context);
|
|
if (mediaQuery == null) {
|
|
return 0;
|
|
}
|
|
|
|
final bottomInset =
|
|
mediaQuery.viewInsets.bottom > mediaQuery.padding.bottom
|
|
? mediaQuery.viewInsets.bottom
|
|
: mediaQuery.padding.bottom;
|
|
final availableHeight =
|
|
mediaQuery.size.height -
|
|
mediaQuery.padding.top -
|
|
bottomInset -
|
|
reservedTop;
|
|
if (!availableHeight.isFinite || availableHeight <= 0) {
|
|
return mediaQuery.size.height;
|
|
}
|
|
return availableHeight.clamp(0.0, mediaQuery.size.height).toDouble();
|
|
}
|
|
|
|
double clampRoomGameHeight(
|
|
double value,
|
|
double maxHeight, {
|
|
double minHeight = 0,
|
|
}) {
|
|
if (!value.isFinite || value <= 0) {
|
|
return maxHeight > 0 ? maxHeight : 0;
|
|
}
|
|
if (!maxHeight.isFinite || maxHeight <= 0) {
|
|
return value;
|
|
}
|
|
if (minHeight > maxHeight) {
|
|
return maxHeight;
|
|
}
|
|
return value.clamp(minHeight, maxHeight).toDouble();
|
|
}
|
|
|
|
String resolveRoomGameScreenMode(
|
|
Map<String, dynamic> launchParams, {
|
|
required bool fullScreen,
|
|
}) {
|
|
final candidates = <String>[
|
|
launchParams['screenMode']?.toString() ?? '',
|
|
launchParams['screen_mode']?.toString() ?? '',
|
|
launchParams['displayMode']?.toString() ?? '',
|
|
launchParams['gameScreenMode']?.toString() ?? '',
|
|
];
|
|
for (final candidate in candidates) {
|
|
final trimmed = candidate.trim();
|
|
if (trimmed.isNotEmpty) {
|
|
return trimmed.toLowerCase();
|
|
}
|
|
}
|
|
return fullScreen ? 'full' : 'half';
|
|
}
|
|
|
|
Map<String, dynamic> buildRoomGameViewportPayload(
|
|
BuildContext context, {
|
|
required double containerHeight,
|
|
double? dialogHeight,
|
|
double headerHeight = 0,
|
|
double topCrop = 0,
|
|
required String screenMode,
|
|
required int safeHeight,
|
|
double designWidth = roomGameDesignWidth,
|
|
double? designHeight,
|
|
double? actualWebViewHeight,
|
|
}) {
|
|
final mediaQuery = MediaQuery.maybeOf(context);
|
|
final size = mediaQuery?.size ?? Size.zero;
|
|
final padding = mediaQuery?.padding ?? EdgeInsets.zero;
|
|
final viewInsets = mediaQuery?.viewInsets ?? EdgeInsets.zero;
|
|
final targetDesignHeight =
|
|
designHeight ?? (safeHeight > 0 ? safeHeight.toDouble() : null);
|
|
final expectedHeight =
|
|
targetDesignHeight != null && size.width > 0 && designWidth > 0
|
|
? size.width * targetDesignHeight / designWidth
|
|
: null;
|
|
final availableHeight = resolveRoomGameAvailableHeight(context);
|
|
|
|
return <String, dynamic>{
|
|
'containerWidth': _roundMetric(size.width),
|
|
'containerHeight': _roundMetric(containerHeight),
|
|
'visibleHeight': _roundMetric(containerHeight),
|
|
'webViewHeight': _roundMetric(actualWebViewHeight ?? containerHeight),
|
|
'dialogHeight': _roundMetric(
|
|
dialogHeight ?? containerHeight + headerHeight,
|
|
),
|
|
'screenHeight': _roundMetric(size.height),
|
|
'headerHeight': _roundMetric(headerHeight),
|
|
'topCrop': _roundMetric(topCrop),
|
|
'safeAreaTop': _roundMetric(padding.top),
|
|
'safeAreaBottom': _roundMetric(padding.bottom),
|
|
'viewInsetBottom': _roundMetric(viewInsets.bottom),
|
|
'availableHeight': _roundMetric(availableHeight),
|
|
'devicePixelRatio': _roundMetric(mediaQuery?.devicePixelRatio ?? 1),
|
|
'screenMode': screenMode,
|
|
'isCompactViewport':
|
|
expectedHeight != null ? containerHeight + 1 < expectedHeight : false,
|
|
'designWidth': _roundMetric(designWidth),
|
|
if (targetDesignHeight != null)
|
|
'designHeight': _roundMetric(targetDesignHeight),
|
|
'safeHeight': safeHeight,
|
|
};
|
|
}
|
|
|
|
Map<String, dynamic> mergeRoomGameViewportPayload(
|
|
Map<String, dynamic> payload,
|
|
Map<String, dynamic> viewport,
|
|
) {
|
|
if (viewport.isEmpty) {
|
|
return payload;
|
|
}
|
|
|
|
return <String, dynamic>{
|
|
...payload,
|
|
'viewport': viewport,
|
|
'nativeViewport': viewport,
|
|
'containerWidth': viewport['containerWidth'],
|
|
'containerHeight': viewport['containerHeight'],
|
|
'visibleHeight': viewport['visibleHeight'],
|
|
'webViewHeight': viewport['webViewHeight'],
|
|
'dialogHeight': viewport['dialogHeight'],
|
|
'safeAreaTop': viewport['safeAreaTop'],
|
|
'safeAreaBottom': viewport['safeAreaBottom'],
|
|
'devicePixelRatio': viewport['devicePixelRatio'],
|
|
'screenMode': viewport['screenMode'],
|
|
'isCompactViewport': viewport['isCompactViewport'],
|
|
};
|
|
}
|
|
|
|
double _roundMetric(double value) {
|
|
if (!value.isFinite) {
|
|
return 0;
|
|
}
|
|
return double.parse(value.toStringAsFixed(2));
|
|
}
|