discoveries

This commit is contained in:
Roman Volosovskyi 2016-05-13 14:58:58 +03:00
parent 73d3fdb3e6
commit 748abd40e4
33 changed files with 388 additions and 528 deletions

View File

@ -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]]

View File

@ -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))))))

View File

@ -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

View File

@ -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]

View File

@ -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

View File

@ -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]]])))

View File

@ -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"])))

View File

@ -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}]]))

View File

@ -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"}}]
]
]))

View File

@ -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}]))

View File

@ -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)))

View File

@ -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))))))

View File

@ -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
[icon :back {:marginTop 21
:marginLeft 23
:width 8
:height 14}}]]])
:height 14}]]])
(if content
[view {:style {:flex 1
[view {:flex 1
:alignItems :center
:justifyContent :center}}
:justifyContent :center}
content]
[view {:style {:flex 1
[view {:flex 1
:alignItems :center
:justifyContent :center}}
[text {:style {:marginTop -2.5
:justifyContent :center}
[text {:marginTop -2.5
:color text1-color
:fontSize 16
:fontFamily font}}
:fontFamily font}
title]])
[touchable-highlight {:on-press (:handler action)}
[view {:width 56

View File

@ -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]]

View File

@ -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}]])))

View File

@ -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}}]]])

View File

@ -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}])))

View File

@ -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)

View File

@ -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!))))

View File

@ -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]]])))

View File

@ -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

View File

@ -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))))))

View File

@ -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"])))

View File

@ -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?]

View File

@ -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]

View File

@ -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]

View File

@ -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)
)

View File

@ -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))
@ -33,7 +24,7 @@
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
:count counter}
@ -59,29 +50,14 @@
(: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}]
(defn- create-discovery [{:keys [tags] :as discovery}]
(log/debug "Creating discovery: " discovery tags)
(realm/create :discoveries discovery true)
(increase-tags-counter tags)))
(increase-tags-counter tags))
(defn- update-discovery [{:keys [name status whisper-id photo location tags last-updated]}]
(defn- update-discovery [{:keys [whisper-id tags] :as discovery}]
(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}]
tags (map :name tags)]
(decrease-tags-counter old-tags)
(realm/create :discoveries discovery true)
(increase-tags-counter tags)))
@ -90,18 +66,21 @@
(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))
(let [db-discoveries (discovery-list)]
(mapv (fn [discovery]
(if-not (discovery-exist? db-discoveries
discovery)
(create-discovery discovery)
(update-discovery discovery)
))
discoveries))))))
(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)

View File

@ -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))])))))

View File

@ -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)))

View File

@ -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 _]

View File

@ -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))