mirror of
https://github.com/zadam/trilium.git
synced 2025-11-01 02:45:54 +01:00
feat(react): port about dialog
This commit is contained in:
@@ -2005,5 +2005,8 @@
|
|||||||
},
|
},
|
||||||
"content_renderer": {
|
"content_renderer": {
|
||||||
"open_externally": "Open externally"
|
"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 (
|
return (
|
||||||
<div className="modal fade mx-auto" tabIndex={-1} role="dialog">
|
<div className={`modal fade mx-auto ${className}`} tabIndex={-1} role="dialog" ref={modalRef}>
|
||||||
<div className="modal-dialog" role="document">
|
<div className={`modal-dialog modal-${size}`} role="document">
|
||||||
<div className="modal-content">
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user