Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb28ac7370 | ||
|
|
cfab672f63 | ||
|
|
69221695b3 | ||
|
|
c44e5bbb67 | ||
|
|
826dd32c40 | ||
|
|
04b7357646 | ||
|
|
2c38c74c16 | ||
|
|
eb7a6ce45a | ||
|
|
525577ab17 | ||
|
|
83a7d3fafc | ||
|
|
4318bb6431 | ||
|
|
c466f96326 | ||
|
|
130308fa8a | ||
|
|
a858918b80 | ||
|
|
d5b8cde8e2 | ||
|
|
e5a30eaf1d | ||
|
|
b0fd58e9cb | ||
|
|
eeb8db00f7 | ||
|
|
3499cdc123 | ||
|
|
44b8a4c0f4 | ||
|
|
e45f959c27 | ||
|
|
cd86a1065b | ||
|
|
ffba396e4d | ||
|
|
961692251c | ||
|
|
94fde74b88 | ||
|
|
5402c217df | ||
|
|
4588dafe02 | ||
|
|
edbb06a7c3 | ||
|
|
29a7e4dc1c | ||
|
|
de3c08ba18 | ||
|
|
e5ff46fdd5 |
@@ -32,3 +32,5 @@ METRICS_ENABLED=0
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
COLLECTIBLES_ENABLED=1
|
||||
COMMANDS_ENABLED=1
|
||||
TWO_MINUTES_SYNCING=1
|
||||
SWAP_ENABLED=1
|
||||
|
||||
@@ -33,3 +33,4 @@ COMMUNITIES_ENABLED=1
|
||||
COMMUNITIES_MANAGEMENT_ENABLED=1
|
||||
METRICS_ENABLED=0
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
TWO_MINUTES_SYNCING=1
|
||||
|
||||
@@ -35,3 +35,4 @@ COMMUNITIES_ENABLED=1
|
||||
COMMUNITIES_MANAGEMENT_ENABLED=1
|
||||
METRICS_ENABLED=0
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
TWO_MINUTES_SYNCING=1
|
||||
|
||||
@@ -27,7 +27,7 @@ Upgrade (e2e):
|
||||
### Process
|
||||
#### 1) Kick-off
|
||||
- [ ] 1. Translation PRs is merged before cutting branch (Jinho)
|
||||
- [ ] 2. Prepare scope of visible changes based on commits history, started from previous release branch cut ([example]( https://notes.status.im/1.14-release-notes?view))
|
||||
- [ ] 2. Prepare scope of visible changes based on commits history, started from previous release branch cut ([guide](https://notes.status.im/how-to-prepare-release-notes))
|
||||
- [ ] 3. Update [RELEASES.md](https://github.com/status-im/status-react/blob/develop/RELEASES.md) with release notes (make PR based on previous step)
|
||||
- [ ] 4. Create release branch using this [guide](https://github.com/status-im/status-react/blob/develop/doc/RELEASE_GUIDE.md), bump VERSION (merge created PR ([example](https://github.com/status-im/status-react/pull/12504) ) to develop) and get successful release builds (so, testing can be started)
|
||||
- [ ] 5. Based on release scope, ask for comms (Jonny)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="alert_background">#141414</color>
|
||||
<color name="alert_text">#ffffff</color>
|
||||
</resources>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="alert_background">#ffffff</color>
|
||||
<color name="alert_text">#000000</color>
|
||||
</resources>
|
||||
@@ -8,6 +8,7 @@
|
||||
<item name="android:forceDarkAllowed">true</item>
|
||||
<item name="android:windowTranslucentStatus">false</item>
|
||||
<item name="android:statusBarColor">?attr/backgroundColor</item>
|
||||
<item name="android:alertDialogTheme">@style/AlertDialogTheme</item>
|
||||
</style>
|
||||
|
||||
<style name="LightTheme" parent="AppTheme">
|
||||
@@ -21,4 +22,10 @@
|
||||
<item name="backgroundColor">#000000</item>
|
||||
<item name="android:windowLightStatusBar">false</item>
|
||||
</style>
|
||||
|
||||
<style name="AlertDialogTheme" parent="Theme.AppCompat.DayNight.Dialog.Alert">
|
||||
<item name="android:textColor">@color/alert_text</item>
|
||||
<item name="android:textColorPrimary">@color/alert_text</item>
|
||||
<item name="android:background">@color/alert_background</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
library 'status-jenkins-lib@v1.3.3'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
agent { label 'linux && x86_64 && nix-2.3' }
|
||||
|
||||
options {
|
||||
timestamps()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
library 'status-jenkins-lib@v1.3.3'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos && x86_64 && xcode-12.5' }
|
||||
agent { label 'macos && x86_64 && nix-2.3 && xcode-12.5' }
|
||||
|
||||
parameters {
|
||||
string(
|
||||
|
||||
@@ -3,15 +3,15 @@ pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
parameters {
|
||||
string(
|
||||
name: 'NETWORK',
|
||||
description: 'Name of test network to use.',
|
||||
defaultValue: 'ropsten',
|
||||
)
|
||||
string(
|
||||
name: 'APK_NAME',
|
||||
description: 'Filename of APK uploaded to SauceLabs.',
|
||||
)
|
||||
string(
|
||||
name: 'KEYWORD_EXPRESSION',
|
||||
description: 'This will run tests which contain names that match the given string expression (Optional)',
|
||||
defaultValue: '',
|
||||
)
|
||||
}
|
||||
|
||||
options {
|
||||
@@ -56,8 +56,8 @@ pipeline {
|
||||
--rerun_count=2 \
|
||||
--testrail_report=True \
|
||||
-m testrail_id \
|
||||
-m "not upgrade" \
|
||||
--network=${params.NETWORK} \
|
||||
-m \"not upgrade\" \
|
||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||
--apk=${params.APK_NAME}
|
||||
"""
|
||||
}
|
||||
|
||||
@@ -8,16 +8,12 @@ pipeline {
|
||||
description: 'Name of the branch to checkout and build.',
|
||||
defaultValue: 'develop',
|
||||
)
|
||||
string(
|
||||
name: 'NETWORK',
|
||||
description: 'Name of test network to use.',
|
||||
defaultValue: 'ropsten',
|
||||
)
|
||||
/* Commented to use TEST_MARKERS values from job params
|
||||
string(
|
||||
name: 'TEST_MARKERS',
|
||||
description: 'Marker expression for matching tests to run.',
|
||||
defaultValue: 'critical or high',
|
||||
)
|
||||
) */
|
||||
string(
|
||||
name: 'APK_NAME',
|
||||
description: 'Filename of APK uploaded to SauceLabs, path, or URL.',
|
||||
@@ -26,9 +22,14 @@ pipeline {
|
||||
name: 'PR_ID',
|
||||
description: 'ID of the Pull Request triggering this build.',
|
||||
)
|
||||
string(
|
||||
name: 'KEYWORD_EXPRESSION',
|
||||
description: 'This will run tests which contain names that match the given string expression (Optional)',
|
||||
defaultValue: '',
|
||||
)
|
||||
string(
|
||||
name: 'TR_CASE_IDS',
|
||||
description: 'IDs of the TestRail case, separated by a comma. (Optional)',
|
||||
description: 'IDs of the TestRail case, separated by a comma (Optional)',
|
||||
defaultValue: '',
|
||||
)
|
||||
}
|
||||
@@ -91,8 +92,8 @@ pipeline {
|
||||
--numprocesses 15 \
|
||||
--rerun_count=2 \
|
||||
--testrail_report=True \
|
||||
-m "${params.TEST_MARKERS}" \
|
||||
--network=${params.NETWORK} \
|
||||
-m \"${params.TEST_MARKERS}\" \
|
||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||
--apk=${params.APK_NAME} \
|
||||
--build=PR-${params.PR_ID} \
|
||||
--pr_number=${params.PR_ID} \
|
||||
|
||||
@@ -3,11 +3,6 @@ pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
parameters {
|
||||
string(
|
||||
name: 'NETWORK',
|
||||
description: 'Name of test network to use',
|
||||
defaultValue: 'ropsten',
|
||||
)
|
||||
string(
|
||||
name: 'APK_NAME',
|
||||
description: 'Filename of APK uploaded to SauceLabs (base for upgrade, usually release build)',
|
||||
@@ -16,6 +11,16 @@ pipeline {
|
||||
name: 'APK_NAME_UPGRADE',
|
||||
description: 'Filename of APK of upgraded application (installed on top of base)',
|
||||
)
|
||||
string(
|
||||
name: 'KEYWORD_EXPRESSION',
|
||||
description: 'This will run tests which contain names that match the given string expression (Optional)',
|
||||
defaultValue: '',
|
||||
)
|
||||
string(
|
||||
name: 'TR_CASE_IDS',
|
||||
description: 'IDs of the TestRail case, separated by a comma (Optional)',
|
||||
defaultValue: '',
|
||||
)
|
||||
}
|
||||
|
||||
options {
|
||||
@@ -32,7 +37,12 @@ pipeline {
|
||||
} }
|
||||
}
|
||||
stage('Test') {
|
||||
steps {
|
||||
steps { script {
|
||||
/* for managing optional arguments */
|
||||
def extraPytestOpts = ''
|
||||
if (params.TR_CASE_IDS != '') {
|
||||
extraPytestOpts = "--run_testrail_ids='${params.TR_CASE_IDS}'"
|
||||
}
|
||||
withCredentials([
|
||||
usernamePassword(
|
||||
credentialsId: 'test-rail-api',
|
||||
@@ -56,18 +66,19 @@ pipeline {
|
||||
dir('test/appium/tests') {
|
||||
sh """
|
||||
python3 -m pytest \
|
||||
-m upgrade \
|
||||
-m "upgrade" \
|
||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||
--numprocesses 15 \
|
||||
--rerun_count=2 \
|
||||
--testrail_report=True \
|
||||
--network=${params.NETWORK} \
|
||||
--apk=${params.APK_NAME} \
|
||||
--apk_upgrade=${params.APK_NAME_UPGRADE}
|
||||
--apk_upgrade=${params.APK_NAME_UPGRADE} \
|
||||
${extraPytestOpts}
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
||||
post {
|
||||
|
||||
@@ -163,4 +163,8 @@ used for some abi encoding primitives
|
||||
|
||||
## "rn-emoji-keyboard": "https://github.com/status-im/rn-emoji-keyboard"
|
||||
|
||||
Used for taking emoji input, for custom emoji thumbnails for community channels
|
||||
Used for taking emoji input, for custom emoji thumbnails for community channels
|
||||
|
||||
## "react-native-draggable-flatlist": "https://github.com/computerjazz/react-native-draggable-flatlist"
|
||||
|
||||
A drag-and-drop-enabled FlatList component for React Native
|
||||
|
||||
@@ -230,7 +230,7 @@ PODS:
|
||||
- React
|
||||
- react-native-status (1.0.0):
|
||||
- React
|
||||
- react-native-status-keycard (2.5.36):
|
||||
- react-native-status-keycard (2.5.37):
|
||||
- Keycard
|
||||
- React
|
||||
- react-native-webview (11.3.0):
|
||||
@@ -626,7 +626,7 @@ SPEC CHECKSUMS:
|
||||
FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
|
||||
FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
|
||||
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
|
||||
glog: 5bc68409594b19a3e5c5cbced7b1ecf61053b709
|
||||
glog: 61334f8bdb4deea07543d4fbac3fb5948e78a7a5
|
||||
Keycard: dd96182888da0aacf4de821b641103143bbb26cc
|
||||
libwebp: 98a37e597e40bfdb4c911fc98f2c53d0b12d05fc
|
||||
Permission-Camera: afad27bf90337684d4a86f3825112d648c8c4d3b
|
||||
@@ -653,7 +653,7 @@ SPEC CHECKSUMS:
|
||||
react-native-slider: 12bd76d3d568c9c5500825db54123d44b48e4ad4
|
||||
react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
|
||||
react-native-status: 45dbf1302ce3c258b459dfab137cd1c2c68c295d
|
||||
react-native-status-keycard: eb84554a23315510948613a9467e7e3481be340c
|
||||
react-native-status-keycard: 961d01ca190889ddf220206822fd752f8f4f3f7a
|
||||
react-native-webview: af9990b21a9aeafa8e8347746eb4116c0de086af
|
||||
React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336
|
||||
React-RCTAnimation: 1bde3ecc0c104c55df246eda516e0deb03c4e49b
|
||||
|
||||
@@ -1011,6 +1011,25 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
StatusThreadPoolExecutor.getInstance().execute(r);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void recover(final String rpcParams, final Callback callback) {
|
||||
Log.d(TAG, "recover");
|
||||
if (!checkAvailability()) {
|
||||
callback.invoke(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String res = Statusgo.recover(rpcParams);
|
||||
callback.invoke(res);
|
||||
}
|
||||
};
|
||||
|
||||
StatusThreadPoolExecutor.getInstance().execute(r);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void signTypedData(final String data, final String account, final String password, final Callback callback) {
|
||||
Log.d(TAG, "signTypedData");
|
||||
|
||||
@@ -662,6 +662,18 @@ RCT_EXPORT_METHOD(signMessage:(NSString *)message
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - Recover
|
||||
//////////////////////////////////////////////////////////////////// recover
|
||||
RCT_EXPORT_METHOD(recover:(NSString *)message
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"Recover() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoRecover(message);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - SignTypedData
|
||||
//////////////////////////////////////////////////////////////////// signTypedData
|
||||
|
||||
@@ -1147,6 +1147,20 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "androidx/webkit/webkit/1.4.0/webkit-1.4.0",
|
||||
"host": "https://dl.google.com/dl/android/maven2",
|
||||
"type": "aar",
|
||||
"pom": {
|
||||
"sha1": "c67e70da5ad98b587cc030a053e3eb45b57ae2a6",
|
||||
"sha256": "0pdmx702dmx83q6svafk1vyac9fnlbz0szxwg4ax9fnlzvc12mfb"
|
||||
},
|
||||
"jar": {
|
||||
"sha1": "48e4cd9c63f7dc9fc62631d8dfbb77e890b459aa",
|
||||
"sha256": "15wip2fimx1xpdv6mwdyn2wsd2yfh9kbfrjkv9rdwlhkmh5b448s"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "android/arch/core/common/1.0.0/common-1.0.0",
|
||||
"host": "https://dl.google.com/dl/android/maven2",
|
||||
@@ -5662,16 +5676,16 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/google/auto/value/auto-value-annotations/1.8.2/auto-value-annotations-1.8.2",
|
||||
"path": "com/google/auto/value/auto-value-annotations/1.9/auto-value-annotations-1.9",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
"type": "jar",
|
||||
"pom": {
|
||||
"sha1": "b50f6be2fc88ebdf201fe89c871e2c0d4d96cf95",
|
||||
"sha256": "083560cp200w5w3h2ksn1piazrr2i0466n6rx49055ygb1vd8h2z"
|
||||
"sha1": "a5c14e2bc293fe9d24d4ec21c2ba966e4832313d",
|
||||
"sha256": "12n9z19gvs617f18p2n2p9k8ci1kz06y9c31y0s97ivmpvda684j"
|
||||
},
|
||||
"jar": {
|
||||
"sha1": "546ae662e646e47a544ef68ebb43987a3146b692",
|
||||
"sha256": "0vhzd5zzbgw8svq5m76yykj7axxzl6lm693w67yzbzqiqs7q8air"
|
||||
"sha1": "25a0fcef915f663679fcdb447541c5d86a9be4ba",
|
||||
"sha256": "0i406m8xyahcza6rj32y1j54kinbkl5anczhv2i9irafqks6jm7s"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -5686,12 +5700,12 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/google/auto/value/auto-value-parent/1.8.2/auto-value-parent-1.8.2",
|
||||
"path": "com/google/auto/value/auto-value-parent/1.9/auto-value-parent-1.9",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
"type": "pom",
|
||||
"pom": {
|
||||
"sha1": "c86ec2e16ac581366a70e4739125a43b133210fb",
|
||||
"sha256": "0rpnrkw72s45lw506kh5dlh7d4b1ihbvcby4bwc5j8wh0mn52jkf"
|
||||
"sha1": "a5a5f16386e4889a6bc0b98c6f6caced5f15764f",
|
||||
"sha256": "11yprfs5ggj5pff2bzzbywqy1n6bdf071qfph6wcl0cncgzrsg9f"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -6580,16 +6594,16 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/squareup/okhttp3/okhttp/5.0.0-alpha.2/okhttp-5.0.0-alpha.2",
|
||||
"path": "com/squareup/okhttp3/okhttp/5.0.0-alpha.3/okhttp-5.0.0-alpha.3",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
"type": "jar",
|
||||
"pom": {
|
||||
"sha1": "afe00f17c08b21b7e356667a05f18b948bd64b95",
|
||||
"sha256": "0kqa21fl17l9l9s5kncvsz92wayp6i285qqf1v23fkb58ig20m4l"
|
||||
"sha1": "f57e69bf80c4307a338188b1629fd0dc09814df4",
|
||||
"sha256": "1nsq0ar2sr9yhhkip3f6jzpyp66jz1vzb1mb2b7xn0hn24zd2nbd"
|
||||
},
|
||||
"jar": {
|
||||
"sha1": "bf7bed2b2469e05290e258813396114ef080f574",
|
||||
"sha256": "1zzmw406i776k076cmrx9g52s7slqw93nq4zga9da7g6q3fwlp7a"
|
||||
"sha1": "b1636a6c8b77837a3a34f197ebdf8e9f48bdc1d7",
|
||||
"sha256": "1a3iya8n1gc50m79pjh1520gckgbfs7882kmkzj8frhg5sjc97gh"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -6623,6 +6637,20 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/squareup/okio/okio-jvm/3.0.0/okio-jvm-3.0.0",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
"type": "jar",
|
||||
"pom": {
|
||||
"sha1": "63dca88e80ade884bc68585baa9940f5c8027bfa",
|
||||
"sha256": "1ym2ydp7b9nqfi9nfmliyjqhwhny926698jk58xmhyb39i277jxh"
|
||||
},
|
||||
"jar": {
|
||||
"sha1": "0ab5a73fa2ccb4a36b0b5c69fe10b16d0255bcf8",
|
||||
"sha256": "01z946cpr2dzjyrrbi1qsw4chwmgaxspxpbhr7arrsi83z6a0r5y"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/squareup/okio/okio-parent/1.15.0/okio-parent-1.15.0",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
@@ -6647,20 +6675,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/squareup/okio/okio/2.9.0/okio-2.9.0",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
"type": "jar",
|
||||
"pom": {
|
||||
"sha1": "eaa6725bd15c851530d55f235208568dfb399bb8",
|
||||
"sha256": "1xppblf9xwjkzck8mbjl88kg2dbhjrdl1hs5hl0bzmsb01dkiqgj"
|
||||
},
|
||||
"jar": {
|
||||
"sha1": "0dcc813b08ce5933f8bdfd1dfbab4ad4bd170e7a",
|
||||
"sha256": "0i4vyq8bvzfkqnx466b93yhdwckckibnd7am0s20pp3y7cb5q9dr"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/squareup/okio/okio/3.0.0/okio-3.0.0",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
@@ -8184,12 +8198,12 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/httpcomponents/httpcomponents-core/4.4.14/httpcomponents-core-4.4.14",
|
||||
"path": "org/apache/httpcomponents/httpcomponents-core/4.4.15/httpcomponents-core-4.4.15",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
"type": "pom",
|
||||
"pom": {
|
||||
"sha1": "6dede7e95d51c365a10c346b010797c2656edc65",
|
||||
"sha256": "1lds3j5my5iij5kjj8v42c365nisq2lwl9z0vx9856aprcqxk7i0"
|
||||
"sha1": "3533a4d4bbf8fb489bc20795ba2826d3a95baa7d",
|
||||
"sha256": "02d5ijdcvj5gkx5wb90h84y7zr1jqsf3xy8pmv408j0plqkkgm30"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -8284,16 +8298,16 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/httpcomponents/httpcore/4.4.14/httpcore-4.4.14",
|
||||
"path": "org/apache/httpcomponents/httpcore/4.4.15/httpcore-4.4.15",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
"type": "jar",
|
||||
"pom": {
|
||||
"sha1": "16db7143a7586192ac1d863c7ecfaf25541bbc47",
|
||||
"sha256": "1n3zdgxwa7nqx85fvih715zsy3aqq3pqlp72z41h5wbqm6c66wam"
|
||||
"sha1": "fcd592279d3c26678aad344894e20f9a01102a16",
|
||||
"sha256": "0sxyq51hjv24rw14kiwwlz2qscj07l5s6wa3qc7n5fw8iamgxb19"
|
||||
},
|
||||
"jar": {
|
||||
"sha1": "9dd1a631c082d92ecd4bd8fd4cf55026c720a8c1",
|
||||
"sha256": "0a1vlr5r9w0bnxifv60jkbdxi79ywlivvpvn2z2x1c8c8ng20mpr"
|
||||
"sha1": "7f2e0c573eaa7a74bac2e89b359e1f73d92a0a1d",
|
||||
"sha256": "0hmi3c0p5a2m2v53i0fqmdqm3677q2fz6n6ydpwi16j9ih4fvfiw"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -8520,16 +8534,16 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/checkerframework/checker-qual/3.19.0/checker-qual-3.19.0",
|
||||
"path": "org/checkerframework/checker-qual/3.21.1/checker-qual-3.21.1",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
"type": "jar",
|
||||
"pom": {
|
||||
"sha1": "7afbf123d32e21bee825bb85dc0be42ca6466fed",
|
||||
"sha256": "0wd3i9zrk3zbsxgpfjcsy68ba9sq5xhyvi13v05p0jx9w5f9rfi9"
|
||||
"sha1": "8702ac7cebf178330090c6a3a9149a33a5c32ade",
|
||||
"sha256": "1ajmkrhrpvdwp2qldnp7cp7nd3z4d8rp65bghzx2il270fv6jsw7"
|
||||
},
|
||||
"jar": {
|
||||
"sha1": "838b42bb6f7f73315167b359d24649845cef1c48",
|
||||
"sha256": "0s5a93bln2b109brsys40wak9jw66rks9817glkk59pkhf8w89x8"
|
||||
"sha1": "cfa7c49db84e21f9fd7799584d7d09f28a665db7",
|
||||
"sha256": "0czlxlbxzpa7ys9rjpz9kwm729dpbf7jfah25x35h88syvvxsyvn"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -9729,34 +9743,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jetbrains/kotlin/kotlin-stdlib-common/1.4.10/kotlin-stdlib-common-1.4.10",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
"type": "jar",
|
||||
"pom": {
|
||||
"sha1": "a7a2da276e4c795619d6dd862cf8db356906ca3c",
|
||||
"sha256": "002xa53xg74zhfsgh6p17xzs6k2lbzj91zx694mp9pnllxr0wj33"
|
||||
},
|
||||
"jar": {
|
||||
"sha1": "6229be3465805c99db1142ad75e6c6ddeac0b04c",
|
||||
"sha256": "1zkl29qhssa8m3k92z7nl2fjyf71b1byv12xb4ipb3566vag50a6"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jetbrains/kotlin/kotlin-stdlib-common/1.4.21/kotlin-stdlib-common-1.4.21",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
"type": "jar",
|
||||
"pom": {
|
||||
"sha1": "079977f80977960cfc8bc34ddd3d12f9d198682e",
|
||||
"sha256": "1gay55x737xvn3af5dddlai0mgy6j81r69bfnw7ayf7qh2w0m16d"
|
||||
},
|
||||
"jar": {
|
||||
"sha1": "7f48a062aa4b53215998780f7c245a4276828e1d",
|
||||
"sha256": "1zxwrhz7fl4qzrxn2q252b8z005nm5r2sppr8wgpxin4v6bz2b41"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jetbrains/kotlin/kotlin-stdlib-common/1.4.30/kotlin-stdlib-common-1.4.30",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
@@ -9855,6 +9841,20 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.5.31/kotlin-stdlib-jdk7-1.5.31",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
"type": "jar",
|
||||
"pom": {
|
||||
"sha1": "b3f53ded7aa6f0f85abfeca4b1a721849587de2d",
|
||||
"sha256": "0y4p0y6csx1h7knpn649z4da3gq0yx2pg1v8f0cnhfi9xs4q84r3"
|
||||
},
|
||||
"jar": {
|
||||
"sha1": "77e0f2568912e45d26c31fd417a332458508acdf",
|
||||
"sha256": "0py1sypb9rq10f6pzagvwxrk99r1sqbfbpmx7j29v2ffadrz8nx2"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.2.71/kotlin-stdlib-jdk8-1.2.71",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
@@ -9911,6 +9911,20 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.5.31/kotlin-stdlib-jdk8-1.5.31",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
"type": "jar",
|
||||
"pom": {
|
||||
"sha1": "6b1353e3e341eeddeea8e67db3d89bed51ceb920",
|
||||
"sha256": "1pwkm0nx186pma90db27hxzb7lhqmwnjpc07b20jnybl02mhl4a5"
|
||||
},
|
||||
"jar": {
|
||||
"sha1": "ff5d99aecd328872494e8921b72bf6e3af97af3e",
|
||||
"sha256": "1p2z9ifcwm1mwa307dhrvsz3wvdx883l8ivy8792kw5cg9vgfj5m"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jetbrains/kotlin/kotlin-stdlib-jre7/1.2.0/kotlin-stdlib-jre7-1.2.0",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
@@ -10065,34 +10079,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jetbrains/kotlin/kotlin-stdlib/1.4.10/kotlin-stdlib-1.4.10",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
"type": "jar",
|
||||
"pom": {
|
||||
"sha1": "1ae8d0e617a4e272ce07664ad928c57b171e31f9",
|
||||
"sha256": "0qi77kk5dssssijv0j4fav5zgh5rbxvjrm943spj79dx9fxwzfd4"
|
||||
},
|
||||
"jar": {
|
||||
"sha1": "ea29e063d2bbe695be13e9d044dcfb0c7add398e",
|
||||
"sha256": "1aldbd3x859ldvyhlh05bllhnd48l4hwz6l3q4qvjhn0habv1v01"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jetbrains/kotlin/kotlin-stdlib/1.4.21/kotlin-stdlib-1.4.21",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
"type": "jar",
|
||||
"pom": {
|
||||
"sha1": "65b290e29135432a1cd6bd364407d39b271f09ff",
|
||||
"sha256": "1gp23b2hbl287xd29r8wf3bihsrxg03j7qaj1c2s56x7nwlmlv07"
|
||||
},
|
||||
"jar": {
|
||||
"sha1": "4a668382d7c38688d3490afde93b6a113ed46698",
|
||||
"sha256": "06yh6zhs73imf9mg0ldisw4g5pak7cydx8c3mc95k66v1665v37p"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jetbrains/kotlin/kotlin-stdlib/1.4.30/kotlin-stdlib-1.4.30",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
@@ -10121,6 +10107,20 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jetbrains/kotlin/kotlin-stdlib/1.5.31/kotlin-stdlib-1.5.31",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
"type": "jar",
|
||||
"pom": {
|
||||
"sha1": "f0765608cf114ef9fd254be913fcc39797b40cc4",
|
||||
"sha256": "0v1fhm2dhr0jvdiislprp39vjxdd3gfk7w6914q8fkmc0h0pcxlg"
|
||||
},
|
||||
"jar": {
|
||||
"sha1": "6628d61d0f5603568e72d2d5915d2c034b4f1c55",
|
||||
"sha256": "0s3y58i395qvpga35fjfxb8yl62kwfw58w88kaavj2zcnancw028"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jetbrains/kotlin/kotlin-test-common/1.4.31/kotlin-test-common-1.4.31",
|
||||
"host": "https://repo.maven.apache.org/maven2",
|
||||
|
||||
@@ -71,6 +71,7 @@ androidx.versionedparcelable:versionedparcelable:1.0.0
|
||||
androidx.versionedparcelable:versionedparcelable:1.1.0
|
||||
androidx.viewpager2:viewpager2:1.0.0
|
||||
androidx.viewpager:viewpager:1.0.0
|
||||
androidx.webkit:webkit:1.4.0
|
||||
commons-codec:commons-codec:1.4
|
||||
commons-codec:commons-codec:1.6
|
||||
commons-codec:commons-codec:1.9
|
||||
|
||||
@@ -80,6 +80,7 @@ https://dl.google.com/dl/android/maven2/androidx/versionedparcelable/versionedpa
|
||||
https://dl.google.com/dl/android/maven2/androidx/versionedparcelable/versionedparcelable/1.1.0/versionedparcelable-1.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/viewpager2/viewpager2/1.0.0/viewpager2-1.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/viewpager/viewpager/1.0.0/viewpager-1.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/webkit/webkit/1.4.0/webkit-1.4.0.pom
|
||||
https://dl.google.com/dl/android/maven2/android/arch/core/common/1.0.0/common-1.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/android/arch/lifecycle/common/1.0.0/common-1.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/android/arch/lifecycle/runtime/1.0.0/runtime-1.0.0.pom
|
||||
@@ -403,9 +404,9 @@ https://repo.maven.apache.org/maven2/com/googlecode/juniversalchardet/juniversal
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/auto-parent/3/auto-parent-3.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/auto-parent/6/auto-parent-6.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-annotations/1.6.2/auto-value-annotations-1.6.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-annotations/1.8.2/auto-value-annotations-1.8.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-annotations/1.9/auto-value-annotations-1.9.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-parent/1.6.2/auto-value-parent-1.6.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-parent/1.8.2/auto-value-parent-1.8.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-parent/1.9/auto-value-parent-1.9.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value/1.5.2/auto-value-1.5.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/2.0.1/jsr305-2.0.1.pom
|
||||
@@ -476,13 +477,13 @@ https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp-urlconnection/3
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/3.9.1/okhttp-3.9.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/3.12.1/okhttp-3.12.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/3.12.12/okhttp-3.12.12.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/5.0.0-alpha.2/okhttp-5.0.0-alpha.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/5.0.0-alpha.3/okhttp-5.0.0-alpha.3.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.9.1/parent-3.9.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.12.1/parent-3.12.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.12.12/parent-3.12.12.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.0.0/okio-jvm-3.0.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-parent/1.15.0/okio-parent-1.15.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/1.15.0/okio-1.15.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.9.0/okio-2.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.0.0/okio-3.0.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.0/all-1.2.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/sun/activation/all/2.0.1/all-2.0.1.pom
|
||||
@@ -610,7 +611,7 @@ https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcomponents-co
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcomponents-core/4.4.5/httpcomponents-core-4.4.5.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcomponents-core/4.4.6/httpcomponents-core-4.4.6.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcomponents-core/4.4.10/httpcomponents-core-4.4.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcomponents-core/4.4.14/httpcomponents-core-4.4.14.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcomponents-core/4.4.15/httpcomponents-core-4.4.15.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcomponents-parent/10/httpcomponents-parent-10.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcomponents-parent/11/httpcomponents-parent-11.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcore/4.1/httpcore-4.1.pom
|
||||
@@ -618,7 +619,7 @@ https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcore/4.2.5/ht
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcore/4.4.5/httpcore-4.4.5.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcore/4.4.6/httpcore-4.4.6.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcore/4.4.10/httpcore-4.4.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcore/4.4.14/httpcore-4.4.14.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpcore/4.4.15/httpcore-4.4.15.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpmime/4.1/httpmime-4.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpmime/4.5.2/httpmime-4.5.2.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpmime/4.5.6/httpmime-4.5.6.pom
|
||||
@@ -636,7 +637,7 @@ https://repo.maven.apache.org/maven2/org/bouncycastle/bcprov-jdk15on/1.56/bcprov
|
||||
https://repo.maven.apache.org/maven2/org/bouncycastle/bcprov-jdk15on/1.60/bcprov-jdk15on-1.60.pom
|
||||
https://repo.maven.apache.org/maven2/org/bouncycastle/bcprov-jdk15on/1.65/bcprov-jdk15on-1.65.pom
|
||||
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/2.5.2/checker-qual-2.5.2.pom
|
||||
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.19.0/checker-qual-3.19.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.21.1/checker-qual-3.21.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/codehaus/codehaus-parent/4/codehaus-parent-4.pom
|
||||
https://repo.maven.apache.org/maven2/org/codehaus/groovy/groovy-all/2.4.15/groovy-all-2.4.15.pom
|
||||
https://repo.maven.apache.org/maven2/org/codehaus/mojo/animal-sniffer-annotations/1.14/animal-sniffer-annotations-1.14.pom
|
||||
@@ -727,8 +728,6 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.31/kotlin-stdlib-common-1.3.31.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.50/kotlin-stdlib-common-1.3.50.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.71/kotlin-stdlib-common-1.3.71.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.10/kotlin-stdlib-common-1.4.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.21/kotlin-stdlib-common-1.4.21.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.30/kotlin-stdlib-common-1.4.30.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.31/kotlin-stdlib-common-1.4.31.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.5.31/kotlin-stdlib-common-1.5.31.pom
|
||||
@@ -736,10 +735,12 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.2
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.3.20/kotlin-stdlib-jdk7-1.3.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.3.50/kotlin-stdlib-jdk7-1.3.50.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.4.31/kotlin-stdlib-jdk7-1.4.31.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.5.31/kotlin-stdlib-jdk7-1.5.31.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.2.71/kotlin-stdlib-jdk8-1.2.71.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.3.20/kotlin-stdlib-jdk8-1.3.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.3.50/kotlin-stdlib-jdk8-1.3.50.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.4.31/kotlin-stdlib-jdk8-1.4.31.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.5.31/kotlin-stdlib-jdk8-1.5.31.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jre7/1.2.0/kotlin-stdlib-jre7-1.2.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jre8/1.2.0/kotlin-stdlib-jre8-1.2.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.1.3-2/kotlin-stdlib-1.1.3-2.pom
|
||||
@@ -751,10 +752,9 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.3.20/k
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.3.31/kotlin-stdlib-1.3.31.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.3.50/kotlin-stdlib-1.3.50.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.3.71/kotlin-stdlib-1.3.71.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.4.10/kotlin-stdlib-1.4.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.4.21/kotlin-stdlib-1.4.21.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.4.30/kotlin-stdlib-1.4.30.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.4.31/kotlin-stdlib-1.4.31.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.5.31/kotlin-stdlib-1.5.31.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-test-common/1.4.31/kotlin-test-common-1.4.31.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-test/1.4.31/kotlin-test-1.4.31.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-util-io/1.3.50/kotlin-util-io-1.3.50.pom
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
"react-native-dark-mode": "^0.2.2",
|
||||
"react-native-device-info": "^7.4.0",
|
||||
"react-native-dialogs": "^1.0.4",
|
||||
"react-native-draggable-flatlist": "^3.0.3",
|
||||
"react-native-fast-image": "8.5.11",
|
||||
"react-native-fetch-polyfill": "^1.1.2",
|
||||
"react-native-fs": "^2.14.1",
|
||||
@@ -62,7 +63,7 @@
|
||||
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#v2.5.37",
|
||||
"react-native-svg": "^9.8.4",
|
||||
"react-native-touch-id": "^4.4.1",
|
||||
"react-native-webview": "git+https://github.com/status-im/react-native-webview.git#v11.3.0-status",
|
||||
"react-native-webview": "git+https://github.com/status-im/react-native-webview.git#v11.16.0-status",
|
||||
"rn-emoji-keyboard": "git+https://github.com/status-im/rn-emoji-keyboard.git#v0.4.2",
|
||||
"tdigest": "^0.1.1",
|
||||
"web3-utils": "^1.2.1"
|
||||
|
||||
|
After Width: | Height: | Size: 527 B |
|
After Width: | Height: | Size: 899 B |
|
After Width: | Height: | Size: 196 B |
|
After Width: | Height: | Size: 250 B |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
@@ -107,6 +107,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
if (window.statusAppDebug) { console.log("resolve " + callback.method + " :" + JSON.stringify(data.result.result)); }
|
||||
callback.resolve(data.result.result);
|
||||
}
|
||||
}
|
||||
@@ -239,6 +240,7 @@
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
callbacks[messageId] = {beta: true,
|
||||
method: method,
|
||||
resolve: resolve,
|
||||
reject: reject};
|
||||
});
|
||||
|
||||
@@ -206,6 +206,9 @@
|
||||
(def rn-emoji-keyboard
|
||||
#js {:EmojiKeyboard #js {}})
|
||||
|
||||
(def react-native-draggable-flatlist
|
||||
#js {:default #js {}})
|
||||
|
||||
;; Update i18n_resources.cljs
|
||||
(defn mock [module]
|
||||
(case module
|
||||
@@ -239,6 +242,7 @@
|
||||
"@react-native-community/push-notification-ios" push-notification-ios
|
||||
"react-native-camera-kit" react-native-camera-kit
|
||||
"rn-emoji-keyboard" rn-emoji-keyboard
|
||||
"react-native-draggable-flatlist" react-native-draggable-flatlist
|
||||
"./fleets.js" default-fleets
|
||||
"./chats.js" default-chats
|
||||
"../translations/ar.json" (js/JSON.parse (slurp "./translations/ar.json"))
|
||||
|
||||
@@ -55,13 +55,13 @@
|
||||
:small :base
|
||||
:large))
|
||||
|
||||
(defn container [{:keys [size]} & children]
|
||||
(defn container [{:keys [size container-style]} & children]
|
||||
(into [rn/view {:style (merge (:tiny spacing/padding-horizontal)
|
||||
{:min-height (size->container-size size)
|
||||
:padding-vertical 8
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :space-between})}]
|
||||
:justify-content :space-between} container-style)}]
|
||||
children))
|
||||
|
||||
(defn icon-column
|
||||
@@ -197,17 +197,19 @@
|
||||
left-side-alignment icon-color icon-bg-color
|
||||
title subtitle subtitle-secondary active on-press on-long-press chevron size text-size
|
||||
accessory-text accessibility-label title-accessibility-label accessory-style
|
||||
haptic-feedback haptic-type error animated animated-accessory? title-text-weight]
|
||||
:or {subtitle-max-lines 1
|
||||
theme :main
|
||||
haptic-feedback true
|
||||
animated platform/ios?
|
||||
haptic-type :selection}}]
|
||||
haptic-feedback haptic-type error animated animated-accessory? title-text-weight container-style
|
||||
active-background-enabled]
|
||||
:or {subtitle-max-lines 1
|
||||
theme :main
|
||||
haptic-feedback true
|
||||
animated platform/ios?
|
||||
active-background-enabled true
|
||||
haptic-type :selection}}]
|
||||
(let [theme (if disabled :disabled theme)
|
||||
{:keys [text-color active-background passive-background]}
|
||||
(themes theme)
|
||||
icon-color (or icon-color (:icon-color (themes theme)))
|
||||
icon-bg-color (or icon-bg-color (:icon-bg-color (themes theme)))
|
||||
icon-color (or icon-color (:icon-color (themes theme)))
|
||||
icon-bg-color (or icon-bg-color (:icon-bg-color (themes theme)))
|
||||
optional-haptic (fn []
|
||||
(when haptic-feedback
|
||||
(haptic/trigger haptic-type)))
|
||||
@@ -223,7 +225,7 @@
|
||||
[component
|
||||
(merge {:type :list-item
|
||||
:disabled disabled
|
||||
:bg-color active-background
|
||||
:bg-color (when active-background-enabled active-background)
|
||||
:accessibility-label accessibility-label}
|
||||
(when on-press
|
||||
{:on-press (fn []
|
||||
@@ -233,7 +235,7 @@
|
||||
{:on-long-press (fn []
|
||||
(optional-haptic)
|
||||
(on-long-press))}))
|
||||
[container {:size size}
|
||||
[container {:size size :container-style container-style}
|
||||
[left-side {:icon-color icon-color
|
||||
:text-color (if on-press
|
||||
text-color
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
["react-native" :as rn]
|
||||
["@react-native-community/hooks" :as hooks]
|
||||
["react-native-navigation" :refer (Navigation)]
|
||||
["rn-emoji-keyboard" :refer (EmojiKeyboard)]))
|
||||
["rn-emoji-keyboard" :refer (EmojiKeyboard)]
|
||||
["react-native-draggable-flatlist" :default DraggableFlatList]))
|
||||
|
||||
(def rn-draggable-flatlist (reagent/adapt-react-class DraggableFlatList))
|
||||
|
||||
(def emoji-keyboard (reagent/adapt-react-class EmojiKeyboard))
|
||||
|
||||
@@ -107,7 +110,13 @@
|
||||
|
||||
(defn- wrap-render-fn [f render-data]
|
||||
(fn [data]
|
||||
(reagent/as-element [f (.-item ^js data) (.-index ^js data) (.-separators ^js data) render-data])))
|
||||
(reagent/as-element [f (.-item ^js data) (.-index ^js data)
|
||||
(.-separators ^js data) render-data
|
||||
(.-isActive ^js data) (.-drag ^js data)])))
|
||||
|
||||
(defn- wrap-on-drag-end-fn [f]
|
||||
(fn [data]
|
||||
(f (.-from ^js data) (.-to ^js data) (.-data ^js data))))
|
||||
|
||||
(defn- wrap-key-fn [f]
|
||||
(fn [data index]
|
||||
@@ -115,19 +124,23 @@
|
||||
(f data index)))
|
||||
|
||||
(defn base-list-props
|
||||
[{:keys [key-fn render-fn empty-component header footer separator data render-data] :as props}]
|
||||
[{:keys [key-fn render-fn empty-component header footer separator data render-data on-drag-end-fn] :as props}]
|
||||
(merge {:data (to-array data)}
|
||||
(when key-fn {:keyExtractor (wrap-key-fn key-fn)})
|
||||
(when render-fn {:renderItem (wrap-render-fn render-fn render-data)})
|
||||
(when separator {:ItemSeparatorComponent (fn [] (reagent/as-element separator))})
|
||||
(when empty-component {:ListEmptyComponent (fn [] (reagent/as-element empty-component))})
|
||||
(when header {:ListHeaderComponent (reagent/as-element header)})
|
||||
(when footer {:ListFooterComponent (reagent/as-element footer)})
|
||||
(dissoc props :data :header :footer :empty-component :separator :render-fn :key-fn)))
|
||||
(when key-fn {:keyExtractor (wrap-key-fn key-fn)})
|
||||
(when render-fn {:renderItem (wrap-render-fn render-fn render-data)})
|
||||
(when separator {:ItemSeparatorComponent (fn [] (reagent/as-element separator))})
|
||||
(when empty-component {:ListEmptyComponent (fn [] (reagent/as-element empty-component))})
|
||||
(when header {:ListHeaderComponent (reagent/as-element header)})
|
||||
(when footer {:ListFooterComponent (reagent/as-element footer)})
|
||||
(when on-drag-end-fn {:onDragEnd (wrap-on-drag-end-fn on-drag-end-fn)})
|
||||
(dissoc props :data :header :footer :empty-component :separator :render-fn :key-fn :on-drag-end-fn)))
|
||||
|
||||
(defn flat-list [props]
|
||||
[rn-flat-list (base-list-props props)])
|
||||
|
||||
(defn draggable-flat-list [props]
|
||||
[rn-draggable-flatlist (base-list-props props)])
|
||||
|
||||
(defn animated-flat-list [props]
|
||||
[animated-flat-list-class (base-list-props props)])
|
||||
;; Hooks
|
||||
|
||||
@@ -418,12 +418,19 @@
|
||||
:result {:jsonrpc "2.0"
|
||||
:id (int id)
|
||||
:result (if (= method "eth_coinbase") dapps-address [dapps-address])}})
|
||||
{:browser/call-rpc [payload
|
||||
#(re-frame/dispatch [:browser.callback/call-rpc
|
||||
{:type constants/web3-send-async-callback
|
||||
:messageId message-id
|
||||
:error %1
|
||||
:result %2}])]}))))
|
||||
(if (= method "personal_ecRecover")
|
||||
{:signing.fx/recover-message {:params {:message (first params)
|
||||
:signature (second params)}
|
||||
:on-completed #(re-frame/dispatch [:browser.callback/call-rpc
|
||||
{:type constants/web3-send-async-callback
|
||||
:messageId message-id
|
||||
:result (types/json->clj %)}])}}
|
||||
{:browser/call-rpc [payload
|
||||
#(re-frame/dispatch [:browser.callback/call-rpc
|
||||
{:type constants/web3-send-async-callback
|
||||
:messageId message-id
|
||||
:error %1
|
||||
:result %2}])]})))))
|
||||
|
||||
(fx/defn handle-no-permissions [cofx {:keys [method id]} message-id]
|
||||
(if (= method "eth_accounts")
|
||||
@@ -504,9 +511,9 @@
|
||||
:browser/send-to-bridge
|
||||
(fn [message]
|
||||
(let [^js webview @webview-ref/webview-ref
|
||||
msg (str "ReactNativeWebView.onMessage('"
|
||||
msg (str "(function() { var __send = function() { if (ReactNativeWebView.onMessage) { ReactNativeWebView.onMessage('"
|
||||
(types/clj->json message)
|
||||
"');")]
|
||||
"');} else {setTimeout(__send, 0)}}; __send();})();")]
|
||||
(when (and message webview)
|
||||
(.injectJavaScript webview msg)))))
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@
|
||||
{:chat-id chat-id
|
||||
:content-type constants/content-type-image
|
||||
:image-path (utils/safe-replace uri #"file://" "")
|
||||
:text (i18n/label :t/update-to-see-image)})
|
||||
:text (i18n/label :t/update-to-see-image {"locale" "en"})})
|
||||
images)))
|
||||
|
||||
(fx/defn clean-input [{:keys [db] :as cofx} current-chat-id]
|
||||
@@ -227,7 +227,7 @@
|
||||
:content-type constants/content-type-audio
|
||||
:audio-path audio-path
|
||||
:audio-duration-ms duration
|
||||
:text (i18n/label :t/update-to-listen-audio)})))
|
||||
:text (i18n/label :t/update-to-listen-audio {"locale" "en"})})))
|
||||
|
||||
(fx/defn send-sticker-message
|
||||
[cofx {:keys [hash pack]} current-chat-id]
|
||||
@@ -236,7 +236,7 @@
|
||||
:content-type constants/content-type-sticker
|
||||
:sticker {:hash hash
|
||||
:pack pack}
|
||||
:text (i18n/label :t/update-to-see-sticker)})))
|
||||
:text (i18n/label :t/update-to-see-sticker {"locale" "en"})})))
|
||||
|
||||
(fx/defn send-edited-message [{:keys [db] :as cofx} text {:keys [message-id]}]
|
||||
(fx/merge
|
||||
|
||||
@@ -42,11 +42,15 @@
|
||||
[{:keys [db]} community-id]
|
||||
{:db (community-failed-to-resolve db community-id)})
|
||||
|
||||
(defn community-link [id]
|
||||
(str "https://join.status.im/c/" id))
|
||||
|
||||
(fx/defn handle-community-resolved
|
||||
{:events [::community-resolved]}
|
||||
[{:keys [db] :as cofx} community-id community]
|
||||
(fx/merge cofx
|
||||
{:db (community-resolved db community-id)}
|
||||
{:db (community-resolved db community-id)
|
||||
:dispatch [::cache-link-preview-data (community-link community-id) community]}
|
||||
(models.communities/handle-community community)))
|
||||
|
||||
(fx/defn resolve-community-info
|
||||
@@ -78,9 +82,6 @@
|
||||
:link-previews-cache
|
||||
(assoc (get multiaccount :link-previews-cache {}) site data)))
|
||||
|
||||
(defn community-link [id]
|
||||
(str "https://join.status.im/c/" id))
|
||||
|
||||
(defn cache-community-preview-data
|
||||
[{:keys [id] :as community}]
|
||||
(re-frame/dispatch [::cache-link-preview-data
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im.native-module.core :as status]
|
||||
[quo.react-native :as rn]
|
||||
[quo.react :as react]))
|
||||
[quo.react :as react]
|
||||
[status-im.multiaccounts.core :as multiaccounts]))
|
||||
|
||||
(def at-sign "@")
|
||||
|
||||
@@ -170,53 +171,83 @@
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn get-mentionable-users
|
||||
[{{:keys [current-chat-id]
|
||||
:contacts/keys [contacts] :as db} :db}]
|
||||
(let [{:keys [chat-type users] :as chat}
|
||||
(get-in db [:chats current-chat-id])
|
||||
chat-specific-suggestions
|
||||
(cond
|
||||
(= chat-type constants/private-group-chat-type)
|
||||
(let [{:keys [public-key]} (:multiaccount db)
|
||||
all-contacts (:contacts/contacts db)
|
||||
group-contacts
|
||||
(contact.db/get-all-contacts-in-group-chat
|
||||
(disj (:contacts chat) public-key)
|
||||
nil
|
||||
all-contacts
|
||||
nil)]
|
||||
(reduce
|
||||
(fn [acc {:keys [alias public-key identicon name]}]
|
||||
(assoc acc public-key
|
||||
{:alias alias
|
||||
:identicon identicon
|
||||
:public-key public-key
|
||||
:name name}))
|
||||
{}
|
||||
group-contacts))
|
||||
(= chat-type constants/one-to-one-chat-type)
|
||||
(assoc users
|
||||
current-chat-id
|
||||
(contact.db/public-key->contact contacts current-chat-id))
|
||||
(defn add-searchable-phrases
|
||||
[{:keys [alias name nickname] :as user}]
|
||||
(reduce
|
||||
(fn [user s]
|
||||
(if (nil? s)
|
||||
user
|
||||
(let [new-words (concat
|
||||
[s]
|
||||
(rest (string/split s " ")))]
|
||||
(update user :searchable-phrases (fnil concat []) new-words))))
|
||||
user
|
||||
[alias name nickname]))
|
||||
|
||||
:else users)
|
||||
{:keys [name preferred-name public-key]}
|
||||
(:multiaccount db)]
|
||||
(reduce
|
||||
(fn [acc [key {:keys [alias name identicon]}]]
|
||||
(let [name (utils/safe-replace name ".stateofus.eth" "")]
|
||||
(assoc acc key
|
||||
{:alias alias
|
||||
:name (or name alias)
|
||||
:identicon identicon
|
||||
:public-key key})))
|
||||
(assoc chat-specific-suggestions
|
||||
public-key
|
||||
{:alias name
|
||||
:name (or preferred-name name)
|
||||
:public-key public-key})
|
||||
contacts)))
|
||||
(defn add-searchable-phrases-to-contact
|
||||
[{:keys [alias name added? blocked? identicon public-key nickname]} community-chat?]
|
||||
(when (and alias
|
||||
(not (string/blank? alias))
|
||||
(or name
|
||||
nickname
|
||||
added?
|
||||
community-chat?)
|
||||
(not blocked?))
|
||||
(add-searchable-phrases
|
||||
{:alias alias
|
||||
:name (or (utils/safe-replace name ".stateofus.eth" "") alias)
|
||||
:identicon identicon
|
||||
:nickname nickname
|
||||
:public-key public-key})))
|
||||
|
||||
(defn mentionable-contacts [contacts]
|
||||
(reduce
|
||||
(fn [acc [key contact]]
|
||||
(let [mentionable-contact (add-searchable-phrases-to-contact contact false)]
|
||||
(if (nil? mentionable-contact)
|
||||
acc
|
||||
(assoc acc key mentionable-contact))))
|
||||
{}
|
||||
contacts))
|
||||
|
||||
(defn mentionable-contacts-from-identites [contacts my-public-key identities]
|
||||
(reduce (fn [acc identity]
|
||||
(let [contact (multiaccounts/contact-by-identity
|
||||
contacts identity)
|
||||
contact (if (string/blank? (:alias contact))
|
||||
(assoc contact :alias
|
||||
(get-in contact [:names :three-words-name]))
|
||||
contact)
|
||||
mentionable-contact (add-searchable-phrases-to-contact
|
||||
contact true)]
|
||||
(if (nil? mentionable-contact) acc
|
||||
(assoc acc identity mentionable-contact))))
|
||||
{}
|
||||
(remove #(= my-public-key %) identities)))
|
||||
|
||||
(defn get-mentionable-users [chat all-contacts current-multiaccount community-members]
|
||||
(let [{:keys [name preferred-name public-key]} current-multiaccount
|
||||
{:keys [chat-id users contacts chat-type]} chat
|
||||
mentionable-contacts (mentionable-contacts all-contacts)
|
||||
mentionable-users (assoc users public-key {:alias name
|
||||
:name (or preferred-name name)
|
||||
:public-key public-key})]
|
||||
(cond
|
||||
(= chat-type constants/private-group-chat-type)
|
||||
(merge mentionable-users
|
||||
(mentionable-contacts-from-identites all-contacts public-key contacts))
|
||||
|
||||
(= chat-type constants/one-to-one-chat-type)
|
||||
(assoc mentionable-users chat-id (get mentionable-contacts chat-id
|
||||
(-> chat-id
|
||||
contact.db/public-key->new-contact
|
||||
contact.db/enrich-contact)))
|
||||
|
||||
(= chat-type constants/community-chat-type)
|
||||
(merge mentionable-users
|
||||
(mentionable-contacts-from-identites all-contacts public-key (keys community-members)))
|
||||
|
||||
:else (merge mentionable-users mentionable-contacts))))
|
||||
|
||||
(def ending-chars "[\\s\\.,;:]")
|
||||
(def ending-chars-regex (re-pattern ending-chars))
|
||||
@@ -328,8 +359,14 @@
|
||||
(recur new-text users (rest idxs)
|
||||
(+ diff (- (count text) (count new-text)))))))))))))
|
||||
|
||||
(defn check-mentions [cofx text]
|
||||
(replace-mentions text (get-mentionable-users cofx)))
|
||||
(defn check-mentions [{:keys [db]} text]
|
||||
(let [current-chat-id (:current-chat-id db)
|
||||
chat (get-in db [:chats current-chat-id])
|
||||
all-contacts (:contacts/contacts db)
|
||||
current-multiaccount (:multiaccount db)
|
||||
community-members (get-in db [:communities (:community-id chat) :members])
|
||||
mentionable-users (get-mentionable-users chat all-contacts current-multiaccount community-members)]
|
||||
(replace-mentions text mentionable-users)))
|
||||
|
||||
(defn get-at-sign-idxs
|
||||
([text start]
|
||||
@@ -634,19 +671,6 @@
|
||||
[_ ref cursor]
|
||||
{::reset-text-input-cursor [ref cursor]})
|
||||
|
||||
(defn add-searchable-phrases
|
||||
[{:keys [alias name nickname] :as user}]
|
||||
(reduce
|
||||
(fn [user s]
|
||||
(if (nil? s)
|
||||
user
|
||||
(let [new-words (concat
|
||||
[s]
|
||||
(rest (string/split s " ")))]
|
||||
(update user :searchable-phrases (fnil concat []) new-words))))
|
||||
user
|
||||
[alias name nickname]))
|
||||
|
||||
(defn is-valid-terminating-character? [c]
|
||||
(case c
|
||||
"\t" true ; tab
|
||||
|
||||
@@ -221,12 +221,10 @@
|
||||
(fx/defn create
|
||||
{:events [::create-confirmation-pressed]}
|
||||
[{:keys [db]}]
|
||||
(let [{:keys [name description image]} (get db :communities/create)]
|
||||
;; If access is ENS only, we set the access to require approval and set the rule
|
||||
;; of ens only
|
||||
(let [{:keys [name description membership image]} (get db :communities/create)]
|
||||
(let [params {:name name
|
||||
:description description
|
||||
:membership constants/community-on-request-access
|
||||
:membership membership
|
||||
:color (rand-nth colors/chat-colors)
|
||||
:image (string/replace-first (str image) #"file://" "")
|
||||
:imageAx 0
|
||||
@@ -288,7 +286,7 @@
|
||||
(fx/defn edit-channel
|
||||
{:events [::edit-channel-confirmation-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{:keys [name description color community-id emoji edit-channel-id category-id]}
|
||||
(let [{:keys [name description color community-id emoji edit-channel-id category-id position]}
|
||||
(get db :communities/create-channel)]
|
||||
{::json-rpc/call [{:method "wakuext_editCommunityChat"
|
||||
:params [community-id
|
||||
@@ -298,6 +296,7 @@
|
||||
:color color
|
||||
:emoji emoji}
|
||||
:category_id category-id
|
||||
:position position
|
||||
:permissions {:access constants/community-channel-access-no-membership}}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::community-channel-edited %])
|
||||
@@ -345,7 +344,7 @@
|
||||
|
||||
(fx/defn edit-channel-pressed
|
||||
{:events [::edit-channel-pressed]}
|
||||
[{:keys [db] :as cofx} community-id chat-name description color emoji chat-id category-id]
|
||||
[{:keys [db] :as cofx} community-id chat-name description color emoji chat-id category-id position]
|
||||
(let [{:keys [color emoji]} (if (string/blank? emoji)
|
||||
(rand-nth emoji-thumbnail-styles/emoji-picker-default-thumbnails)
|
||||
{:color color :emoji emoji})]
|
||||
@@ -356,7 +355,8 @@
|
||||
:community-id community-id
|
||||
:emoji emoji
|
||||
:edit-channel-id chat-id
|
||||
:category-id category-id})}
|
||||
:category-id category-id
|
||||
:position position})}
|
||||
(navigation/open-modal :edit-community-channel nil))))
|
||||
|
||||
(fx/defn community-created
|
||||
@@ -564,6 +564,15 @@
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to remove chat from community" %)}]}))
|
||||
|
||||
(fx/defn delete-community-chat
|
||||
{:events [:delete-community-chat]}
|
||||
[_ community-id chat-id]
|
||||
{::json-rpc/call [{:method "wakuext_deleteCommunityChat"
|
||||
:params [community-id chat-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to delete community chat" %)}]})
|
||||
|
||||
(fx/defn delete-category
|
||||
{:events [:delete-community-category]}
|
||||
[_ community-id category-id]
|
||||
@@ -592,6 +601,18 @@
|
||||
(navigation/navigate-back)
|
||||
(remove-chat-from-category community-id id categoryID))))
|
||||
|
||||
(fx/defn reorder-category-chat
|
||||
{:events [::reorder-community-category-chat]}
|
||||
[_ community-id category-id chat-id new-position]
|
||||
{::json-rpc/call [{:method "wakuext_reorderCommunityChat"
|
||||
:params [{:communityId community-id
|
||||
:categoryId category-id
|
||||
:chatId chat-id
|
||||
:position new-position}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to reorder community category chat" %)}]})
|
||||
|
||||
(fx/defn reorder-category
|
||||
{:events [::reorder-community-category]}
|
||||
[_ community-id category-id new-position]
|
||||
|
||||
@@ -146,6 +146,7 @@
|
||||
|
||||
(def ^:const timeline-chat-id "@timeline70bd746ddcc12beb96b2c9d572d0784ab137ffc774f5383e50585a932080b57cca0484b259e61cecbaa33a4c98a300a")
|
||||
|
||||
(def ^:const two-mins (* 2 60))
|
||||
(def ^:const one-day (* 60 60 24))
|
||||
(def ^:const three-days (* one-day 3))
|
||||
(def ^:const one-week (* one-day 7))
|
||||
|
||||
@@ -165,6 +165,7 @@
|
||||
"wakuext_reorderCommunityChat" {}
|
||||
"wakuext_editCommunityCategory" {}
|
||||
"wakuext_deleteCommunityCategory" {}
|
||||
"wakuext_deleteCommunityChat" {}
|
||||
"wakuext_ensVerified" {}
|
||||
"wakuext_dismissActivityCenterNotifications" {}
|
||||
"wakuext_acceptActivityCenterNotifications" {}
|
||||
|
||||
@@ -778,6 +778,10 @@
|
||||
{:address "0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72"
|
||||
:symbol :ENS
|
||||
:name "Ethereum Name Service"
|
||||
:decimals 18}
|
||||
{:address "0xDd1Ad9A21Ce722C151A836373baBe42c868cE9a4"
|
||||
:symbol :UBI
|
||||
:name "Universal Basic Income"
|
||||
:decimals 18}])
|
||||
:testnet
|
||||
(resolve-icons :testnet
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[status-im.async-storage.core :as async-storage]
|
||||
status-im.backup.core
|
||||
status-im.bootnodes.core
|
||||
status-im.bottom-sheet.core
|
||||
[status-im.bottom-sheet.core :as bottom-sheet]
|
||||
status-im.browser.core
|
||||
status-im.browser.permissions
|
||||
[status-im.chat.models :as chat]
|
||||
@@ -58,7 +58,9 @@
|
||||
status-im.wallet.accounts.core
|
||||
status-im.wallet.choose-recipient.core
|
||||
[status-im.wallet.core :as wallet]
|
||||
status-im.wallet.custom-tokens.core))
|
||||
status-im.wallet.custom-tokens.core
|
||||
[status-im.navigation.core :as navigation.core]
|
||||
[status-im.multiaccounts.login.core :as login.core]))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:dismiss-keyboard
|
||||
@@ -112,10 +114,35 @@
|
||||
|
||||
(fx/defn system-theme-mode-changed
|
||||
{:events [:system-theme-mode-changed]}
|
||||
[{:keys [db]} theme]
|
||||
(let [cur-theme (get-in db [:multiaccount :appearance])]
|
||||
[{:keys [db] :as cofx} theme]
|
||||
(let [cur-theme (get-in db [:multiaccount :appearance])
|
||||
current-tab (get db :current-tab :chat)
|
||||
view-id (:view-id db)
|
||||
screen-params (get-in db [:navigation/screen-params view-id])
|
||||
root-id @navigation.core/root-id]
|
||||
(navigation.core/dismiss-all-modals)
|
||||
(when (or (nil? cur-theme) (zero? cur-theme))
|
||||
{::multiaccounts/switch-theme (if (= :dark theme) 2 1)})))
|
||||
(fx/merge cofx
|
||||
{::multiaccounts/switch-theme (if (= :dark theme) 2 1)
|
||||
:utils/dispatch-later
|
||||
(cond-> [{:ms 2000 :dispatch
|
||||
(if (= view-id :chat)
|
||||
[:chat.ui/navigate-to-chat (:current-chat-id db)]
|
||||
[:navigate-to view-id screen-params])}]
|
||||
|
||||
(some #(= view-id %) navigation.core/community-screens)
|
||||
(conj {:ms 1000 :dispatch
|
||||
[:navigate-to :community
|
||||
(get-in db [:navigation/screen-params :community])]})
|
||||
|
||||
(= view-id :community-emoji-thumbnail-picker)
|
||||
(conj {:ms 1500 :dispatch
|
||||
[:navigate-to :create-community-channel
|
||||
(get-in db [:navigation/screen-params :create-community-channel])]}))}
|
||||
(bottom-sheet/hide-bottom-sheet)
|
||||
(navigation/init-root root-id)
|
||||
(when (= root-id :chat-stack)
|
||||
(navigation/change-tab current-tab))))))
|
||||
|
||||
(def authentication-options
|
||||
{:reason (i18n/label :t/biometric-auth-reason-login)})
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :creating-backup?] backup-type))}
|
||||
(when-not (:multiaccounts/login db)
|
||||
(when (:multiaccount db)
|
||||
(navigation/change-tab :profile))
|
||||
(navigation/navigate-to-cofx :seed-phrase nil)))
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
:error nil
|
||||
:status nil))
|
||||
:hide-popover nil})
|
||||
(when-not (:multiaccounts/login db)
|
||||
(when (:multiaccount db)
|
||||
(navigation/change-tab :profile))
|
||||
(when-not (:multiaccounts/login db)
|
||||
(if (:popover/popover db)
|
||||
|
||||
@@ -217,9 +217,15 @@
|
||||
:t/keycard-access-reset :t/keycard-backup-success-title))
|
||||
:content (i18n/label (if (= backup-type :recovery-card)
|
||||
:t/keycard-can-use-with-new-passcode :t/keycard-backup-success-body))}}
|
||||
(if (multiaccounts.model/logged-in? cofx)
|
||||
(cond
|
||||
(multiaccounts.model/logged-in? cofx)
|
||||
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])
|
||||
(return-to-keycard-login))))
|
||||
|
||||
(:multiaccounts/login db)
|
||||
(return-to-keycard-login)
|
||||
|
||||
:else
|
||||
(navigation/set-stack-root :onboarding [:get-your-keys]))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::finish-migration
|
||||
|
||||
@@ -109,12 +109,15 @@
|
||||
types/json->clj
|
||||
:error
|
||||
string/blank?
|
||||
not)]
|
||||
not)
|
||||
onboarding? (not (or (:multiaccounts/login db) (:multiaccount db)))]
|
||||
(if error?
|
||||
(popover/show-popover cofx {:view :custom-seed-phrase})
|
||||
{::validate-seed-against-key-uid {:seed-phrase (-> db :multiaccounts/key-storage :seed-phrase)
|
||||
;; Unique key-uid of the account for which we are going to move keys
|
||||
:key-uid (or (-> db :multiaccounts/login :key-uid) (-> db :multiaccount :key-uid))}})))
|
||||
:key-uid (or (-> db :multiaccounts/login :key-uid)
|
||||
(-> db :multiaccount :key-uid)
|
||||
(and onboarding? (-> db :keycard :application-info :key-uid)))}})))
|
||||
|
||||
(fx/defn choose-storage-pressed
|
||||
{:events [::choose-storage-pressed]}
|
||||
|
||||
@@ -253,6 +253,11 @@
|
||||
(log/debug "[native-module] sign-message")
|
||||
(.signMessage ^js (status) rpcParams callback))
|
||||
|
||||
(defn recover-message
|
||||
[rpcParams callback]
|
||||
(log/debug "[native-module] recover")
|
||||
(.recover ^js (status) rpcParams callback))
|
||||
|
||||
(defn send-transaction
|
||||
"NOTE: beware, the password has to be sha3 hashed"
|
||||
[rpcParams hashed-password callback]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns status-im.navigation.core
|
||||
(:require
|
||||
["react-native" :as rn]
|
||||
[clojure.set :as clojure.set]
|
||||
["react-native-gesture-handler" :refer (gestureHandlerRootHOC)]
|
||||
["react-native-navigation" :refer (Navigation)]
|
||||
[quo.components.text-input :as quo.text-input]
|
||||
@@ -157,12 +158,14 @@
|
||||
(.registerComponentDidDisappearListener
|
||||
(.events Navigation)
|
||||
(fn [^js evn]
|
||||
(when-not (#{"popover" "bottom-sheet" "signing-sheet" "visibility-status-popover"}
|
||||
(.-componentName evn))
|
||||
(doseq [[_ {:keys [ref value]}] @quo.text-input/text-input-refs]
|
||||
(.setNativeProps ^js ref (clj->js {:text value})))
|
||||
(doseq [[^js text-input default-value] @react/text-input-refs]
|
||||
(.setNativeProps text-input (clj->js {:text default-value})))))))
|
||||
(let [view-id (keyword (.-componentName evn))]
|
||||
(when-not (#{"popover" "bottom-sheet" "signing-sheet" "visibility-status-popover"}
|
||||
(.-componentName evn))
|
||||
(re-frame/dispatch [::view-disappeared view-id])
|
||||
(doseq [[_ {:keys [ref value]}] @quo.text-input/text-input-refs]
|
||||
(.setNativeProps ^js ref (clj->js {:text value})))
|
||||
(doseq [[^js text-input default-value] @react/text-input-refs]
|
||||
(.setNativeProps text-input (clj->js {:text default-value}))))))))
|
||||
|
||||
;; SET ROOT
|
||||
(re-frame/reg-fx
|
||||
@@ -277,7 +280,10 @@
|
||||
(.registerBottomTabSelectedListener
|
||||
(.events Navigation)
|
||||
(fn [^js evn]
|
||||
(let [comp (get tab-root-ids (.-selectedTabIndex evn))]
|
||||
(let [selected-tab-index (.-selectedTabIndex evn)
|
||||
comp (get tab-root-ids selected-tab-index)
|
||||
tab-key (get (clojure.set/map-invert tab-key-idx) selected-tab-index)]
|
||||
(re-frame/dispatch [:set :current-tab tab-key])
|
||||
(when (and platform/android? (= @root-comp-id comp))
|
||||
(.popToRoot Navigation (name comp)))
|
||||
(reset! root-comp-id comp)))))
|
||||
@@ -377,3 +383,27 @@
|
||||
(log/debug :navigate-replace-fx view-id)
|
||||
(.pop Navigation (name @root-comp-id))
|
||||
(navigate view-id)))
|
||||
|
||||
(def community-screens '(:community-management
|
||||
:community-members
|
||||
:community-requests-to-join
|
||||
:create-community-channel
|
||||
:community-emoji-thumbnail-picker
|
||||
:create-community-category
|
||||
:community-edit-chats))
|
||||
|
||||
;; change view-id if it is still same after component is disappeared
|
||||
;; https://github.com/wix/react-native-navigation/issues/5744#issuecomment-563226820
|
||||
(fx/defn view-disappeared
|
||||
{:events [::view-disappeared]}
|
||||
[{:keys [db]} view-id]
|
||||
(when (= view-id (:view-id db))
|
||||
{:db (assoc db :view-id (cond
|
||||
(= view-id :community-emoji-thumbnail-picker)
|
||||
:create-community-channel
|
||||
|
||||
(some #(= view-id %) community-screens)
|
||||
:community
|
||||
|
||||
:else
|
||||
:home))}))
|
||||
|
||||
@@ -19,15 +19,16 @@
|
||||
{:unread-count (get db :activity.center/notifications-count 0)
|
||||
:notifications (get-in db [:activity.center/notifications :notifications])}
|
||||
activities)]
|
||||
{:db (-> db
|
||||
(assoc-in [:activity.center/notifications :notifications] notifications)
|
||||
(assoc :activity.center/notifications-count (max 0 unread-count)))
|
||||
:dispatch (cond
|
||||
(= (:view-id db) :notifications-center)
|
||||
[:mark-all-activity-center-notifications-as-read]
|
||||
(merge
|
||||
{:db (-> db
|
||||
(assoc-in [:activity.center/notifications :notifications] notifications)
|
||||
(assoc :activity.center/notifications-count (max 0 unread-count)))}
|
||||
(cond
|
||||
(= (:view-id db) :notifications-center)
|
||||
{:dispatch [:mark-all-activity-center-notifications-as-read]}
|
||||
|
||||
(= (:view-id db) :chat)
|
||||
[:accept-all-activity-center-notifications-from-chat (:current-chat-id db)])}))
|
||||
(= (:view-id db) :chat)
|
||||
{:dispatch [:accept-all-activity-center-notifications-from-chat (:current-chat-id db)]}))))
|
||||
|
||||
(fx/defn get-activity-center-notifications-count
|
||||
{:events [:get-activity-center-notifications-count]}
|
||||
|
||||
@@ -47,6 +47,12 @@
|
||||
(status/sign-message (types/clj->json params)
|
||||
on-completed)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:signing.fx/recover-message
|
||||
(fn [{:keys [params on-completed]}]
|
||||
(status/recover-message (types/clj->json params)
|
||||
on-completed)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:signing.fx/sign-typed-data
|
||||
(fn [{:keys [v4 data account on-completed hashed-password]}]
|
||||
@@ -230,7 +236,9 @@
|
||||
:signing/sign {:type (cond pinless? :pinless
|
||||
keycard-multiaccount? :keycard
|
||||
:else :password)
|
||||
:formatted-data (if typed? (types/json->clj data) (ethereum/hex->text data))
|
||||
:formatted-data (if typed?
|
||||
(types/js->pretty-json (types/json->js data))
|
||||
(ethereum/hex->text data))
|
||||
:keycard-step (when pinless? :connect)})
|
||||
:show-signing-sheet nil}
|
||||
#(when-not wallet-set-up-passed?
|
||||
@@ -264,14 +272,13 @@
|
||||
:success-event :signing/update-estimated-gas-success
|
||||
:error-event :signing/update-estimated-gas-error}})
|
||||
(fn [cofx]
|
||||
(when-not (or maxFeePerGas gasPrice)
|
||||
{:db (assoc-in (:db cofx) [:signing/edit-fee :gas-price-loading?] true)
|
||||
:signing/update-gas-price
|
||||
{:success-callback #(re-frame/dispatch
|
||||
[:wallet.send/update-gas-price-success :signing/tx %])
|
||||
:error-callback #(re-frame/dispatch [:signing/update-gas-price-error %])
|
||||
:network-id (get-in (ethereum/current-network db)
|
||||
[:config :NetworkId])}}))))))
|
||||
{:db (assoc-in (:db cofx) [:signing/edit-fee :gas-price-loading?] true)
|
||||
:signing/update-gas-price
|
||||
{:success-callback #(re-frame/dispatch
|
||||
[:wallet.send/update-gas-price-success :signing/tx % tx-obj])
|
||||
:error-callback #(re-frame/dispatch [:signing/update-gas-price-error %])
|
||||
:network-id (get-in (ethereum/current-network db)
|
||||
[:config :NetworkId])}})))))
|
||||
|
||||
(fx/defn check-queue [{:keys [db] :as cofx}]
|
||||
(let [{:signing/keys [tx queue]} db]
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
[status-im.utils.security :as security]
|
||||
[status-im.wallet.db :as wallet.db]
|
||||
[status-im.wallet.utils :as wallet.utils]
|
||||
[status-im.utils.utils :as utils]
|
||||
status-im.ui.screens.keycard.subs
|
||||
[status-im.chat.models.mentions :as mentions]
|
||||
[status-im.notifications.core :as notifications]
|
||||
@@ -181,6 +180,12 @@
|
||||
(reg-root-key-sub :wallet/fetching-collection-assets :wallet/fetching-collection-assets)
|
||||
(reg-root-key-sub :wallet/collectible-assets :wallet/collectible-assets)
|
||||
(reg-root-key-sub :wallet/selected-collectible :wallet/selected-collectible)
|
||||
(reg-root-key-sub :wallet/modal-selecting-source-token? :wallet/modal-selecting-source-token?)
|
||||
(reg-root-key-sub :wallet/swap-from-token :wallet/swap-from-token)
|
||||
(reg-root-key-sub :wallet/swap-to-token :wallet/swap-to-token)
|
||||
(reg-root-key-sub :wallet/swap-from-token-amount :wallet/swap-from-token-amount)
|
||||
(reg-root-key-sub :wallet/swap-to-token-amount :wallet/swap-to-token-amount)
|
||||
(reg-root-key-sub :wallet/swap-advanced-mode? :wallet/swap-advanced-mode?)
|
||||
|
||||
;;commands
|
||||
(reg-root-key-sub :commands/select-account :commands/select-account)
|
||||
@@ -877,6 +882,22 @@
|
||||
(assoc :color colors/blue))
|
||||
chats)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/sorted-categories-by-community-id
|
||||
(fn [[_ community-id]]
|
||||
[(re-frame/subscribe [:chats/by-community-id community-id])
|
||||
(re-frame/subscribe [:communities/community-chats community-id])])
|
||||
(fn [[chats comm-chats] [_ community-id]]
|
||||
(let [chat-cat (into {} (map (fn [{:keys [id categoryID position]}]
|
||||
{(str community-id id) {:categoryID categoryID
|
||||
:position position}})
|
||||
(vals comm-chats)))]
|
||||
(group-by :categoryID (sort-by :position
|
||||
(map #(cond-> (merge % (chat-cat (:chat-id %)))
|
||||
(= community-id constants/status-community-id)
|
||||
(assoc :color colors/blue))
|
||||
chats))))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/category-by-chat-id
|
||||
(fn [[_ community-id _]]
|
||||
@@ -903,7 +924,9 @@
|
||||
:<- [:communities]
|
||||
(fn [communities [_ id]]
|
||||
(->> (get-in communities [id :categories])
|
||||
(sort-by #(:position (get % 1))))))
|
||||
(map #(assoc (get % 1) :community-id id))
|
||||
(sort-by :position)
|
||||
(into []))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-chat-ui-props
|
||||
@@ -1395,56 +1418,18 @@
|
||||
(wallet.db/get-confirmations current-block)
|
||||
(>= transactions/confirmations-count-threshold))})))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/mentionable-contacts
|
||||
:<- [:contacts/contacts]
|
||||
(fn [contacts]
|
||||
(reduce
|
||||
(fn [acc [key {:keys [alias name added? blocked? identicon public-key nickname]}]]
|
||||
(if (and alias
|
||||
(not= alias "")
|
||||
(or name
|
||||
nickname
|
||||
added?)
|
||||
(not blocked?))
|
||||
(let [name (utils/safe-replace name ".stateofus.eth" "")]
|
||||
(assoc acc public-key
|
||||
(mentions/add-searchable-phrases
|
||||
{:alias alias
|
||||
:name (or name alias)
|
||||
:identicon identicon
|
||||
:nickname nickname
|
||||
:public-key key})))
|
||||
acc))
|
||||
{}
|
||||
contacts)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/mentionable-users
|
||||
:<- [:chats/current-chat]
|
||||
:<- [:chats/mentionable-contacts]
|
||||
:<- [:contacts/blocked-set]
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:multiaccount]
|
||||
(fn [[{:keys [chat-id users contacts community-id chat-type] :as chat} mentionable-contacts blocked {:keys [name preferred-name public-key]}]]
|
||||
(let [community-members @(re-frame/subscribe [:communities/community-members
|
||||
community-id])
|
||||
contacts-with-one-to-one (if (= chat-type constants/one-to-one-chat-type)
|
||||
(assoc mentionable-contacts chat-id (get mentionable-contacts chat-id (-> chat-id
|
||||
contact.db/public-key->new-contact
|
||||
contact.db/enrich-contact)))
|
||||
mentionable-contacts)
|
||||
members-left (into #{} (filter #(group-chat/member-removed? chat %) (keys users)))
|
||||
filtered-contacts (select-keys contacts-with-one-to-one (if (nil? community-id)
|
||||
(distinct (concat (seq contacts) (keys users) [chat-id]))
|
||||
(keys community-members)))]
|
||||
(apply dissoc
|
||||
(-> users
|
||||
(merge filtered-contacts)
|
||||
(assoc public-key (mentions/add-searchable-phrases
|
||||
{:alias name
|
||||
:name (or preferred-name name)
|
||||
:public-key public-key})))
|
||||
(conj (concat blocked members-left) public-key)))))
|
||||
(fn [[{:keys [users community-id] :as chat} blocked all-contacts
|
||||
{:keys [public-key] :as current-multiaccount}]]
|
||||
(let [community-members @(re-frame/subscribe [:communities/community-members community-id])
|
||||
mentionable-users (mentions/get-mentionable-users chat all-contacts current-multiaccount community-members)
|
||||
members-left (into #{} (filter #(group-chat/member-removed? chat %) (keys users)))]
|
||||
(apply dissoc mentionable-users (conj (concat blocked members-left) public-key)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chat/mention-suggestions
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
(defn emoji-thumbnail [emoji color size]
|
||||
(when-not (string/blank? emoji)
|
||||
[react/view (styles/emoji-thumbnail-icon color size)
|
||||
[react/text {:style (styles/emoji-thumbnail-icon-text size)} emoji]]))
|
||||
[react/text {:style (styles/emoji-thumbnail-icon-text size)
|
||||
:accessibility-label :thumbnail-emoji} emoji]]))
|
||||
|
||||
(defn emoji-thumbnail-touchable [emoji color size func]
|
||||
(when-not (string/blank? emoji)
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
(defn emoji-thumbnail-icon-text [size]
|
||||
{:font-size (emoji-utils/emoji-font-size size)
|
||||
:line-height size
|
||||
:accessibility-label :thumbnail-emoji
|
||||
:margin-top (emoji-utils/emoji-top-margin-for-vertical-alignment size)}) ;; Required for vertical alignment bug - Check function defination for more info
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
{:padding-top subtitle-margin})))
|
||||
|
||||
(defn extended-header
|
||||
[{:keys [title photo color subtitle subtitle-icon on-edit on-press monospace
|
||||
[{:keys [title photo color membership subtitle subtitle-icon on-edit on-press monospace
|
||||
bottom-separator emoji public-key community?]
|
||||
:or {bottom-separator true}}]
|
||||
(fn [{:keys [animation minimized]}]
|
||||
@@ -70,6 +70,12 @@
|
||||
:accessibility-role :text
|
||||
:accessibility-label :default-username}
|
||||
title]
|
||||
(when membership [quo/text {:number-of-lines 1
|
||||
:ellipsize-mode :middle
|
||||
:monospace monospace
|
||||
:size (if minimized :small :base)
|
||||
:color :secondary}
|
||||
membership])
|
||||
(when subtitle
|
||||
[animated/view {:style (header-subtitle {:minimized minimized})
|
||||
:pointer-events :box-none}
|
||||
|
||||
@@ -86,22 +86,4 @@
|
||||
:style {:width 160 :height 160}}]]
|
||||
[react/text {:style {:text-align :center :margin-bottom 16 :line-height 22}}
|
||||
(i18n/label :t/public-chat-description)]
|
||||
[chat-name-input topic error]]
|
||||
[react/view {:margin-top 32}
|
||||
(for [[section chats] (chat.models/chats)]
|
||||
^{:key section}
|
||||
[react/view
|
||||
[react/view {:margin-right 16 :padding-left 16 :padding-vertical 3
|
||||
:border-bottom-width 1 :border-bottom-color colors/gray-lighter
|
||||
:border-top-width 1 :border-top-color colors/gray-lighter
|
||||
:border-right-width 1 :border-right-color colors/gray-lighter
|
||||
:border-bottom-right-radius 14 :border-top-right-radius 14}
|
||||
[quo/text {:weight :medium} section]]
|
||||
[react/view {:flex-direction :row :flex-wrap :wrap :margin-vertical 8 :padding-horizontal 16}
|
||||
(let [lang-topic (get-language-topic)
|
||||
chats (if (and (= section-featured section) lang-topic)
|
||||
(conj chats lang-topic)
|
||||
chats)]
|
||||
(for [chat chats]
|
||||
^{:key chat}
|
||||
[render-topic chat]))]])]]))
|
||||
[chat-name-input topic error]]]))
|
||||
|
||||
@@ -12,28 +12,29 @@
|
||||
(re-frame/dispatch [:chat.ui/fill-gaps chat-id gap-ids])))
|
||||
|
||||
(views/defview gap
|
||||
[{:keys [gap-ids chat-id gap-parameters]}]
|
||||
[{:keys [gap-ids chat-id gap-parameters public? community?]}]
|
||||
(views/letsubs [in-progress? [:chats/fetching-gap-in-progress?
|
||||
gap-ids
|
||||
chat-id]
|
||||
connected? [:mailserver/connected?]
|
||||
first-gap? (= gap-ids #{:first-gap})]
|
||||
[react/view {:style (style/gap-container)}
|
||||
[react/touchable-highlight
|
||||
{:on-press (when (and connected? (not in-progress?))
|
||||
(on-press chat-id gap-ids))
|
||||
:style style/touchable}
|
||||
[react/view {:style style/label-container}
|
||||
(if in-progress?
|
||||
[react/activity-indicator]
|
||||
[react/nested-text
|
||||
{:style (style/gap-text connected?)}
|
||||
(i18n/label (if first-gap? :t/load-more-messages :t/fetch-messages))
|
||||
(when first-gap?
|
||||
[{:style style/date}
|
||||
(let [date (datetime/timestamp->long-date
|
||||
(* 1000 (:from gap-parameters)))]
|
||||
(str
|
||||
"\n"
|
||||
(i18n/label :t/load-messages-before
|
||||
{:date date})))])])]]]))
|
||||
(when (or (not first-gap?) public? community?)
|
||||
[react/view {:style (style/gap-container)}
|
||||
[react/touchable-highlight
|
||||
{:on-press (when (and connected? (not in-progress?))
|
||||
(on-press chat-id gap-ids))
|
||||
:style style/touchable}
|
||||
[react/view {:style style/label-container}
|
||||
(if in-progress?
|
||||
[react/activity-indicator]
|
||||
[react/nested-text
|
||||
{:style (style/gap-text connected?)}
|
||||
(i18n/label (if first-gap? :t/load-more-messages :t/fetch-messages))
|
||||
(when first-gap?
|
||||
[{:style style/date}
|
||||
(let [date (datetime/timestamp->long-date
|
||||
(* 1000 (:from gap-parameters)))]
|
||||
(str
|
||||
"\n"
|
||||
(i18n/label :t/load-messages-before
|
||||
{:date date})))])])]]])))
|
||||
|
||||
@@ -80,7 +80,9 @@
|
||||
(let [anim-opacity (animation/create-value 0)]
|
||||
[react/animated-view {:style (style/message-timestamp-wrapper message) :opacity anim-opacity}
|
||||
(when @show-timestamp? (message-timestamp-anim anim-opacity show-timestamp?))
|
||||
[react/text {:style (style/message-timestamp-text)}
|
||||
[react/text
|
||||
{:style (style/message-timestamp-text)
|
||||
:accessibility-label :message-timestamp}
|
||||
timestamp-str]])))
|
||||
|
||||
(defview quoted-message
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
[status-im.ui.screens.chat.styles.photos :as style]
|
||||
[status-im.profile.db :as profile.db]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.utils.image :as utils.image]))
|
||||
[status-im.utils.image :as utils.image]
|
||||
[quo.design-system.colors :as colors]))
|
||||
|
||||
(def memo-photo-rend
|
||||
(memoize
|
||||
(fn [photo-path size accessibility-label]
|
||||
(fn [photo-path size accessibility-label _]
|
||||
(let [identicon? (when photo-path (profile.db/base64-png? photo-path))]
|
||||
[react/view {:style (style/photo-container size)}
|
||||
[react/image {:source (utils.image/source photo-path)
|
||||
@@ -18,8 +19,9 @@
|
||||
(when identicon?
|
||||
[react/view {:style (style/photo-border size)}])]))))
|
||||
|
||||
;; "(colors/dark?)" is passed to memoized function to avoid previous themes cache
|
||||
(defn photo [photo-path {:keys [size accessibility-label]}]
|
||||
[memo-photo-rend photo-path size accessibility-label])
|
||||
[memo-photo-rend photo-path size accessibility-label (colors/dark?)])
|
||||
|
||||
;; We optionally pass identicon for perfomance reason, so it does not have to be calculated for each message
|
||||
(defn member-photo [pub-key identicon]
|
||||
|
||||
@@ -243,7 +243,8 @@
|
||||
(defn render-fn [{:keys [outgoing type] :as message}
|
||||
idx
|
||||
_
|
||||
{:keys [group-chat public? current-public-key space-keeper chat-id show-input? message-pin-enabled edit-enabled in-pinned-view?]}]
|
||||
{:keys [group-chat public? community? current-public-key space-keeper
|
||||
chat-id show-input? message-pin-enabled edit-enabled in-pinned-view?]}]
|
||||
[react/view {:style (when (and platform/android? (not in-pinned-view?)) {:scaleY -1})}
|
||||
(if (= type :datemark)
|
||||
[message-datemark/chat-datemark (:value message)]
|
||||
@@ -255,6 +256,7 @@
|
||||
:incoming-group (and group-chat (not outgoing))
|
||||
:group-chat group-chat
|
||||
:public? public?
|
||||
:community? community?
|
||||
:current-public-key current-public-key
|
||||
:show-input? show-input?
|
||||
:message-pin-enabled message-pin-enabled
|
||||
@@ -285,6 +287,7 @@
|
||||
community-admin?))))]
|
||||
{:group-chat group-chat
|
||||
:public? public?
|
||||
:community? (not (nil? community-id))
|
||||
:current-public-key current-public-key
|
||||
:space-keeper space-keeper
|
||||
:chat-id chat-id
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
(fn []
|
||||
(let [current-chat (<sub [:chat-by-id chat-id])
|
||||
{:keys [chat-name color description community-id emoji]} current-chat
|
||||
{:keys [position]} (<sub [:chats/community-chat-by-id community-id chat-id])
|
||||
category (<sub [:chats/category-by-chat-id community-id chat-id])
|
||||
{:keys [admin]} (<sub [:communities/community community-id])
|
||||
pinned-messages (<sub [:chats/pinned chat-id])]
|
||||
@@ -27,7 +28,8 @@
|
||||
color
|
||||
emoji
|
||||
chat-id
|
||||
(:id category)])}])
|
||||
(:id category)
|
||||
position])}])
|
||||
:extended-header (profile-header/extended-header
|
||||
{:title chat-name
|
||||
:color color
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ui.screens.chat.sheets :as sheets]
|
||||
[status-im.ui.components.accordion :as accordion]
|
||||
[clojure.string :as string]
|
||||
[status-im.ui.screens.communities.styles :as styles]))
|
||||
|
||||
(def request-cooldown-ms (* 60 1000))
|
||||
@@ -139,12 +138,6 @@
|
||||
:title (i18n/label :t/edit-chats)
|
||||
:accessibility-label :community-edit-chats
|
||||
:icon :main-icons/edit
|
||||
:on-press #(hide-sheet-and-dispatch [:open-modal :community-edit-chats {:community-id id}])}]
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/reorder-categories)
|
||||
:accessibility-label :community-reorder-categories
|
||||
:icon :main-icons/channel-category
|
||||
:on-press #(hide-sheet-and-dispatch
|
||||
[:open-modal :community-reorder-categories {:community-id id}])}]])]))
|
||||
|
||||
@@ -168,46 +161,28 @@
|
||||
{:content (fn []
|
||||
[sheets/actions home-item])}])}])
|
||||
|
||||
(defn categories-accordion [community-id chats categories edit data]
|
||||
(defn categories-accordion [community-id chats categories data]
|
||||
[:<>
|
||||
(for [{:keys [name id state]} (vals categories)]
|
||||
(for [{:keys [name id state]} categories]
|
||||
^{:key (str "cat" name id)}
|
||||
[:<>
|
||||
[accordion/section
|
||||
{:on-open #(>evt [::communities/store-category-state community-id id true])
|
||||
:on-close #(>evt [::communities/store-category-state community-id id false])
|
||||
:default state
|
||||
:opened edit
|
||||
:disabled edit
|
||||
:title [rn/view styles/category-item
|
||||
(if edit
|
||||
[rn/touchable-opacity {:on-press #(>evt [:delete-community-category community-id id])}
|
||||
[icons/icon :main-icons/delete-circle {:no-color true}]]
|
||||
[icons/icon :main-icons/channel-category {:color colors/gray}])
|
||||
[icons/icon :main-icons/channel-category {:color colors/gray}]
|
||||
[rn/text {:style {:font-size 17 :margin-left 10 :color colors/black}} name]]
|
||||
:content [rn/view
|
||||
:content [:<>
|
||||
(for [chat (get chats id)]
|
||||
(if edit
|
||||
^{:key (str "chat" chat id)}
|
||||
[rn/view styles/category-item
|
||||
[rn/touchable-opacity {:on-press #(>evt [:remove-chat-from-community-category
|
||||
community-id
|
||||
(string/replace (:chat-id chat) community-id "")
|
||||
(:categoryID chat)])}
|
||||
[icons/icon :main-icons/delete-circle {:no-color true}]]
|
||||
[rn/view {:flex 1}
|
||||
[inner-item/home-list-item
|
||||
(assoc chat :public? true)]]]
|
||||
^{:key (str "chat" chat id)}
|
||||
[community-chat-item chat nil nil data]))]}]
|
||||
^{:key (str "chat" chat id)}
|
||||
[community-chat-item chat nil nil data])]}]
|
||||
[quo/separator]])])
|
||||
|
||||
(defn community-chat-list [community-id categories edit from-chat]
|
||||
(let [chats (<sub [:chats/categories-by-community-id community-id])]
|
||||
(defn community-chat-list [community-id categories from-chat]
|
||||
(let [chats (<sub [:chats/sorted-categories-by-community-id community-id])]
|
||||
(if (and (empty? categories) (empty? chats))
|
||||
(if edit
|
||||
[blank-page (i18n/label :t/welcome-community-blank-message-edit-chats)]
|
||||
[blank-page (i18n/label :t/welcome-community-blank-message)])
|
||||
[blank-page (i18n/label :t/welcome-community-blank-message)]
|
||||
[list/flat-list
|
||||
{:key-fn :chat-id
|
||||
:content-container-style {:padding-bottom 8}
|
||||
@@ -215,7 +190,7 @@
|
||||
:data (get chats "")
|
||||
:render-data {:from-chat from-chat}
|
||||
:render-fn community-chat-item
|
||||
:header [categories-accordion community-id chats categories edit {:from-chat from-chat}]
|
||||
:header [categories-accordion community-id chats categories {:from-chat from-chat}]
|
||||
:footer [rn/view {:height 68}]}])))
|
||||
|
||||
(defn channel-preview-item [{:keys [id name]}]
|
||||
@@ -267,23 +242,6 @@
|
||||
[components.react/small-loading-indicator]
|
||||
(i18n/label :t/fetch-community))]]]))
|
||||
|
||||
(defn community-edit []
|
||||
(let [{:keys [community-id]} (<sub [:get-screen-params])]
|
||||
(fn []
|
||||
(let [{:keys [id name images members permissions color]} (<sub [:communities/community community-id])
|
||||
categories (<sub [:communities/sorted-categories community-id])]
|
||||
[:<>
|
||||
[topbar/topbar
|
||||
{:modal? true
|
||||
:content [toolbar-content
|
||||
id
|
||||
name
|
||||
color
|
||||
images
|
||||
(not= (:access permissions) constants/community-no-membership-access)
|
||||
(count members)]}]
|
||||
[community-chat-list id categories true false]]))))
|
||||
|
||||
(defn community []
|
||||
(let [{:keys [community-id from-chat]} (<sub [:get-screen-params])]
|
||||
(fn []
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
[status-im.utils.image :as utils.image]
|
||||
[quo.design-system.colors :as colors]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.screens.communities.membership :as memberships]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.utils.debounce :as debounce]))
|
||||
|
||||
@@ -128,7 +129,7 @@
|
||||
(str (count text) "/" max-length)]])
|
||||
|
||||
(defn form []
|
||||
(let [{:keys [name description]} (<sub [:communities/create])]
|
||||
(let [{:keys [name description membership editing?]} (<sub [:communities/create])]
|
||||
[rn/scroll-view {:keyboard-should-persist-taps :handled
|
||||
:style {:flex 1}
|
||||
:content-container-style {:padding-vertical 16}}
|
||||
@@ -156,7 +157,17 @@
|
||||
:on-change-text #(>evt [::communities/create-field :description %])}]]
|
||||
[quo/list-header {:color :main}
|
||||
(i18n/label :t/community-thumbnail-image)]
|
||||
[photo-picker]]))
|
||||
[photo-picker]
|
||||
(when-not editing? [:<>
|
||||
[quo/separator {:style {:margin-vertical 10}}]
|
||||
[quo/list-item {:title (i18n/label :t/membership-button)
|
||||
:accessory-text (i18n/label (get-in memberships/options [membership :title] :t/membership-none))
|
||||
:accessory :text
|
||||
:on-press #(>evt [:navigate-to :community-membership])
|
||||
:chevron true
|
||||
:size :small}]
|
||||
[quo/list-footer
|
||||
(i18n/label (get-in memberships/options [membership :description] :t/membership-none-placeholder))]])]))
|
||||
|
||||
(defn view []
|
||||
(let [{:keys [name description]} (<sub [:communities/create])]
|
||||
|
||||
@@ -65,4 +65,4 @@
|
||||
@category-name
|
||||
(vec @selected-items)]
|
||||
3000)}
|
||||
(i18n/label :t/create)]}]]))))
|
||||
(i18n/label :t/create)]}]]))))
|
||||
|
||||
@@ -10,13 +10,6 @@
|
||||
(def options {constants/community-on-request-access
|
||||
{:title :t/membership-approval
|
||||
:description :t/membership-approval-description}
|
||||
constants/community-invitation-only-access
|
||||
{:title :t/membership-invite
|
||||
:description :t/membership-invite-description}
|
||||
; disabled for now
|
||||
; constants/community-rule-ens-only
|
||||
; {:title :t/membership-ens
|
||||
; :description :t/membership-ens-description}
|
||||
constants/community-no-membership-access
|
||||
{:title :t/membership-free
|
||||
:description :t/membership-free-description}})
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
roles false
|
||||
notifications false
|
||||
show-members-count? (not= (:access permissions) constants/community-no-membership-access)
|
||||
request-membership? (= (:access permissions) constants/community-on-request-access)
|
||||
members-count (count members)]
|
||||
[:<>
|
||||
[quo/animated-header {:left-accessories [{:icon :main-icons/arrow-left
|
||||
@@ -39,6 +40,8 @@
|
||||
(rn/resolve-asset-source
|
||||
(resources/get-image :status-logo)))
|
||||
(get-in community [:images :large :uri]))
|
||||
:membership (when request-membership?
|
||||
(i18n/label :t/membership-approval))
|
||||
:subtitle (if show-members-count?
|
||||
(i18n/label-pluralize members-count :t/community-members {:count members-count})
|
||||
(i18n/label :t/open-membership))
|
||||
|
||||
@@ -1,60 +1,176 @@
|
||||
(ns status-im.ui.screens.communities.reorder-categories
|
||||
(:require [quo.core :as quo]
|
||||
[clojure.walk :as walk]
|
||||
[quo.react-native :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[clojure.string :as string]
|
||||
[clojure.set :as clojure.set]
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im.constants :as constants]
|
||||
[quo.design-system.colors :as colors]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.communities.core :as communities]
|
||||
[status-im.utils.handlers :refer [>evt <sub]]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.ui.screens.communities.styles :as styles]
|
||||
[status-im.ui.screens.communities.community :as community]))
|
||||
[status-im.ui.screens.communities.community :as community]
|
||||
[status-im.ui.screens.home.views.inner-item :as inner-item]))
|
||||
|
||||
(defn category-change-positon [community-id key up? position]
|
||||
(let [new-position (if up? (dec position) (inc position))]
|
||||
(>evt [::communities/reorder-community-category community-id key new-position])))
|
||||
(def collapse-chats? (reagent/atom false))
|
||||
(def data (reagent/atom []))
|
||||
|
||||
(defn category-item-button [community-id up? disabled? key position]
|
||||
(let [[margin-right icon] (if up?
|
||||
[10 :main-icons/dropdown-up]
|
||||
[25 :main-icons/dropdown])]
|
||||
[react/touchable-opacity {:disabled disabled?
|
||||
:on-press #(category-change-positon
|
||||
community-id key up? position)}
|
||||
[rn/view {:style (styles/reorder-categories-button margin-right)}
|
||||
[icons/icon icon {:color colors/black}]]]))
|
||||
(defn show-delete-chat-confirmation [community-id chat-id]
|
||||
(utils/show-confirmation
|
||||
{:title (i18n/label :t/delete-confirmation)
|
||||
:content (i18n/label :t/delete-chat-confirmation)
|
||||
:confirm-button-text (i18n/label :t/delete)
|
||||
:on-accept #(>evt [:delete-community-chat community-id chat-id])}))
|
||||
|
||||
(defn category-item [community-id count {:keys [key name position]}]
|
||||
(let [up-disabled? (= position 0)
|
||||
down-disabled? (= position (dec count))]
|
||||
(defn show-delete-catgory-confirmation [community-id category-id]
|
||||
(utils/show-confirmation
|
||||
{:title (i18n/label :t/delete-confirmation)
|
||||
:content (i18n/label :t/delete-category-confirmation)
|
||||
:confirm-button-text (i18n/label :t/delete)
|
||||
:on-accept #(>evt [:delete-community-category community-id category-id])}))
|
||||
|
||||
(defn chat-item
|
||||
[{:keys [id community-id] :as home-item} is-active? drag]
|
||||
(let [chat-id (string/replace id community-id "")
|
||||
background-color (if is-active? colors/gray-lighter colors/white)
|
||||
home-item (clojure.set/rename-keys home-item {:id :chat-id})]
|
||||
[rn/view {:accessibility-label :chat-item
|
||||
:style (merge styles/category-item
|
||||
{:background-color background-color})}
|
||||
[rn/touchable-opacity
|
||||
{:accessibility-label :delete-community-chat
|
||||
:on-press #(show-delete-chat-confirmation community-id chat-id)}
|
||||
[icons/icon :main-icons/delete-circle {:no-color true}]]
|
||||
[rn/view {:flex 1}
|
||||
[inner-item/home-list-item (assoc home-item :edit? true) {:active-opacity 1}]]
|
||||
[rn/touchable-opacity {:on-long-press drag
|
||||
:delay-long-press 100
|
||||
:accessibility-label :chat-drag-handle
|
||||
:style {:padding 20}}
|
||||
[icons/icon :main-icons/reorder-handle {:no-color true :width 18 :height 12}]]]))
|
||||
|
||||
(defn category-item
|
||||
[{:keys [id name community-id]} is-active? drag]
|
||||
(let [background-color (if is-active? colors/gray-lighter colors/white)
|
||||
category-none? (string/blank? id)]
|
||||
[:<>
|
||||
[rn/view {:style styles/reorder-categories-item}
|
||||
[icons/icon :main-icons/channel-category {:color colors/gray}]
|
||||
[rn/text {:style (styles/reorder-categories-text)} name]
|
||||
[category-item-button community-id true up-disabled? key position]
|
||||
[category-item-button community-id false down-disabled? key position]]
|
||||
[quo/separator]]))
|
||||
[quo/separator]
|
||||
[rn/view {:accessibility-label :category-item
|
||||
:style (merge styles/category-item
|
||||
{:background-color background-color})}
|
||||
(if category-none?
|
||||
[icons/icon :main-icons/channel-category {:color colors/gray}]
|
||||
[rn/touchable-opacity
|
||||
{:accessibility-label :delete-category-button
|
||||
:on-press #(show-delete-catgory-confirmation community-id id)}
|
||||
[icons/icon :main-icons/delete-circle {:no-color true}]])
|
||||
[rn/view {:flex 1}
|
||||
[rn/text {:style {:font-size 17 :margin-left 10 :color colors/black}} name]]
|
||||
(when (and (not category-none?) @collapse-chats?)
|
||||
[rn/touchable-opacity {:accessibility-label :category-drag-handle
|
||||
:on-long-press drag
|
||||
:delay-long-press 100
|
||||
:style {:padding 20}}
|
||||
[icons/icon :main-icons/reorder-handle {:no-color true :width 18 :height 12}]])]]))
|
||||
|
||||
(defn categories-view [community-id categories count]
|
||||
[rn/view {:accessibility-label :reorder-categories-list}
|
||||
(for [category-vector categories]
|
||||
(let [category (clojure.set/rename-keys (get category-vector 1) {:id :key})]
|
||||
[category-item community-id count category]))])
|
||||
(defn render-fn
|
||||
[{:keys [chat-type] :as item} _ _ _ is-active? drag]
|
||||
(if (= chat-type constants/community-chat-type)
|
||||
[chat-item item is-active? drag]
|
||||
[category-item item is-active? drag]))
|
||||
|
||||
(defn calculate-chat-new-position-and-category
|
||||
[to second-call? old-category going-up?]
|
||||
(let [{:keys [id chat-type categoryID position]} (get @data to)
|
||||
[new-category new-position]
|
||||
(if going-up?
|
||||
(if (= chat-type constants/community-chat-type)
|
||||
[categoryID (if second-call? (inc position) position)]
|
||||
(if second-call? [id 0]
|
||||
(calculate-chat-new-position-and-category (dec to) true old-category true)))
|
||||
(if (= chat-type constants/community-chat-type)
|
||||
(if (= categoryID old-category)
|
||||
[categoryID position]
|
||||
[categoryID (inc position)]) [id 0]))]
|
||||
[new-category new-position]))
|
||||
|
||||
(defn update-local-atom [data-js]
|
||||
(reset! data data-js)
|
||||
(reagent/flush))
|
||||
|
||||
(defn on-drag-end-chat [from to data-js]
|
||||
(let [{:keys [id community-id categoryID position]} (get @data from)
|
||||
[new-category new-position] (calculate-chat-new-position-and-category
|
||||
to false categoryID (> from to))
|
||||
chat-id (string/replace id community-id "")]
|
||||
(when-not (and (= new-position position) (= new-category categoryID))
|
||||
(update-local-atom data-js)
|
||||
(>evt [::communities/reorder-community-category-chat
|
||||
community-id new-category chat-id new-position]))))
|
||||
|
||||
(defn on-drag-end-category [from to data-js]
|
||||
(let [{:keys [id community-id position]} (get @data from)]
|
||||
(when (and (< to (count @data)) (not= position to) (not= id ""))
|
||||
(update-local-atom data-js)
|
||||
(>evt [::communities/reorder-community-category community-id id to]))))
|
||||
|
||||
(defn on-drag-end-fn [from to data-js]
|
||||
(if @collapse-chats?
|
||||
(on-drag-end-category from to data-js)
|
||||
(when-not (= to 0) (on-drag-end-chat from to data-js))))
|
||||
|
||||
(defn reset-data [categories chats]
|
||||
(reset! data (if @collapse-chats? categories ;; If chats are collapsed then only show categories
|
||||
(walk/postwalk-replace ;; else, categories and chats
|
||||
{:chat-id :id}
|
||||
(reduce (fn [acc category]
|
||||
(-> acc
|
||||
(conj category)
|
||||
(into (get chats (:id category))))) [] categories)))))
|
||||
|
||||
(defn draggable-list []
|
||||
[rn/draggable-flat-list
|
||||
{:key-fn :id
|
||||
:data @data
|
||||
:render-fn render-fn
|
||||
:autoscroll-threshold (if platform/android? 150 250)
|
||||
:autoscroll-speed (if platform/android? 10 150) ;; TODO - Use same speed for both ios and android
|
||||
:container-style {:margin-bottom 108} ;; after bumping react native version to > 0.64
|
||||
:on-drag-end-fn on-drag-end-fn}])
|
||||
|
||||
(defn view []
|
||||
(let [{:keys [community-id]} (<sub [:get-screen-params])
|
||||
{:keys [id name images members permissions color]}
|
||||
(<sub [:communities/community community-id])
|
||||
categories (<sub [:communities/sorted-categories community-id])]
|
||||
sorted-categories (<sub [:communities/sorted-categories community-id])
|
||||
categories (if @collapse-chats? sorted-categories
|
||||
(conj sorted-categories
|
||||
{:id ""
|
||||
:position (count sorted-categories)
|
||||
:name (i18n/label :t/none)
|
||||
:community-id community-id}))
|
||||
chats (<sub [:chats/sorted-categories-by-community-id community-id])]
|
||||
(reset-data categories chats)
|
||||
[:<>
|
||||
[topbar/topbar
|
||||
{:modal? true
|
||||
:content [community/toolbar-content id name color images
|
||||
(not= (:access permissions) constants/community-no-membership-access)
|
||||
(count members)]}]
|
||||
(if (empty? categories)
|
||||
[community/blank-page (i18n/label :t/welcome-community-blank-message-categories)]
|
||||
[categories-view community-id categories (count categories)])]))
|
||||
(if (and (empty? sorted-categories) (empty? chats))
|
||||
[community/blank-page (i18n/label :t/welcome-community-blank-message-edit-chats)]
|
||||
[:<>
|
||||
[quo/list-item {:size :small
|
||||
:title (i18n/label :t/rearrange-categories)
|
||||
:active @collapse-chats?
|
||||
:accessory :switch
|
||||
:container-style {:padding-left 10}
|
||||
:on-press #(reset! collapse-chats? (not @collapse-chats?))}]
|
||||
[quo/separator]
|
||||
[draggable-list]])]))
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
[status-im.communities.core :as communities]))
|
||||
[status-im.communities.core :as communities]
|
||||
[quo.components.animated.pressable :as animation]))
|
||||
|
||||
(defn hide-sheet-and-dispatch [event]
|
||||
(>evt [:bottom-sheet/hide])
|
||||
@@ -19,11 +20,11 @@
|
||||
|
||||
(defn request-actions [community-id request-id]
|
||||
[react/view {:flex-direction :row}
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:communities.ui/accept-request-to-join-pressed community-id request-id])}
|
||||
[animation/pressable {:on-press #(re-frame/dispatch [:communities.ui/accept-request-to-join-pressed community-id request-id])}
|
||||
[icons/icon :main-icons/checkmark-circle {:width 35
|
||||
:height 35
|
||||
:color colors/green}]]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:communities.ui/decline-request-to-join-pressed community-id request-id])}
|
||||
[animation/pressable {:on-press #(re-frame/dispatch [:communities.ui/decline-request-to-join-pressed community-id request-id])}
|
||||
[icons/icon :main-icons/cancel {:width 35
|
||||
:height 35
|
||||
:container-style {:margin-left 16}
|
||||
@@ -41,7 +42,8 @@
|
||||
:accessory (when can-manage-users?
|
||||
[request-actions community-id id])
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo member)]}]))
|
||||
(multiaccounts/displayed-photo member)]
|
||||
:on-press #(re-frame/dispatch [:chat.ui/show-profile public-key])}]))
|
||||
|
||||
(defn requests-to-join []
|
||||
(let [{:keys [community-id]} (<sub [:get-screen-params])]
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
(let [{:keys [community-id chat]} (<sub [:get-screen-params])]
|
||||
(fn []
|
||||
(let [categories (<sub [:communities/sorted-categories community-id])
|
||||
chats (<sub [:chats/sorted-categories-by-community-id community-id])
|
||||
comm-chat (<sub [:chats/community-chat-by-id community-id (:chat-id chat)])
|
||||
_ (reset! selected-item (:categoryID comm-chat))]
|
||||
[:<>
|
||||
@@ -44,7 +45,7 @@
|
||||
:create-community-category
|
||||
{:community-id community-id}])
|
||||
:title (i18n/label :t/create-category)}]
|
||||
:data (conj (vec (vals categories)) {:name (i18n/label :t/none) :id ""})
|
||||
:data (conj categories {:name (i18n/label :t/none) :id ""})
|
||||
:render-fn render-fn}]]
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
@@ -54,6 +55,7 @@
|
||||
[::communities/change-category-confirmation-pressed
|
||||
community-id
|
||||
@selected-item
|
||||
comm-chat]
|
||||
(assoc comm-chat :position
|
||||
(count (get chats @selected-item)))] ;; Add as last item in new category
|
||||
3000)}
|
||||
(i18n/label :t/done)]}]]))))
|
||||
|
||||
@@ -1,34 +1,8 @@
|
||||
(ns status-im.ui.screens.communities.styles
|
||||
(:require [quo.design-system.colors :as colors]))
|
||||
(ns status-im.ui.screens.communities.styles)
|
||||
|
||||
(def category-item
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:height 52
|
||||
:margin-left 18})
|
||||
|
||||
(def reorder-categories-item
|
||||
{:accessibility-label :reorder-categories-item
|
||||
:flex-direction :row
|
||||
:height 60
|
||||
:align-items :center
|
||||
:margin-left 18})
|
||||
|
||||
(defn reorder-categories-text []
|
||||
{:font-size 17
|
||||
:margin-left 10
|
||||
:color (colors/get-color :text-01)
|
||||
:flex 1})
|
||||
|
||||
(defn reorder-categories-button [margin-right]
|
||||
{:accessibility-label :reorder-categories-button
|
||||
:width 30
|
||||
:height 30
|
||||
:border-radius 15
|
||||
:margin 10
|
||||
:margin-right margin-right
|
||||
:border-width 1
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:border-color colors/black})
|
||||
:padding-left 18})
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.utils.config :as config]
|
||||
[quo.core :as quo]
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
(def titles {constants/one-day (i18n/label :t/one-day)
|
||||
(def titles {constants/two-mins (i18n/label :t/two-minutes)
|
||||
constants/one-day (i18n/label :t/one-day)
|
||||
constants/three-days (i18n/label :t/three-days)
|
||||
constants/one-week (i18n/label :t/one-week)
|
||||
constants/one-month (i18n/label :t/one-month)})
|
||||
@@ -21,6 +23,8 @@
|
||||
(views/defview default-sync-period-settings []
|
||||
(views/letsubs [{:keys [default-sync-period]} [:multiaccount]]
|
||||
[react/view {:margin-top 8}
|
||||
(when config/two-minutes-syncing?
|
||||
[radio-item constants/two-mins default-sync-period])
|
||||
[radio-item constants/one-day default-sync-period]
|
||||
[radio-item constants/three-days default-sync-period]
|
||||
[radio-item constants/one-week default-sync-period]
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
[reagent.core :as reagent]
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.communities.core :as communities]
|
||||
[status-im.ui.components.connectivity.view :as connectivity]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
@@ -13,7 +12,6 @@
|
||||
[status-im.ui.screens.home.views.inner-item :as inner-item]
|
||||
[status-im.ui.screens.referrals.home-item :as referral-item]
|
||||
[quo.design-system.colors :as colors]
|
||||
[status-im.ui.screens.add-new.new-public-chat.view :as new-public-chat]
|
||||
[quo.core :as quo]
|
||||
[status-im.add-new.core :as new-chat]
|
||||
[status-im.ui.components.search-input.view :as search-input]
|
||||
@@ -41,30 +39,10 @@
|
||||
:accessibility-label :hide-home-button}
|
||||
[icons/icon :main-icons/close-circle {:color colors/gray}]]
|
||||
[react/i18n-text {:style styles/no-chats-text :key :chat-and-transact}]
|
||||
[invite/button]
|
||||
[react/view {:align-items :center :margin-bottom 16}
|
||||
[react/view {:style (styles/hr-wrapper)}]
|
||||
[react/i18n-text {:style (styles/or-text) :key :or}]]
|
||||
[react/i18n-text {:style {:margin-horizontal 16
|
||||
:text-align :center}
|
||||
:key :follow-your-interests}]
|
||||
[react/view {:flex-direction :row :flex-wrap :wrap :justify-content :center
|
||||
:margin-top 10
|
||||
:margin-bottom 18}
|
||||
(for [chat (new-public-chat/featured-public-chats)]
|
||||
^{:key chat}
|
||||
[new-public-chat/render-topic chat])]
|
||||
(when @(re-frame/subscribe [:communities/enabled?])
|
||||
[:<>
|
||||
[react/i18n-text {:style {:margin-horizontal 16
|
||||
:text-align :center}
|
||||
:key :join-a-community}]
|
||||
[react/view {:flex-direction :row :flex-wrap :wrap :justify-content :center
|
||||
:margin-top 10
|
||||
:margin-bottom 18}
|
||||
(for [{:keys [id] :as community} communities/featured]
|
||||
^{:key id}
|
||||
[communities.views/render-featured-community community])]])])
|
||||
[react/view {:align-items :center
|
||||
:margin-top 8
|
||||
:margin-bottom 12}
|
||||
[invite/button]]])
|
||||
|
||||
(defn welcome-blank-page []
|
||||
[react/view {:style {:flex 1 :flex-direction :row :align-items :center :justify-content :center}}
|
||||
|
||||
@@ -149,13 +149,16 @@
|
||||
:else
|
||||
[icons/icon :main-icons/tiny-new-contact (icon-style)]))
|
||||
|
||||
(defn chat-item-title [chat-id muted group-chat chat-name]
|
||||
(defn chat-item-title [chat-id muted group-chat chat-name edit?]
|
||||
[quo/text {:weight :medium
|
||||
:color (when muted :secondary)
|
||||
:accessibility-label :chat-name-text
|
||||
:ellipsize-mode :tail
|
||||
:number-of-lines 1
|
||||
:style {:position :absolute :left 92 :top 10 :right 90}}
|
||||
:style {:position :absolute
|
||||
:left 92
|
||||
:top 10
|
||||
:right (if edit? 50 90)}}
|
||||
(if group-chat
|
||||
(utils/truncate-str chat-name 30)
|
||||
;; This looks a bit odd, but I would like only to subscribe
|
||||
@@ -164,7 +167,7 @@
|
||||
(first @(re-frame/subscribe [:contacts/contact-two-names-by-identity chat-id])))])
|
||||
|
||||
(defn home-list-item [home-item opts]
|
||||
(let [{:keys [chat-id chat-name color group-chat public? timestamp last-message muted emoji highlight]} home-item
|
||||
(let [{:keys [chat-id chat-name color group-chat public? timestamp last-message muted emoji highlight edit?]} home-item
|
||||
background-color (when highlight (colors/get-color :interactive-02))]
|
||||
[react/touchable-opacity (merge {:style {:height 64 :background-color background-color}} opts)
|
||||
[:<>
|
||||
@@ -178,13 +181,15 @@
|
||||
:default-chat-icon-text (if (string/blank? emoji)
|
||||
(chat-icon.styles/default-chat-icon-text 40)
|
||||
(chat-icon.styles/emoji-chat-icon-text 40))}]
|
||||
[chat-item-title chat-id muted group-chat chat-name]
|
||||
[react/text {:style styles/datetime-text
|
||||
:number-of-lines 1
|
||||
:accessibility-label :last-message-time-text}
|
||||
;;TODO (perf) move to event
|
||||
(memo-timestamp (if (pos? (:whisper-timestamp last-message))
|
||||
(:whisper-timestamp last-message)
|
||||
timestamp))]
|
||||
[message-content-text (select-keys last-message [:content :content-type :community-id]) true]
|
||||
[unviewed-indicator home-item]]]))
|
||||
[chat-item-title chat-id muted group-chat chat-name edit?]
|
||||
(when-not edit?
|
||||
[:<>
|
||||
[react/text {:style styles/datetime-text
|
||||
:number-of-lines 1
|
||||
:accessibility-label :last-message-time-text}
|
||||
;;TODO (perf) move to event
|
||||
(memo-timestamp (if (pos? (:whisper-timestamp last-message))
|
||||
(:whisper-timestamp last-message)
|
||||
timestamp))]
|
||||
[unviewed-indicator home-item]])
|
||||
[message-content-text (select-keys last-message [:content :content-type :community-id]) true]]]))
|
||||
|
||||
@@ -44,6 +44,17 @@
|
||||
[status-im.ui.screens.currency-settings.views :as currency-settings]
|
||||
[status-im.ui.screens.dapps-permissions.views :as dapps-permissions]
|
||||
[status-im.ui.screens.default-sync-period-settings.view :as default-sync-period-settings]
|
||||
[status-im.ui.screens.wallet.settings.views :as wallet-settings]
|
||||
[status-im.ui.screens.wallet.transactions.views :as wallet-transactions]
|
||||
[status-im.ui.screens.wallet.custom-tokens.views :as custom-tokens]
|
||||
[status-im.ui.screens.wallet.accounts.views :as wallet.accounts]
|
||||
[status-im.ui.screens.wallet.collectibles.views :as wallet.collectibles]
|
||||
[status-im.ui.screens.wallet.account.views :as wallet.account]
|
||||
[status-im.ui.screens.wallet.add-new.views :as add-account]
|
||||
[status-im.ui.screens.wallet.account-settings.views :as account-settings]
|
||||
[status-im.ui.screens.wallet.swap.views :as wallet.swap]
|
||||
[status-im.ui.screens.status.views :as status.views]
|
||||
[status-im.ui.screens.profile.user.views :as profile.user]
|
||||
[status-im.ui.screens.ens.views :as ens]
|
||||
[status-im.ui.screens.fleet-settings.views :as fleet-settings]
|
||||
[status-im.ui.screens.glossary.view :as glossary]
|
||||
@@ -91,7 +102,6 @@
|
||||
[status-im.ui.screens.profile.contact.views :as contact]
|
||||
[status-im.ui.screens.profile.group-chat.views :as profile.group-chat]
|
||||
[status-im.ui.screens.profile.seed.views :as profile.seed]
|
||||
[status-im.ui.screens.profile.user.views :as profile.user]
|
||||
[status-im.ui.screens.progress.views :as progress]
|
||||
[status-im.ui.screens.qr-scanner.views :as qr-scanner]
|
||||
[status-im.ui.screens.referrals.public-chat :as referrals.public-chat]
|
||||
@@ -99,7 +109,6 @@
|
||||
[status-im.ui.screens.reset-password.views :as reset-password]
|
||||
[status-im.ui.screens.rpc-usage-info :as rpc-usage-info]
|
||||
[status-im.ui.screens.status.new.views :as status.new]
|
||||
[status-im.ui.screens.status.views :as status.views]
|
||||
[status-im.ui.screens.stickers.views :as stickers]
|
||||
[status-im.ui.screens.sync-settings.views :as sync-settings]
|
||||
[status-im.ui.screens.terms-of-service.views :as terms-of-service]
|
||||
@@ -107,18 +116,10 @@
|
||||
:as
|
||||
edit-wakuv2-node]
|
||||
[status-im.ui.screens.wakuv2-settings.views :as wakuv2-settings]
|
||||
[status-im.ui.screens.wallet.account-settings.views :as account-settings]
|
||||
[status-im.ui.screens.wallet.account.views :as wallet.account]
|
||||
[status-im.ui.screens.wallet.accounts-manage.views :as accounts-manage]
|
||||
[status-im.ui.screens.wallet.accounts.views :as wallet.accounts]
|
||||
[status-im.ui.screens.wallet.add-new.views :as add-account]
|
||||
[status-im.ui.screens.wallet.buy-crypto.views :as wallet.buy-crypto]
|
||||
[status-im.ui.screens.wallet.collectibles.views :as wallet.collectibles]
|
||||
[status-im.ui.screens.wallet.custom-tokens.views :as custom-tokens]
|
||||
[status-im.ui.screens.wallet.recipient.views :as recipient]
|
||||
[status-im.ui.screens.wallet.send.views :as wallet.send]
|
||||
[status-im.ui.screens.wallet.settings.views :as wallet-settings]
|
||||
[status-im.ui.screens.wallet.transactions.views :as wallet-transactions]))
|
||||
[status-im.ui.screens.wallet.send.views :as wallet.send]))
|
||||
|
||||
(def components
|
||||
[{:name :chat-toolbar
|
||||
@@ -220,9 +221,9 @@
|
||||
;Chat
|
||||
{:name :chat
|
||||
:options {:popGesture false
|
||||
:topBar {:title {:component {:name :chat-toolbar :id :chat-toolbar}
|
||||
:alignment :fill}
|
||||
:rightButtons (right-button-options :chat :more)}}
|
||||
:topBar {:title {:component {:name :chat-toolbar :id :chat-toolbar}
|
||||
:alignment :fill}
|
||||
:rightButtons (right-button-options :chat :more)}}
|
||||
:right-handler chat/topbar-button
|
||||
:component chat/chat}
|
||||
|
||||
@@ -288,11 +289,6 @@
|
||||
;;TODO custom
|
||||
:options {:topBar {:visible false}}
|
||||
:component select-category/view}
|
||||
{:name :community-edit-chats
|
||||
;;TODO custom
|
||||
:insets {:bottom true}
|
||||
:options {:topBar {:visible false}}
|
||||
:component community/community-edit}
|
||||
{:name :community-reorder-categories
|
||||
:insets {:top false}
|
||||
:options {:topBar {:visible false}}
|
||||
@@ -400,6 +396,32 @@
|
||||
:options {:topBar {:title {:text (i18n/label :t/wallet-manage-accounts)}}}
|
||||
:component accounts-manage/manage}
|
||||
|
||||
{:name :token-swap
|
||||
;;TODO dynamic title
|
||||
:options {:topBar {:visible false}}
|
||||
:component wallet.swap/swap}
|
||||
|
||||
{:name :token-swap-advanced-nonce
|
||||
:options {:topBar {:title {:text (i18n/label :t/nonce)}}}
|
||||
:component wallet.swap/nonce-modal}
|
||||
|
||||
{:name :token-swap-advanced-approve-token
|
||||
:options {:topBar {:title {:text (i18n/label :t/approve-token)}}}
|
||||
:component wallet.swap/approve-token-modal}
|
||||
|
||||
{:name :token-swap-advanced-transaction-fee
|
||||
:options {:topBar {:title {:text (i18n/label :t/transaction-fee)}}}
|
||||
:component wallet.swap/transaction-fee-modal}
|
||||
|
||||
{:name :token-swap-advanced-swap-details
|
||||
:options {:topBar {:title {:text (i18n/label :t/swap-details)}}}
|
||||
:component wallet.swap/swap-details-modal}
|
||||
|
||||
{:name :swap-asset-selector
|
||||
;;TODO dynamic title
|
||||
:options {:topBar {:visible false}}
|
||||
:component wallet.swap/asset-selector}
|
||||
|
||||
;;MY STATUS
|
||||
|
||||
{:name :status
|
||||
@@ -708,8 +730,8 @@
|
||||
:options {:topBar {:visible false}}
|
||||
:component wallet.buy-crypto/website}
|
||||
|
||||
{:name :nft-details
|
||||
:insets {:bottom true}
|
||||
{:name :nft-details
|
||||
:insets {:bottom true}
|
||||
;;TODO dynamic title
|
||||
:options {:topBar {:visible false}}
|
||||
:component wallet.collectibles/nft-details-modal}
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[quo.components.animated.pressable :as pressable]
|
||||
[status-im.ui.screens.status.views :as status.views]
|
||||
[status-im.ui.screens.status.new.styles :as styles]))
|
||||
[status-im.ui.screens.status.new.styles :as styles]
|
||||
[status-im.utils.platform :as platform]))
|
||||
|
||||
(defn buttons []
|
||||
[react/view styles/buttons
|
||||
@@ -43,7 +44,7 @@
|
||||
^{:key (str "image" img)}
|
||||
[image-preview img])]]))
|
||||
|
||||
(def message-max-lenght 600)
|
||||
(def message-max-length 600)
|
||||
|
||||
(defn my-status []
|
||||
(let [images-opened (reagent/atom false)
|
||||
@@ -53,7 +54,8 @@
|
||||
input-text (re-frame/subscribe [:chats/timeline-chat-input-text])
|
||||
sending-image (re-frame/subscribe [:chats/timeline-sending-image])]
|
||||
(fn []
|
||||
(let [{:keys [uri]} (first (vals @sending-image))]
|
||||
(let [{:keys [uri]} (first (vals @sending-image))
|
||||
text-length (count @input-text)]
|
||||
[kb-presentation/keyboard-avoiding-view {:style {:flex 1}}
|
||||
[:<>
|
||||
[react/scroll-view {:style {:flex 1}
|
||||
@@ -65,7 +67,10 @@
|
||||
{:style {:margin 16}
|
||||
:scroll-enabled false
|
||||
:accessibility-label :my-status-input
|
||||
:max-length message-max-lenght
|
||||
:max-length (if platform/android?
|
||||
message-max-length
|
||||
(when (>= text-length message-max-length)
|
||||
text-length))
|
||||
:auto-focus true
|
||||
:multiline true
|
||||
:on-selection-change (fn [args]
|
||||
@@ -100,11 +105,14 @@
|
||||
{:accessibility-label :send-my-status-button
|
||||
:type :secondary
|
||||
:after :main-icon/send
|
||||
:disabled (and (string/blank? @input-text) (not uri))
|
||||
:disabled (or (> text-length message-max-length)
|
||||
(and (string/blank? @input-text) (not uri)))
|
||||
:on-press #(do
|
||||
(re-frame/dispatch [:profile.ui/send-my-status-message])
|
||||
(re-frame/dispatch [:navigate-back]))}
|
||||
(i18n/label :t/wallet-send)]}]
|
||||
[react/view styles/count-container
|
||||
[react/text {:style {:color colors/gray}}
|
||||
(str (count @input-text) " / " message-max-lenght)]]]]]]))))
|
||||
[react/text {:style {:color (if (> text-length message-max-length)
|
||||
colors/red
|
||||
colors/gray)}}
|
||||
(str text-length " / " message-max-length)]]]]]]))))
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
:chevron true
|
||||
:accessory :text
|
||||
:accessory-text (cond
|
||||
(= default-sync-period constants/two-mins)
|
||||
(i18n/label :t/two-minutes)
|
||||
(= default-sync-period constants/one-day)
|
||||
(i18n/label :t/one-day)
|
||||
(= default-sync-period constants/three-days)
|
||||
|
||||
@@ -42,3 +42,19 @@
|
||||
:duration 200
|
||||
:easing (.-ease ^js animation/easing)
|
||||
:useNativeDriver true}))
|
||||
|
||||
(def round-action-button
|
||||
{:background-color colors/blue
|
||||
:height 44
|
||||
:flex 1
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:width 44
|
||||
:border-radius 44})
|
||||
|
||||
(def top-actions
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:width "60%"
|
||||
:align-self :center})
|
||||
|
||||
@@ -7,16 +7,17 @@
|
||||
[quo.design-system.colors :as colors]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[quo.core :as quo]
|
||||
[quo.design-system.spacing :as spacing]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.ui.screens.wallet.account.styles :as styles]
|
||||
[status-im.ui.screens.wallet.accounts.sheets :as sheets]
|
||||
[status-im.ui.screens.wallet.accounts.views :as accounts]
|
||||
[status-im.ui.screens.wallet.buy-crypto.views :as buy-crypto]
|
||||
[status-im.ui.screens.wallet.transactions.views :as history]
|
||||
[status-im.ui.components.tabs :as tabs]
|
||||
[status-im.ui.screens.wallet.collectibles.views :as collectibles.views])
|
||||
[status-im.ui.screens.wallet.collectibles.views :as collectibles.views]
|
||||
[status-im.ui.screens.wallet.buy-crypto.views :as buy-crypto])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(def state (reagent/atom {:tab :assets}))
|
||||
@@ -102,7 +103,6 @@
|
||||
currency [:wallet/currency]
|
||||
opensea-enabled? [:opensea-enabled?]
|
||||
collectible-collection [:wallet/collectible-collection address]
|
||||
mainnet? [:mainnet?]
|
||||
ethereum-network? [:ethereum-network?]]
|
||||
(let [{:keys [tab]} @state]
|
||||
[react/view {:flex 1}
|
||||
@@ -111,11 +111,10 @@
|
||||
(when ethereum-network?
|
||||
[tabs/tab-title state :nft (i18n/label :t/wallet-collectibles) (= tab :nft)])
|
||||
[tabs/tab-title state :history (i18n/label :t/history) (= tab :history)]]
|
||||
[quo/separator {:style {:margin-top -8}}]
|
||||
(cond
|
||||
(= tab :assets)
|
||||
[:<>
|
||||
(when mainnet?
|
||||
[buy-crypto/banner])
|
||||
(for [item tokens]
|
||||
^{:key (:name item)}
|
||||
[accounts/render-asset item nil nil (:code currency)])]
|
||||
@@ -181,10 +180,31 @@
|
||||
(styles/bottom-send-recv-buttons-lower anim-y button-group-height)
|
||||
#(reset! to-show false))))))))
|
||||
|
||||
(defn round-action-button [{:keys [icon title on-press]}]
|
||||
[react/view {:style {:flex 1
|
||||
:align-items :center
|
||||
:margin-vertical (:large spacing/spacing)}}
|
||||
[react/touchable-opacity {:style styles/round-action-button
|
||||
:on-press on-press}
|
||||
(icons/icon icon {:color colors/white})]
|
||||
[quo/text {:color :secondary
|
||||
:size :small
|
||||
:style {:margin-top (:tiny spacing/spacing)}}
|
||||
title]])
|
||||
|
||||
(defn top-actions []
|
||||
[react/view {:style styles/top-actions}
|
||||
[round-action-button {:icon :main-icons/add
|
||||
:title (i18n/label :t/buy-crypto)
|
||||
:on-press #(re-frame/dispatch [:buy-crypto.ui/open-screen])}]
|
||||
[round-action-button {:icon :main-icons/change
|
||||
:title (i18n/label :t/swap)
|
||||
:on-press #(re-frame/dispatch [:open-modal :token-swap])}]])
|
||||
|
||||
(views/defview account []
|
||||
(views/letsubs [{:keys [name address] :as account} [:multiaccount/current-account]
|
||||
fetching-error [:wallet/fetching-error]]
|
||||
(let [anim-y (animation/create-value button-group-height)
|
||||
(let [anim-y (animation/create-value button-group-height)
|
||||
scroll-y (animation/create-value 0)]
|
||||
(anim-listener anim-y scroll-y)
|
||||
[:<>
|
||||
@@ -206,9 +226,9 @@
|
||||
@accounts/updates-counter
|
||||
@(re-frame/subscribe [:wallet/refreshing-history?])))}
|
||||
(when fetching-error
|
||||
[react/view {:style {:flex 1
|
||||
[react/view {:style {:flex 1
|
||||
:align-items :center
|
||||
:margin 8}}
|
||||
:margin 8}}
|
||||
[icons/icon
|
||||
:main-icons/warning
|
||||
{:color :red
|
||||
@@ -233,5 +253,8 @@
|
||||
[react/scroll-view {:horizontal true}
|
||||
[react/view {:flex-direction :row :padding-top 8 :padding-bottom 12}
|
||||
[account-card account]]]]
|
||||
(if config/swap-enabled?
|
||||
[top-actions]
|
||||
[buy-crypto/banner])
|
||||
[assets-and-collections address]]
|
||||
[bottom-send-recv-buttons account anim-y]])))
|
||||
|
||||
@@ -0,0 +1,433 @@
|
||||
(ns status-im.ui.screens.wallet.swap.views
|
||||
(:require [quo.core :as quo]
|
||||
[quo.design-system.colors :as colors]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ethereum.tokens :as tokens]
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.ui.components.keyboard-avoid-presentation
|
||||
:as
|
||||
kb-presentation]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.search-input.view :as search-input]
|
||||
[status-im.ui.components.slider :as slider]
|
||||
[status-im.wallet.swap.core :as wallet.swap]
|
||||
[status-im.ui.components.toolbar :as toolbar]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.ui.screens.wallet.components.views :as wallet.components]
|
||||
[status-im.utils.handlers :refer [<sub]]
|
||||
[status-im.wallet.utils :as wallet.utils]
|
||||
[clojure.string :as str]))
|
||||
|
||||
(defn render-asset [{{:keys
|
||||
[icon decimals amount color value]
|
||||
:as token} :token
|
||||
currency :currency
|
||||
on-press :on-press}]
|
||||
[quo/list-item
|
||||
{:title [quo/text {:weight :medium}
|
||||
[quo/text {:weight :inherit}
|
||||
(str (if amount
|
||||
(wallet.utils/format-amount amount decimals)
|
||||
"...")
|
||||
" ")]
|
||||
[quo/text {:color :secondary
|
||||
:weight :inherit}
|
||||
(wallet.utils/display-symbol token)]]
|
||||
:on-press on-press
|
||||
:subtitle (str (if value value "...") " " currency)
|
||||
:accessibility-label
|
||||
(str (:symbol token) "-asset-value")
|
||||
:icon (if icon
|
||||
[wallet.components/token-icon icon]
|
||||
[chat-icon/custom-icon-view-list (:name token) color])}])
|
||||
|
||||
(defn asset-selector []
|
||||
(let [{:keys [address]} (<sub [:multiaccount/current-account])
|
||||
{:keys [tokens]} (<sub [:wallet/visible-assets-with-values address])
|
||||
source? (<sub [:wallet/modal-selecting-source-token?])
|
||||
currency (<sub [:wallet/currency])]
|
||||
[:<>
|
||||
[topbar/topbar
|
||||
{:title (if source?
|
||||
(i18n/label :t/select-token-to-swap)
|
||||
(i18n/label :t/select-token-to-receive))
|
||||
:modal? true}]
|
||||
|
||||
[search-input/search-input
|
||||
{:search-active? true}]
|
||||
|
||||
[react/scroll-view
|
||||
(for [token tokens]
|
||||
^{:key (:name token)}
|
||||
[render-asset {:token token
|
||||
:on-press #(re-frame/dispatch
|
||||
[(if source?
|
||||
::wallet.swap/set-from-token
|
||||
::wallet.swap/set-to-token)
|
||||
(:symbol token)])
|
||||
:currency (:code currency)}])]]))
|
||||
|
||||
(defn pill-button [{:keys [on-press label margin-left]}]
|
||||
[react/touchable-opacity {:on-press on-press
|
||||
:style {:background-color colors/blue-light
|
||||
:padding-horizontal 12
|
||||
:padding-vertical 2
|
||||
:border-radius 24
|
||||
:margin-left (or margin-left 8)}}
|
||||
[quo/text {:color :link
|
||||
:weight :medium} label]])
|
||||
|
||||
(defn token-display
|
||||
"Show token and act as an anchor to open selector."
|
||||
[{:keys [token source?]}]
|
||||
(let [token-icon-source (-> token :icon :source)]
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [::wallet.swap/open-asset-selector-modal source?])}
|
||||
[react/view {:style {:flex-direction :row
|
||||
:align-items :center
|
||||
:border-width 1
|
||||
:border-color colors/gray-lighter
|
||||
:border-radius 8
|
||||
:margin-left 16
|
||||
:padding-horizontal 8
|
||||
:padding-vertical 2}
|
||||
:accessibility-label
|
||||
:choose-asset-button}
|
||||
[quo/text {:style {:margin-right 8}}
|
||||
(-> token :symbol name)]
|
||||
[react/image {:source (if (fn? token-icon-source)
|
||||
(token-icon-source)
|
||||
token-icon-source)}]]]))
|
||||
|
||||
(defn token-input
|
||||
"Component to get the amount and type of tokens"
|
||||
[{:keys [amount error label token max-from source?]}]
|
||||
(let [window-width (<sub [:dimensions/window-width])]
|
||||
[react/view {:style {:justify-content :space-between
|
||||
:flex-direction :row
|
||||
:align-items :center}}
|
||||
[react/view {:flex 2}
|
||||
[react/view {:flex-direction :row
|
||||
:align-items :center}
|
||||
[quo/text label]
|
||||
(when max-from [pill-button {:on-press #()
|
||||
:label "Max 0.043"}])]
|
||||
[react/text-input
|
||||
{:style {:font-size 38
|
||||
:max-width (- (* (/ window-width 4) 3) 106)
|
||||
:color (if error colors/red colors/black)}
|
||||
:keyboard-type :decimal-pad
|
||||
:auto-capitalize :words
|
||||
:accessibility-label :amount-input
|
||||
:default-value amount
|
||||
:editable true
|
||||
:auto-focus true
|
||||
:on-change-text #(re-frame/dispatch [(when source?
|
||||
::wallet.swap/set-from-token-amount)
|
||||
%])
|
||||
:placeholder "0.0"}]]
|
||||
[token-display {:token token
|
||||
:source? source?}]]))
|
||||
|
||||
(defn separator-with-icon []
|
||||
[react/view
|
||||
{:margin-vertical 8}
|
||||
[quo/separator]
|
||||
[react/touchable-opacity
|
||||
{:on-press #(re-frame/dispatch [::wallet.swap/switch-from-token-with-to])}
|
||||
[react/view {:style {:background-color colors/gray-lighter
|
||||
:width 40
|
||||
:height 40
|
||||
:border-radius 40
|
||||
:border-width 4
|
||||
:border-color colors/white
|
||||
:margin-top -20
|
||||
:margin-bottom -20
|
||||
:align-self :center
|
||||
:align-items :center
|
||||
:justify-content :center}}
|
||||
[react/image {:source (icons/icon-source :main-icons/change)
|
||||
:style {:tint-color colors/gray
|
||||
:transform [{:rotate "90deg"}]}}]]]])
|
||||
|
||||
(defn floating-card [{:keys [icon title body on-press]}]
|
||||
[react/view {:style {:border-width 1
|
||||
:padding 2 ;; need a padding because border breaks otherwise
|
||||
:border-radius 12
|
||||
:margin-top 12
|
||||
:border-color colors/gray-lighter}}
|
||||
[quo/list-item {:title title
|
||||
:subtitle body
|
||||
:active-background-enabled
|
||||
false
|
||||
:on-press on-press
|
||||
:theme :main
|
||||
:chevron true
|
||||
:icon [react/view {:style {:background-color colors/blue-light
|
||||
:padding 8
|
||||
:border-radius 4}}
|
||||
(icons/icon icon {:color :dark})]}]])
|
||||
|
||||
(defn card-body-row [key value primary?]
|
||||
[react/view {:flex-direction :row}
|
||||
[quo/text {:color (when-not primary? :secondary)} key]
|
||||
[quo/text {:style {:margin-right 4}
|
||||
:color (when-not primary? :secondary)} ":"]
|
||||
[quo/text {:ellipsize-mode :middle
|
||||
:number-of-lines 1
|
||||
:style {:width "50%"}
|
||||
:color (when-not primary? :secondary)
|
||||
:weight :semi-bold} value]])
|
||||
|
||||
(defn transaction-fee-card [{:keys [gas-amount price-limit tip-limit gas-in-eth gas-in-usd]}]
|
||||
[floating-card {:title (i18n/label :t/transaction-fee)
|
||||
:icon :main-icons/gas
|
||||
:on-press #(re-frame/dispatch [:open-modal :token-swap-advanced-transaction-fee])
|
||||
:body [react/view
|
||||
[card-body-row (i18n/label :t/gas-amount-limit) gas-amount]
|
||||
[card-body-row (i18n/label :t/per-gas-price-limit) price-limit]
|
||||
[card-body-row (i18n/label :t/per-gas-tip-limit) tip-limit]
|
||||
[card-body-row (i18n/label :t/total-gas)
|
||||
(str gas-in-eth " • $" gas-in-usd)
|
||||
true]]}])
|
||||
|
||||
(defn swap-details-card [{:keys [slippage price-impact]}]
|
||||
[floating-card {:title (i18n/label :t/swap-details)
|
||||
:icon :main-icons/change
|
||||
:on-press #(re-frame/dispatch [:open-modal :token-swap-advanced-swap-details])
|
||||
:body [react/view
|
||||
[card-body-row (i18n/label :t/slippage) (str slippage " %")]
|
||||
[card-body-row (i18n/label :t/price-impact) (str price-impact " %")]]}])
|
||||
|
||||
(defn nonce-card [{:keys [nonce]}]
|
||||
[floating-card {:title (i18n/label :t/nonce)
|
||||
:icon :main-icons/channel
|
||||
:on-press #(re-frame/dispatch [:open-modal :token-swap-advanced-nonce])
|
||||
:body [react/view
|
||||
[card-body-row (i18n/label :t/nonce) nonce]]}])
|
||||
|
||||
(defn approve-token-card [{:keys [token contract-address approve-limit]}]
|
||||
[floating-card {:title (i18n/label :t/approve)
|
||||
:icon :main-icons/check
|
||||
:on-press #(re-frame/dispatch [:open-modal :token-swap-advanced-approve-token])
|
||||
:body [react/view
|
||||
[card-body-row (i18n/label :t/token) token]
|
||||
[card-body-row (i18n/label :t/contract-address) contract-address]
|
||||
[card-body-row (i18n/label :t/approve-limit) approve-limit]]}])
|
||||
|
||||
(defn advanced-input [{:keys [label label-help value on-change after]}]
|
||||
[react/view {:style {:padding-horizontal 16
|
||||
:margin-bottom 16}}
|
||||
[react/view {:style {:flex-direction :row
|
||||
:justify-content :space-between}}
|
||||
[quo/text {} label]
|
||||
label-help]
|
||||
|
||||
[quo/text-input {:default-value (str value)
|
||||
:show-cancel false
|
||||
:style {:margin-top 12
|
||||
:border-radius 8}
|
||||
:after {:component after}
|
||||
:on-change-text on-change}]])
|
||||
|
||||
(defn help-label-kv [{:keys [key value]}]
|
||||
[react/view {:style {:flex-direction :row}}
|
||||
[quo/text {:color :secondary} key]
|
||||
[quo/text {:color :secondary
|
||||
:style {:margin-right 4}} ":"]
|
||||
[quo/text {:color :secondary} value]])
|
||||
|
||||
(defn nonce-modal []
|
||||
(let [last-txn-nonce 22
|
||||
nonce 23]
|
||||
[kb-presentation/keyboard-avoiding-view {:style {:flex 1
|
||||
:margin-top 16}
|
||||
:ignore-offset true}
|
||||
[advanced-input {:label (i18n/label :t/nonce)
|
||||
:label-help [help-label-kv {:key (i18n/label :t/last-transaction)
|
||||
:value last-txn-nonce}]
|
||||
:value nonce
|
||||
:on-change #()
|
||||
:on-save #()}]
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:left [quo/button {:type :secondary}
|
||||
(i18n/label :t/cancel)]
|
||||
:right [quo/button {:theme :accent}
|
||||
(i18n/label :t/save)]}]]))
|
||||
|
||||
(defn approve-token-modal []
|
||||
[quo/text "modal"])
|
||||
|
||||
(defn transaction-fee-modal []
|
||||
(let [gas-amount-limit 21000
|
||||
gas-amount 21000
|
||||
per-gas-price-limit 7.3
|
||||
current-avg-per-gas-price-limit 7.3
|
||||
per-gas-tip-limit 150
|
||||
current-avg-per-gas-tip-limit 150]
|
||||
[kb-presentation/keyboard-avoiding-view {:style {:flex 1
|
||||
:margin-top 16}
|
||||
:ignore-offset true}
|
||||
[react/view {:flex 1}
|
||||
[advanced-input {:label (i18n/label :t/gas-amount-limit)
|
||||
:label-help [help-label-kv {:key (i18n/label :t/limit)
|
||||
:value gas-amount-limit}]
|
||||
:value gas-amount
|
||||
:after [quo/text {:color :secondary} (i18n/label :t/gwei)]
|
||||
:on-change #()
|
||||
:on-save #()}]
|
||||
|
||||
[advanced-input {:label (i18n/label :t/per-gas-price-limit)
|
||||
:label-help [help-label-kv {:key (i18n/label :t/current-average)
|
||||
:value current-avg-per-gas-price-limit}]
|
||||
:value per-gas-price-limit
|
||||
:after [quo/text {:color :secondary} (i18n/label :t/gwei)]
|
||||
:on-change #()
|
||||
:on-save #()}]
|
||||
|
||||
[advanced-input {:label (i18n/label :t/per-gas-price-limit)
|
||||
:label-help [help-label-kv {:key (i18n/label :t/current-average)
|
||||
:value current-avg-per-gas-tip-limit}]
|
||||
:value per-gas-tip-limit
|
||||
:after [quo/text {:color :secondary} (i18n/label :t/gwei)]
|
||||
:on-change #()
|
||||
:on-save #()}]
|
||||
|
||||
[quo/list-item {:title (i18n/label :t/maximum-fee)
|
||||
:text-size :base
|
||||
:title-text-weight :regular
|
||||
:accessory :text
|
||||
:accessory-text [quo/text "0.3 ETH"]
|
||||
:container-style {:margin-top 16}}]
|
||||
[quo/text {:color :secondary
|
||||
:style {:padding-horizontal 16}}
|
||||
(i18n/label :t/maximum-fee-desc)]]
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:left [quo/button {:type :secondary}
|
||||
(i18n/label :t/cancel)]
|
||||
:right [quo/button {:theme :accent}
|
||||
(i18n/label :t/save)]}]]))
|
||||
|
||||
(defn swap-details-modal []
|
||||
(let [slippage-limit 20
|
||||
slippage 0.5
|
||||
price-impact 4]
|
||||
[kb-presentation/keyboard-avoiding-view {:style {:flex 1
|
||||
:margin-top 16}
|
||||
:ignore-offset true}
|
||||
[react/view {:flex 1}
|
||||
[advanced-input {:label (str (i18n/label :t/slippage) " %")
|
||||
:label-help [help-label-kv {:key (i18n/label :t/limit)
|
||||
:value (str slippage-limit "%")}]
|
||||
:value slippage
|
||||
:on-change #()
|
||||
:on-save #()}]
|
||||
|
||||
[quo/list-item {:title (i18n/label :t/price-impact)
|
||||
:text-size :base
|
||||
:title-text-weight :regular
|
||||
:accessory :text
|
||||
:accessory-text (str price-impact "%")
|
||||
:container-style {:margin-top 16}}]
|
||||
[quo/text {:color :secondary
|
||||
:style {:padding-horizontal 16}}
|
||||
(i18n/label :t/price-impact-desc)]]
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:left [quo/button {:type :secondary}
|
||||
(i18n/label :t/cancel)]
|
||||
:right [quo/button {:theme :accent}
|
||||
(i18n/label :t/save)]}]]))
|
||||
|
||||
(defn advanced-settings []
|
||||
[react/view {:style {:flex 1
|
||||
:padding-horizontal 16}}
|
||||
[react/view {:align-self :flex-start}
|
||||
[pill-button {:label (i18n/label :t/switch-to-simple-interface)
|
||||
:margin-left 0
|
||||
:on-press #(re-frame/dispatch [::wallet.swap/set-advanced-mode false])}]]
|
||||
[transaction-fee-card {:gas-amount 21000
|
||||
:price-limit 74
|
||||
:tip-limit 21
|
||||
:gas-in-eth 0.0031
|
||||
:gas-in-usd 34.28}]
|
||||
[swap-details-card {:slippage 0.5
|
||||
:price-impact 4}]
|
||||
[approve-token-card {:token "USDC"
|
||||
:contract-address "0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2"
|
||||
:approve-limit "unlimited"}]
|
||||
[nonce-card {:nonce 22}]])
|
||||
|
||||
(defn swap []
|
||||
(let [{:keys [name]}
|
||||
(<sub [:multiaccount/current-account])
|
||||
all-tokens (<sub [:wallet/all-tokens])
|
||||
from-symbol (<sub [:wallet/swap-from-token])
|
||||
to-symbol (<sub [:wallet/swap-to-token])
|
||||
advanced-mode? (<sub [:wallet/swap-advanced-mode?])
|
||||
amount "0.02"
|
||||
from-token (tokens/symbol->token all-tokens (or from-symbol :DGX))
|
||||
to-token (tokens/symbol->token all-tokens (or to-symbol :SNT))]
|
||||
|
||||
[kb-presentation/keyboard-avoiding-view {:style (merge
|
||||
{:flex 1})
|
||||
:ignore-offset true}
|
||||
[topbar/topbar
|
||||
{:title name
|
||||
:subtitle (str/upper-case (i18n/label :t/powered-by-paraswap))
|
||||
:modal? true}]
|
||||
|
||||
[react/view (merge {:padding-horizontal 16
|
||||
:margin-vertical 32}
|
||||
(when-not advanced-mode?
|
||||
{:flex 1}))
|
||||
[token-input {:amount amount
|
||||
:error nil
|
||||
:label (i18n/label :t/amount)
|
||||
:token from-token
|
||||
:source? true
|
||||
:max-from 67.28}]
|
||||
|
||||
[separator-with-icon]
|
||||
|
||||
[token-input {:amount "0.01"
|
||||
:error nil
|
||||
:label (i18n/label :t/minimum-received)
|
||||
:source? false
|
||||
:token to-token}]]
|
||||
|
||||
(when-not advanced-mode?
|
||||
[react/view {:style {:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:padding-horizontal 16
|
||||
:align-items :center}}
|
||||
[react/view {:style {:flex-direction :row}}
|
||||
[quo/text {} (i18n/label :t/priority)]
|
||||
[pill-button {:label (i18n/label :t/advanced)
|
||||
:on-press #(re-frame/dispatch [::wallet.swap/set-advanced-mode true])}]]
|
||||
|
||||
[quo/text {:color :secondary} "0.0034 ETH/ $ 8.09"]])
|
||||
|
||||
(comment
|
||||
(re-frame/dispatch [::wallet.swap/set-advanced-mode false]))
|
||||
|
||||
(when-not advanced-mode?
|
||||
[react/view {:style {:padding-horizontal 16}}
|
||||
[slider/animated-slider
|
||||
{:minimum-value 0
|
||||
:maximum-value 100
|
||||
:style {:margin-vertical 8}}]])
|
||||
|
||||
(when advanced-mode?
|
||||
[quo/text "here"]
|
||||
[advanced-settings])
|
||||
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:right [quo/button {:theme :accent}
|
||||
(i18n/label :t/swap)]}]]))
|
||||
|
||||
@@ -52,6 +52,8 @@
|
||||
(def delete-message-enabled? (enabled? (get-config :DELETE_MESSAGE_ENABLED "0")))
|
||||
(def collectibles-enabled? (enabled? (get-config :COLLECTIBLES_ENABLED "1")))
|
||||
(def test-stateofus? (enabled? (get-config :TEST_STATEOFUS "0")))
|
||||
(def two-minutes-syncing? (enabled? (get-config :TWO_MINUTES_SYNCING "0")))
|
||||
(def swap-enabled? (enabled? (get-config :SWAP_ENABLED "0")))
|
||||
|
||||
;; CONFIG VALUES
|
||||
(def log-level
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
(defn clj->pretty-json [data spaces]
|
||||
(.stringify js/JSON (clj-bean/->js data) nil spaces))
|
||||
|
||||
(defn js->pretty-json [data]
|
||||
(.stringify js/JSON data nil 2))
|
||||
|
||||
(defn clj->json [data]
|
||||
(clj->pretty-json data 0))
|
||||
|
||||
|
||||
@@ -434,7 +434,7 @@
|
||||
|
||||
(fx/defn wallet-send-gas-price-success
|
||||
{:events [:wallet.send/update-gas-price-success]}
|
||||
[{db :db} tx-entry price]
|
||||
[{db :db} tx-entry price {:keys [maxFeePerGas maxPriorityFeePerGas gasPrice]}]
|
||||
(if (eip1559/sync-enabled?)
|
||||
(let [{:keys [slow-base-fee normal-base-fee fast-base-fee
|
||||
current-base-fee max-priority-fee]}
|
||||
@@ -447,8 +447,8 @@
|
||||
tip-cap (money/to-hex max-priority-fee-bn)]
|
||||
{:db (-> db
|
||||
(update tx-entry assoc
|
||||
:maxFeePerGas fee-cap
|
||||
:maxPriorityFeePerGas tip-cap)
|
||||
:maxFeePerGas (or maxFeePerGas fee-cap)
|
||||
:maxPriorityFeePerGas (or maxPriorityFeePerGas tip-cap))
|
||||
(assoc :wallet/current-base-fee current-base-fee
|
||||
:wallet/normal-base-fee normal-base-fee
|
||||
:wallet/slow-base-fee slow-base-fee
|
||||
@@ -456,7 +456,7 @@
|
||||
:wallet/current-priority-fee max-priority-fee)
|
||||
(assoc-in [:signing/edit-fee :gas-price-loading?] false))})
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet/prepare-transaction :gasPrice] price)
|
||||
(assoc-in [:wallet/prepare-transaction :gasPrice] (or gasPrice price))
|
||||
(assoc-in [:signing/edit-fee :gas-price-loading?] false))}))
|
||||
|
||||
(fx/defn set-max-amount
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
(ns status-im.wallet.swap.core
|
||||
(:require [status-im.utils.fx :as fx]
|
||||
[re-frame.db :as re-frame.db]
|
||||
[status-im.navigation :as navigation]))
|
||||
|
||||
(fx/defn open-asset-selector-modal
|
||||
"source? true signinfies we are selecting the source asset. false implies selection of sink asset"
|
||||
{:events [::open-asset-selector-modal]}
|
||||
[{:keys [db]} source?]
|
||||
(fx/merge {:db (assoc db :wallet/modal-selecting-source-token? source?)}
|
||||
(navigation/open-modal :swap-asset-selector {})))
|
||||
|
||||
(fx/defn set-from-token
|
||||
{:events [::set-from-token]}
|
||||
[{:keys [db]} from-symbol]
|
||||
(fx/merge {:db (assoc db :wallet/swap-from-token from-symbol)}
|
||||
(navigation/navigate-back)))
|
||||
|
||||
(fx/defn set-to-token
|
||||
{:events [::set-to-token]}
|
||||
[{:keys [db]} to-symbol]
|
||||
(fx/merge {:db (assoc db :wallet/swap-to-token to-symbol)}
|
||||
(navigation/navigate-back)))
|
||||
|
||||
(fx/defn set-from-token-amount
|
||||
[{:keys [db]} from-amount]
|
||||
{:db (assoc db :wallet/swap-from-token-amount from-amount)})
|
||||
|
||||
(fx/defn set-max-from-token-amount
|
||||
[{:keys [db]} _]
|
||||
{:db (assoc db :wallet/swap-from-token-amount 0)})
|
||||
|
||||
(fx/defn switch-from-token-with-to
|
||||
{:events [::switch-from-token-with-to]}
|
||||
[{:keys [db]}]
|
||||
{:db (assoc db
|
||||
:wallet/swap-from-token (:wallet/swap-to-token db)
|
||||
:wallet/swap-to-token (:wallet/swap-from-token db))})
|
||||
|
||||
(fx/defn set-advanced-mode
|
||||
{:events [::set-advanced-mode]}
|
||||
[{:keys [db]} mode]
|
||||
{:db (assoc db :wallet/swap-advanced-mode? mode)})
|
||||
|
||||
(comment
|
||||
(->> re-frame.db/app-db
|
||||
deref
|
||||
:wallet/all-tokens
|
||||
vals
|
||||
(map #(str (:name %) "-" (:symbol %)))))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "v0.92.5",
|
||||
"commit-sha1": "64589fbd1f81022c7f995a7d993f0c026ecc6923",
|
||||
"src-sha256": "0d4zh9kmgi0vwgn1wsbjfnp7hiv2m0l1472wkjg23snskz2g5g14"
|
||||
"version": "v0.92.7",
|
||||
"commit-sha1": "f1569e4bde50e993611288a59b7a415a010cbfa8",
|
||||
"src-sha256": "12qj6p5m25z7ypgm9yxrg98lcc096sl2pwdks2iwlip585xsrc0h"
|
||||
}
|
||||
|
||||
@@ -42,11 +42,11 @@ rlp==1.2.0
|
||||
sauceclient==1.0.0
|
||||
scrypt==0.8.17
|
||||
selenium==3.14.1
|
||||
six==1.10.0
|
||||
six==1.11.0
|
||||
urllib3==1.26.3
|
||||
yarl==1.6.3
|
||||
zbarlight==3.0
|
||||
docker==4.4.0
|
||||
influxdb==5.3.1
|
||||
web3
|
||||
imagehash
|
||||
web3==5.25.0
|
||||
imagehash
|
||||
@@ -12,8 +12,9 @@ import support.api.web3_api as w3
|
||||
|
||||
class NetworkApi(object):
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.network_url = 'http://api-%s.etherscan.io/api?' % tests.pytest_config_global['network']
|
||||
self.network_url = 'http://api-ropsten.etherscan.io/api?'
|
||||
self.faucet_url = 'https://faucet-ropsten.status.im/donate'
|
||||
self.faucet_backup_address = w3.account_address
|
||||
self.headers = {
|
||||
@@ -179,13 +180,8 @@ class NetworkApi(object):
|
||||
return rounded_balance
|
||||
|
||||
def get_custom_fee_tx_params(self, hash: str):
|
||||
price_limit = int(w3.get_tx_param_by_hash(hash, 'maxFeePerGas'),16)/1000000000
|
||||
tip_limit = int(w3.get_tx_param_by_hash(hash, 'maxPriorityFeePerGas'),16)/1000000000
|
||||
gas_limit = w3.get_tx_param_by_hash(hash, 'gas')
|
||||
return {
|
||||
'fee_cap' : str(price_limit),
|
||||
'tip_cap': str(tip_limit),
|
||||
'gas_limit' : str(gas_limit)
|
||||
'fee_cap': str(w3.get_tx_param_by_hash(hash, 'maxFeePerGas')/1000000000),
|
||||
'tip_cap': str(w3.get_tx_param_by_hash(hash, 'maxPriorityFeePerGas')/1000000000),
|
||||
'gas_limit': str(w3.get_tx_param_by_hash(hash, 'gas'))
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -97,10 +97,11 @@ class TestrailReport(BaseTestReport):
|
||||
|
||||
def get_regression_cases(self):
|
||||
test_cases = dict()
|
||||
test_cases['critical'] = 734
|
||||
test_cases['high'] = 735
|
||||
test_cases['critical'] = 730
|
||||
test_cases['medium'] = 736
|
||||
test_cases['upgrade'] = 881
|
||||
test_cases['public_chat'] = 50654
|
||||
test_cases['one_to_one_chat'] = 50655
|
||||
case_ids = list()
|
||||
for arg in argv:
|
||||
if "run_testrail_ids" in arg:
|
||||
@@ -108,7 +109,7 @@ class TestrailReport(BaseTestReport):
|
||||
case_ids = value.split(',')
|
||||
if len(case_ids) == 0:
|
||||
if 'critical or high' in argv:
|
||||
for case in self.get_cases([test_cases['critical'], test_cases['high']]):
|
||||
for case in self.get_cases([test_cases['critical'], test_cases['public_chat'], test_cases['one_to_one_chat']]):
|
||||
case_ids.append(case['id'])
|
||||
elif 'upgrade' in argv and 'not upgrade' not in argv:
|
||||
for case in self.get_cases([test_cases['upgrade']]):
|
||||
|
||||
@@ -96,12 +96,13 @@ class TestCreateAccount(SingleDeviceTestCase):
|
||||
sign_in.get_started_button.click()
|
||||
if sign_in.generate_key_button.is_element_displayed():
|
||||
self.errors.append("Agree with ToS is not mandatory to proceed onboarding!")
|
||||
sign_in.accept_tos_checkbox.click()
|
||||
sign_in.accept_tos_checkbox.enable()
|
||||
sign_in.get_started_button.click_until_presence_of_element(sign_in.generate_key_button)
|
||||
sign_in.generate_key_button.click()
|
||||
from views.sign_in_view import MultiAccountButton
|
||||
account_button = sign_in.get_multiaccount_by_position(position=random.randint(1, 4),
|
||||
element_class=MultiAccountButton)
|
||||
pub_chat = 'status'
|
||||
username = account_button.username.text
|
||||
account_button.click()
|
||||
sign_in.next_button.click()
|
||||
@@ -111,21 +112,18 @@ class TestCreateAccount(SingleDeviceTestCase):
|
||||
sign_in.next_button.click()
|
||||
[element.wait_and_click(10) for element in (sign_in.maybe_later_button, sign_in.lets_go_button)]
|
||||
home = sign_in.get_home_view()
|
||||
texts = ["chat-and-transact", "follow-your-interests"]
|
||||
texts = ["chat-and-transact", "invite-friends"]
|
||||
for text in texts:
|
||||
if not home.element_by_translation_id(text).is_element_displayed():
|
||||
self.errors.append("'%s' text is not shown" % self.get_translation_by_key(text))
|
||||
for chat in ('#status', '#crypto'):
|
||||
sign_in.element_by_text(chat).click()
|
||||
sign_in.back_button.click_until_presence_of_element(home.search_input)
|
||||
home.join_public_chat(pub_chat)
|
||||
profile = home.profile_button.click()
|
||||
shown_username = profile.default_username_text.text
|
||||
if shown_username != username:
|
||||
self.errors.append("Default username '%s' doesn't match '%s'" % (shown_username, username))
|
||||
profile.home_button.click_until_presence_of_element(home.element_by_text('#status'))
|
||||
profile.home_button.double_click()
|
||||
home.cross_icon_inside_welcome_screen_button.click()
|
||||
for chat in ('#status', '#crypto'):
|
||||
home.delete_chat_long_press(chat)
|
||||
home.delete_chat_long_press('#%s' % pub_chat)
|
||||
if home.element_by_text(texts[0]).is_element_displayed():
|
||||
self.errors.append("'%s' text is shown, but welcome view was closed" % texts[0])
|
||||
home.relogin()
|
||||
@@ -141,7 +139,7 @@ class TestCreateAccount(SingleDeviceTestCase):
|
||||
@marks.high
|
||||
def test_pass_phrase_validation(self):
|
||||
sign_in = SignInView(self.driver)
|
||||
sign_in.accept_tos_checkbox.click()
|
||||
sign_in.accept_tos_checkbox.enable()
|
||||
sign_in.get_started_button.click_until_presence_of_element(sign_in.access_key_button)
|
||||
sign_in.access_key_button.click()
|
||||
validations = [
|
||||
@@ -219,7 +217,7 @@ class TestCreateAccount(SingleDeviceTestCase):
|
||||
@marks.medium
|
||||
def test_create_account_short_and_mismatch_password(self):
|
||||
sign_in = SignInView(self.driver)
|
||||
sign_in.accept_tos_checkbox.click()
|
||||
sign_in.accept_tos_checkbox.enable()
|
||||
sign_in.get_started_button.click()
|
||||
sign_in.generate_key_button.click()
|
||||
sign_in.next_button.click()
|
||||
|
||||
@@ -179,7 +179,7 @@ class TestCreateAccount(SingleDeviceTestCase):
|
||||
sign_in = SignInView(self.driver)
|
||||
|
||||
sign_in.just_fyi('Cancel on PIN code setup stage')
|
||||
sign_in.accept_tos_checkbox.click()
|
||||
sign_in.accept_tos_checkbox.enable()
|
||||
sign_in.get_started_button.click()
|
||||
sign_in.generate_key_button.click()
|
||||
username = sign_in.first_username_on_choose_chat_name.text
|
||||
@@ -232,7 +232,7 @@ class TestCreateAccount(SingleDeviceTestCase):
|
||||
@marks.flaky
|
||||
def test_keycard_interruption_access_key_onboarding_flow(self):
|
||||
sign_in = SignInView(self.driver)
|
||||
sign_in.accept_tos_checkbox.click()
|
||||
sign_in.accept_tos_checkbox.enable()
|
||||
sign_in.get_started_button.click()
|
||||
|
||||
sign_in.access_key_button.click()
|
||||
@@ -277,7 +277,7 @@ class TestCreateAccount(SingleDeviceTestCase):
|
||||
recovered_user = transaction_senders['A']
|
||||
|
||||
sign_in.just_fyi('Recover multiaccount')
|
||||
sign_in.accept_tos_checkbox.click()
|
||||
sign_in.accept_tos_checkbox.enable()
|
||||
sign_in.get_started_button.click_until_presence_of_element(sign_in.access_key_button)
|
||||
sign_in.access_key_button.click()
|
||||
sign_in.recover_with_keycard_button.click()
|
||||
@@ -324,7 +324,7 @@ class TestCreateAccount(SingleDeviceTestCase):
|
||||
sign_in.toggle_airplane_mode()
|
||||
|
||||
sign_in.just_fyi('Recover multiaccount offline')
|
||||
sign_in.accept_tos_checkbox.click()
|
||||
sign_in.accept_tos_checkbox.enable()
|
||||
sign_in.get_started_button.click_until_presence_of_element(sign_in.access_key_button)
|
||||
sign_in.access_key_button.click()
|
||||
sign_in.recover_with_keycard_button.click()
|
||||
@@ -489,8 +489,10 @@ class TestCreateAccount(SingleDeviceTestCase):
|
||||
profile.create_keycard_backup_button.scroll_and_click()
|
||||
sign_in.seedphrase_input.set_value(seed)
|
||||
sign_in.next_button.click()
|
||||
keycard.return_card_to_factory_settings_checkbox.enable()
|
||||
keycard.begin_setup_button.click()
|
||||
keycard.enter_another_pin()
|
||||
keycard.yes_button.wait_and_click()
|
||||
[keycard.enter_another_pin() for _ in range(2)]
|
||||
keycard.element_by_translation_id("keycard-backup-success-title").wait_for_element(30)
|
||||
keycard.ok_button.click()
|
||||
|
||||
@@ -673,7 +675,7 @@ class TestKeycardCreateMultiaccountMultipleDevice(MultipleDeviceTestCase):
|
||||
device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||
|
||||
device_1.just_fyi("Create keycard account and save seed phrase")
|
||||
device_1.accept_tos_checkbox.click()
|
||||
device_1.accept_tos_checkbox.enable()
|
||||
device_1.get_started_button.click()
|
||||
device_1.generate_key_button.click_until_presence_of_element(device_1.next_button)
|
||||
device_1.next_button.click_until_absense_of_element(device_1.element_by_translation_id("intro-wizard-title2"))
|
||||
|
||||
@@ -1219,7 +1219,6 @@ class TestProfileMultipleDevice(MultipleDeviceTestCase):
|
||||
|
||||
@marks.testrail_id(695856)
|
||||
@marks.medium
|
||||
@marks.flaky
|
||||
def test_pair_devices_sync_photo_community_group_chats(self):
|
||||
self.create_drivers(2)
|
||||
device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||
@@ -1238,11 +1237,12 @@ class TestProfileMultipleDevice(MultipleDeviceTestCase):
|
||||
|
||||
device_1.just_fyi('join Status community, create community, create group chat, edit user picture')
|
||||
# Follow Status community
|
||||
home_1.element_by_text(comm_joined_name).scroll_and_click()
|
||||
from views.chat_view import CommunityView
|
||||
comm_to_join_1 = CommunityView(self.drivers[0])
|
||||
comm_to_join_1.follow_button.wait_and_click()
|
||||
comm_to_join_1.home_button.double_click()
|
||||
# TODO: no predefined community to follow now
|
||||
# home_1.element_by_text(comm_joined_name).scroll_and_click()
|
||||
# from views.chat_view import CommunityView
|
||||
# comm_to_join_1 = CommunityView(self.drivers[0])
|
||||
# comm_to_join_1.follow_button.wait_and_click()
|
||||
# comm_to_join_1.home_button.double_click()
|
||||
# Create community as admin, add channel, send message
|
||||
comm_before_1 = home_1.create_community(comm_before_sync_name)
|
||||
channel_before_1 = comm_before_1.add_channel(channel)
|
||||
@@ -1271,9 +1271,10 @@ class TestProfileMultipleDevice(MultipleDeviceTestCase):
|
||||
|
||||
device_2.just_fyi('check that created/joined community and profile details are updated')
|
||||
home_2 = profile_2.home_button.click()
|
||||
for community in (comm_before_sync_name, comm_joined_name):
|
||||
if not home_2.get_chat(community, community=True).is_element_displayed():
|
||||
self.errors.append('Community %s was not appeared after initial sync' % community)
|
||||
# TODO: no predefined community to follow
|
||||
# for community in (comm_before_sync_name, comm_joined_name):
|
||||
if not home_2.get_chat(comm_before_sync_name, community=True).is_element_displayed():
|
||||
self.errors.append('Community %s was not appeared after initial sync' % comm_before_sync_name)
|
||||
comm_before_2 = home_2.get_chat(comm_before_sync_name, community=True).click()
|
||||
channel_2 = comm_before_2.get_chat(channel).click()
|
||||
if not channel_2.chat_element_by_text(message).is_element_displayed(30):
|
||||
@@ -1296,12 +1297,12 @@ class TestProfileMultipleDevice(MultipleDeviceTestCase):
|
||||
[home.home_button.double_click() for home in (home_1, home_2)]
|
||||
home_1.get_chat(comm_before_sync_name, community=True).click()
|
||||
comm_before_1.leave_community()
|
||||
if not home_2.get_chat(comm_before_sync_name).is_element_disappeared(30):
|
||||
if not home_2.element_by_text_part(comm_before_sync_name).is_element_disappeared(30):
|
||||
self.errors.append("Leaving community was not synced!")
|
||||
|
||||
device_1.just_fyi("Adding new community and check it will be synced")
|
||||
home_1.create_community(comm_after_sync_name)
|
||||
if not home_2.get_chat(comm_after_sync_name, community=True).is_element_displayed(30):
|
||||
if not home_2.element_by_text(comm_after_sync_name).is_element_displayed(30):
|
||||
self.errors.append('Added community was not appeared after initial sync')
|
||||
|
||||
# TODO: skip until #11558 (rechecked 23.11.21, valid)
|
||||
|
||||
@@ -91,6 +91,8 @@ class TestWalletManagement(SingleDeviceTestCase):
|
||||
@marks.testrail_id(5346)
|
||||
@marks.flaky
|
||||
@marks.high
|
||||
@marks.skip
|
||||
# TODO: skipped due to 13016
|
||||
def test_collectible_from_wallet(self):
|
||||
passphrase = wallet_users['F']['passphrase']
|
||||
home = SignInView(self.driver).recover_access(passphrase=passphrase)
|
||||
@@ -115,7 +117,7 @@ class TestWalletManagement(SingleDeviceTestCase):
|
||||
self.errors.append(
|
||||
'Wrong number is shown on CK assets: %s' % wallet.get_collectibles_amount().text)
|
||||
wallet.get_collectibles_amount().click()
|
||||
if not wallet.nft_asset_button.is_element_displayed():
|
||||
if not wallet.nft_asset_button.is_element_displayed(60):
|
||||
self.driver.fail("Kitty is not shown after opening it from collectibles!")
|
||||
wallet.nft_asset_button.click()
|
||||
wallet.set_collectible_as_profile_photo_button.scroll_and_click()
|
||||
@@ -168,7 +170,10 @@ class TestWalletManagement(SingleDeviceTestCase):
|
||||
self.errors.append('%s asset is not shown in wallet after relogin' % asset)
|
||||
|
||||
sign_in.just_fyi("Deselecting asset")
|
||||
wallet.select_asset(asset)
|
||||
wallet.multiaccount_more_options.click()
|
||||
wallet.manage_assets_button.click()
|
||||
wallet.asset_checkbox_by_name(asset).click()
|
||||
wallet.cross_icon.click()
|
||||
if wallet.asset_by_name(asset).is_element_displayed():
|
||||
self.errors.append('%s asset is shown in wallet but was deselected' % asset)
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
@@ -696,7 +696,6 @@ class TestChatManagementMultipleDevice(MultipleDeviceTestCase):
|
||||
|
||||
if public_chat_after_block_1.chat_element_by_text(message_after_block_2).is_element_displayed():
|
||||
self.errors.append("Message from blocked user '%s' is received" % device_2.driver.number)
|
||||
public_chat_after_block_1.get_back_to_home_view()
|
||||
if home_1.notifications_unread_badge.is_element_displayed():
|
||||
device_1.driver.fail("Unread badge is shown after receiving new message from blocked user")
|
||||
if blocked_chat_user.is_element_displayed():
|
||||
@@ -718,6 +717,7 @@ class TestChatManagementMultipleDevice(MultipleDeviceTestCase):
|
||||
device_1.click_system_home_button()
|
||||
self.drivers[0].launch_app()
|
||||
device_1.sign_in()
|
||||
public_chat_after_block_1.home_button.double_click()
|
||||
if home_1.notifications_unread_badge.is_element_displayed():
|
||||
device_1.driver.fail("Unread badge is shown after after fetching new messages from offline")
|
||||
if blocked_chat_user.is_element_displayed():
|
||||
@@ -986,10 +986,10 @@ class TestChatManagementMultipleDevice(MultipleDeviceTestCase):
|
||||
chat_1.get_back_to_home_view()
|
||||
home_1.add_contact(public_key=basic_user['public_key'])
|
||||
chat_1.chat_message_input.send_keys('@')
|
||||
if not (chat_1.search_user_in_mention_suggestion_list(ens_nickname_value).is_element_displayed() or
|
||||
if (chat_1.search_user_in_mention_suggestion_list(ens_nickname_value).is_element_displayed() or
|
||||
chat_1.search_user_in_mention_suggestion_list(
|
||||
sender['username']).is_element_displayed()):
|
||||
self.errors.append('ENS-owner user is not available in mention suggestion list')
|
||||
self.errors.append('ENS-owner user who is not in 1-1 chat is available in mention suggestion list')
|
||||
|
||||
device_1.just_fyi('Check there is no random user in different public chat')
|
||||
chat_1.get_back_to_home_view()
|
||||
|
||||
@@ -45,7 +45,7 @@ class TestCommandsMultipleDevices(MultipleDeviceTestCase):
|
||||
|
||||
chat_2 = home_2.get_chat(sender['username']).click()
|
||||
receiver_message = chat_2.get_incoming_transaction(account_name)
|
||||
timestamp_sender = sender_message.timestamp_message.text
|
||||
timestamp_sender = sender_message.timestamp_command_message.text
|
||||
if not receiver_message.is_element_displayed():
|
||||
self.drivers[0].fail('No message about incoming transaction in 1-1 chat is shown for receiver')
|
||||
receiver_message.transaction_status.wait_for_element_text(receiver_message.address_requested)
|
||||
@@ -68,7 +68,7 @@ class TestCommandsMultipleDevices(MultipleDeviceTestCase):
|
||||
send_bottom_sheet = sender_message.sign_and_send.click()
|
||||
send_bottom_sheet.next_button.click()
|
||||
send_bottom_sheet.sign_transaction()
|
||||
updated_timestamp_sender = sender_message.timestamp_message.text
|
||||
updated_timestamp_sender = sender_message.timestamp_command_message.text
|
||||
if updated_timestamp_sender == timestamp_sender:
|
||||
self.errors.append("Timestamp of message is not updated after signing transaction")
|
||||
chat_1.wallet_button.click()
|
||||
|
||||
@@ -81,7 +81,7 @@ class TestCommunitiesMultipleDevices(MultipleDeviceTestCase):
|
||||
def test_notification_in_activity_center_for_mention_in_community_and_group_chat(self):
|
||||
self.create_drivers(2)
|
||||
home_1, home_2 = SignInView(self.drivers[0]).create_user(), SignInView(self.drivers[1]).create_user()
|
||||
community_name, pub_chat_name, channel_name = "some name", home_1.get_random_chat_name(), "first_channel"
|
||||
community_name, gr_chat_name, channel_name = "some name", home_1.get_random_chat_name(), "first_channel"
|
||||
community_description = "something in community"
|
||||
message, message_member = "message", "from member"
|
||||
userkey_2, username_2 = home_2.get_public_key_and_username(return_username=True)
|
||||
@@ -102,9 +102,9 @@ class TestCommunitiesMultipleDevices(MultipleDeviceTestCase):
|
||||
one_to_one_2.home_button.click()
|
||||
community_1 = home_1.get_chat(community_name, community=True).click()
|
||||
community_link_text = community_1.copy_community_link()
|
||||
pub_1 = home_1.create_group_chat(user_names_to_add=[username_2], group_chat_name=pub_chat_name)
|
||||
pub_1 = home_1.create_group_chat(user_names_to_add=[username_2], group_chat_name=gr_chat_name)
|
||||
|
||||
pub_2 = home_2.get_chat(pub_chat_name).click()
|
||||
pub_2 = home_2.get_chat(gr_chat_name).click()
|
||||
pub_2.join_chat_button.click()
|
||||
pub_1.chat_message_input.paste_text_from_clipboard()
|
||||
pub_1.send_message_button.click()
|
||||
@@ -133,7 +133,7 @@ class TestCommunitiesMultipleDevices(MultipleDeviceTestCase):
|
||||
channel_2.send_message_button.click()
|
||||
community_1.home_button.double_click()
|
||||
channel_2.home_button.click()
|
||||
home_2.get_chat_from_home_view(pub_chat_name).click()
|
||||
home_2.get_chat_from_home_view(gr_chat_name).click()
|
||||
pub_2.select_mention_from_suggestion_list(username_1, username_1[:2])
|
||||
pub_2.send_as_keyevent("group")
|
||||
group_chat_message = username_1 + " group"
|
||||
@@ -161,7 +161,7 @@ class TestCommunitiesMultipleDevices(MultipleDeviceTestCase):
|
||||
|
||||
home_1.just_fyi("Check there are no unread messages counters on chats after message read")
|
||||
if (home_1.notifications_unread_badge.is_element_present() or
|
||||
home_1.get_chat_from_home_view(pub_chat_name).new_messages_counter.text == "1" or
|
||||
home_1.get_chat_from_home_view(gr_chat_name).new_messages_counter.text == "1" or
|
||||
home_1.get_chat_from_home_view(community_name).new_messages_counter.text == "1"):
|
||||
self.errors.append("Unread message indicator is kept after all messages read in chats")
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class TestCommandsMultipleDevices(MultipleDeviceTestCase):
|
||||
|
||||
chat_2 = home_2.get_chat(sender['username']).click()
|
||||
receiver_message = chat_2.get_incoming_transaction()
|
||||
timestamp_sender = sender_message.timestamp_message.text
|
||||
timestamp_sender = sender_message.timestamp_command_message.text
|
||||
if not receiver_message.is_element_displayed():
|
||||
self.drivers[0].fail('No message about incoming transaction in 1-1 chat is shown for receiver')
|
||||
receiver_message.transaction_status.wait_for_element_text(receiver_message.address_requested)
|
||||
@@ -63,7 +63,7 @@ class TestCommandsMultipleDevices(MultipleDeviceTestCase):
|
||||
send_message = sender_message.sign_and_send.click()
|
||||
send_message.next_button.click()
|
||||
send_message.sign_transaction(keycard=True)
|
||||
updated_timestamp_sender = sender_message.timestamp_message.text
|
||||
updated_timestamp_sender = sender_message.timestamp_command_message.text
|
||||
if updated_timestamp_sender == timestamp_sender:
|
||||
self.errors.append("Timestamp of message is not updated after signing transaction")
|
||||
|
||||
|
||||
@@ -109,8 +109,7 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
|
||||
|
||||
home_1.just_fyi('go back online and check that 1-1 chat will be fetched')
|
||||
home_1.toggle_airplane_mode()
|
||||
chat_element = home_1.get_chat(username_2)
|
||||
chat_element.wait_for_visibility_of_element(30)
|
||||
chat_element = home_1.get_chat(username_2, wait_time=60)
|
||||
chat_1 = chat_element.click()
|
||||
chat_1.chat_element_by_text(message_1).wait_for_visibility_of_element(2)
|
||||
|
||||
@@ -162,13 +161,14 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
|
||||
if device_2_chat.user_name_text.text != default_username_1:
|
||||
self.errors.append("Default username '%s' is not shown in one-to-one chat" % default_username_1)
|
||||
|
||||
profile_1.just_fyi("Check timestamps for sender and receiver")
|
||||
for chat in device_1_chat, device_2_chat:
|
||||
chat.verify_message_is_under_today_text(timestamp_message, self.errors)
|
||||
timestamp = chat.chat_element_by_text(timestamp_message).timestamp_message.text
|
||||
if timestamp not in sent_time_variants:
|
||||
self.errors.append(
|
||||
"Timestamp is not shown, expected '%s', in fact '%s'" % (sent_time_variants.join(","), timestamp))
|
||||
# TODO: disabled until https://github.com/status-im/status-react/issues/12936 fix
|
||||
# profile_1.just_fyi("Check timestamps for sender and receiver")
|
||||
# for chat in device_1_chat, device_2_chat:
|
||||
# chat.verify_message_is_under_today_text(timestamp_message, self.errors)
|
||||
# timestamp = chat.chat_element_by_text(timestamp_message).timestamp_message.text
|
||||
# if timestamp not in sent_time_variants:
|
||||
# self.errors.append(
|
||||
# "Timestamp is not shown, expected '%s', in fact '%s'" % (sent_time_variants.join(","), timestamp))
|
||||
|
||||
device_2_home.just_fyi("Add user to contact and verify his default username")
|
||||
device_2_chat.add_to_contacts.click()
|
||||
@@ -381,9 +381,8 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
|
||||
private_chat_2.chat_options.click()
|
||||
timeline_device_1 = private_chat_2.view_profile_button.click()
|
||||
for element in timeline_device_1.element_by_text(status_1), timeline_device_1.image_message_in_chat:
|
||||
element.scroll_to_element()
|
||||
if not element.is_element_displayed():
|
||||
self.drivers[0].fail('Status of another user not shown when open another user profile')
|
||||
if not element.is_element_displayed(40):
|
||||
self.errors.append('Status of another user not shown when open another user profile')
|
||||
private_chat_2.close_button.click()
|
||||
|
||||
home_2.just_fyi('check options on long-press image for receiver')
|
||||
@@ -411,6 +410,7 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
|
||||
self.errors.append("Image is not displayed in reply")
|
||||
|
||||
home_2.just_fyi('check share and save options on opened image')
|
||||
private_chat_2.image_message_in_chat.scroll_to_element(direction='up')
|
||||
private_chat_2.image_message_in_chat.click()
|
||||
private_chat_2.share_image_icon_button.click()
|
||||
private_chat_2.share_via_messenger()
|
||||
@@ -883,7 +883,7 @@ class TestMessagesOneToOneChatSingle(SingleDeviceTestCase):
|
||||
chat.send_message_button.click()
|
||||
|
||||
message_bubble = chat.chat_element_by_text(formatted_message[message])
|
||||
message_bubble.timestamp_message.long_press_element()
|
||||
message_bubble.sent_status_checkmark.long_press_element()
|
||||
chat.element_by_text('Copy').click()
|
||||
|
||||
message_input.paste_text_from_clipboard()
|
||||
@@ -964,13 +964,10 @@ class TestMessagesOneToOneChatSingle(SingleDeviceTestCase):
|
||||
self.errors.append('"%s" is not show in chat preview on home screen!' % message)
|
||||
home.get_chat('@%s' % ens).click()
|
||||
|
||||
home.just_fyi('Check redirect to user profile on mention by ENS tap')
|
||||
chat.chat_element_by_text(message).click()
|
||||
if not chat.profile_block_contact.is_element_displayed():
|
||||
self.errors.append('No redirect to user profile after tapping on message with mention (ENS) in 1-1 chat')
|
||||
|
||||
home.just_fyi('Set nickname and mention user by nickname in 1-1 chat')
|
||||
russian_nickname = 'МОЙ дорогой ДРУх'
|
||||
chat.chat_options.click()
|
||||
chat.view_profile_button.click()
|
||||
chat.set_nickname(russian_nickname)
|
||||
chat.select_mention_from_suggestion_list(russian_nickname + ' @' + ens)
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ from dateutil import parser
|
||||
from tests import marks
|
||||
from tests.base_test_case import MultipleDeviceTestCase, SingleDeviceTestCase, create_shared_drivers, \
|
||||
MultipleSharedDeviceTestCase
|
||||
from views.home_view import HomeView
|
||||
from views.sign_in_view import SignInView
|
||||
|
||||
|
||||
@@ -20,104 +19,102 @@ class TestPublicChatMultipleDeviceMerged(MultipleSharedDeviceTestCase):
|
||||
def setup_class(cls):
|
||||
cls.drivers, cls.loop = create_shared_drivers(2)
|
||||
device_1, device_2 = SignInView(cls.drivers[0]), SignInView(cls.drivers[1])
|
||||
home_1, home_2 = device_1.create_user(), device_2.create_user()
|
||||
profile_1 = home_1.profile_button.click()
|
||||
cls.home_1, cls.home_2 = device_1.create_user(), device_2.create_user()
|
||||
profile_1 = cls.home_1.profile_button.click()
|
||||
cls.username_1 = profile_1.default_username_text.text
|
||||
profile_1.home_button.click()
|
||||
home_2.home_button.click()
|
||||
cls.home_2.home_button.click()
|
||||
cls.public_chat_name = cls.home_1.get_random_chat_name()
|
||||
cls.chat_1, cls.chat_2 = cls.home_1.join_public_chat(cls.public_chat_name), cls.home_2.join_public_chat(cls.public_chat_name)
|
||||
|
||||
@marks.testrail_id(5313)
|
||||
@marks.critical
|
||||
def test_public_chat_messaging_emojis_timestamps(self):
|
||||
home_1, home_2 = HomeView(self.drivers[0]), HomeView(self.drivers[1])
|
||||
home_1.just_fyi("Check preselected chats, redirect to status chat")
|
||||
home_1.plus_button.click_until_presence_of_element(home_1.join_public_chat_button)
|
||||
home_1.join_public_chat_button.click()
|
||||
preselected_chats = ['#status', '#chitchat', '#defi', '#crypto', '#markets', '#dap-ps']
|
||||
for chat in preselected_chats:
|
||||
if not home_1.element_by_text(chat).is_element_displayed():
|
||||
self.errors.append("'%s' text is not in the list of preselected chats" % chat)
|
||||
home_1.element_by_text(preselected_chats[0]).click()
|
||||
status_chat = home_1.get_chat_view()
|
||||
if not status_chat.user_name_text != preselected_chats[0]:
|
||||
self.errors.append('No redirect to chat if tap on #status chat')
|
||||
status_chat.home_button.click()
|
||||
def test_public_chat_text_timestamps_while_on_different_tab(self):
|
||||
message = 'hello'
|
||||
self.chat_2.dapp_tab_button.click()
|
||||
self.chat_1.send_message(message)
|
||||
sent_time_variants = self.chat_1.convert_device_time_to_chat_timestamp()
|
||||
timestamp = self.chat_1.chat_element_by_text(message).timestamp_on_tap
|
||||
if timestamp not in sent_time_variants:
|
||||
self.errors.append("Timestamp is not shown, expected: '%s', in fact: '%s'" % (sent_time_variants.join(','), timestamp))
|
||||
self.chat_2.home_button.click(desired_view='chat')
|
||||
for chat in self.chat_1, self.chat_2:
|
||||
chat.verify_message_is_under_today_text(message, self.errors)
|
||||
if self.chat_2.chat_element_by_text(message).username.text != self.username_1:
|
||||
self.errors.append("Default username '%s' is not shown next to the received message" % self.username_1)
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
public_chat_name = home_1.get_random_chat_name()
|
||||
chat_1, chat_2 = home_1.join_public_chat(public_chat_name), home_2.join_public_chat(public_chat_name)
|
||||
|
||||
home_1.just_fyi("Check sending text messages, emojis, usernames and timestamps on messages")
|
||||
@marks.testrail_id(700719)
|
||||
@marks.critical
|
||||
def test_public_emoji(self):
|
||||
emoji_name = random.choice(list(emoji.EMOJI_UNICODE))
|
||||
emoji_unicode = emoji.EMOJI_UNICODE[emoji_name]
|
||||
message, emoji_message = 'hello', emoji.emojize(emoji_name)
|
||||
chat_1.send_message(message)
|
||||
|
||||
sent_time_variants = chat_1.convert_device_time_to_chat_timestamp()
|
||||
for chat in chat_1, chat_2:
|
||||
chat.verify_message_is_under_today_text(message, self.errors)
|
||||
timestamp = chat.chat_element_by_text(message).timestamp_message.text
|
||||
if timestamp not in sent_time_variants:
|
||||
self.errors.append(
|
||||
"Timestamp is not shown, expected '%s', in fact '%s'" % (sent_time_variants.join(','), timestamp))
|
||||
if chat_2.chat_element_by_text(message).username.text != self.username_1:
|
||||
self.errors.append("Default username '%s' is not shown next to the received message" % self.username_1)
|
||||
|
||||
chat_1.send_message(emoji_message)
|
||||
for chat in chat_1, chat_2:
|
||||
if not chat.chat_element_by_text(emoji_unicode).is_element_displayed():
|
||||
emoji_message = emoji.emojize(emoji_name)
|
||||
self.chat_1.send_message(emoji_message)
|
||||
for chat in self.chat_1, self.chat_2:
|
||||
if not chat.chat_element_by_text(emoji_unicode).is_element_displayed(30):
|
||||
self.errors.append('Message with emoji was not sent or received in public chat')
|
||||
|
||||
self.chat_1.just_fyi("Can copy and paste emojis")
|
||||
self.chat_1.element_by_text_part(emoji_unicode).long_press_element()
|
||||
self.chat_1.element_by_text('Copy').click()
|
||||
self.chat_1.chat_message_input.paste_text_from_clipboard()
|
||||
if self.chat_1.chat_message_input.text != emoji_unicode:
|
||||
self.errors.append('Emoji message was not copied')
|
||||
|
||||
self.chat_1.just_fyi("Can reply to emojis")
|
||||
self.chat_2.quote_message(emoji_unicode)
|
||||
message_text = 'test message'
|
||||
self.chat_2.chat_message_input.send_keys(message_text)
|
||||
self.chat_2.send_message_button.click()
|
||||
chat_element_1 = self.chat_1.chat_element_by_text(message_text)
|
||||
if not chat_element_1.is_element_displayed(sec=10) or chat_element_1.replied_message_text != emoji_unicode:
|
||||
self.errors.append('Reply message was not received by the sender')
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
@marks.testrail_id(5360)
|
||||
@marks.critical
|
||||
def test_unread_messages_counter_public_chat(self):
|
||||
home_1, home_2 = HomeView(self.drivers[0]), HomeView(self.drivers[1])
|
||||
home_1.get_back_to_home_view()
|
||||
home_2.get_back_to_home_view()
|
||||
home_1.home_button.click()
|
||||
home_2.home_button.click()
|
||||
chat_name = home_1.get_random_chat_name()
|
||||
chat_1, chat_2 = home_1.join_public_chat(chat_name), home_2.join_public_chat(chat_name)
|
||||
chat_1.send_message('пиу')
|
||||
chat_1.home_button.click()
|
||||
message, message_2 = 'test message', 'test message2'
|
||||
chat_2.send_message(message)
|
||||
|
||||
home_1.just_fyi(
|
||||
"Check unread message indicator on home, on chat element and that it is not shown after reading messages")
|
||||
if not home_1.home_button.public_unread_messages.is_element_displayed():
|
||||
def test_public_unread_messages_counter(self):
|
||||
self.chat_1.send_message('пиу')
|
||||
home_1 = self.chat_1.home_button.click()
|
||||
message = 'test message'
|
||||
self.chat_2.send_message(message)
|
||||
if not self.chat_1.home_button.public_unread_messages.is_element_displayed():
|
||||
self.errors.append('New messages public chat badge is not shown on Home button')
|
||||
chat_element = home_1.get_chat('#' + chat_name)
|
||||
chat_element = home_1.get_chat('#' + self.public_chat_name)
|
||||
if not chat_element.new_messages_public_chat.is_element_displayed():
|
||||
self.errors.append('New messages counter is not shown in public chat')
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
home_1.just_fyi("Check unread message counter when mentioned in public chat")
|
||||
chat_2 = home_2.get_chat_view()
|
||||
chat_2.select_mention_from_suggestion_list(self.username_1, self.username_1[:2])
|
||||
chat_2.send_message_button.click()
|
||||
@marks.testrail_id(700718)
|
||||
@marks.critical
|
||||
def test_public_unread_messages_counter_for_mentions_relogin(self):
|
||||
message = 'test message2'
|
||||
[chat.home_button.double_click() for chat in (self.chat_1, self.chat_2)]
|
||||
chat_element = self.home_1.get_chat('#' + self.public_chat_name)
|
||||
self.home_2.get_chat('#' + self.public_chat_name).click()
|
||||
self.chat_2.select_mention_from_suggestion_list(self.username_1, self.username_1[:2])
|
||||
self.chat_2.send_message_button.click()
|
||||
chat_element.new_messages_counter.wait_for_element(30)
|
||||
chat_element.new_messages_counter.wait_for_element_text("1", 60)
|
||||
|
||||
chat_element.click()
|
||||
home_1.home_button.double_click()
|
||||
|
||||
if home_1.home_button.public_unread_messages.is_element_displayed():
|
||||
self.home_1.home_button.double_click()
|
||||
if self.home_1.home_button.public_unread_messages.is_element_displayed():
|
||||
self.errors.append('New messages public chat badge is shown on Home button')
|
||||
if chat_element.new_messages_public_chat.is_element_displayed():
|
||||
self.errors.append('Unread messages badge is shown in public chat while there are no unread messages')
|
||||
[home.get_chat('#' + chat_name).click() for home in (home_1, home_2)]
|
||||
chat_1.send_message(message_2)
|
||||
chat_2.chat_element_by_text(message_2).wait_for_element(20)
|
||||
[home.get_chat('#' + self.public_chat_name).click() for home in (self.home_1, self.home_2)]
|
||||
self.chat_1.send_message(message)
|
||||
self.chat_2.chat_element_by_text(message).wait_for_element(20)
|
||||
|
||||
home_2.just_fyi("Check that unread message indicator is not reappeared after relogin")
|
||||
self.chat_2.just_fyi("Check that unread messages counter doesn't reappear after relogin")
|
||||
driver_2 = self.drivers[1]
|
||||
driver_2.close_app()
|
||||
driver_2.launch_app()
|
||||
SignInView(driver_2).sign_in()
|
||||
chat_element = home_2.get_chat('#' + chat_name)
|
||||
chat_element = self.home_2.get_chat('#' + self.public_chat_name)
|
||||
if chat_element.new_messages_public_chat.is_element_displayed():
|
||||
self.errors.append('New messages counter is shown after relogin')
|
||||
self.drivers[0].fail('New messages counter is shown after relogin')
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
|
||||
@@ -152,45 +149,6 @@ class TestPublicChatMultipleDevice(MultipleDeviceTestCase):
|
||||
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
@marks.testrail_id(6275)
|
||||
@marks.medium
|
||||
def test_receive_message_while_in_different_tab_and_emoji_messages_long_press(self):
|
||||
self.create_drivers(2)
|
||||
device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||
home_1, home_2 = device_1.create_user(), device_2.create_user()
|
||||
public_chat_name = home_1.get_random_chat_name()
|
||||
chat_1, chat_2 = home_1.join_public_chat(public_chat_name), home_2.join_public_chat(public_chat_name)
|
||||
|
||||
device_2.just_fyi("Switch to different tab out from chat")
|
||||
device_2.dapp_tab_button.click()
|
||||
emoji_name = random.choice(list(emoji.EMOJI_UNICODE))
|
||||
emoji_unicode = emoji.EMOJI_UNICODE[emoji_name]
|
||||
chat_1.chat_message_input.send_keys(emoji.emojize(emoji_name))
|
||||
chat_1.send_message_button.click()
|
||||
|
||||
device_1.just_fyi("Long press emoji message actions")
|
||||
chat_1.element_by_text_part(emoji_unicode).long_press_element()
|
||||
chat_1.element_by_text('Copy').click()
|
||||
chat_1.chat_message_input.paste_text_from_clipboard()
|
||||
if chat_1.chat_message_input.text != emoji_unicode:
|
||||
self.errors.append('Emoji message was not copied')
|
||||
|
||||
home_2.home_button.click(desired_view='chat')
|
||||
chat_element_2 = chat_2.element_by_text_part(emoji_unicode)
|
||||
if not chat_element_2.is_element_displayed(sec=10):
|
||||
self.errors.append('Message with emoji was not received in public chat by the recipient')
|
||||
|
||||
chat_2.quote_message(emoji_unicode)
|
||||
message_text = 'test message'
|
||||
chat_2.chat_message_input.send_keys(message_text)
|
||||
chat_2.send_message_button.click()
|
||||
|
||||
chat_element_1 = chat_1.chat_element_by_text(message_text)
|
||||
if not chat_element_1.is_element_displayed(sec=10) or chat_element_1.replied_message_text != emoji_unicode:
|
||||
self.errors.append('Reply message was not received by the sender')
|
||||
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
@marks.testrail_id(6342)
|
||||
@marks.medium
|
||||
def test_different_status_in_timeline(self):
|
||||
@@ -321,7 +279,7 @@ class TestPublicChatSingleDevice(SingleDeviceTestCase):
|
||||
quiet_time_yesterday, quiet_time_before_yesterday = '24 hours', '2 days'
|
||||
fetch_more = signin.get_translation_by_key("load-more-messages")
|
||||
for message in (yesterday, quiet_time_yesterday):
|
||||
if not chat.element_by_text_part(message).is_element_displayed():
|
||||
if not chat.element_by_text_part(message).is_element_displayed(120):
|
||||
self.driver.fail('"%s" is not shown' % message)
|
||||
chat.element_by_text_part(fetch_more).wait_and_click(120)
|
||||
chat.element_by_text_part(fetch_more).wait_for_visibility_of_element(180)
|
||||
|
||||
@@ -74,6 +74,8 @@ class TestDApps(SingleDeviceTestCase):
|
||||
|
||||
@marks.testrail_id(6232)
|
||||
@marks.medium
|
||||
@marks.flaky
|
||||
# TODO: due to 13011
|
||||
def test_switching_accounts_in_dapp(self):
|
||||
home = SignInView(self.driver).create_user()
|
||||
wallet = home.wallet_button.click()
|
||||
@@ -107,8 +109,6 @@ class TestDApps(SingleDeviceTestCase):
|
||||
|
||||
home.just_fyi('check that can change account')
|
||||
profile.dapp_tab_button.click()
|
||||
if profile.element_by_text("Can't find web3 library").is_element_displayed():
|
||||
status_test_dapp.browser_refresh_page_button.wait_and_click()
|
||||
if not status_test_dapp.element_by_text_part(account_name).is_element_displayed():
|
||||
self.errors.append("No expected account %s is shown in authorize web3 popup for wallet" % account_name)
|
||||
status_test_dapp.allow_button.click()
|
||||
|
||||
@@ -18,6 +18,7 @@ class TestTransactionDApp(SingleDeviceTestCase):
|
||||
status_test_dapp = home.open_status_test_dapp()
|
||||
status_test_dapp.wait_for_d_aap_to_load()
|
||||
status_test_dapp.assets_button.click()
|
||||
status_test_dapp.request_stt_button.wait_for_element(60)
|
||||
send_transaction = status_test_dapp.request_stt_button.click()
|
||||
if not send_transaction.onboarding_message.is_element_displayed(30):
|
||||
self.driver.fail('It seems onboarding screen is not shown.')
|
||||
|
||||
@@ -251,7 +251,7 @@ class TestTransactionWalletSingleDevice(SingleDeviceTestCase):
|
||||
amount=transaction_amount_1)
|
||||
wallet.close_button.click()
|
||||
sub_account_address = wallet.get_wallet_address(account_name)[2:]
|
||||
self.network_api.wait_for_confirmation_of_transaction(status_account_address, transaction_amount)
|
||||
self.network_api.wait_for_confirmation_of_transaction(status_account_address, transaction_amount_1)
|
||||
self.network_api.verify_balance_is_updated(updated_balance, status_account_address)
|
||||
wallet.find_transaction_in_history(amount=transaction_amount)
|
||||
wallet.find_transaction_in_history(amount=format(float(transaction_amount_1), '.11f').rstrip('0'))
|
||||
@@ -626,7 +626,7 @@ class TestTransactionWalletSingleDevice(SingleDeviceTestCase):
|
||||
@marks.transaction
|
||||
@marks.medium
|
||||
def test_custom_gas_settings(self):
|
||||
sender = wallet_users['A']
|
||||
sender = wallet_users['B']
|
||||
sign_in = SignInView(self.driver)
|
||||
sign_in.recover_access(sender['passphrase'])
|
||||
wallet = sign_in.wallet_button.click()
|
||||
@@ -663,7 +663,7 @@ class TestTransactionWalletSingleDevice(SingleDeviceTestCase):
|
||||
send_transaction.per_gas_price_limit_input:
|
||||
{
|
||||
'default': default_price,
|
||||
'value': '4,000000001',
|
||||
'value': str(round(float(default_price)+3, 9)),
|
||||
'-2': 'invalid-number',
|
||||
}
|
||||
}
|
||||
@@ -679,20 +679,19 @@ class TestTransactionWalletSingleDevice(SingleDeviceTestCase):
|
||||
|
||||
wallet.just_fyi("Set custom fee and check that it will be applied")
|
||||
send_transaction.save_fee_button.scroll_and_click()
|
||||
if send_transaction.get_network_fee_from_bottom_sheet() != '0.000088':
|
||||
self.driver.fail(
|
||||
"Custom fee is not applied, in fact it is %s " % send_transaction.get_network_fee_from_bottom_sheet())
|
||||
if wallet.element_by_translation_id("change-tip").is_element_displayed():
|
||||
wallet.element_by_translation_id("continue-anyway").click()
|
||||
send_transaction.sign_transaction()
|
||||
self.network_api.wait_for_confirmation_of_transaction(sender['address'], amount, confirmations=3)
|
||||
transaction = wallet.find_transaction_in_history(amount=amount, return_hash=True)
|
||||
expected_params = {
|
||||
'fee_cap': '4.000000001',
|
||||
'fee_cap': values[send_transaction.per_gas_price_limit_input]['value'],
|
||||
'tip_cap': '2.5',
|
||||
'gas_limit': '22000'
|
||||
}
|
||||
actual_params = self.network_api.get_custom_fee_tx_params(transaction)
|
||||
if actual_params != expected_params:
|
||||
self.errors.append('Real params %s for tx do not match expected ' % str(actual_params))
|
||||
self.errors.append('Real params %s for tx do not match expected %s' % (str(actual_params), str(expected_params)))
|
||||
|
||||
wallet.just_fyi('Verify custom fee data on tx screen')
|
||||
wallet.swipe_up()
|
||||
|
||||
@@ -91,6 +91,20 @@ class BaseElement(object):
|
||||
self.driver.info('Tap on found: %s' % self.name)
|
||||
return self.navigate()
|
||||
|
||||
def click_until_presence_of_element(self, desired_element, attempts=4):
|
||||
counter = 0
|
||||
self.driver.info("Click until '%s' by '%s': `%s` will be presented" % (
|
||||
desired_element.name, desired_element.by, desired_element.locator))
|
||||
while not desired_element.is_element_present(1) and counter <= attempts:
|
||||
try:
|
||||
self.find_element().click()
|
||||
desired_element.wait_for_element(5)
|
||||
return self.navigate()
|
||||
except (NoSuchElementException, TimeoutException):
|
||||
counter += 1
|
||||
else:
|
||||
self.driver.info("%s element not found" % desired_element.name)
|
||||
|
||||
def double_click(self):
|
||||
self.driver.info('Double tap on: %s' % self.name)
|
||||
[self.find_element().click() for _ in range(2)]
|
||||
@@ -352,19 +366,6 @@ class Button(BaseElement):
|
||||
self.wait_for_visibility_of_element(sec)
|
||||
self.click()
|
||||
|
||||
def click_until_presence_of_element(self, desired_element, attempts=4):
|
||||
counter = 0
|
||||
self.driver.info("Click until '%s' by '%s': `%s` will be presented" % (
|
||||
desired_element.name, desired_element.by, desired_element.locator))
|
||||
while not desired_element.is_element_present(1) and counter <= attempts:
|
||||
try:
|
||||
self.find_element().click()
|
||||
desired_element.wait_for_element(5)
|
||||
return self.navigate()
|
||||
except (NoSuchElementException, TimeoutException):
|
||||
counter += 1
|
||||
else:
|
||||
self.driver.info("%s element not found" % desired_element.name)
|
||||
|
||||
def click_until_absense_of_element(self, desired_element, attempts=3):
|
||||
counter = 0
|
||||
@@ -402,6 +403,21 @@ class SilentButton(Button):
|
||||
|
||||
|
||||
class CheckBox(Button):
|
||||
def click(self):
|
||||
super(CheckBox, self).click_until_presence_of_element(Button(self.driver, accessibility_id="checkbox-on"))
|
||||
def __init__(self, driver, **kwargs):
|
||||
super(Button, self).__init__(driver, **kwargs)
|
||||
|
||||
def __define_desired_element(self, elem_accessibility):
|
||||
desired_element_accessibility_id = elem_accessibility
|
||||
if self.accessibility_id is not None and ':' in self.accessibility_id:
|
||||
desired_element_accessibility_id = ':%s' % elem_accessibility
|
||||
return desired_element_accessibility_id
|
||||
|
||||
def enable(self):
|
||||
self.click_until_presence_of_element(Button(self.driver,
|
||||
accessibility_id=self.__define_desired_element("checkbox-on")))
|
||||
return self.navigate()
|
||||
|
||||
def disable(self):
|
||||
self.click_until_presence_of_element(Button(self.driver,
|
||||
accessibility_id=self.__define_desired_element("checkbox-off")))
|
||||
return self.navigate()
|
||||
|
||||
@@ -84,6 +84,7 @@ class HomeButton(TabButton):
|
||||
return self.navigate()
|
||||
|
||||
|
||||
|
||||
class DappTabButton(TabButton):
|
||||
def __init__(self, driver):
|
||||
super().__init__(driver, xpath="//*[contains(@content-desc,'tab, 2 out of 5')]")
|
||||
|
||||
@@ -143,13 +143,25 @@ class ChatElementByText(Text):
|
||||
return ''
|
||||
|
||||
@property
|
||||
def timestamp_message(self):
|
||||
class TimeStampText(Text):
|
||||
def timestamp_command_message(self):
|
||||
|
||||
class TimeStampText(Button):
|
||||
def __init__(self, driver, parent_locator: str):
|
||||
super().__init__(driver, xpath="(%s//android.widget.TextView)[last()]" % parent_locator)
|
||||
|
||||
return TimeStampText(self.driver, self.locator)
|
||||
|
||||
@property
|
||||
def timestamp_on_tap(self):
|
||||
timestamp_element = Text(self.driver, xpath="//*[@content-desc='message-timestamp']")
|
||||
try:
|
||||
self.sent_status_checkmark.wait_for_element(30)
|
||||
except NoSuchElementException:
|
||||
return ''
|
||||
self.sent_status_checkmark.click_until_presence_of_element(timestamp_element)
|
||||
return timestamp_element.text
|
||||
|
||||
|
||||
@property
|
||||
def member_photo(self):
|
||||
class MemberPhoto(Button):
|
||||
@@ -191,6 +203,10 @@ class ChatElementByText(Text):
|
||||
status = 'delivered'
|
||||
return status
|
||||
|
||||
@property
|
||||
def sent_status_checkmark(self) -> object:
|
||||
return Text(self.driver, prefix=self.locator, xpath="//*[@content-desc='sent']")
|
||||
|
||||
@property
|
||||
def replied_message_text(self):
|
||||
class RepliedMessageText(Text):
|
||||
|
||||