A React Native app for the ultimate thinking partner.

feat(settings): add settings view with compaction toggle

- Add Settings menu item to sidebar
- Create full-screen settings view
- Add 'Show Compaction' toggle setting to control visibility of compaction bars
- Update compaction rendering to respect user preference
- Add toggle component styles with active states

Users can now hide compaction bars by disabling the setting in the Settings view.

+99 -1
+99 -1
App.tsx
··· 135 135 const [screenData, setScreenData] = useState(Dimensions.get('window')); 136 136 const [sidebarVisible, setSidebarVisible] = useState(false); 137 137 const [activeSidebarTab, setActiveSidebarTab] = useState<'files'>('files'); 138 - const [currentView, setCurrentView] = useState<'you' | 'chat' | 'knowledge'>('chat'); 138 + const [currentView, setCurrentView] = useState<'you' | 'chat' | 'knowledge' | 'settings'>('chat'); 139 139 const [knowledgeTab, setKnowledgeTab] = useState<'core' | 'archival' | 'files'>('core'); 140 + 141 + // Settings 142 + const [showCompaction, setShowCompaction] = useState(true); 140 143 const [memoryBlocks, setMemoryBlocks] = useState<MemoryBlock[]>([]); 141 144 const [isLoadingBlocks, setIsLoadingBlocks] = useState(false); 142 145 const [blocksError, setBlocksError] = useState<string | null>(null); ··· 1774 1777 } 1775 1778 1776 1779 if (isCompactionAlert) { 1780 + // Hide compaction if user has disabled it in settings 1781 + if (!showCompaction) { 1782 + return null; 1783 + } 1784 + 1777 1785 // Render compaction alert as thin grey expandable line 1778 1786 const isCompactionExpanded = expandedCompaction.has(msg.id); 1779 1787 ··· 2065 2073 > 2066 2074 <Ionicons name="library-outline" size={24} color={theme.colors.text.primary} /> 2067 2075 <Text style={[styles.menuItemText, { color: theme.colors.text.primary }]}>Knowledge</Text> 2076 + </TouchableOpacity> 2077 + 2078 + <TouchableOpacity 2079 + style={[styles.menuItem, { borderBottomColor: theme.colors.border.primary }]} 2080 + onPress={() => { 2081 + setCurrentView('settings'); 2082 + }} 2083 + > 2084 + <Ionicons name="settings-outline" size={24} color={theme.colors.text.primary} /> 2085 + <Text style={[styles.menuItemText, { color: theme.colors.text.primary }]}>Settings</Text> 2068 2086 </TouchableOpacity> 2069 2087 2070 2088 <TouchableOpacity ··· 2867 2885 )} 2868 2886 </View> 2869 2887 </View> 2888 + ) : currentView === 'settings' ? ( 2889 + /* Settings View */ 2890 + <View style={styles.memoryViewContainer}> 2891 + <View style={[styles.settingsHeader, { backgroundColor: theme.colors.background.secondary, borderBottomColor: theme.colors.border.primary }]}> 2892 + <Text style={[styles.settingsTitle, { color: theme.colors.text.primary }]}>Settings</Text> 2893 + </View> 2894 + 2895 + <View style={styles.settingsContent}> 2896 + {/* Show Compaction Setting */} 2897 + <View style={[styles.settingItem, { borderBottomColor: theme.colors.border.primary }]}> 2898 + <View style={styles.settingInfo}> 2899 + <Text style={[styles.settingLabel, { color: theme.colors.text.primary }]}>Show Compaction</Text> 2900 + <Text style={[styles.settingDescription, { color: theme.colors.text.secondary }]}> 2901 + Display compaction bars when conversation history is summarized 2902 + </Text> 2903 + </View> 2904 + <TouchableOpacity 2905 + style={[styles.toggle, showCompaction && styles.toggleActive]} 2906 + onPress={() => setShowCompaction(!showCompaction)} 2907 + > 2908 + <View style={[styles.toggleThumb, showCompaction && styles.toggleThumbActive]} /> 2909 + </TouchableOpacity> 2910 + </View> 2911 + </View> 2912 + </View> 2870 2913 ) : null} 2871 2914 2872 2915 {/* Knowledge block viewer - right pane on desktop */} ··· 3772 3815 modalButtonText: { 3773 3816 fontSize: 16, 3774 3817 fontFamily: 'Lexend_500Medium', 3818 + }, 3819 + // Settings styles 3820 + settingsHeader: { 3821 + paddingVertical: 16, 3822 + paddingHorizontal: 20, 3823 + borderBottomWidth: 1, 3824 + }, 3825 + settingsTitle: { 3826 + fontSize: 24, 3827 + fontFamily: 'Lexend_600SemiBold', 3828 + }, 3829 + settingsContent: { 3830 + flex: 1, 3831 + }, 3832 + settingItem: { 3833 + flexDirection: 'row', 3834 + justifyContent: 'space-between', 3835 + alignItems: 'center', 3836 + paddingVertical: 16, 3837 + paddingHorizontal: 20, 3838 + borderBottomWidth: 1, 3839 + }, 3840 + settingInfo: { 3841 + flex: 1, 3842 + marginRight: 16, 3843 + }, 3844 + settingLabel: { 3845 + fontSize: 16, 3846 + fontFamily: 'Lexend_500Medium', 3847 + marginBottom: 4, 3848 + }, 3849 + settingDescription: { 3850 + fontSize: 14, 3851 + fontFamily: 'Lexend_400Regular', 3852 + lineHeight: 20, 3853 + }, 3854 + toggle: { 3855 + width: 50, 3856 + height: 30, 3857 + borderRadius: 15, 3858 + backgroundColor: '#666', 3859 + justifyContent: 'center', 3860 + padding: 2, 3861 + }, 3862 + toggleActive: { 3863 + backgroundColor: '#4D96FF', 3864 + }, 3865 + toggleThumb: { 3866 + width: 26, 3867 + height: 26, 3868 + borderRadius: 13, 3869 + backgroundColor: '#fff', 3870 + }, 3871 + toggleThumbActive: { 3872 + alignSelf: 'flex-end', 3775 3873 }, 3776 3874 });