From 981fd9fe8f1cf8078598bca16915bd287f69edc4 Mon Sep 17 00:00:00 2001 From: Siddhesh Naik Date: Thu, 25 Apr 2024 05:07:10 +0530 Subject: [PATCH] Add Switch preferences component --- app/build.gradle | 9 ++++ app/src/main/java/org/schabi/newpipe/App.java | 2 + .../main/java/org/schabi/newpipe/AppModule.kt | 22 ++++++++ .../schabi/newpipe/settings/SettingsScreen.kt | 26 ++++++++++ .../newpipe/settings/SettingsV2Activity.kt | 11 ++-- .../settings/viewmodel/SettingsViewModel.kt | 39 ++++++++++++++ .../org/schabi/newpipe/ui/SwitchPreference.kt | 52 +++++++++++++++++++ build.gradle | 1 + 8 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/AppModule.kt create mode 100644 app/src/main/java/org/schabi/newpipe/settings/SettingsScreen.kt create mode 100644 app/src/main/java/org/schabi/newpipe/settings/viewmodel/SettingsViewModel.kt create mode 100644 app/src/main/java/org/schabi/newpipe/ui/SwitchPreference.kt diff --git a/app/build.gradle b/app/build.gradle index 5502025a7..c4c7f1f87 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,6 +9,7 @@ plugins { id "kotlin-parcelize" id "checkstyle" id "org.sonarqube" version "4.0.0.2929" + id 'com.google.dagger.hilt.android' } android { @@ -193,6 +194,10 @@ sonar { } } +kapt { + correctErrorTypes true +} + dependencies { /** Desugaring **/ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.0.4' @@ -295,6 +300,10 @@ dependencies { implementation 'androidx.activity:activity-compose' implementation 'androidx.compose.ui:ui-tooling-preview' + // Hilt + implementation("com.google.dagger:hilt-android:2.51.1") + kapt("com.google.dagger:hilt-compiler:2.51.1") + /** Debugging **/ // Memory leak detection debugImplementation "com.squareup.leakcanary:leakcanary-object-watcher-android:${leakCanaryVersion}" diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java index d92425d20..35be89489 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -32,6 +32,7 @@ import java.net.SocketException; import java.util.List; import java.util.Objects; +import dagger.hilt.android.HiltAndroidApp; import io.reactivex.rxjava3.exceptions.CompositeException; import io.reactivex.rxjava3.exceptions.MissingBackpressureException; import io.reactivex.rxjava3.exceptions.OnErrorNotImplementedException; @@ -57,6 +58,7 @@ import io.reactivex.rxjava3.plugins.RxJavaPlugins; * along with NewPipe. If not, see . */ +@HiltAndroidApp public class App extends Application { public static final String PACKAGE_NAME = BuildConfig.APPLICATION_ID; private static final String TAG = App.class.toString(); diff --git a/app/src/main/java/org/schabi/newpipe/AppModule.kt b/app/src/main/java/org/schabi/newpipe/AppModule.kt new file mode 100644 index 000000000..0aaf2f72b --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/AppModule.kt @@ -0,0 +1,22 @@ +package org.schabi.newpipe + +import android.content.Context +import android.content.SharedPreferences +import androidx.preference.PreferenceManager +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +class AppModule { + + @Provides + @Singleton + fun providesSharedPreference(@ApplicationContext context: Context): SharedPreferences { + return PreferenceManager.getDefaultSharedPreferences(context) + } +} diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingsScreen.kt b/app/src/main/java/org/schabi/newpipe/settings/SettingsScreen.kt new file mode 100644 index 000000000..bc2ace14b --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingsScreen.kt @@ -0,0 +1,26 @@ +package org.schabi.newpipe.settings + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import org.schabi.newpipe.R +import org.schabi.newpipe.settings.viewmodel.SettingsViewModel +import org.schabi.newpipe.ui.SwitchPreference + +@Composable +fun SettingsScreen(viewModel: SettingsViewModel, modifier: Modifier = Modifier) { + val settingsLayoutRedesign by viewModel.settingsLayoutRedesign.collectAsState() + + Column(modifier = modifier) { + SwitchPreference( + Modifier.padding(4.dp), + R.string.settings_layout_redesign, + settingsLayoutRedesign, + viewModel::toggleSettingsLayoutRedesign + ) + } +} diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingsV2Activity.kt b/app/src/main/java/org/schabi/newpipe/settings/SettingsV2Activity.kt index df1bade84..2830a21c6 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingsV2Activity.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingsV2Activity.kt @@ -3,17 +3,22 @@ package org.schabi.newpipe.settings import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.activity.viewModels import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import dagger.hilt.android.AndroidEntryPoint import org.schabi.newpipe.R +import org.schabi.newpipe.settings.viewmodel.SettingsViewModel import org.schabi.newpipe.ui.Toolbar import org.schabi.newpipe.ui.theme.AppTheme +@AndroidEntryPoint class SettingsV2Activity : ComponentActivity() { + private val settingsViewModel: SettingsViewModel by viewModels() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -26,8 +31,8 @@ class SettingsV2Activity : ComponentActivity() { onSearchQueryChange = null // TODO: Add suggestions logic ) }) { padding -> - Text( - text = "Settings", + SettingsScreen( + viewModel = settingsViewModel, modifier = Modifier.padding(padding) ) } diff --git a/app/src/main/java/org/schabi/newpipe/settings/viewmodel/SettingsViewModel.kt b/app/src/main/java/org/schabi/newpipe/settings/viewmodel/SettingsViewModel.kt new file mode 100644 index 000000000..6a25bf1cc --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/settings/viewmodel/SettingsViewModel.kt @@ -0,0 +1,39 @@ +package org.schabi.newpipe.settings.viewmodel + +import android.app.Application +import android.content.Context +import android.content.SharedPreferences +import androidx.core.content.ContextCompat +import androidx.lifecycle.AndroidViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import org.schabi.newpipe.R +import javax.inject.Inject + +@HiltViewModel +class SettingsViewModel @Inject constructor( + @ApplicationContext context: Context, + private val preferenceManager: SharedPreferences +) : + AndroidViewModel(context.applicationContext as Application) { + + private var _settingsLayoutRedesignPref: Boolean + get() = preferenceManager.getBoolean( + ContextCompat.getString(getApplication(), R.string.settings_layout_redesign_key), false + ) + set(value) { + preferenceManager.edit().putBoolean( + ContextCompat.getString(getApplication(), R.string.settings_layout_redesign_key), + value + ).apply() + } + private val _settingsLayoutRedesign: MutableStateFlow = MutableStateFlow(_settingsLayoutRedesignPref) + val settingsLayoutRedesign = _settingsLayoutRedesign.asStateFlow() + + fun toggleSettingsLayoutRedesign(newState: Boolean) { + _settingsLayoutRedesign.value = newState + _settingsLayoutRedesignPref = newState + } +} diff --git a/app/src/main/java/org/schabi/newpipe/ui/SwitchPreference.kt b/app/src/main/java/org/schabi/newpipe/ui/SwitchPreference.kt new file mode 100644 index 000000000..e83b783b3 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/ui/SwitchPreference.kt @@ -0,0 +1,52 @@ +package org.schabi.newpipe.ui + +import androidx.annotation.StringRes +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Switch +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp + +@Composable +fun SwitchPreference( + modifier: Modifier = Modifier, + @StringRes title: Int, + isChecked: Boolean, + onCheckedChange: (Boolean) -> Unit, + @StringRes summary: Int? = null +) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + modifier = modifier.fillMaxWidth() + ) { + Column { + Text( + text = stringResource(id = title), + modifier = Modifier.padding(4.dp), + fontWeight = FontWeight.Medium, + textAlign = TextAlign.Start, + ) + summary?.let { + Text( + text = stringResource(id = summary), + modifier = Modifier.padding(4.dp), + textAlign = TextAlign.Start, + ) + } + } + Spacer(modifier = Modifier.width(8.dp)) + Switch(checked = isChecked, onCheckedChange = onCheckedChange) + } +} diff --git a/build.gradle b/build.gradle index 6d19a6f8a..8adb5fd36 100644 --- a/build.gradle +++ b/build.gradle @@ -9,6 +9,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:8.2.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.google.dagger:hilt-android-gradle-plugin:2.51.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files