mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-11-24 21:31:12 +00:00
Halfway done with redux.
This commit is contained in:
parent
4298c3fb91
commit
dc2e636f61
37 changed files with 260 additions and 125 deletions
|
@ -16,7 +16,7 @@ async function startClient() {
|
||||||
|
|
||||||
await setupDateFns();
|
await setupDateFns();
|
||||||
|
|
||||||
const store = setupRedux(windowData);
|
const store = setupRedux(windowData!);
|
||||||
|
|
||||||
const wrapper = (
|
const wrapper = (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { initializeSite, isAuthPath } from "@utils/app";
|
import { initializeSite, isAuthPath, setupRedux } from "@utils/app";
|
||||||
import { getHttpBaseInternal } from "@utils/env";
|
import { getHttpBaseInternal } from "@utils/env";
|
||||||
import { ErrorPageData } from "@utils/types";
|
import { ErrorPageData } from "@utils/types";
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
|
@ -21,7 +21,6 @@ import { getErrorPageData } from "../utils/get-error-page-data";
|
||||||
import { setForwardedHeaders } from "../utils/set-forwarded-headers";
|
import { setForwardedHeaders } from "../utils/set-forwarded-headers";
|
||||||
import { getJwtCookie } from "../utils/has-jwt-cookie";
|
import { getJwtCookie } from "../utils/has-jwt-cookie";
|
||||||
import { Provider } from "inferno-redux";
|
import { Provider } from "inferno-redux";
|
||||||
import { configureStore, createSlice } from "@reduxjs/toolkit";
|
|
||||||
|
|
||||||
export default async (req: Request, res: Response) => {
|
export default async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
|
@ -110,12 +109,7 @@ export default async (req: Request, res: Response) => {
|
||||||
errorPageData,
|
errorPageData,
|
||||||
};
|
};
|
||||||
|
|
||||||
const slice = createSlice({
|
const store = setupRedux(isoData);
|
||||||
name: "isoData",
|
|
||||||
initialState: { value: isoData },
|
|
||||||
reducers: {},
|
|
||||||
});
|
|
||||||
const store = configureStore({ reducer: slice.reducer });
|
|
||||||
|
|
||||||
const wrapper = (
|
const wrapper = (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
|
|
|
@ -17,6 +17,9 @@ import AnonymousGuard from "../common/anonymous-guard";
|
||||||
import { CodeTheme } from "./code-theme";
|
import { CodeTheme } from "./code-theme";
|
||||||
|
|
||||||
export class App extends Component<any, any> {
|
export class App extends Component<any, any> {
|
||||||
|
get isoData(): IsoDataOptionalSite {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
private readonly mainContentRef: RefObject<HTMLElement>;
|
private readonly mainContentRef: RefObject<HTMLElement>;
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
|
@ -29,8 +32,7 @@ export class App extends Component<any, any> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const reduxState: IsoDataOptionalSite = this.context.store.getState().value;
|
const siteRes = this.isoData.site_res;
|
||||||
const siteRes = reduxState.site_res;
|
|
||||||
const siteView = siteRes?.site_view;
|
const siteView = siteRes?.site_view;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -73,11 +75,16 @@ export class App extends Component<any, any> {
|
||||||
<div tabIndex={-1}>
|
<div tabIndex={-1}>
|
||||||
{RouteComponent &&
|
{RouteComponent &&
|
||||||
(isAuthPath(path ?? "") ? (
|
(isAuthPath(path ?? "") ? (
|
||||||
<AuthGuard {...routeProps}>
|
<AuthGuard
|
||||||
|
isLoggedIn={!!siteRes?.my_user}
|
||||||
|
componentProps={routeProps}
|
||||||
|
>
|
||||||
<RouteComponent {...routeProps} />
|
<RouteComponent {...routeProps} />
|
||||||
</AuthGuard>
|
</AuthGuard>
|
||||||
) : isAnonymousPath(path ?? "") ? (
|
) : isAnonymousPath(path ?? "") ? (
|
||||||
<AnonymousGuard>
|
<AnonymousGuard
|
||||||
|
isLoggedIn={!!siteRes?.my_user}
|
||||||
|
>
|
||||||
<RouteComponent {...routeProps} />
|
<RouteComponent {...routeProps} />
|
||||||
</AnonymousGuard>
|
</AnonymousGuard>
|
||||||
) : (
|
) : (
|
||||||
|
|
|
@ -38,7 +38,7 @@ function handleCollapseClick(i: Navbar) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleLogOut(i: Navbar) {
|
function handleLogOut(i: Navbar) {
|
||||||
HttpService._Instance.logout();
|
HttpService.logout();
|
||||||
handleCollapseClick(i);
|
handleCollapseClick(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,11 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
||||||
>
|
>
|
||||||
{siteView?.site.icon &&
|
{siteView?.site.icon &&
|
||||||
showAvatars(this.props.siteRes?.my_user) && (
|
showAvatars(this.props.siteRes?.my_user) && (
|
||||||
<PictrsImage src={siteView.site.icon} icon />
|
<PictrsImage
|
||||||
|
src={siteView.site.icon}
|
||||||
|
icon
|
||||||
|
myUserInfo={this.props.siteRes?.my_user}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{siteView?.site.name}
|
{siteView?.site.name}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
|
@ -379,8 +383,13 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
data-bs-toggle="dropdown"
|
data-bs-toggle="dropdown"
|
||||||
>
|
>
|
||||||
{showAvatars() && person.avatar && (
|
{showAvatars(this.props.siteRes?.my_user) &&
|
||||||
<PictrsImage src={person.avatar} icon />
|
person.avatar && (
|
||||||
|
<PictrsImage
|
||||||
|
src={person.avatar}
|
||||||
|
icon
|
||||||
|
myUserInfo={this.props.siteRes?.my_user}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{person.display_name ?? person.name}
|
{person.display_name ?? person.name}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
import { UserService } from "../../services";
|
|
||||||
import { Spinner } from "./icon";
|
import { Spinner } from "./icon";
|
||||||
|
|
||||||
|
interface AnonymousGuardProps {
|
||||||
|
isLoggedIn: boolean;
|
||||||
|
}
|
||||||
interface AnonymousGuardState {
|
interface AnonymousGuardState {
|
||||||
hasRedirected: boolean;
|
hasRedirected: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AnonymousGuard extends Component<any, AnonymousGuardState> {
|
class AnonymousGuard extends Component<
|
||||||
|
AnonymousGuardProps,
|
||||||
|
AnonymousGuardState
|
||||||
|
> {
|
||||||
state = {
|
state = {
|
||||||
hasRedirected: false,
|
hasRedirected: false,
|
||||||
} as AnonymousGuardState;
|
} as AnonymousGuardState;
|
||||||
|
@ -16,7 +21,7 @@ class AnonymousGuard extends Component<any, AnonymousGuardState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (UserService.Instance.myUserInfo) {
|
if (this.props.isLoggedIn) {
|
||||||
this.context.router.history.replace(`/`);
|
this.context.router.history.replace(`/`);
|
||||||
} else {
|
} else {
|
||||||
this.setState({ hasRedirected: true });
|
this.setState({ hasRedirected: true });
|
||||||
|
|
|
@ -1,30 +1,28 @@
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
import { RouteComponentProps } from "inferno-router/dist/Route";
|
import { RouteComponentProps } from "inferno-router/dist/Route";
|
||||||
import { UserService } from "../../services";
|
|
||||||
import { Spinner } from "./icon";
|
import { Spinner } from "./icon";
|
||||||
|
|
||||||
|
interface AuthGuardProps {
|
||||||
|
componentProps: RouteComponentProps<Record<string, string>>;
|
||||||
|
isLoggedIn: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
interface AuthGuardState {
|
interface AuthGuardState {
|
||||||
hasRedirected: boolean;
|
hasRedirected: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AuthGuard extends Component<
|
class AuthGuard extends Component<AuthGuardProps, AuthGuardState> {
|
||||||
RouteComponentProps<Record<string, string>>,
|
|
||||||
AuthGuardState
|
|
||||||
> {
|
|
||||||
state = {
|
state = {
|
||||||
hasRedirected: false,
|
hasRedirected: false,
|
||||||
} as AuthGuardState;
|
} as AuthGuardState;
|
||||||
|
|
||||||
constructor(
|
constructor(props: AuthGuardProps, context: any) {
|
||||||
props: RouteComponentProps<Record<string, string>>,
|
|
||||||
context: any,
|
|
||||||
) {
|
|
||||||
super(props, context);
|
super(props, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (!UserService.Instance.myUserInfo) {
|
if (!this.props.isLoggedIn) {
|
||||||
const { pathname, search } = this.props.location;
|
const { pathname, search } = this.props.componentProps.location;
|
||||||
this.context.router.history.replace(
|
this.context.router.history.replace(
|
||||||
`/login?prev=${encodeURIComponent(pathname + search)}`,
|
`/login?prev=${encodeURIComponent(pathname + search)}`,
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
import { PictrsImage } from "./pictrs-image";
|
import { PictrsImage } from "./pictrs-image";
|
||||||
|
import { MyUserInfo } from "lemmy-js-client";
|
||||||
|
|
||||||
interface BannerIconHeaderProps {
|
interface BannerIconHeaderProps {
|
||||||
banner?: string;
|
banner?: string;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BannerIconHeader extends Component<BannerIconHeaderProps, any> {
|
export class BannerIconHeader extends Component<BannerIconHeaderProps, any> {
|
||||||
|
@ -17,13 +19,21 @@ export class BannerIconHeader extends Component<BannerIconHeaderProps, any> {
|
||||||
return (
|
return (
|
||||||
(banner || icon) && (
|
(banner || icon) && (
|
||||||
<div className="banner-icon-header position-relative mb-2">
|
<div className="banner-icon-header position-relative mb-2">
|
||||||
{banner && <PictrsImage src={banner} banner alt="" />}
|
{banner && (
|
||||||
|
<PictrsImage
|
||||||
|
src={banner}
|
||||||
|
banner
|
||||||
|
alt=""
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{icon && (
|
{icon && (
|
||||||
<PictrsImage
|
<PictrsImage
|
||||||
src={icon}
|
src={icon}
|
||||||
iconOverlay
|
iconOverlay
|
||||||
pushup={!!this.props.banner}
|
pushup={!!this.props.banner}
|
||||||
alt=""
|
alt=""
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { randomStr } from "@utils/helpers";
|
import { randomStr } from "@utils/helpers";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, linkEvent } from "inferno";
|
||||||
import { HttpService, I18NextService, UserService } from "../../services";
|
import { HttpService, I18NextService } from "../../services";
|
||||||
import { toast } from "../../toast";
|
import { toast } from "../../toast";
|
||||||
import { Icon } from "./icon";
|
import { Icon } from "./icon";
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ interface ImageUploadFormProps {
|
||||||
onUpload(url: string): any;
|
onUpload(url: string): any;
|
||||||
onRemove(): any;
|
onRemove(): any;
|
||||||
rounded?: boolean;
|
rounded?: boolean;
|
||||||
|
isLoggedIn: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ImageUploadFormState {
|
interface ImageUploadFormState {
|
||||||
|
@ -63,7 +64,7 @@ export class ImageUploadForm extends Component<
|
||||||
accept="image/*,video/*"
|
accept="image/*,video/*"
|
||||||
className="small form-control"
|
className="small form-control"
|
||||||
name={this.id}
|
name={this.id}
|
||||||
disabled={!UserService.Instance.myUserInfo}
|
disabled={!this.props.isLoggedIn}
|
||||||
onChange={linkEvent(this, this.handleImageUpload)}
|
onChange={linkEvent(this, this.handleImageUpload)}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
import { randomStr } from "@utils/helpers";
|
import { randomStr } from "@utils/helpers";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, linkEvent } from "inferno";
|
||||||
import { ListingType } from "lemmy-js-client";
|
import { ListingType, MyUserInfo } from "lemmy-js-client";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
|
import { moderatesSomething } from "@utils/roles";
|
||||||
|
|
||||||
interface ListingTypeSelectProps {
|
interface ListingTypeSelectProps {
|
||||||
type_: ListingType;
|
type_: ListingType;
|
||||||
showLocal: boolean;
|
showLocal: boolean;
|
||||||
showSubscribed: boolean;
|
showSubscribed: boolean;
|
||||||
onChange(val: ListingType): void;
|
onChange(val: ListingType): void;
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ListingTypeSelectState {
|
interface ListingTypeSelectState {
|
||||||
|
@ -52,15 +54,15 @@ export class ListingTypeSelect extends Component<
|
||||||
value={"Subscribed"}
|
value={"Subscribed"}
|
||||||
checked={this.state.type_ === "Subscribed"}
|
checked={this.state.type_ === "Subscribed"}
|
||||||
onChange={linkEvent(this, this.handleTypeChange)}
|
onChange={linkEvent(this, this.handleTypeChange)}
|
||||||
disabled={!UserService.Instance.myUserInfo}
|
disabled={!this.props.myUserInfo}
|
||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
htmlFor={`${this.id}-subscribed`}
|
htmlFor={`${this.id}-subscribed`}
|
||||||
title={I18NextService.i18n.t("subscribed_description")}
|
title={I18NextService.i18n.t("subscribed_description")}
|
||||||
className={classNames("btn btn-outline-secondary", {
|
className={classNames("btn btn-outline-secondary", {
|
||||||
active: this.state.type_ === "Subscribed",
|
active: this.state.type_ === "Subscribed",
|
||||||
disabled: !UserService.Instance.myUserInfo,
|
disabled: !this.props.myUserInfo,
|
||||||
pointer: UserService.Instance.myUserInfo,
|
pointer: !!this.props.myUserInfo,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{I18NextService.i18n.t("subscribed")}
|
{I18NextService.i18n.t("subscribed")}
|
||||||
|
@ -107,7 +109,7 @@ export class ListingTypeSelect extends Component<
|
||||||
>
|
>
|
||||||
{I18NextService.i18n.t("all")}
|
{I18NextService.i18n.t("all")}
|
||||||
</label>
|
</label>
|
||||||
{(UserService.Instance.myUserInfo?.moderates.length ?? 0) > 0 && (
|
{moderatesSomething(this.props.myUserInfo) && (
|
||||||
<>
|
<>
|
||||||
<input
|
<input
|
||||||
id={`${this.id}-moderator-view`}
|
id={`${this.id}-moderator-view`}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
|
import { MyUserInfo } from "lemmy-js-client";
|
||||||
import { UserService } from "../../services";
|
|
||||||
|
|
||||||
const iconThumbnailSize = 96;
|
const iconThumbnailSize = 96;
|
||||||
const thumbnailSize = 256;
|
const thumbnailSize = 256;
|
||||||
|
@ -16,6 +15,7 @@ interface PictrsImageProps {
|
||||||
iconOverlay?: boolean;
|
iconOverlay?: boolean;
|
||||||
pushup?: boolean;
|
pushup?: boolean;
|
||||||
cardTop?: boolean;
|
cardTop?: boolean;
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PictrsImage extends Component<PictrsImageProps, any> {
|
export class PictrsImage extends Component<PictrsImageProps, any> {
|
||||||
|
@ -27,9 +27,9 @@ export class PictrsImage extends Component<PictrsImageProps, any> {
|
||||||
const { src, icon, iconOverlay, banner, thumbnail, nsfw, pushup, cardTop } =
|
const { src, icon, iconOverlay, banner, thumbnail, nsfw, pushup, cardTop } =
|
||||||
this.props;
|
this.props;
|
||||||
let user_blur_nsfw = true;
|
let user_blur_nsfw = true;
|
||||||
if (UserService.Instance.myUserInfo) {
|
if (this.props.myUserInfo) {
|
||||||
user_blur_nsfw =
|
user_blur_nsfw =
|
||||||
UserService.Instance.myUserInfo?.local_user_view.local_user.blur_nsfw;
|
this.props.myUserInfo?.local_user_view.local_user.blur_nsfw;
|
||||||
}
|
}
|
||||||
|
|
||||||
const blur_image = nsfw && user_blur_nsfw;
|
const blur_image = nsfw && user_blur_nsfw;
|
||||||
|
|
|
@ -3,12 +3,13 @@ import classNames from "classnames";
|
||||||
import { NoOptionI18nKeys } from "i18next";
|
import { NoOptionI18nKeys } from "i18next";
|
||||||
import { Component, MouseEventHandler, linkEvent } from "inferno";
|
import { Component, MouseEventHandler, linkEvent } from "inferno";
|
||||||
import { CommunityView } from "lemmy-js-client";
|
import { CommunityView } from "lemmy-js-client";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import { VERSION } from "../../version";
|
import { VERSION } from "../../version";
|
||||||
import { Icon, Spinner } from "./icon";
|
import { Icon, Spinner } from "./icon";
|
||||||
import { toast } from "../../toast";
|
import { toast } from "../../toast";
|
||||||
|
|
||||||
interface SubscribeButtonProps {
|
interface SubscribeButtonProps {
|
||||||
|
loggedIn: boolean;
|
||||||
communityView: CommunityView;
|
communityView: CommunityView;
|
||||||
onFollow: MouseEventHandler;
|
onFollow: MouseEventHandler;
|
||||||
onUnFollow: MouseEventHandler;
|
onUnFollow: MouseEventHandler;
|
||||||
|
@ -25,6 +26,7 @@ export function SubscribeButton({
|
||||||
onUnFollow,
|
onUnFollow,
|
||||||
loading = false,
|
loading = false,
|
||||||
isLink = false,
|
isLink = false,
|
||||||
|
loggedIn,
|
||||||
}: SubscribeButtonProps) {
|
}: SubscribeButtonProps) {
|
||||||
let i18key: NoOptionI18nKeys;
|
let i18key: NoOptionI18nKeys;
|
||||||
|
|
||||||
|
@ -51,7 +53,7 @@ export function SubscribeButton({
|
||||||
isLink ? "btn-link d-inline-block" : "d-block mb-2 w-100",
|
isLink ? "btn-link d-inline-block" : "d-block mb-2 w-100",
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!UserService.Instance.myUserInfo) {
|
if (!loggedIn) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
|
|
|
@ -186,6 +186,7 @@ export class Communities extends Component<any, CommunitiesState> {
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<SubscribeButton
|
<SubscribeButton
|
||||||
communityView={cv}
|
communityView={cv}
|
||||||
|
loggedIn={!!this.isoData.site_res.my_user}
|
||||||
onFollow={linkEvent(
|
onFollow={linkEvent(
|
||||||
{
|
{
|
||||||
i: this,
|
i: this,
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
CreateCommunity,
|
CreateCommunity,
|
||||||
EditCommunity,
|
EditCommunity,
|
||||||
Language,
|
Language,
|
||||||
|
MyUserInfo,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { I18NextService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import { Icon, Spinner } from "../common/icon";
|
import { Icon, Spinner } from "../common/icon";
|
||||||
|
@ -15,6 +16,7 @@ import { MarkdownTextArea } from "../common/markdown-textarea";
|
||||||
|
|
||||||
interface CommunityFormProps {
|
interface CommunityFormProps {
|
||||||
community_view?: CommunityView; // If a community is given, that means this is an edit
|
community_view?: CommunityView; // If a community is given, that means this is an edit
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
allLanguages: Language[];
|
allLanguages: Language[];
|
||||||
siteLanguages: number[];
|
siteLanguages: number[];
|
||||||
communityLanguages?: number[];
|
communityLanguages?: number[];
|
||||||
|
@ -166,6 +168,7 @@ export class CommunityForm extends Component<
|
||||||
imageSrc={this.state.form.icon}
|
imageSrc={this.state.form.icon}
|
||||||
onUpload={this.handleIconUpload}
|
onUpload={this.handleIconUpload}
|
||||||
onRemove={this.handleIconRemove}
|
onRemove={this.handleIconRemove}
|
||||||
|
isLoggedIn={!!this.props.myUserInfo}
|
||||||
rounded
|
rounded
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -180,6 +183,7 @@ export class CommunityForm extends Component<
|
||||||
imageSrc={this.state.form.banner}
|
imageSrc={this.state.form.banner}
|
||||||
onUpload={this.handleBannerUpload}
|
onUpload={this.handleBannerUpload}
|
||||||
onRemove={this.handleBannerRemove}
|
onRemove={this.handleBannerRemove}
|
||||||
|
isLoggedIn={!!this.props.myUserInfo}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -65,7 +65,14 @@ export class CommunityLink extends Component<CommunityLinkProps, any> {
|
||||||
{!this.props.hideAvatar &&
|
{!this.props.hideAvatar &&
|
||||||
!this.props.community.removed &&
|
!this.props.community.removed &&
|
||||||
showAvatars(this.props.myUserInfo) &&
|
showAvatars(this.props.myUserInfo) &&
|
||||||
icon && <PictrsImage src={icon} icon nsfw={nsfw} />}
|
icon && (
|
||||||
|
<PictrsImage
|
||||||
|
src={icon}
|
||||||
|
icon
|
||||||
|
nsfw={nsfw}
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<span className="overflow-wrap-anywhere">{displayName}</span>
|
<span className="overflow-wrap-anywhere">{displayName}</span>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -507,10 +507,15 @@ export class Community extends Component<
|
||||||
return (
|
return (
|
||||||
community && (
|
community && (
|
||||||
<div className="mb-2">
|
<div className="mb-2">
|
||||||
<BannerIconHeader banner={community.banner} icon={community.icon} />
|
<BannerIconHeader
|
||||||
|
banner={community.banner}
|
||||||
|
icon={community.icon}
|
||||||
|
myUserInfo={this.isoData.site_res.my_user}
|
||||||
|
/>
|
||||||
<h1 className="h4 mb-0 overflow-wrap-anywhere">{community.title}</h1>
|
<h1 className="h4 mb-0 overflow-wrap-anywhere">{community.title}</h1>
|
||||||
<CommunityLink
|
<CommunityLink
|
||||||
community={community}
|
community={community}
|
||||||
|
myUserInfo={this.isoData.site_res.my_user}
|
||||||
realLink
|
realLink
|
||||||
useApubName
|
useApubName
|
||||||
muted
|
muted
|
||||||
|
|
|
@ -46,6 +46,7 @@ export class CreateCommunity extends Component<any, CreateCommunityState> {
|
||||||
{I18NextService.i18n.t("create_community")}
|
{I18NextService.i18n.t("create_community")}
|
||||||
</h1>
|
</h1>
|
||||||
<CommunityForm
|
<CommunityForm
|
||||||
|
myUserInfo={this.isoData.site_res.my_user}
|
||||||
onUpsertCommunity={this.handleCommunityCreate}
|
onUpsertCommunity={this.handleCommunityCreate}
|
||||||
enableNsfw={enableNsfw(this.state.siteRes)}
|
enableNsfw={enableNsfw(this.state.siteRes)}
|
||||||
allLanguages={this.state.siteRes.all_languages}
|
allLanguages={this.state.siteRes.all_languages}
|
||||||
|
|
|
@ -110,6 +110,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
||||||
this.sidebar()
|
this.sidebar()
|
||||||
) : (
|
) : (
|
||||||
<CommunityForm
|
<CommunityForm
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
community_view={this.props.community_view}
|
community_view={this.props.community_view}
|
||||||
allLanguages={this.props.allLanguages}
|
allLanguages={this.props.allLanguages}
|
||||||
siteLanguages={this.props.siteLanguages}
|
siteLanguages={this.props.siteLanguages}
|
||||||
|
@ -136,6 +137,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
||||||
{this.communityTitle()}
|
{this.communityTitle()}
|
||||||
{this.props.editable && this.adminButtons()}
|
{this.props.editable && this.adminButtons()}
|
||||||
<SubscribeButton
|
<SubscribeButton
|
||||||
|
loggedIn={!!this.props.myUserInfo}
|
||||||
communityView={this.props.community_view}
|
communityView={this.props.community_view}
|
||||||
onFollow={linkEvent(this, this.handleFollowCommunity)}
|
onFollow={linkEvent(this, this.handleFollowCommunity)}
|
||||||
onUnFollow={linkEvent(this, this.handleUnfollowCommunity)}
|
onUnFollow={linkEvent(this, this.handleUnfollowCommunity)}
|
||||||
|
@ -180,7 +182,11 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
||||||
<div>
|
<div>
|
||||||
<h2 className="h5 mb-0">
|
<h2 className="h5 mb-0">
|
||||||
{this.props.showIcon && !community.removed && (
|
{this.props.showIcon && !community.removed && (
|
||||||
<BannerIconHeader icon={community.icon} banner={community.banner} />
|
<BannerIconHeader
|
||||||
|
icon={community.icon}
|
||||||
|
banner={community.banner}
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
<span className="me-2">
|
<span className="me-2">
|
||||||
<CommunityLink community={community} hideAvatar />
|
<CommunityLink community={community} hideAvatar />
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import { setIsoData } from "@utils/app";
|
|
||||||
import { isBrowser, updateDataBsTheme } from "@utils/browser";
|
import { isBrowser, updateDataBsTheme } from "@utils/browser";
|
||||||
import { getQueryParams } from "@utils/helpers";
|
import { getQueryParams } from "@utils/helpers";
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, linkEvent } from "inferno";
|
||||||
import { RouteComponentProps } from "inferno-router/dist/Route";
|
import { RouteComponentProps } from "inferno-router/dist/Route";
|
||||||
import { GetSiteResponse, LoginResponse } from "lemmy-js-client";
|
import { GetSiteResponse, LoginResponse } from "lemmy-js-client";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
HttpService,
|
HttpService,
|
||||||
|
@ -17,6 +16,9 @@ import { Spinner } from "../common/icon";
|
||||||
import PasswordInput from "../common/password-input";
|
import PasswordInput from "../common/password-input";
|
||||||
import TotpModal from "../common/totp-modal";
|
import TotpModal from "../common/totp-modal";
|
||||||
import { UnreadCounterService } from "../../services";
|
import { UnreadCounterService } from "../../services";
|
||||||
|
import { IsoData, IsoDataOptionalSite } from "../../interfaces";
|
||||||
|
import { updateSite } from "@utils/app/setup-redux";
|
||||||
|
import { EnhancedStore } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
interface LoginProps {
|
interface LoginProps {
|
||||||
prev?: string;
|
prev?: string;
|
||||||
|
@ -39,15 +41,20 @@ interface State {
|
||||||
show2faModal: boolean;
|
show2faModal: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleLoginSuccess(i: Login, loginRes: LoginResponse) {
|
async function handleLoginSuccess(
|
||||||
UserService.Instance.login({
|
i: Login,
|
||||||
|
loginRes: LoginResponse,
|
||||||
|
store: EnhancedStore<IsoDataOptionalSite>,
|
||||||
|
) {
|
||||||
|
HttpService.login({
|
||||||
res: loginRes,
|
res: loginRes,
|
||||||
});
|
});
|
||||||
const site = await HttpService.client.getSite();
|
const site = await HttpService.client.getSite();
|
||||||
|
|
||||||
if (site.state === "success") {
|
if (site.state === "success") {
|
||||||
// TODO this is the key, you need to update the redux store here
|
store.dispatch(updateSite(site.data));
|
||||||
UserService.Instance.myUserInfo = site.data.my_user;
|
|
||||||
|
// TODO why is this just the theme??
|
||||||
updateDataBsTheme(site.data);
|
updateDataBsTheme(site.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +93,7 @@ async function handleLoginSubmit(i: Login, event: any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case "success": {
|
case "success": {
|
||||||
handleLoginSuccess(i, loginRes.data);
|
handleLoginSuccess(i, loginRes.data, this.context.store);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +118,9 @@ export class Login extends Component<
|
||||||
RouteComponentProps<Record<string, never>>,
|
RouteComponentProps<Record<string, never>>,
|
||||||
State
|
State
|
||||||
> {
|
> {
|
||||||
private isoData = setIsoData(this.context);
|
get isoData(): IsoData {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
|
|
||||||
state: State = {
|
state: State = {
|
||||||
loginRes: EMPTY_REQUEST,
|
loginRes: EMPTY_REQUEST,
|
||||||
|
@ -169,7 +178,7 @@ export class Login extends Component<
|
||||||
const successful = loginRes.state === "success";
|
const successful = loginRes.state === "success";
|
||||||
if (successful) {
|
if (successful) {
|
||||||
this.setState({ show2faModal: false });
|
this.setState({ show2faModal: false });
|
||||||
handleLoginSuccess(this, loginRes.data);
|
handleLoginSuccess(this, loginRes.data, this.context.store);
|
||||||
} else {
|
} else {
|
||||||
toast(I18NextService.i18n.t("incorrect_totp_code"), "danger");
|
toast(I18NextService.i18n.t("incorrect_totp_code"), "danger");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { fetchThemeList, setIsoData } from "@utils/app";
|
import { fetchThemeList } from "@utils/app";
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, linkEvent } from "inferno";
|
||||||
import { Helmet } from "inferno-helmet";
|
import { Helmet } from "inferno-helmet";
|
||||||
import {
|
import {
|
||||||
|
@ -7,7 +7,7 @@ import {
|
||||||
LoginResponse,
|
LoginResponse,
|
||||||
Register,
|
Register,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
HttpService,
|
HttpService,
|
||||||
|
@ -17,6 +17,7 @@ import {
|
||||||
import { Spinner } from "../common/icon";
|
import { Spinner } from "../common/icon";
|
||||||
import PasswordInput from "../common/password-input";
|
import PasswordInput from "../common/password-input";
|
||||||
import { SiteForm } from "./site-form";
|
import { SiteForm } from "./site-form";
|
||||||
|
import { IsoData } from "../../interfaces";
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
form: {
|
form: {
|
||||||
|
@ -37,7 +38,9 @@ interface State {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Setup extends Component<any, State> {
|
export class Setup extends Component<any, State> {
|
||||||
private isoData = setIsoData(this.context);
|
get isoData(): IsoData {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
|
|
||||||
state: State = {
|
state: State = {
|
||||||
registerRes: EMPTY_REQUEST,
|
registerRes: EMPTY_REQUEST,
|
||||||
|
@ -45,7 +48,7 @@ export class Setup extends Component<any, State> {
|
||||||
form: {
|
form: {
|
||||||
show_nsfw: true,
|
show_nsfw: true,
|
||||||
},
|
},
|
||||||
doneRegisteringUser: !!UserService.Instance.myUserInfo,
|
doneRegisteringUser: !!this.isoData.site_res.my_user,
|
||||||
siteRes: this.isoData.site_res,
|
siteRes: this.isoData.site_res,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -194,7 +197,7 @@ export class Setup extends Component<any, State> {
|
||||||
if (i.state.registerRes.state === "success") {
|
if (i.state.registerRes.state === "success") {
|
||||||
const data = i.state.registerRes.data;
|
const data = i.state.registerRes.data;
|
||||||
|
|
||||||
UserService.Instance.login({ res: data });
|
HttpService.login({ res: data });
|
||||||
i.setState({ doneRegisteringUser: true });
|
i.setState({ doneRegisteringUser: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { Icon, Spinner } from "../common/icon";
|
||||||
import { MarkdownTextArea } from "../common/markdown-textarea";
|
import { MarkdownTextArea } from "../common/markdown-textarea";
|
||||||
import PasswordInput from "../common/password-input";
|
import PasswordInput from "../common/password-input";
|
||||||
import { IsoData } from "../../interfaces";
|
import { IsoData } from "../../interfaces";
|
||||||
|
import { updateSite } from "@utils/app/setup-redux";
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
registerRes: RequestState<LoginResponse>;
|
registerRes: RequestState<LoginResponse>;
|
||||||
|
@ -400,14 +401,15 @@ export class Signup extends Component<any, State> {
|
||||||
|
|
||||||
// Only log them in if a jwt was set
|
// Only log them in if a jwt was set
|
||||||
if (data.jwt) {
|
if (data.jwt) {
|
||||||
UserService.Instance.login({
|
HttpService.login({
|
||||||
res: data,
|
res: data,
|
||||||
});
|
});
|
||||||
|
|
||||||
const site = await HttpService.client.getSite();
|
const site = await HttpService.client.getSite();
|
||||||
|
|
||||||
|
// TODO test this
|
||||||
if (site.state === "success") {
|
if (site.state === "success") {
|
||||||
UserService.Instance.myUserInfo = site.data.my_user;
|
i.context.store.dispatch(updateSite(site.data));
|
||||||
}
|
}
|
||||||
|
|
||||||
i.props.history.replace("/communities");
|
i.props.history.replace("/communities");
|
||||||
|
|
|
@ -167,6 +167,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
||||||
imageSrc={this.state.siteForm.icon}
|
imageSrc={this.state.siteForm.icon}
|
||||||
onUpload={this.handleIconUpload}
|
onUpload={this.handleIconUpload}
|
||||||
onRemove={this.handleIconRemove}
|
onRemove={this.handleIconRemove}
|
||||||
|
isLoggedIn={!!this.props.siteRes.my_user}
|
||||||
rounded
|
rounded
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -181,6 +182,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
||||||
imageSrc={this.state.siteForm.banner}
|
imageSrc={this.state.siteForm.banner}
|
||||||
onUpload={this.handleBannerUpload}
|
onUpload={this.handleBannerUpload}
|
||||||
onRemove={this.handleBannerRemove}
|
onRemove={this.handleBannerRemove}
|
||||||
|
isLoggedIn={!!this.props.siteRes.my_user}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, linkEvent } from "inferno";
|
||||||
import { PersonView, Site, SiteAggregates } from "lemmy-js-client";
|
import { MyUserInfo, PersonView, Site, SiteAggregates } from "lemmy-js-client";
|
||||||
import { mdToHtml } from "../../markdown";
|
import { mdToHtml } from "../../markdown";
|
||||||
import { I18NextService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import { Badges } from "../common/badges";
|
import { Badges } from "../common/badges";
|
||||||
|
@ -14,6 +14,7 @@ interface SiteSidebarProps {
|
||||||
counts?: SiteAggregates;
|
counts?: SiteAggregates;
|
||||||
admins?: PersonView[];
|
admins?: PersonView[];
|
||||||
isMobile?: boolean;
|
isMobile?: boolean;
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SiteSidebarState {
|
interface SiteSidebarState {
|
||||||
|
@ -36,7 +37,10 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> {
|
||||||
<header className="card-header" id="sidebarInfoHeader">
|
<header className="card-header" id="sidebarInfoHeader">
|
||||||
{this.siteName()}
|
{this.siteName()}
|
||||||
{!this.state.collapsed && (
|
{!this.state.collapsed && (
|
||||||
<BannerIconHeader banner={this.props.site.banner} />
|
<BannerIconHeader
|
||||||
|
banner={this.props.site.banner}
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
|
@ -560,6 +560,7 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
return (
|
return (
|
||||||
<PrivateMessage
|
<PrivateMessage
|
||||||
key={i.id}
|
key={i.id}
|
||||||
|
myUserInfo={this.isoData.site_res.my_user}
|
||||||
private_message_view={i.view as PrivateMessageView}
|
private_message_view={i.view as PrivateMessageView}
|
||||||
onDelete={this.handleDeleteMessage}
|
onDelete={this.handleDeleteMessage}
|
||||||
onMarkRead={this.handleMarkMessageAsRead}
|
onMarkRead={this.handleMarkMessageAsRead}
|
||||||
|
@ -704,6 +705,7 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
<PrivateMessage
|
<PrivateMessage
|
||||||
key={pmv.private_message.id}
|
key={pmv.private_message.id}
|
||||||
private_message_view={pmv}
|
private_message_view={pmv}
|
||||||
|
myUserInfo={this.isoData.site_res.my_user}
|
||||||
onDelete={this.handleDeleteMessage}
|
onDelete={this.handleDeleteMessage}
|
||||||
onMarkRead={this.handleMarkMessageAsRead}
|
onMarkRead={this.handleMarkMessageAsRead}
|
||||||
onReport={this.handleMessageReport}
|
onReport={this.handleMessageReport}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { setIsoData } from "@utils/app";
|
|
||||||
import { capitalizeFirstLetter } from "@utils/helpers";
|
import { capitalizeFirstLetter } from "@utils/helpers";
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, linkEvent } from "inferno";
|
||||||
import { GetSiteResponse, SuccessResponse } from "lemmy-js-client";
|
import { GetSiteResponse, SuccessResponse } from "lemmy-js-client";
|
||||||
import { HttpService, I18NextService, UserService } from "../../services";
|
import { HttpService, I18NextService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
LOADING_REQUEST,
|
LOADING_REQUEST,
|
||||||
|
@ -12,6 +11,8 @@ import { HtmlTags } from "../common/html-tags";
|
||||||
import { Spinner } from "../common/icon";
|
import { Spinner } from "../common/icon";
|
||||||
import PasswordInput from "../common/password-input";
|
import PasswordInput from "../common/password-input";
|
||||||
import { toast } from "../../toast";
|
import { toast } from "../../toast";
|
||||||
|
import { IsoData } from "../../interfaces";
|
||||||
|
import { updateSite } from "@utils/app/setup-redux";
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
passwordChangeRes: RequestState<SuccessResponse>;
|
passwordChangeRes: RequestState<SuccessResponse>;
|
||||||
|
@ -24,7 +25,9 @@ interface State {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PasswordChange extends Component<any, State> {
|
export class PasswordChange extends Component<any, State> {
|
||||||
private isoData = setIsoData(this.context);
|
get isoData(): IsoData {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
|
|
||||||
state: State = {
|
state: State = {
|
||||||
passwordChangeRes: EMPTY_REQUEST,
|
passwordChangeRes: EMPTY_REQUEST,
|
||||||
|
@ -128,9 +131,10 @@ export class PasswordChange extends Component<any, State> {
|
||||||
if (i.state.passwordChangeRes.state === "success") {
|
if (i.state.passwordChangeRes.state === "success") {
|
||||||
toast(I18NextService.i18n.t("password_changed"));
|
toast(I18NextService.i18n.t("password_changed"));
|
||||||
|
|
||||||
|
// TODO test this
|
||||||
const site = await HttpService.client.getSite();
|
const site = await HttpService.client.getSite();
|
||||||
if (site.state === "success") {
|
if (site.state === "success") {
|
||||||
UserService.Instance.myUserInfo = site.data.my_user;
|
i.context.store.dispatch(updateSite(site.data));
|
||||||
}
|
}
|
||||||
|
|
||||||
i.props.history.replace("/");
|
i.props.history.replace("/");
|
||||||
|
|
|
@ -92,6 +92,7 @@ export class PersonListing extends Component<PersonListingProps, any> {
|
||||||
<PictrsImage
|
<PictrsImage
|
||||||
src={avatar ?? `${getStaticDir()}/assets/icons/icon-96x96.png`}
|
src={avatar ?? `${getStaticDir()}/assets/icons/icon-96x96.png`}
|
||||||
icon
|
icon
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<span>{displayName}</span>
|
<span>{displayName}</span>
|
||||||
|
|
|
@ -490,6 +490,7 @@ export class Profile extends Component<
|
||||||
<BannerIconHeader
|
<BannerIconHeader
|
||||||
banner={pv.person.banner}
|
banner={pv.person.banner}
|
||||||
icon={pv.person.avatar}
|
icon={pv.person.avatar}
|
||||||
|
myUserInfo={this.isoData.site_res.my_user}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
|
|
|
@ -4,7 +4,6 @@ import {
|
||||||
fetchThemeList,
|
fetchThemeList,
|
||||||
fetchUsers,
|
fetchUsers,
|
||||||
instanceToChoice,
|
instanceToChoice,
|
||||||
myAuth,
|
|
||||||
personToChoice,
|
personToChoice,
|
||||||
setTheme,
|
setTheme,
|
||||||
showLocal,
|
showLocal,
|
||||||
|
@ -64,6 +63,7 @@ import TotpModal from "../common/totp-modal";
|
||||||
import { LoadingEllipses } from "../common/loading-ellipses";
|
import { LoadingEllipses } from "../common/loading-ellipses";
|
||||||
import { updateDataBsTheme } from "../../utils/browser";
|
import { updateDataBsTheme } from "../../utils/browser";
|
||||||
import { getHttpBaseInternal } from "../../utils/env";
|
import { getHttpBaseInternal } from "../../utils/env";
|
||||||
|
import { updateSite } from "@utils/app/setup-redux";
|
||||||
|
|
||||||
type SettingsData = RouteDataResponse<{
|
type SettingsData = RouteDataResponse<{
|
||||||
instancesRes: GetFederatedInstancesResponse;
|
instancesRes: GetFederatedInstancesResponse;
|
||||||
|
@ -763,6 +763,7 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
imageSrc={this.state.saveUserSettingsForm.avatar}
|
imageSrc={this.state.saveUserSettingsForm.avatar}
|
||||||
onUpload={this.handleAvatarUpload}
|
onUpload={this.handleAvatarUpload}
|
||||||
onRemove={this.handleAvatarRemove}
|
onRemove={this.handleAvatarRemove}
|
||||||
|
isLoggedIn={!!this.isoData.site_res.my_user}
|
||||||
rounded
|
rounded
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -777,6 +778,7 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
imageSrc={this.state.saveUserSettingsForm.banner}
|
imageSrc={this.state.saveUserSettingsForm.banner}
|
||||||
onUpload={this.handleBannerUpload}
|
onUpload={this.handleBannerUpload}
|
||||||
onRemove={this.handleBannerRemove}
|
onRemove={this.handleBannerRemove}
|
||||||
|
isLoggedIn={!!this.isoData.site_res.my_user}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1298,14 +1300,12 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleUnblockCommunity(i: { ctx: Settings; communityId: number }) {
|
async handleUnblockCommunity(i: { ctx: Settings; communityId: number }) {
|
||||||
if (myAuth()) {
|
|
||||||
const res = await HttpService.client.blockCommunity({
|
const res = await HttpService.client.blockCommunity({
|
||||||
community_id: i.communityId,
|
community_id: i.communityId,
|
||||||
block: false,
|
block: false,
|
||||||
});
|
});
|
||||||
i.ctx.communityBlock(res);
|
i.ctx.communityBlock(res);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async handleBlockInstance({ value }: Choice) {
|
async handleBlockInstance({ value }: Choice) {
|
||||||
if (value !== "0") {
|
if (value !== "0") {
|
||||||
|
@ -1530,8 +1530,8 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
siteRes: siteRes.data,
|
siteRes: siteRes.data,
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO need to update this
|
// TODO need to test this
|
||||||
UserService.Instance.myUserInfo = siteRes.data.my_user;
|
i.context.store.dispatch(updateSite(siteRes.data));
|
||||||
}
|
}
|
||||||
|
|
||||||
toast(I18NextService.i18n.t("saved"));
|
toast(I18NextService.i18n.t("saved"));
|
||||||
|
@ -1631,8 +1631,8 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
},
|
},
|
||||||
} = siteRes.data.my_user!.local_user_view;
|
} = siteRes.data.my_user!.local_user_view;
|
||||||
|
|
||||||
// TODO need to update redux
|
// TODO need to test this
|
||||||
UserService.Instance.myUserInfo = siteRes.data.my_user;
|
i.context.store.dispatch(updateSite(siteRes.data));
|
||||||
updateDataBsTheme(siteRes.data);
|
updateDataBsTheme(siteRes.data);
|
||||||
|
|
||||||
i.setState(prev => ({
|
i.setState(prev => ({
|
||||||
|
@ -1695,7 +1695,7 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
delete_content: false,
|
delete_content: false,
|
||||||
});
|
});
|
||||||
if (deleteAccountRes.state === "success") {
|
if (deleteAccountRes.state === "success") {
|
||||||
UserService.Instance.logout();
|
HttpService.logout();
|
||||||
this.context.router.history.replace("/");
|
this.context.router.history.replace("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { myAuth } from "@utils/app";
|
|
||||||
import { canShare, share } from "@utils/browser";
|
import { canShare, share } from "@utils/browser";
|
||||||
import { getExternalHost, getHttpBase } from "@utils/env";
|
import { getExternalHost, getHttpBase } from "@utils/env";
|
||||||
import {
|
import {
|
||||||
|
@ -255,7 +254,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
<>
|
<>
|
||||||
<div className="offset-sm-3 my-2 d-none d-sm-block">
|
<div className="offset-sm-3 my-2 d-none d-sm-block">
|
||||||
<a href={this.imageSrc} className="d-inline-block">
|
<a href={this.imageSrc} className="d-inline-block">
|
||||||
<PictrsImage src={this.imageSrc} />
|
<PictrsImage
|
||||||
|
src={this.imageSrc}
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
|
/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div className="my-2 d-block d-sm-none">
|
<div className="my-2 d-block d-sm-none">
|
||||||
|
@ -264,7 +266,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
className="p-0 border-0 bg-transparent d-inline-block"
|
className="p-0 border-0 bg-transparent d-inline-block"
|
||||||
onClick={linkEvent(this, this.handleImageExpandClick)}
|
onClick={linkEvent(this, this.handleImageExpandClick)}
|
||||||
>
|
>
|
||||||
<PictrsImage src={this.imageSrc} />
|
<PictrsImage
|
||||||
|
src={this.imageSrc}
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
@ -310,6 +315,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
thumbnail
|
thumbnail
|
||||||
alt=""
|
alt=""
|
||||||
nsfw={pv.post.nsfw || pv.community.nsfw}
|
nsfw={pv.post.nsfw || pv.community.nsfw}
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -630,7 +636,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
{mobile && !this.props.viewOnly && (
|
{mobile && !this.props.viewOnly && (
|
||||||
<VoteButtonsCompact
|
<VoteButtonsCompact
|
||||||
voteContentType={VoteContentType.Post}
|
voteContentType={VoteContentType.Post}
|
||||||
loggedIn={!!this.props.myUserInfo}
|
myUserInfo={this.props.myUserInfo}
|
||||||
id={this.postView.post.id}
|
id={this.postView.post.id}
|
||||||
onVote={this.props.onPostVote}
|
onVote={this.props.onPostVote}
|
||||||
enableDownvotes={this.props.enableDownvotes}
|
enableDownvotes={this.props.enableDownvotes}
|
||||||
|
@ -1383,7 +1389,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
<div className="col flex-grow-0">
|
<div className="col flex-grow-0">
|
||||||
<VoteButtons
|
<VoteButtons
|
||||||
voteContentType={VoteContentType.Post}
|
voteContentType={VoteContentType.Post}
|
||||||
loggedIn={!!this.props.myUserInfo}
|
myUserInfo={this.props.myUserInfo}
|
||||||
id={this.postView.post.id}
|
id={this.postView.post.id}
|
||||||
onVote={this.props.onPostVote}
|
onVote={this.props.onPostVote}
|
||||||
enableDownvotes={this.props.enableDownvotes}
|
enableDownvotes={this.props.enableDownvotes}
|
||||||
|
@ -1716,7 +1722,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
i.setState({ imageExpanded: !i.state.imageExpanded });
|
i.setState({ imageExpanded: !i.state.imageExpanded });
|
||||||
setupTippy();
|
setupTippy();
|
||||||
|
|
||||||
if (myAuth() && !i.postView.read) {
|
if (!!this.props.myUserInfo && !i.postView.read) {
|
||||||
i.props.onMarkPostAsRead({
|
i.props.onMarkPostAsRead({
|
||||||
post_ids: [i.postView.post.id],
|
post_ids: [i.postView.post.id],
|
||||||
read: true,
|
read: true,
|
||||||
|
|
|
@ -5,11 +5,12 @@ import {
|
||||||
DeletePrivateMessage,
|
DeletePrivateMessage,
|
||||||
EditPrivateMessage,
|
EditPrivateMessage,
|
||||||
MarkPrivateMessageAsRead,
|
MarkPrivateMessageAsRead,
|
||||||
|
MyUserInfo,
|
||||||
Person,
|
Person,
|
||||||
PrivateMessageView,
|
PrivateMessageView,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { mdToHtml } from "../../markdown";
|
import { mdToHtml } from "../../markdown";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import { Icon, Spinner } from "../common/icon";
|
import { Icon, Spinner } from "../common/icon";
|
||||||
import { MomentTime } from "../common/moment-time";
|
import { MomentTime } from "../common/moment-time";
|
||||||
import { PersonListing } from "../person/person-listing";
|
import { PersonListing } from "../person/person-listing";
|
||||||
|
@ -28,6 +29,7 @@ interface PrivateMessageState {
|
||||||
|
|
||||||
interface PrivateMessageProps {
|
interface PrivateMessageProps {
|
||||||
private_message_view: PrivateMessageView;
|
private_message_view: PrivateMessageView;
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
onDelete(form: DeletePrivateMessage): void;
|
onDelete(form: DeletePrivateMessage): void;
|
||||||
onMarkRead(form: MarkPrivateMessageAsRead): void;
|
onMarkRead(form: MarkPrivateMessageAsRead): void;
|
||||||
onReport(form: CreatePrivateMessageReport): void;
|
onReport(form: CreatePrivateMessageReport): void;
|
||||||
|
@ -57,7 +59,7 @@ export class PrivateMessage extends Component<
|
||||||
|
|
||||||
get mine(): boolean {
|
get mine(): boolean {
|
||||||
return (
|
return (
|
||||||
UserService.Instance.myUserInfo?.local_user_view.person.id ===
|
this.props.myUserInfo?.local_user_view.person.id ===
|
||||||
this.props.private_message_view.creator.id
|
this.props.private_message_view.creator.id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,11 @@ export class RemoteFetch extends Component<any, RemoteFetchState> {
|
||||||
<h1>{I18NextService.i18n.t("community_federated")}</h1>
|
<h1>{I18NextService.i18n.t("community_federated")}</h1>
|
||||||
<div className="card mt-5">
|
<div className="card mt-5">
|
||||||
{communityView.community.banner && (
|
{communityView.community.banner && (
|
||||||
<PictrsImage src={communityView.community.banner} cardTop />
|
<PictrsImage
|
||||||
|
src={communityView.community.banner}
|
||||||
|
cardTop
|
||||||
|
myUserInfo={this.isoData.site_res.my_user}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<h2 className="card-title">
|
<h2 className="card-title">
|
||||||
|
@ -163,6 +167,7 @@ export class RemoteFetch extends Component<any, RemoteFetchState> {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<SubscribeButton
|
<SubscribeButton
|
||||||
|
loggedIn={!!this.isoData.site_res.my_user}
|
||||||
communityView={communityView}
|
communityView={communityView}
|
||||||
onFollow={linkEvent(this, handleFollow)}
|
onFollow={linkEvent(this, handleFollow)}
|
||||||
onUnFollow={linkEvent(this, handleUnfollow)}
|
onUnFollow={linkEvent(this, handleUnfollow)}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import {
|
||||||
fetchCommunities,
|
fetchCommunities,
|
||||||
fetchUsers,
|
fetchUsers,
|
||||||
getUpdatedSearchId,
|
getUpdatedSearchId,
|
||||||
myAuth,
|
|
||||||
personToChoice,
|
personToChoice,
|
||||||
showLocal,
|
showLocal,
|
||||||
} from "@utils/app";
|
} from "@utils/app";
|
||||||
|
@ -979,7 +978,7 @@ export class Search extends Component<any, SearchState> {
|
||||||
window.scrollTo(0, 0);
|
window.scrollTo(0, 0);
|
||||||
restoreScrollPosition(this.context);
|
restoreScrollPosition(this.context);
|
||||||
|
|
||||||
if (myAuth()) {
|
if (this.isoData.site_res.my_user) {
|
||||||
this.setState({ resolveObjectRes: LOADING_REQUEST });
|
this.setState({ resolveObjectRes: LOADING_REQUEST });
|
||||||
this.setState({
|
this.setState({
|
||||||
resolveObjectRes: await HttpService.silent_client.resolveObject({
|
resolveObjectRes: await HttpService.silent_client.resolveObject({
|
||||||
|
|
|
@ -104,6 +104,9 @@ export function wrapClient(client: LemmyHttp, silent = false) {
|
||||||
// auth: string;
|
// auth: string;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An HTTP service, only to be used in the browser client
|
||||||
|
*/
|
||||||
export class HttpService {
|
export class HttpService {
|
||||||
static #_instance: HttpService;
|
static #_instance: HttpService;
|
||||||
#silent_client: WrappedLemmyHttp;
|
#silent_client: WrappedLemmyHttp;
|
||||||
|
@ -114,13 +117,13 @@ export class HttpService {
|
||||||
const auth = cookie.parse(document.cookie)[authCookieName];
|
const auth = cookie.parse(document.cookie)[authCookieName];
|
||||||
|
|
||||||
if (auth) {
|
if (auth) {
|
||||||
HttpService.client.setHeaders({ Authorization: `Bearer ${auth}` });
|
lemmyHttp.setHeaders({ Authorization: `Bearer ${auth}` });
|
||||||
}
|
}
|
||||||
this.#client = wrapClient(lemmyHttp);
|
this.#client = wrapClient(lemmyHttp);
|
||||||
this.#silent_client = wrapClient(lemmyHttp, true);
|
this.#silent_client = wrapClient(lemmyHttp, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public login({
|
public static login({
|
||||||
res,
|
res,
|
||||||
showToast = true,
|
showToast = true,
|
||||||
}: {
|
}: {
|
||||||
|
@ -130,15 +133,17 @@ export class HttpService {
|
||||||
if (isBrowser() && res.jwt) {
|
if (isBrowser() && res.jwt) {
|
||||||
showToast && toast(I18NextService.i18n.t("logged_in"));
|
showToast && toast(I18NextService.i18n.t("logged_in"));
|
||||||
setAuthCookie(res.jwt);
|
setAuthCookie(res.jwt);
|
||||||
|
const headers = { Authorization: `Bearer ${res.jwt}` };
|
||||||
|
this.#_instance.#client.setHeaders(headers);
|
||||||
|
this.#_instance.#silent_client.setHeaders(headers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public logout() {
|
public static logout() {
|
||||||
if (isBrowser()) {
|
if (isBrowser()) {
|
||||||
clearAuthCookie();
|
clearAuthCookie();
|
||||||
}
|
}
|
||||||
|
this.#_instance.#client.logout();
|
||||||
this.#client.logout();
|
|
||||||
|
|
||||||
if (isAuthPath(location.pathname)) {
|
if (isAuthPath(location.pathname)) {
|
||||||
location.replace("/");
|
location.replace("/");
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { isBrowser } from "@utils/browser";
|
import { isBrowser } from "@utils/browser";
|
||||||
import i18next, { Resource } from "i18next";
|
import i18next, { Resource } from "i18next";
|
||||||
import { UserService } from "../services";
|
|
||||||
import { ar } from "../translations/ar";
|
import { ar } from "../translations/ar";
|
||||||
import { bg } from "../translations/bg";
|
import { bg } from "../translations/bg";
|
||||||
import { ca } from "../translations/ca";
|
import { ca } from "../translations/ca";
|
||||||
|
@ -32,6 +31,7 @@ import { sv } from "../translations/sv";
|
||||||
import { vi } from "../translations/vi";
|
import { vi } from "../translations/vi";
|
||||||
import { zh } from "../translations/zh";
|
import { zh } from "../translations/zh";
|
||||||
import { zh_Hant } from "../translations/zh_Hant";
|
import { zh_Hant } from "../translations/zh_Hant";
|
||||||
|
import { MyUserInfo } from "lemmy-js-client";
|
||||||
|
|
||||||
export const languages = [
|
export const languages = [
|
||||||
{ resource: ar, code: "ar", name: "العربية" },
|
{ resource: ar, code: "ar", name: "العربية" },
|
||||||
|
@ -74,20 +74,24 @@ function format(value: any, format: any): any {
|
||||||
return format === "uppercase" ? value.toUpperCase() : value;
|
return format === "uppercase" ? value.toUpperCase() : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
class LanguageDetector {
|
export class LanguageDetector {
|
||||||
static readonly type = "languageDetector";
|
static readonly type = "languageDetector";
|
||||||
|
private myLanguages: string[];
|
||||||
|
|
||||||
|
// TODO What's going on here? test this.
|
||||||
detect() {
|
detect() {
|
||||||
|
return this.myLanguages;
|
||||||
|
}
|
||||||
|
|
||||||
|
setupMyLanguages(myUserInfo?: MyUserInfo): string[] {
|
||||||
const langs: string[] = [];
|
const langs: string[] = [];
|
||||||
|
|
||||||
const myLang =
|
const myLang =
|
||||||
UserService.Instance.myUserInfo?.local_user_view.local_user
|
myUserInfo?.local_user_view.local_user.interface_language ?? "browser";
|
||||||
.interface_language ?? "browser";
|
|
||||||
|
|
||||||
if (myLang !== "browser") langs.push(myLang);
|
if (myLang !== "browser") langs.push(myLang);
|
||||||
|
|
||||||
if (isBrowser()) langs.push(...navigator.languages);
|
if (isBrowser()) langs.push(...navigator.languages);
|
||||||
|
|
||||||
return langs;
|
return langs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { HttpService } from "../services";
|
import { HttpService } from "../services";
|
||||||
import { updateUnreadCountsInterval } from "../config";
|
import { updateUnreadCountsInterval } from "../config";
|
||||||
import { poll } from "@utils/helpers";
|
import { poll } from "@utils/helpers";
|
||||||
import { myAuth } from "@utils/app";
|
import { amAdmin, moderatesSomething } from "@utils/roles";
|
||||||
import { amAdmin } from "@utils/roles";
|
|
||||||
import { isBrowser } from "@utils/browser";
|
import { isBrowser } from "@utils/browser";
|
||||||
import { BehaviorSubject } from "rxjs";
|
import { BehaviorSubject } from "rxjs";
|
||||||
|
import { MyUserInfo } from "lemmy-js-client";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service to poll and keep track of unread messages / notifications.
|
* Service to poll and keep track of unread messages / notifications.
|
||||||
|
@ -14,6 +14,8 @@ export class UnreadCounterService {
|
||||||
unreadPrivateMessages = 0;
|
unreadPrivateMessages = 0;
|
||||||
unreadReplies = 0;
|
unreadReplies = 0;
|
||||||
unreadMentions = 0;
|
unreadMentions = 0;
|
||||||
|
myUserInfo?: MyUserInfo = undefined;
|
||||||
|
|
||||||
public unreadInboxCountSubject: BehaviorSubject<number> =
|
public unreadInboxCountSubject: BehaviorSubject<number> =
|
||||||
new BehaviorSubject<number>(0);
|
new BehaviorSubject<number>(0);
|
||||||
|
|
||||||
|
@ -36,15 +38,19 @@ export class UnreadCounterService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setMyUserInfo(myUserInfo: MyUserInfo) {
|
||||||
|
this.myUserInfo = myUserInfo;
|
||||||
|
}
|
||||||
|
|
||||||
private get shouldUpdate() {
|
private get shouldUpdate() {
|
||||||
if (window.document.visibilityState === "hidden") {
|
if (window.document.visibilityState === "hidden") {
|
||||||
return false;
|
return false;
|
||||||
}
|
} else if (!this.myUserInfo) {
|
||||||
if (!myAuth()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async updateInboxCounts() {
|
public async updateInboxCounts() {
|
||||||
if (this.shouldUpdate) {
|
if (this.shouldUpdate) {
|
||||||
|
@ -61,7 +67,7 @@ export class UnreadCounterService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateReports() {
|
public async updateReports() {
|
||||||
if (this.shouldUpdate && UserService.Instance.moderatesSomething) {
|
if (this.shouldUpdate && moderatesSomething(this.myUserInfo)) {
|
||||||
const reportCountRes = await HttpService.client.getReportCount({});
|
const reportCountRes = await HttpService.client.getReportCount({});
|
||||||
if (reportCountRes.state === "success") {
|
if (reportCountRes.state === "success") {
|
||||||
this.commentReportCount = reportCountRes.data.comment_reports ?? 0;
|
this.commentReportCount = reportCountRes.data.comment_reports ?? 0;
|
||||||
|
@ -78,7 +84,7 @@ export class UnreadCounterService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateApplications() {
|
public async updateApplications() {
|
||||||
if (this.shouldUpdate && amAdmin()) {
|
if (this.shouldUpdate && amAdmin(this.myUserInfo)) {
|
||||||
const unreadApplicationsRes =
|
const unreadApplicationsRes =
|
||||||
await HttpService.client.getUnreadRegistrationApplicationCount();
|
await HttpService.client.getUnreadRegistrationApplicationCount();
|
||||||
if (unreadApplicationsRes.state === "success") {
|
if (unreadApplicationsRes.state === "success") {
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
import { GetSiteResponse } from "lemmy-js-client";
|
import { GetSiteResponse } from "lemmy-js-client";
|
||||||
import { setupEmojiDataModel, setupMarkdown } from "../../markdown";
|
import { setupEmojiDataModel, setupMarkdown } from "../../markdown";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import { updateDataBsTheme } from "@utils/browser";
|
import { updateDataBsTheme } from "@utils/browser";
|
||||||
|
import { LanguageDetector } from "shared/services/I18NextService";
|
||||||
|
|
||||||
export default function initializeSite(site?: GetSiteResponse) {
|
export default function initializeSite(site?: GetSiteResponse) {
|
||||||
// TODO Should already be in siteRes
|
|
||||||
UserService.Instance.myUserInfo = site?.my_user;
|
|
||||||
updateDataBsTheme(site);
|
updateDataBsTheme(site);
|
||||||
|
|
||||||
|
// TODO test this
|
||||||
|
const ld = new LanguageDetector();
|
||||||
|
ld.setupMyLanguages(site?.my_user);
|
||||||
|
|
||||||
I18NextService.i18n.changeLanguage();
|
I18NextService.i18n.changeLanguage();
|
||||||
if (site) {
|
if (site) {
|
||||||
setupEmojiDataModel(site.custom_emojis ?? []);
|
setupEmojiDataModel(site.custom_emojis ?? []);
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
import { isBrowser } from "@utils/browser";
|
import { isBrowser } from "@utils/browser";
|
||||||
import { toast } from "../../../shared/toast";
|
import { toast } from "../../../shared/toast";
|
||||||
import { I18NextService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
|
import cookie from "cookie";
|
||||||
|
import { authCookieName } from "../../config";
|
||||||
|
|
||||||
|
// TODO get rid of this
|
||||||
export default function myAuth(throwErr = false): string | undefined {
|
export default function myAuth(throwErr = false): string | undefined {
|
||||||
|
const auth = cookie.parse(document.cookie)[authCookieName];
|
||||||
if (auth) {
|
if (auth) {
|
||||||
return auth;
|
return auth;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,13 +1,33 @@
|
||||||
import { configureStore, createSlice } from "@reduxjs/toolkit";
|
import { PayloadAction, configureStore, createSlice } from "@reduxjs/toolkit";
|
||||||
import { IsoDataOptionalSite } from "../../../shared/interfaces";
|
import { IsoDataOptionalSite } from "../../../shared/interfaces";
|
||||||
|
import { GetSiteResponse } from "lemmy-js-client";
|
||||||
|
|
||||||
// TODO add reducer function here
|
interface isoDataState {
|
||||||
export default function setupRedux(isoData?: IsoDataOptionalSite) {
|
value?: IsoDataOptionalSite;
|
||||||
const slice = createSlice({
|
}
|
||||||
|
|
||||||
|
const initialState: isoDataState = {
|
||||||
|
value: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isoDataSlice = createSlice({
|
||||||
name: "isoData",
|
name: "isoData",
|
||||||
initialState: { value: isoData },
|
initialState,
|
||||||
reducers: {},
|
reducers: {
|
||||||
});
|
updateIsoData: (state, action: PayloadAction<IsoDataOptionalSite>) => {
|
||||||
const store = configureStore({ reducer: slice.reducer });
|
state.value = action.payload;
|
||||||
|
},
|
||||||
|
updateSite: (state, action: PayloadAction<GetSiteResponse>) => {
|
||||||
|
state.value!.site_res = action.payload;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { updateIsoData, updateSite } = isoDataSlice.actions;
|
||||||
|
|
||||||
|
export default function setupRedux(isoData: IsoDataOptionalSite) {
|
||||||
|
const store = configureStore({ reducer: isoDataSlice.reducer });
|
||||||
|
store.dispatch(updateIsoData(isoData));
|
||||||
|
|
||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue