mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-11-08 09:34:16 +00:00
About 1/3rd done with adding redux.
This commit is contained in:
parent
fc234716b0
commit
4298c3fb91
|
@ -43,6 +43,7 @@
|
||||||
"@babel/preset-typescript": "^7.21.5",
|
"@babel/preset-typescript": "^7.21.5",
|
||||||
"@babel/runtime": "^7.21.5",
|
"@babel/runtime": "^7.21.5",
|
||||||
"@emoji-mart/data": "^1.1.0",
|
"@emoji-mart/data": "^1.1.0",
|
||||||
|
"@reduxjs/toolkit": "^2.0.1",
|
||||||
"@shortcm/qr-image": "^9.0.2",
|
"@shortcm/qr-image": "^9.0.2",
|
||||||
"autosize": "^6.0.1",
|
"autosize": "^6.0.1",
|
||||||
"babel-loader": "^9.1.3",
|
"babel-loader": "^9.1.3",
|
||||||
|
@ -67,6 +68,7 @@
|
||||||
"inferno-helmet": "^5.2.1",
|
"inferno-helmet": "^5.2.1",
|
||||||
"inferno-hydrate": "^8.2.2",
|
"inferno-hydrate": "^8.2.2",
|
||||||
"inferno-i18next-dess": "0.0.2",
|
"inferno-i18next-dess": "0.0.2",
|
||||||
|
"inferno-redux": "^8.2.2",
|
||||||
"inferno-router": "^8.2.2",
|
"inferno-router": "^8.2.2",
|
||||||
"inferno-server": "^8.2.2",
|
"inferno-server": "^8.2.2",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
|
@ -83,6 +85,7 @@
|
||||||
"markdown-it-sub": "^1.0.0",
|
"markdown-it-sub": "^1.0.0",
|
||||||
"markdown-it-sup": "^1.0.0",
|
"markdown-it-sup": "^1.0.0",
|
||||||
"mini-css-extract-plugin": "^2.7.5",
|
"mini-css-extract-plugin": "^2.7.5",
|
||||||
|
"redux": "^5.0.0",
|
||||||
"register-service-worker": "^1.7.2",
|
"register-service-worker": "^1.7.2",
|
||||||
"run-node-webpack-plugin": "^1.3.0",
|
"run-node-webpack-plugin": "^1.3.0",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { initializeSite, setupDateFns } from "@utils/app";
|
import { initializeSite, setupDateFns, setupRedux } from "@utils/app";
|
||||||
import { hydrate } from "inferno-hydrate";
|
import { hydrate } from "inferno-hydrate";
|
||||||
import { BrowserRouter } from "inferno-router";
|
import { BrowserRouter } from "inferno-router";
|
||||||
import { App } from "../shared/components/app/app";
|
import { App } from "../shared/components/app/app";
|
||||||
|
@ -6,16 +6,24 @@ import { App } from "../shared/components/app/app";
|
||||||
import "bootstrap/js/dist/collapse";
|
import "bootstrap/js/dist/collapse";
|
||||||
import "bootstrap/js/dist/dropdown";
|
import "bootstrap/js/dist/dropdown";
|
||||||
import "bootstrap/js/dist/modal";
|
import "bootstrap/js/dist/modal";
|
||||||
|
import { Provider } from "inferno-redux";
|
||||||
|
|
||||||
async function startClient() {
|
async function startClient() {
|
||||||
initializeSite(window.isoData.site_res);
|
const windowData = window.isoData;
|
||||||
|
delete window.isoData;
|
||||||
|
|
||||||
|
initializeSite(windowData?.site_res);
|
||||||
|
|
||||||
await setupDateFns();
|
await setupDateFns();
|
||||||
|
|
||||||
|
const store = setupRedux(windowData);
|
||||||
|
|
||||||
const wrapper = (
|
const wrapper = (
|
||||||
<BrowserRouter>
|
<Provider store={store}>
|
||||||
<App />
|
<BrowserRouter>
|
||||||
</BrowserRouter>
|
<App />
|
||||||
|
</BrowserRouter>
|
||||||
|
</Provider>
|
||||||
);
|
);
|
||||||
|
|
||||||
const root = document.getElementById("root");
|
const root = document.getElementById("root");
|
||||||
|
|
|
@ -20,6 +20,8 @@ import { createSsrHtml } from "../utils/create-ssr-html";
|
||||||
import { getErrorPageData } from "../utils/get-error-page-data";
|
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 { configureStore, createSlice } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
export default async (req: Request, res: Response) => {
|
export default async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
|
@ -108,10 +110,19 @@ export default async (req: Request, res: Response) => {
|
||||||
errorPageData,
|
errorPageData,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const slice = createSlice({
|
||||||
|
name: "isoData",
|
||||||
|
initialState: { value: isoData },
|
||||||
|
reducers: {},
|
||||||
|
});
|
||||||
|
const store = configureStore({ reducer: slice.reducer });
|
||||||
|
|
||||||
const wrapper = (
|
const wrapper = (
|
||||||
<StaticRouter location={url} context={isoData}>
|
<Provider store={store}>
|
||||||
<App />
|
<StaticRouter location={url} context={{}}>
|
||||||
</StaticRouter>
|
<App />
|
||||||
|
</StaticRouter>
|
||||||
|
</Provider>
|
||||||
);
|
);
|
||||||
|
|
||||||
const root = renderToString(wrapper);
|
const root = renderToString(wrapper);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { isAnonymousPath, isAuthPath, setIsoData } from "@utils/app";
|
import { isAnonymousPath, isAuthPath } from "@utils/app";
|
||||||
import { dataBsTheme } from "@utils/browser";
|
import { dataBsTheme } from "@utils/browser";
|
||||||
import { Component, RefObject, createRef, linkEvent } from "inferno";
|
import { Component, RefObject, createRef, linkEvent } from "inferno";
|
||||||
import { Provider } from "inferno-i18next-dess";
|
import { Provider } from "inferno-i18next-dess";
|
||||||
|
@ -17,20 +17,20 @@ 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> {
|
||||||
private isoData: IsoDataOptionalSite = setIsoData(this.context);
|
|
||||||
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);
|
||||||
this.mainContentRef = createRef();
|
this.mainContentRef = createRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleJumpToContent(event) {
|
handleJumpToContent(event: any) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.mainContentRef.current?.focus();
|
this.mainContentRef.current?.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const siteRes = this.isoData.site_res;
|
const reduxState: IsoDataOptionalSite = this.context.store.getState().value;
|
||||||
|
const siteRes = reduxState.site_res;
|
||||||
const siteView = siteRes?.site_view;
|
const siteView = siteRes?.site_view;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { setIsoData } from "@utils/app";
|
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
import { T } from "inferno-i18next-dess";
|
import { T } from "inferno-i18next-dess";
|
||||||
import { Link } from "inferno-router";
|
import { Link } from "inferno-router";
|
||||||
|
@ -6,14 +5,13 @@ import { IsoDataOptionalSite } from "../../interfaces";
|
||||||
import { I18NextService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
|
|
||||||
export class ErrorPage extends Component<any, any> {
|
export class ErrorPage extends Component<any, any> {
|
||||||
private isoData: IsoDataOptionalSite = setIsoData(this.context);
|
|
||||||
|
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { errorPageData } = this.isoData;
|
const reduxState: IsoDataOptionalSite = this.context.store.getState();
|
||||||
|
const errorPageData = reduxState.errorPageData;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="error-page container-lg text-center">
|
<div className="error-page container-lg text-center">
|
||||||
|
@ -41,8 +39,7 @@ export class ErrorPage extends Component<any, any> {
|
||||||
<div>
|
<div>
|
||||||
{I18NextService.i18n.t("error_page_admin_matrix", {
|
{I18NextService.i18n.t("error_page_admin_matrix", {
|
||||||
instance:
|
instance:
|
||||||
this.isoData.site_res?.site_view.site.name ??
|
reduxState.site_res?.site_view.site.name ?? "this instance",
|
||||||
"this instance",
|
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<ul className="mx-auto mt-2" style={{ width: "fit-content" }}>
|
<ul className="mx-auto mt-2" style={{ width: "fit-content" }}>
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import { showAvatars } from "@utils/app";
|
import { showAvatars } from "@utils/app";
|
||||||
import { isBrowser } from "@utils/browser";
|
import { isBrowser } from "@utils/browser";
|
||||||
import { numToSI } from "@utils/helpers";
|
import { numToSI } from "@utils/helpers";
|
||||||
import { amAdmin, canCreateCommunity } from "@utils/roles";
|
import { amAdmin, canCreateCommunity, moderatesSomething } from "@utils/roles";
|
||||||
import { Component, createRef, linkEvent } from "inferno";
|
import { Component, createRef, linkEvent } from "inferno";
|
||||||
import { NavLink } from "inferno-router";
|
import { NavLink } from "inferno-router";
|
||||||
import { GetSiteResponse } from "lemmy-js-client";
|
import { GetSiteResponse } from "lemmy-js-client";
|
||||||
import { donateLemmyUrl } from "../../config";
|
import { donateLemmyUrl } from "../../config";
|
||||||
import {
|
import {
|
||||||
I18NextService,
|
I18NextService,
|
||||||
UserService,
|
|
||||||
UnreadCounterService,
|
UnreadCounterService,
|
||||||
|
HttpService,
|
||||||
} from "../../services";
|
} from "../../services";
|
||||||
import { toast } from "../../toast";
|
import { toast } from "../../toast";
|
||||||
import { Icon } from "../common/icon";
|
import { Icon } from "../common/icon";
|
||||||
|
@ -38,7 +38,7 @@ function handleCollapseClick(i: Navbar) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleLogOut(i: Navbar) {
|
function handleLogOut(i: Navbar) {
|
||||||
UserService.Instance.logout();
|
HttpService._Instance.logout();
|
||||||
handleCollapseClick(i);
|
handleCollapseClick(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
||||||
// TODO class active corresponding to current pages
|
// TODO class active corresponding to current pages
|
||||||
render() {
|
render() {
|
||||||
const siteView = this.props.siteRes?.site_view;
|
const siteView = this.props.siteRes?.site_view;
|
||||||
const person = UserService.Instance.myUserInfo?.local_user_view.person;
|
const person = this.props.siteRes?.my_user?.local_user_view.person;
|
||||||
return (
|
return (
|
||||||
<div className="shadow-sm">
|
<div className="shadow-sm">
|
||||||
<nav
|
<nav
|
||||||
|
@ -108,9 +108,10 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
||||||
className="d-flex align-items-center navbar-brand me-md-3"
|
className="d-flex align-items-center navbar-brand me-md-3"
|
||||||
onMouseUp={linkEvent(this, handleCollapseClick)}
|
onMouseUp={linkEvent(this, handleCollapseClick)}
|
||||||
>
|
>
|
||||||
{siteView?.site.icon && showAvatars() && (
|
{siteView?.site.icon &&
|
||||||
<PictrsImage src={siteView.site.icon} icon />
|
showAvatars(this.props.siteRes?.my_user) && (
|
||||||
)}
|
<PictrsImage src={siteView.site.icon} icon />
|
||||||
|
)}
|
||||||
{siteView?.site.name}
|
{siteView?.site.name}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
{person && (
|
{person && (
|
||||||
|
@ -133,7 +134,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
||||||
)}
|
)}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</li>
|
</li>
|
||||||
{UserService.Instance.moderatesSomething && (
|
{moderatesSomething(this.props.siteRes?.my_user) && (
|
||||||
<li className="nav-item nav-item-icon">
|
<li className="nav-item nav-item-icon">
|
||||||
<NavLink
|
<NavLink
|
||||||
to="/reports"
|
to="/reports"
|
||||||
|
@ -306,7 +307,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
||||||
)}
|
)}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</li>
|
</li>
|
||||||
{UserService.Instance.moderatesSomething && (
|
{moderatesSomething(this.props.siteRes?.my_user) && (
|
||||||
<li id="navModeration" className="nav-item">
|
<li id="navModeration" className="nav-item">
|
||||||
<NavLink
|
<NavLink
|
||||||
className="nav-link d-inline-flex align-items-center d-md-inline-block"
|
className="nav-link d-inline-flex align-items-center d-md-inline-block"
|
||||||
|
@ -467,7 +468,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
requestNotificationPermission() {
|
requestNotificationPermission() {
|
||||||
if (UserService.Instance.myUserInfo) {
|
if (this.props.siteRes?.my_user) {
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
if (!Notification) {
|
if (!Notification) {
|
||||||
toast(I18NextService.i18n.t("notifications_error"), "danger");
|
toast(I18NextService.i18n.t("notifications_error"), "danger");
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
import { Helmet } from "inferno-helmet";
|
import { Helmet } from "inferno-helmet";
|
||||||
import { UserService } from "../../services";
|
import { MyUserInfo } from "lemmy-js-client";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
defaultTheme: string;
|
defaultTheme: string;
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Theme extends Component<Props> {
|
export class Theme extends Component<Props> {
|
||||||
render() {
|
render() {
|
||||||
const user = UserService.Instance.myUserInfo;
|
const user = this.props.myUserInfo;
|
||||||
const hasTheme = user?.local_user_view.local_user.theme !== "browser";
|
const hasTheme = user?.local_user_view.local_user.theme !== "browser";
|
||||||
|
|
||||||
if (user && hasTheme) {
|
if (user && hasTheme) {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { T } from "inferno-i18next-dess";
|
||||||
import { Link } from "inferno-router";
|
import { Link } from "inferno-router";
|
||||||
import { CreateComment, EditComment, Language } from "lemmy-js-client";
|
import { CreateComment, EditComment, Language } from "lemmy-js-client";
|
||||||
import { CommentNodeI } from "../../interfaces";
|
import { CommentNodeI } from "../../interfaces";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import { Icon } from "../common/icon";
|
import { Icon } from "../common/icon";
|
||||||
import { MarkdownTextArea } from "../common/markdown-textarea";
|
import { MarkdownTextArea } from "../common/markdown-textarea";
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ interface CommentFormProps {
|
||||||
* Can either be the parent, or the editable comment. The right side is a postId.
|
* Can either be the parent, or the editable comment. The right side is a postId.
|
||||||
*/
|
*/
|
||||||
node: CommentNodeI | number;
|
node: CommentNodeI | number;
|
||||||
|
loggedIn: boolean;
|
||||||
finished?: boolean;
|
finished?: boolean;
|
||||||
edit?: boolean;
|
edit?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
@ -45,7 +46,7 @@ export class CommentForm extends Component<CommentFormProps, any> {
|
||||||
" ",
|
" ",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{UserService.Instance.myUserInfo ? (
|
{this.props.loggedIn ? (
|
||||||
<MarkdownTextArea
|
<MarkdownTextArea
|
||||||
initialContent={initialContent}
|
initialContent={initialContent}
|
||||||
showLanguage
|
showLanguage
|
||||||
|
|
|
@ -27,6 +27,7 @@ import {
|
||||||
Language,
|
Language,
|
||||||
MarkCommentReplyAsRead,
|
MarkCommentReplyAsRead,
|
||||||
MarkPersonMentionAsRead,
|
MarkPersonMentionAsRead,
|
||||||
|
MyUserInfo,
|
||||||
PersonMentionView,
|
PersonMentionView,
|
||||||
PersonView,
|
PersonView,
|
||||||
PurgeComment,
|
PurgeComment,
|
||||||
|
@ -45,7 +46,7 @@ import {
|
||||||
VoteContentType,
|
VoteContentType,
|
||||||
} from "../../interfaces";
|
} from "../../interfaces";
|
||||||
import { mdToHtml, mdToHtmlNoImages } from "../../markdown";
|
import { mdToHtml, mdToHtmlNoImages } from "../../markdown";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import { setupTippy } from "../../tippy";
|
import { setupTippy } from "../../tippy";
|
||||||
import { Icon, PurgeWarning, Spinner } from "../common/icon";
|
import { Icon, PurgeWarning, Spinner } from "../common/icon";
|
||||||
import { MomentTime } from "../common/moment-time";
|
import { MomentTime } from "../common/moment-time";
|
||||||
|
@ -97,6 +98,7 @@ interface CommentNodeState {
|
||||||
|
|
||||||
interface CommentNodeProps {
|
interface CommentNodeProps {
|
||||||
node: CommentNodeI;
|
node: CommentNodeI;
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
moderators?: CommunityModeratorView[];
|
moderators?: CommunityModeratorView[];
|
||||||
admins?: PersonView[];
|
admins?: PersonView[];
|
||||||
noBorder?: boolean;
|
noBorder?: boolean;
|
||||||
|
@ -238,14 +240,18 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
cv.creator.id,
|
cv.creator.id,
|
||||||
this.props.moderators,
|
this.props.moderators,
|
||||||
this.props.admins,
|
this.props.admins,
|
||||||
UserService.Instance.myUserInfo,
|
this.props.myUserInfo,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
const canAdmin_ = canAdmin(cv.creator.id, this.props.admins);
|
const canAdmin_ = canAdmin(
|
||||||
|
cv.creator.id,
|
||||||
|
this.props.admins,
|
||||||
|
this.props.myUserInfo,
|
||||||
|
);
|
||||||
const canAdminOnSelf = canAdmin(
|
const canAdminOnSelf = canAdmin(
|
||||||
cv.creator.id,
|
cv.creator.id,
|
||||||
this.props.admins,
|
this.props.admins,
|
||||||
UserService.Instance.myUserInfo,
|
this.props.myUserInfo,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
const isMod_ = cv.creator_is_moderator;
|
const isMod_ = cv.creator_is_moderator;
|
||||||
|
@ -253,6 +259,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
const amCommunityCreator_ = amCommunityCreator(
|
const amCommunityCreator_ = amCommunityCreator(
|
||||||
cv.creator.id,
|
cv.creator.id,
|
||||||
this.props.moderators,
|
this.props.moderators,
|
||||||
|
this.props.myUserInfo,
|
||||||
);
|
);
|
||||||
|
|
||||||
const moreRepliesBorderColor = this.props.node.depth
|
const moreRepliesBorderColor = this.props.node.depth
|
||||||
|
@ -327,7 +334,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
{/* This is an expanding spacer for mobile */}
|
{/* This is an expanding spacer for mobile */}
|
||||||
<div className="me-lg-5 flex-grow-1 flex-lg-grow-0 unselectable pointer mx-2" />
|
<div className="me-lg-5 flex-grow-1 flex-lg-grow-0 unselectable pointer mx-2" />
|
||||||
|
|
||||||
{showScores() && (
|
{showScores(this.props.myUserInfo) && (
|
||||||
<>
|
<>
|
||||||
<span
|
<span
|
||||||
className={`me-1 fw-bold ${this.scoreColor}`}
|
className={`me-1 fw-bold ${this.scoreColor}`}
|
||||||
|
@ -352,6 +359,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
{this.state.showEdit && (
|
{this.state.showEdit && (
|
||||||
<CommentForm
|
<CommentForm
|
||||||
node={node}
|
node={node}
|
||||||
|
loggedIn={!!this.props.myUserInfo}
|
||||||
edit
|
edit
|
||||||
onReplyCancel={this.handleReplyCancel}
|
onReplyCancel={this.handleReplyCancel}
|
||||||
disabled={this.props.locked}
|
disabled={this.props.locked}
|
||||||
|
@ -410,7 +418,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{UserService.Instance.myUserInfo && !this.props.viewOnly && (
|
{this.props.myUserInfo && !this.props.viewOnly && (
|
||||||
<>
|
<>
|
||||||
<VoteButtonsCompact
|
<VoteButtonsCompact
|
||||||
voteContentType={VoteContentType.Comment}
|
voteContentType={VoteContentType.Comment}
|
||||||
|
@ -1067,6 +1075,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
{this.state.showReply && (
|
{this.state.showReply && (
|
||||||
<CommentForm
|
<CommentForm
|
||||||
node={node}
|
node={node}
|
||||||
|
loggedIn={!!this.props.myUserInfo}
|
||||||
onReplyCancel={this.handleReplyCancel}
|
onReplyCancel={this.handleReplyCancel}
|
||||||
disabled={this.props.locked}
|
disabled={this.props.locked}
|
||||||
finished={this.props.finished.get(
|
finished={this.props.finished.get(
|
||||||
|
@ -1082,6 +1091,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
{!this.state.collapsed && node.children.length > 0 && (
|
{!this.state.collapsed && node.children.length > 0 && (
|
||||||
<CommentNodes
|
<CommentNodes
|
||||||
nodes={node.children}
|
nodes={node.children}
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
locked={this.props.locked}
|
locked={this.props.locked}
|
||||||
moderators={this.props.moderators}
|
moderators={this.props.moderators}
|
||||||
admins={this.props.admins}
|
admins={this.props.admins}
|
||||||
|
@ -1166,7 +1176,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
|
|
||||||
get myComment(): boolean {
|
get myComment(): boolean {
|
||||||
return (
|
return (
|
||||||
UserService.Instance.myUserInfo?.local_user_view.person.id ===
|
this.props.myUserInfo?.local_user_view.person.id ===
|
||||||
this.commentView.creator.id
|
this.commentView.creator.id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {
|
||||||
Language,
|
Language,
|
||||||
MarkCommentReplyAsRead,
|
MarkCommentReplyAsRead,
|
||||||
MarkPersonMentionAsRead,
|
MarkPersonMentionAsRead,
|
||||||
|
MyUserInfo,
|
||||||
PersonView,
|
PersonView,
|
||||||
PurgeComment,
|
PurgeComment,
|
||||||
PurgePerson,
|
PurgePerson,
|
||||||
|
@ -31,6 +32,7 @@ import { CommentNode } from "./comment-node";
|
||||||
|
|
||||||
interface CommentNodesProps {
|
interface CommentNodesProps {
|
||||||
nodes: CommentNodeI[];
|
nodes: CommentNodeI[];
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
moderators?: CommunityModeratorView[];
|
moderators?: CommunityModeratorView[];
|
||||||
admins?: PersonView[];
|
admins?: PersonView[];
|
||||||
maxCommentsShown?: number;
|
maxCommentsShown?: number;
|
||||||
|
@ -99,6 +101,7 @@ export class CommentNodes extends Component<CommentNodesProps, any> {
|
||||||
<CommentNode
|
<CommentNode
|
||||||
key={node.comment_view.comment.id}
|
key={node.comment_view.comment.id}
|
||||||
node={node}
|
node={node}
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
noBorder={this.props.noBorder}
|
noBorder={this.props.noBorder}
|
||||||
isTopLevel={this.props.isTopLevel}
|
isTopLevel={this.props.isTopLevel}
|
||||||
viewOnly={this.props.viewOnly}
|
viewOnly={this.props.viewOnly}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { T } from "inferno-i18next-dess";
|
||||||
import {
|
import {
|
||||||
CommentReportView,
|
CommentReportView,
|
||||||
CommentView,
|
CommentView,
|
||||||
|
MyUserInfo,
|
||||||
ResolveCommentReport,
|
ResolveCommentReport,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { CommentNodeI, CommentViewType } from "../../interfaces";
|
import { CommentNodeI, CommentViewType } from "../../interfaces";
|
||||||
|
@ -14,6 +15,7 @@ import { EMPTY_REQUEST } from "../../services/HttpService";
|
||||||
|
|
||||||
interface CommentReportProps {
|
interface CommentReportProps {
|
||||||
report: CommentReportView;
|
report: CommentReportView;
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
onResolveReport(form: ResolveCommentReport): void;
|
onResolveReport(form: ResolveCommentReport): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +77,7 @@ export class CommentReport extends Component<
|
||||||
<div className="comment-report">
|
<div className="comment-report">
|
||||||
<CommentNode
|
<CommentNode
|
||||||
node={node}
|
node={node}
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
viewType={CommentViewType.Flat}
|
viewType={CommentViewType.Flat}
|
||||||
enableDownvotes={true}
|
enableDownvotes={true}
|
||||||
viewOnly={true}
|
viewOnly={true}
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
import { setIsoData } from "@utils/app";
|
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
import { ErrorPage } from "../app/error-page";
|
import { ErrorPage } from "../app/error-page";
|
||||||
|
import { IsoDataOptionalSite } from "../../interfaces";
|
||||||
|
|
||||||
class ErrorGuard extends Component<any, any> {
|
class ErrorGuard extends Component<any, any> {
|
||||||
private isoData = setIsoData(this.context);
|
|
||||||
|
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const errorPageData = this.isoData.errorPageData;
|
const reduxState: IsoDataOptionalSite = this.context.store.getState().value;
|
||||||
const siteRes = this.isoData.site_res;
|
const errorPageData = reduxState.errorPageData;
|
||||||
|
const siteRes = reduxState.site_res;
|
||||||
|
console.log(`error guard data: ${reduxState.path}`);
|
||||||
|
|
||||||
if (errorPageData || !siteRes) {
|
if (errorPageData || !siteRes) {
|
||||||
return <ErrorPage />;
|
return <ErrorPage />;
|
||||||
|
|
|
@ -2,12 +2,13 @@ import { selectableLanguages } from "@utils/app";
|
||||||
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 { Language } from "lemmy-js-client";
|
import { Language, MyUserInfo } from "lemmy-js-client";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import { Icon } from "./icon";
|
import { Icon } from "./icon";
|
||||||
|
|
||||||
interface LanguageSelectProps {
|
interface LanguageSelectProps {
|
||||||
allLanguages: Language[];
|
allLanguages: Language[];
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
siteLanguages: number[];
|
siteLanguages: number[];
|
||||||
selectedLanguageIds?: number[];
|
selectedLanguageIds?: number[];
|
||||||
multiple?: boolean;
|
multiple?: boolean;
|
||||||
|
@ -97,7 +98,7 @@ export class LanguageSelect extends Component<LanguageSelectProps, any> {
|
||||||
this.props.siteLanguages,
|
this.props.siteLanguages,
|
||||||
this.props.showAll,
|
this.props.showAll,
|
||||||
this.props.showSite,
|
this.props.showSite,
|
||||||
UserService.Instance.myUserInfo,
|
this.props.myUserInfo,
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -5,7 +5,7 @@ import classNames from "classnames";
|
||||||
import { NoOptionI18nKeys } from "i18next";
|
import { NoOptionI18nKeys } from "i18next";
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, linkEvent } from "inferno";
|
||||||
import { Prompt } from "inferno-router";
|
import { Prompt } from "inferno-router";
|
||||||
import { Language } from "lemmy-js-client";
|
import { Language, MyUserInfo } from "lemmy-js-client";
|
||||||
import {
|
import {
|
||||||
concurrentImageUpload,
|
concurrentImageUpload,
|
||||||
markdownFieldCharacterLimit,
|
markdownFieldCharacterLimit,
|
||||||
|
@ -14,7 +14,7 @@ import {
|
||||||
relTags,
|
relTags,
|
||||||
} from "../../config";
|
} from "../../config";
|
||||||
import { customEmojisLookup, mdToHtml, setupTribute } from "../../markdown";
|
import { customEmojisLookup, mdToHtml, setupTribute } from "../../markdown";
|
||||||
import { HttpService, I18NextService, UserService } from "../../services";
|
import { HttpService, I18NextService } from "../../services";
|
||||||
import { setupTippy } from "../../tippy";
|
import { setupTippy } from "../../tippy";
|
||||||
import { pictrsDeleteToast, toast } from "../../toast";
|
import { pictrsDeleteToast, toast } from "../../toast";
|
||||||
import { EmojiPicker } from "./emoji-picker";
|
import { EmojiPicker } from "./emoji-picker";
|
||||||
|
@ -52,6 +52,7 @@ interface MarkdownTextAreaProps {
|
||||||
onSubmit?(content: string, languageId?: number): void;
|
onSubmit?(content: string, languageId?: number): void;
|
||||||
allLanguages: Language[]; // TODO should probably be nullable
|
allLanguages: Language[]; // TODO should probably be nullable
|
||||||
siteLanguages: number[]; // TODO same
|
siteLanguages: number[]; // TODO same
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ImageUploadStatus {
|
interface ImageUploadStatus {
|
||||||
|
@ -168,7 +169,7 @@ export class MarkdownTextArea extends Component<
|
||||||
<label
|
<label
|
||||||
htmlFor={`file-upload-${this.id}`}
|
htmlFor={`file-upload-${this.id}`}
|
||||||
className={classNames("mb-0", {
|
className={classNames("mb-0", {
|
||||||
pointer: UserService.Instance.myUserInfo,
|
pointer: !!this.props.myUserInfo,
|
||||||
})}
|
})}
|
||||||
data-tippy-content={I18NextService.i18n.t("upload_image")}
|
data-tippy-content={I18NextService.i18n.t("upload_image")}
|
||||||
>
|
>
|
||||||
|
@ -195,7 +196,7 @@ export class MarkdownTextArea extends Component<
|
||||||
name="file"
|
name="file"
|
||||||
className="d-none"
|
className="d-none"
|
||||||
multiple
|
multiple
|
||||||
disabled={!UserService.Instance.myUserInfo}
|
disabled={!this.props.myUserInfo}
|
||||||
onChange={linkEvent(this, this.handleImageUpload)}
|
onChange={linkEvent(this, this.handleImageUpload)}
|
||||||
/>
|
/>
|
||||||
{this.getFormatButton("header", this.handleInsertHeader)}
|
{this.getFormatButton("header", this.handleInsertHeader)}
|
||||||
|
@ -276,6 +277,7 @@ export class MarkdownTextArea extends Component<
|
||||||
{this.props.showLanguage && (
|
{this.props.showLanguage && (
|
||||||
<LanguageSelect
|
<LanguageSelect
|
||||||
iconVersion
|
iconVersion
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
allLanguages={this.props.allLanguages}
|
allLanguages={this.props.allLanguages}
|
||||||
selectedLanguageIds={
|
selectedLanguageIds={
|
||||||
languageId ? Array.of(languageId) : undefined
|
languageId ? Array.of(languageId) : undefined
|
||||||
|
|
|
@ -6,14 +6,16 @@ import {
|
||||||
CommentAggregates,
|
CommentAggregates,
|
||||||
CreateCommentLike,
|
CreateCommentLike,
|
||||||
CreatePostLike,
|
CreatePostLike,
|
||||||
|
MyUserInfo,
|
||||||
PostAggregates,
|
PostAggregates,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { VoteContentType, VoteType } from "../../interfaces";
|
import { VoteContentType, VoteType } from "../../interfaces";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import { Icon, Spinner } from "../common/icon";
|
import { Icon, Spinner } from "../common/icon";
|
||||||
|
|
||||||
interface VoteButtonsProps {
|
interface VoteButtonsProps {
|
||||||
voteContentType: VoteContentType;
|
voteContentType: VoteContentType;
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
id: number;
|
id: number;
|
||||||
onVote: (i: CreateCommentLike | CreatePostLike) => void;
|
onVote: (i: CreateCommentLike | CreatePostLike) => void;
|
||||||
enableDownvotes?: boolean;
|
enableDownvotes?: boolean;
|
||||||
|
@ -113,7 +115,7 @@ export class VoteButtonsCompact extends Component<
|
||||||
this.props.my_vote === 1 ? "text-info" : "text-muted"
|
this.props.my_vote === 1 ? "text-info" : "text-muted"
|
||||||
}`}
|
}`}
|
||||||
data-tippy-content={tippy(this.props.counts)}
|
data-tippy-content={tippy(this.props.counts)}
|
||||||
disabled={!UserService.Instance.myUserInfo}
|
disabled={!this.props.myUserInfo}
|
||||||
onClick={linkEvent(this, handleUpvote)}
|
onClick={linkEvent(this, handleUpvote)}
|
||||||
aria-label={I18NextService.i18n.t("upvote")}
|
aria-label={I18NextService.i18n.t("upvote")}
|
||||||
aria-pressed={this.props.my_vote === 1}
|
aria-pressed={this.props.my_vote === 1}
|
||||||
|
@ -123,7 +125,7 @@ export class VoteButtonsCompact extends Component<
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Icon icon="arrow-up1" classes="icon-inline small" />
|
<Icon icon="arrow-up1" classes="icon-inline small" />
|
||||||
{showScores() && (
|
{showScores(this.props.myUserInfo) && (
|
||||||
<span className="ms-2">
|
<span className="ms-2">
|
||||||
{numToSI(this.props.counts.upvotes)}
|
{numToSI(this.props.counts.upvotes)}
|
||||||
</span>
|
</span>
|
||||||
|
@ -137,7 +139,7 @@ export class VoteButtonsCompact extends Component<
|
||||||
className={`ms-2 btn btn-sm btn-link btn-animate btn py-0 px-1 ${
|
className={`ms-2 btn btn-sm btn-link btn-animate btn py-0 px-1 ${
|
||||||
this.props.my_vote === -1 ? "text-danger" : "text-muted"
|
this.props.my_vote === -1 ? "text-danger" : "text-muted"
|
||||||
}`}
|
}`}
|
||||||
disabled={!UserService.Instance.myUserInfo}
|
disabled={!this.props.myUserInfo}
|
||||||
onClick={linkEvent(this, handleDownvote)}
|
onClick={linkEvent(this, handleDownvote)}
|
||||||
data-tippy-content={tippy(this.props.counts)}
|
data-tippy-content={tippy(this.props.counts)}
|
||||||
aria-label={I18NextService.i18n.t("downvote")}
|
aria-label={I18NextService.i18n.t("downvote")}
|
||||||
|
@ -148,7 +150,7 @@ export class VoteButtonsCompact extends Component<
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Icon icon="arrow-down1" classes="icon-inline small" />
|
<Icon icon="arrow-down1" classes="icon-inline small" />
|
||||||
{showScores() && (
|
{showScores(this.props.myUserInfo) && (
|
||||||
<span
|
<span
|
||||||
className={classNames("ms-2", {
|
className={classNames("ms-2", {
|
||||||
invisible: this.props.counts.downvotes === 0,
|
invisible: this.props.counts.downvotes === 0,
|
||||||
|
@ -193,7 +195,7 @@ export class VoteButtons extends Component<VoteButtonsProps, VoteButtonsState> {
|
||||||
className={`btn-animate btn btn-link p-0 ${
|
className={`btn-animate btn btn-link p-0 ${
|
||||||
this.props.my_vote === 1 ? "text-info" : "text-muted"
|
this.props.my_vote === 1 ? "text-info" : "text-muted"
|
||||||
}`}
|
}`}
|
||||||
disabled={!UserService.Instance.myUserInfo}
|
disabled={!this.props.myUserInfo}
|
||||||
onClick={linkEvent(this, handleUpvote)}
|
onClick={linkEvent(this, handleUpvote)}
|
||||||
data-tippy-content={I18NextService.i18n.t("upvote")}
|
data-tippy-content={I18NextService.i18n.t("upvote")}
|
||||||
aria-label={I18NextService.i18n.t("upvote")}
|
aria-label={I18NextService.i18n.t("upvote")}
|
||||||
|
@ -205,7 +207,7 @@ export class VoteButtons extends Component<VoteButtonsProps, VoteButtonsState> {
|
||||||
<Icon icon="arrow-up1" classes="upvote" />
|
<Icon icon="arrow-up1" classes="upvote" />
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
{showScores() ? (
|
{showScores(this.props.myUserInfo) ? (
|
||||||
<div
|
<div
|
||||||
className="unselectable pointer text-muted post-score"
|
className="unselectable pointer text-muted post-score"
|
||||||
data-tippy-content={tippy(this.props.counts)}
|
data-tippy-content={tippy(this.props.counts)}
|
||||||
|
@ -221,7 +223,7 @@ export class VoteButtons extends Component<VoteButtonsProps, VoteButtonsState> {
|
||||||
className={`btn-animate btn btn-link p-0 ${
|
className={`btn-animate btn btn-link p-0 ${
|
||||||
this.props.my_vote === -1 ? "text-danger" : "text-muted"
|
this.props.my_vote === -1 ? "text-danger" : "text-muted"
|
||||||
}`}
|
}`}
|
||||||
disabled={!UserService.Instance.myUserInfo}
|
disabled={!this.props.myUserInfo}
|
||||||
onClick={linkEvent(this, handleDownvote)}
|
onClick={linkEvent(this, handleDownvote)}
|
||||||
data-tippy-content={I18NextService.i18n.t("downvote")}
|
data-tippy-content={I18NextService.i18n.t("downvote")}
|
||||||
aria-label={I18NextService.i18n.t("downvote")}
|
aria-label={I18NextService.i18n.t("downvote")}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { editCommunity, setIsoData, showLocal } from "@utils/app";
|
import { editCommunity, showLocal } from "@utils/app";
|
||||||
import {
|
import {
|
||||||
getPageFromString,
|
getPageFromString,
|
||||||
getQueryParams,
|
getQueryParams,
|
||||||
|
@ -17,7 +17,7 @@ import {
|
||||||
ListingType,
|
ListingType,
|
||||||
SortType,
|
SortType,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { InitialFetchRequest } from "../../interfaces";
|
import { InitialFetchRequest, IsoData } from "../../interfaces";
|
||||||
import { FirstLoadService, I18NextService } from "../../services";
|
import { FirstLoadService, I18NextService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
|
@ -70,7 +70,9 @@ function getCommunitiesQueryParams() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Communities extends Component<any, CommunitiesState> {
|
export class Communities extends Component<any, CommunitiesState> {
|
||||||
private isoData = setIsoData<CommunitiesData>(this.context);
|
get isoData(): IsoData<CommunitiesData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
state: CommunitiesState = {
|
state: CommunitiesState = {
|
||||||
listCommunitiesResponse: EMPTY_REQUEST,
|
listCommunitiesResponse: EMPTY_REQUEST,
|
||||||
siteRes: this.isoData.site_res,
|
siteRes: this.isoData.site_res,
|
||||||
|
|
|
@ -243,6 +243,7 @@ export class CommunityForm extends Component<
|
||||||
selectedLanguageIds={this.state.form.discussion_languages}
|
selectedLanguageIds={this.state.form.discussion_languages}
|
||||||
multiple={true}
|
multiple={true}
|
||||||
onChange={this.handleDiscussionLanguageChange}
|
onChange={this.handleDiscussionLanguageChange}
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
/>
|
/>
|
||||||
<div className="mb-3 row">
|
<div className="mb-3 row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
|
|
|
@ -2,12 +2,13 @@ import { showAvatars } from "@utils/app";
|
||||||
import { hostname } from "@utils/helpers";
|
import { hostname } from "@utils/helpers";
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
import { Link } from "inferno-router";
|
import { Link } from "inferno-router";
|
||||||
import { Community } from "lemmy-js-client";
|
import { Community, MyUserInfo } from "lemmy-js-client";
|
||||||
import { relTags } from "../../config";
|
import { relTags } from "../../config";
|
||||||
import { PictrsImage } from "../common/pictrs-image";
|
import { PictrsImage } from "../common/pictrs-image";
|
||||||
|
|
||||||
interface CommunityLinkProps {
|
interface CommunityLinkProps {
|
||||||
community: Community;
|
community: Community;
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
realLink?: boolean;
|
realLink?: boolean;
|
||||||
useApubName?: boolean;
|
useApubName?: boolean;
|
||||||
muted?: boolean;
|
muted?: boolean;
|
||||||
|
@ -63,7 +64,7 @@ export class CommunityLink extends Component<CommunityLinkProps, any> {
|
||||||
<>
|
<>
|
||||||
{!this.props.hideAvatar &&
|
{!this.props.hideAvatar &&
|
||||||
!this.props.community.removed &&
|
!this.props.community.removed &&
|
||||||
showAvatars() &&
|
showAvatars(this.props.myUserInfo) &&
|
||||||
icon && <PictrsImage src={icon} icon nsfw={nsfw} />}
|
icon && <PictrsImage src={icon} icon nsfw={nsfw} />}
|
||||||
<span className="overflow-wrap-anywhere">{displayName}</span>
|
<span className="overflow-wrap-anywhere">{displayName}</span>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -9,7 +9,6 @@ import {
|
||||||
getCommentParentId,
|
getCommentParentId,
|
||||||
getDataTypeString,
|
getDataTypeString,
|
||||||
postToCommentSortType,
|
postToCommentSortType,
|
||||||
setIsoData,
|
|
||||||
showLocal,
|
showLocal,
|
||||||
updateCommunityBlock,
|
updateCommunityBlock,
|
||||||
updatePersonBlock,
|
updatePersonBlock,
|
||||||
|
@ -58,6 +57,7 @@ import {
|
||||||
LockPost,
|
LockPost,
|
||||||
MarkCommentReplyAsRead,
|
MarkCommentReplyAsRead,
|
||||||
MarkPersonMentionAsRead,
|
MarkPersonMentionAsRead,
|
||||||
|
MyUserInfo,
|
||||||
PaginationCursor,
|
PaginationCursor,
|
||||||
PostResponse,
|
PostResponse,
|
||||||
PurgeComment,
|
PurgeComment,
|
||||||
|
@ -78,8 +78,9 @@ import {
|
||||||
CommentViewType,
|
CommentViewType,
|
||||||
DataType,
|
DataType,
|
||||||
InitialFetchRequest,
|
InitialFetchRequest,
|
||||||
|
IsoData,
|
||||||
} from "../../interfaces";
|
} from "../../interfaces";
|
||||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
import { FirstLoadService, I18NextService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
HttpService,
|
HttpService,
|
||||||
|
@ -136,10 +137,11 @@ function getDataTypeFromQuery(type?: string): DataType {
|
||||||
return type ? DataType[type] : DataType.Post;
|
return type ? DataType[type] : DataType.Post;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSortTypeFromQuery(type?: string): SortType {
|
function getSortTypeFromQuery(
|
||||||
const mySortType =
|
type?: string,
|
||||||
UserService.Instance.myUserInfo?.local_user_view.local_user
|
myUserInfo?: MyUserInfo,
|
||||||
.default_sort_type;
|
): SortType {
|
||||||
|
const mySortType = myUserInfo?.local_user_view.local_user.default_sort_type;
|
||||||
|
|
||||||
return type ? (type as SortType) : mySortType ?? "Active";
|
return type ? (type as SortType) : mySortType ?? "Active";
|
||||||
}
|
}
|
||||||
|
@ -148,7 +150,9 @@ export class Community extends Component<
|
||||||
RouteComponentProps<{ name: string }>,
|
RouteComponentProps<{ name: string }>,
|
||||||
State
|
State
|
||||||
> {
|
> {
|
||||||
private isoData = setIsoData<CommunityData>(this.context);
|
get isoData(): IsoData<CommunityData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
state: State = {
|
state: State = {
|
||||||
communityRes: EMPTY_REQUEST,
|
communityRes: EMPTY_REQUEST,
|
||||||
postsRes: EMPTY_REQUEST,
|
postsRes: EMPTY_REQUEST,
|
||||||
|
@ -463,6 +467,7 @@ export class Community extends Component<
|
||||||
return (
|
return (
|
||||||
<CommentNodes
|
<CommentNodes
|
||||||
nodes={commentsToFlatNodes(this.state.commentsRes.data.comments)}
|
nodes={commentsToFlatNodes(this.state.commentsRes.data.comments)}
|
||||||
|
myUserInfo={this.isoData.site_res.my_user}
|
||||||
viewType={CommentViewType.Flat}
|
viewType={CommentViewType.Flat}
|
||||||
finished={this.state.finished}
|
finished={this.state.finished}
|
||||||
isTopLevel
|
isTopLevel
|
||||||
|
@ -642,7 +647,7 @@ export class Community extends Component<
|
||||||
// Update myUserInfo
|
// Update myUserInfo
|
||||||
if (followCommunityRes.state === "success") {
|
if (followCommunityRes.state === "success") {
|
||||||
const communityId = followCommunityRes.data.community_view.community.id;
|
const communityId = followCommunityRes.data.community_view.community.id;
|
||||||
const mui = UserService.Instance.myUserInfo;
|
const mui = this.isoData.site_res.my_user;
|
||||||
if (mui) {
|
if (mui) {
|
||||||
mui.follows = mui.follows.filter(i => i.community.id !== communityId);
|
mui.follows = mui.follows.filter(i => i.community.id !== communityId);
|
||||||
}
|
}
|
||||||
|
@ -672,7 +677,10 @@ export class Community extends Component<
|
||||||
async handleBlockCommunity(form: BlockCommunity) {
|
async handleBlockCommunity(form: BlockCommunity) {
|
||||||
const blockCommunityRes = await HttpService.client.blockCommunity(form);
|
const blockCommunityRes = await HttpService.client.blockCommunity(form);
|
||||||
if (blockCommunityRes.state === "success") {
|
if (blockCommunityRes.state === "success") {
|
||||||
updateCommunityBlock(blockCommunityRes.data);
|
updateCommunityBlock(
|
||||||
|
blockCommunityRes.data,
|
||||||
|
this.isoData.site_res.my_user,
|
||||||
|
);
|
||||||
this.setState(s => {
|
this.setState(s => {
|
||||||
if (s.communityRes.state === "success") {
|
if (s.communityRes.state === "success") {
|
||||||
s.communityRes.data.community_view.blocked =
|
s.communityRes.data.community_view.blocked =
|
||||||
|
@ -685,7 +693,7 @@ export class Community extends Component<
|
||||||
async handleBlockPerson(form: BlockPerson) {
|
async handleBlockPerson(form: BlockPerson) {
|
||||||
const blockPersonRes = await HttpService.client.blockPerson(form);
|
const blockPersonRes = await HttpService.client.blockPerson(form);
|
||||||
if (blockPersonRes.state === "success") {
|
if (blockPersonRes.state === "success") {
|
||||||
updatePersonBlock(blockPersonRes.data);
|
updatePersonBlock(blockPersonRes.data, this.isoData.site_res.my_user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { enableNsfw, setIsoData } from "@utils/app";
|
import { enableNsfw } from "@utils/app";
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
import {
|
import {
|
||||||
CreateCommunity as CreateCommunityI,
|
CreateCommunity as CreateCommunityI,
|
||||||
|
@ -7,6 +7,7 @@ import {
|
||||||
import { HttpService, I18NextService } from "../../services";
|
import { HttpService, I18NextService } from "../../services";
|
||||||
import { HtmlTags } from "../common/html-tags";
|
import { HtmlTags } from "../common/html-tags";
|
||||||
import { CommunityForm } from "./community-form";
|
import { CommunityForm } from "./community-form";
|
||||||
|
import { IsoData } from "../../interfaces";
|
||||||
|
|
||||||
interface CreateCommunityState {
|
interface CreateCommunityState {
|
||||||
siteRes: GetSiteResponse;
|
siteRes: GetSiteResponse;
|
||||||
|
@ -14,7 +15,9 @@ interface CreateCommunityState {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CreateCommunity extends Component<any, CreateCommunityState> {
|
export class CreateCommunity extends Component<any, CreateCommunityState> {
|
||||||
private isoData = setIsoData(this.context);
|
get isoData(): IsoData {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
state: CreateCommunityState = {
|
state: CreateCommunityState = {
|
||||||
siteRes: this.isoData.site_res,
|
siteRes: this.isoData.site_res,
|
||||||
loading: false,
|
loading: false,
|
||||||
|
|
|
@ -12,12 +12,13 @@ import {
|
||||||
EditCommunity,
|
EditCommunity,
|
||||||
FollowCommunity,
|
FollowCommunity,
|
||||||
Language,
|
Language,
|
||||||
|
MyUserInfo,
|
||||||
PersonView,
|
PersonView,
|
||||||
PurgeCommunity,
|
PurgeCommunity,
|
||||||
RemoveCommunity,
|
RemoveCommunity,
|
||||||
} 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 { Badges } from "../common/badges";
|
import { Badges } from "../common/badges";
|
||||||
import { BannerIconHeader } from "../common/banner-icon-header";
|
import { BannerIconHeader } from "../common/banner-icon-header";
|
||||||
import { Icon, PurgeWarning, Spinner } from "../common/icon";
|
import { Icon, PurgeWarning, Spinner } from "../common/icon";
|
||||||
|
@ -28,6 +29,7 @@ import { PersonListing } from "../person/person-listing";
|
||||||
|
|
||||||
interface SidebarProps {
|
interface SidebarProps {
|
||||||
community_view: CommunityView;
|
community_view: CommunityView;
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
moderators: CommunityModeratorView[];
|
moderators: CommunityModeratorView[];
|
||||||
admins: PersonView[];
|
admins: PersonView[];
|
||||||
allLanguages: Language[];
|
allLanguages: Language[];
|
||||||
|
@ -122,7 +124,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
sidebar() {
|
sidebar() {
|
||||||
const myUSerInfo = UserService.Instance.myUserInfo;
|
const myUserInfo = this.props.myUserInfo;
|
||||||
const {
|
const {
|
||||||
community: { name, actor_id },
|
community: { name, actor_id },
|
||||||
} = this.props.community_view;
|
} = this.props.community_view;
|
||||||
|
@ -140,8 +142,8 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
||||||
loading={this.state.followCommunityLoading}
|
loading={this.state.followCommunityLoading}
|
||||||
/>
|
/>
|
||||||
{this.canPost && this.createPost()}
|
{this.canPost && this.createPost()}
|
||||||
{myUSerInfo && this.blockCommunity()}
|
{myUserInfo && this.blockCommunity()}
|
||||||
{!myUSerInfo && (
|
{!myUserInfo && (
|
||||||
<div className="alert alert-info" role="alert">
|
<div className="alert alert-info" role="alert">
|
||||||
<T
|
<T
|
||||||
i18nKey="community_not_logged_in_alert"
|
i18nKey="community_not_logged_in_alert"
|
||||||
|
@ -268,7 +270,10 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ul className="list-inline mb-1 text-muted fw-bold">
|
<ul className="list-inline mb-1 text-muted fw-bold">
|
||||||
{amMod(this.props.community_view.community.id) && (
|
{amMod(
|
||||||
|
this.props.community_view.community.id,
|
||||||
|
this.props.myUserInfo,
|
||||||
|
) && (
|
||||||
<>
|
<>
|
||||||
<li className="list-inline-item-action">
|
<li className="list-inline-item-action">
|
||||||
<button
|
<button
|
||||||
|
@ -280,7 +285,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
||||||
<Icon icon="edit" classes="icon-inline" />
|
<Icon icon="edit" classes="icon-inline" />
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
{!amTopMod(this.props.moderators) &&
|
{!amTopMod(this.props.moderators, this.props.myUserInfo) &&
|
||||||
(!this.state.showConfirmLeaveModTeam ? (
|
(!this.state.showConfirmLeaveModTeam ? (
|
||||||
<li className="list-inline-item-action">
|
<li className="list-inline-item-action">
|
||||||
<button
|
<button
|
||||||
|
@ -319,7 +324,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
||||||
</li>
|
</li>
|
||||||
</>
|
</>
|
||||||
))}
|
))}
|
||||||
{amTopMod(this.props.moderators) && (
|
{amTopMod(this.props.moderators, this.props.myUserInfo) && (
|
||||||
<li className="list-inline-item-action">
|
<li className="list-inline-item-action">
|
||||||
<button
|
<button
|
||||||
className="btn btn-link text-muted d-inline-block"
|
className="btn btn-link text-muted d-inline-block"
|
||||||
|
@ -468,8 +473,8 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
||||||
get canPost(): boolean {
|
get canPost(): boolean {
|
||||||
return (
|
return (
|
||||||
!this.props.community_view.community.posting_restricted_to_mods ||
|
!this.props.community_view.community.posting_restricted_to_mods ||
|
||||||
amMod(this.props.community_view.community.id) ||
|
amMod(this.props.community_view.community.id, this.props.myUserInfo) ||
|
||||||
amAdmin()
|
amAdmin(this.props.myUserInfo)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,7 +525,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleLeaveModTeam(i: Sidebar) {
|
handleLeaveModTeam(i: Sidebar) {
|
||||||
const myId = UserService.Instance.myUserInfo?.local_user_view.person.id;
|
const myId = this.props.myUserInfo?.local_user_view.person.id;
|
||||||
if (myId) {
|
if (myId) {
|
||||||
i.setState({ leaveModTeamLoading: true });
|
i.setState({ leaveModTeamLoading: true });
|
||||||
i.props.onLeaveModTeam({
|
i.props.onLeaveModTeam({
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { fetchThemeList, setIsoData, showLocal } from "@utils/app";
|
import { fetchThemeList, showLocal } from "@utils/app";
|
||||||
import { capitalizeFirstLetter } from "@utils/helpers";
|
import { capitalizeFirstLetter } from "@utils/helpers";
|
||||||
import { RouteDataResponse } from "@utils/types";
|
import { RouteDataResponse } from "@utils/types";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
@ -14,7 +14,7 @@ import {
|
||||||
LemmyHttp,
|
LemmyHttp,
|
||||||
PersonView,
|
PersonView,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { InitialFetchRequest } from "../../interfaces";
|
import { InitialFetchRequest, IsoData } from "../../interfaces";
|
||||||
import { removeFromEmojiDataModel, updateEmojiDataModel } from "../../markdown";
|
import { removeFromEmojiDataModel, updateEmojiDataModel } from "../../markdown";
|
||||||
import { FirstLoadService, I18NextService } from "../../services";
|
import { FirstLoadService, I18NextService } from "../../services";
|
||||||
import {
|
import {
|
||||||
|
@ -53,7 +53,9 @@ interface AdminSettingsState {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AdminSettings extends Component<any, AdminSettingsState> {
|
export class AdminSettings extends Component<any, AdminSettingsState> {
|
||||||
private isoData = setIsoData<AdminSettingsData>(this.context);
|
get isoData(): IsoData<AdminSettingsData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
state: AdminSettingsState = {
|
state: AdminSettingsState = {
|
||||||
siteRes: this.isoData.site_res,
|
siteRes: this.isoData.site_res,
|
||||||
banned: [],
|
banned: [],
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
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 {
|
import {
|
||||||
|
@ -13,6 +12,7 @@ import { pictrsDeleteToast, toast } from "../../toast";
|
||||||
import { EmojiMart } from "../common/emoji-mart";
|
import { EmojiMart } from "../common/emoji-mart";
|
||||||
import { Icon, Spinner } from "../common/icon";
|
import { Icon, Spinner } from "../common/icon";
|
||||||
import { Paginator } from "../common/paginator";
|
import { Paginator } from "../common/paginator";
|
||||||
|
import { IsoData } from "../../interfaces";
|
||||||
|
|
||||||
interface EmojiFormProps {
|
interface EmojiFormProps {
|
||||||
onEdit(form: EditCustomEmoji): void;
|
onEdit(form: EditCustomEmoji): void;
|
||||||
|
@ -39,7 +39,9 @@ interface CustomEmojiViewForm {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
|
export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
|
||||||
private isoData = setIsoData(this.context);
|
get isoData(): IsoData {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
private itemsPerPage = 15;
|
private itemsPerPage = 15;
|
||||||
private emptyState: EmojiFormState = {
|
private emptyState: EmojiFormState = {
|
||||||
siteRes: this.isoData.site_res,
|
siteRes: this.isoData.site_res,
|
||||||
|
|
|
@ -9,7 +9,6 @@ import {
|
||||||
getDataTypeString,
|
getDataTypeString,
|
||||||
myAuth,
|
myAuth,
|
||||||
postToCommentSortType,
|
postToCommentSortType,
|
||||||
setIsoData,
|
|
||||||
showLocal,
|
showLocal,
|
||||||
updatePersonBlock,
|
updatePersonBlock,
|
||||||
} from "@utils/app";
|
} from "@utils/app";
|
||||||
|
@ -59,6 +58,7 @@ import {
|
||||||
LockPost,
|
LockPost,
|
||||||
MarkCommentReplyAsRead,
|
MarkCommentReplyAsRead,
|
||||||
MarkPersonMentionAsRead,
|
MarkPersonMentionAsRead,
|
||||||
|
MyUserInfo,
|
||||||
PaginationCursor,
|
PaginationCursor,
|
||||||
PostResponse,
|
PostResponse,
|
||||||
PurgeComment,
|
PurgeComment,
|
||||||
|
@ -77,9 +77,10 @@ import {
|
||||||
CommentViewType,
|
CommentViewType,
|
||||||
DataType,
|
DataType,
|
||||||
InitialFetchRequest,
|
InitialFetchRequest,
|
||||||
|
IsoData,
|
||||||
} from "../../interfaces";
|
} from "../../interfaces";
|
||||||
import { mdToHtml } from "../../markdown";
|
import { mdToHtml } from "../../markdown";
|
||||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
import { FirstLoadService, I18NextService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
HttpService,
|
HttpService,
|
||||||
|
@ -168,7 +169,7 @@ function getDataTypeFromQuery(type?: string): DataType {
|
||||||
|
|
||||||
function getListingTypeFromQuery(
|
function getListingTypeFromQuery(
|
||||||
type?: string,
|
type?: string,
|
||||||
myUserInfo = UserService.Instance.myUserInfo,
|
myUserInfo?: MyUserInfo,
|
||||||
): ListingType | undefined {
|
): ListingType | undefined {
|
||||||
const myListingType =
|
const myListingType =
|
||||||
myUserInfo?.local_user_view?.local_user?.default_listing_type;
|
myUserInfo?.local_user_view?.local_user?.default_listing_type;
|
||||||
|
@ -178,7 +179,7 @@ function getListingTypeFromQuery(
|
||||||
|
|
||||||
function getSortTypeFromQuery(
|
function getSortTypeFromQuery(
|
||||||
type?: string,
|
type?: string,
|
||||||
myUserInfo = UserService.Instance.myUserInfo,
|
myUserInfo?: MyUserInfo,
|
||||||
): SortType {
|
): SortType {
|
||||||
const mySortType = myUserInfo?.local_user_view?.local_user?.default_sort_type;
|
const mySortType = myUserInfo?.local_user_view?.local_user?.default_sort_type;
|
||||||
|
|
||||||
|
@ -225,7 +226,9 @@ const LinkButton = ({
|
||||||
);
|
);
|
||||||
|
|
||||||
export class Home extends Component<any, HomeState> {
|
export class Home extends Component<any, HomeState> {
|
||||||
private isoData = setIsoData<HomeData>(this.context);
|
get isoData(): IsoData<HomeData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
state: HomeState = {
|
state: HomeState = {
|
||||||
postsRes: EMPTY_REQUEST,
|
postsRes: EMPTY_REQUEST,
|
||||||
commentsRes: EMPTY_REQUEST,
|
commentsRes: EMPTY_REQUEST,
|
||||||
|
@ -242,6 +245,7 @@ export class Home extends Component<any, HomeState> {
|
||||||
|
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
|
console.log(this.isoData);
|
||||||
|
|
||||||
this.handleSortChange = this.handleSortChange.bind(this);
|
this.handleSortChange = this.handleSortChange.bind(this);
|
||||||
this.handleListingTypeChange = this.handleListingTypeChange.bind(this);
|
this.handleListingTypeChange = this.handleListingTypeChange.bind(this);
|
||||||
|
@ -416,7 +420,7 @@ export class Home extends Component<any, HomeState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasFollows(): boolean {
|
get hasFollows(): boolean {
|
||||||
const mui = UserService.Instance.myUserInfo;
|
const mui = this.isoData.site_res.my_user;
|
||||||
return !!mui && mui.follows.length > 0;
|
return !!mui && mui.follows.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,7 +610,7 @@ export class Home extends Component<any, HomeState> {
|
||||||
>
|
>
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<ul className="list-inline mb-0">
|
<ul className="list-inline mb-0">
|
||||||
{UserService.Instance.myUserInfo?.follows.map(cfv => (
|
{this.isoData.site_res.my_user?.follows.map(cfv => (
|
||||||
<li
|
<li
|
||||||
key={cfv.community.id}
|
key={cfv.community.id}
|
||||||
className="list-inline-item d-inline-block"
|
className="list-inline-item d-inline-block"
|
||||||
|
@ -734,6 +738,7 @@ export class Home extends Component<any, HomeState> {
|
||||||
return (
|
return (
|
||||||
<CommentNodes
|
<CommentNodes
|
||||||
nodes={commentsToFlatNodes(comments)}
|
nodes={commentsToFlatNodes(comments)}
|
||||||
|
myUserInfo={this.isoData.site_res.my_user}
|
||||||
viewType={CommentViewType.Flat}
|
viewType={CommentViewType.Flat}
|
||||||
finished={this.state.finished}
|
finished={this.state.finished}
|
||||||
isTopLevel
|
isTopLevel
|
||||||
|
@ -909,7 +914,7 @@ export class Home extends Component<any, HomeState> {
|
||||||
async handleBlockPerson(form: BlockPerson) {
|
async handleBlockPerson(form: BlockPerson) {
|
||||||
const blockPersonRes = await HttpService.client.blockPerson(form);
|
const blockPersonRes = await HttpService.client.blockPerson(form);
|
||||||
if (blockPersonRes.state === "success") {
|
if (blockPersonRes.state === "success") {
|
||||||
updatePersonBlock(blockPersonRes.data);
|
updatePersonBlock(blockPersonRes.data, this.isoData.site_res.my_user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { setIsoData } from "@utils/app";
|
|
||||||
import { RouteDataResponse } from "@utils/types";
|
import { RouteDataResponse } from "@utils/types";
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
import {
|
import {
|
||||||
|
@ -9,7 +8,7 @@ import {
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { relTags } from "../../config";
|
import { relTags } from "../../config";
|
||||||
import { InitialFetchRequest } from "../../interfaces";
|
import { InitialFetchRequest, IsoData } from "../../interfaces";
|
||||||
import { FirstLoadService, I18NextService } from "../../services";
|
import { FirstLoadService, I18NextService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
|
@ -34,7 +33,9 @@ interface InstancesState {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Instances extends Component<any, InstancesState> {
|
export class Instances extends Component<any, InstancesState> {
|
||||||
private isoData = setIsoData<InstancesData>(this.context);
|
get isoData(): IsoData<InstancesData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
state: InstancesState = {
|
state: InstancesState = {
|
||||||
instancesRes: EMPTY_REQUEST,
|
instancesRes: EMPTY_REQUEST,
|
||||||
siteRes: this.isoData.site_res,
|
siteRes: this.isoData.site_res,
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
import { setIsoData } from "@utils/app";
|
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
import { GetSiteResponse } from "lemmy-js-client";
|
import { GetSiteResponse } from "lemmy-js-client";
|
||||||
import { mdToHtml } from "../../markdown";
|
import { mdToHtml } from "../../markdown";
|
||||||
import { I18NextService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import { HtmlTags } from "../common/html-tags";
|
import { HtmlTags } from "../common/html-tags";
|
||||||
|
import { IsoData } from "../../interfaces";
|
||||||
|
|
||||||
interface LegalState {
|
interface LegalState {
|
||||||
siteRes: GetSiteResponse;
|
siteRes: GetSiteResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Legal extends Component<any, LegalState> {
|
export class Legal extends Component<any, LegalState> {
|
||||||
private isoData = setIsoData(this.context);
|
get isoData(): IsoData {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
state: LegalState = {
|
state: LegalState = {
|
||||||
siteRes: this.isoData.site_res,
|
siteRes: this.isoData.site_res,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { setIsoData } from "@utils/app";
|
|
||||||
import { capitalizeFirstLetter, validEmail } from "@utils/helpers";
|
import { capitalizeFirstLetter, validEmail } from "@utils/helpers";
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, linkEvent } from "inferno";
|
||||||
import { GetSiteResponse } from "lemmy-js-client";
|
import { GetSiteResponse } from "lemmy-js-client";
|
||||||
|
@ -6,6 +5,7 @@ import { HttpService, I18NextService } from "../../services";
|
||||||
import { toast } from "../../toast";
|
import { toast } from "../../toast";
|
||||||
import { HtmlTags } from "../common/html-tags";
|
import { HtmlTags } from "../common/html-tags";
|
||||||
import { Spinner } from "../common/icon";
|
import { Spinner } from "../common/icon";
|
||||||
|
import { IsoData } from "../../interfaces";
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
form: {
|
form: {
|
||||||
|
@ -16,7 +16,9 @@ interface State {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LoginReset extends Component<any, State> {
|
export class LoginReset extends Component<any, State> {
|
||||||
private isoData = setIsoData(this.context);
|
get isoData(): IsoData {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
|
|
||||||
state: State = {
|
state: State = {
|
||||||
form: {
|
form: {
|
||||||
|
|
|
@ -46,6 +46,7 @@ async function handleLoginSuccess(i: Login, loginRes: LoginResponse) {
|
||||||
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
|
||||||
UserService.Instance.myUserInfo = site.data.my_user;
|
UserService.Instance.myUserInfo = site.data.my_user;
|
||||||
updateDataBsTheme(site.data);
|
updateDataBsTheme(site.data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { setIsoData } from "@utils/app";
|
|
||||||
import { isBrowser } from "@utils/browser";
|
import { isBrowser } from "@utils/browser";
|
||||||
import { validEmail } from "@utils/helpers";
|
import { validEmail } from "@utils/helpers";
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, linkEvent } from "inferno";
|
||||||
|
@ -12,7 +11,7 @@ import {
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { joinLemmyUrl } from "../../config";
|
import { joinLemmyUrl } from "../../config";
|
||||||
import { mdToHtml } from "../../markdown";
|
import { mdToHtml } from "../../markdown";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
HttpService,
|
HttpService,
|
||||||
|
@ -24,6 +23,7 @@ import { HtmlTags } from "../common/html-tags";
|
||||||
import { Icon, Spinner } from "../common/icon";
|
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";
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
registerRes: RequestState<LoginResponse>;
|
registerRes: RequestState<LoginResponse>;
|
||||||
|
@ -44,7 +44,9 @@ interface State {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Signup extends Component<any, State> {
|
export class Signup extends Component<any, State> {
|
||||||
private isoData = setIsoData(this.context);
|
get isoData(): IsoData {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
private audio?: HTMLAudioElement;
|
private audio?: HTMLAudioElement;
|
||||||
|
|
||||||
state: State = {
|
state: State = {
|
||||||
|
|
|
@ -498,6 +498,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
||||||
selectedLanguageIds={this.state.siteForm.discussion_languages}
|
selectedLanguageIds={this.state.siteForm.discussion_languages}
|
||||||
multiple={true}
|
multiple={true}
|
||||||
onChange={this.handleDiscussionLanguageChange}
|
onChange={this.handleDiscussionLanguageChange}
|
||||||
|
myUserInfo={this.props.siteRes.my_user}
|
||||||
showAll
|
showAll
|
||||||
/>
|
/>
|
||||||
<div className="mb-3 row">
|
<div className="mb-3 row">
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
import {
|
import { fetchUsers, getUpdatedSearchId, personToChoice } from "@utils/app";
|
||||||
fetchUsers,
|
|
||||||
getUpdatedSearchId,
|
|
||||||
personToChoice,
|
|
||||||
setIsoData,
|
|
||||||
} from "@utils/app";
|
|
||||||
import {
|
import {
|
||||||
debounce,
|
debounce,
|
||||||
formatPastDate,
|
formatPastDate,
|
||||||
|
@ -46,7 +41,7 @@ import {
|
||||||
Person,
|
Person,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { fetchLimit } from "../config";
|
import { fetchLimit } from "../config";
|
||||||
import { InitialFetchRequest } from "../interfaces";
|
import { InitialFetchRequest, IsoData } from "../interfaces";
|
||||||
import { FirstLoadService, I18NextService } from "../services";
|
import { FirstLoadService, I18NextService } from "../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
|
@ -636,7 +631,9 @@ export class Modlog extends Component<
|
||||||
RouteComponentProps<{ communityId?: string }>,
|
RouteComponentProps<{ communityId?: string }>,
|
||||||
ModlogState
|
ModlogState
|
||||||
> {
|
> {
|
||||||
private isoData = setIsoData<ModlogData>(this.context);
|
get isoData(): IsoData<ModlogData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
|
|
||||||
state: ModlogState = {
|
state: ModlogState = {
|
||||||
res: EMPTY_REQUEST,
|
res: EMPTY_REQUEST,
|
||||||
|
|
|
@ -7,7 +7,6 @@ import {
|
||||||
enableDownvotes,
|
enableDownvotes,
|
||||||
getCommentParentId,
|
getCommentParentId,
|
||||||
myAuth,
|
myAuth,
|
||||||
setIsoData,
|
|
||||||
updatePersonBlock,
|
updatePersonBlock,
|
||||||
} from "@utils/app";
|
} from "@utils/app";
|
||||||
import { capitalizeFirstLetter, randomStr } from "@utils/helpers";
|
import { capitalizeFirstLetter, randomStr } from "@utils/helpers";
|
||||||
|
@ -61,8 +60,12 @@ import {
|
||||||
TransferCommunity,
|
TransferCommunity,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { fetchLimit, relTags } from "../../config";
|
import { fetchLimit, relTags } from "../../config";
|
||||||
import { CommentViewType, InitialFetchRequest } from "../../interfaces";
|
import {
|
||||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
CommentViewType,
|
||||||
|
InitialFetchRequest,
|
||||||
|
IsoData,
|
||||||
|
} from "../../interfaces";
|
||||||
|
import { FirstLoadService, I18NextService } from "../../services";
|
||||||
import { UnreadCounterService } from "../../services";
|
import { UnreadCounterService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
|
@ -127,7 +130,9 @@ interface InboxState {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Inbox extends Component<any, InboxState> {
|
export class Inbox extends Component<any, InboxState> {
|
||||||
private isoData = setIsoData<InboxData>(this.context);
|
get isoData(): IsoData<InboxData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
state: InboxState = {
|
state: InboxState = {
|
||||||
unreadOrAll: UnreadOrAll.Unread,
|
unreadOrAll: UnreadOrAll.Unread,
|
||||||
messageType: MessageType.All,
|
messageType: MessageType.All,
|
||||||
|
@ -194,7 +199,7 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
get documentTitle(): string {
|
get documentTitle(): string {
|
||||||
const mui = UserService.Instance.myUserInfo;
|
const mui = this.isoData.site_res.my_user;
|
||||||
return mui
|
return mui
|
||||||
? `@${mui.local_user_view.person.name} ${I18NextService.i18n.t(
|
? `@${mui.local_user_view.person.name} ${I18NextService.i18n.t(
|
||||||
"inbox",
|
"inbox",
|
||||||
|
@ -483,6 +488,7 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
nodes={[
|
nodes={[
|
||||||
{ comment_view: i.view as CommentView, children: [], depth: 0 },
|
{ comment_view: i.view as CommentView, children: [], depth: 0 },
|
||||||
]}
|
]}
|
||||||
|
myUserInfo={this.isoData.site_res.my_user}
|
||||||
viewType={CommentViewType.Flat}
|
viewType={CommentViewType.Flat}
|
||||||
finished={this.state.finished}
|
finished={this.state.finished}
|
||||||
markable
|
markable
|
||||||
|
@ -848,7 +854,7 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
async handleBlockPerson(form: BlockPerson) {
|
async handleBlockPerson(form: BlockPerson) {
|
||||||
const blockPersonRes = await HttpService.client.blockPerson(form);
|
const blockPersonRes = await HttpService.client.blockPerson(form);
|
||||||
if (blockPersonRes.state === "success") {
|
if (blockPersonRes.state === "success") {
|
||||||
updatePersonBlock(blockPersonRes.data);
|
updatePersonBlock(blockPersonRes.data, this.isoData.site_res.my_user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,14 @@ import { hostname, isCakeDay } from "@utils/helpers";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
import { Link } from "inferno-router";
|
import { Link } from "inferno-router";
|
||||||
import { Person } from "lemmy-js-client";
|
import { MyUserInfo, Person } from "lemmy-js-client";
|
||||||
import { relTags } from "../../config";
|
import { relTags } from "../../config";
|
||||||
import { PictrsImage } from "../common/pictrs-image";
|
import { PictrsImage } from "../common/pictrs-image";
|
||||||
import { CakeDay } from "./cake-day";
|
import { CakeDay } from "./cake-day";
|
||||||
|
|
||||||
interface PersonListingProps {
|
interface PersonListingProps {
|
||||||
person: Person;
|
person: Person;
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
realLink?: boolean;
|
realLink?: boolean;
|
||||||
useApubName?: boolean;
|
useApubName?: boolean;
|
||||||
muted?: boolean;
|
muted?: boolean;
|
||||||
|
@ -87,7 +88,7 @@ export class PersonListing extends Component<PersonListingProps, any> {
|
||||||
<>
|
<>
|
||||||
{!this.props.hideAvatar &&
|
{!this.props.hideAvatar &&
|
||||||
!this.props.person.banned &&
|
!this.props.person.banned &&
|
||||||
showAvatars() && (
|
showAvatars(this.props.myUserInfo) && (
|
||||||
<PictrsImage
|
<PictrsImage
|
||||||
src={avatar ?? `${getStaticDir()}/assets/icons/icon-96x96.png`}
|
src={avatar ?? `${getStaticDir()}/assets/icons/icon-96x96.png`}
|
||||||
icon
|
icon
|
||||||
|
|
|
@ -5,7 +5,6 @@ import {
|
||||||
enableDownvotes,
|
enableDownvotes,
|
||||||
enableNsfw,
|
enableNsfw,
|
||||||
getCommentParentId,
|
getCommentParentId,
|
||||||
setIsoData,
|
|
||||||
updatePersonBlock,
|
updatePersonBlock,
|
||||||
} from "@utils/app";
|
} from "@utils/app";
|
||||||
import { restoreScrollPosition, saveScrollPosition } from "@utils/browser";
|
import { restoreScrollPosition, saveScrollPosition } from "@utils/browser";
|
||||||
|
@ -59,6 +58,7 @@ import {
|
||||||
LockPost,
|
LockPost,
|
||||||
MarkCommentReplyAsRead,
|
MarkCommentReplyAsRead,
|
||||||
MarkPersonMentionAsRead,
|
MarkPersonMentionAsRead,
|
||||||
|
MyUserInfo,
|
||||||
PersonView,
|
PersonView,
|
||||||
PostResponse,
|
PostResponse,
|
||||||
PurgeComment,
|
PurgeComment,
|
||||||
|
@ -73,9 +73,13 @@ import {
|
||||||
TransferCommunity,
|
TransferCommunity,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { fetchLimit, relTags } from "../../config";
|
import { fetchLimit, relTags } from "../../config";
|
||||||
import { InitialFetchRequest, PersonDetailsView } from "../../interfaces";
|
import {
|
||||||
|
InitialFetchRequest,
|
||||||
|
IsoData,
|
||||||
|
PersonDetailsView,
|
||||||
|
} from "../../interfaces";
|
||||||
import { mdToHtml } from "../../markdown";
|
import { mdToHtml } from "../../markdown";
|
||||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
import { FirstLoadService, I18NextService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
HttpService,
|
HttpService,
|
||||||
|
@ -159,13 +163,16 @@ const getCommunitiesListing = (
|
||||||
const Moderates = ({ moderates }: { moderates?: CommunityModeratorView[] }) =>
|
const Moderates = ({ moderates }: { moderates?: CommunityModeratorView[] }) =>
|
||||||
getCommunitiesListing("moderates", moderates);
|
getCommunitiesListing("moderates", moderates);
|
||||||
|
|
||||||
const Follows = () =>
|
const Follows = ({ myUserInfo }: { myUserInfo?: MyUserInfo }) =>
|
||||||
getCommunitiesListing("subscribed", UserService.Instance.myUserInfo?.follows);
|
getCommunitiesListing("subscribed", myUserInfo?.follows);
|
||||||
|
|
||||||
function isPersonBlocked(personRes: RequestState<GetPersonDetailsResponse>) {
|
function isPersonBlocked(
|
||||||
|
personRes: RequestState<GetPersonDetailsResponse>,
|
||||||
|
myUserInfo?: MyUserInfo,
|
||||||
|
) {
|
||||||
return (
|
return (
|
||||||
(personRes.state === "success" &&
|
(personRes.state === "success" &&
|
||||||
UserService.Instance.myUserInfo?.person_blocks.some(
|
myUserInfo?.person_blocks.some(
|
||||||
({ target: { id } }) => id === personRes.data.person_view.person.id,
|
({ target: { id } }) => id === personRes.data.person_view.person.id,
|
||||||
)) ??
|
)) ??
|
||||||
false
|
false
|
||||||
|
@ -176,7 +183,9 @@ export class Profile extends Component<
|
||||||
RouteComponentProps<{ username: string }>,
|
RouteComponentProps<{ username: string }>,
|
||||||
ProfileState
|
ProfileState
|
||||||
> {
|
> {
|
||||||
private isoData = setIsoData<ProfileData>(this.context);
|
get isoData(): IsoData<ProfileData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
state: ProfileState = {
|
state: ProfileState = {
|
||||||
personRes: EMPTY_REQUEST,
|
personRes: EMPTY_REQUEST,
|
||||||
personBlocked: false,
|
personBlocked: false,
|
||||||
|
@ -269,7 +278,7 @@ export class Profile extends Component<
|
||||||
get amCurrentUser() {
|
get amCurrentUser() {
|
||||||
if (this.state.personRes.state === "success") {
|
if (this.state.personRes.state === "success") {
|
||||||
return (
|
return (
|
||||||
UserService.Instance.myUserInfo?.local_user_view.person.id ===
|
this.isoData.site_res.my_user?.local_user_view.person.id ===
|
||||||
this.state.personRes.data.person_view.person.id
|
this.state.personRes.data.person_view.person.id
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -388,7 +397,9 @@ export class Profile extends Component<
|
||||||
|
|
||||||
<div className="col-12 col-md-4">
|
<div className="col-12 col-md-4">
|
||||||
<Moderates moderates={personRes.moderates} />
|
<Moderates moderates={personRes.moderates} />
|
||||||
{this.amCurrentUser && <Follows />}
|
{this.amCurrentUser && (
|
||||||
|
<Follows myUserInfo={this.isoData.site_res.my_user} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -511,7 +522,7 @@ export class Profile extends Component<
|
||||||
</div>
|
</div>
|
||||||
{this.banDialog(pv)}
|
{this.banDialog(pv)}
|
||||||
<div className="flex-grow-1 unselectable pointer mx-2"></div>
|
<div className="flex-grow-1 unselectable pointer mx-2"></div>
|
||||||
{!this.amCurrentUser && UserService.Instance.myUserInfo && (
|
{!this.amCurrentUser && this.isoData.site_res.my_user && (
|
||||||
<>
|
<>
|
||||||
<a
|
<a
|
||||||
className={`d-flex align-self-start btn btn-secondary me-2 ${
|
className={`d-flex align-self-start btn btn-secondary me-2 ${
|
||||||
|
@ -622,7 +633,7 @@ export class Profile extends Component<
|
||||||
{format(parseISO(pv.person.published), "PPP")}
|
{format(parseISO(pv.person.published), "PPP")}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{!UserService.Instance.myUserInfo && (
|
{!this.isoData.site_res.my_user && (
|
||||||
<div className="alert alert-info" role="alert">
|
<div className="alert alert-info" role="alert">
|
||||||
{I18NextService.i18n.t("profile_not_logged_in_alert")}
|
{I18NextService.i18n.t("profile_not_logged_in_alert")}
|
||||||
</div>
|
</div>
|
||||||
|
@ -799,7 +810,7 @@ export class Profile extends Component<
|
||||||
block,
|
block,
|
||||||
});
|
});
|
||||||
if (res.state === "success") {
|
if (res.state === "success") {
|
||||||
updatePersonBlock(res.data);
|
updatePersonBlock(res.data, this.isoData.site_res.my_user);
|
||||||
this.setState({ personBlocked: res.data.blocked });
|
this.setState({ personBlocked: res.data.blocked });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { editRegistrationApplication, setIsoData } from "@utils/app";
|
import { editRegistrationApplication } from "@utils/app";
|
||||||
import { randomStr } from "@utils/helpers";
|
import { randomStr } from "@utils/helpers";
|
||||||
import { RouteDataResponse } from "@utils/types";
|
import { RouteDataResponse } from "@utils/types";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
@ -11,8 +11,8 @@ import {
|
||||||
RegistrationApplicationView,
|
RegistrationApplicationView,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { fetchLimit } from "../../config";
|
import { fetchLimit } from "../../config";
|
||||||
import { InitialFetchRequest } from "../../interfaces";
|
import { InitialFetchRequest, IsoData } from "../../interfaces";
|
||||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
import { FirstLoadService, I18NextService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
HttpService,
|
HttpService,
|
||||||
|
@ -49,7 +49,9 @@ export class RegistrationApplications extends Component<
|
||||||
any,
|
any,
|
||||||
RegistrationApplicationsState
|
RegistrationApplicationsState
|
||||||
> {
|
> {
|
||||||
private isoData = setIsoData<RegistrationApplicationsData>(this.context);
|
get isoData(): IsoData<RegistrationApplicationsData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
state: RegistrationApplicationsState = {
|
state: RegistrationApplicationsState = {
|
||||||
appsRes: EMPTY_REQUEST,
|
appsRes: EMPTY_REQUEST,
|
||||||
siteRes: this.isoData.site_res,
|
siteRes: this.isoData.site_res,
|
||||||
|
@ -82,7 +84,7 @@ export class RegistrationApplications extends Component<
|
||||||
}
|
}
|
||||||
|
|
||||||
get documentTitle(): string {
|
get documentTitle(): string {
|
||||||
const mui = UserService.Instance.myUserInfo;
|
const mui = this.isoData.site_res.my_user;
|
||||||
return mui
|
return mui
|
||||||
? `@${mui.local_user_view.person.name} ${I18NextService.i18n.t(
|
? `@${mui.local_user_view.person.name} ${I18NextService.i18n.t(
|
||||||
"registration_applications",
|
"registration_applications",
|
||||||
|
|
|
@ -2,7 +2,6 @@ import {
|
||||||
editCommentReport,
|
editCommentReport,
|
||||||
editPostReport,
|
editPostReport,
|
||||||
editPrivateMessageReport,
|
editPrivateMessageReport,
|
||||||
setIsoData,
|
|
||||||
} from "@utils/app";
|
} from "@utils/app";
|
||||||
import { randomStr } from "@utils/helpers";
|
import { randomStr } from "@utils/helpers";
|
||||||
import { amAdmin } from "@utils/roles";
|
import { amAdmin } from "@utils/roles";
|
||||||
|
@ -29,13 +28,8 @@ import {
|
||||||
ResolvePrivateMessageReport,
|
ResolvePrivateMessageReport,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { fetchLimit } from "../../config";
|
import { fetchLimit } from "../../config";
|
||||||
import { InitialFetchRequest } from "../../interfaces";
|
import { InitialFetchRequest, IsoData } from "../../interfaces";
|
||||||
import {
|
import { FirstLoadService, HttpService, I18NextService } from "../../services";
|
||||||
FirstLoadService,
|
|
||||||
HttpService,
|
|
||||||
I18NextService,
|
|
||||||
UserService,
|
|
||||||
} from "../../services";
|
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
LOADING_REQUEST,
|
LOADING_REQUEST,
|
||||||
|
@ -94,7 +88,9 @@ interface ReportsState {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Reports extends Component<any, ReportsState> {
|
export class Reports extends Component<any, ReportsState> {
|
||||||
private isoData = setIsoData<ReportsData>(this.context);
|
get isoData(): IsoData<ReportsData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
state: ReportsState = {
|
state: ReportsState = {
|
||||||
commentReportsRes: EMPTY_REQUEST,
|
commentReportsRes: EMPTY_REQUEST,
|
||||||
postReportsRes: EMPTY_REQUEST,
|
postReportsRes: EMPTY_REQUEST,
|
||||||
|
@ -144,7 +140,7 @@ export class Reports extends Component<any, ReportsState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
get documentTitle(): string {
|
get documentTitle(): string {
|
||||||
const mui = UserService.Instance.myUserInfo;
|
const mui = this.isoData.site_res.my_user;
|
||||||
return mui
|
return mui
|
||||||
? `@${mui.local_user_view.person.name} ${I18NextService.i18n.t(
|
? `@${mui.local_user_view.person.name} ${I18NextService.i18n.t(
|
||||||
"reports",
|
"reports",
|
||||||
|
@ -397,6 +393,7 @@ export class Reports extends Component<any, ReportsState> {
|
||||||
return (
|
return (
|
||||||
<CommentReport
|
<CommentReport
|
||||||
key={i.id}
|
key={i.id}
|
||||||
|
myUserInfo={this.isoData.site_res.my_user}
|
||||||
report={i.view as CommentReportView}
|
report={i.view as CommentReportView}
|
||||||
onResolveReport={this.handleResolveCommentReport}
|
onResolveReport={this.handleResolveCommentReport}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -6,7 +6,6 @@ import {
|
||||||
instanceToChoice,
|
instanceToChoice,
|
||||||
myAuth,
|
myAuth,
|
||||||
personToChoice,
|
personToChoice,
|
||||||
setIsoData,
|
|
||||||
setTheme,
|
setTheme,
|
||||||
showLocal,
|
showLocal,
|
||||||
updateCommunityBlock,
|
updateCommunityBlock,
|
||||||
|
@ -37,7 +36,7 @@ import {
|
||||||
UpdateTotpResponse,
|
UpdateTotpResponse,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { elementUrl, emDash, fetchLimit, relTags } from "../../config";
|
import { elementUrl, emDash, fetchLimit, relTags } from "../../config";
|
||||||
import { FirstLoadService, UserService } from "../../services";
|
import { FirstLoadService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
HttpService,
|
HttpService,
|
||||||
|
@ -60,7 +59,7 @@ import { SortSelect } from "../common/sort-select";
|
||||||
import Tabs from "../common/tabs";
|
import Tabs from "../common/tabs";
|
||||||
import { CommunityLink } from "../community/community-link";
|
import { CommunityLink } from "../community/community-link";
|
||||||
import { PersonListing } from "./person-listing";
|
import { PersonListing } from "./person-listing";
|
||||||
import { InitialFetchRequest } from "../../interfaces";
|
import { InitialFetchRequest, IsoData } from "../../interfaces";
|
||||||
import TotpModal from "../common/totp-modal";
|
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";
|
||||||
|
@ -190,7 +189,9 @@ function handleClose2faModal(i: Settings) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Settings extends Component<any, SettingsState> {
|
export class Settings extends Component<any, SettingsState> {
|
||||||
private isoData = setIsoData<SettingsData>(this.context);
|
get isoData(): IsoData<SettingsData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
exportSettingsLink = createRef<HTMLAnchorElement>();
|
exportSettingsLink = createRef<HTMLAnchorElement>();
|
||||||
|
|
||||||
state: SettingsState = {
|
state: SettingsState = {
|
||||||
|
@ -246,7 +247,7 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
this.handleEnable2fa = this.handleEnable2fa.bind(this);
|
this.handleEnable2fa = this.handleEnable2fa.bind(this);
|
||||||
this.handleDisable2fa = this.handleDisable2fa.bind(this);
|
this.handleDisable2fa = this.handleDisable2fa.bind(this);
|
||||||
|
|
||||||
const mui = UserService.Instance.myUserInfo;
|
const mui = this.isoData.site_res.my_user;
|
||||||
if (mui) {
|
if (mui) {
|
||||||
const {
|
const {
|
||||||
local_user: {
|
local_user: {
|
||||||
|
@ -818,6 +819,7 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
showAll={true}
|
showAll={true}
|
||||||
showSite
|
showSite
|
||||||
onChange={this.handleDiscussionLanguageChange}
|
onChange={this.handleDiscussionLanguageChange}
|
||||||
|
myUserInfo={this.isoData.site_res.my_user}
|
||||||
/>
|
/>
|
||||||
<div className="mb-3 row">
|
<div className="mb-3 row">
|
||||||
<label className="col-sm-3 col-form-label" htmlFor="user-theme">
|
<label className="col-sm-3 col-form-label" htmlFor="user-theme">
|
||||||
|
@ -1125,7 +1127,7 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
|
|
||||||
totpSection() {
|
totpSection() {
|
||||||
const totpEnabled =
|
const totpEnabled =
|
||||||
!!UserService.Instance.myUserInfo?.local_user_view.local_user
|
!!this.isoData.site_res.my_user?.local_user_view.local_user
|
||||||
.totp_2fa_enabled;
|
.totp_2fa_enabled;
|
||||||
const { generateTotpRes } = this.state;
|
const { generateTotpRes } = this.state;
|
||||||
|
|
||||||
|
@ -1181,7 +1183,7 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
|
|
||||||
const siteRes = await HttpService.client.getSite();
|
const siteRes = await HttpService.client.getSite();
|
||||||
|
|
||||||
UserService.Instance.myUserInfo!.local_user_view.local_user.totp_2fa_enabled =
|
this.isoData.site_res.my_user!.local_user_view.local_user.totp_2fa_enabled =
|
||||||
enabled;
|
enabled;
|
||||||
|
|
||||||
if (siteRes.state === "success") {
|
if (siteRes.state === "success") {
|
||||||
|
@ -1349,7 +1351,7 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleShowAvatarsChange(i: Settings, event: any) {
|
handleShowAvatarsChange(i: Settings, event: any) {
|
||||||
const mui = UserService.Instance.myUserInfo;
|
const mui = this.isoData.site_res.my_user;
|
||||||
if (mui) {
|
if (mui) {
|
||||||
mui.local_user_view.local_user.show_avatars = event.target.checked;
|
mui.local_user_view.local_user.show_avatars = event.target.checked;
|
||||||
}
|
}
|
||||||
|
@ -1395,7 +1397,7 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleShowScoresChange(i: Settings, event: any) {
|
handleShowScoresChange(i: Settings, event: any) {
|
||||||
const mui = UserService.Instance.myUserInfo;
|
const mui = this.isoData.site_res.my_user;
|
||||||
if (mui) {
|
if (mui) {
|
||||||
mui.local_user_view.local_user.show_scores = event.target.checked;
|
mui.local_user_view.local_user.show_scores = event.target.checked;
|
||||||
}
|
}
|
||||||
|
@ -1528,6 +1530,7 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
siteRes: siteRes.data,
|
siteRes: siteRes.data,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO need to update this
|
||||||
UserService.Instance.myUserInfo = siteRes.data.my_user;
|
UserService.Instance.myUserInfo = siteRes.data.my_user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1628,6 +1631,7 @@ 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
|
||||||
UserService.Instance.myUserInfo = siteRes.data.my_user;
|
UserService.Instance.myUserInfo = siteRes.data.my_user;
|
||||||
updateDataBsTheme(siteRes.data);
|
updateDataBsTheme(siteRes.data);
|
||||||
|
|
||||||
|
@ -1705,8 +1709,8 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
|
|
||||||
personBlock(res: RequestState<BlockPersonResponse>) {
|
personBlock(res: RequestState<BlockPersonResponse>) {
|
||||||
if (res.state === "success") {
|
if (res.state === "success") {
|
||||||
updatePersonBlock(res.data);
|
updatePersonBlock(res.data, this.isoData.site_res.my_user);
|
||||||
const mui = UserService.Instance.myUserInfo;
|
const mui = this.isoData.site_res.my_user;
|
||||||
if (mui) {
|
if (mui) {
|
||||||
this.setState({ personBlocks: mui.person_blocks });
|
this.setState({ personBlocks: mui.person_blocks });
|
||||||
}
|
}
|
||||||
|
@ -1715,8 +1719,8 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
|
|
||||||
communityBlock(res: RequestState<BlockCommunityResponse>) {
|
communityBlock(res: RequestState<BlockCommunityResponse>) {
|
||||||
if (res.state === "success") {
|
if (res.state === "success") {
|
||||||
updateCommunityBlock(res.data);
|
updateCommunityBlock(res.data, this.isoData.site_res.my_user);
|
||||||
const mui = UserService.Instance.myUserInfo;
|
const mui = this.isoData.site_res.my_user;
|
||||||
if (mui) {
|
if (mui) {
|
||||||
this.setState({ communityBlocks: mui.community_blocks });
|
this.setState({ communityBlocks: mui.community_blocks });
|
||||||
}
|
}
|
||||||
|
@ -1730,8 +1734,13 @@ export class Settings extends Component<any, SettingsState> {
|
||||||
) {
|
) {
|
||||||
const linkedInstances =
|
const linkedInstances =
|
||||||
this.state.instancesRes.data.federated_instances?.linked ?? [];
|
this.state.instancesRes.data.federated_instances?.linked ?? [];
|
||||||
updateInstanceBlock(res.data, id, linkedInstances);
|
updateInstanceBlock(
|
||||||
const mui = UserService.Instance.myUserInfo;
|
res.data,
|
||||||
|
id,
|
||||||
|
linkedInstances,
|
||||||
|
this.isoData.site_res.my_user,
|
||||||
|
);
|
||||||
|
const mui = this.isoData.site_res.my_user;
|
||||||
if (mui) {
|
if (mui) {
|
||||||
this.setState({ instanceBlocks: mui.instance_blocks });
|
this.setState({ instanceBlocks: mui.instance_blocks });
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { setIsoData } from "@utils/app";
|
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
import { GetSiteResponse, SuccessResponse } from "lemmy-js-client";
|
import { GetSiteResponse, SuccessResponse } from "lemmy-js-client";
|
||||||
import { I18NextService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
|
@ -11,6 +10,7 @@ import {
|
||||||
import { toast } from "../../toast";
|
import { toast } from "../../toast";
|
||||||
import { HtmlTags } from "../common/html-tags";
|
import { HtmlTags } from "../common/html-tags";
|
||||||
import { Spinner } from "../common/icon";
|
import { Spinner } from "../common/icon";
|
||||||
|
import { IsoData } from "../../interfaces";
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
verifyRes: RequestState<SuccessResponse>;
|
verifyRes: RequestState<SuccessResponse>;
|
||||||
|
@ -18,7 +18,9 @@ interface State {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class VerifyEmail extends Component<any, State> {
|
export class VerifyEmail extends Component<any, State> {
|
||||||
private isoData = setIsoData(this.context);
|
get isoData(): IsoData {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
|
|
||||||
state: State = {
|
state: State = {
|
||||||
verifyRes: EMPTY_REQUEST,
|
verifyRes: EMPTY_REQUEST,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { enableDownvotes, enableNsfw, setIsoData } from "@utils/app";
|
import { enableDownvotes, enableNsfw } from "@utils/app";
|
||||||
import { getIdFromString, getQueryParams } from "@utils/helpers";
|
import { getIdFromString, getQueryParams } from "@utils/helpers";
|
||||||
import type { QueryParams } from "@utils/types";
|
import type { QueryParams } from "@utils/types";
|
||||||
import { Choice, RouteDataResponse } from "@utils/types";
|
import { Choice, RouteDataResponse } from "@utils/types";
|
||||||
|
@ -12,7 +12,7 @@ import {
|
||||||
LemmyHttp,
|
LemmyHttp,
|
||||||
ListCommunitiesResponse,
|
ListCommunitiesResponse,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { InitialFetchRequest, PostFormParams } from "../../interfaces";
|
import { InitialFetchRequest, IsoData, PostFormParams } from "../../interfaces";
|
||||||
import { FirstLoadService, I18NextService } from "../../services";
|
import { FirstLoadService, I18NextService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
|
@ -57,7 +57,9 @@ export class CreatePost extends Component<
|
||||||
RouteComponentProps<Record<string, never>>,
|
RouteComponentProps<Record<string, never>>,
|
||||||
CreatePostState
|
CreatePostState
|
||||||
> {
|
> {
|
||||||
private isoData = setIsoData<CreatePostData>(this.context);
|
get isoData(): IsoData<CreatePostData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
state: CreatePostState = {
|
state: CreatePostState = {
|
||||||
siteRes: this.isoData.site_res,
|
siteRes: this.isoData.site_res,
|
||||||
loading: true,
|
loading: true,
|
||||||
|
|
|
@ -17,6 +17,7 @@ import {
|
||||||
EditPost,
|
EditPost,
|
||||||
GetSiteMetadataResponse,
|
GetSiteMetadataResponse,
|
||||||
Language,
|
Language,
|
||||||
|
MyUserInfo,
|
||||||
PostView,
|
PostView,
|
||||||
SearchResponse,
|
SearchResponse,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
|
@ -28,7 +29,7 @@ import {
|
||||||
webArchiveUrl,
|
webArchiveUrl,
|
||||||
} from "../../config";
|
} from "../../config";
|
||||||
import { PostFormParams } from "../../interfaces";
|
import { PostFormParams } from "../../interfaces";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
HttpService,
|
HttpService,
|
||||||
|
@ -47,6 +48,7 @@ const MAX_POST_TITLE_LENGTH = 200;
|
||||||
|
|
||||||
interface PostFormProps {
|
interface PostFormProps {
|
||||||
post_view?: PostView; // If a post is given, that means this is an edit
|
post_view?: PostView; // If a post is given, that means this is an edit
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
crossPosts?: PostView[];
|
crossPosts?: PostView[];
|
||||||
allLanguages: Language[];
|
allLanguages: Language[];
|
||||||
siteLanguages: number[];
|
siteLanguages: number[];
|
||||||
|
@ -423,7 +425,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
||||||
accept="image/*,video/*"
|
accept="image/*,video/*"
|
||||||
name="file"
|
name="file"
|
||||||
className="small col-sm-10 form-control"
|
className="small col-sm-10 form-control"
|
||||||
disabled={!UserService.Instance.myUserInfo}
|
disabled={!this.props.myUserInfo}
|
||||||
onChange={linkEvent(this, handleImageUpload)}
|
onChange={linkEvent(this, handleImageUpload)}
|
||||||
/>
|
/>
|
||||||
{this.state.imageLoading && <Spinner />}
|
{this.state.imageLoading && <Spinner />}
|
||||||
|
@ -496,6 +498,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
||||||
selectedLanguageIds={selectedLangs}
|
selectedLanguageIds={selectedLangs}
|
||||||
multiple={false}
|
multiple={false}
|
||||||
onChange={this.handleLanguageChange}
|
onChange={this.handleLanguageChange}
|
||||||
|
myUserInfo={this.props.myUserInfo}
|
||||||
/>
|
/>
|
||||||
{!this.props.post_view && (
|
{!this.props.post_view && (
|
||||||
<div className="mb-3 row">
|
<div className="mb-3 row">
|
||||||
|
|
|
@ -33,6 +33,7 @@ import {
|
||||||
Language,
|
Language,
|
||||||
LockPost,
|
LockPost,
|
||||||
MarkPostAsRead,
|
MarkPostAsRead,
|
||||||
|
MyUserInfo,
|
||||||
PersonView,
|
PersonView,
|
||||||
PostView,
|
PostView,
|
||||||
PurgePerson,
|
PurgePerson,
|
||||||
|
@ -49,7 +50,7 @@ import {
|
||||||
VoteContentType,
|
VoteContentType,
|
||||||
} from "../../interfaces";
|
} from "../../interfaces";
|
||||||
import { mdToHtml, mdToHtmlInline } from "../../markdown";
|
import { mdToHtml, mdToHtmlInline } from "../../markdown";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import { setupTippy } from "../../tippy";
|
import { setupTippy } from "../../tippy";
|
||||||
import { Icon, PurgeWarning, Spinner } from "../common/icon";
|
import { Icon, PurgeWarning, Spinner } from "../common/icon";
|
||||||
import { MomentTime } from "../common/moment-time";
|
import { MomentTime } from "../common/moment-time";
|
||||||
|
@ -98,6 +99,7 @@ interface PostListingState {
|
||||||
|
|
||||||
interface PostListingProps {
|
interface PostListingProps {
|
||||||
post_view: PostView;
|
post_view: PostView;
|
||||||
|
myUserInfo?: MyUserInfo;
|
||||||
crossPosts?: PostView[];
|
crossPosts?: PostView[];
|
||||||
moderators?: CommunityModeratorView[];
|
moderators?: CommunityModeratorView[];
|
||||||
admins?: PersonView[];
|
admins?: PersonView[];
|
||||||
|
@ -171,11 +173,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount(): void {
|
componentDidMount(): void {
|
||||||
if (UserService.Instance.myUserInfo) {
|
if (this.props.myUserInfo) {
|
||||||
this.setState({
|
this.setState({
|
||||||
imageExpanded:
|
imageExpanded:
|
||||||
UserService.Instance.myUserInfo.local_user_view.local_user
|
this.props.myUserInfo.local_user_view.local_user.auto_expand,
|
||||||
.auto_expand,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -629,6 +630,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}
|
||||||
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}
|
||||||
|
@ -639,9 +641,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
|
|
||||||
{this.props.showBody && pv.post.body && this.viewSourceButton}
|
{this.props.showBody && pv.post.body && this.viewSourceButton}
|
||||||
|
|
||||||
{UserService.Instance.myUserInfo &&
|
{this.props.myUserInfo && !this.props.viewOnly && this.postActions()}
|
||||||
!this.props.viewOnly &&
|
|
||||||
this.postActions()}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -687,7 +687,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Any mod can do these, not limited to hierarchy*/}
|
{/* Any mod can do these, not limited to hierarchy*/}
|
||||||
{(amMod(this.postView.community.id) || amAdmin()) && (
|
{(amMod(this.postView.community.id, this.props.myUserInfo) ||
|
||||||
|
amAdmin(this.props.myUserInfo)) && (
|
||||||
<>
|
<>
|
||||||
<li>
|
<li>
|
||||||
<hr className="dropdown-divider" />
|
<hr className="dropdown-divider" />
|
||||||
|
@ -718,7 +719,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{(amCommunityCreator(pv.creator.id, this.props.moderators) ||
|
{(amCommunityCreator(
|
||||||
|
pv.creator.id,
|
||||||
|
this.props.moderators,
|
||||||
|
this.props.myUserInfo,
|
||||||
|
) ||
|
||||||
this.canAdmin_) &&
|
this.canAdmin_) &&
|
||||||
pv.creator_is_moderator && (
|
pv.creator_is_moderator && (
|
||||||
<li>{this.transferCommunityButton}</li>
|
<li>{this.transferCommunityButton}</li>
|
||||||
|
@ -753,7 +758,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public get linkTarget(): string {
|
public get linkTarget(): string {
|
||||||
return UserService.Instance.myUserInfo?.local_user_view.local_user
|
return this.props.myUserInfo?.local_user_view.local_user
|
||||||
.open_links_in_new_tab
|
.open_links_in_new_tab
|
||||||
? "_blank"
|
? "_blank"
|
||||||
: // _self is the default target on links when the field is not specified
|
: // _self is the default target on links when the field is not specified
|
||||||
|
@ -1378,6 +1383,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}
|
||||||
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}
|
||||||
|
@ -1409,7 +1415,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
private get myPost(): boolean {
|
private get myPost(): boolean {
|
||||||
return (
|
return (
|
||||||
this.postView.creator.id ===
|
this.postView.creator.id ===
|
||||||
UserService.Instance.myUserInfo?.local_user_view.person.id
|
this.props.myUserInfo?.local_user_view.person.id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1774,10 +1780,15 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
this.postView.creator.id,
|
this.postView.creator.id,
|
||||||
this.props.moderators,
|
this.props.moderators,
|
||||||
this.props.admins,
|
this.props.admins,
|
||||||
|
this.props.myUserInfo,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get canAdmin_(): boolean {
|
get canAdmin_(): boolean {
|
||||||
return canAdmin(this.postView.creator.id, this.props.admins);
|
return canAdmin(
|
||||||
|
this.postView.creator.id,
|
||||||
|
this.props.admins,
|
||||||
|
this.props.myUserInfo,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import {
|
||||||
getCommentParentId,
|
getCommentParentId,
|
||||||
getDepthFromComment,
|
getDepthFromComment,
|
||||||
getIdFromProps,
|
getIdFromProps,
|
||||||
setIsoData,
|
|
||||||
updateCommunityBlock,
|
updateCommunityBlock,
|
||||||
updatePersonBlock,
|
updatePersonBlock,
|
||||||
} from "@utils/app";
|
} from "@utils/app";
|
||||||
|
@ -80,8 +79,9 @@ import {
|
||||||
CommentNodeI,
|
CommentNodeI,
|
||||||
CommentViewType,
|
CommentViewType,
|
||||||
InitialFetchRequest,
|
InitialFetchRequest,
|
||||||
|
IsoData,
|
||||||
} from "../../interfaces";
|
} from "../../interfaces";
|
||||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
import { FirstLoadService, I18NextService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
HttpService,
|
HttpService,
|
||||||
|
@ -123,7 +123,9 @@ interface PostState {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Post extends Component<any, PostState> {
|
export class Post extends Component<any, PostState> {
|
||||||
private isoData = setIsoData<PostData>(this.context);
|
get isoData(): IsoData<PostData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
private commentScrollDebounced: () => void;
|
private commentScrollDebounced: () => void;
|
||||||
state: PostState = {
|
state: PostState = {
|
||||||
postRes: EMPTY_REQUEST,
|
postRes: EMPTY_REQUEST,
|
||||||
|
@ -402,6 +404,7 @@ export class Post extends Component<any, PostState> {
|
||||||
{!this.state.commentId && (
|
{!this.state.commentId && (
|
||||||
<CommentForm
|
<CommentForm
|
||||||
node={res.post_view.post.id}
|
node={res.post_view.post.id}
|
||||||
|
loggedIn={!!this.isoData.site_res.my_user}
|
||||||
disabled={res.post_view.post.locked}
|
disabled={res.post_view.post.locked}
|
||||||
allLanguages={this.state.siteRes.all_languages}
|
allLanguages={this.state.siteRes.all_languages}
|
||||||
siteLanguages={this.state.siteRes.discussion_languages}
|
siteLanguages={this.state.siteRes.discussion_languages}
|
||||||
|
@ -761,7 +764,7 @@ export class Post extends Component<any, PostState> {
|
||||||
// Update myUserInfo
|
// Update myUserInfo
|
||||||
if (followCommunityRes.state === "success") {
|
if (followCommunityRes.state === "success") {
|
||||||
const communityId = followCommunityRes.data.community_view.community.id;
|
const communityId = followCommunityRes.data.community_view.community.id;
|
||||||
const mui = UserService.Instance.myUserInfo;
|
const mui = this.isoData.site_res.my_user;
|
||||||
if (mui) {
|
if (mui) {
|
||||||
mui.follows = mui.follows.filter(i => i.community.id !== communityId);
|
mui.follows = mui.follows.filter(i => i.community.id !== communityId);
|
||||||
}
|
}
|
||||||
|
@ -791,7 +794,10 @@ export class Post extends Component<any, PostState> {
|
||||||
async handleBlockCommunity(form: BlockCommunity) {
|
async handleBlockCommunity(form: BlockCommunity) {
|
||||||
const blockCommunityRes = await HttpService.client.blockCommunity(form);
|
const blockCommunityRes = await HttpService.client.blockCommunity(form);
|
||||||
if (blockCommunityRes.state === "success") {
|
if (blockCommunityRes.state === "success") {
|
||||||
updateCommunityBlock(blockCommunityRes.data);
|
updateCommunityBlock(
|
||||||
|
blockCommunityRes.data,
|
||||||
|
this.isoData.site_res.my_user,
|
||||||
|
);
|
||||||
this.setState(s => {
|
this.setState(s => {
|
||||||
if (s.postRes.state === "success") {
|
if (s.postRes.state === "success") {
|
||||||
s.postRes.data.community_view.blocked =
|
s.postRes.data.community_view.blocked =
|
||||||
|
@ -804,7 +810,7 @@ export class Post extends Component<any, PostState> {
|
||||||
async handleBlockPerson(form: BlockPerson) {
|
async handleBlockPerson(form: BlockPerson) {
|
||||||
const blockPersonRes = await HttpService.client.blockPerson(form);
|
const blockPersonRes = await HttpService.client.blockPerson(form);
|
||||||
if (blockPersonRes.state === "success") {
|
if (blockPersonRes.state === "success") {
|
||||||
updatePersonBlock(blockPersonRes.data);
|
updatePersonBlock(blockPersonRes.data, this.isoData.site_res.my_user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { getRecipientIdFromProps, setIsoData } from "@utils/app";
|
import { getRecipientIdFromProps } from "@utils/app";
|
||||||
import { RouteDataResponse } from "@utils/types";
|
import { RouteDataResponse } from "@utils/types";
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
import {
|
import {
|
||||||
|
@ -8,7 +8,7 @@ import {
|
||||||
GetSiteResponse,
|
GetSiteResponse,
|
||||||
LemmyHttp,
|
LemmyHttp,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { InitialFetchRequest } from "../../interfaces";
|
import { InitialFetchRequest, IsoData } from "../../interfaces";
|
||||||
import { FirstLoadService, I18NextService } from "../../services";
|
import { FirstLoadService, I18NextService } from "../../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
|
@ -38,7 +38,9 @@ export class CreatePrivateMessage extends Component<
|
||||||
any,
|
any,
|
||||||
CreatePrivateMessageState
|
CreatePrivateMessageState
|
||||||
> {
|
> {
|
||||||
private isoData = setIsoData<CreatePrivateMessageData>(this.context);
|
get isoData(): IsoData<CreatePrivateMessageData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
state: CreatePrivateMessageState = {
|
state: CreatePrivateMessageState = {
|
||||||
siteRes: this.isoData.site_res,
|
siteRes: this.isoData.site_res,
|
||||||
recipientRes: EMPTY_REQUEST,
|
recipientRes: EMPTY_REQUEST,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { setIsoData } from "@utils/app";
|
|
||||||
import { getQueryParams } from "@utils/helpers";
|
import { getQueryParams } from "@utils/helpers";
|
||||||
import { QueryParams, RouteDataResponse } from "@utils/types";
|
import { QueryParams, RouteDataResponse } from "@utils/types";
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, linkEvent } from "inferno";
|
||||||
|
@ -7,7 +6,7 @@ import {
|
||||||
LemmyHttp,
|
LemmyHttp,
|
||||||
ResolveObjectResponse,
|
ResolveObjectResponse,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { InitialFetchRequest } from "../interfaces";
|
import { InitialFetchRequest, IsoData } from "../interfaces";
|
||||||
import { FirstLoadService, HttpService, I18NextService } from "../services";
|
import { FirstLoadService, HttpService, I18NextService } from "../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
|
@ -84,7 +83,9 @@ const handleFollow = (i: RemoteFetch) => handleToggleFollow(i, true);
|
||||||
const handleUnfollow = (i: RemoteFetch) => handleToggleFollow(i, false);
|
const handleUnfollow = (i: RemoteFetch) => handleToggleFollow(i, false);
|
||||||
|
|
||||||
export class RemoteFetch extends Component<any, RemoteFetchState> {
|
export class RemoteFetch extends Component<any, RemoteFetchState> {
|
||||||
private isoData = setIsoData<RemoteFetchData>(this.context);
|
get isoData(): IsoData<RemoteFetchData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
state: RemoteFetchState = {
|
state: RemoteFetchState = {
|
||||||
resolveObjectRes: EMPTY_REQUEST,
|
resolveObjectRes: EMPTY_REQUEST,
|
||||||
isIsomorphic: false,
|
isIsomorphic: false,
|
||||||
|
|
|
@ -8,7 +8,6 @@ import {
|
||||||
getUpdatedSearchId,
|
getUpdatedSearchId,
|
||||||
myAuth,
|
myAuth,
|
||||||
personToChoice,
|
personToChoice,
|
||||||
setIsoData,
|
|
||||||
showLocal,
|
showLocal,
|
||||||
} from "@utils/app";
|
} from "@utils/app";
|
||||||
import { restoreScrollPosition, saveScrollPosition } from "@utils/browser";
|
import { restoreScrollPosition, saveScrollPosition } from "@utils/browser";
|
||||||
|
@ -47,7 +46,7 @@ import {
|
||||||
SortType,
|
SortType,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { fetchLimit } from "../config";
|
import { fetchLimit } from "../config";
|
||||||
import { CommentViewType, InitialFetchRequest } from "../interfaces";
|
import { CommentViewType, InitialFetchRequest, IsoData } from "../interfaces";
|
||||||
import { FirstLoadService, I18NextService } from "../services";
|
import { FirstLoadService, I18NextService } from "../services";
|
||||||
import {
|
import {
|
||||||
EMPTY_REQUEST,
|
EMPTY_REQUEST,
|
||||||
|
@ -241,7 +240,9 @@ function getListing(
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Search extends Component<any, SearchState> {
|
export class Search extends Component<any, SearchState> {
|
||||||
private isoData = setIsoData<SearchData>(this.context);
|
get isoData(): IsoData<SearchData> {
|
||||||
|
return this.context.store.getState().value;
|
||||||
|
}
|
||||||
searchInput = createRef<HTMLInputElement>();
|
searchInput = createRef<HTMLInputElement>();
|
||||||
|
|
||||||
state: SearchState = {
|
state: SearchState = {
|
||||||
|
|
|
@ -20,7 +20,7 @@ export type IsoDataOptionalSite<T extends RouteData = any> = Partial<
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
isoData: IsoData;
|
isoData?: IsoDataOptionalSite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import { getHttpBase } from "@utils/env";
|
import { getHttpBase } from "@utils/env";
|
||||||
import { LemmyHttp } from "lemmy-js-client";
|
import { LemmyHttp, LoginResponse } from "lemmy-js-client";
|
||||||
import { toast } from "../toast";
|
import { toast } from "../toast";
|
||||||
import { I18NextService } from "./I18NextService";
|
import { I18NextService } from "./I18NextService";
|
||||||
|
import { clearAuthCookie, isBrowser, setAuthCookie } from "@utils/browser";
|
||||||
|
import { isAuthPath } from "@utils/app";
|
||||||
|
import cookie from "cookie";
|
||||||
|
import { authCookieName } from "../config";
|
||||||
|
|
||||||
export const EMPTY_REQUEST = {
|
export const EMPTY_REQUEST = {
|
||||||
state: "empty",
|
state: "empty",
|
||||||
|
@ -56,7 +60,7 @@ class WrappedLemmyHttpClient {
|
||||||
Object.getPrototypeOf(this.rawClient),
|
Object.getPrototypeOf(this.rawClient),
|
||||||
)) {
|
)) {
|
||||||
if (key !== "constructor") {
|
if (key !== "constructor") {
|
||||||
this[key] = async (...args) => {
|
this[key] = async (...args: any) => {
|
||||||
try {
|
try {
|
||||||
const res = await this.rawClient[key](...args);
|
const res = await this.rawClient[key](...args);
|
||||||
|
|
||||||
|
@ -88,6 +92,18 @@ export function wrapClient(client: LemmyHttp, silent = false) {
|
||||||
) as unknown as WrappedLemmyHttp;
|
) as unknown as WrappedLemmyHttp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO These are unused for now
|
||||||
|
// interface Claims {
|
||||||
|
// sub: number;
|
||||||
|
// iss: string;
|
||||||
|
// iat: number;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// interface AuthInfo {
|
||||||
|
// claims: Claims;
|
||||||
|
// auth: string;
|
||||||
|
// }
|
||||||
|
|
||||||
export class HttpService {
|
export class HttpService {
|
||||||
static #_instance: HttpService;
|
static #_instance: HttpService;
|
||||||
#silent_client: WrappedLemmyHttp;
|
#silent_client: WrappedLemmyHttp;
|
||||||
|
@ -95,10 +111,42 @@ export class HttpService {
|
||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
const lemmyHttp = new LemmyHttp(getHttpBase());
|
const lemmyHttp = new LemmyHttp(getHttpBase());
|
||||||
|
const auth = cookie.parse(document.cookie)[authCookieName];
|
||||||
|
|
||||||
|
if (auth) {
|
||||||
|
HttpService.client.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({
|
||||||
|
res,
|
||||||
|
showToast = true,
|
||||||
|
}: {
|
||||||
|
res: LoginResponse;
|
||||||
|
showToast?: boolean;
|
||||||
|
}) {
|
||||||
|
if (isBrowser() && res.jwt) {
|
||||||
|
showToast && toast(I18NextService.i18n.t("logged_in"));
|
||||||
|
setAuthCookie(res.jwt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public logout() {
|
||||||
|
if (isBrowser()) {
|
||||||
|
clearAuthCookie();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#client.logout();
|
||||||
|
|
||||||
|
if (isAuthPath(location.pathname)) {
|
||||||
|
location.replace("/");
|
||||||
|
} else {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static get #Instance() {
|
static get #Instance() {
|
||||||
return this.#_instance ?? (this.#_instance = new this());
|
return this.#_instance ?? (this.#_instance = new this());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { UserService, 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 { myAuth } from "@utils/app";
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
import { isAuthPath } from "@utils/app";
|
|
||||||
import { clearAuthCookie, isBrowser, setAuthCookie } from "@utils/browser";
|
|
||||||
import * as cookie from "cookie";
|
|
||||||
import { jwtDecode } from "jwt-decode";
|
|
||||||
import { LoginResponse, MyUserInfo } from "lemmy-js-client";
|
|
||||||
import { toast } from "../toast";
|
|
||||||
import { I18NextService } from "./I18NextService";
|
|
||||||
import { amAdmin } from "@utils/roles";
|
|
||||||
import { HttpService } from ".";
|
|
||||||
import { authCookieName } from "../config";
|
|
||||||
|
|
||||||
interface Claims {
|
|
||||||
sub: number;
|
|
||||||
iss: string;
|
|
||||||
iat: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface AuthInfo {
|
|
||||||
claims: Claims;
|
|
||||||
auth: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class UserService {
|
|
||||||
static #instance: UserService;
|
|
||||||
public myUserInfo?: MyUserInfo;
|
|
||||||
public authInfo?: AuthInfo;
|
|
||||||
|
|
||||||
private constructor() {
|
|
||||||
this.#setAuthInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
public login({
|
|
||||||
res,
|
|
||||||
showToast = true,
|
|
||||||
}: {
|
|
||||||
res: LoginResponse;
|
|
||||||
showToast?: boolean;
|
|
||||||
}) {
|
|
||||||
if (isBrowser() && res.jwt) {
|
|
||||||
showToast && toast(I18NextService.i18n.t("logged_in"));
|
|
||||||
setAuthCookie(res.jwt);
|
|
||||||
this.#setAuthInfo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public logout() {
|
|
||||||
this.authInfo = undefined;
|
|
||||||
this.myUserInfo = undefined;
|
|
||||||
|
|
||||||
if (isBrowser()) {
|
|
||||||
clearAuthCookie();
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpService.client.logout();
|
|
||||||
|
|
||||||
if (isAuthPath(location.pathname)) {
|
|
||||||
location.replace("/");
|
|
||||||
} else {
|
|
||||||
location.reload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public auth(throwErr = false): string | undefined {
|
|
||||||
const auth = this.authInfo?.auth;
|
|
||||||
|
|
||||||
if (auth) {
|
|
||||||
return auth;
|
|
||||||
} else {
|
|
||||||
const msg = "No JWT cookie found";
|
|
||||||
|
|
||||||
if (throwErr && isBrowser()) {
|
|
||||||
console.error(msg);
|
|
||||||
toast(I18NextService.i18n.t("not_logged_in"), "danger");
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
// throw msg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#setAuthInfo() {
|
|
||||||
if (isBrowser()) {
|
|
||||||
const auth = cookie.parse(document.cookie)[authCookieName];
|
|
||||||
|
|
||||||
if (auth) {
|
|
||||||
HttpService.client.setHeaders({ Authorization: `Bearer ${auth}` });
|
|
||||||
this.authInfo = { auth, claims: jwtDecode(auth) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public get moderatesSomething(): boolean {
|
|
||||||
return amAdmin() || (this.myUserInfo?.moderates?.length ?? 0) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static get Instance() {
|
|
||||||
return this.#instance || (this.#instance = new this());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,4 @@
|
||||||
export { FirstLoadService } from "./FirstLoadService";
|
export { FirstLoadService } from "./FirstLoadService";
|
||||||
export { HttpService } from "./HttpService";
|
export { HttpService } from "./HttpService";
|
||||||
export { I18NextService } from "./I18NextService";
|
export { I18NextService } from "./I18NextService";
|
||||||
export { UserService } from "./UserService";
|
|
||||||
export { UnreadCounterService } from "./UnreadCounterService";
|
export { UnreadCounterService } from "./UnreadCounterService";
|
||||||
|
|
|
@ -43,7 +43,6 @@ import personToChoice from "./person-to-choice";
|
||||||
import postToCommentSortType from "./post-to-comment-sort-type";
|
import postToCommentSortType from "./post-to-comment-sort-type";
|
||||||
import searchCommentTree from "./search-comment-tree";
|
import searchCommentTree from "./search-comment-tree";
|
||||||
import selectableLanguages from "./selectable-languages";
|
import selectableLanguages from "./selectable-languages";
|
||||||
import setIsoData from "./set-iso-data";
|
|
||||||
import setTheme from "./set-theme";
|
import setTheme from "./set-theme";
|
||||||
import setupDateFns from "./setup-date-fns";
|
import setupDateFns from "./setup-date-fns";
|
||||||
import showAvatars from "./show-avatars";
|
import showAvatars from "./show-avatars";
|
||||||
|
@ -55,6 +54,7 @@ import updatePersonBlock from "./update-person-block";
|
||||||
import instanceToChoice from "./instance-to-choice";
|
import instanceToChoice from "./instance-to-choice";
|
||||||
import updateInstanceBlock from "./update-instance-block";
|
import updateInstanceBlock from "./update-instance-block";
|
||||||
import isAnonymousPath from "./is-anonymous-path";
|
import isAnonymousPath from "./is-anonymous-path";
|
||||||
|
import setupRedux from "./setup-redux";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
buildCommentsTree,
|
buildCommentsTree,
|
||||||
|
@ -102,11 +102,11 @@ export {
|
||||||
postToCommentSortType,
|
postToCommentSortType,
|
||||||
searchCommentTree,
|
searchCommentTree,
|
||||||
selectableLanguages,
|
selectableLanguages,
|
||||||
setIsoData,
|
|
||||||
setTheme,
|
setTheme,
|
||||||
setupDateFns,
|
setupDateFns,
|
||||||
showAvatars,
|
showAvatars,
|
||||||
showLocal,
|
showLocal,
|
||||||
|
setupRedux,
|
||||||
showScores,
|
showScores,
|
||||||
siteBannerCss,
|
siteBannerCss,
|
||||||
updateCommunityBlock,
|
updateCommunityBlock,
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { I18NextService, UserService } from "../../services";
|
||||||
import { updateDataBsTheme } from "@utils/browser";
|
import { updateDataBsTheme } from "@utils/browser";
|
||||||
|
|
||||||
export default function initializeSite(site?: GetSiteResponse) {
|
export default function initializeSite(site?: GetSiteResponse) {
|
||||||
|
// TODO Should already be in siteRes
|
||||||
UserService.Instance.myUserInfo = site?.my_user;
|
UserService.Instance.myUserInfo = site?.my_user;
|
||||||
updateDataBsTheme(site);
|
updateDataBsTheme(site);
|
||||||
I18NextService.i18n.changeLanguage();
|
I18NextService.i18n.changeLanguage();
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { MyUserInfo, PostView } from "lemmy-js-client";
|
import { MyUserInfo, PostView } from "lemmy-js-client";
|
||||||
import { UserService } from "../../services";
|
|
||||||
|
|
||||||
export default function isPostBlocked(
|
export default function isPostBlocked(
|
||||||
pv: PostView,
|
pv: PostView,
|
||||||
myUserInfo: MyUserInfo | undefined = UserService.Instance.myUserInfo,
|
myUserInfo?: MyUserInfo,
|
||||||
): boolean {
|
): boolean {
|
||||||
return (
|
return (
|
||||||
(myUserInfo?.community_blocks
|
(myUserInfo?.community_blocks
|
||||||
|
|
|
@ -1,6 +1,18 @@
|
||||||
import { UserService } from "../../services";
|
import { isBrowser } from "@utils/browser";
|
||||||
|
import { toast } from "../../../shared/toast";
|
||||||
|
import { I18NextService } from "../../services";
|
||||||
|
|
||||||
// Warning, do not use this in fetchInitialData
|
export default function myAuth(throwErr = false): string | undefined {
|
||||||
export default function myAuth(): string | undefined {
|
if (auth) {
|
||||||
return UserService.Instance.auth();
|
return auth;
|
||||||
|
} else {
|
||||||
|
const msg = "No JWT cookie found";
|
||||||
|
|
||||||
|
if (throwErr && isBrowser()) {
|
||||||
|
console.error(msg);
|
||||||
|
toast(I18NextService.i18n.t("not_logged_in"), "danger");
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { PostView } from "lemmy-js-client";
|
import { MyUserInfo, PostView } from "lemmy-js-client";
|
||||||
import { UserService } from "../../services";
|
|
||||||
|
|
||||||
export default function nsfwCheck(
|
export default function nsfwCheck(
|
||||||
pv: PostView,
|
pv: PostView,
|
||||||
myUserInfo = UserService.Instance.myUserInfo,
|
myUserInfo?: MyUserInfo,
|
||||||
): boolean {
|
): boolean {
|
||||||
const nsfw = pv.post.nsfw || pv.community.nsfw;
|
const nsfw = pv.post.nsfw || pv.community.nsfw;
|
||||||
const myShowNsfw = myUserInfo?.local_user_view.local_user.show_nsfw ?? false;
|
const myShowNsfw = myUserInfo?.local_user_view.local_user.show_nsfw ?? false;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { Language } from "lemmy-js-client";
|
import { Language, MyUserInfo } from "lemmy-js-client";
|
||||||
import { UserService } from "../../services";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This shows what language you can select
|
* This shows what language you can select
|
||||||
|
@ -13,7 +12,7 @@ export default function selectableLanguages(
|
||||||
siteLanguages: number[],
|
siteLanguages: number[],
|
||||||
showAll?: boolean,
|
showAll?: boolean,
|
||||||
showSite?: boolean,
|
showSite?: boolean,
|
||||||
myUserInfo = UserService.Instance.myUserInfo,
|
myUserInfo?: MyUserInfo,
|
||||||
): Language[] {
|
): Language[] {
|
||||||
const allLangIds = allLanguages.map(l => l.id);
|
const allLangIds = allLanguages.map(l => l.id);
|
||||||
let myLangs = myUserInfo?.discussion_languages ?? allLangIds;
|
let myLangs = myUserInfo?.discussion_languages ?? allLangIds;
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
import { isBrowser } from "@utils/browser";
|
|
||||||
import { IsoData, RouteData } from "../../interfaces";
|
|
||||||
|
|
||||||
export default function setIsoData<T extends RouteData>(
|
|
||||||
context: any,
|
|
||||||
): IsoData<T> {
|
|
||||||
// If its the browser, you need to deserialize the data from the window
|
|
||||||
if (isBrowser()) {
|
|
||||||
return window.isoData;
|
|
||||||
} else return context.router.staticContext;
|
|
||||||
}
|
|
13
src/shared/utils/app/setup-redux.ts
Normal file
13
src/shared/utils/app/setup-redux.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { configureStore, createSlice } from "@reduxjs/toolkit";
|
||||||
|
import { IsoDataOptionalSite } from "../../../shared/interfaces";
|
||||||
|
|
||||||
|
// TODO add reducer function here
|
||||||
|
export default function setupRedux(isoData?: IsoDataOptionalSite) {
|
||||||
|
const slice = createSlice({
|
||||||
|
name: "isoData",
|
||||||
|
initialState: { value: isoData },
|
||||||
|
reducers: {},
|
||||||
|
});
|
||||||
|
const store = configureStore({ reducer: slice.reducer });
|
||||||
|
return store;
|
||||||
|
}
|
|
@ -1,7 +1,5 @@
|
||||||
import { UserService } from "../../services";
|
import { MyUserInfo } from "lemmy-js-client";
|
||||||
|
|
||||||
export default function showAvatars(
|
export default function showAvatars(myUserInfo?: MyUserInfo): boolean {
|
||||||
myUserInfo = UserService.Instance.myUserInfo,
|
|
||||||
): boolean {
|
|
||||||
return myUserInfo?.local_user_view.local_user.show_avatars ?? true;
|
return myUserInfo?.local_user_view.local_user.show_avatars ?? true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import { UserService } from "../../services";
|
import { MyUserInfo } from "lemmy-js-client";
|
||||||
|
|
||||||
export default function showScores(
|
export default function showScores(myUserInfo?: MyUserInfo): boolean {
|
||||||
myUserInfo = UserService.Instance.myUserInfo,
|
|
||||||
): boolean {
|
|
||||||
return myUserInfo?.local_user_view.local_user.show_scores ?? true;
|
return myUserInfo?.local_user_view.local_user.show_scores ?? true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { BlockCommunityResponse, MyUserInfo } from "lemmy-js-client";
|
import { BlockCommunityResponse, MyUserInfo } from "lemmy-js-client";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import { toast } from "../../toast";
|
import { toast } from "../../toast";
|
||||||
|
|
||||||
export default function updateCommunityBlock(
|
export default function updateCommunityBlock(
|
||||||
data: BlockCommunityResponse,
|
data: BlockCommunityResponse,
|
||||||
myUserInfo: MyUserInfo | undefined = UserService.Instance.myUserInfo,
|
myUserInfo?: MyUserInfo,
|
||||||
) {
|
) {
|
||||||
if (myUserInfo) {
|
if (myUserInfo) {
|
||||||
if (data.blocked) {
|
if (data.blocked) {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { BlockInstanceResponse, Instance, MyUserInfo } from "lemmy-js-client";
|
import { BlockInstanceResponse, Instance, MyUserInfo } from "lemmy-js-client";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import { toast } from "../../toast";
|
import { toast } from "../../toast";
|
||||||
|
|
||||||
export default function updateInstanceBlock(
|
export default function updateInstanceBlock(
|
||||||
data: BlockInstanceResponse,
|
data: BlockInstanceResponse,
|
||||||
id: number,
|
id: number,
|
||||||
linkedInstances: Instance[],
|
linkedInstances: Instance[],
|
||||||
myUserInfo: MyUserInfo | undefined = UserService.Instance.myUserInfo,
|
myUserInfo?: MyUserInfo,
|
||||||
) {
|
) {
|
||||||
if (myUserInfo) {
|
if (myUserInfo) {
|
||||||
const instance = linkedInstances.find(i => i.id === id)!;
|
const instance = linkedInstances.find(i => i.id === id)!;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { BlockPersonResponse, MyUserInfo } from "lemmy-js-client";
|
import { BlockPersonResponse, MyUserInfo } from "lemmy-js-client";
|
||||||
import { I18NextService, UserService } from "../../services";
|
import { I18NextService } from "../../services";
|
||||||
import { toast } from "../../toast";
|
import { toast } from "../../toast";
|
||||||
|
|
||||||
export default function updatePersonBlock(
|
export default function updatePersonBlock(
|
||||||
data: BlockPersonResponse,
|
data: BlockPersonResponse,
|
||||||
myUserInfo: MyUserInfo | undefined = UserService.Instance.myUserInfo,
|
myUserInfo?: MyUserInfo,
|
||||||
) {
|
) {
|
||||||
if (myUserInfo) {
|
if (myUserInfo) {
|
||||||
if (data.blocked) {
|
if (data.blocked) {
|
||||||
|
|
0
src/shared/utils/app/update-redux.ts
Normal file
0
src/shared/utils/app/update-redux.ts
Normal file
|
@ -1,7 +1,5 @@
|
||||||
import { UserService } from "../../services";
|
import { MyUserInfo } from "lemmy-js-client";
|
||||||
|
|
||||||
export default function amAdmin(
|
export default function amAdmin(myUserInfo?: MyUserInfo): boolean {
|
||||||
myUserInfo = UserService.Instance.myUserInfo,
|
|
||||||
): boolean {
|
|
||||||
return myUserInfo?.local_user_view.local_user.admin ?? false;
|
return myUserInfo?.local_user_view.local_user.admin ?? false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import { CommunityModeratorView } from "lemmy-js-client";
|
import { CommunityModeratorView, MyUserInfo } from "lemmy-js-client";
|
||||||
import { UserService } from "../../services";
|
|
||||||
|
|
||||||
export default function amCommunityCreator(
|
export default function amCommunityCreator(
|
||||||
creator_id: number,
|
creator_id: number,
|
||||||
mods?: CommunityModeratorView[],
|
mods?: CommunityModeratorView[],
|
||||||
myUserInfo = UserService.Instance.myUserInfo,
|
myUserInfo?: MyUserInfo,
|
||||||
): boolean {
|
): boolean {
|
||||||
const myId = myUserInfo?.local_user_view.person.id;
|
const myId = myUserInfo?.local_user_view.person.id;
|
||||||
// Don't allow mod actions on yourself
|
// Don't allow mod actions on yourself
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { CommunityId } from "lemmy-js-client";
|
import { CommunityId, MyUserInfo } from "lemmy-js-client";
|
||||||
import { UserService } from "../../services";
|
|
||||||
|
|
||||||
export default function amMod(
|
export default function amMod(
|
||||||
communityId: CommunityId,
|
communityId: CommunityId,
|
||||||
myUserInfo = UserService.Instance.myUserInfo,
|
myUserInfo?: MyUserInfo,
|
||||||
): boolean {
|
): boolean {
|
||||||
return myUserInfo
|
return myUserInfo
|
||||||
? myUserInfo.moderates.map(cmv => cmv.community.id).includes(communityId)
|
? myUserInfo.moderates.map(cmv => cmv.community.id).includes(communityId)
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import { PersonView } from "lemmy-js-client";
|
import { MyUserInfo, PersonView } from "lemmy-js-client";
|
||||||
import { UserService } from "../../services";
|
|
||||||
|
|
||||||
export default function amSiteCreator(
|
export default function amSiteCreator(
|
||||||
creator_id: number,
|
creator_id: number,
|
||||||
admins?: PersonView[],
|
admins?: PersonView[],
|
||||||
myUserInfo = UserService.Instance.myUserInfo,
|
myUserInfo?: MyUserInfo,
|
||||||
): boolean {
|
): boolean {
|
||||||
const myId = myUserInfo?.local_user_view.person.id;
|
const myId = myUserInfo?.local_user_view.person.id;
|
||||||
return myId === admins?.at(0)?.person.id && myId !== creator_id;
|
return myId === admins?.at(0)?.person.id && myId !== creator_id;
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { CommunityModeratorView } from "lemmy-js-client";
|
import { CommunityModeratorView, MyUserInfo } from "lemmy-js-client";
|
||||||
import { UserService } from "../../services";
|
|
||||||
|
|
||||||
export default function amTopMod(
|
export default function amTopMod(
|
||||||
mods: CommunityModeratorView[],
|
mods: CommunityModeratorView[],
|
||||||
myUserInfo = UserService.Instance.myUserInfo,
|
myUserInfo?: MyUserInfo,
|
||||||
): boolean {
|
): boolean {
|
||||||
return mods.at(0)?.moderator.id === myUserInfo?.local_user_view.person.id;
|
return mods.at(0)?.moderator.id === myUserInfo?.local_user_view.person.id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import { canMod } from "@utils/roles";
|
import { canMod } from "@utils/roles";
|
||||||
import { PersonView } from "lemmy-js-client";
|
import { MyUserInfo, PersonView } from "lemmy-js-client";
|
||||||
import { UserService } from "../../services";
|
|
||||||
|
|
||||||
export default function canAdmin(
|
export default function canAdmin(
|
||||||
creatorId: number,
|
creatorId: number,
|
||||||
admins?: PersonView[],
|
admins?: PersonView[],
|
||||||
myUserInfo = UserService.Instance.myUserInfo,
|
myUserInfo?: MyUserInfo,
|
||||||
onSelf = false,
|
onSelf = false,
|
||||||
): boolean {
|
): boolean {
|
||||||
return canMod(creatorId, undefined, admins, myUserInfo, onSelf);
|
return canMod(creatorId, undefined, admins, myUserInfo, onSelf);
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
import { amAdmin } from "@utils/roles";
|
import { amAdmin } from "@utils/roles";
|
||||||
import { GetSiteResponse } from "lemmy-js-client";
|
import { GetSiteResponse } from "lemmy-js-client";
|
||||||
import { UserService } from "../../services";
|
|
||||||
|
|
||||||
export default function canCreateCommunity(
|
export default function canCreateCommunity(siteRes: GetSiteResponse): boolean {
|
||||||
siteRes: GetSiteResponse,
|
|
||||||
myUserInfo = UserService.Instance.myUserInfo,
|
|
||||||
): boolean {
|
|
||||||
const adminOnly = siteRes.site_view.local_site.community_creation_admin_only;
|
const adminOnly = siteRes.site_view.local_site.community_creation_admin_only;
|
||||||
// TODO: Make this check if user is logged on as well
|
// TODO: Make this check if user is logged on as well
|
||||||
return !adminOnly || amAdmin(myUserInfo);
|
return !adminOnly || amAdmin(siteRes.my_user);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
import { CommunityModeratorView, PersonView } from "lemmy-js-client";
|
import {
|
||||||
import { UserService } from "../../services";
|
CommunityModeratorView,
|
||||||
|
MyUserInfo,
|
||||||
|
PersonView,
|
||||||
|
} from "lemmy-js-client";
|
||||||
|
|
||||||
export default function canMod(
|
export default function canMod(
|
||||||
creator_id: number,
|
creator_id: number,
|
||||||
mods?: CommunityModeratorView[],
|
mods?: CommunityModeratorView[],
|
||||||
admins?: PersonView[],
|
admins?: PersonView[],
|
||||||
myUserInfo = UserService.Instance.myUserInfo,
|
myUserInfo?: MyUserInfo,
|
||||||
onSelf = false,
|
onSelf = false,
|
||||||
): boolean {
|
): boolean {
|
||||||
// You can do moderator actions only on the mods added after you.
|
// You can do moderator actions only on the mods added after you.
|
||||||
|
|
|
@ -7,6 +7,7 @@ import canAdmin from "./can-admin";
|
||||||
import canCreateCommunity from "./can-create-community";
|
import canCreateCommunity from "./can-create-community";
|
||||||
import canMod from "./can-mod";
|
import canMod from "./can-mod";
|
||||||
import isBanned from "./is-banned";
|
import isBanned from "./is-banned";
|
||||||
|
import moderatesSomething from "./moderates-something";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
amAdmin,
|
amAdmin,
|
||||||
|
@ -18,4 +19,5 @@ export {
|
||||||
canCreateCommunity,
|
canCreateCommunity,
|
||||||
canMod,
|
canMod,
|
||||||
isBanned,
|
isBanned,
|
||||||
|
moderatesSomething,
|
||||||
};
|
};
|
||||||
|
|
6
src/shared/utils/roles/moderates-something.ts
Normal file
6
src/shared/utils/roles/moderates-something.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { MyUserInfo } from "lemmy-js-client";
|
||||||
|
import amAdmin from "./am-admin";
|
||||||
|
|
||||||
|
export default function moderatesSomething(myUserInfo?: MyUserInfo): boolean {
|
||||||
|
return amAdmin(myUserInfo) || (myUserInfo?.moderates?.length ?? 0) > 0;
|
||||||
|
}
|
38
yarn.lock
38
yarn.lock
|
@ -1217,6 +1217,16 @@
|
||||||
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f"
|
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f"
|
||||||
integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==
|
integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==
|
||||||
|
|
||||||
|
"@reduxjs/toolkit@^2.0.1":
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-2.0.1.tgz#0a5233c1e35c1941b03aece39cceade3467a1062"
|
||||||
|
integrity sha512-fxIjrR9934cmS8YXIGd9e7s1XRsEU++aFc9DVNMFMRTM5Vtsg2DCRMj21eslGtDt43IUf9bJL3h5bwUlZleibA==
|
||||||
|
dependencies:
|
||||||
|
immer "^10.0.3"
|
||||||
|
redux "^5.0.0"
|
||||||
|
redux-thunk "^3.1.0"
|
||||||
|
reselect "^5.0.1"
|
||||||
|
|
||||||
"@rollup/plugin-babel@^5.2.0":
|
"@rollup/plugin-babel@^5.2.0":
|
||||||
version "5.3.1"
|
version "5.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283"
|
resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283"
|
||||||
|
@ -4829,6 +4839,11 @@ ignore@^5.2.0, ignore@^5.2.4:
|
||||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78"
|
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78"
|
||||||
integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==
|
integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==
|
||||||
|
|
||||||
|
immer@^10.0.3:
|
||||||
|
version "10.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/immer/-/immer-10.0.3.tgz#a8de42065e964aa3edf6afc282dfc7f7f34ae3c9"
|
||||||
|
integrity sha512-pwupu3eWfouuaowscykeckFmVTpqbzW+rXFCX8rQLkZzM9ftBmU/++Ra+o+L27mz03zJTlyV4UUr+fdKNffo4A==
|
||||||
|
|
||||||
immutable@^4.0.0:
|
immutable@^4.0.0:
|
||||||
version "4.3.4"
|
version "4.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f"
|
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f"
|
||||||
|
@ -4969,6 +4984,14 @@ inferno-i18next-dess@0.0.2:
|
||||||
inferno-shared "^8.0.3"
|
inferno-shared "^8.0.3"
|
||||||
inferno-vnode-flags "^8.0.3"
|
inferno-vnode-flags "^8.0.3"
|
||||||
|
|
||||||
|
inferno-redux@^8.2.2:
|
||||||
|
version "8.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/inferno-redux/-/inferno-redux-8.2.2.tgz#1df3520f169def67d616d3ba6b54e5b70a59948f"
|
||||||
|
integrity sha512-2H+lYaunRh9jJ92m4JWEDDaM86SeexMg68lf4iJcjs47rJU0GnLYyme508EW3WsIfO9f1say9j9EDzoeHrNTNQ==
|
||||||
|
dependencies:
|
||||||
|
hoist-non-inferno-statics "^1.1.3"
|
||||||
|
inferno "8.2.2"
|
||||||
|
|
||||||
inferno-router@^8.2.2:
|
inferno-router@^8.2.2:
|
||||||
version "8.2.2"
|
version "8.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/inferno-router/-/inferno-router-8.2.2.tgz#3d13e2610ecb8f6bb3e36421ab569c21777a0d23"
|
resolved "https://registry.yarnpkg.com/inferno-router/-/inferno-router-8.2.2.tgz#3d13e2610ecb8f6bb3e36421ab569c21777a0d23"
|
||||||
|
@ -7719,6 +7742,16 @@ rechoir@^0.8.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
resolve "^1.20.0"
|
resolve "^1.20.0"
|
||||||
|
|
||||||
|
redux-thunk@^3.1.0:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-3.1.0.tgz#94aa6e04977c30e14e892eae84978c1af6058ff3"
|
||||||
|
integrity sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==
|
||||||
|
|
||||||
|
redux@^5.0.0:
|
||||||
|
version "5.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/redux/-/redux-5.0.0.tgz#29572e29a439e094ff8fec46883fc45053f6736d"
|
||||||
|
integrity sha512-blLIYmYetpZMET6Q6uCY7Jtl/Im5OBldy+vNPauA8vvsdqyt66oep4EUpAMWNHauTC6xa9JuRPhRB72rY82QGA==
|
||||||
|
|
||||||
reflect.getprototypeof@^1.0.4:
|
reflect.getprototypeof@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3"
|
resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3"
|
||||||
|
@ -7849,6 +7882,11 @@ requires-port@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||||
integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==
|
integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==
|
||||||
|
|
||||||
|
reselect@^5.0.1:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/reselect/-/reselect-5.0.1.tgz#587cdaaeb4e0e8927cff80ebe2bbef05f74b1648"
|
||||||
|
integrity sha512-D72j2ubjgHpvuCiORWkOUxndHJrxDaSolheiz5CO+roz8ka97/4msh2E8F5qay4GawR5vzBt5MkbDHT+Rdy/Wg==
|
||||||
|
|
||||||
resolve-cwd@^3.0.0:
|
resolve-cwd@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
|
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
|
||||||
|
|
Loading…
Reference in a new issue