From 68f9978544663f50f5d99df631cc23bdabc28b50 Mon Sep 17 00:00:00 2001 From: Nerual Dreming Date: Wed, 14 Oct 2026 11:13:56 +0300 Subject: [PATCH 1/6] Welcome tab: report a problem through the issue forms, with the browser filled in The about section links to GitHub's choice of forms and passes the browser and system to the bug form; the forms point to the Bulka Telegram community. --- .github/ISSUE_TEMPLATE/config.yml | 6 ++--- website/src/data/changelog.json | 24 +++++++++++++++++ .../src/repl/components/panel/WelcomeTab.jsx | 26 +++++++++++++++++++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 7aed5ff6..5c80e737 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -3,6 +3,6 @@ contact_links: - name: Latest version / Последняя версия url: https://github.com/timoncool/bulka/releases/latest about: Many problems are already fixed in the newest release. · Многое уже исправлено в свежей версии. - - name: News and announcements / Новости (Telegram) - url: https://t.me/nerual_dreming - about: Releases and plans of the author. · Выпуски и планы автора. + - name: Bulka community / Сообщество Bulka (Telegram) + url: https://t.me/bulka_app + about: Questions, patterns and news. · Вопросы, паттерны и новости. diff --git a/website/src/data/changelog.json b/website/src/data/changelog.json index 7b3f10f2..13687dfe 100644 --- a/website/src/data/changelog.json +++ b/website/src/data/changelog.json @@ -5,10 +5,34 @@ "dateFormatted": "⚠️ ГЕНЕРИРУЕТСЯ АВТОМАТИЧЕСКИ", "changes": [] }, + { + "date": "2026-10-14", + "dateFormatted": "14 октября 2026", + "changes": [ + { + "type": "other", + "typeLabel": "Прочее", + "emoji": "📦", + "description": "Issue forms: bug, idea, question", + "scope": null, + "author": "Nerual Dreming", + "hash": "cd53c2308" + } + ] + }, { "date": "2026-10-12", "dateFormatted": "12 октября 2026", "changes": [ + { + "type": "fix", + "typeLabel": "Исправления", + "emoji": "🐛", + "description": "make-release.sh works from Git Bash (node for Windows got /d/... paths)", + "scope": "desktop", + "author": "Nerual Dreming", + "hash": "6ec511f59" + }, { "type": "fix", "typeLabel": "Исправления", diff --git a/website/src/repl/components/panel/WelcomeTab.jsx b/website/src/repl/components/panel/WelcomeTab.jsx index 7379c37d..d508c4f1 100644 --- a/website/src/repl/components/panel/WelcomeTab.jsx +++ b/website/src/repl/components/panel/WelcomeTab.jsx @@ -46,6 +46,11 @@ function WelcomeRu() { Telegram-сообществу ! + {' '}Нашли ошибку?{' '} + + Сообщите о проблеме + + .

🌐 Официальный сайт:{' '} @@ -110,6 +115,11 @@ function WelcomeEn() { Telegram community ! + {' '}Found a bug?{' '} + + Report a problem + + .

🌐 Website:{' '} @@ -136,6 +146,22 @@ function WelcomeEn() { ); } +/** + * GitHub's choice of forms (bug, idea, question) with the browser and system passed along: the key is the `id` of + * the text field in `.github/ISSUE_TEMPLATE/*.yml`, and the chosen form fills it from the query parameter. + */ +function issueReportUrl() { + const agent = navigator.userAgent; + const known = [['Edg', 'Edge'], ['OPR', 'Opera'], ['YaBrowser', 'Yandex'], ['Firefox', 'Firefox'], ['Chrome', 'Chrome'], ['Version', 'Safari']]; + const found = known.map(([token, label]) => [label, agent.match(new RegExp(`${token}/(\\d+)`))]).find(([, m]) => m); + const name = found ? `${found[0]} ${found[1][1]}` : ''; + const os = /Windows/.test(agent) ? 'Windows' : /Mac OS X|Macintosh/.test(agent) ? 'macOS' : /Android/.test(agent) ? 'Android' : /Linux/.test(agent) ? 'Linux' : ''; + const query = new URLSearchParams(); + const described = [name, os].filter(Boolean).join(', '); + if (described) query.set('browser', described); + return `https://github.com/timoncool/Bulka/issues/new/choose?${query.toString()}`; +} + export function WelcomeTab() { const { fontFamily } = useSettings(); return ( From c5303fe5482192a9d3b932f8225e679b9209c59a Mon Sep 17 00:00:00 2001 From: Nerual Dreming Date: Wed, 14 Oct 2026 17:38:26 +0300 Subject: [PATCH 2/6] The desktop app sends the computer number the studios send, so one person with Bulka and a studio counts once --- desktop/src-tauri/Cargo.lock | 405 +++++++++++++++++- desktop/src-tauri/Cargo.toml | 2 + desktop/src-tauri/src/lib.rs | 2 + test/hub-client.test.mjs | 18 +- website/src/components/HeadCommon.astro | 4 +- website/src/data/changelog.json | 9 + website/src/hub/bulkaHub.mjs | 3 +- website/src/hub/studioHub.mjs | 4 +- website/src/i18n/en.mjs | 2 +- website/src/i18n/ru.mjs | 2 +- .../src/repl/components/TelemetryConsent.jsx | 1 + 11 files changed, 440 insertions(+), 12 deletions(-) diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock index d3cac822..7b8977a2 100644 --- a/desktop/src-tauri/Cargo.lock +++ b/desktop/src-tauri/Cargo.lock @@ -222,6 +222,81 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" +[[package]] +name = "aws-lc-rs" +version = "1.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faac5829c2b74c28f830747e7818ccfb684261b5f48a1118b1e2a13d36dfab13" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1622d8446a2d4b2ce0c7eefc73dd43a99779028d5ee5c2dd8073a658ba8a2bc" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", + "pkg-config", +] + +[[package]] +name = "axum" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" +dependencies = [ + "axum-core", + "bytes", + "form_urlencoded", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "base64" version = "0.21.7" @@ -279,6 +354,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block2" version = "0.6.2" @@ -337,6 +421,7 @@ version = "0.3.0" dependencies = [ "serde", "serde_json", + "studio-hub-client", "tauri", "tauri-build", "tauri-plugin-dialog", @@ -447,6 +532,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6651c9ed80effdc7db0ff72512157f901af5e3549e341e24b1dd4887d836d838" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -483,6 +570,23 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" +[[package]] +name = "cfg_aliases" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" + +[[package]] +name = "chacha20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.1", + "rand_core", +] + [[package]] name = "chrono" version = "0.4.45" @@ -495,6 +599,21 @@ dependencies = [ "windows-link", ] +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "combine" version = "4.6.8" @@ -514,6 +633,12 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "cookie" version = "0.18.2" @@ -589,6 +714,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.5.2" @@ -623,6 +757,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + [[package]] name = "cssparser" version = "0.37.0" @@ -652,6 +795,15 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "914a755b7c2d4af2bdcff7ce1739e2db9a1b81a9b07123d8015786ae03c0980d" +[[package]] +name = "ctutils" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03bb0e1cc970d482d121d9a1744999169b69a07470b3d644a7894e53fcaf4574" +dependencies = [ + "cmov", +] + [[package]] name = "darling" version = "0.24.1" @@ -775,8 +927,20 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "crypto-common", + "block-buffer 0.10.4", + "crypto-common 0.1.7", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", + "const-oid", + "crypto-common 0.2.2", + "ctutils", ] [[package]] @@ -1105,6 +1269,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futures-channel" version = "0.3.34" @@ -1305,8 +1475,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1328,8 +1500,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", + "rand_core", + "wasm-bindgen", ] [[package]] @@ -1516,6 +1691,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hmac" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" +dependencies = [ + "digest 0.11.3", +] + [[package]] name = "html5ever" version = "0.39.0" @@ -1565,6 +1749,21 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hybrid-array" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17" +dependencies = [ + "typenum", +] + [[package]] name = "hyper" version = "1.12.0" @@ -1577,6 +1776,7 @@ dependencies = [ "http", "http-body", "httparse", + "httpdate", "itoa", "pin-project-lite", "smallvec", @@ -1983,6 +2183,16 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + [[package]] name = "js-sys" version = "0.3.106" @@ -2111,6 +2321,23 @@ version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" +[[package]] +name = "lru-slab" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4050469837a6ff301cd14c1f8f24f88549e6d548f24f64e2148eb0f72cebc51f" + +[[package]] +name = "machine-uid" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe0d6336d341b10ae80e099b8f3c59f34bf8aef66ef25e83aa98bf2955c0ae7" +dependencies = [ + "libc", + "windows-registry", + "windows-sys 0.61.2", +] + [[package]] name = "markup5ever" version = "0.39.0" @@ -2122,6 +2349,12 @@ dependencies = [ "web_atoms", ] +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + [[package]] name = "memchr" version = "2.8.3" @@ -2848,6 +3081,63 @@ dependencies = [ "memchr", ] +[[package]] +name = "quinn" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4051e23e9185c255a7e33ef59cdbca87a22d359052eecd22fc6b901fb37d9d11" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.21", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e750cca55fe4f0439a15d0bb529da9651e79993e8e72c61a899a36d462befbe" +dependencies = [ + "aws-lc-rs", + "bytes", + "getrandom 0.4.3", + "lru-slab", + "rand", + "rand_pcg", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.21", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af66907df18639dcf4db56ca65490cabc4b27a97dbadd96f2926cca73298f016" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "quote" version = "1.0.47" @@ -2869,6 +3159,32 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +[[package]] +name = "rand" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65c9fb96cbc91e3478eaae79a69fcd3f1ae4ad052e471fe6732fff548984b4af" +dependencies = [ + "chacha20", + "getrandom 0.4.3", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + +[[package]] +name = "rand_pcg" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core", +] + [[package]] name = "raw-window-handle" version = "0.6.2" @@ -2963,6 +3279,7 @@ dependencies = [ "log", "percent-encoding", "pin-project-lite", + "quinn", "rustls", "rustls-pki-types", "rustls-platform-verifier", @@ -3054,6 +3371,7 @@ version = "0.23.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d41d731c7d2f962d1ccc364cec258de3c0e93b38c2fb3ba97ac74513048d634" dependencies = [ + "aws-lc-rs", "once_cell", "ring", "rustls-pki-types", @@ -3080,6 +3398,7 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" dependencies = [ + "web-time", "zeroize", ] @@ -3116,6 +3435,7 @@ version = "0.103.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -3127,6 +3447,12 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + [[package]] name = "same-file" version = "1.0.6" @@ -3320,6 +3646,17 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + [[package]] name = "serde_repr" version = "0.1.21" @@ -3349,6 +3686,18 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_with" version = "3.24.0" @@ -3420,8 +3769,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", - "digest", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d7069beb7d6ac7b9acd1039986e73443f24234f41074da099d6f994ac9ad19" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.1", + "digest 0.11.3", ] [[package]] @@ -3584,6 +3944,25 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "studio-hub-client" +version = "0.1.0" +source = "git+https://github.com/timoncool/studio-hub-client?rev=987e7bd3fadc6530cd6b2940592ed8a0b917ea39#987e7bd3fadc6530cd6b2940592ed8a0b917ea39" +dependencies = [ + "axum", + "chrono", + "hmac", + "machine-uid", + "regex", + "reqwest", + "serde", + "serde_json", + "sha2 0.11.1", + "tokio", + "tracing", + "uuid", +] + [[package]] name = "subtle" version = "2.6.1" @@ -3844,7 +4223,7 @@ dependencies = [ "semver", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "syn 2.0.119", "tauri-utils", "thiserror 2.0.21", @@ -4224,9 +4603,21 @@ dependencies = [ "mio", "pin-project-lite", "socket2", + "tokio-macros", "windows-sys 0.61.2", ] +[[package]] +name = "tokio-macros" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.8", +] + [[package]] name = "tokio-rustls" version = "0.26.6" @@ -4359,6 +4750,7 @@ dependencies = [ "tokio", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -4397,6 +4789,7 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -5257,7 +5650,7 @@ dependencies = [ "once_cell", "percent-encoding", "raw-window-handle", - "sha2", + "sha2 0.10.9", "soup3", "tao-macros", "thiserror 2.0.21", diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml index 58930551..89081035 100644 --- a/desktop/src-tauri/Cargo.toml +++ b/desktop/src-tauri/Cargo.toml @@ -21,6 +21,8 @@ tauri-plugin-updater = "2" tauri-plugin-shell = "2" serde = { version = "1", features = ["derive"] } serde_json = "1" +# только machine::id — номер компьютера, общий со студиями +studio-hub-client = { git = "https://github.com/timoncool/studio-hub-client", rev = "987e7bd3fadc6530cd6b2940592ed8a0b917ea39" } [profile.release] opt-level = "s" diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs index b9ee7c2d..945ce4a1 100644 --- a/desktop/src-tauri/src/lib.rs +++ b/desktop/src-tauri/src/lib.rs @@ -160,6 +160,8 @@ fn spawn_server(app: &tauri::AppHandle, app_dir: &PathBuf, data: &PathBuf, port: .env("BULKA_DESKTOP", "1") // Куда сохранять записи/экспорт (сервер кладёт файлы в <данные>/recordings и открывает папку). .env("BULKA_APP_DIR", data.to_string_lossy().into_owned()) + // номер компьютера, общий со студиями: статистика считает одного человека один раз + .env("BULKA_MACHINE", studio_hub_client::machine::id().unwrap_or_default()) .current_dir(app_dir.clone()); let (mut rx, child) = cmd.spawn().map_err(|e| format!("node не запустился: {e}"))?; diff --git a/test/hub-client.test.mjs b/test/hub-client.test.mjs index 7c8141ec..442b238f 100644 --- a/test/hub-client.test.mjs +++ b/test/hub-client.test.mjs @@ -11,8 +11,9 @@ function memoryStorage() { return { getItem: (k) => data.get(k) ?? null, setItem: (k, v) => data.set(k, String(v)), data }; } -function hubWith(fetchImpl, storage = memoryStorage()) { +function hubWith(fetchImpl, storage = memoryStorage(), extra = {}) { return new StudioHub({ + ...extra, app: 'bulka', version: '0.6.0', os: 'web Windows Chrome', @@ -152,3 +153,18 @@ describe('studio hub client', () => { expect(() => hub.count('Bad-Name')).toThrow(); }); }); + +describe('computer id', () => { + it('goes with the report of the desktop app and is absent on the web', async () => { + const machine = '041bb722-6c3b-4ebe-be3a-7ed023dab1b9'; + const desktop = hubWith(vi.fn(ok), memoryStorage(), { machine }); + desktop.acknowledge(true); + desktop.count('pattern_play_done'); + const day = new Date().toISOString().slice(0, 10); + expect(desktop.reportFor(day).machine).toBe(machine); + const web = hubWith(vi.fn(ok)); + web.acknowledge(true); + web.count('pattern_play_done'); + expect('machine' in web.reportFor(day)).toBe(false); + }); +}); diff --git a/website/src/components/HeadCommon.astro b/website/src/components/HeadCommon.astro index 9420c2b0..8fb9a598 100644 --- a/website/src/components/HeadCommon.astro +++ b/website/src/components/HeadCommon.astro @@ -15,7 +15,9 @@ const lang = langFromPath(Astro.url.pathname); const desktop = process.env.BULKA_DESKTOP === '1'; const hubUrl = import.meta.env.PUBLIC_STUDIO_HUB_URL || process.env.STUDIO_HUB_URL || ''; const hubTest = import.meta.env.DEV || process.env.STUDIO_HUB_TEST === '1'; -const build = { desktop, version: desktop ? desktopConf.version : websitePackage.version, hubUrl }; +// the computer id the shell derives (studio-hub-client `machine::id`), so Bulka and the studios count one person once +const machine = desktop && process.env.BULKA_MACHINE ? process.env.BULKA_MACHINE : undefined; +const build = { desktop, version: desktop ? desktopConf.version : websitePackage.version, hubUrl, machine }; const notice = { app: 'bulka', lang, version: build.version, ...(hubTest ? { test: '1' } : {}) }; --- diff --git a/website/src/data/changelog.json b/website/src/data/changelog.json index 13687dfe..860bf7d2 100644 --- a/website/src/data/changelog.json +++ b/website/src/data/changelog.json @@ -9,6 +9,15 @@ "date": "2026-10-14", "dateFormatted": "14 октября 2026", "changes": [ + { + "type": "other", + "typeLabel": "Прочее", + "emoji": "📦", + "description": "Welcome tab: report a problem through the issue forms, with the browser filled in", + "scope": null, + "author": "Nerual Dreming", + "hash": "68f997854" + }, { "type": "other", "typeLabel": "Прочее", diff --git a/website/src/hub/bulkaHub.mjs b/website/src/hub/bulkaHub.mjs index 435b40fd..0948ec75 100644 --- a/website/src/hub/bulkaHub.mjs +++ b/website/src/hub/bulkaHub.mjs @@ -41,7 +41,7 @@ function noticeEvents(on) { /** The hub of this page, or null where statistics are not wired (local dev without PUBLIC_STUDIO_HUB_URL). */ export function initBulkaHub() { if (hub || typeof window === 'undefined') return hub; - const { desktop, version, hubUrl } = build(); + const { desktop, version, hubUrl, machine } = build(); if (import.meta.env.DEV && !hubUrl) { console.info('[studio hub] dev: statistics are off; set PUBLIC_STUDIO_HUB_URL to send them to a local hub'); return null; @@ -56,6 +56,7 @@ export function initBulkaHub() { storage: window.localStorage, fetch: window.fetch.bind(window), onTelemetry: noticeEvents, + machine, }); noticeEvents(hub.telemetryOn()); window.__bulkaHub = hub; diff --git a/website/src/hub/studioHub.mjs b/website/src/hub/studioHub.mjs index c343ee1a..1c1e7495 100644 --- a/website/src/hub/studioHub.mjs +++ b/website/src/hub/studioHub.mjs @@ -31,7 +31,8 @@ export function shortName(text) { export class StudioHub { /** * @param {{ app: string, version: string, os: string, backend: string, lang: () => string, - * urls: string[], storage: Storage, fetch: typeof fetch, now?: () => number }} config + * urls: string[], storage: Storage, fetch: typeof fetch, now?: () => number, machine?: string }} config + * `machine`: the computer id the desktop shell derives, the same in every program of timoncool's; none on the web. */ constructor(config) { this.config = config; @@ -129,6 +130,7 @@ export class StudioHub { return { schema: 1, install: this.state.install, + ...(this.config.machine ? { machine: this.config.machine } : {}), app: this.config.app, version: this.config.version, day: dayKey, diff --git a/website/src/i18n/en.mjs b/website/src/i18n/en.mjs index e7ebc6a2..6d53ae3b 100644 --- a/website/src/i18n/en.mjs +++ b/website/src/i18n/en.mjs @@ -365,7 +365,7 @@ export default { 'summary.toolError': 'Tool error', 'telemetry.title': 'Anonymous statistics', 'telemetry.about': - 'Helps us see what is used and what breaks: how many pattern runs, recordings, exports and AI agent replies, which errors happened (without details), the interface language, OS and browser. Nothing personal: no code, no prompts, no keys, no file names. You can turn it off in the settings.', + 'Helps us see what is used and what breaks: how many pattern runs, recordings, exports and AI agent replies, which errors happened (without details), the interface language, OS and browser, and in the desktop app a computer number shared by our programs (a one-way hash, not the system number itself). Nothing personal: no code, no prompts, no keys, no file names. You can turn it off in the settings.', 'telemetry.checkbox': 'Send anonymous usage statistics', 'telemetry.what': 'What is sent', 'telemetry.done': 'Done', diff --git a/website/src/i18n/ru.mjs b/website/src/i18n/ru.mjs index 532324ea..e20cb500 100644 --- a/website/src/i18n/ru.mjs +++ b/website/src/i18n/ru.mjs @@ -364,7 +364,7 @@ export default { 'summary.toolError': 'Ошибка инструмента', 'telemetry.title': 'Анонимная статистика', 'telemetry.about': - 'Помогает понять, чем пользуются и что ломается: сколько запусков паттернов, записей, экспортов и ответов ИИ-агента, какие ошибки случились (без подробностей), язык интерфейса, ОС и браузер. Ничего личного: ни кода, ни промптов, ни ключей, ни имён файлов. Выключить можно в настройках.', + 'Помогает понять, чем пользуются и что ломается: сколько запусков паттернов, записей, экспортов и ответов ИИ-агента, какие ошибки случились (без подробностей), язык интерфейса, ОС и браузер, а в приложении для компьютера ещё номер компьютера, общий для наших программ (необратимый хеш, не сам системный номер). Ничего личного: ни кода, ни промптов, ни ключей, ни имён файлов. Выключить можно в настройках.', 'telemetry.checkbox': 'Отправлять анонимную статистику', 'telemetry.what': 'Что отправляется', 'telemetry.done': 'Готово', diff --git a/website/src/repl/components/TelemetryConsent.jsx b/website/src/repl/components/TelemetryConsent.jsx index 887ed226..57764300 100644 --- a/website/src/repl/components/TelemetryConsent.jsx +++ b/website/src/repl/components/TelemetryConsent.jsx @@ -8,6 +8,7 @@ export function TelemetryPreview({ hub }) { const report = hub.reportFor(day) ?? { schema: 1, install: t('telemetry.previewInstall'), + ...(hub.config.machine ? { machine: hub.config.machine } : {}), app: hub.config.app, version: hub.config.version, day, From 79fe8b8acccf36ffdac30048b0431e9373efa3a3 Mon Sep 17 00:00:00 2001 From: Nerual Dreming Date: Wed, 14 Oct 2026 20:10:02 +0300 Subject: [PATCH 3/6] =?UTF-8?q?=D0=A0=D0=B5=D0=B2=D1=8C=D1=8E:=20=D0=BD?= =?UTF-8?q?=D0=BE=D0=BC=D0=B5=D1=80=20=D0=BA=D0=BE=D0=BC=D0=BF=D1=8C=D1=8E?= =?UTF-8?q?=D1=82=D0=B5=D1=80=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D0=BE=D0=BA?= =?UTF-8?q?=D0=BD=D0=B0=20=E2=80=94=20=D1=82=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE?= =?UTF-8?q?=20=D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=BD=D1=8B=D0=B9=20(ma?= =?UTF-8?q?chine::system=5Fid),=20=D0=B1=D0=B5=D0=B7=20=D0=B7=D0=B0=D0=BF?= =?UTF-8?q?=D0=B8=D1=81=D0=B8=20=D0=BE=D0=B1=D1=89=D0=B5=D0=B3=D0=BE=20?= =?UTF-8?q?=D1=84=D0=B0=D0=B9=D0=BB=D0=B0=20=D0=B4=D0=BE=20=D1=81=D0=BE?= =?UTF-8?q?=D0=B3=D0=BB=D0=B0=D1=81=D0=B8=D1=8F;=20studio-hub-client=2068d?= =?UTF-8?q?95f8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- desktop/src-tauri/Cargo.lock | 32 ++++++++++++++++---------------- desktop/src-tauri/Cargo.toml | 2 +- desktop/src-tauri/src/lib.rs | 2 +- website/src/data/changelog.json | 9 +++++++++ 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock index 7b8977a2..7acbe3eb 100644 --- a/desktop/src-tauri/Cargo.lock +++ b/desktop/src-tauri/Cargo.lock @@ -961,7 +961,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -1146,7 +1146,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -2431,7 +2431,7 @@ dependencies = [ "png 0.18.1", "serde", "thiserror 2.0.21", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -2768,7 +2768,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.45.0", ] [[package]] @@ -3135,7 +3135,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] @@ -3362,7 +3362,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -3420,7 +3420,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -3857,7 +3857,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -3947,7 +3947,7 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "studio-hub-client" version = "0.1.0" -source = "git+https://github.com/timoncool/studio-hub-client?rev=987e7bd3fadc6530cd6b2940592ed8a0b917ea39#987e7bd3fadc6530cd6b2940592ed8a0b917ea39" +source = "git+https://github.com/timoncool/studio-hub-client?rev=68d95f8699ebc5dc919a842c4a5d55802c9ceb1b#68d95f8699ebc5dc919a842c4a5d55802c9ceb1b" dependencies = [ "axum", "chrono", @@ -4491,10 +4491,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.3", + "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -4834,7 +4834,7 @@ dependencies = [ "png 0.18.1", "serde", "thiserror 2.0.21", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -4863,7 +4863,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" dependencies = [ "memoffset", "tempfile", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -5203,7 +5203,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -5224,7 +5224,7 @@ dependencies = [ "objc2-foundation", "objc2-quartz-core", "raw-window-handle", - "windows-sys 0.61.2", + "windows-sys 0.60.2", "windows-version", ] @@ -5605,7 +5605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d6f32a0ff4a9f6f01231eb2059cc85479330739333e0e58cadf03b6af2cca10" dependencies = [ "cfg-if", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml index 89081035..64b391e9 100644 --- a/desktop/src-tauri/Cargo.toml +++ b/desktop/src-tauri/Cargo.toml @@ -22,7 +22,7 @@ tauri-plugin-shell = "2" serde = { version = "1", features = ["derive"] } serde_json = "1" # только machine::id — номер компьютера, общий со студиями -studio-hub-client = { git = "https://github.com/timoncool/studio-hub-client", rev = "987e7bd3fadc6530cd6b2940592ed8a0b917ea39" } +studio-hub-client = { git = "https://github.com/timoncool/studio-hub-client", rev = "68d95f8699ebc5dc919a842c4a5d55802c9ceb1b" } [profile.release] opt-level = "s" diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs index 945ce4a1..581905c7 100644 --- a/desktop/src-tauri/src/lib.rs +++ b/desktop/src-tauri/src/lib.rs @@ -161,7 +161,7 @@ fn spawn_server(app: &tauri::AppHandle, app_dir: &PathBuf, data: &PathBuf, port: // Куда сохранять записи/экспорт (сервер кладёт файлы в <данные>/recordings и открывает папку). .env("BULKA_APP_DIR", data.to_string_lossy().into_owned()) // номер компьютера, общий со студиями: статистика считает одного человека один раз - .env("BULKA_MACHINE", studio_hub_client::machine::id().unwrap_or_default()) + .env("BULKA_MACHINE", studio_hub_client::machine::system_id().unwrap_or_default()) .current_dir(app_dir.clone()); let (mut rx, child) = cmd.spawn().map_err(|e| format!("node не запустился: {e}"))?; diff --git a/website/src/data/changelog.json b/website/src/data/changelog.json index 860bf7d2..cc43818a 100644 --- a/website/src/data/changelog.json +++ b/website/src/data/changelog.json @@ -9,6 +9,15 @@ "date": "2026-10-14", "dateFormatted": "14 октября 2026", "changes": [ + { + "type": "other", + "typeLabel": "Прочее", + "emoji": "📦", + "description": "The desktop app sends the computer number the studios send, so one person with Bulka and a studio counts once", + "scope": null, + "author": "Nerual Dreming", + "hash": "c5303fe54" + }, { "type": "other", "typeLabel": "Прочее", From 2b3d2778557deff84ec6ec11b26101ea9e4b7161 Mon Sep 17 00:00:00 2001 From: Nerual Dreming Date: Wed, 14 Oct 2026 20:18:28 +0300 Subject: [PATCH 4/6] studio-hub-client 365c2b7 --- desktop/src-tauri/Cargo.lock | 28 ++++++++++++++-------------- desktop/src-tauri/Cargo.toml | 2 +- website/src/data/changelog.json | 9 +++++++++ 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock index 7acbe3eb..c07cd6a0 100644 --- a/desktop/src-tauri/Cargo.lock +++ b/desktop/src-tauri/Cargo.lock @@ -961,7 +961,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1146,7 +1146,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2431,7 +2431,7 @@ dependencies = [ "png 0.18.1", "serde", "thiserror 2.0.21", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3135,7 +3135,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3362,7 +3362,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3420,7 +3420,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3857,7 +3857,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3947,7 +3947,7 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "studio-hub-client" version = "0.1.0" -source = "git+https://github.com/timoncool/studio-hub-client?rev=68d95f8699ebc5dc919a842c4a5d55802c9ceb1b#68d95f8699ebc5dc919a842c4a5d55802c9ceb1b" +source = "git+https://github.com/timoncool/studio-hub-client?rev=365c2b757bfddd45fff67e7264b41f4f961a0032#365c2b757bfddd45fff67e7264b41f4f961a0032" dependencies = [ "axum", "chrono", @@ -4494,7 +4494,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -4834,7 +4834,7 @@ dependencies = [ "png 0.18.1", "serde", "thiserror 2.0.21", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -4863,7 +4863,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" dependencies = [ "memoffset", "tempfile", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -5203,7 +5203,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -5224,7 +5224,7 @@ dependencies = [ "objc2-foundation", "objc2-quartz-core", "raw-window-handle", - "windows-sys 0.60.2", + "windows-sys 0.61.2", "windows-version", ] @@ -5605,7 +5605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d6f32a0ff4a9f6f01231eb2059cc85479330739333e0e58cadf03b6af2cca10" dependencies = [ "cfg-if", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml index 64b391e9..1c7be754 100644 --- a/desktop/src-tauri/Cargo.toml +++ b/desktop/src-tauri/Cargo.toml @@ -22,7 +22,7 @@ tauri-plugin-shell = "2" serde = { version = "1", features = ["derive"] } serde_json = "1" # только machine::id — номер компьютера, общий со студиями -studio-hub-client = { git = "https://github.com/timoncool/studio-hub-client", rev = "68d95f8699ebc5dc919a842c4a5d55802c9ceb1b" } +studio-hub-client = { git = "https://github.com/timoncool/studio-hub-client", rev = "365c2b757bfddd45fff67e7264b41f4f961a0032" } [profile.release] opt-level = "s" diff --git a/website/src/data/changelog.json b/website/src/data/changelog.json index cc43818a..a1784524 100644 --- a/website/src/data/changelog.json +++ b/website/src/data/changelog.json @@ -9,6 +9,15 @@ "date": "2026-10-14", "dateFormatted": "14 октября 2026", "changes": [ + { + "type": "other", + "typeLabel": "Прочее", + "emoji": "📦", + "description": "Ревью: номер компьютера для окна — только системный (machine::system_id), без записи общего файла до согласия; studio-hub-client 68d95f8", + "scope": null, + "author": "Nerual Dreming", + "hash": "79fe8b8ac" + }, { "type": "other", "typeLabel": "Прочее", From 758013ac413a17040f14ce8a27a7bc383085bfb4 Mon Sep 17 00:00:00 2001 From: Nerual Dreming Date: Thu, 15 Oct 2026 01:52:58 +0300 Subject: [PATCH 5/6] The window's own page gets the microphone WebView2 left unanswered, so the sound outputs are listed --- desktop/src-tauri/src/lib.rs | 10 ++++++++++ website/src/data/changelog.json | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs index 581905c7..f3f74b89 100644 --- a/desktop/src-tauri/src/lib.rs +++ b/desktop/src-tauri/src/lib.rs @@ -339,6 +339,16 @@ pub fn run() { .min_inner_size(1100.0, 700.0) .resizable(true) .disable_drag_drop_handler() + // WebView2 оставляет запрос микрофона без ответа и без окна согласия: getUserMedia своей страницы + // (названия звуковых выходов, запись) висел, и список устройств вывода оставался пустым + .on_permission_request(move |webview, kind| match kind { + tauri::webview::PermissionKind::Microphone + if webview.url().is_ok_and(|url| url.host_str() == Some("127.0.0.1") && url.port() == Some(port)) => + { + tauri::webview::PermissionResponse::Allow + } + _ => tauri::webview::PermissionResponse::Default, + }) .build()?; if let Some(ic) = icon { win.set_icon(ic)?; diff --git a/website/src/data/changelog.json b/website/src/data/changelog.json index a1784524..dc0dd29f 100644 --- a/website/src/data/changelog.json +++ b/website/src/data/changelog.json @@ -9,6 +9,15 @@ "date": "2026-10-14", "dateFormatted": "14 октября 2026", "changes": [ + { + "type": "other", + "typeLabel": "Прочее", + "emoji": "📦", + "description": "studio-hub-client 365c2b7", + "scope": null, + "author": "Nerual Dreming", + "hash": "2b3d27785" + }, { "type": "other", "typeLabel": "Прочее", From 958d332f287ba38709566286d23fc3e76a9a8af5 Mon Sep 17 00:00:00 2001 From: Nerual Dreming Date: Thu, 15 Oct 2026 02:39:36 +0300 Subject: [PATCH 6/6] The microphone asked for only to name the sound outputs is released at once --- packages/superdough/superdough.mjs | 10 ++++++++-- website/src/data/changelog.json | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index a4f17c98..bc0b7d58 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -171,8 +171,14 @@ export function getSound(s) { } export const getAudioDevices = async () => { - await navigator.mediaDevices.getUserMedia({ audio: true }); - let mediaDevices = await navigator.mediaDevices.enumerateDevices(); + // the microphone is asked for only so the outputs are named: it is released at once + const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); + let mediaDevices; + try { + mediaDevices = await navigator.mediaDevices.enumerateDevices(); + } finally { + stream.getTracks().forEach((track) => track.stop()); + } mediaDevices = mediaDevices.filter((device) => device.kind === 'audiooutput' && device.deviceId !== 'default'); const devicesMap = new Map(); devicesMap.set(DEFAULT_AUDIO_DEVICE_NAME, ''); diff --git a/website/src/data/changelog.json b/website/src/data/changelog.json index dc0dd29f..57559222 100644 --- a/website/src/data/changelog.json +++ b/website/src/data/changelog.json @@ -5,6 +5,21 @@ "dateFormatted": "⚠️ ГЕНЕРИРУЕТСЯ АВТОМАТИЧЕСКИ", "changes": [] }, + { + "date": "2026-10-15", + "dateFormatted": "15 октября 2026", + "changes": [ + { + "type": "other", + "typeLabel": "Прочее", + "emoji": "📦", + "description": "The window's own page gets the microphone WebView2 left unanswered, so the sound outputs are listed", + "scope": null, + "author": "Nerual Dreming", + "hash": "758013ac4" + } + ] + }, { "date": "2026-10-14", "dateFormatted": "14 октября 2026",