|
23 | 23 | {} |
24 | 24 | success)))) |
25 | 25 |
|
| 26 | +(defmethod ws/event-msg-handler :admin/fetch-ip-bans |
| 27 | + [{{success :success} :?data}] |
| 28 | + (when success |
| 29 | + (swap! users-state assoc :ip-banned success))) |
| 30 | + |
| 31 | +(defmethod ws/event-msg-handler :admin/look-up-ip |
| 32 | + [{{:keys [error success]} :?data}] |
| 33 | + (if success |
| 34 | + (let [{:keys [username last-ip-address]} success] |
| 35 | + (prn "success: " success) |
| 36 | + (swap! users-state assoc :ip-lookup-name username :ip-lookup-result last-ip-address)) |
| 37 | + (non-game-toast error nil))) |
| 38 | + |
| 39 | +(defmethod ws/event-msg-handler :admin/ip-ban-user |
| 40 | + [{{:keys [error success]} :?data}] |
| 41 | + (if success |
| 42 | + (let [{:keys [username ip-address]} success] |
| 43 | + (swap! users-state update :ip-banned conj {:username username :ip-address ip-address})) |
| 44 | + (non-game-toast error nil))) |
| 45 | + |
| 46 | +(defmethod ws/event-msg-handler :admin/ip-unban-user |
| 47 | + [{{:keys [error success]} :?data}] |
| 48 | + (if success |
| 49 | + (let [{:keys [username ip-address]} success] |
| 50 | + (swap! users-state update :ip-banned #(filterv (fn [m] (not= username (:username m))) %))) |
| 51 | + (non-game-toast error nil))) |
| 52 | + |
26 | 53 | (defmethod ws/event-msg-handler :admin/user-edit |
27 | 54 | [{{:keys [error success]} :?data}] |
28 | 55 | (cond |
|
70 | 97 | "Remove"]] |
71 | 98 | [:span.title (:username d "")]]))]]) |
72 | 99 |
|
| 100 | +(defn- ip-bans-list [users] |
| 101 | + ;; here it's a list of {:username ... :address ...} |
| 102 | + [:div.users-box.panel.blue-shade |
| 103 | + [:ul.list |
| 104 | + (doall |
| 105 | + (for [d (sort-by #(str/lower-case (:username %)) @users)] |
| 106 | + [:li.users-item |
| 107 | + {:key (:username d)} |
| 108 | + [:span |
| 109 | + [:button.delete |
| 110 | + {:on-click #(ws/ws-send! [:admin/ip-unban-user {:username (:username d)}])} |
| 111 | + "Remove"]] |
| 112 | + [:span.title (:username d "") " - " (:ip-address d)]]))]]) |
| 113 | + |
| 114 | +(defn- ip-ban-user-add [state state-key] |
| 115 | + [:form.msg-box {:on-submit #(let [username (state-key @state "")] |
| 116 | + (.preventDefault %) |
| 117 | + (when-not (str/blank? username) |
| 118 | + (ws/ws-send! [:admin/ip-ban-user {:username username}]) |
| 119 | + (swap! state assoc state-key "")))} |
| 120 | + [:input {:type "text" |
| 121 | + :placeholder "Type username" |
| 122 | + :value (state-key @state "") |
| 123 | + :on-change #(swap! state assoc state-key (-> % .-target .-value))}] |
| 124 | + (let [username (state-key @state "") |
| 125 | + disabled (str/blank? username)] |
| 126 | + [:button {:disabled disabled |
| 127 | + :class (if disabled "disabled" "")} |
| 128 | + "IP Ban User"])]) |
| 129 | + |
73 | 130 | (defn- user-add [state state-key add-fn] |
74 | 131 | [:form.msg-box {:on-submit #(let [username (state-key @state "")] |
75 | 132 | (.preventDefault %) |
|
86 | 143 | :class (if disabled "disabled" "")} |
87 | 144 | "Add"])]) |
88 | 145 |
|
| 146 | +(defn- ip-lookup-box [state state-key] |
| 147 | + (fn [] |
| 148 | + [:form.msg-box {:on-submit #(let [username (state-key @state "")] |
| 149 | + (.preventDefault %) |
| 150 | + (when-not (str/blank? username) |
| 151 | + (ws/ws-send! [:admin/look-up-ip {:username username}])))} |
| 152 | + [:input {:type "text" |
| 153 | + :placeholder "Type username" |
| 154 | + :value (state-key @state "") |
| 155 | + :on-change #(swap! state assoc state-key (-> % .-target .-value))}] |
| 156 | + [:input {:type "text" |
| 157 | + :read-only true |
| 158 | + :value (:ip-lookup-result @state "") |
| 159 | + :placeholder "Look up an IP"}] |
| 160 | + (let [username (state-key @state "") |
| 161 | + disabled (str/blank? username)] |
| 162 | + [:button {:disabled disabled |
| 163 | + :class (if disabled "disabled" "")} |
| 164 | + "Search"])])) |
| 165 | + |
| 166 | + |
| 167 | + |
| 168 | + |
89 | 169 | (defn users-container [] |
90 | 170 | (r/with-let [mods (r/cursor users-state [:mods]) |
91 | 171 | specials (r/cursor users-state [:specials]) |
92 | 172 | tos (r/cursor users-state [:tos]) |
93 | | - banned (r/cursor users-state [:banned])] |
| 173 | + banned (r/cursor users-state [:banned]) |
| 174 | + ip-bans (r/cursor users-state [:ip-banned])] |
94 | 175 | (let [s (r/atom {}) |
95 | 176 | rows [{:h3 "Moderators" |
96 | 177 | :cursor mods |
|
109 | 190 | :key :banned |
110 | 191 | :h4 "Ban user"}]] |
111 | 192 | (fn [] |
112 | | - (into [:div.container.panel.blue-shade.content-page] |
113 | | - (->> (for [row rows] |
114 | | - [[:h3 (:h3 row)] |
115 | | - (users-list (:cursor row) (remove-user (:key row))) |
116 | | - [:h4 (:h4 row)] |
117 | | - (user-add s (:key row) (add-user (:key row)))]) |
118 | | - (interpose [[:br]]) |
119 | | - (mapcat identity) |
120 | | - (map-indexed (fn [idx itm] ^{:key idx} itm)))))))) |
| 193 | + [:div.container.panel.blue-shade.content-page |
| 194 | + (into [:div] |
| 195 | + (->> (for [{:keys [h3 cursor key h4] :as row} rows] |
| 196 | + ;; (if (= key :ip-bans) |
| 197 | + ;; [[:h3 (:h3 row)] |
| 198 | + [[:h3 h3] |
| 199 | + (users-list cursor (remove-user key)) |
| 200 | + [:h4 h4] |
| 201 | + (user-add s key (add-user key))]) |
| 202 | + (interpose [[:br]]) |
| 203 | + (mapcat identity) |
| 204 | + (map-indexed (fn [idx itm] ^{:key idx} itm)))) |
| 205 | + [:br] |
| 206 | + [:h3 "IP Lookup"] |
| 207 | + [ip-lookup-box users-state :ip-lookup-name] |
| 208 | + [:br] |
| 209 | + [:h3 "Ip Bans"] |
| 210 | + [ip-bans-list ip-bans] |
| 211 | + [ip-ban-user-add users-state :ip-ban-name]])))) |
121 | 212 |
|
122 | 213 | (defn users [] |
123 | 214 | (r/with-let [user (r/cursor app-state [:user])] |
124 | 215 | (ws/ws-send! [:admin/fetch-users]) |
| 216 | + (ws/ws-send! [:admin/fetch-ip-bans]) |
125 | 217 | [:div.page-container |
126 | 218 | [:div.account-bg] |
127 | 219 | (when (or (:isadmin @user) (:ismoderator @user)) |
|
0 commit comments