54 lines
1.8 KiB
Dart
54 lines
1.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
|
|
import '../../web/application/mall_web_host_controller.dart';
|
|
import 'mall_tab_config.dart';
|
|
|
|
enum MallEntryOpenResult { opened, unavailable, failed, alreadyOpening }
|
|
|
|
class MallEntryController {
|
|
MallEntryController(this._ref);
|
|
|
|
final Ref _ref;
|
|
bool _opening = false;
|
|
|
|
Future<MallEntryOpenResult> open(
|
|
BuildContext context, {
|
|
MallEntryRequest request = MallEntryRequest.home,
|
|
MallTabConfig? initialConfig,
|
|
}) async {
|
|
if (_opening) return MallEntryOpenResult.alreadyOpening;
|
|
_opening = true;
|
|
try {
|
|
var config = initialConfig;
|
|
if (config?.isVisible != true) {
|
|
config = await _ref.read(mallTabConfigProvider.notifier).ensureLoaded();
|
|
}
|
|
if (config?.isVisible != true || !context.mounted) {
|
|
return MallEntryOpenResult.unavailable;
|
|
}
|
|
config = await _ref
|
|
.read(mallTabConfigProvider.notifier)
|
|
.recordClick(request: request);
|
|
if (!config.isVisible || !context.mounted) {
|
|
return MallEntryOpenResult.unavailable;
|
|
}
|
|
final uri = config.attributedUri(
|
|
isDark: Theme.of(context).brightness == Brightness.dark,
|
|
);
|
|
if (uri == null) return MallEntryOpenResult.unavailable;
|
|
// The bottom mall entry is always resident. Server open-mode metadata is
|
|
// still retained for attribution, while explicit links inside H5 decide
|
|
// their own external handoff through the WebView navigation policy.
|
|
MallWebHostController.instance.open(uri);
|
|
return MallEntryOpenResult.opened;
|
|
} catch (_) {
|
|
return MallEntryOpenResult.failed;
|
|
} finally {
|
|
_opening = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
final mallEntryControllerProvider = Provider((ref) => MallEntryController(ref));
|