mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-29 19:12:27 +08:00
chore(client/ts): port sidebar_container
This commit is contained in:
parent
999977e32f
commit
ce56842353
@ -173,6 +173,7 @@ export type CommandMappings = {
|
|||||||
moveBranchIdsTo: CommandData & {
|
moveBranchIdsTo: CommandData & {
|
||||||
branchIds: string[];
|
branchIds: string[];
|
||||||
};
|
};
|
||||||
|
/** Sets the active {@link Screen} (e.g. to toggle the tree sidebar). It triggers the {@link EventMappings.activeScreenChanged} event, but only if the provided <em>screen</em> is different than the current one. */
|
||||||
setActiveScreen: CommandData & {
|
setActiveScreen: CommandData & {
|
||||||
screen: Screen;
|
screen: Screen;
|
||||||
}
|
}
|
||||||
@ -202,6 +203,10 @@ type EventMappings = {
|
|||||||
},
|
},
|
||||||
readOnlyTemporarilyDisabled: {
|
readOnlyTemporarilyDisabled: {
|
||||||
noteContext: NoteContext
|
noteContext: NoteContext
|
||||||
|
},
|
||||||
|
/** Triggered when the {@link CommandMappings.setActiveScreen} command is invoked. */
|
||||||
|
activeScreenChanged: {
|
||||||
|
activeScreen: Screen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Component from "./component.js";
|
import Component from "./component.js";
|
||||||
import appContext, { CommandListener, CommandListenerData } from "./app_context.js";
|
import type { CommandListener, CommandListenerData } from "./app_context.js";
|
||||||
|
|
||||||
export type Screen = "detail" | "tree";
|
export type Screen = "detail" | "tree";
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import toastService from "../services/toast.js";
|
|||||||
* For information on using widgets, see the tutorial {@tutorial widget_basics}.
|
* For information on using widgets, see the tutorial {@tutorial widget_basics}.
|
||||||
*/
|
*/
|
||||||
class BasicWidget extends Component {
|
class BasicWidget extends Component {
|
||||||
private attrs: Record<string, string>;
|
protected attrs: Record<string, string>;
|
||||||
private classes: string[];
|
private classes: string[];
|
||||||
private childPositionCounter: number;
|
private childPositionCounter: number;
|
||||||
private cssEl?: string;
|
private cssEl?: string;
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import Container from "./container.js";
|
import Container from "./container.js";
|
||||||
|
|
||||||
|
export type FlexDirection = "row" | "column";
|
||||||
|
|
||||||
export default class FlexContainer extends Container {
|
export default class FlexContainer extends Container {
|
||||||
constructor(direction) {
|
|
||||||
|
constructor(direction: FlexDirection) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
if (!direction || !['row', 'column'].includes(direction)) {
|
if (!direction || !['row', 'column'].includes(direction)) {
|
@ -1,4 +1,6 @@
|
|||||||
import FlexContainer from "../containers/flex_container.js";
|
import { EventData } from "../../components/app_context.js";
|
||||||
|
import { Screen } from "../../components/mobile_screen_switcher.js";
|
||||||
|
import FlexContainer, { FlexDirection } from "../containers/flex_container.js";
|
||||||
|
|
||||||
const DRAG_STATE_NONE = 0;
|
const DRAG_STATE_NONE = 0;
|
||||||
const DRAG_STATE_INITIAL_DRAG = 1;
|
const DRAG_STATE_INITIAL_DRAG = 1;
|
||||||
@ -9,12 +11,25 @@ const DRAG_THRESHOLD = 10;
|
|||||||
|
|
||||||
export default class SidebarContainer extends FlexContainer {
|
export default class SidebarContainer extends FlexContainer {
|
||||||
|
|
||||||
constructor(screenName, direction) {
|
private screenName: Screen;
|
||||||
|
private currentTranslate: number;
|
||||||
|
private dragState: number;
|
||||||
|
private startX?: number;
|
||||||
|
private translatePercentage: number;
|
||||||
|
private sidebarEl!: HTMLElement;
|
||||||
|
private backdropEl!: HTMLElement;
|
||||||
|
private originalSidebarTransition: string;
|
||||||
|
private originalBackdropTransition: string;
|
||||||
|
|
||||||
|
constructor(screenName: Screen, direction: FlexDirection) {
|
||||||
super(direction);
|
super(direction);
|
||||||
|
|
||||||
this.screenName = screenName;
|
this.screenName = screenName;
|
||||||
this.currentTranslate = -100;
|
this.currentTranslate = -100;
|
||||||
|
this.translatePercentage = 0;
|
||||||
this.dragState = DRAG_STATE_NONE;
|
this.dragState = DRAG_STATE_NONE;
|
||||||
|
this.originalSidebarTransition = "";
|
||||||
|
this.originalBackdropTransition = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
doRender() {
|
doRender() {
|
||||||
@ -31,8 +46,8 @@ export default class SidebarContainer extends FlexContainer {
|
|||||||
document.addEventListener("touchend", (e) => this.#onDragEnd(e));
|
document.addEventListener("touchend", (e) => this.#onDragEnd(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
#onDragStart(e) {
|
#onDragStart(e: TouchEvent | MouseEvent) {
|
||||||
const x = e.touches ? e.touches[0].clientX : e.clientX;
|
const x = "touches" in e ? e.touches[0].clientX : e.clientX;
|
||||||
this.startX = x;
|
this.startX = x;
|
||||||
|
|
||||||
if (x > 30 && this.currentTranslate === -100) {
|
if (x > 30 && this.currentTranslate === -100) {
|
||||||
@ -44,12 +59,12 @@ export default class SidebarContainer extends FlexContainer {
|
|||||||
this.translatePercentage = 0;
|
this.translatePercentage = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#onDragMove(e) {
|
#onDragMove(e: TouchEvent | MouseEvent) {
|
||||||
if (this.dragState === DRAG_STATE_NONE) {
|
if (this.dragState === DRAG_STATE_NONE || !this.startX) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const x = e.touches ? e.touches[0].clientX : e.clientX;
|
const x = "touches" in e ? e.touches[0].clientX : e.clientX;
|
||||||
const deltaX = x - this.startX;
|
const deltaX = x - this.startX;
|
||||||
if (this.dragState === DRAG_STATE_INITIAL_DRAG) {
|
if (this.dragState === DRAG_STATE_INITIAL_DRAG) {
|
||||||
if (Math.abs(deltaX) > 10) {
|
if (Math.abs(deltaX) > 10) {
|
||||||
@ -57,7 +72,7 @@ export default class SidebarContainer extends FlexContainer {
|
|||||||
this.sidebarEl.style.transition = "none";
|
this.sidebarEl.style.transition = "none";
|
||||||
this.backdropEl.style.transition = "none";
|
this.backdropEl.style.transition = "none";
|
||||||
|
|
||||||
this.backdropEl.style.opacity = (this.currentTranslate === -100 ? 0 : 1);
|
this.backdropEl.style.opacity = String(this.currentTranslate === -100 ? 0 : 1);
|
||||||
this.backdropEl.classList.add("show");
|
this.backdropEl.classList.add("show");
|
||||||
|
|
||||||
this.dragState = DRAG_STATE_DRAGGING;
|
this.dragState = DRAG_STATE_DRAGGING;
|
||||||
@ -67,13 +82,13 @@ export default class SidebarContainer extends FlexContainer {
|
|||||||
const translatePercentage = Math.min(0, Math.max(this.currentTranslate + (deltaX / width) * 100, -100));
|
const translatePercentage = Math.min(0, Math.max(this.currentTranslate + (deltaX / width) * 100, -100));
|
||||||
this.translatePercentage = translatePercentage;
|
this.translatePercentage = translatePercentage;
|
||||||
this.sidebarEl.style.transform = `translateX(${translatePercentage}%)`;
|
this.sidebarEl.style.transform = `translateX(${translatePercentage}%)`;
|
||||||
this.backdropEl.style.opacity = Math.max(0, 1 + (translatePercentage / 100));
|
this.backdropEl.style.opacity = String(Math.max(0, 1 + (translatePercentage / 100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
#onDragEnd(e) {
|
#onDragEnd(e: TouchEvent | MouseEvent) {
|
||||||
if (this.dragState === DRAG_STATE_NONE) {
|
if (this.dragState === DRAG_STATE_NONE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -96,13 +111,20 @@ export default class SidebarContainer extends FlexContainer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sidebarEl = document.getElementById("mobile-sidebar-wrapper");
|
const sidebarEl = document.getElementById("mobile-sidebar-wrapper");
|
||||||
this.backdropEl = document.getElementById("mobile-sidebar-container");
|
const backdropEl = document.getElementById("mobile-sidebar-container");
|
||||||
|
|
||||||
|
if (!sidebarEl || !backdropEl) {
|
||||||
|
throw new Error("Unable to find the sidebar or backdrop.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sidebarEl = sidebarEl;
|
||||||
|
this.backdropEl = backdropEl;
|
||||||
this.originalSidebarTransition = this.sidebarEl.style.transition;
|
this.originalSidebarTransition = this.sidebarEl.style.transition;
|
||||||
this.originalBackdropTransition = this.backdropEl.style.transition;
|
this.originalBackdropTransition = this.backdropEl.style.transition;
|
||||||
}
|
}
|
||||||
|
|
||||||
#setSidebarOpen(isOpen) {
|
#setSidebarOpen(isOpen: boolean) {
|
||||||
if (!this.sidebarEl) {
|
if (!this.sidebarEl) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -113,13 +135,13 @@ export default class SidebarContainer extends FlexContainer {
|
|||||||
|
|
||||||
this.backdropEl.classList.toggle("show", isOpen);
|
this.backdropEl.classList.toggle("show", isOpen);
|
||||||
this.backdropEl.style.transition = this.originalBackdropTransition;
|
this.backdropEl.style.transition = this.originalBackdropTransition;
|
||||||
this.backdropEl.style.opacity = isOpen ? 1 : 0;
|
this.backdropEl.style.opacity = String(isOpen ? 1 : 0);
|
||||||
|
|
||||||
this.currentTranslate = isOpen ? 0 : -100;
|
this.currentTranslate = isOpen ? 0 : -100;
|
||||||
this.dragState = DRAG_STATE_NONE;
|
this.dragState = DRAG_STATE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
activeScreenChangedEvent({activeScreen}) {
|
activeScreenChangedEvent({activeScreen}: EventData<"activeScreenChanged">) {
|
||||||
this.#setInitialState();
|
this.#setInitialState();
|
||||||
this.#setSidebarOpen(activeScreen === this.screenName);
|
this.#setSidebarOpen(activeScreen === this.screenName);
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user