Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
bb7addb
feat: ai panel
DIYgod Jun 11, 2025
c99003c
feat: ai settings
DIYgod Jun 12, 2025
8adfed0
feat: ai entrances
DIYgod Jun 12, 2025
0411925
feat: shortcuts setting
DIYgod Jun 16, 2025
8aece45
refactor: rename ai dialogue
DIYgod Jun 16, 2025
ef76ce9
feat: merge dialogue input and shortcuts
DIYgod Jun 16, 2025
646bbbd
feat: textarea autoheight
DIYgod Jun 16, 2025
7d7ee12
feat: ai dialogue input auto shrink
DIYgod Jun 16, 2025
a7c615a
feat: ai dialogue
DIYgod Jun 16, 2025
eaaee4e
feat: ai icon
DIYgod Jun 17, 2025
4985763
feat: split text
DIYgod Jun 18, 2025
3627e1f
feat: mockDialogues
DIYgod Jun 18, 2025
a15a1de
feat: scrollable shortcuts
DIYgod Jun 18, 2025
8d0030c
Merge branch 'dev' into feature/ai
DIYgod Jun 18, 2025
3455a94
fix
DIYgod Jun 18, 2025
9ccb4cc
feat: use vercel ai
DIYgod Jun 19, 2025
c109d79
Merge remote-tracking branch 'origin/dev' into feature/ai
DIYgod Jun 19, 2025
c7103be
feat: rename
DIYgod Jun 19, 2025
3019cbc
feat: ai tool
DIYgod Jun 19, 2025
2d9cefd
Merge remote-tracking branch 'origin/dev' into feature/ai
DIYgod Jun 19, 2025
ed54a72
Merge remote-tracking branch 'origin/dev' into feature/ai
Innei Jun 20, 2025
8aedb55
refactor: update font settings and layout adjustments
Innei Jun 20, 2025
38ecbb8
refactor: reorganize dependencies and remove unused components
Innei Jun 20, 2025
7c60bcf
Merge remote-tracking branch 'origin/dev' into feature/ai
Innei Jun 20, 2025
996b687
feat: implement AI chat components and context management
Innei Jun 20, 2025
5a199ec
feat: add AIChat hotkey scope and integrate Focusable component
Innei Jun 20, 2025
7c6dadc
refactor: update AIChatInput and AIChatPanel components
Innei Jun 20, 2025
5024106
refactor: remove deprecated useGlobalFocusableScope hook and update T…
Innei Jun 20, 2025
5c70a83
feat: add SettingTextArea component and integrate into AI settings
Innei Jun 20, 2025
16be1a9
Merge remote-tracking branch 'origin/dev' into feature/ai
DIYgod Jun 26, 2025
4b986ac
fix: import path
DIYgod Jun 26, 2025
5c6d144
feat: optimzie ai displayFeeds
DIYgod Jun 26, 2025
aabd199
feat: enhance AIChatPanel with tooltips and improved suggestion display
Innei Jun 26, 2025
7969611
feat: integrate AIPanelRefsContext for improved reference management
Innei Jun 26, 2025
a85bc1e
feat: add EntryContentAccessories component for enhanced entry features
Innei Jun 26, 2025
e5eee6f
Merge remote-tracking branch 'origin/dev' into feature/ai
Innei Jun 30, 2025
2d12c96
refactor: update imports for useSettingModal and clean up unused comp…
Innei Jun 30, 2025
6605c20
feat(ai-chat): implement AI chat components including message input, …
Innei Jul 1, 2025
6453c71
feat(ai-chat): enhance chat functionality with auto-scroll and messag…
Innei Jul 1, 2025
3b52b2b
feat(ai-chat): add sending message animation and enhance chat input
Innei Jul 1, 2025
91e74d2
feat(ai-chat): improve chat input and message handling with enhanced …
Innei Jul 1, 2025
69b23a2
feat(ai-chat): enhance AI chat context management and input handling
Innei Jul 1, 2025
3960376
chore: hono update
Innei Jul 1, 2025
a748cd3
feat(ai-chat): enhance AI chat components with optional wrapping and …
Innei Jul 1, 2025
bd707f2
Merge remote-tracking branch 'origin/dev' into feature/ai
Innei Jul 2, 2025
4833175
Merge remote-tracking branch 'origin/dev' into feature/ai
Innei Jul 2, 2025
5671736
feat(ai-chat): implement AI chat context store and enhance input hand…
Innei Jul 2, 2025
36eacf4
feat(ai-chat): refactor message parts handling in AIChatMessage compo…
Innei Jul 2, 2025
5db539a
feat(diagrams): integrate Mermaid for diagram rendering in AI chat
Innei Jul 2, 2025
6fb0df1
Merge branch 'dev' into feature/ai
Innei Jul 2, 2025
54f0d6a
feat(ai-chat): enhance AI message rendering and introduce ToolInvocat…
Innei Jul 3, 2025
c0227f3
feat(ai-chat): integrate AIChatRoot and enhance auto-scroll functiona…
Innei Jul 3, 2025
03b5cad
feat(ai-chat): update AI SDK dependencies and enhance AI chat functio…
Innei Jul 3, 2025
e5d8df1
feat(layout): implement resizable panel functionality and improve lay…
Innei Jul 4, 2025
bbc4769
feat(ai-chat): update AI chat components and integrate new AI SDK fea…
Innei Jul 4, 2025
d0723e3
feat(ai-chat): integrate node polyfills and enhance chat functionality
Innei Jul 4, 2025
9bae7dd
Merge remote-tracking branch 'origin/dev' into feature/ai
Innei Jul 4, 2025
f2d0358
Merge remote-tracking branch 'origin/dev' into feature/ai
Innei Jul 7, 2025
59a6e49
chore: update pnpm-lock and package.json to include @splinetool/react…
Innei Jul 7, 2025
bc290a1
feat(ai): implement AI chat components and layout
Innei Jul 7, 2025
db695a3
feat(ai): enhance AI chat functionality and localization
Innei Jul 7, 2025
39af6c0
feat(ai): enhance AI settings with personalized prompts and shortcuts…
Innei Jul 7, 2025
1d7736c
feat(shortcuts): implement keyboard shortcut management and localization
Innei Jul 7, 2025
1a9b17f
Merge remote-tracking branch 'origin/dev' into feature/ai
Innei Jul 7, 2025
dcc43dc
Merge remote-tracking branch 'origin/dev' into feature/ai
Innei Jul 8, 2025
a52f4a9
feat: update ai robot model
DIYgod Jul 8, 2025
c8e13ce
Merge branch 'dev' into feature/ai
DIYgod Jul 8, 2025
b5aebbf
feat(ai): introduce new analytics and display components
Innei Jul 8, 2025
df737c8
refactor(ai): consolidate shared components for analytics displays
Innei Jul 8, 2025
4ebd70a
feat(ui): introduce GlassButton component and refactor modal actions
Innei Jul 8, 2025
9456268
refactor(ai): enhance auto-scroll functionality in chat component
Innei Jul 8, 2025
b479d07
Merge remote-tracking branch 'origin/dev' into feature/ai
Innei Jul 9, 2025
21671b2
feat: add class-variance-authority for GlassButton variants
Innei Jul 9, 2025
d8879b0
feat: enhance AI chat functionality and UI components
Innei Jul 9, 2025
6a4d695
refactor: update layout components and improve conditional rendering
Innei Jul 9, 2025
093dd81
feat: enhance AI chat features and session management
Innei Jul 9, 2025
b10dffe
refactor: update AI chat components and improve styling
Innei Jul 9, 2025
e5347f8
feat: implement chat title generation and error handling in AI chat c…
Innei Jul 9, 2025
21989d5
refactor: improve ChatHeader and ChatInterface components
Innei Jul 9, 2025
d23582f
refactor: update layout styling in AI chat components
Innei Jul 9, 2025
b3f37a1
Merge remote-tracking branch 'origin/dev' into feature/ai
Innei Jul 9, 2025
8275d77
refactor: enhance AI settings and chat components
Innei Jul 9, 2025
0349f94
refactor: enhance ChatInput component functionality
Innei Jul 9, 2025
f87c615
refactor: update layout styling in AI display components
Innei Jul 9, 2025
b7158ae
refactor: remove AIChatShortcuts component and enhance shortcut handling
Innei Jul 10, 2025
c02625b
refactor: implement CollapsibleError component for improved error dis…
Innei Jul 10, 2025
c43c395
refactor: re-organize AI components
Innei Jul 10, 2025
6d256cd
refactor: enhance dropdown menu layout and shortcut display
Innei Jul 10, 2025
f0fef16
refactor: remove unused AI components and update imports
Innei Jul 10, 2025
ab70612
refactor: remove AI spline asset and update loader URL
Innei Jul 10, 2025
99b9462
refactor: enhance WelcomeScreen with settings modal integration
Innei Jul 10, 2025
722b2f4
refactor: streamline session state management and enhance UI components
Innei Jul 10, 2025
0009b08
refactor: implement message editing functionality in chat interface
Innei Jul 10, 2025
5e42aa3
refactor: optimize AI chat components with memoization
Innei Jul 10, 2025
584dff2
refactor: update MermaidDiagram and ChatInput components
Innei Jul 10, 2025
dd9b29a
refactor: update GlassButton component and related usages
Innei Jul 11, 2025
1413ef2
refactor: enhance ToolInvocationComponent and WelcomeScreen
Innei Jul 11, 2025
75f4b84
Merge remote-tracking branch 'origin/dev' into feature/ai
Innei Jul 11, 2025
50c490d
feat: implement thinking indicator in AIMessageParts component
Innei Jul 11, 2025
bda61bc
feat: add RelatedEntryLink component for enhanced link handling in AI…
Innei Jul 11, 2025
d23b7ee
feat: update GlassButton styles and introduce EntryLayoutContent comp…
Innei Jul 11, 2025
51ce420
feat: integrate AI chat functionality and enhance toolbar interactions
Innei Jul 11, 2025
d6cdd2e
fix: update useEntryActions to streamline entry properties
Innei Jul 11, 2025
6cef244
Merge remote-tracking branch 'origin/dev' into feature/ai
Innei Jul 14, 2025
0ac7232
ci: update Claude workflow to enhance PR assistance functionality
Innei Jul 15, 2025
bafb6f8
refactor(shortcuts): remove unused shortcut settings component
Innei Jul 15, 2025
fb5514d
Merge branch 'dev' into feature/ai
DIYgod Jul 16, 2025
a6fcc31
Implement code changes to enhance functionality and improve performance
Innei Jul 16, 2025
1f57572
fix: types
DIYgod Jul 16, 2025
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
17 changes: 17 additions & 0 deletions .cursor/rules/i18n.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
description:
globs: locales/**/*.json
alwaysApply: false
---

i18n Coding Standards.

1. Read and follow https://www.i18next.com/translation-function/formatting

2. Use flat keys. Use `.` to separate. Do not use object form nesting.

3. For languages sensitive to singular and plural, distinguish between them using the `_one` and `_other` forms.

4. In the build stage, flattened dot-separated keys (such as 'exif.custom.rendered.custom') will be automatically converted to nested object objects, which may cause conflicts. For example, 'exif.custom.rendered.custom' may conflict with 'exif.custom.rendered'. Please avoid using such dot-separated flat keys.

5. @locales is located at the root directory and needs to handle all existing languages at the same time.
1 change: 1 addition & 0 deletions .cursorignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Add directories or file patterns to ignore during indexing (e.g. foo/ or *.csv)
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
* text=auto eol=lf
*.splinecode filter=lfs diff=lfs merge=lfs -text
6 changes: 6 additions & 0 deletions apps/desktop/layer/renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@ai-sdk/openai": "2.0.0-beta.5",
"@ai-sdk/react": "2.0.0-beta.11",
"@dnd-kit/core": "6.3.1",
"@dnd-kit/sortable": "10.0.0",
"@electron-toolkit/preload": "3.0.2",
Expand All @@ -37,6 +39,7 @@
"@radix-ui/react-slot": "1.2.3",
"@sentry/react": "9.35.0",
"@shikijs/transformers": "3.7.0",
"@splinetool/react-spline": "4.0.0",
"@tanstack/query-sync-storage-persister": "5.81.5",
"@tanstack/react-query": "5.81.5",
"@tanstack/react-query-devtools": "5.81.5",
Expand All @@ -45,7 +48,9 @@
"@use-gesture/react": "10.3.1",
"@welldone-software/why-did-you-render": "10.0.1",
"@yornaath/batshit": "0.10.1",
"ai": "5.0.0-beta.11",
"camelcase-keys": "9.1.3",
"class-variance-authority": "0.7.1",
"clsx": "2.1.1",
"cmdk": "1.1.1",
"cookie-es": "2.0.0",
Expand All @@ -69,6 +74,7 @@
"masonic": "4.1.0",
"mdast-util-gfm-table": "2.0.0",
"mdast-util-to-markdown": "2.1.2",
"mermaid": "11.7.0",
"motion": "12.23.0",
"nanoid": "5.1.5",
"ofetch": "1.4.1",
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/layer/renderer/src/@types/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ export const dayjsLocaleImportMap = {
["ja"]: ["ja", () => import("dayjs/locale/ja")],
["zh-TW"]: ["zh-tw", () => import("dayjs/locale/zh-tw")],
}
export const ns = ["common", "lang", "errors", "app", "settings", "shortcuts"] as const
export const ns = ["common", "lang", "errors", "app", "settings", "shortcuts", "ai"] as const
export const defaultNS = "app" as const
2 changes: 2 additions & 0 deletions apps/desktop/layer/renderer/src/@types/default-resource.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// DONT EDIT THIS FILE MANUALLY
import ai_en from "@locales/ai/en.json"
import en from "@locales/app/en.json"
import common_en from "@locales/common/en.json"
import common_ja from "@locales/common/ja.json"
Expand Down Expand Up @@ -29,6 +30,7 @@ export const defaultResources = {
settings: settings_en,
shortcuts: shortcuts_en,
errors: errors_en,
ai: ai_en,
},
"zh-CN": {
lang: lang_zhCN,
Expand Down
27 changes: 27 additions & 0 deletions apps/desktop/layer/renderer/src/atoms/settings/ai.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { createSettingAtom } from "@follow/atoms/helper/setting.js"
import { defaultAISettings } from "@follow/shared/settings/defaults"
import type { AISettings } from "@follow/shared/settings/interface"
import { jotaiStore } from "@follow/utils"
import { atom, useAtomValue } from "jotai"

export const createDefaultSettings = (): AISettings => defaultAISettings

export const {
useSettingKey: useAISettingKey,
useSettingSelector: useAISettingSelector,
setSetting: setAISetting,
clearSettings: clearAISettings,
initializeDefaultSettings: initializeDefaultAISettings,
getSettings: getAISettings,
useSettingValue: useAISettingValue,
settingAtom: __aiSettingAtom,
} = createSettingAtom("ai", createDefaultSettings)
export const aiServerSyncWhiteListKeys = []
// Local Setting for ai

const aiChatPinnedAtom = atom<boolean>(false)
export const useAIChatPinned = () => useAtomValue(aiChatPinnedAtom)
export const setAIChatPinned = (pinned: boolean) => {
jotaiStore.set(aiChatPinnedAtom, pinned)
}
export const getAIChatPinned = () => jotaiStore.get(aiChatPinnedAtom)
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { createElement, Suspense, useCallback } from "react"

import { getErrorFallback } from "../errors"
import type { ErrorComponentType } from "../errors/enum"
import PageErrorFallback from "../errors/PageError"

export interface AppErrorBoundaryProps extends PropsWithChildren {
height?: number | string
Expand Down Expand Up @@ -38,19 +39,15 @@ type ErrorFallbackProps = Parameters<FallbackRender>["0"]
export type AppErrorFallbackProps = ErrorFallbackProps & {}
const AppErrorBoundaryItem: FC<AppErrorBoundaryProps> = ({ errorType, children }) => {
const fallbackRender = useCallback(
(fallbackProps: ErrorFallbackProps) => (
<Suspense>{createElement(getErrorFallback(errorType), fallbackProps)}</Suspense>
),
(fallbackProps: ErrorFallbackProps) => {
const errorElement = getErrorFallback(errorType)
if (!errorElement) {
return <PageErrorFallback {...fallbackProps} />
}
return <Suspense>{createElement(getErrorFallback(errorType), fallbackProps)}</Suspense>
},
[errorType],
)

const onError = useCallback((error: unknown, componentStack?: string) => {
console.error("Uncaught error:", error, componentStack)
}, [])

return (
<ErrorBoundary fallback={fallbackRender} onError={onError}>
{children}
</ErrorBoundary>
)
return <ErrorBoundary fallback={fallbackRender}>{children}</ErrorBoundary>
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ export const FocusablePresets = {
},
isTimeline: (v) => v.has(HotkeyScope.Timeline) && !v.has(HotkeyScope.EntryRender),
isEntryRender: (v) => v.has(HotkeyScope.EntryRender),
isAIChat: (v) => v.has(HotkeyScope.AIChat),
} satisfies Record<string, (v: Set<string>) => boolean>
198 changes: 198 additions & 0 deletions apps/desktop/layer/renderer/src/components/ui/button/GlassButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import { Spring } from "@follow/components/constants/spring.js"
import {
Tooltip,
TooltipContent,
TooltipPortal,
TooltipTrigger,
} from "@follow/components/ui/tooltip/index.js"
import { cn } from "@follow/utils/utils"
import { cva } from "class-variance-authority"
import { m } from "motion/react"
import type { FC, ReactNode } from "react"

export interface GlassButtonProps {
description?: string
onClick: () => void
className?: string
children: ReactNode
/**
* Custom animation variants for hover and tap states
*/
hoverScale?: number
tapScale?: number
/**
* Size variant
*/
size?: "sm" | "md" | "lg"
/**
* Color theme
*/
theme?: "light" | "dark" | "auto"
/**
* Visual variant
*/
variant?: "glass" | "flat"
}

const glassButtonVariants = cva(
[
// Base styles - perfect 1:1 circle
"pointer-events-auto relative flex items-center justify-center rounded-full",
"transition-all duration-300 ease-out",
],
{
variants: {
size: {
sm: "size-8 text-sm",
md: "size-10 text-lg",
lg: "size-12 text-xl",
},
theme: {
light: ["text-gray-700 hover:text-gray-900"],
dark: ["text-white hover:text-white"],
auto: ["text-text hover:text-text-vibrant"],
},
variant: {
glass: ["backdrop-blur-md border shadow-lg"],
flat: ["border shadow-none"],
},
},
compoundVariants: [
// Glass variant themes
{
variant: "glass",
theme: "light",
className: [
"bg-material-thin hover:bg-material-medium",
"border-gray/30 hover:border-gray/40",
"shadow-gray/30",
],
},
{
variant: "glass",
theme: "dark",
className: [
"bg-material-ultra-thin hover:bg-material-thin",
"border-gray/10 hover:border-gray/20",
"shadow-black/25",
],
},
{
variant: "glass",
theme: "auto",
className: [
"bg-material-thin hover:bg-material-medium",
"border-gray/30 hover:border-gray/40",
"shadow-gray/30",
],
},
// Flat variant themes
{
variant: "flat",
theme: "light",
className: ["bg-white/80 hover:bg-white/90", "border-gray/20 hover:border-gray/30"],
},
{
variant: "flat",
theme: "dark",
className: [
"bg-fill-secondary hover:bg-fill-tertiary",
"border-gray/20 hover:border-gray/30",
],
},
{
variant: "flat",
theme: "auto",
className: [
"bg-white/80 hover:bg-white/90 dark:bg-fill-secondary dark:hover:bg-fill-tertiary",
"border-gray/20 hover:border-gray/30",
],
},
],
defaultVariants: {
size: "md",
theme: "auto",
variant: "glass",
},
},
)

const glassOverlayVariants = cva(
"absolute inset-0 rounded-full bg-gradient-to-t opacity-0 transition-opacity duration-300 hover:opacity-100",
{
variants: {
theme: {
light: "from-material-opaque/10 to-material-opaque/30",
dark: "from-material-opaque/5 to-material-opaque/20",
auto: "from-material-opaque/10 to-material-opaque/30",
},
},
defaultVariants: {
theme: "auto",
},
},
)

const glassInnerShadowVariants = cva("absolute inset-0 rounded-full shadow-inner", {
variants: {
theme: {
light: "shadow-gray/20",
dark: "shadow-black/10",
auto: "shadow-gray/20 dark:shadow-black/10",
},
},
defaultVariants: {
theme: "auto",
},
})

export const GlassButton: FC<GlassButtonProps> = ({
description,
onClick,
className,
children,
hoverScale = 1.1,
tapScale = 0.95,
size = "md",
theme = "auto",
variant = "glass",
}) => {
return (
<Tooltip>
<TooltipTrigger asChild>
<m.button
type="button"
onClick={(e) => {
e.stopPropagation()
onClick()
}}
className={cn(glassButtonVariants({ size, theme, variant }), className)}
initial={{ scale: 1 }}
whileHover={
variant === "flat"
? undefined
: {
scale: hoverScale,
}
}
whileTap={{ scale: tapScale }}
transition={Spring.presets.snappy}
>
{/* Glass effect overlay - only for glass variant */}
{variant === "glass" && <div className={glassOverlayVariants({ theme })} />}

{/* Icon container */}
<div className="center relative z-10 flex">{children}</div>

{/* Subtle inner shadow for depth - only for glass variant */}
{variant === "glass" && <div className={glassInnerShadowVariants({ theme })} />}
</m.button>
</TooltipTrigger>
{description && (
<TooltipPortal>
<TooltipContent>{description}</TooltipContent>
</TooltipPortal>
)}
</Tooltip>
)
}
Loading
Loading