mirror of
https://github.com/M66B/FairEmail.git
synced 2026-01-13 08:12:02 +01:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4cb13b9ec | ||
|
|
9ecdfaafa4 | ||
|
|
7a55f8b8ed | ||
|
|
681a8a31e2 | ||
|
|
0d340d1865 | ||
|
|
155506ce81 | ||
|
|
bf310662c1 | ||
|
|
2f0babc479 | ||
|
|
b19f496ce0 | ||
|
|
1140ae3bf8 | ||
|
|
b75088833e | ||
|
|
8f784c8954 |
BIN
.idea/caches/build_file_checksums.ser
generated
BIN
.idea/caches/build_file_checksums.ser
generated
Binary file not shown.
11
FAQ.md
11
FAQ.md
@@ -8,11 +8,12 @@ At the bottom you can find how to ask other questions, request features and repo
|
||||
<a name="FAQ1"></a>
|
||||
**(1) Which permissions are needed and why?**
|
||||
|
||||
* Full network access (INTERNET): to send and receive email
|
||||
* View network connections (ACCESS_NETWORK_STATE): to monitor internet connectivity changes
|
||||
* Run at startup (RECEIVE_BOOT_COMPLETED): to start monitoring on device start
|
||||
* In-app billing (BILLING): to allow in-app purchases
|
||||
* Foreground service (FOREGROUND_SERVICE): to run a foreground service on Android 9 Pie and later, see also the next question
|
||||
* have full network access (INTERNET): to send and receive email
|
||||
* view network connections (ACCESS_NETWORK_STATE): to monitor internet connectivity changes
|
||||
* run at startup (RECEIVE_BOOT_COMPLETED): to start monitoring on device start
|
||||
* in-app billing (BILLING): to allow in-app purchases
|
||||
* foreground service (FOREGROUND_SERVICE): to run a foreground service on Android 9 Pie and later, see also the next question
|
||||
* prevent device from sleeping (WAKE_LOCK): to keep the device awake while synchronizing messages
|
||||
* Optional: read your contacts (READ_CONTACTS): to autocomplete addresses and to show photos
|
||||
* Optional: find accounts on the device (GET_ACCOUNTS): to use [OAuth](https://en.wikipedia.org/wiki/OAuth) instead of passwords
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ android {
|
||||
applicationId "eu.faircode.email"
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 28
|
||||
versionCode 78
|
||||
versionName "1.78"
|
||||
versionCode 80
|
||||
versionName "1.80"
|
||||
archivesBaseName = "FairEmail-v$versionName"
|
||||
|
||||
javaCompileOptions {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="com.android.vending.BILLING" />
|
||||
|
||||
<application
|
||||
|
||||
@@ -91,6 +91,7 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
|
||||
@Override
|
||||
public void run() {
|
||||
Log.i(Helper.TAG, "Boundary close");
|
||||
DB.getInstance(context).message().deleteFoundMessages();
|
||||
try {
|
||||
if (istore != null)
|
||||
istore.close();
|
||||
|
||||
@@ -124,9 +124,8 @@ public interface DaoFolder {
|
||||
", synchronize = :synchronize" +
|
||||
", unified = :unified" +
|
||||
", `after` = :after" +
|
||||
", `poll_interval` = :poll_interval" +
|
||||
" WHERE id = :id")
|
||||
int setFolderProperties(long id, String name, String display, boolean hide, boolean synchronize, boolean unified, int after, Integer poll_interval);
|
||||
int setFolderProperties(long id, String name, String display, boolean hide, boolean synchronize, boolean unified, int after);
|
||||
|
||||
@Query("UPDATE folder SET name = :name WHERE account = :account AND name = :old")
|
||||
int renameFolder(long account, String old, String name);
|
||||
|
||||
@@ -224,9 +224,6 @@ public interface DaoMessage {
|
||||
@Query("UPDATE message SET headers = :headers WHERE id = :id")
|
||||
int setMessageHeaders(long id, String headers);
|
||||
|
||||
@Query("UPDATE message SET avatar = :avatar WHERE id = :id")
|
||||
int setMessageAvatar(long id, String avatar);
|
||||
|
||||
@Query("DELETE FROM message WHERE id = :id")
|
||||
int deleteMessage(long id);
|
||||
|
||||
@@ -241,4 +238,7 @@ public interface DaoMessage {
|
||||
|
||||
@Query("DELETE FROM message WHERE folder = :folder AND received < :received AND NOT uid IS NULL")
|
||||
int deleteMessagesBefore(long folder, long received);
|
||||
|
||||
@Query("DELETE FROM message WHERE ui_found")
|
||||
int deleteFoundMessages();
|
||||
}
|
||||
@@ -60,7 +60,7 @@ public class EntityFolder implements Serializable {
|
||||
public String type;
|
||||
@NonNull
|
||||
public Boolean synchronize;
|
||||
public Integer poll_interval;
|
||||
public Integer poll_interval; // obsolete
|
||||
@NonNull
|
||||
public Integer after; // days
|
||||
public String display;
|
||||
|
||||
@@ -44,7 +44,6 @@ import javax.mail.Session;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.constraintlayout.widget.Group;
|
||||
import androidx.lifecycle.Observer;
|
||||
|
||||
public class FragmentFolder extends FragmentEx {
|
||||
@@ -55,12 +54,10 @@ public class FragmentFolder extends FragmentEx {
|
||||
private CheckBox cbSynchronize;
|
||||
private CheckBox cbUnified;
|
||||
private EditText etAfter;
|
||||
private EditText etInterval;
|
||||
private Button btnSave;
|
||||
private ImageButton ibDelete;
|
||||
private ProgressBar pbSave;
|
||||
private ProgressBar pbWait;
|
||||
private Group grpInterval;
|
||||
|
||||
private long id = -1;
|
||||
private long account = -1;
|
||||
@@ -89,12 +86,10 @@ public class FragmentFolder extends FragmentEx {
|
||||
cbSynchronize = view.findViewById(R.id.cbSynchronize);
|
||||
cbUnified = view.findViewById(R.id.cbUnified);
|
||||
etAfter = view.findViewById(R.id.etAfter);
|
||||
etInterval = view.findViewById(R.id.etInterval);
|
||||
btnSave = view.findViewById(R.id.btnSave);
|
||||
ibDelete = view.findViewById(R.id.ibDelete);
|
||||
pbSave = view.findViewById(R.id.pbSave);
|
||||
pbWait = view.findViewById(R.id.pbWait);
|
||||
grpInterval = view.findViewById(R.id.grpInterval);
|
||||
|
||||
btnSave.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@@ -113,7 +108,6 @@ public class FragmentFolder extends FragmentEx {
|
||||
args.putBoolean("unified", cbUnified.isChecked());
|
||||
args.putBoolean("synchronize", cbSynchronize.isChecked());
|
||||
args.putString("after", etAfter.getText().toString());
|
||||
args.putString("interval", etInterval.getText().toString());
|
||||
|
||||
new SimpleTask<Void>() {
|
||||
@Override
|
||||
@@ -126,12 +120,10 @@ public class FragmentFolder extends FragmentEx {
|
||||
boolean unified = args.getBoolean("unified");
|
||||
boolean synchronize = args.getBoolean("synchronize");
|
||||
String after = args.getString("after");
|
||||
String interval = args.getString("interval");
|
||||
|
||||
if (TextUtils.isEmpty(display) || display.equals(name))
|
||||
display = null;
|
||||
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;
|
||||
DB db = DB.getInstance(getContext());
|
||||
@@ -165,7 +157,6 @@ public class FragmentFolder extends FragmentEx {
|
||||
create.unified = unified;
|
||||
create.synchronize = synchronize;
|
||||
create.after = days;
|
||||
create.poll_interval = poll_interval;
|
||||
db.folder().insertFolder(create);
|
||||
} else {
|
||||
Log.i(Helper.TAG, "Renaming folder=" + name);
|
||||
@@ -180,7 +171,7 @@ public class FragmentFolder extends FragmentEx {
|
||||
|
||||
if (folder != null) {
|
||||
Log.i(Helper.TAG, "Updating folder=" + name);
|
||||
db.folder().setFolderProperties(id, name, display, hide, synchronize, unified, days, poll_interval);
|
||||
db.folder().setFolderProperties(id, name, display, hide, synchronize, unified, days);
|
||||
if (!synchronize)
|
||||
db.folder().setFolderError(id, null);
|
||||
}
|
||||
@@ -303,7 +294,6 @@ public class FragmentFolder extends FragmentEx {
|
||||
ibDelete.setVisibility(View.GONE);
|
||||
pbSave.setVisibility(View.GONE);
|
||||
pbWait.setVisibility(View.VISIBLE);
|
||||
grpInterval.setVisibility(View.GONE);
|
||||
|
||||
return view;
|
||||
}
|
||||
@@ -330,7 +320,6 @@ public class FragmentFolder extends FragmentEx {
|
||||
cbUnified.setChecked(folder == null ? false : folder.unified);
|
||||
cbSynchronize.setChecked(folder == null || folder.synchronize);
|
||||
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
|
||||
@@ -341,57 +330,5 @@ public class FragmentFolder extends FragmentEx {
|
||||
ibDelete.setVisibility(folder == null || !EntityFolder.USER.equals(folder.type) ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putLong("id", id);
|
||||
args.putLong("account", account);
|
||||
|
||||
new SimpleTask<Boolean>() {
|
||||
@Override
|
||||
protected Boolean onLoad(Context context, Bundle args) throws Throwable {
|
||||
long fid = args.getLong("id");
|
||||
long aid = args.getLong("account");
|
||||
|
||||
IMAPStore istore = null;
|
||||
DB db = DB.getInstance(getContext());
|
||||
try {
|
||||
db.beginTransaction();
|
||||
|
||||
EntityAccount account;
|
||||
if (fid < 0)
|
||||
account = db.account().getAccount(aid);
|
||||
else {
|
||||
EntityFolder folder = db.folder().getFolder(fid);
|
||||
account = db.account().getAccount(folder.account);
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
|
||||
Properties props = MessageHelper.getSessionProperties(account.auth_type);
|
||||
Session isession = Session.getInstance(props, null);
|
||||
istore = (IMAPStore) isession.getStore("imaps");
|
||||
istore.connect(account.host, account.port, account.user, account.password);
|
||||
|
||||
return istore.hasCapability("IDLE");
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
|
||||
if (istore != null)
|
||||
istore.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLoaded(Bundle args, Boolean capIdle) {
|
||||
grpInterval.setVisibility(capIdle ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onException(Bundle args, Throwable ex) {
|
||||
grpInterval.setVisibility(View.VISIBLE);
|
||||
if (BuildConfig.DEBUG)
|
||||
Helper.unexpectedError(getContext(), ex);
|
||||
}
|
||||
}.load(this, args);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -102,26 +102,6 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
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
|
||||
android:id="@+id/btnSave"
|
||||
android:layout_width="wrap_content"
|
||||
@@ -129,7 +109,7 @@
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/title_save"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/etInterval" />
|
||||
app:layout_constraintTop_toBottomOf="@id/etAfter" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/ibDelete"
|
||||
@@ -138,7 +118,7 @@
|
||||
android:layout_marginTop="12dp"
|
||||
android:src="@drawable/baseline_delete_24"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/etInterval" />
|
||||
app:layout_constraintTop_toBottomOf="@id/etAfter" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/pbSave"
|
||||
@@ -161,11 +141,5 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="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>
|
||||
</ScrollView>
|
||||
Reference in New Issue
Block a user