mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-11-26 06:11:15 +00:00
Merge remote-tracking branch 'origin/main' into feat/add-post-body-preview-to-desktop
* origin/main: (40 commits) Adding jsit to codeowners. Cleanup, only check for /u/ if /c/ and /m/ checks fail Rename function to be more generic, since it parses users Typescript linter fixes bandaid fix our video embeds Remove pipe from community link regex Add missing classes Use shorter regex in community link parser Move regex pattern to config Update community link markdown parsing Fix avatar alignment issue (#1475) Omit user-scalable to use default Update getHttpBase dependency reference Enable users to zoom on mobile rethink it a bit rethink it a bit add fallback style tag move env utils into folder fix capitalization (#1467) Fix buildThemeList() function to ensure no duplicates (#1466) ...
This commit is contained in:
commit
a9bcf0567d
97 changed files with 1478 additions and 1121 deletions
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
|
@ -1 +1 @@
|
|||
* @dessalines @SleeplessOne1917 @alectrocute
|
||||
* @dessalines @SleeplessOne1917 @alectrocute @jsit
|
||||
|
|
15
package.json
15
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "lemmy-ui",
|
||||
"version": "0.18.0-rc.4",
|
||||
"version": "0.18.0-rc.6",
|
||||
"description": "An isomorphic UI for lemmy",
|
||||
"repository": "https://github.com/LemmyNet/lemmy-ui",
|
||||
"license": "AGPL-3.0",
|
||||
|
@ -22,9 +22,16 @@
|
|||
"translations:update": "git submodule update --remote --recursive"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{ts,tsx,js}": ["prettier --write", "eslint --fix"],
|
||||
"*.{css, scss}": ["prettier --write"],
|
||||
"package.json": ["sortpack"]
|
||||
"*.{ts,tsx,js}": [
|
||||
"prettier --write",
|
||||
"eslint --fix"
|
||||
],
|
||||
"*.{css, scss}": [
|
||||
"prettier --write"
|
||||
],
|
||||
"package.json": [
|
||||
"sortpack"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/plugin-proposal-decorators": "^7.21.0",
|
||||
|
|
|
@ -2,7 +2,7 @@ import { initializeSite } from "@utils/app";
|
|||
import { hydrate } from "inferno-hydrate";
|
||||
import { Router } from "inferno-router";
|
||||
import { App } from "../shared/components/app/app";
|
||||
import { HistoryService } from "../shared/services/HistoryService";
|
||||
import { HistoryService } from "../shared/services";
|
||||
|
||||
import "bootstrap/js/dist/collapse";
|
||||
import "bootstrap/js/dist/dropdown";
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import { initializeSite, isAuthPath } from "@utils/app";
|
||||
import { getHttpBaseInternal } from "@utils/env";
|
||||
import { ErrorPageData } from "@utils/types";
|
||||
import fetch from "cross-fetch";
|
||||
import type { Request, Response } from "express";
|
||||
import { StaticRouter, matchPath } from "inferno-router";
|
||||
import { renderToString } from "inferno-server";
|
||||
import IsomorphicCookie from "isomorphic-cookie";
|
||||
import { GetSite, GetSiteResponse, LemmyHttp } from "lemmy-js-client";
|
||||
import { App } from "../../shared/components/app/app";
|
||||
import { getHttpBaseInternal } from "../../shared/env";
|
||||
import {
|
||||
InitialFetchRequest,
|
||||
IsoDataOptionalSite,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { getHttpBaseExternal, getHttpBaseInternal } from "@utils/env";
|
||||
import fetch from "cross-fetch";
|
||||
import type { Request, Response } from "express";
|
||||
import { LemmyHttp } from "lemmy-js-client";
|
||||
import { getHttpBaseInternal } from "../../shared/env";
|
||||
import { wrapClient } from "../../shared/services/HttpService";
|
||||
import generateManifestJson from "../utils/generate-manifest-json";
|
||||
import { setForwardedHeaders } from "../utils/set-forwarded-headers";
|
||||
|
@ -9,7 +10,7 @@ let manifest: Awaited<ReturnType<typeof generateManifestJson>> | undefined =
|
|||
undefined;
|
||||
|
||||
export default async (req: Request, res: Response) => {
|
||||
if (!manifest) {
|
||||
if (!manifest || manifest.start_url !== getHttpBaseExternal()) {
|
||||
const headers = setForwardedHeaders(req.headers);
|
||||
const client = wrapClient(
|
||||
new LemmyHttp(getHttpBaseInternal(), { fetchFunction: fetch, headers })
|
||||
|
|
|
@ -25,7 +25,7 @@ if (!process.env["LEMMY_UI_DISABLE_CSP"] && !process.env["LEMMY_UI_DEBUG"]) {
|
|||
|
||||
server.get("/robots.txt", RobotsHandler);
|
||||
server.get("/service-worker.js", ServiceWorkerHandler);
|
||||
server.get("/manifest", ManifestHandler);
|
||||
server.get("/manifest.webmanifest", ManifestHandler);
|
||||
server.get("/css/themes/:name", ThemeHandler);
|
||||
server.get("/css/themelist", ThemesListHandler);
|
||||
server.get("/*", CatchAllHandler);
|
||||
|
|
|
@ -4,15 +4,20 @@ import { readdir } from "fs/promises";
|
|||
const extraThemesFolder =
|
||||
process.env["LEMMY_UI_EXTRA_THEMES_FOLDER"] || "./extra_themes";
|
||||
|
||||
const themes = ["darkly", "darkly-red", "litely", "litely-red"];
|
||||
const themes: ReadonlyArray<string> = [
|
||||
"darkly",
|
||||
"darkly-red",
|
||||
"litely",
|
||||
"litely-red",
|
||||
];
|
||||
|
||||
export async function buildThemeList(): Promise<string[]> {
|
||||
export async function buildThemeList(): Promise<ReadonlyArray<string>> {
|
||||
if (existsSync(extraThemesFolder)) {
|
||||
const dirThemes = await readdir(extraThemesFolder);
|
||||
const cssThemes = dirThemes
|
||||
.filter(d => d.endsWith(".css"))
|
||||
.map(d => d.replace(".css", ""));
|
||||
themes.push(...cssThemes);
|
||||
return themes.concat(cssThemes);
|
||||
}
|
||||
return themes;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import serialize from "serialize-javascript";
|
|||
import sharp from "sharp";
|
||||
import { favIconPngUrl, favIconUrl } from "../../shared/config";
|
||||
import { ILemmyConfig, IsoDataOptionalSite } from "../../shared/interfaces";
|
||||
import { buildThemeList } from "./build-themes-list";
|
||||
import { fetchIconPng } from "./fetch-icon-png";
|
||||
|
||||
const customHtmlHeader = process.env["LEMMY_UI_CUSTOM_HTML_HEADER"] || "";
|
||||
|
@ -16,6 +17,10 @@ export async function createSsrHtml(
|
|||
) {
|
||||
const site = isoData.site_res;
|
||||
|
||||
const fallbackTheme = `<link rel="stylesheet" type="text/css" href="/css/themes/${
|
||||
(await buildThemeList())[0]
|
||||
}.css" />`;
|
||||
|
||||
if (!appleTouchIcon) {
|
||||
appleTouchIcon = site?.site_view.site.icon
|
||||
? `data:image/png;base64,${sharp(
|
||||
|
@ -68,7 +73,7 @@ export async function createSsrHtml(
|
|||
<!-- Required meta tags -->
|
||||
<meta name="Description" content="Lemmy">
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<link
|
||||
id="favicon"
|
||||
rel="shortcut icon"
|
||||
|
@ -77,7 +82,7 @@ export async function createSsrHtml(
|
|||
/>
|
||||
|
||||
<!-- Web app manifest -->
|
||||
<link rel="manifest" href="/manifest" />
|
||||
<link rel="manifest" href="/manifest.webmanifest" />
|
||||
<link rel="apple-touch-icon" href=${appleTouchIcon} />
|
||||
<link rel="apple-touch-startup-image" href=${appleTouchIcon} />
|
||||
|
||||
|
@ -85,7 +90,7 @@ export async function createSsrHtml(
|
|||
<link rel="stylesheet" type="text/css" href="/static/styles/styles.css" />
|
||||
|
||||
<!-- Current theme and more -->
|
||||
${helmet.link.toString()}
|
||||
${helmet.link.toString() || fallbackTheme}
|
||||
|
||||
</head>
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import fetch from "cross-fetch";
|
||||
|
||||
export async function fetchIconPng(iconUrl: string) {
|
||||
return await fetch(iconUrl)
|
||||
.then(res => res.blob())
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { getHttpBaseExternal } from "@utils/env";
|
||||
import { readFile } from "fs/promises";
|
||||
import { GetSiteResponse } from "lemmy-js-client";
|
||||
import path from "path";
|
||||
import sharp from "sharp";
|
||||
import { getHttpBaseExternal } from "../../shared/env";
|
||||
import { fetchIconPng } from "./fetch-icon-png";
|
||||
|
||||
const iconSizes = [72, 96, 128, 144, 152, 192, 384, 512];
|
||||
|
|
|
@ -2,9 +2,9 @@ import { isAuthPath, setIsoData } from "@utils/app";
|
|||
import { Component, RefObject, createRef, linkEvent } from "inferno";
|
||||
import { Provider } from "inferno-i18next-dess";
|
||||
import { Route, Switch } from "inferno-router";
|
||||
import { i18n } from "../../i18next";
|
||||
import { IsoDataOptionalSite } from "../../interfaces";
|
||||
import { routes } from "../../routes";
|
||||
import { I18NextService } from "../../services";
|
||||
import AuthGuard from "../common/auth-guard";
|
||||
import ErrorGuard from "../common/error-guard";
|
||||
import { ErrorPage } from "./error-page";
|
||||
|
@ -31,13 +31,13 @@ export class App extends Component<any, any> {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Provider i18next={i18n}>
|
||||
<Provider i18next={I18NextService.i18n}>
|
||||
<div id="app" className="lemmy-site">
|
||||
<a
|
||||
className="skip-link bg-light text-dark p-2 text-decoration-none position-absolute start-0 z-3"
|
||||
onClick={linkEvent(this, this.handleJumpToContent)}
|
||||
>
|
||||
${i18n.t("jump_to_content", "Jump to content")}
|
||||
${I18NextService.i18n.t("jump_to_content", "Jump to content")}
|
||||
</a>
|
||||
{siteView && (
|
||||
<Theme defaultTheme={siteView.local_site.default_theme} />
|
||||
|
|
|
@ -2,8 +2,8 @@ import { setIsoData } from "@utils/app";
|
|||
import { Component } from "inferno";
|
||||
import { T } from "inferno-i18next-dess";
|
||||
import { Link } from "inferno-router";
|
||||
import { i18n } from "../../i18next";
|
||||
import { IsoDataOptionalSite } from "../../interfaces";
|
||||
import { I18NextService } from "../../services";
|
||||
|
||||
export class ErrorPage extends Component<any, any> {
|
||||
private isoData: IsoDataOptionalSite = setIsoData(this.context);
|
||||
|
@ -19,8 +19,8 @@ export class ErrorPage extends Component<any, any> {
|
|||
<div className="error-page container-lg text-center">
|
||||
<h1>
|
||||
{errorPageData
|
||||
? i18n.t("error_page_title")
|
||||
: i18n.t("not_found_page_title")}
|
||||
? I18NextService.i18n.t("error_page_title")
|
||||
: I18NextService.i18n.t("not_found_page_title")}
|
||||
</h1>
|
||||
{errorPageData ? (
|
||||
<T i18nKey="error_page_paragraph" className="p-4" parent="p">
|
||||
|
@ -28,18 +28,18 @@ export class ErrorPage extends Component<any, any> {
|
|||
<a href="https://matrix.to/#/#lemmy-space:matrix.org">#</a>#
|
||||
</T>
|
||||
) : (
|
||||
<p>{i18n.t("not_found_page_message")}</p>
|
||||
<p>{I18NextService.i18n.t("not_found_page_message")}</p>
|
||||
)}
|
||||
{!errorPageData && (
|
||||
<Link to="/" replace>
|
||||
{i18n.t("not_found_return_home_button")}
|
||||
{I18NextService.i18n.t("not_found_return_home_button")}
|
||||
</Link>
|
||||
)}
|
||||
{errorPageData?.adminMatrixIds &&
|
||||
errorPageData.adminMatrixIds.length > 0 && (
|
||||
<>
|
||||
<div>
|
||||
{i18n.t("error_page_admin_matrix", {
|
||||
{I18NextService.i18n.t("error_page_admin_matrix", {
|
||||
instance:
|
||||
this.isoData.site_res?.site_view.site.name ??
|
||||
"this instance",
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Component } from "inferno";
|
|||
import { NavLink } from "inferno-router";
|
||||
import { GetSiteResponse } from "lemmy-js-client";
|
||||
import { docsUrl, joinLemmyUrl, repoUrl } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { VERSION } from "../../version";
|
||||
|
||||
interface FooterProps {
|
||||
|
@ -29,36 +29,36 @@ export class Footer extends Component<FooterProps, any> {
|
|||
</li>
|
||||
<li className="nav-item">
|
||||
<NavLink className="nav-link" to="/modlog">
|
||||
{i18n.t("modlog")}
|
||||
{I18NextService.i18n.t("modlog")}
|
||||
</NavLink>
|
||||
</li>
|
||||
{this.props.site?.site_view.local_site.legal_information && (
|
||||
<li className="nav-item">
|
||||
<NavLink className="nav-link" to="/legal">
|
||||
{i18n.t("legal_information")}
|
||||
{I18NextService.i18n.t("legal_information")}
|
||||
</NavLink>
|
||||
</li>
|
||||
)}
|
||||
{this.props.site?.site_view.local_site.federation_enabled && (
|
||||
<li className="nav-item">
|
||||
<NavLink className="nav-link" to="/instances">
|
||||
{i18n.t("instances")}
|
||||
{I18NextService.i18n.t("instances")}
|
||||
</NavLink>
|
||||
</li>
|
||||
)}
|
||||
<li className="nav-item">
|
||||
<a className="nav-link" href={docsUrl}>
|
||||
{i18n.t("docs")}
|
||||
{I18NextService.i18n.t("docs")}
|
||||
</a>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<a className="nav-link" href={repoUrl}>
|
||||
{i18n.t("code")}
|
||||
{I18NextService.i18n.t("code")}
|
||||
</a>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<a className="nav-link" href={joinLemmyUrl}>
|
||||
{i18n.t("join_lemmy")}
|
||||
{I18NextService.i18n.t("join_lemmy")}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -11,8 +11,7 @@ import {
|
|||
GetUnreadRegistrationApplicationCountResponse,
|
||||
} from "lemmy-js-client";
|
||||
import { donateLemmyUrl, updateUnreadCountsInterval } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import { UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { toast } from "../../toast";
|
||||
import { Icon } from "../common/icon";
|
||||
|
@ -102,7 +101,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
<NavLink
|
||||
to="/inbox"
|
||||
className="p-1 nav-link border-0 nav-messages"
|
||||
title={i18n.t("unread_messages", {
|
||||
title={I18NextService.i18n.t("unread_messages", {
|
||||
count: Number(this.state.unreadApplicationCountRes.state),
|
||||
formattedCount: numToSI(this.unreadInboxCount),
|
||||
})}
|
||||
|
@ -121,7 +120,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
<NavLink
|
||||
to="/reports"
|
||||
className="p-1 nav-link border-0"
|
||||
title={i18n.t("unread_reports", {
|
||||
title={I18NextService.i18n.t("unread_reports", {
|
||||
count: Number(this.unreadReportCount),
|
||||
formattedCount: numToSI(this.unreadReportCount),
|
||||
})}
|
||||
|
@ -141,10 +140,13 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
<NavLink
|
||||
to="/registration_applications"
|
||||
className="p-1 nav-link border-0"
|
||||
title={i18n.t("unread_registration_applications", {
|
||||
title={I18NextService.i18n.t(
|
||||
"unread_registration_applications",
|
||||
{
|
||||
count: Number(this.unreadApplicationCount),
|
||||
formattedCount: numToSI(this.unreadApplicationCount),
|
||||
})}
|
||||
}
|
||||
)}
|
||||
onMouseUp={linkEvent(this, handleCollapseClick)}
|
||||
>
|
||||
<Icon icon="clipboard" />
|
||||
|
@ -162,7 +164,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
className="navbar-toggler border-0 p-1"
|
||||
type="button"
|
||||
aria-label="menu"
|
||||
data-tippy-content={i18n.t("expand_here")}
|
||||
data-tippy-content={I18NextService.i18n.t("expand_here")}
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#navbarDropdown"
|
||||
aria-controls="navbarDropdown"
|
||||
|
@ -181,10 +183,10 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
<NavLink
|
||||
to="/communities"
|
||||
className="nav-link"
|
||||
title={i18n.t("communities")}
|
||||
title={I18NextService.i18n.t("communities")}
|
||||
onMouseUp={linkEvent(this, handleCollapseClick)}
|
||||
>
|
||||
{i18n.t("communities")}
|
||||
{I18NextService.i18n.t("communities")}
|
||||
</NavLink>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
|
@ -198,10 +200,10 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
state: { prevPath: this.currentLocation },
|
||||
}}
|
||||
className="nav-link"
|
||||
title={i18n.t("create_post")}
|
||||
title={I18NextService.i18n.t("create_post")}
|
||||
onMouseUp={linkEvent(this, handleCollapseClick)}
|
||||
>
|
||||
{i18n.t("create_post")}
|
||||
{I18NextService.i18n.t("create_post")}
|
||||
</NavLink>
|
||||
</li>
|
||||
{this.props.siteRes && canCreateCommunity(this.props.siteRes) && (
|
||||
|
@ -209,22 +211,22 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
<NavLink
|
||||
to="/create_community"
|
||||
className="nav-link"
|
||||
title={i18n.t("create_community")}
|
||||
title={I18NextService.i18n.t("create_community")}
|
||||
onMouseUp={linkEvent(this, handleCollapseClick)}
|
||||
>
|
||||
{i18n.t("create_community")}
|
||||
{I18NextService.i18n.t("create_community")}
|
||||
</NavLink>
|
||||
</li>
|
||||
)}
|
||||
<li className="nav-item">
|
||||
<a
|
||||
className="nav-link d-inline-flex align-items-center d-md-inline-block"
|
||||
title={i18n.t("support_lemmy")}
|
||||
title={I18NextService.i18n.t("support_lemmy")}
|
||||
href={donateLemmyUrl}
|
||||
>
|
||||
<Icon icon="heart" classes="small" />
|
||||
<span className="d-inline ms-1 d-md-none ms-md-0">
|
||||
{i18n.t("support_lemmy")}
|
||||
{I18NextService.i18n.t("support_lemmy")}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
|
@ -234,12 +236,12 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
<NavLink
|
||||
to="/search"
|
||||
className="nav-link d-inline-flex align-items-center d-md-inline-block"
|
||||
title={i18n.t("search")}
|
||||
title={I18NextService.i18n.t("search")}
|
||||
onMouseUp={linkEvent(this, handleCollapseClick)}
|
||||
>
|
||||
<Icon icon="search" />
|
||||
<span className="d-inline ms-1 d-md-none ms-md-0">
|
||||
{i18n.t("search")}
|
||||
{I18NextService.i18n.t("search")}
|
||||
</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
|
@ -248,12 +250,12 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
<NavLink
|
||||
to="/admin"
|
||||
className="nav-link d-inline-flex align-items-center d-md-inline-block"
|
||||
title={i18n.t("admin_settings")}
|
||||
title={I18NextService.i18n.t("admin_settings")}
|
||||
onMouseUp={linkEvent(this, handleCollapseClick)}
|
||||
>
|
||||
<Icon icon="settings" />
|
||||
<span className="d-inline ms-1 d-md-none ms-md-0">
|
||||
{i18n.t("admin_settings")}
|
||||
{I18NextService.i18n.t("admin_settings")}
|
||||
</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
|
@ -264,7 +266,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
<NavLink
|
||||
className="nav-link d-inline-flex align-items-center d-md-inline-block"
|
||||
to="/inbox"
|
||||
title={i18n.t("unread_messages", {
|
||||
title={I18NextService.i18n.t("unread_messages", {
|
||||
count: Number(this.unreadInboxCount),
|
||||
formattedCount: numToSI(this.unreadInboxCount),
|
||||
})}
|
||||
|
@ -272,7 +274,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
>
|
||||
<Icon icon="bell" />
|
||||
<span className="badge text-bg-light d-inline ms-1 d-md-none ms-md-0">
|
||||
{i18n.t("unread_messages", {
|
||||
{I18NextService.i18n.t("unread_messages", {
|
||||
count: Number(this.unreadInboxCount),
|
||||
formattedCount: numToSI(this.unreadInboxCount),
|
||||
})}
|
||||
|
@ -289,7 +291,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
<NavLink
|
||||
className="nav-link d-inline-flex align-items-center d-md-inline-block"
|
||||
to="/reports"
|
||||
title={i18n.t("unread_reports", {
|
||||
title={I18NextService.i18n.t("unread_reports", {
|
||||
count: Number(this.unreadReportCount),
|
||||
formattedCount: numToSI(this.unreadReportCount),
|
||||
})}
|
||||
|
@ -297,7 +299,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
>
|
||||
<Icon icon="shield" />
|
||||
<span className="badge text-bg-light d-inline ms-1 d-md-none ms-md-0">
|
||||
{i18n.t("unread_reports", {
|
||||
{I18NextService.i18n.t("unread_reports", {
|
||||
count: Number(this.unreadReportCount),
|
||||
formattedCount: numToSI(this.unreadReportCount),
|
||||
})}
|
||||
|
@ -315,18 +317,26 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
<NavLink
|
||||
to="/registration_applications"
|
||||
className="nav-link d-inline-flex align-items-center d-md-inline-block"
|
||||
title={i18n.t("unread_registration_applications", {
|
||||
title={I18NextService.i18n.t(
|
||||
"unread_registration_applications",
|
||||
{
|
||||
count: Number(this.unreadApplicationCount),
|
||||
formattedCount: numToSI(this.unreadApplicationCount),
|
||||
})}
|
||||
}
|
||||
)}
|
||||
onMouseUp={linkEvent(this, handleCollapseClick)}
|
||||
>
|
||||
<Icon icon="clipboard" />
|
||||
<span className="badge text-bg-light d-inline ms-1 d-md-none ms-md-0">
|
||||
{i18n.t("unread_registration_applications", {
|
||||
{I18NextService.i18n.t(
|
||||
"unread_registration_applications",
|
||||
{
|
||||
count: Number(this.unreadApplicationCount),
|
||||
formattedCount: numToSI(this.unreadApplicationCount),
|
||||
})}
|
||||
formattedCount: numToSI(
|
||||
this.unreadApplicationCount
|
||||
),
|
||||
}
|
||||
)}
|
||||
</span>
|
||||
{this.unreadApplicationCount > 0 && (
|
||||
<span className="mx-1 badge text-bg-light">
|
||||
|
@ -357,22 +367,22 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
<NavLink
|
||||
to={`/u/${person.name}`}
|
||||
className="dropdown-item px-2"
|
||||
title={i18n.t("profile")}
|
||||
title={I18NextService.i18n.t("profile")}
|
||||
onMouseUp={linkEvent(this, handleCollapseClick)}
|
||||
>
|
||||
<Icon icon="user" classes="me-1" />
|
||||
{i18n.t("profile")}
|
||||
{I18NextService.i18n.t("profile")}
|
||||
</NavLink>
|
||||
</li>
|
||||
<li>
|
||||
<NavLink
|
||||
to="/settings"
|
||||
className="dropdown-item px-2"
|
||||
title={i18n.t("settings")}
|
||||
title={I18NextService.i18n.t("settings")}
|
||||
onMouseUp={linkEvent(this, handleCollapseClick)}
|
||||
>
|
||||
<Icon icon="settings" classes="me-1" />
|
||||
{i18n.t("settings")}
|
||||
{I18NextService.i18n.t("settings")}
|
||||
</NavLink>
|
||||
</li>
|
||||
<li>
|
||||
|
@ -384,7 +394,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
onClick={linkEvent(this, handleLogOut)}
|
||||
>
|
||||
<Icon icon="log-out" classes="me-1" />
|
||||
{i18n.t("logout")}
|
||||
{I18NextService.i18n.t("logout")}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -397,20 +407,20 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
<NavLink
|
||||
to="/login"
|
||||
className="nav-link"
|
||||
title={i18n.t("login")}
|
||||
title={I18NextService.i18n.t("login")}
|
||||
onMouseUp={linkEvent(this, handleCollapseClick)}
|
||||
>
|
||||
{i18n.t("login")}
|
||||
{I18NextService.i18n.t("login")}
|
||||
</NavLink>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<NavLink
|
||||
to="/signup"
|
||||
className="nav-link"
|
||||
title={i18n.t("sign_up")}
|
||||
title={I18NextService.i18n.t("sign_up")}
|
||||
onMouseUp={linkEvent(this, handleCollapseClick)}
|
||||
>
|
||||
{i18n.t("sign_up")}
|
||||
{I18NextService.i18n.t("sign_up")}
|
||||
</NavLink>
|
||||
</li>
|
||||
</>
|
||||
|
@ -504,7 +514,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
|||
if (UserService.Instance.myUserInfo) {
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
if (!Notification) {
|
||||
toast(i18n.t("notifications_error"), "danger");
|
||||
toast(I18NextService.i18n.t("notifications_error"), "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,9 +4,8 @@ import { Component } from "inferno";
|
|||
import { T } from "inferno-i18next-dess";
|
||||
import { Link } from "inferno-router";
|
||||
import { CreateComment, EditComment, Language } from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { CommentNodeI } from "../../interfaces";
|
||||
import { UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { Icon } from "../common/icon";
|
||||
import { MarkdownTextArea } from "../common/markdown-textarea";
|
||||
|
||||
|
@ -58,7 +57,7 @@ export class CommentForm extends Component<CommentFormProps, any> {
|
|||
disabled={this.props.disabled}
|
||||
onSubmit={this.handleCommentSubmit}
|
||||
onReplyCancel={this.props.onReplyCancel}
|
||||
placeholder={i18n.t("comment_here")}
|
||||
placeholder={I18NextService.i18n.t("comment_here") ?? undefined}
|
||||
allLanguages={this.props.allLanguages}
|
||||
siteLanguages={this.props.siteLanguages}
|
||||
/>
|
||||
|
@ -79,10 +78,10 @@ export class CommentForm extends Component<CommentFormProps, any> {
|
|||
|
||||
get buttonTitle(): string {
|
||||
return typeof this.props.node === "number"
|
||||
? capitalizeFirstLetter(i18n.t("post"))
|
||||
? capitalizeFirstLetter(I18NextService.i18n.t("post"))
|
||||
: this.props.edit
|
||||
? capitalizeFirstLetter(i18n.t("save"))
|
||||
: capitalizeFirstLetter(i18n.t("reply"));
|
||||
? capitalizeFirstLetter(I18NextService.i18n.t("save"))
|
||||
: capitalizeFirstLetter(I18NextService.i18n.t("reply"));
|
||||
}
|
||||
|
||||
handleCommentSubmit(content: string, form_id: string, language_id?: number) {
|
||||
|
|
|
@ -48,7 +48,6 @@ import {
|
|||
} from "lemmy-js-client";
|
||||
import moment from "moment";
|
||||
import { commentTreeMaxDepth } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import {
|
||||
BanType,
|
||||
CommentNodeI,
|
||||
|
@ -57,7 +56,7 @@ import {
|
|||
VoteType,
|
||||
} from "../../interfaces";
|
||||
import { mdToHtml, mdToHtmlNoImages } from "../../markdown";
|
||||
import { UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { setupTippy } from "../../tippy";
|
||||
import { Icon, PurgeWarning, Spinner } from "../common/icon";
|
||||
import { MomentTime } from "../common/moment-time";
|
||||
|
@ -241,8 +240,8 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
|
||||
const purgeTypeText =
|
||||
this.state.purgeType == PurgeType.Comment
|
||||
? i18n.t("purge_comment")
|
||||
: `${i18n.t("purge")} ${cv.creator.name}`;
|
||||
? I18NextService.i18n.t("purge_comment")
|
||||
: `${I18NextService.i18n.t("purge")} ${cv.creator.name}`;
|
||||
|
||||
const canMod_ = canMod(
|
||||
cv.creator.id,
|
||||
|
@ -314,27 +313,27 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
)}
|
||||
{this.isPostCreator && (
|
||||
<div className="badge text-bg-light d-none d-sm-inline me-2">
|
||||
{i18n.t("creator")}
|
||||
{I18NextService.i18n.t("creator")}
|
||||
</div>
|
||||
)}
|
||||
{isMod_ && (
|
||||
<div className="badge text-bg-light d-none d-sm-inline me-2">
|
||||
{i18n.t("mod")}
|
||||
{I18NextService.i18n.t("mod")}
|
||||
</div>
|
||||
)}
|
||||
{isAdmin_ && (
|
||||
<div className="badge text-bg-light d-none d-sm-inline me-2">
|
||||
{i18n.t("admin")}
|
||||
{I18NextService.i18n.t("admin")}
|
||||
</div>
|
||||
)}
|
||||
{cv.creator.bot_account && (
|
||||
<div className="badge text-bg-light d-none d-sm-inline me-2">
|
||||
{i18n.t("bot_account").toLowerCase()}
|
||||
{I18NextService.i18n.t("bot_account").toLowerCase()}
|
||||
</div>
|
||||
)}
|
||||
{this.props.showCommunity && (
|
||||
<>
|
||||
<span className="mx-1">{i18n.t("to")}</span>
|
||||
<span className="mx-1">{I18NextService.i18n.t("to")}</span>
|
||||
<CommunityLink community={cv.community} />
|
||||
<span className="mx-2">•</span>
|
||||
<Link className="me-2" to={`/post/${cv.post.id}`}>
|
||||
|
@ -366,7 +365,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
) : (
|
||||
<span
|
||||
className="me-1 font-weight-bold"
|
||||
aria-label={i18n.t("number_of_points", {
|
||||
aria-label={I18NextService.i18n.t("number_of_points", {
|
||||
count: Number(this.commentView.counts.score),
|
||||
formattedCount: numToSI(
|
||||
this.commentView.counts.score
|
||||
|
@ -426,13 +425,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
onClick={linkEvent(this, this.handleMarkAsRead)}
|
||||
data-tippy-content={
|
||||
this.commentReplyOrMentionRead
|
||||
? i18n.t("mark_as_unread")
|
||||
: i18n.t("mark_as_read")
|
||||
? I18NextService.i18n.t("mark_as_unread")
|
||||
: I18NextService.i18n.t("mark_as_read")
|
||||
}
|
||||
aria-label={
|
||||
this.commentReplyOrMentionRead
|
||||
? i18n.t("mark_as_unread")
|
||||
: i18n.t("mark_as_read")
|
||||
? I18NextService.i18n.t("mark_as_unread")
|
||||
: I18NextService.i18n.t("mark_as_read")
|
||||
}
|
||||
>
|
||||
{this.state.readLoading ? (
|
||||
|
@ -456,8 +455,8 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
: "text-muted"
|
||||
}`}
|
||||
onClick={linkEvent(this, this.handleUpvote)}
|
||||
data-tippy-content={i18n.t("upvote")}
|
||||
aria-label={i18n.t("upvote")}
|
||||
data-tippy-content={I18NextService.i18n.t("upvote")}
|
||||
aria-label={I18NextService.i18n.t("upvote")}
|
||||
aria-pressed={this.commentView.my_vote === 1}
|
||||
>
|
||||
{this.state.upvoteLoading ? (
|
||||
|
@ -483,8 +482,8 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
: "text-muted"
|
||||
}`}
|
||||
onClick={linkEvent(this, this.handleDownvote)}
|
||||
data-tippy-content={i18n.t("downvote")}
|
||||
aria-label={i18n.t("downvote")}
|
||||
data-tippy-content={I18NextService.i18n.t("downvote")}
|
||||
aria-label={I18NextService.i18n.t("downvote")}
|
||||
aria-pressed={this.commentView.my_vote === -1}
|
||||
>
|
||||
{this.state.downvoteLoading ? (
|
||||
|
@ -506,8 +505,8 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
<button
|
||||
className="btn btn-link btn-animate text-muted"
|
||||
onClick={linkEvent(this, this.handleReplyClick)}
|
||||
data-tippy-content={i18n.t("reply")}
|
||||
aria-label={i18n.t("reply")}
|
||||
data-tippy-content={I18NextService.i18n.t("reply")}
|
||||
aria-label={I18NextService.i18n.t("reply")}
|
||||
>
|
||||
<Icon icon="reply1" classes="icon-inline" />
|
||||
</button>
|
||||
|
@ -515,8 +514,8 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
<button
|
||||
className="btn btn-link btn-animate text-muted btn-more"
|
||||
onClick={linkEvent(this, this.handleShowAdvanced)}
|
||||
data-tippy-content={i18n.t("more")}
|
||||
aria-label={i18n.t("more")}
|
||||
data-tippy-content={I18NextService.i18n.t("more")}
|
||||
aria-label={I18NextService.i18n.t("more")}
|
||||
>
|
||||
<Icon icon="more-vertical" classes="icon-inline" />
|
||||
</button>
|
||||
|
@ -527,7 +526,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
<Link
|
||||
className="btn btn-link btn-animate text-muted"
|
||||
to={`/create_private_message/${cv.creator.id}`}
|
||||
title={i18n.t("message").toLowerCase()}
|
||||
title={I18NextService.i18n
|
||||
.t("message")
|
||||
.toLowerCase()}
|
||||
>
|
||||
<Icon icon="mail" />
|
||||
</Link>
|
||||
|
@ -537,10 +538,12 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handleShowReportDialog
|
||||
)}
|
||||
data-tippy-content={i18n.t(
|
||||
data-tippy-content={I18NextService.i18n.t(
|
||||
"show_report_dialog"
|
||||
)}
|
||||
aria-label={I18NextService.i18n.t(
|
||||
"show_report_dialog"
|
||||
)}
|
||||
aria-label={i18n.t("show_report_dialog")}
|
||||
>
|
||||
<Icon icon="flag" />
|
||||
</button>
|
||||
|
@ -550,8 +553,10 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handleBlockPerson
|
||||
)}
|
||||
data-tippy-content={i18n.t("block_user")}
|
||||
aria-label={i18n.t("block_user")}
|
||||
data-tippy-content={I18NextService.i18n.t(
|
||||
"block_user"
|
||||
)}
|
||||
aria-label={I18NextService.i18n.t("block_user")}
|
||||
>
|
||||
{this.state.blockPersonLoading ? (
|
||||
<Spinner />
|
||||
|
@ -565,10 +570,14 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
className="btn btn-link btn-animate text-muted"
|
||||
onClick={linkEvent(this, this.handleSaveComment)}
|
||||
data-tippy-content={
|
||||
cv.saved ? i18n.t("unsave") : i18n.t("save")
|
||||
cv.saved
|
||||
? I18NextService.i18n.t("unsave")
|
||||
: I18NextService.i18n.t("save")
|
||||
}
|
||||
aria-label={
|
||||
cv.saved ? i18n.t("unsave") : i18n.t("save")
|
||||
cv.saved
|
||||
? I18NextService.i18n.t("unsave")
|
||||
: I18NextService.i18n.t("save")
|
||||
}
|
||||
>
|
||||
{this.state.saveLoading ? (
|
||||
|
@ -585,8 +594,10 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
<button
|
||||
className="btn btn-link btn-animate text-muted"
|
||||
onClick={linkEvent(this, this.handleViewSource)}
|
||||
data-tippy-content={i18n.t("view_source")}
|
||||
aria-label={i18n.t("view_source")}
|
||||
data-tippy-content={I18NextService.i18n.t(
|
||||
"view_source"
|
||||
)}
|
||||
aria-label={I18NextService.i18n.t("view_source")}
|
||||
>
|
||||
<Icon
|
||||
icon="file-text"
|
||||
|
@ -600,8 +611,10 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
<button
|
||||
className="btn btn-link btn-animate text-muted"
|
||||
onClick={linkEvent(this, this.handleEditClick)}
|
||||
data-tippy-content={i18n.t("edit")}
|
||||
aria-label={i18n.t("edit")}
|
||||
data-tippy-content={I18NextService.i18n.t(
|
||||
"edit"
|
||||
)}
|
||||
aria-label={I18NextService.i18n.t("edit")}
|
||||
>
|
||||
<Icon icon="edit" classes="icon-inline" />
|
||||
</button>
|
||||
|
@ -613,13 +626,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
)}
|
||||
data-tippy-content={
|
||||
!cv.comment.deleted
|
||||
? i18n.t("delete")
|
||||
: i18n.t("restore")
|
||||
? I18NextService.i18n.t("delete")
|
||||
: I18NextService.i18n.t("restore")
|
||||
}
|
||||
aria-label={
|
||||
!cv.comment.deleted
|
||||
? i18n.t("delete")
|
||||
: i18n.t("restore")
|
||||
? I18NextService.i18n.t("delete")
|
||||
: I18NextService.i18n.t("restore")
|
||||
}
|
||||
>
|
||||
{this.state.deleteLoading ? (
|
||||
|
@ -643,13 +656,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
)}
|
||||
data-tippy-content={
|
||||
!cv.comment.distinguished
|
||||
? i18n.t("distinguish")
|
||||
: i18n.t("undistinguish")
|
||||
? I18NextService.i18n.t("distinguish")
|
||||
: I18NextService.i18n.t("undistinguish")
|
||||
}
|
||||
aria-label={
|
||||
!cv.comment.distinguished
|
||||
? i18n.t("distinguish")
|
||||
: i18n.t("undistinguish")
|
||||
? I18NextService.i18n.t("distinguish")
|
||||
: I18NextService.i18n.t("undistinguish")
|
||||
}
|
||||
>
|
||||
<Icon
|
||||
|
@ -672,9 +685,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handleModRemoveShow
|
||||
)}
|
||||
aria-label={i18n.t("remove")}
|
||||
aria-label={I18NextService.i18n.t("remove")}
|
||||
>
|
||||
{i18n.t("remove")}
|
||||
{I18NextService.i18n.t("remove")}
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
|
@ -683,12 +696,12 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handleRemoveComment
|
||||
)}
|
||||
aria-label={i18n.t("restore")}
|
||||
aria-label={I18NextService.i18n.t("restore")}
|
||||
>
|
||||
{this.state.removeLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
i18n.t("restore")
|
||||
I18NextService.i18n.t("restore")
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
|
@ -705,9 +718,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handleModBanFromCommunityShow
|
||||
)}
|
||||
aria-label={i18n.t("ban_from_community")}
|
||||
aria-label={I18NextService.i18n.t(
|
||||
"ban_from_community"
|
||||
)}
|
||||
>
|
||||
{i18n.t("ban_from_community")}
|
||||
{I18NextService.i18n.t(
|
||||
"ban_from_community"
|
||||
)}
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
|
@ -716,12 +733,12 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handleBanPersonFromCommunity
|
||||
)}
|
||||
aria-label={i18n.t("unban")}
|
||||
aria-label={I18NextService.i18n.t("unban")}
|
||||
>
|
||||
{this.state.banLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
i18n.t("unban")
|
||||
I18NextService.i18n.t("unban")
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
|
@ -735,21 +752,25 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
)}
|
||||
aria-label={
|
||||
isMod_
|
||||
? i18n.t("remove_as_mod")
|
||||
: i18n.t("appoint_as_mod")
|
||||
? I18NextService.i18n.t("remove_as_mod")
|
||||
: I18NextService.i18n.t(
|
||||
"appoint_as_mod"
|
||||
)
|
||||
}
|
||||
>
|
||||
{isMod_
|
||||
? i18n.t("remove_as_mod")
|
||||
: i18n.t("appoint_as_mod")}
|
||||
? I18NextService.i18n.t("remove_as_mod")
|
||||
: I18NextService.i18n.t("appoint_as_mod")}
|
||||
</button>
|
||||
) : (
|
||||
<>
|
||||
<button
|
||||
className="btn btn-link btn-animate text-muted"
|
||||
aria-label={i18n.t("are_you_sure")}
|
||||
aria-label={I18NextService.i18n.t(
|
||||
"are_you_sure"
|
||||
)}
|
||||
>
|
||||
{i18n.t("are_you_sure")}
|
||||
{I18NextService.i18n.t("are_you_sure")}
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-link btn-animate text-muted"
|
||||
|
@ -757,12 +778,12 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handleAddModToCommunity
|
||||
)}
|
||||
aria-label={i18n.t("yes")}
|
||||
aria-label={I18NextService.i18n.t("yes")}
|
||||
>
|
||||
{this.state.addModLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
i18n.t("yes")
|
||||
I18NextService.i18n.t("yes")
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
|
@ -771,9 +792,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handleCancelConfirmAppointAsMod
|
||||
)}
|
||||
aria-label={i18n.t("no")}
|
||||
aria-label={I18NextService.i18n.t("no")}
|
||||
>
|
||||
{i18n.t("no")}
|
||||
{I18NextService.i18n.t("no")}
|
||||
</button>
|
||||
</>
|
||||
))}
|
||||
|
@ -790,17 +811,21 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handleShowConfirmTransferCommunity
|
||||
)}
|
||||
aria-label={i18n.t("transfer_community")}
|
||||
aria-label={I18NextService.i18n.t(
|
||||
"transfer_community"
|
||||
)}
|
||||
>
|
||||
{i18n.t("transfer_community")}
|
||||
{I18NextService.i18n.t("transfer_community")}
|
||||
</button>
|
||||
) : (
|
||||
<>
|
||||
<button
|
||||
className="btn btn-link btn-animate text-muted"
|
||||
aria-label={i18n.t("are_you_sure")}
|
||||
aria-label={I18NextService.i18n.t(
|
||||
"are_you_sure"
|
||||
)}
|
||||
>
|
||||
{i18n.t("are_you_sure")}
|
||||
{I18NextService.i18n.t("are_you_sure")}
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-link btn-animate text-muted"
|
||||
|
@ -808,12 +833,12 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handleTransferCommunity
|
||||
)}
|
||||
aria-label={i18n.t("yes")}
|
||||
aria-label={I18NextService.i18n.t("yes")}
|
||||
>
|
||||
{this.state.transferCommunityLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
i18n.t("yes")
|
||||
I18NextService.i18n.t("yes")
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
|
@ -823,9 +848,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this
|
||||
.handleCancelShowConfirmTransferCommunity
|
||||
)}
|
||||
aria-label={i18n.t("no")}
|
||||
aria-label={I18NextService.i18n.t("no")}
|
||||
>
|
||||
{i18n.t("no")}
|
||||
{I18NextService.i18n.t("no")}
|
||||
</button>
|
||||
</>
|
||||
))}
|
||||
|
@ -840,9 +865,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handlePurgePersonShow
|
||||
)}
|
||||
aria-label={i18n.t("purge_user")}
|
||||
aria-label={I18NextService.i18n.t(
|
||||
"purge_user"
|
||||
)}
|
||||
>
|
||||
{i18n.t("purge_user")}
|
||||
{I18NextService.i18n.t("purge_user")}
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-link btn-animate text-muted"
|
||||
|
@ -850,9 +877,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handlePurgeCommentShow
|
||||
)}
|
||||
aria-label={i18n.t("purge_comment")}
|
||||
aria-label={I18NextService.i18n.t(
|
||||
"purge_comment"
|
||||
)}
|
||||
>
|
||||
{i18n.t("purge_comment")}
|
||||
{I18NextService.i18n.t("purge_comment")}
|
||||
</button>
|
||||
|
||||
{!isBanned(cv.creator) ? (
|
||||
|
@ -862,9 +891,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handleModBanShow
|
||||
)}
|
||||
aria-label={i18n.t("ban_from_site")}
|
||||
aria-label={I18NextService.i18n.t(
|
||||
"ban_from_site"
|
||||
)}
|
||||
>
|
||||
{i18n.t("ban_from_site")}
|
||||
{I18NextService.i18n.t("ban_from_site")}
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
|
@ -873,12 +904,14 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handleBanPerson
|
||||
)}
|
||||
aria-label={i18n.t("unban_from_site")}
|
||||
aria-label={I18NextService.i18n.t(
|
||||
"unban_from_site"
|
||||
)}
|
||||
>
|
||||
{this.state.banLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
i18n.t("unban_from_site")
|
||||
I18NextService.i18n.t("unban_from_site")
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
|
@ -895,18 +928,24 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
)}
|
||||
aria-label={
|
||||
isAdmin_
|
||||
? i18n.t("remove_as_admin")
|
||||
: i18n.t("appoint_as_admin")
|
||||
? I18NextService.i18n.t(
|
||||
"remove_as_admin"
|
||||
)
|
||||
: I18NextService.i18n.t(
|
||||
"appoint_as_admin"
|
||||
)
|
||||
}
|
||||
>
|
||||
{isAdmin_
|
||||
? i18n.t("remove_as_admin")
|
||||
: i18n.t("appoint_as_admin")}
|
||||
? I18NextService.i18n.t("remove_as_admin")
|
||||
: I18NextService.i18n.t(
|
||||
"appoint_as_admin"
|
||||
)}
|
||||
</button>
|
||||
) : (
|
||||
<>
|
||||
<button className="btn btn-link btn-animate text-muted">
|
||||
{i18n.t("are_you_sure")}
|
||||
{I18NextService.i18n.t("are_you_sure")}
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-link btn-animate text-muted"
|
||||
|
@ -914,12 +953,12 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handleAddAdmin
|
||||
)}
|
||||
aria-label={i18n.t("yes")}
|
||||
aria-label={I18NextService.i18n.t("yes")}
|
||||
>
|
||||
{this.state.addAdminLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
i18n.t("yes")
|
||||
I18NextService.i18n.t("yes")
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
|
@ -928,9 +967,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
this,
|
||||
this.handleCancelConfirmAppointAsAdmin
|
||||
)}
|
||||
aria-label={i18n.t("no")}
|
||||
aria-label={I18NextService.i18n.t("no")}
|
||||
>
|
||||
{i18n.t("no")}
|
||||
{I18NextService.i18n.t("no")}
|
||||
</button>
|
||||
</>
|
||||
))}
|
||||
|
@ -961,7 +1000,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
<Spinner />
|
||||
) : (
|
||||
<>
|
||||
{i18n.t("x_more_replies", {
|
||||
{I18NextService.i18n.t("x_more_replies", {
|
||||
count: node.comment_view.counts.child_count,
|
||||
formattedCount: numToSI(
|
||||
node.comment_view.counts.child_count
|
||||
|
@ -983,22 +1022,22 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
className="visually-hidden"
|
||||
htmlFor={`mod-remove-reason-${cv.comment.id}`}
|
||||
>
|
||||
{i18n.t("reason")}
|
||||
{I18NextService.i18n.t("reason")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id={`mod-remove-reason-${cv.comment.id}`}
|
||||
className="form-control me-2"
|
||||
placeholder={i18n.t("reason")}
|
||||
placeholder={I18NextService.i18n.t("reason")}
|
||||
value={this.state.removeReason}
|
||||
onInput={linkEvent(this, this.handleModRemoveReasonChange)}
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-secondary"
|
||||
aria-label={i18n.t("remove_comment")}
|
||||
aria-label={I18NextService.i18n.t("remove_comment")}
|
||||
>
|
||||
{i18n.t("remove_comment")}
|
||||
{I18NextService.i18n.t("remove_comment")}
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
|
@ -1011,23 +1050,23 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
className="visually-hidden"
|
||||
htmlFor={`report-reason-${cv.comment.id}`}
|
||||
>
|
||||
{i18n.t("reason")}
|
||||
{I18NextService.i18n.t("reason")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
required
|
||||
id={`report-reason-${cv.comment.id}`}
|
||||
className="form-control me-2"
|
||||
placeholder={i18n.t("reason")}
|
||||
placeholder={I18NextService.i18n.t("reason")}
|
||||
value={this.state.reportReason}
|
||||
onInput={linkEvent(this, this.handleReportReasonChange)}
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-secondary"
|
||||
aria-label={i18n.t("create_report")}
|
||||
aria-label={I18NextService.i18n.t("create_report")}
|
||||
>
|
||||
{i18n.t("create_report")}
|
||||
{I18NextService.i18n.t("create_report")}
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
|
@ -1038,13 +1077,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
className="col-form-label"
|
||||
htmlFor={`mod-ban-reason-${cv.comment.id}`}
|
||||
>
|
||||
{i18n.t("reason")}
|
||||
{I18NextService.i18n.t("reason")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id={`mod-ban-reason-${cv.comment.id}`}
|
||||
className="form-control me-2"
|
||||
placeholder={i18n.t("reason")}
|
||||
placeholder={I18NextService.i18n.t("reason")}
|
||||
value={this.state.banReason}
|
||||
onInput={linkEvent(this, this.handleModBanReasonChange)}
|
||||
/>
|
||||
|
@ -1052,13 +1091,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
className="col-form-label"
|
||||
htmlFor={`mod-ban-expires-${cv.comment.id}`}
|
||||
>
|
||||
{i18n.t("expires")}
|
||||
{I18NextService.i18n.t("expires")}
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
id={`mod-ban-expires-${cv.comment.id}`}
|
||||
className="form-control me-2"
|
||||
placeholder={i18n.t("number_of_days")}
|
||||
placeholder={I18NextService.i18n.t("number_of_days")}
|
||||
value={this.state.banExpireDays}
|
||||
onInput={linkEvent(this, this.handleModBanExpireDaysChange)}
|
||||
/>
|
||||
|
@ -1074,9 +1113,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
<label
|
||||
className="form-check-label"
|
||||
htmlFor="mod-ban-remove-data"
|
||||
title={i18n.t("remove_content_more")}
|
||||
title={I18NextService.i18n.t("remove_content_more")}
|
||||
>
|
||||
{i18n.t("remove_content")}
|
||||
{I18NextService.i18n.t("remove_content")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1084,19 +1123,19 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
{/* TODO hold off on expires until later */}
|
||||
{/* <div class="mb-3 row"> */}
|
||||
{/* <label class="col-form-label">Expires</label> */}
|
||||
{/* <input type="date" class="form-control me-2" placeholder={i18n.t('expires')} value={this.state.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */}
|
||||
{/* <input type="date" class="form-control me-2" placeholder={I18NextService.i18n.t('expires')} value={this.state.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */}
|
||||
{/* </div> */}
|
||||
<div className="mb-3 row">
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-secondary"
|
||||
aria-label={i18n.t("ban")}
|
||||
aria-label={I18NextService.i18n.t("ban")}
|
||||
>
|
||||
{this.state.banLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
<span>
|
||||
{i18n.t("ban")} {cv.creator.name}
|
||||
{I18NextService.i18n.t("ban")} {cv.creator.name}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
|
@ -1108,13 +1147,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
<form onSubmit={linkEvent(this, this.handlePurgeBothSubmit)}>
|
||||
<PurgeWarning />
|
||||
<label className="visually-hidden" htmlFor="purge-reason">
|
||||
{i18n.t("reason")}
|
||||
{I18NextService.i18n.t("reason")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="purge-reason"
|
||||
className="form-control my-3"
|
||||
placeholder={i18n.t("reason")}
|
||||
placeholder={I18NextService.i18n.t("reason")}
|
||||
value={this.state.purgeReason}
|
||||
onInput={linkEvent(this, this.handlePurgeReasonChange)}
|
||||
/>
|
||||
|
@ -1209,8 +1248,8 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
});
|
||||
|
||||
const title = this.props.showContext
|
||||
? i18n.t("show_context")
|
||||
: i18n.t("link");
|
||||
? I18NextService.i18n.t("show_context")
|
||||
: I18NextService.i18n.t("link");
|
||||
|
||||
// The context button should show the parent comment by default
|
||||
const parentCommentId = getCommentParentId(cv.comment) ?? cv.comment.id;
|
||||
|
@ -1255,17 +1294,17 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
}
|
||||
|
||||
get pointsTippy(): string {
|
||||
const points = i18n.t("number_of_points", {
|
||||
const points = I18NextService.i18n.t("number_of_points", {
|
||||
count: Number(this.commentView.counts.score),
|
||||
formattedCount: numToSI(this.commentView.counts.score),
|
||||
});
|
||||
|
||||
const upvotes = i18n.t("number_of_upvotes", {
|
||||
const upvotes = I18NextService.i18n.t("number_of_upvotes", {
|
||||
count: Number(this.commentView.counts.upvotes),
|
||||
formattedCount: numToSI(this.commentView.counts.upvotes),
|
||||
});
|
||||
|
||||
const downvotes = i18n.t("number_of_downvotes", {
|
||||
const downvotes = I18NextService.i18n.t("number_of_downvotes", {
|
||||
count: Number(this.commentView.counts.downvotes),
|
||||
formattedCount: numToSI(this.commentView.counts.downvotes),
|
||||
});
|
||||
|
@ -1274,15 +1313,17 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
}
|
||||
|
||||
get expandText(): string {
|
||||
return this.state.collapsed ? i18n.t("expand") : i18n.t("collapse");
|
||||
return this.state.collapsed
|
||||
? I18NextService.i18n.t("expand")
|
||||
: I18NextService.i18n.t("collapse");
|
||||
}
|
||||
|
||||
get commentUnlessRemoved(): string {
|
||||
const comment = this.commentView.comment;
|
||||
return comment.removed
|
||||
? `*${i18n.t("removed")}*`
|
||||
? `*${I18NextService.i18n.t("removed")}*`
|
||||
: comment.deleted
|
||||
? `*${i18n.t("deleted")}*`
|
||||
? `*${I18NextService.i18n.t("deleted")}*`
|
||||
: comment.content;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ import {
|
|||
CommentView,
|
||||
ResolveCommentReport,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { CommentNodeI, CommentViewType } from "../../interfaces";
|
||||
import { I18NextService } from "../../services";
|
||||
import { Icon, Spinner } from "../common/icon";
|
||||
import { PersonListing } from "../person/person-listing";
|
||||
import { CommentNode } from "./comment-node";
|
||||
|
@ -43,7 +43,7 @@ export class CommentReport extends Component<
|
|||
render() {
|
||||
const r = this.props.report;
|
||||
const comment = r.comment;
|
||||
const tippyContent = i18n.t(
|
||||
const tippyContent = I18NextService.i18n.t(
|
||||
r.comment_report.resolved ? "unresolve_report" : "resolve_report"
|
||||
);
|
||||
|
||||
|
@ -102,10 +102,11 @@ export class CommentReport extends Component<
|
|||
onEditComment={() => Promise.resolve({ state: "empty" })}
|
||||
/>
|
||||
<div>
|
||||
{i18n.t("reporter")}: <PersonListing person={r.creator} />
|
||||
{I18NextService.i18n.t("reporter")}:{" "}
|
||||
<PersonListing person={r.creator} />
|
||||
</div>
|
||||
<div>
|
||||
{i18n.t("reason")}: {r.comment_report.reason}
|
||||
{I18NextService.i18n.t("reason")}: {r.comment_report.reason}
|
||||
</div>
|
||||
{r.resolver && (
|
||||
<div>
|
||||
|
|
|
@ -5,7 +5,7 @@ import {
|
|||
CommunityId,
|
||||
SiteAggregates,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
|
||||
interface BadgesProps {
|
||||
counts: CommunityAggregates | SiteAggregates;
|
||||
|
@ -29,66 +29,82 @@ export const Badges = ({ counts, communityId }: BadgesProps) => {
|
|||
<ul className="badges my-1 list-inline">
|
||||
<li
|
||||
className="list-inline-item badge text-bg-secondary pointer"
|
||||
data-tippy-content={i18n.t("active_users_in_the_last_day", {
|
||||
data-tippy-content={I18NextService.i18n.t(
|
||||
"active_users_in_the_last_day",
|
||||
{
|
||||
count: Number(counts.users_active_day),
|
||||
formattedCount: numToSI(counts.users_active_day),
|
||||
})}
|
||||
}
|
||||
)}
|
||||
>
|
||||
{i18n.t("number_of_users", {
|
||||
{I18NextService.i18n.t("number_of_users", {
|
||||
count: Number(counts.users_active_day),
|
||||
formattedCount: numToSI(counts.users_active_day),
|
||||
})}{" "}
|
||||
/ {i18n.t("day")}
|
||||
/ {I18NextService.i18n.t("day")}
|
||||
</li>
|
||||
<li
|
||||
className="list-inline-item badge text-bg-secondary pointer"
|
||||
data-tippy-content={i18n.t("active_users_in_the_last_week", {
|
||||
data-tippy-content={I18NextService.i18n.t(
|
||||
"active_users_in_the_last_week",
|
||||
{
|
||||
count: Number(counts.users_active_week),
|
||||
formattedCount: numToSI(counts.users_active_week),
|
||||
})}
|
||||
}
|
||||
)}
|
||||
>
|
||||
{i18n.t("number_of_users", {
|
||||
{I18NextService.i18n.t("number_of_users", {
|
||||
count: Number(counts.users_active_week),
|
||||
formattedCount: numToSI(counts.users_active_week),
|
||||
})}{" "}
|
||||
/ {i18n.t("week")}
|
||||
/ {I18NextService.i18n.t("week")}
|
||||
</li>
|
||||
<li
|
||||
className="list-inline-item badge text-bg-secondary pointer"
|
||||
data-tippy-content={i18n.t("active_users_in_the_last_month", {
|
||||
data-tippy-content={I18NextService.i18n.t(
|
||||
"active_users_in_the_last_month",
|
||||
{
|
||||
count: Number(counts.users_active_month),
|
||||
formattedCount: numToSI(counts.users_active_month),
|
||||
})}
|
||||
}
|
||||
)}
|
||||
>
|
||||
{i18n.t("number_of_users", {
|
||||
{I18NextService.i18n.t("number_of_users", {
|
||||
count: Number(counts.users_active_month),
|
||||
formattedCount: numToSI(counts.users_active_month),
|
||||
})}{" "}
|
||||
/ {i18n.t("month")}
|
||||
/ {I18NextService.i18n.t("month")}
|
||||
</li>
|
||||
<li
|
||||
className="list-inline-item badge text-bg-secondary pointer"
|
||||
data-tippy-content={i18n.t("active_users_in_the_last_six_months", {
|
||||
data-tippy-content={I18NextService.i18n.t(
|
||||
"active_users_in_the_last_six_months",
|
||||
{
|
||||
count: Number(counts.users_active_half_year),
|
||||
formattedCount: numToSI(counts.users_active_half_year),
|
||||
})}
|
||||
}
|
||||
)}
|
||||
>
|
||||
{i18n.t("number_of_users", {
|
||||
{I18NextService.i18n.t("number_of_users", {
|
||||
count: Number(counts.users_active_half_year),
|
||||
formattedCount: numToSI(counts.users_active_half_year),
|
||||
})}{" "}
|
||||
/ {i18n.t("number_of_months", { count: 6, formattedCount: 6 })}
|
||||
/{" "}
|
||||
{I18NextService.i18n.t("number_of_months", {
|
||||
count: 6,
|
||||
formattedCount: 6,
|
||||
})}
|
||||
</li>
|
||||
{isSiteAggregates(counts) && (
|
||||
<>
|
||||
<li className="list-inline-item badge text-bg-secondary">
|
||||
{i18n.t("number_of_users", {
|
||||
{I18NextService.i18n.t("number_of_users", {
|
||||
count: Number(counts.users),
|
||||
formattedCount: numToSI(counts.users),
|
||||
})}
|
||||
</li>
|
||||
<li className="list-inline-item badge text-bg-secondary">
|
||||
{i18n.t("number_of_communities", {
|
||||
{I18NextService.i18n.t("number_of_communities", {
|
||||
count: Number(counts.communities),
|
||||
formattedCount: numToSI(counts.communities),
|
||||
})}
|
||||
|
@ -97,20 +113,20 @@ export const Badges = ({ counts, communityId }: BadgesProps) => {
|
|||
)}
|
||||
{isCommunityAggregates(counts) && (
|
||||
<li className="list-inline-item badge text-bg-secondary">
|
||||
{i18n.t("number_of_subscribers", {
|
||||
{I18NextService.i18n.t("number_of_subscribers", {
|
||||
count: Number(counts.subscribers),
|
||||
formattedCount: numToSI(counts.subscribers),
|
||||
})}
|
||||
</li>
|
||||
)}
|
||||
<li className="list-inline-item badge text-bg-secondary">
|
||||
{i18n.t("number_of_posts", {
|
||||
{I18NextService.i18n.t("number_of_posts", {
|
||||
count: Number(counts.posts),
|
||||
formattedCount: numToSI(counts.posts),
|
||||
})}
|
||||
</li>
|
||||
<li className="list-inline-item badge text-bg-secondary">
|
||||
{i18n.t("number_of_comments", {
|
||||
{I18NextService.i18n.t("number_of_comments", {
|
||||
count: Number(counts.comments),
|
||||
formattedCount: numToSI(counts.comments),
|
||||
})}
|
||||
|
@ -120,7 +136,7 @@ export const Badges = ({ counts, communityId }: BadgesProps) => {
|
|||
className="badge text-bg-primary"
|
||||
to={`/modlog${communityId ? `/${communityId}` : ""}`}
|
||||
>
|
||||
{i18n.t("modlog")}
|
||||
{I18NextService.i18n.t("modlog")}
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -2,7 +2,7 @@ import { randomStr } from "@utils/helpers";
|
|||
import { Component, linkEvent } from "inferno";
|
||||
import { CommentSortType } from "lemmy-js-client";
|
||||
import { relTags, sortingHelpUrl } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { Icon } from "./icon";
|
||||
|
||||
interface CommentSortSelectProps {
|
||||
|
@ -42,21 +42,21 @@ export class CommentSortSelect extends Component<
|
|||
value={this.state.sort}
|
||||
onChange={linkEvent(this, this.handleSortChange)}
|
||||
className="sort-select form-select d-inline-block w-auto me-2 mb-2"
|
||||
aria-label={i18n.t("sort_type")}
|
||||
aria-label={I18NextService.i18n.t("sort_type")}
|
||||
>
|
||||
<option disabled aria-hidden="true">
|
||||
{i18n.t("sort_type")}
|
||||
{I18NextService.i18n.t("sort_type")}
|
||||
</option>
|
||||
<option value={"Hot"}>{i18n.t("hot")}</option>,
|
||||
<option value={"Top"}>{i18n.t("top")}</option>,
|
||||
<option value={"New"}>{i18n.t("new")}</option>
|
||||
<option value={"Old"}>{i18n.t("old")}</option>
|
||||
<option value={"Hot"}>{I18NextService.i18n.t("hot")}</option>,
|
||||
<option value={"Top"}>{I18NextService.i18n.t("top")}</option>,
|
||||
<option value={"New"}>{I18NextService.i18n.t("new")}</option>
|
||||
<option value={"Old"}>{I18NextService.i18n.t("old")}</option>
|
||||
</select>
|
||||
<a
|
||||
className="sort-select-help text-muted"
|
||||
href={sortingHelpUrl}
|
||||
rel={relTags}
|
||||
title={i18n.t("sorting_help")}
|
||||
title={I18NextService.i18n.t("sorting_help")}
|
||||
>
|
||||
<Icon icon="help-circle" classes="icon-inline" />
|
||||
</a>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, linkEvent } from "inferno";
|
||||
import { i18n } from "../../i18next";
|
||||
import { DataType } from "../../interfaces";
|
||||
import { I18NextService } from "../../services";
|
||||
|
||||
interface DataTypeSelectProps {
|
||||
type_: DataType;
|
||||
|
@ -44,7 +44,7 @@ export class DataTypeSelect extends Component<
|
|||
checked={this.state.type_ == DataType.Post}
|
||||
onChange={linkEvent(this, this.handleTypeChange)}
|
||||
/>
|
||||
{i18n.t("posts")}
|
||||
{I18NextService.i18n.t("posts")}
|
||||
</label>
|
||||
<label
|
||||
className={`pointer btn btn-outline-secondary ${
|
||||
|
@ -58,7 +58,7 @@ export class DataTypeSelect extends Component<
|
|||
checked={this.state.type_ == DataType.Comment}
|
||||
onChange={linkEvent(this, this.handleTypeChange)}
|
||||
/>
|
||||
{i18n.t("comments")}
|
||||
{I18NextService.i18n.t("comments")}
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, linkEvent } from "inferno";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { EmojiMart } from "./emoji-mart";
|
||||
import { Icon } from "./icon";
|
||||
|
||||
|
@ -28,8 +28,8 @@ export class EmojiPicker extends Component<EmojiPickerProps, EmojiPickerState> {
|
|||
<span className="emoji-picker">
|
||||
<button
|
||||
className="btn btn-sm text-muted"
|
||||
data-tippy-content={i18n.t("emoji")}
|
||||
aria-label={i18n.t("emoji")}
|
||||
data-tippy-content={I18NextService.i18n.t("emoji")}
|
||||
aria-label={I18NextService.i18n.t("emoji")}
|
||||
disabled={this.props.disabled}
|
||||
onClick={linkEvent(this, this.togglePicker)}
|
||||
>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { httpExternalPath } from "@utils/env";
|
||||
import { htmlToText } from "html-to-text";
|
||||
import { Component } from "inferno";
|
||||
import { Helmet } from "inferno-helmet";
|
||||
import { httpExternalPath } from "../../env";
|
||||
import { i18n } from "../../i18next";
|
||||
import { md } from "../../markdown";
|
||||
import { I18NextService } from "../../services";
|
||||
|
||||
interface HtmlTagsProps {
|
||||
title: string;
|
||||
|
@ -21,7 +21,7 @@ export class HtmlTags extends Component<HtmlTagsProps, any> {
|
|||
|
||||
return (
|
||||
<Helmet title={this.props.title}>
|
||||
<html lang={i18n.resolvedLanguage} />
|
||||
<html lang={I18NextService.i18n.resolvedLanguage} />
|
||||
|
||||
{["title", "og:title", "twitter:title"].map(t => (
|
||||
<meta key={t} property={t} content={this.props.title} />
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import classNames from "classnames";
|
||||
import { Component } from "inferno";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
|
||||
interface IconProps {
|
||||
icon: string;
|
||||
|
@ -61,7 +61,7 @@ export class PurgeWarning extends Component<any, any> {
|
|||
return (
|
||||
<div className="purge-warning mt-2 alert alert-danger" role="alert">
|
||||
<Icon icon="alert-triangle" classes="icon-inline me-2" />
|
||||
{i18n.t("purge_warning")}
|
||||
{I18NextService.i18n.t("purge_warning")}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { randomStr } from "@utils/helpers";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import { i18n } from "../../i18next";
|
||||
import { HttpService, UserService } from "../../services";
|
||||
import { HttpService, I18NextService, UserService } from "../../services";
|
||||
import { toast } from "../../toast";
|
||||
import { Icon } from "./icon";
|
||||
|
||||
|
@ -50,7 +49,7 @@ export class ImageUploadForm extends Component<
|
|||
/>
|
||||
<a
|
||||
onClick={linkEvent(this, this.handleRemoveImage)}
|
||||
aria-label={i18n.t("remove")}
|
||||
aria-label={I18NextService.i18n.t("remove")}
|
||||
>
|
||||
<Icon icon="x" classes="mini-overlay" />
|
||||
</a>
|
||||
|
|
|
@ -3,8 +3,7 @@ import { randomStr } from "@utils/helpers";
|
|||
import classNames from "classnames";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import { Language } from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { UserService } from "../../services/UserService";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { Icon } from "./icon";
|
||||
|
||||
interface LanguageSelectProps {
|
||||
|
@ -53,7 +52,7 @@ export class LanguageSelect extends Component<LanguageSelectProps, any> {
|
|||
<div className="language-select">
|
||||
{this.props.multiple && this.props.showLanguageWarning && (
|
||||
<div className="alert alert-warning" role="alert">
|
||||
{i18n.t("undetermined_language_warning")}
|
||||
{I18NextService.i18n.t("undetermined_language_warning")}
|
||||
</div>
|
||||
)}
|
||||
<div className="mb-3 row">
|
||||
|
@ -64,7 +63,9 @@ export class LanguageSelect extends Component<LanguageSelectProps, any> {
|
|||
)}
|
||||
htmlFor={this.id}
|
||||
>
|
||||
{i18n.t(this.props.multiple ? "language_plural" : "language")}
|
||||
{I18NextService.i18n.t(
|
||||
this.props.multiple ? "language_plural" : "language"
|
||||
)}
|
||||
</label>
|
||||
<div
|
||||
className={classNames(`col-sm-${this.props.multiple ? 9 : 10}`, {
|
||||
|
@ -103,13 +104,13 @@ export class LanguageSelect extends Component<LanguageSelectProps, any> {
|
|||
})}
|
||||
id={this.id}
|
||||
onChange={linkEvent(this, this.handleLanguageChange)}
|
||||
aria-label={i18n.t("language_select_placeholder")}
|
||||
aria-label={I18NextService.i18n.t("language_select_placeholder")}
|
||||
multiple={this.props.multiple}
|
||||
disabled={this.props.disabled}
|
||||
>
|
||||
{!this.props.multiple && (
|
||||
<option selected disabled hidden>
|
||||
{i18n.t("language_select_placeholder")}
|
||||
{I18NextService.i18n.t("language_select_placeholder")}
|
||||
</option>
|
||||
)}
|
||||
{filteredLangs.map(l => (
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { randomStr } from "@utils/helpers";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import { ListingType } from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
|
||||
interface ListingTypeSelectProps {
|
||||
type_: ListingType;
|
||||
|
@ -42,7 +41,7 @@ export class ListingTypeSelect extends Component<
|
|||
<div className="listing-type-select btn-group btn-group-toggle flex-wrap">
|
||||
{this.props.showSubscribed && (
|
||||
<label
|
||||
title={i18n.t("subscribed_description")}
|
||||
title={I18NextService.i18n.t("subscribed_description")}
|
||||
className={`btn btn-outline-secondary
|
||||
${this.state.type_ == "Subscribed" && "active"}
|
||||
${!UserService.Instance.myUserInfo ? "disabled" : "pointer"}
|
||||
|
@ -57,12 +56,12 @@ export class ListingTypeSelect extends Component<
|
|||
onChange={linkEvent(this, this.handleTypeChange)}
|
||||
disabled={!UserService.Instance.myUserInfo}
|
||||
/>
|
||||
{i18n.t("subscribed")}
|
||||
{I18NextService.i18n.t("subscribed")}
|
||||
</label>
|
||||
)}
|
||||
{this.props.showLocal && (
|
||||
<label
|
||||
title={i18n.t("local_description")}
|
||||
title={I18NextService.i18n.t("local_description")}
|
||||
className={`pointer btn btn-outline-secondary ${
|
||||
this.state.type_ == "Local" && "active"
|
||||
}`}
|
||||
|
@ -75,11 +74,11 @@ export class ListingTypeSelect extends Component<
|
|||
checked={this.state.type_ == "Local"}
|
||||
onChange={linkEvent(this, this.handleTypeChange)}
|
||||
/>
|
||||
{i18n.t("local")}
|
||||
{I18NextService.i18n.t("local")}
|
||||
</label>
|
||||
)}
|
||||
<label
|
||||
title={i18n.t("all_description")}
|
||||
title={I18NextService.i18n.t("all_description")}
|
||||
className={`pointer btn btn-outline-secondary ${
|
||||
(this.state.type_ == "All" && "active") ||
|
||||
(!this.props.showLocal && this.state.type_ == "Local" && "active")
|
||||
|
@ -93,7 +92,7 @@ export class ListingTypeSelect extends Component<
|
|||
checked={this.state.type_ == "All"}
|
||||
onChange={linkEvent(this, this.handleTypeChange)}
|
||||
/>
|
||||
{i18n.t("all")}
|
||||
{I18NextService.i18n.t("all")}
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -12,9 +12,8 @@ import {
|
|||
maxUploadImages,
|
||||
relTags,
|
||||
} from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import { customEmojisLookup, mdToHtml, setupTribute } from "../../markdown";
|
||||
import { HttpService, UserService } from "../../services";
|
||||
import { HttpService, I18NextService, UserService } from "../../services";
|
||||
import { setupTippy } from "../../tippy";
|
||||
import { pictrsDeleteToast, toast } from "../../toast";
|
||||
import { EmojiPicker } from "./emoji-picker";
|
||||
|
@ -129,7 +128,7 @@ export class MarkdownTextArea extends Component<
|
|||
// TODO add these prompts back in at some point
|
||||
// <Prompt
|
||||
// when={!this.props.hideNavigationWarnings && this.state.content}
|
||||
// message={i18n.t("block_leaving")}
|
||||
// message={I18NextService.i18n.t("block_leaving")}
|
||||
// />
|
||||
return (
|
||||
<form
|
||||
|
@ -161,7 +160,7 @@ export class MarkdownTextArea extends Component<
|
|||
className={`mb-0 ${
|
||||
UserService.Instance.myUserInfo && "pointer"
|
||||
}`}
|
||||
data-tippy-content={i18n.t("upload_image")}
|
||||
data-tippy-content={I18NextService.i18n.t("upload_image")}
|
||||
>
|
||||
{this.state.imageUploadStatus ? (
|
||||
<Spinner />
|
||||
|
@ -199,7 +198,7 @@ export class MarkdownTextArea extends Component<
|
|||
<a
|
||||
href={markdownHelpUrl}
|
||||
className="btn btn-sm text-muted font-weight-bold"
|
||||
title={i18n.t("formatting_help")}
|
||||
title={I18NextService.i18n.t("formatting_help")}
|
||||
rel={relTags}
|
||||
>
|
||||
<Icon icon="help-circle" classes="icon-inline" />
|
||||
|
@ -241,15 +240,17 @@ export class MarkdownTextArea extends Component<
|
|||
animated
|
||||
value={this.state.imageUploadStatus.uploaded}
|
||||
max={this.state.imageUploadStatus.total}
|
||||
text={i18n.t("pictures_uploded_progess", {
|
||||
text={
|
||||
I18NextService.i18n.t("pictures_uploded_progess", {
|
||||
uploaded: this.state.imageUploadStatus.uploaded,
|
||||
total: this.state.imageUploadStatus.total,
|
||||
})}
|
||||
}) ?? undefined
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<label className="visually-hidden" htmlFor={this.id}>
|
||||
{i18n.t("body")}
|
||||
{I18NextService.i18n.t("body")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -290,7 +291,7 @@ export class MarkdownTextArea extends Component<
|
|||
className="btn btn-sm btn-secondary ms-2"
|
||||
onClick={linkEvent(this, this.handleReplyCancel)}
|
||||
>
|
||||
{i18n.t("cancel")}
|
||||
{I18NextService.i18n.t("cancel")}
|
||||
</button>
|
||||
)}
|
||||
{this.state.content && (
|
||||
|
@ -300,7 +301,9 @@ export class MarkdownTextArea extends Component<
|
|||
}`}
|
||||
onClick={linkEvent(this, this.handlePreviewToggle)}
|
||||
>
|
||||
{this.state.previewMode ? i18n.t("edit") : i18n.t("preview")}
|
||||
{this.state.previewMode
|
||||
? I18NextService.i18n.t("edit")
|
||||
: I18NextService.i18n.t("preview")}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
@ -332,8 +335,8 @@ export class MarkdownTextArea extends Component<
|
|||
return (
|
||||
<button
|
||||
className="btn btn-sm text-muted"
|
||||
data-tippy-content={i18n.t(type)}
|
||||
aria-label={i18n.t(type)}
|
||||
data-tippy-content={I18NextService.i18n.t(type)}
|
||||
aria-label={I18NextService.i18n.t(type)}
|
||||
onClick={linkEvent(this, handleClick)}
|
||||
disabled={this.isDisabled}
|
||||
>
|
||||
|
@ -376,7 +379,7 @@ export class MarkdownTextArea extends Component<
|
|||
|
||||
if (files.length > maxUploadImages) {
|
||||
toast(
|
||||
i18n.t("too_many_images_upload", {
|
||||
I18NextService.i18n.t("too_many_images_upload", {
|
||||
count: Number(maxUploadImages),
|
||||
formattedCount: numToSI(maxUploadImages),
|
||||
}),
|
||||
|
@ -677,7 +680,7 @@ export class MarkdownTextArea extends Component<
|
|||
|
||||
handleInsertSpoiler(i: MarkdownTextArea, event: any) {
|
||||
event.preventDefault();
|
||||
const beforeChars = `\n::: spoiler ${i18n.t("spoiler")}\n`;
|
||||
const beforeChars = `\n::: spoiler ${I18NextService.i18n.t("spoiler")}\n`;
|
||||
const afterChars = "\n:::\n";
|
||||
i.simpleSurroundBeforeAfter(beforeChars, afterChars);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { capitalizeFirstLetter } from "@utils/helpers";
|
||||
import { Component } from "inferno";
|
||||
import moment from "moment";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { Icon } from "./icon";
|
||||
|
||||
interface MomentTimeProps {
|
||||
|
@ -15,18 +15,18 @@ export class MomentTime extends Component<MomentTimeProps, any> {
|
|||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
|
||||
moment.locale([...i18n.languages]);
|
||||
moment.locale([...I18NextService.i18n.languages]);
|
||||
}
|
||||
|
||||
createdAndModifiedTimes() {
|
||||
const updated = this.props.updated;
|
||||
let line = `${capitalizeFirstLetter(i18n.t("created"))}: ${this.format(
|
||||
this.props.published
|
||||
)}`;
|
||||
let line = `${capitalizeFirstLetter(
|
||||
I18NextService.i18n.t("created")
|
||||
)}: ${this.format(this.props.published)}`;
|
||||
if (updated) {
|
||||
line += `\n\n\n${capitalizeFirstLetter(i18n.t("modified"))} ${this.format(
|
||||
updated
|
||||
)}`;
|
||||
line += `\n\n\n${capitalizeFirstLetter(
|
||||
I18NextService.i18n.t("modified")
|
||||
)} ${this.format(updated)}`;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component } from "inferno";
|
||||
import { i18n } from "../../../shared/i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
|
||||
export interface IPromptProps {
|
||||
when: boolean;
|
||||
|
@ -14,7 +14,7 @@ export default class NavigationPrompt extends Component<IPromptProps, any> {
|
|||
}
|
||||
|
||||
this.unblock = this.context.router.history.block(tx => {
|
||||
if (window.confirm(i18n.t("block_leaving"))) {
|
||||
if (window.confirm(I18NextService.i18n.t("block_leaving") ?? undefined)) {
|
||||
this.unblock();
|
||||
tx.retry();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, linkEvent } from "inferno";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
|
||||
interface PaginatorProps {
|
||||
page: number;
|
||||
|
@ -18,13 +18,13 @@ export class Paginator extends Component<PaginatorProps, any> {
|
|||
disabled={this.props.page == 1}
|
||||
onClick={linkEvent(this, this.handlePrev)}
|
||||
>
|
||||
{i18n.t("prev")}
|
||||
{I18NextService.i18n.t("prev")}
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-secondary"
|
||||
onClick={linkEvent(this, this.handleNext)}
|
||||
>
|
||||
{i18n.t("next")}
|
||||
{I18NextService.i18n.t("next")}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -22,7 +22,7 @@ export class PictrsImage extends Component<PictrsImageProps, any> {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<picture className="pictrs-image d-inline-block overflow-hidden">
|
||||
<picture>
|
||||
<source srcSet={this.src("webp")} type="image/webp" />
|
||||
<source srcSet={this.props.src} />
|
||||
<source srcSet={this.src("jpg")} type="image/jpeg" />
|
||||
|
@ -31,7 +31,7 @@ export class PictrsImage extends Component<PictrsImageProps, any> {
|
|||
alt={this.alt()}
|
||||
title={this.alt()}
|
||||
loading="lazy"
|
||||
className={classNames({
|
||||
className={classNames("overflow-hidden pictrs-image", {
|
||||
"img-fluid": !this.props.icon && !this.props.iconOverlay,
|
||||
banner: this.props.banner,
|
||||
"thumbnail rounded":
|
||||
|
|
|
@ -5,8 +5,8 @@ import {
|
|||
ApproveRegistrationApplication,
|
||||
RegistrationApplicationView,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { mdToHtml } from "../../markdown";
|
||||
import { I18NextService } from "../../services";
|
||||
import { PersonListing } from "../person/person-listing";
|
||||
import { Spinner } from "./icon";
|
||||
import { MarkdownTextArea } from "./markdown-textarea";
|
||||
|
@ -61,12 +61,14 @@ export class RegistrationApplication extends Component<
|
|||
return (
|
||||
<div className="registration-application">
|
||||
<div>
|
||||
{i18n.t("applicant")}: <PersonListing person={a.creator} />
|
||||
{I18NextService.i18n.t("applicant")}:{" "}
|
||||
<PersonListing person={a.creator} />
|
||||
</div>
|
||||
<div>
|
||||
{i18n.t("created")}: <MomentTime showAgo published={ra.published} />
|
||||
{I18NextService.i18n.t("created")}:{" "}
|
||||
<MomentTime showAgo published={ra.published} />
|
||||
</div>
|
||||
<div>{i18n.t("answer")}:</div>
|
||||
<div>{I18NextService.i18n.t("answer")}:</div>
|
||||
<div className="md-div" dangerouslySetInnerHTML={mdToHtml(ra.answer)} />
|
||||
|
||||
{a.admin && (
|
||||
|
@ -84,7 +86,7 @@ export class RegistrationApplication extends Component<
|
|||
</T>
|
||||
{ra.deny_reason && (
|
||||
<div>
|
||||
{i18n.t("deny_reason")}:{" "}
|
||||
{I18NextService.i18n.t("deny_reason")}:{" "}
|
||||
<div
|
||||
className="md-div d-inline-flex"
|
||||
dangerouslySetInnerHTML={mdToHtml(ra.deny_reason)}
|
||||
|
@ -99,7 +101,7 @@ export class RegistrationApplication extends Component<
|
|||
{this.state.denyExpanded && (
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2 col-form-label">
|
||||
{i18n.t("deny_reason")}
|
||||
{I18NextService.i18n.t("deny_reason")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<MarkdownTextArea
|
||||
|
@ -116,18 +118,26 @@ export class RegistrationApplication extends Component<
|
|||
<button
|
||||
className="btn btn-secondary me-2 my-2"
|
||||
onClick={linkEvent(this, this.handleApprove)}
|
||||
aria-label={i18n.t("approve")}
|
||||
aria-label={I18NextService.i18n.t("approve")}
|
||||
>
|
||||
{this.state.approveLoading ? <Spinner /> : i18n.t("approve")}
|
||||
{this.state.approveLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
I18NextService.i18n.t("approve")
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
{(!ra.admin_id || (ra.admin_id && accepted)) && (
|
||||
<button
|
||||
className="btn btn-secondary me-2"
|
||||
onClick={linkEvent(this, this.handleDeny)}
|
||||
aria-label={i18n.t("deny")}
|
||||
aria-label={I18NextService.i18n.t("deny")}
|
||||
>
|
||||
{this.state.denyLoading ? <Spinner /> : i18n.t("deny")}
|
||||
{this.state.denyLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
I18NextService.i18n.t("deny")
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
linkEvent,
|
||||
RefObject,
|
||||
} from "inferno";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { Icon, Spinner } from "./icon";
|
||||
|
||||
interface SearchableSelectProps {
|
||||
|
@ -113,7 +113,7 @@ export class SearchableSelect extends Component<
|
|||
ref={this.toggleButtonRef}
|
||||
>
|
||||
{loading
|
||||
? `${i18n.t("loading")}${loadingEllipses}`
|
||||
? `${I18NextService.i18n.t("loading")}${loadingEllipses}`
|
||||
: options[selectedIndex].label}
|
||||
</button>
|
||||
<div
|
||||
|
@ -131,7 +131,7 @@ export class SearchableSelect extends Component<
|
|||
ref={this.searchInputRef}
|
||||
onInput={linkEvent(this, handleSearch)}
|
||||
value={searchText}
|
||||
placeholder={`${i18n.t("search")}...`}
|
||||
placeholder={`${I18NextService.i18n.t("search")}...`}
|
||||
/>
|
||||
</div>
|
||||
{!loading &&
|
||||
|
|
|
@ -2,7 +2,7 @@ import { randomStr } from "@utils/helpers";
|
|||
import { Component, linkEvent } from "inferno";
|
||||
import { SortType } from "lemmy-js-client";
|
||||
import { relTags, sortingHelpUrl } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { Icon } from "./icon";
|
||||
|
||||
interface SortSelectProps {
|
||||
|
@ -41,43 +41,52 @@ export class SortSelect extends Component<SortSelectProps, SortSelectState> {
|
|||
value={this.state.sort}
|
||||
onChange={linkEvent(this, this.handleSortChange)}
|
||||
className="sort-select form-select d-inline-block w-auto me-2"
|
||||
aria-label={i18n.t("sort_type")}
|
||||
aria-label={I18NextService.i18n.t("sort_type")}
|
||||
>
|
||||
<option disabled aria-hidden="true">
|
||||
{i18n.t("sort_type")}
|
||||
{I18NextService.i18n.t("sort_type")}
|
||||
</option>
|
||||
{!this.props.hideHot && [
|
||||
<option key={"Hot"} value={"Hot"}>
|
||||
{i18n.t("hot")}
|
||||
{I18NextService.i18n.t("hot")}
|
||||
</option>,
|
||||
<option key={"Active"} value={"Active"}>
|
||||
{i18n.t("active")}
|
||||
{I18NextService.i18n.t("active")}
|
||||
</option>,
|
||||
]}
|
||||
<option value={"New"}>{i18n.t("new")}</option>
|
||||
<option value={"Old"}>{i18n.t("old")}</option>
|
||||
<option value={"New"}>{I18NextService.i18n.t("new")}</option>
|
||||
<option value={"Old"}>{I18NextService.i18n.t("old")}</option>
|
||||
{!this.props.hideMostComments && [
|
||||
<option key={"MostComments"} value={"MostComments"}>
|
||||
{i18n.t("most_comments")}
|
||||
{I18NextService.i18n.t("most_comments")}
|
||||
</option>,
|
||||
<option key={"NewComments"} value={"NewComments"}>
|
||||
{i18n.t("new_comments")}
|
||||
{I18NextService.i18n.t("new_comments")}
|
||||
</option>,
|
||||
]}
|
||||
<option disabled aria-hidden="true">
|
||||
─────
|
||||
</option>
|
||||
<option value={"TopDay"}>{i18n.t("top_day")}</option>
|
||||
<option value={"TopWeek"}>{i18n.t("top_week")}</option>
|
||||
<option value={"TopMonth"}>{i18n.t("top_month")}</option>
|
||||
<option value={"TopYear"}>{i18n.t("top_year")}</option>
|
||||
<option value={"TopAll"}>{i18n.t("top_all")}</option>
|
||||
<option value={"TopHour"}>{I18NextService.i18n.t("top_hour")}</option>
|
||||
<option value={"TopSixHour"}>
|
||||
{I18NextService.i18n.t("top_six_hours")}
|
||||
</option>
|
||||
<option value={"TopTwelveHour"}>
|
||||
{I18NextService.i18n.t("top_twelve_hours")}
|
||||
</option>
|
||||
<option value={"TopDay"}>{I18NextService.i18n.t("top_day")}</option>
|
||||
<option value={"TopWeek"}>{I18NextService.i18n.t("top_week")}</option>
|
||||
<option value={"TopMonth"}>
|
||||
{I18NextService.i18n.t("top_month")}
|
||||
</option>
|
||||
<option value={"TopYear"}>{I18NextService.i18n.t("top_year")}</option>
|
||||
<option value={"TopAll"}>{I18NextService.i18n.t("top_all")}</option>
|
||||
</select>
|
||||
<a
|
||||
className="sort-select-icon text-muted"
|
||||
href={sortingHelpUrl}
|
||||
rel={relTags}
|
||||
title={i18n.t("sorting_help")}
|
||||
title={I18NextService.i18n.t("sorting_help")}
|
||||
>
|
||||
<Icon icon="help-circle" classes="icon-inline" />
|
||||
</a>
|
||||
|
|
|
@ -21,9 +21,8 @@ import {
|
|||
ListCommunitiesResponse,
|
||||
ListingType,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { InitialFetchRequest } from "../../interfaces";
|
||||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import { FirstLoadService, I18NextService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
import { Spinner } from "../common/icon";
|
||||
|
@ -86,7 +85,7 @@ export class Communities extends Component<any, CommunitiesState> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
return `${i18n.t("communities")} - ${
|
||||
return `${I18NextService.i18n.t("communities")} - ${
|
||||
this.state.siteRes.site_view.site.name
|
||||
}`;
|
||||
}
|
||||
|
@ -103,7 +102,9 @@ export class Communities extends Component<any, CommunitiesState> {
|
|||
const { listingType, page } = this.getCommunitiesQueryParams();
|
||||
return (
|
||||
<div>
|
||||
<h1 className="h4">{i18n.t("list_of_communities")}</h1>
|
||||
<h1 className="h4">
|
||||
{I18NextService.i18n.t("list_of_communities")}
|
||||
</h1>
|
||||
<div className="row g-2 justify-content-between">
|
||||
<div className="col-auto">
|
||||
<ListingTypeSelect
|
||||
|
@ -123,16 +124,19 @@ export class Communities extends Component<any, CommunitiesState> {
|
|||
>
|
||||
<thead className="pointer">
|
||||
<tr>
|
||||
<th>{i18n.t("name")}</th>
|
||||
<th className="text-right">{i18n.t("subscribers")}</th>
|
||||
<th>{I18NextService.i18n.t("name")}</th>
|
||||
<th className="text-right">
|
||||
{i18n.t("users")} / {i18n.t("month")}
|
||||
{I18NextService.i18n.t("subscribers")}
|
||||
</th>
|
||||
<th className="text-right">
|
||||
{I18NextService.i18n.t("users")} /{" "}
|
||||
{I18NextService.i18n.t("month")}
|
||||
</th>
|
||||
<th className="text-right d-none d-lg-table-cell">
|
||||
{i18n.t("posts")}
|
||||
{I18NextService.i18n.t("posts")}
|
||||
</th>
|
||||
<th className="text-right d-none d-lg-table-cell">
|
||||
{i18n.t("comments")}
|
||||
{I18NextService.i18n.t("comments")}
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
@ -169,7 +173,7 @@ export class Communities extends Component<any, CommunitiesState> {
|
|||
this.handleFollow
|
||||
)}
|
||||
>
|
||||
{i18n.t("unsubscribe")}
|
||||
{I18NextService.i18n.t("unsubscribe")}
|
||||
</button>
|
||||
)}
|
||||
{cv.subscribed === "NotSubscribed" && (
|
||||
|
@ -184,12 +188,12 @@ export class Communities extends Component<any, CommunitiesState> {
|
|||
this.handleFollow
|
||||
)}
|
||||
>
|
||||
{i18n.t("subscribe")}
|
||||
{I18NextService.i18n.t("subscribe")}
|
||||
</button>
|
||||
)}
|
||||
{cv.subscribed === "Pending" && (
|
||||
<div className="text-warning d-inline-block">
|
||||
{i18n.t("subscribe_pending")}
|
||||
{I18NextService.i18n.t("subscribe_pending")}
|
||||
</div>
|
||||
)}
|
||||
</td>
|
||||
|
@ -230,7 +234,7 @@ export class Communities extends Component<any, CommunitiesState> {
|
|||
id="communities-search"
|
||||
className="form-control"
|
||||
value={this.state.searchText}
|
||||
placeholder={`${i18n.t("search")}...`}
|
||||
placeholder={`${I18NextService.i18n.t("search")}...`}
|
||||
onInput={linkEvent(this, this.handleSearchChange)}
|
||||
required
|
||||
minLength={3}
|
||||
|
@ -238,10 +242,10 @@ export class Communities extends Component<any, CommunitiesState> {
|
|||
</div>
|
||||
<div className="col-auto">
|
||||
<label className="visually-hidden" htmlFor="communities-search">
|
||||
{i18n.t("search")}
|
||||
{I18NextService.i18n.t("search")}
|
||||
</label>
|
||||
<button type="submit" className="btn btn-secondary">
|
||||
<span>{i18n.t("search")}</span>
|
||||
<span>{I18NextService.i18n.t("search")}</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
EditCommunity,
|
||||
Language,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { Icon, Spinner } from "../common/icon";
|
||||
import { ImageUploadForm } from "../common/image-upload-form";
|
||||
import { LanguageSelect } from "../common/language-select";
|
||||
|
@ -107,10 +107,10 @@ export class CommunityForm extends Component<
|
|||
className="col-12 col-sm-2 col-form-label"
|
||||
htmlFor="community-name"
|
||||
>
|
||||
{i18n.t("name")}
|
||||
{I18NextService.i18n.t("name")}
|
||||
<span
|
||||
className="position-absolute pointer unselectable ms-2 text-muted"
|
||||
data-tippy-content={i18n.t("name_explain")}
|
||||
data-tippy-content={I18NextService.i18n.t("name_explain")}
|
||||
>
|
||||
<Icon icon="help-circle" classes="icon-inline" />
|
||||
</span>
|
||||
|
@ -125,7 +125,7 @@ export class CommunityForm extends Component<
|
|||
required
|
||||
minLength={3}
|
||||
pattern="[a-z0-9_]+"
|
||||
title={i18n.t("community_reqs")}
|
||||
title={I18NextService.i18n.t("community_reqs")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -135,10 +135,10 @@ export class CommunityForm extends Component<
|
|||
className="col-12 col-sm-2 col-form-label"
|
||||
htmlFor="community-title"
|
||||
>
|
||||
{i18n.t("display_name")}
|
||||
{I18NextService.i18n.t("display_name")}
|
||||
<span
|
||||
className="position-absolute pointer unselectable ms-2 text-muted"
|
||||
data-tippy-content={i18n.t("display_name_explain")}
|
||||
data-tippy-content={I18NextService.i18n.t("display_name_explain")}
|
||||
>
|
||||
<Icon icon="help-circle" classes="icon-inline" />
|
||||
</span>
|
||||
|
@ -158,11 +158,11 @@ export class CommunityForm extends Component<
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-12 col-sm-2 col-form-label">
|
||||
{i18n.t("icon")}
|
||||
{I18NextService.i18n.t("icon")}
|
||||
</label>
|
||||
<div className="col-12 col-sm-10">
|
||||
<ImageUploadForm
|
||||
uploadTitle={i18n.t("upload_icon")}
|
||||
uploadTitle={I18NextService.i18n.t("upload_icon")}
|
||||
imageSrc={this.state.form.icon}
|
||||
onUpload={this.handleIconUpload}
|
||||
onRemove={this.handleIconRemove}
|
||||
|
@ -172,11 +172,11 @@ export class CommunityForm extends Component<
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-12 col-sm-2 col-form-label">
|
||||
{i18n.t("banner")}
|
||||
{I18NextService.i18n.t("banner")}
|
||||
</label>
|
||||
<div className="col-12 col-sm-10">
|
||||
<ImageUploadForm
|
||||
uploadTitle={i18n.t("upload_banner")}
|
||||
uploadTitle={I18NextService.i18n.t("upload_banner")}
|
||||
imageSrc={this.state.form.banner}
|
||||
onUpload={this.handleBannerUpload}
|
||||
onRemove={this.handleBannerRemove}
|
||||
|
@ -185,12 +185,12 @@ export class CommunityForm extends Component<
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-12 col-sm-2 col-form-label" htmlFor={this.id}>
|
||||
{i18n.t("sidebar")}
|
||||
{I18NextService.i18n.t("sidebar")}
|
||||
</label>
|
||||
<div className="col-12 col-sm-10">
|
||||
<MarkdownTextArea
|
||||
initialContent={this.state.form.description}
|
||||
placeholder={i18n.t("description")}
|
||||
placeholder={I18NextService.i18n.t("description") ?? undefined}
|
||||
onContentChange={this.handleCommunityDescriptionChange}
|
||||
hideNavigationWarnings
|
||||
allLanguages={[]}
|
||||
|
@ -202,7 +202,7 @@ export class CommunityForm extends Component<
|
|||
{this.props.enableNsfw && (
|
||||
<div className="mb-3 row">
|
||||
<legend className="col-form-label col-sm-2 pt-0">
|
||||
{i18n.t("nsfw")}
|
||||
{I18NextService.i18n.t("nsfw")}
|
||||
</legend>
|
||||
<div className="col-10">
|
||||
<div className="form-check">
|
||||
|
@ -219,7 +219,7 @@ export class CommunityForm extends Component<
|
|||
)}
|
||||
<div className="mb-3 row">
|
||||
<legend className="col-form-label col-6 pt-0">
|
||||
{i18n.t("only_mods_can_post_in_community")}
|
||||
{I18NextService.i18n.t("only_mods_can_post_in_community")}
|
||||
</legend>
|
||||
<div className="col-6">
|
||||
<div className="form-check">
|
||||
|
@ -254,9 +254,9 @@ export class CommunityForm extends Component<
|
|||
{this.props.loading ? (
|
||||
<Spinner />
|
||||
) : this.props.community_view ? (
|
||||
capitalizeFirstLetter(i18n.t("save"))
|
||||
capitalizeFirstLetter(I18NextService.i18n.t("save"))
|
||||
) : (
|
||||
capitalizeFirstLetter(i18n.t("create"))
|
||||
capitalizeFirstLetter(I18NextService.i18n.t("create"))
|
||||
)}
|
||||
</button>
|
||||
{this.props.community_view && (
|
||||
|
@ -265,7 +265,7 @@ export class CommunityForm extends Component<
|
|||
className="btn btn-secondary"
|
||||
onClick={linkEvent(this, this.handleCancel)}
|
||||
>
|
||||
{i18n.t("cancel")}
|
||||
{I18NextService.i18n.t("cancel")}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -15,7 +15,6 @@ import {
|
|||
updateCommunityBlock,
|
||||
updatePersonBlock,
|
||||
} from "@utils/app";
|
||||
import { restoreScrollPosition, saveScrollPosition } from "@utils/browser";
|
||||
import {
|
||||
getPageFromString,
|
||||
getQueryParams,
|
||||
|
@ -78,14 +77,12 @@ import {
|
|||
TransferCommunity,
|
||||
} from "lemmy-js-client";
|
||||
import { fetchLimit, relTags } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import {
|
||||
CommentViewType,
|
||||
DataType,
|
||||
InitialFetchRequest,
|
||||
} from "../../interfaces";
|
||||
import { UserService } from "../../services";
|
||||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { setupTippy } from "../../tippy";
|
||||
import { toast } from "../../toast";
|
||||
|
@ -231,10 +228,6 @@ export class Community extends Component<
|
|||
setupTippy();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
saveScrollPosition(this.context);
|
||||
}
|
||||
|
||||
static async fetchInitialData({
|
||||
client,
|
||||
path,
|
||||
|
@ -331,7 +324,7 @@ export class Community extends Component<
|
|||
className="btn btn-secondary d-inline-block mb-2 me-3"
|
||||
onClick={linkEvent(this, this.handleShowSidebarMobile)}
|
||||
>
|
||||
{i18n.t("sidebar")}{" "}
|
||||
{I18NextService.i18n.t("sidebar")}{" "}
|
||||
<Icon
|
||||
icon={
|
||||
this.state.showSidebarMobile
|
||||
|
@ -611,7 +604,6 @@ export class Community extends Component<
|
|||
});
|
||||
}
|
||||
|
||||
restoreScrollPosition(this.context);
|
||||
setupTippy();
|
||||
}
|
||||
|
||||
|
@ -758,14 +750,14 @@ export class Community extends Component<
|
|||
async handleCommentReport(form: CreateCommentReport) {
|
||||
const reportRes = await HttpService.client.createCommentReport(form);
|
||||
if (reportRes.state == "success") {
|
||||
toast(i18n.t("report_created"));
|
||||
toast(I18NextService.i18n.t("report_created"));
|
||||
}
|
||||
}
|
||||
|
||||
async handlePostReport(form: CreatePostReport) {
|
||||
const reportRes = await HttpService.client.createPostReport(form);
|
||||
if (reportRes.state == "success") {
|
||||
toast(i18n.t("report_created"));
|
||||
toast(I18NextService.i18n.t("report_created"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -791,7 +783,7 @@ export class Community extends Component<
|
|||
const transferCommunityRes = await HttpService.client.transferCommunity(
|
||||
form
|
||||
);
|
||||
toast(i18n.t("transfer_community"));
|
||||
toast(I18NextService.i18n.t("transfer_community"));
|
||||
this.updateCommunityFull(transferCommunityRes);
|
||||
}
|
||||
|
||||
|
@ -880,7 +872,7 @@ export class Community extends Component<
|
|||
|
||||
purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
|
||||
if (purgeRes.state == "success") {
|
||||
toast(i18n.t("purge_success"));
|
||||
toast(I18NextService.i18n.t("purge_success"));
|
||||
this.context.router.history.push(`/`);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,7 @@ import {
|
|||
CreateCommunity as CreateCommunityI,
|
||||
GetSiteResponse,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { HttpService } from "../../services/HttpService";
|
||||
import { HttpService, I18NextService } from "../../services";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
import { CommunityForm } from "./community-form";
|
||||
|
||||
|
@ -26,7 +25,7 @@ export class CreateCommunity extends Component<any, CreateCommunityState> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
return `${i18n.t("create_community")} - ${
|
||||
return `${I18NextService.i18n.t("create_community")} - ${
|
||||
this.state.siteRes.site_view.site.name
|
||||
}`;
|
||||
}
|
||||
|
@ -40,7 +39,7 @@ export class CreateCommunity extends Component<any, CreateCommunityState> {
|
|||
/>
|
||||
<div className="row">
|
||||
<div className="col-12 col-lg-6 offset-lg-3 mb-4">
|
||||
<h5>{i18n.t("create_community")}</h5>
|
||||
<h5>{I18NextService.i18n.t("create_community")}</h5>
|
||||
<CommunityForm
|
||||
onUpsertCommunity={this.handleCommunityCreate}
|
||||
enableNsfw={enableNsfw(this.state.siteRes)}
|
||||
|
|
|
@ -17,9 +17,8 @@ import {
|
|||
PurgeCommunity,
|
||||
RemoveCommunity,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { mdToHtml } from "../../markdown";
|
||||
import { UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { Badges } from "../common/badges";
|
||||
import { BannerIconHeader } from "../common/banner-icon-header";
|
||||
import { Icon, PurgeWarning, Spinner } from "../common/icon";
|
||||
|
@ -187,7 +186,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
) : (
|
||||
<>
|
||||
<Icon icon="check" classes="icon-inline text-success me-1" />
|
||||
{i18n.t("joined")}
|
||||
{I18NextService.i18n.t("joined")}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
|
@ -200,23 +199,23 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
{this.state.followCommunityLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
i18n.t("subscribe_pending")
|
||||
I18NextService.i18n.t("subscribe_pending")
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
{community.removed && (
|
||||
<small className="me-2 text-muted font-italic">
|
||||
{i18n.t("removed")}
|
||||
{I18NextService.i18n.t("removed")}
|
||||
</small>
|
||||
)}
|
||||
{community.deleted && (
|
||||
<small className="me-2 text-muted font-italic">
|
||||
{i18n.t("deleted")}
|
||||
{I18NextService.i18n.t("deleted")}
|
||||
</small>
|
||||
)}
|
||||
{community.nsfw && (
|
||||
<small className="me-2 text-muted font-italic">
|
||||
{i18n.t("nsfw")}
|
||||
{I18NextService.i18n.t("nsfw")}
|
||||
</small>
|
||||
)}
|
||||
</h5>
|
||||
|
@ -234,7 +233,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
mods() {
|
||||
return (
|
||||
<ul className="list-inline small">
|
||||
<li className="list-inline-item">{i18n.t("mods")}: </li>
|
||||
<li className="list-inline-item">{I18NextService.i18n.t("mods")}: </li>
|
||||
{this.props.moderators.map(mod => (
|
||||
<li key={mod.moderator.id} className="list-inline-item">
|
||||
<PersonListing person={mod.moderator} />
|
||||
|
@ -253,7 +252,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
}`}
|
||||
to={`/create_post?communityId=${cv.community.id}`}
|
||||
>
|
||||
{i18n.t("create_a_post")}
|
||||
{I18NextService.i18n.t("create_a_post")}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
@ -270,7 +269,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
{this.state.followCommunityLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
i18n.t("subscribe")
|
||||
I18NextService.i18n.t("subscribe")
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
|
@ -288,7 +287,9 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
className="btn btn-danger d-block mb-2 w-100"
|
||||
onClick={linkEvent(this, this.handleBlockCommunity)}
|
||||
>
|
||||
{i18n.t(blocked ? "unblock_community" : "block_community")}
|
||||
{I18NextService.i18n.t(
|
||||
blocked ? "unblock_community" : "block_community"
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
|
@ -315,8 +316,8 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
<button
|
||||
className="btn btn-link text-muted d-inline-block"
|
||||
onClick={linkEvent(this, this.handleEditClick)}
|
||||
data-tippy-content={i18n.t("edit")}
|
||||
aria-label={i18n.t("edit")}
|
||||
data-tippy-content={I18NextService.i18n.t("edit")}
|
||||
aria-label={I18NextService.i18n.t("edit")}
|
||||
>
|
||||
<Icon icon="edit" classes="icon-inline" />
|
||||
</button>
|
||||
|
@ -331,20 +332,20 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
this.handleShowConfirmLeaveModTeamClick
|
||||
)}
|
||||
>
|
||||
{i18n.t("leave_mod_team")}
|
||||
{I18NextService.i18n.t("leave_mod_team")}
|
||||
</button>
|
||||
</li>
|
||||
) : (
|
||||
<>
|
||||
<li className="list-inline-item-action">
|
||||
{i18n.t("are_you_sure")}
|
||||
{I18NextService.i18n.t("are_you_sure")}
|
||||
</li>
|
||||
<li className="list-inline-item-action">
|
||||
<button
|
||||
className="btn btn-link text-muted d-inline-block"
|
||||
onClick={linkEvent(this, this.handleLeaveModTeam)}
|
||||
>
|
||||
{i18n.t("yes")}
|
||||
{I18NextService.i18n.t("yes")}
|
||||
</button>
|
||||
</li>
|
||||
<li className="list-inline-item-action">
|
||||
|
@ -355,7 +356,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
this.handleCancelLeaveModTeamClick
|
||||
)}
|
||||
>
|
||||
{i18n.t("no")}
|
||||
{I18NextService.i18n.t("no")}
|
||||
</button>
|
||||
</li>
|
||||
</>
|
||||
|
@ -367,13 +368,13 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
onClick={linkEvent(this, this.handleDeleteCommunity)}
|
||||
data-tippy-content={
|
||||
!community_view.community.deleted
|
||||
? i18n.t("delete")
|
||||
: i18n.t("restore")
|
||||
? I18NextService.i18n.t("delete")
|
||||
: I18NextService.i18n.t("restore")
|
||||
}
|
||||
aria-label={
|
||||
!community_view.community.deleted
|
||||
? i18n.t("delete")
|
||||
: i18n.t("restore")
|
||||
? I18NextService.i18n.t("delete")
|
||||
: I18NextService.i18n.t("restore")
|
||||
}
|
||||
>
|
||||
{this.state.deleteCommunityLoading ? (
|
||||
|
@ -398,7 +399,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
className="btn btn-link text-muted d-inline-block"
|
||||
onClick={linkEvent(this, this.handleModRemoveShow)}
|
||||
>
|
||||
{i18n.t("remove")}
|
||||
{I18NextService.i18n.t("remove")}
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
|
@ -408,16 +409,16 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
{this.state.removeCommunityLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
i18n.t("restore")
|
||||
I18NextService.i18n.t("restore")
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
className="btn btn-link text-muted d-inline-block"
|
||||
onClick={linkEvent(this, this.handlePurgeCommunityShow)}
|
||||
aria-label={i18n.t("purge_community")}
|
||||
aria-label={I18NextService.i18n.t("purge_community")}
|
||||
>
|
||||
{i18n.t("purge_community")}
|
||||
{I18NextService.i18n.t("purge_community")}
|
||||
</button>
|
||||
</li>
|
||||
)}
|
||||
|
@ -426,13 +427,13 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
<form onSubmit={linkEvent(this, this.handleRemoveCommunity)}>
|
||||
<div className="input-group mb-3">
|
||||
<label className="col-form-label" htmlFor="remove-reason">
|
||||
{i18n.t("reason")}
|
||||
{I18NextService.i18n.t("reason")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="remove-reason"
|
||||
className="form-control me-2"
|
||||
placeholder={i18n.t("optional")}
|
||||
placeholder={I18NextService.i18n.t("optional")}
|
||||
value={this.state.removeReason}
|
||||
onInput={linkEvent(this, this.handleModRemoveReasonChange)}
|
||||
/>
|
||||
|
@ -440,14 +441,14 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
{/* TODO hold off on expires for now */}
|
||||
{/* <div class="mb-3 row"> */}
|
||||
{/* <label class="col-form-label">Expires</label> */}
|
||||
{/* <input type="date" class="form-control me-2" placeholder={i18n.t('expires')} value={this.state.removeExpires} onInput={linkEvent(this, this.handleModRemoveExpiresChange)} /> */}
|
||||
{/* <input type="date" class="form-control me-2" placeholder={I18NextService.i18n.t('expires')} value={this.state.removeExpires} onInput={linkEvent(this, this.handleModRemoveExpiresChange)} /> */}
|
||||
{/* </div> */}
|
||||
<div className="input-group mb-3">
|
||||
<button type="submit" className="btn btn-secondary">
|
||||
{this.state.removeCommunityLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
i18n.t("remove_community")
|
||||
I18NextService.i18n.t("remove_community")
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -460,13 +461,13 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
</div>
|
||||
<div className="input-group mb-3">
|
||||
<label className="visually-hidden" htmlFor="purge-reason">
|
||||
{i18n.t("reason")}
|
||||
{I18NextService.i18n.t("reason")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="purge-reason"
|
||||
className="form-control me-2"
|
||||
placeholder={i18n.t("reason")}
|
||||
placeholder={I18NextService.i18n.t("reason")}
|
||||
value={this.state.purgeReason}
|
||||
onInput={linkEvent(this, this.handlePurgeReasonChange)}
|
||||
/>
|
||||
|
@ -478,9 +479,9 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
|||
<button
|
||||
type="submit"
|
||||
className="btn btn-secondary"
|
||||
aria-label={i18n.t("purge_community")}
|
||||
aria-label={I18NextService.i18n.t("purge_community")}
|
||||
>
|
||||
{i18n.t("purge_community")}
|
||||
{I18NextService.i18n.t("purge_community")}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -18,10 +18,9 @@ import {
|
|||
GetSiteResponse,
|
||||
PersonView,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { InitialFetchRequest } from "../../interfaces";
|
||||
import { removeFromEmojiDataModel, updateEmojiDataModel } from "../../markdown";
|
||||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import { FirstLoadService, I18NextService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { toast } from "../../toast";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
|
@ -108,7 +107,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
return `${i18n.t("admin_settings")} - ${
|
||||
return `${I18NextService.i18n.t("admin_settings")} - ${
|
||||
this.state.siteRes.site_view.site.name
|
||||
}`;
|
||||
}
|
||||
|
@ -129,7 +128,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
|||
tabs={[
|
||||
{
|
||||
key: "site",
|
||||
label: i18n.t("site"),
|
||||
label: I18NextService.i18n.t("site"),
|
||||
getNode: isSelected => (
|
||||
<div
|
||||
className={classNames("tab-pane show", {
|
||||
|
@ -181,7 +180,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
|||
},
|
||||
{
|
||||
key: "taglines",
|
||||
label: i18n.t("taglines"),
|
||||
label: I18NextService.i18n.t("taglines"),
|
||||
getNode: isSelected => (
|
||||
<div
|
||||
className={classNames("tab-pane", {
|
||||
|
@ -202,7 +201,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
|||
},
|
||||
{
|
||||
key: "emojis",
|
||||
label: i18n.t("emojis"),
|
||||
label: I18NextService.i18n.t("emojis"),
|
||||
getNode: isSelected => (
|
||||
<div
|
||||
className={classNames("tab-pane", {
|
||||
|
@ -253,7 +252,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
|||
admins() {
|
||||
return (
|
||||
<>
|
||||
<h5>{capitalizeFirstLetter(i18n.t("admins"))}</h5>
|
||||
<h5>{capitalizeFirstLetter(I18NextService.i18n.t("admins"))}</h5>
|
||||
<ul className="list-unstyled">
|
||||
{this.state.siteRes.admins.map(admin => (
|
||||
<li key={admin.person.id} className="list-inline-item">
|
||||
|
@ -275,7 +274,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
|||
{this.state.leaveAdminTeamRes.state == "loading" ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
i18n.t("leave_admin_team")
|
||||
I18NextService.i18n.t("leave_admin_team")
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
|
@ -293,7 +292,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
|||
const bans = this.state.bannedRes.data.banned;
|
||||
return (
|
||||
<>
|
||||
<h5>{i18n.t("banned_users")}</h5>
|
||||
<h5>{I18NextService.i18n.t("banned_users")}</h5>
|
||||
<ul className="list-unstyled">
|
||||
{bans.map(banned => (
|
||||
<li key={banned.person.id} className="list-inline-item">
|
||||
|
@ -319,7 +318,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
|||
s.siteRes.taglines = editRes.data.taglines;
|
||||
return s;
|
||||
});
|
||||
toast(i18n.t("site_saved"));
|
||||
toast(I18NextService.i18n.t("site_saved"));
|
||||
}
|
||||
|
||||
this.setState({ loading: false });
|
||||
|
@ -340,7 +339,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
|||
});
|
||||
|
||||
if (this.state.leaveAdminTeamRes.state === "success") {
|
||||
toast(i18n.t("left_admin_team"));
|
||||
toast(I18NextService.i18n.t("left_admin_team"));
|
||||
this.context.router.history.replace("/");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,8 @@ import {
|
|||
EditCustomEmoji,
|
||||
GetSiteResponse,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { customEmojisLookup } from "../../markdown";
|
||||
import { HttpService } from "../../services/HttpService";
|
||||
import { HttpService, I18NextService } from "../../services";
|
||||
import { pictrsDeleteToast, toast } from "../../toast";
|
||||
import { EmojiMart } from "../common/emoji-mart";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
|
@ -66,7 +65,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
|
|||
this.handleEmojiClick = this.handleEmojiClick.bind(this);
|
||||
}
|
||||
get documentTitle(): string {
|
||||
return i18n.t("custom_emojis");
|
||||
return I18NextService.i18n.t("custom_emojis");
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -76,7 +75,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
|
|||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
<h5 className="col-12">{i18n.t("custom_emojis")}</h5>
|
||||
<h5 className="col-12">{I18NextService.i18n.t("custom_emojis")}</h5>
|
||||
{customEmojisLookup.size > 0 && (
|
||||
<div>
|
||||
<EmojiMart
|
||||
|
@ -89,15 +88,21 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
|
|||
<table id="emojis_table" className="table table-sm table-hover">
|
||||
<thead className="pointer">
|
||||
<tr>
|
||||
<th>{i18n.t("column_emoji")}</th>
|
||||
<th className="text-right">{i18n.t("column_shortcode")}</th>
|
||||
<th className="text-right">{i18n.t("column_category")}</th>
|
||||
<th className="text-right d-lg-table-cell d-none">
|
||||
{i18n.t("column_imageurl")}
|
||||
<th>{I18NextService.i18n.t("column_emoji")}</th>
|
||||
<th className="text-right">
|
||||
{I18NextService.i18n.t("column_shortcode")}
|
||||
</th>
|
||||
<th className="text-right">
|
||||
{I18NextService.i18n.t("column_category")}
|
||||
</th>
|
||||
<th className="text-right d-lg-table-cell d-none">
|
||||
{I18NextService.i18n.t("column_imageurl")}
|
||||
</th>
|
||||
<th className="text-right">
|
||||
{I18NextService.i18n.t("column_alttext")}
|
||||
</th>
|
||||
<th className="text-right">{i18n.t("column_alttext")}</th>
|
||||
<th className="text-right d-lg-table-cell">
|
||||
{i18n.t("column_keywords")}
|
||||
{I18NextService.i18n.t("column_keywords")}
|
||||
</th>
|
||||
<th style="width:121px"></th>
|
||||
</tr>
|
||||
|
@ -215,8 +220,8 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
|
|||
{ i: this, cv: cv },
|
||||
this.handleEditEmojiClick
|
||||
)}
|
||||
data-tippy-content={i18n.t("save")}
|
||||
aria-label={i18n.t("save")}
|
||||
data-tippy-content={I18NextService.i18n.t("save")}
|
||||
aria-label={I18NextService.i18n.t("save")}
|
||||
disabled={
|
||||
this.props.loading ||
|
||||
!this.canEdit(cv) ||
|
||||
|
@ -236,10 +241,10 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
|
|||
{ i: this, index: index, cv: cv },
|
||||
this.handleDeleteEmojiClick
|
||||
)}
|
||||
data-tippy-content={i18n.t("delete")}
|
||||
aria-label={i18n.t("delete")}
|
||||
data-tippy-content={I18NextService.i18n.t("delete")}
|
||||
aria-label={I18NextService.i18n.t("delete")}
|
||||
disabled={this.props.loading}
|
||||
title={i18n.t("delete")}
|
||||
title={I18NextService.i18n.t("delete")}
|
||||
>
|
||||
<Icon
|
||||
icon="trash"
|
||||
|
@ -257,7 +262,7 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
|
|||
className="btn btn-sm btn-secondary me-2"
|
||||
onClick={linkEvent(this, this.handleAddEmojiClick)}
|
||||
>
|
||||
{i18n.t("add_custom_emoji")}
|
||||
{I18NextService.i18n.t("add_custom_emoji")}
|
||||
</button>
|
||||
|
||||
<Paginator page={this.state.page} onChange={this.handlePageChange} />
|
||||
|
@ -280,8 +285,8 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
|
|||
}
|
||||
|
||||
getEditTooltip(cv: CustomEmojiViewForm) {
|
||||
if (this.canEdit(cv)) return i18n.t("save");
|
||||
else return i18n.t("custom_emoji_save_validation");
|
||||
if (this.canEdit(cv)) return I18NextService.i18n.t("save");
|
||||
else return I18NextService.i18n.t("custom_emoji_save_validation");
|
||||
}
|
||||
|
||||
handlePageChange(page: number) {
|
||||
|
|
|
@ -13,7 +13,6 @@ import {
|
|||
showLocal,
|
||||
updatePersonBlock,
|
||||
} from "@utils/app";
|
||||
import { restoreScrollPosition, saveScrollPosition } from "@utils/browser";
|
||||
import {
|
||||
getPageFromString,
|
||||
getQueryParams,
|
||||
|
@ -73,15 +72,13 @@ import {
|
|||
TransferCommunity,
|
||||
} from "lemmy-js-client";
|
||||
import { fetchLimit, relTags, trendingFetchLimit } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import {
|
||||
CommentViewType,
|
||||
DataType,
|
||||
InitialFetchRequest,
|
||||
} from "../../interfaces";
|
||||
import { mdToHtml } from "../../markdown";
|
||||
import { UserService } from "../../services";
|
||||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { setupTippy } from "../../tippy";
|
||||
import { toast } from "../../toast";
|
||||
|
@ -197,7 +194,7 @@ const MobileButton = ({
|
|||
className="btn btn-secondary d-inline-block mb-2 me-3"
|
||||
onClick={onClick}
|
||||
>
|
||||
{i18n.t(textKey)}{" "}
|
||||
{I18NextService.i18n.t(textKey)}{" "}
|
||||
<Icon icon={show ? `minus-square` : `plus-square`} classes="icon-inline" />
|
||||
</button>
|
||||
);
|
||||
|
@ -210,7 +207,7 @@ const LinkButton = ({
|
|||
translationKey: NoOptionI18nKeys;
|
||||
}) => (
|
||||
<Link className="btn btn-secondary d-block" to={path}>
|
||||
{i18n.t(translationKey)}
|
||||
{I18NextService.i18n.t(translationKey)}
|
||||
</Link>
|
||||
);
|
||||
|
||||
|
@ -295,10 +292,6 @@ export class Home extends Component<any, HomeState> {
|
|||
setupTippy();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
saveScrollPosition(this.context);
|
||||
}
|
||||
|
||||
static async fetchInitialData({
|
||||
client,
|
||||
auth,
|
||||
|
@ -565,10 +558,14 @@ export class Home extends Component<any, HomeState> {
|
|||
className="btn btn-sm text-muted"
|
||||
onClick={linkEvent(this, this.handleCollapseSubscribe)}
|
||||
aria-label={
|
||||
subscribedCollapsed ? i18n.t("expand") : i18n.t("collapse")
|
||||
subscribedCollapsed
|
||||
? I18NextService.i18n.t("expand")
|
||||
: I18NextService.i18n.t("collapse")
|
||||
}
|
||||
data-tippy-content={
|
||||
subscribedCollapsed ? i18n.t("expand") : i18n.t("collapse")
|
||||
subscribedCollapsed
|
||||
? I18NextService.i18n.t("expand")
|
||||
: I18NextService.i18n.t("collapse")
|
||||
}
|
||||
aria-expanded="true"
|
||||
aria-controls="sidebarSubscribedBody"
|
||||
|
@ -798,7 +795,6 @@ export class Home extends Component<any, HomeState> {
|
|||
});
|
||||
}
|
||||
|
||||
restoreScrollPosition(this.context);
|
||||
setupTippy();
|
||||
}
|
||||
|
||||
|
@ -932,14 +928,14 @@ export class Home extends Component<any, HomeState> {
|
|||
async handleCommentReport(form: CreateCommentReport) {
|
||||
const reportRes = await HttpService.client.createCommentReport(form);
|
||||
if (reportRes.state == "success") {
|
||||
toast(i18n.t("report_created"));
|
||||
toast(I18NextService.i18n.t("report_created"));
|
||||
}
|
||||
}
|
||||
|
||||
async handlePostReport(form: CreatePostReport) {
|
||||
const reportRes = await HttpService.client.createPostReport(form);
|
||||
if (reportRes.state == "success") {
|
||||
toast(i18n.t("report_created"));
|
||||
toast(I18NextService.i18n.t("report_created"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -963,7 +959,7 @@ export class Home extends Component<any, HomeState> {
|
|||
|
||||
async handleTransferCommunity(form: TransferCommunity) {
|
||||
await HttpService.client.transferCommunity(form);
|
||||
toast(i18n.t("transfer_community"));
|
||||
toast(I18NextService.i18n.t("transfer_community"));
|
||||
}
|
||||
|
||||
async handleCommentReplyRead(form: MarkCommentReplyAsRead) {
|
||||
|
@ -1030,7 +1026,7 @@ export class Home extends Component<any, HomeState> {
|
|||
|
||||
purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
|
||||
if (purgeRes.state == "success") {
|
||||
toast(i18n.t("purge_success"));
|
||||
toast(I18NextService.i18n.t("purge_success"));
|
||||
this.context.router.history.push(`/`);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,8 @@ import {
|
|||
Instance,
|
||||
} from "lemmy-js-client";
|
||||
import { relTags } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import { InitialFetchRequest } from "../../interfaces";
|
||||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import { FirstLoadService, I18NextService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
import { Spinner } from "../common/icon";
|
||||
|
@ -70,7 +69,9 @@ export class Instances extends Component<any, InstancesState> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
return `${i18n.t("instances")} - ${this.state.siteRes.site_view.site.name}`;
|
||||
return `${I18NextService.i18n.t("instances")} - ${
|
||||
this.state.siteRes.site_view.site.name
|
||||
}`;
|
||||
}
|
||||
|
||||
renderInstances() {
|
||||
|
@ -86,18 +87,18 @@ export class Instances extends Component<any, InstancesState> {
|
|||
return instances ? (
|
||||
<div className="row">
|
||||
<div className="col-md-6">
|
||||
<h5>{i18n.t("linked_instances")}</h5>
|
||||
<h5>{I18NextService.i18n.t("linked_instances")}</h5>
|
||||
{this.itemList(instances.linked)}
|
||||
</div>
|
||||
{instances.allowed && instances.allowed.length > 0 && (
|
||||
<div className="col-md-6">
|
||||
<h5>{i18n.t("allowed_instances")}</h5>
|
||||
<h5>{I18NextService.i18n.t("allowed_instances")}</h5>
|
||||
{this.itemList(instances.allowed)}
|
||||
</div>
|
||||
)}
|
||||
{instances.blocked && instances.blocked.length > 0 && (
|
||||
<div className="col-md-6">
|
||||
<h5>{i18n.t("blocked_instances")}</h5>
|
||||
<h5>{I18NextService.i18n.t("blocked_instances")}</h5>
|
||||
{this.itemList(instances.blocked)}
|
||||
</div>
|
||||
)}
|
||||
|
@ -127,9 +128,9 @@ export class Instances extends Component<any, InstancesState> {
|
|||
<table id="instances_table" className="table table-sm table-hover">
|
||||
<thead className="pointer">
|
||||
<tr>
|
||||
<th>{i18n.t("name")}</th>
|
||||
<th>{i18n.t("software")}</th>
|
||||
<th>{i18n.t("version")}</th>
|
||||
<th>{I18NextService.i18n.t("name")}</th>
|
||||
<th>{I18NextService.i18n.t("software")}</th>
|
||||
<th>{I18NextService.i18n.t("version")}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -148,7 +149,7 @@ export class Instances extends Component<any, InstancesState> {
|
|||
</table>
|
||||
</div>
|
||||
) : (
|
||||
<div>{i18n.t("none_found")}</div>
|
||||
<div>{I18NextService.i18n.t("none_found")}</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { setIsoData } from "@utils/app";
|
||||
import { Component } from "inferno";
|
||||
import { GetSiteResponse } from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { mdToHtml } from "../../markdown";
|
||||
import { I18NextService } from "../../services";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
|
||||
interface LegalState {
|
||||
|
@ -20,7 +20,7 @@ export class Legal extends Component<any, LegalState> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
return i18n.t("legal_information");
|
||||
return I18NextService.i18n.t("legal_information");
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -3,8 +3,7 @@ import { isBrowser } from "@utils/browser";
|
|||
import { validEmail } from "@utils/helpers";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import { GetSiteResponse, LoginResponse } from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { toast } from "../../toast";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
|
@ -43,7 +42,9 @@ export class Login extends Component<any, State> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
return `${i18n.t("login")} - ${this.state.siteRes.site_view.site.name}`;
|
||||
return `${I18NextService.i18n.t("login")} - ${
|
||||
this.state.siteRes.site_view.site.name
|
||||
}`;
|
||||
}
|
||||
|
||||
get isLemmyMl(): boolean {
|
||||
|
@ -68,13 +69,13 @@ export class Login extends Component<any, State> {
|
|||
return (
|
||||
<div>
|
||||
<form onSubmit={linkEvent(this, this.handleLoginSubmit)}>
|
||||
<h5>{i18n.t("login")}</h5>
|
||||
<h5>{I18NextService.i18n.t("login")}</h5>
|
||||
<div className="mb-3 row">
|
||||
<label
|
||||
className="col-sm-2 col-form-label"
|
||||
htmlFor="login-email-or-username"
|
||||
>
|
||||
{i18n.t("email_or_username")}
|
||||
{I18NextService.i18n.t("email_or_username")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<input
|
||||
|
@ -91,7 +92,7 @@ export class Login extends Component<any, State> {
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2 col-form-label" htmlFor="login-password">
|
||||
{i18n.t("password")}
|
||||
{I18NextService.i18n.t("password")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<input
|
||||
|
@ -112,9 +113,9 @@ export class Login extends Component<any, State> {
|
|||
!!this.state.form.username_or_email &&
|
||||
!validEmail(this.state.form.username_or_email)
|
||||
}
|
||||
title={i18n.t("no_password_reset")}
|
||||
title={I18NextService.i18n.t("no_password_reset")}
|
||||
>
|
||||
{i18n.t("forgot_password")}
|
||||
{I18NextService.i18n.t("forgot_password")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -124,7 +125,7 @@ export class Login extends Component<any, State> {
|
|||
className="col-sm-6 col-form-label"
|
||||
htmlFor="login-totp-token"
|
||||
>
|
||||
{i18n.t("two_factor_token")}
|
||||
{I18NextService.i18n.t("two_factor_token")}
|
||||
</label>
|
||||
<div className="col-sm-6">
|
||||
<input
|
||||
|
@ -146,7 +147,7 @@ export class Login extends Component<any, State> {
|
|||
{this.state.loginRes.state == "loading" ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
i18n.t("login")
|
||||
I18NextService.i18n.t("login")
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -172,7 +173,7 @@ export class Login extends Component<any, State> {
|
|||
case "failed": {
|
||||
if (loginRes.msg === "missing_totp_token") {
|
||||
i.setState({ showTotp: true });
|
||||
toast(i18n.t("enter_two_factor_code"), "info");
|
||||
toast(I18NextService.i18n.t("enter_two_factor_code"), "info");
|
||||
}
|
||||
|
||||
i.setState({ loginRes: { state: "failed", msg: loginRes.msg } });
|
||||
|
@ -220,7 +221,7 @@ export class Login extends Component<any, State> {
|
|||
if (email) {
|
||||
const res = await HttpService.client.passwordReset({ email });
|
||||
if (res.state == "success") {
|
||||
toast(i18n.t("reset_password_mail_sent"));
|
||||
toast(I18NextService.i18n.t("reset_password_mail_sent"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { capitalizeFirstLetter } from "@utils/helpers";
|
|||
import classNames from "classnames";
|
||||
import { Component, FormEventHandler, linkEvent } from "inferno";
|
||||
import { EditSite, LocalSiteRateLimit } from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { Spinner } from "../common/icon";
|
||||
import Tabs from "../common/tabs";
|
||||
|
||||
|
@ -57,7 +57,9 @@ function RateLimits({
|
|||
return (
|
||||
<div role="tabpanel" className={classNames("mb-3 row", className)}>
|
||||
<div className="col-md-6">
|
||||
<label htmlFor="rate-limit">{i18n.t("rate_limit")}</label>
|
||||
<label htmlFor="rate-limit">
|
||||
{I18NextService.i18n.t("rate_limit")}
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
id="rate-limit"
|
||||
|
@ -68,7 +70,9 @@ function RateLimits({
|
|||
/>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<label htmlFor="rate-limit-per-second">{i18n.t("per_second")}</label>
|
||||
<label htmlFor="rate-limit-per-second">
|
||||
{I18NextService.i18n.t("per_second")}
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
id="rate-limit-per-second"
|
||||
|
@ -141,11 +145,11 @@ export default class RateLimitsForm extends Component<
|
|||
className="rate-limit-form"
|
||||
onSubmit={linkEvent(this, submitRateLimitForm)}
|
||||
>
|
||||
<h5>{i18n.t("rate_limit_header")}</h5>
|
||||
<h5>{I18NextService.i18n.t("rate_limit_header")}</h5>
|
||||
<Tabs
|
||||
tabs={rateLimitTypes.map(rateLimitType => ({
|
||||
key: rateLimitType,
|
||||
label: i18n.t(`rate_limit_${rateLimitType}`),
|
||||
label: I18NextService.i18n.t(`rate_limit_${rateLimitType}`),
|
||||
getNode: isSelected => (
|
||||
<RateLimits
|
||||
className={classNames("tab-pane show", {
|
||||
|
@ -176,7 +180,7 @@ export default class RateLimitsForm extends Component<
|
|||
{this.props.loading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
capitalizeFirstLetter(i18n.t("save"))
|
||||
capitalizeFirstLetter(I18NextService.i18n.t("save"))
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -7,8 +7,7 @@ import {
|
|||
LoginResponse,
|
||||
Register,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { Spinner } from "../common/icon";
|
||||
import { SiteForm } from "./site-form";
|
||||
|
@ -55,7 +54,7 @@ export class Setup extends Component<any, State> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
return `${i18n.t("setup")} - Lemmy`;
|
||||
return `${I18NextService.i18n.t("setup")} - Lemmy`;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -64,7 +63,7 @@ export class Setup extends Component<any, State> {
|
|||
<Helmet title={this.documentTitle} />
|
||||
<div className="row">
|
||||
<div className="col-12 offset-lg-3 col-lg-6">
|
||||
<h3>{i18n.t("lemmy_instance_setup")}</h3>
|
||||
<h3>{I18NextService.i18n.t("lemmy_instance_setup")}</h3>
|
||||
{!this.state.doneRegisteringUser ? (
|
||||
this.registerUser()
|
||||
) : (
|
||||
|
@ -85,10 +84,10 @@ export class Setup extends Component<any, State> {
|
|||
registerUser() {
|
||||
return (
|
||||
<form onSubmit={linkEvent(this, this.handleRegisterSubmit)}>
|
||||
<h5>{i18n.t("setup_admin")}</h5>
|
||||
<h5>{I18NextService.i18n.t("setup_admin")}</h5>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2 col-form-label" htmlFor="username">
|
||||
{i18n.t("username")}
|
||||
{I18NextService.i18n.t("username")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<input
|
||||
|
@ -105,7 +104,7 @@ export class Setup extends Component<any, State> {
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2 col-form-label" htmlFor="email">
|
||||
{i18n.t("email")}
|
||||
{I18NextService.i18n.t("email")}
|
||||
</label>
|
||||
|
||||
<div className="col-sm-10">
|
||||
|
@ -113,7 +112,7 @@ export class Setup extends Component<any, State> {
|
|||
type="email"
|
||||
id="email"
|
||||
className="form-control"
|
||||
placeholder={i18n.t("optional")}
|
||||
placeholder={I18NextService.i18n.t("optional")}
|
||||
value={this.state.form.email}
|
||||
onInput={linkEvent(this, this.handleRegisterEmailChange)}
|
||||
minLength={3}
|
||||
|
@ -122,7 +121,7 @@ export class Setup extends Component<any, State> {
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2 col-form-label" htmlFor="password">
|
||||
{i18n.t("password")}
|
||||
{I18NextService.i18n.t("password")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<input
|
||||
|
@ -140,7 +139,7 @@ export class Setup extends Component<any, State> {
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2 col-form-label" htmlFor="verify-password">
|
||||
{i18n.t("verify_password")}
|
||||
{I18NextService.i18n.t("verify_password")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<input
|
||||
|
@ -162,7 +161,7 @@ export class Setup extends Component<any, State> {
|
|||
{this.state.registerRes.state == "loading" ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
i18n.t("sign_up")
|
||||
I18NextService.i18n.t("sign_up")
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -13,9 +13,8 @@ import {
|
|||
SiteView,
|
||||
} from "lemmy-js-client";
|
||||
import { joinLemmyUrl } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import { mdToHtml } from "../../markdown";
|
||||
import { UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { toast } from "../../toast";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
|
@ -113,7 +112,7 @@ export class Signup extends Component<any, State> {
|
|||
}
|
||||
|
||||
titleName(siteView: SiteView): string {
|
||||
return i18n.t(
|
||||
return I18NextService.i18n.t(
|
||||
siteView.local_site.private_instance ? "apply_to_join" : "sign_up"
|
||||
);
|
||||
}
|
||||
|
@ -159,7 +158,7 @@ export class Signup extends Component<any, State> {
|
|||
className="col-sm-2 col-form-label"
|
||||
htmlFor="register-username"
|
||||
>
|
||||
{i18n.t("username")}
|
||||
{I18NextService.i18n.t("username")}
|
||||
</label>
|
||||
|
||||
<div className="col-sm-10">
|
||||
|
@ -172,14 +171,14 @@ export class Signup extends Component<any, State> {
|
|||
required
|
||||
minLength={3}
|
||||
pattern="[a-zA-Z0-9_]+"
|
||||
title={i18n.t("community_reqs")}
|
||||
title={I18NextService.i18n.t("community_reqs")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2 col-form-label" htmlFor="register-email">
|
||||
{i18n.t("email")}
|
||||
{I18NextService.i18n.t("email")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<input
|
||||
|
@ -188,8 +187,8 @@ export class Signup extends Component<any, State> {
|
|||
className="form-control"
|
||||
placeholder={
|
||||
siteView.local_site.require_email_verification
|
||||
? i18n.t("required")
|
||||
: i18n.t("optional")
|
||||
? I18NextService.i18n.t("required")
|
||||
: I18NextService.i18n.t("optional")
|
||||
}
|
||||
value={this.state.form.email}
|
||||
autoComplete="email"
|
||||
|
@ -202,7 +201,7 @@ export class Signup extends Component<any, State> {
|
|||
!validEmail(this.state.form.email) && (
|
||||
<div className="mt-2 mb-0 alert alert-warning" role="alert">
|
||||
<Icon icon="alert-triangle" classes="icon-inline me-2" />
|
||||
{i18n.t("no_password_reset")}
|
||||
{I18NextService.i18n.t("no_password_reset")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -213,7 +212,7 @@ export class Signup extends Component<any, State> {
|
|||
className="col-sm-2 col-form-label"
|
||||
htmlFor="register-password"
|
||||
>
|
||||
{i18n.t("password")}
|
||||
{I18NextService.i18n.t("password")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<input
|
||||
|
@ -229,7 +228,9 @@ export class Signup extends Component<any, State> {
|
|||
/>
|
||||
{this.state.form.password && (
|
||||
<div className={this.passwordColorClass}>
|
||||
{i18n.t(this.passwordStrength as NoOptionI18nKeys)}
|
||||
{I18NextService.i18n.t(
|
||||
this.passwordStrength as NoOptionI18nKeys
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -240,7 +241,7 @@ export class Signup extends Component<any, State> {
|
|||
className="col-sm-2 col-form-label"
|
||||
htmlFor="register-verify-password"
|
||||
>
|
||||
{i18n.t("verify_password")}
|
||||
{I18NextService.i18n.t("verify_password")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<input
|
||||
|
@ -262,7 +263,7 @@ export class Signup extends Component<any, State> {
|
|||
<div className="offset-sm-2 col-sm-10">
|
||||
<div className="mt-2 alert alert-warning" role="alert">
|
||||
<Icon icon="alert-triangle" classes="icon-inline me-2" />
|
||||
{i18n.t("fill_out_application")}
|
||||
{I18NextService.i18n.t("fill_out_application")}
|
||||
</div>
|
||||
{siteView.local_site.application_question && (
|
||||
<div
|
||||
|
@ -280,7 +281,7 @@ export class Signup extends Component<any, State> {
|
|||
className="col-sm-2 col-form-label"
|
||||
htmlFor="application_answer"
|
||||
>
|
||||
{i18n.t("answer")}
|
||||
{I18NextService.i18n.t("answer")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<MarkdownTextArea
|
||||
|
@ -306,7 +307,7 @@ export class Signup extends Component<any, State> {
|
|||
onChange={linkEvent(this, this.handleRegisterShowNsfwChange)}
|
||||
/>
|
||||
<label className="form-check-label" htmlFor="register-show-nsfw">
|
||||
{i18n.t("show_nsfw")}
|
||||
{I18NextService.i18n.t("show_nsfw")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -345,12 +346,14 @@ export class Signup extends Component<any, State> {
|
|||
return (
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2" htmlFor="register-captcha">
|
||||
<span className="me-2">{i18n.t("enter_code")}</span>
|
||||
<span className="me-2">
|
||||
{I18NextService.i18n.t("enter_code")}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary"
|
||||
onClick={linkEvent(this, this.handleRegenCaptcha)}
|
||||
aria-label={i18n.t("captcha")}
|
||||
aria-label={I18NextService.i18n.t("captcha")}
|
||||
>
|
||||
<Icon icon="refresh-cw" classes="icon-refresh-cw" />
|
||||
</button>
|
||||
|
@ -384,13 +387,13 @@ export class Signup extends Component<any, State> {
|
|||
className="rounded-top img-fluid"
|
||||
src={this.captchaPngSrc(captchaRes)}
|
||||
style="border-bottom-right-radius: 0; border-bottom-left-radius: 0;"
|
||||
alt={i18n.t("captcha")}
|
||||
alt={I18NextService.i18n.t("captcha")}
|
||||
/>
|
||||
{captchaRes.wav && (
|
||||
<button
|
||||
className="rounded-bottom btn btn-sm btn-secondary d-block"
|
||||
style="border-top-right-radius: 0; border-top-left-radius: 0;"
|
||||
title={i18n.t("play_captcha_audio")}
|
||||
title={I18NextService.i18n.t("play_captcha_audio")}
|
||||
onClick={linkEvent(this, this.handleCaptchaPlay)}
|
||||
type="button"
|
||||
disabled={this.state.captchaPlaying}
|
||||
|
@ -474,10 +477,10 @@ export class Signup extends Component<any, State> {
|
|||
i.props.history.replace("/communities");
|
||||
} else {
|
||||
if (data.verify_email_sent) {
|
||||
toast(i18n.t("verify_email_sent"));
|
||||
toast(I18NextService.i18n.t("verify_email_sent"));
|
||||
}
|
||||
if (data.registration_created) {
|
||||
toast(i18n.t("registration_application_sent"));
|
||||
toast(I18NextService.i18n.t("registration_application_sent"));
|
||||
}
|
||||
i.props.history.push("/");
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
Instance,
|
||||
ListingType,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { Icon, Spinner } from "../common/icon";
|
||||
import { ImageUploadForm } from "../common/image-upload-form";
|
||||
import { LanguageSelect } from "../common/language-select";
|
||||
|
@ -136,12 +136,12 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
/>
|
||||
<h5>{`${
|
||||
siteSetup
|
||||
? capitalizeFirstLetter(i18n.t("edit"))
|
||||
: capitalizeFirstLetter(i18n.t("setup"))
|
||||
} ${i18n.t("your_site")}`}</h5>
|
||||
? capitalizeFirstLetter(I18NextService.i18n.t("edit"))
|
||||
: capitalizeFirstLetter(I18NextService.i18n.t("setup"))
|
||||
} ${I18NextService.i18n.t("your_site")}`}</h5>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-12 col-form-label" htmlFor="create-site-name">
|
||||
{i18n.t("name")}
|
||||
{I18NextService.i18n.t("name")}
|
||||
</label>
|
||||
<div className="col-12">
|
||||
<input
|
||||
|
@ -157,9 +157,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
</div>
|
||||
</div>
|
||||
<div className="input-group mb-3">
|
||||
<label className="me-2 col-form-label">{i18n.t("icon")}</label>
|
||||
<label className="me-2 col-form-label">
|
||||
{I18NextService.i18n.t("icon")}
|
||||
</label>
|
||||
<ImageUploadForm
|
||||
uploadTitle={i18n.t("upload_icon")}
|
||||
uploadTitle={I18NextService.i18n.t("upload_icon")}
|
||||
imageSrc={this.state.siteForm.icon}
|
||||
onUpload={this.handleIconUpload}
|
||||
onRemove={this.handleIconRemove}
|
||||
|
@ -167,9 +169,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
/>
|
||||
</div>
|
||||
<div className="input-group mb-3">
|
||||
<label className="me-2 col-form-label">{i18n.t("banner")}</label>
|
||||
<label className="me-2 col-form-label">
|
||||
{I18NextService.i18n.t("banner")}
|
||||
</label>
|
||||
<ImageUploadForm
|
||||
uploadTitle={i18n.t("upload_banner")}
|
||||
uploadTitle={I18NextService.i18n.t("upload_banner")}
|
||||
imageSrc={this.state.siteForm.banner}
|
||||
onUpload={this.handleBannerUpload}
|
||||
onRemove={this.handleBannerRemove}
|
||||
|
@ -177,7 +181,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-12 col-form-label" htmlFor="site-desc">
|
||||
{i18n.t("description")}
|
||||
{I18NextService.i18n.t("description")}
|
||||
</label>
|
||||
<div className="col-12">
|
||||
<input
|
||||
|
@ -191,7 +195,9 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
</div>
|
||||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-12 col-form-label">{i18n.t("sidebar")}</label>
|
||||
<label className="col-12 col-form-label">
|
||||
{I18NextService.i18n.t("sidebar")}
|
||||
</label>
|
||||
<div className="col-12">
|
||||
<MarkdownTextArea
|
||||
initialContent={this.state.siteForm.sidebar}
|
||||
|
@ -204,7 +210,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-12 col-form-label">
|
||||
{i18n.t("legal_information")}
|
||||
{I18NextService.i18n.t("legal_information")}
|
||||
</label>
|
||||
<div className="col-12">
|
||||
<MarkdownTextArea
|
||||
|
@ -230,7 +236,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="form-check-label"
|
||||
htmlFor="create-site-downvotes"
|
||||
>
|
||||
{i18n.t("enable_downvotes")}
|
||||
{I18NextService.i18n.t("enable_downvotes")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -249,7 +255,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="form-check-label"
|
||||
htmlFor="create-site-enable-nsfw"
|
||||
>
|
||||
{i18n.t("enable_nsfw")}
|
||||
{I18NextService.i18n.t("enable_nsfw")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -260,7 +266,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="form-check-label me-2"
|
||||
htmlFor="create-site-registration-mode"
|
||||
>
|
||||
{i18n.t("registration_mode")}
|
||||
{I18NextService.i18n.t("registration_mode")}
|
||||
</label>
|
||||
<select
|
||||
id="create-site-registration-mode"
|
||||
|
@ -269,17 +275,21 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="form-select d-inline-block w-auto"
|
||||
>
|
||||
<option value={"RequireApplication"}>
|
||||
{i18n.t("require_registration_application")}
|
||||
{I18NextService.i18n.t("require_registration_application")}
|
||||
</option>
|
||||
<option value={"Open"}>
|
||||
{I18NextService.i18n.t("open_registration")}
|
||||
</option>
|
||||
<option value={"Closed"}>
|
||||
{I18NextService.i18n.t("close_registration")}
|
||||
</option>
|
||||
<option value={"Open"}>{i18n.t("open_registration")}</option>
|
||||
<option value={"Closed"}>{i18n.t("close_registration")}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{this.state.siteForm.registration_mode == "RequireApplication" && (
|
||||
<div className="mb-3 row">
|
||||
<label className="col-12 col-form-label">
|
||||
{i18n.t("application_questionnaire")}
|
||||
{I18NextService.i18n.t("application_questionnaire")}
|
||||
</label>
|
||||
<div className="col-12">
|
||||
<MarkdownTextArea
|
||||
|
@ -309,7 +319,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="form-check-label"
|
||||
htmlFor="create-site-community-creation-admin-only"
|
||||
>
|
||||
{i18n.t("community_creation_admin_only")}
|
||||
{I18NextService.i18n.t("community_creation_admin_only")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -331,7 +341,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="form-check-label"
|
||||
htmlFor="create-site-require-email-verification"
|
||||
>
|
||||
{i18n.t("require_email_verification")}
|
||||
{I18NextService.i18n.t("require_email_verification")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -353,7 +363,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="form-check-label"
|
||||
htmlFor="create-site-email-admins"
|
||||
>
|
||||
{i18n.t("application_email_admins")}
|
||||
{I18NextService.i18n.t("application_email_admins")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -372,7 +382,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="form-check-label"
|
||||
htmlFor="create-site-reports-email-admins"
|
||||
>
|
||||
{i18n.t("reports_email_admins")}
|
||||
{I18NextService.i18n.t("reports_email_admins")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -383,7 +393,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="form-check-label me-2"
|
||||
htmlFor="create-site-default-theme"
|
||||
>
|
||||
{i18n.t("theme")}
|
||||
{I18NextService.i18n.t("theme")}
|
||||
</label>
|
||||
<select
|
||||
id="create-site-default-theme"
|
||||
|
@ -391,7 +401,9 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
onChange={linkEvent(this, this.handleSiteDefaultTheme)}
|
||||
className="form-select d-inline-block w-auto"
|
||||
>
|
||||
<option value="browser">{i18n.t("browser_default")}</option>
|
||||
<option value="browser">
|
||||
{I18NextService.i18n.t("browser_default")}
|
||||
</option>
|
||||
{this.props.themeList?.map(theme => (
|
||||
<option key={theme} value={theme}>
|
||||
{theme}
|
||||
|
@ -403,7 +415,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
{this.props.showLocal && (
|
||||
<form className="mb-3 row">
|
||||
<label className="col-sm-3 col-form-label">
|
||||
{i18n.t("listing_type")}
|
||||
{I18NextService.i18n.t("listing_type")}
|
||||
</label>
|
||||
<div className="col-sm-9">
|
||||
<ListingTypeSelect
|
||||
|
@ -429,7 +441,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="form-check-label"
|
||||
htmlFor="create-site-private-instance"
|
||||
>
|
||||
{i18n.t("private_instance")}
|
||||
{I18NextService.i18n.t("private_instance")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -448,7 +460,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="form-check-label"
|
||||
htmlFor="create-site-hide-modlog-mod-names"
|
||||
>
|
||||
{i18n.t("hide_modlog_mod_names")}
|
||||
{I18NextService.i18n.t("hide_modlog_mod_names")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -458,7 +470,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="col-12 col-form-label"
|
||||
htmlFor="create-site-slur-filter-regex"
|
||||
>
|
||||
{i18n.t("slur_filter_regex")}
|
||||
{I18NextService.i18n.t("slur_filter_regex")}
|
||||
</label>
|
||||
<div className="col-12">
|
||||
<input
|
||||
|
@ -485,7 +497,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="col-12 col-form-label"
|
||||
htmlFor="create-site-actor-name"
|
||||
>
|
||||
{i18n.t("actor_name_max_length")}
|
||||
{I18NextService.i18n.t("actor_name_max_length")}
|
||||
</label>
|
||||
<div className="col-12">
|
||||
<input
|
||||
|
@ -512,7 +524,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="form-check-label"
|
||||
htmlFor="create-site-federation-enabled"
|
||||
>
|
||||
{i18n.t("federation_enabled")}
|
||||
{I18NextService.i18n.t("federation_enabled")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -537,7 +549,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="form-check-label"
|
||||
htmlFor="create-site-federation-debug"
|
||||
>
|
||||
{i18n.t("federation_debug")}
|
||||
{I18NextService.i18n.t("federation_debug")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -547,7 +559,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="col-12 col-form-label"
|
||||
htmlFor="create-site-federation-worker-count"
|
||||
>
|
||||
{i18n.t("federation_worker_count")}
|
||||
{I18NextService.i18n.t("federation_worker_count")}
|
||||
</label>
|
||||
<div className="col-12">
|
||||
<input
|
||||
|
@ -579,7 +591,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="form-check-label"
|
||||
htmlFor="create-site-captcha-enabled"
|
||||
>
|
||||
{i18n.t("captcha_enabled")}
|
||||
{I18NextService.i18n.t("captcha_enabled")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -591,7 +603,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
className="form-check-label me-2"
|
||||
htmlFor="create-site-captcha-difficulty"
|
||||
>
|
||||
{i18n.t("captcha_difficulty")}
|
||||
{I18NextService.i18n.t("captcha_difficulty")}
|
||||
</label>
|
||||
<select
|
||||
id="create-site-captcha-difficulty"
|
||||
|
@ -599,9 +611,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
onChange={linkEvent(this, this.handleSiteCaptchaDifficulty)}
|
||||
className="form-select d-inline-block w-auto"
|
||||
>
|
||||
<option value="easy">{i18n.t("easy")}</option>
|
||||
<option value="medium">{i18n.t("medium")}</option>
|
||||
<option value="hard">{i18n.t("hard")}</option>
|
||||
<option value="easy">{I18NextService.i18n.t("easy")}</option>
|
||||
<option value="medium">
|
||||
{I18NextService.i18n.t("medium")}
|
||||
</option>
|
||||
<option value="hard">{I18NextService.i18n.t("hard")}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -616,9 +630,9 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
{this.props.loading ? (
|
||||
<Spinner />
|
||||
) : siteSetup ? (
|
||||
capitalizeFirstLetter(i18n.t("save"))
|
||||
capitalizeFirstLetter(I18NextService.i18n.t("save"))
|
||||
) : (
|
||||
capitalizeFirstLetter(i18n.t("create"))
|
||||
capitalizeFirstLetter(I18NextService.i18n.t("create"))
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -634,7 +648,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
return (
|
||||
<div className="col-12 col-md-6">
|
||||
<label className="col-form-label" htmlFor={id}>
|
||||
{i18n.t(key)}
|
||||
{I18NextService.i18n.t(key)}
|
||||
</label>
|
||||
<div className="d-flex justify-content-between align-items-center">
|
||||
<input
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Component, linkEvent } from "inferno";
|
||||
import { PersonView, Site, SiteAggregates } from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { mdToHtml } from "../../markdown";
|
||||
import { I18NextService } from "../../services";
|
||||
import { Badges } from "../common/badges";
|
||||
import { BannerIconHeader } from "../common/banner-icon-header";
|
||||
import { Icon } from "../common/icon";
|
||||
|
@ -62,10 +62,14 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> {
|
|||
className="btn btn-sm"
|
||||
onClick={linkEvent(this, this.handleCollapseSidebar)}
|
||||
aria-label={
|
||||
this.state.collapsed ? i18n.t("expand") : i18n.t("collapse")
|
||||
this.state.collapsed
|
||||
? I18NextService.i18n.t("expand")
|
||||
: I18NextService.i18n.t("collapse")
|
||||
}
|
||||
data-tippy-content={
|
||||
this.state.collapsed ? i18n.t("expand") : i18n.t("collapse")
|
||||
this.state.collapsed
|
||||
? I18NextService.i18n.t("expand")
|
||||
: I18NextService.i18n.t("collapse")
|
||||
}
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#sidebarInfoBody"
|
||||
|
@ -104,7 +108,7 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> {
|
|||
admins(admins: PersonView[]) {
|
||||
return (
|
||||
<ul className="mt-1 list-inline small mb-0">
|
||||
<li className="list-inline-item">{i18n.t("admins")}:</li>
|
||||
<li className="list-inline-item">{I18NextService.i18n.t("admins")}:</li>
|
||||
{admins.map(av => (
|
||||
<li key={av.person.id} className="list-inline-item">
|
||||
<PersonListing person={av.person} />
|
||||
|
|
|
@ -2,7 +2,7 @@ import { myAuthRequired } from "@utils/app";
|
|||
import { capitalizeFirstLetter } from "@utils/helpers";
|
||||
import { Component, InfernoMouseEvent, linkEvent } from "inferno";
|
||||
import { EditSite, Tagline } from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
import { Icon, Spinner } from "../common/icon";
|
||||
import { MarkdownTextArea } from "../common/markdown-textarea";
|
||||
|
@ -27,7 +27,7 @@ export class TaglineForm extends Component<TaglineFormProps, TaglineFormState> {
|
|||
super(props, context);
|
||||
}
|
||||
get documentTitle(): string {
|
||||
return i18n.t("taglines");
|
||||
return I18NextService.i18n.t("taglines");
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -37,7 +37,7 @@ export class TaglineForm extends Component<TaglineFormProps, TaglineFormState> {
|
|||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
<h5 className="col-12">{i18n.t("taglines")}</h5>
|
||||
<h5 className="col-12">{I18NextService.i18n.t("taglines")}</h5>
|
||||
<div className="table-responsive col-12">
|
||||
<table id="taglines_table" className="table table-sm table-hover">
|
||||
<thead className="pointer">
|
||||
|
@ -68,8 +68,8 @@ export class TaglineForm extends Component<TaglineFormProps, TaglineFormState> {
|
|||
{ i: this, index: index },
|
||||
this.handleEditTaglineClick
|
||||
)}
|
||||
data-tippy-content={i18n.t("edit")}
|
||||
aria-label={i18n.t("edit")}
|
||||
data-tippy-content={I18NextService.i18n.t("edit")}
|
||||
aria-label={I18NextService.i18n.t("edit")}
|
||||
>
|
||||
<Icon icon="edit" classes={`icon-inline`} />
|
||||
</button>
|
||||
|
@ -80,8 +80,8 @@ export class TaglineForm extends Component<TaglineFormProps, TaglineFormState> {
|
|||
{ i: this, index: index },
|
||||
this.handleDeleteTaglineClick
|
||||
)}
|
||||
data-tippy-content={i18n.t("delete")}
|
||||
aria-label={i18n.t("delete")}
|
||||
data-tippy-content={I18NextService.i18n.t("delete")}
|
||||
aria-label={I18NextService.i18n.t("delete")}
|
||||
>
|
||||
<Icon icon="trash" classes={`icon-inline text-danger`} />
|
||||
</button>
|
||||
|
@ -96,7 +96,7 @@ export class TaglineForm extends Component<TaglineFormProps, TaglineFormState> {
|
|||
className="btn btn-sm btn-secondary me-2"
|
||||
onClick={linkEvent(this, this.handleAddTaglineClick)}
|
||||
>
|
||||
{i18n.t("add_tagline")}
|
||||
{I18NextService.i18n.t("add_tagline")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -111,7 +111,7 @@ export class TaglineForm extends Component<TaglineFormProps, TaglineFormState> {
|
|||
{this.props.loading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
capitalizeFirstLetter(i18n.t("save"))
|
||||
capitalizeFirstLetter(I18NextService.i18n.t("save"))
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -46,9 +46,8 @@ import {
|
|||
} from "lemmy-js-client";
|
||||
import moment from "moment";
|
||||
import { fetchLimit } from "../config";
|
||||
import { i18n } from "../i18next";
|
||||
import { InitialFetchRequest } from "../interfaces";
|
||||
import { FirstLoadService } from "../services/FirstLoadService";
|
||||
import { FirstLoadService, I18NextService } from "../services";
|
||||
import { HttpService, RequestState } from "../services/HttpService";
|
||||
import { HtmlTags } from "./common/html-tags";
|
||||
import { Icon, Spinner } from "./common/icon";
|
||||
|
@ -586,14 +585,14 @@ const Filter = ({
|
|||
}) => (
|
||||
<div className="col-sm-6 mb-3">
|
||||
<label className="mb-2" htmlFor={`filter-${filterType}`}>
|
||||
{i18n.t(`filter_by_${filterType}` as NoOptionI18nKeys)}
|
||||
{I18NextService.i18n.t(`filter_by_${filterType}` as NoOptionI18nKeys)}
|
||||
</label>
|
||||
<SearchableSelect
|
||||
id={`filter-${filterType}`}
|
||||
value={value ?? 0}
|
||||
options={[
|
||||
{
|
||||
label: i18n.t("all"),
|
||||
label: I18NextService.i18n.t("all"),
|
||||
value: "0",
|
||||
},
|
||||
].concat(options)}
|
||||
|
@ -724,8 +723,8 @@ export class Modlog extends Component<
|
|||
this.isoData.site_res.admins.some(
|
||||
({ person: { id } }) => id === person.id
|
||||
)
|
||||
? i18n.t("admin")
|
||||
: i18n.t("mod");
|
||||
? I18NextService.i18n.t("admin")
|
||||
: I18NextService.i18n.t("mod");
|
||||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
|
@ -770,7 +769,7 @@ export class Modlog extends Component<
|
|||
>
|
||||
/c/{this.state.communityRes.data.community_view.community.name}{" "}
|
||||
</Link>
|
||||
<span>{i18n.t("modlog")}</span>
|
||||
<span>{I18NextService.i18n.t("modlog")}</span>
|
||||
</h5>
|
||||
)}
|
||||
<div className="row mb-2">
|
||||
|
@ -782,9 +781,9 @@ export class Modlog extends Component<
|
|||
aria-label="action"
|
||||
>
|
||||
<option disabled aria-hidden="true">
|
||||
{i18n.t("filter_by_action")}
|
||||
{I18NextService.i18n.t("filter_by_action")}
|
||||
</option>
|
||||
<option value={"All"}>{i18n.t("all")}</option>
|
||||
<option value={"All"}>{I18NextService.i18n.t("all")}</option>
|
||||
<option value={"ModRemovePost"}>Removing Posts</option>
|
||||
<option value={"ModLockPost"}>Locking Posts</option>
|
||||
<option value={"ModFeaturePost"}>Featuring Posts</option>
|
||||
|
@ -848,9 +847,9 @@ export class Modlog extends Component<
|
|||
<table id="modlog_table" className="table table-sm table-hover">
|
||||
<thead className="pointer">
|
||||
<tr>
|
||||
<th> {i18n.t("time")}</th>
|
||||
<th>{i18n.t("mod")}</th>
|
||||
<th>{i18n.t("action")}</th>
|
||||
<th> {I18NextService.i18n.t("time")}</th>
|
||||
<th>{I18NextService.i18n.t("mod")}</th>
|
||||
<th>{I18NextService.i18n.t("action")}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{this.combined}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component } from "inferno";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { Icon } from "../common/icon";
|
||||
|
||||
interface CakeDayProps {
|
||||
|
@ -19,6 +19,8 @@ export class CakeDay extends Component<CakeDayProps, any> {
|
|||
}
|
||||
|
||||
cakeDayTippy(): string {
|
||||
return i18n.t("cake_day_info", { creator_name: this.props.creatorName });
|
||||
return I18NextService.i18n.t("cake_day_info", {
|
||||
creator_name: this.props.creatorName,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,10 +59,8 @@ import {
|
|||
TransferCommunity,
|
||||
} from "lemmy-js-client";
|
||||
import { fetchLimit, relTags } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import { CommentViewType, InitialFetchRequest } from "../../interfaces";
|
||||
import { UserService } from "../../services";
|
||||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { toast } from "../../toast";
|
||||
import { CommentNodes } from "../comment/comment-nodes";
|
||||
|
@ -187,9 +185,9 @@ export class Inbox extends Component<any, InboxState> {
|
|||
get documentTitle(): string {
|
||||
const mui = UserService.Instance.myUserInfo;
|
||||
return mui
|
||||
? `@${mui.local_user_view.person.name} ${i18n.t("inbox")} - ${
|
||||
this.state.siteRes.site_view.site.name
|
||||
}`
|
||||
? `@${mui.local_user_view.person.name} ${I18NextService.i18n.t(
|
||||
"inbox"
|
||||
)} - ${this.state.siteRes.site_view.site.name}`
|
||||
: "";
|
||||
}
|
||||
|
||||
|
@ -223,7 +221,7 @@ export class Inbox extends Component<any, InboxState> {
|
|||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
<h5 className="mb-2">
|
||||
{i18n.t("inbox")}
|
||||
{I18NextService.i18n.t("inbox")}
|
||||
{inboxRss && (
|
||||
<small>
|
||||
<a href={inboxRss} title="RSS" rel={relTags}>
|
||||
|
@ -245,7 +243,7 @@ export class Inbox extends Component<any, InboxState> {
|
|||
{this.state.markAllAsReadRes.state == "loading" ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
i18n.t("mark_all_as_read")
|
||||
I18NextService.i18n.t("mark_all_as_read")
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
|
@ -296,7 +294,7 @@ export class Inbox extends Component<any, InboxState> {
|
|||
checked={this.state.unreadOrAll == UnreadOrAll.Unread}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
{i18n.t("unread")}
|
||||
{I18NextService.i18n.t("unread")}
|
||||
</label>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
|
@ -310,7 +308,7 @@ export class Inbox extends Component<any, InboxState> {
|
|||
checked={this.state.unreadOrAll == UnreadOrAll.All}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
{i18n.t("all")}
|
||||
{I18NextService.i18n.t("all")}
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
|
@ -331,7 +329,7 @@ export class Inbox extends Component<any, InboxState> {
|
|||
checked={this.state.messageType == MessageType.All}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{i18n.t("all")}
|
||||
{I18NextService.i18n.t("all")}
|
||||
</label>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
|
@ -345,7 +343,7 @@ export class Inbox extends Component<any, InboxState> {
|
|||
checked={this.state.messageType == MessageType.Replies}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{i18n.t("replies")}
|
||||
{I18NextService.i18n.t("replies")}
|
||||
</label>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
|
@ -359,7 +357,7 @@ export class Inbox extends Component<any, InboxState> {
|
|||
checked={this.state.messageType == MessageType.Mentions}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{i18n.t("mentions")}
|
||||
{I18NextService.i18n.t("mentions")}
|
||||
</label>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
|
@ -373,7 +371,7 @@ export class Inbox extends Component<any, InboxState> {
|
|||
checked={this.state.messageType == MessageType.Messages}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{i18n.t("messages")}
|
||||
{I18NextService.i18n.t("messages")}
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
|
@ -826,7 +824,7 @@ export class Inbox extends Component<any, InboxState> {
|
|||
const res = await HttpService.client.createComment(form);
|
||||
|
||||
if (res.state === "success") {
|
||||
toast(i18n.t("reply_sent"));
|
||||
toast(I18NextService.i18n.t("reply_sent"));
|
||||
this.findAndUpdateComment(res);
|
||||
}
|
||||
|
||||
|
@ -837,7 +835,7 @@ export class Inbox extends Component<any, InboxState> {
|
|||
const res = await HttpService.client.editComment(form);
|
||||
|
||||
if (res.state === "success") {
|
||||
toast(i18n.t("edit"));
|
||||
toast(I18NextService.i18n.t("edit"));
|
||||
this.findAndUpdateComment(res);
|
||||
} else if (res.state === "failed") {
|
||||
toast(res.msg, "danger");
|
||||
|
@ -849,7 +847,7 @@ export class Inbox extends Component<any, InboxState> {
|
|||
async handleDeleteComment(form: DeleteComment) {
|
||||
const res = await HttpService.client.deleteComment(form);
|
||||
if (res.state == "success") {
|
||||
toast(i18n.t("deleted"));
|
||||
toast(I18NextService.i18n.t("deleted"));
|
||||
this.findAndUpdateComment(res);
|
||||
}
|
||||
}
|
||||
|
@ -857,7 +855,7 @@ export class Inbox extends Component<any, InboxState> {
|
|||
async handleRemoveComment(form: RemoveComment) {
|
||||
const res = await HttpService.client.removeComment(form);
|
||||
if (res.state == "success") {
|
||||
toast(i18n.t("remove_comment"));
|
||||
toast(I18NextService.i18n.t("remove_comment"));
|
||||
this.findAndUpdateComment(res);
|
||||
}
|
||||
}
|
||||
|
@ -892,7 +890,7 @@ export class Inbox extends Component<any, InboxState> {
|
|||
|
||||
async handleTransferCommunity(form: TransferCommunity) {
|
||||
await HttpService.client.transferCommunity(form);
|
||||
toast(i18n.t("transfer_community"));
|
||||
toast(I18NextService.i18n.t("transfer_community"));
|
||||
}
|
||||
|
||||
async handleCommentReplyRead(form: MarkCommentReplyAsRead) {
|
||||
|
@ -1004,7 +1002,7 @@ export class Inbox extends Component<any, InboxState> {
|
|||
|
||||
purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
|
||||
if (purgeRes.state == "success") {
|
||||
toast(i18n.t("purge_success"));
|
||||
toast(I18NextService.i18n.t("purge_success"));
|
||||
this.context.router.history.push(`/`);
|
||||
}
|
||||
}
|
||||
|
@ -1013,7 +1011,7 @@ export class Inbox extends Component<any, InboxState> {
|
|||
res: RequestState<PrivateMessageReportResponse | CommentReportResponse>
|
||||
) {
|
||||
if (res.state == "success") {
|
||||
toast(i18n.t("report_created"));
|
||||
toast(I18NextService.i18n.t("report_created"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@ import { myAuth, setIsoData } from "@utils/app";
|
|||
import { capitalizeFirstLetter } from "@utils/helpers";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import { GetSiteResponse, LoginResponse } from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { HttpService, UserService } from "../../services";
|
||||
import { HttpService, I18NextService, UserService } from "../../services";
|
||||
import { RequestState } from "../../services/HttpService";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
import { Spinner } from "../common/icon";
|
||||
|
@ -34,7 +33,7 @@ export class PasswordChange extends Component<any, State> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
return `${i18n.t("password_change")} - ${
|
||||
return `${I18NextService.i18n.t("password_change")} - ${
|
||||
this.state.siteRes.site_view.site.name
|
||||
}`;
|
||||
}
|
||||
|
@ -48,7 +47,7 @@ export class PasswordChange extends Component<any, State> {
|
|||
/>
|
||||
<div className="row">
|
||||
<div className="col-12 col-lg-6 offset-lg-3 mb-4">
|
||||
<h5>{i18n.t("password_change")}</h5>
|
||||
<h5>{I18NextService.i18n.t("password_change")}</h5>
|
||||
{this.passwordChangeForm()}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -61,7 +60,7 @@ export class PasswordChange extends Component<any, State> {
|
|||
<form onSubmit={linkEvent(this, this.handlePasswordChangeSubmit)}>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2 col-form-label" htmlFor="new-password">
|
||||
{i18n.t("new_password")}
|
||||
{I18NextService.i18n.t("new_password")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<input
|
||||
|
@ -77,7 +76,7 @@ export class PasswordChange extends Component<any, State> {
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2 col-form-label" htmlFor="verify-password">
|
||||
{i18n.t("verify_password")}
|
||||
{I18NextService.i18n.t("verify_password")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<input
|
||||
|
@ -97,7 +96,7 @@ export class PasswordChange extends Component<any, State> {
|
|||
{this.state.passwordChangeRes.state == "loading" ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
capitalizeFirstLetter(i18n.t("save"))
|
||||
capitalizeFirstLetter(I18NextService.i18n.t("save"))
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -72,11 +72,9 @@ import {
|
|||
} from "lemmy-js-client";
|
||||
import moment from "moment";
|
||||
import { fetchLimit, relTags } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import { InitialFetchRequest, PersonDetailsView } from "../../interfaces";
|
||||
import { mdToHtml } from "../../markdown";
|
||||
import { UserService } from "../../services";
|
||||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { setupTippy } from "../../tippy";
|
||||
import { toast } from "../../toast";
|
||||
|
@ -137,7 +135,7 @@ const getCommunitiesListing = (
|
|||
communityViews.length > 0 && (
|
||||
<div className="card border-secondary mb-3">
|
||||
<div className="card-body">
|
||||
<h5>{i18n.t(translationKey)}</h5>
|
||||
<h5>{I18NextService.i18n.t(translationKey)}</h5>
|
||||
<ul className="list-unstyled mb-0">
|
||||
{communityViews.map(({ community }) => (
|
||||
<li key={community.id}>
|
||||
|
@ -422,7 +420,7 @@ export class Profile extends Component<
|
|||
checked={active}
|
||||
onChange={linkEvent(this, this.handleViewChange)}
|
||||
/>
|
||||
{i18n.t(view.toLowerCase() as NoOptionI18nKeys)}
|
||||
{I18NextService.i18n.t(view.toLowerCase() as NoOptionI18nKeys)}
|
||||
</label>
|
||||
);
|
||||
}
|
||||
|
@ -485,22 +483,22 @@ export class Profile extends Component<
|
|||
</li>
|
||||
{isBanned(pv.person) && (
|
||||
<li className="list-inline-item badge text-bg-danger">
|
||||
{i18n.t("banned")}
|
||||
{I18NextService.i18n.t("banned")}
|
||||
</li>
|
||||
)}
|
||||
{pv.person.deleted && (
|
||||
<li className="list-inline-item badge text-bg-danger">
|
||||
{i18n.t("deleted")}
|
||||
{I18NextService.i18n.t("deleted")}
|
||||
</li>
|
||||
)}
|
||||
{pv.person.admin && (
|
||||
<li className="list-inline-item badge text-bg-light">
|
||||
{i18n.t("admin")}
|
||||
{I18NextService.i18n.t("admin")}
|
||||
</li>
|
||||
)}
|
||||
{pv.person.bot_account && (
|
||||
<li className="list-inline-item badge text-bg-light">
|
||||
{i18n.t("bot_account").toLowerCase()}
|
||||
{I18NextService.i18n.t("bot_account").toLowerCase()}
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
|
@ -516,7 +514,7 @@ export class Profile extends Component<
|
|||
rel={relTags}
|
||||
href={`https://matrix.to/#/${pv.person.matrix_user_id}`}
|
||||
>
|
||||
{i18n.t("send_secure_message")}
|
||||
{I18NextService.i18n.t("send_secure_message")}
|
||||
</a>
|
||||
<Link
|
||||
className={
|
||||
|
@ -524,7 +522,7 @@ export class Profile extends Component<
|
|||
}
|
||||
to={`/create_private_message/${pv.person.id}`}
|
||||
>
|
||||
{i18n.t("send_message")}
|
||||
{I18NextService.i18n.t("send_message")}
|
||||
</Link>
|
||||
{personBlocked ? (
|
||||
<button
|
||||
|
@ -536,7 +534,7 @@ export class Profile extends Component<
|
|||
this.handleUnblockPerson
|
||||
)}
|
||||
>
|
||||
{i18n.t("unblock_user")}
|
||||
{I18NextService.i18n.t("unblock_user")}
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
|
@ -548,7 +546,7 @@ export class Profile extends Component<
|
|||
this.handleBlockPerson
|
||||
)}
|
||||
>
|
||||
{i18n.t("block_user")}
|
||||
{I18NextService.i18n.t("block_user")}
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
|
@ -563,9 +561,9 @@ export class Profile extends Component<
|
|||
"d-flex align-self-start btn btn-secondary me-2"
|
||||
}
|
||||
onClick={linkEvent(this, this.handleModBanShow)}
|
||||
aria-label={i18n.t("ban")}
|
||||
aria-label={I18NextService.i18n.t("ban")}
|
||||
>
|
||||
{capitalizeFirstLetter(i18n.t("ban"))}
|
||||
{capitalizeFirstLetter(I18NextService.i18n.t("ban"))}
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
|
@ -573,9 +571,9 @@ export class Profile extends Component<
|
|||
"d-flex align-self-start btn btn-secondary me-2"
|
||||
}
|
||||
onClick={linkEvent(this, this.handleModBanSubmit)}
|
||||
aria-label={i18n.t("unban")}
|
||||
aria-label={I18NextService.i18n.t("unban")}
|
||||
>
|
||||
{capitalizeFirstLetter(i18n.t("unban"))}
|
||||
{capitalizeFirstLetter(I18NextService.i18n.t("unban"))}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
@ -590,13 +588,13 @@ export class Profile extends Component<
|
|||
<div>
|
||||
<ul className="list-inline mb-2">
|
||||
<li className="list-inline-item badge text-bg-light">
|
||||
{i18n.t("number_of_posts", {
|
||||
{I18NextService.i18n.t("number_of_posts", {
|
||||
count: Number(pv.counts.post_count),
|
||||
formattedCount: numToSI(pv.counts.post_count),
|
||||
})}
|
||||
</li>
|
||||
<li className="list-inline-item badge text-bg-light">
|
||||
{i18n.t("number_of_comments", {
|
||||
{I18NextService.i18n.t("number_of_comments", {
|
||||
count: Number(pv.counts.comment_count),
|
||||
formattedCount: numToSI(pv.counts.comment_count),
|
||||
})}
|
||||
|
@ -604,7 +602,7 @@ export class Profile extends Component<
|
|||
</ul>
|
||||
</div>
|
||||
<div className="text-muted">
|
||||
{i18n.t("joined")}{" "}
|
||||
{I18NextService.i18n.t("joined")}{" "}
|
||||
<MomentTime
|
||||
published={pv.person.published}
|
||||
showAgo
|
||||
|
@ -614,7 +612,7 @@ export class Profile extends Component<
|
|||
<div className="d-flex align-items-center text-muted mb-2">
|
||||
<Icon icon="cake" />
|
||||
<span className="ms-2">
|
||||
{i18n.t("cake_day_title")}{" "}
|
||||
{I18NextService.i18n.t("cake_day_title")}{" "}
|
||||
{moment
|
||||
.utc(pv.person.published)
|
||||
.local()
|
||||
|
@ -623,7 +621,7 @@ export class Profile extends Component<
|
|||
</div>
|
||||
{!UserService.Instance.myUserInfo && (
|
||||
<div className="alert alert-info" role="alert">
|
||||
{i18n.t("profile_not_logged_in_alert")}
|
||||
{I18NextService.i18n.t("profile_not_logged_in_alert")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -641,24 +639,24 @@ export class Profile extends Component<
|
|||
<form onSubmit={linkEvent(this, this.handleModBanSubmit)}>
|
||||
<div className="mb-3 row col-12">
|
||||
<label className="col-form-label" htmlFor="profile-ban-reason">
|
||||
{i18n.t("reason")}
|
||||
{I18NextService.i18n.t("reason")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="profile-ban-reason"
|
||||
className="form-control me-2"
|
||||
placeholder={i18n.t("reason")}
|
||||
placeholder={I18NextService.i18n.t("reason")}
|
||||
value={this.state.banReason}
|
||||
onInput={linkEvent(this, this.handleModBanReasonChange)}
|
||||
/>
|
||||
<label className="col-form-label" htmlFor={`mod-ban-expires`}>
|
||||
{i18n.t("expires")}
|
||||
{I18NextService.i18n.t("expires")}
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
id={`mod-ban-expires`}
|
||||
className="form-control me-2"
|
||||
placeholder={i18n.t("number_of_days")}
|
||||
placeholder={I18NextService.i18n.t("number_of_days")}
|
||||
value={this.state.banExpireDays}
|
||||
onInput={linkEvent(this, this.handleModBanExpireDaysChange)}
|
||||
/>
|
||||
|
@ -674,9 +672,9 @@ export class Profile extends Component<
|
|||
<label
|
||||
className="form-check-label"
|
||||
htmlFor="mod-ban-remove-data"
|
||||
title={i18n.t("remove_content_more")}
|
||||
title={I18NextService.i18n.t("remove_content_more")}
|
||||
>
|
||||
{i18n.t("remove_content")}
|
||||
{I18NextService.i18n.t("remove_content")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -684,23 +682,23 @@ export class Profile extends Component<
|
|||
{/* TODO hold off on expires until later */}
|
||||
{/* <div class="mb-3 row"> */}
|
||||
{/* <label class="col-form-label">Expires</label> */}
|
||||
{/* <input type="date" class="form-control me-2" placeholder={i18n.t('expires')} value={this.state.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */}
|
||||
{/* <input type="date" class="form-control me-2" placeholder={I18NextService.i18n.t('expires')} value={this.state.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */}
|
||||
{/* </div> */}
|
||||
<div className="mb-3 row">
|
||||
<button
|
||||
type="reset"
|
||||
className="btn btn-secondary me-2"
|
||||
aria-label={i18n.t("cancel")}
|
||||
aria-label={I18NextService.i18n.t("cancel")}
|
||||
onClick={linkEvent(this, this.handleModBanSubmitCancel)}
|
||||
>
|
||||
{i18n.t("cancel")}
|
||||
{I18NextService.i18n.t("cancel")}
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-secondary"
|
||||
aria-label={i18n.t("ban")}
|
||||
aria-label={I18NextService.i18n.t("ban")}
|
||||
>
|
||||
{i18n.t("ban")} {pv.person.name}
|
||||
{I18NextService.i18n.t("ban")} {pv.person.name}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -904,14 +902,14 @@ export class Profile extends Component<
|
|||
async handleCommentReport(form: CreateCommentReport) {
|
||||
const reportRes = await HttpService.client.createCommentReport(form);
|
||||
if (reportRes.state === "success") {
|
||||
toast(i18n.t("report_created"));
|
||||
toast(I18NextService.i18n.t("report_created"));
|
||||
}
|
||||
}
|
||||
|
||||
async handlePostReport(form: CreatePostReport) {
|
||||
const reportRes = await HttpService.client.createPostReport(form);
|
||||
if (reportRes.state === "success") {
|
||||
toast(i18n.t("report_created"));
|
||||
toast(I18NextService.i18n.t("report_created"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -935,7 +933,7 @@ export class Profile extends Component<
|
|||
|
||||
async handleTransferCommunity(form: TransferCommunity) {
|
||||
await HttpService.client.transferCommunity(form);
|
||||
toast(i18n.t("transfer_community"));
|
||||
toast(I18NextService.i18n.t("transfer_community"));
|
||||
}
|
||||
|
||||
async handleCommentReplyRead(form: MarkCommentReplyAsRead) {
|
||||
|
@ -999,7 +997,7 @@ export class Profile extends Component<
|
|||
|
||||
purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
|
||||
if (purgeRes.state == "success") {
|
||||
toast(i18n.t("purge_success"));
|
||||
toast(I18NextService.i18n.t("purge_success"));
|
||||
this.context.router.history.push(`/`);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,10 +12,8 @@ import {
|
|||
RegistrationApplicationView,
|
||||
} from "lemmy-js-client";
|
||||
import { fetchLimit } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import { InitialFetchRequest } from "../../interfaces";
|
||||
import { UserService } from "../../services";
|
||||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { setupTippy } from "../../tippy";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
|
@ -79,7 +77,7 @@ export class RegistrationApplications extends Component<
|
|||
get documentTitle(): string {
|
||||
const mui = UserService.Instance.myUserInfo;
|
||||
return mui
|
||||
? `@${mui.local_user_view.person.name} ${i18n.t(
|
||||
? `@${mui.local_user_view.person.name} ${I18NextService.i18n.t(
|
||||
"registration_applications"
|
||||
)} - ${this.state.siteRes.site_view.site.name}`
|
||||
: "";
|
||||
|
@ -102,7 +100,9 @@ export class RegistrationApplications extends Component<
|
|||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
<h5 className="mb-2">{i18n.t("registration_applications")}</h5>
|
||||
<h5 className="mb-2">
|
||||
{I18NextService.i18n.t("registration_applications")}
|
||||
</h5>
|
||||
{this.selects()}
|
||||
{this.applicationList(apps)}
|
||||
<Paginator
|
||||
|
@ -139,7 +139,7 @@ export class RegistrationApplications extends Component<
|
|||
checked={this.state.unreadOrAll == UnreadOrAll.Unread}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
{i18n.t("unread")}
|
||||
{I18NextService.i18n.t("unread")}
|
||||
</label>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
|
@ -153,7 +153,7 @@ export class RegistrationApplications extends Component<
|
|||
checked={this.state.unreadOrAll == UnreadOrAll.All}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
{i18n.t("all")}
|
||||
{I18NextService.i18n.t("all")}
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -27,10 +27,13 @@ import {
|
|||
ResolvePrivateMessageReport,
|
||||
} from "lemmy-js-client";
|
||||
import { fetchLimit } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import { InitialFetchRequest } from "../../interfaces";
|
||||
import { HttpService, UserService } from "../../services";
|
||||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import {
|
||||
FirstLoadService,
|
||||
HttpService,
|
||||
I18NextService,
|
||||
UserService,
|
||||
} from "../../services";
|
||||
import { RequestState } from "../../services/HttpService";
|
||||
import { CommentReport } from "../comment/comment-report";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
|
@ -134,9 +137,9 @@ export class Reports extends Component<any, ReportsState> {
|
|||
get documentTitle(): string {
|
||||
const mui = UserService.Instance.myUserInfo;
|
||||
return mui
|
||||
? `@${mui.local_user_view.person.name} ${i18n.t("reports")} - ${
|
||||
this.state.siteRes.site_view.site.name
|
||||
}`
|
||||
? `@${mui.local_user_view.person.name} ${I18NextService.i18n.t(
|
||||
"reports"
|
||||
)} - ${this.state.siteRes.site_view.site.name}`
|
||||
: "";
|
||||
}
|
||||
|
||||
|
@ -149,7 +152,7 @@ export class Reports extends Component<any, ReportsState> {
|
|||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
<h5 className="mb-2">{i18n.t("reports")}</h5>
|
||||
<h5 className="mb-2">{I18NextService.i18n.t("reports")}</h5>
|
||||
{this.selects()}
|
||||
{this.section}
|
||||
<Paginator
|
||||
|
@ -198,7 +201,7 @@ export class Reports extends Component<any, ReportsState> {
|
|||
checked={this.state.unreadOrAll == UnreadOrAll.Unread}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
{i18n.t("unread")}
|
||||
{I18NextService.i18n.t("unread")}
|
||||
</label>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
|
@ -212,7 +215,7 @@ export class Reports extends Component<any, ReportsState> {
|
|||
checked={this.state.unreadOrAll == UnreadOrAll.All}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
{i18n.t("all")}
|
||||
{I18NextService.i18n.t("all")}
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
|
@ -233,7 +236,7 @@ export class Reports extends Component<any, ReportsState> {
|
|||
checked={this.state.messageType == MessageType.All}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{i18n.t("all")}
|
||||
{I18NextService.i18n.t("all")}
|
||||
</label>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
|
@ -247,7 +250,7 @@ export class Reports extends Component<any, ReportsState> {
|
|||
checked={this.state.messageType == MessageType.CommentReport}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{i18n.t("comments")}
|
||||
{I18NextService.i18n.t("comments")}
|
||||
</label>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
|
@ -261,7 +264,7 @@ export class Reports extends Component<any, ReportsState> {
|
|||
checked={this.state.messageType == MessageType.PostReport}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{i18n.t("posts")}
|
||||
{I18NextService.i18n.t("posts")}
|
||||
</label>
|
||||
{amAdmin() && (
|
||||
<label
|
||||
|
@ -281,7 +284,7 @@ export class Reports extends Component<any, ReportsState> {
|
|||
}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{i18n.t("messages")}
|
||||
{I18NextService.i18n.t("messages")}
|
||||
</label>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -29,9 +29,9 @@ import {
|
|||
SortType,
|
||||
} from "lemmy-js-client";
|
||||
import { elementUrl, emDash, relTags } from "../../config";
|
||||
import { i18n, languages } from "../../i18next";
|
||||
import { UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { I18NextService, languages } from "../../services/I18NextService";
|
||||
import { setupTippy } from "../../tippy";
|
||||
import { toast } from "../../toast";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
|
@ -113,7 +113,7 @@ const Filter = ({
|
|||
className="col-md-4 col-form-label"
|
||||
htmlFor={`block-${filterType}-filter`}
|
||||
>
|
||||
{i18n.t(`block_${filterType}` as NoOptionI18nKeys)}
|
||||
{I18NextService.i18n.t(`block_${filterType}` as NoOptionI18nKeys)}
|
||||
</label>
|
||||
<div className="col-md-8">
|
||||
<SearchableSelect
|
||||
|
@ -233,7 +233,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
return i18n.t("settings");
|
||||
return I18NextService.i18n.t("settings");
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -249,12 +249,12 @@ export class Settings extends Component<any, SettingsState> {
|
|||
tabs={[
|
||||
{
|
||||
key: "settings",
|
||||
label: i18n.t("settings"),
|
||||
label: I18NextService.i18n.t("settings"),
|
||||
getNode: this.userSettings,
|
||||
},
|
||||
{
|
||||
key: "blocks",
|
||||
label: i18n.t("blocks"),
|
||||
label: I18NextService.i18n.t("blocks"),
|
||||
getNode: this.blockCards,
|
||||
},
|
||||
]}
|
||||
|
@ -316,11 +316,11 @@ export class Settings extends Component<any, SettingsState> {
|
|||
changePasswordHtmlForm() {
|
||||
return (
|
||||
<>
|
||||
<h5>{i18n.t("change_password")}</h5>
|
||||
<h5>{I18NextService.i18n.t("change_password")}</h5>
|
||||
<form onSubmit={linkEvent(this, this.handleChangePasswordSubmit)}>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-5 col-form-label" htmlFor="user-password">
|
||||
{i18n.t("new_password")}
|
||||
{I18NextService.i18n.t("new_password")}
|
||||
</label>
|
||||
<div className="col-sm-7">
|
||||
<input
|
||||
|
@ -339,7 +339,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
className="col-sm-5 col-form-label"
|
||||
htmlFor="user-verify-password"
|
||||
>
|
||||
{i18n.t("verify_password")}
|
||||
{I18NextService.i18n.t("verify_password")}
|
||||
</label>
|
||||
<div className="col-sm-7">
|
||||
<input
|
||||
|
@ -358,7 +358,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
className="col-sm-5 col-form-label"
|
||||
htmlFor="user-old-password"
|
||||
>
|
||||
{i18n.t("old_password")}
|
||||
{I18NextService.i18n.t("old_password")}
|
||||
</label>
|
||||
<div className="col-sm-7">
|
||||
<input
|
||||
|
@ -380,7 +380,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
{this.state.changePasswordRes.state === "loading" ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
capitalizeFirstLetter(i18n.t("save"))
|
||||
capitalizeFirstLetter(I18NextService.i18n.t("save"))
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -409,7 +409,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
blockedUsersList() {
|
||||
return (
|
||||
<>
|
||||
<h5>{i18n.t("blocked_users")}</h5>
|
||||
<h5>{I18NextService.i18n.t("blocked_users")}</h5>
|
||||
<ul className="list-unstyled mb-0">
|
||||
{this.state.personBlocks.map(pb => (
|
||||
<li key={pb.target.id}>
|
||||
|
@ -421,7 +421,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
{ ctx: this, recipientId: pb.target.id },
|
||||
this.handleUnblockPerson
|
||||
)}
|
||||
data-tippy-content={i18n.t("unblock_user")}
|
||||
data-tippy-content={I18NextService.i18n.t("unblock_user")}
|
||||
>
|
||||
<Icon icon="x" classes="icon-inline" />
|
||||
</button>
|
||||
|
@ -453,7 +453,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
blockedCommunitiesList() {
|
||||
return (
|
||||
<>
|
||||
<h5>{i18n.t("blocked_communities")}</h5>
|
||||
<h5>{I18NextService.i18n.t("blocked_communities")}</h5>
|
||||
<ul className="list-unstyled mb-0">
|
||||
{this.state.communityBlocks.map(cb => (
|
||||
<li key={cb.community.id}>
|
||||
|
@ -465,7 +465,9 @@ export class Settings extends Component<any, SettingsState> {
|
|||
{ ctx: this, communityId: cb.community.id },
|
||||
this.handleUnblockCommunity
|
||||
)}
|
||||
data-tippy-content={i18n.t("unblock_community")}
|
||||
data-tippy-content={I18NextService.i18n.t(
|
||||
"unblock_community"
|
||||
)}
|
||||
>
|
||||
<Icon icon="x" classes="icon-inline" />
|
||||
</button>
|
||||
|
@ -482,18 +484,18 @@ export class Settings extends Component<any, SettingsState> {
|
|||
|
||||
return (
|
||||
<>
|
||||
<h5>{i18n.t("settings")}</h5>
|
||||
<h5>{I18NextService.i18n.t("settings")}</h5>
|
||||
<form onSubmit={linkEvent(this, this.handleSaveSettingsSubmit)}>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-3 col-form-label" htmlFor="display-name">
|
||||
{i18n.t("display_name")}
|
||||
{I18NextService.i18n.t("display_name")}
|
||||
</label>
|
||||
<div className="col-sm-9">
|
||||
<input
|
||||
id="display-name"
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder={i18n.t("optional")}
|
||||
placeholder={I18NextService.i18n.t("optional")}
|
||||
value={this.state.saveUserSettingsForm.display_name}
|
||||
onInput={linkEvent(this, this.handleDisplayNameChange)}
|
||||
pattern="^(?!@)(.+)$"
|
||||
|
@ -503,7 +505,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-3 col-form-label" htmlFor="user-bio">
|
||||
{i18n.t("bio")}
|
||||
{I18NextService.i18n.t("bio")}
|
||||
</label>
|
||||
<div className="col-sm-9">
|
||||
<MarkdownTextArea
|
||||
|
@ -518,14 +520,14 @@ export class Settings extends Component<any, SettingsState> {
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-3 col-form-label" htmlFor="user-email">
|
||||
{i18n.t("email")}
|
||||
{I18NextService.i18n.t("email")}
|
||||
</label>
|
||||
<div className="col-sm-9">
|
||||
<input
|
||||
type="email"
|
||||
id="user-email"
|
||||
className="form-control"
|
||||
placeholder={i18n.t("optional")}
|
||||
placeholder={I18NextService.i18n.t("optional")}
|
||||
value={this.state.saveUserSettingsForm.email}
|
||||
onInput={linkEvent(this, this.handleEmailChange)}
|
||||
minLength={3}
|
||||
|
@ -535,7 +537,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
<div className="mb-3 row">
|
||||
<label className="col-sm-3 col-form-label" htmlFor="matrix-user-id">
|
||||
<a href={elementUrl} rel={relTags}>
|
||||
{i18n.t("matrix_user_id")}
|
||||
{I18NextService.i18n.t("matrix_user_id")}
|
||||
</a>
|
||||
</label>
|
||||
<div className="col-sm-9">
|
||||
|
@ -552,11 +554,11 @@ export class Settings extends Component<any, SettingsState> {
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-3 col-form-label">
|
||||
{i18n.t("avatar")}
|
||||
{I18NextService.i18n.t("avatar")}
|
||||
</label>
|
||||
<div className="col-sm-9">
|
||||
<ImageUploadForm
|
||||
uploadTitle={i18n.t("upload_avatar")}
|
||||
uploadTitle={I18NextService.i18n.t("upload_avatar")}
|
||||
imageSrc={this.state.saveUserSettingsForm.avatar}
|
||||
onUpload={this.handleAvatarUpload}
|
||||
onRemove={this.handleAvatarRemove}
|
||||
|
@ -566,11 +568,11 @@ export class Settings extends Component<any, SettingsState> {
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-3 col-form-label">
|
||||
{i18n.t("banner")}
|
||||
{I18NextService.i18n.t("banner")}
|
||||
</label>
|
||||
<div className="col-sm-9">
|
||||
<ImageUploadForm
|
||||
uploadTitle={i18n.t("upload_banner")}
|
||||
uploadTitle={I18NextService.i18n.t("upload_banner")}
|
||||
imageSrc={this.state.saveUserSettingsForm.banner}
|
||||
onUpload={this.handleBannerUpload}
|
||||
onRemove={this.handleBannerRemove}
|
||||
|
@ -579,7 +581,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-3 form-label" htmlFor="user-language">
|
||||
{i18n.t("interface_language")}
|
||||
{I18NextService.i18n.t("interface_language")}
|
||||
</label>
|
||||
<div className="col-sm-9">
|
||||
<select
|
||||
|
@ -589,9 +591,11 @@ export class Settings extends Component<any, SettingsState> {
|
|||
className="form-select d-inline-block w-auto"
|
||||
>
|
||||
<option disabled aria-hidden="true">
|
||||
{i18n.t("interface_language")}
|
||||
{I18NextService.i18n.t("interface_language")}
|
||||
</option>
|
||||
<option value="browser">
|
||||
{I18NextService.i18n.t("browser_default")}
|
||||
</option>
|
||||
<option value="browser">{i18n.t("browser_default")}</option>
|
||||
<option disabled aria-hidden="true">
|
||||
──
|
||||
</option>
|
||||
|
@ -616,7 +620,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
/>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-3 col-form-label" htmlFor="user-theme">
|
||||
{i18n.t("theme")}
|
||||
{I18NextService.i18n.t("theme")}
|
||||
</label>
|
||||
<div className="col-sm-9">
|
||||
<select
|
||||
|
@ -626,9 +630,11 @@ export class Settings extends Component<any, SettingsState> {
|
|||
className="form-select d-inline-block w-auto"
|
||||
>
|
||||
<option disabled aria-hidden="true">
|
||||
{i18n.t("theme")}
|
||||
{I18NextService.i18n.t("theme")}
|
||||
</option>
|
||||
<option value="browser">
|
||||
{I18NextService.i18n.t("browser_default")}
|
||||
</option>
|
||||
<option value="browser">{i18n.t("browser_default")}</option>
|
||||
{this.state.themeList.map(theme => (
|
||||
<option key={theme} value={theme}>
|
||||
{theme}
|
||||
|
@ -638,7 +644,9 @@ export class Settings extends Component<any, SettingsState> {
|
|||
</div>
|
||||
</div>
|
||||
<form className="mb-3 row">
|
||||
<label className="col-sm-3 col-form-label">{i18n.t("type")}</label>
|
||||
<label className="col-sm-3 col-form-label">
|
||||
{I18NextService.i18n.t("type")}
|
||||
</label>
|
||||
<div className="col-sm-9">
|
||||
<ListingTypeSelect
|
||||
type_={
|
||||
|
@ -653,7 +661,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
</form>
|
||||
<form className="mb-3 row">
|
||||
<label className="col-sm-3 col-form-label">
|
||||
{i18n.t("sort_type")}
|
||||
{I18NextService.i18n.t("sort_type")}
|
||||
</label>
|
||||
<div className="col-sm-9">
|
||||
<SortSelect
|
||||
|
@ -674,7 +682,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
onChange={linkEvent(this, this.handleShowNsfwChange)}
|
||||
/>
|
||||
<label className="form-check-label" htmlFor="user-show-nsfw">
|
||||
{i18n.t("show_nsfw")}
|
||||
{I18NextService.i18n.t("show_nsfw")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -688,7 +696,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
onChange={linkEvent(this, this.handleShowScoresChange)}
|
||||
/>
|
||||
<label className="form-check-label" htmlFor="user-show-scores">
|
||||
{i18n.t("show_scores")}
|
||||
{I18NextService.i18n.t("show_scores")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -702,7 +710,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
onChange={linkEvent(this, this.handleShowAvatarsChange)}
|
||||
/>
|
||||
<label className="form-check-label" htmlFor="user-show-avatars">
|
||||
{i18n.t("show_avatars")}
|
||||
{I18NextService.i18n.t("show_avatars")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -716,7 +724,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
onChange={linkEvent(this, this.handleBotAccount)}
|
||||
/>
|
||||
<label className="form-check-label" htmlFor="user-bot-account">
|
||||
{i18n.t("bot_account")}
|
||||
{I18NextService.i18n.t("bot_account")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -733,7 +741,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
className="form-check-label"
|
||||
htmlFor="user-show-bot-accounts"
|
||||
>
|
||||
{i18n.t("show_bot_accounts")}
|
||||
{I18NextService.i18n.t("show_bot_accounts")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -750,7 +758,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
className="form-check-label"
|
||||
htmlFor="user-show-read-posts"
|
||||
>
|
||||
{i18n.t("show_read_posts")}
|
||||
{I18NextService.i18n.t("show_read_posts")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -767,7 +775,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
className="form-check-label"
|
||||
htmlFor="user-show-new-post-notifs"
|
||||
>
|
||||
{i18n.t("show_new_post_notifs")}
|
||||
{I18NextService.i18n.t("show_new_post_notifs")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -790,7 +798,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
className="form-check-label"
|
||||
htmlFor="user-send-notifications-to-email"
|
||||
>
|
||||
{i18n.t("send_notifications_to_email")}
|
||||
{I18NextService.i18n.t("send_notifications_to_email")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -800,7 +808,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
{this.state.saveRes.state === "loading" ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
capitalizeFirstLetter(i18n.t("save"))
|
||||
capitalizeFirstLetter(I18NextService.i18n.t("save"))
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -813,12 +821,12 @@ export class Settings extends Component<any, SettingsState> {
|
|||
this.handleDeleteAccountShowConfirmToggle
|
||||
)}
|
||||
>
|
||||
{i18n.t("delete_account")}
|
||||
{I18NextService.i18n.t("delete_account")}
|
||||
</button>
|
||||
{this.state.deleteAccountShowConfirm && (
|
||||
<>
|
||||
<div className="my-2 alert alert-danger" role="alert">
|
||||
{i18n.t("delete_account_confirm")}
|
||||
{I18NextService.i18n.t("delete_account_confirm")}
|
||||
</div>
|
||||
<input
|
||||
type="password"
|
||||
|
@ -839,7 +847,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
{this.state.deleteAccountRes.state === "loading" ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
capitalizeFirstLetter(i18n.t("delete"))
|
||||
capitalizeFirstLetter(I18NextService.i18n.t("delete"))
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
|
@ -849,7 +857,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
this.handleDeleteAccountShowConfirmToggle
|
||||
)}
|
||||
>
|
||||
{i18n.t("cancel")}
|
||||
{I18NextService.i18n.t("cancel")}
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
|
@ -876,7 +884,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
onChange={linkEvent(this, this.handleGenerateTotp)}
|
||||
/>
|
||||
<label className="form-check-label" htmlFor="user-generate-totp">
|
||||
{i18n.t("set_up_two_factor")}
|
||||
{I18NextService.i18n.t("set_up_two_factor")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -886,7 +894,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
<>
|
||||
<div>
|
||||
<a className="btn btn-secondary mb-2" href={totpUrl}>
|
||||
{i18n.t("two_factor_link")}
|
||||
{I18NextService.i18n.t("two_factor_link")}
|
||||
</a>
|
||||
</div>
|
||||
<div className="input-group mb-3">
|
||||
|
@ -901,7 +909,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
onChange={linkEvent(this, this.handleRemoveTotp)}
|
||||
/>
|
||||
<label className="form-check-label" htmlFor="user-remove-totp">
|
||||
{i18n.t("remove_two_factor")}
|
||||
{I18NextService.i18n.t("remove_two_factor")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1050,7 +1058,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
// Coerce false to undefined here, so it won't generate it.
|
||||
const checked: boolean | undefined = event.target.checked || undefined;
|
||||
if (checked) {
|
||||
toast(i18n.t("two_factor_setup_instructions"));
|
||||
toast(I18NextService.i18n.t("two_factor_setup_instructions"));
|
||||
}
|
||||
i.setState(s => ((s.saveUserSettingsForm.generate_totp_2fa = checked), s));
|
||||
}
|
||||
|
@ -1078,7 +1086,9 @@ export class Settings extends Component<any, SettingsState> {
|
|||
|
||||
handleInterfaceLangChange(i: Settings, event: any) {
|
||||
const newLang = event.target.value ?? "browser";
|
||||
i18n.changeLanguage(newLang === "browser" ? navigator.languages : newLang);
|
||||
I18NextService.i18n.changeLanguage(
|
||||
newLang === "browser" ? navigator.languages : newLang
|
||||
);
|
||||
|
||||
i.setState(
|
||||
s => ((s.saveUserSettingsForm.interface_language = event.target.value), s)
|
||||
|
@ -1168,7 +1178,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
if (saveRes.state === "success") {
|
||||
UserService.Instance.login(saveRes.data);
|
||||
location.reload();
|
||||
toast(i18n.t("saved"));
|
||||
toast(I18NextService.i18n.t("saved"));
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
|
@ -1191,7 +1201,7 @@ export class Settings extends Component<any, SettingsState> {
|
|||
if (changePasswordRes.state === "success") {
|
||||
UserService.Instance.login(changePasswordRes.data);
|
||||
window.scrollTo(0, 0);
|
||||
toast(i18n.t("password_changed"));
|
||||
toast(I18NextService.i18n.t("password_changed"));
|
||||
}
|
||||
|
||||
i.setState({ changePasswordRes });
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { setIsoData } from "@utils/app";
|
||||
import { Component } from "inferno";
|
||||
import { GetSiteResponse, VerifyEmailResponse } from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { toast } from "../../toast";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
|
@ -36,7 +36,7 @@ export class VerifyEmail extends Component<any, State> {
|
|||
});
|
||||
|
||||
if (this.state.verifyRes.state == "success") {
|
||||
toast(i18n.t("email_verified"));
|
||||
toast(I18NextService.i18n.t("email_verified"));
|
||||
this.props.history.push("/login");
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ export class VerifyEmail extends Component<any, State> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
return `${i18n.t("verify_email")} - ${
|
||||
return `${I18NextService.i18n.t("verify_email")} - ${
|
||||
this.state.siteRes.site_view.site.name
|
||||
}`;
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ export class VerifyEmail extends Component<any, State> {
|
|||
/>
|
||||
<div className="row">
|
||||
<div className="col-12 col-lg-6 offset-lg-3 mb-4">
|
||||
<h5>{i18n.t("verify_email")}</h5>
|
||||
<h5>{I18NextService.i18n.t("verify_email")}</h5>
|
||||
{this.state.verifyRes.state == "loading" && (
|
||||
<h5>
|
||||
<Spinner large />
|
||||
|
|
|
@ -11,9 +11,8 @@ import {
|
|||
GetSiteResponse,
|
||||
ListCommunitiesResponse,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { InitialFetchRequest, PostFormParams } from "../../interfaces";
|
||||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import { FirstLoadService, I18NextService } from "../../services";
|
||||
import {
|
||||
HttpService,
|
||||
RequestState,
|
||||
|
@ -143,7 +142,7 @@ export class CreatePost extends Component<
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
return `${i18n.t("create_post")} - ${
|
||||
return `${I18NextService.i18n.t("create_post")} - ${
|
||||
this.state.siteRes.site_view.site.name
|
||||
}`;
|
||||
}
|
||||
|
@ -171,7 +170,7 @@ export class CreatePost extends Component<
|
|||
id="createPostForm"
|
||||
className="col-12 col-lg-6 offset-lg-3 mb-4"
|
||||
>
|
||||
<h1 className="h4">{i18n.t("create_post")}</h1>
|
||||
<h1 className="h4">{I18NextService.i18n.t("create_post")}</h1>
|
||||
<PostForm
|
||||
onCreate={this.handlePostCreate}
|
||||
params={locationState}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Component, linkEvent } from "inferno";
|
|||
import { Post } from "lemmy-js-client";
|
||||
import * as sanitizeHtml from "sanitize-html";
|
||||
import { relTags } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { Icon } from "../common/icon";
|
||||
|
||||
interface MetadataCardProps {
|
||||
|
@ -66,7 +66,7 @@ export class MetadataCard extends Component<
|
|||
className="mt-2 btn btn-secondary text-monospace"
|
||||
onClick={linkEvent(this, this.handleIframeExpand)}
|
||||
>
|
||||
{i18n.t("expand_here")}
|
||||
{I18NextService.i18n.t("expand_here")}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
@ -75,10 +75,14 @@ export class MetadataCard extends Component<
|
|||
</div>
|
||||
)}
|
||||
{this.state.expanded && post.embed_video_url && (
|
||||
<div className="ratio ratio-16x9">
|
||||
<iframe
|
||||
allowFullScreen
|
||||
className="post-metadata-iframe"
|
||||
src={post.embed_video_url}
|
||||
title={post.embed_title}
|
||||
></iframe>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -31,9 +31,8 @@ import {
|
|||
trendingFetchLimit,
|
||||
webArchiveUrl,
|
||||
} from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import { PostFormParams } from "../../interfaces";
|
||||
import { UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { setupTippy } from "../../tippy";
|
||||
import { toast } from "../../toast";
|
||||
|
@ -342,7 +341,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
/>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2 col-form-label" htmlFor="post-url">
|
||||
{i18n.t("url")}
|
||||
{I18NextService.i18n.t("url")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<input
|
||||
|
@ -360,7 +359,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
className={`${
|
||||
UserService.Instance.myUserInfo && "pointer"
|
||||
} d-inline-block float-right text-muted font-weight-bold`}
|
||||
data-tippy-content={i18n.t("upload_image")}
|
||||
data-tippy-content={I18NextService.i18n.t("upload_image")}
|
||||
>
|
||||
<Icon icon="image" classes="icon-inline" />
|
||||
</label>
|
||||
|
@ -381,7 +380,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
className="me-2 d-inline-block float-right text-muted small font-weight-bold"
|
||||
rel={relTags}
|
||||
>
|
||||
archive.org {i18n.t("archive_link")}
|
||||
archive.org {I18NextService.i18n.t("archive_link")}
|
||||
</a>
|
||||
<a
|
||||
href={`${ghostArchiveUrl}/search?term=${encodeURIComponent(
|
||||
|
@ -390,7 +389,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
className="me-2 d-inline-block float-right text-muted small font-weight-bold"
|
||||
rel={relTags}
|
||||
>
|
||||
ghostarchive.org {i18n.t("archive_link")}
|
||||
ghostarchive.org {I18NextService.i18n.t("archive_link")}
|
||||
</a>
|
||||
<a
|
||||
href={`${archiveTodayUrl}/?run=1&url=${encodeURIComponent(
|
||||
|
@ -399,7 +398,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
className="me-2 d-inline-block float-right text-muted small font-weight-bold"
|
||||
rel={relTags}
|
||||
>
|
||||
archive.today {i18n.t("archive_link")}
|
||||
archive.today {I18NextService.i18n.t("archive_link")}
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
|
@ -411,17 +410,17 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
<button
|
||||
className="btn btn-danger btn-sm mt-2"
|
||||
onClick={linkEvent(this, handleImageDelete)}
|
||||
aria-label={i18n.t("delete")}
|
||||
data-tippy-content={i18n.t("delete")}
|
||||
aria-label={I18NextService.i18n.t("delete")}
|
||||
data-tippy-content={I18NextService.i18n.t("delete")}
|
||||
>
|
||||
<Icon icon="x" classes="icon-inline me-1" />
|
||||
{capitalizeFirstLetter(i18n.t("delete"))}
|
||||
{capitalizeFirstLetter(I18NextService.i18n.t("delete"))}
|
||||
</button>
|
||||
)}
|
||||
{this.props.crossPosts && this.props.crossPosts.length > 0 && (
|
||||
<>
|
||||
<div className="my-1 text-muted small font-weight-bold">
|
||||
{i18n.t("cross_posts")}
|
||||
{I18NextService.i18n.t("cross_posts")}
|
||||
</div>
|
||||
<PostListings
|
||||
showCommunity
|
||||
|
@ -455,7 +454,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2 col-form-label" htmlFor="post-title">
|
||||
{i18n.t("title")}
|
||||
{I18NextService.i18n.t("title")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<textarea
|
||||
|
@ -472,7 +471,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
/>
|
||||
{!validTitle(this.state.form.name) && (
|
||||
<div className="invalid-feedback">
|
||||
{i18n.t("invalid_post_title")}
|
||||
{I18NextService.i18n.t("invalid_post_title")}
|
||||
</div>
|
||||
)}
|
||||
{this.renderSuggestedPosts()}
|
||||
|
@ -480,7 +479,9 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
</div>
|
||||
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2 col-form-label">{i18n.t("body")}</label>
|
||||
<label className="col-sm-2 col-form-label">
|
||||
{I18NextService.i18n.t("body")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<MarkdownTextArea
|
||||
initialContent={this.state.form.body}
|
||||
|
@ -501,7 +502,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
{!this.props.post_view && (
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2 col-form-label" htmlFor="post-community">
|
||||
{i18n.t("community")}
|
||||
{I18NextService.i18n.t("community")}
|
||||
</label>
|
||||
<div className="col-sm-10">
|
||||
<SearchableSelect
|
||||
|
@ -509,7 +510,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
value={this.state.form.community_id}
|
||||
options={[
|
||||
{
|
||||
label: i18n.t("select_a_community"),
|
||||
label: I18NextService.i18n.t("select_a_community"),
|
||||
value: "",
|
||||
disabled: true,
|
||||
} as Choice,
|
||||
|
@ -530,7 +531,9 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
checked={this.state.form.nsfw}
|
||||
onChange={linkEvent(this, handlePostNsfwChange)}
|
||||
/>
|
||||
<label className="form-check-label">{i18n.t("nsfw")}</label>
|
||||
<label className="form-check-label">
|
||||
{I18NextService.i18n.t("nsfw")}
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
<input
|
||||
|
@ -553,9 +556,9 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
{this.state.loading ? (
|
||||
<Spinner />
|
||||
) : this.props.post_view ? (
|
||||
capitalizeFirstLetter(i18n.t("save"))
|
||||
capitalizeFirstLetter(I18NextService.i18n.t("save"))
|
||||
) : (
|
||||
capitalizeFirstLetter(i18n.t("create"))
|
||||
capitalizeFirstLetter(I18NextService.i18n.t("create"))
|
||||
)}
|
||||
</button>
|
||||
{this.props.post_view && (
|
||||
|
@ -564,7 +567,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
className="btn btn-secondary"
|
||||
onClick={linkEvent(this, handleCancel)}
|
||||
>
|
||||
{i18n.t("cancel")}
|
||||
{I18NextService.i18n.t("cancel")}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
@ -590,7 +593,8 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
copySuggestedTitle
|
||||
)}
|
||||
>
|
||||
{i18n.t("copy_suggested_title", { title: "" })} {suggestedTitle}
|
||||
{I18NextService.i18n.t("copy_suggested_title", { title: "" })}{" "}
|
||||
{suggestedTitle}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
@ -610,7 +614,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
suggestedPosts.length > 0 && (
|
||||
<>
|
||||
<div className="my-1 text-muted small font-weight-bold">
|
||||
{i18n.t("related_posts")}
|
||||
{I18NextService.i18n.t("related_posts")}
|
||||
</div>
|
||||
<PostListings
|
||||
showCommunity
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
import { myAuthRequired, newVote, showScores } from "@utils/app";
|
||||
import { canShare, share } from "@utils/browser";
|
||||
import { futureDaysToUnixTime, hostname, numToSI } from "@utils/helpers";
|
||||
import { getExternalHost, getHttpBase } from "@utils/env";
|
||||
import {
|
||||
capitalizeFirstLetter,
|
||||
futureDaysToUnixTime,
|
||||
hostname,
|
||||
numToSI,
|
||||
} from "@utils/helpers";
|
||||
import { isImage, isVideo } from "@utils/media";
|
||||
import {
|
||||
amAdmin,
|
||||
|
@ -38,11 +44,9 @@ import {
|
|||
TransferCommunity,
|
||||
} from "lemmy-js-client";
|
||||
import { relTags } from "../../config";
|
||||
import { getExternalHost, getHttpBase } from "../../env";
|
||||
import { i18n } from "../../i18next";
|
||||
import { BanType, PostFormParams, PurgeType, VoteType } from "../../interfaces";
|
||||
import { mdNoImages, mdToHtml, mdToHtmlInline } from "../../markdown";
|
||||
import { UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { setupTippy } from "../../tippy";
|
||||
import { Icon, PurgeWarning, Spinner } from "../common/icon";
|
||||
import { MomentTime } from "../common/moment-time";
|
||||
|
@ -235,7 +239,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
}
|
||||
|
||||
get img() {
|
||||
return this.imageSrc ? (
|
||||
if (this.imageSrc) {
|
||||
return (
|
||||
<>
|
||||
<div className="offset-sm-3 my-2 d-none d-sm-block">
|
||||
<a href={this.imageSrc} className="d-inline-block">
|
||||
|
@ -251,11 +256,25 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
</a>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
);
|
||||
}
|
||||
|
||||
const { post } = this.postView;
|
||||
const { url } = post;
|
||||
|
||||
if (url && isVideo(url)) {
|
||||
return (
|
||||
<div className="embed-responsive mt-3">
|
||||
<video muted controls className="embed-responsive-item col-12">
|
||||
<source src={url} type="video/mp4" />
|
||||
</video>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <></>;
|
||||
}
|
||||
|
||||
imgThumb(src: string) {
|
||||
const post_view = this.postView;
|
||||
return (
|
||||
|
@ -298,9 +317,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
<a
|
||||
href={this.imageSrc}
|
||||
className="text-body d-inline-block position-relative mb-2"
|
||||
data-tippy-content={i18n.t("expand_here")}
|
||||
data-tippy-content={I18NextService.i18n.t("expand_here")}
|
||||
onClick={linkEvent(this, this.handleImageExpandClick)}
|
||||
aria-label={i18n.t("expand_here")}
|
||||
aria-label={I18NextService.i18n.t("expand_here")}
|
||||
>
|
||||
{this.imgThumb(this.imageSrc)}
|
||||
<Icon icon="image" classes="mini-overlay" />
|
||||
|
@ -321,17 +340,19 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
} else if (url) {
|
||||
if (!this.props.hideImage && isVideo(url)) {
|
||||
return (
|
||||
<div className="embed-responsive embed-responsive-16by9">
|
||||
<video
|
||||
playsInline
|
||||
muted
|
||||
loop
|
||||
controls
|
||||
className="embed-responsive-item"
|
||||
<a
|
||||
className="text-body"
|
||||
href={url}
|
||||
title={url}
|
||||
rel={relTags}
|
||||
data-tippy-content={I18NextService.i18n.t("expand_here")}
|
||||
onClick={linkEvent(this, this.handleImageExpandClick)}
|
||||
aria-label={I18NextService.i18n.t("expand_here")}
|
||||
>
|
||||
<source src={url} type="video/mp4" />
|
||||
</video>
|
||||
<div className="thumbnail rounded bg-light d-flex justify-content-center">
|
||||
<Icon icon="play" classes="d-flex align-items-center" />
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
|
@ -347,7 +368,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
<Link
|
||||
className="text-body"
|
||||
to={`/post/${post.id}`}
|
||||
title={i18n.t("comments")}
|
||||
title={I18NextService.i18n.t("comments")}
|
||||
>
|
||||
<div className="thumbnail rounded bg-light d-flex justify-content-center">
|
||||
<Icon icon="message-square" classes="d-flex align-items-center" />
|
||||
|
@ -363,20 +384,25 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
<span className="small">
|
||||
<PersonListing person={post_view.creator} />
|
||||
{this.creatorIsMod_ && (
|
||||
<span className="mx-1 badge text-bg-light">{i18n.t("mod")}</span>
|
||||
<span className="mx-1 badge text-bg-light">
|
||||
{I18NextService.i18n.t("mod")}
|
||||
</span>
|
||||
)}
|
||||
{this.creatorIsAdmin_ && (
|
||||
<span className="mx-1 badge text-bg-light">{i18n.t("admin")}</span>
|
||||
<span className="mx-1 badge text-bg-light">
|
||||
{I18NextService.i18n.t("admin")}
|
||||
</span>
|
||||
)}
|
||||
{post_view.creator.bot_account && (
|
||||
<span className="mx-1 badge text-bg-light">
|
||||
{i18n.t("bot_account").toLowerCase()}
|
||||
{I18NextService.i18n.t("bot_account").toLowerCase()}
|
||||
</span>
|
||||
)}
|
||||
{this.props.showCommunity && (
|
||||
<>
|
||||
{" "}
|
||||
{i18n.t("to")} <CommunityLink community={post_view.community} />
|
||||
{I18NextService.i18n.t("to")}{" "}
|
||||
<CommunityLink community={post_view.community} />
|
||||
</>
|
||||
)}
|
||||
{post_view.post.language_id !== 0 && (
|
||||
|
@ -405,8 +431,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
this.postView.my_vote == 1 ? "text-info" : "text-muted"
|
||||
}`}
|
||||
onClick={linkEvent(this, this.handleUpvote)}
|
||||
data-tippy-content={i18n.t("upvote")}
|
||||
aria-label={i18n.t("upvote")}
|
||||
data-tippy-content={I18NextService.i18n.t("upvote")}
|
||||
aria-label={I18NextService.i18n.t("upvote")}
|
||||
aria-pressed={this.postView.my_vote === 1}
|
||||
>
|
||||
{this.state.upvoteLoading ? (
|
||||
|
@ -431,8 +457,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
this.postView.my_vote == -1 ? "text-danger" : "text-muted"
|
||||
}`}
|
||||
onClick={linkEvent(this, this.handleDownvote)}
|
||||
data-tippy-content={i18n.t("downvote")}
|
||||
aria-label={i18n.t("downvote")}
|
||||
data-tippy-content={I18NextService.i18n.t("downvote")}
|
||||
aria-label={I18NextService.i18n.t("downvote")}
|
||||
aria-pressed={this.postView.my_vote === -1}
|
||||
>
|
||||
{this.state.downvoteLoading ? (
|
||||
|
@ -456,7 +482,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
: "text-primary"
|
||||
}`}
|
||||
to={`/post/${post.id}`}
|
||||
title={i18n.t("comments")}
|
||||
title={I18NextService.i18n.t("comments")}
|
||||
>
|
||||
<span
|
||||
className="d-inline"
|
||||
|
@ -494,7 +520,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
(post.thumbnail_url && (
|
||||
<button
|
||||
className="btn btn-sm text-monospace text-muted d-inline-block"
|
||||
data-tippy-content={i18n.t("expand_here")}
|
||||
data-tippy-content={I18NextService.i18n.t("expand_here")}
|
||||
onClick={linkEvent(this, this.handleImageExpandClick)}
|
||||
>
|
||||
<Icon
|
||||
|
@ -507,13 +533,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
))}
|
||||
{post.removed && (
|
||||
<small className="ms-2 badge text-bg-secondary">
|
||||
{i18n.t("removed")}
|
||||
{I18NextService.i18n.t("removed")}
|
||||
</small>
|
||||
)}
|
||||
{post.deleted && (
|
||||
<small
|
||||
className="unselectable pointer ms-2 text-muted font-italic"
|
||||
data-tippy-content={i18n.t("deleted")}
|
||||
data-tippy-content={I18NextService.i18n.t("deleted")}
|
||||
>
|
||||
<Icon icon="trash" classes="icon-inline text-danger" />
|
||||
</small>
|
||||
|
@ -521,7 +547,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
{post.locked && (
|
||||
<small
|
||||
className="unselectable pointer ms-2 text-muted font-italic"
|
||||
data-tippy-content={i18n.t("locked")}
|
||||
data-tippy-content={I18NextService.i18n.t("locked")}
|
||||
>
|
||||
<Icon icon="lock" classes="icon-inline text-danger" />
|
||||
</small>
|
||||
|
@ -529,8 +555,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
{post.featured_community && (
|
||||
<small
|
||||
className="unselectable pointer ms-2 text-muted font-italic"
|
||||
data-tippy-content={i18n.t("featured_in_community")}
|
||||
aria-label={i18n.t("featured_in_community")}
|
||||
data-tippy-content={I18NextService.i18n.t(
|
||||
"featured_in_community"
|
||||
)}
|
||||
aria-label={I18NextService.i18n.t("featured_in_community")}
|
||||
>
|
||||
<Icon icon="pin" classes="icon-inline text-primary" />
|
||||
</small>
|
||||
|
@ -538,15 +566,15 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
{post.featured_local && (
|
||||
<small
|
||||
className="unselectable pointer ms-2 text-muted font-italic"
|
||||
data-tippy-content={i18n.t("featured_in_local")}
|
||||
aria-label={i18n.t("featured_in_local")}
|
||||
data-tippy-content={I18NextService.i18n.t("featured_in_local")}
|
||||
aria-label={I18NextService.i18n.t("featured_in_local")}
|
||||
>
|
||||
<Icon icon="pin" classes="icon-inline text-secondary" />
|
||||
</small>
|
||||
)}
|
||||
{post.nsfw && (
|
||||
<small className="ms-2 badge text-bg-danger">
|
||||
{i18n.t("nsfw")}
|
||||
{I18NextService.i18n.t("nsfw")}
|
||||
</small>
|
||||
)}
|
||||
</div>
|
||||
|
@ -580,7 +608,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
return dupes && dupes.length > 0 ? (
|
||||
<ul className="list-inline mb-1 small text-muted">
|
||||
<>
|
||||
<li className="list-inline-item me-2">{i18n.t("cross_posted_to")}</li>
|
||||
<li className="list-inline-item me-2">
|
||||
{I18NextService.i18n.t("cross_posted_to")}
|
||||
</li>
|
||||
{dupes.map(pv => (
|
||||
<li key={pv.post.id} className="list-inline-item me-2">
|
||||
<Link to={`/post/${pv.post.id}`}>
|
||||
|
@ -615,7 +645,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
{!post.local && (
|
||||
<a
|
||||
className="btn btn-sm btn-animate text-muted py-0"
|
||||
title={i18n.t("link")}
|
||||
title={I18NextService.i18n.t("link")}
|
||||
href={post.ap_id}
|
||||
>
|
||||
<Icon icon="fedilink" inline />
|
||||
|
@ -674,11 +704,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
<button
|
||||
className="btn btn-sm btn-animate text-muted py-0 dropdown-toggle"
|
||||
onClick={linkEvent(this, this.handleShowAdvanced)}
|
||||
data-tippy-content={i18n.t("more")}
|
||||
data-tippy-content={I18NextService.i18n.t("more")}
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false"
|
||||
aria-controls="advancedButtonsDropdown"
|
||||
aria-label={i18n.t("more")}
|
||||
aria-label={I18NextService.i18n.t("more")}
|
||||
>
|
||||
<Icon icon="more-vertical" inline />
|
||||
</button>
|
||||
|
@ -718,7 +748,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
|
||||
get commentsButton() {
|
||||
const post_view = this.postView;
|
||||
const title = i18n.t("number_of_comments", {
|
||||
const title = I18NextService.i18n.t("number_of_comments", {
|
||||
count: Number(post_view.counts.comments),
|
||||
formattedCount: Number(post_view.counts.comments),
|
||||
});
|
||||
|
@ -734,7 +764,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
{post_view.counts.comments}
|
||||
{this.unreadCount && (
|
||||
<span className="text-muted fst-italic">
|
||||
({this.unreadCount} {i18n.t("new")})
|
||||
({this.unreadCount} {I18NextService.i18n.t("new")})
|
||||
</span>
|
||||
)}
|
||||
</Link>
|
||||
|
@ -762,7 +792,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
}`}
|
||||
{...tippy}
|
||||
onClick={linkEvent(this, this.handleUpvote)}
|
||||
aria-label={i18n.t("upvote")}
|
||||
aria-label={I18NextService.i18n.t("upvote")}
|
||||
aria-pressed={this.postView.my_vote === 1}
|
||||
>
|
||||
{this.state.upvoteLoading ? (
|
||||
|
@ -785,7 +815,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
}`}
|
||||
onClick={linkEvent(this, this.handleDownvote)}
|
||||
{...tippy}
|
||||
aria-label={i18n.t("downvote")}
|
||||
aria-label={I18NextService.i18n.t("downvote")}
|
||||
aria-pressed={this.postView.my_vote === -1}
|
||||
>
|
||||
{this.state.downvoteLoading ? (
|
||||
|
@ -813,7 +843,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
|
||||
get saveButton() {
|
||||
const saved = this.postView.saved;
|
||||
const label = saved ? i18n.t("unsave") : i18n.t("save");
|
||||
const label = saved
|
||||
? I18NextService.i18n.t("unsave")
|
||||
: I18NextService.i18n.t("save");
|
||||
return (
|
||||
<button
|
||||
className="btn btn-sm btn-animate text-muted py-0"
|
||||
|
@ -846,9 +878,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
key: "",
|
||||
search: "",
|
||||
}}
|
||||
title={i18n.t("cross_post")}
|
||||
data-tippy-content={i18n.t("cross_post")}
|
||||
aria-label={i18n.t("cross_post")}
|
||||
title={I18NextService.i18n.t("cross_post")}
|
||||
data-tippy-content={I18NextService.i18n.t("cross_post")}
|
||||
aria-label={I18NextService.i18n.t("cross_post")}
|
||||
>
|
||||
<Icon icon="copy" inline />
|
||||
</Link>
|
||||
|
@ -860,10 +892,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
<button
|
||||
className="btn btn-link btn-sm d-flex align-items-center rounded-0 dropdown-item"
|
||||
onClick={linkEvent(this, this.handleShowReportDialog)}
|
||||
aria-label={i18n.t("show_report_dialog")}
|
||||
aria-label={I18NextService.i18n.t("show_report_dialog")}
|
||||
>
|
||||
<Icon classes="me-1" icon="flag" inline />
|
||||
{i18n.t("create_report")}
|
||||
{I18NextService.i18n.t("create_report")}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
@ -873,14 +905,14 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
<button
|
||||
className="btn btn-link btn-sm d-flex align-items-center rounded-0 dropdown-item"
|
||||
onClick={linkEvent(this, this.handleBlockPersonClick)}
|
||||
aria-label={i18n.t("block_user")}
|
||||
aria-label={I18NextService.i18n.t("block_user")}
|
||||
>
|
||||
{this.state.blockLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
<Icon classes="me-1" icon="slash" inline />
|
||||
)}
|
||||
{i18n.t("block_user")}
|
||||
{I18NextService.i18n.t("block_user")}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
@ -890,17 +922,19 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
<button
|
||||
className="btn btn-link btn-sm d-flex align-items-center rounded-0 dropdown-item"
|
||||
onClick={linkEvent(this, this.handleEditClick)}
|
||||
aria-label={i18n.t("edit")}
|
||||
aria-label={I18NextService.i18n.t("edit")}
|
||||
>
|
||||
<Icon classes="me-1" icon="edit" inline />
|
||||
{i18n.t("edit")}
|
||||
{I18NextService.i18n.t("edit")}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
get deleteButton() {
|
||||
const deleted = this.postView.post.deleted;
|
||||
const label = !deleted ? i18n.t("delete") : i18n.t("restore");
|
||||
const label = !deleted
|
||||
? I18NextService.i18n.t("delete")
|
||||
: I18NextService.i18n.t("restore");
|
||||
return (
|
||||
<button
|
||||
className="btn btn-link btn-sm d-flex align-items-center rounded-0 dropdown-item"
|
||||
|
@ -928,8 +962,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
<button
|
||||
className="btn btn-sm btn-animate text-muted py-0"
|
||||
onClick={linkEvent(this, this.handleViewSource)}
|
||||
data-tippy-content={i18n.t("view_source")}
|
||||
aria-label={i18n.t("view_source")}
|
||||
data-tippy-content={I18NextService.i18n.t("view_source")}
|
||||
aria-label={I18NextService.i18n.t("view_source")}
|
||||
>
|
||||
<Icon
|
||||
icon="file-text"
|
||||
|
@ -942,7 +976,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
|
||||
get lockButton() {
|
||||
const locked = this.postView.post.locked;
|
||||
const label = locked ? i18n.t("unlock") : i18n.t("lock");
|
||||
const label = locked
|
||||
? I18NextService.i18n.t("unlock")
|
||||
: I18NextService.i18n.t("lock");
|
||||
return (
|
||||
<button
|
||||
className="btn btn-link btn-sm d-flex align-items-center rounded-0 dropdown-item"
|
||||
|
@ -958,7 +994,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
classes={classNames("me-1", { "text-danger": locked })}
|
||||
inline
|
||||
/>
|
||||
{label}
|
||||
{capitalizeFirstLetter(label)}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
|
@ -968,13 +1004,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
get featureButtons() {
|
||||
const featuredCommunity = this.postView.post.featured_community;
|
||||
const labelCommunity = featuredCommunity
|
||||
? i18n.t("unfeature_from_community")
|
||||
: i18n.t("feature_in_community");
|
||||
? I18NextService.i18n.t("unfeature_from_community")
|
||||
: I18NextService.i18n.t("feature_in_community");
|
||||
|
||||
const featuredLocal = this.postView.post.featured_local;
|
||||
const labelLocal = featuredLocal
|
||||
? i18n.t("unfeature_from_local")
|
||||
: i18n.t("feature_in_local");
|
||||
? I18NextService.i18n.t("unfeature_from_local")
|
||||
: I18NextService.i18n.t("feature_in_local");
|
||||
return (
|
||||
<>
|
||||
<li>
|
||||
|
@ -995,7 +1031,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
})}
|
||||
inline
|
||||
/>
|
||||
{i18n.t("community")}
|
||||
{I18NextService.i18n.t("community")}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
|
@ -1019,7 +1055,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
})}
|
||||
inline
|
||||
/>
|
||||
{i18n.t("local")}
|
||||
{I18NextService.i18n.t("local")}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
|
@ -1043,9 +1079,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
{this.state.removeLoading ? (
|
||||
<Spinner />
|
||||
) : !removed ? (
|
||||
i18n.t("remove")
|
||||
I18NextService.i18n.t("remove")
|
||||
) : (
|
||||
i18n.t("restore")
|
||||
I18NextService.i18n.t("restore")
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
|
@ -1070,9 +1106,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
this,
|
||||
this.handleModBanFromCommunityShow
|
||||
)}
|
||||
aria-label={i18n.t("ban_from_community")}
|
||||
aria-label={I18NextService.i18n.t("ban_from_community")}
|
||||
>
|
||||
{i18n.t("ban_from_community")}
|
||||
{I18NextService.i18n.t("ban_from_community")}
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
|
@ -1081,9 +1117,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
this,
|
||||
this.handleModBanFromCommunitySubmit
|
||||
)}
|
||||
aria-label={i18n.t("unban")}
|
||||
aria-label={I18NextService.i18n.t("unban")}
|
||||
>
|
||||
{this.state.banLoading ? <Spinner /> : i18n.t("unban")}
|
||||
{this.state.banLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
I18NextService.i18n.t("unban")
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
{!post_view.creator_banned_from_community && (
|
||||
|
@ -1092,16 +1132,16 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
onClick={linkEvent(this, this.handleAddModToCommunity)}
|
||||
aria-label={
|
||||
this.creatorIsMod_
|
||||
? i18n.t("remove_as_mod")
|
||||
: i18n.t("appoint_as_mod")
|
||||
? I18NextService.i18n.t("remove_as_mod")
|
||||
: I18NextService.i18n.t("appoint_as_mod")
|
||||
}
|
||||
>
|
||||
{this.state.addModLoading ? (
|
||||
<Spinner />
|
||||
) : this.creatorIsMod_ ? (
|
||||
i18n.t("remove_as_mod")
|
||||
I18NextService.i18n.t("remove_as_mod")
|
||||
) : (
|
||||
i18n.t("appoint_as_mod")
|
||||
I18NextService.i18n.t("appoint_as_mod")
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
|
@ -1118,24 +1158,28 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
this,
|
||||
this.handleShowConfirmTransferCommunity
|
||||
)}
|
||||
aria-label={i18n.t("transfer_community")}
|
||||
aria-label={I18NextService.i18n.t("transfer_community")}
|
||||
>
|
||||
{i18n.t("transfer_community")}
|
||||
{I18NextService.i18n.t("transfer_community")}
|
||||
</button>
|
||||
) : (
|
||||
<>
|
||||
<button
|
||||
className="d-inline-block me-1 btn btn-link btn-animate text-muted py-0"
|
||||
aria-label={i18n.t("are_you_sure")}
|
||||
aria-label={I18NextService.i18n.t("are_you_sure")}
|
||||
>
|
||||
{i18n.t("are_you_sure")}
|
||||
{I18NextService.i18n.t("are_you_sure")}
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-link btn-animate text-muted py-0 d-inline-block me-1"
|
||||
aria-label={i18n.t("yes")}
|
||||
aria-label={I18NextService.i18n.t("yes")}
|
||||
onClick={linkEvent(this, this.handleTransferCommunity)}
|
||||
>
|
||||
{this.state.transferLoading ? <Spinner /> : i18n.t("yes")}
|
||||
{this.state.transferLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
I18NextService.i18n.t("yes")
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-link btn-animate text-muted py-0 d-inline-block"
|
||||
|
@ -1143,9 +1187,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
this,
|
||||
this.handleCancelShowConfirmTransferCommunity
|
||||
)}
|
||||
aria-label={i18n.t("no")}
|
||||
aria-label={I18NextService.i18n.t("no")}
|
||||
>
|
||||
{i18n.t("no")}
|
||||
{I18NextService.i18n.t("no")}
|
||||
</button>
|
||||
</>
|
||||
))}
|
||||
|
@ -1158,36 +1202,36 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
<button
|
||||
className="btn btn-link btn-animate text-muted py-0"
|
||||
onClick={linkEvent(this, this.handleModBanShow)}
|
||||
aria-label={i18n.t("ban_from_site")}
|
||||
aria-label={I18NextService.i18n.t("ban_from_site")}
|
||||
>
|
||||
{i18n.t("ban_from_site")}
|
||||
{I18NextService.i18n.t("ban_from_site")}
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
className="btn btn-link btn-animate text-muted py-0"
|
||||
onClick={linkEvent(this, this.handleModBanSubmit)}
|
||||
aria-label={i18n.t("unban_from_site")}
|
||||
aria-label={I18NextService.i18n.t("unban_from_site")}
|
||||
>
|
||||
{this.state.banLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
i18n.t("unban_from_site")
|
||||
I18NextService.i18n.t("unban_from_site")
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
className="btn btn-link btn-animate text-muted py-0"
|
||||
onClick={linkEvent(this, this.handlePurgePersonShow)}
|
||||
aria-label={i18n.t("purge_user")}
|
||||
aria-label={I18NextService.i18n.t("purge_user")}
|
||||
>
|
||||
{i18n.t("purge_user")}
|
||||
{I18NextService.i18n.t("purge_user")}
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-link btn-animate text-muted py-0"
|
||||
onClick={linkEvent(this, this.handlePurgePostShow)}
|
||||
aria-label={i18n.t("purge_post")}
|
||||
aria-label={I18NextService.i18n.t("purge_post")}
|
||||
>
|
||||
{i18n.t("purge_post")}
|
||||
{I18NextService.i18n.t("purge_post")}
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
|
@ -1197,16 +1241,16 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
onClick={linkEvent(this, this.handleAddAdmin)}
|
||||
aria-label={
|
||||
this.creatorIsAdmin_
|
||||
? i18n.t("remove_as_admin")
|
||||
: i18n.t("appoint_as_admin")
|
||||
? I18NextService.i18n.t("remove_as_admin")
|
||||
: I18NextService.i18n.t("appoint_as_admin")
|
||||
}
|
||||
>
|
||||
{this.state.addAdminLoading ? (
|
||||
<Spinner />
|
||||
) : this.creatorIsAdmin_ ? (
|
||||
i18n.t("remove_as_admin")
|
||||
I18NextService.i18n.t("remove_as_admin")
|
||||
) : (
|
||||
i18n.t("appoint_as_admin")
|
||||
I18NextService.i18n.t("appoint_as_admin")
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
|
@ -1221,8 +1265,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
const post = this.postView;
|
||||
const purgeTypeText =
|
||||
this.state.purgeType == PurgeType.Post
|
||||
? i18n.t("purge_post")
|
||||
: `${i18n.t("purge")} ${post.creator.name}`;
|
||||
? I18NextService.i18n.t("purge_post")
|
||||
: `${I18NextService.i18n.t("purge")} ${post.creator.name}`;
|
||||
return (
|
||||
<>
|
||||
{this.state.showRemoveDialog && (
|
||||
|
@ -1234,22 +1278,26 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
className="visually-hidden"
|
||||
htmlFor="post-listing-remove-reason"
|
||||
>
|
||||
{i18n.t("reason")}
|
||||
{I18NextService.i18n.t("reason")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="post-listing-remove-reason"
|
||||
className="form-control me-2"
|
||||
placeholder={i18n.t("reason")}
|
||||
placeholder={I18NextService.i18n.t("reason")}
|
||||
value={this.state.removeReason}
|
||||
onInput={linkEvent(this, this.handleModRemoveReasonChange)}
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-secondary"
|
||||
aria-label={i18n.t("remove_post")}
|
||||
aria-label={I18NextService.i18n.t("remove_post")}
|
||||
>
|
||||
{this.state.removeLoading ? <Spinner /> : i18n.t("remove_post")}
|
||||
{this.state.removeLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
I18NextService.i18n.t("remove_post")
|
||||
)}
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
|
@ -1260,24 +1308,24 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
className="col-form-label"
|
||||
htmlFor="post-listing-ban-reason"
|
||||
>
|
||||
{i18n.t("reason")}
|
||||
{I18NextService.i18n.t("reason")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="post-listing-ban-reason"
|
||||
className="form-control me-2"
|
||||
placeholder={i18n.t("reason")}
|
||||
placeholder={I18NextService.i18n.t("reason")}
|
||||
value={this.state.banReason}
|
||||
onInput={linkEvent(this, this.handleModBanReasonChange)}
|
||||
/>
|
||||
<label className="col-form-label" htmlFor={`mod-ban-expires`}>
|
||||
{i18n.t("expires")}
|
||||
{I18NextService.i18n.t("expires")}
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
id={`mod-ban-expires`}
|
||||
className="form-control me-2"
|
||||
placeholder={i18n.t("number_of_days")}
|
||||
placeholder={I18NextService.i18n.t("number_of_days")}
|
||||
value={this.state.banExpireDays}
|
||||
onInput={linkEvent(this, this.handleModBanExpireDaysChange)}
|
||||
/>
|
||||
|
@ -1293,9 +1341,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
<label
|
||||
className="form-check-label"
|
||||
htmlFor="mod-ban-remove-data"
|
||||
title={i18n.t("remove_content_more")}
|
||||
title={I18NextService.i18n.t("remove_content_more")}
|
||||
>
|
||||
{i18n.t("remove_content")}
|
||||
{I18NextService.i18n.t("remove_content")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1303,19 +1351,19 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
{/* TODO hold off on expires until later */}
|
||||
{/* <div class="mb-3 row"> */}
|
||||
{/* <label class="col-form-label">Expires</label> */}
|
||||
{/* <input type="date" class="form-control me-2" placeholder={i18n.t('expires')} value={this.state.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */}
|
||||
{/* <input type="date" class="form-control me-2" placeholder={I18NextService.i18n.t('expires')} value={this.state.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */}
|
||||
{/* </div> */}
|
||||
<div className="mb-3 row">
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-secondary"
|
||||
aria-label={i18n.t("ban")}
|
||||
aria-label={I18NextService.i18n.t("ban")}
|
||||
>
|
||||
{this.state.banLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
<span>
|
||||
{i18n.t("ban")} {post.creator.name}
|
||||
{I18NextService.i18n.t("ban")} {post.creator.name}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
|
@ -1328,13 +1376,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
onSubmit={linkEvent(this, this.handleReportSubmit)}
|
||||
>
|
||||
<label className="visually-hidden" htmlFor="post-report-reason">
|
||||
{i18n.t("reason")}
|
||||
{I18NextService.i18n.t("reason")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="post-report-reason"
|
||||
className="form-control me-2"
|
||||
placeholder={i18n.t("reason")}
|
||||
placeholder={I18NextService.i18n.t("reason")}
|
||||
required
|
||||
value={this.state.reportReason}
|
||||
onInput={linkEvent(this, this.handleReportReasonChange)}
|
||||
|
@ -1342,9 +1390,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
<button
|
||||
type="submit"
|
||||
className="btn btn-secondary"
|
||||
aria-label={i18n.t("create_report")}
|
||||
aria-label={I18NextService.i18n.t("create_report")}
|
||||
>
|
||||
{this.state.reportLoading ? <Spinner /> : i18n.t("create_report")}
|
||||
{this.state.reportLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
I18NextService.i18n.t("create_report")
|
||||
)}
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
|
@ -1355,13 +1407,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
>
|
||||
<PurgeWarning />
|
||||
<label className="visually-hidden" htmlFor="purge-reason">
|
||||
{i18n.t("reason")}
|
||||
{I18NextService.i18n.t("reason")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="purge-reason"
|
||||
className="form-control me-2"
|
||||
placeholder={i18n.t("reason")}
|
||||
placeholder={I18NextService.i18n.t("reason")}
|
||||
value={this.state.purgeReason}
|
||||
onInput={linkEvent(this, this.handlePurgeReasonChange)}
|
||||
/>
|
||||
|
@ -1557,10 +1609,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
const body = post.body;
|
||||
|
||||
return body
|
||||
? `${i18n.t("cross_posted_from")} ${post.ap_id}\n\n${body.replace(
|
||||
/^/gm,
|
||||
"> "
|
||||
)}`
|
||||
? `${I18NextService.i18n.t("cross_posted_from")} ${
|
||||
post.ap_id
|
||||
}\n\n${body.replace(/^/gm, "> ")}`
|
||||
: undefined;
|
||||
}
|
||||
|
||||
|
@ -1822,17 +1873,17 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
}
|
||||
|
||||
get pointsTippy(): string {
|
||||
const points = i18n.t("number_of_points", {
|
||||
const points = I18NextService.i18n.t("number_of_points", {
|
||||
count: Number(this.postView.counts.score),
|
||||
formattedCount: Number(this.postView.counts.score),
|
||||
});
|
||||
|
||||
const upvotes = i18n.t("number_of_upvotes", {
|
||||
const upvotes = I18NextService.i18n.t("number_of_upvotes", {
|
||||
count: Number(this.postView.counts.upvotes),
|
||||
formattedCount: Number(this.postView.counts.upvotes),
|
||||
});
|
||||
|
||||
const downvotes = i18n.t("number_of_downvotes", {
|
||||
const downvotes = I18NextService.i18n.t("number_of_downvotes", {
|
||||
count: Number(this.postView.counts.downvotes),
|
||||
formattedCount: Number(this.postView.counts.downvotes),
|
||||
});
|
||||
|
|
|
@ -21,7 +21,7 @@ import {
|
|||
SavePost,
|
||||
TransferCommunity,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { PostListing } from "./post-listing";
|
||||
|
||||
interface PostListingsProps {
|
||||
|
@ -101,7 +101,7 @@ export class PostListings extends Component<PostListingsProps, any> {
|
|||
))
|
||||
) : (
|
||||
<>
|
||||
<div>{i18n.t("no_posts")}</div>
|
||||
<div>{I18NextService.i18n.t("no_posts")}</div>
|
||||
{this.props.showCommunity && (
|
||||
<T i18nKey="subscribe_to_communities">
|
||||
#<Link to="/communities">#</Link>
|
||||
|
|
|
@ -2,7 +2,7 @@ import { myAuthRequired } from "@utils/app";
|
|||
import { Component, InfernoNode, linkEvent } from "inferno";
|
||||
import { T } from "inferno-i18next-dess";
|
||||
import { PostReportView, PostView, ResolvePostReport } from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { Icon, Spinner } from "../common/icon";
|
||||
import { PersonListing } from "../person/person-listing";
|
||||
import { PostListing } from "./post-listing";
|
||||
|
@ -37,7 +37,7 @@ export class PostReport extends Component<PostReportProps, PostReportState> {
|
|||
const r = this.props.report;
|
||||
const resolver = r.resolver;
|
||||
const post = r.post;
|
||||
const tippyContent = i18n.t(
|
||||
const tippyContent = I18NextService.i18n.t(
|
||||
r.post_report.resolved ? "unresolve_report" : "resolve_report"
|
||||
);
|
||||
|
||||
|
@ -89,10 +89,11 @@ export class PostReport extends Component<PostReportProps, PostReportState> {
|
|||
onTransferCommunity={() => {}}
|
||||
/>
|
||||
<div>
|
||||
{i18n.t("reporter")}: <PersonListing person={r.creator} />
|
||||
{I18NextService.i18n.t("reporter")}:{" "}
|
||||
<PersonListing person={r.creator} />
|
||||
</div>
|
||||
<div>
|
||||
{i18n.t("reason")}: {r.post_report.reason}
|
||||
{I18NextService.i18n.t("reason")}: {r.post_report.reason}
|
||||
</div>
|
||||
{resolver && (
|
||||
<div>
|
||||
|
|
|
@ -76,14 +76,12 @@ import {
|
|||
TransferCommunity,
|
||||
} from "lemmy-js-client";
|
||||
import { commentTreeMaxDepth } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import {
|
||||
CommentNodeI,
|
||||
CommentViewType,
|
||||
InitialFetchRequest,
|
||||
} from "../../interfaces";
|
||||
import { UserService } from "../../services";
|
||||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { setupTippy } from "../../tippy";
|
||||
import { toast } from "../../toast";
|
||||
|
@ -400,7 +398,7 @@ export class Post extends Component<any, PostState> {
|
|||
className="btn btn-secondary d-inline-block mb-2 me-3"
|
||||
onClick={linkEvent(this, this.handleShowSidebarMobile)}
|
||||
>
|
||||
{i18n.t("sidebar")}{" "}
|
||||
{I18NextService.i18n.t("sidebar")}{" "}
|
||||
<Icon
|
||||
icon={
|
||||
this.state.showSidebarMobile
|
||||
|
@ -438,7 +436,7 @@ export class Post extends Component<any, PostState> {
|
|||
this.state.commentSort === "Hot" && "active"
|
||||
}`}
|
||||
>
|
||||
{i18n.t("hot")}
|
||||
{I18NextService.i18n.t("hot")}
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
|
@ -452,7 +450,7 @@ export class Post extends Component<any, PostState> {
|
|||
this.state.commentSort === "Top" && "active"
|
||||
}`}
|
||||
>
|
||||
{i18n.t("top")}
|
||||
{I18NextService.i18n.t("top")}
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
|
@ -466,7 +464,7 @@ export class Post extends Component<any, PostState> {
|
|||
this.state.commentSort === "New" && "active"
|
||||
}`}
|
||||
>
|
||||
{i18n.t("new")}
|
||||
{I18NextService.i18n.t("new")}
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
|
@ -480,7 +478,7 @@ export class Post extends Component<any, PostState> {
|
|||
this.state.commentSort === "Old" && "active"
|
||||
}`}
|
||||
>
|
||||
{i18n.t("old")}
|
||||
{I18NextService.i18n.t("old")}
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
|
@ -496,7 +494,7 @@ export class Post extends Component<any, PostState> {
|
|||
this.state.commentViewType === CommentViewType.Flat && "active"
|
||||
}`}
|
||||
>
|
||||
{i18n.t("chat")}
|
||||
{I18NextService.i18n.t("chat")}
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
|
@ -595,14 +593,14 @@ export class Post extends Component<any, PostState> {
|
|||
className="ps-0 d-block btn btn-link text-muted"
|
||||
onClick={linkEvent(this, this.handleViewPost)}
|
||||
>
|
||||
{i18n.t("view_all_comments")} ➔
|
||||
{I18NextService.i18n.t("view_all_comments")} ➔
|
||||
</button>
|
||||
{showContextButton && (
|
||||
<button
|
||||
className="ps-0 d-block btn btn-link text-muted"
|
||||
onClick={linkEvent(this, this.handleViewContext)}
|
||||
>
|
||||
{i18n.t("show_context")} ➔
|
||||
{I18NextService.i18n.t("show_context")} ➔
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
|
@ -836,14 +834,14 @@ export class Post extends Component<any, PostState> {
|
|||
async handleCommentReport(form: CreateCommentReport) {
|
||||
const reportRes = await HttpService.client.createCommentReport(form);
|
||||
if (reportRes.state == "success") {
|
||||
toast(i18n.t("report_created"));
|
||||
toast(I18NextService.i18n.t("report_created"));
|
||||
}
|
||||
}
|
||||
|
||||
async handlePostReport(form: CreatePostReport) {
|
||||
const reportRes = await HttpService.client.createPostReport(form);
|
||||
if (reportRes.state == "success") {
|
||||
toast(i18n.t("report_created"));
|
||||
toast(I18NextService.i18n.t("report_created"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -982,7 +980,7 @@ export class Post extends Component<any, PostState> {
|
|||
|
||||
purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
|
||||
if (purgeRes.state == "success") {
|
||||
toast(i18n.t("purge_success"));
|
||||
toast(I18NextService.i18n.t("purge_success"));
|
||||
this.context.router.history.push(`/`);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,8 @@ import {
|
|||
GetPersonDetailsResponse,
|
||||
GetSiteResponse,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { InitialFetchRequest } from "../../interfaces";
|
||||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import { FirstLoadService, I18NextService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { toast } from "../../toast";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
|
@ -97,7 +96,7 @@ export class CreatePrivateMessage extends Component<
|
|||
get documentTitle(): string {
|
||||
if (this.state.recipientRes.state == "success") {
|
||||
const name_ = this.state.recipientRes.data.person_view.person.name;
|
||||
return `${i18n.t("create_private_message")} - ${name_}`;
|
||||
return `${I18NextService.i18n.t("create_private_message")} - ${name_}`;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
@ -116,7 +115,7 @@ export class CreatePrivateMessage extends Component<
|
|||
return (
|
||||
<div className="row">
|
||||
<div className="col-12 col-lg-6 offset-lg-3 mb-4">
|
||||
<h5>{i18n.t("create_private_message")}</h5>
|
||||
<h5>{I18NextService.i18n.t("create_private_message")}</h5>
|
||||
<PrivateMessageForm
|
||||
onCreate={this.handlePrivateMessageCreate}
|
||||
recipient={res.person_view.person}
|
||||
|
@ -144,7 +143,7 @@ export class CreatePrivateMessage extends Component<
|
|||
const res = await HttpService.client.createPrivateMessage(form);
|
||||
|
||||
if (res.state == "success") {
|
||||
toast(i18n.t("message_sent"));
|
||||
toast(I18NextService.i18n.t("message_sent"));
|
||||
|
||||
// Navigate to the front
|
||||
this.context.router.history.push("/");
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
PrivateMessageView,
|
||||
} from "lemmy-js-client";
|
||||
import { relTags } from "../../config";
|
||||
import { i18n } from "../../i18next";
|
||||
import { I18NextService } from "../../services";
|
||||
import { setupTippy } from "../../tippy";
|
||||
import { Icon, Spinner } from "../common/icon";
|
||||
import { MarkdownTextArea } from "../common/markdown-textarea";
|
||||
|
@ -66,7 +66,7 @@ export class PrivateMessageForm extends Component<
|
|||
// TODO
|
||||
// <Prompt
|
||||
// when={!this.state.loading && this.state.content}
|
||||
// message={i18n.t("block_leaving")}
|
||||
// message={I18NextService.i18n.t("block_leaving")}
|
||||
// />
|
||||
|
||||
render() {
|
||||
|
@ -83,7 +83,7 @@ export class PrivateMessageForm extends Component<
|
|||
{!this.props.privateMessageView && (
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2 col-form-label">
|
||||
{capitalizeFirstLetter(i18n.t("to"))}
|
||||
{capitalizeFirstLetter(I18NextService.i18n.t("to"))}
|
||||
</label>
|
||||
|
||||
<div className="col-sm-10 form-control-plaintext">
|
||||
|
@ -93,12 +93,14 @@ export class PrivateMessageForm extends Component<
|
|||
)}
|
||||
<div className="mb-3 row">
|
||||
<label className="col-sm-2 col-form-label">
|
||||
{i18n.t("message")}
|
||||
{I18NextService.i18n.t("message")}
|
||||
<button
|
||||
className="btn btn-link text-warning d-inline-block"
|
||||
onClick={linkEvent(this, this.handleShowDisclaimer)}
|
||||
data-tippy-content={i18n.t("private_message_disclaimer")}
|
||||
aria-label={i18n.t("private_message_disclaimer")}
|
||||
data-tippy-content={I18NextService.i18n.t(
|
||||
"private_message_disclaimer"
|
||||
)}
|
||||
aria-label={I18NextService.i18n.t("private_message_disclaimer")}
|
||||
>
|
||||
<Icon icon="alert-triangle" classes="icon-inline" />
|
||||
</button>
|
||||
|
@ -142,9 +144,9 @@ export class PrivateMessageForm extends Component<
|
|||
{this.state.loading ? (
|
||||
<Spinner />
|
||||
) : this.props.privateMessageView ? (
|
||||
capitalizeFirstLetter(i18n.t("save"))
|
||||
capitalizeFirstLetter(I18NextService.i18n.t("save"))
|
||||
) : (
|
||||
capitalizeFirstLetter(i18n.t("send_message"))
|
||||
capitalizeFirstLetter(I18NextService.i18n.t("send_message"))
|
||||
)}
|
||||
</button>
|
||||
{this.props.privateMessageView && (
|
||||
|
@ -153,7 +155,7 @@ export class PrivateMessageForm extends Component<
|
|||
className="btn btn-secondary"
|
||||
onClick={linkEvent(this, this.handleCancel)}
|
||||
>
|
||||
{i18n.t("cancel")}
|
||||
{I18NextService.i18n.t("cancel")}
|
||||
</button>
|
||||
)}
|
||||
<ul className="d-inline-block float-right list-inline mb-1 text-muted font-weight-bold">
|
||||
|
|
|
@ -5,8 +5,8 @@ import {
|
|||
PrivateMessageReportView,
|
||||
ResolvePrivateMessageReport,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { mdToHtml } from "../../markdown";
|
||||
import { I18NextService } from "../../services";
|
||||
import { Icon, Spinner } from "../common/icon";
|
||||
import { PersonListing } from "../person/person-listing";
|
||||
|
||||
|
@ -39,28 +39,29 @@ export class PrivateMessageReport extends Component<Props, State> {
|
|||
render() {
|
||||
const r = this.props.report;
|
||||
const pmr = r.private_message_report;
|
||||
const tippyContent = i18n.t(
|
||||
const tippyContent = I18NextService.i18n.t(
|
||||
r.private_message_report.resolved ? "unresolve_report" : "resolve_report"
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="private-message-report">
|
||||
<div>
|
||||
{i18n.t("creator")}:{" "}
|
||||
{I18NextService.i18n.t("creator")}:{" "}
|
||||
<PersonListing person={r.private_message_creator} />
|
||||
</div>
|
||||
<div>
|
||||
{i18n.t("message")}:
|
||||
{I18NextService.i18n.t("message")}:
|
||||
<div
|
||||
className="md-div"
|
||||
dangerouslySetInnerHTML={mdToHtml(pmr.original_pm_text)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{i18n.t("reporter")}: <PersonListing person={r.creator} />
|
||||
{I18NextService.i18n.t("reporter")}:{" "}
|
||||
<PersonListing person={r.creator} />
|
||||
</div>
|
||||
<div>
|
||||
{i18n.t("reason")}: {pmr.reason}
|
||||
{I18NextService.i18n.t("reason")}: {pmr.reason}
|
||||
</div>
|
||||
{r.resolver && (
|
||||
<div>
|
||||
|
|
|
@ -9,9 +9,8 @@ import {
|
|||
Person,
|
||||
PrivateMessageView,
|
||||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { mdToHtml } from "../../markdown";
|
||||
import { UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { Icon, Spinner } from "../common/icon";
|
||||
import { MomentTime } from "../common/moment-time";
|
||||
import { PersonListing } from "../person/person-listing";
|
||||
|
@ -94,7 +93,9 @@ export class PrivateMessage extends Component<
|
|||
<ul className="list-inline mb-0 text-muted small">
|
||||
{/* TODO refactor this */}
|
||||
<li className="list-inline-item">
|
||||
{this.mine ? i18n.t("to") : i18n.t("from")}
|
||||
{this.mine
|
||||
? I18NextService.i18n.t("to")
|
||||
: I18NextService.i18n.t("from")}
|
||||
</li>
|
||||
<li className="list-inline-item">
|
||||
<PersonListing person={otherPerson} />
|
||||
|
@ -148,13 +149,13 @@ export class PrivateMessage extends Component<
|
|||
onClick={linkEvent(this, this.handleMarkRead)}
|
||||
data-tippy-content={
|
||||
message_view.private_message.read
|
||||
? i18n.t("mark_as_unread")
|
||||
: i18n.t("mark_as_read")
|
||||
? I18NextService.i18n.t("mark_as_unread")
|
||||
: I18NextService.i18n.t("mark_as_read")
|
||||
}
|
||||
aria-label={
|
||||
message_view.private_message.read
|
||||
? i18n.t("mark_as_unread")
|
||||
: i18n.t("mark_as_read")
|
||||
? I18NextService.i18n.t("mark_as_unread")
|
||||
: I18NextService.i18n.t("mark_as_read")
|
||||
}
|
||||
>
|
||||
{this.state.readLoading ? (
|
||||
|
@ -175,8 +176,8 @@ export class PrivateMessage extends Component<
|
|||
<button
|
||||
className="btn btn-link btn-animate text-muted"
|
||||
onClick={linkEvent(this, this.handleReplyClick)}
|
||||
data-tippy-content={i18n.t("reply")}
|
||||
aria-label={i18n.t("reply")}
|
||||
data-tippy-content={I18NextService.i18n.t("reply")}
|
||||
aria-label={I18NextService.i18n.t("reply")}
|
||||
>
|
||||
<Icon icon="reply1" classes="icon-inline" />
|
||||
</button>
|
||||
|
@ -189,8 +190,8 @@ export class PrivateMessage extends Component<
|
|||
<button
|
||||
className="btn btn-link btn-animate text-muted"
|
||||
onClick={linkEvent(this, this.handleEditClick)}
|
||||
data-tippy-content={i18n.t("edit")}
|
||||
aria-label={i18n.t("edit")}
|
||||
data-tippy-content={I18NextService.i18n.t("edit")}
|
||||
aria-label={I18NextService.i18n.t("edit")}
|
||||
>
|
||||
<Icon icon="edit" classes="icon-inline" />
|
||||
</button>
|
||||
|
@ -201,13 +202,13 @@ export class PrivateMessage extends Component<
|
|||
onClick={linkEvent(this, this.handleDeleteClick)}
|
||||
data-tippy-content={
|
||||
!message_view.private_message.deleted
|
||||
? i18n.t("delete")
|
||||
: i18n.t("restore")
|
||||
? I18NextService.i18n.t("delete")
|
||||
: I18NextService.i18n.t("restore")
|
||||
}
|
||||
aria-label={
|
||||
!message_view.private_message.deleted
|
||||
? i18n.t("delete")
|
||||
: i18n.t("restore")
|
||||
? I18NextService.i18n.t("delete")
|
||||
: I18NextService.i18n.t("restore")
|
||||
}
|
||||
>
|
||||
{this.state.deleteLoading ? (
|
||||
|
@ -229,8 +230,8 @@ export class PrivateMessage extends Component<
|
|||
<button
|
||||
className="btn btn-link btn-animate text-muted"
|
||||
onClick={linkEvent(this, this.handleViewSource)}
|
||||
data-tippy-content={i18n.t("view_source")}
|
||||
aria-label={i18n.t("view_source")}
|
||||
data-tippy-content={I18NextService.i18n.t("view_source")}
|
||||
aria-label={I18NextService.i18n.t("view_source")}
|
||||
>
|
||||
<Icon
|
||||
icon="file-text"
|
||||
|
@ -250,13 +251,13 @@ export class PrivateMessage extends Component<
|
|||
onSubmit={linkEvent(this, this.handleReportSubmit)}
|
||||
>
|
||||
<label className="visually-hidden" htmlFor="pm-report-reason">
|
||||
{i18n.t("reason")}
|
||||
{I18NextService.i18n.t("reason")}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="pm-report-reason"
|
||||
className="form-control me-2"
|
||||
placeholder={i18n.t("reason")}
|
||||
placeholder={I18NextService.i18n.t("reason")}
|
||||
required
|
||||
value={this.state.reportReason}
|
||||
onInput={linkEvent(this, this.handleReportReasonChange)}
|
||||
|
@ -264,9 +265,13 @@ export class PrivateMessage extends Component<
|
|||
<button
|
||||
type="submit"
|
||||
className="btn btn-secondary"
|
||||
aria-label={i18n.t("create_report")}
|
||||
aria-label={I18NextService.i18n.t("create_report")}
|
||||
>
|
||||
{this.state.reportLoading ? <Spinner /> : i18n.t("create_report")}
|
||||
{this.state.reportLoading ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
I18NextService.i18n.t("create_report")
|
||||
)}
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
|
@ -287,8 +292,8 @@ export class PrivateMessage extends Component<
|
|||
<button
|
||||
className="btn btn-link btn-animate text-muted py-0"
|
||||
onClick={linkEvent(this, this.handleShowReportDialog)}
|
||||
data-tippy-content={i18n.t("show_report_dialog")}
|
||||
aria-label={i18n.t("show_report_dialog")}
|
||||
data-tippy-content={I18NextService.i18n.t("show_report_dialog")}
|
||||
aria-label={I18NextService.i18n.t("show_report_dialog")}
|
||||
>
|
||||
<Icon icon="flag" inline />
|
||||
</button>
|
||||
|
@ -297,7 +302,9 @@ export class PrivateMessage extends Component<
|
|||
|
||||
get messageUnlessRemoved(): string {
|
||||
const message = this.props.private_message_view.private_message;
|
||||
return message.deleted ? `*${i18n.t("deleted")}*` : message.content;
|
||||
return message.deleted
|
||||
? `*${I18NextService.i18n.t("deleted")}*`
|
||||
: message.content;
|
||||
}
|
||||
|
||||
handleReplyClick(i: PrivateMessage) {
|
||||
|
|
|
@ -46,9 +46,8 @@ import {
|
|||
SortType,
|
||||
} from "lemmy-js-client";
|
||||
import { fetchLimit } from "../config";
|
||||
import { i18n } from "../i18next";
|
||||
import { CommentViewType, InitialFetchRequest } from "../interfaces";
|
||||
import { FirstLoadService } from "../services/FirstLoadService";
|
||||
import { FirstLoadService, I18NextService } from "../services";
|
||||
import { HttpService, RequestState } from "../services/HttpService";
|
||||
import { CommentNodes } from "./comment/comment-nodes";
|
||||
import { HtmlTags } from "./common/html-tags";
|
||||
|
@ -184,13 +183,13 @@ const Filter = ({
|
|||
return (
|
||||
<div className="mb-3 col-sm-6">
|
||||
<label className="col-form-label me-2" htmlFor={`${filterType}-filter`}>
|
||||
{capitalizeFirstLetter(i18n.t(filterType))}
|
||||
{capitalizeFirstLetter(I18NextService.i18n.t(filterType))}
|
||||
</label>
|
||||
<SearchableSelect
|
||||
id={`${filterType}-filter`}
|
||||
options={[
|
||||
{
|
||||
label: i18n.t("all"),
|
||||
label: I18NextService.i18n.t("all"),
|
||||
value: "0",
|
||||
},
|
||||
].concat(options)}
|
||||
|
@ -228,7 +227,7 @@ function getListing(
|
|||
return (
|
||||
<>
|
||||
<span>{listing}</span>
|
||||
<span>{` - ${i18n.t(translationKey, {
|
||||
<span>{` - ${I18NextService.i18n.t(translationKey, {
|
||||
count: Number(count),
|
||||
formattedCount: numToSI(count),
|
||||
})}`}</span>
|
||||
|
@ -448,7 +447,7 @@ export class Search extends Component<any, SearchState> {
|
|||
get documentTitle(): string {
|
||||
const { q } = getSearchQueryParams();
|
||||
const name = this.state.siteRes.site_view.site.name;
|
||||
return `${i18n.t("search")} - ${q ? `${q} - ` : ""}${name}`;
|
||||
return `${I18NextService.i18n.t("search")} - ${q ? `${q} - ` : ""}${name}`;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -460,13 +459,13 @@ export class Search extends Component<any, SearchState> {
|
|||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
<h5>{i18n.t("search")}</h5>
|
||||
<h5>{I18NextService.i18n.t("search")}</h5>
|
||||
{this.selects}
|
||||
{this.searchForm}
|
||||
{this.displayResults(type)}
|
||||
{this.resultsCount === 0 &&
|
||||
this.state.searchRes.state === "success" && (
|
||||
<span>{i18n.t("no_results")}</span>
|
||||
<span>{I18NextService.i18n.t("no_results")}</span>
|
||||
)}
|
||||
<Paginator page={page} onChange={this.handlePageChange} />
|
||||
</div>
|
||||
|
@ -499,8 +498,8 @@ export class Search extends Component<any, SearchState> {
|
|||
type="text"
|
||||
className="form-control me-2 mb-2 col-sm-8"
|
||||
value={this.state.searchText}
|
||||
placeholder={`${i18n.t("search")}...`}
|
||||
aria-label={i18n.t("search")}
|
||||
placeholder={`${I18NextService.i18n.t("search")}...`}
|
||||
aria-label={I18NextService.i18n.t("search")}
|
||||
onInput={linkEvent(this, this.handleQChange)}
|
||||
required
|
||||
minLength={1}
|
||||
|
@ -511,7 +510,7 @@ export class Search extends Component<any, SearchState> {
|
|||
{this.state.searchRes.state === "loading" ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
<span>{i18n.t("search")}</span>
|
||||
<span>{I18NextService.i18n.t("search")}</span>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -540,14 +539,16 @@ export class Search extends Component<any, SearchState> {
|
|||
value={type}
|
||||
onChange={linkEvent(this, this.handleTypeChange)}
|
||||
className="form-select d-inline-block w-auto mb-2"
|
||||
aria-label={i18n.t("type")}
|
||||
aria-label={I18NextService.i18n.t("type")}
|
||||
>
|
||||
<option disabled aria-hidden="true">
|
||||
{i18n.t("type")}
|
||||
{I18NextService.i18n.t("type")}
|
||||
</option>
|
||||
{searchTypes.map(option => (
|
||||
<option value={option} key={option}>
|
||||
{i18n.t(option.toString().toLowerCase() as NoOptionI18nKeys)}
|
||||
{I18NextService.i18n.t(
|
||||
option.toString().toLowerCase() as NoOptionI18nKeys
|
||||
)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
|
|
@ -24,3 +24,15 @@ export const updateUnreadCountsInterval = 30000;
|
|||
export const fetchLimit = 40;
|
||||
export const relTags = "noopener nofollow";
|
||||
export const emDash = "\u2014";
|
||||
|
||||
/**
|
||||
* Accepted formats:
|
||||
* !community@server.com
|
||||
* /c/community@server.com
|
||||
* /m/community@server.com
|
||||
* /u/username@server.com
|
||||
*/
|
||||
export const instanceLinkRegex =
|
||||
/(\/[cmu]\/|!)[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;
|
||||
|
||||
export const testHost = "0.0.0.0:8536";
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
|
||||
const testHost = "0.0.0.0:8536";
|
||||
|
||||
function getInternalHost() {
|
||||
return !isBrowser()
|
||||
? process.env.LEMMY_UI_LEMMY_INTERNAL_HOST ?? testHost
|
||||
: testHost; // used for local dev
|
||||
}
|
||||
|
||||
export function getExternalHost() {
|
||||
return isBrowser()
|
||||
? `${window.location.hostname}${
|
||||
["1234", "1235"].includes(window.location.port)
|
||||
? ":8536"
|
||||
: window.location.port == ""
|
||||
? ""
|
||||
: `:${window.location.port}`
|
||||
}`
|
||||
: process.env.LEMMY_UI_LEMMY_EXTERNAL_HOST || testHost;
|
||||
}
|
||||
|
||||
function getSecure() {
|
||||
return (
|
||||
isBrowser()
|
||||
? window.location.protocol.includes("https")
|
||||
: process.env.LEMMY_UI_HTTPS === "true"
|
||||
)
|
||||
? "s"
|
||||
: "";
|
||||
}
|
||||
|
||||
function getHost() {
|
||||
return isBrowser() ? getExternalHost() : getInternalHost();
|
||||
}
|
||||
|
||||
function getBaseLocal(s = "") {
|
||||
return `http${s}://${getHost()}`;
|
||||
}
|
||||
|
||||
export function getHttpBaseInternal() {
|
||||
return getBaseLocal(); // Don't use secure here
|
||||
}
|
||||
|
||||
export function getHttpBaseExternal() {
|
||||
return `http${getSecure()}://${getExternalHost()}`;
|
||||
}
|
||||
|
||||
export function getHttpBase() {
|
||||
return getBaseLocal(getSecure());
|
||||
}
|
||||
|
||||
export function isHttps() {
|
||||
return getSecure() === "s";
|
||||
}
|
||||
|
||||
console.log(`httpbase: ${getHttpBase()}`);
|
||||
console.log(`isHttps: ${isHttps()}`);
|
||||
|
||||
// This is for html tags, don't include port
|
||||
export function httpExternalPath(path: string) {
|
||||
return `http${getSecure()}://${getExternalHost().replace(
|
||||
/:\d+/g,
|
||||
""
|
||||
)}${path}`;
|
||||
}
|
|
@ -7,13 +7,14 @@ import emojiShortName from "emoji-short-name";
|
|||
import { CustomEmojiView } from "lemmy-js-client";
|
||||
import { default as MarkdownIt } from "markdown-it";
|
||||
import markdown_it_container from "markdown-it-container";
|
||||
import markdown_it_emoji from "markdown-it-emoji/bare";
|
||||
// import markdown_it_emoji from "markdown-it-emoji/bare";
|
||||
import markdown_it_footnote from "markdown-it-footnote";
|
||||
import markdown_it_html5_embed from "markdown-it-html5-embed";
|
||||
import markdown_it_sub from "markdown-it-sub";
|
||||
import markdown_it_sup from "markdown-it-sup";
|
||||
import Renderer from "markdown-it/lib/renderer";
|
||||
import Token from "markdown-it/lib/token";
|
||||
import { instanceLinkRegex } from "./config";
|
||||
|
||||
export let Tribute: any;
|
||||
|
||||
|
@ -72,6 +73,75 @@ const html5EmbedConfig = {
|
|||
},
|
||||
};
|
||||
|
||||
function localInstanceLinkParser(md: MarkdownIt) {
|
||||
md.core.ruler.push("replace-text", state => {
|
||||
for (let i = 0; i < state.tokens.length; i++) {
|
||||
if (state.tokens[i].type !== "inline") {
|
||||
continue;
|
||||
}
|
||||
const inlineTokens: Token[] = state.tokens[i].children || [];
|
||||
for (let j = inlineTokens.length - 1; j >= 0; j--) {
|
||||
if (
|
||||
inlineTokens[j].type === "text" &&
|
||||
new RegExp(instanceLinkRegex).test(inlineTokens[j].content)
|
||||
) {
|
||||
const text = inlineTokens[j].content;
|
||||
const matches = Array.from(text.matchAll(instanceLinkRegex));
|
||||
|
||||
let lastIndex = 0;
|
||||
const newTokens: Token[] = [];
|
||||
|
||||
let linkClass = "community-link";
|
||||
|
||||
for (const match of matches) {
|
||||
// If there is plain text before the match, add it as a separate token
|
||||
if (match.index !== undefined && match.index > lastIndex) {
|
||||
const textToken = new state.Token("text", "", 0);
|
||||
textToken.content = text.slice(lastIndex, match.index);
|
||||
newTokens.push(textToken);
|
||||
}
|
||||
|
||||
let href;
|
||||
if (match[0].startsWith("!")) {
|
||||
href = "/c/" + match[0].substring(1);
|
||||
} else if (match[0].startsWith("/m/")) {
|
||||
href = "/c/" + match[0].substring(3);
|
||||
} else {
|
||||
href = match[0];
|
||||
if (match[0].startsWith("/u/")) {
|
||||
linkClass = "user-link";
|
||||
}
|
||||
}
|
||||
|
||||
const linkOpenToken = new state.Token("link_open", "a", 1);
|
||||
linkOpenToken.attrs = [
|
||||
["href", href],
|
||||
["class", linkClass],
|
||||
];
|
||||
const textToken = new state.Token("text", "", 0);
|
||||
textToken.content = match[0];
|
||||
const linkCloseToken = new state.Token("link_close", "a", -1);
|
||||
|
||||
newTokens.push(linkOpenToken, textToken, linkCloseToken);
|
||||
|
||||
lastIndex =
|
||||
(match.index !== undefined ? match.index : 0) + match[0].length;
|
||||
}
|
||||
|
||||
// If there is plain text after the last match, add it as a separate token
|
||||
if (lastIndex < text.length) {
|
||||
const textToken = new state.Token("text", "", 0);
|
||||
textToken.content = text.slice(lastIndex);
|
||||
newTokens.push(textToken);
|
||||
}
|
||||
|
||||
inlineTokens.splice(j, 1, ...newTokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function setupMarkdown() {
|
||||
const markdownItConfig: MarkdownIt.Options = {
|
||||
html: false,
|
||||
|
@ -79,19 +149,20 @@ export function setupMarkdown() {
|
|||
typographer: true,
|
||||
};
|
||||
|
||||
const emojiDefs = Array.from(customEmojisLookup.entries()).reduce(
|
||||
(main, [key, value]) => ({ ...main, [key]: value }),
|
||||
{}
|
||||
);
|
||||
// const emojiDefs = Array.from(customEmojisLookup.entries()).reduce(
|
||||
// (main, [key, value]) => ({ ...main, [key]: value }),
|
||||
// {}
|
||||
// );
|
||||
md = new MarkdownIt(markdownItConfig)
|
||||
.use(markdown_it_sub)
|
||||
.use(markdown_it_sup)
|
||||
.use(markdown_it_footnote)
|
||||
.use(markdown_it_html5_embed, html5EmbedConfig)
|
||||
.use(markdown_it_container, "spoiler", spoilerConfig)
|
||||
.use(markdown_it_emoji, {
|
||||
defs: emojiDefs,
|
||||
});
|
||||
.use(localInstanceLinkParser);
|
||||
// .use(markdown_it_emoji, {
|
||||
// defs: emojiDefs,
|
||||
// });
|
||||
|
||||
mdNoImages = new MarkdownIt(markdownItConfig)
|
||||
.use(markdown_it_sub)
|
||||
|
@ -99,9 +170,10 @@ export function setupMarkdown() {
|
|||
.use(markdown_it_footnote)
|
||||
.use(markdown_it_html5_embed, html5EmbedConfig)
|
||||
.use(markdown_it_container, "spoiler", spoilerConfig)
|
||||
.use(markdown_it_emoji, {
|
||||
defs: emojiDefs,
|
||||
})
|
||||
.use(localInstanceLinkParser)
|
||||
// .use(markdown_it_emoji, {
|
||||
// defs: emojiDefs,
|
||||
// })
|
||||
.disable("image");
|
||||
const defaultRenderer = md.renderer.rules.image;
|
||||
md.renderer.rules.image = function (
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { getHttpBase } from "@utils/env";
|
||||
import { LemmyHttp } from "lemmy-js-client";
|
||||
import { getHttpBase } from "../../shared/env";
|
||||
import { i18n } from "../../shared/i18next";
|
||||
import { toast } from "../../shared/toast";
|
||||
import { I18NextService } from "./I18NextService";
|
||||
|
||||
type EmptyRequestState = {
|
||||
state: "empty";
|
||||
|
@ -62,7 +62,7 @@ class WrappedLemmyHttpClient {
|
|||
};
|
||||
} catch (error) {
|
||||
console.error(`API error: ${error}`);
|
||||
toast(i18n.t(error), "danger");
|
||||
toast(I18NextService.i18n.t(error), "danger");
|
||||
return {
|
||||
state: "failed",
|
||||
msg: error,
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
import i18next, { i18nTyped, Resource } from "i18next";
|
||||
import { UserService } from "./services/UserService";
|
||||
import { ar } from "./translations/ar";
|
||||
import { bg } from "./translations/bg";
|
||||
import { ca } from "./translations/ca";
|
||||
import { cs } from "./translations/cs";
|
||||
import { da } from "./translations/da";
|
||||
import { de } from "./translations/de";
|
||||
import { el } from "./translations/el";
|
||||
import { en } from "./translations/en";
|
||||
import { eo } from "./translations/eo";
|
||||
import { es } from "./translations/es";
|
||||
import { eu } from "./translations/eu";
|
||||
import { fa } from "./translations/fa";
|
||||
import { fi } from "./translations/fi";
|
||||
import { fr } from "./translations/fr";
|
||||
import { ga } from "./translations/ga";
|
||||
import { gl } from "./translations/gl";
|
||||
import { hr } from "./translations/hr";
|
||||
import { id } from "./translations/id";
|
||||
import { it } from "./translations/it";
|
||||
import { ja } from "./translations/ja";
|
||||
import { ko } from "./translations/ko";
|
||||
import { nl } from "./translations/nl";
|
||||
import { oc } from "./translations/oc";
|
||||
import { pl } from "./translations/pl";
|
||||
import { pt } from "./translations/pt";
|
||||
import { pt_BR } from "./translations/pt_BR";
|
||||
import { ru } from "./translations/ru";
|
||||
import { sv } from "./translations/sv";
|
||||
import { vi } from "./translations/vi";
|
||||
import { zh } from "./translations/zh";
|
||||
import { zh_Hant } from "./translations/zh_Hant";
|
||||
import i18next, { Resource } from "i18next";
|
||||
import { UserService } from "../services";
|
||||
import { ar } from "../translations/ar";
|
||||
import { bg } from "../translations/bg";
|
||||
import { ca } from "../translations/ca";
|
||||
import { cs } from "../translations/cs";
|
||||
import { da } from "../translations/da";
|
||||
import { de } from "../translations/de";
|
||||
import { el } from "../translations/el";
|
||||
import { en } from "../translations/en";
|
||||
import { eo } from "../translations/eo";
|
||||
import { es } from "../translations/es";
|
||||
import { eu } from "../translations/eu";
|
||||
import { fa } from "../translations/fa";
|
||||
import { fi } from "../translations/fi";
|
||||
import { fr } from "../translations/fr";
|
||||
import { ga } from "../translations/ga";
|
||||
import { gl } from "../translations/gl";
|
||||
import { hr } from "../translations/hr";
|
||||
import { id } from "../translations/id";
|
||||
import { it } from "../translations/it";
|
||||
import { ja } from "../translations/ja";
|
||||
import { ko } from "../translations/ko";
|
||||
import { nl } from "../translations/nl";
|
||||
import { oc } from "../translations/oc";
|
||||
import { pl } from "../translations/pl";
|
||||
import { pt } from "../translations/pt";
|
||||
import { pt_BR } from "../translations/pt_BR";
|
||||
import { ru } from "../translations/ru";
|
||||
import { sv } from "../translations/sv";
|
||||
import { vi } from "../translations/vi";
|
||||
import { zh } from "../translations/zh";
|
||||
import { zh_Hant } from "../translations/zh_Hant";
|
||||
|
||||
export const languages = [
|
||||
{ resource: ar, code: "ar", name: "العربية" },
|
||||
|
@ -92,7 +92,13 @@ class LanguageDetector {
|
|||
}
|
||||
}
|
||||
|
||||
i18next.use(LanguageDetector).init({
|
||||
export class I18NextService {
|
||||
#i18n: typeof i18next;
|
||||
static #instance: I18NextService;
|
||||
|
||||
private constructor() {
|
||||
this.#i18n = i18next;
|
||||
this.#i18n.use(LanguageDetector).init({
|
||||
debug: false,
|
||||
compatibilityJSON: "v3",
|
||||
supportedLngs: languages.map(l => l.code),
|
||||
|
@ -102,6 +108,14 @@ i18next.use(LanguageDetector).init({
|
|||
fallbackLng: "en",
|
||||
resources,
|
||||
interpolation: { format },
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export const i18n = i18next as i18nTyped;
|
||||
static get #Instance() {
|
||||
return this.#instance ?? (this.#instance = new this());
|
||||
}
|
||||
|
||||
public static get i18n() {
|
||||
return this.#Instance.#i18n;
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
// import Cookies from 'js-cookie';
|
||||
import { isAuthPath } from "@utils/app";
|
||||
import { isBrowser } from "@utils/browser";
|
||||
import { isHttps } from "@utils/env";
|
||||
import IsomorphicCookie from "isomorphic-cookie";
|
||||
import jwt_decode from "jwt-decode";
|
||||
import { LoginResponse, MyUserInfo } from "lemmy-js-client";
|
||||
import { isHttps } from "../env";
|
||||
import { i18n } from "../i18next";
|
||||
import { toast } from "../toast";
|
||||
import { I18NextService } from "./I18NextService";
|
||||
|
||||
interface Claims {
|
||||
sub: number;
|
||||
|
@ -32,7 +32,7 @@ export class UserService {
|
|||
const expires = new Date();
|
||||
expires.setDate(expires.getDate() + 365);
|
||||
if (res.jwt) {
|
||||
toast(i18n.t("logged_in"));
|
||||
toast(I18NextService.i18n.t("logged_in"));
|
||||
IsomorphicCookie.save("jwt", res.jwt, { expires, secure: isHttps() });
|
||||
this.#setJwtInfo();
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ export class UserService {
|
|||
const msg = "No JWT cookie found";
|
||||
if (throwErr && isBrowser()) {
|
||||
console.error(msg);
|
||||
toast(i18n.t("not_logged_in"), "danger");
|
||||
toast(I18NextService.i18n.t("not_logged_in"), "danger");
|
||||
}
|
||||
return undefined;
|
||||
// throw msg;
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
export { FirstLoadService } from "./FirstLoadService";
|
||||
export { HistoryService } from "./HistoryService";
|
||||
export { HttpService } from "./HttpService";
|
||||
export { I18NextService } from "./I18NextService";
|
||||
export { UserService } from "./UserService";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
import { ThemeColor } from "@utils/types";
|
||||
import Toastify from "toastify-js";
|
||||
import { i18n } from "./i18next";
|
||||
import { I18NextService } from "./services";
|
||||
|
||||
export function toast(text: string, background: ThemeColor = "success") {
|
||||
if (isBrowser()) {
|
||||
|
@ -18,13 +18,18 @@ export function toast(text: string, background: ThemeColor = "success") {
|
|||
|
||||
export function pictrsDeleteToast(filename: string, deleteUrl: string) {
|
||||
if (isBrowser()) {
|
||||
const clickToDeleteText = i18n.t("click_to_delete_picture", { filename });
|
||||
const deletePictureText = i18n.t("picture_deleted", {
|
||||
const clickToDeleteText = I18NextService.i18n.t("click_to_delete_picture", {
|
||||
filename,
|
||||
});
|
||||
const failedDeletePictureText = i18n.t("failed_to_delete_picture", {
|
||||
const deletePictureText = I18NextService.i18n.t("picture_deleted", {
|
||||
filename,
|
||||
});
|
||||
const failedDeletePictureText = I18NextService.i18n.t(
|
||||
"failed_to_delete_picture",
|
||||
{
|
||||
filename,
|
||||
}
|
||||
);
|
||||
|
||||
const backgroundColor = `var(--bs-light)`;
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@ export default function convertCommentSortType(
|
|||
): CommentSortType {
|
||||
switch (sort) {
|
||||
case "TopAll":
|
||||
case "TopHour":
|
||||
case "TopSixHour":
|
||||
case "TopTwelveHour":
|
||||
case "TopDay":
|
||||
case "TopWeek":
|
||||
case "TopMonth":
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { GetSiteResponse } from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { setupEmojiDataModel, setupMarkdown } from "../../markdown";
|
||||
import { UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
|
||||
export default function initializeSite(site?: GetSiteResponse) {
|
||||
UserService.Instance.myUserInfo = site?.my_user;
|
||||
i18n.changeLanguage();
|
||||
I18NextService.i18n.changeLanguage();
|
||||
if (site) {
|
||||
setupEmojiDataModel(site.custom_emojis ?? []);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { BlockCommunityResponse, MyUserInfo } from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { toast } from "../../toast";
|
||||
|
||||
export default function updateCommunityBlock(
|
||||
|
@ -13,12 +12,20 @@ export default function updateCommunityBlock(
|
|||
person: myUserInfo.local_user_view.person,
|
||||
community: data.community_view.community,
|
||||
});
|
||||
toast(`${i18n.t("blocked")} ${data.community_view.community.name}`);
|
||||
toast(
|
||||
`${I18NextService.i18n.t("blocked")} ${
|
||||
data.community_view.community.name
|
||||
}`
|
||||
);
|
||||
} else {
|
||||
myUserInfo.community_blocks = myUserInfo.community_blocks.filter(
|
||||
i => i.community.id !== data.community_view.community.id
|
||||
);
|
||||
toast(`${i18n.t("unblocked")} ${data.community_view.community.name}`);
|
||||
toast(
|
||||
`${I18NextService.i18n.t("unblocked")} ${
|
||||
data.community_view.community.name
|
||||
}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { BlockPersonResponse, MyUserInfo } from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { toast } from "../../toast";
|
||||
|
||||
export default function updatePersonBlock(
|
||||
|
@ -13,12 +12,16 @@ export default function updatePersonBlock(
|
|||
person: myUserInfo.local_user_view.person,
|
||||
target: data.person_view.person,
|
||||
});
|
||||
toast(`${i18n.t("blocked")} ${data.person_view.person.name}`);
|
||||
toast(
|
||||
`${I18NextService.i18n.t("blocked")} ${data.person_view.person.name}`
|
||||
);
|
||||
} else {
|
||||
myUserInfo.person_blocks = myUserInfo.person_blocks.filter(
|
||||
i => i.target.id !== data.person_view.person.id
|
||||
);
|
||||
toast(`${i18n.t("unblocked")} ${data.person_view.person.name}`);
|
||||
toast(
|
||||
`${I18NextService.i18n.t("unblocked")} ${data.person_view.person.name}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export default function restoreScrollPosition(context: any) {
|
||||
const path: string = context.router.route.location.pathname;
|
||||
const y = Number(sessionStorage.getItem(`scrollPosition_${path}`));
|
||||
|
||||
window.scrollTo(0, y);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export default function saveScrollPosition(context: any) {
|
||||
const path: string = context.router.route.location.pathname;
|
||||
const y = window.scrollY;
|
||||
|
||||
sessionStorage.setItem(`scrollPosition_${path}`, y.toString());
|
||||
}
|
||||
|
|
5
src/shared/utils/env/get-base-local.ts
vendored
Normal file
5
src/shared/utils/env/get-base-local.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { getHost } from "@utils/env";
|
||||
|
||||
export default function getBaseLocal(s = "") {
|
||||
return `http${s}://${getHost()}`;
|
||||
}
|
14
src/shared/utils/env/get-external-host.ts
vendored
Normal file
14
src/shared/utils/env/get-external-host.ts
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
import { testHost } from "../../config";
|
||||
|
||||
export default function getExternalHost() {
|
||||
return isBrowser()
|
||||
? `${window.location.hostname}${
|
||||
["1234", "1235"].includes(window.location.port)
|
||||
? ":8536"
|
||||
: window.location.port == ""
|
||||
? ""
|
||||
: `:${window.location.port}`
|
||||
}`
|
||||
: process.env.LEMMY_UI_LEMMY_EXTERNAL_HOST || testHost;
|
||||
}
|
6
src/shared/utils/env/get-host.ts
vendored
Normal file
6
src/shared/utils/env/get-host.ts
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
import { getExternalHost, getInternalHost } from "@utils/env";
|
||||
|
||||
export default function getHost() {
|
||||
return isBrowser() ? getExternalHost() : getInternalHost();
|
||||
}
|
5
src/shared/utils/env/get-http-base-external.ts
vendored
Normal file
5
src/shared/utils/env/get-http-base-external.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { getExternalHost, getSecure } from "@utils/env";
|
||||
|
||||
export default function getHttpBaseExternal() {
|
||||
return `http${getSecure()}://${getExternalHost()}`;
|
||||
}
|
5
src/shared/utils/env/get-http-base-internal.ts
vendored
Normal file
5
src/shared/utils/env/get-http-base-internal.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { getBaseLocal } from "@utils/env";
|
||||
|
||||
export default function getHttpBaseInternal() {
|
||||
return getBaseLocal(); // Don't use secure here
|
||||
}
|
5
src/shared/utils/env/get-http-base.ts
vendored
Normal file
5
src/shared/utils/env/get-http-base.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { getBaseLocal, getSecure } from "@utils/env";
|
||||
|
||||
export default function getHttpBase() {
|
||||
return getBaseLocal(getSecure());
|
||||
}
|
8
src/shared/utils/env/get-internal-host.ts
vendored
Normal file
8
src/shared/utils/env/get-internal-host.ts
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
import { testHost } from "../../config";
|
||||
|
||||
export default function getInternalHost() {
|
||||
return !isBrowser()
|
||||
? process.env.LEMMY_UI_LEMMY_INTERNAL_HOST ?? testHost
|
||||
: testHost; // used for local dev
|
||||
}
|
11
src/shared/utils/env/get-secure.ts
vendored
Normal file
11
src/shared/utils/env/get-secure.ts
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
|
||||
export default function getSecure() {
|
||||
return (
|
||||
isBrowser()
|
||||
? window.location.protocol.includes("https")
|
||||
: process.env.LEMMY_UI_HTTPS === "true"
|
||||
)
|
||||
? "s"
|
||||
: "";
|
||||
}
|
9
src/shared/utils/env/http-external-path.ts
vendored
Normal file
9
src/shared/utils/env/http-external-path.ts
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { getExternalHost, getSecure } from "@utils/env";
|
||||
|
||||
// This is for html tags, don't include port
|
||||
export default function httpExternalPath(path: string) {
|
||||
return `http${getSecure()}://${getExternalHost().replace(
|
||||
/:\d+/g,
|
||||
""
|
||||
)}${path}`;
|
||||
}
|
23
src/shared/utils/env/index.ts
vendored
Normal file
23
src/shared/utils/env/index.ts
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
import getBaseLocal from "./get-base-local";
|
||||
import getExternalHost from "./get-external-host";
|
||||
import getHost from "./get-host";
|
||||
import getHttpBase from "./get-http-base";
|
||||
import getHttpBaseExternal from "./get-http-base-external";
|
||||
import getHttpBaseInternal from "./get-http-base-internal";
|
||||
import getInternalHost from "./get-internal-host";
|
||||
import getSecure from "./get-secure";
|
||||
import httpExternalPath from "./http-external-path";
|
||||
import isHttps from "./is-https";
|
||||
|
||||
export {
|
||||
getBaseLocal,
|
||||
getExternalHost,
|
||||
getHost,
|
||||
getHttpBase,
|
||||
getHttpBaseExternal,
|
||||
getHttpBaseInternal,
|
||||
getInternalHost,
|
||||
getSecure,
|
||||
httpExternalPath,
|
||||
isHttps,
|
||||
};
|
5
src/shared/utils/env/is-https.ts
vendored
Normal file
5
src/shared/utils/env/is-https.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { getSecure } from "@utils/env";
|
||||
|
||||
export default function isHttps() {
|
||||
return getSecure() === "s";
|
||||
}
|
Loading…
Reference in a new issue