From 6320357d21bab63f6c4af285ff879b6c601ed48f Mon Sep 17 00:00:00 2001 From: Dessalines <dessalines@users.noreply.github.com> Date: Thu, 22 Sep 2022 11:03:35 -0400 Subject: [PATCH] Upgrade inferno v8.0.0 try2 (#790) * Upgrade non-breaking deps. * Upgrade to Inferno v8. Fixes #731 * Upgrading inferno-i18next-dess --- .eslintrc.json | 3 +- package.json | 17 +- src/shared/components/app/app.tsx | 2 +- src/shared/components/app/footer.tsx | 20 +- src/shared/components/app/navbar.tsx | 104 +- src/shared/components/app/no-match.tsx | 2 +- .../components/comment/comment-form.tsx | 6 +- .../components/comment/comment-node.tsx | 338 ++-- .../components/common/banner-icon-header.tsx | 2 +- .../components/common/comment-sort-select.tsx | 2 +- .../components/common/data-type-select.tsx | 2 +- src/shared/components/common/html-tags.tsx | 7 +- src/shared/components/common/icon.tsx | 6 +- .../components/common/image-upload-form.tsx | 27 +- .../components/common/listing-type-select.tsx | 2 +- .../components/common/markdown-textarea.tsx | 142 +- src/shared/components/common/paginator.tsx | 6 +- .../common/registration-application.tsx | 9 +- src/shared/components/common/sort-select.tsx | 14 +- src/shared/components/common/symbols.tsx | 4 +- .../components/community/communities.tsx | 66 +- .../components/community/community-form.tsx | 116 +- .../components/community/community-link.tsx | 2 +- src/shared/components/community/community.tsx | 68 +- .../components/community/create-community.tsx | 6 +- src/shared/components/community/sidebar.tsx | 112 +- src/shared/components/home/admin-settings.tsx | 47 +- src/shared/components/home/home.tsx | 113 +- src/shared/components/home/instances.tsx | 12 +- src/shared/components/home/legal.tsx | 2 +- src/shared/components/home/login.tsx | 40 +- src/shared/components/home/setup.tsx | 53 +- src/shared/components/home/signup.tsx | 138 +- src/shared/components/home/site-form.tsx | 201 +-- src/shared/components/home/site-sidebar.tsx | 34 +- src/shared/components/modlog.tsx | 574 ++++--- src/shared/components/person/inbox.tsx | 143 +- .../components/person/password-change.tsx | 37 +- .../components/person/person-details.tsx | 7 +- src/shared/components/person/profile.tsx | 121 +- .../person/registration-applications.tsx | 34 +- src/shared/components/person/reports.tsx | 58 +- src/shared/components/person/settings.tsx | 425 +++-- src/shared/components/person/verify-email.tsx | 9 +- src/shared/components/post/create-post.tsx | 39 +- src/shared/components/post/metadata-card.tsx | 55 +- src/shared/components/post/post-form.tsx | 209 +-- src/shared/components/post/post-listing.tsx | 349 ++-- src/shared/components/post/post-listings.tsx | 2 +- src/shared/components/post/post.tsx | 115 +- .../create-private-message.tsx | 27 +- .../private_message/private-message-form.tsx | 62 +- .../private_message/private-message.tsx | 39 +- src/shared/components/search.tsx | 155 +- src/shared/utils.ts | 2 +- yarn.lock | 1422 ++++++++++------- 56 files changed, 2964 insertions(+), 2645 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 4e05f0c5a..0c9a5f46f 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,7 +8,8 @@ ], "extends": [ "eslint:recommended", - "plugin:@typescript-eslint/recommended" + "plugin:@typescript-eslint/recommended", + "plugin:inferno/recommended" ], "parser": "@typescript-eslint/parser", "parserOptions": { diff --git a/package.json b/package.json index a430314b3..903974e96 100644 --- a/package.json +++ b/package.json @@ -25,13 +25,13 @@ "emoji-short-name": "^2.0.0", "express": "~4.18.1", "i18next": "^21.8.14", - "inferno": "^7.4.11", - "inferno-create-element": "^7.4.11", + "inferno": "^8.0.3", + "inferno-create-element": "^8.0.3", "inferno-helmet": "^5.2.1", - "inferno-hydrate": "^7.4.11", - "inferno-i18next-dess": "^0.0.1", - "inferno-router": "^7.4.11", - "inferno-server": "^7.4.11", + "inferno-hydrate": "^8.0.3", + "inferno-i18next-dess": "0.0.2", + "inferno-router": "^8.0.3", + "inferno-server": "^8.0.3", "isomorphic-cookie": "^1.2.4", "jwt-decode": "^3.1.2", "markdown-it": "^13.0.1", @@ -55,7 +55,7 @@ "@babel/plugin-proposal-decorators": "^7.18.9", "@babel/plugin-transform-runtime": "^7.18.9", "@babel/plugin-transform-typescript": "^7.18.8", - "@babel/preset-env": "7.18.9", + "@babel/preset-env": "7.19.1", "@babel/preset-typescript": "^7.18.6", "@babel/runtime": "^7.18.9", "@sniptt/monads": "^0.5.10", @@ -74,6 +74,7 @@ "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.7.1", "eslint": "^8.20.0", + "eslint-plugin-inferno": "^7.31.8", "eslint-plugin-prettier": "^4.2.1", "husky": "^8.0.1", "import-sort-style-module": "^6.0.0", @@ -95,7 +96,7 @@ "typescript": "^4.7.4", "webpack": "5.74.0", "webpack-cli": "^4.10.0", - "webpack-dev-server": "4.9.3", + "webpack-dev-server": "4.11.1", "webpack-node-externals": "^3.0.0" }, "engines": { diff --git a/src/shared/components/app/app.tsx b/src/shared/components/app/app.tsx index 72119a8d6..960f6badd 100644 --- a/src/shared/components/app/app.tsx +++ b/src/shared/components/app/app.tsx @@ -42,7 +42,7 @@ export class App extends Component<any, any> { none: <></>, })} <Navbar siteRes={siteRes} /> - <div class="mt-4 p-0 fl-1"> + <div className="mt-4 p-0 fl-1"> <Switch> {routes.map(({ path, exact, component: C, ...rest }) => ( <Route diff --git a/src/shared/components/app/footer.tsx b/src/shared/components/app/footer.tsx index e5e1db5a5..f2a5e83c9 100644 --- a/src/shared/components/app/footer.tsx +++ b/src/shared/components/app/footer.tsx @@ -16,16 +16,16 @@ export class Footer extends Component<FooterProps, any> { render() { return ( - <nav class="container navbar navbar-expand-md navbar-light navbar-bg p-3"> + <nav className="container navbar navbar-expand-md navbar-light navbar-bg p-3"> <div className="navbar-collapse"> - <ul class="navbar-nav ml-auto"> + <ul className="navbar-nav ml-auto"> {this.props.site.version !== VERSION && ( - <li class="nav-item"> - <span class="nav-link">UI: {VERSION}</span> + <li className="nav-item"> + <span className="nav-link">UI: {VERSION}</span> </li> )} - <li class="nav-item"> - <span class="nav-link">BE: {this.props.site.version}</span> + <li className="nav-item"> + <span className="nav-link">BE: {this.props.site.version}</span> </li> <li className="nav-item"> <NavLink className="nav-link" to="/modlog"> @@ -42,23 +42,23 @@ export class Footer extends Component<FooterProps, any> { </li> )} {this.props.site.federated_instances && ( - <li class="nav-item"> + <li className="nav-item"> <NavLink className="nav-link" to="/instances"> {i18n.t("instances")} </NavLink> </li> )} - <li class="nav-item"> + <li className="nav-item"> <a className="nav-link" href={docsUrl}> {i18n.t("docs")} </a> </li> - <li class="nav-item"> + <li className="nav-item"> <a className="nav-link" href={repoUrl}> {i18n.t("code")} </a> </li> - <li class="nav-item"> + <li className="nav-item"> <a className="nav-link" href={joinLemmyUrl}> {i18n.t("join_lemmy")} </a> diff --git a/src/shared/components/app/navbar.tsx b/src/shared/components/app/navbar.tsx index 2408a76b8..345003533 100644 --- a/src/shared/components/app/navbar.tsx +++ b/src/shared/components/app/navbar.tsx @@ -144,8 +144,8 @@ export class Navbar extends Component<NavbarProps, NavbarState> { // TODO class active corresponding to current page navbar() { return ( - <nav class="navbar navbar-expand-md navbar-light shadow-sm p-0 px-3"> - <div class="container"> + <nav className="navbar navbar-expand-md navbar-light shadow-sm p-0 px-3"> + <div className="container"> {this.props.siteRes.site_view.match({ some: siteView => ( <NavLink @@ -166,7 +166,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { })} {UserService.Instance.myUserInfo.isSome() && ( <> - <ul class="navbar-nav ml-auto"> + <ul className="navbar-nav ml-auto"> <li className="nav-item"> <NavLink to="/inbox" @@ -179,7 +179,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { > <Icon icon="bell" /> {this.state.unreadInboxCount > 0 && ( - <span class="mx-1 badge badge-light"> + <span className="mx-1 badge badge-light"> {numToSI(this.state.unreadInboxCount)} </span> )} @@ -187,7 +187,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { </li> </ul> {this.moderatesSomething && ( - <ul class="navbar-nav ml-1"> + <ul className="navbar-nav ml-1"> <li className="nav-item"> <NavLink to="/reports" @@ -200,7 +200,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { > <Icon icon="shield" /> {this.state.unreadReportCount > 0 && ( - <span class="mx-1 badge badge-light"> + <span className="mx-1 badge badge-light"> {numToSI(this.state.unreadReportCount)} </span> )} @@ -209,7 +209,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { </ul> )} {this.amAdmin && ( - <ul class="navbar-nav ml-1"> + <ul className="navbar-nav ml-1"> <li className="nav-item"> <NavLink to="/registration_applications" @@ -224,7 +224,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { > <Icon icon="clipboard" /> {this.state.unreadApplicationCount > 0 && ( - <span class="mx-1 badge badge-light"> + <span className="mx-1 badge badge-light"> {numToSI(this.state.unreadApplicationCount)} </span> )} @@ -235,7 +235,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { </> )} <button - class="navbar-toggler border-0 p-1" + className="navbar-toggler border-0 p-1" type="button" aria-label="menu" onClick={linkEvent(this, this.handleToggleExpandNavbar)} @@ -246,8 +246,8 @@ export class Navbar extends Component<NavbarProps, NavbarState> { <div className={`${!this.state.expanded && "collapse"} navbar-collapse`} > - <ul class="navbar-nav my-2 mr-auto"> - <li class="nav-item"> + <ul className="navbar-nav my-2 mr-auto"> + <li className="nav-item"> <NavLink to="/communities" className="nav-link" @@ -257,11 +257,15 @@ export class Navbar extends Component<NavbarProps, NavbarState> { {i18n.t("communities")} </NavLink> </li> - <li class="nav-item"> + <li className="nav-item"> + {/* TODO make sure this works: https://github.com/infernojs/inferno/issues/1608 */} <NavLink to={{ pathname: "/create_post", - prevPath: this.currentLocation, + search: "", + hash: "", + key: "", + state: { prevPath: this.currentLocation }, }} className="nav-link" onMouseUp={linkEvent(this, this.handleHideExpandNavbar)} @@ -271,7 +275,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { </NavLink> </li> {this.canCreateCommunity && ( - <li class="nav-item"> + <li className="nav-item"> <NavLink to="/create_community" className="nav-link" @@ -282,7 +286,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { </NavLink> </li> )} - <li class="nav-item"> + <li className="nav-item"> <a className="nav-link" title={i18n.t("support_lemmy")} @@ -292,7 +296,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { </a> </li> </ul> - <ul class="navbar-nav my-2"> + <ul className="navbar-nav my-2"> {this.amAdmin && ( <li className="nav-item"> <NavLink @@ -310,12 +314,12 @@ export class Navbar extends Component<NavbarProps, NavbarState> { /^\/search/ ) && ( <form - class="form-inline mr-2" + className="form-inline mr-2" onSubmit={linkEvent(this, this.handleSearchSubmit)} > <input id="search-input" - class={`form-control mr-0 search-input ${ + className={`form-control mr-0 search-input ${ this.state.toggleSearch ? "show-input" : "hide-input" }`} onInput={linkEvent(this, this.handleSearchParam)} @@ -325,13 +329,13 @@ export class Navbar extends Component<NavbarProps, NavbarState> { placeholder={i18n.t("search")} onBlur={linkEvent(this, this.handleSearchBlur)} ></input> - <label class="sr-only" htmlFor="search-input"> + <label className="sr-only" htmlFor="search-input"> {i18n.t("search")} </label> <button name="search-btn" onClick={linkEvent(this, this.handleSearchBtn)} - class="px-1 btn btn-link" + className="px-1 btn btn-link" style="color: var(--gray)" aria-label={i18n.t("search")} > @@ -341,7 +345,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { )} {UserService.Instance.myUserInfo.isSome() ? ( <> - <ul class="navbar-nav my-2"> + <ul className="navbar-nav my-2"> <li className="nav-item"> <NavLink className="nav-link" @@ -354,7 +358,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { > <Icon icon="bell" /> {this.state.unreadInboxCount > 0 && ( - <span class="ml-1 badge badge-light"> + <span className="ml-1 badge badge-light"> {numToSI(this.state.unreadInboxCount)} </span> )} @@ -362,7 +366,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { </li> </ul> {this.moderatesSomething && ( - <ul class="navbar-nav my-2"> + <ul className="navbar-nav my-2"> <li className="nav-item"> <NavLink className="nav-link" @@ -375,7 +379,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { > <Icon icon="shield" /> {this.state.unreadReportCount > 0 && ( - <span class="ml-1 badge badge-light"> + <span className="ml-1 badge badge-light"> {numToSI(this.state.unreadReportCount)} </span> )} @@ -384,7 +388,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { </ul> )} {this.amAdmin && ( - <ul class="navbar-nav my-2"> + <ul className="navbar-nav my-2"> <li className="nav-item"> <NavLink to="/registration_applications" @@ -399,7 +403,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { > <Icon icon="clipboard" /> {this.state.unreadApplicationCount > 0 && ( - <span class="mx-1 badge badge-light"> + <span className="mx-1 badge badge-light"> {numToSI(this.state.unreadApplicationCount)} </span> )} @@ -411,10 +415,10 @@ export class Navbar extends Component<NavbarProps, NavbarState> { .map(m => m.local_user_view.person) .match({ some: person => ( - <ul class="navbar-nav"> - <li class="nav-item dropdown"> + <ul className="navbar-nav"> + <li className="nav-item dropdown"> <button - class="nav-link btn btn-link dropdown-toggle" + className="nav-link btn btn-link dropdown-toggle" onClick={linkEvent(this, this.handleToggleDropdown)} id="navbarDropdown" role="button" @@ -433,7 +437,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { </button> {this.state.showDropdown && ( <div - class="dropdown-content" + className="dropdown-content" onMouseLeave={linkEvent( this, this.handleToggleDropdown @@ -460,7 +464,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { </NavLink> </li> <li> - <hr class="dropdown-divider" /> + <hr className="dropdown-divider" /> </li> <li className="nav-item"> <button @@ -484,7 +488,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { })} </> ) : ( - <ul class="navbar-nav my-2"> + <ul className="navbar-nav my-2"> <li className="nav-item"> <NavLink to="/login" @@ -532,8 +536,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { } handleToggleExpandNavbar(i: Navbar) { - i.state.expanded = !i.state.expanded; - i.setState(i.state); + i.setState({ expanded: !i.state.expanded }); } handleHideExpandNavbar(i: Navbar) { @@ -541,8 +544,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { } handleSearchParam(i: Navbar, event: any) { - i.state.searchParam = event.target.value; - i.setState(i.state); + i.setState({ searchParam: event.target.value }); } handleSearchSubmit(i: Navbar, event: any) { @@ -563,8 +565,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { handleSearchBlur(i: Navbar, event: any) { if (!(event.relatedTarget && event.relatedTarget.name !== "search-btn")) { - i.state.toggleSearch = false; - i.setState(i.state); + i.setState({ toggleSearch: false }); } } @@ -574,8 +575,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> { } handleToggleDropdown(i: Navbar) { - i.state.showDropdown = !i.state.showDropdown; - i.setState(i.state); + i.setState({ showDropdown: !i.state.showDropdown }); } parseMessage(msg: any) { @@ -601,25 +601,25 @@ export class Navbar extends Component<NavbarProps, NavbarState> { msg, GetUnreadCountResponse ); - this.state.unreadInboxCount = - data.replies + data.mentions + data.private_messages; - this.setState(this.state); + this.setState({ + unreadInboxCount: data.replies + data.mentions + data.private_messages, + }); this.sendUnreadCount(); } else if (op == UserOperation.GetReportCount) { let data = wsJsonToRes<GetReportCountResponse>( msg, GetReportCountResponse ); - this.state.unreadReportCount = data.post_reports + data.comment_reports; - this.setState(this.state); + this.setState({ + unreadReportCount: data.post_reports + data.comment_reports, + }); this.sendReportUnread(); } else if (op == UserOperation.GetUnreadRegistrationApplicationCount) { let data = wsJsonToRes<GetUnreadRegistrationApplicationCountResponse>( msg, GetUnreadRegistrationApplicationCountResponse ); - this.state.unreadApplicationCount = data.registration_applications; - this.setState(this.state); + this.setState({ unreadApplicationCount: data.registration_applications }); this.sendApplicationUnread(); } else if (op == UserOperation.CreateComment) { let data = wsJsonToRes<CommentResponse>(msg, CommentResponse); @@ -627,8 +627,9 @@ export class Navbar extends Component<NavbarProps, NavbarState> { UserService.Instance.myUserInfo.match({ some: mui => { if (data.recipient_ids.includes(mui.local_user_view.local_user.id)) { - this.state.unreadInboxCount++; - this.setState(this.state); + this.setState({ + unreadInboxCount: this.state.unreadInboxCount + 1, + }); this.sendUnreadCount(); notifyComment(data.comment_view, this.context.router); } @@ -647,8 +648,9 @@ export class Navbar extends Component<NavbarProps, NavbarState> { data.private_message_view.recipient.id == mui.local_user_view.person.id ) { - this.state.unreadInboxCount++; - this.setState(this.state); + this.setState({ + unreadInboxCount: this.state.unreadInboxCount + 1, + }); this.sendUnreadCount(); notifyPrivateMessage( data.private_message_view, diff --git a/src/shared/components/app/no-match.tsx b/src/shared/components/app/no-match.tsx index ca3fe64f0..45ba65e99 100644 --- a/src/shared/components/app/no-match.tsx +++ b/src/shared/components/app/no-match.tsx @@ -13,7 +13,7 @@ export class NoMatch extends Component<any, any> { render() { return ( - <div class="container"> + <div className="container"> <h1>404</h1> {this.errCode && ( <h3> diff --git a/src/shared/components/comment/comment-form.tsx b/src/shared/components/comment/comment-form.tsx index 6778b68fc..d91e86c17 100644 --- a/src/shared/components/comment/comment-form.tsx +++ b/src/shared/components/comment/comment-form.tsx @@ -75,7 +75,7 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { right: () => None, }); return ( - <div class="mb-3"> + <div className="mb-3"> {UserService.Instance.myUserInfo.isSome() ? ( <MarkdownTextArea initialContent={initialContent} @@ -90,7 +90,7 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { placeholder={Some(i18n.t("comment_here"))} /> ) : ( - <div class="alert alert-warning" role="alert"> + <div className="alert alert-warning" role="alert"> <Icon icon="alert-triangle" classes="icon-inline mr-2" /> <T i18nKey="must_login" class="d-inline"> # @@ -106,7 +106,7 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { handleCommentSubmit(msg: { val: string; formId: string }) { let content = msg.val; - this.state.formId = Some(msg.formId); + this.setState({ formId: Some(msg.formId) }); this.props.node.match({ left: node => { diff --git a/src/shared/components/comment/comment-node.tsx b/src/shared/components/comment/comment-node.tsx index f654b65a2..f5fc69813 100644 --- a/src/shared/components/comment/comment-node.tsx +++ b/src/shared/components/comment/comment-node.tsx @@ -147,13 +147,14 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { // TODO see if there's a better way to do this, and all willReceiveProps componentWillReceiveProps(nextProps: CommentNodeProps) { let cv = nextProps.node.comment_view; - this.state.my_vote = cv.my_vote; - this.state.upvotes = cv.counts.upvotes; - this.state.downvotes = cv.counts.downvotes; - this.state.score = cv.counts.score; - this.state.readLoading = false; - this.state.saveLoading = false; - this.setState(this.state); + this.setState({ + my_vote: cv.my_vote, + upvotes: cv.counts.upvotes, + downvotes: cv.counts.downvotes, + score: cv.counts.score, + readLoading: false, + saveLoading: false, + }); } render() { @@ -227,10 +228,12 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { } > <div - class={`${!this.props.noIndent && this.props.node.depth && "ml-2"}`} + className={`${ + !this.props.noIndent && this.props.node.depth && "ml-2" + }`} > - <div class="d-flex flex-wrap align-items-center text-muted small"> - <span class="mr-2"> + <div className="d-flex flex-wrap align-items-center text-muted small"> + <span className="mr-2"> <PersonListing person={cv.creator} /> </span> {cv.comment.distinguished && ( @@ -263,16 +266,16 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { )} {this.props.showCommunity && ( <> - <span class="mx-1">{i18n.t("to")}</span> + <span className="mx-1">{i18n.t("to")}</span> <CommunityLink community={cv.community} /> - <span class="mx-2">•</span> + <span className="mx-2">•</span> <Link className="mr-2" to={`/post/${cv.post.id}`}> {cv.post.name} </Link> </> )} <button - class="btn btn-sm text-muted" + className="btn btn-sm text-muted" onClick={linkEvent(this, this.handleCommentCollapse)} aria-label={this.expandText} data-tippy-content={this.expandText} @@ -294,7 +297,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { data-tippy-content={this.pointsTippy} > <span - class="mr-1 font-weight-bold" + className="mr-1 font-weight-bold" aria-label={i18n.t("number_of_points", { count: this.state.score, formattedCount: this.state.score, @@ -335,11 +338,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { )} /> )} - <div class="d-flex justify-content-between justify-content-lg-start flex-wrap text-muted font-weight-bold"> + <div className="d-flex justify-content-between justify-content-lg-start flex-wrap text-muted font-weight-bold"> {this.props.showContext && this.linkBtn()} {this.props.markable && ( <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent(this, this.handleMarkRead)} data-tippy-content={ this.commentReplyOrMentionRead @@ -380,7 +383,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { <Icon icon="arrow-up1" classes="icon-inline" /> {showScores() && this.state.upvotes !== this.state.score && ( - <span class="ml-1"> + <span className="ml-1"> {numToSI(this.state.upvotes)} </span> )} @@ -399,14 +402,14 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { <Icon icon="arrow-down1" classes="icon-inline" /> {showScores() && this.state.upvotes !== this.state.score && ( - <span class="ml-1"> + <span className="ml-1"> {numToSI(this.state.downvotes)} </span> )} </button> )} <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent(this, this.handleReplyClick)} data-tippy-content={i18n.t("reply")} aria-label={i18n.t("reply")} @@ -426,7 +429,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { <> {!this.myComment && ( <> - <button class="btn btn-link btn-animate"> + <button className="btn btn-link btn-animate"> <Link className="text-muted" to={`/create_private_message/recipient/${cv.creator.id}`} @@ -436,7 +439,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { </Link> </button> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleShowReportDialog @@ -449,7 +452,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { <Icon icon="flag" /> </button> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleBlockUserClick @@ -462,7 +465,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { </> )} <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleSaveCommentClick @@ -501,7 +504,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { {this.myComment && ( <> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleEditClick @@ -512,7 +515,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { <Icon icon="edit" classes="icon-inline" /> </button> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleDeleteClick @@ -538,7 +541,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { {(canModOnSelf || canAdminOnSelf) && ( <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleDistinguishClick @@ -570,7 +573,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { <> {!cv.comment.removed ? ( <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleModRemoveShow @@ -581,7 +584,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { </button> ) : ( <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleModRemoveSubmit @@ -599,7 +602,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { {!isMod_ && (!cv.creator_banned_from_community ? ( <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleModBanFromCommunityShow @@ -610,7 +613,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { </button> ) : ( <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleModBanFromCommunitySubmit @@ -623,7 +626,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { {!cv.creator_banned_from_community && (!this.state.showConfirmAppointAsMod ? ( <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleShowConfirmAppointAsMod @@ -641,13 +644,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { ) : ( <> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" aria-label={i18n.t("are_you_sure")} > {i18n.t("are_you_sure")} </button> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleAddModToCommunity @@ -657,7 +660,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { {i18n.t("yes")} </button> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleCancelConfirmAppointAsMod @@ -676,7 +679,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { cv.creator.local && (!this.state.showConfirmTransferCommunity ? ( <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleShowConfirmTransferCommunity @@ -688,13 +691,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { ) : ( <> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" aria-label={i18n.t("are_you_sure")} > {i18n.t("are_you_sure")} </button> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleTransferCommunity @@ -704,7 +707,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { {i18n.t("yes")} </button> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this @@ -722,7 +725,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { {!isAdmin_ && ( <> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handlePurgePersonShow @@ -732,7 +735,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { {i18n.t("purge_user")} </button> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handlePurgeCommentShow @@ -744,7 +747,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { {!isBanned(cv.creator) ? ( <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleModBanShow @@ -755,7 +758,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { </button> ) : ( <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleModBanSubmit @@ -771,7 +774,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { cv.creator.local && (!this.state.showConfirmAppointAsAdmin ? ( <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleShowConfirmAppointAsAdmin @@ -788,11 +791,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { </button> ) : ( <> - <button class="btn btn-link btn-animate text-muted"> + <button className="btn btn-link btn-animate text-muted"> {i18n.t("are_you_sure")} </button> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleAddAdmin @@ -802,7 +805,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { {i18n.t("yes")} </button> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent( this, this.handleCancelConfirmAppointAsAdmin @@ -833,7 +836,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { style={`border-left: 2px ${moreRepliesBorderColor} solid !important`} > <button - class="btn btn-link text-muted" + className="btn btn-link text-muted" onClick={linkEvent(this, this.handleFetchChildren)} > {i18n.t("x_more_replies", { @@ -847,11 +850,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { {/* end of details */} {this.state.showRemoveDialog && ( <form - class="form-inline" + className="form-inline" onSubmit={linkEvent(this, this.handleModRemoveSubmit)} > <label - class="sr-only" + className="sr-only" htmlFor={`mod-remove-reason-${cv.comment.id}`} > {i18n.t("reason")} @@ -859,14 +862,14 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { <input type="text" id={`mod-remove-reason-${cv.comment.id}`} - class="form-control mr-2" + className="form-control mr-2" placeholder={i18n.t("reason")} value={toUndefined(this.state.removeReason)} onInput={linkEvent(this, this.handleModRemoveReasonChange)} /> <button type="submit" - class="btn btn-secondary" + className="btn btn-secondary" aria-label={i18n.t("remove_comment")} > {i18n.t("remove_comment")} @@ -875,24 +878,27 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { )} {this.state.showReportDialog && ( <form - class="form-inline" + className="form-inline" onSubmit={linkEvent(this, this.handleReportSubmit)} > - <label class="sr-only" htmlFor={`report-reason-${cv.comment.id}`}> + <label + className="sr-only" + htmlFor={`report-reason-${cv.comment.id}`} + > {i18n.t("reason")} </label> <input type="text" required id={`report-reason-${cv.comment.id}`} - class="form-control mr-2" + className="form-control mr-2" placeholder={i18n.t("reason")} value={this.state.reportReason} onInput={linkEvent(this, this.handleReportReasonChange)} /> <button type="submit" - class="btn btn-secondary" + className="btn btn-secondary" aria-label={i18n.t("create_report")} > {i18n.t("create_report")} @@ -901,9 +907,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { )} {this.state.showBanDialog && ( <form onSubmit={linkEvent(this, this.handleModBanBothSubmit)}> - <div class="form-group row col-12"> + <div className="form-group row col-12"> <label - class="col-form-label" + className="col-form-label" htmlFor={`mod-ban-reason-${cv.comment.id}`} > {i18n.t("reason")} @@ -911,13 +917,13 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { <input type="text" id={`mod-ban-reason-${cv.comment.id}`} - class="form-control mr-2" + className="form-control mr-2" placeholder={i18n.t("reason")} value={toUndefined(this.state.banReason)} onInput={linkEvent(this, this.handleModBanReasonChange)} /> <label - class="col-form-label" + className="col-form-label" htmlFor={`mod-ban-expires-${cv.comment.id}`} > {i18n.t("expires")} @@ -925,22 +931,22 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { <input type="number" id={`mod-ban-expires-${cv.comment.id}`} - class="form-control mr-2" + className="form-control mr-2" placeholder={i18n.t("number_of_days")} value={toUndefined(this.state.banExpireDays)} onInput={linkEvent(this, this.handleModBanExpireDaysChange)} /> - <div class="form-group"> - <div class="form-check"> + <div className="form-group"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="mod-ban-remove-data" type="checkbox" checked={this.state.removeData} onChange={linkEvent(this, this.handleModRemoveDataChange)} /> <label - class="form-check-label" + className="form-check-label" htmlFor="mod-ban-remove-data" title={i18n.t("remove_content_more")} > @@ -954,10 +960,10 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { {/* <label class="col-form-label">Expires</label> */} {/* <input type="date" class="form-control mr-2" placeholder={i18n.t('expires')} value={this.state.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */} {/* </div> */} - <div class="form-group row"> + <div className="form-group row"> <button type="submit" - class="btn btn-secondary" + className="btn btn-secondary" aria-label={i18n.t("ban")} > {i18n.t("ban")} {cv.creator.name} @@ -969,24 +975,24 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { {this.state.showPurgeDialog && ( <form onSubmit={linkEvent(this, this.handlePurgeSubmit)}> <PurgeWarning /> - <label class="sr-only" htmlFor="purge-reason"> + <label className="sr-only" htmlFor="purge-reason"> {i18n.t("reason")} </label> <input type="text" id="purge-reason" - class="form-control my-3" + className="form-control my-3" placeholder={i18n.t("reason")} value={toUndefined(this.state.purgeReason)} onInput={linkEvent(this, this.handlePurgeReasonChange)} /> - <div class="form-group row col-12"> + <div className="form-group row col-12"> {this.state.purgeLoading ? ( <Spinner /> ) : ( <button type="submit" - class="btn btn-secondary" + className="btn btn-secondary" aria-label={purgeTypeText} > {purgeTypeText} @@ -1015,7 +1021,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { /> )} {/* A collapsed clearfix */} - {this.state.collapsed && <div class="row col-12"></div>} + {this.state.collapsed && <div className="row col-12"></div>} </div> ); } @@ -1090,13 +1096,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { } handleReplyClick(i: CommentNode) { - i.state.showReply = true; - i.setState(i.state); + i.setState({ showReply: true }); } handleEditClick(i: CommentNode) { - i.state.showEdit = true; - i.setState(i.state); + i.setState({ showEdit: true }); } handleBlockUserClick(i: CommentNode) { @@ -1129,14 +1133,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { WebSocketService.Instance.send(wsClient.saveComment(form)); - i.state.saveLoading = true; - i.setState(this.state); + i.setState({ saveLoading: true }); } handleReplyCancel() { - this.state.showReply = false; - this.state.showEdit = false; - this.setState(this.state); + this.setState({ showReply: false, showEdit: false }); } handleCommentUpvote(event: any) { @@ -1145,18 +1146,24 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { let newVote = myVote == 1 ? 0 : 1; if (myVote == 1) { - this.state.score--; - this.state.upvotes--; + this.setState({ + score: this.state.score - 1, + upvotes: this.state.upvotes - 1, + }); } else if (myVote == -1) { - this.state.downvotes--; - this.state.upvotes++; - this.state.score += 2; + this.setState({ + downvotes: this.state.downvotes - 1, + upvotes: this.state.upvotes + 1, + score: this.state.score + 2, + }); } else { - this.state.upvotes++; - this.state.score++; + this.setState({ + score: this.state.score + 1, + upvotes: this.state.upvotes + 1, + }); } - this.state.my_vote = Some(newVote); + this.setState({ my_vote: Some(newVote) }); let form = new CreateCommentLike({ comment_id: this.props.node.comment_view.comment.id, @@ -1164,7 +1171,6 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { auth: auth().unwrap(), }); WebSocketService.Instance.send(wsClient.likeComment(form)); - this.setState(this.state); setupTippy(); } @@ -1174,18 +1180,24 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { let newVote = myVote == -1 ? 0 : -1; if (myVote == 1) { - this.state.score -= 2; - this.state.upvotes--; - this.state.downvotes++; + this.setState({ + downvotes: this.state.downvotes + 1, + upvotes: this.state.upvotes - 1, + score: this.state.score - 2, + }); } else if (myVote == -1) { - this.state.downvotes--; - this.state.score++; + this.setState({ + downvotes: this.state.downvotes - 1, + score: this.state.score + 1, + }); } else { - this.state.downvotes++; - this.state.score--; + this.setState({ + downvotes: this.state.downvotes + 1, + score: this.state.score - 1, + }); } - this.state.my_vote = Some(newVote); + this.setState({ my_vote: Some(newVote) }); let form = new CreateCommentLike({ comment_id: this.props.node.comment_view.comment.id, @@ -1194,18 +1206,15 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { }); WebSocketService.Instance.send(wsClient.likeComment(form)); - this.setState(this.state); setupTippy(); } handleShowReportDialog(i: CommentNode) { - i.state.showReportDialog = !i.state.showReportDialog; - i.setState(i.state); + i.setState({ showReportDialog: !i.state.showReportDialog }); } handleReportReasonChange(i: CommentNode, event: any) { - i.state.reportReason = event.target.value; - i.setState(i.state); + i.setState({ reportReason: event.target.value }); } handleReportSubmit(i: CommentNode) { @@ -1217,24 +1226,22 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { }); WebSocketService.Instance.send(wsClient.createCommentReport(form)); - i.state.showReportDialog = false; - i.setState(i.state); + i.setState({ showReportDialog: false }); } handleModRemoveShow(i: CommentNode) { - i.state.showRemoveDialog = !i.state.showRemoveDialog; - i.state.showBanDialog = false; - i.setState(i.state); + i.setState({ + showRemoveDialog: !i.state.showRemoveDialog, + showBanDialog: false, + }); } handleModRemoveReasonChange(i: CommentNode, event: any) { - i.state.removeReason = Some(event.target.value); - i.setState(i.state); + i.setState({ removeReason: Some(event.target.value) }); } handleModRemoveDataChange(i: CommentNode, event: any) { - i.state.removeData = event.target.checked; - i.setState(i.state); + i.setState({ removeData: event.target.checked }); } handleModRemoveSubmit(i: CommentNode) { @@ -1247,8 +1254,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { }); WebSocketService.Instance.send(wsClient.removeComment(form)); - i.state.showRemoveDialog = false; - i.setState(i.state); + i.setState({ showRemoveDialog: false }); } handleDistinguishClick(i: CommentNode) { @@ -1293,43 +1299,40 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { WebSocketService.Instance.send(wsClient.markCommentReplyAsRead(form)); } - i.state.readLoading = true; - i.setState(this.state); + i.setState({ readLoading: true }); } handleModBanFromCommunityShow(i: CommentNode) { - i.state.showBanDialog = true; - i.state.banType = BanType.Community; - i.state.showRemoveDialog = false; - i.setState(i.state); + i.setState({ + showBanDialog: true, + banType: BanType.Community, + showRemoveDialog: false, + }); } handleModBanShow(i: CommentNode) { - i.state.showBanDialog = true; - i.state.banType = BanType.Site; - i.state.showRemoveDialog = false; - i.setState(i.state); + i.setState({ + showBanDialog: true, + banType: BanType.Site, + showRemoveDialog: false, + }); } handleModBanReasonChange(i: CommentNode, event: any) { - i.state.banReason = Some(event.target.value); - i.setState(i.state); + i.setState({ banReason: Some(event.target.value) }); } handleModBanExpireDaysChange(i: CommentNode, event: any) { - i.state.banExpireDays = Some(event.target.value); - i.setState(i.state); + i.setState({ banExpireDays: Some(event.target.value) }); } handleModBanFromCommunitySubmit(i: CommentNode) { - i.state.banType = BanType.Community; - i.setState(i.state); + i.setState({ banType: BanType.Community }); i.handleModBanBothSubmit(i); } handleModBanSubmit(i: CommentNode) { - i.state.banType = BanType.Site; - i.setState(i.state); + i.setState({ banType: BanType.Site }); i.handleModBanBothSubmit(i); } @@ -1340,7 +1343,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { // If its an unban, restore all their data let ban = !cv.creator_banned_from_community; if (ban == false) { - i.state.removeData = false; + i.setState({ removeData: false }); } let form = new BanFromCommunity({ person_id: cv.creator.id, @@ -1356,7 +1359,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { // If its an unban, restore all their data let ban = !cv.creator.banned; if (ban == false) { - i.state.removeData = false; + i.setState({ removeData: false }); } let form = new BanPerson({ person_id: cv.creator.id, @@ -1369,27 +1372,27 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { WebSocketService.Instance.send(wsClient.banPerson(form)); } - i.state.showBanDialog = false; - i.setState(i.state); + i.setState({ showBanDialog: false }); } handlePurgePersonShow(i: CommentNode) { - i.state.showPurgeDialog = true; - i.state.purgeType = PurgeType.Person; - i.state.showRemoveDialog = false; - i.setState(i.state); + i.setState({ + showPurgeDialog: true, + purgeType: PurgeType.Person, + showRemoveDialog: false, + }); } handlePurgeCommentShow(i: CommentNode) { - i.state.showPurgeDialog = true; - i.state.purgeType = PurgeType.Comment; - i.state.showRemoveDialog = false; - i.setState(i.state); + i.setState({ + showPurgeDialog: true, + purgeType: PurgeType.Comment, + showRemoveDialog: false, + }); } handlePurgeReasonChange(i: CommentNode, event: any) { - i.state.purgeReason = Some(event.target.value); - i.setState(i.state); + i.setState({ purgeReason: Some(event.target.value) }); } handlePurgeSubmit(i: CommentNode, event: any) { @@ -1411,18 +1414,15 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { WebSocketService.Instance.send(wsClient.purgeComment(form)); } - i.state.purgeLoading = true; - i.setState(i.state); + i.setState({ purgeLoading: true }); } handleShowConfirmAppointAsMod(i: CommentNode) { - i.state.showConfirmAppointAsMod = true; - i.setState(i.state); + i.setState({ showConfirmAppointAsMod: true }); } handleCancelConfirmAppointAsMod(i: CommentNode) { - i.state.showConfirmAppointAsMod = false; - i.setState(i.state); + i.setState({ showConfirmAppointAsMod: false }); } handleAddModToCommunity(i: CommentNode) { @@ -1434,18 +1434,15 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { auth: auth().unwrap(), }); WebSocketService.Instance.send(wsClient.addModToCommunity(form)); - i.state.showConfirmAppointAsMod = false; - i.setState(i.state); + i.setState({ showConfirmAppointAsMod: false }); } handleShowConfirmAppointAsAdmin(i: CommentNode) { - i.state.showConfirmAppointAsAdmin = true; - i.setState(i.state); + i.setState({ showConfirmAppointAsAdmin: true }); } handleCancelConfirmAppointAsAdmin(i: CommentNode) { - i.state.showConfirmAppointAsAdmin = false; - i.setState(i.state); + i.setState({ showConfirmAppointAsAdmin: false }); } handleAddAdmin(i: CommentNode) { @@ -1456,18 +1453,15 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { auth: auth().unwrap(), }); WebSocketService.Instance.send(wsClient.addAdmin(form)); - i.state.showConfirmAppointAsAdmin = false; - i.setState(i.state); + i.setState({ showConfirmAppointAsAdmin: false }); } handleShowConfirmTransferCommunity(i: CommentNode) { - i.state.showConfirmTransferCommunity = true; - i.setState(i.state); + i.setState({ showConfirmTransferCommunity: true }); } handleCancelShowConfirmTransferCommunity(i: CommentNode) { - i.state.showConfirmTransferCommunity = false; - i.setState(i.state); + i.setState({ showConfirmTransferCommunity: false }); } handleTransferCommunity(i: CommentNode) { @@ -1478,18 +1472,15 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { auth: auth().unwrap(), }); WebSocketService.Instance.send(wsClient.transferCommunity(form)); - i.state.showConfirmTransferCommunity = false; - i.setState(i.state); + i.setState({ showConfirmTransferCommunity: false }); } handleShowConfirmTransferSite(i: CommentNode) { - i.state.showConfirmTransferSite = true; - i.setState(i.state); + i.setState({ showConfirmTransferSite: true }); } handleCancelShowConfirmTransferSite(i: CommentNode) { - i.state.showConfirmTransferSite = false; - i.setState(i.state); + i.setState({ showConfirmTransferSite: false }); } get isCommentNew(): boolean { @@ -1499,19 +1490,16 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> { } handleCommentCollapse(i: CommentNode) { - i.state.collapsed = !i.state.collapsed; - i.setState(i.state); + i.setState({ collapsed: !i.state.collapsed }); setupTippy(); } handleViewSource(i: CommentNode) { - i.state.viewSource = !i.state.viewSource; - i.setState(i.state); + i.setState({ viewSource: !i.state.viewSource }); } handleShowAdvanced(i: CommentNode) { - i.state.showAdvanced = !i.state.showAdvanced; - i.setState(i.state); + i.setState({ showAdvanced: !i.state.showAdvanced }); setupTippy(); } diff --git a/src/shared/components/common/banner-icon-header.tsx b/src/shared/components/common/banner-icon-header.tsx index d3383b5f6..a72400a3d 100644 --- a/src/shared/components/common/banner-icon-header.tsx +++ b/src/shared/components/common/banner-icon-header.tsx @@ -14,7 +14,7 @@ export class BannerIconHeader extends Component<BannerIconHeaderProps, any> { render() { return ( - <div class="position-relative mb-2"> + <div className="position-relative mb-2"> {this.props.banner.match({ some: banner => <PictrsImage src={banner} banner alt="" />, none: <></>, diff --git a/src/shared/components/common/comment-sort-select.tsx b/src/shared/components/common/comment-sort-select.tsx index b87f26664..0e49d561e 100644 --- a/src/shared/components/common/comment-sort-select.tsx +++ b/src/shared/components/common/comment-sort-select.tsx @@ -41,7 +41,7 @@ export class CommentSortSelect extends Component< name={this.id} value={this.state.sort} onChange={linkEvent(this, this.handleSortChange)} - class="custom-select w-auto mr-2 mb-2" + className="custom-select w-auto mr-2 mb-2" aria-label={i18n.t("sort_type")} > <option disabled aria-hidden="true"> diff --git a/src/shared/components/common/data-type-select.tsx b/src/shared/components/common/data-type-select.tsx index b9b6a6f58..8a5613e85 100644 --- a/src/shared/components/common/data-type-select.tsx +++ b/src/shared/components/common/data-type-select.tsx @@ -32,7 +32,7 @@ export class DataTypeSelect extends Component< render() { return ( - <div class="btn-group btn-group-toggle flex-wrap mb-2"> + <div className="btn-group btn-group-toggle flex-wrap mb-2"> <label className={`pointer btn btn-outline-secondary ${this.state.type_ == DataType.Post && "active"} diff --git a/src/shared/components/common/html-tags.tsx b/src/shared/components/common/html-tags.tsx index 1997b4f8c..56cf3238e 100644 --- a/src/shared/components/common/html-tags.tsx +++ b/src/shared/components/common/html-tags.tsx @@ -19,10 +19,10 @@ export class HtmlTags extends Component<HtmlTagsProps, any> { return ( <Helmet title={this.props.title}> {["title", "og:title", "twitter:title"].map(t => ( - <meta property={t} content={this.props.title} /> + <meta key={t} property={t} content={this.props.title} /> ))} {["og:url", "twitter:url"].map(u => ( - <meta property={u} content={url} /> + <meta key={u} property={u} content={url} /> ))} {/* Open Graph / Facebook */} @@ -35,6 +35,7 @@ export class HtmlTags extends Component<HtmlTagsProps, any> { {this.props.description.isSome() && ["description", "og:description", "twitter:description"].map(n => ( <meta + key={n} name={n} content={md.renderInline(this.props.description.unwrap())} /> @@ -42,7 +43,7 @@ export class HtmlTags extends Component<HtmlTagsProps, any> { {this.props.image.isSome() && ["og:image", "twitter:image"].map(p => ( - <meta property={p} content={this.props.image.unwrap()} /> + <meta key={p} property={p} content={this.props.image.unwrap()} /> ))} </Helmet> ); diff --git a/src/shared/components/common/icon.tsx b/src/shared/components/common/icon.tsx index 91271cfe5..f922e175e 100644 --- a/src/shared/components/common/icon.tsx +++ b/src/shared/components/common/icon.tsx @@ -17,13 +17,13 @@ export class Icon extends Component<IconProps, any> { render() { return ( <svg - class={classNames("icon", this.props.classes, { + className={classNames("icon", this.props.classes, { "icon-inline": this.props.inline, small: this.props.small, })} > <use xlinkHref={`#icon-${this.props.icon}`}></use> - <div class="sr-only"> + <div className="sr-only"> <title>{this.props.icon}</title> </div> </svg> @@ -57,7 +57,7 @@ export class PurgeWarning extends Component<any, any> { render() { return ( - <div class="mt-2 alert alert-danger" role="alert"> + <div className="mt-2 alert alert-danger" role="alert"> <Icon icon="alert-triangle" classes="icon-inline mr-2" /> {i18n.t("purge_warning")} </div> diff --git a/src/shared/components/common/image-upload-form.tsx b/src/shared/components/common/image-upload-form.tsx index 5f7a8168f..432521efa 100644 --- a/src/shared/components/common/image-upload-form.tsx +++ b/src/shared/components/common/image-upload-form.tsx @@ -34,14 +34,14 @@ export class ImageUploadForm extends Component< render() { return ( - <form class="d-inline"> + <form className="d-inline"> <label htmlFor={this.id} - class="pointer text-muted small font-weight-bold" + className="pointer text-muted small font-weight-bold" > {this.props.imageSrc.match({ some: imageSrc => ( - <span class="d-inline-block position-relative"> + <span className="d-inline-block position-relative"> <img src={imageSrc} height={this.props.rounded ? 60 : ""} @@ -59,7 +59,9 @@ export class ImageUploadForm extends Component< </span> ), none: ( - <span class="btn btn-secondary">{this.props.uploadTitle}</span> + <span className="btn btn-secondary"> + {this.props.uploadTitle} + </span> ), })} </label> @@ -68,7 +70,7 @@ export class ImageUploadForm extends Component< type="file" accept="image/*,video/*" name={this.id} - class="d-none" + className="d-none" disabled={UserService.Instance.myUserInfo.isNone()} onChange={linkEvent(this, this.handleImageUpload)} /> @@ -82,8 +84,7 @@ export class ImageUploadForm extends Component< const formData = new FormData(); formData.append("images[]", file); - i.state.loading = true; - i.setState(i.state); + i.setState({ loading: true }); fetch(pictrsUri, { method: "POST", @@ -96,18 +97,15 @@ export class ImageUploadForm extends Component< if (res.msg == "ok") { let hash = res.files[0].file; let url = `${pictrsUri}/${hash}`; - i.state.loading = false; - i.setState(i.state); + i.setState({ loading: false }); i.props.onUpload(url); } else { - i.state.loading = false; - i.setState(i.state); + i.setState({ loading: false }); toast(JSON.stringify(res), "danger"); } }) .catch(error => { - i.state.loading = false; - i.setState(i.state); + i.setState({ loading: false }); console.error(error); toast(error, "danger"); }); @@ -115,8 +113,7 @@ export class ImageUploadForm extends Component< handleRemoveImage(i: ImageUploadForm, event: any) { event.preventDefault(); - i.state.loading = true; - i.setState(i.state); + i.setState({ loading: true }); i.props.onRemove(); } } diff --git a/src/shared/components/common/listing-type-select.tsx b/src/shared/components/common/listing-type-select.tsx index 0ddd0e9ab..38e6acddc 100644 --- a/src/shared/components/common/listing-type-select.tsx +++ b/src/shared/components/common/listing-type-select.tsx @@ -40,7 +40,7 @@ export class ListingTypeSelect extends Component< render() { return ( - <div class="btn-group btn-group-toggle flex-wrap mb-2"> + <div className="btn-group btn-group-toggle flex-wrap mb-2"> {this.props.showSubscribed && ( <label title={i18n.t("subscribed_description")} diff --git a/src/shared/components/common/markdown-textarea.tsx b/src/shared/components/common/markdown-textarea.tsx index e369f8fbb..b3374847f 100644 --- a/src/shared/components/common/markdown-textarea.tsx +++ b/src/shared/components/common/markdown-textarea.tsx @@ -70,8 +70,7 @@ export class MarkdownTextArea extends Component< autosize(textarea); this.tribute.attach(textarea); textarea.addEventListener("tribute-replaced", () => { - this.state.content = Some(textarea.value); - this.setState(this.state); + this.setState({ content: Some(textarea.value) }); autosize.update(textarea); }); @@ -96,10 +95,7 @@ export class MarkdownTextArea extends Component< componentWillReceiveProps(nextProps: MarkdownTextAreaProps) { if (nextProps.finished) { - this.state.previewMode = false; - this.state.loading = false; - this.state.content = None; - this.setState(this.state); + this.setState({ previewMode: false, loading: false, content: None }); if (this.props.replyType) { this.props.onReplyCancel(); } @@ -108,7 +104,6 @@ export class MarkdownTextArea extends Component< let form: any = document.getElementById(this.formId); form.reset(); setTimeout(() => autosize.update(textarea), 10); - this.setState(this.state); } } @@ -125,7 +120,7 @@ export class MarkdownTextArea extends Component< } message={i18n.t("block_leaving")} /> - <div class="form-group row"> + <div className="form-group row"> <div className={`col-sm-12`}> <textarea id={this.id} @@ -150,17 +145,17 @@ export class MarkdownTextArea extends Component< none: <></>, })} </div> - <label class="sr-only" htmlFor={this.id}> + <label className="sr-only" htmlFor={this.id}> {i18n.t("body")} </label> </div> - <div class="row"> - <div class="col-sm-12 d-flex flex-wrap"> + <div className="row"> + <div className="col-sm-12 d-flex flex-wrap"> {this.props.buttonTitle.match({ some: buttonTitle => ( <button type="submit" - class="btn btn-sm btn-secondary mr-2" + className="btn btn-sm btn-secondary mr-2" disabled={this.props.disabled || this.state.loading} > {this.state.loading ? ( @@ -175,7 +170,7 @@ export class MarkdownTextArea extends Component< {this.props.replyType && ( <button type="button" - class="btn btn-sm btn-secondary mr-2" + className="btn btn-sm btn-secondary mr-2" onClick={linkEvent(this, this.handleReplyCancel)} > {i18n.t("cancel")} @@ -192,9 +187,9 @@ export class MarkdownTextArea extends Component< </button> )} {/* A flex expander */} - <div class="flex-grow-1"></div> + <div className="flex-grow-1"></div> <button - class="btn btn-sm text-muted" + className="btn btn-sm text-muted" data-tippy-content={i18n.t("bold")} aria-label={i18n.t("bold")} onClick={linkEvent(this, this.handleInsertBold)} @@ -202,7 +197,7 @@ export class MarkdownTextArea extends Component< <Icon icon="bold" classes="icon-inline" /> </button> <button - class="btn btn-sm text-muted" + className="btn btn-sm text-muted" data-tippy-content={i18n.t("italic")} aria-label={i18n.t("italic")} onClick={linkEvent(this, this.handleInsertItalic)} @@ -210,14 +205,14 @@ export class MarkdownTextArea extends Component< <Icon icon="italic" classes="icon-inline" /> </button> <button - class="btn btn-sm text-muted" + className="btn btn-sm text-muted" data-tippy-content={i18n.t("link")} aria-label={i18n.t("link")} onClick={linkEvent(this, this.handleInsertLink)} > <Icon icon="link" classes="icon-inline" /> </button> - <form class="btn btn-sm text-muted font-weight-bold"> + <form className="btn btn-sm text-muted font-weight-bold"> <label htmlFor={`file-upload-${this.id}`} className={`mb-0 ${ @@ -236,13 +231,13 @@ export class MarkdownTextArea extends Component< type="file" accept="image/*,video/*" name="file" - class="d-none" + className="d-none" disabled={UserService.Instance.myUserInfo.isNone()} onChange={linkEvent(this, this.handleImageUpload)} /> </form> <button - class="btn btn-sm text-muted" + className="btn btn-sm text-muted" data-tippy-content={i18n.t("header")} aria-label={i18n.t("header")} onClick={linkEvent(this, this.handleInsertHeader)} @@ -250,7 +245,7 @@ export class MarkdownTextArea extends Component< <Icon icon="header" classes="icon-inline" /> </button> <button - class="btn btn-sm text-muted" + className="btn btn-sm text-muted" data-tippy-content={i18n.t("strikethrough")} aria-label={i18n.t("strikethrough")} onClick={linkEvent(this, this.handleInsertStrikethrough)} @@ -258,7 +253,7 @@ export class MarkdownTextArea extends Component< <Icon icon="strikethrough" classes="icon-inline" /> </button> <button - class="btn btn-sm text-muted" + className="btn btn-sm text-muted" data-tippy-content={i18n.t("quote")} aria-label={i18n.t("quote")} onClick={linkEvent(this, this.handleInsertQuote)} @@ -266,7 +261,7 @@ export class MarkdownTextArea extends Component< <Icon icon="format_quote" classes="icon-inline" /> </button> <button - class="btn btn-sm text-muted" + className="btn btn-sm text-muted" data-tippy-content={i18n.t("list")} aria-label={i18n.t("list")} onClick={linkEvent(this, this.handleInsertList)} @@ -274,7 +269,7 @@ export class MarkdownTextArea extends Component< <Icon icon="list" classes="icon-inline" /> </button> <button - class="btn btn-sm text-muted" + className="btn btn-sm text-muted" data-tippy-content={i18n.t("code")} aria-label={i18n.t("code")} onClick={linkEvent(this, this.handleInsertCode)} @@ -282,7 +277,7 @@ export class MarkdownTextArea extends Component< <Icon icon="code" classes="icon-inline" /> </button> <button - class="btn btn-sm text-muted" + className="btn btn-sm text-muted" data-tippy-content={i18n.t("subscript")} aria-label={i18n.t("subscript")} onClick={linkEvent(this, this.handleInsertSubscript)} @@ -290,7 +285,7 @@ export class MarkdownTextArea extends Component< <Icon icon="subscript" classes="icon-inline" /> </button> <button - class="btn btn-sm text-muted" + className="btn btn-sm text-muted" data-tippy-content={i18n.t("superscript")} aria-label={i18n.t("superscript")} onClick={linkEvent(this, this.handleInsertSuperscript)} @@ -298,7 +293,7 @@ export class MarkdownTextArea extends Component< <Icon icon="superscript" classes="icon-inline" /> </button> <button - class="btn btn-sm text-muted" + className="btn btn-sm text-muted" data-tippy-content={i18n.t("spoiler")} aria-label={i18n.t("spoiler")} onClick={linkEvent(this, this.handleInsertSpoiler)} @@ -307,7 +302,7 @@ export class MarkdownTextArea extends Component< </button> <a href={markdownHelpUrl} - class="btn btn-sm text-muted font-weight-bold" + className="btn btn-sm text-muted font-weight-bold" title={i18n.t("formatting_help")} rel={relTags} > @@ -338,8 +333,7 @@ export class MarkdownTextArea extends Component< const formData = new FormData(); formData.append("images[]", file); - i.state.imageLoading = true; - i.setState(i.state); + i.setState({ imageLoading: true }); fetch(pictrsUri, { method: "POST", @@ -355,15 +349,16 @@ export class MarkdownTextArea extends Component< let deleteToken = res.files[0].delete_token; let deleteUrl = `${pictrsUri}/delete/${deleteToken}/${hash}`; let imageMarkdown = `![](${url})`; - i.state.content = Some( - i.state.content.match({ - some: content => `${content}\n${imageMarkdown}`, - none: imageMarkdown, - }) - ); - i.state.imageLoading = false; + i.setState({ + content: Some( + i.state.content.match({ + some: content => `${content}\n${imageMarkdown}`, + none: imageMarkdown, + }) + ), + imageLoading: false, + }); i.contentChange(); - i.setState(i.state); let textarea: any = document.getElementById(i.id); autosize.update(textarea); pictrsDeleteToast( @@ -372,14 +367,12 @@ export class MarkdownTextArea extends Component< deleteUrl ); } else { - i.state.imageLoading = false; - i.setState(i.state); + i.setState({ imageLoading: false }); toast(JSON.stringify(res), "danger"); } }) .catch(error => { - i.state.imageLoading = false; - i.setState(i.state); + i.setState({ imageLoading: false }); console.error(error); toast(error, "danger"); }); @@ -392,21 +385,18 @@ export class MarkdownTextArea extends Component< } handleContentChange(i: MarkdownTextArea, event: any) { - i.state.content = Some(event.target.value); + i.setState({ content: Some(event.target.value) }); i.contentChange(); - i.setState(i.state); } handlePreviewToggle(i: MarkdownTextArea, event: any) { event.preventDefault(); - i.state.previewMode = !i.state.previewMode; - i.setState(i.state); + i.setState({ previewMode: !i.state.previewMode }); } handleSubmit(i: MarkdownTextArea, event: any) { event.preventDefault(); - i.state.loading = true; - i.setState(i.state); + i.setState({ loading: true }); let msg = { val: toUndefined(i.state.content), formId: i.formId }; i.props.onSubmit(msg); } @@ -423,27 +413,28 @@ export class MarkdownTextArea extends Component< let end: number = textarea.selectionEnd; if (i.state.content.isNone()) { - i.state.content = Some(""); + i.setState({ content: Some("") }); } let content = i.state.content.unwrap(); if (start !== end) { let selectedText = content.substring(start, end); - i.state.content = Some( - `${content.substring(0, start)}[${selectedText}]()${content.substring( - end - )}` - ); + i.setState({ + content: Some( + `${content.substring(0, start)}[${selectedText}]()${content.substring( + end + )}` + ), + }); textarea.focus(); setTimeout(() => (textarea.selectionEnd = end + 3), 10); } else { - i.state.content = Some(`${content} []()`); + i.setState({ content: Some(`${content} []()`) }); textarea.focus(); setTimeout(() => (textarea.selectionEnd -= 1), 10); } i.contentChange(); - i.setState(i.state); } simpleSurround(chars: string) { @@ -460,7 +451,7 @@ export class MarkdownTextArea extends Component< emptyChars = "___" ) { if (this.state.content.isNone()) { - this.state.content = Some(""); + this.setState({ content: Some("") }); } let textarea: any = document.getElementById(this.id); let start: number = textarea.selectionStart; @@ -470,19 +461,20 @@ export class MarkdownTextArea extends Component< if (start !== end) { let selectedText = content.substring(start, end); - this.state.content = Some( - `${content.substring( - 0, - start - )}${beforeChars}${selectedText}${afterChars}${content.substring(end)}` - ); + this.setState({ + content: Some( + `${content.substring( + 0, + start + )}${beforeChars}${selectedText}${afterChars}${content.substring(end)}` + ), + }); } else { - this.state.content = Some( - `${content}${beforeChars}${emptyChars}${afterChars}` - ); + this.setState({ + content: Some(`${content}${beforeChars}${emptyChars}${afterChars}`), + }); } this.contentChange(); - this.setState(this.state); textarea.focus(); @@ -554,9 +546,11 @@ export class MarkdownTextArea extends Component< simpleInsert(chars: string) { if (this.state.content.isNone()) { - this.state.content = Some(`${chars} `); + this.setState({ content: Some(`${chars} `) }); } else { - this.state.content = Some(`${this.state.content.unwrap()}\n${chars} `); + this.setState({ + content: Some(`${this.state.content.unwrap()}\n${chars} `), + }); } let textarea: any = document.getElementById(this.id); @@ -565,7 +559,6 @@ export class MarkdownTextArea extends Component< autosize.update(textarea); }, 10); this.contentChange(); - this.setState(this.state); } handleInsertSpoiler(i: MarkdownTextArea, event: any) { @@ -585,13 +578,14 @@ export class MarkdownTextArea extends Component< .map(t => `> ${t}`) .join("\n") + "\n\n"; if (this.state.content.isNone()) { - this.state.content = Some(""); + this.setState({ content: Some("") }); } else { - this.state.content = Some(`${this.state.content.unwrap()}\n`); + this.setState({ content: Some(`${this.state.content.unwrap()}\n`) }); } - this.state.content = Some(`${this.state.content.unwrap()}${quotedText}`); + this.setState({ + content: Some(`${this.state.content.unwrap()}${quotedText}`), + }); this.contentChange(); - this.setState(this.state); // Not sure why this needs a delay setTimeout(() => autosize.update(textarea), 10); } diff --git a/src/shared/components/common/paginator.tsx b/src/shared/components/common/paginator.tsx index 50094de48..75acde3e1 100644 --- a/src/shared/components/common/paginator.tsx +++ b/src/shared/components/common/paginator.tsx @@ -12,16 +12,16 @@ export class Paginator extends Component<PaginatorProps, any> { } render() { return ( - <div class="my-2"> + <div className="my-2"> <button - class="btn btn-secondary mr-2" + className="btn btn-secondary mr-2" disabled={this.props.page == 1} onClick={linkEvent(this, this.handlePrev)} > {i18n.t("prev")} </button> <button - class="btn btn-secondary" + className="btn btn-secondary" onClick={linkEvent(this, this.handleNext)} > {i18n.t("next")} diff --git a/src/shared/components/common/registration-application.tsx b/src/shared/components/common/registration-application.tsx index f3c2cf523..cac317eef 100644 --- a/src/shared/components/common/registration-application.tsx +++ b/src/shared/components/common/registration-application.tsx @@ -88,11 +88,11 @@ export class RegistrationApplication extends Component< })} {this.state.denyExpanded && ( - <div class="form-group row"> - <label class="col-sm-2 col-form-label"> + <div className="form-group row"> + <label className="col-sm-2 col-form-label"> {i18n.t("deny_reason")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <MarkdownTextArea initialContent={this.state.denyReason} onContentChange={this.handleDenyReasonChange} @@ -157,7 +157,6 @@ export class RegistrationApplication extends Component< } handleDenyReasonChange(val: string) { - this.state.denyReason = Some(val); - this.setState(this.state); + this.setState({ denyReason: Some(val) }); } } diff --git a/src/shared/components/common/sort-select.tsx b/src/shared/components/common/sort-select.tsx index 3f815f5b0..facc16f47 100644 --- a/src/shared/components/common/sort-select.tsx +++ b/src/shared/components/common/sort-select.tsx @@ -40,23 +40,27 @@ export class SortSelect extends Component<SortSelectProps, SortSelectState> { name={this.id} value={this.state.sort} onChange={linkEvent(this, this.handleSortChange)} - class="custom-select w-auto mr-2 mb-2" + className="custom-select w-auto mr-2 mb-2" aria-label={i18n.t("sort_type")} > <option disabled aria-hidden="true"> {i18n.t("sort_type")} </option> {!this.props.hideHot && [ - <option value={SortType.Hot}>{i18n.t("hot")}</option>, - <option value={SortType.Active}>{i18n.t("active")}</option>, + <option key={SortType.Hot} value={SortType.Hot}> + {i18n.t("hot")} + </option>, + <option key={SortType.Active} value={SortType.Active}> + {i18n.t("active")} + </option>, ]} <option value={SortType.New}>{i18n.t("new")}</option> <option value={SortType.Old}>{i18n.t("old")}</option> {!this.props.hideMostComments && [ - <option value={SortType.MostComments}> + <option key={SortType.MostComments} value={SortType.MostComments}> {i18n.t("most_comments")} </option>, - <option value={SortType.NewComments}> + <option key={SortType.NewComments} value={SortType.NewComments}> {i18n.t("new_comments")} </option>, ]} diff --git a/src/shared/components/common/symbols.tsx b/src/shared/components/common/symbols.tsx index 03791d1be..cb066cc2e 100644 --- a/src/shared/components/common/symbols.tsx +++ b/src/shared/components/common/symbols.tsx @@ -17,7 +17,7 @@ export const SYMBOLS = ( viewBox="0 0 196.52 196.52" xmlns="http://www.w3.org/2000/svg" > - <g color="#000" font-weight="400" font-family="sans-serif"> + <g color="#000" fontWeight="400" fontFamily="sans-serif"> <path d="M47.924 72.797a18.228 18.228 0 0 1-7.796 7.76l42.799 42.965 10.318-5.23zm56.453 56.67l-10.319 5.23 21.686 21.77a18.228 18.228 0 0 1 7.798-7.76z" overflow="visible" @@ -69,7 +69,7 @@ export const SYMBOLS = ( fill="#dbb210" /> </g> - <g transform="rotate(3.118 600.365 106.46)" fill-opacity=".996"> + <g transform="rotate(3.118 600.365 106.46)" fillOpacity=".996"> <circle cx="106.266" cy="51.536" r="16.571" fill="#ffca00" /> <circle cx="171.428" cy="110.193" r="16.571" fill="#64ff00" /> <circle cx="135.764" cy="190.277" r="16.571" fill="#00a3ff" /> diff --git a/src/shared/components/community/communities.tsx b/src/shared/components/community/communities.tsx index db17084a3..95e593efb 100644 --- a/src/shared/components/community/communities.tsx +++ b/src/shared/components/community/communities.tsx @@ -75,8 +75,11 @@ export class Communities extends Component<any, CommunitiesState> { // Only fetch the data if coming from another route if (this.isoData.path == this.context.router.route.match.url) { let listRes = Some(this.isoData.routeData[0] as ListCommunitiesResponse); - this.state.listCommunitiesResponse = listRes; - this.state.loading = false; + this.state = { + ...this.state, + listCommunitiesResponse: listRes, + loading: false, + }; } else { this.refetch(); } @@ -114,7 +117,7 @@ export class Communities extends Component<any, CommunitiesState> { render() { return ( - <div class="container"> + <div className="container"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} @@ -127,10 +130,10 @@ export class Communities extends Component<any, CommunitiesState> { </h5> ) : ( <div> - <div class="row"> - <div class="col-md-6"> + <div className="row"> + <div className="col-md-6"> <h4>{i18n.t("list_of_communities")}</h4> - <span class="mb-2"> + <span className="mb-2"> <ListingTypeSelect type_={this.state.listingType} showLocal={showLocal(this.isoData)} @@ -139,24 +142,27 @@ export class Communities extends Component<any, CommunitiesState> { /> </span> </div> - <div class="col-md-6"> - <div class="float-md-right">{this.searchForm()}</div> + <div className="col-md-6"> + <div className="float-md-right">{this.searchForm()}</div> </div> </div> - <div class="table-responsive"> - <table id="community_table" class="table table-sm table-hover"> - <thead class="pointer"> + <div className="table-responsive"> + <table + id="community_table" + className="table table-sm table-hover" + > + <thead className="pointer"> <tr> <th>{i18n.t("name")}</th> - <th class="text-right">{i18n.t("subscribers")}</th> - <th class="text-right"> + <th className="text-right">{i18n.t("subscribers")}</th> + <th className="text-right"> {i18n.t("users")} / {i18n.t("month")} </th> - <th class="text-right d-none d-lg-table-cell"> + <th className="text-right d-none d-lg-table-cell"> {i18n.t("posts")} </th> - <th class="text-right d-none d-lg-table-cell"> + <th className="text-right d-none d-lg-table-cell"> {i18n.t("comments")} </th> <th></th> @@ -167,26 +173,26 @@ export class Communities extends Component<any, CommunitiesState> { .map(l => l.communities) .unwrapOr([]) .map(cv => ( - <tr> + <tr key={cv.community.id}> <td> <CommunityLink community={cv.community} /> </td> - <td class="text-right"> + <td className="text-right"> {numToSI(cv.counts.subscribers)} </td> - <td class="text-right"> + <td className="text-right"> {numToSI(cv.counts.users_active_month)} </td> - <td class="text-right d-none d-lg-table-cell"> + <td className="text-right d-none d-lg-table-cell"> {numToSI(cv.counts.posts)} </td> - <td class="text-right d-none d-lg-table-cell"> + <td className="text-right d-none d-lg-table-cell"> {numToSI(cv.counts.comments)} </td> - <td class="text-right"> + <td className="text-right"> {cv.subscribed == SubscribedType.Subscribed && ( <button - class="btn btn-link d-inline-block" + className="btn btn-link d-inline-block" onClick={linkEvent( cv.community.id, this.handleUnsubscribe @@ -197,7 +203,7 @@ export class Communities extends Component<any, CommunitiesState> { )} {cv.subscribed == SubscribedType.NotSubscribed && ( <button - class="btn btn-link d-inline-block" + className="btn btn-link d-inline-block" onClick={linkEvent( cv.community.id, this.handleSubscribe @@ -207,7 +213,7 @@ export class Communities extends Component<any, CommunitiesState> { </button> )} {cv.subscribed == SubscribedType.Pending && ( - <div class="text-warning d-inline-block"> + <div className="text-warning d-inline-block"> {i18n.t("subscribe_pending")} </div> )} @@ -230,23 +236,23 @@ export class Communities extends Component<any, CommunitiesState> { searchForm() { return ( <form - class="form-inline" + className="form-inline" onSubmit={linkEvent(this, this.handleSearchSubmit)} > <input type="text" id="communities-search" - class="form-control mr-2 mb-2" + className="form-control mr-2 mb-2" value={this.state.searchText} placeholder={`${i18n.t("search")}...`} onInput={linkEvent(this, this.handleSearchChange)} required minLength={3} /> - <label class="sr-only" htmlFor="communities-search"> + <label className="sr-only" htmlFor="communities-search"> {i18n.t("search")} </label> - <button type="submit" class="btn btn-secondary mr-2 mb-2"> + <button type="submit" className="btn btn-secondary mr-2 mb-2"> <span>{i18n.t("search")}</span> </button> </form> @@ -343,10 +349,8 @@ export class Communities extends Component<any, CommunitiesState> { msg, ListCommunitiesResponse ); - this.state.listCommunitiesResponse = Some(data); - this.state.loading = false; + this.setState({ listCommunitiesResponse: Some(data), loading: false }); window.scrollTo(0, 0); - this.setState(this.state); } else if (op == UserOperation.FollowCommunity) { let data = wsJsonToRes<CommunityResponse>(msg, CommunityResponse); this.state.listCommunitiesResponse.match({ diff --git a/src/shared/components/community/community-form.tsx b/src/shared/components/community/community-form.tsx index cce144bf0..8f70f36f0 100644 --- a/src/shared/components/community/community-form.tsx +++ b/src/shared/components/community/community-form.tsx @@ -73,9 +73,14 @@ export class CommunityForm extends Component< this.handleBannerUpload = this.handleBannerUpload.bind(this); this.handleBannerRemove = this.handleBannerRemove.bind(this); - this.props.community_view.match({ - some: cv => { - this.state.communityForm = new CreateCommunity({ + this.parseMessage = this.parseMessage.bind(this); + this.subscription = wsSubscribe(this.parseMessage); + + if (this.props.community_view.isSome()) { + let cv = this.props.community_view.unwrap(); + this.state = { + ...this.state, + communityForm: new CreateCommunity({ name: cv.community.name, title: cv.community.title, description: cv.community.description, @@ -86,13 +91,9 @@ export class CommunityForm extends Component< cv.community.posting_restricted_to_mods ), auth: undefined, - }); - }, - none: void 0, - }); - - this.parseMessage = this.parseMessage.bind(this); - this.subscription = wsSubscribe(this.parseMessage); + }), + }; + } } componentDidUpdate() { @@ -127,24 +128,24 @@ export class CommunityForm extends Component< /> <form onSubmit={linkEvent(this, this.handleCreateCommunitySubmit)}> {this.props.community_view.isNone() && ( - <div class="form-group row"> + <div className="form-group row"> <label - class="col-12 col-sm-2 col-form-label" + className="col-12 col-sm-2 col-form-label" htmlFor="community-name" > {i18n.t("name")} <span - class="position-absolute pointer unselectable ml-2 text-muted" + className="position-absolute pointer unselectable ml-2 text-muted" data-tippy-content={i18n.t("name_explain")} > <Icon icon="help-circle" classes="icon-inline" /> </span> </label> - <div class="col-12 col-sm-10"> + <div className="col-12 col-sm-10"> <input type="text" id="community-name" - class="form-control" + className="form-control" value={this.state.communityForm.name} onInput={linkEvent(this, this.handleCommunityNameChange)} required @@ -155,35 +156,35 @@ export class CommunityForm extends Component< </div> </div> )} - <div class="form-group row"> + <div className="form-group row"> <label - class="col-12 col-sm-2 col-form-label" + className="col-12 col-sm-2 col-form-label" htmlFor="community-title" > {i18n.t("display_name")} <span - class="position-absolute pointer unselectable ml-2 text-muted" + className="position-absolute pointer unselectable ml-2 text-muted" data-tippy-content={i18n.t("display_name_explain")} > <Icon icon="help-circle" classes="icon-inline" /> </span> </label> - <div class="col-12 col-sm-10"> + <div className="col-12 col-sm-10"> <input type="text" id="community-title" value={this.state.communityForm.title} onInput={linkEvent(this, this.handleCommunityTitleChange)} - class="form-control" + className="form-control" required minLength={3} maxLength={100} /> </div> </div> - <div class="form-group row"> - <label class="col-12 col-sm-2">{i18n.t("icon")}</label> - <div class="col-12 col-sm-10"> + <div className="form-group row"> + <label className="col-12 col-sm-2">{i18n.t("icon")}</label> + <div className="col-12 col-sm-10"> <ImageUploadForm uploadTitle={i18n.t("upload_icon")} imageSrc={this.state.communityForm.icon} @@ -193,9 +194,9 @@ export class CommunityForm extends Component< /> </div> </div> - <div class="form-group row"> - <label class="col-12 col-sm-2">{i18n.t("banner")}</label> - <div class="col-12 col-sm-10"> + <div className="form-group row"> + <label className="col-12 col-sm-2">{i18n.t("banner")}</label> + <div className="col-12 col-sm-10"> <ImageUploadForm uploadTitle={i18n.t("upload_banner")} imageSrc={this.state.communityForm.banner} @@ -204,11 +205,11 @@ export class CommunityForm extends Component< /> </div> </div> - <div class="form-group row"> - <label class="col-12 col-sm-2 col-form-label" htmlFor={this.id}> + <div className="form-group row"> + <label className="col-12 col-sm-2 col-form-label" htmlFor={this.id}> {i18n.t("sidebar")} </label> - <div class="col-12 col-sm-10"> + <div className="col-12 col-sm-10"> <MarkdownTextArea initialContent={this.state.communityForm.description} placeholder={Some("description")} @@ -220,14 +221,14 @@ export class CommunityForm extends Component< </div> {this.props.enableNsfw && ( - <div class="form-group row"> - <legend class="col-form-label col-sm-2 pt-0"> + <div className="form-group row"> + <legend className="col-form-label col-sm-2 pt-0"> {i18n.t("nsfw")} </legend> - <div class="col-10"> - <div class="form-check"> + <div className="col-10"> + <div className="form-check"> <input - class="form-check-input position-static" + className="form-check-input position-static" id="community-nsfw" type="checkbox" checked={toUndefined(this.state.communityForm.nsfw)} @@ -237,14 +238,14 @@ export class CommunityForm extends Component< </div> </div> )} - <div class="form-group row"> - <legend class="col-form-label col-6 pt-0"> + <div className="form-group row"> + <legend className="col-form-label col-6 pt-0"> {i18n.t("only_mods_can_post_in_community")} </legend> - <div class="col-6"> - <div class="form-check"> + <div className="col-6"> + <div className="form-check"> <input - class="form-check-input position-static" + className="form-check-input position-static" id="community-only-mods-can-post" type="checkbox" checked={toUndefined( @@ -258,11 +259,11 @@ export class CommunityForm extends Component< </div> </div> </div> - <div class="form-group row"> - <div class="col-12"> + <div className="form-group row"> + <div className="col-12"> <button type="submit" - class="btn btn-secondary mr-2" + className="btn btn-secondary mr-2" disabled={this.state.loading} > {this.state.loading ? ( @@ -276,7 +277,7 @@ export class CommunityForm extends Component< {this.props.community_view.isSome() && ( <button type="button" - class="btn btn-secondary" + className="btn btn-secondary" onClick={linkEvent(this, this.handleCancel)} > {i18n.t("cancel")} @@ -291,7 +292,7 @@ export class CommunityForm extends Component< handleCreateCommunitySubmit(i: CommunityForm, event: any) { event.preventDefault(); - i.state.loading = true; + i.setState({ loading: true }); let cForm = i.state.communityForm; cForm.auth = auth().unwrap(); @@ -330,17 +331,18 @@ export class CommunityForm extends Component< } handleCommunityDescriptionChange(val: string) { - this.state.communityForm.description = Some(val); - this.setState(this.state); + this.setState(s => ((s.communityForm.description = Some(val)), s)); } handleCommunityNsfwChange(i: CommunityForm, event: any) { - i.state.communityForm.nsfw = event.target.checked; + i.state.communityForm.nsfw = Some(event.target.checked); i.setState(i.state); } handleCommunityPostingRestrictedToMods(i: CommunityForm, event: any) { - i.state.communityForm.posting_restricted_to_mods = event.target.checked; + i.state.communityForm.posting_restricted_to_mods = Some( + event.target.checked + ); i.setState(i.state); } @@ -349,23 +351,19 @@ export class CommunityForm extends Component< } handleIconUpload(url: string) { - this.state.communityForm.icon = Some(url); - this.setState(this.state); + this.setState(s => ((s.communityForm.icon = Some(url)), s)); } handleIconRemove() { - this.state.communityForm.icon = Some(""); - this.setState(this.state); + this.setState(s => ((s.communityForm.icon = Some("")), s)); } handleBannerUpload(url: string) { - this.state.communityForm.banner = Some(url); - this.setState(this.state); + this.setState(s => ((s.communityForm.banner = Some(url)), s)); } handleBannerRemove() { - this.state.communityForm.banner = Some(""); - this.setState(this.state); + this.setState(s => ((s.communityForm.banner = Some("")), s)); } parseMessage(msg: any) { @@ -374,12 +372,10 @@ export class CommunityForm extends Component< if (msg.error) { // Errors handled by top level pages // toast(i18n.t(msg.error), "danger"); - this.state.loading = false; - this.setState(this.state); + this.setState({ loading: false }); return; } else if (op == UserOperation.CreateCommunity) { let data = wsJsonToRes<CommunityResponse>(msg, CommunityResponse); - this.state.loading = false; this.props.onCreate(data.community_view); // Update myUserInfo @@ -401,7 +397,7 @@ export class CommunityForm extends Component< }); } else if (op == UserOperation.EditCommunity) { let data = wsJsonToRes<CommunityResponse>(msg, CommunityResponse); - this.state.loading = false; + this.setState({ loading: false }); this.props.onEdit(data.community_view); let community = data.community_view.community; diff --git a/src/shared/components/community/community-link.tsx b/src/shared/components/community/community-link.tsx index cc9870532..b051ed8aa 100644 --- a/src/shared/components/community/community-link.tsx +++ b/src/shared/components/community/community-link.tsx @@ -64,7 +64,7 @@ export class CommunityLink extends Component<CommunityLinkProps, any> { some: icon => <PictrsImage src={icon} icon />, none: <></>, })} - <span class="overflow-wrap-anywhere">{displayName}</span> + <span className="overflow-wrap-anywhere">{displayName}</span> </> ); } diff --git a/src/shared/components/community/community.tsx b/src/shared/components/community/community.tsx index 4e8d949c4..5c3746e1b 100644 --- a/src/shared/components/community/community.tsx +++ b/src/shared/components/community/community.tsx @@ -139,24 +139,27 @@ export class Community extends Component<any, State> { // Only fetch the data if coming from another route if (this.isoData.path == this.context.router.route.match.url) { - this.state.communityRes = Some( - this.isoData.routeData[0] as GetCommunityResponse - ); + this.state = { + ...this.state, + communityRes: Some(this.isoData.routeData[0] as GetCommunityResponse), + }; let postsRes = Some(this.isoData.routeData[1] as GetPostsResponse); let commentsRes = Some(this.isoData.routeData[2] as GetCommentsResponse); - postsRes.match({ - some: pvs => (this.state.posts = pvs.posts), - none: void 0, - }); - commentsRes.match({ - some: cvs => (this.state.comments = cvs.comments), - none: void 0, - }); + if (postsRes.isSome()) { + this.state = { ...this.state, posts: postsRes.unwrap().posts }; + } - this.state.communityLoading = false; - this.state.postsLoading = false; - this.state.commentsLoading = false; + if (commentsRes.isSome()) { + this.state = { ...this.state, comments: commentsRes.unwrap().comments }; + } + + this.state = { + ...this.state, + communityLoading: false, + postsLoading: false, + commentsLoading: false, + }; } else { this.fetchCommunity(); this.fetchData(); @@ -278,7 +281,7 @@ export class Community extends Component<any, State> { render() { return ( - <div class="container"> + <div className="container"> {this.state.communityLoading ? ( <h5> <Spinner large /> @@ -294,12 +297,12 @@ export class Community extends Component<any, State> { image={res.community_view.community.icon} /> - <div class="row"> - <div class="col-12 col-md-8"> + <div className="row"> + <div className="col-12 col-md-8"> {this.communityInfo()} - <div class="d-block d-md-none"> + <div className="d-block d-md-none"> <button - class="btn btn-secondary d-inline-block mb-2 mr-3" + className="btn btn-secondary d-inline-block mb-2 mr-3" onClick={linkEvent(this, this.handleShowSidebarMobile)} > {i18n.t("sidebar")}{" "} @@ -344,7 +347,7 @@ export class Community extends Component<any, State> { onChange={this.handlePageChange} /> </div> - <div class="d-none d-md-block col-md-4"> + <div className="d-none d-md-block col-md-4"> <Sidebar community_view={res.community_view} moderators={res.moderators} @@ -413,9 +416,9 @@ export class Community extends Component<any, State> { .map(r => r.community_view.community) .match({ some: community => ( - <div class="mb-2"> + <div className="mb-2"> <BannerIconHeader banner={community.banner} icon={community.icon} /> - <h5 class="mb-0 overflow-wrap-anywhere">{community.title}</h5> + <h5 className="mb-0 overflow-wrap-anywhere">{community.title}</h5> <CommunityLink community={community} realLink @@ -434,14 +437,14 @@ export class Community extends Component<any, State> { communityRSSUrl(r.community_view.community.actor_id, this.state.sort) ); return ( - <div class="mb-3"> - <span class="mr-3"> + <div className="mb-3"> + <span className="mr-3"> <DataTypeSelect type_={this.state.dataType} onChange={this.handleDataTypeChange} /> </span> - <span class="mr-2"> + <span className="mr-2"> <SortSelect sort={this.state.sort} onChange={this.handleSortChange} /> </span> {communityRss.match({ @@ -475,8 +478,7 @@ export class Community extends Component<any, State> { } handleShowSidebarMobile(i: Community) { - i.state.showSidebarMobile = !i.state.showSidebarMobile; - i.setState(i.state); + i.setState({ showSidebarMobile: !i.state.showSidebarMobile }); } updateUrl(paramUpdates: UrlParams) { @@ -543,9 +545,7 @@ export class Community extends Component<any, State> { this.fetchData(); } else if (op == UserOperation.GetCommunity) { let data = wsJsonToRes<GetCommunityResponse>(msg, GetCommunityResponse); - this.state.communityRes = Some(data); - this.state.communityLoading = false; - this.setState(this.state); + this.setState({ communityRes: Some(data), communityLoading: false }); // TODO why is there no auth in this form? WebSocketService.Instance.send( wsClient.communityJoin({ @@ -576,9 +576,7 @@ export class Community extends Component<any, State> { this.setState(this.state); } else if (op == UserOperation.GetPosts) { let data = wsJsonToRes<GetPostsResponse>(msg, GetPostsResponse); - this.state.posts = data.posts; - this.state.postsLoading = false; - this.setState(this.state); + this.setState({ posts: data.posts, postsLoading: false }); restoreScrollPosition(this.context); setupTippy(); } else if ( @@ -631,9 +629,7 @@ export class Community extends Component<any, State> { this.setState(this.state); } else if (op == UserOperation.GetComments) { let data = wsJsonToRes<GetCommentsResponse>(msg, GetCommentsResponse); - this.state.comments = data.comments; - this.state.commentsLoading = false; - this.setState(this.state); + this.setState({ comments: data.comments, commentsLoading: false }); } else if ( op == UserOperation.EditComment || op == UserOperation.DeleteComment || diff --git a/src/shared/components/community/create-community.tsx b/src/shared/components/community/create-community.tsx index 9a3667843..8aed56b12 100644 --- a/src/shared/components/community/create-community.tsx +++ b/src/shared/components/community/create-community.tsx @@ -56,7 +56,7 @@ export class CreateCommunity extends Component<any, CreateCommunityState> { render() { return ( - <div class="container"> + <div className="container"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} @@ -68,8 +68,8 @@ export class CreateCommunity extends Component<any, CreateCommunityState> { <Spinner large /> </h5> ) : ( - <div class="row"> - <div class="col-12 col-lg-6 offset-lg-3 mb-4"> + <div className="row"> + <div className="col-12 col-lg-6 offset-lg-3 mb-4"> <h5>{i18n.t("create_community")}</h5> <CommunityForm community_view={None} diff --git a/src/shared/components/community/sidebar.tsx b/src/shared/components/community/sidebar.tsx index 84879d7b2..c72356778 100644 --- a/src/shared/components/community/sidebar.tsx +++ b/src/shared/components/community/sidebar.tsx @@ -91,8 +91,8 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { sidebar() { return ( <div> - <div class="card border-secondary mb-3"> - <div class="card-body"> + <div className="card border-secondary mb-3"> + <div className="card-body"> {this.communityTitle()} {this.adminButtons()} {this.subscribe()} @@ -100,8 +100,8 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { {this.blockCommunity()} </div> </div> - <div class="card border-secondary mb-3"> - <div class="card-body"> + <div className="card border-secondary mb-3"> + <div className="card-body"> {this.description()} {this.badges()} {this.mods()} @@ -120,10 +120,10 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { {this.props.showIcon && ( <BannerIconHeader icon={community.icon} banner={community.banner} /> )} - <span class="mr-2">{community.title}</span> + <span className="mr-2">{community.title}</span> {subscribed == SubscribedType.Subscribed && ( <button - class="btn btn-secondary btn-sm mr-2" + className="btn btn-secondary btn-sm mr-2" onClick={linkEvent(this, this.handleUnsubscribe)} > <Icon icon="check" classes="icon-inline text-success mr-1" /> @@ -132,7 +132,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { )} {subscribed == SubscribedType.Pending && ( <button - class="btn btn-warning mr-2" + className="btn btn-warning mr-2" onClick={linkEvent(this, this.handleUnsubscribe)} > {i18n.t("subscribe_pending")} @@ -169,7 +169,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { let community_view = this.props.community_view; let counts = community_view.counts; return ( - <ul class="my-1 list-inline"> + <ul className="my-1 list-inline"> <li className="list-inline-item badge badge-secondary"> {i18n.t("number_online", { count: this.props.online, @@ -260,10 +260,10 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { mods() { return ( - <ul class="list-inline small"> - <li class="list-inline-item">{i18n.t("mods")}: </li> + <ul className="list-inline small"> + <li className="list-inline-item">{i18n.t("mods")}: </li> {this.props.moderators.map(mod => ( - <li class="list-inline-item"> + <li key={mod.moderator.id} className="list-inline-item"> <PersonListing person={mod.moderator} /> </li> ))} @@ -288,10 +288,10 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { subscribe() { let community_view = this.props.community_view; return ( - <div class="mb-2"> + <div className="mb-2"> {community_view.subscribed == SubscribedType.NotSubscribed && ( <button - class="btn btn-secondary btn-block" + className="btn btn-secondary btn-block" onClick={linkEvent(this, this.handleSubscribe)} > {i18n.t("subscribe")} @@ -306,18 +306,18 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { let blocked = this.props.community_view.blocked; return ( - <div class="mb-2"> + <div className="mb-2"> {community_view.subscribed == SubscribedType.NotSubscribed && (blocked ? ( <button - class="btn btn-danger btn-block" + className="btn btn-danger btn-block" onClick={linkEvent(this, this.handleUnblock)} > {i18n.t("unblock_community")} </button> ) : ( <button - class="btn btn-danger btn-block" + className="btn btn-danger btn-block" onClick={linkEvent(this, this.handleBlock)} > {i18n.t("block_community")} @@ -341,12 +341,12 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { let community_view = this.props.community_view; return ( <> - <ul class="list-inline mb-1 text-muted font-weight-bold"> + <ul className="list-inline mb-1 text-muted font-weight-bold"> {amMod(Some(this.props.moderators)) && ( <> <li className="list-inline-item-action"> <button - class="btn btn-link text-muted d-inline-block" + className="btn btn-link text-muted d-inline-block" onClick={linkEvent(this, this.handleEditClick)} data-tippy-content={i18n.t("edit")} aria-label={i18n.t("edit")} @@ -358,7 +358,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { (!this.state.showConfirmLeaveModTeam ? ( <li className="list-inline-item-action"> <button - class="btn btn-link text-muted d-inline-block" + className="btn btn-link text-muted d-inline-block" onClick={linkEvent( this, this.handleShowConfirmLeaveModTeamClick @@ -374,7 +374,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { </li> <li className="list-inline-item-action"> <button - class="btn btn-link text-muted d-inline-block" + className="btn btn-link text-muted d-inline-block" onClick={linkEvent(this, this.handleLeaveModTeamClick)} > {i18n.t("yes")} @@ -382,7 +382,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { </li> <li className="list-inline-item-action"> <button - class="btn btn-link text-muted d-inline-block" + className="btn btn-link text-muted d-inline-block" onClick={linkEvent( this, this.handleCancelLeaveModTeamClick @@ -396,7 +396,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { {amTopMod(Some(this.props.moderators)) && ( <li className="list-inline-item-action"> <button - class="btn btn-link text-muted d-inline-block" + className="btn btn-link text-muted d-inline-block" onClick={linkEvent(this, this.handleDeleteClick)} data-tippy-content={ !community_view.community.deleted @@ -424,21 +424,21 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { <li className="list-inline-item"> {!this.props.community_view.community.removed ? ( <button - class="btn btn-link text-muted d-inline-block" + className="btn btn-link text-muted d-inline-block" onClick={linkEvent(this, this.handleModRemoveShow)} > {i18n.t("remove")} </button> ) : ( <button - class="btn btn-link text-muted d-inline-block" + className="btn btn-link text-muted d-inline-block" onClick={linkEvent(this, this.handleModRemoveSubmit)} > {i18n.t("restore")} </button> )} <button - class="btn btn-link text-muted d-inline-block" + className="btn btn-link text-muted d-inline-block" onClick={linkEvent(this, this.handlePurgeCommunityShow)} aria-label={i18n.t("purge_community")} > @@ -449,14 +449,14 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { </ul> {this.state.showRemoveDialog && ( <form onSubmit={linkEvent(this, this.handleModRemoveSubmit)}> - <div class="form-group"> - <label class="col-form-label" htmlFor="remove-reason"> + <div className="form-group"> + <label className="col-form-label" htmlFor="remove-reason"> {i18n.t("reason")} </label> <input type="text" id="remove-reason" - class="form-control mr-2" + className="form-control mr-2" placeholder={i18n.t("optional")} value={toUndefined(this.state.removeReason)} onInput={linkEvent(this, this.handleModRemoveReasonChange)} @@ -467,8 +467,8 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { {/* <label class="col-form-label">Expires</label> */} {/* <input type="date" class="form-control mr-2" placeholder={i18n.t('expires')} value={this.state.removeExpires} onInput={linkEvent(this, this.handleModRemoveExpiresChange)} /> */} {/* </div> */} - <div class="form-group"> - <button type="submit" class="btn btn-secondary"> + <div className="form-group"> + <button type="submit" className="btn btn-secondary"> {i18n.t("remove_community")} </button> </div> @@ -476,29 +476,29 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { )} {this.state.showPurgeDialog && ( <form onSubmit={linkEvent(this, this.handlePurgeSubmit)}> - <div class="form-group"> + <div className="form-group"> <PurgeWarning /> </div> - <div class="form-group"> - <label class="sr-only" htmlFor="purge-reason"> + <div className="form-group"> + <label className="sr-only" htmlFor="purge-reason"> {i18n.t("reason")} </label> <input type="text" id="purge-reason" - class="form-control mr-2" + className="form-control mr-2" placeholder={i18n.t("reason")} value={toUndefined(this.state.purgeReason)} onInput={linkEvent(this, this.handlePurgeReasonChange)} /> </div> - <div class="form-group"> + <div className="form-group"> {this.state.purgeLoading ? ( <Spinner /> ) : ( <button type="submit" - class="btn btn-secondary" + className="btn btn-secondary" aria-label={i18n.t("purge_community")} > {i18n.t("purge_community")} @@ -512,18 +512,15 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { } handleEditClick(i: Sidebar) { - i.state.showEdit = true; - i.setState(i.state); + i.setState({ showEdit: true }); } handleEditCommunity() { - this.state.showEdit = false; - this.setState(this.state); + this.setState({ showEdit: false }); } handleEditCancel() { - this.state.showEdit = false; - this.setState(this.state); + this.setState({ showEdit: false }); } handleDeleteClick(i: Sidebar, event: any) { @@ -537,8 +534,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { } handleShowConfirmLeaveModTeamClick(i: Sidebar) { - i.state.showConfirmLeaveModTeam = true; - i.setState(i.state); + i.setState({ showConfirmLeaveModTeam: true }); } handleLeaveModTeamClick(i: Sidebar) { @@ -551,16 +547,14 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { auth: auth().unwrap(), }); WebSocketService.Instance.send(wsClient.addModToCommunity(form)); - i.state.showConfirmLeaveModTeam = false; - i.setState(i.state); + i.setState({ showConfirmLeaveModTeam: false }); }, none: void 0, }); } handleCancelLeaveModTeamClick(i: Sidebar) { - i.state.showConfirmLeaveModTeam = false; - i.setState(i.state); + i.setState({ showConfirmLeaveModTeam: false }); } handleUnsubscribe(i: Sidebar, event: any) { @@ -611,18 +605,15 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { } handleModRemoveShow(i: Sidebar) { - i.state.showRemoveDialog = true; - i.setState(i.state); + i.setState({ showRemoveDialog: true }); } handleModRemoveReasonChange(i: Sidebar, event: any) { - i.state.removeReason = Some(event.target.value); - i.setState(i.state); + i.setState({ removeReason: Some(event.target.value) }); } handleModRemoveExpiresChange(i: Sidebar, event: any) { - i.state.removeExpires = Some(event.target.value); - i.setState(i.state); + i.setState({ removeExpires: Some(event.target.value) }); } handleModRemoveSubmit(i: Sidebar, event: any) { @@ -636,19 +627,15 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { }); WebSocketService.Instance.send(wsClient.removeCommunity(removeForm)); - i.state.showRemoveDialog = false; - i.setState(i.state); + i.setState({ showRemoveDialog: false }); } handlePurgeCommunityShow(i: Sidebar) { - i.state.showPurgeDialog = true; - i.state.showRemoveDialog = false; - i.setState(i.state); + i.setState({ showPurgeDialog: true, showRemoveDialog: false }); } handlePurgeReasonChange(i: Sidebar, event: any) { - i.state.purgeReason = Some(event.target.value); - i.setState(i.state); + i.setState({ purgeReason: Some(event.target.value) }); } handlePurgeSubmit(i: Sidebar, event: any) { @@ -661,8 +648,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { }); WebSocketService.Instance.send(wsClient.purgeCommunity(form)); - i.state.purgeLoading = true; - i.setState(i.state); + i.setState({ purgeLoading: true }); } handleBlock(i: Sidebar, event: any) { diff --git a/src/shared/components/home/admin-settings.tsx b/src/shared/components/home/admin-settings.tsx index e01a09d7a..011a5767a 100644 --- a/src/shared/components/home/admin-settings.tsx +++ b/src/shared/components/home/admin-settings.tsx @@ -59,10 +59,11 @@ export class AdminSettings extends Component<any, AdminSettingsState> { // Only fetch the data if coming from another route if (this.isoData.path == this.context.router.route.match.url) { - this.state.banned = ( - this.isoData.routeData[0] as BannedPersonsResponse - ).banned; - this.state.loading = false; + this.state = { + ...this.state, + banned: (this.isoData.routeData[0] as BannedPersonsResponse).banned, + loading: false, + }; } else { WebSocketService.Instance.send( wsClient.getBannedPersons({ @@ -103,14 +104,14 @@ export class AdminSettings extends Component<any, AdminSettingsState> { render() { return ( - <div class="container"> + <div className="container"> {this.state.loading ? ( <h5> <Spinner large /> </h5> ) : ( - <div class="row"> - <div class="col-12 col-md-6"> + <div className="row"> + <div className="col-12 col-md-6"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} @@ -127,7 +128,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> { none: <></>, })} </div> - <div class="col-12 col-md-6"> + <div className="col-12 col-md-6"> {this.admins()} {this.bannedUsers()} </div> @@ -141,9 +142,9 @@ export class AdminSettings extends Component<any, AdminSettingsState> { return ( <> <h5>{capitalizeFirstLetter(i18n.t("admins"))}</h5> - <ul class="list-unstyled"> + <ul className="list-unstyled"> {this.state.siteRes.admins.map(admin => ( - <li class="list-inline-item"> + <li key={admin.person.id} className="list-inline-item"> <PersonListing person={admin.person} /> </li> ))} @@ -157,7 +158,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> { return ( <button onClick={linkEvent(this, this.handleLeaveAdminTeam)} - class="btn btn-danger mb-2" + className="btn btn-danger mb-2" > {this.state.leaveAdminTeamLoading ? ( <Spinner /> @@ -172,9 +173,9 @@ export class AdminSettings extends Component<any, AdminSettingsState> { return ( <> <h5>{i18n.t("banned_users")}</h5> - <ul class="list-unstyled"> + <ul className="list-unstyled"> {this.state.banned.map(banned => ( - <li class="list-inline-item"> + <li key={banned.person.id} className="list-inline-item"> <PersonListing person={banned.person} /> </li> ))} @@ -184,11 +185,10 @@ export class AdminSettings extends Component<any, AdminSettingsState> { } handleLeaveAdminTeam(i: AdminSettings) { - i.state.leaveAdminTeamLoading = true; + i.setState({ leaveAdminTeamLoading: true }); WebSocketService.Instance.send( wsClient.leaveAdmin({ auth: auth().unwrap() }) ); - i.setState(i.state); } parseMessage(msg: any) { @@ -197,26 +197,21 @@ export class AdminSettings extends Component<any, AdminSettingsState> { if (msg.error) { toast(i18n.t(msg.error), "danger"); this.context.router.history.push("/"); - this.state.loading = false; - this.setState(this.state); + this.setState({ loading: false }); return; } else if (op == UserOperation.EditSite) { let data = wsJsonToRes<SiteResponse>(msg, SiteResponse); - this.state.siteRes.site_view = Some(data.site_view); - this.setState(this.state); + this.setState(s => ((s.siteRes.site_view = Some(data.site_view)), s)); toast(i18n.t("site_saved")); } else if (op == UserOperation.GetBannedPersons) { let data = wsJsonToRes<BannedPersonsResponse>(msg, BannedPersonsResponse); - this.state.banned = data.banned; - this.state.loading = false; - this.setState(this.state); + this.setState({ banned: data.banned, loading: false }); } else if (op == UserOperation.LeaveAdmin) { let data = wsJsonToRes<GetSiteResponse>(msg, GetSiteResponse); - this.state.siteRes.site_view = data.site_view; - this.setState(this.state); - this.state.leaveAdminTeamLoading = false; + this.setState(s => ((s.siteRes.site_view = data.site_view), s)); + this.setState({ leaveAdminTeamLoading: false }); + toast(i18n.t("left_admin_team")); - this.setState(this.state); this.context.router.history.push("/"); } } diff --git a/src/shared/components/home/home.tsx b/src/shared/components/home/home.tsx index 53559df9c..69de7a858 100644 --- a/src/shared/components/home/home.tsx +++ b/src/shared/components/home/home.tsx @@ -157,22 +157,24 @@ export class Home extends Component<any, HomeState> { let commentsRes = Some(this.isoData.routeData[1] as GetCommentsResponse); let trendingRes = this.isoData.routeData[2] as ListCommunitiesResponse; - postsRes.match({ - some: pvs => (this.state.posts = pvs.posts), - none: void 0, - }); - commentsRes.match({ - some: cvs => (this.state.comments = cvs.comments), - none: void 0, - }); - this.state.trendingCommunities = trendingRes.communities; + if (postsRes.isSome()) { + this.state = { ...this.state, posts: postsRes.unwrap().posts }; + } + + if (commentsRes.isSome()) { + this.state = { ...this.state, comments: commentsRes.unwrap().comments }; + } if (isBrowser()) { WebSocketService.Instance.send( wsClient.communityJoin({ community_id: 0 }) ); } - this.state.loading = false; + this.state = { + ...this.state, + trendingCommunities: trendingRes.communities, + loading: false, + }; } else { this.fetchTrendingCommunities(); this.fetchData(); @@ -317,7 +319,7 @@ export class Home extends Component<any, HomeState> { render() { return ( - <div class="container"> + <div className="container"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} @@ -325,12 +327,14 @@ export class Home extends Component<any, HomeState> { image={None} /> {this.state.siteRes.site_view.isSome() && ( - <div class="row"> - <main role="main" class="col-12 col-md-8"> - <div class="d-block d-md-none">{this.mobileView()}</div> + <div className="row"> + <main role="main" className="col-12 col-md-8"> + <div className="d-block d-md-none">{this.mobileView()}</div> {this.posts()} </main> - <aside class="d-none d-md-block col-md-4">{this.mySidebar()}</aside> + <aside className="d-none d-md-block col-md-4"> + {this.mySidebar()} + </aside> </div> )} </div> @@ -347,11 +351,11 @@ export class Home extends Component<any, HomeState> { mobileView() { let siteRes = this.state.siteRes; return ( - <div class="row"> - <div class="col-12"> + <div className="row"> + <div className="col-12"> {this.hasFollows && ( <button - class="btn btn-secondary d-inline-block mb-2 mr-3" + className="btn btn-secondary d-inline-block mb-2 mr-3" onClick={linkEvent(this, this.handleShowSubscribedMobile)} > {i18n.t("subscribed")}{" "} @@ -366,7 +370,7 @@ export class Home extends Component<any, HomeState> { </button> )} <button - class="btn btn-secondary d-inline-block mb-2 mr-3" + className="btn btn-secondary d-inline-block mb-2 mr-3" onClick={linkEvent(this, this.handleShowTrendingMobile)} > {i18n.t("trending")}{" "} @@ -378,7 +382,7 @@ export class Home extends Component<any, HomeState> { /> </button> <button - class="btn btn-secondary d-inline-block mb-2 mr-3" + className="btn btn-secondary d-inline-block mb-2 mr-3" onClick={linkEvent(this, this.handleShowSidebarMobile)} > {i18n.t("sidebar")}{" "} @@ -403,13 +407,13 @@ export class Home extends Component<any, HomeState> { none: <></>, })} {this.state.showTrendingMobile && ( - <div class="col-12 card border-secondary mb-3"> - <div class="card-body">{this.trendingCommunities()}</div> + <div className="col-12 card border-secondary mb-3"> + <div className="card-body">{this.trendingCommunities()}</div> </div> )} {this.state.showSubscribedMobile && ( - <div class="col-12 card border-secondary mb-3"> - <div class="card-body">{this.subscribedCommunities()}</div> + <div className="col-12 card border-secondary mb-3"> + <div className="card-body">{this.subscribedCommunities()}</div> </div> )} </div> @@ -423,8 +427,8 @@ export class Home extends Component<any, HomeState> { <div> {!this.state.loading && ( <div> - <div class="card border-secondary mb-3"> - <div class="card-body"> + <div className="card border-secondary mb-3"> + <div className="card-body"> {this.trendingCommunities()} {this.createCommunityButton()} {this.exploreCommunitiesButton()} @@ -443,8 +447,8 @@ export class Home extends Component<any, HomeState> { none: <></>, })} {this.hasFollows && ( - <div class="card border-secondary mb-3"> - <div class="card-body">{this.subscribedCommunities()}</div> + <div className="card border-secondary mb-3"> + <div className="card-body">{this.subscribedCommunities()}</div> </div> )} </div> @@ -480,9 +484,12 @@ export class Home extends Component<any, HomeState> { </Link> </T> </h5> - <ul class="list-inline mb-0"> + <ul className="list-inline mb-0"> {this.state.trendingCommunities.map(cv => ( - <li class="list-inline-item d-inline-block"> + <li + key={cv.community.id} + className="list-inline-item d-inline-block" + > <CommunityLink community={cv.community} /> </li> ))} @@ -502,7 +509,7 @@ export class Home extends Component<any, HomeState> { </Link> </T> <button - class="btn btn-sm text-muted" + className="btn btn-sm text-muted" onClick={linkEvent(this, this.handleCollapseSubscribe)} aria-label={i18n.t("collapse")} data-tippy-content={i18n.t("collapse")} @@ -515,12 +522,15 @@ export class Home extends Component<any, HomeState> { </button> </h5> {!this.state.subscribedCollapsed && ( - <ul class="list-inline mb-0"> + <ul className="list-inline mb-0"> {UserService.Instance.myUserInfo .map(m => m.follows) .unwrapOr([]) .map(cfv => ( - <li class="list-inline-item d-inline-block"> + <li + key={cfv.community.id} + className="list-inline-item d-inline-block" + > <CommunityLink community={cfv.community} /> </li> ))} @@ -542,7 +552,7 @@ export class Home extends Component<any, HomeState> { posts() { return ( - <div class="main-content-wrapper"> + <div className="main-content-wrapper"> {this.state.loading ? ( <h5> <Spinner large /> @@ -594,13 +604,13 @@ export class Home extends Component<any, HomeState> { return ( <div className="mb-3"> - <span class="mr-3"> + <span className="mr-3"> <DataTypeSelect type_={this.state.dataType} onChange={this.handleDataTypeChange} /> </span> - <span class="mr-3"> + <span className="mr-3"> <ListingTypeSelect type_={this.state.listingType} showLocal={showLocal(this.isoData)} @@ -608,7 +618,7 @@ export class Home extends Component<any, HomeState> { onChange={this.handleListingTypeChange} /> </span> - <span class="mr-2"> + <span className="mr-2"> <SortSelect sort={this.state.sort} onChange={this.handleSortChange} /> </span> {this.state.listingType == ListingType.All && ( @@ -644,23 +654,19 @@ export class Home extends Component<any, HomeState> { } handleShowSubscribedMobile(i: Home) { - i.state.showSubscribedMobile = !i.state.showSubscribedMobile; - i.setState(i.state); + i.setState({ showSubscribedMobile: !i.state.showSubscribedMobile }); } handleShowTrendingMobile(i: Home) { - i.state.showTrendingMobile = !i.state.showTrendingMobile; - i.setState(i.state); + i.setState({ showTrendingMobile: !i.state.showTrendingMobile }); } handleShowSidebarMobile(i: Home) { - i.state.showSidebarMobile = !i.state.showSidebarMobile; - i.setState(i.state); + i.setState({ showSidebarMobile: !i.state.showSidebarMobile }); } handleCollapseSubscribe(i: Home) { - i.state.subscribedCollapsed = !i.state.subscribedCollapsed; - i.setState(i.state); + i.setState({ subscribedCollapsed: !i.state.subscribedCollapsed }); } handlePageChange(page: number) { @@ -731,18 +737,14 @@ export class Home extends Component<any, HomeState> { msg, ListCommunitiesResponse ); - this.state.trendingCommunities = data.communities; - this.setState(this.state); + this.setState({ trendingCommunities: data.communities }); } else if (op == UserOperation.EditSite) { let data = wsJsonToRes<SiteResponse>(msg, SiteResponse); - this.state.siteRes.site_view = Some(data.site_view); - this.setState(this.state); + this.setState(s => ((s.siteRes.site_view = Some(data.site_view)), s)); toast(i18n.t("site_saved")); } else if (op == UserOperation.GetPosts) { let data = wsJsonToRes<GetPostsResponse>(msg, GetPostsResponse); - this.state.posts = data.posts; - this.state.loading = false; - this.setState(this.state); + this.setState({ posts: data.posts, loading: false }); WebSocketService.Instance.send( wsClient.communityJoin({ community_id: 0 }) ); @@ -812,8 +814,7 @@ export class Home extends Component<any, HomeState> { this.setState(this.state); } else if (op == UserOperation.AddAdmin) { let data = wsJsonToRes<AddAdminResponse>(msg, AddAdminResponse); - this.state.siteRes.admins = data.admins; - this.setState(this.state); + this.setState(s => ((s.siteRes.admins = data.admins), s)); } else if (op == UserOperation.BanPerson) { let data = wsJsonToRes<BanPersonResponse>(msg, BanPersonResponse); this.state.posts @@ -823,9 +824,7 @@ export class Home extends Component<any, HomeState> { this.setState(this.state); } else if (op == UserOperation.GetComments) { let data = wsJsonToRes<GetCommentsResponse>(msg, GetCommentsResponse); - this.state.comments = data.comments; - this.state.loading = false; - this.setState(this.state); + this.setState({ comments: data.comments, loading: false }); } else if ( op == UserOperation.EditComment || op == UserOperation.DeleteComment || diff --git a/src/shared/components/home/instances.tsx b/src/shared/components/home/instances.tsx index fe4064dec..f473ffa17 100644 --- a/src/shared/components/home/instances.tsx +++ b/src/shared/components/home/instances.tsx @@ -30,22 +30,22 @@ export class Instances extends Component<any, InstancesState> { render() { return this.state.siteRes.federated_instances.match({ some: federated_instances => ( - <div class="container"> + <div className="container"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} description={None} image={None} /> - <div class="row"> - <div class="col-md-6"> + <div className="row"> + <div className="col-md-6"> <h5>{i18n.t("linked_instances")}</h5> {this.itemList(federated_instances.linked)} </div> {federated_instances.allowed.match({ some: allowed => allowed.length > 0 && ( - <div class="col-md-6"> + <div className="col-md-6"> <h5>{i18n.t("allowed_instances")}</h5> {this.itemList(allowed)} </div> @@ -55,7 +55,7 @@ export class Instances extends Component<any, InstancesState> { {federated_instances.blocked.match({ some: blocked => blocked.length > 0 && ( - <div class="col-md-6"> + <div className="col-md-6"> <h5>{i18n.t("blocked_instances")}</h5> {this.itemList(blocked)} </div> @@ -74,7 +74,7 @@ export class Instances extends Component<any, InstancesState> { return items.length > 0 ? ( <ul> {items.map(i => ( - <li> + <li key={i}> <a href={`https://${i}`} rel={relTags}> {i} </a> diff --git a/src/shared/components/home/legal.tsx b/src/shared/components/home/legal.tsx index 590d7d846..78c9bbba8 100644 --- a/src/shared/components/home/legal.tsx +++ b/src/shared/components/home/legal.tsx @@ -26,7 +26,7 @@ export class Legal extends Component<any, LegalState> { render() { return ( - <div class="container"> + <div className="container"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} diff --git a/src/shared/components/home/login.tsx b/src/shared/components/home/login.tsx index 753e9d816..001cfd4c9 100644 --- a/src/shared/components/home/login.tsx +++ b/src/shared/components/home/login.tsx @@ -81,15 +81,15 @@ export class Login extends Component<any, State> { render() { return ( - <div class="container"> + <div className="container"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} description={None} image={None} /> - <div class="row"> - <div class="col-12 col-lg-6 offset-lg-3">{this.loginForm()}</div> + <div className="row"> + <div className="col-12 col-lg-6 offset-lg-3">{this.loginForm()}</div> </div> </div> ); @@ -100,17 +100,17 @@ export class Login extends Component<any, State> { <div> <form onSubmit={linkEvent(this, this.handleLoginSubmit)}> <h5>{i18n.t("login")}</h5> - <div class="form-group row"> + <div className="form-group row"> <label - class="col-sm-2 col-form-label" + className="col-sm-2 col-form-label" htmlFor="login-email-or-username" > {i18n.t("email_or_username")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <input type="text" - class="form-control" + className="form-control" id="login-email-or-username" value={this.state.loginForm.username_or_email} onInput={linkEvent(this, this.handleLoginUsernameChange)} @@ -120,17 +120,17 @@ export class Login extends Component<any, State> { /> </div> </div> - <div class="form-group row"> - <label class="col-sm-2 col-form-label" htmlFor="login-password"> + <div className="form-group row"> + <label className="col-sm-2 col-form-label" htmlFor="login-password"> {i18n.t("password")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <input type="password" id="login-password" value={this.state.loginForm.password} onInput={linkEvent(this, this.handleLoginPasswordChange)} - class="form-control" + className="form-control" autoComplete="current-password" required maxLength={60} @@ -146,9 +146,9 @@ export class Login extends Component<any, State> { </button> </div> </div> - <div class="form-group row"> - <div class="col-sm-10"> - <button type="submit" class="btn btn-secondary"> + <div className="form-group row"> + <div className="col-sm-10"> + <button type="submit" className="btn btn-secondary"> {this.state.loginLoading ? <Spinner /> : i18n.t("login")} </button> </div> @@ -160,8 +160,7 @@ export class Login extends Component<any, State> { handleLoginSubmit(i: Login, event: any) { event.preventDefault(); - i.state.loginLoading = true; - i.setState(i.state); + i.setState({ loginLoading: true }); WebSocketService.Instance.send(wsClient.login(i.state.loginForm)); } @@ -188,21 +187,18 @@ export class Login extends Component<any, State> { console.log(msg); if (msg.error) { toast(i18n.t(msg.error), "danger"); - this.state = this.emptyState; - this.setState(this.state); + this.setState(this.emptyState); return; } else { if (op == UserOperation.Login) { let data = wsJsonToRes<LoginResponse>(msg, LoginResponse); - this.state = this.emptyState; - this.setState(this.state); + this.setState(this.emptyState); UserService.Instance.login(data); } else if (op == UserOperation.PasswordReset) { toast(i18n.t("reset_password_mail_sent")); } else if (op == UserOperation.GetSite) { let data = wsJsonToRes<GetSiteResponse>(msg, GetSiteResponse); - this.state.siteRes = data; - this.setState(this.state); + this.setState({ siteRes: data }); } } } diff --git a/src/shared/components/home/setup.tsx b/src/shared/components/home/setup.tsx index 46d225e24..8e1c9fff0 100644 --- a/src/shared/components/home/setup.tsx +++ b/src/shared/components/home/setup.tsx @@ -67,10 +67,10 @@ export class Setup extends Component<any, State> { render() { return ( - <div class="container"> + <div className="container"> <Helmet title={this.documentTitle} /> - <div class="row"> - <div class="col-12 offset-lg-3 col-lg-6"> + <div className="row"> + <div className="col-12 offset-lg-3 col-lg-6"> <h3>{i18n.t("lemmy_instance_setup")}</h3> {!this.state.doneRegisteringUser ? ( this.registerUser() @@ -87,14 +87,14 @@ export class Setup extends Component<any, State> { return ( <form onSubmit={linkEvent(this, this.handleRegisterSubmit)}> <h5>{i18n.t("setup_admin")}</h5> - <div class="form-group row"> - <label class="col-sm-2 col-form-label" htmlFor="username"> + <div className="form-group row"> + <label className="col-sm-2 col-form-label" htmlFor="username"> {i18n.t("username")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <input type="text" - class="form-control" + className="form-control" id="username" value={this.state.userForm.username} onInput={linkEvent(this, this.handleRegisterUsernameChange)} @@ -104,16 +104,16 @@ export class Setup extends Component<any, State> { /> </div> </div> - <div class="form-group row"> - <label class="col-sm-2 col-form-label" htmlFor="email"> + <div className="form-group row"> + <label className="col-sm-2 col-form-label" htmlFor="email"> {i18n.t("email")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <input type="email" id="email" - class="form-control" + className="form-control" placeholder={i18n.t("optional")} value={toUndefined(this.state.userForm.email)} onInput={linkEvent(this, this.handleRegisterEmailChange)} @@ -121,17 +121,17 @@ export class Setup extends Component<any, State> { /> </div> </div> - <div class="form-group row"> - <label class="col-sm-2 col-form-label" htmlFor="password"> + <div className="form-group row"> + <label className="col-sm-2 col-form-label" htmlFor="password"> {i18n.t("password")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <input type="password" id="password" value={this.state.userForm.password} onInput={linkEvent(this, this.handleRegisterPasswordChange)} - class="form-control" + className="form-control" required autoComplete="new-password" minLength={10} @@ -139,17 +139,17 @@ export class Setup extends Component<any, State> { /> </div> </div> - <div class="form-group row"> - <label class="col-sm-2 col-form-label" htmlFor="verify-password"> + <div className="form-group row"> + <label className="col-sm-2 col-form-label" htmlFor="verify-password"> {i18n.t("verify_password")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <input type="password" id="verify-password" value={this.state.userForm.password_verify} onInput={linkEvent(this, this.handleRegisterPasswordVerifyChange)} - class="form-control" + className="form-control" required autoComplete="new-password" minLength={10} @@ -157,9 +157,9 @@ export class Setup extends Component<any, State> { /> </div> </div> - <div class="form-group row"> - <div class="col-sm-10"> - <button type="submit" class="btn btn-secondary"> + <div className="form-group row"> + <div className="col-sm-10"> + <button type="submit" className="btn btn-secondary"> {this.state.userLoading ? <Spinner /> : i18n.t("sign_up")} </button> </div> @@ -170,8 +170,7 @@ export class Setup extends Component<any, State> { handleRegisterSubmit(i: Setup, event: any) { event.preventDefault(); - i.state.userLoading = true; - i.setState(i.state); + i.setState({ userLoading: true }); event.preventDefault(); WebSocketService.Instance.send(wsClient.register(i.state.userForm)); } @@ -200,14 +199,12 @@ export class Setup extends Component<any, State> { let op = wsUserOp(msg); if (msg.error) { toast(i18n.t(msg.error), "danger"); - this.state.userLoading = false; - this.setState(this.state); + this.setState({ userLoading: false }); return; } else if (op == UserOperation.Register) { let data = wsJsonToRes<LoginResponse>(msg, LoginResponse); - this.state.userLoading = false; + this.setState({ userLoading: false }); UserService.Instance.login(data); - this.setState(this.state); } else if (op == UserOperation.CreateSite) { window.location.href = "/"; } diff --git a/src/shared/components/home/signup.tsx b/src/shared/components/home/signup.tsx index 9e6e3c756..d7dc2a276 100644 --- a/src/shared/components/home/signup.tsx +++ b/src/shared/components/home/signup.tsx @@ -127,15 +127,17 @@ export class Signup extends Component<any, State> { render() { return ( - <div class="container"> + <div className="container"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} description={None} image={None} /> - <div class="row"> - <div class="col-12 col-lg-6 offset-lg-3">{this.registerForm()}</div> + <div className="row"> + <div className="col-12 col-lg-6 offset-lg-3"> + {this.registerForm()} + </div> </div> </div> ); @@ -148,8 +150,8 @@ export class Signup extends Component<any, State> { <h5>{this.titleName(siteView)}</h5> {this.isLemmyMl && ( - <div class="form-group row"> - <div class="mt-2 mb-0 alert alert-warning" role="alert"> + <div className="form-group row"> + <div className="mt-2 mb-0 alert alert-warning" role="alert"> <T i18nKey="lemmy_ml_registration_message"> #<a href={joinLemmyUrl}>#</a> </T> @@ -157,16 +159,19 @@ export class Signup extends Component<any, State> { </div> )} - <div class="form-group row"> - <label class="col-sm-2 col-form-label" htmlFor="register-username"> + <div className="form-group row"> + <label + className="col-sm-2 col-form-label" + htmlFor="register-username" + > {i18n.t("username")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <input type="text" id="register-username" - class="form-control" + className="form-control" value={this.state.registerForm.username} onInput={linkEvent(this, this.handleRegisterUsernameChange)} required @@ -177,15 +182,15 @@ export class Signup extends Component<any, State> { </div> </div> - <div class="form-group row"> - <label class="col-sm-2 col-form-label" htmlFor="register-email"> + <div className="form-group row"> + <label className="col-sm-2 col-form-label" htmlFor="register-email"> {i18n.t("email")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <input type="email" id="register-email" - class="form-control" + className="form-control" placeholder={ siteView.site.require_email_verification ? i18n.t("required") @@ -201,7 +206,7 @@ export class Signup extends Component<any, State> { !this.state.registerForm.email .map(validEmail) .unwrapOr(true) && ( - <div class="mt-2 mb-0 alert alert-warning" role="alert"> + <div className="mt-2 mb-0 alert alert-warning" role="alert"> <Icon icon="alert-triangle" classes="icon-inline mr-2" /> {i18n.t("no_password_reset")} </div> @@ -209,11 +214,14 @@ export class Signup extends Component<any, State> { </div> </div> - <div class="form-group row"> - <label class="col-sm-2 col-form-label" htmlFor="register-password"> + <div className="form-group row"> + <label + className="col-sm-2 col-form-label" + htmlFor="register-password" + > {i18n.t("password")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <input type="password" id="register-password" @@ -222,25 +230,25 @@ export class Signup extends Component<any, State> { onInput={linkEvent(this, this.handleRegisterPasswordChange)} minLength={10} maxLength={60} - class="form-control" + className="form-control" required /> {this.state.registerForm.password && ( - <div class={this.passwordColorClass}> + <div className={this.passwordColorClass}> {i18n.t(this.passwordStrength as I18nKeys)} </div> )} </div> </div> - <div class="form-group row"> + <div className="form-group row"> <label - class="col-sm-2 col-form-label" + className="col-sm-2 col-form-label" htmlFor="register-verify-password" > {i18n.t("verify_password")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <input type="password" id="register-verify-password" @@ -251,7 +259,7 @@ export class Signup extends Component<any, State> { this.handleRegisterPasswordVerifyChange )} maxLength={60} - class="form-control" + className="form-control" required /> </div> @@ -259,9 +267,9 @@ export class Signup extends Component<any, State> { {siteView.site.require_application && ( <> - <div class="form-group row"> - <div class="offset-sm-2 col-sm-10"> - <div class="mt-2 alert alert-warning" role="alert"> + <div className="form-group row"> + <div className="offset-sm-2 col-sm-10"> + <div className="mt-2 alert alert-warning" role="alert"> <Icon icon="alert-triangle" classes="icon-inline mr-2" /> {i18n.t("fill_out_application")} </div> @@ -277,14 +285,14 @@ export class Signup extends Component<any, State> { </div> </div> - <div class="form-group row"> + <div className="form-group row"> <label - class="col-sm-2 col-form-label" + className="col-sm-2 col-form-label" htmlFor="application_answer" > {i18n.t("answer")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <MarkdownTextArea initialContent={None} placeholder={None} @@ -299,12 +307,12 @@ export class Signup extends Component<any, State> { )} {this.state.captcha.isSome() && ( - <div class="form-group row"> - <label class="col-sm-2" htmlFor="register-captcha"> - <span class="mr-2">{i18n.t("enter_code")}</span> + <div className="form-group row"> + <label className="col-sm-2" htmlFor="register-captcha"> + <span className="mr-2">{i18n.t("enter_code")}</span> <button type="button" - class="btn btn-secondary" + className="btn btn-secondary" onClick={linkEvent(this, this.handleRegenCaptcha)} aria-label={i18n.t("captcha")} > @@ -312,10 +320,10 @@ export class Signup extends Component<any, State> { </button> </label> {this.showCaptcha()} - <div class="col-sm-6"> + <div className="col-sm-6"> <input type="text" - class="form-control" + className="form-control" id="register-captcha" value={toUndefined(this.state.registerForm.captcha_answer)} onInput={linkEvent( @@ -328,11 +336,11 @@ export class Signup extends Component<any, State> { </div> )} {siteView.site.enable_nsfw && ( - <div class="form-group row"> - <div class="col-sm-10"> - <div class="form-check"> + <div className="form-group row"> + <div className="col-sm-10"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="register-show-nsfw" type="checkbox" checked={this.state.registerForm.show_nsfw} @@ -341,7 +349,10 @@ export class Signup extends Component<any, State> { this.handleRegisterShowNsfwChange )} /> - <label class="form-check-label" htmlFor="register-show-nsfw"> + <label + className="form-check-label" + htmlFor="register-show-nsfw" + > {i18n.t("show_nsfw")} </label> </div> @@ -353,14 +364,14 @@ export class Signup extends Component<any, State> { autoComplete="false" name="a_password" type="text" - class="form-control honeypot" + className="form-control honeypot" id="register-honey" value={toUndefined(this.state.registerForm.honeypot)} onInput={linkEvent(this, this.handleHoneyPotChange)} /> - <div class="form-group row"> - <div class="col-sm-10"> - <button type="submit" class="btn btn-secondary"> + <div className="form-group row"> + <div className="col-sm-10"> + <button type="submit" className="btn btn-secondary"> {this.state.registerLoading ? ( <Spinner /> ) : ( @@ -378,19 +389,19 @@ export class Signup extends Component<any, State> { showCaptcha() { return this.state.captcha.match({ some: captcha => ( - <div class="col-sm-4"> + <div className="col-sm-4"> {captcha.ok.match({ some: res => ( <> <img - class="rounded-top img-fluid" + className="rounded-top img-fluid" src={this.captchaPngSrc(res)} style="border-bottom-right-radius: 0; border-bottom-left-radius: 0;" alt={i18n.t("captcha")} /> {res.wav.isSome() && ( <button - class="rounded-bottom btn btn-sm btn-secondary btn-block" + className="rounded-bottom btn btn-sm btn-secondary btn-block" style="border-top-right-radius: 0; border-top-left-radius: 0;" title={i18n.t("play_captcha_audio")} onClick={linkEvent(this, this.handleCaptchaPlay)} @@ -431,8 +442,7 @@ export class Signup extends Component<any, State> { handleRegisterSubmit(i: Signup, event: any) { event.preventDefault(); - i.state.registerLoading = true; - i.setState(i.state); + i.setState({ registerLoading: true }); WebSocketService.Instance.send(wsClient.register(i.state.registerForm)); } @@ -470,8 +480,7 @@ export class Signup extends Component<any, State> { } handleAnswerChange(val: string) { - this.state.registerForm.answer = Some(val); - this.setState(this.state); + this.setState(s => ((s.registerForm.answer = Some(val)), s)); } handleHoneyPotChange(i: Signup, event: any) { @@ -481,8 +490,7 @@ export class Signup extends Component<any, State> { handleRegenCaptcha(i: Signup) { i.audio = null; - i.state.captchaPlaying = false; - i.setState(i.state); + i.setState({ captchaPlaying: false }); WebSocketService.Instance.send(wsClient.getCaptcha()); } @@ -500,13 +508,11 @@ export class Signup extends Component<any, State> { i.audio.play(); - i.state.captchaPlaying = true; - i.setState(i.state); + i.setState({ captchaPlaying: true }); i.audio.addEventListener("ended", () => { i.audio.currentTime = 0; - i.state.captchaPlaying = false; - i.setState(i.state); + i.setState({ captchaPlaying: false }); }); }, none: void 0, @@ -524,17 +530,15 @@ export class Signup extends Component<any, State> { console.log(msg); if (msg.error) { toast(i18n.t(msg.error), "danger"); - this.state = this.emptyState; - this.state.registerForm.captcha_answer = undefined; + this.setState(this.emptyState); + this.setState(s => ((s.registerForm.captcha_answer = undefined), s)); // Refetch another captcha // WebSocketService.Instance.send(wsClient.getCaptcha()); - this.setState(this.state); return; } else { if (op == UserOperation.Register) { let data = wsJsonToRes<LoginResponse>(msg, LoginResponse); - this.state = this.emptyState; - this.setState(this.state); + this.setState(this.emptyState); // Only log them in if a jwt was set if (data.jwt.isSome()) { UserService.Instance.login(data); @@ -552,9 +556,10 @@ export class Signup extends Component<any, State> { let data = wsJsonToRes<GetCaptchaResponse>(msg, GetCaptchaResponse); data.ok.match({ some: res => { - this.state.captcha = Some(data); - this.state.registerForm.captcha_uuid = Some(res.uuid); - this.setState(this.state); + this.setState({ captcha: Some(data) }); + this.setState( + s => ((s.registerForm.captcha_uuid = Some(res.uuid)), s) + ); }, none: void 0, }); @@ -562,8 +567,7 @@ export class Signup extends Component<any, State> { toast(i18n.t("reset_password_mail_sent")); } else if (op == UserOperation.GetSite) { let data = wsJsonToRes<GetSiteResponse>(msg, GetSiteResponse); - this.state.siteRes = data; - this.setState(this.state); + this.setState({ siteRes: data }); } } } diff --git a/src/shared/components/home/site-form.tsx b/src/shared/components/home/site-form.tsx index 5602d9bf1..4f275cfd4 100644 --- a/src/shared/components/home/site-form.tsx +++ b/src/shared/components/home/site-form.tsx @@ -78,9 +78,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { this.handleDefaultPostListingTypeChange = this.handleDefaultPostListingTypeChange.bind(this); - this.props.site.match({ - some: site => { - this.state.siteForm = new EditSite({ + if (this.props.site.isSome()) { + let site = this.props.site.unwrap(); + this.state = { + ...this.state, + siteForm: new EditSite({ name: Some(site.name), sidebar: site.sidebar, description: site.description, @@ -101,21 +103,18 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { legal_information: site.legal_information, hide_modlog_mod_names: site.hide_modlog_mod_names, auth: undefined, - }); - }, - none: void 0, - }); + }), + }; + } } async componentDidMount() { - this.state.themeList = Some(await fetchThemeList()); - this.setState(this.state); + this.setState({ themeList: Some(await fetchThemeList()) }); } // Necessary to stop the loading componentWillReceiveProps() { - this.state.loading = false; - this.setState(this.state); + this.setState({ loading: false }); } componentDidUpdate() { @@ -157,15 +156,15 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { ? capitalizeFirstLetter(i18n.t("save")) : capitalizeFirstLetter(i18n.t("name")) } ${i18n.t("your_site")}`}</h5> - <div class="form-group row"> - <label class="col-12 col-form-label" htmlFor="create-site-name"> + <div className="form-group row"> + <label className="col-12 col-form-label" htmlFor="create-site-name"> {i18n.t("name")} </label> - <div class="col-12"> + <div className="col-12"> <input type="text" id="create-site-name" - class="form-control" + className="form-control" value={toUndefined(this.state.siteForm.name)} onInput={linkEvent(this, this.handleSiteNameChange)} required @@ -174,7 +173,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { /> </div> </div> - <div class="form-group"> + <div className="form-group"> <label>{i18n.t("icon")}</label> <ImageUploadForm uploadTitle={i18n.t("upload_icon")} @@ -184,7 +183,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { rounded /> </div> - <div class="form-group"> + <div className="form-group"> <label>{i18n.t("banner")}</label> <ImageUploadForm uploadTitle={i18n.t("upload_banner")} @@ -193,14 +192,14 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { onRemove={this.handleBannerRemove} /> </div> - <div class="form-group row"> - <label class="col-12 col-form-label" htmlFor="site-desc"> + <div className="form-group row"> + <label className="col-12 col-form-label" htmlFor="site-desc"> {i18n.t("description")} </label> - <div class="col-12"> + <div className="col-12"> <input type="text" - class="form-control" + className="form-control" id="site-desc" value={toUndefined(this.state.siteForm.description)} onInput={linkEvent(this, this.handleSiteDescChange)} @@ -208,9 +207,9 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { /> </div> </div> - <div class="form-group row"> - <label class="col-12 col-form-label">{i18n.t("sidebar")}</label> - <div class="col-12"> + <div className="form-group row"> + <label className="col-12 col-form-label">{i18n.t("sidebar")}</label> + <div className="col-12"> <MarkdownTextArea initialContent={this.state.siteForm.sidebar} placeholder={None} @@ -221,11 +220,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { /> </div> </div> - <div class="form-group row"> - <label class="col-12 col-form-label"> + <div className="form-group row"> + <label className="col-12 col-form-label"> {i18n.t("legal_information")} </label> - <div class="col-12"> + <div className="col-12"> <MarkdownTextArea initialContent={this.state.siteForm.legal_information} placeholder={None} @@ -237,11 +236,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { </div> </div> {this.state.siteForm.require_application.unwrapOr(false) && ( - <div class="form-group row"> - <label class="col-12 col-form-label"> + <div className="form-group row"> + <label className="col-12 col-form-label"> {i18n.t("application_questionnaire")} </label> - <div class="col-12"> + <div className="col-12"> <MarkdownTextArea initialContent={this.state.siteForm.application_question} placeholder={None} @@ -253,11 +252,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { </div> </div> )} - <div class="form-group row"> - <div class="col-12"> - <div class="form-check"> + <div className="form-group row"> + <div className="col-12"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="create-site-downvotes" type="checkbox" checked={toUndefined(this.state.siteForm.enable_downvotes)} @@ -266,24 +265,27 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { this.handleSiteEnableDownvotesChange )} /> - <label class="form-check-label" htmlFor="create-site-downvotes"> + <label + className="form-check-label" + htmlFor="create-site-downvotes" + > {i18n.t("enable_downvotes")} </label> </div> </div> </div> - <div class="form-group row"> - <div class="col-12"> - <div class="form-check"> + <div className="form-group row"> + <div className="col-12"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="create-site-enable-nsfw" type="checkbox" checked={toUndefined(this.state.siteForm.enable_nsfw)} onChange={linkEvent(this, this.handleSiteEnableNsfwChange)} /> <label - class="form-check-label" + className="form-check-label" htmlFor="create-site-enable-nsfw" > {i18n.t("enable_nsfw")} @@ -291,11 +293,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { </div> </div> </div> - <div class="form-group row"> - <div class="col-12"> - <div class="form-check"> + <div className="form-group row"> + <div className="col-12"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="create-site-open-registration" type="checkbox" checked={toUndefined(this.state.siteForm.open_registration)} @@ -305,7 +307,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { )} /> <label - class="form-check-label" + className="form-check-label" htmlFor="create-site-open-registration" > {i18n.t("open_registration")} @@ -313,11 +315,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { </div> </div> </div> - <div class="form-group row"> - <div class="col-12"> - <div class="form-check"> + <div className="form-group row"> + <div className="col-12"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="create-site-community-creation-admin-only" type="checkbox" checked={toUndefined( @@ -329,7 +331,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { )} /> <label - class="form-check-label" + className="form-check-label" htmlFor="create-site-community-creation-admin-only" > {i18n.t("community_creation_admin_only")} @@ -337,11 +339,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { </div> </div> </div> - <div class="form-group row"> - <div class="col-12"> - <div class="form-check"> + <div className="form-group row"> + <div className="col-12"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="create-site-require-email-verification" type="checkbox" checked={toUndefined( @@ -353,7 +355,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { )} /> <label - class="form-check-label" + className="form-check-label" htmlFor="create-site-require-email-verification" > {i18n.t("require_email_verification")} @@ -361,18 +363,18 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { </div> </div> </div> - <div class="form-group row"> - <div class="col-12"> - <div class="form-check"> + <div className="form-group row"> + <div className="col-12"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="create-site-require-application" type="checkbox" checked={toUndefined(this.state.siteForm.require_application)} onChange={linkEvent(this, this.handleSiteRequireApplication)} /> <label - class="form-check-label" + className="form-check-label" htmlFor="create-site-require-application" > {i18n.t("require_registration_application")} @@ -380,10 +382,10 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { </div> </div> </div> - <div class="form-group row"> - <div class="col-12"> + <div className="form-group row"> + <div className="col-12"> <label - class="form-check-label mr-2" + className="form-check-label mr-2" htmlFor="create-site-default-theme" > {i18n.t("theme")} @@ -392,19 +394,21 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { id="create-site-default-theme" value={toUndefined(this.state.siteForm.default_theme)} onChange={linkEvent(this, this.handleSiteDefaultTheme)} - class="custom-select w-auto" + className="custom-select w-auto" > <option value="browser">{i18n.t("browser_default")}</option> {this.state.themeList.unwrapOr([]).map(theme => ( - <option value={theme}>{theme}</option> + <option key={theme} value={theme}> + {theme} + </option> ))} </select> </div> </div> {this.props.showLocal && ( <form className="form-group row"> - <label class="col-sm-3">{i18n.t("listing_type")}</label> - <div class="col-sm-9"> + <label className="col-sm-3">{i18n.t("listing_type")}</label> + <div className="col-sm-9"> <ListingTypeSelect type_={ ListingType[ @@ -420,18 +424,18 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { </div> </form> )} - <div class="form-group row"> - <div class="col-12"> - <div class="form-check"> + <div className="form-group row"> + <div className="col-12"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="create-site-private-instance" type="checkbox" checked={toUndefined(this.state.siteForm.private_instance)} onChange={linkEvent(this, this.handleSitePrivateInstance)} /> <label - class="form-check-label" + className="form-check-label" htmlFor="create-site-private-instance" > {i18n.t("private_instance")} @@ -439,11 +443,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { </div> </div> </div> - <div class="form-group row"> - <div class="col-12"> - <div class="form-check"> + <div className="form-group row"> + <div className="col-12"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="create-site-hide-modlog-mod-names" type="checkbox" checked={toUndefined( @@ -452,7 +456,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { onChange={linkEvent(this, this.handleSiteHideModlogModNames)} /> <label - class="form-check-label" + className="form-check-label" htmlFor="create-site-hide-modlog-mod-names" > {i18n.t("hide_modlog_mod_names")} @@ -460,11 +464,11 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { </div> </div> </div> - <div class="form-group row"> - <div class="col-12"> + <div className="form-group row"> + <div className="col-12"> <button type="submit" - class="btn btn-secondary mr-2" + className="btn btn-secondary mr-2" disabled={this.state.loading} > {this.state.loading ? ( @@ -478,7 +482,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { {this.props.site.isSome() && ( <button type="button" - class="btn btn-secondary" + className="btn btn-secondary" onClick={linkEvent(this, this.handleCancel)} > {i18n.t("cancel")} @@ -493,8 +497,8 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { handleCreateSiteSubmit(i: SiteForm, event: any) { event.preventDefault(); - i.state.loading = true; - i.state.siteForm.auth = auth().unwrap(); + i.setState({ loading: true }); + i.setState(s => ((s.siteForm.auth = auth().unwrap()), s)); if (i.props.site.isSome()) { WebSocketService.Instance.send(wsClient.editSite(i.state.siteForm)); @@ -531,18 +535,15 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { } handleSiteSidebarChange(val: string) { - this.state.siteForm.sidebar = Some(val); - this.setState(this.state); + this.setState(s => ((s.siteForm.sidebar = Some(val)), s)); } handleSiteLegalInfoChange(val: string) { - this.state.siteForm.legal_information = Some(val); - this.setState(this.state); + this.setState(s => ((s.siteForm.legal_information = Some(val)), s)); } handleSiteApplicationQuestionChange(val: string) { - this.state.siteForm.application_question = Some(val); - this.setState(this.state); + this.setState(s => ((s.siteForm.application_question = Some(val)), s)); } handleSiteDescChange(i: SiteForm, event: any) { @@ -600,29 +601,29 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> { } handleIconUpload(url: string) { - this.state.siteForm.icon = Some(url); - this.setState(this.state); + this.setState(s => ((s.siteForm.icon = Some(url)), s)); } handleIconRemove() { - this.state.siteForm.icon = Some(""); - this.setState(this.state); + this.setState(s => ((s.siteForm.icon = Some("")), s)); } handleBannerUpload(url: string) { - this.state.siteForm.banner = Some(url); - this.setState(this.state); + this.setState(s => ((s.siteForm.banner = Some(url)), s)); } handleBannerRemove() { - this.state.siteForm.banner = Some(""); - this.setState(this.state); + this.setState(s => ((s.siteForm.banner = Some("")), s)); } handleDefaultPostListingTypeChange(val: ListingType) { - this.state.siteForm.default_post_listing_type = Some( - ListingType[ListingType[val]] + this.setState( + s => ( + (s.siteForm.default_post_listing_type = Some( + ListingType[ListingType[val]] + )), + s + ) ); - this.setState(this.state); } } diff --git a/src/shared/components/home/site-sidebar.tsx b/src/shared/components/home/site-sidebar.tsx index 79a8a4306..d867c8d56 100644 --- a/src/shared/components/home/site-sidebar.tsx +++ b/src/shared/components/home/site-sidebar.tsx @@ -38,11 +38,11 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> { render() { let site = this.props.site; return ( - <div class="card border-secondary mb-3"> - <div class="card-body"> + <div className="card border-secondary mb-3"> + <div className="card-body"> {!this.state.showEdit ? ( <div> - <div class="mb-2"> + <div className="mb-2"> {this.siteName()} {this.props.admins.isSome() && this.adminButtons()} </div> @@ -69,10 +69,10 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> { siteName() { let site = this.props.site; return ( - <h5 class="mb-0 d-inline"> + <h5 className="mb-0 d-inline"> {site.name} <button - class="btn btn-sm text-muted" + className="btn btn-sm text-muted" onClick={linkEvent(this, this.handleCollapseSidebar)} aria-label={i18n.t("collapse")} data-tippy-content={i18n.t("collapse")} @@ -114,10 +114,10 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> { adminButtons() { return ( amAdmin(this.props.admins) && ( - <ul class="list-inline mb-1 text-muted font-weight-bold"> + <ul className="list-inline mb-1 text-muted font-weight-bold"> <li className="list-inline-item-action"> <button - class="btn btn-link d-inline-block text-muted" + className="btn btn-link d-inline-block text-muted" onClick={linkEvent(this, this.handleEditClick)} aria-label={i18n.t("edit")} data-tippy-content={i18n.t("edit")} @@ -138,10 +138,10 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> { admins(admins: PersonViewSafe[]) { return ( - <ul class="mt-1 list-inline small mb-0"> - <li class="list-inline-item">{i18n.t("admins")}:</li> + <ul className="mt-1 list-inline small mb-0"> + <li className="list-inline-item">{i18n.t("admins")}:</li> {admins.map(av => ( - <li class="list-inline-item"> + <li key={av.person.id} className="list-inline-item"> <PersonListing person={av.person} /> </li> ))} @@ -153,7 +153,7 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> { let counts = siteAggregates; let online = this.props.online.unwrapOr(1); return ( - <ul class="my-2 list-inline"> + <ul className="my-2 list-inline"> <li className="list-inline-item badge badge-secondary"> {i18n.t("number_online", { count: online, @@ -246,22 +246,18 @@ export class SiteSidebar extends Component<SiteSidebarProps, SiteSidebarState> { } handleCollapseSidebar(i: SiteSidebar) { - i.state.collapsed = !i.state.collapsed; - i.setState(i.state); + i.setState({ collapsed: !i.state.collapsed }); } handleEditClick(i: SiteSidebar) { - i.state.showEdit = true; - i.setState(i.state); + i.setState({ showEdit: true }); } handleEditSite() { - this.state.showEdit = false; - this.setState(this.state); + this.setState({ showEdit: false }); } handleEditCancel() { - this.state.showEdit = false; - this.setState(this.state); + this.setState({ showEdit: false }); } } diff --git a/src/shared/components/modlog.tsx b/src/shared/components/modlog.tsx index e8192d27c..9eed9c9a9 100644 --- a/src/shared/components/modlog.tsx +++ b/src/shared/components/modlog.tsx @@ -114,31 +114,41 @@ export class Modlog extends Component<any, ModlogState> { filter_user: None, filter_mod: None, }; + constructor(props: any, context: any) { super(props, context); this.state = this.emptyState; this.handlePageChange = this.handlePageChange.bind(this); - this.state.communityId = this.props.match.params.community_id - ? Some(Number(this.props.match.params.community_id)) - : None; - this.parseMessage = this.parseMessage.bind(this); this.subscription = wsSubscribe(this.parseMessage); + this.state = { + ...this.state, + communityId: this.props.match.params.community_id + ? Some(Number(this.props.match.params.community_id)) + : None, + }; + // Only fetch the data if coming from another route if (this.isoData.path == this.context.router.route.match.url) { - this.state.res = Some(this.isoData.routeData[0] as GetModlogResponse); + this.state = { + ...this.state, + res: Some(this.isoData.routeData[0] as GetModlogResponse), + }; if (this.isoData.routeData[1]) { // Getting the moderators let communityRes = Some( this.isoData.routeData[1] as GetCommunityResponse ); - this.state.communityMods = communityRes.map(c => c.moderators); + this.state = { + ...this.state, + communityMods: communityRes.map(c => c.moderators), + }; } - this.state.loading = false; + this.state = { ...this.state, loading: false }; } else { this.refetch(); } @@ -300,219 +310,283 @@ export class Modlog extends Component<any, ModlogState> { switch (i.type_) { case ModlogActionType.ModRemovePost: { let mrpv = i.view as ModRemovePostView; - return [ - mrpv.mod_remove_post.removed.unwrapOr(false) - ? "Removed " - : "Restored ", - <span> - Post <Link to={`/post/${mrpv.post.id}`}>{mrpv.post.name}</Link> - </span>, - mrpv.mod_remove_post.reason.match({ - some: reason => <div>reason: {reason}</div>, - none: <></>, - }), - ]; + return ( + <> + <span> + {mrpv.mod_remove_post.removed.unwrapOr(false) + ? "Removed " + : "Restored "} + </span> + <span> + Post <Link to={`/post/${mrpv.post.id}`}>{mrpv.post.name}</Link> + </span> + <span> + {mrpv.mod_remove_post.reason.match({ + some: reason => <div>reason: {reason}</div>, + none: <></>, + })} + </span> + </> + ); } case ModlogActionType.ModLockPost: { let mlpv = i.view as ModLockPostView; - return [ - mlpv.mod_lock_post.locked.unwrapOr(false) ? "Locked " : "Unlocked ", - <span> - Post <Link to={`/post/${mlpv.post.id}`}>{mlpv.post.name}</Link> - </span>, - ]; + return ( + <> + <span> + {mlpv.mod_lock_post.locked.unwrapOr(false) + ? "Locked " + : "Unlocked "} + </span> + <span> + Post <Link to={`/post/${mlpv.post.id}`}>{mlpv.post.name}</Link> + </span> + </> + ); } case ModlogActionType.ModStickyPost: { let mspv = i.view as ModStickyPostView; - return [ - mspv.mod_sticky_post.stickied.unwrapOr(false) - ? "Stickied " - : "Unstickied ", - <span> - Post <Link to={`/post/${mspv.post.id}`}>{mspv.post.name}</Link> - </span>, - ]; + return ( + <> + <span> + {mspv.mod_sticky_post.stickied.unwrapOr(false) + ? "Stickied " + : "Unstickied "} + </span> + <span> + Post <Link to={`/post/${mspv.post.id}`}>{mspv.post.name}</Link> + </span> + </> + ); } case ModlogActionType.ModRemoveComment: { let mrc = i.view as ModRemoveCommentView; - return [ - mrc.mod_remove_comment.removed.unwrapOr(false) - ? "Removed " - : "Restored ", - <span> - Comment{" "} - <Link to={`/post/${mrc.post.id}/comment/${mrc.comment.id}`}> - {mrc.comment.content} - </Link> - </span>, - <span> - {" "} - by <PersonListing person={mrc.commenter} /> - </span>, - mrc.mod_remove_comment.reason.match({ - some: reason => <div>reason: {reason}</div>, - none: <></>, - }), - ]; + return ( + <> + <span> + {mrc.mod_remove_comment.removed.unwrapOr(false) + ? "Removed " + : "Restored "} + </span> + <span> + Comment{" "} + <Link to={`/post/${mrc.post.id}/comment/${mrc.comment.id}`}> + {mrc.comment.content} + </Link> + </span> + <span> + {" "} + by <PersonListing person={mrc.commenter} /> + </span> + <span> + {mrc.mod_remove_comment.reason.match({ + some: reason => <div>reason: {reason}</div>, + none: <></>, + })} + </span> + </> + ); } case ModlogActionType.ModRemoveCommunity: { let mrco = i.view as ModRemoveCommunityView; - return [ - mrco.mod_remove_community.removed.unwrapOr(false) - ? "Removed " - : "Restored ", - <span> - Community <CommunityLink community={mrco.community} /> - </span>, - mrco.mod_remove_community.reason.match({ - some: reason => <div>reason: {reason}</div>, - none: <></>, - }), - mrco.mod_remove_community.expires.match({ - some: expires => ( - <div>expires: {moment.utc(expires).fromNow()}</div> - ), - none: <></>, - }), - ]; + return ( + <> + <span> + {mrco.mod_remove_community.removed.unwrapOr(false) + ? "Removed " + : "Restored "} + </span> + <span> + Community <CommunityLink community={mrco.community} /> + </span> + <span> + {mrco.mod_remove_community.reason.match({ + some: reason => <div>reason: {reason}</div>, + none: <></>, + })} + </span> + <span> + {mrco.mod_remove_community.expires.match({ + some: expires => ( + <div>expires: {moment.utc(expires).fromNow()}</div> + ), + none: <></>, + })} + </span> + </> + ); } case ModlogActionType.ModBanFromCommunity: { let mbfc = i.view as ModBanFromCommunityView; - return [ - <span> - {mbfc.mod_ban_from_community.banned.unwrapOr(false) - ? "Banned " - : "Unbanned "}{" "} - </span>, - <span> - <PersonListing person={mbfc.banned_person} /> - </span>, - <span> from the community </span>, - <span> - <CommunityLink community={mbfc.community} /> - </span>, - mbfc.mod_ban_from_community.reason.match({ - some: reason => <div>reason: {reason}</div>, - none: <></>, - }), - mbfc.mod_ban_from_community.expires.match({ - some: expires => ( - <div>expires: {moment.utc(expires).fromNow()}</div> - ), - none: <></>, - }), - ]; + return ( + <> + <span> + {mbfc.mod_ban_from_community.banned.unwrapOr(false) + ? "Banned " + : "Unbanned "}{" "} + </span> + <span> + <PersonListing person={mbfc.banned_person} /> + </span> + <span> from the community </span> + <span> + <CommunityLink community={mbfc.community} /> + </span> + <span> + {mbfc.mod_ban_from_community.reason.match({ + some: reason => <div>reason: {reason}</div>, + none: <></>, + })} + </span> + <span> + {mbfc.mod_ban_from_community.expires.match({ + some: expires => ( + <div>expires: {moment.utc(expires).fromNow()}</div> + ), + none: <></>, + })} + </span> + </> + ); } case ModlogActionType.ModAddCommunity: { let mac = i.view as ModAddCommunityView; - return [ - <span> - {mac.mod_add_community.removed.unwrapOr(false) - ? "Removed " - : "Appointed "}{" "} - </span>, - <span> - <PersonListing person={mac.modded_person} /> - </span>, - <span> as a mod to the community </span>, - <span> - <CommunityLink community={mac.community} /> - </span>, - ]; + return ( + <> + <span> + {mac.mod_add_community.removed.unwrapOr(false) + ? "Removed " + : "Appointed "}{" "} + </span> + <span> + <PersonListing person={mac.modded_person} /> + </span> + <span> as a mod to the community </span> + <span> + <CommunityLink community={mac.community} /> + </span> + </> + ); } case ModlogActionType.ModTransferCommunity: { let mtc = i.view as ModTransferCommunityView; - return [ - <span> - {mtc.mod_transfer_community.removed.unwrapOr(false) - ? "Removed " - : "Transferred "}{" "} - </span>, - <span> - <CommunityLink community={mtc.community} /> - </span>, - <span> to </span>, - <span> - <PersonListing person={mtc.modded_person} /> - </span>, - ]; + return ( + <> + <span> + {mtc.mod_transfer_community.removed.unwrapOr(false) + ? "Removed " + : "Transferred "}{" "} + </span> + <span> + <CommunityLink community={mtc.community} /> + </span> + <span> to </span> + <span> + <PersonListing person={mtc.modded_person} /> + </span> + </> + ); } case ModlogActionType.ModBan: { let mb = i.view as ModBanView; - return [ - <span> - {mb.mod_ban.banned.unwrapOr(false) ? "Banned " : "Unbanned "}{" "} - </span>, - <span> - <PersonListing person={mb.banned_person} /> - </span>, - mb.mod_ban.reason.match({ - some: reason => <div>reason: {reason}</div>, - none: <></>, - }), - mb.mod_ban.expires.match({ - some: expires => ( - <div>expires: {moment.utc(expires).fromNow()}</div> - ), - none: <></>, - }), - ]; + return ( + <> + <span> + {mb.mod_ban.banned.unwrapOr(false) ? "Banned " : "Unbanned "}{" "} + </span> + <span> + <PersonListing person={mb.banned_person} /> + </span> + <span> + {mb.mod_ban.reason.match({ + some: reason => <div>reason: {reason}</div>, + none: <></>, + })} + </span> + <span> + {mb.mod_ban.expires.match({ + some: expires => ( + <div>expires: {moment.utc(expires).fromNow()}</div> + ), + none: <></>, + })} + </span> + </> + ); } case ModlogActionType.ModAdd: { let ma = i.view as ModAddView; - return [ - <span> - {ma.mod_add.removed.unwrapOr(false) ? "Removed " : "Appointed "}{" "} - </span>, - <span> - <PersonListing person={ma.modded_person} /> - </span>, - <span> as an admin </span>, - ]; + return ( + <> + <span> + {ma.mod_add.removed.unwrapOr(false) ? "Removed " : "Appointed "}{" "} + </span> + <span> + <PersonListing person={ma.modded_person} /> + </span> + <span> as an admin </span> + </> + ); } case ModlogActionType.AdminPurgePerson: { let ap = i.view as AdminPurgePersonView; - return [ - <span>Purged a Person</span>, - ap.admin_purge_person.reason.match({ - some: reason => <div>reason: {reason}</div>, - none: <></>, - }), - ]; + return ( + <> + <span>Purged a Person</span> + <span> + {ap.admin_purge_person.reason.match({ + some: reason => <div>reason: {reason}</div>, + none: <></>, + })} + </span> + </> + ); } case ModlogActionType.AdminPurgeCommunity: { let ap = i.view as AdminPurgeCommunityView; - return [ - <span>Purged a Community</span>, - ap.admin_purge_community.reason.match({ - some: reason => <div>reason: {reason}</div>, - none: <></>, - }), - ]; + return ( + <> + <span>Purged a Community</span> + <span> + {ap.admin_purge_community.reason.match({ + some: reason => <div>reason: {reason}</div>, + none: <></>, + })} + </span> + </> + ); } case ModlogActionType.AdminPurgePost: { let ap = i.view as AdminPurgePostView; - return [ - <span>Purged a Post from from </span>, - <CommunityLink community={ap.community} />, - ap.admin_purge_post.reason.match({ - some: reason => <div>reason: {reason}</div>, - none: <></>, - }), - ]; + return ( + <> + <span>Purged a Post from from </span> + <CommunityLink community={ap.community} /> + <span> + {ap.admin_purge_post.reason.match({ + some: reason => <div>reason: {reason}</div>, + none: <></>, + })} + </span> + </> + ); } case ModlogActionType.AdminPurgeComment: { let ap = i.view as AdminPurgeCommentView; - return [ - <span> - Purged a Comment from{" "} - <Link to={`/post/${ap.post.id}`}>{ap.post.name}</Link> - </span>, - ap.admin_purge_comment.reason.match({ - some: reason => <div>reason: {reason}</div>, - none: <></>, - }), - ]; + return ( + <> + <span> + Purged a Comment from{" "} + <Link to={`/post/${ap.post.id}`}>{ap.post.name}</Link> + </span> + <span> + {ap.admin_purge_comment.reason.match({ + some: reason => <div>reason: {reason}</div>, + none: <></>, + })} + </span> + </> + ); } default: return <div />; @@ -525,7 +599,7 @@ export class Modlog extends Component<any, ModlogState> { return ( <tbody> {combined.map(i => ( - <tr> + <tr key={i.id}> <td> <MomentTime published={i.when_} updated={None} /> </td> @@ -593,67 +667,75 @@ export class Modlog extends Component<any, ModlogState> { })} <span>{i18n.t("modlog")}</span> </h5> - <form className="form-inline mr-2"> - <select - value={this.state.filter_action} - onChange={linkEvent(this, this.handleFilterActionChange)} - className="custom-select col-4 mb-2" - aria-label="action" - > - <option disabled aria-hidden="true"> - {i18n.t("filter_by_action")} - </option> - <option value={ModlogActionType.All}>{i18n.t("all")}</option> - <option value={ModlogActionType.ModRemovePost}> - Removing Posts - </option> - <option value={ModlogActionType.ModLockPost}> - Locking Posts - </option> - <option value={ModlogActionType.ModStickyPost}> - Stickying Posts - </option> - <option value={ModlogActionType.ModRemoveComment}> - Removing Comments - </option> - <option value={ModlogActionType.ModRemoveCommunity}> - Removing Communities - </option> - <option value={ModlogActionType.ModBanFromCommunity}> - Banning From Communities - </option> - <option value={ModlogActionType.ModAddCommunity}> - Adding Mod to Community - </option> - <option value={ModlogActionType.ModTransferCommunity}> - Transfering Communities - </option> - <option value={ModlogActionType.ModAdd}> - Adding Mod to Site - </option> - <option value={ModlogActionType.ModBan}> - Banning From Site - </option> - </select> + <div className="form-row"> + <div className="form-group col-sm-6"> + <select + value={this.state.filter_action} + onChange={linkEvent(this, this.handleFilterActionChange)} + className="custom-select mb-2" + aria-label="action" + > + <option disabled aria-hidden="true"> + {i18n.t("filter_by_action")} + </option> + <option value={ModlogActionType.All}>{i18n.t("all")}</option> + <option value={ModlogActionType.ModRemovePost}> + Removing Posts + </option> + <option value={ModlogActionType.ModLockPost}> + Locking Posts + </option> + <option value={ModlogActionType.ModStickyPost}> + Stickying Posts + </option> + <option value={ModlogActionType.ModRemoveComment}> + Removing Comments + </option> + <option value={ModlogActionType.ModRemoveCommunity}> + Removing Communities + </option> + <option value={ModlogActionType.ModBanFromCommunity}> + Banning From Communities + </option> + <option value={ModlogActionType.ModAddCommunity}> + Adding Mod to Community + </option> + <option value={ModlogActionType.ModTransferCommunity}> + Transfering Communities + </option> + <option value={ModlogActionType.ModAdd}> + Adding Mod to Site + </option> + <option value={ModlogActionType.ModBan}> + Banning From Site + </option> + </select> + </div> {this.state.siteRes.site_view.match({ some: site_view => !site_view.site.hide_modlog_mod_names.unwrapOr(false) && ( - <select - id="filter-mod" - value={toUndefined(this.state.filter_mod)} - > - <option>{i18n.t("filter_by_mod")}</option> - </select> + <div className="form-group col-sm-6"> + <select + id="filter-mod" + className="form-control" + value={toUndefined(this.state.filter_mod)} + > + <option>{i18n.t("filter_by_mod")}</option> + </select> + </div> ), none: <></>, })} - <select - id="filter-user" - value={toUndefined(this.state.filter_user)} - > - <option>{i18n.t("filter_by_user")}</option> - </select> - </form> + <div className="form-group col-sm-6"> + <select + id="filter-user" + className="form-control" + value={toUndefined(this.state.filter_user)} + > + <option>{i18n.t("filter_by_user")}</option> + </select> + </div> + </div> <div className="table-responsive"> <table id="modlog_table" className="table table-sm table-hover"> <thead className="pointer"> @@ -719,8 +801,7 @@ export class Modlog extends Component<any, ModlogState> { this.userChoices.passedElement.element.addEventListener( "choice", (e: any) => { - this.state.filter_user = Some(Number(e.detail.choice.value)); - this.setState(this.state); + this.setState({ filter_user: Some(Number(e.detail.choice.value)) }); this.refetch(); }, false @@ -759,8 +840,7 @@ export class Modlog extends Component<any, ModlogState> { this.modChoices.passedElement.element.addEventListener( "choice", (e: any) => { - this.state.filter_mod = Some(Number(e.detail.choice.value)); - this.setState(this.state); + this.setState({ filter_mod: Some(Number(e.detail.choice.value)) }); this.refetch(); }, false @@ -829,14 +909,16 @@ export class Modlog extends Component<any, ModlogState> { return; } else if (op == UserOperation.GetModlog) { let data = wsJsonToRes<GetModlogResponse>(msg, GetModlogResponse); - this.state.loading = false; window.scrollTo(0, 0); - this.state.res = Some(data); - this.setState(this.state); + this.setState({ res: Some(data), loading: false }); + this.setupUserFilter(); + this.setupModFilter(); } else if (op == UserOperation.GetCommunity) { let data = wsJsonToRes<GetCommunityResponse>(msg, GetCommunityResponse); - this.state.communityMods = Some(data.moderators); - this.state.communityName = Some(data.community_view.community.name); + this.setState({ + communityMods: Some(data.moderators), + communityName: Some(data.community_view.community.name), + }); } } } diff --git a/src/shared/components/person/inbox.tsx b/src/shared/components/person/inbox.tsx index 2a8a7b298..858364f94 100644 --- a/src/shared/components/person/inbox.tsx +++ b/src/shared/components/person/inbox.tsx @@ -127,15 +127,19 @@ export class Inbox extends Component<any, InboxState> { // Only fetch the data if coming from another route if (this.isoData.path == this.context.router.route.match.url) { - this.state.replies = - (this.isoData.routeData[0] as GetRepliesResponse).replies || []; - this.state.mentions = - (this.isoData.routeData[1] as GetPersonMentionsResponse).mentions || []; - this.state.messages = - (this.isoData.routeData[2] as PrivateMessagesResponse) - .private_messages || []; - this.state.combined = this.buildCombined(); - this.state.loading = false; + this.state = { + ...this.state, + replies: + (this.isoData.routeData[0] as GetRepliesResponse).replies || [], + mentions: + (this.isoData.routeData[1] as GetPersonMentionsResponse).mentions || + [], + messages: + (this.isoData.routeData[2] as PrivateMessagesResponse) + .private_messages || [], + loading: false, + }; + this.state = { ...this.state, combined: this.buildCombined() }; } else { this.refetch(); } @@ -166,21 +170,21 @@ export class Inbox extends Component<any, InboxState> { .ok() .map(a => `/feeds/inbox/${a}.xml`); return ( - <div class="container"> + <div className="container"> {this.state.loading ? ( <h5> <Spinner large /> </h5> ) : ( - <div class="row"> - <div class="col-12"> + <div className="row"> + <div className="col-12"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} description={None} image={None} /> - <h5 class="mb-2"> + <h5 className="mb-2"> {i18n.t("inbox")} {inboxRss.match({ some: rss => ( @@ -204,7 +208,7 @@ export class Inbox extends Component<any, InboxState> { 0 && this.state.unreadOrAll == UnreadOrAll.Unread && ( <button - class="btn btn-secondary mb-2" + className="btn btn-secondary mb-2" onClick={linkEvent(this, this.markAllAsRead)} > {i18n.t("mark_all_as_read")} @@ -230,7 +234,7 @@ export class Inbox extends Component<any, InboxState> { unreadOrAllRadios() { return ( - <div class="btn-group btn-group-toggle flex-wrap mb-2"> + <div className="btn-group btn-group-toggle flex-wrap mb-2"> <label className={`btn btn-outline-secondary pointer ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"} @@ -263,7 +267,7 @@ export class Inbox extends Component<any, InboxState> { messageTypeRadios() { return ( - <div class="btn-group btn-group-toggle flex-wrap mb-2"> + <div className="btn-group btn-group-toggle flex-wrap mb-2"> <label className={`btn btn-outline-secondary pointer ${this.state.messageType == MessageType.All && "active"} @@ -323,8 +327,8 @@ export class Inbox extends Component<any, InboxState> { selects() { return ( <div className="mb-2"> - <span class="mr-3">{this.unreadOrAllRadios()}</span> - <span class="mr-3">{this.messageTypeRadios()}</span> + <span className="mr-3">{this.unreadOrAllRadios()}</span> + <span className="mr-3">{this.messageTypeRadios()}</span> <CommentSortSelect sort={this.state.sort} onChange={this.handleSortChange} @@ -494,16 +498,12 @@ export class Inbox extends Component<any, InboxState> { } handleUnreadOrAllChange(i: Inbox, event: any) { - i.state.unreadOrAll = Number(event.target.value); - i.state.page = 1; - i.setState(i.state); + i.setState({ unreadOrAll: Number(event.target.value), page: 1 }); i.refetch(); } handleMessageTypeChange(i: Inbox, event: any) { - i.state.messageType = Number(event.target.value); - i.state.page = 1; - i.setState(i.state); + i.setState({ messageType: Number(event.target.value), page: 1 }); i.refetch(); } @@ -580,9 +580,7 @@ export class Inbox extends Component<any, InboxState> { } handleSortChange(val: CommentSortType) { - this.state.sort = val; - this.state.page = 1; - this.setState(this.state); + this.setState({ sort: val, page: 1 }); this.refetch(); } @@ -592,10 +590,8 @@ export class Inbox extends Component<any, InboxState> { auth: auth().unwrap(), }) ); - i.state.replies = []; - i.state.mentions = []; - i.state.messages = []; - i.state.combined = i.buildCombined(); + i.setState({ replies: [], mentions: [], messages: [] }); + i.setState({ combined: i.buildCombined() }); UserService.Instance.unreadInboxCountSub.next(0); window.scrollTo(0, 0); i.setState(i.state); @@ -620,31 +616,27 @@ export class Inbox extends Component<any, InboxState> { this.refetch(); } else if (op == UserOperation.GetReplies) { let data = wsJsonToRes<GetRepliesResponse>(msg, GetRepliesResponse); - this.state.replies = data.replies; - this.state.combined = this.buildCombined(); - this.state.loading = false; + this.setState({ replies: data.replies }); + this.setState({ combined: this.buildCombined(), loading: false }); window.scrollTo(0, 0); - this.setState(this.state); setupTippy(); } else if (op == UserOperation.GetPersonMentions) { let data = wsJsonToRes<GetPersonMentionsResponse>( msg, GetPersonMentionsResponse ); - this.state.mentions = data.mentions; - this.state.combined = this.buildCombined(); + this.setState({ mentions: data.mentions }); + this.setState({ combined: this.buildCombined() }); window.scrollTo(0, 0); - this.setState(this.state); setupTippy(); } else if (op == UserOperation.GetPrivateMessages) { let data = wsJsonToRes<PrivateMessagesResponse>( msg, PrivateMessagesResponse ); - this.state.messages = data.private_messages; - this.state.combined = this.buildCombined(); + this.setState({ messages: data.private_messages }); + this.setState({ combined: this.buildCombined() }); window.scrollTo(0, 0); - this.setState(this.state); setupTippy(); } else if (op == UserOperation.EditPrivateMessage) { let data = wsJsonToRes<PrivateMessageResponse>( @@ -696,7 +688,9 @@ export class Inbox extends Component<any, InboxState> { if (found) { let combinedView = this.state.combined.find( - i => i.id == data.private_message_view.private_message.id + i => + i.id == data.private_message_view.private_message.id && + i.type_ == ReplyEnum.Message ).view as PrivateMessageView; found.private_message.updated = combinedView.private_message.updated = data.private_message_view.private_message.updated; @@ -706,14 +700,18 @@ export class Inbox extends Component<any, InboxState> { this.state.unreadOrAll == UnreadOrAll.Unread && data.private_message_view.private_message.read ) { - this.state.messages = this.state.messages.filter( - r => - r.private_message.id !== - data.private_message_view.private_message.id - ); - this.state.combined = this.state.combined.filter( - r => r.id !== data.private_message_view.private_message.id - ); + this.setState({ + messages: this.state.messages.filter( + r => + r.private_message.id !== + data.private_message_view.private_message.id + ), + }); + this.setState({ + combined: this.state.combined.filter( + r => r.id !== data.private_message_view.private_message.id + ), + }); } else { found.private_message.read = combinedView.private_message.read = data.private_message_view.private_message.read; @@ -733,7 +731,6 @@ export class Inbox extends Component<any, InboxState> { this.setState(this.state); } else if (op == UserOperation.MarkCommentReplyAsRead) { let data = wsJsonToRes<CommentReplyResponse>(msg, CommentReplyResponse); - console.log(data); let found = this.state.replies.find( c => c.comment_reply.id == data.comment_reply_view.comment_reply.id @@ -741,7 +738,9 @@ export class Inbox extends Component<any, InboxState> { if (found) { let combinedView = this.state.combined.find( - i => i.id == data.comment_reply_view.comment_reply.id + i => + i.id == data.comment_reply_view.comment_reply.id && + i.type_ == ReplyEnum.Reply ).view as CommentReplyView; found.comment.content = combinedView.comment.content = data.comment_reply_view.comment.content; @@ -763,12 +762,17 @@ export class Inbox extends Component<any, InboxState> { this.state.unreadOrAll == UnreadOrAll.Unread && data.comment_reply_view.comment_reply.read ) { - this.state.replies = this.state.replies.filter( - r => r.comment_reply.id !== data.comment_reply_view.comment_reply.id - ); - this.state.combined = this.state.combined.filter( - r => r.id !== data.comment_reply_view.comment_reply.id - ); + this.setState({ + replies: this.state.replies.filter( + r => + r.comment_reply.id !== data.comment_reply_view.comment_reply.id + ), + }); + this.setState({ + combined: this.state.combined.filter( + r => r.id !== data.comment_reply_view.comment_reply.id + ), + }); } else { found.comment_reply.read = combinedView.comment_reply.read = data.comment_reply_view.comment_reply.read; @@ -786,7 +790,9 @@ export class Inbox extends Component<any, InboxState> { if (found) { let combinedView = this.state.combined.find( - i => i.id == data.person_mention_view.person_mention.id + i => + i.id == data.person_mention_view.person_mention.id && + i.type_ == ReplyEnum.Mention ).view as PersonMentionView; found.comment.content = combinedView.comment.content = data.person_mention_view.comment.content; @@ -808,13 +814,18 @@ export class Inbox extends Component<any, InboxState> { this.state.unreadOrAll == UnreadOrAll.Unread && data.person_mention_view.person_mention.read ) { - this.state.mentions = this.state.mentions.filter( - r => - r.person_mention.id !== data.person_mention_view.person_mention.id - ); - this.state.combined = this.state.combined.filter( - r => r.id !== data.person_mention_view.person_mention.id - ); + this.setState({ + mentions: this.state.mentions.filter( + r => + r.person_mention.id !== + data.person_mention_view.person_mention.id + ), + }); + this.setState({ + combined: this.state.combined.filter( + r => r.id !== data.person_mention_view.person_mention.id + ), + }); } else { // TODO test to make sure these mentions are getting marked as read found.person_mention.read = combinedView.person_mention.read = diff --git a/src/shared/components/person/password-change.tsx b/src/shared/components/person/password-change.tsx index 8120fe976..42a287e6d 100644 --- a/src/shared/components/person/password-change.tsx +++ b/src/shared/components/person/password-change.tsx @@ -66,15 +66,15 @@ export class PasswordChange extends Component<any, State> { render() { return ( - <div class="container"> + <div className="container"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} description={None} image={None} /> - <div class="row"> - <div class="col-12 col-lg-6 offset-lg-3 mb-4"> + <div className="row"> + <div className="col-12 col-lg-6 offset-lg-3 mb-4"> <h5>{i18n.t("password_change")}</h5> {this.passwordChangeForm()} </div> @@ -86,41 +86,41 @@ export class PasswordChange extends Component<any, State> { passwordChangeForm() { return ( <form onSubmit={linkEvent(this, this.handlePasswordChangeSubmit)}> - <div class="form-group row"> - <label class="col-sm-2 col-form-label" htmlFor="new-password"> + <div className="form-group row"> + <label className="col-sm-2 col-form-label" htmlFor="new-password"> {i18n.t("new_password")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <input id="new-password" type="password" value={this.state.passwordChangeForm.password} onInput={linkEvent(this, this.handlePasswordChange)} - class="form-control" + className="form-control" required maxLength={60} /> </div> </div> - <div class="form-group row"> - <label class="col-sm-2 col-form-label" htmlFor="verify-password"> + <div className="form-group row"> + <label className="col-sm-2 col-form-label" htmlFor="verify-password"> {i18n.t("verify_password")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <input id="verify-password" type="password" value={this.state.passwordChangeForm.password_verify} onInput={linkEvent(this, this.handleVerifyPasswordChange)} - class="form-control" + className="form-control" required maxLength={60} /> </div> </div> - <div class="form-group row"> - <div class="col-sm-10"> - <button type="submit" class="btn btn-secondary"> + <div className="form-group row"> + <div className="col-sm-10"> + <button type="submit" className="btn btn-secondary"> {this.state.loading ? ( <Spinner /> ) : ( @@ -145,8 +145,7 @@ export class PasswordChange extends Component<any, State> { handlePasswordChangeSubmit(i: PasswordChange, event: any) { event.preventDefault(); - i.state.loading = true; - i.setState(i.state); + i.setState({ loading: true }); WebSocketService.Instance.send( wsClient.passwordChange(i.state.passwordChangeForm) @@ -158,13 +157,11 @@ export class PasswordChange extends Component<any, State> { console.log(msg); if (msg.error) { toast(i18n.t(msg.error), "danger"); - this.state.loading = false; - this.setState(this.state); + this.setState({ loading: false }); return; } else if (op == UserOperation.PasswordChange) { let data = wsJsonToRes<LoginResponse>(msg, LoginResponse); - this.state = this.emptyState; - this.setState(this.state); + this.setState(this.emptyState); UserService.Instance.login(data); this.props.history.push("/"); } diff --git a/src/shared/components/person/person-details.tsx b/src/shared/components/person/person-details.tsx index 6ce7a8b8d..8eaa5f0ac 100644 --- a/src/shared/components/person/person-details.tsx +++ b/src/shared/components/person/person-details.tsx @@ -150,7 +150,10 @@ export class PersonDetails extends Component<PersonDetailsProps, any> { return ( <div> - {combined.map(i => [this.renderItemType(i), <hr class="my-3" />])} + {combined.map(i => [ + this.renderItemType(i), + <hr key={i.type_} className="my-3" />, + ])} </div> ); } @@ -187,7 +190,7 @@ export class PersonDetails extends Component<PersonDetailsProps, any> { enableDownvotes={this.props.enableDownvotes} enableNsfw={this.props.enableNsfw} /> - <hr class="my-3" /> + <hr className="my-3" /> </> ))} </div> diff --git a/src/shared/components/person/profile.tsx b/src/shared/components/person/profile.tsx index 9de6d0b96..0a8e4c09f 100644 --- a/src/shared/components/person/profile.tsx +++ b/src/shared/components/person/profile.tsx @@ -121,10 +121,11 @@ export class Profile extends Component<any, ProfileState> { // Only fetch the data if coming from another route if (this.isoData.path == this.context.router.route.match.url) { - this.state.personRes = Some( - this.isoData.routeData[0] as GetPersonDetailsResponse - ); - this.state.loading = false; + this.state = { + ...this.state, + personRes: Some(this.isoData.routeData[0] as GetPersonDetailsResponse), + loading: false, + }; } else { this.fetchUserData(); } @@ -162,11 +163,12 @@ export class Profile extends Component<any, ProfileState> { UserService.Instance.myUserInfo.match({ some: mui => this.state.personRes.match({ - some: res => { - this.state.personBlocked = mui.person_blocks - .map(a => a.target.id) - .includes(res.person_view.person.id); - }, + some: res => + this.setState({ + personBlocked: mui.person_blocks + .map(a => a.target.id) + .includes(res.person_view.person.id), + }), none: void 0, }), none: void 0, @@ -250,7 +252,7 @@ export class Profile extends Component<any, ProfileState> { render() { return ( - <div class="container"> + <div className="container"> {this.state.loading ? ( <h5> <Spinner large /> @@ -258,8 +260,8 @@ export class Profile extends Component<any, ProfileState> { ) : ( this.state.personRes.match({ some: res => ( - <div class="row"> - <div class="col-12 col-md-8"> + <div className="row"> + <div className="col-12 col-md-8"> <> <HtmlTags title={this.documentTitle} @@ -285,7 +287,7 @@ export class Profile extends Component<any, ProfileState> { </div> {!this.state.loading && ( - <div class="col-12 col-md-4"> + <div className="col-12 col-md-4"> {this.moderates()} {this.amCurrentUser && this.follows()} </div> @@ -301,7 +303,7 @@ export class Profile extends Component<any, ProfileState> { viewRadios() { return ( - <div class="btn-group btn-group-toggle flex-wrap mb-2"> + <div className="btn-group btn-group-toggle flex-wrap mb-2"> <label className={`btn btn-outline-secondary pointer ${this.state.view == PersonDetailsView.Overview && "active"} @@ -363,7 +365,7 @@ export class Profile extends Component<any, ProfileState> { return ( <div className="mb-2"> - <span class="mr-3">{this.viewRadios()}</span> + <span className="mr-3">{this.viewRadios()}</span> <SortSelect sort={this.state.sort} onChange={this.handleSortChange} @@ -406,14 +408,14 @@ export class Profile extends Component<any, ProfileState> { banner={pv.person.banner} icon={pv.person.avatar} /> - <div class="mb-3"> - <div class=""> - <div class="mb-0 d-flex flex-wrap"> + <div className="mb-3"> + <div className=""> + <div className="mb-0 d-flex flex-wrap"> <div> {pv.person.display_name && ( - <h5 class="mb-0">{pv.person.display_name}</h5> + <h5 className="mb-0">{pv.person.display_name}</h5> )} - <ul class="list-inline mb-2"> + <ul className="list-inline mb-2"> <li className="list-inline-item"> <PersonListing person={pv.person} @@ -531,7 +533,7 @@ export class Profile extends Component<any, ProfileState> { none: <></>, })} <div> - <ul class="list-inline mb-2"> + <ul className="list-inline mb-2"> <li className="list-inline-item badge badge-light"> {i18n.t("number_of_posts", { count: pv.counts.post_count, @@ -546,7 +548,7 @@ export class Profile extends Component<any, ProfileState> { </li> </ul> </div> - <div class="text-muted"> + <div className="text-muted"> {i18n.t("joined")}{" "} <MomentTime published={pv.person.published} @@ -581,33 +583,36 @@ export class Profile extends Component<any, ProfileState> { <> {this.state.showBanDialog && ( <form onSubmit={linkEvent(this, this.handleModBanSubmit)}> - <div class="form-group row col-12"> - <label class="col-form-label" htmlFor="profile-ban-reason"> + <div className="form-group row col-12"> + <label + className="col-form-label" + htmlFor="profile-ban-reason" + > {i18n.t("reason")} </label> <input type="text" id="profile-ban-reason" - class="form-control mr-2" + className="form-control mr-2" placeholder={i18n.t("reason")} value={toUndefined(this.state.banReason)} onInput={linkEvent(this, this.handleModBanReasonChange)} /> - <label class="col-form-label" htmlFor={`mod-ban-expires`}> + <label className="col-form-label" htmlFor={`mod-ban-expires`}> {i18n.t("expires")} </label> <input type="number" id={`mod-ban-expires`} - class="form-control mr-2" + className="form-control mr-2" placeholder={i18n.t("number_of_days")} value={toUndefined(this.state.banExpireDays)} onInput={linkEvent(this, this.handleModBanExpireDaysChange)} /> - <div class="form-group"> - <div class="form-check"> + <div className="form-group"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="mod-ban-remove-data" type="checkbox" checked={this.state.removeData} @@ -617,7 +622,7 @@ export class Profile extends Component<any, ProfileState> { )} /> <label - class="form-check-label" + className="form-check-label" htmlFor="mod-ban-remove-data" title={i18n.t("remove_content_more")} > @@ -631,10 +636,10 @@ export class Profile extends Component<any, ProfileState> { {/* <label class="col-form-label">Expires</label> */} {/* <input type="date" class="form-control mr-2" placeholder={i18n.t('expires')} value={this.state.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */} {/* </div> */} - <div class="form-group row"> + <div className="form-group row"> <button - type="cancel" - class="btn btn-secondary mr-2" + type="reset" + className="btn btn-secondary mr-2" aria-label={i18n.t("cancel")} onClick={linkEvent(this, this.handleModBanSubmitCancel)} > @@ -642,7 +647,7 @@ export class Profile extends Component<any, ProfileState> { </button> <button type="submit" - class="btn btn-secondary" + className="btn btn-secondary" aria-label={i18n.t("ban")} > {i18n.t("ban")} {pv.person.name} @@ -663,12 +668,12 @@ export class Profile extends Component<any, ProfileState> { .match({ some: moderates => { if (moderates.length > 0) { - <div class="card border-secondary mb-3"> - <div class="card-body"> + <div className="card border-secondary mb-3"> + <div className="card-body"> <h5>{i18n.t("moderates")}</h5> - <ul class="list-unstyled mb-0"> + <ul className="list-unstyled mb-0"> {moderates.map(cmv => ( - <li> + <li key={cmv.community.id}> <CommunityLink community={cmv.community} /> </li> ))} @@ -687,12 +692,12 @@ export class Profile extends Component<any, ProfileState> { .match({ some: follows => { if (follows.length > 0) { - <div class="card border-secondary mb-3"> - <div class="card-body"> + <div className="card border-secondary mb-3"> + <div className="card-body"> <h5>{i18n.t("subscribed")}</h5> - <ul class="list-unstyled mb-0"> + <ul className="list-unstyled mb-0"> {follows.map(cfv => ( - <li> + <li key={cfv.community.id}> <CommunityLink community={cfv.community} /> </li> ))} @@ -715,8 +720,7 @@ export class Profile extends Component<any, ProfileState> { this.props.history.push( `${typeView}/view/${viewStr}/sort/${sortStr}/page/${page}` ); - this.state.loading = true; - this.setState(this.state); + this.setState({ loading: true }); this.fetchUserData(); } @@ -736,29 +740,24 @@ export class Profile extends Component<any, ProfileState> { } handleModBanShow(i: Profile) { - i.state.showBanDialog = true; - i.setState(i.state); + i.setState({ showBanDialog: true }); } handleModBanReasonChange(i: Profile, event: any) { - i.state.banReason = event.target.value; - i.setState(i.state); + i.setState({ banReason: event.target.value }); } handleModBanExpireDaysChange(i: Profile, event: any) { - i.state.banExpireDays = event.target.value; - i.setState(i.state); + i.setState({ banExpireDays: event.target.value }); } handleModRemoveDataChange(i: Profile, event: any) { - i.state.removeData = event.target.checked; - i.setState(i.state); + i.setState({ removeData: event.target.checked }); } handleModBanSubmitCancel(i: Profile, event?: any) { event.preventDefault(); - i.state.showBanDialog = false; - i.setState(i.state); + i.setState({ showBanDialog: false }); } handleModBanSubmit(i: Profile, event?: any) { @@ -771,7 +770,7 @@ export class Profile extends Component<any, ProfileState> { // If its an unban, restore all their data let ban = !person.banned; if (ban == false) { - i.state.removeData = false; + i.setState({ removeData: false }); } let form = new BanPerson({ person_id: person.id, @@ -783,8 +782,7 @@ export class Profile extends Component<any, ProfileState> { }); WebSocketService.Instance.send(wsClient.banPerson(form)); - i.state.showBanDialog = false; - i.setState(i.state); + i.setState({ showBanDialog: false }); }, none: void 0, }); @@ -809,15 +807,12 @@ export class Profile extends Component<any, ProfileState> { msg, GetPersonDetailsResponse ); - this.state.personRes = Some(data); - this.state.loading = false; + this.setState({ personRes: Some(data), loading: false }); this.setPersonBlock(); - this.setState(this.state); restoreScrollPosition(this.context); } else if (op == UserOperation.AddAdmin) { let data = wsJsonToRes<AddAdminResponse>(msg, AddAdminResponse); - this.state.siteRes.admins = data.admins; - this.setState(this.state); + this.setState(s => ((s.siteRes.admins = data.admins), s)); } else if (op == UserOperation.CreateCommentLike) { let data = wsJsonToRes<CommentResponse>(msg, CommentResponse); createCommentLikeRes( diff --git a/src/shared/components/person/registration-applications.tsx b/src/shared/components/person/registration-applications.tsx index eec90319a..e2ef43467 100644 --- a/src/shared/components/person/registration-applications.tsx +++ b/src/shared/components/person/registration-applications.tsx @@ -75,10 +75,13 @@ export class RegistrationApplications extends Component< // Only fetch the data if coming from another route if (this.isoData.path == this.context.router.route.match.url) { - this.state.listRegistrationApplicationsResponse = Some( - this.isoData.routeData[0] as ListRegistrationApplicationsResponse - ); - this.state.loading = false; + this.state = { + ...this.state, + listRegistrationApplicationsResponse: Some( + this.isoData.routeData[0] as ListRegistrationApplicationsResponse + ), + loading: false, + }; } else { this.refetch(); } @@ -110,21 +113,21 @@ export class RegistrationApplications extends Component< render() { return ( - <div class="container"> + <div className="container"> {this.state.loading ? ( <h5> <Spinner large /> </h5> ) : ( - <div class="row"> - <div class="col-12"> + <div className="row"> + <div className="col-12"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} description={None} image={None} /> - <h5 class="mb-2">{i18n.t("registration_applications")}</h5> + <h5 className="mb-2">{i18n.t("registration_applications")}</h5> {this.selects()} {this.applicationList()} <Paginator @@ -140,7 +143,7 @@ export class RegistrationApplications extends Component< unreadOrAllRadios() { return ( - <div class="btn-group btn-group-toggle flex-wrap mb-2"> + <div className="btn-group btn-group-toggle flex-wrap mb-2"> <label className={`btn btn-outline-secondary pointer ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"} @@ -174,7 +177,7 @@ export class RegistrationApplications extends Component< selects() { return ( <div className="mb-2"> - <span class="mr-3">{this.unreadOrAllRadios()}</span> + <span className="mr-3">{this.unreadOrAllRadios()}</span> </div> ); } @@ -199,9 +202,7 @@ export class RegistrationApplications extends Component< } handleUnreadOrAllChange(i: RegistrationApplications, event: any) { - i.state.unreadOrAll = Number(event.target.value); - i.state.page = 1; - i.setState(i.state); + i.setState({ unreadOrAll: Number(event.target.value), page: 1 }); i.refetch(); } @@ -248,10 +249,11 @@ export class RegistrationApplications extends Component< msg, ListRegistrationApplicationsResponse ); - this.state.listRegistrationApplicationsResponse = Some(data); - this.state.loading = false; + this.setState({ + listRegistrationApplicationsResponse: Some(data), + loading: false, + }); window.scrollTo(0, 0); - this.setState(this.state); } else if (op == UserOperation.ApproveRegistrationApplication) { let data = wsJsonToRes<RegistrationApplicationResponse>( msg, diff --git a/src/shared/components/person/reports.tsx b/src/shared/components/person/reports.tsx index f8a641b55..ed1182fe2 100644 --- a/src/shared/components/person/reports.tsx +++ b/src/shared/components/person/reports.tsx @@ -104,14 +104,20 @@ export class Reports extends Component<any, ReportsState> { // Only fetch the data if coming from another route if (this.isoData.path == this.context.router.route.match.url) { - this.state.listCommentReportsResponse = Some( - this.isoData.routeData[0] as ListCommentReportsResponse - ); - this.state.listPostReportsResponse = Some( - this.isoData.routeData[1] as ListPostReportsResponse - ); - this.state.combined = this.buildCombined(); - this.state.loading = false; + this.state = { + ...this.state, + listCommentReportsResponse: Some( + this.isoData.routeData[0] as ListCommentReportsResponse + ), + listPostReportsResponse: Some( + this.isoData.routeData[1] as ListPostReportsResponse + ), + }; + this.state = { + ...this.state, + combined: this.buildCombined(), + loading: false, + }; } else { this.refetch(); } @@ -139,21 +145,21 @@ export class Reports extends Component<any, ReportsState> { render() { return ( - <div class="container"> + <div className="container"> {this.state.loading ? ( <h5> <Spinner large /> </h5> ) : ( - <div class="row"> - <div class="col-12"> + <div className="row"> + <div className="col-12"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} description={None} image={None} /> - <h5 class="mb-2">{i18n.t("reports")}</h5> + <h5 className="mb-2">{i18n.t("reports")}</h5> {this.selects()} {this.state.messageType == MessageType.All && this.all()} {this.state.messageType == MessageType.CommentReport && @@ -173,7 +179,7 @@ export class Reports extends Component<any, ReportsState> { unreadOrAllRadios() { return ( - <div class="btn-group btn-group-toggle flex-wrap mb-2"> + <div className="btn-group btn-group-toggle flex-wrap mb-2"> <label className={`btn btn-outline-secondary pointer ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"} @@ -206,7 +212,7 @@ export class Reports extends Component<any, ReportsState> { messageTypeRadios() { return ( - <div class="btn-group btn-group-toggle flex-wrap mb-2"> + <div className="btn-group btn-group-toggle flex-wrap mb-2"> <label className={`btn btn-outline-secondary pointer ${this.state.messageType == MessageType.All && "active"} @@ -253,8 +259,8 @@ export class Reports extends Component<any, ReportsState> { selects() { return ( <div className="mb-2"> - <span class="mr-3">{this.unreadOrAllRadios()}</span> - <span class="mr-3">{this.messageTypeRadios()}</span> + <span className="mr-3">{this.unreadOrAllRadios()}</span> + <span className="mr-3">{this.messageTypeRadios()}</span> </div> ); } @@ -356,16 +362,12 @@ export class Reports extends Component<any, ReportsState> { } handleUnreadOrAllChange(i: Reports, event: any) { - i.state.unreadOrAll = Number(event.target.value); - i.state.page = 1; - i.setState(i.state); + i.setState({ unreadOrAll: Number(event.target.value), page: 1 }); i.refetch(); } handleMessageTypeChange(i: Reports, event: any) { - i.state.messageType = Number(event.target.value); - i.state.page = 1; - i.setState(i.state); + i.setState({ messageType: Number(event.target.value), page: 1 }); i.refetch(); } @@ -443,24 +445,20 @@ export class Reports extends Component<any, ReportsState> { msg, ListCommentReportsResponse ); - this.state.listCommentReportsResponse = Some(data); - this.state.combined = this.buildCombined(); - this.state.loading = false; + this.setState({ listCommentReportsResponse: Some(data) }); + this.setState({ combined: this.buildCombined(), loading: false }); // this.sendUnreadCount(); window.scrollTo(0, 0); - this.setState(this.state); setupTippy(); } else if (op == UserOperation.ListPostReports) { let data = wsJsonToRes<ListPostReportsResponse>( msg, ListPostReportsResponse ); - this.state.listPostReportsResponse = Some(data); - this.state.combined = this.buildCombined(); - this.state.loading = false; + this.setState({ listPostReportsResponse: Some(data) }); + this.setState({ combined: this.buildCombined(), loading: false }); // this.sendUnreadCount(); window.scrollTo(0, 0); - this.setState(this.state); setupTippy(); } else if (op == UserOperation.ResolvePostReport) { let data = wsJsonToRes<PostReportResponse>(msg, PostReportResponse); diff --git a/src/shared/components/person/settings.tsx b/src/shared/components/person/settings.tsx index 532d92204..838c1ec10 100644 --- a/src/shared/components/person/settings.tsx +++ b/src/shared/components/person/settings.tsx @@ -150,13 +150,43 @@ export class Settings extends Component<any, SettingsState> { this.parseMessage = this.parseMessage.bind(this); this.subscription = wsSubscribe(this.parseMessage); - this.setUserInfo(); + if (UserService.Instance.myUserInfo.isSome()) { + let mui = UserService.Instance.myUserInfo.unwrap(); + let luv = mui.local_user_view; + this.state = { + ...this.state, + personBlocks: mui.person_blocks, + communityBlocks: mui.community_blocks, + saveUserSettingsForm: { + ...this.state.saveUserSettingsForm, + show_nsfw: Some(luv.local_user.show_nsfw), + theme: Some(luv.local_user.theme ? luv.local_user.theme : "browser"), + default_sort_type: Some(luv.local_user.default_sort_type), + default_listing_type: Some(luv.local_user.default_listing_type), + lang: Some(luv.local_user.lang), + avatar: luv.person.avatar, + banner: luv.person.banner, + display_name: luv.person.display_name, + show_avatars: Some(luv.local_user.show_avatars), + bot_account: Some(luv.person.bot_account), + show_bot_accounts: Some(luv.local_user.show_bot_accounts), + show_scores: Some(luv.local_user.show_scores), + show_read_posts: Some(luv.local_user.show_read_posts), + show_new_post_notifs: Some(luv.local_user.show_new_post_notifs), + email: luv.local_user.email, + bio: luv.person.bio, + send_notifications_to_email: Some( + luv.local_user.send_notifications_to_email + ), + matrix_user_id: luv.person.matrix_user_id, + }, + }; + } } async componentDidMount() { setupTippy(); - this.state.themeList = await fetchThemeList(); - this.setState(this.state); + this.setState({ themeList: await fetchThemeList() }); } componentWillUnmount() { @@ -169,7 +199,7 @@ export class Settings extends Component<any, SettingsState> { render() { return ( - <div class="container"> + <div className="container"> <> <HtmlTags title={this.documentTitle} @@ -177,10 +207,10 @@ export class Settings extends Component<any, SettingsState> { description={Some(this.documentTitle)} image={this.state.saveUserSettingsForm.avatar} /> - <ul class="nav nav-tabs mb-2"> - <li class="nav-item"> + <ul className="nav nav-tabs mb-2"> + <li className="nav-item"> <button - class={`nav-link btn ${ + className={`nav-link btn ${ this.state.currentTab == "settings" && "active" }`} onClick={linkEvent( @@ -191,9 +221,9 @@ export class Settings extends Component<any, SettingsState> { {i18n.t("settings")} </button> </li> - <li class="nav-item"> + <li className="nav-item"> <button - class={`nav-link btn ${ + className={`nav-link btn ${ this.state.currentTab == "blocks" && "active" }`} onClick={linkEvent( @@ -214,15 +244,15 @@ export class Settings extends Component<any, SettingsState> { userSettings() { return ( - <div class="row"> - <div class="col-12 col-md-6"> - <div class="card border-secondary mb-3"> - <div class="card-body">{this.saveUserSettingsHtmlForm()}</div> + <div className="row"> + <div className="col-12 col-md-6"> + <div className="card border-secondary mb-3"> + <div className="card-body">{this.saveUserSettingsHtmlForm()}</div> </div> </div> - <div class="col-12 col-md-6"> - <div class="card border-secondary mb-3"> - <div class="card-body">{this.changePasswordHtmlForm()}</div> + <div className="col-12 col-md-6"> + <div className="card border-secondary mb-3"> + <div className="card-body">{this.changePasswordHtmlForm()}</div> </div> </div> </div> @@ -231,15 +261,15 @@ export class Settings extends Component<any, SettingsState> { blockCards() { return ( - <div class="row"> - <div class="col-12 col-md-6"> - <div class="card border-secondary mb-3"> - <div class="card-body">{this.blockUserCard()}</div> + <div className="row"> + <div className="col-12 col-md-6"> + <div className="card border-secondary mb-3"> + <div className="card-body">{this.blockUserCard()}</div> </div> </div> - <div class="col-12 col-md-6"> - <div class="card border-secondary mb-3"> - <div class="card-body">{this.blockCommunityCard()}</div> + <div className="col-12 col-md-6"> + <div className="card border-secondary mb-3"> + <div className="card-body">{this.blockCommunityCard()}</div> </div> </div> </div> @@ -251,15 +281,15 @@ export class Settings extends Component<any, SettingsState> { <> <h5>{i18n.t("change_password")}</h5> <form onSubmit={linkEvent(this, this.handleChangePasswordSubmit)}> - <div class="form-group row"> - <label class="col-sm-5 col-form-label" htmlFor="user-password"> + <div className="form-group row"> + <label className="col-sm-5 col-form-label" htmlFor="user-password"> {i18n.t("new_password")} </label> - <div class="col-sm-7"> + <div className="col-sm-7"> <input type="password" id="user-password" - class="form-control" + className="form-control" value={this.state.changePasswordForm.new_password} autoComplete="new-password" maxLength={60} @@ -267,18 +297,18 @@ export class Settings extends Component<any, SettingsState> { /> </div> </div> - <div class="form-group row"> + <div className="form-group row"> <label - class="col-sm-5 col-form-label" + className="col-sm-5 col-form-label" htmlFor="user-verify-password" > {i18n.t("verify_password")} </label> - <div class="col-sm-7"> + <div className="col-sm-7"> <input type="password" id="user-verify-password" - class="form-control" + className="form-control" value={this.state.changePasswordForm.new_password_verify} autoComplete="new-password" maxLength={60} @@ -286,15 +316,18 @@ export class Settings extends Component<any, SettingsState> { /> </div> </div> - <div class="form-group row"> - <label class="col-sm-5 col-form-label" htmlFor="user-old-password"> + <div className="form-group row"> + <label + className="col-sm-5 col-form-label" + htmlFor="user-old-password" + > {i18n.t("old_password")} </label> - <div class="col-sm-7"> + <div className="col-sm-7"> <input type="password" id="user-old-password" - class="form-control" + className="form-control" value={this.state.changePasswordForm.old_password} autoComplete="new-password" maxLength={60} @@ -302,8 +335,8 @@ export class Settings extends Component<any, SettingsState> { /> </div> </div> - <div class="form-group"> - <button type="submit" class="btn btn-block btn-secondary mr-4"> + <div className="form-group"> + <button type="submit" className="btn btn-block btn-secondary mr-4"> {this.state.changePasswordLoading ? ( <Spinner /> ) : ( @@ -329,9 +362,9 @@ export class Settings extends Component<any, SettingsState> { return ( <> <h5>{i18n.t("blocked_users")}</h5> - <ul class="list-unstyled mb-0"> + <ul className="list-unstyled mb-0"> {this.state.personBlocks.map(pb => ( - <li> + <li key={pb.target.id}> <span> <PersonListing person={pb.target} /> <button @@ -354,13 +387,16 @@ export class Settings extends Component<any, SettingsState> { blockUserForm() { return ( - <div class="form-group row"> - <label class="col-md-4 col-form-label" htmlFor="block-person-filter"> + <div className="form-group row"> + <label + className="col-md-4 col-form-label" + htmlFor="block-person-filter" + > {i18n.t("block_user")} </label> - <div class="col-md-8"> + <div className="col-md-8"> <select - class="form-control" + className="form-control" id="block-person-filter" value={this.state.blockPerson.map(p => p.person.id).unwrapOr(0)} > @@ -392,9 +428,9 @@ export class Settings extends Component<any, SettingsState> { return ( <> <h5>{i18n.t("blocked_communities")}</h5> - <ul class="list-unstyled mb-0"> + <ul className="list-unstyled mb-0"> {this.state.communityBlocks.map(cb => ( - <li> + <li key={cb.community.id}> <span> <CommunityLink community={cb.community} /> <button @@ -417,13 +453,16 @@ export class Settings extends Component<any, SettingsState> { blockCommunityForm() { return ( - <div class="form-group row"> - <label class="col-md-4 col-form-label" htmlFor="block-community-filter"> + <div className="form-group row"> + <label + className="col-md-4 col-form-label" + htmlFor="block-community-filter" + > {i18n.t("block_community")} </label> - <div class="col-md-8"> + <div className="col-md-8"> <select - class="form-control" + className="form-control" id="block-community-filter" value={this.state.blockCommunityId} > @@ -444,15 +483,15 @@ export class Settings extends Component<any, SettingsState> { <> <h5>{i18n.t("settings")}</h5> <form onSubmit={linkEvent(this, this.handleSaveSettingsSubmit)}> - <div class="form-group row"> - <label class="col-sm-5 col-form-label" htmlFor="display-name"> + <div className="form-group row"> + <label className="col-sm-5 col-form-label" htmlFor="display-name"> {i18n.t("display_name")} </label> - <div class="col-sm-7"> + <div className="col-sm-7"> <input id="display-name" type="text" - class="form-control" + className="form-control" placeholder={i18n.t("optional")} value={toUndefined( this.state.saveUserSettingsForm.display_name @@ -463,11 +502,11 @@ export class Settings extends Component<any, SettingsState> { /> </div> </div> - <div class="form-group row"> - <label class="col-sm-3 col-form-label" htmlFor="user-bio"> + <div className="form-group row"> + <label className="col-sm-3 col-form-label" htmlFor="user-bio"> {i18n.t("bio")} </label> - <div class="col-sm-9"> + <div className="col-sm-9"> <MarkdownTextArea initialContent={this.state.saveUserSettingsForm.bio} onContentChange={this.handleBioChange} @@ -478,15 +517,15 @@ export class Settings extends Component<any, SettingsState> { /> </div> </div> - <div class="form-group row"> - <label class="col-sm-3 col-form-label" htmlFor="user-email"> + <div className="form-group row"> + <label className="col-sm-3 col-form-label" htmlFor="user-email"> {i18n.t("email")} </label> - <div class="col-sm-9"> + <div className="col-sm-9"> <input type="email" id="user-email" - class="form-control" + className="form-control" placeholder={i18n.t("optional")} value={toUndefined(this.state.saveUserSettingsForm.email)} onInput={linkEvent(this, this.handleEmailChange)} @@ -494,17 +533,17 @@ export class Settings extends Component<any, SettingsState> { /> </div> </div> - <div class="form-group row"> - <label class="col-sm-5 col-form-label" htmlFor="matrix-user-id"> + <div className="form-group row"> + <label className="col-sm-5 col-form-label" htmlFor="matrix-user-id"> <a href={elementUrl} rel={relTags}> {i18n.t("matrix_user_id")} </a> </label> - <div class="col-sm-7"> + <div className="col-sm-7"> <input id="matrix-user-id" type="text" - class="form-control" + className="form-control" placeholder="@user:example.com" value={toUndefined( this.state.saveUserSettingsForm.matrix_user_id @@ -514,9 +553,9 @@ export class Settings extends Component<any, SettingsState> { /> </div> </div> - <div class="form-group row"> - <label class="col-sm-3">{i18n.t("avatar")}</label> - <div class="col-sm-9"> + <div className="form-group row"> + <label className="col-sm-3">{i18n.t("avatar")}</label> + <div className="col-sm-9"> <ImageUploadForm uploadTitle={i18n.t("upload_avatar")} imageSrc={this.state.saveUserSettingsForm.avatar} @@ -526,9 +565,9 @@ export class Settings extends Component<any, SettingsState> { /> </div> </div> - <div class="form-group row"> - <label class="col-sm-3">{i18n.t("banner")}</label> - <div class="col-sm-9"> + <div className="form-group row"> + <label className="col-sm-3">{i18n.t("banner")}</label> + <div className="col-sm-9"> <ImageUploadForm uploadTitle={i18n.t("upload_banner")} imageSrc={this.state.saveUserSettingsForm.banner} @@ -537,16 +576,16 @@ export class Settings extends Component<any, SettingsState> { /> </div> </div> - <div class="form-group row"> - <label class="col-sm-3" htmlFor="user-language"> + <div className="form-group row"> + <label className="col-sm-3" htmlFor="user-language"> {i18n.t("language")} </label> - <div class="col-sm-9"> + <div className="col-sm-9"> <select id="user-language" value={toUndefined(this.state.saveUserSettingsForm.lang)} onChange={linkEvent(this, this.handleLangChange)} - class="custom-select w-auto" + className="custom-select w-auto" > <option disabled aria-hidden="true"> {i18n.t("language")} @@ -558,35 +597,39 @@ export class Settings extends Component<any, SettingsState> { {languages .sort((a, b) => a.code.localeCompare(b.code)) .map(lang => ( - <option value={lang.code}>{lang.name}</option> + <option key={lang.code} value={lang.code}> + {lang.name} + </option> ))} </select> </div> </div> - <div class="form-group row"> - <label class="col-sm-3" htmlFor="user-theme"> + <div className="form-group row"> + <label className="col-sm-3" htmlFor="user-theme"> {i18n.t("theme")} </label> - <div class="col-sm-9"> + <div className="col-sm-9"> <select id="user-theme" value={toUndefined(this.state.saveUserSettingsForm.theme)} onChange={linkEvent(this, this.handleThemeChange)} - class="custom-select w-auto" + className="custom-select w-auto" > <option disabled aria-hidden="true"> {i18n.t("theme")} </option> <option value="browser">{i18n.t("browser_default")}</option> {this.state.themeList.map(theme => ( - <option value={theme}>{theme}</option> + <option key={theme} value={theme}> + {theme} + </option> ))} </select> </div> </div> <form className="form-group row"> - <label class="col-sm-3">{i18n.t("type")}</label> - <div class="col-sm-9"> + <label className="col-sm-3">{i18n.t("type")}</label> + <div className="col-sm-9"> <ListingTypeSelect type_={ Object.values(ListingType)[ @@ -602,8 +645,8 @@ export class Settings extends Component<any, SettingsState> { </div> </form> <form className="form-group row"> - <label class="col-sm-3">{i18n.t("sort_type")}</label> - <div class="col-sm-9"> + <label className="col-sm-3">{i18n.t("sort_type")}</label> + <div className="col-sm-9"> <SortSelect sort={ Object.values(SortType)[ @@ -617,10 +660,10 @@ export class Settings extends Component<any, SettingsState> { </div> </form> {enableNsfw(this.state.siteRes) && ( - <div class="form-group"> - <div class="form-check"> + <div className="form-group"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="user-show-nsfw" type="checkbox" checked={toUndefined( @@ -628,16 +671,16 @@ export class Settings extends Component<any, SettingsState> { )} onChange={linkEvent(this, this.handleShowNsfwChange)} /> - <label class="form-check-label" htmlFor="user-show-nsfw"> + <label className="form-check-label" htmlFor="user-show-nsfw"> {i18n.t("show_nsfw")} </label> </div> </div> )} - <div class="form-group"> - <div class="form-check"> + <div className="form-group"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="user-show-scores" type="checkbox" checked={toUndefined( @@ -645,15 +688,15 @@ export class Settings extends Component<any, SettingsState> { )} onChange={linkEvent(this, this.handleShowScoresChange)} /> - <label class="form-check-label" htmlFor="user-show-scores"> + <label className="form-check-label" htmlFor="user-show-scores"> {i18n.t("show_scores")} </label> </div> </div> - <div class="form-group"> - <div class="form-check"> + <div className="form-group"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="user-show-avatars" type="checkbox" checked={toUndefined( @@ -661,15 +704,15 @@ export class Settings extends Component<any, SettingsState> { )} onChange={linkEvent(this, this.handleShowAvatarsChange)} /> - <label class="form-check-label" htmlFor="user-show-avatars"> + <label className="form-check-label" htmlFor="user-show-avatars"> {i18n.t("show_avatars")} </label> </div> </div> - <div class="form-group"> - <div class="form-check"> + <div className="form-group"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="user-bot-account" type="checkbox" checked={toUndefined( @@ -677,15 +720,15 @@ export class Settings extends Component<any, SettingsState> { )} onChange={linkEvent(this, this.handleBotAccount)} /> - <label class="form-check-label" htmlFor="user-bot-account"> + <label className="form-check-label" htmlFor="user-bot-account"> {i18n.t("bot_account")} </label> </div> </div> - <div class="form-group"> - <div class="form-check"> + <div className="form-group"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="user-show-bot-accounts" type="checkbox" checked={toUndefined( @@ -693,15 +736,18 @@ export class Settings extends Component<any, SettingsState> { )} onChange={linkEvent(this, this.handleShowBotAccounts)} /> - <label class="form-check-label" htmlFor="user-show-bot-accounts"> + <label + className="form-check-label" + htmlFor="user-show-bot-accounts" + > {i18n.t("show_bot_accounts")} </label> </div> </div> - <div class="form-group"> - <div class="form-check"> + <div className="form-group"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="user-show-read-posts" type="checkbox" checked={toUndefined( @@ -709,15 +755,18 @@ export class Settings extends Component<any, SettingsState> { )} onChange={linkEvent(this, this.handleReadPosts)} /> - <label class="form-check-label" htmlFor="user-show-read-posts"> + <label + className="form-check-label" + htmlFor="user-show-read-posts" + > {i18n.t("show_read_posts")} </label> </div> </div> - <div class="form-group"> - <div class="form-check"> + <div className="form-group"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="user-show-new-post-notifs" type="checkbox" checked={toUndefined( @@ -726,17 +775,17 @@ export class Settings extends Component<any, SettingsState> { onChange={linkEvent(this, this.handleShowNewPostNotifs)} /> <label - class="form-check-label" + className="form-check-label" htmlFor="user-show-new-post-notifs" > {i18n.t("show_new_post_notifs")} </label> </div> </div> - <div class="form-group"> - <div class="form-check"> + <div className="form-group"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="user-send-notifications-to-email" type="checkbox" disabled={!this.state.saveUserSettingsForm.email} @@ -749,15 +798,15 @@ export class Settings extends Component<any, SettingsState> { )} /> <label - class="form-check-label" + className="form-check-label" htmlFor="user-send-notifications-to-email" > {i18n.t("send_notifications_to_email")} </label> </div> </div> - <div class="form-group"> - <button type="submit" class="btn btn-block btn-secondary mr-4"> + <div className="form-group"> + <button type="submit" className="btn btn-block btn-secondary mr-4"> {this.state.saveUserSettingsLoading ? ( <Spinner /> ) : ( @@ -766,9 +815,9 @@ export class Settings extends Component<any, SettingsState> { </button> </div> <hr /> - <div class="form-group"> + <div className="form-group"> <button - class="btn btn-block btn-danger" + className="btn btn-block btn-danger" onClick={linkEvent( this, this.handleDeleteAccountShowConfirmToggle @@ -778,7 +827,7 @@ export class Settings extends Component<any, SettingsState> { </button> {this.state.deleteAccountShowConfirm && ( <> - <div class="my-2 alert alert-danger" role="alert"> + <div className="my-2 alert alert-danger" role="alert"> {i18n.t("delete_account_confirm")} </div> <input @@ -790,10 +839,10 @@ export class Settings extends Component<any, SettingsState> { this, this.handleDeleteAccountPasswordChange )} - class="form-control my-2" + className="form-control my-2" /> <button - class="btn btn-danger mr-4" + className="btn btn-danger mr-4" disabled={!this.state.deleteAccountForm.password} onClick={linkEvent(this, this.handleDeleteAccount)} > @@ -804,7 +853,7 @@ export class Settings extends Component<any, SettingsState> { )} </button> <button - class="btn btn-secondary" + className="btn btn-secondary" onClick={linkEvent( this, this.handleDeleteAccountShowConfirmToggle @@ -1000,17 +1049,25 @@ export class Settings extends Component<any, SettingsState> { } handleSortTypeChange(val: SortType) { - this.state.saveUserSettingsForm.default_sort_type = Some( - Object.keys(SortType).indexOf(val) + this.setState( + s => ( + (s.saveUserSettingsForm.default_sort_type = Some( + Object.keys(SortType).indexOf(val) + )), + s + ) ); - this.setState(this.state); } handleListingTypeChange(val: ListingType) { - this.state.saveUserSettingsForm.default_listing_type = Some( - Object.keys(ListingType).indexOf(val) + this.setState( + s => ( + (s.saveUserSettingsForm.default_listing_type = Some( + Object.keys(ListingType).indexOf(val) + )), + s + ) ); - this.setState(this.state); } handleEmailChange(i: Settings, event: any) { @@ -1019,28 +1076,23 @@ export class Settings extends Component<any, SettingsState> { } handleBioChange(val: string) { - this.state.saveUserSettingsForm.bio = Some(val); - this.setState(this.state); + this.setState(s => ((s.saveUserSettingsForm.bio = Some(val)), s)); } handleAvatarUpload(url: string) { - this.state.saveUserSettingsForm.avatar = Some(url); - this.setState(this.state); + this.setState(s => ((s.saveUserSettingsForm.avatar = Some(url)), s)); } handleAvatarRemove() { - this.state.saveUserSettingsForm.avatar = Some(""); - this.setState(this.state); + this.setState(s => ((s.saveUserSettingsForm.avatar = Some("")), s)); } handleBannerUpload(url: string) { - this.state.saveUserSettingsForm.banner = Some(url); - this.setState(this.state); + this.setState(s => ((s.saveUserSettingsForm.banner = Some(url)), s)); } handleBannerRemove() { - this.state.saveUserSettingsForm.banner = Some(""); - this.setState(this.state); + this.setState(s => ((s.saveUserSettingsForm.banner = Some("")), s)); } handleDisplayNameChange(i: Settings, event: any) { @@ -1079,30 +1131,26 @@ export class Settings extends Component<any, SettingsState> { handleSaveSettingsSubmit(i: Settings, event: any) { event.preventDefault(); - i.state.saveUserSettingsLoading = true; - i.state.saveUserSettingsForm.auth = auth().unwrap(); - i.setState(i.state); + i.setState({ saveUserSettingsLoading: true }); + i.setState(s => ((s.saveUserSettingsForm.auth = auth().unwrap()), s)); - WebSocketService.Instance.send( - wsClient.saveUserSettings(i.state.saveUserSettingsForm) - ); + let form = new SaveUserSettings({ ...i.state.saveUserSettingsForm }); + WebSocketService.Instance.send(wsClient.saveUserSettings(form)); } handleChangePasswordSubmit(i: Settings, event: any) { event.preventDefault(); - i.state.changePasswordLoading = true; - i.state.changePasswordForm.auth = auth().unwrap(); - i.setState(i.state); + i.setState({ changePasswordLoading: true }); + i.setState(s => ((s.changePasswordForm.auth = auth().unwrap()), s)); - WebSocketService.Instance.send( - wsClient.changePassword(i.state.changePasswordForm) - ); + let form = new ChangePassword({ ...i.state.changePasswordForm }); + + WebSocketService.Instance.send(wsClient.changePassword(form)); } handleDeleteAccountShowConfirmToggle(i: Settings, event: any) { event.preventDefault(); - i.state.deleteAccountShowConfirm = !i.state.deleteAccountShowConfirm; - i.setState(i.state); + i.setState({ deleteAccountShowConfirm: !i.state.deleteAccountShowConfirm }); } handleDeleteAccountPasswordChange(i: Settings, event: any) { @@ -1112,13 +1160,12 @@ export class Settings extends Component<any, SettingsState> { handleDeleteAccount(i: Settings, event: any) { event.preventDefault(); - i.state.deleteAccountLoading = true; - i.state.deleteAccountForm.auth = auth().unwrap(); - i.setState(i.state); + i.setState({ deleteAccountLoading: true }); + i.setState(s => ((s.deleteAccountForm.auth = auth().unwrap()), s)); - WebSocketService.Instance.send( - wsClient.deleteAccount(i.state.deleteAccountForm) - ); + let form = new DeleteAccount({ ...i.state.deleteAccountForm }); + + WebSocketService.Instance.send(wsClient.deleteAccount(form)); } handleSwitchTab(i: { ctx: Settings; tab: string }) { @@ -1130,58 +1177,6 @@ export class Settings extends Component<any, SettingsState> { } } - setUserInfo() { - UserService.Instance.myUserInfo.match({ - some: mui => { - let luv = mui.local_user_view; - this.state.saveUserSettingsForm.show_nsfw = Some( - luv.local_user.show_nsfw - ); - this.state.saveUserSettingsForm.theme = Some( - luv.local_user.theme ? luv.local_user.theme : "browser" - ); - this.state.saveUserSettingsForm.default_sort_type = Some( - luv.local_user.default_sort_type - ); - this.state.saveUserSettingsForm.default_listing_type = Some( - luv.local_user.default_listing_type - ); - this.state.saveUserSettingsForm.lang = Some(luv.local_user.lang); - this.state.saveUserSettingsForm.avatar = luv.person.avatar; - this.state.saveUserSettingsForm.banner = luv.person.banner; - this.state.saveUserSettingsForm.display_name = luv.person.display_name; - this.state.saveUserSettingsForm.show_avatars = Some( - luv.local_user.show_avatars - ); - this.state.saveUserSettingsForm.bot_account = Some( - luv.person.bot_account - ); - this.state.saveUserSettingsForm.show_bot_accounts = Some( - luv.local_user.show_bot_accounts - ); - this.state.saveUserSettingsForm.show_scores = Some( - luv.local_user.show_scores - ); - this.state.saveUserSettingsForm.show_read_posts = Some( - luv.local_user.show_read_posts - ); - this.state.saveUserSettingsForm.show_new_post_notifs = Some( - luv.local_user.show_new_post_notifs - ); - this.state.saveUserSettingsForm.email = luv.local_user.email; - this.state.saveUserSettingsForm.bio = luv.person.bio; - this.state.saveUserSettingsForm.send_notifications_to_email = Some( - luv.local_user.send_notifications_to_email - ); - this.state.saveUserSettingsForm.matrix_user_id = - luv.person.matrix_user_id; - this.state.personBlocks = mui.person_blocks; - this.state.communityBlocks = mui.community_blocks; - }, - none: void 0, - }); - } - parseMessage(msg: any) { let op = wsUserOp(msg); console.log(msg); @@ -1196,15 +1191,13 @@ export class Settings extends Component<any, SettingsState> { } else if (op == UserOperation.SaveUserSettings) { let data = wsJsonToRes<LoginResponse>(msg, LoginResponse); UserService.Instance.login(data); - this.state.saveUserSettingsLoading = false; - this.setState(this.state); + this.setState({ saveUserSettingsLoading: false }); toast(i18n.t("saved")); window.scrollTo(0, 0); } else if (op == UserOperation.ChangePassword) { let data = wsJsonToRes<LoginResponse>(msg, LoginResponse); UserService.Instance.login(data); - this.state.changePasswordLoading = false; - this.setState(this.state); + this.setState({ changePasswordLoading: false }); window.scrollTo(0, 0); toast(i18n.t("password_changed")); } else if (op == UserOperation.DeleteAccount) { diff --git a/src/shared/components/person/verify-email.tsx b/src/shared/components/person/verify-email.tsx index fed026fdf..e5389584d 100644 --- a/src/shared/components/person/verify-email.tsx +++ b/src/shared/components/person/verify-email.tsx @@ -66,15 +66,15 @@ export class VerifyEmail extends Component<any, State> { render() { return ( - <div class="container"> + <div className="container"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} description={None} image={None} /> - <div class="row"> - <div class="col-12 col-lg-6 offset-lg-3 mb-4"> + <div className="row"> + <div className="col-12 col-lg-6 offset-lg-3 mb-4"> <h5>{i18n.t("verify_email")}</h5> </div> </div> @@ -94,8 +94,7 @@ export class VerifyEmail extends Component<any, State> { let data = wsJsonToRes<VerifyEmailResponse>(msg, VerifyEmailResponse); if (data) { toast(i18n.t("email_verified")); - this.state = this.emptyState; - this.setState(this.state); + this.setState(this.emptyState); this.props.history.push("/login"); } } diff --git a/src/shared/components/post/create-post.tsx b/src/shared/components/post/create-post.tsx index 68d546e2e..6bb2f4d28 100644 --- a/src/shared/components/post/create-post.tsx +++ b/src/shared/components/post/create-post.tsx @@ -50,23 +50,27 @@ export class CreatePost extends Component<any, CreatePostState> { constructor(props: any, context: any) { super(props, context); - this.handlePostCreate = this.handlePostCreate.bind(this); this.state = this.emptyState; + this.handlePostCreate = this.handlePostCreate.bind(this); + + this.parseMessage = this.parseMessage.bind(this); + this.subscription = wsSubscribe(this.parseMessage); + if (UserService.Instance.myUserInfo.isNone() && isBrowser()) { toast(i18n.t("not_logged_in"), "danger"); this.context.router.history.push(`/login`); } - this.parseMessage = this.parseMessage.bind(this); - this.subscription = wsSubscribe(this.parseMessage); - // Only fetch the data if coming from another route if (this.isoData.path == this.context.router.route.match.url) { - this.state.listCommunitiesResponse = Some( - this.isoData.routeData[0] as ListCommunitiesResponse - ); - this.state.loading = false; + this.state = { + ...this.state, + listCommunitiesResponse: Some( + this.isoData.routeData[0] as ListCommunitiesResponse + ), + loading: false, + }; } else { this.refetch(); } @@ -123,7 +127,7 @@ export class CreatePost extends Component<any, CreatePostState> { render() { return ( - <div class="container"> + <div className="container"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} @@ -137,8 +141,8 @@ export class CreatePost extends Component<any, CreatePostState> { ) : ( this.state.listCommunitiesResponse.match({ some: res => ( - <div class="row"> - <div class="col-12 col-lg-6 offset-lg-3 mb-4"> + <div className="row"> + <div className="col-12 col-lg-6 offset-lg-3 mb-4"> <h5>{i18n.t("create_post")}</h5> <PostForm post_view={None} @@ -230,16 +234,15 @@ export class CreatePost extends Component<any, CreatePostState> { msg, ListCommunitiesResponse ); - this.state.listCommunitiesResponse = Some(data); - this.state.loading = false; - this.setState(this.state); + this.setState({ listCommunitiesResponse: Some(data), loading: false }); } else if (op == UserOperation.GetCommunity) { let data = wsJsonToRes<GetCommunityResponse>(msg, GetCommunityResponse); - this.state.listCommunitiesResponse = Some({ - communities: [data.community_view], + this.setState({ + listCommunitiesResponse: Some({ + communities: [data.community_view], + }), + loading: false, }); - this.state.loading = false; - this.setState(this.state); } } } diff --git a/src/shared/components/post/metadata-card.tsx b/src/shared/components/post/metadata-card.tsx index 116cdc9a4..a3b5b75ec 100644 --- a/src/shared/components/post/metadata-card.tsx +++ b/src/shared/components/post/metadata-card.tsx @@ -34,27 +34,33 @@ export class MetadataCard extends Component< some: embedTitle => post.url.match({ some: url => ( - <div class="card border-secondary mt-3 mb-2"> - <div class="row"> - <div class="col-12"> - <div class="card-body"> - {post.name !== embedTitle && [ - <h5 class="card-title d-inline"> - <a class="text-body" href={url} rel={relTags}> - {embedTitle} - </a> - </h5>, - <span class="d-inline-block ml-2 mb-2 small text-muted"> - <a - class="text-muted font-italic" - href={url} - rel={relTags} - > - {new URL(url).hostname} - <Icon icon="external-link" classes="ml-1" /> - </a> - </span>, - ]} + <div className="card border-secondary mt-3 mb-2"> + <div className="row"> + <div className="col-12"> + <div className="card-body"> + {post.name !== embedTitle && ( + <> + <h5 className="card-title d-inline"> + <a + className="text-body" + href={url} + rel={relTags} + > + {embedTitle} + </a> + </h5> + <span className="d-inline-block ml-2 mb-2 small text-muted"> + <a + className="text-muted font-italic" + href={url} + rel={relTags} + > + {new URL(url).hostname} + <Icon icon="external-link" classes="ml-1" /> + </a> + </span> + </> + )} {post.embed_description.match({ some: desc => ( <div @@ -68,7 +74,7 @@ export class MetadataCard extends Component< })} {post.embed_html.isSome() && ( <button - class="mt-2 btn btn-secondary text-monospace" + className="mt-2 btn btn-secondary text-monospace" onClick={linkEvent(this, this.handleIframeExpand)} data-tippy-content={i18n.t("expand_here")} > @@ -88,7 +94,7 @@ export class MetadataCard extends Component< post.embed_html.match({ some: html => ( <div - class="mt-3 mb-2" + className="mt-3 mb-2" dangerouslySetInnerHTML={{ __html: html }} /> ), @@ -99,7 +105,6 @@ export class MetadataCard extends Component< } handleIframeExpand(i: MetadataCard) { - i.state.expanded = !i.state.expanded; - i.setState(i.state); + i.setState({ expanded: !i.state.expanded }); } } diff --git a/src/shared/components/post/post-form.tsx b/src/shared/components/post/post-form.tsx index dde1cb423..286378b11 100644 --- a/src/shared/components/post/post-form.tsx +++ b/src/shared/components/post/post-form.tsx @@ -108,10 +108,16 @@ export class PostForm extends Component<PostFormProps, PostFormState> { this.state = this.emptyState; + this.parseMessage = this.parseMessage.bind(this); + this.subscription = wsSubscribe(this.parseMessage); + // Means its an edit - this.props.post_view.match({ - some: pv => - (this.state.postForm = new CreatePost({ + if (this.props.post_view.isSome()) { + let pv = this.props.post_view.unwrap(); + + this.state = { + ...this.state, + postForm: new CreatePost({ body: pv.post.body, name: pv.post.name, community_id: pv.community.id, @@ -119,21 +125,22 @@ export class PostForm extends Component<PostFormProps, PostFormState> { nsfw: Some(pv.post.nsfw), honeypot: None, auth: auth().unwrap(), - })), - none: void 0, - }); - - this.props.params.match({ - some: params => { - this.state.postForm.name = toUndefined(params.name); - this.state.postForm.url = params.url; - this.state.postForm.body = params.body; - }, - none: void 0, - }); + }), + }; + } - this.parseMessage = this.parseMessage.bind(this); - this.subscription = wsSubscribe(this.parseMessage); + if (this.props.params.isSome()) { + let params = this.props.params.unwrap(); + this.state = { + ...this.state, + postForm: { + ...this.state.postForm, + name: toUndefined(params.name), + url: params.url, + body: params.body, + }, + }; + } } componentDidMount() { @@ -177,15 +184,15 @@ export class PostForm extends Component<PostFormProps, PostFormState> { message={i18n.t("block_leaving")} /> <form onSubmit={linkEvent(this, this.handlePostSubmit)}> - <div class="form-group row"> - <label class="col-sm-2 col-form-label" htmlFor="post-url"> + <div className="form-group row"> + <label className="col-sm-2 col-form-label" htmlFor="post-url"> {i18n.t("url")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <input type="url" id="post-url" - class="form-control" + className="form-control" value={toUndefined(this.state.postForm.url)} onInput={linkEvent(this, this.handlePostUrlChange)} onPaste={linkEvent(this, this.handleImageUploadPaste)} @@ -193,7 +200,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> { {this.state.suggestedTitle.match({ some: title => ( <div - class="mt-1 text-muted small font-weight-bold pointer" + className="mt-1 text-muted small font-weight-bold pointer" role="button" onClick={linkEvent(this, this.copySuggestedTitle)} > @@ -217,7 +224,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> { type="file" accept="image/*,video/*" name="file" - class="d-none" + className="d-none" disabled={UserService.Instance.myUserInfo.isNone()} onChange={linkEvent(this, this.handleImageUpload)} /> @@ -230,7 +237,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> { href={`${webArchiveUrl}/save/${encodeURIComponent( url )}`} - class="mr-2 d-inline-block float-right text-muted small font-weight-bold" + className="mr-2 d-inline-block float-right text-muted small font-weight-bold" rel={relTags} > archive.org {i18n.t("archive_link")} @@ -239,7 +246,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> { href={`${ghostArchiveUrl}/search?term=${encodeURIComponent( url )}`} - class="mr-2 d-inline-block float-right text-muted small font-weight-bold" + className="mr-2 d-inline-block float-right text-muted small font-weight-bold" rel={relTags} > ghostarchive.org {i18n.t("archive_link")} @@ -248,7 +255,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> { href={`${archiveTodayUrl}/?run=1&url=${encodeURIComponent( url )}`} - class="mr-2 d-inline-block float-right text-muted small font-weight-bold" + className="mr-2 d-inline-block float-right text-muted small font-weight-bold" rel={relTags} > archive.today {i18n.t("archive_link")} @@ -260,14 +267,16 @@ export class PostForm extends Component<PostFormProps, PostFormState> { {this.state.imageLoading && <Spinner />} {this.state.postForm.url.match({ some: url => - isImage(url) && <img src={url} class="img-fluid" alt="" />, + isImage(url) && ( + <img src={url} className="img-fluid" alt="" /> + ), none: <></>, })} {this.state.crossPosts.match({ some: xPosts => xPosts.length > 0 && ( <> - <div class="my-1 text-muted small font-weight-bold"> + <div className="my-1 text-muted small font-weight-bold"> {i18n.t("cross_posts")} </div> <PostListings @@ -282,16 +291,16 @@ export class PostForm extends Component<PostFormProps, PostFormState> { })} </div> </div> - <div class="form-group row"> - <label class="col-sm-2 col-form-label" htmlFor="post-title"> + <div className="form-group row"> + <label className="col-sm-2 col-form-label" htmlFor="post-title"> {i18n.t("title")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <textarea value={this.state.postForm.name} id="post-title" onInput={linkEvent(this, this.handlePostNameChange)} - class={`form-control ${ + className={`form-control ${ !validTitle(this.state.postForm.name) && "is-invalid" }`} required @@ -300,7 +309,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> { maxLength={MAX_POST_TITLE_LENGTH} /> {!validTitle(this.state.postForm.name) && ( - <div class="invalid-feedback"> + <div className="invalid-feedback"> {i18n.t("invalid_post_title")} </div> )} @@ -308,7 +317,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> { some: sPosts => sPosts.length > 0 && ( <> - <div class="my-1 text-muted small font-weight-bold"> + <div className="my-1 text-muted small font-weight-bold"> {i18n.t("related_posts")} </div> <PostListings @@ -324,9 +333,9 @@ export class PostForm extends Component<PostFormProps, PostFormState> { </div> </div> - <div class="form-group row"> - <label class="col-sm-2 col-form-label">{i18n.t("body")}</label> - <div class="col-sm-10"> + <div className="form-group row"> + <label className="col-sm-2 col-form-label">{i18n.t("body")}</label> + <div className="col-sm-10"> <MarkdownTextArea initialContent={this.state.postForm.body} onContentChange={this.handlePostBodyChange} @@ -337,20 +346,23 @@ export class PostForm extends Component<PostFormProps, PostFormState> { </div> </div> {this.props.post_view.isNone() && ( - <div class="form-group row"> - <label class="col-sm-2 col-form-label" htmlFor="post-community"> + <div className="form-group row"> + <label + className="col-sm-2 col-form-label" + htmlFor="post-community" + > {i18n.t("community")} </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <select - class="form-control" + className="form-control" id="post-community" value={this.state.postForm.community_id} onInput={linkEvent(this, this.handlePostCommunityChange)} > <option>{i18n.t("select_a_community")}</option> {this.props.communities.unwrapOr([]).map(cv => ( - <option value={cv.community.id}> + <option key={cv.community.id} value={cv.community.id}> {communitySelectName(cv)} </option> ))} @@ -359,14 +371,14 @@ export class PostForm extends Component<PostFormProps, PostFormState> { </div> )} {this.props.enableNsfw && ( - <div class="form-group row"> - <legend class="col-form-label col-sm-2 pt-0"> + <div className="form-group row"> + <legend className="col-form-label col-sm-2 pt-0"> {i18n.t("nsfw")} </legend> - <div class="col-sm-10"> - <div class="form-check"> + <div className="col-sm-10"> + <div className="form-check"> <input - class="form-check-input position-static" + className="form-check-input position-static" id="post-nsfw" type="checkbox" checked={toUndefined(this.state.postForm.nsfw)} @@ -381,19 +393,19 @@ export class PostForm extends Component<PostFormProps, PostFormState> { autoComplete="false" name="a_password" type="text" - class="form-control honeypot" + className="form-control honeypot" id="register-honey" value={toUndefined(this.state.postForm.honeypot)} onInput={linkEvent(this, this.handleHoneyPotChange)} /> - <div class="form-group row"> - <div class="col-sm-10"> + <div className="form-group row"> + <div className="col-sm-10"> <button disabled={ !this.state.postForm.community_id || this.state.loading } type="submit" - class="btn btn-secondary mr-2" + className="btn btn-secondary mr-2" > {this.state.loading ? ( <Spinner /> @@ -406,7 +418,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> { {this.props.post_view.isSome() && ( <button type="button" - class="btn btn-secondary" + className="btn btn-secondary" onClick={linkEvent(this, this.handleCancel)} > {i18n.t("cancel")} @@ -422,12 +434,14 @@ export class PostForm extends Component<PostFormProps, PostFormState> { handlePostSubmit(i: PostForm, event: any) { event.preventDefault(); + i.setState({ loading: true }); + // Coerce empty url string to undefined if ( i.state.postForm.url.isSome() && i.state.postForm.url.unwrapOr("blank") === "" ) { - i.state.postForm.url = None; + i.setState(s => ((s.postForm.url = None), s)); } let pForm = i.state.postForm; @@ -444,32 +458,33 @@ export class PostForm extends Component<PostFormProps, PostFormState> { WebSocketService.Instance.send(wsClient.editPost(form)); }, none: () => { - i.state.postForm.auth = auth().unwrap(); - WebSocketService.Instance.send(wsClient.createPost(i.state.postForm)); + i.setState(s => ((s.postForm.auth = auth().unwrap()), s)); + let form = new CreatePost({ ...i.state.postForm }); + WebSocketService.Instance.send(wsClient.createPost(form)); }, }); - i.state.loading = true; - i.setState(i.state); } copySuggestedTitle(i: PostForm) { i.state.suggestedTitle.match({ some: sTitle => { - i.state.postForm.name = sTitle.substring(0, MAX_POST_TITLE_LENGTH); - i.state.suggestedTitle = None; + i.setState( + s => ( + (s.postForm.name = sTitle.substring(0, MAX_POST_TITLE_LENGTH)), s + ) + ); + i.setState({ suggestedTitle: None }); setTimeout(() => { let textarea: any = document.getElementById("post-title"); autosize.update(textarea); }, 10); - i.setState(i.state); }, none: void 0, }); } handlePostUrlChange(i: PostForm, event: any) { - i.state.postForm.url = Some(event.target.value); - i.setState(i.state); + i.setState(s => ((s.postForm.url = Some(event.target.value)), s)); i.fetchPageTitle(); } @@ -494,12 +509,10 @@ export class PostForm extends Component<PostFormProps, PostFormState> { // Fetch the page title getSiteMetadata(url).then(d => { - this.state.suggestedTitle = d.metadata.title; - this.setState(this.state); + this.setState({ suggestedTitle: d.metadata.title }); }); } else { - this.state.suggestedTitle = None; - this.state.crossPosts = None; + this.setState({ suggestedTitle: None, crossPosts: None }); } }, none: void 0, @@ -507,8 +520,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> { } handlePostNameChange(i: PostForm, event: any) { - i.state.postForm.name = event.target.value; - i.setState(i.state); + i.setState(s => ((s.postForm.name = event.target.value), s)); i.fetchSimilarPosts(); } @@ -529,30 +541,26 @@ export class PostForm extends Component<PostFormProps, PostFormState> { if (this.state.postForm.name !== "") { WebSocketService.Instance.send(wsClient.search(form)); } else { - this.state.suggestedPosts = None; + this.setState({ suggestedPosts: None }); } - - this.setState(this.state); } handlePostBodyChange(val: string) { - this.state.postForm.body = Some(val); - this.setState(this.state); + this.setState(s => ((s.postForm.body = Some(val)), s)); } handlePostCommunityChange(i: PostForm, event: any) { - i.state.postForm.community_id = Number(event.target.value); - i.setState(i.state); + i.setState( + s => ((s.postForm.community_id = Number(event.target.value)), s) + ); } handlePostNsfwChange(i: PostForm, event: any) { - i.state.postForm.nsfw = Some(event.target.checked); - i.setState(i.state); + i.setState(s => ((s.postForm.nsfw = Some(event.target.checked)), s)); } handleHoneyPotChange(i: PostForm, event: any) { - i.state.postForm.honeypot = Some(event.target.value); - i.setState(i.state); + i.setState(s => ((s.postForm.honeypot = Some(event.target.value)), s)); } handleCancel(i: PostForm) { @@ -561,8 +569,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> { handlePreviewToggle(i: PostForm, event: any) { event.preventDefault(); - i.state.previewMode = !i.state.previewMode; - i.setState(i.state); + i.setState({ previewMode: !i.state.previewMode }); } handleImageUploadPaste(i: PostForm, event: any) { @@ -584,8 +591,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> { const formData = new FormData(); formData.append("images[]", file); - i.state.imageLoading = true; - i.setState(i.state); + i.setState({ imageLoading: true }); fetch(pictrsUri, { method: "POST", @@ -601,22 +607,19 @@ export class PostForm extends Component<PostFormProps, PostFormState> { let deleteToken = res.files[0].delete_token; let deleteUrl = `${pictrsUri}/delete/${deleteToken}/${hash}`; i.state.postForm.url = Some(url); - i.state.imageLoading = false; - i.setState(i.state); + i.setState({ imageLoading: false }); pictrsDeleteToast( i18n.t("click_to_delete_picture"), i18n.t("picture_deleted"), deleteUrl ); } else { - i.state.imageLoading = false; - i.setState(i.state); + i.setState({ imageLoading: false }); toast(JSON.stringify(res), "danger"); } }) .catch(error => { - i.state.imageLoading = false; - i.setState(i.state); + i.setState({ imageLoading: false }); console.error(error); toast(error, "danger"); }); @@ -631,8 +634,11 @@ export class PostForm extends Component<PostFormProps, PostFormState> { this.choices.passedElement.element.addEventListener( "choice", (e: any) => { - this.state.postForm.community_id = Number(e.detail.choice.value); - this.setState(this.state); + this.setState( + s => ( + (s.postForm.community_id = Number(e.detail.choice.value)), s + ) + ); }, false ); @@ -658,7 +664,8 @@ export class PostForm extends Component<PostFormProps, PostFormState> { } this.props.post_view.match({ - some: pv => (this.state.postForm.community_id = pv.community.id), + some: pv => + this.setState(s => ((s.postForm.community_id = pv.community.id), s)), none: void 0, }); this.props.params.match({ @@ -670,9 +677,12 @@ export class PostForm extends Component<PostFormProps, PostFormState> { let foundCommunityId = this.props.communities .unwrapOr([]) .find(r => r.community.name == name).community.id; - this.state.postForm.community_id = foundCommunityId; + this.setState( + s => ((s.postForm.community_id = foundCommunityId), s) + ); }, - right: id => (this.state.postForm.community_id = id), + right: id => + this.setState(s => ((s.postForm.community_id = id), s)), }), none: void 0, }), @@ -693,15 +703,13 @@ export class PostForm extends Component<PostFormProps, PostFormState> { if (msg.error) { // Errors handled by top level pages // toast(i18n.t(msg.error), "danger"); - this.state.loading = false; - this.setState(this.state); + this.setState({ loading: false }); return; } else if (op == UserOperation.CreatePost) { let data = wsJsonToRes<PostResponse>(msg, PostResponse); UserService.Instance.myUserInfo.match({ some: mui => { if (data.post_view.creator.id == mui.local_user_view.person.id) { - this.state.loading = false; this.props.onCreate(data.post_view); } }, @@ -712,7 +720,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> { UserService.Instance.myUserInfo.match({ some: mui => { if (data.post_view.creator.id == mui.local_user_view.person.id) { - this.state.loading = false; + this.setState({ loading: false }); this.props.onEdit(data.post_view); } }, @@ -722,11 +730,10 @@ export class PostForm extends Component<PostFormProps, PostFormState> { let data = wsJsonToRes<SearchResponse>(msg, SearchResponse); if (data.type_ == SearchType[SearchType.Posts]) { - this.state.suggestedPosts = Some(data.posts); + this.setState({ suggestedPosts: Some(data.posts) }); } else if (data.type_ == SearchType[SearchType.Url]) { - this.state.crossPosts = Some(data.posts); + this.setState({ crossPosts: Some(data.posts) }); } - this.setState(this.state); } } } diff --git a/src/shared/components/post/post-listing.tsx b/src/shared/components/post/post-listing.tsx index 672d3d692..e24682476 100644 --- a/src/shared/components/post/post-listing.tsx +++ b/src/shared/components/post/post-listing.tsx @@ -135,20 +135,21 @@ export class PostListing extends Component<PostListingProps, PostListingState> { } componentWillReceiveProps(nextProps: PostListingProps) { - this.state.my_vote = nextProps.post_view.my_vote; - this.state.upvotes = nextProps.post_view.counts.upvotes; - this.state.downvotes = nextProps.post_view.counts.downvotes; - this.state.score = nextProps.post_view.counts.score; + this.setState({ + my_vote: nextProps.post_view.my_vote, + upvotes: nextProps.post_view.counts.upvotes, + downvotes: nextProps.post_view.counts.downvotes, + score: nextProps.post_view.counts.score, + }); if (this.props.post_view.post.id !== nextProps.post_view.post.id) { - this.state.imageExpanded = false; + this.setState({ imageExpanded: false }); } - this.setState(this.state); } render() { let post = this.props.post_view.post; return ( - <div class="post-listing"> + <div className="post-listing"> {!this.state.showEdit ? ( <> {this.listing()} @@ -159,7 +160,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { {this.showBody && this.body()} </> ) : ( - <div class="col-12"> + <div className="col-12"> <PostForm post_view={Some(this.props.post_view)} communities={None} @@ -178,7 +179,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { body() { return this.props.post_view.post.body.match({ some: body => ( - <div class="col-12 card my-2 p-2"> + <div className="col-12 card my-2 p-2"> {this.state.viewSource ? ( <pre>{body}</pre> ) : ( @@ -194,14 +195,14 @@ export class PostListing extends Component<PostListingProps, PostListingState> { return this.imageSrc.match({ some: src => ( <> - <div class="offset-sm-3 my-2 d-none d-sm-block"> - <a href={src} class="d-inline-block"> + <div className="offset-sm-3 my-2 d-none d-sm-block"> + <a href={src} className="d-inline-block"> <PictrsImage src={src} /> </a> </div> <div className="my-2 d-block d-sm-none"> <a - class="d-inline-block" + className="d-inline-block" onClick={linkEvent(this, this.handleImageExpandClick)} > <PictrsImage src={src} /> @@ -254,7 +255,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { return ( <a href={this.imageSrc.unwrap()} - class="text-body d-inline-block position-relative mb-2" + className="text-body d-inline-block position-relative mb-2" data-tippy-content={i18n.t("expand_here")} onClick={linkEvent(this, this.handleImageExpandClick)} aria-label={i18n.t("expand_here")} @@ -266,7 +267,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { } else if (url.isSome() && thumbnail.isSome()) { return ( <a - class="text-body d-inline-block position-relative mb-2" + className="text-body d-inline-block position-relative mb-2" href={url.unwrap()} rel={relTags} title={url.unwrap()} @@ -278,13 +279,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> { } else if (url.isSome()) { if (isVideo(url.unwrap())) { return ( - <div class="embed-responsive embed-responsive-16by9"> + <div className="embed-responsive embed-responsive-16by9"> <video - playsinline + playsInline muted loop controls - class="embed-responsive-item" + className="embed-responsive-item" > <source src={url.unwrap()} type="video/mp4" /> </video> @@ -298,7 +299,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { title={url.unwrap()} rel={relTags} > - <div class="thumbnail rounded bg-light d-flex justify-content-center"> + <div className="thumbnail rounded bg-light d-flex justify-content-center"> <Icon icon="external-link" classes="d-flex align-items-center" /> </div> </a> @@ -311,7 +312,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { to={`/post/${post.id}`} title={i18n.t("comments")} > - <div class="thumbnail rounded bg-light d-flex justify-content-center"> + <div className="thumbnail rounded bg-light d-flex justify-content-center"> <Icon icon="message-square" classes="d-flex align-items-center" /> </div> </Link> @@ -322,7 +323,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { createdLine() { let post_view = this.props.post_view; return ( - <ul class="list-inline mb-1 text-muted small"> + <ul className="list-inline mb-1 text-muted small"> <li className="list-inline-item"> <PersonListing person={post_view.creator} /> @@ -346,7 +347,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { )} {this.props.showCommunity && ( <span> - <span class="mx-1"> {i18n.t("to")} </span> + <span className="mx-1"> {i18n.t("to")} </span> <CommunityLink community={post_view.community} /> </span> )} @@ -416,13 +417,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> { </button> {showScores() ? ( <div - class={`unselectable pointer font-weight-bold text-muted px-1`} + className={`unselectable pointer font-weight-bold text-muted px-1`} data-tippy-content={this.pointsTippy} > {numToSI(this.state.score)} </div> ) : ( - <div class="p-1"></div> + <div className="p-1"></div> )} {this.props.enableDownvotes && ( <button @@ -470,7 +471,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { })} {post.url.map(isImage).or(post.thumbnail_url).unwrapOr(false) && ( <button - class="btn btn-link text-monospace text-muted small d-inline-block ml-2" + className="btn btn-link text-monospace text-muted small d-inline-block ml-2" data-tippy-content={i18n.t("expand_here")} onClick={linkEvent(this, this.handleImageExpandClick)} > @@ -525,13 +526,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> { return this.props.duplicates.match({ some: dupes => dupes.length > 0 && ( - <ul class="list-inline mb-1 small text-muted"> + <ul className="list-inline mb-1 small text-muted"> <> <li className="list-inline-item mr-2"> {i18n.t("cross_posted_to")} </li> {dupes.map(pv => ( - <li className="list-inline-item mr-2"> + <li key={pv.post.id} className="list-inline-item mr-2"> <Link to={`/post/${pv.post.id}`}> {pv.community.local ? pv.community.name @@ -551,7 +552,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { commentsLine(mobile = false) { let post = this.props.post_view.post; return ( - <div class="d-flex justify-content-start flex-wrap text-muted font-weight-bold mb-1"> + <div className="d-flex justify-content-start flex-wrap text-muted font-weight-bold mb-1"> {this.commentsButton} {!post.local && ( <a @@ -617,7 +618,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { get commentsButton() { let post_view = this.props.post_view; return ( - <button class="btn btn-link text-muted py-0 pl-0"> + <button className="btn btn-link text-muted py-0 pl-0"> <Link className="text-muted" title={i18n.t("number_of_comments", { @@ -652,7 +653,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { > <Icon icon="arrow-up1" classes="icon-inline small" /> {showScores() && ( - <span class="ml-2">{numToSI(this.state.upvotes)}</span> + <span className="ml-2">{numToSI(this.state.upvotes)}</span> )} </button> {this.props.enableDownvotes && ( @@ -669,7 +670,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { <Icon icon="arrow-down1" classes="icon-inline small" /> {showScores() && ( <span - class={classNames("ml-2", { + className={classNames("ml-2", { invisible: this.state.downvotes === 0, })} > @@ -688,7 +689,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { let label = saved ? i18n.t("unsave") : i18n.t("save"); return ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent(this, this.handleSavePostClick)} data-tippy-content={label} aria-label={label} @@ -717,7 +718,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { get reportButton() { return ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent(this, this.handleShowReportDialog)} data-tippy-content={i18n.t("show_report_dialog")} aria-label={i18n.t("show_report_dialog")} @@ -730,7 +731,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { get blockButton() { return ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent(this, this.handleBlockUserClick)} data-tippy-content={i18n.t("block_user")} aria-label={i18n.t("block_user")} @@ -743,7 +744,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { get editButton() { return ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent(this, this.handleEditClick)} data-tippy-content={i18n.t("edit")} aria-label={i18n.t("edit")} @@ -758,7 +759,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { let label = !deleted ? i18n.t("delete") : i18n.t("restore"); return ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent(this, this.handleDeleteClick)} data-tippy-content={label} aria-label={label} @@ -775,7 +776,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { get showMoreButton() { return ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent(this, this.handleShowAdvanced)} data-tippy-content={i18n.t("more")} aria-label={i18n.t("more")} @@ -788,7 +789,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { get viewSourceButton() { return ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent(this, this.handleViewSource)} data-tippy-content={i18n.t("view_source")} aria-label={i18n.t("view_source")} @@ -807,7 +808,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { let label = locked ? i18n.t("unlock") : i18n.t("lock"); return ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent(this, this.handleModLock)} data-tippy-content={label} aria-label={label} @@ -826,7 +827,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { let label = stickied ? i18n.t("unsticky") : i18n.t("sticky"); return ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent(this, this.handleModSticky)} data-tippy-content={label} aria-label={label} @@ -844,7 +845,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { let removed = this.props.post_view.post.removed; return ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent( this, !removed ? this.handleModRemoveShow : this.handleModRemoveSubmit @@ -870,7 +871,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { {!this.creatorIsMod_ && (!post_view.creator_banned_from_community ? ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent( this, this.handleModBanFromCommunityShow @@ -881,7 +882,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { </button> ) : ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent( this, this.handleModBanFromCommunitySubmit @@ -893,7 +894,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { ))} {!post_view.creator_banned_from_community && ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent(this, this.handleAddModToCommunity)} aria-label={ this.creatorIsMod_ @@ -914,7 +915,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { this.creatorIsMod_ && (!this.state.showConfirmTransferCommunity ? ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent( this, this.handleShowConfirmTransferCommunity @@ -926,20 +927,20 @@ export class PostListing extends Component<PostListingProps, PostListingState> { ) : ( <> <button - class="d-inline-block mr-1 btn btn-link btn-animate text-muted py-0" + className="d-inline-block mr-1 btn btn-link btn-animate text-muted py-0" aria-label={i18n.t("are_you_sure")} > {i18n.t("are_you_sure")} </button> <button - class="btn btn-link btn-animate text-muted py-0 d-inline-block mr-1" + className="btn btn-link btn-animate text-muted py-0 d-inline-block mr-1" aria-label={i18n.t("yes")} onClick={linkEvent(this, this.handleTransferCommunity)} > {i18n.t("yes")} </button> <button - class="btn btn-link btn-animate text-muted py-0 d-inline-block" + className="btn btn-link btn-animate text-muted py-0 d-inline-block" onClick={linkEvent( this, this.handleCancelShowConfirmTransferCommunity @@ -957,7 +958,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { <> {!isBanned(post_view.creator) ? ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent(this, this.handleModBanShow)} aria-label={i18n.t("ban_from_site")} > @@ -965,7 +966,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { </button> ) : ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent(this, this.handleModBanSubmit)} aria-label={i18n.t("unban_from_site")} > @@ -973,14 +974,14 @@ export class PostListing extends Component<PostListingProps, PostListingState> { </button> )} <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent(this, this.handlePurgePersonShow)} aria-label={i18n.t("purge_user")} > {i18n.t("purge_user")} </button> <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent(this, this.handlePurgePostShow)} aria-label={i18n.t("purge_post")} > @@ -990,7 +991,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { )} {!isBanned(post_view.creator) && post_view.creator.local && ( <button - class="btn btn-link btn-animate text-muted py-0" + className="btn btn-link btn-animate text-muted py-0" onClick={linkEvent(this, this.handleAddAdmin)} aria-label={ this.creatorIsAdmin_ @@ -1022,23 +1023,23 @@ export class PostListing extends Component<PostListingProps, PostListingState> { <> {this.state.showRemoveDialog && ( <form - class="form-inline" + className="form-inline" onSubmit={linkEvent(this, this.handleModRemoveSubmit)} > - <label class="sr-only" htmlFor="post-listing-remove-reason"> + <label className="sr-only" htmlFor="post-listing-remove-reason"> {i18n.t("reason")} </label> <input type="text" id="post-listing-remove-reason" - class="form-control mr-2" + className="form-control mr-2" placeholder={i18n.t("reason")} value={toUndefined(this.state.removeReason)} onInput={linkEvent(this, this.handleModRemoveReasonChange)} /> <button type="submit" - class="btn btn-secondary" + className="btn btn-secondary" aria-label={i18n.t("remove_post")} > {i18n.t("remove_post")} @@ -1047,40 +1048,43 @@ export class PostListing extends Component<PostListingProps, PostListingState> { )} {this.state.showBanDialog && ( <form onSubmit={linkEvent(this, this.handleModBanBothSubmit)}> - <div class="form-group row col-12"> - <label class="col-form-label" htmlFor="post-listing-ban-reason"> + <div className="form-group row col-12"> + <label + className="col-form-label" + htmlFor="post-listing-ban-reason" + > {i18n.t("reason")} </label> <input type="text" id="post-listing-ban-reason" - class="form-control mr-2" + className="form-control mr-2" placeholder={i18n.t("reason")} value={toUndefined(this.state.banReason)} onInput={linkEvent(this, this.handleModBanReasonChange)} /> - <label class="col-form-label" htmlFor={`mod-ban-expires`}> + <label className="col-form-label" htmlFor={`mod-ban-expires`}> {i18n.t("expires")} </label> <input type="number" id={`mod-ban-expires`} - class="form-control mr-2" + className="form-control mr-2" placeholder={i18n.t("number_of_days")} value={toUndefined(this.state.banExpireDays)} onInput={linkEvent(this, this.handleModBanExpireDaysChange)} /> - <div class="form-group"> - <div class="form-check"> + <div className="form-group"> + <div className="form-check"> <input - class="form-check-input" + className="form-check-input" id="mod-ban-remove-data" type="checkbox" checked={this.state.removeData} onChange={linkEvent(this, this.handleModRemoveDataChange)} /> <label - class="form-check-label" + className="form-check-label" htmlFor="mod-ban-remove-data" title={i18n.t("remove_content_more")} > @@ -1094,10 +1098,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> { {/* <label class="col-form-label">Expires</label> */} {/* <input type="date" class="form-control mr-2" placeholder={i18n.t('expires')} value={this.state.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */} {/* </div> */} - <div class="form-group row"> + <div className="form-group row"> <button type="submit" - class="btn btn-secondary" + className="btn btn-secondary" aria-label={i18n.t("ban")} > {i18n.t("ban")} {post.creator.name} @@ -1107,16 +1111,16 @@ export class PostListing extends Component<PostListingProps, PostListingState> { )} {this.state.showReportDialog && ( <form - class="form-inline" + className="form-inline" onSubmit={linkEvent(this, this.handleReportSubmit)} > - <label class="sr-only" htmlFor="post-report-reason"> + <label className="sr-only" htmlFor="post-report-reason"> {i18n.t("reason")} </label> <input type="text" id="post-report-reason" - class="form-control mr-2" + className="form-control mr-2" placeholder={i18n.t("reason")} required value={toUndefined(this.state.reportReason)} @@ -1124,7 +1128,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { /> <button type="submit" - class="btn btn-secondary" + className="btn btn-secondary" aria-label={i18n.t("create_report")} > {i18n.t("create_report")} @@ -1133,17 +1137,17 @@ export class PostListing extends Component<PostListingProps, PostListingState> { )} {this.state.showPurgeDialog && ( <form - class="form-inline" + className="form-inline" onSubmit={linkEvent(this, this.handlePurgeSubmit)} > <PurgeWarning /> - <label class="sr-only" htmlFor="purge-reason"> + <label className="sr-only" htmlFor="purge-reason"> {i18n.t("reason")} </label> <input type="text" id="purge-reason" - class="form-control mr-2" + className="form-control mr-2" placeholder={i18n.t("reason")} value={toUndefined(this.state.purgeReason)} onInput={linkEvent(this, this.handlePurgeReasonChange)} @@ -1153,7 +1157,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { ) : ( <button type="submit" - class="btn btn-secondary" + className="btn btn-secondary" aria-label={purgeTypeText} > {purgeTypeText} @@ -1169,11 +1173,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> { let post = this.props.post_view.post; return post.thumbnail_url.isSome() || post.url.map(isImage).unwrapOr(false) ? ( - <div class="row"> + <div className="row"> <div className={`${this.state.imageExpanded ? "col-12" : "col-8"}`}> {this.postTitleLine()} </div> - <div class="col-4"> + <div className="col-4"> {/* Post body prev or thumbnail */} {!this.state.imageExpanded && this.thumbnail()} </div> @@ -1198,9 +1202,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> { return ( <> {/* The mobile view*/} - <div class="d-block d-sm-none"> - <div class="row"> - <div class="col-12"> + <div className="d-block d-sm-none"> + <div className="row"> + <div className="col-12"> {this.createdLine()} {/* If it has a thumbnail, do a right aligned thumbnail */} @@ -1218,14 +1222,14 @@ export class PostListing extends Component<PostListingProps, PostListingState> { </div> {/* The larger view*/} - <div class="d-none d-sm-block"> - <div class="row"> + <div className="d-none d-sm-block"> + <div className="row"> {!this.props.viewOnly && this.voteBar()} - <div class="col-sm-2 pr-0"> - <div class="">{this.thumbnail()}</div> + <div className="col-sm-2 pr-0"> + <div className="">{this.thumbnail()}</div> </div> - <div class="col-12 col-sm-9"> - <div class="row"> + <div className="col-12 col-sm-9"> + <div className="row"> <div className="col-12"> {this.postTitleLine()} {this.createdLine()} @@ -1260,18 +1264,24 @@ export class PostListing extends Component<PostListingProps, PostListingState> { let newVote = myVote == 1 ? 0 : 1; if (myVote == 1) { - this.state.score--; - this.state.upvotes--; + this.setState({ + score: this.state.score - 1, + upvotes: this.state.upvotes - 1, + }); } else if (myVote == -1) { - this.state.downvotes--; - this.state.upvotes++; - this.state.score += 2; + this.setState({ + score: this.state.score + 2, + upvotes: this.state.upvotes + 1, + downvotes: this.state.downvotes - 1, + }); } else { - this.state.upvotes++; - this.state.score++; + this.setState({ + score: this.state.score + 1, + upvotes: this.state.upvotes + 1, + }); } - this.state.my_vote = Some(newVote); + this.setState({ my_vote: Some(newVote) }); let form = new CreatePostLike({ post_id: this.props.post_view.post.id, @@ -1294,18 +1304,24 @@ export class PostListing extends Component<PostListingProps, PostListingState> { let newVote = myVote == -1 ? 0 : -1; if (myVote == 1) { - this.state.score -= 2; - this.state.upvotes--; - this.state.downvotes++; + this.setState({ + score: this.state.score - 2, + upvotes: this.state.upvotes - 1, + downvotes: this.state.downvotes + 1, + }); } else if (myVote == -1) { - this.state.downvotes--; - this.state.score++; + this.setState({ + score: this.state.score + 1, + downvotes: this.state.downvotes - 1, + }); } else { - this.state.downvotes++; - this.state.score--; + this.setState({ + score: this.state.score - 1, + downvotes: this.state.downvotes + 1, + }); } - this.state.my_vote = Some(newVote); + this.setState({ my_vote: Some(newVote) }); let form = new CreatePostLike({ post_id: this.props.post_view.post.id, @@ -1319,29 +1335,24 @@ export class PostListing extends Component<PostListingProps, PostListingState> { } handleEditClick(i: PostListing) { - i.state.showEdit = true; - i.setState(i.state); + i.setState({ showEdit: true }); } handleEditCancel() { - this.state.showEdit = false; - this.setState(this.state); + this.setState({ showEdit: false }); } // The actual editing is done in the recieve for post handleEditPost() { - this.state.showEdit = false; - this.setState(this.state); + this.setState({ showEdit: false }); } handleShowReportDialog(i: PostListing) { - i.state.showReportDialog = !i.state.showReportDialog; - i.setState(this.state); + i.setState({ showReportDialog: !i.state.showReportDialog }); } handleReportReasonChange(i: PostListing, event: any) { - i.state.reportReason = Some(event.target.value); - i.setState(i.state); + i.setState({ reportReason: Some(event.target.value) }); } handleReportSubmit(i: PostListing, event: any) { @@ -1353,8 +1364,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { }); WebSocketService.Instance.send(wsClient.createPostReport(form)); - i.state.showReportDialog = false; - i.setState(i.state); + i.setState({ showReportDialog: false }); } handleBlockUserClick(i: PostListing) { @@ -1413,19 +1423,18 @@ export class PostListing extends Component<PostListingProps, PostListingState> { } handleModRemoveShow(i: PostListing) { - i.state.showRemoveDialog = !i.state.showRemoveDialog; - i.state.showBanDialog = false; - i.setState(i.state); + i.setState({ + showRemoveDialog: !i.state.showRemoveDialog, + showBanDialog: false, + }); } handleModRemoveReasonChange(i: PostListing, event: any) { - i.state.removeReason = Some(event.target.value); - i.setState(i.state); + i.setState({ removeReason: Some(event.target.value) }); } handleModRemoveDataChange(i: PostListing, event: any) { - i.state.removeData = event.target.checked; - i.setState(i.state); + i.setState({ removeData: event.target.checked }); } handleModRemoveSubmit(i: PostListing, event: any) { @@ -1438,8 +1447,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { }); WebSocketService.Instance.send(wsClient.removePost(form)); - i.state.showRemoveDialog = false; - i.setState(i.state); + i.setState({ showRemoveDialog: false }); } handleModLock(i: PostListing) { @@ -1461,36 +1469,39 @@ export class PostListing extends Component<PostListingProps, PostListingState> { } handleModBanFromCommunityShow(i: PostListing) { - i.state.showBanDialog = true; - i.state.banType = BanType.Community; - i.state.showRemoveDialog = false; - i.setState(i.state); + i.setState({ + showBanDialog: true, + banType: BanType.Community, + showRemoveDialog: false, + }); } handleModBanShow(i: PostListing) { - i.state.showBanDialog = true; - i.state.banType = BanType.Site; - i.state.showRemoveDialog = false; - i.setState(i.state); + i.setState({ + showBanDialog: true, + banType: BanType.Site, + showRemoveDialog: false, + }); } handlePurgePersonShow(i: PostListing) { - i.state.showPurgeDialog = true; - i.state.purgeType = PurgeType.Person; - i.state.showRemoveDialog = false; - i.setState(i.state); + i.setState({ + showPurgeDialog: true, + purgeType: PurgeType.Person, + showRemoveDialog: false, + }); } handlePurgePostShow(i: PostListing) { - i.state.showPurgeDialog = true; - i.state.purgeType = PurgeType.Post; - i.state.showRemoveDialog = false; - i.setState(i.state); + i.setState({ + showPurgeDialog: true, + purgeType: PurgeType.Post, + showRemoveDialog: false, + }); } handlePurgeReasonChange(i: PostListing, event: any) { - i.state.purgeReason = Some(event.target.value); - i.setState(i.state); + i.setState({ purgeReason: Some(event.target.value) }); } handlePurgeSubmit(i: PostListing, event: any) { @@ -1512,29 +1523,24 @@ export class PostListing extends Component<PostListingProps, PostListingState> { WebSocketService.Instance.send(wsClient.purgePost(form)); } - i.state.purgeLoading = true; - i.setState(i.state); + i.setState({ purgeLoading: true }); } handleModBanReasonChange(i: PostListing, event: any) { - i.state.banReason = Some(event.target.value); - i.setState(i.state); + i.setState({ banReason: Some(event.target.value) }); } handleModBanExpireDaysChange(i: PostListing, event: any) { - i.state.banExpireDays = Some(event.target.value); - i.setState(i.state); + i.setState({ banExpireDays: Some(event.target.value) }); } handleModBanFromCommunitySubmit(i: PostListing) { - i.state.banType = BanType.Community; - i.setState(i.state); + i.setState({ banType: BanType.Community }); i.handleModBanBothSubmit(i); } handleModBanSubmit(i: PostListing) { - i.state.banType = BanType.Site; - i.setState(i.state); + i.setState({ banType: BanType.Site }); i.handleModBanBothSubmit(i); } @@ -1545,7 +1551,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { // If its an unban, restore all their data let ban = !i.props.post_view.creator_banned_from_community; if (ban == false) { - i.state.removeData = false; + i.setState({ removeData: false }); } let form = new BanFromCommunity({ person_id: i.props.post_view.creator.id, @@ -1561,7 +1567,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { // If its an unban, restore all their data let ban = !i.props.post_view.creator.banned; if (ban == false) { - i.state.removeData = false; + i.setState({ removeData: false }); } let form = new BanPerson({ person_id: i.props.post_view.creator.id, @@ -1574,8 +1580,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> { WebSocketService.Instance.send(wsClient.banPerson(form)); } - i.state.showBanDialog = false; - i.setState(i.state); + i.setState({ showBanDialog: false }); } handleAddModToCommunity(i: PostListing) { @@ -1600,13 +1605,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> { } handleShowConfirmTransferCommunity(i: PostListing) { - i.state.showConfirmTransferCommunity = true; - i.setState(i.state); + i.setState({ showConfirmTransferCommunity: true }); } handleCancelShowConfirmTransferCommunity(i: PostListing) { - i.state.showConfirmTransferCommunity = false; - i.setState(i.state); + i.setState({ showConfirmTransferCommunity: false }); } handleTransferCommunity(i: PostListing) { @@ -1616,48 +1619,42 @@ export class PostListing extends Component<PostListingProps, PostListingState> { auth: auth().unwrap(), }); WebSocketService.Instance.send(wsClient.transferCommunity(form)); - i.state.showConfirmTransferCommunity = false; - i.setState(i.state); + i.setState({ showConfirmTransferCommunity: false }); } handleShowConfirmTransferSite(i: PostListing) { - i.state.showConfirmTransferSite = true; - i.setState(i.state); + i.setState({ showConfirmTransferSite: true }); } handleCancelShowConfirmTransferSite(i: PostListing) { - i.state.showConfirmTransferSite = false; - i.setState(i.state); + i.setState({ showConfirmTransferSite: false }); } handleImageExpandClick(i: PostListing, event: any) { event.preventDefault(); - i.state.imageExpanded = !i.state.imageExpanded; - i.setState(i.state); + i.setState({ imageExpanded: !i.state.imageExpanded }); setupTippy(); } handleViewSource(i: PostListing) { - i.state.viewSource = !i.state.viewSource; - i.setState(i.state); + i.setState({ viewSource: !i.state.viewSource }); } handleShowAdvanced(i: PostListing) { - i.state.showAdvanced = !i.state.showAdvanced; - i.setState(i.state); + i.setState({ showAdvanced: !i.state.showAdvanced }); setupTippy(); } handleShowMoreMobile(i: PostListing) { - i.state.showMoreMobile = !i.state.showMoreMobile; - i.state.showAdvanced = !i.state.showAdvanced; - i.setState(i.state); + i.setState({ + showMoreMobile: !i.state.showMoreMobile, + showAdvanced: !i.state.showAdvanced, + }); setupTippy(); } handleShowBody(i: PostListing) { - i.state.showBody = !i.state.showBody; - i.setState(i.state); + i.setState({ showBody: !i.state.showBody }); setupTippy(); } diff --git a/src/shared/components/post/post-listings.tsx b/src/shared/components/post/post-listings.tsx index a26d9d6d4..158bd8e42 100644 --- a/src/shared/components/post/post-listings.tsx +++ b/src/shared/components/post/post-listings.tsx @@ -42,7 +42,7 @@ export class PostListings extends Component<PostListingsProps, any> { enableDownvotes={this.props.enableDownvotes} enableNsfw={this.props.enableNsfw} /> - <hr class="my-3" /> + <hr className="my-3" /> </> )) ) : ( diff --git a/src/shared/components/post/post.tsx b/src/shared/components/post/post.tsx index 58cf71e81..2d3f4245a 100644 --- a/src/shared/components/post/post.tsx +++ b/src/shared/components/post/post.tsx @@ -120,28 +120,31 @@ export class Post extends Component<any, PostState> { super(props, context); this.state = this.emptyState; - this.state.commentSectionRef = createRef(); this.parseMessage = this.parseMessage.bind(this); this.subscription = wsSubscribe(this.parseMessage); + this.state = { ...this.state, commentSectionRef: createRef() }; + // Only fetch the data if coming from another route if (this.isoData.path == this.context.router.route.match.url) { - this.state.postRes = Some(this.isoData.routeData[0] as GetPostResponse); - this.state.commentsRes = Some( - this.isoData.routeData[1] as GetCommentsResponse - ); - - this.state.commentsRes.match({ - some: res => { - this.state.commentTree = buildCommentsTree( - res.comments, + this.state = { + ...this.state, + postRes: Some(this.isoData.routeData[0] as GetPostResponse), + commentsRes: Some(this.isoData.routeData[1] as GetCommentsResponse), + }; + + if (this.state.commentsRes.isSome()) { + this.state = { + ...this.state, + commentTree: buildCommentsTree( + this.state.commentsRes.unwrap().comments, this.state.commentId.isSome() - ); - }, - none: void 0, - }); - this.state.loading = false; + ), + }; + } + + this.state = { ...this.state, loading: false }; if (isBrowser()) { WebSocketService.Instance.send( @@ -305,8 +308,9 @@ export class Post extends Component<any, PostState> { trackCommentsBoxScrolling = () => { const wrappedElement = document.getElementsByClassName("comments")[0]; if (wrappedElement && this.isBottom(wrappedElement)) { - this.state.maxCommentsShown += commentsShownInterval; - this.setState(this.state); + this.setState({ + maxCommentsShown: this.state.maxCommentsShown + commentsShownInterval, + }); } }; @@ -341,7 +345,7 @@ export class Post extends Component<any, PostState> { render() { return ( - <div class="container"> + <div className="container"> {this.state.loading ? ( <h5> <Spinner large /> @@ -349,8 +353,8 @@ export class Post extends Component<any, PostState> { ) : ( this.state.postRes.match({ some: res => ( - <div class="row"> - <div class="col-12 col-md-8 mb-3"> + <div className="row"> + <div className="col-12 col-md-8 mb-3"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} @@ -372,9 +376,9 @@ export class Post extends Component<any, PostState> { node={Right(res.post_view.post.id)} disabled={res.post_view.post.locked} /> - <div class="d-block d-md-none"> + <div className="d-block d-md-none"> <button - class="btn btn-secondary d-inline-block mb-2 mr-3" + className="btn btn-secondary d-inline-block mb-2 mr-3" onClick={linkEvent(this, this.handleShowSidebarMobile)} > {i18n.t("sidebar")}{" "} @@ -395,7 +399,9 @@ export class Post extends Component<any, PostState> { {this.state.commentViewType == CommentViewType.Flat && this.commentsFlat()} </div> - <div class="d-none d-md-block col-md-4">{this.sidebar()}</div> + <div className="d-none d-md-block col-md-4"> + {this.sidebar()} + </div> </div> ), none: <></>, @@ -408,7 +414,7 @@ export class Post extends Component<any, PostState> { sortRadios() { return ( <> - <div class="btn-group btn-group-toggle flex-wrap mr-3 mb-2"> + <div className="btn-group btn-group-toggle flex-wrap mr-3 mb-2"> <label className={`btn btn-outline-secondary pointer ${ CommentSortType[this.state.commentSort] === CommentSortType.Hot && @@ -466,7 +472,7 @@ export class Post extends Component<any, PostState> { /> </label> </div> - <div class="btn-group btn-group-toggle flex-wrap mb-2"> + <div className="btn-group btn-group-toggle flex-wrap mb-2"> <label className={`btn btn-outline-secondary pointer ${ this.state.commentViewType === CommentViewType.Flat && "active" @@ -514,7 +520,7 @@ export class Post extends Component<any, PostState> { sidebar() { return this.state.postRes.match({ some: res => ( - <div class="mb-3"> + <div className="mb-3"> <Sidebar community_view={res.community_view} moderators={res.moderators} @@ -530,25 +536,26 @@ export class Post extends Component<any, PostState> { } handleCommentSortChange(i: Post, event: any) { - i.state.commentSort = CommentSortType[event.target.value]; - i.state.commentViewType = CommentViewType.Tree; - i.setState(i.state); + i.setState({ + commentSort: CommentSortType[event.target.value], + commentViewType: CommentViewType.Tree, + }); i.fetchPost(); } handleCommentViewTypeChange(i: Post, event: any) { - i.state.commentViewType = Number(event.target.value); - i.state.commentSort = CommentSortType.New; - i.state.commentTree = buildCommentsTree( - i.state.commentsRes.map(r => r.comments).unwrapOr([]), - i.state.commentId.isSome() - ); - i.setState(i.state); + i.setState({ + commentViewType: Number(event.target.value), + commentSort: CommentSortType.New, + commentTree: buildCommentsTree( + i.state.commentsRes.map(r => r.comments).unwrapOr([]), + i.state.commentId.isSome() + ), + }); } handleShowSidebarMobile(i: Post) { - i.state.showSidebarMobile = !i.state.showSidebarMobile; - i.setState(i.state); + i.setState({ showSidebarMobile: !i.state.showSidebarMobile }); } handleViewPost(i: Post) { @@ -581,14 +588,14 @@ export class Post extends Component<any, PostState> { {this.state.commentId.isSome() && ( <> <button - class="pl-0 d-block btn btn-link text-muted" + className="pl-0 d-block btn btn-link text-muted" onClick={linkEvent(this, this.handleViewPost)} > {i18n.t("view_all_comments")} ➔ </button> {showContextButton && ( <button - class="pl-0 d-block btn btn-link text-muted" + className="pl-0 d-block btn btn-link text-muted" onClick={linkEvent(this, this.handleViewContext)} > {i18n.t("show_context")} ➔ @@ -636,7 +643,7 @@ export class Post extends Component<any, PostState> { }); } else if (op == UserOperation.GetPost) { let data = wsJsonToRes<GetPostResponse>(msg, GetPostResponse); - this.state.postRes = Some(data); + this.setState({ postRes: Some(data) }); // join the rooms WebSocketService.Instance.send( @@ -651,7 +658,6 @@ export class Post extends Component<any, PostState> { // Get cross-posts // TODO move this into initial fetch and refetch this.fetchCrossPosts(); - this.setState(this.state); setupTippy(); if (this.state.commentId.isNone()) restoreScrollPosition(this.context); @@ -668,16 +674,16 @@ export class Post extends Component<any, PostState> { newComments.shift(); res.comments.push(...newComments); }, - none: () => { - this.state.commentsRes = Some(data); - }, + none: () => this.setState({ commentsRes: Some(data) }), }); // this.state.commentsRes = Some(data); - this.state.commentTree = buildCommentsTree( - this.state.commentsRes.map(r => r.comments).unwrapOr([]), - this.state.commentId.isSome() - ); - this.state.loading = false; + this.setState({ + commentTree: buildCommentsTree( + this.state.commentsRes.map(r => r.comments).unwrapOr([]), + this.state.commentId.isSome() + ), + loading: false, + }); this.setState(this.state); } else if (op == UserOperation.CreateComment) { let data = wsJsonToRes<CommentResponse>(msg, CommentResponse); @@ -827,19 +833,16 @@ export class Post extends Component<any, PostState> { }); } else if (op == UserOperation.AddAdmin) { let data = wsJsonToRes<AddAdminResponse>(msg, AddAdminResponse); - this.state.siteRes.admins = data.admins; - this.setState(this.state); + this.setState(s => ((s.siteRes.admins = data.admins), s)); } else if (op == UserOperation.Search) { let data = wsJsonToRes<SearchResponse>(msg, SearchResponse); let xPosts = data.posts.filter( p => p.post.id != Number(this.props.match.params.id) ); - this.state.crossPosts = xPosts.length > 0 ? Some(xPosts) : None; - this.setState(this.state); + this.setState({ crossPosts: xPosts.length > 0 ? Some(xPosts) : None }); } else if (op == UserOperation.LeaveAdmin) { let data = wsJsonToRes<GetSiteResponse>(msg, GetSiteResponse); - this.state.siteRes = data; - this.setState(this.state); + this.setState({ siteRes: data }); } else if (op == UserOperation.TransferCommunity) { let data = wsJsonToRes<GetCommunityResponse>(msg, GetCommunityResponse); this.state.postRes.match({ diff --git a/src/shared/components/private_message/create-private-message.tsx b/src/shared/components/private_message/create-private-message.tsx index a93ba99cc..9cbe47a9f 100644 --- a/src/shared/components/private_message/create-private-message.tsx +++ b/src/shared/components/private_message/create-private-message.tsx @@ -45,6 +45,7 @@ export class CreatePrivateMessage extends Component< recipient_id: getRecipientIdFromProps(this.props), loading: true, }; + constructor(props: any, context: any) { super(props, context); this.state = this.emptyState; @@ -61,10 +62,13 @@ export class CreatePrivateMessage extends Component< // Only fetch the data if coming from another route if (this.isoData.path == this.context.router.route.match.url) { - this.state.recipientDetailsRes = Some( - this.isoData.routeData[0] as GetPersonDetailsResponse - ); - this.state.loading = false; + this.state = { + ...this.state, + recipientDetailsRes: Some( + this.isoData.routeData[0] as GetPersonDetailsResponse + ), + loading: false, + }; } else { this.fetchPersonDetails(); } @@ -115,7 +119,7 @@ export class CreatePrivateMessage extends Component< render() { return ( - <div class="container"> + <div className="container"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} @@ -129,8 +133,8 @@ export class CreatePrivateMessage extends Component< ) : ( this.state.recipientDetailsRes.match({ some: res => ( - <div class="row"> - <div class="col-12 col-lg-6 offset-lg-3 mb-4"> + <div className="row"> + <div className="col-12 col-lg-6 offset-lg-3 mb-4"> <h5>{i18n.t("create_private_message")}</h5> <PrivateMessageForm privateMessageView={None} @@ -151,7 +155,7 @@ export class CreatePrivateMessage extends Component< toast(i18n.t("message_sent")); // Navigate to the front - this.context.router.history.push(`/`); + this.context.router.history.push("/"); } parseMessage(msg: any) { @@ -159,17 +163,14 @@ export class CreatePrivateMessage extends Component< console.log(msg); if (msg.error) { toast(i18n.t(msg.error), "danger"); - this.state.loading = false; - this.setState(this.state); + this.setState({ loading: false }); return; } else if (op == UserOperation.GetPersonDetails) { let data = wsJsonToRes<GetPersonDetailsResponse>( msg, GetPersonDetailsResponse ); - this.state.recipientDetailsRes = Some(data); - this.state.loading = false; - this.setState(this.state); + this.setState({ recipientDetailsRes: Some(data), loading: false }); } } } diff --git a/src/shared/components/private_message/private-message-form.tsx b/src/shared/components/private_message/private-message-form.tsx index 62649816d..46953d723 100644 --- a/src/shared/components/private_message/private-message-form.tsx +++ b/src/shared/components/private_message/private-message-form.tsx @@ -71,11 +71,10 @@ export class PrivateMessageForm extends Component< this.subscription = wsSubscribe(this.parseMessage); // Its an edit - this.props.privateMessageView.match({ - some: pm => - (this.state.privateMessageForm.content = pm.private_message.content), - none: void 0, - }); + if (this.props.privateMessageView.isSome()) { + this.state.privateMessageForm.content = + this.props.privateMessageView.unwrap().private_message.content; + } } componentDidMount() { @@ -106,21 +105,21 @@ export class PrivateMessageForm extends Component< /> <form onSubmit={linkEvent(this, this.handlePrivateMessageSubmit)}> {this.props.privateMessageView.isNone() && ( - <div class="form-group row"> - <label class="col-sm-2 col-form-label"> + <div className="form-group row"> + <label className="col-sm-2 col-form-label"> {capitalizeFirstLetter(i18n.t("to"))} </label> - <div class="col-sm-10 form-control-plaintext"> + <div className="col-sm-10 form-control-plaintext"> <PersonListing person={this.props.recipient} /> </div> </div> )} - <div class="form-group row"> - <label class="col-sm-2 col-form-label"> + <div className="form-group row"> + <label className="col-sm-2 col-form-label"> {i18n.t("message")} <button - class="btn btn-link text-warning d-inline-block" + className="btn btn-link text-warning d-inline-block" onClick={linkEvent(this, this.handleShowDisclaimer)} data-tippy-content={i18n.t("private_message_disclaimer")} aria-label={i18n.t("private_message_disclaimer")} @@ -128,7 +127,7 @@ export class PrivateMessageForm extends Component< <Icon icon="alert-triangle" classes="icon-inline" /> </button> </label> - <div class="col-sm-10"> + <div className="col-sm-10"> <MarkdownTextArea initialContent={Some(this.state.privateMessageForm.content)} placeholder={None} @@ -140,13 +139,13 @@ export class PrivateMessageForm extends Component< </div> {this.state.showDisclaimer && ( - <div class="form-group row"> - <div class="offset-sm-2 col-sm-10"> - <div class="alert alert-danger" role="alert"> + <div className="form-group row"> + <div className="offset-sm-2 col-sm-10"> + <div className="alert alert-danger" role="alert"> <T i18nKey="private_message_disclaimer"> # <a - class="alert-link" + className="alert-link" rel={relTags} href="https://element.io/get-started" > @@ -157,11 +156,11 @@ export class PrivateMessageForm extends Component< </div> </div> )} - <div class="form-group row"> - <div class="offset-sm-2 col-sm-10"> + <div className="form-group row"> + <div className="offset-sm-2 col-sm-10"> <button type="submit" - class="btn btn-secondary mr-2" + className="btn btn-secondary mr-2" disabled={this.state.loading} > {this.state.loading ? ( @@ -175,14 +174,14 @@ export class PrivateMessageForm extends Component< {this.props.privateMessageView.isSome() && ( <button type="button" - class="btn btn-secondary" + className="btn btn-secondary" onClick={linkEvent(this, this.handleCancel)} > {i18n.t("cancel")} </button> )} - <ul class="d-inline-block float-right list-inline mb-1 text-muted font-weight-bold"> - <li class="list-inline-item"></li> + <ul className="d-inline-block float-right list-inline mb-1 text-muted font-weight-bold"> + <li className="list-inline-item"></li> </ul> </div> </div> @@ -206,13 +205,11 @@ export class PrivateMessageForm extends Component< wsClient.createPrivateMessage(i.state.privateMessageForm) ), }); - i.state.loading = true; - i.setState(i.state); + i.setState({ loading: true }); } handleContentChange(val: string) { - this.state.privateMessageForm.content = val; - this.setState(this.state); + this.setState(s => ((s.privateMessageForm.content = val), s)); } handleCancel(i: PrivateMessageForm) { @@ -221,13 +218,11 @@ export class PrivateMessageForm extends Component< handlePreviewToggle(i: PrivateMessageForm, event: any) { event.preventDefault(); - i.state.previewMode = !i.state.previewMode; - i.setState(i.state); + i.setState({ previewMode: !i.state.previewMode }); } handleShowDisclaimer(i: PrivateMessageForm) { - i.state.showDisclaimer = !i.state.showDisclaimer; - i.setState(i.state); + i.setState({ showDisclaimer: !i.state.showDisclaimer }); } parseMessage(msg: any) { @@ -235,8 +230,7 @@ export class PrivateMessageForm extends Component< console.log(msg); if (msg.error) { toast(i18n.t(msg.error), "danger"); - this.state.loading = false; - this.setState(this.state); + this.setState({ loading: false }); return; } else if ( op == UserOperation.EditPrivateMessage || @@ -247,16 +241,14 @@ export class PrivateMessageForm extends Component< msg, PrivateMessageResponse ); - this.state.loading = false; + this.setState({ loading: false }); this.props.onEdit(data.private_message_view); } else if (op == UserOperation.CreatePrivateMessage) { let data = wsJsonToRes<PrivateMessageResponse>( msg, PrivateMessageResponse ); - this.state.loading = false; this.props.onCreate(data.private_message_view); - this.setState(this.state); } } } diff --git a/src/shared/components/private_message/private-message.tsx b/src/shared/components/private_message/private-message.tsx index 576626065..436a07a53 100644 --- a/src/shared/components/private_message/private-message.tsx +++ b/src/shared/components/private_message/private-message.tsx @@ -63,9 +63,9 @@ export class PrivateMessage extends Component< : message_view.creator; return ( - <div class="border-top border-light"> + <div className="border-top border-light"> <div> - <ul class="list-inline mb-0 text-muted small"> + <ul className="list-inline mb-0 text-muted small"> {/* TODO refactor this */} <li className="list-inline-item"> {this.mine ? i18n.t("to") : i18n.t("from")} @@ -114,12 +114,12 @@ export class PrivateMessage extends Component< dangerouslySetInnerHTML={mdToHtml(this.messageUnlessRemoved)} /> )} - <ul class="list-inline mb-0 text-muted font-weight-bold"> + <ul className="list-inline mb-0 text-muted font-weight-bold"> {!this.mine && ( <> <li className="list-inline-item"> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent(this, this.handleMarkRead)} data-tippy-content={ message_view.private_message.read @@ -142,7 +142,7 @@ export class PrivateMessage extends Component< </li> <li className="list-inline-item"> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent(this, this.handleReplyClick)} data-tippy-content={i18n.t("reply")} aria-label={i18n.t("reply")} @@ -156,7 +156,7 @@ export class PrivateMessage extends Component< <> <li className="list-inline-item"> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent(this, this.handleEditClick)} data-tippy-content={i18n.t("edit")} aria-label={i18n.t("edit")} @@ -166,7 +166,7 @@ export class PrivateMessage extends Component< </li> <li className="list-inline-item"> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent(this, this.handleDeleteClick)} data-tippy-content={ !message_view.private_message.deleted @@ -192,7 +192,7 @@ export class PrivateMessage extends Component< )} <li className="list-inline-item"> <button - class="btn btn-link btn-animate text-muted" + className="btn btn-link btn-animate text-muted" onClick={linkEvent(this, this.handleViewSource)} data-tippy-content={i18n.t("view_source")} aria-label={i18n.t("view_source")} @@ -217,7 +217,7 @@ export class PrivateMessage extends Component< /> )} {/* A collapsed clearfix */} - {this.state.collapsed && <div class="row col-12"></div>} + {this.state.collapsed && <div className="row col-12"></div>} </div> ); } @@ -228,12 +228,11 @@ export class PrivateMessage extends Component< } handleReplyClick(i: PrivateMessage) { - i.state.showReply = true; - i.setState(i.state); + i.setState({ showReply: true }); } handleEditClick(i: PrivateMessage) { - i.state.showEdit = true; + i.setState({ showEdit: true }); i.setState(i.state); } @@ -247,9 +246,7 @@ export class PrivateMessage extends Component< } handleReplyCancel() { - this.state.showReply = false; - this.state.showEdit = false; - this.setState(this.state); + this.setState({ showReply: false, showEdit: false }); } handleMarkRead(i: PrivateMessage) { @@ -262,26 +259,22 @@ export class PrivateMessage extends Component< } handleMessageCollapse(i: PrivateMessage) { - i.state.collapsed = !i.state.collapsed; - i.setState(i.state); + i.setState({ collapsed: !i.state.collapsed }); } handleViewSource(i: PrivateMessage) { - i.state.viewSource = !i.state.viewSource; - i.setState(i.state); + i.setState({ viewSource: !i.state.viewSource }); } handlePrivateMessageEdit() { - this.state.showEdit = false; - this.setState(this.state); + this.setState({ showEdit: false }); } handlePrivateMessageCreate(message: PrivateMessageView) { UserService.Instance.myUserInfo.match({ some: mui => { if (message.creator.id == mui.local_user_view.person.id) { - this.state.showReply = false; - this.setState(this.state); + this.setState({ showReply: false }); toast(i18n.t("message_sent")); } }, diff --git a/src/shared/components/search.tsx b/src/shared/components/search.tsx index 30bd9b88c..09f28f9b9 100644 --- a/src/shared/components/search.tsx +++ b/src/shared/components/search.tsx @@ -200,28 +200,36 @@ export class Search extends Component<any, SearchState> { ); // This can be single or multiple communities given - communitiesRes.match({ - some: res => (this.state.communities = res.communities), - none: void 0, - }); + if (communitiesRes.isSome()) { + this.state = { + ...this.state, + communities: communitiesRes.unwrap().communities, + }; + } - communityRes.match({ - some: res => (this.state.communities = [res.community_view]), - none: void 0, - }); + if (communityRes.isSome()) { + this.state = { + ...this.state, + communities: [communityRes.unwrap().community_view], + }; + } - this.state.creatorDetails = Some( - this.isoData.routeData[2] as GetPersonDetailsResponse - ); + this.state = { + ...this.state, + creatorDetails: Some( + this.isoData.routeData[2] as GetPersonDetailsResponse + ), + }; if (this.state.q != "") { - this.state.searchResponse = Some( - this.isoData.routeData[3] as SearchResponse - ); - this.state.resolveObjectResponse = Some( - this.isoData.routeData[4] as ResolveObjectResponse - ); - this.state.loading = false; + this.state = { + ...this.state, + searchResponse: Some(this.isoData.routeData[3] as SearchResponse), + resolveObjectResponse: Some( + this.isoData.routeData[4] as ResolveObjectResponse + ), + loading: false, + }; } else { this.search(); } @@ -382,7 +390,7 @@ export class Search extends Component<any, SearchState> { render() { return ( - <div class="container"> + <div className="container"> <HtmlTags title={this.documentTitle} path={this.context.router.route.match.url} @@ -407,12 +415,12 @@ export class Search extends Component<any, SearchState> { searchForm() { return ( <form - class="form-inline" + className="form-inline" onSubmit={linkEvent(this, this.handleSearchSubmit)} > <input type="text" - class="form-control mr-2 mb-2" + className="form-control mr-2 mb-2" value={this.state.searchText} placeholder={`${i18n.t("search")}...`} aria-label={i18n.t("search")} @@ -420,7 +428,7 @@ export class Search extends Component<any, SearchState> { required minLength={1} /> - <button type="submit" class="btn btn-secondary mr-2 mb-2"> + <button type="submit" className="btn btn-secondary mr-2 mb-2"> {this.state.loading ? <Spinner /> : <span>{i18n.t("search")}</span>} </button> </form> @@ -433,7 +441,7 @@ export class Search extends Component<any, SearchState> { <select value={this.state.type_} onChange={linkEvent(this, this.handleTypeChange)} - class="custom-select w-auto mb-2" + className="custom-select w-auto mb-2" aria-label={i18n.t("type")} > <option disabled aria-hidden="true"> @@ -448,7 +456,7 @@ export class Search extends Component<any, SearchState> { <option value={SearchType.Users}>{i18n.t("users")}</option> <option value={SearchType.Url}>{i18n.t("url")}</option> </select> - <span class="ml-2"> + <span className="ml-2"> <ListingTypeSelect type_={this.state.listingType} showLocal={showLocal(this.isoData)} @@ -456,7 +464,7 @@ export class Search extends Component<any, SearchState> { onChange={this.handleListingTypeChange} /> </span> - <span class="ml-2"> + <span className="ml-2"> <SortSelect sort={this.state.sort} onChange={this.handleSortChange} @@ -464,7 +472,7 @@ export class Search extends Component<any, SearchState> { hideMostComments /> </span> - <div class="form-row"> + <div className="form-row"> {this.state.communities.length > 0 && this.communityFilter()} {this.creatorFilter()} </div> @@ -577,8 +585,8 @@ export class Search extends Component<any, SearchState> { return ( <div> {combined.map(i => ( - <div class="row"> - <div class="col-12"> + <div key={i.published} className="row"> + <div className="col-12"> {i.type_ == "posts" && ( <PostListing key={(i.data as PostView).post.id} @@ -616,7 +624,7 @@ export class Search extends Component<any, SearchState> { <div>{this.communityListing(i.data as CommunityView)}</div> )} {i.type_ == "users" && ( - <div>{this.userListing(i.data as PersonViewSafe)}</div> + <div>{this.personListing(i.data as PersonViewSafe)}</div> )} </div> </div> @@ -666,11 +674,11 @@ export class Search extends Component<any, SearchState> { return ( <> - {posts.map(post => ( - <div class="row"> - <div class="col-12"> + {posts.map(pv => ( + <div key={pv.post.id} className="row"> + <div className="col-12"> <PostListing - post_view={post} + post_view={pv} showCommunity duplicates={None} moderators={None} @@ -700,9 +708,9 @@ export class Search extends Component<any, SearchState> { return ( <> - {communities.map(community => ( - <div class="row"> - <div class="col-12">{this.communityListing(community)}</div> + {communities.map(cv => ( + <div key={cv.community.id} className="row"> + <div className="col-12">{this.communityListing(cv)}</div> </div> ))} </> @@ -723,9 +731,9 @@ export class Search extends Component<any, SearchState> { return ( <> - {users.map(user => ( - <div class="row"> - <div class="col-12">{this.userListing(user)}</div> + {users.map(pvs => ( + <div key={pvs.person.id} className="row"> + <div className="col-12">{this.personListing(pvs)}</div> </div> ))} </> @@ -748,33 +756,37 @@ export class Search extends Component<any, SearchState> { ); } - userListing(person_view: PersonViewSafe) { - return [ - <span> - <PersonListing person={person_view.person} showApubName /> - </span>, - <span>{` - ${i18n.t("number_of_comments", { - count: person_view.counts.comment_count, - formattedCount: numToSI(person_view.counts.comment_count), - })}`}</span>, - ]; + personListing(person_view: PersonViewSafe) { + return ( + <> + <span> + <PersonListing person={person_view.person} showApubName /> + </span> + <span>{` - ${i18n.t("number_of_comments", { + count: person_view.counts.comment_count, + formattedCount: numToSI(person_view.counts.comment_count), + })}`}</span> + </> + ); } communityFilter() { return ( - <div class="form-group col-sm-6"> - <label class="col-form-label" htmlFor="community-filter"> + <div className="form-group col-sm-6"> + <label className="col-form-label" htmlFor="community-filter"> {i18n.t("community")} </label> <div> <select - class="form-control" + className="form-control" id="community-filter" value={this.state.communityId} > <option value="0">{i18n.t("all")}</option> {this.state.communities.map(cv => ( - <option value={cv.community.id}>{communitySelectName(cv)}</option> + <option key={cv.community.id} value={cv.community.id}> + {communitySelectName(cv)} + </option> ))} </select> </div> @@ -784,13 +796,13 @@ export class Search extends Component<any, SearchState> { creatorFilter() { return ( - <div class="form-group col-sm-6"> - <label class="col-form-label" htmlFor="creator-filter"> + <div className="form-group col-sm-6"> + <label className="col-form-label" htmlFor="creator-filter"> {capitalizeFirstLetter(i18n.t("creator"))} </label> <div> <select - class="form-control" + className="form-control" id="creator-filter" value={this.state.creatorId} > @@ -856,10 +868,11 @@ export class Search extends Component<any, SearchState> { }); if (this.state.q != "") { - this.state.searchResponse = None; - this.state.resolveObjectResponse = None; - this.state.loading = true; - this.setState(this.state); + this.setState({ + searchResponse: None, + resolveObjectResponse: None, + loading: true, + }); WebSocketService.Instance.send(wsClient.search(form)); WebSocketService.Instance.send(wsClient.resolveObject(resolveObjectForm)); } @@ -1000,11 +1013,13 @@ export class Search extends Component<any, SearchState> { let op = wsUserOp(msg); if (msg.error) { if (msg.error == "couldnt_find_object") { - this.state.resolveObjectResponse = Some({ - comment: None, - post: None, - community: None, - person: None, + this.setState({ + resolveObjectResponse: Some({ + comment: None, + post: None, + community: None, + person: None, + }), }); this.checkFinishedLoading(); } else { @@ -1013,7 +1028,7 @@ export class Search extends Component<any, SearchState> { } } else if (op == UserOperation.Search) { let data = wsJsonToRes<SearchResponse>(msg, SearchResponse); - this.state.searchResponse = Some(data); + this.setState({ searchResponse: Some(data) }); window.scrollTo(0, 0); this.checkFinishedLoading(); restoreScrollPosition(this.context); @@ -1036,12 +1051,11 @@ export class Search extends Component<any, SearchState> { msg, ListCommunitiesResponse ); - this.state.communities = data.communities; - this.setState(this.state); + this.setState({ communities: data.communities }); this.setupCommunityFilter(); } else if (op == UserOperation.ResolveObject) { let data = wsJsonToRes<ResolveObjectResponse>(msg, ResolveObjectResponse); - this.state.resolveObjectResponse = Some(data); + this.setState({ resolveObjectResponse: Some(data) }); this.checkFinishedLoading(); } } @@ -1051,8 +1065,7 @@ export class Search extends Component<any, SearchState> { this.state.searchResponse.isSome() && this.state.resolveObjectResponse.isSome() ) { - this.state.loading = false; - this.setState(this.state); + this.setState({ loading: false }); } } } diff --git a/src/shared/utils.ts b/src/shared/utils.ts index 695ba1e6f..69452f798 100644 --- a/src/shared/utils.ts +++ b/src/shared/utils.ts @@ -1360,7 +1360,7 @@ export const choicesModLogConfig = { shouldSort: false, searchResultLimit: fetchLimit, classNames: { - containerOuter: "choices mb-2 custom-select col-4 px-0", + containerOuter: "choices mb-2 custom-select px-0", containerInner: "choices__inner bg-secondary border-0 py-0 modlog-choices-font-size", input: "form-control", diff --git a/yarn.lock b/yarn.lock index 93f1f5d0f..8d0e3f525 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3,11 +3,12 @@ "@ampproject/remapping@^2.1.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" - integrity sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg== + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== dependencies: - "@jridgewell/trace-mapping" "^0.3.0" + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" "@babel/code-frame@^7.16.7": version "7.16.7" @@ -28,31 +29,26 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.8.tgz#31560f9f29fdf1868de8cb55049538a1b9732a60" integrity sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q== -"@babel/compat-data@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" - integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== - -"@babel/compat-data@^7.18.8": - version "7.18.8" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" - integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8", "@babel/compat-data@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.1.tgz#72d647b4ff6a4f82878d184613353af1dd0290f9" + integrity sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg== "@babel/core@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.9.tgz#805461f967c77ff46c74ca0460ccf4fe933ddd59" - integrity sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g== + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.1.tgz#c8fa615c5e88e272564ace3d42fbc8b17bfeb22b" + integrity sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw== dependencies: "@ampproject/remapping" "^2.1.0" "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.18.9" - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-module-transforms" "^7.18.9" - "@babel/helpers" "^7.18.9" - "@babel/parser" "^7.18.9" - "@babel/template" "^7.18.6" - "@babel/traverse" "^7.18.9" - "@babel/types" "^7.18.9" + "@babel/generator" "^7.19.0" + "@babel/helper-compilation-targets" "^7.19.1" + "@babel/helper-module-transforms" "^7.19.0" + "@babel/helpers" "^7.19.0" + "@babel/parser" "^7.19.1" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.1" + "@babel/types" "^7.19.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" @@ -89,12 +85,12 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.9.tgz#68337e9ea8044d6ddc690fb29acae39359cca0a5" - integrity sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug== +"@babel/generator@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.0.tgz#785596c06425e59334df2ccee63ab166b738419a" + integrity sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg== dependencies: - "@babel/types" "^7.18.9" + "@babel/types" "^7.19.0" "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" @@ -130,34 +126,24 @@ browserslist "^4.17.5" semver "^6.3.0" -"@babel/helper-compilation-targets@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46" - integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w== +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.19.0", "@babel/helper-compilation-targets@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz#7f630911d83b408b76fe584831c98e5395d7a17c" + integrity sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg== dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-validator-option" "^7.16.7" - browserslist "^4.17.5" - semver "^6.3.0" - -"@babel/helper-compilation-targets@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf" - integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg== - dependencies: - "@babel/compat-data" "^7.18.8" + "@babel/compat-data" "^7.19.1" "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.20.2" + browserslist "^4.21.3" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.9.tgz#d802ee16a64a9e824fcbf0a2ffc92f19d58550ce" - integrity sha512-WvypNAYaVh23QcjpMR24CwZY2Nz6hqdOcFdPbNpV56hL5H6KiFheO7Xm1aPdlLQ7d5emYZX7VZwPp9x3z+2opw== +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz#bfd6904620df4e46470bae4850d66be1054c404b" + integrity sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" "@babel/helper-member-expression-to-functions" "^7.18.9" "@babel/helper-optimise-call-expression" "^7.18.6" "@babel/helper-replace-supers" "^7.18.9" @@ -179,10 +165,18 @@ "@babel/helper-annotate-as-pure" "^7.18.6" regexpu-core "^5.1.0" -"@babel/helper-define-polyfill-provider@^0.3.1", "@babel/helper-define-polyfill-provider@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.2.tgz#bd10d0aca18e8ce012755395b05a79f45eca5073" - integrity sha512-r9QJJ+uDWrd+94BSPcP6/de67ygLtvVy6cK4luE6MOuDsZIdoaPBnfSpbO/+LTifjPckbKXRuI9BB/Z2/y3iTg== +"@babel/helper-create-regexp-features-plugin@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz#7976aca61c0984202baca73d84e2337a5424a41b" + integrity sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + regexpu-core "^5.1.0" + +"@babel/helper-define-polyfill-provider@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a" + integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== dependencies: "@babel/helper-compilation-targets" "^7.17.7" "@babel/helper-plugin-utils" "^7.16.7" @@ -198,7 +192,7 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-environment-visitor@^7.18.6", "@babel/helper-environment-visitor@^7.18.9": +"@babel/helper-environment-visitor@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== @@ -219,13 +213,13 @@ "@babel/template" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/helper-function-name@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0" - integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A== +"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" + integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== dependencies: - "@babel/template" "^7.18.6" - "@babel/types" "^7.18.9" + "@babel/template" "^7.18.10" + "@babel/types" "^7.19.0" "@babel/helper-get-function-arity@^7.16.7": version "7.16.7" @@ -283,7 +277,7 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.18.9": +"@babel/helper-module-transforms@^7.18.6": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712" integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g== @@ -297,6 +291,20 @@ "@babel/traverse" "^7.18.9" "@babel/types" "^7.18.9" +"@babel/helper-module-transforms@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30" + integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.0" + "@babel/types" "^7.19.0" + "@babel/helper-optimise-call-expression@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" @@ -304,17 +312,17 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== -"@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz#4b8aea3b069d8cb8a72cdfe28ddf5ceca695ef2f" - integrity sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w== +"@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf" + integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw== -"@babel/helper-remap-async-to-generator@^7.18.6": +"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== @@ -324,7 +332,7 @@ "@babel/helper-wrap-function" "^7.18.9" "@babel/types" "^7.18.9" -"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9": +"@babel/helper-replace-supers@^7.18.6": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz#1092e002feca980fbbb0bd4d51b74a65c6a500e6" integrity sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ== @@ -335,6 +343,17 @@ "@babel/traverse" "^7.18.9" "@babel/types" "^7.18.9" +"@babel/helper-replace-supers@^7.18.9", "@babel/helper-replace-supers@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz#e1592a9b4b368aa6bdb8784a711e0bcbf0612b78" + integrity sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/traverse" "^7.19.1" + "@babel/types" "^7.19.0" + "@babel/helper-simple-access@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" @@ -370,22 +389,22 @@ dependencies: "@babel/types" "^7.18.6" +"@babel/helper-string-parser@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56" + integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== + "@babel/helper-validator-identifier@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== "@babel/helper-validator-identifier@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" - integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== - -"@babel/helper-validator-option@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" - integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== -"@babel/helper-validator-option@^7.18.6": +"@babel/helper-validator-option@^7.16.7", "@babel/helper-validator-option@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== @@ -409,14 +428,14 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/helpers@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9" - integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ== +"@babel/helpers@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.0.tgz#f30534657faf246ae96551d88dd31e9d1fa1fc18" + integrity sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg== dependencies: - "@babel/template" "^7.18.6" - "@babel/traverse" "^7.18.9" - "@babel/types" "^7.18.9" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.0" + "@babel/types" "^7.19.0" "@babel/highlight@^7.16.7": version "7.16.7" @@ -441,10 +460,10 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.8.tgz#61c243a3875f7d0b0962b0543a33ece6ff2f1f17" integrity sha512-i7jDUfrVBWc+7OKcBzEe5n7fbv3i2fWtxKzzCvOjnzSxMfWMigAhtfJ7qzZNGFNMsCCd67+uz553dYKWXPvCKw== -"@babel/parser@^7.18.6", "@babel/parser@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.9.tgz#f2dde0c682ccc264a9a8595efd030a5cc8fd2539" - integrity sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg== +"@babel/parser@^7.18.10", "@babel/parser@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.1.tgz#6f6d6c2e621aad19a92544cc217ed13f1aac5b4c" + integrity sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": version "7.18.6" @@ -462,14 +481,14 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" "@babel/plugin-proposal-optional-chaining" "^7.18.9" -"@babel/plugin-proposal-async-generator-functions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.6.tgz#aedac81e6fc12bb643374656dd5f2605bf743d17" - integrity sha512-WAz4R9bvozx4qwf74M+sfqPMKfSqwM0phxPTR6iJIi8robgzXwkEgmeJG1gEKhm6sDqT/U9aV3lfcqybIpev8w== +"@babel/plugin-proposal-async-generator-functions@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz#34f6f5174b688529342288cd264f80c9ea9fb4a7" + integrity sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q== dependencies: - "@babel/helper-environment-visitor" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-remap-async-to-generator" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-remap-async-to-generator" "^7.18.9" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-proposal-class-properties@^7.18.6": @@ -490,15 +509,15 @@ "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-proposal-decorators@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.18.9.tgz#d09d41ffc74af8499d2ac706ed0dbd5474711665" - integrity sha512-KD7zDNaD14CRpjQjVbV4EnH9lsKYlcpUrhZH37ei2IY+AlXrfAPy5pTmRUE4X6X1k8EsKXPraykxeaogqQvSGA== + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.1.tgz#4bab3e7afe894fdbf47ffa86701266104fcb6ecc" + integrity sha512-LfIKNBBY7Q1OX5C4xAgRQffOg2OnhAo9fnbcOHgOC9Yytm2Sw+4XqHufRYU86tHomzepxtvuVaNO+3EVKR4ivw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-create-class-features-plugin" "^7.19.0" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-replace-supers" "^7.19.1" "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/plugin-syntax-decorators" "^7.18.6" + "@babel/plugin-syntax-decorators" "^7.19.0" "@babel/plugin-proposal-dynamic-import@^7.18.6": version "7.18.6" @@ -631,12 +650,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-decorators@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.18.6.tgz#2e45af22835d0b0f8665da2bfd4463649ce5dbc1" - integrity sha512-fqyLgjcxf/1yhyZ6A+yo1u9gJ7eleFQod2lkaUsF9DQ7sbbY3Ligym3L0+I2c0WmqNKDpoD9UTb1AKP3qRMOAQ== +"@babel/plugin-syntax-decorators@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz#5f13d1d8fce96951bea01a10424463c9a5b3a599" + integrity sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.19.0" "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" @@ -766,16 +785,17 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-classes@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.9.tgz#90818efc5b9746879b869d5ce83eb2aa48bbc3da" - integrity sha512-EkRQxsxoytpTlKJmSPYrsOMjCILacAjtSVkd4gChEe2kXjFCun3yohhW5I7plXJhCemM0gKsaGMcO8tinvCA5g== +"@babel/plugin-transform-classes@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz#0e61ec257fba409c41372175e7c1e606dc79bb20" + integrity sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-compilation-targets" "^7.19.0" "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.19.0" "@babel/helper-replace-supers" "^7.18.9" "@babel/helper-split-export-declaration" "^7.18.6" globals "^11.1.0" @@ -787,10 +807,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-destructuring@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.9.tgz#68906549c021cb231bee1db21d3b5b095f8ee292" - integrity sha512-p5VCYNddPLkZTq4XymQIaIfZNJwT9YsjkPOhkVEqt6QIpQFZVM9IltqqYpOEkJoN1DPznmxUDyZ5CTZs/ZCuHA== +"@babel/plugin-transform-destructuring@^7.18.13": + version "7.18.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz#9e03bc4a94475d62b7f4114938e6c5c33372cbf5" + integrity sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow== dependencies: "@babel/helper-plugin-utils" "^7.18.9" @@ -874,14 +894,14 @@ "@babel/helper-simple-access" "^7.18.6" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.9.tgz#545df284a7ac6a05125e3e405e536c5853099a06" - integrity sha512-zY/VSIbbqtoRoJKo2cDTewL364jSlZGvn0LKOf9ntbfxOvjfmyrdtEEOAdswOswhZEb8UH3jDkCKHd1sPgsS0A== +"@babel/plugin-transform-modules-systemjs@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz#5f20b471284430f02d9c5059d9b9a16d4b085a1f" + integrity sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A== dependencies: "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-module-transforms" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-module-transforms" "^7.19.0" + "@babel/helper-plugin-utils" "^7.19.0" "@babel/helper-validator-identifier" "^7.18.6" babel-plugin-dynamic-import-node "^2.3.3" @@ -893,13 +913,13 @@ "@babel/helper-module-transforms" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-named-capturing-groups-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz#c89bfbc7cc6805d692f3a49bc5fc1b630007246d" - integrity sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg== +"@babel/plugin-transform-named-capturing-groups-regex@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz#ec7455bab6cd8fb05c525a94876f435a48128888" + integrity sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-regexp-features-plugin" "^7.19.0" + "@babel/helper-plugin-utils" "^7.19.0" "@babel/plugin-transform-new-target@^7.18.6": version "7.18.6" @@ -946,15 +966,15 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-runtime@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.9.tgz#d9e4b1b25719307bfafbf43065ed7fb3a83adb8f" - integrity sha512-wS8uJwBt7/b/mzE13ktsJdmS4JP/j7PQSaADtnb4I2wL0zK51MQ0pmF8/Jy0wUIS96fr+fXT6S/ifiPXnvrlSg== + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.1.tgz#a3df2d7312eea624c7889a2dcd37fd1dfd25b2c6" + integrity sha512-2nJjTUFIzBMP/f/miLxEK9vxwW/KUXsdvN4sR//TmuDhe6yU2h57WmIOE12Gng3MDP/xpjUV/ToZRdcf8Yj4fA== dependencies: "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.9" - babel-plugin-polyfill-corejs2 "^0.3.1" - babel-plugin-polyfill-corejs3 "^0.5.2" - babel-plugin-polyfill-regenerator "^0.3.1" + "@babel/helper-plugin-utils" "^7.19.0" + babel-plugin-polyfill-corejs2 "^0.3.3" + babel-plugin-polyfill-corejs3 "^0.6.0" + babel-plugin-polyfill-regenerator "^0.4.1" semver "^6.3.0" "@babel/plugin-transform-shorthand-properties@^7.18.6": @@ -964,12 +984,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-spread@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.18.9.tgz#6ea7a6297740f381c540ac56caf75b05b74fb664" - integrity sha512-39Q814wyoOPtIB/qGopNIL9xDChOE1pNU0ZY5dO0owhiVt/5kFm4li+/bBtwc7QotG0u5EPzqhZdjMtmqBqyQA== +"@babel/plugin-transform-spread@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz#dd60b4620c2fec806d60cfaae364ec2188d593b6" + integrity sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.19.0" "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" "@babel/plugin-transform-sticky-regex@^7.18.6": @@ -993,7 +1013,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-typescript@^7.18.6", "@babel/plugin-transform-typescript@^7.18.8": +"@babel/plugin-transform-typescript@^7.18.6": version "7.18.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.8.tgz#303feb7a920e650f2213ef37b36bbf327e6fa5a0" integrity sha512-p2xM8HI83UObjsZGofMV/EdYjamsDm6MoN3hXPYIT0+gxIoopE+B7rPYKAxfrz9K9PK7JafTTjqYC6qipLExYA== @@ -1002,12 +1022,21 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-typescript" "^7.18.6" -"@babel/plugin-transform-unicode-escapes@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.6.tgz#0d01fb7fb2243ae1c033f65f6e3b4be78db75f27" - integrity sha512-XNRwQUXYMP7VLuy54cr/KS/WeL3AZeORhrmeZ7iewgu+X2eBqmpaLI/hzqr9ZxCeUoq0ASK4GUzSM0BDhZkLFw== +"@babel/plugin-transform-typescript@^7.18.8": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.1.tgz#adcf180a041dcbd29257ad31b0c65d4de531ce8d" + integrity sha512-+ILcOU+6mWLlvCwnL920m2Ow3wWx3Wo8n2t5aROQmV55GZt+hOiLvBaa3DNzRjSEHa1aauRs4/YLmkCfFkhhRQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.19.0" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/plugin-syntax-typescript" "^7.18.6" + +"@babel/plugin-transform-unicode-escapes@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz#1ecfb0eda83d09bbcb77c09970c2dd55832aa246" + integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-transform-unicode-regex@^7.18.6": version "7.18.6" @@ -1017,18 +1046,18 @@ "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/preset-env@7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.18.9.tgz#9b3425140d724fbe590322017466580844c7eaff" - integrity sha512-75pt/q95cMIHWssYtyfjVlvI+QEZQThQbKvR9xH+F/Agtw/s4Wfc2V9Bwd/P39VtixB7oWxGdH4GteTTwYJWMg== +"@babel/preset-env@7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.19.1.tgz#9f04c916f9c0205a48ebe5cc1be7768eb1983f67" + integrity sha512-c8B2c6D16Lp+Nt6HcD+nHl0VbPKVnNPTpszahuxJJnurfMtKeZ80A+qUv48Y7wqvS+dTFuLuaM9oYxyNHbCLWA== dependencies: - "@babel/compat-data" "^7.18.8" - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/compat-data" "^7.19.1" + "@babel/helper-compilation-targets" "^7.19.1" + "@babel/helper-plugin-utils" "^7.19.0" "@babel/helper-validator-option" "^7.18.6" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-async-generator-functions" "^7.18.6" + "@babel/plugin-proposal-async-generator-functions" "^7.19.1" "@babel/plugin-proposal-class-properties" "^7.18.6" "@babel/plugin-proposal-class-static-block" "^7.18.6" "@babel/plugin-proposal-dynamic-import" "^7.18.6" @@ -1062,9 +1091,9 @@ "@babel/plugin-transform-async-to-generator" "^7.18.6" "@babel/plugin-transform-block-scoped-functions" "^7.18.6" "@babel/plugin-transform-block-scoping" "^7.18.9" - "@babel/plugin-transform-classes" "^7.18.9" + "@babel/plugin-transform-classes" "^7.19.0" "@babel/plugin-transform-computed-properties" "^7.18.9" - "@babel/plugin-transform-destructuring" "^7.18.9" + "@babel/plugin-transform-destructuring" "^7.18.13" "@babel/plugin-transform-dotall-regex" "^7.18.6" "@babel/plugin-transform-duplicate-keys" "^7.18.9" "@babel/plugin-transform-exponentiation-operator" "^7.18.6" @@ -1074,9 +1103,9 @@ "@babel/plugin-transform-member-expression-literals" "^7.18.6" "@babel/plugin-transform-modules-amd" "^7.18.6" "@babel/plugin-transform-modules-commonjs" "^7.18.6" - "@babel/plugin-transform-modules-systemjs" "^7.18.9" + "@babel/plugin-transform-modules-systemjs" "^7.19.0" "@babel/plugin-transform-modules-umd" "^7.18.6" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.18.6" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.1" "@babel/plugin-transform-new-target" "^7.18.6" "@babel/plugin-transform-object-super" "^7.18.6" "@babel/plugin-transform-parameters" "^7.18.8" @@ -1084,18 +1113,18 @@ "@babel/plugin-transform-regenerator" "^7.18.6" "@babel/plugin-transform-reserved-words" "^7.18.6" "@babel/plugin-transform-shorthand-properties" "^7.18.6" - "@babel/plugin-transform-spread" "^7.18.9" + "@babel/plugin-transform-spread" "^7.19.0" "@babel/plugin-transform-sticky-regex" "^7.18.6" "@babel/plugin-transform-template-literals" "^7.18.9" "@babel/plugin-transform-typeof-symbol" "^7.18.9" - "@babel/plugin-transform-unicode-escapes" "^7.18.6" + "@babel/plugin-transform-unicode-escapes" "^7.18.10" "@babel/plugin-transform-unicode-regex" "^7.18.6" "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.18.9" - babel-plugin-polyfill-corejs2 "^0.3.1" - babel-plugin-polyfill-corejs3 "^0.5.2" - babel-plugin-polyfill-regenerator "^0.3.1" - core-js-compat "^3.22.1" + "@babel/types" "^7.19.0" + babel-plugin-polyfill-corejs2 "^0.3.3" + babel-plugin-polyfill-corejs3 "^0.6.0" + babel-plugin-polyfill-regenerator "^0.4.1" + core-js-compat "^3.25.1" semver "^6.3.0" "@babel/preset-modules@^0.1.5": @@ -1118,24 +1147,17 @@ "@babel/helper-validator-option" "^7.18.6" "@babel/plugin-transform-typescript" "^7.18.6" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" - integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.17.2": - version "7.17.8" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.8.tgz#3e56e4aff81befa55ac3ac6a0967349fd1c5bca2" - integrity sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA== +"@babel/runtime@^7.17.2", "@babel/runtime@^7.18.9", "@babel/runtime@^7.7.6": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259" + integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA== dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" - integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== +"@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" + integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== dependencies: regenerator-runtime "^0.13.4" @@ -1148,14 +1170,14 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/template@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31" - integrity sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw== +"@babel/template@^7.18.10", "@babel/template@^7.18.6": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" + integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== dependencies: "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.18.6" - "@babel/types" "^7.18.6" + "@babel/parser" "^7.18.10" + "@babel/types" "^7.18.10" "@babel/traverse@^7.0.0-beta.54", "@babel/traverse@^7.16.7": version "7.16.8" @@ -1173,19 +1195,19 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.9.tgz#deeff3e8f1bad9786874cb2feda7a2d77a904f98" - integrity sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg== +"@babel/traverse@^7.18.9", "@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.1.tgz#0fafe100a8c2a603b4718b1d9bf2568d1d193347" + integrity sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA== dependencies: "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.18.9" + "@babel/generator" "^7.19.0" "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" "@babel/helper-hoist-variables" "^7.18.6" "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.18.9" - "@babel/types" "^7.18.9" + "@babel/parser" "^7.19.1" + "@babel/types" "^7.19.0" debug "^4.1.0" globals "^11.1.0" @@ -1197,11 +1219,12 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" -"@babel/types@^7.18.6", "@babel/types@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.9.tgz#7148d64ba133d8d73a41b3172ac4b83a1452205f" - integrity sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg== +"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.0.tgz#75f21d73d73dc0351f3368d28db73465f4814600" + integrity sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA== dependencies: + "@babel/helper-string-parser" "^7.18.10" "@babel/helper-validator-identifier" "^7.18.6" to-fast-properties "^2.0.0" @@ -1210,14 +1233,14 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA== -"@eslint/eslintrc@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f" - integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw== +"@eslint/eslintrc@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.2.tgz#58b69582f3b7271d8fa67fe5251767a5b38ea356" + integrity sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.3.2" + espree "^9.4.0" globals "^13.15.0" ignore "^5.2.0" import-fresh "^3.2.1" @@ -1225,15 +1248,25 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@humanwhocodes/config-array@^0.9.2": - version "0.9.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.2.tgz#68be55c737023009dfc5fe245d51181bb6476914" - integrity sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA== +"@humanwhocodes/config-array@^0.10.4": + version "0.10.4" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.4.tgz#01e7366e57d2ad104feea63e72248f22015c520c" + integrity sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" minimatch "^3.0.4" +"@humanwhocodes/gitignore-to-minimatch@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d" + integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA== + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" @@ -1248,16 +1281,15 @@ update-notifier "^2.2.0" yargs "^8.0.2" -"@jridgewell/gen-mapping@^0.3.0": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz#cf92a983c83466b8c0ce9124fadeaf09f7c66ea9" - integrity sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg== +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== dependencies: "@jridgewell/set-array" "^1.0.0" "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/gen-mapping@^0.3.2": +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": version "0.3.2" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== @@ -1267,16 +1299,11 @@ "@jridgewell/trace-mapping" "^0.3.9" "@jridgewell/resolve-uri@^3.0.3": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c" - integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew== - -"@jridgewell/set-array@^1.0.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.1.tgz#36a6acc93987adcf0ba50c66908bd0b70de8afea" - integrity sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ== + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== -"@jridgewell/set-array@^1.0.1": +"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== @@ -1290,22 +1317,14 @@ "@jridgewell/trace-mapping" "^0.3.9" "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" - integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== - -"@jridgewell/trace-mapping@^0.3.0": - version "0.3.4" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" - integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== "@jridgewell/trace-mapping@^0.3.9": - version "0.3.13" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz#dcfe3e95f224c8fe97a87a5235defec999aa92ea" - integrity sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w== + version "0.3.15" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" + integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== dependencies: "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" @@ -1407,7 +1426,7 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": +"@types/express-serve-static-core@*": version "4.17.27" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz#7a776191e47295d2a05962ecbb3a4ce97e38b401" integrity sha512-e/sVallzUTPdyOTiqi8O8pMdBBphscvI6E4JYaKlja4Lm+zh7UFSSdW5VMkRbhDtmrONqOUHOXRguPsDckzxNA== @@ -1416,7 +1435,16 @@ "@types/qs" "*" "@types/range-parser" "*" -"@types/express@*", "@types/express@^4.17.13": +"@types/express-serve-static-core@^4.17.18": + version "4.17.31" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz#a1139efeab4e7323834bb0226e62ac019f474b2f" + integrity sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*": version "4.17.13" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== @@ -1426,6 +1454,16 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/express@^4.17.13": + version "4.17.14" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.14.tgz#143ea0557249bc1b3b54f15db4c81c3d4eb3569c" + integrity sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + "@types/glob@^7.1.1": version "7.2.0" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" @@ -1441,11 +1479,21 @@ dependencies: "@types/node" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8": version "7.0.9" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== +"@types/json-schema@^7.0.9": + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + +"@types/mime@*": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" + integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== + "@types/mime@^1": version "1.3.2" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" @@ -1464,15 +1512,10 @@ "@types/node" "*" form-data "^3.0.0" -"@types/node@*": - version "17.0.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.8.tgz#50d680c8a8a78fe30abe6906453b21ad8ab0ad7b" - integrity sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg== - -"@types/node@^18.6.2": - version "18.6.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.2.tgz#ffc5f0f099d27887c8d9067b54e55090fcd54126" - integrity sha512-KcfkBq9H4PI6Vpu5B/KoPeuVDAbmi+2mDBqGPGUgoL7yXQtcWGu2vJWmmRkneWK3Rh0nIAX192Aa87AqKHYChQ== +"@types/node@*", "@types/node@^18.6.2": + version "18.7.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.18.tgz#633184f55c322e4fb08612307c274ee6d5ed3154" + integrity sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg== "@types/qs@*": version "6.9.7" @@ -1501,7 +1544,15 @@ dependencies: "@types/express" "*" -"@types/serve-static@*", "@types/serve-static@^1.13.10": +"@types/serve-static@*": + version "1.15.0" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" + integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg== + dependencies: + "@types/mime" "*" + "@types/node" "*" + +"@types/serve-static@^1.13.10": version "1.13.10" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== @@ -1524,83 +1575,83 @@ "@types/node" "*" "@typescript-eslint/eslint-plugin@^5.31.0": - version "5.31.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.31.0.tgz#cae1967b1e569e6171bbc6bec2afa4e0c8efccfe" - integrity sha512-VKW4JPHzG5yhYQrQ1AzXgVgX8ZAJEvCz0QI6mLRX4tf7rnFfh5D8SKm0Pq6w5PyNfAWJk6sv313+nEt3ohWMBQ== + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.38.0.tgz#ac919a199548861012e8c1fb2ec4899ac2bc22ae" + integrity sha512-GgHi/GNuUbTOeoJiEANi0oI6fF3gBQc3bGFYj40nnAPCbhrtEDf2rjBmefFadweBmO1Du1YovHeDP2h5JLhtTQ== dependencies: - "@typescript-eslint/scope-manager" "5.31.0" - "@typescript-eslint/type-utils" "5.31.0" - "@typescript-eslint/utils" "5.31.0" + "@typescript-eslint/scope-manager" "5.38.0" + "@typescript-eslint/type-utils" "5.38.0" + "@typescript-eslint/utils" "5.38.0" debug "^4.3.4" - functional-red-black-tree "^1.0.1" ignore "^5.2.0" regexpp "^3.2.0" semver "^7.3.7" tsutils "^3.21.0" "@typescript-eslint/parser@^5.31.0": - version "5.31.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.31.0.tgz#7f42d7dcc68a0a6d80a0f3d9a65063aee7bb8d2c" - integrity sha512-UStjQiZ9OFTFReTrN+iGrC6O/ko9LVDhreEK5S3edmXgR396JGq7CoX2TWIptqt/ESzU2iRKXAHfSF2WJFcWHw== + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.38.0.tgz#5a59a1ff41a7b43aacd1bb2db54f6bf1c02b2ff8" + integrity sha512-/F63giJGLDr0ms1Cr8utDAxP2SPiglaD6V+pCOcG35P2jCqdfR7uuEhz1GIC3oy4hkUF8xA1XSXmd9hOh/a5EA== dependencies: - "@typescript-eslint/scope-manager" "5.31.0" - "@typescript-eslint/types" "5.31.0" - "@typescript-eslint/typescript-estree" "5.31.0" + "@typescript-eslint/scope-manager" "5.38.0" + "@typescript-eslint/types" "5.38.0" + "@typescript-eslint/typescript-estree" "5.38.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.31.0": - version "5.31.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.31.0.tgz#f47a794ba84d9b818ab7f8f44fff55a61016c606" - integrity sha512-8jfEzBYDBG88rcXFxajdVavGxb5/XKXyvWgvD8Qix3EEJLCFIdVloJw+r9ww0wbyNLOTYyBsR+4ALNGdlalLLg== +"@typescript-eslint/scope-manager@5.38.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.38.0.tgz#8f0927024b6b24e28671352c93b393a810ab4553" + integrity sha512-ByhHIuNyKD9giwkkLqzezZ9y5bALW8VNY6xXcP+VxoH4JBDKjU5WNnsiD4HJdglHECdV+lyaxhvQjTUbRboiTA== dependencies: - "@typescript-eslint/types" "5.31.0" - "@typescript-eslint/visitor-keys" "5.31.0" + "@typescript-eslint/types" "5.38.0" + "@typescript-eslint/visitor-keys" "5.38.0" -"@typescript-eslint/type-utils@5.31.0": - version "5.31.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.31.0.tgz#70a0b7201360b5adbddb0c36080495aa08f6f3d9" - integrity sha512-7ZYqFbvEvYXFn9ax02GsPcEOmuWNg+14HIf4q+oUuLnMbpJ6eHAivCg7tZMVwzrIuzX3QCeAOqKoyMZCv5xe+w== +"@typescript-eslint/type-utils@5.38.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.38.0.tgz#c8b7f681da825fcfc66ff2b63d70693880496876" + integrity sha512-iZq5USgybUcj/lfnbuelJ0j3K9dbs1I3RICAJY9NZZpDgBYXmuUlYQGzftpQA9wC8cKgtS6DASTvF3HrXwwozA== dependencies: - "@typescript-eslint/utils" "5.31.0" + "@typescript-eslint/typescript-estree" "5.38.0" + "@typescript-eslint/utils" "5.38.0" debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.31.0": - version "5.31.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.31.0.tgz#7aa389122b64b18e473c1672fb3b8310e5f07a9a" - integrity sha512-/f/rMaEseux+I4wmR6mfpM2wvtNZb1p9hAV77hWfuKc3pmaANp5dLAZSiE3/8oXTYTt3uV9KW5yZKJsMievp6g== +"@typescript-eslint/types@5.38.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.38.0.tgz#8cd15825e4874354e31800dcac321d07548b8a5f" + integrity sha512-HHu4yMjJ7i3Cb+8NUuRCdOGu2VMkfmKyIJsOr9PfkBVYLYrtMCK/Ap50Rpov+iKpxDTfnqvDbuPLgBE5FwUNfA== -"@typescript-eslint/typescript-estree@5.31.0": - version "5.31.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.31.0.tgz#eb92970c9d6e3946690d50c346fb9b1d745ee882" - integrity sha512-3S625TMcARX71wBc2qubHaoUwMEn+l9TCsaIzYI/ET31Xm2c9YQ+zhGgpydjorwQO9pLfR/6peTzS/0G3J/hDw== +"@typescript-eslint/typescript-estree@5.38.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.0.tgz#89f86b2279815c6fb7f57d68cf9b813f0dc25d98" + integrity sha512-6P0RuphkR+UuV7Avv7MU3hFoWaGcrgOdi8eTe1NwhMp2/GjUJoODBTRWzlHpZh6lFOaPmSvgxGlROa0Sg5Zbyg== dependencies: - "@typescript-eslint/types" "5.31.0" - "@typescript-eslint/visitor-keys" "5.31.0" + "@typescript-eslint/types" "5.38.0" + "@typescript-eslint/visitor-keys" "5.38.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.31.0": - version "5.31.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.31.0.tgz#e146fa00dca948bfe547d665b2138a2dc1b79acd" - integrity sha512-kcVPdQS6VIpVTQ7QnGNKMFtdJdvnStkqS5LeALr4rcwx11G6OWb2HB17NMPnlRHvaZP38hL9iK8DdE9Fne7NYg== +"@typescript-eslint/utils@5.38.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.38.0.tgz#5b31f4896471818153790700eb02ac869a1543f4" + integrity sha512-6sdeYaBgk9Fh7N2unEXGz+D+som2QCQGPAf1SxrkEr+Z32gMreQ0rparXTNGRRfYUWk/JzbGdcM8NSSd6oqnTA== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.31.0" - "@typescript-eslint/types" "5.31.0" - "@typescript-eslint/typescript-estree" "5.31.0" + "@typescript-eslint/scope-manager" "5.38.0" + "@typescript-eslint/types" "5.38.0" + "@typescript-eslint/typescript-estree" "5.38.0" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/visitor-keys@5.31.0": - version "5.31.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.31.0.tgz#b0eca264df01ce85dceb76aebff3784629258f54" - integrity sha512-ZK0jVxSjS4gnPirpVjXHz7mgdOsZUHzNYSfTw2yPa3agfbt9YfqaBiBZFSSxeBWnpWkzCxTfUpnzA3Vily/CSg== +"@typescript-eslint/visitor-keys@5.38.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.0.tgz#60591ca3bf78aa12b25002c0993d067c00887e34" + integrity sha512-MxnrdIyArnTi+XyFLR+kt/uNAcdOnmT+879os7qDRI+EYySR4crXJq9BXPfRzzLGq0wgxkwidrCJ9WCAoacm1w== dependencies: - "@typescript-eslint/types" "5.31.0" + "@typescript-eslint/types" "5.38.0" eslint-visitor-keys "^3.3.0" "@webassemblyjs/ast@1.11.1": @@ -1790,12 +1841,7 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.5.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" - integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== - -acorn@^8.7.1: +acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0: version "8.8.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== @@ -1994,6 +2040,17 @@ array-flatten@^2.1.2: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== +array-includes@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb" + integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + get-intrinsic "^1.1.1" + is-string "^1.0.7" + array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -2078,29 +2135,29 @@ babel-plugin-inferno@^6.5.0: "@babel/plugin-syntax-jsx" "^7" "@babel/types" "^7" -babel-plugin-polyfill-corejs2@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.2.tgz#e4c31d4c89b56f3cf85b92558954c66b54bd972d" - integrity sha512-LPnodUl3lS0/4wN3Rb+m+UK8s7lj2jcLRrjho4gLw+OJs+I4bvGXshINesY5xx/apM+biTnQ9reDI8yj+0M5+Q== +babel-plugin-polyfill-corejs2@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122" + integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== dependencies: "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.3.2" + "@babel/helper-define-polyfill-provider" "^0.3.3" semver "^6.1.1" -babel-plugin-polyfill-corejs3@^0.5.2: - version "0.5.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz#d7e09c9a899079d71a8b670c6181af56ec19c5c7" - integrity sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw== +babel-plugin-polyfill-corejs3@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz#56ad88237137eade485a71b52f72dbed57c6230a" + integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.2" - core-js-compat "^3.21.0" + "@babel/helper-define-polyfill-provider" "^0.3.3" + core-js-compat "^3.25.1" -babel-plugin-polyfill-regenerator@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" - integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A== +babel-plugin-polyfill-regenerator@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747" + integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.1" + "@babel/helper-define-polyfill-provider" "^0.3.3" balanced-match@^1.0.0: version "1.0.2" @@ -2187,14 +2244,14 @@ bonjour-service@^1.0.11: multicast-dns "^7.2.4" bootstrap@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.2.0.tgz#838727fb60f1630db370fe57c63cbcf2962bb3d3" - integrity sha512-qlnS9GL6YZE6Wnef46GxGv1UpGGzAwO0aPL1yOjzDIJpeApeMvqV24iL+pjr2kU4dduoBA9fINKWKgMToobx9A== + version "5.2.1" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.2.1.tgz#45f97ff05cbe828bad807b014d8425f3aeb8ec3a" + integrity sha512-UQi3v2NpVPEi1n35dmRRzBJFlgvWHYwyem6yHhuT6afYF+sziEt46McRbT//kVXZ7b1YUYEVGdXEH74Nx3xzGA== bootswatch@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/bootswatch/-/bootswatch-5.2.0.tgz#c02a0d84e0382552f8a7b9bdd055f36b758ffed9" - integrity sha512-v9krdPdybb5hUwVwlv3f7/FhOa5cXbCb5U5CI4gdnalcxR3ekclXE6kPZWL5O8V8qwNI9BB73apASO1MLmRpIA== + version "5.2.1" + resolved "https://registry.yarnpkg.com/bootswatch/-/bootswatch-5.2.1.tgz#80c49ac3ad394e58be630978c95e3bce1d1679ac" + integrity sha512-tbuZb0nJ1XUvRO8KYoEULsbAlAqazcFS6S5dTeJOkw2RxQgg0RJqKkngRTfNSFfqfI4mTdFPpC4mKkaw0YoDFA== boxen@^1.2.1: version "1.3.0" @@ -2217,6 +2274,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -2224,7 +2288,7 @@ braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.14.5, browserslist@^4.17.5: +browserslist@^4.14.5: version "4.19.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== @@ -2235,15 +2299,15 @@ browserslist@^4.14.5, browserslist@^4.17.5: node-releases "^2.0.1" picocolors "^1.0.0" -browserslist@^4.20.2, browserslist@^4.21.2: - version "4.21.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" - integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== +browserslist@^4.17.5, browserslist@^4.21.3, browserslist@^4.21.4: + version "4.21.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" + integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== dependencies: - caniuse-lite "^1.0.30001370" - electron-to-chromium "^1.4.202" + caniuse-lite "^1.0.30001400" + electron-to-chromium "^1.4.251" node-releases "^2.0.6" - update-browserslist-db "^1.0.5" + update-browserslist-db "^1.0.9" buffer-from@^1.0.0: version "1.1.2" @@ -2371,15 +2435,10 @@ camelcase@^5.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-lite@^1.0.30001286: - version "1.0.30001298" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001298.tgz#0e690039f62e91c3ea581673d716890512e7ec52" - integrity sha512-AcKqikjMLlvghZL/vfTHorlQsLDhGRalYf1+GmWCf5SCMziSGjRYQW/JEksj14NaYHIR6KIhrFAy0HV5C25UzQ== - -caniuse-lite@^1.0.30001370: - version "1.0.30001373" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz#2dc3bc3bfcb5d5a929bec11300883040d7b4b4be" - integrity sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ== +caniuse-lite@^1.0.30001286, caniuse-lite@^1.0.30001400: + version "1.0.30001409" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001409.tgz#6135da9dcab34cd9761d9cdb12a68e6740c5e96e" + integrity sha512-V0mnJ5dwarmhYv8/MzhJ//aW68UpvnQBXv8lJ2QUsvn2pHcmAuNtu8hQEDz37XnA1iE+lRR9CIfGWWpgJ5QedQ== capture-stack-trace@^1.0.0: version "1.0.1" @@ -2422,22 +2481,7 @@ choices.js@^10.1.0: fuse.js "^6.5.3" redux "^4.1.2" -"chokidar@>=3.0.0 <4.0.0": - version "3.5.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" - integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chokidar@^3.5.3: +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -2483,9 +2527,9 @@ class-transformer@^0.5.1: integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw== classnames@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" - integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== + version "2.3.2" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" + integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== clean-stack@^2.0.0: version "2.2.0" @@ -2625,7 +2669,7 @@ color-convert@^2.0.1: color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== color-name@~1.1.4: version "1.1.4" @@ -2705,7 +2749,7 @@ compression@^1.7.4: concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== concat-stream@^1.5.0, concat-stream@^1.5.2: version "1.6.2" @@ -2805,13 +2849,12 @@ copy-webpack-plugin@^11.0.0: schema-utils "^4.0.0" serialize-javascript "^6.0.0" -core-js-compat@^3.21.0, core-js-compat@^3.22.1: - version "3.24.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.24.0.tgz#885958fac38bf3f4464a90f2663b4620f6aee6e3" - integrity sha512-F+2E63X3ff/nj8uIrf8Rf24UDGIz7p838+xjEp+Bx3y8OWXj+VTPPZNCtdqovPaS9o7Tka5mCH01Zn5vOd6UQg== +core-js-compat@^3.25.1: + version "3.25.2" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.25.2.tgz#7875573586809909c69e03ef310810c1969ee138" + integrity sha512-TxfyECD4smdn3/CjWxczVtJqVLEEC2up7/82t7vC0AzNogr+4nQ8vyF7abxAuTXWvjTClSbvGhU0RgqA4ToQaQ== dependencies: - browserslist "^4.21.2" - semver "7.0.0" + browserslist "^4.21.4" core-util-is@1.0.2: version "1.0.2" @@ -2882,6 +2925,11 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== +csstype@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" + integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== + cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" @@ -2915,14 +2963,7 @@ debug@^3.1.0: dependencies: ms "^2.1.1" -debug@^4.1.0, debug@^4.1.1, debug@^4.3.2: - version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - -debug@^4.3.4: +debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -2997,6 +3038,14 @@ define-properties@^1.1.3: dependencies: object-keys "^1.0.12" +define-properties@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + del@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" @@ -3144,15 +3193,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.4.17: - version "1.4.41" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.41.tgz#0b2e126796e7fafb9fd71e29304468b9d0af5d65" - integrity sha512-VQEXEJc+8rJIva85H8EPtB5Ux9g8TzkNGBanqphM9ZWMZ34elueKJ+5g+BPhz3Lk8gkujfQRcIZ+fpA0btUIuw== - -electron-to-chromium@^1.4.202: - version "1.4.206" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.206.tgz#580ff85b54d7ec0c05f20b1e37ea0becdd7b0ee4" - integrity sha512-h+Fadt1gIaQ06JaIiyqPsBjJ08fV5Q7md+V8bUvQW/9OvXfL2LRICTz2EcnnCP7QzrFTS6/27MRV6Bl9Yn97zA== +electron-to-chromium@^1.4.17, electron-to-chromium@^1.4.251: + version "1.4.256" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.256.tgz#c735032f412505e8e0482f147a8ff10cfca45bf4" + integrity sha512-x+JnqyluoJv8I0U9gVe+Sk2st8vF0CzMt78SXxuoWCooLLY2k5VerIBdpvG7ql6GKI4dzNnPjmqgDJ76EdaAKw== emoji-regex@^7.0.1: version "7.0.3" @@ -3240,6 +3284,35 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +es-abstract@^1.19.0, es-abstract@^1.19.5: + version "1.20.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.2.tgz#8495a07bc56d342a3b8ea3ab01bd986700c2ccb3" + integrity sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.1.2" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-weakref "^1.0.2" + object-inspect "^1.12.2" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.4.3" + string.prototype.trimend "^1.0.5" + string.prototype.trimstart "^1.0.5" + unbox-primitive "^1.0.2" + es-abstract@^1.19.1: version "1.19.1" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" @@ -3305,13 +3378,29 @@ escape-html@~1.0.3: escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +eslint-plugin-inferno@^7.31.8: + version "7.31.8" + resolved "https://registry.yarnpkg.com/eslint-plugin-inferno/-/eslint-plugin-inferno-7.31.8.tgz#4f83ed446a14d428a791188cc10ea07080563f77" + integrity sha512-3ZfdlZB8qDzKgRo28MuNWXOwwpxPuDBvwl6SwgBmz9uRKrAUTvxWT3/GzVCoYvhFTLmgo6Z7UVKV5wvJucnNbw== + dependencies: + doctrine "^3.0.0" + estraverse "^5.3.0" + jsx-ast-utils "^3.3.3" + minimatch "^5.1.0" + object.entries "^1.1.5" + object.fromentries "^2.0.5" + object.hasown "^1.1.1" + object.values "^1.1.5" + prop-types "^15.8.1" + resolve "^2.0.0-next.4" + eslint-plugin-prettier@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" @@ -3353,12 +3442,14 @@ eslint-visitor-keys@^3.3.0: integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== eslint@^8.20.0: - version "8.20.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.20.0.tgz#048ac56aa18529967da8354a478be4ec0a2bc81b" - integrity sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA== - dependencies: - "@eslint/eslintrc" "^1.3.0" - "@humanwhocodes/config-array" "^0.9.2" + version "8.23.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.23.1.tgz#cfd7b3f7fdd07db8d16b4ac0516a29c8d8dca5dc" + integrity sha512-w7C1IXCc6fNqjpuYd0yPlcTKKmHlHHktRkzmBPZ+7cvNBQuiNjx0xaMTjAJGCafJhQkrFJooREv0CtrVzmHwqg== + dependencies: + "@eslint/eslintrc" "^1.3.2" + "@humanwhocodes/config-array" "^0.10.4" + "@humanwhocodes/gitignore-to-minimatch" "^1.0.2" + "@humanwhocodes/module-importer" "^1.0.1" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -3368,18 +3459,21 @@ eslint@^8.20.0: eslint-scope "^7.1.1" eslint-utils "^3.0.0" eslint-visitor-keys "^3.3.0" - espree "^9.3.2" + espree "^9.4.0" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" + find-up "^5.0.0" glob-parent "^6.0.1" globals "^13.15.0" + globby "^11.1.0" + grapheme-splitter "^1.0.4" ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" + js-sdsl "^4.1.4" js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" @@ -3391,14 +3485,13 @@ eslint@^8.20.0: strip-ansi "^6.0.1" strip-json-comments "^3.1.0" text-table "^0.2.0" - v8-compile-cache "^2.0.3" -espree@^9.3.2: - version "9.3.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.2.tgz#f58f77bd334731182801ced3380a8cc859091596" - integrity sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA== +espree@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" + integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== dependencies: - acorn "^8.7.1" + acorn "^8.8.0" acorn-jsx "^5.3.2" eslint-visitor-keys "^3.3.0" @@ -3426,7 +3519,7 @@ estraverse@^4.1.1: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -estraverse@^5.1.0, estraverse@^5.2.0: +estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== @@ -3598,7 +3691,7 @@ fast-diff@^1.1.2: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== -fast-glob@^3.0.3, fast-glob@^3.2.9: +fast-glob@^3.0.3: version "3.2.10" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.10.tgz#2734f83baa7f43b7fd41e13bc34438f4ffe284ee" integrity sha512-s9nFhFnvR63wls6/kM88kQqDhMu0AfdjqouE2l5GVQPbqLgyFjjU5ry/r2yKsJxpb9Py1EYNqieFrmMaX4v++A== @@ -3620,6 +3713,17 @@ fast-glob@^3.2.11: merge2 "^1.3.0" micromatch "^4.0.4" +fast-glob@^3.2.9: + version "3.2.12" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -3628,7 +3732,7 @@ fast-json-stable-stringify@^2.0.0: fast-levenshtein@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastest-levenshtein@^1.0.12: version "1.0.12" @@ -3732,6 +3836,14 @@ find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + flat-cache@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" @@ -3741,9 +3853,9 @@ flat-cache@^3.0.4: rimraf "^3.0.2" flatted@^3.1.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2" - integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw== + version "3.2.7" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== flush-write-stream@^1.0.0: version "1.1.1" @@ -3863,10 +3975,20 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + functions-have-names "^1.2.2" + +functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== fuse.js@^6.5.3: version "6.5.3" @@ -3933,6 +4055,15 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.1" +get-intrinsic@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" + integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -4100,6 +4231,11 @@ graceful-fs@~4.1.11: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + handle-thing@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" @@ -4123,21 +4259,38 @@ has-bigints@^1.0.1: resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== +has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + has-symbols@^1.0.1, has-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + has-tostringtag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" @@ -4157,17 +4310,12 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -history@^4.10.1: - version "4.10.1" - resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" - integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== +history@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b" + integrity sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ== dependencies: - "@babel/runtime" "^7.1.2" - loose-envify "^1.2.0" - resolve-pathname "^3.0.0" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - value-equal "^1.0.1" + "@babel/runtime" "^7.7.6" hoist-non-inferno-statics@^1.1.3: version "1.1.3" @@ -4305,9 +4453,9 @@ husky@^8.0.1: integrity sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw== i18next@^21.8.14: - version "21.8.14" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.8.14.tgz#03a3a669ef4520aadd9d152c80596f600e287c6a" - integrity sha512-4Yi+DtexvMm/Yw3Q9fllzY12SgLk+Mcmar+rCAccsOPul/2UmnBzoHbTGn/L48IPkFcmrNaH7xTLboBWIbH6pw== + version "21.9.2" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.9.2.tgz#3f7c5594393eb27117c1db4c38f5ec766e68de0e" + integrity sha512-00fVrLQOwy45nm3OtC9l1WiLK3nJlIYSljgCt0qzTaAy65aciMdRy9GsuW+a2AtKtdg9/njUGfRH30LRupV7ZQ== dependencies: "@babel/runtime" "^7.17.2" @@ -4348,9 +4496,9 @@ ignore@^5.1.1, ignore@^5.2.0: integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== immutable@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23" - integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw== + version "4.1.0" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.1.0.tgz#f795787f0db780183307b9eb2091fcac1f6fafef" + integrity sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ== import-fresh@^2.0.0: version "2.0.0" @@ -4438,7 +4586,7 @@ import-sort@^6.0.0: imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== indent-string@^4.0.0: version "4.0.0" @@ -4450,19 +4598,19 @@ infer-owner@^1.0.4: resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== -inferno-clone-vnode@^7.4.2: - version "7.4.11" - resolved "https://registry.yarnpkg.com/inferno-clone-vnode/-/inferno-clone-vnode-7.4.11.tgz#1bcce4ff6ac9ea2986766b17aee1d1a22b158558" - integrity sha512-6/newyzWO/lrwcA9q5DBAfslccPWqhpgrDQg/wWiHKZwRBe1kJjtiALsR+/1wLq1Z+YO3L1MPnlEnFu+nltUbA== +inferno-clone-vnode@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/inferno-clone-vnode/-/inferno-clone-vnode-8.0.3.tgz#01feac1f06226f59cbdcc07d513d4d23fbbe3d03" + integrity sha512-WPwbxwKHgT6rO++RLvJvF5pPuwxPwpH6dupDorWqkRmRwEyzszvtUJG5C2VSA3LEhH2iyV4+wC28hhtRwHN6+w== dependencies: - inferno "7.4.11" + inferno "8.0.3" -inferno-create-element@^7.4.11, inferno-create-element@^7.4.2: - version "7.4.11" - resolved "https://registry.yarnpkg.com/inferno-create-element/-/inferno-create-element-7.4.11.tgz#1690b3ad28b61be93765b11b409dc9a9a35bf63a" - integrity sha512-kE6XIx2hPAd5qpDli2iGjNXgubvuyxdLvoiW71WnSzIIxA+Uxa/s8lY8m03VyHHVypFV3n329ZY5dFvKc7UQMg== +inferno-create-element@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/inferno-create-element/-/inferno-create-element-8.0.3.tgz#883961e497b4ab7359c1ef19a1f5388fe81137d6" + integrity sha512-eQ7GLpC1lGB8+BaeFvNHo6Dl3fKfbv3kobWgw5qYttRPeMaufIfn0lEkhzx2anx1Hv99INwPl+9jbpybciQLTQ== dependencies: - inferno "7.4.11" + inferno "8.0.3" inferno-helmet@^5.2.1: version "5.2.1" @@ -4473,46 +4621,46 @@ inferno-helmet@^5.2.1: inferno-side-effect "^1.1.5" object-assign "^4.1.1" -inferno-hydrate@^7.4.11: - version "7.4.11" - resolved "https://registry.yarnpkg.com/inferno-hydrate/-/inferno-hydrate-7.4.11.tgz#275027585268055f7d741c21978d7b5065169a3a" - integrity sha512-hF9Ke4GHAkj8GQrMXBZPfsUqhq6WjkoDCAfXhPBuF1Wiceqyy8KerOOXEnuocHky77fuEXq0AzVnQcC064Bkfw== +inferno-hydrate@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/inferno-hydrate/-/inferno-hydrate-8.0.3.tgz#75c3c53300a7b7b550dfa93f363956201d86f71f" + integrity sha512-7q1BDuVIy3XCmyKlAJhe+s1CLJhl3+gfFcBpjCq9iA7J/Z3kwo/6xjwJQbcQHNrCr/XZvTM+2uVwfxiX6wgYCQ== dependencies: - inferno "7.4.11" + inferno "8.0.3" -inferno-i18next-dess@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/inferno-i18next-dess/-/inferno-i18next-dess-0.0.1.tgz#48ae6bb4c3a617e59ff8dc97b9ed70f2ef762206" - integrity sha512-z/6UnuWFMyBivfR3SI9AmgA0/JvXARqtG/9BQryaLPenlG7iAb4cN2TeSt0mHIgFOo01QHVWZ8dqn7jZRijp2Q== +inferno-i18next-dess@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/inferno-i18next-dess/-/inferno-i18next-dess-0.0.2.tgz#4cd4e3e2e1d900212b399a85dbfd4015e887039b" + integrity sha512-TkpBTZzfqgK7O8gIJ7gLB9CvP1bEOfO8OA7vUfJpd2kgGom9eoj6xbAMUPk5BNH6nBN5Y+mCaG/dInQjW5Jkug== dependencies: html-parse-stringify2 "^2.0.1" - inferno "^7.4.2" - inferno-clone-vnode "^7.4.2" - inferno-create-element "^7.4.2" - inferno-shared "^7.4.2" - inferno-vnode-flags "^7.4.2" - -inferno-router@^7.4.11: - version "7.4.11" - resolved "https://registry.yarnpkg.com/inferno-router/-/inferno-router-7.4.11.tgz#80bd47bf7c059a219cad9f3857585023fd55781f" - integrity sha512-7H5OTpoxGjRl2wtF1exFdlFVmO3k6EhNm0yMSfk34DOEEDqiIpy0QiWx0Q0nn7Mm2Wddgdt31RAl69/k/GuBYA== - dependencies: - history "^4.10.1" + inferno "^8.0.3" + inferno-clone-vnode "^8.0.3" + inferno-create-element "^8.0.3" + inferno-shared "^8.0.3" + inferno-vnode-flags "^8.0.3" + +inferno-router@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/inferno-router/-/inferno-router-8.0.3.tgz#ef08da8b0cb158b8920147b260a4f84c64bc3877" + integrity sha512-bWkrFfIBDued0LfS/x6Bot3+J3VwGImH3ukSdIFe/GLFPBljDbvayc1JotriJtNFKA1E+1T/OZyw1E6UqIcDaA== + dependencies: + history "^5.3.0" hoist-non-inferno-statics "^1.1.3" - inferno "7.4.11" + inferno "8.0.3" path-to-regexp-es6 "1.7.0" -inferno-server@^7.4.11: - version "7.4.11" - resolved "https://registry.yarnpkg.com/inferno-server/-/inferno-server-7.4.11.tgz#05ec0f7ceea4a30da412baaccbbfeca258db27cf" - integrity sha512-SUnkCqZNWOIrjRVoVk/E1/70O1f1ImkCX9H2gDPbS0uc3GDxuzIeCgn0rpcc0XV9KzZJ2LTGxuBtEoQQOjUn2Q== +inferno-server@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/inferno-server/-/inferno-server-8.0.3.tgz#4030ac5f20d9ddf191163daa10d3ef4e8b0c4593" + integrity sha512-YG9f9e0KsVGV6qByWCkFoGI80SckqIptHtTHMoVHsAbw3krzX414zxwA5H9OTnkubJJsSHBjVtFxaq6hHT/YcA== dependencies: - inferno "7.4.11" + inferno "8.0.3" -inferno-shared@7.4.11, inferno-shared@^7.4.2: - version "7.4.11" - resolved "https://registry.yarnpkg.com/inferno-shared/-/inferno-shared-7.4.11.tgz#6e06e0668c4dad5f8b1fd4c688e1072faa6f1e87" - integrity sha512-pN725bDSTxkQmRS3e/3H02/xAqgHl+xgddCMjPm8M0etRdRcVCisi3NGPhzSbDDmiftrxhY31exs7+dwsngcDA== +inferno-shared@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/inferno-shared/-/inferno-shared-8.0.3.tgz#74c0cdd523937763d01945b50b65690a7064a957" + integrity sha512-+1ZV0DtBnYFfb5WF2FXSnCYjejGGl2BZhN5hMNRwfColRKd08N2r2i0EyLSDlTM1yB5n7BW2YdOegMf3YsV4yQ== inferno-side-effect@^1.1.5: version "1.1.5" @@ -4523,18 +4671,18 @@ inferno-side-effect@^1.1.5: npm "^5.8.0" shallowequal "^1.0.1" -inferno-vnode-flags@7.4.11, inferno-vnode-flags@^7.4.2: - version "7.4.11" - resolved "https://registry.yarnpkg.com/inferno-vnode-flags/-/inferno-vnode-flags-7.4.11.tgz#642a835a8dde514f244296b27c176a2b8704fbac" - integrity sha512-L7lslEQCq3IfwgT/b9zhuMf8fv6KXCNXXHZevk/WYxnqJsOWGDcKpJn0zkzXfvmj0otbB149iLUQVBq3oe2sfA== +inferno-vnode-flags@8.0.3, inferno-vnode-flags@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/inferno-vnode-flags/-/inferno-vnode-flags-8.0.3.tgz#1bd78745033719596211155ae673bd648b266a78" + integrity sha512-r+wJZNliJWvtcwBd66L3fMSp+M0rinHLilZeLiAX87+ZVPoXKiTDLVmTRI+1j8dm1XmC3IuAHijVfwELnEmoCQ== -inferno@7.4.11, inferno@^7.4.11, inferno@^7.4.2: - version "7.4.11" - resolved "https://registry.yarnpkg.com/inferno/-/inferno-7.4.11.tgz#fcee308cf0e4a2f6066d96da74e3b425583bfc66" - integrity sha512-N+cs33ESWI8fdToCd98yMRYl7jkLnCkJskxov3FKKlaKOvk3PRlAttbhmUaYdWXlRvt2WeXi+J4MbzNj3V6G0w== +inferno@8.0.3, inferno@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/inferno/-/inferno-8.0.3.tgz#99124f050a9c60995dbdeef8ac258a936df7e62e" + integrity sha512-EZJyGfnlNoX4rQj9oX09ZqPmG8Ejrzqb/Y5O1D+QBN84VJ8uQGTqhZdmz3n7mhUnSyHg7VLt+rlbLnlTI4bs4g== dependencies: - inferno-shared "7.4.11" - inferno-vnode-flags "7.4.11" + csstype "^3.1.0" + inferno-vnode-flags "8.0.3" opencollective-postinstall "^2.0.3" inflight@^1.0.4, inflight@~1.0.6: @@ -4676,10 +4824,10 @@ is-cidr@~1.0.0: dependencies: cidr-regex "1.0.6" -is-core-module@^2.8.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" - integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== +is-core-module@^2.8.0, is-core-module@^2.9.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" + integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== dependencies: has "^1.0.3" @@ -4703,7 +4851,7 @@ is-docker@^2.0.0, is-docker@^2.1.1: is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^1.0.0: version "1.0.0" @@ -4742,7 +4890,7 @@ is-installed-globally@^0.1.0: global-dirs "^0.1.0" is-path-inside "^1.0.0" -is-negative-zero@^2.0.1: +is-negative-zero@^2.0.1, is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== @@ -4835,6 +4983,13 @@ is-shared-array-buffer@^1.0.1: resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + is-stream@^1.0.0, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -4869,7 +5024,7 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -is-weakref@^1.0.1: +is-weakref@^1.0.1, is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== @@ -4896,7 +5051,7 @@ isarray@~1.0.0: isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== isobject@^3.0.1: version "3.0.1" @@ -4925,6 +5080,11 @@ jest-worker@^27.4.1: merge-stream "^2.0.0" supports-color "^8.0.0" +js-sdsl@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.4.tgz#78793c90f80e8430b7d8dc94515b6c77d98a26a6" + integrity sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -4988,7 +5148,7 @@ json-schema@0.4.0: json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== json-stringify-safe@~5.0.1: version "5.0.1" @@ -5022,6 +5182,14 @@ jsprim@^1.2.2: json-schema "0.4.0" verror "1.10.0" +jsx-ast-utils@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" + integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== + dependencies: + array-includes "^3.1.5" + object.assign "^4.1.3" + jwt-decode@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59" @@ -5201,6 +5369,13 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lock-verify@^2.0.2: version "2.2.1" resolved "https://registry.yarnpkg.com/lock-verify/-/lock-verify-2.2.1.tgz#81107948c51ed16f97b96ff8b60675affb243fc1" @@ -5243,7 +5418,7 @@ lodash.clonedeep@~4.5.0: lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== lodash.merge@^4.6.2: version "4.6.2" @@ -5285,7 +5460,7 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" -loose-envify@^1.2.0: +loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -5483,7 +5658,7 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -micromatch@^4.0.2, micromatch@^4.0.4: +micromatch@^4.0.2: version "4.0.4" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== @@ -5491,7 +5666,7 @@ micromatch@^4.0.2, micromatch@^4.0.4: braces "^3.0.1" picomatch "^2.2.3" -micromatch@^4.0.5: +micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -5562,20 +5737,20 @@ minimalistic-assert@^1.0.0: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" +minimatch@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" + integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" @@ -5704,7 +5879,7 @@ nanoid@^3.3.1: natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== negotiator@0.6.2: version "0.6.2" @@ -5731,9 +5906,9 @@ node-fetch-npm@^2.0.2: safe-buffer "^5.1.1" node-fetch@^2.6.1: - version "2.6.6" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89" - integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA== + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== dependencies: whatwg-url "^5.0.0" @@ -5777,12 +5952,7 @@ node-gyp@^4.0.0: tar "^4.4.8" which "1" -node-releases@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" - integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== - -node-releases@^2.0.6: +node-releases@^2.0.1, node-releases@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== @@ -6150,6 +6320,34 @@ object.assign@^4.1.0, object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" +object.assign@^4.1.3, object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.entries@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" + integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +object.fromentries@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251" + integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + object.getownpropertydescriptors@^2.0.3: version "2.1.3" resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz#b223cf38e17fefb97a63c10c91df72ccb386df9e" @@ -6159,6 +6357,23 @@ object.getownpropertydescriptors@^2.0.3: define-properties "^1.1.3" es-abstract "^1.19.1" +object.hasown@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.1.tgz#ad1eecc60d03f49460600430d97f23882cf592a3" + integrity sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A== + dependencies: + define-properties "^1.1.4" + es-abstract "^1.19.5" + +object.values@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" + integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" @@ -6274,6 +6489,13 @@ p-limit@^2.0.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -6295,6 +6517,13 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-map@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" @@ -6635,9 +6864,9 @@ prettier-plugin-import-sort@^0.0.7: import-sort-parser-typescript "^6.0.0" prettier-plugin-organize-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.0.0.tgz#39739423cc7069f2a3bfa58d14f8a502ff163df2" - integrity sha512-juSCJs5TMOqGGPaN/A/1xzWFzRPH2LG1LPLCr64dzKaVnPafJdtgDNmDVlU+8A4LbQzVJg0DTvgA8swBuIUhlg== + version "3.1.1" + resolved "https://registry.yarnpkg.com/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.1.1.tgz#e581cb6fa528cf72f7d95b807ce38c3e51c3c27c" + integrity sha512-6bHIQzybqA644h0WGUW3gpWEVbMBvzui5wCMRBi7qA++d5ov2xjjfDk8pxJJ/ardfZrGAwizKMq/fQMFdJ+0Zw== prettier-plugin-packagejson@^2.2.18: version "2.2.18" @@ -6676,6 +6905,15 @@ promzard@^0.3.0: dependencies: read "1" +prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + proto-list@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" @@ -6818,6 +7056,11 @@ rc@^1.0.1, rc@^1.1.6: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + read-cmd-shim@^1.0.1, read-cmd-shim@~1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz#87e43eba50098ba5a32d0ceb583ab8e43b961c16" @@ -6989,6 +7232,15 @@ regexp.prototype.flags@^1.2.0: call-bind "^1.0.2" define-properties "^1.1.3" +regexp.prototype.flags@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + functions-have-names "^1.2.2" + regexpp@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" @@ -7135,12 +7387,7 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve-pathname@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" - integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== - -resolve@^1.10.0, resolve@^1.14.2, resolve@^1.8.1, resolve@^1.9.0: +resolve@^1.10.0, resolve@^1.8.1, resolve@^1.9.0: version "1.21.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.21.0.tgz#b51adc97f3472e6a5cf4444d34bc9d6b9037591f" integrity sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA== @@ -7149,6 +7396,24 @@ resolve@^1.10.0, resolve@^1.14.2, resolve@^1.8.1, resolve@^1.9.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@^1.14.2: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@^2.0.0-next.4: + version "2.0.0-next.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660" + integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + restore-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" @@ -7260,9 +7525,9 @@ sass-loader@^13.0.2: neo-async "^2.6.2" sass@^1.54.0: - version "1.54.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.54.0.tgz#24873673265e2a4fe3d3a997f714971db2fba1f4" - integrity sha512-C4zp79GCXZfK0yoHZg+GxF818/aclhp9F48XBu/+bm9vXEVAYov9iU3FBVRMq3Hx3OA4jfKL+p2K9180mEh0xQ== + version "1.54.9" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.54.9.tgz#b05f14ed572869218d1a76961de60cd647221762" + integrity sha512-xb1hjASzEH+0L0WI9oFjqhRi51t/gagWnxLiwUNMltA0Ab6jIDkAacgKiGYKM9Jhy109osM7woEEai6SXeJo5Q== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" @@ -7301,10 +7566,10 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= -selfsigned@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" - integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== +selfsigned@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" + integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== dependencies: node-forge "^1" @@ -7320,11 +7585,6 @@ semver-diff@^2.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -7603,12 +7863,7 @@ sortpack@^2.3.0: resolved "https://registry.yarnpkg.com/sortpack/-/sortpack-2.3.0.tgz#90d4688e61a91fa1da61e1b0f04dab327b94a3e8" integrity sha512-BkqYsA2ksQkVlk2xrwEZoWaz8y26ZMLEkrgdUjrkU5GDysCBoFmDt76D+P8hfJsu9AGdsqqK8XrEpH37ZjG7yw== -"source-map-js@>=0.6.2 <2.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" - integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== - -source-map-js@^1.0.2: +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== @@ -7817,6 +8072,15 @@ string.prototype.trimend@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" +string.prototype.trimend@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" + integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + string.prototype.trimstart@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" @@ -7825,6 +8089,15 @@ string.prototype.trimstart@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" +string.prototype.trimstart@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" + integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -7986,9 +8259,9 @@ terser-webpack-plugin@^5.1.3: terser "^5.7.2" terser@^5.14.2: - version "5.14.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" - integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== + version "5.15.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.15.0.tgz#e16967894eeba6e1091509ec83f0c60e179f2425" + integrity sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA== dependencies: "@jridgewell/source-map" "^0.3.2" acorn "^8.5.0" @@ -8032,21 +8305,11 @@ timed-out@^4.0.0: resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= -tiny-invariant@^1.0.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz#a1141f86b672a9148c72e978a19a73b9b94a15a9" - integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg== - tiny-relative-date@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz#fa08aad501ed730f31cc043181d995c39a935e07" integrity sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A== -tiny-warning@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" - integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== - tippy.js@^6.3.7: version "6.3.7" resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.7.tgz#8ccfb651d642010ed9a32ff29b0e9e19c5b8c61c" @@ -8057,7 +8320,7 @@ tippy.js@^6.3.7: to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== to-regex-range@^5.0.1: version "5.0.1" @@ -8087,7 +8350,7 @@ tough-cookie@~2.5.0: tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== tributejs@^5.1.3: version "5.1.3" @@ -8159,9 +8422,9 @@ typescript@^3.2.4: integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== typescript@^4.7.4: - version "4.7.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" - integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== + version "4.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.3.tgz#d59344522c4bc464a65a730ac695007fdb66dd88" + integrity sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig== uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" @@ -8188,6 +8451,16 @@ unbox-primitive@^1.0.1: has-symbols "^1.0.2" which-boxed-primitive "^1.0.2" +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" @@ -8242,10 +8515,10 @@ unzip-response@^2.0.1: resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= -update-browserslist-db@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" - integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== +update-browserslist-db@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz#2924d3927367a38d5c555413a7ce138fc95fcb18" + integrity sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg== dependencies: escalade "^3.1.1" picocolors "^1.0.0" @@ -8312,11 +8585,6 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -8332,11 +8600,6 @@ validate-npm-package-name@^3.0.0, validate-npm-package-name@~3.0.0: dependencies: builtins "^1.0.3" -value-equal@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" - integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== - vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -8381,7 +8644,7 @@ wcwidth@^1.0.0: webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== webpack-cli@^4.10.0: version "4.10.0" @@ -8412,10 +8675,10 @@ webpack-dev-middleware@^5.3.1: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@4.9.3: - version "4.9.3" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.9.3.tgz#2360a5d6d532acb5410a668417ad549ee3b8a3c9" - integrity sha512-3qp/eoboZG5/6QgiZ3llN8TUzkSpYg1Ko9khWX1h40MIEUNS2mDoIa8aXsPfskER+GbTvs/IJZ1QTBBhhuetSw== +webpack-dev-server@4.11.1: + version "4.11.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz#ae07f0d71ca0438cf88446f09029b92ce81380b5" + integrity sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" @@ -8440,7 +8703,7 @@ webpack-dev-server@4.9.3: p-retry "^4.5.0" rimraf "^3.0.2" schema-utils "^4.0.0" - selfsigned "^2.0.1" + selfsigned "^2.1.1" serve-index "^1.9.1" sockjs "^0.3.24" spdy "^4.0.2" @@ -8517,7 +8780,7 @@ websocket-ts@^1.1.1: whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== dependencies: tr46 "~0.0.3" webidl-conversions "^3.0.0" @@ -8727,3 +8990,8 @@ yargs@^8.0.2: which-module "^2.0.0" y18n "^3.2.1" yargs-parser "^7.0.0" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==