diff --git a/android/app/build.gradle b/android/app/build.gradle index 40466f004c5..b6022843a95 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -269,6 +269,7 @@ dependencies { implementation project(':react-native-webview') implementation project(':react-native-config') implementation project(':react-native-firebase') + implementation project(':RNMail') compile ('com.google.android.gms:play-services-base:16.0.1') { force = true } diff --git a/android/app/src/main/java/im/status/ethereum/MainApplication.java b/android/app/src/main/java/im/status/ethereum/MainApplication.java index 7cff8e780fe..3af87055a92 100644 --- a/android/app/src/main/java/im/status/ethereum/MainApplication.java +++ b/android/app/src/main/java/im/status/ethereum/MainApplication.java @@ -35,6 +35,7 @@ import io.invertase.firebase.notifications.RNFirebaseNotificationsPackage; import io.realm.react.RealmReactPackage; import me.alwx.HttpServer.HttpServerReactPackage; +import com.chirag.RNMail.*; public class MainApplication extends MultiDexApplication implements ReactApplication { @@ -50,6 +51,7 @@ protected List getPackages() { Function callRPC = statusPackage.getCallRPC(); return Arrays.asList( new MainReactPackage(), + new RNMail(), new RNFirebasePackage(), new RNFirebaseMessagingPackage(), new RNFirebaseNotificationsPackage(), diff --git a/android/settings.gradle b/android/settings.gradle index 420c34ac087..fb722f36bc9 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -42,3 +42,5 @@ include ':react-native-config' project(':react-native-config').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-config/android') include ':react-native-android' project(':react-native-android').projectDir = new File(rootProject.projectDir, '../node_modules/react-native/ReactAndroid') +include ':RNMail', ':app' +project(':RNMail').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-mail/android') diff --git a/clj-rn.conf.edn b/clj-rn.conf.edn index c1d013442a0..ed7a5af09b8 100644 --- a/clj-rn.conf.edn +++ b/clj-rn.conf.edn @@ -43,7 +43,8 @@ "text-encoding" "js-sha3" "react-navigation" - "hi-base32"] + "hi-base32" + "react-native-mail"] ;; Desktop modules :desktop-modules ["realm" diff --git a/mobile_files/package.json.orig b/mobile_files/package.json.orig index 262affe4867..61917bc0cc8 100644 --- a/mobile_files/package.json.orig +++ b/mobile_files/package.json.orig @@ -48,6 +48,7 @@ "react-native-invertible-scroll-view": "1.1.0", "react-native-keychain": "git+https://github.com/status-im/react-native-keychain.git#v.3.0.0-status", "react-native-languages": "^3.0.2", + "react-native-mail": "git+https://github.com/status-im/react-native-mail.git#v3.0.7_status", "react-native-os": "git+https://github.com/status-im/react-native-os.git#v1.1.0-1-status", "react-native-qrcode": "git+https://github.com/status-im/react-native-qrcode.git#v0.2.8", "react-native-randombytes": "3.5.0", diff --git a/mobile_files/yarn.lock b/mobile_files/yarn.lock index 45d514de9b4..45a07b39d19 100644 --- a/mobile_files/yarn.lock +++ b/mobile_files/yarn.lock @@ -5527,6 +5527,10 @@ react-native-languages@^3.0.2: resolved "https://registry.yarnpkg.com/react-native-languages/-/react-native-languages-3.0.2.tgz#c2c4c5050974fe4b50f7372051ca1f9824c1c778" integrity sha512-LGsTfixFM6hXDhcFJI6mrtrNBsGPSvXT9RtZQ0tlqmGFKmMyZW6eQgJ7kLw8lISD2FIGl4jJwY06EAJpbMsNxg== +"react-native-mail@git+https://github.com/status-im/react-native-mail.git#v3.0.7_status": + version "3.0.7" + resolved "git+https://github.com/status-im/react-native-mail.git#9c002e9c178970786404f8ce34ba9b26c50ec6c0" + "react-native-os@git+https://github.com/status-im/react-native-os.git#v1.1.0-1-status": version "1.1.0" resolved "git+https://github.com/status-im/react-native-os.git#1a6d0835f919cb075793ad7c602f2724eee4702d" diff --git a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java index ccb0ebd6260..9dfc2111290 100644 --- a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java +++ b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java @@ -522,7 +522,7 @@ private Boolean zip(File[] _files, File zipFile, Stack errorList) { } out.close(); - + return true; } catch (Exception e) { Log.e(TAG, e.getMessage()); @@ -557,9 +557,9 @@ public void onClick(final DialogInterface dialog, final int id) { } }).show(); } - + @ReactMethod - public void sendLogs(final String dbJson) { + public void sendLogs(final String dbJson, final Callback callback) { Log.d(TAG, "sendLogs"); if (!checkAvailability()) { return; @@ -594,33 +594,14 @@ public void sendLogs(final String dbJson) { return; } } - + dumpAdbLogsTo(new FileOutputStream(statusLogFile)); - + final Stack errorList = new Stack(); final Boolean zipped = zip(new File[] {dbFile, gethLogFile, statusLogFile}, zipFile, errorList); if (zipped && zipFile.exists()) { - Log.d(TAG, "Sending " + zipFile.getAbsolutePath() + " file through share intent"); - - final String providerName = context.getPackageName() + ".provider"; - final Activity activity = getCurrentActivity(); zipFile.setReadable(true, false); - final Uri dbJsonURI = FileProvider.getUriForFile(activity, providerName, zipFile); - - Intent intentShareFile = new Intent(Intent.ACTION_SEND); - - intentShareFile.setType("application/json"); - intentShareFile.putExtra(Intent.EXTRA_STREAM, dbJsonURI); - - SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - dateFormatGmt.setTimeZone(java.util.TimeZone.getTimeZone("GMT")); - intentShareFile.putExtra(Intent.EXTRA_SUBJECT, "Status.im logs"); - intentShareFile.putExtra(Intent.EXTRA_TEXT, - String.format("Logs from %s GMT\n\nThese logs have been generated automatically by the user's request for debugging purposes.\n\n%s", - dateFormatGmt.format(new java.util.Date()), - errorList)); - - activity.startActivity(Intent.createChooser(intentShareFile, "Share Debug Logs")); + callback.invoke(zipFile.getAbsolutePath()); } else { Log.d(TAG, "File " + zipFile.getAbsolutePath() + " does not exist"); } diff --git a/react-native/src/mobile/status_im/react_native/js_dependencies.cljs b/react-native/src/mobile/status_im/react_native/js_dependencies.cljs index 2033ed47b03..aaaadf04bb8 100644 --- a/react-native/src/mobile/status_im/react_native/js_dependencies.cljs +++ b/react-native/src/mobile/status_im/react_native/js_dependencies.cljs @@ -28,6 +28,7 @@ (def snoopy-buffer (js/require "rn-snoopy/stream/buffer")) (def background-timer (.-default (js/require "react-native-background-timer"))) (def react-navigation (js/require "react-navigation")) +(def react-native-mail (.-default (js/require "react-native-mail"))) (def desktop-linking #js {:addEventListener (fn [])}) (def desktop-menu #js {:addEventListener (fn [])}) (def desktop-config #js {:addEventListener (fn [])}) diff --git a/src/status_im/native_module/core.cljs b/src/status_im/native_module/core.cljs index 403a898afd4..b7e7c474001 100644 --- a/src/status_im/native_module/core.cljs +++ b/src/status_im/native_module/core.cljs @@ -70,8 +70,8 @@ (defn send-data-notification [m callback] (native-module/send-data-notification m callback)) -(defn send-logs [dbJson] - (native-module/send-logs dbJson)) +(defn send-logs [dbJson callback] + (native-module/send-logs dbJson callback)) (defn add-peer [enode callback] (native-module/add-peer enode callback)) diff --git a/src/status_im/native_module/impl/module.cljs b/src/status_im/native_module/impl/module.cljs index 97743950687..53e85e9f2e5 100644 --- a/src/status_im/native_module/impl/module.cljs +++ b/src/status_im/native_module/impl/module.cljs @@ -49,9 +49,9 @@ (when status (.sendDataNotification status data-payload tokens on-result))) -(defn send-logs [dbJson] +(defn send-logs [dbJson callback] (when status - (.sendLogs status dbJson))) + (.sendLogs status dbJson callback))) (defn add-peer [enode on-result] (when (and @node-started status) diff --git a/src/status_im/utils/email.cljs b/src/status_im/utils/email.cljs new file mode 100644 index 00000000000..389571b8ef7 --- /dev/null +++ b/src/status_im/utils/email.cljs @@ -0,0 +1,16 @@ +(ns status-im.utils.email + (:require [re-frame.core :as re-frame] + [status-im.utils.fx :as fx] + [status-im.react-native.js-dependencies :as dependencies])) + +(re-frame/reg-fx + :email/send + ;; https://github.com/chirag04/react-native-mail#example + (fn [[opts callback]] + (.mail dependencies/react-native-mail + (clj->js opts) + callback))) + +(fx/defn send-email + [_ opts callback] + {:email/send [opts callback]}) diff --git a/src/status_im/utils/logging/core.cljs b/src/status_im/utils/logging/core.cljs index c77c9079caf..9589c46024c 100644 --- a/src/status_im/utils/logging/core.cljs +++ b/src/status_im/utils/logging/core.cljs @@ -2,10 +2,21 @@ (:require [re-frame.core :as re-frame] [status-im.native-module.core :as status] [status-im.utils.fx :as fx] - [status-im.utils.types :as types])) + [status-im.utils.types :as types] + [status-im.utils.handlers :as handlers] + [status-im.utils.email :as mail])) + +(def report-email "error-reports@status.im") + +(re-frame/reg-fx + :logs/archive-logs + (fn [[db-json callback-handler]] + (status/send-logs + db-json + #(re-frame/dispatch [callback-handler %])))) (fx/defn send-logs - [{:keys [db] :as cofx}] + [{:keys [db]}] ;; TODO: Add message explaining db export (let [db-json (types/clj->json (select-keys db [:app-state :current-chat-id @@ -29,4 +40,16 @@ :dimensions/window :my-profile/editing? :node/status]))] - (status/send-logs db-json))) + {:logs/archive-logs [db-json ::send-email]})) + +(handlers/register-handler-fx + ::send-email + (fn [cofx [_ archive-path]] + (mail/send-email cofx + {:subject "Error report" + :recipients [report-email] + :body "logs attached" + :attachment {:path archive-path + :type "zip" + :name "status_logs.zip"}} + (fn []))))