mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-09-01 17:10:24 +08:00
Compare commits
13 Commits
fix/electr
...
pr-657-upd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43161977a5 | ||
|
|
f09d2c100a | ||
|
|
03e2d9da9d | ||
|
|
bd1e5cc237 | ||
|
|
edc10803e4 | ||
|
|
b074cee95c | ||
|
|
121b6fc99f | ||
|
|
0e1bed39a4 | ||
|
|
d5e2885623 | ||
|
|
7662b00bb3 | ||
|
|
8a93d4ea9f | ||
|
|
add9111c82 | ||
|
|
1c1c6a4d38 |
@@ -1,7 +1,7 @@
|
|||||||
import type { Metadata } from "next"
|
import type { Metadata } from "next"
|
||||||
import Image from "next/image"
|
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
import { FaGithub } from "react-icons/fa"
|
import { FaGithub } from "react-icons/fa"
|
||||||
|
import Image from "@/components/image-with-basepath"
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "关于 - Next AI Draw.io",
|
title: "关于 - Next AI Draw.io",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { Metadata } from "next"
|
import type { Metadata } from "next"
|
||||||
import Image from "next/image"
|
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
import { FaGithub } from "react-icons/fa"
|
import { FaGithub } from "react-icons/fa"
|
||||||
|
import Image from "@/components/image-with-basepath"
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "概要 - Next AI Draw.io",
|
title: "概要 - Next AI Draw.io",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { Metadata } from "next"
|
import type { Metadata } from "next"
|
||||||
import Image from "next/image"
|
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
import { FaGithub } from "react-icons/fa"
|
import { FaGithub } from "react-icons/fa"
|
||||||
|
import Image from "@/components/image-with-basepath"
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "About - Next AI Draw.io",
|
title: "About - Next AI Draw.io",
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import {
|
|||||||
ThumbsUp,
|
ThumbsUp,
|
||||||
X,
|
X,
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
import Image from "next/image"
|
|
||||||
import type { MutableRefObject } from "react"
|
import type { MutableRefObject } from "react"
|
||||||
import { useCallback, useEffect, useRef, useState } from "react"
|
import { useCallback, useEffect, useRef, useState } from "react"
|
||||||
import ReactMarkdown from "react-markdown"
|
import ReactMarkdown from "react-markdown"
|
||||||
@@ -31,6 +30,7 @@ import { ToolCallCard } from "@/components/chat/ToolCallCard"
|
|||||||
import type { DiagramOperation, ToolPartLike } from "@/components/chat/types"
|
import type { DiagramOperation, ToolPartLike } from "@/components/chat/types"
|
||||||
import type { ValidationState } from "@/components/chat/ValidationCard"
|
import type { ValidationState } from "@/components/chat/ValidationCard"
|
||||||
import { ValidationCard } from "@/components/chat/ValidationCard"
|
import { ValidationCard } from "@/components/chat/ValidationCard"
|
||||||
|
import Image from "@/components/image-with-basepath"
|
||||||
import { ScrollArea } from "@/components/ui/scroll-area"
|
import { ScrollArea } from "@/components/ui/scroll-area"
|
||||||
import { useDictionary } from "@/hooks/use-dictionary"
|
import { useDictionary } from "@/hooks/use-dictionary"
|
||||||
import { getApiEndpoint } from "@/lib/base-path"
|
import { getApiEndpoint } from "@/lib/base-path"
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ import {
|
|||||||
PanelRightOpen,
|
PanelRightOpen,
|
||||||
Settings,
|
Settings,
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
import Image from "next/image"
|
import { usePathname, useRouter, useSearchParams } from "next/navigation"
|
||||||
import { useRouter, useSearchParams } from "next/navigation"
|
|
||||||
import type React from "react"
|
import type React from "react"
|
||||||
import {
|
import {
|
||||||
useCallback,
|
useCallback,
|
||||||
@@ -22,6 +21,7 @@ import { flushSync } from "react-dom"
|
|||||||
import { Toaster, toast } from "sonner"
|
import { Toaster, toast } from "sonner"
|
||||||
import { ButtonWithTooltip } from "@/components/button-with-tooltip"
|
import { ButtonWithTooltip } from "@/components/button-with-tooltip"
|
||||||
import { ChatInput } from "@/components/chat-input"
|
import { ChatInput } from "@/components/chat-input"
|
||||||
|
import Image from "@/components/image-with-basepath"
|
||||||
import { ModelConfigDialog } from "@/components/model-config-dialog"
|
import { ModelConfigDialog } from "@/components/model-config-dialog"
|
||||||
import { SettingsDialog } from "@/components/settings-dialog"
|
import { SettingsDialog } from "@/components/settings-dialog"
|
||||||
import { useDiagram } from "@/contexts/diagram-context"
|
import { useDiagram } from "@/contexts/diagram-context"
|
||||||
@@ -131,6 +131,7 @@ export default function ChatPanel({
|
|||||||
|
|
||||||
const dict = useDictionary()
|
const dict = useDictionary()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const pathname = usePathname()
|
||||||
const searchParams = useSearchParams()
|
const searchParams = useSearchParams()
|
||||||
const urlSessionId = searchParams.get("session")
|
const urlSessionId = searchParams.get("session")
|
||||||
|
|
||||||
@@ -901,10 +902,10 @@ export default function ChatPanel({
|
|||||||
if (result.wasCurrentSession) {
|
if (result.wasCurrentSession) {
|
||||||
// Deleted current session - clear UI and URL
|
// Deleted current session - clear UI and URL
|
||||||
syncUIWithSession(null)
|
syncUIWithSession(null)
|
||||||
router.replace(window.location.pathname, { scroll: false })
|
router.replace(pathname, { scroll: false })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[sessionManager, syncUIWithSession, router],
|
[sessionManager, syncUIWithSession, router, pathname],
|
||||||
)
|
)
|
||||||
|
|
||||||
const handleNewChat = useCallback(async () => {
|
const handleNewChat = useCallback(async () => {
|
||||||
@@ -937,7 +938,7 @@ export default function ChatPanel({
|
|||||||
toast.success(dict.dialogs.clearSuccess)
|
toast.success(dict.dialogs.clearSuccess)
|
||||||
|
|
||||||
// Clear URL param to show blank state
|
// Clear URL param to show blank state
|
||||||
router.replace(window.location.pathname, { scroll: false })
|
router.replace(pathname, { scroll: false })
|
||||||
|
|
||||||
// After starting a fresh chat, move focus back to the chat input
|
// After starting a fresh chat, move focus back to the chat input
|
||||||
setShouldFocusInput(true)
|
setShouldFocusInput(true)
|
||||||
@@ -952,6 +953,7 @@ export default function ChatPanel({
|
|||||||
dict.dialogs.clearSuccess,
|
dict.dialogs.clearSuccess,
|
||||||
buildSessionData,
|
buildSessionData,
|
||||||
setDiagramHistory,
|
setDiagramHistory,
|
||||||
|
pathname,
|
||||||
])
|
])
|
||||||
|
|
||||||
const handleInputChange = (
|
const handleInputChange = (
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import {
|
|||||||
Trash2,
|
Trash2,
|
||||||
X,
|
X,
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
import Image from "next/image"
|
|
||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
import ExamplePanel from "@/components/chat-example-panel"
|
import ExamplePanel from "@/components/chat-example-panel"
|
||||||
|
import Image from "@/components/image-with-basepath"
|
||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
AlertDialogAction,
|
AlertDialogAction,
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import {
|
|||||||
RefreshCw,
|
RefreshCw,
|
||||||
X,
|
X,
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
import Image from "next/image"
|
|
||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
|
import Image from "@/components/image-with-basepath"
|
||||||
import { useDictionary } from "@/hooks/use-dictionary"
|
import { useDictionary } from "@/hooks/use-dictionary"
|
||||||
import type { ValidationResult } from "@/lib/diagram-validator"
|
import type { ValidationResult } from "@/lib/diagram-validator"
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { FileCode, FileText, Link, Loader2, X } from "lucide-react"
|
import { FileCode, FileText, Link, Loader2, X } from "lucide-react"
|
||||||
import Image from "next/image"
|
|
||||||
import { useEffect, useRef, useState } from "react"
|
import { useEffect, useRef, useState } from "react"
|
||||||
|
import Image from "@/components/image-with-basepath"
|
||||||
import { useDictionary } from "@/hooks/use-dictionary"
|
import { useDictionary } from "@/hooks/use-dictionary"
|
||||||
import { isPdfFile, isTextFile } from "@/lib/pdf-utils"
|
import { isPdfFile, isTextFile } from "@/lib/pdf-utils"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import Image from "next/image"
|
|
||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
|
import Image from "@/components/image-with-basepath"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
|
|||||||
16
components/image-with-basepath.tsx
Normal file
16
components/image-with-basepath.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import NextImage, { type ImageProps } from "next/image"
|
||||||
|
import { forwardRef } from "react"
|
||||||
|
import { getAssetUrl } from "@/lib/base-path"
|
||||||
|
|
||||||
|
export default forwardRef<HTMLImageElement, ImageProps>(
|
||||||
|
function Image(props, ref) {
|
||||||
|
const src =
|
||||||
|
typeof props.src === "string" &&
|
||||||
|
props.src.startsWith("/") &&
|
||||||
|
!props.src.startsWith("//")
|
||||||
|
? getAssetUrl(props.src)
|
||||||
|
: props.src
|
||||||
|
|
||||||
|
return <NextImage {...props} src={src} ref={ref} />
|
||||||
|
},
|
||||||
|
)
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useCallback, useEffect, useState } from "react"
|
import { useCallback, useEffect, useState } from "react"
|
||||||
|
import { getApiEndpoint } from "@/lib/base-path"
|
||||||
import type { FlattenedServerModel } from "@/lib/server-model-config"
|
import type { FlattenedServerModel } from "@/lib/server-model-config"
|
||||||
import { STORAGE_KEYS } from "@/lib/storage"
|
import { STORAGE_KEYS } from "@/lib/storage"
|
||||||
import {
|
import {
|
||||||
@@ -147,7 +148,7 @@ export function useModelConfig(): UseModelConfigReturn {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof window === "undefined") return
|
if (typeof window === "undefined") return
|
||||||
|
|
||||||
fetch("/api/server-models")
|
fetch(getApiEndpoint("/api/server-models"))
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
console.error(
|
console.error(
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
import { getApiEndpoint } from "@/lib/base-path"
|
||||||
|
|
||||||
export interface UrlData {
|
export interface UrlData {
|
||||||
url: string
|
url: string
|
||||||
@@ -15,7 +16,7 @@ const UrlResponseSchema = z.object({
|
|||||||
})
|
})
|
||||||
|
|
||||||
export async function extractUrlContent(url: string): Promise<UrlData> {
|
export async function extractUrlContent(url: string): Promise<UrlData> {
|
||||||
const response = await fetch("/api/parse-url", {
|
const response = await fetch(getApiEndpoint("/api/parse-url"), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ url }),
|
body: JSON.stringify({ url }),
|
||||||
|
|||||||
Reference in New Issue
Block a user