Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 30 additions & 54 deletions components/animate-ui/components/code-tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,17 @@ import * as React from 'react';
import { useTheme } from 'next-themes';

import { cn } from '@/lib/utils';
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
TabsContents,
type TabsProps,
} from '@/components/animate-ui/components/tabs';
import { Tabs, TabsContent, TabsList, TabsTrigger, TabsContents, type TabsProps } from '@/components/animate-ui/components/tabs';
import { CopyButton } from '@/components/animate-ui/buttons/copy';

type CodeTabsProps = {
codes: Record<string, string>;
type CodeItem = {
name: string;
lang?: string;
code: string;
};

type CodeTabsProps = {
codes: CodeItem[];
themes?: {
light: string;
dark: string;
Expand All @@ -27,10 +25,9 @@ type CodeTabsProps = {

function CodeTabs({
codes,
lang = 'bash',
themes = {
light: 'github-light',
dark: 'github-dark',
dark: 'github-dark'
},
className,
defaultValue,
Expand All @@ -42,49 +39,46 @@ function CodeTabs({
}: CodeTabsProps) {
const { resolvedTheme } = useTheme();

const [highlightedCodes, setHighlightedCodes] = React.useState<Record<
string,
string
> | null>(null);
const [selectedCode, setSelectedCode] = React.useState<string>(
value ?? defaultValue ?? Object.keys(codes)[0] ?? '',
);
const [highlightedCodes, setHighlightedCodes] = React.useState<Record<string, string> | null>(null);
const [selectedCode, setSelectedCode] = React.useState<string>(value ?? defaultValue ?? codes[0]?.name ?? '');

React.useEffect(() => {
async function loadHighlightedCode() {
try {
const { codeToHtml } = await import('shiki');
const newHighlightedCodes: Record<string, string> = {};

for (const [command, val] of Object.entries(codes)) {
const highlighted = await codeToHtml(val, {
lang,
for (const codeItem of codes) {
const highlighted = await codeToHtml(codeItem.code, {
lang: codeItem.lang || codeItem.name.toLowerCase(),
themes: {
light: themes.light,
dark: themes.dark,
dark: themes.dark
},
defaultColor: resolvedTheme === 'dark' ? 'dark' : 'light',
defaultColor: resolvedTheme === 'dark' ? 'dark' : 'light'
});

newHighlightedCodes[command] = highlighted;
newHighlightedCodes[codeItem.name] = highlighted;
}

setHighlightedCodes(newHighlightedCodes);
} catch (error) {
console.error('Error highlighting codes', error);
setHighlightedCodes(codes);
// 降级处理:创建简单的文本映射
const fallbackCodes: Record<string, string> = {};
codes.forEach((item) => {
fallbackCodes[item.name] = item.code;
});
setHighlightedCodes(fallbackCodes);
}
}
loadHighlightedCode();
}, [resolvedTheme, lang, themes.light, themes.dark, codes]);
}, [resolvedTheme, themes.light, themes.dark, codes]);

return (
<Tabs
data-slot="install-tabs"
className={cn(
'w-full gap-0 bg-muted/50 rounded-xl border overflow-hidden',
className,
)}
className={cn('w-full gap-0 bg-muted/50 rounded-xl border overflow-hidden', className)}
{...props}
value={selectedCode}
onValueChange={(val) => {
Expand All @@ -100,44 +94,26 @@ function CodeTabs({
<div className="flex gap-x-3 h-full">
{highlightedCodes &&
Object.keys(highlightedCodes).map((code) => (
<TabsTrigger
key={code}
value={code}
className="text-muted-foreground data-[state=active]:text-current px-0"
>
<TabsTrigger key={code} value={code} className="text-muted-foreground data-[state=active]:text-current px-0">
{code}
</TabsTrigger>
))}
</div>

{copyButton && highlightedCodes && (
<CopyButton
content={codes[selectedCode]}
size="sm"
variant="ghost"
className="-me-2 bg-transparent hover:bg-black/5 dark:hover:bg-white/10"
onCopy={onCopy}
/>
<CopyButton content={codes.find((item) => item.name === selectedCode)?.code || ''} size="sm" variant="ghost" className="-me-2 bg-transparent hover:bg-black/5 dark:hover:bg-white/10" onCopy={onCopy} />
)}
</TabsList>
<TabsContents data-slot="install-tabs-contents">
{highlightedCodes &&
Object.entries(highlightedCodes).map(([code, val]) => (
<TabsContent
data-slot="install-tabs-content"
key={code}
className="w-full text-sm flex items-center p-4 overflow-auto"
value={code}
>
<div
className="[&>pre,_&_code]:!bg-transparent [&>pre,_&_code]:[background:transparent_!important] [&>pre,_&_code]:border-none [&_code]:!text-[13px]"
dangerouslySetInnerHTML={{ __html: val }}
/>
<TabsContent data-slot="install-tabs-content" key={code} className="w-full text-sm flex items-center p-4 overflow-auto" value={code}>
<div className="[&>pre,_&_code]:!bg-transparent [&>pre,_&_code]:[background:transparent_!important] [&>pre,_&_code]:border-none [&_code]:!text-[13px]" dangerouslySetInnerHTML={{ __html: val }} />
</TabsContent>
))}
</TabsContents>
</Tabs>
);
}

export { CodeTabs, type CodeTabsProps };
export { CodeTabs, type CodeTabsProps, type CodeItem };
36 changes: 26 additions & 10 deletions content/AI/Fuclaude/Fuclaude.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,21 @@ import { CodeTabs } from '@/components/animate-ui/components/code-tabs'
<br></br>

<CodeTabs
codes={{
Curl: `curl 'http://YOURDOMAIN/manage-api/auth/oauth_token' \\
codes={[
{
name: "Curl",
lang: "bash",
code: `curl 'http://YOURDOMAIN/manage-api/auth/oauth_token' \\
-H 'Content-Type: application/json' \\
-d '{
"session_key": SESSION_KEY,
"unique_name": UNIQUE_NAME
}'`,
Python: `import requests
}'`
},
{
name: "Python",
lang: "python",
code: `import requests

domain = 'YOURDOMAIN' # 替换为你的域名
session_key = 'SESSION_KEY' # 替换为你的 Session Token
Expand All @@ -65,8 +72,12 @@ response = requests.post(
'unique_name': unique_name
})

login_url = response.json().get('login_url')`,
Javascript: `const domain = 'YOURDOMAIN'; // 替换为你的域名
login_url = response.json().get('login_url')`
},
{
name: "Javascript",
lang: "javascript",
code: `const domain = 'YOURDOMAIN'; // 替换为你的域名
const sessionKey = 'SESSION_KEY'; // 替换为你的 Session Token
const uniqueName = 'UNIQUE_NAME'; // 替换为你的独一无二的名称

Expand All @@ -93,7 +104,8 @@ fetch(url, {
.catch(error => {
console.error('Error:', error);
});`
}}
}
]}
/>

## 部署使用
Expand All @@ -109,8 +121,11 @@ fetch(url, {
<br></br>

<CodeTabs
codes={{
'Docker-compose': `version: '3'
codes={[
{
name: "Docker-compose",
lang: "yaml",
code: `version: '3'
services:
fuclaude:
image: pengzhile/fuclaude
Expand All @@ -130,5 +145,6 @@ services:
- FUCLAUDE_SIGNUP_ENABLED=false # 启用或禁用用户注册(true/false)
- FUCLAUDE_SHOW_SESSION_KEY=false # 显示或隐藏会话密钥(true/false)
restart: unless-stopped`
}}
}
]}
/>
26 changes: 19 additions & 7 deletions content/AI/OAIFree/AccessToken.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,29 @@ import { CodeTabs } from '@/components/animate-ui/components/code-tabs'
<br></br>

<CodeTabs
codes={{
Curl: `curl -X POST "https://token.oaifree.com/api/auth/refresh" \\
-d "refresh_token=YOUR_REFRESH_TOKEN"`,
Python: `import json
codes={[
{
name: "Curl",
lang: "bash",
code: `curl -X POST "https://token.oaifree.com/api/auth/refresh" \\
-d "refresh_token=YOUR_REFRESH_TOKEN"`
},
{
name: "Python",
lang: "python",
code: `import json
import requests

response = requests.post(
'https://token.oaifree.com/api/auth/refresh',
data={'refresh_token': YOUR_REFRESH_TOKEN}
)
access_token = response.json().get('access_token')`,
Javascript: `const refreshToken = 'YOUR_REFRESH_TOKEN';
access_token = response.json().get('access_token')`
},
{
name: "Javascript",
lang: "javascript",
code: `const refreshToken = 'YOUR_REFRESH_TOKEN';

fetch('https://token.oaifree.com/api/auth/refresh', {
method: 'POST',
Expand All @@ -68,7 +79,8 @@ fetch('https://token.oaifree.com/api/auth/refresh', {
console.log(accessToken);
})
.catch(error => console.error('Error:', error));`
}}
}
]}
/>

<br></br>
Expand Down
26 changes: 19 additions & 7 deletions content/AI/OAIFree/Chat2APIOAIFree.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ API 调用方式与 OpenAI 官方完全一致,只需将 base_url 修改为 OAI
<br></br>

<CodeTabs
codes={{
Curl: `curl https://api.oaifree.com/v1 \\
codes={[
{
name: "Curl",
lang: "bash",
code: `curl https://api.oaifree.com/v1 \\
-H 'Content-Type: application/json' \\
-H 'Authorization: Bearer <access token>' \\ # 替换为你的 ACCESS TOKEN
-d '{
Expand All @@ -42,8 +45,12 @@ API 调用方式与 OpenAI 官方完全一致,只需将 base_url 修改为 OAI
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is a LLM?"}
]
}'`,
Python: `from openai import OpenAI
}'`
},
{
name: "Python",
lang: "python",
code: `from openai import OpenAI

client = OpenAI(
api_key='<access token>', # 替换为你的 ACCESS TOKEN
Expand All @@ -56,8 +63,12 @@ response = client.chat.completions.create(
{'role': 'system', 'content': 'You are a helpful assistant.'},
{'role': 'user', 'content': 'What is a LLM?'}
]
)`,
Javascript: `const response = await fetch('https://api.oaifree.com/v1', {
)`
},
{
name: "Javascript",
lang: "javascript",
code: `const response = await fetch('https://api.oaifree.com/v1', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Expand All @@ -71,5 +82,6 @@ response = client.chat.completions.create(
]
})
});`
}}
}
]}
/>
Loading