polish
This commit is contained in:
@@ -83,7 +83,7 @@ export function FileNote({ event }: { event: NDKEvent }) {
|
||||
<div className="mb-3 h-min w-full px-3">
|
||||
<div className="relative flex flex-col gap-2 overflow-hidden rounded-xl bg-neutral-50 pt-3 dark:bg-neutral-950">
|
||||
<User pubkey={event.pubkey} time={event.created_at} eventId={event.id} />
|
||||
<div>{renderFileType()}</div>
|
||||
<div className="relative mt-2">{renderFileType()}</div>
|
||||
<NoteActions id={event.id} pubkey={event.pubkey} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,15 +1,29 @@
|
||||
import { downloadDir } from '@tauri-apps/api/path';
|
||||
import { Window } from '@tauri-apps/api/window';
|
||||
import { download } from '@tauri-apps/plugin-upload';
|
||||
import { SyntheticEvent } from 'react';
|
||||
import Zoom from 'react-medium-image-zoom';
|
||||
import { SyntheticEvent, useState } from 'react';
|
||||
|
||||
import { CancelIcon, DownloadIcon } from '@shared/icons';
|
||||
import { CheckCircleIcon, DownloadIcon } from '@shared/icons';
|
||||
|
||||
export function ImagePreview({ url }: { url: string }) {
|
||||
const downloadImage = async (url: string) => {
|
||||
const downloadDirPath = await downloadDir();
|
||||
const filename = url.substring(url.lastIndexOf('/') + 1);
|
||||
return await download(url, downloadDirPath + `/${filename}`);
|
||||
const [downloaded, setDownloaded] = useState(false);
|
||||
|
||||
const downloadImage = async (e: { stopPropagation: () => void }) => {
|
||||
try {
|
||||
e.stopPropagation();
|
||||
|
||||
const downloadDirPath = await downloadDir();
|
||||
const filename = url.substring(url.lastIndexOf('/') + 1);
|
||||
await download(url, downloadDirPath + `/${filename}`);
|
||||
|
||||
setDownloaded(true);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
const open = () => {
|
||||
return new Window('image-viewer', { url, title: 'Image Viewer' });
|
||||
};
|
||||
|
||||
const fallback = (event: SyntheticEvent<HTMLImageElement, Event>) => {
|
||||
@@ -17,25 +31,28 @@ export function ImagePreview({ url }: { url: string }) {
|
||||
};
|
||||
|
||||
return (
|
||||
<Zoom key={url} zoomMargin={50} IconUnzoom={() => <CancelIcon className="h-4 w-4" />}>
|
||||
<div className="group relative my-2">
|
||||
<img
|
||||
src={url}
|
||||
alt={url}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
style={{ contentVisibility: 'auto' }}
|
||||
onError={fallback}
|
||||
className="h-auto w-full rounded-lg border border-neutral-300/50 object-cover dark:border-neutral-700/50"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => downloadImage(url)}
|
||||
className="absolute right-2 top-2 hidden h-10 w-10 items-center justify-center rounded-lg bg-black/50 backdrop-blur-xl group-hover:inline-flex hover:bg-blue-500"
|
||||
>
|
||||
<DownloadIcon className="h-4 w-4 text-white" />
|
||||
</button>
|
||||
</div>
|
||||
</Zoom>
|
||||
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
|
||||
<div onClick={open} className="group relative my-2">
|
||||
<img
|
||||
src={url}
|
||||
alt={url}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
style={{ contentVisibility: 'auto' }}
|
||||
onError={fallback}
|
||||
className="h-auto w-full rounded-lg border border-neutral-300/50 object-cover dark:border-neutral-700/50"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => downloadImage(e)}
|
||||
className="absolute right-2 top-2 z-10 hidden h-10 w-10 items-center justify-center rounded-lg bg-blue-500 group-hover:inline-flex hover:bg-blue-600"
|
||||
>
|
||||
{downloaded ? (
|
||||
<CheckCircleIcon className="h-5 w-5 text-white" />
|
||||
) : (
|
||||
<DownloadIcon className="h-5 w-5 text-white" />
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ export function TextNote({ event }: { event: NDKEvent }) {
|
||||
const { addWidget } = useWidget();
|
||||
const { getEventThread } = useNostr();
|
||||
|
||||
const thread = getEventThread(event);
|
||||
const thread = getEventThread(event.tags);
|
||||
|
||||
return (
|
||||
<div className="mb-3 h-min w-full px-3">
|
||||
|
||||
@@ -4,6 +4,7 @@ import { WVList } from 'virtua';
|
||||
|
||||
import { LoaderIcon } from '@shared/icons';
|
||||
import {
|
||||
ChildNote,
|
||||
MemoizedArticleKind,
|
||||
MemoizedFileKind,
|
||||
MemoizedTextKind,
|
||||
@@ -16,16 +17,33 @@ import { User } from '@shared/user';
|
||||
import { WidgetWrapper } from '@shared/widgets';
|
||||
|
||||
import { useEvent } from '@utils/hooks/useEvent';
|
||||
import { useNostr } from '@utils/hooks/useNostr';
|
||||
import { Widget } from '@utils/types';
|
||||
|
||||
export function ThreadWidget({ widget }: { widget: Widget }) {
|
||||
const { status, data } = useEvent(widget.content);
|
||||
const { getEventThread } = useNostr();
|
||||
|
||||
const renderKind = useCallback(
|
||||
(event: NDKEvent) => {
|
||||
const thread = getEventThread(event.tags);
|
||||
switch (event.kind) {
|
||||
case NDKKind.Text:
|
||||
return <MemoizedTextKind content={event.content} />;
|
||||
return (
|
||||
<>
|
||||
{thread ? (
|
||||
<div className="mb-2 w-full px-3">
|
||||
<div className="flex h-min w-full flex-col gap-3 rounded-lg bg-neutral-100 p-3 dark:bg-neutral-900">
|
||||
{thread.rootEventId ? (
|
||||
<ChildNote id={thread.rootEventId} isRoot />
|
||||
) : null}
|
||||
{thread.replyEventId ? <ChildNote id={thread.replyEventId} /> : null}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
<MemoizedTextKind content={event.content} />
|
||||
</>
|
||||
);
|
||||
case NDKKind.Article:
|
||||
return <MemoizedArticleKind id={event.id} tags={event.tags} />;
|
||||
case 1063:
|
||||
|
||||
Reference in New Issue
Block a user