Files
Qlyra/lib/core/share/share_intent_bridge.dart
sevenhill f74057ce9b
Build Android (FCM) / build-android-fcm (push) Canceled after 0s
Build Android / build-android (push) Canceled after 0s
Build iOS / build-ios (push) Canceled after 0s
Build Linux / build-linux (push) Canceled after 0s
Build macOS / build-macos (push) Canceled after 0s
Build Windows / build-windows (push) Canceled after 0s
Release (main) / android (oneme) (push) Canceled after 0s
Release (main) / android (qlyra) (push) Canceled after 0s
Release (main) / windows (push) Canceled after 0s
Release (main) / linux (push) Canceled after 0s
Release (main) / macos (push) Canceled after 0s
Release (main) / ios (push) Canceled after 0s
Release (main) / release (push) Canceled after 0s
Rebrand application as Qlyra
2026-08-30 13:16:17 +03:00

115 lines
2.8 KiB
Dart

import 'dart:async';
import 'dart:io' show Platform;
import 'package:flutter/services.dart';
import '../../backend/api.dart';
import '../../frontend/screens/chats/chat_list_screen.dart';
import '../../frontend/widgets/swipe_route.dart';
import '../../main.dart';
import '../../models/shared_payload.dart';
import '../utils/logger.dart';
class ShareIntentBridge {
ShareIntentBridge._();
static final ShareIntentBridge instance = ShareIntentBridge._();
static const _method = MethodChannel('ru.qlyra.app/share');
static const _events = EventChannel('ru.qlyra.app/share_events');
static const _retryDelay = Duration(milliseconds: 300);
static const _maxRetries = 100;
bool _started = false;
bool _ready = false;
bool _presenting = false;
SharedPayload? _pending;
int _retriesLeft = 0;
Timer? _retry;
bool get _native {
try {
return Platform.isAndroid;
} catch (_) {
return false;
}
}
void init() {
if (_started || !_native) return;
_started = true;
_events.receiveBroadcastStream().listen(
_onEvent,
onError: (e) => logger.w('ShareIntentBridge: events stream error: $e'),
);
api.stateStream.listen((state) {
if (state == SessionState.online) _flushPending();
});
}
void markReady() {
_ready = true;
_flushPending();
}
Future<void> checkInitialShare() async {
if (!_native) return;
try {
_onEvent(await _method.invokeMethod<dynamic>('consumeInitialShare'));
} catch (e) {
logger.w('ShareIntentBridge.checkInitialShare: $e');
}
}
Future<void> clearCache() async {
if (!_native) return;
try {
await _method.invokeMethod<void>('clearCache');
} catch (e) {
logger.w('ShareIntentBridge.clearCache: $e');
}
}
void _onEvent(Object? event) {
final payload = SharedPayload.fromMap(event);
if (payload == null) return;
logger.i(
'Поделиться: получено ${payload.files.length} файлов'
'${payload.text != null ? ' и текст' : ''}',
);
_pending = payload;
_retriesLeft = _maxRetries;
_flushPending();
}
void _flushPending() {
final payload = _pending;
if (payload == null || _presenting) return;
final context = QlyraApp.navigatorKey.currentContext;
if (!_ready || context == null || api.state != SessionState.online) {
if (_retriesLeft <= 0) {
_pending = null;
return;
}
_retriesLeft--;
_retry ??= Timer(_retryDelay, () {
_retry = null;
_flushPending();
});
return;
}
_pending = null;
_presenting = true;
unawaited(
pushSwipeable<void>(
context,
(_) => ChatListScreen(sharePayload: payload),
).whenComplete(() {
_presenting = false;
unawaited(clearCache());
}),
);
}
}