只做flutter侧兜底
This commit is contained in:
parent
83fb6465f9
commit
4cf895b11e
@ -388,11 +388,8 @@ class BaishunJsBridge {
|
|||||||
static String buildConfigScript(
|
static String buildConfigScript(
|
||||||
BaishunBridgeConfigModel config, {
|
BaishunBridgeConfigModel config, {
|
||||||
String? jsCallbackPath,
|
String? jsCallbackPath,
|
||||||
Map<String, dynamic> viewportPayload = const <String, dynamic>{},
|
|
||||||
}) {
|
}) {
|
||||||
final payload = jsonEncode(
|
final payload = jsonEncode(config.toJson());
|
||||||
_mergeViewportPayload(config.toJson(), viewportPayload),
|
|
||||||
);
|
|
||||||
final encodedCallbackPath = jsonEncode(jsCallbackPath?.trim() ?? '');
|
final encodedCallbackPath = jsonEncode(jsCallbackPath?.trim() ?? '');
|
||||||
return '''
|
return '''
|
||||||
(function() {
|
(function() {
|
||||||
@ -440,15 +437,8 @@ class BaishunJsBridge {
|
|||||||
}
|
}
|
||||||
window.__baishunLastConfig = config;
|
window.__baishunLastConfig = config;
|
||||||
window.baishunBridgeConfig = config;
|
window.baishunBridgeConfig = config;
|
||||||
const viewport = config.viewport || config.nativeViewport || {};
|
|
||||||
window.__baishunViewport = viewport;
|
|
||||||
window.baishunViewport = viewport;
|
|
||||||
window.NativeBridge = window.NativeBridge || {};
|
window.NativeBridge = window.NativeBridge || {};
|
||||||
window.NativeBridge.config = config;
|
window.NativeBridge.config = config;
|
||||||
window.NativeBridge.viewport = viewport;
|
|
||||||
window.NativeBridge.getViewport = function() {
|
|
||||||
return viewport;
|
|
||||||
};
|
|
||||||
const callbackPath = explicitCallbackPath || window.__baishunLastJsCallback || '';
|
const callbackPath = explicitCallbackPath || window.__baishunLastJsCallback || '';
|
||||||
let callbackInvoked = false;
|
let callbackInvoked = false;
|
||||||
if (explicitCallbackPath) {
|
if (explicitCallbackPath) {
|
||||||
@ -465,7 +455,6 @@ class BaishunJsBridge {
|
|||||||
gsp: config.gsp,
|
gsp: config.gsp,
|
||||||
code: maskText(config.code),
|
code: maskText(config.code),
|
||||||
codeLength: config.code ? String(config.code).length : 0,
|
codeLength: config.code ? String(config.code).length : 0,
|
||||||
viewport: config.viewport || config.nativeViewport || null,
|
|
||||||
callbackPath: callbackPath
|
callbackPath: callbackPath
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -497,30 +486,6 @@ class BaishunJsBridge {
|
|||||||
''';
|
''';
|
||||||
}
|
}
|
||||||
|
|
||||||
static Map<String, dynamic> _mergeViewportPayload(
|
|
||||||
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'],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static String buildWalletUpdateScript({Map<String, dynamic>? payload}) {
|
static String buildWalletUpdateScript({Map<String, dynamic>? payload}) {
|
||||||
final safePayload = jsonEncode(
|
final safePayload = jsonEncode(
|
||||||
payload ??
|
payload ??
|
||||||
|
|||||||
@ -172,14 +172,6 @@ class LeaderJsBridge {
|
|||||||
normalizedPayload.entry && typeof normalizedPayload.entry === 'object'
|
normalizedPayload.entry && typeof normalizedPayload.entry === 'object'
|
||||||
? normalizedPayload.entry
|
? normalizedPayload.entry
|
||||||
: {};
|
: {};
|
||||||
const viewport =
|
|
||||||
normalizedPayload.viewport && typeof normalizedPayload.viewport === 'object'
|
|
||||||
? normalizedPayload.viewport
|
|
||||||
: (
|
|
||||||
launchConfig.viewport && typeof launchConfig.viewport === 'object'
|
|
||||||
? launchConfig.viewport
|
|
||||||
: {}
|
|
||||||
);
|
|
||||||
window.__leaderLaunchPayload = normalizedPayload;
|
window.__leaderLaunchPayload = normalizedPayload;
|
||||||
window.__leaderLaunchPayloadText = payloadText;
|
window.__leaderLaunchPayloadText = payloadText;
|
||||||
window.leaderLaunchPayload = normalizedPayload;
|
window.leaderLaunchPayload = normalizedPayload;
|
||||||
@ -187,21 +179,14 @@ class LeaderJsBridge {
|
|||||||
window.leaderLaunchConfig = launchConfig;
|
window.leaderLaunchConfig = launchConfig;
|
||||||
window.__leaderLaunchEntry = entry;
|
window.__leaderLaunchEntry = entry;
|
||||||
window.leaderLaunchEntry = entry;
|
window.leaderLaunchEntry = entry;
|
||||||
window.__leaderViewport = viewport;
|
|
||||||
window.leaderViewport = viewport;
|
|
||||||
window.NativeBridge = window.NativeBridge || {};
|
window.NativeBridge = window.NativeBridge || {};
|
||||||
window.NativeBridge.config = launchConfig;
|
window.NativeBridge.config = launchConfig;
|
||||||
window.NativeBridge.launchConfig = launchConfig;
|
window.NativeBridge.launchConfig = launchConfig;
|
||||||
window.NativeBridge.entry = entry;
|
window.NativeBridge.entry = entry;
|
||||||
window.NativeBridge.viewport = viewport;
|
|
||||||
window.NativeBridge.getConfig = function(callback) {
|
window.NativeBridge.getConfig = function(callback) {
|
||||||
invokeCallback(callback, launchConfig);
|
invokeCallback(callback, launchConfig);
|
||||||
return launchConfig;
|
return launchConfig;
|
||||||
};
|
};
|
||||||
window.NativeBridge.getViewport = function(callback) {
|
|
||||||
invokeCallback(callback, viewport);
|
|
||||||
return viewport;
|
|
||||||
};
|
|
||||||
window.NativeBridge.getLaunchPayload = function(callback) {
|
window.NativeBridge.getLaunchPayload = function(callback) {
|
||||||
invokeCallback(callback, normalizedPayload);
|
invokeCallback(callback, normalizedPayload);
|
||||||
return normalizedPayload;
|
return normalizedPayload;
|
||||||
@ -222,8 +207,7 @@ class LeaderJsBridge {
|
|||||||
? String(launchConfig.code).slice(0, 6) + '***'
|
? String(launchConfig.code).slice(0, 6) + '***'
|
||||||
: '',
|
: '',
|
||||||
codeLength: launchConfig.code ? String(launchConfig.code).length : 0,
|
codeLength: launchConfig.code ? String(launchConfig.code).length : 0,
|
||||||
entryUrl: entry.entryUrl || '',
|
entryUrl: entry.entryUrl || ''
|
||||||
viewport: viewport
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
const double roomGameDesignWidth = 750;
|
const double roomGameDesignWidth = 750;
|
||||||
@ -62,79 +64,74 @@ String resolveRoomGameScreenMode(
|
|||||||
return fullScreen ? 'full' : 'half';
|
return fullScreen ? 'full' : 'half';
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> buildRoomGameViewportPayload(
|
String buildRoomGameNativeFitScript({
|
||||||
BuildContext context, {
|
required double visibleHeight,
|
||||||
required double containerHeight,
|
required double expectedHeight,
|
||||||
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 options = jsonEncode(<String, dynamic>{
|
||||||
final size = mediaQuery?.size ?? Size.zero;
|
'visibleHeight': _roundMetric(visibleHeight),
|
||||||
final padding = mediaQuery?.padding ?? EdgeInsets.zero;
|
'expectedHeight': _roundMetric(expectedHeight),
|
||||||
final viewInsets = mediaQuery?.viewInsets ?? EdgeInsets.zero;
|
});
|
||||||
final targetDesignHeight =
|
return '''
|
||||||
designHeight ?? (safeHeight > 0 ? safeHeight.toDouble() : null);
|
(function() {
|
||||||
final expectedHeight =
|
const options = $options;
|
||||||
targetDesignHeight != null && size.width > 0 && designWidth > 0
|
const fitKey = '__roomGameNativeViewportFit';
|
||||||
? size.width * targetDesignHeight / designWidth
|
|
||||||
: null;
|
|
||||||
final availableHeight = resolveRoomGameAvailableHeight(context);
|
|
||||||
|
|
||||||
return <String, dynamic>{
|
function applyFit() {
|
||||||
'containerWidth': _roundMetric(size.width),
|
try {
|
||||||
'containerHeight': _roundMetric(containerHeight),
|
const visibleHeight = Number(options.visibleHeight) || window.innerHeight || 0;
|
||||||
'visibleHeight': _roundMetric(containerHeight),
|
const expectedHeight = Number(options.expectedHeight) || 0;
|
||||||
'webViewHeight': _roundMetric(actualWebViewHeight ?? containerHeight),
|
if (!document.body || !visibleHeight || !expectedHeight) {
|
||||||
'dialogHeight': _roundMetric(
|
return;
|
||||||
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(
|
const rawScale = visibleHeight / expectedHeight;
|
||||||
Map<String, dynamic> payload,
|
const scale = Math.min(1, rawScale);
|
||||||
Map<String, dynamic> viewport,
|
window[fitKey] = {
|
||||||
) {
|
scale: scale,
|
||||||
if (viewport.isEmpty) {
|
visibleHeight: visibleHeight,
|
||||||
return payload;
|
expectedHeight: expectedHeight,
|
||||||
}
|
compact: scale < 0.999
|
||||||
|
};
|
||||||
|
|
||||||
return <String, dynamic>{
|
if (scale >= 0.999) {
|
||||||
...payload,
|
document.documentElement.style.overflow = '';
|
||||||
'viewport': viewport,
|
document.body.style.overflow = '';
|
||||||
'nativeViewport': viewport,
|
document.body.style.transform = '';
|
||||||
'containerWidth': viewport['containerWidth'],
|
document.body.style.transformOrigin = '';
|
||||||
'containerHeight': viewport['containerHeight'],
|
document.body.style.width = '';
|
||||||
'visibleHeight': viewport['visibleHeight'],
|
document.body.style.minHeight = '';
|
||||||
'webViewHeight': viewport['webViewHeight'],
|
document.documentElement.removeAttribute('data-room-game-native-fit');
|
||||||
'dialogHeight': viewport['dialogHeight'],
|
return;
|
||||||
'safeAreaTop': viewport['safeAreaTop'],
|
}
|
||||||
'safeAreaBottom': viewport['safeAreaBottom'],
|
|
||||||
'devicePixelRatio': viewport['devicePixelRatio'],
|
document.documentElement.setAttribute('data-room-game-native-fit', 'true');
|
||||||
'screenMode': viewport['screenMode'],
|
document.documentElement.style.overflow = 'hidden';
|
||||||
'isCompactViewport': viewport['isCompactViewport'],
|
document.body.style.overflow = 'hidden';
|
||||||
};
|
document.body.style.transform = 'scale(' + scale + ')';
|
||||||
|
document.body.style.transformOrigin = 'top left';
|
||||||
|
document.body.style.width = (100 / scale) + '%';
|
||||||
|
document.body.style.minHeight = expectedHeight + 'px';
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', applyFit, { once: true });
|
||||||
|
} else {
|
||||||
|
applyFit();
|
||||||
|
}
|
||||||
|
[50, 250, 800, 1600, 3000].forEach(function(delay) {
|
||||||
|
window.setTimeout(applyFit, delay);
|
||||||
|
});
|
||||||
|
if (!window.__roomGameNativeFitResizeReady) {
|
||||||
|
window.__roomGameNativeFitResizeReady = true;
|
||||||
|
window.addEventListener('resize', applyFit, true);
|
||||||
|
window.addEventListener('orientationchange', function() {
|
||||||
|
window.setTimeout(applyFit, 120);
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
''';
|
||||||
}
|
}
|
||||||
|
|
||||||
double _roundMetric(double value) {
|
double _roundMetric(double value) {
|
||||||
|
|||||||
@ -105,6 +105,7 @@ class _BaishunGamePageState extends State<BaishunGamePage> {
|
|||||||
_didFinishPageLoad = true;
|
_didFinishPageLoad = true;
|
||||||
_log('page_finished url=${_clip(url, 240)}');
|
_log('page_finished url=${_clip(url, 240)}');
|
||||||
await _injectBridge(reason: 'page_finished');
|
await _injectBridge(reason: 'page_finished');
|
||||||
|
await _applyNativeViewportFit(reason: 'page_finished');
|
||||||
},
|
},
|
||||||
onWebResourceError: (WebResourceError error) {
|
onWebResourceError: (WebResourceError error) {
|
||||||
_log(
|
_log(
|
||||||
@ -260,19 +261,18 @@ class _BaishunGamePageState extends State<BaishunGamePage> {
|
|||||||
_hasDeliveredLaunchConfig = true;
|
_hasDeliveredLaunchConfig = true;
|
||||||
final rawConfig = widget.launchModel.bridgeConfig;
|
final rawConfig = widget.launchModel.bridgeConfig;
|
||||||
final config = _buildEffectiveBridgeConfig(rawConfig);
|
final config = _buildEffectiveBridgeConfig(rawConfig);
|
||||||
final viewport = _buildViewportPayload();
|
|
||||||
_log(
|
_log(
|
||||||
'send_config jsCallback=${jsCallbackPath ?? ''} '
|
'send_config jsCallback=${jsCallbackPath ?? ''} '
|
||||||
'force=$force config=${_stringifyForLog(<String, dynamic>{..._buildConfigSummary(config, rawConfig: rawConfig), 'viewport': viewport})}',
|
'force=$force config=${_stringifyForLog(_buildConfigSummary(config, rawConfig: rawConfig))}',
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
await _controller.runJavaScript(
|
await _controller.runJavaScript(
|
||||||
BaishunJsBridge.buildConfigScript(
|
BaishunJsBridge.buildConfigScript(
|
||||||
config,
|
config,
|
||||||
jsCallbackPath: jsCallbackPath,
|
jsCallbackPath: jsCallbackPath,
|
||||||
viewportPayload: viewport,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
await _applyNativeViewportFit(reason: 'send_config');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
_log('send_config_error error=${_clip(error.toString(), 300)}');
|
_log('send_config_error error=${_clip(error.toString(), 300)}');
|
||||||
}
|
}
|
||||||
@ -330,6 +330,7 @@ class _BaishunGamePageState extends State<BaishunGamePage> {
|
|||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
_errorMessage = null;
|
_errorMessage = null;
|
||||||
});
|
});
|
||||||
|
await _applyNativeViewportFit(reason: 'game_loaded');
|
||||||
break;
|
break;
|
||||||
case BaishunBridgeActions.gameRecharge:
|
case BaishunBridgeActions.gameRecharge:
|
||||||
_log('game_recharge open_wallet');
|
_log('game_recharge open_wallet');
|
||||||
@ -611,45 +612,51 @@ class _BaishunGamePageState extends State<BaishunGamePage> {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _resolveScreenMode() {
|
|
||||||
return resolveRoomGameScreenMode(
|
|
||||||
widget.game.launchParams,
|
|
||||||
fullScreen: widget.game.fullScreen,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
double _calculateWebViewHeight(BuildContext context) {
|
double _calculateWebViewHeight(BuildContext context) {
|
||||||
final mediaQuery = MediaQuery.maybeOf(context);
|
final preferredHeight = _calculatePreferredWebViewHeight(context);
|
||||||
final screenSize = mediaQuery?.size ?? Size.zero;
|
|
||||||
final safeHeight = _resolveSafeHeight();
|
|
||||||
final fallbackHeight = screenSize.height * 0.5;
|
|
||||||
final maxHeight = resolveRoomGameAvailableHeight(
|
final maxHeight = resolveRoomGameAvailableHeight(
|
||||||
context,
|
context,
|
||||||
reservedTop: 12.w,
|
reservedTop: 12.w,
|
||||||
);
|
);
|
||||||
|
return clampRoomGameHeight(preferredHeight, maxHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
double _calculatePreferredWebViewHeight(BuildContext context) {
|
||||||
|
final mediaQuery = MediaQuery.maybeOf(context);
|
||||||
|
final screenSize = mediaQuery?.size ?? Size.zero;
|
||||||
|
final safeHeight = _resolveSafeHeight();
|
||||||
|
final fallbackHeight = screenSize.height * 0.5;
|
||||||
if (safeHeight <= 0 || screenSize.width <= 0) {
|
if (safeHeight <= 0 || screenSize.width <= 0) {
|
||||||
return clampRoomGameHeight(fallbackHeight, maxHeight);
|
return fallbackHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
final ratio = roomGameDesignWidth / safeHeight;
|
final ratio = roomGameDesignWidth / safeHeight;
|
||||||
final webViewHeight = screenSize.width / ratio;
|
return screenSize.width / ratio;
|
||||||
return clampRoomGameHeight(webViewHeight, maxHeight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> _buildViewportPayload() {
|
Future<void> _applyNativeViewportFit({String reason = 'manual'}) async {
|
||||||
final topCrop = 28.w;
|
final topCrop = 28.w;
|
||||||
final webViewHeight = _calculateWebViewHeight(context);
|
final visibleHeight = _calculateWebViewHeight(context) + topCrop;
|
||||||
final safeHeight = _resolveSafeHeight();
|
final expectedHeight = _calculatePreferredWebViewHeight(context);
|
||||||
return buildRoomGameViewportPayload(
|
if (expectedHeight <= visibleHeight + 1) {
|
||||||
context,
|
return;
|
||||||
containerHeight: webViewHeight,
|
}
|
||||||
dialogHeight: webViewHeight,
|
_log(
|
||||||
topCrop: topCrop,
|
'native_fit reason=$reason visible=${visibleHeight.toStringAsFixed(1)} '
|
||||||
screenMode: _resolveScreenMode(),
|
'expected=${expectedHeight.toStringAsFixed(1)}',
|
||||||
safeHeight: safeHeight,
|
|
||||||
designHeight: safeHeight > 0 ? safeHeight.toDouble() : null,
|
|
||||||
actualWebViewHeight: webViewHeight + topCrop,
|
|
||||||
);
|
);
|
||||||
|
try {
|
||||||
|
await _controller.runJavaScript(
|
||||||
|
buildRoomGameNativeFitScript(
|
||||||
|
visibleHeight: visibleHeight,
|
||||||
|
expectedHeight: expectedHeight,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
_log(
|
||||||
|
'native_fit_error reason=$reason error=${_clip(error.toString(), 300)}',
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@ -215,10 +215,9 @@ class _LeaderGamePageState extends State<LeaderGamePage> {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await _controller.runJavaScript(
|
await _controller.runJavaScript(
|
||||||
LeaderJsBridge.bootstrapScript(
|
LeaderJsBridge.bootstrapScript(launchPayload: _buildLaunchPayload()),
|
||||||
launchPayload: _buildLaunchPayload(viewport: _buildViewportPayload()),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
await _applyNativeViewportFit(reason: reason);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
_log(
|
_log(
|
||||||
'inject_bridge_error reason=$reason error=${_clip(error.toString(), 300)}',
|
'inject_bridge_error reason=$reason error=${_clip(error.toString(), 300)}',
|
||||||
@ -347,11 +346,7 @@ class _LeaderGamePageState extends State<LeaderGamePage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
double _calculateBodyHeight(BuildContext context, double headerHeight) {
|
double _calculateBodyHeight(BuildContext context, double headerHeight) {
|
||||||
final mediaQuery = MediaQuery.maybeOf(context);
|
|
||||||
final screenSize = mediaQuery?.size ?? Size.zero;
|
|
||||||
final screenMode = _resolveScreenMode();
|
final screenMode = _resolveScreenMode();
|
||||||
final safeHeight = _resolveSafeHeight();
|
|
||||||
final fallback = screenSize.width;
|
|
||||||
final maxDialogHeight = resolveRoomGameAvailableHeight(
|
final maxDialogHeight = resolveRoomGameAvailableHeight(
|
||||||
context,
|
context,
|
||||||
reservedTop: 24.w,
|
reservedTop: 24.w,
|
||||||
@ -365,19 +360,58 @@ class _LeaderGamePageState extends State<LeaderGamePage> {
|
|||||||
return maxBodyHeight;
|
return maxBodyHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return clampRoomGameHeight(
|
||||||
|
_calculatePreferredBodyHeight(context),
|
||||||
|
maxBodyHeight,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
double _calculatePreferredBodyHeight(BuildContext context) {
|
||||||
|
final mediaQuery = MediaQuery.maybeOf(context);
|
||||||
|
final screenSize = mediaQuery?.size ?? Size.zero;
|
||||||
|
final screenMode = _resolveScreenMode();
|
||||||
|
final safeHeight = _resolveSafeHeight();
|
||||||
|
final fallback = screenSize.width;
|
||||||
|
|
||||||
if (safeHeight > 0 && screenSize.width > 0) {
|
if (safeHeight > 0 && screenSize.width > 0) {
|
||||||
final ratio = roomGameDesignWidth / safeHeight;
|
final ratio = roomGameDesignWidth / safeHeight;
|
||||||
final bodyHeight = screenSize.width / ratio;
|
return screenSize.width / ratio;
|
||||||
return clampRoomGameHeight(bodyHeight, maxBodyHeight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (screenMode == 'hd') {
|
if (screenMode == 'hd') {
|
||||||
final bodyHeight =
|
return screenSize.width * _hdDesignHeight / roomGameDesignWidth;
|
||||||
screenSize.width * _hdDesignHeight / roomGameDesignWidth;
|
|
||||||
return clampRoomGameHeight(bodyHeight, maxBodyHeight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return clampRoomGameHeight(fallback, maxBodyHeight);
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _applyNativeViewportFit({String reason = 'manual'}) async {
|
||||||
|
final screenMode = _resolveScreenMode();
|
||||||
|
if (screenMode == 'full') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final headerHeight = 44.w;
|
||||||
|
final visibleHeight = _calculateBodyHeight(context, headerHeight);
|
||||||
|
final expectedHeight = _calculatePreferredBodyHeight(context);
|
||||||
|
if (expectedHeight <= visibleHeight + 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_log(
|
||||||
|
'native_fit reason=$reason visible=${visibleHeight.toStringAsFixed(1)} '
|
||||||
|
'expected=${expectedHeight.toStringAsFixed(1)}',
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
await _controller.runJavaScript(
|
||||||
|
buildRoomGameNativeFitScript(
|
||||||
|
visibleHeight: visibleHeight,
|
||||||
|
expectedHeight: expectedHeight,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
_log(
|
||||||
|
'native_fit_error reason=$reason error=${_clip(error.toString(), 300)}',
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _log(String message) {
|
void _log(String message) {
|
||||||
@ -440,20 +474,14 @@ class _LeaderGamePageState extends State<LeaderGamePage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> _buildLaunchPayload({
|
Map<String, dynamic> _buildLaunchPayload() {
|
||||||
Map<String, dynamic> viewport = const <String, dynamic>{},
|
return <String, dynamic>{
|
||||||
}) {
|
|
||||||
final launchConfig = mergeRoomGameViewportPayload(
|
|
||||||
widget.launchModel.launchConfig.toJson(),
|
|
||||||
viewport,
|
|
||||||
);
|
|
||||||
final payload = <String, dynamic>{
|
|
||||||
'provider': widget.launchModel.provider,
|
'provider': widget.launchModel.provider,
|
||||||
'gameId': widget.launchModel.gameId,
|
'gameId': widget.launchModel.gameId,
|
||||||
'providerGameId': widget.launchModel.providerGameId,
|
'providerGameId': widget.launchModel.providerGameId,
|
||||||
'gameSessionId': widget.launchModel.gameSessionId,
|
'gameSessionId': widget.launchModel.gameSessionId,
|
||||||
'entry': widget.launchModel.entry.toJson(),
|
'entry': widget.launchModel.entry.toJson(),
|
||||||
'launchConfig': launchConfig,
|
'launchConfig': widget.launchModel.launchConfig.toJson(),
|
||||||
'roomState': widget.launchModel.roomState.toJson(),
|
'roomState': widget.launchModel.roomState.toJson(),
|
||||||
'game': <String, dynamic>{
|
'game': <String, dynamic>{
|
||||||
'gameId': widget.game.gameId,
|
'gameId': widget.game.gameId,
|
||||||
@ -463,25 +491,6 @@ class _LeaderGamePageState extends State<LeaderGamePage> {
|
|||||||
'launchMode': widget.game.launchMode,
|
'launchMode': widget.game.launchMode,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return mergeRoomGameViewportPayload(payload, viewport);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> _buildViewportPayload() {
|
|
||||||
final headerHeight = 44.w;
|
|
||||||
final bodyHeight = _calculateBodyHeight(context, headerHeight);
|
|
||||||
final safeHeight = _resolveSafeHeight();
|
|
||||||
return buildRoomGameViewportPayload(
|
|
||||||
context,
|
|
||||||
containerHeight: bodyHeight,
|
|
||||||
dialogHeight: bodyHeight + headerHeight,
|
|
||||||
headerHeight: headerHeight,
|
|
||||||
screenMode: _resolveScreenMode(),
|
|
||||||
safeHeight: safeHeight,
|
|
||||||
designHeight:
|
|
||||||
safeHeight > 0
|
|
||||||
? safeHeight.toDouble()
|
|
||||||
: (_resolveScreenMode() == 'hd' ? _hdDesignHeight : null),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> _buildLaunchPayloadForLog() {
|
Map<String, dynamic> _buildLaunchPayloadForLog() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user