mirror of
https://github.com/M66B/FairEmail.git
synced 2025-03-04 02:28:18 +00:00
parent
f813f1669f
commit
7b74f87e0f
4 changed files with 78 additions and 3 deletions
2
FAQ.md
2
FAQ.md
|
@ -14,7 +14,7 @@ If you have a question, please check the frequently asked questions below first.
|
|||
* 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
|
||||
* Optional: read your contacts (READ_CONTACTS): to autocomplete addresses
|
||||
* 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
|
||||
|
||||
<a name="FAQ2"></a>
|
||||
|
|
|
@ -19,11 +19,19 @@ package eu.faircode.email;
|
|||
Copyright 2018 by Marcel Bokhorst (M66B)
|
||||
*/
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.ContactsContract;
|
||||
import android.text.format.DateUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
|
@ -35,13 +43,17 @@ import android.widget.ProgressBar;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.mail.internet.InternetAddress;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.PopupMenu;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
@ -55,6 +67,7 @@ public class AdapterMessage extends PagedListAdapter<TupleMessageEx, AdapterMess
|
|||
private ViewType viewType;
|
||||
|
||||
private boolean debug;
|
||||
private boolean hasContactsPermission;
|
||||
private DateFormat df = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.LONG);
|
||||
|
||||
enum ViewType {UNIFIED, FOLDER, THREAD, SEARCH}
|
||||
|
@ -62,6 +75,7 @@ public class AdapterMessage extends PagedListAdapter<TupleMessageEx, AdapterMess
|
|||
public class ViewHolder extends RecyclerView.ViewHolder
|
||||
implements View.OnClickListener, View.OnLongClickListener {
|
||||
View itemView;
|
||||
ImageView ivAvatar;
|
||||
ImageView ivFlagged;
|
||||
TextView tvFrom;
|
||||
TextView tvTime;
|
||||
|
@ -80,6 +94,7 @@ public class AdapterMessage extends PagedListAdapter<TupleMessageEx, AdapterMess
|
|||
super(itemView);
|
||||
|
||||
this.itemView = itemView;
|
||||
ivAvatar = itemView.findViewById(R.id.ivAvatar);
|
||||
ivFlagged = itemView.findViewById(R.id.ivFlagged);
|
||||
tvFrom = itemView.findViewById(R.id.tvFrom);
|
||||
tvTime = itemView.findViewById(R.id.tvTime);
|
||||
|
@ -119,6 +134,54 @@ public class AdapterMessage extends PagedListAdapter<TupleMessageEx, AdapterMess
|
|||
private void bindTo(final TupleMessageEx message) {
|
||||
pbLoading.setVisibility(View.GONE);
|
||||
|
||||
ivAvatar.setVisibility(View.GONE);
|
||||
if (hasContactsPermission && message.from != null && message.from.length > 0) {
|
||||
itemView.setHasTransientState(true);
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putSerializable("from", message.from[0]);
|
||||
|
||||
new SimpleTask<Drawable>() {
|
||||
@Override
|
||||
protected Drawable onLoad(Context context, Bundle args) {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
InternetAddress from = (InternetAddress) args.getSerializable("from");
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
cursor = resolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,
|
||||
new String[]{ContactsContract.CommonDataKinds.Photo.CONTACT_ID},
|
||||
ContactsContract.CommonDataKinds.Email.ADDRESS + " = ?",
|
||||
new String[]{from.getAddress()}, null);
|
||||
if (cursor.moveToNext()) {
|
||||
int colContactId = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Photo.CONTACT_ID);
|
||||
long contactId = cursor.getLong(colContactId);
|
||||
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
|
||||
InputStream is = ContactsContract.Contacts.openContactPhotoInputStream(resolver, uri);
|
||||
return Drawable.createFromStream(is, from.getPersonal());
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLoaded(Bundle args, Drawable photo) {
|
||||
if (photo != null) {
|
||||
ivAvatar.setImageDrawable(photo);
|
||||
ivAvatar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
itemView.setHasTransientState(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onException(Bundle args, Throwable ex) {
|
||||
itemView.setHasTransientState(false);
|
||||
}
|
||||
}.load(context, owner, args);
|
||||
}
|
||||
|
||||
ivFlagged.setVisibility(message.ui_flagged ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (EntityFolder.DRAFTS.equals(message.folderType) ||
|
||||
|
@ -276,6 +339,7 @@ public class AdapterMessage extends PagedListAdapter<TupleMessageEx, AdapterMess
|
|||
this.context = context;
|
||||
this.owner = owner;
|
||||
this.viewType = viewType;
|
||||
this.hasContactsPermission = (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED);
|
||||
this.debug = PreferenceManager.getDefaultSharedPreferences(context).getBoolean("debug", false);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,17 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/tvFrom" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivAvatar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:src="@drawable/baseline_person_24"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tvFrom"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintStart_toEndOf="@id/ivFlagged"
|
||||
app:layout_constraintTop_toTopOf="@+id/tvFrom" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvFrom"
|
||||
android:layout_width="0dp"
|
||||
|
@ -27,7 +38,7 @@
|
|||
android:text="From"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
app:layout_constraintEnd_toStartOf="@+id/tvTime"
|
||||
app:layout_constraintStart_toEndOf="@id/ivFlagged"
|
||||
app:layout_constraintStart_toEndOf="@id/ivAvatar"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<string name="title_setup_doze_instructions">In the next dialog, select \"All apps\" at the top, select this app and select and confirm \"Don\'t optimize\"</string>
|
||||
<string name="title_setup_data">Disable data saving</string>
|
||||
<string name="title_setup_permissions">Grant permissions</string>
|
||||
<string name="title_setup_permissions_remark">To autocomplete addresses (optional)</string>
|
||||
<string name="title_setup_permissions_remark">To get contact information (optional)</string>
|
||||
<string name="title_setup_to_do">To do</string>
|
||||
<string name="title_setup_done">Done</string>
|
||||
<string name="title_setup_light_theme">Light theme</string>
|
||||
|
|
Loading…
Add table
Reference in a new issue