mirror of https://github.com/M66B/FairEmail.git
Improved folder collapsing/expanding
This commit is contained in:
parent
afa752328c
commit
3a85a016f8
File diff suppressed because it is too large
Load Diff
|
@ -64,24 +64,25 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
|||
private LifecycleOwner owner;
|
||||
|
||||
private long account;
|
||||
private int level;
|
||||
private EntityFolder parent;
|
||||
private IProperties properties;
|
||||
private boolean debug;
|
||||
private int dp12;
|
||||
private float textSize;
|
||||
private int colorUnread;
|
||||
private int textColorSecondary;
|
||||
|
||||
private List<TupleFolderEx> all = new ArrayList<>();
|
||||
private List<TupleFolderEx> filtered = new ArrayList<>();
|
||||
private List<Long> collapsed = new ArrayList<>();
|
||||
private List<TupleFolderEx> items = new ArrayList<>();
|
||||
|
||||
private static NumberFormat nf = NumberFormat.getNumberInstance();
|
||||
|
||||
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
|
||||
private View view;
|
||||
private View vwColor;
|
||||
private ImageView ivExpander;
|
||||
private View vwLevel;
|
||||
private ImageView ivState;
|
||||
private View vwLevel;
|
||||
private ImageView ivExpander;
|
||||
private ImageView ivNotify;
|
||||
private TextView tvName;
|
||||
private TextView tvMessages;
|
||||
|
@ -109,9 +110,9 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
|||
|
||||
view = itemView.findViewById(R.id.clItem);
|
||||
vwColor = itemView.findViewById(R.id.vwColor);
|
||||
ivExpander = itemView.findViewById(R.id.ivExpander);
|
||||
vwLevel = itemView.findViewById(R.id.vwLevel);
|
||||
ivState = itemView.findViewById(R.id.ivState);
|
||||
vwLevel = itemView.findViewById(R.id.vwLevel);
|
||||
ivExpander = itemView.findViewById(R.id.ivExpander);
|
||||
ivNotify = itemView.findViewById(R.id.ivNotify);
|
||||
tvName = itemView.findViewById(R.id.tvName);
|
||||
tvMessages = itemView.findViewById(R.id.tvMessages);
|
||||
|
@ -128,7 +129,7 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
|||
rvChilds.setLayoutManager(llm);
|
||||
rvChilds.setNestedScrollingEnabled(false);
|
||||
|
||||
childs = new AdapterFolder(context, owner);
|
||||
childs = new AdapterFolder(context, owner, properties);
|
||||
rvChilds.setAdapter(childs);
|
||||
}
|
||||
|
||||
|
@ -144,7 +145,7 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
|||
view.setOnLongClickListener(null);
|
||||
}
|
||||
|
||||
private void bindTo(TupleFolderEx folder) {
|
||||
private void bindTo(final TupleFolderEx folder) {
|
||||
view.setActivated(folder.tbc != null || folder.tbd != null);
|
||||
view.setAlpha(folder.hide ? 0.5f : 1.0f);
|
||||
|
||||
|
@ -154,16 +155,6 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
|||
vwColor.setBackgroundColor(folder.accountColor == null ? Color.TRANSPARENT : folder.accountColor);
|
||||
vwColor.setVisibility(account < 0 ? View.VISIBLE : View.GONE);
|
||||
|
||||
ivExpander.setImageResource(collapsed.contains(folder.id)
|
||||
? R.drawable.baseline_expand_more_24 : R.drawable.baseline_expand_less_24);
|
||||
ivExpander.setVisibility(folder.childs > 0 ? View.VISIBLE : View.INVISIBLE);
|
||||
|
||||
if (account > 0) {
|
||||
ViewGroup.LayoutParams lp = vwLevel.getLayoutParams();
|
||||
lp.width = (EntityFolder.USER.equals(folder.type) ? folder.level : 0) * dp12;
|
||||
vwLevel.setLayoutParams(lp);
|
||||
}
|
||||
|
||||
if (folder.sync_state == null || "requested".equals(folder.sync_state)) {
|
||||
if ("waiting".equals(folder.state))
|
||||
ivState.setImageResource(R.drawable.baseline_hourglass_empty_24);
|
||||
|
@ -189,14 +180,22 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
|||
folder.synchronize || folder.state != null || folder.sync_state != null
|
||||
? View.VISIBLE : View.INVISIBLE);
|
||||
|
||||
ViewGroup.LayoutParams lp = vwLevel.getLayoutParams();
|
||||
lp.width = (account < 0 ? 1 : level) * dp12;
|
||||
vwLevel.setLayoutParams(lp);
|
||||
|
||||
ivExpander.setImageResource(folder.collapsed
|
||||
? R.drawable.baseline_expand_more_24 : R.drawable.baseline_expand_less_24);
|
||||
ivExpander.setVisibility(account < 0 ? View.GONE : (folder.childs > 0 ? View.VISIBLE : View.INVISIBLE));
|
||||
|
||||
ivNotify.setVisibility(folder.notify ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (folder.unseen > 0)
|
||||
tvName.setText(context.getString(R.string.title_name_count,
|
||||
folder.getDisplayName(context),
|
||||
folder.getDisplayName(context, parent),
|
||||
nf.format(folder.unseen)));
|
||||
else
|
||||
tvName.setText(folder.getDisplayName(context));
|
||||
tvName.setText(folder.getDisplayName(context, parent));
|
||||
|
||||
tvName.setTypeface(null, folder.unseen > 0 ? Typeface.BOLD : Typeface.NORMAL);
|
||||
tvName.setTextColor(folder.unseen > 0 ? colorUnread : textColorSecondary);
|
||||
|
@ -219,7 +218,7 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
|||
ivMessages.setImageResource(folder.download || EntityFolder.OUTBOX.equals(folder.type)
|
||||
? R.drawable.baseline_mail_24 : R.drawable.baseline_mail_outline_24);
|
||||
|
||||
ivUnified.setVisibility(account > 0 && folder.unified ? View.VISIBLE : View.INVISIBLE);
|
||||
ivUnified.setVisibility(account > 0 && folder.unified ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (account < 0)
|
||||
tvType.setText(folder.accountName);
|
||||
|
@ -255,20 +254,30 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
|||
tvError.setText(folder.error);
|
||||
tvError.setVisibility(folder.error != null ? View.VISIBLE : View.GONE);
|
||||
|
||||
rvChilds.setVisibility(collapsed.contains(folder.id) ? View.GONE : View.VISIBLE);
|
||||
|
||||
cowner.restart();
|
||||
if (folder.childs > 0) {
|
||||
DB db = DB.getInstance(context);
|
||||
cowner.start();
|
||||
db.folder().liveFolders(folder.account, folder.id).observe(cowner, new Observer<List<TupleFolderEx>>() {
|
||||
@Override
|
||||
public void onChanged(List<TupleFolderEx> folders) {
|
||||
childs.set(account, true, folders);
|
||||
}
|
||||
});
|
||||
} else
|
||||
childs.set(account, true, new ArrayList<TupleFolderEx>());
|
||||
if (account > 0 && folder.childs > 0) {
|
||||
if (folder.collapsed) {
|
||||
rvChilds.setVisibility(View.GONE);
|
||||
childs.set(account, folder, level + 1, new ArrayList<TupleFolderEx>());
|
||||
} else {
|
||||
DB db = DB.getInstance(context);
|
||||
cowner.start();
|
||||
rvChilds.setVisibility(View.VISIBLE);
|
||||
childs.set(folder.account, folder, level + 1, properties.getChilds(folder.id));
|
||||
db.folder().liveFolders(folder.account, folder.id).observe(cowner, new Observer<List<TupleFolderEx>>() {
|
||||
@Override
|
||||
public void onChanged(List<TupleFolderEx> folders) {
|
||||
if (folders == null)
|
||||
folders = new ArrayList<>();
|
||||
properties.setChilds(folder.id, folders);
|
||||
childs.set(account, folder, level + 1, folders);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
rvChilds.setVisibility(View.GONE);
|
||||
childs.set(account, null, 0, new ArrayList<TupleFolderEx>());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -277,24 +286,13 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
|||
if (pos == RecyclerView.NO_POSITION)
|
||||
return;
|
||||
|
||||
TupleFolderEx folder = filtered.get(pos);
|
||||
TupleFolderEx folder = items.get(pos);
|
||||
if (folder.tbd != null)
|
||||
return;
|
||||
|
||||
if (view.getId() == R.id.ivExpander) {
|
||||
if (collapsed.contains(folder.id))
|
||||
collapsed.remove(folder.id);
|
||||
else
|
||||
collapsed.add(folder.id);
|
||||
|
||||
boolean expanded = !collapsed.contains(folder.id);
|
||||
Log.i("Expanded=" + expanded);
|
||||
|
||||
ivExpander.setImageResource(collapsed.contains(folder.id)
|
||||
? R.drawable.baseline_expand_more_24 : R.drawable.baseline_expand_less_24);
|
||||
rvChilds.setVisibility(collapsed.contains(folder.id) ? View.GONE : View.VISIBLE);
|
||||
//notifyItemChanged(pos);
|
||||
} else {
|
||||
if (view.getId() == R.id.ivExpander)
|
||||
onCollapse(folder);
|
||||
else {
|
||||
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
|
||||
lbm.sendBroadcast(
|
||||
new Intent(ActivityView.ACTION_VIEW_MESSAGES)
|
||||
|
@ -303,13 +301,37 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
|||
}
|
||||
}
|
||||
|
||||
private void onCollapse(TupleFolderEx folder) {
|
||||
Bundle args = new Bundle();
|
||||
args.putLong("id", folder.id);
|
||||
args.putBoolean("collapsed", !folder.collapsed);
|
||||
|
||||
new SimpleTask<Void>() {
|
||||
@Override
|
||||
protected Void onExecute(Context context, Bundle args) {
|
||||
long id = args.getLong("id");
|
||||
boolean collapsed = args.getBoolean("collapsed");
|
||||
|
||||
DB db = DB.getInstance(context);
|
||||
db.folder().setFolderCollapsed(id, collapsed);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onException(Bundle args, Throwable ex) {
|
||||
Helper.unexpectedError(context, owner, ex);
|
||||
}
|
||||
}.execute(context, owner, args, "folder:collapse");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
int pos = getAdapterPosition();
|
||||
if (pos == RecyclerView.NO_POSITION)
|
||||
return false;
|
||||
|
||||
final TupleFolderEx folder = filtered.get(pos);
|
||||
final TupleFolderEx folder = items.get(pos);
|
||||
if (folder.tbd != null)
|
||||
return false;
|
||||
|
||||
|
@ -504,10 +526,11 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
|||
}
|
||||
}
|
||||
|
||||
AdapterFolder(Context context, LifecycleOwner owner) {
|
||||
AdapterFolder(Context context, LifecycleOwner owner, IProperties properties) {
|
||||
this.context = context;
|
||||
this.inflater = LayoutInflater.from(context);
|
||||
this.owner = owner;
|
||||
this.properties = properties;
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
boolean compact = prefs.getBoolean("compact", false);
|
||||
|
@ -525,14 +548,12 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
|||
setHasStableIds(true);
|
||||
}
|
||||
|
||||
void showHidden(boolean show) {
|
||||
set(account, show, all);
|
||||
}
|
||||
|
||||
public void set(final long account, boolean showAll, @NonNull List<TupleFolderEx> folders) {
|
||||
public void set(final long account, EntityFolder parent, int level, @NonNull List<TupleFolderEx> folders) {
|
||||
Log.i("Set account=" + account + " folders=" + folders.size());
|
||||
|
||||
this.account = account;
|
||||
this.parent = parent;
|
||||
this.level = level;
|
||||
|
||||
final Collator collator = Collator.getInstance(Locale.getDefault());
|
||||
collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc
|
||||
|
@ -569,18 +590,9 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
|||
}
|
||||
});
|
||||
|
||||
all.clear();
|
||||
for (EntityFolder folder : folders)
|
||||
all.add((TupleFolderEx) folder);
|
||||
DiffUtil.DiffResult diff = DiffUtil.calculateDiff(new DiffCallback(items, folders), false);
|
||||
|
||||
List<TupleFolderEx> shown = new ArrayList<>();
|
||||
for (EntityFolder folder : folders)
|
||||
if (!folder.hide || showAll)
|
||||
shown.add((TupleFolderEx) folder);
|
||||
|
||||
DiffUtil.DiffResult diff = DiffUtil.calculateDiff(new DiffCallback(filtered, shown), false);
|
||||
|
||||
filtered = shown;
|
||||
items = folders;
|
||||
|
||||
diff.dispatchUpdatesTo(new ListUpdateCallback() {
|
||||
@Override
|
||||
|
@ -642,12 +654,12 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
|||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return filtered.get(position).id;
|
||||
return items.get(position).id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return filtered.size();
|
||||
return items.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -660,9 +672,15 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
|
|||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
holder.unwire();
|
||||
|
||||
TupleFolderEx folder = filtered.get(position);
|
||||
TupleFolderEx folder = items.get(position);
|
||||
holder.bindTo(folder);
|
||||
|
||||
holder.wire();
|
||||
}
|
||||
|
||||
interface IProperties {
|
||||
void setChilds(long parent, List<TupleFolderEx> childs);
|
||||
|
||||
List<TupleFolderEx> getChilds(long parent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -755,7 +755,6 @@ class Core {
|
|||
if (type != null) {
|
||||
names.remove(fullName);
|
||||
|
||||
int level = EntityFolder.getLevel(separator, fullName);
|
||||
String display = null;
|
||||
if (account.prefix != null && fullName.startsWith(account.prefix + separator))
|
||||
display = fullName.substring(account.prefix.length() + 1);
|
||||
|
@ -767,7 +766,6 @@ class Core {
|
|||
folder.name = fullName;
|
||||
folder.display = display;
|
||||
folder.type = (EntityFolder.SYSTEM.equals(type) ? type : EntityFolder.USER);
|
||||
folder.level = level;
|
||||
folder.synchronize = false;
|
||||
folder.poll = ("imap.gmail.com".equals(account.host));
|
||||
folder.sync_days = EntityFolder.DEFAULT_SYNC;
|
||||
|
@ -791,8 +789,6 @@ class Core {
|
|||
}
|
||||
}
|
||||
|
||||
db.folder().setFolderLevel(folder.id, level);
|
||||
|
||||
// Compatibility
|
||||
if ("Inbox_sub".equals(folder.type))
|
||||
db.folder().setFolderType(folder.id, EntityFolder.USER);
|
||||
|
|
|
@ -50,7 +50,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
|
|||
// https://developer.android.com/topic/libraries/architecture/room.html
|
||||
|
||||
@Database(
|
||||
version = 60,
|
||||
version = 61,
|
||||
entities = {
|
||||
EntityIdentity.class,
|
||||
EntityAccount.class,
|
||||
|
@ -662,6 +662,13 @@ public abstract class DB extends RoomDatabase {
|
|||
db.execSQL("ALTER TABLE `folder` ADD COLUMN `parent` INTEGER");
|
||||
}
|
||||
})
|
||||
.addMigrations(new Migration(60, 61) {
|
||||
@Override
|
||||
public void migrate(SupportSQLiteDatabase db) {
|
||||
Log.i("DB migration from version " + startVersion + " to " + endVersion);
|
||||
db.execSQL("ALTER TABLE `folder` ADD COLUMN `collapsed` INTEGER NOT NULL DEFAULT 0");
|
||||
}
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -159,12 +159,12 @@ public interface DaoFolder {
|
|||
@Query("UPDATE folder SET display = :display WHERE id = :id")
|
||||
int setFolderDisplay(long id, String display);
|
||||
|
||||
@Query("UPDATE folder SET level = :level WHERE id = :id")
|
||||
int setFolderLevel(long id, int level);
|
||||
|
||||
@Query("UPDATE folder SET parent = :parent WHERE id = :id")
|
||||
int setFolderParent(long id, Long parent);
|
||||
|
||||
@Query("UPDATE folder SET collapsed = :collapsed WHERE id = :id")
|
||||
int setFolderCollapsed(long id, boolean collapsed);
|
||||
|
||||
@Query("UPDATE folder" +
|
||||
" SET type = '" + EntityFolder.USER + "'" +
|
||||
" WHERE account = :account" +
|
||||
|
|
|
@ -69,7 +69,7 @@ public class EntityFolder implements Serializable {
|
|||
@NonNull
|
||||
public String type;
|
||||
@NonNull
|
||||
public Integer level;
|
||||
public Integer level = 0; // obsolete
|
||||
@NonNull
|
||||
public Boolean synchronize;
|
||||
@NonNull
|
||||
|
@ -84,6 +84,8 @@ public class EntityFolder implements Serializable {
|
|||
@NonNull
|
||||
public Boolean hide = false;
|
||||
@NonNull
|
||||
public Boolean collapsed = false;
|
||||
@NonNull
|
||||
public Boolean unified = false;
|
||||
@NonNull
|
||||
public Boolean notify = false;
|
||||
|
@ -200,6 +202,13 @@ public class EntityFolder implements Serializable {
|
|||
return (display == null ? Helper.localizeFolderName(context, name) : display);
|
||||
}
|
||||
|
||||
String getDisplayName(Context context, EntityFolder parent) {
|
||||
String n = name;
|
||||
if (parent != null && name.startsWith(parent.name))
|
||||
n = n.substring(parent.name.length() + 1);
|
||||
return (display == null ? Helper.localizeFolderName(context, n) : display);
|
||||
}
|
||||
|
||||
boolean isOutgoing() {
|
||||
return isOutgoing(this.type);
|
||||
}
|
||||
|
@ -227,19 +236,6 @@ public class EntityFolder implements Serializable {
|
|||
return USER;
|
||||
}
|
||||
|
||||
static int getLevel(Character separator, String name) {
|
||||
int level = 0;
|
||||
if (separator != null) {
|
||||
for (int i = 0; i < name.length(); i++)
|
||||
if (name.charAt(i) == separator)
|
||||
level++;
|
||||
if (name.startsWith("INBOX" + separator))
|
||||
level--;
|
||||
}
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
String getParentName(Character separator) {
|
||||
if (separator == null)
|
||||
return null;
|
||||
|
@ -250,7 +246,6 @@ public class EntityFolder implements Serializable {
|
|||
else
|
||||
return name.substring(0, p);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -261,7 +256,6 @@ public class EntityFolder implements Serializable {
|
|||
Objects.equals(this.account, other.account) &&
|
||||
this.name.equals(other.name) &&
|
||||
this.type.equals(other.type) &&
|
||||
this.level.equals(other.level) &&
|
||||
this.synchronize.equals(other.synchronize) &&
|
||||
this.poll.equals(other.poll) &&
|
||||
this.download.equals(other.download) &&
|
||||
|
@ -269,6 +263,7 @@ public class EntityFolder implements Serializable {
|
|||
this.keep_days.equals(other.keep_days) &&
|
||||
Objects.equals(this.display, other.display) &&
|
||||
this.hide == other.hide &&
|
||||
this.collapsed == other.collapsed &&
|
||||
this.unified == other.unified &&
|
||||
this.notify == other.notify &&
|
||||
Objects.equals(this.total, other.total) &&
|
||||
|
@ -292,7 +287,6 @@ public class EntityFolder implements Serializable {
|
|||
json.put("id", id);
|
||||
json.put("name", name);
|
||||
json.put("type", type);
|
||||
json.put("level", level);
|
||||
json.put("synchronize", synchronize);
|
||||
json.put("poll", poll);
|
||||
json.put("download", download);
|
||||
|
@ -300,6 +294,7 @@ public class EntityFolder implements Serializable {
|
|||
json.put("keep_days", keep_days);
|
||||
json.put("display", display);
|
||||
json.put("hide", hide);
|
||||
json.put("collapsed", collapsed);
|
||||
json.put("unified", unified);
|
||||
json.put("notify", notify);
|
||||
return json;
|
||||
|
@ -313,11 +308,6 @@ public class EntityFolder implements Serializable {
|
|||
folder.name = json.getString("name");
|
||||
folder.type = json.getString("type");
|
||||
|
||||
if (json.has("level"))
|
||||
folder.level = json.getInt("level");
|
||||
else
|
||||
folder.level = 0;
|
||||
|
||||
folder.synchronize = json.getBoolean("synchronize");
|
||||
|
||||
if (json.has("poll"))
|
||||
|
@ -341,6 +331,8 @@ public class EntityFolder implements Serializable {
|
|||
|
||||
if (json.has("hide"))
|
||||
folder.hide = json.getBoolean("hide");
|
||||
if (json.has("collapsed"))
|
||||
folder.collapsed = json.getBoolean("collapsed");
|
||||
|
||||
folder.unified = json.getBoolean("unified");
|
||||
|
||||
|
|
|
@ -1013,7 +1013,6 @@ public class FragmentAccount extends FragmentBase {
|
|||
db.folder().setFoldersUser(account.id);
|
||||
|
||||
for (EntityFolder folder : folders) {
|
||||
folder.level = EntityFolder.getLevel(separator, folder.name);
|
||||
if (account.prefix != null && folder.name.startsWith(account.prefix + separator))
|
||||
folder.display = folder.name.substring(account.prefix.length() + 1);
|
||||
|
||||
|
@ -1025,7 +1024,6 @@ public class FragmentAccount extends FragmentBase {
|
|||
} else {
|
||||
EntityLog.log(context, "Updated folder=" + folder.name + " type=" + folder.type);
|
||||
db.folder().setFolderType(existing.id, folder.type);
|
||||
db.folder().setFolderLevel(existing.id, folder.level);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -213,7 +213,6 @@ public class FragmentFolder extends FragmentBase {
|
|||
EntityFolder create = new EntityFolder();
|
||||
create.account = aid;
|
||||
create.name = name;
|
||||
create.level = 0;
|
||||
create.display = display;
|
||||
create.hide = hide;
|
||||
create.type = EntityFolder.USER;
|
||||
|
|
|
@ -24,6 +24,7 @@ import android.content.Intent;
|
|||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.util.LongSparseArray;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
|
@ -35,6 +36,7 @@ import android.widget.ImageButton;
|
|||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -65,7 +67,7 @@ public class FragmentFolders extends FragmentBase {
|
|||
private boolean searching = false;
|
||||
private AdapterFolder adapter;
|
||||
|
||||
private Boolean show_hidden = null;
|
||||
private static LongSparseArray<List<TupleFolderEx>> parentChilds = new LongSparseArray<>();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -128,7 +130,18 @@ public class FragmentFolders extends FragmentBase {
|
|||
LinearLayoutManager llm = new LinearLayoutManager(getContext());
|
||||
rvFolder.setLayoutManager(llm);
|
||||
|
||||
adapter = new AdapterFolder(getContext(), getViewLifecycleOwner());
|
||||
adapter = new AdapterFolder(getContext(), getViewLifecycleOwner(), new AdapterFolder.IProperties() {
|
||||
@Override
|
||||
public void setChilds(long parent, List<TupleFolderEx> childs) {
|
||||
parentChilds.put(parent, childs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TupleFolderEx> getChilds(long parent) {
|
||||
List<TupleFolderEx> childs = parentChilds.get(parent);
|
||||
return (childs == null ? new ArrayList<TupleFolderEx>() : childs);
|
||||
}
|
||||
});
|
||||
rvFolder.setAdapter(adapter);
|
||||
|
||||
fab.setOnClickListener(new View.OnClickListener() {
|
||||
|
@ -188,22 +201,10 @@ public class FragmentFolders extends FragmentBase {
|
|||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
if (show_hidden != null)
|
||||
outState.putBoolean("fair:show_hidden", show_hidden);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
show_hidden = (Boolean) savedInstanceState.get("fair:show_hidden");
|
||||
getActivity().invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
|
||||
grpHintActions.setVisibility(prefs.getBoolean("folder_actions", false) ? View.GONE : View.VISIBLE);
|
||||
grpHintSync.setVisibility(prefs.getBoolean("folder_sync", false) ? View.GONE : View.VISIBLE);
|
||||
|
@ -247,26 +248,7 @@ public class FragmentFolders extends FragmentBase {
|
|||
return;
|
||||
}
|
||||
|
||||
boolean has_hidden = false;
|
||||
for (TupleFolderEx folder : folders)
|
||||
if (folder.hide) {
|
||||
has_hidden = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (has_hidden) {
|
||||
if (show_hidden == null) {
|
||||
show_hidden = false;
|
||||
getActivity().invalidateOptionsMenu();
|
||||
}
|
||||
} else {
|
||||
if (show_hidden != null) {
|
||||
show_hidden = null;
|
||||
getActivity().invalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
|
||||
adapter.set(account, show_hidden == null || show_hidden, folders);
|
||||
adapter.set(account, null, 0, folders);
|
||||
|
||||
pbWait.setVisibility(View.GONE);
|
||||
grpReady.setVisibility(View.VISIBLE);
|
||||
|
@ -368,38 +350,4 @@ public class FragmentFolders extends FragmentBase {
|
|||
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(Menu menu) {
|
||||
menu.findItem(R.id.menu_search).setVisible(account < 0);
|
||||
|
||||
MenuItem item = menu.findItem(R.id.menu_show_hidden);
|
||||
if (show_hidden != null) {
|
||||
item.setTitle(show_hidden ? R.string.title_hide_folders : R.string.title_show_folders);
|
||||
item.setIcon(show_hidden ? R.drawable.baseline_visibility_off_24 : R.drawable.baseline_visibility_24);
|
||||
}
|
||||
item.setVisible(show_hidden != null);
|
||||
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_show_hidden:
|
||||
onMenuShowHidden();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void onMenuShowHidden() {
|
||||
if (show_hidden == null)
|
||||
show_hidden = false;
|
||||
else
|
||||
show_hidden = !show_hidden;
|
||||
getActivity().invalidateOptionsMenu();
|
||||
adapter.showHidden(show_hidden);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -286,7 +286,6 @@ public class FragmentQuickSetup extends FragmentBase {
|
|||
EntityFolder folder = new EntityFolder();
|
||||
folder.name = fullName;
|
||||
folder.type = type;
|
||||
folder.level = EntityFolder.getLevel(separator, folder.name);
|
||||
folder.synchronize = (sync >= 0);
|
||||
folder.download = (sync < 0 ? true : EntityFolder.SYSTEM_FOLDER_DOWNLOAD.get(sync));
|
||||
folder.sync_days = EntityFolder.DEFAULT_SYNC;
|
||||
|
|
|
@ -239,7 +239,6 @@ public class FragmentSetup extends FragmentBase {
|
|||
outbox = new EntityFolder();
|
||||
outbox.name = "OUTBOX";
|
||||
outbox.type = EntityFolder.OUTBOX;
|
||||
outbox.level = 0;
|
||||
outbox.synchronize = false;
|
||||
outbox.sync_days = 0;
|
||||
outbox.keep_days = 0;
|
||||
|
|
|
@ -20,41 +20,16 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivExpander"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:paddingStart="6dp"
|
||||
android:paddingEnd="6dp"
|
||||
android:src="@drawable/baseline_expand_less_24"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintBottom_toTopOf="@+id/vSeparator"
|
||||
app:layout_constraintStart_toEndOf="@+id/vwColor"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivState"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:src="@drawable/baseline_cloud_off_24"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tvName"
|
||||
app:layout_constraintStart_toEndOf="@id/ivExpander"
|
||||
app:layout_constraintStart_toEndOf="@id/vwColor"
|
||||
app:layout_constraintTop_toTopOf="@+id/tvName" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivUnified"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:src="@drawable/baseline_folder_special_24"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tvType"
|
||||
app:layout_constraintStart_toEndOf="@id/ivExpander"
|
||||
app:layout_constraintTop_toTopOf="@+id/tvType" />
|
||||
|
||||
<View
|
||||
android:id="@+id/vwLevel"
|
||||
android:layout_width="0dp"
|
||||
|
@ -64,20 +39,42 @@
|
|||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivNotify"
|
||||
android:layout_width="24dp"
|
||||
android:id="@+id/ivExpander"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:src="@drawable/baseline_expand_less_24"
|
||||
app:layout_constraintBottom_toTopOf="@+id/vSeparator"
|
||||
app:layout_constraintStart_toEndOf="@+id/vwLevel"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivUnified"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:paddingEnd="6dp"
|
||||
android:src="@drawable/baseline_folder_special_24"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tvType"
|
||||
app:layout_constraintStart_toEndOf="@id/ivExpander"
|
||||
app:layout_constraintTop_toTopOf="@+id/tvType" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivNotify"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="24dp"
|
||||
android:paddingEnd="6dp"
|
||||
android:src="@drawable/baseline_notifications_24"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tvName"
|
||||
app:layout_constraintStart_toEndOf="@id/vwLevel"
|
||||
app:layout_constraintStart_toEndOf="@id/ivExpander"
|
||||
app:layout_constraintTop_toTopOf="@+id/tvName" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvName"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:ellipsize="end"
|
||||
|
@ -116,7 +113,6 @@
|
|||
android:id="@+id/tvType"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:gravity="center_vertical"
|
||||
|
@ -125,7 +121,7 @@
|
|||
android:textAppearance="@android:style/TextAppearance.Small"
|
||||
android:textStyle="italic"
|
||||
app:layout_constraintEnd_toStartOf="@+id/tvAfter"
|
||||
app:layout_constraintStart_toEndOf="@id/vwLevel"
|
||||
app:layout_constraintStart_toEndOf="@id/ivUnified"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvName" />
|
||||
|
||||
<TextView
|
||||
|
@ -154,21 +150,19 @@
|
|||
android:id="@+id/tvKeywords"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:gravity="center_vertical"
|
||||
android:text="Keywords"
|
||||
android:textAppearance="@android:style/TextAppearance.Small"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/vwLevel"
|
||||
app:layout_constraintStart_toEndOf="@id/ivExpander"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvType" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvError"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="error"
|
||||
|
|
|
@ -8,10 +8,4 @@
|
|||
android:title="@string/title_search"
|
||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||
app:showAsAction="collapseActionView|always" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_show_hidden"
|
||||
android:icon="@drawable/baseline_visibility_24"
|
||||
android:title="@string/title_show_folders"
|
||||
app:showAsAction="always" />
|
||||
</menu>
|
||||
|
|
|
@ -289,9 +289,7 @@
|
|||
|
||||
<string name="title_folder_name">Folder name</string>
|
||||
<string name="title_display_name">Display name</string>
|
||||
<string name="title_hide_folders">Hide hidden folders</string>
|
||||
<string name="title_show_folders">Show hidden folders</string>
|
||||
<string name="title_hide_folder">Hide from list</string>
|
||||
<string name="title_hide_folder">Hide from menus</string>
|
||||
<string name="title_unified_folder">Show in unified inbox</string>
|
||||
<string name="title_synchronize_folder">Synchronize (receive messages)</string>
|
||||
<string name="title_poll_folder">Check periodically instead of continuous synchronize</string>
|
||||
|
|
Loading…
Reference in New Issue