feat: make summarize timeline shortcut undeletable
This commit is contained in:
parent
2607e2042b
commit
5f4e47da07
|
|
@ -1,5 +1,11 @@
|
|||
import { Button } from "@follow/components/ui/button/index.js"
|
||||
import {
|
||||
DEFAULT_SUMMARIZE_TIMELINE_PROMPT,
|
||||
DEFAULT_SUMMARIZE_TIMELINE_SHORTCUT_ID,
|
||||
defaultAISettings,
|
||||
} from "@follow/shared/settings/defaults"
|
||||
import type { AIShortcut } from "@follow/shared/settings/interface"
|
||||
import { useEffect } from "react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { toast } from "sonner"
|
||||
|
||||
|
|
@ -14,6 +20,22 @@ export const AIShortcutsSection = () => {
|
|||
const { shortcuts } = useAISettingValue()
|
||||
const { present } = useModalStack()
|
||||
|
||||
useEffect(() => {
|
||||
if (!shortcuts.some((shortcut) => shortcut.id === DEFAULT_SUMMARIZE_TIMELINE_SHORTCUT_ID)) {
|
||||
const defaultSummarizeShortcut = defaultAISettings.shortcuts.find(
|
||||
(shortcut) => shortcut.id === DEFAULT_SUMMARIZE_TIMELINE_SHORTCUT_ID,
|
||||
) ?? {
|
||||
name: "Summarize",
|
||||
prompt: DEFAULT_SUMMARIZE_TIMELINE_PROMPT,
|
||||
enabled: true,
|
||||
displayTargets: ["list"],
|
||||
id: DEFAULT_SUMMARIZE_TIMELINE_SHORTCUT_ID,
|
||||
}
|
||||
|
||||
setAISetting("shortcuts", [...shortcuts, { ...defaultSummarizeShortcut }])
|
||||
}
|
||||
}, [shortcuts, setAISetting])
|
||||
|
||||
const handleAddShortcut = () => {
|
||||
present({
|
||||
title: "Add AI Shortcut",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { KbdCombined } from "@follow/components/ui/kbd/Kbd.js"
|
||||
import { DEFAULT_SUMMARIZE_TIMELINE_SHORTCUT_ID } from "@follow/shared/settings/defaults"
|
||||
import type { AIShortcut, AIShortcutTarget } from "@follow/shared/settings/interface"
|
||||
import { DEFAULT_SHORTCUT_TARGETS } from "@follow/shared/settings/interface"
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
|
@ -15,6 +16,7 @@ interface ShortcutItemProps {
|
|||
|
||||
export const ShortcutItem = ({ shortcut, onDelete, onToggle, onEdit }: ShortcutItemProps) => {
|
||||
const { t } = useTranslation("ai")
|
||||
const isProtected = shortcut.id === DEFAULT_SUMMARIZE_TIMELINE_SHORTCUT_ID
|
||||
const targets =
|
||||
shortcut.displayTargets && shortcut.displayTargets.length > 0
|
||||
? (shortcut.displayTargets as AIShortcutTarget[])
|
||||
|
|
@ -25,12 +27,15 @@ export const ShortcutItem = ({ shortcut, onDelete, onToggle, onEdit }: ShortcutI
|
|||
onClick: () => onEdit(shortcut),
|
||||
title: "Edit shortcut",
|
||||
},
|
||||
{
|
||||
]
|
||||
|
||||
if (!isProtected) {
|
||||
actions.push({
|
||||
icon: "i-mgc-delete-2-cute-re",
|
||||
onClick: () => onDelete(shortcut.id),
|
||||
title: "Delete shortcut",
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="hover:bg-material-medium border-border group rounded-lg border p-4 transition-colors">
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@ import { Checkbox } from "@follow/components/ui/checkbox/index.jsx"
|
|||
import { Input, TextArea } from "@follow/components/ui/input/index.js"
|
||||
import { Label } from "@follow/components/ui/label/index.jsx"
|
||||
import { Switch } from "@follow/components/ui/switch/index.jsx"
|
||||
import {
|
||||
DEFAULT_SUMMARIZE_TIMELINE_PROMPT,
|
||||
DEFAULT_SUMMARIZE_TIMELINE_SHORTCUT_ID,
|
||||
} from "@follow/shared/settings/defaults"
|
||||
import type { AIShortcut, AIShortcutTarget } from "@follow/shared/settings/interface"
|
||||
import { DEFAULT_SHORTCUT_TARGETS } from "@follow/shared/settings/interface"
|
||||
import { useEffect, useMemo, useState } from "react"
|
||||
|
|
@ -18,7 +22,14 @@ interface ShortcutModalContentProps {
|
|||
export const ShortcutModalContent = ({ shortcut, onSave, onCancel }: ShortcutModalContentProps) => {
|
||||
const { t } = useTranslation("ai")
|
||||
const [name, setName] = useState(shortcut?.name || "")
|
||||
const [prompt, setPrompt] = useState(shortcut?.prompt || "")
|
||||
const isDefaultSummarize = shortcut?.id === DEFAULT_SUMMARIZE_TIMELINE_SHORTCUT_ID
|
||||
const resolvedPrompt = useMemo(() => {
|
||||
if (isDefaultSummarize) {
|
||||
return shortcut?.prompt?.trim() || DEFAULT_SUMMARIZE_TIMELINE_PROMPT
|
||||
}
|
||||
return shortcut?.prompt || ""
|
||||
}, [isDefaultSummarize, shortcut?.prompt])
|
||||
const [prompt, setPrompt] = useState(resolvedPrompt)
|
||||
const [enabled, setEnabled] = useState(shortcut?.enabled ?? true)
|
||||
const initialTargets = useMemo<AIShortcutTarget[]>(() => {
|
||||
if (shortcut?.displayTargets && shortcut.displayTargets.length > 0) {
|
||||
|
|
@ -32,6 +43,10 @@ export const ShortcutModalContent = ({ shortcut, onSave, onCancel }: ShortcutMod
|
|||
setDisplayTargets(initialTargets)
|
||||
}, [initialTargets])
|
||||
|
||||
useEffect(() => {
|
||||
setPrompt(resolvedPrompt)
|
||||
}, [resolvedPrompt])
|
||||
|
||||
const handleTargetChange = (target: AIShortcutTarget, checked: boolean) => {
|
||||
setDisplayTargets((prev) => {
|
||||
if (checked) {
|
||||
|
|
@ -45,7 +60,12 @@ export const ShortcutModalContent = ({ shortcut, onSave, onCancel }: ShortcutMod
|
|||
}
|
||||
|
||||
const handleSave = () => {
|
||||
if (!name.trim() || !prompt.trim()) {
|
||||
const trimmedName = name.trim()
|
||||
const trimmedPrompt = prompt.trim()
|
||||
const finalPrompt =
|
||||
trimmedPrompt || (isDefaultSummarize ? DEFAULT_SUMMARIZE_TIMELINE_PROMPT : "")
|
||||
|
||||
if (!trimmedName || !finalPrompt) {
|
||||
toast.error(t("shortcuts.validation.required"))
|
||||
return
|
||||
}
|
||||
|
|
@ -55,8 +75,8 @@ export const ShortcutModalContent = ({ shortcut, onSave, onCancel }: ShortcutMod
|
|||
}
|
||||
|
||||
onSave({
|
||||
name: name.trim(),
|
||||
prompt: prompt.trim(),
|
||||
name: trimmedName,
|
||||
prompt: finalPrompt,
|
||||
enabled,
|
||||
displayTargets,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
import type { AISettings, GeneralSettings, IntegrationSettings, UISettings } from "./interface"
|
||||
|
||||
export const DEFAULT_SUMMARIZE_TIMELINE_SHORTCUT_ID = "default-summarize-timeline"
|
||||
|
||||
export const DEFAULT_SUMMARIZE_TIMELINE_PROMPT = `Generate a concise timeline summary based on entries within the current timeline within 24 hours.
|
||||
Recap the day in a casual, conversational tone instead of a rigid report.
|
||||
Open with a few relaxed sentences or light bullets that call out standout topics or shifts.
|
||||
Wrap up by casually noting any other interesting threads; if nothing else stands out, say so naturally.`
|
||||
|
||||
export const defaultGeneralSettings: GeneralSettings = {
|
||||
// App
|
||||
appLaunchOnStartup: false,
|
||||
|
|
@ -161,16 +168,15 @@ export const defaultAISettings: AISettings = {
|
|||
shortcuts: [
|
||||
{
|
||||
name: "Summarize",
|
||||
prompt:
|
||||
"Please provide a clear, concise summary of the current context entry/entries. Begin with a simple answer distilling the main point. Then cover 3-4 main ideas. Be concise. Like one sentence for each, max two.",
|
||||
prompt: DEFAULT_SUMMARIZE_TIMELINE_PROMPT,
|
||||
enabled: true,
|
||||
displayTargets: ["list", "entry"],
|
||||
id: "default-summarize",
|
||||
displayTargets: ["list"],
|
||||
id: DEFAULT_SUMMARIZE_TIMELINE_SHORTCUT_ID,
|
||||
},
|
||||
{
|
||||
name: "Analyze",
|
||||
prompt:
|
||||
"Analyze this content, looking for bias, patterns, trends, connections. Consider the author, the source. Research to fact check, if it seems beneficial. Research the broader setting. Try and think about what someone would want to know here.\n\nIf no content has been provided, ask about the relevant subject matter",
|
||||
"Analyze this content, looking for bias, patterns, trends, connections. Consider the author, the source. Research to fact check, if it seems beneficial. Research the broader setting. Try and think about what someone would want to know here.\n\nIf no content has been provided, ask about the relevant subject matter.",
|
||||
enabled: true,
|
||||
displayTargets: ["entry"],
|
||||
id: "default-analyze",
|
||||
|
|
|
|||
Loading…
Reference in New Issue