app-starlock/lib/tools/remote_unlock_coordinator.dart

148 lines
4.9 KiB
Dart

import 'dart:async';
import 'package:get/get.dart';
import 'package:flutter/scheduler.dart';
import 'package:get/get.dart';
import 'package:star_lock/appRouters.dart';
import 'package:star_lock/main/lockDetail/lockDetail/lockDetail_logic.dart';
import 'package:star_lock/main/lockMian/entity/lockListInfo_entity.dart';
import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/tools/eventBusEventManage.dart';
import 'package:star_lock/tools/push/message_constant.dart';
import 'package:star_lock/tools/storage.dart';
import 'package:star_lock/tools/remote_unlock_overlay.dart';
class RemoteUnlockCoordinator {
factory RemoteUnlockCoordinator() => _instance;
RemoteUnlockCoordinator._();
static final RemoteUnlockCoordinator _instance = RemoteUnlockCoordinator._();
StreamSubscription? _sub;
bool _inited = false;
final List<RemoteUnlockRequestEvent> _pending = <RemoteUnlockRequestEvent>[];
String? _previousRoute;
dynamic _previousArgs;
bool get hasPrevious => _previousRoute != null;
static void init() {
_instance._init();
}
void _init() {
if (_inited) return;
_inited = true;
_sub = eventBus.on<PushExtraEvent>().listen((PushExtraEvent evt) async {
final Map<String, dynamic> data = evt.data;
final int eventNo = int.tryParse(data['eventNo']?.toString() ?? '') ?? -1;
if (eventNo != MessageConstant.talkPushBigImage) {
return;
}
final int lockId = int.tryParse(
data['lockId']?.toString() ?? '',
) ?? -1;
final int operateDate = int.tryParse(
data['operateDate']?.toString() ?? '',
) ?? 0;
final int currentDate = DateTime.now().millisecondsSinceEpoch;
final int timeoutSeconds = (60 - (currentDate - operateDate) ~/ 1000) < 0
? 0
: (60 - (currentDate - operateDate) ~/ 1000);
final RemoteUnlockRequestEvent event = RemoteUnlockRequestEvent(
lockId: lockId,
timeoutSeconds: timeoutSeconds,
operateDate: operateDate,
);
// 无论当前是否在目标锁详情页,都显示覆盖层以保证体验一致
if (Get.context == null) {
_pending.add(event);
_waitAppReadyAndFlush();
return;
}
await _navigateToLockDetailAndRefire(event);
});
}
void _waitAppReadyAndFlush() {
Timer.periodic(const Duration(milliseconds: 100), (Timer t) async {
print('等待app启动中...${Get.context}');
if (Get.context != null) {
t.cancel();
for (final RemoteUnlockRequestEvent e in List<RemoteUnlockRequestEvent>.from(_pending)) {
await _navigateToLockDetailAndRefire(e);
print('导航到指定界面成功');
}
_pending.clear();
}
});
}
Future<void> _navigateToLockDetailAndRefire(RemoteUnlockRequestEvent event) async {
final LockListInfoItemEntity? item = await _findLockItem(event.lockId);
print('导航item: $item');
if (item == null) {
return;
}
if(item.hasGateway != 1) {
return;
}
final String? lastHandledStr = await Storage.getString('handledRemoteUnlockOperateDate');
final int lastHandled = int.tryParse(lastHandledStr ?? '0') ?? 0;
if (event.timeoutSeconds <= 0) {
print('远程请求已超时,忽略展示');
return;
}
if (event.operateDate != 0 && event.operateDate == lastHandled) {
print('重复的远程请求,已处理,忽略展示');
return;
}
_previousRoute = Get.currentRoute;
_previousArgs = Get.arguments;
await RemoteUnlockOverlay.show(
lockId: event.lockId,
lockAlias: item.lockAlias ?? item.lockName ?? '',
operateDate: event.operateDate,
timeoutSeconds: event.timeoutSeconds,
);
await Storage.setString('handledRemoteUnlockOperateDate', event.operateDate.toString());
}
void restorePreviousRouteIfAny() {
if (_previousRoute != null) {
Get.toNamed(_previousRoute!, arguments: _previousArgs);
_previousRoute = null;
_previousArgs = null;
}
}
Future<LockListInfoItemEntity?> _findLockItem(int lockId) async {
final LockListInfoGroupEntity? stored = await Storage.getLockMainListData();
LockListInfoItemEntity? item;
if (stored != null) {
for (final GroupList g in stored.groupList ?? <GroupList>[]) {
for (final LockListInfoItemEntity l in g.lockList ?? <LockListInfoItemEntity>[]) {
if ((l.lockId ?? 0) == lockId) {
item = l;
break;
}
}
if (item != null) break;
}
}
if (item != null) return item;
final LockListInfoEntity res = await ApiRepository.to.getStarLockListInfo(pageNo: 1, pageSize: 50, isUnShowLoading: true);
for (final GroupList g in res.data?.groupList ?? <GroupList>[]) {
for (final LockListInfoItemEntity l in g.lockList ?? <LockListInfoItemEntity>[]) {
if ((l.lockId ?? 0) == lockId) {
return l;
}
}
}
return null;
}
}