prepare settings modal navigation
This commit is contained in:
Vendored
+9
-9
@@ -856,8 +856,8 @@ body[showing-chat] #chat-page-wrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* src/View/Components/fileBrowser.css */
|
/* src/View/Components/splitModal.css */
|
||||||
.file-browser {
|
.split-modal {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -866,7 +866,7 @@ body[showing-chat] #chat-page-wrapper {
|
|||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
scroll-snap-type: x mandatory;
|
scroll-snap-type: x mandatory;
|
||||||
}
|
}
|
||||||
.file-browser > div {
|
.split-modal > div {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -874,33 +874,33 @@ body[showing-chat] #chat-page-wrapper {
|
|||||||
flex: 0;
|
flex: 0;
|
||||||
scroll-snap-align: center;
|
scroll-snap-align: center;
|
||||||
}
|
}
|
||||||
.file-browser .scroll-area {
|
.split-modal .scroll-area {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: var(--content-padding);
|
padding: var(--content-padding);
|
||||||
}
|
}
|
||||||
.file-browser .detail-button-wrapper {
|
.split-modal .detail-button-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: end;
|
justify-content: end;
|
||||||
border-top: 1px solid var(--border);
|
border-top: 1px solid var(--border);
|
||||||
padding: var(--content-padding);
|
padding: var(--content-padding);
|
||||||
}
|
}
|
||||||
.file-browser .detail-button-wrapper button {
|
.split-modal .detail-button-wrapper button {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
.file-browser code {
|
.split-modal code {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
.file-browser > div {
|
.split-modal > div {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
min-width: 50%;
|
min-width: 50%;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
.file-browser .detail-button-wrapper {
|
.split-modal .detail-button-wrapper {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+63
-19
@@ -2748,6 +2748,12 @@
|
|||||||
addChatPlaceholder: "Add chat",
|
addChatPlaceholder: "Add chat",
|
||||||
addChatButton: "Add chat"
|
addChatButton: "Add chat"
|
||||||
},
|
},
|
||||||
|
settings: {
|
||||||
|
pages: {
|
||||||
|
appearance: "Appearance",
|
||||||
|
regional: "Language & Region"
|
||||||
|
}
|
||||||
|
},
|
||||||
connectionModal: {
|
connectionModal: {
|
||||||
connectionModalHeadline: "Manage Connections",
|
connectionModalHeadline: "Manage Connections",
|
||||||
///
|
///
|
||||||
@@ -6194,6 +6200,9 @@
|
|||||||
this.usernameInput = new State("");
|
this.usernameInput = new State("");
|
||||||
this.firstDayOfWeekInput = new State("0");
|
this.firstDayOfWeekInput = new State("0");
|
||||||
this.isShowingSettingsModal = new State(false);
|
this.isShowingSettingsModal = new State(false);
|
||||||
|
this.selectedModalPage = new State(
|
||||||
|
0 /* Appearance */
|
||||||
|
);
|
||||||
// guards
|
// guards
|
||||||
this.cannotSetName = createProxyState(
|
this.cannotSetName = createProxyState(
|
||||||
[this.usernameInput],
|
[this.usernameInput],
|
||||||
@@ -6214,6 +6223,9 @@
|
|||||||
this.hideSettingsModal = () => {
|
this.hideSettingsModal = () => {
|
||||||
this.isShowingSettingsModal.value = false;
|
this.isShowingSettingsModal.value = false;
|
||||||
};
|
};
|
||||||
|
this.showModalPage = (page) => {
|
||||||
|
this.selectedModalPage.value = page;
|
||||||
|
};
|
||||||
this.settingsModel = settingsModel2;
|
this.settingsModel = settingsModel2;
|
||||||
this.username.value = settingsModel2.username;
|
this.username.value = settingsModel2.username;
|
||||||
this.usernameInput.value = settingsModel2.username;
|
this.usernameInput.value = settingsModel2.username;
|
||||||
@@ -6222,6 +6234,21 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// src/View/Components/splitModal.tsx
|
||||||
|
function SplitModal(leftView, rightView, scrollButtonLabel) {
|
||||||
|
const view = /* @__PURE__ */ createElement("div", { class: "split-modal" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("div", { class: "scroll-area", "children:set": leftView }), /* @__PURE__ */ createElement("div", { class: "detail-button-wrapper" }, /* @__PURE__ */ createElement("button", { class: "ghost", "on:click": scrollToDetails }, /* @__PURE__ */ createElement(
|
||||||
|
"span",
|
||||||
|
{
|
||||||
|
class: "ellipsis",
|
||||||
|
"subscribe:innerText": scrollButtonLabel
|
||||||
|
}
|
||||||
|
), /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_forward")))), /* @__PURE__ */ createElement("div", { class: "scroll-area", "children:set": rightView }));
|
||||||
|
function scrollToDetails() {
|
||||||
|
view.scrollLeft = view.scrollWidth;
|
||||||
|
}
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
// src/View/Components/directoryItemList.tsx
|
// src/View/Components/directoryItemList.tsx
|
||||||
function DirectoryItemList(storageViewModel2, pathString = PATH_COMPONENT_SEPARATOR) {
|
function DirectoryItemList(storageViewModel2, pathString = PATH_COMPONENT_SEPARATOR) {
|
||||||
const StringToDirectoryItemList = (pathString2) => DirectoryItemList(storageViewModel2, pathString2);
|
const StringToDirectoryItemList = (pathString2) => DirectoryItemList(storageViewModel2, pathString2);
|
||||||
@@ -6271,8 +6298,8 @@
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/View/Components/fileBrowser.tsx
|
// src/View/Modals/storageModal.tsx
|
||||||
function FileBrowser(storageViewModel2) {
|
function StorageModal(storageViewModel2) {
|
||||||
const detailView = createProxyState(
|
const detailView = createProxyState(
|
||||||
[storageViewModel2.selectedPath],
|
[storageViewModel2.selectedPath],
|
||||||
() => {
|
() => {
|
||||||
@@ -6300,22 +6327,11 @@
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const view = /* @__PURE__ */ createElement("div", { class: "file-browser" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("div", { class: "scroll-area" }, DirectoryItemList(storageViewModel2)), /* @__PURE__ */ createElement("div", { class: "detail-button-wrapper" }, /* @__PURE__ */ createElement("button", { class: "ghost", "on:click": scrollToDetails }, /* @__PURE__ */ createElement(
|
return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": storageViewModel2.isShowingStorageModal }, /* @__PURE__ */ createElement("div", { style: "max-width: 64rem" }, /* @__PURE__ */ createElement("main", { class: "padding-0" }, SplitModal(
|
||||||
"span",
|
new State(DirectoryItemList(storageViewModel2)),
|
||||||
{
|
detailView,
|
||||||
class: "ellipsis",
|
storageViewModel2.selectedFileName
|
||||||
"subscribe:innerText": storageViewModel2.selectedFileName
|
)), /* @__PURE__ */ createElement("button", { "on:click": storageViewModel2.hideStorageModal }, translations.general.closeButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "close"))));
|
||||||
}
|
|
||||||
), /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_forward")))), /* @__PURE__ */ createElement("div", { class: "scroll-area", "children:set": detailView }));
|
|
||||||
function scrollToDetails() {
|
|
||||||
view.scrollLeft = view.scrollWidth;
|
|
||||||
}
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
// src/View/Modals/storageModal.tsx
|
|
||||||
function StorageModal(storageViewModel2) {
|
|
||||||
return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": storageViewModel2.isShowingStorageModal }, /* @__PURE__ */ createElement("div", { style: "max-width: 64rem" }, /* @__PURE__ */ createElement("main", { class: "padding-0" }, FileBrowser(storageViewModel2)), /* @__PURE__ */ createElement("button", { "on:click": storageViewModel2.hideStorageModal }, translations.general.closeButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "close"))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/ViewModel/Global/storageViewModel.ts
|
// src/ViewModel/Global/storageViewModel.ts
|
||||||
@@ -6574,7 +6590,35 @@
|
|||||||
|
|
||||||
// src/View/Modals/settingsModal.tsx
|
// src/View/Modals/settingsModal.tsx
|
||||||
function SettingsModal(settingsViewModel2) {
|
function SettingsModal(settingsViewModel2) {
|
||||||
return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": settingsViewModel2.isShowingSettingsModal }, /* @__PURE__ */ createElement("div", { style: "max-width: 64rem" }, /* @__PURE__ */ createElement("main", { class: "padding-0" }), /* @__PURE__ */ createElement("button", { "on:click": settingsViewModel2.hideSettingsModal }, translations.general.closeButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "close"))));
|
return /* @__PURE__ */ createElement(
|
||||||
|
"div",
|
||||||
|
{
|
||||||
|
class: "modal",
|
||||||
|
"toggle:open": settingsViewModel2.isShowingSettingsModal
|
||||||
|
},
|
||||||
|
/* @__PURE__ */ createElement("div", { style: "max-width: 64rem" }, /* @__PURE__ */ createElement("main", { class: "padding-0" }, SplitModal(
|
||||||
|
new State(SettingsLeftPane(settingsViewModel2)),
|
||||||
|
new State(/* @__PURE__ */ createElement("span", null, "settings")),
|
||||||
|
new State("")
|
||||||
|
)), /* @__PURE__ */ createElement("button", { "on:click": settingsViewModel2.hideSettingsModal }, translations.general.closeButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "close")))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function SettingsLeftPane(settingsViewModel2) {
|
||||||
|
return /* @__PURE__ */ createElement("div", { class: "flex-column" }, SettingsPaneButton(settingsViewModel2, 0 /* Appearance */, translations.settings.pages.appearance), SettingsPaneButton(settingsViewModel2, 1 /* Regional */, translations.settings.pages.regional));
|
||||||
|
}
|
||||||
|
function SettingsPaneButton(settingsViewModel2, page, label) {
|
||||||
|
const isSelected = createProxyState(
|
||||||
|
[settingsViewModel2.selectedModalPage],
|
||||||
|
() => settingsViewModel2.selectedModalPage.value == page
|
||||||
|
);
|
||||||
|
return /* @__PURE__ */ createElement(
|
||||||
|
"button",
|
||||||
|
{
|
||||||
|
"toggle:selected": isSelected,
|
||||||
|
"on:click": () => settingsViewModel2.showModalPage(page)
|
||||||
|
},
|
||||||
|
label
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/index.tsx
|
// src/index.tsx
|
||||||
|
|||||||
@@ -1,93 +0,0 @@
|
|||||||
import "./fileBrowser.css";
|
|
||||||
|
|
||||||
import * as React from "bloatless-react";
|
|
||||||
|
|
||||||
import { DangerousActionButton } from "./dangerousActionButton";
|
|
||||||
import { DirectoryItemList } from "./directoryItemList";
|
|
||||||
import { PATH_COMPONENT_SEPARATOR } from "../../Model/Global/storageModel";
|
|
||||||
import StorageViewModel from "../../ViewModel/Global/storageViewModel";
|
|
||||||
import { translations } from "../translations";
|
|
||||||
|
|
||||||
export function FileBrowser(storageViewModel: StorageViewModel) {
|
|
||||||
const detailView = React.createProxyState(
|
|
||||||
[storageViewModel.selectedPath],
|
|
||||||
() => {
|
|
||||||
if (storageViewModel.selectedPath.value == PATH_COMPONENT_SEPARATOR)
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<span class="secondary">
|
|
||||||
{translations.storage.noItemSelected}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<hr></hr>
|
|
||||||
|
|
||||||
{DangerousActionButton(
|
|
||||||
translations.storage.removeJunkButton,
|
|
||||||
"delete_forever",
|
|
||||||
storageViewModel.removeJunk,
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div class="flex-column gap">
|
|
||||||
<div class="tile flex-no">
|
|
||||||
<div>
|
|
||||||
<b>{translations.storage.path}</b>
|
|
||||||
<span
|
|
||||||
class="break-all"
|
|
||||||
subscribe:innerText={
|
|
||||||
storageViewModel.selectedPath
|
|
||||||
}
|
|
||||||
></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="tile flex-no">
|
|
||||||
<div>
|
|
||||||
<b>{translations.storage.content}</b>
|
|
||||||
<code
|
|
||||||
subscribe:innerText={
|
|
||||||
storageViewModel.selectedFileContent
|
|
||||||
}
|
|
||||||
></code>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{DangerousActionButton(
|
|
||||||
translations.storage.deleteItem,
|
|
||||||
"delete_forever",
|
|
||||||
storageViewModel.deleteSelectedItem,
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const view = (
|
|
||||||
<div class="file-browser">
|
|
||||||
<div>
|
|
||||||
<div class="scroll-area">
|
|
||||||
{DirectoryItemList(storageViewModel)}
|
|
||||||
</div>
|
|
||||||
<div class="detail-button-wrapper">
|
|
||||||
<button class="ghost" on:click={scrollToDetails}>
|
|
||||||
<span
|
|
||||||
class="ellipsis"
|
|
||||||
subscribe:innerText={
|
|
||||||
storageViewModel.selectedFileName
|
|
||||||
}
|
|
||||||
></span>
|
|
||||||
<span class="icon">arrow_forward</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="scroll-area" children:set={detailView}></div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
function scrollToDetails() {
|
|
||||||
view.scrollLeft = view.scrollWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
.file-browser {
|
.split-modal {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
scroll-snap-type: x mandatory;
|
scroll-snap-type: x mandatory;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-browser > div {
|
.split-modal > div {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
scroll-snap-align: center;
|
scroll-snap-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-browser .scroll-area {
|
.split-modal .scroll-area {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
padding: var(--content-padding);
|
padding: var(--content-padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-browser .detail-button-wrapper {
|
.split-modal .detail-button-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: end;
|
justify-content: end;
|
||||||
|
|
||||||
@@ -37,11 +37,11 @@
|
|||||||
padding: var(--content-padding);
|
padding: var(--content-padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-browser .detail-button-wrapper button {
|
.split-modal .detail-button-wrapper button {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-browser code {
|
.split-modal code {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
@@ -49,14 +49,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
.file-browser > div {
|
.split-modal > div {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
min-width: 50%;
|
min-width: 50%;
|
||||||
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-browser .detail-button-wrapper {
|
.split-modal .detail-button-wrapper {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import "./splitModal.css";
|
||||||
|
|
||||||
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
|
export function SplitModal(
|
||||||
|
leftView: React.State<Element>,
|
||||||
|
rightView: React.State<Element>,
|
||||||
|
scrollButtonLabel: React.State<string>,
|
||||||
|
) {
|
||||||
|
const view = (
|
||||||
|
<div class="split-modal">
|
||||||
|
<div>
|
||||||
|
<div class="scroll-area" children:set={leftView}></div>
|
||||||
|
<div class="detail-button-wrapper">
|
||||||
|
<button class="ghost" on:click={scrollToDetails}>
|
||||||
|
<span
|
||||||
|
class="ellipsis"
|
||||||
|
subscribe:innerText={scrollButtonLabel}
|
||||||
|
></span>
|
||||||
|
<span class="icon">arrow_forward</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="scroll-area" children:set={rightView}></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
function scrollToDetails() {
|
||||||
|
view.scrollLeft = view.scrollWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
@@ -1,15 +1,25 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { FileBrowser } from "../Components/fileBrowser";
|
|
||||||
import StorageViewModel from "../../ViewModel/Global/storageViewModel";
|
|
||||||
import { translations } from "../translations";
|
import { translations } from "../translations";
|
||||||
import SettingsViewModel from "../../ViewModel/Global/settingsViewModel";
|
import SettingsViewModel, {
|
||||||
|
SettingsModalPages,
|
||||||
|
} from "../../ViewModel/Global/settingsViewModel";
|
||||||
|
import { SplitModal } from "../Components/splitModal";
|
||||||
|
|
||||||
export function SettingsModal(settingsViewModel: SettingsViewModel) {
|
export function SettingsModal(settingsViewModel: SettingsViewModel) {
|
||||||
return (
|
return (
|
||||||
<div class="modal" toggle:open={settingsViewModel.isShowingSettingsModal}>
|
<div
|
||||||
|
class="modal"
|
||||||
|
toggle:open={settingsViewModel.isShowingSettingsModal}
|
||||||
|
>
|
||||||
<div style="max-width: 64rem">
|
<div style="max-width: 64rem">
|
||||||
<main class="padding-0"></main>
|
<main class="padding-0">
|
||||||
|
{SplitModal(
|
||||||
|
new React.State(SettingsLeftPane(settingsViewModel)),
|
||||||
|
new React.State(<span>settings</span>),
|
||||||
|
new React.State(""),
|
||||||
|
)}
|
||||||
|
</main>
|
||||||
<button on:click={settingsViewModel.hideSettingsModal}>
|
<button on:click={settingsViewModel.hideSettingsModal}>
|
||||||
{translations.general.closeButton}
|
{translations.general.closeButton}
|
||||||
<span class="icon">close</span>
|
<span class="icon">close</span>
|
||||||
@@ -18,3 +28,40 @@ export function SettingsModal(settingsViewModel: SettingsViewModel) {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function SettingsLeftPane(settingsViewModel: SettingsViewModel) {
|
||||||
|
return (
|
||||||
|
<div class="flex-column">
|
||||||
|
{SettingsPaneButton(
|
||||||
|
settingsViewModel,
|
||||||
|
SettingsModalPages.Appearance,
|
||||||
|
translations.settings.pages.appearance,
|
||||||
|
)}
|
||||||
|
{SettingsPaneButton(
|
||||||
|
settingsViewModel,
|
||||||
|
SettingsModalPages.Regional,
|
||||||
|
translations.settings.pages.regional,
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SettingsPaneButton(
|
||||||
|
settingsViewModel: SettingsViewModel,
|
||||||
|
page: SettingsModalPages,
|
||||||
|
label: string,
|
||||||
|
) {
|
||||||
|
const isSelected = React.createProxyState(
|
||||||
|
[settingsViewModel.selectedModalPage],
|
||||||
|
() => settingsViewModel.selectedModalPage.value == page,
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
toggle:selected={isSelected}
|
||||||
|
on:click={() => settingsViewModel.showModalPage(page)}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,14 +1,77 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { FileBrowser } from "../Components/fileBrowser";
|
import { PATH_COMPONENT_SEPARATOR } from "../../Model/Global/storageModel";
|
||||||
import StorageViewModel from "../../ViewModel/Global/storageViewModel";
|
import StorageViewModel from "../../ViewModel/Global/storageViewModel";
|
||||||
import { translations } from "../translations";
|
import { translations } from "../translations";
|
||||||
|
|
||||||
|
import { SplitModal } from "../Components/splitModal";
|
||||||
|
import { DangerousActionButton } from "../Components/dangerousActionButton";
|
||||||
|
import { DirectoryItemList } from "../Components/directoryItemList";
|
||||||
|
|
||||||
export function StorageModal(storageViewModel: StorageViewModel) {
|
export function StorageModal(storageViewModel: StorageViewModel) {
|
||||||
|
const detailView = React.createProxyState(
|
||||||
|
[storageViewModel.selectedPath],
|
||||||
|
() => {
|
||||||
|
if (storageViewModel.selectedPath.value == PATH_COMPONENT_SEPARATOR)
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<span class="secondary">
|
||||||
|
{translations.storage.noItemSelected}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<hr></hr>
|
||||||
|
|
||||||
|
{DangerousActionButton(
|
||||||
|
translations.storage.removeJunkButton,
|
||||||
|
"delete_forever",
|
||||||
|
storageViewModel.removeJunk,
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class="flex-column gap">
|
||||||
|
<div class="tile flex-no">
|
||||||
|
<div>
|
||||||
|
<b>{translations.storage.path}</b>
|
||||||
|
<span
|
||||||
|
class="break-all"
|
||||||
|
subscribe:innerText={
|
||||||
|
storageViewModel.selectedPath
|
||||||
|
}
|
||||||
|
></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tile flex-no">
|
||||||
|
<div>
|
||||||
|
<b>{translations.storage.content}</b>
|
||||||
|
<code
|
||||||
|
subscribe:innerText={
|
||||||
|
storageViewModel.selectedFileContent
|
||||||
|
}
|
||||||
|
></code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{DangerousActionButton(
|
||||||
|
translations.storage.deleteItem,
|
||||||
|
"delete_forever",
|
||||||
|
storageViewModel.deleteSelectedItem,
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<div class="modal" toggle:open={storageViewModel.isShowingStorageModal}>
|
<div class="modal" toggle:open={storageViewModel.isShowingStorageModal}>
|
||||||
<div style="max-width: 64rem">
|
<div style="max-width: 64rem">
|
||||||
<main class="padding-0">{FileBrowser(storageViewModel)}</main>
|
<main class="padding-0">
|
||||||
|
{SplitModal(
|
||||||
|
new React.State(DirectoryItemList(storageViewModel)),
|
||||||
|
detailView,
|
||||||
|
storageViewModel.selectedFileName,
|
||||||
|
)}
|
||||||
|
</main>
|
||||||
<button on:click={storageViewModel.hideStorageModal}>
|
<button on:click={storageViewModel.hideStorageModal}>
|
||||||
{translations.general.closeButton}
|
{translations.general.closeButton}
|
||||||
<span class="icon">close</span>
|
<span class="icon">close</span>
|
||||||
|
|||||||
@@ -76,6 +76,13 @@ const englishTranslations = {
|
|||||||
addChatButton: "Add chat",
|
addChatButton: "Add chat",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
settings: {
|
||||||
|
pages: {
|
||||||
|
appearance: "Appearance",
|
||||||
|
regional: "Language+Region",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
connectionModal: {
|
connectionModal: {
|
||||||
connectionModalHeadline: "Manage Connections",
|
connectionModalHeadline: "Manage Connections",
|
||||||
|
|
||||||
@@ -358,6 +365,13 @@ const allTranslations: { [language: string]: typeof englishTranslations } = {
|
|||||||
addChatButton: "Chat hinzufügen",
|
addChatButton: "Chat hinzufügen",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
settings: {
|
||||||
|
pages: {
|
||||||
|
appearance: "Erscheinungsbild",
|
||||||
|
regional: "Sprache+Region",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
connectionModal: {
|
connectionModal: {
|
||||||
connectionModalHeadline: "Verbindungen verwalten",
|
connectionModalHeadline: "Verbindungen verwalten",
|
||||||
|
|
||||||
@@ -611,6 +625,12 @@ const allTranslations: { [language: string]: typeof englishTranslations } = {
|
|||||||
addChatButton: "Añadir chat",
|
addChatButton: "Añadir chat",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
settings: {
|
||||||
|
pages: {
|
||||||
|
appearance: "Aspecto",
|
||||||
|
regional: "Idioma+Región",
|
||||||
|
},
|
||||||
|
},
|
||||||
connectionModal: {
|
connectionModal: {
|
||||||
connectionModalHeadline: "Gestionar Conexiones",
|
connectionModalHeadline: "Gestionar Conexiones",
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ export default class SettingsViewModel {
|
|||||||
usernameInput: React.State<string> = new React.State("");
|
usernameInput: React.State<string> = new React.State("");
|
||||||
firstDayOfWeekInput: React.State<string> = new React.State("0");
|
firstDayOfWeekInput: React.State<string> = new React.State("0");
|
||||||
isShowingSettingsModal: React.State<boolean> = new React.State(false);
|
isShowingSettingsModal: React.State<boolean> = new React.State(false);
|
||||||
|
selectedModalPage: React.State<SettingsModalPages> = new React.State(
|
||||||
|
SettingsModalPages.Appearance,
|
||||||
|
);
|
||||||
|
|
||||||
// guards
|
// guards
|
||||||
cannotSetName: React.State<boolean> = React.createProxyState(
|
cannotSetName: React.State<boolean> = React.createProxyState(
|
||||||
@@ -33,11 +36,15 @@ export default class SettingsViewModel {
|
|||||||
|
|
||||||
showSettingsModal = (): void => {
|
showSettingsModal = (): void => {
|
||||||
this.isShowingSettingsModal.value = true;
|
this.isShowingSettingsModal.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
hideSettingsModal = (): void => {
|
hideSettingsModal = (): void => {
|
||||||
this.isShowingSettingsModal.value = false;
|
this.isShowingSettingsModal.value = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
showModalPage = (page: SettingsModalPages): void => {
|
||||||
|
this.selectedModalPage.value = page;
|
||||||
|
};
|
||||||
|
|
||||||
// init
|
// init
|
||||||
constructor(
|
constructor(
|
||||||
@@ -54,3 +61,8 @@ export default class SettingsViewModel {
|
|||||||
this.firstDayOfWeekInput.subscribe(this.setFirstDayofWeek);
|
this.firstDayOfWeekInput.subscribe(this.setFirstDayofWeek);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum SettingsModalPages {
|
||||||
|
Appearance,
|
||||||
|
Regional,
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user