Compare commits

..
49 changed files with 933 additions and 1114 deletions
-2
View File
@@ -36,8 +36,6 @@ endif
export TMPDIR = /tmp/tmp-status-mobile-$(BUILD_TAG)
# This has to be specified for both the Node.JS server process and the Qt process.
export REACT_SERVER_PORT ?= 5001
# Fix for ERR_OSSL_EVP_UNSUPPORTED error.
export NODE_OPTIONS += --openssl-legacy-provider
# The path can be anything, but home is usually safest.
export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
+1 -1
View File
@@ -1 +1 @@
1.20.2
1.20.0
+18 -18
View File
@@ -8,8 +8,8 @@ GEM
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
aws-partitions (1.644.0)
aws-sdk-core (3.159.0)
aws-partitions (1.622.0)
aws-sdk-core (3.136.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.525.0)
aws-sigv4 (~> 1.1)
@@ -21,7 +21,7 @@ GEM
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
aws-sigv4 (1.5.2)
aws-sigv4 (1.5.1)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.1.0)
@@ -36,7 +36,7 @@ GEM
unf (>= 0.0.5, < 1.0.0)
dotenv (2.8.1)
emoji_regex (3.2.3)
excon (0.93.0)
excon (0.92.4)
faraday (1.10.2)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
@@ -66,7 +66,7 @@ GEM
faraday_middleware (1.2.0)
faraday (~> 1.0)
fastimage (2.2.6)
fastlane (2.210.1)
fastlane (2.209.1)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
@@ -109,9 +109,9 @@ GEM
fastlane-plugin-diawi (2.1.0)
rest-client (>= 2.0.0)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.29.0)
google-apis-core (>= 0.9.0, < 2.a)
google-apis-core (0.9.0)
google-apis-androidpublisher_v3 (0.25.0)
google-apis-core (>= 0.7, < 2.a)
google-apis-core (0.7.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
@@ -120,23 +120,23 @@ GEM
retriable (>= 2.0, < 4.a)
rexml
webrick
google-apis-iamcredentials_v1 (0.15.0)
google-apis-core (>= 0.9.0, < 2.a)
google-apis-playcustomapp_v1 (0.11.0)
google-apis-core (>= 0.9.0, < 2.a)
google-apis-storage_v1 (0.19.0)
google-apis-core (>= 0.9.0, < 2.a)
google-apis-iamcredentials_v1 (0.13.0)
google-apis-core (>= 0.7, < 2.a)
google-apis-playcustomapp_v1 (0.10.0)
google-apis-core (>= 0.7, < 2.a)
google-apis-storage_v1 (0.17.0)
google-apis-core (>= 0.7, < 2.a)
google-cloud-core (1.6.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.3.0)
google-cloud-storage (1.43.0)
google-cloud-errors (1.2.0)
google-cloud-storage (1.39.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.19.0)
google-apis-storage_v1 (~> 0.17.0)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
@@ -230,4 +230,4 @@ DEPENDENCIES
fastlane-plugin-diawi
BUNDLED WITH
2.3.20
2.3.9
+24 -24
View File
@@ -45,10 +45,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0x58gl654kcx65wyrix5swh5f9y431881a5mql8g3zwshd81fyb3";
sha256 = "1py4q91ll3v7ylcqflgd190y40d3ixgrhpln011gr5adgbzg9hr6";
type = "gem";
};
version = "1.644.0";
version = "1.622.0";
};
aws-sdk-core = {
dependencies = ["aws-eventstream" "aws-partitions" "aws-sigv4" "jmespath"];
@@ -56,10 +56,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0cdjmpblskjmhag7wx6scwkd3cw1gfh85syr599s05k8zp6y4qw8";
sha256 = "111zdfl6p1n949rvsfr0c88k9yzpibrcd8fihyshbibc2w06qj2b";
type = "gem";
};
version = "3.159.0";
version = "3.136.0";
};
aws-sdk-kms = {
dependencies = ["aws-sdk-core" "aws-sigv4"];
@@ -89,10 +89,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "11hkna2av47bl0yprgp8k4ya70rc3m2ib5w10fn0piplgkkmhz7m";
sha256 = "1d4bifmll4hrf4gihr5hdvn59wjpz4qpyg5jj95kp17fykzqg36n";
type = "gem";
};
version = "1.5.2";
version = "1.5.1";
};
babosa = {
groups = ["default"];
@@ -213,10 +213,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0b3rfqy87yiv9xmh260nyddxxjqj0vy32xvajvyn5jnjx96jwa24";
sha256 = "0cdc76kgr4f1mq4jwbmq1qvr9c15hb4r1cx4dvrdra13vy9sckb5";
type = "gem";
};
version = "0.93.0";
version = "0.92.4";
};
faraday = {
dependencies = ["faraday-em_http" "faraday-em_synchrony" "faraday-excon" "faraday-httpclient" "faraday-multipart" "faraday-net_http" "faraday-net_http_persistent" "faraday-patron" "faraday-rack" "faraday-retry" "ruby2_keywords"];
@@ -368,10 +368,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1wxzcs81c5ji30hrz64884rg0w56v2nwjyiyc8daka578bg7s8d6";
sha256 = "17m4nrpsjx2kadgy3qasis9d8rzajxgi9gzwkvdj7c0jjs6a768d";
type = "gem";
};
version = "2.210.1";
version = "2.209.1";
};
fastlane-plugin-clean_testflight_testers = {
groups = ["default"];
@@ -410,10 +410,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0z2i5wpkawkf4f42i55b1240iw8819wx828579s4vavhd9s17yik";
sha256 = "0psz3w8c95ashk5hlfvn5l32mg111z7fv07ngvvgm5mkw6wksh4d";
type = "gem";
};
version = "0.29.0";
version = "0.25.0";
};
google-apis-core = {
dependencies = ["addressable" "googleauth" "httpclient" "mini_mime" "representable" "retriable" "rexml" "webrick"];
@@ -421,10 +421,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1w9m4zc5xswz2h7gj4jvnb1ivzb6lcsl75fnw8ip7qz6hzwfgrlc";
sha256 = "07jhk74awjc1npf2rim4kmwz4v0n3ny6y5g31saq7aqxkjmlp3hd";
type = "gem";
};
version = "0.9.0";
version = "0.7.0";
};
google-apis-iamcredentials_v1 = {
dependencies = ["google-apis-core"];
@@ -432,10 +432,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "06smnmn2s460xl9x9rh07a3fkqdrjjy6azmx8iywggqgv2k5d8p9";
sha256 = "0mf9l1r28hxqqh2ilza2pfffy32vvzq10ifqf88a732k16iwvin1";
type = "gem";
};
version = "0.15.0";
version = "0.13.0";
};
google-apis-playcustomapp_v1 = {
dependencies = ["google-apis-core"];
@@ -443,10 +443,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "00nfh3xh51mbh02f8nqlsijdh59k9vjs5sglvpv09pl3wnhirf7w";
sha256 = "0jgmfayhww7sy06pzf8r7bvxjix4jdazbyyy4mhp6ghv1s9r85w7";
type = "gem";
};
version = "0.11.0";
version = "0.10.0";
};
google-apis-storage_v1 = {
dependencies = ["google-apis-core"];
@@ -454,10 +454,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "17qamcjnf22zvw1g169g8a2gkzdsxx4ij3a4ganihyrcf9r62asj";
sha256 = "19ccrdgb34w49l62p28yy5qrgwgb4wxs9q3mnb2d334q4q3wsk9f";
type = "gem";
};
version = "0.19.0";
version = "0.17.0";
};
google-cloud-core = {
dependencies = ["google-cloud-env" "google-cloud-errors"];
@@ -486,10 +486,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0jynh1s93nl8njm5l5wcy86pnjmv112cq6m0443s52f04hg6h2s5";
sha256 = "0nakfswnck6grjpyhckzl40qccyys3sy999h5axk0rldx96fnivd";
type = "gem";
};
version = "1.3.0";
version = "1.2.0";
};
google-cloud-storage = {
dependencies = ["addressable" "digest-crc" "google-apis-iamcredentials_v1" "google-apis-storage_v1" "google-cloud-core" "googleauth" "mini_mime"];
@@ -497,10 +497,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0j3hqyb4zgj6az6p0bz0kgskl6fddrwb095kxfbdx8r11m07mfr8";
sha256 = "030y55cybc5w538bdd2xxjqwfka8fnkhv7ld4iqmn7byrkgy9dxc";
type = "gem";
};
version = "1.43.0";
version = "1.39.0";
};
googleauth = {
dependencies = ["faraday" "jwt" "memoist" "multi_json" "os" "signet"];
-3
View File
@@ -72,9 +72,6 @@ in stdenv.mkDerivation rec {
ANDROID_SDK_ROOT = "${androidPkgs.sdk}";
ANDROID_NDK_ROOT = "${androidPkgs.ndk}";
# Fix for ERR_OSSL_EVP_UNSUPPORTED error.
NODE_OPTIONS = "--openssl-legacy-provider";
# Used by the Android Gradle build script in android/build.gradle
STATUS_GO_ANDROID_LIBDIR = status-go;
+3 -6
View File
@@ -4,10 +4,8 @@
let
inherit (lib) catAttrs unique;
# Sub-shells preparing various dependencies.
nodejs-sh = callPackage ./shells/nodejs.nix { };
bundler-sh = callPackage ./shells/bundler.nix { };
cocoapods-sh = callPackage ./shells/cocoapods.nix { };
cocoapods-sh = callPackage ./shells/pod.nix { };
status-go-sh = callPackage ./shells/status-go.nix { inherit status-go; };
in {
@@ -15,7 +13,7 @@ in {
shell = mkShell {
buildInputs = with pkgs; [
xcodeWrapper watchman procps
xcodeWrapper watchman bundler procps
flock # used in nix/scripts/node_modules.sh
];
@@ -23,8 +21,7 @@ in {
inputsFrom = [
fastlane.shell
cocoapods-sh
nodejs-sh # before 'pod install'
bundler-sh # before 'pod install'
nodejs-sh # before 'pod install'
status-go-sh # before 'pod install'
];
};
-8
View File
@@ -1,8 +0,0 @@
{ mkShell, bundler }:
mkShell {
buildInputs = [ bundler ];
shellHook = ''
bundle install --quiet --gemfile=fastlane/Gemfile
'';
}
+24
View File
@@ -0,0 +1,24 @@
{ mkShell, cocoapods }:
let
# source of what pod should install
podfileLock = "ios/Podfile.lock";
# current state of pods installed by pod
manifestLock = "ios/Pods/Manifest.lock";
in mkShell {
buildInputs = [ cocoapods ];
shellHook = ''
pushd "$STATUS_MOBILE_HOME" > /dev/null
{
echo "Checking for modifications in ios/Pods..."
if diff -q ${podfileLock} ${manifestLock}; then
echo "No modifications detected."
else
# CocoaPods are trash and can't handle other pod instances running
./scripts/wait-for.sh 240 'pod install'
(cd ios && pod install)
fi
}
popd > /dev/null
'';
}
+7 -8
View File
@@ -33,19 +33,18 @@ in {
gradlePropParser = callPackage ./tools/gradlePropParser.nix { };
# Package version adjustments
gradle = super.gradle_5;
nodejs = super.nodejs-16_x;
yarn = super.yarn.override { nodejs = super.nodejs-16_x; };
openjdk = super.openjdk8_headless;
gradle = super.pkgs.gradle_5;
nodejs = super.pkgs.nodejs-16_x;
openjdk = super.pkgs.openjdk8_headless;
xcodeWrapper = callPackage ./pkgs/xcodeenv/compose-xcodewrapper.nix { } {
version = "13.3";
allowHigher = true;
};
go = super.go_1_18;
buildGoPackage = super.buildGo118Package;
buildGoModule = super.buildGo118Module;
go = super.pkgs.go_1_17;
buildGoPackage = super.pkgs.buildGo117Package;
buildGoModule = super.pkgs.buildGo117Module;
gomobile = (super.gomobile.overrideAttrs (old: {
patches = self.fetchurl { # https://github.com/golang/mobile/pull/84
patches = self.pkgs.fetchurl { # https://github.com/golang/mobile/pull/84
url = "https://github.com/golang/mobile/commit/f20e966e05b8f7e06bed500fa0da81cf6ebca307.patch";
sha256 = "sha256-TZ/Yhe8gMRQUZFAs9G5/cf2b9QGtTHRSObBFD5Pbh7Y=";
};
+2 -2
View File
@@ -13,8 +13,8 @@ let
name = "nixpkgs-source";
owner = "NixOS";
repo = "nixpkgs";
rev = "579238da5f431b7833a9f0681663900aaf0dd1e8";
sha256 = "sha256-cDwASlAf/h0fsHtDm9yNBHEHK0uq6do+mIUEgh1i5yg=";
rev = "280d485b6f94d5ee8645aaf098c61a5def5df2be";
sha256 = "sha256-8ZWWJEDypkTCrzIWUxpin7CS2M3uPjjbl/8mpcVZQ9I";
# To get the compressed Nix sha256, use:
# nix-prefetch-url --unpack https://github.com/${ORG}/nixpkgs/archive/${REV}.tar.gz
};
+1 -1
View File
@@ -9,7 +9,7 @@
# by setting android_sdk.accept_license = true.
androidenv.composeAndroidPackages {
toolsVersion = "26.1.1";
platformToolsVersion = "33.0.2";
platformToolsVersion = "33.0.1";
buildToolsVersions = [ "31.0.0" ];
platformVersions = [ "31" ];
cmakeVersions = [ "3.18.1" ];
Binary file not shown.

Before

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 447 B

+17 -13
View File
@@ -6,8 +6,13 @@
[quo2.foundations.colors :as colors]
[quo2.components.markdown.text :as text]))
(defn- in?
"true if collection contains element"
[collection element]
(some #(= element %) collection))
(defn- get-button-color [type pressed? customization-color]
(if (#{:jump-to :mention} type)
(if (in? '(:jump-to :mention) type)
(if pressed?
(colors/custom-color-by-theme customization-color 60 50)
(colors/custom-color-by-theme customization-color 50 60))
@@ -16,7 +21,7 @@
(colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70))))
(defn- get-icon-and-text-color [type]
(if (#{:jump-to :mention} type)
(if (in? '(:jump-to :mention) type)
colors/white
(colors/theme-colors colors/white colors/neutral-100)))
@@ -52,7 +57,7 @@
:bottom 6)}}])
(defn dynamic-button
"[dynamic-button opts]
"[:dynamic-button opts]
opts
{:type :jump-to/:mention/:notification-down/:notification-up/:search/:search-with-label/:bottom
:on-press fn
@@ -60,20 +65,19 @@
:customization-color customize jump-to and mention button color}"
[_]
(let [pressed? (reagent/atom false)]
(fn [{:keys [type on-press count customization-color style]}]
(fn [{:keys [type on-press count customization-color]
:or {customization-color :primary}}]
[rn/touchable-without-feedback
{:on-press-in #(reset! pressed? true)
:on-press-out #(reset! pressed? false)
:on-press on-press}
[rn/view {:style (merge
{:flex-direction :row
:height 24
:border-radius 12
:background-color (get-button-color type @pressed? (or customization-color :primary))}
style)}
(when (#{:mention :search :search-with-label :bottom} type)
[rn/view {:style {:flex-direction :row
:height 24
:border-radius 12
:background-color (get-button-color type @pressed? customization-color)}}
(when (in? '(:mention :search :search-with-label :bottom) type)
[icon-view type])
(when (#{:jump-to :mention :notification-down :notification-up :search-with-label} type)
(when (in? '(:jump-to :mention :notification-down :notification-up :search-with-label) type)
[text/text {:weight :medium
:size :paragraph-2
:style {:color (get-icon-and-text-color type)
@@ -95,5 +99,5 @@
:jump-to (i18n/label :t/jump-to)
:search-with-label (i18n/label :t/back)
(:mention :notification-down :notification-up) (str count))])
(when (#{:jump-to :notification-down :notification-up} type)
(when (in? '(:jump-to :notification-down :notification-up) type)
[icon-view type])]])))
@@ -1,68 +0,0 @@
(ns quo2.components.drawers.action-drawers
(:require [status-im.ui.components.react :as react]
[quo.react-native :as rn]
[quo2.components.markdown.text :as text]
[quo2.components.icon :as icon]
[quo2.foundations.colors :as colors]))
(defn- get-icon-color [section]
(if (= section :bottom)
(colors/theme-colors colors/danger-50 colors/danger-60)
(colors/theme-colors colors/neutral-50 colors/neutral-40)))
(defn action [section]
(fn [{:keys [icon label sub-label right-icon on-press]}]
[rn/touchable-opacity {:on-press on-press}
[react/view {:style
{:flex 1
:height (if sub-label 56 47)
:margin-horizontal 20
:flex-direction :row}}
[react/view {:style
{:height 20
:margin-top :auto
:margin-bottom :auto
:margin-right 12
:width 20}}
[icon/icon icon
{:color (get-icon-color section)
:size 20}]]
[react/view
{:style
{:flex 1
:justify-content :center}}
[text/text
{:size :paragraph-1
:weight :medium
:style
{:color (when (= section :bottom)
(colors/theme-colors colors/danger-50 colors/danger-60))}}
label]
(when sub-label [text/text
{:size :paragraph-2
:style
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}}
sub-label])]
(when right-icon
[react/view {:style
{:height 20
:margin-top :auto
:margin-bottom :auto
:width 20}}
[icon/icon right-icon
{:color (get-icon-color section)
:size 20}]])]]))
(defn action-drawer [{:keys [actions actions-with-consequence]}]
[:<> {:style
{:flex 1}}
(map (action :top) actions)
(when actions-with-consequence
[:<>
[rn/view {:style {:border-top-width 1
:border-top-color (colors/theme-colors colors/neutral-10 colors/neutral-80)
:margin-top 8
:margin-bottom 7
:align-items :center
:flex-direction :row}}]
(map (action :bottom) actions-with-consequence)])])
@@ -1,35 +0,0 @@
(ns quo2.components.navigation.floating-shell-button
(:require [quo.react-native :as rn]
[quo2.components.buttons.dynamic-button :as dynamic-button]))
(defn dynamic-button-view [type dynamic-buttons style]
(when-let [{:keys [count on-press customization-color]} (get dynamic-buttons type)]
[dynamic-button/dynamic-button
{:type type
:on-press on-press
:count count
:style style
:customization-color customization-color}]))
(defn floating-shell-button
"[floating-shell-button dynamic-buttons style]
dynamic-buttons
{:button-type {:on-press on-press :count count}}"
[dynamic-buttons style]
[rn/view {:style (merge {:flex-direction :row
:margin-horizontal 12} style)}
;; Left Section
[rn/view {:style {:flex 1}}
[dynamic-button-view :search dynamic-buttons {:position :absolute
:right 8}]]
;; Mid Section (jump-to)
[dynamic-button-view :jump-to dynamic-buttons nil]
;; Right Section
[rn/view {:style {:flex 1}}
[rn/view {:style {:position :absolute
:flex-direction :row
:right 0}}
[dynamic-button-view :mention dynamic-buttons {:margin-left 8}]
[dynamic-button-view :notification-down dynamic-buttons {:margin-left 8}]
[dynamic-button-view :notification-up dynamic-buttons {:margin-left 8}]
[dynamic-button-view :bottom dynamic-buttons {:margin-left 8}]]]])
+21 -20
View File
@@ -3,7 +3,8 @@
[quo.react-native :as rn]
[quo.theme :as theme]
[quo2.components.markdown.text :as text]
[status-im.ui.components.icons.icons :as icons]))
[status-im.ui.components.icons.icons :as icons]
[quo2.components.tags.tag :as tag]))
(def themes {:light {:background-color colors/neutral-20}
:dark {:background-color colors/neutral-80}})
@@ -76,23 +77,23 @@
:or
{size :small border-color (colors/custom-color-by-theme :purple 50 60)}}]
[tag {:size size
:token-img-src token-img-src
:border-color (when is-required border-color)
:overlay
(when (or is-required is-purchasable)
[rn/view
{:style (merge icon-container-styles
{:width 15.5
:height 15.5
:background-color border-color
:border-color (if (= (theme/get-theme) :dark) colors/neutral-100 colors/white)
:border-width 1
:right (get-value-from-size size -3.75 -5.75)
:bottom (get-value-from-size size (- 32 7.75 4) (- 24 7.75 2)) ; (- height (icon-height/2) spacing)
})}
[icons/icon (if is-required :main-icons2/required-checkmark12 :main-icons2/purchasable12)
{:no-color true
:width 13.5
:height 13.5}]])}
[tag/tag {:size size
:token-img-src token-img-src
:border-color (when is-required border-color)
:overlay
(when (or is-required is-purchasable)
[rn/view
{:style (merge icon-container-styles
{:width 15.5
:height 15.5
:background-color border-color
:border-color (if (= (theme/get-theme) :dark) colors/neutral-100 colors/white)
:border-width 1
:right (get-value-from-size size -3.75 -5.75)
:bottom (get-value-from-size size (- 32 7.75 4) (- 24 7.75 2)) ; (- height (icon-height/2) spacing)
})}
[icons/icon (if is-required :main-icons2/required-checkmark12 :main-icons2/purchasable12)
{:no-color true
:width 13.5
:height 13.5}]])}
(str value " " token)]))
+1 -1
View File
@@ -27,7 +27,7 @@
:type :text}])
(defn cool-preview []
(let [state (reagent/atom {:count "5" :type :jump-to})]
(let [state (reagent/atom {:count 5 :type :jump-to})]
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:padding-bottom 150}
@@ -1,59 +0,0 @@
(ns quo2.screens.drawers.action-drawers
(:require [quo.previews.preview :as preview]
[quo.react-native :as rn]
[quo2.components.drawers.action-drawers :as quo2]
[quo2.components.buttons.button :as button]
[quo2.foundations.colors :as colors]
[status-im.utils.handlers :refer [>evt]]
[reagent.core :as reagent]))
(def descriptor [{:label "Muted?"
:key :muted?
:type :boolean}
{:label "Show red options?"
:key :show-red-options?
:type :boolean}])
(def options-with-consequences [{:icon :main-icons2/share-context
:label "Clear history"}])
(defn render-action-sheet [state]
[quo2/action-drawer {:actions-with-consequence (when (:show-red-options? @state) options-with-consequences)
:actions [{:icon :main-icons2/share-context
:label "View channel members and details"}
{:icon :main-icons2/communities
:label "Mark as read"}
{:icon :main-icons2/muted
:label (if (:muted? @state) "Unmute channel" "Mute channel")
:right-icon :main-icons2/chevron-right
:sub-label (when (:muted? @state) "Muted for 15 min")}
{:icon :main-icons2/scanner
:right-icon :main-icons2/chevron-right
:label "Fetch messages"}
{:icon :main-icons2/add-user
:label "Share link to the channel"}]}])
(defn cool-preview []
(let [state (reagent/atom {:muted? true
:show-red-options? true})]
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:padding-bottom 400}
[preview/customizer state descriptor]
[button/button
{:style {:margin-horizontal 40}
:on-press #(>evt [:bottom-sheet/show-sheet
{:content (constantly (render-action-sheet state))
:content-height 300}])}
"See in bottom sheet"]
[rn/view {:padding-vertical 60}
(render-action-sheet state)]]])))
(defn preview-action-drawers []
[rn/view {:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list {:flex 1
:nestedScrollEnabled true
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn (fn [_ index] (str "actions-drawers-" index))}]])
+1 -9
View File
@@ -18,7 +18,6 @@
[quo2.screens.community.community-card-view :as community-card]
[quo2.screens.dividers.divider-label :as divider-label]
[quo2.screens.dividers.new-messages :as new-messages]
[quo2.screens.drawers.action-drawers :as drawers]
[quo2.screens.dropdowns.dropdown :as dropdown]
[quo2.screens.info.info-message :as info-message]
[quo2.screens.info.information-box :as information-box]
@@ -35,7 +34,6 @@
[quo2.screens.switcher.switcher-cards :as switcher-cards]
[quo2.screens.navigation.top-nav :as top-nav]
[quo2.screens.navigation.bottom-nav-tab :as bottom-nav-tab]
[quo2.screens.navigation.floating-shell-button :as floating-shell-button]
[quo2.screens.tabs.account-selector :as account-selector]
[quo2.screens.tabs.segmented-tab :as segmented]
[quo2.screens.tabs.tabs :as tabs]
@@ -84,9 +82,6 @@
{:name :new-messages
:insets {:top false}
:component new-messages/preview-new-messages}]
:drawers [{:name :action-drawers
:insets {:top false}
:component drawers/preview-action-drawers}]
:dropdowns [{:name :dropdown
:insets {:top false}
:component dropdown/preview-dropdown}]
@@ -119,10 +114,7 @@
:component top-nav/preview-top-nav}
{:name :page-nav
:insets {:top false}
:component page-nav/preview-page-nav}
{:name :floating-shell-button
:insets {:top false}
:component floating-shell-button/preview-floating-shell-button}]
:component page-nav/preview-page-nav}]
:notifications [{:name :activity-logs
:insets {:top false}
:component activity-logs/preview-activity-logs}]
@@ -1,59 +0,0 @@
(ns quo2.screens.navigation.floating-shell-button
(:require [quo.react-native :as rn]
[quo.previews.preview :as preview]
[reagent.core :as reagent]
[quo2.components.navigation.floating-shell-button :as quo2]
[quo2.foundations.colors :as colors]))
(def descriptor [{:label "Show jump to?"
:key :show-jump-to?
:type :boolean}
{:label "Show search?"
:key :show-search?
:type :boolean}
{:label "Show mention?"
:key :show-mention?
:type :boolean}
{:label "Scroll Type"
:key :scroll-type
:type :select
:options [{:key :notification-up
:value "Notification Up"}
{:key :notification-down
:value "Notification Down"}
{:key :scroll-to-bottom
:value "Scroll To Bottom"}]}])
(defn mock-data [{:keys [show-jump-to? show-search? show-mention? scroll-type]}]
(cond-> {}
show-jump-to?
(assoc :jump-to {:on-press #()})
show-search?
(assoc :search {:on-press #()})
show-mention?
(assoc :mention {:on-press #() :count 6 :customization-color :turquoise})
(= scroll-type :notification-up)
(assoc :notification-up {:on-press #() :count 8})
(= scroll-type :notification-down)
(assoc :notification-down {:on-press #() :count 8})
(= scroll-type :scroll-to-bottom)
(assoc :bottom {:on-press #()})))
(defn cool-preview []
(let [state (reagent/atom {:show-jump-to? true
:scroll-type :notification-down})]
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:padding-bottom 150}
[preview/customizer state descriptor]
[rn/view {:padding-vertical 60
:align-items :center}
[quo2/floating-shell-button (mock-data @state)]]]])))
(defn preview-floating-shell-button []
[rn/view {:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list {:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
@@ -145,7 +145,6 @@
[rn/view {:flex 1}
[preview/customizer state descriptor]]
[rn/view {:padding-vertical 60
:align-self :center
:justify-content :center}
(when @state
(for [{:keys [tokens]} community-tokens]
+541 -8
View File
@@ -4,10 +4,488 @@
[status-im.data-store.activities :as data-store.activities]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.utils.fx :as fx]
[status-im.utils.datetime :as utils.datetime]
[taoensso.timbre :as log]))
;;;; Notification reconciliation
(def response-notifications
[{:replyMessage nil,
:read true,
:dismissed false,
:chatId
"0x047c654a4b35e4c3605c0eacf68364dd43140616e4d96ae362c4bf7c5ae3f1a3c03ad5935ae1face369bf96edda4ec02459b33964f1a7781036824f1e528c21b2f",
:name "0x047c65",
:accepted false,
:type 5,
:author
"0x047c654a4b35e4c3605c0eacf68364dd43140616e4d96ae362c4bf7c5ae3f1a3c03ad5935ae1face369bf96edda4ec02459b33964f1a7781036824f1e528c21b2f",
:lastMessage nil,
:id
"0x047c654a4b35e4c3605c0eacf68364dd43140616e4d96ae362c4bf7c5ae3f1a3c03ad5935ae1face369bf96edda4ec02459b33964f1a7781036824f1e528c21b2f20",
:timestamp 1665167287000,
:message
{:messageType 0,
:identicon
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAeElEQVR4nOzR0QnCMBhGURV3cR53cQx3cR6naRfoQ6EtXH7OeQwh5PI9bkMIqRFSI6RGSI2QGiE1QmqE1AipEVIzJuS59+L3/1u2zj+v9/2Mjxx9f8wiQmqE1AipEVIjpEZIjZAaIVxkzCJCaoTUCKkRUrMGAAD////ICGUlBQ5nAAAAAElFTkSuQmCC",
:replace "",
:chatId "",
:displayName "",
:lineCount 0,
:contactRequestState 2,
:whisperTimestamp 1665167287000,
:alias "Darkseagreen Colorless Honeybee",
:seen true,
:gapParameters {},
:from
"0x047c654a4b35e4c3605c0eacf68364dd43140616e4d96ae362c4bf7c5ae3f1a3c03ad5935ae1face369bf96edda4ec02459b33964f1a7781036824f1e528c21b2f",
:id
"0x047c654a4b35e4c3605c0eacf68364dd43140616e4d96ae362c4bf7c5ae3f1a3c03ad5935ae1face369bf96edda4ec02459b33964f1a7781036824f1e528c21b2f20",
:parsedText
[{:type "paragraph",
:children [{:literal "Please add me to your contacts"}]}],
:contentType 11,
:clock 0,
:localChatId "",
:timestamp 0,
:ensName "",
:quotedMessage nil,
:rtl false,
:responseTo "",
:text "Please add me to your contacts"}}
{:replyMessage nil,
:read true,
:dismissed false,
:chatId
"0x04892d0884fb44a940853ba988ce14b4c7c18351ea617bf29a5ceaa9eca03a8e1770f66282d9af9f5644578f8fcb8f4ff8fd926d8b389db4384ec91492aee8406d",
:name "0x04892d",
:accepted false,
:type 5,
:author
"0x04892d0884fb44a940853ba988ce14b4c7c18351ea617bf29a5ceaa9eca03a8e1770f66282d9af9f5644578f8fcb8f4ff8fd926d8b389db4384ec91492aee8406d",
:lastMessage nil,
:id
"0x04892d0884fb44a940853ba988ce14b4c7c18351ea617bf29a5ceaa9eca03a8e1770f66282d9af9f5644578f8fcb8f4ff8fd926d8b389db4384ec91492aee8406d20",
:timestamp 1665100538000,
:message
{:messageType 0,
:identicon
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzWUQmAYAwHcRW7GMwKxrCCwUyjBRSUMTj+3O/Rh0+Owdg0hDCExhAaQ2gMoYkJmbse3o/zevq+rcvY8b+YiRhCYwjN5w3SvYWq78dMxBAaQ2i8tWgMoTGExhAaQ2gMoSnfPW831V/VGyxmIobQGKImMRMxhMYQGkNoDKG5AwAA//9P5BRl2i6T5QAAAABJRU5ErkJggg==",
:replace "",
:chatId "",
:displayName "",
:lineCount 0,
:contactRequestState 2,
:whisperTimestamp 1665100538000,
:alias "Amused Neighboring Senegalpython",
:seen true,
:gapParameters {},
:from
"0x04892d0884fb44a940853ba988ce14b4c7c18351ea617bf29a5ceaa9eca03a8e1770f66282d9af9f5644578f8fcb8f4ff8fd926d8b389db4384ec91492aee8406d",
:id
"0x04892d0884fb44a940853ba988ce14b4c7c18351ea617bf29a5ceaa9eca03a8e1770f66282d9af9f5644578f8fcb8f4ff8fd926d8b389db4384ec91492aee8406d20",
:parsedText
[{:type "paragraph",
:children [{:literal "Please add me to your contacts"}]}],
:contentType 11,
:clock 0,
:localChatId "",
:timestamp 0,
:ensName "",
:quotedMessage nil,
:rtl false,
:responseTo "",
:text "Please add me to your contacts"}}
{:replyMessage nil,
:read true,
:dismissed false,
:chatId
"0x04d7b7648d9ef3cacdb64755d2fed9a70e4eb1e287e5f59c58cb3eda2485bdc0d0fb0f88f87dcd568637f2213205defee3fbd864bfe279bf87e43301a32647b88f",
:name "0x04d7b7",
:accepted false,
:type 5,
:author
"0x04d7b7648d9ef3cacdb64755d2fed9a70e4eb1e287e5f59c58cb3eda2485bdc0d0fb0f88f87dcd568637f2213205defee3fbd864bfe279bf87e43301a32647b88f",
:lastMessage nil,
:id
"0x04d7b7648d9ef3cacdb64755d2fed9a70e4eb1e287e5f59c58cb3eda2485bdc0d0fb0f88f87dcd568637f2213205defee3fbd864bfe279bf87e43301a32647b88f20",
:timestamp 1665097520000,
:message
{:messageType 0,
:identicon
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAgUlEQVR4nOzWwQmAMBAFURV7sRI7sgw7shKr0XtASMCF4TPvHALDXv4yhTCExhAaQ2gMoYkJWXsfnvf1jHx8bPtc+U8r5iKG0BhCYwiNITSG0HRvrS+jm+qvDdaKuYghNIaoSMxFDKExhMYQGkNoDKExhMYQGkNoDKExhOYNAAD//0iXEGcISwhOAAAAAElFTkSuQmCC",
:replace "",
:chatId "",
:displayName "",
:lineCount 0,
:contactRequestState 3,
:whisperTimestamp 1665097520000,
:alias "Honeydew Golden Amazondolphin",
:seen true,
:gapParameters {},
:from
"0x04d7b7648d9ef3cacdb64755d2fed9a70e4eb1e287e5f59c58cb3eda2485bdc0d0fb0f88f87dcd568637f2213205defee3fbd864bfe279bf87e43301a32647b88f",
:id
"0x04d7b7648d9ef3cacdb64755d2fed9a70e4eb1e287e5f59c58cb3eda2485bdc0d0fb0f88f87dcd568637f2213205defee3fbd864bfe279bf87e43301a32647b88f20",
:parsedText
[{:type "paragraph",
:children [{:literal "Please add me to your contacts"}]}],
:contentType 11,
:clock 0,
:localChatId "",
:timestamp 0,
:ensName "",
:quotedMessage nil,
:rtl false,
:responseTo "",
:text "Please add me to your contacts"}}
{:replyMessage nil,
:read true,
:dismissed false,
:chatId
"0x040185b964f42f2f11a07bb3275478605cf9f5a2f79af8a15d30baeaa9fe47e19d636d6461b797cfd2edf57a51e7be912c81e60698758bf145eaa611ae30f921df",
:name "0x040185",
:accepted false,
:type 5,
:author
"0x040185b964f42f2f11a07bb3275478605cf9f5a2f79af8a15d30baeaa9fe47e19d636d6461b797cfd2edf57a51e7be912c81e60698758bf145eaa611ae30f921df",
:lastMessage nil,
:id
"0x040185b964f42f2f11a07bb3275478605cf9f5a2f79af8a15d30baeaa9fe47e19d636d6461b797cfd2edf57a51e7be912c81e60698758bf145eaa611ae30f921df20",
:timestamp 1665097287000,
:message
{:messageType 0,
:identicon
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAfklEQVR4nOzYsQmAMABEURV3sXI7x3A7K6fRBSyEcPA5/istIp+DFFmmEobQGEJjCI0hNDUha+rg876er+/Hts+J/9UsYgiNITS/b5D0LTR6fs0ihtAYQmMIjSE0hiikZhFDaAyh8V2LxhAaQxRSs4ghNIbQGEJjCM0bAAD//5fvEGQwrcNWAAAAAElFTkSuQmCC",
:replace "",
:chatId "",
:displayName "",
:lineCount 0,
:contactRequestState 2,
:whisperTimestamp 1665097287000,
:alias "Quizzical Private Anteater",
:seen true,
:gapParameters {},
:from
"0x040185b964f42f2f11a07bb3275478605cf9f5a2f79af8a15d30baeaa9fe47e19d636d6461b797cfd2edf57a51e7be912c81e60698758bf145eaa611ae30f921df",
:id
"0x040185b964f42f2f11a07bb3275478605cf9f5a2f79af8a15d30baeaa9fe47e19d636d6461b797cfd2edf57a51e7be912c81e60698758bf145eaa611ae30f921df20",
:parsedText
[{:type "paragraph",
:children [{:literal "Please add me to your contacts"}]}],
:contentType 11,
:clock 0,
:localChatId "",
:timestamp 0,
:ensName "",
:quotedMessage nil,
:rtl false,
:responseTo "",
:text "Please add me to your contacts"}}
{:replyMessage nil,
:read true,
:dismissed false,
:chatId
"0x046bf5a02fd3a28f82f656bbfbfcaf9bec021b3617c3dc043dc8353f4f6f009ac53df5eba2a2ae63b6f77413a1ad9a054f5c4509ce68b4bf0e688186ab95d2fca7",
:name "0x046bf5",
:accepted false,
:type 5,
:author
"0x046bf5a02fd3a28f82f656bbfbfcaf9bec021b3617c3dc043dc8353f4f6f009ac53df5eba2a2ae63b6f77413a1ad9a054f5c4509ce68b4bf0e688186ab95d2fca7",
:lastMessage nil,
:id
"0x046bf5a02fd3a28f82f656bbfbfcaf9bec021b3617c3dc043dc8353f4f6f009ac53df5eba2a2ae63b6f77413a1ad9a054f5c4509ce68b4bf0e688186ab95d2fca720",
:timestamp 1665089696000,
:message
{:messageType 0,
:identicon
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAgklEQVR4nOzWQQpAYABEYeQu9s7mGM5m7zTsZaE09Zret5R+vab+TEMJQ2gMoTGExhCampA5dfB+Htfb821Zx8T3ahYxhMYQms+3VvoW+nt+zSKG0BiikJpFDKExhCb2r5V+/6lmEUNoDFFIzSKG0BhCYwiNITSG0BhCYwjNHQAA///zHxhnUGfT1gAAAABJRU5ErkJggg==",
:replace "",
:chatId "",
:displayName "",
:lineCount 0,
:contactRequestState 2,
:whisperTimestamp 1665089696000,
:alias "Growling Marvelous Parrot",
:seen true,
:gapParameters {},
:from
"0x046bf5a02fd3a28f82f656bbfbfcaf9bec021b3617c3dc043dc8353f4f6f009ac53df5eba2a2ae63b6f77413a1ad9a054f5c4509ce68b4bf0e688186ab95d2fca7",
:id
"0x046bf5a02fd3a28f82f656bbfbfcaf9bec021b3617c3dc043dc8353f4f6f009ac53df5eba2a2ae63b6f77413a1ad9a054f5c4509ce68b4bf0e688186ab95d2fca720",
:parsedText
[{:type "paragraph",
:children [{:literal "Please add me to your contacts"}]}],
:contentType 11,
:clock 0,
:localChatId "",
:timestamp 0,
:ensName "",
:quotedMessage nil,
:rtl false,
:responseTo "",
:text "Please add me to your contacts"}}
{:replyMessage nil,
:read true,
:dismissed false,
:chatId
"0x044a2e346d30266b1b0a05def37b91a1578ab5e420c6971da1bde04d125c40b40a3ea1fe9519398b3fb354986096700f5887b67bb82a93f6e3dd151edc633b8f67",
:name "0x044a2e",
:accepted false,
:type 5,
:author
"0x044a2e346d30266b1b0a05def37b91a1578ab5e420c6971da1bde04d125c40b40a3ea1fe9519398b3fb354986096700f5887b67bb82a93f6e3dd151edc633b8f67",
:lastMessage nil,
:id
"0x044a2e346d30266b1b0a05def37b91a1578ab5e420c6971da1bde04d125c40b40a3ea1fe9519398b3fb354986096700f5887b67bb82a93f6e3dd151edc633b8f6720",
:timestamp 1665075842000,
:message
{:messageType 0,
:identicon
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiUlEQVR4nOzWwQmEQBAF0V0xF2Pzbhjejc1oNIKRkR6h+NS7KxYNH6dfCENoDKExhMYQGkNoDKExhCYmZK6+4Dj3a8SHrMv2rzwfcxFDaAyhKS3Fk9aaVdepJeYihtAYQtO9IKP+qd7qXbmYixhCY4g+EnMRQ2gMoTGExhAaQ2gMoTGE5g4AAP//09cMY3Qm6ZsAAAAASUVORK5CYII=",
:replace "",
:chatId "",
:displayName "",
:lineCount 0,
:contactRequestState 2,
:whisperTimestamp 1665075842000,
:alias "Stable Sniveling Baldeagle",
:seen true,
:gapParameters {},
:from
"0x044a2e346d30266b1b0a05def37b91a1578ab5e420c6971da1bde04d125c40b40a3ea1fe9519398b3fb354986096700f5887b67bb82a93f6e3dd151edc633b8f67",
:id
"0x044a2e346d30266b1b0a05def37b91a1578ab5e420c6971da1bde04d125c40b40a3ea1fe9519398b3fb354986096700f5887b67bb82a93f6e3dd151edc633b8f6720",
:parsedText
[{:type "paragraph",
:children [{:literal "Please add me to your contacts"}]}],
:contentType 11,
:clock 0,
:localChatId "",
:timestamp 0,
:ensName "",
:quotedMessage nil,
:rtl false,
:responseTo "",
:text "Please add me to your contacts"}}
{:replyMessage nil,
:read true,
:dismissed false,
:chatId
"0x043e742bfa6dcd0c93689727ad02ac9e9d418f2a03a783b40d72bc8f0b3144707022ef84ae59a787977275c27ac9421ab094b8fb3908bb80f729f483eff38d84fc",
:name "0x043e74",
:accepted false,
:type 5,
:author
"0x043e742bfa6dcd0c93689727ad02ac9e9d418f2a03a783b40d72bc8f0b3144707022ef84ae59a787977275c27ac9421ab094b8fb3908bb80f729f483eff38d84fc",
:lastMessage nil,
:id
"0x043e742bfa6dcd0c93689727ad02ac9e9d418f2a03a783b40d72bc8f0b3144707022ef84ae59a787977275c27ac9421ab094b8fb3908bb80f729f483eff38d84fc20",
:timestamp 1665075615000,
:message
{:messageType 0,
:identicon
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAkklEQVR4nOzWwQnDMBAF0SSkl3SQylJGKksHqca+GwvWyGuGz7yzDho+CD1uIQyhMYTGEBpDaGJCntWD399/6b3Kvs/7da+ci1nEEBpD1CRmEUNoDKGZ/muN/kLd57diFjGExhCa8qt1VPW1OUvMIobQGEIz/bJc/acaiVnEEBpD1CRmEUNoDKExhMYQmjUAAP//o5AZOL4SLM8AAAAASUVORK5CYII=",
:replace "",
:chatId "",
:displayName "",
:lineCount 0,
:contactRequestState 2,
:whisperTimestamp 1665075615000,
:alias "Trusty Nautical Zethusspinipes",
:seen true,
:gapParameters {},
:from
"0x043e742bfa6dcd0c93689727ad02ac9e9d418f2a03a783b40d72bc8f0b3144707022ef84ae59a787977275c27ac9421ab094b8fb3908bb80f729f483eff38d84fc",
:id
"0x043e742bfa6dcd0c93689727ad02ac9e9d418f2a03a783b40d72bc8f0b3144707022ef84ae59a787977275c27ac9421ab094b8fb3908bb80f729f483eff38d84fc20",
:parsedText
[{:type "paragraph",
:children [{:literal "Please add me to your contacts"}]}],
:contentType 11,
:clock 0,
:localChatId "",
:timestamp 0,
:ensName "",
:quotedMessage nil,
:rtl false,
:responseTo "",
:text "Please add me to your contacts"}}
{:replyMessage nil,
:read true,
:dismissed false,
:chatId
"0x0435b461849c0af696b2f71ad95e9c57053722a2390c833b304b4284b00466f52f940004d45f0fee149cf6ed65b8ff856921d40059344a01e68b2fa9dae82e4900",
:name "0x0435b4",
:accepted false,
:type 5,
:author
"0x0435b461849c0af696b2f71ad95e9c57053722a2390c833b304b4284b00466f52f940004d45f0fee149cf6ed65b8ff856921d40059344a01e68b2fa9dae82e4900",
:lastMessage nil,
:id
"0x0435b461849c0af696b2f71ad95e9c57053722a2390c833b304b4284b00466f52f940004d45f0fee149cf6ed65b8ff856921d40059344a01e68b2fa9dae82e490020",
:timestamp 1665074686000,
:message
{:messageType 0,
:identicon
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAgUlEQVR4nOzWsQmAMBgFYRV3cTwbx7BxPKfRPigYJOR43FdKEI7X/NMQwhAaQ2gMoTGEJiZk/vrw2M/r6fu6LWOP96WYRQyhMUSNxCxiCI0hNL9vrTe1N1Xtf0oxixhCYwiNITSG0BiiRmIWMYTGEBpDaAyhMYTGEBpDaO4AAAD//5TbFGUr+nc/AAAAAElFTkSuQmCC",
:replace "",
:chatId "",
:displayName "",
:lineCount 0,
:contactRequestState 3,
:whisperTimestamp 1665074686000,
:alias "Remote Vapid Honeyeater",
:seen true,
:gapParameters {},
:from
"0x0435b461849c0af696b2f71ad95e9c57053722a2390c833b304b4284b00466f52f940004d45f0fee149cf6ed65b8ff856921d40059344a01e68b2fa9dae82e4900",
:id
"0x0435b461849c0af696b2f71ad95e9c57053722a2390c833b304b4284b00466f52f940004d45f0fee149cf6ed65b8ff856921d40059344a01e68b2fa9dae82e490020",
:parsedText
[{:type "paragraph",
:children [{:literal "Please add me to your contacts"}]}],
:contentType 11,
:clock 0,
:localChatId "",
:timestamp 0,
:ensName "",
:quotedMessage nil,
:rtl false,
:responseTo "",
:text "Please add me to your contacts"}}
{:replyMessage nil,
:read true,
:dismissed false,
:chatId
"0x04f18135a0d5e904d5a877c24ad286d227b1a91ee583d61f16ba71de801d9d92df330696c5788b0810999c4710271584ec84eac223bc5f7f9eaf483b0ed2bd2093",
:name "0x04f181",
:accepted false,
:type 5,
:author
"0x04f18135a0d5e904d5a877c24ad286d227b1a91ee583d61f16ba71de801d9d92df330696c5788b0810999c4710271584ec84eac223bc5f7f9eaf483b0ed2bd2093",
:lastMessage nil,
:id
"0x04f18135a0d5e904d5a877c24ad286d227b1a91ee583d61f16ba71de801d9d92df330696c5788b0810999c4710271584ec84eac223bc5f7f9eaf483b0ed2bd209320",
:timestamp 1665073831000,
:message
{:messageType 0,
:identicon
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAkElEQVR4nOzY0QmAMAwGYRV3cQI3cww3cwKn0QUUAm3h+LnvUYpwBELpMoUwhMYQGkNoDKGJCVlbf3Cd9/P1fT+2ucf5qpiJGEJjCE15U/xtm9Gq2yxmIobQGELTfNfqdadq3YoxEzGExhAaQ2gMoTGEZti7Vq/zVTETMYTGEA0SMxFDaAyhMYTGEJo3AAD//6aKGsYhz2MYAAAAAElFTkSuQmCC",
:replace "",
:chatId "",
:displayName "",
:lineCount 0,
:contactRequestState 2,
:whisperTimestamp 1665073831000,
:alias "Nippy Idolized Armyworm",
:seen true,
:gapParameters {},
:from
"0x04f18135a0d5e904d5a877c24ad286d227b1a91ee583d61f16ba71de801d9d92df330696c5788b0810999c4710271584ec84eac223bc5f7f9eaf483b0ed2bd2093",
:id
"0x04f18135a0d5e904d5a877c24ad286d227b1a91ee583d61f16ba71de801d9d92df330696c5788b0810999c4710271584ec84eac223bc5f7f9eaf483b0ed2bd209320",
:parsedText
[{:type "paragraph",
:children [{:literal "Please add me to your contacts"}]}],
:contentType 11,
:clock 0,
:localChatId "",
:timestamp 0,
:ensName "",
:quotedMessage nil,
:rtl false,
:responseTo "",
:text "Please add me to your contacts"}}
{:replyMessage nil,
:read true,
:dismissed false,
:chatId
"0x04b5aed12d7de0f72a7e3494b7d3ab20b316a9fde5732a3eb1d0f41a957900f764d725a3e725152c37bb615ab2251349ef84e92a145333d8ece9a598cae75681e7",
:name "0x04b5ae",
:accepted false,
:type 5,
:author
"0x04b5aed12d7de0f72a7e3494b7d3ab20b316a9fde5732a3eb1d0f41a957900f764d725a3e725152c37bb615ab2251349ef84e92a145333d8ece9a598cae75681e7",
:lastMessage nil,
:id
"0x04b5aed12d7de0f72a7e3494b7d3ab20b316a9fde5732a3eb1d0f41a957900f764d725a3e725152c37bb615ab2251349ef84e92a145333d8ece9a598cae75681e720",
:timestamp 1665064413000,
:message
{:messageType 0,
:identicon
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAm0lEQVR4nOzXsQnDMBBA0SRkl7QZLmNkOLeexm5cCcmcsIQ/x3+lUfM5OM6vRxKG0BhCYwiNITRpQt7Rh/912Wrff5/v8473pTQTMYTGEJrQRjjT2ja9otupJc1EDKExhGbardXLW+tgCI0hNOGt1TLqT/CqNBMxhMYQmiF3Us3s26yUZiKG0BiiSdJMxBAaQ2gMoTGEZg8AAP//9ecjm0YKWeEAAAAASUVORK5CYII=",
:replace "",
:chatId "",
:displayName "",
:lineCount 0,
:contactRequestState 2,
:whisperTimestamp 1665064413000,
:alias "Scary Quickwitted Wrasse",
:seen true,
:gapParameters {},
:from
"0x04b5aed12d7de0f72a7e3494b7d3ab20b316a9fde5732a3eb1d0f41a957900f764d725a3e725152c37bb615ab2251349ef84e92a145333d8ece9a598cae75681e7",
:id
"0x04b5aed12d7de0f72a7e3494b7d3ab20b316a9fde5732a3eb1d0f41a957900f764d725a3e725152c37bb615ab2251349ef84e92a145333d8ece9a598cae75681e720",
:parsedText
[{:type "paragraph",
:children [{:literal "Please add me to your contacts"}]}],
:contentType 11,
:clock 0,
:localChatId "",
:timestamp 0,
:ensName "",
:quotedMessage nil,
:rtl false,
:responseTo "",
:text "Please add me to your contacts"}}])
(def response-unread-notifications
[{:replyMessage nil,
:read false,
:dismissed false,
:chatId
"0x047c654a4b35e4c3605c0eacf68364dd43140616e4d96ae362c4bf7c5ae3f1a3c03ad5935ae1face369bf96edda4ec02459b33964f1a7781036824f1e528c21b2f",
:name "0x047c65",
:accepted false,
:type 5,
:author
"0x047c654a4b35e4c3605c0eacf68364dd43140616e4d96ae362c4bf7c5ae3f1a3c03ad5935ae1face369bf96edda4ec02459b33964f1a7781036824f1e528c21b2f",
:lastMessage nil,
:id
"0x047c654a4b35e4c3605c0eacf68364dd43140616e4d96ae362c4bf7c5ae3f1a3c03ad5935ae1face369bf96edda4ec02459b33964f1a7781036824f1e528c21b2f20",
:timestamp 1665167287000,
:message
{:messageType 0,
:identicon
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAeElEQVR4nOzR0QnCMBhGURV3cR53cQx3cR6naRfoQ6EtXH7OeQwh5PI9bkMIqRFSI6RGSI2QGiE1QmqE1AipEVIzJuS59+L3/1u2zj+v9/2Mjxx9f8wiQmqE1AipEVIjpEZIjZAaIVxkzCJCaoTUCKkRUrMGAAD////ICGUlBQ5nAAAAAElFTkSuQmCC",
:replace "",
:chatId "",
:displayName "",
:lineCount 0,
:contactRequestState 2,
:whisperTimestamp 1665167287000,
:alias "Darkseagreen Colorless Honeybee",
:seen true,
:gapParameters {},
:from
"0x047c654a4b35e4c3605c0eacf68364dd43140616e4d96ae362c4bf7c5ae3f1a3c03ad5935ae1face369bf96edda4ec02459b33964f1a7781036824f1e528c21b2f",
:id
"0x047c654a4b35e4c3605c0eacf68364dd43140616e4d96ae362c4bf7c5ae3f1a3c03ad5935ae1face369bf96edda4ec02459b33964f1a7781036824f1e528c21b2f20",
:parsedText
[{:type "paragraph",
:children [{:literal "Please add me to your contacts"}]}],
:contentType 11,
:clock 0,
:localChatId "",
:timestamp 0,
:ensName "",
:quotedMessage nil,
:rtl false,
:responseTo "",
:text "Please add me to your contacts"}}])
(defn- update-notifications
"Insert `new-notifications` in `db-notifications`.
@@ -76,20 +554,45 @@
(fx/defn notifications-fetch-first-page
{:events [:activity-center.notifications/fetch-first-page]}
[{:keys [db] :as cofx} {:keys [filter-type filter-status]}]
(tap> {:EVT-fetch-first-page (utils.datetime/now->iso8601)})
(let [filter-type (or filter-type
(get-in db [:activity-center :filter :type]
(defaults :filter-type)))
filter-status (or filter-status
(get-in db [:activity-center :filter :status]
(defaults :filter-status)))]
(fx/merge cofx
{:db (-> db
(assoc-in [:activity-center :filter :type] filter-type)
(assoc-in [:activity-center :filter :status] filter-status))}
(notifications-fetch {:cursor start-or-end-cursor
:filter-type filter-type
:filter-status filter-status
:reset-data? true}))))
(as-> {:db (-> db
(assoc-in [:activity-center :filter :type] filter-type)
(assoc-in [:activity-center :filter :status] filter-status)
(assoc-in [:activity-center :notifications filter-type filter-status :loading?] true)
;; Comment this assoc call and the UI becomes less
;; responsive. If you use the fake orange rectangles in the
;; UI you still notice the latency when this line is
;; commented. This is worrisome news.
(assoc-in [:activity-center :notifications filter-type filter-status :data] [])
)}
cofx'
(if (and (= 0 filter-type) (= :read filter-status))
(assoc cofx' :dispatch-later [;; Lower the delay and eventually the UI becomes less responsive.
{:ms 50
:dispatch [:activity-center.notifications/fetch-success
filter-type
filter-status
true
{:cursor "" :notifications response-notifications}]}])
(if (and (= 0 filter-type) (= :unread filter-status))
(assoc cofx' :dispatch-later [;; Lower the delay and eventually the UI becomes less responsive.
{:ms 50
:dispatch [:activity-center.notifications/fetch-success
filter-type
filter-status
true
{:cursor "" :notifications response-unread-notifications}]}])
(assoc cofx' :dispatch [:activity-center.notifications/fetch-success
filter-type
filter-status
true
{:cursor "" :notifications []}]))))))
(fx/defn notifications-fetch-next-page
{:events [:activity-center.notifications/fetch-next-page]}
@@ -97,6 +600,7 @@
(let [{:keys [type status]} (get-in db [:activity-center :filter])
{:keys [cursor]} (get-in db [:activity-center :notifications type status])]
(when (valid-cursor? cursor)
(tap> {:EVT-fetch-next-page (utils.datetime/now->iso8601)})
(notifications-fetch cofx {:cursor cursor
:filter-type type
:filter-status status
@@ -109,6 +613,7 @@
filter-status
reset-data?
{:keys [cursor notifications]}]
(tap> {:EVT-fetch-success (utils.datetime/now->iso8601)})
(let [processed (map data-store.activities/<-rpc notifications)]
{:db (-> db
(assoc-in [:activity-center :notifications filter-type filter-status :cursor] cursor)
@@ -123,3 +628,31 @@
[{:keys [db]} filter-type filter-status error]
(log/warn "Failed to load Activity Center notifications" error)
{:db (update-in db [:activity-center :notifications filter-type filter-status] dissoc :loading?)})
(fx/defn notifications-quick-toggle
{:events [:activity-center.notifications/quick-toggle]}
[{:keys [db]}]
{:db (assoc db :activity-center-notifications-filter-status
(if (= :read (:activity-center-notifications-filter-status db))
:unread
:read))})
(comment
(fx/defn notifications-quick-toggle
{:events [:activity-center.notifications/quick-toggle]}
[{:keys [db]}]
{:db (assoc-in db [:activity-center :filter :status]
(if (= :read (get-in db [:activity-center :filter :status]))
:unread
:read))})
(re-frame/reg-event-db
:dev/reset-activity-center
(fn [db]
(-> db
(assoc-in [:activity-center]
{:filter {:status :read
:type 0}
:notifications {}}))))
(re-frame/dispatch [:dev/reset-activity-center]))
+17 -27
View File
@@ -22,9 +22,7 @@
[status-im.bottom-sheet.core :as bottom-sheet]
[status-im.browser.webview-ref :as webview-ref]
["eth-phishing-detect" :as eth-phishing-detect]
[status-im.utils.debounce :as debounce]
[status-im.browser.eip3085 :as eip3085]
[status-im.browser.eip3326 :as eip3326]))
[status-im.utils.debounce :as debounce]))
(fx/defn update-browser-option
[{:keys [db]} option-key option-value]
@@ -347,7 +345,7 @@
constants/web3-eth-sign constants/web3-keycard-sign-typed-data} method))
(fx/defn web3-send-async
[cofx dapp-name {:keys [method params id] :as payload} message-id]
[cofx {:keys [method params id] :as payload} message-id]
(let [message? (web3-sign-message? method)
dapps-address (get-in cofx [:db :multiaccount :dapps-address])
typed? (and (not= constants/web3-personal-sign method) (not= constants/web3-eth-sign method))]
@@ -373,33 +371,25 @@
(dissoc :gasPrice))})
{:on-result [:browser.dapp/transaction-on-result message-id id]
:on-error [:browser.dapp/transaction-on-error message-id]}))))
(cond
(#{"eth_accounts" "eth_coinbase"} method)
(if (#{"eth_accounts" "eth_coinbase"} method)
(send-to-bridge cofx {:type constants/web3-send-async-callback
:messageId message-id
:result {:jsonrpc "2.0"
:id (int id)
:result (if (= method "eth_coinbase") dapps-address [dapps-address])}})
(= 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 %)}])}}
(= method "wallet_switchEthereumChain")
(eip3326/handle-switch-ethereum-chain cofx dapp-name id message-id (first params))
(= method "wallet_addEthereumChain")
(eip3085/handle-add-ethereum-chain cofx dapp-name id message-id (first params))
:else
{: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")
@@ -429,7 +419,7 @@
[{:keys [db] :as cofx} dapp-name {:keys [method] :as payload} message-id]
(if (has-permissions? db dapp-name method)
(handle-no-permissions cofx payload message-id)
(web3-send-async cofx dapp-name payload message-id)))
(web3-send-async cofx payload message-id)))
(fx/defn handle-scanned-qr-code
{:events [:browser.bridge.callback/qr-code-scanned]}
-69
View File
@@ -1,69 +0,0 @@
;reference https://eips.ethereum.org/EIPS/eip-3085 EIP-3085: Wallet Add Ethereum Chain RPC Method (`wallet_addEthereumChain`)
(ns status-im.browser.eip3085
(:require [status-im.constants :as constants]
[clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.utils.fx :as fx]
[status-im.network.core :as network]
[taoensso.timbre :as log]
[status-im.utils.random :as random]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.ui.screens.browser.eip3085.sheet :as sheet]))
(fx/defn send-success-call-to-bridge
{:events [:eip3085/send-success-call-to-bridge]}
[_ id messageId]
{:browser/send-to-bridge {:type constants/web3-send-async-callback
:messageId messageId
:result {:jsonrpc "2.0"
:id (int id)
:result nil}}})
(fx/defn allow-permission
{:events [:eip3085.ui/dapp-permission-allowed]}
[{:keys [db] :as cofx} message-id {:keys [new-networks id]}]
{:db (assoc db :networks/networks new-networks)
::json-rpc/call [{:method "settings_saveSetting"
:params [:networks/networks (vals new-networks)]
:on-success #(re-frame/dispatch [:eip3085/send-success-call-to-bridge cofx id message-id])
:on-error #(log/error "failed to perform settings_saveSetting" %)}]
:dispatch [:bottom-sheet/hide]})
(fx/defn deny-permission
{:events [:eip3085.ui/dapp-permission-denied]}
[_ message-id _]
{:browser/send-to-bridge {:type constants/web3-send-async-callback
:messageId message-id
:error {:code 4001
:message "User rejected the request."}}
:dispatch [:bottom-sheet/hide]})
(fx/defn handle-add-ethereum-chain
{:events [:eip3085/handle-add-ethereum-chain]}
[{{:networks/keys [networks] :as db} :db :as cofx}
dapp-name id message-id {:keys [chainId blockExplorerUrls chainName iconUrls nativeCurrency rpcUrls] :as params}]
(let [manage {:name {:value chainName}
:symbol {:value (:symbol nativeCurrency)}
:url {:value (first rpcUrls)}
:network-id {:value chainId}
:chain {:value :custom}}]
(if (network/valid-manage? manage)
(let [{:keys [name url chain network-id symbol]} manage
random-id (string/replace (random/id) "-" "")
network (network/new-network random-id
(:value name)
(:value symbol)
(:value url)
(:value chain)
(:value network-id))
new-networks (assoc networks random-id network)
params (assoc params :new-networks new-networks :id id :new-network network)]
(if (network/chain-id-available? networks network)
{:dispatch [:bottom-sheet/show-sheet {:content (fn []
[sheet/permissions-panel dapp-name message-id params])}]}
(send-success-call-to-bridge cofx id message-id)))
{:browser/send-to-bridge {:type constants/web3-send-async-callback
:messageId message-id
:error {:code -32602
:message "invalid network parameters"}}})))
-43
View File
@@ -1,43 +0,0 @@
;reference https://eips.ethereum.org/EIPS/eip-3326 EIP-3326: Wallet Switch Ethereum Chain RPC Method (`wallet_switchEthereumChain`)
(ns status-im.browser.eip3326
(:require [status-im.constants :as constants]
[status-im.utils.fx :as fx]
[status-im.ethereum.core :as ethereum]
[status-im.ui.screens.browser.eip3326.sheet :as sheet]))
(fx/defn deny-permission
{:events [:eip3326.ui/dapp-permission-denied]}
[{:keys [db] :as cofx} message-id _]
{:browser/send-to-bridge {:type constants/web3-send-async-callback
:messageId message-id
:error {:code 4001
:message "User rejected the request."}}
:dispatch [:bottom-sheet/hide]})
(fx/defn handle-switch-ethereum-chain
{:events [:eip3326/handle-switch-ethereum-chain]}
[{:keys [db] :as cofx} dapp-name id message-id {:keys [chainId] :as params}]
(let [target-chain-id (js/parseInt chainId 16)
networks (vals (get-in db [:networks/networks]))
exist-chain-ids (set (map ethereum/network->chain-id networks))
current-chain-id (ethereum/chain-id db)]
(if (exist-chain-ids target-chain-id)
(if (= current-chain-id target-chain-id)
{:browser/send-to-bridge {:type constants/web3-send-async-callback
:messageId message-id
:result {:jsonrpc "2.0"
:id (int id)
:result nil}}}
(let [target-network (first (filter #(= (ethereum/network->chain-id %1) target-chain-id) networks))
target-network-id (:id target-network)
current-network (ethereum/current-network db)
network-from (:name current-network)
network-to (:name target-network)
params (assoc params :target-network-id target-network-id :network-from network-from :network-to network-to)]
{:dispatch [:bottom-sheet/show-sheet {:content (fn []
[sheet/permissions-panel dapp-name message-id params])}]}))
{:browser/send-to-bridge {:type constants/web3-send-async-callback
:messageId message-id
:error {:code 4902
:message (str "Unrecognized chain ID: " target-chain-id ". Try adding the chain using wallet_addEthereumChain first.")}}})))
@@ -1,68 +0,0 @@
(ns status-im.chat.models.delete-message-for-me
(:require [re-frame.core :as re-frame]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.utils.datetime :as datetime]
[status-im.utils.fx :as fx]
[taoensso.timbre :as log]))
(defn- update-db-clear-undo-timer
[db chat-id message-id]
(when (get-in db [:messages chat-id message-id])
(update-in db
[:messages chat-id message-id]
dissoc
:deleted-for-me-undoable-till)))
(defn- update-db-delete-locally
"Delete message for me in re-frame db and set the undo timelimit"
[db chat-id message-id undo-time-limit-ms]
(when (get-in db [:messages chat-id message-id])
(update-in db
[:messages chat-id message-id]
assoc
:deleted-for-me? true
:deleted-for-me-undoable-till (+ (datetime/timestamp)
undo-time-limit-ms))))
(defn- update-db-undo-locally
"Restore deleted-for-me message if called within timelimit"
[db chat-id message-id]
(let [{:keys [deleted-for-me? deleted-for-me-undoable-till]}
(get-in db [:messages chat-id message-id])]
(if (and deleted-for-me?
(> deleted-for-me-undoable-till (datetime/timestamp)))
(update-in db
[:messages chat-id message-id]
dissoc
:deleted-for-me?
:deleted-for-me-undoable-till)
(update-db-clear-undo-timer db chat-id message-id))))
(fx/defn delete
"Delete message for me now locally and broadcast after undo time limit timeout"
{:events [:chat.ui/delete-message-for-me]}
[{:keys [db]} {:keys [chat-id message-id]} undo-time-limit-ms]
(when (get-in db [:messages chat-id message-id])
{:db (update-db-delete-locally db chat-id message-id undo-time-limit-ms)
:utils/dispatch-later [{:dispatch [:chat.ui/delete-message-for-me-and-sync
{:chat-id chat-id
:message-id message-id}]
:ms undo-time-limit-ms}]}))
(fx/defn undo
{:events [:chat.ui/undo-delete-message-for-me]}
[{:keys [db]} {:keys [chat-id message-id]}]
(when (get-in db [:messages chat-id message-id])
{:db (update-db-undo-locally db chat-id message-id)}))
(fx/defn delete-and-sync
{:events [:chat.ui/delete-message-for-me-and-sync]}
[{:keys [db]} {:keys [message-id chat-id]}]
(when (get-in db [:messages chat-id message-id])
{:db (update-db-clear-undo-timer db chat-id message-id)
::json-rpc/call [{:method "wakuext_deleteMessageForMeAndSync"
:params [chat-id message-id]
:js-response true
:on-error #(log/error "failed to delete message for me " %)
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response
%])}]}))
@@ -1,115 +0,0 @@
(ns status-im.chat.models.delete-message-for-me-test
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.chat.models.delete-message-for-me :as
delete-message-for-me]
[status-im.utils.datetime :as datetime]))
(defonce mid "message-id")
(defonce cid "chat-id")
(deftest delete-for-me
(let [db {:messages {cid {mid {:id mid}}}}
message {:message-id mid :chat-id cid}]
(testing "delete for me"
(let [expected {:db {:messages {"chat-id" {"message-id"
{:id "message-id"
:deleted-for-me? true}}}}
:utils/dispatch-later
[{:dispatch [:chat.ui/delete-message-for-me-and-sync
{:chat-id "chat-id" :message-id "message-id"}]
:ms 1000}]}
result (delete-message-for-me/delete {:db db} message 1000)
timestamp (+ (datetime/timestamp) 1000)]
(is (= (update-in result [:db :messages "chat-id" "message-id"] dissoc :deleted-for-me-undoable-till)
expected))
(is (-> (get-in result [:db :messages "chat-id" "message-id" :deleted-for-me-undoable-till])
(- timestamp)
js/Math.abs
(< 10)))))
(testing "should return nil if message in db"
(is (= (delete-message-for-me/delete {:db {:messages []}} message 1000)
nil)))))
(deftest undo-delete-for-me
(let [db {:messages {cid {mid {:id mid}}}}
message {:message-id mid :chat-id cid}]
(testing "undo delete for me in time"
(let [db (update-in db
[:messages cid mid]
assoc
:deleted-for-me? true
:deleted-for-me-undoable-till
(+ (datetime/timestamp) 1000))
expected {:db {:messages {"chat-id" {"message-id"
{:id "message-id"}}}}}]
(is (= (delete-message-for-me/undo {:db db} message) expected))))
(testing "remain deleted for me when undo delete for me late"
(let [db (update-in db
[:messages cid mid]
assoc
:deleted-for-me? true
:deleted-for-me-undoable-till (- (datetime/timestamp) 1000))
expected {:db {:messages {"chat-id" {"message-id"
{:id "message-id"
:deleted-for-me? true}}}}}]
(is (= (delete-message-for-me/undo {:db db} message) expected))))
(testing "remain deleted for me when undo delete for me late"
(let [db (update-in db
[:messages cid mid]
assoc
:deleted-for-me? true
:deleted-for-me-undoable-till (- (datetime/timestamp) 1000))
expected {:db {:messages {"chat-id" {"message-id"
{:id "message-id"
:deleted-for-me? true}}}}}]
(is (= (delete-message-for-me/undo {:db db} message) expected))))
(testing "should return nil if message in db"
(is (= (delete-message-for-me/undo {:db {:messages []}} message)
nil)))))
(deftest delete-for-me-and-sync
(let [db {:messages {cid {mid {:id mid}}}}
message {:message-id mid :chat-id cid}]
(testing "delete for me and sync"
(let [expected-db {:messages {"chat-id" {"message-id" {:id "message-id"}}}}
effects (delete-message-for-me/delete-and-sync {:db db} message)
result-db (:db effects)
rpc-calls (:status-im.ethereum.json-rpc/call effects)]
(is (= result-db expected-db))
(is (= (count rpc-calls) 1))
(is (= (-> rpc-calls
first
:method)
"wakuext_deleteMessageForMeAndSync"))
(is (= (-> rpc-calls
first
:params
count)
2))
(is (= (-> rpc-calls
first
:params
first)
cid))
(is (= (-> rpc-calls
first
:params
second)
mid))))
(testing "delete for me and sync, should clean undo timer"
(let [expected-db {:messages {"chat-id" {"message-id" {:id "message-id"}}}}
effects (delete-message-for-me/delete-and-sync
{:db (update-in db
[:messages cid mid
:deleted-for-me-undoable-till]
(constantly (datetime/timestamp)))}
message)
result-db (:db effects)]
(is (= result-db expected-db))))
(testing "should return nil if message in db"
(is (= (delete-message-for-me/delete-and-sync {:db {:messages []}}
message)
nil)))))
+6 -7
View File
@@ -185,7 +185,7 @@
[alias name nickname]))
(defn add-searchable-phrases-to-contact
[{:keys [alias name added? blocked? identicon public-key nickname ens-verified]} community-chat?]
[{:keys [alias name added? blocked? identicon public-key nickname]} community-chat?]
(when (and alias
(not (string/blank? alias))
(or name
@@ -194,12 +194,11 @@
community-chat?)
(not blocked?))
(add-searchable-phrases
{:alias alias
:name (or (and ens-verified (utils/safe-replace name ".stateofus.eth" "")) alias)
:identicon identicon
:nickname nickname
:ens-verified ens-verified
:public-key public-key})))
{:alias alias
:name (or (utils/safe-replace name ".stateofus.eth" "") alias)
:identicon identicon
:nickname nickname
:public-key public-key})))
(defn mentionable-contacts [contacts]
(reduce
+2 -9
View File
@@ -4,7 +4,6 @@
[status-im.data-store.pin-messages :as data-store.pin-messages]
[status-im.utils.fx :as fx]
[taoensso.timbre :as log]
[status-im.transport.message.protocol :as protocol]
[re-frame.core :as re-frame]))
(fx/defn handle-failed-loading-pin-messages
@@ -74,8 +73,7 @@
{:events [::send-pin-message]}
[{:keys [db] :as cofx} {:keys [chat-id message-id pinned] :as pin-message}]
(let [current-public-key (get-in db [:multiaccount :public-key])
message (merge pin-message {:pinned-by current-public-key})
preferred-name (get-in db [:multiaccount :preferred-name])]
message (merge pin-message {:pinned-by current-public-key})]
(fx/merge cofx
{:db (cond-> db
pinned
@@ -88,12 +86,7 @@
(update-in [:pin-messages chat-id] dissoc message-id)))}
(data-store.pin-messages/send-pin-message {:chat-id (pin-message :chat-id)
:message_id (pin-message :message-id)
:pinned (pin-message :pinned)})
(when pinned
(protocol/send-chat-messages [{:chat-id (pin-message :chat-id)
:content-type constants/content-type-pin
:response-to (pin-message :message-id)
:ens-name preferred-name}])))))
:pinned (pin-message :pinned)}))))
(fx/defn load-pin-messages
{:events [::load-pin-messages]}
-1
View File
@@ -14,7 +14,6 @@
(def ^:const content-type-community 9)
(def ^:const content-type-gap 10)
(def ^:const content-type-contact-request 11) ;; TODO: temp, will be removed
(def ^:const content-type-pin 13)
(def ^:const contact-request-state-none 0)
(def ^:const contact-request-state-mutual 1)
-1
View File
@@ -31,7 +31,6 @@
:quotedMessage :quoted-message
:outgoingStatus :outgoing-status
:audioDurationMs :audio-duration-ms
:deletedForMe :deleted-for-me?
:new :new?})
(update :quoted-message clojure.set/rename-keys {:parsedText :parsed-text :communityId :community-id})
+15 -1
View File
@@ -3,6 +3,7 @@
[status-im.utils.datetime :as datetime]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.constants :as constants]
[status-im.utils.datetime :as utils.datetime]
[clojure.string :as string]))
(re-frame/reg-sub
@@ -23,19 +24,32 @@
(fn [activity-center]
(get-in activity-center [:filter :type] constants/activity-center-notification-type-no-type)))
(re-frame/reg-sub
:activity-center/loading?
:<- [:activity-center/filter-type]
:<- [:activity-center/filter-status]
:<- [:activity-center/notifications]
(fn [[filter-type filter-status notifications]]
(get-in notifications [filter-type filter-status :loading?])))
(re-frame/reg-sub
:activity-center/filtered-notifications
:<- [:activity-center/filter-type]
:<- [:activity-center/filter-status]
:<- [:activity-center/notifications]
(fn [[filter-type filter-status notifications]]
(tap> {:SUB-filtered-notifications (utils.datetime/now->iso8601)})
(get-in notifications [filter-type filter-status :data])))
(re-frame/reg-sub
:activity-center/filter-status-unread-enabled?
:<- [:activity-center/filter-status]
(fn [filter-status]
(= :unread filter-status)))
(= :unread filter-status))
;; (fn [db]
;; (tap> {:SUB-filter-status-unread-enabled? (utils.datetime/now->iso8601)})
;; (= :read (:activity-center-notifications-filter-status db)))
)
(defn- group-notifications-by-date
[notifications]
@@ -92,30 +92,41 @@
(defn render-notification
[notification index]
(tap> {:render-notification (datetime/now->iso8601)})
[rn/view {:margin-top (if (= 0 index) 0 4)
:padding-horizontal 20}
[activity-pressable notification
[activity-logs/activity-log
(merge {:context (activity-context notification)
:icon (activity-icon notification)
:message (activity-message notification)
:status (activity-status notification)
:timestamp (datetime/timestamp->relative (:timestamp notification))
:title (activity-title notification)
:unread? (not (:read notification))}
(activity-buttons notification))]]])
;; Use this fake notification rectangle to see a massive rendering
;; performance difference.
(if true
[rn/view {:style {:width 100
:height 100
:background-color :orange
:padding-vertical 10}}]
[activity-pressable notification
[activity-logs/activity-log
(merge {:context (activity-context notification)
:icon (activity-icon notification)
:message (activity-message notification)
:status (activity-status notification)
:timestamp (datetime/timestamp->relative (:timestamp notification))
:title (activity-title notification)
:unread? (not (:read notification))}
(activity-buttons notification))]])])
(defn filter-selector-read-toggle
[]
(tap> {:filter-selector-read-toggle (datetime/now->iso8601)})
(let [unread-filter-enabled? (<sub [:activity-center/filter-status-unread-enabled?])]
;; TODO: Replace the button by a Filter Selector component once available for use.
[button/button {:icon true
:type (if unread-filter-enabled? :primary :outline)
:size 32
:on-press #(>evt [:activity-center.notifications/fetch-first-page
{:filter-status (if unread-filter-enabled?
:read
:unread)}])}
:on-press #(do
(tap> {:filter-selector-read-toggle-ON-PRESS (datetime/now->iso8601)})
(>evt [:activity-center.notifications/fetch-first-page
{:filter-status (if unread-filter-enabled?
:read
:unread)}]))}
:main-icons2/unread]))
;; TODO(2022-10-07): The empty state is still under design analysis, so we
@@ -140,6 +151,7 @@
(defn tabs
[]
(tap> {:tabs (datetime/now->iso8601)})
(let [filter-type (<sub [:activity-center/filter-type])]
[tabs/scrollable-tabs {:size 32
:style {:padding-left 20}
@@ -169,6 +181,7 @@
(defn header
[]
(tap> {:header (datetime/now->iso8601)})
(let [screen-padding 20]
;; TODO: Remove temporary (and old) background color when the screen and
;; header are properly blurred.
@@ -195,18 +208,33 @@
:padding-right screen-padding}
[filter-selector-read-toggle]]]]))
(defn loading-indicator
[]
(tap> {:loading-indicator (datetime/now->iso8601)})
(when (<sub [:activity-center/loading?])
[rn/view {:background-color :orange
:position :absolute
:top 0
:left 0
:width 100
:height 50}]))
(defn activity-center
[]
(reagent/create-class
{:component-did-mount #(>evt [:activity-center.notifications/fetch-first-page])
:reagent-render
(fn []
(tap> {:activity-center (datetime/now->iso8601)})
(let [notifications (<sub [:activity-center/filtered-notifications])]
[rn/flat-list {:content-container-style {:flex-grow 1}
:data notifications
:empty-component [empty-tab]
:header [header]
:key-fn :id
:on-end-reached #(>evt [:activity-center.notifications/fetch-next-page])
:render-fn render-notification
:sticky-header-indices [0]}]))}))
[:<>
[loading-indicator]
[rn/flat-list {:content-container-style {:flex-grow 1}
:data notifications
:empty-component [empty-tab]
:header [header]
:key-fn :id
;; Commented to simplify analysis.
;; :on-end-reached #(>evt [:activity-center.notifications/fetch-next-page])
:render-fn render-notification
:sticky-header-indices [0]}]]))}))
@@ -1,81 +0,0 @@
(ns status-im.ui.screens.browser.eip3085.sheet
(:require [re-frame.core :as re-frame]
[status-im.i18n.i18n :as i18n]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.react :as react]
[status-im.ui.screens.browser.styles :as styles]
[quo.design-system.colors :as colors]
[quo.core :as quo]
[status-im.ui.components.copyable-text :as copyable-text])
(:require-macros [status-im.utils.views :as views]))
(views/defview permissions-panel [dapp-name message-id params]
(views/letsubs [{:keys [dapp? dapp]} [:get-current-browser]]
[react/view {}
[react/view styles/permissions-panel-icons-container
(if dapp?
[chat-icon.screen/dapp-icon-permission dapp 40]
[react/view styles/permissions-panel-dapp-icon-container
[icons/icon :main-icons/dapp {:color colors/gray}]])
[react/view {:margin-left 8 :margin-right 4}
[react/view styles/dot]]
[react/view {:margin-right 4}
[react/view styles/dot]]
[react/view {:margin-right 8}
[react/view styles/dot]]
[react/view styles/permissions-panel-ok-icon-container
[icons/icon :tiny-icons/tiny-check styles/permissions-panel-ok-ico]]
[react/view {:margin-left 8 :margin-right 4}
[react/view styles/dot]]
[react/view {:margin-right 4}
[react/view styles/dot]]
[react/view {:margin-right 8}
[react/view styles/dot]]
[react/view styles/permissions-panel-wallet-icon-container
[icons/icon :main-icons/wallet {:color colors/white}]]]
[react/text {:style styles/permissions-panel-title-label :number-of-lines 2}
(str "\"" dapp-name "\" Allow this site to add a network?")]
[react/text {:style styles/permissions-panel-description-label :number-of-lines 4} "This will allow this network to be used within Status.Status does not verify custom networks.Learn about scams and network security risks."]
[react/scroll-view
[copyable-text/copyable-text-view
{:copied-text (:name (:new-network params))}
[quo/list-item
{:size :small
:accessibility-label :network-name
:title "Network Name"
:accessory :text
:accessory-text (:name (:new-network params))}]]
[copyable-text/copyable-text-view
{:copied-text (get-in params [:new-network :config :UpstreamConfig :URL])}
[quo/list-item
{:size :small
:accessibility-label :network-url
:title "Network URL"
:accessory :text
:accessory-text (get-in params [:new-network :config :UpstreamConfig :URL])}]]
[copyable-text/copyable-text-view
{:copied-text (str (get-in params [:new-network :config :NetworkId]))}
[quo/list-item
{:size :small
:accessibility-label :network-id
:title "Chain ID"
:accessory :text
:accessory-text (str (get-in params [:new-network :config :NetworkId]))}]]]
[react/view {:style {:flex-direction :row
:justify-content :center
:margin-horizontal 8
:margin-top 24}}
[react/view {:flex 1
:margin-horizontal 8}
[quo/button
{:theme :negative
:on-press #(re-frame/dispatch [:eip3085.ui/dapp-permission-denied message-id params])}
(i18n/label :t/deny)]]
[react/view {:flex 1
:margin-horizontal 8}
[quo/button
{:theme :positive
:style {:margin-horizontal 8}
:on-press #(re-frame/dispatch [:eip3085.ui/dapp-permission-allowed message-id params])}
(i18n/label :t/allow)]]]]))
@@ -1,58 +0,0 @@
(ns status-im.ui.screens.browser.eip3326.sheet
(:require [re-frame.core :as re-frame]
[status-im.i18n.i18n :as i18n]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.react :as react]
[status-im.ui.screens.browser.styles :as styles]
[status-im.utils.debounce :as debounce]
[status-im.network.core :as network]
[quo.design-system.colors :as colors]
[quo.core :as quo])
(:require-macros [status-im.utils.views :as views]))
(views/defview permissions-panel [dapp-name message-id {:keys [network-from network-to target-network-id] :as params}]
(views/letsubs [{:keys [dapp? dapp]} [:get-current-browser]]
[react/view {}
[react/view styles/permissions-panel-icons-container
(if dapp?
[chat-icon.screen/dapp-icon-permission dapp 40]
[react/view styles/permissions-panel-dapp-icon-container
[icons/icon :main-icons/dapp {:color colors/gray}]])
[react/view {:margin-left 8 :margin-right 4}
[react/view styles/dot]]
[react/view {:margin-right 4}
[react/view styles/dot]]
[react/view {:margin-right 8}
[react/view styles/dot]]
[react/view styles/permissions-panel-ok-icon-container
[icons/icon :tiny-icons/tiny-check styles/permissions-panel-ok-ico]]
[react/view {:margin-left 8 :margin-right 4}
[react/view styles/dot]]
[react/view {:margin-right 4}
[react/view styles/dot]]
[react/view {:margin-right 8}
[react/view styles/dot]]
[react/view styles/permissions-panel-wallet-icon-container
[icons/icon :main-icons/wallet {:color colors/white}]]]
[react/text {:style styles/permissions-panel-title-label :number-of-lines 2}
(str "\"" dapp-name "\" Allow this site to switch the network?")]
[react/text {:style styles/permissions-panel-description-label :number-of-lines 5}
(str "This will switch the selected network within Status to a previously added network:\n" network-from " -> " network-to "\nit will require login/logout")]
[react/view {:style {:flex-direction :row
:justify-content :center
:margin-horizontal 8
:margin-top 24}}
[react/view {:flex 1
:margin-horizontal 8}
[quo/button
{:theme :negative
:on-press #(re-frame/dispatch [:eip3326.ui/dapp-permission-denied message-id params])}
(i18n/label :t/deny)]]
[react/view {:flex 1
:margin-horizontal 8}
[quo/button
{:theme :positive
:style {:margin-horizontal 8}
:on-press #(debounce/dispatch-and-chill [::network/connect-network-pressed target-network-id] 1000)}
(i18n/label :t/allow)]]]]))
@@ -31,7 +31,7 @@
(defn edit-message []
[rn/view {:style {:flex-direction :row :height 24}}
[rn/view {:style (styles/reply-content false)}
[rn/view {:style (styles/reply-content)}
[icons/icon :main-icons/edit-connector {:color (theme-colors quo2.colors/neutral-40 quo2.colors/neutral-60)
:container-style {:position :absolute :left 10 :bottom -4 :width 16 :height 16}}]
[rn/view {:style {:position :absolute :left 36 :right 54 :top 3 :flex-direction :row :align-items :center}}
@@ -6,10 +6,9 @@
[quo.platform :as platform]
[quo.components.text :as text]
[quo.design-system.colors :as colors]
[quo2.foundations.colors :as quo2.colors]
[status-im.ui.screens.chat.components.style :as styles]
[status-im.utils.fx :as fx]
[status-im.utils.handlers :refer [<sub >evt]]
[status-im.utils.handlers :refer [<sub]]
[status-im.ui.screens.chat.components.reply :as reply]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.chat.constants :as chat.constants]
@@ -218,23 +217,16 @@
as arguments and returns new fx. Always clear all validation messages."
{:events [:chat.ui.input/set-chat-input-text]}
[{:keys [db] :as cofx} text chat-id]
(let [text-with-mentions (mentions/->input-field text)
all-contacts (:contacts/contacts db)
chat (get-in db [:chats chat-id])
current-multiaccount (:multiaccount db)
mentionable-users (mentions/get-mentionable-users
chat all-contacts current-multiaccount nil)
hydrated-mentions (map
(fn [[t mention :as e]]
(if (= t :mention)
(let [mention (multiaccounts/displayed-name
(get mentionable-users mention))]
[:mention (if (string/starts-with? mention "@")
mention (str "@" mention))])
e)) text-with-mentions)
info (mentions/->info hydrated-mentions)
new-text (string/join (map second hydrated-mentions))]
{:set-input-text [chat-id new-text]
(let [text-with-mentions (mentions/->input-field text)
contacts (:contacts db)
hydrated-mentions (map (fn [[t mention :as e]]
(if (= t :mention)
[:mention (str "@" (multiaccounts/displayed-name
(or (get contacts mention)
{:public-key mention})))]
e)) text-with-mentions)
info (mentions/->info hydrated-mentions)]
{:set-input-text [chat-id text]
:db
(-> db
(assoc-in [:chats/cursor chat-id] (:mention-end info))
@@ -339,46 +331,47 @@
[idx item])
@(re-frame/subscribe [:chat/input-with-mentions]))]
^{:key (str idx "_" type "_" text)}
[rn/text (when (= type :mention) {:style {:color quo2.colors/primary-50}}) text])
[rn/text (when (= type :mention) {:style {:color "#0DA4C9"}})
text])
(get @input-texts chat-id))]))
(defn mention-item
[[public-key {:keys [alias name nickname] :as user}] _ _ text-input-ref]
(let [ens-name? (not= alias name)]
[rn/touchable-opacity
{:on-press #(re-frame/dispatch [:chat.ui/select-mention text-input-ref user])}
[list-item/list-item
(cond-> {:icon [photos/member-photo public-key]
:size :small
:text-size :small
:title
[text/text
{:weight :medium
:ellipsize-mode :tail
:number-of-lines 1
:size :small}
(if nickname
nickname
name)
(when nickname
[text/text
{:weight :regular
:color :secondary
:ellipsize-mode :tail
:size :small}
" "
(when ens-name?
"@")
name])]
:title-text-weight :medium
:on-press
(fn []
(re-frame/dispatch [:chat.ui/select-mention text-input-ref user]))}
[list-item/list-item
(cond-> {:icon [photos/member-photo public-key]
:size :small
:text-size :small
:title
[text/text
{:weight :medium
:ellipsize-mode :tail
:number-of-lines 1
:size :small}
(if nickname
nickname
name)
(when nickname
[text/text
{:weight :regular
:color :secondary
:ellipsize-mode :tail
:size :small}
" "
(when ens-name?
"@")
name])]
:title-text-weight :medium}
ens-name?
(assoc :subtitle alias))]]))
ens-name?
(assoc :subtitle alias))]))
(def chat-toolbar-height (reagent/atom nil))
(defn autocomplete-mentions-old [text-input-ref bottom]
(defn autocomplete-mentions [text-input-ref bottom]
(let [suggestions @(re-frame/subscribe [:chat/mention-suggestions])]
(when (seq suggestions)
(let [height (+ 16 (* 52 (min 4.5 (count suggestions))))]
@@ -396,22 +389,6 @@
:render-data text-input-ref
:render-fn mention-item}]]]))))
(defn autocomplete-mentions [suggestions]
[:f>
(fn []
(let [animation (reanimated/use-shared-value 0)]
(quo.react/effect! #(do
(reanimated/set-shared-value animation (reanimated/with-timing (if (seq suggestions) 0 200)))))
[reanimated/view {:style (reanimated/apply-animations-to-style
{:transform [{:translateY animation}]}
{:bottom 0 :position :absolute :z-index 5 :max-height 180})}
[list/flat-list
{:keyboardShouldPersistTaps :always
:data suggestions
:key-fn first
:render-fn mention-item
:content-container-style {:padding-bottom 12}}]]))])
(defn on-chat-toolbar-layout [^js ev]
(reset! chat-toolbar-height (-> ev .-nativeEvent .-layout .-height)))
@@ -498,21 +475,6 @@
(swap! context assoc :state :min)
min-y)))
(defn calculate-y-with-mentions [y max-y max-height chat-id suggestions reply]
(let [input-text (:input-text (get (<sub [:chat/inputs]) chat-id))
num-lines (count (string/split input-text "\n"))
text-height (* num-lines 22)
mentions-height (min 132 (+ 16 (* 46 (- (count suggestions) 1))))
should-translate (if (< (- max-height text-height) mentions-height) true false)
min-value (if-not reply mentions-height (+ mentions-height 44))
; translate value when mentions list appear while at bottom of expanded input sheet
mentions-translate-value (if should-translate (min min-value (- mentions-height (- max-height text-height))) mentions-height)]
(when (or (< y max-y) should-translate) mentions-translate-value)))
(defn get-y-value [context keyboard-shown min-y max-y added-value max-height chat-id suggestions reply]
(let [y (calculate-y context keyboard-shown min-y max-y added-value)]
y (+ y (when (seq suggestions) (calculate-y-with-mentions y max-y max-height chat-id suggestions reply)))))
(defn get-bottom-sheet-gesture [context translate-y text-input-ref keyboard-shown min-y max-y shared-height max-height bg-opacity]
(-> (gesture/gesture-pan)
(gesture/on-start
@@ -602,17 +564,18 @@
[:f>
(fn []
(let [reply (<sub [:chats/reply-message])
suggestions (<sub [:chat/mention-suggestions])
{window-height :height} (rn/use-window-dimensions)
{:keys [keyboard-shown keyboard-height]} (rn/use-keyboard)
max-y (- window-height (if (> keyboard-height 0) keyboard-height 360) (:top insets)) ; 360 - default height
max-height (- max-y 56 (:bottom insets)) ; 56 - top-bar height
added-value (if (and (not (seq suggestions)) reply) 38 0) ; increased height of input box needed when reply
min-y (+ min-y (when reply 38))
y (get-y-value context keyboard-shown min-y max-y added-value max-height chat-id suggestions reply)
added-value (if reply 38 0) ; increased height of input box needed when reply
min-y (+ min-y added-value)
y (calculate-y context keyboard-shown min-y max-y added-value)
translate-y (reanimated/use-shared-value 0)
shared-height (reanimated/use-shared-value min-y)
bg-opacity (reanimated/use-shared-value 0)
input-content-change (get-input-content-change context translate-y shared-height max-height
bg-opacity keyboard-shown min-y max-y)
bottom-sheet-gesture (get-bottom-sheet-gesture context translate-y (:text-input-ref refs) keyboard-shown
@@ -644,21 +607,19 @@
:refs refs
:set-active-panel #()}]]]]
;CONTROLS
(when-not (seq suggestions)
[rn/view {:style (styles/new-bottom-sheet-controls insets)}
[quo2.button/button {:icon true :type :outline :size 32} :main-icons2/image]
[rn/view {:width 12}]
[quo2.button/button {:icon true :type :outline :size 32} :main-icons2/reaction]
[rn/view {:flex 1}]
;;SEND button
[rn/view {:ref send-ref :style (when-not (seq (get @input-texts chat-id)) {:width 0 :right -100})}
[quo2.button/button {:icon true :size 32 :accessibility-label :send-message-button
:on-press #(do (swap! context assoc :clear true)
(clear-input chat-id refs)
(>evt [:chat.ui/send-current-message]))}
:main-icons2/arrow-up]]])
[rn/view {:style (styles/new-bottom-sheet-controls insets)}
[quo2.button/button {:icon true :type :outline :size 32} :main-icons2/image]
[rn/view {:width 12}]
[quo2.button/button {:icon true :type :outline :size 32} :main-icons2/reaction]
[rn/view {:flex 1}]
;;SEND button
[rn/view {:ref send-ref :style (when-not (seq (get @input-texts chat-id)) {:width 0 :right -100})}
[quo2.button/button {:icon true :size 32 :accessibility-label :send-message-button
:on-press #(do (swap! context assoc :clear true)
(clear-input chat-id refs)
(re-frame/dispatch [:chat.ui/send-current-message]))}
:main-icons2/arrow-up]]]
;black background
[reanimated/view {:style (reanimated/apply-animations-to-style
{:opacity bg-opacity}
(styles/new-bottom-sheet-background window-height))}]
[autocomplete-mentions suggestions]]))])))])
(styles/new-bottom-sheet-background window-height))}]]))])))])
@@ -81,16 +81,15 @@
[icons/icon :main-icons/close-circle {:container-style (styles/close-button)
:color (:icon-02 @quo.colors/theme)}]]]]))
; This component is also used for quoted pinned message as the UI is very similar
(defn reply-message [{:keys [from identicon content-type contentType parsed-text content]} in-chat-input? pin?]
(defn reply-message [{:keys [from identicon content-type contentType parsed-text content]} in-chat-input?]
(let [contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity from])
current-public-key @(re-frame/subscribe [:multiaccount/public-key])
content-type (or content-type contentType)]
[rn/view {:style {:flex-direction :row :height (when-not pin? 24)}}
[rn/view {:style (styles/reply-content pin?)}
(when-not pin? [icons/icon :main-icons/connector {:color (theme-colors quo2.colors/neutral-40 quo2.colors/neutral-60)
:container-style {:position :absolute :left 10 :bottom -4 :width 16 :height 16}}])
[rn/view {:style (styles/quoted-message pin?)}
[rn/view {:style {:flex-direction :row :height 24}}
[rn/view {:style (styles/reply-content)}
[icons/icon :main-icons/connector {:color (theme-colors quo2.colors/neutral-40 quo2.colors/neutral-60)
:container-style {:position :absolute :left 10 :bottom -4 :width 16 :height 16}}]
[rn/view {:style {:position :absolute :left 34 :top 3 :flex-direction :row :align-items :center :width "45%"}}
[photos/member-photo from identicon 16]
[quo2.text/text {:weight :semi-bold
:size :paragraph-2
@@ -126,7 +125,7 @@
(defn send-image [images]
[rn/view {:style (styles/reply-container-image)}
[rn/scroll-view {:horizontal true
:style (styles/reply-content false)}
:style (styles/reply-content)}
(for [{:keys [uri]} (vals images)]
^{:key uri}
[rn/image {:source {:uri uri}
@@ -108,19 +108,11 @@
:padding-horizontal 10
:flex 1})
(defn reply-content [pin?]
{:padding-horizontal (when-not pin? 10)
(defn reply-content []
{:padding-horizontal 10
:flex 1
:flex-direction :row})
(defn quoted-message [pin?]
(merge {:flex-direction :row
:align-items :center
:width "45%"}
(when-not pin? {:position :absolute
:left 34
:top 3})))
(defn contact-request-content []
{:flex 1
:flex-direction :row
@@ -151,8 +143,7 @@
:bottom bottom
:background-color (colors/get-color :ui-background)
:border-top-width 1
:border-top-color (colors/get-color :ui-01)
:z-index 3})
:border-top-color (colors/get-color :ui-01)})
(defn new-input-bottom-sheet [window-height]
(merge {:border-top-left-radius 20
@@ -164,7 +155,7 @@
:height window-height
:flex 1
:background-color (quo2.colors/theme-colors quo2.colors/white quo2.colors/neutral-90)
:z-index 2}
:z-index 1000}
(if platform/ios?
{:shadow-radius 16
:shadow-opacity 1
@@ -185,7 +176,7 @@
{:flex-direction :row
:padding-horizontal 20
:elevation 2
:z-index 2
:z-index 2000
:position :absolute
:background-color (quo2.colors/theme-colors quo2.colors/white quo2.colors/neutral-90)
;these 3 props play together, we need this magic to hide message text in the safe area
@@ -201,4 +192,4 @@
:bottom 0
:height window-height
:background-color quo2.colors/neutral-95-opa-70
:z-index 1})
:z-index 500})
@@ -1,40 +1,34 @@
(ns status-im.ui.screens.chat.message.message
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.chat.models.delete-message-for-me]
[status-im.chat.models.images :as images]
[status-im.chat.models.pin-message :as models.pin-message]
[status-im.chat.models.reactions :as models.reactions]
(:require [re-frame.core :as re-frame]
[status-im.constants :as constants]
[status-im.i18n.i18n :as i18n]
[status-im.react-native.resources :as resources]
[status-im.ui.components.animation :as animation]
[status-im.ui.components.fast-image :as fast-image]
[quo.design-system.colors :as colors]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.react :as react]
[status-im.ui.screens.chat.bottom-sheets.context-drawer :as message-context-drawer]
[status-im.ui.screens.chat.components.reply :as components.reply]
[status-im.ui.screens.chat.image.preview.views :as preview]
[status-im.ui.screens.chat.message.audio :as message.audio]
[status-im.chat.models.reactions :as models.reactions]
[status-im.ui.screens.chat.message.command :as message.command]
[status-im.ui.screens.chat.message.gap :as message.gap]
[status-im.ui.screens.chat.message.link-preview :as link-preview]
[status-im.ui.screens.chat.message.reactions :as reactions]
[status-im.ui.screens.chat.message.reactions-row :as reaction-row]
[status-im.ui.screens.chat.photos :as photos]
[status-im.ui.screens.chat.sheets :as sheets]
[status-im.ui.screens.chat.message.gap :as message.gap]
[status-im.ui.screens.chat.styles.message.message :as style]
[status-im.ui.screens.chat.utils :as chat.utils]
[status-im.ui.screens.chat.styles.photos :as photos.style]
[status-im.ui.screens.communities.icon :as communities.icon]
[status-im.utils.handlers :refer [>evt]]
[status-im.utils.config :as config]
[status-im.utils.security :as security]
[quo2.foundations.typography :as typography]
[quo2.foundations.colors :as quo2.colors])
[status-im.ui.screens.chat.message.reactions :as reactions]
[status-im.ui.screens.chat.image.preview.views :as preview]
[quo.core :as quo]
[status-im.utils.config :as config]
[reagent.core :as reagent]
[status-im.ui.screens.chat.components.reply :as components.reply]
[status-im.ui.screens.chat.message.link-preview :as link-preview]
[status-im.ui.screens.communities.icon :as communities.icon]
[status-im.ui.components.animation :as animation]
[status-im.chat.models.images :as images]
[status-im.chat.models.pin-message :as models.pin-message]
[status-im.ui.components.fast-image :as fast-image]
[status-im.ui.screens.chat.bottom-sheets.context-drawer :as message-context-drawer]
[status-im.ui.screens.chat.message.reactions-row :as reaction-row])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
(defn message-timestamp-anim
@@ -95,12 +89,9 @@
timestamp-str]])))
(defview quoted-message
[_ reply pin?]
[react/view {:style (when-not pin? (style/quoted-message-container))}
[components.reply/reply-message reply false pin?]])
(defn system-text? [content-type]
(= content-type constants/content-type-system-text))
[_ reply]
[react/view {:style (style/quoted-message-container)}
[components.reply/reply-message reply false]])
(defn render-inline [message-text content-type acc {:keys [type literal destination]}]
(case type
@@ -139,14 +130,13 @@
destination])
"mention"
(conj acc
[react/view {:style {:background-color quo2.colors/primary-50-opa-10 :border-radius 6 :padding-horizontal 3}}
[react/text-class
{:style (merge {:color (if (system-text? content-type) colors/black quo2.colors/primary-50)}
(if (system-text? content-type) typography/font-regular typography/font-medium))
:on-press (when-not (system-text? content-type)
#(>evt [:chat.ui/show-profile literal]))}
[mention-element literal]]])
(conj acc [react/text-class
{:style {:color (cond
(= content-type constants/content-type-system-text) colors/black
:else colors/mention-incoming)}
:on-press (when-not (= content-type constants/content-type-system-text)
#(re-frame/dispatch [:chat.ui/show-profile literal]))}
[mention-element literal]])
"status-tag"
(conj acc [react/text-class
{:style {:color colors/blue
@@ -229,22 +219,28 @@
(let [user-contact @(re-frame/subscribe [:multiaccount/contact])
contact-names @(re-frame/subscribe [:contacts/contact-two-names-by-identity pinned-by])]
;; We append empty spaces to the name as a workaround to make one-line and multi-line label components show correctly
(str " " (if (= pinned-by (user-contact :public-key)) (i18n/label :t/You) (first contact-names)))))
(str " " (if (= pinned-by (user-contact :public-key)) (i18n/label :t/You) (first contact-names)))))
(def pin-icon-width 10)
(def pin-icon-width 9)
(def pin-icon-height 15)
(defn pin-icon []
[icons/icon :main-icons/pin16 {:color (:text-04 @colors/theme)
:height pin-icon-height
:width pin-icon-width}])
(defn pinned-by-indicator [pinned-by]
[react/view {:style (style/pin-indicator)
(defn pinned-by-indicator [display-photo? pinned-by]
[react/view {:style (style/pin-indicator display-photo?)
:accessibility-label :pinned-by}
[pin-icon]
[quo/text {:size :small
[react/view {:style (style/pinned-by-text-icon-container)}
[react/view {:style (style/pin-icon-container)}
[icons/icon :main-icons/pin {:color colors/gray
:height pin-icon-height
:width pin-icon-width
:background-color :red}]]
[quo/text {:weight :regular
:size :small
:color :main
:style (style/pinned-by-text)}
(i18n/label :t/pinned-by)]]
[quo/text {:weight :medium
:size :small
:color :main
:style (style/pin-author-text)}
(pin-author-name pinned-by)]])
@@ -298,8 +294,7 @@
"Author, userpic and delivery wrapper"
[{:keys [last-in-group?
identicon
from in-popover? timestamp-str
deleted-for-me? pinned]
from in-popover? timestamp-str]
:as message} content {:keys [modal close-modal]}]
(let [response-to (:response-to (:content message))]
[react/view {:style (style/message-wrapper message)
@@ -310,12 +305,12 @@
[react/view {:style (style/message-body)
:pointer-events :box-none}
[react/view (style/message-author-userpic)
(when (or (and (seq response-to) (:quoted-message message)) last-in-group? pinned)
(when (or (and (seq response-to) (:quoted-message message)) last-in-group?)
[react/touchable-highlight {:on-press #(do (when modal (close-modal))
(re-frame/dispatch [:chat.ui/show-profile from]))}
[photos/member-photo from identicon]])]
[react/view {:style (style/message-author-wrapper)}
(when (or (and (seq response-to) (:quoted-message message)) last-in-group? pinned)
(when (or (and (seq response-to) (:quoted-message message)) last-in-group?)
[react/view {:style {:flex-direction :row :align-items :center}}
[react/touchable-opacity {:style style/message-author-touchable
:disabled in-popover?
@@ -325,19 +320,14 @@
[react/text
{:style (merge
{:padding-left 5
:margin-top 2}
:margin-top 2}
(style/message-timestamp-text))
:accessibility-label :message-timestamp}
timestamp-str]])
;; MESSAGE CONTENT
;; TODO(yqrashawn): wait for system message component to display deleted for me UI
(if deleted-for-me?
[react/view {:style {:border-width 2
:border-color :red}}
content]
content)
;;MESSAGE CONTENT
content
[link-preview/link-preview-wrapper (:links (:content message)) false false]]]
; delivery status
; delivery status
[react/view (style/delivery-status)
[message-delivery-status message]]]))
@@ -446,13 +436,6 @@
:label (i18n/label (if pinned :t/unpin-from-chat :t/pin-to-chat))
:icon :main-icons/pin-context20
:id (if pinned :unpin :pin)}])
[{:type :danger
:on-press #(re-frame/dispatch
[:chat.ui/delete-message-for-me message
config/delete-message-for-me-undo-time-limit-ms])
:label (i18n/label :t/delete-for-me)
:icon :main-icons/delete-context20
:id :delete-for-me}]
(when (and outgoing config/delete-message-enabled?)
[{:type :danger
:on-press #(re-frame/dispatch [:chat.ui/soft-delete-message message])
@@ -491,34 +474,6 @@
[collapsible-text-message message on-long-press modal ref]
reaction-picker])
(defmethod ->message constants/content-type-pin [{:keys [from in-popover? timestamp-str] :as message} {:keys [modal close-modal]}]
(let [response-to (:response-to (:content message))]
[react/view {:style (merge {:flex-direction :row :margin-vertical 8} (style/message-wrapper message))}
[react/view {:style {:width photos.style/default-size
:height photos.style/default-size
:margin-horizontal 8
:border-radius photos.style/default-size
:justify-content :center
:align-items :center
:background-color quo2.colors/primary-50-opa-10}}
[pin-icon]]
[react/view
[react/view {:style {:flex-direction :row :align-items :center}}
[react/touchable-opacity {:style style/message-author-touchable
:disabled in-popover?
:on-press #(do (when modal (close-modal))
(re-frame/dispatch [:chat.ui/show-profile from]))}
[message-author-name from {:modal modal}]]
[react/text {:style {:font-size 13}} (str " " (i18n/label :pinned-a-message))]
[react/text
{:style (merge
{:padding-left 5
:margin-top 2}
(style/message-timestamp-text))
:accessibility-label :message-timestamp}
timestamp-str]]
[quoted-message response-to (:quoted-message message) true]]]))
(defmethod ->message constants/content-type-community
[message]
[community-content message])
@@ -626,13 +581,6 @@
:id :share
:icon :main-icons/share-context20
:label (i18n/label :t/share-image)}]
[{:type :danger
:on-press #(re-frame/dispatch
[:chat.ui/delete-message-for-me message
config/delete-message-for-me-undo-time-limit-ms])
:label (i18n/label :t/delete-for-me)
:icon :main-icons/delete-context20
:id :delete-for-me}]
(when (and outgoing config/delete-message-enabled?)
[{:type :danger
:on-press #(re-frame/dispatch [:chat.ui/soft-delete-message message])
@@ -663,13 +611,6 @@
:label (i18n/label (if pinned :t/unpin-from-chat :t/pin-to-chat))
:icon :main-icons/pin-context20
:id (if pinned :unpin :pin)}
{:type :danger
:on-press #(re-frame/dispatch
[:chat.ui/delete-message-for-me message
config/delete-message-for-me-undo-time-limit-ms])
:label (i18n/label :t/delete-for-me)
:icon :main-icons/delete-context20
:id :delete-for-me}
(when (and outgoing config/delete-message-enabled?)
{:type :danger
:on-press #(re-frame/dispatch [:chat.ui/soft-delete-message message])
@@ -737,7 +678,7 @@
[message-content-wrapper message
[unknown-content-type message]])
(defn chat-message [{:keys [pinned pinned-by mentioned] :as message}]
(defn chat-message [{:keys [display-photo? pinned pinned-by] :as message}]
(let [reactions @(re-frame/subscribe [:chats/message-reactions (:message-id message) (:chat-id message)])
own-reactions (reduce (fn [acc {:keys [emoji-id own]}]
(if own (conj acc emoji-id) acc))
@@ -764,12 +705,11 @@
(into #{} (js->clj own-reactions))
#(on-emoji-press %))}]))
on-long-press (atom nil)]
[react/view {:style (merge (when (or mentioned pinned) {:background-color quo2.colors/primary-50-opa-5 :border-radius 16 :margin-bottom 4}) {:margin-horizontal 8})}
(when pinned
[react/view {:style (style/pin-indicator-container)}
[pinned-by-indicator pinned-by]])
[:<>
[->message message {:ref on-long-press
:modal false
:on-long-press on-open-drawer}]
[reaction-row/message-reactions message reactions nil on-emoji-press on-long-press] ;; TODO: pass on-open-drawer function
]))
(when pinned
[react/view {:style (style/pin-indicator-container)}
[pinned-by-indicator display-photo? pinned-by]])]))
@@ -92,7 +92,6 @@
(defn reactions-row [timeline margin-top]
{:flex-direction :row
:padding-right 8
:padding-bottom 8
:justify-content :flex-start
:margin-top margin-top
:flex-wrap :wrap
@@ -3,8 +3,7 @@
[quo.design-system.colors :as colors]
[status-im.ui.components.react :as react]
[status-im.ui.screens.chat.styles.photos :as photos]
[quo2.foundations.colors :as quo2.colors]
[quo2.foundations.typography :as typography]))
[quo2.foundations.colors :as quo2.colors]))
(defn style-message-text
[]
@@ -72,15 +71,30 @@
{:align-self :flex-start
:padding-left 8})
(defn pin-indicator []
(merge {:flex-direction :row}))
(defn pin-indicator [display-photo?]
(merge
{:flex-direction :row
:border-top-left-radius 4
:border-top-right-radius 12
:border-bottom-left-radius 12
:border-bottom-right-radius 12
:padding-left 8
:padding-right 10
:padding-vertical 5
:background-color colors/gray-lighter
:justify-content :center
:max-width "80%"
:align-self :flex-start
:align-items :flex-start}
(when display-photo?
{:margin-left 44})))
(defn pin-indicator-container []
{:margin-top 8
:margin-left 68
{:margin-top 2
:justify-content :center
:align-self :flex-start
:align-items :flex-start})
:align-items :flex-start
:padding-left 8})
(defn pinned-by-text-icon-container []
{:flex-direction :row
@@ -94,9 +108,14 @@
:margin-top 1})
(defn pin-author-text []
(merge typography/font-medium
{:color quo2.colors/primary-50
:bottom 2}))
{:margin-left 2
:margin-right 12
:padding-right 0
:left 12
:flex-direction :row
:flex-shrink 1
:align-self :flex-start
:overflow :hidden})
(defn pinned-by-text []
{:margin-left 5})
@@ -108,7 +127,7 @@
(defn message-author-userpic []
(merge
{:width (+ 16 photos/default-size)} ;; 16 is for the padding
{:padding-left 0
{:padding-left 8
:padding-right 8}))
(def delivery-text
@@ -152,17 +171,20 @@
:flex-direction :row-reverse})
(defn message-view
[{:keys [content-type mentioned]}]
[{:keys [content-type mentioned pinned]}]
(merge
{:border-radius 10}
(cond
pinned {:background-color colors/pin-background}
(= content-type constants/content-type-system-text) nil
mentioned {:background-color colors/mentioned-background
:border-color colors/mentioned-border
:border-width 1}
(= content-type constants/content-type-audio) {:background-color colors/blue
:padding-horizontal 12
:padding-top 6})
:padding-top 6}
:else {:background-color colors/white})
(when (= content-type constants/content-type-emoji)
{:flex-direction :row})))
+3 -3
View File
@@ -419,7 +419,7 @@
:keyboard-should-persist-taps :handled
:onMomentumScrollBegin state/start-scrolling
:onMomentumScrollEnd state/stop-scrolling
;;TODO https://github.com/facebook/react-native/issues/30034
;;TODO https://github.com/facebook/react-native/issues/30034
:inverted (when platform/ios? true)
:style (when platform/android? {:scaleY -1})})]))
@@ -502,7 +502,7 @@
:onMomentumScrollEnd state/stop-scrolling
:scrollEventThrottle 16
:on-scroll on-scroll
;;TODO https://github.com/facebook/react-native/issues/30034
;;TODO https://github.com/facebook/react-native/issues/30034
:inverted (when platform/ios? true)
:style (when platform/android? {:scaleY -1})})]
(when @show-floating-scroll-down-button
@@ -602,7 +602,7 @@
[accessory/view {:y position-y
:on-update-inset on-update}
[invitation-bar chat-id]])
[components/autocomplete-mentions-old text-input-ref max-bottom-space]
[components/autocomplete-mentions text-input-ref max-bottom-space]
(when show-input?
;; NOTE: this only accepts two children
[accessory/view {:y position-y
@@ -74,7 +74,8 @@
{:style
{:flex 1
:border-radius 20}}
[react/view (styles/community-cover-container 148)
[react/view (styles/community-cover-container 148)
[react/image
{:source cover
:style {:position :relative
+1 -3
View File
@@ -181,6 +181,4 @@
;; TODO: Remove this (highly) temporary flag once the new Activity Center is
;; usable enough to replace the old one **in the new UI**.
(def new-activity-center-enabled?
(atom false))
(def delete-message-for-me-undo-time-limit-ms 4000)
(atom true))
+6
View File
@@ -240,3 +240,9 @@
(defn to-ms [sec]
(* 1000 sec))
(defn now->iso8601 []
(unparse {:format-str "HH:mm:ss.SSS"}
(-> (timestamp)
(from-long)
(plus time-zone-offset))))
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "fix/pairing-server-race",
"commit-sha1": "e435e00c1bfdf6db44d3bce6dff42ce05be9f25f",
"src-sha256": "1825vn59vazx2i7zqs0in471rfgkbcz3y7i4wx3s3mqp6nz6w5f7"
"version": "v0.110.3",
"commit-sha1": "506921509e477445a95e1961a2557ef584d7caec",
"src-sha256": "1xmngbfl67n031rxhhbs7m14gzmfhgr1d34szclf1a6qxb9kw946"
}
-1
View File
@@ -418,7 +418,6 @@
"delete-chat-confirmation": "Are you sure you want to delete this chat?",
"delete-category-confirmation": "Are you sure you want to delete this category?",
"delete-confirmation": "Delete?",
"delete-for-me": "Delete for me",
"delete-mailserver": "Delete Status node",
"delete-mailserver-are-you-sure": "Are you sure you want to delete this Status node?",
"delete-mailserver-title": "Delete Status node",