Compare commits

...
Author SHA1 Message Date
ibrkhalil 0ff1012c57 Rename endpoint 2024-01-01 16:33:08 +02:00
Ibrkhalil 7849d8debe Add lastOpenedAtKey for communities 2023-12-31 18:27:54 +02:00
Ibrahem Khalil e392608697 Fix no message preview on long press on the reaction (#18292) 2023-12-30 11:25:01 +02:00
Siddarth Kumar d495bb6b57 Kotlinify StatusOkHttpClientFactory.java (#18318)
This commit converts  
`android/app/src/main/java/im/status/ethereum/StatusOkHttpClientFactory.java` to
`android/app/src/main/java/im/status/ethereum/StatusOkHttpClientFactory.kt`
2023-12-29 16:57:27 +05:30
Parvesh Monu 7af62c04eb Keep chat screen loaded (#17839) 2023-12-29 14:55:12 +05:30
10 changed files with 120 additions and 129 deletions
@@ -0,0 +1,88 @@
package im.status.ethereum
import android.util.Log
import com.facebook.react.modules.network.OkHttpClientFactory
import com.facebook.react.modules.network.OkHttpClientProvider
import okhttp3.OkHttpClient
import okhttp3.tls.HandshakeCertificates
import java.io.ByteArrayInputStream
import java.lang.RuntimeException
import java.lang.reflect.Field
import java.lang.reflect.Method
import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate
import im.status.ethereum.module.StatusPackage
class StatusOkHttpClientFactory : OkHttpClientFactory {
companion object {
private const val TAG = "StatusOkHttpClientFactory"
private const val SLEEP_DURATION = 500L // milliseconds
}
override fun createNewNetworkModuleClient(): OkHttpClient? {
val certPem = getCertificatePem().takeIf { it.isNotEmpty() }
?: return logAndReturnNull("Certificate is empty, cannot create OkHttpClient without a valid certificate")
val cert = try {
induceSleep()
// Convert PEM certificate string to X509Certificate object
CertificateFactory.getInstance("X.509")
.generateCertificate(ByteArrayInputStream(certPem.toByteArray())) as? X509Certificate
?: return logAndReturnNull("Certificate could not be parsed as non-null")
} catch (e: Exception) {
return logAndReturnNull("Could not parse certificate", e)
}
val clientCertificates = try {
induceSleep()
// Create HandshakeCertificates object with our certificate
HandshakeCertificates.Builder()
.addPlatformTrustedCertificates()
.addTrustedCertificate(cert)
.build()
} catch (e: Exception) {
return logAndReturnNull("Could not build HandshakeCertificates", e)
}
return try {
OkHttpClientProvider.createClientBuilder()
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager)
.build()
} catch (e: Exception) {
logAndReturnNull("Could not create OkHttpClient", e)
}
}
private fun getCertificatePem(): String {
return try {
// Create OkHttpClient with custom SSL socket factory and trust manager
StatusPackage.getImageTLSCert().takeIf { !it.isNullOrBlank() }
?: logAndReturnEmpty("Certificate PEM string is null or empty")
} catch (e: Exception) {
logAndReturnEmpty("Could not getImageTLSCert", e)
}
}
private fun induceSleep() {
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices with
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
Thread.sleep(SLEEP_DURATION)
} catch (e: InterruptedException) {
Log.e(TAG, "Sleep interrupted", e)
}
}
private fun logAndReturnNull(message: String, e: Exception? = null): Nothing? {
Log.e(TAG, message, e)
return null
}
private fun logAndReturnEmpty(message: String, e: Exception? = null): String {
Log.e(TAG, message, e)
return ""
}
}
@@ -1,95 +0,0 @@
package im.status.ethereum;
import android.util.Log;
import com.facebook.react.modules.network.OkHttpClientFactory;
import com.facebook.react.modules.network.OkHttpClientProvider;
import okhttp3.OkHttpClient;
import okhttp3.Interceptor;
import okhttp3.tls.HandshakeCertificates;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.RuntimeException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import im.status.ethereum.module.StatusPackage;
class StatusOkHttpClientFactory implements OkHttpClientFactory {
private static final String TAG = "StatusOkHttpClientFactory";
public OkHttpClient createNewNetworkModuleClient() {
X509Certificate cert = null;
HandshakeCertificates clientCertificates;
String certPem = "";
// Get TLS PEM certificate from status-go
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices with
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
Thread.sleep(500);
certPem = getCertificatePem();
} catch(Exception e) {
Log.e(TAG, "Could not getImageTLSCert",e);
}
if (certPem.isEmpty()) {
Log.e(TAG, "Certificate is empty, cannot create OkHttpClient without a valid certificate");
return null;
}
// Convert PEM certificate string to X509Certificate object
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
Thread.sleep(500);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certPem.getBytes()));
} catch(Exception e) {
Log.e(TAG, "Could not parse certificate",e);
}
// Create HandshakeCertificates object with our certificate
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
Thread.sleep(500);
clientCertificates = new HandshakeCertificates.Builder()
.addPlatformTrustedCertificates()
.addTrustedCertificate(cert)
.build();
} catch(Exception e) {
Log.e(TAG, "Could not build HandshakeCertificates", e);
return null;
}
// Create OkHttpClient with custom SSL socket factory and trust manager
try {
return OkHttpClientProvider.createClientBuilder()
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager())
.build();
} catch(Exception e) {
Log.e(TAG, "Could not create OkHttpClient", e);
return null;
}
}
private String getCertificatePem() {
try {
String certPem = StatusPackage.getImageTLSCert();
if (certPem == null || certPem.trim().isEmpty()) {
Log.e(TAG, "Certificate PEM string is null or empty");
return "";
}
return certPem;
} catch (Exception e) {
Log.e(TAG, "Could not getImageTLSCert", e);
return "";
}
}
}
@@ -64,9 +64,10 @@
:use-case (when pinned-by :pinned)
:on-press #(on-press (assoc % :message-id message-id))
:on-long-press #(on-long-press (assoc %
:message-id message-id
:theme theme
:reactions-order (map :emoji-id reactions)))
:message-id message-id
:theme theme
:reactions-order (map :emoji-id reactions)
:user-message-content user-message-content))
:on-press-add #(on-press-add {:chat-id chat-id
:message-id message-id
:user-message-content user-message-content})}])]))
@@ -13,8 +13,7 @@
;; NOTE(parvesh) - I am working on refactoring/optimization of the chat screen for performance
;; improvement. Please avoid refactoring these files. Also if you are not already working on bug
;; fixes related to the chat navigation bar, please skip them.
;; And ping me, so I can address them while refactoring
;; fixes related to the composer, please skip them. And ping me, so I can address them while refactoring
(defn- f-chat-screen
[calculations-complete?]
(let [insets (safe-area/get-insets)
@@ -47,6 +46,8 @@
(defn lazy-chat-screen
[calculations-complete?]
(let [screen-loaded? (rf/sub [:shell/chat-screen-loaded?])]
(when-not screen-loaded?
(reanimated/set-shared-value calculations-complete? false))
(when screen-loaded?
[:f> f-chat-screen calculations-complete?])))
@@ -48,7 +48,8 @@
:tokenPermissions :token-permissions
:communityTokensMetadata :tokens-metadata
:introMessage :intro-message
:muteTill :muted-till})
:muteTill :muted-till
:lastOpenedAt :last-opened-at})
(update :admin-settings
set/rename-keys
{:pinMessageAllMembersEnabled :pin-message-all-members-enabled?})
@@ -169,6 +170,13 @@
{}
categories))}))
(rf/reg-event-fx :communities/update-last-opened-at
(fn [_ [community-id]]
{:json-rpc/call [{:method "wakuext_communityUpdateLastOpenedAt"
:params [community-id]
:on-success #(rf/dispatch [:communities/handle-community (first (:communities %))])
:on-error #(log/error (str "failed to update last opened at for community " %))}]}))
(rf/reg-event-fx :community/fetch
(fn [_]
{:json-rpc/call [{:method "wakuext_communities"
@@ -374,10 +374,11 @@
(rf/dispatch [:activity-center.notifications/dismiss-community-overview id]))
[community-scroll-page community pending?]))
(defn overview
(defn internal-overview
[id]
(let [id (or id (rf/sub [:get-screen-params :community-overview]))
customization-color (rf/sub [:profile/customization-color])]
(rn/use-effect #(rf/dispatch [:communities/update-last-opened-at id]) [id])
[rn/view {:style style/community-overview-container}
[community-card-page-view id]
[quo/floating-shell-button
@@ -385,3 +386,5 @@
:customization-color customization-color
:label (i18n/label :t/jump-to)}}
style/floating-shell-button]]))
(defn overview [id] [:f> internal-overview id])
@@ -1,6 +1,5 @@
(ns status-im.contexts.shell.jump-to.animation
(:require
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
[status-im.contexts.shell.jump-to.state :as state]
@@ -47,11 +46,6 @@
;;;; Floating Screen
;; Dispatch Delay - Animation time for the opening of a screen is 200 ms,
;; But starting and completion of animation sometimes takes a little extra time,
;; according to the performance of the device. And if before the animation is
;; complete we start other tasks like rendering messages or opening of the home screen
;; in the background then the animation breaks. So we are adding a small delay for that dispatch.
(defn animate-floating-screen
[screen-id {:keys [id animation community-id hidden-screen?]}]
(when (not= animation (get @state/floating-screens-state screen-id))
@@ -66,13 +60,7 @@
shell.constants/close-screen-without-animation}
animation)
0
shell.constants/shell-animation-time)
dispatch-delay (cond
(not floating-screen-open?) 0
js/goog.DEBUG 100
platform/android? 75
:else 50)
dispatch-time (+ animation-time dispatch-delay)]
shell.constants/shell-animation-time)]
(js/setTimeout
(fn [floating-screen-open?]
(if floating-screen-open?
@@ -81,7 +69,7 @@
id community-id hidden-screen?])
;; Events realted to closing of a screen
(rf/dispatch [:shell/floating-screen-closed screen-id])))
dispatch-time
animation-time
floating-screen-open?))))
(defn set-floating-screen-position
@@ -33,12 +33,9 @@
[rn/view
{:style (style/screen-container (utils/dimensions))
:accessibility-label (str screen-id "-floating-screen")
:accessible true
:key id}
:accessible true}
[(get screens-map screen-id) id]]]))
;; Currently chat screen and events both depends on current-chat-id, once we remove
;; use of current-chat-id from view then we can keep last chat loaded, for fast navigation
(defn lazy-screen
[screen-id]
(let [screen-param (rf/sub [:shell/floating-screen screen-id])]
@@ -201,9 +201,9 @@
(rf/defn floating-screen-closed
{:events [:shell/floating-screen-closed]}
[{:keys [db]} screen-id]
(merge
{:db (-> (update db :shell/floating-screens dissoc screen-id)
(update :shell/loaded-screens dissoc screen-id))
:dispatch-n (cond-> [[:set-view-id :shell-stack]]
(= screen-id shell.constants/chat-screen)
(conj [:chat/close]))}))
{:db (cond-> (update db :shell/loaded-screens dissoc screen-id)
(= screen-id shell.constants/discover-communities-screen)
(update :shell/floating-screen dissoc screen-id))
:dispatch-n (cond-> [[:set-view-id :shell-stack]]
(= screen-id shell.constants/chat-screen)
(conj [:chat/close]))})
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v0.171.39",
"commit-sha1": "debfe1cab368140b16d2383efc68007d3c28a4ef",
"src-sha256": "0cbj3796qz69ylwcvdw5jsl1cdyrcfk81d7shjkakvjh59rv5sjk"
"version": "4479",
"commit-sha1": "5d5a8edc1697df8879ab587a8e89436907373581",
"src-sha256": "1629dm4bjnl39fhxh6hgvs3wjv0m0c0a717f3xnprfjxn0vhpq5z"
}