mirror of
https://github.com/wownero/cyberwow.git
synced 2026-10-17 15:31:47 +02:00
@@ -7,3 +7,4 @@ screenshots/
|
||||
git/
|
||||
|
||||
flutter_export_environment.sh
|
||||
.flutter-plugins-dependencies
|
||||
|
||||
@@ -35,7 +35,7 @@ watch:
|
||||
|
||||
run:
|
||||
cd cyberwow && \
|
||||
flutter run --release --pid-file /tmp/flutter.pid
|
||||
flutter run --debug --pid-file /tmp/flutter.pid
|
||||
|
||||
# clang -target aarch64-linux-android21 cyberwow/native/hello.c -o cyberwow/native/output/hello
|
||||
c:
|
||||
|
||||
@@ -32,7 +32,7 @@ The binary needed is `./bin/wownerod`.
|
||||
|
||||
1. One docker instance per hash
|
||||
|
||||
See `etc/scripts/build-wownero.sh`, modify the value of `version` per build.
|
||||
See `etc/scripts/docker-build-wownero.sh`, modify the value of `version` per build.
|
||||
|
||||
2. Debian based system similar to F-droid
|
||||
|
||||
@@ -44,7 +44,7 @@ See the `wow` task in `Makefile`.
|
||||
|
||||
```
|
||||
popd
|
||||
git clone https://github.com/fuwa0529/cyberwow/
|
||||
git clone https://github.com/wownero/cyberwow/
|
||||
cd cyberwow
|
||||
|
||||
mkdir -p cyberwow/native/output/arm64
|
||||
|
||||
@@ -38,7 +38,7 @@ android {
|
||||
targetSdkVersion 28
|
||||
versionCode 22
|
||||
versionName "0.7.0.0-i"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
if(project.hasProperty("RELEASE_STORE_FILE")) {
|
||||
@@ -78,6 +78,6 @@ flutter {
|
||||
|
||||
dependencies {
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||
androidTestImplementation 'androidx.test:runner:1.1.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath 'com.android.tools.build:gradle:3.4.1'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
android.enableR8=true
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#Fri Jun 23 08:50:38 CEST 2017
|
||||
#Tue Dec 24 05:26:22 UTC 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
|
||||
|
||||
@@ -24,15 +24,16 @@ import 'config/cyberwow.dart' as cryptoConfig;
|
||||
|
||||
final c = cryptoConfig.config;
|
||||
|
||||
const arch = 'arm64';
|
||||
enum Arch { arm64, x86_64 }
|
||||
|
||||
const arch = Arch.arm64;
|
||||
// const arch = 'x86_64';
|
||||
const minimumHeight = 118361;
|
||||
|
||||
const isEmu = arch == 'x86_64';
|
||||
const isEmu = identical(arch, Arch.x86_64);
|
||||
const emuHost = '192.168.10.100';
|
||||
|
||||
const host = isEmu ? emuHost : '127.0.0.1';
|
||||
|
||||
const int hashViewBlock = 6;
|
||||
const stdoutLineBufferSize = 100;
|
||||
|
||||
|
||||
@@ -93,4 +93,5 @@ final config = CryptoConfig
|
||||
'--block-sync-size=5',
|
||||
],
|
||||
'[1337@cyberwow]: ',
|
||||
6,
|
||||
);
|
||||
|
||||
@@ -30,6 +30,7 @@ class CryptoConfig {
|
||||
final int port;
|
||||
final List<String> extraArgs;
|
||||
final String promptString;
|
||||
final int hashViewBlockLength;
|
||||
const CryptoConfig
|
||||
(
|
||||
this.outputBin,
|
||||
@@ -40,5 +41,6 @@ class CryptoConfig {
|
||||
this.port,
|
||||
this.extraArgs,
|
||||
this.promptString,
|
||||
this.hashViewBlockLength,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ Future<String> rpc2String(final String method, {final String field}) async {
|
||||
|
||||
Future<http.Response> getTransactionPool() async => rpc2('get_transaction_pool');
|
||||
|
||||
Future<List<dynamic>> getTransactionPoolSimple() async {
|
||||
Future<List<Map<String, dynamic>>> getTransactionPoolSimple() async {
|
||||
final response = await getTransactionPool();
|
||||
|
||||
if (response == null) return [];
|
||||
|
||||
@@ -162,7 +162,8 @@ Map<String, dynamic> getInfoView(Map<String, dynamic> x) {
|
||||
(k,v) => _remove.contains(k)
|
||||
);
|
||||
|
||||
final Map<String, double> _hashRate = {'hash_rate': _filteredInfo['difficulty'] / 300};
|
||||
final int _difficulty = _filteredInfo['difficulty'] ?? 0;
|
||||
final Map<String, double> _hashRate = {'hash_rate': _difficulty / 300};
|
||||
final Map<String, dynamic> _ammendedInfo = {
|
||||
..._filteredInfo,
|
||||
..._hashRate,
|
||||
|
||||
@@ -32,11 +32,10 @@ String pretty(dynamic x) {
|
||||
;
|
||||
}
|
||||
|
||||
String trimHash(String x) =>
|
||||
x.substring(0, config.hashViewBlock)
|
||||
+ '-'
|
||||
+ x.substring(config.hashViewBlock, config.hashViewBlock * 2)
|
||||
+ ' ...';
|
||||
String trimHash(String x) {
|
||||
final l = config.c.hashViewBlockLength;
|
||||
return x.substring(0, l) + '-' + x.substring(l, l * 2) + ' ...';
|
||||
}
|
||||
|
||||
Map<String, dynamic> cleanKey(Map<String, dynamic> x) {
|
||||
final _cleaned = x.map
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 fuwa
|
||||
|
||||
This file is part of CyberWOW.
|
||||
|
||||
CyberWOW is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CyberWOW is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CyberWOW. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
final Logger log = Logger('Default');
|
||||
|
||||
+35
-56
@@ -27,17 +27,12 @@ import 'package:logging/logging.dart';
|
||||
import 'dart:io';
|
||||
import 'dart:async';
|
||||
|
||||
import 'state.dart';
|
||||
import 'config.dart' as config;
|
||||
import 'logging.dart';
|
||||
import 'controller/process/deploy.dart' as process;
|
||||
import 'controller/process/run.dart' as process;
|
||||
import 'widget/loading.dart' as widget;
|
||||
import 'widget/blank.dart' as widget;
|
||||
import 'widget/syncing.dart' as widget;
|
||||
import 'widget/synced.dart' as widget;
|
||||
import 'widget/resyncing.dart' as widget;
|
||||
import 'widget/exiting.dart' as widget;
|
||||
import 'logging.dart';
|
||||
import 'state.dart' as state;
|
||||
import 'widget.dart' as widget;
|
||||
|
||||
void main() {
|
||||
Logger.root.level = kReleaseMode ? Level.INFO : Level.FINE;
|
||||
@@ -49,7 +44,7 @@ void main() {
|
||||
|
||||
class CyberWOW_App extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget build(final BuildContext context) {
|
||||
SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);
|
||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
|
||||
|
||||
@@ -75,7 +70,7 @@ class _CyberWOW_PageState extends State<CyberWOW_Page> with WidgetsBindingObserv
|
||||
{
|
||||
// AppState _state = LoadingState("init...");
|
||||
|
||||
AppState _state;
|
||||
state.AppState _state;
|
||||
AppLifecycleState _notification = AppLifecycleState.resumed;
|
||||
|
||||
bool _exiting = false;
|
||||
@@ -83,7 +78,7 @@ class _CyberWOW_PageState extends State<CyberWOW_Page> with WidgetsBindingObserv
|
||||
final StreamController<String> inputStreamController = StreamController();
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
void didChangeAppLifecycleState(final AppLifecycleState state) {
|
||||
log.fine('app cycle: ${state}');
|
||||
setState(() { _notification = state; });
|
||||
}
|
||||
@@ -94,7 +89,7 @@ class _CyberWOW_PageState extends State<CyberWOW_Page> with WidgetsBindingObserv
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _setState(AppState newState) {
|
||||
void _setState(final state.AppState newState) {
|
||||
setState
|
||||
(
|
||||
() => _state = newState
|
||||
@@ -109,58 +104,49 @@ class _CyberWOW_PageState extends State<CyberWOW_Page> with WidgetsBindingObserv
|
||||
return _exiting;
|
||||
}
|
||||
|
||||
AppState _getState() {
|
||||
state.AppState _getState() {
|
||||
return _state;
|
||||
}
|
||||
|
||||
|
||||
void _updateLoading(LoadingState state, final String msg) {
|
||||
log.fine('updateLoading: ' + msg);
|
||||
}
|
||||
|
||||
Future<void> buildStateMachine(final BlankState _blankState) async {
|
||||
Future<void> buildStateMachine(final state.BlankState _blankState) async {
|
||||
final loadingText = config.c.splash;
|
||||
LoadingState _loadingState = await _blankState.next(loadingText);
|
||||
state.LoadingState _loadingState = await _blankState.next(loadingText);
|
||||
|
||||
final binName = config.c.outputBin;
|
||||
final resourcePath = 'native/output/' + config.arch + '/' + binName;
|
||||
final resourcePath = 'native/output/' + describeEnum(config.arch) + '/' + binName;
|
||||
final bundle = DefaultAssetBundle.of(context);
|
||||
final loading = process.deployBinary(bundle, resourcePath, binName);
|
||||
|
||||
SyncingState _syncingState = await _loadingState.next(loading, '');
|
||||
state.SyncingState _syncingState = await _loadingState.next(loading);
|
||||
|
||||
final syncing = process
|
||||
.runBinary(binName, input: inputStreamController.stream, shouldExit: _isExiting)
|
||||
.asBroadcastStream();
|
||||
|
||||
HookedState _syncedNextState = await _syncingState.next(inputStreamController.sink, syncing);
|
||||
await _syncingState.next(inputStreamController.sink, syncing);
|
||||
|
||||
var exited = false;
|
||||
bool exited = false;
|
||||
bool validState = true;
|
||||
|
||||
if (_syncedNextState is SyncedState) {
|
||||
SyncedState _syncedState = _syncedNextState;
|
||||
await _syncedState.next();
|
||||
} else {
|
||||
ExitingState _exitingState = _syncedNextState;
|
||||
await _exitingState.wait();
|
||||
exited = true;
|
||||
}
|
||||
|
||||
var validState = true;
|
||||
while (validState && !exited) {
|
||||
await _getState().use
|
||||
(
|
||||
(s) => validState = false,
|
||||
(s) => validState = false,
|
||||
(s) => validState = false,
|
||||
(s) => s.next(),
|
||||
(s) => s.next(),
|
||||
(s) async {
|
||||
await s.wait();
|
||||
switch (_state.runtimeType) {
|
||||
case state.ExitingState: {
|
||||
await (_state as state.ExitingState).wait();
|
||||
log.finer('exit state wait done');
|
||||
exited = true;
|
||||
}
|
||||
);
|
||||
break;
|
||||
|
||||
case state.SyncedState:
|
||||
await (_state as state.SyncedState).next();
|
||||
break;
|
||||
|
||||
case state.ReSyncingState:
|
||||
await (_state as state.ReSyncingState).next();
|
||||
break;
|
||||
|
||||
default: validState = false;
|
||||
}
|
||||
}
|
||||
|
||||
log.finer('state machine finished');
|
||||
@@ -182,13 +168,14 @@ class _CyberWOW_PageState extends State<CyberWOW_Page> with WidgetsBindingObserv
|
||||
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
|
||||
final BlankState _blankState = BlankState(_setState, _getNotification, _isExiting);
|
||||
final state.AppHook _appHook = state.AppHook(_setState, _getNotification, _isExiting);
|
||||
final state.BlankState _blankState = state.BlankState(_appHook);
|
||||
_state = _blankState;
|
||||
|
||||
buildStateMachine(_blankState);
|
||||
}
|
||||
|
||||
Future<bool> _exitApp(BuildContext context) async {
|
||||
Future<bool> _exitApp(final BuildContext context) async {
|
||||
log.info("CyberWOW_PageState _exitApp");
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
|
||||
@@ -203,19 +190,11 @@ class _CyberWOW_PageState extends State<CyberWOW_Page> with WidgetsBindingObserv
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget build(final BuildContext context) {
|
||||
return WillPopScope
|
||||
(
|
||||
onWillPop: () => _exitApp(context),
|
||||
child: _state.use
|
||||
(
|
||||
(s) => widget.buildBlank(context, s),
|
||||
(s) => widget.buildLoading(context, s),
|
||||
(s) => widget.buildSyncing(context, s),
|
||||
(s) => widget.buildSynced(context, s),
|
||||
(s) => widget.buildReSyncing(context, s),
|
||||
(s) => widget.buildExiting(context, s),
|
||||
),
|
||||
child: widget.build(context, _state),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-424
@@ -19,430 +19,13 @@ along with CyberWOW. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:io';
|
||||
import 'dart:developer';
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:collection';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
export 'state/prototype.dart';
|
||||
export 'state/blank.dart';
|
||||
export 'state/loading.dart';
|
||||
export 'state/syncing.dart';
|
||||
export 'state/synced.dart';
|
||||
export 'state/resyncing.dart';
|
||||
export 'state/exiting.dart';
|
||||
|
||||
import 'controller/helper.dart';
|
||||
import 'controller/rpc/rpc.dart' as rpc;
|
||||
import 'controller/rpc/rpc2.dart' as rpc;
|
||||
import 'controller/daemon.dart' as daemon;
|
||||
import 'controller/refresh.dart' as refresh;
|
||||
import 'config.dart' as config;
|
||||
import 'logging.dart';
|
||||
import 'helper.dart';
|
||||
import 'controller/rpc/rpcView.dart' as rpcView;
|
||||
import 'controller/rpc/rpc2View.dart' as rpc2View;
|
||||
|
||||
abstract class AppState {
|
||||
T use<T>
|
||||
(
|
||||
T Function(BlankState) useBlankState,
|
||||
T Function(LoadingState) useLoadingState,
|
||||
T Function(SyncingState) useSyncingState,
|
||||
T Function(SyncedState) useSyncedState,
|
||||
T Function(ReSyncingState) useReSyncingState,
|
||||
T Function(ExitingState) useExitingState,
|
||||
)
|
||||
{
|
||||
if (this is BlankState) {
|
||||
return useBlankState(this);
|
||||
}
|
||||
if (this is LoadingState) {
|
||||
return useLoadingState(this);
|
||||
}
|
||||
if (this is SyncingState) {
|
||||
return useSyncingState(this);
|
||||
}
|
||||
if (this is SyncedState) {
|
||||
return useSyncedState(this);
|
||||
}
|
||||
if (this is ReSyncingState) {
|
||||
return useReSyncingState(this);
|
||||
}
|
||||
if (this is ExitingState) {
|
||||
return useExitingState(this);
|
||||
}
|
||||
throw Exception('Invalid state');
|
||||
}
|
||||
}
|
||||
|
||||
typedef SetStateFunc = void Function(AppState);
|
||||
typedef GetNotificationFunc = AppLifecycleState Function();
|
||||
typedef IsExitingFunc = bool Function();
|
||||
|
||||
class HookedState extends AppState {
|
||||
final SetStateFunc setState;
|
||||
final GetNotificationFunc getNotification;
|
||||
final IsExitingFunc isExiting;
|
||||
HookedState(this.setState, this.getNotification, this.isExiting);
|
||||
|
||||
syncState() {
|
||||
setState(this);
|
||||
}
|
||||
|
||||
HookedState moveState(HookedState _next) {
|
||||
setState(_next);
|
||||
return _next;
|
||||
}
|
||||
}
|
||||
|
||||
class BlankState extends HookedState {
|
||||
BlankState(f1, f2, f3) : super (f1, f2, f3);
|
||||
|
||||
Future<LoadingState> next(String status) async {
|
||||
LoadingState _next = LoadingState(setState, getNotification, isExiting, status);
|
||||
return moveState(_next);
|
||||
}
|
||||
}
|
||||
|
||||
class LoadingState extends HookedState {
|
||||
final String banner;
|
||||
String status = '';
|
||||
|
||||
LoadingState(f1, f2, f3, this.banner) : super (f1, f2, f3);
|
||||
|
||||
void append(final String msg) {
|
||||
this.status += msg;
|
||||
syncState();
|
||||
}
|
||||
|
||||
|
||||
Future<SyncingState> next(Stream<String> loadingProgress, String status) async {
|
||||
Future<void> showBanner() async {
|
||||
var chars = [];
|
||||
banner.runes.forEach((int rune) {
|
||||
final c = String.fromCharCode(rune);
|
||||
chars.add(c);
|
||||
});
|
||||
|
||||
for (String char in chars) {
|
||||
append(char);
|
||||
await Future.delayed(Duration(milliseconds: config.c.splashDelay), () => "1");
|
||||
}
|
||||
|
||||
await Future.delayed(const Duration(seconds: 2), () => "1");
|
||||
}
|
||||
|
||||
Future<void> load() async {
|
||||
log.fine("Loading next");
|
||||
await for (final line in loadingProgress) {
|
||||
// append(line);
|
||||
log.info(line);
|
||||
}
|
||||
}
|
||||
|
||||
final outputBinExists = await binaryExists(config.c.outputBin);
|
||||
if (outputBinExists) {
|
||||
await load();
|
||||
}
|
||||
else {
|
||||
await Future.wait([load(), showBanner()]);
|
||||
}
|
||||
|
||||
SyncingState _next = SyncingState(setState, getNotification, isExiting);
|
||||
return moveState(_next);
|
||||
}
|
||||
}
|
||||
|
||||
class SyncingState extends HookedState {
|
||||
final Queue<String> stdout = Queue.from(['']);
|
||||
|
||||
bool synced = false;
|
||||
|
||||
SyncingState(f1, f2, f3) : super (f1, f2, f3);
|
||||
|
||||
void append(final String msg) {
|
||||
stdout.addLast(msg);
|
||||
while (stdout.length > config.stdoutLineBufferSize) {
|
||||
stdout.removeFirst();
|
||||
}
|
||||
syncState();
|
||||
}
|
||||
|
||||
Future<HookedState> next
|
||||
(
|
||||
StreamSink<String> processInput, Stream<String> processOutput
|
||||
) async {
|
||||
log.fine("Syncing next");
|
||||
|
||||
Future<void> printStdout() async {
|
||||
await for (final line in processOutput) {
|
||||
if (synced) break;
|
||||
log.finest('syncing: print stdout loop');
|
||||
|
||||
append(line);
|
||||
log.info(line);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> checkSync() async {
|
||||
await for (final _null in refresh.pull(getNotification, 'syncingState')) {
|
||||
log.finer('SyncingState: checkSync loop');
|
||||
|
||||
if (isExiting()) {
|
||||
log.fine('Syncing state detected exiting');
|
||||
break;
|
||||
}
|
||||
|
||||
// here doc is wrong, targetHeight could match height when synced
|
||||
// potential bug, targetHeight could be smaller then height
|
||||
final _isConnected = await daemon.isConnected();
|
||||
final _isSynced = await daemon.isSynced();
|
||||
|
||||
if (_isConnected && _isSynced) {
|
||||
synced = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printStdout();
|
||||
await checkSync();
|
||||
|
||||
if (isExiting()) {
|
||||
ExitingState _next = ExitingState
|
||||
(
|
||||
setState, getNotification, isExiting, stdout, processOutput
|
||||
);
|
||||
return moveState(_next);
|
||||
}
|
||||
|
||||
log.fine('syncing: loop exit');
|
||||
|
||||
// processInput.add('exit');
|
||||
|
||||
final _height = await rpc.height();
|
||||
SyncedState _next = SyncedState
|
||||
(
|
||||
setState, getNotification, isExiting, stdout, processInput, processOutput, 1,
|
||||
);
|
||||
_next.height = _height;
|
||||
return moveState(_next);
|
||||
}
|
||||
}
|
||||
|
||||
class SyncedState extends HookedState {
|
||||
final Queue<String> stdout;
|
||||
final StreamSink<String> processInput;
|
||||
final Stream<String> processOutput;
|
||||
final TextEditingController textController = TextEditingController();
|
||||
|
||||
int height;
|
||||
bool synced = true;
|
||||
bool userExit = false;
|
||||
bool connected = true;
|
||||
Map<String, dynamic> getInfo = {};
|
||||
List<Map<String, dynamic>> getConnections = [];
|
||||
List<Map<String, dynamic>> getTransactionPool = [];
|
||||
int pageIndex;
|
||||
String syncInfo = 'syncInfo';
|
||||
PageController pageController;
|
||||
|
||||
String getInfoCache = '';
|
||||
String getConnectionsCache = '';
|
||||
String getTransactionPoolCache = '';
|
||||
|
||||
SyncedState(f1, f2, f3, this.stdout, this.processInput, this.processOutput, this.pageIndex)
|
||||
: super (f1, f2, f3) {
|
||||
pageController = PageController( initialPage: pageIndex );
|
||||
}
|
||||
|
||||
void appendInput(final String line) {
|
||||
stdout.addLast(config.c.promptString + line + '\n');
|
||||
syncState();
|
||||
processInput.add(line);
|
||||
|
||||
if (line == 'exit') {
|
||||
userExit = true;
|
||||
}
|
||||
}
|
||||
|
||||
void append(final String msg) {
|
||||
stdout.addLast(msg);
|
||||
while (stdout.length > config.stdoutLineBufferSize) {
|
||||
stdout.removeFirst();
|
||||
}
|
||||
syncState();
|
||||
}
|
||||
|
||||
void onPageChanged(int value) {
|
||||
this.pageIndex = value;
|
||||
}
|
||||
|
||||
Future<HookedState> next() async {
|
||||
log.fine("Synced next");
|
||||
|
||||
Future<void> logStdout() async {
|
||||
await for (final line in processOutput) {
|
||||
if (!synced) break;
|
||||
|
||||
// print('synced: print stdout loop');
|
||||
append(line);
|
||||
log.info(line);
|
||||
}
|
||||
}
|
||||
|
||||
logStdout();
|
||||
|
||||
Future<void> checkSync() async {
|
||||
await for (final _null in refresh.pull(getNotification, 'syncedState')) {
|
||||
if (isExiting() || userExit) {
|
||||
log.fine('Synced state detected exiting');
|
||||
break;
|
||||
}
|
||||
|
||||
if (await daemon.isNotSynced()) {
|
||||
synced = false;
|
||||
break;
|
||||
}
|
||||
// log.finer('SyncedState: checkSync loop');
|
||||
height = await rpc.height();
|
||||
connected = await daemon.isConnected();
|
||||
getInfo = await rpc.getInfoSimple();
|
||||
final _getInfoView = cleanKey(rpcView.getInfoView(getInfo));
|
||||
getInfoCache = pretty(_getInfoView);
|
||||
|
||||
getConnections = await rpc.getConnectionsSimple();
|
||||
final List<Map<String, dynamic>> _getConnectionsView =
|
||||
getConnections
|
||||
.map(rpcView.getConnectionView)
|
||||
.map((x) => rpcView.simpleHeight(height, x))
|
||||
.map(cleanKey)
|
||||
.toList();
|
||||
getConnectionsCache = pretty(_getConnectionsView);
|
||||
|
||||
getTransactionPool = await rpc.getTransactionPoolSimple();
|
||||
final List<Map<String, dynamic>> _getTransactionPoolView =
|
||||
getTransactionPool.map(rpc2View.txView).map(cleanKey).toList();
|
||||
getTransactionPoolCache = pretty(_getTransactionPoolView);
|
||||
|
||||
syncState();
|
||||
}
|
||||
}
|
||||
|
||||
await checkSync();
|
||||
|
||||
if (isExiting() || userExit) {
|
||||
ExitingState _next = ExitingState
|
||||
(
|
||||
setState, getNotification, isExiting, stdout, processOutput
|
||||
);
|
||||
return moveState(_next);
|
||||
}
|
||||
|
||||
log.fine('synced: loop exit');
|
||||
|
||||
ReSyncingState _next = ReSyncingState
|
||||
(
|
||||
setState, getNotification, isExiting, stdout, processInput, processOutput, pageIndex
|
||||
);
|
||||
return moveState(_next);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ReSyncingState extends HookedState {
|
||||
final Queue<String> stdout;
|
||||
final StreamSink<String> processInput;
|
||||
final Stream<String> processOutput;
|
||||
final int pageIndex;
|
||||
|
||||
bool synced = false;
|
||||
|
||||
ReSyncingState(f1, f2, f3, this.stdout, this.processInput, this.processOutput, this.pageIndex)
|
||||
: super (f1, f2, f3);
|
||||
|
||||
void append(final String msg) {
|
||||
stdout.addLast(msg);
|
||||
while (stdout.length > config.stdoutLineBufferSize) {
|
||||
stdout.removeFirst();
|
||||
}
|
||||
syncState();
|
||||
}
|
||||
|
||||
Future<HookedState> next() async {
|
||||
log.fine("ReSyncing next");
|
||||
|
||||
Future<void> printStdout() async {
|
||||
await for (final line in processOutput) {
|
||||
if (synced) break;
|
||||
// print('re-syncing: print stdout loop');
|
||||
append(line);
|
||||
log.info(line);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> checkSync() async {
|
||||
await for (final _null in refresh.pull(getNotification, 'ReSyncingState')) {
|
||||
if (isExiting()) {
|
||||
log.fine('ReSyncing state detected exiting');
|
||||
break;
|
||||
}
|
||||
|
||||
if (await daemon.isSynced()) {
|
||||
synced = true;
|
||||
break;
|
||||
}
|
||||
// print('re-syncing: checkSync loop');
|
||||
}
|
||||
}
|
||||
|
||||
printStdout();
|
||||
await checkSync();
|
||||
|
||||
if (isExiting()) {
|
||||
ExitingState _next = ExitingState
|
||||
(
|
||||
setState, getNotification, isExiting, stdout, processOutput
|
||||
);
|
||||
return moveState(_next);
|
||||
}
|
||||
|
||||
log.fine('resync: await exit');
|
||||
SyncedState _next = SyncedState
|
||||
(
|
||||
setState, getNotification, isExiting, stdout, processInput, processOutput, pageIndex
|
||||
);
|
||||
_next.height = await rpc.height();
|
||||
return moveState(_next);
|
||||
}
|
||||
}
|
||||
|
||||
class ExitingState extends HookedState {
|
||||
final Queue<String> stdout;
|
||||
final Stream<String> processOutput;
|
||||
|
||||
ExitingState(f1, f2, f3, this.stdout, this.processOutput) : super (f1, f2, f3);
|
||||
|
||||
void append(final String msg) {
|
||||
stdout.addLast(msg);
|
||||
while (stdout.length > config.stdoutLineBufferSize) {
|
||||
stdout.removeFirst();
|
||||
}
|
||||
syncState();
|
||||
}
|
||||
|
||||
Future<SyncedState> wait() async {
|
||||
log.finer("Exiting wait");
|
||||
|
||||
Future<void> printStdout() async {
|
||||
await for (final line in processOutput) {
|
||||
log.finer('exiting: print stdout loop');
|
||||
|
||||
append(line);
|
||||
log.info(line);
|
||||
}
|
||||
}
|
||||
|
||||
await printStdout();
|
||||
|
||||
log.finer('exiting state done');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 fuwa
|
||||
|
||||
This file is part of CyberWOW.
|
||||
|
||||
CyberWOW is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CyberWOW is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CyberWOW. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'prototype.dart';
|
||||
import 'loading.dart';
|
||||
|
||||
class BlankState extends AppState {
|
||||
BlankState(appHook) : super (appHook);
|
||||
|
||||
Future<LoadingState> next(String status) async {
|
||||
LoadingState _next = LoadingState(appHook, status);
|
||||
return moveState(_next);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 fuwa
|
||||
|
||||
This file is part of CyberWOW.
|
||||
|
||||
CyberWOW is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CyberWOW is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CyberWOW. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
import 'dart:collection';
|
||||
|
||||
import '../config.dart' as config;
|
||||
import '../logging.dart';
|
||||
|
||||
import 'prototype.dart';
|
||||
|
||||
class ExitingState extends AppState {
|
||||
final Queue<String> stdout;
|
||||
final Stream<String> processOutput;
|
||||
|
||||
ExitingState(appHook, this.stdout, this.processOutput) : super (appHook);
|
||||
|
||||
void append(final String msg) {
|
||||
stdout.addLast(msg);
|
||||
while (stdout.length > config.stdoutLineBufferSize) {
|
||||
stdout.removeFirst();
|
||||
}
|
||||
syncState();
|
||||
}
|
||||
|
||||
Future<void> wait() async {
|
||||
log.finer("Exiting wait");
|
||||
|
||||
Future<void> printStdout() async {
|
||||
await for (final line in processOutput) {
|
||||
log.finer('exiting: print stdout loop');
|
||||
|
||||
append(line);
|
||||
log.info(line);
|
||||
}
|
||||
}
|
||||
|
||||
await printStdout();
|
||||
|
||||
log.finer('exiting state done');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 fuwa
|
||||
|
||||
This file is part of CyberWOW.
|
||||
|
||||
CyberWOW is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CyberWOW is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CyberWOW. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
import '../controller/helper.dart';
|
||||
import '../config.dart' as config;
|
||||
import '../logging.dart';
|
||||
|
||||
import 'prototype.dart';
|
||||
import 'syncing.dart';
|
||||
|
||||
class LoadingState extends AppState {
|
||||
final String banner;
|
||||
String status = '';
|
||||
|
||||
LoadingState(appHook, this.banner) : super (appHook);
|
||||
|
||||
void append(final String msg) {
|
||||
this.status += msg;
|
||||
syncState();
|
||||
}
|
||||
|
||||
|
||||
Future<SyncingState> next(final Stream<String> loadingProgress) async {
|
||||
Future<void> showBanner() async {
|
||||
List<String> chars = [];
|
||||
banner.runes.forEach((int rune) {
|
||||
final c = String.fromCharCode(rune);
|
||||
chars.add(c);
|
||||
});
|
||||
|
||||
for (final String char in chars) {
|
||||
append(char);
|
||||
await Future.delayed(Duration(milliseconds: config.c.splashDelay), () => "1");
|
||||
}
|
||||
|
||||
await Future.delayed(const Duration(seconds: 2), () => "1");
|
||||
}
|
||||
|
||||
Future<void> load() async {
|
||||
log.fine("Loading next");
|
||||
await for (final line in loadingProgress) {
|
||||
// append(line);
|
||||
log.info(line);
|
||||
}
|
||||
}
|
||||
|
||||
final outputBinExists = await binaryExists(config.c.outputBin);
|
||||
if (outputBinExists) {
|
||||
await load();
|
||||
}
|
||||
else {
|
||||
await Future.wait([load(), showBanner()]);
|
||||
}
|
||||
|
||||
SyncingState _next = SyncingState(appHook);
|
||||
return moveState(_next);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 fuwa
|
||||
|
||||
This file is part of CyberWOW.
|
||||
|
||||
CyberWOW is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CyberWOW is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CyberWOW. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
typedef SetStateFunc = void Function(AppState);
|
||||
typedef GetNotificationFunc = AppLifecycleState Function();
|
||||
typedef IsExitingFunc = bool Function();
|
||||
|
||||
class AppHook {
|
||||
final SetStateFunc setState;
|
||||
final GetNotificationFunc getNotification;
|
||||
final IsExitingFunc isExiting;
|
||||
AppHook(this.setState, this.getNotification, this.isExiting);
|
||||
}
|
||||
|
||||
class AppState {
|
||||
final AppHook appHook;
|
||||
AppState(this.appHook);
|
||||
|
||||
syncState() {
|
||||
appHook.setState(this);
|
||||
}
|
||||
|
||||
AppState moveState(AppState _next) {
|
||||
appHook.setState(_next);
|
||||
return _next;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 fuwa
|
||||
|
||||
This file is part of CyberWOW.
|
||||
|
||||
CyberWOW is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CyberWOW is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CyberWOW. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
|
||||
import '../controller/rpc/rpc.dart' as rpc;
|
||||
import '../controller/daemon.dart' as daemon;
|
||||
import '../controller/refresh.dart' as refresh;
|
||||
import '../config.dart' as config;
|
||||
import '../logging.dart';
|
||||
|
||||
import 'prototype.dart';
|
||||
import 'synced.dart';
|
||||
import 'exiting.dart';
|
||||
|
||||
|
||||
class ReSyncingState extends AppState {
|
||||
final Queue<String> stdout;
|
||||
final StreamSink<String> processInput;
|
||||
final Stream<String> processOutput;
|
||||
final int pageIndex;
|
||||
|
||||
bool synced = false;
|
||||
|
||||
ReSyncingState(appHook, this.stdout, this.processInput, this.processOutput, this.pageIndex)
|
||||
: super (appHook);
|
||||
|
||||
void append(final String msg) {
|
||||
stdout.addLast(msg);
|
||||
while (stdout.length > config.stdoutLineBufferSize) {
|
||||
stdout.removeFirst();
|
||||
}
|
||||
syncState();
|
||||
}
|
||||
|
||||
Future<AppState> next() async {
|
||||
log.fine("ReSyncing next");
|
||||
|
||||
Future<void> printStdout() async {
|
||||
await for (final line in processOutput) {
|
||||
if (synced) break;
|
||||
// print('re-syncing: print stdout loop');
|
||||
append(line);
|
||||
log.info(line);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> checkSync() async {
|
||||
await for (final _null in refresh.pull(appHook.getNotification, 'ReSyncingState')) {
|
||||
if (appHook.isExiting()) {
|
||||
log.fine('ReSyncing state detected exiting');
|
||||
break;
|
||||
}
|
||||
|
||||
if (await daemon.isSynced()) {
|
||||
synced = true;
|
||||
break;
|
||||
}
|
||||
// print('re-syncing: checkSync loop');
|
||||
}
|
||||
}
|
||||
|
||||
printStdout();
|
||||
await checkSync();
|
||||
|
||||
if (appHook.isExiting()) {
|
||||
ExitingState _next = ExitingState
|
||||
(
|
||||
appHook, stdout, processOutput
|
||||
);
|
||||
return moveState(_next);
|
||||
}
|
||||
|
||||
log.fine('resync: await exit');
|
||||
SyncedState _next = SyncedState
|
||||
(
|
||||
appHook, stdout, processInput, processOutput, pageIndex
|
||||
);
|
||||
_next.height = await rpc.height();
|
||||
return moveState(_next);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 fuwa
|
||||
|
||||
This file is part of CyberWOW.
|
||||
|
||||
CyberWOW is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CyberWOW is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CyberWOW. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../config.dart' as config;
|
||||
import '../controller/daemon.dart' as daemon;
|
||||
import '../controller/refresh.dart' as refresh;
|
||||
import '../controller/rpc/rpc.dart' as rpc;
|
||||
import '../controller/rpc/rpc2.dart' as rpc;
|
||||
import '../controller/rpc/rpc2View.dart' as rpc2View;
|
||||
import '../controller/rpc/rpcView.dart' as rpcView;
|
||||
import '../helper.dart';
|
||||
import '../logging.dart';
|
||||
|
||||
import 'prototype.dart';
|
||||
import 'resyncing.dart';
|
||||
import 'exiting.dart';
|
||||
|
||||
class SyncedState extends AppState {
|
||||
final Queue<String> stdout;
|
||||
final StreamSink<String> processInput;
|
||||
final Stream<String> processOutput;
|
||||
final TextEditingController textController = TextEditingController();
|
||||
|
||||
int height;
|
||||
bool synced = true;
|
||||
bool userExit = false;
|
||||
bool connected = true;
|
||||
Map<String, dynamic> getInfo = {};
|
||||
List<Map<String, dynamic>> getConnections = [];
|
||||
List<Map<String, dynamic>> getTransactionPool = [];
|
||||
int pageIndex;
|
||||
String syncInfo = 'syncInfo';
|
||||
PageController pageController;
|
||||
|
||||
String getInfoCache = '';
|
||||
String getConnectionsCache = '';
|
||||
String getTransactionPoolCache = '';
|
||||
|
||||
SyncedState(appHook, this.stdout, this.processInput, this.processOutput, this.pageIndex)
|
||||
: super (appHook) {
|
||||
pageController = PageController( initialPage: pageIndex );
|
||||
}
|
||||
|
||||
void appendInput(final String line) {
|
||||
stdout.addLast(config.c.promptString + line + '\n');
|
||||
syncState();
|
||||
processInput.add(line);
|
||||
|
||||
if (line == 'exit') {
|
||||
userExit = true;
|
||||
}
|
||||
}
|
||||
|
||||
void append(final String msg) {
|
||||
stdout.addLast(msg);
|
||||
while (stdout.length > config.stdoutLineBufferSize) {
|
||||
stdout.removeFirst();
|
||||
}
|
||||
syncState();
|
||||
}
|
||||
|
||||
void onPageChanged(int value) {
|
||||
this.pageIndex = value;
|
||||
}
|
||||
|
||||
Future<AppState> next() async {
|
||||
log.fine("Synced next");
|
||||
|
||||
Future<void> logStdout() async {
|
||||
await for (final line in processOutput) {
|
||||
if (!synced) break;
|
||||
|
||||
// print('synced: print stdout loop');
|
||||
append(line);
|
||||
log.info(line);
|
||||
}
|
||||
}
|
||||
|
||||
logStdout();
|
||||
|
||||
Future<void> checkSync() async {
|
||||
await for (final _null in refresh.pull(appHook.getNotification, 'syncedState')) {
|
||||
if (appHook.isExiting() || userExit) {
|
||||
log.fine('Synced state detected exiting');
|
||||
break;
|
||||
}
|
||||
|
||||
if (await daemon.isNotSynced()) {
|
||||
synced = false;
|
||||
break;
|
||||
}
|
||||
// log.finer('SyncedState: checkSync loop');
|
||||
height = await rpc.height();
|
||||
connected = await daemon.isConnected();
|
||||
getInfo = await rpc.getInfoSimple();
|
||||
final _getInfoView = cleanKey(rpcView.getInfoView(getInfo));
|
||||
getInfoCache = pretty(_getInfoView);
|
||||
|
||||
getConnections = await rpc.getConnectionsSimple();
|
||||
final List<Map<String, dynamic>> _getConnectionsView =
|
||||
getConnections
|
||||
.map(rpcView.getConnectionView)
|
||||
.map((x) => rpcView.simpleHeight(height, x))
|
||||
.map(cleanKey)
|
||||
.toList();
|
||||
getConnectionsCache = pretty(_getConnectionsView);
|
||||
|
||||
getTransactionPool = await rpc.getTransactionPoolSimple();
|
||||
final List<Map<String, dynamic>> _getTransactionPoolView =
|
||||
getTransactionPool.map(rpc2View.txView).map(cleanKey).toList();
|
||||
getTransactionPoolCache = pretty(_getTransactionPoolView);
|
||||
|
||||
syncState();
|
||||
}
|
||||
}
|
||||
|
||||
await checkSync();
|
||||
|
||||
if (appHook.isExiting() || userExit) {
|
||||
ExitingState _next = ExitingState
|
||||
(
|
||||
appHook, stdout, processOutput
|
||||
);
|
||||
return moveState(_next);
|
||||
}
|
||||
|
||||
log.fine('synced: loop exit');
|
||||
|
||||
ReSyncingState _next = ReSyncingState
|
||||
(
|
||||
appHook, stdout, processInput, processOutput, pageIndex
|
||||
);
|
||||
return moveState(_next);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 fuwa
|
||||
|
||||
This file is part of CyberWOW.
|
||||
|
||||
CyberWOW is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CyberWOW is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CyberWOW. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
|
||||
import '../controller/rpc/rpc.dart' as rpc;
|
||||
import '../controller/daemon.dart' as daemon;
|
||||
import '../controller/refresh.dart' as refresh;
|
||||
import '../config.dart' as config;
|
||||
import '../logging.dart';
|
||||
|
||||
import 'prototype.dart';
|
||||
import 'synced.dart';
|
||||
import 'exiting.dart';
|
||||
|
||||
|
||||
class SyncingState extends AppState {
|
||||
final Queue<String> stdout = Queue.from(['']);
|
||||
|
||||
bool synced = false;
|
||||
|
||||
SyncingState(appHook) : super (appHook);
|
||||
|
||||
void append(final String msg) {
|
||||
stdout.addLast(msg);
|
||||
while (stdout.length > config.stdoutLineBufferSize) {
|
||||
stdout.removeFirst();
|
||||
}
|
||||
syncState();
|
||||
}
|
||||
|
||||
Future<AppState> next
|
||||
(
|
||||
StreamSink<String> processInput, Stream<String> processOutput
|
||||
) async {
|
||||
log.fine("Syncing next");
|
||||
|
||||
Future<void> printStdout() async {
|
||||
await for (final line in processOutput) {
|
||||
if (synced) break;
|
||||
log.finest('syncing: print stdout loop');
|
||||
|
||||
append(line);
|
||||
log.info(line);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> checkSync() async {
|
||||
await for (final _null in refresh.pull(appHook.getNotification, 'syncingState')) {
|
||||
log.finer('SyncingState: checkSync loop');
|
||||
|
||||
if (appHook.isExiting()) {
|
||||
log.fine('Syncing state detected exiting');
|
||||
break;
|
||||
}
|
||||
|
||||
// here doc is wrong, targetHeight could match height when synced
|
||||
// potential bug, targetHeight could be smaller then height
|
||||
final _isConnected = await daemon.isConnected();
|
||||
final _isSynced = await daemon.isSynced();
|
||||
|
||||
if (_isConnected && _isSynced) {
|
||||
synced = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printStdout();
|
||||
await checkSync();
|
||||
|
||||
if (appHook.isExiting()) {
|
||||
ExitingState _next = ExitingState
|
||||
(
|
||||
appHook, stdout, processOutput
|
||||
);
|
||||
return moveState(_next);
|
||||
}
|
||||
|
||||
log.fine('syncing: loop exit');
|
||||
|
||||
// processInput.add('exit');
|
||||
|
||||
final _height = await rpc.height();
|
||||
SyncedState _next = SyncedState
|
||||
(
|
||||
appHook, stdout, processInput, processOutput, 1,
|
||||
);
|
||||
_next.height = _height;
|
||||
return moveState(_next);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 fuwa
|
||||
|
||||
This file is part of CyberWOW.
|
||||
|
||||
CyberWOW is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CyberWOW is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CyberWOW. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'state.dart';
|
||||
import 'widget/blank.dart' as blank;
|
||||
import 'widget/loading.dart' as loading;
|
||||
import 'widget/syncing.dart' as syncing;
|
||||
import 'widget/synced.dart' as synced;
|
||||
import 'widget/resyncing.dart' as resyncing;
|
||||
import 'widget/exiting.dart' as exiting;
|
||||
|
||||
Widget build(final BuildContext context, final AppState state) {
|
||||
switch (state.runtimeType) {
|
||||
case BlankState: return blank.build(context, state);
|
||||
case LoadingState: return loading.build(context, state);
|
||||
case SyncingState: return syncing.build(context, state);
|
||||
case SyncedState: return synced.build(context, state);
|
||||
case ReSyncingState: return resyncing.build(context, state);
|
||||
case ExitingState: return exiting.build(context, state);
|
||||
default: Placeholder();
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import 'package:flutter/material.dart';
|
||||
import '../state.dart';
|
||||
import '../config.dart' as config;
|
||||
|
||||
Widget buildBlank(BuildContext context, BlankState state) {
|
||||
Widget build(BuildContext context, BlankState state) {
|
||||
return Scaffold(
|
||||
body: Container
|
||||
(
|
||||
|
||||
@@ -24,7 +24,7 @@ import 'package:flutter/material.dart';
|
||||
import '../state.dart';
|
||||
import '../config.dart' as config;
|
||||
|
||||
Widget buildExiting(BuildContext context, ExitingState state) {
|
||||
Widget build(BuildContext context, ExitingState state) {
|
||||
return Scaffold
|
||||
(
|
||||
// appBar: AppBar
|
||||
|
||||
@@ -24,7 +24,7 @@ import 'package:flutter/material.dart';
|
||||
import '../state.dart';
|
||||
import '../config.dart' as config;
|
||||
|
||||
Widget buildLoading(BuildContext context, LoadingState state) {
|
||||
Widget build(BuildContext context, LoadingState state) {
|
||||
return Scaffold(
|
||||
// appBar: AppBar(
|
||||
// // title: Text(widget.title),
|
||||
|
||||
@@ -24,7 +24,7 @@ import 'package:flutter/material.dart';
|
||||
import '../state.dart';
|
||||
import '../config.dart' as config;
|
||||
|
||||
Widget buildReSyncing(BuildContext context, ReSyncingState state) {
|
||||
Widget build(BuildContext context, ReSyncingState state) {
|
||||
return Scaffold
|
||||
(
|
||||
// appBar: AppBar
|
||||
|
||||
@@ -320,7 +320,7 @@ Widget pageView (BuildContext context, SyncedState state) {
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildSynced(BuildContext context, SyncedState state) {
|
||||
Widget build(BuildContext context, SyncedState state) {
|
||||
return Scaffold
|
||||
(
|
||||
body: pageView(context, state)
|
||||
|
||||
@@ -24,7 +24,7 @@ import 'package:flutter/material.dart';
|
||||
import '../state.dart';
|
||||
import '../config.dart' as config;
|
||||
|
||||
Widget buildSyncing(BuildContext context, SyncingState state) {
|
||||
Widget build(BuildContext context, SyncingState state) {
|
||||
return Scaffold
|
||||
(
|
||||
// appBar: AppBar
|
||||
|
||||
+54
-5
@@ -1,13 +1,27 @@
|
||||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.11"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.5.2"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
version: "2.4.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -29,6 +43,20 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.14.11"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
cupertino_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -60,6 +88,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
image:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -80,14 +115,14 @@ packages:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.5"
|
||||
version: "0.12.6"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.7"
|
||||
version: "1.1.8"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -109,6 +144,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0+1"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -169,7 +211,7 @@ packages:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.5"
|
||||
version: "0.2.11"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -184,6 +226,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.8"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.5.0"
|
||||
sdks:
|
||||
dart: ">=2.2.2 <3.0.0"
|
||||
dart: ">=2.4.0 <3.0.0"
|
||||
flutter: ">=0.1.4 <2.0.0"
|
||||
|
||||
+1
-2
@@ -82,7 +82,7 @@ with nixpkgs;
|
||||
; profile = ''
|
||||
export ANDROID_HOME=~/SDK/Android/Sdk
|
||||
|
||||
PATH=~/scm/flutter/vendor/flutter/bin:$PATH
|
||||
PATH=~/local/sdk/flutter/bin:$PATH
|
||||
PATH=~/SDK/Android/android-studio/bin:$PATH
|
||||
|
||||
export ANDROID_NDK_VERSION=r20
|
||||
@@ -96,7 +96,6 @@ with nixpkgs;
|
||||
export _JAVA_AWT_WM_NONREPARENTING=1
|
||||
export DART_VM_OPTIONS=--root-certs-file=/etc/ssl/certs/ca-certificates.crt
|
||||
|
||||
|
||||
export ANDROID_NDK_VERSION_WOW=r17c
|
||||
export ANDROID_NDK_ROOT_WOW=~/SDK/Android/ndk-archive/android-ndk-$ANDROID_NDK_VERSION_WOW
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2019, The Wownero Project
|
||||
# Copyright (c) 2014-2019, The Monero Project
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification, are
|
||||
# permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other
|
||||
# materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software without specific
|
||||
# prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
set -e
|
||||
|
||||
version=v2.3.0.0
|
||||
|
||||
curl -O -L https://github.com/fuwa0529/wownerujo/releases/download/${version}/external-libs.tgz
|
||||
|
||||
rm -rf external-libs
|
||||
|
||||
echo "unpacking external-libs"
|
||||
tar zxfv external-libs.tgz
|
||||
rm external-libs.tgz
|
||||
@@ -1 +0,0 @@
|
||||
curl -X POST http://nas:34568/json_rpc -d '{"jsonrpc":"2.0","id":"0","method":"get_connections"}'
|
||||
Reference in New Issue
Block a user