add app picker to attachments menu

This commit is contained in:
adbenitez 2024-12-03 18:52:15 +01:00
parent 1b57880be3
commit 0a73877c25
7 changed files with 223 additions and 45 deletions

View file

@ -376,6 +376,13 @@
android:exported="true">
</activity>
<activity android:name=".WebxdcStoreActivity"
android:label=""
android:theme="@style/TextSecure.LightTheme"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize|uiMode"
android:exported="true">
</activity>
<activity android:name=".FullMsgActivity"
android:theme="@style/TextSecure.LightTheme"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">

View file

@ -158,8 +158,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private static final int GROUP_EDIT = 6;
private static final int TAKE_PHOTO = 7;
private static final int RECORD_VIDEO = 8;
private static final int PICK_LOCATION = 9; // TODO: i think, this can be deleted
private static final int SMS_DEFAULT = 11; // TODO: i think, this can be deleted
private static final int PICK_WEBXDC = 9;
private GlideRequests glideRequests;
protected ComposeText composeText;
@ -337,8 +336,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
public void onActivityResult(final int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
if ((data == null && reqCode != TAKE_PHOTO && reqCode != RECORD_VIDEO && reqCode != SMS_DEFAULT) ||
(resultCode != RESULT_OK && reqCode != SMS_DEFAULT))
if (resultCode != RESULT_OK || (data == null && reqCode != TAKE_PHOTO && reqCode != RECORD_VIDEO))
{
return;
}
@ -374,6 +372,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
setMedia(data.getData(), docMediaType);
break;
case PICK_WEBXDC:
setMedia(data.getData(), MediaType.DOCUMENT);
break;
case PICK_CONTACT:
addAttachmentContactInfo(data.getIntExtra(AttachContactActivity.CONTACT_ID_EXTRA, 0));
break;
@ -401,16 +403,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
break;
case PICK_LOCATION:
break;
case ScribbleActivity.SCRIBBLE_REQUEST_CODE:
setMedia(data.getData(), MediaType.IMAGE);
break;
case SMS_DEFAULT:
initializeSecurity(isSecureText, isDefaultSms);
break;
}
}
@ -942,6 +937,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
case AttachmentTypeSelector.RECORD_VIDEO:
attachmentManager.captureVideo(this, RECORD_VIDEO);
break;
case AttachmentTypeSelector.ADD_WEBXDC:
AttachmentManager.selectWebxdc(this, PICK_WEBXDC); break;
}
}

View file

@ -0,0 +1,136 @@
package org.thoughtcrime.securesms;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.MenuItem;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.appcompat.app.ActionBar;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.rpc.HttpResponse;
import com.b44t.messenger.rpc.Rpc;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
import org.thoughtcrime.securesms.util.MediaUtil;
import java.io.ByteArrayInputStream;
import java.util.HashMap;
public class WebxdcStoreActivity extends PassphraseRequiredActionBarActivity {
private static final String TAG = WebxdcStoreActivity.class.getSimpleName();
private DcContext dcContext;
private Rpc rpc;
@Override
protected void onCreate(Bundle state, boolean ready) {
setContentView(R.layout.web_view_activity);
rpc = DcHelper.getRpc(this);
dcContext = DcHelper.getContext(this);
WebView webView = findViewById(R.id.webview);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(R.string.webxdc_apps);
}
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
@TargetApi(Build.VERSION_CODES.N)
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
view.loadUrl(request.getUrl().toString());
return true;
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
WebResourceResponse res = interceptRequest(request.getUrl().toString());
if (res == null) {
res = super.shouldInterceptRequest(view, request);
}
return res;
}
});
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccess(false);
webSettings.setAllowContentAccess(false);
webSettings.setGeolocationEnabled(false);
webSettings.setAllowFileAccessFromFileURLs(false);
webSettings.setAllowUniversalAccessFromFileURLs(false);
webSettings.setDatabaseEnabled(true);
webSettings.setDomStorageEnabled(true);
webView.setNetworkAvailable(true); // this does not block network but sets `window.navigator.isOnline` in js land
// TODO: use setting
String storeURL = "https://webxdc.org/apps/";
webView.loadUrl(storeURL);
}
private WebResourceResponse interceptRequest(String url) {
WebResourceResponse res = null;
try {
if (url == null) {
throw new Exception("no url specified");
}
HttpResponse httpResponse = rpc.getHttpResponse(dcContext.getAccountId(), url);
String mimeType = httpResponse.getMimetype();
if (mimeType == null) {
mimeType = "application/octet-stream";
}
String ext = MediaUtil.getFileExtensionFromUrl(Uri.parse(url).getPath());
if ("xdc".equals(ext)) {
Intent intent = new Intent();
Uri uri = PersistentBlobProvider.getInstance().create(this, httpResponse.getBlob(), mimeType, "app.xdc");
intent.setType(mimeType);
intent.setData(uri);
setResult(Activity.RESULT_OK, intent);
finish();
} else {
ByteArrayInputStream data = new ByteArrayInputStream(httpResponse.getBlob());
res = new WebResourceResponse(mimeType, httpResponse.getEncoding(), data);
}
} catch (Exception e) {
e.printStackTrace();
ByteArrayInputStream data = new ByteArrayInputStream(("Error: " + e.getMessage()).getBytes());
res = new WebResourceResponse("text/plain", "UTF-8", data);
}
if (res != null) {
HashMap<String, String> headers = new HashMap<>();
headers.put("access-control-allow-origin", "*");
res.setResponseHeaders(headers);
}
return res;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
}
return false;
}
}

View file

@ -41,6 +41,7 @@ public class AttachmentTypeSelector extends PopupWindow {
public static final int TAKE_PHOTO = 5;
public static final int ADD_LOCATION = 6;
public static final int RECORD_VIDEO = 7;
public static final int ADD_WEBXDC = 8;
private static final int ANIMATION_DURATION = 300;
@ -53,7 +54,7 @@ public class AttachmentTypeSelector extends PopupWindow {
private final @NonNull ImageView cameraButton;
private final @NonNull ImageView videoButton;
private final @NonNull ImageView locationButton;
private final @NonNull ImageView closeButton;
private final @NonNull ImageView webxdcButton;
private @Nullable View currentAnchor;
private @Nullable AttachmentClickedListener listener;
@ -76,7 +77,7 @@ public class AttachmentTypeSelector extends PopupWindow {
this.cameraButton = ViewUtil.findById(layout, R.id.camera_button);
this.videoButton = ViewUtil.findById(layout, R.id.record_video_button);
this.locationButton = ViewUtil.findById(layout, R.id.location_button);
this.closeButton = ViewUtil.findById(layout, R.id.close_button);
this.webxdcButton = ViewUtil.findById(layout, R.id.webxdc_button);
this.imageButton.setOnClickListener(new PropagatingClickListener(ADD_GALLERY));
this.videoChatButton.setOnClickListener(new PropagatingClickListener(INVITE_VIDEO_CHAT));
@ -85,7 +86,7 @@ public class AttachmentTypeSelector extends PopupWindow {
this.cameraButton.setOnClickListener(new PropagatingClickListener(TAKE_PHOTO));
this.videoButton.setOnClickListener(new PropagatingClickListener(RECORD_VIDEO));
this.locationButton.setOnClickListener(new PropagatingClickListener(ADD_LOCATION));
this.closeButton.setOnClickListener(new CloseClickListener());
this.webxdcButton.setOnClickListener(new PropagatingClickListener(ADD_WEBXDC));
this.recentRail.setListener(new RecentPhotoSelectedListener());
if (!Prefs.isLocationStreamingEnabled(context)) {
@ -140,8 +141,8 @@ public class AttachmentTypeSelector extends PopupWindow {
animateButtonIn(contactButton, ANIMATION_DURATION / 3);
animateButtonIn(locationButton, ANIMATION_DURATION / 4);
animateButtonIn(documentButton, ANIMATION_DURATION / 4);
animateButtonIn(webxdcButton, 0);
animateButtonIn(videoChatButton, 0);
animateButtonIn(closeButton, 0);
}
@Override
@ -289,13 +290,6 @@ public class AttachmentTypeSelector extends PopupWindow {
}
private class CloseClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
dismiss();
}
}
public interface AttachmentClickedListener {
public void onClick(int type);
public void onQuickAttachment(Uri uri);

View file

@ -51,6 +51,7 @@ import org.thoughtcrime.securesms.MediaPreviewActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.ShareLocationDialog;
import org.thoughtcrime.securesms.WebxdcActivity;
import org.thoughtcrime.securesms.WebxdcStoreActivity;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.attachments.UriAttachment;
import org.thoughtcrime.securesms.audio.AudioSlidePlayer;
@ -452,6 +453,11 @@ public class AttachmentManager {
selectMediaType(activity, "*/*", null, requestCode);
}
public static void selectWebxdc(Activity activity, int requestCode) {
Intent intent = new Intent(activity, WebxdcStoreActivity.class);
activity.startActivityForResult(intent, requestCode);
}
public static void selectGallery(Activity activity, int requestCode) {
// to enable camera roll,
// we're asking for "gallery permissions" also on newer systems that do not strictly require that.

View file

@ -0,0 +1,39 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="72dp"
android:height="72dp"
android:viewportWidth="72"
android:viewportHeight="72">
<group>
<clip-path
android:pathData="m72,36a36,36 121.356,0 1,-35.965 36,36 36,121.356 0,1 -36.035,-35.93 36,36 121.356,0 1,35.895 -36.07,36 36,121.356 0,1 36.105,35.86"/>
<path
android:pathData="M36,-0.122l36.122,0l0,72.241l-36.122,0z"
android:strokeWidth="0.209"
android:fillColor="#364e59"/>
<path
android:pathData="M-0.122,-0.122l45.153,0l0,72.241l-45.153,0z"
android:strokeWidth="0.209"
android:fillColor="#7cc5cc"/>
<path
android:pathData="m45.229,72.016 l-21.071,-0.019 20.943,-72.463z"
android:strokeWidth="0.25"
android:fillColor="#364e59"/>
<path
android:pathData="M9.56,31.485l16.965,16.965l-3.903,3.903l-16.965,-16.965z"
android:strokeWidth="0.01"
android:fillColor="#364e59"/>
<path
android:pathData="M5.656,35.388l16.965,-16.965l3.903,3.903l-16.965,16.965z"
android:strokeWidth="0.01"
android:fillColor="#364e59"/>
<path
android:pathData="M60.405,31.485l-16.965,16.965l3.903,3.903l16.965,-16.965z"
android:strokeWidth="0.01"
android:fillColor="#7cc5cc"/>
<path
android:pathData="M64.309,35.388l-16.965,-16.965l-3.903,3.903l16.965,16.965z"
android:strokeWidth="0.01"
android:fillColor="#7cc5cc"/>
</group>
</vector>

View file

@ -188,6 +188,28 @@
</LinearLayout>
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<org.thoughtcrime.securesms.components.CircleColorImageView
android:id="@+id/webxdc_button"
android:layout_width="53dp"
android:layout_height="53dp"
android:src="@drawable/ic_webxdc"
android:scaleType="centerInside"
android:contentDescription="@string/webxdc_apps"/>
<TextView android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AttachmentTypeLabel"
android:text="@string/webxdc_apps"/>
</LinearLayout>
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
@ -212,29 +234,6 @@
</LinearLayout>
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<org.thoughtcrime.securesms.components.CircleColorImageView
android:id="@+id/close_button"
android:layout_width="53dp"
android:layout_height="53dp"
android:src="@drawable/ic_keyboard_arrow_down_white_24dp"
android:scaleType="center"
android:contentDescription="@string/cancel"
app:circleColor="?attr/close_icon_color"/>
<TextView android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AttachmentTypeLabel"
android:text=" "/>
</LinearLayout>
</LinearLayout>