js-dos 8.1.4 → 8.1.6

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 (141) hide show
  1. package/README.md +1 -1
  2. package/dist/emulators/emulators.js +2 -0
  3. package/dist/emulators/emulators.js.map +1 -0
  4. package/dist/emulators/types/build.d.ts +28 -0
  5. package/dist/emulators/types/dos/bundle/dos-bundle.d.ts +20 -0
  6. package/dist/emulators/types/dos/dosbox/ts/direct.d.ts +3 -0
  7. package/dist/emulators/types/dos/dosbox/ts/worker.d.ts +3 -0
  8. package/dist/emulators/types/emulators.d.ts +76 -0
  9. package/dist/emulators/types/http.d.ts +9 -0
  10. package/dist/emulators/types/impl/ci-impl.d.ts +29 -0
  11. package/dist/emulators/types/impl/emulators-impl.d.ts +26 -0
  12. package/dist/emulators/types/impl/modules.d.ts +38 -0
  13. package/dist/emulators/types/libzip/libzip.d.ts +16 -0
  14. package/dist/emulators/types/protocol/messages-queue.d.ts +8 -0
  15. package/dist/emulators/types/protocol/protocol.d.ts +128 -0
  16. package/dist/emulators/wdosbox-x.js +55 -0
  17. package/dist/emulators/wdosbox-x.js.symbols +8760 -0
  18. package/dist/emulators/wdosbox-x.wasm +0 -0
  19. package/dist/emulators/wdosbox.js +55 -0
  20. package/dist/emulators/wdosbox.js.symbols +3001 -0
  21. package/dist/emulators/wdosbox.wasm +0 -0
  22. package/dist/emulators/wlibzip.js +21 -0
  23. package/dist/emulators/wlibzip.js.symbols +268 -0
  24. package/dist/emulators/wlibzip.wasm +0 -0
  25. package/dist/js-dos.css +1 -0
  26. package/dist/js-dos.js +22 -0
  27. package/dist/js-dos.js.map +1 -0
  28. package/package.json +1 -1
  29. package/release.zip +0 -0
  30. package/.eslintrc.json +0 -43
  31. package/.github/workflows/build.yml +0 -51
  32. package/.gitmodules +0 -4
  33. package/index.html +0 -110
  34. package/postcss.config.cjs +0 -8
  35. package/src/app.css +0 -14
  36. package/src/base.css +0 -10
  37. package/src/components/checkbox.tsx +0 -41
  38. package/src/components/close-button.tsx +0 -17
  39. package/src/components/components.css +0 -28
  40. package/src/components/dos-option-checkbox.tsx +0 -94
  41. package/src/components/dos-option-select.tsx +0 -108
  42. package/src/components/dos-option-slider.tsx +0 -35
  43. package/src/components/error.tsx +0 -16
  44. package/src/components/loading.tsx +0 -26
  45. package/src/components/lock.tsx +0 -10
  46. package/src/components/select.tsx +0 -33
  47. package/src/components/slider.tsx +0 -69
  48. package/src/download-file.ts +0 -18
  49. package/src/frame/account-frame.tsx +0 -156
  50. package/src/frame/editor/defaults.ts +0 -419
  51. package/src/frame/editor/editor-conf-frame.tsx +0 -227
  52. package/src/frame/editor/editor-frame.css +0 -55
  53. package/src/frame/editor/editor-fs-frame.tsx +0 -314
  54. package/src/frame/fat-drives-frame.tsx +0 -199
  55. package/src/frame/frame.css +0 -119
  56. package/src/frame/frame.tsx +0 -34
  57. package/src/frame/image-rendering-frame.tsx +0 -8
  58. package/src/frame/network-frame.tsx +0 -157
  59. package/src/frame/quick-save-frame.tsx +0 -98
  60. package/src/frame/settings-frame.tsx +0 -14
  61. package/src/frame/stats-frame.tsx +0 -87
  62. package/src/host/bundle-storage.ts +0 -91
  63. package/src/host/fullscreen.ts +0 -35
  64. package/src/host/lcache.ts +0 -203
  65. package/src/host/lstorage.ts +0 -156
  66. package/src/i18n.ts +0 -185
  67. package/src/index.css +0 -7
  68. package/src/load.ts +0 -132
  69. package/src/login/login.css +0 -9
  70. package/src/login/login.tsx +0 -77
  71. package/src/main.tsx +0 -197
  72. package/src/public/types.ts +0 -45
  73. package/src/sidebar/account-button.tsx +0 -33
  74. package/src/sidebar/cloud-save-button.tsx +0 -89
  75. package/src/sidebar/diskette-icon.tsx +0 -14
  76. package/src/sidebar/fullscreen-button.tsx +0 -44
  77. package/src/sidebar/network-button.tsx +0 -39
  78. package/src/sidebar/sidebar-button.tsx +0 -244
  79. package/src/sidebar/sidebar.css +0 -47
  80. package/src/sidebar/sidebar.tsx +0 -30
  81. package/src/sockdrive/LICENSE +0 -674
  82. package/src/sockdrive/README.md +0 -45
  83. package/src/sockdrive/include/sockdrive.h +0 -23
  84. package/src/sockdrive/js/.eslintrc.json +0 -43
  85. package/src/sockdrive/js/package.json +0 -29
  86. package/src/sockdrive/js/src/fatfs/chains.js +0 -318
  87. package/src/sockdrive/js/src/fatfs/dir.js +0 -385
  88. package/src/sockdrive/js/src/fatfs/helpers.js +0 -210
  89. package/src/sockdrive/js/src/fatfs/index.js +0 -606
  90. package/src/sockdrive/js/src/fatfs/structs.js +0 -255
  91. package/src/sockdrive/js/src/fatfs/vol.js +0 -166
  92. package/src/sockdrive/js/src/sockdrive/cache.ts +0 -56
  93. package/src/sockdrive/js/src/sockdrive/drive.ts +0 -471
  94. package/src/sockdrive/js/src/sockdrive/lru.ts +0 -221
  95. package/src/sockdrive/js/src/sockdrive/types.ts +0 -14
  96. package/src/sockdrive/js/src/sockdrive-fat.d.ts +0 -64
  97. package/src/sockdrive/js/src/sockdrive-fat.ts +0 -226
  98. package/src/sockdrive/js/src/sockdrive-native.ts +0 -100
  99. package/src/sockdrive/js/src/test/test.ts +0 -289
  100. package/src/sockdrive/js/tsconfig.json +0 -11
  101. package/src/sockdrive/js/webpack.config.js +0 -68
  102. package/src/sockdrive/js/yarn.lock +0 -1808
  103. package/src/store/auth.ts +0 -115
  104. package/src/store/dos.ts +0 -305
  105. package/src/store/editor.ts +0 -61
  106. package/src/store/init.ts +0 -48
  107. package/src/store/storage.ts +0 -32
  108. package/src/store/ui.ts +0 -191
  109. package/src/store.tsx +0 -116
  110. package/src/ui.tsx +0 -140
  111. package/src/v8/changes.ts +0 -56
  112. package/src/v8/config.ts +0 -20
  113. package/src/v8/subscriptions.ts +0 -62
  114. package/src/vite-env.d.ts +0 -5
  115. package/src/window/dos/controls/keyboard.ts +0 -32
  116. package/src/window/dos/controls/keys.ts +0 -331
  117. package/src/window/dos/controls/mouse/mount.ts +0 -99
  118. package/src/window/dos/controls/mouse/mouse-locked.ts +0 -51
  119. package/src/window/dos/controls/mouse/mouse-not-locked.ts +0 -84
  120. package/src/window/dos/controls/mouse/mouse-swipe.ts +0 -57
  121. package/src/window/dos/controls/mouse/pointer.ts +0 -85
  122. package/src/window/dos/controls/mouse.ts +0 -21
  123. package/src/window/dos/dos-dhry2.tsx +0 -191
  124. package/src/window/dos/dos-runtime.tsx +0 -216
  125. package/src/window/dos/dos-window.tsx +0 -91
  126. package/src/window/dos/render/canvas.ts +0 -65
  127. package/src/window/dos/render/resize.ts +0 -31
  128. package/src/window/dos/render/webgl.ts +0 -173
  129. package/src/window/dos/sound/audio-node.ts +0 -148
  130. package/src/window/error-window.tsx +0 -9
  131. package/src/window/loading-window.tsx +0 -54
  132. package/src/window/prerun-window.tsx +0 -121
  133. package/src/window/select-window.tsx +0 -118
  134. package/src/window/window.css +0 -78
  135. package/src/window/window.tsx +0 -49
  136. package/src/ws/ws-sockdrive.ts +0 -123
  137. package/src/ws/ws-transport-layer.ts +0 -468
  138. package/tailwind.config.cjs +0 -48
  139. package/tsconfig.json +0 -32
  140. package/tsconfig.node.json +0 -9
  141. package/vite.config.ts +0 -25
@@ -1,199 +0,0 @@
1
- import { useT } from "../i18n";
2
- import { SockdriveBackend } from "../components/dos-option-select";
3
- import { useDispatch, useSelector } from "react-redux";
4
- import { sockdriveBackend } from "../store/init";
5
- import { State } from "../store";
6
- import { useEffect, useRef, useState } from "preact/hooks";
7
- import { dispatchLoginAction, uiSlice } from "../store/ui";
8
- import { LockBadge } from "../components/lock";
9
-
10
- interface Drive {
11
- name: string,
12
- owner: string
13
- fork_of: string[],
14
- template: string,
15
- }
16
-
17
- export function FatDrivesFrame() {
18
- const t = useT();
19
- const account = useSelector((state: State) => state.auth.account);
20
- const { sockdriveEndpoint } = useSelector((state: State) =>
21
- sockdriveBackend[state.init.sockdriveBackendName] ??
22
- sockdriveBackend["js-dos"]);
23
- const [myDrives, setMyDrives] = useState<Drive[]>([]);
24
- const dispatch = useDispatch();
25
- const preimium = account?.premium ?? false;
26
- const me = account?.email ?? "";
27
- const [filter, setFilter] = useState<string>("");
28
- const [busy, setBusy] = useState<boolean>(true);
29
- const forkDialogRef = useRef<HTMLDialogElement>(null);
30
- const deleteDialogRef = useRef<HTMLDialogElement>(null);
31
- const [forkName, setForkName] = useState<string>("");
32
- const [deleteConfirm, setDeleteConfirm] = useState<string>("");
33
- const [dialogError, setDialogError] = useState<string | null>(null);
34
- const [dialogIndex, setDialogIndex] = useState<number>(-1);
35
-
36
-
37
- function reloadDrives() {
38
- if (!account || !account.token) {
39
- setMyDrives([]);
40
- } else {
41
- setBusy(true);
42
- fetch(sockdriveEndpoint + "/list/drives/" + account.token.access_token)
43
- .then((r) => r.json())
44
- .then((drives: Drive[]) => {
45
- setMyDrives(drives.sort((a, b) => a.name.localeCompare(b.name)));
46
- })
47
- .catch(console.error)
48
- .finally(() => setBusy(false));
49
- }
50
- }
51
-
52
- useEffect(() => {
53
- reloadDrives();
54
- }, [account?.token, sockdriveEndpoint]);
55
-
56
- return <div class="frame-root items-start gap-3 px-4">
57
- <SockdriveBackend multiline={true} class="w-full " />
58
- <input class="input input-bordered input-sm w-full" placeholder={t("filter")}
59
- value={filter} onChange={(e) => setFilter(e.currentTarget.value ?? "")}></input>
60
- <div class="w-full">
61
- {!busy && <table class="table w-full">
62
- <thead>
63
- <tr>
64
- <th>{t("net_drives")}</th>
65
- <th></th>
66
- </tr>
67
- </thead>
68
- <tbody>
69
- {
70
- // eslint-disable-next-line camelcase
71
- myDrives.map(({ name, owner, fork_of }, index) => {
72
- if (filter.length > 0 &&
73
- owner.indexOf(filter) === -1 && name.indexOf(filter) === -1) {
74
- return null;
75
- }
76
- return <>
77
- <tr>
78
- <td onClick={() => { }}>
79
- <p class="font-bold">{name}</p>
80
- {
81
- // eslint-disable-next-line camelcase
82
- fork_of.map((path) => {
83
- return <p class="text-xs">&nbsp;&nbsp;&nbsp;&nbsp;{path}</p>;
84
- })}
85
- {owner !== account?.email &&
86
- <p class="text-xs">{owner}</p>}
87
- </td>
88
- {preimium && <td>
89
- {account?.token && <div class="btn btn-ghost btn-xs"
90
- onClick={() => {
91
- setDialogIndex(index);
92
- forkDialogRef.current?.showModal();
93
- }}>Fork</div>}
94
- {account?.token && owner === me && <div class="btn btn-xs btn-ghost"
95
- onClick={() => {
96
- setDialogIndex(index);
97
- deleteDialogRef.current?.showModal();
98
- }}>{t("delete")}</div>}
99
- </td>}
100
- {!preimium && <td>
101
- <div class="cursor-pointer"
102
- onClick={() => dispatchLoginAction(account, dispatch)}>
103
- <LockBadge class="text-error" />
104
- </div>
105
- </td>}
106
- </tr>
107
- </>;
108
- })}
109
- </tbody>
110
- </table>
111
- }
112
- {busy && <span class="loading loading-spinner loading-lg"></span>}
113
- </div>
114
- <dialog ref={forkDialogRef} class="modal">
115
- {!busy && dialogIndex >= 0 && account !== null && <div class="modal-box">
116
- <h3 class="font-bold text-lg">{t("enter_name_of_drive")}:</h3>
117
- <p class="text-xs text-neutral-content mt-2">
118
- fork of: {myDrives[dialogIndex].owner}/{myDrives[dialogIndex].name}
119
- </p>
120
- <input type="text" placeholder="name" value={forkName}
121
- class="mt-6 input input-bordered input-primary w-full" onChange={(e) =>
122
- setForkName(e.currentTarget.value)} />
123
- {dialogError !== null &&
124
- <p class="mt-2 text-error">{t("error")}: {dialogError}</p>}
125
- <div class="modal-action">
126
- {forkName.length > 0 && <button class="btn mr-2 btn-primary" onClick={() => {
127
- setDialogIndex(-1);
128
- setBusy(true);
129
- // eslint-disable-next-line max-len
130
- fetch(`${sockdriveEndpoint}/fork/drive/${myDrives[dialogIndex].owner}/${myDrives[dialogIndex].name}/${forkName}/${account.token.access_token}`, {
131
- method: "POST",
132
- })
133
- .then((r) => r.json())
134
- .then((response) => {
135
- if (response.error) {
136
- throw new Error(response.error);
137
- } else {
138
- setMyDrives([]);
139
- reloadDrives();
140
- }
141
- forkDialogRef.current?.close();
142
- })
143
- .catch((e) => {
144
- console.error(e.message);
145
- dispatch(uiSlice.actions
146
- .showToast({ message: e.message, intent: "error" }));
147
- })
148
- .finally(() => {
149
- setBusy(false);
150
- });
151
- }}>{t("fork")}</button>}
152
- <button class="btn" onClick={() => forkDialogRef.current?.close()}>{t("close")}</button>
153
- </div>
154
- </div>}
155
- </dialog>
156
- <dialog ref={deleteDialogRef} class="modal">
157
- {!busy && dialogIndex >= 0 && account !== null && <div class="modal-box">
158
- <h3 class="font-bold text-lg">{t("enter_name_of_drive")}:</h3>
159
- <p class="text-xs text-neutral mt-2">{myDrives[dialogIndex].owner}/{myDrives[dialogIndex].name}</p>
160
- <input type="text" placeholder="name" value={deleteConfirm}
161
- class="mt-6 input input-bordered input-primary w-full"
162
- onChange={(e) => setDeleteConfirm(e.currentTarget.value)} />
163
- {dialogError !== null &&
164
- <p class="mt-2 text-error">{t("error")}: {setDialogError}</p>}
165
- <div class="modal-action">
166
- {deleteConfirm === myDrives[dialogIndex].owner + "/" + myDrives[dialogIndex].name &&
167
- <button class="btn mr-2 btn-primary" onClick={() => {
168
- setDialogIndex(-1);
169
- setBusy(true);
170
- // eslint-disable-next-line max-len
171
- fetch(`${sockdriveEndpoint}/fork/delete/${myDrives[dialogIndex].owner}/${myDrives[dialogIndex].name}/${account.token.access_token}`, { method: "POST" })
172
- .then((r) => r.json())
173
- .then((response) => {
174
- if (response.error) {
175
- throw new Error(response.error);
176
- } else {
177
- const newDrives = [...myDrives];
178
- newDrives.splice(dialogIndex, 1);
179
- setMyDrives(newDrives);
180
- }
181
- deleteDialogRef.current?.close();
182
- })
183
- .catch((e) => {
184
- console.error(e.message);
185
- setDialogError(e.message);
186
- dispatch(uiSlice.actions
187
- .showToast({ message: e.message, intent: "error" }));
188
- })
189
- .finally(() => {
190
- setBusy(false);
191
- });
192
- }}>{t("delete")}</button>}
193
- <button class="btn" onClick={() => deleteDialogRef.current?.close()}>{t("close")}</button>
194
- </div>
195
- </div>
196
- }
197
- </dialog >
198
- </div >;
199
- }
@@ -1,119 +0,0 @@
1
- @import "./editor/editor-frame.css";
2
-
3
- .jsdos-rso {
4
- .frame-root {
5
- @apply flex flex-col;
6
- }
7
-
8
- .frame {
9
- @apply absolute left-0 top-0 pl-12 overflow-auto h-full w-96 py-4;
10
- background-color: hsl(var(--b3));
11
- }
12
-
13
- .frame-md {
14
- width: 100% !important;
15
- }
16
-
17
- .frame-xs {
18
- width: calc(var(--sidebar-width) * 2) !important;
19
- }
20
-
21
- .premium-plan-root {
22
- @apply bg-white rounded-xl px-4 pt-4 pb-2 w-64;
23
- }
24
-
25
- .premium-plan-root.have-premium {
26
- @apply bg-green-200;
27
- }
28
-
29
- .premium-plan-head {
30
- @apply text-blue-400;
31
- }
32
-
33
- .premium-plan-cost {
34
- @apply text-blue-600 text-5xl;
35
- }
36
-
37
- .premium-plan-cost-expl {
38
- @apply text-gray-600 ml-4 flex flex-col;
39
- }
40
-
41
- .premium-plan-highlight {
42
- @apply flex flex-row text-xs items-center py-2 border-b border-b-gray-200;
43
- @apply text-gray-600;
44
- }
45
-
46
- .premium-plan-root.have-premium .premium-plan-highlight {
47
- @apply border-b-green-300;
48
- }
49
-
50
- .settings-frame {
51
- @apply px-6 -mt-2;
52
-
53
- .label {
54
- @apply p-0;
55
- }
56
-
57
- .label-text {
58
- font-size: inherit;
59
- }
60
-
61
- .option {
62
- @apply w-full justify-between;
63
- }
64
-
65
- .slider {
66
- .touch {
67
- @apply w-40 flex-grow-0;
68
- }
69
- }
70
- }
71
-
72
- .image-rendering-frame {
73
- @apply px-6 -mt-2;
74
-
75
- .option {
76
- @apply w-full justify-between;
77
- }
78
- }
79
-
80
- .account-frame {
81
- .account-img {
82
- @apply w-24 h-24 my-8 rounded-full;
83
- }
84
-
85
- .account-email {
86
- @apply text-xs mt-4;
87
- }
88
- }
89
-
90
- .network-frame {
91
- @apply w-full;
92
-
93
- .option {
94
- @apply w-full;
95
- }
96
-
97
- .error {
98
- .label-text {
99
- @apply text-error;
100
- }
101
-
102
- input {
103
- border-color: hsl(var(--er) / var(--tw-border-opacity));
104
- --tw-border-opacity: 0.1;
105
- --tw-bg-opacity: 1;
106
- background-color: hsl(var(--er) / var(--tw-bg-opacity));
107
- --tw-text-opacity: 1;
108
- color: hsl(var(--erc, var(--nc)) / var(--tw-text-opacity));
109
- }
110
- }
111
- }
112
-
113
- .quick-save-frame {
114
- .text-badge {
115
- @apply absolute left-0 top-0 w-3 h-3 font-bold rounded-full flex items-center justify-center;
116
- font-size: 0.5rem;
117
- }
118
- }
119
- }
@@ -1,34 +0,0 @@
1
- import { useSelector } from "react-redux";
2
- import { State } from "../store";
3
- import { AccountFrame } from "./account-frame";
4
- import { EditorConf } from "./editor/editor-conf-frame";
5
- import { EditorFsFrame } from "./editor/editor-fs-frame";
6
- import { FatDrivesFrame } from "./fat-drives-frame";
7
- import { NetworkFrame } from "./network-frame";
8
- import { QuickSaveFrame } from "./quick-save-frame";
9
- import { SettingsFrame } from "./settings-frame";
10
- import { StatsFrame } from "./stats-frame";
11
- import { ImageRenderingFrame } from "./image-rendering-frame";
12
-
13
- export function Frame(props: {}) {
14
- const frame = useSelector((state: State) => state.ui.frame);
15
- const frameXs = useSelector((state: State) => state.ui.frameXs);
16
- const wideScreen = useSelector((state: State) => state.ui.wideScreen);
17
- if (frame === "none") {
18
- return null;
19
- }
20
-
21
-
22
- return <div class={"frame " + (frameXs ? " frame-xs " : "") +
23
- (frameXs || wideScreen ? "" : " frame-md")}>
24
- { frame === "account" && <AccountFrame /> }
25
- { frame === "settings" && <SettingsFrame /> }
26
- { frame === "editor-conf" && <EditorConf /> }
27
- { frame === "editor-fs" && <EditorFsFrame /> }
28
- { frame === "network" && <NetworkFrame /> }
29
- { frame === "stats" && <StatsFrame /> }
30
- { frame === "fat-drives" && <FatDrivesFrame /> }
31
- { frame === "quick-save" && <QuickSaveFrame /> }
32
- { frame === "image-rendering" && <ImageRenderingFrame /> }
33
- </div>;
34
- };
@@ -1,8 +0,0 @@
1
- import { ImageRenderingSelect, RenderAspectSelect } from "../components/dos-option-select";
2
-
3
- export function ImageRenderingFrame(props: {}) {
4
- return <div class="image-rendering-frame frame-root items-start pl-4">
5
- <RenderAspectSelect multiline={true} />
6
- <ImageRenderingSelect multiline={true} />
7
- </div>;
8
- }
@@ -1,157 +0,0 @@
1
- import { useEffect } from "preact/hooks";
2
- import { useDispatch, useSelector } from "react-redux";
3
- import { Checkbox } from "../components/checkbox";
4
- import { useT } from "../i18n";
5
- import { State } from "../store";
6
- import { dosSlice } from "../store/dos";
7
- import { Select } from "../components/select";
8
- import { dispatchLoginAction, uiSlice } from "../store/ui";
9
- import { LockBadge } from "../components/lock";
10
- import { Dispatch } from "@reduxjs/toolkit";
11
-
12
- export function NetworkFrame() {
13
- const account = useSelector((state: State) => state.auth.account);
14
- const network = useSelector((state: State) => state.dos.network);
15
- const room = network.room;
16
- const server = network.server;
17
- const disabled = network.ipx !== "disconnected";
18
- const t = useT();
19
- const dispatch = useDispatch();
20
- const premium = account?.premium === true;
21
- const ipxLink =
22
- network.ipx === "connected" ?
23
- location.href + searchSeparator() +
24
- "ipx=1&server=" + network.server + "&room=" + room :
25
- null;
26
-
27
- useEffect(() => {
28
- if (server !== "netherlands" && account?.premium !== true) {
29
- dispatch(dosSlice.actions.setServer("netherlands"));
30
- }
31
- }, [server, account]);
32
-
33
- function setRoom(room: string) {
34
- dispatch(dosSlice.actions.setRoom(room));
35
- }
36
-
37
- function setServer(server: string) {
38
- dispatch(dosSlice.actions.setServer(server as any));
39
- }
40
-
41
- function toggleIpx() {
42
- if (network.ipx === "connected") {
43
- dispatch(dosSlice.actions.disconnectIpx({}));
44
- } else {
45
- dispatch(dosSlice.actions.connectIpx({
46
- room,
47
- address: "wss://" + (premium ? server : "netherlands") + ".dos.zone",
48
- }) as any);
49
- }
50
- }
51
-
52
- function copyAndClose() {
53
- if (ipxLink) {
54
- copyToClipBoard(ipxLink, t, dispatch);
55
- dispatch(uiSlice.actions.frameNone());
56
- }
57
- }
58
-
59
- function lockClick() {
60
- dispatchLoginAction(account, dispatch);
61
- }
62
-
63
- function onServer(newServer: string) {
64
- setServer(newServer);
65
-
66
- if (!premium) {
67
- dispatchLoginAction(account, dispatch);
68
- return;
69
- }
70
- }
71
-
72
- return <div class="network-frame frame-root items-start px-4 relative">
73
- <div class="ml-1 mb-4 w-full flex flex-row items-center">
74
- <Select
75
- class="text-sm"
76
- selectClass="w-full"
77
- label={t("server") + ":"}
78
- selected={server}
79
- values={["netherlands", "newyork", "singapore"]}
80
- disabled={disabled}
81
- onSelect={onServer}
82
- />
83
- <div onClick={lockClick}>
84
- <LockBadge class="cursor-pointer ml-2 w-4 h-4 text-error" />
85
- </div>
86
- </div>
87
- <div class="form-control w-full">
88
- <label class="label">
89
- <span class="label-text">{t("room")}:</span>
90
- </label>
91
- <input type="text"
92
- class="input w-full input-sm input-bordered"
93
- disabled={disabled}
94
- onChange={(e) => setRoom(e.currentTarget.value)}
95
- value={room}></input>
96
- </div>
97
- <Checkbox
98
- class={"mt-4 " + (network.ipx === "error" ? "error" : "")}
99
- onChange={toggleIpx}
100
- label="IPX"
101
- checked={network.ipx === "connected"}
102
- disabled={network.ipx === "connecting"}
103
- intermediate={network.ipx === "connecting"}
104
- />
105
-
106
- {ipxLink !== null && <div class="mt-4 text-sm alert alert-success shadow-lg flex flex-col">
107
- <div>{t("copy_net_link")}:</div>
108
- <div class="flex flex-row">
109
- <svg xmlns="http://www.w3.org/2000/svg"
110
- class="w-6 h-6 mx-1 cursor-pointer hover:text-accent-focus flex-shrink-0"
111
- fill="none" onClick={copyAndClose}
112
- viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
113
- <path stroke-linecap="round"
114
- stroke-linejoin="round"
115
- d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125
116
- 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06
117
- 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504
118
- 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0
119
- 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5
120
- 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m12
121
- 6.625v-1.875a3.375 3.375 0 00-3.375-3.375h-1.5a1.125 1.125
122
- 0 01-1.125-1.125v-1.5a3.375 3.375 0 00-3.375-3.375H9.75" />
123
- </svg>
124
- <div class="contextmenu underline break-all"
125
- target="_blank">{ipxLink}</div>
126
- </div>
127
- </div>}
128
- </div >;
129
- }
130
-
131
- function searchSeparator() {
132
- if (location.href.endsWith("?") || location.href.endsWith("&")) {
133
- return "";
134
- }
135
- return location.href.indexOf("?") > 0 ? "&" : "?";
136
- }
137
-
138
- async function copyToClipBoard(text: string,
139
- t: (key: string) => string,
140
- dispatch: Dispatch) {
141
- if (!navigator.clipboard) {
142
- return;
143
- }
144
-
145
- try {
146
- await navigator.clipboard.writeText(text);
147
- dispatch(uiSlice.actions.showToast({
148
- message: t("copied"),
149
- intent: "success",
150
- }));
151
- } catch (e: any) {
152
- dispatch(uiSlice.actions.showToast({
153
- message: t("error"),
154
- intent: "error",
155
- }));
156
- }
157
- }
@@ -1,98 +0,0 @@
1
- import { useDispatch, useSelector } from "react-redux";
2
- import { LockBadge } from "../components/lock";
3
- import { CloudSaveButton } from "../sidebar/cloud-save-button";
4
- import { DisketteIcon } from "../sidebar/diskette-icon";
5
- import { State, useNonSerializableStore } from "../store";
6
- import { dispatchLoginAction } from "../store/ui";
7
-
8
- export function QuickSaveFrame() {
9
- const premium = useSelector((state: State) => state.auth.account)?.premium && false;
10
- return <div class="quick-save-frame flex flex-col justify-center items-center -my-2">
11
- <CloudSaveButton />
12
- <SaveButton label="quick" bgcolor="bg-primary" textcolor="text-primary-content" />
13
- <LoadButton label="quick" bgcolor="bg-primary" />
14
- {premium && <>
15
- <SaveButton disabled={!premium} label={2} bgcolor="bg-secondary" textcolor="text-secondary-content" />
16
- <LoadButton disabled={!premium} label={2} bgcolor="bg-secondary" />
17
- <SaveButton disabled={!premium} label={3} bgcolor="bg-accent" textcolor="text-accent-content" />
18
- <LoadButton disabled={!premium} label={3} bgcolor="bg-accent" />
19
- </>}
20
- </div>;
21
- }
22
-
23
- function SaveButton(props: {
24
- label: number | string,
25
- bgcolor: string,
26
- textcolor: string,
27
- disabled?: boolean,
28
- }) {
29
- const account = useSelector((state: State) => state.auth.account);
30
- const dispatch = useDispatch();
31
- const nonSerializableStore = useNonSerializableStore();
32
- function onClick() {
33
- if (props.disabled === true) {
34
- dispatchLoginAction(account, dispatch);
35
- }
36
-
37
- const ci = nonSerializableStore.ci;
38
- if (ci === null) {
39
- return;
40
- }
41
-
42
- ci.sendBackendEvent({
43
- type: "wc-trigger-event",
44
- event: "hand_savestate",
45
- });
46
- }
47
-
48
- return <div class={"sidebar-button flex justify-center " + (props.disabled ? "opacity-50" : "")}
49
- onClick={onClick}>
50
- <DisketteIcon />
51
- {props.disabled !== true &&
52
- <div class={"text-badge " + props.textcolor + " " + props.bgcolor}>{props.label}</div>}
53
- {props.disabled === true && <LockBadge />}
54
-
55
- <svg xmlns="http://www.w3.org/2000/svg" fill="none"
56
- viewBox="0 0 24 24" stroke-width="1.5"
57
- stroke="currentColor" class="absolute bottom-1 w-3 h-3">
58
- <path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18" />
59
- </svg>
60
- </div>;
61
- }
62
-
63
- function LoadButton(props: {
64
- label: number | string,
65
- bgcolor: string,
66
- disabled?: boolean,
67
- }) {
68
- const account = useSelector((state: State) => state.auth.account);
69
- const dispatch = useDispatch();
70
- const nonSerializableStore = useNonSerializableStore();
71
- function onClick() {
72
- if (props.disabled === true) {
73
- dispatchLoginAction(account, dispatch);
74
- }
75
-
76
- const ci = nonSerializableStore.ci;
77
- if (ci === null) {
78
- return;
79
- }
80
-
81
- ci.sendBackendEvent({
82
- type: "wc-trigger-event",
83
- event: "hand_loadstate",
84
- });
85
- }
86
-
87
- return <div class={"sidebar-button flex justify-center " + (props.disabled ? " opacity-50" : "")}
88
- onClick={onClick}>
89
- <DisketteIcon class="opacity-10" />
90
- {props.disabled === true && <LockBadge />}
91
- <svg xmlns="http://www.w3.org/2000/svg" fill="none"
92
- viewBox="0 0 24 24" stroke-width="1.5"
93
- stroke="currentColor" class="absolute bottom-1 w-6 h-6 -scale-y-100">
94
- <path stroke-linecap="round" stroke-linejoin="round"
95
- d="m15 15 6-6m0 0-6-6m6 6H9a6 6 0 0 0 0 12h3" />
96
- </svg>
97
- </div>;
98
- }
@@ -1,14 +0,0 @@
1
- import { Editor, MouseCapture, PauseCheckbox } from "../components/dos-option-checkbox";
2
- import { ThemeSelect } from "../components/dos-option-select";
3
- import { MouseSensitiviySlider, VolumeSlider } from "../components/dos-option-slider";
4
-
5
- export function SettingsFrame(props: {}) {
6
- return <div class="settings-frame frame-root items-start pl-4">
7
- <PauseCheckbox />
8
- <MouseCapture />
9
- <MouseSensitiviySlider />
10
- <VolumeSlider />
11
- <Editor />
12
- <ThemeSelect multiline={true} />
13
- </div>;
14
- }