mirror of
https://github.com/MeexReay/bRAC.git
synced 2025-05-06 13:38:04 +03:00
gtk gui
This commit is contained in:
parent
b99311bd7c
commit
440d6c72d8
617
Cargo.lock
generated
617
Cargo.lock
generated
@ -2,6 +2,21 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
@ -77,9 +92,11 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
name = "bRAC"
|
||||
version = "0.1.2+2.0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"clap",
|
||||
"colored",
|
||||
"crossterm",
|
||||
"gtk4",
|
||||
"homedir",
|
||||
"lazy_static",
|
||||
"native-tls",
|
||||
@ -87,6 +104,22 @@ dependencies = [
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_yml",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -101,6 +134,35 @@ version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||
|
||||
[[package]]
|
||||
name = "cairo-rs"
|
||||
version = "0.20.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae50b5510d86cf96ac2370e66d8dc960882f3df179d6a5a1e52bd94a1416c0f7"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cairo-sys-rs",
|
||||
"glib",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cairo-sys-rs"
|
||||
version = "0.20.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f18b6bb8e43c7eb0f2aac7976afe0c61b6f5fc2ab7bc4c139537ea56c92290df"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.13"
|
||||
@ -110,6 +172,16 @@ dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-expr"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d4ba6e40bd1184518716a6e1a781bf9160e286d219ccdb8ab2612e74cfe4789"
|
||||
dependencies = [
|
||||
"smallvec",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
@ -281,6 +353,16 @@ version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||
|
||||
[[package]]
|
||||
name = "field-offset"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f"
|
||||
dependencies = [
|
||||
"memoffset",
|
||||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
@ -296,6 +378,126 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-macro",
|
||||
"futures-task",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gdk-pixbuf"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7563afd6ff0a221edfbb70a78add5075b8d9cb48e637a40a24c3ece3fea414d0"
|
||||
dependencies = [
|
||||
"gdk-pixbuf-sys",
|
||||
"gio",
|
||||
"glib",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gdk-pixbuf-sys"
|
||||
version = "0.20.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67f2587c9202bf997476bbba6aaed4f78a11538a2567df002a5f57f5331d0b5c"
|
||||
dependencies = [
|
||||
"gio-sys",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gdk4"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4850c9d9c1aecd1a3eb14fadc1cdb0ac0a2298037e116264c7473e1740a32d60"
|
||||
dependencies = [
|
||||
"cairo-rs",
|
||||
"gdk-pixbuf",
|
||||
"gdk4-sys",
|
||||
"gio",
|
||||
"glib",
|
||||
"libc",
|
||||
"pango",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gdk4-sys"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f6eb95798e2b46f279cf59005daf297d5b69555428f185650d71974a910473a"
|
||||
dependencies = [
|
||||
"cairo-sys-rs",
|
||||
"gdk-pixbuf-sys",
|
||||
"gio-sys",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"pango-sys",
|
||||
"pkg-config",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.1"
|
||||
@ -308,6 +510,203 @@ dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "gio"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4f00c70f8029d84ea7572dd0e1aaa79e5329667b4c17f329d79ffb1e6277487"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"gio-sys",
|
||||
"glib",
|
||||
"libc",
|
||||
"pin-project-lite",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gio-sys"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "160eb5250a26998c3e1b54e6a3d4ea15c6c7762a6062a19a7b63eff6e2b33f9e"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "707b819af8059ee5395a2de9f2317d87a53dbad8846a2f089f0bb44703f37686"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
"gio-sys",
|
||||
"glib-macros",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"memchr",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-macros"
|
||||
version = "0.20.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "715601f8f02e71baef9c1f94a657a9a77c192aea6097cf9ae7e5e177cd8cde68"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-sys"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8928869a44cfdd1fccb17d6746e4ff82c8f82e41ce705aa026a52ca8dc3aefb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gobject-sys"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c773a3cb38a419ad9c26c81d177d96b4b08980e8bdbbf32dace883e96e96e7e3"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "graphene-rs"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cbc5911bfb32d68dcfa92c9510c462696c2f715548fcd7f3f1be424c739de19"
|
||||
dependencies = [
|
||||
"glib",
|
||||
"graphene-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "graphene-sys"
|
||||
version = "0.20.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11a68d39515bf340e879b72cecd4a25c1332557757ada6e8aba8654b4b81d23a"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gsk4"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61f5e72f931c8c9f65fbfc89fe0ddc7746f147f822f127a53a9854666ac1f855"
|
||||
dependencies = [
|
||||
"cairo-rs",
|
||||
"gdk4",
|
||||
"glib",
|
||||
"graphene-rs",
|
||||
"gsk4-sys",
|
||||
"libc",
|
||||
"pango",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gsk4-sys"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "755059de55fa6f85a46bde8caf03e2184c96bfda1f6206163c72fb0ea12436dc"
|
||||
dependencies = [
|
||||
"cairo-sys-rs",
|
||||
"gdk4-sys",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"graphene-sys",
|
||||
"libc",
|
||||
"pango-sys",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gtk4"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af1c491051f030994fd0cde6f3c44f3f5640210308cff1298c7673c47408091d"
|
||||
dependencies = [
|
||||
"cairo-rs",
|
||||
"field-offset",
|
||||
"futures-channel",
|
||||
"gdk-pixbuf",
|
||||
"gdk4",
|
||||
"gio",
|
||||
"glib",
|
||||
"graphene-rs",
|
||||
"gsk4",
|
||||
"gtk4-macros",
|
||||
"gtk4-sys",
|
||||
"libc",
|
||||
"pango",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gtk4-macros"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ed1786c4703dd196baf7e103525ce0cf579b3a63a0570fe653b7ee6bac33999"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gtk4-sys"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41e03b01e54d77c310e1d98647d73f996d04b2f29b9121fe493ea525a7ec03d6"
|
||||
dependencies = [
|
||||
"cairo-sys-rs",
|
||||
"gdk-pixbuf-sys",
|
||||
"gdk4-sys",
|
||||
"gio-sys",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"graphene-sys",
|
||||
"gsk4-sys",
|
||||
"libc",
|
||||
"pango-sys",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.2"
|
||||
@ -416,6 +815,24 @@ version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.0.3"
|
||||
@ -457,6 +874,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.20.3"
|
||||
@ -507,6 +933,30 @@ dependencies = [
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pango"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b1f5dc1b8cf9bc08bfc0843a04ee0fa2e78f1e1fa4b126844a383af4f25f0ec"
|
||||
dependencies = [
|
||||
"gio",
|
||||
"glib",
|
||||
"libc",
|
||||
"pango-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pango-sys"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dbb9b751673bd8fe49eb78620547973a1e719ed431372122b20abd12445bab5"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.3"
|
||||
@ -530,6 +980,18 @@ dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.31"
|
||||
@ -545,6 +1007,15 @@ dependencies = [
|
||||
"zerocopy 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35"
|
||||
dependencies = [
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.93"
|
||||
@ -632,6 +1103,21 @@ version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.44"
|
||||
@ -702,6 +1188,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
@ -722,6 +1214,15 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yml"
|
||||
version = "0.0.12"
|
||||
@ -773,12 +1274,31 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
@ -796,6 +1316,25 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-deps"
|
||||
version = "7.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66d23aaf9f331227789a99e8de4c91bf46703add012bdfd45fdecdfb2975a005"
|
||||
dependencies = [
|
||||
"cfg-expr",
|
||||
"heck",
|
||||
"pkg-config",
|
||||
"toml",
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.12.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.16.0"
|
||||
@ -810,6 +1349,69 @@ dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.44.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.16"
|
||||
@ -834,6 +1436,12 @@ version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version-compare"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
@ -1018,6 +1626,15 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.33.0"
|
||||
|
10
Cargo.toml
10
Cargo.toml
@ -14,9 +14,13 @@ serde_yml = "0.0.12"
|
||||
crossterm = { version = "0.29.0", optional = true }
|
||||
homedir = { version = "0.3.4", optional = true }
|
||||
native-tls = { version = "0.2.14", optional = true }
|
||||
gtk4 = { version = "0.9.6", optional = true }
|
||||
cfg-if = "1.0.0"
|
||||
tokio = { version = "1.44.2", optional = true, features = [ "full" ] }
|
||||
|
||||
[features]
|
||||
default = ["ssl", "pretty", "homedir"]
|
||||
default = ["ssl", "homedir", "gtk_gui"]
|
||||
ssl = ["dep:native-tls"]
|
||||
pretty = ["dep:crossterm"]
|
||||
homedir = ["dep:homedir"]
|
||||
pretty_tui = ["dep:crossterm"]
|
||||
gtk_gui = ["dep:gtk4"]
|
||||
homedir = ["dep:homedir", "dep:tokio"]
|
||||
|
BIN
brac_logo.png
Normal file
BIN
brac_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 95 KiB |
@ -59,6 +59,11 @@
|
||||
features = "default";
|
||||
deps = with pkgs; [ pkg-config openssl ];
|
||||
});
|
||||
packages.bRAC-gtk = (rustPackage {
|
||||
version = "-gtk";
|
||||
features = "default gtk_gui";
|
||||
deps = with pkgs; [ pkg-config openssl gtk4 pango ];
|
||||
});
|
||||
packages.bRAC-minimal = (rustPackage {
|
||||
version = "-minimal";
|
||||
features = "";
|
||||
|
158
src/chat.rs
158
src/chat.rs
@ -16,6 +16,7 @@ use super::{
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref DATE_REGEX: Regex = Regex::new(r"\[(.*?)\] (.*)").unwrap();
|
||||
@ -29,15 +30,19 @@ lazy_static! {
|
||||
];
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "pretty"))]
|
||||
pub mod minimal_tui;
|
||||
#[cfg(not(feature = "pretty"))]
|
||||
pub use minimal_tui::{run_main_loop, update_console};
|
||||
|
||||
#[cfg(feature = "pretty")]
|
||||
pub mod pretty_tui;
|
||||
#[cfg(feature = "pretty")]
|
||||
pub use pretty_tui::{run_main_loop, update_console};
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "gtk_gui")] {
|
||||
mod gtk_gui;
|
||||
pub use gtk_gui::*;
|
||||
} else if #[cfg(feature = "pretty_tui")] {
|
||||
mod pretty_tui;
|
||||
pub use pretty_tui::*;
|
||||
} else {
|
||||
mod minimal_tui;
|
||||
pub use minimal_tui::*;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct ChatStorage {
|
||||
@ -94,11 +99,11 @@ const HELP_MESSAGE: &str = "Help message:
|
||||
|
||||
|
||||
pub fn add_message(ctx: Arc<Context>, message: &str) -> Result<(), Box<dyn Error>> {
|
||||
ctx.messages.append(
|
||||
ctx.max_messages,
|
||||
message.split("\n").map(|o| o.to_string()).collect::<Vec<String>>()
|
||||
);
|
||||
update_console(ctx)
|
||||
for i in message.split("\n")
|
||||
.map(|o| o.to_string()) {
|
||||
print_message(ctx.clone(), i)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn on_command(ctx: Arc<Context>, command: &str) -> Result<(), Box<dyn Error>> {
|
||||
@ -130,7 +135,7 @@ pub fn on_command(ctx: Arc<Context>, command: &str) -> Result<(), Box<dyn Error>
|
||||
match register_user(&mut connect(&ctx.host, ctx.enable_ssl)?, &ctx.name, pass) {
|
||||
Ok(true) => {
|
||||
add_message(ctx.clone(), "you was registered successfully bro")?;
|
||||
*ctx.registered.write().unwrap() = Some(pass.to_string());
|
||||
*ctx.chat().registered.write().unwrap() = Some(pass.to_string());
|
||||
},
|
||||
Ok(false) => add_message(ctx.clone(), "user with this account already exists bruh")?,
|
||||
Err(e) => add_message(ctx.clone(), &format!("ERROR while registrationing: {}", e))?
|
||||
@ -142,9 +147,9 @@ pub fn on_command(ctx: Arc<Context>, command: &str) -> Result<(), Box<dyn Error>
|
||||
};
|
||||
|
||||
add_message(ctx.clone(), "ye bro you was logged in")?;
|
||||
*ctx.registered.write().unwrap() = Some(pass.to_string());
|
||||
*ctx.chat().registered.write().unwrap() = Some(pass.to_string());
|
||||
} else if command == "ping" {
|
||||
let mut before = ctx.messages.packet_size();
|
||||
let mut before = ctx.chat().messages.packet_size();
|
||||
let message = format!("Checking ping... {:X}", SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis());
|
||||
|
||||
send_message(&mut connect(&ctx.host, ctx.enable_ssl)?, &message)?;
|
||||
@ -218,7 +223,7 @@ pub fn on_send_message(ctx: Arc<Context>, message: &str) -> Result<(), Box<dyn E
|
||||
.replace("{text}", &message)
|
||||
);
|
||||
|
||||
if let Some(password) = ctx.registered.read().unwrap().clone() {
|
||||
if let Some(password) = ctx.chat().registered.read().unwrap().clone() {
|
||||
send_message_auth(&mut connect(&ctx.host, ctx.enable_ssl)?, &ctx.name, &password, &message)?;
|
||||
} else if ctx.enable_auth {
|
||||
send_message_spoof_auth(&mut connect(&ctx.host, ctx.enable_ssl)?, &message)?;
|
||||
@ -230,73 +235,70 @@ pub fn on_send_message(ctx: Arc<Context>, message: &str) -> Result<(), Box<dyn E
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn format_message(enable_ip_viewing: bool, message: String) -> Option<String> {
|
||||
/// message -> (date, ip, text)
|
||||
pub fn parse_message(message: String) -> Option<(String, Option<String>, String, Option<(String, Color)>)> {
|
||||
let message = sanitize_text(&message);
|
||||
|
||||
let message = message
|
||||
.trim_start_matches("(UNREGISTERED)")
|
||||
.trim_start_matches("(UNAUTHORIZED)")
|
||||
.trim_start_matches("(UNAUTHENTICATED)")
|
||||
.trim()
|
||||
.to_string()+" ";
|
||||
|
||||
if message.is_empty() {
|
||||
None
|
||||
return None
|
||||
}
|
||||
|
||||
let date = DATE_REGEX.captures(&message)?;
|
||||
let (date, message) = (
|
||||
date.get(1)?.as_str().to_string(),
|
||||
date.get(2)?.as_str().to_string(),
|
||||
);
|
||||
|
||||
let (ip, message) = if let Some(message) = IP_REGEX.captures(&message) {
|
||||
(Some(message.get(1)?.as_str().to_string()), message.get(2)?.as_str().to_string())
|
||||
} else {
|
||||
Some(
|
||||
{
|
||||
let message = message.clone();
|
||||
move || -> Option<String> {
|
||||
let message = sanitize_text(&message);
|
||||
(None, message)
|
||||
};
|
||||
|
||||
let (message, nick) = match find_username_color(&message) {
|
||||
Some((name, content, color)) => (content, Some((name, color))),
|
||||
None => (message, None),
|
||||
};
|
||||
|
||||
let date = DATE_REGEX.captures(&message)?;
|
||||
let (date, message) = (
|
||||
date.get(1)?.as_str().to_string(),
|
||||
date.get(2)?.as_str().to_string(),
|
||||
);
|
||||
Some((date, ip, message, nick))
|
||||
}
|
||||
|
||||
let (ip, message) = if let Some(message) = IP_REGEX.captures(&message) {
|
||||
(Some(message.get(1)?.as_str().to_string()), message.get(2)?.as_str().to_string())
|
||||
pub fn format_message(enable_ip_viewing: bool, message: String) -> Option<String> {
|
||||
if let Some((date, ip, content, nick)) = parse_message(message.clone()) {
|
||||
Some(format!(
|
||||
"{} {}{}",
|
||||
if enable_ip_viewing {
|
||||
if let Some(ip) = ip {
|
||||
format!("{}{} [{}]", ip, " ".repeat(if 15 >= ip.chars().count() {15-ip.chars().count()} else {0}), date)
|
||||
} else {
|
||||
(None, message)
|
||||
};
|
||||
|
||||
let message = message
|
||||
.trim_start_matches("(UNREGISTERED)")
|
||||
.trim_start_matches("(UNAUTHORIZED)")
|
||||
.trim_start_matches("(UNAUTHENTICATED)")
|
||||
.trim()
|
||||
.to_string()+" ";
|
||||
|
||||
let prefix = if enable_ip_viewing {
|
||||
if let Some(ip) = ip {
|
||||
format!("{}{} [{}]", ip, " ".repeat(if 15 >= ip.chars().count() {15-ip.chars().count()} else {0}), date)
|
||||
} else {
|
||||
format!("{} [{}]", " ".repeat(15), date)
|
||||
}
|
||||
} else {
|
||||
format!("[{}]", date)
|
||||
};
|
||||
|
||||
Some(if let Some(captures) = find_username_color(&message) {
|
||||
let nick = captures.0;
|
||||
let content = captures.1;
|
||||
let color = captures.2;
|
||||
|
||||
format!(
|
||||
"{} {} {}",
|
||||
prefix.white().dimmed(),
|
||||
format!("<{}>", nick).color(color).bold(),
|
||||
content.white().blink()
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"{} {}",
|
||||
prefix.white().dimmed(),
|
||||
message.white().blink()
|
||||
)
|
||||
})
|
||||
}()
|
||||
}.unwrap_or_else(|| {
|
||||
format!(
|
||||
"{}",
|
||||
message.bright_white()
|
||||
)
|
||||
}))
|
||||
format!("{} [{}]", " ".repeat(15), date)
|
||||
}
|
||||
} else {
|
||||
format!("[{}]", date)
|
||||
}.white().dimmed(),
|
||||
nick.map(|(name, color)|
|
||||
format!("<{}> ", name)
|
||||
.color(color)
|
||||
.bold()
|
||||
.to_string()
|
||||
).unwrap_or_default(),
|
||||
content.white().blink()
|
||||
))
|
||||
} else if !message.is_empty() {
|
||||
Some(message.bright_white().to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// message -> (nick, content, color)
|
||||
pub fn find_username_color(message: &str) -> Option<(String, String, Color)> {
|
||||
for (re, color) in COLORED_USERNAMES.iter() {
|
||||
if let Some(captures) = re.captures(message) {
|
||||
@ -304,4 +306,8 @@ pub fn find_username_color(message: &str) -> Option<(String, String, Color)> {
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn set_chat(ctx: Arc<Context>, chat: ChatContext) {
|
||||
*ctx.chat.write().unwrap() = Some(Arc::new(chat));
|
||||
}
|
467
src/chat/gtk_gui.rs
Normal file
467
src/chat/gtk_gui.rs
Normal file
@ -0,0 +1,467 @@
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::time::Duration;
|
||||
|
||||
use colored::{Color, Colorize};
|
||||
use gtk4::gdk::Display;
|
||||
use gtk4::gdk_pixbuf::PixbufLoader;
|
||||
use gtk4::glib::clone::Downgrade;
|
||||
use gtk4::glib::{idle_add_local, idle_add_local_once, ControlFlow, source::timeout_add_once};
|
||||
use gtk4::{glib, glib::clone, Align, Box as GtkBox, Label, ScrolledWindow};
|
||||
use gtk4::{CssProvider, Entry, Orientation, Overlay, Picture};
|
||||
use gtk4::prelude::*;
|
||||
use gtk4::{Application, ApplicationWindow, Button};
|
||||
use std::sync::mpsc::{channel, Sender, Receiver};
|
||||
use std::error::Error;
|
||||
use std::thread;
|
||||
use std::cell::RefCell;
|
||||
|
||||
use crate::config::Context;
|
||||
use crate::proto::{connect, read_messages};
|
||||
|
||||
use super::{format_message, on_send_message, parse_message, set_chat, ChatStorage};
|
||||
|
||||
|
||||
pub struct ChatContext {
|
||||
pub messages: Arc<ChatStorage>,
|
||||
pub registered: Arc<RwLock<Option<String>>>,
|
||||
pub sender: Sender<String>
|
||||
}
|
||||
|
||||
struct UiModel {
|
||||
chat_box: GtkBox,
|
||||
chat_scrolled: ScrolledWindow
|
||||
}
|
||||
|
||||
pub fn add_chat_message(ctx: Arc<Context>, message: String) {
|
||||
let _ = ctx.chat().sender.send(message);
|
||||
// MainContext::default().invoke_local(move || {
|
||||
// ctx.chat().chat_box.upgrade().unwrap().append(&Label::new(Some(message.as_str())));
|
||||
// });
|
||||
}
|
||||
|
||||
pub fn print_message(ctx: Arc<Context>, message: String) -> Result<(), Box<dyn Error>> {
|
||||
ctx.chat().messages.append(ctx.max_messages, vec![message.clone()]);
|
||||
add_chat_message(ctx.clone(), message);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn recv_tick(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
match read_messages(
|
||||
&mut connect(&ctx.host, ctx.enable_ssl)?,
|
||||
ctx.max_messages,
|
||||
ctx.chat().messages.packet_size(),
|
||||
!ctx.enable_ssl,
|
||||
ctx.enable_chunked
|
||||
) {
|
||||
Ok(Some((messages, size))) => {
|
||||
let messages: Vec<String> = if ctx.disable_formatting {
|
||||
messages
|
||||
} else {
|
||||
messages.into_iter().flat_map(|o| format_message(ctx.enable_ip_viewing, o)).collect()
|
||||
};
|
||||
|
||||
if ctx.enable_chunked {
|
||||
ctx.chat().messages.append_and_store(ctx.max_messages, messages.clone(), size);
|
||||
for msg in messages {
|
||||
add_chat_message(ctx.clone(), msg.clone());
|
||||
}
|
||||
} else {
|
||||
ctx.chat().messages.update(ctx.max_messages, messages.clone(), size);
|
||||
for msg in messages {
|
||||
add_chat_message(ctx.clone(), msg.clone());
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
let msg = format!("Read messages error: {}", e.to_string()).bright_red().to_string();
|
||||
ctx.chat().messages.append(ctx.max_messages, vec![msg.clone()]);
|
||||
add_chat_message(ctx.clone(), msg.clone());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
thread::sleep(Duration::from_millis(ctx.update_time as u64));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build_ui(ctx: Arc<Context>, app: &Application) {
|
||||
let main_box = GtkBox::new(Orientation::Vertical, 5);
|
||||
|
||||
main_box.set_margin_bottom(5);
|
||||
main_box.set_margin_end(5);
|
||||
main_box.set_margin_start(5);
|
||||
main_box.set_margin_top(5);
|
||||
|
||||
let chat_box = GtkBox::new(Orientation::Vertical, 2);
|
||||
|
||||
let chat_scrolled = ScrolledWindow::builder()
|
||||
.child(&chat_box)
|
||||
.vexpand(true)
|
||||
.hexpand(true)
|
||||
.propagate_natural_height(true)
|
||||
.build();
|
||||
|
||||
main_box.append(&chat_scrolled);
|
||||
|
||||
let send_box = GtkBox::new(Orientation::Horizontal, 5);
|
||||
|
||||
let text_entry = Entry::builder()
|
||||
.placeholder_text("Message")
|
||||
.hexpand(true)
|
||||
.build();
|
||||
|
||||
send_box.append(&text_entry);
|
||||
|
||||
let send_btn = Button::builder()
|
||||
.label("Send")
|
||||
.build();
|
||||
|
||||
send_btn.connect_clicked(clone!(
|
||||
#[weak] text_entry,
|
||||
#[weak] ctx,
|
||||
move |_| {
|
||||
idle_add_local_once(clone!(
|
||||
#[weak] text_entry,
|
||||
move || {
|
||||
text_entry.set_text("");
|
||||
}
|
||||
));
|
||||
|
||||
if let Err(e) = on_send_message(ctx.clone(), &text_entry.text()) {
|
||||
let msg = format!("Send message error: {}", e.to_string()).bright_red().to_string();
|
||||
add_chat_message(ctx.clone(), msg);
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
text_entry.connect_activate(clone!(
|
||||
#[weak] text_entry,
|
||||
#[weak] ctx,
|
||||
move |_| {
|
||||
idle_add_local_once(clone!(
|
||||
#[weak] text_entry,
|
||||
move || {
|
||||
text_entry.set_text("");
|
||||
}
|
||||
));
|
||||
|
||||
if let Err(e) = on_send_message(ctx.clone(), &text_entry.text()) {
|
||||
let msg = format!("Send message error: {}", e.to_string()).bright_red().to_string();
|
||||
add_chat_message(ctx.clone(), msg);
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
send_box.append(&send_btn);
|
||||
|
||||
main_box.append(&send_box);
|
||||
|
||||
let scrolled_window_weak = Downgrade::downgrade(&chat_scrolled);
|
||||
|
||||
idle_add_local({
|
||||
let scrolled_window_weak = scrolled_window_weak.clone();
|
||||
|
||||
move || {
|
||||
if let Some(o) = scrolled_window_weak.upgrade() {
|
||||
o.vadjustment().set_value(o.vadjustment().upper() - o.vadjustment().page_size());
|
||||
}
|
||||
ControlFlow::Break
|
||||
}
|
||||
});
|
||||
|
||||
let overlay = Overlay::new();
|
||||
|
||||
overlay.set_child(Some(&main_box));
|
||||
|
||||
let bytes = include_bytes!("../../brac_logo.png");
|
||||
let loader = PixbufLoader::new();
|
||||
loader.write(bytes).unwrap();
|
||||
loader.close().unwrap();
|
||||
let pixbuf = loader.pixbuf().unwrap();
|
||||
|
||||
let logo = Picture::for_pixbuf(&pixbuf);
|
||||
logo.set_size_request(500, 189);
|
||||
logo.set_can_target(false);
|
||||
logo.set_can_focus(false);
|
||||
logo.set_halign(Align::End);
|
||||
logo.set_valign(Align::Start);
|
||||
|
||||
overlay.add_overlay(&logo);
|
||||
|
||||
let window = ApplicationWindow::builder()
|
||||
.application(app)
|
||||
.title(format!("bRAC - Connected to {} as {}", &ctx.host, &ctx.name))
|
||||
.default_width(500)
|
||||
.default_height(500)
|
||||
.resizable(false)
|
||||
.decorated(true)
|
||||
.child(&overlay)
|
||||
.build();
|
||||
|
||||
window.connect_default_width_notify({
|
||||
let scrolled_window_weak = scrolled_window_weak.clone();
|
||||
|
||||
move |_| {
|
||||
let scrolled_window_weak = scrolled_window_weak.clone();
|
||||
idle_add_local(move || {
|
||||
if let Some(o) = scrolled_window_weak.upgrade() {
|
||||
o.vadjustment().set_value(o.vadjustment().upper() - o.vadjustment().page_size());
|
||||
}
|
||||
ControlFlow::Break
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
window.show();
|
||||
|
||||
let ui = UiModel {
|
||||
chat_scrolled,
|
||||
chat_box
|
||||
};
|
||||
|
||||
setup(ctx.clone(), ui);
|
||||
load_css();
|
||||
}
|
||||
|
||||
fn setup(ctx: Arc<Context>, ui: UiModel) {
|
||||
let (sender, receiver) = channel();
|
||||
|
||||
set_chat(ctx.clone(), ChatContext {
|
||||
messages: Arc::new(ChatStorage::new()),
|
||||
registered: Arc::new(RwLock::new(None)),
|
||||
sender
|
||||
});
|
||||
|
||||
thread::spawn({
|
||||
let ctx = ctx.clone();
|
||||
|
||||
move || {
|
||||
loop {
|
||||
if let Err(e) = recv_tick(ctx.clone()) {
|
||||
let _ = print_message(ctx.clone(), format!("Print messages error: {}", e.to_string()).bright_red().to_string());
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let (tx, rx) = channel();
|
||||
|
||||
GLOBAL.with(|global| {
|
||||
*global.borrow_mut() = Some((ui, rx));
|
||||
});
|
||||
|
||||
thread::spawn({
|
||||
let ctx = ctx.clone();
|
||||
move || {
|
||||
while let Ok(message) = receiver.recv() {
|
||||
let _ = tx.send(message.clone());
|
||||
let ctx = ctx.clone();
|
||||
glib::source::timeout_add_once(Duration::ZERO, move || {
|
||||
GLOBAL.with(|global| {
|
||||
if let Some((ui, rx)) = &*global.borrow() {
|
||||
let message: String = rx.recv().unwrap();
|
||||
on_add_message(ctx.clone(), &ui, message);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn load_css() {
|
||||
let provider = CssProvider::new();
|
||||
provider.load_from_data("
|
||||
|
||||
.message-content {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.message-date {
|
||||
color: #AAAAAA;
|
||||
}
|
||||
|
||||
.message-ip {
|
||||
color: #AAAAAA;
|
||||
}
|
||||
|
||||
.message-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.message-name-black {
|
||||
color: #2E2E2E; /* Темный черный */
|
||||
}
|
||||
|
||||
.message-name-red {
|
||||
color: #8B0000; /* Темный красный */
|
||||
}
|
||||
|
||||
.message-name-green {
|
||||
color: #006400; /* Темный зеленый */
|
||||
}
|
||||
|
||||
.message-name-yellow {
|
||||
color: #8B8B00; /* Темный желтый */
|
||||
}
|
||||
|
||||
.message-name-blue {
|
||||
color: #00008B; /* Темный синий */
|
||||
}
|
||||
|
||||
.message-name-magenta {
|
||||
color: #8B008B; /* Темный пурпурный */
|
||||
}
|
||||
|
||||
.message-name-cyan {
|
||||
color: #008B8B; /* Темный бирюзовый */
|
||||
}
|
||||
|
||||
.message-name-white {
|
||||
color: #A9A9A9; /* Темный белый */
|
||||
}
|
||||
|
||||
.message-name-bright-black {
|
||||
color: #555555; /* Яркий черный */
|
||||
}
|
||||
|
||||
.message-name-bright-red {
|
||||
color: #FF0000; /* Яркий красный */
|
||||
}
|
||||
|
||||
.message-name-bright-green {
|
||||
color: #00FF00; /* Яркий зеленый */
|
||||
}
|
||||
|
||||
.message-name-bright-yellow {
|
||||
color: #FFFF00; /* Яркий желтый */
|
||||
}
|
||||
|
||||
.message-name-bright-blue {
|
||||
color: #0000FF; /* Яркий синий */
|
||||
}
|
||||
|
||||
.message-name-bright-magenta {
|
||||
color: #FF00FF; /* Яркий пурпурный */
|
||||
}
|
||||
|
||||
.message-name-bright-cyan {
|
||||
color: #00FFFF; /* Яркий бирюзовый */
|
||||
}
|
||||
|
||||
.message-name-bright-white {
|
||||
color: #FFFFFF; /* Яркий белый */
|
||||
}
|
||||
|
||||
");
|
||||
|
||||
gtk4::style_context_add_provider_for_display(
|
||||
&Display::default().expect("Could not connect to a display."),
|
||||
&provider,
|
||||
gtk4::STYLE_PROVIDER_PRIORITY_APPLICATION,
|
||||
);
|
||||
}
|
||||
|
||||
fn on_add_message(ctx: Arc<Context>, ui: &UiModel, message: String) {
|
||||
if let Some((date, ip, content, nick)) = parse_message(message.clone()) {
|
||||
let hbox = GtkBox::new(Orientation::Horizontal, 2);
|
||||
|
||||
if let Some(ip) = ip {
|
||||
if ctx.enable_ip_viewing {
|
||||
let ip = Label::builder()
|
||||
.label(ip)
|
||||
.margin_end(10)
|
||||
.halign(Align::Start)
|
||||
.css_classes(["message-ip"])
|
||||
.build();
|
||||
|
||||
hbox.append(&ip);
|
||||
}
|
||||
}
|
||||
|
||||
let date = Label::builder()
|
||||
.label(format!("[{date}]"))
|
||||
.halign(Align::Start)
|
||||
.css_classes(["message-date"])
|
||||
.build();
|
||||
|
||||
hbox.append(&date);
|
||||
|
||||
if let Some((name, color)) = nick {
|
||||
let color = match color {
|
||||
Color::Black => "black",
|
||||
Color::Red => "red",
|
||||
Color::Green => "green",
|
||||
Color::Yellow => "yellow",
|
||||
Color::Blue => "blue",
|
||||
Color::Magenta => "magenta",
|
||||
Color::Cyan => "cyan",
|
||||
Color::White => "white",
|
||||
Color::BrightBlack => "bright-black",
|
||||
Color::BrightRed => "bright-red",
|
||||
Color::BrightGreen => "bright-green",
|
||||
Color::BrightYellow => "bright-yellow",
|
||||
Color::BrightBlue => "bright-blue",
|
||||
Color::BrightMagenta => "bright-magenta",
|
||||
Color::BrightCyan => "bright-cyan",
|
||||
Color::BrightWhite => "bright-white",
|
||||
_ => "unknown"
|
||||
};
|
||||
|
||||
let name = Label::builder()
|
||||
.label(format!("<{name}>"))
|
||||
.halign(Align::Start)
|
||||
.css_classes(["message-name", &format!("message-name-{}", color)])
|
||||
.build();
|
||||
|
||||
hbox.append(&name);
|
||||
}
|
||||
|
||||
let content = Label::builder()
|
||||
.label(content)
|
||||
.halign(Align::Start)
|
||||
.css_classes(["message-content"])
|
||||
.build();
|
||||
|
||||
hbox.append(&content);
|
||||
|
||||
ui.chat_box.append(&hbox);
|
||||
} else {
|
||||
let content = Label::builder()
|
||||
.label(message)
|
||||
.halign(Align::Start)
|
||||
.css_classes(["message-content"])
|
||||
.build();
|
||||
|
||||
ui.chat_box.append(&content);
|
||||
}
|
||||
|
||||
timeout_add_once(Duration::from_millis(10), move || {
|
||||
GLOBAL.with(|global| {
|
||||
if let Some((ui, _)) = &*global.borrow() {
|
||||
let o = &ui.chat_scrolled;
|
||||
o.vadjustment().set_value(o.vadjustment().upper() - o.vadjustment().page_size());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
pub fn run_main_loop(ctx: Arc<Context>) {
|
||||
let application = Application::builder()
|
||||
.application_id("ru.themixray.bRAC")
|
||||
.build();
|
||||
|
||||
application.connect_activate({
|
||||
let ctx = ctx.clone();
|
||||
|
||||
move |app| {
|
||||
build_ui(ctx.clone(), app);
|
||||
}
|
||||
});
|
||||
|
||||
application.run();
|
||||
}
|
||||
|
||||
thread_local!(
|
||||
static GLOBAL: RefCell<Option<(UiModel, Receiver<String>)>> = RefCell::new(None);
|
||||
);
|
@ -13,7 +13,12 @@ use super::{
|
||||
}, format_message, on_send_message
|
||||
};
|
||||
|
||||
pub fn update_console(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
pub struct ChatContext {
|
||||
pub messages: Arc<ChatStorage>,
|
||||
pub registered: Arc<RwLock<Option<String>>>
|
||||
}
|
||||
|
||||
fn update_console(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
let messages = ctx.messages.messages();
|
||||
|
||||
let mut out = stdout().lock();
|
||||
@ -33,7 +38,17 @@ pub fn update_console(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn print_message(ctx: Arc<Context>, message: String) -> Result<(), Box<dyn Error>> {
|
||||
ctx.chat().messages.append(ctx.max_messages, vec![message]);
|
||||
update_console(ctx.clone())
|
||||
}
|
||||
|
||||
pub fn run_main_loop(ctx: Arc<Context>) {
|
||||
set_chat(ctx.clone(), ChatContext {
|
||||
messages: Arc::new(ChatStorage::new()),
|
||||
registered: Arc::new(RwLock::new(None)),
|
||||
});
|
||||
|
||||
loop {
|
||||
match connect(&ctx.host, ctx.enable_ssl) {
|
||||
Ok(mut stream) => {
|
||||
|
@ -10,7 +10,7 @@ use colored::Colorize;
|
||||
use std::{
|
||||
cmp::{max, min},
|
||||
error::Error, io::{stdout, Write},
|
||||
sync::{atomic::Ordering, Arc},
|
||||
sync::{atomic::{AtomicUsize, Ordering}, Arc, RwLock},
|
||||
thread,
|
||||
time::Duration
|
||||
};
|
||||
@ -20,11 +20,11 @@ use super::{
|
||||
config::Context,
|
||||
proto::{connect, read_messages},
|
||||
util::{char_index_to_byte_index, string_chunks}
|
||||
}, format_message, on_send_message
|
||||
}, format_message, on_send_message, set_chat, ChatStorage
|
||||
};
|
||||
|
||||
|
||||
pub fn print_console(ctx: Arc<Context>, messages: Vec<String>, input: &str) -> Result<(), Box<dyn Error>> {
|
||||
fn print_console(ctx: Arc<Context>, messages: Vec<String>, input: &str) -> Result<(), Box<dyn Error>> {
|
||||
let (width, height) = terminal::size()?;
|
||||
let (width, height) = (width as usize, height as usize);
|
||||
|
||||
@ -43,7 +43,7 @@ pub fn print_console(ctx: Arc<Context>, messages: Vec<String>, input: &str) -> R
|
||||
0
|
||||
};
|
||||
|
||||
let scroll = min(ctx.scroll.load(Ordering::SeqCst), messages_size);
|
||||
let scroll = min(ctx.chat().scroll.load(Ordering::SeqCst), messages_size);
|
||||
let scroll_f = ((1f64 - scroll as f64 / (messages_size+1) as f64) * (height-2) as f64).round() as usize+1;
|
||||
|
||||
let messages = if height < messages.len() {
|
||||
@ -143,8 +143,8 @@ fn poll_events(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
let mut history_cursor: usize = 0;
|
||||
let mut cursor: usize = 0;
|
||||
|
||||
let input = ctx.input.clone();
|
||||
let messages = ctx.messages.clone();
|
||||
let input = ctx.chat().input.clone();
|
||||
let messages = ctx.chat().messages.clone();
|
||||
|
||||
loop {
|
||||
if !event::poll(Duration::from_millis(50)).unwrap_or(false) { continue }
|
||||
@ -171,8 +171,8 @@ fn poll_events(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
|
||||
if let Err(e) = on_send_message(ctx.clone(), &message) {
|
||||
let msg = format!("Send message error: {}", e.to_string()).bright_red().to_string();
|
||||
ctx.messages.append(ctx.max_messages, vec![msg]);
|
||||
print_console(ctx.clone(), ctx.messages.messages(), &ctx.input.read().unwrap())?;
|
||||
ctx.chat().messages.append(ctx.max_messages, vec![msg]);
|
||||
print_console(ctx.clone(), ctx.chat().messages.messages(), &ctx.chat().input.read().unwrap())?;
|
||||
}
|
||||
} else {
|
||||
print_console(
|
||||
@ -220,7 +220,11 @@ fn poll_events(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
KeyCode::PageUp => {
|
||||
let height = terminal::size().unwrap().1 as usize;
|
||||
ctx.scroll.store(min(ctx.scroll.load(Ordering::SeqCst)+height, ctx.messages.messages().len()), Ordering::SeqCst);
|
||||
ctx.chat().scroll.store(min(
|
||||
ctx.chat().scroll.load(Ordering::SeqCst)+height,
|
||||
ctx.chat().messages.messages().len()
|
||||
),
|
||||
Ordering::SeqCst);
|
||||
print_console(
|
||||
ctx.clone(),
|
||||
messages.messages(),
|
||||
@ -229,7 +233,11 @@ fn poll_events(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
KeyCode::PageDown => {
|
||||
let height = terminal::size().unwrap().1 as usize;
|
||||
ctx.scroll.store(max(ctx.scroll.load(Ordering::SeqCst), height)-height, Ordering::SeqCst);
|
||||
ctx.chat().scroll.store(max(
|
||||
ctx.chat().scroll.load(Ordering::SeqCst),
|
||||
height
|
||||
)-height,
|
||||
Ordering::SeqCst);
|
||||
print_console(
|
||||
ctx.clone(),
|
||||
messages.messages(),
|
||||
@ -289,7 +297,10 @@ fn poll_events(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
Event::Mouse(data) => {
|
||||
match data.kind {
|
||||
MouseEventKind::ScrollUp => {
|
||||
ctx.scroll.store(min(ctx.scroll.load(Ordering::SeqCst)+3, ctx.messages.messages().len()), Ordering::SeqCst);
|
||||
ctx.chat().scroll.store(min(
|
||||
ctx.chat().scroll.load(Ordering::SeqCst)+3,
|
||||
ctx.chat().messages.messages().len()
|
||||
), Ordering::SeqCst);
|
||||
print_console(
|
||||
ctx.clone(),
|
||||
messages.messages(),
|
||||
@ -297,7 +308,7 @@ fn poll_events(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
)?;
|
||||
},
|
||||
MouseEventKind::ScrollDown => {
|
||||
ctx.scroll.store(max(ctx.scroll.load(Ordering::SeqCst), 3)-3, Ordering::SeqCst);
|
||||
ctx.chat().scroll.store(max(ctx.chat().scroll.load(Ordering::SeqCst), 3)-3, Ordering::SeqCst);
|
||||
print_console(
|
||||
ctx.clone(),
|
||||
messages.messages(),
|
||||
@ -314,11 +325,11 @@ fn poll_events(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn recv_tick(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
fn recv_tick(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
match read_messages(
|
||||
&mut connect(&ctx.host, ctx.enable_ssl)?,
|
||||
ctx.max_messages,
|
||||
ctx.messages.packet_size(),
|
||||
ctx.chat().messages.packet_size(),
|
||||
!ctx.enable_ssl,
|
||||
ctx.enable_chunked
|
||||
) {
|
||||
@ -330,17 +341,17 @@ pub fn recv_tick(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
};
|
||||
|
||||
if ctx.enable_chunked {
|
||||
ctx.messages.append_and_store(ctx.max_messages, messages.clone(), size);
|
||||
print_console(ctx.clone(), ctx.messages.messages(), &ctx.input.read().unwrap())?;
|
||||
ctx.chat().messages.append_and_store(ctx.max_messages, messages.clone(), size);
|
||||
print_console(ctx.clone(), ctx.chat().messages.messages(), &ctx.chat().input.read().unwrap())?;
|
||||
} else {
|
||||
ctx.messages.update(ctx.max_messages, messages.clone(), size);
|
||||
print_console(ctx.clone(), messages, &ctx.input.read().unwrap())?;
|
||||
ctx.chat().messages.update(ctx.max_messages, messages.clone(), size);
|
||||
print_console(ctx.clone(), messages, &ctx.chat().input.read().unwrap())?;
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
let msg = format!("Read messages error: {}", e.to_string()).bright_red().to_string();
|
||||
ctx.messages.append(ctx.max_messages, vec![msg]);
|
||||
print_console(ctx.clone(), ctx.messages.messages(), &ctx.input.read().unwrap())?;
|
||||
ctx.chat().messages.append(ctx.max_messages, vec![msg]);
|
||||
print_console(ctx.clone(), ctx.chat().messages.messages(), &ctx.chat().input.read().unwrap())?;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -348,23 +359,39 @@ pub fn recv_tick(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn on_close() {
|
||||
fn on_close() {
|
||||
disable_raw_mode().unwrap();
|
||||
execute!(stdout(), event::DisableMouseCapture).unwrap();
|
||||
}
|
||||
|
||||
pub fn update_console(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||
print_console(ctx.clone(), ctx.messages.messages(), &ctx.input.read().unwrap())
|
||||
|
||||
pub struct ChatContext {
|
||||
pub messages: Arc<ChatStorage>,
|
||||
pub input: Arc<RwLock<String>>,
|
||||
pub registered: Arc<RwLock<Option<String>>>,
|
||||
pub scroll: Arc<AtomicUsize>,
|
||||
}
|
||||
|
||||
pub fn print_message(ctx: Arc<Context>, message: String) -> Result<(), Box<dyn Error>> {
|
||||
ctx.chat().messages.append(ctx.max_messages, vec![message]);
|
||||
print_console(ctx.clone(), ctx.chat().messages.messages(), &ctx.chat().input.read().unwrap())
|
||||
}
|
||||
|
||||
pub fn run_main_loop(ctx: Arc<Context>) {
|
||||
set_chat(ctx.clone(), ChatContext {
|
||||
messages: Arc::new(ChatStorage::new()),
|
||||
input: Arc::new(RwLock::new(String::new())),
|
||||
registered: Arc::new(RwLock::new(None)),
|
||||
scroll: Arc::new(AtomicUsize::new(0)),
|
||||
});
|
||||
|
||||
enable_raw_mode().unwrap();
|
||||
execute!(stdout(), event::EnableMouseCapture).unwrap();
|
||||
|
||||
if let Err(e) = print_console(ctx.clone(), Vec::new(), &ctx.input.read().unwrap()) {
|
||||
if let Err(e) = print_console(ctx.clone(), Vec::new(), &ctx.chat().input.read().unwrap()) {
|
||||
let msg = format!("Print messages error: {}", e.to_string()).bright_red().to_string();
|
||||
ctx.messages.append(ctx.max_messages, vec![msg]);
|
||||
let _ = print_console(ctx.clone(), ctx.messages.messages(), &ctx.input.read().unwrap());
|
||||
ctx.chat().messages.append(ctx.max_messages, vec![msg]);
|
||||
let _ = print_console(ctx.clone(), ctx.chat().messages.messages(), &ctx.chat().input.read().unwrap());
|
||||
}
|
||||
|
||||
thread::spawn({
|
||||
@ -374,8 +401,8 @@ pub fn run_main_loop(ctx: Arc<Context>) {
|
||||
loop {
|
||||
if let Err(e) = recv_tick(ctx.clone()) {
|
||||
let msg = format!("Print messages error: {}", e.to_string()).bright_red().to_string();
|
||||
ctx.messages.append(ctx.max_messages, vec![msg]);
|
||||
let _ = print_console(ctx.clone(), ctx.messages.messages(), &ctx.input.read().unwrap());
|
||||
ctx.chat().messages.append(ctx.max_messages, vec![msg]);
|
||||
let _ = print_console(ctx.clone(), ctx.chat().messages.messages(), &ctx.chat().input.read().unwrap());
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
}
|
||||
@ -384,7 +411,7 @@ pub fn run_main_loop(ctx: Arc<Context>) {
|
||||
|
||||
if let Err(e) = poll_events(ctx.clone()) {
|
||||
let msg = format!("Poll events error: {}", e.to_string()).bright_red().to_string();
|
||||
ctx.messages.append(ctx.max_messages, vec![msg]);
|
||||
let _ = print_console(ctx.clone(), ctx.messages.messages(), &ctx.input.read().unwrap());
|
||||
ctx.chat().messages.append(ctx.max_messages, vec![msg]);
|
||||
let _ = print_console(ctx.clone(), ctx.chat().messages.messages(), &ctx.chat().input.read().unwrap());
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use std::{str::FromStr, sync::{atomic::AtomicUsize, Arc, RwLock}};
|
||||
use std::{str::FromStr, sync::{Arc, RwLock}};
|
||||
#[allow(unused_imports)]
|
||||
use std::{env, fs, path::{Path, PathBuf}, thread, time::Duration};
|
||||
use colored::Colorize;
|
||||
@ -6,7 +6,7 @@ use rand::random;
|
||||
use serde_yml;
|
||||
use clap::Parser;
|
||||
|
||||
use crate::chat::ChatStorage;
|
||||
use crate::chat::ChatContext;
|
||||
|
||||
use super::util::get_input;
|
||||
|
||||
@ -209,11 +209,9 @@ pub struct Args {
|
||||
}
|
||||
|
||||
pub struct Context {
|
||||
pub messages: Arc<ChatStorage>,
|
||||
pub input: Arc<RwLock<String>>,
|
||||
pub chat: Arc<RwLock<Option<Arc<ChatContext>>>>,
|
||||
pub host: String,
|
||||
pub name: String,
|
||||
pub registered: Arc<RwLock<Option<String>>>,
|
||||
pub disable_formatting: bool,
|
||||
pub disable_commands: bool,
|
||||
pub disable_hiding_ip: bool,
|
||||
@ -221,7 +219,6 @@ pub struct Context {
|
||||
pub update_time: usize,
|
||||
pub max_messages: usize,
|
||||
pub enable_ip_viewing: bool,
|
||||
pub scroll: Arc<AtomicUsize>,
|
||||
pub enable_auth: bool,
|
||||
pub enable_ssl: bool,
|
||||
pub enable_chunked: bool,
|
||||
@ -230,22 +227,23 @@ pub struct Context {
|
||||
impl Context {
|
||||
pub fn new(config: &Config, args: &Args) -> Context {
|
||||
Context {
|
||||
messages: Arc::new(ChatStorage::new()),
|
||||
input: Arc::new(RwLock::new(String::new())),
|
||||
chat: Arc::new(RwLock::new(None)),
|
||||
message_format: args.message_format.clone().unwrap_or(config.message_format.clone()),
|
||||
host: args.host.clone().unwrap_or(config.host.clone()),
|
||||
name: args.name.clone().or(config.name.clone()).unwrap_or_else(|| ask_string("Name", format!("Anon#{:X}", random::<u16>()))),
|
||||
registered: Arc::new(RwLock::new(None)),
|
||||
disable_formatting: args.disable_formatting,
|
||||
disable_commands: args.disable_commands,
|
||||
disable_hiding_ip: args.disable_ip_hiding,
|
||||
update_time: config.update_time,
|
||||
max_messages: config.max_messages,
|
||||
enable_ip_viewing: args.enable_users_ip_viewing || config.enable_ip_viewing,
|
||||
scroll: Arc::new(AtomicUsize::new(0)),
|
||||
enable_auth: args.enable_auth || config.enable_auth,
|
||||
enable_ssl: args.enable_ssl || config.enable_ssl,
|
||||
enable_chunked: args.enable_chunked || config.enable_chunked,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn chat(&self) -> Arc<ChatContext> {
|
||||
self.chat.read().unwrap().clone().unwrap()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user