Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/stefan-niedermann/nextcloud-deck.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorStefan Niedermann <info@niedermann.it>2024-01-14 13:18:03 +0300
committerStefan Niedermann <info@niedermann.it>2024-01-14 13:18:03 +0300
commit8471bf3b4dea916ed87f70c6b497bb18336723e3 (patch)
tree032d730d37f4a1a044a760a5dae41a660afecc25 /app
parent8ab9514b4a129d7d0db55811e785be367c86a176 (diff)
feat(done): Enhance due date / done UX in board view
- Use ✔️ icon when done is present in favor of 📆 / 🕙 in board view - Change icon from 📆 to 🕙 for due dates - Move temporal information into own reusable component to encapsulate logic Refs: #1556 Signed-off-by: Stefan Niedermann <info@niedermann.it>
Diffstat (limited to 'app')
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AbstractCardViewHolder.java14
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CompactCardViewHolder.java3
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/DefaultCardOnlyTitleViewHolder.java3
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/DefaultCardViewHolder.java3
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/theme/DeckViewThemeUtils.java37
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/view/DueDateChip.java105
-rw-r--r--app/src/main/res/drawable/due_done_background.xml7
-rw-r--r--app/src/main/res/drawable/due_overdue_background.xml7
-rw-r--r--app/src/main/res/drawable/due_today_background.xml7
-rw-r--r--app/src/main/res/drawable/ic_time_24.xml6
-rw-r--r--app/src/main/res/drawable/ic_time_filled_24.xml5
-rw-r--r--app/src/main/res/layout/item_card_compact.xml8
-rw-r--r--app/src/main/res/layout/item_card_default.xml8
-rw-r--r--app/src/main/res/layout/item_card_default_only_title.xml8
14 files changed, 135 insertions, 86 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AbstractCardViewHolder.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AbstractCardViewHolder.java
index da9790a0d..7653f4ff3 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AbstractCardViewHolder.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AbstractCardViewHolder.java
@@ -22,7 +22,6 @@ import com.nextcloud.android.common.ui.theme.utils.ColorRole;
import org.jetbrains.annotations.Contract;
import java.time.Instant;
-import java.time.ZoneId;
import java.util.List;
import java.util.stream.Collectors;
@@ -32,10 +31,9 @@ import it.niedermann.nextcloud.deck.model.Card;
import it.niedermann.nextcloud.deck.model.User;
import it.niedermann.nextcloud.deck.model.enums.DBStatus;
import it.niedermann.nextcloud.deck.model.full.FullCard;
-import it.niedermann.nextcloud.deck.ui.theme.DeckViewThemeUtils;
import it.niedermann.nextcloud.deck.ui.theme.ThemeUtils;
+import it.niedermann.nextcloud.deck.ui.view.DueDateChip;
import it.niedermann.nextcloud.deck.util.AttachmentUtil;
-import it.niedermann.nextcloud.deck.util.DateUtil;
import it.niedermann.nextcloud.deck.util.MimeTypeUtil;
import it.niedermann.nextcloud.sso.glide.SingleSignOnUrl;
@@ -91,7 +89,7 @@ public abstract class AbstractCardViewHolder extends RecyclerView.ViewHolder {
});
}
- protected abstract TextView getCardDueDate();
+ protected abstract DueDateChip getCardDueDate();
protected abstract ImageView getNotSyncedYet();
@@ -113,12 +111,14 @@ public abstract class AbstractCardViewHolder extends RecyclerView.ViewHolder {
return getCard();
}
- private static void setupDueDate(@NonNull TextView cardDueDate, @NonNull Card card) {
+ private static void setupDueDate(@NonNull DueDateChip cardDueDate, @NonNull Card card) {
final boolean isDone = card.getDone() != null;
final Instant date = isDone ? card.getDone() : card.getDueDate();
- cardDueDate.setText(DateUtil.getRelativeDateTimeString(cardDueDate.getContext(), date.toEpochMilli()));
- DeckViewThemeUtils.themeDueDate(cardDueDate, date.atZone(ZoneId.systemDefault()).toLocalDate(), isDone);
+ if (date == null) {
+ throw new IllegalArgumentException("Expected due date or done date to be present but both were null.");
+ }
+ cardDueDate.setDueDate(date, isDone);
}
protected static void setupCoverImages(@NonNull Account account, @NonNull ViewGroup coverImagesHolder, @NonNull FullCard fullCard, int maxCoverImagesCount) {
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CompactCardViewHolder.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CompactCardViewHolder.java
index cf947c90b..7c53451a5 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CompactCardViewHolder.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CompactCardViewHolder.java
@@ -19,6 +19,7 @@ import it.niedermann.nextcloud.deck.model.Account;
import it.niedermann.nextcloud.deck.model.Label;
import it.niedermann.nextcloud.deck.model.full.FullCard;
import it.niedermann.nextcloud.deck.ui.theme.ThemeUtils;
+import it.niedermann.nextcloud.deck.ui.view.DueDateChip;
public class CompactCardViewHolder extends AbstractCardViewHolder {
private final ItemCardCompactBinding binding;
@@ -63,7 +64,7 @@ public class CompactCardViewHolder extends AbstractCardViewHolder {
}
@Override
- protected TextView getCardDueDate() {
+ protected DueDateChip getCardDueDate() {
return binding.cardDueDate;
}
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/DefaultCardOnlyTitleViewHolder.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/DefaultCardOnlyTitleViewHolder.java
index 27aacc614..1b6b2b3a0 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/DefaultCardOnlyTitleViewHolder.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/DefaultCardOnlyTitleViewHolder.java
@@ -12,6 +12,7 @@ import androidx.annotation.Nullable;
import com.google.android.material.card.MaterialCardView;
import it.niedermann.nextcloud.deck.databinding.ItemCardDefaultOnlyTitleBinding;
+import it.niedermann.nextcloud.deck.ui.view.DueDateChip;
public class DefaultCardOnlyTitleViewHolder extends AbstractCardViewHolder {
private final ItemCardDefaultOnlyTitleBinding binding;
@@ -35,7 +36,7 @@ public class DefaultCardOnlyTitleViewHolder extends AbstractCardViewHolder {
}
@Override
- protected TextView getCardDueDate() {
+ protected DueDateChip getCardDueDate() {
return binding.cardDueDate;
}
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/DefaultCardViewHolder.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/DefaultCardViewHolder.java
index dc6e5a956..083480736 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/DefaultCardViewHolder.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/DefaultCardViewHolder.java
@@ -19,6 +19,7 @@ import it.niedermann.nextcloud.deck.databinding.ItemCardDefaultBinding;
import it.niedermann.nextcloud.deck.model.Account;
import it.niedermann.nextcloud.deck.model.full.FullCard;
import it.niedermann.nextcloud.deck.ui.theme.ThemeUtils;
+import it.niedermann.nextcloud.deck.ui.view.DueDateChip;
public class DefaultCardViewHolder extends AbstractCardViewHolder {
private final ItemCardDefaultBinding binding;
@@ -93,7 +94,7 @@ public class DefaultCardViewHolder extends AbstractCardViewHolder {
}
@Override
- protected TextView getCardDueDate() {
+ protected DueDateChip getCardDueDate() {
return binding.cardDueDate;
}
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/theme/DeckViewThemeUtils.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/theme/DeckViewThemeUtils.java
index d1b1535fd..d52b78f96 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/theme/DeckViewThemeUtils.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/theme/DeckViewThemeUtils.java
@@ -2,7 +2,6 @@ package it.niedermann.nextcloud.deck.ui.theme;
import static com.nextcloud.android.common.ui.util.ColorStateListUtilsKt.buildColorStateList;
import static com.nextcloud.android.common.ui.util.PlatformThemeUtil.isDarkMode;
-import static java.time.temporal.ChronoUnit.DAYS;
import android.content.Context;
import android.content.res.ColorStateList;
@@ -11,7 +10,6 @@ import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.widget.ImageView;
-import android.widget.TextView;
import androidx.annotation.AttrRes;
import androidx.annotation.ColorInt;
@@ -23,7 +21,6 @@ import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.graphics.drawable.DrawableCompat;
-import androidx.core.widget.TextViewCompat;
import com.google.android.material.search.SearchBar;
import com.google.android.material.search.SearchView;
@@ -35,7 +32,6 @@ import com.nextcloud.android.common.ui.theme.utils.ColorRole;
import com.nextcloud.android.common.ui.theme.utils.MaterialViewThemeUtils;
import java.lang.reflect.InvocationTargetException;
-import java.time.LocalDate;
import java.util.Optional;
import it.niedermann.nextcloud.deck.R;
@@ -195,39 +191,6 @@ public class DeckViewThemeUtils extends ViewThemeUtilsBase {
return Optional.empty();
}
-
- @Deprecated(forRemoval = true)
- public static void themeDueDate(@NonNull TextView cardDueDate, @NonNull LocalDate date, boolean isDone) {
- final var context = cardDueDate.getContext();
-
- @ColorInt @Nullable Integer textColor = null;
- @DrawableRes int backgroundDrawable = 0;
-
- if (isDone) {
- // due date: done
- backgroundDrawable = R.drawable.due_done_background;
- textColor = ContextCompat.getColor(context, R.color.due_text_done);
- } else {
- final long diff = DAYS.between(LocalDate.now(), date);
-
- if (diff == 0) {
- // due date: today
- backgroundDrawable = R.drawable.due_today_background;
- textColor = ContextCompat.getColor(context, R.color.due_text_today);
- } else if (diff < 0) {
- // due date: overdue
- backgroundDrawable = R.drawable.due_overdue_background;
- textColor = ContextCompat.getColor(context, R.color.due_text_overdue);
- } // else we use default text styling
- }
-
- cardDueDate.setBackgroundResource(backgroundDrawable);
- if (textColor != null) {
- cardDueDate.setTextColor(textColor);
- TextViewCompat.setCompoundDrawableTintList(cardDueDate, ColorStateList.valueOf(textColor));
- }
- }
-
@Deprecated(forRemoval = true)
public static Drawable getTintedImageView(@NonNull Context context, @DrawableRes int imageId, @ColorInt int color) {
final var drawable = ContextCompat.getDrawable(context, imageId);
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/view/DueDateChip.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/view/DueDateChip.java
new file mode 100644
index 000000000..568dfb053
--- /dev/null
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/view/DueDateChip.java
@@ -0,0 +1,105 @@
+package it.niedermann.nextcloud.deck.ui.view;
+
+import static java.time.temporal.ChronoUnit.DAYS;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+
+import androidx.annotation.ColorInt;
+import androidx.annotation.ColorRes;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.Px;
+import androidx.core.content.ContextCompat;
+
+import com.google.android.material.chip.Chip;
+
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.ZoneId;
+
+import it.niedermann.android.util.DimensionUtil;
+import it.niedermann.nextcloud.deck.R;
+import it.niedermann.nextcloud.deck.util.DateUtil;
+
+public class DueDateChip extends Chip {
+
+ protected @ColorInt int colorOnSurface;
+
+ public DueDateChip(Context context) {
+ super(context);
+ initialize();
+ }
+
+ public DueDateChip(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initialize();
+ }
+
+ public DueDateChip(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initialize();
+ }
+
+ private void initialize() {
+ setEnsureMinTouchTargetSize(false);
+ setMinHeight(0);
+ setChipMinHeight(0);
+ @Px final var padding = DimensionUtil.INSTANCE.dpToPx(getContext(), R.dimen.spacer_1x);
+ setPadding(padding, padding, padding, padding);
+ setClickable(false);
+
+ final var typedValue = new TypedValue();
+ final var theme = getContext().getTheme();
+ theme.resolveAttribute(R.attr.colorOnSurface, typedValue, true);
+ this.colorOnSurface = typedValue.data;
+ }
+
+ public void setDueDate(@NonNull Instant date, boolean isDone) {
+ setText(DateUtil.getRelativeDateTimeString(getContext(), date.toEpochMilli()));
+
+ @DrawableRes final int chipIconRes;
+ @Nullable @ColorRes final Integer textColorRes;
+ @ColorRes final int backgroundColorRes;
+
+ if (isDone) { // Done
+ chipIconRes = R.drawable.ic_check_white_24dp;
+ backgroundColorRes = R.color.due_done;
+ textColorRes = R.color.due_text_done;
+
+ } else {
+ final long diff = DAYS.between(LocalDate.now(), date.atZone(ZoneId.systemDefault()).toLocalDate());
+
+ if (diff == 0) { // Today
+ chipIconRes = R.drawable.ic_time_24;
+ backgroundColorRes = R.color.due_today;
+ textColorRes = R.color.due_text_today;
+
+ } else if (diff < 0) { // Overdue
+ chipIconRes = R.drawable.ic_time_filled_24;
+ backgroundColorRes = R.color.due_overdue;
+ textColorRes = R.color.due_text_overdue;
+
+ } else { // Future
+ chipIconRes = R.drawable.ic_time_24;
+ backgroundColorRes = android.R.color.transparent;
+ textColorRes = null;
+ }
+ }
+
+ setChipIcon(ContextCompat.getDrawable(getContext(), chipIconRes));
+ setChipBackgroundColorResource(backgroundColorRes);
+
+ if (textColorRes == null) {
+ setTextColor(colorOnSurface);
+ setChipIconTint(ColorStateList.valueOf(colorOnSurface));
+
+ } else {
+ setTextColor(ContextCompat.getColor(getContext(), textColorRes));
+ setChipIconTintResource(textColorRes);
+ }
+ }
+} \ No newline at end of file
diff --git a/app/src/main/res/drawable/due_done_background.xml b/app/src/main/res/drawable/due_done_background.xml
deleted file mode 100644
index cdc93a0b9..000000000
--- a/app/src/main/res/drawable/due_done_background.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="@color/due_done" />
-
- <corners
- android:radius="4dp" />
-</shape> \ No newline at end of file
diff --git a/app/src/main/res/drawable/due_overdue_background.xml b/app/src/main/res/drawable/due_overdue_background.xml
deleted file mode 100644
index 658797d91..000000000
--- a/app/src/main/res/drawable/due_overdue_background.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="@color/due_overdue" />
-
- <corners
- android:radius="4dp" />
-</shape> \ No newline at end of file
diff --git a/app/src/main/res/drawable/due_today_background.xml b/app/src/main/res/drawable/due_today_background.xml
deleted file mode 100644
index fc0a6a727..000000000
--- a/app/src/main/res/drawable/due_today_background.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="@color/due_today" />
-
- <corners
- android:radius="4dp" />
-</shape> \ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_time_24.xml b/app/src/main/res/drawable/ic_time_24.xml
new file mode 100644
index 000000000..e0355a270
--- /dev/null
+++ b/app/src/main/res/drawable/ic_time_24.xml
@@ -0,0 +1,6 @@
+<vector android:autoMirrored="true" android:height="24dp"
+ android:tint="?attr/colorOnSurface" android:viewportHeight="24"
+ android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@android:color/white" android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
+ <path android:fillColor="@android:color/white" android:pathData="M12.5,7H11v6l5.25,3.15 0.75,-1.23 -4.5,-2.67z"/>
+</vector>
diff --git a/app/src/main/res/drawable/ic_time_filled_24.xml b/app/src/main/res/drawable/ic_time_filled_24.xml
new file mode 100644
index 000000000..77d3da030
--- /dev/null
+++ b/app/src/main/res/drawable/ic_time_filled_24.xml
@@ -0,0 +1,5 @@
+<vector android:autoMirrored="true" android:height="24dp"
+ android:tint="?attr/colorOnSurface" android:viewportHeight="24"
+ android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@android:color/white" android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM15.29,16.71L11,12.41V7h2v4.59l3.71,3.71L15.29,16.71z"/>
+</vector>
diff --git a/app/src/main/res/layout/item_card_compact.xml b/app/src/main/res/layout/item_card_compact.xml
index 3a14b0d43..16336d4d4 100644
--- a/app/src/main/res/layout/item_card_compact.xml
+++ b/app/src/main/res/layout/item_card_compact.xml
@@ -52,15 +52,11 @@
app:srcCompat="@drawable/ic_sync_blue_24dp"
tools:visibility="visible" />
- <com.google.android.material.textview.MaterialTextView
+ <it.niedermann.nextcloud.deck.ui.view.DueDateChip
android:id="@+id/card_due_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:drawablePadding="@dimen/spacer_1hx"
- android:gravity="center"
- android:paddingHorizontal="@dimen/spacer_1x"
- android:paddingVertical="@dimen/spacer_1hx"
- app:drawableStartCompat="@drawable/calendar_blank_grey600_24dp"
+ tools:chipIcon="@drawable/ic_time_24"
tools:text="tomorrow" />
<ImageView
diff --git a/app/src/main/res/layout/item_card_default.xml b/app/src/main/res/layout/item_card_default.xml
index 7454129f4..a46582418 100644
--- a/app/src/main/res/layout/item_card_default.xml
+++ b/app/src/main/res/layout/item_card_default.xml
@@ -54,15 +54,11 @@
app:srcCompat="@drawable/ic_sync_blue_24dp"
tools:visibility="visible" />
- <androidx.appcompat.widget.AppCompatTextView
+ <it.niedermann.nextcloud.deck.ui.view.DueDateChip
android:id="@+id/card_due_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:drawablePadding="@dimen/spacer_1hx"
- android:gravity="center"
- android:paddingHorizontal="@dimen/spacer_1x"
- android:paddingVertical="@dimen/spacer_1hx"
- app:drawableStartCompat="@drawable/calendar_blank_grey600_24dp"
+ tools:chipIcon="@drawable/ic_time_24"
tools:text="tomorrow" />
</LinearLayout>
diff --git a/app/src/main/res/layout/item_card_default_only_title.xml b/app/src/main/res/layout/item_card_default_only_title.xml
index 1739a2905..145023167 100644
--- a/app/src/main/res/layout/item_card_default_only_title.xml
+++ b/app/src/main/res/layout/item_card_default_only_title.xml
@@ -37,15 +37,11 @@
app:srcCompat="@drawable/ic_sync_blue_24dp"
tools:visibility="visible" />
- <com.google.android.material.textview.MaterialTextView
+ <it.niedermann.nextcloud.deck.ui.view.DueDateChip
android:id="@+id/card_due_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:drawablePadding="@dimen/spacer_1hx"
- android:gravity="center"
- android:paddingHorizontal="@dimen/spacer_1x"
- android:paddingVertical="@dimen/spacer_1hx"
- app:drawableStartCompat="@drawable/calendar_blank_grey600_24dp"
+ tools:chipIcon="@drawable/ic_time_24"
tools:text="tomorrow" />
<ImageView