mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
Merge remote-tracking branch 'upstream/master' into lite
This commit is contained in:
@@ -199,7 +199,7 @@ public class DcContext {
|
||||
public native int sendTextMsg (int chat_id, String text);
|
||||
public native int sendVideochatInvitation(int chat_id);
|
||||
public native boolean sendWebxdcStatusUpdate(int msg_id, String payload, String descr);
|
||||
public native String getWebxdcStatusUpdates(int msg_id, int status_update_id);
|
||||
public native String getWebxdcStatusUpdates(int msg_id, int last_known_serial);
|
||||
public native int addDeviceMsg (String label, DcMsg msg);
|
||||
public native boolean wasDeviceMsgEverAdded(String label);
|
||||
public DcLot checkQr (String qr) { return new DcLot(checkQrCPtr(qr)); }
|
||||
|
||||
@@ -325,6 +325,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
initializeDraft();
|
||||
doReinitializeDraft = false;
|
||||
}
|
||||
|
||||
attachmentManager.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
*/
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import static com.b44t.messenger.DcContact.DC_CONTACT_ID_SELF;
|
||||
import static org.thoughtcrime.securesms.util.RelayUtil.setForwardingMessageIds;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
@@ -77,10 +80,6 @@ import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import static com.b44t.messenger.DcContact.DC_CONTACT_ID_SELF;
|
||||
import static org.thoughtcrime.securesms.util.RelayUtil.REQUEST_RELAY;
|
||||
import static org.thoughtcrime.securesms.util.RelayUtil.setForwardingMessageIds;
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
public class ConversationFragment extends MessageSelectorFragment
|
||||
{
|
||||
@@ -433,10 +432,10 @@ public class ConversationFragment extends MessageSelectorFragment
|
||||
}
|
||||
|
||||
private void handleForwardMessage(final Set<DcMsg> messageRecords) {
|
||||
Intent composeIntent = new Intent(getActivity(), ConversationListActivity.class);
|
||||
Intent composeIntent = new Intent();
|
||||
int[] msgIds = DcMsg.msgSetToIds(messageRecords);
|
||||
setForwardingMessageIds(composeIntent, msgIds);
|
||||
startActivityForResult(composeIntent, REQUEST_RELAY);
|
||||
ConversationListRelayingActivity.start(this, composeIntent);
|
||||
getActivity().overridePendingTransition(R.anim.slide_from_right, R.anim.fade_scale_out);
|
||||
}
|
||||
|
||||
@@ -670,7 +669,7 @@ public class ConversationFragment extends MessageSelectorFragment
|
||||
int index = 0;
|
||||
for(int pos = firstPos; pos <= lastPos; pos++) {
|
||||
DcMsg message = ((ConversationAdapter) list.getAdapter()).getMsg(pos);
|
||||
if (message.getFromId() != DC_CONTACT_ID_SELF && !message.isSeen()) {
|
||||
if (message.getFromId() != DC_CONTACT_ID_SELF) {
|
||||
ids[index] = message.getId();
|
||||
index++;
|
||||
}
|
||||
@@ -779,7 +778,7 @@ public class ConversationFragment extends MessageSelectorFragment
|
||||
else if(DozeReminder.isDozeReminderMsg(getContext(), messageRecord)) {
|
||||
DozeReminder.dozeReminderTapped(getContext());
|
||||
}
|
||||
else if(messageRecord.isInfo() && messageRecord.getParent() != null) {
|
||||
else if(messageRecord.isInfo() && messageRecord.getParent() != null && messageRecord.getParent().getType() == DcMsg.DC_MSG_WEBXDC) {
|
||||
scrollMaybeSmoothToMsgId(messageRecord.getParent().getId());
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -466,7 +466,7 @@ public class ConversationItem extends BaseConversationItem
|
||||
if (documentViewStub.resolved()) documentViewStub.get().setVisibility(View.GONE);
|
||||
if (stickerStub.resolved()) stickerStub.get().setVisibility(View.GONE);
|
||||
|
||||
webxdcViewStub.get().setWebxdc(messageRecord);
|
||||
webxdcViewStub.get().setWebxdc(messageRecord, "Webxdc");
|
||||
webxdcViewStub.get().setWebxdcClickListener(new ThumbnailClickListener());
|
||||
webxdcViewStub.get().setOnLongClickListener(passthroughClickListener);
|
||||
|
||||
|
||||
@@ -98,12 +98,8 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
||||
// it is not needed to keep all past update messages, however, when deleted, also the strings should be deleted.
|
||||
DcContext dcContext = DcHelper.getContext(this);
|
||||
DcMsg msg = new DcMsg(dcContext, DcMsg.DC_MSG_TEXT);
|
||||
msg.setText(getString(R.string.update_1_24_android) + " https://delta.chat/en/blog");
|
||||
dcContext.addDeviceMsg("update_1_24n_android", msg); // addDeviceMessage() makes sure, messages with the same id are not added twice
|
||||
|
||||
msg = new DcMsg(dcContext, DcMsg.DC_MSG_TEXT);
|
||||
msg.setText(getString(R.string.update_1_26));
|
||||
dcContext.addDeviceMsg("update_1_26c_android", msg); // addDeviceMessage() makes sure, messages with the same id are not added twice
|
||||
msg.setText(getString(R.string.update_1_28_android));
|
||||
dcContext.addDeviceMsg("update_1_28e_android", msg); // addDeviceMessage() makes sure, messages with the same id are not added twice
|
||||
|
||||
// create view
|
||||
setContentView(R.layout.conversation_list_activity);
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import static org.thoughtcrime.securesms.util.RelayUtil.REQUEST_RELAY;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
/**
|
||||
* "Relaying" means "Forwarding or Sharing".
|
||||
*
|
||||
* When forwarding or sharing, we show the ConversationListActivity to the user.
|
||||
* However, ConversationListActivity has `launchMode="singleTask"`, which means that this will
|
||||
* destroy the existing ConversationListActivity.
|
||||
*
|
||||
* In API 20-29, `startActivityForResult()` could be used instead of `startActivity()`
|
||||
* to override this behavior and get two instances of ConversationListActivity.
|
||||
*
|
||||
* As this is not possible anymore starting with API 30, we needed another solution, and created
|
||||
* this activity here.
|
||||
*
|
||||
* See https://github.com/deltachat/deltachat-android/issues/1704.
|
||||
*/
|
||||
|
||||
public class ConversationListRelayingActivity extends ConversationListActivity {
|
||||
public static void start(Fragment fragment, Intent intent) {
|
||||
intent.setComponent(new ComponentName(fragment.getContext(), ConversationListRelayingActivity.class));
|
||||
fragment.startActivityForResult(intent, REQUEST_RELAY);
|
||||
}
|
||||
|
||||
public static void start(Activity activity, Intent intent) {
|
||||
intent.setComponent(new ComponentName(activity, ConversationListRelayingActivity.class));
|
||||
activity.startActivityForResult(intent, REQUEST_RELAY);
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
@@ -27,6 +26,8 @@ import androidx.annotation.NonNull;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.soundcloud.android.crop.Crop;
|
||||
|
||||
import org.thoughtcrime.securesms.components.AvatarSelector;
|
||||
@@ -48,12 +49,12 @@ import org.thoughtcrime.securesms.util.Prefs;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
public class CreateProfileActivity extends BaseActionBarActivity implements EmojiKeyboardProvider.EmojiEventListener {
|
||||
|
||||
@@ -74,8 +75,10 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Emoj
|
||||
private View reveal;
|
||||
|
||||
private boolean fromWelcome;
|
||||
private boolean avatarChanged;
|
||||
private boolean imageLoaded;
|
||||
|
||||
private byte[] avatarBytes;
|
||||
private Bitmap avatarBmp;
|
||||
private AttachmentManager attachmentManager;
|
||||
|
||||
|
||||
@@ -94,6 +97,7 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Emoj
|
||||
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close_white_24dp);
|
||||
|
||||
attachmentManager = new AttachmentManager(this, () -> {});
|
||||
avatarChanged = false;
|
||||
initializeResources();
|
||||
initializeEmojiInput();
|
||||
initializeProfileName();
|
||||
@@ -170,49 +174,38 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Emoj
|
||||
|
||||
case Crop.REQUEST_CROP:
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
|
||||
new AsyncTask<Void, Void, byte[]>() {
|
||||
@Override
|
||||
protected byte[] doInBackground(Void... params) {
|
||||
try {
|
||||
try {
|
||||
Uri imageUri = Crop.getOutput(data);
|
||||
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
|
||||
return stream.toByteArray();
|
||||
} catch (Exception any) {
|
||||
Log.e(TAG, "could not send raw JPG to core. Using scaled JPG.", any);
|
||||
}
|
||||
BitmapUtil.ScaleResult result =
|
||||
BitmapUtil.createScaledBytes(CreateProfileActivity.this, Crop.getOutput(data), new ProfileMediaConstraints());
|
||||
return result.getBitmap();
|
||||
} catch (BitmapDecodingException e) {
|
||||
Log.w(TAG, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(byte[] result) {
|
||||
if (result != null) {
|
||||
avatarBytes = result;
|
||||
GlideApp.with(CreateProfileActivity.this)
|
||||
.load(avatarBytes)
|
||||
.skipMemoryCache(true)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.circleCrop()
|
||||
.into(avatar);
|
||||
} else {
|
||||
Toast.makeText(CreateProfileActivity.this, R.string.error, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
setAvatarView(data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setAvatarView(Intent data) {
|
||||
final Uri output = Crop.getOutput(data);
|
||||
final ProfileMediaConstraints constraints = new ProfileMediaConstraints();
|
||||
GlideApp.with(this)
|
||||
.asBitmap()
|
||||
.load(output)
|
||||
.skipMemoryCache(true)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.centerCrop()
|
||||
.override(constraints.getImageMaxWidth(this), constraints.getImageMaxHeight(this))
|
||||
.into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
|
||||
avatarChanged = true;
|
||||
imageLoaded = true;
|
||||
avatarBmp = resource;
|
||||
}
|
||||
});
|
||||
GlideApp.with(this)
|
||||
.load(output)
|
||||
.circleCrop()
|
||||
.skipMemoryCache(true)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.into(avatar);
|
||||
}
|
||||
|
||||
private void onFileSelected(Uri inputFile) {
|
||||
Uri outputFile = Uri.fromFile(new File(getCacheDir(), "cropped"));
|
||||
if (inputFile == null) {
|
||||
@@ -232,13 +225,6 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Emoj
|
||||
this.reveal = ViewUtil.findById(this, R.id.reveal);
|
||||
this.statusView = ViewUtil.findById(this, R.id.status_text);
|
||||
|
||||
this.avatar.setImageDrawable(new ResourceContactPhoto(R.drawable.ic_camera_alt_white_24dp).asDrawable(this, getResources().getColor(R.color.grey_400)));
|
||||
|
||||
this.avatar.setOnClickListener(view ->
|
||||
new AvatarSelector(this, LoaderManager.getInstance(this), new AvatarSelectedListener(), avatarBytes != null)
|
||||
.show(this, avatar)
|
||||
);
|
||||
|
||||
passwordAccountSettings.setOnClickListener(view -> {
|
||||
Intent intent = new Intent(this, RegistrationActivity.class);
|
||||
startActivity(intent);
|
||||
@@ -264,32 +250,21 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Emoj
|
||||
}
|
||||
|
||||
private void initializeProfileAvatar() {
|
||||
String address = DcHelper.get(this, DcHelper.CONFIG_ADDRESS);
|
||||
|
||||
if (AvatarHelper.getSelfAvatarFile(this).exists() && AvatarHelper.getSelfAvatarFile(this).length() > 0) {
|
||||
new AsyncTask<Void, Void, byte[]>() {
|
||||
@Override
|
||||
protected byte[] doInBackground(Void... params) {
|
||||
try {
|
||||
return Util.readFully(new FileInputStream(AvatarHelper.getSelfAvatarFile(CreateProfileActivity.this)));
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(byte[] result) {
|
||||
if (result != null) {
|
||||
avatarBytes = result;
|
||||
GlideApp.with(CreateProfileActivity.this)
|
||||
.load(result)
|
||||
.circleCrop()
|
||||
.into(avatar);
|
||||
}
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
File avatarFile = AvatarHelper.getSelfAvatarFile(this);
|
||||
if (avatarFile.exists() && avatarFile.length() > 0) {
|
||||
imageLoaded = true;
|
||||
GlideApp.with(this)
|
||||
.load(avatarFile)
|
||||
.circleCrop()
|
||||
.into(avatar);
|
||||
} else {
|
||||
imageLoaded = false;
|
||||
avatar.setImageDrawable(new ResourceContactPhoto(R.drawable.ic_camera_alt_white_24dp).asDrawable(this, getResources().getColor(R.color.grey_400)));
|
||||
}
|
||||
avatar.setOnClickListener(view ->
|
||||
new AvatarSelector(this, LoaderManager.getInstance(this), new AvatarSelectedListener(), imageLoaded)
|
||||
.show(this, avatar)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -337,12 +312,14 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Emoj
|
||||
DcHelper.set(context, DcHelper.CONFIG_DISPLAY_NAME, name);
|
||||
setStatusText();
|
||||
|
||||
try {
|
||||
AvatarHelper.setSelfAvatar(CreateProfileActivity.this, avatarBytes);
|
||||
Prefs.setProfileAvatarId(CreateProfileActivity.this, new SecureRandom().nextInt());
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
return false;
|
||||
if (avatarChanged) {
|
||||
try {
|
||||
AvatarHelper.setSelfAvatar(CreateProfileActivity.this, avatarBmp);
|
||||
Prefs.setProfileAvatarId(CreateProfileActivity.this, new SecureRandom().nextInt());
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -378,7 +355,9 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Emoj
|
||||
AttachmentManager.selectImage(CreateProfileActivity.this, REQUEST_CODE_AVATAR);
|
||||
break;
|
||||
case AvatarSelector.REMOVE_PHOTO:
|
||||
avatarBytes = null;
|
||||
avatarBmp = null;
|
||||
imageLoaded = false;
|
||||
avatarChanged = true;
|
||||
avatar.setImageDrawable(new ResourceContactPhoto(R.drawable.ic_camera_alt_white_24dp).asDrawable(CreateProfileActivity.this, getResources().getColor(R.color.grey_400)));
|
||||
break;
|
||||
case AvatarSelector.TAKE_PHOTO:
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import static org.thoughtcrime.securesms.util.RelayUtil.REQUEST_RELAY;
|
||||
import static org.thoughtcrime.securesms.util.RelayUtil.setSharedText;
|
||||
|
||||
import android.Manifest;
|
||||
@@ -263,11 +262,13 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity implement
|
||||
if (chatId != -1) {
|
||||
composeIntent = getBaseShareIntent(ConversationActivity.class);
|
||||
composeIntent.putExtra(EXTRA_CHAT_ID, chatId);
|
||||
RelayUtil.setSharedUris(composeIntent, resolvedExtras);
|
||||
startActivity(composeIntent);
|
||||
} else {
|
||||
composeIntent = getBaseShareIntent(ConversationListActivity.class);
|
||||
composeIntent = getBaseShareIntent(ConversationListRelayingActivity.class);
|
||||
RelayUtil.setSharedUris(composeIntent, resolvedExtras);
|
||||
ConversationListRelayingActivity.start(this, composeIntent);
|
||||
}
|
||||
RelayUtil.setSharedUris(composeIntent, resolvedExtras);
|
||||
startActivityForResult(composeIntent, REQUEST_RELAY);
|
||||
// We use startActivityForResult() here so that the conversations list is correctly updated. (hide "Device messages", ...)a
|
||||
// With startActivity() the list was not always updated before and after sharing and incorrectly showed or did not show the device talk.
|
||||
finish();
|
||||
|
||||
@@ -70,13 +70,15 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
|
||||
webSettings.setGeolocationEnabled(false);
|
||||
webSettings.setAllowFileAccessFromFileURLs(false);
|
||||
webSettings.setAllowUniversalAccessFromFileURLs(false);
|
||||
webSettings.setDatabaseEnabled(true);
|
||||
webSettings.setDomStorageEnabled(true);
|
||||
webView.addJavascriptInterface(new InternalJSApi(), "InternalJSApi");
|
||||
|
||||
// `msg_id` in the subdomain makes sure, different apps using same files do not share the same cache entry
|
||||
// (WebView may use a global cache shared across objects).
|
||||
// (a random-id would also work, but would need maintenance and does not add benefits as we regard the file-part interceptRequest() only,
|
||||
// also a random-id is not that useful for debugging)
|
||||
webView.loadUrl("webxdc://msg" + appMessageId + ".localhost/index.html");
|
||||
webView.loadUrl("https://acc" + dcContext.getAccountId() + "-msg" + appMessageId + ".localhost/index.html");
|
||||
|
||||
Util.runOnAnyBackgroundThread(() -> {
|
||||
JSONObject info = this.dcAppMsg.getWebxdcInfo();
|
||||
@@ -147,7 +149,7 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
|
||||
int eventId = event.getId();
|
||||
if ((eventId == DcContext.DC_EVENT_WEBXDC_STATUS_UPDATE && event.getData1Int() == dcAppMsg.getId())) {
|
||||
Log.i(TAG, "handleEvent");
|
||||
webView.loadUrl("javascript:window.__webxdcUpdate(" + event.getData2Int() + ");");
|
||||
webView.loadUrl("javascript:window.__webxdcUpdate();");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,9 +184,9 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
public String getStatusUpdates(int statusUpdateId) {
|
||||
public String getStatusUpdates(int lastKnownSerial) {
|
||||
Log.i(TAG, "getStatusUpdates");
|
||||
return WebxdcActivity.this.dcContext.getWebxdcStatusUpdates(WebxdcActivity.this.dcAppMsg.getId(), statusUpdateId);
|
||||
return WebxdcActivity.this.dcContext.getWebxdcStatusUpdates(WebxdcActivity.this.dcAppMsg.getId(), lastKnownSerial );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class WebxdcView extends FrameLayout {
|
||||
this.viewListener = listener;
|
||||
}
|
||||
|
||||
public void setWebxdc(final @NonNull DcMsg dcMsg)
|
||||
public void setWebxdc(final @NonNull DcMsg dcMsg, String defaultSummary)
|
||||
{
|
||||
try {
|
||||
JSONObject info = dcMsg.getWebxdcInfo();
|
||||
@@ -76,7 +76,7 @@ public class WebxdcView extends FrameLayout {
|
||||
// subtitle
|
||||
String summary = info.optString("summary");
|
||||
if (summary.isEmpty()) {
|
||||
summary = Util.getPrettyFileSize(dcMsg.getFilebytes()) + " Webxdc";
|
||||
summary = defaultSummary;
|
||||
}
|
||||
appSubtitle.setText(summary);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -7,7 +7,6 @@ import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.AppCompatEditText;
|
||||
import android.text.InputFilter;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiProvider.EmojiDrawable;
|
||||
@@ -30,7 +29,6 @@ public class EmojiEditText extends AppCompatEditText {
|
||||
if (!Prefs.isSystemEmojiPreferred(getContext())) {
|
||||
setFilters(appendEmojiFilter(this.getFilters()));
|
||||
}
|
||||
setImeOptions(getImeOptions() | EditorInfo.IME_FLAG_NO_FULLSCREEN);
|
||||
}
|
||||
|
||||
public void insertEmoji(String emoji) {
|
||||
|
||||
@@ -58,6 +58,7 @@ public class DcHelper {
|
||||
public static final String CONFIG_SENTBOX_WATCH = "sentbox_watch";
|
||||
public static final String CONFIG_MVBOX_WATCH = "mvbox_watch";
|
||||
public static final String CONFIG_MVBOX_MOVE = "mvbox_move";
|
||||
public static final String CONFIG_ONLY_FETCH_MVBOX = "only_fetch_mvbox";
|
||||
public static final String CONFIG_BCC_SELF = "bcc_self";
|
||||
public static final String CONFIG_SHOW_EMAILS = "show_emails";
|
||||
public static final String CONFIG_MEDIA_QUALITY = "media_quality";
|
||||
@@ -200,7 +201,11 @@ public class DcHelper {
|
||||
dcContext.setStockTranslation(117, context.getString(R.string.secure_join_started));
|
||||
dcContext.setStockTranslation(118, context.getString(R.string.secure_join_replies));
|
||||
dcContext.setStockTranslation(119, context.getString(R.string.qrshow_join_contact_hint));
|
||||
dcContext.setStockTranslation(120, context.getString(R.string.qrshow_join_group_hint));
|
||||
|
||||
// HACK: svg does not handle entities correctly and shows `"` as the text `quot;`.
|
||||
// until that is fixed, we fix the most obvious errors (core uses encode_minimal, so this does not affect so many characters)
|
||||
// cmp. https://github.com/deltachat/deltachat-android/issues/2187
|
||||
dcContext.setStockTranslation(120, context.getString(R.string.qrshow_join_group_hint).replace("\"", ""));
|
||||
}
|
||||
|
||||
public static File getImexDir() {
|
||||
|
||||
@@ -309,7 +309,7 @@ public class AttachmentManager {
|
||||
} else if (slide.hasDocument()) {
|
||||
if (slide.isWebxdcDocument()) {
|
||||
DcMsg instance = msg != null ? msg : DcHelper.getContext(context).getMsg(slide.dcMsgId);
|
||||
webxdcView.setWebxdc(instance);
|
||||
webxdcView.setWebxdc(instance, context.getString(R.string.videochat_tap_to_open));
|
||||
webxdcView.setWebxdcClickListener((v, s) -> {
|
||||
WebxdcActivity.openWebxdcActivity(context, instance);
|
||||
});
|
||||
@@ -399,6 +399,18 @@ public class AttachmentManager {
|
||||
return result;
|
||||
}
|
||||
|
||||
// should be called when the attachement manager comes into view again.
|
||||
// if the attachment manager contains a webxdc, its summary is updated.
|
||||
public void onResume() {
|
||||
if (slide.isPresent()) {
|
||||
if (slide.get().isWebxdcDocument()) {
|
||||
if (webxdcView != null) {
|
||||
webxdcView.setWebxdc(DcHelper.getContext(context).getMsg(slide.get().dcMsgId), context.getString(R.string.videochat_tap_to_open));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAttachmentPresent() {
|
||||
return attachmentViewStub.resolved() && attachmentViewStub.get().getVisibility() == View.VISIBLE;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
package org.thoughtcrime.securesms.preferences;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
import static android.text.InputType.TYPE_TEXT_VARIATION_URI;
|
||||
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_BCC_SELF;
|
||||
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_E2EE_ENABLED;
|
||||
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_MVBOX_MOVE;
|
||||
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_ONLY_FETCH_MVBOX;
|
||||
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_SENTBOX_WATCH;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
@@ -32,13 +40,6 @@ import org.thoughtcrime.securesms.util.ScreenLockUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.views.ProgressDialog;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
import static android.text.InputType.TYPE_TEXT_VARIATION_URI;
|
||||
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_BCC_SELF;
|
||||
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_E2EE_ENABLED;
|
||||
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_MVBOX_MOVE;
|
||||
import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_SENTBOX_WATCH;
|
||||
|
||||
|
||||
public class AdvancedPreferenceFragment extends ListSummaryPreferenceFragment
|
||||
implements DcEventCenter.DcEventDelegate
|
||||
@@ -52,6 +53,7 @@ public class AdvancedPreferenceFragment extends ListSummaryPreferenceFragment
|
||||
CheckBoxPreference sentboxWatchCheckbox;
|
||||
CheckBoxPreference bccSelfCheckbox;
|
||||
CheckBoxPreference mvboxMoveCheckbox;
|
||||
CheckBoxPreference onlyFetchMvboxCheckbox;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle paramBundle) {
|
||||
@@ -82,10 +84,21 @@ public class AdvancedPreferenceFragment extends ListSummaryPreferenceFragment
|
||||
mvboxMoveCheckbox = (CheckBoxPreference) this.findPreference("pref_mvbox_move");
|
||||
mvboxMoveCheckbox.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
DcHelper.getAccounts(getContext()).stopIo();
|
||||
dcContext.setConfigInt(CONFIG_MVBOX_MOVE, enabled? 1 : 0);
|
||||
DcHelper.getAccounts(getContext()).startIo();
|
||||
return true;
|
||||
});
|
||||
|
||||
onlyFetchMvboxCheckbox = this.findPreference("pref_only_fetch_mvbox");
|
||||
onlyFetchMvboxCheckbox.setOnPreferenceChangeListener(((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
DcHelper.getAccounts(getContext()).stopIo();
|
||||
dcContext.setConfigInt(CONFIG_ONLY_FETCH_MVBOX, enabled? 1 : 0);
|
||||
DcHelper.getAccounts(getContext()).startIo();
|
||||
return true;
|
||||
}));
|
||||
|
||||
Preference manageKeys = this.findPreference("pref_manage_keys");
|
||||
manageKeys.setOnPreferenceClickListener(new ManageKeysListener());
|
||||
|
||||
@@ -137,6 +150,7 @@ public class AdvancedPreferenceFragment extends ListSummaryPreferenceFragment
|
||||
sentboxWatchCheckbox.setChecked(0!=dcContext.getConfigInt(CONFIG_SENTBOX_WATCH));
|
||||
bccSelfCheckbox.setChecked(0!=dcContext.getConfigInt(CONFIG_BCC_SELF));
|
||||
mvboxMoveCheckbox.setChecked(0!=dcContext.getConfigInt(CONFIG_MVBOX_MOVE));
|
||||
onlyFetchMvboxCheckbox.setChecked(0!=dcContext.getConfigInt(CONFIG_ONLY_FETCH_MVBOX));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -42,13 +42,13 @@ public class AvatarHelper {
|
||||
return new File(dirString);
|
||||
}
|
||||
|
||||
public static void setSelfAvatar(@NonNull Context context, @Nullable byte[] data) throws IOException {
|
||||
if (data == null) {
|
||||
public static void setSelfAvatar(@NonNull Context context, @Nullable Bitmap bitmap) throws IOException {
|
||||
if (bitmap == null) {
|
||||
DcHelper.set(context, DcHelper.CONFIG_SELF_AVATAR, null);
|
||||
} else {
|
||||
File avatar = File.createTempFile("selfavatar", ".jpg", context.getCacheDir());
|
||||
FileOutputStream out = new FileOutputStream(avatar);
|
||||
out.write(data);
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
|
||||
out.close();
|
||||
DcHelper.set(context, DcHelper.CONFIG_SELF_AVATAR, avatar.getPath()); // The avatar is copied to the blobs directory here...
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
|
||||
@@ -163,9 +163,7 @@ public class SearchFragment extends Fragment implements SearchListAdapter.EventL
|
||||
if (conversationList != null) {
|
||||
DcContext dcContext = DcHelper.getContext(getContext());
|
||||
int chatId = message.getChatId();
|
||||
int msgId = message.getId();
|
||||
int startingPosition = DcMsg.getMessagePosition(message, dcContext);
|
||||
int msgs[] = dcContext.getChatMsgs(chatId, 0, 0);
|
||||
conversationList.openConversation(chatId, startingPosition);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,9 @@ public class MediaUtil {
|
||||
if (type == null) {
|
||||
final String extension = MimeTypeMap.getFileExtensionFromUrl(uri.toString());
|
||||
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
|
||||
if (type == null) {
|
||||
type = "application/octet-stream";
|
||||
}
|
||||
}
|
||||
return getCorrectedMimeType(type);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user