mirror of
https://github.com/lumehq/lume.git
synced 2025-03-18 05:41:53 +01:00
update preview components
This commit is contained in:
parent
188c052a1a
commit
f0d0e79e3d
@ -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",
|
||||
|
141
pnpm-lock.yaml
generated
141
pnpm-lock.yaml
generated
@ -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:
|
||||
{
|
||||
|
92
src/components/navigation.tsx
Normal file
92
src/components/navigation.tsx
Normal 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>
|
||||
);
|
||||
}
|
@ -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>
|
||||
);
|
||||
}
|
@ -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>
|
||||
);
|
||||
}
|
@ -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>
|
||||
);
|
||||
}
|
@ -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>
|
||||
);
|
||||
}
|
@ -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>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
@ -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>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
16
src/components/note/preview/youtube.tsx
Normal file
16
src/components/note/preview/youtube.tsx
Normal 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>
|
||||
);
|
||||
};
|
@ -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;
|
||||
|
@ -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} />;
|
||||
|
@ -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"],
|
||||
|
Loading…
x
Reference in New Issue
Block a user