diff --git a/app/src/main/java/eu/faircode/email/ActivityBase.java b/app/src/main/java/eu/faircode/email/ActivityBase.java index 9939018480..83f77cabcc 100644 --- a/app/src/main/java/eu/faircode/email/ActivityBase.java +++ b/app/src/main/java/eu/faircode/email/ActivityBase.java @@ -91,15 +91,7 @@ abstract class ActivityBase extends AppCompatActivity implements SharedPreferenc finish(); if (this.getClass().equals(ActivitySetup.class)) startActivity(getIntent()); - } else if (!this.getClass().equals(ActivitySetup.class) && - ("threading".equals(key) || - "compact".equals(key) || - "avatars".equals(key) || - "identicons".equals(key) || - "preview".equals(key) || - "actionbar".equals(key) || - "confirm".equals(key) || - "debug".equals(key))) + } else if (!this.getClass().equals(ActivitySetup.class)) finish(); } diff --git a/app/src/main/java/eu/faircode/email/ActivityView.java b/app/src/main/java/eu/faircode/email/ActivityView.java index 80705e3904..43193ab435 100644 --- a/app/src/main/java/eu/faircode/email/ActivityView.java +++ b/app/src/main/java/eu/faircode/email/ActivityView.java @@ -98,6 +98,8 @@ import androidx.lifecycle.ViewModelProviders; import androidx.localbroadcastmanager.content.LocalBroadcastManager; public class ActivityView extends ActivityBilling implements FragmentManager.OnBackStackChangedListener { + private boolean unified; + private View view; private DrawerLayout drawerLayout; private Group grpPane; @@ -138,6 +140,9 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + unified = prefs.getBoolean("unified", true); + view = LayoutInflater.from(this).inflate(R.layout.activity_view, null); setContentView(view); @@ -299,11 +304,8 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB }); if (getSupportFragmentManager().getFragments().size() == 0) { - Bundle args = new Bundle(); - args.putLong("folder", -1); - - FragmentMessages fragment = new FragmentMessages(); - fragment.setArguments(args); + FragmentEx fragment = (unified ? new FragmentMessages() : new FragmentFolders()); + fragment.setArguments(new Bundle()); FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack("unified"); diff --git a/app/src/main/java/eu/faircode/email/AdapterFolder.java b/app/src/main/java/eu/faircode/email/AdapterFolder.java index 2f6230c60c..4c8c37e6ce 100644 --- a/app/src/main/java/eu/faircode/email/AdapterFolder.java +++ b/app/src/main/java/eu/faircode/email/AdapterFolder.java @@ -23,6 +23,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; +import android.graphics.Color; import android.graphics.Typeface; import android.os.Bundle; import android.preference.PreferenceManager; @@ -54,7 +55,7 @@ import androidx.recyclerview.widget.RecyclerView; public class AdapterFolder extends RecyclerView.Adapter { private Context context; private LifecycleOwner owner; - private String accountState = null; + private long account; private boolean debug; private List all = new ArrayList<>(); @@ -62,6 +63,7 @@ public class AdapterFolder extends RecyclerView.Adapter 0 && folder.unified ? View.VISIBLE : View.INVISIBLE); - int resid = context.getResources().getIdentifier( - "title_folder_" + folder.type.toLowerCase(), - "string", - context.getPackageName()); - tvType.setText(resid > 0 ? context.getString(resid) : folder.type); + if (account < 0) + tvType.setText(folder.accountName); + else { + int resid = context.getResources().getIdentifier( + "title_folder_" + folder.type.toLowerCase(), + "string", + context.getPackageName()); + tvType.setText(resid > 0 ? context.getString(resid) : folder.type); + } if (folder.account == null) { tvAfter.setText(null); @@ -180,7 +190,7 @@ public class AdapterFolder extends RecyclerView.Adapter folders) { - Log.i(Helper.TAG, "Set folders=" + folders.size()); + public void set(long account, @NonNull List folders) { + Log.i(Helper.TAG, "Set account=" + account + " folders=" + folders.size()); + + this.account = account; final Collator collator = Collator.getInstance(Locale.getDefault()); collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc @@ -396,10 +408,6 @@ public class AdapterFolder extends RecyclerView.Adapter prev; private List next; diff --git a/app/src/main/java/eu/faircode/email/DaoFolder.java b/app/src/main/java/eu/faircode/email/DaoFolder.java index 6e01bfa2e8..c0bec2973f 100644 --- a/app/src/main/java/eu/faircode/email/DaoFolder.java +++ b/app/src/main/java/eu/faircode/email/DaoFolder.java @@ -44,23 +44,26 @@ public interface DaoFolder { " AND type = '" + EntityFolder.USER + "'") List getUserFolders(long account); - @Query("SELECT folder.*, account.name AS accountName" + + @Query("SELECT folder.*, account.name AS accountName, account.color AS accountColor" + ", COUNT(message.id) AS messages" + ", SUM(CASE WHEN message.content = 1 THEN 1 ELSE 0 END) AS content" + ", SUM(CASE WHEN message.ui_seen = 0 THEN 1 ELSE 0 END) AS unseen" + " FROM folder" + " LEFT JOIN account ON account.id = folder.account" + " LEFT JOIN message ON message.folder = folder.id AND NOT message.ui_hide AND NOT message.ui_found" + - " WHERE folder.account = :account OR folder.account IS NULL" + + " WHERE CASE WHEN :account IS NULL" + + " THEN folder.unified AND account.synchronize" + + " ELSE folder.account = :account OR folder.account IS NULL" + + " END" + " GROUP BY folder.id") - LiveData> liveFolders(long account); + LiveData> liveFolders(Long account); @Query("SELECT * FROM folder" + " WHERE (:account < 0 OR folder.account = :account)" + " AND type <> '" + EntityFolder.USER + "'") LiveData> liveSystemFolders(long account); - @Query("SELECT folder.*, account.name AS accountName" + + @Query("SELECT folder.*, account.name AS accountName, account.color AS accountColor" + ", COUNT(message.id) AS messages" + ", SUM(CASE WHEN message.content = 1 THEN 1 ELSE 0 END) AS content" + ", SUM(CASE WHEN message.ui_seen = 0 THEN 1 ELSE 0 END) AS unseen" + @@ -72,7 +75,7 @@ public interface DaoFolder { " GROUP BY folder.id") LiveData> liveUnified(); - @Query("SELECT folder.*, account.name AS accountName" + + @Query("SELECT folder.*, account.name AS accountName, account.color AS accountColor" + ", COUNT(message.id) AS messages" + ", SUM(CASE WHEN message.content = 1 THEN 1 ELSE 0 END) AS content" + ", SUM(CASE WHEN message.ui_seen = 0 THEN 1 ELSE 0 END) AS unseen" + @@ -135,7 +138,13 @@ public interface DaoFolder { ", `sync_days` = :sync_days" + ", `keep_days` = :keep_days" + " WHERE id = :id") - int setFolderProperties(long id, String name, String display, boolean hide, boolean synchronize, boolean unified, int sync_days, int keep_days); + int setFolderProperties( + long id, + String name, String display, + boolean hide, + boolean synchronize, + boolean unified, + int sync_days, int keep_days); @Query("UPDATE folder SET keywords = :keywords WHERE id = :id") int setFolderKeywords(long id, String keywords); diff --git a/app/src/main/java/eu/faircode/email/FragmentFolders.java b/app/src/main/java/eu/faircode/email/FragmentFolders.java index 949cac8dcd..33091305da 100644 --- a/app/src/main/java/eu/faircode/email/FragmentFolders.java +++ b/app/src/main/java/eu/faircode/email/FragmentFolders.java @@ -60,7 +60,7 @@ public class FragmentFolders extends FragmentEx { // Get arguments Bundle args = getArguments(); - account = (args == null ? -1 : args.getLong("account")); + account = args.getLong("account", -1); } @Override @@ -119,6 +119,8 @@ public class FragmentFolders extends FragmentEx { tbShowHidden.setVisibility(View.GONE); grpReady.setVisibility(View.GONE); pbWait.setVisibility(View.VISIBLE); + if (account < 0) + fab.hide(); return view; } @@ -133,16 +135,18 @@ public class FragmentFolders extends FragmentEx { DB db = DB.getInstance(getContext()); // Observe account - db.account().liveAccount(account).observe(getViewLifecycleOwner(), new Observer() { - @Override - public void onChanged(@Nullable EntityAccount account) { - setSubtitle(account == null ? null : account.name); - adapter.setAccountState(account.state); - } - }); + if (account < 0) + setSubtitle(R.string.title_folder_unified); + else + db.account().liveAccount(account).observe(getViewLifecycleOwner(), new Observer() { + @Override + public void onChanged(@Nullable EntityAccount account) { + setSubtitle(account == null ? null : account.name); + } + }); // Observe folders - db.folder().liveFolders(account).observe(getViewLifecycleOwner(), new Observer>() { + db.folder().liveFolders(account < 0 ? null : account).observe(getViewLifecycleOwner(), new Observer>() { @Override public void onChanged(@Nullable List folders) { if (folders == null) { @@ -158,7 +162,7 @@ public class FragmentFolders extends FragmentEx { } tbShowHidden.setVisibility(hidden ? View.VISIBLE : View.GONE); - adapter.set(folders); + adapter.set(account, folders); pbWait.setVisibility(View.GONE); grpReady.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/eu/faircode/email/FragmentOptions.java b/app/src/main/java/eu/faircode/email/FragmentOptions.java index 9c3c51e235..7407768c29 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptions.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptions.java @@ -43,6 +43,7 @@ import androidx.appcompat.widget.SwitchCompat; public class FragmentOptions extends FragmentEx implements SharedPreferences.OnSharedPreferenceChangeListener { private SwitchCompat swEnabled; private SwitchCompat swMetered; + private SwitchCompat swUnified; private SwitchCompat swThreading; private SwitchCompat swCompact; private SwitchCompat swAvatars; @@ -70,6 +71,7 @@ public class FragmentOptions extends FragmentEx implements SharedPreferences.OnS // Get controls swEnabled = view.findViewById(R.id.swEnabled); swMetered = view.findViewById(R.id.swMetered); + swUnified = view.findViewById(R.id.swUnified); swThreading = view.findViewById(R.id.swThreading); swCompact = view.findViewById(R.id.swCompact); swAvatars = view.findViewById(R.id.swAvatars); @@ -109,6 +111,14 @@ public class FragmentOptions extends FragmentEx implements SharedPreferences.OnS } }); + swUnified.setChecked(prefs.getBoolean("unified", true)); + swUnified.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("unified", checked).apply(); + } + }); + swThreading.setChecked(prefs.getBoolean("threading", true)); swThreading.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override diff --git a/app/src/main/java/eu/faircode/email/TupleFolderEx.java b/app/src/main/java/eu/faircode/email/TupleFolderEx.java index 3add2137c4..98ee67d6d4 100644 --- a/app/src/main/java/eu/faircode/email/TupleFolderEx.java +++ b/app/src/main/java/eu/faircode/email/TupleFolderEx.java @@ -21,6 +21,7 @@ package eu.faircode.email; public class TupleFolderEx extends EntityFolder { public String accountName; + public Integer accountColor; public int messages; public int content; public int unseen; @@ -31,6 +32,7 @@ public class TupleFolderEx extends EntityFolder { TupleFolderEx other = (TupleFolderEx) obj; return (super.equals(obj) && (this.accountName == null ? other.accountName == null : accountName.equals(other.accountName)) && + (this.accountColor == null ? other.accountColor == null : this.accountColor.equals(other.accountColor)) && this.messages == other.messages && this.content == other.content && this.unseen == other.unseen); diff --git a/app/src/main/res/layout/fragment_options.xml b/app/src/main/res/layout/fragment_options.xml index 7f7ab42924..3a3b1ee835 100644 --- a/app/src/main/res/layout/fragment_options.xml +++ b/app/src/main/res/layout/fragment_options.xml @@ -29,6 +29,15 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/swEnabled" /> + + + app:layout_constraintTop_toBottomOf="@id/swUnified" /> + + Advanced options Synchronize Use metered connections + Unified inbox Conversation threading Compact message view Show contact photos