Refactor movement code to be more generic and easier to test.
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Oliver 2026-03-25 13:36:19 +00:00
parent eed0874c2d
commit 0232946798
16 changed files with 422 additions and 209 deletions

View File

@ -19,8 +19,8 @@
:aliases {:dev {:extra-paths
["components/ui-hiccup/src"]
:extra-deps {thheller/shadow-cljs {:mvn/version "2.25.2"}
cider/cider-nrepl {:mvn/version "0.50.2"}
refactor-nrepl/refactor-nrepl {:mvn/version "3.10.0"}
cider/cider-nrepl {:mvn/version "0.58.0"}
refactor-nrepl/refactor-nrepl {:mvn/version "3.11.3"}
cider/piggieback {:mvn/version "0.5.3"}}}
:test {:extra-paths ["test"]

View File

@ -135,8 +135,8 @@
(let [search (r/atom "")]
(fn [{:keys [sidebar body]}]
[:div.h-100.flex.items-stretch
[:div.dn.db-l.pa3.bg-blue {:style {:flex-basis "20rem" :flex-grow "1"}} sidebar]
[:div.ma3.pa3 {:style {:flex-basis "0" :flex-grow "999"}}
#_[:div.dn.db-l.pa3.bg-blue {:style {:flex-basis "20rem" :flex-grow "1"}} sidebar]
#_[:div.ma3.pa3 {:style {:flex-basis "0" :flex-grow "999"}}
[ui-search search]
body]])))

View File

@ -0,0 +1,47 @@
(ns com.oly.static-sites.do-blog.pages.chess.board)
(defn calculate-black-white [pos]
(if (even? (first pos))
(if (even? (second pos))
:black :white)
(if (even? (second pos))
:white :black)))
(defn square-defaults [pos]
{:piece {}
:bg-colour (name (calculate-black-white pos))})
(defn create-board-data [size]
(loop [x-pos 1
y-pos 1
result []]
(if (> y-pos size) #_(and (= x-pos size))
result
(if (= size x-pos)
(recur 1
(inc y-pos)
(conj result [x-pos y-pos]))
(recur (inc x-pos)
y-pos
(conj result [x-pos y-pos]))))))
(defn create-board-data-map
([size] (create-board-data-map size square-defaults))
([size square-defaults-map]
(->> (create-board-data size)
(mapv #(vector % (square-defaults-map %)))
(into {}))))
(defn merge-board-piece
"Merge in piece changes at position"
[board position piece]
(update board position update :piece merge piece))
(comment
(create-board-data 5)
(create-board-data-map 5)
(-> (create-board-data-map 5)
(update-board-piece [1 1] {:type :pawn}))
)

View File

@ -1,4 +1,6 @@
(ns com.oly.static-sites.do-blog.pages.chess.movement)
(ns com.oly.static-sites.do-blog.pages.chess.movement
(:require
[cljs.test :refer [deftest]]))
(defn get-square [pos game-state]
(get game-state pos {}))
@ -7,62 +9,86 @@
[( + 1 (first (keep-indexed #(when (= (first chars) %2) %1) [\A \B "C" \D \E \F \G \H])))
(js/parseInt (second chars))])
(defn inside-grid-edge?
"Return true if x and y are inside the grid"
[size x y]
(let [board-size (+ 1 size)]
(and (and (< x board-size) (< y board-size))
(and (> x -1) (> y -1)))))
(defn outside-grid-edge?
"Return true if x and y are outside the grid"
[size x y]
(not (inside-grid-edge? size x y)))
(defn edge?
"Return true if x and are inside the grid"
"Return true if x and y are inside the grid"
[[distance x y]]
(if (or (nil? distance) (= distance 1))
true
(and (and (< x 9) (< y 9))
(and (> x 0) (> y 0)))))
(defn opposite-piece? [src-pos dest-pos board]
(prn (str "opposite piece" dest-pos))
(defn opposite-piece?
"Check the board for a piece, and check its a different colour"
[src-pos dest-pos board]
(and (-> (get board dest-pos) :piece :type some?)
(not= (-> (get board src-pos) :piece :colour)
(-> (get board dest-pos) :piece :colour))))
(defn piece?
(defn piece-at-destination?
"Is the destination spot a piece or empty square ?"
[src-pos dest-pos board]
(prn (str "piece" dest-pos))
(-> (get board dest-pos) :piece :type some?))
(defn end-seq? [s]
(defn end-seq?
"Check if its an empty sequence or the sequence has ended with a nil"
[s]
(if (empty? s)
false
(nil? (last s))))
(defn identity-step [value _] value)
(defn line-step
"Given if the move to the next position is valid"
[board size step x1 y1 x2 y2 cords]
(prn "1")
(if (outside-grid-edge? size x2 y2) #_(and
(piece-at-destination? [x1 y1] [x2 y2] board))
(do (prn "2") (conj cords nil))
(if (opposite-piece? [x1 y1] [x2 y2] board)
(do (prn "4") (conj cords nil))
(do (prn "3") (conj cords [step x2 y2]))
)))
(defn line-move
"Use the same function for horizontal vertical and diagonals
We can abstract this because all the change is which axes we calculate on
We can abstract this because all that change's is which axes we calculate on
Just adjust the x1-fn x2-fn y1-fn y2-fn fn's"
[[x y] size x1-fn y1-fn x2-fn y2-fn board]
(prn "line-move")
(prn "move")
(loop [step 1
cords-set-one []
cords-set-two []]
;; nil at end of list indicates end of valid moves
(prn (concat
cords-set-one
cords-set-two))
(if (and (end-seq? cords-set-one)
(end-seq? cords-set-two))
(concat cords-set-one cords-set-two)
(concat
(drop-last cords-set-one)
(drop-last cords-set-two))
(recur (+ step 1)
(if (end-seq? cords-set-one)
cords-set-one
(if (and (edge? [step (x1-fn x step) (y1-fn y step)])
(piece? [x y] [(x1-fn x step) (y1-fn y step)] board))
(conj cords-set-one [step (x1-fn x step) (y1-fn y step)])
(conj cords-set-one
(when (opposite-piece? [x y] [(x1-fn x step) (y1-fn y step)] board)
[(x1-fn x step) (y1-fn y step)] nil) nil)))
(line-step board size step x y (x1-fn x step) (y1-fn x step) cords-set-one))
(if (end-seq? cords-set-two)
cords-set-two
(if (and (edge? [step (x2-fn x step) (y2-fn y step)])
(piece? [x y] [(x2-fn x step) (y2-fn y step)] board))
(conj cords-set-two [step (x2-fn x step) (y2-fn y step)])
(conj cords-set-two nil)))))))
(line-step board size step x y (x2-fn x step) (y2-fn x step) cords-set-two)
)))))
(defn line-horizontal [[x y] size board]
(prn "horizontal")
@ -126,21 +152,14 @@
[0 (- x 1) (- y 1)] [0 x (- y 1)] [0 (+ 1 x) (- y 1)]])
(defn pawn-projection [[x y] direction size board]
(prn "pawn diagonal")
(prn (piece? [x y] [(+ x 1) (+ y direction)] board))
(prn (piece? [x y] [(- x 1) (+ y direction)] board))
#_(piece? [x y] [(+ x direction) y] board)
(prn (concat [(when (piece? [x y] [(+ x 1) (+ y direction)] board) [0 (+ x 1) (+ y direction)])
(when (piece? [x y] [(- x 1) (+ y direction)] board) [0 (- x 1) (+ y direction)])]
(concat [(when (opposite-piece? [x y] [(+ x 1) (+ y direction)] board)
[0 (+ x 1) (+ y direction)])
(when (opposite-piece? [x y] [(- x 1) (+ y direction)] board)
[0 (- x 1) (+ y direction)])]
(if (or (= y 2) (= y 7))
[[0 x (+ y direction)] [1 x (+ y (* 2 direction))]]
[[0 x (+ y direction)]])))
(concat [(when (opposite-piece? [x y] [(+ x 1) (+ y direction)] board) [0 (+ x 1) (+ y direction)])
(when (opposite-piece? [x y] [(- x 1) (+ y direction)] board) [0 (- x 1) (+ y direction)])]
(if (or (= y 2) (= y 7))
[[0 x (+ y direction)] [1 x (+ y (* 2 direction))]]
[[0 x (+ y direction)]])))
(defn fetch-selected-piece-moves [[pos {:keys [piece]}] game-state]
(case (:type piece)

View File

@ -1,14 +1,12 @@
(ns com.oly.static-sites.do-blog.pages.chess.render
(:require
[com.oly.static-sites.do-blog.pages.chess.state :refer [game-state white-square black-square]]
[com.oly.static-sites.do-blog.pages.chess.movement :refer [fetch-selected-piece-moves]]))
(defn calculate-black-white [pos]
(if (even? (first pos))
(if (even? (second pos))
:black :white)
(if (even? (second pos))
:white :black)))
[com.oly.static-sites.do-blog.pages.chess.board
:refer [calculate-black-white create-board-data-map]]
[com.oly.static-sites.do-blog.pages.chess.movement
:refer [fetch-selected-piece-moves]]
[com.oly.static-sites.do-blog.pages.chess.state
:refer
[black-square game-state white-square]]))
(defn draw-square [pos pieces]
(let [square (calculate-black-white pos)
@ -31,34 +29,8 @@
"black-80"
"white-80")))))
(defn draw-board [pieces]
(loop [x 1
y 1
result []]
(if (>= x 8)
(if (>= y 8)
(conj result (draw-square [x y] pieces))
(recur 1 (+ 1 y) (conj result (draw-square [x y] pieces))))
(recur (+ 1 x) y (conj result (draw-square [x y] pieces))))))
(defn board-test [size]
(loop [x-pos 1
y-pos 1
result []]
(if (and (= x-pos size) (= y-pos size))
result
(if (= size x-pos)
(recur 1
(inc y-pos)
(conj result [x-pos y-pos]))
(recur (inc x-pos)
y-pos
(conj result [x-pos y-pos]))))))
(defn create-board [size square-defaults]
(->> (board-test size)
(mapv #(vector % (square-defaults %)) )
(into {})))
(create-board-data-map size square-defaults))
(defn enhance-board [board on-click-fn]
(reduce-kv
@ -85,3 +57,6 @@
(str (if (= :white (:colour piece)) " white " " black")))}))))
board
pieces))
(comment (create-board 5))

View File

@ -1,15 +1,15 @@
(ns com.oly.static-sites.do-blog.pages.chess-board
(:require
[com.oly.static-sites.do-blog.pages.chess.board
:refer [square-defaults]]
[com.oly.static-sites.do-blog.pages.chess.movement
:refer [fetch-selected-piece-moves valid-move? chess-pos->coords ]]
:refer [chess-pos->coords fetch-selected-piece-moves valid-move?]]
[com.oly.static-sites.do-blog.pages.chess.render
:refer [calculate-black-white create-board enhance-board place-pieces-on-board]]
[com.oly.static-sites.do-blog.pages.chess.state :refer [game-state start-state translate-char->piece find-piece]]
[com.oly.static-sites.do-blog.pages.chess.vstate :as v :refer [viking-start-state]]
[com.oly.static-sites.ui-hiccup.interface :refer [board]]
[reagent.core :as r]))
:refer [create-board enhance-board place-pieces-on-board]]
[com.oly.static-sites.do-blog.pages.chess.state
:refer [find-piece game-state start-state translate-char->piece]]
[com.oly.static-sites.do-blog.pages.chess.vstate :as v]
[com.oly.static-sites.ui-hiccup.interface :refer [board]]))
;;/addwidget https://blog-test.digitaloctave.com/chess?widgetId=dochess
;;/addwidget https://blog-test.digitaloctave.com/chess?roomI=!YOyzcCyoomnjylcOFP:matrix.org&widgetId=dochess
@ -55,7 +55,8 @@
(defn site-startup []
(prn "site start up")
(.addEventListener js/window "message"
;; experiment in matrix widget api
#_(.addEventListener js/window "message"
(fn [event]
(prn "message from element ")
(.log js/console event)
@ -73,6 +74,7 @@
(prn "sending capabilities")
(swap! widget assoc :widget-id (aget event "data" "widgetId"))
(send-to-parent "capabilities" :capabilities #js ["m.capability.screenshot"]))
"notify_capabilities"
(do
(send-to-parent "capabilities" :capabilities #js ["m.capability.screenshot"]))
@ -133,61 +135,52 @@
(defonce test-event (setup))
(defn square-defaults [pos]
{:piece {}
:bg-colour (name (calculate-black-white pos))
#_(if (= (calculate-black-white pos) :black)
"bg-slate-200 black-80"
"bg-slate-800 white-80")})
(defn board-test [size]
(loop [x-pos 1
y-pos 1
result []]
(if (and (= x-pos size) (= y-pos size))
result
(if (= size x-pos)
(recur 1
(inc y-pos)
(conj result [x-pos y-pos]))
(recur (inc x-pos)
y-pos
(conj result [x-pos y-pos]))))))
(defn get-square [pos]
(get @game-state [:board pos] {}))
(defn get-square [board-state pos]
(get @board-state [:board pos] {}))
(defn reset-square
([board pos] (reset-square board pos (square-defaults pos)))
([board pos value]
(swap! board assoc-in [:board pos] value)))
([board-state pos value]
(prn "reset")
(prn pos)
(swap! board-state assoc-in [:board pos] value)))
(defn update-square [pos value]
(defn update-square
([pos value] (update-square game-state pos value))
([board-state pos value]
(prn (str "update square " pos " " value))
(swap! game-state update-in [:board pos]
merge #_(get-in @game-state [:board pos] {})
value))
(swap! board-state update-in [:board pos]
merge
value)))
(defn collisions [positions]
(defn collisions [board-state positions]
(filterv (fn [[distance x y]]
(let [piece (get-square [x y])]
(let [piece (get-square board-state [x y])]
(prn (str "collision = " [x y] " - " (:type piece) " - " (:colour piece)))
(and (nil? (:type piece))
(nil? (:colour piece))))) positions))
(defn highlight-moves [pos]
(prn "highlight")
(prn (fetch-selected-piece-moves
(first (filter (fn [[k v]] (:selected v)) (-> @game-state :board)))
(-> @game-state :board)))
(defn highlight-moves
([pos] (highlight-moves pos game-state))
([pos board-state]
(prn "highlight moves")
(->> (fetch-selected-piece-moves
(first (filter (fn [[k v]] (:selected v)) (-> @game-state :board)))
(-> @game-state :board))
(first (filter (fn [[k v]] (:selected v)) (-> @board-state :board)))
(-> @board-state :board))
(mapv (fn [[distance x y]]
(update-square
board-state
[x y]
{:highlight (str " bg-green-" (+ 2 distance) "00 ")
:pos [x y]})))))
{:highlight
(case (+ 2 distance)
2 (str " bg-green-200 ")
3 (str " bg-green-300 ")
4 (str " bg-green-400 ")
5 (str " bg-green-500 ")
6 (str " bg-green-600 ")
7 (str " bg-green-700 ")
8 (str " bg-green-800 "))
:pos [x y]}))))))
(defn clear-keys [key]
(swap! game-state
@ -225,37 +218,46 @@
(-> @game-state :player-two)))
(defn move-piece
[selected-piece dest-square]
([selected-piece dest-square] (move-piece game-state selected-piece dest-square))
([board-state selected-piece dest-square]
;; check the colours don't match can't land on our own piece
(if (piece-attribute-match? selected-piece dest-square :colour)
nil
(when
(valid-move? (:pos dest-square) (-> @game-state :board))
(valid-move? (:pos dest-square) (-> @board-state :board))
(prn "--------------")
(switch-player)
(when (take-piece? selected-piece dest-square)
(prn (str "taking " dest-square))
(prn (str "taking " (:colour dest-square)))
(swap! game-state update (if (= :white (:colour selected-piece)) :player-one :player-two) conj dest-square))
(swap! board-state update (if (= :white (:colour selected-piece)) :player-one :player-two) conj dest-square))
(prn "#####")
(update-square (:pos dest-square) (merge dest-square {:piece (assoc selected-piece :pos (:pos dest-square))}))
(reset-square game-state (:pos selected-piece) (square-defaults (:pos selected-piece))))))
(update-square
(:pos dest-square)
(merge dest-square {:piece (assoc selected-piece :pos (:pos dest-square))}))
(reset-square board-state
(:pos selected-piece)
(square-defaults (:pos selected-piece)))))))
(defn click-square [evt p]
(let [[selected-pos {selected-piece :piece} #_selected-piece] (get-selected-square)
(defn click-square
([evt p] (click-square game-state evt p))
([board-state evt p]
(prn @game-state)
(let [[selected-pos {selected-piece :piece}] (get-selected-square)
clicked-square p]
(prn "click square")
(clear-keys :highlight)
(when (piece-attribute-match? (current-player) selected-piece :colour)
(when selected-pos
(prn "previously selected piece")
(move-piece selected-piece clicked-square)))
(move-piece board-state selected-piece clicked-square)))
(clear-keys :selected)
(clear-keys :highlight)
;; set new square as selected
(update-square (:pos p) (assoc (get-square (:pos p)) :selected true))
(highlight-moves (:pos p))))
(update-square board-state (:pos p) (assoc (get-square board-state (:pos p)) :selected true))
(highlight-moves (:pos p) board-state))))
(defonce viking-chess-board-setup
(reset! v/game-state
@ -267,8 +269,8 @@
:selected false}
:board
(-> (create-board 11 square-defaults)
(enhance-board click-square)
(place-pieces-on-board v/viking-start-state click-square))}))
(enhance-board (partial click-square @game-state))
(place-pieces-on-board v/viking-start-state (partial click-square @game-state)))}))
(defn chess-board-setup [start-state]
(reset! game-state
@ -284,11 +286,6 @@
(place-pieces-on-board start-state click-square))}))
(defn chess-page [{:keys [path-params query-params] :as route}]
(prn route)
(prn (:pieces query-params))
(prn start-state)
(prn (chars->map (:pieces query-params)))
(if (:pieces query-params)
(chess-board-setup (chars->map (:pieces query-params)))
(chess-board-setup start-state))
@ -315,6 +312,9 @@
[:div (board 11 (-> @v/game-state :board))]]))
(comment
(board-test 5)
(board 5 (-> @game-state :board))
(get-selected-square)
@game-state)

View File

@ -30,12 +30,16 @@
[(get-else $ ?e :thumbnail :nil) ?thumbnail]
[?e :relative-path ?path]]})
(defn check-match [re-patt title]
(prn re-patt)
(prn title)
(re-find re-patt title))
(defn db-search-filter
"Add where clauses to the datalog query when supplied"
[{:keys [search tag]}]
(let [re-search (if (not (str/blank? search)) #_(js/RegEx (str "(?i)" search))
(re-pattern (str "(?i)" search)) nil)]
(prn re-search)
(cond-> db-search
(not (str/blank? tag))
(update-in [:where] #(conj % ['?e :tags tag]))

View File

@ -0,0 +1,2 @@
(ns com.oly.static-sites.portfolio.chess)

View File

@ -18,7 +18,7 @@
y-pos 1
row [:div.h-8.md:h-12.lg:h-24]
result [:div]]
(if (and (= size (- y-pos 1)) (= size x-pos))
(if (> y-pos size )
result
(if (= size x-pos)
(recur 1

View File

@ -1,28 +1,28 @@
{:paths ["development/src" "bases/portfolio/src" "bases/do-blog/src"]
:deps {cjohansen/dumdom {:mvn/version "2023.11.06"}
org.clojure/clojurescript {:mvn/version "1.11.60"}
no.cjohansen/portfolio {:mvn/version "2023.07.15"}}
org.clojure/clojurescript {:mvn/version "1.12.134"}
no.cjohansen/portfolio {:mvn/version "2026.03.1"}}
:aliases {:dev {:extra-paths ["development/src" "bases/portfolio/src" "bases/do-blog/src"]
:extra-deps {org.clojure/clojure {:mvn/version "1.10.3"}
org.clojure/clojurescript {:mvn/version "1.11.60"}
org.clojure/clojurescript {:mvn/version "1.12.134"}
org.clojure/tools.deps.alpha {:mvn/version "0.12.1003"}
cljs-ajax/cljs-ajax {:mvn/version "0.8.4"}
;; dev libraries
thheller/shadow-cljs {:mvn/version "2.25.2"}
thheller/shadow-cljs {:mvn/version "3.3.6"}
;;refactor-nrepl/refactor-nrepl {:mvn/version "3.9.0"}
;;cider/cider-nrepl {:mvn/version "0.43.1"}
no.cjohansen/portfolio {:mvn/version "2023.07.15"}
no.cjohansen/portfolio {:mvn/version "2026.03.1"}
djblue/portal {:mvn/version "0.48.0"}}}
:blog {:extra-paths ["components/ui-hiccup/src"
"development/src" "bases/do-blog/src"]
"development/src" "bases/do-blog/src"
"bases/do-blog/test"]
:extra-deps {
org.clojure/core.async {:mvn/version "1.6.673"}
org.clojure/clojurescript {:mvn/version "1.11.60"}
org.clojure/clojurescript {:mvn/version "1.12.134"}
reagent/reagent {:mvn/version "1.1.1"}
tick/tick {:mvn/version "0.5.0"}
@ -40,9 +40,9 @@
:shadow-cljs-run
{:extra-deps {thheller/shadow-cljs {:mvn/version "2.25.2"}
cider/cider-nrepl {:mvn/version "0.50.2"}
refactor-nrepl/refactor-nrepl {:mvn/version "3.10.0"}
{:extra-deps {thheller/shadow-cljs {:mvn/version "3.3.6"}
cider/cider-nrepl {:mvn/version "0.58.0"}
refactor-nrepl/refactor-nrepl {:mvn/version "3.11.0"}
cider/piggieback {:mvn/version "0.5.3"}}
:extra-paths ["dev" "bases/do-blog/src" "components/ui_hiccup/src"]
:main-opts ["-m" "shadow.cljs.devtools.cli"]}

View File

@ -546,35 +546,59 @@ video {
@tailwind forms;
.\!container {
width: 100% !important;
}
.container {
width: 100%;
}
@media (min-width: 640px) {
.\!container {
max-width: 640px !important;
}
.container {
max-width: 640px;
}
}
@media (min-width: 768px) {
.\!container {
max-width: 768px !important;
}
.container {
max-width: 768px;
}
}
@media (min-width: 1024px) {
.\!container {
max-width: 1024px !important;
}
.container {
max-width: 1024px;
}
}
@media (min-width: 1280px) {
.\!container {
max-width: 1280px !important;
}
.container {
max-width: 1280px;
}
}
@media (min-width: 1536px) {
.\!container {
max-width: 1536px !important;
}
.container {
max-width: 1536px;
}
@ -604,6 +628,14 @@ video {
position: relative;
}
.order-1 {
order: 1;
}
.order-2 {
order: 2;
}
.m-2 {
margin: 0.5rem;
}
@ -652,6 +684,10 @@ video {
margin-right: 2rem;
}
.mt-0 {
margin-top: 0px;
}
.mt-4 {
margin-top: 1rem;
}
@ -676,6 +712,10 @@ video {
display: flex;
}
.inline-flex {
display: inline-flex;
}
.table {
display: table;
}
@ -704,6 +744,10 @@ video {
height: 16rem;
}
.h-8 {
height: 2rem;
}
.h-96 {
height: 24rem;
}
@ -720,6 +764,10 @@ video {
width: 12rem;
}
.w-8 {
width: 2rem;
}
.w-96 {
width: 24rem;
}
@ -740,6 +788,10 @@ video {
flex-grow: 1;
}
.grow {
flex-grow: 1;
}
.skew-x-12 {
--tw-skew-x: 12deg;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
@ -769,16 +821,40 @@ video {
flex-direction: column;
}
.flex-wrap {
flex-wrap: wrap;
}
.items-center {
align-items: center;
}
.items-stretch {
align-items: stretch;
}
.justify-around {
justify-content: space-around;
}
.gap-4 {
gap: 1rem;
}
.overflow-auto {
overflow: auto;
}
.truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.rounded {
border-radius: 0.25rem;
}
.rounded-full {
border-radius: 9999px;
}
@ -800,6 +876,11 @@ video {
border-color: rgb(15 23 42 / var(--tw-border-opacity));
}
.bg-black {
--tw-bg-opacity: 1;
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
}
.bg-slate-200 {
--tw-bg-opacity: 1;
background-color: rgb(226 232 240 / var(--tw-bg-opacity));
@ -810,6 +891,46 @@ video {
background-color: rgb(148 163 184 / var(--tw-bg-opacity));
}
.bg-white {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.bg-green-200 {
--tw-bg-opacity: 1;
background-color: rgb(187 247 208 / var(--tw-bg-opacity));
}
.bg-green-300 {
--tw-bg-opacity: 1;
background-color: rgb(134 239 172 / var(--tw-bg-opacity));
}
.bg-green-400 {
--tw-bg-opacity: 1;
background-color: rgb(74 222 128 / var(--tw-bg-opacity));
}
.bg-green-500 {
--tw-bg-opacity: 1;
background-color: rgb(34 197 94 / var(--tw-bg-opacity));
}
.bg-green-600 {
--tw-bg-opacity: 1;
background-color: rgb(22 163 74 / var(--tw-bg-opacity));
}
.bg-green-700 {
--tw-bg-opacity: 1;
background-color: rgb(21 128 61 / var(--tw-bg-opacity));
}
.bg-green-800 {
--tw-bg-opacity: 1;
background-color: rgb(22 101 52 / var(--tw-bg-opacity));
}
.object-cover {
-o-object-fit: cover;
object-fit: cover;
@ -889,6 +1010,10 @@ video {
text-transform: uppercase;
}
.lowercase {
text-transform: lowercase;
}
.capitalize {
text-transform: capitalize;
}
@ -916,6 +1041,10 @@ video {
text-decoration-line: underline;
}
.no-underline {
text-decoration-line: none;
}
.opacity-15 {
opacity: 0.15;
}
@ -926,6 +1055,10 @@ video {
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.outline {
outline-style: solid;
}
.ring {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
@ -974,6 +1107,14 @@ video {
display: block;
}
.md\:h-12 {
height: 3rem;
}
.md\:w-12 {
width: 3rem;
}
.md\:w-4\/5 {
width: 80%;
}
@ -993,6 +1134,14 @@ video {
}
@media (min-width: 1024px) {
.lg\:h-24 {
height: 6rem;
}
.lg\:w-24 {
width: 6rem;
}
.lg\:w-4\/5 {
width: 80%;
}

View File

@ -1,30 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title>Personal portfolio for olymk2</title>
<meta charset="utf-8" />
<meta content="#da532c" name="msapplication-TileColor" />
<meta content="#ffffff" name="theme-color" />
<link
href="https://cdn.jsdelivr.net/gh/devicons/devicon@v2.15.1/devicon.min.css"
rel="stylesheet"
type="text/css"
/>
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"
rel="stylesheet"
type="text/css"
/>
<link rel="stylesheet" href="./css/styles.css" type="text/css" />
<meta content="Personal portfolio" property="og:title" />
<meta
content="Portfolio of projects worked on past to present"
property="og:description"
/>
</head>
<body>
<div id="app"></div>
<script src="/cljs-out/base.js" type="application/javascript"></script>
<script src="/cljs-out/portfolio.js" type="application/javascript"></script>
</body>
</html>
<html><head><title>portfolio.runner</title><meta charset="utf-8">
<script src="https://cdn.tailwindcss.com"></script>
<style type="text/css" media="screen">
#loading {
-webkit-animation: rotation 2s infinite linear;
}
@-webkit-keyframes rotation {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(359deg);
}
}
</style>
</head><body><script src="/js/portfolio.js"></script></body></html>

View File

@ -2,6 +2,7 @@
(:require [portfolio.ui :as ui]
[portfolio.dumdom :as d]
[portfolio.dom :as r]
[blog.chess-scene :as chess]
[com.oly.static-sites.portfolio.page :as c]))
(d/defscene circle-flow

View File

@ -11,3 +11,4 @@ clj -M:blog:shadow-cljs-run watch blog
docker build -t europe-west2-docker.pkg.dev/blog-9d51d/blog/caddy .
docker push europe-west2-docker.pkg.dev/blog-9d51d/blog/caddy
clj -M:blog:shadow-cljs-run watch app ui blog blog-tests

View File

@ -2,14 +2,34 @@
:dev-http {8080 ["bases/do-blog/resources/public" "classpath:public"]
8081 ["development/resources/public/" "classpath:public"]}
;:nrepl {:middleware [refactor-nrepl.middleware/wrap-refactor]}
:nrepl {:middleware [refactor-nrepl.middleware/wrap-refactor]}
;;:nrepl {:middleware [refactor-nrepl.middleware/wrap-refactor]}
;; :source ["devlopment/src" "bases/portfolio/src"] ;;"src"
;; "../../components/web-ui/src"
;; "../../components/web-api/src"
;; "../../components/polyculture/src"
;; "../../components/svg-generation/src"
;; "../../components/local-store/src"]
:builds {:app {:output-dir "bases/portfolio/resources/public/js"
:builds {:ui {:output-dir "development/resources/public/js"
;:asset-path "."
:target :portfolio
:title "My UI components library"
;;:runner-ns blog.chess-scene
:portfolio.ui/config {
:css-paths ["/css/styles.css"
"https://unpkg.com/tachyons@4.12.0/css/tachyons.min.css"]}
:html-file {
:path "development/resources/public/portfolio.html"}
:compiler-options {:infer-externs :auto :output-feature-set :es6}
;; :modules {:base {:entries [com.oly.static-sites.portfolio.core]}
;; ;; :app {:init-fn com.oly.static-sites.portfolio.core/launch
;; ;; :depends-on #{:base}
;; ;; }
;; ;; :portfolio {;;:init-fn design/launch
;; ;; :depends-on #{:app}}
;; }
:devtools {:after-load app.main/reload!}}
:app {:output-dir "development/resources/public/js"
;:asset-path "."
:target :browser
:compiler-options {:infer-externs :auto :output-feature-set :es6}
@ -30,4 +50,9 @@
}
:devtools {:after-load app.main/reload!}
}
:blog-tests {:target :browser-test
:test-dir "development/resources/public/test/"
:ns-regexp "-test$"
:devtools {:http-port 8091
:http-root "development/resources/public/test"}}
}}

View File

@ -1,5 +1,5 @@
module.exports = {
content: ['./development/resources/public/**/*.{html,js}'],
content: ['./development/resources/public/**/*.{html,js,cljs}'],
theme: {
extend: {
backgroundImage: {