A few more fixes.
This commit is contained in:
parent
e64b71339d
commit
f981f103ef
19 changed files with 249 additions and 116 deletions
41
README.md
41
README.md
|
@ -1,21 +1,20 @@
|
||||||
# lemmy-ui
|
# Lemmy-UI
|
||||||
|
|
||||||
The official web app for [Lemmy](https://github.com/LemmyNet/lemmy), written in inferno.
|
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).
|
Based off of MrFoxPro's [inferno-isomorphic-template](https://github.com/MrFoxPro/inferno-isomorphic-template).
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The following environment variables can be used to configure lemmy-ui:
|
The following environment variables can be used to configure lemmy-ui:
|
||||||
|
|
||||||
`ENV_VAR` | type | default | description
|
| `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_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_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_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_HTTPS` | `bool` | `false` | Whether to use https.
|
| `LEMMY_UI_EXTRA_THEMES_FOLDER` | `string` | `./extra_themes` | A location for additional lemmy css themes. |
|
||||||
`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_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_DISABLE_CSP` | `bool` | `false` | Disables CSP security headers
|
| `LEMMY_UI_CUSTOM_HTML_HEADER` | `string` | | Injects a custom script into `<head>`. |
|
||||||
`LEMMY_UI_CUSTOM_HTML_HEADER` | `string` | | Injects a custom script into `<head>`.
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ interface CommentFormProps {
|
||||||
* Can either be the parent, or the editable comment. The right side is a postId.
|
* Can either be the parent, or the editable comment. The right side is a postId.
|
||||||
*/
|
*/
|
||||||
node: CommentNodeI | number;
|
node: CommentNodeI | number;
|
||||||
|
finished?: boolean;
|
||||||
edit?: boolean;
|
edit?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
focus?: boolean;
|
focus?: boolean;
|
||||||
|
@ -24,25 +25,11 @@ interface CommentFormProps {
|
||||||
onEditComment(form: EditComment): void;
|
onEditComment(form: EditComment): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CommentFormState {
|
export class CommentForm extends Component<CommentFormProps, any> {
|
||||||
buttonTitle: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CommentForm extends Component<CommentFormProps, CommentFormState> {
|
|
||||||
state: CommentFormState = {
|
|
||||||
buttonTitle:
|
|
||||||
typeof this.props.node === "number"
|
|
||||||
? capitalizeFirstLetter(i18n.t("post"))
|
|
||||||
: this.props.edit
|
|
||||||
? capitalizeFirstLetter(i18n.t("save"))
|
|
||||||
: capitalizeFirstLetter(i18n.t("reply")),
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
|
|
||||||
this.handleCommentSubmit = this.handleCommentSubmit.bind(this);
|
this.handleCommentSubmit = this.handleCommentSubmit.bind(this);
|
||||||
this.handleReplyCancel = this.handleReplyCancel.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -59,12 +46,13 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
|
||||||
<MarkdownTextArea
|
<MarkdownTextArea
|
||||||
initialContent={initialContent}
|
initialContent={initialContent}
|
||||||
showLanguage
|
showLanguage
|
||||||
buttonTitle={this.state.buttonTitle}
|
buttonTitle={this.buttonTitle}
|
||||||
|
finished={this.props.finished}
|
||||||
replyType={typeof this.props.node !== "number"}
|
replyType={typeof this.props.node !== "number"}
|
||||||
focus={this.props.focus}
|
focus={this.props.focus}
|
||||||
disabled={this.props.disabled}
|
disabled={this.props.disabled}
|
||||||
onSubmit={this.handleCommentSubmit}
|
onSubmit={this.handleCommentSubmit}
|
||||||
onReplyCancel={this.handleReplyCancel}
|
onReplyCancel={this.props.onReplyCancel}
|
||||||
placeholder={i18n.t("comment_here")}
|
placeholder={i18n.t("comment_here")}
|
||||||
allLanguages={this.props.allLanguages}
|
allLanguages={this.props.allLanguages}
|
||||||
siteLanguages={this.props.siteLanguages}
|
siteLanguages={this.props.siteLanguages}
|
||||||
|
@ -84,6 +72,14 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
handleCommentSubmit(content: string, form_id: string, language_id?: number) {
|
||||||
let node = this.props.node;
|
let node = this.props.node;
|
||||||
|
|
||||||
|
@ -100,6 +96,7 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
|
||||||
if (this.props.edit) {
|
if (this.props.edit) {
|
||||||
let comment_id = node.comment_view.comment.id;
|
let comment_id = node.comment_view.comment.id;
|
||||||
this.props.onEditComment({
|
this.props.onEditComment({
|
||||||
|
content,
|
||||||
comment_id,
|
comment_id,
|
||||||
form_id,
|
form_id,
|
||||||
language_id,
|
language_id,
|
||||||
|
@ -119,8 +116,4 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleReplyCancel() {
|
|
||||||
this.props.onReplyCancel?.();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,6 +121,7 @@ interface CommentNodeProps {
|
||||||
allLanguages: Language[];
|
allLanguages: Language[];
|
||||||
siteLanguages: number[];
|
siteLanguages: number[];
|
||||||
hideImages?: boolean;
|
hideImages?: boolean;
|
||||||
|
finished: Map<CommentId, boolean | undefined>;
|
||||||
onSaveComment(form: SaveComment): void;
|
onSaveComment(form: SaveComment): void;
|
||||||
onCommentReplyRead(form: MarkCommentReplyAsRead): void;
|
onCommentReplyRead(form: MarkCommentReplyAsRead): void;
|
||||||
onPersonMentionRead(form: MarkPersonMentionAsRead): void;
|
onPersonMentionRead(form: MarkPersonMentionAsRead): void;
|
||||||
|
@ -197,6 +198,22 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
): void {
|
): void {
|
||||||
if (this.props != nextProps) {
|
if (this.props != nextProps) {
|
||||||
this.setState({
|
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,
|
createOrEditCommentLoading: false,
|
||||||
upvoteLoading: false,
|
upvoteLoading: false,
|
||||||
downvoteLoading: false,
|
downvoteLoading: false,
|
||||||
|
@ -389,6 +406,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
edit
|
edit
|
||||||
onReplyCancel={this.handleReplyCancel}
|
onReplyCancel={this.handleReplyCancel}
|
||||||
disabled={this.props.locked}
|
disabled={this.props.locked}
|
||||||
|
finished={this.props.finished.get(
|
||||||
|
this.props.node.comment_view.comment.id
|
||||||
|
)}
|
||||||
focus
|
focus
|
||||||
allLanguages={this.props.allLanguages}
|
allLanguages={this.props.allLanguages}
|
||||||
siteLanguages={this.props.siteLanguages}
|
siteLanguages={this.props.siteLanguages}
|
||||||
|
@ -1130,6 +1150,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
node={node}
|
node={node}
|
||||||
onReplyCancel={this.handleReplyCancel}
|
onReplyCancel={this.handleReplyCancel}
|
||||||
disabled={this.props.locked}
|
disabled={this.props.locked}
|
||||||
|
finished={this.props.finished.get(
|
||||||
|
this.props.node.comment_view.comment.id
|
||||||
|
)}
|
||||||
focus
|
focus
|
||||||
allLanguages={this.props.allLanguages}
|
allLanguages={this.props.allLanguages}
|
||||||
siteLanguages={this.props.siteLanguages}
|
siteLanguages={this.props.siteLanguages}
|
||||||
|
@ -1148,6 +1171,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
allLanguages={this.props.allLanguages}
|
allLanguages={this.props.allLanguages}
|
||||||
siteLanguages={this.props.siteLanguages}
|
siteLanguages={this.props.siteLanguages}
|
||||||
hideImages={this.props.hideImages}
|
hideImages={this.props.hideImages}
|
||||||
|
finished={this.props.finished}
|
||||||
onCommentReplyRead={this.props.onCommentReplyRead}
|
onCommentReplyRead={this.props.onCommentReplyRead}
|
||||||
onPersonMentionRead={this.props.onPersonMentionRead}
|
onPersonMentionRead={this.props.onPersonMentionRead}
|
||||||
onCreateComment={this.props.onCreateComment}
|
onCreateComment={this.props.onCreateComment}
|
||||||
|
@ -1457,7 +1481,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
read: !cv.person_mention.read,
|
read: !cv.person_mention.read,
|
||||||
auth: myAuthRequired(),
|
auth: myAuthRequired(),
|
||||||
});
|
});
|
||||||
} else if (this.isCommentReplyType(cv)) {
|
} else if (i.isCommentReplyType(cv)) {
|
||||||
i.props.onCommentReplyRead({
|
i.props.onCommentReplyRead({
|
||||||
comment_reply_id: cv.comment_reply.id,
|
comment_reply_id: cv.comment_reply.id,
|
||||||
read: !cv.comment_reply.read,
|
read: !cv.comment_reply.read,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
BanFromCommunity,
|
BanFromCommunity,
|
||||||
BanPerson,
|
BanPerson,
|
||||||
BlockPerson,
|
BlockPerson,
|
||||||
|
CommentId,
|
||||||
CommunityModeratorView,
|
CommunityModeratorView,
|
||||||
CreateComment,
|
CreateComment,
|
||||||
CreateCommentLike,
|
CreateCommentLike,
|
||||||
|
@ -43,6 +44,7 @@ interface CommentNodesProps {
|
||||||
allLanguages: Language[];
|
allLanguages: Language[];
|
||||||
siteLanguages: number[];
|
siteLanguages: number[];
|
||||||
hideImages?: boolean;
|
hideImages?: boolean;
|
||||||
|
finished: Map<CommentId, boolean | undefined>;
|
||||||
onSaveComment(form: SaveComment): void;
|
onSaveComment(form: SaveComment): void;
|
||||||
onCommentReplyRead(form: MarkCommentReplyAsRead): void;
|
onCommentReplyRead(form: MarkCommentReplyAsRead): void;
|
||||||
onPersonMentionRead(form: MarkPersonMentionAsRead): void;
|
onPersonMentionRead(form: MarkPersonMentionAsRead): void;
|
||||||
|
@ -94,6 +96,7 @@ export class CommentNodes extends Component<CommentNodesProps, any> {
|
||||||
hideImages={this.props.hideImages}
|
hideImages={this.props.hideImages}
|
||||||
onCommentReplyRead={this.props.onCommentReplyRead}
|
onCommentReplyRead={this.props.onCommentReplyRead}
|
||||||
onPersonMentionRead={this.props.onPersonMentionRead}
|
onPersonMentionRead={this.props.onPersonMentionRead}
|
||||||
|
finished={this.props.finished}
|
||||||
onCreateComment={this.props.onCreateComment}
|
onCreateComment={this.props.onCreateComment}
|
||||||
onEditComment={this.props.onEditComment}
|
onEditComment={this.props.onEditComment}
|
||||||
onCommentVote={this.props.onCommentVote}
|
onCommentVote={this.props.onCommentVote}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, InfernoNode, linkEvent } from "inferno";
|
||||||
import { T } from "inferno-i18next-dess";
|
import { T } from "inferno-i18next-dess";
|
||||||
import {
|
import {
|
||||||
CommentReportView,
|
CommentReportView,
|
||||||
|
@ -32,6 +32,14 @@ export class CommentReport extends Component<
|
||||||
super(props, context);
|
super(props, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(
|
||||||
|
nextProps: Readonly<{ children?: InfernoNode } & CommentReportProps>
|
||||||
|
): void {
|
||||||
|
if (this.props != nextProps) {
|
||||||
|
this.setState({ loading: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let r = this.props.report;
|
let r = this.props.report;
|
||||||
let comment = r.comment;
|
let comment = r.comment;
|
||||||
|
@ -73,6 +81,7 @@ export class CommentReport extends Component<
|
||||||
siteLanguages={[]}
|
siteLanguages={[]}
|
||||||
hideImages
|
hideImages
|
||||||
// All of these are unused, since its viewonly
|
// All of these are unused, since its viewonly
|
||||||
|
finished={new Map()}
|
||||||
onSaveComment={() => {}}
|
onSaveComment={() => {}}
|
||||||
onBlockPerson={() => {}}
|
onBlockPerson={() => {}}
|
||||||
onDeleteComment={() => {}}
|
onDeleteComment={() => {}}
|
||||||
|
|
|
@ -36,6 +36,7 @@ interface MarkdownTextAreaProps {
|
||||||
replyType?: boolean;
|
replyType?: boolean;
|
||||||
focus?: boolean;
|
focus?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
finished?: boolean;
|
||||||
showLanguage?: boolean;
|
showLanguage?: boolean;
|
||||||
hideNavigationWarnings?: boolean;
|
hideNavigationWarnings?: boolean;
|
||||||
onContentChange?(val: string): void;
|
onContentChange?(val: string): void;
|
||||||
|
@ -113,12 +114,7 @@ export class MarkdownTextArea extends Component<
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps: MarkdownTextAreaProps) {
|
componentWillReceiveProps(nextProps: MarkdownTextAreaProps) {
|
||||||
if (
|
if (nextProps.finished) {
|
||||||
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
|
|
||||||
) {
|
|
||||||
this.setState({
|
this.setState({
|
||||||
previewMode: false,
|
previewMode: false,
|
||||||
imageUploadStatus: undefined,
|
imageUploadStatus: undefined,
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
BanPersonResponse,
|
BanPersonResponse,
|
||||||
BlockCommunity,
|
BlockCommunity,
|
||||||
BlockPerson,
|
BlockPerson,
|
||||||
|
CommentId,
|
||||||
CommentReplyResponse,
|
CommentReplyResponse,
|
||||||
CommentResponse,
|
CommentResponse,
|
||||||
CommunityResponse,
|
CommunityResponse,
|
||||||
|
@ -73,6 +74,7 @@ import {
|
||||||
enableDownvotes,
|
enableDownvotes,
|
||||||
enableNsfw,
|
enableNsfw,
|
||||||
fetchLimit,
|
fetchLimit,
|
||||||
|
getCommentParentId,
|
||||||
getDataTypeString,
|
getDataTypeString,
|
||||||
getPageFromString,
|
getPageFromString,
|
||||||
getQueryParams,
|
getQueryParams,
|
||||||
|
@ -108,6 +110,7 @@ interface State {
|
||||||
commentsRes: RequestState<GetCommentsResponse>;
|
commentsRes: RequestState<GetCommentsResponse>;
|
||||||
siteRes: GetSiteResponse;
|
siteRes: GetSiteResponse;
|
||||||
showSidebarMobile: boolean;
|
showSidebarMobile: boolean;
|
||||||
|
finished: Map<CommentId, boolean | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CommunityProps {
|
interface CommunityProps {
|
||||||
|
@ -147,6 +150,7 @@ export class Community extends Component<
|
||||||
commentsRes: { state: "empty" },
|
commentsRes: { state: "empty" },
|
||||||
siteRes: this.isoData.site_res,
|
siteRes: this.isoData.site_res,
|
||||||
showSidebarMobile: false,
|
showSidebarMobile: false,
|
||||||
|
finished: new Map(),
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props: RouteComponentProps<{ name: string }>, context: any) {
|
constructor(props: RouteComponentProps<{ name: string }>, context: any) {
|
||||||
|
@ -445,6 +449,7 @@ export class Community extends Component<
|
||||||
<CommentNodes
|
<CommentNodes
|
||||||
nodes={commentsToFlatNodes(this.state.commentsRes.data.comments)}
|
nodes={commentsToFlatNodes(this.state.commentsRes.data.comments)}
|
||||||
viewType={CommentViewType.Flat}
|
viewType={CommentViewType.Flat}
|
||||||
|
finished={this.state.finished}
|
||||||
noIndent
|
noIndent
|
||||||
showContext
|
showContext
|
||||||
enableDownvotes={enableDownvotes(site_res)}
|
enableDownvotes={enableDownvotes(site_res)}
|
||||||
|
@ -706,16 +711,7 @@ export class Community extends Component<
|
||||||
const createCommentRes = await apiWrapper(
|
const createCommentRes = await apiWrapper(
|
||||||
HttpService.client.createComment(form)
|
HttpService.client.createComment(form)
|
||||||
);
|
);
|
||||||
|
this.createAndUpdateComments(createCommentRes);
|
||||||
this.setState(s => {
|
|
||||||
if (
|
|
||||||
s.commentsRes.state == "success" &&
|
|
||||||
createCommentRes.state == "success"
|
|
||||||
) {
|
|
||||||
s.commentsRes.data.comments.unshift(createCommentRes.data.comment_view);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleEditComment(form: EditComment) {
|
async handleEditComment(form: EditComment) {
|
||||||
|
@ -924,6 +920,22 @@ export class Community extends Component<
|
||||||
res.data.comment_view,
|
res.data.comment_view,
|
||||||
s.commentsRes.data.comments
|
s.commentsRes.data.comments
|
||||||
);
|
);
|
||||||
|
s.finished.set(res.data.comment_view.comment.id, true);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
createAndUpdateComments(res: RequestState<CommentResponse>) {
|
||||||
|
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;
|
return s;
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
BanPerson,
|
BanPerson,
|
||||||
BanPersonResponse,
|
BanPersonResponse,
|
||||||
BlockPerson,
|
BlockPerson,
|
||||||
|
CommentId,
|
||||||
CommentReplyResponse,
|
CommentReplyResponse,
|
||||||
CommentResponse,
|
CommentResponse,
|
||||||
CreateComment,
|
CreateComment,
|
||||||
|
@ -67,6 +68,7 @@ import {
|
||||||
enableDownvotes,
|
enableDownvotes,
|
||||||
enableNsfw,
|
enableNsfw,
|
||||||
fetchLimit,
|
fetchLimit,
|
||||||
|
getCommentParentId,
|
||||||
getDataTypeString,
|
getDataTypeString,
|
||||||
getPageFromString,
|
getPageFromString,
|
||||||
getQueryParams,
|
getQueryParams,
|
||||||
|
@ -108,6 +110,7 @@ interface HomeState {
|
||||||
subscribedCollapsed: boolean;
|
subscribedCollapsed: boolean;
|
||||||
tagline?: string;
|
tagline?: string;
|
||||||
siteRes: GetSiteResponse;
|
siteRes: GetSiteResponse;
|
||||||
|
finished: Map<CommentId, boolean | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HomeProps {
|
interface HomeProps {
|
||||||
|
@ -186,6 +189,7 @@ export class Home extends Component<any, HomeState> {
|
||||||
showTrendingMobile: false,
|
showTrendingMobile: false,
|
||||||
showSidebarMobile: false,
|
showSidebarMobile: false,
|
||||||
subscribedCollapsed: false,
|
subscribedCollapsed: false,
|
||||||
|
finished: new Map(),
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
|
@ -646,6 +650,7 @@ export class Home extends Component<any, HomeState> {
|
||||||
<CommentNodes
|
<CommentNodes
|
||||||
nodes={commentsToFlatNodes(comments)}
|
nodes={commentsToFlatNodes(comments)}
|
||||||
viewType={CommentViewType.Flat}
|
viewType={CommentViewType.Flat}
|
||||||
|
finished={this.state.finished}
|
||||||
noIndent
|
noIndent
|
||||||
showCommunity
|
showCommunity
|
||||||
showContext
|
showContext
|
||||||
|
@ -864,15 +869,7 @@ export class Home extends Component<any, HomeState> {
|
||||||
HttpService.client.createComment(form)
|
HttpService.client.createComment(form)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.setState(s => {
|
this.createAndUpdateComments(createCommentRes);
|
||||||
if (
|
|
||||||
s.commentsRes.state == "success" &&
|
|
||||||
createCommentRes.state == "success"
|
|
||||||
) {
|
|
||||||
s.commentsRes.data.comments.unshift(createCommentRes.data.comment_view);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleEditComment(form: EditComment) {
|
async handleEditComment(form: EditComment) {
|
||||||
|
@ -1057,6 +1054,22 @@ export class Home extends Component<any, HomeState> {
|
||||||
res.data.comment_view,
|
res.data.comment_view,
|
||||||
s.commentsRes.data.comments
|
s.commentsRes.data.comments
|
||||||
);
|
);
|
||||||
|
s.finished.set(res.data.comment_view.comment.id, true);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
createAndUpdateComments(res: RequestState<CommentResponse>) {
|
||||||
|
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;
|
return s;
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
BanPerson,
|
BanPerson,
|
||||||
BanPersonResponse,
|
BanPersonResponse,
|
||||||
BlockPerson,
|
BlockPerson,
|
||||||
|
CommentId,
|
||||||
CommentReplyResponse,
|
CommentReplyResponse,
|
||||||
CommentReplyView,
|
CommentReplyView,
|
||||||
CommentReportResponse,
|
CommentReportResponse,
|
||||||
|
@ -64,6 +65,7 @@ import {
|
||||||
editPrivateMessages,
|
editPrivateMessages,
|
||||||
enableDownvotes,
|
enableDownvotes,
|
||||||
fetchLimit,
|
fetchLimit,
|
||||||
|
getCommentParentId,
|
||||||
isBrowser,
|
isBrowser,
|
||||||
isInitialRoute,
|
isInitialRoute,
|
||||||
myAuth,
|
myAuth,
|
||||||
|
@ -114,6 +116,7 @@ interface InboxState {
|
||||||
sort: CommentSortType;
|
sort: CommentSortType;
|
||||||
page: number;
|
page: number;
|
||||||
siteRes: GetSiteResponse;
|
siteRes: GetSiteResponse;
|
||||||
|
finished: Map<CommentId, boolean | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Inbox extends Component<any, InboxState> {
|
export class Inbox extends Component<any, InboxState> {
|
||||||
|
@ -128,6 +131,7 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
mentionsRes: { state: "empty" },
|
mentionsRes: { state: "empty" },
|
||||||
messagesRes: { state: "empty" },
|
messagesRes: { state: "empty" },
|
||||||
markAllAsReadRes: { state: "empty" },
|
markAllAsReadRes: { state: "empty" },
|
||||||
|
finished: new Map(),
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
|
@ -434,6 +438,7 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
{ comment_view: i.view as CommentView, children: [], depth: 0 },
|
{ comment_view: i.view as CommentView, children: [], depth: 0 },
|
||||||
]}
|
]}
|
||||||
viewType={CommentViewType.Flat}
|
viewType={CommentViewType.Flat}
|
||||||
|
finished={this.state.finished}
|
||||||
noIndent
|
noIndent
|
||||||
markable
|
markable
|
||||||
showCommunity
|
showCommunity
|
||||||
|
@ -472,6 +477,7 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
depth: 0,
|
depth: 0,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
finished={this.state.finished}
|
||||||
viewType={CommentViewType.Flat}
|
viewType={CommentViewType.Flat}
|
||||||
noIndent
|
noIndent
|
||||||
markable
|
markable
|
||||||
|
@ -529,7 +535,9 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
</h5>
|
</h5>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return <div>{this.buildCombined().map(this.renderReplyType)}</div>;
|
return (
|
||||||
|
<div>{this.buildCombined().map(r => this.renderReplyType(r))}</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,6 +556,7 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
<CommentNodes
|
<CommentNodes
|
||||||
nodes={commentsToFlatNodes(replies)}
|
nodes={commentsToFlatNodes(replies)}
|
||||||
viewType={CommentViewType.Flat}
|
viewType={CommentViewType.Flat}
|
||||||
|
finished={this.state.finished}
|
||||||
noIndent
|
noIndent
|
||||||
markable
|
markable
|
||||||
showCommunity
|
showCommunity
|
||||||
|
@ -597,6 +606,7 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
key={umv.person_mention.id}
|
key={umv.person_mention.id}
|
||||||
nodes={[{ comment_view: umv, children: [], depth: 0 }]}
|
nodes={[{ comment_view: umv, children: [], depth: 0 }]}
|
||||||
viewType={CommentViewType.Flat}
|
viewType={CommentViewType.Flat}
|
||||||
|
finished={this.state.finished}
|
||||||
noIndent
|
noIndent
|
||||||
markable
|
markable
|
||||||
showCommunity
|
showCommunity
|
||||||
|
@ -683,7 +693,7 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
if (auth) {
|
if (auth) {
|
||||||
// It can be /u/me, or /username/1
|
// It can be /u/me, or /username/1
|
||||||
let repliesForm: GetReplies = {
|
let repliesForm: GetReplies = {
|
||||||
sort: "New",
|
sort,
|
||||||
unread_only: true,
|
unread_only: true,
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: fetchLimit,
|
limit: fetchLimit,
|
||||||
|
@ -772,7 +782,7 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.state.markAllAsReadRes.state == "success") {
|
if (i.state.markAllAsReadRes.state == "success") {
|
||||||
i.setState({
|
i.setState({
|
||||||
repliesRes: { state: "empty" },
|
repliesRes: { state: "empty" },
|
||||||
mentionsRes: { state: "empty" },
|
mentionsRes: { state: "empty" },
|
||||||
|
@ -819,7 +829,8 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
const res = await apiWrapper(HttpService.client.createComment(form));
|
const res = await apiWrapper(HttpService.client.createComment(form));
|
||||||
|
|
||||||
if (res.state == "success") {
|
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<any, InboxState> {
|
||||||
|
|
||||||
if (res.state == "success") {
|
if (res.state == "success") {
|
||||||
toast(i18n.t("edit"));
|
toast(i18n.t("edit"));
|
||||||
|
this.findAndUpdateComment(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,6 +847,7 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
const res = await apiWrapper(HttpService.client.deleteComment(form));
|
const res = await apiWrapper(HttpService.client.deleteComment(form));
|
||||||
if (res.state == "success") {
|
if (res.state == "success") {
|
||||||
toast(i18n.t("deleted"));
|
toast(i18n.t("deleted"));
|
||||||
|
this.findAndUpdateComment(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,6 +855,7 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
const res = await apiWrapper(HttpService.client.removeComment(form));
|
const res = await apiWrapper(HttpService.client.removeComment(form));
|
||||||
if (res.state == "success") {
|
if (res.state == "success") {
|
||||||
toast(i18n.t("remove_comment"));
|
toast(i18n.t("remove_comment"));
|
||||||
|
this.findAndUpdateComment(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1026,6 +1040,11 @@ export class Inbox extends Component<any, InboxState> {
|
||||||
s.mentionsRes.data.mentions
|
s.mentionsRes.data.mentions
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// Set finished for the parent
|
||||||
|
s.finished.set(
|
||||||
|
getCommentParentId(res.data.comment_view.comment) ?? 0,
|
||||||
|
true
|
||||||
|
);
|
||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
BanFromCommunity,
|
BanFromCommunity,
|
||||||
BanPerson,
|
BanPerson,
|
||||||
BlockPerson,
|
BlockPerson,
|
||||||
|
CommentId,
|
||||||
CommentView,
|
CommentView,
|
||||||
CreateComment,
|
CreateComment,
|
||||||
CreateCommentLike,
|
CreateCommentLike,
|
||||||
|
@ -42,6 +43,7 @@ import { PostListing } from "../post/post-listing";
|
||||||
|
|
||||||
interface PersonDetailsProps {
|
interface PersonDetailsProps {
|
||||||
personRes: GetPersonDetailsResponse;
|
personRes: GetPersonDetailsResponse;
|
||||||
|
finished: Map<CommentId, boolean | undefined>;
|
||||||
admins: PersonView[];
|
admins: PersonView[];
|
||||||
allLanguages: Language[];
|
allLanguages: Language[];
|
||||||
siteLanguages: number[];
|
siteLanguages: number[];
|
||||||
|
@ -147,6 +149,7 @@ export class PersonDetails extends Component<PersonDetailsProps, any> {
|
||||||
key={i.id}
|
key={i.id}
|
||||||
nodes={[{ comment_view: c, children: [], depth: 0 }]}
|
nodes={[{ comment_view: c, children: [], depth: 0 }]}
|
||||||
viewType={CommentViewType.Flat}
|
viewType={CommentViewType.Flat}
|
||||||
|
finished={this.props.finished}
|
||||||
admins={this.props.admins}
|
admins={this.props.admins}
|
||||||
noBorder
|
noBorder
|
||||||
noIndent
|
noIndent
|
||||||
|
@ -255,6 +258,7 @@ export class PersonDetails extends Component<PersonDetailsProps, any> {
|
||||||
nodes={commentsToFlatNodes(this.props.personRes.comments)}
|
nodes={commentsToFlatNodes(this.props.personRes.comments)}
|
||||||
viewType={CommentViewType.Flat}
|
viewType={CommentViewType.Flat}
|
||||||
admins={this.props.admins}
|
admins={this.props.admins}
|
||||||
|
finished={this.props.finished}
|
||||||
noIndent
|
noIndent
|
||||||
showCommunity
|
showCommunity
|
||||||
showContext
|
showContext
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
BanPerson,
|
BanPerson,
|
||||||
BanPersonResponse,
|
BanPersonResponse,
|
||||||
BlockPerson,
|
BlockPerson,
|
||||||
|
CommentId,
|
||||||
CommentReplyResponse,
|
CommentReplyResponse,
|
||||||
CommentResponse,
|
CommentResponse,
|
||||||
Community,
|
Community,
|
||||||
|
@ -65,6 +66,7 @@ import {
|
||||||
enableNsfw,
|
enableNsfw,
|
||||||
fetchLimit,
|
fetchLimit,
|
||||||
futureDaysToUnixTime,
|
futureDaysToUnixTime,
|
||||||
|
getCommentParentId,
|
||||||
getPageFromString,
|
getPageFromString,
|
||||||
getQueryParams,
|
getQueryParams,
|
||||||
getQueryString,
|
getQueryString,
|
||||||
|
@ -100,6 +102,7 @@ interface ProfileState {
|
||||||
showBanDialog: boolean;
|
showBanDialog: boolean;
|
||||||
removeData: boolean;
|
removeData: boolean;
|
||||||
siteRes: GetSiteResponse;
|
siteRes: GetSiteResponse;
|
||||||
|
finished: Map<CommentId, boolean | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ProfileProps {
|
interface ProfileProps {
|
||||||
|
@ -163,6 +166,7 @@ export class Profile extends Component<
|
||||||
siteRes: this.isoData.site_res,
|
siteRes: this.isoData.site_res,
|
||||||
showBanDialog: false,
|
showBanDialog: false,
|
||||||
removeData: false,
|
removeData: false,
|
||||||
|
finished: new Map(),
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props: RouteComponentProps<{ username: string }>, context: any) {
|
constructor(props: RouteComponentProps<{ username: string }>, context: any) {
|
||||||
|
@ -333,6 +337,7 @@ export class Profile extends Component<
|
||||||
sort={sort}
|
sort={sort}
|
||||||
page={page}
|
page={page}
|
||||||
limit={fetchLimit}
|
limit={fetchLimit}
|
||||||
|
finished={this.state.finished}
|
||||||
enableDownvotes={enableDownvotes(siteRes)}
|
enableDownvotes={enableDownvotes(siteRes)}
|
||||||
enableNsfw={enableNsfw(siteRes)}
|
enableNsfw={enableNsfw(siteRes)}
|
||||||
view={view}
|
view={view}
|
||||||
|
@ -842,16 +847,7 @@ export class Profile extends Component<
|
||||||
const createCommentRes = await apiWrapper(
|
const createCommentRes = await apiWrapper(
|
||||||
HttpService.client.createComment(form)
|
HttpService.client.createComment(form)
|
||||||
);
|
);
|
||||||
|
this.createAndUpdateComments(createCommentRes);
|
||||||
this.setState(s => {
|
|
||||||
if (
|
|
||||||
s.personRes.state == "success" &&
|
|
||||||
createCommentRes.state == "success"
|
|
||||||
) {
|
|
||||||
s.personRes.data.comments.unshift(createCommentRes.data.comment_view);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleEditComment(form: EditComment) {
|
async handleEditComment(form: EditComment) {
|
||||||
|
@ -1033,6 +1029,21 @@ export class Profile extends Component<
|
||||||
res.data.comment_view,
|
res.data.comment_view,
|
||||||
s.personRes.data.comments
|
s.personRes.data.comments
|
||||||
);
|
);
|
||||||
|
s.finished.set(res.data.comment_view.comment.id, true);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
createAndUpdateComments(res: RequestState<CommentResponse>) {
|
||||||
|
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;
|
return s;
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,7 +17,6 @@ import {
|
||||||
ResolvePostReport,
|
ResolvePostReport,
|
||||||
ResolvePrivateMessageReport,
|
ResolvePrivateMessageReport,
|
||||||
} from "lemmy-js-client";
|
} from "lemmy-js-client";
|
||||||
import { Subscription } from "rxjs";
|
|
||||||
import { i18n } from "../../i18next";
|
import { i18n } from "../../i18next";
|
||||||
import { InitialFetchRequest } from "../../interfaces";
|
import { InitialFetchRequest } from "../../interfaces";
|
||||||
import { HttpService, UserService } from "../../services";
|
import { HttpService, UserService } from "../../services";
|
||||||
|
@ -82,7 +81,6 @@ interface ReportsState {
|
||||||
|
|
||||||
export class Reports extends Component<any, ReportsState> {
|
export class Reports extends Component<any, ReportsState> {
|
||||||
private isoData = setIsoData(this.context);
|
private isoData = setIsoData(this.context);
|
||||||
private subscription?: Subscription;
|
|
||||||
state: ReportsState = {
|
state: ReportsState = {
|
||||||
commentReportsRes: { state: "empty" },
|
commentReportsRes: { state: "empty" },
|
||||||
postReportsRes: { state: "empty" },
|
postReportsRes: { state: "empty" },
|
||||||
|
@ -130,9 +128,9 @@ export class Reports extends Component<any, ReportsState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
async componentDidMount() {
|
||||||
if (isBrowser()) {
|
if (!isInitialRoute(this.isoData, this.context)) {
|
||||||
this.subscription?.unsubscribe();
|
await this.refetch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,14 +467,14 @@ export class Reports extends Component<any, ReportsState> {
|
||||||
await this.refetch();
|
await this.refetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUnreadOrAllChange(i: Reports, event: any) {
|
async handleUnreadOrAllChange(i: Reports, event: any) {
|
||||||
i.setState({ unreadOrAll: Number(event.target.value), page: 1 });
|
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.setState({ messageType: Number(event.target.value), page: 1 });
|
||||||
i.refetch();
|
await i.refetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
|
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, InfernoNode, linkEvent } from "inferno";
|
||||||
import { T } from "inferno-i18next-dess";
|
import { T } from "inferno-i18next-dess";
|
||||||
import { PostReportView, PostView, ResolvePostReport } from "lemmy-js-client";
|
import { PostReportView, PostView, ResolvePostReport } from "lemmy-js-client";
|
||||||
import { i18n } from "../../i18next";
|
import { i18n } from "../../i18next";
|
||||||
|
@ -25,6 +25,14 @@ export class PostReport extends Component<PostReportProps, PostReportState> {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(
|
||||||
|
nextProps: Readonly<{ children?: InfernoNode } & PostReportProps>
|
||||||
|
): void {
|
||||||
|
if (this.props != nextProps) {
|
||||||
|
this.setState({ loading: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let r = this.props.report;
|
let r = this.props.report;
|
||||||
let resolver = r.resolver;
|
let resolver = r.resolver;
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
BanPersonResponse,
|
BanPersonResponse,
|
||||||
BlockCommunity,
|
BlockCommunity,
|
||||||
BlockPerson,
|
BlockPerson,
|
||||||
|
CommentId,
|
||||||
CommentReplyResponse,
|
CommentReplyResponse,
|
||||||
CommentResponse,
|
CommentResponse,
|
||||||
CommentSortType,
|
CommentSortType,
|
||||||
|
@ -108,6 +109,7 @@ interface PostState {
|
||||||
commentSectionRef?: RefObject<HTMLDivElement>;
|
commentSectionRef?: RefObject<HTMLDivElement>;
|
||||||
showSidebarMobile: boolean;
|
showSidebarMobile: boolean;
|
||||||
maxCommentsShown: number;
|
maxCommentsShown: number;
|
||||||
|
finished: Map<CommentId, boolean | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Post extends Component<any, PostState> {
|
export class Post extends Component<any, PostState> {
|
||||||
|
@ -124,6 +126,7 @@ export class Post extends Component<any, PostState> {
|
||||||
siteRes: this.isoData.site_res,
|
siteRes: this.isoData.site_res,
|
||||||
showSidebarMobile: false,
|
showSidebarMobile: false,
|
||||||
maxCommentsShown: commentsShownInterval,
|
maxCommentsShown: commentsShownInterval,
|
||||||
|
finished: new Map(),
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
|
@ -382,6 +385,7 @@ export class Post extends Component<any, PostState> {
|
||||||
siteLanguages={this.state.siteRes.discussion_languages}
|
siteLanguages={this.state.siteRes.discussion_languages}
|
||||||
onCreateComment={this.handleCreateComment}
|
onCreateComment={this.handleCreateComment}
|
||||||
onEditComment={this.handleEditComment}
|
onEditComment={this.handleEditComment}
|
||||||
|
finished={this.state.finished.get(0)}
|
||||||
/>
|
/>
|
||||||
<div className="d-block d-md-none">
|
<div className="d-block d-md-none">
|
||||||
<button
|
<button
|
||||||
|
@ -511,6 +515,7 @@ export class Post extends Component<any, PostState> {
|
||||||
admins={this.state.siteRes.admins}
|
admins={this.state.siteRes.admins}
|
||||||
enableDownvotes={enableDownvotes(this.state.siteRes)}
|
enableDownvotes={enableDownvotes(this.state.siteRes)}
|
||||||
showContext
|
showContext
|
||||||
|
finished={this.state.finished}
|
||||||
allLanguages={this.state.siteRes.all_languages}
|
allLanguages={this.state.siteRes.all_languages}
|
||||||
siteLanguages={this.state.siteRes.discussion_languages}
|
siteLanguages={this.state.siteRes.discussion_languages}
|
||||||
onSaveComment={this.handleSaveComment}
|
onSaveComment={this.handleSaveComment}
|
||||||
|
@ -600,6 +605,7 @@ export class Post extends Component<any, PostState> {
|
||||||
moderators={res.data.moderators}
|
moderators={res.data.moderators}
|
||||||
admins={this.state.siteRes.admins}
|
admins={this.state.siteRes.admins}
|
||||||
enableDownvotes={enableDownvotes(this.state.siteRes)}
|
enableDownvotes={enableDownvotes(this.state.siteRes)}
|
||||||
|
finished={this.state.finished}
|
||||||
allLanguages={this.state.siteRes.all_languages}
|
allLanguages={this.state.siteRes.all_languages}
|
||||||
siteLanguages={this.state.siteRes.discussion_languages}
|
siteLanguages={this.state.siteRes.discussion_languages}
|
||||||
onSaveComment={this.handleSaveComment}
|
onSaveComment={this.handleSaveComment}
|
||||||
|
@ -782,16 +788,7 @@ export class Post extends Component<any, PostState> {
|
||||||
const createCommentRes = await apiWrapper(
|
const createCommentRes = await apiWrapper(
|
||||||
HttpService.client.createComment(form)
|
HttpService.client.createComment(form)
|
||||||
);
|
);
|
||||||
|
this.createAndUpdateComments(createCommentRes);
|
||||||
this.setState(s => {
|
|
||||||
if (
|
|
||||||
s.commentsRes.state == "success" &&
|
|
||||||
createCommentRes.state == "success"
|
|
||||||
) {
|
|
||||||
s.commentsRes.data.comments.unshift(createCommentRes.data.comment_view);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleEditComment(form: EditComment) {
|
async handleEditComment(form: EditComment) {
|
||||||
|
@ -1021,6 +1018,21 @@ export class Post extends Component<any, PostState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createAndUpdateComments(res: RequestState<CommentResponse>) {
|
||||||
|
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<CommentResponse>) {
|
findAndUpdateComment(res: RequestState<CommentResponse>) {
|
||||||
this.setState(s => {
|
this.setState(s => {
|
||||||
if (s.commentsRes.state == "success" && res.state == "success") {
|
if (s.commentsRes.state == "success" && res.state == "success") {
|
||||||
|
@ -1028,6 +1040,7 @@ export class Post extends Component<any, PostState> {
|
||||||
res.data.comment_view,
|
res.data.comment_view,
|
||||||
s.commentsRes.data.comments
|
s.commentsRes.data.comments
|
||||||
);
|
);
|
||||||
|
s.finished.set(res.data.comment_view.comment.id, true);
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
import {
|
import {
|
||||||
|
CreatePrivateMessage as CreatePrivateMessageI,
|
||||||
GetPersonDetails,
|
GetPersonDetails,
|
||||||
GetPersonDetailsResponse,
|
GetPersonDetailsResponse,
|
||||||
GetSiteResponse,
|
GetSiteResponse,
|
||||||
|
@ -151,10 +152,14 @@ export class CreatePrivateMessage extends Component<
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePrivateMessageCreate() {
|
async handlePrivateMessageCreate(form: CreatePrivateMessageI) {
|
||||||
toast(i18n.t("message_sent"));
|
const res = await apiWrapper(HttpService.client.createPrivateMessage(form));
|
||||||
|
|
||||||
// Navigate to the front
|
if (res.state == "success") {
|
||||||
this.context.router.history.push("/");
|
toast(i18n.t("message_sent"));
|
||||||
|
|
||||||
|
// Navigate to the front
|
||||||
|
this.context.router.history.push("/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, InfernoNode, linkEvent } from "inferno";
|
||||||
import { T } from "inferno-i18next-dess";
|
import { T } from "inferno-i18next-dess";
|
||||||
import { Prompt } from "inferno-router";
|
import { Prompt } from "inferno-router";
|
||||||
import {
|
import {
|
||||||
|
@ -56,12 +56,11 @@ export class PrivateMessageForm extends Component<
|
||||||
setupTippy();
|
setupTippy();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO what is this
|
componentWillReceiveProps(
|
||||||
componentDidUpdate() {
|
nextProps: Readonly<{ children?: InfernoNode } & PrivateMessageFormProps>
|
||||||
if (!this.state.loading && this.state.content) {
|
): void {
|
||||||
window.onbeforeunload = () => true;
|
if (this.props != nextProps) {
|
||||||
} else {
|
this.setState({ loading: false, content: undefined, previewMode: false });
|
||||||
window.onbeforeunload = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, InfernoNode, linkEvent } from "inferno";
|
||||||
import { T } from "inferno-i18next-dess";
|
import { T } from "inferno-i18next-dess";
|
||||||
import {
|
import {
|
||||||
PrivateMessageReportView,
|
PrivateMessageReportView,
|
||||||
|
@ -27,6 +27,14 @@ export class PrivateMessageReport extends Component<Props, State> {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(
|
||||||
|
nextProps: Readonly<{ children?: InfernoNode } & Props>
|
||||||
|
): void {
|
||||||
|
if (this.props != nextProps) {
|
||||||
|
this.setState({ loading: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let r = this.props.report;
|
let r = this.props.report;
|
||||||
let pmr = r.private_message_report;
|
let pmr = r.private_message_report;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component, InfernoNode, linkEvent } from "inferno";
|
||||||
import {
|
import {
|
||||||
CreatePrivateMessage,
|
CreatePrivateMessage,
|
||||||
CreatePrivateMessageReport,
|
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() {
|
render() {
|
||||||
let message_view = this.props.private_message_view;
|
let message_view = this.props.private_message_view;
|
||||||
let otherPerson: Person = this.mine
|
let otherPerson: Person = this.mine
|
||||||
|
|
|
@ -657,6 +657,7 @@ export class Search extends Component<any, SearchState> {
|
||||||
allLanguages={this.state.siteRes.all_languages}
|
allLanguages={this.state.siteRes.all_languages}
|
||||||
siteLanguages={this.state.siteRes.discussion_languages}
|
siteLanguages={this.state.siteRes.discussion_languages}
|
||||||
// All of these are unused, since its viewonly
|
// All of these are unused, since its viewonly
|
||||||
|
finished={new Map()}
|
||||||
onSaveComment={() => {}}
|
onSaveComment={() => {}}
|
||||||
onBlockPerson={() => {}}
|
onBlockPerson={() => {}}
|
||||||
onDeleteComment={() => {}}
|
onDeleteComment={() => {}}
|
||||||
|
@ -717,6 +718,7 @@ export class Search extends Component<any, SearchState> {
|
||||||
allLanguages={siteRes.all_languages}
|
allLanguages={siteRes.all_languages}
|
||||||
siteLanguages={siteRes.discussion_languages}
|
siteLanguages={siteRes.discussion_languages}
|
||||||
// All of these are unused, since its viewonly
|
// All of these are unused, since its viewonly
|
||||||
|
finished={new Map()}
|
||||||
onSaveComment={() => {}}
|
onSaveComment={() => {}}
|
||||||
onBlockPerson={() => {}}
|
onBlockPerson={() => {}}
|
||||||
onDeleteComment={() => {}}
|
onDeleteComment={() => {}}
|
||||||
|
|
Loading…
Reference in a new issue