chore: add CONTRIBUTING.md for project guidelines and enhance README with author follow section

This commit is contained in:
Nexmoe
2025-10-24 19:22:37 +08:00
parent 8ad41eebe2
commit 4dfac6bb34
18 changed files with 808 additions and 580 deletions

View File

@@ -49,7 +49,7 @@ function AppContent() {
</ScrollArea>
</main>
<Toaster />
<Toaster richColors={true} />
</div>
)
}

View File

@@ -7,6 +7,7 @@ import { useSetAtom } from 'jotai'
import {
AlertCircle,
CheckCircle2,
Copy,
ExternalLink,
FolderOpen,
Loader2,
@@ -110,6 +111,25 @@ export function DownloadItem({ download }: DownloadItemProps) {
await handleOpenFileLocation()
}
const handleCopyToClipboard = async () => {
if (!download.outputPath) {
toast.error(t('notifications.copyFailed'))
return
}
try {
const success = await ipcServices.fs.copyFileToClipboard(download.outputPath)
if (!success) {
toast.error(t('notifications.copyFailed'))
return
}
toast.success(t('notifications.videoCopied'))
} catch (error) {
console.error('Failed to copy file to clipboard:', error)
toast.error(t('notifications.copyFailed'))
}
}
const handleRemoveHistory = async () => {
if (!isHistory) return
try {
@@ -166,11 +186,11 @@ export function DownloadItem({ download }: DownloadItemProps) {
<div className="group relative w-full max-w-full overflow-hidden">
<div className="flex w-full flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-start sm:gap-4">
{/* Thumbnail */}
<div className="shrink-0 overflow-hidden rounded-md border border-border/60 bg-background/60">
<div className="shrink-0 overflow-hidden rounded-md border border-border/60 bg-background/60 w-32 h-20">
<ImageWithPlaceholder
src={thumbnailSrc}
alt={download.title}
className="w-32 h-18 object-cover aspect-video"
className="w-full h-full object-cover"
fallbackIcon={<Play className="h-6 w-6" />}
/>
</div>
@@ -179,18 +199,11 @@ export function DownloadItem({ download }: DownloadItemProps) {
<div className="flex-1 min-w-0 max-w-full space-y-3 overflow-hidden">
<div className="flex w-full flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-start sm:justify-between sm:gap-4">
<div className="flex-1 min-w-0 max-w-full space-y-2 overflow-hidden">
<Tooltip>
<TooltipTrigger asChild>
<div className="w-full min-w-0 overflow-hidden">
<p className="w-full wrap-break-word text-sm font-medium sm:text-base line-clamp-2">
{download.title}
</p>
</div>
</TooltipTrigger>
<TooltipContent>
<p className="max-w-xs wrap-break-word">{download.title}</p>
</TooltipContent>
</Tooltip>
<div className="w-full min-w-0 overflow-hidden">
<p className="w-full wrap-break-word text-sm font-medium sm:text-base line-clamp-2">
{download.title}
</p>
</div>
<div className="flex w-full flex-wrap items-center gap-2 text-xs text-muted-foreground">
<Badge variant="outline" className="bg-muted/50 capitalize text-[11px] font-medium">
{download.type}
@@ -285,13 +298,13 @@ export function DownloadItem({ download }: DownloadItemProps) {
variant="ghost"
size="icon"
className="h-8 w-8 shrink-0"
onClick={handleOpenFile}
onClick={handleCopyToClipboard}
>
<ExternalLink className="h-4 w-4" />
<Copy className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>{t('history.openFile')}</p>
<p>{t('history.copyToClipboard')}</p>
</TooltipContent>
</Tooltip>
<Tooltip>
@@ -346,6 +359,21 @@ export function DownloadItem({ download }: DownloadItemProps) {
<p>{t('history.openFile')}</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 shrink-0"
onClick={handleCopyToClipboard}
>
<Copy className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>{t('history.copyToClipboard')}</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button

View File

@@ -44,7 +44,7 @@ export function ImageWithPlaceholder({
}
return (
<div className={cn('relative', className)}>
<div className={cn('relative w-full h-full', className)}>
{isLoading && (
<div
className={cn(

View File

@@ -48,6 +48,12 @@
"shareSupport": "Recommend VidBee to your friends to support our growth and updates.",
"shareTitle": "Spread the word",
"shareDescription": "Share VidBee with your community in one click.",
"followAuthorActions": {
"follow": "Follow @nexmoex"
},
"followAuthorDescription": "Stay updated with the latest VidBee news and updates.",
"followAuthorSupport": "Follow the developer on X (Twitter) to get the latest updates and news about VidBee.",
"followAuthorTitle": "Follow the Developer",
"shareActions": {
"twitter": "Share on X (Twitter)",
"facebook": "Share on Facebook",
@@ -175,6 +181,7 @@
"noHistory": "No download history yet",
"noHistoryDescription": "Your completed downloads will appear here",
"openFile": "Open File",
"copyToClipboard": "Copy to clipboard",
"openFileLocation": "Open File Location",
"openFolder": "Open Folder",
"openDownloadFolder": "Open Download Folder",
@@ -203,6 +210,7 @@
},
"notifications": {
"copyFailed": "Failed to copy to clipboard",
"videoCopied": "Video copied to clipboard",
"downloadCompleted": "Download completed",
"downloadFailed": "Download failed",
"downloadStarted": "Download started",

View File

@@ -43,6 +43,12 @@
"website": "官方网站",
"websiteDescription": "产品亮点、路线图与社区动态。"
},
"followAuthorActions": {
"follow": "关注 @nexmoex"
},
"followAuthorDescription": "获取 VidBee 的最新消息和更新。",
"followAuthorSupport": "在 X (Twitter) 上关注开发者,获取 VidBee 的最新更新和消息。",
"followAuthorTitle": "关注开发者",
"resourcesDescription": "了解 VidBee 并保持关注的实用链接。",
"resourcesTitle": "资源",
"sourceCode": "源代码已开放",

View File

@@ -213,6 +213,29 @@ export function About() {
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>{t('about.followAuthorTitle')}</CardTitle>
<CardDescription>{t('about.followAuthorDescription')}</CardDescription>
</CardHeader>
<CardContent className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
<p className="text-sm text-muted-foreground md:max-w-md">
{t('about.followAuthorSupport')}
</p>
<div className="flex flex-wrap gap-2">
<Button
variant="outline"
size="sm"
onClick={() => openShareUrl('https://x.com/nexmoex')}
className="gap-2"
>
<Twitter className="h-4 w-4" />
{t('about.followAuthorActions.follow')}
</Button>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>{t('about.shareTitle')}</CardTitle>