feat: negentropy progress

This commit is contained in:
reya
2024-10-25 14:57:12 +07:00
parent 055d73c829
commit 5ab2b1ae31
27 changed files with 769 additions and 663 deletions
+41 -46
View File
@@ -1,7 +1,7 @@
import { appSettings, cn } from "@/commons";
import { useStore } from "@tanstack/react-store";
import { nanoid } from "nanoid";
import { type ReactNode, memo, useMemo, useState } from "react";
import { type ReactNode, useMemo, useState } from "react";
import reactStringReplace from "react-string-replace";
import { Hashtag } from "./mentions/hashtag";
import { MentionNote } from "./mentions/note";
@@ -22,7 +22,6 @@ export function NoteContent({
}) {
const event = useNoteContext();
const visible = useStore(appSettings, (state) => state.display_media);
const warning = useMemo(() => event.warning, [event]);
const content = useMemo(() => {
try {
// Get parsed meta
@@ -88,52 +87,48 @@ export function NoteContent({
}
}, [event.content]);
const [blurred, setBlurred] = useState(() =>
event.warning ? event.warning.length > 0 : false,
);
return (
<div className="relative flex flex-col gap-2">
<ContentWarning warning={warning} />
<div
className={cn(
"select-text text-pretty content-break overflow-hidden",
className,
)}
>
{content}
</div>
{visible ? (
event.meta?.images.length ? (
<Images urls={event.meta.images} />
) : null
) : null}
{!blurred ? (
<>
<div
className={cn(
"select-text text-pretty content-break overflow-hidden",
className,
)}
>
{content}
</div>
{visible ? (
event.meta?.images.length ? (
<Images urls={event.meta.images} />
) : null
) : null}
</>
) : (
<div
className={cn(
"select-text text-pretty content-break overflow-hidden",
className,
)}
>
<p className="text-yellow-600 dark:text-yellow-400">
The content is hidden because the author marked it with a warning
for a reason: <span className="font-semibold">{event.warning}</span>
</p>
<button
type="button"
onClick={() => setBlurred(false)}
className="font-medium text-sm text-blue-500 hover:text-blue-600"
>
View anyway
</button>
</div>
)}
</div>
);
}
const ContentWarning = memo(function ContentWarning({
warning,
}: { warning: string }) {
const [blurred, setBlurred] = useState(() => warning?.length > 0);
if (!blurred) {
return null;
}
return (
<div className="absolute inset-0 z-10 flex items-center justify-center w-full bg-black/80 backdrop-blur-lg">
<div className="flex flex-col items-center justify-center gap-2 text-center">
<p className="text-sm text-white/60">
The content is hidden because the author
<br />
marked it with a warning for a reason:
</p>
<p className="text-sm font-medium text-white">{warning}</p>
<button
type="button"
onClick={() => setBlurred(false)}
className="inline-flex items-center justify-center px-2 mt-4 text-sm font-medium border rounded-lg text-white/70 h-9 w-max bg-white/20 hover:bg-white/30 border-white/5"
>
View anyway
</button>
</div>
</div>
);
});
+7 -4
View File
@@ -17,16 +17,19 @@ export const MentionNote = memo(function MentionNote({
return (
<div className="relative my-2">
<div className="min-h-[64px] pl-3 before:content-[''] before:absolute before:top-1.5 before:bottom-1.5 before:left-0 before:border-l-[2px] before:border-black/10 dark:before:border-white/10">
<div className="pl-3 before:content-[''] before:absolute before:top-1.5 before:bottom-1.5 before:left-0 before:border-l-[2px] before:border-black/10 dark:before:border-white/10">
{isLoading ? (
<div className="h-[64px] flex items-center">
<div className="h-[32px] flex items-center gap-2 text-sm">
<Spinner />
Loadng note
</div>
) : isError || !event ? (
<div className="h-[64px] flex items-center">
<div className="flex flex-col break-all">
<p className="text-sm font-medium text-red-500">
{error.message || "Note can be found with your current relay set"}
{error?.message ??
"Cannot found this note within your current relay set"}
</p>
<p className="text-sm">{eventId}</p>
</div>
) : (
<Note.Provider event={event}>
-4
View File
@@ -39,10 +39,6 @@ export function ImagePreview({ url }: { url: string }) {
decoding="async"
style={{ contentVisibility: "auto" }}
className="max-h-[400px] w-full h-auto object-cover rounded-lg outline outline-1 -outline-offset-1 outline-black/15"
onError={({ currentTarget }) => {
currentTarget.onerror = null;
currentTarget.src = "/404.jpg";
}}
/>
</div>
);
+9 -11
View File
@@ -21,9 +21,15 @@ export function Images({ urls }: { urls: string[] }) {
let newUrls: string[];
if (urls.length === 1) {
newUrls = urls.map(
(url) => `${service}?url=${url}&ll&af&default=1&n=-1`,
);
newUrls = urls.map((url) => {
if (url.includes("_next/")) {
return url;
}
if (url.includes("bsky.network")) {
return url;
}
return `${service}?url=${url}&ll&af&default=1&n=-1`;
});
} else {
newUrls = urls.map(
(url) => `${service}?url=${url}&w=480&h=640&ll&af&default=1&n=-1`,
@@ -83,10 +89,6 @@ export function Images({ urls }: { urls: string[] }) {
className="max-h-[400px] w-auto object-cover rounded-lg outline outline-1 -outline-offset-1 outline-black/15"
onClick={() => urls[0]}
onKeyDown={() => urls[0]}
onError={({ currentTarget }) => {
currentTarget.onerror = null;
currentTarget.src = "/404.jpg";
}}
/>
</div>
);
@@ -162,10 +164,6 @@ function LazyImage({ url, inView }: { url: string; inView: boolean }) {
onClick={() => open(url)}
onKeyDown={() => open(url)}
onLoad={setLoaded}
onError={({ currentTarget }) => {
currentTarget.onerror = null;
currentTarget.src = "/404.jpg";
}}
/>
</div>
);
+3
View File
@@ -18,6 +18,9 @@ export function UserAvatar({ className }: { className?: string }) {
if (user.profile?.picture.includes("_next/")) {
return user.profile?.picture;
}
if (user.profile?.picture.includes("bsky.network")) {
return user.profile?.picture;
}
return `${service}?url=${user.profile?.picture}&w=100&h=100&n=-1&default=${user.profile?.picture}`;
} else {
return user.profile?.picture;