From 7d47ab2d627436d9a0353e8386024983592fafa3 Mon Sep 17 00:00:00 2001 From: Adrian Tiberius Date: Wed, 25 May 2016 04:27:03 +0300 Subject: [PATCH] added i18n translations Former-commit-id: b15c156a40957c27f0c4feea3ea7ceedf0407090 --- src/status_im/chat/screen.cljs | 44 ++++---- src/status_im/chat/sign_up.cljs | 105 ++++++++---------- src/status_im/chats_list/screen.cljs | 7 +- src/status_im/components/drawer/view.cljs | 17 +-- src/status_im/components/main_tabs.cljs | 8 +- src/status_im/components/toolbar.cljs | 16 +-- src/status_im/contacts/screen.cljs | 5 +- .../contacts/views/contact_inner.cljs | 5 +- src/status_im/discovery/screen.cljs | 11 +- src/status_im/discovery/tag.cljs | 3 - src/status_im/discovery/views/popular.cljs | 5 +- src/status_im/group_settings/screen.cljs | 37 +++--- .../group_settings/views/member.cljs | 5 +- src/status_im/i18n.cljs | 22 ++++ src/status_im/models/commands.cljs | 39 +++---- src/status_im/new_group/screen.cljs | 13 ++- src/status_im/participants/views/add.cljs | 5 +- src/status_im/participants/views/remove.cljs | 2 +- src/status_im/profile/screen.cljs | 23 ++-- src/status_im/protocol/handlers.cljs | 15 +-- src/status_im/translations/en.cljs | 99 +++++++++++++++++ 21 files changed, 302 insertions(+), 184 deletions(-) create mode 100644 src/status_im/i18n.cljs create mode 100644 src/status_im/translations/en.cljs diff --git a/src/status_im/chat/screen.cljs b/src/status_im/chat/screen.cljs index 19723aba22..55096319e4 100644 --- a/src/status_im/chat/screen.cljs +++ b/src/status_im/chat/screen.cljs @@ -17,7 +17,8 @@ [status-im.components.invertible-scroll-view :refer [invertible-scroll-view]] [status-im.components.toolbar :refer [toolbar]] [status-im.chat.views.message :refer [chat-message]] - [status-im.chat.views.new-message :refer [chat-message-new]])) + [status-im.chat.views.new-message :refer [chat-message-new]] + [status-im.i18n :refer [t]])) (defn contacts-by-identity [contacts] @@ -46,7 +47,7 @@ [view st/typing-view [view st/typing-background [text {:style st/typing-text} - (str member " is typing")]]]) + (str member " " (t :chat.is-typing))]]]) (defn typing-all [] [view st/typing-all @@ -100,63 +101,63 @@ [chat-icon-view-menu-item chat-id group-chat name color true]) (defn members-text [members] - (truncate-str (str (s/join ", " (map #(:name %) members)) " and you") 35)) + (truncate-str (str (s/join ", " (map #(:name %) members)) " " (t :chat.and-you)) 35)) (defn actions-list-view [] (let [{:keys [group-chat chat-id]} (subscribe [:chat-properties [:group-chat :chat-id]]) members (subscribe [:current-chat-contacts])] (when-let [actions (if @group-chat - [{:title "Members" + [{:title (t :members-title) :subtitle (members-text @members) :icon :menu_group :icon-style {:width 25 :height 19} ;; TODO not implemented: action Members :handler nil} - {:title "Search chat" - :subtitle "!not implemented" + {:title (t :chat.search-chat) + :subtitle (t :not-implemented) :icon :search_gray_copy :icon-style {:width 17 :height 17} ;; TODO not implemented: action Search chat :handler nil} - {:title "Notifications and sounds" - :subtitle "!not implemented" + {:title (t :notifications.title) + :subtitle (t :not-implemented) ;;:subtitle "Chat muted" :icon :muted :icon-style {:width 18 :height 21} ;; TODO not implemented: action Notifications :handler nil} - {:title "Settings" + {:title (t :settings.title) :icon :settings :icon-style {:width 20 :height 13} :handler #(dispatch [:show-group-settings])}] - [{:title "Profile" + [{:title (t :profile.title) :custom-icon [menu-item-icon-profile] :icon :menu_group :icon-style {:width 25 :height 19} :handler #(dispatch [:show-profile @chat-id])} - {:title "Search chat" - :subtitle "!not implemented" + {:title (t :chat.search-chat) + :subtitle (t :not-implemented) :icon :search_gray_copy :icon-style {:width 17 :height 17} ;; TODO not implemented: action Search chat :handler nil} - {:title "Notifications and sounds" - :subtitle "!not implemented" + {:title (t :notifications.title) + :subtitle (t :not-implemented) ;;:subtitle "Notifications on" :icon :muted :icon-style {:width 18 :height 21} ;; TODO not implemented: action Notifications :handler nil} - {:title "Settings" - :subtitle "!not implemented" + {:title (t :settings.title) + :subtitle (t :not-implemented) :icon :settings :icon-style {:width 20 :height 13} @@ -179,20 +180,15 @@ (fn [] [view (st/chat-name-view @show-actions) [text {:style st/chat-name-text} - (truncate-str (or @name "Chat name") 30)] + (truncate-str (or @name (t :chat-name)) 30)] (if @group-chat [view {:flexDirection :row} [icon :group st/group-icon] [text {:style st/members} (let [cnt (inc (count @contacts))] - (str cnt - (if (< 1 cnt) - " members" - " member") - ;; TODO stub data: active members - ", " cnt " active"))]] + (t :chat.members {:count cnt}))]] ;; TODO stub data: last activity - [text {:style st/last-activity} "Active a minute ago"])]))) + [text {:style st/last-activity} (t :chat.last-active)])]))) (defn toolbar-action [] (let [show-actions (subscribe [:show-actions])] diff --git a/src/status_im/chat/sign_up.cljs b/src/status_im/chat/sign_up.cljs index ef855d0021..5026b4914f 100644 --- a/src/status_im/chat/sign_up.cljs +++ b/src/status_im/chat/sign_up.cljs @@ -13,12 +13,13 @@ [status-im.constants :refer [text-content-type content-type-command content-type-command-request - content-type-status]])) + content-type-status]] + [status-im.i18n :refer [t]])) (defn send-console-msg [text] {:msg-id (random/id) - :from "me" - :to "console" + :from (t :me) + :to (t :console) :content text :content-type text-content-type :outgoing true}) @@ -32,11 +33,11 @@ (defn on-sync-contacts [] (dispatch [:received-msg {:msg-id (random/id) - :content (str "Your contacts have been synchronized") + :content (t :sign-up.contacts-syncronized) :content-type text-content-type :outgoing false - :from "console" - :to "me"}]) + :from (t :console) + :to (t :me)}]) (dispatch [:set-signed-up true])) (defn sync-contacts [] @@ -49,8 +50,8 @@ :content (:message body) :content-type text-content-type :outgoing false - :from "console" - :to "me"}]) + :from (t :console) + :to (t :me)}]) (when (:confirmed body) (dispatch [:stop-listening-confirmation-code-sms]) (sync-contacts) @@ -70,12 +71,11 @@ {:msg-id msg-id :content (command-content :confirmation-code - (str "Thanks! We've sent you a text message with a confirmation " - "code. Please provide that code to confirm your phone number")) + (t :sign-up.confirmation-code)) :content-type content-type-command-request :outgoing false - :from "console" - :to "me"}]))) + :from (t :console) + :to (t :me)}]))) (defn handle-sms [{body :body}] (when-let [matches (re-matches #"(\d{4})" body)] @@ -95,28 +95,25 @@ ;; TODO validate and save password (dispatch [:received-msg {:msg-id (random/id) - :content (str "OK great! Your password has been saved. Just to let you " - "know you can always change it in the Console by the way " - "it's me the Console nice to meet you!") + :content (t :sign-up.password-saved) :content-type text-content-type :outgoing false - :from "console" - :to "me"}]) + :from (t :console) + :to (t :me)}]) (dispatch [:received-msg {:msg-id (random/id) - :content (str "I'll generate a passphrase for you so you can restore your " - "access or log in from another device") + :content (t :sign-up.generate-passphrase) :content-type text-content-type :outgoing false - :from "console" - :to "me"}]) + :from (t :console) + :to (t :me)}]) (dispatch [:received-msg {:msg-id (random/id) - :content "Here's your passphrase:" + :content (t :sign-up.passphrase) :content-type text-content-type :outgoing false - :from "console" - :to "me"}]) + :from (t :console) + :to (t :me)}]) ;; TODO generate passphrase (let [passphrase (str "The brash businessman's braggadocio and public squabbing with " "candidates in the US presidential election")] @@ -125,79 +122,73 @@ :content passphrase :content-type text-content-type :outgoing false - :from "console" - :to "me"}])) + :from (t :console) + :to (t :me)}])) (dispatch [:received-msg {:msg-id "8" - :content "Make sure you had securely written it down" + :content (t :sign-up.written-down) :content-type text-content-type :outgoing false - :from "console" - :to "me"}]) + :from (t :console) + :to (t :me)}]) ;; TODO highlight '!phone' (let [msg-id (random/id)] (dispatch [:received-msg {:msg-id msg-id :content (command-content :phone - (str "Your phone number is also required to use the app. Type the " - "exclamation mark or hit the icon to open the command list " - "and choose the !phone command")) + (t :sign-up.phone-number-required)) :content-type content-type-command-request :outgoing false - :from "console" - :to "me"}]))) + :from (t :console) + :to (t :me)}]))) (def intro-status {:msg-id "intro-status" - :content (str "The brash businessman’s braggadocio " - "and public exchange with candidates " - "in the US presidential election") + :content (t :sign-up.intro-status) :delivery-status "seen" - :from "console" - :chat-id "console" + :from (t :console) + :chat-id (t :console) :content-type content-type-status :outgoing false - :to "me"}) + :to (t :me)}) (defn intro [db] (dispatch [:received-msg intro-status]) (dispatch [:received-msg {:msg-id "intro-message1" - :content "Hello there! It's Status a Dapp browser in your phone." + :content (t :sign-up.intro-message1) :content-type text-content-type :outgoing false - :from "console" - :to "me"}]) + :from (t :console) + :to (t :me)}]) (dispatch [:received-msg {:msg-id "intro-message2" - :content (str "Status uses a highly secure key-pair authentication type " - "to provide you a reliable way to access your account") + :content (t :sign-up.intro-message2) :content-type text-content-type :outgoing false - :from "console" - :to "me"}]) + :from (t :console) + :to (t :me)}]) (let [msg-id "into-message3"] (dispatch [:received-msg {:msg-id msg-id :content (command-content :keypair-password - (str "A key pair has been generated and saved to your device. " - "Create a password to secure your key")) + (t :sign-up.keypair-generated)) :content-type content-type-command-request :outgoing false - :from "console" - :to "me"}])) + :from (t :console) + :to (t :me)}])) db) (def console-chat - {:chat-id "console" - :name "console" + {:chat-id (t :console) + :name (t :console) :color default-chat-color :group-chat false :is-active true :timestamp (.getTime (js/Date.)) - :contacts [{:identity "console" + :contacts [{:identity (t :console) :text-color "#FFFFFF" :background-color "#AB7967"}]}) @@ -211,10 +202,10 @@ (def init (create-chat (fn [{:keys [chats] :as db}] - (if (chats "console") + (if (chats (t :console)) db (-> db - (assoc-in [:chats "console"] console-chat) + (assoc-in [:chats (t :console)] console-chat) (assoc :new-chat console-chat) - (assoc :current-chat-id "console") + (assoc :current-chat-id (t :console)) (intro)))))) diff --git a/src/status_im/chats_list/screen.cljs b/src/status_im/chats_list/screen.cljs index 980c21146e..cf4cadde59 100644 --- a/src/status_im/chats_list/screen.cljs +++ b/src/status_im/chats_list/screen.cljs @@ -16,13 +16,14 @@ toolbar-background2]] [status-im.components.toolbar :refer [toolbar]] [status-im.components.icons.ionicons :refer [icon]] + [status-im.i18n :refer [t]] [status-im.chats-list.styles :as st])) (defn chats-list-toolbar [] [toolbar {:nav-action {:image {:source {:uri :icon_hamburger} :style st/hamburger-icon} :handler open-drawer} - :title "Chats" + :title (t :chats.title) :background-color toolbar-background2 ;; TODO implement search :action {:image {:source {:uri :icon_search} @@ -43,13 +44,13 @@ :offsetY 16 :offsetX 16} [action-button-item - {:title "New Chat" + {:title (t :chats.new-chat) :buttonColor :#9b59b6 :onPress #(dispatch [:navigate-to :contact-list])} [icon {:name :android-create :style st/create-icon}]] [action-button-item - {:title "New Group Chat" + {:title (t :chats.new-group-chat) :buttonColor :#1abc9c :onPress #(dispatch [:show-group-new])} [icon {:name :person-stalker diff --git a/src/status_im/components/drawer/view.cljs b/src/status_im/components/drawer/view.cljs index 5101c6eaaa..29ffa414b4 100644 --- a/src/status_im/components/drawer/view.cljs +++ b/src/status_im/components/drawer/view.cljs @@ -11,7 +11,8 @@ drawer-layout-android touchable-opacity]] [status-im.resources :as res] - [status-im.components.drawer.styles :as st])) + [status-im.components.drawer.styles :as st] + [status-im.i18n :refer [t]])) (defonce drawer-atom (atom)) @@ -45,21 +46,21 @@ [text {:style st/name-text} @username]] [view st/menu-items-container - [menu-item {:name "Profile" + [menu-item {:name (t :profile.title) :handler #(dispatch [:navigate-to :my-profile])}] - [menu-item {:name "Settings" + [menu-item {:name (t :settings.title) :handler (fn [] ;; TODO not implemented )}] - [menu-item {:name "Discovery" + [menu-item {:name (t :discovery.title) :handler #(dispatch [:navigate-to :discovery])}] - [menu-item {:name "Contacts" + [menu-item {:name (t :contacts.title) :handler #(dispatch [:show-contacts navigator])}] - [menu-item {:name "Invite friends" + [menu-item {:name (t :invite-friends.title) :handler (fn [] ;; TODO not implemented )}] - [menu-item {:name "FAQ" + [menu-item {:name (t :faq.title) :handler (fn [])}]] [view st/switch-users-container [touchable-opacity {:onPress (fn [] @@ -67,7 +68,7 @@ ;; TODO not implemented )} [text {:style st/switch-users-text} - "Switch users"]]]]))) + (t :drawer.switch-users)]]]]))) (defn drawer-view [items] [drawer-layout-android {:drawerWidth 260 diff --git a/src/status_im/components/main_tabs.cljs b/src/status_im/components/main_tabs.cljs index b25ade7f4b..20a8ee5103 100644 --- a/src/status_im/components/main_tabs.cljs +++ b/src/status_im/components/main_tabs.cljs @@ -12,19 +12,19 @@ [status-im.components.tabs.tabs :refer [tabs]] [status-im.components.tabs.styles :as st] [status-im.components.styles :as common-st] - [status-im.utils.logging :as log])) + [status-im.i18n :refer [t]])) (def tab-list [{:view-id :chat-list - :title "Chats" + :title (t :chats.title) :screen chats-list :icon :icon_tab_chats} {:view-id :discovery - :title "Discover" + :title (t :discovery.title) :screen discovery :icon :icon_tab_discovery} {:view-id :contact-list - :title "Contacts" + :title (t :contacts.title) :screen contact-list :icon :icon_tab_contacts}]) diff --git a/src/status_im/components/toolbar.cljs b/src/status_im/components/toolbar.cljs index d7a164a624..3f21fc8a35 100644 --- a/src/status_im/components/toolbar.cljs +++ b/src/status_im/components/toolbar.cljs @@ -18,7 +18,7 @@ (defn toolbar [{:keys [title nav-action hide-nav? action custom-action background-color custom-content style]}] - (let [style (merge {:flexDirection "row" + (let [style (merge {:flexDirection :row :backgroundColor (or background-color toolbar-background1) :height 56 :elevation 2} style)] @@ -28,21 +28,21 @@ [touchable-highlight {:on-press (:handler nav-action)} [view {:width 56 :height 56 - :alignItems "center" - :justifyContent "center"} + :alignItems :center + :justifyContent :center} [image (:image nav-action)]]] [touchable-highlight {:on-press #(dispatch [:navigate-back])} [view {:width 56 :height 56} - [image {:source {:uri "icon_back"} + [image {:source {:uri :icon_back} :style {:marginTop 21 :marginLeft 23 :width 8 :height 14}}]]])) (or custom-content [view {:style {:flex 1 - :alignItems "center" - :justifyContent "center"}} + :alignItems :center + :justifyContent :center}} [text {:style {:marginTop -2.5 :color text1-color :fontSize 16 @@ -54,7 +54,7 @@ [view {:width 56 :height 56 - :alignItems "center" - :justifyContent "center"} + :alignItems :center + :justifyContent :center} [image (:image action)]]])])) diff --git a/src/status_im/contacts/screen.cljs b/src/status_im/contacts/screen.cljs index 3ed6af93bf..ab5944796a 100644 --- a/src/status_im/contacts/screen.cljs +++ b/src/status_im/contacts/screen.cljs @@ -10,13 +10,14 @@ [status-im.components.styles :refer [toolbar-background2]] [status-im.components.toolbar :refer [toolbar]] [status-im.contacts.styles :as st] - [status-im.utils.listview :as lw])) + [status-im.utils.listview :as lw] + [status-im.i18n :refer [t]])) (defn render-row [row _ _] (list-item [contact-view row])) (defn contact-list-toolbar [] - [toolbar {:title "Contacts" + [toolbar {:title (t :contacts.title) :background-color toolbar-background2 :action {:image {:source {:uri :icon_search} :style st/search-icon} diff --git a/src/status_im/contacts/views/contact_inner.cljs b/src/status_im/contacts/views/contact_inner.cljs index 0c62dbd650..222c34ffe9 100644 --- a/src/status_im/contacts/views/contact_inner.cljs +++ b/src/status_im/contacts/views/contact_inner.cljs @@ -2,7 +2,8 @@ (:require [clojure.string :as s] [status-im.components.react :refer [view image text]] [status-im.resources :as res] - [status-im.contacts.styles :as st])) + [status-im.contacts.styles :as st] + [status-im.i18n :refer [t]])) (defn contact-photo [{:keys [photo-path]}] [view st/contact-photo-container @@ -27,4 +28,4 @@ (if (pos? (count name)) name ;; todo is this correct behaviour? - "Noname")]]]) + (t :contacts.no-name))]]]) diff --git a/src/status_im/discovery/screen.cljs b/src/status_im/discovery/screen.cljs index fc06443fa7..07995499c8 100644 --- a/src/status_im/discovery/screen.cljs +++ b/src/status_im/discovery/screen.cljs @@ -9,7 +9,8 @@ [status-im.components.toolbar :refer [toolbar]] [status-im.discovery.views.popular :refer [popular]] [status-im.discovery.views.recent :refer [discovery-recent]] - [status-im.discovery.styles :as st])) + [status-im.discovery.styles :as st] + [status-im.i18n :refer [t]])) (defn get-hashtags [status] (let [hashtags (map #(subs % 1) (re-seq #"#[^ !?,;:.]+" status))] @@ -20,13 +21,13 @@ (if show-search [text-input {:style st/discovery-search-input :autoFocus true - :placeholder "Type your search tags here" + :placeholder (t :discovery.search-tags) :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"]])]) + [text {:style st/discovery-title} (t :discovery.title)]])]) (defn toogle-search [current-value] (dispatch [:set ::show-search (not current-value)])) @@ -45,8 +46,8 @@ :handler #(toogle-search show-search)}}] [scroll-view st/scroll-view-container [view st/section-spacing - [text {:style st/discovery-subtitle} "Popular tags"]] + [text {:style st/discovery-subtitle} (t :discovery.popular-tags)]] [popular] [view st/section-spacing - [text {:style st/discovery-subtitle} "Recent"]] + [text {:style st/discovery-subtitle} (t :discovery.recent)]] [discovery-recent]]]) diff --git a/src/status_im/discovery/tag.cljs b/src/status_im/discovery/tag.cljs index a872b48000..aeda1f4d3c 100644 --- a/src/status_im/discovery/tag.cljs +++ b/src/status_im/discovery/tag.cljs @@ -1,7 +1,6 @@ (ns status-im.discovery.tag (:require [re-frame.core :refer [subscribe dispatch]] - [status-im.utils.logging :as log] [status-im.utils.listview :refer [to-datasource]] [status-im.components.react :refer [view text list-view list-item]] [status-im.components.toolbar :refer [toolbar]] @@ -23,7 +22,6 @@ (defn discovery-tag [] (let [tag (subscribe [:get :current-tag]) discoveries (subscribe [:get-discoveries-by-tag])] - (log/debug "Got discoveries: " @discoveries) (fn [] (let [items @discoveries datasource (to-datasource items)] @@ -31,7 +29,6 @@ [toolbar {:nav-action {:image {:source {:uri :icon_back} :style st/icon-back} :handler #(dispatch [:navigate-back])} - :title "Add Participants" :custom-content (title-content @tag) :action {:image {:source {:uri :icon_search} :style st/icon-search} diff --git a/src/status_im/discovery/views/popular.cljs b/src/status_im/discovery/views/popular.cljs index 65b47fdf05..2b997d6829 100644 --- a/src/status_im/discovery/views/popular.cljs +++ b/src/status_im/discovery/views/popular.cljs @@ -7,7 +7,8 @@ text]] [status-im.components.carousel.carousel :refer [carousel]] [status-im.discovery.styles :as st] - [status-im.discovery.views.popular-list :refer [discovery-popular-list]])) + [status-im.discovery.views.popular-list :refer [discovery-popular-list]] + [status-im.i18n :refer [t]])) (defn page-width [] (.-width (.get (.. js/React -Dimensions) "window"))) @@ -19,4 +20,4 @@ :sneak 20} (for [{:keys [name count]} popular-tags] [discovery-popular-list name count])] - [text "None"])) + [text (t :discovery.none)])) diff --git a/src/status_im/group_settings/screen.cljs b/src/status_im/group_settings/screen.cljs index 1c49c4f094..8544b85728 100644 --- a/src/status_im/group_settings/screen.cljs +++ b/src/status_im/group_settings/screen.cljs @@ -14,7 +14,8 @@ [status-im.components.toolbar :refer [toolbar]] [status-im.components.chat-icon.screen :refer [chat-icon-view-action]] [status-im.group-settings.styles.group-settings :as st] - [status-im.group-settings.views.member :refer [member-view]])) + [status-im.group-settings.views.member :refer [member-view]] + [status-im.i18n :refer [t]])) (defn remove-member [] (dispatch [:remove-participants])) @@ -35,7 +36,7 @@ [text {:style st/modal-member-name} name] [touchable-highlight {:on-press remove-member} [text {:style st/modal-remove-text} - "Remove"]]]]])) + (t :group-settings.remove)]]]]])) (defview chat-members [] [members [:current-chat-contacts]] @@ -75,13 +76,13 @@ [view st/modal-color-picker-inner-container [picker {:selectedValue new-color :onValueChange #(dispatch [:set :new-chat-color %])} - [picker-item {:label "Blue" :value "#7099e6"}] - [picker-item {:label "Purple" :value "#a187d5"}] - [picker-item {:label "Green" :value "green"}] - [picker-item {:label "Red" :value "red"}]] + [picker-item {:label (t :colors.blue) :value "#7099e6"}] + [picker-item {:label (t :colors.purple) :value "#a187d5"}] + [picker-item {:label (t :colors.green) :value "green"}] + [picker-item {:label (t :colors.red) :value "red"}]] [touchable-highlight {:on-press set-chat-color} [text {:style st/modal-color-picker-save-btn-text} - "Save"]]]]]) + (t :group-settings.save)]]]]]) (defview chat-color-icon [] [chat-color [:chat :color]] @@ -92,11 +93,11 @@ (defn settings-view [] (let [settings [{:custom-icon [chat-color-icon] - :title "Change color" + :title (t :group-settings.change-color) :handler show-chat-color-picker} ;; TODO not implemented: Notifications - (merge {:title "Notifications and sounds" - :subtitle "!not implemented" + (merge {:title (t :notifications.title) + :subtitle (t :not-implemented) :handler nil} (if true {:icon :notifications-on @@ -108,13 +109,13 @@ {:icon :close-gray :icon-style {:width 12 :height 12} - :title "Clear history" + :title (t :group-settings.clear-history) ;; TODO show confirmation dialog? :handler #(dispatch [:clear-history])} {:icon :bin :icon-style {:width 12 :height 18} - :title "Delete and leave" + :title (t :group-settings.delete-and-leave) ;; TODO show confirmation dialog? :handler #(dispatch [:leave-group-chat])}]] [view st/settings-container @@ -130,7 +131,7 @@ [chat-icon-view-action chat-id group-chat name color false]]) (defn new-group-toolbar [] - [toolbar {:title "Chat settings" + [toolbar {:title (t :group-settings.chat-settings) :custom-action [chat-icon]}]) (defn focus [] @@ -147,7 +148,7 @@ new-name [:get :new-chat-name] focused? [:get ::name-input-focused]] [view - [text {:style st/chat-name-text} "Chat name"] + [text {:style st/chat-name-text} (t :chat-name)] [view (st/chat-name-value-container focused?) [text-input {:style st/chat-name-value :ref #(when (and % focused?) (.focus %)) @@ -161,7 +162,7 @@ [view [icon :ok-purple st/add-members-icon]]] [touchable-highlight {:style st/chat-name-btn-edit-container :on-press focus} - [text {:style st/chat-name-btn-edit-text} "Edit"]])]]) + [text {:style st/chat-name-btn-edit-text} (t :group-settings.edit)]])]]) (defview group-settings [] [show-color-picker [:group-settings :show-color-picker]] @@ -169,16 +170,16 @@ [new-group-toolbar] [scroll-view st/body [chat-name] - [text {:style st/members-text} "Members"] + [text {:style st/members-text} (t :members-title)] [touchable-highlight {:on-press #(dispatch [:navigate-to :add-participants])} ;; TODO add participants view is not in design [view st/add-members-container [icon :add-gray st/add-members-icon] [text {:style st/add-members-text} - "Add members"]]] + (t :group-settings.add-members)]]] [chat-members] [text {:style st/settings-text} - "Settings"] + (t :settings.title)] [settings-view]] (when show-color-picker [chat-color-picker]) diff --git a/src/status_im/group_settings/views/member.cljs b/src/status_im/group_settings/views/member.cljs index 240d6a09c8..302b516fe3 100644 --- a/src/status_im/group_settings/views/member.cljs +++ b/src/status_im/group_settings/views/member.cljs @@ -7,7 +7,8 @@ icon touchable-highlight]] [status-im.resources :as res] - [status-im.group-settings.styles.member :as st])) + [status-im.group-settings.styles.member :as st] + [status-im.i18n :refer [t]])) (defn contact-photo [{:keys [photo-path]}] [view st/contact-photo-container @@ -32,7 +33,7 @@ (if (pos? (count name)) name ;; todo is this correct behaviour? - "Noname")] + (t :group-settings.no-name))] ;; TODO implement :role property for group chat contact (when role [text {:style st/role-text} diff --git a/src/status_im/i18n.cljs b/src/status_im/i18n.cljs new file mode 100644 index 0000000000..22410ace37 --- /dev/null +++ b/src/status_im/i18n.cljs @@ -0,0 +1,22 @@ +(ns status-im.i18n + (:require + [status-im.translations.en :as en])) + +(set! js/window.I18n (js/require "react-native-i18n")) +(set! (.-fallbacks js/I18n) true) + +(set! (.-translations js.I18n) (clj->js {:en en/translations})) + +(defn t [path & options] + (.t js/I18n (name path) options)) + +(comment + (defn deep-merge [& maps] + (if (every? map? maps) + (apply merge-with deep-merge maps) + (last maps))) + + (defn add-translations [new-translations] + (let [translations (.-translations js/I18n)] + (set! (.-translations js/I18n) (clj->js (deep-merge (js->clj translations) new-translations))))) + ) \ No newline at end of file diff --git a/src/status_im/models/commands.cljs b/src/status_im/models/commands.cljs index 4ade2ed196..5b8a3ec915 100644 --- a/src/status_im/models/commands.cljs +++ b/src/status_im/models/commands.cljs @@ -3,58 +3,59 @@ [clojure.walk :refer [stringify-keys keywordize-keys]] [re-frame.core :refer [subscribe dispatch]] [status-im.db :as db] - [status-im.components.styles :refer [color-blue color-dark-mint]])) + [status-im.components.styles :refer [color-blue color-dark-mint]] + [status-im.i18n :refer [t]])) ;; todo delete (def commands [{:command :money - :text "!money" - :description "Send money" + :text (t :commands.money.text) + :description (t :commands.money.description) :color color-dark-mint :request-icon {:uri "icon_lock_white"} :icon {:uri "icon_lock_gray"} :suggestion true} {:command :location - :text "!location" - :description "Send location" + :text (t :commands.location.text) + :description (t :commands.location.description) :color "#9a5dcf" :suggestion true} {:command :phone - :text "!phone" - :description "Send phone number" + :text (t :commands.phone.text) + :description (t :commands.phone.description) :color color-dark-mint - :request-text "Phone number request" + :request-text (t :commands.phone.request-text) :suggestion true :handler #(dispatch [:sign-up %])} {:command :confirmation-code - :text "!confirmationCode" - :description "Send confirmation code" - :request-text "Confirmation code request" + :text (t :commands.confirmation-code.text) + :description (t :commands.confirmation-code.description) + :request-text (t :commands.confirmation-code.request-text) :color color-blue :request-icon {:uri "icon_lock_white"} :icon {:uri "icon_lock_gray"} :suggestion true :handler #(dispatch [:sign-up-confirm %])} {:command :send - :text "!send" - :description "Send location" + :text (t :commands.send.text) + :description (t :commands.send.description) :color "#9a5dcf" :suggestion true} {:command :request - :text "!request" - :description "Send request" + :text (t :commands.request.text) + :description (t :commands.request.description) :color "#48ba30" :suggestion true} {:command :keypair-password - :text "!keypairPassword" - :description "" + :text (t :commands.keypair-password.text) + :description (t :commands.keypair-password.description) :color color-blue :request-icon {:uri "icon_lock_white"} :icon {:uri "icon_lock_gray"} :suggestion false :handler #(dispatch [:save-password %])} {:command :help - :text "!help" - :description "Help" + :text (t :commands.help.text) + :description (t :commands.help.description) :color "#9a5dcf" :suggestion true}]) diff --git a/src/status_im/new_group/screen.cljs b/src/status_im/new_group/screen.cljs index a620959d50..0639d55dc3 100644 --- a/src/status_im/new_group/screen.cljs +++ b/src/status_im/new_group/screen.cljs @@ -14,14 +14,15 @@ [status-im.components.toolbar :refer [toolbar]] [status-im.utils.listview :refer [to-datasource]] [status-im.new-group.views.contact :refer [new-group-contact]] - [status-im.new-group.styles :as st])) + [status-im.new-group.styles :as st] + [status-im.i18n :refer [t]])) (defview new-group-toolbar [] [group-name [:get ::group-name] creation-disabled? [:get :disable-group-creation]] [toolbar - {:title "New group chat" + {:title (t :new-group.title) :action {:image {:source res/v ;; {:uri "icon_search"} :style st/toolbar-icon} :handler (when-not creation-disabled? @@ -33,7 +34,7 @@ {:underlineColorAndroid color-purple :style st/group-name-input :autoFocus true - :placeholder "Group Name" + :placeholder (t :new-group.group-name) :onChangeText #(dispatch [:set ::group-name %])} group-name]) @@ -42,13 +43,13 @@ [view st/new-group-container [new-group-toolbar] [view st/chat-name-container - [text {:style st/chat-name-text} "Chat name"] + [text {:style st/chat-name-text} (t :chat-name)] [group-name-input] - [text {:style st/members-text} "Members"] + [text {:style st/members-text} (t :members-title)] [touchable-highlight {:on-press (fn [])} [view st/add-container [icon :add_gray st/add-icon] - [text {:style st/add-text} "Add members"]]] + [text {:style st/add-text} (t :group-settings.add-members)]]] [list-view {:dataSource (to-datasource contacts) :renderRow (fn [row _ _] diff --git a/src/status_im/participants/views/add.cljs b/src/status_im/participants/views/add.cljs index 5bab93ea1c..56f3a2a597 100644 --- a/src/status_im/participants/views/add.cljs +++ b/src/status_im/participants/views/add.cljs @@ -7,11 +7,12 @@ [status-im.utils.listview :refer [to-datasource]] [status-im.participants.views.contact :refer [participant-contact]] [reagent.core :as r] - [status-im.participants.styles :as st])) + [status-im.participants.styles :as st] + [status-im.i18n :refer [t]])) (defn new-participants-toolbar [] [toolbar - {:title "Add Participants" + {:title (t :participants.add) :action {:image {:source res/v ;; {:uri "icon_search"} :style st/new-participant-image} :handler #(do (dispatch [:add-new-participants]) diff --git a/src/status_im/participants/views/remove.cljs b/src/status_im/participants/views/remove.cljs index e7b8103ffe..b7fee9f419 100644 --- a/src/status_im/participants/views/remove.cljs +++ b/src/status_im/participants/views/remove.cljs @@ -14,7 +14,7 @@ (defn remove-participants-toolbar [] [toolbar - {:title "Remove Participants" + {:title (t :participants.remove) :action {:handler #(do (dispatch [:remove-participants]) (dispatch [:navigate-back])) :image {:source res/trash-icon ;; {:uri "icon_search"} diff --git a/src/status_im/profile/screen.cljs b/src/status_im/profile/screen.cljs index 83470681dc..3665619229 100644 --- a/src/status_im/profile/screen.cljs +++ b/src/status_im/profile/screen.cljs @@ -10,7 +10,8 @@ touchable-opacity]] [status-im.components.chat-icon.screen :refer [profile-icon my-profile-icon]] - [status-im.profile.styles :as st])) + [status-im.profile.styles :as st] + [status-im.i18n :refer [t]])) (defn profile-property-view [{:keys [name value]}] [view st/profile-property-view-container @@ -34,29 +35,29 @@ [profile-icon]] [text {:style st/user-name} name] ;; TODO stub data - [text {:style st/status} "!not implemented"] + [text {:style st/status} (t :not-implemented)] [view st/btns-container [touchable-highlight {:onPress #(message-user whisper-identity)} [view st/message-btn - [text {:style st/message-btn-text} "Message"]]] + [text {:style st/message-btn-text} (t :profile.message)]]] [touchable-highlight {:onPress (fn [] ;; TODO not implemented )} [view st/more-btn [icon :more_vertical_blue st/more-btn-image]]]]] [view st/profile-properties-container - [profile-property-view {:name "Username" + [profile-property-view {:name (t :profile.username) :value name}] - [profile-property-view {:name "Phone number" + [profile-property-view {:name (t :profile.phone-number) :value phone-number}] ;; TODO stub data - [profile-property-view {:name "Email" - :value "!not implemented"}] + [profile-property-view {:name (t :profile.email) + :value (t :not-implemented)}] [view st/report-user-container [touchable-highlight {:on-press (fn [] ;; TODO not implemented )} - [text {:style st/report-user-text} "REPORT USER"]]]]]) + [text {:style st/report-user-text} (t :profile.report-user)]]]]]) (defview my-profile [] [username [:get :username] @@ -81,9 +82,9 @@ [text {:style st/user-name} username] [text {:style st/status} status]] [view st/profile-properties-container - [profile-property-view {:name "Username" + [profile-property-view {:name (t :profile.username) :value username}] - [profile-property-view {:name "Phone number" + [profile-property-view {:name (t :profile.phone-number) :value phone-number}] - [profile-property-view {:name "Email" + [profile-property-view {:name (t :profile.email) :value email}]]]) diff --git a/src/status_im/protocol/handlers.cljs b/src/status_im/protocol/handlers.cljs index 4b51c9ec65..2ba283f6f8 100644 --- a/src/status_im/protocol/handlers.cljs +++ b/src/status_im/protocol/handlers.cljs @@ -12,7 +12,8 @@ set-initialized]] [status-im.constants :refer [text-content-type]] [status-im.models.messages :as messages] - [status-im.models.chats :as chats])) + [status-im.models.chats :as chats] + [status-im.i18n :refer [t]])) (register-handler :initialize-protocol (u/side-effect! @@ -35,35 +36,35 @@ (let [contact-name (:name (contacts/contact-by-identity from))] (messages/save-message chat-id {:from "system" :msg-id (str msg-id "_" from) - :content (str (or contact-name from) " received chat invitation") + :content (str (or contact-name from) " " (t :protocol.received-invitation)) :content-type text-content-type}))) (defn participant-invited-to-group-msg [chat-id identity from msg-id] (let [inviter-name (:name (contacts/contact-by-identity from)) invitee-name (if (= identity (api/my-identity)) - "You" + (t :You) (:name (contacts/contact-by-identity identity)))] (messages/save-message chat-id {:from "system" :msg-id msg-id - :content (str (or inviter-name from) " invited " (or invitee-name identity)) + :content (str (or inviter-name from) " " (t :invited) " " (or invitee-name identity)) :content-type text-content-type}))) (defn participant-removed-from-group-msg [chat-id identity from msg-id] (let [remover-name (:name (contacts/contact-by-identity from)) removed-name (:name (contacts/contact-by-identity identity))] - (->> (str (or remover-name from) " removed " (or removed-name identity)) + (->> (str (or remover-name from) " " (t :removed) " " (or removed-name identity)) (system-message msg-id) (messages/save-message chat-id)))) (defn you-removed-from-group-msg [chat-id from msg-id] (let [remover-name (:name (contacts/contact-by-identity from))] - (->> (str (or remover-name from) " removed you from group chat") + (->> (str (or remover-name from) " " (t :protocol.removed-from-chat)) (system-message msg-id) (messages/save-message chat-id)))) (defn participant-left-group-msg [chat-id from msg-id] (let [left-name (:name (contacts/contact-by-identity from))] - (->> (str (or left-name from) " left") + (->> (str (or left-name from) " " (t :left)) (system-message msg-id) (messages/save-message chat-id)))) diff --git a/src/status_im/translations/en.cljs b/src/status_im/translations/en.cljs new file mode 100644 index 0000000000..66dbe07ae4 --- /dev/null +++ b/src/status_im/translations/en.cljs @@ -0,0 +1,99 @@ +(ns status-im.translations.en) + +(def translations + {:chat {:is-typing "is typing" + :and-you "and you" + + :search-chat "Search chat" + + :members {:one "1 member, 1 active" + :other "{{count}} members, {{count}} active"} + :last-active "Active a minute ago"} + :sign-up {:contacts-syncronized "Your contacts have been synchronized" + :confirmation-code (str "Thanks! We've sent you a text message with a confirmation " + "code. Please provide that code to confirm your phone number") + :password-saved (str "OK great! Your password has been saved. Just to let you " + "know you can always change it in the Console by the way " + "it's me the Console nice to meet you!") + :generate-passphrase (str "I'll generate a passphrase for you so you can restore your " + "access or log in from another device") + :passphrase "Here's your passphrase:" + :written-down "Make sure you had securely written it down" + :phone-number-required (str "Your phone number is also required to use the app. Type the " + "exclamation mark or hit the icon to open the command list " + "and choose the !phone command") + :intro-status (str "The brash businessman’s braggadocio " + "and public exchange with candidates " + "in the US presidential election") + :intro-message1 "Hello there! It's Status a Dapp browser in your phone." + :intro-message2 (str "Status1 uses a highly secure key-pair authentication type " + "to provide you a reliable way to access your account") + :keypair-generated (str "A key pair has been generated and saved to your device. " + "Create a password to secure your key")} + :chats {:title "Chats" + :new-chat "New Chat" + :new-group-chat "New Group Chat"} + :profile {:title "Profile" + :message "Message" + :username "Username" + :phone-number "Phone number" + :email "Email" + :report-user "REPORT USER"} + :settings {:title "Settings"} + :discovery {:title "Discovery" + :none "None" + :search-tags "Type your search tags here" + :popular-tags "Popular tags" + :recent "Recent"} + :contacts {:title "Contacts" + :no-name "Noname"} + :invite-friends {:title "Invite friends"} + :faq {:title "FAQ"} + :drawer {:switch-users "Switch users"} + :group-settings {:no-name "Noname" + :remove "Remove" + :save "Save" + :change-color "Change color" + :clear-history "Clear history" + :delete-and-leave "Delete and leave" + :chat-settings "Chat settings" + :edit "Edit" + :add-members "Add Members"} + :new-group {:title "New Group Chat" + :group-name "Group Name"} + :participants {:add "Add Participants" + :remove "Remove Participants"} + :commands {:money {:text "!money" + :description "Send money"} + :location {:text "!location" + :description "Send location"} + :phone {:text "!phone" + :description "Send phone number" + :request-text "Phone number request"} + :confirmation-code {:text "!confirmationCode" + :description "Send confirmation code" + :request-text "Confirmation code request"} + :send {:text "!send" + :description "Send location"} + :request {:text "!request" + :description "Send request"} + :keypair-password {:text "!keypair-password" + :description ""} + :help {:text "!help" + :description "Help"}} + :protocol {:received-invitation "received chat invitation" + :removed-from-chat "removed you from group chat"} + :colors {:blue "Blue" + :purple "Purple" + :green "Green" + :red "Red"} + :notifications {:title "Notifications and sounds"} + :not-implemented "!not implemented" + :chat-name "Chat name" + :members-title "Members" + :left "left" + :invited "invited" + :removed "removed" + :You "You" + :me "me" + :console "console"}) \ No newline at end of file