Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion public/sw.js

Large diffs are not rendered by default.

32 changes: 9 additions & 23 deletions src/api/mutations/create-reply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,15 @@ import { EcencyEntriesCacheManagement } from "@/core/caches";
import { comment, formatError } from "../operations";
import { tempEntry } from "@/utils";
import { QueryIdentifiers } from "@/core/react-query";
import { error } from "@/features/shared";
import { error, success } from "@/features/shared";
import * as ss from "@/utils/session-storage";
import { useGlobalStore } from "@/core/global-store";
import i18next from "i18next";

export function useCreateReply(entry?: Entry | null, parent?: Entry, onSuccess?: () => void) {
const activeUser = useGlobalStore((state) => state.activeUser);

const { addReply } = EcencyEntriesCacheManagement.useAddReply(entry ?? undefined);
const { updateRepliesCount } = EcencyEntriesCacheManagement.useUpdateRepliesCount(
entry ?? undefined
);
const { updateEntryQueryData } = EcencyEntriesCacheManagement.useUpdateEntry();

const queryClient = useQueryClient();
Expand Down Expand Up @@ -61,36 +59,24 @@ export function useCreateReply(entry?: Entry | null, parent?: Entry, onSuccess?:
});
},
onSuccess: (data) => {
if (!entry) {
return;
}

addReply(data);
updateEntryQueryData([data]);

// remove reply draft
ss.remove(`reply_draft_${entry.author}_${entry.permlink}`);
ss.remove(`reply_draft_${entry!.author}_${entry!.permlink}`);

if (entry.children === 0) {
// Update parent comment.
updateRepliesCount(1);
}
const previousReplies =
queryClient.getQueryData<Entry[]>([
QueryIdentifiers.FETCH_DISCUSSIONS,
parent?.author ?? entry.author,
parent?.permlink ?? entry.permlink
]) ?? [];
queryClient.setQueryData(
queryClient.setQueryData<Entry[]>(
[
QueryIdentifiers.FETCH_DISCUSSIONS,
parent?.author ?? entry.author,
parent?.permlink ?? entry.permlink
parent?.author ?? entry!.author,
parent?.permlink ?? entry!.permlink
],
[data, ...previousReplies]
(previousReplies) => [data, ...(previousReplies ?? [])]
);

onSuccess?.();

success(i18next.t("comment.success"));
},
onError: (e) => error(...formatError(e))
});
Expand Down
57 changes: 20 additions & 37 deletions src/app/[...slugs]/_entry-components/entry-page-content.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
"use client";

import { EntryPageNsfwWarning } from "@/app/[...slugs]/_entry-components/entry-page-nsfw-warning";
import { EntryPageCrossPostBody } from "@/app/[...slugs]/_entry-components/entry-page-cross-post-body";
import { EntryPageWarnings } from "@/app/[...slugs]/_entry-components/entry-page-warnings";
import { EntryPageIsCommentHeader } from "@/app/[...slugs]/_entry-components/entry-page-is-comment-header";
Expand All @@ -14,9 +11,7 @@ import { EntryPageShowOriginal } from "@/app/[...slugs]/_entry-components/entry-
import { EntryPageSimilarEntries } from "@/app/[...slugs]/_entry-components/entry-page-similar-entries";
import { EntryPageDiscussions } from "@/app/[...slugs]/_entry-components/entry-page-discussions";
import { Entry } from "@/entities";
import { useGlobalStore } from "@/core/global-store";
import { EcencyClientServerBridge } from "@/core/client-server-bridge";
import { EntryPageContext } from "@/app/[...slugs]/_entry-components/context";
import { EntryPageNsfwRevealing } from "@/app/[...slugs]/_entry-components/entry-page-nsfw-revealing";

interface Props {
entry: Entry;
Expand All @@ -26,37 +21,25 @@ interface Props {
}

export function EntryPageContent({ entry, rawParam, isEdit, category }: Props) {
const globalNsfw = useGlobalStore((s) => s.nsfw);

const { showIfNsfw } = EcencyClientServerBridge.useSafeContext(EntryPageContext);

const showNsfwWarning =
(entry.json_metadata.tags?.includes("nsfw") ?? false) && !showIfNsfw && !globalNsfw;

return (
<>
{showNsfwWarning && <EntryPageNsfwWarning />}
{!showNsfwWarning && (
<>
<EntryPageCrossPostBody entry={entry} />
<EntryPageProfileBox entry={entry} />
<div className="entry-header">
<EntryPageWarnings entry={entry} />
<EntryPageIsCommentHeader entry={entry} />
<h1 className="entry-title">{entry.title}</h1>
<EntryPageMainInfo entry={entry} />
</div>
<EntryPageBodyViewer entry={entry} rawParam={rawParam} isEdit={isEdit} />
<div className="entry-footer flex-wrap mb-4 lg:mb-8 border border-[--border-color] p-2 md:p-4 rounded-2xl">
<EntryTags entry={entry} />
<EntryFooterInfo entry={entry} />
<EntryFooterControls entry={entry} />
</div>
<EntryPageShowOriginal entry={entry} />
<EntryPageSimilarEntries entry={entry} />
<EntryPageDiscussions category={category} entry={entry} />
</>
)}
</>
<EntryPageNsfwRevealing entry={entry}>
<EntryPageCrossPostBody entry={entry} />
<EntryPageProfileBox entry={entry} />
<div className="entry-header">
<EntryPageWarnings entry={entry} />
<EntryPageIsCommentHeader entry={entry} />
<h1 className="entry-title">{entry.title}</h1>
<EntryPageMainInfo entry={entry} />
</div>
<EntryPageBodyViewer entry={entry} rawParam={rawParam} isEdit={isEdit} />
<div className="entry-footer flex-wrap mb-4 lg:mb-8 border border-[--border-color] p-2 md:p-4 rounded-2xl">
<EntryTags entry={entry} />
<EntryFooterInfo entry={entry} />
<EntryFooterControls entry={entry} />
</div>
<EntryPageShowOriginal entry={entry} />
<EntryPageSimilarEntries entry={entry} />
<EntryPageDiscussions category={category} entry={entry} />
</EntryPageNsfwRevealing>
);
}
19 changes: 12 additions & 7 deletions src/app/[...slugs]/_entry-components/entry-page-discussions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,25 @@ import { EntryPageContext } from "@/app/[...slugs]/_entry-components/context";
import { createReplyPermlink, makeJsonMetaDataReply } from "@/utils";
import appPackage from "../../../../package.json";
import { useCreateReply } from "@/api/mutations";
import { getCommunityCache } from "@/core/caches";
import { EcencyEntriesCacheManagement, getCommunityCache } from "@/core/caches";
import { EcencyConfigManager } from "@/config";

interface Props {
entry: Entry;
category: string;
}

export function EntryPageDiscussions({ entry, category }: Props) {
export function EntryPageDiscussions({ entry: initialEntry, category }: Props) {
const params = useSearchParams();

const { commentsInputRef, selection } = EcencyClientServerBridge.useSafeContext(EntryPageContext);
const { commentsInputRef, selection, setSelection } =
EcencyClientServerBridge.useSafeContext(EntryPageContext);

const activeUser = useGlobalStore((s) => s.activeUser);

const [isCommented, setIsCommented] = useState(false);

const { data: entry } = EcencyEntriesCacheManagement.getEntryQuery(initialEntry).useClientQuery();
const { data: community } = getCommunityCache(category).useClientQuery();
const isRawContent = useMemo(
() =>
Expand All @@ -48,30 +50,33 @@ export function EntryPageDiscussions({ entry, category }: Props) {
const permlink = createReplyPermlink(entry!.author);
const tags = entry!.json_metadata.tags || ["ecency"];

return createReply({
const response = await createReply({
jsonMeta: makeJsonMetaDataReply(tags, appPackage.version),
text,
permlink,
point: true
});

setSelection("");
return response;
};

return (
<>
<Comment
defText={selection}
submitText={i18next.t("g.reply")}
entry={entry}
entry={entry!}
onSubmit={replySubmitted}
isCommented={isCommented}
inProgress={isCreateReplyLoading}
inputRef={commentsInputRef}
/>

{activeUser && entry.children === 0 && <CommentEngagement />}
{activeUser && entry!.children === 0 && <CommentEngagement />}

<Discussion
parent={entry}
parent={entry!}
community={community!!}
hideControls={false}
isRawContent={isRawContent}
Expand Down
23 changes: 23 additions & 0 deletions src/app/[...slugs]/_entry-components/entry-page-nsfw-revealing.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"use client";

import { useGlobalStore } from "@/core/global-store";
import { EcencyClientServerBridge } from "@/core/client-server-bridge";
import { EntryPageContext } from "@/app/[...slugs]/_entry-components/context";
import { Entry } from "@/entities";
import { EntryPageNsfwWarning } from "@/app/[...slugs]/_entry-components/entry-page-nsfw-warning";
import { PropsWithChildren } from "react";

interface Props {
entry: Entry;
}

export function EntryPageNsfwRevealing({ entry, children }: PropsWithChildren<Props>) {
const globalNsfw = useGlobalStore((s) => s.nsfw);

const { showIfNsfw } = EcencyClientServerBridge.useSafeContext(EntryPageContext);

const showNsfwWarning =
(entry.json_metadata.tags?.includes("nsfw") ?? false) && !showIfNsfw && !globalNsfw;

return showNsfwWarning ? <EntryPageNsfwWarning /> : children;
}
2 changes: 1 addition & 1 deletion src/app/submit/_hooks/api-draft-detector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export function useApiDraftDetector(
onDraftLoaded(draftQuery.data);
setActivePoll(draftQuery.data.meta?.poll);
}
}, [draftQuery.data, onDraftLoaded, setActivePoll]);
}, [draftQuery.data]);

useEffect(() => {
// location change. only occurs once a draft picked on drafts dialog
Expand Down
18 changes: 1 addition & 17 deletions src/core/caches/entries-cache.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,23 +114,7 @@ export namespace EcencyEntriesCacheManagement {
const qc = useQueryClient();

return {
updateEntryQueryData: (entries: Entry[]) =>
entries.forEach((entry) => {
qc.setQueryData<Entry>(
[QueryIdentifiers.ENTRY, makeEntryPath("", entry.author, entry.permlink)],
() => {
const data = { ...entry };
if (
dmca.some((rx: string) => new RegExp(rx).test(`@${entry.author}/${entry.permlink}`))
) {
data.body = "This post is not available due to a copyright/fraudulent claim.";
data.title = "";
}

return data;
}
);
})
updateEntryQueryData: (entries: Entry[]) => updateEntryQueryData(entries, qc)
};
}

Expand Down
3 changes: 2 additions & 1 deletion src/features/i18n/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,8 @@
},
"comment": {
"body-placeholder": "Write your reply here",
"preview": "Preview"
"preview": "Preview",
"success": "Your reply created successfully!"
},
"discussion": {
"join": "Join the conversation now",
Expand Down
5 changes: 3 additions & 2 deletions src/features/shared/comment/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { Entry } from "@/entities";
import { useDebounce, useMount } from "react-use";
import useUnmount from "react-use/lib/useUnmount";
import { detectEvent, EditorToolbar, toolbarEventListener } from "@/features/shared/editor-toolbar";
import { AvailableCredits } from "../available-credits";
import { AvailableCredits } from "@/features/shared";
import { TextareaAutocomplete } from "@/features/shared/textarea-autocomplete";
import usePrevious from "react-use/lib/usePrevious";

Expand Down Expand Up @@ -149,9 +149,10 @@ export function Comment({
if (resetSelection) resetSelection();
updateLsCommentDraft(commentText);
}
if (previousIsCommented && !isCommented) {
if (!previousIsCommented && isCommented) {
setText("");
setPreview("");
updateLsCommentDraft("");
}
}, [
defText,
Expand Down
27 changes: 14 additions & 13 deletions src/features/shared/discussion/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,20 @@ export function Discussion({ hideControls, isRawContent, parent, community }: Pr
).useClientQuery();
const { data: botsList } = getBotsQuery().useClientQuery();

const count = useMemo(() => parent.children, [parent]);
const strCount = useMemo(
() =>
count > 1 ? i18next.t("discussion.n-replies", { n: count }) : i18next.t("discussion.replies"),
[count]
);
const filtered = useMemo(
() =>
data?.filter(
(x) => x.parent_author === parent.author && x.parent_permlink === parent.permlink
),
) ?? [],
[data, parent]
);
const strCount = useMemo(
() =>
filtered.length > 1
? i18next.t("discussion.n-replies", { n: filtered.length })
: i18next.t("discussion.replies"),
[filtered]
);
const botsData = useMemo(
() => filtered?.filter((entry) => botsList?.includes(entry.author) && entry.children === 0),
[botsList, filtered]
Expand All @@ -69,8 +70,8 @@ export function Discussion({ hideControls, isRawContent, parent, community }: Pr
useEffect(() => setVisible(!!activeUser), [activeUser]);

useEffect(() => {
updateEntryQueryData(Array.from(Object.values(data ?? [])));
}, [data]);
updateEntryQueryData(filtered);
}, [filtered]);

const show = () => setVisible(true);

Expand All @@ -92,15 +93,15 @@ export function Discussion({ hideControls, isRawContent, parent, community }: Pr
);
}

if (!activeUser && count < 1) {
if (!activeUser && filtered.length < 1) {
return <div className="discussion">{join}</div>;
}

if (count < 1) {
return <div className="discussion empty" />;
if (filtered.length < 1) {
return <></>;
}

if (!visible && count >= 1) {
if (!visible && filtered.length >= 1) {
return (
<div className="discussion">
<div className="discussion-card">
Expand Down
4 changes: 1 addition & 3 deletions src/features/shared/textarea-autocomplete/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ export function TextareaAutocomplete(props: any) {
}

useEffect(() => {
if (!value && props.value) {
setValue(props.value);
}
setValue(props.value);
}, [props.value, value]);

const handleChange = (event: any) => {
Expand Down