Summary
Build a Conversation Mode as a sheet presented from TranslationScreen. This is the app's hero differentiator — a face-to-face translation flow with alternating speaker bubbles.
Entry Point
Add a pill button in the language row between the two LanguagePickerButton components:
[ EN ▾ ] [ Conversation ] [ ⇄ ] [ KO ▾ ]
Tapping it presents ConversationView as a .sheet with .presentationDetents([.large]).
ConversationView Layout
Sheet handle
Title: "Conversation" | [EN • KO pill] | [✕]
ScrollView (auto-scrolls to bottom)
ConversationBubble — Person A (left-aligned, normal orientation)
ConversationBubble — Person B (right-aligned, rotated 180°)
...
[Empty state: bubble icon + "Tap mic or type to begin"]
──────────────────────────────────
[🎙] [text field: "Speak or type..."] [➤]
[ Person A ] [ Person B ] ← speaker toggle
──────────────────────────────────
ConversationBubble Spec
- Source text:
.caption, .secondary — above the translated text
- Translated text:
.body, .primary
- Language flag badge: 16pt circle in the top corner
- Person A bubble: accent color at 15% opacity
- Person B bubble: neutral
Color.appInputOutputBackground, rotated 180°: .rotationEffect(.degrees(180))
- Max width: 75% of screen width
- Corner radii: 16pt, tail corner reduced to 4pt (
UnevenRoundedRectangle, iOS 17+)
- Timestamp: shown in
.caption2, .tertiaryLabel when >60s gap between bubbles
Behaviour
- Active speaker's language is used for speech recognition
- On recognition finish → auto-translate → append both source + translated bubbles
- No manual "Translate" button in conversation mode
ScrollViewReader auto-scrolls to the latest bubble (.easeOut(duration: 0.3))
- Speaker toggle: tappable pill pair with haptic feedback (
.impactOccurred(intensity: 0.6))
- On dismiss with ≥2 bubbles: confirm "Leave conversation?" alert. If history is implemented, offer "Save to History" option.
Also
- Remove or raise the hardcoded 100-character limit (
TranslationViewModel.maxTextLength) — it breaks real conversation use
Files
Projects/App/Sources/Screens/TranslationScreen.swift
Projects/App/Sources/ViewModels/TranslationViewModel.swift
Projects/App/Sources/Screens/SpeechRecognitionScreen.swift
Summary
Build a Conversation Mode as a sheet presented from
TranslationScreen. This is the app's hero differentiator — a face-to-face translation flow with alternating speaker bubbles.Entry Point
Add a pill button in the language row between the two
LanguagePickerButtoncomponents:Tapping it presents
ConversationViewas a.sheetwith.presentationDetents([.large]).ConversationView Layout
ConversationBubble Spec
.caption,.secondary— above the translated text.body,.primaryColor.appInputOutputBackground, rotated 180°:.rotationEffect(.degrees(180))UnevenRoundedRectangle, iOS 17+).caption2,.tertiaryLabelwhen >60s gap between bubblesBehaviour
ScrollViewReaderauto-scrolls to the latest bubble (.easeOut(duration: 0.3)).impactOccurred(intensity: 0.6))Also
TranslationViewModel.maxTextLength) — it breaks real conversation useFiles
Projects/App/Sources/Screens/TranslationScreen.swiftProjects/App/Sources/ViewModels/TranslationViewModel.swiftProjects/App/Sources/Screens/SpeechRecognitionScreen.swift