Copy link to clipboard.
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Oly 2023-08-10 14:35:50 +01:00
parent 47402cb1e2
commit d72019d6bb
6 changed files with 158 additions and 76 deletions

View File

@ -0,0 +1,8 @@
#+TITLE: About
#+DESCRIPTION: Examples mostly oriented around web development
* Introduction
This site has various example's guides and snippets showing how to use Clojure and ClojureScript, they are mainly based on my journey learning coming from JavaScript and python having no previous experience with java or the JVM.
Some of the struggles have been around Terminology & inter-op with the host languages along side re orientating my brain to think more functionally.

View File

@ -21,6 +21,13 @@
<meta property="og:site_name" content="SITE NAME" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"
integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<link
rel="stylesheet"
type="text/css"

View File

@ -0,0 +1,25 @@
(ns clojure-demo.components
(:require
[clojure-demo.state :refer [site-state]]
[clojure-demo.helpers :refer [copy->clipboard slugify]]))
(defn notification []
(if (-> @site-state :notification)
[:div.fixed.p-5.top-20.right-0.border-2.border-sky-400.bg-white.opacity-100.transition-opacity.delay-150.duration-200
(-> @site-state :notification)]
[:<>]))
(defn header-on-click-copy-link [v]
{:on-click (fn [] (copy->clipboard (slugify v)))})
(defn header-lvl1 [v _]
[:h1.text-2xl.fw6.lh-title.mt-0.mb-2 {:id (slugify v)}
[:a {:name (slugify v)} [:i.fa-solid.fa-link (header-on-click-copy-link v)] v]])
(defn header-lvl2 [v _]
[:h2.text-xl.fw6.lh-title.mt-0.mb-2 {:id (slugify v)}
[:a {:name (slugify v)} [:i.fa-solid.fa-link (header-on-click-copy-link v)] v]])
(defn header-lvl3 [v _]
[:h3.text-base.fw6.lh-title.mt-0.mb-2 {:id (slugify v)}
[:a {:name (slugify v)} [:i.fa-solid.fa-link (header-on-click-copy-link v)] v]])

View File

@ -8,16 +8,17 @@
["@nextjournal/lang-clojure" :refer [clojure]]
["react-dom/client" :refer [createRoot]]
["tarts" :as tarts]
[tick.core :as t]
[cljs.core.async :as async]
[cljs.core.async.interop :as async-in]
[shadow.cljs.modern :refer [js-await]]
[ajax.core :refer [GET raw-response-format]]
[cl-eorg.html :as h :refer [body headers org->replacements]]
[cl-eorg.parser :as o :refer [parse]]
[cl-eorg.themes.tachyon :refer [tachyon-theme]]
[clojure.string :as str]
[clojure-demo.components
:refer [header-lvl1 header-lvl2 header-lvl3 notification]]
[clojure-demo.helpers :refer [slugify]]
[clojure-demo.state :refer [site-state]]
[clojure-demo.tailwind-theme :refer [tailwind-theme]]
[clojure.data.xml :as xml]
[clojure.string :as str]
[honey.sql :as sql]
[honey.sql.helpers :as sqlh]
[reagent.core :as reagent]
@ -25,12 +26,12 @@
[reitit.frontend :as rf]
[reitit.frontend.easy :as rfe]
[reitit.frontend.history :refer [ignore-anchor-click?]]
[sci.configs.funcool.promesa :as sci-promesa]
[sci.configs.reagent.reagent :as sci-reagent]
[sci.configs.tonsky.datascript :as sci-datascript]
[sci.configs.funcool.promesa :as sci-promesa]
[sci.core :as sci]
[clojure-demo.tailwind-theme :refer [tailwind-theme]]
[spec-tools.data-spec :as ds]))
[spec-tools.data-spec :as ds]
[tick.core :as t]))
(def languages
{"clojure" {:mode "clojure"}
@ -41,7 +42,8 @@
(def yaml-mode (LanguageSupport. (.define StreamLanguage yaml)))
(defn ^:sci/macro my-js-await [_ _ [name thenable] & body]
(defn ^:sci/macro my-js-await
[_ _ [name thenable] & body]
(let [last-expr (last body)
[body catch]
(if (and (seq? last-expr) (= 'catch (first last-expr)))
@ -54,8 +56,7 @@
[`(.then (fn [~name] ~@body))])
~@(when catch
(let [[name & body] catch]
[`(.catch (fn [~name] ~@body))]
)))))
[`(.catch (fn [~name] ~@body))])))))
;; https://github.com/babashka/sci.configs
(def rf-ns (sci/create-ns 'reitit.frontend nil))
@ -112,14 +113,6 @@
;(def sci-ctx (sci/empty-environment))
(sci/alter-var-root sci/print-fn (constantly *print-fn*))
(defn slugify [s]
(when s
(str
(-> s
(str/lower-case)
(str/replace #"[^\w]+" "-")
(str/replace #"^-\\|-\\-$" "")))))
(defn fetch-selected-text
"Get the users selected text"
[updated-view transactions]
@ -208,9 +201,9 @@
(def theme-tachyon
(merge tachyon-theme
{:SRC code-editor
:HEADER1 (fn [v _] [:h1 {:id (slugify v)} [:a {:name (slugify v)} v]])
:HEADER2 (fn [v _] [:h2 {:id (slugify v)} [:a {:name (slugify v)} v]])
:HEADER3 (fn [v _] [:h2 {:id (slugify v)} [:a {:name (slugify v)} v]])
:HEADER1 header-lvl1 #_(fn [v _] [:h1 {:id (slugify v)} [:a {:name (slugify v)} v]])
:HEADER2 header-lvl2 #_(fn [v _] [:h2 {:id (slugify v)} [:a {:name (slugify v)} v]])
:HEADER3 header-lvl3 #_(fn [v _] [:h2 {:id (slugify v)} [:a {:name (slugify v)} v]])
:LINE :p.f5.f5-ns.lh-copy.mt0
:BULLETS :ul.mt0
:LINK :a #_link-handler}))
@ -218,9 +211,9 @@
(def theme
(merge tailwind-theme
{:SRC code-editor
:HEADER1 (fn [v _] [:h1.text-2xl.fw6.lh-title.mt-0.mb-2 {:id (slugify v)} [:a {:name (slugify v)} v]])
:HEADER2 (fn [v _] [:h2.text-xl.fw6.lh-title.mt-0.mb-2 {:id (slugify v)} [:a {:name (slugify v)} v]])
:HEADER3 (fn [v _] [:h2.text-base.lh-title.mt-0.mb-2 {:id (slugify v)} [:a {:name (slugify v)} v]])
:HEADER1 header-lvl1 #_(fn [v _] [:h1.text-2xl.fw6.lh-title.mt-0.mb-2 {:id (slugify v)} [:a {:name (slugify v)} v]])
:HEADER2 header-lvl2 #_(fn [v _] [:h2.text-xl.fw6.lh-title.mt-0.mb-2 {:id (slugify v)} [:a {:name (slugify v)} v]])
:HEADER3 header-lvl3 #_(fn [v _] [:h2.text-base.lh-title.mt-0.mb-2 {:id (slugify v)} [:a {:name (slugify v)} v]])
:LINE :p.f5.f5-ns.lh-copy.mt0
:BULLETS :ul.mt0
:LINK :a #_link-handler}))
@ -318,8 +311,7 @@
:icon-image "https://avatars.githubusercontent.com/u/2181346?s=200&v=4"}]}
:terminology {:title "Terminology"
:intro ""
:key ::terminology}
}
:key ::terminology}}
:demos
{:hiccup-dsl-demo
{:file "documents/hiccup-dsl-demo.org" :git-link "https://github.com/atomjuice/dsl-demo"}
@ -340,9 +332,6 @@
:containers
{:file "documents/containers.org" :git-link "https://github.com/atomjuice/containers"}}})
;; Store site state
(defonce site-state (reagent/atom {}))
;; form one component to render an article
(defn article [{:keys [title description tagline]}]
[:article.prose {:data-name "article-full-bleed-background"}
@ -420,7 +409,6 @@
:code (filter (fn filter-code [tag] (org-code (first tag))) dsl)
:body (filter (fn filter-body [tag] (body (first tag))) dsl)})
(defn home-page []
[:<>
[articles
@ -438,6 +426,8 @@
(defn grouped-page [route]
(let [group (keyword (name (:name (:data route))))]
(swap! site-state dissoc :notification)
(fn [route]
[:<>
[articles
{:title (-> site-data :pages group :title)
@ -448,9 +438,27 @@
:description (:description demo)
:link (rfe/href ::page {:page (:page demo)})
:img-src (:icon-image demo)})
(-> site-data :pages group :demos))}]]))
(-> site-data :pages group :demos))}]])))
(defn default-page [route]
(let [demo-key (keyword (-> route :parameters :path :page))
content (reagent/atom {})]
(GET (str "/" (-> site-data :demos demo-key :file))
{:response-format (raw-response-format)
:handler (fn [response]
(->> response
parse
org->split2
(reset! content)))})
(fn [route]
(if @content
[:main
[:h1.mt-8.mb-8.text-4xl (:content (last (first (:header @content))))]
[:div
(into [:div] (org->replacements theme (:body @content)))]]
[:<>]))))
(defn default-page-header [route]
(let [demo-key (keyword (-> route :parameters :path :page))
content (reagent/atom {})]
(GET (str "/" (-> site-data :demos demo-key :file))
@ -483,11 +491,10 @@
(into [:div] (org->replacements theme (:body @content)))]]
[:<>]))))
;; form one render about page component
(defn about-page []
[:div
[default-page {:parameters {:path {:page "about"}}}]
#_[:div
[:section.mw7.center.avenir
[:h1 "Clojure library examples to aid learning"]
[:p ""]
@ -504,7 +511,7 @@
["/page/:page"
{:name ::page
:view default-page
:view default-page-header
:parameters {:path {:page string?}
:query {(ds/opt :foo) keyword?}}}]
@ -530,21 +537,15 @@
["/about/"
{:name ::about
:view about-page}]
#_["/demo/:page"
{:name ::demo
:view demo-page
:parameters {:path {:page string?}
:query {(ds/opt :foo) keyword?}}}]])
:view about-page}]])
;; top level component contains nav and adds in the select page into a containing element
;; we are adding in a style sheet but this will often be done in index.html
(defn current-page []
[:div
[notification]
[navbar (concat
[{:href (rfe/href ::frontpage) :title "title here" :text "home" :key "homepage"}]
(mapv (fn build-nav [[key page]] {:href (rfe/href (:key page)) :text (:title page)}) (-> site-data :pages))
[;;{:href (rfe/href ::dsl) :text "DSL's" :key "dsl"}
{:title "Domain Specific Languages" :href (rfe/href ::about) :text "About" :key "about"}

View File

@ -0,0 +1,36 @@
(ns clojure-demo.helpers
(:require
[cljs.core.async :refer [go]]
[cljs.core.async.interop :refer [<p!]]
[clojure.string :as str]
[clojure-demo.state :refer [site-state]]))
(defn slugify [s]
(when s
(str
(-> s
(str/lower-case)
(str/replace #"[^\w]+" "-")
(str/replace #"^-\\|-\\-$" "")))))
(defn build-page-path [title]
(str "http://127.0.0.1:8080/" #_"https://clojure-demos.digitaloctave.com/" "page/"
(when (-> @site-state :current-route :parameters :path :page)
(-> @site-state :current-route :parameters :path :page))
"#" title)
)
(defn copy->clipboard
"Simple wrapper which copies text to the clipboard and resolves the promise"
[text]
(go (<p! (.writeText (.-clipboard js/navigator) (build-page-path text)))
(swap! site-state assoc :notification "Copied to clipboard")
(prn "copied")))
(comment
(.-writeText (.-clipboard js/navigator) "test")
(copy->clipboard "test2"))

View File

@ -0,0 +1,5 @@
(ns clojure-demo.state
(:require [reagent.core :as reagent]))
;; Store site state
(defonce site-state (reagent/atom {}))