[Fix #2408] Alternative setTimeout for long timers

Signed-off-by: Oskar Thoren <ot@oskarthoren.com>
This commit is contained in:
Foo Pang 2017-12-30 12:35:25 +08:00 committed by Oskar Thoren
parent d958c96d67
commit cd90e59325
No known key found for this signature in database
GPG Key ID: 5128AB0637CD85AF
24 changed files with 108 additions and 48 deletions

View File

@ -54,7 +54,8 @@
"rn-snoopy/stream/bars",
"rn-snoopy/stream/filter",
"rn-snoopy/stream/buffer",
"react-native/Libraries/vendor/emitter/EventEmitter"
"react-native/Libraries/vendor/emitter/EventEmitter",
"react-native-background-timer"
],
"imageDirs": [
"resources/images"

View File

@ -186,6 +186,7 @@ android {
}
dependencies {
implementation project(':react-native-background-timer')
implementation project(':react-native-svg')
implementation 'com.android.support:multidex:1.0.2'
implementation project(':react-native-http-bridge')

View File

@ -7,6 +7,7 @@ import com.bitgo.randombytes.RandomBytesPackage;
import org.devio.rn.splashscreen.SplashScreenReactPackage;
import com.centaurwarchief.smslistener.SmsListenerPackage;
import com.facebook.react.ReactApplication;
import com.ocetnik.timer.BackgroundTimerPackage;
import com.horcrux.svg.SvgPackage;
import com.evollu.react.fcm.FIRMessagingPackage;
import com.lugg.ReactNativeConfig.ReactNativeConfigPackage;
@ -58,6 +59,7 @@ public class MainApplication extends MultiDexApplication implements ReactApplica
Function<String, String> callRPC = statusPackage.getCallRPC();
List<ReactPackage> packages = new ArrayList<ReactPackage>(Arrays.asList(
new MainReactPackage(),
new BackgroundTimerPackage(),
new SvgPackage(),
new FIRMessagingPackage(),
new HttpServerReactPackage(),

View File

@ -1,4 +1,6 @@
rootProject.name = 'StatusIm'
include ':react-native-background-timer'
project(':react-native-background-timer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-timer/android')
include ':react-native-svg'
project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android')
include ':react-native-fcm'

View File

@ -18,7 +18,11 @@ target 'StatusIm' do
# Pods for StatusIm
pod 'Instabug', '~> 7.0'
pod 'FirebaseMessaging'
pod 'React', :path => '../node_modules/react-native'
pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
pod 'react-native-background-timer', :path => '../node_modules/react-native-background-timer'
target 'StatusImTests' do
inherit! :search_paths
# Pods for testing

View File

@ -20,10 +20,28 @@ PODS:
- GoogleToolboxForMac/Defines (= 2.1.1)
- Instabug (7.2.6)
- Protobuf (3.3.0)
- React (0.51.0):
- React/Core (= 0.51.0)
- react-native-background-timer (2.0.0):
- React
- React/Core (0.51.0):
- yoga (= 0.51.0.React)
- yoga (0.51.0.React)
DEPENDENCIES:
- FirebaseMessaging
- Instabug (~> 7.0)
- React (from `../node_modules/react-native`)
- react-native-background-timer (from `../node_modules/react-native-background-timer`)
- yoga (from `../node_modules/react-native/ReactCommon/yoga`)
EXTERNAL SOURCES:
React:
:path: ../node_modules/react-native
react-native-background-timer:
:path: ../node_modules/react-native-background-timer
yoga:
:path: ../node_modules/react-native/ReactCommon/yoga
SPEC CHECKSUMS:
FirebaseAnalytics: 4d7040fefc3cd8b291cde35f12cf063d7963f15d
@ -33,7 +51,10 @@ SPEC CHECKSUMS:
GoogleToolboxForMac: 8e329f1b599f2512c6b10676d45736bcc2cbbeb0
Instabug: 49d4fbf1bf14e2f9074dfb7774ca5611bae993b4
Protobuf: d582fecf68201eac3d79ed61369ef45734394b9c
React: 352f02f1db6e4744f9a758527e13e3fdefbbd6ba
react-native-background-timer: 10063c04bf85d7f8811dff8c74399f0aa715245f
yoga: b5d96400ca8b2936965a7a6516da7c1177f432a3
PODFILE CHECKSUM: 99245e16fcfd88ea22cee996e71ce86ab3a43138
PODFILE CHECKSUM: 2fb09df3e1ea33a8eef1757e72a6577bd5d547c1
COCOAPODS: 1.3.1

5
package-lock.json generated
View File

@ -7750,6 +7750,11 @@
"prop-types": "15.6.0"
}
},
"react-native-background-timer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/react-native-background-timer/-/react-native-background-timer-2.0.0.tgz",
"integrity": "sha512-vLNJIedXQZN4p3ChFsAgVHacnJqQMnLl+wBsnZuliRkmsjEHo8kQOA9fnLih/OoiDi1O3eHQvXC5L8f+RYiKgw=="
},
"react-native-camera": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/react-native-camera/-/react-native-camera-0.10.0.tgz",

View File

@ -50,6 +50,7 @@
"react-native-action-button": "2.8.1",
"react-native-android-sms-listener": "github:adrian-tiberius/react-native-android-sms-listener#listener-bugfix",
"react-native-autolink": "1.1.1",
"react-native-background-timer": "2.0.0",
"react-native-camera": "0.10.0",
"react-native-config": "0.9.0",
"react-native-contacts": "1.0.3",

View File

@ -36,3 +36,4 @@
(def snoopy-bars (js/require "rn-snoopy/stream/bars"))
(def snoopy-buffer (js/require "rn-snoopy/stream/buffer"))
(def EventEmmiter (js/require "react-native/Libraries/vendor/emitter/EventEmitter"))
(def background-timer (.-default (js/require "react-native-background-timer")))

View File

@ -18,7 +18,8 @@
[status-im.ui.components.react :as react]
[status-im.ui.components.icons.vector-icons :as vi]
[status-im.i18n :as i18n]
[status-im.utils.platform :as platform]))
[status-im.utils.platform :as platform]
[status-im.utils.utils :as utils]))
(defn command-view [first? command]
[react/touchable-highlight {:on-press #(dispatch [:select-chat-input-command command nil])}
@ -88,8 +89,8 @@
(.-height))]
(set-layout-height-fn h)))
:on-selection-change #(let [s (-> (.-nativeEvent %)
(.-selection))
end (.-end s)]
(.-selection))
end (.-end s)]
(dispatch [:update-text-selection end]))
:style (style/input-view height single-line-input?)
:placeholder-text-color style/color-input-helper-placeholder
@ -162,7 +163,7 @@
(when-not (or (str/blank? @seq-arg-input-text)
(get-in @command [:command :hide-send-button]))
(dispatch [:send-seq-argument]))
(js/setTimeout
(utils/set-timeout
#(dispatch [:chat-input-focus :seq-input-ref])
100))}
(get-options type))])))))
@ -228,7 +229,7 @@
(do
(when-not (str/blank? seq-arg-input-text)
(dispatch [:send-seq-argument]))
(js/setTimeout
(utils/set-timeout
(fn [] (dispatch [:chat-input-focus :seq-input-ref]))
100))
(dispatch [:send-current-message]))}

View File

@ -9,7 +9,7 @@
[goog.object :as object]))
(when js/goog.DEBUG
(object/set js/console "ignoredYellowBox" #js ["re-frame: overwriting" "Setting a timer"]))
(object/set js/console "ignoredYellowBox" #js ["re-frame: overwriting"]))
(defn init [app-root]
(log/set-level! config/log-level)

View File

@ -4,12 +4,12 @@
(:require [status-im.ui.components.react :as r]
[re-frame.core :refer [dispatch]]
[taoensso.timbre :as log]
[cljs.core.async :as async :refer [<! timeout]]
[cljs.core.async :as async :refer [<!]]
[status-im.utils.js-resources :as js-res]
[status-im.utils.platform :as p]
[status-im.utils.types :as types]
[status-im.utils.transducers :as transducers]
[status-im.utils.async :as async-util]
[status-im.utils.async :as async-util :refer [timeout]]
[status-im.react-native.js-dependencies :as rn-dependencies]
[status-im.native-module.module :as module]
[status-im.utils.config :as config]))

View File

@ -7,7 +7,8 @@
[taoensso.timbre :refer-macros [debug] :as log]
[status-im.protocol.validation :refer-macros [valid?]]
[clojure.set :as set]
[status-im.protocol.web3.keys :as shh-keys]))
[status-im.protocol.web3.keys :as shh-keys]
[status-im.utils.async :refer [timeout]]))
(defonce loop-state (atom nil))
(defonce messages (atom {}))
@ -85,7 +86,7 @@
(defn add-pending-message!
[web3 message]
{:pre [(valid? :protocol/message message)]}
{:pre [(valid? :protocol/message message)]}
(debug :add-pending-message! message)
;; encryption can take some time, better to run asynchronously
(async/put! pending-message-queue [web3 message]))
@ -237,7 +238,7 @@
(async/go-loop [_ nil]
(doseq [[_ messages] (@messages web3)]
(doseq [[_ {:keys [id message to type] :as data}] messages]
;; check each message asynchronously
;; check each message asynchronously
(when (should-be-retransmitted? options data)
(try
(let [message' (check-ttl message type ttl-config default-ttl)
@ -248,11 +249,11 @@
(finally
(attempt-was-made! web3 id to))))))
(when-not @stop?
(recur (async/<! (async/timeout delivery-loop-ms-interval)))))
(recur (async/<! (timeout delivery-loop-ms-interval)))))
(async/go-loop [_ nil]
(when-not @stop?
(online-message)
(recur (async/<! (async/timeout (* 1000 send-online-s-interval))))))))
(recur (async/<! (timeout (* 1000 send-online-s-interval))))))))
(defn reset-pending-messages! [to]
(doseq [key (@recipient->pending-message to)]

View File

@ -3,7 +3,8 @@
[status-im.ui.components.react :as react]
[status-im.ui.components.carousel.styles :as st]
[taoensso.timbre :as log]
[status-im.react-native.js-dependencies :as rn-dependencies]))
[status-im.react-native.js-dependencies :as rn-dependencies]
[status-im.utils.utils :as utils]))
(defn window-page-width []
@ -88,7 +89,7 @@
(log/debug "go-to-page: props-page-width=" page-width "; gap=" gap
"; page-position=" page-position "; page: " page)
(reagent.core/set-state component {:scrolling? true})
(js/setTimeout #(reagent.core/set-state component {:scrolling? false}) 200)
(utils/set-timeout #(reagent.core/set-state component {:scrolling? false}) 200)
(scroll-to component page-position 0)
(reagent.core/set-state component {:activePage page})
(when (:onPageChange props)

View File

@ -196,7 +196,7 @@
(if (or (nil? timeout)
(> 100 timeout))
(reset! loading false)
(js/setTimeout (fn []
(u/set-timeout (fn []
(reset! loading false))
timeout)))}
(if (and (not enabled?) @loading)

View File

@ -8,7 +8,8 @@
[status-im.data-store.core :as data-store]
[status-im.native-module.core :as status]
[status-im.constants :refer [console-chat-id]]
[status-im.utils.config :as config]))
[status-im.utils.config :as config]
[status-im.utils.utils :as utils]))
;;;; FX
@ -31,7 +32,7 @@
;; if we don't add delay when running app without status-go
;; "null is not an object (evaluating 'realm.schema')" error appears
(if config/stub-status-go?
(js/setTimeout
(utils/set-timeout
(fn []
(data-store/change-account address new-account?
#(dispatch [:change-account-handler % address new-account?])))

View File

@ -3,7 +3,8 @@
[status-im.protocol.core :as protocol]
[status-im.ui.screens.discover.navigation]
[status-im.utils.handlers :as handlers]
[clojure.string :as string]))
[clojure.string :as string]
[status-im.utils.utils :as utils]))
(def request-discoveries-interval-s 600)
(def maximum-number-of-discoveries 1000)
@ -117,8 +118,14 @@
(handlers/register-handler-fx
:init-discoveries
[(re-frame/inject-cofx :data-store/discoveries)]
(fn [{:keys [data-store/discoveries db]} _]
{:db (assoc db :discoveries discoveries)
(fn [{:keys [data-store/discoveries db] {:keys [request-discoveries-timer]} :db} _]
(when request-discoveries-timer
(utils/clear-interval request-discoveries-timer))
{:db (assoc db
:discoveries discoveries
:request-discoveries-timer
(utils/set-interval #(re-frame/dispatch [:request-discoveries])
(* request-discoveries-interval-s 1000)))
:dispatch [:request-discoveries]}))
(handlers/register-handler-fx
@ -126,18 +133,11 @@
[(re-frame/inject-cofx :random-id)]
(fn [{{:keys [current-public-key web3]
:contacts/keys [contacts]} :db
random-id :random-id} [this-event]]
;; this event calls itself at regular intervals
;; TODO (yenda): this was previously using setInterval explicitly, with
;; dispatch-later it is using it implicitly. setInterval is
;; problematic for such long period of time and will cause a warning
;; for Android in latest versions of react-nativexb
random-id :random-id} _]
{::request-discoveries {:current-public-key current-public-key
:web3 web3
:identities (handlers/identities contacts)
:message-id random-id}
:dispatch-later [{:ms (* request-discoveries-interval-s 1000)
:dispatch [this-event]}]}))
:message-id random-id}}))
(handlers/register-handler-fx
:discoveries-send-portions

View File

@ -15,7 +15,8 @@
[status-im.ui.screens.wallet.styles :as wallet.styles]
[status-im.utils.ethereum.core :as ethereum]
[status-im.utils.ethereum.eip681 :as eip681]
[status-im.utils.ethereum.tokens :as tokens]))
[status-im.utils.ethereum.tokens :as tokens]
[status-im.utils.utils :as utils]))
(defn toolbar-view []
[toolbar/toolbar {:style wallet.styles/toolbar}
@ -63,7 +64,7 @@
[qr-code amount symbol]]]]
[components/amount-selector
{:error amount-error
:input-options {:on-focus (fn [] (when @scroll (js/setTimeout #(.scrollToEnd @scroll) 100)))
:input-options {:on-focus (fn [] (when @scroll (utils/set-timeout #(.scrollToEnd @scroll) 100)))
:on-change-text #(re-frame/dispatch [:wallet.request/set-and-validate-amount %])}}]
[components/asset-selector {:type :request
:symbol symbol}]]]

View File

@ -46,7 +46,7 @@
::show-transaction-error
(fn [message]
;; (andrey) we need this timeout because modal window conflicts with alert
(js/setTimeout #(utils/show-popup (i18n/label :t/transaction-failed) message) 1000)))
(utils/set-timeout #(utils/show-popup (i18n/label :t/transaction-failed) message) 1000)))
(re-frame/reg-fx
:discard-transaction

View File

@ -182,7 +182,7 @@
(when-not sufficient-funds? (i18n/label :t/wallet-insufficient-funds)))
:input-options {:default-value (str (money/to-fixed (money/wei->ether amount)))
:max-length 21
:on-focus (fn [] (when @scroll (js/setTimeout #(.scrollToEnd @scroll) 100)))
:on-focus (fn [] (when @scroll (utils/set-timeout #(.scrollToEnd @scroll) 100)))
:on-change-text #(re-frame/dispatch [:wallet.send/set-and-validate-amount %])}}]
[advanced-options advanced? transaction modal?]]]
(if signing?

View File

@ -1,6 +1,12 @@
(ns status-im.utils.async
"Utility namespace containing `core.async` helper constructs"
(:require [cljs.core.async :as async]))
(:require [cljs.core.async :as async]
[status-im.utils.utils :as utils]))
(defn timeout [ms]
(let [c (async/chan)]
(utils/set-timeout (fn [] (async/close! c)) ms)
c))
(defn chunked-pipe!
"Connects input channel to the output channel with time-based chunking.
@ -16,7 +22,7 @@
(if flush?
(do (async/put! output-ch acc)
(recur [] false))
(let [[v ch] (async/alts! [input-ch (async/timeout flush-time)])]
(let [[v ch] (async/alts! [input-ch (timeout flush-time)])]
(if (= ch input-ch)
(if v
(recur (conj acc v) (and (seq acc) flush?))

View File

@ -1,6 +1,7 @@
(ns status-im.utils.pre-receiver
(:require [cljs.core.async :as async]
[taoensso.timbre :as log]))
[taoensso.timbre :as log]
[status-im.utils.async :as async-utils]))
;; See status-im.test.utils.pre-receiver for justification.
@ -25,7 +26,7 @@
(async/go-loop []
(let [{:keys [message-id clock-value] :as msg} (async/<! in-ch)]
(swap! seen conj [clock-value message-id])
(async/<! (async/timeout delay-ms))
(async/<! (async-utils/timeout delay-ms))
(async/put! mature-ch msg))
(recur))
(async/go-loop []

View File

@ -81,9 +81,16 @@
(fn [error]
(show-popup "Error" (str error))))))))
(defn deep-merge
"Recursively merge maps"
[& maps]
(if (every? map? maps)
(apply merge-with deep-merge maps)
(last maps)))
;; background-timer
(defn set-timeout [cb ms]
(.setTimeout rn-dependencies/background-timer cb ms))
(defn clear-timeout [id]
(.clearTimeout rn-dependencies/background-timer id))
(defn set-interval [cb ms]
(.setInterval rn-dependencies/background-timer cb ms))
(defn clear-interval [id]
(.clearInterval rn-dependencies/background-timer id))

View File

@ -41,4 +41,7 @@
(def snoopy-buffer #js {:default #js {}})
(def EventEmmiter #js {})
(def background-timer #js {:setTimeout js/setTimeout
:setInterval js/setInterval
:clearTimeout js/clearTimeout
:clearInterval js/clearInterval})