From 2b0e5b467fc5e8df9a0383a165e7f4254bb6f906 Mon Sep 17 00:00:00 2001 From: proletarius101 Date: Fri, 16 Feb 2024 13:46:59 +0800 Subject: [PATCH 1/9] feat: migrate to material design 3 --- app/build.gradle | 3 +- .../fdroid/fdroid/nearby/StartSwapView.java | 12 +- .../fdroid/nearby/SwapWorkflowActivity.java | 12 +- .../fdroid/fdroid/panic/HidingManager.java | 5 +- .../panic/PanicPreferencesFragment.java | 7 +- .../full/res/layout/activity_calculator.xml | 3 +- .../res/layout/activity_panic_settings.xml | 3 +- app/src/full/res/layout/swap_activity.xml | 3 +- app/src/full/res/layout/swap_start_swap.xml | 28 ++-- app/src/main/AndroidManifest.xml | 6 +- .../java/org/fdroid/fdroid/FDroidApp.java | 3 +- .../org/fdroid/fdroid/compose/ComposeUtils.kt | 62 ++------- .../fdroid/installer/ErrorDialogActivity.java | 5 +- .../installer/FileInstallerActivity.java | 5 +- .../views/AppSecurityPermissions.java | 4 +- .../views/UninstallDialogActivity.java | 5 +- .../java/org/fdroid/fdroid/ui/theme/Color.kt | 64 ++++++++++ .../java/org/fdroid/fdroid/ui/theme/Theme.kt | 120 ++++++++++++++++++ .../fdroid/views/AppDetailsActivity.java | 9 +- .../views/AppDetailsRecyclerViewAdapter.java | 4 +- .../fdroid/views/IpfsGatewayAddActivity.kt | 45 ++++--- .../views/IpfsGatewaySettingsActivity.kt | 53 ++++---- .../fdroid/views/appdetails/RepoChooser.kt | 96 +++++++------- .../fdroid/views/repos/AddRepoActivity.kt | 28 ++-- .../fdroid/views/repos/AddRepoErrorScreen.kt | 14 +- .../fdroid/views/repos/AddRepoIntroScreen.kt | 35 +++-- .../views/repos/ManageReposActivity.java | 19 ++- .../views/repos/RepoDetailsActivity.java | 17 +-- .../fdroid/views/repos/RepoPreviewScreen.kt | 30 ++--- .../fdroid/views/repos/RepoProgressScreen.kt | 8 +- .../main/res/drawable/background_circle.xml | 2 +- .../details_panel_donate_background_dark.xml | 5 - .../details_panel_donate_background_light.xml | 5 - app/src/main/res/drawable/seekbar_thumb.xml | 2 +- .../res/layout/activity_install_history.xml | 3 +- .../main/res/layout/activity_repo_details.xml | 3 +- app/src/main/res/layout/app_card_normal.xml | 4 +- app/src/main/res/layout/app_details2.xml | 10 +- .../main/res/layout/installed_apps_layout.xml | 3 +- app/src/main/res/layout/login.xml | 4 +- .../main/res/layout/preference_edit_text.xml | 60 +++++++++ app/src/main/res/layout/preference_switch.xml | 11 ++ app/src/main/res/layout/repo_item.xml | 6 +- .../main/res/layout/repo_list_activity.xml | 1 - app/src/main/res/values-night/colors.xml | 51 ++++++++ app/src/main/res/values-night/themes.xml | 68 +++++++--- app/src/main/res/values/colors.xml | 57 ++++++++- app/src/main/res/values/shape.xml | 10 +- app/src/main/res/values/styles.xml | 41 +++--- app/src/main/res/values/styles_detail.xml | 18 +-- app/src/main/res/values/theme_overlays.xml | 17 +++ app/src/main/res/values/themes.xml | 90 ++++++++----- app/src/main/res/values/type.xml | 12 +- gradle/libs.versions.toml | 3 +- gradle/verification-metadata.xml | 20 +++ 55 files changed, 804 insertions(+), 410 deletions(-) create mode 100644 app/src/main/java/org/fdroid/fdroid/ui/theme/Color.kt create mode 100644 app/src/main/java/org/fdroid/fdroid/ui/theme/Theme.kt delete mode 100644 app/src/main/res/drawable/details_panel_donate_background_dark.xml delete mode 100644 app/src/main/res/drawable/details_panel_donate_background_light.xml create mode 100644 app/src/main/res/layout/preference_edit_text.xml create mode 100644 app/src/main/res/layout/preference_switch.xml create mode 100644 app/src/main/res/values/theme_overlays.xml diff --git a/app/build.gradle b/app/build.gradle index ad974de4e..b30b64808 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -214,12 +214,11 @@ dependencies { fullImplementation libs.nanohttpd implementation platform(libs.androidx.compose.bom) - implementation libs.androidx.compose.material + implementation libs.androidx.compose.material3 implementation libs.androidx.compose.material.icons.extended implementation libs.androidx.lifecycle.viewmodel.compose implementation libs.androidx.compose.ui.tooling.preview implementation libs.androidx.activity.compose - implementation libs.accompanist.themeadapter.material implementation libs.accompanist.drawablepainter debugImplementation libs.androidx.compose.ui.tooling diff --git a/app/src/full/java/org/fdroid/fdroid/nearby/StartSwapView.java b/app/src/full/java/org/fdroid/fdroid/nearby/StartSwapView.java index 77ed105c8..2d6be417a 100644 --- a/app/src/full/java/org/fdroid/fdroid/nearby/StartSwapView.java +++ b/app/src/full/java/org/fdroid/fdroid/nearby/StartSwapView.java @@ -26,7 +26,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager; import com.google.android.material.button.MaterialButton; import com.google.android.material.progressindicator.CircularProgressIndicator; -import com.google.android.material.switchmaterial.SwitchMaterial; +import com.google.android.material.materialswitch.MaterialSwitch; import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.R; @@ -35,6 +35,12 @@ import org.fdroid.fdroid.nearby.peers.Peer; import java.util.ArrayList; +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; + +import com.google.android.material.progressindicator.CircularProgressIndicator; + import cc.mvdan.accesspoint.WifiApControl; @SuppressWarnings("LineLength") @@ -82,7 +88,7 @@ public class StartSwapView extends SwapView { @Nullable /* Emulators typically don't have bluetooth adapters */ private final BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter(); - private SwitchMaterial bluetoothSwitch; + private MaterialSwitch bluetoothSwitch; private TextView viewBluetoothId; private TextView textBluetoothVisible; private TextView viewWifiId; @@ -173,7 +179,7 @@ public class StartSwapView extends SwapView { textBluetoothVisible = findViewById(R.id.bluetooth_visible); - bluetoothSwitch = (SwitchMaterial) findViewById(R.id.switch_bluetooth); + bluetoothSwitch = (MaterialSwitch) findViewById(R.id.switch_bluetooth); bluetoothSwitch.setOnCheckedChangeListener(onBluetoothSwitchToggled); bluetoothSwitch.setChecked(SwapService.getBluetoothVisibleUserPreference()); bluetoothSwitch.setEnabled(true); diff --git a/app/src/full/java/org/fdroid/fdroid/nearby/SwapWorkflowActivity.java b/app/src/full/java/org/fdroid/fdroid/nearby/SwapWorkflowActivity.java index b4c5174d0..66118bc64 100644 --- a/app/src/full/java/org/fdroid/fdroid/nearby/SwapWorkflowActivity.java +++ b/app/src/full/java/org/fdroid/fdroid/nearby/SwapWorkflowActivity.java @@ -40,7 +40,6 @@ import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; -import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.SearchView; import androidx.core.content.ContextCompat; @@ -48,7 +47,8 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager; import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.button.MaterialButton; -import com.google.android.material.switchmaterial.SwitchMaterial; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.materialswitch.MaterialSwitch; import com.google.android.material.progressindicator.CircularProgressIndicator; import com.google.zxing.integration.android.IntentIntegrator; import com.google.zxing.integration.android.IntentResult; @@ -456,7 +456,7 @@ public class SwapWorkflowActivity extends AppCompatActivity { } private void promptToSelectWifiNetwork() { - new AlertDialog.Builder(this) + new MaterialAlertDialogBuilder(this) .setTitle(R.string.swap_join_same_wifi) .setMessage(R.string.swap_join_same_wifi_desc) .setNeutralButton(R.string.cancel, (dialog, which) -> { @@ -872,7 +872,7 @@ public class SwapWorkflowActivity extends AppCompatActivity { private final BroadcastReceiver bluetoothScanModeChanged = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - SwitchMaterial bluetoothSwitch = container.findViewById(R.id.switch_bluetooth); + MaterialSwitch bluetoothSwitch = container.findViewById(R.id.switch_bluetooth); TextView textBluetoothVisible = container.findViewById(R.id.bluetooth_visible); if (bluetoothSwitch == null || textBluetoothVisible == null || !BluetoothManager.ACTION_STATUS.equals(intent.getAction())) { @@ -1082,7 +1082,7 @@ public class SwapWorkflowActivity extends AppCompatActivity { bonjourStatusReceiver.onReceive(this, new Intent(BonjourManager.ACTION_STATUS)); TextView viewWifiNetwork = findViewById(R.id.wifi_network); - SwitchMaterial wifiSwitch = findViewById(R.id.switch_wifi); + MaterialSwitch wifiSwitch = findViewById(R.id.switch_wifi); MaterialButton scanQrButton = findViewById(R.id.btn_scan_qr); MaterialButton appsButton = findViewById(R.id.btn_apps); if (viewWifiNetwork == null || wifiSwitch == null || scanQrButton == null || appsButton == null) { @@ -1240,7 +1240,7 @@ public class SwapWorkflowActivity extends AppCompatActivity { return; } bluetoothStatus = intent.getIntExtra(BluetoothManager.EXTRA_STATUS, bluetoothStatus); - SwitchMaterial bluetoothSwitch = container.findViewById(R.id.switch_bluetooth); + MaterialSwitch bluetoothSwitch = container.findViewById(R.id.switch_bluetooth); TextView textBluetoothVisible = container.findViewById(R.id.bluetooth_visible); TextView textDeviceIdBluetooth = container.findViewById(R.id.device_id_bluetooth); TextView peopleNearbyText = container.findViewById(R.id.text_people_nearby); diff --git a/app/src/full/java/org/fdroid/fdroid/panic/HidingManager.java b/app/src/full/java/org/fdroid/fdroid/panic/HidingManager.java index bd2f745c1..c8ff50786 100644 --- a/app/src/full/java/org/fdroid/fdroid/panic/HidingManager.java +++ b/app/src/full/java/org/fdroid/fdroid/panic/HidingManager.java @@ -7,9 +7,10 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; -import androidx.appcompat.app.AlertDialog; import androidx.core.app.NotificationManagerCompat; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + import org.fdroid.fdroid.BuildConfig; import org.fdroid.fdroid.R; import org.fdroid.fdroid.views.main.MainActivity; @@ -41,7 +42,7 @@ public class HidingManager { public static void showHideDialog(final Context context) { String appName = context.getString(R.string.app_name); - AlertDialog.Builder builder = new AlertDialog.Builder(context); + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context); builder.setTitle(context.getString(R.string.hiding_dialog_title, appName)); builder.setMessage(context.getString(R.string.hiding_dialog_message, appName, HidingManager.getUnhidePin(context), context.getString(R.string.hiding_calculator))); diff --git a/app/src/full/java/org/fdroid/fdroid/panic/PanicPreferencesFragment.java b/app/src/full/java/org/fdroid/fdroid/panic/PanicPreferencesFragment.java index 9a97ba015..5ae61aaee 100644 --- a/app/src/full/java/org/fdroid/fdroid/panic/PanicPreferencesFragment.java +++ b/app/src/full/java/org/fdroid/fdroid/panic/PanicPreferencesFragment.java @@ -17,7 +17,6 @@ import android.util.TypedValue; import androidx.annotation.ColorInt; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; import androidx.preference.ListPreference; @@ -26,6 +25,8 @@ import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceFragmentCompat; import androidx.preference.SwitchPreferenceCompat; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.R; import org.fdroid.fdroid.installer.PrivilegedInstaller; @@ -234,7 +235,7 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat requireActivity().finish(); }; - AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity()); + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity()); builder.setTitle(getString(R.string.panic_app_dialog_title)); CharSequence app = getString(R.string.panic_app_unknown_app); @@ -266,7 +267,7 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat private void showHideConfirmationDialog() { String appName = getString(R.string.app_name); - AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity()); + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity()); builder.setTitle(R.string.panic_hide_warning_title); builder.setMessage(getString(R.string.panic_hide_warning_message, appName, HidingManager.getUnhidePin(requireActivity()), getString(R.string.hiding_calculator))); diff --git a/app/src/full/res/layout/activity_calculator.xml b/app/src/full/res/layout/activity_calculator.xml index a1b233b91..184a9334d 100644 --- a/app/src/full/res/layout/activity_calculator.xml +++ b/app/src/full/res/layout/activity_calculator.xml @@ -20,8 +20,7 @@ + android:layout_height="?attr/actionBarSize" /> diff --git a/app/src/full/res/layout/activity_panic_settings.xml b/app/src/full/res/layout/activity_panic_settings.xml index 1338eaa31..d3a1119f6 100644 --- a/app/src/full/res/layout/activity_panic_settings.xml +++ b/app/src/full/res/layout/activity_panic_settings.xml @@ -16,8 +16,7 @@ android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" - app:title="@string/panic_settings" - style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface" /> + app:title="@string/panic_settings" /> diff --git a/app/src/full/res/layout/swap_activity.xml b/app/src/full/res/layout/swap_activity.xml index 5af4523db..898f3a4b0 100644 --- a/app/src/full/res/layout/swap_activity.xml +++ b/app/src/full/res/layout/swap_activity.xml @@ -15,8 +15,7 @@ + android:layout_height="?attr/actionBarSize" /> diff --git a/app/src/full/res/layout/swap_start_swap.xml b/app/src/full/res/layout/swap_start_swap.xml index fb7a3bea6..080b23dec 100644 --- a/app/src/full/res/layout/swap_start_swap.xml +++ b/app/src/full/res/layout/swap_start_swap.xml @@ -1,7 +1,7 @@ - - + - - @@ -189,14 +189,14 @@ android:textColor="@color/swap_light_text" /> + android:id="@+id/searching_people_nearby" + android:layout_width="24dp" + android:layout_height="24dp" + android:indeterminate="true" + app:showAnimationBehavior="inward" + app:hideAnimationBehavior="outward" + app:indicatorSize="24dp" + app:trackCornerRadius="@dimen/mtrl_progress_indicator_full_rounded_corner_radius" /> diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a3f021c76..9631c765a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -272,10 +272,10 @@ + android:theme="@style/Theme.App.Transparent" /> + android:theme="@style/Theme.App.Transparent" /> + android:theme="@style/Theme.App.Transparent" /> Nearby Swap Crash on Android 12: no such algorithm: SHA1WITHRSA for provider BC + * @see Nearby Swap Crash on Android 12: no such algorithm: SHA1WITHRSA for provider BC */ private static void enableBouncyCastle() { if (Build.VERSION.SDK_INT >= 31) { diff --git a/app/src/main/java/org/fdroid/fdroid/compose/ComposeUtils.kt b/app/src/main/java/org/fdroid/fdroid/compose/ComposeUtils.kt index 4615a588f..2cdffe826 100644 --- a/app/src/main/java/org/fdroid/fdroid/compose/ComposeUtils.kt +++ b/app/src/main/java/org/fdroid/fdroid/compose/ComposeUtils.kt @@ -5,71 +5,31 @@ import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Button -import androidx.compose.material.ButtonDefaults -import androidx.compose.material.Icon -import androidx.compose.material.MaterialTheme -import androidx.compose.material.OutlinedButton -import androidx.compose.material.Surface -import androidx.compose.material.Text +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Surface +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalInspectionMode -import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalLifecycleOwner -import androidx.compose.ui.res.colorResource import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.em -import androidx.compose.ui.unit.sp import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleOwner -import com.google.accompanist.themeadapter.material.createMdcTheme -import org.fdroid.fdroid.Preferences -import org.fdroid.fdroid.R import java.util.Locale object ComposeUtils { + + @Composable fun FDroidContent(content: @Composable () -> Unit) { - val context = LocalContext.current - val layoutDirection = LocalLayoutDirection.current - val (colors, typography, shapes) = createMdcTheme( - context = context, - layoutDirection = layoutDirection, - ) - val newColors = (colors ?: MaterialTheme.colors).let { c -> - if (!LocalInspectionMode.current && !c.isLight && Preferences.get().isPureBlack) { - c.copy(background = Color.Black, surface = Color(0xff1e1e1e)) - } else if (!c.isLight) { - c.copy(surface = Color(0xff1e1e1e)) - } else { - c - } - } - MaterialTheme( - colors = newColors, - typography = typography?.let { - it.copy( - // adapt letter-spacing to non-compose UI - body1 = it.body1.copy(letterSpacing = 0.em), - body2 = it.body2.copy(letterSpacing = 0.em), - // set caption style to match MDC - caption = it.caption.copy( - color = colorResource(id = R.color.fdroid_caption), - fontSize = 12.sp, - ) - ) - } ?: MaterialTheme.typography, - shapes = shapes ?: MaterialTheme.shapes - ) { - Surface(content = content) - } + Surface(content = content) } @Composable @@ -154,7 +114,7 @@ object ComposeUtils { fun CaptionText(text: String) { Text( text = text, - style = MaterialTheme.typography.caption, + style = MaterialTheme.typography.bodySmall, modifier = Modifier.padding(0.dp, 16.dp, 0.dp, 4.dp) ) } diff --git a/app/src/main/java/org/fdroid/fdroid/installer/ErrorDialogActivity.java b/app/src/main/java/org/fdroid/fdroid/installer/ErrorDialogActivity.java index 236998450..52aaa8f19 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/ErrorDialogActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/ErrorDialogActivity.java @@ -26,10 +26,11 @@ import android.util.TypedValue; import android.widget.TextView; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentActivity; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + import org.fdroid.fdroid.R; public class ErrorDialogActivity extends FragmentActivity { @@ -46,7 +47,7 @@ public class ErrorDialogActivity extends FragmentActivity { final String message = intent.getStringExtra(EXTRA_MESSAGE); // pass the theme, it is not automatically applied due to activity's Theme.NoDisplay - final AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.AppThemeDialog); + final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this); builder.setTitle(title); builder.setNeutralButton(R.string.ok, (dialog, which) -> { setResult(AppCompatActivity.RESULT_OK); diff --git a/app/src/main/java/org/fdroid/fdroid/installer/FileInstallerActivity.java b/app/src/main/java/org/fdroid/fdroid/installer/FileInstallerActivity.java index df5f46e44..d2732534b 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/FileInstallerActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/FileInstallerActivity.java @@ -8,11 +8,12 @@ import android.os.Bundle; import android.widget.Toast; import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.fragment.app.FragmentActivity; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + import org.apache.commons.io.FileUtils; import org.fdroid.fdroid.R; import org.fdroid.fdroid.Utils; @@ -102,7 +103,7 @@ public class FileInstallerActivity extends FragmentActivity { private void showDialog() { // pass the theme, it is not automatically applied due to activity's Theme.NoDisplay - final AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.Theme_App); + final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this, R.style.Theme_App); builder.setMessage(R.string.app_permission_storage) .setPositiveButton(R.string.ok, (dialog, id) -> ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, diff --git a/app/src/main/java/org/fdroid/fdroid/privileged/views/AppSecurityPermissions.java b/app/src/main/java/org/fdroid/fdroid/privileged/views/AppSecurityPermissions.java index 2755d08bc..a975b8814 100644 --- a/app/src/main/java/org/fdroid/fdroid/privileged/views/AppSecurityPermissions.java +++ b/app/src/main/java/org/fdroid/fdroid/privileged/views/AppSecurityPermissions.java @@ -44,6 +44,8 @@ import androidx.appcompat.app.AlertDialog; import androidx.core.content.ContextCompat; import androidx.core.graphics.drawable.DrawableCompat; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.R; import org.fdroid.fdroid.Utils; @@ -206,7 +208,7 @@ public class AppSecurityPermissions { dialog.dismiss(); } PackageManager pm = getContext().getPackageManager(); - AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getContext()); builder.setTitle(group.label); if (perm.descriptionRes != 0) { builder.setMessage(perm.loadDescription(pm)); diff --git a/app/src/main/java/org/fdroid/fdroid/privileged/views/UninstallDialogActivity.java b/app/src/main/java/org/fdroid/fdroid/privileged/views/UninstallDialogActivity.java index 0d756e00f..ae61e76e8 100644 --- a/app/src/main/java/org/fdroid/fdroid/privileged/views/UninstallDialogActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/privileged/views/UninstallDialogActivity.java @@ -26,10 +26,11 @@ import android.os.Bundle; import android.util.Log; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentActivity; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + import org.fdroid.fdroid.R; import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.App; @@ -82,7 +83,7 @@ public class UninstallDialogActivity extends FragmentActivity { } // pass the theme, it is not automatically applied due to activity's Theme.NoDisplay - final AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.Theme_App); + final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this, R.style.Theme_App); builder.setTitle(appInfo.loadLabel(pm)); builder.setIcon(appInfo.loadIcon(pm)); builder.setPositiveButton(android.R.string.ok, (dialog, which) -> { diff --git a/app/src/main/java/org/fdroid/fdroid/ui/theme/Color.kt b/app/src/main/java/org/fdroid/fdroid/ui/theme/Color.kt new file mode 100644 index 000000000..314f41d3d --- /dev/null +++ b/app/src/main/java/org/fdroid/fdroid/ui/theme/Color.kt @@ -0,0 +1,64 @@ +package org.fdroid.fdroid.ui.theme + +import androidx.compose.ui.graphics.Color + +// Generated by the Material Theme Builder from fdroid_blue and fdroid_green +// https://www.figma.com/community/plugin/1034969338659738588 + +val primaryLight = Color(0xFF005197) +val onPrimaryLight = Color(0xFFFFFFFF) +val primaryContainerLight = Color(0xFF1976D2) +val onPrimaryContainerLight = Color(0xFFFFFFFF) +val secondaryLight = Color(0xFF4F6600) +val onSecondaryLight = Color(0xFFFFFFFF) +val secondaryContainerLight = Color(0xFF95BC18) +val onSecondaryContainerLight = Color(0xFF1C2700) +val tertiaryLight = Color(0xFF763192) +val onTertiaryLight = Color(0xFFFFFFFF) +val tertiaryContainerLight = Color(0xFF9F58BA) +val onTertiaryContainerLight = Color(0xFFFFFFFF) +val errorLight = Color(0xFFBA1A1A) +val onErrorLight = Color(0xFFFFFFFF) +val errorContainerLight = Color(0xFFFFDAD6) +val onErrorContainerLight = Color(0xFF410002) +val backgroundLight = Color(0xFFF9F9FF) +val onBackgroundLight = Color(0xFF181C21) +val surfaceLight = Color(0xFFF9F9FF) +val onSurfaceLight = Color(0xFF181C21) +val surfaceVariantLight = Color(0xFFDDE2F0) +val onSurfaceVariantLight = Color(0xFF414752) +val outlineLight = Color(0xFF717783) +val outlineVariantLight = Color(0xFFC1C6D4) +val scrimLight = Color(0xFF000000) +val inverseSurfaceLight = Color(0xFF2D3037) +val inverseOnSurfaceLight = Color(0xFFEFF0F9) +val inversePrimaryLight = Color(0xFFA5C8FF) + +val primaryDark = Color(0xFFA5C8FF) +val onPrimaryDark = Color(0xFF00315F) +val primaryContainerDark = Color(0xFF006DC7) +val onPrimaryContainerDark = Color(0xFFFFFFFF) +val secondaryDark = Color(0xFFADD535) +val onSecondaryDark = Color(0xFF283500) +val secondaryContainerDark = Color(0xFF83A800) +val onSecondaryContainerDark = Color(0xFF080D00) +val tertiaryDark = Color(0xFFEDB1FF) +val onTertiaryDark = Color(0xFF52046E) +val tertiaryContainerDark = Color(0xFF954FB0) +val onTertiaryContainerDark = Color(0xFFFFFFFF) +val errorDark = Color(0xFFFFB4AB) +val onErrorDark = Color(0xFF690005) +val errorContainerDark = Color(0xFF93000A) +val onErrorContainerDark = Color(0xFFFFDAD6) +val backgroundDark = Color(0xFF101319) +val onBackgroundDark = Color(0xFFE0E2EA) +val surfaceDark = Color(0xFF101319) +val onSurfaceDark = Color(0xFFE0E2EA) +val surfaceVariantDark = Color(0xFF414752) +val onSurfaceVariantDark = Color(0xFFC1C6D4) +val outlineDark = Color(0xFF8B919E) +val outlineVariantDark = Color(0xFF414752) +val scrimDark = Color(0xFF000000) +val inverseSurfaceDark = Color(0xFFE0E2EA) +val inverseOnSurfaceDark = Color(0xFF2D3037) +val inversePrimaryDark = Color(0xFF005FAF) diff --git a/app/src/main/java/org/fdroid/fdroid/ui/theme/Theme.kt b/app/src/main/java/org/fdroid/fdroid/ui/theme/Theme.kt new file mode 100644 index 000000000..15d080d02 --- /dev/null +++ b/app/src/main/java/org/fdroid/fdroid/ui/theme/Theme.kt @@ -0,0 +1,120 @@ +package org.fdroid.fdroid.ui.theme + +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext + +// The followings are generated by the Material Theme Builder with modifications +// https://www.figma.com/community/plugin/1034969338659738588 +// Unused code are and themes with contrast are removed + +private val lightScheme = lightColorScheme( + primary = primaryLight, + onPrimary = onPrimaryLight, + primaryContainer = primaryContainerLight, + onPrimaryContainer = onPrimaryContainerLight, + secondary = secondaryLight, + onSecondary = onSecondaryLight, + secondaryContainer = secondaryContainerLight, + onSecondaryContainer = onSecondaryContainerLight, + tertiary = tertiaryLight, + onTertiary = onTertiaryLight, + tertiaryContainer = tertiaryContainerLight, + onTertiaryContainer = onTertiaryContainerLight, + error = errorLight, + onError = onErrorLight, + errorContainer = errorContainerLight, + onErrorContainer = onErrorContainerLight, + background = backgroundLight, + onBackground = onBackgroundLight, + surface = surfaceLight, + onSurface = onSurfaceLight, + surfaceVariant = surfaceVariantLight, + onSurfaceVariant = onSurfaceVariantLight, + outline = outlineLight, + outlineVariant = outlineVariantLight, + scrim = scrimLight, + inverseSurface = inverseSurfaceLight, + inverseOnSurface = inverseOnSurfaceLight, + inversePrimary = inversePrimaryLight, +) + +private val darkScheme = darkColorScheme( + primary = primaryDark, + onPrimary = onPrimaryDark, + primaryContainer = primaryContainerDark, + onPrimaryContainer = onPrimaryContainerDark, + secondary = secondaryDark, + onSecondary = onSecondaryDark, + secondaryContainer = secondaryContainerDark, + onSecondaryContainer = onSecondaryContainerDark, + tertiary = tertiaryDark, + onTertiary = onTertiaryDark, + tertiaryContainer = tertiaryContainerDark, + onTertiaryContainer = onTertiaryContainerDark, + error = errorDark, + onError = onErrorDark, + errorContainer = errorContainerDark, + onErrorContainer = onErrorContainerDark, + background = backgroundDark, + onBackground = onBackgroundDark, + surface = surfaceDark, + onSurface = onSurfaceDark, + surfaceVariant = surfaceVariantDark, + onSurfaceVariant = onSurfaceVariantDark, + outline = outlineDark, + outlineVariant = outlineVariantDark, + scrim = scrimDark, + inverseSurface = inverseSurfaceDark, + inverseOnSurface = inverseOnSurfaceDark, + inversePrimary = inversePrimaryDark, +) + +private val pureBlackScheme = darkScheme.copy(background = Color.Black, surface = Color(0xff1e1e1e)) + +@Immutable +data class ColorFamily( + val color: Color, + val onColor: Color, + val colorContainer: Color, + val onColorContainer: Color +) + +val unspecified_scheme = ColorFamily( + Color.Unspecified, Color.Unspecified, Color.Unspecified, Color.Unspecified +) + +// Pure black theme logic is added on top of the generated code +@Composable +fun AppTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + pureBlack: Boolean = false, + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = false, + content: @Composable() () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme && pureBlack -> pureBlackScheme + darkTheme -> darkScheme + else -> lightScheme + } + + MaterialTheme( + colorScheme = colorScheme, + content = content + ) +} + diff --git a/app/src/main/java/org/fdroid/fdroid/views/AppDetailsActivity.java b/app/src/main/java/org/fdroid/fdroid/views/AppDetailsActivity.java index 584df0943..b83c7f0b6 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/AppDetailsActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/views/AppDetailsActivity.java @@ -52,6 +52,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; import com.google.android.material.appbar.MaterialToolbar; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import org.fdroid.database.AppPrefs; import org.fdroid.database.AppVersion; @@ -363,7 +364,7 @@ public class AppDetailsActivity extends AppCompatActivity } if (!apk.compatible) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this); builder.setMessage(R.string.installIncompatible); builder.setPositiveButton(R.string.yes, (dialog, whichButton) -> initiateInstall(apk)); builder.setNegativeButton(R.string.no, (dialog, whichButton) -> { @@ -374,7 +375,7 @@ public class AppDetailsActivity extends AppCompatActivity } if (app.installedSigner != null && apk.signer != null && !apk.signer.equals(app.installedSigner)) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this); builder.setMessage(R.string.SignatureMismatch).setPositiveButton( R.string.ok, (dialog, id) -> dialog.cancel()); AlertDialog alert = builder.create(); @@ -615,7 +616,9 @@ public class AppDetailsActivity extends AppCompatActivity if (!TextUtils.isEmpty(errorMessage) && !isFinishing()) { Log.e(TAG, "uninstall aborted with errorMessage: " + errorMessage); - AlertDialog.Builder alertBuilder = new AlertDialog.Builder(AppDetailsActivity.this); + MaterialAlertDialogBuilder alertBuilder = new MaterialAlertDialogBuilder( + AppDetailsActivity.this + ); Uri uri = intent.getData(); if (uri == null) { alertBuilder.setTitle(getString(R.string.uninstall_error_notify_title, "")); diff --git a/app/src/main/java/org/fdroid/fdroid/views/AppDetailsRecyclerViewAdapter.java b/app/src/main/java/org/fdroid/fdroid/views/AppDetailsRecyclerViewAdapter.java index 89a8d13b8..504d4452f 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/AppDetailsRecyclerViewAdapter.java +++ b/app/src/main/java/org/fdroid/fdroid/views/AppDetailsRecyclerViewAdapter.java @@ -34,7 +34,6 @@ import androidx.annotation.DrawableRes; import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import androidx.compose.ui.platform.ComposeView; import androidx.compose.ui.platform.ViewCompositionStrategy; import androidx.core.content.ContextCompat; @@ -52,6 +51,7 @@ import androidx.recyclerview.widget.LinearSmoothScroller; import androidx.recyclerview.widget.RecyclerView; import androidx.transition.TransitionManager; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.progressindicator.LinearProgressIndicator; import org.apache.commons.io.FilenameUtils; @@ -993,7 +993,7 @@ public class AppDetailsRecyclerViewAdapter message = showIncompatible; } - new AlertDialog.Builder(context) + new MaterialAlertDialogBuilder(context) .setTitle(title) .setMessage(message) .setPositiveButton(R.string.menu_settings, (dialog, which) -> { diff --git a/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewayAddActivity.kt b/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewayAddActivity.kt index 1c0c527de..e0c1a5c26 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewayAddActivity.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewayAddActivity.kt @@ -10,18 +10,17 @@ 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.material.ContentAlpha -import androidx.compose.material.Icon -import androidx.compose.material.IconButton -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Scaffold -import androidx.compose.material.Text -import androidx.compose.material.TextField -import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.ContentPaste -import androidx.compose.material.primarySurface +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -29,7 +28,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.layout.onGloballyPositioned @@ -43,14 +41,17 @@ import org.fdroid.fdroid.Preferences import org.fdroid.fdroid.R import org.fdroid.fdroid.compose.ComposeUtils import org.fdroid.fdroid.compose.ComposeUtils.FDroidContent +import org.fdroid.fdroid.ui.theme.AppTheme class IpfsGatewayAddActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + val pureBlack = Preferences.get().isPureBlack + setContent { - FDroidContent { + AppTheme(pureBlack = pureBlack) { IpfsGatewayAddScreen( onBackClicked = { onBackPressedDispatcher.onBackPressed() }, onAddUserGateway = { url -> @@ -71,6 +72,7 @@ class IpfsGatewayAddActivity : AppCompatActivity() { } } +@OptIn(ExperimentalMaterial3Api::class) @Composable fun IpfsGatewayAddScreen( onBackClicked: () -> Unit, @@ -83,17 +85,14 @@ fun IpfsGatewayAddScreen( Scaffold( topBar = { TopAppBar( - elevation = 4.dp, - backgroundColor = MaterialTheme.colors.primarySurface, navigationIcon = { - IconButton(onClick = onBackClicked) { - Icon(Icons.Filled.ArrowBack, stringResource(R.string.back)) - } - }, - title = { - Text( - text = stringResource(R.string.ipfsgw_add_title), - modifier = Modifier.alpha(ContentAlpha.high), + IconButton(onClick = onBackClicked) { + Icon(Icons.Filled.ArrowBack, stringResource(R.string.back)) + } + }, + title = { + Text( + text = stringResource(R.string.ipfsgw_add_title), ) }, ) @@ -107,7 +106,7 @@ fun IpfsGatewayAddScreen( ) { Text( text = "Enter IPFS gateway URL", - style = MaterialTheme.typography.body1, + style = MaterialTheme.typography.bodyLarge, ) Column { TextField( @@ -125,7 +124,7 @@ fun IpfsGatewayAddScreen( if (errorMsg.isNotEmpty()) { Text( text = errorMsg, - style = MaterialTheme.typography.body1, + style = MaterialTheme.typography.bodyLarge, color = colorResource( id = R.color.fdroid_error ) diff --git a/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewaySettingsActivity.kt b/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewaySettingsActivity.kt index bf9bc33ef..ccd7f306c 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewaySettingsActivity.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewaySettingsActivity.kt @@ -14,20 +14,19 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material.ContentAlpha -import androidx.compose.material.FloatingActionButton -import androidx.compose.material.Icon -import androidx.compose.material.IconButton -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Scaffold -import androidx.compose.material.Switch -import androidx.compose.material.Text -import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.DeleteForever -import androidx.compose.material.primarySurface +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FloatingActionButton +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Switch +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -47,6 +46,7 @@ import org.fdroid.fdroid.R import org.fdroid.fdroid.compose.ComposeUtils.CaptionText import org.fdroid.fdroid.compose.ComposeUtils.FDroidContent import org.fdroid.fdroid.compose.ComposeUtils.LifecycleEventListener +import org.fdroid.fdroid.ui.theme.AppTheme class IpfsGatewaySettingsActivity : AppCompatActivity() { @@ -56,18 +56,22 @@ class IpfsGatewaySettingsActivity : AppCompatActivity() { super.onCreate(savedInstanceState) prefs = Preferences.get() + val pureBlack = prefs.isPureBlack setContent { - FDroidContent { - IpfsGatewaySettingsScreen( + AppTheme(pureBlack = pureBlack) { + FDroidContent { + IpfsGatewaySettingsScreen( prefs = prefs, - onBackClicked = { onBackPressedDispatcher.onBackPressed() }, + onBackClicked = { onBackPressedDispatcher.onBackPressed() }, ) + } } } } } +@OptIn(ExperimentalMaterial3Api::class) @Composable fun IpfsGatewaySettingsScreen( onBackClicked: () -> Unit, @@ -79,17 +83,14 @@ fun IpfsGatewaySettingsScreen( Scaffold( topBar = { TopAppBar( - elevation = 4.dp, - backgroundColor = MaterialTheme.colors.primarySurface, navigationIcon = { - IconButton(onClick = onBackClicked) { - Icon(Icons.Filled.ArrowBack, stringResource(R.string.back)) - } - }, - title = { - Text( - text = stringResource(R.string.ipfsgw_title), - modifier = Modifier.alpha(ContentAlpha.high), + IconButton(onClick = onBackClicked) { + Icon(Icons.Filled.ArrowBack, stringResource(R.string.back)) + } + }, + title = { + Text( + text = stringResource(R.string.ipfsgw_title), ) }, ) @@ -120,7 +121,7 @@ fun IpfsGatewaySettingsScreen( ) { Text( text = stringResource(id = R.string.ipfsgw_explainer), - style = MaterialTheme.typography.body1, + style = MaterialTheme.typography.bodyLarge, modifier = Modifier.weight(1f) ) Switch(checked = ipfsEnabled, onCheckedChange = { checked -> @@ -157,7 +158,7 @@ fun DefaultGatewaysSettings( ) { Text( text = gatewayUrl, - style = MaterialTheme.typography.body1, + style = MaterialTheme.typography.bodyLarge, modifier = Modifier .weight(1f) .align(Alignment.CenterVertically) @@ -211,7 +212,7 @@ fun UserGatewaysSettings( ) { Text( text = gatewayUrl, - style = MaterialTheme.typography.body1, + style = MaterialTheme.typography.bodyLarge, modifier = Modifier .weight(1f) .align(Alignment.CenterVertically) diff --git a/app/src/main/java/org/fdroid/fdroid/views/appdetails/RepoChooser.kt b/app/src/main/java/org/fdroid/fdroid/views/appdetails/RepoChooser.kt index 752a6aeb6..6527b9759 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/appdetails/RepoChooser.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/appdetails/RepoChooser.kt @@ -1,32 +1,27 @@ package org.fdroid.fdroid.views.appdetails import android.content.res.Configuration -import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement.spacedBy import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.material.DropdownMenu -import androidx.compose.material.DropdownMenuItem -import androidx.compose.material.Icon -import androidx.compose.material.LocalContentAlpha -import androidx.compose.material.LocalContentColor -import androidx.compose.material.MaterialTheme -import androidx.compose.material.OutlinedTextField -import androidx.compose.material.Text -import androidx.compose.material.TextFieldDefaults import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowDropDown +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.OutlinedTextFieldDefaults +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Alignment.Companion.End import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView @@ -41,9 +36,11 @@ import androidx.compose.ui.unit.dp import androidx.core.os.LocaleListCompat import androidx.core.util.Consumer import org.fdroid.database.Repository +import org.fdroid.fdroid.Preferences import org.fdroid.fdroid.R import org.fdroid.fdroid.compose.ComposeUtils.FDroidContent import org.fdroid.fdroid.compose.ComposeUtils.FDroidOutlineButton +import org.fdroid.fdroid.ui.theme.AppTheme import org.fdroid.fdroid.views.repos.RepoIcon import org.fdroid.index.IndexFormatVersion.TWO @@ -58,20 +55,24 @@ fun setContentRepoChooser( onRepoChanged: Consumer, onPreferredRepoChanged: Consumer, ) { + val pureBlack = Preferences.get().isPureBlack + composeView.setContent { - FDroidContent { - RepoChooser( - repos = repos, - currentRepoId = currentRepoId, - preferredRepoId = preferredRepoId, - onRepoChanged = onRepoChanged::accept, - onPreferredRepoChanged = onPreferredRepoChanged::accept, - modifier = Modifier.background(MaterialTheme.colors.surface), - ) + AppTheme(pureBlack = pureBlack) { + FDroidContent { + RepoChooser( + repos = repos, + currentRepoId = currentRepoId, + preferredRepoId = preferredRepoId, + onRepoChanged = onRepoChanged::accept, + onPreferredRepoChanged = onPreferredRepoChanged::accept, + ) + } } } } +@OptIn(ExperimentalMaterial3Api::class) @Composable fun RepoChooser( repos: List, @@ -93,7 +94,7 @@ fun RepoChooser( val borderColor = if (isPreferred) { colorResource(id = R.color.fdroid_blue) } else { - LocalContentColor.current.copy(alpha = LocalContentAlpha.current) + MaterialTheme.colorScheme.outline } OutlinedTextField( value = TextFieldValue( @@ -102,7 +103,7 @@ fun RepoChooser( isPreferred = repos.size > 1 && isPreferred, ), ), - textStyle = MaterialTheme.typography.body2, + textStyle = MaterialTheme.typography.bodyMedium, onValueChange = {}, label = { if (repos.size == 1) { @@ -121,18 +122,18 @@ fun RepoChooser( tint = if (isPreferred) { colorResource(id = R.color.fdroid_blue) } else { - LocalContentColor.current.copy(alpha = LocalContentAlpha.current) + MaterialTheme.colorScheme.onSurface }, ) }, singleLine = false, enabled = false, - colors = TextFieldDefaults.outlinedTextFieldColors( - // hack to enable clickable - disabledTextColor = LocalContentColor.current.copy(LocalContentAlpha.current), + colors = OutlinedTextFieldDefaults.colors( + // hack to enable clickable and look like enabled + disabledTextColor = MaterialTheme.colorScheme.onSurface, disabledBorderColor = borderColor, + disabledLeadingIconColor = MaterialTheme.colorScheme.onSurface, disabledLabelColor = borderColor, - disabledLeadingIconColor = MaterialTheme.colors.onSurface, ), modifier = Modifier .fillMaxWidth() @@ -145,12 +146,10 @@ fun RepoChooser( onDismissRequest = { expanded = false }, ) { repos.iterator().forEach { repo -> - DropdownMenuItem(onClick = { + RepoMenuItem(repo = repo, isPreferred = isPreferred, onClick = { onRepoChanged(repo) expanded = false - }) { - RepoItem(repo, repo.repoId == preferredRepoId) - } + }, modifier = modifier) } } } @@ -158,25 +157,32 @@ fun RepoChooser( FDroidOutlineButton( text = stringResource(R.string.app_details_repository_button_prefer), onClick = { onPreferredRepoChanged(currentRepo.repoId) }, - modifier = Modifier.align(End).padding(top = 8.dp), + modifier = Modifier + .align(End) + .padding(top = 8.dp), ) } } } @Composable -private fun RepoItem(repo: Repository, isPreferred: Boolean, modifier: Modifier = Modifier) { - Row( - horizontalArrangement = spacedBy(8.dp), - verticalAlignment = CenterVertically, +private fun RepoMenuItem( + repo: Repository, + isPreferred: Boolean, + modifier: Modifier = Modifier, + onClick: () -> Unit +) { + DropdownMenuItem( + text = { + Text( + text = getRepoString(repo, isPreferred), + style = MaterialTheme.typography.bodyMedium, + ) + }, modifier = modifier, - ) { - RepoIcon(repo, Modifier.size(24.dp)) - Text( - text = getRepoString(repo, isPreferred), - style = MaterialTheme.typography.body2, - ) - } + onClick = onClick, + leadingIcon = { RepoIcon(repo, Modifier.size(24.dp)) } + ) } @Composable diff --git a/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoActivity.kt b/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoActivity.kt index 179395bc8..95ef299f8 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoActivity.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoActivity.kt @@ -21,6 +21,7 @@ import org.fdroid.fdroid.Preferences import org.fdroid.fdroid.R import org.fdroid.fdroid.compose.ComposeUtils.FDroidContent import org.fdroid.fdroid.nearby.SwapService +import org.fdroid.fdroid.ui.theme.AppTheme import org.fdroid.fdroid.views.apps.AppListActivity import org.fdroid.fdroid.views.apps.AppListActivity.EXTRA_REPO_ID import org.fdroid.fdroid.work.RepoUpdateWorker @@ -53,19 +54,24 @@ class AddRepoActivity : AppCompatActivity() { } } } + + val pureBlack = Preferences.get().isPureBlack + setContent { - FDroidContent { - val state = repoManager.addRepoState.collectAsState().value - BackHandler(state is AddRepoError) { - // reset state when going back on error screen - repoManager.abortAddingRepository() + AppTheme(pureBlack = pureBlack) { + FDroidContent { + val state = repoManager.addRepoState.collectAsState().value + BackHandler(state is AddRepoError) { + // reset state when going back on error screen + repoManager.abortAddingRepository() + } + AddRepoIntroScreen( + state = state, + onFetchRepo = this::onFetchRepo, + onAddRepo = { repoManager.addFetchedRepository() }, + onBackClicked = { onBackPressedDispatcher.onBackPressed() }, + ) } - AddRepoIntroScreen( - state = state, - onFetchRepo = this::onFetchRepo, - onAddRepo = { repoManager.addFetchedRepository() }, - onBackClicked = { onBackPressedDispatcher.onBackPressed() }, - ) } } addOnNewIntentListener { intent -> diff --git a/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoErrorScreen.kt b/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoErrorScreen.kt index c3d1180a2..42c9c2cfa 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoErrorScreen.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoErrorScreen.kt @@ -7,16 +7,14 @@ import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.material.ContentAlpha -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Error +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment.Companion.CenterHorizontally import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalInspectionMode @@ -48,7 +46,7 @@ fun AddRepoErrorScreen(paddingValues: PaddingValues, state: AddRepoError) { Image( imageVector = Icons.Default.Error, contentDescription = null, - colorFilter = ColorFilter.tint(MaterialTheme.colors.error), + colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.error), modifier = Modifier.size(48.dp), ) val title = when (state.errorType) { @@ -67,13 +65,13 @@ fun AddRepoErrorScreen(paddingValues: PaddingValues, state: AddRepoError) { } Text( text = title, - style = MaterialTheme.typography.h5, + style = MaterialTheme.typography.headlineSmall, textAlign = TextAlign.Center, ) if (state.exception != null) Text( text = state.exception.toString(), - style = MaterialTheme.typography.body1, - modifier = Modifier.alpha(ContentAlpha.medium), + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurfaceVariant, ) } } diff --git a/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoIntroScreen.kt b/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoIntroScreen.kt index ed8c6f795..2a63ebd03 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoIntroScreen.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoIntroScreen.kt @@ -4,6 +4,7 @@ import android.content.res.Configuration.UI_MODE_NIGHT_YES import androidx.activity.compose.rememberLauncherForActivityResult import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement.SpaceBetween import androidx.compose.foundation.layout.Arrangement.spacedBy import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -18,22 +19,21 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll -import androidx.compose.material.ButtonDefaults -import androidx.compose.material.ContentAlpha -import androidx.compose.material.Icon -import androidx.compose.material.IconButton -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Scaffold -import androidx.compose.material.Text -import androidx.compose.material.TextField -import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.ArrowDropDown import androidx.compose.material.icons.filled.ArrowDropUp import androidx.compose.material.icons.filled.ContentPaste import androidx.compose.material.icons.filled.QrCode -import androidx.compose.material.primarySurface +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -44,7 +44,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment.Companion.CenterHorizontally import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.layout.onGloballyPositioned @@ -72,6 +71,7 @@ import org.fdroid.repo.FetchResult import org.fdroid.repo.Fetching import org.fdroid.repo.None +@OptIn(ExperimentalMaterial3Api::class) @Composable fun AddRepoIntroScreen( state: AddRepoState, @@ -92,8 +92,6 @@ fun AddRepoIntroScreen( Scaffold(topBar = { TopAppBar( - elevation = 4.dp, - backgroundColor = MaterialTheme.colors.primarySurface, navigationIcon = { IconButton(onClick = onBackClicked) { Icon(Icons.Filled.ArrowBack, stringResource(R.string.back)) @@ -102,7 +100,6 @@ fun AddRepoIntroScreen( title = { Text( text = appBarTitle, - modifier = Modifier.alpha(ContentAlpha.high), ) }, ) @@ -137,7 +134,7 @@ fun AddRepoIntroContent(paddingValues: PaddingValues, onFetchRepo: (String) -> U ) { Text( text = stringResource(R.string.repo_intro), - style = MaterialTheme.typography.body1, + style = MaterialTheme.typography.bodyLarge, ) val startForResult = rememberLauncherForActivityResult(ScanContract()) { result -> if (result.contents != null) { @@ -160,7 +157,7 @@ fun AddRepoIntroContent(paddingValues: PaddingValues, onFetchRepo: (String) -> U val isPreview = LocalInspectionMode.current var manualExpanded by rememberSaveable { mutableStateOf(isPreview) } Row( - horizontalArrangement = spacedBy(16.dp), + horizontalArrangement = SpaceBetween, verticalAlignment = CenterVertically, modifier = Modifier .fillMaxWidth() @@ -168,9 +165,11 @@ fun AddRepoIntroContent(paddingValues: PaddingValues, onFetchRepo: (String) -> U .clickable { manualExpanded = !manualExpanded }, ) { Text( - text = stringResource(R.string.repo_enter_url) + text = stringResource(R.string.repo_enter_url), + style = MaterialTheme.typography.bodyMedium, + // avoid occupying the whole row + modifier = Modifier.weight(1f), ) - Spacer(modifier = Modifier.weight(1f)) Icon( imageVector = if (manualExpanded) { Icons.Default.ArrowDropUp diff --git a/app/src/main/java/org/fdroid/fdroid/views/repos/ManageReposActivity.java b/app/src/main/java/org/fdroid/fdroid/views/repos/ManageReposActivity.java index e4099161e..a6e1264f6 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/repos/ManageReposActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/views/repos/ManageReposActivity.java @@ -32,7 +32,6 @@ import android.view.MenuItem; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.NavUtils; import androidx.core.app.TaskStackBuilder; @@ -193,15 +192,15 @@ public class ManageReposActivity extends AppCompatActivity implements RepoAdapte @Override public void onToggleEnabled(Repository repo) { if (repo.getEnabled()) { - new AlertDialog.Builder(this) - .setMessage(R.string.repo_disable_warning) - .setPositiveButton(R.string.repo_disable_warning_button, (dialog, id) -> { - disableRepo(repo); - dialog.dismiss(); - }) - .setNegativeButton(R.string.cancel, (dialog, id) -> dialog.cancel()) - .setOnCancelListener(dialog -> repoAdapter.updateRepoItem(repo)) // reset toggle - .show(); + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this); + builder.setMessage(R.string.repo_disable_warning); + builder.setPositiveButton(R.string.repo_disable_warning_button, (dialog, id) -> { + disableRepo(repo); + dialog.dismiss(); + }); + builder.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.cancel()); + builder.setOnCancelListener(dialog -> repoAdapter.updateRepoItem(repo)); // reset toggle + builder.show(); } else { Utils.runOffUiThread(() -> { repoManager.setRepositoryEnabled(repo.getRepoId(), true); diff --git a/app/src/main/java/org/fdroid/fdroid/views/repos/RepoDetailsActivity.java b/app/src/main/java/org/fdroid/fdroid/views/repos/RepoDetailsActivity.java index e0990fd56..ef6369925 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/repos/RepoDetailsActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/views/repos/RepoDetailsActivity.java @@ -27,7 +27,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.widget.SwitchCompat; import androidx.core.app.NavUtils; import androidx.core.content.ContextCompat; import androidx.lifecycle.ViewModelProvider; @@ -35,6 +34,8 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.appbar.MaterialToolbar; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.materialswitch.MaterialSwitch; import com.google.android.material.textfield.TextInputLayout; import org.fdroid.database.AppDao; @@ -203,17 +204,17 @@ public class RepoDetailsActivity extends AppCompatActivity { updateRepoView(); }); - SwitchCompat switchCompat = findViewById(R.id.archiveRepo); + MaterialSwitch archiveRepoSwitch = findViewById(R.id.archiveRepo); model.getLiveData().observe(this, s -> { Boolean enabled = s.getArchiveEnabled(); if (enabled == null) { - switchCompat.setEnabled(false); + archiveRepoSwitch.setEnabled(false); } else { - switchCompat.setEnabled(true); - switchCompat.setChecked(enabled); + archiveRepoSwitch.setEnabled(true); + archiveRepoSwitch.setChecked(enabled); } }); - switchCompat.setOnClickListener(v -> model.setArchiveRepoEnabled(repo, switchCompat.isChecked())); + archiveRepoSwitch.setOnClickListener(v -> model.setArchiveRepoEnabled(repo, archiveRepoSwitch.isChecked())); } @Override @@ -452,7 +453,7 @@ public class RepoDetailsActivity extends AppCompatActivity { } private void promptForDelete() { - new AlertDialog.Builder(this) + new MaterialAlertDialogBuilder(this) .setTitle(R.string.repo_confirm_delete_title) .setMessage(R.string.repo_confirm_delete_body) .setPositiveButton(R.string.delete, (dialog, which) -> { @@ -469,7 +470,7 @@ public class RepoDetailsActivity extends AppCompatActivity { private void showChangePasswordDialog(final View parentView) { final View view = getLayoutInflater().inflate(R.layout.login, (ViewGroup) parentView, false); - final AlertDialog credentialsDialog = new AlertDialog.Builder(this).setView(view).create(); + final AlertDialog credentialsDialog = new MaterialAlertDialogBuilder(this).setView(view).create(); final TextInputLayout nameInputLayout = view.findViewById(R.id.edit_name); final TextInputLayout passwordInputLayout = view.findViewById(R.id.edit_password); final EditText nameInput = nameInputLayout.getEditText(); diff --git a/app/src/main/java/org/fdroid/fdroid/views/repos/RepoPreviewScreen.kt b/app/src/main/java/org/fdroid/fdroid/views/repos/RepoPreviewScreen.kt index e251783e5..a2a709360 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/repos/RepoPreviewScreen.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/repos/RepoPreviewScreen.kt @@ -15,17 +15,15 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.items -import androidx.compose.material.Card -import androidx.compose.material.ContentAlpha -import androidx.compose.material.LinearProgressIndicator -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text +import androidx.compose.material3.Card +import androidx.compose.material3.LinearProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Alignment.Companion.End import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.res.colorResource @@ -85,11 +83,11 @@ fun RepoPreviewScreen( ) { Text( text = stringResource(R.string.repo_preview_included_apps), - style = MaterialTheme.typography.body1, + style = MaterialTheme.typography.bodyLarge, ) Text( text = state.apps.size.toString(), - style = MaterialTheme.typography.body1, + style = MaterialTheme.typography.bodyLarge, ) if (!state.done) LinearProgressIndicator(modifier = Modifier.weight(1f)) } @@ -165,16 +163,16 @@ fun RepoPreviewHeader( text = repo.getName(localeList) ?: "Unknown Repository", maxLines = 1, fontWeight = FontWeight.Bold, - style = MaterialTheme.typography.body1, + style = MaterialTheme.typography.bodyLarge, ) Text( text = repo.address.replaceFirst("https://", ""), - style = MaterialTheme.typography.body2, - modifier = Modifier.alpha(ContentAlpha.medium), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, ) Text( text = Utils.formatLastUpdated(LocalContext.current.resources, repo.timestamp), - style = MaterialTheme.typography.body2, + style = MaterialTheme.typography.bodyMedium, ) } } @@ -190,7 +188,7 @@ fun RepoPreviewHeader( .padding(8.dp), text = warningText, textAlign = TextAlign.Center, - style = MaterialTheme.typography.body2, + style = MaterialTheme.typography.bodyLarge, color = colorResource(android.R.color.white), ) } @@ -208,7 +206,7 @@ fun RepoPreviewHeader( } if (description != null) Text( text = description, - style = MaterialTheme.typography.body2, + style = MaterialTheme.typography.bodyMedium, ) } } @@ -246,11 +244,11 @@ fun LazyItemScope.RepoPreviewApp( Column { Text( app.name ?: "Unknown app", - style = MaterialTheme.typography.body1, + style = MaterialTheme.typography.bodyLarge, ) Text( app.summary ?: "", - style = MaterialTheme.typography.body2, + style = MaterialTheme.typography.bodyMedium, ) } } diff --git a/app/src/main/java/org/fdroid/fdroid/views/repos/RepoProgressScreen.kt b/app/src/main/java/org/fdroid/fdroid/views/repos/RepoProgressScreen.kt index a5b256fe8..68ea12042 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/repos/RepoProgressScreen.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/repos/RepoProgressScreen.kt @@ -6,9 +6,9 @@ import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.material.CircularProgressIndicator -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment.Companion.CenterHorizontally import androidx.compose.ui.Alignment.Companion.CenterVertically @@ -31,7 +31,7 @@ fun RepoProgressScreen(paddingValues: PaddingValues, text: String) { ) { Text( text = text, - style = MaterialTheme.typography.h5, + style = MaterialTheme.typography.headlineSmall, ) CircularProgressIndicator(modifier = Modifier.size(64.dp)) } diff --git a/app/src/main/res/drawable/background_circle.xml b/app/src/main/res/drawable/background_circle.xml index d69609875..2bfb6e576 100644 --- a/app/src/main/res/drawable/background_circle.xml +++ b/app/src/main/res/drawable/background_circle.xml @@ -1,5 +1,5 @@ - + diff --git a/app/src/main/res/drawable/details_panel_donate_background_dark.xml b/app/src/main/res/drawable/details_panel_donate_background_dark.xml deleted file mode 100644 index 34aefb95a..000000000 --- a/app/src/main/res/drawable/details_panel_donate_background_dark.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/details_panel_donate_background_light.xml b/app/src/main/res/drawable/details_panel_donate_background_light.xml deleted file mode 100644 index 229c42b8b..000000000 --- a/app/src/main/res/drawable/details_panel_donate_background_light.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/seekbar_thumb.xml b/app/src/main/res/drawable/seekbar_thumb.xml index 7a0837c26..b924e5f80 100644 --- a/app/src/main/res/drawable/seekbar_thumb.xml +++ b/app/src/main/res/drawable/seekbar_thumb.xml @@ -5,7 +5,7 @@ - + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_install_history.xml b/app/src/main/res/layout/activity_install_history.xml index 5f93c152b..387bf84c2 100644 --- a/app/src/main/res/layout/activity_install_history.xml +++ b/app/src/main/res/layout/activity_install_history.xml @@ -18,8 +18,7 @@ android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" - app:title="@string/install_history" - style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface" /> + app:title="@string/install_history" /> @@ -166,7 +165,7 @@ style="@style/CaptionText" android:text="@string/repo_archive_toggle" /> - + android:layout_margin="4dp" + android:clickable="true" + android:focusable="true"> + app:title="@string/installed_apps__activity_title" /> diff --git a/app/src/main/res/layout/login.xml b/app/src/main/res/layout/login.xml index 26cf1bc3d..20d47397f 100644 --- a/app/src/main/res/layout/login.xml +++ b/app/src/main/res/layout/login.xml @@ -16,7 +16,7 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/preference_switch.xml b/app/src/main/res/layout/preference_switch.xml new file mode 100644 index 000000000..511e07bb8 --- /dev/null +++ b/app/src/main/res/layout/preference_switch.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/repo_item.xml b/app/src/main/res/layout/repo_item.xml index 2f0e6ec84..923aa2052 100644 --- a/app/src/main/res/layout/repo_item.xml +++ b/app/src/main/res/layout/repo_item.xml @@ -1,5 +1,5 @@ - - - + diff --git a/app/src/main/res/layout/repo_list_activity.xml b/app/src/main/res/layout/repo_list_activity.xml index 07097c934..642b1bef4 100644 --- a/app/src/main/res/layout/repo_list_activity.xml +++ b/app/src/main/res/layout/repo_list_activity.xml @@ -14,7 +14,6 @@ #ffcf6679 #ffb8b8b8 + + + + + + #A5C8FF + #00315F + #006DC7 + #FFFFFF + #ADD535 + #283500 + #83A800 + #080D00 + #EDB1FF + #52046E + #954FB0 + #FFFFFF + #FFB4AB + #690005 + #93000A + #FFDAD6 + #101319 + #E0E2EA + #101319 + #E0E2EA + #414752 + #C1C6D4 + #8B919E + #414752 + #E0E2EA + #2D3037 + #005FAF + #D4E3FF + #001C3A + #A5C8FF + #004786 + #C8F250 + #161F00 + #ADD535 + #3B4D00 + #F9D8FF + #320046 + #EDB1FF + #6B2687 + #101319 + #363940 + #0B0E14 + #181C21 + #1C2026 + #272A30 + #32353B diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index ca8861484..ea2279cc9 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -15,25 +15,9 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - + - - - - diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index b2376bf63..f9dbd31f6 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -11,56 +11,47 @@ - - - - - - - - - - - + + + + + diff --git a/app/src/main/res/values/styles_detail.xml b/app/src/main/res/values/styles_detail.xml index 98c7d79b4..3b407f6d1 100644 --- a/app/src/main/res/values/styles_detail.xml +++ b/app/src/main/res/values/styles_detail.xml @@ -11,16 +11,11 @@ 18dp 18dp true - @style/ThemeOverlay.App.DetailsButton @null 0.05 - - - - + - - diff --git a/app/src/main/res/values/theme_overlays.xml b/app/src/main/res/values/theme_overlays.xml new file mode 100644 index 000000000..2bc05e24c --- /dev/null +++ b/app/src/main/res/values/theme_overlays.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index dd7d30843..2c19523e1 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -15,9 +15,12 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - - @@ -87,7 +123,7 @@ - - diff --git a/app/src/main/res/values/type.xml b/app/src/main/res/values/type.xml index c22d613e1..c9640c776 100644 --- a/app/src/main/res/values/type.xml +++ b/app/src/main/res/values/type.xml @@ -14,14 +14,4 @@ ~ limitations under the License. --> - - - - - - - + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 391681dfe..8c82f7a49 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -97,8 +97,7 @@ androidx-compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" } androidx-compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" } androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose" } androidx-compose-material-icons-extended = { module = "androidx.compose.material:material-icons-extended" } -androidx-compose-material = { module = "androidx.compose.material:material" } -accompanist-themeadapter-material = { module = "com.google.accompanist:accompanist-themeadapter-material", version.ref = "accompanistThemeadapterMaterial" } +androidx-compose-material3 = { module = "androidx.compose.material3:material3" } accompanist-drawablepainter = { module = "com.google.accompanist:accompanist-drawablepainter", version.ref = "accompanistDrawablepainter" } androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidxActivityCompose" } diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 5a424fc96..1da9e1e3f 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -961,6 +961,21 @@ + + + + + + + + + + + + + + + @@ -1950,6 +1965,11 @@ + + + + + From e824f5666036ce88793c4dcecaea0f4cbad560b6 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 22 Jan 2025 14:55:03 -0300 Subject: [PATCH 2/9] Unify theme and content, fix some minor issues --- app/src/full/res/layout/swap_start_swap.xml | 2 +- .../org/fdroid/fdroid/compose/ComposeUtils.kt | 9 +---- .../java/org/fdroid/fdroid/ui/theme/Theme.kt | 40 ++++--------------- .../fdroid/views/IpfsGatewayAddActivity.kt | 23 +++++------ .../views/IpfsGatewaySettingsActivity.kt | 36 +++++++---------- .../fdroid/views/appdetails/RepoChooser.kt | 36 ++++++++--------- .../fdroid/views/main/LatestViewBinder.java | 17 +++----- .../fdroid/views/repos/AddRepoActivity.kt | 30 ++++++-------- .../fdroid/views/repos/AddRepoErrorScreen.kt | 12 +++--- .../fdroid/views/repos/AddRepoIntroScreen.kt | 10 ++--- .../fdroid/views/repos/RepoPreviewScreen.kt | 14 +++---- .../fdroid/views/repos/RepoProgressScreen.kt | 4 +- .../main/res/layout/app_details2_header.xml | 1 + app/src/main/res/layout/main_tab_latest.xml | 30 +++++++++----- app/src/main/res/values/styles_detail.xml | 3 +- 15 files changed, 112 insertions(+), 155 deletions(-) diff --git a/app/src/full/res/layout/swap_start_swap.xml b/app/src/full/res/layout/swap_start_swap.xml index 080b23dec..ebda7b3e2 100644 --- a/app/src/full/res/layout/swap_start_swap.xml +++ b/app/src/full/res/layout/swap_start_swap.xml @@ -193,9 +193,9 @@ android:layout_width="24dp" android:layout_height="24dp" android:indeterminate="true" - app:showAnimationBehavior="inward" app:hideAnimationBehavior="outward" app:indicatorSize="24dp" + app:showAnimationBehavior="inward" app:trackCornerRadius="@dimen/mtrl_progress_indicator_full_rounded_corner_radius" /> diff --git a/app/src/main/java/org/fdroid/fdroid/compose/ComposeUtils.kt b/app/src/main/java/org/fdroid/fdroid/compose/ComposeUtils.kt index 2cdffe826..5a4ea16b1 100644 --- a/app/src/main/java/org/fdroid/fdroid/compose/ComposeUtils.kt +++ b/app/src/main/java/org/fdroid/fdroid/compose/ComposeUtils.kt @@ -10,28 +10,21 @@ import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton -import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.unit.dp import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.compose.LocalLifecycleOwner import java.util.Locale object ComposeUtils { - - @Composable - fun FDroidContent(content: @Composable () -> Unit) { - Surface(content = content) - } - @Composable fun FDroidButton( text: String, diff --git a/app/src/main/java/org/fdroid/fdroid/ui/theme/Theme.kt b/app/src/main/java/org/fdroid/fdroid/ui/theme/Theme.kt index 15d080d02..8ec84b582 100644 --- a/app/src/main/java/org/fdroid/fdroid/ui/theme/Theme.kt +++ b/app/src/main/java/org/fdroid/fdroid/ui/theme/Theme.kt @@ -1,16 +1,13 @@ package org.fdroid.fdroid.ui.theme -import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface import androidx.compose.material3.darkColorScheme -import androidx.compose.material3.dynamicDarkColorScheme -import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable -import androidx.compose.runtime.Immutable import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext +import org.fdroid.fdroid.Preferences // The followings are generated by the Material Theme Builder with modifications // https://www.figma.com/community/plugin/1034969338659738588 @@ -80,41 +77,20 @@ private val darkScheme = darkColorScheme( private val pureBlackScheme = darkScheme.copy(background = Color.Black, surface = Color(0xff1e1e1e)) -@Immutable -data class ColorFamily( - val color: Color, - val onColor: Color, - val colorContainer: Color, - val onColorContainer: Color -) - -val unspecified_scheme = ColorFamily( - Color.Unspecified, Color.Unspecified, Color.Unspecified, Color.Unspecified -) - -// Pure black theme logic is added on top of the generated code @Composable -fun AppTheme( +fun FDroidContent( darkTheme: Boolean = isSystemInDarkTheme(), - pureBlack: Boolean = false, - // Dynamic color is available on Android 12+ - dynamicColor: Boolean = false, - content: @Composable() () -> Unit + pureBlack: Boolean = Preferences.get().isPureBlack, + content: @Composable () -> Unit ) { val colorScheme = when { - dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { - val context = LocalContext.current - if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) - } - darkTheme && pureBlack -> pureBlackScheme darkTheme -> darkScheme else -> lightScheme } - MaterialTheme( colorScheme = colorScheme, - content = content - ) + ) { + Surface(content = content) + } } - diff --git a/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewayAddActivity.kt b/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewayAddActivity.kt index e0c1a5c26..30e76d84e 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewayAddActivity.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewayAddActivity.kt @@ -11,7 +11,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.ContentPaste import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon @@ -40,8 +40,7 @@ import androidx.compose.ui.unit.dp import org.fdroid.fdroid.Preferences import org.fdroid.fdroid.R import org.fdroid.fdroid.compose.ComposeUtils -import org.fdroid.fdroid.compose.ComposeUtils.FDroidContent -import org.fdroid.fdroid.ui.theme.AppTheme +import org.fdroid.fdroid.ui.theme.FDroidContent class IpfsGatewayAddActivity : AppCompatActivity() { @@ -51,7 +50,7 @@ class IpfsGatewayAddActivity : AppCompatActivity() { val pureBlack = Preferences.get().isPureBlack setContent { - AppTheme(pureBlack = pureBlack) { + FDroidContent(pureBlack = pureBlack) { IpfsGatewayAddScreen( onBackClicked = { onBackPressedDispatcher.onBackPressed() }, onAddUserGateway = { url -> @@ -86,13 +85,13 @@ fun IpfsGatewayAddScreen( topBar = { TopAppBar( navigationIcon = { - IconButton(onClick = onBackClicked) { - Icon(Icons.Filled.ArrowBack, stringResource(R.string.back)) - } - }, - title = { - Text( - text = stringResource(R.string.ipfsgw_add_title), + IconButton(onClick = onBackClicked) { + Icon(Icons.AutoMirrored.Filled.ArrowBack, stringResource(R.string.back)) + } + }, + title = { + Text( + text = stringResource(R.string.ipfsgw_add_title), ) }, ) @@ -180,7 +179,7 @@ fun IpfsGatewayAddScreen( @Composable @Preview fun IpfsGatewayAddScreenPreview() { - FDroidContent { + FDroidContent(pureBlack = true) { IpfsGatewayAddScreen( onBackClicked = {}, onAddUserGateway = {}, diff --git a/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewaySettingsActivity.kt b/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewaySettingsActivity.kt index ccd7f306c..887e1b983 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewaySettingsActivity.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/IpfsGatewaySettingsActivity.kt @@ -15,8 +15,8 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Add -import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.DeleteForever import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FloatingActionButton @@ -44,28 +44,20 @@ import org.fdroid.fdroid.IPreferencesIpfs import org.fdroid.fdroid.Preferences import org.fdroid.fdroid.R import org.fdroid.fdroid.compose.ComposeUtils.CaptionText -import org.fdroid.fdroid.compose.ComposeUtils.FDroidContent import org.fdroid.fdroid.compose.ComposeUtils.LifecycleEventListener -import org.fdroid.fdroid.ui.theme.AppTheme +import org.fdroid.fdroid.ui.theme.FDroidContent class IpfsGatewaySettingsActivity : AppCompatActivity() { - lateinit var prefs: Preferences - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - - prefs = Preferences.get() - val pureBlack = prefs.isPureBlack - + val prefs = Preferences.get() setContent { - AppTheme(pureBlack = pureBlack) { - FDroidContent { - IpfsGatewaySettingsScreen( + FDroidContent { + IpfsGatewaySettingsScreen( prefs = prefs, - onBackClicked = { onBackPressedDispatcher.onBackPressed() }, + onBackClicked = { onBackPressedDispatcher.onBackPressed() }, ) - } } } } @@ -84,13 +76,13 @@ fun IpfsGatewaySettingsScreen( topBar = { TopAppBar( navigationIcon = { - IconButton(onClick = onBackClicked) { - Icon(Icons.Filled.ArrowBack, stringResource(R.string.back)) - } - }, - title = { - Text( - text = stringResource(R.string.ipfsgw_title), + IconButton(onClick = onBackClicked) { + Icon(Icons.AutoMirrored.Filled.ArrowBack, stringResource(R.string.back)) + } + }, + title = { + Text( + text = stringResource(R.string.ipfsgw_title), ) }, ) @@ -254,7 +246,7 @@ fun IpfsGatewaySettingsScreenPreview() { throw NotImplementedError() } - FDroidContent { + FDroidContent(pureBlack = true) { IpfsGatewaySettingsScreen( prefs = prefs, onBackClicked = {}, diff --git a/app/src/main/java/org/fdroid/fdroid/views/appdetails/RepoChooser.kt b/app/src/main/java/org/fdroid/fdroid/views/appdetails/RepoChooser.kt index 6527b9759..4c4919d9e 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/appdetails/RepoChooser.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/appdetails/RepoChooser.kt @@ -1,6 +1,7 @@ package org.fdroid.fdroid.views.appdetails import android.content.res.Configuration +import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -11,7 +12,6 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowDropDown import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField @@ -36,11 +36,9 @@ import androidx.compose.ui.unit.dp import androidx.core.os.LocaleListCompat import androidx.core.util.Consumer import org.fdroid.database.Repository -import org.fdroid.fdroid.Preferences import org.fdroid.fdroid.R -import org.fdroid.fdroid.compose.ComposeUtils.FDroidContent import org.fdroid.fdroid.compose.ComposeUtils.FDroidOutlineButton -import org.fdroid.fdroid.ui.theme.AppTheme +import org.fdroid.fdroid.ui.theme.FDroidContent import org.fdroid.fdroid.views.repos.RepoIcon import org.fdroid.index.IndexFormatVersion.TWO @@ -55,24 +53,22 @@ fun setContentRepoChooser( onRepoChanged: Consumer, onPreferredRepoChanged: Consumer, ) { - val pureBlack = Preferences.get().isPureBlack - composeView.setContent { - AppTheme(pureBlack = pureBlack) { - FDroidContent { - RepoChooser( - repos = repos, - currentRepoId = currentRepoId, - preferredRepoId = preferredRepoId, - onRepoChanged = onRepoChanged::accept, - onPreferredRepoChanged = onPreferredRepoChanged::accept, - ) - } + FDroidContent { + RepoChooser( + repos = repos, + currentRepoId = currentRepoId, + preferredRepoId = preferredRepoId, + onRepoChanged = onRepoChanged::accept, + onPreferredRepoChanged = onPreferredRepoChanged::accept, + // FIXME background color in light theme is not *exactly* the same, but ok for now + // see https://m3.material.io/components/cards/specs + modifier = Modifier.background(MaterialTheme.colorScheme.surfaceContainerLow), + ) } } } -@OptIn(ExperimentalMaterial3Api::class) @Composable fun RepoChooser( repos: List, @@ -200,7 +196,7 @@ private fun getRepoString(repo: Repository, isPreferred: Boolean) = buildAnnotat @Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) fun RepoChooserSingleRepoPreview() { val repo1 = Repository(1L, "1", 1L, TWO, "null", 1L, 1, 1L) - FDroidContent { + FDroidContent(pureBlack = true) { RepoChooser(listOf(repo1), 1L, 1L, {}, {}) } } @@ -211,7 +207,7 @@ fun RepoChooserPreview() { val repo1 = Repository(1L, "1", 1L, TWO, "null", 1L, 1, 1L) val repo2 = Repository(2L, "2", 2L, TWO, "null", 2L, 2, 2L) val repo3 = Repository(3L, "2", 3L, TWO, "null", 3L, 3, 3L) - FDroidContent { + FDroidContent(pureBlack = true) { RepoChooser(listOf(repo1, repo2, repo3), 1L, 1L, {}, {}) } } @@ -222,7 +218,7 @@ fun RepoChooserNightPreview() { val repo1 = Repository(1L, "1", 1L, TWO, "null", 1L, 1, 1L) val repo2 = Repository(2L, "2", 2L, TWO, "null", 2L, 2, 2L) val repo3 = Repository(3L, "2", 3L, TWO, "null", 3L, 3, 3L) - FDroidContent { + FDroidContent(pureBlack = true) { RepoChooser(listOf(repo1, repo2, repo3), 1L, 2L, {}, {}) } } diff --git a/app/src/main/java/org/fdroid/fdroid/views/main/LatestViewBinder.java b/app/src/main/java/org/fdroid/fdroid/views/main/LatestViewBinder.java index f13f499d0..0caa8557c 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/main/LatestViewBinder.java +++ b/app/src/main/java/org/fdroid/fdroid/views/main/LatestViewBinder.java @@ -3,7 +3,6 @@ package org.fdroid.fdroid.views.main; import android.content.Intent; import android.view.View; import android.widget.FrameLayout; -import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.NonNull; @@ -44,12 +43,11 @@ class LatestViewBinder implements Observer>, ChangeListene private final LatestAdapter latestAdapter; private final AppCompatActivity activity; + private final CircularProgressIndicator progressBar; private final TextView emptyState; private final RecyclerView appList; private final FDroidDatabase db; - private CircularProgressIndicator progressBar; - LatestViewBinder(final AppCompatActivity activity, FrameLayout parent) { this.activity = activity; activity.getLifecycle().addObserver(new DefaultLifecycleObserver() { @@ -76,6 +74,7 @@ class LatestViewBinder implements Observer>, ChangeListene layoutManager.setSpanSizeLookup(latestAdapter.getSpanSizeLookup()); emptyState = latestView.findViewById(R.id.empty_state); + progressBar = latestView.findViewById(R.id.progress_bar); appList = latestView.findViewById(R.id.app_list); appList.setHasFixedSize(true); @@ -113,6 +112,7 @@ class LatestViewBinder implements Observer>, ChangeListene appList.setVisibility(View.GONE); explainEmptyStateToUser(); } else { + progressBar.setVisibility(View.GONE); emptyState.setVisibility(View.GONE); appList.setVisibility(View.VISIBLE); } @@ -122,7 +122,7 @@ class LatestViewBinder implements Observer>, ChangeListene public void onPreferenceChange() { // reload and re-filter apps from DB when anti-feature settings change LiveData> liveData = db.getAppDao().getAppOverviewItems(200); - liveData.observe(activity, new Observer>() { + liveData.observe(activity, new Observer<>() { @Override public void onChanged(List items) { LatestViewBinder.this.onChanged(items); @@ -166,17 +166,12 @@ class LatestViewBinder implements Observer>, ChangeListene private void explainEmptyStateToUser() { if (Preferences.get().isIndexNeverUpdated() && FDroidApp.getRepoUpdateManager(activity).isUpdating().getValue()) { - if (progressBar != null) { - return; - } - LinearLayout linearLayout = (LinearLayout) appList.getParent(); - progressBar = new CircularProgressIndicator(activity); - progressBar.setId(R.id.progress_bar); - linearLayout.addView(progressBar); + progressBar.setVisibility(View.VISIBLE); emptyState.setVisibility(View.GONE); appList.setVisibility(View.GONE); return; } + progressBar.setVisibility(View.GONE); StringBuilder emptyStateText = new StringBuilder(); emptyStateText.append(activity.getString(R.string.latest__empty_state__no_recent_apps)); diff --git a/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoActivity.kt b/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoActivity.kt index 95ef299f8..73e406a88 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoActivity.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoActivity.kt @@ -19,9 +19,8 @@ import kotlinx.coroutines.launch import org.fdroid.fdroid.FDroidApp import org.fdroid.fdroid.Preferences import org.fdroid.fdroid.R -import org.fdroid.fdroid.compose.ComposeUtils.FDroidContent import org.fdroid.fdroid.nearby.SwapService -import org.fdroid.fdroid.ui.theme.AppTheme +import org.fdroid.fdroid.ui.theme.FDroidContent import org.fdroid.fdroid.views.apps.AppListActivity import org.fdroid.fdroid.views.apps.AppListActivity.EXTRA_REPO_ID import org.fdroid.fdroid.work.RepoUpdateWorker @@ -54,24 +53,19 @@ class AddRepoActivity : AppCompatActivity() { } } } - - val pureBlack = Preferences.get().isPureBlack - setContent { - AppTheme(pureBlack = pureBlack) { - FDroidContent { - val state = repoManager.addRepoState.collectAsState().value - BackHandler(state is AddRepoError) { - // reset state when going back on error screen - repoManager.abortAddingRepository() - } - AddRepoIntroScreen( - state = state, - onFetchRepo = this::onFetchRepo, - onAddRepo = { repoManager.addFetchedRepository() }, - onBackClicked = { onBackPressedDispatcher.onBackPressed() }, - ) + FDroidContent { + val state = repoManager.addRepoState.collectAsState().value + BackHandler(state is AddRepoError) { + // reset state when going back on error screen + repoManager.abortAddingRepository() } + AddRepoIntroScreen( + state = state, + onFetchRepo = this::onFetchRepo, + onAddRepo = { repoManager.addFetchedRepository() }, + onBackClicked = { onBackPressedDispatcher.onBackPressed() }, + ) } } addOnNewIntentListener { intent -> diff --git a/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoErrorScreen.kt b/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoErrorScreen.kt index 42c9c2cfa..749a07ccb 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoErrorScreen.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoErrorScreen.kt @@ -23,7 +23,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import org.fdroid.fdroid.R -import org.fdroid.fdroid.compose.ComposeUtils +import org.fdroid.fdroid.ui.theme.FDroidContent import org.fdroid.fdroid.views.repos.ManageReposActivity.getDisallowInstallUnknownSourcesErrorMessage import org.fdroid.repo.AddRepoError import org.fdroid.repo.AddRepoError.ErrorType.INVALID_FINGERPRINT @@ -79,7 +79,7 @@ fun AddRepoErrorScreen(paddingValues: PaddingValues, state: AddRepoError) { @Preview @Composable fun AddRepoErrorInvalidFingerprintPreview() { - ComposeUtils.FDroidContent { + FDroidContent(pureBlack = true) { AddRepoErrorScreen(PaddingValues(0.dp), AddRepoError(INVALID_FINGERPRINT)) } } @@ -87,7 +87,7 @@ fun AddRepoErrorInvalidFingerprintPreview() { @Preview @Composable fun AddRepoErrorIoErrorPreview() { - ComposeUtils.FDroidContent { + FDroidContent(pureBlack = true) { AddRepoErrorScreen(PaddingValues(0.dp), AddRepoError(IO_ERROR, IOException("foo bar"))) } } @@ -95,7 +95,7 @@ fun AddRepoErrorIoErrorPreview() { @Preview @Composable fun AddRepoErrorInvalidIndexPreview() { - ComposeUtils.FDroidContent { + FDroidContent(pureBlack = true) { AddRepoErrorScreen( PaddingValues(0.dp), AddRepoError(INVALID_INDEX, RuntimeException("foo bar")) @@ -106,7 +106,7 @@ fun AddRepoErrorInvalidIndexPreview() { @Preview @Composable fun AddRepoErrorUnknownSourcesPreview() { - ComposeUtils.FDroidContent { + FDroidContent(pureBlack = true) { AddRepoErrorScreen(PaddingValues(0.dp), AddRepoError(UNKNOWN_SOURCES_DISALLOWED)) } } @@ -114,7 +114,7 @@ fun AddRepoErrorUnknownSourcesPreview() { @Preview @Composable fun AddRepoErrorArchivePreview() { - ComposeUtils.FDroidContent { + FDroidContent(pureBlack = true) { AddRepoErrorScreen(PaddingValues(0.dp), AddRepoError(IS_ARCHIVE_REPO)) } } diff --git a/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoIntroScreen.kt b/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoIntroScreen.kt index 2a63ebd03..326451069 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoIntroScreen.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/repos/AddRepoIntroScreen.kt @@ -20,7 +20,7 @@ import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.ArrowDropDown import androidx.compose.material.icons.filled.ArrowDropUp import androidx.compose.material.icons.filled.ContentPaste @@ -61,8 +61,8 @@ import com.journeyapps.barcodescanner.ScanOptions import com.journeyapps.barcodescanner.ScanOptions.QR_CODE import org.fdroid.fdroid.R import org.fdroid.fdroid.compose.ComposeUtils.FDroidButton -import org.fdroid.fdroid.compose.ComposeUtils.FDroidContent import org.fdroid.fdroid.compose.ComposeUtils.FDroidOutlineButton +import org.fdroid.fdroid.ui.theme.FDroidContent import org.fdroid.repo.AddRepoError import org.fdroid.repo.AddRepoState import org.fdroid.repo.Added @@ -94,7 +94,7 @@ fun AddRepoIntroScreen( TopAppBar( navigationIcon = { IconButton(onClick = onBackClicked) { - Icon(Icons.Filled.ArrowBack, stringResource(R.string.back)) + Icon(Icons.AutoMirrored.Filled.ArrowBack, stringResource(R.string.back)) } }, title = { @@ -232,7 +232,7 @@ fun AddRepoIntroContent(paddingValues: PaddingValues, onFetchRepo: (String) -> U @Composable @Preview fun AddRepoIntroScreenPreview() { - FDroidContent { + FDroidContent(pureBlack = true) { AddRepoIntroScreen(None, {}, {}) {} } } @@ -240,7 +240,7 @@ fun AddRepoIntroScreenPreview() { @Composable @Preview(uiMode = UI_MODE_NIGHT_YES, widthDp = 720, heightDp = 360) fun AddRepoIntroScreenPreviewNight() { - FDroidContent { + FDroidContent(pureBlack = true) { AddRepoIntroScreen(None, {}, {}) {} } } diff --git a/app/src/main/java/org/fdroid/fdroid/views/repos/RepoPreviewScreen.kt b/app/src/main/java/org/fdroid/fdroid/views/repos/RepoPreviewScreen.kt index a2a709360..83483390b 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/repos/RepoPreviewScreen.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/repos/RepoPreviewScreen.kt @@ -45,7 +45,7 @@ import org.fdroid.fdroid.R import org.fdroid.fdroid.Utils import org.fdroid.fdroid.Utils.getGlideModel import org.fdroid.fdroid.compose.ComposeUtils.FDroidButton -import org.fdroid.fdroid.compose.ComposeUtils.FDroidContent +import org.fdroid.fdroid.ui.theme.FDroidContent import org.fdroid.index.v2.FileV2 import org.fdroid.repo.FetchResult.IsExistingMirror import org.fdroid.repo.FetchResult.IsExistingRepository @@ -221,7 +221,7 @@ fun LazyItemScope.RepoPreviewApp( val isDevPreview = LocalInspectionMode.current Card( modifier = Modifier - .animateItemPlacement() + .animateItem() .fillMaxWidth(), ) { Row( @@ -284,7 +284,7 @@ fun RepoPreviewScreenFetchingPreview() { override fun getIcon(localeList: LocaleListCompat): FileV2? = null } - FDroidContent { + FDroidContent(pureBlack = true) { RepoPreviewScreen( PaddingValues(0.dp), Fetching(address, repo, listOf(app1, app2, app3), IsNewRepository) @@ -296,7 +296,7 @@ fun RepoPreviewScreenFetchingPreview() { @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 720, heightDp = 360) fun RepoPreviewScreenNewMirrorPreview() { val repo = FDroidApp.createSwapRepo("https://example.org", "foo bar") - FDroidContent { + FDroidContent(pureBlack = true) { RepoPreviewScreen( PaddingValues(0.dp), Fetching("https://mirror.example.org", repo, emptyList(), IsNewMirror(0L)) @@ -308,7 +308,7 @@ fun RepoPreviewScreenNewMirrorPreview() { @Preview fun RepoPreviewScreenNewRepoAndNewMirrorPreview() { val repo = FDroidApp.createSwapRepo("https://example.org", "foo bar") - FDroidContent { + FDroidContent(pureBlack = true) { RepoPreviewScreen( PaddingValues(0.dp), Fetching("https://mirror.example.org", repo, emptyList(), IsNewRepoAndNewMirror) @@ -321,7 +321,7 @@ fun RepoPreviewScreenNewRepoAndNewMirrorPreview() { fun RepoPreviewScreenExistingRepoPreview() { val address = "https://example.org" val repo = FDroidApp.createSwapRepo(address, "foo bar") - FDroidContent { + FDroidContent(pureBlack = true) { RepoPreviewScreen( PaddingValues(0.dp), Fetching(address, repo, emptyList(), IsExistingRepository(0L)) @@ -333,7 +333,7 @@ fun RepoPreviewScreenExistingRepoPreview() { @Composable fun RepoPreviewScreenExistingMirrorPreview() { val repo = FDroidApp.createSwapRepo("https://example.org", "foo bar") - FDroidContent { + FDroidContent(pureBlack = true) { RepoPreviewScreen( PaddingValues(0.dp), Fetching("https://mirror.example.org", repo, emptyList(), IsExistingMirror(0L)) diff --git a/app/src/main/java/org/fdroid/fdroid/views/repos/RepoProgressScreen.kt b/app/src/main/java/org/fdroid/fdroid/views/repos/RepoProgressScreen.kt index 68ea12042..f7a42c0bb 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/repos/RepoProgressScreen.kt +++ b/app/src/main/java/org/fdroid/fdroid/views/repos/RepoProgressScreen.kt @@ -17,7 +17,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import org.fdroid.fdroid.R -import org.fdroid.fdroid.compose.ComposeUtils.FDroidContent +import org.fdroid.fdroid.ui.theme.FDroidContent @Composable fun RepoProgressScreen(paddingValues: PaddingValues, text: String) { @@ -40,7 +40,7 @@ fun RepoProgressScreen(paddingValues: PaddingValues, text: String) { @Preview @Composable fun FetchingRepoScreenPreview() { - FDroidContent { + FDroidContent(pureBlack = true) { RepoProgressScreen(PaddingValues(0.dp), stringResource(R.string.repo_state_fetching)) } } diff --git a/app/src/main/res/layout/app_details2_header.xml b/app/src/main/res/layout/app_details2_header.xml index d3f0961f7..130b33ffc 100644 --- a/app/src/main/res/layout/app_details2_header.xml +++ b/app/src/main/res/layout/app_details2_header.xml @@ -2,6 +2,7 @@ + android:layout_height="match_parent" + android:orientation="vertical"> + android:layout_height="match_parent"> + android:layout_height="wrap_content" + tools:background="#cdcdcd" /> + + @@ -31,8 +43,8 @@ android:id="@+id/app_list" android:layout_width="match_parent" android:layout_height="match_parent" - tools:listitem="@layout/app_card_normal" - android:scrollbars="vertical" /> + android:scrollbars="vertical" + tools:listitem="@layout/app_card_normal" /> @@ -40,4 +52,4 @@ - \ No newline at end of file + diff --git a/app/src/main/res/values/styles_detail.xml b/app/src/main/res/values/styles_detail.xml index 3b407f6d1..ad5a7dd65 100644 --- a/app/src/main/res/values/styles_detail.xml +++ b/app/src/main/res/values/styles_detail.xml @@ -10,7 +10,6 @@ 10dp 18dp 18dp - true @null 0.05 @@ -52,4 +51,4 @@ bold - \ No newline at end of file + From 922330c0896f6689656812c976c5418519402790 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Thu, 23 Jan 2025 10:53:50 -0300 Subject: [PATCH 3/9] Improve empty state icon colors Fixes #2927 --- app/src/main/res/layout/main_tab_updates.xml | 56 +++++++++++--------- app/src/main/res/values-night/themes.xml | 2 +- app/src/main/res/values/themes.xml | 2 +- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/app/src/main/res/layout/main_tab_updates.xml b/app/src/main/res/layout/main_tab_updates.xml index bc462410c..1138b91ba 100644 --- a/app/src/main/res/layout/main_tab_updates.xml +++ b/app/src/main/res/layout/main_tab_updates.xml @@ -2,14 +2,14 @@ + android:layout_height="match_parent" + android:orientation="vertical"> + android:layout_height="match_parent"> + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toBottomOf="@+id/banner_updating_repos" /> + app:trackCornerRadius="@dimen/mtrl_progress_indicator_full_rounded_corner_radius" + tools:visibility="visible" /> + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toRightOf="parent" + app:layout_constraintTop_toBottomOf="@+id/empty_state" + app:srcCompat="@drawable/no_updates_bg" + app:tint="?attr/mainTabSwapSplashTint" + tools:visibility="visible" /> + tools:listitem="@layout/app_list_item" /> - \ No newline at end of file + diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index ea2279cc9..b47c168d1 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -25,7 +25,7 @@ ?android:windowBackground - #2c2c2c + ?attr/colorSurfaceContainerLow #ffffff #ffffff #ffffff diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 2c19523e1..e6e2ab737 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -48,7 +48,7 @@ @drawable/ic_close - #f5f5f5 + ?attr/colorSurfaceDim #4a4a4a #424242 #424242 From 3906cad5fc5e04994710dd8d7064462c679931e1 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Thu, 23 Jan 2025 14:09:39 -0300 Subject: [PATCH 4/9] Address review feedback --- .../panic/DestructiveSwitchPreference.java | 5 +++ app/src/full/res/layout/swap_wifi_qr.xml | 39 ++++++++++--------- app/src/full/res/values/styles.xml | 3 +- app/src/full/res/xml/preferences_panic.xml | 5 ++- .../org/fdroid/fdroid/compose/ComposeUtils.kt | 5 +-- .../fdroid/views/AppDetailsActivity.java | 23 +++++------ .../fdroid/views/IpfsGatewayAddActivity.kt | 13 +++---- .../views/repos/ManageReposActivity.java | 18 ++++----- app/src/main/res/values/theme_overlays.xml | 1 + app/src/main/res/values/type.xml | 17 -------- 10 files changed, 56 insertions(+), 73 deletions(-) delete mode 100644 app/src/main/res/values/type.xml diff --git a/app/src/full/java/org/fdroid/fdroid/panic/DestructiveSwitchPreference.java b/app/src/full/java/org/fdroid/fdroid/panic/DestructiveSwitchPreference.java index f4560140a..b97d76af2 100644 --- a/app/src/full/java/org/fdroid/fdroid/panic/DestructiveSwitchPreference.java +++ b/app/src/full/java/org/fdroid/fdroid/panic/DestructiveSwitchPreference.java @@ -7,6 +7,8 @@ import androidx.core.content.ContextCompat; import androidx.preference.PreferenceViewHolder; import androidx.preference.SwitchPreferenceCompat; +import com.google.android.material.materialswitch.MaterialSwitch; + import org.fdroid.fdroid.R; public class DestructiveSwitchPreference extends SwitchPreferenceCompat { @@ -33,5 +35,8 @@ public class DestructiveSwitchPreference extends SwitchPreferenceCompat { return; } holder.itemView.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.panic_destructive)); + + //noinspection unused // TODO choose more fitting color below + MaterialSwitch switchView = holder.itemView.findViewById(androidx.preference.R.id.switchWidget); } } diff --git a/app/src/full/res/layout/swap_wifi_qr.xml b/app/src/full/res/layout/swap_wifi_qr.xml index 4825e4998..cccf5418e 100644 --- a/app/src/full/res/layout/swap_wifi_qr.xml +++ b/app/src/full/res/layout/swap_wifi_qr.xml @@ -1,35 +1,36 @@ - + android:background="@color/swap_blue" + swap:toolbarTitle="@string/swap_scan_qr"> + android:layout_height="wrap_content" + android:gravity="center" + android:orientation="vertical"> + android:text="@string/swap_scan_or_type_url" /> + tools:text="http://255.255.255.255:8888" />