Skip to content

Commit

Permalink
Communities
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobobryant committed Feb 10, 2024
1 parent 56f951a commit 60f42d5
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 25 deletions.
2 changes: 1 addition & 1 deletion resources/tailwind.css
Expand Up @@ -22,7 +22,7 @@

@layer components {
.btn {
@apply bg-blue-500 hover:bg-blue-700 text-center py-2 px-4 rounded disabled:opacity-50 text-white;
@apply bg-teal-600 hover:bg-teal-800 text-center py-2 px-4 disabled:opacity-50 text-white;
}
}

Expand Down
90 changes: 74 additions & 16 deletions src/com/eelchat/app.clj
Expand Up @@ -4,21 +4,79 @@
[com.eelchat.ui :as ui]
[xtdb.api :as xt]))

(defn app [{:keys [session biff/db] :as ctx}]
(let [{:user/keys [email]} (xt/entity db (:uid session))]
(ui/page
{}
[:div "Signed in as " email ". "
(biff/form
{:action "/auth/signout"
:class "inline"}
[:button.text-blue-500.hover:text-blue-800 {:type "submit"}
"Sign out"])
"."]
[:.h-6]
[:div "Thanks for joining the waitlist. "
"We'll let you know when eelchat is ready to use."])))
(defn app [ctx]
(ui/app-page
ctx
[:p "Select a community, or create a new one."]))

(defn new-community [{:keys [session] :as ctx}]
(let [community-id (random-uuid)]
(biff/submit-tx ctx
[{:db/doc-type :community
:xt/id community-id
:community/title (str "Community #" (rand-int 1000))}
{:db/doc-type :membership
:membership/user (:uid session)
:membership/community community-id
:membership/roles #{:admin}}])
{:status 303
:headers {"Location" (str "/community/" community-id)}}))

(defn join-community [{:keys [user community] :as ctx}]
(biff/submit-tx ctx
[{:db/doc-type :membership
:db.op/upsert {:membership/user (:xt/id user)
:membership/community (:xt/id community)}
:membership/roles [:db/default #{}]}])
{:status 303
:headers {"Location" (str "/community/" (:xt/id community))}})

(defn community [{:keys [biff/db path-params] :as ctx}]
(if (some? (xt/entity db (parse-uuid (:id path-params))))
(ui/app-page
ctx
[:.border.border-neutral-600.p-3.bg-white.grow
"Messages window"]
[:.h-3]
[:.border.border-neutral-600.p-3.h-28.bg-white
"Compose window"])
{:status 303
:headers {"location" "/app"}}))

(defn community [{:keys [biff/db user community] :as ctx}]
(let [member (some (fn [membership]
(= (:xt/id community) (get-in membership [:membership/community :xt/id])))
(:user/memberships user))]
(ui/app-page
ctx
(if member
[:<>
[:.border.border-neutral-600.p-3.bg-white.grow
"Messages window"]
[:.h-3]
[:.border.border-neutral-600.p-3.h-28.bg-white
"Compose window"]]
[:<>
[:.grow]
[:h1.text-3xl.text-center (:community/title community)]
[:.h-6]
(biff/form
{:action (str "/community/" (:xt/id community) "/join")
:class "flex justify-center"}
[:button.btn {:type "submit"} "Join this community"])
[:div {:class "grow-[1.75]"}]]))))

(defn wrap-community [handler]
(fn [{:keys [biff/db path-params] :as ctx}]
(if-some [community (xt/entity db (parse-uuid (:id path-params)))]
(handler (assoc ctx :community community))
{:status 303
:headers {"location" "/app"}})))

(def module
{:routes ["/app" {:middleware [mid/wrap-signed-in]}
["" {:get app}]]})
{:routes ["" {:middleware [mid/wrap-signed-in]}
["/app" {:get app}]
["/community" {:post new-community}]
["/community/:id" {:middleware [wrap-community]}
["" {:get community}]
["/join" {:post join-community}]]]})
14 changes: 9 additions & 5 deletions src/com/eelchat/middleware.clj
Expand Up @@ -2,7 +2,8 @@
(:require [com.biffweb :as biff]
[muuntaja.middleware :as muuntaja]
[ring.middleware.anti-forgery :as csrf]
[ring.middleware.defaults :as rd]))
[ring.middleware.defaults :as rd]
[xtdb.api :as xt]))

(defn wrap-redirect-signed-in [handler]
(fn [{:keys [session] :as ctx}]
Expand All @@ -12,11 +13,14 @@
(handler ctx))))

(defn wrap-signed-in [handler]
(fn [{:keys [session] :as ctx}]
(if (some? (:uid session))
(handler ctx)
(fn [{:keys [biff/db session] :as ctx}]
(if-some [user (xt/pull db
'[* {(:membership/_user {:as :user/memberships})
[* {:membership/community [*]}]}]
(:uid session))]
(handler (assoc ctx :user user))
{:status 303
:headers {"location" "/signin?error=not-signed-in"}})))
:headers {"location" "/?error=not-signed-in"}})))

;; Stick this function somewhere in your middleware stack below if you want to
;; inspect what things look like before/after certain middleware fns run.
Expand Down
32 changes: 29 additions & 3 deletions src/com/eelchat/schema.clj
Expand Up @@ -3,9 +3,35 @@
(def schema
{:user/id :uuid
:user [:map {:closed true}
[:xt/id :user/id]
[:user/email :string]
[:user/joined-at inst?]]})
[:xt/id :user/id]
[:user/email :string]
[:user/joined-at inst?]]

:community/id :uuid
:community [:map {:closed true}
[:xt/id :community/id]
[:community/title :string]]

:membership/id :uuid
:membership [:map {:closed true}
[:xt/id :membership/id]
[:membership/user :user/id]
[:membership/community :community/id]
[:membership/roles [:set [:enum :admin]]]]

:channel/id :uuid
:channel [:map {:closed true}
[:xt/id :channel/id]
[:channel/title :string]
[:channel/community :community/id]]

:message/id :uuid
:message [:map {:closed true}
[:xt/id :message/id]
[:message/membership :membership/id]
[:message/text :string]
[:message/channel :channel/id]
[:message/created-at inst?]]})

(def module
{:schema schema})
34 changes: 34 additions & 0 deletions src/com/eelchat/ui.clj
@@ -1,6 +1,7 @@
(ns com.eelchat.ui
(:require [cheshire.core :as cheshire]
[clojure.java.io :as io]
[clojure.string :as str]
[com.eelchat.settings :as settings]
[com.biffweb :as biff]
[ring.middleware.anti-forgery :as csrf]
Expand Down Expand Up @@ -74,3 +75,36 @@
(if (= status 404)
"Page not found."
"Something went wrong.")]))})

(defn app-page [{:keys [uri user] :as ctx} & body]
(base
ctx
[:.flex.bg-orange-50
[:.h-screen.w-80.p-3.pr-0.flex.flex-col.flex-grow
[:select
{:class '[text-sm
cursor-pointer
focus:border-teal-600
focus:ring-teal-600]
:onchange "window.location = this.value"}
[:option {:value "/app"}
"Select a community"]
(for [{:keys [membership/community]} (:user/memberships user)
:let [url (str "/community/" (:xt/id community))]]
[:option.cursor-pointer
{:value url
:selected (str/starts-with? uri url)}
(:community/title community)])]
[:.grow]
(biff/form
{:action "/community"}
[:button.btn.w-full {:type "submit"} "New community"])
[:.h-3]
[:.text-sm (:user/email user) " | "
(biff/form
{:action "/auth/signout"
:class "inline"}
[:button.text-teal-600.hover:text-teal-800 {:type "submit"}
"Sign out"])]]
[:.h-screen.w-full.p-3.flex.flex-col
body]]))

0 comments on commit 60f42d5

Please sign in to comment.