prepare fileBrowser layout on mobile
This commit is contained in:
Vendored
+21
-4
@@ -499,14 +499,28 @@ body[showing-chat] #chat-page-wrapper {
|
|||||||
scroll-snap-type: x mandatory;
|
scroll-snap-type: x mandatory;
|
||||||
}
|
}
|
||||||
.file-browser > div {
|
.file-browser > div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
flex: 0;
|
flex: 0;
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: var(--content-padding);
|
|
||||||
scroll-snap-align: center;
|
scroll-snap-align: center;
|
||||||
overflow: auto;
|
}
|
||||||
|
.file-browser .scroll-area {
|
||||||
|
flex: 1;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: var(--content-padding);
|
||||||
|
}
|
||||||
|
.file-browser .detail-button-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
padding: var(--content-padding);
|
||||||
|
}
|
||||||
|
.file-browser .detail-button-wrapper button {
|
||||||
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
.file-browser code {
|
.file-browser code {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -518,4 +532,7 @@ body[showing-chat] #chat-page-wrapper {
|
|||||||
min-width: 50%;
|
min-width: 50%;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
.file-browser .detail-button-wrapper {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+27
-2
@@ -379,6 +379,13 @@
|
|||||||
printTree = () => {
|
printTree = () => {
|
||||||
return stringify(this.storageEntryTree);
|
return stringify(this.storageEntryTree);
|
||||||
};
|
};
|
||||||
|
static getFileName = (pathComponents) => {
|
||||||
|
return pathComponents[pathComponents.length - 1] || "\\";
|
||||||
|
};
|
||||||
|
static getFileNameFromString = (pathString) => {
|
||||||
|
const pathComponents = this.stringToPathComponents(pathString);
|
||||||
|
return pathComponents[pathComponents.length - 1] || "\\";
|
||||||
|
};
|
||||||
static pathComponentsToString = (...pathComponents) => {
|
static pathComponentsToString = (...pathComponents) => {
|
||||||
return pathComponents.join(PATH_COMPONENT_SEPARATOR);
|
return pathComponents.join(PATH_COMPONENT_SEPARATOR);
|
||||||
};
|
};
|
||||||
@@ -2081,7 +2088,7 @@
|
|||||||
function DirectoryItemList(storageModel2, pathString, selectedPath) {
|
function DirectoryItemList(storageModel2, pathString, selectedPath) {
|
||||||
const StringToDirectoryItemList = (pathString2) => DirectoryItemList(storageModel2, pathString2, selectedPath);
|
const StringToDirectoryItemList = (pathString2) => DirectoryItemList(storageModel2, pathString2, selectedPath);
|
||||||
const path = StorageModel.stringToPathComponents(pathString);
|
const path = StorageModel.stringToPathComponents(pathString);
|
||||||
const fileName = path[path.length - 1] || "\\";
|
const fileName = StorageModel.getFileName(path);
|
||||||
const items = new ListState();
|
const items = new ListState();
|
||||||
const style = `text-indent: ${path.length * 2}rem`;
|
const style = `text-indent: ${path.length * 2}rem`;
|
||||||
function loadItems() {
|
function loadItems() {
|
||||||
@@ -2128,7 +2135,25 @@
|
|||||||
const content = storageModel2.restore(path);
|
const content = storageModel2.restore(path);
|
||||||
return content || "";
|
return content || "";
|
||||||
});
|
});
|
||||||
return /* @__PURE__ */ createElement("div", { class: "file-browser" }, DirectoryItemList(storageModel2, "\\", selectedPath), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("code", { "subscribe:innerText": fileContent })));
|
const selectedFileName = createProxyState(
|
||||||
|
[selectedPath],
|
||||||
|
() => StorageModel.getFileNameFromString(selectedPath.value) ?? PATH_COMPONENT_SEPARATOR
|
||||||
|
);
|
||||||
|
const view = /* @__PURE__ */ createElement("div", { class: "file-browser" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("div", { class: "scroll-area" }, DirectoryItemList(
|
||||||
|
storageModel2,
|
||||||
|
PATH_COMPONENT_SEPARATOR,
|
||||||
|
selectedPath
|
||||||
|
)), /* @__PURE__ */ createElement("div", { class: "detail-button-wrapper" }, /* @__PURE__ */ createElement("button", { class: "ghost", "on:click": scrollToDetails }, /* @__PURE__ */ createElement(
|
||||||
|
"span",
|
||||||
|
{
|
||||||
|
class: "ellipsis",
|
||||||
|
"subscribe:innerText": selectedFileName
|
||||||
|
}
|
||||||
|
), /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_forward")))), /* @__PURE__ */ createElement("div", { class: "scroll-area" }, /* @__PURE__ */ createElement("code", { "subscribe:innerText": fileContent })));
|
||||||
|
function scrollToDetails() {
|
||||||
|
view.scrollLeft = view.scrollWidth;
|
||||||
|
}
|
||||||
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/View/Modals/storageModal.tsx
|
// src/View/Modals/storageModal.tsx
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { localeCompare, parse, stringify } from "./Utility/utility";
|
|||||||
|
|
||||||
import { DATA_VERSION } from "./Utility/typeSafety";
|
import { DATA_VERSION } from "./Utility/typeSafety";
|
||||||
|
|
||||||
const PATH_COMPONENT_SEPARATOR = "\\";
|
export const PATH_COMPONENT_SEPARATOR = "\\";
|
||||||
|
|
||||||
export default class StorageModel {
|
export default class StorageModel {
|
||||||
storageEntryTree: StorageEntry = {};
|
storageEntryTree: StorageEntry = {};
|
||||||
@@ -112,6 +112,15 @@ export default class StorageModel {
|
|||||||
return stringify(this.storageEntryTree);
|
return stringify(this.storageEntryTree);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static getFileName = (pathComponents: string[]): string => {
|
||||||
|
return pathComponents[pathComponents.length - 1] || "\\"
|
||||||
|
}
|
||||||
|
|
||||||
|
static getFileNameFromString = (pathString: string): string => {
|
||||||
|
const pathComponents: string[] = this.stringToPathComponents(pathString);
|
||||||
|
return pathComponents[pathComponents.length - 1] || "\\"
|
||||||
|
}
|
||||||
|
|
||||||
static pathComponentsToString = (...pathComponents: string[]): string => {
|
static pathComponentsToString = (...pathComponents: string[]): string => {
|
||||||
return pathComponents.join(PATH_COMPONENT_SEPARATOR);
|
return pathComponents.join(PATH_COMPONENT_SEPARATOR);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export function DirectoryItemList(
|
|||||||
|
|
||||||
// data
|
// data
|
||||||
const path = StorageModel.stringToPathComponents(pathString);
|
const path = StorageModel.stringToPathComponents(pathString);
|
||||||
const fileName = path[path.length - 1] || "\\";
|
const fileName = StorageModel.getFileName(path);
|
||||||
const items = new React.ListState<string>();
|
const items = new React.ListState<string>();
|
||||||
|
|
||||||
const style = `text-indent: ${path.length * 2}rem`;
|
const style = `text-indent: ${path.length * 2}rem`;
|
||||||
|
|||||||
@@ -11,17 +11,35 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.file-browser > div {
|
.file-browser > div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
flex: 0;
|
flex: 0;
|
||||||
|
|
||||||
display: flex;
|
scroll-snap-align: center;
|
||||||
flex-direction: column;
|
}
|
||||||
|
|
||||||
|
.file-browser .scroll-area {
|
||||||
|
flex: 1;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
padding: var(--content-padding);
|
padding: var(--content-padding);
|
||||||
|
}
|
||||||
|
|
||||||
scroll-snap-align: center;
|
.file-browser .detail-button-wrapper {
|
||||||
overflow: auto;
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
padding: var(--content-padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-browser .detail-button-wrapper button {
|
||||||
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-browser code {
|
.file-browser code {
|
||||||
@@ -36,4 +54,8 @@
|
|||||||
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.file-browser .detail-button-wrapper {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,25 +2,60 @@ import "./fileBrowser.css";
|
|||||||
|
|
||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
|
import StorageModel, {
|
||||||
|
PATH_COMPONENT_SEPARATOR,
|
||||||
|
} from "../../Model/storageModel";
|
||||||
|
|
||||||
import { DirectoryItemList } from "./directoryItemList";
|
import { DirectoryItemList } from "./directoryItemList";
|
||||||
import StorageModel from "../../Model/storageModel";
|
|
||||||
|
|
||||||
export function FileBrowser(
|
export function FileBrowser(
|
||||||
storageModel: StorageModel,
|
storageModel: StorageModel,
|
||||||
selectedPath: React.State<string>
|
selectedPath: React.State<string>
|
||||||
) {
|
) {
|
||||||
|
// state
|
||||||
const fileContent = React.createProxyState([selectedPath], () => {
|
const fileContent = React.createProxyState([selectedPath], () => {
|
||||||
const path = StorageModel.stringToPathComponents(selectedPath.value);
|
const path = StorageModel.stringToPathComponents(selectedPath.value);
|
||||||
const content = storageModel.restore(path);
|
const content = storageModel.restore(path);
|
||||||
return content || "";
|
return content || "";
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
const selectedFileName = React.createProxyState(
|
||||||
|
[selectedPath],
|
||||||
|
() =>
|
||||||
|
StorageModel.getFileNameFromString(selectedPath.value) ??
|
||||||
|
PATH_COMPONENT_SEPARATOR
|
||||||
|
);
|
||||||
|
|
||||||
|
// view
|
||||||
|
const view = (
|
||||||
<div class="file-browser">
|
<div class="file-browser">
|
||||||
{DirectoryItemList(storageModel, "\\", selectedPath)}
|
|
||||||
<div>
|
<div>
|
||||||
|
<div class="scroll-area">
|
||||||
|
{DirectoryItemList(
|
||||||
|
storageModel,
|
||||||
|
PATH_COMPONENT_SEPARATOR,
|
||||||
|
selectedPath
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div class="detail-button-wrapper">
|
||||||
|
<button class="ghost" on:click={scrollToDetails}>
|
||||||
|
<span
|
||||||
|
class="ellipsis"
|
||||||
|
subscribe:innerText={selectedFileName}
|
||||||
|
></span>
|
||||||
|
<span class="icon">arrow_forward</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="scroll-area">
|
||||||
<code subscribe:innerText={fileContent}></code>
|
<code subscribe:innerText={fileContent}></code>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function scrollToDetails() {
|
||||||
|
view.scrollLeft = view.scrollWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user