Browse Source

Merge pull request #10148 from nextcloud/proseMirror

Test proseMirror with custom user agent
Tobias Kaminsky 3 years ago
parent
commit
c1cf416872

+ 5 - 39
app/src/main/java/com/owncloud/android/files/FileMenuFilter.java

@@ -22,24 +22,20 @@
 package com.owncloud.android.files;
 
 import android.accounts.AccountManager;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.view.Menu;
 import android.view.MenuItem;
 
-import com.google.gson.Gson;
 import com.nextcloud.android.files.FileLockingHelper;
 import com.nextcloud.client.account.User;
 import com.owncloud.android.R;
-import com.owncloud.android.datamodel.ArbitraryDataProvider;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
-import com.owncloud.android.lib.common.DirectEditing;
-import com.owncloud.android.lib.common.Editor;
 import com.owncloud.android.lib.resources.status.OCCapability;
 import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
 import com.owncloud.android.ui.activity.ComponentsGetter;
+import com.owncloud.android.utils.EditorUtils;
 import com.owncloud.android.utils.MimeTypeUtil;
 import com.owncloud.android.utils.NextcloudServer;
 
@@ -49,8 +45,6 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 
-import androidx.annotation.Nullable;
-
 /**
  * Filters out the file actions available in a given {@link Menu} for a given {@link OCFile}
  * according to the current state of the latest.
@@ -352,44 +346,16 @@ public class FileMenuFilter {
 
         String mimeType = files.iterator().next().getMimeType();
 
-        if (isRichDocumentEditingSupported(capability, mimeType) || isEditorAvailable(context.getContentResolver(),
-                                                                                      user,
-                                                                                      mimeType)) {
+        if (isRichDocumentEditingSupported(capability, mimeType) ||
+            EditorUtils.isEditorAvailable(context.getContentResolver(),
+                                          user,
+                                          mimeType)) {
             toShow.add(R.id.action_edit);
         } else {
             toHide.add(R.id.action_edit);
         }
     }
 
-    public static boolean isEditorAvailable(ContentResolver contentResolver, User user, String mimeType) {
-        return getEditor(contentResolver, user, mimeType) != null;
-    }
-
-    @Nullable
-    public static Editor getEditor(ContentResolver contentResolver, User user, String mimeType) {
-        String json = new ArbitraryDataProvider(contentResolver).getValue(user, ArbitraryDataProvider.DIRECT_EDITING);
-
-        if (json.isEmpty()) {
-            return null;
-        }
-
-        DirectEditing directEditing = new Gson().fromJson(json, DirectEditing.class);
-
-        for (Editor editor : directEditing.getEditors().values()) {
-            if (editor.getMimetypes().contains(mimeType)) {
-                return editor;
-            }
-        }
-
-        for (Editor editor : directEditing.getEditors().values()) {
-            if (editor.getOptionalMimetypes().contains(mimeType)) {
-                return editor;
-            }
-        }
-
-        return null;
-    }
-
     /**
      * This will be replaced by unified editor and can be removed once EOL of corresponding server version.
      */

+ 5 - 1
app/src/main/java/com/owncloud/android/ui/activity/ExternalSiteWebView.java

@@ -179,7 +179,7 @@ public class ExternalSiteWebView extends FileActivity {
         webSettings.setLoadWithOverviewMode(true);
 
         // user agent
-        webSettings.setUserAgentString(MainApp.getUserAgent());
+        setUserAgentString(webSettings);
 
         // no private data storing
         webSettings.setSavePassword(false);
@@ -199,6 +199,10 @@ public class ExternalSiteWebView extends FileActivity {
         }
     }
 
+    protected void setUserAgentString(WebSettings webSettings) {
+        webSettings.setUserAgentString(MainApp.getUserAgent());
+    }
+
     private void setupActionBar(String title) {
         ActionBar actionBar = getSupportActionBar();
         if (actionBar != null) {

+ 20 - 11
app/src/main/java/com/owncloud/android/ui/activity/TextEditorWebView.kt

@@ -23,14 +23,15 @@ package com.owncloud.android.ui.activity
 
 import android.annotation.SuppressLint
 import android.net.Uri
+import android.webkit.WebSettings
 import android.widget.Toast
 import androidx.webkit.WebSettingsCompat
 import androidx.webkit.WebViewFeature
 import com.nextcloud.client.appinfo.AppInfo
 import com.nextcloud.client.device.DeviceInfo
 import com.owncloud.android.R
-import com.owncloud.android.files.FileMenuFilter
 import com.owncloud.android.ui.asynctasks.TextEditorLoadUrlTask
+import com.owncloud.android.utils.EditorUtils
 import com.owncloud.android.utils.theme.ThemeUtils
 import javax.inject.Inject
 
@@ -53,29 +54,33 @@ class TextEditorWebView : EditorWebView() {
             finish()
         }
 
-        val editor = FileMenuFilter.getEditor(contentResolver, user.get(), file.mimeType)
-
-        if (editor != null && editor.id == "onlyoffice") {
-            getWebView().settings.userAgentString = generateOnlyOfficeUserAgent()
-        }
-
-        getWebView().addJavascriptInterface(MobileInterface(), "DirectEditingMobileInterface")
+        webView.addJavascriptInterface(MobileInterface(), "DirectEditingMobileInterface")
 
         if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
             WebSettingsCompat.setForceDarkStrategy(
-                getWebView().settings,
+                webView.settings,
                 WebSettingsCompat.DARK_STRATEGY_WEB_THEME_DARKENING_ONLY
             )
         }
         if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK) && themeUtils.isDarkModeActive(this)) {
-            WebSettingsCompat.setForceDark(getWebView().settings, WebSettingsCompat.FORCE_DARK_ON)
+            WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_ON)
         }
 
-        getWebView().setDownloadListener { url, _, _, _, _ -> downloadFile(Uri.parse(url)) }
+        webView.setDownloadListener { url, _, _, _, _ -> downloadFile(Uri.parse(url)) }
 
         loadUrl(intent.getStringExtra(ExternalSiteWebView.EXTRA_URL))
     }
 
+    override fun setUserAgentString(webSettings: WebSettings?) {
+        val editor = EditorUtils.getEditor(contentResolver, user.get(), file.mimeType)
+
+        if (editor != null && editor.id == ONLYOFFICE) {
+            webView.settings.userAgentString = generateOnlyOfficeUserAgent()
+        }
+
+        // For Text/prosemirror we keep default user agent to not mess around with their special treatments
+    }
+
     override fun loadUrl(url: String?) {
         if (url.isNullOrEmpty()) {
             TextEditorLoadUrlTask(this, user.get(), file).execute()
@@ -87,4 +92,8 @@ class TextEditorWebView : EditorWebView() {
 
         return String.format(userAgent, deviceInfo.androidVersion, appInfo.getAppVersion(this))
     }
+
+    companion object {
+        const val ONLYOFFICE = "onlyoffice"
+    }
 }

+ 2 - 2
app/src/main/java/com/owncloud/android/ui/asynctasks/TextEditorLoadUrlTask.java

@@ -26,10 +26,10 @@ import android.os.AsyncTask;
 import com.nextcloud.android.lib.resources.directediting.DirectEditingOpenFileRemoteOperation;
 import com.nextcloud.client.account.User;
 import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.files.FileMenuFilter;
 import com.owncloud.android.lib.common.Editor;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.ui.activity.EditorWebView;
+import com.owncloud.android.utils.EditorUtils;
 
 import java.lang.ref.WeakReference;
 
@@ -55,7 +55,7 @@ public class TextEditorLoadUrlTask extends AsyncTask<Void, Void, String> {
             return "";
         }
 
-        Editor editor = FileMenuFilter.getEditor(editorWebView.getContentResolver(), user, file.getMimeType());
+        Editor editor = EditorUtils.getEditor(editorWebView.getContentResolver(), user, file.getMimeType());
 
         if (editor == null) {
             return "";

+ 4 - 6
app/src/main/java/com/owncloud/android/ui/fragment/OCFileListBottomSheetDialog.java

@@ -35,19 +35,17 @@ import com.owncloud.android.databinding.FileListActionsBottomSheetCreatorBinding
 import com.owncloud.android.databinding.FileListActionsBottomSheetFragmentBinding;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
 import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.files.FileMenuFilter;
 import com.owncloud.android.lib.common.Creator;
 import com.owncloud.android.lib.common.DirectEditing;
 import com.owncloud.android.lib.resources.status.OCCapability;
 import com.owncloud.android.ui.activity.AppScanActivity;
 import com.owncloud.android.ui.activity.FileActivity;
+import com.owncloud.android.utils.EditorUtils;
 import com.owncloud.android.utils.MimeTypeUtil;
 import com.owncloud.android.utils.theme.ThemeColorUtils;
 import com.owncloud.android.utils.theme.ThemeDrawableUtils;
 import com.owncloud.android.utils.theme.ThemeUtils;
 
-import javax.inject.Inject;
-
 /**
  * FAB menu {@link android.app.Dialog} styled as a bottom sheet for main actions.
  */
@@ -155,9 +153,9 @@ public class OCFileListBottomSheetDialog extends BottomSheetDialog implements In
         }
 
         // create rich workspace
-        if (FileMenuFilter.isEditorAvailable(getContext().getContentResolver(),
-                                             user,
-                                             MimeTypeUtil.MIMETYPE_TEXT_MARKDOWN) &&
+        if (EditorUtils.isEditorAvailable(getContext().getContentResolver(),
+                                          user,
+                                          MimeTypeUtil.MIMETYPE_TEXT_MARKDOWN) &&
             file != null && !file.isEncrypted()) {
             // richWorkspace
             // == "": no info set -> show button

+ 7 - 6
app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java

@@ -104,6 +104,7 @@ import com.owncloud.android.ui.preview.PreviewImageFragment;
 import com.owncloud.android.ui.preview.PreviewMediaFragment;
 import com.owncloud.android.ui.preview.PreviewTextFileFragment;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.EditorUtils;
 import com.owncloud.android.utils.EncryptionUtils;
 import com.owncloud.android.utils.FileSortOrder;
 import com.owncloud.android.utils.FileStorageUtils;
@@ -1062,9 +1063,9 @@ public class OCFileListFragment extends ExtendedListFragment implements
                             setFabVisible(false);
                             resetHeaderScrollingState();
                             ((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0, true, true, true);
-                        } else if (FileMenuFilter.isEditorAvailable(requireContext().getContentResolver(),
-                                                                    accountManager.getUser(),
-                                                                    file.getMimeType()) &&
+                        } else if (EditorUtils.isEditorAvailable(requireContext().getContentResolver(),
+                                                                 accountManager.getUser(),
+                                                                 file.getMimeType()) &&
                             !file.isEncrypted()) {
                             mContainerActivity.getFileOperationsHelper().openFileWithTextEditor(file, getContext());
                         } else if (capability.getRichDocumentsMimeTypeList().contains(file.getMimeType()) &&
@@ -1131,9 +1132,9 @@ public class OCFileListFragment extends ExtendedListFragment implements
                 return true;
             } else if (itemId == R.id.action_edit) {
                 // should not be necessary, as menu item is filtered, but better play safe
-                if (FileMenuFilter.isEditorAvailable(requireContext().getContentResolver(),
-                                                     accountManager.getUser(),
-                                                     singleFile.getMimeType())) {
+                if (EditorUtils.isEditorAvailable(requireContext().getContentResolver(),
+                                                  accountManager.getUser(),
+                                                  singleFile.getMimeType())) {
                     mContainerActivity.getFileOperationsHelper().openFileWithTextEditor(singleFile, getContext());
                 } else {
                     mContainerActivity.getFileOperationsHelper().openFileAsRichDocument(singleFile, getContext());

+ 4 - 4
app/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java

@@ -55,7 +55,6 @@ import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.files.FileMenuFilter;
 import com.owncloud.android.files.StreamMediaFileOperation;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
@@ -82,6 +81,7 @@ import com.owncloud.android.ui.events.FavoriteEvent;
 import com.owncloud.android.ui.events.FileLockEvent;
 import com.owncloud.android.ui.events.SyncEventFinished;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.EditorUtils;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.PermissionUtil;
 import com.owncloud.android.utils.UriUtils;
@@ -302,9 +302,9 @@ public class FileOperationsHelper {
             if (launchables.isEmpty()) {
                 Optional<User> optionalUser = fileActivity.getUser();
 
-                if (optionalUser.isPresent() && FileMenuFilter.isEditorAvailable(fileActivity.getContentResolver(),
-                                                                                 optionalUser.get(),
-                                                                                 file.getMimeType())) {
+                if (optionalUser.isPresent() && EditorUtils.isEditorAvailable(fileActivity.getContentResolver(),
+                                                                              optionalUser.get(),
+                                                                              file.getMimeType())) {
                     openFileWithTextEditor(file, fileActivity);
                 } else {
                     Account account = fileActivity.getAccount();

+ 48 - 0
app/src/main/java/com/owncloud/android/utils/EditorUtils.kt

@@ -0,0 +1,48 @@
+/*
+ *
+ * Nextcloud Android client application
+ *
+ * @author Tobias Kaminsky
+ * Copyright (C) 2022 Tobias Kaminsky
+ * Copyright (C) 2022 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.utils
+
+import android.content.ContentResolver
+import com.google.gson.Gson
+import com.nextcloud.client.account.User
+import com.owncloud.android.datamodel.ArbitraryDataProvider
+import com.owncloud.android.lib.common.DirectEditing
+import com.owncloud.android.lib.common.Editor
+
+object EditorUtils {
+    @JvmStatic
+    fun isEditorAvailable(contentResolver: ContentResolver?, user: User?, mimeType: String?): Boolean {
+        return getEditor(contentResolver, user, mimeType) != null
+    }
+
+    @JvmStatic
+    fun getEditor(contentResolver: ContentResolver?, user: User?, mimeType: String?): Editor? {
+        val json = ArbitraryDataProvider(contentResolver).getValue(user, ArbitraryDataProvider.DIRECT_EDITING)
+        if (json.isEmpty()) {
+            return null
+        }
+        val directEditing = Gson().fromJson(json, DirectEditing::class.java)
+        val editors = directEditing.editors.values
+        return editors.firstOrNull { it.mimetypes.contains(mimeType) || it.optionalMimetypes.contains(mimeType) }
+    }
+}