@velor/remote-mouse 6.4.8

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 (316) hide show
  1. package/.artifacts/screenshots/remote-mobile-config.png +0 -0
  2. package/.artifacts/screenshots/remote-mobile-home.png +0 -0
  3. package/.artifacts/screenshots/remote-mobile-preferences.png +0 -0
  4. package/.artifacts/screenshots/remote-mobile-server-info.png +0 -0
  5. package/.artifacts/screenshots/remote-mobile-vlc.png +0 -0
  6. package/.env.example +93 -0
  7. package/README.md +370 -0
  8. package/bin/remote-mouse.js +19 -0
  9. package/client/core/dom.js +148 -0
  10. package/client/core/init-socket-io.js +117 -0
  11. package/client/core/socket-emit.js +6 -0
  12. package/client/core/window-events.js +23 -0
  13. package/client/i18n/apply-page-translations.js +18 -0
  14. package/client/i18n/constants.js +3 -0
  15. package/client/i18n/core.js +40 -0
  16. package/client/i18n/locale-registry.js +77 -0
  17. package/client/i18n/locales/de.js +227 -0
  18. package/client/i18n/locales/en.js +389 -0
  19. package/client/i18n/locales/es.js +228 -0
  20. package/client/i18n/locales/fr.js +389 -0
  21. package/client/i18n/locales/it.js +227 -0
  22. package/client/i18n/locales/ja.js +227 -0
  23. package/client/i18n/locales/pt.js +227 -0
  24. package/client/i18n/locales/ru.js +240 -0
  25. package/client/i18n/locales/zh.js +227 -0
  26. package/client/preferences/constants.js +15 -0
  27. package/client/preferences/effects.js +24 -0
  28. package/client/preferences/load.js +19 -0
  29. package/client/preferences/render.js +26 -0
  30. package/client/preferences/rows.js +78 -0
  31. package/client/preferences/state.js +29 -0
  32. package/client/preview/create-preview-frame-receiver.js +13 -0
  33. package/client/preview/draw.js +77 -0
  34. package/client/preview/parse-preview-frame.js +39 -0
  35. package/client/preview/preview-stream.js +152 -0
  36. package/client/services/app-state/appStateKeys.js +30 -0
  37. package/client/services/app-state/createAppStateService.js +216 -0
  38. package/client/services/app-state/createPersistStoreService.js +122 -0
  39. package/client/services/app-state/createStateStoreService.js +64 -0
  40. package/client/services/app-state/localStorageBinding.js +26 -0
  41. package/client/services/app-state/normalizers.js +74 -0
  42. package/client/services/app-state/resolveEffectiveStateValue.js +58 -0
  43. package/client/services/app-state/stateDefinitions.js +107 -0
  44. package/client/services/backend/createBackendService.js +55 -0
  45. package/client/services/config/ConfigView.js +45 -0
  46. package/client/services/config/createClientConfigService.js +122 -0
  47. package/client/services/config/defaultClientConfig.js +22 -0
  48. package/client/services/createServicesContainer.js +48 -0
  49. package/client/services/createServicesRegistry.js +26 -0
  50. package/client/services/i18n/createI18nService.js +86 -0
  51. package/client/services/notifications/createNotificationService.js +56 -0
  52. package/client/services/pubsub/createPubSubService.js +20 -0
  53. package/client/services/remotes/createRemotesService.js +20 -0
  54. package/client/services/transport/createSocketIoTransportService.js +50 -0
  55. package/client/touch/bindTouchPassthrough.js +94 -0
  56. package/client/touch/createTouchList.js +18 -0
  57. package/client/touch/dispatchSyntheticTouch.js +20 -0
  58. package/client/touch/gesture-zone.js +28 -0
  59. package/client/touch/throttle.js +46 -0
  60. package/client/touch/touch-handlers.js +193 -0
  61. package/client/touch/touchpad.js +231 -0
  62. package/client/ui/config/page.js +840 -0
  63. package/client/ui/main/applyRemoteVisibilityState.js +60 -0
  64. package/client/ui/main/bind-client-notifications.js +3 -0
  65. package/client/ui/main/bindings/bindAccordion.js +121 -0
  66. package/client/ui/main/bindings/bindActionButtons.js +13 -0
  67. package/client/ui/main/bindings/bindAdminDrawer.js +137 -0
  68. package/client/ui/main/bindings/bindAdminRemoteButtons.js +77 -0
  69. package/client/ui/main/bindings/bindAdminVersion.js +27 -0
  70. package/client/ui/main/bindings/bindBrowserRemoteButtons.js +119 -0
  71. package/client/ui/main/bindings/bindRemoteAccordion.js +23 -0
  72. package/client/ui/main/bindings/bindSamsungRemoteButtons.js +320 -0
  73. package/client/ui/main/bindings/bindSystemRemoteButtons.js +41 -0
  74. package/client/ui/main/bindings/bindVlcRemoteButtons.js +64 -0
  75. package/client/ui/main/canvas-ui.js +33 -0
  76. package/client/ui/main/connection-overlay.js +57 -0
  77. package/client/ui/main/init-ui.js +54 -0
  78. package/client/ui/main/keyboard-panel.js +271 -0
  79. package/client/ui/main/mouse-buttons.js +94 -0
  80. package/client/ui/main/page.js +21 -0
  81. package/client/ui/notifications/show-toast.js +48 -0
  82. package/client/ui/preferences/bindPreferenceSwitchers.js +49 -0
  83. package/client/ui/preferences/page.js +61 -0
  84. package/client/ui/preferences/switchers.js +200 -0
  85. package/index.js +9 -0
  86. package/package.json +41 -0
  87. package/public/admin-config.css +447 -0
  88. package/public/admin-config.html +63 -0
  89. package/public/apple-touch-icon.png +0 -0
  90. package/public/brave-icon.svg +13 -0
  91. package/public/favicon.svg +30 -0
  92. package/public/icon-192.png +0 -0
  93. package/public/icon-512.png +0 -0
  94. package/public/index.html +246 -0
  95. package/public/manifest.webmanifest +45 -0
  96. package/public/preferences.html +55 -0
  97. package/public/server-info.html +574 -0
  98. package/public/styles.css +1042 -0
  99. package/public/sw.js +103 -0
  100. package/scripts/codex-commit.sh +112 -0
  101. package/scripts/generate-mobile-screenshots.mjs +244 -0
  102. package/scripts/install-linux.sh +633 -0
  103. package/scripts/install-windows.ps1 +369 -0
  104. package/server/application/createApplicationLifecycle.js +15 -0
  105. package/server/application/logger.js +216 -0
  106. package/server/application/shutdown.js +81 -0
  107. package/server/application/start.js +95 -0
  108. package/server/application/state.js +19 -0
  109. package/server/connection/api/admin-actions.router.js +65 -0
  110. package/server/connection/api/admin-configs.router.js +165 -0
  111. package/server/connection/api/admin-remotes.router.js +61 -0
  112. package/server/connection/api/admin-subs.router.js +49 -0
  113. package/server/connection/api/client.router.js +15 -0
  114. package/server/connection/api/configs.js +96 -0
  115. package/server/connection/api/qr-page.handler.js +17 -0
  116. package/server/connection/api/remotes.router.js +30 -0
  117. package/server/connection/api/server-info.router.js +149 -0
  118. package/server/connection/api/session.middleware.js +93 -0
  119. package/server/connection/api/unauthorized-response.js +73 -0
  120. package/server/connection/socket/createConnectionRegistrar.js +23 -0
  121. package/server/connection/socket/createSocketSessionAuthMiddleware.js +49 -0
  122. package/server/connection/socket/socket-action-responder.js +12 -0
  123. package/server/connection/socket/socket.timestamp-middleware.js +51 -0
  124. package/server/index.js +12 -0
  125. package/server/init/bootstrapApi.js +87 -0
  126. package/server/init/bootstrapSocket.js +79 -0
  127. package/server/init/createAdminApiRouter.js +22 -0
  128. package/server/init/createAdminUiRouter.js +21 -0
  129. package/server/init/createSocketActionRegistrars.js +52 -0
  130. package/server/init/observers/startConfigObserver.js +51 -0
  131. package/server/init/observers/startDisplaySizeObserver.js +55 -0
  132. package/server/init/observers/startNotificationObserver.js +49 -0
  133. package/server/init/observers/startQrOverlayHoverObserver.js +89 -0
  134. package/server/init/observers/startQrOverlayRefreshObserver.js +53 -0
  135. package/server/os/darwin/app.js +45 -0
  136. package/server/os/darwin/applescript.js +51 -0
  137. package/server/os/darwin/cliSocket.js +53 -0
  138. package/server/os/darwin/url.js +9 -0
  139. package/server/os/darwin/window.js +10 -0
  140. package/server/os/linux/app.js +120 -0
  141. package/server/os/linux/cliSocket.js +53 -0
  142. package/server/os/linux/process.js +69 -0
  143. package/server/os/linux/screen.js +58 -0
  144. package/server/os/linux/systemd.js +139 -0
  145. package/server/os/linux/url.js +17 -0
  146. package/server/os/linux/windows.js +144 -0
  147. package/server/os/win32/app.js +66 -0
  148. package/server/os/win32/cliSocket.js +15 -0
  149. package/server/os/win32/powershell.js +70 -0
  150. package/server/os/win32/process.js +20 -0
  151. package/server/os/win32/service.js +95 -0
  152. package/server/os/win32/url.js +9 -0
  153. package/server/os/win32/window.js +10 -0
  154. package/server/remotes/admin/createAdminEventGuardMiddleware.js +29 -0
  155. package/server/remotes/admin/createForceUpdateCheckAction.js +39 -0
  156. package/server/remotes/admin/createInstallUpdateAction.js +64 -0
  157. package/server/remotes/admin/createOpenQrBrowserAction.js +63 -0
  158. package/server/remotes/admin/createOpenServerInfoBrowserAction.js +58 -0
  159. package/server/remotes/admin/createRestartServiceAction.js +20 -0
  160. package/server/remotes/admin/createRotateEntryTokenAction.js +43 -0
  161. package/server/remotes/admin/createToggleQrOverlayAction.js +38 -0
  162. package/server/remotes/admin/index.js +32 -0
  163. package/server/remotes/admin/notifyIfRestarted.js +102 -0
  164. package/server/remotes/admin/registrar.js +94 -0
  165. package/server/remotes/browser/actions/createFocusOrLaunchBrowserAction.js +22 -0
  166. package/server/remotes/browser/actions/openUrlOnHost.js +3 -0
  167. package/server/remotes/browser/browserCatalog.js +70 -0
  168. package/server/remotes/browser/index.js +15 -0
  169. package/server/remotes/browser/listBrowsersOnHost.js +23 -0
  170. package/server/remotes/browser/registrar.js +29 -0
  171. package/server/remotes/browser/spec.js +18 -0
  172. package/server/remotes/browser/state.js +5 -0
  173. package/server/remotes/input/registrar.js +39 -0
  174. package/server/remotes/preview/bgraToRgbaBuffer.js +20 -0
  175. package/server/remotes/preview/captureAroundCursor.js +19 -0
  176. package/server/remotes/preview/createPreviewStreamer.js +85 -0
  177. package/server/remotes/preview/registrar.js +34 -0
  178. package/server/remotes/samsung/createSamsungCommandService.js +203 -0
  179. package/server/remotes/samsung/createSamsungRemote.js +26 -0
  180. package/server/remotes/samsung/createSamsungRemoteGetter.js +46 -0
  181. package/server/remotes/samsung/createSamsungTvGetter.js +102 -0
  182. package/server/remotes/samsung/device-config.js +122 -0
  183. package/server/remotes/samsung/registrar.js +59 -0
  184. package/server/remotes/samsung/utils.js +56 -0
  185. package/server/remotes/vlc/index.js +39 -0
  186. package/server/remotes/vlc/registrar.js +94 -0
  187. package/server/remotes/vlc/spec.js +15 -0
  188. package/server/remotes/vlc/state.js +5 -0
  189. package/server/remotes/window/index.js +6 -0
  190. package/server/remotes/window/registrar.js +28 -0
  191. package/server/services/application/createApplicationDaemonService.js +144 -0
  192. package/server/services/application/getDaemonServiceAdapter.js +56 -0
  193. package/server/services/application/utils.js +29 -0
  194. package/server/services/config/bootstrapConfig.js +38 -0
  195. package/server/services/config/configPaths.js +42 -0
  196. package/server/services/config/configSchema.js +297 -0
  197. package/server/services/config/configService.js +89 -0
  198. package/server/services/config/defaultConfig.js +137 -0
  199. package/server/services/config/envConfig.js +49 -0
  200. package/server/services/config/index.js +9 -0
  201. package/server/services/config/logConfig.js +54 -0
  202. package/server/services/config/system-config.js +44 -0
  203. package/server/services/createServicesContainer.js +94 -0
  204. package/server/services/createServicesRegistry.js +48 -0
  205. package/server/services/input/createInputController.js +17 -0
  206. package/server/services/input/createKeyboardController.js +146 -0
  207. package/server/services/input/createMouseController.js +182 -0
  208. package/server/services/notifier/createClientNotifier.js +23 -0
  209. package/server/services/notifier/createHostNotifier.js +41 -0
  210. package/server/services/notifier/createNotifier.js +13 -0
  211. package/server/services/notifier/createNotifierComposite.js +122 -0
  212. package/server/services/notifier/handleOpenQrBrowserEvent.js +40 -0
  213. package/server/services/notifier/handleOpenServerInfoBrowserEvent.js +40 -0
  214. package/server/services/notifier/handleRestartServiceEvent.js +37 -0
  215. package/server/services/notifier/handleRotateEntryTokenEvent.js +42 -0
  216. package/server/services/notifier/handleSessionEvent.js +24 -0
  217. package/server/services/notifier/handleToggleQrOverlayEvent.js +21 -0
  218. package/server/services/notifier/host-notifier/createLinuxHostNotifier.js +23 -0
  219. package/server/services/notifier/host-notifier/createNodeNotifierHostNotifier.js +24 -0
  220. package/server/services/notifier/host-notifier/index.js +11 -0
  221. package/server/services/notifier/mapper/handleForceUpdateCheckEvent.js +24 -0
  222. package/server/services/notifier/mapper/handleInstallUpdateEvent.js +53 -0
  223. package/server/services/notifier/mapper/handleSocketEvent.js +40 -0
  224. package/server/services/notifier/mapper/handleUpdateManagerEvent.js +24 -0
  225. package/server/services/notifier/mapper/notify.js +7 -0
  226. package/server/services/os/index.js +23 -0
  227. package/server/services/os/platforms/createFallbackAdapter.js +31 -0
  228. package/server/services/os/platforms/darwin/app.js +6 -0
  229. package/server/services/os/platforms/darwin/index.js +21 -0
  230. package/server/services/os/platforms/darwin/scripts.js +4 -0
  231. package/server/services/os/platforms/darwin/url.js +1 -0
  232. package/server/services/os/platforms/darwin/window.js +4 -0
  233. package/server/services/os/platforms/linux/app.js +6 -0
  234. package/server/services/os/platforms/linux/index.js +33 -0
  235. package/server/services/os/platforms/linux/url.js +1 -0
  236. package/server/services/os/platforms/linux/windows.js +11 -0
  237. package/server/services/os/platforms/win32/app.js +6 -0
  238. package/server/services/os/platforms/win32/index.js +21 -0
  239. package/server/services/os/platforms/win32/overlay.js +6 -0
  240. package/server/services/os/platforms/win32/powershell.js +4 -0
  241. package/server/services/os/platforms/win32/url.js +1 -0
  242. package/server/services/os/platforms/win32/window.js +4 -0
  243. package/server/services/os/shared.js +2 -0
  244. package/server/services/overlay/createNoopOverlay.js +13 -0
  245. package/server/services/overlay/createQrOverlay.js +27 -0
  246. package/server/services/overlay/createQrOverlayWin32.js +158 -0
  247. package/server/services/overlay/createQrOverlayYad.js +178 -0
  248. package/server/services/overlay/renderQrPage.js +82 -0
  249. package/server/services/persistence/createConfigDao.js +106 -0
  250. package/server/services/persistence/createDatabaseProvider.js +23 -0
  251. package/server/services/persistence/createEntryTokenDao.js +140 -0
  252. package/server/services/persistence/createRestartLogDao.js +210 -0
  253. package/server/services/persistence/index.js +19 -0
  254. package/server/services/pubsub/createEventStore.js +54 -0
  255. package/server/services/pubsub/createPubSub.js +89 -0
  256. package/server/services/pubsub/createServiceEvents.js +29 -0
  257. package/server/services/pubsub/serviceEventConstants.js +39 -0
  258. package/server/services/remotes/createRemotes.js +25 -0
  259. package/server/services/server/createHttpsServer.js +12 -0
  260. package/server/services/server/createServer.js +66 -0
  261. package/server/services/sse/createSseService.js +96 -0
  262. package/server/services/sse/utils.js +7 -0
  263. package/server/services/system/createSystemService.js +170 -0
  264. package/server/services/system/getNetworkInfo.js +18 -0
  265. package/server/services/system/getScreenInfo.js +32 -0
  266. package/server/services/system/listNetworkInterfaces.js +27 -0
  267. package/server/services/task-manager/createTaskManager.js +68 -0
  268. package/server/services/task-runner/createTaskRunner.js +114 -0
  269. package/server/services/token-manager/createTokenManager.js +244 -0
  270. package/server/services/token-manager/token-format.js +7 -0
  271. package/server/services/token-manager/token-store-utils.js +8 -0
  272. package/server/services/update-manager/CommandUpdateSource.js +70 -0
  273. package/server/services/update-manager/NpmUpdateSource.js +34 -0
  274. package/server/services/update-manager/buildNpmGlobalUpdateCommand.js +15 -0
  275. package/server/services/update-manager/chooseUpdateCheckSource.js +20 -0
  276. package/server/services/update-manager/chooseUpdateInstallSource.js +5 -0
  277. package/server/services/update-manager/createUpdateManager.js +109 -0
  278. package/server/services/update-manager/resolveInstallUpdateCommand.js +42 -0
  279. package/server/term/cli/executeLocalServiceCommand.js +42 -0
  280. package/server/term/cli/getCliSocketPath.js +5 -0
  281. package/server/term/cli/parseCliArgs.js +110 -0
  282. package/server/term/cli/printCliResult.js +18 -0
  283. package/server/term/cli/runCliCmd.js +50 -0
  284. package/server/term/cli/sendCliCommand.js +76 -0
  285. package/server/term/cliSocket.js +29 -0
  286. package/server/term/srv/commands/configCommand.js +84 -0
  287. package/server/term/srv/commands/helpCommand.js +6 -0
  288. package/server/term/srv/commands/infoCommand.js +7 -0
  289. package/server/term/srv/commands/openQrCommand.js +7 -0
  290. package/server/term/srv/commands/samsungDetectCommand.js +52 -0
  291. package/server/term/srv/commands/serviceCommand.js +25 -0
  292. package/server/term/srv/commands/systemConfigCommand.js +7 -0
  293. package/server/term/srv/commands/tasksCommand.js +24 -0
  294. package/server/term/srv/commands/tokensCommand.js +15 -0
  295. package/server/term/srv/executeCliCommand.js +44 -0
  296. package/server/term/srv/executeCliRequest.js +38 -0
  297. package/server/term/srv/startCliServer.js +140 -0
  298. package/server/utils/createRandomToken.js +11 -0
  299. package/server/utils/env.js +155 -0
  300. package/server/utils/git.js +13 -0
  301. package/server/utils/http.js +7 -0
  302. package/server/utils/network.js +45 -0
  303. package/server/utils/paths.js +10 -0
  304. package/server/utils/process.js +57 -0
  305. package/server/utils/robot.js +11 -0
  306. package/server/utils/semver.js +33 -0
  307. package/server/utils/truncateText.js +7 -0
  308. package/utils/createLazy.js +13 -0
  309. package/utils/functional.js +48 -0
  310. package/utils/math.js +26 -0
  311. package/utils/notificationSettings.js +61 -0
  312. package/utils/object.utils.js +79 -0
  313. package/utils/predicates.js +17 -0
  314. package/utils/remoteCommands.js +40 -0
  315. package/utils/sync.js +3 -0
  316. package/velor-remote-mouse-6.4.8.tgz +0 -0
@@ -0,0 +1,271 @@
1
+ import { emitWithTimestamp } from '../../core/socket-emit.js';
2
+ import {
3
+ REMOTE_EVENT_KEYBOARD_KEY,
4
+ REMOTE_EVENT_KEYBOARD_TEXT,
5
+ } from '../../../utils/remoteCommands.js';
6
+ import {APP_STATE_KEYBOARD_PREVIEW_ACTIVE} from '../../services/app-state/createAppStateService.js';
7
+
8
+ export function bindKeyboardPanel(services, dom) {
9
+ const socket = services.getTransport();
10
+ const appState = services.getAppState();
11
+ const {
12
+ keyboardPanel,
13
+ keyboardPanelPreview,
14
+ keyboardTextMode,
15
+ keyboardLiveMode,
16
+ textInput,
17
+ liveTextInput,
18
+ keyboardEsc,
19
+ keyboardTab,
20
+ keyboardEnter,
21
+ keyboardShift,
22
+ keyboardAlt,
23
+ keyboardCtrl,
24
+ btnTextEntry,
25
+ btnLiveKeyboard,
26
+ btnSendText,
27
+ } = dom.remotes.keyboard;
28
+ const modifierState = {
29
+ control: false,
30
+ alt: false,
31
+ shift: false,
32
+ };
33
+ let activeMode = '';
34
+
35
+ function setPreviewActive(active) {
36
+ appState.set(APP_STATE_KEYBOARD_PREVIEW_ACTIVE, Boolean(active));
37
+ }
38
+
39
+ function forceViewportLayout(input) {
40
+ if (!input) {
41
+ return;
42
+ }
43
+
44
+ const run = () => {
45
+ // Force a layout read before asking the browser to reposition the field.
46
+ void document.body.offsetHeight;
47
+ input.scrollIntoView({
48
+ block: 'end',
49
+ inline: 'nearest',
50
+ });
51
+ window.dispatchEvent(new Event('resize'));
52
+ };
53
+
54
+ window.setTimeout(run, 50);
55
+ window.setTimeout(run, 250);
56
+ }
57
+
58
+ function getActiveInput() {
59
+ return activeMode === 'live' ? liveTextInput : textInput;
60
+ }
61
+
62
+ function restoreInputFocus() {
63
+ const input = getActiveInput();
64
+ if (!input || keyboardPanel.classList.contains('hidden')) {
65
+ return;
66
+ }
67
+
68
+ window.setTimeout(() => {
69
+ input.focus();
70
+ }, 0);
71
+ }
72
+
73
+ function preserveKeyboard(button) {
74
+ if (!button) {
75
+ return;
76
+ }
77
+
78
+ const handleMouseDown = (event) => {
79
+ event.preventDefault();
80
+ };
81
+
82
+ button.addEventListener('mousedown', handleMouseDown);
83
+ }
84
+
85
+ function syncModeButtons(mode = '') {
86
+ btnTextEntry.classList.toggle('is-active', mode === 'text');
87
+ btnLiveKeyboard.classList.toggle('is-active', mode === 'live');
88
+ }
89
+
90
+ function updatePreview(text = '') {
91
+ if (!keyboardPanelPreview) {
92
+ return;
93
+ }
94
+
95
+ keyboardPanelPreview.textContent = text;
96
+ keyboardPanelPreview.classList.toggle('is-empty', !text);
97
+ }
98
+
99
+ function closePanel() {
100
+ activeMode = '';
101
+ keyboardPanel.classList.add('hidden');
102
+ keyboardTextMode.classList.remove('hidden');
103
+ keyboardLiveMode.classList.add('hidden');
104
+ textInput.blur();
105
+ liveTextInput.blur();
106
+ modifierState.control = false;
107
+ modifierState.alt = false;
108
+ modifierState.shift = false;
109
+ syncModifierButtons();
110
+ syncModeButtons('');
111
+ setPreviewActive(false);
112
+ }
113
+
114
+ function openPanel(mode) {
115
+ activeMode = mode;
116
+ keyboardPanel.classList.remove('hidden');
117
+ keyboardTextMode.classList.toggle('hidden', mode !== 'text');
118
+ keyboardLiveMode.classList.toggle('hidden', mode !== 'live');
119
+ syncModeButtons(mode);
120
+ setPreviewActive(true);
121
+
122
+ const target = mode === 'live' ? liveTextInput : textInput;
123
+ updatePreview('');
124
+ setTimeout(() => {
125
+ target.focus();
126
+ forceViewportLayout(target);
127
+ }, 40);
128
+ }
129
+
130
+ function togglePanel(mode) {
131
+ const panelHidden = keyboardPanel.classList.contains('hidden');
132
+ const textModeHidden = keyboardTextMode.classList.contains('hidden');
133
+ const currentMode = textModeHidden ? 'live' : 'text';
134
+
135
+ if (!panelHidden && currentMode === mode) {
136
+ closePanel();
137
+ return;
138
+ }
139
+
140
+ openPanel(mode);
141
+ }
142
+
143
+ function sendText() {
144
+ const text = textInput.value;
145
+ if (!text.trim()) {
146
+ return;
147
+ }
148
+
149
+ emitWithTimestamp(socket, REMOTE_EVENT_KEYBOARD_TEXT, { text });
150
+ textInput.value = '';
151
+ updatePreview('');
152
+ setPreviewActive(true);
153
+ textInput.focus();
154
+ }
155
+
156
+ function sendSpecialKey(key, modifiers) {
157
+ emitWithTimestamp(socket, REMOTE_EVENT_KEYBOARD_KEY, { key, modifiers });
158
+ }
159
+
160
+ function getActiveModifiers() {
161
+ return Object.entries(modifierState)
162
+ .filter(([, enabled]) => enabled)
163
+ .map(([key]) => key);
164
+ }
165
+
166
+ function syncModifierButtons() {
167
+ const buttonMap = [
168
+ [keyboardShift, modifierState.shift],
169
+ [keyboardAlt, modifierState.alt],
170
+ [keyboardCtrl, modifierState.control],
171
+ ];
172
+
173
+ for (const [button, active] of buttonMap) {
174
+ button?.classList.toggle('is-active', active);
175
+ button?.setAttribute('aria-pressed', active ? 'true' : 'false');
176
+ }
177
+ }
178
+
179
+ function toggleModifier(modifier) {
180
+ modifierState[modifier] = !modifierState[modifier];
181
+ syncModifierButtons();
182
+ setPreviewActive(true);
183
+ restoreInputFocus();
184
+ }
185
+
186
+ function pressKeyboardAction(key) {
187
+ const modifiers = getActiveModifiers();
188
+ sendSpecialKey(key, modifiers.length ? modifiers : undefined);
189
+ setPreviewActive(true);
190
+ if (modifierState.shift || modifierState.alt || modifierState.control) {
191
+ modifierState.shift = false;
192
+ modifierState.alt = false;
193
+ modifierState.control = false;
194
+ syncModifierButtons();
195
+ }
196
+ restoreInputFocus();
197
+ }
198
+
199
+ [
200
+ keyboardEsc,
201
+ keyboardTab,
202
+ keyboardEnter,
203
+ keyboardShift,
204
+ keyboardAlt,
205
+ keyboardCtrl,
206
+ btnSendText,
207
+ ].forEach(preserveKeyboard);
208
+
209
+ btnTextEntry.addEventListener('click', () => togglePanel('text'));
210
+ btnLiveKeyboard.addEventListener('click', () => togglePanel('live'));
211
+ btnSendText.addEventListener('click', sendText);
212
+ keyboardEsc.addEventListener('click', () => pressKeyboardAction('escape'));
213
+ keyboardTab.addEventListener('click', () => pressKeyboardAction('tab'));
214
+ keyboardEnter.addEventListener('click', () => pressKeyboardAction('enter'));
215
+ keyboardShift.addEventListener('click', () => toggleModifier('shift'));
216
+ keyboardAlt.addEventListener('click', () => toggleModifier('alt'));
217
+ keyboardCtrl.addEventListener('click', () => toggleModifier('control'));
218
+
219
+ textInput.addEventListener('keydown', (event) => {
220
+ if ((event.ctrlKey || event.metaKey) && event.key === 'Enter') {
221
+ event.preventDefault();
222
+ sendText();
223
+ }
224
+ });
225
+
226
+ textInput.addEventListener('input', () => {
227
+ setPreviewActive(true);
228
+ });
229
+
230
+ textInput.addEventListener('focus', () => {
231
+ forceViewportLayout(textInput);
232
+ });
233
+
234
+ liveTextInput.addEventListener('beforeinput', (event) => {
235
+ const inputType = String(event.inputType || '');
236
+
237
+ if (inputType.startsWith('delete')) {
238
+ pressKeyboardAction('backspace');
239
+ setPreviewActive(true);
240
+ return;
241
+ }
242
+
243
+ const text = typeof event.data === 'string' ? event.data : '';
244
+ if (!text) {
245
+ return;
246
+ }
247
+
248
+ emitWithTimestamp(socket, REMOTE_EVENT_KEYBOARD_TEXT, { text });
249
+ setPreviewActive(true);
250
+ });
251
+
252
+ liveTextInput.addEventListener('keydown', (event) => {
253
+ if (event.key === 'Enter') {
254
+ event.preventDefault();
255
+ pressKeyboardAction('enter');
256
+ return;
257
+ }
258
+
259
+ if (event.key === 'Tab') {
260
+ event.preventDefault();
261
+ pressKeyboardAction('tab');
262
+ }
263
+ });
264
+
265
+ liveTextInput.addEventListener('focus', () => {
266
+ forceViewportLayout(liveTextInput);
267
+ });
268
+
269
+ syncModifierButtons();
270
+ updatePreview('');
271
+ }
@@ -0,0 +1,94 @@
1
+ import { emitWithTimestamp } from '../../core/socket-emit.js';
2
+ import { REMOTE_EVENT_MOUSE_BUTTON } from '../../../utils/remoteCommands.js';
3
+
4
+ export function bindMouseButtons(services, dom) {
5
+ const socket = services.getTransport();
6
+ const {btnLeft, btnRight} = dom.remotes.mouse;
7
+
8
+ function bindHoldButton(buttonNode, button) {
9
+ if (!buttonNode) {
10
+ return;
11
+ }
12
+
13
+ let isPressed = false;
14
+ let activeTouchId = null;
15
+
16
+ const press = () => {
17
+ if (isPressed) {
18
+ return;
19
+ }
20
+
21
+ isPressed = true;
22
+ console.log('[mouse-buttons] emit down', { button });
23
+ emitWithTimestamp(socket, REMOTE_EVENT_MOUSE_BUTTON, { button, state: 'down' });
24
+ };
25
+
26
+ const release = () => {
27
+ if (!isPressed) {
28
+ return;
29
+ }
30
+
31
+ isPressed = false;
32
+ activeTouchId = null;
33
+ console.log('[mouse-buttons] emit up', { button });
34
+ emitWithTimestamp(socket, REMOTE_EVENT_MOUSE_BUTTON, { button, state: 'up' });
35
+ };
36
+
37
+ const onDocumentTouchEnd = (event) => {
38
+ if (activeTouchId === null) {
39
+ return;
40
+ }
41
+
42
+ const touchStillActive = Array.from(event.touches || []).some((touch) => touch.identifier === activeTouchId);
43
+ if (!touchStillActive) {
44
+ release();
45
+ }
46
+ };
47
+
48
+ const onDocumentMouseUp = () => {
49
+ release();
50
+ };
51
+
52
+ buttonNode.addEventListener('pointerdown', (event) => {
53
+ event.preventDefault();
54
+ buttonNode.setPointerCapture?.(event.pointerId);
55
+ press();
56
+ });
57
+
58
+ buttonNode.addEventListener('pointerup', (event) => {
59
+ event.preventDefault();
60
+ buttonNode.releasePointerCapture?.(event.pointerId);
61
+ release();
62
+ });
63
+
64
+ buttonNode.addEventListener('mousedown', (event) => {
65
+ event.preventDefault();
66
+ press();
67
+ });
68
+
69
+ buttonNode.addEventListener('mouseup', (event) => {
70
+ event.preventDefault();
71
+ release();
72
+ });
73
+
74
+ buttonNode.addEventListener('mouseleave', release);
75
+ buttonNode.addEventListener('touchstart', (event) => {
76
+ event.preventDefault();
77
+ activeTouchId = event.changedTouches?.[0]?.identifier ?? null;
78
+ press();
79
+ }, { passive: false });
80
+ buttonNode.addEventListener('touchend', (event) => {
81
+ event.preventDefault();
82
+ release();
83
+ }, { passive: false });
84
+ buttonNode.addEventListener('touchcancel', release, { passive: false });
85
+ buttonNode.addEventListener('pointercancel', release);
86
+ buttonNode.addEventListener('lostpointercapture', release);
87
+ document.addEventListener('touchend', onDocumentTouchEnd, { passive: false });
88
+ document.addEventListener('touchcancel', onDocumentTouchEnd, { passive: false });
89
+ document.addEventListener('mouseup', onDocumentMouseUp);
90
+ }
91
+
92
+ bindHoldButton(btnLeft, 'left');
93
+ bindHoldButton(btnRight, 'right');
94
+ }
@@ -0,0 +1,21 @@
1
+ import { initUi } from './init-ui.js';
2
+ import {createServicesRegistry} from '../../services/createServicesRegistry.js';
3
+ import {
4
+ initializeCoreServices,
5
+ initializeRealtimeServices,
6
+ } from '../../services/createServicesContainer.js';
7
+
8
+ async function initClient() {
9
+ const services = createServicesRegistry();
10
+ await initializeCoreServices(services);
11
+ initializeRealtimeServices(services);
12
+ initUi(services);
13
+ }
14
+
15
+ void initClient();
16
+
17
+ if ('serviceWorker' in navigator) {
18
+ window.addEventListener('load', () => {
19
+ navigator.serviceWorker.register('/sw.js').catch(() => {});
20
+ });
21
+ }
@@ -0,0 +1,48 @@
1
+ export function showToast(root, payload = {}, t) {
2
+ if (!root) {
3
+ return;
4
+ }
5
+ const params = payload.params && typeof payload.params === 'object' ? payload.params : {};
6
+
7
+ const title = String(
8
+ payload.titleKey
9
+ ? t(payload.titleKey, params)
10
+ : (payload.title || t('common.notification')),
11
+ );
12
+ const message = String(
13
+ payload.messageKey
14
+ ? t(payload.messageKey, params)
15
+ : (payload.message || ''),
16
+ ).trim();
17
+ if (!message) {
18
+ return;
19
+ }
20
+
21
+ const level = String(payload.level || 'info');
22
+ const ttlMs = Number(payload.ttlMs) > 0 ? Number(payload.ttlMs) : 4500;
23
+
24
+ const toast = document.createElement('article');
25
+ toast.className = `toast ${level}`;
26
+
27
+ const titleEl = document.createElement('p');
28
+ titleEl.className = 'toast-title';
29
+ titleEl.textContent = title;
30
+
31
+ const msgEl = document.createElement('p');
32
+ msgEl.className = 'toast-msg';
33
+ msgEl.textContent = message;
34
+
35
+ toast.appendChild(titleEl);
36
+ toast.appendChild(msgEl);
37
+ root.prepend(toast);
38
+
39
+ while (root.children.length > 5) {
40
+ root.removeChild(root.lastElementChild);
41
+ }
42
+
43
+ setTimeout(() => {
44
+ if (toast.parentElement === root) {
45
+ root.removeChild(toast);
46
+ }
47
+ }, ttlMs);
48
+ }
@@ -0,0 +1,49 @@
1
+ import {
2
+ mountLanguageSwitcher,
3
+ mountHandednessSwitcher,
4
+ mountRemoteAutoHideSwitcher,
5
+ mountThemeSwitcher,
6
+ } from './switchers.js';
7
+ import {
8
+ APP_STATE_HANDEDNESS,
9
+ APP_STATE_LOCALE,
10
+ APP_STATE_REMOTE_AUTO_HIDE,
11
+ APP_STATE_THEME,
12
+ } from '../../services/app-state/createAppStateService.js';
13
+
14
+ export function bindPreferenceSwitchers(services) {
15
+ const appState = services.getAppState();
16
+ const i18n = services.getI18n();
17
+
18
+ mountLanguageSwitcher({
19
+ locale: appState.get(APP_STATE_LOCALE),
20
+ t: i18n.t,
21
+ onChange(locale) {
22
+ appState.set(APP_STATE_LOCALE, locale);
23
+ },
24
+ });
25
+
26
+ mountThemeSwitcher({
27
+ theme: appState.get(APP_STATE_THEME),
28
+ t: i18n.t,
29
+ onChange(theme) {
30
+ appState.set(APP_STATE_THEME, theme);
31
+ },
32
+ });
33
+
34
+ mountHandednessSwitcher({
35
+ handedness: appState.get(APP_STATE_HANDEDNESS),
36
+ t: i18n.t,
37
+ onChange(handedness) {
38
+ appState.set(APP_STATE_HANDEDNESS, handedness);
39
+ },
40
+ });
41
+
42
+ mountRemoteAutoHideSwitcher({
43
+ enabled: appState.get(APP_STATE_REMOTE_AUTO_HIDE),
44
+ t: i18n.t,
45
+ onChange(value) {
46
+ appState.set(APP_STATE_REMOTE_AUTO_HIDE, value);
47
+ },
48
+ });
49
+ }
@@ -0,0 +1,61 @@
1
+ import {
2
+ loadAvailableBrowsers,
3
+ loadAvailableRemotes,
4
+ } from '../../preferences/load.js';
5
+ import {
6
+ renderBrowserVisibilityList as renderBrowserVisibilityListView,
7
+ renderRemoteVisibilityList as renderRemoteVisibilityListView,
8
+ } from '../../preferences/render.js';
9
+ import {createPreferencesState} from '../../preferences/state.js';
10
+ import {createServicesRegistry} from '../../services/createServicesRegistry.js';
11
+ import {initializeCoreServices} from '../../services/createServicesContainer.js';
12
+ import {bindPreferenceSwitchers} from './bindPreferenceSwitchers.js';
13
+
14
+ const services = createServicesRegistry();
15
+ await initializeCoreServices(services);
16
+ services.getI18n().translateRoot(document);
17
+ bindPreferenceSwitchers(services);
18
+
19
+ const remotesRoot = document.getElementById('preferences-remotes');
20
+ const browsersRoot = document.getElementById('preferences-browsers');
21
+ const state = createPreferencesState();
22
+
23
+ function t(key, params) {
24
+ return services.getI18n().t(key, params);
25
+ }
26
+
27
+ function renderRemotes() {
28
+ renderRemoteVisibilityListView(remotesRoot, state.availableRemotes, t, services);
29
+ }
30
+
31
+ function renderBrowsers() {
32
+ renderBrowserVisibilityListView(browsersRoot, state.availableBrowsers, t, services);
33
+ }
34
+
35
+ async function refreshAvailableRemotes() {
36
+ state.availableRemotes = await loadAvailableRemotes(services);
37
+ renderRemotes();
38
+ }
39
+
40
+ async function refreshAvailableBrowsers() {
41
+ state.availableBrowsers = await loadAvailableBrowsers(services);
42
+ renderBrowsers();
43
+ }
44
+
45
+ services.getI18n().onChange(() => {
46
+ services.getI18n().translateRoot(document);
47
+ bindPreferenceSwitchers(services);
48
+ renderRemotes();
49
+ renderBrowsers();
50
+ });
51
+
52
+ services.getAppState().subscribeProperty('preferences.remoteVisibility', () => {
53
+ renderRemotes();
54
+ });
55
+
56
+ services.getAppState().subscribeProperty('preferences.browserVisibility', () => {
57
+ renderBrowsers();
58
+ });
59
+
60
+ await refreshAvailableRemotes();
61
+ await refreshAvailableBrowsers();