diff --git a/dist/index.css b/dist/index.css index a2171347..3c534b17 100644 --- a/dist/index.css +++ b/dist/index.css @@ -864,19 +864,34 @@ body[showing-chat] #chat-page-wrapper { scroll-snap-type: x mandatory; } .split-modal > div { - display: flex; - flex-direction: column; width: 100%; min-width: calc(100% - 4rem); flex: 0; scroll-snap-align: center; } +.split-modal > div, +.split-modal > div > .scroll-area { + width: 100%; + display: flex; + flex-direction: column; + align-items: stretch; + justify-content: safe center; +} +.split-modal[navigation] > div > .scroll-area { + justify-content: start; +} +.split-modal[navigation] > div { + min-width: 100%; +} .split-modal .scroll-area { flex: 1; width: 100%; overflow-y: auto; padding: var(--content-padding); } +.split-modal[navigation] > div:nth-child(2) > .flex-row > button { + transform: translateX(calc(-1 * var(--content-padding))); +} .split-modal .detail-button-wrapper { display: flex; justify-content: end; @@ -896,11 +911,14 @@ body[showing-chat] #chat-page-wrapper { flex: 1; min-width: unset; } - .split-modal:not([primitive]) > div:first-child { + .split-modal[navigation] > div { + min-width: unset; + } + .split-modal[navigation] > div:first-child { flex: 0; min-width: 20rem; } - .split-modal[primitive] > div { + .split-modal:not([navigation]) > div { width: 50%; min-width: 50%; } @@ -908,3 +926,11 @@ body[showing-chat] #chat-page-wrapper { display: none; } } +@media (max-width: 640px) { + .split-modal[navigation]:not([page-open]) > div:nth-child(2) { + display: none; + } + .split-modal[navigation][page-open] > div:first-child { + display: none; + } +} diff --git a/dist/index.js b/dist/index.js index d6b49b24..db4127bb 100644 --- a/dist/index.js +++ b/dist/index.js @@ -5025,7 +5025,8 @@ fileVersionLabel: "Version", searchLabel: "Search", waitingLabel: "Waiting...", - restoreConnection: "Restore connection" + restoreConnection: "Restore connection", + noPageSelected: "No page selected" }, regional: { weekdays: { @@ -5237,7 +5238,8 @@ fileVersionLabel: "Version", searchLabel: "Suche", waitingLabel: "Warten...", - restoreConnection: "Verbindung wiederherstellen" + restoreConnection: "Verbindung wiederherstellen", + noPageSelected: "Keine Seite ausgew\xE4hlt" }, regional: { weekdays: { @@ -5430,7 +5432,8 @@ fileVersionLabel: "Versi\xF3n", searchLabel: "Buscar", waitingLabel: "Esperando...", - restoreConnection: "Conectar de nuevo" + restoreConnection: "Conectar de nuevo", + noPageSelected: "No p\xE1gina seleccionada" }, regional: { weekdays: { @@ -6350,9 +6353,7 @@ this.username = new State(""); this.usernameInput = new State(""); this.isShowingSettingsModal = new State(false); - this.selectedModalPage = new State( - 0 /* Appearance */ - ); + this.selectedModalPage = new State(void 0); this.requiresReload = new State(false); this.firstDayOfWeek = new State("0"); this.language = new State( @@ -6428,21 +6429,40 @@ }; // src/View/Components/splitModal.tsx - function SplitModal(leftView, rightView, extendedStyle = false, navigationState) { + function SplitModal(coreViewModel2, leftView, rightView, extendedStyle = false, navigationState) { + function closePage() { + navigationState.value = void 0; + } + const hasPageOpen = new State(false); + navigationState?.subscribe( + (newValue) => hasPageOpen.value = newValue != void 0 + ); const view = /* @__PURE__ */ createElement( "div", { class: "split-modal", "toggle:extended": extendedStyle, - "toggle:primitive": navigationState == void 0 + "toggle:navigation": navigationState != void 0, + "toggle:page-open": hasPageOpen }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("div", { class: "scroll-area", "children:set": leftView })), - /* @__PURE__ */ createElement("div", { class: "scroll-area", "children:set": rightView }) + /* @__PURE__ */ createElement("div", { class: "scroll-area slide-up" }, /* @__PURE__ */ createElement( + "div", + { + class: "flex-row width-100 mobile-only", + "toggle:hidden": navigationState == void 0 + }, + /* @__PURE__ */ createElement( + "button", + { + class: "ghost square", + "aria-label": coreViewModel2.translations.general.backButton, + "on:click": closePage + }, + /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_back") + ) + ), /* @__PURE__ */ createElement("div", { "children:set": rightView })) ); - function scrollToDetails() { - view.scrollLeft = view.scrollWidth; - } - navigationState?.subscribe(scrollToDetails); return view; } @@ -6527,6 +6547,7 @@ } ); return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": storageViewModel2.isShowingStorageModal }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", { class: "padding-0" }, SplitModal( + coreViewModel2, new State(DirectoryItemList(storageViewModel2)), detailView, true @@ -6819,6 +6840,11 @@ [settingsViewModel2.selectedModalPage], () => { switch (settingsViewModel2.selectedModalPage.value) { + case void 0: { + return PlaceholderView( + coreViewModel2.translations.general.noPageSelected + ); + } case 0 /* Appearance */: return SettingsAppearancePane( coreViewModel2, @@ -6841,6 +6867,7 @@ "toggle:open": settingsViewModel2.isShowingSettingsModal }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", { class: "padding-0" }, SplitModal( + coreViewModel2, new State( SettingsLeftPane(coreViewModel2, settingsViewModel2) ), @@ -6851,7 +6878,7 @@ ); } function SettingsLeftPane(coreViewModel2, settingsViewModel2) { - return /* @__PURE__ */ createElement("div", { class: "flex-column gap" }, SettingsPaneButton( + return /* @__PURE__ */ createElement("div", { class: "flex-column gap slide-up" }, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.homePage.settingsButton), SettingsPaneButton( settingsViewModel2, 0 /* Appearance */, coreViewModel2.translations.settings.pages.appearance diff --git a/dist/styles.css b/dist/styles.css index ec7afa06..fe2a9757 100644 --- a/dist/styles.css +++ b/dist/styles.css @@ -1128,7 +1128,7 @@ main { @media (min-width: 640px) { /* basic */ .mobile-only { - display: none; + display: none !important; } /* border, outline, etc */ diff --git a/src/View/Components/splitModal.css b/src/View/Components/splitModal.css index 96b74dbc..b3c2a289 100644 --- a/src/View/Components/splitModal.css +++ b/src/View/Components/splitModal.css @@ -15,9 +15,6 @@ } .split-modal > div { - display: flex; - flex-direction: column; - width: 100%; min-width: calc(100% - 4rem); flex: 0; @@ -25,6 +22,25 @@ scroll-snap-align: center; } +.split-modal > div, +.split-modal > div > .scroll-area { + width: 100%; + + display: flex; + flex-direction: column; + + align-items: stretch; + justify-content: safe center; +} + +.split-modal[navigation] > div > .scroll-area{ + justify-content: start; +} + +.split-modal[navigation] > div { + min-width: 100%; +} + .split-modal .scroll-area { flex: 1; width: 100%; @@ -33,6 +49,10 @@ padding: var(--content-padding); } +.split-modal[navigation] > div:nth-child(2) > .flex-row > button { + transform: translateX(calc(-1 * var(--content-padding))); +} + .split-modal .detail-button-wrapper { display: flex; justify-content: end; @@ -58,12 +78,16 @@ min-width: unset; } - .split-modal:not([primitive]) > div:first-child { + .split-modal[navigation] > div { + min-width: unset; + } + + .split-modal[navigation] > div:first-child { flex: 0; min-width: 20rem; } - .split-modal[primitive] > div { + .split-modal:not([navigation]) > div { width: 50%; min-width: 50%; } @@ -72,3 +96,13 @@ display: none; } } + +@media (max-width: 640px) { + .split-modal[navigation]:not([page-open]) > div:nth-child(2) { + display: none; + } + + .split-modal[navigation][page-open] > div:first-child { + display: none; + } +} diff --git a/src/View/Components/splitModal.tsx b/src/View/Components/splitModal.tsx index 8c4e786c..0910ddbb 100644 --- a/src/View/Components/splitModal.tsx +++ b/src/View/Components/splitModal.tsx @@ -1,31 +1,53 @@ +import CoreViewModel from "../../ViewModel/Global/coreViewModel"; import "./splitModal.css"; import * as React from "bloatless-react"; -export function SplitModal( +export function SplitModal( + coreViewModel: CoreViewModel, leftView: React.State, rightView: React.State, extendedStyle: boolean = false, - navigationState?: React.State, + navigationState?: React.State, ) { + function closePage() { + navigationState.value = undefined; + } + + const hasPageOpen = new React.State(false); + navigationState?.subscribe( + (newValue) => (hasPageOpen.value = newValue != undefined), + ); + const view = (
-
+
+
+ +
+
+
); - function scrollToDetails() { - view.scrollLeft = view.scrollWidth; - } - - navigationState?.subscribe(scrollToDetails); - return view; } diff --git a/src/View/Modals/settingsModal.tsx b/src/View/Modals/settingsModal.tsx index aa275c6a..fb927e18 100644 --- a/src/View/Modals/settingsModal.tsx +++ b/src/View/Modals/settingsModal.tsx @@ -11,6 +11,7 @@ import CoreViewModel from "../../ViewModel/Global/coreViewModel"; import { Languages, ThemeSettings } from "../../Model/Global/settingsModel"; import { OptionButtonList } from "../Components/optionButtonList"; import { stringify } from "../../Model/Utility/utility"; +import { PlaceholderView } from "../Components/placeholderView"; export function SettingsModal( coreViewModel: CoreViewModel, @@ -20,6 +21,11 @@ export function SettingsModal( [settingsViewModel.selectedModalPage], () => { switch (settingsViewModel.selectedModalPage.value) { + case undefined: { + return PlaceholderView( + coreViewModel.translations.general.noPageSelected, + ); + } case SettingsModalPages.Appearance: return SettingsAppearancePane( coreViewModel, @@ -44,6 +50,7 @@ export function SettingsModal(
{SplitModal( + coreViewModel, new React.State( SettingsLeftPane(coreViewModel, settingsViewModel), ), @@ -66,7 +73,8 @@ function SettingsLeftPane( settingsViewModel: SettingsViewModel, ) { return ( -
+
+

{coreViewModel.translations.homePage.settingsButton}

{SettingsPaneButton( settingsViewModel, SettingsModalPages.Appearance, diff --git a/src/View/Modals/storageModal.tsx b/src/View/Modals/storageModal.tsx index e96ab873..1b2f5b47 100644 --- a/src/View/Modals/storageModal.tsx +++ b/src/View/Modals/storageModal.tsx @@ -72,6 +72,7 @@ export function StorageModal(
{SplitModal( + coreViewModel, new React.State(DirectoryItemList(storageViewModel)), detailView, true, diff --git a/src/View/translations.ts b/src/View/translations.ts index 9331c9b4..f9f65599 100644 --- a/src/View/translations.ts +++ b/src/View/translations.ts @@ -24,6 +24,8 @@ const englishTranslations = { waitingLabel: "Waiting...", restoreConnection: "Restore connection", + + noPageSelected: "No page selected", }, regional: { @@ -328,6 +330,8 @@ export const allTranslations: { waitingLabel: "Warten...", restoreConnection: "Verbindung wiederherstellen", + + noPageSelected: "Keine Seite ausgewählt", }, regional: { @@ -597,6 +601,8 @@ export const allTranslations: { waitingLabel: "Esperando...", restoreConnection: "Conectar de nuevo", + + noPageSelected: "No página seleccionada", }, regional: { diff --git a/src/ViewModel/Global/settingsViewModel.ts b/src/ViewModel/Global/settingsViewModel.ts index 488a684f..183c0292 100644 --- a/src/ViewModel/Global/settingsViewModel.ts +++ b/src/ViewModel/Global/settingsViewModel.ts @@ -8,9 +8,8 @@ export default class SettingsViewModel { username: React.State = new React.State(""); usernameInput: React.State = new React.State(""); isShowingSettingsModal: React.State = new React.State(false); - selectedModalPage: React.State = new React.State( - SettingsModalPages.Appearance, - ); + selectedModalPage: React.State = + new React.State(undefined); requiresReload = new React.State(false); firstDayOfWeek: React.State = new React.State("0");