update preview components

This commit is contained in:
Ren Amamiya
2023-04-24 17:54:12 +07:00
parent 188c052a1a
commit f0d0e79e3d
13 changed files with 237 additions and 184 deletions

View File

@@ -0,0 +1,92 @@
import { ActiveLink } from '@components/activeLink';
import ChannelList from '@components/channels/channelList';
import ChatList from '@components/chats/chatList';
import { Disclosure } from '@headlessui/react';
import { Bonfire, NavArrowUp, PeopleTag } from 'iconoir-react';
import { Suspense } from 'react';
import Skeleton from 'react-loading-skeleton';
export default function Navigation() {
return (
<div className="relative flex h-full flex-col gap-1 overflow-hidden pt-3">
{/* Newsfeed */}
<Disclosure defaultOpen={true}>
{({ open }) => (
<div className="flex flex-col px-2">
<Disclosure.Button className="flex cursor-pointer items-center gap-1 px-1 py-1">
<div
className={`inline-flex h-5 w-5 transform items-center justify-center transition-transform duration-150 ease-in-out ${
open ? 'rotate-180' : ''
}`}
>
<NavArrowUp width={16} height={16} className="text-zinc-700" />
</div>
<h3 className="text-[11px] font-bold uppercase tracking-widest text-zinc-600">Newsfeed</h3>
</Disclosure.Button>
<Disclosure.Panel className="flex flex-col text-zinc-400">
<ActiveLink
href="/newsfeed/following"
className="flex h-8 items-center gap-2.5 rounded-md px-2.5 text-sm font-medium hover:text-zinc-200"
activeClassName="dark:bg-zinc-900 dark:text-zinc-100 hover:dark:bg-zinc-800"
>
<PeopleTag width={16} height={16} className="text-zinc-500" />
<span>Following</span>
</ActiveLink>
<ActiveLink
href="/newsfeed/circle"
className="flex h-8 items-center gap-2.5 rounded-md px-2.5 text-sm font-medium hover:text-zinc-200"
activeClassName="dark:bg-zinc-900 dark:text-zinc-100 hover:dark:bg-zinc-800"
>
<Bonfire width={16} height={16} className="text-zinc-500" />
<span>Circle</span>
</ActiveLink>
</Disclosure.Panel>
</div>
)}
</Disclosure>
{/* Channels */}
<Disclosure defaultOpen={true}>
{({ open }) => (
<div className="flex flex-col px-2">
<Disclosure.Button className="flex cursor-pointer items-center gap-1 px-1 py-1">
<div
className={`inline-flex h-5 w-5 transform items-center justify-center transition-transform duration-150 ease-in-out ${
open ? 'rotate-180' : ''
}`}
>
<NavArrowUp width={16} height={16} className="text-zinc-700" />
</div>
<h3 className="text-[11px] font-bold uppercase tracking-widest text-zinc-600">Channels</h3>
</Disclosure.Button>
<Disclosure.Panel>
<Suspense fallback={<Skeleton count={2} />}>
<ChannelList />
</Suspense>
</Disclosure.Panel>
</div>
)}
</Disclosure>
{/* Chats */}
<Disclosure defaultOpen={true}>
{({ open }) => (
<div className="flex flex-col px-2">
<Disclosure.Button className="flex cursor-pointer items-center gap-1 px-1 py-1">
<div
className={`inline-flex h-5 w-5 transform items-center justify-center transition-transform duration-150 ease-in-out ${
open ? 'rotate-180' : ''
}`}
>
<NavArrowUp width={16} height={16} className="text-zinc-700" />
</div>
<h3 className="text-[11px] font-bold uppercase tracking-widest text-zinc-600">Chats</h3>
</Disclosure.Button>
<Disclosure.Panel>
<ChatList />
</Disclosure.Panel>
</div>
)}
</Disclosure>
</div>
);
}

View File

@@ -1,32 +0,0 @@
import ChannelList from '@components/channels/channelList';
import { Disclosure } from '@headlessui/react';
import { NavArrowUp } from 'iconoir-react';
import { Suspense } from 'react';
import Skeleton from 'react-loading-skeleton';
export default function Channels() {
return (
<Disclosure>
{({ open }) => (
<div className="flex flex-col px-2">
<Disclosure.Button className="flex cursor-pointer items-center gap-1 px-1 py-1">
<div
className={`inline-flex h-5 w-5 transform items-center justify-center transition-transform duration-150 ease-in-out ${
open ? 'rotate-180' : ''
}`}
>
<NavArrowUp width={16} height={16} className="text-zinc-700" />
</div>
<h3 className="text-[11px] font-bold uppercase tracking-widest text-zinc-600">Channels</h3>
</Disclosure.Button>
<Disclosure.Panel>
<Suspense fallback={<Skeleton count={2} />}>
<ChannelList />
</Suspense>
</Disclosure.Panel>
</div>
)}
</Disclosure>
);
}

View File

@@ -1,28 +0,0 @@
import ChatList from '@components/chats/chatList';
import { Disclosure } from '@headlessui/react';
import { NavArrowUp } from 'iconoir-react';
export default function Chats() {
return (
<Disclosure>
{({ open }) => (
<div className="flex flex-col px-2">
<Disclosure.Button className="flex cursor-pointer items-center gap-1 px-1 py-1">
<div
className={`inline-flex h-5 w-5 transform items-center justify-center transition-transform duration-150 ease-in-out ${
open ? 'rotate-180' : ''
}`}
>
<NavArrowUp width={16} height={16} className="text-zinc-700" />
</div>
<h3 className="text-[11px] font-bold uppercase tracking-widest text-zinc-600">Chats</h3>
</Disclosure.Button>
<Disclosure.Panel>
<ChatList />
</Disclosure.Panel>
</div>
)}
</Disclosure>
);
}

View File

@@ -1,16 +0,0 @@
import Channels from '@components/navigation/channels';
import Chats from '@components/navigation/chats';
import Newsfeed from '@components/navigation/newsfeed';
export default function Navigation() {
return (
<div className="relative flex h-full flex-col gap-1 overflow-hidden pt-3">
{/* Newsfeed */}
<Newsfeed />
{/* Channels */}
<Channels />
{/* Chats */}
<Chats />
</div>
);
}

View File

@@ -1,43 +0,0 @@
import { ActiveLink } from '@components/activeLink';
import { Disclosure } from '@headlessui/react';
import { Bonfire, NavArrowUp, PeopleTag } from 'iconoir-react';
export default function Newsfeed() {
return (
<Disclosure>
{({ open }) => (
<div className="flex flex-col px-2">
<Disclosure.Button className="flex cursor-pointer items-center gap-1 px-1 py-1">
<div
className={`inline-flex h-5 w-5 transform items-center justify-center transition-transform duration-150 ease-in-out ${
open ? 'rotate-180' : ''
}`}
>
<NavArrowUp width={16} height={16} className="text-zinc-700" />
</div>
<h3 className="text-[11px] font-bold uppercase tracking-widest text-zinc-600">Newsfeed</h3>
</Disclosure.Button>
<Disclosure.Panel className="flex flex-col text-zinc-400">
<ActiveLink
href="/newsfeed/following"
className="flex h-8 items-center gap-2.5 rounded-md px-2.5 text-sm font-medium hover:text-zinc-200"
activeClassName="dark:bg-zinc-900 dark:text-zinc-100 hover:dark:bg-zinc-800"
>
<PeopleTag width={16} height={16} className="text-zinc-500" />
<span>Following</span>
</ActiveLink>
<ActiveLink
href="/newsfeed/circle"
className="flex h-8 items-center gap-2.5 rounded-md px-2.5 text-sm font-medium hover:text-zinc-200"
activeClassName="dark:bg-zinc-900 dark:text-zinc-100 hover:dark:bg-zinc-800"
>
<Bonfire width={16} height={16} className="text-zinc-500" />
<span>Circle</span>
</ActiveLink>
</Disclosure.Panel>
</div>
)}
</Disclosure>
);
}

View File

@@ -1,9 +1,7 @@
import { memo } from 'react';
export const ImagePreview = memo(function ImagePreview({ url, size }: { url: string; size: string }) {
export const ImagePreview = ({ url, size }: { url: string; size: string }) => {
return (
<div className={`relative h-full ${size === 'large' ? 'w-4/5' : 'w-1/2'} mt-2 rounded-lg border border-zinc-800`}>
<img src={url} alt={url} className="h-auto w-full rounded-lg object-cover" loading="lazy" fetchpriority="high" />
<img src={url} alt={url} className="h-auto w-full rounded-lg object-cover" loading="lazy" />
</div>
);
});
};

View File

@@ -1,17 +1,11 @@
import { memo } from 'react';
import ReactPlayer from 'react-player';
import { MediaOutlet, MediaPlayer } from '@vidstack/react';
export const VideoPreview = memo(function VideoPreview({ url }: { url: string }) {
export const VideoPreview = ({ url }: { url: string }) => {
return (
<div onClick={(e) => e.stopPropagation()} className="relative mt-2 flex flex-col overflow-hidden rounded-lg">
<ReactPlayer
url={url}
controls={true}
volume={0}
className="aspect-video w-full xl:w-2/3"
width="100%"
height="100%"
/>
<MediaPlayer src={url} poster="" controls>
<MediaOutlet />
</MediaPlayer>
</div>
);
});
};

View File

@@ -0,0 +1,16 @@
import YouTube from 'react-youtube';
function getVideoId(url: string) {
const regex = /(youtu.*be.*)\/(watch\?v=|embed\/|v|shorts|)(.*?((?=[&#?])|$))/gm;
return regex.exec(url)[3];
}
export const YoutubePreview = ({ url }: { url: string }) => {
const id = getVideoId(url);
return (
<div onClick={(e) => e.stopPropagation()} className="relative mt-2 flex flex-col overflow-hidden rounded-lg">
<YouTube videoId={id} className="aspect-video xl:w-2/3" opts={{ width: '100%', height: '100%' }} />
</div>
);
};