diff --git a/app/src/main/java/eu/faircode/email/AdapterIdentity.java b/app/src/main/java/eu/faircode/email/AdapterIdentity.java index 976f259119..085eb7a7f2 100644 --- a/app/src/main/java/eu/faircode/email/AdapterIdentity.java +++ b/app/src/main/java/eu/faircode/email/AdapterIdentity.java @@ -373,6 +373,11 @@ public class AdapterIdentity extends RecyclerView.Adapter() { @Override public int compare(TupleIdentityEx i1, TupleIdentityEx i2) { + int c = collator.compare( + i1.accountCategory == null ? "" : i1.accountCategory, + i2.accountCategory == null ? "" : i2.accountCategory); + if (c != 0) + return c; int n = collator.compare(i1.getDisplayName(), i2.getDisplayName()); if (n != 0) return n; @@ -450,6 +455,13 @@ public class AdapterIdentity extends RecyclerView.Adapter= 0 && pos < items.size()) + return items.get(pos); + else + return null; + } + @Override public int getItemCount() { return items.size(); diff --git a/app/src/main/java/eu/faircode/email/DaoIdentity.java b/app/src/main/java/eu/faircode/email/DaoIdentity.java index 2e92ec3201..12b7dd4db1 100644 --- a/app/src/main/java/eu/faircode/email/DaoIdentity.java +++ b/app/src/main/java/eu/faircode/email/DaoIdentity.java @@ -32,13 +32,17 @@ public interface DaoIdentity { @Query(TupleIdentityView.query) LiveData> liveIdentityView(); - @Query("SELECT identity.*, account.name AS accountName, folder.id AS drafts" + + @Query("SELECT identity.*" + + ", account.name AS accountName, account.category AS accountCategory" + + ", folder.id AS drafts" + " FROM identity" + " JOIN account ON account.id = identity.account" + " LEFT JOIN folder ON folder.account = account.id AND folder.type = '" + EntityFolder.DRAFTS + "'") LiveData> liveIdentities(); - @Query("SELECT identity.*, account.name AS accountName, folder.id AS drafts" + + @Query("SELECT identity.*" + + ", account.name AS accountName, account.category AS accountCategory" + + ", folder.id AS drafts" + " FROM identity" + " JOIN account ON account.id = identity.account" + " JOIN folder ON folder.account = identity.account AND folder.type = '" + EntityFolder.DRAFTS + "'" + @@ -46,7 +50,9 @@ public interface DaoIdentity { " AND account.synchronize") LiveData> liveComposableIdentities(); - @Query("SELECT identity.*, account.name AS accountName, folder.id AS drafts" + + @Query("SELECT identity.*" + + ", account.name AS accountName, account.category AS accountCategory" + + ", folder.id AS drafts" + " FROM identity" + " JOIN account ON account.id = identity.account" + " JOIN folder ON folder.account = identity.account AND folder.type = '" + EntityFolder.DRAFTS + "'" + diff --git a/app/src/main/java/eu/faircode/email/FragmentIdentities.java b/app/src/main/java/eu/faircode/email/FragmentIdentities.java index 9c1edc0a55..f31870b308 100644 --- a/app/src/main/java/eu/faircode/email/FragmentIdentities.java +++ b/app/src/main/java/eu/faircode/email/FragmentIdentities.java @@ -19,14 +19,19 @@ package eu.faircode.email; Copyright 2018-2021 by Marcel Bokhorst (M66B) */ +import static androidx.recyclerview.widget.RecyclerView.NO_POSITION; + import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; import android.content.SharedPreferences; +import android.graphics.Canvas; +import android.graphics.Rect; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -43,6 +48,7 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton; import java.util.ArrayList; import java.util.List; +import java.util.Objects; public class FragmentIdentities extends FragmentBase { private boolean cards; @@ -88,6 +94,74 @@ public class FragmentIdentities extends FragmentBase { rvIdentity.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; + + TupleIdentityEx prev = adapter.getItemAtPosition(pos - 1); + TupleIdentityEx identity = adapter.getItemAtPosition(pos); + if (pos > 0 && prev == null) + return null; + if (identity == null) + return null; + + if (pos > 0) { + if (Objects.equals(prev.accountCategory, identity.accountCategory)) + return null; + } else { + if (identity.accountCategory == 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(identity.accountCategory); + 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; + } + }; + rvIdentity.addItemDecoration(categoryDecorator); + adapter = new AdapterIdentity(this); rvIdentity.setAdapter(adapter); diff --git a/app/src/main/java/eu/faircode/email/TupleIdentityEx.java b/app/src/main/java/eu/faircode/email/TupleIdentityEx.java index 3412ee0e22..e9f805230a 100644 --- a/app/src/main/java/eu/faircode/email/TupleIdentityEx.java +++ b/app/src/main/java/eu/faircode/email/TupleIdentityEx.java @@ -23,6 +23,7 @@ import java.util.Objects; public class TupleIdentityEx extends EntityIdentity { public String accountName; + public String accountCategory; public Long drafts; @Override @@ -30,6 +31,7 @@ public class TupleIdentityEx extends EntityIdentity { if (obj instanceof TupleIdentityEx) { TupleIdentityEx other = (TupleIdentityEx) obj; return (super.equals(obj) && + Objects.equals(accountCategory, other.accountCategory) && Objects.equals(accountName, other.accountName) && Objects.equals(drafts, other.drafts)); } else