mirror of
https://github.com/zadam/trilium.git
synced 2025-10-27 00:06:30 +01:00
feat(website/i18n): get translation to actually render
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { ComponentChildren, HTMLAttributes } from "preact";
|
import { ComponentChildren, HTMLAttributes } from "preact";
|
||||||
import { Link } from "./Button.js";
|
import { Link } from "./Button.js";
|
||||||
import Icon from "./Icon.js";
|
import Icon from "./Icon.js";
|
||||||
import { t } from "../i18n.js";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
|
interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
|
||||||
title: ComponentChildren;
|
title: ComponentChildren;
|
||||||
@@ -13,6 +13,8 @@ interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Card({ title, children, imageUrl, iconSvg, className, moreInfoUrl, ...restProps }: CardProps) {
|
export default function Card({ title, children, imageUrl, iconSvg, className, moreInfoUrl, ...restProps }: CardProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`card ${className}`} {...restProps}>
|
<div className={`card ${className}`} {...restProps}>
|
||||||
{imageUrl && <img class="image" src={imageUrl} loading="lazy" />}
|
{imageUrl && <img class="image" src={imageUrl} loading="lazy" />}
|
||||||
|
|||||||
@@ -4,16 +4,17 @@ import Button from "./Button.js";
|
|||||||
import downloadIcon from "../assets/boxicons/bx-arrow-in-down-square-half.svg?raw";
|
import downloadIcon from "../assets/boxicons/bx-arrow-in-down-square-half.svg?raw";
|
||||||
import packageJson from "../../../../package.json" with { type: "json" };
|
import packageJson from "../../../../package.json" with { type: "json" };
|
||||||
import { useEffect, useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
import { t } from "../i18n.js";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
interface DownloadButtonProps {
|
interface DownloadButtonProps {
|
||||||
big?: boolean;
|
big?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function DownloadButton({ big }: DownloadButtonProps) {
|
export default function DownloadButton({ big }: DownloadButtonProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const [ recommendedDownload, setRecommendedDownload ] = useState<RecommendedDownload | null>();
|
const [ recommendedDownload, setRecommendedDownload ] = useState<RecommendedDownload | null>();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getRecommendedDownload()?.then(setRecommendedDownload);
|
getRecommendedDownload(t)?.then(setRecommendedDownload);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (recommendedDownload &&
|
return (recommendedDownload &&
|
||||||
|
|||||||
@@ -5,9 +5,12 @@ import githubDiscussionsIcon from "../assets/boxicons/bx-discussion.svg?raw";
|
|||||||
import matrixIcon from "../assets/boxicons/bx-message-dots.svg?raw";
|
import matrixIcon from "../assets/boxicons/bx-message-dots.svg?raw";
|
||||||
import redditIcon from "../assets/boxicons/bx-reddit.svg?raw";
|
import redditIcon from "../assets/boxicons/bx-reddit.svg?raw";
|
||||||
import { Link } from "./Button.js";
|
import { Link } from "./Button.js";
|
||||||
import { LOCALES, t } from "../i18n";
|
import { LOCALES } from "../i18n";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<footer>
|
<footer>
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
@@ -33,6 +36,8 @@ export default function Footer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function SocialButtons({ className, withText }: { className?: string, withText?: boolean }) {
|
export function SocialButtons({ className, withText }: { className?: string, withText?: boolean }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`social-buttons ${className}`}>
|
<div className={`social-buttons ${className}`}>
|
||||||
<SocialButton
|
<SocialButton
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
import { TFunction } from 'i18next';
|
||||||
import rootPackageJson from '../../../package.json' with { type: "json" };
|
import rootPackageJson from '../../../package.json' with { type: "json" };
|
||||||
import { t } from './i18n';
|
|
||||||
|
|
||||||
export type App = "desktop" | "server";
|
export type App = "desktop" | "server";
|
||||||
|
|
||||||
@@ -34,151 +34,155 @@ export interface RecommendedDownload {
|
|||||||
type DownloadMatrix = Record<App, { [ P in Platform ]?: DownloadMatrixEntry }>;
|
type DownloadMatrix = Record<App, { [ P in Platform ]?: DownloadMatrixEntry }>;
|
||||||
|
|
||||||
// Keep compatibility info inline with https://github.com/electron/electron/blob/main/README.md#platform-support.
|
// Keep compatibility info inline with https://github.com/electron/electron/blob/main/README.md#platform-support.
|
||||||
export const downloadMatrix: DownloadMatrix = {
|
export function getDownloadMatrix(t: TFunction<"translation", undefined>): DownloadMatrix {
|
||||||
desktop: {
|
return {
|
||||||
windows: {
|
desktop: {
|
||||||
title: {
|
windows: {
|
||||||
x64: t("download_helper_desktop_windows.title_x64"),
|
title: {
|
||||||
arm64: t("download_helper_desktop_windows.title_arm64")
|
x64: t("download_helper_desktop_windows.title_x64"),
|
||||||
},
|
arm64: t("download_helper_desktop_windows.title_arm64")
|
||||||
description: {
|
|
||||||
x64: t("download_helper_desktop_windows.description_x64"),
|
|
||||||
arm64: t("download_helper_desktop_windows.description_arm64"),
|
|
||||||
},
|
|
||||||
quickStartTitle: t("download_helper_desktop_windows.quick_start"),
|
|
||||||
quickStartCode: "winget install TriliumNext.Notes",
|
|
||||||
downloads: {
|
|
||||||
exe: {
|
|
||||||
recommended: true,
|
|
||||||
name: t("download_helper_desktop_windows.download_exe")
|
|
||||||
},
|
},
|
||||||
zip: {
|
description: {
|
||||||
name: t("download_helper_desktop_windows.download_zip")
|
x64: t("download_helper_desktop_windows.description_x64"),
|
||||||
|
arm64: t("download_helper_desktop_windows.description_arm64"),
|
||||||
},
|
},
|
||||||
scoop: {
|
quickStartTitle: t("download_helper_desktop_windows.quick_start"),
|
||||||
name: t("download_helper_desktop_windows.download_scoop"),
|
quickStartCode: "winget install TriliumNext.Notes",
|
||||||
url: "https://scoop.sh/#/apps?q=trilium&id=7c08bc3c105b9ee5c00dd4245efdea0f091b8a5c"
|
downloads: {
|
||||||
|
exe: {
|
||||||
|
recommended: true,
|
||||||
|
name: t("download_helper_desktop_windows.download_exe")
|
||||||
|
},
|
||||||
|
zip: {
|
||||||
|
name: t("download_helper_desktop_windows.download_zip")
|
||||||
|
},
|
||||||
|
scoop: {
|
||||||
|
name: t("download_helper_desktop_windows.download_scoop"),
|
||||||
|
url: "https://scoop.sh/#/apps?q=trilium&id=7c08bc3c105b9ee5c00dd4245efdea0f091b8a5c"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
linux: {
|
||||||
|
title: {
|
||||||
|
x64: t("download_helper_desktop_linux.title_x64"),
|
||||||
|
arm64: t("download_helper_desktop_linux.title_arm64")
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
x64: t("download_helper_desktop_linux.description_x64"),
|
||||||
|
arm64: t("download_helper_desktop_linux.description_arm64"),
|
||||||
|
},
|
||||||
|
quickStartTitle: t("download_helper_desktop_linux.quick_start"),
|
||||||
|
downloads: {
|
||||||
|
deb: {
|
||||||
|
recommended: true,
|
||||||
|
name: t("download_helper_desktop_linux.download_deb")
|
||||||
|
},
|
||||||
|
rpm: {
|
||||||
|
recommended: true,
|
||||||
|
name: t("download_helper_desktop_linux.download_rpm")
|
||||||
|
},
|
||||||
|
flatpak: {
|
||||||
|
name: t("download_helper_desktop_linux.download_flatpak")
|
||||||
|
},
|
||||||
|
zip: {
|
||||||
|
name: t("download_helper_desktop_linux.download_zip")
|
||||||
|
},
|
||||||
|
nixpkgs: {
|
||||||
|
name: t("download_helper_desktop_linux.download_nixpkgs"),
|
||||||
|
url: "https://search.nixos.org/packages?query=trilium-next"
|
||||||
|
},
|
||||||
|
aur: {
|
||||||
|
name: t("download_helper_desktop_linux.download_aur"),
|
||||||
|
url: "https://aur.archlinux.org/packages/triliumnext-bin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
macos: {
|
||||||
|
title: {
|
||||||
|
x64: t("download_helper_desktop_macos.title_x64"),
|
||||||
|
arm64: t("download_helper_desktop_macos.title_arm64")
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
x64: t("download_helper_desktop_macos.description_x64"),
|
||||||
|
arm64: t("download_helper_desktop_macos.description_arm64"),
|
||||||
|
},
|
||||||
|
quickStartTitle: t("download_helper_desktop_macos.quick_start"),
|
||||||
|
quickStartCode: "brew install --cask trilium-notes",
|
||||||
|
downloads: {
|
||||||
|
dmg: {
|
||||||
|
recommended: true,
|
||||||
|
name: t("download_helper_desktop_macos.download_dmg")
|
||||||
|
},
|
||||||
|
homebrew: {
|
||||||
|
name: t("download_helper_desktop_macos.download_homebrew_cask"),
|
||||||
|
url: "https://formulae.brew.sh/cask/trilium-notes#default"
|
||||||
|
},
|
||||||
|
zip: {
|
||||||
|
name: t("download_helper_desktop_macos.download_zip")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
linux: {
|
server: {
|
||||||
title: {
|
docker: {
|
||||||
x64: t("download_helper_desktop_linux.title_x64"),
|
title: t("download_helper_server_docker.title"),
|
||||||
arm64: t("download_helper_desktop_linux.title_arm64")
|
description: t("download_helper_server_docker.description"),
|
||||||
},
|
helpUrl: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Installation%20%26%20Setup/Server%20Installation/1.%20Installing%20the%20server/Using%20Docker.html",
|
||||||
description: {
|
quickStartCode: "docker pull triliumnext/trilium\ndocker run -p 8080:8080 -d -v ./data:/home/node/trilium-data triliumnext/trilium",
|
||||||
x64: t("download_helper_desktop_linux.description_x64"),
|
downloads: {
|
||||||
arm64: t("download_helper_desktop_linux.description_arm64"),
|
dockerhub: {
|
||||||
},
|
name: t("download_helper_server_docker.download_dockerhub"),
|
||||||
quickStartTitle: t("download_helper_desktop_linux.quick_start"),
|
url: "https://hub.docker.com/r/triliumnext/trilium"
|
||||||
downloads: {
|
},
|
||||||
deb: {
|
ghcr: {
|
||||||
recommended: true,
|
name: t("download_helper_server_docker.download_ghcr"),
|
||||||
name: t("download_helper_desktop_linux.download_deb")
|
url: "https://github.com/TriliumNext/Trilium/pkgs/container/trilium"
|
||||||
},
|
}
|
||||||
rpm: {
|
|
||||||
recommended: true,
|
|
||||||
name: t("download_helper_desktop_linux.download_rpm")
|
|
||||||
},
|
|
||||||
flatpak: {
|
|
||||||
name: t("download_helper_desktop_linux.download_flatpak")
|
|
||||||
},
|
|
||||||
zip: {
|
|
||||||
name: t("download_helper_desktop_linux.download_zip")
|
|
||||||
},
|
|
||||||
nixpkgs: {
|
|
||||||
name: t("download_helper_desktop_linux.download_nixpkgs"),
|
|
||||||
url: "https://search.nixos.org/packages?query=trilium-next"
|
|
||||||
},
|
|
||||||
aur: {
|
|
||||||
name: t("download_helper_desktop_linux.download_aur"),
|
|
||||||
url: "https://aur.archlinux.org/packages/triliumnext-bin"
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
macos: {
|
|
||||||
title: {
|
|
||||||
x64: t("download_helper_desktop_macos.title_x64"),
|
|
||||||
arm64: t("download_helper_desktop_macos.title_arm64")
|
|
||||||
},
|
},
|
||||||
description: {
|
linux: {
|
||||||
x64: t("download_helper_desktop_macos.description_x64"),
|
title: t("download_helper_server_linux.title"),
|
||||||
arm64: t("download_helper_desktop_macos.description_arm64"),
|
description: t("download_helper_server_linux.description"),
|
||||||
|
helpUrl: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Installation%20%26%20Setup/Server%20Installation/1.%20Installing%20the%20server/Packaged%20version%20for%20Linux.html",
|
||||||
|
downloads: {
|
||||||
|
tarX64: {
|
||||||
|
recommended: true,
|
||||||
|
name: t("download_helper_server_linux.download_tar_x64"),
|
||||||
|
url: `https://github.com/TriliumNext/Trilium/releases/download/v${version}/TriliumNotes-Server-v${version}-linux-x64.tar.xz`,
|
||||||
|
},
|
||||||
|
tarArm64: {
|
||||||
|
recommended: true,
|
||||||
|
name: t("download_helper_server_linux.download_tar_arm64"),
|
||||||
|
url: `https://github.com/TriliumNext/Trilium/releases/download/v${version}/TriliumNotes-Server-v${version}-linux-arm64.tar.xz`
|
||||||
|
},
|
||||||
|
nixos: {
|
||||||
|
name: t("download_helper_server_linux.download_nixos"),
|
||||||
|
url: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation/1.%20Installing%20the%20server/On%20NixOS"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
quickStartTitle: t("download_helper_desktop_macos.quick_start"),
|
pikapod: {
|
||||||
quickStartCode: "brew install --cask trilium-notes",
|
title: t("download_helper_server_hosted.title"),
|
||||||
downloads: {
|
description: t("download_helper_server_hosted.description"),
|
||||||
dmg: {
|
downloads: {
|
||||||
recommended: true,
|
pikapod: {
|
||||||
name: t("download_helper_desktop_macos.download_dmg")
|
recommended: true,
|
||||||
},
|
name: t("download_helper_server_hosted.download_pikapod"),
|
||||||
homebrew: {
|
url: "https://www.pikapods.com/pods?run=trilium-next"
|
||||||
name: t("download_helper_desktop_macos.download_homebrew_cask"),
|
},
|
||||||
url: "https://formulae.brew.sh/cask/trilium-notes#default"
|
triliumcc: {
|
||||||
},
|
name: t("download_helper_server_hosted.download_triliumcc"),
|
||||||
zip: {
|
url: "https://trilium.cc/"
|
||||||
name: t("download_helper_desktop_macos.download_zip")
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
server: {
|
|
||||||
docker: {
|
|
||||||
title: t("download_helper_server_docker.title"),
|
|
||||||
description: t("download_helper_server_docker.description"),
|
|
||||||
helpUrl: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Installation%20%26%20Setup/Server%20Installation/1.%20Installing%20the%20server/Using%20Docker.html",
|
|
||||||
quickStartCode: "docker pull triliumnext/trilium\ndocker run -p 8080:8080 -d -v ./data:/home/node/trilium-data triliumnext/trilium",
|
|
||||||
downloads: {
|
|
||||||
dockerhub: {
|
|
||||||
name: t("download_helper_server_docker.download_dockerhub"),
|
|
||||||
url: "https://hub.docker.com/r/triliumnext/trilium"
|
|
||||||
},
|
|
||||||
ghcr: {
|
|
||||||
name: t("download_helper_server_docker.download_ghcr"),
|
|
||||||
url: "https://github.com/TriliumNext/Trilium/pkgs/container/trilium"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
linux: {
|
|
||||||
title: t("download_helper_server_linux.title"),
|
|
||||||
description: t("download_helper_server_linux.description"),
|
|
||||||
helpUrl: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Installation%20%26%20Setup/Server%20Installation/1.%20Installing%20the%20server/Packaged%20version%20for%20Linux.html",
|
|
||||||
downloads: {
|
|
||||||
tarX64: {
|
|
||||||
recommended: true,
|
|
||||||
name: t("download_helper_server_linux.download_tar_x64"),
|
|
||||||
url: `https://github.com/TriliumNext/Trilium/releases/download/v${version}/TriliumNotes-Server-v${version}-linux-x64.tar.xz`,
|
|
||||||
},
|
|
||||||
tarArm64: {
|
|
||||||
recommended: true,
|
|
||||||
name: t("download_helper_server_linux.download_tar_arm64"),
|
|
||||||
url: `https://github.com/TriliumNext/Trilium/releases/download/v${version}/TriliumNotes-Server-v${version}-linux-arm64.tar.xz`
|
|
||||||
},
|
|
||||||
nixos: {
|
|
||||||
name: t("download_helper_server_linux.download_nixos"),
|
|
||||||
url: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation/1.%20Installing%20the%20server/On%20NixOS"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
pikapod: {
|
|
||||||
title: t("download_helper_server_hosted.title"),
|
|
||||||
description: t("download_helper_server_hosted.description"),
|
|
||||||
downloads: {
|
|
||||||
pikapod: {
|
|
||||||
recommended: true,
|
|
||||||
name: t("download_helper_server_hosted.download_pikapod"),
|
|
||||||
url: "https://www.pikapods.com/pods?run=trilium-next"
|
|
||||||
},
|
|
||||||
triliumcc: {
|
|
||||||
name: t("download_helper_server_hosted.download_triliumcc"),
|
|
||||||
url: "https://trilium.cc/"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export function buildDownloadUrl(app: App, platform: Platform, format: string, architecture: Architecture): string {
|
export function buildDownloadUrl(t: TFunction<"translation", undefined>, app: App, platform: Platform, format: string, architecture: Architecture): string {
|
||||||
|
const downloadMatrix = getDownloadMatrix(t);
|
||||||
|
|
||||||
if (app === "desktop") {
|
if (app === "desktop") {
|
||||||
return downloadMatrix.desktop[platform]?.downloads[format].url ??
|
return downloadMatrix.desktop[platform]?.downloads[format].url ??
|
||||||
`https://github.com/TriliumNext/Trilium/releases/download/v${version}/TriliumNotes-v${version}-${platform}-${architecture}.${format}`;
|
`https://github.com/TriliumNext/Trilium/releases/download/v${version}/TriliumNotes-v${version}-${platform}-${architecture}.${format}`;
|
||||||
@@ -218,8 +222,9 @@ export function getPlatform(): Platform | null {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getRecommendedDownload(): Promise<RecommendedDownload | null> {
|
export async function getRecommendedDownload(t: TFunction<"translation", undefined>): Promise<RecommendedDownload | null> {
|
||||||
if (typeof window === "undefined") return null;
|
if (typeof window === "undefined") return null;
|
||||||
|
const downloadMatrix = getDownloadMatrix(t);
|
||||||
|
|
||||||
const architecture = await getArchitecture();
|
const architecture = await getArchitecture();
|
||||||
const platform = getPlatform();
|
const platform = getPlatform();
|
||||||
@@ -233,7 +238,7 @@ export async function getRecommendedDownload(): Promise<RecommendedDownload | nu
|
|||||||
if (!recommendedDownload) return null;
|
if (!recommendedDownload) return null;
|
||||||
|
|
||||||
const format = recommendedDownload[0];
|
const format = recommendedDownload[0];
|
||||||
const url = buildDownloadUrl("desktop", platform, format || 'zip', architecture);
|
const url = buildDownloadUrl(t, "desktop", platform, format || 'zip', architecture);
|
||||||
|
|
||||||
const platformTitle = platformInfo.title;
|
const platformTitle = platformInfo.title;
|
||||||
const name = typeof platformTitle === "string" ? platformTitle : platformTitle[architecture] as string;
|
const name = typeof platformTitle === "string" ? platformTitle : platformTitle[architecture] as string;
|
||||||
|
|||||||
@@ -33,5 +33,3 @@ await i18next.init({
|
|||||||
},
|
},
|
||||||
returnEmptyString: false
|
returnEmptyString: false
|
||||||
});
|
});
|
||||||
|
|
||||||
export const t = i18next.t;
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import Footer from './components/Footer.js';
|
|||||||
import GetStarted from './pages/GetStarted/get-started.js';
|
import GetStarted from './pages/GetStarted/get-started.js';
|
||||||
import SupportUs from './pages/SupportUs/SupportUs.js';
|
import SupportUs from './pages/SupportUs/SupportUs.js';
|
||||||
import { createContext } from 'preact';
|
import { createContext } from 'preact';
|
||||||
|
import { useEffect } from 'preact/hooks';
|
||||||
|
import { changeLanguage } from 'i18next';
|
||||||
|
|
||||||
export const LocaleContext = createContext('en');
|
export const LocaleContext = createContext('en');
|
||||||
|
|
||||||
@@ -34,6 +36,10 @@ export function LocaleProvider({ children }) {
|
|||||||
const { path } = useLocation();
|
const { path } = useLocation();
|
||||||
const locale = path.split('/')[1] || 'en';
|
const locale = path.split('/')[1] || 'en';
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
changeLanguage(locale);
|
||||||
|
}, [ locale ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LocaleContext.Provider value={locale}>
|
<LocaleContext.Provider value={locale}>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
import { useLayoutEffect, useState } from "preact/hooks";
|
import { useLayoutEffect, useState } from "preact/hooks";
|
||||||
import Card from "../../components/Card.js";
|
import Card from "../../components/Card.js";
|
||||||
import Section from "../../components/Section.js";
|
import Section from "../../components/Section.js";
|
||||||
import { App, Architecture, buildDownloadUrl, downloadMatrix, DownloadMatrixEntry, getArchitecture, getPlatform, Platform } from "../../download-helper.js";
|
import { App, Architecture, buildDownloadUrl, DownloadMatrixEntry, getArchitecture, getDownloadMatrix, getPlatform, Platform } from "../../download-helper.js";
|
||||||
import { usePageTitle } from "../../hooks.js";
|
import { usePageTitle } from "../../hooks.js";
|
||||||
import Button, { Link } from "../../components/Button.js";
|
import Button, { Link } from "../../components/Button.js";
|
||||||
import Icon from "../../components/Icon.js";
|
import Icon from "../../components/Icon.js";
|
||||||
import helpIcon from "../../assets/boxicons/bx-help-circle.svg?raw";
|
import helpIcon from "../../assets/boxicons/bx-help-circle.svg?raw";
|
||||||
import "./get-started.css";
|
import "./get-started.css";
|
||||||
import packageJson from "../../../../../package.json" with { type: "json" };
|
import packageJson from "../../../../../package.json" with { type: "json" };
|
||||||
import { t } from "../../i18n.js";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
export default function DownloadPage() {
|
export default function DownloadPage() {
|
||||||
|
const { t } = useTranslation();
|
||||||
const [ currentArch, setCurrentArch ] = useState<Architecture>("x64");
|
const [ currentArch, setCurrentArch ] = useState<Architecture>("x64");
|
||||||
const [ userPlatform, setUserPlatform ] = useState<Platform>();
|
const [ userPlatform, setUserPlatform ] = useState<Platform>();
|
||||||
|
const downloadMatrix = getDownloadMatrix(t);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
getArchitecture().then((arch) => setCurrentArch(arch ?? "x64"));
|
getArchitecture().then((arch) => setCurrentArch(arch ?? "x64"));
|
||||||
@@ -71,6 +73,7 @@ export function DownloadCard({ app, arch, entry: [ platform, entry ], isRecommen
|
|||||||
return (typeof text === "string" ? text : text[arch]);
|
return (typeof text === "string" ? text : text[arch]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { t } = useTranslation();
|
||||||
const allDownloads = Object.entries(entry.downloads);
|
const allDownloads = Object.entries(entry.downloads);
|
||||||
const recommendedDownloads = allDownloads.filter(download => download[1].recommended);
|
const recommendedDownloads = allDownloads.filter(download => download[1].recommended);
|
||||||
const restDownloads = allDownloads.filter(download => !download[1].recommended);
|
const restDownloads = allDownloads.filter(download => !download[1].recommended);
|
||||||
@@ -107,7 +110,7 @@ export function DownloadCard({ app, arch, entry: [ platform, entry ], isRecommen
|
|||||||
{recommendedDownloads.map(recommendedDownload => (
|
{recommendedDownloads.map(recommendedDownload => (
|
||||||
<Button
|
<Button
|
||||||
className="recommended"
|
className="recommended"
|
||||||
href={buildDownloadUrl(app, platform as Platform, recommendedDownload[0], arch)}
|
href={buildDownloadUrl(t, app, platform as Platform, recommendedDownload[0], arch)}
|
||||||
text={recommendedDownload[1].name}
|
text={recommendedDownload[1].name}
|
||||||
openExternally={!!recommendedDownload[1].url}
|
openExternally={!!recommendedDownload[1].url}
|
||||||
/>
|
/>
|
||||||
@@ -117,7 +120,7 @@ export function DownloadCard({ app, arch, entry: [ platform, entry ], isRecommen
|
|||||||
<div class="other-options">
|
<div class="other-options">
|
||||||
{restDownloads.map(download => (
|
{restDownloads.map(download => (
|
||||||
<Link
|
<Link
|
||||||
href={buildDownloadUrl(app, platform as Platform, download[0], arch)}
|
href={buildDownloadUrl(t, app, platform as Platform, download[0], arch)}
|
||||||
openExternally={!!download[1].url}
|
openExternally={!!download[1].url}
|
||||||
>
|
>
|
||||||
{download[1].name}
|
{download[1].name}
|
||||||
|
|||||||
@@ -31,8 +31,7 @@ import boardIcon from "../../assets/boxicons/bx-columns-3.svg?raw";
|
|||||||
import geomapIcon from "../../assets/boxicons/bx-map.svg?raw";
|
import geomapIcon from "../../assets/boxicons/bx-map.svg?raw";
|
||||||
import { getPlatform } from '../../download-helper.js';
|
import { getPlatform } from '../../download-helper.js';
|
||||||
import { useEffect, useState } from 'preact/hooks';
|
import { useEffect, useState } from 'preact/hooks';
|
||||||
import { t } from '../../i18n.js';
|
import { Trans, useTranslation } from 'react-i18next';
|
||||||
import { Trans } from 'react-i18next';
|
|
||||||
|
|
||||||
export function Home() {
|
export function Home() {
|
||||||
usePageTitle("");
|
usePageTitle("");
|
||||||
@@ -52,6 +51,7 @@ export function Home() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function HeroSection() {
|
function HeroSection() {
|
||||||
|
const { t } = useTranslation();
|
||||||
const platform = getPlatform();
|
const platform = getPlatform();
|
||||||
const colorScheme = useColorScheme();
|
const colorScheme = useColorScheme();
|
||||||
const [ screenshotUrl, setScreenshotUrl ] = useState<string>();
|
const [ screenshotUrl, setScreenshotUrl ] = useState<string>();
|
||||||
@@ -96,6 +96,7 @@ function HeroSection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function OrganizationBenefitsSection() {
|
function OrganizationBenefitsSection() {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Section className="benefits" title={t("organization_benefits.title")}>
|
<Section className="benefits" title={t("organization_benefits.title")}>
|
||||||
@@ -110,6 +111,7 @@ function OrganizationBenefitsSection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ProductivityBenefitsSection() {
|
function ProductivityBenefitsSection() {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Section className="benefits accented" title={t("productivity_benefits.title")}>
|
<Section className="benefits accented" title={t("productivity_benefits.title")}>
|
||||||
@@ -127,6 +129,7 @@ function ProductivityBenefitsSection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function NoteTypesSection() {
|
function NoteTypesSection() {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Section className="note-types" title="Multiple ways to represent your information">
|
<Section className="note-types" title="Multiple ways to represent your information">
|
||||||
<ListWithScreenshot horizontal items={[
|
<ListWithScreenshot horizontal items={[
|
||||||
@@ -190,6 +193,7 @@ function NoteTypesSection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ExtensibilityBenefitsSection() {
|
function ExtensibilityBenefitsSection() {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Section className="benefits accented" title={t("extensibility_benefits.title")}>
|
<Section className="benefits accented" title={t("extensibility_benefits.title")}>
|
||||||
@@ -205,6 +209,7 @@ function ExtensibilityBenefitsSection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function CollectionsSection() {
|
function CollectionsSection() {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Section className="collections" title="Collections">
|
<Section className="collections" title="Collections">
|
||||||
<ListWithScreenshot items={[
|
<ListWithScreenshot items={[
|
||||||
@@ -247,6 +252,7 @@ function ListWithScreenshot({ items, horizontal, cardExtra }: {
|
|||||||
cardExtra?: ComponentChildren;
|
cardExtra?: ComponentChildren;
|
||||||
}) {
|
}) {
|
||||||
const [ selectedItem, setSelectedItem ] = useState(items[0]);
|
const [ selectedItem, setSelectedItem ] = useState(items[0]);
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`list-with-screenshot ${horizontal ? "horizontal" : ""}`}>
|
<div className={`list-with-screenshot ${horizontal ? "horizontal" : ""}`}>
|
||||||
@@ -278,6 +284,7 @@ function ListWithScreenshot({ items, horizontal, cardExtra }: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function FaqSection() {
|
function FaqSection() {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Section className="faq" title={t("faq.title")}>
|
<Section className="faq" title={t("faq.title")}>
|
||||||
<div class="grid-2-cols">
|
<div class="grid-2-cols">
|
||||||
@@ -301,6 +308,7 @@ function FaqItem({ question, children }: { question: string; children: Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
function FinalCta() {
|
function FinalCta() {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Section className="final-cta accented" title={t("final_cta.title")}>
|
<Section className="final-cta accented" title={t("final_cta.title")}>
|
||||||
<p>{t("final_cta.description")}</p>
|
<p>{t("final_cta.description")}</p>
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import buyMeACoffeeIcon from "../../assets/boxicons/bx-buy-me-a-coffee.svg?raw";
|
|||||||
import Button, { Link } from "../../components/Button.js";
|
import Button, { Link } from "../../components/Button.js";
|
||||||
import Card from "../../components/Card.js";
|
import Card from "../../components/Card.js";
|
||||||
import { usePageTitle } from "../../hooks.js";
|
import { usePageTitle } from "../../hooks.js";
|
||||||
import { t } from "../../i18n.js";
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
import { Trans } from "react-i18next";
|
|
||||||
|
|
||||||
export default function Donate() {
|
export default function Donate() {
|
||||||
|
const { t } = useTranslation();
|
||||||
usePageTitle(t("support_us.title"));
|
usePageTitle(t("support_us.title"));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
import { useTranslation } from "react-i18next";
|
||||||
import Section from "../components/Section.js";
|
import Section from "../components/Section.js";
|
||||||
import { usePageTitle } from "../hooks.js";
|
import { usePageTitle } from "../hooks.js";
|
||||||
import { t } from "../i18n.js";
|
|
||||||
import "./_404.css";
|
import "./_404.css";
|
||||||
|
|
||||||
export function NotFound() {
|
export function NotFound() {
|
||||||
|
const { t } = useTranslation();
|
||||||
usePageTitle(t("404.title"));
|
usePageTitle(t("404.title"));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user