mirror of
https://github.com/zadam/trilium.git
synced 2025-12-04 14:34:24 +01:00
chore(react/launch_bar): port open_note_button_widget
This commit is contained in:
parent
1af6200655
commit
48cbb80e79
@ -150,7 +150,7 @@ export function isMac() {
|
||||
|
||||
export const hasTouchBar = (isMac() && isElectron());
|
||||
|
||||
function isCtrlKey(evt: KeyboardEvent | MouseEvent | JQuery.ClickEvent | JQuery.ContextMenuEvent | JQuery.TriggeredEvent | React.PointerEvent<HTMLCanvasElement> | JQueryEventObject) {
|
||||
export function isCtrlKey(evt: KeyboardEvent | MouseEvent | JQuery.ClickEvent | JQuery.ContextMenuEvent | JQuery.TriggeredEvent | React.PointerEvent<HTMLCanvasElement> | JQueryEventObject) {
|
||||
return (!isMac() && evt.ctrlKey) || (isMac() && evt.metaKey);
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import FlexContainer from "./containers/flex_container.js";
|
||||
import OpenNoteButtonWidget from "./buttons/open_note_button_widget.js";
|
||||
import BookmarkFolderWidget from "./buttons/bookmark_folder.js";
|
||||
import froca from "../services/froca.js";
|
||||
import utils from "../services/utils.js";
|
||||
@ -23,10 +22,6 @@ export default class BookmarkButtons extends FlexContainer<Component> {
|
||||
}
|
||||
|
||||
async refresh(): Promise<void> {
|
||||
this.$widget.empty();
|
||||
this.children = [];
|
||||
this.noteIds = [];
|
||||
|
||||
const bookmarkParentNote = await froca.getNote("_lbBookmarks");
|
||||
|
||||
if (!bookmarkParentNote) {
|
||||
@ -37,8 +32,7 @@ export default class BookmarkButtons extends FlexContainer<Component> {
|
||||
this.noteIds.push(note.noteId);
|
||||
|
||||
let buttonWidget: OpenNoteButtonWidget | BookmarkFolderWidget = note.isLabelTruthy("bookmarkFolder")
|
||||
? new BookmarkFolderWidget(note)
|
||||
: new OpenNoteButtonWidget(note).class("launcher-button");
|
||||
? new BookmarkFolderWidget(note);
|
||||
|
||||
if (this.settings.titlePlacement) {
|
||||
if (!("settings" in buttonWidget)) {
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
import OnClickButtonWidget from "./onclick_button.js";
|
||||
import linkContextMenuService from "../../menus/link_context_menu.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
|
||||
export default class OpenNoteButtonWidget extends OnClickButtonWidget {
|
||||
|
||||
private noteToOpen: FNote;
|
||||
|
||||
constructor(noteToOpen: FNote) {
|
||||
super();
|
||||
|
||||
this.noteToOpen = noteToOpen;
|
||||
|
||||
this.title(() => utils.escapeHtml(this.noteToOpen.title))
|
||||
.icon(() => this.noteToOpen.getIcon())
|
||||
.onClick((widget, evt) => this.launch(evt))
|
||||
.onAuxClick((widget, evt) => this.launch(evt))
|
||||
.onContextMenu((evt) => {
|
||||
if (evt) {
|
||||
linkContextMenuService.openContextMenu(this.noteToOpen.noteId, evt);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async launch(evt: JQuery.ClickEvent | JQuery.TriggeredEvent | JQuery.ContextMenuEvent) {
|
||||
if (evt.which === 3) {
|
||||
return;
|
||||
}
|
||||
const hoistedNoteId = this.getHoistedNoteId();
|
||||
const ctrlKey = utils.isCtrlKey(evt);
|
||||
|
||||
if ((evt.which === 1 && ctrlKey) || evt.which === 2) {
|
||||
const activate = evt.shiftKey ? true : false;
|
||||
await appContext.tabManager.openInNewTab(this.noteToOpen.noteId, hoistedNoteId, activate);
|
||||
} else {
|
||||
await appContext.tabManager.openInSameTab(this.noteToOpen.noteId);
|
||||
}
|
||||
}
|
||||
|
||||
getHoistedNoteId() {
|
||||
return this.noteToOpen.getRelationValue("hoistedNote") || appContext.tabManager.getActiveContext()?.hoistedNoteId;
|
||||
}
|
||||
|
||||
initialRenderCompleteEvent() {
|
||||
// we trigger refresh above
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,71 @@
|
||||
import { useMemo } from "preact/hooks";
|
||||
import type { LaunchBarWidgetProps } from "./launch_bar_widget";
|
||||
import { CSSProperties } from "preact";
|
||||
import type FNote from "../../entities/fnote";
|
||||
import { useChildNotes, useNoteLabel, useNoteProperty } from "../react/hooks";
|
||||
import Dropdown from "../react/Dropdown";
|
||||
import ActionButton from "../react/ActionButton";
|
||||
import appContext from "../../components/app_context";
|
||||
import { escapeHtml, isCtrlKey } from "../../services/utils";
|
||||
import link_context_menu from "../../menus/link_context_menu";
|
||||
|
||||
export default function BookmarkButtons({ }: LaunchBarWidgetProps) {
|
||||
return <p>Bookmarks goes here.</p>;
|
||||
const PARENT_NOTE_ID = "_lbBookmarks";
|
||||
|
||||
export default function BookmarkButtons({ isHorizontalLayout }: LaunchBarWidgetProps) {
|
||||
const style = useMemo<CSSProperties>(() => ({
|
||||
display: "flex",
|
||||
flexDirection: isHorizontalLayout ? "row" : "column",
|
||||
contain: "none"
|
||||
}), [ isHorizontalLayout ]);
|
||||
const childNotes = useChildNotes(PARENT_NOTE_ID);
|
||||
|
||||
return (
|
||||
<div style={style}>
|
||||
{childNotes?.map(childNote => <SingleBookmark note={childNote} />)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function SingleBookmark({ note }: { note: FNote }) {
|
||||
return <OpenNoteButtonWidget note={note} />
|
||||
}
|
||||
|
||||
function OpenNoteButtonWidget({ note }: { note: FNote }) {
|
||||
const [ iconClass ] = useNoteLabel(note, "iconClass");
|
||||
const title = useNoteProperty(note, "title");
|
||||
|
||||
async function launch(evt: MouseEvent) {
|
||||
if (evt.which === 3) {
|
||||
return;
|
||||
}
|
||||
const hoistedNoteId = getHoistedNoteId(note);
|
||||
const ctrlKey = isCtrlKey(evt);
|
||||
|
||||
if ((evt.which === 1 && ctrlKey) || evt.which === 2) {
|
||||
const activate = evt.shiftKey ? true : false;
|
||||
await appContext.tabManager.openInNewTab(note.noteId, hoistedNoteId, activate);
|
||||
} else {
|
||||
await appContext.tabManager.openInSameTab(note.noteId);
|
||||
}
|
||||
}
|
||||
|
||||
return title && iconClass && (
|
||||
<ActionButton
|
||||
icon={iconClass}
|
||||
text={escapeHtml(title)}
|
||||
className="button-widget launcher-button"
|
||||
noIconActionClass
|
||||
titlePosition="right"
|
||||
onClick={launch}
|
||||
onAuxClick={launch}
|
||||
onContextMenu={evt => {
|
||||
evt.preventDefault();
|
||||
link_context_menu.openContextMenu(note.noteId, evt);
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function getHoistedNoteId(noteToOpen: FNote) {
|
||||
return noteToOpen.getRelationValue("hoistedNote") || appContext.tabManager.getActiveContext()?.hoistedNoteId;
|
||||
}
|
||||
|
||||
@ -2,13 +2,13 @@ import { useEffect, useRef, useState } from "preact/hooks";
|
||||
import { CommandNames } from "../../components/app_context";
|
||||
import { useStaticTooltip } from "./hooks";
|
||||
import keyboard_actions from "../../services/keyboard_actions";
|
||||
import { HTMLAttributes } from "preact";
|
||||
|
||||
export interface ActionButtonProps {
|
||||
export interface ActionButtonProps extends Pick<HTMLAttributes<HTMLButtonElement>, "onClick" | "onAuxClick" | "onContextMenu"> {
|
||||
text: string;
|
||||
titlePosition?: "top" | "right" | "bottom" | "left";
|
||||
icon: string;
|
||||
className?: string;
|
||||
onClick?: (e: MouseEvent) => void;
|
||||
triggerCommand?: CommandNames;
|
||||
noIconActionClass?: boolean;
|
||||
frame?: boolean;
|
||||
@ -16,7 +16,7 @@ export interface ActionButtonProps {
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export default function ActionButton({ text, icon, className, onClick, triggerCommand, titlePosition, noIconActionClass, frame, active, disabled }: ActionButtonProps) {
|
||||
export default function ActionButton({ text, icon, className, triggerCommand, titlePosition, noIconActionClass, frame, active, disabled, ...restProps }: ActionButtonProps) {
|
||||
const buttonRef = useRef<HTMLButtonElement>(null);
|
||||
const [ keyboardShortcut, setKeyboardShortcut ] = useState<string[]>();
|
||||
|
||||
@ -35,8 +35,8 @@ export default function ActionButton({ text, icon, className, onClick, triggerCo
|
||||
return <button
|
||||
ref={buttonRef}
|
||||
class={`${className ?? ""} ${!noIconActionClass ? "icon-action" : "btn"} ${icon} ${frame ? "btn btn-primary" : ""} ${disabled ? "disabled" : ""} ${active ? "active" : ""}`}
|
||||
onClick={onClick}
|
||||
data-trigger-command={triggerCommand}
|
||||
disabled={disabled}
|
||||
{...restProps}
|
||||
/>;
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import toast, { ToastOptions } from "../../services/toast";
|
||||
import utils, { escapeRegExp, reloadFrontendApp } from "../../services/utils";
|
||||
import server from "../../services/server";
|
||||
import { removeIndividualBinding } from "../../services/shortcuts";
|
||||
import froca from "../../services/froca";
|
||||
|
||||
export function useTriliumEvent<T extends EventNames>(eventName: T, handler: (data: EventData<T>) => void) {
|
||||
const parentComponent = useContext(ParentComponent);
|
||||
@ -836,3 +837,15 @@ async function isNoteReadOnly(note: FNote, noteContext: NoteContext) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function useChildNotes(parentNoteId: string) {
|
||||
const [ childNotes, setChildNotes ] = useState<FNote[]>([]);
|
||||
async function refreshChildNotes() {
|
||||
const parentNote = await froca.getNote(parentNoteId);
|
||||
const childNotes = await parentNote?.getChildNotes();
|
||||
setChildNotes(childNotes ?? []);
|
||||
}
|
||||
useEffect(() => { refreshChildNotes() }, [ parentNoteId ]);
|
||||
|
||||
return childNotes;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user