mirror of
https://codeberg.org/shroff/phylum.git
synced 2026-05-12 07:08:44 -05:00
[client] Working primary handoff
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:js_interop';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:offtheline/offtheline.dart';
|
||||
@@ -6,6 +8,7 @@ import 'package:phylum/libphylum/phylum_account.dart';
|
||||
import 'package:phylum/ui/app/dialog_scaffold.dart';
|
||||
import 'package:phylum/ui/app/login_page.dart';
|
||||
import 'package:phylum/ui/layout/app_layout.dart';
|
||||
import 'package:phylum/util/logging.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:web/web.dart' as web;
|
||||
|
||||
@@ -23,12 +26,24 @@ class AccountSelector extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _AccountSelectorState extends State<AccountSelector> {
|
||||
final channel = web.BroadcastChannel('takover');
|
||||
final channel = web.BroadcastChannel('handoff');
|
||||
late final AccountManager<PhylumAccount> accountManager;
|
||||
String? requestId;
|
||||
Timer? retryRequestTimer;
|
||||
int retriesLeft = 0;
|
||||
bool requestAccepted = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
channel.onmessage = processMessage.toJS;
|
||||
accountManager = context.read();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
channel.onmessage = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -43,10 +58,8 @@ class _AccountSelectorState extends State<AccountSelector> {
|
||||
const Text('Phylum is already open in another tab or window'),
|
||||
const SizedBox(height: 12),
|
||||
ElevatedButton(
|
||||
onPressed: requestId == null ? requestHandoff : null,
|
||||
child: const Text('Use Here'),
|
||||
onPressed: () {
|
||||
channel.postMessage('close'.toJS);
|
||||
},
|
||||
),
|
||||
],
|
||||
));
|
||||
@@ -71,20 +84,74 @@ class _AccountSelectorState extends State<AccountSelector> {
|
||||
return AppLayout.create(account);
|
||||
}
|
||||
|
||||
void requestHandoff() {
|
||||
if (requestId != null) return;
|
||||
final r = Random();
|
||||
const chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
|
||||
|
||||
setState(() {
|
||||
requestId = String.fromCharCodes(Iterable.generate(12, (_) => chars.codeUnitAt(r.nextInt(chars.length))));
|
||||
});
|
||||
|
||||
channel.postMessage('request|$requestId'.toJS);
|
||||
retryRequestTimer = Timer.periodic(const Duration(milliseconds: 100), (t) {
|
||||
if (retriesLeft-- > 0) {
|
||||
if (!requestAccepted) {
|
||||
channel.postMessage('request|$requestId'.toJS);
|
||||
}
|
||||
} else {
|
||||
channel.postMessage('hijack|$requestId'.toJS);
|
||||
retryRequestTimer?.cancel();
|
||||
retryRequestTimer = null;
|
||||
requestId = null;
|
||||
setPrimary(true.toJS);
|
||||
accountManager.initialize();
|
||||
}
|
||||
});
|
||||
retriesLeft = 5;
|
||||
requestAccepted = false;
|
||||
}
|
||||
|
||||
void processMessage(web.MessageEvent event) {
|
||||
final msg = event.data.toString();
|
||||
final accountManager = context.read<AccountManager<PhylumAccount>>();
|
||||
if (msg == 'close') {
|
||||
final data = event.data.toString();
|
||||
final msg = data.split('|');
|
||||
if (msg.length < 2) {
|
||||
logger.w('Unrecognized message: $data');
|
||||
}
|
||||
|
||||
if (msg[0] == 'request') {
|
||||
final id = msg[1];
|
||||
if (accountManager.status == AccountManagerStatus.ready) {
|
||||
channel.postMessage('closing'.toJS);
|
||||
channel.postMessage('accept|$id'.toJS);
|
||||
accountManager.close().then((v) {
|
||||
channel.postMessage('closed'.toJS);
|
||||
channel.postMessage('success|$id'.toJS);
|
||||
setPrimary(false.toJS);
|
||||
accountManager.close();
|
||||
});
|
||||
} else {
|
||||
channel.postMessage('reject|$id'.toJS);
|
||||
}
|
||||
}
|
||||
if (msg == 'closed') {
|
||||
if (msg[0] == 'hijack') {
|
||||
setPrimary(false.toJS);
|
||||
}
|
||||
|
||||
// Process responses, but make sure the id matches
|
||||
if (msg[1] != requestId) return;
|
||||
|
||||
if (msg[0] == 'reject') {
|
||||
retryRequestTimer?.cancel();
|
||||
retryRequestTimer = null;
|
||||
requestId = null;
|
||||
}
|
||||
if (msg[0] == 'accept') {
|
||||
// Maybe display a message if this is taking time
|
||||
requestAccepted = true;
|
||||
retriesLeft += 10;
|
||||
}
|
||||
if (msg[0] == 'success') {
|
||||
retryRequestTimer?.cancel();
|
||||
retryRequestTimer = null;
|
||||
requestId = null;
|
||||
setPrimary(true.toJS);
|
||||
accountManager.initialize();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user