most-box 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/README.md +66 -6
  2. package/electron/deepLink.js +29 -0
  3. package/electron/main.js +87 -20
  4. package/out/admin/index.html +0 -0
  5. package/out/app/index.html +0 -0
  6. package/out/assets/AppShell-BOtfY12t.js +1 -0
  7. package/out/assets/FilePreviewOverlay-C5qK9HAE.js +1 -0
  8. package/out/assets/LanguageToggle-Di5b88mK.js +1 -0
  9. package/out/assets/MarketingHeader-BOytKcCc.js +1 -0
  10. package/out/assets/MarketingLayout-B8m1Q7Pa.js +1 -0
  11. package/out/assets/{MarketingThemeToggle-qlwCZU1o.js → MarketingThemeToggle-C6fggkl7.js} +1 -1
  12. package/out/assets/{MilkdownEditor-_TGlDyA_.js → MilkdownEditor-Cfze75zl.js} +1 -1
  13. package/out/assets/OpenSidebarButton-DDuALgJ2.js +1 -0
  14. package/out/assets/SidebarAccount-bo1ypzrJ.js +1 -0
  15. package/out/assets/arrow-right-RldN7Rwi.js +1 -0
  16. package/out/assets/circle-alert-BQoSDxUe.js +1 -0
  17. package/out/assets/cloud-DHoTMeZY.js +1 -0
  18. package/out/assets/copy-BtJHJnqH.js +1 -0
  19. package/out/assets/download-Bg-OdoxM.js +1 -0
  20. package/out/assets/downloadValidation-CUvbvj9f.js +1 -0
  21. package/out/assets/external-link-m8ZIQe4p.js +1 -0
  22. package/out/assets/file-text-DG1orIkZ.js +1 -0
  23. package/out/assets/game-s6irY8hS.js +1 -0
  24. package/out/assets/hard-drive-BB-sllXA.js +1 -0
  25. package/out/assets/index-3OD3Chi9.css +1 -0
  26. package/out/assets/index-BSOvFG3o.css +1 -0
  27. package/out/assets/index-C0xqKeu-.css +1 -0
  28. package/out/assets/index-CrAXrmfP.js +31 -0
  29. package/out/assets/index.lazy-0Njp0U6I.js +1 -0
  30. package/out/assets/index.lazy-BTndBeBF.js +1 -0
  31. package/out/assets/index.lazy-Bq39jYTl.js +1 -0
  32. package/out/assets/index.lazy-Bu93oGzJ.js +2 -0
  33. package/out/assets/index.lazy-BvdBwgHx.js +1 -0
  34. package/out/assets/index.lazy-CIx8ist6.js +3 -0
  35. package/out/assets/index.lazy-DK7R297q.js +1 -0
  36. package/out/assets/index.lazy-DVOcrcEB.js +2 -0
  37. package/out/assets/index.lazy-DejOniAm.js +1 -0
  38. package/out/assets/index.lazy-DfsgyiMN.js +1 -0
  39. package/out/assets/index.lazy-DpNIiSXF.js +1 -0
  40. package/out/assets/index.lazy-Vnvz-t7T.js +1 -0
  41. package/out/assets/index.lazy-v7nBJ-sF.js +1 -0
  42. package/out/assets/key-round-DIQ3Xt5F.js +1 -0
  43. package/out/assets/lock-tf1t2yuy.js +1 -0
  44. package/out/assets/message-square-DaQH7q-P.js +1 -0
  45. package/out/assets/mp-DvFTsIL9.js +1 -0
  46. package/out/assets/music-DaFvU2DL.js +1 -0
  47. package/out/assets/notebook-pen-CqEFOHKx.js +1 -0
  48. package/out/assets/play-B7q6F75-.js +1 -0
  49. package/out/assets/plus-H2i2mspM.js +1 -0
  50. package/out/assets/refresh-cw-roxAhABl.js +1 -0
  51. package/out/assets/save-DR0O9ReR.js +1 -0
  52. package/out/assets/search-ncblG-zw.js +1 -0
  53. package/out/assets/send-m1XCcuPn.js +1 -0
  54. package/out/assets/shield-check-BwcvTU4U.js +1 -0
  55. package/out/assets/trash-2-CNpsqYc1.js +1 -0
  56. package/out/assets/triangle-alert-DP9EP7IM.js +1 -0
  57. package/out/assets/upload-V--8p13l.js +1 -0
  58. package/out/assets/useChannelMessages-46C52EyL.js +3 -0
  59. package/out/assets/useGameRoom-BtxPpfck.js +1 -0
  60. package/out/assets/useNavigate-DWlBD_-b.js +1 -0
  61. package/out/assets/userStore-C4vdYsQp.js +4 -0
  62. package/out/assets/wallet-CozFU6yK.js +1 -0
  63. package/out/assets/wifi-DIR3g_8A.js +1 -0
  64. package/out/chat/index.html +0 -0
  65. package/out/chat/join/index.html +0 -0
  66. package/out/download/index.html +2 -2
  67. package/out/game/gandengyan/index.html +0 -0
  68. package/out/game/index.html +0 -0
  69. package/out/game/zhajinhua/index.html +0 -0
  70. package/out/index.html +2 -2
  71. package/out/note/index.html +0 -0
  72. package/out/ping/index.html +2 -2
  73. package/out/profile/index.html +0 -0
  74. package/out/web3/index.html +0 -0
  75. package/package.json +9 -1
  76. package/server/index.js +36 -7
  77. package/server/src/core/channelIdentity.js +6 -0
  78. package/server/src/core/gameRoom.js +15 -5
  79. package/server/src/core/mostLink.js +8 -7
  80. package/server/src/core/zhajinhua.js +6 -0
  81. package/server/src/games/gandengyan.js +10 -0
  82. package/server/src/http/access.js +63 -12
  83. package/server/src/http/app.js +34 -838
  84. package/server/src/http/nodeStatus.js +101 -9
  85. package/server/src/http/routePolicy.js +2 -0
  86. package/server/src/http/routes/channelRoutes.js +163 -0
  87. package/server/src/http/routes/fileRoutes.js +345 -0
  88. package/server/src/http/routes/nodeRoutes.js +323 -0
  89. package/server/src/http/routes/seedRoutes.js +58 -0
  90. package/server/src/index.js +197 -16
  91. package/server/src/node/config.js +2 -6
  92. package/server/src/utils/avatar.js +30 -15
  93. package/server/src/utils/downloadMessages.js +0 -2
  94. package/out/assets/AppShell-OiOEqXPr.js +0 -1
  95. package/out/assets/ChatUi-Cif5LRF3.js +0 -1
  96. package/out/assets/CopyButton-Dm7krgbq.js +0 -1
  97. package/out/assets/LanguageToggle-B4ZNuBCV.js +0 -1
  98. package/out/assets/MarketingHeader-yIZuQP7m.js +0 -1
  99. package/out/assets/MarketingLayout-DVH0Nx7S.js +0 -1
  100. package/out/assets/MoveModal-BVr4Q7-b.js +0 -1
  101. package/out/assets/Nav-5xeettNJ.js +0 -1
  102. package/out/assets/NoteSidebar-DpniUKmy.js +0 -1
  103. package/out/assets/OpenSidebarButton-BfgG2HIT.js +0 -1
  104. package/out/assets/PemBlock-CxwIepth.js +0 -1
  105. package/out/assets/SidebarAccount-Zg5DZblE.js +0 -1
  106. package/out/assets/arrow-right-CL9YSDVS.js +0 -1
  107. package/out/assets/channelApi-DNdJfsJ-.js +0 -1
  108. package/out/assets/chevron-down-CnLh_-aO.js +0 -1
  109. package/out/assets/circle-alert-oiiRDvhx.js +0 -1
  110. package/out/assets/cloud-BEe2N89j.js +0 -1
  111. package/out/assets/code-9LB8QqxL.js +0 -1
  112. package/out/assets/copy-giX4rmFJ.js +0 -1
  113. package/out/assets/download-D0oMEYQZ.js +0 -1
  114. package/out/assets/downloadValidation-Bk1VsBBo.js +0 -1
  115. package/out/assets/external-link-Cm2WCUxv.js +0 -1
  116. package/out/assets/filePreview-BZ50vZZf.js +0 -1
  117. package/out/assets/game-Bvz4dspe.js +0 -1
  118. package/out/assets/hard-drive-B3CQbcp2.js +0 -1
  119. package/out/assets/index-8eWJAjpY.css +0 -1
  120. package/out/assets/index-BZc4blbW.css +0 -1
  121. package/out/assets/index-BkZvz4WA.css +0 -1
  122. package/out/assets/index-WCK14Vja.js +0 -34
  123. package/out/assets/index.lazy-5Q6GuMNT.js +0 -1
  124. package/out/assets/index.lazy-5jq6EFXa.js +0 -3
  125. package/out/assets/index.lazy-7n1Q-NrA.js +0 -3
  126. package/out/assets/index.lazy-BFnOyQFj.js +0 -1
  127. package/out/assets/index.lazy-B_oPp6qK.js +0 -1
  128. package/out/assets/index.lazy-BvY50KVz.js +0 -1
  129. package/out/assets/index.lazy-C0Kn_amZ.js +0 -1
  130. package/out/assets/index.lazy-C3cek3Gn.js +0 -1
  131. package/out/assets/index.lazy-CLpPkdy1.js +0 -1
  132. package/out/assets/index.lazy-Cpr1kApf.js +0 -2
  133. package/out/assets/index.lazy-CuwLZiUK.js +0 -1
  134. package/out/assets/index.lazy-DDc3Ylgf.js +0 -2
  135. package/out/assets/index.lazy-Dg3aqOss.js +0 -1
  136. package/out/assets/key-round-CzuljhND.js +0 -1
  137. package/out/assets/lock-D2NhNoJW.js +0 -1
  138. package/out/assets/message-square-DwBq_Go5.js +0 -1
  139. package/out/assets/mp-Bln2MB9G.js +0 -1
  140. package/out/assets/music-CB73K5Gz.js +0 -1
  141. package/out/assets/notebook-pen-Up7r5zoI.js +0 -1
  142. package/out/assets/play-OszVgROb.js +0 -1
  143. package/out/assets/plus-BbxQG_Ai.js +0 -1
  144. package/out/assets/save-CiqyiifY.js +0 -1
  145. package/out/assets/search-gqAPOsgS.js +0 -1
  146. package/out/assets/send-vwCWsZGP.js +0 -1
  147. package/out/assets/shield-check-CxWxsNLc.js +0 -1
  148. package/out/assets/trash-2-DNGr8IgF.js +0 -1
  149. package/out/assets/triangle-alert-B_1BlX1b.js +0 -1
  150. package/out/assets/upload-Dxl7GUzb.js +0 -1
  151. package/out/assets/useChannelMessages-7bYKXU_R.js +0 -3
  152. package/out/assets/useGameRoom-DqA1mkfk.js +0 -1
  153. package/out/assets/wallet-DlkawdPJ.js +0 -1
  154. package/out/assets/wifi-sBOKcPFM.js +0 -1
  155. package/out/demo/index.html +0 -0
  156. /package/out/avatars/default/{ocean.svg → dolphin.svg} +0 -0
  157. /package/out/avatars/default/{violet.svg → owl.svg} +0 -0
  158. /package/out/avatars/default/{mint.svg → panda.svg} +0 -0
  159. /package/out/avatars/default/{dusk.svg → snow-mountain.svg} +0 -0
  160. /package/out/avatars/default/{ember.svg → tiger.svg} +0 -0
  161. /package/out/avatars/default/{sage.svg → turtle.svg} +0 -0
  162. /package/public/avatars/default/{ocean.svg → dolphin.svg} +0 -0
  163. /package/public/avatars/default/{violet.svg → owl.svg} +0 -0
  164. /package/public/avatars/default/{mint.svg → panda.svg} +0 -0
  165. /package/public/avatars/default/{dusk.svg → snow-mountain.svg} +0 -0
  166. /package/public/avatars/default/{ember.svg → tiger.svg} +0 -0
  167. /package/public/avatars/default/{sage.svg → turtle.svg} +0 -0
package/README.md CHANGED
@@ -81,11 +81,71 @@ npm run test:unit # 只运行单元测试
81
81
 
82
82
  ## 访问场景
83
83
 
84
- | 场景 | 方式 | 访问地址 |
85
- | -------- | ------------------------------------- | ----------------------- |
86
- | 本地 | 桌面客户端或 `npx most-box@latest` | `http://localhost:1976` |
87
- | 远程管理 | SSH 隧道 + `/admin/` | `http://localhost:1976` |
88
- | 外网 | Caddy 反向代理 | `https://your-domain` |
84
+ | 场景 | 方式 | 访问地址 |
85
+ | ---------- | ------------------------------------- | --------------------------- |
86
+ | 本地 | 桌面客户端或 `npx most-box@latest` | `http://localhost:1976` |
87
+ | 局域网/NAS | 监听 `0.0.0.0`,仅信任家庭局域网 | `http://NAS-IP:1976` |
88
+ | 远程管理 | SSH 隧道 + `/admin/` | `http://localhost:1976` |
89
+ | 外网 | Caddy 反向代理 | `https://your-domain` |
90
+
91
+ ### 飞牛 OS / NAS 局域网部署
92
+
93
+ 飞牛 OS 自带 Docker,可以把 NAS 变成一台 24 小时在线的 MostBox 做种机。普通用户建议直接用飞牛的 Docker 图形界面,不需要 SSH。
94
+
95
+ 你只需要准备两样东西:
96
+
97
+ - 飞牛 OS 已安装并启用 Docker。
98
+ - 知道 NAS 的局域网地址,例如 `192.168.31.107`。如果你是通过 `http://192.168.31.107:5666/` 打开飞牛 OS,那么 NAS 地址就是 `192.168.31.107`。
99
+
100
+ 部署步骤:
101
+
102
+ 1. 打开飞牛 OS 桌面的 **Docker**。
103
+ 2. 找到 **Compose**、**项目** 或 **创建项目** 入口。
104
+ 3. 项目名填写 `mostbox`。
105
+ 4. Compose 内容整段复制下面这一块,不需要改里面的命令。
106
+ 5. 保存并启动项目。
107
+
108
+ ```yaml
109
+ services:
110
+ mostbox:
111
+ image: node:22-bookworm-slim
112
+ container_name: mostbox
113
+ network_mode: host
114
+ restart: unless-stopped
115
+ volumes:
116
+ - /vol1/docker/mostbox:/data
117
+ working_dir: /data
118
+ command: >
119
+ sh -lc "if [ ! -e /usr/lib/x86_64-linux-gnu/libatomic.so.1 ]; then
120
+ apt-get update &&
121
+ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends libatomic1 ca-certificates &&
122
+ rm -rf /var/lib/apt/lists/*;
123
+ fi;
124
+ mkdir -p /data/home /data/npm-cache &&
125
+ chown -R 1000:1000 /data/home /data/npm-cache &&
126
+ su node -s /bin/sh -c 'HOME=/data/home npm_config_cache=/data/npm-cache npm_config_audit=false npm_config_fund=false npx -y most-box@latest --host 0.0.0.0'"
127
+ ```
128
+
129
+ 启动后,在同一局域网的电脑或手机浏览器打开:
130
+
131
+ ```text
132
+ http://你的NAS地址:1976
133
+ ```
134
+
135
+ 例如你的飞牛地址是 `192.168.31.107`,就打开:
136
+
137
+ ```text
138
+ http://192.168.31.107:1976
139
+ ```
140
+
141
+ 看到 MostBox 页面后,就可以在 NAS 上发布文件。发布后复制生成的 `most://<cid>?filename=...` 链接发给别人;下载者运行自己的 MostBox,粘贴链接下载。你的 NAS 会继续在线做种,关闭浏览器页面也不影响容器做种。
142
+
143
+ 常见问题:
144
+
145
+ - 页面打不开:先确认 Docker 项目状态是“运行中”,再确认访问的是 NAS 的局域网 IP 加 `:1976`。
146
+ - 日志里一直下载失败:可能是 NAS 访问 npm 或 Debian 软件源太慢,可以给 Docker 项目临时加代理。
147
+ - 数据目录:文件和节点数据保存在 NAS 的 `/vol1/docker/mostbox`,通常位于飞牛的第一个存储空间。
148
+ - 安全提醒:`--host 0.0.0.0` 是给家庭局域网使用的。不要在路由器里把 `1976` 端口直接暴露到公网;需要公网 Web 入口时,请使用 HTTPS 反向代理,并在管理台配置远程访问邀请码。
89
149
 
90
150
  ### 远程管理节点
91
151
 
@@ -107,7 +167,7 @@ mostbox.example.com {
107
167
  }
108
168
  ```
109
169
 
110
- 开放到局域网或公网时,在 `/admin/` 中配置邀请码,远程请求必须携带有效邀请码。
170
+ 开放到公网时,在 `/admin/` 中配置邀请码,远程请求必须携带有效邀请码。
111
171
 
112
172
  ## 核心功能
113
173
 
@@ -0,0 +1,29 @@
1
+ const MOST_PROTOCOL_PREFIX = /^most:\/\//i
2
+
3
+ export function findMostDeepLinkArg(argv = []) {
4
+ return (
5
+ argv.find(arg => typeof arg === 'string' && MOST_PROTOCOL_PREFIX.test(arg)) ||
6
+ ''
7
+ )
8
+ }
9
+
10
+ export function createCidRoutePathFromMostLink(link) {
11
+ if (!link || typeof link !== 'string') return ''
12
+
13
+ let url
14
+ try {
15
+ url = new URL(link)
16
+ } catch {
17
+ return ''
18
+ }
19
+
20
+ if (url.protocol !== 'most:' || !url.hostname) return ''
21
+
22
+ return `/cid/${encodeURIComponent(url.hostname)}${url.search}`
23
+ }
24
+
25
+ export function createMostDeepLinkTarget(link, baseUrl) {
26
+ const routePath = createCidRoutePathFromMostLink(link)
27
+ if (!routePath) return ''
28
+ return new URL(routePath, baseUrl).toString()
29
+ }
package/electron/main.js CHANGED
@@ -18,6 +18,10 @@ import {
18
18
  getCurrentPlatform,
19
19
  getReleaseManifestUrl,
20
20
  } from './updateChecker.js'
21
+ import {
22
+ createMostDeepLinkTarget,
23
+ findMostDeepLinkArg,
24
+ } from './deepLink.js'
21
25
 
22
26
  const __dirname = path.dirname(fileURLToPath(import.meta.url))
23
27
  const PORT = 1976
@@ -27,6 +31,9 @@ let engine = null
27
31
  let tray = null
28
32
  let isQuitting = false
29
33
  let hasCheckedForUpdates = false
34
+ let pendingDeepLinkUrl = ''
35
+
36
+ const gotSingleInstanceLock = app.requestSingleInstanceLock()
30
37
 
31
38
  function getIconCandidates() {
32
39
  return [
@@ -72,6 +79,44 @@ function showMainWindow() {
72
79
  mainWindow.focus()
73
80
  }
74
81
 
82
+ function getLocalAppUrl(routePath = '/') {
83
+ return new URL(routePath, `http://localhost:${PORT}`).toString()
84
+ }
85
+
86
+ function getInitialWindowUrl() {
87
+ const initialUrl = pendingDeepLinkUrl || getLocalAppUrl('/')
88
+ pendingDeepLinkUrl = ''
89
+ return initialUrl
90
+ }
91
+
92
+ function registerMostProtocolClient() {
93
+ if (process.defaultApp && process.argv.length >= 2) {
94
+ app.setAsDefaultProtocolClient('most', process.execPath, [
95
+ path.resolve(process.argv[1]),
96
+ ])
97
+ return
98
+ }
99
+
100
+ app.setAsDefaultProtocolClient('most')
101
+ }
102
+
103
+ function openMostDeepLink(link) {
104
+ const targetUrl = createMostDeepLinkTarget(
105
+ link,
106
+ `http://localhost:${PORT}`
107
+ )
108
+ if (!targetUrl) return
109
+
110
+ pendingDeepLinkUrl = targetUrl
111
+ if (!mainWindow) {
112
+ return
113
+ }
114
+
115
+ showMainWindow()
116
+ mainWindow.loadURL(targetUrl)
117
+ pendingDeepLinkUrl = ''
118
+ }
119
+
75
120
  function quitFromTray() {
76
121
  isQuitting = true
77
122
  if (tray) {
@@ -117,7 +162,7 @@ function createWindow() {
117
162
  },
118
163
  })
119
164
 
120
- mainWindow.loadURL(`http://localhost:${PORT}`)
165
+ mainWindow.loadURL(getInitialWindowUrl())
121
166
 
122
167
  mainWindow.on('close', event => {
123
168
  if (isQuitting) {
@@ -204,25 +249,47 @@ async function checkForUpdates() {
204
249
  }
205
250
  }
206
251
 
207
- app.whenReady().then(async () => {
208
- try {
209
- await startServer()
210
- createWindow()
211
- createTray()
212
- Menu.setApplicationMenu(null)
213
- setTimeout(() => {
214
- checkForUpdates()
215
- }, 3000)
216
-
217
- app.on('activate', () => {
218
- showMainWindow()
219
- })
220
- } catch (err) {
221
- console.error('[Electron] Failed to start server:', err)
222
- isQuitting = true
223
- app.quit()
224
- }
225
- })
252
+ if (!gotSingleInstanceLock) {
253
+ isQuitting = true
254
+ app.quit()
255
+ } else {
256
+ registerMostProtocolClient()
257
+ openMostDeepLink(findMostDeepLinkArg(process.argv))
258
+
259
+ app.on('second-instance', (_event, commandLine) => {
260
+ const link = findMostDeepLinkArg(commandLine)
261
+ if (link) {
262
+ openMostDeepLink(link)
263
+ return
264
+ }
265
+ showMainWindow()
266
+ })
267
+
268
+ app.on('open-url', (event, url) => {
269
+ event.preventDefault()
270
+ openMostDeepLink(url)
271
+ })
272
+
273
+ app.whenReady().then(async () => {
274
+ try {
275
+ await startServer()
276
+ createWindow()
277
+ createTray()
278
+ Menu.setApplicationMenu(null)
279
+ setTimeout(() => {
280
+ checkForUpdates()
281
+ }, 3000)
282
+
283
+ app.on('activate', () => {
284
+ showMainWindow()
285
+ })
286
+ } catch (err) {
287
+ console.error('[Electron] Failed to start server:', err)
288
+ isQuitting = true
289
+ app.quit()
290
+ }
291
+ })
292
+ }
226
293
 
227
294
  app.on('window-all-closed', () => {
228
295
  // Keep the daemon alive; users exit from the tray menu.
Binary file
Binary file
@@ -0,0 +1 @@
1
+ import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{y as r}from"./userStore-C4vdYsQp.js";import{t as i}from"./LanguageToggle-Di5b88mK.js";import{B as a}from"./index-CrAXrmfP.js";var o=r(`menu`,[[`path`,{d:`M4 5h16`,key:`1tepv9`}],[`path`,{d:`M4 12h16`,key:`1lakjw`}],[`path`,{d:`M4 19h16`,key:`1djgab`}]]),s=t(e(),1);function c(e,t){return typeof t==`boolean`?t:typeof window<`u`&&`matchMedia`in window?window.matchMedia(e).matches:!1}function l(e,t,{getInitialValueInEffect:n}={getInitialValueInEffect:!0}){let[r,i]=(0,s.useState)(n?t:c(e));return(0,s.useEffect)(()=>{try{if(`matchMedia`in window){let t=window.matchMedia(e);i(t.matches);let n=e=>i(e.matches);return t.addEventListener(`change`,n),()=>{t.removeEventListener(`change`,n)}}}catch{return}},[e]),r||!1}function u(e=!1,t={}){let[n,r]=(0,s.useState)(e),i=(0,s.useCallback)(()=>{r(e=>e||(t.onOpen?.(),!0))},[t.onOpen]),a=(0,s.useCallback)(()=>{r(e=>e&&(t.onClose?.(),!1))},[t.onClose]);return[n,{open:i,close:a,toggle:(0,s.useCallback)(()=>{n?a():i()},[a,i,n]),set:r}]}var d=n(),f=(0,s.createContext)(null);function p(){let e=(0,s.useContext)(f);if(!e)throw Error(`useAppShell must be used within AppShell`);return e}function m({sidebar:e,className:t=``,headerTitle:n,headerRight:r,sidebarToggleReplacement:c,defaultHide:p=!1,children:m}){let[h,g]=u(!1),[_,v]=(0,s.useState)(p),y=(0,s.useRef)(p),b=l(`(max-width: 768px)`),{t:x}=a(),S=(0,s.useCallback)((e={})=>{g.close(),e.collapse&&v(!0)},[g]);(0,s.useEffect)(()=>{p!==y.current&&(p?S({collapse:!0}):v(!1),y.current=p)},[p,S]);let C=()=>{b?g.toggle():v(!_)},w=()=>{b?g.open():v(!1)},T=b?h:!_;return(0,d.jsx)(f.Provider,{value:{closeSidebar:S,openSidebar:w,isSidebarVisible:T},children:(0,d.jsxs)(`div`,{className:[`app-layout`,t].filter(Boolean).join(` `),children:[(0,d.jsx)(`div`,{className:`sidebar-overlay ${h?`visible`:``}`,onClick:()=>S()}),(0,d.jsx)(`div`,{className:`sidebar ${h?`open`:``} ${_?`collapsed`:``}`,children:e({closeSidebar:S,openSidebar:w})}),(0,d.jsxs)(`div`,{className:`main-content`,children:[(0,d.jsxs)(`header`,{className:`app-header`,children:[(0,d.jsxs)(`div`,{className:`header-left`,children:[c??(0,d.jsx)(`button`,{onClick:C,className:`btn btn-icon sidebar-toggle-btn`,"aria-label":x(b?`appShell.openMenu`:_?`appShell.expandSidebar`:`appShell.collapseSidebar`),children:(0,d.jsx)(o,{size:16})}),n]}),(0,d.jsxs)(`div`,{className:`header-right`,children:[(0,d.jsx)(i,{className:`btn btn-icon app-language-toggle`}),r]})]}),m]})]})})}export{p as n,u as r,m as t};
@@ -0,0 +1 @@
1
+ import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{y as r}from"./userStore-C4vdYsQp.js";import{t as i}from"./file-text-DG1orIkZ.js";import{t as a}from"./music-DaFvU2DL.js";import{B as o,C as s,N as c}from"./index-CrAXrmfP.js";var l=r(`film`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M7 3v18`,key:`bbkbws`}],[`path`,{d:`M3 7.5h4`,key:`zfgn84`}],[`path`,{d:`M3 12h18`,key:`1i2n21`}],[`path`,{d:`M3 16.5h4`,key:`1230mu`}],[`path`,{d:`M17 3v18`,key:`in4fa5`}],[`path`,{d:`M17 7.5h4`,key:`myr1c1`}],[`path`,{d:`M17 16.5h4`,key:`go4c1d`}]]),u=r(`image`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,ry:`2`,key:`1m3agn`}],[`circle`,{cx:`9`,cy:`9`,r:`2`,key:`af1f0g`}],[`path`,{d:`m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21`,key:`1xmnt7`}]]),d=r(`loader`,[[`path`,{d:`M12 2v4`,key:`3427ic`}],[`path`,{d:`m16.2 7.8 2.9-2.9`,key:`r700ao`}],[`path`,{d:`M18 12h4`,key:`wj9ykh`}],[`path`,{d:`m16.2 16.2 2.9 2.9`,key:`1bxg5t`}],[`path`,{d:`M12 18v4`,key:`jadmvz`}],[`path`,{d:`m4.9 19.1 2.9-2.9`,key:`bwix9q`}],[`path`,{d:`M2 12h4`,key:`j09sii`}],[`path`,{d:`m4.9 4.9 2.9 2.9`,key:`giyufr`}]]),f=r(`pen`,[[`path`,{d:`M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z`,key:`1a8usu`}]]);function p(e){let t=String(e||``).split(`.`).pop()?.toLowerCase()||``,n=[`jpg`,`jpeg`,`png`,`gif`,`webp`,`svg`,`bmp`,`ico`,`tiff`,`heic`,`heif`],r=[`mp4`,`webm`,`mov`,`avi`,`mkv`,`flv`,`wmv`,`m4v`,`mpeg`,`3gp`],i=[`mp3`,`wav`,`ogg`,`flac`,`aac`,`m4a`,`wma`,`opus`],a=`txt.md.js.ts.jsx.tsx.css.scss.less.json.xml.html.htm.yaml.yml.toml.ini.cfg.conf.log.sh.bash.py.rb.go.rs.java.c.cpp.h.hpp.cs.php.sql.graphql.env.gitignore.dockerfile.readme`.split(`.`);return n.includes(t)?`image`:r.includes(t)?`video`:i.includes(t)?`audio`:a.includes(t)?`text`:`file`}var m=t(e(),1),h=n();function g(e){return e===`image`||e===`video`||e===`audio`}function _({item:e,isBackendReady:t,getFileDownloadUrl:n,onClose:r}){let{t:l}=o(),[u,f]=(0,m.useState)(``),[p,_]=(0,m.useState)(!1),[v,y]=(0,m.useState)(``),[b,x]=(0,m.useState)(``);return(0,m.useEffect)(()=>{if(e.subtype!==`text`)return;let r=!1;if(f(``),x(``),!t){f(l(`preview.loadFailed`));return}return _(!0),(async()=>{try{let t=await fetch(n(e.cid),{headers:{...await s(`GET`,`/api/files/${e.cid}/download`),Range:`bytes=0-9999`}});if(!t.ok)throw Error(l(`preview.loadFailed`));let i=await t.text();r||f(i||l(`preview.emptyFile`))}catch{r||f(l(`preview.loadFailed`))}finally{r||_(!1)}})(),()=>{r=!0}},[n,t,e.cid,e.subtype]),(0,m.useEffect)(()=>{if(!g(e.subtype)){y(``);return}if(y(``),x(``),!t){x(l(`preview.loadFailed`));return}let r=``,i=!1;return(async()=>{try{let t=await fetch(n(e.cid),{headers:await s(`GET`,`/api/files/${e.cid}/download`)});if(!t.ok)throw Error(l(`preview.loadFailed`));let a=URL.createObjectURL(await t.blob());r=a,i||y(a)}catch{i||x(l(`preview.loadFailed`))}})(),()=>{i=!0,r&&URL.revokeObjectURL(r)}},[n,t,e.cid,e.subtype]),(0,h.jsxs)(`div`,{className:`preview-overlay`,onClick:r,children:[(0,h.jsx)(`button`,{type:`button`,className:`preview-close`,onClick:r,"aria-label":l(`preview.close`),children:(0,h.jsx)(c,{size:20})}),(0,h.jsxs)(`div`,{onClick:e=>e.stopPropagation(),children:[e.subtype===`image`&&(0,h.jsx)(`div`,{className:`preview-media-wrapper`,children:v?(0,h.jsx)(`img`,{src:v,alt:e.fileName,translate:`no`}):b?(0,h.jsxs)(`div`,{className:`preview-unsupported`,children:[(0,h.jsx)(i,{size:48,className:`preview-file-icon`}),(0,h.jsx)(`p`,{translate:`no`,children:e.fileName}),(0,h.jsx)(`p`,{className:`preview-unsupported-hint`,children:b})]}):(0,h.jsx)(`div`,{className:`preview-loading`,children:(0,h.jsx)(`div`,{className:`preview-loading-spinner`})})}),e.subtype===`video`&&(0,h.jsx)(`div`,{className:`preview-media-wrapper`,children:v?(0,h.jsx)(`video`,{src:v,controls:!0}):b?(0,h.jsxs)(`div`,{className:`preview-unsupported`,children:[(0,h.jsx)(i,{size:48,className:`preview-file-icon`}),(0,h.jsx)(`p`,{translate:`no`,children:e.fileName}),(0,h.jsx)(`p`,{className:`preview-unsupported-hint`,children:b})]}):(0,h.jsx)(`div`,{className:`preview-loading`,children:(0,h.jsx)(`div`,{className:`preview-loading-spinner`})})}),e.subtype===`audio`&&(0,h.jsxs)(`div`,{className:`preview-audio`,children:[(0,h.jsx)(`div`,{className:`preview-audio-icon`,children:(0,h.jsx)(a,{size:36,color:`var(--accent)`})}),(0,h.jsx)(`p`,{className:`preview-audio-filename`,translate:`no`,children:e.fileName}),v?(0,h.jsx)(`audio`,{className:`preview-audio-player`,src:v,controls:!0}):(0,h.jsx)(`div`,{className:`preview-text-loading`,children:b?(0,h.jsx)(`p`,{children:b}):(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(d,{size:24,className:`preview-text-spinner`}),(0,h.jsx)(`p`,{children:l(`preview.audioLoading`)})]})})]}),e.subtype===`file`&&(0,h.jsxs)(`div`,{className:`preview-unsupported`,children:[(0,h.jsx)(i,{size:48,className:`preview-file-icon`}),(0,h.jsx)(`p`,{translate:`no`,children:e.fileName}),(0,h.jsx)(`p`,{className:`preview-unsupported-hint`,children:l(`preview.unsupported`)})]}),e.subtype===`text`&&(0,h.jsxs)(`div`,{className:`preview-text-container`,children:[(0,h.jsx)(`div`,{className:`preview-text-header`,children:(0,h.jsx)(`span`,{translate:`no`,children:e.fileName})}),p?(0,h.jsxs)(`div`,{className:`preview-text-loading`,children:[(0,h.jsx)(d,{size:24,className:`preview-text-spinner`}),(0,h.jsx)(`p`,{children:l(`preview.textLoading`)}),(0,h.jsx)(`p`,{className:`preview-text-loading-hint`,children:l(`preview.firstSyncHint`)})]}):(0,h.jsx)(`pre`,{className:`preview-text`,translate:`no`,children:u||l(`preview.emptyFile`)})]})]})]})}export{u as a,d as i,p as n,l as o,f as r,_ as t};
@@ -0,0 +1 @@
1
+ import{t as e}from"./jsx-runtime-Bt-cYkS5.js";import{y as t}from"./userStore-C4vdYsQp.js";import{B as n,H as r,V as i,f as a}from"./index-CrAXrmfP.js";var o=t(`check`,[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]),s=t(`languages`,[[`path`,{d:`m5 8 6 6`,key:`1wu5hv`}],[`path`,{d:`m4 14 6-6 2-3`,key:`1k1g8d`}],[`path`,{d:`M2 5h12`,key:`or177f`}],[`path`,{d:`M7 2h1`,key:`1t2jsx`}],[`path`,{d:`m22 22-5-10-5 10`,key:`don7ne`}],[`path`,{d:`M14 18h6`,key:`1m8k6r`}]]),c=t(`moon`,[[`path`,{d:`M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401`,key:`kfwtm`}]]),l=t(`sun`,[[`circle`,{cx:`12`,cy:`12`,r:`4`,key:`4exip2`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`m4.93 4.93 1.41 1.41`,key:`149t6j`}],[`path`,{d:`m17.66 17.66 1.41 1.41`,key:`ptbguv`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`m6.34 17.66-1.41 1.41`,key:`1m8zz5`}],[`path`,{d:`m19.07 4.93-1.41 1.41`,key:`1shlcs`}]]),u=e();function d({className:e=``}){let{locale:t,localeName:c,setLocale:l,t:d}=n(),f=d(`common.locale.choose`),p=`${f} (${d(`common.locale.current`)}: ${c})`;return(0,u.jsx)(a,{ariaLabel:f,placement:`bottom-end`,items:i.map(e=>({key:e,label:r[e],icon:e===t?(0,u.jsx)(o,{size:16}):(0,u.jsx)(`span`,{"aria-hidden":`true`}),onSelect:()=>{e!==t&&l(e)}})),renderTrigger:t=>(0,u.jsx)(`button`,{...t,className:[`language-toggle`,e].filter(Boolean).join(` `),"aria-label":f,title:p,children:(0,u.jsx)(s,{size:16})})})}export{o as i,l as n,c as r,d as t};
@@ -0,0 +1 @@
1
+ import{t as e}from"./jsx-runtime-Bt-cYkS5.js";import{t}from"./LanguageToggle-Di5b88mK.js";import{L as n,M as r}from"./index-CrAXrmfP.js";import{t as i}from"./MarketingThemeToggle-C6fggkl7.js";var a=e();function o(){return(0,a.jsx)(`nav`,{className:`mkt-nav`,children:(0,a.jsxs)(`div`,{className:`mkt-nav-inner`,children:[(0,a.jsxs)(`button`,{type:`button`,className:`mkt-nav-logo`,onClick:r(),children:[(0,a.jsx)(n,{size:18}),(0,a.jsx)(`span`,{children:`MOST PEOPLE`})]}),(0,a.jsxs)(`div`,{className:`mkt-nav-cta`,children:[(0,a.jsx)(i,{}),(0,a.jsx)(t,{className:`mkt-theme-toggle`})]})]})})}export{o as t};
@@ -0,0 +1 @@
1
+ import{t as e}from"./jsx-runtime-Bt-cYkS5.js";import{C as t,t as n}from"./userStore-C4vdYsQp.js";import{t as r}from"./LanguageToggle-Di5b88mK.js";import{t as i}from"./download-Bg-OdoxM.js";import{B as a,c as o,g as s}from"./index-CrAXrmfP.js";import{t as c}from"./MarketingThemeToggle-C6fggkl7.js";import{t as l}from"./LogoIcon-B2fFe0l1.js";var u=e();function d(){let e=n(e=>e.identity),d=n(e=>e.openLoginModal),{t:f}=a(),p=s(),m=e?.displayName||e?.username||f(`nav.openWeb`);return(0,u.jsx)(`nav`,{className:`mkt-nav`,children:(0,u.jsxs)(`div`,{className:`mkt-nav-inner`,children:[(0,u.jsxs)(t,{to:`/`,className:`mkt-nav-logo`,children:[(0,u.jsx)(l,{}),`MOST PEOPLE`]}),(0,u.jsxs)(`div`,{className:`mkt-nav-cta`,children:[(0,u.jsx)(c,{}),(0,u.jsx)(r,{className:`mkt-theme-toggle`}),!p&&(0,u.jsxs)(t,{to:`/download/`,className:`btn btn-primary mkt-nav-preview`,children:[(0,u.jsx)(i,{size:16}),f(`nav.downloadClient`)]}),e?(0,u.jsx)(t,{to:`/profile/`,className:`mkt-nav-avatar-trigger`,"aria-label":f(`nav.profile`),title:m,children:(0,u.jsx)(`img`,{className:`mkt-nav-avatar`,src:o(e.address,e.avatar),alt:``,"aria-hidden":`true`})}):(0,u.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:d,children:f(`nav.getStarted`)})]})]})})}var f={name:`most-box`,version:`0.2.2`,description:`MostBox - P2P file sharing application`,type:`module`,main:`electron/main.js`,bin:{"most-box":`server/cli.js`},files:[`out`,`public`,`electron`,`server/src`,`server/index.js`,`server/cli.js`],scripts:{start:`vite`,server:`node --watch server/index.js`,dev:`vite`,build:`vite build && node scripts/prepare-start-static.mjs`,preview:`vite preview`,serve:`npm run build && node server/index.js`,test:`node --test server/tests/**/*.test.js`,"test:unit":`node --test server/tests/unit/*.test.js`,"test:frontend":`node --test src/tests/*.test.js`,"test:protocol":`node --test --test-name-pattern "extracts CID and filename|matches golden CID samples|publishes a file from Buffer|lists published files|pulls through local seed nodes" server/tests/unit/cid.test.js server/tests/integration/cid.test.js server/tests/integration/engine.test.js`,typecheck:`tsc -p tsconfig.typecheck.json`,"typecheck:strict-router":`tsc -p tsconfig.strict-router.json`,"check:static-output":`node scripts/check-static-output.mjs`,format:`npx prettier --write .`,lint:`npx eslint .`,"r2:cors":`node scripts/configure-r2-cors.mjs`,"electron:dev":`concurrently "npm run build" "wait-on out/index.html && electron ."`,"electron:rebuild":`electron-rebuild -f -w sodium-native`,"electron:build":`npm run build && npm run electron:rebuild && electron-builder`,"electron:build:win":`npm run build && npm run electron:rebuild && electron-builder --win`,"electron:build:win:x64":`npm run electron:build:win -- --x64`,"electron:build:win:arm64":`npm run electron:build:win -- --arm64`,"electron:build:mac":`npm run build && npm run electron:rebuild && electron-builder --mac`,"electron:build:linux":`npm run build && npm run electron:rebuild && electron-builder --linux`},keywords:[`p2p`,`file-sharing`,`hyperswarm`,`hyperdrive`],license:`MIT`,dependencies:{"@dicebear/collection":`^9.4.2`,"@dicebear/core":`^9.4.2`,"@hono/node-server":`^2.0.4`,"@tanstack/react-router":`^1.170.15`,"@tanstack/react-start":`^1.168.25`,b4a:`^1.8.1`,busboy:`^1.6.0`,corestore:`^7.10.0`,dayjs:`^1.11.21`,ethers:`^6.16.0`,eventemitter3:`^5.0.4`,hono:`^4.12.23`,hypercore:`^11.33.1`,hyperdrive:`^13.3.2`,hyperswarm:`^4.17.0`,"ipfs-unixfs-importer":`^17.0.1`,multiformats:`^14.0.0`,tweetnacl:`^1.0.3`,ws:`^8.21.0`},devDependencies:{"@electron/rebuild":`^4.0.4`,"@eslint/js":`^10.0.1`,"@iconify/react":`^6.0.2`,"@mantine/hooks":`^9.3.0`,"@milkdown/crepe":`^7.21.2`,"@milkdown/utils":`^7.21.2`,"@types/react":`^19.2.16`,"@vitejs/plugin-react":`^6.0.2`,concurrently:`^10.0.3`,electron:`^42.3.3`,"electron-builder":`^26.8.1`,esbuild:`^0.28.0`,eslint:`^10.4.1`,globals:`^17.6.0`,ky:`^2.0.2`,"lucide-react":`^1.17.0`,prettier:`^3.8.3`,"qrcode.react":`^4.2.0`,react:`^19.2.7`,"react-dom":`^19.2.7`,typescript:`6.0.3`,"typescript-eslint":`^8.60.1`,vite:`^8.0.16`,"wait-on":`^9.0.10`,zustand:`^5.0.14`},overrides:{"brace-expansion":`5.0.6`,postcss:`8.5.15`,ws:`$ws`},build:{appId:`com.mostbox.app`,productName:`MostBox`,publish:[{provider:`github`,releaseType:`release`}],directories:{output:`dist`},afterPack:`electron/afterPack.cjs`,files:[`out/**/*`,`electron/**/*`,`server/src/**/*`,`server/index.js`,`server/cli.js`,`package.json`,`!**/*.map`,`!electron/**/*.test.js`,`!server/tests/**/*`],asarUnpack:[`**/*.node`,`**/sodium-native/**`],protocols:[{name:`MostBox Link`,schemes:[`most`]}],win:{target:[`nsis`],artifactName:"${productName}-${version}-win-${arch}-setup.${ext}",icon:`public/logo.ico`},nsis:{oneClick:!1,allowToChangeInstallationDirectory:!0,createDesktopShortcut:!0,createStartMenuShortcut:!0,shortcutName:`MostBox`},mac:{artifactName:"${productName}-${version}-mac-${arch}.${ext}",target:[{target:`dmg`,arch:[`x64`,`arm64`]}],icon:`public/logo-512.png`,category:`public.app-category.utilities`},dmg:{contents:[{x:130,y:220},{x:410,y:220,type:`link`,path:`/Applications`}]},linux:{artifactName:"${productName}-${version}-linux-${arch}.${ext}",target:[{target:`AppImage`,arch:[`x64`,`arm64`]}],icon:`public/logo-512.png`,category:`Utility`}}},p=[{to:`/`,labelKey:`footer.about`},{to:`/ping/`,labelKey:`footer.network`},{href:`https://github.com/most-people/most`,labelKey:null,label:`GitHub`,external:!0}],m=f.version;function h(){let{t:e}=a();return(0,u.jsx)(`footer`,{className:`mkt-footer`,children:(0,u.jsx)(`div`,{className:`mkt-container`,children:(0,u.jsxs)(`div`,{className:`mkt-footer-inner`,children:[(0,u.jsx)(`div`,{className:`mkt-footer-links`,children:p.map(n=>`external`in n?(0,u.jsx)(`a`,{href:n.href,target:`_blank`,rel:`noopener noreferrer`,children:n.label},n.href):(0,u.jsx)(t,{to:n.to,children:e(n.labelKey)},n.to))}),(0,u.jsxs)(`span`,{className:`mkt-footer-copy`,children:[`© `,new Date().getFullYear(),` MOST PEOPLE · MIT License`]}),(0,u.jsxs)(`span`,{className:`mkt-footer-build`,translate:`no`,children:[`v`,m]})]})})})}function g({children:e,header:t}){return(0,u.jsxs)(`div`,{className:`mkt-layout`,children:[t??(0,u.jsx)(d,{}),(0,u.jsx)(`main`,{className:`mkt-layout-main`,children:e}),(0,u.jsx)(h,{})]})}export{g as t};
@@ -1 +1 @@
1
- import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{n as r,r as i}from"./LanguageToggle-B4ZNuBCV.js";import{Z as a}from"./index-WCK14Vja.js";var o=t(e(),1),s=n();function c(){let[e,t]=(0,o.useState)(!1),{t:n}=a();return(0,o.useEffect)(()=>{let e=localStorage.getItem(`theme`),n=window.matchMedia(`(prefers-color-scheme: dark)`).matches;(e===`dark`||!e&&n)&&t(!0)},[]),(0,o.useEffect)(()=>{document.documentElement.setAttribute(`data-theme`,e?`dark`:`light`),localStorage.setItem(`theme`,e?`dark`:`light`)},[e]),(0,s.jsx)(`button`,{type:`button`,className:`mkt-theme-toggle`,onClick:()=>t(!e),"aria-label":n(`common.theme.toggle`),title:n(`common.theme.toggle`),children:e?(0,s.jsx)(r,{size:16}):(0,s.jsx)(i,{size:16})})}export{c as t};
1
+ import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{n as r,r as i}from"./LanguageToggle-Di5b88mK.js";import{B as a}from"./index-CrAXrmfP.js";var o=t(e(),1),s=n();function c(){let[e,t]=(0,o.useState)(!1),{t:n}=a();return(0,o.useEffect)(()=>{let e=localStorage.getItem(`theme`),n=window.matchMedia(`(prefers-color-scheme: dark)`).matches;(e===`dark`||!e&&n)&&t(!0)},[]),(0,o.useEffect)(()=>{document.documentElement.setAttribute(`data-theme`,e?`dark`:`light`),localStorage.setItem(`theme`,e?`dark`:`light`)},[e]),(0,s.jsx)(`button`,{type:`button`,className:`mkt-theme-toggle`,onClick:()=>t(!e),"aria-label":n(`common.theme.toggle`),title:n(`common.theme.toggle`),children:e?(0,s.jsx)(r,{size:16}):(0,s.jsx)(i,{size:16})})}export{c as t};