Added folder colors

pull/162/head
M66B 5 years ago
parent 7057cdaf18
commit 0f133e9bed

File diff suppressed because it is too large Load Diff

@ -184,8 +184,8 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
tvName.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); tvName.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
if (listener == null) { if (listener == null) {
vwColor.setBackgroundColor(folder.accountColor == null ? Color.TRANSPARENT : folder.accountColor); vwColor.setBackgroundColor(folder.color == null ? Color.TRANSPARENT : folder.color);
vwColor.setVisibility(account < 0 && ActivityBilling.isPro(context) ? View.VISIBLE : View.GONE); vwColor.setVisibility(ActivityBilling.isPro(context) ? View.VISIBLE : View.GONE);
if (folder.sync_state == null || "requested".equals(folder.sync_state)) { if (folder.sync_state == null || "requested".equals(folder.sync_state)) {
if (folder.executing > 0) if (folder.executing > 0)

@ -106,10 +106,10 @@ public class AdapterNavFolder extends RecyclerView.Adapter<AdapterNavFolder.View
? R.drawable.baseline_folder_24 ? R.drawable.baseline_folder_24
: R.drawable.baseline_folder_open_24); : R.drawable.baseline_folder_open_24);
if (folder.accountColor == null || !ActivityBilling.isPro(context)) if (folder.color == null || !ActivityBilling.isPro(context))
ivItem.clearColorFilter(); ivItem.clearColorFilter();
else else
ivItem.setColorFilter(folder.accountColor); ivItem.setColorFilter(folder.color);
} }
int count = (EntityFolder.OUTBOX.equals(folder.type) ? folder.snoozed + folder.operations : folder.unseen); int count = (EntityFolder.OUTBOX.equals(folder.type) ? folder.snoozed + folder.operations : folder.unseen);
@ -232,7 +232,6 @@ public class AdapterNavFolder extends RecyclerView.Adapter<AdapterNavFolder.View
return (f1.name.equals(f2.name) && return (f1.name.equals(f2.name) &&
f1.type.equals(f2.type) && f1.type.equals(f2.type) &&
Objects.equals(f1.display, f2.display) && Objects.equals(f1.display, f2.display) &&
Objects.equals(f1.accountColor, f2.accountColor) &&
Objects.equals(f1.state, f2.state) && Objects.equals(f1.state, f2.state) &&
Objects.equals(f1.sync_state, f2.sync_state) && Objects.equals(f1.sync_state, f2.sync_state) &&
Objects.equals(f1.last_sync, f2.last_sync) && Objects.equals(f1.last_sync, f2.last_sync) &&

@ -58,7 +58,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
// https://developer.android.com/topic/libraries/architecture/room.html // https://developer.android.com/topic/libraries/architecture/room.html
@Database( @Database(
version = 107, version = 108,
entities = { entities = {
EntityIdentity.class, EntityIdentity.class,
EntityAccount.class, EntityAccount.class,
@ -1056,6 +1056,13 @@ public abstract class DB extends RoomDatabase {
db.execSQL("ALTER TABLE `message` ADD COLUMN `receipt` INTEGER"); db.execSQL("ALTER TABLE `message` ADD COLUMN `receipt` INTEGER");
} }
}) })
.addMigrations(new Migration(107, 108) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {
Log.i("DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `folder` ADD COLUMN `color` INTEGER");
}
})
.build(); .build();
} }

@ -36,7 +36,7 @@ public interface DaoFolder {
@Query("SELECT folder.*" + @Query("SELECT folder.*" +
", account.id AS accountId, account.pop AS accountPop, account.`order` AS accountOrder" + ", account.id AS accountId, account.pop AS accountPop, account.`order` AS accountOrder" +
", account.name AS accountName, account.color AS accountColor, account.state AS accountState" + ", account.name AS accountName, account.state AS accountState" +
", COUNT(DISTINCT CASE WHEN rule.enabled THEN rule.id ELSE NULL END) rules" + ", COUNT(DISTINCT CASE WHEN rule.enabled THEN rule.id ELSE NULL END) rules" +
", COUNT(DISTINCT CASE WHEN message.ui_hide THEN NULL ELSE message.id END) AS messages" + ", COUNT(DISTINCT CASE WHEN message.ui_hide THEN NULL ELSE message.id END) AS messages" +
", COUNT(DISTINCT CASE WHEN message.content = 1 AND NOT message.ui_hide THEN message.id ELSE NULL END) AS content" + ", COUNT(DISTINCT CASE WHEN message.content = 1 AND NOT message.ui_hide THEN message.id ELSE NULL END) AS content" +
@ -73,7 +73,7 @@ public interface DaoFolder {
@Query("SELECT folder.*" + @Query("SELECT folder.*" +
", account.id AS accountId, account.pop AS accountPop, account.`order` AS accountOrder" + ", account.id AS accountId, account.pop AS accountPop, account.`order` AS accountOrder" +
", account.name AS accountName, account.color AS accountColor, account.state AS accountState" + ", account.name AS accountName, account.state AS accountState" +
", COUNT(DISTINCT CASE WHEN rule.enabled THEN rule.id ELSE NULL END) rules" + ", COUNT(DISTINCT CASE WHEN rule.enabled THEN rule.id ELSE NULL END) rules" +
", COUNT(DISTINCT CASE WHEN message.ui_hide THEN NULL ELSE message.id END) AS messages" + ", COUNT(DISTINCT CASE WHEN message.ui_hide THEN NULL ELSE message.id END) AS messages" +
", COUNT(DISTINCT CASE WHEN message.content = 1 AND NOT message.ui_hide THEN message.id ELSE NULL END) AS content" + ", COUNT(DISTINCT CASE WHEN message.content = 1 AND NOT message.ui_hide THEN message.id ELSE NULL END) AS content" +
@ -93,7 +93,7 @@ public interface DaoFolder {
@Query("SELECT folder.*" + @Query("SELECT folder.*" +
", account.id AS accountId, account.pop AS accountPop, account.`order` AS accountOrder" + ", account.id AS accountId, account.pop AS accountPop, account.`order` AS accountOrder" +
", account.name AS accountName, account.color AS accountColor, account.state AS accountState" + ", account.name AS accountName, account.state AS accountState" +
", COUNT(DISTINCT CASE WHEN rule.enabled THEN rule.id ELSE NULL END) rules" + ", COUNT(DISTINCT CASE WHEN rule.enabled THEN rule.id ELSE NULL END) rules" +
", COUNT(DISTINCT CASE WHEN message.ui_hide THEN NULL ELSE message.id END) AS messages" + ", COUNT(DISTINCT CASE WHEN message.ui_hide THEN NULL ELSE message.id END) AS messages" +
", COUNT(DISTINCT CASE WHEN message.content = 1 AND NOT message.ui_hide THEN message.id ELSE NULL END) AS content" + ", COUNT(DISTINCT CASE WHEN message.content = 1 AND NOT message.ui_hide THEN message.id ELSE NULL END) AS content" +
@ -110,7 +110,7 @@ public interface DaoFolder {
LiveData<List<TupleFolderEx>> liveUnified(String type); LiveData<List<TupleFolderEx>> liveUnified(String type);
@Query("SELECT folder.*" + @Query("SELECT folder.*" +
", account.`order` AS accountOrder, account.name AS accountName, account.color AS accountColor" + ", account.`order` AS accountOrder, account.name AS accountName" +
", SUM(CASE WHEN NOT message.ui_seen THEN 1 ELSE 0 END) AS unseen" + ", SUM(CASE WHEN NOT message.ui_seen THEN 1 ELSE 0 END) AS unseen" +
", SUM(CASE WHEN message.ui_snoozed IS NULL THEN 0 ELSE 1 END) AS snoozed" + ", SUM(CASE WHEN message.ui_snoozed IS NULL THEN 0 ELSE 1 END) AS snoozed" +
", (SELECT COUNT(operation.id) FROM operation WHERE operation.folder = folder.id) AS operations" + ", (SELECT COUNT(operation.id) FROM operation WHERE operation.folder = folder.id) AS operations" +
@ -130,7 +130,7 @@ public interface DaoFolder {
@Query("SELECT folder.*" + @Query("SELECT folder.*" +
", account.id AS accountId, account.pop AS accountPop, account.`order` AS accountOrder" + ", account.id AS accountId, account.pop AS accountPop, account.`order` AS accountOrder" +
", account.name AS accountName, account.color AS accountColor, account.state AS accountState" + ", account.name AS accountName, account.state AS accountState" +
", COUNT(DISTINCT CASE WHEN rule.enabled THEN rule.id ELSE NULL END) rules" + ", COUNT(DISTINCT CASE WHEN rule.enabled THEN rule.id ELSE NULL END) rules" +
", COUNT(DISTINCT CASE WHEN message.ui_hide THEN NULL ELSE message.id END) AS messages" + ", COUNT(DISTINCT CASE WHEN message.ui_hide THEN NULL ELSE message.id END) AS messages" +
", COUNT(DISTINCT CASE WHEN message.content = 1 AND NOT message.ui_hide THEN message.id ELSE NULL END) AS content" + ", COUNT(DISTINCT CASE WHEN message.content = 1 AND NOT message.ui_hide THEN message.id ELSE NULL END) AS content" +
@ -245,6 +245,7 @@ public interface DaoFolder {
@Query("UPDATE folder" + @Query("UPDATE folder" +
" SET `rename` = :rename" + " SET `rename` = :rename" +
", display = :display" + ", display = :display" +
", color = :color" +
", unified = :unified" + ", unified = :unified" +
", navigation = :navigation" + ", navigation = :navigation" +
", notify = :notify" + ", notify = :notify" +
@ -258,7 +259,7 @@ public interface DaoFolder {
" WHERE id = :id") " WHERE id = :id")
int setFolderProperties( int setFolderProperties(
long id, String rename, long id, String rename,
String display, boolean unified, boolean navigation, boolean notify, boolean hide, String display, Integer color, boolean unified, boolean navigation, boolean notify, boolean hide,
boolean synchronize, boolean poll, boolean download, boolean synchronize, boolean poll, boolean download,
int sync_days, int keep_days, boolean auto_delete); int sync_days, int keep_days, boolean auto_delete);

@ -87,6 +87,7 @@ public class EntityFolder extends EntityOrder implements Serializable {
@NonNull @NonNull
public Boolean auto_delete = false; public Boolean auto_delete = false;
public String display; public String display;
public Integer color;
@NonNull @NonNull
public Boolean hide = false; public Boolean hide = false;
@NonNull @NonNull
@ -339,6 +340,7 @@ public class EntityFolder extends EntityOrder implements Serializable {
this.keep_days.equals(other.keep_days) && this.keep_days.equals(other.keep_days) &&
this.auto_delete.equals(other.auto_delete) && this.auto_delete.equals(other.auto_delete) &&
Objects.equals(this.display, other.display) && Objects.equals(this.display, other.display) &&
Objects.equals(this.color, other.color) &&
Objects.equals(this.order, other.order) && Objects.equals(this.order, other.order) &&
this.hide == other.hide && this.hide == other.hide &&
this.collapsed == other.collapsed && this.collapsed == other.collapsed &&
@ -349,8 +351,8 @@ public class EntityFolder extends EntityOrder implements Serializable {
Helper.equal(this.keywords, other.keywords) && Helper.equal(this.keywords, other.keywords) &&
this.initialize.equals(other.initialize) && this.initialize.equals(other.initialize) &&
Objects.equals(this.tbc, other.tbc) && Objects.equals(this.tbc, other.tbc) &&
Objects.equals(this.rename, other.rename) &&
Objects.equals(this.tbd, other.tbd) && Objects.equals(this.tbd, other.tbd) &&
Objects.equals(this.rename, other.rename) &&
Objects.equals(this.state, other.state) && Objects.equals(this.state, other.state) &&
Objects.equals(this.sync_state, other.sync_state) && Objects.equals(this.sync_state, other.sync_state) &&
this.read_only == other.read_only && this.read_only == other.read_only &&
@ -379,6 +381,7 @@ public class EntityFolder extends EntityOrder implements Serializable {
json.put("keep_days", keep_days); json.put("keep_days", keep_days);
json.put("auto_delete", auto_delete); json.put("auto_delete", auto_delete);
json.put("display", display); json.put("display", display);
json.put("color", color);
json.put("hide", hide); json.put("hide", hide);
json.put("collapsed", collapsed); json.put("collapsed", collapsed);
json.put("unified", unified); json.put("unified", unified);
@ -422,6 +425,9 @@ public class EntityFolder extends EntityOrder implements Serializable {
if (json.has("display") && !json.isNull("display")) if (json.has("display") && !json.isNull("display"))
folder.display = json.getString("display"); folder.display = json.getString("display");
if (json.has("color") && !json.isNull("color"))
folder.color = json.getInt("color");
if (json.has("hide")) if (json.has("hide"))
folder.hide = json.getBoolean("hide"); folder.hide = json.getBoolean("hide");

@ -21,6 +21,7 @@ package eu.faircode.email;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.text.TextUtils; import android.text.TextUtils;
@ -55,6 +56,7 @@ public class FragmentFolder extends FragmentBase {
private TextView tvParent; private TextView tvParent;
private EditText etName; private EditText etName;
private EditText etDisplay; private EditText etDisplay;
private ViewButtonColor btnColor;
private CheckBox cbHide; private CheckBox cbHide;
private CheckBox cbUnified; private CheckBox cbUnified;
private CheckBox cbNavigation; private CheckBox cbNavigation;
@ -78,6 +80,7 @@ public class FragmentFolder extends FragmentBase {
private boolean saving = false; private boolean saving = false;
private boolean deletable = false; private boolean deletable = false;
private static final int REQUEST_COLOR = 1;
private static final int REQUEST_SAVE_CHANGES = 101; private static final int REQUEST_SAVE_CHANGES = 101;
private static final int REQUEST_DELETE_FOLDER = 102; private static final int REQUEST_DELETE_FOLDER = 102;
@ -105,6 +108,7 @@ public class FragmentFolder extends FragmentBase {
etName = view.findViewById(R.id.etName); etName = view.findViewById(R.id.etName);
tvParent = view.findViewById(R.id.tvParent); tvParent = view.findViewById(R.id.tvParent);
etDisplay = view.findViewById(R.id.etDisplay); etDisplay = view.findViewById(R.id.etDisplay);
btnColor = view.findViewById(R.id.btnColor);
cbHide = view.findViewById(R.id.cbHide); cbHide = view.findViewById(R.id.cbHide);
cbUnified = view.findViewById(R.id.cbUnified); cbUnified = view.findViewById(R.id.cbUnified);
cbNavigation = view.findViewById(R.id.cbNavigation); cbNavigation = view.findViewById(R.id.cbNavigation);
@ -122,6 +126,21 @@ public class FragmentFolder extends FragmentBase {
pbWait = view.findViewById(R.id.pbWait); pbWait = view.findViewById(R.id.pbWait);
grpParent = view.findViewById(R.id.grpParent); grpParent = view.findViewById(R.id.grpParent);
btnColor.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bundle args = new Bundle();
args.putInt("color", btnColor.getColor());
args.putString("title", getString(R.string.title_color));
args.putBoolean("reset", true);
FragmentDialogColor fragment = new FragmentDialogColor();
fragment.setArguments(args);
fragment.setTargetFragment(FragmentFolder.this, REQUEST_COLOR);
fragment.show(getFragmentManager(), "account:color");
}
});
cbSynchronize.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { cbSynchronize.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
@ -192,6 +211,7 @@ public class FragmentFolder extends FragmentBase {
etName.setText(folder == null ? null : folder.name); etName.setText(folder == null ? null : folder.name);
etDisplay.setText(folder == null ? null : folder.display); etDisplay.setText(folder == null ? null : folder.display);
etDisplay.setHint(folder == null ? null : Helper.localizeFolderName(getContext(), folder.name)); etDisplay.setHint(folder == null ? null : Helper.localizeFolderName(getContext(), folder.name));
btnColor.setColor(folder == null ? null : folder.color);
cbHide.setChecked(folder == null ? false : folder.hide); cbHide.setChecked(folder == null ? false : folder.hide);
cbUnified.setChecked(folder == null ? false : folder.unified); cbUnified.setChecked(folder == null ? false : folder.unified);
cbNavigation.setChecked(folder == null ? false : folder.navigation); cbNavigation.setChecked(folder == null ? false : folder.navigation);
@ -244,6 +264,15 @@ public class FragmentFolder extends FragmentBase {
try { try {
switch (requestCode) { switch (requestCode) {
case REQUEST_COLOR:
if (resultCode == RESULT_OK && data != null) {
if (ActivityBilling.isPro(getContext())) {
Bundle args = data.getBundleExtra("args");
btnColor.setColor(args.getInt("color"));
} else
startActivity(new Intent(getContext(), ActivityBilling.class));
}
break;
case REQUEST_SAVE_CHANGES: case REQUEST_SAVE_CHANGES:
if (resultCode == RESULT_OK) { if (resultCode == RESULT_OK) {
new Handler().post(new Runnable() { new Handler().post(new Runnable() {
@ -307,6 +336,7 @@ public class FragmentFolder extends FragmentBase {
args.putString("parent", parent); args.putString("parent", parent);
args.putString("name", etName.getText().toString()); args.putString("name", etName.getText().toString());
args.putString("display", etDisplay.getText().toString()); args.putString("display", etDisplay.getText().toString());
args.putInt("color", btnColor.getColor());
args.putBoolean("hide", cbHide.isChecked()); args.putBoolean("hide", cbHide.isChecked());
args.putBoolean("unified", cbUnified.isChecked()); args.putBoolean("unified", cbUnified.isChecked());
args.putBoolean("navigation", cbNavigation.isChecked()); args.putBoolean("navigation", cbNavigation.isChecked());
@ -346,6 +376,7 @@ public class FragmentFolder extends FragmentBase {
String parent = args.getString("parent"); String parent = args.getString("parent");
String name = args.getString("name"); String name = args.getString("name");
String display = args.getString("display"); String display = args.getString("display");
Integer color = args.getInt("color");
boolean hide = args.getBoolean("hide"); boolean hide = args.getBoolean("hide");
boolean unified = args.getBoolean("unified"); boolean unified = args.getBoolean("unified");
boolean navigation = args.getBoolean("navigation"); boolean navigation = args.getBoolean("navigation");
@ -357,8 +388,11 @@ public class FragmentFolder extends FragmentBase {
String keep = args.getString("keep"); String keep = args.getString("keep");
boolean auto_delete = args.getBoolean("auto_delete"); boolean auto_delete = args.getBoolean("auto_delete");
boolean pro = ActivityBilling.isPro(context);
boolean should = args.getBoolean("should"); boolean should = args.getBoolean("should");
if (color == Color.TRANSPARENT || !pro)
color = null;
if (TextUtils.isEmpty(display) || display.equals(name)) if (TextUtils.isEmpty(display) || display.equals(name))
display = null; display = null;
@ -428,6 +462,7 @@ public class FragmentFolder extends FragmentBase {
create.account = aid; create.account = aid;
create.name = name; create.name = name;
create.display = display; create.display = display;
create.color = color;
create.type = EntityFolder.USER; create.type = EntityFolder.USER;
create.unified = unified; create.unified = unified;
create.navigation = navigation; create.navigation = navigation;
@ -454,7 +489,7 @@ public class FragmentFolder extends FragmentBase {
Log.i("Updating folder=" + folder.name); Log.i("Updating folder=" + folder.name);
db.folder().setFolderProperties(id, db.folder().setFolderProperties(id,
folder.name.equals(name) ? null : name, folder.name.equals(name) ? null : name,
display, unified, navigation, notify, hide, display, color, unified, navigation, notify, hide,
synchronize, poll, download, synchronize, poll, download,
sync_days, keep_days, auto_delete); sync_days, keep_days, auto_delete);
db.folder().setFolderError(id, null); db.folder().setFolderError(id, null);

@ -41,7 +41,6 @@ public class TupleFolderEx extends EntityFolder implements Serializable {
public Boolean accountPop; public Boolean accountPop;
public Integer accountOrder; public Integer accountOrder;
public String accountName; public String accountName;
public Integer accountColor;
public String accountState; public String accountState;
public int rules; public int rules;
public int messages; public int messages;
@ -69,7 +68,6 @@ public class TupleFolderEx extends EntityFolder implements Serializable {
Objects.equals(this.accountId, other.accountId) && Objects.equals(this.accountId, other.accountId) &&
Objects.equals(this.accountPop, other.accountPop) && Objects.equals(this.accountPop, other.accountPop) &&
Objects.equals(this.accountName, other.accountName) && Objects.equals(this.accountName, other.accountName) &&
Objects.equals(this.accountColor, other.accountColor) &&
Objects.equals(this.accountState, other.accountState) && Objects.equals(this.accountState, other.accountState) &&
this.rules == other.rules && this.rules == other.rules &&
this.messages == other.messages && this.messages == other.messages &&

@ -29,7 +29,6 @@ import java.util.Locale;
public class TupleFolderNav extends EntityFolder implements Serializable { public class TupleFolderNav extends EntityFolder implements Serializable {
public Integer accountOrder; public Integer accountOrder;
public String accountName; public String accountName;
public Integer accountColor;
public int unseen; public int unseen;
public int snoozed; public int snoozed;
public int operations; public int operations;

@ -75,6 +75,29 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvDisplay" /> app:layout_constraintTop_toBottomOf="@id/tvDisplay" />
<TextView
android:id="@+id/tvColor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_color"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etDisplay" />
<eu.faircode.email.ViewButtonColor
android:id="@+id/btnColor"
style="@style/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:minWidth="0dp"
android:minHeight="0dp"
android:tag="disable"
android:text="@string/title_select"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvColor" />
<CheckBox <CheckBox
android:id="@+id/cbHide" android:id="@+id/cbHide"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -82,7 +105,7 @@
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:text="@string/title_hide_folder" android:text="@string/title_hide_folder"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etDisplay" /> app:layout_constraintTop_toBottomOf="@id/btnColor" />
<CheckBox <CheckBox
android:id="@+id/cbUnified" android:id="@+id/cbUnified"

Loading…
Cancel
Save