[#6455]: Updated extension management
Signed-off-by: Aleksandr Pantiukhov <alwxndr@gmail.com>
This commit is contained in:
parent
8592b25093
commit
17f74ff2f6
|
@ -63,10 +63,10 @@
|
||||||
(let [extensions (-> account :extensions vals)]
|
(let [extensions (-> account :extensions vals)]
|
||||||
(if dev-mode?
|
(if dev-mode?
|
||||||
{:extensions/load {:extensions extensions
|
{:extensions/load {:extensions extensions
|
||||||
:follow-up :extensions/add}}
|
:follow-up :extensions/add-to-registry}}
|
||||||
{:dispatch [:extensions/deactivate-all (filter :active? extensions)]})))
|
{:dispatch [:extensions/update-hooks extensions]})))
|
||||||
|
|
||||||
(fx/defn switch-dev-mode [{{:account/keys [account]} :db :as cofx} dev-mode?]
|
(fx/defn switch-dev-mode [cofx dev-mode?]
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
(update-dev-server-state dev-mode?)
|
(update-dev-server-state dev-mode?)
|
||||||
(update-extensions-state dev-mode?)
|
(update-extensions-state dev-mode?)
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
(s/def :chat/current-chat-id (s/nilable string?)) ; current or last opened chat-id
|
(s/def :chat/current-chat-id (s/nilable string?)) ; current or last opened chat-id
|
||||||
(s/def :chat/chat-id (s/nilable string?)) ; what is the difference ? ^
|
(s/def :chat/chat-id (s/nilable string?)) ; what is the difference ? ^
|
||||||
(s/def :chat/new-chat-name (s/nilable string?)) ; we have name in the new-chat why do we need this field
|
(s/def :chat/new-chat-name (s/nilable string?)) ; we have name in the new-chat why do we need this field
|
||||||
(s/def :chat/chat-animations (s/nilable map?)) ; {id (string) props (map)}
|
(s/def :chat/animations (s/nilable map?)) ; {id (string) props (map)}
|
||||||
(s/def :chat/chat-ui-props (s/nilable map?)) ; {id (string) props (map)}
|
(s/def :chat/chat-ui-props (s/nilable map?)) ; {id (string) props (map)}
|
||||||
(s/def :chat/chat-list-ui-props (s/nilable map?))
|
(s/def :chat/chat-list-ui-props (s/nilable map?))
|
||||||
(s/def :chat/layout-height (s/nilable number?)) ; height of chat's view layout
|
(s/def :chat/layout-height (s/nilable number?)) ; height of chat's view layout
|
||||||
|
|
|
@ -370,7 +370,7 @@
|
||||||
:chat-animations
|
:chat-animations
|
||||||
(fn [db [_ key type]]
|
(fn [db [_ key type]]
|
||||||
(let [chat-id (subscribe [:get-current-chat-id])]
|
(let [chat-id (subscribe [:get-current-chat-id])]
|
||||||
(get-in db [:chat-animations @chat-id key type]))))
|
(get-in db [:animations :chats @chat-id key type]))))
|
||||||
|
|
||||||
(reg-sub
|
(reg-sub
|
||||||
:get-chats-unread-messages-number
|
:get-chats-unread-messages-number
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
|
|
||||||
(defn- deserialize-extensions [extensions]
|
(defn- deserialize-extensions [extensions]
|
||||||
(reduce-kv
|
(reduce-kv
|
||||||
(fn [acc _ {:keys [id] :as extension}]
|
(fn [acc _ {:keys [url] :as extension}]
|
||||||
(assoc acc id extension))
|
(assoc acc url extension))
|
||||||
{}
|
{}
|
||||||
extensions))
|
extensions))
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
[status-im.contact.core :as contact]
|
[status-im.contact.core :as contact]
|
||||||
[status-im.data-store.core :as data-store]
|
[status-im.data-store.core :as data-store]
|
||||||
[status-im.extensions.core :as extensions]
|
[status-im.extensions.core :as extensions]
|
||||||
|
[status-im.extensions.registry :as extensions.registry]
|
||||||
[status-im.fleet.core :as fleet]
|
[status-im.fleet.core :as fleet]
|
||||||
[status-im.group-chats.core :as group-chats]
|
[status-im.group-chats.core :as group-chats]
|
||||||
[status-im.hardwallet.core :as hardwallet]
|
[status-im.hardwallet.core :as hardwallet]
|
||||||
|
@ -34,9 +35,7 @@
|
||||||
[status-im.search.core :as search]
|
[status-im.search.core :as search]
|
||||||
[status-im.signals.core :as signals]
|
[status-im.signals.core :as signals]
|
||||||
[status-im.transport.message.core :as transport.message]
|
[status-im.transport.message.core :as transport.message]
|
||||||
[status-im.ui.screens.currency-settings.models
|
[status-im.ui.screens.currency-settings.models :as currency-settings.models]
|
||||||
:as
|
|
||||||
currency-settings.models]
|
|
||||||
[status-im.ui.screens.navigation :as navigation]
|
[status-im.ui.screens.navigation :as navigation]
|
||||||
[status-im.utils.fx :as fx]
|
[status-im.utils.fx :as fx]
|
||||||
[status-im.utils.handlers :as handlers]
|
[status-im.utils.handlers :as handlers]
|
||||||
|
@ -459,8 +458,13 @@
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:extensions.ui/add-extension-pressed
|
:extensions.ui/add-extension-pressed
|
||||||
(fn [cofx [_ id]]
|
(fn [cofx [_ extension-key]]
|
||||||
(extensions/edit cofx id)))
|
(extensions/edit cofx extension-key)))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:extensions.ui/uninstall-extension-pressed
|
||||||
|
(fn [cofx [_ extension-key]]
|
||||||
|
(extensions.registry/uninstall cofx extension-key)))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:extensions.ui/input-changed
|
:extensions.ui/input-changed
|
||||||
|
@ -469,19 +473,19 @@
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:extensions.ui/activation-checkbox-pressed
|
:extensions.ui/activation-checkbox-pressed
|
||||||
(fn [cofx [_ id state]]
|
(fn [cofx [_ extension-key active?]]
|
||||||
(extensions/toggle-activation cofx id state)))
|
(extensions.registry/change-state cofx extension-key active?)))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:extensions.ui/show-button-pressed
|
:extensions.ui/show-button-pressed
|
||||||
(fn [cofx [_ url]]
|
(fn [cofx [_ url]]
|
||||||
(extensions/load cofx url)))
|
(extensions.registry/load cofx url)))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:extensions.ui/install-button-pressed
|
:extensions.ui/install-button-pressed
|
||||||
[(re-frame/inject-cofx :random-id-generator)]
|
[(re-frame/inject-cofx :random-id-generator)]
|
||||||
(fn [cofx [_ data]]
|
(fn [cofx [_ data]]
|
||||||
(extensions/install cofx data)))
|
(extensions.registry/install cofx data)))
|
||||||
|
|
||||||
;; log-level module
|
;; log-level module
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
(ns status-im.extensions.core
|
(ns status-im.extensions.core
|
||||||
(:refer-clojure :exclude [list])
|
(:refer-clojure :exclude [list])
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
[pluto.reader :as reader]
|
|
||||||
[pluto.registry :as registry]
|
|
||||||
[pluto.storages :as storages]
|
[pluto.storages :as storages]
|
||||||
|
[pluto.reader :as reader]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.accounts.update.core :as accounts.update]
|
|
||||||
[status-im.chat.commands.core :as commands]
|
[status-im.chat.commands.core :as commands]
|
||||||
[status-im.chat.commands.impl.transactions :as transactions]
|
[status-im.chat.commands.impl.transactions :as transactions]
|
||||||
[status-im.ui.components.button.view :as button]
|
[status-im.ui.components.button.view :as button]
|
||||||
[status-im.ui.components.checkbox.view :as checkbox]
|
[status-im.ui.components.checkbox.view :as checkbox]
|
||||||
[status-im.ui.components.list.views :as list]
|
[status-im.ui.components.list.views :as list]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.i18n :as i18n]
|
|
||||||
[status-im.ui.components.colors :as colors]
|
[status-im.ui.components.colors :as colors]
|
||||||
[status-im.ui.screens.navigation :as navigation]
|
[status-im.ui.screens.navigation :as navigation]
|
||||||
[status-im.utils.handlers :as handlers]
|
[status-im.utils.handlers :as handlers]
|
||||||
|
@ -324,64 +321,11 @@
|
||||||
[{:keys [db]} input-key value]
|
[{:keys [db]} input-key value]
|
||||||
{:db (update db :extensions/manage assoc input-key {:value value})})
|
{:db (update db :extensions/manage assoc input-key {:value value})})
|
||||||
|
|
||||||
(fx/defn fetch [cofx id]
|
(fx/defn fetch [cofx ext-key]
|
||||||
(get-in cofx [:db :account/account :extensions id]))
|
(get-in cofx [:db :account/account :extensions ext-key]))
|
||||||
|
|
||||||
(fx/defn edit
|
(fx/defn edit
|
||||||
[cofx id]
|
[cofx extension-key]
|
||||||
(let [{:keys [url]} (fetch cofx id)]
|
(let [{:keys [url]} (fetch cofx extension-key)]
|
||||||
(fx/merge (set-input cofx :url (str url))
|
(fx/merge (set-input cofx :url (str url))
|
||||||
(navigation/navigate-to-cofx :edit-extension nil))))
|
(navigation/navigate-to-cofx :edit-extension nil))))
|
||||||
|
|
||||||
(fx/defn add
|
|
||||||
[cofx extension-data active?]
|
|
||||||
(let [extension-key "extension"
|
|
||||||
extension-data (assoc-in extension-data ['meta :name] extension-key)]
|
|
||||||
(fx/merge cofx
|
|
||||||
#(registry/deactivate extension-key %)
|
|
||||||
#(registry/add extension-data %)
|
|
||||||
(when active?
|
|
||||||
#(registry/activate extension-key %)))))
|
|
||||||
|
|
||||||
(fx/defn install
|
|
||||||
[{{:extensions/keys [manage] :account/keys [account] :as db} :db
|
|
||||||
random-id-generator :random-id-generator :as cofx}
|
|
||||||
extension-data]
|
|
||||||
(let [extension-key (get-in extension-data ['meta :name])
|
|
||||||
{:keys [url id]} manage
|
|
||||||
extension {:id (or (:value id) "extension")
|
|
||||||
:name (str extension-key)
|
|
||||||
:url (:value url)
|
|
||||||
:active? true}
|
|
||||||
new-extensions (assoc (:extensions account) (:id extension) extension)]
|
|
||||||
(fx/merge cofx
|
|
||||||
{:ui/show-confirmation {:title (i18n/label :t/success)
|
|
||||||
:content (i18n/label :t/extension-installed)
|
|
||||||
:on-accept #(re-frame/dispatch [:navigate-to-clean :my-profile])
|
|
||||||
:on-cancel nil}}
|
|
||||||
(accounts.update/account-update {:extensions new-extensions} {})
|
|
||||||
(add extension-data true))))
|
|
||||||
|
|
||||||
(fx/defn toggle-activation
|
|
||||||
[cofx id state]
|
|
||||||
(let [toggle-fn (get {true registry/activate
|
|
||||||
false registry/deactivate}
|
|
||||||
state)
|
|
||||||
extensions (get-in cofx [:db :account/account :extensions])
|
|
||||||
new-extensions (assoc-in extensions [id :active?] state)]
|
|
||||||
(fx/merge cofx
|
|
||||||
(accounts.update/account-update {:extensions new-extensions} {:success-event nil})
|
|
||||||
#(toggle-fn id %))))
|
|
||||||
|
|
||||||
(fx/defn load
|
|
||||||
[_ url]
|
|
||||||
{:extensions/load {:extensions [{:url (string/trim url)
|
|
||||||
:active? true}]
|
|
||||||
:follow-up :extensions/stage}})
|
|
||||||
|
|
||||||
(fx/defn activate-extensions
|
|
||||||
[{{:account/keys [account]} :db}]
|
|
||||||
(let [{:keys [extensions dev-mode?]} account]
|
|
||||||
(when dev-mode?
|
|
||||||
{:extensions/load {:extensions (vals extensions)
|
|
||||||
:follow-up :extensions/add}})))
|
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
(ns status-im.extensions.registry
|
||||||
|
(:refer-clojure :exclude [list])
|
||||||
|
(:require [clojure.string :as string]
|
||||||
|
[pluto.utils :as utils]
|
||||||
|
[pluto.reader.hooks :as hooks]
|
||||||
|
[re-frame.core :as re-frame]
|
||||||
|
[status-im.accounts.update.core :as accounts.update]
|
||||||
|
[status-im.i18n :as i18n]
|
||||||
|
[status-im.utils.fx :as fx]
|
||||||
|
[clojure.set :as set]))
|
||||||
|
|
||||||
|
(fx/defn update-hooks
|
||||||
|
[{:keys [db] :as cofx} hook-fn extension-key]
|
||||||
|
(let [account (get db :account/account)
|
||||||
|
hooks (get-in account [:extensions extension-key :hooks])]
|
||||||
|
(apply utils/merge-fx cofx
|
||||||
|
(mapcat (fn [[_ extension-hooks]]
|
||||||
|
(map (fn [[hook-id {:keys [hook-ref parsed]}]]
|
||||||
|
(partial hook-fn (:hook hook-ref) hook-id parsed))
|
||||||
|
extension-hooks))
|
||||||
|
hooks))))
|
||||||
|
|
||||||
|
(fx/defn add-to-registry
|
||||||
|
[{:keys [db] :as cofx} extension-key extension-data active?]
|
||||||
|
(let [{:keys [hooks]} extension-data
|
||||||
|
data {:hooks hooks
|
||||||
|
:active? active?}]
|
||||||
|
(fx/merge cofx
|
||||||
|
{:db (update-in db [:account/account :extensions extension-key] merge data)}
|
||||||
|
(update-hooks hooks/hook-in extension-key))))
|
||||||
|
|
||||||
|
(fx/defn remove-from-registry
|
||||||
|
[{:keys [db] :as cofx} extension-key]
|
||||||
|
(fx/merge cofx
|
||||||
|
(update-hooks hooks/unhook extension-key)
|
||||||
|
{:db (update-in db [:account/account :extensions] dissoc extension-key)}))
|
||||||
|
|
||||||
|
(fx/defn change-state
|
||||||
|
[cofx extension-key active?]
|
||||||
|
(let [extensions (get-in cofx [:db :account/account :extensions])
|
||||||
|
new-extensions (assoc-in extensions [extension-key :active?] active?)
|
||||||
|
hook-fn (if active?
|
||||||
|
hooks/hook-in
|
||||||
|
hooks/unhook)]
|
||||||
|
(fx/merge cofx
|
||||||
|
(accounts.update/account-update {:extensions new-extensions} {:success-event nil})
|
||||||
|
(update-hooks hook-fn extension-key))))
|
||||||
|
|
||||||
|
(fx/defn install
|
||||||
|
[{:keys [db random-id-generator] :as cofx} extension-data]
|
||||||
|
(let [{:extensions/keys [manage]
|
||||||
|
:account/keys [account]} db
|
||||||
|
{:keys [id url]} manage
|
||||||
|
extension {:id (-> (:value id)
|
||||||
|
(or (random-id-generator))
|
||||||
|
(string/replace "-" ""))
|
||||||
|
:name (get-in extension-data ['meta :name])
|
||||||
|
:url (:value url)
|
||||||
|
:active? true}
|
||||||
|
new-extensions (assoc (:extensions account) (:url extension) extension)]
|
||||||
|
(fx/merge cofx
|
||||||
|
{:ui/show-confirmation {:title (i18n/label :t/success)
|
||||||
|
:content (i18n/label :t/extension-installed)
|
||||||
|
:on-accept #(re-frame/dispatch [:navigate-to-clean :my-profile])
|
||||||
|
:on-cancel nil}}
|
||||||
|
(accounts.update/account-update {:extensions new-extensions} {})
|
||||||
|
(add-to-registry (:value url) extension-data true))))
|
||||||
|
|
||||||
|
(fx/defn uninstall
|
||||||
|
[{:keys [db] :as cofx} extension-key]
|
||||||
|
(let [{:account/keys [account]} db
|
||||||
|
new-extensions (dissoc (:extensions account) extension-key)]
|
||||||
|
(fx/merge cofx
|
||||||
|
{:ui/show-confirmation {:title (i18n/label :t/success)
|
||||||
|
:content (i18n/label :t/extension-uninstalled)
|
||||||
|
:on-accept nil
|
||||||
|
:on-cancel nil}}
|
||||||
|
(remove-from-registry extension-key)
|
||||||
|
(accounts.update/account-update {:extensions new-extensions} {}))))
|
||||||
|
|
||||||
|
(fx/defn load
|
||||||
|
[cofx url]
|
||||||
|
(if (get-in cofx [:db :account/account :extensions url])
|
||||||
|
{:utils/show-popup {:title (i18n/label :t/error)
|
||||||
|
:content (i18n/label :t/extension-is-already-added)}}
|
||||||
|
{:extensions/load {:extensions [{:url (string/trim url)
|
||||||
|
:active? true}]
|
||||||
|
:follow-up :extensions/stage}}))
|
||||||
|
|
||||||
|
(fx/defn initialize
|
||||||
|
[{{:account/keys [account]} :db}]
|
||||||
|
(let [{:keys [extensions dev-mode?]} account]
|
||||||
|
(when dev-mode?
|
||||||
|
{:extensions/load {:extensions (vals extensions)
|
||||||
|
:follow-up :extensions/add-to-registry}})))
|
||||||
|
|
||||||
|
(defn existing-hooks-for
|
||||||
|
[type cofx extension-data]
|
||||||
|
(let [added-hooks (reduce (fn [acc [_ {:keys [hooks]}]]
|
||||||
|
(->> (type hooks)
|
||||||
|
(keys)
|
||||||
|
(into acc)))
|
||||||
|
#{}
|
||||||
|
(get-in cofx [:db :account/account :extensions]))
|
||||||
|
hooks (->> (get-in extension-data [:data :hooks type])
|
||||||
|
(keys)
|
||||||
|
(into #{}))]
|
||||||
|
(set/intersection added-hooks hooks)))
|
||||||
|
|
||||||
|
(defn existing-hooks [cofx extension-data]
|
||||||
|
(->> (get-in extension-data [:data :hooks])
|
||||||
|
(keys)
|
||||||
|
(map #(existing-hooks-for % cofx extension-data))
|
||||||
|
(apply set/union)))
|
|
@ -7,7 +7,7 @@
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.data-store.core :as data-store]
|
[status-im.data-store.core :as data-store]
|
||||||
[status-im.data-store.realm.core :as realm]
|
[status-im.data-store.realm.core :as realm]
|
||||||
[status-im.extensions.core :as extensions]
|
[status-im.extensions.registry :as extensions.registry]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.browser.core :as browser]
|
[status-im.browser.core :as browser]
|
||||||
[status-im.contact.core :as contact]
|
[status-im.contact.core :as contact]
|
||||||
|
@ -218,7 +218,7 @@
|
||||||
(chat-loading/initialize-pending-messages)
|
(chat-loading/initialize-pending-messages)
|
||||||
(browser/initialize-browsers)
|
(browser/initialize-browsers)
|
||||||
(browser/initialize-dapp-permissions)
|
(browser/initialize-dapp-permissions)
|
||||||
(extensions/activate-extensions)
|
(extensions.registry/initialize)
|
||||||
#(when-not platform/desktop?
|
#(when-not platform/desktop?
|
||||||
(initialize-wallet %))
|
(initialize-wallet %))
|
||||||
(accounts.update/update-sign-in-time)
|
(accounts.update/update-sign-in-time)
|
||||||
|
|
|
@ -120,3 +120,19 @@
|
||||||
|
|
||||||
(def label
|
(def label
|
||||||
{:color colors/gray})
|
{:color colors/gray})
|
||||||
|
|
||||||
|
(def delete-button-width 100)
|
||||||
|
|
||||||
|
(def delete-icon-highlight
|
||||||
|
{:position :absolute
|
||||||
|
:top 0
|
||||||
|
:bottom 0
|
||||||
|
:right -800
|
||||||
|
:width 800
|
||||||
|
:background-color colors/red-light})
|
||||||
|
|
||||||
|
(def delete-icon-container
|
||||||
|
{:flex 1
|
||||||
|
:width delete-button-width
|
||||||
|
:justify-content :center
|
||||||
|
:align-items :center})
|
|
@ -18,13 +18,16 @@
|
||||||
|
|
||||||
[section-list {:sections [{:title \"\" :key :unik :render-fn render :data {:title \"\" :subtitle \"\"}}]}]
|
[section-list {:sections [{:title \"\" :key :unik :render-fn render :data {:title \"\" :subtitle \"\"}}]}]
|
||||||
"
|
"
|
||||||
|
(:require-macros [status-im.utils.views :as views])
|
||||||
(:require [reagent.core :as reagent]
|
(:require [reagent.core :as reagent]
|
||||||
|
[status-im.ui.components.animation :as animation]
|
||||||
[status-im.ui.components.checkbox.view :as checkbox]
|
[status-im.ui.components.checkbox.view :as checkbox]
|
||||||
[status-im.ui.components.colors :as colors]
|
[status-im.ui.components.colors :as colors]
|
||||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||||
[status-im.ui.components.list.styles :as styles]
|
[status-im.ui.components.list.styles :as styles]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.utils.platform :as platform]))
|
[status-im.utils.platform :as platform]
|
||||||
|
[status-im.ui.screens.home.animations.responder :as responder]))
|
||||||
|
|
||||||
(def flat-list-class (react/get-class "FlatList"))
|
(def flat-list-class (react/get-class "FlatList"))
|
||||||
(def section-list-class (react/get-class "SectionList"))
|
(def section-list-class (react/get-class "SectionList"))
|
||||||
|
@ -219,3 +222,16 @@
|
||||||
[react/text {:style styles/label}
|
[react/text {:style styles/label}
|
||||||
label]
|
label]
|
||||||
list])
|
list])
|
||||||
|
|
||||||
|
(views/defview deletable-list-item [{:keys [type id on-delete]} body]
|
||||||
|
(views/letsubs [swiped? [:delete-swipe-position type id]]
|
||||||
|
(let [offset-x (animation/create-value (if swiped? styles/delete-button-width 0))
|
||||||
|
swipe-pan-responder (responder/swipe-pan-responder offset-x styles/delete-button-width id swiped?)
|
||||||
|
swipe-pan-handler (responder/pan-handlers swipe-pan-responder)]
|
||||||
|
[react/view swipe-pan-handler
|
||||||
|
[react/animated-view {:style {:flex 1 :right offset-x}}
|
||||||
|
body
|
||||||
|
[react/touchable-highlight {:style styles/delete-icon-highlight
|
||||||
|
:on-press on-delete}
|
||||||
|
[react/view {:style styles/delete-icon-container}
|
||||||
|
[vector-icons/icon :icons/delete {:color colors/red}]]]]])))
|
|
@ -4,7 +4,6 @@
|
||||||
[status-im.utils.platform :as platform]
|
[status-im.utils.platform :as platform]
|
||||||
[status-im.utils.dimensions :as dimensions]
|
[status-im.utils.dimensions :as dimensions]
|
||||||
[status-im.fleet.core :as fleet]
|
[status-im.fleet.core :as fleet]
|
||||||
pluto.registry
|
|
||||||
status-im.transport.db
|
status-im.transport.db
|
||||||
status-im.accounts.db
|
status-im.accounts.db
|
||||||
status-im.contact.db
|
status-im.contact.db
|
||||||
|
@ -274,7 +273,7 @@
|
||||||
:chat/chat-id
|
:chat/chat-id
|
||||||
:chat/new-chat
|
:chat/new-chat
|
||||||
:chat/new-chat-name
|
:chat/new-chat-name
|
||||||
:chat/chat-animations
|
:chat/animations
|
||||||
:chat/chat-ui-props
|
:chat/chat-ui-props
|
||||||
:chat/chat-list-ui-props
|
:chat/chat-list-ui-props
|
||||||
:chat/layout-height
|
:chat/layout-height
|
||||||
|
|
|
@ -141,8 +141,8 @@
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:set-swipe-position
|
:set-swipe-position
|
||||||
(fn [{:keys [db]} [_ item-id value]]
|
(fn [{:keys [db]} [_ type item-id value]]
|
||||||
{:db (assoc-in db [:chat-animations item-id :delete-swiped] value)}))
|
{:db (assoc-in db [:animations type item-id :delete-swiped] value)}))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:show-tab-bar
|
:show-tab-bar
|
||||||
|
|
|
@ -1,32 +1,40 @@
|
||||||
(ns status-im.ui.screens.extensions.add.events
|
(ns status-im.ui.screens.extensions.add.events
|
||||||
(:require [pluto.registry :as registry]
|
(:require [re-frame.core :as re-frame]
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[status-im.extensions.core :as extensions]
|
[status-im.extensions.core :as extensions]
|
||||||
|
[status-im.extensions.registry :as extensions.registry]
|
||||||
[status-im.ui.screens.navigation :as navigation]
|
[status-im.ui.screens.navigation :as navigation]
|
||||||
[status-im.utils.handlers :as handlers]
|
[status-im.utils.handlers :as handlers]
|
||||||
[status-im.utils.fx :as fx]))
|
[status-im.utils.fx :as fx]
|
||||||
|
[status-im.i18n :as i18n]))
|
||||||
|
|
||||||
(re-frame/reg-fx
|
(re-frame/reg-fx
|
||||||
:extensions/load
|
:extensions/load
|
||||||
(fn [{:keys [extensions follow-up]}]
|
(fn [{:keys [extensions follow-up]}]
|
||||||
(doseq [{:keys [url active?]} extensions]
|
(doseq [{:keys [url active?]} extensions]
|
||||||
(extensions/load-from url #(re-frame/dispatch [follow-up (extensions/parse-extension %) active?])))))
|
(extensions/load-from url #(re-frame/dispatch [follow-up url (extensions/parse-extension %) active?])))))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:extensions/stage
|
:extensions/stage
|
||||||
(fn [{:keys [db] :as cofx} [_ extension-data]]
|
(fn [{:keys [db] :as cofx} [_ _ extension-data]]
|
||||||
|
(let [hooks (extensions.registry/existing-hooks cofx extension-data)]
|
||||||
|
(if (empty? hooks)
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
{:db (assoc db :staged-extension extension-data)}
|
{:db (assoc db :staged-extension extension-data)}
|
||||||
(navigation/navigate-to-cofx :show-extension nil))))
|
(navigation/navigate-to-cofx :show-extension nil))
|
||||||
|
{:utils/show-popup {:title (i18n/label :t/error)
|
||||||
|
:content (i18n/label :t/extension-hooks-cannot-be-added
|
||||||
|
{:hooks (->> hooks
|
||||||
|
(map name)
|
||||||
|
(clojure.string/join ", "))})}}))))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:extensions/add
|
:extensions/add-to-registry
|
||||||
(fn [cofx [_ {:keys [data]} active?]]
|
(fn [cofx [_ extension-key {:keys [data]} active?]]
|
||||||
(extensions/add cofx data active?)))
|
(extensions.registry/add-to-registry cofx extension-key data active?)))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:extensions/deactivate-all
|
:extensions/update-hooks
|
||||||
(fn [cofx [_ extensions]]
|
(fn [cofx [_ extensions]]
|
||||||
(apply fx/merge cofx (map (fn [{:keys [id]}]
|
(apply fx/merge cofx (map (fn [{:keys [url]}]
|
||||||
(partial registry/deactivate id))
|
(extensions.registry/update-hooks cofx url))
|
||||||
extensions))))
|
extensions))))
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
:extension/name
|
:extension/name
|
||||||
:extension/url
|
:extension/url
|
||||||
:extension/active?]
|
:extension/active?]
|
||||||
:opt-un [:extension/data]))
|
:opt-un [:extension/data
|
||||||
|
:extension/hooks]))
|
||||||
|
|
||||||
(spec/def :extensions/extensions (spec/nilable (spec/map-of :extension/id :extension/extension)))
|
(spec/def :extensions/extensions (spec/nilable (spec/map-of :extension/id :extension/extension)))
|
||||||
|
|
|
@ -14,15 +14,20 @@
|
||||||
[react/view (styles/mailserver-icon true)
|
[react/view (styles/mailserver-icon true)
|
||||||
[vector-icons/icon :icons/mailserver {:color :white}]])
|
[vector-icons/icon :icons/mailserver {:color :white}]])
|
||||||
|
|
||||||
(defn- render-extension [{:keys [id name url active?]}]
|
(defn- render-extension [{:keys [name url active?]}]
|
||||||
|
[list/deletable-list-item {:type :extensions
|
||||||
|
:id url
|
||||||
|
:on-delete #(do
|
||||||
|
(re-frame/dispatch [:set-swipe-position :extensions url false])
|
||||||
|
(re-frame/dispatch [:extensions.ui/uninstall-extension-pressed url]))}
|
||||||
[list/list-item-with-checkbox
|
[list/list-item-with-checkbox
|
||||||
{:checked? active?
|
{:checked? active?
|
||||||
:on-value-change #(re-frame/dispatch [:extensions.ui/activation-checkbox-pressed id %])}
|
:on-value-change #(re-frame/dispatch [:extensions.ui/activation-checkbox-pressed url %])}
|
||||||
[list/item
|
[list/item
|
||||||
mailserver-icon
|
mailserver-icon
|
||||||
[list/item-content
|
[list/item-content
|
||||||
[list/item-primary name]
|
[list/item-primary name]
|
||||||
[list/item-secondary url]]]])
|
[list/item-secondary url]]]]])
|
||||||
|
|
||||||
(views/defview extensions-settings []
|
(views/defview extensions-settings []
|
||||||
(views/letsubs [extensions [:extensions/all-extensions]]
|
(views/letsubs [extensions [:extensions/all-extensions]]
|
||||||
|
@ -38,6 +43,8 @@
|
||||||
:default-separator? false
|
:default-separator? false
|
||||||
:key-fn :id
|
:key-fn :id
|
||||||
:render-fn render-extension
|
:render-fn render-extension
|
||||||
:content-container-style (merge (when (zero? (count extensions)) {:flex-grow 1}) {:justify-content :center})
|
:content-container-style (merge (when (zero? (count extensions))
|
||||||
|
{:flex-grow 1})
|
||||||
|
{:justify-content :center})
|
||||||
:empty-component [react/text {:style styles/empty-list}
|
:empty-component [react/text {:style styles/empty-list}
|
||||||
(i18n/label :t/no-extension)]}]]]))
|
(i18n/label :t/no-extension)]}]]]))
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
(let [updated-value (get-updated-value gesture end-offset-x swiped?)
|
(let [updated-value (get-updated-value gesture end-offset-x swiped?)
|
||||||
should-open? (> updated-value (/ end-offset-x 2))
|
should-open? (> updated-value (/ end-offset-x 2))
|
||||||
to-value (if should-open? end-offset-x 0)]
|
to-value (if should-open? end-offset-x 0)]
|
||||||
(re-frame/dispatch [:set-swipe-position chat-id should-open?])
|
(re-frame/dispatch [:set-swipe-position :chats chat-id should-open?])
|
||||||
(animation/start (animation/spring animated-offset-x {:toValue to-value})))))
|
(animation/start (animation/spring animated-offset-x {:toValue to-value})))))
|
||||||
|
|
||||||
(defn swipe-pan-responder [animated-offset-x end-offset-x chat-id swiped?]
|
(defn swipe-pan-responder [animated-offset-x end-offset-x chat-id swiped?]
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
|
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
|
||||||
(:require [status-im.ui.components.colors :as colors]))
|
(:require [status-im.ui.components.colors :as colors]))
|
||||||
|
|
||||||
(def delete-button-width 100)
|
|
||||||
|
|
||||||
(defn toolbar []
|
(defn toolbar []
|
||||||
{:background-color colors/white})
|
{:background-color colors/white})
|
||||||
|
|
||||||
|
@ -172,20 +170,6 @@
|
||||||
:icon-size 17
|
:icon-size 17
|
||||||
:shadow? false})
|
:shadow? false})
|
||||||
|
|
||||||
(def delete-icon-highlight
|
|
||||||
{:position :absolute
|
|
||||||
:top 0
|
|
||||||
:bottom 0
|
|
||||||
:right -800
|
|
||||||
:width 800
|
|
||||||
:background-color colors/red-light})
|
|
||||||
|
|
||||||
(def delete-icon-container
|
|
||||||
{:flex 1
|
|
||||||
:width delete-button-width
|
|
||||||
:justify-content :center
|
|
||||||
:align-items :center})
|
|
||||||
|
|
||||||
(def action-button-container
|
(def action-button-container
|
||||||
{:position :absolute
|
{:position :absolute
|
||||||
:bottom 16
|
:bottom 16
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
(ns status-im.ui.screens.home.views
|
(ns status-im.ui.screens.home.views
|
||||||
(:require-macros [status-im.utils.views :as views])
|
(:require-macros [status-im.utils.views :as views])
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[status-im.ui.components.colors :as colors]
|
|
||||||
[status-im.ui.components.list.views :as list]
|
[status-im.ui.components.list.views :as list]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.components.toolbar.view :as toolbar]
|
[status-im.ui.components.toolbar.view :as toolbar]
|
||||||
|
@ -9,13 +8,9 @@
|
||||||
[status-im.ui.components.connectivity.view :as connectivity]
|
[status-im.ui.components.connectivity.view :as connectivity]
|
||||||
[status-im.ui.screens.home.views.inner-item :as inner-item]
|
[status-im.ui.screens.home.views.inner-item :as inner-item]
|
||||||
[status-im.ui.screens.home.styles :as styles]
|
[status-im.ui.screens.home.styles :as styles]
|
||||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
|
||||||
[status-im.ui.components.animation :as animation]
|
|
||||||
[status-im.ui.screens.home.animations.responder :as responder]
|
|
||||||
[status-im.utils.platform :as platform]
|
[status-im.utils.platform :as platform]
|
||||||
[status-im.react-native.resources :as resources]
|
[status-im.react-native.resources :as resources]
|
||||||
[status-im.ui.components.common.common :as components.common]
|
[status-im.ui.components.common.common :as components.common]
|
||||||
[status-im.i18n :as i18n]
|
|
||||||
[status-im.ui.components.icons.vector-icons :as icons]))
|
[status-im.ui.components.icons.vector-icons :as icons]))
|
||||||
|
|
||||||
(defn- toolbar [show-welcome?]
|
(defn- toolbar [show-welcome?]
|
||||||
|
@ -37,8 +32,7 @@
|
||||||
[react/view styles/action-button
|
[react/view styles/action-button
|
||||||
[icons/icon :icons/add {:color :white}]]]])
|
[icons/icon :icons/add {:color :white}]]]])
|
||||||
|
|
||||||
(views/defview home-list-item [[home-item-id home-item]]
|
(defn home-list-item [[home-item-id home-item]]
|
||||||
(views/letsubs [swiped? [:delete-swipe-position home-item-id]]
|
|
||||||
(let [delete-action (if (:chat-id home-item)
|
(let [delete-action (if (:chat-id home-item)
|
||||||
(if (and (:group-chat home-item)
|
(if (and (:group-chat home-item)
|
||||||
(not (:public? home-item)))
|
(not (:public? home-item)))
|
||||||
|
@ -47,19 +41,13 @@
|
||||||
:browser.ui/remove-browser-pressed)
|
:browser.ui/remove-browser-pressed)
|
||||||
inner-item-view (if (:chat-id home-item)
|
inner-item-view (if (:chat-id home-item)
|
||||||
inner-item/home-list-chat-item-inner-view
|
inner-item/home-list-chat-item-inner-view
|
||||||
inner-item/home-list-browser-item-inner-view)
|
inner-item/home-list-browser-item-inner-view)]
|
||||||
offset-x (animation/create-value (if swiped? styles/delete-button-width 0))
|
[list/deletable-list-item {:type :chats
|
||||||
swipe-pan-responder (responder/swipe-pan-responder offset-x styles/delete-button-width home-item-id swiped?)
|
:id home-item-id
|
||||||
swipe-pan-handler (responder/pan-handlers swipe-pan-responder)]
|
:on-delete #(do
|
||||||
[react/view (assoc swipe-pan-handler :accessibility-label :chat-item)
|
(re-frame/dispatch [:set-swipe-position :chats home-item-id false])
|
||||||
[react/animated-view {:style {:flex 1 :right offset-x}}
|
|
||||||
[inner-item-view home-item]
|
|
||||||
[react/touchable-highlight {:style styles/delete-icon-highlight
|
|
||||||
:on-press #(do
|
|
||||||
(re-frame/dispatch [:set-swipe-position home-item-id false])
|
|
||||||
(re-frame/dispatch [delete-action home-item-id]))}
|
(re-frame/dispatch [delete-action home-item-id]))}
|
||||||
[react/view {:style styles/delete-icon-container}
|
[inner-item-view home-item]]))
|
||||||
[vector-icons/icon :icons/delete {:color colors/red}]]]]])))
|
|
||||||
|
|
||||||
;;do not remove view-id and will-update or will-unmount handlers, this is how it works
|
;;do not remove view-id and will-update or will-unmount handlers, this is how it works
|
||||||
(views/defview welcome [view-id]
|
(views/defview welcome [view-id]
|
||||||
|
|
|
@ -77,8 +77,8 @@
|
||||||
(> (count (:navigation-stack db)) 1)))
|
(> (count (:navigation-stack db)) 1)))
|
||||||
|
|
||||||
(reg-sub :delete-swipe-position
|
(reg-sub :delete-swipe-position
|
||||||
(fn [db [_ item-id]]
|
(fn [db [_ type item-id]]
|
||||||
(let [item-animation (get-in db [:chat-animations item-id])]
|
(let [item-animation (get-in db [:animations type item-id])]
|
||||||
(if (some? item-animation) (:delete-swiped item-animation) nil))))
|
(if (some? item-animation) (:delete-swiped item-animation) nil))))
|
||||||
|
|
||||||
(reg-sub :dimensions/window
|
(reg-sub :dimensions/window
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.accounts.db :as accounts.db]
|
[status-im.accounts.db :as accounts.db]
|
||||||
[status-im.chat.models :as chat]
|
[status-im.chat.models :as chat]
|
||||||
[status-im.extensions.core :as extensions]
|
[status-im.extensions.registry :as extensions.registry]
|
||||||
[status-im.ui.components.list-selection :as list-selection]
|
[status-im.ui.components.list-selection :as list-selection]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.screens.add-new.new-chat.db :as new-chat.db]
|
[status-im.ui.screens.add-new.new-chat.db :as new-chat.db]
|
||||||
|
@ -72,7 +72,7 @@
|
||||||
|
|
||||||
(fx/defn handle-extension [cofx url]
|
(fx/defn handle-extension [cofx url]
|
||||||
(log/info "universal-links: handling url profile" url)
|
(log/info "universal-links: handling url profile" url)
|
||||||
(extensions/load cofx url))
|
(extensions.registry/load cofx url))
|
||||||
|
|
||||||
(defn handle-not-found [full-url]
|
(defn handle-not-found [full-url]
|
||||||
(log/info "universal-links: no handler for " full-url))
|
(log/info "universal-links: no handler for " full-url))
|
||||||
|
|
|
@ -767,5 +767,7 @@
|
||||||
"share-dapp-text": "Check out this DApp I'm using on Status: {{link}}",
|
"share-dapp-text": "Check out this DApp I'm using on Status: {{link}}",
|
||||||
"network-invalid-url": "Network URL is invalid",
|
"network-invalid-url": "Network URL is invalid",
|
||||||
"network-invalid-status-code": "Invalid status code: {{code}}",
|
"network-invalid-status-code": "Invalid status code: {{code}}",
|
||||||
"extension-is-already-added": "The extension is already added"
|
"extension-is-already-added": "The extension is already added",
|
||||||
|
"extension-uninstalled": "The extension was uninstalled",
|
||||||
|
"extension-hooks-cannot-be-added": "The following hooks from this extension cannot be added: {{hooks}}"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue