mirror of
https://github.com/CatimaLoyalty/Android.git
synced 2026-09-12 22:33:37 -04:00
Migrate WearOS app to Material3
Also always display sync status on screen
This commit is contained in:
1 parent
b326a7148d
commit
9459c78e7c
10 files changed
+76
-49
No files matched your search
@@ -14,6 +14,7 @@ import android.widget.RemoteViews
|
||||
import androidx.core.widget.RemoteViewsCompat
|
||||
import protect.card_locker.DBHelper.LoyaltyCardArchiveFilter
|
||||
import protect.card_locker.cardview.LoyaltyCardViewActivity
|
||||
import protect.card_locker.shared.ForegroundColorHelper
|
||||
|
||||
class ListWidget : AppWidgetProvider() {
|
||||
fun updateAll(context: Context) {
|
||||
@@ -100,7 +101,7 @@ class ListWidget : AppWidgetProvider() {
|
||||
// Note: Android 5 will not use bitmaps
|
||||
val remoteViews = RemoteViews(context.packageName, R.layout.list_widget_item).apply {
|
||||
val headerColor = Utils.getHeaderColor(context, loyaltyCard)
|
||||
val foreground = if (Utils.needsDarkForeground(headerColor)) Color.BLACK else Color.WHITE
|
||||
val foreground = if (ForegroundColorHelper.needsDarkForeground(headerColor)) Color.BLACK else Color.WHITE
|
||||
setInt(R.id.item_container_foreground, "setBackgroundColor", headerColor)
|
||||
val icon = loyaltyCard.getImageThumbnail(context)
|
||||
// FIXME: The icon flow causes a crash up to Android 12L, so force anything below 33 down this path
|
||||
|
||||
@@ -91,6 +91,7 @@ import java.util.concurrent.Callable;
|
||||
import protect.card_locker.async.TaskHandler;
|
||||
import protect.card_locker.databinding.LayoutChipChoiceBinding;
|
||||
import protect.card_locker.databinding.LoyaltyCardEditActivityBinding;
|
||||
import protect.card_locker.shared.ForegroundColorHelper;
|
||||
import protect.card_locker.viewmodels.LoyaltyCardEditActivityViewModel;
|
||||
|
||||
public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements BarcodeImageWriterResultCallback, ColorPickerDialogListener {
|
||||
@@ -896,8 +897,8 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
|
||||
Integer headerColor = viewModel.getLoyaltyCard().headerColor;
|
||||
if (headerColor != null) {
|
||||
thumbnail.setOnClickListener(new ChooseCardImage());
|
||||
thumbnailEditIcon.setBackgroundColor(Utils.needsDarkForeground(headerColor) ? Color.BLACK : Color.WHITE);
|
||||
thumbnailEditIcon.setColorFilter(Utils.needsDarkForeground(headerColor) ? Color.WHITE : Color.BLACK);
|
||||
thumbnailEditIcon.setBackgroundColor(ForegroundColorHelper.Companion.needsDarkForeground(headerColor) ? Color.BLACK : Color.WHITE);
|
||||
thumbnailEditIcon.setColorFilter(ForegroundColorHelper.Companion.needsDarkForeground(headerColor) ? Color.WHITE : Color.BLACK);
|
||||
}
|
||||
|
||||
onResuming = false;
|
||||
@@ -919,18 +920,18 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
|
||||
|
||||
setLoyaltyCardHeaderColor(headerColor);
|
||||
|
||||
thumbnail.setBackgroundColor(Utils.needsDarkForeground(headerColor) ? Color.BLACK : Color.WHITE);
|
||||
thumbnail.setBackgroundColor(ForegroundColorHelper.Companion.needsDarkForeground(headerColor) ? Color.BLACK : Color.WHITE);
|
||||
|
||||
thumbnailEditIcon.setBackgroundColor(Utils.needsDarkForeground(headerColor) ? Color.BLACK : Color.WHITE);
|
||||
thumbnailEditIcon.setColorFilter(Utils.needsDarkForeground(headerColor) ? Color.WHITE : Color.BLACK);
|
||||
thumbnailEditIcon.setBackgroundColor(ForegroundColorHelper.Companion.needsDarkForeground(headerColor) ? Color.BLACK : Color.WHITE);
|
||||
thumbnailEditIcon.setColorFilter(ForegroundColorHelper.Companion.needsDarkForeground(headerColor) ? Color.WHITE : Color.BLACK);
|
||||
} else {
|
||||
generateIcon(storeFieldEdit.getText().toString().trim());
|
||||
|
||||
Integer headerColor = viewModel.getLoyaltyCard().headerColor;
|
||||
|
||||
if (headerColor != null) {
|
||||
thumbnailEditIcon.setBackgroundColor(Utils.needsDarkForeground(headerColor) ? Color.BLACK : Color.WHITE);
|
||||
thumbnailEditIcon.setColorFilter(Utils.needsDarkForeground(headerColor) ? Color.WHITE : Color.BLACK);
|
||||
thumbnailEditIcon.setBackgroundColor(ForegroundColorHelper.Companion.needsDarkForeground(headerColor) ? Color.BLACK : Color.WHITE);
|
||||
thumbnailEditIcon.setColorFilter(ForegroundColorHelper.Companion.needsDarkForeground(headerColor) ? Color.WHITE : Color.BLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import protect.card_locker.cardview.LoyaltyCardViewActivity;
|
||||
import protect.card_locker.shared.ForegroundColorHelper;
|
||||
|
||||
public class ShortcutHelper {
|
||||
/**
|
||||
@@ -102,7 +103,7 @@ public class ShortcutHelper {
|
||||
if (iconBitmap == null) {
|
||||
iconBitmap = Utils.generateIcon(context, loyaltyCard, true).getLetterTile();
|
||||
} else {
|
||||
iconBitmap = createAdaptiveBitmap(iconBitmap, Utils.needsDarkForeground(Utils.getHeaderColor(context, loyaltyCard)) ? Color.BLACK : Color.WHITE);
|
||||
iconBitmap = createAdaptiveBitmap(iconBitmap, ForegroundColorHelper.Companion.needsDarkForeground(Utils.getHeaderColor(context, loyaltyCard)) ? Color.BLACK : Color.WHITE);
|
||||
}
|
||||
|
||||
IconCompat icon = IconCompat.createWithAdaptiveBitmap(iconBitmap);
|
||||
|
||||
@@ -39,7 +39,6 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RawRes;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.core.graphics.Insets;
|
||||
import androidx.core.os.LocaleListCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
@@ -95,6 +94,7 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import protect.card_locker.preferences.Settings;
|
||||
import protect.card_locker.shared.ForegroundColorHelper;
|
||||
|
||||
public class Utils {
|
||||
private static final String TAG = "Catima";
|
||||
@@ -115,8 +115,6 @@ public class Utils {
|
||||
|
||||
public static final String CARD_IMAGE_FILENAME_REGEX = "^(card_)(\\d+)(_(?:front|back|icon)\\.png)$";
|
||||
|
||||
static final double LUMINANCE_MIDPOINT = 0.5;
|
||||
|
||||
static final int BITMAP_SIZE_SMALL = 512;
|
||||
static final int BITMAP_SIZE_BIG = 1600;
|
||||
|
||||
@@ -147,11 +145,7 @@ public class Utils {
|
||||
}
|
||||
|
||||
return new LetterBitmap(context, store, store,
|
||||
tileLetterFontSize, pixelSize, pixelSize, backgroundColor, needsDarkForeground(backgroundColor) ? Color.BLACK : Color.WHITE);
|
||||
}
|
||||
|
||||
static public boolean needsDarkForeground(Integer backgroundColor) {
|
||||
return ColorUtils.calculateLuminance(backgroundColor) > LUMINANCE_MIDPOINT;
|
||||
tileLetterFontSize, pixelSize, pixelSize, backgroundColor, ForegroundColorHelper.Companion.needsDarkForeground(backgroundColor) ? Color.BLACK : Color.WHITE);
|
||||
}
|
||||
|
||||
static public List<ParseResult> retrieveBarcodesFromImage(Context context, Uri uri) {
|
||||
@@ -1070,7 +1064,7 @@ public class Utils {
|
||||
|
||||
if (icon != null) {
|
||||
// Use header colour to decide if this image will need a white or black background
|
||||
backgroundOrIcon.setBackgroundColor(needsDarkForeground(headerColor) ? Color.BLACK : Color.WHITE);
|
||||
backgroundOrIcon.setBackgroundColor(ForegroundColorHelper.Companion.needsDarkForeground(headerColor) ? Color.BLACK : Color.WHITE);
|
||||
|
||||
// Ensure correct cropping style
|
||||
backgroundOrIcon.setScaleType(Utils.getRecommendedScaleTypeForThumbnailImage(icon));
|
||||
@@ -1100,7 +1094,7 @@ public class Utils {
|
||||
// Actually set the text and colour
|
||||
textWhenNoImage.setVisibility(View.VISIBLE);
|
||||
textWhenNoImage.setText(loyaltyCard.store);
|
||||
textWhenNoImage.setTextColor(Utils.needsDarkForeground(headerColor) ? Color.BLACK : Color.WHITE);
|
||||
textWhenNoImage.setTextColor(ForegroundColorHelper.Companion.needsDarkForeground(headerColor) ? Color.BLACK : Color.WHITE);
|
||||
}
|
||||
|
||||
return headerColor;
|
||||
|
||||
@@ -54,6 +54,7 @@ import protect.card_locker.cardimageview.LoyaltyCardImageViewActivity;
|
||||
import protect.card_locker.databinding.LoyaltyCardViewLayoutBinding;
|
||||
import protect.card_locker.preferences.Settings;
|
||||
import protect.card_locker.preferences.SettingsActivity;
|
||||
import protect.card_locker.shared.ForegroundColorHelper;
|
||||
|
||||
public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements BarcodeImageWriterResultCallback {
|
||||
private LoyaltyCardViewLayoutBinding binding;
|
||||
@@ -598,20 +599,20 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
|
||||
// Set bottomAppBar and system navigation bar color
|
||||
binding.bottomAppBar.setBackgroundColor(darkenedColor);
|
||||
Utils.setNavigationBarColor(null, window, darkenedColor, Utils.needsDarkForeground(darkenedColor));
|
||||
Utils.setNavigationBarColor(null, window, darkenedColor, ForegroundColorHelper.Companion.needsDarkForeground(darkenedColor));
|
||||
|
||||
int complementaryColor = Utils.getComplementaryColor(darkenedColor);
|
||||
binding.fabEdit.setBackgroundTintList(ColorStateList.valueOf(complementaryColor));
|
||||
Drawable editButtonIcon = binding.fabEdit.getDrawable();
|
||||
editButtonIcon.mutate();
|
||||
editButtonIcon.setTint(Utils.needsDarkForeground(complementaryColor) ? Color.BLACK : Color.WHITE);
|
||||
editButtonIcon.setTint(ForegroundColorHelper.Companion.needsDarkForeground(complementaryColor) ? Color.BLACK : Color.WHITE);
|
||||
binding.fabEdit.setImageDrawable(editButtonIcon);
|
||||
|
||||
Bitmap icon = loyaltyCard.getImageThumbnail(this);
|
||||
Utils.setIconOrTextWithBackground(this, loyaltyCard, icon, binding.iconImage, binding.iconText, 1);
|
||||
|
||||
// If the background is very bright, we should use dark icons
|
||||
backgroundNeedsDarkIcons = Utils.needsDarkForeground(backgroundHeaderColor);
|
||||
backgroundNeedsDarkIcons = ForegroundColorHelper.Companion.needsDarkForeground(backgroundHeaderColor);
|
||||
|
||||
fixBottomAppBarImageButtonColor(binding.bottomAppBarInfoButton);
|
||||
fixBottomAppBarImageButtonColor(binding.bottomAppBarPreviousButton);
|
||||
|
||||
@@ -47,8 +47,8 @@ ch-acra-acra-mail = { group = "ch.acra", name = "acra-mail", version.ref = "acra
|
||||
ch-acra-acra-dialog = { group = "ch.acra", name = "acra-dialog", version.ref = "acra" }
|
||||
|
||||
# Wear OS
|
||||
androidx-wear-compose-material = { group = "androidx.wear.compose", name = "compose-material", version.ref = "wearCompose" }
|
||||
androidx-wear-compose-foundation = { group = "androidx.wear.compose", name = "compose-foundation", version.ref = "wearCompose" }
|
||||
androidx-wear-compose-material3 = { group = "androidx.wear.compose", name = "compose-material3", version.ref = "wearCompose" }
|
||||
androidx-wear-compose-navigation = { group = "androidx.wear.compose", name = "compose-navigation", version.ref = "wearCompose" }
|
||||
|
||||
# Testing
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package protect.card_locker.shared
|
||||
|
||||
import androidx.core.graphics.ColorUtils
|
||||
|
||||
class ForegroundColorHelper {
|
||||
companion object {
|
||||
const val LUMINANCE_MIDPOINT: Double = 0.5
|
||||
|
||||
fun needsDarkForeground(backgroundColor: Int): Boolean {
|
||||
return ColorUtils.calculateLuminance(backgroundColor) > LUMINANCE_MIDPOINT
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ dependencies {
|
||||
implementation(libs.androidx.activity.activity.compose)
|
||||
|
||||
// Wear OS Compose
|
||||
implementation(libs.androidx.wear.compose.material)
|
||||
implementation(libs.androidx.wear.compose.material3)
|
||||
implementation(libs.androidx.wear.compose.foundation)
|
||||
implementation(libs.androidx.wear.compose.navigation)
|
||||
|
||||
|
||||
@@ -15,15 +15,19 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
|
||||
import androidx.wear.compose.foundation.lazy.TransformingLazyColumn
|
||||
import androidx.wear.compose.foundation.lazy.items
|
||||
import androidx.wear.compose.material.Chip
|
||||
import androidx.wear.compose.material.ChipDefaults
|
||||
import androidx.wear.compose.material.CircularProgressIndicator
|
||||
import androidx.wear.compose.material.Text
|
||||
import androidx.wear.compose.material3.CircularProgressIndicator
|
||||
import androidx.wear.compose.material3.Text
|
||||
import androidx.wear.compose.material3.Button
|
||||
import androidx.wear.compose.material3.ButtonDefaults
|
||||
import androidx.wear.compose.material3.SurfaceTransformation
|
||||
import androidx.wear.compose.material3.lazy.rememberTransformationSpec
|
||||
import androidx.wear.compose.material3.lazy.transformedHeight
|
||||
import me.hackerchick.catima.wear.R
|
||||
import me.hackerchick.catima.wear.SyncStatus
|
||||
import me.hackerchick.catima.wear.WearCard
|
||||
import protect.card_locker.shared.ForegroundColorHelper
|
||||
|
||||
@Composable
|
||||
fun CardListScreen(
|
||||
@@ -63,14 +67,16 @@ fun CardListScreen(
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
ScalingLazyColumn(
|
||||
val transformationSpec = rememberTransformationSpec()
|
||||
TransformingLazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentPadding = PaddingValues(horizontal = 8.dp, vertical = 32.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
items(cards, key = { it.id }) { card ->
|
||||
Chip(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
Button(
|
||||
modifier = Modifier.fillMaxWidth().transformedHeight(this, transformationSpec),
|
||||
transformation = SurfaceTransformation(transformationSpec),
|
||||
label = {
|
||||
Text(
|
||||
text = card.store,
|
||||
@@ -79,23 +85,33 @@ fun CardListScreen(
|
||||
},
|
||||
onClick = { onCardClick(card) },
|
||||
colors = if (card.headerColor != null) {
|
||||
ChipDefaults.chipColors(backgroundColor = Color(card.headerColor))
|
||||
ButtonDefaults.buttonColors(
|
||||
containerColor = Color(card.headerColor),
|
||||
contentColor = if (ForegroundColorHelper.needsDarkForeground(card.headerColor)) Color.Black else Color.White
|
||||
)
|
||||
} else {
|
||||
ChipDefaults.primaryChipColors()
|
||||
ButtonDefaults.buttonColors()
|
||||
},
|
||||
)
|
||||
}
|
||||
val footerLabel = syncStatus.labelRes
|
||||
if (footerLabel != null) {
|
||||
item {
|
||||
Text(
|
||||
text = stringResource(footerLabel),
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = 11.sp,
|
||||
color = Color.Gray,
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 4.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
val footerLabel = syncStatus.labelRes
|
||||
if (footerLabel != null) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.align(Alignment.BottomCenter)
|
||||
.background(Color.Black.copy(alpha = 0.75f))
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(footerLabel),
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = 11.sp,
|
||||
color = Color.LightGray,
|
||||
modifier = Modifier
|
||||
.padding(40.dp, 4.dp, 40.dp, 20.dp)
|
||||
.align(Alignment.Center)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@ import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.wear.compose.material.CircularProgressIndicator
|
||||
import androidx.wear.compose.material.MaterialTheme
|
||||
import androidx.wear.compose.material.Text
|
||||
import androidx.wear.compose.material3.CircularProgressIndicator
|
||||
import androidx.wear.compose.material3.MaterialTheme
|
||||
import androidx.wear.compose.material3.Text
|
||||
import com.google.zxing.BarcodeFormat
|
||||
import com.google.zxing.EncodeHintType
|
||||
import com.google.zxing.MultiFormatWriter
|
||||
@@ -40,7 +40,7 @@ fun CardViewScreen(card: WearCard?) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(MaterialTheme.colors.background),
|
||||
.background(MaterialTheme.colorScheme.background),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
if (card == null) {
|
||||
|
||||
Reference in new issue
Block a user