Move to favorite folder

pull/197/head
M66B 3 years ago
parent d0eb35edd1
commit fe12c64f89

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1340,6 +1340,6 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
}
interface IFolderSelectedListener {
void onFolderSelected(TupleFolderEx folder);
void onFolderSelected(@NonNull TupleFolderEx folder);
}
}

@ -1254,6 +1254,9 @@ class Core {
itarget.close();
}
if (EntityFolder.USER.equals(target.type))
db.folder().increaseSelectedCount(target.id, new Date().getTime());
// Delete junk contacts
if (EntityFolder.JUNK.equals(target.type))
for (EntityMessage message : map.values()) {

@ -65,7 +65,7 @@ import static eu.faircode.email.ServiceAuthenticator.AUTH_TYPE_PASSWORD;
// https://developer.android.com/topic/libraries/architecture/room.html
@Database(
version = 189,
version = 191,
entities = {
EntityIdentity.class,
EntityAccount.class,
@ -1953,6 +1953,20 @@ public abstract class DB extends RoomDatabase {
db.execSQL("ALTER TABLE `identity` ADD COLUMN `sign_default` INTEGER NOT NULL DEFAULT 0");
db.execSQL("ALTER TABLE `identity` ADD COLUMN `encrypt_default` INTEGER NOT NULL DEFAULT 0");
}
})
.addMigrations(new Migration(189, 190) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {
Log.i("DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `folder` ADD COLUMN `selected_count` INTEGER NOT NULL DEFAULT 0");
}
})
.addMigrations(new Migration(190, 191) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {
Log.i("DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `folder` ADD COLUMN `selected_last` INTEGER NOT NULL DEFAULT 0");
}
});
}

@ -198,6 +198,22 @@ public interface DaoFolder {
" GROUP BY folder.type")
LiveData<List<TupleFolderUnified>> liveUnified();
@Query("SELECT * FROM folder" +
" WHERE selected_count > 0" +
" AND NOT folder.id IN (:disabled)" +
" ORDER BY selected_count DESC, selected_last DESC" +
" LIMIT :count")
List<EntityFolder> getFavoriteFolders(int count, long[] disabled);
@Query("UPDATE folder" +
" SET selected_last = :last, selected_count = selected_count + 1" +
" WHERE id = :id")
int increaseSelectedCount(long id, long last);
@Query("UPDATE folder" +
" SET selected_last = 0, selected_count = 0")
int resetSelectedCount();
@Query("SELECT * FROM folder WHERE id = :id")
EntityFolder getFolder(Long id);

@ -116,6 +116,11 @@ public class EntityFolder extends EntityOrder implements Serializable {
public Integer total; // messages on server
public String[] keywords;
@NonNull
public Long selected_last = 0L;
@NonNull
public Integer selected_count = 0;
@NonNull
public Integer initialize = DEFAULT_KEEP;
public Boolean tbc; // to be created

@ -22,6 +22,7 @@ package eu.faircode.email;
import android.app.Dialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Paint;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
@ -77,9 +78,12 @@ public class FragmentDialogFolder extends FragmentDialogBase {
}
final View dview = LayoutInflater.from(context).inflate(R.layout.dialog_folder_select, null);
final TextView tvNoFolder = dview.findViewById(R.id.tvNoFolder);
final AutoCompleteTextView etSearch = dview.findViewById(R.id.etSearch);
final ImageButton ibNext = dview.findViewById(R.id.ibNext);
final TextView tvNoFolder = dview.findViewById(R.id.tvNoFolder);
final TextView tvFavorite1 = dview.findViewById(R.id.tvFavorite1);
final TextView tvFavorite2 = dview.findViewById(R.id.tvFavorite2);
final TextView tvFavorite3 = dview.findViewById(R.id.tvFavorite3);
final RecyclerView rvFolder = dview.findViewById(R.id.rvFolder);
final ContentLoadingProgressBar pbWait = dview.findViewById(R.id.pbWait);
final Group grpReady = dview.findViewById(R.id.grpReady);
@ -123,7 +127,7 @@ public class FragmentDialogFolder extends FragmentDialogBase {
final AdapterFolder adapter = new AdapterFolder(context, getViewLifecycleOwner(),
account, false, false, false, false, new AdapterFolder.IFolderSelectedListener() {
@Override
public void onFolderSelected(TupleFolderEx folder) {
public void onFolderSelected(@NonNull TupleFolderEx folder) {
String name = folder.getDisplayName(context, folder.parent_ref);
selected_folders.remove(name);
selected_folders.add(0, name);
@ -140,6 +144,32 @@ public class FragmentDialogFolder extends FragmentDialogBase {
}
});
tvFavorite1.setVisibility(View.GONE);
tvFavorite2.setVisibility(View.GONE);
tvFavorite3.setVisibility(View.GONE);
tvFavorite1.setPaintFlags(tvFavorite1.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
tvFavorite2.setPaintFlags(tvFavorite2.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
tvFavorite3.setPaintFlags(tvFavorite3.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View v) {
Long id = (Long) v.getTag();
if (id == null)
return;
Bundle args = getArguments();
args.putLong("folder", id);
sendResult(RESULT_OK);
dismiss();
}
};
tvFavorite1.setOnClickListener(listener);
tvFavorite2.setOnClickListener(listener);
tvFavorite3.setOnClickListener(listener);
rvFolder.setAdapter(adapter);
etSearch.addTextChangedListener(new TextWatcher() {
@ -200,8 +230,9 @@ public class FragmentDialogFolder extends FragmentDialogBase {
Bundle args = new Bundle();
args.putLong("account", account);
args.putLongArray("disabled", disabled);
new SimpleTask<List<TupleFolderEx>>() {
new SimpleTask<Data>() {
@Override
protected void onPreExecute(Bundle args) {
tvNoFolder.setVisibility(View.GONE);
@ -215,20 +246,35 @@ public class FragmentDialogFolder extends FragmentDialogBase {
}
@Override
protected List<TupleFolderEx> onExecute(Context context, Bundle args) {
protected Data onExecute(Context context, Bundle args) {
long account = args.getLong("account");
long[] disabled = args.getLongArray("disabled");
DB db = DB.getInstance(context);
return db.folder().getFoldersEx(account);
Data data = new Data();
data.folders = db.folder().getFoldersEx(account);
data.favorites = db.folder().getFavoriteFolders(3, disabled);
return data;
}
@Override
protected void onExecuted(final Bundle args, List<TupleFolderEx> folders) {
if (folders == null || folders.size() == 0)
protected void onExecuted(final Bundle args, Data data) {
if (data.folders == null || data.folders.size() == 0)
tvNoFolder.setVisibility(View.VISIBLE);
else {
adapter.setDisabled(Helper.fromLongArray(disabled));
adapter.set(folders);
adapter.set(data.folders);
if (data.favorites != null) {
TextView[] tv = new TextView[]{tvFavorite1, tvFavorite2, tvFavorite3};
for (int i = 0; i < data.favorites.size(); i++) {
EntityFolder favorite = data.favorites.get(i);
tv[i].setTag(favorite.id);
tv[i].setText(favorite.getDisplayName(context));
tv[i].setVisibility(View.VISIBLE);
}
}
grpReady.setVisibility(View.VISIBLE);
}
}
@ -246,4 +292,9 @@ public class FragmentDialogFolder extends FragmentDialogBase {
.setNegativeButton(android.R.string.cancel, null)
.create();
}
private static class Data {
private List<TupleFolderEx> folders;
private List<EntityFolder> favorites;
}
}

@ -3496,7 +3496,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
if (sourceFolder == null || sourceFolder.read_only)
continue;
result.add(new MessageTarget(context, threaded, sourceAccount, sourceFolder, targetAccount, targetFolder, copy));
result.add(new MessageTarget(context, threaded, sourceAccount, sourceFolder, targetAccount, targetFolder).setCopy(copy));
}
}
@ -7957,19 +7957,16 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
MessageTarget(Context context, EntityMessage message,
EntityAccount sourceAccount, EntityFolder sourceFolder,
EntityAccount targetAccount, EntityFolder targetFolder) {
this(context, message, sourceAccount, sourceFolder, targetAccount, targetFolder, false);
}
MessageTarget(Context context, EntityMessage message,
EntityAccount sourceAccount, EntityFolder sourceFolder,
EntityAccount targetAccount, EntityFolder targetFolder,
boolean copy) {
this.id = message.id;
this.sourceAccount = new Account(sourceAccount);
this.sourceFolder = new Folder(context, sourceFolder);
this.targetAccount = new Account(targetAccount);
this.targetFolder = new Folder(context, targetFolder);
}
MessageTarget setCopy(boolean copy) {
this.copy = copy;
return this;
}
protected MessageTarget(Parcel in) {

@ -834,6 +834,21 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
if (key.endsWith(".show_full") || key.endsWith(".show_images") || key.endsWith(".confirm_link"))
editor.remove(key);
editor.apply();
new SimpleTask<Void>() {
@Override
protected Void onExecute(Context context, Bundle args) {
DB db = DB.getInstance(context);
db.folder().resetSelectedCount();
return null;
}
@Override
protected void onException(Bundle args, Throwable ex) {
Log.unexpectedError(getParentFragmentManager(), ex);
}
}.execute(this, new Bundle(), "reset:questions");
ToastEx.makeText(getContext(), R.string.title_setup_done, Toast.LENGTH_LONG).show();
}

@ -8,18 +8,6 @@
android:focusableInTouchMode="true"
android:padding="12dp">
<eu.faircode.email.FixedTextView
android:id="@+id/tvNoFolder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="24dp"
android:text="@string/title_no_folders"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<AutoCompleteTextView
android:id="@+id/etSearch"
android:layout_width="0dp"
@ -42,6 +30,68 @@
app:layout_constraintTop_toTopOf="@+id/etSearch"
app:srcCompat="@drawable/twotone_fast_forward_24" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvNoFolder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"
android:text="@string/title_no_folders"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/etSearch" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvFavorite1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="start"
android:padding="6dp"
android:singleLine="true"
android:text="favorite1"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="?android:attr/textColorLink"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/tvFavorite2"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvNoFolder" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvFavorite2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="start"
android:padding="6dp"
android:singleLine="true"
android:text="favorite2"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="?android:attr/textColorLink"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/tvFavorite3"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toEndOf="@id/tvFavorite1"
app:layout_constraintTop_toBottomOf="@id/tvNoFolder" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvFavorite3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="start"
android:padding="6dp"
android:singleLine="true"
android:text="favorite3"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="?android:attr/textColorLink"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toEndOf="@id/tvFavorite2"
app:layout_constraintTop_toBottomOf="@id/tvNoFolder" />
<eu.faircode.email.FixedRecyclerView
android:id="@+id/rvFolder"
android:layout_width="0dp"
@ -58,7 +108,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/etSearch" />
app:layout_constraintTop_toBottomOf="@+id/tvFavorite1" />
<eu.faircode.email.ContentLoadingProgressBar
android:id="@+id/pbWait"

Loading…
Cancel
Save