diff --git a/android/app/build.gradle b/android/app/build.gradle index e20a67eeaa..4694be9e9c 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,8 +1,3 @@ - -plugins { - id 'io.sentry.android.gradle' version '4.1.1' -} - apply plugin: 'com.android.application' android { @@ -20,7 +15,6 @@ android { // Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61 ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~' } - manifestPlaceholders = [LOGSEQ_SENTRY_DSN: "$System.env.LOGSEQ_SENTRY_DSN"] } buildTypes { release { @@ -59,13 +53,3 @@ try { } catch(Exception e) { logger.warn("google-services.json not found, google-services plugin not applied. Push Notifications won't work") } - - -sentry { - org = "logseq" - projectName = "logseq" - - // this will upload your source code to Sentry to show it as part of the stack traces - // disable if you don't want to expose your sources - includeSourceContext = false -} diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle index 6b8af71f99..de5663b84e 100644 --- a/android/app/capacitor.build.gradle +++ b/android/app/capacitor.build.gradle @@ -9,6 +9,7 @@ android { apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" dependencies { + implementation project(':capacitor-action-sheet') implementation project(':capacitor-app') implementation project(':capacitor-camera') implementation project(':capacitor-clipboard') diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 3b450542c8..dcd579035b 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -60,20 +60,5 @@ android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> - - - - - - - - - - - - - - - - + diff --git a/android/app/src/main/assets/capacitor.plugins.json b/android/app/src/main/assets/capacitor.plugins.json index aa92b4daae..d571823044 100644 --- a/android/app/src/main/assets/capacitor.plugins.json +++ b/android/app/src/main/assets/capacitor.plugins.json @@ -1,4 +1,8 @@ [ + { + "pkg": "@capacitor/action-sheet", + "classpath": "com.capacitorjs.plugins.actionsheet.ActionSheetPlugin" + }, { "pkg": "@capacitor/app", "classpath": "com.capacitorjs.plugins.app.AppPlugin" diff --git a/android/app/src/main/java/com/logseq/app/FolderPicker.java b/android/app/src/main/java/com/logseq/app/FolderPicker.java index 325076bff6..e89b71caa1 100644 --- a/android/app/src/main/java/com/logseq/app/FolderPicker.java +++ b/android/app/src/main/java/com/logseq/app/FolderPicker.java @@ -11,6 +11,7 @@ import android.provider.Settings; import android.util.Log; import androidx.activity.result.ActivityResult; +import androidx.core.content.FileProvider; import androidx.documentfile.provider.DocumentFile; import com.getcapacitor.JSObject; @@ -49,6 +50,23 @@ public class FolderPicker extends Plugin { } } + @PluginMethod() + public void openFile(PluginCall call) { + Uri uri = Uri.parse(call.getString("uri")); + File file = new File(uri.getPath()); + + // Get URI and MIME type of file + String appId = getAppId(); + uri = FileProvider.getUriForFile(getActivity(), appId + ".fileprovider", file); + String mime = getContext().getContentResolver().getType(uri); + + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setDataAndType(uri, mime); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + getContext().startActivity(intent); + } + @ActivityCallback private void folderPickerResult(PluginCall call, ActivityResult result) { if (call == null) { diff --git a/android/capacitor.settings.gradle b/android/capacitor.settings.gradle index b3eb84d1f6..8d08fb38f7 100644 --- a/android/capacitor.settings.gradle +++ b/android/capacitor.settings.gradle @@ -2,6 +2,9 @@ include ':capacitor-android' project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') +include ':capacitor-action-sheet' +project(':capacitor-action-sheet').projectDir = new File('../node_modules/@capacitor/action-sheet/android') + include ':capacitor-app' project(':capacitor-app').projectDir = new File('../node_modules/@capacitor/app/android') diff --git a/package.json b/package.json index 321f666099..2a33ba1332 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,7 @@ "postinstall": "yarn tldraw:build && yarn amplify:build && yarn ui:build" }, "dependencies": { + "@capacitor/action-sheet": "^5.0.7", "@capacitor/android": "^5.0.0", "@capacitor/app": "^5.0.0", "@capacitor/camera": "^5.0.0", diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index 48e921b0de..23eddb3ad7 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -2,7 +2,6 @@ (:refer-clojure :exclude [range]) (:require-macros [hiccups.core]) (:require ["/frontend/utils" :as utils] - ["@capacitor/share" :refer [^js Share]] [cljs-bean.core :as bean] [cljs.core.match :refer [match]] [cljs.reader :as reader] @@ -54,6 +53,7 @@ [frontend.handler.db-based.property :as db-property-handler] [frontend.handler.db-based.property.util :as db-pu] [frontend.mobile.util :as mobile-util] + [frontend.mobile.intent :as mobile-intent] [frontend.modules.outliner.tree :as tree] [frontend.security :as security] [frontend.shui :refer [get-shui-component-version make-shui-context]] @@ -400,8 +400,7 @@ (let [[rel-dir basename] (util/get-dir-and-basename href) rel-dir (string/replace rel-dir #"^/+" "") asset-url (path/path-join repo-dir rel-dir basename)] - (.share Share (clj->js {:url asset-url - :title "Open file with your favorite app"})))))] + (mobile-intent/open-or-share-file asset-url))))] (cond (contains? config/audio-formats ext) diff --git a/src/main/frontend/mobile/intent.cljs b/src/main/frontend/mobile/intent.cljs index 3041f1933a..3a24573faf 100644 --- a/src/main/frontend/mobile/intent.cljs +++ b/src/main/frontend/mobile/intent.cljs @@ -1,5 +1,7 @@ (ns frontend.mobile.intent (:require ["@capacitor/filesystem" :refer [Filesystem]] + ["@capacitor/share" :refer [^js Share]] + ["@capacitor/action-sheet" :refer [ActionSheet]] ["path" :as node-path] ["send-intent" :refer [^js SendIntent]] [clojure.pprint :as pprint] @@ -22,6 +24,26 @@ [logseq.common.util.page-ref :as page-ref] [promesa.core :as p])) +(defn open-or-share-file + "Share file to mobile platform" + [uri] + (p/let [options [{:title "Open" + :style "DEFAULT"} + {:title "Share"} + {:title "Cancel" + :style "CANCEL"}] + result (.showActions ActionSheet (clj->js {:title "File Options" + :message "Select an option to perform" + :options options})) + index (.-index result)] + + (when (not= index 2) + (if (and (= index 0) (mobile-util/native-android?)) + (.openFile mobile-util/folder-picker (clj->js {:uri uri})) + (.share Share (clj->js {:url uri + :dialogTitle "Open file with your favorite app" + :title "Open file with your favorite app"})))))) + (defn- is-link [url] (when (not-empty url) diff --git a/yarn.lock b/yarn.lock index 163c33f8ba..fd3a20a9b6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -240,6 +240,11 @@ "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" +"@capacitor/action-sheet@^5.0.7": + version "5.0.7" + resolved "https://registry.yarnpkg.com/@capacitor/action-sheet/-/action-sheet-5.0.7.tgz#4808af8c483a85f58c7fffdea76f8d374883e3a0" + integrity sha512-8q8fYYy9dwLi4eiDiYq+ys/uOm9C2YpjfAnlG7fYdha8QNpaz2314jR+dxsJO423zYB2Wag9NXlupHpXeGdGOA== + "@capacitor/android@^5.0.0": version "5.4.1" resolved "https://registry.yarnpkg.com/@capacitor/android/-/android-5.4.1.tgz#5b0445202ca5e48fcb79d0c88e4403acc32504bc"