mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-30 23:03:00 +00:00 
			
		
		
		
	Settings redesign debug page (#10876)
Initial Work for Settings Page with Jetpack Compose - Implemented a new settings page using Jetpack Compose. - Added a new settings option to enable the redesigned settings page. - This option allows for gradual integration and testing of the new settings page, minimizing disruptions to current functionality. Plan for Settings Items: - Jetpack Compose does not have a direct equivalent to the Preference/settings library. - We could consider using third-party libraries that offer preference items as composables. - However, these libraries may be incomplete or lack active development. - Given our specific needs for only a subset of preference types, creating custom composables would be beneficial. - This approach allows for fine-tuning the components to our specific use case.
This commit is contained in:
		| @@ -10,6 +10,7 @@ plugins { | ||||
|     id "checkstyle" | ||||
|     id "org.sonarqube" version "4.0.0.2929" | ||||
|     id "org.jetbrains.kotlin.plugin.compose" version "${kotlin_version}" | ||||
|     id 'com.google.dagger.hilt.android' | ||||
| } | ||||
|  | ||||
| android { | ||||
| @@ -190,6 +191,10 @@ sonar { | ||||
|     } | ||||
| } | ||||
|  | ||||
| kapt { | ||||
|     correctErrorTypes true | ||||
| } | ||||
|  | ||||
| dependencies { | ||||
| /** Desugaring **/ | ||||
|     coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.0.4' | ||||
| @@ -200,7 +205,7 @@ dependencies { | ||||
|     // name and the commit hash with the commit hash of the (pushed) commit you want to test | ||||
|     // This works thanks to JitPack: https://jitpack.io/ | ||||
|     implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' | ||||
|     implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.24.2' | ||||
|     implementation 'com.github.teamnewpipe:newpipeextractor:v0.24.2' | ||||
|     implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' | ||||
|  | ||||
| /** Checkstyle **/ | ||||
| @@ -285,20 +290,29 @@ dependencies { | ||||
|     // Date and time formatting | ||||
|     implementation "org.ocpsoft.prettytime:prettytime:5.0.8.Final" | ||||
|  | ||||
|     // Jetpack Compose | ||||
|     implementation(platform('androidx.compose:compose-bom:2024.06.00')) | ||||
|     implementation 'androidx.compose.material3:material3:1.3.0-beta05' | ||||
|     implementation 'androidx.compose.material3.adaptive:adaptive:1.0.0-beta04' | ||||
|     implementation 'androidx.activity:activity-compose' | ||||
|     // Jetpack Compose BOM group | ||||
|     implementation(platform('androidx.compose:compose-bom:2024.09.03')) | ||||
|     implementation 'androidx.compose.material3:material3' | ||||
|     implementation 'androidx.compose.ui:ui-tooling-preview' | ||||
|     implementation 'androidx.compose.ui:ui-text:1.7.0-beta07' // Needed for parsing HTML to AnnotatedString | ||||
|     implementation 'androidx.lifecycle:lifecycle-viewmodel-compose' | ||||
|     implementation 'androidx.compose.ui:ui-text' // Needed for parsing HTML to AnnotatedString | ||||
|  | ||||
|     // Jetpack Compose related dependencies | ||||
|     implementation 'androidx.compose.material3.adaptive:adaptive:1.0.0' | ||||
|     implementation 'androidx.activity:activity-compose:1.9.2' | ||||
|     implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.8.6' | ||||
|     implementation 'androidx.paging:paging-compose:3.3.2' | ||||
|     implementation 'com.github.nanihadesuka:LazyColumnScrollbar:2.2.0' | ||||
|     implementation "androidx.navigation:navigation-compose:2.8.2" | ||||
|  | ||||
|     // Coroutines interop | ||||
|     implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-rx3:1.8.1' | ||||
|  | ||||
|     // Hilt | ||||
|     implementation("com.google.dagger:hilt-android:2.51.1") | ||||
|     kapt("com.google.dagger:hilt-compiler:2.51.1") | ||||
|  | ||||
|     // Scroll | ||||
|     implementation 'com.github.nanihadesuka:LazyColumnScrollbar:2.2.0' | ||||
|  | ||||
| /** Debugging **/ | ||||
|     // Memory leak detection | ||||
|     debugImplementation "com.squareup.leakcanary:leakcanary-object-watcher-android:${leakCanaryVersion}" | ||||
|   | ||||
| @@ -77,6 +77,11 @@ | ||||
|             android:exported="false" | ||||
|             android:label="@string/settings" /> | ||||
|  | ||||
|         <activity | ||||
|             android:name=".settings.SettingsV2Activity" | ||||
|             android:exported="true" | ||||
|             android:label="@string/settings" /> | ||||
|  | ||||
|         <activity | ||||
|             android:name=".about.AboutActivity" | ||||
|             android:exported="false" | ||||
|   | ||||
| @@ -36,6 +36,7 @@ import java.util.Objects; | ||||
| import coil.ImageLoader; | ||||
| import coil.ImageLoaderFactory; | ||||
| import coil.util.DebugLogger; | ||||
| import dagger.hilt.android.HiltAndroidApp; | ||||
| import io.reactivex.rxjava3.exceptions.CompositeException; | ||||
| import io.reactivex.rxjava3.exceptions.MissingBackpressureException; | ||||
| import io.reactivex.rxjava3.exceptions.OnErrorNotImplementedException; | ||||
| @@ -61,6 +62,7 @@ import io.reactivex.rxjava3.plugins.RxJavaPlugins; | ||||
|  * along with NewPipe.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| @HiltAndroidApp | ||||
| public class App extends Application implements ImageLoaderFactory { | ||||
|     public static final String PACKAGE_NAME = BuildConfig.APPLICATION_ID; | ||||
|     private static final String TAG = App.class.toString(); | ||||
|   | ||||
							
								
								
									
										22
									
								
								app/src/main/java/org/schabi/newpipe/AppModule.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								app/src/main/java/org/schabi/newpipe/AppModule.kt
									
									
									
									
									
										Normal file
									
								
							| @@ -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) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										27
									
								
								app/src/main/java/org/schabi/newpipe/settings/DebugScreen.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/src/main/java/org/schabi/newpipe/settings/DebugScreen.kt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| 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 org.schabi.newpipe.R | ||||
| import org.schabi.newpipe.settings.viewmodel.SettingsViewModel | ||||
| import org.schabi.newpipe.ui.SwitchPreference | ||||
| import org.schabi.newpipe.ui.theme.SizeTokens | ||||
|  | ||||
| @Composable | ||||
| fun DebugScreen(viewModel: SettingsViewModel, modifier: Modifier = Modifier) { | ||||
|  | ||||
|     val settingsLayoutRedesign by viewModel.settingsLayoutRedesign.collectAsState() | ||||
|  | ||||
|     Column(modifier = modifier) { | ||||
|         SwitchPreference( | ||||
|             modifier = Modifier.padding(SizeTokens.SpacingExtraSmall), | ||||
|             R.string.settings_layout_redesign, | ||||
|             settingsLayoutRedesign, | ||||
|             viewModel::toggleSettingsLayoutRedesign | ||||
|         ) | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,23 @@ | ||||
| package org.schabi.newpipe.settings | ||||
|  | ||||
| import androidx.compose.foundation.layout.Column | ||||
| import androidx.compose.material3.HorizontalDivider | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.ui.Modifier | ||||
| import androidx.compose.ui.graphics.Color | ||||
| import org.schabi.newpipe.R | ||||
| import org.schabi.newpipe.ui.TextPreference | ||||
|  | ||||
| @Composable | ||||
| fun SettingsScreen( | ||||
|     onSelectSettingOption: (SettingsScreenKey) -> Unit, | ||||
|     modifier: Modifier = Modifier | ||||
| ) { | ||||
|     Column(modifier = modifier) { | ||||
|         TextPreference( | ||||
|             title = R.string.settings_category_debug_title, | ||||
|             onClick = { onSelectSettingOption(SettingsScreenKey.DEBUG) } | ||||
|         ) | ||||
|         HorizontalDivider(color = Color.Black) | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,85 @@ | ||||
| package org.schabi.newpipe.settings | ||||
|  | ||||
| import android.os.Bundle | ||||
| import androidx.activity.ComponentActivity | ||||
| import androidx.activity.compose.setContent | ||||
| import androidx.activity.viewModels | ||||
| import androidx.annotation.StringRes | ||||
| import androidx.compose.foundation.layout.padding | ||||
| import androidx.compose.material3.Scaffold | ||||
| import androidx.compose.runtime.getValue | ||||
| import androidx.compose.runtime.mutableIntStateOf | ||||
| import androidx.compose.runtime.remember | ||||
| import androidx.compose.runtime.setValue | ||||
| import androidx.compose.ui.Modifier | ||||
| import androidx.compose.ui.res.stringResource | ||||
| import androidx.navigation.compose.NavHost | ||||
| import androidx.navigation.compose.composable | ||||
| import androidx.navigation.compose.rememberNavController | ||||
| import androidx.navigation.navArgument | ||||
| 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 | ||||
|  | ||||
| const val SCREEN_TITLE_KEY = "SCREEN_TITLE_KEY" | ||||
|  | ||||
| @AndroidEntryPoint | ||||
| class SettingsV2Activity : ComponentActivity() { | ||||
|  | ||||
|     private val settingsViewModel: SettingsViewModel by viewModels() | ||||
|  | ||||
|     override fun onCreate(savedInstanceState: Bundle?) { | ||||
|         super.onCreate(savedInstanceState) | ||||
|  | ||||
|         setContent { | ||||
|             val navController = rememberNavController() | ||||
|             var screenTitle by remember { mutableIntStateOf(SettingsScreenKey.ROOT.screenTitle) } | ||||
|             navController.addOnDestinationChangedListener { _, _, arguments -> | ||||
|                 screenTitle = | ||||
|                     arguments?.getInt(SCREEN_TITLE_KEY) ?: SettingsScreenKey.ROOT.screenTitle | ||||
|             } | ||||
|  | ||||
|             AppTheme { | ||||
|                 Scaffold(topBar = { | ||||
|                     Toolbar( | ||||
|                         title = stringResource(id = screenTitle), | ||||
|                         hasSearch = true, | ||||
|                         onSearchQueryChange = null // TODO: Add suggestions logic | ||||
|                     ) | ||||
|                 }) { padding -> | ||||
|                     NavHost( | ||||
|                         navController = navController, | ||||
|                         startDestination = SettingsScreenKey.ROOT.name, | ||||
|                         modifier = Modifier.padding(padding) | ||||
|                     ) { | ||||
|                         composable( | ||||
|                             SettingsScreenKey.ROOT.name, | ||||
|                             listOf(createScreenTitleArg(SettingsScreenKey.ROOT.screenTitle)) | ||||
|                         ) { | ||||
|                             SettingsScreen(onSelectSettingOption = { screen -> | ||||
|                                 navController.navigate(screen.name) | ||||
|                             }) | ||||
|                         } | ||||
|                         composable( | ||||
|                             SettingsScreenKey.DEBUG.name, | ||||
|                             listOf(createScreenTitleArg(SettingsScreenKey.DEBUG.screenTitle)) | ||||
|                         ) { | ||||
|                             DebugScreen(settingsViewModel) | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| fun createScreenTitleArg(@StringRes screenTitle: Int) = navArgument(SCREEN_TITLE_KEY) { | ||||
|     defaultValue = screenTitle | ||||
| } | ||||
|  | ||||
| enum class SettingsScreenKey(@StringRes val screenTitle: Int) { | ||||
|     ROOT(R.string.settings), | ||||
|     DEBUG(R.string.settings_category_debug_title) | ||||
| } | ||||
| @@ -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<Boolean> = | ||||
|         MutableStateFlow(_settingsLayoutRedesignPref) | ||||
|     val settingsLayoutRedesign = _settingsLayoutRedesign.asStateFlow() | ||||
|  | ||||
|     fun toggleSettingsLayoutRedesign(newState: Boolean) { | ||||
|         _settingsLayoutRedesign.value = newState | ||||
|         _settingsLayoutRedesignPref = newState | ||||
|     } | ||||
| } | ||||
							
								
								
									
										53
									
								
								app/src/main/java/org/schabi/newpipe/ui/SwitchPreference.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								app/src/main/java/org/schabi/newpipe/ui/SwitchPreference.kt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| 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.MaterialTheme | ||||
| 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.style.TextAlign | ||||
| import org.schabi.newpipe.ui.theme.SizeTokens | ||||
|  | ||||
| @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(SizeTokens.SpacingExtraSmall), | ||||
|                 style = MaterialTheme.typography.titleSmall, | ||||
|                 textAlign = TextAlign.Start, | ||||
|             ) | ||||
|             summary?.let { | ||||
|                 Text( | ||||
|                     text = stringResource(id = summary), | ||||
|                     modifier = Modifier.padding(SizeTokens.SpacingExtraSmall), | ||||
|                     style = MaterialTheme.typography.bodySmall, | ||||
|                     textAlign = TextAlign.Start, | ||||
|                 ) | ||||
|             } | ||||
|         } | ||||
|         Spacer(modifier = Modifier.width(SizeTokens.SpacingSmall)) | ||||
|         Switch(checked = isChecked, onCheckedChange = onCheckedChange) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										66
									
								
								app/src/main/java/org/schabi/newpipe/ui/TextPreference.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								app/src/main/java/org/schabi/newpipe/ui/TextPreference.kt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| package org.schabi.newpipe.ui | ||||
|  | ||||
| import androidx.annotation.DrawableRes | ||||
| import androidx.annotation.StringRes | ||||
| import androidx.compose.foundation.clickable | ||||
| 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.defaultMinSize | ||||
| import androidx.compose.foundation.layout.fillMaxWidth | ||||
| import androidx.compose.foundation.layout.padding | ||||
| import androidx.compose.foundation.layout.width | ||||
| import androidx.compose.material3.Icon | ||||
| import androidx.compose.material3.MaterialTheme | ||||
| 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.painterResource | ||||
| import androidx.compose.ui.res.stringResource | ||||
| import androidx.compose.ui.text.style.TextAlign | ||||
| import org.schabi.newpipe.ui.theme.SizeTokens | ||||
|  | ||||
| @Composable | ||||
| fun TextPreference( | ||||
|     modifier: Modifier = Modifier, | ||||
|     @StringRes title: Int, | ||||
|     @DrawableRes icon: Int? = null, | ||||
|     @StringRes summary: Int? = null, | ||||
|     onClick: () -> Unit, | ||||
| ) { | ||||
|     Row( | ||||
|         verticalAlignment = Alignment.CenterVertically, | ||||
|         horizontalArrangement = Arrangement.SpaceBetween, | ||||
|         modifier = modifier | ||||
|             .fillMaxWidth() | ||||
|             .padding(SizeTokens.SpacingSmall) | ||||
|             .defaultMinSize(minHeight = SizeTokens.SpaceMinSize) | ||||
|             .clickable { onClick() } | ||||
|     ) { | ||||
|         icon?.let { | ||||
|             Icon( | ||||
|                 painter = painterResource(id = icon), | ||||
|                 contentDescription = "icon for $title preference" | ||||
|             ) | ||||
|             Spacer(modifier = Modifier.width(SizeTokens.SpacingSmall)) | ||||
|         } | ||||
|         Column { | ||||
|             Text( | ||||
|                 text = stringResource(id = title), | ||||
|                 modifier = Modifier.padding(SizeTokens.SpacingExtraSmall), | ||||
|                 style = MaterialTheme.typography.titleSmall, | ||||
|                 textAlign = TextAlign.Start, | ||||
|             ) | ||||
|             summary?.let { | ||||
|                 Text( | ||||
|                     text = stringResource(id = summary), | ||||
|                     modifier = Modifier.padding(SizeTokens.SpacingExtraSmall), | ||||
|                     style = MaterialTheme.typography.bodySmall, | ||||
|                     textAlign = TextAlign.Start, | ||||
|                 ) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -21,6 +21,7 @@ import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentActivity; | ||||
| import androidx.fragment.app.FragmentManager; | ||||
| import androidx.fragment.app.FragmentTransaction; | ||||
| import androidx.preference.PreferenceManager; | ||||
|  | ||||
| import com.jakewharton.processphoenix.ProcessPhoenix; | ||||
|  | ||||
| @@ -64,6 +65,7 @@ import org.schabi.newpipe.player.helper.PlayerHolder; | ||||
| import org.schabi.newpipe.player.playqueue.PlayQueue; | ||||
| import org.schabi.newpipe.player.playqueue.PlayQueueItem; | ||||
| import org.schabi.newpipe.settings.SettingsActivity; | ||||
| import org.schabi.newpipe.settings.SettingsV2Activity; | ||||
| import org.schabi.newpipe.util.external_communication.ShareUtils; | ||||
|  | ||||
| import java.util.List; | ||||
| @@ -648,7 +650,13 @@ public final class NavigationHelper { | ||||
|     } | ||||
|  | ||||
|     public static void openSettings(final Context context) { | ||||
|         final Intent intent = new Intent(context, SettingsActivity.class); | ||||
|         final Class<?> settingsClass = PreferenceManager.getDefaultSharedPreferences(context) | ||||
|                 .getBoolean( | ||||
|                         ContextCompat.getString(context, R.string.settings_layout_redesign_key), | ||||
|                         false | ||||
|                 ) ? SettingsV2Activity.class : SettingsActivity.class; | ||||
|  | ||||
|         final Intent intent = new Intent(context, settingsClass); | ||||
|         context.startActivity(intent); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -246,6 +246,7 @@ | ||||
|     <string name="crash_the_app_key">crash_the_app_key</string> | ||||
|     <string name="show_error_snackbar_key">show_error_snackbar_key</string> | ||||
|     <string name="create_error_notification_key">create_error_notification_key</string> | ||||
|     <string name="settings_layout_redesign_key">settings_layout_redesign_key</string> | ||||
|  | ||||
|     <!-- THEMES --> | ||||
|     <string name="theme_key">theme</string> | ||||
|   | ||||
| @@ -492,6 +492,7 @@ | ||||
|     <string name="crash_the_app">Crash the app</string> | ||||
|     <string name="show_error_snackbar">Show an error snackbar</string> | ||||
|     <string name="create_error_notification">Create an error notification</string> | ||||
|     <string name="settings_layout_redesign">Enable the Redesigned Settings page</string> | ||||
|     <!-- Subscriptions import/export --> | ||||
|     <string name="import_title">Import</string> | ||||
|     <string name="import_from">Import from</string> | ||||
|   | ||||
| @@ -64,4 +64,11 @@ | ||||
|         android:title="@string/create_error_notification" | ||||
|         app:singleLineTitle="false" | ||||
|         app:iconSpaceReserved="false" /> | ||||
|  | ||||
|     <SwitchPreferenceCompat | ||||
|         android:defaultValue="false" | ||||
|         android:key="@string/settings_layout_redesign_key" | ||||
|         android:title="@string/settings_layout_redesign" | ||||
|         app:iconSpaceReserved="false" | ||||
|         app:singleLineTitle="false" /> | ||||
| </PreferenceScreen> | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Siddhesh Naik
					Siddhesh Naik