- 同步商城 H5 登录态与原生 token - 完善商城/原生 tab 切换、动画及返回交互 - 修复七鱼客服键盘避让和状态栏恢复 - 调整开屏跳过按钮与登录入口交互
88 lines
2.4 KiB
Dart
88 lines
2.4 KiB
Dart
import 'dart:async';
|
|
import 'dart:convert';
|
|
|
|
import 'package:dsbridge_flutter/dsbridge_flutter.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:package_info_plus/package_info_plus.dart';
|
|
|
|
import 'js_api_result.dart';
|
|
|
|
class JsApi extends JavaScriptNamespaceInterface {
|
|
JsApi({
|
|
this.onClose,
|
|
this.onLoginRequested,
|
|
this.onMallStateChanged,
|
|
Future<String> Function()? appVersionResolver,
|
|
}) : _appVersionResolver = appVersionResolver ?? _readAppVersion;
|
|
|
|
final VoidCallback? onClose;
|
|
final VoidCallback? onLoginRequested;
|
|
final ValueChanged<Map<dynamic, dynamic>?>? onMallStateChanged;
|
|
final Future<String> Function() _appVersionResolver;
|
|
|
|
@override
|
|
void register() {
|
|
registerFunction(close);
|
|
registerFunction(getAppVersion);
|
|
registerFunction(mallStateChanged);
|
|
registerFunction(login);
|
|
}
|
|
|
|
@pragma('vm:entry-point')
|
|
void close(dynamic arg, CompletionHandler handler) {
|
|
onClose?.call();
|
|
handler.complete(const JsApiResult.success().toMap());
|
|
}
|
|
|
|
@pragma('vm:entry-point')
|
|
void getAppVersion(dynamic arg, CompletionHandler handler) {
|
|
unawaited(_completeAppVersion(handler));
|
|
}
|
|
|
|
Future<void> _completeAppVersion(CompletionHandler handler) async {
|
|
try {
|
|
final version = await _appVersionResolver();
|
|
handler.complete(
|
|
JsApiResult(
|
|
code: 0,
|
|
message: 'success',
|
|
data: <String, dynamic>{'version': version},
|
|
).toMap(),
|
|
);
|
|
} catch (_) {
|
|
handler.complete(
|
|
const JsApiResult(code: 1, message: 'app version unavailable').toMap(),
|
|
);
|
|
}
|
|
}
|
|
|
|
static Future<String> _readAppVersion() async =>
|
|
(await PackageInfo.fromPlatform()).version;
|
|
|
|
@pragma('vm:entry-point')
|
|
void mallStateChanged(dynamic arg, CompletionHandler handler) {
|
|
onMallStateChanged?.call(coerceMallStateMap(arg));
|
|
handler.complete(const JsApiResult.success().toMap());
|
|
}
|
|
|
|
@pragma('vm:entry-point')
|
|
void login(dynamic arg, CompletionHandler handler) {
|
|
onLoginRequested?.call();
|
|
handler.complete(const JsApiResult.success().toMap());
|
|
}
|
|
}
|
|
|
|
Map<dynamic, dynamic>? coerceMallStateMap(dynamic arg) {
|
|
if (arg is Map) return arg;
|
|
if (arg is String && arg.isNotEmpty) {
|
|
try {
|
|
final decoded = jsonDecode(arg);
|
|
if (decoded is Map) return decoded;
|
|
} catch (_) {}
|
|
}
|
|
if (arg is List && arg.isNotEmpty && arg.first is Map) {
|
|
return arg.first as Map<dynamic, dynamic>;
|
|
}
|
|
return null;
|
|
}
|