package com.rosetta.messenger.data import android.content.Context import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.intPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.core.stringSetPreferencesKey import androidx.datastore.preferences.preferencesDataStore import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map private val Context.dataStore: DataStore by preferencesDataStore(name = "rosetta_preferences") class PreferencesManager(private val context: Context) { companion object { // Onboarding & Theme val HAS_SEEN_ONBOARDING = booleanPreferencesKey("has_seen_onboarding") val IS_DARK_THEME = booleanPreferencesKey("is_dark_theme") val THEME_MODE = stringPreferencesKey("theme_mode") // "light", "dark", "auto" // Notifications val NOTIFICATIONS_ENABLED = booleanPreferencesKey("notifications_enabled") val NOTIFICATION_SOUND_ENABLED = booleanPreferencesKey("notification_sound_enabled") val NOTIFICATION_VIBRATE_ENABLED = booleanPreferencesKey("notification_vibrate_enabled") val NOTIFICATION_PREVIEW_ENABLED = booleanPreferencesKey("notification_preview_enabled") // Chat Settings val MESSAGE_TEXT_SIZE = intPreferencesKey("message_text_size") // 0=small, 1=medium, 2=large val SEND_BY_ENTER = booleanPreferencesKey("send_by_enter") val AUTO_DOWNLOAD_PHOTOS = booleanPreferencesKey("auto_download_photos") val AUTO_DOWNLOAD_VIDEOS = booleanPreferencesKey("auto_download_videos") val AUTO_DOWNLOAD_FILES = booleanPreferencesKey("auto_download_files") // Privacy val SHOW_ONLINE_STATUS = booleanPreferencesKey("show_online_status") val SHOW_READ_RECEIPTS = booleanPreferencesKey("show_read_receipts") val SHOW_TYPING_INDICATOR = booleanPreferencesKey("show_typing_indicator") // Language val APP_LANGUAGE = stringPreferencesKey("app_language") // "en", "ru", etc. // Appearance / Customization val BACKGROUND_BLUR_COLOR_ID = stringPreferencesKey("background_blur_color_id") // id from BackgroundBlurPresets // Pinned Chats (max 3) val PINNED_CHATS = stringSetPreferencesKey("pinned_chats") // Set of opponent public keys } // ═════════════════════════════════════════════════════════════ // 🎨 ONBOARDING & THEME // ═════════════════════════════════════════════════════════════ val hasSeenOnboarding: Flow = context.dataStore.data.map { preferences -> preferences[HAS_SEEN_ONBOARDING] ?: false } val isDarkTheme: Flow = context.dataStore.data.map { preferences -> preferences[IS_DARK_THEME] ?: true // Default to dark theme like Telegram } suspend fun setHasSeenOnboarding(value: Boolean) { context.dataStore.edit { preferences -> preferences[HAS_SEEN_ONBOARDING] = value } } suspend fun setDarkTheme(value: Boolean) { context.dataStore.edit { preferences -> preferences[IS_DARK_THEME] = value } } val themeMode: Flow = context.dataStore.data.map { preferences -> preferences[THEME_MODE] ?: "dark" // Default to dark theme } suspend fun setThemeMode(value: String) { context.dataStore.edit { preferences -> preferences[THEME_MODE] = value } } // ═════════════════════════════════════════════════════════════ // 🔔 NOTIFICATIONS // ═════════════════════════════════════════════════════════════ val notificationsEnabled: Flow = context.dataStore.data.map { preferences -> preferences[NOTIFICATIONS_ENABLED] ?: true } val notificationSoundEnabled: Flow = context.dataStore.data.map { preferences -> preferences[NOTIFICATION_SOUND_ENABLED] ?: true } val notificationVibrateEnabled: Flow = context.dataStore.data.map { preferences -> preferences[NOTIFICATION_VIBRATE_ENABLED] ?: true } val notificationPreviewEnabled: Flow = context.dataStore.data.map { preferences -> preferences[NOTIFICATION_PREVIEW_ENABLED] ?: true } suspend fun setNotificationsEnabled(value: Boolean) { context.dataStore.edit { preferences -> preferences[NOTIFICATIONS_ENABLED] = value } } suspend fun setNotificationSoundEnabled(value: Boolean) { context.dataStore.edit { preferences -> preferences[NOTIFICATION_SOUND_ENABLED] = value } } suspend fun setNotificationVibrateEnabled(value: Boolean) { context.dataStore.edit { preferences -> preferences[NOTIFICATION_VIBRATE_ENABLED] = value } } suspend fun setNotificationPreviewEnabled(value: Boolean) { context.dataStore.edit { preferences -> preferences[NOTIFICATION_PREVIEW_ENABLED] = value } } // ═════════════════════════════════════════════════════════════ // 💬 CHAT SETTINGS // ═════════════════════════════════════════════════════════════ val messageTextSize: Flow = context.dataStore.data.map { preferences -> preferences[MESSAGE_TEXT_SIZE] ?: 1 // Default medium } val sendByEnter: Flow = context.dataStore.data.map { preferences -> preferences[SEND_BY_ENTER] ?: false } val autoDownloadPhotos: Flow = context.dataStore.data.map { preferences -> preferences[AUTO_DOWNLOAD_PHOTOS] ?: true } val autoDownloadVideos: Flow = context.dataStore.data.map { preferences -> preferences[AUTO_DOWNLOAD_VIDEOS] ?: false } val autoDownloadFiles: Flow = context.dataStore.data.map { preferences -> preferences[AUTO_DOWNLOAD_FILES] ?: false } suspend fun setMessageTextSize(value: Int) { context.dataStore.edit { preferences -> preferences[MESSAGE_TEXT_SIZE] = value } } suspend fun setSendByEnter(value: Boolean) { context.dataStore.edit { preferences -> preferences[SEND_BY_ENTER] = value } } suspend fun setAutoDownloadPhotos(value: Boolean) { context.dataStore.edit { preferences -> preferences[AUTO_DOWNLOAD_PHOTOS] = value } } suspend fun setAutoDownloadVideos(value: Boolean) { context.dataStore.edit { preferences -> preferences[AUTO_DOWNLOAD_VIDEOS] = value } } suspend fun setAutoDownloadFiles(value: Boolean) { context.dataStore.edit { preferences -> preferences[AUTO_DOWNLOAD_FILES] = value } } // ═════════════════════════════════════════════════════════════ // 🔐 PRIVACY // ═════════════════════════════════════════════════════════════ val showOnlineStatus: Flow = context.dataStore.data.map { preferences -> preferences[SHOW_ONLINE_STATUS] ?: true } val showReadReceipts: Flow = context.dataStore.data.map { preferences -> preferences[SHOW_READ_RECEIPTS] ?: true } val showTypingIndicator: Flow = context.dataStore.data.map { preferences -> preferences[SHOW_TYPING_INDICATOR] ?: true } suspend fun setShowOnlineStatus(value: Boolean) { context.dataStore.edit { preferences -> preferences[SHOW_ONLINE_STATUS] = value } } suspend fun setShowReadReceipts(value: Boolean) { context.dataStore.edit { preferences -> preferences[SHOW_READ_RECEIPTS] = value } } suspend fun setShowTypingIndicator(value: Boolean) { context.dataStore.edit { preferences -> preferences[SHOW_TYPING_INDICATOR] = value } } // ═════════════════════════════════════════════════════════════ // 🌐 LANGUAGE // ═════════════════════════════════════════════════════════════ val appLanguage: Flow = context.dataStore.data.map { preferences -> preferences[APP_LANGUAGE] ?: "en" // Default English } suspend fun setAppLanguage(value: String) { context.dataStore.edit { preferences -> preferences[APP_LANGUAGE] = value } } // ═════════════════════════════════════════════════════════════ // 🎨 APPEARANCE / CUSTOMIZATION // ═════════════════════════════════════════════════════════════ val backgroundBlurColorId: Flow = context.dataStore.data.map { preferences -> preferences[BACKGROUND_BLUR_COLOR_ID] ?: "avatar" // Default: use avatar blur } suspend fun setBackgroundBlurColorId(value: String) { context.dataStore.edit { preferences -> preferences[BACKGROUND_BLUR_COLOR_ID] = value } } // ═════════════════════════════════════════════════════════════ // 📌 PINNED CHATS // ═════════════════════════════════════════════════════════════ val pinnedChats: Flow> = context.dataStore.data.map { preferences -> preferences[PINNED_CHATS] ?: emptySet() } suspend fun setPinnedChats(value: Set) { context.dataStore.edit { preferences -> preferences[PINNED_CHATS] = value } } suspend fun togglePinChat(opponentKey: String): Boolean { var wasPinned = false context.dataStore.edit { preferences -> val current = preferences[PINNED_CHATS] ?: emptySet() if (current.contains(opponentKey)) { // Unpin preferences[PINNED_CHATS] = current - opponentKey wasPinned = true } else if (current.size < 3) { // Pin (max 3) preferences[PINNED_CHATS] = current + opponentKey } } return wasPinned } }