Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/.name

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions app/src/main/kotlin/com/example/aisecretary/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.appcompat.app.AppCompatDelegate
import com.example.aisecretary.settings.SettingsManager
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class MainActivity : AppCompatActivity() {

Expand All @@ -19,6 +25,18 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

// Apply dark mode setting
val settingsManager = SettingsManager(applicationContext)
CoroutineScope(Dispatchers.Main).launch {
settingsManager.darkModeEnabled.collectLatest { enabled ->
if (enabled) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
}
}
}

// Setup toolbar
setSupportActionBar(findViewById(R.id.toolbar))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ class SettingsManager(context: Context) {
)
val autoActivateMic: StateFlow<Boolean> = _autoActivateMic.asStateFlow()

// Dark mode setting
private val _darkModeEnabled = MutableStateFlow(
preferences.getBoolean(KEY_DARK_MODE_ENABLED, false)
)
val darkModeEnabled: StateFlow<Boolean> = _darkModeEnabled.asStateFlow()

fun isMemoryEnabled(): Boolean {
return preferences.getBoolean(KEY_MEMORY_ENABLED, true)
}
Expand Down Expand Up @@ -72,11 +78,21 @@ class SettingsManager(context: Context) {
_autoActivateMic.value = enabled
}

fun isDarkModeEnabled(): Boolean {
return preferences.getBoolean(KEY_DARK_MODE_ENABLED, false)
}

fun setDarkModeEnabled(enabled: Boolean) {
preferences.edit().putBoolean(KEY_DARK_MODE_ENABLED, enabled).apply()
_darkModeEnabled.value = enabled
}

companion object {
private const val PREFS_NAME = "secretary_settings"
private const val KEY_MEMORY_ENABLED = "memory_enabled"
private const val KEY_VOICE_OUTPUT_ENABLED = "voice_output_enabled"
private const val KEY_WAKE_WORD_ENABLED = "wake_word_enabled"
private const val KEY_AUTO_ACTIVATE_MIC = "auto_activate_mic"
private const val KEY_DARK_MODE_ENABLED = "dark_mode_enabled"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class SettingsFragment : Fragment() {
private lateinit var switchMemoryStorage: SwitchMaterial
private lateinit var switchWakeWord: SwitchMaterial
private lateinit var switchAutoActivateMic: SwitchMaterial
private lateinit var switchDarkMode: SwitchMaterial
private lateinit var buttonSaveSettings: Button

override fun onCreateView(
Expand All @@ -42,6 +43,7 @@ class SettingsFragment : Fragment() {
switchMemoryStorage = view.findViewById(R.id.switch_memory_storage)
switchWakeWord = view.findViewById(R.id.switch_wake_word)
switchAutoActivateMic = view.findViewById(R.id.switch_auto_activate_mic)
switchDarkMode = view.findViewById(R.id.switch_dark_mode)
buttonSaveSettings = view.findViewById(R.id.button_save_settings)

setupListeners()
Expand All @@ -66,6 +68,10 @@ class SettingsFragment : Fragment() {
viewModel.setAutoActivateMicEnabled(isChecked)
}

switchDarkMode.setOnCheckedChangeListener { _, isChecked ->
viewModel.setDarkModeEnabled(isChecked)
}

buttonSaveSettings.setOnClickListener {
viewModel.saveSettings()
}
Expand Down Expand Up @@ -104,6 +110,14 @@ class SettingsFragment : Fragment() {
}
}

viewLifecycleOwner.lifecycleScope.launch {
viewModel.darkModeEnabled.collectLatest { enabled ->
if (switchDarkMode.isChecked != enabled) {
switchDarkMode.isChecked = enabled
}
}
}

viewLifecycleOwner.lifecycleScope.launch {
viewModel.settingsUpdated.collectLatest { updated ->
if (updated) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
private val _autoActivateMicEnabled = MutableStateFlow(settingsManager.isAutoActivateMicEnabled())
val autoActivateMicEnabled: StateFlow<Boolean> = _autoActivateMicEnabled.asStateFlow()

private val _darkModeEnabled = MutableStateFlow(settingsManager.isDarkModeEnabled())
val darkModeEnabled: StateFlow<Boolean> = _darkModeEnabled.asStateFlow()

private val _settingsUpdated = MutableStateFlow(false)
val settingsUpdated: StateFlow<Boolean> = _settingsUpdated.asStateFlow()

Expand Down Expand Up @@ -66,6 +69,12 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
_autoActivateMicEnabled.value = it
}
}

viewModelScope.launch {
settingsManager.darkModeEnabled.collectLatest {
_darkModeEnabled.value = it
}
}
}

fun setVoiceInputEnabled(enabled: Boolean) {
Expand All @@ -87,13 +96,18 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
fun setAutoActivateMicEnabled(enabled: Boolean) {
_autoActivateMicEnabled.value = enabled
}

fun setDarkModeEnabled(enabled: Boolean) {
_darkModeEnabled.value = enabled
}

fun saveSettings() {
settingsManager.setVoiceOutputEnabled(_voiceInputEnabled.value)
settingsManager.setVoiceOutputEnabled(_voiceOutputEnabled.value)
settingsManager.setMemoryEnabled(_memoryEnabled.value)
settingsManager.setWakeWordEnabled(_wakeWordEnabled.value)
settingsManager.setAutoActivateMicEnabled(_autoActivateMicEnabled.value)
settingsManager.setDarkModeEnabled(_darkModeEnabled.value)
_settingsUpdated.value = true
}

Expand Down
38 changes: 37 additions & 1 deletion app/src/main/res/layout/fragment_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,42 @@
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

<!-- Display Settings Card -->
<com.google.android.material.card.MaterialCardView
android:id="@+id/card_display_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:cardCornerRadius="12dp"
app:cardElevation="4dp"
app:layout_constraintTop_toBottomOf="@id/card_memory_settings"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/display_settings"
android:textSize="18sp"
android:textStyle="bold"
android:textColor="@color/primaryColor"
android:paddingBottom="8dp" />

<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/switch_dark_mode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/activate_dark_mode"
android:padding="8dp" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

<com.google.android.material.button.MaterialButton
android:id="@+id/button_save_settings"
android:layout_width="match_parent"
Expand All @@ -140,7 +176,7 @@
android:textSize="16sp"
app:cornerRadius="8dp"
app:elevation="4dp"
app:layout_constraintTop_toBottomOf="@id/card_memory_settings"
app:layout_constraintTop_toBottomOf="@id/card_display_settings"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

Expand Down
43 changes: 43 additions & 0 deletions app/src/main/res/values-night/colors.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Primary brand colors (unchanged) -->
<color name="primaryColor">#4F46E5</color>
<color name="primaryVariant">#3730A3</color>
<color name="primaryLight">#818CF8</color>
<!-- Secondary accent colors (unchanged) -->
<color name="secondaryColor">#0EA5E9</color>
<color name="secondaryVariant">#0284C7</color>
<color name="secondaryLight">#38BDF8</color>
<!-- Dark mode backgrounds -->
<color name="backgroundColor">#1F2937</color>
<color name="surfaceColor">#111827</color>
<color name="backgroundDark">#1F2937</color>
<color name="surfaceDark">#111827</color>
<color name="background">#121212</color>
<!-- Text colors for dark mode -->
<color name="textPrimary">#F3F4F6</color>
<color name="textSecondary">#9CA3AF</color>
<color name="textTertiary">#6B7280</color>
<color name="textOnPrimary">#FFFFFF</color>
<color name="textOnSecondary">#FFFFFF</color>
<!-- Status colors (unchanged) -->
<color name="success">#10B981</color>
<color name="warning">#F59E0B</color>
<color name="error">#EF4444</color>
<color name="errorColor">#EF4444</color>
<color name="info">#3B82F6</color>
<!-- Chat message colors for dark mode -->
<color name="userMessageBackground">#4F46E5</color>
<color name="assistantMessageBackground">#23272F</color>
<color name="userMessageText">#FFFFFF</color>
<color name="assistantMessageText">#F3F4F6</color>
<!-- Legacy colors for backward compatibility (unchanged) -->
<color name="purple_200">#818CF8</color>
<color name="purple_500">#4F46E5</color>
<color name="purple_700">#3730A3</color>
<color name="teal_200">#38BDF8</color>
<color name="teal_700">#0284C7</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="ic_launcher_background">#111827</color>
</resources>
60 changes: 60 additions & 0 deletions app/src/main/res/values-night/themes.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Base application theme for dark mode -->
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand colors -->
<item name="colorPrimary">@color/primaryColor</item>
<item name="colorPrimaryVariant">@color/primaryVariant</item>
<item name="colorOnPrimary">@color/textOnPrimary</item>
<!-- Secondary brand colors -->
<item name="colorSecondary">@color/secondaryColor</item>
<item name="colorSecondaryVariant">@color/secondaryVariant</item>
<item name="colorOnSecondary">@color/textOnSecondary</item>
<!-- Status bar and navigation colors -->
<item name="android:statusBarColor">@color/primaryVariant</item>
<item name="android:navigationBarColor">@color/surfaceColor</item>
<item name="android:windowLightNavigationBar">false</item>
<!-- Background colors for dark mode -->
<item name="android:windowBackground">@color/backgroundColor</item>
<item name="colorSurface">@color/surfaceColor</item>
<item name="colorOnSurface">@color/textPrimary</item>
<!-- Text colors for dark mode -->
<item name="android:textColorPrimary">@color/textPrimary</item>
<item name="android:textColorSecondary">@color/textSecondary</item>
<!-- Shape customization -->
<item name="shapeAppearanceSmallComponent">@style/ShapeAppearance.App.SmallComponent</item>
<item name="shapeAppearanceMediumComponent">@style/ShapeAppearance.App.MediumComponent</item>
<item name="shapeAppearanceLargeComponent">@style/ShapeAppearance.App.LargeComponent</item>
<!-- Button styling -->
<item name="materialButtonStyle">@style/Widget.App.Button</item>
<item name="textInputStyle">@style/Widget.App.TextInputLayout</item>
</style>
<!-- Shape appearances (same as light) -->
<style name="ShapeAppearance.App.SmallComponent" parent="ShapeAppearance.MaterialComponents.SmallComponent">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">8dp</item>
</style>
<style name="ShapeAppearance.App.MediumComponent" parent="ShapeAppearance.MaterialComponents.MediumComponent">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">12dp</item>
</style>
<style name="ShapeAppearance.App.LargeComponent" parent="ShapeAppearance.MaterialComponents.LargeComponent">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">16dp</item>
</style>
<!-- Button style (same as light) -->
<style name="Widget.App.Button" parent="Widget.MaterialComponents.Button">
<item name="android:textColor">@color/textOnPrimary</item>
<item name="android:padding">12dp</item>
<item name="android:textStyle">bold</item>
<item name="cornerRadius">24dp</item>
<item name="elevation">2dp</item>
</style>
<!-- Text Input style (same as light) -->
<style name="Widget.App.TextInputLayout" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<item name="boxCornerRadiusBottomEnd">12dp</item>
<item name="boxCornerRadiusBottomStart">12dp</item>
<item name="boxCornerRadiusTopEnd">12dp</item>
<item name="boxCornerRadiusTopStart">12dp</item>
</style>
</resources>
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@
<string name="auto_activate_mic">Auto-activate microphone after speaking</string>
<string name="auto_activate_mic_description">Automatically start listening after Astra finishes speaking</string>
<string name="cancel">Cancel</string>
<string name="activate_dark_mode">Activate Dark Mode</string>
<string name="display_settings">Display Settings</string>
</resources>
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ android.nonTransitiveRClass=true
# Suppress unsupported compileSdk warning
android.suppressUnsupportedCompileSdk=34

# Use JDK 17 for the build
org.gradle.java.home=/usr/lib/jvm/java-17-openjdk
# Use JDK 17 + upwards for the build
org.gradle.java.home=C\:\\Program Files\\Eclipse Adoptium\\jdk-17.0.16.8-hotspot