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

@ -17,6 +17,7 @@
"@headlessui/react": "^1.7.14",
"@supabase/supabase-js": "^2.21.0",
"@tauri-apps/api": "^1.2.0",
"@vidstack/react": "^0.4.5",
"dayjs": "^1.11.7",
"destr": "^1.2.2",
"iconoir-react": "^6.6.0",
@ -27,12 +28,13 @@
"react-dom": "^18.2.0",
"react-hook-form": "^7.43.9",
"react-loading-skeleton": "^3.2.1",
"react-player": "^2.12.0",
"react-string-replace": "^1.1.0",
"react-virtuoso": "^4.3.1",
"react-youtube": "^10.1.0",
"swr": "^2.1.4",
"tailwind-merge": "^1.12.0",
"tauri-plugin-sql-api": "github:tauri-apps/tauri-plugin-sql"
"tauri-plugin-sql-api": "github:tauri-apps/tauri-plugin-sql",
"vidstack": "^0.4.5"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.9",
@ -41,6 +43,7 @@
"@types/node": "^18.16.0",
"@types/react": "^18.0.38",
"@types/react-dom": "^18.0.11",
"@types/youtube-player": "^5.5.7",
"@typescript-eslint/eslint-plugin": "^5.59.0",
"@typescript-eslint/parser": "^5.59.0",
"@vitejs/plugin-react-swc": "^3.3.0",

View File

@ -10,6 +10,9 @@ dependencies:
'@tauri-apps/api':
specifier: ^1.2.0
version: 1.2.0
'@vidstack/react':
specifier: ^0.4.5
version: 0.4.5(@types/react@18.0.38)(maverick.js@0.33.1)(media-icons@0.4.2)(react@18.2.0)(vidstack@0.4.5)
dayjs:
specifier: ^1.11.7
version: 1.11.7
@ -40,15 +43,15 @@ dependencies:
react-loading-skeleton:
specifier: ^3.2.1
version: 3.2.1(react@18.2.0)
react-player:
specifier: ^2.12.0
version: 2.12.0(react@18.2.0)
react-string-replace:
specifier: ^1.1.0
version: 1.1.0
react-virtuoso:
specifier: ^4.3.1
version: 4.3.1(react-dom@18.2.0)(react@18.2.0)
react-youtube:
specifier: ^10.1.0
version: 10.1.0(react@18.2.0)
swr:
specifier: ^2.1.4
version: 2.1.4(react@18.2.0)
@ -58,6 +61,9 @@ dependencies:
tauri-plugin-sql-api:
specifier: github:tauri-apps/tauri-plugin-sql
version: github.com/tauri-apps/tauri-plugin-sql/62b21ef24303d80e9905f57b2b6d27efc8677c23
vidstack:
specifier: ^0.4.5
version: 0.4.5
devDependencies:
'@tailwindcss/typography':
@ -78,6 +84,9 @@ devDependencies:
'@types/react-dom':
specifier: ^18.0.11
version: 18.0.11
'@types/youtube-player':
specifier: ^5.5.7
version: 5.5.7
'@typescript-eslint/eslint-plugin':
specifier: ^5.59.0
version: 5.59.0(@typescript-eslint/parser@5.59.0)(eslint@8.39.0)(typescript@4.9.5)
@ -644,6 +653,11 @@ packages:
'@jridgewell/resolve-uri': 3.1.0
'@jridgewell/sourcemap-codec': 1.4.14
/@maverick-js/signals@5.9.3:
resolution:
{ integrity: sha512-rqaaetjcqQQXbloejGYyHqN6i+cf2Lp88nw8qx2s86CD0X+1Tl/dq+I53wFM6VK6cvm925fQLszGG24AMSWAaw== }
dev: false
/@noble/hashes@1.2.0:
resolution:
{ integrity: sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== }
@ -1065,7 +1079,6 @@ packages:
/@types/prop-types@15.7.5:
resolution:
{ integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== }
dev: true
/@types/react-dom@18.0.11:
resolution:
@ -1081,12 +1094,10 @@ packages:
'@types/prop-types': 15.7.5
'@types/scheduler': 0.16.3
csstype: 3.1.2
dev: true
/@types/scheduler@0.16.3:
resolution:
{ integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== }
dev: true
/@types/semver@7.3.13:
resolution:
@ -1100,6 +1111,11 @@ packages:
'@types/node': 18.16.0
dev: false
/@types/youtube-player@5.5.7:
resolution:
{ integrity: sha512-W8F4eoTIvzXeNrT3JroQPimZLXnlJA8smYygHZUKFPVoYwgs/OhJkA1VBhL3iSs57OQkuINqHlY4SmMT5wtnJg== }
dev: true
/@typescript-eslint/eslint-plugin@5.59.0(@typescript-eslint/parser@5.59.0)(eslint@8.39.0)(typescript@4.9.5):
resolution:
{ integrity: sha512-p0QgrEyrxAWBecR56gyn3wkG15TJdI//eetInP3zYRewDh0XS+DhB3VUAd3QqvziFsfaQIoIuZMxZRB7vXYaYw== }
@ -1238,6 +1254,24 @@ packages:
eslint-visitor-keys: 3.4.0
dev: true
/@vidstack/react@0.4.5(@types/react@18.0.38)(maverick.js@0.33.1)(media-icons@0.4.2)(react@18.2.0)(vidstack@0.4.5):
resolution:
{ integrity: sha512-spcim3+p1fMzkhHRKn5PS54YQjfThW5M3F2+R8tCT+wpsxbbCDa/TGdLBoIy2oC0LNziPkn0vlBWIZko9F5iig== }
engines: { node: '>=16' }
peerDependencies:
'@types/react': ^18.0.0
maverick.js: 0.33.1
media-icons: ^0.4.2
react: ^18.0.0
vidstack: 0.4.5
dependencies:
'@types/react': 18.0.38
maverick.js: 0.33.1
media-icons: 0.4.2
react: 18.2.0
vidstack: 0.4.5
dev: false
/@vitejs/plugin-react-swc@3.3.0(vite@4.3.1):
resolution:
{ integrity: sha512-Ycg+n2eyCOTpn/wRy+evVo859+hw7qCj9iaX5CMny6x1fx1Uoq0xBG+a98lFtwLNGfGEnpI0F26YigRuxCRkwg== }
@ -1669,7 +1703,6 @@ packages:
/csstype@3.1.2:
resolution:
{ integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== }
dev: true
/d@1.0.1:
resolution:
@ -1714,12 +1747,6 @@ packages:
{ integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== }
dev: true
/deepmerge@4.3.1:
resolution:
{ integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== }
engines: { node: '>=0.10.0' }
dev: false
/define-properties@1.2.0:
resolution:
{ integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== }
@ -2142,7 +2169,6 @@ packages:
/fast-deep-equal@3.1.3:
resolution:
{ integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== }
dev: true
/fast-glob@3.2.12:
resolution:
@ -2883,9 +2909,25 @@ packages:
yallist: 4.0.0
dev: true
/memoize-one@5.2.1:
/maverick.js@0.33.1:
resolution:
{ integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== }
{ integrity: sha512-p8L5V62CV6TmHAngmRAopp231oJKeH77mJja5SsKOfvzrPRoThT/Jo9U0jMRB5iMykqkvyg2J5V5Agn6FPXDWQ== }
engines: { node: '>=16' }
dependencies:
'@maverick-js/signals': 5.9.3
type-fest: 3.8.0
dev: false
/media-captions@0.0.8:
resolution:
{ integrity: sha512-gX6ozU5smrAb90FwI+wd1VnqkwcAQ2NF8l72KZ67k+o3Vr0wYBAsTFRfdOePqde9IBhfBZbZsYEA5509npwtZA== }
engines: { node: '>=16' }
dev: false
/media-icons@0.4.2:
resolution:
{ integrity: sha512-jrxoQzxsZFyzt6P3CoGZWa6FVKoR/Ii1plbVjtyTSyQGpeVWkJ++0oBAwGOv/F9mWRxmGkaQ04uEIKTFouRG1w== }
engines: { node: '>=16' }
dev: false
/merge-stream@2.0.0:
@ -3438,11 +3480,6 @@ packages:
scheduler: 0.23.0
dev: false
/react-fast-compare@3.2.1:
resolution:
{ integrity: sha512-xTYf9zFim2pEif/Fw16dBiXpe0hoy5PxcD8+OwBnTtNLfIm3g6WxhKNurY+6OmdH1u6Ta/W/Vl6vjbYP1MFnDg== }
dev: false
/react-hook-form@7.43.9(react@18.2.0):
resolution:
{ integrity: sha512-AUDN3Pz2NSeoxQ7Hs6OhQhDr6gtF9YRuutGDwPQqhSUAHJSgGl2VeY3qN19MG0SucpjgDiuMJ4iC5T5uB+eaNQ== }
@ -3466,20 +3503,6 @@ packages:
react: 18.2.0
dev: false
/react-player@2.12.0(react@18.2.0):
resolution:
{ integrity: sha512-rymLRz/2GJJD+Wc01S7S+i9pGMFYnNmQibR2gVE3KmHJCBNN8BhPAlOPTGZtn1uKpJ6p4RPLlzPQ1OLreXd8gw== }
peerDependencies:
react: '>=16.6.0'
dependencies:
deepmerge: 4.3.1
load-script: 1.0.0
memoize-one: 5.2.1
prop-types: 15.8.1
react: 18.2.0
react-fast-compare: 3.2.1
dev: false
/react-string-replace@1.1.0:
resolution:
{ integrity: sha512-N6RalSDFGbOHs0IJi1H611WbZsvk3ZT47Jl2JEXFbiS3kTwsdCYij70Keo/tWtLy7sfhDsYm7CwNM/WmjXIaMw== }
@ -3498,6 +3521,21 @@ packages:
react-dom: 18.2.0(react@18.2.0)
dev: false
/react-youtube@10.1.0(react@18.2.0):
resolution:
{ integrity: sha512-ZfGtcVpk0SSZtWCSTYOQKhfx5/1cfyEW1JN/mugGNfAxT3rmVJeMbGpA9+e78yG21ls5nc/5uZJETE3cm3knBg== }
engines: { node: '>= 14.x' }
peerDependencies:
react: '>=0.14.1'
dependencies:
fast-deep-equal: 3.1.3
prop-types: 15.8.1
react: 18.2.0
youtube-player: 5.5.2
transitivePeerDependencies:
- supports-color
dev: false
/react@18.2.0:
resolution:
{ integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== }
@ -3687,6 +3725,11 @@ packages:
totalist: 3.0.1
dev: true
/sister@3.0.2:
resolution:
{ integrity: sha512-p19rtTs+NksBRKW9qn0UhZ8/TUI9BPw9lmtHny+Y3TinWlOa9jWh9xB0AtPSdmOy49NJJJSSe0Ey4C7h0TrcYA== }
dev: false
/slash@3.0.0:
resolution:
{ integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== }
@ -4028,6 +4071,12 @@ packages:
engines: { node: '>=10' }
dev: true
/type-fest@3.8.0:
resolution:
{ integrity: sha512-FVNSzGQz9Th+/9R6Lvv7WIAkstylfHN2/JYxkyhhmKFYh9At2DST8t6L6Lref9eYO8PXFTfG9Sg1Agg0K3vq3Q== }
engines: { node: '>=14.16' }
dev: false
/type@1.2.0:
resolution:
{ integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== }
@ -4119,6 +4168,17 @@ packages:
hasBin: true
dev: true
/vidstack@0.4.5:
resolution:
{ integrity: sha512-6CFkWRSvDQAd91WQ6PZ/ovwbGFDI8pLuIA0swcDLLAOM6MiKWFd/gFjJ/x7+DAcCf0hqOngO34MJhG3zTZQtcQ== }
engines: { node: '>=16' }
dependencies:
maverick.js: 0.33.1
media-captions: 0.0.8
media-icons: 0.4.2
type-fest: 3.8.0
dev: false
/vite-plugin-ssr@0.4.116(vite@4.3.1):
resolution:
{ integrity: sha512-GtXvlUtwnLdrnfuodJhcs+kV1BXyoUhECjqdoC1pSU+7dRKyU7A9V6NmkT7yPbHu1s8bWSgqC/EP91F4DSt4rA== }
@ -4345,6 +4405,17 @@ packages:
engines: { node: '>=10' }
dev: true
/youtube-player@5.5.2:
resolution:
{ integrity: sha512-ZGtsemSpXnDky2AUYWgxjaopgB+shFHgXVpiJFeNB5nWEugpW1KWYDaHKuLqh2b67r24GtP6HoSW5swvf0fFIQ== }
dependencies:
debug: 2.6.9
load-script: 1.0.0
sister: 3.0.2
transitivePeerDependencies:
- supports-color
dev: false
github.com/tauri-apps/tauri-plugin-sql/62b21ef24303d80e9905f57b2b6d27efc8677c23:
resolution:
{

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>
);
};

View File

@ -3,6 +3,7 @@ import { Shell } from '@renderer/shell';
import { PageContextClient } from '@renderer/types';
import { Root, createRoot, hydrateRoot } from 'react-dom/client';
import 'vidstack/styles/defaults.css';
export const clientRouting = true;
let root: Root;

View File

@ -1,12 +1,13 @@
import { ImagePreview } from '@components/note/preview/image';
import { VideoPreview } from '@components/note/preview/video';
import { YoutubePreview } from '@components/note/preview/youtube';
import { NoteQuote } from '@components/note/quote';
import { UserMention } from '@components/user/mention';
import destr from 'destr';
import reactStringReplace from 'react-string-replace';
export const contentParser = (noteContent, noteTags) => {
export const contentParser = (noteContent: any, noteTags: any) => {
let parsedContent = noteContent.trim();
// get data tags
@ -16,9 +17,9 @@ export const contentParser = (noteContent, noteTags) => {
if (match.match(/\.(jpg|jpeg|gif|png|webp)$/i)) {
// image url
return <ImagePreview key={match + i} url={match} size="large" />;
} else if (match.match(/(www\.)?(youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9_-]{11})/i)) {
} else if (match.match(/(http:|https:)?(\/\/)?(www\.)?(youtube.com|youtu.be)\/(watch|embed)?(\?v=|\/)?(\S+)?/)) {
// youtube
return <VideoPreview key={match + i} url={match} />;
return <YoutubePreview key={match + i} url={match} />;
} else if (match.match(/\.(mp4|webm)$/i)) {
// video
return <VideoPreview key={match + i} url={match} />;
@ -54,7 +55,7 @@ export const contentParser = (noteContent, noteTags) => {
return parsedContent;
};
export const messageParser = (noteContent) => {
export const messageParser = (noteContent: any) => {
let parsedContent = noteContent.trim();
// handle urls
@ -62,9 +63,9 @@ export const messageParser = (noteContent) => {
if (match.match(/\.(jpg|jpeg|gif|png|webp)$/i)) {
// image url
return <ImagePreview key={match + i} url={match} size="small" />;
} else if (match.match(/(www\.)?(youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9_-]{11})/i)) {
} else if (match.match(/(http:|https:)?(\/\/)?(www\.)?(youtube.com|youtu.be)\/(watch|embed)?(\?v=|\/)?(\S+)?/)) {
// youtube
return <VideoPreview key={match + i} url={match} />;
return <YoutubePreview key={match + i} url={match} />;
} else if (match.match(/\.(mp4|webm)$/i)) {
// video
return <VideoPreview key={match + i} url={match} />;

View File

@ -9,6 +9,7 @@
"@assets/*": ["src/assets/*"],
"@renderer/*": ["src/renderer/*"]
},
"types": ["vidstack/globals"],
"target": "es2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
@ -23,11 +24,6 @@
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"plugins": [
{
"name": "next"
}
],
"strictNullChecks": false
},
"include": ["global.d.ts", "**/*.ts", "**/*.tsx"],