mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-11-22 20:31:13 +00:00
Merge branch 'main' into emoji-upload-button
This commit is contained in:
commit
77ff6b45f7
16 changed files with 107 additions and 115 deletions
|
@ -68,7 +68,8 @@
|
|||
"isomorphic-cookie": "^1.2.4",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"lemmy-js-client": "0.18.0-rc.2",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"lodash.merge": "^4.6.2",
|
||||
"markdown-it": "^13.0.1",
|
||||
"markdown-it-container": "^3.0.0",
|
||||
"markdown-it-emoji": "^2.0.2",
|
||||
|
@ -98,6 +99,7 @@
|
|||
"@types/bootstrap": "^5.2.6",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/html-to-text": "^9.0.0",
|
||||
"@types/lodash.isequal": "^4.5.6",
|
||||
"@types/markdown-it": "^12.2.3",
|
||||
"@types/markdown-it-container": "^2.0.5",
|
||||
"@types/node": "^20.1.2",
|
||||
|
|
|
@ -4,7 +4,7 @@ import { Provider } from "inferno-i18next-dess";
|
|||
import { Route, Switch } from "inferno-router";
|
||||
import { IsoDataOptionalSite } from "../../interfaces";
|
||||
import { routes } from "../../routes";
|
||||
import { I18NextService } from "../../services";
|
||||
import { FirstLoadService, I18NextService } from "../../services";
|
||||
import AuthGuard from "../common/auth-guard";
|
||||
import ErrorGuard from "../common/error-guard";
|
||||
import { ErrorPage } from "./error-page";
|
||||
|
@ -45,27 +45,35 @@ export class App extends Component<any, any> {
|
|||
<Navbar siteRes={siteRes} />
|
||||
<div className="mt-4 p-0 fl-1">
|
||||
<Switch>
|
||||
{routes.map(({ path, component: RouteComponent }) => (
|
||||
<Route
|
||||
key={path}
|
||||
path={path}
|
||||
exact
|
||||
component={routeProps => (
|
||||
<ErrorGuard>
|
||||
<main tabIndex={-1} ref={this.mainContentRef}>
|
||||
{RouteComponent &&
|
||||
(isAuthPath(path ?? "") ? (
|
||||
<AuthGuard>
|
||||
<RouteComponent {...routeProps} />
|
||||
</AuthGuard>
|
||||
) : (
|
||||
<RouteComponent {...routeProps} />
|
||||
))}
|
||||
</main>
|
||||
</ErrorGuard>
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
{routes.map(
|
||||
({ path, component: RouteComponent, fetchInitialData }) => (
|
||||
<Route
|
||||
key={path}
|
||||
path={path}
|
||||
exact
|
||||
component={routeProps => {
|
||||
if (!fetchInitialData) {
|
||||
FirstLoadService.falsify();
|
||||
}
|
||||
|
||||
return (
|
||||
<ErrorGuard>
|
||||
<main tabIndex={-1} ref={this.mainContentRef}>
|
||||
{RouteComponent &&
|
||||
(isAuthPath(path ?? "") ? (
|
||||
<AuthGuard>
|
||||
<RouteComponent {...routeProps} />
|
||||
</AuthGuard>
|
||||
) : (
|
||||
<RouteComponent {...routeProps} />
|
||||
))}
|
||||
</main>
|
||||
</ErrorGuard>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
<Route component={ErrorPage} />
|
||||
</Switch>
|
||||
</div>
|
||||
|
|
|
@ -49,6 +49,7 @@ import {
|
|||
SaveComment,
|
||||
TransferCommunity,
|
||||
} from "lemmy-js-client";
|
||||
import deepEqual from "lodash.isequal";
|
||||
import { commentTreeMaxDepth } from "../../config";
|
||||
import {
|
||||
BanType,
|
||||
|
@ -198,7 +199,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
componentWillReceiveProps(
|
||||
nextProps: Readonly<{ children?: InfernoNode } & CommentNodeProps>
|
||||
): void {
|
||||
if (this.props != nextProps) {
|
||||
if (!deepEqual(this.props, nextProps)) {
|
||||
this.setState({
|
||||
showReply: false,
|
||||
showEdit: false,
|
||||
|
|
|
@ -49,39 +49,42 @@ export class LanguageSelect extends Component<LanguageSelectProps, any> {
|
|||
return this.props.iconVersion ? (
|
||||
this.selectBtn
|
||||
) : (
|
||||
<div className="language-select">
|
||||
<div className="language-select mb-3">
|
||||
<label
|
||||
className={classNames(
|
||||
"col-form-label",
|
||||
`col-sm-${this.props.multiple ? 3 : 2}`
|
||||
)}
|
||||
htmlFor={this.id}
|
||||
>
|
||||
{I18NextService.i18n.t(
|
||||
this.props.multiple ? "language_plural" : "language"
|
||||
)}
|
||||
</label>
|
||||
{this.props.multiple && this.props.showLanguageWarning && (
|
||||
<div className="alert alert-warning" role="alert">
|
||||
<div
|
||||
id="lang-warning"
|
||||
className="alert small alert-warning"
|
||||
role="alert"
|
||||
>
|
||||
<Icon icon="alert-triangle" classes="icon-inline me-2" />
|
||||
{I18NextService.i18n.t("undetermined_language_warning")}
|
||||
</div>
|
||||
)}
|
||||
<div className="mb-3 row">
|
||||
<label
|
||||
className={classNames(
|
||||
"col-form-label",
|
||||
`col-sm-${this.props.multiple ? 3 : 2}`
|
||||
)}
|
||||
htmlFor={this.id}
|
||||
>
|
||||
{I18NextService.i18n.t(
|
||||
this.props.multiple ? "language_plural" : "language"
|
||||
)}
|
||||
</label>
|
||||
<div
|
||||
className={classNames(`col-sm-${this.props.multiple ? 9 : 10}`, {
|
||||
"input-group": this.props.multiple,
|
||||
})}
|
||||
>
|
||||
{this.selectBtn}
|
||||
{this.props.multiple && (
|
||||
<button
|
||||
className="btn btn-outline-secondary"
|
||||
onClick={linkEvent(this, this.handleDeselectAll)}
|
||||
>
|
||||
<Icon icon="x" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={classNames(`col-sm-${this.props.multiple ? 9 : 10}`, {
|
||||
"input-group": this.props.multiple,
|
||||
})}
|
||||
>
|
||||
{this.selectBtn}
|
||||
{this.props.multiple && (
|
||||
<button
|
||||
className="btn btn-outline-secondary"
|
||||
onClick={linkEvent(this, this.handleDeselectAll)}
|
||||
>
|
||||
<Icon icon="x" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -105,6 +108,11 @@ export class LanguageSelect extends Component<LanguageSelectProps, any> {
|
|||
id={this.id}
|
||||
onChange={linkEvent(this, this.handleLanguageChange)}
|
||||
aria-label={I18NextService.i18n.t("language_select_placeholder")}
|
||||
aria-describedby={
|
||||
this.props.multiple && this.props.showLanguageWarning
|
||||
? "lang-warning"
|
||||
: ""
|
||||
}
|
||||
multiple={this.props.multiple}
|
||||
disabled={this.props.disabled}
|
||||
>
|
||||
|
|
|
@ -4,7 +4,7 @@ import {
|
|||
CreateCommunity as CreateCommunityI,
|
||||
GetSiteResponse,
|
||||
} from "lemmy-js-client";
|
||||
import { FirstLoadService, HttpService, I18NextService } from "../../services";
|
||||
import { HttpService, I18NextService } from "../../services";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
import { CommunityForm } from "./community-form";
|
||||
|
||||
|
@ -22,8 +22,6 @@ export class CreateCommunity extends Component<any, CreateCommunityState> {
|
|||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
this.handleCommunityCreate = this.handleCommunityCreate.bind(this);
|
||||
|
||||
FirstLoadService.isFirstLoad;
|
||||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
|
|
|
@ -2,7 +2,7 @@ import { setIsoData } from "@utils/app";
|
|||
import { Component } from "inferno";
|
||||
import { GetSiteResponse } from "lemmy-js-client";
|
||||
import { mdToHtml } from "../../markdown";
|
||||
import { FirstLoadService, I18NextService } from "../../services";
|
||||
import { I18NextService } from "../../services";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
|
||||
interface LegalState {
|
||||
|
@ -17,8 +17,6 @@ export class Legal extends Component<any, LegalState> {
|
|||
|
||||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
|
||||
FirstLoadService.isFirstLoad;
|
||||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
|
|
|
@ -3,7 +3,7 @@ import { isBrowser } from "@utils/browser";
|
|||
import { validEmail } from "@utils/helpers";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import { GetSiteResponse, LoginResponse } from "lemmy-js-client";
|
||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { toast } from "../../toast";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
|
@ -32,8 +32,6 @@ export class Login extends Component<any, State> {
|
|||
|
||||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
|
||||
FirstLoadService.isFirstLoad;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
LoginResponse,
|
||||
Register,
|
||||
} from "lemmy-js-client";
|
||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { Spinner } from "../common/icon";
|
||||
import { SiteForm } from "./site-form";
|
||||
|
@ -47,8 +47,6 @@ export class Setup extends Component<any, State> {
|
|||
super(props, context);
|
||||
|
||||
this.handleCreateSite = this.handleCreateSite.bind(this);
|
||||
|
||||
FirstLoadService.isFirstLoad;
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
} from "lemmy-js-client";
|
||||
import { joinLemmyUrl } from "../../config";
|
||||
import { mdToHtml } from "../../markdown";
|
||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { toast } from "../../toast";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
|
@ -84,8 +84,6 @@ export class Signup extends Component<any, State> {
|
|||
super(props, context);
|
||||
|
||||
this.handleAnswerChange = this.handleAnswerChange.bind(this);
|
||||
|
||||
FirstLoadService.isFirstLoad;
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
|
|
|
@ -78,7 +78,6 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
slur_filter_regex: ls.slur_filter_regex,
|
||||
actor_name_max_length: ls.actor_name_max_length,
|
||||
federation_enabled: ls.federation_enabled,
|
||||
federation_worker_count: ls.federation_worker_count,
|
||||
captcha_enabled: ls.captcha_enabled,
|
||||
captcha_difficulty: ls.captcha_difficulty,
|
||||
allowed_instances: this.props.allowedInstances?.map(i => i.domain),
|
||||
|
@ -554,27 +553,6 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-3 row">
|
||||
<label
|
||||
className="col-12 col-form-label"
|
||||
htmlFor="create-site-federation-worker-count"
|
||||
>
|
||||
{I18NextService.i18n.t("federation_worker_count")}
|
||||
</label>
|
||||
<div className="col-12">
|
||||
<input
|
||||
type="number"
|
||||
id="create-site-federation-worker-count"
|
||||
className="form-control"
|
||||
min={0}
|
||||
value={this.state.siteForm.federation_worker_count}
|
||||
onInput={linkEvent(
|
||||
this,
|
||||
this.handleSiteFederationWorkerCount
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="mb-3 row">
|
||||
|
@ -781,7 +759,6 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
stateSiteForm.rate_limit_search_per_second,
|
||||
federation_enabled: stateSiteForm.federation_enabled,
|
||||
federation_debug: stateSiteForm.federation_debug,
|
||||
federation_worker_count: stateSiteForm.federation_worker_count,
|
||||
captcha_enabled: stateSiteForm.captcha_enabled,
|
||||
captcha_difficulty: stateSiteForm.captcha_difficulty,
|
||||
allowed_instances: stateSiteForm.allowed_instances,
|
||||
|
@ -982,14 +959,6 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
|||
i.setState(i.state);
|
||||
}
|
||||
|
||||
handleSiteFederationWorkerCount(i: SiteForm, event: any) {
|
||||
i.setState(
|
||||
s => (
|
||||
(s.siteForm.federation_worker_count = Number(event.target.value)), s
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
handleSiteCaptchaEnabled(i: SiteForm, event: any) {
|
||||
i.state.siteForm.captcha_enabled = event.target.checked;
|
||||
i.setState(i.state);
|
||||
|
|
|
@ -2,12 +2,7 @@ import { myAuth, setIsoData } from "@utils/app";
|
|||
import { capitalizeFirstLetter } from "@utils/helpers";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import { GetSiteResponse, LoginResponse } from "lemmy-js-client";
|
||||
import {
|
||||
FirstLoadService,
|
||||
HttpService,
|
||||
I18NextService,
|
||||
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";
|
||||
|
@ -35,8 +30,6 @@ export class PasswordChange extends Component<any, State> {
|
|||
|
||||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
|
||||
FirstLoadService.isFirstLoad;
|
||||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
|
|
|
@ -29,7 +29,7 @@ import {
|
|||
SortType,
|
||||
} from "lemmy-js-client";
|
||||
import { elementUrl, emDash, relTags } from "../../config";
|
||||
import { FirstLoadService, UserService } from "../../services";
|
||||
import { UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { I18NextService, languages } from "../../services/I18NextService";
|
||||
import { setupTippy } from "../../tippy";
|
||||
|
@ -170,8 +170,6 @@ export class Settings extends Component<any, SettingsState> {
|
|||
this.handleBlockPerson = this.handleBlockPerson.bind(this);
|
||||
this.handleBlockCommunity = this.handleBlockCommunity.bind(this);
|
||||
|
||||
FirstLoadService.isFirstLoad;
|
||||
|
||||
const mui = UserService.Instance.myUserInfo;
|
||||
if (mui) {
|
||||
const {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { setIsoData } from "@utils/app";
|
||||
import { Component } from "inferno";
|
||||
import { GetSiteResponse, VerifyEmailResponse } from "lemmy-js-client";
|
||||
import { FirstLoadService, I18NextService } from "../../services";
|
||||
import { I18NextService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { toast } from "../../toast";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
|
@ -22,8 +22,6 @@ export class VerifyEmail extends Component<any, State> {
|
|||
|
||||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
|
||||
FirstLoadService.isFirstLoad;
|
||||
}
|
||||
|
||||
async verify() {
|
||||
|
|
|
@ -17,6 +17,10 @@ export class FirstLoadService {
|
|||
return isFirst;
|
||||
}
|
||||
|
||||
falsify() {
|
||||
this.#isFirstLoad = false;
|
||||
}
|
||||
|
||||
static get #Instance() {
|
||||
return this.#instance ?? (this.#instance = new this());
|
||||
}
|
||||
|
@ -24,4 +28,8 @@ export class FirstLoadService {
|
|||
static get isFirstLoad() {
|
||||
return !isBrowser() || this.#Instance.isFirstLoad;
|
||||
}
|
||||
|
||||
static falsify() {
|
||||
this.#Instance.falsify();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
|||
const nodeExternals = require("webpack-node-externals");
|
||||
const CopyPlugin = require("copy-webpack-plugin");
|
||||
const RunNodeWebpackPlugin = require("run-node-webpack-plugin");
|
||||
const merge = require("lodash/merge");
|
||||
const merge = require("lodash.merge");
|
||||
const { ServiceWorkerPlugin } = require("service-worker-webpack");
|
||||
const BundleAnalyzerPlugin =
|
||||
require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
|
||||
|
|
19
yarn.lock
19
yarn.lock
|
@ -1595,6 +1595,18 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.2.tgz#fd2cd2edbaa7eaac7e7f3c1748b52a19143846c9"
|
||||
integrity sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==
|
||||
|
||||
"@types/lodash.isequal@^4.5.6":
|
||||
version "4.5.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash.isequal/-/lodash.isequal-4.5.6.tgz#ff42a1b8e20caa59a97e446a77dc57db923bc02b"
|
||||
integrity sha512-Ww4UGSe3DmtvLLJm2F16hDwEQSv7U0Rr8SujLUA2wHI2D2dm8kPu6Et+/y303LfjTIwSBKXB/YTUcAKpem/XEg==
|
||||
dependencies:
|
||||
"@types/lodash" "*"
|
||||
|
||||
"@types/lodash@*":
|
||||
version "4.14.195"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.195.tgz#bafc975b252eb6cea78882ce8a7b6bf22a6de632"
|
||||
integrity sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==
|
||||
|
||||
"@types/markdown-it-container@^2.0.5":
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/markdown-it-container/-/markdown-it-container-2.0.5.tgz#abd793b64c5adc7b2d1e8963eddb388198248152"
|
||||
|
@ -5916,6 +5928,11 @@ lodash.debounce@^4.0.8:
|
|||
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
|
||||
|
||||
lodash.isequal@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||
integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==
|
||||
|
||||
lodash.merge@^4.6.2:
|
||||
version "4.6.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||
|
@ -5951,7 +5968,7 @@ lodash@^3.10.1:
|
|||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
|
||||
integrity sha512-9mDDwqVIma6OZX79ZlDACZl8sBm0TEnkf99zV3iMA4GzkIT/9hiqP5mY0HoT1iNLCrKc/R1HByV+yJfRWVJryQ==
|
||||
|
||||
lodash@^4.17.20, lodash@^4.17.21:
|
||||
lodash@^4.17.20:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
|
Loading…
Reference in a new issue