Merge branch 'md3' into 'master'

Migrate to Material Design 3

Closes #1962, #2246, #2511, #2927, and #2926

See merge request fdroid/fdroidclient!1350
This commit is contained in:
Torsten Grote
2025-01-29 13:34:15 +00:00
76 changed files with 943 additions and 576 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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)));

View File

@@ -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)));

View File

@@ -20,8 +20,7 @@
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface" />
android:layout_height="?attr/actionBarSize" />
</com.google.android.material.appbar.AppBarLayout>

View File

@@ -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" />
</com.google.android.material.appbar.AppBarLayout>

View File

@@ -15,8 +15,7 @@
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface" />
android:layout_height="?attr/actionBarSize" />
</com.google.android.material.appbar.AppBarLayout>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.nearby.StartSwapView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:swap="http://schemas.android.com/apk/res-auto"
xmlns:swap="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -10,7 +10,7 @@
swap:toolbarTitle="@string/swap_nearby"
tools:context=".nearby.SwapWorkflowActivity">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:id="@+id/wifi_banner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -45,10 +45,10 @@
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/turn_on_wifi"
style="@style/Widget.MaterialComponents.Button.TextButton"
style="@style/ThemeOverlay.App.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_gravity="end"
android:layout_marginTop="8dp"
android:text="@string/turn_on_wifi" />
@@ -56,7 +56,7 @@
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
<!-- Misc header -->
<include
@@ -105,7 +105,7 @@
</LinearLayout>
<com.google.android.material.switchmaterial.SwitchMaterial
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_bluetooth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -156,13 +156,13 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="150dp"
android:textColor="@color/swap_bright_blue"
android:textColor="?attr/colorPrimary"
android:textSize="16sp"
tools:text="wifi network name" />
</LinearLayout>
<com.google.android.material.switchmaterial.SwitchMaterial
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_wifi"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
@@ -189,14 +189,14 @@
android:textColor="@color/swap_light_text" />
<com.google.android.material.progressindicator.CircularProgressIndicator
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"/>
android:id="@+id/searching_people_nearby"
android:layout_width="24dp"
android:layout_height="24dp"
android:indeterminate="true"
app:hideAnimationBehavior="outward"
app:indicatorSize="24dp"
app:showAnimationBehavior="inward"
app:trackCornerRadius="@dimen/mtrl_progress_indicator_full_rounded_corner_radius" />
</LinearLayout>

View File

@@ -1,35 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.nearby.SwapView xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
<org.fdroid.fdroid.nearby.SwapView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_scan_qr"
android:background="@color/swap_blue"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_width="wrap_content">
android:background="@color/swap_blue"
swap:toolbarTitle="@string/swap_scan_qr">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/wifi_qr_code"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_margin="16dp"
android:maxHeight="20dp"
android:id="@+id/wifi_qr_code"
tools:src="@drawable/swap_qr_example" />
<TextView
style="@style/SwapTheme.Wizard.MainText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/swap_scan_or_type_url"
style="@style/SwapTheme.Wizard.MainText" />
android:text="@string/swap_scan_or_type_url" />
<!--
<Button style="@style/SwapTheme.Wizard.OptionButton"
@@ -39,26 +40,26 @@
-->
<TextView
android:id="@+id/device_ip_address"
style="@style/SwapTheme.Wizard.LocalIpAddress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/device_ip_address"
tools:text="http://255.255.255.255:8888"
style="@style/SwapTheme.Wizard.LocalIpAddress" />
tools:text="http://255.255.255.255:8888" />
<Button
android:id="@+id/btn_qr_scanner"
style="@style/SwapTheme.Wizard.OptionButton"
android:text="@string/open_qr_code_scanner"
android:layout_gravity="center"
android:id="@+id/btn_qr_scanner" />
android:text="@string/open_qr_code_scanner" />
<TextView
android:id="@+id/warning_qr_scanner"
style="@style/SwapTheme.Wizard.QRScanWarningText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/warning_scaning_qr_code"
android:visibility="gone"
style="@style/SwapTheme.Wizard.QRScanWarningText" />
android:visibility="gone" />
</LinearLayout>
</ScrollView>
</org.fdroid.fdroid.nearby.SwapView>
</org.fdroid.fdroid.nearby.SwapView>

View File

@@ -103,8 +103,7 @@
Buttons down the bottom of the screen, which prompt the user for further
info, or to change the process somehow (e.g. Use Bluetooth instead of Wifi).
-->
<style name="SwapTheme.Wizard.OptionButton" parent="Widget.AppCompat.Button">
<item name="android:textColor">@android:color/white</item>
<style name="SwapTheme.Wizard.OptionButton" parent="Widget.Material3.Button">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_margin">0dp</item>

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<SwitchPreferenceCompat
android:defaultValue="true"
@@ -40,4 +41,4 @@
</PreferenceCategory>
</PreferenceScreen>
</PreferenceScreen>

View File

@@ -272,10 +272,10 @@
<activity
android:name=".installer.DefaultInstallerActivity"
android:theme="@style/AppThemeTransparent" />
android:theme="@style/Theme.App.Transparent" />
<activity
android:name=".installer.ErrorDialogActivity"
android:theme="@style/AppThemeTransparent" />
android:theme="@style/Theme.App.Transparent" />
<activity
android:name=".views.main.MainActivity"
@@ -444,7 +444,7 @@
<activity
android:name=".installer.FileInstallerActivity"
android:theme="@style/AppThemeTransparent" />
android:theme="@style/Theme.App.Transparent" />
<provider
android:name="org.fdroid.fdroid.installer.ApkFileProvider"

View File

@@ -202,8 +202,7 @@ public class FDroidApp extends Application implements androidx.work.Configuratio
* The built-in BouncyCastle was stripped down in {@link Build.VERSION_CODES#S}
* so that {@code SHA1withRSA} and {@code SHA256withRSA} are no longer included.
*
* @see
* <a href="https://gitlab.com/fdroid/fdroidclient/-/issues/2338">Nearby Swap Crash on Android 12: no such algorithm: SHA1WITHRSA for provider BC</a>
* @see <a href="https://gitlab.com/fdroid/fdroidclient/-/issues/2338">Nearby Swap Crash on Android 12: no such algorithm: SHA1WITHRSA for provider BC</a>
*/
private static void enableBouncyCastle() {
if (Build.VERSION.SDK_INT >= 31) {

View File

@@ -1,76 +1,34 @@
package org.fdroid.fdroid.compose
import androidx.annotation.AttrRes
import androidx.annotation.ColorInt
import androidx.compose.foundation.layout.Spacer
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.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.ReadOnlyComposable
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
import androidx.lifecycle.compose.LocalLifecycleOwner
import com.google.android.material.color.MaterialColors
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)
}
}
@Composable
fun FDroidButton(
@@ -92,7 +50,7 @@ object ComposeUtils {
)
Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
}
Text(text = text.uppercase(Locale.getDefault()))
Text(text = text)
}
}
@@ -116,7 +74,7 @@ object ComposeUtils {
)
Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
}
Text(text = text.uppercase(Locale.getDefault()), maxLines = 1)
Text(text = text, maxLines = 1)
}
}
@@ -154,8 +112,16 @@ 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)
)
}
}
@Composable
@ColorInt
@ReadOnlyComposable
fun colorAttribute(@AttrRes attrColor: Int): Color {
val color = MaterialColors.getColor(LocalContext.current, attrColor, 0)
return Color(color)
}

View File

@@ -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);

View File

@@ -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},

View File

@@ -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));

View File

@@ -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) -> {

View File

@@ -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)

View File

@@ -0,0 +1,96 @@
package org.fdroid.fdroid.ui.theme
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import org.fdroid.fdroid.Preferences
// 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))
@Composable
fun FDroidContent(
darkTheme: Boolean = isSystemInDarkTheme(),
pureBlack: Boolean = Preferences.get().isPureBlack,
content: @Composable () -> Unit
) {
val colorScheme = when {
darkTheme && pureBlack -> pureBlackScheme
darkTheme -> darkScheme
else -> lightScheme
}
MaterialTheme(
colorScheme = colorScheme,
) {
Surface(content = content)
}
}

View File

@@ -40,7 +40,6 @@ import android.view.MenuItem;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.util.ObjectsCompat;
@@ -52,6 +51,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,22 +363,20 @@ public class AppDetailsActivity extends AppCompatActivity
}
if (!apk.compatible) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.installIncompatible);
builder.setPositiveButton(R.string.yes, (dialog, whichButton) -> initiateInstall(apk));
builder.setNegativeButton(R.string.no, (dialog, whichButton) -> {
});
AlertDialog alert = builder.create();
alert.show();
new MaterialAlertDialogBuilder(this)
.setMessage(R.string.installIncompatible)
.setPositiveButton(R.string.yes, (dialog, whichButton) -> initiateInstall(apk))
.setNegativeButton(R.string.no, (dialog, whichButton) -> {
})
.show();
return;
}
if (app.installedSigner != null && apk.signer != null
&& !apk.signer.equals(app.installedSigner)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.SignatureMismatch).setPositiveButton(
R.string.ok, (dialog, id) -> dialog.cancel());
AlertDialog alert = builder.create();
alert.show();
new MaterialAlertDialogBuilder(this)
.setMessage(R.string.SignatureMismatch)
.setPositiveButton(R.string.ok, (dialog, id) -> dialog.cancel())
.show();
return;
}
initiateInstall(apk);
@@ -615,7 +613,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, ""));

View File

@@ -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,8 @@ import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;
import androidx.transition.TransitionManager;
import com.google.android.material.color.MaterialColors;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.progressindicator.LinearProgressIndicator;
import org.apache.commons.io.FilenameUtils;
@@ -583,7 +584,7 @@ public class AppDetailsRecyclerViewAdapter
warningView.setVisibility(View.VISIBLE);
} else if (SessionInstallManager.canBeUsed(context) && suggestedApk != null
&& !SessionInstallManager.isTargetSdkSupported(suggestedApk.targetSdkVersion)) {
int color = ContextCompat.getColor(context, R.color.warning);
int color = MaterialColors.getColor(warningView, R.attr.warning);
warningView.setBackgroundColor(color);
warningView.setText(R.string.warning_target_sdk);
warningView.setVisibility(View.VISIBLE);
@@ -993,7 +994,7 @@ public class AppDetailsRecyclerViewAdapter
message = showIncompatible;
}
new AlertDialog.Builder(context)
new MaterialAlertDialogBuilder(context)
.setTitle(title)
.setMessage(message)
.setPositiveButton(R.string.menu_settings, (dialog, which) -> {

View File

@@ -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.automirrored.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
@@ -41,14 +39,14 @@ import androidx.compose.ui.tooling.preview.Preview
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.compose.ComposeUtils.FDroidButton
import org.fdroid.fdroid.compose.ComposeUtils.FDroidOutlineButton
import org.fdroid.fdroid.ui.theme.FDroidContent
class IpfsGatewayAddActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
FDroidContent {
IpfsGatewayAddScreen(
@@ -71,6 +69,7 @@ class IpfsGatewayAddActivity : AppCompatActivity() {
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun IpfsGatewayAddScreen(
onBackClicked: () -> Unit,
@@ -83,17 +82,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))
Icon(Icons.AutoMirrored.Filled.ArrowBack, stringResource(R.string.back))
}
},
title = {
Text(
text = stringResource(R.string.ipfsgw_add_title),
modifier = Modifier.alpha(ContentAlpha.high),
)
},
)
@@ -107,7 +103,7 @@ fun IpfsGatewayAddScreen(
) {
Text(
text = "Enter IPFS gateway URL",
style = MaterialTheme.typography.body1,
style = MaterialTheme.typography.bodyLarge,
)
Column {
TextField(
@@ -125,7 +121,7 @@ fun IpfsGatewayAddScreen(
if (errorMsg.isNotEmpty()) {
Text(
text = errorMsg,
style = MaterialTheme.typography.body1,
style = MaterialTheme.typography.bodyLarge,
color = colorResource(
id = R.color.fdroid_error
)
@@ -137,7 +133,7 @@ fun IpfsGatewayAddScreen(
verticalAlignment = Alignment.CenterVertically,
) {
val clipboardManager = LocalClipboardManager.current
ComposeUtils.FDroidOutlineButton(
FDroidOutlineButton(
stringResource(R.string.paste),
imageVector = Icons.Default.ContentPaste,
onClick = {
@@ -147,7 +143,7 @@ fun IpfsGatewayAddScreen(
},
)
Spacer(modifier = Modifier.weight(1f))
ComposeUtils.FDroidButton(
FDroidButton(
text = stringResource(R.string.ipfsgw_add_add),
onClick = l@{
errorMsg = ""
@@ -168,7 +164,6 @@ fun IpfsGatewayAddScreen(
errorMsg = "could not parse uri ($e)"
return@l
}
// no errors -> proceed to add the url
onAddUserGateway(inputUri)
},
@@ -181,7 +176,7 @@ fun IpfsGatewayAddScreen(
@Composable
@Preview
fun IpfsGatewayAddScreenPreview() {
FDroidContent {
FDroidContent(pureBlack = true) {
IpfsGatewayAddScreen(
onBackClicked = {},
onAddUserGateway = {},

View File

@@ -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.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.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
@@ -45,18 +44,14 @@ 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.FDroidContent
class IpfsGatewaySettingsActivity : AppCompatActivity() {
lateinit var prefs: Preferences
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
prefs = Preferences.get()
val prefs = Preferences.get()
setContent {
FDroidContent {
IpfsGatewaySettingsScreen(
@@ -68,6 +63,7 @@ class IpfsGatewaySettingsActivity : AppCompatActivity() {
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun IpfsGatewaySettingsScreen(
onBackClicked: () -> Unit,
@@ -79,17 +75,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))
Icon(Icons.AutoMirrored.Filled.ArrowBack, stringResource(R.string.back))
}
},
title = {
Text(
text = stringResource(R.string.ipfsgw_title),
modifier = Modifier.alpha(ContentAlpha.high),
)
},
)
@@ -120,7 +113,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 +150,7 @@ fun DefaultGatewaysSettings(
) {
Text(
text = gatewayUrl,
style = MaterialTheme.typography.body1,
style = MaterialTheme.typography.bodyLarge,
modifier = Modifier
.weight(1f)
.align(Alignment.CenterVertically)
@@ -211,7 +204,7 @@ fun UserGatewaysSettings(
) {
Text(
text = gatewayUrl,
style = MaterialTheme.typography.body1,
style = MaterialTheme.typography.bodyLarge,
modifier = Modifier
.weight(1f)
.align(Alignment.CenterVertically)
@@ -253,7 +246,7 @@ fun IpfsGatewaySettingsScreenPreview() {
throw NotImplementedError()
}
FDroidContent {
FDroidContent(pureBlack = true) {
IpfsGatewaySettingsScreen(
prefs = prefs,
onBackClicked = {},

View File

@@ -9,7 +9,6 @@ import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import androidx.lifecycle.Observer;
@@ -66,11 +65,6 @@ public class StatusBanner extends androidx.appcompat.widget.AppCompatTextView {
public StatusBanner(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
int padding = (int) getResources().getDimension(R.dimen.banner__padding);
setPadding(padding, padding, padding, padding);
setBackgroundColor(0xFF4A4A4A);
setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
setTextColor(0xFFFFFFFF);
preferences = PreferenceManager.getDefaultSharedPreferences(context);
repoUpdateManager = FDroidApp.getRepoUpdateManager(context);
@@ -113,7 +107,7 @@ public class StatusBanner extends androidx.appcompat.widget.AppCompatTextView {
* device, and users are generally not aware of them.
*/
private void setBannerTextAndVisibility() {
if (isUpdatingRepos) {
if (isInEditMode() || isUpdatingRepos) {
setText(R.string.banner_updating_repositories);
setVisibility(View.VISIBLE);
} else if (networkState == ConnectivityMonitorService.FLAG_NET_UNAVAILABLE
@@ -135,7 +129,7 @@ public class StatusBanner extends androidx.appcompat.widget.AppCompatTextView {
break; // only check the first segment NOPMD
}
}
if (localRepos.size() == 0 || !hasLocalNonSystemRepos) {
if (localRepos.isEmpty() || !hasLocalNonSystemRepos) {
setText(R.string.banner_no_data_or_wifi);
setVisibility(View.VISIBLE);
} else {

View File

@@ -3,34 +3,28 @@ 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.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
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
@@ -42,8 +36,8 @@ import androidx.core.os.LocaleListCompat
import androidx.core.util.Consumer
import org.fdroid.database.Repository
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.FDroidContent
import org.fdroid.fdroid.views.repos.RepoIcon
import org.fdroid.index.IndexFormatVersion.TWO
@@ -66,7 +60,9 @@ fun setContentRepoChooser(
preferredRepoId = preferredRepoId,
onRepoChanged = onRepoChanged::accept,
onPreferredRepoChanged = onPreferredRepoChanged::accept,
modifier = Modifier.background(MaterialTheme.colors.surface),
// 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),
)
}
}
@@ -91,9 +87,9 @@ fun RepoChooser(
) {
Box {
val borderColor = if (isPreferred) {
colorResource(id = R.color.fdroid_blue)
MaterialTheme.colorScheme.primary
} else {
LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
MaterialTheme.colorScheme.outline
}
OutlinedTextField(
value = TextFieldValue(
@@ -102,7 +98,7 @@ fun RepoChooser(
isPreferred = repos.size > 1 && isPreferred,
),
),
textStyle = MaterialTheme.typography.body2,
textStyle = MaterialTheme.typography.bodyMedium,
onValueChange = {},
label = {
if (repos.size == 1) {
@@ -119,20 +115,20 @@ fun RepoChooser(
imageVector = Icons.Default.ArrowDropDown,
contentDescription = stringResource(R.string.app_details_repository_expand),
tint = if (isPreferred) {
colorResource(id = R.color.fdroid_blue)
MaterialTheme.colorScheme.primary
} 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 +141,15 @@ fun RepoChooser(
onDismissRequest = { expanded = false },
) {
repos.iterator().forEach { repo ->
DropdownMenuItem(onClick = {
onRepoChanged(repo)
expanded = false
}) {
RepoItem(repo, repo.repoId == preferredRepoId)
}
RepoMenuItem(
repo = repo,
isPreferred = repo.repoId == preferredRepoId,
onClick = {
onRepoChanged(repo)
expanded = false
},
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
@@ -194,7 +200,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, {}, {})
}
}
@@ -205,7 +211,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, {}, {})
}
}
@@ -216,7 +222,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, {}, {})
}
}

View File

@@ -12,6 +12,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.google.android.material.color.MaterialColors;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.views.categories.CategoryController;
@@ -119,13 +121,18 @@ public class CategorySpan extends ReplacementSpan {
// The background behind the category icon.
Paint iconBackgroundPaint = new Paint();
iconBackgroundPaint.setColor(0xffd8d8d8);
int backgroundColor =
MaterialColors.getColor(context, com.google.android.material.R.attr.colorSurfaceContainerHigh, 0);
iconBackgroundPaint.setColor(backgroundColor);
iconBackgroundPaint.setAntiAlias(true);
RectF iconBackgroundRect = new RectF(0, 0, iconBackgroundSize, height);
canvas.drawRoundRect(iconBackgroundRect, cornerRadius, cornerRadius, iconBackgroundPaint);
// Category icon on top of the circular background which was just drawn.
Drawable icon = ContextCompat.getDrawable(context, R.drawable.ic_categories);
int iconColor =
MaterialColors.getColor(context, com.google.android.material.R.attr.colorOnSurface, 0);
icon.setTint(iconColor);
icon.setBounds(iconPadding, iconPadding, iconPadding + iconSize, iconPadding + iconSize);
icon.draw(canvas);

View File

@@ -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<List<AppOverviewItem>>, 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<List<AppOverviewItem>>, 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<List<AppOverviewItem>>, 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<List<AppOverviewItem>>, ChangeListene
public void onPreferenceChange() {
// reload and re-filter apps from DB when anti-feature settings change
LiveData<List<AppOverviewItem>> liveData = db.getAppDao().getAppOverviewItems(200);
liveData.observe(activity, new Observer<List<AppOverviewItem>>() {
liveData.observe(activity, new Observer<>() {
@Override
public void onChanged(List<AppOverviewItem> items) {
LatestViewBinder.this.onChanged(items);
@@ -166,17 +166,12 @@ class LatestViewBinder implements Observer<List<AppOverviewItem>>, 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));

View File

@@ -19,8 +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.FDroidContent
import org.fdroid.fdroid.views.apps.AppListActivity
import org.fdroid.fdroid.views.apps.AppListActivity.EXTRA_REPO_ID
import org.fdroid.fdroid.work.RepoUpdateWorker

View File

@@ -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
@@ -25,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
@@ -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,
)
}
}
@@ -81,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))
}
}
@@ -89,7 +87,7 @@ fun AddRepoErrorInvalidFingerprintPreview() {
@Preview
@Composable
fun AddRepoErrorIoErrorPreview() {
ComposeUtils.FDroidContent {
FDroidContent(pureBlack = true) {
AddRepoErrorScreen(PaddingValues(0.dp), AddRepoError(IO_ERROR, IOException("foo bar")))
}
}
@@ -97,7 +95,7 @@ fun AddRepoErrorIoErrorPreview() {
@Preview
@Composable
fun AddRepoErrorInvalidIndexPreview() {
ComposeUtils.FDroidContent {
FDroidContent(pureBlack = true) {
AddRepoErrorScreen(
PaddingValues(0.dp),
AddRepoError(INVALID_INDEX, RuntimeException("foo bar"))
@@ -108,7 +106,7 @@ fun AddRepoErrorInvalidIndexPreview() {
@Preview
@Composable
fun AddRepoErrorUnknownSourcesPreview() {
ComposeUtils.FDroidContent {
FDroidContent(pureBlack = true) {
AddRepoErrorScreen(PaddingValues(0.dp), AddRepoError(UNKNOWN_SOURCES_DISALLOWED))
}
}
@@ -116,7 +114,7 @@ fun AddRepoErrorUnknownSourcesPreview() {
@Preview
@Composable
fun AddRepoErrorArchivePreview() {
ComposeUtils.FDroidContent {
FDroidContent(pureBlack = true) {
AddRepoErrorScreen(PaddingValues(0.dp), AddRepoError(IS_ARCHIVE_REPO))
}
}

View File

@@ -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.automirrored.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
@@ -62,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
@@ -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,17 +92,14 @@ fun AddRepoIntroScreen(
Scaffold(topBar = {
TopAppBar(
elevation = 4.dp,
backgroundColor = MaterialTheme.colors.primarySurface,
navigationIcon = {
IconButton(onClick = onBackClicked) {
Icon(Icons.Filled.ArrowBack, stringResource(R.string.back))
Icon(Icons.AutoMirrored.Filled.ArrowBack, stringResource(R.string.back))
}
},
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
@@ -233,7 +232,7 @@ fun AddRepoIntroContent(paddingValues: PaddingValues, onFetchRepo: (String) -> U
@Composable
@Preview
fun AddRepoIntroScreenPreview() {
FDroidContent {
FDroidContent(pureBlack = true) {
AddRepoIntroScreen(None, {}, {}) {}
}
}
@@ -241,7 +240,7 @@ fun AddRepoIntroScreenPreview() {
@Composable
@Preview(uiMode = UI_MODE_NIGHT_YES, widthDp = 720, heightDp = 360)
fun AddRepoIntroScreenPreviewNight() {
FDroidContent {
FDroidContent(pureBlack = true) {
AddRepoIntroScreen(None, {}, {}) {}
}
}

View File

@@ -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,7 +192,7 @@ public class ManageReposActivity extends AppCompatActivity implements RepoAdapte
@Override
public void onToggleEnabled(Repository repo) {
if (repo.getEnabled()) {
new AlertDialog.Builder(this)
new MaterialAlertDialogBuilder(this)
.setMessage(R.string.repo_disable_warning)
.setPositiveButton(R.string.repo_disable_warning_button, (dialog, id) -> {
disableRepo(repo);

View File

@@ -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();

View File

@@ -1,7 +1,6 @@
package org.fdroid.fdroid.views.repos
import android.content.res.Configuration
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement.spacedBy
@@ -15,17 +14,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.ElevatedCard
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
@@ -47,7 +44,8 @@ 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.compose.colorAttribute
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
@@ -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,
)
}
}
@@ -182,7 +180,7 @@ fun RepoPreviewHeader(
if (warningText != null) Box(
modifier = Modifier
.fillMaxWidth()
.background(colorResource(R.color.warning)),
.background(colorAttribute(R.attr.warning)),
contentAlignment = Alignment.Center,
) {
Text(
@@ -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,22 +206,22 @@ fun RepoPreviewHeader(
}
if (description != null) Text(
text = description,
style = MaterialTheme.typography.body2,
style = MaterialTheme.typography.bodyMedium,
)
}
}
@Composable
@OptIn(ExperimentalGlideComposeApi::class, ExperimentalFoundationApi::class)
@OptIn(ExperimentalGlideComposeApi::class)
fun LazyItemScope.RepoPreviewApp(
repo: Repository,
app: MinimalApp,
localeList: LocaleListCompat,
) {
val isDevPreview = LocalInspectionMode.current
Card(
ElevatedCard(
modifier = Modifier
.animateItemPlacement()
.animateItem()
.fillMaxWidth(),
) {
Row(
@@ -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,
)
}
}
@@ -286,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)
@@ -298,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))
@@ -310,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)
@@ -323,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))
@@ -335,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))

View File

@@ -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
@@ -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) {
@@ -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))
}
@@ -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))
}
}

View File

@@ -3,6 +3,6 @@
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#19c878" />
android:color="?attr/colorSecondaryContainer" />
<corners android:radius="2dp" />
</shape>

View File

@@ -3,7 +3,7 @@
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#429fff" />
android:color="?attr/colorPrimaryContainer" />
<corners android:radius="2dp" />
<solid android:color="?colorSurface" />
</shape>

View File

@@ -3,6 +3,6 @@
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#777777" />
android:color="?attr/colorPrimaryContainer" />
<corners android:radius="2dp" />
</shape>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="?attr/iconBackgroundColor" />
<solid android:color="?attr/colorSurfaceContainer" />
</shape>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#3c3c3e" />
</shape>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#eff4f9" />
</shape>

View File

@@ -5,7 +5,7 @@
<size
android:width="20dp"
android:height="20dp" />
<solid android:color="@color/fdroid_green" />
<solid android:color="?attr/colorPrimary" />
</shape>
</item>
</layer-list>

View File

@@ -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" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView

View File

@@ -15,7 +15,6 @@
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@string/repo_details" />
@@ -166,7 +165,7 @@
style="@style/CaptionText"
android:text="@string/repo_archive_toggle" />
<androidx.appcompat.widget.SwitchCompat
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/archiveRepo"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@@ -68,4 +68,4 @@
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
</com.google.android.material.card.MaterialCardView>

View File

@@ -6,7 +6,9 @@
android:id="@+id/card"
android:layout_width="120dp"
android:layout_height="144dp"
android:layout_margin="4dp">
android:layout_margin="4dp"
android:clickable="true"
android:focusable="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/linearLayout"

View File

@@ -5,25 +5,22 @@
android:id="@+id/rootCoordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/appDetailsBackground"
android:fitsSystemWindows="true"
tools:context="org.fdroid.fdroid.views.AppDetailsActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/app_bar_height"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:layout_behavior="org.fdroid.fdroid.views.FixAppBarLayoutBehavior">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize"
style="?attr/collapsingToolbarLayoutLargeStyle"
android:fitsSystemWindows="true"
app:collapsedTitleTextAppearance="@style/TextAppearance.App.CollapsingToolbar.Collapsed"
app:contentScrim="?colorPrimarySurface"
app:expandedTitleMarginTop="24dp"
app:expandedTitleTextAppearance="@style/TextAppearance.App.CollapsingToolbar.Expanded"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<org.fdroid.fdroid.views.apps.FeatureImage
@@ -36,7 +33,6 @@
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@android:color/transparent"

View File

@@ -2,6 +2,7 @@
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
style="@style/Widget.Material3.CardView.Elevated"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/details_activity_padding"
@@ -188,7 +189,7 @@
android:id="@+id/warning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/warning"
android:background="?attr/warning"
android:padding="8dp"
android:text="@string/warning_target_sdk"
android:textAlignment="center"
@@ -276,7 +277,6 @@
android:paddingRight="8dp"
android:scrollbars="none"
android:text="@string/antifeatures"
android:textAllCaps="true"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textStyle="bold" />

View File

@@ -62,7 +62,7 @@
android:id="@+id/status_installed"
style="@style/AppVersionStatus"
android:background="@drawable/app_version_item_status_installed"
android:textColor="#19c878"
android:textColor="?attr/colorSecondaryContainer"
android:textStyle="bold"
android:text="@string/app_installed" />

View File

@@ -2,5 +2,5 @@
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@drawable/app_version_item_status_new"
android:text="@string/app_new"
android:textColor="#429fff"
style="@style/AppVersionStatus" />
android:textColor="?attr/colorPrimaryContainer"
style="@style/AppVersionStatus" />

View File

@@ -2,5 +2,5 @@
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@drawable/app_version_item_status_suggested"
android:text="@string/app_suggested"
android:textColor="#777777"
style="@style/AppVersionStatus" />
android:textColor="?attr/colorPrimaryContainer"
style="@style/AppVersionStatus" />

View File

@@ -20,8 +20,7 @@
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@string/installed_apps__activity_title"
style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface" />
app:title="@string/installed_apps__activity_title" />
</com.google.android.material.appbar.AppBarLayout>

View File

@@ -16,7 +16,7 @@
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/edit_name"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
@@ -33,7 +33,7 @@
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/edit_password"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"

View File

@@ -2,14 +2,14 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_to_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/swipe_to_refresh">
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
@@ -17,46 +17,48 @@
<org.fdroid.fdroid.views.StatusBanner
android:id="@+id/banner_updating_repos"
style="@style/StatusBanner"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/banner_updating_repositories" />
<TextView
android:id="@+id/empty_state"
style="@style/AppListEmptyText"
android:layout_width="0dp"
android:layout_height="0dp"
style="@style/AppListEmptyText"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="@string/categories__empty_state__no_categories"
android:visibility="gone"
android:text="@string/categories__empty_state__no_categories" />
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/category_list"
android:layout_width="0dp"
android:layout_height="0dp"
tools:listitem="@layout/category_item"
app:layout_constraintTop_toBottomOf="@+id/banner_updating_repos"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:scrollbars="vertical"
tools:layout_editor_absoluteX="0dp" />
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/banner_updating_repos"
tools:layout_editor_absoluteX="0dp"
tools:listitem="@layout/category_item" />
<include
layout="@layout/fab_search"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginBottom="@dimen/fab_margin"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/fab_margin"
android:layout_marginRight="@dimen/fab_margin" />
android:layout_marginRight="@dimen/fab_margin"
android:layout_marginBottom="@dimen/fab_margin"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_to_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/swipe_to_refresh">
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
@@ -16,14 +16,26 @@
android:orientation="vertical">
<org.fdroid.fdroid.views.StatusBanner
style="@style/StatusBanner"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.google.android.material.progressindicator.CircularProgressIndicator
android:id="@+id/progress_bar"
style="@style/Widget.Material3.CircularProgressIndicator.Medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="16dp"
android:indeterminate="true"
android:visibility="gone"
tools:visibility="visible" />
<TextView
android:id="@+id/empty_state"
style="@style/AppListEmptyText"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="@style/AppListEmptyText"
android:visibility="gone"
tools:text="@string/latest__empty_state__no_recent_apps" />
@@ -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" />
</LinearLayout>
@@ -40,4 +52,4 @@
<include layout="@layout/fab_search" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -2,14 +2,14 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_to_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/swipe_to_refresh">
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
@@ -18,60 +18,65 @@
<org.fdroid.fdroid.views.StatusBanner
android:id="@+id/banner_updating_repos"
style="@style/StatusBanner"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/empty_state"
style="@style/AppListEmptyText"
android:layout_width="0dp"
android:layout_height="wrap_content"
style="@style/AppListEmptyText"
android:text="@string/empty_can_update_app_list"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/banner_updating_repos"
android:visibility="gone"
android:text="@string/empty_can_update_app_list" />
app:layout_constraintTop_toBottomOf="@+id/banner_updating_repos" />
<com.google.android.material.progressindicator.CircularProgressIndicator
android:id="@+id/empty_updating_progress"
android:layout_width="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/banner_updating_repos"
android:layout_margin="16dp"
android:indeterminate="true"
android:visibility="gone"
app:hideAnimationBehavior="outward"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/banner_updating_repos"
app:showAnimationBehavior="inward"
app:trackCornerRadius="@dimen/mtrl_progress_indicator_full_rounded_corner_radius"/>
app:trackCornerRadius="@dimen/mtrl_progress_indicator_full_rounded_corner_radius"
tools:visibility="visible" />
<ImageView
android:id="@+id/image"
android:layout_width="0dp"
android:layout_height="0dp"
app:srcCompat="@drawable/no_updates_bg"
android:importantForAccessibility="no"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/empty_state"
app:tint="?attr/mainTabSwapSplashTint"
android:scaleType="fitCenter"
android:visibility="gone" />
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" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
tools:listitem="@layout/app_list_item"
android:layout_width="0dp"
android:layout_height="0dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/banner_updating_repos"
app:layout_constraintBottom_toBottomOf="parent"
android:scrollbars="vertical" />
tools:listitem="@layout/app_list_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (C) 2015 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
<!-- Derived from https://github.com/androidx/androidx/blob/824114c787e8be1b5a81e589f81827c9121c36e6/preference/preference/res/layout/preference_dialog_edittext.xml -->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="48dp"
android:layout_marginBottom="48dp"
android:overScrollMode="ifContentScrolls">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@android:id/message"
style="?android:attr/textAppearanceSmall"
android:layout_marginLeft="24dp"
android:layout_marginRight="24dp"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="48dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorSecondary" />
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputEditText
android:id="@android:id/edit"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</ScrollView>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Derived from https://github.com/androidx/androidx/blob/005e9694795cee9a42375d80b0d813af9e700ac1/preference/preference/res/layout/preference_widget_switch_compat.xml -->
<!-- Thanks to https://stackoverflow.com/a/73782598/9077356 -->
<com.google.android.material.materialswitch.MaterialSwitch xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/switchWidget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:clickable="false"
android:background="@null" />

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -84,11 +84,11 @@
</LinearLayout>
<com.google.android.material.switchmaterial.SwitchMaterial
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/repo_switch"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>

View File

@@ -14,7 +14,6 @@
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
style="@style/Widget.MaterialComponents.Toolbar.PrimarySurface"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"

View File

@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?appDetailsCardBackground">
android:background="?colorSurfaceBright">
<!-- Ignore ContentDescription because it is kind of meaningless to have TTS read out "App icon"
when it will inevitably read out the name of the app straight after. -->
@@ -105,4 +105,4 @@
app:layout_constraintBottom_toBottomOf="parent"
tools:text="Update" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -4,7 +4,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?appDetailsCardBackground">
android:background="?colorSurfaceBright">
<TextView
android:id="@+id/text_updates_available"
@@ -60,4 +60,4 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_apps_to_update" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -2,4 +2,55 @@
<resources>
<color name="fdroid_error">#ffcf6679</color>
<color name="fdroid_caption">#ffb8b8b8</color>
<!-- Generated by Material Theme Builder from fdroid_blue and fdroid_green with modifications -->
<!-- https://www.figma.com/community/plugin/1034969338659738588 -->
<!-- Unused code are and themes with contrast are removed -->
<color name="md_theme_primary">#A5C8FF</color>
<color name="md_theme_onPrimary">#00315F</color>
<color name="md_theme_primaryContainer">#006DC7</color>
<color name="md_theme_onPrimaryContainer">#FFFFFF</color>
<color name="md_theme_secondary">#ADD535</color>
<color name="md_theme_onSecondary">#283500</color>
<color name="md_theme_secondaryContainer">#83A800</color>
<color name="md_theme_onSecondaryContainer">#080D00</color>
<color name="md_theme_tertiary">#EDB1FF</color>
<color name="md_theme_onTertiary">#52046E</color>
<color name="md_theme_tertiaryContainer">#954FB0</color>
<color name="md_theme_onTertiaryContainer">#FFFFFF</color>
<color name="md_theme_error">#FFB4AB</color>
<color name="md_theme_onError">#690005</color>
<color name="md_theme_errorContainer">#93000A</color>
<color name="md_theme_onErrorContainer">#FFDAD6</color>
<color name="md_theme_background">#101319</color>
<color name="md_theme_onBackground">#E0E2EA</color>
<color name="md_theme_surface">#101319</color>
<color name="md_theme_onSurface">#E0E2EA</color>
<color name="md_theme_surfaceVariant">#414752</color>
<color name="md_theme_onSurfaceVariant">#C1C6D4</color>
<color name="md_theme_outline">#8B919E</color>
<color name="md_theme_outlineVariant">#414752</color>
<color name="md_theme_inverseSurface">#E0E2EA</color>
<color name="md_theme_inverseOnSurface">#2D3037</color>
<color name="md_theme_inversePrimary">#005FAF</color>
<color name="md_theme_primaryFixed">#D4E3FF</color>
<color name="md_theme_onPrimaryFixed">#001C3A</color>
<color name="md_theme_primaryFixedDim">#A5C8FF</color>
<color name="md_theme_onPrimaryFixedVariant">#004786</color>
<color name="md_theme_secondaryFixed">#C8F250</color>
<color name="md_theme_onSecondaryFixed">#161F00</color>
<color name="md_theme_secondaryFixedDim">#ADD535</color>
<color name="md_theme_onSecondaryFixedVariant">#3B4D00</color>
<color name="md_theme_tertiaryFixed">#F9D8FF</color>
<color name="md_theme_onTertiaryFixed">#320046</color>
<color name="md_theme_tertiaryFixedDim">#EDB1FF</color>
<color name="md_theme_onTertiaryFixedVariant">#6B2687</color>
<color name="md_theme_surfaceDim">#101319</color>
<color name="md_theme_surfaceBright">#363940</color>
<color name="md_theme_surfaceContainerLowest">#0B0E14</color>
<color name="md_theme_surfaceContainerLow">#181C21</color>
<color name="md_theme_surfaceContainer">#1C2026</color>
<color name="md_theme_surfaceContainerHigh">#272A30</color>
<color name="md_theme_surfaceContainerHighest">#32353B</color>
</resources>

View File

@@ -15,36 +15,18 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<resources xmlns:tools="http://schemas.android.com/tools">
<resources>
<!--Top level DayNight theme to be used in AndroidManifest.xml-->
<style name="Theme.App" parent="Base.Theme.App">
<!--Material color attributes (dark theme) -->
<!--Platform attributes-->
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
<item name="android:windowLightNavigationBar" tools:targetApi="27">false</item>
<item name="android:statusBarColor">@android:color/black</item>
<item name="android:navigationBarColor">@android:color/black</item>
<!-- backward-compatibility theme options go here -->
<item name="colorPrimary">@color/fdroid_blue_light</item>
<item name="colorPrimaryVariant">@color/fdroid_blue</item>
<item name="colorPrimaryDark">?colorPrimaryVariant</item>
<item name="colorOnPrimary">#000000</item>
<item name="colorSecondary">@color/fdroid_green_light</item>
<item name="colorOnSecondary">#ffffff</item>
<item name="android:textColorLink">@color/fdroid_green</item>
<item name="appDetailsBackground">?android:windowBackground</item>
<item name="appDetailsCardBackground">#424242</item>
<item name="categoryPreviewAppCardBackground">
@drawable/category_preview_app_card_background_dark
</item>
<item name="mainTabSwapBackground">?android:windowBackground</item>
<item name="mainTabSwapSplashTint">#2c2c2c</item>
<item name="mainTabSwapSplashTint">?attr/colorSurfaceContainerLow</item>
<item name="categoryName">#ffffff</item>
<item name="installedApps">#ffffff</item>
<item name="detailPanel">@drawable/details_panel_donate_background_dark</item>
<item name="appListItem">#ffffff</item>
<item name="lightGrayTextColor">#a6a6a6</item>
<item name="antiFeaturesWarning">@drawable/ic_warning</item>
@@ -55,6 +37,55 @@
<item name="screenshotPlaceholderIconColor">#424242</item>
<item name="iconBackgroundColor">#80121212</item>
<item name="android:windowLightStatusBar">false</item>
<item name="colorPrimary">@color/md_theme_primary</item>
<item name="colorOnPrimary">@color/md_theme_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_primaryContainer</item>
<item name="colorOnPrimaryContainer">@color/md_theme_onPrimaryContainer</item>
<item name="colorSecondary">@color/md_theme_secondary</item>
<item name="colorOnSecondary">@color/md_theme_onSecondary</item>
<item name="colorSecondaryContainer">@color/md_theme_secondaryContainer</item>
<item name="colorOnSecondaryContainer">@color/md_theme_onSecondaryContainer</item>
<item name="colorTertiary">@color/md_theme_tertiary</item>
<item name="colorOnTertiary">@color/md_theme_onTertiary</item>
<item name="colorTertiaryContainer">@color/md_theme_tertiaryContainer</item>
<item name="colorOnTertiaryContainer">@color/md_theme_onTertiaryContainer</item>
<item name="colorError">@color/md_theme_error</item>
<item name="colorOnError">@color/md_theme_onError</item>
<item name="colorErrorContainer">@color/md_theme_errorContainer</item>
<item name="colorOnErrorContainer">@color/md_theme_onErrorContainer</item>
<item name="android:colorBackground">@color/md_theme_background</item>
<item name="colorOnBackground">@color/md_theme_onBackground</item>
<item name="colorSurface">@color/md_theme_surface</item>
<item name="colorOnSurface">@color/md_theme_onSurface</item>
<item name="colorSurfaceVariant">@color/md_theme_surfaceVariant</item>
<item name="colorOnSurfaceVariant">@color/md_theme_onSurfaceVariant</item>
<item name="colorOutline">@color/md_theme_outline</item>
<item name="colorOutlineVariant">@color/md_theme_outlineVariant</item>
<item name="colorSurfaceInverse">@color/md_theme_inverseSurface</item>
<item name="colorOnSurfaceInverse">@color/md_theme_inverseOnSurface</item>
<item name="colorPrimaryInverse">@color/md_theme_inversePrimary</item>
<item name="colorPrimaryFixed">@color/md_theme_primaryFixed</item>
<item name="colorOnPrimaryFixed">@color/md_theme_onPrimaryFixed</item>
<item name="colorPrimaryFixedDim">@color/md_theme_primaryFixedDim</item>
<item name="colorOnPrimaryFixedVariant">@color/md_theme_onPrimaryFixedVariant</item>
<item name="colorSecondaryFixed">@color/md_theme_secondaryFixed</item>
<item name="colorOnSecondaryFixed">@color/md_theme_onSecondaryFixed</item>
<item name="colorSecondaryFixedDim">@color/md_theme_secondaryFixedDim</item>
<item name="colorOnSecondaryFixedVariant">@color/md_theme_onSecondaryFixedVariant</item>
<item name="colorTertiaryFixed">@color/md_theme_tertiaryFixed</item>
<item name="colorOnTertiaryFixed">@color/md_theme_onTertiaryFixed</item>
<item name="colorTertiaryFixedDim">@color/md_theme_tertiaryFixedDim</item>
<item name="colorOnTertiaryFixedVariant">@color/md_theme_onTertiaryFixedVariant</item>
<item name="colorSurfaceDim">@color/md_theme_surfaceDim</item>
<item name="colorSurfaceBright">@color/md_theme_surfaceBright</item>
<item name="colorSurfaceContainerLowest">@color/md_theme_surfaceContainerLowest</item>
<item name="colorSurfaceContainerLow">@color/md_theme_surfaceContainerLow</item>
<item name="colorSurfaceContainer">@color/md_theme_surfaceContainer</item>
<item name="colorSurfaceContainerHigh">@color/md_theme_surfaceContainerHigh</item>
<item name="colorSurfaceContainerHighest">@color/md_theme_surfaceContainerHighest</item>
</style>
<style name="Theme.App.Black" parent="Theme.App">

View File

@@ -6,6 +6,7 @@
<attr name="categoryPreviewAppCardBackground" format="reference" />
<attr name="mainTabSwapBackground" format="color" />
<attr name="mainTabSwapSplashTint" format="color" />
<attr name="warning" format="color" />
<attr name="categoryName" format="color" />
<attr name="installedApps" format="color" />
<attr name="detailPanel" format="reference" />

View File

@@ -24,18 +24,62 @@
<color tools:ignore="UnusedResources" name="category_time">#FF7043</color>
<color tools:ignore="UnusedResources" name="category_writing">#F2E9CE</color>
<color name="fdroid_blue_light">#ff63a4ff</color>
<color name="fdroid_blue">#ff1976d2</color>
<color name="fdroid_blue_dark">#ff004ba0</color>
<color name="fdroid_green_light">#ffbee247</color>
<color name="fdroid_green">#ff8ab000</color>
<color tools:ignore="UnusedResources" name="fdroid_blue">#ff1976d2</color>
<color tools:ignore="UnusedResources" name="fdroid_green">#ff8ab000</color>
<color name="fdroid_red">#ffb00020</color>
<color name="fdroid_error">@color/fdroid_red</color>
<color name="fdroid_caption">#ff757575</color>
<color tools:ignore="UnusedResources" name="fdroid_caption">#ff757575</color>
<color name="shadow">#cc222222</color>
<color name="warning">#827717</color>
<color name="perms_costs_money">#fff4511e</color>
<!-- Generated by Material Theme Builder from fdroid_blue and fdroid_green -->
<!-- https://www.figma.com/community/plugin/1034969338659738588-->
<color name="md_theme_primary">#005197</color>
<color name="md_theme_onPrimary">#FFFFFF</color>
<color name="md_theme_primaryContainer">#1976D2</color>
<color name="md_theme_onPrimaryContainer">#FFFFFF</color>
<color name="md_theme_secondary">#4F6600</color>
<color name="md_theme_onSecondary">#FFFFFF</color>
<color name="md_theme_secondaryContainer">#95BC18</color>
<color name="md_theme_onSecondaryContainer">#1C2700</color>
<color name="md_theme_tertiary">#763192</color>
<color name="md_theme_onTertiary">#FFFFFF</color>
<color name="md_theme_tertiaryContainer">#9F58BA</color>
<color name="md_theme_onTertiaryContainer">#FFFFFF</color>
<color name="md_theme_error">#BA1A1A</color>
<color name="md_theme_onError">#FFFFFF</color>
<color name="md_theme_errorContainer">#FFDAD6</color>
<color name="md_theme_onErrorContainer">#410002</color>
<color name="md_theme_background">#F9F9FF</color>
<color name="md_theme_onBackground">#181C21</color>
<color name="md_theme_surface">#F9F9FF</color>
<color name="md_theme_onSurface">#181C21</color>
<color name="md_theme_surfaceVariant">#DDE2F0</color>
<color name="md_theme_onSurfaceVariant">#414752</color>
<color name="md_theme_outline">#717783</color>
<color name="md_theme_outlineVariant">#C1C6D4</color>
<color name="md_theme_inverseSurface">#2D3037</color>
<color name="md_theme_inverseOnSurface">#EFF0F9</color>
<color name="md_theme_inversePrimary">#A5C8FF</color>
<color name="md_theme_primaryFixed">#D4E3FF</color>
<color name="md_theme_onPrimaryFixed">#001C3A</color>
<color name="md_theme_primaryFixedDim">#A5C8FF</color>
<color name="md_theme_onPrimaryFixedVariant">#004786</color>
<color name="md_theme_secondaryFixed">#C8F250</color>
<color name="md_theme_onSecondaryFixed">#161F00</color>
<color name="md_theme_secondaryFixedDim">#ADD535</color>
<color name="md_theme_onSecondaryFixedVariant">#3B4D00</color>
<color name="md_theme_tertiaryFixed">#F9D8FF</color>
<color name="md_theme_onTertiaryFixed">#320046</color>
<color name="md_theme_tertiaryFixedDim">#EDB1FF</color>
<color name="md_theme_onTertiaryFixedVariant">#6B2687</color>
<color name="md_theme_surfaceDim">#D8DAE2</color>
<color name="md_theme_surfaceBright">#F9F9FF</color>
<color name="md_theme_surfaceContainerLowest">#FFFFFF</color>
<color name="md_theme_surfaceContainerLow">#F2F3FC</color>
<color name="md_theme_surfaceContainer">#ECEDF6</color>
<color name="md_theme_surfaceContainerHigh">#E6E8F0</color>
<color name="md_theme_surfaceContainerHighest">#E0E2EA</color>
</resources>

View File

@@ -34,19 +34,19 @@
<!--and cornerSizeBottomRight.-->
<!--Shape Appearance for small components like chips, buttons, text fields and FABs-->
<style name="ShapeAppearance.App.SmallComponent" parent="ShapeAppearance.MaterialComponents.SmallComponent">
<style name="ShapeAppearance.App.SmallComponent" parent="ShapeAppearance.Material3.SmallComponent">
<item name="cornerSize">4dp</item>
<item name="cornerFamily">rounded</item>
</style>
<!--Shape Appearance for medium components like cards, alert dialogs-->
<style name="ShapeAppearance.App.MediumComponent" parent="ShapeAppearance.MaterialComponents.MediumComponent">
<style name="ShapeAppearance.App.MediumComponent" parent="ShapeAppearance.Material3.MediumComponent">
<item name="cornerSize">16dp</item>
<item name="cornerFamily">rounded</item>
</style>
<!--Shape Appearance for large components like side and bottom navigation drawers-->
<style name="ShapeAppearance.App.LargeComponent" parent="ShapeAppearance.MaterialComponents.LargeComponent">
<style name="ShapeAppearance.App.LargeComponent" parent="ShapeAppearance.Material3.LargeComponent">
<item name="cornerSizeTopLeft">20dp</item>
<item name="cornerSizeTopRight">20dp</item>
<item name="cornerSizeBottomRight">0dp</item>
@@ -54,12 +54,12 @@
<item name="cornerFamily">rounded</item>
</style>
<style name="ShapeAppearance.App.Button" parent="ShapeAppearance.MaterialComponents.SmallComponent">
<style name="ShapeAppearance.App.Button" parent="ShapeAppearance.Material3.SmallComponent">
<item name="cornerSize">50%</item>
<item name="cornerFamily">rounded</item>
</style>
<style name="ShapeAppearance.App.Card" parent="ShapeAppearance.MaterialComponents.MediumComponent">
<style name="ShapeAppearance.App.Card" parent="ShapeAppearance.Material3.MediumComponent">
<item name="cornerSize">4dp</item>
<item name="cornerFamily">rounded</item>
</style>

View File

@@ -1,66 +1,57 @@
<?xml version='1.0' encoding='utf-8'?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<!--Button-->
<style name="ThemeOverlay.App.Button" parent="">
<style name="ThemeOverlay.App.Button" parent="Widget.Material3.Button">
<item name="colorPrimary">@color/fdroid_green</item>
</style>
<style name="ThemeOverlay.App.Button.TextButton" parent="">
<style name="ThemeOverlay.App.Button.TextButton" parent="Widget.Material3.Button.TextButton">
<item name="colorPrimary">@color/fdroid_green</item>
<item name="android:textColor">@color/fdroid_green</item>
</style>
<!--Dialog-->
<style name="MaterialAlertDialog.App.Title.Text" parent="MaterialAlertDialog.MaterialComponents.Title.Text">
<style name="MaterialAlertDialog.App.Title.Text" parent="MaterialAlertDialog.Material3.Title.Text">
<item name="android:textColor">@color/fdroid_green</item>
</style>
<style name="Widget.App.CardView" parent="Widget.MaterialComponents.CardView">
<!-- To preserve the UX before MD3 migration -->
<style name="Widget.App.CardView" parent="Widget.Material3.CardView.Elevated">
<item name="shapeAppearance">@style/ShapeAppearance.App.Card</item>
</style>
<style name="Widget.App.Button.Dialog" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
<style name="Widget.App.Button.Dialog" parent="Widget.Material3.Button.TextButton.Dialog">
<item name="materialThemeOverlay">@style/ThemeOverlay.App.Button.TextButton</item>
<item name="colorPrimary">@color/fdroid_green</item>
<item name="android:textColor">@color/fdroid_green</item>
<item name="shapeAppearance">@style/ShapeAppearance.App.Button</item>
</style>
<style name="Widget.App.Button.TextButton" parent="Widget.MaterialComponents.Button.TextButton">
<style name="Widget.App.Button.TextButton" parent="Widget.Material3.Button.TextButton">
<item name="shapeAppearance">@style/ShapeAppearance.App.Button</item>
</style>
<style name="Widget.App.Button.OutlinedButton" parent="Widget.MaterialComponents.Button.OutlinedButton">
<style name="Widget.App.Button.OutlinedButton" parent="Widget.Material3.Button.OutlinedButton">
<item name="shapeAppearance">@style/ShapeAppearance.App.Button</item>
</style>
<style name="Widget.App.Button" parent="Widget.MaterialComponents.Button">
<style name="Widget.App.Button" parent="Widget.Material3.Button">
<item name="shapeAppearance">@style/ShapeAppearance.App.Button</item>
</style>
<style name="AlertDialogBaseThemeDark" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog" />
<style name="ThemeOverlay.App.MaterialAlertDialog.Dark" parent="AlertDialogBaseThemeDark">
<item name="android:windowBackground">@color/cardview_dark_background</item>
<style name="Widget.App.Button.ElevatedButton" parent="Widget.Material3.Button.ElevatedButton">
<item name="shapeAppearance">@style/ShapeAppearance.App.Button</item>
</style>
<style name="AlertDialogBaseThemeLight" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog" />
<style name="ThemeOverlay.App.MaterialAlertDialog.Light" parent="AlertDialogBaseThemeLight">
<item name="colorSecondary">@color/fdroid_green</item>
</style>
<style name="AlertDialogBaseThemeNight" parent="AlertDialogBaseThemeDark" />
<style name="MinWithDialogBaseThemeDark" parent="Theme.MaterialComponents.Dialog.MinWidth">
<style name="MinWithDialogBaseThemeDark" parent="Theme.Material3.DayNight.Dialog.MinWidth">
<item name="colorSecondary">@color/fdroid_green</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="MinWithDialogBaseThemeLight" parent="Theme.MaterialComponents.Light.Dialog.MinWidth">
<style name="MinWithDialogBaseThemeLight" parent="Theme.Material3.Light.Dialog.MinWidth">
<item name="colorSecondary">@color/fdroid_green</item>
<item name="windowActionBar">false</item>
@@ -100,7 +91,6 @@
<style name="AppListItemStatusText">
<item name="android:textStyle">italic</item>
<item name="android:textSize">14sp</item>
<item name="android:textColor">?attr/lightGrayTextColor</item>
<item name="android:maxLines">1</item>
<item name="android:ellipsize">end</item>
<item name="fontFamily">sans-serif-light</item>
@@ -144,4 +134,20 @@
<!-- Disable default tickMarks. We draw our own in SeekBarForegroundThumb -->
<item name="tickMark">@null</item>
</style>
<style name="Widget.App.Preference.SwitchPreferenceCompat" parent="Preference.SwitchPreferenceCompat.Material">
<item name="android:widgetLayout">@layout/preference_switch</item>
</style>
<style name="Widget.App.Preference.DialogPreference.EditTextPreference" parent="Preference.DialogPreference.EditTextPreference.Material">
<item name="android:dialogLayout">@layout/preference_edit_text</item>
</style>
<style name="StatusBanner" parent="Widget.Material3.CardView.Elevated">
<item name="android:padding">@dimen/banner__padding</item>
<item name="android:gravity">center</item>
<item name="android:background">?colorSurfaceBright</item>
<item name="android:textColor">?colorOnSurface</item>
</style>
</resources>

View File

@@ -10,17 +10,11 @@
<item name="android:paddingBottom">10dp</item>
<item name="android:paddingLeft">18dp</item>
<item name="android:paddingRight">18dp</item>
<item name="textAllCaps">true</item>
<item name="materialThemeOverlay">@style/ThemeOverlay.App.DetailsButton</item>
<item name="android:stateListAnimator">@null</item> <!-- no elevation change on hover -->
<item name="android:letterSpacing">0.05</item>
</style>
<style name="DetailsPrimaryButtonStyle" parent="Widget.App.Button">
<item name="materialThemeOverlay">@style/ThemeOverlay.App.DetailsButton</item>
</style>
<style name="ThemeOverlay.App.DetailsButton" parent="" />
<style name="DetailsPrimaryButtonStyle" parent="Widget.App.Button"></style>
<style name="DetailsPrimaryButtonStyleSmall" parent="DetailsPrimaryButtonStyle">
<item name="android:textSize">12sp</item>
@@ -30,9 +24,7 @@
<item name="android:paddingRight">12dp</item>
</style>
<style name="DetailsSecondaryButtonStyle" parent="DetailsButtonStyle">
<item name="materialThemeOverlay">@style/ThemeOverlay.App.DetailsButton</item>
</style>
<style name="DetailsSecondaryButtonStyle" parent="DetailsButtonStyle"></style>
<style name="DetailsSecondaryButtonStyleSmall" parent="DetailsSecondaryButtonStyle">
<item name="android:textSize">12sp</item>
@@ -46,18 +38,17 @@
<item name="android:padding">8dp</item>
<item name="android:textSize">14sp</item>
<item name="android:textStyle">normal</item>
<item name="materialThemeOverlay">@style/ThemeOverlay.App.DetailsButton</item>
</style>
<style name="DetailsAppTitleStyle" parent="TextAppearance.MaterialComponents.Headline6">
<style name="DetailsAppTitleStyle" parent="TextAppearance.Material3.TitleLarge">
<item name="android:textSize">18sp</item>
</style>
<style name="DetailsLastUpdatedStyle" parent="TextAppearance.MaterialComponents.Caption" />
<style name="DetailsLastUpdatedStyle" parent="TextAppearance.Material3.BodySmall" />
<style name="DetailsAntiFeaturesWarningStyle" parent="TextAppearance.MaterialComponents.Body1">
<style name="DetailsAntiFeaturesWarningStyle" parent="TextAppearance.Material3.BodyLarge">
<item name="android:textStyle">bold</item>
</style>
</resources>
</resources>

View File

@@ -0,0 +1,19 @@
<resources>
<!-- Workaround to get Material 3 for preferences -->
<!-- https://github.com/material-components/material-components-android/blob/22de817c30a493fb7dda46a8bea784d5bdc1dbdb/catalog/java/io/material/catalog/application/theme/res/values/themes.xml#L32-L38 -->
<style name="ThemeOverlay.App.Preference" parent="PreferenceThemeOverlay">
<item name="switchPreferenceCompatStyle">
@style/Widget.App.Preference.SwitchPreferenceCompat
</item>
<item name="editTextPreferenceStyle">
@style/Widget.App.Preference.DialogPreference.EditTextPreference
</item>
</style>
<!-- Workaround to get Material 3 for dialogs in preferences -->
<style name="ThemeOverlay.App.MaterialAlertDialog" parent="ThemeOverlay.Material3.MaterialAlertDialog">
<item name="dialogCornerRadius">28dp</item>
<item name="android:colorBackground">?attr/colorSurfaceContainerHigh</item>
<item name="android:layout">@layout/m3_alert_dialog</item>
</style>
</resources>

View File

@@ -15,9 +15,12 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="Base.Theme.App" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Generated by the Material Theme Builder with modifications-->
<!-- https://www.figma.com/community/plugin/1034969338659738588&ndash;&gt;-->
<resources>
<style name="Base.Theme.App" parent="Theme.Material3.DayNight.NoActionBar">
<!--Material shape attributes-->
<item name="shapeAppearanceSmallComponent">@style/ShapeAppearance.App.SmallComponent</item>
<item name="shapeAppearanceMediumComponent">@style/ShapeAppearance.App.MediumComponent
@@ -29,54 +32,87 @@
<item name="materialButtonStyle">@style/Widget.App.Button</item>
<item name="materialCardViewStyle">@style/Widget.App.CardView</item>
<!-- backward-compatibility theme options go here -->
<!--Material color attributes (light theme) -->
<!--colorPrimary colors map to components and elements, such as app bars and buttons. -->
<!--colorSecondary colors are most often used as accents on components, such as FABs and -->
<!--selection controls.-->
<item name="colorPrimary">@color/fdroid_blue</item>
<item name="colorPrimaryVariant">@color/fdroid_blue_dark</item>
<item name="colorPrimaryDark">?colorPrimaryVariant</item>
<item name="colorSecondary">@color/fdroid_green</item>
<!--colorBackground appears behind scrollable content and is used for the default window-->
<!--background. colorSurface is mapped to the surface of components such as cards, sheets-->
<!--and menus. colorError is used to indicate an error state for components such as-->
<!--text fields.-->
<item name="appDetailsBackground">#fcfcfc</item>
<item name="appDetailsCardBackground">#ffffff</item>
<item name="categoryPreviewAppCardBackground">
@drawable/category_preview_app_card_background_light
</item>
<item name="mainTabSwapBackground">#fafafa</item>
<item name="detailPanel">@drawable/details_panel_donate_background_light</item>
<item name="detailPanel">?attr/colorSurfaceContainerHighest</item>
<item name="antiFeaturesWarning">@drawable/ic_warning</item>
<item name="backButtonDrawable">@drawable/abc_ic_ab_back_material</item>
<item name="clearButtonDrawable">@drawable/ic_close</item>
<!--"On" colors define how text, icons and strokes are colored in relation to the surface-->
<!--on which they appear.-->
<item name="colorOnPrimary">#ffffff</item>
<item name="colorOnSecondary">#ffffff</item>
<item name="android:textColorLink">@color/fdroid_green</item>
<item name="mainTabSwapSplashTint">#f5f5f5</item>
<item name="mainTabSwapSplashTint">?attr/colorSurfaceDim</item>
<item name="warning">?attr/colorTertiaryContainer</item>
<item name="categoryName">#4a4a4a</item>
<item name="installedApps">#424242</item>
<item name="appListItem">#424242</item>
<item name="lightGrayTextColor">#4a4a4a</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="preferenceTheme">@style/ThemeOverlay.App.Preference</item>
<item name="appDetailsAntiFeatureIconColor">#000000</item>
<item name="iconBackgroundColor">#801976D2</item>
<item name="bottomNavigationStyle">
@style/Widget.MaterialComponents.BottomNavigationView.PrimarySurface
</item>
<item name="screenshotPlaceholderIconColor">#e8e8e8</item>
<!--Platform attributes-->
<item name="android:windowLightStatusBar">false</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowLightStatusBar">true</item>
<!-- Adjust androidx.preference dialogs to follow Material You -->
<!-- https://github.com/material-components/material-components-android/issues/2732#issuecomment-1146086018 -->
<item name="alertDialogTheme">@style/ThemeOverlay.App.MaterialAlertDialog</item>
<item name="colorPrimary">@color/md_theme_primary</item>
<item name="colorOnPrimary">@color/md_theme_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_primaryContainer</item>
<item name="colorOnPrimaryContainer">@color/md_theme_onPrimaryContainer</item>
<item name="colorSecondary">@color/md_theme_secondary</item>
<item name="colorOnSecondary">@color/md_theme_onSecondary</item>
<item name="colorSecondaryContainer">@color/md_theme_secondaryContainer</item>
<item name="colorOnSecondaryContainer">@color/md_theme_onSecondaryContainer</item>
<item name="colorTertiary">@color/md_theme_tertiary</item>
<item name="colorOnTertiary">@color/md_theme_onTertiary</item>
<item name="colorTertiaryContainer">@color/md_theme_tertiaryContainer</item>
<item name="colorOnTertiaryContainer">@color/md_theme_onTertiaryContainer</item>
<item name="colorError">@color/md_theme_error</item>
<item name="colorOnError">@color/md_theme_onError</item>
<item name="colorErrorContainer">@color/md_theme_errorContainer</item>
<item name="colorOnErrorContainer">@color/md_theme_onErrorContainer</item>
<item name="android:colorBackground">@color/md_theme_background</item>
<item name="colorOnBackground">@color/md_theme_onBackground</item>
<item name="colorSurface">@color/md_theme_surface</item>
<item name="colorOnSurface">@color/md_theme_onSurface</item>
<item name="colorSurfaceVariant">@color/md_theme_surfaceVariant</item>
<item name="colorOnSurfaceVariant">@color/md_theme_onSurfaceVariant</item>
<item name="colorOutline">@color/md_theme_outline</item>
<item name="colorOutlineVariant">@color/md_theme_outlineVariant</item>
<item name="colorSurfaceInverse">@color/md_theme_inverseSurface</item>
<item name="colorOnSurfaceInverse">@color/md_theme_inverseOnSurface</item>
<item name="colorPrimaryInverse">@color/md_theme_inversePrimary</item>
<item name="colorPrimaryFixed">@color/md_theme_primaryFixed</item>
<item name="colorOnPrimaryFixed">@color/md_theme_onPrimaryFixed</item>
<item name="colorPrimaryFixedDim">@color/md_theme_primaryFixedDim</item>
<item name="colorOnPrimaryFixedVariant">@color/md_theme_onPrimaryFixedVariant</item>
<item name="colorSecondaryFixed">@color/md_theme_secondaryFixed</item>
<item name="colorOnSecondaryFixed">@color/md_theme_onSecondaryFixed</item>
<item name="colorSecondaryFixedDim">@color/md_theme_secondaryFixedDim</item>
<item name="colorOnSecondaryFixedVariant">@color/md_theme_onSecondaryFixedVariant</item>
<item name="colorTertiaryFixed">@color/md_theme_tertiaryFixed</item>
<item name="colorOnTertiaryFixed">@color/md_theme_onTertiaryFixed</item>
<item name="colorTertiaryFixedDim">@color/md_theme_tertiaryFixedDim</item>
<item name="colorOnTertiaryFixedVariant">@color/md_theme_onTertiaryFixedVariant</item>
<item name="colorSurfaceDim">@color/md_theme_surfaceDim</item>
<item name="colorSurfaceBright">@color/md_theme_surfaceBright</item>
<item name="colorSurfaceContainerLowest">@color/md_theme_surfaceContainerLowest</item>
<item name="colorSurfaceContainerLow">@color/md_theme_surfaceContainerLow</item>
<item name="colorSurfaceContainer">@color/md_theme_surfaceContainer</item>
<item name="colorSurfaceContainerHigh">@color/md_theme_surfaceContainerHigh</item>
<item name="colorSurfaceContainerHighest">@color/md_theme_surfaceContainerHighest</item>
</style>
<!-- light app theme with accent colors following roughly android design guidelines -->
@@ -87,7 +123,7 @@
<!-- Same as Theme.App except a black background in Dark mode -->
<style name="Theme.App.Black" parent="Theme.App" />
<style name="AppThemeTransparent" parent="@android:style/Theme.Translucent.NoTitleBar">
<style name="Theme.App.Transparent" parent="Base.Theme.App">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
@@ -95,8 +131,4 @@
<item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
<style name="AppThemeDialog" parent="Theme.MaterialComponents.DayNight.Dialog.Alert">
<item name="colorPrimary">@color/fdroid_green</item>
</style>
</resources>

View File

@@ -1,27 +0,0 @@
<!--
~ Copyright (C) 2019 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<resources>
<style name="TextAppearance.App.CollapsingToolbar.Expanded" parent="TextAppearance.MaterialComponents.Headline5">
<item name="android:textColor">?attr/colorOnPrimarySurface</item>
</style>
<style name="TextAppearance.App.CollapsingToolbar.Collapsed" parent="TextAppearance.MaterialComponents.Headline6">
<item name="android:textColor">?attr/colorOnPrimarySurface</item>
</style>
</resources>

View File

@@ -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" }

View File

@@ -961,6 +961,21 @@
<sha256 value="fe999f1da8a5e06bc06daefd24a560781b568d6ed3fa6ad104a18c4dad513cdd" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.compose.material3" name="material3" version="1.1.2">
<artifact name="material3-1.1.2.aar">
<sha256 value="fd9f8fe91d6661afcaf0e9c9cef30b5a196b4def5b28a370f13f2c259c26e482" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.compose.material3" name="material3" version="1.3.1">
<artifact name="material3-metadata-1.3.1.jar">
<sha256 value="e2667048f898be236e8f3980d8137496bcafb626ebc4eedf32aa00f481f8fff7" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.compose.material3" name="material3-android" version="1.3.1">
<artifact name="material3-release.aar">
<sha256 value="752473d4ea271f822858c313ec0d857ab05249021906f3005b30f2b1fcd0dcc0" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.compose.runtime" name="runtime" version="1.4.3">
<artifact name="runtime-1.4.3.aar">
<sha256 value="f975185e13d3e5b0c142e220e924bfe643d4421b0fdae3f2036f1e0160a390f4" origin="Generated by Gradle"/>
@@ -1950,6 +1965,11 @@
<sha256 value="c6deada2fac53b8ea6523dbda77597b128006674616f140f04df23264c6d1aa3" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.lifecycle" name="lifecycle-common-java8" version="2.8.7">
<artifact name="lifecycle-common-java8-2.8.7.jar">
<sha256 value="c6deada2fac53b8ea6523dbda77597b128006674616f140f04df23264c6d1aa3" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.lifecycle" name="lifecycle-common-jvm" version="2.8.6">
<artifact name="lifecycle-common-jvm-2.8.6.jar">
<sha256 value="61c873a7327c946ec033c310bb98f3f92eeabcede0e1a5200ab8a1896483c7bf" origin="Generated by Gradle"/>