diff --git a/README.md b/README.md
index e1e6e1fd..f1917bff 100644
--- a/README.md
+++ b/README.md
@@ -1,21 +1,20 @@
-# lemmy-ui
-
-The official web app for [Lemmy](https://github.com/LemmyNet/lemmy), written in inferno.
-
-Based off of MrFoxPro's [inferno-isomorphic-template](https://github.com/MrFoxPro/inferno-isomorphic-template).
-
-## Configuration
-
-The following environment variables can be used to configure lemmy-ui:
-
-`ENV_VAR` | type | default | description
---- | --- | --- | ---
-`LEMMY_UI_HOST` | `string` | `0.0.0.0:1234` | The IP / port that the lemmy-ui isomorphic node server is hosted at.
-`LEMMY_UI_LEMMY_INTERNAL_HOST` | `string` | `0.0.0.0:8536` | The internal IP / port that lemmy is hosted at. Often `lemmy:8536` if using docker.
-`LEMMY_UI_LEMMY_EXTERNAL_HOST` | `string` | `0.0.0.0:8536` | The external IP / port that lemmy is hosted at. Often `DOMAIN.TLD`.
-`LEMMY_UI_LEMMY_WS_HOST` | `string` | `0.0.0.0:8536` | An alternate location for lemmy's websocket address. Not usually necessary.
-`LEMMY_UI_HTTPS` | `bool` | `false` | Whether to use https.
-`LEMMY_UI_EXTRA_THEMES_FOLDER` | `string` | `./extra_themes` | A location for additional lemmy css themes.
-`LEMMY_UI_DEBUG` | `bool` | `false` | Loads the [Eruda](https://github.com/liriliri/eruda) debugging utility.
-`LEMMY_UI_DISABLE_CSP` | `bool` | `false` | Disables CSP security headers
-`LEMMY_UI_CUSTOM_HTML_HEADER` | `string` | | Injects a custom script into `
`.
+# Lemmy-UI
+
+The official web app for [Lemmy](https://github.com/LemmyNet/lemmy), written in inferno.
+
+Based off of MrFoxPro's [inferno-isomorphic-template](https://github.com/MrFoxPro/inferno-isomorphic-template).
+
+## Configuration
+
+The following environment variables can be used to configure lemmy-ui:
+
+| `ENV_VAR` | type | default | description |
+| ------------------------------ | -------- | ---------------- | ----------------------------------------------------------------------------------- |
+| `LEMMY_UI_HOST` | `string` | `0.0.0.0:1234` | The IP / port that the lemmy-ui isomorphic node server is hosted at. |
+| `LEMMY_UI_LEMMY_INTERNAL_HOST` | `string` | `0.0.0.0:8536` | The internal IP / port that lemmy is hosted at. Often `lemmy:8536` if using docker. |
+| `LEMMY_UI_LEMMY_EXTERNAL_HOST` | `string` | `0.0.0.0:8536` | The external IP / port that lemmy is hosted at. Often `DOMAIN.TLD`. |
+| `LEMMY_UI_HTTPS` | `bool` | `false` | Whether to use https. |
+| `LEMMY_UI_EXTRA_THEMES_FOLDER` | `string` | `./extra_themes` | A location for additional lemmy css themes. |
+| `LEMMY_UI_DEBUG` | `bool` | `false` | Loads the [Eruda](https://github.com/liriliri/eruda) debugging utility. |
+| `LEMMY_UI_DISABLE_CSP` | `bool` | `false` | Disables CSP security headers |
+| `LEMMY_UI_CUSTOM_HTML_HEADER` | `string` | | Injects a custom script into ``. |
diff --git a/src/shared/components/comment/comment-form.tsx b/src/shared/components/comment/comment-form.tsx
index b76492a9..f2b5f931 100644
--- a/src/shared/components/comment/comment-form.tsx
+++ b/src/shared/components/comment/comment-form.tsx
@@ -14,6 +14,7 @@ interface CommentFormProps {
* Can either be the parent, or the editable comment. The right side is a postId.
*/
node: CommentNodeI | number;
+ finished?: boolean;
edit?: boolean;
disabled?: boolean;
focus?: boolean;
@@ -24,25 +25,11 @@ interface CommentFormProps {
onEditComment(form: EditComment): void;
}
-interface CommentFormState {
- buttonTitle: string;
-}
-
-export class CommentForm extends Component {
- state: CommentFormState = {
- buttonTitle:
- typeof this.props.node === "number"
- ? capitalizeFirstLetter(i18n.t("post"))
- : this.props.edit
- ? capitalizeFirstLetter(i18n.t("save"))
- : capitalizeFirstLetter(i18n.t("reply")),
- };
-
+export class CommentForm extends Component {
constructor(props: any, context: any) {
super(props, context);
this.handleCommentSubmit = this.handleCommentSubmit.bind(this);
- this.handleReplyCancel = this.handleReplyCancel.bind(this);
}
render() {
@@ -59,12 +46,13 @@ export class CommentForm extends Component {
{
);
}
+ get buttonTitle(): string {
+ return typeof this.props.node === "number"
+ ? capitalizeFirstLetter(i18n.t("post"))
+ : this.props.edit
+ ? capitalizeFirstLetter(i18n.t("save"))
+ : capitalizeFirstLetter(i18n.t("reply"));
+ }
+
handleCommentSubmit(content: string, form_id: string, language_id?: number) {
let node = this.props.node;
@@ -100,6 +96,7 @@ export class CommentForm extends Component {
if (this.props.edit) {
let comment_id = node.comment_view.comment.id;
this.props.onEditComment({
+ content,
comment_id,
form_id,
language_id,
@@ -119,8 +116,4 @@ export class CommentForm extends Component {
}
}
}
-
- handleReplyCancel() {
- this.props.onReplyCancel?.();
- }
}
diff --git a/src/shared/components/comment/comment-node.tsx b/src/shared/components/comment/comment-node.tsx
index 008cd537..1f2bf49e 100644
--- a/src/shared/components/comment/comment-node.tsx
+++ b/src/shared/components/comment/comment-node.tsx
@@ -121,6 +121,7 @@ interface CommentNodeProps {
allLanguages: Language[];
siteLanguages: number[];
hideImages?: boolean;
+ finished: Map;
onSaveComment(form: SaveComment): void;
onCommentReplyRead(form: MarkCommentReplyAsRead): void;
onPersonMentionRead(form: MarkPersonMentionAsRead): void;
@@ -197,6 +198,22 @@ export class CommentNode extends Component {
): void {
if (this.props != nextProps) {
this.setState({
+ showReply: false,
+ showEdit: false,
+ showRemoveDialog: false,
+ showBanDialog: false,
+ removeData: false,
+ banType: BanType.Community,
+ showPurgeDialog: false,
+ purgeType: PurgeType.Person,
+ collapsed: false,
+ viewSource: false,
+ showAdvanced: false,
+ showConfirmTransferSite: false,
+ showConfirmTransferCommunity: false,
+ showConfirmAppointAsMod: false,
+ showConfirmAppointAsAdmin: false,
+ showReportDialog: false,
createOrEditCommentLoading: false,
upvoteLoading: false,
downvoteLoading: false,
@@ -389,6 +406,9 @@ export class CommentNode extends Component {
edit
onReplyCancel={this.handleReplyCancel}
disabled={this.props.locked}
+ finished={this.props.finished.get(
+ this.props.node.comment_view.comment.id
+ )}
focus
allLanguages={this.props.allLanguages}
siteLanguages={this.props.siteLanguages}
@@ -1130,6 +1150,9 @@ export class CommentNode extends Component {
node={node}
onReplyCancel={this.handleReplyCancel}
disabled={this.props.locked}
+ finished={this.props.finished.get(
+ this.props.node.comment_view.comment.id
+ )}
focus
allLanguages={this.props.allLanguages}
siteLanguages={this.props.siteLanguages}
@@ -1148,6 +1171,7 @@ export class CommentNode extends Component {
allLanguages={this.props.allLanguages}
siteLanguages={this.props.siteLanguages}
hideImages={this.props.hideImages}
+ finished={this.props.finished}
onCommentReplyRead={this.props.onCommentReplyRead}
onPersonMentionRead={this.props.onPersonMentionRead}
onCreateComment={this.props.onCreateComment}
@@ -1457,7 +1481,7 @@ export class CommentNode extends Component {
read: !cv.person_mention.read,
auth: myAuthRequired(),
});
- } else if (this.isCommentReplyType(cv)) {
+ } else if (i.isCommentReplyType(cv)) {
i.props.onCommentReplyRead({
comment_reply_id: cv.comment_reply.id,
read: !cv.comment_reply.read,
diff --git a/src/shared/components/comment/comment-nodes.tsx b/src/shared/components/comment/comment-nodes.tsx
index aadd3815..c1ad3097 100644
--- a/src/shared/components/comment/comment-nodes.tsx
+++ b/src/shared/components/comment/comment-nodes.tsx
@@ -5,6 +5,7 @@ import {
BanFromCommunity,
BanPerson,
BlockPerson,
+ CommentId,
CommunityModeratorView,
CreateComment,
CreateCommentLike,
@@ -43,6 +44,7 @@ interface CommentNodesProps {
allLanguages: Language[];
siteLanguages: number[];
hideImages?: boolean;
+ finished: Map;
onSaveComment(form: SaveComment): void;
onCommentReplyRead(form: MarkCommentReplyAsRead): void;
onPersonMentionRead(form: MarkPersonMentionAsRead): void;
@@ -94,6 +96,7 @@ export class CommentNodes extends Component {
hideImages={this.props.hideImages}
onCommentReplyRead={this.props.onCommentReplyRead}
onPersonMentionRead={this.props.onPersonMentionRead}
+ finished={this.props.finished}
onCreateComment={this.props.onCreateComment}
onEditComment={this.props.onEditComment}
onCommentVote={this.props.onCommentVote}
diff --git a/src/shared/components/comment/comment-report.tsx b/src/shared/components/comment/comment-report.tsx
index d88659e7..f6343759 100644
--- a/src/shared/components/comment/comment-report.tsx
+++ b/src/shared/components/comment/comment-report.tsx
@@ -1,4 +1,4 @@
-import { Component, linkEvent } from "inferno";
+import { Component, InfernoNode, linkEvent } from "inferno";
import { T } from "inferno-i18next-dess";
import {
CommentReportView,
@@ -32,6 +32,14 @@ export class CommentReport extends Component<
super(props, context);
}
+ componentWillReceiveProps(
+ nextProps: Readonly<{ children?: InfernoNode } & CommentReportProps>
+ ): void {
+ if (this.props != nextProps) {
+ this.setState({ loading: false });
+ }
+ }
+
render() {
let r = this.props.report;
let comment = r.comment;
@@ -73,6 +81,7 @@ export class CommentReport extends Component<
siteLanguages={[]}
hideImages
// All of these are unused, since its viewonly
+ finished={new Map()}
onSaveComment={() => {}}
onBlockPerson={() => {}}
onDeleteComment={() => {}}
diff --git a/src/shared/components/common/markdown-textarea.tsx b/src/shared/components/common/markdown-textarea.tsx
index fb5148a2..32cf5deb 100644
--- a/src/shared/components/common/markdown-textarea.tsx
+++ b/src/shared/components/common/markdown-textarea.tsx
@@ -36,6 +36,7 @@ interface MarkdownTextAreaProps {
replyType?: boolean;
focus?: boolean;
disabled?: boolean;
+ finished?: boolean;
showLanguage?: boolean;
hideNavigationWarnings?: boolean;
onContentChange?(val: string): void;
@@ -113,12 +114,7 @@ export class MarkdownTextArea extends Component<
}
componentWillReceiveProps(nextProps: MarkdownTextAreaProps) {
- if (
- nextProps != this.props &&
- // Don't trigger this on an initial content change (IE the form field version)
- // This should only trigger in an
- this.props.initialContent == nextProps.initialContent
- ) {
+ if (nextProps.finished) {
this.setState({
previewMode: false,
imageUploadStatus: undefined,
diff --git a/src/shared/components/community/community.tsx b/src/shared/components/community/community.tsx
index e19a8c85..3b3ae864 100644
--- a/src/shared/components/community/community.tsx
+++ b/src/shared/components/community/community.tsx
@@ -10,6 +10,7 @@ import {
BanPersonResponse,
BlockCommunity,
BlockPerson,
+ CommentId,
CommentReplyResponse,
CommentResponse,
CommunityResponse,
@@ -73,6 +74,7 @@ import {
enableDownvotes,
enableNsfw,
fetchLimit,
+ getCommentParentId,
getDataTypeString,
getPageFromString,
getQueryParams,
@@ -108,6 +110,7 @@ interface State {
commentsRes: RequestState;
siteRes: GetSiteResponse;
showSidebarMobile: boolean;
+ finished: Map;
}
interface CommunityProps {
@@ -147,6 +150,7 @@ export class Community extends Component<
commentsRes: { state: "empty" },
siteRes: this.isoData.site_res,
showSidebarMobile: false,
+ finished: new Map(),
};
constructor(props: RouteComponentProps<{ name: string }>, context: any) {
@@ -445,6 +449,7 @@ export class Community extends Component<
{
- if (
- s.commentsRes.state == "success" &&
- createCommentRes.state == "success"
- ) {
- s.commentsRes.data.comments.unshift(createCommentRes.data.comment_view);
- }
- return s;
- });
+ this.createAndUpdateComments(createCommentRes);
}
async handleEditComment(form: EditComment) {
@@ -924,6 +920,22 @@ export class Community extends Component<
res.data.comment_view,
s.commentsRes.data.comments
);
+ s.finished.set(res.data.comment_view.comment.id, true);
+ }
+ return s;
+ });
+ }
+
+ createAndUpdateComments(res: RequestState) {
+ this.setState(s => {
+ if (s.commentsRes.state == "success" && res.state == "success") {
+ s.commentsRes.data.comments.unshift(res.data.comment_view);
+
+ // Set finished for the parent
+ s.finished.set(
+ getCommentParentId(res.data.comment_view.comment) ?? 0,
+ true
+ );
}
return s;
});
diff --git a/src/shared/components/home/home.tsx b/src/shared/components/home/home.tsx
index cea29c54..d658cf3e 100644
--- a/src/shared/components/home/home.tsx
+++ b/src/shared/components/home/home.tsx
@@ -10,6 +10,7 @@ import {
BanPerson,
BanPersonResponse,
BlockPerson,
+ CommentId,
CommentReplyResponse,
CommentResponse,
CreateComment,
@@ -67,6 +68,7 @@ import {
enableDownvotes,
enableNsfw,
fetchLimit,
+ getCommentParentId,
getDataTypeString,
getPageFromString,
getQueryParams,
@@ -108,6 +110,7 @@ interface HomeState {
subscribedCollapsed: boolean;
tagline?: string;
siteRes: GetSiteResponse;
+ finished: Map;
}
interface HomeProps {
@@ -186,6 +189,7 @@ export class Home extends Component {
showTrendingMobile: false,
showSidebarMobile: false,
subscribedCollapsed: false,
+ finished: new Map(),
};
constructor(props: any, context: any) {
@@ -646,6 +650,7 @@ export class Home extends Component {
{
HttpService.client.createComment(form)
);
- this.setState(s => {
- if (
- s.commentsRes.state == "success" &&
- createCommentRes.state == "success"
- ) {
- s.commentsRes.data.comments.unshift(createCommentRes.data.comment_view);
- }
- return s;
- });
+ this.createAndUpdateComments(createCommentRes);
}
async handleEditComment(form: EditComment) {
@@ -1057,6 +1054,22 @@ export class Home extends Component {
res.data.comment_view,
s.commentsRes.data.comments
);
+ s.finished.set(res.data.comment_view.comment.id, true);
+ }
+ return s;
+ });
+ }
+
+ createAndUpdateComments(res: RequestState) {
+ this.setState(s => {
+ if (s.commentsRes.state == "success" && res.state == "success") {
+ s.commentsRes.data.comments.unshift(res.data.comment_view);
+
+ // Set finished for the parent
+ s.finished.set(
+ getCommentParentId(res.data.comment_view.comment) ?? 0,
+ true
+ );
}
return s;
});
diff --git a/src/shared/components/person/inbox.tsx b/src/shared/components/person/inbox.tsx
index 7febf53a..f3fc2714 100644
--- a/src/shared/components/person/inbox.tsx
+++ b/src/shared/components/person/inbox.tsx
@@ -7,6 +7,7 @@ import {
BanPerson,
BanPersonResponse,
BlockPerson,
+ CommentId,
CommentReplyResponse,
CommentReplyView,
CommentReportResponse,
@@ -64,6 +65,7 @@ import {
editPrivateMessages,
enableDownvotes,
fetchLimit,
+ getCommentParentId,
isBrowser,
isInitialRoute,
myAuth,
@@ -114,6 +116,7 @@ interface InboxState {
sort: CommentSortType;
page: number;
siteRes: GetSiteResponse;
+ finished: Map;
}
export class Inbox extends Component {
@@ -128,6 +131,7 @@ export class Inbox extends Component {
mentionsRes: { state: "empty" },
messagesRes: { state: "empty" },
markAllAsReadRes: { state: "empty" },
+ finished: new Map(),
};
constructor(props: any, context: any) {
@@ -434,6 +438,7 @@ export class Inbox extends Component {
{ comment_view: i.view as CommentView, children: [], depth: 0 },
]}
viewType={CommentViewType.Flat}
+ finished={this.state.finished}
noIndent
markable
showCommunity
@@ -472,6 +477,7 @@ export class Inbox extends Component {
depth: 0,
},
]}
+ finished={this.state.finished}
viewType={CommentViewType.Flat}
noIndent
markable
@@ -529,7 +535,9 @@ export class Inbox extends Component {
);
} else {
- return {this.buildCombined().map(this.renderReplyType)}
;
+ return (
+ {this.buildCombined().map(r => this.renderReplyType(r))}
+ );
}
}
@@ -548,6 +556,7 @@ export class Inbox extends Component {
{
key={umv.person_mention.id}
nodes={[{ comment_view: umv, children: [], depth: 0 }]}
viewType={CommentViewType.Flat}
+ finished={this.state.finished}
noIndent
markable
showCommunity
@@ -683,7 +693,7 @@ export class Inbox extends Component {
if (auth) {
// It can be /u/me, or /username/1
let repliesForm: GetReplies = {
- sort: "New",
+ sort,
unread_only: true,
page: 1,
limit: fetchLimit,
@@ -772,7 +782,7 @@ export class Inbox extends Component {
),
});
- if (this.state.markAllAsReadRes.state == "success") {
+ if (i.state.markAllAsReadRes.state == "success") {
i.setState({
repliesRes: { state: "empty" },
mentionsRes: { state: "empty" },
@@ -819,7 +829,8 @@ export class Inbox extends Component {
const res = await apiWrapper(HttpService.client.createComment(form));
if (res.state == "success") {
- toast(i18n.t("created"));
+ toast(i18n.t("reply_sent"));
+ this.findAndUpdateComment(res);
}
}
@@ -828,6 +839,7 @@ export class Inbox extends Component {
if (res.state == "success") {
toast(i18n.t("edit"));
+ this.findAndUpdateComment(res);
}
}
@@ -835,6 +847,7 @@ export class Inbox extends Component {
const res = await apiWrapper(HttpService.client.deleteComment(form));
if (res.state == "success") {
toast(i18n.t("deleted"));
+ this.findAndUpdateComment(res);
}
}
@@ -842,6 +855,7 @@ export class Inbox extends Component {
const res = await apiWrapper(HttpService.client.removeComment(form));
if (res.state == "success") {
toast(i18n.t("remove_comment"));
+ this.findAndUpdateComment(res);
}
}
@@ -1026,6 +1040,11 @@ export class Inbox extends Component {
s.mentionsRes.data.mentions
);
}
+ // Set finished for the parent
+ s.finished.set(
+ getCommentParentId(res.data.comment_view.comment) ?? 0,
+ true
+ );
return s;
});
}
diff --git a/src/shared/components/person/person-details.tsx b/src/shared/components/person/person-details.tsx
index 9e990a61..4ff6fc5d 100644
--- a/src/shared/components/person/person-details.tsx
+++ b/src/shared/components/person/person-details.tsx
@@ -5,6 +5,7 @@ import {
BanFromCommunity,
BanPerson,
BlockPerson,
+ CommentId,
CommentView,
CreateComment,
CreateCommentLike,
@@ -42,6 +43,7 @@ import { PostListing } from "../post/post-listing";
interface PersonDetailsProps {
personRes: GetPersonDetailsResponse;
+ finished: Map;
admins: PersonView[];
allLanguages: Language[];
siteLanguages: number[];
@@ -147,6 +149,7 @@ export class PersonDetails extends Component {
key={i.id}
nodes={[{ comment_view: c, children: [], depth: 0 }]}
viewType={CommentViewType.Flat}
+ finished={this.props.finished}
admins={this.props.admins}
noBorder
noIndent
@@ -255,6 +258,7 @@ export class PersonDetails extends Component {
nodes={commentsToFlatNodes(this.props.personRes.comments)}
viewType={CommentViewType.Flat}
admins={this.props.admins}
+ finished={this.props.finished}
noIndent
showCommunity
showContext
diff --git a/src/shared/components/person/profile.tsx b/src/shared/components/person/profile.tsx
index 58e888e1..813d5227 100644
--- a/src/shared/components/person/profile.tsx
+++ b/src/shared/components/person/profile.tsx
@@ -11,6 +11,7 @@ import {
BanPerson,
BanPersonResponse,
BlockPerson,
+ CommentId,
CommentReplyResponse,
CommentResponse,
Community,
@@ -65,6 +66,7 @@ import {
enableNsfw,
fetchLimit,
futureDaysToUnixTime,
+ getCommentParentId,
getPageFromString,
getQueryParams,
getQueryString,
@@ -100,6 +102,7 @@ interface ProfileState {
showBanDialog: boolean;
removeData: boolean;
siteRes: GetSiteResponse;
+ finished: Map;
}
interface ProfileProps {
@@ -163,6 +166,7 @@ export class Profile extends Component<
siteRes: this.isoData.site_res,
showBanDialog: false,
removeData: false,
+ finished: new Map(),
};
constructor(props: RouteComponentProps<{ username: string }>, context: any) {
@@ -333,6 +337,7 @@ export class Profile extends Component<
sort={sort}
page={page}
limit={fetchLimit}
+ finished={this.state.finished}
enableDownvotes={enableDownvotes(siteRes)}
enableNsfw={enableNsfw(siteRes)}
view={view}
@@ -842,16 +847,7 @@ export class Profile extends Component<
const createCommentRes = await apiWrapper(
HttpService.client.createComment(form)
);
-
- this.setState(s => {
- if (
- s.personRes.state == "success" &&
- createCommentRes.state == "success"
- ) {
- s.personRes.data.comments.unshift(createCommentRes.data.comment_view);
- }
- return s;
- });
+ this.createAndUpdateComments(createCommentRes);
}
async handleEditComment(form: EditComment) {
@@ -1033,6 +1029,21 @@ export class Profile extends Component<
res.data.comment_view,
s.personRes.data.comments
);
+ s.finished.set(res.data.comment_view.comment.id, true);
+ }
+ return s;
+ });
+ }
+
+ createAndUpdateComments(res: RequestState) {
+ this.setState(s => {
+ if (s.personRes.state == "success" && res.state == "success") {
+ s.personRes.data.comments.unshift(res.data.comment_view);
+ // Set finished for the parent
+ s.finished.set(
+ getCommentParentId(res.data.comment_view.comment) ?? 0,
+ true
+ );
}
return s;
});
diff --git a/src/shared/components/person/reports.tsx b/src/shared/components/person/reports.tsx
index dc7dfe09..dad5704c 100644
--- a/src/shared/components/person/reports.tsx
+++ b/src/shared/components/person/reports.tsx
@@ -17,7 +17,6 @@ import {
ResolvePostReport,
ResolvePrivateMessageReport,
} from "lemmy-js-client";
-import { Subscription } from "rxjs";
import { i18n } from "../../i18next";
import { InitialFetchRequest } from "../../interfaces";
import { HttpService, UserService } from "../../services";
@@ -82,7 +81,6 @@ interface ReportsState {
export class Reports extends Component {
private isoData = setIsoData(this.context);
- private subscription?: Subscription;
state: ReportsState = {
commentReportsRes: { state: "empty" },
postReportsRes: { state: "empty" },
@@ -130,9 +128,9 @@ export class Reports extends Component {
}
}
- componentWillUnmount() {
- if (isBrowser()) {
- this.subscription?.unsubscribe();
+ async componentDidMount() {
+ if (!isInitialRoute(this.isoData, this.context)) {
+ await this.refetch();
}
}
@@ -469,14 +467,14 @@ export class Reports extends Component {
await this.refetch();
}
- handleUnreadOrAllChange(i: Reports, event: any) {
+ async handleUnreadOrAllChange(i: Reports, event: any) {
i.setState({ unreadOrAll: Number(event.target.value), page: 1 });
- i.refetch();
+ await i.refetch();
}
- handleMessageTypeChange(i: Reports, event: any) {
+ async handleMessageTypeChange(i: Reports, event: any) {
i.setState({ messageType: Number(event.target.value), page: 1 });
- i.refetch();
+ await i.refetch();
}
static fetchInitialData(req: InitialFetchRequest): Promise[] {
diff --git a/src/shared/components/post/post-report.tsx b/src/shared/components/post/post-report.tsx
index 30970462..22fb73e4 100644
--- a/src/shared/components/post/post-report.tsx
+++ b/src/shared/components/post/post-report.tsx
@@ -1,4 +1,4 @@
-import { Component, linkEvent } from "inferno";
+import { Component, InfernoNode, linkEvent } from "inferno";
import { T } from "inferno-i18next-dess";
import { PostReportView, PostView, ResolvePostReport } from "lemmy-js-client";
import { i18n } from "../../i18next";
@@ -25,6 +25,14 @@ export class PostReport extends Component {
super(props, context);
}
+ componentWillReceiveProps(
+ nextProps: Readonly<{ children?: InfernoNode } & PostReportProps>
+ ): void {
+ if (this.props != nextProps) {
+ this.setState({ loading: false });
+ }
+ }
+
render() {
let r = this.props.report;
let resolver = r.resolver;
diff --git a/src/shared/components/post/post.tsx b/src/shared/components/post/post.tsx
index 229b55ff..8c43534b 100644
--- a/src/shared/components/post/post.tsx
+++ b/src/shared/components/post/post.tsx
@@ -10,6 +10,7 @@ import {
BanPersonResponse,
BlockCommunity,
BlockPerson,
+ CommentId,
CommentReplyResponse,
CommentResponse,
CommentSortType,
@@ -108,6 +109,7 @@ interface PostState {
commentSectionRef?: RefObject;
showSidebarMobile: boolean;
maxCommentsShown: number;
+ finished: Map;
}
export class Post extends Component {
@@ -124,6 +126,7 @@ export class Post extends Component {
siteRes: this.isoData.site_res,
showSidebarMobile: false,
maxCommentsShown: commentsShownInterval,
+ finished: new Map(),
};
constructor(props: any, context: any) {
@@ -382,6 +385,7 @@ export class Post extends Component {
siteLanguages={this.state.siteRes.discussion_languages}
onCreateComment={this.handleCreateComment}
onEditComment={this.handleEditComment}
+ finished={this.state.finished.get(0)}
/>
{
admins={this.state.siteRes.admins}
enableDownvotes={enableDownvotes(this.state.siteRes)}
showContext
+ finished={this.state.finished}
allLanguages={this.state.siteRes.all_languages}
siteLanguages={this.state.siteRes.discussion_languages}
onSaveComment={this.handleSaveComment}
@@ -600,6 +605,7 @@ export class Post extends Component {
moderators={res.data.moderators}
admins={this.state.siteRes.admins}
enableDownvotes={enableDownvotes(this.state.siteRes)}
+ finished={this.state.finished}
allLanguages={this.state.siteRes.all_languages}
siteLanguages={this.state.siteRes.discussion_languages}
onSaveComment={this.handleSaveComment}
@@ -782,16 +788,7 @@ export class Post extends Component {
const createCommentRes = await apiWrapper(
HttpService.client.createComment(form)
);
-
- this.setState(s => {
- if (
- s.commentsRes.state == "success" &&
- createCommentRes.state == "success"
- ) {
- s.commentsRes.data.comments.unshift(createCommentRes.data.comment_view);
- }
- return s;
- });
+ this.createAndUpdateComments(createCommentRes);
}
async handleEditComment(form: EditComment) {
@@ -1021,6 +1018,21 @@ export class Post extends Component {
}
}
+ createAndUpdateComments(res: RequestState) {
+ this.setState(s => {
+ if (s.commentsRes.state == "success" && res.state == "success") {
+ s.commentsRes.data.comments.unshift(res.data.comment_view);
+
+ // Set finished for the parent
+ s.finished.set(
+ getCommentParentId(res.data.comment_view.comment) ?? 0,
+ true
+ );
+ }
+ return s;
+ });
+ }
+
findAndUpdateComment(res: RequestState) {
this.setState(s => {
if (s.commentsRes.state == "success" && res.state == "success") {
@@ -1028,6 +1040,7 @@ export class Post extends Component {
res.data.comment_view,
s.commentsRes.data.comments
);
+ s.finished.set(res.data.comment_view.comment.id, true);
}
return s;
});
diff --git a/src/shared/components/private_message/create-private-message.tsx b/src/shared/components/private_message/create-private-message.tsx
index 32ce9e19..5036b3f7 100644
--- a/src/shared/components/private_message/create-private-message.tsx
+++ b/src/shared/components/private_message/create-private-message.tsx
@@ -1,5 +1,6 @@
import { Component } from "inferno";
import {
+ CreatePrivateMessage as CreatePrivateMessageI,
GetPersonDetails,
GetPersonDetailsResponse,
GetSiteResponse,
@@ -151,10 +152,14 @@ export class CreatePrivateMessage extends Component<
);
}
- handlePrivateMessageCreate() {
- toast(i18n.t("message_sent"));
+ async handlePrivateMessageCreate(form: CreatePrivateMessageI) {
+ const res = await apiWrapper(HttpService.client.createPrivateMessage(form));
- // Navigate to the front
- this.context.router.history.push("/");
+ if (res.state == "success") {
+ toast(i18n.t("message_sent"));
+
+ // Navigate to the front
+ this.context.router.history.push("/");
+ }
}
}
diff --git a/src/shared/components/private_message/private-message-form.tsx b/src/shared/components/private_message/private-message-form.tsx
index 36ec84fa..321eadeb 100644
--- a/src/shared/components/private_message/private-message-form.tsx
+++ b/src/shared/components/private_message/private-message-form.tsx
@@ -1,4 +1,4 @@
-import { Component, linkEvent } from "inferno";
+import { Component, InfernoNode, linkEvent } from "inferno";
import { T } from "inferno-i18next-dess";
import { Prompt } from "inferno-router";
import {
@@ -56,12 +56,11 @@ export class PrivateMessageForm extends Component<
setupTippy();
}
- // TODO what is this
- componentDidUpdate() {
- if (!this.state.loading && this.state.content) {
- window.onbeforeunload = () => true;
- } else {
- window.onbeforeunload = null;
+ componentWillReceiveProps(
+ nextProps: Readonly<{ children?: InfernoNode } & PrivateMessageFormProps>
+ ): void {
+ if (this.props != nextProps) {
+ this.setState({ loading: false, content: undefined, previewMode: false });
}
}
diff --git a/src/shared/components/private_message/private-message-report.tsx b/src/shared/components/private_message/private-message-report.tsx
index 51796806..f715d8ec 100644
--- a/src/shared/components/private_message/private-message-report.tsx
+++ b/src/shared/components/private_message/private-message-report.tsx
@@ -1,4 +1,4 @@
-import { Component, linkEvent } from "inferno";
+import { Component, InfernoNode, linkEvent } from "inferno";
import { T } from "inferno-i18next-dess";
import {
PrivateMessageReportView,
@@ -27,6 +27,14 @@ export class PrivateMessageReport extends Component {
super(props, context);
}
+ componentWillReceiveProps(
+ nextProps: Readonly<{ children?: InfernoNode } & Props>
+ ): void {
+ if (this.props != nextProps) {
+ this.setState({ loading: false });
+ }
+ }
+
render() {
let r = this.props.report;
let pmr = r.private_message_report;
diff --git a/src/shared/components/private_message/private-message.tsx b/src/shared/components/private_message/private-message.tsx
index b06f55dd..8fe6c896 100644
--- a/src/shared/components/private_message/private-message.tsx
+++ b/src/shared/components/private_message/private-message.tsx
@@ -1,4 +1,4 @@
-import { Component, linkEvent } from "inferno";
+import { Component, InfernoNode, linkEvent } from "inferno";
import {
CreatePrivateMessage,
CreatePrivateMessageReport,
@@ -64,6 +64,23 @@ export class PrivateMessage extends Component<
);
}
+ componentWillReceiveProps(
+ nextProps: Readonly<{ children?: InfernoNode } & PrivateMessageProps>
+ ): void {
+ if (this.props != nextProps) {
+ this.setState({
+ showReply: false,
+ showEdit: false,
+ collapsed: false,
+ viewSource: false,
+ showReportDialog: false,
+ deleteLoading: false,
+ readLoading: false,
+ reportLoading: false,
+ });
+ }
+ }
+
render() {
let message_view = this.props.private_message_view;
let otherPerson: Person = this.mine
diff --git a/src/shared/components/search.tsx b/src/shared/components/search.tsx
index b5572c3a..2452e7b8 100644
--- a/src/shared/components/search.tsx
+++ b/src/shared/components/search.tsx
@@ -657,6 +657,7 @@ export class Search extends Component {
allLanguages={this.state.siteRes.all_languages}
siteLanguages={this.state.siteRes.discussion_languages}
// All of these are unused, since its viewonly
+ finished={new Map()}
onSaveComment={() => {}}
onBlockPerson={() => {}}
onDeleteComment={() => {}}
@@ -717,6 +718,7 @@ export class Search extends Component {
allLanguages={siteRes.all_languages}
siteLanguages={siteRes.discussion_languages}
// All of these are unused, since its viewonly
+ finished={new Map()}
onSaveComment={() => {}}
onBlockPerson={() => {}}
onDeleteComment={() => {}}