refactor: separate mobile note projection
This commit is contained in:
@@ -1,19 +1,8 @@
|
||||
import { countWords, deriveDisplayTitleState, extractSnippet } from '@tolaria/markdown'
|
||||
import { projectMobileNotes, type MobileNote, type MobileNoteSource } from './mobileNoteProjection'
|
||||
|
||||
export interface MobileNote {
|
||||
id: string
|
||||
type: string
|
||||
icon: string
|
||||
date: string
|
||||
modified: string
|
||||
content: string
|
||||
title: string
|
||||
snippet: string
|
||||
words: number
|
||||
tags: string[]
|
||||
}
|
||||
export type { MobileNote } from './mobileNoteProjection'
|
||||
|
||||
const noteContent = [
|
||||
const noteContent: MobileNoteSource[] = [
|
||||
{
|
||||
id: 'workflow',
|
||||
type: 'Essay',
|
||||
@@ -76,15 +65,7 @@ const noteContent = [
|
||||
},
|
||||
]
|
||||
|
||||
export const notes: MobileNote[] = noteContent.map((note) => {
|
||||
const titleState = deriveDisplayTitleState({ content: note.content, filename: note.filename })
|
||||
return {
|
||||
...note,
|
||||
title: titleState.title,
|
||||
snippet: extractSnippet(note.content),
|
||||
words: countWords(note.content),
|
||||
}
|
||||
})
|
||||
export const notes: MobileNote[] = projectMobileNotes(noteContent)
|
||||
|
||||
export const sidebarSections = [
|
||||
{
|
||||
|
||||
44
apps/mobile/src/mobileNoteProjection.test.ts
Normal file
44
apps/mobile/src/mobileNoteProjection.test.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { projectMobileNote, projectMobileNotes, type MobileNoteSource } from './mobileNoteProjection'
|
||||
|
||||
const sourceNote: MobileNoteSource = {
|
||||
id: 'workflow',
|
||||
type: 'Essay',
|
||||
icon: 'pen-nib',
|
||||
date: 'May 13, 2026',
|
||||
modified: '6h ago',
|
||||
filename: 'workflow-orchestration-kestra.md',
|
||||
tags: ['Design Inspiration', 'Tolaria MVP'],
|
||||
content: [
|
||||
'---',
|
||||
'title: Workflow Orchestration Essay',
|
||||
'type: Essay',
|
||||
'---',
|
||||
'',
|
||||
'# Workflow Orchestration Essay',
|
||||
'',
|
||||
'The current narrative / temptation is everything routed through an LLM.',
|
||||
].join('\n'),
|
||||
}
|
||||
|
||||
describe('mobile note projection', () => {
|
||||
it('derives list and editor metadata from markdown content', () => {
|
||||
const note = projectMobileNote(sourceNote)
|
||||
|
||||
expect(note).toMatchObject({
|
||||
id: 'workflow',
|
||||
title: 'Workflow Orchestration Essay',
|
||||
snippet: 'The current narrative / temptation is everything routed through an LLM.',
|
||||
words: 11,
|
||||
})
|
||||
})
|
||||
|
||||
it('keeps projection order stable for note lists', () => {
|
||||
const notes = projectMobileNotes([
|
||||
sourceNote,
|
||||
{ ...sourceNote, id: 'release', filename: 'release.md' },
|
||||
])
|
||||
|
||||
expect(notes.map((note) => note.id)).toEqual(['workflow', 'release'])
|
||||
})
|
||||
})
|
||||
42
apps/mobile/src/mobileNoteProjection.ts
Normal file
42
apps/mobile/src/mobileNoteProjection.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { countWords, deriveDisplayTitleState, extractSnippet } from '@tolaria/markdown'
|
||||
|
||||
export type MobileNoteSource = {
|
||||
id: string
|
||||
type: string
|
||||
icon: string
|
||||
date: string
|
||||
modified: string
|
||||
filename: string
|
||||
content: string
|
||||
tags: string[]
|
||||
}
|
||||
|
||||
export type MobileNote = Omit<MobileNoteSource, 'filename'> & {
|
||||
title: string
|
||||
snippet: string
|
||||
words: number
|
||||
}
|
||||
|
||||
export function projectMobileNote(source: MobileNoteSource): MobileNote {
|
||||
const titleState = deriveDisplayTitleState({
|
||||
content: source.content,
|
||||
filename: source.filename,
|
||||
})
|
||||
|
||||
return {
|
||||
id: source.id,
|
||||
type: source.type,
|
||||
icon: source.icon,
|
||||
date: source.date,
|
||||
modified: source.modified,
|
||||
content: source.content,
|
||||
tags: source.tags,
|
||||
title: titleState.title,
|
||||
snippet: extractSnippet(source.content),
|
||||
words: countWords(source.content),
|
||||
}
|
||||
}
|
||||
|
||||
export function projectMobileNotes(sources: MobileNoteSource[]): MobileNote[] {
|
||||
return sources.map(projectMobileNote)
|
||||
}
|
||||
@@ -8,7 +8,7 @@ This file is the resumable working log for Tolaria mobile. The strategy and road
|
||||
|
||||
- Branch: `codex/mobile`
|
||||
- Active phase: Phase 2 - Mobile Shell
|
||||
- Active slice: Prepare compact navigation for gesture-driven phone shell
|
||||
- Active slice: Separate mobile note projection from fixtures
|
||||
- Push policy: commit locally; do not push unless explicitly requested
|
||||
- Validation target: iPad/iOS simulator first
|
||||
|
||||
@@ -35,6 +35,7 @@ This file is the resumable working log for Tolaria mobile. The strategy and road
|
||||
- Split mobile styles into small panel-specific StyleSheet modules so new mobile code starts at CodeScene `10.0`.
|
||||
- Pinned Expo runtime dependencies to the versions expected by Expo 55 after the initial generated versions failed iOS bundle export (`react-native@0.83.6`, `react@19.2.0`, matching safe-area/svg versions).
|
||||
- Extracted compact phone navigation into a pure tested state machine so future swipe gestures can dispatch explicit events instead of mutating panels ad hoc.
|
||||
- Extracted mobile note projection into a pure module that turns raw vault-like note records into the list/editor shape used by the mobile shell.
|
||||
|
||||
## Next Action
|
||||
|
||||
@@ -85,6 +86,10 @@ Continue Phase 2 with the next mobile shell slice:
|
||||
- `pnpm --filter @tolaria/mobile typecheck` passed after compact navigation extraction.
|
||||
- CodeScene after compact navigation extraction: `apps/mobile/src/compactNavigation.ts`, `apps/mobile/src/compactNavigation.test.ts`, and the touched `apps/mobile/src/MobileApp.tsx` scored `10`.
|
||||
- `pnpm --filter @tolaria/mobile exec expo export --platform ios --output-dir /tmp/tolaria-mobile-export` passed after compact navigation extraction.
|
||||
- `pnpm --filter @tolaria/mobile test` passed after note projection extraction: 3 files / 8 tests.
|
||||
- `pnpm --filter @tolaria/mobile typecheck` passed after note projection extraction.
|
||||
- CodeScene after note projection extraction: `apps/mobile/src/mobileNoteProjection.ts` and `apps/mobile/src/mobileNoteProjection.test.ts` scored `10`; `apps/mobile/src/demoData.ts` returned no scorable code and no findings.
|
||||
- `pnpm --filter @tolaria/mobile exec expo export --platform ios --output-dir /tmp/tolaria-mobile-export` passed after note projection extraction.
|
||||
|
||||
## Risks / Watch Items
|
||||
|
||||
|
||||
Reference in New Issue
Block a user