feat: brainstorm sessions, PDF document Q&A, embedding fixes, and UI improvements
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 7s
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 7s
- Add brainstorm feature with collaborative canvas, AI idea generation, live cursors, playback, and export - Add PDF upload/extraction/ingestion pipeline with pgvector document search (RAG) - Add document Q&A overlay with streaming chat and PDF preview - Add note attachments UI with status polling, grid layout, and auto-scroll - Add task extraction AI tool and agent executor improvements - Fix NoteEmbedding missing updatedAt column, re-index 66 notes with 1536-dim embeddings - Fix brainstorm 'Create Note' button: add success toast and redirect to created note - Fix memory echo notification infinite polling - Fix chat route to always include document_search tool - Add brainstorm i18n keys across all 14 locales - Add socket server for real-time brainstorm collaboration - Add hierarchical notebook selector and organize notebook dialog improvements - Add sidebar brainstorm section with session management - Update prisma schema with brainstorm tables, attachments, and document chunks
This commit is contained in:
74
memento-note/lib/utils/format-localized-date.ts
Normal file
74
memento-note/lib/utils/format-localized-date.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { format, type Locale } from 'date-fns'
|
||||
import { toJalaali } from 'jalaali-js'
|
||||
|
||||
const JALALI_MONTHS_FA = [
|
||||
'فروردین',
|
||||
'اردیبهشت',
|
||||
'خرداد',
|
||||
'تیر',
|
||||
'مرداد',
|
||||
'شهریور',
|
||||
'مهر',
|
||||
'آبان',
|
||||
'آذر',
|
||||
'دی',
|
||||
'بهمن',
|
||||
'اسفند',
|
||||
] as const
|
||||
|
||||
const PERSIAN_DIGITS = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'] as const
|
||||
|
||||
/** Western digits → Persian (Extended Arabic-Indic) numerals, e.g. 1405 → ۱۴۰۵ */
|
||||
export function toPersianDigits(input: string): string {
|
||||
return input.replace(/\d/g, (ch) => PERSIAN_DIGITS[Number(ch)] ?? ch)
|
||||
}
|
||||
|
||||
function pad2(n: number): string {
|
||||
return n < 10 ? `0${n}` : `${n}`
|
||||
}
|
||||
|
||||
function formatJalaliAbsolute(date: Date, pattern: string): string {
|
||||
const { jy, jm, jd } = toJalaali(date)
|
||||
const monthName = JALALI_MONTHS_FA[jm - 1]
|
||||
const h = pad2(date.getHours())
|
||||
const min = pad2(date.getMinutes())
|
||||
|
||||
let s: string
|
||||
switch (pattern) {
|
||||
case 'd MMM yyyy':
|
||||
s = `${jd} ${monthName} ${jy}`
|
||||
break
|
||||
case 'd MMM yyyy · HH:mm':
|
||||
s = `${jd} ${monthName} ${jy} · ${h}:${min}`
|
||||
break
|
||||
case 'd MMM yyyy HH:mm':
|
||||
s = `${jd} ${monthName} ${jy} ${h}:${min}`
|
||||
break
|
||||
case 'd MMM · HH:mm':
|
||||
s = `${jd} ${monthName} · ${h}:${min}`
|
||||
break
|
||||
case 'MMM d, yyyy':
|
||||
s = `${monthName} ${jd}، ${jy}`
|
||||
break
|
||||
default:
|
||||
s = `${jd} ${monthName} ${jy}`
|
||||
}
|
||||
return toPersianDigits(s)
|
||||
}
|
||||
|
||||
/**
|
||||
* Absolute calendar dates for Persian (`fa`) use the Solar Hijri (Jalali / هجری شمسی) calendar.
|
||||
* Times remain in the user's local timezone. For relative phrases, keep using `formatDistanceToNow` with `faIR`.
|
||||
*/
|
||||
export function formatAbsoluteDateLocalized(
|
||||
date: Date | string,
|
||||
language: string,
|
||||
pattern: string,
|
||||
locale: Locale
|
||||
): string {
|
||||
const d = typeof date === 'string' ? new Date(date) : date
|
||||
if (language === 'fa') {
|
||||
return formatJalaliAbsolute(d, pattern)
|
||||
}
|
||||
return format(d, pattern, { locale })
|
||||
}
|
||||
Reference in New Issue
Block a user