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
diff options
context:
space:
mode:
authorStefan Niedermann <info@niedermann.it>2024-01-15 21:16:04 +0300
committerStefan Niedermann <info@niedermann.it>2024-01-15 21:30:35 +0300
commit8405834a5db1701120e65d17997b14e91853626b (patch)
treea02bacda86f1f4e4b51391d4dd47e3f3cab5e7b6 /app/src/main/java/it
parent5efb0875514efa77744a38a7ddc243f8375b5740 (diff)
chore(done): Limit done support to Deck server 1.12.0 and higher
Refs: #1556 Signed-off-by: Stefan Niedermann <info@niedermann.it>
Diffstat (limited to 'app/src/main/java/it')
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/database/dao/CardDao.java2
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/database/migration/Migration_32_33.java2
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/model/ocs/Version.java15
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/comments/ItemCommentViewHolder.java2
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDetailsFragment.java9
-rw-r--r--app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDueDateView.java165
6 files changed, 107 insertions, 88 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/database/dao/CardDao.java b/app/src/main/java/it/niedermann/nextcloud/deck/database/dao/CardDao.java
index 5d25f943f..d3d6f4060 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/database/dao/CardDao.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/database/dao/CardDao.java
@@ -23,7 +23,7 @@ public interface CardDao extends GenericDao<Card> {
"and (c.deletedAt is null or c.deletedAt = 0) " +
"and (s.deletedAt is null or s.deletedAt = 0) " +
"and (b.deletedAt is null or b.deletedAt = 0) " +
- // FUll Logic: (hasDueDate AND isIn_PRIVATE_Board) OR (isInSharedBoard AND (assignedToMe OR (hasDueDate AND noAssignees)))
+ // Full Logic: (hasDueDate AND isIn_PRIVATE_Board) OR (isInSharedBoard AND (assignedToMe OR (hasDueDate AND noAssignees)))
"and (" +
"(c.dueDate is not null AND NOT exists(select 1 from AccessControl ac where ac.boardId = b.localId and ac.status <> 3))" + //(hasDueDate AND isInPrivateBoard)
"OR (" +
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/database/migration/Migration_32_33.java b/app/src/main/java/it/niedermann/nextcloud/deck/database/migration/Migration_32_33.java
index c19b06715..d6938dda6 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/database/migration/Migration_32_33.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/database/migration/Migration_32_33.java
@@ -16,7 +16,7 @@ public class Migration_32_33 extends Migration {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE `Card` add column done INTEGER");
- // reset etags, so cards will be fetched after app-update
+ // Reset ETags: Refetch all cards to support Done state which did not change ETags
database.execSQL("UPDATE `Account` SET `boardsEtag` = NULL");
database.execSQL("UPDATE `Board` SET `etag` = NULL");
database.execSQL("UPDATE `Stack` SET `etag` = NULL");
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/model/ocs/Version.java b/app/src/main/java/it/niedermann/nextcloud/deck/model/ocs/Version.java
index 355307ce0..a0f375329 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/model/ocs/Version.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/model/ocs/Version.java
@@ -9,6 +9,7 @@ import java.util.regex.Pattern;
import it.niedermann.nextcloud.deck.R;
import it.niedermann.nextcloud.deck.model.Attachment;
+import it.niedermann.nextcloud.deck.model.Card;
import it.niedermann.nextcloud.deck.model.ocs.comment.DeckComment;
public class Version implements Comparable<Version> {
@@ -17,6 +18,7 @@ public class Version implements Comparable<Version> {
private static final Version VERSION_1_0_0 = new Version("1.0.0", 1, 0, 0);
private static final Version VERSION_1_0_3 = new Version("1.0.3", 1, 0, 3);
private static final Version VERSION_1_3_0 = new Version("1.3.0", 1, 3, 0);
+ private static final Version VERSION_1_12_0 = new Version("1.12.0", 1, 12, 0);
private String originalVersion = "?";
private final int major;
@@ -148,11 +150,11 @@ public class Version implements Comparable<Version> {
/**
* Replying to a {@link DeckComment} does cause synchronization errors because the API expected the
* <code>parentId</code> to be a {@link String} up until {@link Version} 1.0.3
- * https://github.com/nextcloud/deck/issues/1831#issuecomment-627207849
*
* @return whether or not the server supports replying to comments
+ * @see <a href="https://github.com/nextcloud/deck/issues/1831#issuecomment-627207849">Deck server issue #1831</a>
*/
- public boolean supportsCommentsReplys() {
+ public boolean supportsCommentsReplies() {
return isGreaterOrEqualTo(VERSION_1_0_3);
}
@@ -171,6 +173,15 @@ public class Version implements Comparable<Version> {
}
/**
+ * Cards started to have an additional property called <a href="https://github.com/nextcloud/deck/pull/4137"><code>done</code></a> with {@link #VERSION_1_12_0}.
+ *
+ * @return whether or not the server supports the {@link Card#getDone()} state
+ */
+ public boolean supportsDone() {
+ return isGreaterOrEqualTo(VERSION_1_12_0);
+ }
+
+ /**
* Title max length has been increased from 100 to 255 characters beginning with server {@link Version} 1.0.0
*
* @return the number of characters that the title fields of cards allow
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/comments/ItemCommentViewHolder.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/comments/ItemCommentViewHolder.java
index 221beea76..e2bf7a84b 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/comments/ItemCommentViewHolder.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/comments/ItemCommentViewHolder.java
@@ -64,7 +64,7 @@ public class ItemCommentViewHolder extends RecyclerView.ViewHolder {
inflater.inflate(R.menu.comment_menu, menu);
menu.findItem(android.R.id.copy).setOnMenuItemClickListener(item -> ClipboardUtil.INSTANCE.copyToClipboard(itemView.getContext(), comment.getComment().getMessage()));
final var replyMenuItem = menu.findItem(R.id.reply);
- if (comment.getStatusEnum() != DBStatus.LOCAL_EDITED && account.getServerDeckVersionAsObject().supportsCommentsReplys()) {
+ if (comment.getStatusEnum() != DBStatus.LOCAL_EDITED && account.getServerDeckVersionAsObject().supportsCommentsReplies()) {
replyMenuItem.setOnMenuItemClickListener(item -> {
selectAsReplyListener.onSelectAsReply(comment);
return true;
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDetailsFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDetailsFragment.java
index f5b7149e6..4401eaf08 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDetailsFragment.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDetailsFragment.java
@@ -183,24 +183,27 @@ public class CardDetailsFragment extends Fragment implements CardDueDateView.Due
}
private void setupDueDate() {
+ final var version = this.viewModel.getAccount().getServerDeckVersionAsObject();
final var card = this.viewModel.getFullCard().getCard();
binding.cardDueDateView.setDueDateListener(this);
binding.cardDueDateView.setEnabled(this.viewModel.canEdit());
- binding.cardDueDateView.setDueDate(getChildFragmentManager(), card.getDueDate(), card.getDone());
+ binding.cardDueDateView.setDueDate(getChildFragmentManager(), version, card.getDueDate(), card.getDone());
}
@Override
public void onDueDateChanged(@Nullable Instant dueDate) {
+ final var version = this.viewModel.getAccount().getServerDeckVersionAsObject();
final var card = this.viewModel.getFullCard().getCard();
card.setDueDate(dueDate);
- binding.cardDueDateView.setDueDate(getChildFragmentManager(), card.getDueDate(), card.getDone());
+ binding.cardDueDateView.setDueDate(getChildFragmentManager(), version, card.getDueDate(), card.getDone());
}
@Override
public void onDoneChanged(@Nullable Instant done) {
+ final var version = this.viewModel.getAccount().getServerDeckVersionAsObject();
final var card = this.viewModel.getFullCard().getCard();
card.setDone(done);
- binding.cardDueDateView.setDueDate(getChildFragmentManager(), card.getDueDate(), card.getDone());
+ binding.cardDueDateView.setDueDate(getChildFragmentManager(), version, card.getDueDate(), card.getDone());
}
private void setupLabels(@NonNull Account account) {
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDueDateView.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDueDateView.java
index 147b1032a..a9f7e02c2 100644
--- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDueDateView.java
+++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDueDateView.java
@@ -27,6 +27,7 @@ import java.util.stream.Stream;
import it.niedermann.nextcloud.deck.R;
import it.niedermann.nextcloud.deck.databinding.ViewCardDueDateBinding;
+import it.niedermann.nextcloud.deck.model.ocs.Version;
import it.niedermann.nextcloud.deck.ui.theme.ThemeUtils;
import it.niedermann.nextcloud.deck.ui.theme.Themed;
import it.niedermann.nextcloud.deck.ui.theme.ThemedDatePickerDialog;
@@ -40,6 +41,7 @@ public class CardDueDateView extends FrameLayout implements DatePickerDialog.OnD
private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("d. MMM yyyy HH:mm");
private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
private final DateTimeFormatter timeFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
+ boolean supportsDone = false;
@Nullable
private Instant dueDate = null;
@Nullable
@@ -64,6 +66,9 @@ public class CardDueDateView extends FrameLayout implements DatePickerDialog.OnD
binding = ViewCardDueDateBinding.inflate(LayoutInflater.from(context), this, true);
}
+ /**
+ * @noinspection unused
+ */
public CardDueDateView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
binding = ViewCardDueDateBinding.inflate(LayoutInflater.from(context), this, true);
@@ -77,8 +82,9 @@ public class CardDueDateView extends FrameLayout implements DatePickerDialog.OnD
}
}
- public void setDueDate(@NonNull FragmentManager fragmentManager, @Nullable Instant dueDate, @Nullable Instant done) {
+ public void setDueDate(@NonNull FragmentManager fragmentManager, @NonNull Version version, @Nullable Instant dueDate, @Nullable Instant done) {
this.fragmentManager = fragmentManager;
+ this.supportsDone = version.supportsDone();
this.dueDate = dueDate;
this.done = done;
render();
@@ -90,6 +96,72 @@ public class CardDueDateView extends FrameLayout implements DatePickerDialog.OnD
setInteraction();
}
+ private void setVisibilityState() {
+ if (done == null) {
+ Stream.of(
+ binding.dueDateDateWrapper,
+ binding.dueDateTimeWrapper
+ ).forEach(v -> v.setVisibility(View.VISIBLE));
+
+ Stream.of(
+ binding.doneCheck,
+ binding.doneDueDate,
+ binding.doneDate,
+ binding.clearDone
+ ).forEach(v -> v.setVisibility(View.GONE));
+
+ binding.markAsDone.setVisibility(supportsDone ? View.VISIBLE : View.GONE);
+ binding.clearDueDate.setVisibility(dueDate == null || !isEnabled() ? View.GONE : View.VISIBLE);
+ } else {
+
+ Stream.of(
+ binding.doneCheck,
+ binding.doneDate,
+ binding.clearDone
+ ).forEach(v -> v.setVisibility(View.VISIBLE));
+
+ Stream.of(
+ binding.markAsDone,
+ binding.dueDateDateWrapper,
+ binding.dueDateTimeWrapper,
+ binding.clearDueDate
+ ).forEach(v -> v.setVisibility(View.GONE));
+
+ binding.doneDueDate.setVisibility(dueDate == null || !isEnabled() ? View.GONE : View.VISIBLE);
+ }
+ }
+
+ private void setTextState() {
+ if (done == null) {
+ binding.doneDate.setText(null);
+ binding.doneDueDate.setText(null);
+
+ if (this.dueDate == null) {
+ binding.dueDateDate.setText(null);
+ binding.dueDateTime.setText(null);
+
+ } else {
+ final var dueDate = this.dueDate.atZone(ZoneId.systemDefault());
+ binding.dueDateDate.setText(dueDate.format(dateFormatter));
+ binding.dueDateTime.setText(dueDate.format(timeFormatter));
+ }
+
+ } else {
+ binding.dueDateDate.setText(null);
+ binding.dueDateTime.setText(null);
+
+ binding.doneDate.setText(done.atZone(ZoneId.systemDefault()).format(dateTimeFormatter));
+
+ if (this.dueDate == null) {
+ binding.doneDueDate.setText(null);
+
+ } else {
+ final var dueDate = this.dueDate.atZone(ZoneId.systemDefault());
+ binding.doneDueDate.setText(getContext().getString(R.string.label_due_at, dueDate.format(dateTimeFormatter)));
+ }
+ }
+ }
+
private void setInteraction() {
final var enabled = isEnabled();
@@ -103,11 +175,15 @@ public class CardDueDateView extends FrameLayout implements DatePickerDialog.OnD
}
});
- binding.markAsDone.setOnClickListener(v -> {
- if (this.dueDateChangedListener != null) {
- this.dueDateChangedListener.onDoneChanged(Instant.now());
- }
- });
+ if (supportsDone) {
+ binding.markAsDone.setOnClickListener(v -> {
+ if (this.dueDateChangedListener != null) {
+ this.dueDateChangedListener.onDoneChanged(Instant.now());
+ }
+ });
+ } else {
+ binding.markAsDone.setOnClickListener(null);
+ }
binding.clearDueDate.setOnClickListener(v -> {
if (this.dueDateChangedListener != null) {
@@ -154,72 +230,6 @@ public class CardDueDateView extends FrameLayout implements DatePickerDialog.OnD
}
}
- private void setTextState() {
- if (done == null) {
- binding.doneDate.setText(null);
- binding.doneDueDate.setText(null);
-
- if (this.dueDate == null) {
- binding.dueDateDate.setText(null);
- binding.dueDateTime.setText(null);
-
- } else {
- final var dueDate = this.dueDate.atZone(ZoneId.systemDefault());
- binding.dueDateDate.setText(dueDate.format(dateFormatter));
- binding.dueDateTime.setText(dueDate.format(timeFormatter));
- }
-
- } else {
- binding.dueDateDate.setText(null);
- binding.dueDateTime.setText(null);
-
- binding.doneDate.setText(done.atZone(ZoneId.systemDefault()).format(dateTimeFormatter));
-
- if (this.dueDate == null) {
- binding.doneDueDate.setText(null);
-
- } else {
- final var dueDate = this.dueDate.atZone(ZoneId.systemDefault());
- binding.doneDueDate.setText(getContext().getString(R.string.label_due_at, dueDate.format(dateTimeFormatter)));
- }
- }
- }
-
- private void setVisibilityState() {
- if (done == null) {
- Stream.of(
- binding.markAsDone,
- binding.dueDateDateWrapper,
- binding.dueDateTimeWrapper
- ).forEach(v -> v.setVisibility(View.VISIBLE));
-
- Stream.of(
- binding.doneCheck,
- binding.doneDueDate,
- binding.doneDate,
- binding.clearDone
- ).forEach(v -> v.setVisibility(View.GONE));
-
- binding.clearDueDate.setVisibility(dueDate == null || !isEnabled() ? View.GONE : View.VISIBLE);
- } else {
-
- Stream.of(
- binding.doneCheck,
- binding.doneDate,
- binding.clearDone
- ).forEach(v -> v.setVisibility(View.VISIBLE));
-
- Stream.of(
- binding.markAsDone,
- binding.dueDateDateWrapper,
- binding.dueDateTimeWrapper,
- binding.clearDueDate
- ).forEach(v -> v.setVisibility(View.GONE));
-
- binding.doneDueDate.setVisibility(dueDate == null || !isEnabled() ? View.GONE : View.VISIBLE);
- }
- }
-
@Override
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
int hourOfDay;
@@ -230,6 +240,7 @@ public class CardDueDateView extends FrameLayout implements DatePickerDialog.OnD
hourOfDay = 0;
minute = 0;
} else {
+ assert this.dueDate != null; // Since selectedTime is not empty and is derived from dueDate, dueDate itself shouldn't be null here.
final var oldTime = LocalTime.from(this.dueDate.atZone(ZoneId.systemDefault()));
hourOfDay = oldTime.getHour();
minute = oldTime.getMinute();
@@ -269,19 +280,13 @@ public class CardDueDateView extends FrameLayout implements DatePickerDialog.OnD
binding.dueDateTimeWrapper
).forEach(utils.material::colorTextInputLayout);
-// Stream.of(
-// binding.doneDueDate,
-// binding.doneDate
-// ).forEach(v -> utils.platform.colorTextView(v, ColorRole.ON_SURFACE));
-
- utils.platform.colorTextView(binding.doneDate, ColorRole.ON_SURFACE);
- utils.platform.colorTextView(binding.doneDueDate, ColorRole.ON_SURFACE_VARIANT);
-
Stream.of(
binding.clearDone,
binding.clearDueDate
).forEach(v -> utils.platform.colorImageView(v, ColorRole.SECONDARY));
+ utils.platform.colorTextView(binding.doneDate, ColorRole.ON_SURFACE);
+ utils.platform.colorTextView(binding.doneDueDate, ColorRole.ON_SURFACE_VARIANT);
utils.material.colorMaterialButtonPrimaryTonal(binding.markAsDone);
}