148 lines
4.9 KiB
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;
|
|
}
|
|
}
|
|
|