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";
import type { Request, Response } from "express";
import { LemmyHttp } from "lemmy-js-client";
-import { getHttpBaseInternal } from "../../shared/env";
+import { getHttpBaseExternal, getHttpBaseInternal } from "../../shared/env";
import { wrapClient } from "../../shared/services/HttpService";
import generateManifestJson from "../utils/generate-manifest-json";
import { setForwardedHeaders } from "../utils/set-forwarded-headers";
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 })
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";
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} />
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);
<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">
<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",
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 {
</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>
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";
<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),
})}
<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),
})}
<NavLink
to="/registration_applications"
className="p-1 nav-link border-0"
- title={i18n.t("unread_registration_applications", {
- count: Number(this.unreadApplicationCount),
- formattedCount: numToSI(this.unreadApplicationCount),
- })}
+ title={I18NextService.i18n.t(
+ "unread_registration_applications",
+ {
+ count: Number(this.unreadApplicationCount),
+ formattedCount: numToSI(this.unreadApplicationCount),
+ }
+ )}
onMouseUp={linkEvent(this, handleCollapseClick)}
>
<Icon icon="clipboard" />
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"
<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">
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) && (
<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>
<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>
<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>
<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),
})}
>
<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),
})}
<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),
})}
>
<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),
})}
<NavLink
to="/registration_applications"
className="nav-link d-inline-flex align-items-center d-md-inline-block"
- title={i18n.t("unread_registration_applications", {
- count: Number(this.unreadApplicationCount),
- formattedCount: numToSI(this.unreadApplicationCount),
- })}
+ 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", {
- count: Number(this.unreadApplicationCount),
- formattedCount: numToSI(this.unreadApplicationCount),
- })}
+ {I18NextService.i18n.t(
+ "unread_registration_applications",
+ {
+ count: Number(this.unreadApplicationCount),
+ formattedCount: numToSI(
+ this.unreadApplicationCount
+ ),
+ }
+ )}
</span>
{this.unreadApplicationCount > 0 && (
<span className="mx-1 badge text-bg-light">
<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>
onClick={linkEvent(this, handleLogOut)}
>
<Icon icon="log-out" classes="me-1" />
- {i18n.t("logout")}
+ {I18NextService.i18n.t("logout")}
</button>
</li>
</ul>
<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>
</>
if (UserService.Instance.myUserInfo) {
document.addEventListener("DOMContentLoaded", function () {
if (!Notification) {
- toast(i18n.t("notifications_error"), "danger");
+ toast(I18NextService.i18n.t("notifications_error"), "danger");
return;
}
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";
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}
/>
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) {
} from "lemmy-js-client";
import moment from "moment";
import { commentTreeMaxDepth } from "../../config";
-import { i18n } from "../../i18next";
import {
BanType,
CommentNodeI,
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";
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,
)}
{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}`}>
) : (
<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
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 ? (
: "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 ? (
: "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 ? (
<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>
<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>
<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>
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>
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 />
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 ? (
<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"
<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>
)}
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 ? (
)}
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
this,
this.handleModRemoveShow
)}
- aria-label={i18n.t("remove")}
+ aria-label={I18NextService.i18n.t("remove")}
>
- {i18n.t("remove")}
+ {I18NextService.i18n.t("remove")}
</button>
) : (
<button
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>
)}
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
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>
))}
)}
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"
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
this,
this.handleCancelConfirmAppointAsMod
)}
- aria-label={i18n.t("no")}
+ aria-label={I18NextService.i18n.t("no")}
>
- {i18n.t("no")}
+ {I18NextService.i18n.t("no")}
</button>
</>
))}
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"
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
this
.handleCancelShowConfirmTransferCommunity
)}
- aria-label={i18n.t("no")}
+ aria-label={I18NextService.i18n.t("no")}
>
- {i18n.t("no")}
+ {I18NextService.i18n.t("no")}
</button>
</>
))}
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"
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) ? (
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
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>
)}
)}
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"
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
this,
this.handleCancelConfirmAppointAsAdmin
)}
- aria-label={i18n.t("no")}
+ aria-label={I18NextService.i18n.t("no")}
>
- {i18n.t("no")}
+ {I18NextService.i18n.t("no")}
</button>
</>
))}
<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
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>
)}
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>
)}
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)}
/>
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)}
/>
<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>
{/* 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>
<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)}
/>
});
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;
}
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),
});
}
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;
}
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";
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"
);
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>
CommunityId,
SiteAggregates,
} from "lemmy-js-client";
-import { i18n } from "../../i18next";
+import { I18NextService } from "../../services";
interface BadgesProps {
counts: CommunityAggregates | SiteAggregates;
<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", {
- count: Number(counts.users_active_day),
- formattedCount: numToSI(counts.users_active_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", {
- count: Number(counts.users_active_week),
- formattedCount: numToSI(counts.users_active_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", {
- count: Number(counts.users_active_month),
- formattedCount: numToSI(counts.users_active_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", {
- count: Number(counts.users_active_half_year),
- formattedCount: numToSI(counts.users_active_half_year),
- })}
+ 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),
})}
)}
{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),
})}
className="badge text-bg-primary"
to={`/modlog${communityId ? `/${communityId}` : ""}`}
>
- {i18n.t("modlog")}
+ {I18NextService.i18n.t("modlog")}
</Link>
</li>
</ul>
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 {
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>
import { Component, linkEvent } from "inferno";
-import { i18n } from "../../i18next";
import { DataType } from "../../interfaces";
+import { I18NextService } from "../../services";
interface DataTypeSelectProps {
type_: DataType;
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 ${
checked={this.state.type_ == DataType.Comment}
onChange={linkEvent(this, this.handleTypeChange)}
/>
- {i18n.t("comments")}
+ {I18NextService.i18n.t("comments")}
</label>
</div>
);
import { Component, linkEvent } from "inferno";
-import { i18n } from "../../i18next";
+import { I18NextService } from "../../services";
import { EmojiMart } from "./emoji-mart";
import { Icon } from "./icon";
<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)}
>
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;
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} />
import classNames from "classnames";
import { Component } from "inferno";
-import { i18n } from "../../i18next";
+import { I18NextService } from "../../services";
interface IconProps {
icon: string;
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>
);
}
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";
/>
<a
onClick={linkEvent(this, this.handleRemoveImage)}
- aria-label={i18n.t("remove")}
+ aria-label={I18NextService.i18n.t("remove")}
>
<Icon icon="x" classes="mini-overlay" />
</a>
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 {
<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">
)}
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}`, {
})}
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 => (
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;
<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"}
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"
}`}
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")
checked={this.state.type_ == "All"}
onChange={linkEvent(this, this.handleTypeChange)}
/>
- {i18n.t("all")}
+ {I18NextService.i18n.t("all")}
</label>
</div>
);
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";
// 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
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 />
<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" />
animated
value={this.state.imageUploadStatus.uploaded}
max={this.state.imageUploadStatus.total}
- text={i18n.t("pictures_uploded_progess", {
- uploaded: this.state.imageUploadStatus.uploaded,
- total: this.state.imageUploadStatus.total,
- })}
+ 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>
className="btn btn-sm btn-secondary ms-2"
onClick={linkEvent(this, this.handleReplyCancel)}
>
- {i18n.t("cancel")}
+ {I18NextService.i18n.t("cancel")}
</button>
)}
{this.state.content && (
}`}
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>
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}
>
if (files.length > maxUploadImages) {
toast(
- i18n.t("too_many_images_upload", {
+ I18NextService.i18n.t("too_many_images_upload", {
count: Number(maxUploadImages),
formattedCount: numToSI(maxUploadImages),
}),
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);
}
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 {
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;
}
import { Component } from "inferno";
-import { i18n } from "../../../shared/i18next";
+import { I18NextService } from "../../services";
export interface IPromptProps {
when: boolean;
}
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();
}
import { Component, linkEvent } from "inferno";
-import { i18n } from "../../i18next";
+import { I18NextService } from "../../services";
interface PaginatorProps {
page: number;
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>
);
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";
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 && (
</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)}
{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
<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>
linkEvent,
RefObject,
} from "inferno";
-import { i18n } from "../../i18next";
+import { I18NextService } from "../../services";
import { Icon, Spinner } from "./icon";
interface SearchableSelectProps {
ref={this.toggleButtonRef}
>
{loading
- ? `${i18n.t("loading")}${loadingEllipses}`
+ ? `${I18NextService.i18n.t("loading")}${loadingEllipses}`
: options[selectedIndex].label}
</button>
<div
ref={this.searchInputRef}
onInput={linkEvent(this, handleSearch)}
value={searchText}
- placeholder={`${i18n.t("search")}...`}
+ placeholder={`${I18NextService.i18n.t("search")}...`}
/>
</div>
{!loading &&
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 {
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={"TopHour"}>{i18n.t("top_hour")}</option>
- <option value={"TopSixHour"}>{i18n.t("top_six_hours")}</option>
- <option value={"TopTwelveHour"}>{i18n.t("top_twelve_hours")}</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>
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";
}
get documentTitle(): string {
- return `${i18n.t("communities")} - ${
+ return `${I18NextService.i18n.t("communities")} - ${
this.state.siteRes.site_view.site.name
}`;
}
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
>
<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>
this.handleFollow
)}
>
- {i18n.t("unsubscribe")}
+ {I18NextService.i18n.t("unsubscribe")}
</button>
)}
{cv.subscribed === "NotSubscribed" && (
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>
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}
</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>
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";
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>
required
minLength={3}
pattern="[a-z0-9_]+"
- title={i18n.t("community_reqs")}
+ title={I18NextService.i18n.t("community_reqs")}
/>
</div>
</div>
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>
</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}
</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}
</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={[]}
{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">
)}
<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">
{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 && (
className="btn btn-secondary"
onClick={linkEvent(this, this.handleCancel)}
>
- {i18n.t("cancel")}
+ {I18NextService.i18n.t("cancel")}
</button>
)}
</div>
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";
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
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"));
}
}
const transferCommunityRes = await HttpService.client.transferCommunity(
form
);
- toast(i18n.t("transfer_community"));
+ toast(I18NextService.i18n.t("transfer_community"));
this.updateCommunityFull(transferCommunityRes);
}
purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
if (purgeRes.state == "success") {
- toast(i18n.t("purge_success"));
+ toast(I18NextService.i18n.t("purge_success"));
this.context.router.history.push(`/`);
}
}
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";
}
get documentTitle(): string {
- return `${i18n.t("create_community")} - ${
+ return `${I18NextService.i18n.t("create_community")} - ${
this.state.siteRes.site_view.site.name
}`;
}
/>
<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)}
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";
) : (
<>
<Icon icon="check" classes="icon-inline text-success me-1" />
- {i18n.t("joined")}
+ {I18NextService.i18n.t("joined")}
</>
)}
</button>
{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>
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} />
}`}
to={`/create_post?communityId=${cv.community.id}`}
>
- {i18n.t("create_a_post")}
+ {I18NextService.i18n.t("create_a_post")}
</Link>
);
}
{this.state.followCommunityLoading ? (
<Spinner />
) : (
- i18n.t("subscribe")
+ I18NextService.i18n.t("subscribe")
)}
</button>
)}
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>
)}
</>
<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>
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">
this.handleCancelLeaveModTeamClick
)}
>
- {i18n.t("no")}
+ {I18NextService.i18n.t("no")}
</button>
</li>
</>
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 ? (
className="btn btn-link text-muted d-inline-block"
onClick={linkEvent(this, this.handleModRemoveShow)}
>
- {i18n.t("remove")}
+ {I18NextService.i18n.t("remove")}
</button>
) : (
<button
{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>
)}
<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)}
/>
{/* 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>
</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)}
/>
<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>
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";
}
get documentTitle(): string {
- return `${i18n.t("admin_settings")} - ${
+ return `${I18NextService.i18n.t("admin_settings")} - ${
this.state.siteRes.site_view.site.name
}`;
}
tabs={[
{
key: "site",
- label: i18n.t("site"),
+ label: I18NextService.i18n.t("site"),
getNode: isSelected => (
<div
className={classNames("tab-pane show", {
},
{
key: "taglines",
- label: i18n.t("taglines"),
+ label: I18NextService.i18n.t("taglines"),
getNode: isSelected => (
<div
className={classNames("tab-pane", {
},
{
key: "emojis",
- label: i18n.t("emojis"),
+ label: I18NextService.i18n.t("emojis"),
getNode: isSelected => (
<div
className={classNames("tab-pane", {
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">
{this.state.leaveAdminTeamRes.state == "loading" ? (
<Spinner />
) : (
- i18n.t("leave_admin_team")
+ I18NextService.i18n.t("leave_admin_team")
)}
</button>
);
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">
s.siteRes.taglines = editRes.data.taglines;
return s;
});
- toast(i18n.t("site_saved"));
+ toast(I18NextService.i18n.t("site_saved"));
}
this.setState({ loading: false });
});
if (this.state.leaveAdminTeamRes.state === "success") {
- toast(i18n.t("left_admin_team"));
+ toast(I18NextService.i18n.t("left_admin_team"));
this.context.router.history.replace("/");
}
}
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";
this.handleEmojiClick = this.handleEmojiClick.bind(this);
}
get documentTitle(): string {
- return i18n.t("custom_emojis");
+ return I18NextService.i18n.t("custom_emojis");
}
render() {
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
<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>{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">
- {i18n.t("column_imageurl")}
+ {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>
{ 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) ||
{ 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"
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} />
}
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) {
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";
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>
);
translationKey: NoOptionI18nKeys;
}) => (
<Link className="btn btn-secondary d-block" to={path}>
- {i18n.t(translationKey)}
+ {I18NextService.i18n.t(translationKey)}
</Link>
);
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"
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"));
}
}
async handleTransferCommunity(form: TransferCommunity) {
await HttpService.client.transferCommunity(form);
- toast(i18n.t("transfer_community"));
+ toast(I18NextService.i18n.t("transfer_community"));
}
async handleCommentReplyRead(form: MarkCommentReplyAsRead) {
purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
if (purgeRes.state == "success") {
- toast(i18n.t("purge_success"));
+ toast(I18NextService.i18n.t("purge_success"));
this.context.router.history.push(`/`);
}
}
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";
}
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() {
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>
)}
<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>
</table>
</div>
) : (
- <div>{i18n.t("none_found")}</div>
+ <div>{I18NextService.i18n.t("none_found")}</div>
);
}
}
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 {
}
get documentTitle(): string {
- return i18n.t("legal_information");
+ return I18NextService.i18n.t("legal_information");
}
render() {
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";
}
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 {
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
</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
!!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>
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
{this.state.loginRes.state == "loading" ? (
<Spinner />
) : (
- i18n.t("login")
+ I18NextService.i18n.t("login")
)}
</button>
</div>
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 } });
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"));
}
}
}
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";
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"
/>
</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"
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", {
{this.props.loading ? (
<Spinner />
) : (
- capitalizeFirstLetter(i18n.t("save"))
+ capitalizeFirstLetter(I18NextService.i18n.t("save"))
)}
</button>
</div>
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";
}
get documentTitle(): string {
- return `${i18n.t("setup")} - Lemmy`;
+ return `${I18NextService.i18n.t("setup")} - Lemmy`;
}
render() {
<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()
) : (
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
</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">
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}
</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
</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
{this.state.registerRes.state == "loading" ? (
<Spinner />
) : (
- i18n.t("sign_up")
+ I18NextService.i18n.t("sign_up")
)}
</button>
</div>
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";
}
titleName(siteView: SiteView): string {
- return i18n.t(
+ return I18NextService.i18n.t(
siteView.local_site.private_instance ? "apply_to_join" : "sign_up"
);
}
className="col-sm-2 col-form-label"
htmlFor="register-username"
>
- {i18n.t("username")}
+ {I18NextService.i18n.t("username")}
</label>
<div className="col-sm-10">
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
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"
!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>
className="col-sm-2 col-form-label"
htmlFor="register-password"
>
- {i18n.t("password")}
+ {I18NextService.i18n.t("password")}
</label>
<div className="col-sm-10">
<input
/>
{this.state.form.password && (
<div className={this.passwordColorClass}>
- {i18n.t(this.passwordStrength as NoOptionI18nKeys)}
+ {I18NextService.i18n.t(
+ this.passwordStrength as NoOptionI18nKeys
+ )}
</div>
)}
</div>
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
<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
className="col-sm-2 col-form-label"
htmlFor="application_answer"
>
- {i18n.t("answer")}
+ {I18NextService.i18n.t("answer")}
</label>
<div className="col-sm-10">
<MarkdownTextArea
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>
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>
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}
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("/");
}
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";
/>
<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
</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}
/>
</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}
</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
</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}
</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
className="form-check-label"
htmlFor="create-site-downvotes"
>
- {i18n.t("enable_downvotes")}
+ {I18NextService.i18n.t("enable_downvotes")}
</label>
</div>
</div>
className="form-check-label"
htmlFor="create-site-enable-nsfw"
>
- {i18n.t("enable_nsfw")}
+ {I18NextService.i18n.t("enable_nsfw")}
</label>
</div>
</div>
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"
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
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>
className="form-check-label"
htmlFor="create-site-require-email-verification"
>
- {i18n.t("require_email_verification")}
+ {I18NextService.i18n.t("require_email_verification")}
</label>
</div>
</div>
className="form-check-label"
htmlFor="create-site-email-admins"
>
- {i18n.t("application_email_admins")}
+ {I18NextService.i18n.t("application_email_admins")}
</label>
</div>
</div>
className="form-check-label"
htmlFor="create-site-reports-email-admins"
>
- {i18n.t("reports_email_admins")}
+ {I18NextService.i18n.t("reports_email_admins")}
</label>
</div>
</div>
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"
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}
{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
className="form-check-label"
htmlFor="create-site-private-instance"
>
- {i18n.t("private_instance")}
+ {I18NextService.i18n.t("private_instance")}
</label>
</div>
</div>
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>
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
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
className="form-check-label"
htmlFor="create-site-federation-enabled"
>
- {i18n.t("federation_enabled")}
+ {I18NextService.i18n.t("federation_enabled")}
</label>
</div>
</div>
className="form-check-label"
htmlFor="create-site-federation-debug"
>
- {i18n.t("federation_debug")}
+ {I18NextService.i18n.t("federation_debug")}
</label>
</div>
</div>
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
className="form-check-label"
htmlFor="create-site-captcha-enabled"
>
- {i18n.t("captcha_enabled")}
+ {I18NextService.i18n.t("captcha_enabled")}
</label>
</div>
</div>
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"
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>
{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>
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
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";
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"
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} />
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";
super(props, context);
}
get documentTitle(): string {
- return i18n.t("taglines");
+ return I18NextService.i18n.t("taglines");
}
render() {
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">
{ 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>
{ 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>
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>
{this.props.loading ? (
<Spinner />
) : (
- capitalizeFirstLetter(i18n.t("save"))
+ capitalizeFirstLetter(I18NextService.i18n.t("save"))
)}
</button>
</div>
} 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";
}) => (
<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)}
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 {
>
/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">
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>
<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}
import { Component } from "inferno";
-import { i18n } from "../../i18next";
+import { I18NextService } from "../../services";
import { Icon } from "../common/icon";
interface CakeDayProps {
}
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,
+ });
}
}
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";
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}`
: "";
}
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}>
{this.state.markAllAsReadRes.state == "loading" ? (
<Spinner />
) : (
- i18n.t("mark_all_as_read")
+ I18NextService.i18n.t("mark_all_as_read")
)}
</button>
)}
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
checked={this.state.unreadOrAll == UnreadOrAll.All}
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
/>
- {i18n.t("all")}
+ {I18NextService.i18n.t("all")}
</label>
</div>
);
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
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
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
checked={this.state.messageType == MessageType.Messages}
onChange={linkEvent(this, this.handleMessageTypeChange)}
/>
- {i18n.t("messages")}
+ {I18NextService.i18n.t("messages")}
</label>
</div>
);
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);
}
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");
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);
}
}
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);
}
}
async handleTransferCommunity(form: TransferCommunity) {
await HttpService.client.transferCommunity(form);
- toast(i18n.t("transfer_community"));
+ toast(I18NextService.i18n.t("transfer_community"));
}
async handleCommentReplyRead(form: MarkCommentReplyAsRead) {
purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
if (purgeRes.state == "success") {
- toast(i18n.t("purge_success"));
+ toast(I18NextService.i18n.t("purge_success"));
this.context.router.history.push(`/`);
}
}
res: RequestState<PrivateMessageReportResponse | CommentReportResponse>
) {
if (res.state == "success") {
- toast(i18n.t("report_created"));
+ toast(I18NextService.i18n.t("report_created"));
}
}
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";
}
get documentTitle(): string {
- return `${i18n.t("password_change")} - ${
+ return `${I18NextService.i18n.t("password_change")} - ${
this.state.siteRes.site_view.site.name
}`;
}
/>
<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>
<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
</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
{this.state.passwordChangeRes.state == "loading" ? (
<Spinner />
) : (
- capitalizeFirstLetter(i18n.t("save"))
+ capitalizeFirstLetter(I18NextService.i18n.t("save"))
)}
</button>
</div>
} 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";
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}>
checked={active}
onChange={linkEvent(this, this.handleViewChange)}
/>
- {i18n.t(view.toLowerCase() as NoOptionI18nKeys)}
+ {I18NextService.i18n.t(view.toLowerCase() as NoOptionI18nKeys)}
</label>
);
}
</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>
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={
}
to={`/create_private_message/${pv.person.id}`}
>
- {i18n.t("send_message")}
+ {I18NextService.i18n.t("send_message")}
</Link>
{personBlocked ? (
<button
this.handleUnblockPerson
)}
>
- {i18n.t("unblock_user")}
+ {I18NextService.i18n.t("unblock_user")}
</button>
) : (
<button
this.handleBlockPerson
)}
>
- {i18n.t("block_user")}
+ {I18NextService.i18n.t("block_user")}
</button>
)}
</>
"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
"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>
<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),
})}
</ul>
</div>
<div className="text-muted">
- {i18n.t("joined")}{" "}
+ {I18NextService.i18n.t("joined")}{" "}
<MomentTime
published={pv.person.published}
showAgo
<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()
</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>
<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)}
/>
<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>
{/* 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>
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"));
}
}
async handleTransferCommunity(form: TransferCommunity) {
await HttpService.client.transferCommunity(form);
- toast(i18n.t("transfer_community"));
+ toast(I18NextService.i18n.t("transfer_community"));
}
async handleCommentReplyRead(form: MarkCommentReplyAsRead) {
purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
if (purgeRes.state == "success") {
- toast(i18n.t("purge_success"));
+ toast(I18NextService.i18n.t("purge_success"));
this.context.router.history.push(`/`);
}
}
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";
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}`
: "";
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
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
checked={this.state.unreadOrAll == UnreadOrAll.All}
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
/>
- {i18n.t("all")}
+ {I18NextService.i18n.t("all")}
</label>
</div>
);
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";
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}`
: "";
}
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
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
checked={this.state.unreadOrAll == UnreadOrAll.All}
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
/>
- {i18n.t("all")}
+ {I18NextService.i18n.t("all")}
</label>
</div>
);
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
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
checked={this.state.messageType == MessageType.PostReport}
onChange={linkEvent(this, this.handleMessageTypeChange)}
/>
- {i18n.t("posts")}
+ {I18NextService.i18n.t("posts")}
</label>
{amAdmin() && (
<label
}
onChange={linkEvent(this, this.handleMessageTypeChange)}
/>
- {i18n.t("messages")}
+ {I18NextService.i18n.t("messages")}
</label>
)}
</div>
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";
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
}
get documentTitle(): string {
- return i18n.t("settings");
+ return I18NextService.i18n.t("settings");
}
render() {
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,
},
]}
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
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
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
{this.state.changePasswordRes.state === "loading" ? (
<Spinner />
) : (
- capitalizeFirstLetter(i18n.t("save"))
+ capitalizeFirstLetter(I18NextService.i18n.t("save"))
)}
</button>
</div>
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}>
{ 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>
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}>
{ 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>
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="^(?!@)(.+)$"
</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
</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}
<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">
</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}
</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}
</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
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>
/>
<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
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}
</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_={
</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
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>
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>
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>
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>
className="form-check-label"
htmlFor="user-show-bot-accounts"
>
- {i18n.t("show_bot_accounts")}
+ {I18NextService.i18n.t("show_bot_accounts")}
</label>
</div>
</div>
className="form-check-label"
htmlFor="user-show-read-posts"
>
- {i18n.t("show_read_posts")}
+ {I18NextService.i18n.t("show_read_posts")}
</label>
</div>
</div>
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>
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>
{this.state.saveRes.state === "loading" ? (
<Spinner />
) : (
- capitalizeFirstLetter(i18n.t("save"))
+ capitalizeFirstLetter(I18NextService.i18n.t("save"))
)}
</button>
</div>
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"
{this.state.deleteAccountRes.state === "loading" ? (
<Spinner />
) : (
- capitalizeFirstLetter(i18n.t("delete"))
+ capitalizeFirstLetter(I18NextService.i18n.t("delete"))
)}
</button>
<button
this.handleDeleteAccountShowConfirmToggle
)}
>
- {i18n.t("cancel")}
+ {I18NextService.i18n.t("cancel")}
</button>
</>
)}
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>
<>
<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">
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>
// 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));
}
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)
if (saveRes.state === "success") {
UserService.Instance.login(saveRes.data);
location.reload();
- toast(i18n.t("saved"));
+ toast(I18NextService.i18n.t("saved"));
window.scrollTo(0, 0);
}
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 });
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";
});
if (this.state.verifyRes.state == "success") {
- toast(i18n.t("email_verified"));
+ toast(I18NextService.i18n.t("email_verified"));
this.props.history.push("/login");
}
}
}
get documentTitle(): string {
- return `${i18n.t("verify_email")} - ${
+ return `${I18NextService.i18n.t("verify_email")} - ${
this.state.siteRes.site_view.site.name
}`;
}
/>
<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 />
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,
}
get documentTitle(): string {
- return `${i18n.t("create_post")} - ${
+ return `${I18NextService.i18n.t("create_post")} - ${
this.state.siteRes.site_view.site.name
}`;
}
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}
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 {
className="mt-2 btn btn-secondary text-monospace"
onClick={linkEvent(this, this.handleIframeExpand)}
>
- {i18n.t("expand_here")}
+ {I18NextService.i18n.t("expand_here")}
</button>
)}
</div>
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";
/>
<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
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>
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(
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(
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>
)}
<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
</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
/>
{!validTitle(this.state.form.name) && (
<div className="invalid-feedback">
- {i18n.t("invalid_post_title")}
+ {I18NextService.i18n.t("invalid_post_title")}
</div>
)}
{this.renderSuggestedPosts()}
</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}
{!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
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,
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
{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 && (
className="btn btn-secondary"
onClick={linkEvent(this, handleCancel)}
>
- {i18n.t("cancel")}
+ {I18NextService.i18n.t("cancel")}
</button>
)}
</div>
copySuggestedTitle
)}
>
- {i18n.t("copy_suggested_title", { title: "" })} {suggestedTitle}
+ {I18NextService.i18n.t("copy_suggested_title", { title: "" })}{" "}
+ {suggestedTitle}
</div>
)
);
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
} 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";
<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" />
<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" />
<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} />
</>
)}
</li>
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 ? (
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 ? (
: "text-primary"
}`}
to={`/post/${post.id}`}
- title={i18n.t("comments")}
+ title={I18NextService.i18n.t("comments")}
>
<span
className="d-inline"
(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
))}
{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>
{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>
{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>
{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>
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}`}>
{!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 />
<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>
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),
});
</span>
{this.unreadCount && (
<span className="text-muted fst-italic">
- ({this.unreadCount} {i18n.t("new")})
+ ({this.unreadCount} {I18NextService.i18n.t("new")})
</span>
)}
</Link>
}`}
{...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 ? (
}`}
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 ? (
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"
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>
<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>
);
}
<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>
);
}
<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"
<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"
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"
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>
})}
inline
/>
- {i18n.t("community")}
+ {I18NextService.i18n.t("community")}
</>
)}
</button>
})}
inline
/>
- {i18n.t("local")}
+ {I18NextService.i18n.t("local")}
</>
)}
</button>
{this.state.removeLoading ? (
<Spinner />
) : !removed ? (
- i18n.t("remove")
+ I18NextService.i18n.t("remove")
) : (
- i18n.t("restore")
+ I18NextService.i18n.t("restore")
)}
</button>
);
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
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 && (
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>
)}
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"
this,
this.handleCancelShowConfirmTransferCommunity
)}
- aria-label={i18n.t("no")}
+ aria-label={I18NextService.i18n.t("no")}
>
- {i18n.t("no")}
+ {I18NextService.i18n.t("no")}
</button>
</>
))}
<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>
</>
)}
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>
)}
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 && (
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>
)}
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)}
/>
<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>
{/* 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>
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)}
<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>
)}
>
<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)}
/>
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;
}
}
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),
});
SavePost,
TransferCommunity,
} from "lemmy-js-client";
-import { i18n } from "../../i18next";
+import { I18NextService } from "../../services";
import { PostListing } from "./post-listing";
interface PostListingsProps {
))
) : (
<>
- <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>
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";
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"
);
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>
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";
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
this.state.commentSort === "Hot" && "active"
}`}
>
- {i18n.t("hot")}
+ {I18NextService.i18n.t("hot")}
<input
type="radio"
className="btn-check"
this.state.commentSort === "Top" && "active"
}`}
>
- {i18n.t("top")}
+ {I18NextService.i18n.t("top")}
<input
type="radio"
className="btn-check"
this.state.commentSort === "New" && "active"
}`}
>
- {i18n.t("new")}
+ {I18NextService.i18n.t("new")}
<input
type="radio"
className="btn-check"
this.state.commentSort === "Old" && "active"
}`}
>
- {i18n.t("old")}
+ {I18NextService.i18n.t("old")}
<input
type="radio"
className="btn-check"
this.state.commentViewType === CommentViewType.Flat && "active"
}`}
>
- {i18n.t("chat")}
+ {I18NextService.i18n.t("chat")}
<input
type="radio"
className="btn-check"
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>
)}
</>
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"));
}
}
purgeItem(purgeRes: RequestState<PurgeItemResponse>) {
if (purgeRes.state == "success") {
- toast(i18n.t("purge_success"));
+ toast(I18NextService.i18n.t("purge_success"));
this.context.router.history.push(`/`);
}
}
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";
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 "";
}
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}
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("/");
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";
// TODO
// <Prompt
// when={!this.state.loading && this.state.content}
- // message={i18n.t("block_leaving")}
+ // message={I18NextService.i18n.t("block_leaving")}
// />
render() {
{!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">
)}
<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>
{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 && (
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">
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";
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>
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";
<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} />
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 ? (
<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>
<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>
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 ? (
<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"
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)}
<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>
)}
<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>
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) {
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";
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)}
return (
<>
<span>{listing}</span>
- <span>{` - ${i18n.t(translationKey, {
+ <span>{` - ${I18NextService.i18n.t(translationKey, {
count: Number(count),
formattedCount: numToSI(count),
})}`}</span>
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() {
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>
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}
{this.state.searchRes.state === "loading" ? (
<Spinner />
) : (
- <span>{i18n.t("search")}</span>
+ <span>{I18NextService.i18n.t("search")}</span>
)}
</button>
</div>
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>
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";
};
} catch (error) {
console.error(`API error: ${error}`);
- toast(i18n.t(error), "danger");
+ toast(I18NextService.i18n.t(error), "danger");
return {
state: "failed",
msg: error,
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: "العربية" },
}
}
-i18next.use(LanguageDetector).init({
- debug: false,
- compatibilityJSON: "v3",
- supportedLngs: languages.map(l => l.code),
- nonExplicitSupportedLngs: true,
- // load: 'languageOnly',
- // initImmediate: false,
- fallbackLng: "en",
- resources,
- interpolation: { format },
-});
+export class I18NextService {
+ #i18n: typeof i18next;
+ static #instance: I18NextService;
-export const i18n = i18next as i18nTyped;
+ private constructor() {
+ this.#i18n = i18next;
+ this.#i18n.use(LanguageDetector).init({
+ debug: false,
+ compatibilityJSON: "v3",
+ supportedLngs: languages.map(l => l.code),
+ nonExplicitSupportedLngs: true,
+ // load: 'languageOnly',
+ // initImmediate: false,
+ fallbackLng: "en",
+ resources,
+ interpolation: { format },
+ });
+ }
+
+ static get #Instance() {
+ return this.#instance ?? (this.#instance = new this());
+ }
+
+ public static get i18n() {
+ return this.#Instance.#i18n;
+ }
+}
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;
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();
}
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;
+export { FirstLoadService } from "./FirstLoadService";
+export { HistoryService } from "./HistoryService";
export { HttpService } from "./HttpService";
+export { I18NextService } from "./I18NextService";
export { UserService } from "./UserService";
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()) {
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)`;
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 ?? []);
}
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(
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
+ }`
+ );
}
}
}
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(
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}`
+ );
}
}
}