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:
@@ -31,6 +31,7 @@ public class DcChat {
|
||||
public native int getType ();
|
||||
public native int getVisibility ();
|
||||
public native String getName ();
|
||||
public native String getMailinglistAddr();
|
||||
public native String getProfileImage ();
|
||||
public native int getColor ();
|
||||
public native boolean isUnpromoted ();
|
||||
|
||||
@@ -52,6 +52,10 @@ public class DcMsg {
|
||||
this.msgCPtr = msgCPtr;
|
||||
}
|
||||
|
||||
public boolean isOk() {
|
||||
return msgCPtr != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
|
||||
@@ -320,6 +320,7 @@ public class ConversationFragment extends MessageSelectorFragment
|
||||
menu.findItem(R.id.menu_context_share).setVisible(false);
|
||||
menu.findItem(R.id.menu_context_reply).setVisible(false);
|
||||
menu.findItem(R.id.menu_context_reply_privately).setVisible(false);
|
||||
menu.findItem(R.id.menu_add_to_home_screen).setVisible(false);
|
||||
} else {
|
||||
DcMsg messageRecord = messageRecords.iterator().next();
|
||||
DcChat chat = getListAdapter().getChat();
|
||||
@@ -329,17 +330,26 @@ public class ConversationFragment extends MessageSelectorFragment
|
||||
menu.findItem(R.id.menu_context_reply).setVisible(chat.canSend() && canReply);
|
||||
boolean showReplyPrivately = chat.isMultiUser() && !messageRecord.isOutgoing() && canReply;
|
||||
menu.findItem(R.id.menu_context_reply_privately).setVisible(showReplyPrivately);
|
||||
menu.findItem(R.id.menu_add_to_home_screen).setVisible(messageRecord.getType() == DcMsg.DC_MSG_WEBXDC);
|
||||
}
|
||||
|
||||
// if one of the selected items cannot be saved, disable saving.
|
||||
boolean canSave = true;
|
||||
// if one of the selected items is not from self, disable resending.
|
||||
boolean canResend = true;
|
||||
for (DcMsg messageRecord : messageRecords) {
|
||||
if (!messageRecord.hasFile()) {
|
||||
if (canSave && !messageRecord.hasFile()) {
|
||||
canSave = false;
|
||||
}
|
||||
if (canResend && !messageRecord.isOutgoing()) {
|
||||
canResend = false;
|
||||
}
|
||||
if (!canSave && !canResend) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
menu.findItem(R.id.menu_context_save_attachment).setVisible(canSave);
|
||||
menu.findItem(R.id.menu_resend).setVisible(canResend);
|
||||
}
|
||||
|
||||
static boolean canReplyToMsg(DcMsg dcMsg) {
|
||||
@@ -918,6 +928,10 @@ public class ConversationFragment extends MessageSelectorFragment
|
||||
handleForwardMessage(getListAdapter().getSelectedItems());
|
||||
actionMode.finish();
|
||||
return true;
|
||||
case R.id.menu_add_to_home_screen:
|
||||
WebxdcActivity.addToHomeScreen(getActivity(), getSelectedMessageRecord(getListAdapter().getSelectedItems()).getId());
|
||||
actionMode.finish();
|
||||
return true;
|
||||
case R.id.menu_context_save_attachment:
|
||||
handleSaveAttachment(getListAdapter().getSelectedItems());
|
||||
return true;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
@@ -57,17 +58,17 @@ public class ConversationTitleView extends RelativeLayout {
|
||||
}
|
||||
|
||||
public void setTitle(@NonNull GlideRequests glideRequests, @NonNull DcChat dcChat) {
|
||||
setTitle(glideRequests, dcChat, true);
|
||||
setTitle(glideRequests, dcChat, false);
|
||||
}
|
||||
|
||||
public void setTitle(@NonNull GlideRequests glideRequests, @NonNull DcChat dcChat, boolean showAddInfo) {
|
||||
public void setTitle(@NonNull GlideRequests glideRequests, @NonNull DcChat dcChat, boolean profileView) {
|
||||
final int chatId = dcChat.getId();
|
||||
final Context context = getContext();
|
||||
final DcContext dcContext = DcHelper.getContext(context);
|
||||
|
||||
// set title and subtitle texts
|
||||
title.setText(dcChat.getName());
|
||||
String subtitleStr = "ErrSubtitle";
|
||||
String subtitleStr = null;
|
||||
|
||||
// set icons etc.
|
||||
int imgLeft = 0;
|
||||
@@ -82,11 +83,19 @@ public class ConversationTitleView extends RelativeLayout {
|
||||
|
||||
int[] chatContacts = dcContext.getChatContacts(chatId);
|
||||
if (dcChat.isMailingList()) {
|
||||
subtitleStr = context.getString(R.string.mailing_list);
|
||||
if (profileView) {
|
||||
subtitleStr = dcChat.getMailinglistAddr();
|
||||
} else {
|
||||
subtitleStr = context.getString(R.string.mailing_list);
|
||||
}
|
||||
} else if (dcChat.isBroadcast()) {
|
||||
subtitleStr = context.getResources().getQuantityString(R.plurals.n_recipients, chatContacts.length, chatContacts.length);
|
||||
if (!profileView) {
|
||||
subtitleStr = context.getResources().getQuantityString(R.plurals.n_recipients, chatContacts.length, chatContacts.length);
|
||||
}
|
||||
} else if( dcChat.isMultiUser() ) {
|
||||
subtitleStr = context.getResources().getQuantityString(R.plurals.n_members, chatContacts.length, chatContacts.length);
|
||||
if (!profileView) {
|
||||
subtitleStr = context.getResources().getQuantityString(R.plurals.n_members, chatContacts.length, chatContacts.length);
|
||||
}
|
||||
} else if( chatContacts.length>=1 ) {
|
||||
if( dcChat.isSelfTalk() ) {
|
||||
subtitleStr = context.getString(R.string.chat_self_talk_subtitle);
|
||||
@@ -107,10 +116,14 @@ public class ConversationTitleView extends RelativeLayout {
|
||||
|
||||
avatar.setAvatar(glideRequests, new Recipient(getContext(), dcChat), false);
|
||||
title.setCompoundDrawablesWithIntrinsicBounds(imgLeft, 0, imgRight, 0);
|
||||
subtitle.setVisibility(showAddInfo? View.VISIBLE : View.GONE);
|
||||
|
||||
if (!TextUtils.isEmpty(subtitleStr)) {
|
||||
subtitle.setText(subtitleStr);
|
||||
subtitle.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
subtitle.setVisibility(View.GONE);
|
||||
}
|
||||
boolean isEphemeral = dcContext.getChatEphemeralTimer(chatId) != 0;
|
||||
ephemeralIcon.setVisibility((showAddInfo && isEphemeral)? View.VISIBLE : View.GONE);
|
||||
ephemeralIcon.setVisibility(isEphemeral? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
public void setTitle(@NonNull GlideRequests glideRequests, @NonNull DcContact contact) {
|
||||
|
||||
@@ -259,7 +259,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
||||
}
|
||||
else if (chatId > 0) {
|
||||
DcChat dcChat = dcContext.getChat(chatId);
|
||||
titleView.setTitle(GlideApp.with(this), dcChat, isContactProfile());
|
||||
titleView.setTitle(GlideApp.with(this), dcChat, true);
|
||||
}
|
||||
else if (isContactProfile()){
|
||||
titleView.setTitle(GlideApp.with(this), dcContext.getContact(contactId));
|
||||
@@ -362,7 +362,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
|
||||
return getString(R.string.tab_gallery);
|
||||
|
||||
case TAB_DOCS:
|
||||
return getString(R.string.tab_docs);
|
||||
return getString(R.string.files);
|
||||
|
||||
case TAB_LINKS:
|
||||
return getString(R.string.tab_links);
|
||||
|
||||
@@ -182,6 +182,9 @@ public class ProfileDocumentsFragment
|
||||
menu.findItem(R.id.details).setVisible(singleSelection);
|
||||
menu.findItem(R.id.show_in_chat).setVisible(singleSelection);
|
||||
menu.findItem(R.id.share).setVisible(singleSelection);
|
||||
|
||||
boolean webxdcApp = singleSelection && messageRecords.iterator().next().getType() == DcMsg.DC_MSG_WEBXDC;
|
||||
menu.findItem(R.id.menu_add_to_home_screen).setVisible(webxdcApp);
|
||||
}
|
||||
|
||||
private ProfileDocumentsAdapter getListAdapter() {
|
||||
@@ -225,6 +228,10 @@ public class ProfileDocumentsFragment
|
||||
case R.id.share:
|
||||
handleShare(getSelectedMessageRecord(getListAdapter().getSelectedMedia()));
|
||||
return true;
|
||||
case R.id.menu_add_to_home_screen:
|
||||
WebxdcActivity.addToHomeScreen(getActivity(), getSelectedMessageRecord(getListAdapter().getSelectedMedia()).getId());
|
||||
mode.finish();
|
||||
return true;
|
||||
case R.id.show_in_chat:
|
||||
handleShowInChat(getSelectedMessageRecord(getListAdapter().getSelectedMedia()));
|
||||
return true;
|
||||
|
||||
@@ -61,6 +61,7 @@ import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
|
||||
import org.thoughtcrime.securesms.util.views.ProgressDialog;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class RegistrationActivity extends BaseActionBarActivity implements DcEventCenter.DcEventDelegate {
|
||||
@@ -233,23 +234,19 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
|
||||
int id = item.getItemId();
|
||||
|
||||
if (id == R.id.do_register) {
|
||||
// "log in" button clicked - even if oauth2DeclinedByUser is true,
|
||||
// we will ask for oauth2 to allow reverting the decision.
|
||||
checkOauth2start().addListener(new ListenableFuture.Listener<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(Boolean oauth2started) {
|
||||
if(!oauth2started) {
|
||||
updateProviderInfo();
|
||||
onLogin();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(ExecutionException e) {
|
||||
updateProviderInfo();
|
||||
onLogin();
|
||||
}
|
||||
});
|
||||
String oldAddr = DcHelper.getSelfAddr(this);
|
||||
String newAddr = emailInput.getText().toString();
|
||||
if (!TextUtils.isEmpty(oldAddr)
|
||||
&& !TextUtils.equals(oldAddr.toLowerCase(Locale.ROOT), newAddr.toLowerCase(Locale.ROOT))) {
|
||||
// Tell the user about AEAP if they are about to change their address
|
||||
new AlertDialog.Builder(this)
|
||||
.setMessage(getString(R.string.aeap_explanation, oldAddr, newAddr))
|
||||
.setNegativeButton(R.string.cancel, (d, w) -> {})
|
||||
.setPositiveButton(R.string.perm_continue, (d, w) -> do_register())
|
||||
.show();
|
||||
} else {
|
||||
do_register();
|
||||
}
|
||||
return true;
|
||||
} else if (id == android.R.id.home) {
|
||||
// handle close button click here
|
||||
@@ -259,6 +256,26 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void do_register() {
|
||||
// "log in" button clicked - even if oauth2DeclinedByUser is true,
|
||||
// we will ask for oauth2 to allow reverting the decision.
|
||||
checkOauth2start().addListener(new ListenableFuture.Listener<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(Boolean oauth2started) {
|
||||
if(!oauth2started) {
|
||||
updateProviderInfo();
|
||||
onLogin();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(ExecutionException e) {
|
||||
updateProviderInfo();
|
||||
onLogin();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
@@ -17,6 +21,10 @@ import android.webkit.WebView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.TaskStackBuilder;
|
||||
import androidx.core.content.pm.ShortcutInfoCompat;
|
||||
import androidx.core.content.pm.ShortcutManagerCompat;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
|
||||
import com.b44t.messenger.DcChat;
|
||||
import com.b44t.messenger.DcContext;
|
||||
@@ -41,20 +49,43 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
|
||||
private String baseURL;
|
||||
private String sourceCodeUrl = "";
|
||||
|
||||
|
||||
|
||||
public static void openWebxdcActivity(Context context, DcMsg instance) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (Prefs.isDeveloperModeEnabled(context)) {
|
||||
WebView.setWebContentsDebuggingEnabled(true);
|
||||
}
|
||||
|
||||
Intent intent =new Intent(context, WebxdcActivity.class);
|
||||
intent.putExtra("appMessageId", instance.getId());
|
||||
context.startActivity(intent);
|
||||
context.startActivity(getWebxdcIntent(context, instance.getId()));
|
||||
} else {
|
||||
Toast.makeText(context, "At least Android 5.0 (Lollipop) required for Webxdc.", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
private static Intent getWebxdcIntent(Context context, int msgId) {
|
||||
DcContext dcContext = DcHelper.getContext(context);
|
||||
Intent intent = new Intent(context, WebxdcActivity.class);
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
intent.putExtra("accountId", dcContext.getAccountId());
|
||||
intent.putExtra("appMessageId", msgId);
|
||||
return intent;
|
||||
}
|
||||
|
||||
private static Intent[] getWebxdcIntentWithParentStack(Context context, int msgId) {
|
||||
DcContext dcContext = DcHelper.getContext(context);
|
||||
|
||||
final Intent chatIntent = new Intent(context, ConversationActivity.class)
|
||||
.putExtra(ConversationActivity.CHAT_ID_EXTRA, dcContext.getMsg(msgId).getChatId())
|
||||
.setAction(Intent.ACTION_VIEW);
|
||||
|
||||
final Intent webxdcIntent = getWebxdcIntent(context, msgId);
|
||||
|
||||
return TaskStackBuilder.create(context)
|
||||
.addNextIntentWithParentStack(chatIntent)
|
||||
.addNextIntent(webxdcIntent)
|
||||
.getIntents();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle state, boolean ready) {
|
||||
super.onCreate(state, ready);
|
||||
@@ -65,7 +96,19 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
|
||||
int appMessageId = b.getInt("appMessageId");
|
||||
|
||||
this.dcContext = DcHelper.getContext(getApplicationContext());
|
||||
if (dcContext.getAccountId() != b.getInt("accountId")) {
|
||||
Toast.makeText(this, "Switch to belonging account first.", Toast.LENGTH_LONG).show();
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
this.dcAppMsg = this.dcContext.getMsg(appMessageId);
|
||||
if (!this.dcAppMsg.isOk()) {
|
||||
Toast.makeText(this, "Webxdc does no longer exist.", Toast.LENGTH_LONG).show();
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// `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,
|
||||
@@ -107,6 +150,9 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
super.onOptionsItemSelected(item);
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_add_to_home_screen:
|
||||
addToHomeScreen(this, dcAppMsg.getId());
|
||||
return true;
|
||||
case R.id.source_code:
|
||||
openUrlInBrowser(this, sourceCodeUrl);
|
||||
return true;
|
||||
@@ -192,6 +238,36 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
|
||||
});
|
||||
}
|
||||
|
||||
public static void addToHomeScreen(Activity activity, int msgId) {
|
||||
Context context = activity.getApplicationContext();
|
||||
try {
|
||||
DcContext dcContext = DcHelper.getContext(context);
|
||||
DcMsg msg = dcContext.getMsg(msgId);
|
||||
final JSONObject info = msg.getWebxdcInfo();
|
||||
|
||||
final String docName = JsonUtils.optString(info, "document");
|
||||
final String xdcName = JsonUtils.optString(info, "name");
|
||||
byte[] blob = msg.getWebxdcBlob(JsonUtils.optString(info, "icon"));
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(blob);
|
||||
BitmapDrawable drawable = (BitmapDrawable) Drawable.createFromStream(is, "icon");
|
||||
Bitmap bitmap = drawable.getBitmap();
|
||||
|
||||
ShortcutInfoCompat shortcutInfoCompat = new ShortcutInfoCompat.Builder(context, "xdc-" + dcContext.getAccountId() + "-" + msgId)
|
||||
.setShortLabel(docName.isEmpty() ? xdcName : docName)
|
||||
.setIcon(IconCompat.createWithAdaptiveBitmap(bitmap))
|
||||
.setIntents(getWebxdcIntentWithParentStack(context, msgId))
|
||||
.build();
|
||||
|
||||
if (ShortcutManagerCompat.requestPinShortcut(context, shortcutInfoCompat, null)) {
|
||||
Toast.makeText(context, R.string.done, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(context, "ErrAddToHomescreen: requestPinShortcut() failed", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
} catch(Exception e) {
|
||||
Toast.makeText(context, "ErrAddToHomescreen: " + e, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
class InternalJSApi {
|
||||
@JavascriptInterface
|
||||
public String selfAddr() {
|
||||
|
||||
@@ -39,6 +39,7 @@ public class DcHelper {
|
||||
private static final String TAG = DcHelper.class.getSimpleName();
|
||||
|
||||
public static final String CONFIG_ADDRESS = "addr";
|
||||
public static final String CONFIG_CONFIGURED_ADDRESS = "configured_addr";
|
||||
public static final String CONFIG_MAIL_SERVER = "mail_server";
|
||||
public static final String CONFIG_MAIL_USER = "mail_user";
|
||||
public static final String CONFIG_MAIL_PASSWORD = "mail_pw";
|
||||
@@ -97,6 +98,10 @@ public class DcHelper {
|
||||
return dcContext.isConfigured() == 1;
|
||||
}
|
||||
|
||||
public static String getSelfAddr(Context context) {
|
||||
DcContext dcContext = getContext(context);
|
||||
return dcContext.getConfig(CONFIG_CONFIGURED_ADDRESS);
|
||||
}
|
||||
|
||||
public static int getInt(Context context, String key) {
|
||||
DcContext dcContext = getContext(context);
|
||||
@@ -207,6 +212,8 @@ public class DcHelper {
|
||||
// cmp. https://github.com/deltachat/deltachat-android/issues/2187
|
||||
dcContext.setStockTranslation(120, context.getString(R.string.qrshow_join_group_hint).replace("\"", ""));
|
||||
dcContext.setStockTranslation(121, context.getString(R.string.connectivity_not_connected));
|
||||
dcContext.setStockTranslation(122, context.getString(R.string.aeap_addr_changed));
|
||||
dcContext.setStockTranslation(123, context.getString(R.string.aeap_explanation));
|
||||
}
|
||||
|
||||
public static File getImexDir() {
|
||||
|
||||
@@ -45,7 +45,11 @@ public abstract class ProgressDialogAsyncTask<Params, Progress, Result> extends
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Result result) {
|
||||
if (progress != null) progress.dismiss();
|
||||
try {
|
||||
if (progress != null) progress.dismiss();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected Context getContext() {
|
||||
|
||||
@@ -24,8 +24,9 @@ public class ConversationAdaptiveActionsToolbar extends Toolbar {
|
||||
private static final int OVERFLOW_VIEW_WIDTH_DP = 36;
|
||||
|
||||
private static final int ID_NEVER_SHOW_AS_ACTION_1 = R.id.menu_context_reply_privately;
|
||||
private static final int ID_NEVER_SHOW_AS_ACTION_2 = R.id.menu_context_save_attachment;
|
||||
private static final int ID_NEVER_SHOW_AS_ACTION_3 = R.id.menu_resend;
|
||||
private static final int ID_NEVER_SHOW_AS_ACTION_2 = R.id.menu_add_to_home_screen;
|
||||
private static final int ID_NEVER_SHOW_AS_ACTION_3 = R.id.menu_context_save_attachment;
|
||||
private static final int ID_NEVER_SHOW_AS_ACTION_4 = R.id.menu_resend;
|
||||
private static final int ID_ALWAYS_SHOW_AS_ACTION = R.id.menu_context_forward;
|
||||
|
||||
private int maxShown;
|
||||
@@ -81,7 +82,8 @@ public class ConversationAdaptiveActionsToolbar extends Toolbar {
|
||||
|
||||
boolean neverShowAsAction = item.getItemId() == ID_NEVER_SHOW_AS_ACTION_1
|
||||
|| item.getItemId() == ID_NEVER_SHOW_AS_ACTION_2
|
||||
|| item.getItemId() == ID_NEVER_SHOW_AS_ACTION_3;
|
||||
|| item.getItemId() == ID_NEVER_SHOW_AS_ACTION_3
|
||||
|| item.getItemId() == ID_NEVER_SHOW_AS_ACTION_4;
|
||||
boolean alwaysShowAsAction = item.getItemId() == ID_ALWAYS_SHOW_AS_ACTION;
|
||||
|
||||
if (alwaysShowAsAction) continue;
|
||||
|
||||
Reference in New Issue
Block a user