chore(ci): correct Gitea runner to runs-on ubuntu-24.04 and feat(billing): implement US-3.7 billing/subscription UX
Some checks failed
CI / Deploy production (on server) (push) Has been cancelled
CI / Lint, Unit Tests & Build (push) Has been cancelled

This commit is contained in:
Antigravity
2026-05-28 21:39:08 +00:00
parent 4bfa7c6b69
commit 3b2570d981
11 changed files with 180 additions and 71 deletions

View File

@@ -50,6 +50,7 @@ export function NoteEditorProvider({ note, readOnly = false, fullPage = false, o
}
}, [session?.user?.id])
const [quotaExceededFeature, setQuotaExceededFeature] = useState<string | null>(null)
const [title, setTitle] = useState(note.title || '')
const contentRef = useRef(note.content)
const [content, setContentState] = useState(note.content)
@@ -93,6 +94,7 @@ export function NoteEditorProvider({ note, readOnly = false, fullPage = false, o
const prev = prevNoteRef.current
if (note.id !== prev.id) {
setQuotaExceededFeature(null)
setTitle(note.title || '')
setContentImmediate(note.content)
setCheckItems(note.checkItems || [])
@@ -165,7 +167,8 @@ export function NoteEditorProvider({ note, readOnly = false, fullPage = false, o
const { suggestions, isAnalyzing: isAnalyzingSuggestions } = useAutoTagging({
content: content,
notebookId: note.notebookId,
enabled: autoTaggingEnabled
enabled: autoTaggingEnabled,
onQuotaExceeded: () => setQuotaExceededFeature('auto_tag')
})
const [showReminderDialog, setShowReminderDialog] = useState(false)
@@ -382,6 +385,10 @@ export function NoteEditorProvider({ note, readOnly = false, fullPage = false, o
})
if (!response.ok) {
if (response.status === 402) {
setQuotaExceededFeature('auto_title')
return
}
const errorData = await response.json()
throw new Error(errorData.error || t('ai.titleGenerationError'))
}
@@ -454,6 +461,10 @@ export function NoteEditorProvider({ note, readOnly = false, fullPage = false, o
})
if (!response.ok) {
if (response.status === 402) {
setQuotaExceededFeature('reformulate')
return
}
const errorData = await response.json()
throw new Error(errorData.error || t('ai.reformulationError'))
}
@@ -490,6 +501,10 @@ export function NoteEditorProvider({ note, readOnly = false, fullPage = false, o
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: content, option: 'clarify' })
})
if (response.status === 402) {
setQuotaExceededFeature('reformulate')
return
}
const data = await response.json()
if (!response.ok) throw new Error(data.error || t('notes.clarifyFailed'))
setContentImmediate(data.reformulatedText || data.text)
@@ -519,6 +534,10 @@ export function NoteEditorProvider({ note, readOnly = false, fullPage = false, o
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: content, option: 'shorten' })
})
if (response.status === 402) {
setQuotaExceededFeature('reformulate')
return
}
const data = await response.json()
if (!response.ok) throw new Error(data.error || t('notes.shortenFailed'))
setContentImmediate(data.reformulatedText || data.text)
@@ -548,6 +567,10 @@ export function NoteEditorProvider({ note, readOnly = false, fullPage = false, o
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: content, option: 'improve' })
})
if (response.status === 402) {
setQuotaExceededFeature('reformulate')
return
}
const data = await response.json()
if (!response.ok) throw new Error(data.error || t('notes.improveFailed'))
setContentImmediate(data.reformulatedText || data.text)
@@ -864,13 +887,14 @@ export function NoteEditorProvider({ note, readOnly = false, fullPage = false, o
isMarkdown,
allImages,
colorClasses,
quotaExceededFeature,
}), [
title, content, checkItems, labels, images, links, newLabel, color, size,
showMarkdownPreview, removedImageUrls, isSaving, isDirty, isProcessingAI, aiOpen, infoOpen,
isGeneratingTitles, titleSuggestions, dismissedTitleSuggestions, isReformulating,
reformulationModal, previousContentForCopilot, showReminderDialog, currentReminder,
showLinkDialog, linkUrl, comparisonNotes, fusionNotes, dismissedTags, filteredSuggestions,
isAnalyzingSuggestions, isMarkdown, allImages, colorClasses
isAnalyzingSuggestions, isMarkdown, allImages, colorClasses, quotaExceededFeature
])
const actions: NoteEditorActions = useMemo(() => ({
@@ -924,13 +948,14 @@ export function NoteEditorProvider({ note, readOnly = false, fullPage = false, o
setIsGeneratingTitles,
setIsAnalyzingSuggestions: (_a) => { /* handled by useAutoTagging */ },
setPreviousContentForCopilot,
setQuotaExceededFeature,
}), [
handleCheckItem, handleUpdateCheckItem, handleAddCheckItem, handleRemoveCheckItem,
handleSelectGhostTag, handleDismissGhostTag, handleRemoveLabel, handleImageUpload,
handleRemoveImage, handleAddLink, handleRemoveLink, handleReminderSave,
handleRemoveReminder, handleGenerateTitles, handleSelectTitle, handleReformulate,
handleApplyRefactor, handleClarifyDirect, handleShortenDirect, handleImproveDirect,
handleTransformMarkdown, handleSave, handleSaveInPlace, handleMakeCopy
handleTransformMarkdown, handleSave, handleSaveInPlace, handleMakeCopy, setQuotaExceededFeature
])
const value: NoteEditorContextValue = useMemo(() => ({