boardcast + interval tick.

This commit is contained in:
Ivan Li 2023-04-03 23:19:45 +08:00
parent a1e6c6e5fb
commit 3ec983cd95
7 changed files with 313 additions and 372 deletions

300
src-tauri/Cargo.lock generated
View File

@ -34,9 +34,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.69"
version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
[[package]]
name = "async-channel"
@ -70,7 +70,7 @@ dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps 6.0.3",
"system-deps 6.0.4",
]
[[package]]
@ -135,9 +135,9 @@ dependencies = [
[[package]]
name = "bstr"
version = "1.3.0"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ffdb39cb703212f3c11973452c2861b972f757b021158f3516ba10f2fa8b2c1"
checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09"
dependencies = [
"memchr",
"serde",
@ -182,7 +182,7 @@ checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8"
dependencies = [
"glib-sys",
"libc",
"system-deps 6.0.3",
"system-deps 6.0.4",
]
[[package]]
@ -228,9 +228,9 @@ dependencies = [
[[package]]
name = "cfg-expr"
version = "0.11.0"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0357a6402b295ca3a86bc148e84df46c02e41f41fef186bda662557ef6328aa"
checksum = "a35b255461940a32985c627ce82900867c61db1659764d3675ea81963f72a4c6"
dependencies = [
"smallvec",
]
@ -243,9 +243,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cmake"
version = "0.1.49"
version = "0.1.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c"
checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130"
dependencies = [
"cc",
]
@ -268,9 +268,9 @@ dependencies = [
[[package]]
name = "cocoa-foundation"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318"
checksum = "931d3837c286f56e3c58423ce4eba12d08db2374461a785c86f672b08b5650d6"
dependencies = [
"bitflags",
"block",
@ -361,9 +361,9 @@ dependencies = [
[[package]]
name = "cpufeatures"
version = "0.2.5"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181"
dependencies = [
"libc",
]
@ -420,7 +420,7 @@ dependencies = [
"proc-macro2",
"quote",
"smallvec",
"syn",
"syn 1.0.109",
]
[[package]]
@ -430,7 +430,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e"
dependencies = [
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -440,7 +440,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
dependencies = [
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -464,7 +464,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
"syn",
"syn 1.0.109",
]
[[package]]
@ -475,7 +475,7 @@ checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835"
dependencies = [
"darling_core",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -488,7 +488,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustc_version",
"syn",
"syn 1.0.109",
]
[[package]]
@ -599,13 +599,13 @@ dependencies = [
[[package]]
name = "errno"
version = "0.2.8"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0"
dependencies = [
"errno-dragonfly",
"libc",
"winapi",
"windows-sys 0.45.0",
]
[[package]]
@ -651,7 +651,7 @@ checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"redox_syscall 0.2.16",
"windows-sys 0.45.0",
]
@ -707,9 +707,9 @@ dependencies = [
[[package]]
name = "futures"
version = "0.3.27"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "531ac96c6ff5fd7c62263c5e3c67a603af4fcaee2e1a0ae5565ba3a11e69e549"
checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
dependencies = [
"futures-channel",
"futures-core",
@ -722,9 +722,9 @@ dependencies = [
[[package]]
name = "futures-channel"
version = "0.3.27"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac"
checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
dependencies = [
"futures-core",
"futures-sink",
@ -732,15 +732,15 @@ dependencies = [
[[package]]
name = "futures-core"
version = "0.3.27"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd"
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
[[package]]
name = "futures-executor"
version = "0.3.27"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1997dd9df74cdac935c76252744c1ed5794fac083242ea4fe77ef3ed60ba0f83"
checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
dependencies = [
"futures-core",
"futures-task",
@ -749,32 +749,32 @@ dependencies = [
[[package]]
name = "futures-io"
version = "0.3.27"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d422fa3cbe3b40dca574ab087abb5bc98258ea57eea3fd6f1fa7162c778b91"
checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
[[package]]
name = "futures-macro"
version = "0.3.27"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6"
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.13",
]
[[package]]
name = "futures-sink"
version = "0.3.27"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2"
checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
[[package]]
name = "futures-task"
version = "0.3.27"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879"
checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
[[package]]
name = "futures-timer"
@ -784,9 +784,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
[[package]]
name = "futures-util"
version = "0.3.27"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab"
checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
dependencies = [
"futures-channel",
"futures-core",
@ -848,7 +848,7 @@ dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps 6.0.3",
"system-deps 6.0.4",
]
[[package]]
@ -865,7 +865,7 @@ dependencies = [
"libc",
"pango-sys",
"pkg-config",
"system-deps 6.0.3",
"system-deps 6.0.4",
]
[[package]]
@ -877,7 +877,7 @@ dependencies = [
"gdk-sys",
"glib-sys",
"libc",
"system-deps 6.0.3",
"system-deps 6.0.4",
"x11",
]
@ -896,9 +896,9 @@ dependencies = [
[[package]]
name = "generic-array"
version = "0.14.6"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
@ -952,7 +952,7 @@ dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps 6.0.3",
"system-deps 6.0.4",
"winapi",
]
@ -978,9 +978,9 @@ dependencies = [
[[package]]
name = "glib-macros"
version = "0.15.11"
version = "0.15.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a68131a662b04931e71891fb14aaf65ee4b44d08e8abc10f49e77418c86c64"
checksum = "10c6ae9f6fa26f4fb2ac16b528d138d971ead56141de489f8111e259b9df3c4a"
dependencies = [
"anyhow",
"heck 0.4.1",
@ -988,7 +988,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -998,7 +998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef4b192f8e65e9cf76cbf4ea71fa8e3be4a0e18ffe3d68b8da6836974cc5bad4"
dependencies = [
"libc",
"system-deps 6.0.3",
"system-deps 6.0.4",
]
[[package]]
@ -1028,7 +1028,7 @@ checksum = "0d57ce44246becd17153bd035ab4d32cfee096a657fc01f2231c9278378d1e0a"
dependencies = [
"glib-sys",
"libc",
"system-deps 6.0.3",
"system-deps 6.0.4",
]
[[package]]
@ -1069,21 +1069,21 @@ dependencies = [
"gobject-sys",
"libc",
"pango-sys",
"system-deps 6.0.3",
"system-deps 6.0.4",
]
[[package]]
name = "gtk3-macros"
version = "0.15.4"
version = "0.15.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24f518afe90c23fba585b2d7697856f9e6a7bbc62f65588035e66f6afb01a2e9"
checksum = "684c0456c086e8e7e9af73ec5b84e35938df394712054550e81558d21c44ab0d"
dependencies = [
"anyhow",
"proc-macro-crate",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -1139,7 +1139,7 @@ dependencies = [
"markup5ever",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -1211,9 +1211,9 @@ dependencies = [
[[package]]
name = "image"
version = "0.24.5"
version = "0.24.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945"
checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a"
dependencies = [
"bytemuck",
"byteorder",
@ -1224,9 +1224,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "1.9.2"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown",
@ -1252,19 +1252,20 @@ dependencies = [
[[package]]
name = "io-lifetimes"
version = "1.0.6"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfa919a82ea574332e2de6e74b4c36e74d41982b335080fa59d4ef31be20fdf3"
checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb"
dependencies = [
"hermit-abi 0.3.1",
"libc",
"windows-sys 0.45.0",
]
[[package]]
name = "is-terminal"
version = "0.4.4"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b6b32576413a8e69b90e952e4a026476040d81017b80445deda5f2d3921857"
checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8"
dependencies = [
"hermit-abi 0.3.1",
"io-lifetimes",
@ -1382,9 +1383,9 @@ dependencies = [
[[package]]
name = "linux-raw-sys"
version = "0.1.4"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f"
[[package]]
name = "lock_api"
@ -1608,7 +1609,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -1647,20 +1648,20 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
name = "open"
version = "3.4.0"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21ecf2487e799604735754d2c5896106785987b441b5aee58f242e4d4963179a"
checksum = "2078c0039e6a54a0c42c28faa984e115fb4c2d5bf2208f77d1961002df8576f8"
dependencies = [
"pathdiff",
"windows-sys 0.42.0",
]
[[package]]
name = "openssl-sys"
version = "0.9.83"
version = "0.9.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b"
checksum = "3a20eace9dc2d82904039cb76dcf50fb1a0bba071cfd1629720b5d6f1ddba0fa"
dependencies = [
"autocfg",
"cc",
"libc",
"pkg-config",
@ -1721,14 +1722,14 @@ dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps 6.0.3",
"system-deps 6.0.4",
]
[[package]]
name = "paris"
version = "1.5.13"
version = "1.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2eaf2319cd71dd9ff38c72bebde61b9ea657134abcf26ae4205f54f772a32810"
checksum = "8fecab3723493c7851f292cb060f3ee1c42f19b8d749345d0d7eaf3fd19aa62d"
[[package]]
name = "parking_lot"
@ -1748,7 +1749,7 @@ checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"redox_syscall 0.2.16",
"smallvec",
"windows-sys 0.45.0",
]
@ -1834,7 +1835,7 @@ dependencies = [
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -1848,7 +1849,7 @@ dependencies = [
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -1889,14 +1890,14 @@ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
[[package]]
name = "plist"
version = "1.4.2"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffac6a51110e97610dd3ac73e34a65b27e56a1e305df41bad1f616d8e1cb22f4"
checksum = "9bd9647b268a3d3e14ff09c23201133a62589c658db02bb7388c7246aafe0590"
dependencies = [
"base64 0.21.0",
"indexmap",
"line-wrap",
"quick-xml 0.27.1",
"quick-xml 0.28.1",
"serde",
"time",
]
@ -1944,7 +1945,7 @@ dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
"version_check",
]
@ -1967,9 +1968,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
[[package]]
name = "proc-macro2"
version = "1.0.52"
version = "1.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224"
checksum = "1d0dd4be24fcdcfeaa12a432d588dc59bbad6cad3510c67e74a2b6b2fc950564"
dependencies = [
"unicode-ident",
]
@ -1985,9 +1986,9 @@ dependencies = [
[[package]]
name = "quick-xml"
version = "0.27.1"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffc053f057dd768a56f62cd7e434c42c831d296968997e9ac1f76ea7c2d14c41"
checksum = "e5c1a97b1bc42b1d550bfb48d4262153fe400a12bab1511821736f7eac76d7e2"
dependencies = [
"memchr",
]
@ -2084,9 +2085,9 @@ dependencies = [
[[package]]
name = "raw-window-handle"
version = "0.5.1"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f851a03551ceefd30132e447f07f96cb7011d6b658374f3aed847333adb5559"
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
[[package]]
name = "redox_syscall"
@ -2097,6 +2098,15 @@ dependencies = [
"bitflags",
]
[[package]]
name = "redox_syscall"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_users"
version = "0.4.3"
@ -2104,15 +2114,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
dependencies = [
"getrandom 0.2.8",
"redox_syscall",
"redox_syscall 0.2.16",
"thiserror",
]
[[package]]
name = "regex"
version = "1.7.1"
version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d"
dependencies = [
"aho-corasick",
"memchr",
@ -2130,9 +2140,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.28"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "rustc_version"
@ -2145,9 +2155,9 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.36.9"
version = "0.37.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc"
checksum = "d097081ed288dfe45699b72f5b5d648e5f15d64d900c7080273baa20c16a6849"
dependencies = [
"bitflags",
"errno",
@ -2227,29 +2237,29 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.156"
version = "1.0.159"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "314b5b092c0ade17c00142951e50ced110ec27cea304b1037c6969246c2469a4"
checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.156"
version = "1.0.159"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7e29c4601e36bcec74a223228dce795f4cd3616341a4af93520ca1a837c087d"
checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.13",
]
[[package]]
name = "serde_json"
version = "1.0.94"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea"
checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744"
dependencies = [
"itoa 1.0.6",
"ryu",
@ -2258,13 +2268,13 @@ dependencies = [
[[package]]
name = "serde_repr"
version = "0.1.11"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "395627de918015623b32e7669714206363a7fc00382bf477e72c1f7533e8eafc"
checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.13",
]
[[package]]
@ -2295,7 +2305,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -2317,7 +2327,7 @@ checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -2476,6 +2486,17 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "system-deps"
version = "5.0.0"
@ -2491,14 +2512,14 @@ dependencies = [
[[package]]
name = "system-deps"
version = "6.0.3"
version = "6.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2955b1fe31e1fa2fbd1976b71cc69a606d7d4da16f6de3333d0c92d51419aeff"
checksum = "555fc8147af6256f3931a36bb83ad0023240ce9cf2b319dec8236fd1f220b05f"
dependencies = [
"cfg-expr 0.11.0",
"cfg-expr 0.14.0",
"heck 0.4.1",
"pkg-config",
"toml 0.5.11",
"toml 0.7.3",
"version-compare 0.1.1",
]
@ -2657,7 +2678,7 @@ dependencies = [
"heck 0.4.1",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
"tauri-codegen",
"tauri-utils",
]
@ -2732,15 +2753,15 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.4.0"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95"
checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
dependencies = [
"cfg-if",
"fastrand",
"redox_syscall",
"redox_syscall 0.3.5",
"rustix",
"windows-sys 0.42.0",
"windows-sys 0.45.0",
]
[[package]]
@ -2796,22 +2817,22 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
[[package]]
name = "thiserror"
version = "1.0.39"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c"
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.39"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e"
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.13",
]
[[package]]
@ -2868,14 +2889,13 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.26.0"
version = "1.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64"
checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001"
dependencies = [
"autocfg",
"bytes",
"libc",
"memchr",
"mio",
"num_cpus",
"parking_lot",
@ -2888,13 +2908,13 @@ dependencies = [
[[package]]
name = "tokio-macros"
version = "1.8.2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.13",
]
[[package]]
@ -2929,9 +2949,9 @@ dependencies = [
[[package]]
name = "toml_edit"
version = "0.19.7"
version = "0.19.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc18466501acd8ac6a3f615dd29a3438f8ca6bb3b19537138b3106e575621274"
checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13"
dependencies = [
"indexmap",
"serde",
@ -2960,7 +2980,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -3019,9 +3039,9 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "unicode-bidi"
version = "0.3.11"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524b68aca1d05e03fdf03fcdce2c6c94b6daf6d16861ddaa7e4f2b6638a9052c"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
[[package]]
name = "unicode-ident"
@ -3188,7 +3208,7 @@ dependencies = [
"pango-sys",
"pkg-config",
"soup2-sys",
"system-deps 6.0.3",
"system-deps 6.0.4",
]
[[package]]
@ -3211,7 +3231,7 @@ checksum = "eaebe196c01691db62e9e4ca52c5ef1e4fd837dcae27dae3ada599b5a8fd05ac"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@ -3305,7 +3325,7 @@ version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba01f98f509cb5dc05f4e5fc95e535f78260f15fea8fe1a8abdd08f774f1cee7"
dependencies = [
"syn",
"syn 1.0.109",
"windows-tokens",
]
@ -3434,9 +3454,9 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "winnow"
version = "0.3.6"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d020b441f92996c80d94ae9166e8501e59c7bb56121189dc9eab3bd8216966"
checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28"
dependencies = [
"memchr",
]

View File

@ -1,4 +1,4 @@
use std::{sync::Arc, time::Duration};
use std::{collections::HashMap, sync::Arc, time::Duration};
use paris::{info, warn};
use tauri::async_runtime::{Mutex, RwLock};
@ -6,9 +6,10 @@ use tokio::{sync::watch, time::sleep};
use crate::{
ambient_light::{config, ConfigManager},
led_color::LedColor,
rpc::MqttRpc,
screenshot::Screenshot,
screenshot_manager::ScreenshotManager, led_color::LedColor,
screenshot::{self, Screenshot},
screenshot_manager::ScreenshotManager,
};
use itertools::Itertools;
@ -57,67 +58,76 @@ impl LedColorsPublisher {
let configs = config_receiver.borrow().clone();
let configs = Self::get_colors_configs(&configs).await;
let mut some_screenshot_receiver_is_none = false;
if let Err(err) = configs {
warn!("Failed to get configs: {}", err);
sleep(Duration::from_millis(100)).await;
continue;
}
let configs = configs.unwrap();
let mut merged_screenshot_receiver =
screenshot_manager.clone_merged_screenshot_rx().await;
let mut screenshots = HashMap::new();
loop {
let mut screenshots = Vec::new();
let screenshot = merged_screenshot_receiver.recv().await;
for rx in configs.screenshot_receivers.to_owned() {
let mut rx = rx.lock_owned().await;
if rx.is_none() {
some_screenshot_receiver_is_none = true;
warn!("screenshot receiver is none");
continue;
}
let rx = rx.as_mut().unwrap();
if let Err(err) = rx.changed().await {
warn!("rx changed error: {}", err);
continue;
}
// log::info!("screenshot updated");
let screenshot = rx.borrow().clone();
screenshots.push(screenshot);
}
let colors = screenshot_manager
.get_all_colors(&configs.sample_point_groups, &screenshots)
.await;
let sorted_colors =
ScreenshotManager::get_sorted_colors(&colors, &configs.mappers).await;
match colors_tx.send(colors) {
Ok(_) => {
// log::info!("colors updated");
}
Err(_) => {
warn!("colors update failed");
if let Err(err) = screenshot {
match err {
tokio::sync::broadcast::error::RecvError::Closed => {
warn!("closed");
continue;
},
tokio::sync::broadcast::error::RecvError::Lagged(_) => {
warn!("lagged");
continue;
},
}
}
match sorted_colors_tx.send(sorted_colors) {
Ok(_) => {
// log::info!("colors updated");
}
Err(_) => {
warn!("colors update failed");
}
}
let screenshot = screenshot.unwrap();
// log::info!("got screenshot: {:?}", screenshot.display_id);
if some_screenshot_receiver_is_none {
info!("some screenshot receiver is none. reload.");
sleep(Duration::from_millis(1000)).await;
break;
}
screenshots.insert(screenshot.display_id, screenshot);
if config_receiver.has_changed().unwrap_or(true) {
info!("config changed. reload.");
sleep(Duration::from_millis(100)).await;
break;
if screenshots.len() == configs.sample_point_groups.len() {
{
let screenshots = configs
.sample_point_groups
.iter()
.map(|strip| screenshots.get(&strip.display_id).unwrap())
.collect::<Vec<_>>();
let colors = screenshot_manager
.get_all_colors(&configs.sample_point_groups, &screenshots)
.await;
let sorted_colors =
ScreenshotManager::get_sorted_colors(&colors, &configs.mappers)
.await;
match colors_tx.send(colors) {
Ok(_) => {
// log::info!("colors updated");
}
Err(_) => {
warn!("colors update failed");
}
}
match sorted_colors_tx.send(sorted_colors) {
Ok(_) => {
// log::info!("colors updated");
}
Err(_) => {
warn!("colors update failed");
}
}
}
screenshots.clear();
}
}
}
@ -158,8 +168,9 @@ impl LedColorsPublisher {
pub async fn clone_sorted_colors_receiver(&self) -> watch::Receiver<Vec<u8>> {
self.sorted_colors_rx.read().await.clone()
}
pub async fn get_colors_configs(configs: &LedStripConfigGroup) -> AllColorConfig {
pub async fn get_colors_configs(
configs: &LedStripConfigGroup,
) -> anyhow::Result<AllColorConfig> {
let screenshot_manager = ScreenshotManager::global().await;
let channels = screenshot_manager.channels.read().await;
@ -180,11 +191,13 @@ impl LedColorsPublisher {
let display_id = *display_id;
let channel = channels.get(&display_id);
let channel = match channel {
Some(channel) => Some(channel.clone()),
None => None,
};
local_rx_list.push(Arc::new(Mutex::new(channel.clone())));
if channel.is_none() {
anyhow::bail!("no channel for display_id: {}", display_id);
}
let channel_rx = channel.unwrap().clone();
local_rx_list.push(channel.unwrap().clone());
let led_strip_configs: Vec<_> = configs
.strips
@ -192,39 +205,31 @@ impl LedColorsPublisher {
.filter(|c| c.display_id == display_id)
.collect();
let rx = channel;
if rx.is_none() {
warn!("no channel for display_id: {}", display_id);
continue;
}
if led_strip_configs.len() == 0 {
warn!("no led strip config for display_id: {}", display_id);
continue;
}
let mut rx = rx.unwrap().to_owned();
let rx = channel_rx.to_owned();
if rx.changed().await.is_ok() {
let screenshot = rx.borrow().clone();
log::info!("screenshot updated: {:?}", display_id);
let screenshot = rx.borrow().clone();
log::debug!("screenshot updated: {:?}", display_id);
let points: Vec<_> = led_strip_configs
.iter()
.map(|config| screenshot.get_sample_points(&config))
.flatten()
.collect();
let points: Vec<_> = led_strip_configs
.iter()
.map(|config| screenshot.get_sample_points(&config))
.flatten()
.collect();
let colors_config = config::SamplePointConfig { display_id, points };
let colors_config = config::SamplePointConfig { display_id, points };
colors_configs.push(colors_config);
}
colors_configs.push(colors_config);
}
return AllColorConfig {
return Ok(AllColorConfig {
sample_point_groups: colors_configs,
mappers,
screenshot_receivers: local_rx_list,
};
});
}
pub async fn clone_colors_receiver(&self) -> watch::Receiver<Vec<LedColor>> {
@ -232,8 +237,9 @@ impl LedColorsPublisher {
}
}
#[derive(Debug)]
pub struct AllColorConfig {
pub sample_point_groups: Vec<SamplePointConfig>,
pub mappers: Vec<config::SamplePointMapper>,
pub screenshot_receivers: Vec<Arc<Mutex<Option<watch::Receiver<Screenshot>>>>>,
pub screenshot_receivers: Vec<watch::Receiver<Screenshot>>,
}

View File

@ -57,21 +57,6 @@ fn list_display_info() -> Result<String, String> {
Ok(json_str)
}
#[tauri::command]
async fn subscribe_encoded_screenshot_updated(
window: tauri::Window,
display_id: u32,
) -> Result<(), String> {
let screenshot_manager = ScreenshotManager::global().await;
screenshot_manager
.subscribe_encoded_screenshot_updated(window, display_id)
.await
.map_err(|err| {
error!("subscribe_encoded_screenshot_updated: {}", err);
err.to_string()
})
}
#[tauri::command]
async fn read_led_strip_configs() -> Result<LedStripConfigGroup, String> {
let config = ambient_light::LedStripConfigGroup::read_config()
@ -201,7 +186,6 @@ async fn main() {
.invoke_handler(tauri::generate_handler![
greet,
list_display_info,
subscribe_encoded_screenshot_updated,
read_led_strip_configs,
write_led_strip_configs,
get_led_strips_sample_points,

View File

@ -3,14 +3,15 @@ use std::{collections::HashMap, sync::Arc};
use core_graphics::display::{
kCGNullWindowID, kCGWindowImageDefault, kCGWindowListOptionOnScreenOnly, CGDisplay,
};
use paris::{error, info, warn};
use tauri::{async_runtime::RwLock, Window};
use tokio::sync::{watch, OnceCell};
use paris::warn;
use tauri::async_runtime::RwLock;
use tokio::sync::{broadcast, watch, OnceCell};
use tokio::time::{self, Duration};
use crate::{
ambient_light::{SamplePointConfig, SamplePointMapper},
led_color::LedColor,
screenshot::{ScreenSamplePoints, Screenshot, ScreenshotPayload},
screenshot::{ScreenSamplePoints, Screenshot},
};
pub fn take_screenshot(display_id: u32, scale_factor: f32) -> anyhow::Result<Screenshot> {
@ -54,7 +55,8 @@ pub fn take_screenshot(display_id: u32, scale_factor: f32) -> anyhow::Result<Scr
pub struct ScreenshotManager {
pub channels: Arc<RwLock<HashMap<u32, watch::Receiver<Screenshot>>>>,
encode_listeners: Arc<RwLock<HashMap<u32, Vec<Window>>>>,
merged_screenshot_rx: Arc<RwLock<broadcast::Receiver<Screenshot>>>,
merged_screenshot_tx: Arc<RwLock<broadcast::Sender<Screenshot>>>,
}
impl ScreenshotManager {
@ -64,10 +66,11 @@ impl ScreenshotManager {
SCREENSHOT_MANAGER
.get_or_init(|| async {
let channels = Arc::new(RwLock::new(HashMap::new()));
let encode_listeners = Arc::new(RwLock::new(HashMap::new()));
let (merged_screenshot_tx, merged_screenshot_rx) = broadcast::channel(2);
Self {
channels,
encode_listeners,
merged_screenshot_rx: Arc::new(RwLock::new(merged_screenshot_rx)),
merged_screenshot_tx: Arc::new(RwLock::new(merged_screenshot_tx)),
}
})
.await
@ -83,6 +86,7 @@ impl ScreenshotManager {
fn start_one(&self, display_id: u32, scale_factor: f32) -> anyhow::Result<()> {
let channels = self.channels.to_owned();
let merged_screenshot_tx = self.merged_screenshot_tx.clone();
tokio::spawn(async move {
let screenshot = take_screenshot(display_id, scale_factor);
@ -90,126 +94,45 @@ impl ScreenshotManager {
warn!("take_screenshot_loop: {}", screenshot.err().unwrap());
return;
}
let mut interval = time::interval(Duration::from_millis(33));
let screenshot = screenshot.unwrap();
let (tx, rx) = watch::channel(screenshot);
let (screenshot_tx, screenshot_rx) = watch::channel(screenshot);
{
let channels = channels.clone();
let mut channels = channels.write().await;
channels.insert(display_id, rx);
channels.insert(display_id, screenshot_rx.clone());
}
let merged_screenshot_tx = merged_screenshot_tx.read().await.clone();
loop {
Self::take_screenshot_loop(display_id, scale_factor, &tx).await;
tokio::time::sleep(std::time::Duration::from_millis(20)).await;
// interval.tick().await;
Self::take_screenshot_loop(
display_id,
scale_factor,
&screenshot_tx,
&merged_screenshot_tx,
)
.await;
tokio::time::sleep(Duration::from_millis(20)).await;
}
});
Ok(())
}
pub async fn subscribe_encoded_screenshot_updated(
&self,
window: Window,
display_id: u32,
) -> anyhow::Result<()> {
let channels = self.channels.to_owned();
let encode_listeners = self.encode_listeners.to_owned();
// log::info!("subscribe_encoded_screenshot_updated. {}", display_id);
{
let encode_listeners = encode_listeners.read().await;
let listening_windows = encode_listeners.get(&display_id);
if listening_windows.is_some() && listening_windows.unwrap().contains(&window) {
log::debug!("subscribe_encoded_screenshot_updated: already listening. display#{}, window#{}", display_id, window.label());
return Ok(());
}
}
{
encode_listeners
.write()
.await
.entry(display_id)
.or_default()
.push(window);
}
tokio::spawn(async move {
info!("subscribe_encoded_screenshot_updated: start");
let channels = channels.read().await;
let rx = channels.get(&display_id);
if rx.is_none() {
error!(
"subscribe_encoded_screenshot_updated: can not find display_id {}",
display_id
);
return;
}
let mut rx = rx.unwrap().clone();
loop {
if let Err(err) = rx.changed().await {
error!(
"subscribe_encoded_screenshot_updated: can not wait rx {}",
err
);
break;
}
let encode_listeners = encode_listeners.read().await;
let windows = encode_listeners.get(&display_id);
if windows.is_none() || windows.unwrap().is_empty() {
info!("subscribe_encoded_screenshot_updated: no listener, stop");
break;
}
let screenshot = rx.borrow().clone();
// let base64_image = Self::encode_screenshot_to_base64(&screenshot).await;
let height = screenshot.height;
let width = screenshot.width;
// if base64_image.is_err() {
// error!(
// "subscribe_encoded_screenshot_updated: encode_screenshot_to_base64 error {}",
// base64_image.err().unwrap()
// );
// continue;
// }
// let base64_image = base64_image.unwrap();
for window in windows.unwrap().into_iter() {
// let base64_image = base64_image.clone();
let payload = ScreenshotPayload {
display_id,
// base64_image,
height,
width,
};
if let Err(err) = window.emit("encoded-screenshot-updated", payload) {
error!("subscribe_encoded_screenshot_updated: emit error {}", err)
} else {
log::debug!(
"subscribe_encoded_screenshot_updated: emit success. display#{}",
display_id
)
}
}
}
});
Ok(())
}
async fn unsubscribe_encoded_screenshot_updated(&self, display_id: u32) -> anyhow::Result<()> {
let channels = self.channels.to_owned();
let mut channels = channels.write().await;
channels.remove(&display_id);
Ok(())
}
async fn take_screenshot_loop(
display_id: u32,
scale_factor: f32,
tx: &watch::Sender<Screenshot>,
screenshot_tx: &watch::Sender<Screenshot>,
merged_screenshot_tx: &broadcast::Sender<Screenshot>,
) {
let screenshot = take_screenshot(display_id, scale_factor);
if let Ok(screenshot) = screenshot {
tx.send(screenshot).unwrap();
// log::info!("take_screenshot_loop: send success. display#{}", display_id)
screenshot_tx.send(screenshot.clone()).unwrap();
merged_screenshot_tx.send(screenshot).unwrap();
log::debug!("take_screenshot_loop: send success. display#{}", display_id)
} else {
warn!("take_screenshot_loop: {}", screenshot.err().unwrap());
}
@ -218,7 +141,7 @@ impl ScreenshotManager {
pub async fn get_all_colors(
&self,
configs: &Vec<SamplePointConfig>,
screenshots: &Vec<Screenshot>,
screenshots: &Vec<&Screenshot>,
) -> Vec<LedColor> {
let mut all_colors = vec![];
@ -287,4 +210,8 @@ impl ScreenshotManager {
});
global_colors
}
pub async fn clone_merged_screenshot_rx(&self) -> broadcast::Receiver<Screenshot> {
self.merged_screenshot_tx.read().await.subscribe()
}
}

View File

@ -1,4 +1,4 @@
import { createContext, createEffect, onCleanup } from 'solid-js';
import { createEffect, onCleanup } from 'solid-js';
import { invoke } from '@tauri-apps/api/tauri';
import { DisplayView } from './components/display-view';
import { DisplayListContainer } from './components/display-list-container';

View File

@ -116,25 +116,6 @@ const SorterItem: Component<{ strip: LedStripConfig; mapper: LedStripPixelMapper
createEffect(() => {
const fullLeds = new Array(ledStripStore.totalLedCount).fill(null);
// if (props.mapper.start < props.mapper.end) {
// for (
// let i = props.mapper.start, j = props.mapper.pos;
// i < props.mapper.end;
// i++, j++
// ) {
// fullLeds[i] = ledStripStore.colors[j];
// }
// } else {
// for (
// let i = props.mapper.start, j = props.mapper.pos;
// i >= props.mapper.end;
// i--, j++
// ) {
// fullLeds[i] = ledStripStore.colors[j];
// }
// }
// 优化上面的代码
const { start, end, pos } = props.mapper;
const isForward = start < end;
const step = isForward ? 1 : -1;
@ -197,7 +178,6 @@ const SorterResult: Component = () => {
return `linear-gradient(70deg, ${c1} 10%, ${c2})`;
});
console.log(fullLeds);
setFullLeds(fullLeds);
});

View File

@ -1,4 +1,3 @@
import { invoke } from '@tauri-apps/api';
import { convertFileSrc } from '@tauri-apps/api/tauri';
import {
Component,
@ -30,6 +29,7 @@ export const ScreenView: Component<ScreenViewProps> = (props) => {
width: number;
height: number;
} | null>(null);
const [hidden, setHidden] = createSignal(false);
const resetSize = () => {
const aspectRatio = canvas.width / canvas.height;
@ -103,6 +103,10 @@ export const ScreenView: Component<ScreenViewProps> = (props) => {
(async () => {
while (!stopped) {
if (hidden()) {
await new Promise((resolve) => setTimeout(resolve, 1000));
continue;
}
await frame();
}
})();
@ -128,6 +132,26 @@ export const ScreenView: Component<ScreenViewProps> = (props) => {
});
});
// update hidden
createEffect(() => {
const hide = () => {
setHidden(true);
console.log('hide');
};
const show = () => {
setHidden(false);
console.log('show');
};
window.addEventListener('focus', show);
window.addEventListener('blur', hide);
onCleanup(() => {
window.removeEventListener('focus', show);
window.removeEventListener('blur', hide);
});
});
return (
<div
ref={root!}