Remove jump to (#21634)

This commit is contained in:
Parvesh Monu 2024-11-19 17:21:24 +05:30 committed by GitHub
parent 65c872c6ec
commit e6f290c06a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
118 changed files with 358 additions and 3421 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@ -10,40 +10,3 @@ export function scrollDownButtonOpacity(chatListScrollY, isComposerFocused, wind
}
});
}
export function jumpToButtonOpacity(scrollDownButtonOpacity, isComposerFocused) {
return useDerivedValue(function () {
'worklet';
return withTiming(scrollDownButtonOpacity.value == 1 || isComposerFocused.value ? 0 : 1);
});
}
export function jumpToButtonPosition(scrollDownButtonOpacity, isComposerFocused) {
return useDerivedValue(function () {
'worklet';
return withTiming(scrollDownButtonOpacity.value == 1 || isComposerFocused.value ? 35 : 0);
});
}
export function composerContainerOpacity(isComposerFocused, isEmptyInput, emptyOpacity) {
return useDerivedValue(function () {
'worklet';
return isEmptyInput.value && !isComposerFocused.value
? withDelay(300, withTiming(emptyOpacity, { duration: 0 }))
: 1;
});
}
export function blurContainerElevation(isComposerFocused, isEmptyInput) {
return useDerivedValue(function () {
'worklet';
return isEmptyInput.value && !isComposerFocused.value ? 10 : 0;
});
}
export function composerElevation(isComposerFocused, isEmptyInput) {
return useDerivedValue(function () {
'worklet';
return isEmptyInput.value && !isComposerFocused.value ? 0 : 10;
});
}

View File

@ -1,47 +1,12 @@
import { useDerivedValue, withTiming } from 'react-native-reanimated';
import * as constants from './constants';
export function bottomTabIconColor(
stackId,
selectedStackId,
homeStackState,
passThrough,
selectedTabColor,
defaultColor,
passThroughColor,
) {
export function bottomTabIconColor(stackId, selectedStackId, selectedTabColor, defaultColor) {
return useDerivedValue(function () {
'worklet';
var homeStackStateValue = homeStackState.value;
if (
selectedStackId.value == stackId &&
(homeStackStateValue == constants.OPEN_WITH_ANIMATION || homeStackStateValue == constants.OPEN_WITHOUT_ANIMATION)
) {
if (selectedStackId.value == stackId) {
return selectedTabColor;
} else if (passThrough.value) {
return passThroughColor;
} else {
return defaultColor;
}
});
}
export function bottomTabsHeight(homeStackState, height, extendedHeight) {
return useDerivedValue(function () {
'worklet';
switch (homeStackState.value) {
case constants.OPEN_WITH_ANIMATION:
return withTiming(extendedHeight, constants.LINEAR_EASING);
break;
case constants.CLOSE_WITH_ANIMATION:
return withTiming(height, constants.LINEAR_EASING);
break;
case constants.OPEN_WITHOUT_ANIMATION:
return extendedHeight;
break;
case constants.CLOSE_WITHOUT_ANIMATION:
return height;
break;
}
});
}

View File

@ -1,29 +0,0 @@
import { Easing } from 'react-native-reanimated';
// Home Stack States
export const CLOSE_WITHOUT_ANIMATION = 0;
export const OPEN_WITHOUT_ANIMATION = 1;
export const CLOSE_WITH_ANIMATION = 2;
export const OPEN_WITH_ANIMATION = 3;
// Floating Screen States
export const CLOSE_SCREEN_WITHOUT_ANIMATION = 0;
export const OPEN_SCREEN_WITHOUT_ANIMATION = 1;
export const CLOSE_SCREEN_WITH_SHELL_ANIMATION = 2;
export const OPEN_SCREEN_WITH_SHELL_ANIMATION = 3;
export const CLOSE_SCREEN_WITH_SLIDE_TO_RIGHT_ANIMATION = 4;
export const OPEN_SCREEN_WITH_SLIDE_FROM_RIGHT_ANIMATION = 5;
export const CLOSE_SCREEN_WITH_SLIDE_TO_BOTTOM_ANIMATION = 6;
export const OPEN_SCREEN_WITH_SLIDE_FROM_BOTTOM_ANIMATION = 7;
export const SHELL_ANIMATION_TIME = 200;
export const LINEAR_EASING = {
duration: SHELL_ANIMATION_TIME,
easing: Easing.bezier(0, 0, 1, 1),
};
export const EASE_OUT_EASING = {
duration: SHELL_ANIMATION_TIME,
easing: Easing.bezier(0, 0, 0.58, 1),
};

View File

@ -1,180 +0,0 @@
import { useDerivedValue, withTiming, withSequence, withDelay, Easing, runOnJS } from 'react-native-reanimated';
import * as constants from './constants';
// Derived Values
export function screenLeft(screenState, screenWidth, switcherCardLeftPosition) {
return useDerivedValue(function () {
'worklet';
switch (screenState.value) {
case constants.CLOSE_SCREEN_WITHOUT_ANIMATION:
return screenWidth;
case constants.OPEN_SCREEN_WITHOUT_ANIMATION:
// Note - don't use return 0; its not working in ios
// https://github.com/software-mansion/react-native-reanimated/issues/3296#issuecomment-1573900172
return withSequence(withTiming(-1, { duration: 0 }), withTiming(0, { duration: 0 }));
case constants.CLOSE_SCREEN_WITH_SHELL_ANIMATION:
return withSequence(
withTiming(switcherCardLeftPosition, constants.EASE_OUT_EASING),
withTiming(screenWidth, { duration: 0 }),
);
case constants.OPEN_SCREEN_WITH_SHELL_ANIMATION:
return withTiming(0, constants.EASE_OUT_EASING);
case constants.CLOSE_SCREEN_WITH_SLIDE_TO_RIGHT_ANIMATION:
return withTiming(screenWidth, constants.EASE_OUT_EASING);
case constants.OPEN_SCREEN_WITH_SLIDE_FROM_RIGHT_ANIMATION:
return withTiming(0, constants.EASE_OUT_EASING);
case constants.CLOSE_SCREEN_WITH_SLIDE_TO_BOTTOM_ANIMATION:
return withDelay(constants.SHELL_ANIMATION_TIME, withTiming(screenWidth, { duration: 0 }));
case constants.OPEN_SCREEN_WITH_SLIDE_FROM_BOTTOM_ANIMATION:
return 0;
default:
return screenWidth;
}
});
}
export function screenTop(screenState, screenHeight, switcherCardTopPosition) {
return useDerivedValue(function () {
'worklet';
switch (screenState.value) {
case constants.CLOSE_SCREEN_WITHOUT_ANIMATION:
return screenHeight;
case constants.OPEN_SCREEN_WITHOUT_ANIMATION:
return withSequence(withTiming(-1, { duration: 0 }), withTiming(0, { duration: 0 }));
case constants.CLOSE_SCREEN_WITH_SHELL_ANIMATION:
return withSequence(
withTiming(switcherCardTopPosition, constants.EASE_OUT_EASING),
withTiming(screenHeight, { duration: 0 }),
);
case constants.OPEN_SCREEN_WITH_SHELL_ANIMATION:
return withTiming(0, constants.EASE_OUT_EASING);
case constants.CLOSE_SCREEN_WITH_SLIDE_TO_RIGHT_ANIMATION:
return withDelay(constants.SHELL_ANIMATION_TIME, withTiming(screenHeight, { duration: 0 }));
case constants.OPEN_SCREEN_WITH_SLIDE_FROM_RIGHT_ANIMATION:
return 0;
case constants.CLOSE_SCREEN_WITH_SLIDE_TO_BOTTOM_ANIMATION:
return withTiming(screenHeight, constants.EASE_OUT_EASING);
case constants.OPEN_SCREEN_WITH_SLIDE_FROM_BOTTOM_ANIMATION:
return withTiming(0, constants.EASE_OUT_EASING);
default:
return screenHeight;
}
});
}
export function screenWidth(screenState, screenWidth, switcherCardSize) {
return useDerivedValue(function () {
'worklet';
switch (screenState.value) {
case constants.CLOSE_SCREEN_WITH_SHELL_ANIMATION:
return withTiming(switcherCardSize, constants.EASE_OUT_EASING);
case constants.OPEN_SCREEN_WITH_SHELL_ANIMATION:
return withSequence(
withTiming(switcherCardSize, { duration: 0 }),
withTiming(screenWidth, constants.EASE_OUT_EASING),
);
default:
return screenWidth;
}
});
}
export function screenHeight(screenState, screenHeight, switcherCardSize) {
return useDerivedValue(function () {
'worklet';
switch (screenState.value) {
case constants.CLOSE_SCREEN_WITH_SHELL_ANIMATION:
return withTiming(switcherCardSize, constants.EASE_OUT_EASING);
case constants.OPEN_SCREEN_WITH_SHELL_ANIMATION:
return withSequence(
withTiming(switcherCardSize, { duration: 0 }),
withTiming(screenHeight, constants.EASE_OUT_EASING),
);
default:
return screenHeight;
}
});
}
export function screenZIndex(screenState) {
return useDerivedValue(function () {
'worklet';
switch (screenState.value) {
case constants.CLOSE_SCREEN_WITH_SHELL_ANIMATION:
case constants.CLOSE_SCREEN_WITH_SLIDE_TO_RIGHT_ANIMATION:
case constants.CLOSE_SCREEN_WITH_SLIDE_TO_BOTTOM_ANIMATION:
return withDelay(constants.SHELL_ANIMATION_TIME, withTiming(-1, { duration: 0 }));
case constants.CLOSE_SCREEN_WITHOUT_ANIMATION:
return -1;
default:
return 1;
}
});
}
export function screenBorderRadius(screenState) {
return useDerivedValue(function () {
'worklet';
switch (screenState.value) {
case constants.OPEN_SCREEN_WITH_SHELL_ANIMATION:
return withDelay(constants.SHELL_ANIMATION_TIME, withTiming(0, { duration: 0 }));
case constants.OPEN_SCREEN_WITH_SLIDE_FROM_RIGHT_ANIMATION:
case constants.OPEN_SCREEN_WITH_SLIDE_FROM_BOTTOM_ANIMATION:
case constants.OPEN_SCREEN_WITHOUT_ANIMATION:
return 0;
case constants.CLOSE_SCREEN_WITH_SLIDE_TO_RIGHT_ANIMATION:
case constants.CLOSE_SCREEN_WITH_SLIDE_TO_BOTTOM_ANIMATION:
return withDelay(constants.SHELL_ANIMATION_TIME, withTiming(20, { duration: 0 }));
case constants.CLOSE_SCREEN_WITHOUT_ANIMATION:
case constants.CLOSE_SCREEN_WITH_SHELL_ANIMATION:
return 20;
}
});
}
export function screenGestureOnUpdate(screenLeft) {
return function (event) {
'worklet';
const absoluteX = event.absoluteX;
if (absoluteX !== null) {
screenLeft.value = event.absoluteX;
}
};
}
export function screenGestureOnEnd(data) {
return function (event) {
'worklet';
const {
'screen-left': screenLeft,
'screen-state': screenState,
'screen-width': screenWidth,
'left-velocity': leftVelocity,
'right-velocity': rightVelocity,
'screen-closed-callback': screenClosedCallback,
} = data;
const absoluteX = event.absoluteX ?? 0;
const velocityX = event.velocityX ?? 0;
const closeScreen = velocityX > rightVelocity || (velocityX > leftVelocity && absoluteX >= screenWidth / 2);
// Velocity (points/sec) = Distance/time
var animationVelocity = (screenWidth * 1000) / constants.SHELL_ANIMATION_TIME;
if (Math.abs(velocityX) > animationVelocity) {
animationVelocity = velocityX; // Faster fling
}
const newDistance = closeScreen ? screenWidth - absoluteX : absoluteX;
const animationTime = (newDistance * 1000) / animationVelocity;
screenLeft.value = withTiming(closeScreen ? screenWidth : 0, {
duration: animationTime,
easing: Easing.bezier(0, 0, 0.58, 1),
});
if (closeScreen) {
runOnJS(screenClosedCallback)(animationTime);
}
};
}

View File

@ -1,5 +1,4 @@
import { useDerivedValue, withTiming, withSequence, withDelay } from 'react-native-reanimated';
import * as constants from './constants';
// Derived values for each stack (communities, chat, wallet, browser)
export function stackOpacity(stackId, selectedStackId) {
@ -15,99 +14,3 @@ export function stackZIndex(stackId, selectedStackId) {
return selectedStackId.value == stackId ? 10 : 9;
});
}
// Derived values for home stack (container)
export function homeStackOpacity(homeStackState) {
return useDerivedValue(function () {
'worklet';
switch (homeStackState.value) {
case constants.OPEN_WITH_ANIMATION:
return withTiming(1, constants.LINEAR_EASING);
case constants.CLOSE_WITH_ANIMATION:
return withTiming(0, constants.LINEAR_EASING);
case constants.OPEN_WITHOUT_ANIMATION:
return 1;
case constants.CLOSE_WITHOUT_ANIMATION:
return 0;
}
});
}
export function homeStackTop(homeStackState, top) {
return useDerivedValue(function () {
'worklet';
switch (homeStackState.value) {
case constants.OPEN_WITH_ANIMATION:
return withTiming(0, constants.LINEAR_EASING);
case constants.CLOSE_WITH_ANIMATION:
return withTiming(top, constants.LINEAR_EASING);
case constants.OPEN_WITHOUT_ANIMATION:
return 0;
case constants.CLOSE_WITHOUT_ANIMATION:
return top;
}
});
}
export function homeStackLeft(selectedStackId, animateHomeStackLeft, homeStackState, left) {
return useDerivedValue(function () {
'worklet';
if (animateHomeStackLeft.value) {
var leftValue = left[selectedStackId.value];
switch (homeStackState.value) {
case constants.OPEN_WITH_ANIMATION:
return withSequence(withTiming(leftValue, { duration: 0 }), withTiming(0, constants.LINEAR_EASING));
case constants.CLOSE_WITH_ANIMATION:
return withTiming(leftValue, constants.LINEAR_EASING);
case constants.OPEN_WITHOUT_ANIMATION:
return 0;
case constants.CLOSE_WITHOUT_ANIMATION:
return leftValue;
}
} else {
return 0;
}
});
}
export function homeStackPointer(homeStackState) {
return useDerivedValue(function () {
'worklet';
var homeStackStateValue = homeStackState.value;
return homeStackStateValue == constants.OPEN_WITH_ANIMATION ||
homeStackStateValue == constants.OPEN_WITHOUT_ANIMATION
? 'auto'
: 'none';
});
}
export function homeStackScale(homeStackState, minimizeScale) {
return useDerivedValue(function () {
'worklet';
switch (homeStackState.value) {
case constants.OPEN_WITH_ANIMATION:
return withTiming(1, constants.LINEAR_EASING);
case constants.CLOSE_WITH_ANIMATION:
return withTiming(minimizeScale, constants.LINEAR_EASING);
case constants.OPEN_WITHOUT_ANIMATION:
return 1;
case constants.CLOSE_WITHOUT_ANIMATION:
return minimizeScale;
}
});
}
export function homeStackBorderRadius(homeStackState) {
return useDerivedValue(function () {
'worklet';
switch (homeStackState.value) {
case constants.OPEN_WITH_ANIMATION:
return withDelay(constants.SHELL_ANIMATION_TIME, withTiming(0, { duration: 0 }));
case constants.CLOSE_WITH_ANIMATION:
case constants.CLOSE_WITHOUT_ANIMATION:
return 20;
case constants.OPEN_WITHOUT_ANIMATION:
return 0;
}
});
}

View File

@ -309,10 +309,10 @@
{:db (assoc db
:browser/options
{:browser-id (:browser-id browser)}
:browser/screen-id :browser)}
:browser/screen-id :browser)
:dispatch-n [[:shell/change-tab :browser-stack]]}
(navigation/pop-to-root :shell-stack)
(chat.events/close-chat (:current-chat-id db))
(navigation/change-tab :browser-stack)
(update-browser browser)
(resolve-url nil))
{:linking/open-url url}))))
@ -326,17 +326,17 @@
{:db (assoc db
:browser/options
{:browser-id browser-id}
:browser/screen-id :browser)}
:browser/screen-id :browser)
:dispatch-n [[:shell/change-tab :browser-stack]]}
(update-browser browser)
(navigation/change-tab :browser-stack)
(resolve-url nil))))
(rf/defn open-browser-tabs
{:events [:browser.ui/open-browser-tabs]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc db :browser/screen-id :browser-tabs)}
(navigation/change-tab :browser-stack)))
{:db (assoc db :browser/screen-id :browser-tabs)
:dispatch-n [[:shell/change-tab :browser-stack]]}))
(rf/defn web3-error-callback
{:events [:browser.dapp/transaction-on-error]}

View File

@ -1,44 +0,0 @@
(ns legacy.status-im.data-store.switcher-cards
(:require
[clojure.set :as set]
[clojure.walk :as walk]
[re-frame.core :as re-frame]
[status-im.common.json-rpc.events :as json-rpc]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(defn <-rpc
[switcher-cards]
(walk/postwalk-replace
{:cardId :card-id
:screenId :screen-id}
switcher-cards))
(defn rpc->
[switcher-card]
(set/rename-keys switcher-card
{:card-id :cardId
:screen-id :screenId}))
(rf/defn upsert-switcher-card-rpc
[_ switcher-card]
{:json-rpc/call [{:method "wakuext_upsertSwitcherCard"
:params [(rpc-> switcher-card)]
:on-success #()
:on-error #()}]})
(rf/defn delete-switcher-card-rpc
[_ card-id]
{:json-rpc/call [{:method "wakuext_deleteSwitcherCard"
:params [card-id]
:on-success #()
:on-error #()}]})
(re-frame/reg-fx :switcher-cards/fetch
(fn []
(json-rpc/call {:method "wakuext_switcherCards"
:params []
:on-success #(rf/dispatch
[:shell/switcher-cards-loaded
(:switcherCards ^js %)])
:on-error #(log/error "Failed to fetch switcher cards" %)})))

View File

@ -6,7 +6,6 @@
legacy.status-im.browser.permissions
legacy.status-im.chat.models.loading
legacy.status-im.data-store.chats
legacy.status-im.data-store.switcher-cards
legacy.status-im.data-store.visibility-status-updates
legacy.status-im.fleet.core
legacy.status-im.group-chats.core
@ -43,7 +42,6 @@
status-im.contexts.onboarding.events
status-im.contexts.shell.activity-center.events
status-im.contexts.shell.activity-center.notification.contact-requests.events
status-im.contexts.shell.jump-to.events
[utils.i18n :as i18n]
[utils.re-frame :as rf]))

View File

@ -20,10 +20,9 @@
(chat.events/pop-to-root-and-navigate-to-chat cofx chat-id nil)))
(re-frame/reg-event-fx :chat-removed
(fn [{:keys [db]} [response chat-id]]
(fn [{:keys [db]} [response]]
{:db (dissoc db :current-chat-id)
:fx [[:dispatch [:shell/close-switcher-card chat-id]]
[:dispatch [:sanitize-messages-and-process-response response]]
:fx [[:dispatch [:sanitize-messages-and-process-response response]]
[:dispatch [:pop-to-root :shell-stack]]
[:activity-center.notifications/fetch-unread-count]]}))

View File

@ -78,8 +78,8 @@
(rf/defn handle-eip681
[cofx data]
(rf/merge cofx
{:dispatch [:wallet-legacy/parse-eip681-uri-and-resolve-ens data]}
(navigation/change-tab :wallet-stack)
{:dispatch-n [[:shell/change-tab :wallet-stack]
[:wallet-legacy/parse-eip681-uri-and-resolve-ens data]]}
(navigation/pop-to-root :shell-stack)))
(rf/defn handle-local-pairing

View File

@ -431,7 +431,6 @@
"../src/js/worklets/core.js" worklet-factory
"../src/js/worklets/shell/bottom_tabs.js" #js {}
"../src/js/worklets/shell/home_stack.js" #js {}
"../src/js/worklets/shell/floating_screen.js" #js {}
"../src/js/worklets/bottom_sheet.js" #js {}
"../src/js/worklets/record_audio.js" #js {}
"../src/js/worklets/scroll_view.js" #js {}

View File

@ -5,7 +5,6 @@
{:margin-top 6
:margin-bottom 6
:margin-left (case type
:jump-to 0
:mention 8
:notification-down 2
:notification-up 2
@ -14,7 +13,6 @@
:scroll-to-bottom 6
nil)
:margin-right (case type
:jump-to 8
:mention 2
:notification-down 8
:notification-up 8
@ -28,14 +26,12 @@
{:margin-top 2.5
:margin-bottom 3.5
:margin-left (case type
:jump-to 8
:mention 0
:notification-down 8
:notification-up 8
:search-with-label 0
nil)
:margin-right (case type
:jump-to 0
:mention 8
:notification-down 0
:notification-up 0

View File

@ -9,7 +9,7 @@
(defn- get-button-color
[{:keys [type pressed? customization-color theme]}]
(if (#{:jump-to :mention} type)
(if (= type :mention)
(if pressed?
(colors/theme-colors
(colors/custom-color customization-color 60)
@ -25,7 +25,7 @@
(defn- get-icon-and-text-color
[type theme]
(if (#{:jump-to :mention} type)
(if (= type :mention)
colors/white
(colors/theme-colors colors/white colors/neutral-100 theme)))
@ -33,7 +33,6 @@
[type theme]
[icon/icon
(case type
:jump-to :i/jump-to
:mention :i/mention
:notification-down :i/arrow-down
:notification-up :i/arrow-up
@ -47,10 +46,10 @@
(defn view
"[dynamic-button opts]
opts
{:type :jump-to/:mention/:notification-down/:notification-up/:search/:search-with-label/:scroll-to-bottom
{:type :mention/:notification-down/:notification-up/:search/:search-with-label/:scroll-to-bottom
:on-press fn
:count mentions or notifications count
:customization-color customize jump-to and mention button color}"
:customization-color customize and mention button color}"
[{:keys [type label on-press customization-color style] :as args}]
(let [theme (quo.theme/use-theme)
[pressed? set-pressed] (rn/use-state false)
@ -78,14 +77,13 @@
style)}
(when (#{:mention :search :search-with-label :scroll-to-bottom} type)
[icon-view type theme])
(when (#{:jump-to :mention :notification-down :notification-up :search-with-label} type)
(when (#{:mention :notification-down :notification-up :search-with-label} type)
[text/text
{:weight :medium
:size :paragraph-2
:style (assoc (style/text type) :color (get-icon-and-text-color type theme))}
(case type
:jump-to label
:search-with-label label
(:mention :notification-down :notification-up) (str (:count args)))])
(when (#{:jump-to :notification-down :notification-up} type)
(when (#{:notification-down :notification-up} type)
[icon-view type theme])]]))

View File

@ -28,8 +28,6 @@
[dynamic-button-view :search dynamic-buttons
{:position :absolute
:right 8}]]
;; Mid Section (jump-to)
[dynamic-button-view :jump-to dynamic-buttons nil]
;; Right Section
[section
[rn/view

View File

@ -34,12 +34,11 @@
[])))
(defn- get-button-common-props
[{:keys [jump-to? theme blur?]}]
[{:keys [theme blur?]}]
{:icon-only? true
:size 32
:container-style {:margin-left 12}
:type (cond
jump-to? :black
(and (not blur?) (= :dark theme)) :dark-grey
:else :grey)
:background (when blur? :blur)})
@ -88,8 +87,7 @@
avatar-props)]]])
(defn- right-section
[{:keys [jump-to?
blur?
[{:keys [blur?
notification
notification-count
activity-center-on-press
@ -99,7 +97,6 @@
:as props}]
(let [theme (quo.theme/use-theme)
button-common-props (get-button-common-props {:theme theme
:jump-to? jump-to?
:blur? blur?})]
[rn/view {:style style/right-section}
(when right-section-content
@ -130,7 +127,6 @@
":container-style style map merged with outer view for margins/paddings
:customization-color custom colors
:blur? true/false
:jump-to? true/false
:theme :light/:dark
:notification :mention/:seen/:notification (TODO :mention-seen temporarily used while resolving https://github.com/status-im/status-mobile/issues/17102 )
:avatar-props qu2/user-avatar props

View File

@ -1,19 +0,0 @@
(ns quo.components.switchers.base-card.component-spec
(:require
[quo.components.switchers.base-card.view :as base-card]
[quo.foundations.colors :as colors]
[test-helpers.component :as h]))
(h/describe "Switcher: Base card"
(h/test "Default render"
(h/render [base-card/base-card {}])
(h/is-truthy (h/query-by-label-text :base-card)))
(h/test "Banner render"
(h/render [base-card/base-card {:banner {:source "banner"}}])
(h/is-truthy (h/query-by-label-text :base-card))
(h/is-truthy (h/query-by-label-text :banner)))
(h/test "Customization color"
(h/render [base-card/base-card {:customization-color :blue}])
(h/has-style
(h/query-by-label-text :base-card)
{:backgroundColor (colors/custom-color :blue 50 40)})))

View File

@ -1,24 +0,0 @@
(ns quo.components.switchers.base-card.style
(:require
[quo.foundations.colors :as colors]))
(defn base-container
[customization-color]
{:width 160
:height 160
:border-radius 16
:background-color (colors/custom-color customization-color 50 40)})
(def thumb-card
{:width 160
:height 120
:border-radius 16
:bottom 0
:position :absolute
:background-color colors/neutral-95
:padding 12})
(def close-button
{:position :absolute
:right 8
:top 8})

View File

@ -1,32 +0,0 @@
(ns quo.components.switchers.base-card.view
(:require
[quo.components.buttons.button.view :as button]
[quo.components.switchers.base-card.style :as style]
[react-native.core :as rn]))
(defn base-card
[]
(let [card-ref (atom nil)
set-ref #(reset! card-ref %)]
(fn [{:keys [banner on-press on-close customization-color]} & children]
[rn/touchable-opacity
{:on-press on-press
:ref set-ref
:active-opacity 1}
[rn/view
{:accessibility-label :base-card
:style (style/base-container customization-color)}
(when banner
[rn/image
{:accessibility-label :banner
:source (:source banner)
:style {:width 160}}])
[button/button
{:size 24
:type :grey
:icon-only? true
:on-press on-close
:background :photo
:container-style style/close-button}
:i/close]
(into [rn/view {:style style/thumb-card}] children)]])))

View File

@ -1,28 +0,0 @@
(ns quo.components.switchers.card-content.style
(:require
[quo.foundations.colors :as colors]))
(defn content-container
[status]
{:flex-direction :row
:justify-content :space-between
:align-items (if (= status :mention) :center :flex-end)})
(def notification-container
{:width 20
:height 20
:justify-content :center
:align-items :center
:margin-left 8})
(def message-text
{:color colors/white})
(def sticker
{:width 24
:height 24})
(def gif
{:width 24
:height 24
:border-radius 8})

View File

@ -1,99 +0,0 @@
(ns quo.components.switchers.card-content.view
(:require
[quo.components.code.snippet-preview.view :as snippet-preview]
[quo.components.common.notification-dot.view :as notification-dot]
[quo.components.counter.counter.view :as counter]
[quo.components.list-items.preview-list.view :as preview-list]
[quo.components.markdown.text :as text]
[quo.components.switchers.card-content.style :as style]
[quo.components.tags.context-tag.view :as tag]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]
[utils.i18n :as i18n]))
(defn content-view
[{:keys [type content customization-color]
{:keys [text duration photos community-avatar
community-name source]} :content}]
[rn/view {:style {:max-width 108}}
(case type
:message
[text/text
{:size :paragraph-2
:weight :regular
:number-of-lines 1
:ellipsize-mode :tail
:style style/message-text}
text]
:photo
[preview-list/view
{:type :collectibles
:more-than-99-label (i18n/label :t/counter-99-plus)
:size :size/s-24}
photos]
:sticker
[fast-image/fast-image
{:accessibility-label :sticker
:source source
:style style/sticker}]
:gif
[fast-image/fast-image
{:accessibility-label :gif
:source source
:style style/gif}]
:audio
[tag/view
{:type :audio
:duration duration
:customization-color customization-color}]
:community
[tag/view
{:type :community
:community-name community-name
:community-logo community-avatar
:size 24}]
:link
[tag/view
{:type :icon
:icon (:icon content)
:context (:text content)
:size 24}]
:code
[snippet-preview/view
{:language (:language content)}
content]
nil)])
(defn notification-indicator
[{:keys [status mention-count customization-color]}]
(when (not= status :read)
[rn/view {:style style/notification-container}
(case status
:unread
[notification-dot/view
{:customization-color customization-color}]
:mention
[counter/view
{:outline false
:customization-color customization-color}
mention-count]
nil)]))
(defn view
[type status customization-color content]
[rn/view {:style (style/content-container status)}
[content-view {:type type :content content :customization-color customization-color}]
[notification-indicator
{:status status
:customization-color customization-color
:mention-count (:mention-count content)}]])

View File

@ -1,6 +0,0 @@
(ns quo.components.switchers.card-main-info.style
(:require
[quo.foundations.colors :as colors]))
(def subtitle
{:color colors/neutral-40})

View File

@ -1,22 +0,0 @@
(ns quo.components.switchers.card-main-info.view
(:require
[quo.components.markdown.text :as text]
[quo.components.switchers.card-main-info.style :as style]
[react-native.core :as rn]))
(defn view
[{:keys [title subtitle]}]
[rn/view
[text/text
{:accessibility-label :title
:size :paragraph-1
:weight :semi-bold
:number-of-lines 1
:ellipsize-mode :tail}
title]
[text/text
{:accessibility-label :subtitle
:size :paragraph-2
:weight :medium
:style style/subtitle}
subtitle]])

View File

@ -1,117 +0,0 @@
(ns quo.components.switchers.group-messaging-card.component-spec
(:require
[quo.components.switchers.group-messaging-card.view :as group-messaging-card]
[quo.components.switchers.utils :as utils]
[test-helpers.component :as h]))
(def photos-list
[{:source (js/require "../resources/images/mock2/photo1.png")}
{:source (js/require "../resources/images/mock2/photo2.png")}
{:source (js/require "../resources/images/mock2/photo3.png")}
{:source (js/require "../resources/images/mock2/photo1.png")}
{:source (js/require "../resources/images/mock2/photo2.png")}
{:source (js/require "../resources/images/mock2/photo3.png")}])
(def sticker {:source (js/require "../resources/images/mock2/sticker.png")})
(def gif {:source (js/require "../resources/images/mock2/gif.png")})
(def coinbase-community (js/require "../resources/images/mock2/coinbase.png"))
(def link-icon (js/require "../resources/images/mock2/status-logo.png"))
(h/describe "Switcher: Group Messaging Card"
(h/test "Default render"
(h/render [group-messaging-card/view {}])
(h/is-truthy (h/query-by-label-text :base-card)))
(h/test "Avatar render"
(h/render [group-messaging-card/view {:avatar true}])
(h/is-truthy (h/query-by-label-text :group-avatar)))
(h/test "Status: Read, Type: Message, Avatar: true"
(h/render [group-messaging-card/view
{:avatar true
:status :read
:type :message
:title "Title"
:content {:text "Last message"}}])
(h/is-truthy (h/get-by-text "Title"))
(h/is-truthy (h/get-by-text (utils/subtitle :message nil)))
(h/is-truthy (h/get-by-text "Last message")))
(h/test "Status: Unread, Type: Message, Avatar: true"
(h/render [group-messaging-card/view
{:avatar true
:status :unread
:type :message
:title "Title"}])
(h/is-truthy (h/query-by-label-text :notification-dot)))
(h/test "Status: Mention, Type: Message, Avatar: true"
(h/render [group-messaging-card/view
{:avatar true
:status :mention
:type :message
:title "Title"
:content {:mention-count 5}}])
(h/is-truthy (h/get-by-test-id :counter-component)))
(h/test "Status: Read, Type: Photo, Avatar: true"
(h/render [group-messaging-card/view
{:avatar true
:status :read
:type :photo
:title "Title"
:content {:photos photos-list}}])
(h/is-truthy (h/get-by-text (utils/subtitle :photo {:photos photos-list}))))
(h/test "Status: Read, Type: Stciker, Avatar: true"
(h/render [group-messaging-card/view
{:avatar true
:status :read
:type :sticker
:title "Title"
:content sticker}])
(h/is-truthy (h/get-by-text (utils/subtitle :sticker nil)))
(h/is-truthy (h/get-by-label-text :sticker)))
(h/test "Status: Read, Type: Gif, Avatar: true"
(h/render [group-messaging-card/view
{:avatar true
:status :read
:type :gif
:title "Title"
:content gif}])
(h/is-truthy (h/get-by-text (utils/subtitle :gif nil)))
(h/is-truthy (h/get-by-label-text :gif)))
(h/test "Status: Read, Type: Audio, Avatar: true"
(h/render-with-theme-provider [group-messaging-card/view
{:avatar true
:status :read
:type :audio
:title "Title"
:content {:duration "00:32"}}])
(h/is-truthy (h/get-by-text (utils/subtitle :audio nil)))
(h/is-truthy (h/get-by-text "00:32")))
(h/test "Status: Read, Type: Community, Avatar: true"
(h/render-with-theme-provider [group-messaging-card/view
{:avatar true
:status :read
:type :community
:title "Title"
:content {:community-avatar coinbase-community
:community-name "Coinbase"}}])
(h/is-truthy (h/get-by-text (utils/subtitle :community nil)))
(h/is-truthy (h/get-by-label-text :group-avatar))
(h/is-truthy (h/get-by-text "Coinbase")))
(h/test "Status: Read, Type: Link, Avatar: true"
(h/render-with-theme-provider [group-messaging-card/view
{:avatar true
:status :read
:type :link
:title "Title"
:content {:icon :placeholder
:text "Rolling St..."}}])
(h/is-truthy (h/get-by-text (utils/subtitle :link nil)))
(h/is-truthy (h/get-by-label-text :group-avatar))
(h/is-truthy (h/get-by-text "Rolling St..."))))

View File

@ -1,17 +0,0 @@
(ns quo.components.switchers.group-messaging-card.style
(:require
[quo.foundations.colors :as colors]))
(def avatar-container
{:left 10
:top -30
:border-radius 48
:border-width 2
:border-color colors/neutral-95
:position :absolute})
(def content-container
{:flex 1
:flex-direction :column
:justify-content :space-between
:margin-top 16})

View File

@ -1,32 +0,0 @@
(ns quo.components.switchers.group-messaging-card.view
(:require
[quo.components.avatars.group-avatar.view :as group-avatar]
[quo.components.switchers.base-card.view :as base-card]
[quo.components.switchers.card-content.view :as card-content]
[quo.components.switchers.card-main-info.view :as card-main-info]
[quo.components.switchers.group-messaging-card.style :as style]
[quo.components.switchers.utils :as utils]
[react-native.core :as rn]))
(defn view
"Opts:
:type - keyword -> :message/:photo/:sticker/:gif/:audio/:community/:link/:code
:status - keyword -> :read/:unread/:mention
:profile-color -> keyword or hexstring -> :blue/:army/... or #ABCEDF
:customization-color -> keyword or hexstring -> :blue/:army/... or #ABCEDF"
[{:keys [avatar type status title profile-color customization-color on-close content]
:or {profile-color :blue avatar nil}}]
[base-card/base-card
{:customization-color customization-color
:on-close on-close}
[rn/view {:style style/avatar-container}
[group-avatar/view
{:customization-color customization-color
:picture avatar
:icon-name :i/members
:size :size-48}]]
[rn/view {:style style/content-container}
[card-main-info/view
{:title title
:subtitle (utils/subtitle type content)}]
[card-content/view type status profile-color content]]])

View File

@ -1,36 +0,0 @@
(ns quo.components.switchers.utils
(:require
[utils.i18n :as i18n]))
(defn subtitle
[type {:keys [photos]}]
(case type
:message
(i18n/label :t/message)
:photo
(i18n/label
(if (= (count photos) 1)
:t/one-photo
:t/n-photos)
{:count (count photos)})
:sticker
(i18n/label :t/sticker)
:gif
(i18n/label :t/gif)
:audio
(i18n/label :t/audio-message)
:community
(i18n/label :t/link-to-community)
:link
(i18n/label :t/external-link)
:code
(i18n/label :t/code-snippet)
""))

View File

@ -149,7 +149,6 @@
quo.components.share.qr-code.view
quo.components.share.share-qr-code.view
quo.components.slideshow.slider-bar.view
quo.components.switchers.group-messaging-card.view
quo.components.tabs.account-selector
quo.components.tabs.segmented-tab
quo.components.tabs.tabs.view
@ -426,9 +425,6 @@
;;;; Slideshow
(def slider-bar quo.components.slideshow.slider-bar.view/view)
;;;; SWITCHER
(def group-messaging-card quo.components.switchers.group-messaging-card.view/view)
;;;; Tabs
(def tabs quo.components.tabs.tabs.view/view)
(def segmented-control quo.components.tabs.segmented-tab/segmented-control)

View File

@ -89,8 +89,6 @@
quo.components.settings.settings-item.component-spec
quo.components.share.share-qr-code.component-spec
quo.components.slideshow.slider-bar.component-spec
quo.components.switchers.base-card.component-spec
quo.components.switchers.group-messaging-card.component-spec
quo.components.tags.collectible-tag.component-spec
quo.components.tags.network-tags.component-spec
quo.components.tags.status-tags-component-spec

View File

@ -25,9 +25,8 @@
"[top-nav props]
props
{:blur? true/false
:jump-to? true/false
:container-style passed to outer view of component}"
[{:keys [container-style blur? jump-to?]}]
[{:keys [container-style blur?]}]
(let [{:keys [public-key] :as profile} (rf/sub [:profile/profile-with-image])
online? (rf/sub [:visibility-status-updates/online?
public-key])
@ -61,7 +60,6 @@
{:initial-tab initial-share-tab}])
:container-style (merge style/top-nav-container container-style)
:blur? blur?
:jump-to? jump-to?
:customization-color customization-color
:avatar-props avatar
:max-unread-notifications constants/activity-center-max-unread-count

View File

@ -54,8 +54,6 @@
:keycard-chip
{:light (js/require "../resources/images/ui2/keycard-chip-light.png")
:dark (js/require "../resources/images/ui2/keycard-chip-dark.png")}
:jump-to
{:dark (js/require "../resources/images/ui2/jump-to-dark.png")}
:no-group-chats
{:light (js/require "../resources/images/ui2/no-group-chats-light.png")
:dark (js/require "../resources/images/ui2/no-group-chats-dark.png")}

View File

@ -2,7 +2,6 @@
(:require
[react-native.async-storage :as async-storage]
[status-im.contexts.chat.messenger.messages.list.state :as chat.state]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
[utils.re-frame :as rf]))
(rf/reg-fx :effects.chat/open-last-chat
@ -15,8 +14,7 @@
:key-uid
(fn [stored-key-uid]
(when (= stored-key-uid key-uid)
(rf/dispatch [:chat/pop-to-root-and-navigate-to-chat chat-id
shell.constants/open-screen-without-animation])))))))))
(rf/dispatch [:chat/pop-to-root-and-navigate-to-chat chat-id])))))))))
(rf/reg-fx :effects.chat/scroll-to-bottom
(fn []

View File

@ -203,7 +203,7 @@
[{db :db :as cofx} chat-id animation]
(rf/merge cofx
(when-not (:current-chat-id db)
{:dispatch [(if animation :shell/navigate-to :navigate-to) :chat chat-id animation]})
{:dispatch [:navigate-to :chat {:animation animation}]})
(close-chat chat-id)
(force-close-chat chat-id)
(fn [{:keys [db]}]
@ -270,9 +270,7 @@
{:events [:chat.ui/close-and-remove-chat]}
[{:keys [db now] :as cofx} chat-id]
(rf/merge cofx
{:effects/push-notifications-clear-message-notifications [chat-id]
:dispatch [:shell/close-switcher-card
chat-id]}
{:effects/push-notifications-clear-message-notifications [chat-id]}
(deactivate-chat chat-id)
(offload-messages chat-id)))

View File

@ -39,7 +39,3 @@
:margin-bottom bottom
:background-color (colors/theme-colors colors/white colors/neutral-95-opa-70 theme)
:flex-direction :row})
(def floating-shell-button
{:position :absolute
:bottom 21})

View File

@ -12,7 +12,6 @@
[status-im.common.home.actions.view :as actions]
[status-im.constants :as constants]
[status-im.contexts.chat.group.details.style :as style]
[status-im.feature-flags :as ff]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@ -131,7 +130,6 @@
members (rf/sub [:contacts/group-members-sections chat-id])
pinned-messages (rf/sub [:chats/pinned chat-id])
current-pk (rf/sub [:multiaccount/public-key])
profile-color (rf/sub [:profile/customization-color])
admin? (get admins current-pk)]
[:<>
[quo/gradient-cover
@ -188,10 +186,4 @@
:render-data {:chat-id chat-id
:admin? admin?}
:render-fn contact-item-render
:separator [rn/view {:style {:height 4}}]}]
(when (ff/enabled? ::ff/shell.jump-to)
[quo/floating-shell-button
{:jump-to {:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
:customization-color profile-color
:label (i18n/label :t/jump-to)}}
style/floating-shell-button])]))
:separator [rn/view {:style {:height 4}}]}]]))

View File

@ -15,7 +15,7 @@
[status-im.contexts.chat.actions.view :as chat.actions.view]
[status-im.contexts.chat.home.chat-list-item.view :as chat-list-item]
[status-im.contexts.chat.home.contact-request.view :as contact-request]
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]
[status-im.contexts.shell.constants :as shell.constants]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@ -66,7 +66,7 @@
(chat-list-item/chat-list-item item theme))
:scroll-event-throttle 8
:content-container-style {:padding-bottom
jump-to.constants/floating-shell-button-height
shell.constants/floating-shell-button-height
:padding-top 8}
:on-scroll #(common.banner/set-scroll-shared-value
{:scroll-input (oops/oget % "nativeEvent.contentOffset.y")

View File

@ -3,9 +3,7 @@
[quo.foundations.colors :as colors]
[quo.foundations.typography :as typography]
[react-native.reanimated :as reanimated]
[status-im.contexts.chat.messenger.composer.constants :as constants]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
[status-im.feature-flags :as ff]))
[status-im.contexts.chat.messenger.composer.constants :as constants]))
(def border-top-radius 20)
@ -41,13 +39,6 @@
:opacity opacity}
{}))
(defn shell-button-container
[]
{:z-index 1
:top (if (ff/enabled? ::ff/shell.jump-to)
0
(- shell.constants/floating-shell-button-height))})
(def scroll-to-bottom-button
{:position :absolute
:right 0

View File

@ -4,15 +4,12 @@
[react-native.core :as rn]
[status-im.constants :as constants]
[status-im.contexts.chat.messenger.messages.contact-requests.bottom-drawer.style :as style]
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]
[status-im.feature-flags :as ff]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn view
[{:keys [contact-id]}]
(let [customization-color (rf/sub [:profile/customization-color])
{:keys [contact-request-state
(let [{:keys [contact-request-state
community-id
chat-name]} (rf/sub [:chats/current-chat-chat-view])
chat-type (rf/sub [:chats/chat-type])
@ -68,12 +65,4 @@
(i18n/label :t/contact-request-chat-received {:name primary-name})
contact-request-pending?
(i18n/label :t/contact-request-chat-pending))}]
(when (ff/enabled? ::ff/shell.jump-to)
[quo/floating-shell-button
{:jump-to
{:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
:customization-color customization-color
:label (i18n/label :t/jump-to)}}
{:position :absolute
:top (- jump-to.constants/floating-shell-button-height)}])]))
(i18n/label :t/contact-request-chat-pending))}]]))

View File

@ -16,8 +16,6 @@
[status-im.contexts.chat.messenger.messages.content.view :as message]
[status-im.contexts.chat.messenger.messages.list.state :as state]
[status-im.contexts.chat.messenger.messages.list.style :as style]
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]
[status-im.feature-flags :as ff]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.worklets.chat.messenger.messages :as worklets]))
@ -72,9 +70,6 @@
[{:keys [insets able-to-send-message? images reply edit link-previews? input-content-height]}]
(if able-to-send-message?
(cond-> composer.constants/composer-default-height
(ff/enabled? ::ff/shell.jump-to)
(+ jump-to.constants/floating-shell-button-height)
(seq images)
(+ composer.constants/images-container-height)

View File

@ -1,6 +1,6 @@
(ns status-im.contexts.chat.messenger.messages.scroll-to-bottom.style
(:require [react-native.safe-area :as safe-area]
[status-im.contexts.shell.jump-to.constants :as shell.constants]))
[status-im.contexts.shell.constants :as shell.constants]))
(def ^:private bottom-drawer-height 46)

View File

@ -15,7 +15,6 @@
[status-im.contexts.chat.messenger.messages.navigation.view :as messages.navigation]
[status-im.contexts.chat.messenger.messages.scroll-to-bottom.view :as scroll-to-bottom]
[status-im.contexts.chat.messenger.placeholder.view :as placeholder.view]
[status-im.feature-flags :as ff]
[utils.re-frame :as rf]))
(defn- footer
@ -55,14 +54,9 @@
(let [on-layout-done? (reagent/atom false)
first-render-done? (reagent/atom false)]
(fn []
(let [chat-exists? (rf/sub [:chats/current-chat-exist?])
jump-to-enabled? (ff/enabled? ::ff/shell.jump-to)
screen-loaded-for-jump-to? (rf/sub [:shell/chat-screen-loaded?])
screen-loaded? (if jump-to-enabled?
screen-loaded-for-jump-to?
@first-render-done?)]
(let [chat-exists? (rf/sub [:chats/current-chat-exist?])]
(rn/use-mount #(reset! first-render-done? true))
[:<>
(when (and chat-exists? screen-loaded?)
(when (and chat-exists? @first-render-done?)
[chat-screen on-layout-done?])
[placeholder.view/view on-layout-done?]]))))

View File

@ -7,8 +7,3 @@
(def text-combinations {:margin-top 12 :margin-horizontal 20})
(def wrapper {:padding 20})
(def floating-shell-button
{:position :absolute
:bottom 34
:z-index 3})

View File

@ -8,7 +8,6 @@
[status-im.common.home.actions.view :as home.actions]
[status-im.constants :as constants]
[status-im.contexts.communities.actions.channel-view-details.style :as style]
[status-im.feature-flags :as ff]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@ -87,12 +86,6 @@
(rn/use-mount (fn []
(rf/dispatch [:pin-message/load-pin-messages chat-id])))
[:<>
(when (ff/enabled? ::ff/shell.jump-to)
[quo/floating-shell-button
{:jump-to {:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
:customization-color color
:label (i18n/label :t/jump-to)}}
style/floating-shell-button])
[quo/gradient-cover {:customization-color color :opacity 0.4}]
[quo/page-nav
{:background :blur

View File

@ -37,7 +37,6 @@
(let [community-chat-ids (map #(str community-id %)
(keys (get-in db [:communities community-id :chats])))]
{:effects/push-notifications-clear-message-notifications community-chat-ids
:dispatch [:shell/close-switcher-card community-id]
:json-rpc/call
[{:method "wakuext_leaveCommunity"
:params [community-id]

View File

@ -1,6 +1,6 @@
(ns status-im.contexts.communities.discover.style
(:require
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]))
[status-im.contexts.shell.constants :as shell.constants]))
(def header-height 56)
@ -36,7 +36,7 @@
(def other-communities-container
{:flex 1
:padding-bottom (+ jump-to.constants/floating-shell-button-height 34)
:padding-bottom (+ shell.constants/floating-shell-button-height 34)
:margin-horizontal 20})
(defn discover-communities-segments
@ -74,7 +74,3 @@
:justify-content :center
:flex 1
:background-color :transparent})
(def floating-shell-button
{:position :absolute
:bottom 34})

View File

@ -11,7 +11,6 @@
[status-im.config :as config]
[status-im.contexts.communities.actions.community-options.view :as options]
[status-im.contexts.communities.discover.style :as style]
[status-im.feature-flags :as ff]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@ -233,18 +232,11 @@
(defn view
[]
(let [theme (quo.theme/use-theme)
featured-communities (rf/sub [:communities/featured-contract-communities])
customization-color (rf/sub [:profile/customization-color])]
featured-communities (rf/sub [:communities/featured-contract-communities])]
(rn/use-mount #(rf/dispatch [:fetch-contract-communities]))
[rn/view
{:style (style/discover-screen-container (colors/theme-colors
colors/white
colors/neutral-95
theme))}
[discover-screen-content featured-communities theme]
(when (ff/enabled? ::ff/shell.jump-to)
[quo/floating-shell-button
{:jump-to {:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
:customization-color customization-color
:label (i18n/label :t/jump-to)}}
style/floating-shell-button])]))
[discover-screen-content featured-communities theme]]))

View File

@ -11,7 +11,6 @@
status-im.contexts.communities.actions.community-options.events
status-im.contexts.communities.actions.leave.events
[status-im.contexts.communities.utils :as utils]
[status-im.feature-flags :as ff]
[status-im.navigation.events :as navigation]
[status-im.navigation.transitions :as transitions]
[taoensso.timbre :as log]
@ -356,9 +355,7 @@
(if pop-to-root?
[:dispatch [:chat/pop-to-root-and-navigate-to-chat chat-id]]
[:dispatch
[:chat/navigate-to-chat chat-id
(when-not (ff/enabled? ::ff/shell.jump-to)
transitions/stack-slide-transition)]])]}
[:chat/navigate-to-chat chat-id transitions/stack-slide-transition]])]}
(when-not (get-in db [:chats chat-id :community-id])
{:db (assoc-in db [:chats chat-id :community-id] community-id)}))))

View File

@ -12,7 +12,7 @@
[status-im.config :as config]
[status-im.contexts.communities.actions.community-options.view :as options]
[status-im.contexts.communities.actions.home-plus.view :as actions.home-plus]
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]
[status-im.contexts.shell.constants :as shell.constants]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.number]
@ -114,7 +114,7 @@
:data selected-items
:scroll-event-throttle 8
:content-container-style {:padding-bottom
jump-to.constants/floating-shell-button-height}
shell.constants/floating-shell-button-height}
:on-scroll on-scroll}])
[common.banner/animated-banner
{:content banner-data

View File

@ -1,6 +1,6 @@
(ns status-im.contexts.communities.overview.style
(:require
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]))
[status-im.contexts.shell.constants :as shell.constants]))
(def screen-horizontal-padding 20)
@ -35,12 +35,8 @@
:right 0
:bottom 0})
(def floating-shell-button
{:position :absolute
:bottom 21})
(defn channel-list-component
[]
{:margin-top 8
:margin-bottom (+ 21 jump-to.constants/floating-shell-button-height)
:margin-bottom (+ 21 shell.constants/floating-shell-button-height)
:flex 1})

View File

@ -17,7 +17,6 @@
[status-im.contexts.communities.actions.community-options.view :as options]
[status-im.contexts.communities.overview.style :as style]
[status-im.contexts.communities.utils :as communities.utils]
[status-im.feature-flags :as ff]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@ -373,13 +372,6 @@
(defn view
[id]
(let [id (or id (rf/sub [:get-screen-params :community-overview]))
customization-color (rf/sub [:profile/customization-color])]
(let [id (or id (rf/sub [:get-screen-params :community-overview]))]
[rn/view {:style style/community-overview-container}
[community-card-page-view id]
(when (ff/enabled? ::ff/shell.jump-to)
[quo/floating-shell-button
{:jump-to {:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
:customization-color customization-color
:label (i18n/label :t/jump-to)}}
style/floating-shell-button])]))
[community-card-page-view id]]))

View File

@ -1,8 +1,6 @@
(ns status-im.contexts.onboarding.common.background.view
(:require
[oops.core :refer [oget]]
[quo.core :as quo]
[react-native.async-storage :as async-storage]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
@ -10,7 +8,6 @@
[status-im.contexts.onboarding.common.background.style :as style]
[status-im.contexts.onboarding.common.carousel.animation :as carousel.animation]
[status-im.contexts.onboarding.common.carousel.view :as carousel]
[status-im.contexts.shell.jump-to.state :as shell.state]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@ -37,24 +34,6 @@
(defonce is-dragging? (atom nil))
(defonce drag-amount (atom nil))
;; Layout height calculation
;; 1. Always prefer on-layout height over window height, as some devices include status bar height in
;; the window while others do not.
;; https://github.com/status-im/status-mobile/issues/14633#issuecomment-1366191478
;; 2. This preference is unless on-layout is triggered with a random value.
;; https://github.com/status-im/status-mobile/issues/14849
;; To ensure that on-layout height falls within the actual height range, a difference between window
;; height and the maximum possible status bar height is allowed (assumed to be 60, as the Pixel emulator
;; has a height of 52).
(defn store-screen-height
[evt]
(let [window-height (or (:height (rn/get-window)) 0)
height (or (oget evt "nativeEvent" "layout" "height") 0)]
(when (and (not= height @shell.state/screen-height)
(< (Math/abs (- window-height height)) 60))
(reset! shell.state/screen-height height)
(async-storage/set-item! :screen-height height))))
(defn view
[dark-overlay?]
(let [view-id (rf/sub [:view-id])
@ -72,8 +51,7 @@
[view-id])
[rn/view
{:style style/background-container
:on-layout store-screen-height}
{:style style/background-container}
[carousel/view
{:animate? animate?
:progress progress

View File

@ -5,8 +5,6 @@
[react-native.safe-area :as safe-area]
[status-im.common.resources :as resources]
[status-im.contexts.onboarding.enable-notifications.style :as style]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
[status-im.contexts.shell.jump-to.utils :as shell.utils]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@ -19,26 +17,21 @@
:description (i18n/label :t/enable-notifications-sub-title)
:description-accessibility-label :notifications-sub-title}])
(defn- finish-onboarding
[notifications-enabled?]
(rf/dispatch [:push-notifications/switch notifications-enabled?])
(shell.utils/change-selected-stack-id shell.constants/default-selected-stack true nil)
(rf/dispatch [:update-theme-and-init-root :shell-stack])
(rf/dispatch [:profile/show-testnet-mode-banner-if-enabled])
(rf/dispatch [:universal-links/process-stored-event]))
(defn enable-notification-buttons
[{:keys [insets]}]
(let [profile-color (rf/sub [:onboarding/customization-color])
ask-permission (fn []
(rf/dispatch [:request-notifications
(rf/dispatch
[:request-notifications
{:on-allowed (fn []
(js/setTimeout #(finish-onboarding true)
(js/setTimeout
#(rf/dispatch [:onboarding/finish-onboarding true])
300))
:on-denied (fn []
(js/setTimeout #(finish-onboarding false)
(js/setTimeout
#(rf/dispatch [:onboarding/finish-onboarding false])
300))}]))
skip-permission #(finish-onboarding false)]
skip-permission #(rf/dispatch [:onboarding/finish-onboarding false])]
[rn/view {:style (style/buttons insets)}
[quo/button
{:on-press ask-permission

View File

@ -5,11 +5,22 @@
[status-im.constants :as constants]
[status-im.contexts.profile.create.events :as profile.create]
[status-im.contexts.profile.recover.events :as profile.recover]
[status-im.contexts.shell.constants :as shell.constants]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.security.core :as security]))
(rf/reg-event-fx
:onboarding/finish-onboarding
(fn [_ [notifications-enabled?]]
{:fx [(when notifications-enabled?
[:dispatch [:push-notifications/switch true]])
[:dispatch [:shell/change-tab shell.constants/default-selected-stack]]
[:dispatch [:update-theme-and-init-root :shell-stack]]
[:dispatch [:profile/show-testnet-mode-banner-if-enabled]]
[:dispatch [:universal-links/process-stored-event]]]}))
(rf/reg-event-fx
:onboarding/profile-data-set
(fn [{:keys [db]} [onboarding-data]]

View File

@ -8,8 +8,7 @@
(def descriptor
[{:key :type
:type :select
:options [{:key :jump-to}
{:key :mention}
:options [{:key :mention}
{:key :notification-down}
{:key :notification-up}
{:key :search}
@ -21,9 +20,8 @@
(defn view
[]
(let [state (reagent/atom {:count "5"
:type :jump-to
:labels {:jump-to (i18n/label :t/jump-to)
:search-with-label (i18n/label :t/back)}})]
:type :search-with-label
:labels {:search-with-label (i18n/label :t/back)}})]
(fn []
[preview/preview-container
{:state state

View File

@ -172,9 +172,6 @@
[status-im.contexts.preview.quo.share.share-qr-code :as share-qr-code]
[status-im.contexts.preview.quo.slideshow.slider-bar :as slider-bar]
[status-im.contexts.preview.quo.style :as style]
[status-im.contexts.preview.quo.switcher.group-messaging-card :as
group-messaging-card]
[status-im.contexts.preview.quo.switcher.switcher-cards :as switcher-cards]
[status-im.contexts.preview.quo.tabs.account-selector :as account-selector]
[status-im.contexts.preview.quo.tabs.segmented-tab :as segmented]
[status-im.contexts.preview.quo.tabs.tabs :as tabs]
@ -507,10 +504,6 @@
:component share-qr-code/view}]
:slideshow [{:name :slider-bar
:component slider-bar/view}]
:switchers [{:name :group-messaging-card
:component group-messaging-card/view}
{:name :switcher-cards
:component switcher-cards/view}]
:tabs [{:name :segmented
:component segmented/view}
{:name :tabs

View File

@ -2,12 +2,10 @@
(:require
[quo.core :as quo]
[reagent.core :as reagent]
[status-im.contexts.preview.quo.preview :as preview]
[utils.i18n :as i18n]))
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
[{:key :show-jump-to? :type :boolean}
{:key :show-search? :type :boolean}
[{:key :show-search? :type :boolean}
{:key :show-mention? :type :boolean}
{:key :scroll-type
:type :select
@ -16,10 +14,8 @@
{:key :scroll-to-bottom}]}])
(defn mock-data
[{:keys [show-jump-to? show-search? show-mention? scroll-type]}]
[{:keys [show-search? show-mention? scroll-type]}]
(cond-> {}
show-jump-to?
(assoc :jump-to {:on-press #() :label (i18n/label :t/jump-to)})
show-search?
(assoc :search {:on-press #()})
show-mention?
@ -33,8 +29,7 @@
(defn view
[]
(let [state (reagent/atom {:show-jump-to? true
:scroll-type :notification-down})]
(let [state (reagent/atom {:scroll-type :notification-down})]
(fn []
[preview/preview-container
{:state state

View File

@ -1,7 +1,6 @@
(ns status-im.contexts.preview.quo.navigation.top-nav
(:require
[quo.core :as quo]
[quo.foundations.colors :as colors]
[reagent.core :as reagent]
[status-im.common.resources :as resources]
[status-im.contexts.preview.quo.preview :as preview]))
@ -14,8 +13,6 @@
{:key :seen}]}
{:key :blur?
:type :boolean}
{:key :jump-to?
:type :boolean}
{:key :notification-count
:type :number}
(preview/customization-color-option)])
@ -27,17 +24,15 @@
(fn []
(let [blur? (:blur? @state)
customization-color (:customization-color @state)
jump-to? (:jump-to? @state)
notification (:notification @state)
notification-count (:notification-count @state)]
[preview/preview-container
{:state state
:descriptor descriptor
:blur? (and blur? (not jump-to?))
:show-blur-background? (and blur? (not jump-to?))
:blur? blur?
:show-blur-background? blur?
:component-container-style {:padding-vertical 60
:padding-horizontal 20
:background-color (when jump-to? colors/neutral-100)}}
:padding-horizontal 20}}
[quo/top-nav
{:container-style {:flex 1 :z-index 2}
:max-unread-notifications 99
@ -45,7 +40,6 @@
:notification notification
:customization-color customization-color
:notification-count notification-count
:jump-to? jump-to?
:avatar-props {:online? true
:full-name "Test User"
:profile-picture (resources/mock-images :user-picture-female2)}

View File

@ -1,114 +0,0 @@
(ns status-im.contexts.preview.quo.switcher.group-messaging-card
(:require
[quo.core :as quo]
[reagent.core :as reagent]
[status-im.common.resources :as resources]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
[{:key :title :type :text}
{:key :status
:type :select
:options [{:key :read}
{:key :unread}
{:key :mention}]}
{:key :counter-label :type :text}
{:key :type
:type :select
:options [{:key :message
:value :text}
{:key :photo}
{:key :sticker}
{:key :gif}
{:key :audio}
{:key :community}
{:key :link}
{:key :code
:value :code-snippet}]}
{:key :last-message :type :text}
{:key :avatar? :type :boolean}
(preview/customization-color-option)])
;; Mock data
(def sticker {:source (resources/get-mock-image :sticker)})
(def community-avatar (resources/get-mock-image :community-logo))
(def gif {:source (resources/get-mock-image :gif)})
(def coinbase-community (resources/get-mock-image :coinbase))
(def photos-list
[{:source (resources/get-mock-image :photo1)}
{:source (resources/get-mock-image :photo2)}
{:source (resources/get-mock-image :photo3)}
{:source (resources/get-mock-image :photo1)}
{:source (resources/get-mock-image :photo2)}
{:source (resources/get-mock-image :photo3)}])
(def clojure-example
"(defn request->xhrio-options
[{:as request
:keys [on-success on-failure]
:or {on-success [:http-no-on-success]
on-failure [:http-no-on-failure]}}]
; wrap events in cljs-ajax callback
(let [api (new goog.net.XhrIo)]
(-> request
(assoc
:api api
:handler (partial ajax-xhrio-handler
#(dispatch (conj on-success %))
#(dispatch (conj on-failure %))
api))
(dissoc :on-success :on-failure :on-request))))")
(defn get-mock-content
[data]
(case (:type data)
:message
{:text (:last-message data)}
:photo
{:photos photos-list}
:sticker
sticker
:gif
gif
:audio
{:duration "00:32"}
:community
{:community-avatar coinbase-community
:community-name "Coinbase"}
:link
{:icon :placeholder
:text "Rolling St..."}
:code
{:language :clojure
:text clojure-example}
nil))
(defn get-mock-data
[data]
(merge
data
{:content (merge (get-mock-content data)
{:mention-count (when (= (:status data) :mention) (:counter-label data))})}))
(defn view
[]
(let [state (reagent/atom {:title "Hester, John, Steven, and 2 others"
:type :message
:status :read
:last-message "Hello there, there is a new message"
:customization-color :camel
:avatar? false
:counter-label 5})]
(fn []
[preview/preview-container {:state state :descriptor descriptor}
[quo/group-messaging-card
(cond-> (get-mock-data @state)
(:avatar? @state)
(assoc :avatar community-avatar))]])))

View File

@ -1,146 +0,0 @@
(ns status-im.contexts.preview.quo.switcher.switcher-cards
(:require
[quo.foundations.colors :as colors]
[reagent.core :as reagent]
[status-im.common.resources :as resources]
[status-im.constants :as constants]
[status-im.contexts.preview.quo.preview :as preview]
[status-im.contexts.shell.jump-to.components.switcher-cards.view :as switcher-cards]
[status-im.contexts.shell.jump-to.constants :as shell.constants]))
(def descriptor
[{:key :type
:type :select
:options [{:key shell.constants/communities-discover
:value "Communities Discover"}
{:key shell.constants/one-to-one-chat-card
:value "Messaging"}
{:key shell.constants/private-group-chat-card
:value "Group Messaging"}
{:key shell.constants/community-card
:value "Community Card"}
{:key shell.constants/community-channel-card
:value "Community Channel Card"}
{:key shell.constants/browser-card
:value "Browser Card"}
{:key shell.constants/wallet-card
:value "Wallet Card"}
{:key shell.constants/wallet-collectible
:value "Wallet Collectible"}
{:key shell.constants/wallet-graph
:value "Wallet Graph"}
{:key shell.constants/empty-card
:value "Empty Card"}]}
{:key :title :type :text}
{:key :new-notifications? :type :boolean}
{:key :banner? :type :boolean}
{:key :notification-indicator
:type :select
:options [{:key :counter}
{:key :unread-dot}]}
{:key :counter-label :type :text}
{:key :content-type
:type :select
:options [{:key constants/content-type-text
:value :text}
{:key constants/content-type-image
:value :photo}
{:key constants/content-type-sticker
:value :sticker}
{:key constants/content-type-gif
:value :gif}
{:key constants/content-type-audio
:value :audio}
{:key constants/content-type-community
:value :community}
{:key constants/content-type-link
:value :link}]}
{:key :last-message :type :text}
(preview/customization-color-option)])
;; Mocked Data
(def banner (resources/get-mock-image :community-banner))
(def sticker {:source (resources/get-mock-image :sticker)})
(def community-avatar {:source (resources/get-mock-image :community-logo)})
(def gif {:source (resources/get-mock-image :gif)})
(def coinbase-community (resources/get-mock-image :coinbase))
(def photos-list
[{:source (resources/get-mock-image :photo1)}
{:source (resources/get-mock-image :photo2)}
{:source (resources/get-mock-image :photo3)}
{:source (resources/get-mock-image :photo1)}
{:source (resources/get-mock-image :photo2)}
{:source (resources/get-mock-image :photo3)}])
(defn get-mock-content
[data]
(condp = (:content-type data)
constants/content-type-text
(:last-message data)
constants/content-type-image
photos-list
constants/content-type-sticker
sticker
constants/content-type-gif
gif
constants/content-type-audio
"00:32"
constants/content-type-community
{:avatar coinbase-community
:community-name "Coinbase"}
constants/content-type-link
nil))
(defn get-mock-data
[{:keys [type] :as data}]
(merge
data
{:type type
:banner (when (:banner? data) banner)
:content {:new-notifications? (:new-notifications? data)
:notification-indicator (:notification-indicator data)
:counter-label (:counter-label data)
:content-type (:content-type data)
:community-channel {:emoji "🍑" :channel-name "# random"}
:community-info {:type :kicked}
:data (get-mock-content data)}}
(cond
(= type shell.constants/one-to-one-chat-card)
{:avatar-params {:full-name (:title data)}}
(= type shell.constants/private-group-chat-card)
{}
(#{shell.constants/community-card
shell.constants/community-channel-card}
type)
{:avatar-params community-avatar}
:else
{})))
(defn view
[]
(let [state (reagent/atom {:type shell.constants/private-group-chat-card
:title "Alisher Yakupov"
:customization-color :turquoise
:new-notifications? true
:banner? false
:notification-indicator :counter
:counter-label 2
:content-type constants/content-type-text
:last-message "This is fantastic! Ethereum"
:preview-label-color colors/white})]
(fn []
[preview/preview-container
{:state state
:descriptor descriptor
:component-container-style {:padding-vertical 60}}
[switcher-cards/card (get-mock-data @state)]])))

View File

@ -1,15 +1,10 @@
(ns status-im.contexts.profile.contact.view
(:require [quo.core :as quo]
[quo.foundations.colors :as colors]
(:require [quo.foundations.colors :as colors]
[quo.theme]
[react-native.reanimated :as reanimated]
[status-im.common.scroll-page.view :as scroll-page]
[status-im.contexts.profile.contact.actions.view :as actions]
[status-im.contexts.profile.contact.header.view :as contact-header]
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]
[status-im.feature-flags :as ff]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn on-show-actions
@ -17,15 +12,9 @@
(rf/dispatch [:show-bottom-sheet
{:content (fn [] [actions/view])}]))
(defn on-jump-to
[]
(rf/dispatch [:navigate-back])
(debounce/throttle-and-dispatch [:shell/navigate-to-jump-to] 500))
(defn view
[]
(let [{:keys [customization-color]} (rf/sub [:contacts/current-contact])
profile-customization-color (rf/sub [:profile/customization-color])
scroll-y (reanimated/use-shared-value 0)
theme (quo.theme/use-theme)]
[:<>
@ -40,12 +29,4 @@
:page-nav-props {:right-side [{:icon-name :i/options
:on-press on-show-actions
:accessibility-label :contact-actions}]}}
[contact-header/view {:scroll-y scroll-y}]]
(when (ff/enabled? ::ff/shell.jump-to)
[quo/floating-shell-button
{:jump-to
{:on-press on-jump-to
:customization-color profile-customization-color
:label (i18n/label :t/jump-to)}}
{:position :absolute
:bottom jump-to.constants/floating-shell-button-height}])]))
[contact-header/view {:scroll-y scroll-y}]]]))

View File

@ -6,7 +6,6 @@
[status-im.config :as config]
status-im.contexts.profile.login.effects
[status-im.contexts.profile.rpc :as profile.rpc]
[status-im.feature-flags :as ff]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
@ -119,8 +118,6 @@
[:logging/initialize-web3-client-version]
[:group-chats/get-group-chat-invitations]
[:profile.settings/blank-preview-flag-changed preview-privacy?]
(when (ff/enabled? ::ff/shell.jump-to)
[:switcher-cards/fetch])
[:visibility-status-updates/fetch]
[:dispatch [:universal-links/generate-profile-url]]
[:push-notifications/load-preferences]

View File

@ -1,7 +1,7 @@
(ns status-im.contexts.profile.settings.style
(:require [quo.foundations.colors :as colors]
[react-native.platform :as platform]
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]))
[status-im.contexts.shell.constants :as shell.constants]))
(defn navigation-wrapper
[{:keys [customization-color inset theme]}]
@ -15,13 +15,6 @@
[bottom]
{:padding-horizontal footer-padding
:padding-top footer-padding
:padding-bottom (+ jump-to.constants/floating-shell-button-height
:padding-bottom (+ shell.constants/floating-shell-button-height
footer-padding
(if platform/ios? ios-bottom-offset bottom))})
(defn floating-shell-button-style
[{:keys [bottom]}]
{:position :absolute
:bottom (if platform/ios?
(+ bottom ios-bottom-offset)
0)})

View File

@ -11,7 +11,6 @@
[status-im.contexts.profile.utils :as profile.utils]
[status-im.feature-flags :as ff]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn show-settings-item?
@ -88,11 +87,4 @@
:scroll-event-throttle 16
:on-scroll on-scroll
:bounces false
:over-scroll-mode :never}]
(when (ff/enabled? ::ff/shell.jump-to)
[quo/floating-shell-button
{:jump-to
{:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
:customization-color customization-color
:label (i18n/label :t/jump-to)}}
(style/floating-shell-button-style insets)])]))
:over-scroll-mode :never}]]))

View File

@ -0,0 +1,21 @@
(ns status-im.contexts.shell.bottom-tabs.style
(:require
[quo.foundations.colors :as colors]
[react-native.platform :as platform]
[status-im.contexts.shell.utils :as utils]))
(defn bottom-tabs-container
[height]
[{:height height}
{:background-color colors/neutral-100
:align-items :center
:height (utils/bottom-tabs-container-height)
:accessibility-label :bottom-tabs-container}])
(defn bottom-tabs
[]
{:flex-direction :row
:position :absolute
:bottom (if platform/android? 8 34)
:flex 1
:accessibility-label :bottom-tabs})

View File

@ -1,31 +1,19 @@
(ns status-im.contexts.shell.jump-to.components.bottom-tabs.view
(ns status-im.contexts.shell.bottom-tabs.view
(:require
[quo.core :as quo]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.gesture :as gesture]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[status-im.config :as config]
[status-im.contexts.shell.jump-to.animation :as animation]
[status-im.contexts.shell.jump-to.components.bottom-tabs.style :as style]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
[status-im.contexts.shell.jump-to.state :as state]
[status-im.contexts.shell.jump-to.utils :as utils]
[status-im.feature-flags :as ff]
[status-im.contexts.shell.bottom-tabs.style :as style]
[status-im.contexts.shell.constants :as shell.constants]
[utils.re-frame :as rf]))
(defn blur-overlay-params
[style]
{:style style
:blur-amount (if platform/android? 30 20)
:blur-radius (if platform/android? 25 10)
:blur-type :transparent
:overlay-color :transparent})
(defn bottom-tab
[icon stack-id shared-values notifications-data]
(let [customization-color (rf/sub [:profile/customization-color])
on-press (rn/use-callback #(rf/dispatch [:shell/change-tab stack-id]))
icon-color (->> stack-id
(get shell.constants/tabs-icon-color-keywords)
(get shared-values))]
@ -35,19 +23,13 @@
(assoc :test-ID stack-id
:icon icon
:icon-color-anim icon-color
:on-press (fn []
(when-not (= stack-id :wallet-stack)
(rf/dispatch [:wallet/reset-selected-networks]))
(animation/bottom-tab-on-press stack-id true))
:on-press on-press
:accessibility-label (str (name stack-id) "-tab")
:customization-color customization-color))]))
(defn f-bottom-tabs
[]
(defn view
[shared-values]
(let [notifications-data (rf/sub [:shell/bottom-tabs-notifications-data])
pass-through? (and (ff/enabled? ::ff/shell.jump-to)
(rf/sub [:shell/shell-pass-through?]))
shared-values @state/shared-values-atom
communities-double-tab-gesture (-> (gesture/gesture-tap)
(gesture/number-of-taps 2)
(gesture/on-start
@ -57,18 +39,10 @@
(gesture/number-of-taps 2)
(gesture/on-start
(fn [_event]
(rf/dispatch [:messages-home/select-tab :tab/recent]))))
bottom-tabs-blur-overlay-style (style/bottom-tabs-blur-overlay (:bottom-tabs-height
shared-values))]
(utils/load-stack (if (ff/enabled? ::ff/shell.jump-to)
@state/selected-stack-id
shell.constants/default-selected-stack))
(reanimated/set-shared-value (:pass-through? shared-values) pass-through?)
(rf/dispatch [:messages-home/select-tab :tab/recent]))))]
[quo.theme/provider :dark
[reanimated/view
{:style (style/bottom-tabs-container pass-through? (:bottom-tabs-height shared-values))}
(when pass-through?
[reanimated/blur-view (blur-overlay-params bottom-tabs-blur-overlay-style)])
{:style (style/bottom-tabs-container (:bottom-tabs-height shared-values))}
[rn/view {:style (style/bottom-tabs)}
[bottom-tab :i/wallet :wallet-stack shared-values notifications-data]
[gesture/gesture-detector {:gesture messages-double-tap-gesture}

View File

@ -0,0 +1,31 @@
(ns status-im.contexts.shell.constants)
(def ^:const floating-shell-button-height 44)
(def ^:const default-selected-stack :wallet-stack)
;; Bottom tabs
(def ^:const bottom-tabs-container-height-android 57)
(def ^:const bottom-tabs-container-height-ios 82)
;; Stacks
(def ^:const stacks-ids [:communities-stack :chats-stack :wallet-stack :browser-stack])
;; Keywords
(def ^:const stacks-opacity-keywords
{:communities-stack :communities-stack-opacity
:chats-stack :chats-stack-opacity
:wallet-stack :wallet-stack-opacity
:browser-stack :browser-stack-opacity})
(def ^:const tabs-icon-color-keywords
{:communities-stack :communities-tab-icon-color
:chats-stack :chats-tab-icon-opacity
:wallet-stack :wallet-tab-icon-opacity
:browser-stack :browser-tab-icon-opacity})
(def ^:const stacks-z-index-keywords
{:communities-stack :communities-stack-z-index
:chats-stack :chats-stack-z-index
:wallet-stack :wallet-stack-z-index
:browser-stack :browser-stack-z-index})

View File

@ -0,0 +1,17 @@
(ns status-im.contexts.shell.effects
(:require
[react-native.reanimated :as reanimated]
[status-im.contexts.shell.constants :as shell.constants]
[status-im.contexts.shell.state :as state]
[status-im.contexts.shell.utils :as utils]
[utils.re-frame :as rf]))
(rf/reg-fx :effects.shell/change-tab
(fn [stack-id]
(when (and (not= stack-id @state/selected-stack-id-value)
(some #(= stack-id %) shell.constants/stacks-ids))
(some-> @state/selected-stack-id-shared-value
(reanimated/set-shared-value (name stack-id)))
(utils/change-selected-stack stack-id)
(when-not (= stack-id :wallet-stack)
(rf/dispatch [:wallet/reset-selected-networks])))))

View File

@ -0,0 +1,10 @@
(ns status-im.contexts.shell.events
(:require
[re-frame.core :as re-frame]))
(re-frame/reg-event-fx :shell/change-tab
(fn [{:keys [db]} [stack-id]]
{:db (-> db
(assoc :view-id stack-id)
(assoc :shell/selected-stack-id stack-id))
:fx [[:effects.shell/change-tab stack-id]]}))

View File

@ -0,0 +1,23 @@
(ns status-im.contexts.shell.home-stack.style
(:require
[quo.foundations.colors :as colors]
[react-native.reanimated :as reanimated]))
(defn stack-view
[stack-id {:keys [opacity z-index]}]
(reanimated/apply-animations-to-style
{:opacity opacity
:z-index z-index}
{:top 0
:left 0
:right 0
:bottom 0
:position :absolute
:accessibility-label stack-id}))
(defn home-stack
[theme]
{:border-bottom-left-radius 20
:border-bottom-right-radius 20
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)
:flex 1})

View File

@ -1,16 +1,15 @@
(ns status-im.contexts.shell.jump-to.components.home-stack.view
(ns status-im.contexts.shell.home-stack.view
(:require
[legacy.status-im.ui.screens.browser.stack :as browser.stack]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[status-im.contexts.chat.home.view :as chat]
[status-im.contexts.communities.home.view :as communities]
[status-im.contexts.shell.jump-to.components.home-stack.style :as style]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
[status-im.contexts.shell.jump-to.state :as state]
[status-im.contexts.shell.jump-to.utils :as utils]
[status-im.contexts.wallet.home.view :as wallet]
[utils.re-frame :as rf]))
[status-im.contexts.shell.constants :as shell.constants]
[status-im.contexts.shell.home-stack.style :as style]
[status-im.contexts.shell.state :as state]
[status-im.contexts.wallet.home.view :as wallet]))
(defn load-stack?
[stack-id]
@ -41,18 +40,10 @@
(when (load-stack? stack-id)
[:f> f-stack-view stack-id shared-values]))
(defn f-home-stack
[]
(let [shared-values @state/shared-values-atom
theme (quo.theme/use-theme)
{:keys [width height]} (utils/dimensions)
alert-banners-top-margin (rf/sub [:alert-banners/top-margin])]
[reanimated/view
{:style (style/home-stack
shared-values
{:theme theme
:width width
:height (- height alert-banners-top-margin)})}
(defn view
[shared-values]
(let [theme (quo.theme/use-theme)]
[rn/view {:style (style/home-stack theme)}
[lazy-screen :communities-stack shared-values]
[lazy-screen :chats-stack shared-values]
[lazy-screen :browser-stack shared-values]

View File

@ -1,91 +0,0 @@
(ns status-im.contexts.shell.jump-to.animation
(:require
[react-native.reanimated :as reanimated]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
[status-im.contexts.shell.jump-to.state :as state]
[status-im.contexts.shell.jump-to.utils :as utils]
[utils.re-frame :as rf]))
;;;; Home stack
(defn open-home-stack
[stack-id animate?]
(let [home-stack-state-value (utils/calculate-home-stack-state-value stack-id animate?)]
(reanimated/set-shared-value (:selected-stack-id @state/shared-values-atom) (name stack-id))
(reanimated/set-shared-value (:home-stack-state @state/shared-values-atom) home-stack-state-value)
(utils/change-selected-stack-id stack-id true home-stack-state-value)
(js/setTimeout
#(utils/load-stack stack-id)
(if animate? shell.constants/shell-animation-time 0))))
(defn change-tab
[stack-id]
(reanimated/set-shared-value (:animate-home-stack-left @state/shared-values-atom) false)
(reanimated/set-shared-value (:selected-stack-id @state/shared-values-atom) (name stack-id))
(utils/load-stack stack-id)
(utils/change-selected-stack-id stack-id true nil))
(defn bottom-tab-on-press
[stack-id animate?]
(when (and @state/shared-values-atom (not= stack-id @state/selected-stack-id))
(if (utils/home-stack-open?)
(change-tab stack-id)
(open-home-stack stack-id animate?))
(when animate? (utils/update-view-id (or stack-id :shell)))))
(defn close-home-stack
[animate?]
(let [stack-id nil
home-stack-state-value (utils/calculate-home-stack-state-value stack-id animate?)]
(reanimated/set-shared-value (:animate-home-stack-left @state/shared-values-atom) true)
(reanimated/set-shared-value (:home-stack-state @state/shared-values-atom) home-stack-state-value)
(utils/change-selected-stack-id stack-id true home-stack-state-value)
(when animate? (utils/update-view-id (or stack-id :shell)))))
;;;; Floating Screen
(defn animate-floating-screen
[screen-id {:keys [id animation community-id hidden-screen?]}]
(when (not= animation (get @state/floating-screens-state screen-id))
;; Animate Floating Screen
(reanimated/set-shared-value
(get-in @state/shared-values-atom [screen-id :screen-state])
animation)
(reset! state/floating-screens-state
(assoc @state/floating-screens-state screen-id animation))
(let [floating-screen-open? (utils/floating-screen-open? screen-id)
animation-time (if (#{shell.constants/open-screen-without-animation
shell.constants/close-screen-without-animation}
animation)
0
shell.constants/shell-animation-time)]
(js/setTimeout
(fn [floating-screen-open?]
(if floating-screen-open?
;; Events realted to opening of a screen
(rf/dispatch [:shell/floating-screen-opened screen-id
id community-id hidden-screen?])
;; Events realted to closing of a screen
(rf/dispatch [:shell/floating-screen-closed screen-id])))
animation-time
floating-screen-open?))))
(defn set-floating-screen-position
[left top card-type]
(let [screen-id (cond
(#{shell.constants/one-to-one-chat-card
shell.constants/private-group-chat-card
shell.constants/community-channel-card}
card-type)
shell.constants/chat-screen
(= card-type shell.constants/community-card)
shell.constants/community-screen
:else nil)]
(when screen-id
(reanimated/set-shared-value
(get-in @state/shared-values-atom [screen-id :screen-left])
left)
(reanimated/set-shared-value
(get-in @state/shared-values-atom [screen-id :screen-top])
top))))

View File

@ -1,41 +0,0 @@
(ns status-im.contexts.shell.jump-to.components.bottom-tabs.style
(:require
[quo.foundations.colors :as colors]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[status-im.contexts.shell.jump-to.utils :as utils]))
(defn bottom-tabs-container
[pass-through? height]
[{:height height}
{:background-color (if (and platform/ios? pass-through?)
:transparent
colors/neutral-100)
:flex 1
:align-items :center
:height (utils/bottom-tabs-container-height)
:position :absolute
:bottom 0
:right 0
:left 0
:overflow :hidden
:accessibility-label :bottom-tabs-container}])
(defn bottom-tabs
[]
{:flex-direction :row
:position :absolute
:bottom (if platform/android? 8 34)
:flex 1
:accessibility-label :bottom-tabs})
(defn bottom-tabs-blur-overlay
[height]
(reanimated/apply-animations-to-style
{:height height}
{:position :absolute
:left 0
:right 0
:bottom 0
:height (utils/bottom-tabs-container-height)
:background-color colors/neutral-100-opa-70-blur}))

View File

@ -1,30 +0,0 @@
(ns status-im.contexts.shell.jump-to.components.floating-screens.style
(:require
[quo.foundations.colors :as colors]
[react-native.reanimated :as reanimated]
[status-im.contexts.shell.jump-to.constants :as shell.constants]))
(defn screen
[{:keys [screen-left screen-top screen-width screen-height screen-border-radius screen-z-index]}
{:keys [screen-id theme]}]
(reanimated/apply-animations-to-style
{:left screen-left
:top screen-top
:width screen-width
:height screen-height
:border-radius screen-border-radius
:z-index screen-z-index}
{:background-color (colors/theme-colors colors/white colors/neutral-95 theme)
:overflow :hidden
;; KeyboardAvoidingView which is used for chat screen composer, not working when we use
;; :absolute layout. One fix is to add. KeyboardAvoidingView :behaviour height in android, which
;; is also recommended in the documentation. It fixes KeyboardAvoidingView but the pushing of
;; views by the keyboard is not smooth & while animating it creates a weird jump.
:position (if (= screen-id shell.constants/chat-screen) :relative :absolute)
:flex -1}))
(defn screen-container
[{:keys [width height]}]
{:width width
:flex -1
:height height})

View File

@ -1,50 +0,0 @@
(ns status-im.contexts.shell.jump-to.components.floating-screens.view
(:require
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[status-im.contexts.chat.messenger.messages.view :as chat]
[status-im.contexts.communities.discover.view :as communities.discover]
[status-im.contexts.communities.overview.view :as communities.overview]
[status-im.contexts.shell.jump-to.animation :as animation]
[status-im.contexts.shell.jump-to.components.floating-screens.style :as style]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
[status-im.contexts.shell.jump-to.state :as state]
[status-im.contexts.shell.jump-to.utils :as utils]
[utils.re-frame :as rf]))
(def screens-map
{shell.constants/chat-screen chat/chat
shell.constants/community-screen communities.overview/view
shell.constants/discover-communities-screen communities.discover/view})
(defn f-screen
[{:keys [screen-id id animation clock] :as screen-param}]
(let [theme (quo.theme/use-theme)]
;; First render screen, then animate (smoother animation)
(rn/use-effect
(fn []
(animation/animate-floating-screen screen-id screen-param))
[animation id clock])
[reanimated/view
{:style (style/screen (get @state/shared-values-atom screen-id)
{:theme theme
:screen-id screen-id})}
[rn/view
{:style (style/screen-container (utils/dimensions))
:accessibility-label (str screen-id "-floating-screen")
:accessible true}
[(get screens-map screen-id) id]]]))
(defn lazy-screen
[screen-id]
(let [screen-param (rf/sub [:shell/floating-screen screen-id])]
(when screen-param
[:f> f-screen (assoc screen-param :screen-id screen-id)])))
(defn view
[]
[:<>
[lazy-screen shell.constants/discover-communities-screen]
[lazy-screen shell.constants/community-screen]
[lazy-screen shell.constants/chat-screen]])

View File

@ -1,34 +0,0 @@
(ns status-im.contexts.shell.jump-to.components.home-stack.style
(:require
[quo.foundations.colors :as colors]
[react-native.reanimated :as reanimated]
[status-im.contexts.shell.jump-to.utils :as utils]))
(defn home-stack
[shared-values {:keys [width height theme]}]
(reanimated/apply-animations-to-style
{:top (:home-stack-top shared-values)
:left (:home-stack-left shared-values)
:opacity (:home-stack-opacity shared-values)
:pointer-events (:home-stack-pointer shared-values)
:border-radius (:home-stack-border-radius shared-values)
:transform [{:scale (:home-stack-scale shared-values)}]}
{:border-bottom-left-radius 20
:border-bottom-right-radius 20
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)
:overflow :hidden
:position :absolute
:width width
:height (- height (utils/bottom-tabs-container-height))}))
(defn stack-view
[stack-id {:keys [opacity z-index]}]
(reanimated/apply-animations-to-style
{:opacity opacity
:z-index z-index}
{:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:accessibility-label stack-id}))

View File

@ -1,67 +0,0 @@
(ns status-im.contexts.shell.jump-to.components.jump-to-screen.style
(:require
[quo.foundations.colors :as colors]
[react-native.platform :as platform]
[status-im.contexts.shell.jump-to.utils :as utils]))
;;;; Placeholder
(defn placeholder-container
[status-bar-height]
{:position :absolute
:top (+ 112 status-bar-height)
:left 0
:right 0
:bottom (utils/bottom-tabs-container-height)
:align-items :center
:justify-content :center
:accessibility-label :shell-placeholder-view})
(def placeholder-image
{:margin-top 186
:width 120
:height 120
;; Code to remove once placeholder image/vector will be available
:border-width 5
:border-radius 10
:border-color :red})
(def placeholder-title
{:margin-top 20
:color colors/white})
(def placeholder-subtitle
{:margin-top 4
:color colors/white})
;;;; Shell
(defn jump-to-text
[status-bar-height]
{:color colors/white
:margin-top (+ 68 status-bar-height)
:margin-bottom 20
:margin-left 20})
(def jump-to-list
{:top 0
:left 0
:right 0
:bottom 0
:position :absolute})
(defn top-nav-blur-overlay-container
[height pass-through?]
{:height height
:position :absolute
:left 0
:top 0
:right 0
:overflow :hidden
:background-color (if pass-through? :transparent colors/neutral-100)})
(def top-nav-blur-overlay
{:height 100
:position :absolute
:left 0
:right 0
:top 0
:background-color (when platform/ios? colors/neutral-100-opa-70-blur)})

View File

@ -1,105 +0,0 @@
(ns status-im.contexts.shell.jump-to.components.jump-to-screen.view
(:require
[quo.core :as quo]
[quo.foundations.colors :as colors]
[quo.theme]
[react-native.core :as rn]
[react-native.linear-gradient :as linear-gradient]
[react-native.safe-area :as safe-area]
[status-im.common.home.top-nav.view :as common.top-nav]
[status-im.common.resources :as resources]
[status-im.contexts.shell.jump-to.components.bottom-tabs.view :as bottom-tabs]
[status-im.contexts.shell.jump-to.components.jump-to-screen.style :as style]
[status-im.contexts.shell.jump-to.components.switcher-cards.view :as switcher-cards]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
[status-im.contexts.shell.jump-to.state :as state]
[status-im.contexts.shell.jump-to.utils :as utils]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn placeholder
[]
[rn/view {:style (style/placeholder-container (safe-area/get-top))}
[linear-gradient/linear-gradient
{:colors [colors/neutral-100-opa-0 colors/neutral-100-opa-100]
:start {:x 0 :y 0}
:end {:x 0 :y 1}
:style (style/placeholder-container (safe-area/get-top))}]
[quo/empty-state
{:title (i18n/label :t/shell-placeholder-title)
:description (i18n/label :t/shell-placeholder-subtitle)
:image (resources/get-themed-image :jump-to :dark)}]])
(defn jump-to-text
[]
[quo/text
{:size :heading-1
:weight :semi-bold
:style (style/jump-to-text (safe-area/get-top))}
(i18n/label :t/jump-to)])
(defn render-card
[{:keys [type screen-id] :as card}]
(let [card-data (cond
(= type shell.constants/one-to-one-chat-card)
(rf/sub [:shell/one-to-one-chat-card screen-id])
(= type shell.constants/private-group-chat-card)
(rf/sub [:shell/private-group-chat-card screen-id])
(= type shell.constants/community-card)
(rf/sub [:shell/community-card screen-id])
(= type shell.constants/community-channel-card)
(rf/sub [:shell/community-channel-card screen-id])
:else nil)]
[switcher-cards/card (merge card card-data)]))
(def empty-cards (repeat 6 {:type shell.constants/empty-card}))
(defn jump-to-list
[switcher-cards]
(let [data (if (seq switcher-cards) switcher-cards empty-cards)]
[:<>
[rn/flat-list
{:data data
:render-fn render-card
:key-fn :screen-id
:header (jump-to-text)
:ref #(reset! state/jump-to-list-ref %)
:num-columns 2
:column-wrapper-style {:margin-horizontal 20
:justify-content :space-between
:margin-bottom 16}
:style style/jump-to-list
:content-inset-adjustment-behavior :never
:content-container-style {:padding-bottom (utils/bottom-tabs-container-height)}}]
(when-not (seq switcher-cards)
[placeholder])]))
(defn top-nav-blur-overlay
[top]
(let [pass-through? (rf/sub [:shell/shell-pass-through?])]
[rn/view {:style (style/top-nav-blur-overlay-container (+ 56 top) pass-through?)}
(when pass-through?
[quo/blur (bottom-tabs/blur-overlay-params style/top-nav-blur-overlay)])]))
(defn view
[]
(let [switcher-cards (rf/sub [:shell/sorted-switcher-cards])
top (safe-area/get-top)]
[quo.theme/provider :dark
[rn/view
{:style {:top 0
:left 0
:right 0
:bottom -1
:position :absolute
:background-color colors/neutral-100}}
[jump-to-list switcher-cards]
[top-nav-blur-overlay top]
[common.top-nav/view
{:jump-to? true
:container-style {:margin-top top
:z-index 2}}]]]))

View File

@ -1,131 +0,0 @@
(ns status-im.contexts.shell.jump-to.components.switcher-cards.style
(:require
[quo.foundations.colors :as colors]))
(def colors-map
{:secondary-container-bg-color colors/neutral-95
:title-color colors/white
:subtitle-color colors/neutral-40
:last-message-text-color colors/white
:close-button-bg-color colors/neutral-80-opa-40
:close-button-icon-color colors/white
:community-channel colors/white})
(defn base-container
[background-color card-size]
{:width card-size
:height card-size
:border-radius 16
:overflow :hidden
:background-color (colors/alpha background-color 0.4)})
(defn empty-card
[card-size]
(merge
(base-container nil card-size)
{:background-color colors/neutral-95}))
(defn secondary-container
[card-size]
{:width card-size
:height (- card-size 40)
:border-radius 16
:bottom 0
:position :absolute
:background-color (:secondary-container-bg-color colors-map)})
(def title
{:position :absolute
:top 28
:margin-horizontal 12
:color (:title-color colors-map)})
(def subtitle
{:position :absolute
:top 50
:margin-horizontal 12
:color (:subtitle-color colors-map)})
(defn content-container
[new-notifications?]
{:flex 1
:max-width (if new-notifications? 108 136)})
(def notification-container
{:margin-top :auto
:width 20
:height 20
:justify-content :center
:align-items :center
:margin-left 8})
(def last-message-text
{:color (:last-message-text-color colors-map)})
(def close-button
{:position :absolute
:right 8
:top 8
:background-color (:close-button-bg-color colors-map)
:icon-color (:close-button-icon-color colors-map)})
(def avatar-container
{:width 48
:height 48
:left 12
:top 12
:border-radius 26
:border-width 26
:border-color colors/neutral-95
:justify-content :center
:align-items :center
:position :absolute})
(defn unread-dot
[customization-color]
{:width 8
:height 8
:border-radius 4
:background-color (colors/custom-color customization-color 60)})
(def bottom-container
{:position :absolute
:flex-direction :row
:justify-content :space-between
:align-items :flex-end
:bottom 12
:left 12
:right 12})
;; Supporting Components
(def channel-card-container
{:flex-direction :row
:align-items :center})
(def channel-card-text-container {:flex 1})
(def sticker
{:width 24
:height 24})
(def gif
{:width 24
:height 24
:border-radius 8})
(defn community-avatar
[customization-color]
{:width 48
:height 48
:border-radius 24
;; TODO - Update to fall back community avatar once designs are available
:justify-content :center
:align-items :center
:background-color (colors/custom-color
(or customization-color :primary)
60)})
(def community-channel
{:margin-left 8
:color (:community-channel colors-map)})

View File

@ -1,328 +0,0 @@
(ns status-im.contexts.shell.jump-to.components.switcher-cards.view
(:require
[clojure.string :as string]
[quo.core :as quo]
[quo.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]
[status-im.constants :as constants]
[status-im.contexts.chat.messenger.messages.resolver.message-resolver :as resolver]
[status-im.contexts.shell.jump-to.animation :as animation]
[status-im.contexts.shell.jump-to.components.switcher-cards.style :as style]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- channel-card
[{:keys [emoji channel-name customization-color]}]
[rn/view style/channel-card-container
[quo/channel-avatar
{:emoji emoji
:full-name channel-name
:customization-color customization-color}]
[rn/view style/channel-card-text-container
[quo/text
{:size :paragraph-2
:weight :medium
:number-of-lines 1
:ellipsize-mode :tail
:style style/community-channel}
channel-name]]])
(defn content-container
[type
{:keys [content-type data new-notifications? color-50
community-info community-channel]
{:keys [text parsed-text source]} :data}]
[rn/view {:style (style/content-container new-notifications?)}
(condp = type
shell.constants/community-card
(case (:type community-info)
:pending [quo/status-tag
{:status {:type :pending}
:label (i18n/label :t/pending)
:size :small}]
:kicked [quo/status-tag
{:status {:type :negative}
:size :small
:label (i18n/label :t/kicked)}]
(:count :permission) [:<>] ;; Add components for these cases
nil)
shell.constants/community-channel-card
[channel-card (assoc community-channel :customization-color color-50)]
(condp = content-type
constants/content-type-text
[quo/text
{:size :paragraph-2
:weight :regular
:number-of-lines 1
:ellipsize-mode :tail
:style style/last-message-text}
(if parsed-text
(resolver/resolve-message parsed-text)
text)]
constants/content-type-image
[quo/preview-list
{:type :collectibles
:size :size-24}
data]
constants/content-type-sticker
[fast-image/fast-image
{:source source
:style style/sticker}]
constants/content-type-gif
[fast-image/fast-image
{:source source
:style style/gif}]
constants/content-type-audio
[quo/context-tag {:type :audio :duration data}]
constants/content-type-community
[quo/context-tag
{:type :community
:size 24
:community-logo (:avatar data)
:community-name (:community-name data)}]
constants/content-type-link ;; Components not available
;; Code snippet content type is not supported yet
[:<>]
nil))])
(defn notification-container
[{:keys [notification-indicator counter-label profile-customization-color]}]
[rn/view {:style style/notification-container}
(if (= notification-indicator :counter)
[quo/counter
{:customization-color profile-customization-color}
counter-label]
[rn/view {:style (style/unread-dot profile-customization-color)}])])
(defn bottom-container
[type {:keys [new-notifications?] :as content}]
[rn/view {:style style/bottom-container}
[content-container type content]
(when new-notifications?
[notification-container content])])
(defn avatar
[avatar-params type customization-color]
(cond
(= type shell.constants/one-to-one-chat-card)
[quo/user-avatar
(merge {:size :medium
:status-indicator? false}
avatar-params)]
(= type shell.constants/private-group-chat-card)
[quo/group-avatar
{:customization-color customization-color
:size :size-48
:override-theme :dark}]
(#{shell.constants/community-card
shell.constants/community-channel-card}
type)
(cond
(:source avatar-params)
[fast-image/fast-image
{:source (:source avatar-params)
:style (style/community-avatar customization-color)}]
(:name avatar-params)
;; TODO - Update to fall back community avatar once designs are available
[rn/view {:style (style/community-avatar customization-color)}
[quo/text
{:weight :semi-bold
:size :heading-2
:style {:color colors/white-opa-70}}
(string/upper-case (first (:name avatar-params)))]])
:else
nil))
(defn subtitle
[type {:keys [content-type data]}]
(condp = type
shell.constants/community-card
(i18n/label :t/community)
shell.constants/community-channel-card
(i18n/label :t/community-channel)
(condp = content-type
constants/content-type-text
(i18n/label :t/message)
constants/content-type-image
(i18n/label
(if (= (count data) 1)
:t/one-photo
:t/n-photos)
{:count (count data)})
constants/content-type-sticker
(i18n/label :t/sticker)
constants/content-type-gif
(i18n/label :t/gif)
constants/content-type-audio
(i18n/label :t/audio-message)
constants/content-type-community
(i18n/label :t/link-to-community)
constants/content-type-link
(i18n/label :t/external-link)
constants/content-type-contact-request
(i18n/label :t/contact-request)
"")))
(defn open-screen
[card-type id channel-id]
(cond
(#{shell.constants/one-to-one-chat-card
shell.constants/private-group-chat-card}
card-type)
(rf/dispatch [:chat/navigate-to-chat id])
(= card-type shell.constants/community-channel-card)
(rf/dispatch [:communities/navigate-to-community-chat channel-id])
(= card-type shell.constants/community-card)
(rf/dispatch [:communities/navigate-to-community-overview id])))
(defn calculate-card-position-and-open-screen
[card-ref card-type id channel-id]
(when @card-ref
(.measure
^js
@card-ref
(fn [_ _ _ _ page-x page-y]
(animation/set-floating-screen-position
page-x
page-y
card-type)
(open-screen card-type id channel-id)))))
;; Screens Card
(defn screens-card
[]
(let [card-ref (atom nil)]
(fn [{:keys [avatar-params title type customization-color
content banner id channel-id profile-customization-color]} card-size]
(let [color-50 (colors/custom-color customization-color 50)]
[rn/touchable-opacity
{:on-press #(calculate-card-position-and-open-screen
card-ref
type
id
channel-id)
:ref #(reset! card-ref %)
:active-opacity 1}
[rn/view {:style (style/base-container color-50 card-size)}
(when banner
[rn/image
{:source banner
:style {:width 160
:height 65}}])
[rn/view {:style (style/secondary-container card-size)}
[quo/text
{:size :paragraph-1
:weight :semi-bold
:number-of-lines 1
:ellipsize-mode :tail
:style style/title}
title]
[quo/text
{:size :paragraph-2
:weight :medium
:style style/subtitle}
(subtitle type content)]
[bottom-container type
(merge {:color-50 color-50
:customization-color customization-color
:profile-customization-color profile-customization-color}
content)]]
(when avatar-params
[rn/view {:style style/avatar-container}
[avatar avatar-params type customization-color]])
[quo/button
{:size 24
:type :grey
:icon-only? true
:on-press #(rf/dispatch [:shell/close-switcher-card id])
:container-style style/close-button}
:i/close]]]))))
;; browser Card
(defn browser-card
[_]
[:<>])
;; Wallet Cards
(defn wallet-card
[_]
[:<>])
(defn wallet-collectible
[_]
[:<>])
(defn wallet-graph
[_]
[:<>])
(defn empty-card
[card-size]
[rn/view {:style (style/empty-card card-size)}])
;; Home Card
(defn communities-discover
[_]
[:<>])
(defn card
[{:keys [type] :as data}]
(let [screen-width (:width (rn/get-window))
;; 2 column, 20px horizontal margin, 15px gap
card-size (/ (- screen-width 55) 2)]
(cond
(= type shell.constants/empty-card) ; Placeholder
[empty-card card-size]
;; Screens Card
(#{shell.constants/one-to-one-chat-card
shell.constants/private-group-chat-card
shell.constants/community-card
shell.constants/community-channel-card}
type)
[screens-card data card-size]
(= type shell.constants/browser-card) ; Browser Card
[browser-card data]
(= type shell.constants/wallet-card) ; Wallet Card
[wallet-card data]
(= type shell.constants/wallet-collectible) ; Wallet Card
[wallet-collectible data]
(= type shell.constants/wallet-graph) ; Wallet Card
[wallet-graph data]
(= type shell.constants/communities-discover) ; Home Card
[communities-discover data]
:else
nil)))

View File

@ -1,76 +0,0 @@
(ns status-im.contexts.shell.jump-to.constants)
(def ^:const shell-animation-time 200)
(def ^:const switcher-card-size 160)
(def ^:const floating-shell-button-height 44)
(def ^:const default-selected-stack :wallet-stack)
;; Bottom tabs
(def ^:const bottom-tabs-container-height-android 57)
(def ^:const bottom-tabs-container-height-ios 82)
(def ^:const bottom-tabs-container-extended-height-android 90)
(def ^:const bottom-tabs-container-extended-height-ios 120)
(def ^:const bottom-tab-width 90)
;; Stacks
(def ^:const stacks-ids [:communities-stack :chats-stack :wallet-stack :browser-stack])
;; Keywords
(def ^:const stacks-opacity-keywords
{:communities-stack :communities-stack-opacity
:chats-stack :chats-stack-opacity
:wallet-stack :wallet-stack-opacity
:browser-stack :browser-stack-opacity})
(def ^:const tabs-icon-color-keywords
{:communities-stack :communities-tab-icon-color
:chats-stack :chats-tab-icon-opacity
:wallet-stack :wallet-tab-icon-opacity
:browser-stack :browser-tab-icon-opacity})
(def ^:const stacks-z-index-keywords
{:communities-stack :communities-stack-z-index
:chats-stack :chats-stack-z-index
:wallet-stack :wallet-stack-z-index
:browser-stack :browser-stack-z-index})
;; Home stack states
(def ^:const close-without-animation 0)
(def ^:const open-without-animation 1)
(def ^:const close-with-animation 2)
(def ^:const open-with-animation 3)
;; Switcher Cards
(def ^:const empty-card 0)
(def ^:const one-to-one-chat-card 1)
(def ^:const private-group-chat-card 2)
(def ^:const community-card 3)
(def ^:const community-channel-card 4)
(def ^:const browser-card 5)
(def ^:const wallet-card 6)
(def ^:const wallet-collectible 7)
(def ^:const wallet-graph 8)
(def ^:const communities-discover 9)
;; Floating Screens
(def ^:const chat-screen :chat)
(def ^:const community-screen :community-overview)
(def ^:const discover-communities-screen :discover-communities)
(def ^:const floating-screens [chat-screen community-screen discover-communities-screen])
;; Floating Screen states
(def ^:const close-screen-without-animation 0)
(def ^:const open-screen-without-animation 1)
(def ^:const close-screen-with-shell-animation 2)
(def ^:const open-screen-with-shell-animation 3)
(def ^:const close-screen-with-slide-to-right-animation 4)
(def ^:const open-screen-with-slide-from-right-animation 5)
(def ^:const close-screen-with-slide-to-bottom-animation 6)
(def ^:const open-screen-with-slide-from-bottom-animation 7)
;; Floating Screen gesture
(def ^:const gesture-width 30)
(def ^:const gesture-fling-right-velocity 2000)
(def ^:const gesture-fling-left-velocity -1000)

View File

@ -1,30 +0,0 @@
(ns status-im.contexts.shell.jump-to.effects
(:require
[status-im.contexts.shell.jump-to.animation :as animation]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
[status-im.contexts.shell.jump-to.state :as state]
[status-im.contexts.shell.jump-to.utils :as shell.utils]
[utils.re-frame :as rf]))
(rf/reg-fx :effects.shell/change-tab
(fn [stack-id]
(when (some #(= stack-id %) shell.constants/stacks-ids)
(animation/bottom-tab-on-press stack-id false))))
(rf/reg-fx :effects.shell/navigate-to-jump-to
(fn []
(animation/close-home-stack false)
(some-> ^js @state/jump-to-list-ref
(.scrollToOffset #js {:y 0 :animated false}))))
;; Note - pop-to-root resets currently opened screens to `close-screen-without-animation`.
;; This might take some time. So don't directly merge the effect of `pop-to-root` and
;; `navigate-to` for the floating screen. Because it might close even the currently opened screen.
;; https://github.com/status-im/status-mobile/pull/16438#issuecomment-1623954774
(rf/reg-fx :effects.shell/pop-to-root
(fn []
(shell.utils/reset-floating-screens)))
(rf/reg-fx :effects.shell/reset-state
(fn []
(reset! state/floating-screens-state {})))

View File

@ -1,211 +0,0 @@
(ns status-im.contexts.shell.jump-to.events
(:require
[legacy.status-im.data-store.switcher-cards :as switcher-cards-store]
[legacy.status-im.utils.core :as utils]
[status-im.constants :as constants]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
status-im.contexts.shell.jump-to.effects
[status-im.contexts.shell.jump-to.utils :as shell.utils]
[status-im.feature-flags :as ff]
[status-im.navigation.state :as navigation.state]
[utils.re-frame :as rf]))
;;;; Events
;; Switcher
(rf/defn switcher-cards-loaded
{:events [:shell/switcher-cards-loaded]}
[{:keys [db]} loaded-switcher-cards]
{:db (assoc db
:shell/switcher-cards
(utils/index-by :card-id (switcher-cards-store/<-rpc loaded-switcher-cards)))})
(defn calculate-card-data
[db now view-id id]
(case view-id
:chat
(let [chat (get-in db [:chats id])]
(condp = (:chat-type chat)
constants/one-to-one-chat-type
{:card-id id
:switcher-card {:type shell.constants/one-to-one-chat-card
:card-id id
:clock now
:screen-id id}}
constants/private-group-chat-type
{:card-id id
:switcher-card {:type shell.constants/private-group-chat-card
:card-id id
:clock now
:screen-id id}}
constants/community-chat-type
{:card-id (:community-id chat)
:switcher-card {:type shell.constants/community-channel-card
:card-id (:community-id chat)
:clock now
:screen-id (:chat-id chat)}}
nil))
:community-overview
{:card-id id
:switcher-card {:type shell.constants/community-card
:card-id id
:clock now
:screen-id id}}
nil))
(rf/defn add-switcher-card
{:events [:shell/add-switcher-card]}
[{:keys [db now] :as cofx} view-id id]
(let [card-data (calculate-card-data db now view-id id)
switcher-card (:switcher-card card-data)
card-type (:type switcher-card)]
(when card-data
(rf/merge
cofx
{:db (assoc-in
db
[:shell/switcher-cards (:card-id card-data)]
switcher-card)}
(switcher-cards-store/upsert-switcher-card-rpc switcher-card)))))
(rf/defn close-switcher-card
{:events [:shell/close-switcher-card]}
[{:keys [db] :as cofx} card-id]
(rf/merge
cofx
{:db (update db :shell/switcher-cards dissoc card-id)}
(switcher-cards-store/delete-switcher-card-rpc card-id)))
;; Navigation
(rf/defn navigate-to-jump-to
{:events [:shell/navigate-to-jump-to]}
[{:keys [db]}]
(let [current-view-id (:view-id db)
open-floating-screens (shell.utils/open-floating-screens)
chat-screen-open? (get open-floating-screens shell.constants/chat-screen)
community-screen-open? (get open-floating-screens shell.constants/community-screen)
discover-communities-screen-open? (get open-floating-screens
shell.constants/discover-communities-screen)]
(assoc
(if (shell.utils/shell-navigation? current-view-id)
{:db
(cond-> db
chat-screen-open?
(assoc-in [:shell/floating-screens shell.constants/chat-screen :animation]
shell.constants/close-screen-with-shell-animation)
(and chat-screen-open? community-screen-open?)
(assoc-in [:shell/floating-screens shell.constants/community-screen :animation]
shell.constants/close-screen-without-animation)
(and (not chat-screen-open?) community-screen-open?)
(assoc-in [:shell/floating-screens shell.constants/community-screen :animation]
shell.constants/close-screen-with-shell-animation)
discover-communities-screen-open?
(assoc-in [:shell/floating-screens shell.constants/discover-communities-screen :animation]
shell.constants/close-screen-without-animation))
:dispatch [:set-view-id :shell]}
{:dispatch [:pop-to-root :shell-stack]})
:effects.shell/navigate-to-jump-to
nil)))
(rf/defn shell-navigate-to
{:events [:shell/navigate-to]}
[{:keys [db now]} go-to-view-id screen-params animation hidden-screen?]
(if (shell.utils/shell-navigation? go-to-view-id)
(let [current-view-id (:view-id db)
community-id (get-in db [:chats screen-params :community-id])]
{:db (assoc-in
db
[:shell/floating-screens go-to-view-id]
{:id screen-params
:community-id community-id
:hidden-screen? hidden-screen?
:clock now
:animation (or
animation
(cond
(= current-view-id :shell)
shell.constants/open-screen-with-shell-animation
(= current-view-id :chat)
shell.constants/open-screen-without-animation
(= go-to-view-id shell.constants/discover-communities-screen)
shell.constants/open-screen-with-slide-from-bottom-animation
:else
shell.constants/open-screen-with-slide-from-right-animation))})
:dispatch-n (cond-> []
(not hidden-screen?)
(conj [:set-view-id go-to-view-id])
(and (= go-to-view-id shell.constants/community-screen)
(not hidden-screen?)
(:current-chat-id db))
(conj [:chat/close]))})
{:db (assoc db :view-id go-to-view-id)
:navigate-to [go-to-view-id (:theme db) animation]}))
(rf/defn shell-navigate-back
{:events [:shell/navigate-back]}
[{:keys [db]} animation]
(let [current-chat-id (:current-chat-id db)
current-view-id (:view-id db)
community-id (when current-chat-id
(get-in db [:chats current-chat-id :community-id]))]
(if (and (not (seq @navigation.state/modals))
(shell.utils/shell-navigation? current-view-id)
(seq (shell.utils/open-floating-screens)))
(merge
{:db (assoc-in
db
[:shell/floating-screens current-view-id :animation]
(cond
animation animation
(= current-view-id shell.constants/discover-communities-screen)
shell.constants/close-screen-with-slide-to-bottom-animation
:else
shell.constants/close-screen-with-slide-to-right-animation))}
(when (and current-chat-id community-id)
{:dispatch [:shell/add-switcher-card shell.constants/community-screen community-id]}))
(merge
{:navigate-back nil}
(when (and (not (ff/enabled? ::ff/shell.jump-to))
(= current-view-id :chat))
{:dispatch [:chat/close]})))))
(rf/defn floating-screen-opened
{:events [:shell/floating-screen-opened]}
[{:keys [db]} screen-id id community-id hidden-screen?]
(merge
{:db (assoc-in db [:shell/loaded-screens screen-id] true)
:dispatch-later
(cond-> []
community-id
;; When opening community chat, open community screen in background
(conj {:ms 50
:dispatch [:shell/navigate-to shell.constants/community-screen
community-id shell.constants/open-screen-without-animation true]})
;; Only update switcher cards for top screen
(and id (not hidden-screen?))
(conj {:ms (* 2 shell.constants/shell-animation-time)
:dispatch [:shell/add-switcher-card screen-id id]}))}
(when (and id (not hidden-screen?))
{:effects.shell/change-tab (if (or (= screen-id shell.constants/community-screen)
community-id)
:communities-stack
:chats-stack)})))
(rf/defn floating-screen-closed
{:events [:shell/floating-screen-closed]}
[{:keys [db]} screen-id]
{:db (cond-> (update db :shell/loaded-screens dissoc screen-id)
(= screen-id shell.constants/discover-communities-screen)
(update :shell/floating-screen dissoc screen-id))
:dispatch-n (cond-> [[:set-view-id :shell-stack]]
(= screen-id shell.constants/chat-screen)
(conj [:chat/close]))})

View File

@ -1,37 +0,0 @@
(ns status-im.contexts.shell.jump-to.gesture
(:require
[react-native.gesture :as gesture]
[status-im.contexts.shell.jump-to.constants :as constants]
[status-im.contexts.shell.jump-to.state :as state]
[status-im.contexts.shell.jump-to.utils :as utils]
[utils.re-frame :as rf]
[utils.worklets.shell :as worklets.shell]))
(defn on-screen-closed
[animation-time]
(js/setTimeout
#(rf/dispatch [:shell/navigate-back constants/close-screen-without-animation])
(or animation-time constants/shell-animation-time)))
;; Make sure issue is fixed before enabling gesture for floating screens
;; Issue: https://github.com/status-im/status-mobile/pull/16438#issuecomment-1621397789
;; More Info: https://github.com/status-im/status-mobile/pull/16438#issuecomment-1622589147
(defn floating-screen-gesture
[screen-id]
(let [{:keys [screen-left screen-state]} (get @state/shared-values-atom screen-id)
{:keys [width]} (utils/dimensions)]
(-> (gesture/gesture-pan)
(gesture/min-distance 0)
(gesture/max-pointers 1)
(gesture/fail-offset-x -1)
(gesture/hit-slop (clj->js {:left 0 :width constants/gesture-width}))
(gesture/on-update (worklets.shell/floating-screen-gesture-on-update screen-left))
(gesture/on-end
(worklets.shell/floating-screen-gesture-on-end
{:screen-left screen-left
:screen-state screen-state
:screen-width width
:left-velocity constants/gesture-fling-left-velocity
:right-velocity constants/gesture-fling-right-velocity
:screen-closed-callback on-screen-closed})))))

View File

@ -1,137 +0,0 @@
(ns status-im.contexts.shell.jump-to.shared-values
(:require
[quo.foundations.colors :as colors]
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
[status-im.contexts.shell.jump-to.state :as state]
[status-im.contexts.shell.jump-to.utils :as utils]
[status-im.feature-flags :as ff]
[utils.worklets.shell :as worklets.shell]))
(defn calculate-home-stack-position
[{:keys [width height]}]
(let [bottom-nav-tab-width shell.constants/bottom-tab-width
minimize-scale (/ bottom-nav-tab-width width)
empty-space-half-scale (/ (- 1 minimize-scale) 2)
left-margin (/ (- width (* 4 bottom-nav-tab-width)) 2)
left-empty-space (* empty-space-half-scale width)
top-empty-space (* empty-space-half-scale
(- height (utils/bottom-tabs-container-height)))]
{:left (reduce
(fn [acc stack-id]
(assoc acc
stack-id
(+ (- left-margin left-empty-space)
(* (.indexOf shell.constants/stacks-ids stack-id)
bottom-nav-tab-width))))
{:none 0}
shell.constants/stacks-ids)
:top (+ top-empty-space (utils/bottom-tabs-container-height))
:scale minimize-scale}))
(defn stacks-and-bottom-tabs-derived-values
[{:keys [selected-stack-id home-stack-state]}]
(let [pass-through (reanimated/use-shared-value false)]
(reduce
(fn [acc id]
(let [tabs-icon-color-keyword (get shell.constants/tabs-icon-color-keywords id)
stack-opacity-keyword (get shell.constants/stacks-opacity-keywords id)
stack-z-index-keyword (get shell.constants/stacks-z-index-keywords id)]
(assoc
acc
stack-opacity-keyword
(worklets.shell/stack-opacity (name id) selected-stack-id)
stack-z-index-keyword
(worklets.shell/stack-z-index (name id) selected-stack-id)
tabs-icon-color-keyword
(worklets.shell/bottom-tab-icon-color
(name id)
selected-stack-id
home-stack-state
pass-through
colors/white
colors/neutral-50
colors/white-opa-40))))
{:bottom-tabs-height (worklets.shell/bottom-tabs-height
home-stack-state
(utils/bottom-tabs-container-height)
(utils/bottom-tabs-extended-container-height))
:pass-through pass-through}
shell.constants/stacks-ids)))
(defn home-stack-derived-values
[{:keys [selected-stack-id home-stack-state]} dimensions]
(let [home-stack-position (calculate-home-stack-position dimensions)
animate-home-stack-left (reanimated/use-shared-value (not (utils/home-stack-open?)))]
{:animate-home-stack-left animate-home-stack-left
:home-stack-left (worklets.shell/home-stack-left
selected-stack-id
animate-home-stack-left
home-stack-state
(clj->js (:left home-stack-position)))
:home-stack-top (worklets.shell/home-stack-top
home-stack-state
(:top home-stack-position))
:home-stack-opacity (worklets.shell/home-stack-opacity home-stack-state)
:home-stack-pointer (worklets.shell/home-stack-pointer home-stack-state)
:home-stack-border-radius (worklets.shell/home-stack-border-radius home-stack-state)
:home-stack-scale (worklets.shell/home-stack-scale
home-stack-state
(:scale home-stack-position))}))
(defn floating-screen-derived-values
[screen-id {:keys [width height]} switcher-card-left-position switcher-card-top-position]
(let [screen-state (reanimated/use-shared-value
(if (utils/floating-screen-open? screen-id)
shell.constants/open-screen-without-animation
shell.constants/close-screen-without-animation))]
{:screen-state screen-state
:screen-left (worklets.shell/floating-screen-left screen-state
width
switcher-card-left-position)
:screen-top (worklets.shell/floating-screen-top screen-state
height
switcher-card-top-position)
:screen-z-index (worklets.shell/floating-screen-z-index screen-state)
:screen-width (worklets.shell/floating-screen-width screen-state
width
shell.constants/switcher-card-size)
:screen-border-radius (worklets.shell/floating-screen-border-radius screen-state)
:screen-height (worklets.shell/floating-screen-height screen-state
height
shell.constants/switcher-card-size)}))
(defn calculate-and-set-shared-values
[alert-banners-top-margin]
(let [{:keys [width height] :as dimensions} (utils/dimensions)
dimensions (assoc dimensions :height (- height alert-banners-top-margin))
switcher-card-left-position (/ (- width (* 2 shell.constants/switcher-card-size)) 3)
switcher-card-top-position (+ (safe-area/get-top) 120)
shared-values
{:selected-stack-id (reanimated/use-shared-value
(name (or @state/selected-stack-id shell.constants/default-selected-stack)))
:home-stack-state (reanimated/use-shared-value
(if (ff/enabled? ::ff/shell.jump-to)
@state/home-stack-state
shell.constants/open-without-animation))}]
;; Whenever shell stack is created, calculate shared values function is called
;; Means On login and on UI reloading (like changing theme)
;; So we are also resetting bottom tabs here (disabling loading of unselected tabs),
;; for Speed up UI reloading
(utils/reset-bottom-tabs)
(reset!
state/shared-values-atom
(merge
shared-values
(stacks-and-bottom-tabs-derived-values shared-values)
(home-stack-derived-values shared-values dimensions)
(into {}
(for [screen-id shell.constants/floating-screens]
[screen-id
(floating-screen-derived-values
screen-id
dimensions
switcher-card-left-position
switcher-card-top-position)]))))
@state/shared-values-atom))

View File

@ -1,19 +0,0 @@
(ns status-im.contexts.shell.jump-to.state
(:require
[reagent.core :as reagent]
[status-im.contexts.shell.jump-to.constants :as shell.constants]))
;; Atoms
(def selected-stack-id (atom nil))
(def screen-height (atom nil))
(def shared-values-atom (atom nil))
(def jump-to-list-ref (atom nil))
(def home-stack-state (atom shell.constants/close-with-animation))
(def floating-screens-state (atom {}))
;; Reagent atoms used for lazily loading home screen tabs
(def load-communities-stack? (reagent/atom false))
(def load-chats-stack? (reagent/atom false))
(def load-wallet-stack? (reagent/atom false))
(def load-browser-stack? (reagent/atom false))

View File

@ -1,139 +0,0 @@
(ns status-im.contexts.shell.jump-to.utils
(:require
[react-native.async-storage :as async-storage]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
[status-im.contexts.shell.jump-to.state :as state]
[status-im.feature-flags :as ff]
[utils.re-frame :as rf]))
;;;; Helper Functions
;;; UI
(defn bottom-tabs-container-height
[]
(if platform/android?
shell.constants/bottom-tabs-container-height-android
shell.constants/bottom-tabs-container-height-ios))
(defn bottom-tabs-extended-container-height
[]
(if platform/android?
shell.constants/bottom-tabs-container-extended-height-android
shell.constants/bottom-tabs-container-extended-height-ios))
(defn status-bar-offset
[]
(if platform/android? (safe-area/get-top) 0))
;; status bar height is not included in : the dimensions/window for devices with a notch
;; https://github.com/facebook/react-native/issues/23693#issuecomment-662860819
;; More info - https://github.com/status-im/status-mobile/issues/14633
(defn dimensions
[]
(let [{:keys [width height]} (rn/get-window)]
{:width width
:height (or @state/screen-height
(if (> (status-bar-offset) 28)
(+ height (status-bar-offset))
height))}))
;;;; State
;;; Home Stack
(defn home-stack-open?
[]
(let [state @state/home-stack-state]
(or (= state shell.constants/open-with-animation)
(= state shell.constants/open-without-animation))))
(defn calculate-home-stack-state-value
[stack-id animate?]
(if animate?
(if (some? stack-id)
shell.constants/open-with-animation
shell.constants/close-with-animation)
(if (some? stack-id)
shell.constants/open-without-animation
shell.constants/close-without-animation)))
(defn load-stack
[stack-id]
(case stack-id
:communities-stack (reset! state/load-communities-stack? true)
:chats-stack (reset! state/load-chats-stack? true)
:wallet-stack (reset! state/load-wallet-stack? true)
:browser-stack (reset! state/load-browser-stack? true)
""))
(defn change-selected-stack-id
[stack-id store? home-stack-state-value]
(let [home-stack-state-value (or home-stack-state-value
(calculate-home-stack-state-value stack-id nil))]
(reset! state/selected-stack-id stack-id)
(reset! state/home-stack-state home-stack-state-value)
(when store?
(async-storage/set-item! :selected-stack-id stack-id))))
(defn reset-bottom-tabs
[]
(let [selected-stack-id @state/selected-stack-id]
(reset! state/load-communities-stack? (= selected-stack-id :communities-stack))
(reset! state/load-chats-stack? (= selected-stack-id :chats-stack))
(reset! state/load-wallet-stack? (= selected-stack-id :wallet-stack))
(reset! state/load-browser-stack? (= selected-stack-id :browser-stack))))
(defn reset-floating-screens
[]
(reset! state/floating-screens-state {})
(when @state/shared-values-atom
(doseq [screen-id (seq shell.constants/floating-screens)]
(reanimated/set-shared-value
(:screen-state (get @state/shared-values-atom screen-id))
shell.constants/close-screen-with-shell-animation))))
;;; Floating screen
(defn- screen-state-open?
[state]
(#{shell.constants/open-screen-without-animation
shell.constants/open-screen-with-shell-animation
shell.constants/open-screen-with-slide-from-right-animation
shell.constants/open-screen-with-slide-from-bottom-animation}
state))
(defn floating-screen-open?
[screen-id]
(screen-state-open? (get @state/floating-screens-state screen-id)))
(defn open-floating-screens
[]
(reduce (fn [acc [screen-id state]]
(let [open? (screen-state-open? state)]
(if open? (assoc acc screen-id true) acc)))
{}
@state/floating-screens-state))
;;; Navigation
(defn shell-navigation?
[view-id]
(and (ff/enabled? ::ff/shell.jump-to)
(some #{view-id} shell.constants/floating-screens)))
(defn calculate-view-id
[]
(let [screens (open-floating-screens)]
(cond
(get screens shell.constants/chat-screen)
shell.constants/chat-screen
(get screens shell.constants/community-screen)
shell.constants/community-screen
(get screens shell.constants/discover-communities-screen)
shell.constants/discover-communities-screen
:else (or @state/selected-stack-id :shell))))
(defn update-view-id
[view-id]
(rf/dispatch [:set-view-id view-id]))

View File

@ -1,54 +0,0 @@
(ns status-im.contexts.shell.jump-to.view
(:require
[quo.core :as quo]
[react-native.core :as rn]
[status-im.contexts.shell.jump-to.animation :as animation]
[status-im.contexts.shell.jump-to.components.bottom-tabs.view :as bottom-tabs]
[status-im.contexts.shell.jump-to.components.floating-screens.view :as floating-screens]
[status-im.contexts.shell.jump-to.components.home-stack.view :as home-stack]
[status-im.contexts.shell.jump-to.components.jump-to-screen.view :as jump-to-screen]
[status-im.contexts.shell.jump-to.shared-values :as shared-values]
[status-im.contexts.shell.jump-to.utils :as utils]
[status-im.feature-flags :as ff]
[status-im.navigation.state :as navigation.state]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- navigate-back-handler
[]
(when (or (seq @navigation.state/modals)
(seq (utils/open-floating-screens))
(> (count (navigation.state/get-navigation-state)) 1))
(rf/dispatch [:navigate-back])
true))
(defn- floating-button
[shared-values]
(let [current-screen-id (rf/sub [:view-id])]
(when-not (= current-screen-id :settings)
[quo/floating-shell-button
{:jump-to {:on-press #(animation/close-home-stack true)
:label (i18n/label :t/jump-to)
:customization-color (rf/sub [:profile/customization-color])}}
{:position :absolute
:bottom (utils/bottom-tabs-container-height)}
(:home-stack-opacity shared-values)])))
(defn shell-stack
[]
(let [alert-banners-top-margin (rf/sub [:alert-banners/top-margin])
shared-values (shared-values/calculate-and-set-shared-values
alert-banners-top-margin)]
(rn/use-mount
(fn []
(rn/hw-back-add-listener navigate-back-handler)
#(rn/hw-back-remove-listener navigate-back-handler)))
[:<>
(when (ff/enabled? ::ff/shell.jump-to)
[jump-to-screen/view])
[:f> bottom-tabs/f-bottom-tabs]
[:f> home-stack/f-home-stack]
(when (ff/enabled? ::ff/shell.jump-to)
[:<>
[floating-button shared-values]
[floating-screens/view]])]))

View File

@ -86,14 +86,14 @@
(utils-address/supported-address? scanned-text)
(when-let [address (utils-address/supported-address->eth-address scanned-text)]
(debounce/debounce-and-dispatch [:generic-scanner/scan-success address] 300)
(debounce/debounce-and-dispatch [:navigate-change-tab :wallet-stack] 300))
(debounce/debounce-and-dispatch [:shell/change-tab :wallet-stack] 300))
(eip681-address? scanned-text)
(do
(debounce/debounce-and-dispatch [:wallet-legacy/request-uri-parsed
(eip681/parse-uri scanned-text)]
300)
(debounce/debounce-and-dispatch [:navigate-change-tab :wallet-stack] 300))
(debounce/debounce-and-dispatch [:shell/change-tab :wallet-stack] 300))
(pairing-qr-code? scanned-text)
;; TODO: https://github.com/status-im/status-mobile/issues/18744

View File

@ -0,0 +1,37 @@
(ns status-im.contexts.shell.shared-values
(:require
[quo.foundations.colors :as colors]
[react-native.reanimated :as reanimated]
[status-im.contexts.shell.constants :as shell.constants]
[status-im.contexts.shell.state :as state]
[status-im.contexts.shell.utils :as utils]
[utils.worklets.shell :as worklets.shell]))
(defn stacks-and-bottom-tabs-derived-values
[selected-stack-id]
(reduce
(fn [acc id]
(let [tabs-icon-color-keyword (get shell.constants/tabs-icon-color-keywords id)
stack-opacity-keyword (get shell.constants/stacks-opacity-keywords id)
stack-z-index-keyword (get shell.constants/stacks-z-index-keywords id)]
(assoc
acc
stack-opacity-keyword
(worklets.shell/stack-opacity (name id) selected-stack-id)
stack-z-index-keyword
(worklets.shell/stack-z-index (name id) selected-stack-id)
tabs-icon-color-keyword
(worklets.shell/bottom-tab-icon-color
(name id)
selected-stack-id
colors/white
colors/neutral-50))))
{}
shell.constants/stacks-ids))
(defn calculate-and-set-shared-values
[]
(let [selected-stack-id (reanimated/use-shared-value (name @state/selected-stack-id-value))]
(utils/reset-bottom-tabs) ;; Reset the state of loaded tabs for faster re-login and hot reloads
(reset! state/selected-stack-id-shared-value selected-stack-id)
(stacks-and-bottom-tabs-derived-values selected-stack-id)))

View File

@ -0,0 +1,14 @@
(ns status-im.contexts.shell.state
(:require
[reagent.core :as reagent]
[status-im.contexts.shell.constants :as shell.constants]))
;; Atoms
(def selected-stack-id-value (atom shell.constants/default-selected-stack))
(def selected-stack-id-shared-value (atom nil))
;; Reagent atoms used for lazily loading home screen tabs
(def load-communities-stack? (reagent/atom false))
(def load-chats-stack? (reagent/atom false))
(def load-wallet-stack? (reagent/atom false))
(def load-browser-stack? (reagent/atom false))

View File

@ -0,0 +1,36 @@
(ns status-im.contexts.shell.utils
(:require
[react-native.async-storage :as async-storage]
[react-native.platform :as platform]
[status-im.contexts.shell.constants :as shell.constants]
[status-im.contexts.shell.state :as state]))
(defn bottom-tabs-container-height
[]
(if platform/android?
shell.constants/bottom-tabs-container-height-android
shell.constants/bottom-tabs-container-height-ios))
(defn load-stack
[stack-id]
(case stack-id
:communities-stack (reset! state/load-communities-stack? true)
:chats-stack (reset! state/load-chats-stack? true)
:wallet-stack (reset! state/load-wallet-stack? true)
:browser-stack (reset! state/load-browser-stack? true)
""))
(defn change-selected-stack
[stack-id]
(when stack-id
(load-stack stack-id)
(reset! state/selected-stack-id-value stack-id)
(async-storage/set-item! :selected-stack-id stack-id)))
(defn reset-bottom-tabs
[]
(let [selected-stack-id @state/selected-stack-id-value]
(reset! state/load-communities-stack? (= selected-stack-id :communities-stack))
(reset! state/load-chats-stack? (= selected-stack-id :chats-stack))
(reset! state/load-wallet-stack? (= selected-stack-id :wallet-stack))
(reset! state/load-browser-stack? (= selected-stack-id :browser-stack))))

View File

@ -0,0 +1,27 @@
(ns status-im.contexts.shell.view
(:require
[quo.foundations.colors :as colors]
[react-native.core :as rn]
[status-im.contexts.shell.bottom-tabs.view :as bottom-tabs]
[status-im.contexts.shell.home-stack.view :as home-stack]
[status-im.contexts.shell.shared-values :as shared-values]
[status-im.navigation.state :as navigation.state]
[utils.re-frame :as rf]))
(defn- navigate-back-handler
[]
(when (or (seq @navigation.state/modals)
(> (count (navigation.state/get-navigation-state)) 1))
(rf/dispatch [:navigate-back])
true))
(defn shell-stack
[]
(let [shared-values (shared-values/calculate-and-set-shared-values)]
(rn/use-mount
(fn []
(rn/hw-back-add-listener navigate-back-handler)
#(rn/hw-back-remove-listener navigate-back-handler)))
[rn/view {:style {:background-color colors/neutral-100 :flex 1}}
[home-stack/view shared-values]
[bottom-tabs/view shared-values]]))

View File

@ -5,7 +5,7 @@
[react-native.core :as rn]
[status-im.config :as config]
[status-im.contexts.profile.utils :as profile.utils]
[status-im.contexts.shell.jump-to.constants :as constants]
[status-im.contexts.shell.constants :as constants]
[status-im.contexts.wallet.account.tabs.about.style :as style]
[status-im.contexts.wallet.common.utils :as utils]
[utils.i18n :as i18n]

View File

@ -1,5 +1,5 @@
(ns status-im.contexts.wallet.account.tabs.assets.style
(:require [status-im.contexts.shell.jump-to.constants :as constants]))
(:require [status-im.contexts.shell.constants :as constants]))
(def list-container-style
{:padding-horizontal 8

View File

@ -26,7 +26,6 @@
(let [selected-tab (or (rf/sub [:wallet/account-tab]) first-tab-id)
{:keys [name color formatted-balance
watch-only?]} (rf/sub [:wallet/current-viewing-account])
customization-color (rf/sub [:profile/customization-color])
testnet-mode? (rf/sub [:profile/test-networks-enabled?])]
(hot-reload/use-safe-unmount (fn []
(rf/dispatch [:wallet/close-account-page])
@ -74,11 +73,4 @@
:on-change change-tab
:scrollable? true
:scroll-on-press? true}]
[tabs/view {:selected-tab selected-tab}]
(when (ff/enabled? ::ff/shell.jump-to)
[quo/floating-shell-button
{:jump-to
{:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
:customization-color customization-color
:label (i18n/label :t/jump-to)}}
style/shell-button])]))
[tabs/view {:selected-tab selected-tab}]]))

View File

@ -6,7 +6,7 @@
[react-native.core :as rn]
[status-im.common.resources :as resources]
[status-im.constants :as constants]
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]
[status-im.contexts.shell.constants :as shell.constants]
[status-im.contexts.wallet.common.empty-tab.view :as empty-tab]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@ -152,6 +152,6 @@
:sticky-section-headers-enabled false
:style {:flex 1
:padding-horizontal 8}
:content-container-style {:padding-bottom jump-to.constants/floating-shell-button-height}
:content-container-style {:padding-bottom shell.constants/floating-shell-button-height}
:render-fn activity-item
:render-section-header-fn section-header}])]))

View File

@ -1,5 +1,5 @@
(ns status-im.contexts.wallet.common.collectibles-tab.style
(:require [status-im.contexts.shell.jump-to.constants :as constants]))
(:require [status-im.contexts.shell.constants :as constants]))
(def list-container-style
{:margin-horizontal 12

View File

@ -2,7 +2,7 @@
(:require
[quo.foundations.colors :as colors]
[react-native.safe-area :as safe-area]
[status-im.contexts.shell.jump-to.constants :as constants]))
[status-im.contexts.shell.constants :as constants]))
(def tabs
{:padding-horizontal 20

View File

@ -1,5 +1,5 @@
(ns status-im.contexts.wallet.home.tabs.assets.style
(:require [status-im.contexts.shell.jump-to.constants :as constants]))
(:require [status-im.contexts.shell.constants :as constants]))
(def list-container
{:padding-horizontal 8

Some files were not shown because too many files have changed in this diff Show More