feat: Initial commit!
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
{
|
||||
{
|
||||
"setup": {
|
||||
"dialogs": {
|
||||
"select_language": "Select Language",
|
||||
"select_save_folder_button": "Select Folder",
|
||||
"save_folder": "SnapEnhance requires Storage permissions to download and Save Media from Snapchat.\nPlease choose the location where media should be downloaded to."
|
||||
"save_folder": "PurrfectSnap requires Storage permissions to download and Save Media from Snapchat.\nPlease choose the location where media should be downloaded to."
|
||||
},
|
||||
"mappings": {
|
||||
"generate_failure_no_snapchat": "SnapEnhance was unable to detect Snapchat, please try reinstalling Snapchat.",
|
||||
"generate_failure_no_snapchat": "PurrfectSnap was unable to detect Snapchat, please try reinstalling Snapchat.",
|
||||
"generate_failure": "An error occurred while trying to generate mappings, please try again.",
|
||||
"dialog": "Generating Mappings, this may take a while, please be patient..."
|
||||
},
|
||||
@@ -65,11 +65,11 @@
|
||||
"empty_hint": "(blank)"
|
||||
},
|
||||
"home": {
|
||||
"update_title": "SnapEnhance Update",
|
||||
"update_title": "PurrfectSnap Update",
|
||||
"update_button": "Download",
|
||||
"update_content": "Version {version} is Available!",
|
||||
"debug_build_summary_title": "You are running a debug build of SnapEnhance",
|
||||
"version_title": "v{versionName} · by rhunk",
|
||||
"debug_build_summary_title": "You are running a debug build of PurrfectSnap",
|
||||
"version_title": "v{versionName} · forked by Eternal",
|
||||
"debug_build_summary_date": "Build date: {date} ({days} days ago)",
|
||||
"debug_build_summary_content": "Version {versionName} ({versionCode})",
|
||||
"quick_actions_title": "Quick Actions"
|
||||
@@ -174,7 +174,7 @@
|
||||
},
|
||||
"scripting_warning": {
|
||||
"title": "Warning",
|
||||
"content": "SnapEnhance includes a scripting tool, allowing the execution of user-defined code on your device. Use extreme caution and only install modules from known, reliable sources. Unauthorised or unverified modules may pose security risks to your system."
|
||||
"content": "PurrfectSnap includes a scripting tool, allowing the execution of user-defined code on your device. Use extreme caution and only install modules from known, reliable sources. Unauthorised or unverified modules may pose security risks to your system."
|
||||
},
|
||||
"reset_config": {
|
||||
"title": "Reset config",
|
||||
@@ -287,7 +287,7 @@
|
||||
},
|
||||
"change_language": {
|
||||
"name": "Change Language",
|
||||
"description": "Change the Language of SnapEnhance"
|
||||
"description": "Change the Language of PurrfectSnap"
|
||||
},
|
||||
"logger_history": {
|
||||
"name": "Logger History",
|
||||
@@ -901,7 +901,7 @@
|
||||
},
|
||||
"composer_logs": {
|
||||
"name": "Composer Logs",
|
||||
"description": "Redirects console logs of Composer to SnapEnhance"
|
||||
"description": "Redirects console logs of Composer to PurrfectSnap"
|
||||
},
|
||||
"show_first_created_username": {
|
||||
"description": "Shows the first created username next to the current username in the profile page",
|
||||
@@ -1055,7 +1055,7 @@
|
||||
},
|
||||
"scripting": {
|
||||
"name": "Scripting",
|
||||
"description": "Run custom scripts to extend SnapEnhance",
|
||||
"description": "Run custom scripts to extend PurrfectSnap",
|
||||
"properties": {
|
||||
"developer_mode": {
|
||||
"name": "Developer Mode",
|
||||
@@ -1223,7 +1223,7 @@
|
||||
},
|
||||
"auto_reload": {
|
||||
"snapchat_only": "Snapchat Only",
|
||||
"all": "All (Snapchat + SnapEnhance)"
|
||||
"all": "All (Snapchat + PurrfectSnap)"
|
||||
},
|
||||
"edit_text_override": {
|
||||
"multi_line_chat_input": "Multi Line Chat Input",
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
{
|
||||
"setup": {
|
||||
"dialogs": {
|
||||
"select_language": "Select Language",
|
||||
"save_folder": "SnapEnhance requires Storage permissions to download and Save Media from Snapchat.\nPlease choose the location where media should be downloaded to.",
|
||||
"save_folder": "PurrfectSnap requires Storage permissions to download and Save Media from Snapchat.\nPlease choose the location where media should be downloaded to.",
|
||||
"select_save_folder_button": "Select Folder"
|
||||
},
|
||||
"mappings": {
|
||||
"dialog": "Generating Mappings, this may take a while ...",
|
||||
"generate_failure_no_snapchat": "SnapEnhance was unable to detect Snapchat, please try reinstalling Snapchat.",
|
||||
"generate_failure_no_snapchat": "PurrfectSnap was unable to detect Snapchat, please try reinstalling Snapchat.",
|
||||
"generate_failure": "An error occurred while trying to generate mappings, please try again."
|
||||
},
|
||||
"permissions": {
|
||||
@@ -46,11 +46,11 @@
|
||||
},
|
||||
"sections": {
|
||||
"home": {
|
||||
"version_title": "v{versionName} · by rhunk",
|
||||
"update_title": "SnapEnhance Update",
|
||||
"version_title": "v{versionName} · forked by Eternal",
|
||||
"update_title": "PurrfectSnap Update",
|
||||
"update_content": "Version {version} is available!",
|
||||
"update_button": "Download",
|
||||
"debug_build_summary_title": "You are running a debug build of SnapEnhance",
|
||||
"debug_build_summary_title": "You are running a debug build of PurrfectSnap",
|
||||
"debug_build_summary_content": "Version {versionName} ({versionCode})",
|
||||
"debug_build_summary_date": "Build date: {date} ({days} days ago)",
|
||||
"quick_actions_title": "Quick Actions"
|
||||
@@ -71,7 +71,13 @@
|
||||
"message_logger_summary": "{messageCount} messages\n{storyCount} stories",
|
||||
"export_button": "Export",
|
||||
"clear_button": "Clear",
|
||||
"view_logger_history_button": "View Logger History"
|
||||
"view_logger_history_button": "View Logger History",
|
||||
"updates_title": "Updates",
|
||||
"auto_update_check": "Auto check for updates",
|
||||
"update_check_frequency": "Update check frequency",
|
||||
"update_check_frequency_daily": "Daily",
|
||||
"update_check_frequency_weekly": "Weekly",
|
||||
"update_check_frequency_monthly": "Monthly"
|
||||
},
|
||||
"tasks": {
|
||||
"no_tasks": "No tasks",
|
||||
@@ -200,7 +206,7 @@
|
||||
},
|
||||
"scripting_warning": {
|
||||
"title": "Warning",
|
||||
"content": "SnapEnhance includes a scripting tool, allowing the execution of user-defined code on your device. Use extreme caution and only install modules from known, reliable sources. Unauthorized or unverified modules may pose security risks to your system."
|
||||
"content": "PurrfectSnap includes a scripting tool, allowing the execution of user-defined code on your device. Use extreme caution and only install modules from known, reliable sources. Unauthorized or unverified modules may pose security risks to your system."
|
||||
},
|
||||
"reset_config": {
|
||||
"title": "Reset config",
|
||||
@@ -314,7 +320,7 @@
|
||||
},
|
||||
"change_language": {
|
||||
"name": "Change Language",
|
||||
"description": "Change the language of SnapEnhance"
|
||||
"description": "Change the language of PurrfectSnap"
|
||||
},
|
||||
"file_imports": {
|
||||
"name": "File Imports",
|
||||
@@ -469,6 +475,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"force_amoled_theme": {
|
||||
"name": "Amoled Dark Mode",
|
||||
"description": "Uses a true black background for the dark theme"
|
||||
},
|
||||
"map_friend_nametags": {
|
||||
"name": "Enhanced Friend Map Nametags",
|
||||
"description": "Improves the Nametags of friends on the Snapmap"
|
||||
@@ -544,6 +554,14 @@
|
||||
"prevent_forced_keyboard": {
|
||||
"name": "Prevent Forced Keyboard",
|
||||
"description": "Prevents Snapchat from automatically popping up the keyboard when you open a conversation"
|
||||
},
|
||||
"settings_menu": {
|
||||
"name": "Settings Menu",
|
||||
"description": "Changes the way you open the PurrfectSnap menu",
|
||||
"options": {
|
||||
"default": "Default",
|
||||
"legacy": "Legacy"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -979,7 +997,7 @@
|
||||
},
|
||||
"composer_logs": {
|
||||
"name": "Composer Logs",
|
||||
"description": "Redirects console logs of Composer to SnapEnhance"
|
||||
"description": "Redirects console logs of Composer to PurrfectSnap"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1139,7 +1157,7 @@
|
||||
},
|
||||
"scripting": {
|
||||
"name": "Scripting",
|
||||
"description": "Run custom scripts to extend SnapEnhance",
|
||||
"description": "Run custom scripts to extend PurrfectSnap",
|
||||
"properties": {
|
||||
"developer_mode": {
|
||||
"name": "Developer Mode",
|
||||
@@ -1305,7 +1323,7 @@
|
||||
},
|
||||
"auto_reload": {
|
||||
"snapchat_only": "Snapchat Only",
|
||||
"all": "All (Snapchat + SnapEnhance)"
|
||||
"all": "All (Snapchat + PurrfectSnap)"
|
||||
},
|
||||
"edit_text_override": {
|
||||
"multi_line_chat_input": "Multi Line Chat Input",
|
||||
|
||||
@@ -56,4 +56,16 @@ class Global : ConfigContainer() {
|
||||
val disableTelecomFramework = boolean("disable_telecom_framework") { requireRestart() }
|
||||
val hideActiveMusic = boolean("hide_active_music") { requireRestart() }
|
||||
val disableSnapSplitting = boolean("disable_snap_splitting") { addNotices(FeatureNotice.UNSTABLE) }
|
||||
}
|
||||
|
||||
inner class UpdateSettings : ConfigContainer() {
|
||||
val autoUpdateCheck = boolean("auto_update_check")
|
||||
val updateCheckFrequency = unique("update_check_frequency", "daily", "weekly", "monthly")
|
||||
}
|
||||
|
||||
inner class UISettings : ConfigContainer() {
|
||||
val hapticFeedback = boolean("haptic_feedback", true)
|
||||
}
|
||||
|
||||
val updateSettings = container("update_settings", UpdateSettings()) { addFlags(ConfigFlag.HIDDEN) }
|
||||
val uiSettings = container("ui_settings", UISettings()) { addFlags(ConfigFlag.HIDDEN) }
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ class UserInterfaceTweaks : ConfigContainer() {
|
||||
val friendFeedMessagePreview = container("friend_feed_message_preview", FriendFeedMessagePreview()) { requireRestart() }
|
||||
val snapPreview = boolean("snap_preview") { addNotices(FeatureNotice.UNSTABLE); requireRestart() }
|
||||
val bootstrapOverride = container("bootstrap_override", BootstrapOverride()) { requireRestart() }
|
||||
val forceAmoledTheme = boolean("force_amoled_theme") { requireRestart() }
|
||||
val mapFriendNameTags = boolean("map_friend_nametags") { requireRestart() }
|
||||
val preventMessageListAutoScroll = boolean("prevent_message_list_auto_scroll") { requireRestart(); addNotices(FeatureNotice.UNSTABLE) }
|
||||
val streakExpirationInfo = boolean("streak_expiration_info") { requireRestart() }
|
||||
@@ -58,4 +59,5 @@ class UserInterfaceTweaks : ConfigContainer() {
|
||||
requireRestart(); addNotices(FeatureNotice.BAN_RISK, FeatureNotice.INTERNAL_BEHAVIOR)
|
||||
}
|
||||
val preventForcedKeyboard = boolean("prevent_forced_keyboard") { requireRestart() }
|
||||
val settingsMenu = unique("settings_menu", "default", "legacy") { requireRestart() }.apply { set("default") }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package me.rhunk.snapenhance.common.data
|
||||
|
||||
enum class ExportType {
|
||||
BULK,
|
||||
SINGLE
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package me.rhunk.snapenhance.common.data
|
||||
|
||||
data class ExportedTrackerData(
|
||||
val type: ExportType,
|
||||
val rules: List<TrackerRule>
|
||||
)
|
||||
@@ -150,6 +150,9 @@ data class TrackerRule(
|
||||
val id: Int,
|
||||
val enabled: Boolean,
|
||||
val name: String,
|
||||
val author: String? = null,
|
||||
val events: List<TrackerRuleEvent>? = null,
|
||||
val scopes: Map<String, TrackerScopeType>? = null
|
||||
): Parcelable
|
||||
|
||||
@Parcelize
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package me.rhunk.snapenhance.common.data
|
||||
|
||||
interface TrackerDataManager {
|
||||
fun getExportedTrackerData(): ExportedTrackerData
|
||||
fun getExportedTrackerData(ruleId: Int): ExportedTrackerData?
|
||||
fun importTrackerData(data: ExportedTrackerData)
|
||||
}
|
||||
@@ -10,7 +10,9 @@ private val rhinoAndroidHelper = RhinoAndroidHelper(null as File?)
|
||||
fun contextScope(shouldOptimize: Boolean = false, f: Context.() -> Any?): Any? {
|
||||
val context = rhinoAndroidHelper.enterContext().apply {
|
||||
languageVersion = Context.VERSION_ES6
|
||||
optimizationLevel = if (!shouldOptimize) -1 else 0
|
||||
// Deprecated: optimizationLevel. No longer set in new Rhino/Java.
|
||||
// If you have a modern way to tweak optimization, use it here.
|
||||
// optimizationLevel = if (!shouldOptimize) -1 else 0 <-- REMOVE THIS LINE
|
||||
}
|
||||
try {
|
||||
return context.f().let {
|
||||
@@ -49,7 +51,7 @@ fun ScriptableObject.putFunction(name: String, proxy: Scriptable.(Array<out Any?
|
||||
}
|
||||
|
||||
fun scriptableObject(name: String? = "ScriptableObject", f: ScriptableObject.() -> Unit): ScriptableObject {
|
||||
return object: ScriptableObject() {
|
||||
return object : ScriptableObject() {
|
||||
override fun getClassName() = name
|
||||
}.apply(f)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,14 @@ package me.rhunk.snapenhance.common.ui
|
||||
|
||||
import android.os.Build
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.material3.dynamicLightColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
// ---------- Light color palette ----------
|
||||
val md_theme_light_primary = Color(0xFF6750A4)
|
||||
val md_theme_light_onPrimary = Color(0xFFFFFFFF)
|
||||
val md_theme_light_primaryContainer = Color(0xFFE9DDFF)
|
||||
@@ -40,6 +40,7 @@ val md_theme_light_surfaceTint = Color(0xFF6750A4)
|
||||
val md_theme_light_outlineVariant = Color(0xFFCAC4CF)
|
||||
val md_theme_light_scrim = Color(0xFF000000)
|
||||
|
||||
// ---------- Dark color palette ----------
|
||||
val md_theme_dark_primary = Color(0xFFCFBCFF)
|
||||
val md_theme_dark_onPrimary = Color(0xFF381E72)
|
||||
val md_theme_dark_primaryContainer = Color(0xFF4F378A)
|
||||
@@ -70,10 +71,13 @@ val md_theme_dark_surfaceTint = Color(0xFFCFBCFF)
|
||||
val md_theme_dark_outlineVariant = Color(0xFF49454E)
|
||||
val md_theme_dark_scrim = Color(0xFF000000)
|
||||
|
||||
// ---------- AMOLED (true black dark) palette (only crucial overrides) ----------
|
||||
val md_theme_amoled_background = Color(0xFF000000)
|
||||
val md_theme_amoled_surface = Color(0xFF000000)
|
||||
val md_theme_amoled_onBackground = Color(0xFFE6E1E6)
|
||||
val md_theme_amoled_onSurface = Color(0xFFE6E1E6)
|
||||
|
||||
val seed = Color(0xFF6750A4)
|
||||
|
||||
|
||||
// Material3 ColorScheme for light theme
|
||||
private val LightThemeColors = lightColorScheme(
|
||||
primary = md_theme_light_primary,
|
||||
onPrimary = md_theme_light_onPrimary,
|
||||
@@ -106,7 +110,8 @@ private val LightThemeColors = lightColorScheme(
|
||||
scrim = md_theme_light_scrim
|
||||
)
|
||||
|
||||
private val DarkThemeColors = lightColorScheme(
|
||||
// Material3 ColorScheme for dark theme
|
||||
private val DarkThemeColors = darkColorScheme(
|
||||
primary = md_theme_dark_primary,
|
||||
onPrimary = md_theme_dark_onPrimary,
|
||||
primaryContainer = md_theme_dark_primaryContainer,
|
||||
@@ -141,22 +146,41 @@ private val DarkThemeColors = lightColorScheme(
|
||||
@Composable
|
||||
fun AppMaterialTheme(
|
||||
isDarkTheme: Boolean = isSystemInDarkTheme(),
|
||||
themeMode: ThemeMode? = null,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val dynamicColor = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||
val colorScheme = when {
|
||||
dynamicColor && isDarkTheme -> {
|
||||
dynamicDarkColorScheme(LocalContext.current)
|
||||
val effectiveThemeMode = themeMode ?: if (isDarkTheme) ThemeMode.DARK else ThemeMode.LIGHT
|
||||
val colorScheme = when (effectiveThemeMode) {
|
||||
ThemeMode.AMOLED -> {
|
||||
val baseScheme = if (dynamicColor) dynamicDarkColorScheme(context) else DarkThemeColors
|
||||
baseScheme.copy(
|
||||
background = md_theme_amoled_background,
|
||||
onBackground = md_theme_amoled_onBackground,
|
||||
surface = md_theme_amoled_surface,
|
||||
onSurface = md_theme_amoled_onSurface
|
||||
)
|
||||
}
|
||||
dynamicColor && !isDarkTheme -> {
|
||||
dynamicLightColorScheme(LocalContext.current)
|
||||
ThemeMode.DARK -> if (dynamicColor) dynamicDarkColorScheme(context) else DarkThemeColors
|
||||
ThemeMode.LIGHT -> if (dynamicColor) dynamicLightColorScheme(context) else LightThemeColors
|
||||
ThemeMode.SYSTEM -> when {
|
||||
isSystemInDarkTheme() && dynamicColor -> dynamicDarkColorScheme(context)
|
||||
!isSystemInDarkTheme() && dynamicColor -> dynamicLightColorScheme(context)
|
||||
isSystemInDarkTheme() -> DarkThemeColors
|
||||
else -> LightThemeColors
|
||||
}
|
||||
!isDarkTheme -> LightThemeColors
|
||||
else -> DarkThemeColors
|
||||
}
|
||||
|
||||
val shapes = Shapes(
|
||||
extraSmall = RoundedCornerShape(24.dp),
|
||||
small = RoundedCornerShape(24.dp),
|
||||
medium = RoundedCornerShape(24.dp),
|
||||
large = RoundedCornerShape(24.dp),
|
||||
extraLarge = RoundedCornerShape(24.dp)
|
||||
)
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme,
|
||||
shapes = shapes,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package me.rhunk.snapenhance.common.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Brightness4
|
||||
import androidx.compose.material.icons.filled.DarkMode
|
||||
import androidx.compose.material.icons.filled.LightMode
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.InvertColors // AMOLED icon
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun ThemeChooserDialog(
|
||||
selected: ThemeMode,
|
||||
onSelect: (ThemeMode) -> Unit,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
confirmButton = {},
|
||||
title = {
|
||||
Text("Choose App Theme", style = MaterialTheme.typography.titleMedium)
|
||||
},
|
||||
text = {
|
||||
Column {
|
||||
ThemeMode.values().forEachIndexed { idx, mode ->
|
||||
val (icon, label) = when (mode) {
|
||||
ThemeMode.LIGHT -> Icons.Filled.LightMode to "Light"
|
||||
ThemeMode.DARK -> Icons.Filled.DarkMode to "Dark"
|
||||
ThemeMode.SYSTEM -> Icons.Filled.Brightness4 to "System Default"
|
||||
ThemeMode.AMOLED -> Icons.Filled.InvertColors to "AMOLED"
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable {
|
||||
onSelect(mode)
|
||||
onDismiss()
|
||||
}
|
||||
.background(
|
||||
if (mode == selected) MaterialTheme.colorScheme.secondary.copy(alpha = 0.12f)
|
||||
else MaterialTheme.colorScheme.surface,
|
||||
MaterialTheme.shapes.small
|
||||
)
|
||||
.padding(12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = label,
|
||||
tint = if (mode == selected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface,
|
||||
modifier = Modifier.size(28.dp)
|
||||
)
|
||||
Spacer(Modifier.width(20.dp))
|
||||
Text(label, color = if (mode == selected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface)
|
||||
Spacer(Modifier.weight(1f))
|
||||
if (mode == selected) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Check,
|
||||
contentDescription = "Selected",
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
// Add a spacer between all buttons except the last
|
||||
if (idx < ThemeMode.values().lastIndex) Spacer(Modifier.height(8.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package me.rhunk.snapenhance.common.ui
|
||||
|
||||
enum class ThemeMode(val displayName: String) {
|
||||
SYSTEM("System Default"),
|
||||
LIGHT("Light"),
|
||||
DARK("Dark"),
|
||||
AMOLED("AMOLED")
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package me.rhunk.snapenhance.common.ui
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
val Context.themeDataStore by preferencesDataStore("theme_prefs")
|
||||
|
||||
object ThemePreferences {
|
||||
private val THEME_KEY = stringPreferencesKey("theme_mode")
|
||||
|
||||
fun getThemeModeFlow(context: Context): Flow<ThemeMode> =
|
||||
context.themeDataStore.data.map { prefs ->
|
||||
when (prefs[THEME_KEY]) {
|
||||
ThemeMode.LIGHT.name -> ThemeMode.LIGHT
|
||||
ThemeMode.DARK.name -> ThemeMode.DARK
|
||||
ThemeMode.AMOLED.name -> ThemeMode.AMOLED
|
||||
else -> ThemeMode.SYSTEM
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun setThemeMode(context: Context, mode: ThemeMode) {
|
||||
context.themeDataStore.edit { it[THEME_KEY] = mode.name }
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,8 @@ object SQLiteDatabaseHelper {
|
||||
}
|
||||
cursor.close()
|
||||
|
||||
val newColumns = columns.filter {
|
||||
existingColumns.none { existingColumn -> it.startsWith(existingColumn) }
|
||||
val newColumns = columns.filter { column ->
|
||||
!column.uppercase().startsWith("PRIMARY KEY") && existingColumns.none { existingColumn -> column.startsWith(existingColumn) }
|
||||
}
|
||||
|
||||
if (newColumns.isEmpty()) return@forEach
|
||||
|
||||
Reference in New Issue
Block a user