Browse Source

Added option to set poll interval per folder

main
M66B 6 years ago
parent
commit
11e9333f14
9 changed files with 1063 additions and 11 deletions
  1. +1000
    -0
      app/schemas/eu.faircode.email.DB/20.json
  2. +8
    -1
      app/src/main/java/eu/faircode/email/DB.java
  3. +2
    -1
      app/src/main/java/eu/faircode/email/DaoFolder.java
  4. +1
    -0
      app/src/main/java/eu/faircode/email/EntityFolder.java
  5. +13
    -1
      app/src/main/java/eu/faircode/email/FragmentFolder.java
  6. +7
    -3
      app/src/main/java/eu/faircode/email/ServiceSynchronize.java
  7. +2
    -2
      app/src/main/res/layout/fragment_account.xml
  8. +28
    -2
      app/src/main/res/layout/fragment_folder.xml
  9. +2
    -1
      app/src/main/res/values/strings.xml

+ 1000
- 0
app/schemas/eu.faircode.email.DB/20.json
File diff suppressed because it is too large
View File


+ 8
- 1
app/src/main/java/eu/faircode/email/DB.java View File

@ -45,7 +45,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase;
// https://developer.android.com/topic/libraries/architecture/room.html // https://developer.android.com/topic/libraries/architecture/room.html
@Database( @Database(
version = 19,
version = 20,
entities = { entities = {
EntityIdentity.class, EntityIdentity.class,
EntityAccount.class, EntityAccount.class,
@ -250,6 +250,13 @@ public abstract class DB extends RoomDatabase {
db.execSQL("ALTER TABLE `folder` ADD COLUMN `hide` INTEGER NOT NULL DEFAULT 0"); db.execSQL("ALTER TABLE `folder` ADD COLUMN `hide` INTEGER NOT NULL DEFAULT 0");
} }
}) })
.addMigrations(new Migration(19, 20) {
@Override
public void migrate(SupportSQLiteDatabase db) {
Log.i(Helper.TAG, "DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `folder` ADD COLUMN `poll_interval` INTEGER");
}
})
.build(); .build();
} }


+ 2
- 1
app/src/main/java/eu/faircode/email/DaoFolder.java View File

@ -124,8 +124,9 @@ public interface DaoFolder {
", synchronize = :synchronize" + ", synchronize = :synchronize" +
", unified = :unified" + ", unified = :unified" +
", `after` = :after" + ", `after` = :after" +
", `poll_interval` = :poll_interval" +
" WHERE id = :id") " WHERE id = :id")
int setFolderProperties(long id, String name, String display, boolean hide, boolean synchronize, boolean unified, int after);
int setFolderProperties(long id, String name, String display, boolean hide, boolean synchronize, boolean unified, int after, Integer poll_interval);
@Query("UPDATE folder SET name = :name WHERE account = :account AND name = :old") @Query("UPDATE folder SET name = :name WHERE account = :account AND name = :old")
int renameFolder(long account, String old, String name); int renameFolder(long account, String old, String name);


+ 1
- 0
app/src/main/java/eu/faircode/email/EntityFolder.java View File

@ -62,6 +62,7 @@ public class EntityFolder implements Parcelable {
public String type; public String type;
@NonNull @NonNull
public Boolean synchronize; public Boolean synchronize;
public Integer poll_interval;
@NonNull @NonNull
public Integer after; // days public Integer after; // days
public String display; public String display;


+ 13
- 1
app/src/main/java/eu/faircode/email/FragmentFolder.java View File

@ -44,6 +44,7 @@ import javax.mail.Session;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.Group;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
public class FragmentFolder extends FragmentEx { public class FragmentFolder extends FragmentEx {
@ -54,10 +55,12 @@ public class FragmentFolder extends FragmentEx {
private CheckBox cbSynchronize; private CheckBox cbSynchronize;
private CheckBox cbUnified; private CheckBox cbUnified;
private EditText etAfter; private EditText etAfter;
private EditText etInterval;
private Button btnSave; private Button btnSave;
private ImageButton ibDelete; private ImageButton ibDelete;
private ProgressBar pbSave; private ProgressBar pbSave;
private ProgressBar pbWait; private ProgressBar pbWait;
private Group grpInterval;
private long id = -1; private long id = -1;
private long account = -1; private long account = -1;
@ -86,10 +89,12 @@ public class FragmentFolder extends FragmentEx {
cbSynchronize = view.findViewById(R.id.cbSynchronize); cbSynchronize = view.findViewById(R.id.cbSynchronize);
cbUnified = view.findViewById(R.id.cbUnified); cbUnified = view.findViewById(R.id.cbUnified);
etAfter = view.findViewById(R.id.etAfter); etAfter = view.findViewById(R.id.etAfter);
etInterval = view.findViewById(R.id.etInterval);
btnSave = view.findViewById(R.id.btnSave); btnSave = view.findViewById(R.id.btnSave);
ibDelete = view.findViewById(R.id.ibDelete); ibDelete = view.findViewById(R.id.ibDelete);
pbSave = view.findViewById(R.id.pbSave); pbSave = view.findViewById(R.id.pbSave);
pbWait = view.findViewById(R.id.pbWait); pbWait = view.findViewById(R.id.pbWait);
grpInterval = view.findViewById(R.id.grpInterval);
btnSave.setOnClickListener(new View.OnClickListener() { btnSave.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -108,6 +113,7 @@ public class FragmentFolder extends FragmentEx {
args.putBoolean("unified", cbUnified.isChecked()); args.putBoolean("unified", cbUnified.isChecked());
args.putBoolean("synchronize", cbSynchronize.isChecked()); args.putBoolean("synchronize", cbSynchronize.isChecked());
args.putString("after", etAfter.getText().toString()); args.putString("after", etAfter.getText().toString());
args.putString("interval", etInterval.getText().toString());
new SimpleTask<Void>() { new SimpleTask<Void>() {
@Override @Override
@ -120,10 +126,12 @@ public class FragmentFolder extends FragmentEx {
boolean unified = args.getBoolean("unified"); boolean unified = args.getBoolean("unified");
boolean synchronize = args.getBoolean("synchronize"); boolean synchronize = args.getBoolean("synchronize");
String after = args.getString("after"); String after = args.getString("after");
String interval = args.getString("interval");
if (TextUtils.isEmpty(display) || display.equals(name)) if (TextUtils.isEmpty(display) || display.equals(name))
display = null; display = null;
int days = (TextUtils.isEmpty(after) ? EntityFolder.DEFAULT_USER_SYNC : Integer.parseInt(after)); int days = (TextUtils.isEmpty(after) ? EntityFolder.DEFAULT_USER_SYNC : Integer.parseInt(after));
Integer poll_interval = (TextUtils.isEmpty(interval) ? null : Integer.parseInt(interval));
IMAPStore istore = null; IMAPStore istore = null;
DB db = DB.getInstance(getContext()); DB db = DB.getInstance(getContext());
@ -157,6 +165,7 @@ public class FragmentFolder extends FragmentEx {
create.unified = unified; create.unified = unified;
create.synchronize = synchronize; create.synchronize = synchronize;
create.after = days; create.after = days;
create.poll_interval = poll_interval;
db.folder().insertFolder(create); db.folder().insertFolder(create);
} else { } else {
Log.i(Helper.TAG, "Renaming folder=" + name); Log.i(Helper.TAG, "Renaming folder=" + name);
@ -171,7 +180,7 @@ public class FragmentFolder extends FragmentEx {
if (folder != null) { if (folder != null) {
Log.i(Helper.TAG, "Updating folder=" + name); Log.i(Helper.TAG, "Updating folder=" + name);
db.folder().setFolderProperties(id, name, display, hide, synchronize, unified, days);
db.folder().setFolderProperties(id, name, display, hide, synchronize, unified, days, poll_interval);
if (!synchronize) if (!synchronize)
db.folder().setFolderError(id, null); db.folder().setFolderError(id, null);
} }
@ -294,6 +303,7 @@ public class FragmentFolder extends FragmentEx {
ibDelete.setVisibility(View.GONE); ibDelete.setVisibility(View.GONE);
pbSave.setVisibility(View.GONE); pbSave.setVisibility(View.GONE);
pbWait.setVisibility(View.VISIBLE); pbWait.setVisibility(View.VISIBLE);
grpInterval.setVisibility(View.GONE);
return view; return view;
} }
@ -320,12 +330,14 @@ public class FragmentFolder extends FragmentEx {
cbUnified.setChecked(folder == null ? false : folder.unified); cbUnified.setChecked(folder == null ? false : folder.unified);
cbSynchronize.setChecked(folder == null || folder.synchronize); cbSynchronize.setChecked(folder == null || folder.synchronize);
etAfter.setText(Integer.toString(folder == null ? EntityFolder.DEFAULT_USER_SYNC : folder.after)); etAfter.setText(Integer.toString(folder == null ? EntityFolder.DEFAULT_USER_SYNC : folder.after));
etInterval.setText(folder == null || folder.poll_interval == null ? null : Integer.toString(folder.poll_interval));
} }
// Consider previous save as cancelled // Consider previous save as cancelled
pbWait.setVisibility(View.GONE); pbWait.setVisibility(View.GONE);
Helper.setViewsEnabled(view, true); Helper.setViewsEnabled(view, true);
etRename.setEnabled(folder == null || EntityFolder.USER.equals(folder.type)); etRename.setEnabled(folder == null || EntityFolder.USER.equals(folder.type));
grpInterval.setVisibility(folder == null || EntityFolder.USER.equals(folder.type) ? View.VISIBLE : View.GONE);
btnSave.setEnabled(true); btnSave.setEnabled(true);
ibDelete.setVisibility(folder == null || !EntityFolder.USER.equals(folder.type) ? View.GONE : View.VISIBLE); ibDelete.setVisibility(folder == null || !EntityFolder.USER.equals(folder.type) ? View.GONE : View.VISIBLE);
} }


+ 7
- 3
app/src/main/java/eu/faircode/email/ServiceSynchronize.java View File

@ -814,9 +814,8 @@ public class ServiceSynchronize extends LifecycleService {
Log.i(Helper.TAG, folder.name + " start noop"); Log.i(Helper.TAG, folder.name + " start noop");
while (state.running && ifolder.isOpen()) { while (state.running && ifolder.isOpen()) {
try { try {
Thread.sleep(account.poll_interval * 60 * 1000L);
if (!EntityFolder.USER.equals(folder.type) && capIdle) { if (!EntityFolder.USER.equals(folder.type) && capIdle) {
Thread.sleep(account.poll_interval * 60 * 1000L);
Log.i(Helper.TAG, folder.name + " request NOOP"); Log.i(Helper.TAG, folder.name + " request NOOP");
ifolder.doCommand(new IMAPFolder.ProtocolCommand() { ifolder.doCommand(new IMAPFolder.ProtocolCommand() {
public Object doCommand(IMAPProtocol p) throws ProtocolException { public Object doCommand(IMAPProtocol p) throws ProtocolException {
@ -826,8 +825,13 @@ public class ServiceSynchronize extends LifecycleService {
return null; return null;
} }
}); });
} else
} else {
if (folder.poll_interval == null)
Thread.sleep(account.poll_interval * 60 * 1000L);
else
Thread.sleep(folder.poll_interval * 60 * 1000L);
synchronizeMessages(account, folder, ifolder, state); synchronizeMessages(account, folder, ifolder, state);
}
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
Log.w(Helper.TAG, folder.name + " noop " + ex.toString()); Log.w(Helper.TAG, folder.name + " noop " + ex.toString());


+ 2
- 2
app/src/main/res/layout/fragment_account.xml View File

@ -318,14 +318,14 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbSynchronize" /> app:layout_constraintTop_toBottomOf="@id/cbSynchronize" />
<!-- port -->
<!-- keep alive -->
<TextView <TextView
android:id="@+id/tvInterval" android:id="@+id/tvInterval"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:text="@string/title_poll_interval"
android:text="@string/title_keep_alive_interval"
android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbPrimary" /> app:layout_constraintTop_toBottomOf="@id/cbPrimary" />


+ 28
- 2
app/src/main/res/layout/fragment_folder.xml View File

@ -102,6 +102,26 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvAfter" /> app:layout_constraintTop_toBottomOf="@id/tvAfter" />
<TextView
android:id="@+id/tvInterval"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_poll_interval"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etAfter" />
<EditText
android:id="@+id/etInterval"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="9"
android:inputType="number"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvInterval" />
<Button <Button
android:id="@+id/btnSave" android:id="@+id/btnSave"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -109,7 +129,7 @@
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:text="@string/title_save" android:text="@string/title_save"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etAfter" />
app:layout_constraintTop_toBottomOf="@id/etInterval" />
<ImageButton <ImageButton
android:id="@+id/ibDelete" android:id="@+id/ibDelete"
@ -118,7 +138,7 @@
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:src="@drawable/baseline_delete_24" android:src="@drawable/baseline_delete_24"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/etAfter" />
app:layout_constraintTop_toBottomOf="@id/etInterval" />
<ProgressBar <ProgressBar
android:id="@+id/pbSave" android:id="@+id/pbSave"
@ -141,5 +161,11 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Group
android:id="@+id/grpInterval"
android:layout_width="0dp"
android:layout_height="0dp"
app:constraint_referenced_ids="tvInterval,etInterval" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView> </ScrollView>

+ 2
- 1
app/src/main/res/values/strings.xml View File

@ -113,7 +113,7 @@
<string name="title_synchronize_identity">Synchronize (send messages)</string> <string name="title_synchronize_identity">Synchronize (send messages)</string>
<string name="title_primary_account">Primary (default account)</string> <string name="title_primary_account">Primary (default account)</string>
<string name="title_primary_identity">Primary (default identity)</string> <string name="title_primary_identity">Primary (default identity)</string>
<string name="title_poll_interval">Poll interval (minutes)</string>
<string name="title_keep_alive_interval">Keep alive interval (minutes)</string>
<string name="title_check">Check</string> <string name="title_check">Check</string>
<string name="title_no_name">Name missing</string> <string name="title_no_name">Name missing</string>
<string name="title_no_email">Email address missing</string> <string name="title_no_email">Email address missing</string>
@ -147,6 +147,7 @@
<string name="title_synchronize_folder">Synchronize (receive messages)</string> <string name="title_synchronize_folder">Synchronize (receive messages)</string>
<string name="title_unified_folder">Show in unified inbox</string> <string name="title_unified_folder">Show in unified inbox</string>
<string name="title_after">Synchronize (days)</string> <string name="title_after">Synchronize (days)</string>
<string name="title_poll_interval">Poll interval (minutes)</string>
<string name="title_folder_exists">Folder %1$s exists</string> <string name="title_folder_exists">Folder %1$s exists</string>
<string name="title_folder_delete">Delete folder permanently?</string> <string name="title_folder_delete">Delete folder permanently?</string>


Loading…
Cancel
Save