A React Native app for the ultimate thinking partner.

feat: Extract YouView and SettingsView components

YouView (✅ Complete):
- Extracted from App.tsx.monolithic lines 2181-2237
- Memory blocks viewer ('You' view)
- Three states: loading, empty, content
- Markdown rendering for You block
- Create button for empty state

Features:
- Loading spinner while checking for You block
- Empty state: 'Want to understand yourself?' prompt
- Content state: Markdown-rendered You block
- Responsive max-width (700px)
- Theme-aware styling

SettingsView (✅ Complete):
- Extracted from App.tsx.monolithic lines 2791-2814
- App preferences and toggles
- Show Compaction setting

Features:
- Header with title
- Toggle switch for compaction display
- Descriptive text for each setting
- Expandable for future settings
- Animated toggle with theme colors

Both components:
- Fully documented with migration status
- Accept theme and callbacks as props
- Not yet integrated (zero risk)

Next: Extract KnowledgeView (most complex view)

+356
+183
src/views/SettingsView.tsx
··· 1 + /** 2 + * SettingsView Component 3 + * 4 + * MIGRATION STATUS: ✅ EXTRACTED - Ready for use 5 + * 6 + * REPLACES: App.tsx.monolithic lines 2791-2814 7 + * - Settings screen with app preferences 8 + * - Show Compaction toggle 9 + * - Future: More settings can be added here 10 + * 11 + * FEATURES: 12 + * - Show Compaction toggle 13 + * - Controls display of compaction bars in chat 14 + * - When enabled, shows when conversation history is summarized 15 + * - Header with title 16 + * - Expandable for future settings 17 + * 18 + * CURRENT SETTINGS: 19 + * 1. Show Compaction - Toggle compaction visualization 20 + * 21 + * FUTURE SETTINGS (Ideas): 22 + * - Developer mode toggle 23 + * - Message font size 24 + * - Auto-scroll behavior 25 + * - Notification preferences 26 + * - Data export/import 27 + * - Account management 28 + * 29 + * USED BY: (not yet integrated) 30 + * - [ ] App.new.tsx (planned) 31 + * 32 + * RELATED COMPONENTS: 33 + * - AppSidebar.tsx (Settings menu item navigates here) 34 + * - BottomNavigation.tsx (Settings tab navigates here) 35 + */ 36 + 37 + import React from 'react'; 38 + import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'; 39 + import type { Theme } from '../theme'; 40 + 41 + interface SettingsViewProps { 42 + theme: Theme; 43 + showCompaction: boolean; 44 + onToggleCompaction: () => void; 45 + } 46 + 47 + export function SettingsView({ 48 + theme, 49 + showCompaction, 50 + onToggleCompaction, 51 + }: SettingsViewProps) { 52 + return ( 53 + <View style={[styles.container, { backgroundColor: theme.colors.background.primary }]}> 54 + {/* Header */} 55 + <View 56 + style={[ 57 + styles.header, 58 + { 59 + backgroundColor: theme.colors.background.secondary, 60 + borderBottomColor: theme.colors.border.primary, 61 + }, 62 + ]} 63 + > 64 + <Text style={[styles.title, { color: theme.colors.text.primary }]}> 65 + Settings 66 + </Text> 67 + </View> 68 + 69 + {/* Settings Content */} 70 + <View style={styles.content}> 71 + {/* Show Compaction Toggle */} 72 + <View 73 + style={[ 74 + styles.settingItem, 75 + { borderBottomColor: theme.colors.border.primary }, 76 + ]} 77 + > 78 + <View style={styles.settingInfo}> 79 + <Text style={[styles.settingLabel, { color: theme.colors.text.primary }]}> 80 + Show Compaction 81 + </Text> 82 + <Text 83 + style={[ 84 + styles.settingDescription, 85 + { color: theme.colors.text.secondary }, 86 + ]} 87 + > 88 + Display compaction bars when conversation history is summarized 89 + </Text> 90 + </View> 91 + <TouchableOpacity 92 + style={[ 93 + styles.toggle, 94 + showCompaction && [ 95 + styles.toggleActive, 96 + { backgroundColor: theme.colors.interactive.primary }, 97 + ], 98 + !showCompaction && { 99 + backgroundColor: theme.colors.background.tertiary, 100 + }, 101 + ]} 102 + onPress={onToggleCompaction} 103 + > 104 + <View 105 + style={[ 106 + styles.toggleThumb, 107 + showCompaction && styles.toggleThumbActive, 108 + ]} 109 + /> 110 + </TouchableOpacity> 111 + </View> 112 + 113 + {/* Future settings can be added here */} 114 + </View> 115 + </View> 116 + ); 117 + } 118 + 119 + const styles = StyleSheet.create({ 120 + container: { 121 + flex: 1, 122 + }, 123 + header: { 124 + paddingHorizontal: 20, 125 + paddingVertical: 20, 126 + borderBottomWidth: 1, 127 + }, 128 + title: { 129 + fontSize: 28, 130 + fontFamily: 'Lexend_700Bold', 131 + }, 132 + content: { 133 + flex: 1, 134 + }, 135 + settingItem: { 136 + flexDirection: 'row', 137 + alignItems: 'center', 138 + justifyContent: 'space-between', 139 + paddingHorizontal: 20, 140 + paddingVertical: 16, 141 + borderBottomWidth: StyleSheet.hairlineWidth, 142 + }, 143 + settingInfo: { 144 + flex: 1, 145 + marginRight: 16, 146 + }, 147 + settingLabel: { 148 + fontSize: 16, 149 + fontFamily: 'Lexend_500Medium', 150 + marginBottom: 4, 151 + }, 152 + settingDescription: { 153 + fontSize: 13, 154 + fontFamily: 'Lexend_400Regular', 155 + lineHeight: 18, 156 + }, 157 + toggle: { 158 + width: 50, 159 + height: 30, 160 + borderRadius: 15, 161 + padding: 2, 162 + justifyContent: 'center', 163 + }, 164 + toggleActive: { 165 + // Background color set dynamically 166 + }, 167 + toggleThumb: { 168 + width: 26, 169 + height: 26, 170 + borderRadius: 13, 171 + backgroundColor: '#FFFFFF', 172 + shadowColor: '#000', 173 + shadowOffset: { width: 0, height: 2 }, 174 + shadowOpacity: 0.2, 175 + shadowRadius: 2, 176 + elevation: 2, 177 + }, 178 + toggleThumbActive: { 179 + transform: [{ translateX: 20 }], 180 + }, 181 + }); 182 + 183 + export default SettingsView;
+173
src/views/YouView.tsx
··· 1 + /** 2 + * YouView Component 3 + * 4 + * MIGRATION STATUS: ✅ EXTRACTED - Ready for use 5 + * 6 + * REPLACES: App.tsx.monolithic lines 2181-2237 7 + * - Memory blocks viewer ("You" view) 8 + * - Shows "You" block content in markdown 9 + * - Create "You" block if it doesn't exist 10 + * - Loading and empty states 11 + * 12 + * FEATURES: 13 + * - Three states: loading, empty, content 14 + * - Loading: Shows spinner while checking for You block 15 + * - Empty: Shows "Want to understand yourself?" with create button 16 + * - Content: Renders You block markdown 17 + * - Markdown rendering with custom styles 18 + * - Responsive max-width (700px) 19 + * 20 + * LOGIC DEPENDENCIES: 21 + * - Parent must handle: 22 + * - Checking if You block exists 23 + * - Creating You block 24 + * - Loading You block content 25 + * - State management (hasCheckedYouBlock, hasYouBlock, youBlockContent) 26 + * 27 + * USED BY: (not yet integrated) 28 + * - [ ] App.new.tsx (planned) 29 + * 30 + * RELATED COMPONENTS: 31 + * - MemoryBlockViewer.tsx (alternative memory block display) 32 + * - KnowledgeView.tsx (archival memory view) 33 + * 34 + * TODO: 35 + * - Add edit functionality 36 + * - Add multiple memory blocks support 37 + * - Add block type badges 38 + */ 39 + 40 + import React from 'react'; 41 + import { View, Text, TouchableOpacity, ScrollView, ActivityIndicator, StyleSheet } from 'react-native'; 42 + import { Ionicons } from '@expo/vector-icons'; 43 + import Markdown from '@ronradtke/react-native-markdown-display'; 44 + import { createMarkdownStyles } from '../components/markdownStyles'; 45 + import type { Theme } from '../theme'; 46 + 47 + interface YouViewProps { 48 + theme: Theme; 49 + colorScheme: 'light' | 'dark'; 50 + hasCheckedYouBlock: boolean; 51 + hasYouBlock: boolean; 52 + youBlockContent: string; 53 + isCreatingYouBlock: boolean; 54 + onCreateYouBlock: () => void; 55 + } 56 + 57 + export function YouView({ 58 + theme, 59 + colorScheme, 60 + hasCheckedYouBlock, 61 + hasYouBlock, 62 + youBlockContent, 63 + isCreatingYouBlock, 64 + onCreateYouBlock, 65 + }: YouViewProps) { 66 + // Loading state - checking for You block 67 + if (!hasCheckedYouBlock) { 68 + return ( 69 + <View style={[styles.container, { backgroundColor: theme.colors.background.primary }]}> 70 + <View style={styles.centerContent}> 71 + <ActivityIndicator size="large" color={theme.colors.text.primary} /> 72 + </View> 73 + </View> 74 + ); 75 + } 76 + 77 + // Empty state - no You block exists 78 + if (!hasYouBlock) { 79 + return ( 80 + <View style={[styles.container, { backgroundColor: theme.colors.background.primary }]}> 81 + <View style={styles.emptyState}> 82 + <Text 83 + style={[ 84 + styles.emptyTitle, 85 + { color: theme.colors.text.primary }, 86 + ]} 87 + > 88 + Want to understand yourself? 89 + </Text> 90 + <TouchableOpacity 91 + onPress={onCreateYouBlock} 92 + disabled={isCreatingYouBlock} 93 + style={[ 94 + styles.createButton, 95 + { 96 + backgroundColor: theme.colors.background.tertiary, 97 + borderColor: theme.colors.border.primary, 98 + }, 99 + ]} 100 + > 101 + {isCreatingYouBlock ? ( 102 + <ActivityIndicator size="large" color={theme.colors.text.primary} /> 103 + ) : ( 104 + <Ionicons name="add" size={48} color={theme.colors.text.primary} /> 105 + )} 106 + </TouchableOpacity> 107 + </View> 108 + </View> 109 + ); 110 + } 111 + 112 + // Content state - You block exists, show markdown 113 + return ( 114 + <View style={[styles.container, { backgroundColor: theme.colors.background.primary }]}> 115 + <ScrollView 116 + style={styles.scrollView} 117 + contentContainerStyle={styles.contentContainer} 118 + > 119 + <Markdown 120 + style={createMarkdownStyles({ 121 + isUser: false, 122 + isDark: colorScheme === 'dark', 123 + })} 124 + > 125 + {youBlockContent} 126 + </Markdown> 127 + </ScrollView> 128 + </View> 129 + ); 130 + } 131 + 132 + const styles = StyleSheet.create({ 133 + container: { 134 + flex: 1, 135 + }, 136 + centerContent: { 137 + flex: 1, 138 + justifyContent: 'center', 139 + alignItems: 'center', 140 + }, 141 + emptyState: { 142 + flex: 1, 143 + justifyContent: 'center', 144 + alignItems: 'center', 145 + padding: 40, 146 + }, 147 + emptyTitle: { 148 + fontSize: 24, 149 + fontWeight: 'bold', 150 + marginBottom: 40, 151 + textAlign: 'center', 152 + fontFamily: 'Lexend_700Bold', 153 + }, 154 + createButton: { 155 + width: 80, 156 + height: 80, 157 + borderRadius: 40, 158 + borderWidth: 2, 159 + justifyContent: 'center', 160 + alignItems: 'center', 161 + }, 162 + scrollView: { 163 + flex: 1, 164 + }, 165 + contentContainer: { 166 + maxWidth: 700, 167 + width: '100%', 168 + alignSelf: 'center', 169 + padding: 20, 170 + }, 171 + }); 172 + 173 + export default YouView;