dhammawatthumpra commited on
Commit
1d46bea
·
1 Parent(s): f11cd44

docs: update arch doc to v2.4.0 and move maximize button to bottom-right

Browse files
TIPITAKA_WEB_ARCHITECTURE_V2.md CHANGED
@@ -1,10 +1,10 @@
1
  # Tipitaka Web Application Architecture V2
2
  ## Vite + FastAPI + Qdrant — "Book Sanctuary + Floating AI Consultant"
3
 
4
- > **Version:** 2.3.0
5
- > **Date:** 2026-05-17
6
  > **Status:** Production (local dev, ready for HF Spaces)
7
- > **Based on:** Code at commit `b8531b2`
8
 
9
  ---
10
 
@@ -15,6 +15,19 @@ Web Application สำหรับอ่านพระไตรปิฎก ม
15
 
16
  ### 1.2 Key Changes
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  #### V2.3.0 (2026-05-17)
19
 
20
  | Layer | V2.2.0 | V2.3.0 |
@@ -86,12 +99,13 @@ graph TB
86
  RT[RightToolbar<br/>44px controls strip]
87
  AIP[AIPopup<br/>Draggable + resizable chat]
88
  SP[SelectionPopup<br/>AI from selection]
 
89
  end
90
  subgraph "State (Zustand)"
91
  RS[ReaderStore<br/>volume, page, content]
92
  TS[ThemeStore<br/>theme, fontSize]
93
  US[UIStore<br/>navOpen, activeTab]
94
- AS[AIStore<br/>messages, mode, width, pos, panelSize]
95
  SS[SearchStore<br/>query, results, breakdown]
96
  end
97
  end
@@ -124,11 +138,12 @@ graph TB
124
  end
125
 
126
  UI --> APP
127
- APP --> ND & RP & RT & AIP & SP
128
  RP --> RS
129
  ND --> SS & US
130
  RT --> TS & RS
131
  AIP --> AS
 
132
  R1 & R2 & R3 --> S1 --> DB
133
  R4 & R5 --> S2 --> DB
134
  R4 --> S3
@@ -225,12 +240,18 @@ sequenceDiagram
225
 
226
  ```
227
  tipitaka-web/
228
- ├── index.html # Vite entry
229
  ├── vite.config.ts # Vite + proxy config
230
  ├── tsconfig.json / .app.json / .node.json
231
  ├── package.json
232
  ├── eslint.config.js
233
 
 
 
 
 
 
 
234
  └── src/
235
  ├── main.tsx # React entry
236
  ├── App.tsx # <AppShell /> only
@@ -240,7 +261,7 @@ tipitaka-web/
240
  │ ├── layout/
241
  │ │ ├── AppShell.tsx # flex h-screen: NavDrawer + Reader + RightToolbar
242
  │ │ ├── NavDrawer.tsx # 320px sidebar: TOC / Search / Overview tabs
243
- │ │ ├── ReaderPanel.tsx # Main content area with swipe nav
244
  │ │ └── MobileBottomBar.tsx # Mobile page nav
245
  │ │
246
  │ ├── reader/
@@ -250,7 +271,8 @@ tipitaka-web/
250
  │ │ └── RightToolbar.tsx # 44px fixed right: page nav, font size, theme
251
  │ │
252
  │ └── ai/
253
- ── AIPopup.tsx # Draggable + vertically/diagonally resizable chat
 
254
 
255
  ├── hooks/
256
  │ ├── useKeyboardNav.ts # ← → PgUp PgDown Space
@@ -258,7 +280,7 @@ tipitaka-web/
258
 
259
  ├── stores/
260
  │ ├── appStore.ts # readerStore + themeStore + uiStore
261
- │ ├── aiStore.ts # AI messages, streaming, drag+resize state, panelSize
262
  │ └── searchStore.ts # Search queries, results, suggestions
263
 
264
  └── lib/
@@ -271,7 +293,7 @@ tipitaka-web/
271
  ```tsx
272
  // Layout: flex h-screen overflow-hidden
273
  // Structure: NavDrawer | Reader (flex-1) | RightToolbar (fixed 44px)
274
- // Overlays: AI Popup (fixed), Selection Popup (fixed), Mobile Bottom Bar
275
  // Theme: dynamic SHELL_BG per theme (dark/light/classic)
276
  ```
277
 
@@ -288,10 +310,37 @@ tipitaka-web/
288
  // Line height: 2.1
289
  // Theme-aware styles (3 themes: dark/light/classic)
290
  // End markers: extracted from raw <B> tags containing "จบ" — rendered as --- marker text ---
291
- // AnimatePresence for page transitions
 
292
  // Swipe support: ← next, → prev (mobile)
293
  ```
294
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
  #### NavDrawer (320px)
296
  ```tsx
297
  // 3 tabs: TOC | Search | Overview
@@ -648,10 +697,10 @@ Config intelligently resolves paths based on environment:
648
  - **Navigation**: Clear page markers, prev/next predictable
649
  - **Swipe**: Mobile gesture ← → works naturally with page boundaries
650
 
651
- ### 7.5 Why No PWA/Offline?
652
- - **Content is dynamic**: Pages rendered with AI context and search results
653
- - **Token-based auth**: Not applicable (public content, but still server-dependant)
654
- - **Snapshot data too large**: 250MB+ not practical for offline storage
655
 
656
  ### 7.6 Why Split First Page at "ขอนอบน้อม"?
657
  - **Universal**: Works for all 45 volumes — the homage line is the only consistent structural element on page 1
@@ -663,6 +712,22 @@ Config intelligently resolves paths based on environment:
663
  - **CSS**: `text-justify: inter-character` ensures even spacing in Thai script (where inter-word gaps would look uneven due to lack of explicit word boundaries in Thai)
664
  - **User preference**: ผู้ใช้ request ให้จัด justify (2026-05-07)
665
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
666
  ---
667
 
668
  ## 8. Test Coverage
 
1
  # Tipitaka Web Application Architecture V2
2
  ## Vite + FastAPI + Qdrant — "Book Sanctuary + Floating AI Consultant"
3
 
4
+ > **Version:** 2.4.0
5
+ > **Date:** 2026-05-20
6
  > **Status:** Production (local dev, ready for HF Spaces)
7
+ > **Based on:** Code at commit `f11cd44`
8
 
9
  ---
10
 
 
15
 
16
  ### 1.2 Key Changes
17
 
18
+ #### V2.4.0 (2026-05-20)
19
+
20
+ | Layer | V2.3.0 | V2.4.0 |
21
+ |-------|--------|--------|
22
+ | **AI Assistant UI** | Simple round button | **Speed Dial Floating Menu** — 5 quick actions (`AIFloatingMenu.tsx`) with responsive font size |
23
+ | **Response Display** | Text in chat window | **Translucent Answer Card** — frosted-glass overlay (`viewMode: 'answer'`) with full height/width resize support |
24
+ | **Disclaimer Warning** | Bottom/separate block | **Centered Title Bar Disclaimer** — Kalama Sutta warning absolute-centered in header to save vertical space |
25
+ | **Focus Mode (Zoom)** | Latest assistant message only | **Individual Message Zoom** — maximize button on each assistant message bubble, responsive opacity |
26
+ | **Mobile UX** | Cutoff on status bar | **Safe Area Insets** — top padding support for Focus Mode Header and menu buttons |
27
+ | **Reader Navigation** | Keep scroll state | **Scroll Reset** — resets reader view to top when a new page loads, direction-aware transitions |
28
+ | **PWA & Offline** | None | **Full Progressive Web App** — manifest, high-res Dharma wheel icons, Safari-compatible apple-touch-icons, Cache-Control headers |
29
+ | **Commit** | `b8531b2` | `f11cd44` |
30
+
31
  #### V2.3.0 (2026-05-17)
32
 
33
  | Layer | V2.2.0 | V2.3.0 |
 
99
  RT[RightToolbar<br/>44px controls strip]
100
  AIP[AIPopup<br/>Draggable + resizable chat]
101
  SP[SelectionPopup<br/>AI from selection]
102
+ AIF[AIFloatingMenu<br/>Speed Dial Menu]
103
  end
104
  subgraph "State (Zustand)"
105
  RS[ReaderStore<br/>volume, page, content]
106
  TS[ThemeStore<br/>theme, fontSize]
107
  US[UIStore<br/>navOpen, activeTab]
108
+ AS[AIStore<br/>messages, mode, useRag, viewMode, width, height, pos]
109
  SS[SearchStore<br/>query, results, breakdown]
110
  end
111
  end
 
138
  end
139
 
140
  UI --> APP
141
+ APP --> ND & RP & RT & AIP & SP & AIF
142
  RP --> RS
143
  ND --> SS & US
144
  RT --> TS & RS
145
  AIP --> AS
146
+ AIF --> AS
147
  R1 & R2 & R3 --> S1 --> DB
148
  R4 & R5 --> S2 --> DB
149
  R4 --> S3
 
240
 
241
  ```
242
  tipitaka-web/
243
+ ├── index.html # Vite entry with PWA viewport & iOS meta tags
244
  ├── vite.config.ts # Vite + proxy config
245
  ├── tsconfig.json / .app.json / .node.json
246
  ├── package.json
247
  ├── eslint.config.js
248
 
249
+ ├── public/ # PWA Assets
250
+ │ ├── manifest.json # Web app manifest for installability
251
+ │ ├── favicon.ico / favicon.svg # App icons
252
+ │ ├── icon-192.png / icon-512.png # High-res Dharma wheel icons
253
+ │ └── apple-touch-icon*.png # Safari touch icons (precomposed & sized)
254
+
255
  └── src/
256
  ├── main.tsx # React entry
257
  ├── App.tsx # <AppShell /> only
 
261
  │ ├── layout/
262
  │ │ ├── AppShell.tsx # flex h-screen: NavDrawer + Reader + RightToolbar
263
  │ │ ├── NavDrawer.tsx # 320px sidebar: TOC / Search / Overview tabs
264
+ │ │ ├── ReaderPanel.tsx # Main content area with swipe & vertical scroll nav
265
  │ │ └── MobileBottomBar.tsx # Mobile page nav
266
  │ │
267
  │ ├── reader/
 
271
  │ │ └── RightToolbar.tsx # 44px fixed right: page nav, font size, theme
272
  │ │
273
  │ └── ai/
274
+ ── AIPopup.tsx # Draggable + resizable chat & translucent answer card
275
+ │ └── AIFloatingMenu.tsx # Floating speed dial menu with 5 quick actions
276
 
277
  ├── hooks/
278
  │ ├── useKeyboardNav.ts # ← → PgUp PgDown Space
 
280
 
281
  ├── stores/
282
  │ ├── appStore.ts # readerStore + themeStore + uiStore
283
+ │ ├── aiStore.ts # AI messages, streaming, drag+resize state, viewMode, panelSize
284
  │ └── searchStore.ts # Search queries, results, suggestions
285
 
286
  └── lib/
 
293
  ```tsx
294
  // Layout: flex h-screen overflow-hidden
295
  // Structure: NavDrawer | Reader (flex-1) | RightToolbar (fixed 44px)
296
+ // Overlays: AI Popup (fixed), Selection Popup (fixed), AIFloatingMenu (fixed), Mobile Bottom Bar
297
  // Theme: dynamic SHELL_BG per theme (dark/light/classic)
298
  ```
299
 
 
310
  // Line height: 2.1
311
  // Theme-aware styles (3 themes: dark/light/classic)
312
  // End markers: extracted from raw <B> tags containing "จบ" — rendered as --- marker text ---
313
+ // AnimatePresence for page transitions (direction-aware)
314
+ // Scroll reset: automatic scroll-to-top when navigating to a new page
315
  // Swipe support: ← next, → prev (mobile)
316
  ```
317
 
318
+ #### AIFloatingMenu [NEW]
319
+ ```tsx
320
+ // Floating Speed Dial menu collapsing into a single Sparkles/X icon
321
+ // Expands upward to reveal 5 action buttons with tooltips (อธิบาย, สรุป, วิเคราะห์ธรรม, ประยุกต์ใช้, แชทสอบถาม)
322
+ // Label font size: text-[13px] md:text-sm font-bold for high readability on all screens
323
+ // Radial stagger animation using framer-motion
324
+ // Actions 1-4 automatically send current page context and trigger 'answer' viewMode (Translucent Answer Card)
325
+ // Action 5 switches to 'chat' viewMode (opens the main chat window)
326
+ ```
327
+
328
+ #### AIPopup
329
+ ```tsx
330
+ // Floating, draggable assistant panel supporting two modes:
331
+ // 1. 'chat' viewMode (full conversational interface)
332
+ // 2. 'answer' viewMode (translucent glassmorphism card for quick AI summaries)
333
+ // Three resize modes: right-edge (horizontal), bottom-edge (vertical), corner (diagonal)
334
+ // Panel size (width, height) and coordinates (pos) are fully resizable and persisted in localStorage
335
+ // Two AI models: fast (deepseek-chat) / reasoner (deepseek-reasoner)
336
+ // RAG toggle pill (green/yellow/red dot readiness indicator)
337
+ // Title Bar Disclaimer: Kalama Sutta warning is absolute-centered in Row 1 of header to save vertical space
338
+ // Individual Message Fullscreen: Maximize button on each assistant message bubble, enabling focus mode on any previous message in the chat log. Oppacity is responsive (always visible on mobile, hover-only on desktop)
339
+ // Safe Area Support: paddingTop calculation in Focus Mode Header preventing notched phones from cutting off buttons
340
+ // Input + Send button
341
+ // Width: 300px–80vw, default 400px
342
+ ```
343
+
344
  #### NavDrawer (320px)
345
  ```tsx
346
  // 3 tabs: TOC | Search | Overview
 
697
  - **Navigation**: Clear page markers, prev/next predictable
698
  - **Swipe**: Mobile gesture ← → works naturally with page boundaries
699
 
700
+ ### 7.5 Why Progressive Web App (PWA) Implementation?
701
+ - **Immersive View (จิตวิเวก)**: Standalone display mode removes browser address bars and controls, creating an clean, distraction-free environment for scripture reading.
702
+ - **Platform Integration**: Custom Dharma wheel icons and manifest settings provide native-like installability on mobile (iOS/Android) and desktop, including proper theme coloring matching the midnight dark mode.
703
+ - **Safe Area Insets**: Safe area environment variables (`env(safe-area-inset-top)`) are utilized in headers to handle physical phone notches and overlays on mobile when installed.
704
 
705
  ### 7.6 Why Split First Page at "ขอนอบน้อม"?
706
  - **Universal**: Works for all 45 volumes — the homage line is the only consistent structural element on page 1
 
712
  - **CSS**: `text-justify: inter-character` ensures even spacing in Thai script (where inter-word gaps would look uneven due to lack of explicit word boundaries in Thai)
713
  - **User preference**: ผู้ใช้ request ให้จัด justify (2026-05-07)
714
 
715
+ ### 7.8 Why Speed Dial Floating Menu & Translucent Answer Card?
716
+ - **Cleaner Interface**: Replaced the permanent floating AI block/button with a single collapsible Sparkles icon to preserve the Book Sanctuary theme when the AI is not needed.
717
+ - **Frosted Glass Card (Answer Card)**: Triggers only when executing quick functions (Explain, Summarize, Analyze, Apply). The frosted glass background blends naturally into the reader background without full-screen distraction.
718
+ - **Complete Freedom of Resizing**: The panel size constraint was lifted (allowing full height/width expansion) to prevent text overflow issues and allow comfortable reading of long AI responses.
719
+
720
+ ### 7.9 Why Centered Title Bar Disclaimer (Kalama Sutta)?
721
+ - **Saves Vertical Screen Real Estate**: Instead of having a dedicated banner occupying vertical space in the reader or popup layout, the Kalama Sutta warning is absolute-centered in the top title bar of the AIPopup.
722
+ - **Safety Reference**: Constantly reminds readers of the Kalama Sutta guidelines when interpreting AI output, without affecting content readability.
723
+
724
+ ### 7.10 Why Zoom Button on Individual History Bubbles?
725
+ - **Focus Mode Flexibility**: Instead of only allowing the latest AI response to be opened in full-screen Focus Mode, a zoom button was added to *every* assistant response bubble in the history. Users can now zoom into any past answer.
726
+ - **Responsive Opacity**: Always visible (semi-transparent) on mobile devices for ease of touch interaction, and only visible on hover on desktops to keep the interface clean.
727
+
728
+ ### 7.11 Why Resetting Scroll Position to Top on Page Load?
729
+ - **Consistent Reading Position**: Previously, when navigating to the next/prev page, the scroll position did not reset, starting the reader mid-way down the page. Resetting it to `0` ensures a natural reading flow from the top header downwards.
730
+
731
  ---
732
 
733
  ## 8. Test Coverage
webapp/tipitaka-web/src/components/ai/AIPopup.tsx CHANGED
@@ -582,7 +582,7 @@ const AIPopup: React.FC = () => {
582
  <button
583
  onClick={() => setExpandedIndex(i)}
584
  onMouseDown={e => e.stopPropagation()}
585
- className="absolute top-2.5 right-2.5 p-1 rounded-lg bg-black/5 hover:bg-[#c8860a]/20 text-[#c8860a] transition-all opacity-60 md:opacity-0 md:group-hover:opacity-100"
586
  title="อ่านข้อความนี้เต็มจอ"
587
  >
588
  <Maximize2 size={13} />
 
582
  <button
583
  onClick={() => setExpandedIndex(i)}
584
  onMouseDown={e => e.stopPropagation()}
585
+ className="absolute bottom-2 right-2 p-1 rounded-lg bg-black/5 hover:bg-[#c8860a]/20 text-[#c8860a] transition-all opacity-60 md:opacity-0 md:group-hover:opacity-100"
586
  title="อ่านข้อความนี้เต็มจอ"
587
  >
588
  <Maximize2 size={13} />