Store message preview

pull/146/head
M66B 7 years ago
parent f60418c71b
commit dee32db0b8

File diff suppressed because it is too large Load Diff

@ -66,7 +66,6 @@ import android.widget.Toast;
import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import org.jsoup.Jsoup;
import org.xml.sax.XMLReader; import org.xml.sax.XMLReader;
import java.io.File; import java.io.File;
@ -333,38 +332,8 @@ public class AdapterMessage extends PagedListAdapter<TupleMessageEx, AdapterMess
ivAttachments.setVisibility(message.attachments > 0 ? View.VISIBLE : View.GONE); ivAttachments.setVisibility(message.attachments > 0 ? View.VISIBLE : View.GONE);
tvSubject.setText(message.subject); tvSubject.setText(message.subject);
tvPreview.setVisibility(View.GONE); tvPreview.setText(message.preview);
if (preview && message.content) { tvPreview.setVisibility(preview && !TextUtils.isEmpty(message.preview) ? View.VISIBLE : View.GONE);
Bundle args = new Bundle();
args.putSerializable("message", message);
new SimpleTask<String>() {
@Override
protected void onInit(Bundle args) {
tvPreview.setHasTransientState(true);
}
@Override
protected String onLoad(Context context, Bundle args) throws Throwable {
TupleMessageEx message = (TupleMessageEx) args.getSerializable("message");
String body = message.read(context);
return Jsoup.parse(body).text();
}
@Override
protected void onLoaded(Bundle args, String preview) {
tvPreview.setText(preview);
tvPreview.setVisibility(View.VISIBLE);
tvPreview.setHasTransientState(false);
}
@Override
protected void onException(Bundle args, Throwable ex) {
tvPreview.setHasTransientState(false);
Helper.unexpectedError(context, ex);
}
}.load(context, owner, args);
}
if (viewType == ViewType.UNIFIED) if (viewType == ViewType.UNIFIED)
tvFolder.setText(message.accountName); tvFolder.setText(message.accountName);

@ -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 = 23, version = 24,
entities = { entities = {
EntityIdentity.class, EntityIdentity.class,
EntityAccount.class, EntityAccount.class,
@ -284,6 +284,13 @@ public abstract class DB extends RoomDatabase {
db.execSQL("ALTER TABLE `identity` ADD COLUMN `insecure` INTEGER NOT NULL DEFAULT 0"); db.execSQL("ALTER TABLE `identity` ADD COLUMN `insecure` INTEGER NOT NULL DEFAULT 0");
} }
}) })
.addMigrations(new Migration(23, 24) {
@Override
public void migrate(SupportSQLiteDatabase db) {
Log.i(Helper.TAG, "DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `message` ADD COLUMN `preview` TEXT");
}
})
.build(); .build();
} }

@ -158,6 +158,11 @@ public interface DaoMessage {
" AND ui_seen") " AND ui_seen")
List<EntityMessage> getMessageSeen(long folder); List<EntityMessage> getMessageSeen(long folder);
@Query("SELECT id FROM message" +
" WHERE content" +
" AND preview IS NULL")
List<Long> getMessageWithoutPreview();
@Query("SELECT message.*" + @Query("SELECT message.*" +
", account.name AS accountName, account.color AS accountColor" + ", account.name AS accountName, account.color AS accountColor" +
", folder.name AS folderName, folder.display AS folderDisplay, folder.type AS folderType" + ", folder.name AS folderName, folder.display AS folderDisplay, folder.type AS folderType" +
@ -220,8 +225,8 @@ public interface DaoMessage {
@Query("UPDATE message SET error = :error WHERE id = :id") @Query("UPDATE message SET error = :error WHERE id = :id")
int setMessageError(long id, String error); int setMessageError(long id, String error);
@Query("UPDATE message SET content = :content WHERE id = :id") @Query("UPDATE message SET content = NOT preview IS NULL, preview = :preview WHERE id = :id")
int setMessageContent(long id, boolean content); int setMessageContent(long id, String preview);
@Query("UPDATE message SET headers = :headers WHERE id = :id") @Query("UPDATE message SET headers = :headers WHERE id = :id")
int setMessageHeaders(long id, String headers); int setMessageHeaders(long id, String headers);

@ -94,6 +94,7 @@ public class EntityMessage implements Serializable {
public Integer size; public Integer size;
@NonNull @NonNull
public Boolean content = false; public Boolean content = false;
public String preview;
public Long sent; // compose = null public Long sent; // compose = null
@NonNull @NonNull
public Long received; // compose = stored public Long received; // compose = stored
@ -198,6 +199,7 @@ public class EntityMessage implements Serializable {
(this.subject == null ? other.subject == null : this.subject.equals(other.subject)) && (this.subject == null ? other.subject == null : this.subject.equals(other.subject)) &&
(this.size == null ? other.size == null : this.size.equals(other.size)) && (this.size == null ? other.size == null : this.size.equals(other.size)) &&
this.content == other.content && this.content == other.content &&
(this.preview == null ? other.preview == null : this.preview.equals(other.preview)) &&
(this.sent == null ? other.sent == null : this.sent.equals(other.sent)) && (this.sent == null ? other.sent == null : this.sent.equals(other.sent)) &&
this.received.equals(other.received) && this.received.equals(other.received) &&
this.stored.equals(other.stored) && this.stored.equals(other.stored) &&

@ -19,9 +19,12 @@ package eu.faircode.email;
Copyright 2018 by Marcel Bokhorst (M66B) Copyright 2018 by Marcel Bokhorst (M66B)
*/ */
import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -29,6 +32,10 @@ import android.widget.AdapterView;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.Spinner; import android.widget.Spinner;
import org.jsoup.Jsoup;
import java.io.IOException;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.widget.SwitchCompat; import androidx.appcompat.widget.SwitchCompat;
@ -113,6 +120,36 @@ public class FragmentOptions extends FragmentEx {
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("preview", checked).apply(); prefs.edit().putBoolean("preview", checked).apply();
if (checked)
new SimpleTask<Void>() {
@Override
protected Void onLoad(Context context, Bundle args) {
DB db = DB.getInstance(context);
ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
boolean metered = (cm == null || cm.isActiveNetworkMetered());
for (Long id : db.message().getMessageWithoutPreview()) {
EntityMessage message = db.message().getMessage(id);
try {
Log.i(Helper.TAG, "Building preview id=" + id);
String html = message.read(context);
String text = Jsoup.parse(html).text();
String preview = text.substring(0, Math.min(text.length(), 250));
db.message().setMessageContent(message.id, preview);
} catch (IOException ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
db.message().setMessageContent(message.id, null);
if (!metered)
EntityOperation.queue(db, message, EntityOperation.BODY);
}
}
EntityOperation.process(context);
return null;
}
}.load(FragmentOptions.this, null);
} }
}); });

@ -61,6 +61,7 @@ import com.sun.mail.util.MailConnectException;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.jsoup.Jsoup;
import java.io.IOException; import java.io.IOException;
import java.net.SocketException; import java.net.SocketException;
@ -134,6 +135,7 @@ public class ServiceSynchronize extends LifecycleService {
private static final int SYNC_BATCH_SIZE = 20; private static final int SYNC_BATCH_SIZE = 20;
private static final int DOWNLOAD_BATCH_SIZE = 20; private static final int DOWNLOAD_BATCH_SIZE = 20;
private static final long RECONNECT_BACKOFF = 90 * 1000L; // milliseconds private static final long RECONNECT_BACKOFF = 90 * 1000L; // milliseconds
private static final int PREVIEW_SIZE = 250;
static final int PI_CLEAR = 1; static final int PI_CLEAR = 1;
static final int PI_SEEN = 2; static final int PI_SEEN = 2;
@ -1432,8 +1434,11 @@ public class ServiceSynchronize extends LifecycleService {
throw new MessageRemovedException(); throw new MessageRemovedException();
MessageHelper helper = new MessageHelper((MimeMessage) imessage); MessageHelper helper = new MessageHelper((MimeMessage) imessage);
message.write(this, helper.getHtml()); String html = helper.getHtml();
db.message().setMessageContent(message.id, true); String text = Jsoup.parse(html).text();
String preview = text.substring(0, Math.min(text.length(), PREVIEW_SIZE));
message.write(this, html);
db.message().setMessageContent(message.id, preview);
} }
private void doAttachment(EntityFolder folder, EntityOperation op, IMAPFolder ifolder, EntityMessage message, JSONArray jargs, DB db) throws JSONException, MessagingException, IOException { private void doAttachment(EntityFolder folder, EntityOperation op, IMAPFolder ifolder, EntityMessage message, JSONArray jargs, DB db) throws JSONException, MessagingException, IOException {
@ -1890,8 +1895,11 @@ public class ServiceSynchronize extends LifecycleService {
if (!message.content) if (!message.content)
if (!metered || (message.size != null && message.size < download)) { if (!metered || (message.size != null && message.size < download)) {
message.write(context, helper.getHtml()); String html = helper.getHtml();
db.message().setMessageContent(message.id, true); String text = Jsoup.parse(html).text();
String preview = text.substring(0, Math.min(text.length(), PREVIEW_SIZE));
message.write(context, html);
db.message().setMessageContent(message.id, preview);
Log.i(Helper.TAG, folder.name + " downloaded message id=" + message.id + " size=" + message.size); Log.i(Helper.TAG, folder.name + " downloaded message id=" + message.id + " size=" + message.size);
} }

Loading…
Cancel
Save