node: handle statuses, added base ui
This commit is contained in:
parent
b24a204d59
commit
ba5cd82f4b
19 changed files with 751 additions and 454 deletions
282
Cargo.lock
generated
282
Cargo.lock
generated
|
@ -320,12 +320,6 @@ version = "0.12.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
|
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "base64"
|
|
||||||
version = "0.13.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64ct"
|
name = "base64ct"
|
||||||
version = "1.6.0"
|
version = "1.6.0"
|
||||||
|
@ -678,12 +672,6 @@ dependencies = [
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "color_quant"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "combine"
|
name = "combine"
|
||||||
version = "4.6.6"
|
version = "4.6.6"
|
||||||
|
@ -946,15 +934,6 @@ dependencies = [
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "data-url"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3a30bfce702bcfa94e906ef82421f2c0e61c076ad76030c16ee5d2e9a32fe193"
|
|
||||||
dependencies = [
|
|
||||||
"matches",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
@ -1151,10 +1130,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1975cd88ff7430f93b29e6b9868b648a8ff6a43b08b9ff8474ee0a648bd8f9a6"
|
checksum = "1975cd88ff7430f93b29e6b9868b648a8ff6a43b08b9ff8474ee0a648bd8f9a6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"egui",
|
"egui",
|
||||||
"resvg",
|
|
||||||
"serde",
|
"serde",
|
||||||
"tiny-skia 0.6.6",
|
|
||||||
"usvg",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1371,39 +1347,12 @@ dependencies = [
|
||||||
"miniz_oxide 0.6.2",
|
"miniz_oxide 0.6.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "float-cmp"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fontconfig-parser"
|
|
||||||
version = "0.5.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4ab2e12762761366dcb876ab8b6e0cfa4797ddcd890575919f008b5ba655672a"
|
|
||||||
dependencies = [
|
|
||||||
"roxmltree 0.18.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fontdb"
|
|
||||||
version = "0.9.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d52186a39c335aa6f79fc0bf1c3cf854870b6ad4e50a7bb8a59b4ba1331f478a"
|
|
||||||
dependencies = [
|
|
||||||
"fontconfig-parser",
|
|
||||||
"log",
|
|
||||||
"memmap2",
|
|
||||||
"ttf-parser 0.17.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foreign-types"
|
name = "foreign-types"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
|
@ -1650,16 +1599,6 @@ dependencies = [
|
||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gif"
|
|
||||||
version = "0.11.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06"
|
|
||||||
dependencies = [
|
|
||||||
"color_quant",
|
|
||||||
"weezl",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gimli"
|
name = "gimli"
|
||||||
version = "0.27.2"
|
version = "0.27.2"
|
||||||
|
@ -1818,12 +1757,15 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android_logger",
|
"android_logger",
|
||||||
"built",
|
"built",
|
||||||
|
"chrono",
|
||||||
|
"dirs 2.0.2",
|
||||||
"eframe",
|
"eframe",
|
||||||
"egui",
|
"egui",
|
||||||
"egui_demo_lib",
|
"egui_demo_lib",
|
||||||
"egui_extras",
|
"egui_extras",
|
||||||
"env_logger 0.10.0",
|
"env_logger 0.10.0",
|
||||||
"futures 0.3.28",
|
"futures 0.3.28",
|
||||||
|
"grin_chain",
|
||||||
"grin_config",
|
"grin_config",
|
||||||
"grin_core",
|
"grin_core",
|
||||||
"grin_servers",
|
"grin_servers",
|
||||||
|
@ -2441,12 +2383,6 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "jpeg-decoder"
|
|
||||||
version = "0.2.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9478aa10f73e7528198d75109c8be5cd7d15fb530238040148d5f9a22d4c5b3b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.61"
|
version = "0.3.61"
|
||||||
|
@ -2678,12 +2614,6 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "matches"
|
|
||||||
version = "0.1.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
|
@ -3201,7 +3131,7 @@ version = "0.18.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e25e9fb15717794fae58ab55c26e044103aad13186fbb625893f9a3bbcc24228"
|
checksum = "e25e9fb15717794fae58ab55c26e044103aad13186fbb625893f9a3bbcc24228"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ttf-parser 0.18.1",
|
"ttf-parser",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3293,12 +3223,6 @@ version = "2.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pico-args"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.0.12"
|
version = "1.0.12"
|
||||||
|
@ -3572,12 +3496,6 @@ version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
|
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rctree"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9ae028b272a6e99d9f8260ceefa3caa09300a8d6c8d2b2001316474bc52122e9"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rdrand"
|
name = "rdrand"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -3645,33 +3563,6 @@ version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157"
|
checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "resvg"
|
|
||||||
version = "0.23.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "34489194784b86c03c3d688258e2ba73f3c82700ba4673ee2ecad5ae540b9438"
|
|
||||||
dependencies = [
|
|
||||||
"gif",
|
|
||||||
"jpeg-decoder",
|
|
||||||
"log",
|
|
||||||
"pico-args",
|
|
||||||
"png",
|
|
||||||
"rgb",
|
|
||||||
"svgfilters",
|
|
||||||
"svgtypes",
|
|
||||||
"tiny-skia 0.6.6",
|
|
||||||
"usvg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rgb"
|
|
||||||
version = "0.8.36"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "20ec2d3e3fc7a92ced357df9cebd5a10b6fb2aa1ee797bf7e9ce2f17dffc8f59"
|
|
||||||
dependencies = [
|
|
||||||
"bytemuck",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.16.20"
|
version = "0.16.20"
|
||||||
|
@ -3698,24 +3589,6 @@ dependencies = [
|
||||||
"opaque-debug",
|
"opaque-debug",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "roxmltree"
|
|
||||||
version = "0.14.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "921904a62e410e37e215c40381b7117f830d9d89ba60ab5236170541dd25646b"
|
|
||||||
dependencies = [
|
|
||||||
"xmlparser",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "roxmltree"
|
|
||||||
version = "0.18.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d8f595a457b6b8c6cda66a48503e92ee8d19342f905948f29c383200ec9eb1d8"
|
|
||||||
dependencies = [
|
|
||||||
"xmlparser",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-i18n"
|
name = "rust-i18n"
|
||||||
version = "1.1.4"
|
version = "1.1.4"
|
||||||
|
@ -3842,22 +3715,6 @@ dependencies = [
|
||||||
"security-framework",
|
"security-framework",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustybuzz"
|
|
||||||
version = "0.5.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a617c811f5c9a7060fe511d35d13bf5b9f0463ce36d63ce666d05779df2b4eba"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 1.3.2",
|
|
||||||
"bytemuck",
|
|
||||||
"smallvec",
|
|
||||||
"ttf-parser 0.15.2",
|
|
||||||
"unicode-bidi-mirroring",
|
|
||||||
"unicode-ccc",
|
|
||||||
"unicode-general-category",
|
|
||||||
"unicode-script",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.13"
|
version = "1.0.13"
|
||||||
|
@ -3928,7 +3785,7 @@ dependencies = [
|
||||||
"crossfont",
|
"crossfont",
|
||||||
"log",
|
"log",
|
||||||
"smithay-client-toolkit",
|
"smithay-client-toolkit",
|
||||||
"tiny-skia 0.7.0",
|
"tiny-skia",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -4071,15 +3928,6 @@ version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f"
|
checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "simplecss"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a11be7c62927d9427e9f40f3444d5499d868648e2edbc4e2116de69e7ec0e89d"
|
|
||||||
dependencies = [
|
|
||||||
"log",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "siphasher"
|
name = "siphasher"
|
||||||
version = "0.3.10"
|
version = "0.3.10"
|
||||||
|
@ -4196,25 +4044,6 @@ version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "171758edb47aa306a78dfa4ab9aeb5167405bd4e3dc2b64e88f6a84bbe98bd63"
|
checksum = "171758edb47aa306a78dfa4ab9aeb5167405bd4e3dc2b64e88f6a84bbe98bd63"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "svgfilters"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "639abcebc15fdc2df179f37d6f5463d660c1c79cd552c12343a4600827a04bce"
|
|
||||||
dependencies = [
|
|
||||||
"float-cmp",
|
|
||||||
"rgb",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "svgtypes"
|
|
||||||
version = "0.8.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "22975e8a2bac6a76bb54f898a6b18764633b00e780330f0b689f65afb3975564"
|
|
||||||
dependencies = [
|
|
||||||
"siphasher",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "0.15.44"
|
version = "0.15.44"
|
||||||
|
@ -4353,20 +4182,6 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tiny-skia"
|
|
||||||
version = "0.6.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d049bfef0eaa2521e75d9ffb5ce86ad54480932ae19b85f78bec6f52c4d30d78"
|
|
||||||
dependencies = [
|
|
||||||
"arrayref",
|
|
||||||
"arrayvec 0.5.2",
|
|
||||||
"bytemuck",
|
|
||||||
"cfg-if 1.0.0",
|
|
||||||
"png",
|
|
||||||
"safe_arch",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiny-skia"
|
name = "tiny-skia"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
|
@ -4567,18 +4382,6 @@ version = "0.2.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
|
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ttf-parser"
|
|
||||||
version = "0.15.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ttf-parser"
|
|
||||||
version = "0.17.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "375812fa44dab6df41c195cd2f7fecb488f6c09fbaafb62807488cefab642bff"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ttf-parser"
|
name = "ttf-parser"
|
||||||
version = "0.18.1"
|
version = "0.18.1"
|
||||||
|
@ -4615,24 +4418,6 @@ version = "0.3.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-bidi-mirroring"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "56d12260fb92d52f9008be7e4bca09f584780eb2266dc8fecc6a192bec561694"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-ccc"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cc2520efa644f8268dce4dcd3050eaa7fc044fca03961e9998ac7e2e92b77cf1"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-general-category"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "07547e3ee45e28326cc23faac56d44f58f16ab23e413db526debce3b0bfd2742"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.8"
|
version = "1.0.8"
|
||||||
|
@ -4648,24 +4433,12 @@ dependencies = [
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-script"
|
|
||||||
version = "0.5.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7d817255e1bed6dfd4ca47258685d14d2bdcfbc64fdc9e3819bd5848057b8ecc"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.10.1"
|
version = "1.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-vo"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.1.10"
|
version = "0.1.10"
|
||||||
|
@ -4716,33 +4489,6 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "usvg"
|
|
||||||
version = "0.23.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "28a82565b5c96dcbb58c9bdbb6aa3642abd395a6a6b480658532c6f74c3c4b7a"
|
|
||||||
dependencies = [
|
|
||||||
"base64 0.13.1",
|
|
||||||
"data-url",
|
|
||||||
"flate2",
|
|
||||||
"float-cmp",
|
|
||||||
"fontdb",
|
|
||||||
"kurbo",
|
|
||||||
"log",
|
|
||||||
"pico-args",
|
|
||||||
"rctree",
|
|
||||||
"roxmltree 0.14.1",
|
|
||||||
"rustybuzz",
|
|
||||||
"simplecss",
|
|
||||||
"siphasher",
|
|
||||||
"svgtypes",
|
|
||||||
"ttf-parser 0.15.2",
|
|
||||||
"unicode-bidi",
|
|
||||||
"unicode-script",
|
|
||||||
"unicode-vo",
|
|
||||||
"xmlwriter",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcpkg"
|
name = "vcpkg"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
@ -4981,12 +4727,6 @@ dependencies = [
|
||||||
"untrusted",
|
"untrusted",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "weezl"
|
|
||||||
version = "0.1.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu"
|
name = "wgpu"
|
||||||
version = "0.14.2"
|
version = "0.14.2"
|
||||||
|
@ -5476,18 +5216,6 @@ version = "0.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
|
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "xmlparser"
|
|
||||||
version = "0.13.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4d25c75bf9ea12c4040a97f829154768bbbce366287e2dc044af160cd79a13fd"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "xmlwriter"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yaml-rust"
|
name = "yaml-rust"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
|
|
|
@ -14,7 +14,7 @@ build = "src/build/build.rs"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
#android-activity = { version = "0.4", features = ["game-activity"] }
|
#android-activity = { version = "0.4", features = ["game-activity"] }
|
||||||
#grin_api = "5.1.2"
|
#grin_api = "5.1.2"
|
||||||
#grin_chain = "5.1.2"
|
grin_chain = "5.1.2"
|
||||||
grin_config = "5.1.2"
|
grin_config = "5.1.2"
|
||||||
grin_core = "5.1.2"
|
grin_core = "5.1.2"
|
||||||
#grin_keychain = "5.1.2"
|
#grin_keychain = "5.1.2"
|
||||||
|
@ -33,17 +33,19 @@ openssl-sys = { version = "0.9.82", features = ["vendored"] }
|
||||||
pollster = "0.3.0"
|
pollster = "0.3.0"
|
||||||
wgpu = "0.14.0"
|
wgpu = "0.14.0"
|
||||||
egui = "0.20.1"
|
egui = "0.20.1"
|
||||||
egui_extras = { version = "0.20.0", features = [ "svg" ] }
|
egui_extras = { version = "0.20.0" }
|
||||||
eframe = { version = "0.20.1", features = [ "wgpu" ] }
|
eframe = { version = "0.20.1", features = [ "wgpu" ] }
|
||||||
egui_demo_lib = "0.20.0"
|
egui_demo_lib = "0.20.0"
|
||||||
|
|
||||||
## grin_servers
|
## grin_servers
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
|
dirs = "2.0"
|
||||||
|
|
||||||
## other
|
## other
|
||||||
once_cell = "1.10.0"
|
once_cell = "1.10.0"
|
||||||
rust-i18n = "1.1.4"
|
rust-i18n = "1.1.4"
|
||||||
sys-locale = "0.3.0"
|
sys-locale = "0.3.0"
|
||||||
|
chrono = "0.4.11"
|
||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
winit = { git = "https://github.com/rib/winit", branch = "android-activity" }
|
winit = { git = "https://github.com/rib/winit", branch = "android-activity" }
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
accounts: Accounts
|
accounts: Accounts
|
||||||
|
node: Node
|
||||||
|
metrics: Metrics
|
||||||
|
settings: Settings
|
|
@ -56,3 +56,11 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_dual_panel_mode(frame: &mut Frame) -> bool {
|
||||||
|
is_landscape(frame) && frame.info().window_info.size.x > 400.0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_landscape(frame: &mut Frame) -> bool {
|
||||||
|
return frame.info().window_info.size.x > frame.info().window_info.size.y
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,10 @@ pub const COLOR_LIGHT: egui::Color32 = egui::Color32::from_gray(240);
|
||||||
pub const COLOR_DARK: egui::Color32 = egui::Color32::from_gray(60);
|
pub const COLOR_DARK: egui::Color32 = egui::Color32::from_gray(60);
|
||||||
|
|
||||||
// Material icons chars
|
// Material icons chars
|
||||||
pub const SYM_ARROW_BACK: &str = "";//"";
|
pub const SYM_ARROW_BACK: &str = "";
|
||||||
pub const SYM_ADD: &str = "+";
|
|
||||||
pub const SYM_ACCOUNTS: &str = "";
|
pub const SYM_ACCOUNTS: &str = "";
|
||||||
pub const SYM_NETWORK: &str = "";
|
pub const SYM_NETWORK: &str = "";
|
||||||
pub const SYM_SETTINGS: &str = "";//"";
|
pub const SYM_SETTINGS: &str = "";
|
||||||
|
pub const SYM_TUNING: &str = "";
|
||||||
|
pub const SYM_METRICS: &str = "";
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use egui::Context;
|
use eframe::epaint::Stroke;
|
||||||
use winit::platform::android::activity::AndroidApp;
|
use winit::platform::android::activity::AndroidApp;
|
||||||
|
|
||||||
use crate::gui::{App, PlatformApp};
|
use crate::gui::{App, PlatformApp};
|
||||||
|
@ -85,7 +85,10 @@ impl PlatformApp<Android> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_visuals(ctx: &egui::Context) {
|
fn setup_visuals(ctx: &egui::Context) {
|
||||||
ctx.set_visuals(egui::Visuals::light());
|
let mut visuals = egui::Visuals::light();
|
||||||
|
// Disable stroke around panels by default
|
||||||
|
visuals.widgets.noninteractive.bg_stroke = Stroke::NONE;
|
||||||
|
ctx.set_visuals(visuals);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_fonts(ctx: &egui::Context) {
|
fn setup_fonts(ctx: &egui::Context) {
|
||||||
|
@ -106,16 +109,6 @@ impl PlatformApp<Android> {
|
||||||
// },
|
// },
|
||||||
// });
|
// });
|
||||||
|
|
||||||
// fonts.font_data.insert(
|
|
||||||
// "material".to_owned(),
|
|
||||||
// egui::FontData::from_static(include_bytes!(
|
|
||||||
// "../../../../fonts/material-light.ttf"
|
|
||||||
// )).tweak(egui::FontTweak {
|
|
||||||
// scale: 1.0,
|
|
||||||
// y_offset_factor: 0.06,
|
|
||||||
// y_offset: 0.0
|
|
||||||
// }),
|
|
||||||
// );
|
|
||||||
fonts.font_data.insert(
|
fonts.font_data.insert(
|
||||||
"material".to_owned(),
|
"material".to_owned(),
|
||||||
egui::FontData::from_static(include_bytes!(
|
egui::FontData::from_static(include_bytes!(
|
||||||
|
@ -160,7 +153,7 @@ impl PlatformApp<Android> {
|
||||||
(Heading, FontId::new(20.0, Proportional)),
|
(Heading, FontId::new(20.0, Proportional)),
|
||||||
(Name("icon".into()), FontId::new(24.0, Proportional)),
|
(Name("icon".into()), FontId::new(24.0, Proportional)),
|
||||||
(Body, FontId::new(16.0, Proportional)),
|
(Body, FontId::new(16.0, Proportional)),
|
||||||
(Button, FontId::new(20.0, Proportional)),
|
(Button, FontId::new(18.0, Proportional)),
|
||||||
(Small, FontId::new(12.0, Proportional)),
|
(Small, FontId::new(12.0, Proportional)),
|
||||||
(Monospace, FontId::new(16.0, Proportional)),
|
(Monospace, FontId::new(16.0, Proportional)),
|
||||||
].into();
|
].into();
|
||||||
|
|
|
@ -32,7 +32,7 @@ impl super::Screen for Account {
|
||||||
ScreenId::Account
|
ScreenId::Account
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show(&mut self,
|
fn ui(&mut self,
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
frame: &mut eframe::Frame,
|
frame: &mut eframe::Frame,
|
||||||
nav: &mut Navigator,
|
nav: &mut Navigator,
|
||||||
|
|
|
@ -13,13 +13,15 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use egui::Widget;
|
use eframe::epaint::{Color32, Stroke};
|
||||||
|
|
||||||
|
use egui::{Frame, Widget};
|
||||||
|
|
||||||
|
use crate::gui::{SYM_ARROW_BACK, SYM_NETWORK, SYM_SETTINGS};
|
||||||
|
use crate::gui::app::is_dual_panel_mode;
|
||||||
use crate::gui::platform::PlatformCallbacks;
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
use crate::gui::screens::{Navigator, Screen, ScreenId};
|
use crate::gui::screens::{Navigator, Screen, ScreenId};
|
||||||
use crate::gui::{SYM_ACCOUNTS, SYM_ARROW_BACK, SYM_NETWORK, SYM_SETTINGS};
|
use crate::gui::views::{TitlePanel, TitlePanelAction};
|
||||||
use crate::gui::screens::root::dual_panel_mode;
|
|
||||||
use crate::gui::views::title_panel::{PanelAction, TitlePanel};
|
|
||||||
use crate::gui::views::View;
|
|
||||||
|
|
||||||
pub struct Accounts {
|
pub struct Accounts {
|
||||||
title: String,
|
title: String,
|
||||||
|
@ -38,7 +40,7 @@ impl Screen for Accounts {
|
||||||
ScreenId::Accounts
|
ScreenId::Accounts
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show(&mut self,
|
fn ui(&mut self,
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
frame: &mut eframe::Frame,
|
frame: &mut eframe::Frame,
|
||||||
nav: &mut Navigator,
|
nav: &mut Navigator,
|
||||||
|
@ -47,19 +49,27 @@ impl Screen for Accounts {
|
||||||
|
|
||||||
let mut panel: TitlePanel = TitlePanel::default()
|
let mut panel: TitlePanel = TitlePanel::default()
|
||||||
.title(title)
|
.title(title)
|
||||||
.right_action(PanelAction {
|
.right_action(TitlePanelAction {
|
||||||
icon: SYM_SETTINGS.into(),
|
icon: SYM_SETTINGS.into(),
|
||||||
on_click: Box::new(on_settings_click),
|
on_click: Box::new(|nav| {
|
||||||
|
//TODO: open settings
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
.with_navigator(nav);
|
.with_navigator(nav);
|
||||||
if !dual_panel_mode(frame) {
|
if !is_dual_panel_mode(frame) {
|
||||||
panel = panel.left_action(PanelAction {
|
panel = panel.left_action(TitlePanelAction {
|
||||||
icon: SYM_NETWORK.into(),
|
icon: SYM_NETWORK.into(),
|
||||||
on_click: Box::new(on_network_click),
|
on_click: Box::new(|nav|{
|
||||||
|
nav.as_mut().unwrap().toggle_left_panel();
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
panel.ui(ui);
|
panel.ui(ui);
|
||||||
|
|
||||||
|
egui::CentralPanel::default().frame(Frame {
|
||||||
|
stroke: Stroke::new(1.0, Color32::from_gray(190)),
|
||||||
|
.. Default::default()
|
||||||
|
}).show_inside(ui, |ui| {
|
||||||
ui.label(format!("{}Here we go 10000 ツ", SYM_ARROW_BACK));
|
ui.label(format!("{}Here we go 10000 ツ", SYM_ARROW_BACK));
|
||||||
if ui.button("TEST").clicked() {
|
if ui.button("TEST").clicked() {
|
||||||
nav.to(ScreenId::Account)
|
nav.to(ScreenId::Account)
|
||||||
|
@ -67,13 +77,6 @@ impl Screen for Accounts {
|
||||||
if ui.button(format!("{}BACK ", SYM_ARROW_BACK)).clicked() {
|
if ui.button(format!("{}BACK ", SYM_ARROW_BACK)).clicked() {
|
||||||
nav.to(ScreenId::Account)
|
nav.to(ScreenId::Account)
|
||||||
};
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_network_click(nav: &mut Option<&mut Navigator>) {
|
|
||||||
nav.as_mut().unwrap().toggle_left_panel();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_settings_click(nav: &mut Option<&mut Navigator>) {
|
|
||||||
//TODO: Open settings
|
|
||||||
}
|
|
|
@ -12,14 +12,14 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
pub use account::Account;
|
||||||
|
pub use accounts::Accounts;
|
||||||
pub use navigator::Navigator;
|
pub use navigator::Navigator;
|
||||||
pub use root::Root;
|
pub use root::Root;
|
||||||
pub use accounts::Accounts;
|
|
||||||
pub use account::Account;
|
|
||||||
|
|
||||||
use crate::gui::App;
|
use crate::gui::App;
|
||||||
use crate::gui::platform::PlatformCallbacks;
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
use crate::gui::views::title_panel::PanelAction;
|
use crate::gui::views::TitlePanelAction;
|
||||||
|
|
||||||
mod navigator;
|
mod navigator;
|
||||||
mod root;
|
mod root;
|
||||||
|
@ -30,12 +30,12 @@ mod account;
|
||||||
pub enum ScreenId {
|
pub enum ScreenId {
|
||||||
Root,
|
Root,
|
||||||
Accounts,
|
Accounts,
|
||||||
Account
|
Account,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Screen {
|
pub trait Screen {
|
||||||
fn id(&self) -> ScreenId;
|
fn id(&self) -> ScreenId;
|
||||||
fn show(&mut self,
|
fn ui(&mut self,
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
frame: &mut eframe::Frame,
|
frame: &mut eframe::Frame,
|
||||||
navigator: &mut Navigator,
|
navigator: &mut Navigator,
|
||||||
|
|
|
@ -17,7 +17,7 @@ use std::collections::BTreeSet;
|
||||||
use crate::gui::screens::ScreenId;
|
use crate::gui::screens::ScreenId;
|
||||||
|
|
||||||
pub struct Navigator {
|
pub struct Navigator {
|
||||||
pub(crate) stack: BTreeSet<ScreenId>,
|
stack: BTreeSet<ScreenId>,
|
||||||
pub(crate) left_panel_open: bool,
|
pub(crate) left_panel_open: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,10 @@ impl Default for Navigator {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Navigator {
|
impl Navigator {
|
||||||
|
pub fn current(&mut self) -> &ScreenId {
|
||||||
|
self.stack.last().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to(&mut self, id: ScreenId) {
|
pub fn to(&mut self, id: ScreenId) {
|
||||||
self.stack.insert(id);
|
self.stack.insert(id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,17 +13,20 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use eframe::epaint::{Shadow, Stroke};
|
|
||||||
use eframe::Frame;
|
use eframe::epaint::{Color32, Shadow, Stroke};
|
||||||
use egui::style::Margin;
|
use egui::style::Margin;
|
||||||
use egui::Ui;
|
|
||||||
use crate::gui::{App, COLOR_YELLOW};
|
use crate::gui::{App, COLOR_YELLOW};
|
||||||
|
use crate::gui::app::is_dual_panel_mode;
|
||||||
use crate::gui::platform::PlatformCallbacks;
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
use crate::gui::screens::{Account, Accounts, Navigator, Screen, ScreenId};
|
use crate::gui::screens::{Account, Accounts, Navigator, Screen, ScreenId};
|
||||||
|
use crate::gui::views::Network;
|
||||||
|
|
||||||
pub struct Root {
|
pub struct Root {
|
||||||
navigator: Navigator,
|
navigator: Navigator,
|
||||||
screens: Vec<Box<dyn Screen>>,
|
screens: Vec<Box<dyn Screen>>,
|
||||||
|
network: Network
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Root {
|
impl Default for Root {
|
||||||
|
@ -34,6 +37,7 @@ impl Default for Root {
|
||||||
Box::new(Accounts::default()),
|
Box::new(Accounts::default()),
|
||||||
Box::new(Account::default())
|
Box::new(Account::default())
|
||||||
]),
|
]),
|
||||||
|
network: Network::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,32 +47,24 @@ impl Root {
|
||||||
ScreenId::Root
|
ScreenId::Root
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ui(&mut self, ui: &mut Ui, frame: &mut Frame, cb: &dyn PlatformCallbacks) {
|
pub fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, cb: &dyn PlatformCallbacks) {
|
||||||
let is_network_panel_open = self.navigator.left_panel_open || dual_panel_mode(frame);
|
let is_network_panel_open = self.navigator.left_panel_open || is_dual_panel_mode(frame);
|
||||||
|
|
||||||
egui::SidePanel::left("network_panel")
|
egui::SidePanel::left("network_panel")
|
||||||
.resizable(false)
|
.resizable(false)
|
||||||
.exact_width(if dual_panel_mode(frame) {
|
.exact_width(if is_dual_panel_mode(frame) {
|
||||||
min(frame.info().window_info.size.x as i64, 400) as f32
|
min(frame.info().window_info.size.x as i64, 400) as f32
|
||||||
} else {
|
} else {
|
||||||
frame.info().window_info.size.x
|
frame.info().window_info.size.x
|
||||||
})
|
})
|
||||||
.frame(egui::Frame {
|
.frame(egui::Frame {
|
||||||
inner_margin: Margin::same(0.0),
|
|
||||||
outer_margin: Margin::same(0.0),
|
|
||||||
fill: COLOR_YELLOW,
|
|
||||||
.. Default::default()
|
.. Default::default()
|
||||||
})
|
})
|
||||||
.show_animated_inside(ui, is_network_panel_open, |ui| {
|
.show_animated_inside(ui, is_network_panel_open, |ui| {
|
||||||
//TODO: Network content
|
self.network.ui(ui, frame, &mut self.navigator, cb);
|
||||||
ui.vertical_centered(|ui| {
|
|
||||||
ui.heading("🖧 Node");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.separator();
|
egui::CentralPanel::default().frame(egui::Frame {
|
||||||
});
|
|
||||||
|
|
||||||
egui::CentralPanel::default().frame(egui::containers::Frame {
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}).show_inside(ui, |ui| {
|
}).show_inside(ui, |ui| {
|
||||||
self.show_current_screen(ui, frame, cb);
|
self.show_current_screen(ui, frame, cb);
|
||||||
|
@ -76,22 +72,17 @@ impl Root {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show_current_screen(&mut self, ui: &mut Ui, frame: &mut Frame, cb: &dyn PlatformCallbacks) {
|
pub fn show_current_screen(&mut self,
|
||||||
|
ui: &mut egui::Ui,
|
||||||
|
frame: &mut eframe::Frame,
|
||||||
|
cb: &dyn PlatformCallbacks) {
|
||||||
let Self { navigator, screens, .. } = self;
|
let Self { navigator, screens, .. } = self;
|
||||||
let current = navigator.stack.last().unwrap();
|
let current = navigator.current();
|
||||||
for screen in screens.iter_mut() {
|
for screen in screens.iter_mut() {
|
||||||
if screen.id() == *current {
|
if screen.id() == *current {
|
||||||
screen.show(ui, frame, navigator, cb);
|
screen.ui(ui, frame, navigator, cb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dual_panel_mode(frame: &mut Frame) -> bool {
|
|
||||||
is_landscape(frame) && frame.info().window_info.size.x > 400.0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_landscape(frame: &mut Frame) -> bool {
|
|
||||||
return frame.info().window_info.size.x > frame.info().window_info.size.y
|
|
||||||
}
|
|
|
@ -13,8 +13,18 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
pub mod buttons;
|
pub mod buttons;
|
||||||
pub mod title_panel;
|
|
||||||
|
|
||||||
pub trait View {
|
mod title_panel;
|
||||||
fn ui(&mut self, ui: &mut egui::Ui);
|
pub use crate::gui::views::title_panel::{TitlePanel, TitlePanelAction, TitlePanelActions};
|
||||||
|
|
||||||
|
mod network;
|
||||||
|
pub use crate::gui::views::network::Network;
|
||||||
|
|
||||||
|
mod network_node;
|
||||||
|
mod network_tuning;
|
||||||
|
mod network_metrics;
|
||||||
|
|
||||||
|
pub trait NetworkTab {
|
||||||
|
fn ui(&mut self, ui: &mut egui::Ui, node: &mut crate::node::Node);
|
||||||
|
fn title(&self) -> &String;
|
||||||
}
|
}
|
288
src/gui/views/network.rs
Normal file
288
src/gui/views/network.rs
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
// Copyright 2023 The Grim Developers
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
|
use std::collections::hash_map::DefaultHasher;
|
||||||
|
use std::time::Duration;
|
||||||
|
use eframe::epaint::{Color32, FontId, Stroke};
|
||||||
|
use eframe::epaint::text::{LayoutJob, TextFormat, TextWrapping};
|
||||||
|
use egui::{Response, RichText, Sense, Spinner, Widget};
|
||||||
|
use egui::style::Margin;
|
||||||
|
use egui_extras::{Size, StripBuilder};
|
||||||
|
use grin_chain::SyncStatus;
|
||||||
|
|
||||||
|
use grin_core::global::ChainTypes;
|
||||||
|
use grin_servers::ServerStats;
|
||||||
|
use crate::gui::app::is_dual_panel_mode;
|
||||||
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
|
use crate::gui::screens::Navigator;
|
||||||
|
use crate::gui::{COLOR_DARK, COLOR_LIGHT, COLOR_YELLOW, SYM_ACCOUNTS, SYM_METRICS, SYM_NETWORK};
|
||||||
|
|
||||||
|
use crate::gui::views::{NetworkTab, TitlePanel, TitlePanelAction};
|
||||||
|
use crate::gui::views::network_node::NetworkNode;
|
||||||
|
use crate::node;
|
||||||
|
use crate::node::Node;
|
||||||
|
|
||||||
|
enum Mode {
|
||||||
|
Node,
|
||||||
|
// Miner,
|
||||||
|
Metrics,
|
||||||
|
Tuning
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Network {
|
||||||
|
current_mode: Mode,
|
||||||
|
node: Node,
|
||||||
|
node_view: NetworkNode,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Network {
|
||||||
|
fn default() -> Self {
|
||||||
|
let node = Node::new(ChainTypes::Mainnet, true);
|
||||||
|
Self {
|
||||||
|
node,
|
||||||
|
current_mode: Mode::Node,
|
||||||
|
node_view: NetworkNode::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Network {
|
||||||
|
pub fn ui(&mut self,
|
||||||
|
ui: &mut egui::Ui,
|
||||||
|
frame: &mut eframe::Frame,
|
||||||
|
nav: &mut Navigator,
|
||||||
|
cb: &dyn PlatformCallbacks) {
|
||||||
|
|
||||||
|
egui::TopBottomPanel::top("network_title")
|
||||||
|
.resizable(false)
|
||||||
|
.frame(egui::Frame {
|
||||||
|
fill: COLOR_YELLOW,
|
||||||
|
inner_margin: Margin::same(0.0),
|
||||||
|
outer_margin: Margin::same(0.0),
|
||||||
|
stroke: Stroke::NONE,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.show_inside(ui, |ui| {
|
||||||
|
self.draw_title(ui, frame, nav);
|
||||||
|
});
|
||||||
|
|
||||||
|
egui::CentralPanel::default().frame(egui::Frame {
|
||||||
|
stroke: Stroke::new(1.0, Color32::from_gray(190)),
|
||||||
|
fill: Color32::WHITE,
|
||||||
|
.. Default::default()
|
||||||
|
}).show_inside(ui, |ui| {
|
||||||
|
self.draw_tab_content(ui);
|
||||||
|
});
|
||||||
|
|
||||||
|
egui::TopBottomPanel::bottom("network_tabs")
|
||||||
|
.frame(egui::Frame {
|
||||||
|
stroke: Stroke::new(1.0, Color32::from_gray(190)),
|
||||||
|
.. Default::default()
|
||||||
|
})
|
||||||
|
.resizable(false)
|
||||||
|
.show_inside(ui, |ui| {
|
||||||
|
self.draw_tabs(ui);
|
||||||
|
});
|
||||||
|
|
||||||
|
ui.ctx().request_repaint_after(Duration::from_millis(500));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_tabs(&self, ui: &mut egui::Ui) {
|
||||||
|
ui.vertical_centered(|ui| {
|
||||||
|
ui.columns(3, |columns| {
|
||||||
|
columns[0].horizontal_wrapped(|ui| {
|
||||||
|
});
|
||||||
|
columns[1].vertical_centered(|ui| {
|
||||||
|
});
|
||||||
|
columns[2].horizontal_wrapped(|ui| {
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_tab_content(&mut self, ui: &mut egui::Ui) {
|
||||||
|
match self.current_mode {
|
||||||
|
Mode::Node => {
|
||||||
|
self.node_view.ui(ui, &mut self.node);
|
||||||
|
}
|
||||||
|
Mode::Metrics => {}
|
||||||
|
Mode::Tuning => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_title(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame, nav: &mut Navigator) {
|
||||||
|
// Disable stroke around title buttons on hover
|
||||||
|
ui.style_mut().visuals.widgets.active.bg_stroke = Stroke::NONE;
|
||||||
|
|
||||||
|
StripBuilder::new(ui)
|
||||||
|
.size(Size::exact(52.0))
|
||||||
|
.vertical(|mut strip| {
|
||||||
|
strip.strip(|builder| {
|
||||||
|
builder
|
||||||
|
.size(Size::exact(52.0))
|
||||||
|
.size(Size::remainder())
|
||||||
|
.size(Size::exact(52.0))
|
||||||
|
.horizontal(|mut strip| {
|
||||||
|
strip.empty();
|
||||||
|
strip.strip(|builder| {
|
||||||
|
self.draw_title_text(builder);
|
||||||
|
});
|
||||||
|
strip.cell(|ui| {
|
||||||
|
if !is_dual_panel_mode(frame) {
|
||||||
|
ui.centered_and_justified(|ui| {
|
||||||
|
let b = egui::widgets::Button::new(
|
||||||
|
RichText::new(SYM_ACCOUNTS)
|
||||||
|
.size(24.0)
|
||||||
|
.color(COLOR_DARK)
|
||||||
|
).fill(Color32::TRANSPARENT)
|
||||||
|
.ui(ui).interact(Sense::click_and_drag());
|
||||||
|
if b.drag_released() || b.clicked() {
|
||||||
|
nav.toggle_left_panel();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_title_text(&self, mut builder: StripBuilder) {
|
||||||
|
let title_text = match &self.current_mode {
|
||||||
|
Mode::Node => {
|
||||||
|
self.node_view.title()
|
||||||
|
}
|
||||||
|
Mode::Metrics => {
|
||||||
|
self.node_view.title()
|
||||||
|
}
|
||||||
|
Mode::Tuning => {
|
||||||
|
self.node_view.title()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
let state = self.node.acquire_state();
|
||||||
|
let syncing = state.stats.is_some() &&
|
||||||
|
state.stats.as_ref().unwrap().sync_status != SyncStatus::NoSync;
|
||||||
|
|
||||||
|
let mut b = builder.size(Size::remainder());
|
||||||
|
if syncing {
|
||||||
|
b = b.size(Size::remainder());
|
||||||
|
}
|
||||||
|
b.vertical(|mut strip| {
|
||||||
|
strip.cell(|ui| {
|
||||||
|
ui.centered_and_justified(|ui| {
|
||||||
|
ui.heading(title_text.to_uppercase());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if syncing {
|
||||||
|
let stats = state.stats.as_ref().unwrap();
|
||||||
|
strip.cell(|ui| {
|
||||||
|
ui.centered_and_justified(|ui| {
|
||||||
|
let status_text = if state.is_stopping() {
|
||||||
|
get_sync_status(SyncStatus::Shutdown).to_string()
|
||||||
|
} else if state.is_restarting() {
|
||||||
|
"Restarting".to_string()
|
||||||
|
} else {
|
||||||
|
get_sync_status(stats.sync_status).to_string()
|
||||||
|
};
|
||||||
|
let mut job = LayoutJob::single_section(status_text, TextFormat {
|
||||||
|
font_id: FontId::proportional(15.0),
|
||||||
|
color: COLOR_DARK,
|
||||||
|
.. Default::default()
|
||||||
|
});
|
||||||
|
job.wrap = TextWrapping {
|
||||||
|
max_rows: 1,
|
||||||
|
break_anywhere: false,
|
||||||
|
overflow_character: Option::from('…'),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
ui.label(job);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_sync_status(sync_status: SyncStatus) -> Cow<'static, str> {
|
||||||
|
match sync_status {
|
||||||
|
SyncStatus::Initial => Cow::Borrowed("Initializing"),
|
||||||
|
SyncStatus::NoSync => Cow::Borrowed("Running"),
|
||||||
|
SyncStatus::AwaitingPeers(_) => Cow::Borrowed("Waiting for peers"),
|
||||||
|
SyncStatus::HeaderSync {
|
||||||
|
sync_head,
|
||||||
|
highest_height,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
if highest_height == 0 {
|
||||||
|
Cow::Borrowed("Downloading headers data")
|
||||||
|
} else {
|
||||||
|
let percent = sync_head.height * 100 / highest_height;
|
||||||
|
Cow::Owned(format!("Downloading headers: {}%", percent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SyncStatus::TxHashsetDownload(stat) => {
|
||||||
|
Cow::Borrowed("Downloading chain state")
|
||||||
|
}
|
||||||
|
SyncStatus::TxHashsetSetup => {
|
||||||
|
Cow::Borrowed("Preparing chain state for validation")
|
||||||
|
}
|
||||||
|
SyncStatus::TxHashsetRangeProofsValidation {
|
||||||
|
rproofs,
|
||||||
|
rproofs_total,
|
||||||
|
} => {
|
||||||
|
let r_percent = if rproofs_total > 0 {
|
||||||
|
(rproofs * 100) / rproofs_total
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
Cow::Owned(format!("Validating state - range proofs: {}%", r_percent))
|
||||||
|
}
|
||||||
|
SyncStatus::TxHashsetKernelsValidation {
|
||||||
|
kernels,
|
||||||
|
kernels_total,
|
||||||
|
} => {
|
||||||
|
let k_percent = if kernels_total > 0 {
|
||||||
|
(kernels * 100) / kernels_total
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
Cow::Owned(format!("Validating state - kernels: {}%", k_percent))
|
||||||
|
}
|
||||||
|
SyncStatus::TxHashsetSave => {
|
||||||
|
Cow::Borrowed("Finalizing chain state")
|
||||||
|
}
|
||||||
|
SyncStatus::TxHashsetDone => {
|
||||||
|
Cow::Borrowed("Finalized chain state")
|
||||||
|
}
|
||||||
|
SyncStatus::BodySync {
|
||||||
|
current_height,
|
||||||
|
highest_height,
|
||||||
|
} => {
|
||||||
|
if highest_height == 0 {
|
||||||
|
Cow::Borrowed("Downloading blocks data")
|
||||||
|
} else {
|
||||||
|
Cow::Owned(format!(
|
||||||
|
"Downloading blocks: {}%",
|
||||||
|
current_height * 100 / highest_height
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SyncStatus::Shutdown => Cow::Borrowed("Shutting down"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
13
src/gui/views/network_metrics.rs
Normal file
13
src/gui/views/network_metrics.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright 2023 The Grim Developers
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
76
src/gui/views/network_node.rs
Normal file
76
src/gui/views/network_node.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright 2023 The Grim Developers
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
|
use std::ptr::null;
|
||||||
|
use std::sync::mpsc;
|
||||||
|
|
||||||
|
use chrono::Utc;
|
||||||
|
use egui::{Ui, Widget};
|
||||||
|
use grin_chain::SyncStatus;
|
||||||
|
use grin_core::global::ChainTypes;
|
||||||
|
use grin_servers::ServerStats;
|
||||||
|
|
||||||
|
use crate::gui::views::NetworkTab;
|
||||||
|
use crate::node::Node;
|
||||||
|
|
||||||
|
|
||||||
|
pub struct NetworkNode {
|
||||||
|
title: String
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for NetworkNode {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
title: t!("node"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NetworkTab for NetworkNode {
|
||||||
|
fn ui(&mut self, ui: &mut Ui, node: &mut Node) {
|
||||||
|
// ui.vertical_centered_justified(|ui| {
|
||||||
|
// let node_state = node.acquire_state();
|
||||||
|
// let stats = &node_state.stats;
|
||||||
|
// if stats.is_some() {
|
||||||
|
// ui.horizontal_wrapped(|ui| {
|
||||||
|
// let sync_status = stats.as_ref().unwrap().sync_status;
|
||||||
|
// ui.label(get_sync_progress_status(sync_status));
|
||||||
|
// ui.spinner();
|
||||||
|
// });
|
||||||
|
// } else {
|
||||||
|
// if node.stop_state.is_stopped() {
|
||||||
|
// ui.label("Stopped");
|
||||||
|
// } else {
|
||||||
|
// ui.label(get_sync_progress_status(SyncStatus::Initial));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
if ui.button("stop").clicked() {
|
||||||
|
node.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ui.button("re-start").clicked() {
|
||||||
|
node.restart(ChainTypes::Mainnet);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ui.button("start").clicked() {
|
||||||
|
node.start(ChainTypes::Mainnet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn title(&self) -> &String {
|
||||||
|
&self.title
|
||||||
|
}
|
||||||
|
}
|
13
src/gui/views/network_tuning.rs
Normal file
13
src/gui/views/network_tuning.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright 2023 The Grim Developers
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
|
@ -12,61 +12,55 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
use eframe::epaint::text::{LayoutJob, TextFormat, TextWrapping};
|
use eframe::epaint::text::{LayoutJob, TextFormat, TextWrapping};
|
||||||
use egui::{Color32, FontId, RichText, Sense, Stroke, Widget};
|
use egui::{Color32, FontId, RichText, Sense, Stroke, Widget};
|
||||||
use egui::style::Margin;
|
use egui::style::Margin;
|
||||||
use egui_extras::{Size, StripBuilder};
|
use egui_extras::{Size, StripBuilder};
|
||||||
|
|
||||||
use crate::gui::{COLOR_DARK, COLOR_YELLOW};
|
use crate::gui::{COLOR_DARK, COLOR_YELLOW};
|
||||||
use crate::gui::screens::Navigator;
|
use crate::gui::screens::Navigator;
|
||||||
use crate::gui::views::View;
|
|
||||||
|
|
||||||
pub struct PanelAction {
|
pub struct TitlePanelAction {
|
||||||
pub(crate) icon: Box<str>,
|
pub(crate) icon: Box<str>,
|
||||||
pub(crate) on_click: Box<dyn Fn(&mut Option<&mut Navigator>)>,
|
pub(crate) on_click: Box<dyn Fn(&mut Option<&mut Navigator>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct PanelActions {
|
pub struct TitlePanelActions {
|
||||||
left: Option<PanelAction>,
|
left: Option<TitlePanelAction>,
|
||||||
right: Option<PanelAction>
|
right: Option<TitlePanelAction>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct TitlePanel<'screen> {
|
pub struct TitlePanel<'nav> {
|
||||||
title: Option<&'screen String>,
|
title: Option<&'nav str>,
|
||||||
actions: PanelActions,
|
actions: TitlePanelActions,
|
||||||
navigator: Option<&'screen mut Navigator>
|
navigator: Option<&'nav mut Navigator>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'screen> TitlePanel<'screen> {
|
impl<'nav> TitlePanel<'nav> {
|
||||||
pub fn title(mut self, title: &'screen String) -> Self {
|
pub fn title(mut self, title: &'nav str) -> Self {
|
||||||
self.title = Some(title);
|
self.title = Some(title);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn left_action(mut self, action: PanelAction) -> Self {
|
pub fn left_action(mut self, action: TitlePanelAction) -> Self {
|
||||||
self.actions.left = Some(action);
|
self.actions.left = Some(action);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn right_action(mut self, action: PanelAction) -> Self {
|
pub fn right_action(mut self, action: TitlePanelAction) -> Self {
|
||||||
self.actions.right = Some(action);
|
self.actions.right = Some(action);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_navigator(mut self, nav: &'screen mut Navigator) -> Self {
|
pub fn with_navigator(mut self, nav: &'nav mut Navigator) -> Self {
|
||||||
self.navigator = Some(nav);
|
self.navigator = Some(nav);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl View for TitlePanel<'_> {
|
pub fn ui(&mut self, ui: &mut egui::Ui) {
|
||||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
// Disable stroke around panel buttons on hover
|
||||||
// Disable stroke around panel
|
|
||||||
ui.style_mut().visuals.widgets.noninteractive.bg_stroke = Stroke::NONE;
|
|
||||||
|
|
||||||
// Disable stroke around buttons on hover
|
|
||||||
ui.style_mut().visuals.widgets.active.bg_stroke = Stroke::NONE;
|
ui.style_mut().visuals.widgets.active.bg_stroke = Stroke::NONE;
|
||||||
|
|
||||||
let Self { actions, title, navigator } = self;
|
let Self { actions, title, navigator } = self;
|
||||||
|
@ -114,7 +108,7 @@ impl View for TitlePanel<'_> {
|
||||||
strip.cell(|ui| {
|
strip.cell(|ui| {
|
||||||
if title.is_some() {
|
if title.is_some() {
|
||||||
ui.centered_and_justified(|ui| {
|
ui.centered_and_justified(|ui| {
|
||||||
show_title(title.as_ref().unwrap(), ui);
|
Self::show_title(title.unwrap(), ui);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -141,9 +135,8 @@ impl View for TitlePanel<'_> {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn show_title(title: &String, ui: &mut egui::Ui) {
|
fn show_title(title: &str, ui: &mut egui::Ui) {
|
||||||
let mut job = LayoutJob::single_section(title.to_uppercase(), TextFormat {
|
let mut job = LayoutJob::single_section(title.to_uppercase(), TextFormat {
|
||||||
font_id: FontId::proportional(20.0),
|
font_id: FontId::proportional(20.0),
|
||||||
color: COLOR_DARK,
|
color: COLOR_DARK,
|
||||||
|
@ -156,4 +149,6 @@ fn show_title(title: &String, ui: &mut egui::Ui) {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
ui.label(job);
|
ui.label(job);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
pub mod node;
|
mod node;
|
||||||
|
|
||||||
pub use self::node::start;
|
pub use self::node::Node;
|
||||||
|
pub use self::node::NodeState;
|
214
src/node/node.rs
214
src/node/node.rs
|
@ -12,29 +12,153 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::sync::mpsc;
|
use std::{fs, thread};
|
||||||
use grin_config::{config, GlobalConfig};
|
use std::fmt::format;
|
||||||
|
use std::ops::Deref;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::{Arc, LockResult, mpsc, Mutex, MutexGuard};
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::thread::JoinHandle;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use futures::channel::oneshot;
|
||||||
|
use grin_chain::SyncStatus;
|
||||||
|
use grin_config::config;
|
||||||
use grin_core::global;
|
use grin_core::global;
|
||||||
use grin_core::global::ChainTypes;
|
use grin_core::global::ChainTypes;
|
||||||
|
use grin_servers::{Server, ServerStats};
|
||||||
|
use grin_servers::common::types::Error;
|
||||||
use grin_util::logger::LogEntry;
|
use grin_util::logger::LogEntry;
|
||||||
|
use grin_util::StopState;
|
||||||
use log::info;
|
use log::info;
|
||||||
use futures::channel::oneshot;
|
|
||||||
|
|
||||||
pub fn start(chain_type: &ChainTypes) {
|
pub struct Node {
|
||||||
let node_config = Some(
|
/// Node state updated from the separate thread
|
||||||
config::initial_setup_server(&ChainTypes::Mainnet).unwrap_or_else(|e| {
|
node_state: Arc<Mutex<NodeState>>,
|
||||||
//TODO: Error handling
|
}
|
||||||
panic!("Error loading server configuration: {}", e);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
impl Node {
|
||||||
|
/// Instantiate new node with provided chain type, start server if needed
|
||||||
|
pub fn new(chain_type: ChainTypes, start: bool) -> Self {
|
||||||
|
let stop_state = Arc::new(StopState::new());
|
||||||
|
let mut state = NodeState::new(chain_type, stop_state.clone());
|
||||||
|
let node_state = Arc::new(Mutex::new(state));
|
||||||
|
if start {
|
||||||
|
let server = start_server(&chain_type, stop_state);
|
||||||
|
start_server_thread(node_state.clone(), server);
|
||||||
|
} else {
|
||||||
|
stop_state.stop();
|
||||||
|
}
|
||||||
|
Self { node_state }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Acquire node state to be used by a current thread
|
||||||
|
pub fn acquire_state(&self) -> MutexGuard<'_, NodeState> {
|
||||||
|
self.node_state.lock().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stop server
|
||||||
|
pub fn stop(&self) {
|
||||||
|
self.acquire_state().stop_needed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start server with provided chain type
|
||||||
|
pub fn start(&self, chain_type: ChainTypes) {
|
||||||
|
let mut state = self.node_state.lock().unwrap();
|
||||||
|
if state.stop_state.is_stopped() {
|
||||||
|
self.start_with_acquired_state(state, chain_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restart server with provided chain type
|
||||||
|
pub fn restart(&mut self, chain_type: ChainTypes) {
|
||||||
|
let mut state = self.acquire_state();
|
||||||
|
if !state.stop_state.is_stopped() {
|
||||||
|
state.chain_type = chain_type;
|
||||||
|
state.restart_needed = true;
|
||||||
|
} else {
|
||||||
|
self.start_with_acquired_state(state, chain_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start server with provided acquired state
|
||||||
|
fn start_with_acquired_state(&self, mut state: MutexGuard<NodeState>, chain_type: ChainTypes) {
|
||||||
|
state.chain_type = chain_type;
|
||||||
|
state.stop_state = Arc::new(StopState::new());
|
||||||
|
|
||||||
|
let server = start_server(&chain_type, state.stop_state.clone());
|
||||||
|
start_server_thread(self.node_state.clone(), server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NodeState {
|
||||||
|
/// To check server state
|
||||||
|
stop_state: Arc<StopState>,
|
||||||
|
/// Data for UI, None means server is not started
|
||||||
|
pub(crate) stats: Option<ServerStats>,
|
||||||
|
/// Chain type of launched server
|
||||||
|
chain_type: ChainTypes,
|
||||||
|
/// Thread flag to stop the server and start it again
|
||||||
|
restart_needed: bool,
|
||||||
|
/// Thread flag to stop the server
|
||||||
|
stop_needed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NodeState {
|
||||||
|
/// Instantiate new node state with provided chain type and server state
|
||||||
|
pub fn new(chain_type: ChainTypes, stop_state: Arc<StopState>) -> Self {
|
||||||
|
Self {
|
||||||
|
stop_state,
|
||||||
|
stats: None,
|
||||||
|
chain_type,
|
||||||
|
restart_needed: false,
|
||||||
|
stop_needed: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if server is stopping at separate thread
|
||||||
|
pub fn is_stopping(&self) -> bool {
|
||||||
|
return self.stop_needed
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if server is restarting at separate thread
|
||||||
|
pub fn is_restarting(&self) -> bool {
|
||||||
|
return self.restart_needed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start server with provided chain type and node state
|
||||||
|
fn start_server(chain_type: &ChainTypes, stop_state: Arc<StopState>) -> Server {
|
||||||
|
let mut node_config_result = config::initial_setup_server(chain_type);
|
||||||
|
if node_config_result.is_err() {
|
||||||
|
// Remove config file on init error
|
||||||
|
let mut grin_path = dirs::home_dir().unwrap();
|
||||||
|
grin_path.push(".grin");
|
||||||
|
grin_path.push(chain_type.shortname());
|
||||||
|
grin_path.push(config::SERVER_CONFIG_FILE_NAME);
|
||||||
|
fs::remove_file(grin_path).unwrap();
|
||||||
|
|
||||||
|
// Reinit config
|
||||||
|
node_config_result = config::initial_setup_server(chain_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
let node_config = node_config_result.ok();
|
||||||
let config = node_config.clone().unwrap();
|
let config = node_config.clone().unwrap();
|
||||||
let server_config = config.members.as_ref().unwrap().server.clone();
|
let server_config = config.members.as_ref().unwrap().server.clone();
|
||||||
|
|
||||||
// Initialize our global chain_type, feature flags (NRD kernel support currently), accept_fee_base, and future_time_limit.
|
let mut db_path = PathBuf::from(&server_config.db_root);
|
||||||
|
db_path.push("grin.lock");
|
||||||
|
fs::remove_file(db_path).unwrap();
|
||||||
|
|
||||||
|
// Initialize our global chain_type, feature flags (NRD kernel support currently),
|
||||||
|
// accept_fee_base, and future_time_limit.
|
||||||
// These are read via global and not read from config beyond this point.
|
// These are read via global and not read from config beyond this point.
|
||||||
|
if !global::GLOBAL_CHAIN_TYPE.is_init() {
|
||||||
global::init_global_chain_type(config.members.as_ref().unwrap().server.chain_type);
|
global::init_global_chain_type(config.members.as_ref().unwrap().server.chain_type);
|
||||||
|
}
|
||||||
info!("Chain: {:?}", global::get_chain_type());
|
info!("Chain: {:?}", global::get_chain_type());
|
||||||
|
|
||||||
|
if !global::GLOBAL_NRD_FEATURE_ENABLED.is_init() {
|
||||||
match global::get_chain_type() {
|
match global::get_chain_type() {
|
||||||
ChainTypes::Mainnet => {
|
ChainTypes::Mainnet => {
|
||||||
// Set various mainnet specific feature flags.
|
// Set various mainnet specific feature flags.
|
||||||
|
@ -45,6 +169,8 @@ pub fn start(chain_type: &ChainTypes) {
|
||||||
global::init_global_nrd_enabled(true);
|
global::init_global_nrd_enabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if !global::GLOBAL_ACCEPT_FEE_BASE.is_init() {
|
||||||
let afb = config
|
let afb = config
|
||||||
.members
|
.members
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -54,21 +180,63 @@ pub fn start(chain_type: &ChainTypes) {
|
||||||
.accept_fee_base;
|
.accept_fee_base;
|
||||||
global::init_global_accept_fee_base(afb);
|
global::init_global_accept_fee_base(afb);
|
||||||
info!("Accept Fee Base: {:?}", global::get_accept_fee_base());
|
info!("Accept Fee Base: {:?}", global::get_accept_fee_base());
|
||||||
|
}
|
||||||
|
if !global::GLOBAL_FUTURE_TIME_LIMIT.is_init() {
|
||||||
global::init_global_future_time_limit(config.members.unwrap().server.future_time_limit);
|
global::init_global_future_time_limit(config.members.unwrap().server.future_time_limit);
|
||||||
info!("Future Time Limit: {:?}", global::get_future_time_limit());
|
info!("Future Time Limit: {:?}", global::get_future_time_limit());
|
||||||
|
}
|
||||||
|
|
||||||
let api_chan: &'static mut (oneshot::Sender<()>, oneshot::Receiver<()>) =
|
let api_chan: &'static mut (oneshot::Sender<()>, oneshot::Receiver<()>) =
|
||||||
Box::leak(Box::new(oneshot::channel::<()>()));
|
Box::leak(Box::new(oneshot::channel::<()>()));
|
||||||
grin_servers::Server::start(
|
let mut server_result = Server::new(server_config.clone(), Some(stop_state.clone()), api_chan);
|
||||||
server_config,
|
if server_result.is_err() {
|
||||||
None,
|
let mut db_path = PathBuf::from(&server_config.db_root);
|
||||||
|serv: grin_servers::Server, info: Option<mpsc::Receiver<LogEntry>>| {
|
db_path.push("grin.lock");
|
||||||
serv.get_server_stats();
|
fs::remove_file(db_path).unwrap();
|
||||||
info!("Info callback")
|
|
||||||
//serv.stop();
|
// Remove chain data on server start error
|
||||||
},
|
let dirs_to_remove: Vec<&str> = vec!["header", "lmdb", "txhashset", "peer"];
|
||||||
None,
|
for dir in dirs_to_remove {
|
||||||
api_chan
|
let mut path = PathBuf::from(&server_config.db_root);
|
||||||
)
|
path.push(dir);
|
||||||
.unwrap();
|
fs::remove_dir_all(path).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recreate server
|
||||||
|
let config = node_config.clone().unwrap();
|
||||||
|
let server_config = config.members.as_ref().unwrap().server.clone();
|
||||||
|
let api_chan: &'static mut (oneshot::Sender<()>, oneshot::Receiver<()>) =
|
||||||
|
Box::leak(Box::new(oneshot::channel::<()>()));
|
||||||
|
server_result = Server::new(server_config.clone(), Some(stop_state.clone()), api_chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
server_result.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start a thread to launch server and update node state with server stats
|
||||||
|
fn start_server_thread(node_state: Arc<Mutex<NodeState>>, mut server: Server) -> JoinHandle<()> {
|
||||||
|
thread::spawn(move || loop {
|
||||||
|
thread::sleep(Duration::from_millis(500));
|
||||||
|
let mut state = node_state.lock().unwrap();
|
||||||
|
if state.restart_needed {
|
||||||
|
server.stop();
|
||||||
|
|
||||||
|
// Create new server with new stop state
|
||||||
|
state.stop_state = Arc::new(StopState::new());
|
||||||
|
server = start_server(&state.chain_type, state.stop_state.clone());
|
||||||
|
|
||||||
|
state.restart_needed = false;
|
||||||
|
} else if state.stop_needed {
|
||||||
|
server.stop();
|
||||||
|
state.stats = None;
|
||||||
|
state.stop_needed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if !state.stop_state.is_stopped() {
|
||||||
|
let stats = server.get_server_stats();
|
||||||
|
if stats.is_ok() {
|
||||||
|
state.stats = Some(stats.as_ref().ok().unwrap().clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
Loading…
Reference in a new issue