feat: smart note history with manual/auto modes, delete entries, i18n fixes
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 1m16s

- Add noteHistoryMode setting (manual default / auto) with DB migration
- Manual mode: commit button in editor toolbar creates snapshots on demand
- Auto mode: smart snapshots with 20-char diff threshold + 5min cooldown,
  structural changes (color, pin, archive, labels) bypass cooldown
- Add delete individual history entries from history modal
- Fix sidebar: Notes nav no longer active on notebook pages
- Fix sidebar icon: replace filled Lightbulb with outlined FileText
- Fix title suggestions: change from amber to sky blue color scheme
- Fix hydration mismatch: add suppressHydrationWarning on locale dates
- Complete i18n: add history, sort, and AI chat translations for all 16 languages
- Translate French AI assistant section (40+ keys) from English to French
- Update README with new features and stack info

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-28 21:05:55 +02:00
parent ed807d3b2a
commit 69ea064ca8
40 changed files with 2110 additions and 250 deletions

View File

@@ -21,6 +21,8 @@ export type UserAISettingsData = {
fontSize?: 'small' | 'medium' | 'large'
languageDetection?: boolean
autoLabeling?: boolean
noteHistory?: boolean
noteHistoryMode?: 'manual' | 'auto'
}
/** Only fields that exist on `UserAISettings` in Prisma (excludes e.g. `theme`, which lives on `User`). */
@@ -41,6 +43,8 @@ const USER_AI_SETTINGS_PRISMA_KEYS = [
'anonymousAnalytics',
'languageDetection',
'autoLabeling',
'noteHistory',
'noteHistoryMode',
] as const
type UserAISettingsPrismaKey = (typeof USER_AI_SETTINGS_PRISMA_KEYS)[number]
@@ -151,6 +155,8 @@ const getCachedAISettings = unstable_cache(
fontSize: 'medium' as const,
languageDetection: true,
autoLabeling: true,
noteHistory: false,
noteHistoryMode: 'manual' as const,
}
}
@@ -180,6 +186,8 @@ const getCachedAISettings = unstable_cache(
fontSize: (settings.fontSize || 'medium') as 'small' | 'medium' | 'large',
languageDetection: settings.languageDetection ?? true,
autoLabeling: settings.autoLabeling ?? true,
noteHistory: settings.noteHistory ?? false,
noteHistoryMode: (settings.noteHistoryMode ?? 'manual') as 'manual' | 'auto',
}
} catch (error) {
console.error('Error getting AI settings:', error)
@@ -202,6 +210,8 @@ const getCachedAISettings = unstable_cache(
fontSize: 'medium' as const,
languageDetection: true,
autoLabeling: true,
noteHistory: false,
noteHistoryMode: 'manual' as const,
}
}
},
@@ -237,6 +247,8 @@ export async function getAISettings(userId?: string) {
fontSize: 'medium' as const,
languageDetection: true,
autoLabeling: true,
noteHistory: false,
noteHistoryMode: 'manual' as const,
}
}
@@ -266,6 +278,8 @@ export async function isAIFeatureEnabled(feature: keyof UserAISettingsData): Pro
return settings.paragraphRefactor
case 'memoryEcho':
return settings.memoryEcho
case 'noteHistory':
return settings.noteHistory
default:
return true
}