Sync Pause/Resume

This commit is contained in:
Hanh 2022-07-22 10:35:21 +08:00
parent d852546fd2
commit 80e0df2daf
16 changed files with 155 additions and 47 deletions

View File

@ -6,7 +6,6 @@ LIB_OUT_DIR = "debug"
TARGET_OS = "unknown"
DEV = true
RELEASE = false
FEATURES = { script = ["echo ${COIN}"] }
[env.release]
RELEASE = true
@ -45,6 +44,7 @@ description = "Runs the rust compiler."
category = "Build"
dependencies = ["android"]
# TODO replace with "android"
args = ["build"]
[tasks.build.mac]
description = "Runs the rust compiler."

View File

@ -62,12 +62,16 @@ class SyncStatusState extends State<SyncStatusWidget> {
if (simpleMode) Padding(padding: EdgeInsets.fromLTRB(0, 8, 0, 0), child: Text(s.simpleMode)),
Observer(builder: (context) {
final time = eta.eta;
final synced = syncStatus.isSynced();
final syncedHeight = syncStatus.syncedHeight;
final timestamp = syncStatus.timestamp?.timeAgo() ?? s.na;
final latestHeight = syncStatus.latestHeight;
final remaining = syncedHeight != null ? max(latestHeight-syncedHeight, 0) : 0;
final percent = latestHeight > 0 ? 100 * (syncedHeight ?? 0) ~/ latestHeight : 0;
final disconnected = latestHeight == 0;
final neverSynced = syncedHeight == null;
final synced = syncStatus.isSynced();
final paused = syncStatus.paused;
final syncing = !paused && !disconnected && !neverSynced && !synced;
dynamic createSyncText(int iDisplay, bool animated) {
switch (iDisplay) {
@ -96,26 +100,35 @@ class SyncStatusState extends State<SyncStatusWidget> {
return createSyncText(d-1, false);
}
final text = latestHeight == 0 ? Text(s.disconnected)
: syncedHeight == null
? Text(s.rescanNeeded)
: synced
? Text('$syncedHeight', style: theme.textTheme.caption)
: GestureDetector(
onTap: () => setState(() { display += 1; }),
child: createSyncStatus());
final text;
if (paused)
text = Text(s.syncPaused);
else if (disconnected)
text = Text(s.disconnected);
else if (neverSynced)
text = Text(s.rescanNeeded);
else if (synced)
text = Text('$syncedHeight', style: theme.textTheme.caption);
else
text = createSyncStatus();
return TextButton(onPressed: synced ? () => _onSync(context) : null, child: text);
return TextButton(onPressed: () { syncing ? _onNextDisplay() : _onSync(context); }, child: text);
})
]);
}
_onSync(BuildContext context) {
if (syncStatus.syncedHeight != null)
if (syncStatus.paused)
syncStatus.setPause(false);
else if (syncStatus.syncedHeight != null)
Future.microtask(syncStatus.sync);
else
rescan(context);
}
_onNextDisplay() {
setState(() { display += 1; });
}
}
class QRAddressWidget extends StatefulWidget {

View File

@ -135,6 +135,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Broadcast from your online device"),
"budget": MessageLookupByLibrary.simpleMessage("Budget"),
"cancel": MessageLookupByLibrary.simpleMessage("Cancel"),
"cancelScan": MessageLookupByLibrary.simpleMessage("Cancel Scan"),
"changeAccountName":
MessageLookupByLibrary.simpleMessage("Change Account Name"),
"changeTransparentKey":
@ -315,6 +316,7 @@ class MessageLookup extends MessageLookupByLibrary {
"restart": MessageLookupByLibrary.simpleMessage("Restart"),
"restoreAnAccount":
MessageLookupByLibrary.simpleMessage("Restore an account?"),
"resumeScan": MessageLookupByLibrary.simpleMessage("Resume Scan"),
"retrieveTransactionDetails": MessageLookupByLibrary.simpleMessage(
"Retrieve Transaction Details"),
"roundToMillis":
@ -366,6 +368,7 @@ class MessageLookup extends MessageLookupByLibrary {
"subAccountIndexOf": m15,
"subAccountOf": m16,
"subject": MessageLookupByLibrary.simpleMessage("Subject"),
"syncPaused": MessageLookupByLibrary.simpleMessage("Sync Paused"),
"synching": MessageLookupByLibrary.simpleMessage("Synching"),
"table": MessageLookupByLibrary.simpleMessage("Table"),
"tapAnIconToShowTheQrCode": MessageLookupByLibrary.simpleMessage(

View File

@ -135,6 +135,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Transmite desde tu dispositivo en línea"),
"budget": MessageLookupByLibrary.simpleMessage("Presupuesto"),
"cancel": MessageLookupByLibrary.simpleMessage("Cancelar"),
"cancelScan": MessageLookupByLibrary.simpleMessage("Cancelar Escaneo"),
"changeAccountName":
MessageLookupByLibrary.simpleMessage("Cambiar nombre de la cuenta"),
"changeTransparentKey":
@ -318,6 +319,7 @@ class MessageLookup extends MessageLookupByLibrary {
"restart": MessageLookupByLibrary.simpleMessage("Reiniciar"),
"restoreAnAccount":
MessageLookupByLibrary.simpleMessage("Restaurar una Cuenta?"),
"resumeScan": MessageLookupByLibrary.simpleMessage("Reanudar Escaneo"),
"retrieveTransactionDetails": MessageLookupByLibrary.simpleMessage(
"Obtener detalles de la transacción"),
"roundToMillis":
@ -368,6 +370,7 @@ class MessageLookup extends MessageLookupByLibrary {
"subAccountIndexOf": m15,
"subAccountOf": m16,
"subject": MessageLookupByLibrary.simpleMessage("Subject"),
"syncPaused": MessageLookupByLibrary.simpleMessage("Escaneo en pausa"),
"synching": MessageLookupByLibrary.simpleMessage("Sincronizando"),
"table": MessageLookupByLibrary.simpleMessage("Lista"),
"tapAnIconToShowTheQrCode": MessageLookupByLibrary.simpleMessage(

View File

@ -136,6 +136,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Diffuser avec l\'appareil connecté en ligne"),
"budget": MessageLookupByLibrary.simpleMessage("Budget"),
"cancel": MessageLookupByLibrary.simpleMessage("Annuler"),
"cancelScan": MessageLookupByLibrary.simpleMessage("Suspendre Sync"),
"changeAccountName":
MessageLookupByLibrary.simpleMessage("Modifier le nom du compte"),
"changeTransparentKey":
@ -322,6 +323,7 @@ class MessageLookup extends MessageLookupByLibrary {
"restart": MessageLookupByLibrary.simpleMessage("Redémarrage"),
"restoreAnAccount":
MessageLookupByLibrary.simpleMessage("Récuperation d\'un Compte?"),
"resumeScan": MessageLookupByLibrary.simpleMessage("Continuer Sync"),
"retrieveTransactionDetails": MessageLookupByLibrary.simpleMessage(
"Récupérer les détails de la transaction"),
"roundToMillis":
@ -372,6 +374,7 @@ class MessageLookup extends MessageLookupByLibrary {
"subAccountIndexOf": m15,
"subAccountOf": m16,
"subject": MessageLookupByLibrary.simpleMessage("Sujet"),
"syncPaused": MessageLookupByLibrary.simpleMessage("Sync en Pause"),
"synching":
MessageLookupByLibrary.simpleMessage("Synchronisation en cours"),
"table": MessageLookupByLibrary.simpleMessage("Tableau"),

View File

@ -2511,6 +2511,36 @@ class S {
args: [],
);
}
/// `Cancel Scan`
String get cancelScan {
return Intl.message(
'Cancel Scan',
name: 'cancelScan',
desc: '',
args: [],
);
}
/// `Resume Scan`
String get resumeScan {
return Intl.message(
'Resume Scan',
name: 'resumeScan',
desc: '',
args: [],
);
}
/// `Sync Paused`
String get syncPaused {
return Intl.message(
'Sync Paused',
name: 'syncPaused',
desc: '',
args: [],
);
}
}
class AppLocalizationDelegate extends LocalizationsDelegate<S> {

View File

@ -132,34 +132,19 @@ class HomeInnerState extends State<HomeInnerPage> with SingleTickerProviderState
child: Icon(Icons.send),
);
final menu = PopupMenuButton<String>(
itemBuilder: (context) {
return [
PopupMenuItem(child: Text(s.accounts), value: "Accounts"),
PopupMenuItem(child: Text(s.backup), value: "Backup"),
PopupMenuItem(child: Text(s.rescan), value: "Rescan", enabled: !syncStatus.syncing),
if (!simpleMode)
PopupMenuItem(child:
PopupMenuButton(
child: Text(s.advanced),
itemBuilder: (_) => [
PopupMenuItem(child: Text(s.convertToWatchonly), enabled: active.canPay, value: "Cold"),
PopupMenuItem(child: Text(s.signOffline), enabled: active.canPay, value: "Sign"),
PopupMenuItem(child: Text(s.broadcast), value: "Broadcast"),
PopupMenuItem(child: Text(s.multipay), value: "MultiPay"),
], onSelected: _onMenu)),
// if (!simpleMode && !isMobile())
// PopupMenuItem(child: Text(s.ledger), value: "Ledger"),
PopupMenuItem(child: Text(s.settings), value: "Settings"),
PopupMenuItem(child: Text(s.help), value: "Help"),
PopupMenuItem(child: Text(s.about), value: "About"),
];
},
onSelected: _onMenu,
);
return Observer(builder: (context) {
final _1 = active.dataEpoch;
final _2 = syncStatus.paused;
final _3 = syncStatus.syncing;
final rescanMsg;
if (syncStatus.paused)
rescanMsg = s.resumeScan;
else if (syncStatus.syncing)
rescanMsg = s.cancelScan;
else
rescanMsg = s.rescan;
final unread = active.unread;
final messageTab = unread != 0 ?
Tab(child: Badge(
@ -174,6 +159,32 @@ class HomeInnerState extends State<HomeInnerPage> with SingleTickerProviderState
return SizedBox(); // Show a placeholder
}
final menu = PopupMenuButton<String>(
itemBuilder: (context) {
return [
PopupMenuItem(child: Text(s.accounts), value: "Accounts"),
PopupMenuItem(child: Text(s.backup), value: "Backup"),
PopupMenuItem(child: Text(rescanMsg), value: "Rescan"),
if (!simpleMode)
PopupMenuItem(child:
PopupMenuButton(
child: Text(s.advanced),
itemBuilder: (_) => [
PopupMenuItem(child: Text(s.convertToWatchonly), enabled: active.canPay, value: "Cold"),
PopupMenuItem(child: Text(s.signOffline), enabled: active.canPay, value: "Sign"),
PopupMenuItem(child: Text(s.broadcast), value: "Broadcast"),
PopupMenuItem(child: Text(s.multipay), value: "MultiPay"),
], onSelected: _onMenu)),
// if (!simpleMode && !isMobile())
// PopupMenuItem(child: Text(s.ledger), value: "Ledger"),
PopupMenuItem(child: Text(s.settings), value: "Settings"),
PopupMenuItem(child: Text(s.help), value: "Help"),
PopupMenuItem(child: Text(s.about), value: "About"),
];
},
onSelected: _onMenu,
);
showAboutOnce(this.context);
return Scaffold(
@ -274,7 +285,12 @@ class HomeInnerState extends State<HomeInnerPage> with SingleTickerProviderState
}
_rescan() {
rescan(context);
if (syncStatus.paused)
syncStatus.setPause(false);
else if (syncStatus.syncing)
cancelScan(context);
else
rescan(context);
}
_multiPay() {

View File

@ -244,5 +244,8 @@
"auto": "Auto",
"count": "Count",
"close": "Close",
"changeTransparentKey": "Change Transparent Key"
"changeTransparentKey": "Change Transparent Key",
"cancelScan": "Cancel Scan",
"resumeScan": "Resume Scan",
"syncPaused": "Sync Paused"
}

View File

@ -243,4 +243,7 @@
"count": "Cuenta",
"close": "Cerrar",
"changeTransparentKey": "Cambiar la clave transparente"
"cancelScan": "Cancelar Escaneo",
"resumeScan": "Reanudar Escaneo",
"syncPaused": "Escaneo en pausa"
}

View File

@ -242,5 +242,8 @@
"auto": "Auto",
"count": "Nombre",
"close": "Fermer",
"changeTransparentKey": "Changer la clé"
"changeTransparentKey": "Changer la clé",
"cancelScan": "Suspendre Sync",
"resumeScan": "Continuer Sync",
"syncPaused": "Sync en Pause"
}

View File

@ -729,6 +729,11 @@ Future<void> rescan(BuildContext context) async {
}
}
void cancelScan(BuildContext context) {
syncStatus.setPause(true);
WarpApi.cancelSync();
}
void sqlFfiInit() {
open.overrideFor(OperatingSystem.linux, _openOnLinux);
}

View File

@ -541,6 +541,9 @@ abstract class _SyncStatus with Store {
@observable
bool syncing = false;
@observable
bool paused = false;
bool isSynced() {
final sh = syncedHeight;
return sh != null && sh >= latestHeight;
@ -593,6 +596,7 @@ abstract class _SyncStatus with Store {
@action
Future<void> sync() async {
if (paused) return;
if (syncing) return;
await syncStatus.update();
if (syncedHeight == null) return;
@ -645,6 +649,11 @@ abstract class _SyncStatus with Store {
setSyncHeight(latestHeight, null);
WarpApi.skipToLastHeight(0xFF);
}
@action
void setPause(bool v) {
paused = v;
}
}
class MultiPayStore = _MultiPayStore with _$MultiPayStore;

View File

@ -21,6 +21,6 @@
<content_rating type="oars-1.1"/>
<developer_name>Hanh Huynh Huu</developer_name>
<releases>
<release version="1.2.9+252" date="2022-07-10" />
<release version="1.2.11+259" date="2022-07-18" />
</releases>
</component>

@ -1 +1 @@
Subproject commit 4fabf69589ba2f9054e761943a6d987539b9579b
Subproject commit e28ca7fd6847812d5a8db39cde4e4baa15aca845

View File

@ -87,6 +87,10 @@ class WarpApi {
return res;
}
static void cancelSync() {
warp_api_lib.cancel_warp();
}
static void mempoolReset() {
warp_api_lib.mempool_reset();
}

View File

@ -203,6 +203,15 @@ class NativeLibrary {
late final _dart_import_transparent_key _import_transparent_key =
_import_transparent_key_ptr.asFunction<_dart_import_transparent_key>();
void cancel_warp() {
return _cancel_warp();
}
late final _cancel_warp_ptr =
_lookup<ffi.NativeFunction<_c_cancel_warp>>('cancel_warp');
late final _dart_cancel_warp _cancel_warp =
_cancel_warp_ptr.asFunction<_dart_cancel_warp>();
int warp(
int coin,
int get_tx,
@ -681,12 +690,12 @@ class NativeLibrary {
void import_from_zwl(
int coin,
ffi.Pointer<ffi.Int8> name,
ffi.Pointer<ffi.Int8> path,
ffi.Pointer<ffi.Int8> data,
) {
return _import_from_zwl(
coin,
name,
path,
data,
);
}
@ -814,6 +823,10 @@ typedef _dart_import_transparent_key = void Function(
ffi.Pointer<ffi.Int8> path,
);
typedef _c_cancel_warp = ffi.Void Function();
typedef _dart_cancel_warp = void Function();
typedef _c_warp = ffi.Uint8 Function(
ffi.Uint8 coin,
ffi.Int8 get_tx,
@ -1109,11 +1122,11 @@ typedef _dart_get_best_server = ffi.Pointer<ffi.Int8> Function(
typedef _c_import_from_zwl = ffi.Void Function(
ffi.Uint8 coin,
ffi.Pointer<ffi.Int8> name,
ffi.Pointer<ffi.Int8> path,
ffi.Pointer<ffi.Int8> data,
);
typedef _dart_import_from_zwl = void Function(
int coin,
ffi.Pointer<ffi.Int8> name,
ffi.Pointer<ffi.Int8> path,
ffi.Pointer<ffi.Int8> data,
);