From c8e292f2bfa79c8222f56fb1a478676a51f0fa19 Mon Sep 17 00:00:00 2001 From: M66B Date: Sat, 22 Jan 2022 11:30:19 +0100 Subject: [PATCH] Display answers by group --- CHANGELOG.md | 1 + app/src/main/assets/CHANGELOG.md | 1 + .../java/eu/faircode/email/AdapterAnswer.java | 11 ++- .../java/eu/faircode/email/DaoAnswer.java | 2 +- .../eu/faircode/email/FragmentAnswers.java | 79 +++++++++++++++++++ app/src/main/res/layout/item_answer.xml | 17 +--- metadata/en-US/changelogs/1817.txt | 1 + 7 files changed, 92 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8162d33859..b8cee59f6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### Next version * Added colors to reply templates +* Added displaying reply templates by group * Added option to group messages by account category (default disabled) * Small improvements and minor bug fixes diff --git a/app/src/main/assets/CHANGELOG.md b/app/src/main/assets/CHANGELOG.md index 8162d33859..b8cee59f6d 100644 --- a/app/src/main/assets/CHANGELOG.md +++ b/app/src/main/assets/CHANGELOG.md @@ -7,6 +7,7 @@ ### Next version * Added colors to reply templates +* Added displaying reply templates by group * Added option to group messages by account category (default disabled) * Small improvements and minor bug fixes diff --git a/app/src/main/java/eu/faircode/email/AdapterAnswer.java b/app/src/main/java/eu/faircode/email/AdapterAnswer.java index 5286368cf0..4c92b06dee 100644 --- a/app/src/main/java/eu/faircode/email/AdapterAnswer.java +++ b/app/src/main/java/eu/faircode/email/AdapterAnswer.java @@ -73,7 +73,6 @@ public class AdapterAnswer extends RecyclerView.Adapter= 0 && pos < selected.size()) + return selected.get(pos); + else + return null; + } + @Override public int getItemCount() { return selected.size(); diff --git a/app/src/main/java/eu/faircode/email/DaoAnswer.java b/app/src/main/java/eu/faircode/email/DaoAnswer.java index f9a00d08c2..3e52f988f4 100644 --- a/app/src/main/java/eu/faircode/email/DaoAnswer.java +++ b/app/src/main/java/eu/faircode/email/DaoAnswer.java @@ -58,7 +58,7 @@ public interface DaoAnswer { EntityAnswer getReceiptAnswer(); @Query("SELECT * FROM answer" + - " ORDER BY -favorite, name COLLATE NOCASE") + " ORDER BY `group`, -favorite, name COLLATE NOCASE") LiveData> liveAnswers(); @Query("SELECT COUNT(*) FROM answer" + diff --git a/app/src/main/java/eu/faircode/email/FragmentAnswers.java b/app/src/main/java/eu/faircode/email/FragmentAnswers.java index 2ee8b60fa0..2209780766 100644 --- a/app/src/main/java/eu/faircode/email/FragmentAnswers.java +++ b/app/src/main/java/eu/faircode/email/FragmentAnswers.java @@ -19,7 +19,11 @@ package eu.faircode.email; Copyright 2018-2022 by Marcel Bokhorst (M66B) */ +import static androidx.recyclerview.widget.RecyclerView.NO_POSITION; + import android.content.SharedPreferences; +import android.graphics.Canvas; +import android.graphics.Rect; import android.os.Bundle; import android.text.TextUtils; import android.view.LayoutInflater; @@ -28,12 +32,14 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.SearchView; import androidx.constraintlayout.widget.Group; import androidx.fragment.app.FragmentTransaction; +import androidx.lifecycle.Lifecycle; import androidx.lifecycle.Observer; import androidx.preference.PreferenceManager; import androidx.recyclerview.widget.DividerItemDecoration; @@ -44,6 +50,7 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton; import java.util.ArrayList; import java.util.List; +import java.util.Objects; public class FragmentAnswers extends FragmentBase { private boolean cards; @@ -90,6 +97,78 @@ public class FragmentAnswers extends FragmentBase { rvAnswer.addItemDecoration(itemDecorator); } + DividerItemDecoration categoryDecorator = new DividerItemDecoration(getContext(), llm.getOrientation()) { + @Override + public void onDraw(@NonNull Canvas canvas, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { + int count = parent.getChildCount(); + for (int i = 0; i < count; i++) { + View view = parent.getChildAt(i); + int pos = parent.getChildAdapterPosition(view); + + View header = getView(view, parent, pos); + if (header != null) { + canvas.save(); + canvas.translate(0, parent.getChildAt(i).getTop() - header.getMeasuredHeight()); + header.draw(canvas); + canvas.restore(); + } + } + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + int pos = parent.getChildAdapterPosition(view); + View header = getView(view, parent, pos); + if (header == null) + outRect.setEmpty(); + else + outRect.top = header.getMeasuredHeight(); + } + + private View getView(View view, RecyclerView parent, int pos) { + if (pos == NO_POSITION) + return null; + + if (!getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) + return null; + + EntityAnswer prev = adapter.getItemAtPosition(pos - 1); + EntityAnswer account = adapter.getItemAtPosition(pos); + if (pos > 0 && prev == null) + return null; + if (account == null) + return null; + + if (pos > 0) { + if (Objects.equals(prev.group, account.group)) + return null; + } else { + if (account.group == null) + return null; + } + + View header = inflater.inflate(R.layout.item_group, parent, false); + TextView tvCategory = header.findViewById(R.id.tvCategory); + TextView tvDate = header.findViewById(R.id.tvDate); + + if (cards) { + View vSeparator = header.findViewById(R.id.vSeparator); + vSeparator.setVisibility(View.GONE); + } + + tvCategory.setText(account.group); + tvDate.setVisibility(View.GONE); + + header.measure(View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); + header.layout(0, 0, header.getMeasuredWidth(), header.getMeasuredHeight()); + + return header; + } + }; + + rvAnswer.addItemDecoration(categoryDecorator); + adapter = new AdapterAnswer(this); rvAnswer.setAdapter(adapter); diff --git a/app/src/main/res/layout/item_answer.xml b/app/src/main/res/layout/item_answer.xml index 1507dfed0b..5615f5037c 100644 --- a/app/src/main/res/layout/item_answer.xml +++ b/app/src/main/res/layout/item_answer.xml @@ -39,19 +39,6 @@ app:layout_constraintStart_toEndOf="@id/vwColor" app:layout_constraintTop_toTopOf="parent" /> - - + app:layout_constraintTop_toBottomOf="@id/tvName" /> + app:layout_constraintTop_toBottomOf="@id/tvName" />