diff --git a/src/syng_im/android/core.cljs b/src/syng_im/android/core.cljs index fb82b1b085..cec2fd2772 100644 --- a/src/syng_im/android/core.cljs +++ b/src/syng_im/android/core.cljs @@ -8,8 +8,8 @@ [syng-im.subs] [syng-im.components.react :refer [navigator app-registry]] [syng-im.contacts.screen :refer [contact-list]] - [syng-im.components.discovery.discovery :refer [discovery]] - [syng-im.components.discovery.discovery-tag :refer [discovery-tag]] + [syng-im.discovery.screen :refer [discovery]] + [syng-im.discovery.discovery-tag :refer [discovery-tag]] [syng-im.chat.screen :refer [chat]] [syng-im.chats-list.screen :refer [chats-list]] [syng-im.new-group.screen :refer [new-group]] diff --git a/src/syng_im/chat/handlers.cljs b/src/syng_im/chat/handlers.cljs index 42d9294301..e5fd8213e0 100644 --- a/src/syng_im/chat/handlers.cljs +++ b/src/syng_im/chat/handlers.cljs @@ -2,7 +2,7 @@ (:require [re-frame.core :refer [register-handler enrich after debug]] [syng-im.models.commands :as commands] [clojure.string :as str] - [syng-im.handlers.suggestions :as suggestions] + [syng-im.chat.suggestions :as suggestions] [syng-im.protocol.api :as api] [syng-im.models.messages :as messages] [syng-im.constants :refer [text-content-type @@ -221,6 +221,7 @@ (register-handler :sign-up (-> (fn [db [_ phone-number]] + ;; todo save phone number to db (assoc db :user-phone-number phone-number)) ((after (fn [& _] (sign-up-service/on-sign-up-response)))))) diff --git a/src/syng_im/chat/subs.cljs b/src/syng_im/chat/subs.cljs index 35f7386b93..9b5692c094 100644 --- a/src/syng_im/chat/subs.cljs +++ b/src/syng_im/chat/subs.cljs @@ -3,7 +3,7 @@ (:require [re-frame.core :refer [register-sub]] [syng-im.db :as db] ;todo handlers in subs?... - [syng-im.handlers.suggestions :refer [get-suggestions]] + [syng-im.chat.suggestions :refer [get-suggestions]] [syng-im.models.commands :as commands])) (register-sub :chat-properties diff --git a/src/syng_im/handlers/suggestions.cljs b/src/syng_im/chat/suggestions.cljs similarity index 96% rename from src/syng_im/handlers/suggestions.cljs rename to src/syng_im/chat/suggestions.cljs index bf9fc11e65..86718068d7 100644 --- a/src/syng_im/handlers/suggestions.cljs +++ b/src/syng_im/chat/suggestions.cljs @@ -1,4 +1,4 @@ -(ns syng-im.handlers.suggestions +(ns syng-im.chat.suggestions (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] [syng-im.db :as db] [syng-im.models.commands :refer [commands @@ -8,7 +8,6 @@ get-chat-command-to-msg-id clear-staged-commands]] [syng-im.utils.utils :refer [log on-error http-get]] - [syng-im.utils.logging :as log] [clojure.string :as s])) (defn suggestion? [text] diff --git a/src/syng_im/components/carousel/carousel.cljs b/src/syng_im/components/carousel/carousel.cljs index b489482f5d..28831eb3ec 100644 --- a/src/syng_im/components/carousel/carousel.cljs +++ b/src/syng_im/components/carousel/carousel.cljs @@ -1,4 +1,4 @@ -(ns syng-im.components.carousel +(ns syng-im.components.carousel.carousel (:require [syng-im.components.react :refer [android? view scroll-view diff --git a/src/syng_im/components/discovery/discovery.cljs b/src/syng_im/components/discovery/discovery.cljs deleted file mode 100644 index 2738781de8..0000000000 --- a/src/syng_im/components/discovery/discovery.cljs +++ /dev/null @@ -1,79 +0,0 @@ -(ns syng-im.components.discovery.discovery - - (:require - [syng-im.utils.logging :as log] - [re-frame.core :refer [dispatch]] - [syng-im.models.discoveries :refer [save-discoveries]] - [syng-im.components.react :refer [android? - view - scroll-view - text - text-input]] - [reagent.core :as r] - [syng-im.components.toolbar :refer [toolbar]] - [syng-im.components.discovery.discovery-popular :refer [discovery-popular]] - [syng-im.components.discovery.discovery-recent :refer [discovery-recent]] - [syng-im.components.discovery.styles :as st] - [syng-im.persistence.realm :as realm])) - -(def search-input (atom {:search "x"})) - -(defn get-hashtags [status] - (let [hashtags (map #(subs % 1) (re-seq #"#[^ !?,;:.]+" status))] - (if hashtags - hashtags - []))) - -(defn title-content [showSearch] - (if showSearch - [text-input {:underlineColorAndroid "transparent" - :style st/discovery-search-input - :autoFocus true - :placeholder "Type your search tags here" - :onSubmitEditing (fn [e] - (let [search (aget e "nativeEvent" "text") - hashtags (get-hashtags search)] - (dispatch [:broadcast-status search hashtags])))}] - [view - [text {:style st/discovery-title} "Discover"]])) - -(defn create-fake-discovery [] - (let [number (rand-int 999)] - (do - (save-discoveries [{:name (str "Name " number) - :status (str "Status This is some longer status to get the second line " number) - :whisper-id (str number) - :photo "" - :location "" - :tags ["tag1" "tag2" "tag3"] - :last-updated (new js/Date)}]) - (dispatch [:updated-discoveries])))) - -(defn discovery [{:keys [navigator]}] - [] - (let [showSearch (r/atom false)] - (fn [] - [view {:style {:flex 1 - :backgroundColor "#eef2f5"}} - [toolbar {:style st/discovery-toolbar - :navigator navigator - :nav-action {:image {:source {:uri "icon_hamburger"} - :style {:width 16 - :height 12}} - :handler create-fake-discovery} - :title "Add Participants" - :content (title-content @showSearch) - :action {:image {:source {:uri "icon_search"} - :style {:width 17 - :height 17}} - :handler (fn [] - (if @showSearch - (reset! showSearch false) - (reset! showSearch true)))}}] - [scroll-view {:style {}} - [view {:style st/section-spacing} - [text {:style st/discovery-subtitle} "Popular tags"]] - [discovery-popular navigator] - [view {:style st/section-spacing} - [text {:style st/discovery-subtitle} "Recent"]] - [discovery-recent]]]))) diff --git a/src/syng_im/components/discovery/discovery_popular.cljs b/src/syng_im/components/discovery/discovery_popular.cljs deleted file mode 100644 index df33467899..0000000000 --- a/src/syng_im/components/discovery/discovery_popular.cljs +++ /dev/null @@ -1,23 +0,0 @@ -(ns syng-im.components.discovery.discovery-popular - (:require - [re-frame.core :refer [subscribe]] - [syng-im.utils.logging :as log] - [syng-im.components.react :refer [android? - text]] - [syng-im.components.carousel :refer [carousel]] - [syng-im.components.discovery.styles :as st] - [syng-im.components.discovery.discovery-popular-list :refer [discovery-popular-list]] - )) - -(defn page-width [] - (.-width (.get (.. js/React -Dimensions) "window"))) - -(defn discovery-popular [navigator] - (let [popular-tags (subscribe [:get-popular-tags 3])] - (log/debug "Got popular tags: " @popular-tags) - (if (> (count @popular-tags) 0) - [carousel {:pageStyle st/carousel-page-style - :sneak 20} - (for [tag @popular-tags] - (discovery-popular-list (.-name tag) (.-count tag) navigator))] - [text "None"]))) \ No newline at end of file diff --git a/src/syng_im/components/discovery/discovery_popular_list.cljs b/src/syng_im/components/discovery/discovery_popular_list.cljs deleted file mode 100644 index 55a4b94c83..0000000000 --- a/src/syng_im/components/discovery/discovery_popular_list.cljs +++ /dev/null @@ -1,43 +0,0 @@ -(ns syng-im.components.discovery.discovery-popular-list - (:require - [re-frame.core :refer [subscribe dispatch dispatch-sync]] - [syng-im.utils.logging :as log] - [syng-im.components.react :refer [android? - view - list-view - touchable-highlight - text - image]] - [reagent.core :as r] - [syng-im.components.discovery.styles :as st] - [syng-im.utils.listview :refer [to-realm-datasource]] - [syng-im.components.discovery.discovery-popular-list-item :refer [discovery-popular-list-item] ]) - ) - - -(defn render-row [row section-id row-id] - (let [elem (discovery-popular-list-item row)] - elem) -) - -(defn render-separator [sectionID, rowID, adjacentRowHighlighted] - (let [elem (r/as-element [view {:style st/row-separator - :key rowID}])] - elem)) - -(defn discovery-popular-list [tag count navigator] - (let [discoveries (subscribe [:get-discoveries-by-tag tag 3])] - [view {:style st/popular-list-container} - [view st/row - [view st/tag-name-container - [touchable-highlight {:onPress #(dispatch [:show-discovery-tag tag navigator :push])} - [text {:style st/tag-name} - (str " #" (name tag))]]] - [view {:style st/tag-count-container} - [text {:style st/tag-count} - count]]] - [list-view {:dataSource (to-realm-datasource @discoveries) - :enableEmptySections true - :renderRow render-row - :renderSeparator render-separator - :style st/popular-list}]])) diff --git a/src/syng_im/components/discovery/discovery_popular_list_item.cljs b/src/syng_im/components/discovery/discovery_popular_list_item.cljs deleted file mode 100644 index 2313d4ff76..0000000000 --- a/src/syng_im/components/discovery/discovery_popular_list_item.cljs +++ /dev/null @@ -1,23 +0,0 @@ -(ns syng-im.components.discovery.discovery-popular-list-item - (:require - [syng-im.utils.logging :as log] - [syng-im.components.react :refer [android? - view - text - image]] - [syng-im.components.discovery.styles :as st] - [reagent.core :as r]) - ) - -(defn discovery-popular-list-item [discovery] - (r/as-element [view {:style st/popular-list-item} - [view {:style st/popular-list-item-name-container} - [text {:style st/popular-list-item-name} (aget discovery "name")] - [text {:style st/popular-list-item-status - :numberOfLines 2} (aget discovery "status")] - ] - [view {:style st/popular-list-item-avatar-container} - [image {:style st/popular-list-item-avatar - :source {:uri "icon_avatar"}}] - ] - ])) \ No newline at end of file diff --git a/src/syng_im/components/discovery/discovery_recent.cljs b/src/syng_im/components/discovery/discovery_recent.cljs deleted file mode 100644 index c253ca02b4..0000000000 --- a/src/syng_im/components/discovery/discovery_recent.cljs +++ /dev/null @@ -1,33 +0,0 @@ -(ns syng-im.components.discovery.discovery-recent - (:require-macros - [natal-shell.data-source :refer [data-source clone-with-rows]] - - ) - (:require - [re-frame.core :refer [subscribe]] - [syng-im.components.react :refer [android? - view]] - [syng-im.components.realm :refer [list-view]] - [syng-im.utils.listview :refer [to-realm-datasource]] - [syng-im.components.discovery.styles :as st] - [syng-im.components.discovery.discovery-popular-list-item :refer [discovery-popular-list-item]] - [reagent.core :as r])) - - -(defn render-row [row section-id row-id] - (let [elem (discovery-popular-list-item row)] - elem) - ) - -(defn render-separator [sectionID, rowID, adjacentRowHighlighted] - (let [elem (r/as-element [view {:style st/row-separator - :key rowID}])] - elem)) - -(defn discovery-recent [] - (let [discoveries (subscribe [:get-discoveries]) - datasource (to-realm-datasource @discoveries)] - [list-view {:dataSource datasource - :renderRow render-row - :renderSeparator render-separator - :style st/recent-list}])) diff --git a/src/syng_im/components/discovery/handlers.cljs b/src/syng_im/components/discovery/handlers.cljs deleted file mode 100644 index 44d24c99d9..0000000000 --- a/src/syng_im/components/discovery/handlers.cljs +++ /dev/null @@ -1,44 +0,0 @@ -(ns syng-im.components.discovery.handlers - (:require [re-frame.core :refer [register-handler after dispatch]] - [syng-im.utils.logging :as log] - [syng-im.protocol.api :as api] - [syng-im.navigation :refer [nav-push - nav-replace - nav-pop]] - [syng-im.models.discoveries :refer [save-discoveries - set-current-tag - signal-discoveries-updated]])) - - -;; -- Discovery -------------------------------------------------------------- - -(register-handler :discovery-response-received - (fn [db [_ from payload]] - (let [{:keys [name status hashtags location]} payload - location (if location location "")] - (save-discoveries [{:name name - :status status - :whisper-id from - :photo "" - :location location - :tags hashtags - :last-updated (js/Date.)}]) - (signal-discoveries-updated db)))) - -(register-handler :updated-discoveries - (fn [db _] - (signal-discoveries-updated db))) - -(register-handler :broadcast-status - (fn [db [action status hashtags]] - (let [name (:name db)] - (log/debug "Status: " status ", Hashtags: " hashtags) - (api/broadcast-discover-status name status hashtags) - db))) - -(register-handler :show-discovery-tag - (fn [db [action tag navigator nav-type]] - (log/debug action "setting current tag: " tag) - (let [db (set-current-tag db tag)] - (dispatch [:navigate-to navigator {:view-id :discovery-tag} nav-type]) - db))) \ No newline at end of file diff --git a/src/syng_im/components/discovery/subs.cljs b/src/syng_im/components/discovery/subs.cljs deleted file mode 100644 index c335d4366d..0000000000 --- a/src/syng_im/components/discovery/subs.cljs +++ /dev/null @@ -1,48 +0,0 @@ -(ns syng-im.components.discovery.subs - (:require-macros [reagent.ratom :refer [reaction]]) - (:require [re-frame.core :refer [register-sub]] - [syng-im.db :as db] - [syng-im.utils.logging :as log] - [syng-im.models.discoveries :refer [discovery-list - current-tag - get-tag-popular - discoveries-by-tag - current-tag-updated? - discoveries-updated?]])) - - - -(register-sub :get-discoveries - (fn [db _] - (let [discoveries-updated (-> (discoveries-updated? @db) - (reaction))] - (reaction - (let [_ @discoveries-updated] - (discovery-list)))))) - -(register-sub :get-discoveries-by-tag - (fn [db [_ tag limit]] - (let [discoveries-updated (-> (discoveries-updated? @db) - (reaction))] - (log/debug "Getting discoveries for: " tag) - (reaction - (let [_ @discoveries-updated] - (discoveries-by-tag tag limit)))))) - -(register-sub :get-popular-tags - (fn [db [_ limit]] - (let [discoveries-updated (-> (discoveries-updated? @db) - (reaction))] - (log/debug "Getting tags limited: " limit) - (reaction - (let [_ @discoveries-updated] - (get-tag-popular limit)))))) - -(register-sub :get-current-tag - (fn [db _] - (let [current-tag-updated (-> (current-tag-updated? @db) - (reaction))] - (reaction - (let [_ @current-tag-updated] - (current-tag @db)))))) - diff --git a/src/syng_im/components/toolbar.cljs b/src/syng_im/components/toolbar.cljs index edc824c83b..d13ac69050 100644 --- a/src/syng_im/components/toolbar.cljs +++ b/src/syng_im/components/toolbar.cljs @@ -2,6 +2,7 @@ (:require [re-frame.core :refer [subscribe dispatch]] [syng-im.components.react :refer [view text-input + icon text image touchable-highlight]] @@ -30,23 +31,22 @@ [touchable-highlight {:on-press #(dispatch [:navigate-back])} [view {:width 56 :height 56} - [image {:source {:uri "icon_back"} - :style {:marginTop 21 - :marginLeft 23 - :width 8 - :height 14}}]]]) + [icon :back {:marginTop 21 + :marginLeft 23 + :width 8 + :height 14}]]]) (if content - [view {:style {:flex 1 - :alignItems :center - :justifyContent :center}} + [view {:flex 1 + :alignItems :center + :justifyContent :center} content] - [view {:style {:flex 1 - :alignItems :center - :justifyContent :center}} - [text {:style {:marginTop -2.5 - :color text1-color - :fontSize 16 - :fontFamily font}} + [view {:flex 1 + :alignItems :center + :justifyContent :center} + [text {:marginTop -2.5 + :color text1-color + :fontSize 16 + :fontFamily font} title]]) [touchable-highlight {:on-press (:handler action)} [view {:width 56 diff --git a/src/syng_im/contacts/handlers.cljs b/src/syng_im/contacts/handlers.cljs index c434a95ea1..9cb4903d9b 100644 --- a/src/syng_im/contacts/handlers.cljs +++ b/src/syng_im/contacts/handlers.cljs @@ -4,16 +4,12 @@ [syng-im.utils.crypt :refer [encrypt]] [clojure.string :as s] [syng-im.utils.utils :refer [http-post]] - [syng-im.utils.phone-number :refer [format-phone-number]])) - -(defn side-effect! [handler] - (fn [db params] - (handler db params) - db)) + [syng-im.utils.phone-number :refer [format-phone-number]] + [syng-im.utils.handlers :as u])) (defn save-contact [_ [_ contact]] - (contacts/save-syng-contacts [contact])) + (contacts/save-contacts [contact])) (register-handler :add-contact (-> (fn [db [_ contact]] @@ -26,6 +22,7 @@ (register-handler :load-syng-contacts load-contacts!) +;; TODO see https://github.com/rt2zz/react-native-contacts/issues/45 (def react-native-contacts (js/require "react-native-contacts")) (defn contact-name [contact] @@ -51,7 +48,7 @@ (dispatch [:get-contacts-identities contacts'])))))) (register-handler :sync-contacts - (side-effect! fetch-contacts-from-phone!)) + (u/side-effect! fetch-contacts-from-phone!)) (defn get-contacts-by-hash [contacts] (->> contacts @@ -83,10 +80,10 @@ (request-stored-contacts contacts)) (register-handler :get-contacts-identities - (side-effect! get-identities-by-contacts!)) + (u/side-effect! get-identities-by-contacts!)) (defn save-contacts! [{:keys [new-contacts]} _] - (contacts/save-syng-contacts new-contacts)) + (contacts/save-contacts new-contacts)) (defn add-new-contacts [{:keys [contacts] :as db} [_ new-contacts]] diff --git a/src/syng_im/discovery/discovery_popular_list.cljs b/src/syng_im/discovery/discovery_popular_list.cljs new file mode 100644 index 0000000000..9eebed2463 --- /dev/null +++ b/src/syng_im/discovery/discovery_popular_list.cljs @@ -0,0 +1,40 @@ +(ns syng-im.discovery.discovery-popular-list + (:require + [re-frame.core :refer [subscribe dispatch dispatch-sync]] + [syng-im.utils.logging :as log] + [syng-im.components.react :refer [android? + view + list-view + list-item + touchable-highlight + text + image]] + [reagent.core :as r] + [syng-im.discovery.styles :as st] + [syng-im.utils.listview :refer [to-realm-datasource to-datasource2]] + [syng-im.discovery.discovery-popular-list-item :refer [discovery-popular-list-item] ]) + ) + + +(defn render-row [row _ _] + (list-item [discovery-popular-list-item row])) + +(defn render-separator [sectionID rowID adjacentRowHighlighted] + (list-item [view {:style st/row-separator + :key rowID}])) + +(defn discovery-popular-list [tag count] + (let [discoveries (subscribe [:get-discoveries-by-tag tag 3])] + (fn [tag count] + [view st/popular-list-container + [view st/row + [view st/tag-name-container + [touchable-highlight {:onPress #(dispatch [:show-discovery-tag tag])} + [text {:style st/tag-name} (str " #" (name tag))]]] + [view st/tag-count-container + [text {:style st/tag-count} count]]] + [list-view {:dataSource (to-datasource2 @discoveries) + :enableEmptySections true + :renderRow render-row + :renderSeparator render-separator + :style st/popular-list}]]))) diff --git a/src/syng_im/discovery/discovery_popular_list_item.cljs b/src/syng_im/discovery/discovery_popular_list_item.cljs new file mode 100644 index 0000000000..65df82164a --- /dev/null +++ b/src/syng_im/discovery/discovery_popular_list_item.cljs @@ -0,0 +1,15 @@ +(ns syng-im.discovery.discovery-popular-list-item + (:require [syng-im.components.react :refer [view text image]] + [syng-im.discovery.styles :as st] + [reagent.core :as r])) + +(defn discovery-popular-list-item + [{:keys [name status]}] + [view st/popular-list-item + [view st/popular-list-item-name-container + [text {:style st/popular-list-item-name} name] + [text {:style st/popular-list-item-status + :numberOfLines 2} status]] + [view st/popular-list-item-avatar-container + [image {:style st/popular-list-item-avatar + :source {:uri :icon_avatar}}]]]) diff --git a/src/syng_im/discovery/discovery_recent.cljs b/src/syng_im/discovery/discovery_recent.cljs new file mode 100644 index 0000000000..d9128b2fef --- /dev/null +++ b/src/syng_im/discovery/discovery_recent.cljs @@ -0,0 +1,23 @@ +(ns syng-im.discovery.discovery-recent + (:require + [re-frame.core :refer [subscribe]] + [syng-im.components.react :refer [view list-view list-item]] + [syng-im.utils.listview :refer [to-realm-datasource to-datasource2]] + [syng-im.discovery.styles :as st] + [syng-im.discovery.discovery-popular-list-item + :refer [discovery-popular-list-item]])) + +(defn render-row [row _ _] + (list-item [discovery-popular-list-item row])) + +(defn render-separator [_ row-id _] + (list-item [view {:style st/row-separator + :key row-id}])) + +(defn discovery-recent [] + (let [discoveries (subscribe [:get :discoveries])] + (fn [] + [list-view {:dataSource (to-datasource2 @discoveries) + :renderRow render-row + :renderSeparator render-separator + :style st/recent-list}]))) diff --git a/src/syng_im/components/discovery/discovery_tag.cljs b/src/syng_im/discovery/discovery_tag.cljs similarity index 91% rename from src/syng_im/components/discovery/discovery_tag.cljs rename to src/syng_im/discovery/discovery_tag.cljs index 70cffe6d23..5123eab794 100644 --- a/src/syng_im/components/discovery/discovery_tag.cljs +++ b/src/syng_im/discovery/discovery_tag.cljs @@ -1,4 +1,4 @@ -(ns syng-im.components.discovery.discovery-tag +(ns syng-im.discovery.discovery-tag (:require [re-frame.core :refer [subscribe]] [syng-im.utils.logging :as log] @@ -11,8 +11,8 @@ [syng-im.components.realm :refer [list-view]] [syng-im.components.toolbar :refer [toolbar]] [reagent.core :as r] - [syng-im.components.discovery.discovery-popular-list-item :refer [discovery-popular-list-item]] - [syng-im.components.discovery.styles :as st])) + [syng-im.discovery.discovery-popular-list-item :refer [discovery-popular-list-item]] + [syng-im.discovery.styles :as st])) (defn render-row [row section-id row-id] (log/debug "discovery-tag-row: " row section-id row-id) diff --git a/src/syng_im/discovery/handlers.cljs b/src/syng_im/discovery/handlers.cljs new file mode 100644 index 0000000000..c1cdf901c4 --- /dev/null +++ b/src/syng_im/discovery/handlers.cljs @@ -0,0 +1,76 @@ +(ns syng-im.discovery.handlers + (:require [re-frame.core :refer [register-handler after dispatch enrich + log-ex debug]] + [syng-im.protocol.api :as api] + [syng-im.models.discoveries :refer [save-discoveries + set-current-tag]] + [syng-im.navigation.handlers :as nav] + [syng-im.models.discoveries :as discoveries] + [syng-im.utils.handlers :as u])) + +(defmethod nav/preload-data! :discovery + [{:keys [] :as db} _] + (-> db + (assoc :tags (discoveries/all-tags)) + (assoc :discoveries (discoveries/discovery-list)))) + +(register-handler :discovery-response-received + (u/side-effect! + (fn [_ [_ from payload]] + (let [{:keys [name status hashtags location]} payload + location (or location "") + discovery [{:name name + :status status + :whisper-id from + :photo "" + :location location + :tags (map #(hash-map :name %) hashtags) + :last-updated (js/Date.)}]] + (dispatch [:add-discovery discovery]))))) + +(register-handler :broadcast-status + (fn [{:keys [name] :as db} [_ status hashtags]] + (api/broadcast-discover-status name status hashtags) + db)) + +(register-handler :show-discovery-tag + (fn [db [_ tag]] + (let [db (set-current-tag db tag)] + (dispatch [:navigate-to :discovery-tag]) + db))) + +;; todo remove this +(register-handler :create-fake-discovery! + (u/side-effect! + (fn [_ _] + (let [number (rand-int 999) + discovery {:name (str "Name " number) + :status (str "Status This is some longer status to get the second line " number) + :whisper-id (str number) + :photo "" + :location "" + :tags [{:name "tag1"} + {:name "tag2"} + {:name "tag3"}] + :last-updated (new js/Date)}] + (dispatch [:add-discovery discovery]))))) + +(defn add-discovery + [db [_ discovery]] + (-> db + (assoc :new-discovery discovery) + (update :discoveries conj discovery))) + +(defn save-discovery! + [{:keys [new-discovery]} _] + (discoveries/save-discoveries [new-discovery])) + +(defn reload-tags! + [db _] + (assoc db :tags (discoveries/all-tags))) + +(register-handler :add-discovery + (-> add-discovery + debug + ((after save-discovery!)) + ((enrich reload-tags!)))) diff --git a/src/syng_im/discovery/screen.cljs b/src/syng_im/discovery/screen.cljs new file mode 100644 index 0000000000..eb1838fcd7 --- /dev/null +++ b/src/syng_im/discovery/screen.cljs @@ -0,0 +1,62 @@ +(ns syng-im.discovery.screen + + (:require + [syng-im.utils.logging :as log] + [re-frame.core :refer [dispatch subscribe]] + [syng-im.models.discoveries :refer [save-discoveries]] + [syng-im.components.react :refer [android? + view + scroll-view + text + text-input]] + [reagent.core :as r] + [syng-im.components.toolbar :refer [toolbar]] + [syng-im.discovery.views.popular :refer [popular]] + [syng-im.discovery.discovery-recent :refer [discovery-recent]] + [syng-im.discovery.styles :as st] + [syng-im.persistence.realm :as realm])) + +(defn get-hashtags [status] + (let [hashtags (map #(subs % 1) (re-seq #"#[^ !?,;:.]+" status))] + (or hashtags []))) + +(defn title-content [showSearch] + (if showSearch + [text-input {:style st/discovery-search-input + :autoFocus true + :placeholder "Type your search tags here" + :onSubmitEditing (fn [e] + (let [search (aget e "nativeEvent" "text") + hashtags (get-hashtags search)] + (dispatch [:broadcast-status search hashtags])))}] + [view + [text {:style st/discovery-title} "Discover"]])) + +(defn toogle-search [current-value] + (dispatch [:set ::show-search (not current-value)])) + +(defn discovery [] + [] + (let [show-search (subscribe [:get ::show-search])] + (fn [] + [view {:flex 1 + :backgroundColor :#eef2f5} + [toolbar + {:style st/discovery-toolbar + :nav-action {:image {:source {:uri :icon_hamburger} + :style {:width 16 + :height 12}} + :handler #(dispatch [:create-fake-discovery!])} + :title "Add Participants" + :content (title-content @show-search) + :action {:image {:source {:uri :icon_search} + :style {:width 17 + :height 17}} + :handler #(toogle-search @show-search)}}] + [scroll-view {:style {}} + [view st/section-spacing + [text {:style st/discovery-subtitle} "Popular tags"]] + [popular] + [view st/section-spacing + [text {:style st/discovery-subtitle} "Recent"]] + [discovery-recent]]]))) diff --git a/src/syng_im/components/discovery/styles.cljs b/src/syng_im/discovery/styles.cljs similarity index 98% rename from src/syng_im/components/discovery/styles.cljs rename to src/syng_im/discovery/styles.cljs index 957a1f7940..b4518d057d 100644 --- a/src/syng_im/components/discovery/styles.cljs +++ b/src/syng_im/discovery/styles.cljs @@ -1,4 +1,4 @@ -(ns syng-im.components.discovery.styles +(ns syng-im.discovery.styles (:require [syng-im.components.styles :refer [font title-font color-white diff --git a/src/syng_im/discovery/subs.cljs b/src/syng_im/discovery/subs.cljs new file mode 100644 index 0000000000..09c98628a6 --- /dev/null +++ b/src/syng_im/discovery/subs.cljs @@ -0,0 +1,26 @@ +(ns syng-im.discovery.subs + (:require-macros [reagent.ratom :refer [reaction]]) + (:require [re-frame.core :refer [register-sub]] + [syng-im.models.discoveries :refer [current-tag + current-tag-updated?]])) + +(register-sub :get-discoveries-by-tag + (fn [db [_ tag limit]] + (let [discoveries (reaction (:discoveries @db))] + (->> @discoveries + (into [] (comp (filter #(some #{tag} (map :name (:tags %)))) + (take limit))) + (reaction))))) + +(register-sub :get-popular-tags + (fn [db [_ limit]] + (reaction (take limit (:tags @db))))) + +(register-sub :get-current-tag + (fn [db _] + (let [current-tag-updated (-> (current-tag-updated? @db) + (reaction))] + (reaction + (let [_ @current-tag-updated] + (current-tag @db)))))) + diff --git a/src/syng_im/discovery/views/popular.cljs b/src/syng_im/discovery/views/popular.cljs new file mode 100644 index 0000000000..91bd8f8b7a --- /dev/null +++ b/src/syng_im/discovery/views/popular.cljs @@ -0,0 +1,22 @@ +(ns syng-im.discovery.views.popular + (:require + [re-frame.core :refer [subscribe]] + [syng-im.utils.logging :as log] + [syng-im.components.react :refer [android? + text]] + [syng-im.components.carousel.carousel :refer [carousel]] + [syng-im.discovery.styles :as st] + [syng-im.discovery.discovery-popular-list :refer [discovery-popular-list]])) + +(defn page-width [] + (.-width (.get (.. js/React -Dimensions) "window"))) + +(defn popular [] + (let [popular-tags (subscribe [:get-popular-tags 3])] + (log/debug "Got popular tags: " @popular-tags) + (if (pos? (count @popular-tags)) + [carousel {:pageStyle st/carousel-page-style + :sneak 20} + (for [{:keys [name count]} @popular-tags] + [discovery-popular-list name count])] + [text "None"]))) diff --git a/src/syng_im/handlers.cljs b/src/syng_im/handlers.cljs index 342ec071df..021b072111 100644 --- a/src/syng_im/handlers.cljs +++ b/src/syng_im/handlers.cljs @@ -7,14 +7,13 @@ [syng-im.protocol.protocol-handler :refer [make-handler]] [syng-im.models.protocol :refer [update-identity set-initialized]] - [syng-im.models.user-data :as user-data] [syng-im.models.contacts :as contacts] [syng-im.models.messages :refer [save-message update-message! message-by-id]] [syng-im.models.commands :refer [set-commands]] [syng-im.handlers.server :as server] - [syng-im.handlers.suggestions :refer [get-command + [syng-im.chat.suggestions :refer [get-command handle-command get-command-handler load-commands @@ -37,8 +36,8 @@ [syng-im.utils.crypt :refer [gen-random-bytes]] [syng-im.utils.random :as random] syng-im.chat.handlers - syng-im.navigation.handlers - syng-im.components.discovery.handlers + [syng-im.navigation.handlers :as nav] + syng-im.discovery.handlers syng-im.contacts.handlers)) ;; -- Middleware ------------------------------------------------------------ @@ -62,7 +61,12 @@ (fn [db [_ k v]] (assoc db k v)))) +(defn preload-data! + [{:keys [view-id] :as db} _] + (nav/preload-data! db [nil view-id])) + (register-handler :initialize-db + (enrich preload-data!) (fn [_ _] app-db)) (register-handler :set-loading @@ -218,15 +222,10 @@ (left-chat-msg chat-id)))) ;; -- User data -------------------------------------------------------------- - -(register-handler :set-user-phone-number - (fn [db [_ value]] - (assoc db :user-phone-number value))) - (register-handler :load-user-phone-number (fn [db [_]] - (user-data/load-phone-number) - db)) + ;; todo fetch phone number from db + (assoc db :user-phone-number "123"))) ;; -- Chats -------------------------------------------------------------- (defn update-new-participants-selection [db identity add?] diff --git a/src/syng_im/handlers/server.cljs b/src/syng_im/handlers/server.cljs index 76707a8a33..70c0a45fe7 100644 --- a/src/syng_im/handlers/server.cljs +++ b/src/syng_im/handlers/server.cljs @@ -1,12 +1,11 @@ (ns syng-im.handlers.server (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] - [syng-im.models.user-data :as user-data] [syng-im.utils.utils :refer [log on-error http-post]] [syng-im.utils.logging :as log])) (defn sign-up [db phone-number handler] - (user-data/save-phone-number phone-number) + ;(user-data/save-phone-number phone-number) (http-post "sign-up" {:phone-number phone-number :whisper-identity (get-in db [:user-identity :public])} (fn [body] diff --git a/src/syng_im/models/chats.cljs b/src/syng_im/models/chats.cljs index f92f3f67e5..9bfca22293 100644 --- a/src/syng_im/models/chats.cljs +++ b/src/syng_im/models/chats.cljs @@ -8,7 +8,6 @@ [syng-im.models.messages :refer [save-message]] [syng-im.persistence.realm-queries :refer [include-query]])) - (defn chat-name-from-contacts [identities] (let [chat-name (->> identities (map (fn [identity] diff --git a/src/syng_im/models/contacts.cljs b/src/syng_im/models/contacts.cljs index ecec1e6992..6369cb9262 100644 --- a/src/syng_im/models/contacts.cljs +++ b/src/syng_im/models/contacts.cljs @@ -1,71 +1,21 @@ (ns syng-im.models.contacts - (:require [cljs.core.async :as async :refer [chan put! !]] - [re-frame.core :refer [subscribe dispatch dispatch-sync]] - [syng-im.utils.utils :refer [log toast]] - [syng-im.persistence.realm :as realm] - [syng-im.persistence.realm :as r] + (:require [syng-im.persistence.realm :as r] [syng-im.persistence.realm-queries :refer [include-query exclude-query]])) -;; TODO see https://github.com/rt2zz/react-native-contacts/issues/45 - -(def react-native-contacts (js/require "react-native-contacts")) - -(defn- generate-contact [n] - {:name (str "Contact " n) - :photo-path "" - :phone-numbers [{:label "mobile" :number (apply str (repeat 7 n))}] - :delivery-status (if (< (rand) 0.5) :delivered :seen) - :datetime "15:30" - :new-messages-count (rand-int 3) - :online (< (rand) 0.5)}) - -(defn- generate-contacts [n] - (map generate-contact (range 1 (inc n)))) - -(defn load-phone-contacts - ([callback] (.getAll react-native-contacts callback)) - ([] - (.getAll react-native-contacts - (fn [error raw-contacts] - (println raw-contacts) - {:error error - :contacts - (when (not error) - (log raw-contacts) - (map (fn [contact] - (merge contact - (generate-contact 1) - {:name (:givenName contact) - :photo-path (:thumbnailPath contact) - :phone-numbers (:phoneNumbers contact)})) - (js->clj raw-contacts :keywordize-keys true)))})))) - (defn get-contacts [] - (realm/collection->map (realm/get-all :contacts))) + (-> (r/get-all :contacts) + (r/sorted :name :asc) + r/collection->map)) -(defn- create-contact [{:keys [phone-number whisper-identity name photo-path]}] - (realm/create :contacts - {:phone-number phone-number - :whisper-identity whisper-identity - :name (or name "") - :photo-path (or photo-path "")})) +(defn create-contact [{:keys [name photo-path] :as contact}] + (->> {:name (or name "") + :photo-path (or photo-path "")} + (merge contact) + (r/create :contacts))) -(defn- contact-exist? [contacts contact] - (some #(= (:phone-number contact) (:phone-number %)) contacts)) - -(defn- add-contacts [contacts] - (realm/write (fn [] - (let [db-contacts (get-contacts)] - (dorun (map (fn [contact] - (if (not (contact-exist? db-contacts contact)) - (create-contact contact) - ;; TODO else override? - )) - contacts)))))) - -(defn save-syng-contacts [syng-contacts] - (add-contacts syng-contacts)) +(defn save-contacts [contacts] + (r/write #(mapv create-contact contacts))) ;;;;;;;;;;;;;;;;;;;;---------------------------------------------- @@ -87,31 +37,3 @@ (defn contact-by-identity [identity] (r/single-cljs (r/get-by-field :contacts :whisper-identity identity))) - -(comment - - (r/write #(create-contact {:phone-number "0543072333" - :whisper-identity "0x04e43e861a6dd99ad9eee7bd58af89dcaa430188ebec8698de7b7bad54573324fff4ac5cb9bb277af317efd7abfc917b91bf48cc41e40bf70062fd79400016a1f9" - :name "Splinter" - :photo-path ""})) - - (r/write #(create-contact {:phone-number "0544828649" - :whisper-identity "0x0487954e7fa746d8cf787403c2c491aadad540b9bb1f0f7b8184792e91c33b6a394079295f5777ec6d4af9ad5ba24794b3ff1ec8be9ff6a708c85a163733192665" - :name "Exodius" - :photo-path ""})) - - (r/write #(create-contact {:phone-number "0522222222" - :whisper-identity "0x0407c278af94e0b4599645023f5bec03cbdb3973bd0ae33b94c6a5885d9d20e82ff3f3c3584a637ba016af40bac2f711fd6028045756f561e36e4b07d0c2b4e623" - :name "Mr. Eagle" - :photo-path ""})) - - (r/write #(create-contact {:phone-number "0533333333" - :whisper-identity "0x04512f852558ea09d09419019f3f443ec03ff2c1913c48e567723d70e5abf239ed87fb62486b90b85e12de5d327501c1993c9905a69f2ca7e1bfbaab12dd033313" - :name "Mr. PiggyBear" - :photo-path ""})) - - (contacts-list) - - (:new-group @re-frame.db/app-db) - - ) diff --git a/src/syng_im/models/discoveries.cljs b/src/syng_im/models/discoveries.cljs index 03f7a623ad..2261d8e63c 100644 --- a/src/syng_im/models/discoveries.cljs +++ b/src/syng_im/models/discoveries.cljs @@ -1,22 +1,13 @@ (ns syng-im.models.discoveries - (:require [cljs.core.async :as async :refer [chan put! !]] - [re-frame.core :refer [subscribe dispatch dispatch-sync]] + (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] [syng-im.utils.logging :as log] [syng-im.persistence.realm :as realm] [syng-im.persistence.realm :as r] [syng-im.db :as db])) -(defn signal-discoveries-updated [db] - (update-in db db/updated-discoveries-signal-path #(if % (inc %) 0))) - -(defn discoveries-updated? [db] - (get-in db db/updated-discoveries-signal-path)) - (defn current-tag-updated? [db] (get-in db db/updated-current-tag-signal-path)) - - (defn current-tag [db] (get-in db db/current-tag-path)) @@ -29,21 +20,21 @@ (r/single-cljs))) (defn decrease-tag-counter [tag] - (let [tag (:name tag) + (let [tag (:name tag) tag-object (get-tag tag)] (if tag-object (let [counter (dec (:count tag-object))] - (if (= counter 0) + (if (zero? counter) (realm/delete tag-object) - (realm/create :tag {:name tag + (realm/create :tag {:name tag :count counter} true)))))) (defn increase-tag-counter [tag] - (let [tag (:name tag) + (let [tag (:name tag) tag-object (get-tag tag)] (if tag-object - (realm/create :tag {:name tag + (realm/create :tag {:name tag :count (inc (:count tag-object))} true)))) @@ -59,49 +50,37 @@ (:tags (-> (r/get-by-field :discoveries :whisper-id whisper-id) (r/single-cljs)))) -(defn- create-discovery [{:keys [name status whisper-id photo location tags last-updated]}] - (let [tags (mapv (fn [tag] {:name tag}) tags) - discovery {:name name - :status status - :whisper-id whisper-id - :photo photo - :location location - :tags tags - :last-updated last-updated}] - (log/debug "Creating discovery: " discovery tags) +(defn- create-discovery [{:keys [tags] :as discovery}] + (log/debug "Creating discovery: " discovery tags) + (realm/create :discoveries discovery true) + (increase-tags-counter tags)) + +(defn- update-discovery [{:keys [whisper-id tags] :as discovery}] + (let [old-tags (get-tags whisper-id) + tags (map :name tags)] + (decrease-tags-counter old-tags) (realm/create :discoveries discovery true) (increase-tags-counter tags))) -(defn- update-discovery [{:keys [name status whisper-id photo location tags last-updated]}] - (let [old-tags (get-tags whisper-id) - tags (mapv (fn [tag] {:name tag}) tags) - discovery {:name name - :status status - :whisper-id whisper-id - :photo photo - :location location - :tags tags - :last-updated last-updated}] - (decrease-tags-counter old-tags) - (realm/create :discoveries discovery true) - (increase-tags-counter tags))) - (defn- discovery-exist? [discoveries discovery] (some #(= (:whisper-id discovery) (:whisper-id %)) discoveries)) (defn discovery-list [] - (-> (r/get-all :discoveries) - (r/sorted :last-updated :desc))) + (->> (-> (r/get-all :discoveries) + (r/sorted :last-updated :desc) + r/collection->map) + (map #(update % :tags vals)) + (into '()))) (defn- add-discoveries [discoveries] (realm/write (fn [] - (let [db-discoveries (.slice (discovery-list) 0)] - (dorun (map (fn [discovery] - (if (not (discovery-exist? db-discoveries discovery)) - (create-discovery discovery) - (update-discovery discovery) - )) - discoveries)))))) + (let [db-discoveries (discovery-list)] + (mapv (fn [discovery] + (if-not (discovery-exist? db-discoveries + discovery) + (create-discovery discovery) + (update-discovery discovery))) + discoveries))))) (defn save-discoveries [discoveries] (add-discoveries discoveries)) @@ -114,6 +93,11 @@ (r/page discoveries 0 limit) discoveries))) +(defn all-tags [] + (-> (r/get-all :tag) + (r/sorted :count :desc) + r/collection->map)) + (defn get-tag-popular [limit] (-> (r/get-all :tag) (r/sorted :count :desc) diff --git a/src/syng_im/models/user_data.cljs b/src/syng_im/models/user_data.cljs deleted file mode 100644 index 463a731b5a..0000000000 --- a/src/syng_im/models/user_data.cljs +++ /dev/null @@ -1,17 +0,0 @@ -(ns syng-im.models.user-data - (:require-macros - [natal-shell.async-storage :refer [get-item set-item]]) - (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] - [syng-im.utils.utils :refer [log on-error toast]])) - -(defn save-phone-number [phone-number] - (set-item "user-phone-number" phone-number) - (dispatch [:set-user-phone-number phone-number])) - -(defn load-phone-number [] - (get-item "user-phone-number" - (fn [error value] - (if error - (on-error error) - (dispatch [:set-user-phone-number (when value - (str value))]))))) diff --git a/src/syng_im/navigation/handlers.cljs b/src/syng_im/navigation/handlers.cljs index d15d29bf0d..112fc6ec0a 100644 --- a/src/syng_im/navigation/handlers.cljs +++ b/src/syng_im/navigation/handlers.cljs @@ -1,5 +1,5 @@ (ns syng-im.navigation.handlers - (:require [re-frame.core :refer [register-handler dispatch debug]])) + (:require [re-frame.core :refer [register-handler dispatch debug enrich]])) (defn push-view [db view-id] (-> db @@ -17,7 +17,11 @@ (update :navigation-stack replace-top-element view-id) (assoc :view-id view-id))) +(defmulti preload-data! (fn [_ [_ view-id]] view-id)) +(defmethod preload-data! :default [db _] db) + (register-handler :navigate-to + (enrich preload-data!) (fn [db [_ view-id]] (push-view db view-id))) diff --git a/src/syng_im/persistence/realm.cljs b/src/syng_im/persistence/realm.cljs index 83faef94a4..01879ebb3a 100644 --- a/src/syng_im/persistence/realm.cljs +++ b/src/syng_im/persistence/realm.cljs @@ -44,28 +44,28 @@ :properties {:chat-id "string" :name "string" :group-chat {:type "bool" - :indexed true} - :is-active "bool" - :timestamp "int" - :contacts {:type "list" - :objectType "chat-contact"} + :indexed true} + :is-active "bool" + :timestamp "int" + :contacts {:type "list" + :objectType "chat-contact"} :last-msg-id "string"}} - {:name :tag - :primaryKey :name - :properties {:name "string" - :count {:type "int" - :optional true - :default 0}}} - {:name :discoveries - :primaryKey :whisper-id - :properties {:name "string" - :status "string" - :whisper-id "string" - :photo "string" - :location "string" - :tags {:type "list" - :objectType "tag"} - :last-updated "date"}}]}) + {:name :tag + :primaryKey :name + :properties {:name "string" + :count {:type "int" + :optional true + :default 0}}} + {:name :discoveries + :primaryKey :whisper-id + :properties {:name "string" + :status "string" + :whisper-id "string" + :photo "string" + :location "string" + :tags {:type "list" + :objectType "tag"} + :last-updated "date"}}]}) (def realm (js/Realm. (clj->js opts))) diff --git a/src/syng_im/subs.cljs b/src/syng_im/subs.cljs index 04e6813ee0..1f713b248e 100644 --- a/src/syng_im/subs.cljs +++ b/src/syng_im/subs.cljs @@ -2,12 +2,12 @@ (:require-macros [reagent.ratom :refer [reaction]]) (:require [re-frame.core :refer [register-sub]] [syng-im.models.chats :refer [chats-list chat-by-id]] - [syng-im.models.contacts :refer [contacts-list + [syng-im.models.contacts :refer [get-contacts contacts-list-exclude contacts-list-include]] syng-im.chat.subs syng-im.navigation.subs - syng-im.components.discovery.subs + syng-im.discovery.subs syng-im.contacts.subs)) ;; -- Chats list -------------------------------------------------------------- @@ -18,12 +18,6 @@ ;; -- User data -------------------------------------------------------------- -;; (register-sub -;; :get-user-phone-number -;; (fn [db _] -;; (reaction -;; (get @db :user-phone-number)))) - (register-sub :signed-up (fn [db _] @@ -36,7 +30,7 @@ (register-sub :all-contacts (fn [_ _] - (reaction (contacts-list)))) + (reaction (get-contacts)))) (register-sub :all-new-contacts (fn [db _] diff --git a/src/syng_im/utils/handlers.cljs b/src/syng_im/utils/handlers.cljs new file mode 100644 index 0000000000..154022cad1 --- /dev/null +++ b/src/syng_im/utils/handlers.cljs @@ -0,0 +1,8 @@ +(ns syng-im.utils.handlers) + +(defn side-effect! + "Middleware for handlers that will not affect db." + [handler] + (fn [db params] + (handler db params) + db))