Detailed changes
@@ -45,6 +45,11 @@
android:label="@string/invite_to_app"
android:exported="false"
android:launchMode="singleTask" />
+ <activity
+ android:name="com.cheogram.android.WebxdcStore"
+ android:label="Widgets"
+ android:exported="false"
+ android:launchMode="standard" />
<activity
android:name=".ui.ImportBackupActivity"
android:label="@string/restore_backup"
@@ -0,0 +1,111 @@
+package com.cheogram.android;
+
+// Based on code from https://codeberg.org/monocles/monocles_chat/raw/commit/master/src/main/java/de/monocles/chat/WebXDCStore.java
+
+import static android.view.View.VISIBLE;
+import static eu.siacs.conversations.ui.ActionBarActivity.configureActionBar;
+import static eu.siacs.conversations.utils.AccountUtils.MANAGE_ACCOUNT_ACTIVITY;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Environment;
+import android.text.Html;
+import android.text.method.LinkMovementMethod;
+import android.view.MenuItem;
+import android.webkit.DownloadListener;
+import android.webkit.URLUtil;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+import eu.siacs.conversations.R;
+import eu.siacs.conversations.services.ChannelDiscoveryService;
+import eu.siacs.conversations.ui.Activities;
+import eu.siacs.conversations.ui.XmppActivity;
+import eu.siacs.conversations.databinding.ActivityWebxdcStoreBinding;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AlertDialog;
+import androidx.databinding.DataBindingUtil;
+
+import android.annotation.SuppressLint;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class WebxdcStore extends XmppActivity {
+ @SuppressLint("SetJavaScriptEnabled")
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ final ActivityWebxdcStoreBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_webxdc_store);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
+ setSupportActionBar(binding.toolbar);
+ configureActionBar(getSupportActionBar());
+
+ //getSupportActionBar().setDisplayShowHomeEnabled(false);
+ //getSupportActionBar().setDisplayHomeAsUpEnabled(false);
+ WebView webView = findViewById(R.id.web);
+ String URL = "https://webxdc.org/apps/";
+ if (isNetworkAvailable(this)) {
+ webView.loadUrl(URL);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ webView.setForceDarkAllowed(true);
+ }
+ webView.getSettings().setJavaScriptEnabled(true);
+ webView.getSettings().setDomStorageEnabled(true);
+ webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
+ webView.setWebViewClient(new WebViewClient() {
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ view.loadUrl(url);
+ return true;
+ }
+ });
+ webView.setDownloadListener(new DownloadListener() {
+ @Override
+ public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) {
+ final var intent = new Intent();
+ intent.setData(Uri.parse(url));
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ }
+ });
+ } else {
+ Toast.makeText(this, R.string.account_status_no_internet, Toast.LENGTH_LONG).show();
+ }
+ }
+
+ @Override
+ protected void refreshUiReal() {
+
+ }
+
+ @Override
+ protected void onBackendConnected() {
+ }
+
+ //check for internet connection
+ private boolean isNetworkAvailable(Context context) {
+ ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (connectivity != null) {
+ NetworkInfo[] info = connectivity.getAllNetworkInfo();
+ if (info != null) {
+ for (NetworkInfo anInfo : info) {
+ if (anInfo.getState() == NetworkInfo.State.CONNECTED) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+}
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (c) 2024, Arne-BrΓΌn Vogelsang All rights reserved.
+ ~
+ ~ Redistribution and use in source and binary forms, with or without modification,
+ ~ are permitted provided that the following conditions are met:
+ ~
+ ~ 1. Redistributions of source code must retain the above copyright notice, this
+ ~ list of conditions and the following disclaimer.
+ ~
+ ~ 2. Redistributions in binary form must reproduce the above copyright notice,
+ ~ this list of conditions and the following disclaimer in the documentation and/or
+ ~ other materials provided with the distribution.
+ ~
+ ~ 3. Neither the name of the copyright holder nor the names of its contributors
+ ~ may be used to endorse or promote products derived from this software without
+ ~ specific prior written permission.
+ ~
+ ~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ~ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ ~ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ ~ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ ~ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ ~ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ ~ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ~ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ~ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ ~ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ -->
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <com.google.android.material.appbar.AppBarLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <com.google.android.material.appbar.MaterialToolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?attr/actionBarSize" />
+
+ </com.google.android.material.appbar.AppBarLayout>
+
+ <WebView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/web"/>
+
+ </LinearLayout>
+</layout>
@@ -89,6 +89,7 @@ import androidx.viewpager.widget.ViewPager;
import com.cheogram.android.BobTransfer;
import com.cheogram.android.EmojiSearch;
import com.cheogram.android.WebxdcPage;
+import com.cheogram.android.WebxdcStore;
import com.google.android.material.color.MaterialColors;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
@@ -217,6 +218,7 @@ public class ConversationFragment extends XmppFragment
public static final int REQUEST_START_AUDIO_CALL = 0x213;
public static final int REQUEST_START_VIDEO_CALL = 0x214;
public static final int REQUEST_SAVE_STICKER = 0x215;
+ public static final int REQUEST_WEBXDC_STORE = 0x216;
public static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x0301;
public static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302;
public static final int ATTACHMENT_CHOICE_CHOOSE_FILE = 0x0303;
@@ -1138,6 +1140,10 @@ public class ConversationFragment extends XmppFragment
private void handlePositiveActivityResult(int requestCode, final Intent data) {
switch (requestCode) {
+ case REQUEST_WEBXDC_STORE:
+ mediaPreviewAdapter.addMediaPreviews(Attachment.of(activity, data.getData(), Attachment.Type.FILE));
+ toggleInputMethod();
+ break;
case REQUEST_SAVE_STICKER:
final DocumentFile df = DocumentFile.fromSingleUri(activity, data.getData());
final File f = savingAsSticker;
@@ -1982,6 +1988,10 @@ public class ConversationFragment extends XmppFragment
case R.id.attach_location:
handleAttachmentSelection(item);
break;
+ case R.id.attach_webxdc:
+ final Intent intent = new Intent(getActivity(), WebxdcStore.class);
+ startActivityForResult(intent, REQUEST_WEBXDC_STORE);
+ break;
case R.id.attach_subject:
binding.textinputSubject.setVisibility(binding.textinputSubject.getVisibility() == View.GONE ? View.VISIBLE : View.GONE);
break;
@@ -0,0 +1,5 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#FFFFFF" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
+
+ <path android:fillColor="@android:color/white" android:pathData="M19,3H5C3.9,3 3,3.9 3,5v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V5C21,3.9 20.1,3 19,3zM12.01,18c-0.7,0 -1.26,-0.56 -1.26,-1.26c0,-0.71 0.56,-1.25 1.26,-1.25c0.71,0 1.25,0.54 1.25,1.25C13.25,17.43 12.72,18 12.01,18zM15.02,10.6c-0.76,1.11 -1.48,1.46 -1.87,2.17c-0.16,0.29 -0.22,0.48 -0.22,1.41h-1.82c0,-0.49 -0.08,-1.29 0.31,-1.98c0.49,-0.87 1.42,-1.39 1.96,-2.16c0.57,-0.81 0.25,-2.33 -1.37,-2.33c-1.06,0 -1.58,0.8 -1.8,1.48L8.56,8.49C9.01,7.15 10.22,6 11.99,6c1.48,0 2.49,0.67 3.01,1.52C15.44,8.24 15.7,9.59 15.02,10.6z"/>
+
+</vector>
@@ -62,6 +62,11 @@
android:icon="@drawable/ic_location_pin_24dp"
android:title="@string/send_location" />
+ <item
+ android:id="@+id/attach_webxdc"
+ android:icon="@drawable/ic_help_center_24dp"
+ android:title="Choose Widget" />
+
<item
android:id="@+id/attach_subject"
android:icon="@drawable/subject"