Added unsubscribe button

This commit is contained in:
M66B
2019-09-08 12:57:21 +02:00
parent da265bcc86
commit d9d601ef4a
9 changed files with 1945 additions and 7 deletions

View File

@@ -304,6 +304,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
private ImageButton ibFull;
private ImageButton ibImages;
private ImageButton ibUnsubscribe;
private ImageButton ibDecrypt;
private TextView tvBody;
@@ -447,6 +448,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibFull = vsBody.findViewById(R.id.ibFull);
ibImages = vsBody.findViewById(R.id.ibImages);
ibUnsubscribe = vsBody.findViewById(R.id.ibUnsubscribe);
ibDecrypt = vsBody.findViewById(R.id.ibDecrypt);
tvBody = vsBody.findViewById(R.id.tvBody);
@@ -516,6 +518,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibFull.setOnClickListener(this);
ibImages.setOnClickListener(this);
ibUnsubscribe.setOnClickListener(this);
ibDecrypt.setOnClickListener(this);
tvBody.setOnTouchListener(this);
@@ -566,6 +569,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibFull.setOnClickListener(null);
ibImages.setOnClickListener(null);
ibUnsubscribe.setOnClickListener(null);
ibDecrypt.setOnClickListener(null);
tvBody.setOnTouchListener(null);
@@ -910,6 +914,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibFull.setVisibility(View.GONE);
ibImages.setVisibility(View.GONE);
ibUnsubscribe.setVisibility(View.GONE);
ibDecrypt.setVisibility(View.GONE);
tvBody.setVisibility(View.GONE);
@@ -978,6 +983,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
ibFull.setVisibility(View.GONE);
ibImages.setVisibility(View.GONE);
ibUnsubscribe.setVisibility(message.unsubscribe == null ? View.GONE : View.VISIBLE);
if (textSize != 0) {
float size = properties.getSize(message.id, textSize);
@@ -1512,6 +1518,9 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
case R.id.ibImages:
onShowImages(message);
break;
case R.id.ibUnsubscribe:
onActionUnsubscribe(message);
break;
case R.id.ibDecrypt:
onActionDecrypt(message);
break;
@@ -2101,6 +2110,11 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
}.execute(context, owner, args, "show:images");
}
private void onActionUnsubscribe(TupleMessageEx message) {
Uri uri = Uri.parse(message.unsubscribe);
onOpenLink(uri, context.getString(R.string.title_legend_show_unsubscribe));
}
private void onActionDecrypt(TupleMessageEx message) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
lbm.sendBroadcast(

View File

@@ -1477,6 +1477,7 @@ class Core {
message.bcc = helper.getBcc();
message.reply = helper.getReply();
message.list_post = helper.getListPost();
message.unsubscribe = helper.getListUnsubscribe();
message.subject = helper.getSubject();
message.size = helper.getSize();
message.content = false;

View File

@@ -58,7 +58,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
// https://developer.android.com/topic/libraries/architecture/room.html
@Database(
version = 99,
version = 100,
entities = {
EntityIdentity.class,
EntityAccount.class,
@@ -999,6 +999,13 @@ public abstract class DB extends RoomDatabase {
db.execSQL("ALTER TABLE `message` ADD COLUMN `signature` INTEGER NOT NULL DEFAULT 1");
}
})
.addMigrations(new Migration(99, 100) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {
Log.i("DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `message` ADD COLUMN `unsubscribe` TEXT");
}
})
.build();
}

View File

@@ -108,6 +108,7 @@ public class EntityMessage implements Serializable {
public Address[] bcc;
public Address[] reply;
public Address[] list_post;
public String unsubscribe;
public String headers;
public Boolean raw;
public String subject;

View File

@@ -22,6 +22,7 @@ package eu.faircode.email;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.MailTo;
import android.net.Uri;
import android.text.TextUtils;
import android.webkit.MimeTypeMap;
@@ -548,19 +549,20 @@ public class MessageHelper {
return null;
list = MimeUtility.unfold(list);
list = decodeMime(list);
// List-Post: NO (posting not allowed on this list)
if (list != null && list.startsWith("NO"))
return null;
// https://www.ietf.org/rfc/rfc2368.txt
for (String _to : list.split(",")) {
String to = _to.trim();
int lt = to.indexOf("<");
int gt = to.lastIndexOf(">");
for (String entry : list.split(",")) {
entry = entry.trim();
int lt = entry.indexOf("<");
int gt = entry.lastIndexOf(">");
if (lt >= 0 && gt > lt)
try {
MailTo mailto = MailTo.parse(to.substring(lt + 1, gt));
MailTo mailto = MailTo.parse(entry.substring(lt + 1, gt));
if (mailto.getTo() != null)
return new Address[]{new InternetAddress(mailto.getTo().split(",")[0])};
} catch (android.net.ParseException ex) {
@@ -576,6 +578,42 @@ public class MessageHelper {
}
}
String getListUnsubscribe() throws MessagingException {
String list;
try {
// https://www.ietf.org/rfc/rfc2369.txt
list = imessage.getHeader("List-Unsubscribe", null);
if (list == null)
return null;
list = MimeUtility.unfold(list);
list = decodeMime(list);
if (list != null && list.startsWith("NO"))
return null;
for (String entry : list.split(",")) {
entry = entry.trim();
int lt = entry.indexOf("<");
int gt = entry.lastIndexOf(">");
if (lt >= 0 && gt > lt) {
String unsubscribe = entry.substring(lt + 1, gt);
Uri uri = Uri.parse(unsubscribe);
String scheme = uri.getScheme();
if ("mailto".equals(scheme) ||
"http".equals(scheme) || "https".equals(scheme))
return unsubscribe;
}
}
Log.w(new IllegalArgumentException("List-Unsubscribe: " + list));
return null;
} catch (AddressException ex) {
Log.w(ex);
return null;
}
}
String getSubject() throws MessagingException {
String subject = imessage.getHeader("Subject", null);
if (subject == null)