mirror of
https://github.com/zadam/trilium.git
synced 2025-10-26 07:46:30 +01:00
feat(react): port about dialog
This commit is contained in:
@@ -2005,5 +2005,8 @@
|
||||
},
|
||||
"content_renderer": {
|
||||
"open_externally": "Open externally"
|
||||
},
|
||||
"modal": {
|
||||
"close": "Close"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
import { formatDateTime } from "../../utils/formatters.js";
|
||||
import { t } from "../../services/i18n.js";
|
||||
import BasicWidget from "../basic_widget.js";
|
||||
import openService from "../../services/open.js";
|
||||
import server from "../../services/server.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import { openDialog } from "../../services/dialog.js";
|
||||
|
||||
interface AppInfo {
|
||||
appVersion: string;
|
||||
dbVersion: number;
|
||||
syncVersion: number;
|
||||
buildDate: string;
|
||||
buildRevision: string;
|
||||
dataDirectory: string;
|
||||
}
|
||||
|
||||
const TPL = /*html*/`
|
||||
<div class="about-dialog modal fade mx-auto" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">${t("about.title")}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="${t("about.close")}"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<th>${t("about.homepage")}</th>
|
||||
<td><a class="tn-link" href="https://github.com/TriliumNext/Trilium" class="external">https://github.com/TriliumNext/Trilium</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>${t("about.app_version")}</th>
|
||||
<td class="app-version"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>${t("about.db_version")}</th>
|
||||
<td class="db-version"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>${t("about.sync_version")}</th>
|
||||
<td class="sync-version"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>${t("about.build_date")}</th>
|
||||
<td class="build-date"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>${t("about.build_revision")}</th>
|
||||
<td><a class="tn-link build-revision external" href="" target="_blank"></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>${t("about.data_directory")}</th>
|
||||
<td class="data-directory"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.about-dialog a {
|
||||
word-break: break-all;
|
||||
}
|
||||
</style>
|
||||
`;
|
||||
|
||||
export default class AboutDialog extends BasicWidget {
|
||||
private $appVersion!: JQuery<HTMLElement>;
|
||||
private $dbVersion!: JQuery<HTMLElement>;
|
||||
private $syncVersion!: JQuery<HTMLElement>;
|
||||
private $buildDate!: JQuery<HTMLElement>;
|
||||
private $buildRevision!: JQuery<HTMLElement>;
|
||||
private $dataDirectory!: JQuery<HTMLElement>;
|
||||
|
||||
doRender(): void {
|
||||
this.$widget = $(TPL);
|
||||
this.$appVersion = this.$widget.find(".app-version");
|
||||
this.$dbVersion = this.$widget.find(".db-version");
|
||||
this.$syncVersion = this.$widget.find(".sync-version");
|
||||
this.$buildDate = this.$widget.find(".build-date");
|
||||
this.$buildRevision = this.$widget.find(".build-revision");
|
||||
this.$dataDirectory = this.$widget.find(".data-directory");
|
||||
}
|
||||
|
||||
async refresh() {
|
||||
const appInfo = await server.get<AppInfo>("app-info");
|
||||
|
||||
this.$appVersion.text(appInfo.appVersion);
|
||||
this.$dbVersion.text(appInfo.dbVersion.toString());
|
||||
this.$syncVersion.text(appInfo.syncVersion.toString());
|
||||
this.$buildDate.text(formatDateTime(appInfo.buildDate));
|
||||
this.$buildRevision.text(appInfo.buildRevision);
|
||||
this.$buildRevision.attr("href", `https://github.com/TriliumNext/Trilium/commit/${appInfo.buildRevision}`);
|
||||
if (utils.isElectron()) {
|
||||
this.$dataDirectory.html(
|
||||
$("<a></a>", {
|
||||
href: "#",
|
||||
class: "tn-link",
|
||||
text: appInfo.dataDirectory
|
||||
}).prop("outerHTML")
|
||||
);
|
||||
this.$dataDirectory.find("a").on("click", (event: JQuery.ClickEvent) => {
|
||||
event.preventDefault();
|
||||
openService.openDirectory(appInfo.dataDirectory);
|
||||
});
|
||||
} else {
|
||||
this.$dataDirectory.text(appInfo.dataDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
async openAboutDialogEvent() {
|
||||
await this.refresh();
|
||||
openDialog(this.$widget);
|
||||
}
|
||||
}
|
||||
98
apps/client/src/widgets/dialogs/about.tsx
Normal file
98
apps/client/src/widgets/dialogs/about.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import { openDialog } from "../../services/dialog.js";
|
||||
import ReactBasicWidget from "../react/ReactBasicWidget.js";
|
||||
import Modal from "../react/Modal.js";
|
||||
import { t } from "../../services/i18n.js";
|
||||
import { formatDateTime } from "../../utils/formatters.js";
|
||||
import { useState } from "react";
|
||||
import server from "../../services/server.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import openService from "../../services/open.js";
|
||||
|
||||
interface AppInfo {
|
||||
appVersion: string;
|
||||
dbVersion: number;
|
||||
syncVersion: number;
|
||||
buildDate: string;
|
||||
buildRevision: string;
|
||||
dataDirectory: string;
|
||||
}
|
||||
|
||||
function AboutDialogComponent() {
|
||||
let [appInfo, setAppInfo] = useState<AppInfo | null>(null);
|
||||
|
||||
async function onShown() {
|
||||
const appInfo = await server.get<AppInfo>("app-info");
|
||||
setAppInfo(appInfo);
|
||||
}
|
||||
|
||||
const forceWordBreak = { wordBreak: "break-all" };
|
||||
|
||||
return (
|
||||
<Modal className="about-dialog" size="lg" title={t("about.title")} onShown={onShown}>
|
||||
{(appInfo !== null) ? (
|
||||
<table className="table table-borderless">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>{t("about.homepage")}</th>
|
||||
<td><a className="tn-link external" href="https://github.com/TriliumNext/Trilium" style={forceWordBreak}>https://github.com/TriliumNext/Trilium</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{t("about.app_version")}</th>
|
||||
<td className="app-version">{appInfo.appVersion}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{t("about.db_version")}</th>
|
||||
<td className="db-version">{appInfo.dbVersion}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{t("about.sync_version")}</th>
|
||||
<td className="sync-version">{appInfo.syncVersion}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{t("about.build_date")}</th>
|
||||
<td className="build-date">{formatDateTime(appInfo.buildDate)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{t("about.build_revision")}</th>
|
||||
<td>
|
||||
<a className="tn-link build-revision external" href={`https://github.com/TriliumNext/Trilium/commit/${appInfo.buildRevision}`} target="_blank" style={forceWordBreak}>{appInfo.buildRevision}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{t("about.data_directory")}</th>
|
||||
<td className="data-directory">
|
||||
<DirectoryLink directory={appInfo.dataDirectory} style={forceWordBreak} />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
) : (
|
||||
<div className="loading-spinner"></div>
|
||||
)}
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
function DirectoryLink({ directory, style }: { directory: string, style?: React.CSSProperties }) {
|
||||
if (utils.isElectron()) {
|
||||
const onClick = (e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
openService.openDirectory(directory);
|
||||
};
|
||||
|
||||
return <a className="tn-link" href="#" onClick={onClick} style={style}></a>
|
||||
} else {
|
||||
return <span style={style}>{directory}</span>;
|
||||
}
|
||||
}
|
||||
|
||||
export default class AboutDialog extends ReactBasicWidget {
|
||||
|
||||
get component() {
|
||||
return <AboutDialogComponent />;
|
||||
}
|
||||
|
||||
async openAboutDialogEvent() {
|
||||
openDialog(this.$widget);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,39 @@
|
||||
export default function Modal({ children }) {
|
||||
import { useEffect, useRef } from "preact/hooks";
|
||||
import { t } from "../../services/i18n";
|
||||
import { ComponentChildren } from "preact";
|
||||
|
||||
interface ModalProps {
|
||||
className: string;
|
||||
title: string;
|
||||
size: "lg" | "sm";
|
||||
children: ComponentChildren;
|
||||
onShown?: () => void;
|
||||
}
|
||||
|
||||
export default function Modal({ children, className, size, title, onShown }: ModalProps) {
|
||||
const modalRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
if (onShown) {
|
||||
useEffect(() => {
|
||||
const modalElement = modalRef.current;
|
||||
if (modalElement) {
|
||||
modalElement.addEventListener("shown.bs.modal", onShown);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="modal fade mx-auto" tabIndex={-1} role="dialog">
|
||||
<div className="modal-dialog" role="document">
|
||||
<div className={`modal fade mx-auto ${className}`} tabIndex={-1} role="dialog" ref={modalRef}>
|
||||
<div className={`modal-dialog modal-${size}`} role="document">
|
||||
<div className="modal-content">
|
||||
{children}
|
||||
<div className="modal-header">
|
||||
<h5 className="modal-title">{title}</h5>
|
||||
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label={t("modal.close")}></button>
|
||||
</div>
|
||||
|
||||
<div className="modal-body">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user