generated from PEZ/rn-rf-shadow
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlanguages_section.cljs
139 lines (118 loc) · 5.38 KB
/
languages_section.cljs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
(ns gurps.pages.character.info.widgets.languages-section
(:require [gurps.widgets.base :refer [view text button]]
[gurps.widgets.dropdown :refer [dropdown]]
[gurps.widgets.underlined-input :refer [underlined-input]]
[gurps.widgets.bracketed-numeric-input :refer [bracketed-numeric-input]]
[gurps.utils.i18n :as i18n]
[gurps.utils.debounce :refer [debounce-and-dispatch]]
["@expo/vector-icons/FontAwesome" :default icon]
["twrnc" :refer [style] :rename {style tw}]
[re-frame.core :as rf]
[clojure.string :as str]))
;; TODO: "written" skill may be less if TL is low (less than 3?)
;; TODO: dyslexia makes you illiterate ??
(def dropdown-data
[{:label (i18n/label :t/lang-lvl-native) :value "native"},
{:label (i18n/label :t/lang-lvl-accented) :value "accented"},
{:label (i18n/label :t/lang-lvl-broken) :value "broken"}])
(defn- row
[col1 col2 col3 col4 col5]
[:> view {:style (tw "flex flex-row grow gap-2 w-full h-6")}
[:> view {:style (tw "w-4/12")} col1]
col2
col3
col4
col5])
(defn- native-icon
[{:keys [i native?]}]
(let [color (-> (tw (if native? "text-black" "text-slate-400")) .-color)]
[:> button {:style (tw "items-center justify-center")
:onPress #(rf/dispatch [:languages/update, i, :native?, (not native?)])}
[:> icon {:style (tw "align-middle mt-1") :name "language" :size 20 :color color}]]))
(defn- get-lang-skill-label
[skill]
(->> dropdown-data
(filter #(= skill (:value %)))
first
:label))
(def ^:private lang-skill-cost {:native 3, :accented 2, :broken 1})
(defn- lang-cost
[{:keys [native? spoken written name]}]
(if (or native? (empty? name))
0
(+ ((keyword spoken) lang-skill-cost)
((keyword written) lang-skill-cost))))
(defn- language-row
[{:keys [name spoken written native?]} idx]
[row
;; language name underline (adds a "(Native)" to the right if native button is pressed)
[underlined-input {:val (str name (when (and native?
(not (str/includes? name (i18n/label :t/lang-lvl-native))))
(str " (" (i18n/label :t/lang-lvl-native) ")")))
:style (when native? (tw "text-slate-400"))
:disabled? native?
:on-change-text #(debounce-and-dispatch [:languages/update, idx, :name, %] 500)}]
;; spoken skill dropdown
^{:key (str idx "-spoken")}
[dropdown {:style (tw "flex-1")
:placeholder-style (tw "text-right text-xs")
:selected-style (tw "text-right text-xs")
:on-change #(rf/dispatch [:languages/update, idx, :spoken, %])
:placeholder (get-lang-skill-label spoken)
:disabled? native?
:data dropdown-data}]
;; written skill dropdown
^{:key (str idx "-written")}
[dropdown {:style (tw "flex-1")
:placeholder-style (tw "text-right text-xs")
:selected-style (tw "text-right text-xs")
:on-change #(rf/dispatch [:languages/update, idx, :written, %])
:placeholder (get-lang-skill-label written)
:disabled? native?
:data dropdown-data}]
;; turn native button
[native-icon {:i idx :native? native?}]
;; cost (0 if native) or not yet filled in
[bracketed-numeric-input {:max-length 2
:val (lang-cost {:native? native? :written written :spoken spoken :name name})
:editable? false}]])
(defn- header
[]
[row
[:> text {:style (tw "flex-1 font-bold")} (i18n/label :t/languages)]
[:> text {:style (tw "flex-1 text-center font-bold")} (i18n/label :t/lang-spoken)]
[:> text {:style (tw "flex-1 text-center font-bold")} (i18n/label :t/lang-written)]
[:> view {:style (tw "w-5")}]
[:> view {:style (tw "w-10")}]])
(def ^:private default-lang {:name "" :spoken "broken" :written "broken" :native? false})
(defn languages-section []
(let [languages (some-> (rf/subscribe [:languages]) deref)]
[:> view {:style (tw "flex flex-col gap-1")}
[header]
(map-indexed
(fn [idx lang]
^{:key (str idx "-lang")}
[language-row (conj lang {:i idx}) idx])
(conj languages default-lang))]))
(rf/reg-sub
:languages
(fn [db _]
(get-in db [:languages] [])))
(rf/reg-event-fx
:languages/update
(fn [{:keys [db]} [_ i k v]]
(let [existing-language (get-in db [:languages i] default-lang)
old-cost (lang-cost existing-language)
new-language (merge existing-language {k v})
new-db (assoc-in db [:languages i] (merge new-language {:cost (lang-cost new-language)}))
cost (get-in new-db [:languages i :cost])]
{:db new-db
:fx [[:dispatch [:profile.update/unspent-points (- cost old-cost)]]]
:effects.async-storage/set {:k :languages
:value (get-in new-db [:languages])}})))
(comment
(def a {:0 {:i 0 :name "a" :spoken "broken", :written "broken", :native? false, :cost 0}
:1 {:i 1 :name "" :spoken "broken", :written "broken", :native? false, :cost 0}})
(vec (sort-by :i (filter map? (apply concat (:languages gurps.db/app-db)))))
(def lang-array (vec (filter map? (apply concat a))))
(not-any? #(seq (:name %)) lang-array))