chore(react/type_widget): bring back full-height

This commit is contained in:
Elian Doran
2025-09-19 21:40:35 +03:00
parent 071fcb85c9
commit d83ff641d7
6 changed files with 40 additions and 112 deletions

View File

@@ -0,0 +1,9 @@
.note-detail {
font-family: var(--detail-font-family);
font-size: var(--detail-font-size);
}
.note-detail.full-height {
contain: none;
height: 100%;
}

View File

@@ -12,6 +12,7 @@ import ProtectedSession from "./type_widgets/ProtectedSession";
import Book from "./type_widgets/Book";
import ContentWidget from "./type_widgets/ContentWidget";
import WebView from "./type_widgets/WebView";
import "./NoteDetail.css";
/**
* A `NoteType` altered by the note detail widget, taking into consideration whether the note is editable or not and adding special note types such as an empty one,
@@ -23,9 +24,10 @@ type ExtendedNoteType = Exclude<NoteType, "launcher" | "text" | "code"> | "empty
* The note detail is in charge of rendering the content of a note, by determining its type (e.g. text, code) and using the appropriate view widget.
*/
export default function NoteDetail() {
const { note, type } = useNoteInfo();
const { viewScope, ntxId } = useNoteContext();
const { note, type, noteContext } = useNoteInfo();
const { ntxId, viewScope } = noteContext ?? {};
const [ correspondingWidget, setCorrespondingWidget ] = useState<VNode>();
const isFullHeight = checkFullHeight(noteContext, type);
const props: TypeWidgetProps = {
note: note!,
@@ -35,7 +37,7 @@ export default function NoteDetail() {
useEffect(() => setCorrespondingWidget(getCorrespondingWidget(type, props)), [ note, viewScope, type ]);
return (
<div>
<div class={`note-detail ${isFullHeight ? "full-height" : ""}`}>
{correspondingWidget || <p>Note detail goes here! {note?.title} of {type}</p>}
</div>
);
@@ -54,7 +56,7 @@ function useNoteInfo() {
});
}, [ actualNote, noteContext ]);
return { note, type };
return { note, type, noteContext };
}
function getCorrespondingWidget(noteType: ExtendedNoteType | undefined, props: TypeWidgetProps) {
@@ -102,3 +104,15 @@ async function getWidgetType(note: FNote | null | undefined, noteContext: NoteCo
return resultingType;
}
function checkFullHeight(noteContext: NoteContext | undefined, type: ExtendedNoteType | undefined) {
if (!noteContext) return false;
// https://github.com/zadam/trilium/issues/2522
const isBackendNote = noteContext?.noteId === "_backendLog";
const isSqlNote = noteContext.note?.mime === "text/x-sqlite;schema=trilium";
const isFullHeightNoteType = ["canvas", "webView", "noteMap", "mindMap", "mermaid", "file"].includes(type ?? "");
return (!noteContext?.hasNoteList() && isFullHeightNoteType && !isSqlNote)
|| noteContext?.viewScope?.viewMode === "attachments"
|| isBackendNote;
}

View File

@@ -34,21 +34,6 @@ import type TypeWidget from "./type_widgets/type_widget.js";
import { MermaidTypeWidget } from "./type_widgets/mermaid.js";
import AiChatTypeWidget from "./type_widgets/ai_chat.js";
const TPL = /*html*/`
<div class="note-detail">
<style>
.note-detail {
font-family: var(--detail-font-family);
font-size: var(--detail-font-size);
}
.note-detail.full-height {
height: 100%;
}
</style>
</div>
`;
const typeWidgetClasses = {
empty: EmptyTypeWidget,
editableText: EditableTextTypeWidget,
@@ -176,18 +161,6 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
/**
* sets full height of container that contains note content for a subset of note-types
*/
checkFullHeight() {
// https://github.com/zadam/trilium/issues/2522
const isBackendNote = this.noteContext?.noteId === "_backendLog";
const isSqlNote = this.mime === "text/x-sqlite;schema=trilium";
const isFullHeightNoteType = ["canvas", "webView", "noteMap", "mindMap", "mermaid", "file"].includes(this.type ?? "");
const isFullHeight = (!this.noteContext?.hasNoteList() && isFullHeightNoteType && !isSqlNote)
|| this.noteContext?.viewScope?.viewMode === "attachments"
|| isBackendNote;
this.$widget.toggleClass("full-height", isFullHeight);
}
getTypeWidget() {
if (!this.type || !this.typeWidgets[this.type]) {
throw new Error(t(`note_detail.could_not_find_typewidget`, { type: this.type }));
@@ -196,8 +169,6 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
return this.typeWidgets[this.type];
}
async focusOnDetailEvent({ ntxId }: EventData<"focusOnDetail">) {
if (this.noteContext?.ntxId !== ntxId) {
return;

View File

@@ -0,0 +1,11 @@
.note-detail-web-view {
height: 100%;
position: relative;
}
.note-detail-web-view > * {
position: absolute;
top: 0;
width: 100%;
height: 100%;
}

View File

@@ -3,6 +3,7 @@ import utils from "../../services/utils";
import Alert from "../react/Alert";
import { useNoteLabel } from "../react/hooks";
import { TypeWidgetProps } from "./type_widget";
import "./WebView.css";
const isElectron = utils.isElectron();
@@ -10,7 +11,7 @@ export default function WebView({ note }: TypeWidgetProps) {
const [ webViewSrc ] = useNoteLabel(note, "webViewSrc");
return (
<div className="note-detail-web-view note-detail-printable" style={{ height: "100%" }}>
<div className="note-detail-web-view note-detail-printable">
{webViewSrc
? <WebViewContent src={webViewSrc} />
: <WebViewHelp />}

View File

@@ -1,78 +0,0 @@
import { t } from "../../services/i18n.js";
import TypeWidget from "./type_widget.js";
import attributeService from "../../services/attributes.js";
import type FNote from "../../entities/fnote.js";
import type { EventData } from "../../components/app_context.js";
import utils from "../../services/utils.js";
const TPL = /*html*/`
${buildElement()}
</div>`;
function buildElement() {
if (!utils.isElectron()) {
} else {
return ``;
}
}
export default class WebViewTypeWidget extends TypeWidget {
private $noteDetailWebViewHelp!: JQuery<HTMLElement>;
private $noteDetailWebViewContent!: JQuery<HTMLElement>;
static getType() {
return "webView";
}
doRender() {
this.$widget = $(TPL);
this.$noteDetailWebViewHelp = this.$widget.find(".note-detail-web-view-help");
this.$noteDetailWebViewContent = this.$widget.find(".note-detail-web-view-content");
window.addEventListener("resize", () => this.setDimensions(), false);
super.doRender();
}
async doRefresh(note: FNote) {
this.$widget.show();
this.$noteDetailWebViewHelp.hide();
this.$noteDetailWebViewContent.hide();
if (!this.note) {
return;
}
const webViewSrc = this.note.getLabelValue("webViewSrc");
if (webViewSrc) {
this.$noteDetailWebViewContent.show().attr("src", webViewSrc);
} else {
this.$noteDetailWebViewContent.hide();
this.$noteDetailWebViewHelp.show();
}
this.setDimensions();
setTimeout(() => this.setDimensions(), 1000);
}
cleanup() {
this.$noteDetailWebViewContent.removeAttr("src");
}
setDimensions() {
const $parent = this.$widget;
this.$noteDetailWebViewContent
.height($parent.height() ?? 0)
.width($parent.width() ?? 0);
}
entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
if (loadResults.getAttributeRows().find((attr) => attr.name === "webViewSrc" && attributeService.isAffecting(attr, this.noteContext?.note))) {
this.refresh();
}
}
}