mirror of
https://github.com/M66B/FairEmail.git
synced 2026-04-04 16:16:33 +02:00
@@ -21,6 +21,7 @@ package eu.faircode.email;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -49,6 +50,7 @@ public class AdapterAccount extends RecyclerView.Adapter<AdapterAccount.ViewHold
|
||||
|
||||
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
||||
View itemView;
|
||||
View vwColor;
|
||||
ImageView ivPrimary;
|
||||
TextView tvName;
|
||||
ImageView ivSync;
|
||||
@@ -61,6 +63,7 @@ public class AdapterAccount extends RecyclerView.Adapter<AdapterAccount.ViewHold
|
||||
super(itemView);
|
||||
|
||||
this.itemView = itemView;
|
||||
vwColor = itemView.findViewById(R.id.vwColor);
|
||||
ivPrimary = itemView.findViewById(R.id.ivPrimary);
|
||||
tvName = itemView.findViewById(R.id.tvName);
|
||||
ivSync = itemView.findViewById(R.id.ivSync);
|
||||
@@ -79,6 +82,7 @@ public class AdapterAccount extends RecyclerView.Adapter<AdapterAccount.ViewHold
|
||||
}
|
||||
|
||||
private void bindTo(EntityAccount account) {
|
||||
vwColor.setBackgroundColor(account.color == null ? Color.TRANSPARENT : account.color);
|
||||
ivPrimary.setVisibility(account.primary ? View.VISIBLE : View.INVISIBLE);
|
||||
tvName.setText(account.name);
|
||||
ivSync.setImageResource(account.synchronize ? R.drawable.baseline_sync_24 : R.drawable.baseline_sync_disabled_24);
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
@@ -81,6 +82,7 @@ public class AdapterMessage extends PagedListAdapter<TupleMessageEx, AdapterMess
|
||||
public class ViewHolder extends RecyclerView.ViewHolder
|
||||
implements View.OnClickListener, View.OnLongClickListener {
|
||||
View itemView;
|
||||
View vwColor;
|
||||
ImageView ivAvatar;
|
||||
ImageView ivFlagged;
|
||||
TextView tvFrom;
|
||||
@@ -100,6 +102,7 @@ public class AdapterMessage extends PagedListAdapter<TupleMessageEx, AdapterMess
|
||||
super(itemView);
|
||||
|
||||
this.itemView = itemView;
|
||||
vwColor = itemView.findViewById(R.id.vwColor);
|
||||
ivAvatar = itemView.findViewById(R.id.ivAvatar);
|
||||
ivFlagged = itemView.findViewById(R.id.ivFlagged);
|
||||
tvFrom = itemView.findViewById(R.id.tvFrom);
|
||||
@@ -179,6 +182,8 @@ public class AdapterMessage extends PagedListAdapter<TupleMessageEx, AdapterMess
|
||||
});
|
||||
}
|
||||
|
||||
vwColor.setBackgroundColor(message.accountColor == null ? Color.TRANSPARENT : message.accountColor);
|
||||
|
||||
ivFlagged.setVisibility(message.ui_flagged ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (EntityFolder.DRAFTS.equals(message.folderType) ||
|
||||
|
||||
@@ -45,7 +45,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase;
|
||||
// https://developer.android.com/topic/libraries/architecture/room.html
|
||||
|
||||
@Database(
|
||||
version = 13,
|
||||
version = 14,
|
||||
entities = {
|
||||
EntityIdentity.class,
|
||||
EntityAccount.class,
|
||||
@@ -206,6 +206,13 @@ public abstract class DB extends RoomDatabase {
|
||||
db.execSQL("ALTER TABLE `message` ADD COLUMN `avatar` TEXT");
|
||||
}
|
||||
})
|
||||
.addMigrations(new Migration(13, 14) {
|
||||
@Override
|
||||
public void migrate(SupportSQLiteDatabase db) {
|
||||
Log.i(Helper.TAG, "DB migration from version " + startVersion + " to " + endVersion);
|
||||
db.execSQL("ALTER TABLE `account` ADD COLUMN `color` INTEGER");
|
||||
}
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,9 @@ public interface DaoMessage {
|
||||
// all bare columns in the result set take values from the input row which also contains the minimum or maximum."
|
||||
// https://www.sqlite.org/lang_select.html
|
||||
|
||||
@Query("SELECT message.*, account.name AS accountName, folder.name as folderName, folder.type as folderType" +
|
||||
@Query("SELECT message.*" +
|
||||
", account.name AS accountName, account.color AS accountColor" +
|
||||
", folder.name as folderName, folder.type as folderType" +
|
||||
", COUNT(message.id) as count" +
|
||||
", SUM(CASE WHEN message.ui_seen" +
|
||||
" OR folder.type = '" + EntityFolder.OUTBOX + "'" +
|
||||
@@ -52,7 +54,9 @@ public interface DaoMessage {
|
||||
" ORDER BY message.received DESC")
|
||||
DataSource.Factory<Integer, TupleMessageEx> pagedUnifiedInbox(boolean debug);
|
||||
|
||||
@Query("SELECT message.*, account.name AS accountName, folder.name as folderName, folder.type as folderType" +
|
||||
@Query("SELECT message.*" +
|
||||
", account.name AS accountName, account.color AS accountColor" +
|
||||
", folder.name as folderName, folder.type as folderType" +
|
||||
", COUNT(message.id) as count" +
|
||||
", SUM(CASE WHEN message.ui_seen" +
|
||||
" OR (folder.id <> :folder AND folder.type = '" + EntityFolder.OUTBOX + "')" +
|
||||
@@ -70,7 +74,9 @@ public interface DaoMessage {
|
||||
" ORDER BY message.received DESC, message.sent DESC")
|
||||
DataSource.Factory<Integer, TupleMessageEx> pagedFolder(long folder, boolean found, boolean debug);
|
||||
|
||||
@Query("SELECT message.*, account.name AS accountName, folder.name as folderName, folder.type as folderType" +
|
||||
@Query("SELECT message.*" +
|
||||
", account.name AS accountName, account.color AS accountColor" +
|
||||
", folder.name as folderName, folder.type as folderType" +
|
||||
", 1 AS count" +
|
||||
", SUM(CASE WHEN message.ui_seen THEN 0 ELSE 1 END) as unseen" +
|
||||
", (SELECT COUNT(a.id) FROM attachment a WHERE a.message = message.id) AS attachments" +
|
||||
@@ -118,7 +124,9 @@ public interface DaoMessage {
|
||||
" ORDER BY message.received DESC, message.sent DESC")
|
||||
List<Long> getMessageIDs(long folder);
|
||||
|
||||
@Query("SELECT message.*, account.name AS accountName, folder.name as folderName, folder.type as folderType" +
|
||||
@Query("SELECT message.*" +
|
||||
", account.name AS accountName, account.color AS accountColor" +
|
||||
", folder.name as folderName, folder.type as folderType" +
|
||||
", (SELECT COUNT(m1.id) FROM message m1 WHERE m1.account = message.account AND m1.thread = message.thread AND NOT m1.ui_hide) AS count" +
|
||||
", (SELECT COUNT(m2.id) FROM message m2 WHERE m2.account = message.account AND m2.thread = message.thread AND NOT m2.ui_hide AND NOT m2.ui_seen) AS unseen" +
|
||||
", (SELECT COUNT(a.id) FROM attachment a WHERE a.message = message.id) AS attachments" +
|
||||
|
||||
@@ -49,6 +49,7 @@ public class EntityAccount {
|
||||
public Boolean primary;
|
||||
@NonNull
|
||||
public Boolean synchronize;
|
||||
public Integer color;
|
||||
@NonNull
|
||||
public Boolean store_sent; // obsolete
|
||||
@NonNull
|
||||
|
||||
@@ -29,6 +29,8 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
@@ -48,11 +50,14 @@ import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.colorpicker.ColorPickerDialog;
|
||||
import com.android.colorpicker.ColorPickerSwatch;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
import com.sun.mail.imap.IMAPFolder;
|
||||
@@ -94,6 +99,9 @@ public class FragmentAccount extends FragmentEx {
|
||||
private ImageButton ibPro;
|
||||
private CheckBox cbSynchronize;
|
||||
private CheckBox cbPrimary;
|
||||
private Button btnColor;
|
||||
private View vwColor;
|
||||
private ImageView ibColorDefault;
|
||||
private Button btnCheck;
|
||||
private ProgressBar pbCheck;
|
||||
private Spinner spDrafts;
|
||||
@@ -111,6 +119,7 @@ public class FragmentAccount extends FragmentEx {
|
||||
private Group grpFolders;
|
||||
|
||||
private long id = -1;
|
||||
private int color = Color.TRANSPARENT;
|
||||
private String authorized = null;
|
||||
|
||||
@Override
|
||||
@@ -146,6 +155,10 @@ public class FragmentAccount extends FragmentEx {
|
||||
cbSynchronize = view.findViewById(R.id.cbSynchronize);
|
||||
cbPrimary = view.findViewById(R.id.cbPrimary);
|
||||
|
||||
btnColor = view.findViewById(R.id.btnColor);
|
||||
vwColor = view.findViewById(R.id.vwColor);
|
||||
ibColorDefault = view.findViewById(R.id.ibColorDefault);
|
||||
|
||||
btnCheck = view.findViewById(R.id.btnCheck);
|
||||
pbCheck = view.findViewById(R.id.pbCheck);
|
||||
|
||||
@@ -265,6 +278,34 @@ public class FragmentAccount extends FragmentEx {
|
||||
}
|
||||
});
|
||||
|
||||
vwColor.setBackgroundColor(color);
|
||||
btnColor.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int[] colors = getContext().getResources().getIntArray(R.array.colorPicker);
|
||||
|
||||
ColorPickerDialog colorPickerDialog = new ColorPickerDialog();
|
||||
colorPickerDialog.initialize(
|
||||
R.string.title_account_color, colors, color, 4, colors.length);
|
||||
|
||||
colorPickerDialog.setOnColorSelectedListener(new ColorPickerSwatch.OnColorSelectedListener() {
|
||||
@Override
|
||||
public void onColorSelected(int color) {
|
||||
setColor(color);
|
||||
}
|
||||
});
|
||||
|
||||
colorPickerDialog.show(getFragmentManager(), "colorpicker");
|
||||
}
|
||||
});
|
||||
|
||||
ibColorDefault.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setColor(Color.TRANSPARENT);
|
||||
}
|
||||
});
|
||||
|
||||
btnCheck.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
@@ -491,6 +532,7 @@ public class FragmentAccount extends FragmentEx {
|
||||
args.putString("name", etName.getText().toString());
|
||||
args.putString("signature", Html.toHtml(etSignature.getText()));
|
||||
args.putBoolean("primary", cbPrimary.isChecked());
|
||||
args.putInt("color", color);
|
||||
args.putParcelable("drafts", drafts);
|
||||
args.putParcelable("sent", sent);
|
||||
args.putParcelable("all", all);
|
||||
@@ -509,6 +551,7 @@ public class FragmentAccount extends FragmentEx {
|
||||
String signature = args.getString("signature");
|
||||
boolean synchronize = args.getBoolean("synchronize");
|
||||
boolean primary = args.getBoolean("primary");
|
||||
int color = args.getInt("color");
|
||||
EntityFolder drafts = args.getParcelable("drafts");
|
||||
EntityFolder sent = args.getParcelable("sent");
|
||||
EntityFolder all = args.getParcelable("all");
|
||||
@@ -563,6 +606,7 @@ public class FragmentAccount extends FragmentEx {
|
||||
account.auth_type = auth_type;
|
||||
account.synchronize = synchronize;
|
||||
account.primary = (account.synchronize && primary);
|
||||
account.color = color;
|
||||
account.store_sent = false;
|
||||
account.poll_interval = 9;
|
||||
|
||||
@@ -779,6 +823,8 @@ public class FragmentAccount extends FragmentEx {
|
||||
cbSynchronize.setChecked(account == null ? true : account.synchronize);
|
||||
cbPrimary.setChecked(account == null ? true : account.primary);
|
||||
|
||||
color = (account == null || account.color == null ? Color.TRANSPARENT : account.color);
|
||||
|
||||
if (account == null)
|
||||
new SimpleTask<Integer>() {
|
||||
@Override
|
||||
@@ -814,6 +860,7 @@ public class FragmentAccount extends FragmentEx {
|
||||
}
|
||||
|
||||
cbPrimary.setEnabled(cbSynchronize.isChecked());
|
||||
setColor(color);
|
||||
|
||||
// Consider previous check/save/delete as cancelled
|
||||
ibDelete.setVisibility(account == null ? View.GONE : View.VISIBLE);
|
||||
@@ -887,4 +934,13 @@ public class FragmentAccount extends FragmentEx {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setColor(int color) {
|
||||
FragmentAccount.this.color = color;
|
||||
|
||||
GradientDrawable border = new GradientDrawable();
|
||||
border.setColor(color);
|
||||
border.setStroke(1, Helper.resolveColor(getContext(), R.attr.colorSeparator));
|
||||
vwColor.setBackground(border);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ package eu.faircode.email;
|
||||
|
||||
public class TupleMessageEx extends EntityMessage {
|
||||
public String accountName;
|
||||
public Integer accountColor;
|
||||
public String folderName;
|
||||
public String folderType;
|
||||
public int count;
|
||||
@@ -33,6 +34,7 @@ public class TupleMessageEx extends EntityMessage {
|
||||
TupleMessageEx other = (TupleMessageEx) obj;
|
||||
return (super.equals(obj) &&
|
||||
(this.accountName == null ? other.accountName == null : this.accountName.equals(other.accountName)) &&
|
||||
(this.accountColor == null ? other.accountColor == null : this.accountColor.equals(other.accountColor)) &&
|
||||
this.folderName.equals(other.folderName) &&
|
||||
this.folderType.equals(other.folderType) &&
|
||||
this.count == other.count &&
|
||||
|
||||
Reference in New Issue
Block a user