From 04c86680e1781bbceb895477a6fc7de3465bf38d Mon Sep 17 00:00:00 2001 From: leiDnedyA Date: Tue, 15 Aug 2023 12:32:57 -0400 Subject: [PATCH 1/8] added examples --- Makefile | 1 + examples/chatroom-client.rkt | 199 +++++++++++++++++++++++++++++++++++ examples/chatroom-server.rkt | 59 +++++++++++ static/index.html | 2 + 4 files changed, 261 insertions(+) create mode 100644 examples/chatroom-client.rkt create mode 100644 examples/chatroom-server.rkt diff --git a/Makefile b/Makefile index 73727c0..25a9ffb 100644 --- a/Makefile +++ b/Makefile @@ -52,6 +52,7 @@ examples/%.rkt.js: examples/%.rkt @echo "Compiling $<..." racks $(RACKS_FLAGS) $(RACKS_ARGS) $(RACKS_EXAMPLE_FLAGS) -d build/examples $< cp build/examples/modules/$*.rkt.js examples/ + clean: rm -rf build/ examples/*.rkt.js diff --git a/examples/chatroom-client.rkt b/examples/chatroom-client.rkt new file mode 100644 index 0000000..f0e24b3 --- /dev/null +++ b/examples/chatroom-client.rkt @@ -0,0 +1,199 @@ +#lang racketscript/base + +(require racket/list + racketscript-universe + racketscript/htdp/image) + +;; Example based on https://course.khoury.northeastern.edu/cs5010sp15/set08.html + +;; TODO: Implement encoding/decoding of racket elements so that complex +;; datatypes like MsgFromServer can be more easily sent + +;; UserName +;; String of only letters and numbers between 1 and 12 chars long + +;; MsgFromServer +;; (list 'userlist ListOf) ;; don't include in event-messages +;; (list 'join UserName) +;; (list 'leave UserName) +;; (list 'error Message) +;; (list 'private UserName Message) ;; a private msg from a user +;; (list 'broadcast UserName Message) ;; a public msg from a user + +;; Current solution: JSON version of MsgFromServer +;; {"type": "userlist", "content": Array} +;; {"type": "broadcast", "sender": , "content": js-string} + +;; WorldState +;; (list client-name connected-users> event-messages> curr-input) + +;; +;; Helper functions +;; + +(define (slice-list l start stop) + (take (drop l start) (- stop start))) + +;; +;; Constants +;; + +(define FONT-SIZE 12) +(define MARGIN 3) +(define MT (empty-scene 400 400)) +(define CHARS-PER-LINE 44) ;; max chars that can fit in the input box +(define MAX-MESSAGES 25) + + +;; +;; WorldState parsers +;; + +(define (get-client-name ws) + (list-ref ws 0)) + +(define (get-connected-users ws) + (list-ref ws 1)) + +(define (get-event-messages ws) + (list-ref ws 2)) + +(define (get-curr-input ws) + (list-ref ws 3)) + + +;; +;; Message Parsing +;; + +(define (parse-user-list u-list) + (#js.u-list.reduce (lambda (result curr) + (append result (list (js-string->string curr)))) + '())) + + +;; +;; Drawing Functions +;; + +(define (participant-names-column names) + (define container (rectangle 100 400 'outline 'black)) + (define i 0) + (foldl (lambda (name res) + (define name-text (text name FONT-SIZE 'black)) + (define col (underlay/xy res + MARGIN (+ MARGIN (* i 20)) + name-text)) + (set! i (+ i 1)) + col) + container + names)) + +(define (message-textbox curr-text cursor-pos) + (define container (rectangle 300 20 'outline 'black)) + (define text-len (string-length curr-text)) + (define input-text (text (if (> text-len CHARS-PER-LINE) + (substring curr-text (- text-len CHARS-PER-LINE) text-len) + curr-text) + FONT-SIZE + 'black)) + + (underlay/xy container MARGIN MARGIN input-text)) + +(define (message-log-display event-list username) + (define background (rectangle 300 380 'outline 'black)) + (define count 0) + (foldl (lambda (evt res) + (define evt-type (list-ref evt 0)) + (define (add-text img) + (define new-res (underlay/xy res MARGIN (+ (* count FONT-SIZE) (* (+ count 1) MARGIN)) img)) + (set! count (+ count 1)) + new-res) + (define (message-text user msg color) + (text (format "<~a> ~a" user msg) FONT-SIZE color)) + (case evt-type + [(broadcast) (add-text (message-text (list-ref evt 1) + (list-ref evt 2) + 'black))] + [(private) (add-text (message-text (format "~a->~a" (list-ref evt 1) username) + (list-ref evt 2) + 'blue))] + [(join) (add-text (text (format "~a joined." (list-ref evt 1)) + FONT-SIZE + 'gray))] + [(leave) (add-text (text (format "~a left the chat." (list-ref evt 1)) + FONT-SIZE + 'gray))] + [(error) (add-text (text (list-ref evt 1) FONT-SIZE 'red))] + [else res])) + background + (if (> (length event-list) MAX-MESSAGES) + (slice-list event-list + (- (length event-list) MAX-MESSAGES) + (length event-list)) + event-list))) + +(define (draw ws) + (define textbox (message-textbox (get-curr-input ws))) + (define users (participant-names-column (get-connected-users ws))) + (define log (message-log-display (get-event-messages ws) (get-client-name ws))) + + (underlay/xy (underlay/xy (underlay/xy MT 0 0 users) + 100 380 + textbox) + 100 0 + log)) + + +;; +;; Event Handlers +;; + +(define (handle-key ws k) + (define curr-text (get-curr-input ws)) + (define new-text (cond + [(> (string-length k) 1) curr-text] + [(key=? k "\b") (if (<= (string-length curr-text) 0) + curr-text + (substring curr-text + 0 + (- (string-length curr-text) 1)))] + [else (string-append curr-text k)])) + (if (key=? k "\r") + (make-package (list (get-client-name ws) + (get-connected-users ws) + (get-event-messages ws) + "") + curr-text) + (list (get-client-name ws) + (get-connected-users ws) + (get-event-messages ws) + new-text))) + +(define (handle-receive ws msg) + (define username (get-client-name ws)) + (define users (get-connected-users ws)) + (define messages (get-event-messages ws)) + (define input (get-curr-input ws)) + + (define msg-type (list-ref msg 0)) + (case msg-type + [(userlist) (set! users (list-ref msg 1))] + [(broadcast) (set! messages (append messages (list msg)))]) + + (list username users messages input)) + +;; +;; Start func +;; + +(define (start-world username root) + (big-bang #:dom-root root + (list username '() '() "") + [to-draw draw] + [on-key handle-key] + [on-receive handle-receive] + [name username] + [register "my-server"])) + +(start-world "test user") \ No newline at end of file diff --git a/examples/chatroom-server.rkt b/examples/chatroom-server.rkt new file mode 100644 index 0000000..ab8fc59 --- /dev/null +++ b/examples/chatroom-server.rkt @@ -0,0 +1,59 @@ +#lang racketscript/base + +(require racketscript-universe + racketscript/htdp/image) + +;; Example based on https://course.khoury.northeastern.edu/cs5010sp15/set08.html + +;; WorldState: +;; (list ListOf ListOf) + +;; TODO: +;; Create methods to: +;; - generate mails for all clients +;; - add event to the event list + +(define (make-client-list ws) + (foldl (lambda (iw result) (append result (list (iworld-name iw)))) '() ws)) + +(define (make-broadcast sender msg) + (format "[]")) + +(define (mail-to-all ws content) + (foldl (lambda (iw result) + (append result (list (make-mail iw content)))) + '() + ws)) + +(define (client-list-mails ws) + (define client-list (make-client-list ws)) + (mail-to-all ws (list 'userlist client-list))) + +(define (handle-new ws iw) + (define ws* (append ws (list iw))) + (define mails (client-list-mails ws*)) + (define to-remove '()) + (make-bundle ws* mails to-remove)) + +(define (handle-msg ws iw msg) + (define msg-mail (list 'broadcast (iworld-name iw) msg)) + (define ws* ws) + (define mails (mail-to-all ws* msg-mail)) + (define to-remove '()) + (make-bundle ws* mails to-remove)) + +(define (handle-disconnect ws iw) + (define ws* (remove iw ws)) + (define mails (client-list-mails ws*)) + (define to-remove '()) + (make-bundle ws* mails to-remove)) + +(define (start-universe root) + (universe #:dom-root root + '() + [server-id "my-server"] + [on-new handle-new] + [on-msg handle-msg] + [on-disconnect handle-disconnect])) + +(start-universe) \ No newline at end of file diff --git a/static/index.html b/static/index.html index f2d05c7..ea994bd 100644 --- a/static/index.html +++ b/static/index.html @@ -78,6 +78,8 @@
  • Tetris
  • Archery
  • Wordle
  • +
  • Chatroom Server
  • +
  • Chatroom Client
  • From b4de5f31d4b5a5127bedc06bd6249fd1766e2578 Mon Sep 17 00:00:00 2001 From: leiDnedyA Date: Tue, 15 Aug 2023 12:44:19 -0400 Subject: [PATCH 2/8] more work on implementing examples --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 25a9ffb..73727c0 100644 --- a/Makefile +++ b/Makefile @@ -52,7 +52,6 @@ examples/%.rkt.js: examples/%.rkt @echo "Compiling $<..." racks $(RACKS_FLAGS) $(RACKS_ARGS) $(RACKS_EXAMPLE_FLAGS) -d build/examples $< cp build/examples/modules/$*.rkt.js examples/ - clean: rm -rf build/ examples/*.rkt.js From c44f49dd39b730e88ee353977b60d01740d75188 Mon Sep 17 00:00:00 2001 From: leiDnedyA Date: Wed, 16 Aug 2023 11:45:57 -0400 Subject: [PATCH 3/8] switched from standalone racketscript-universe module to racketscript/htdp/peer-universe and tweaked build process --- examples/chatroom-client.rkt | 4 ++-- examples/chatroom-server.rkt | 4 ++-- stub.rkt | 6 +++++- stub2.rkt | 10 ++++++++++ 4 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 stub2.rkt diff --git a/examples/chatroom-client.rkt b/examples/chatroom-client.rkt index f0e24b3..c273c0a 100644 --- a/examples/chatroom-client.rkt +++ b/examples/chatroom-client.rkt @@ -1,7 +1,7 @@ #lang racketscript/base (require racket/list - racketscript-universe + racketscript/htdp/peer-universe racketscript/htdp/image) ;; Example based on https://course.khoury.northeastern.edu/cs5010sp15/set08.html @@ -196,4 +196,4 @@ [name username] [register "my-server"])) -(start-world "test user") \ No newline at end of file +(start-world "test user") diff --git a/examples/chatroom-server.rkt b/examples/chatroom-server.rkt index ab8fc59..1407b1e 100644 --- a/examples/chatroom-server.rkt +++ b/examples/chatroom-server.rkt @@ -1,6 +1,6 @@ #lang racketscript/base -(require racketscript-universe +(require racketscript/htdp/peer-universe racketscript/htdp/image) ;; Example based on https://course.khoury.northeastern.edu/cs5010sp15/set08.html @@ -56,4 +56,4 @@ [on-msg handle-msg] [on-disconnect handle-disconnect])) -(start-universe) \ No newline at end of file +(start-universe) diff --git a/stub.rkt b/stub.rkt index 271be68..4899094 100644 --- a/stub.rkt +++ b/stub.rkt @@ -5,7 +5,8 @@ (require racketscript/interop racketscript/browser racketscript/htdp/image - racketscript/htdp/universe) + racketscript/htdp/universe + "stub2.rkt") ;; interop assoc->object @@ -20,6 +21,9 @@ square ;; universe big-bang +;; peer-universe +(peer-universe-imports) + ;; list foldr make-list diff --git a/stub2.rkt b/stub2.rkt new file mode 100644 index 0000000..6d7f94a --- /dev/null +++ b/stub2.rkt @@ -0,0 +1,10 @@ +#lang racket + +(require racketscript/htdp/peer-universe) + +(provide peer-universe-imports) + +(define (peer-universe-imports) + big-bang + universe + 0) From 8598607b9bf1b1a64b8bee683f6dfed1612f6558 Mon Sep 17 00:00:00 2001 From: leiDnedyA Date: Thu, 17 Aug 2023 11:02:33 -0400 Subject: [PATCH 4/8] Added form at start of chatroom-client to choose username and provide server peer ID --- examples/chatroom-client.rkt | 57 +++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/examples/chatroom-client.rkt b/examples/chatroom-client.rkt index c273c0a..c2ea6cf 100644 --- a/examples/chatroom-client.rkt +++ b/examples/chatroom-client.rkt @@ -6,12 +6,6 @@ ;; Example based on https://course.khoury.northeastern.edu/cs5010sp15/set08.html -;; TODO: Implement encoding/decoding of racket elements so that complex -;; datatypes like MsgFromServer can be more easily sent - -;; UserName -;; String of only letters and numbers between 1 and 12 chars long - ;; MsgFromServer ;; (list 'userlist ListOf) ;; don't include in event-messages ;; (list 'join UserName) @@ -20,13 +14,10 @@ ;; (list 'private UserName Message) ;; a private msg from a user ;; (list 'broadcast UserName Message) ;; a public msg from a user -;; Current solution: JSON version of MsgFromServer -;; {"type": "userlist", "content": Array} -;; {"type": "broadcast", "sender": , "content": js-string} - ;; WorldState ;; (list client-name connected-users> event-messages> curr-input) + ;; ;; Helper functions ;; @@ -187,13 +178,51 @@ ;; Start func ;; -(define (start-world username root) - (big-bang #:dom-root root +(define (start-world username server-id) + (big-bang #:dom-root #js*.document.body (list username '() '() "") [to-draw draw] [on-key handle-key] [on-receive handle-receive] [name username] - [register "my-server"])) + [register server-id])) + + +;; +;; Join UI +;; -(start-world "test user") +(define join-form (#js*.document.createElement #js"form")) +(define name-label (#js*.document.createElement #js"label")) +(define br-1 (#js*.document.createElement #js"br")) +(define name-input (#js*.document.createElement #js"input")) +(define br-2 (#js*.document.createElement #js"br")) +(define server-id-label (#js*.document.createElement #js"label")) +(define br-3 (#js*.document.createElement #js"br")) +(define server-id-input (#js*.document.createElement #js"input")) +(define br-4 (#js*.document.createElement #js"br")) +(define form-submit (#js*.document.createElement #js"input")) + +($/:= #js.name-label.innerHTML #js"Username") +($/:= #js.server-id-label.innerHTML #js"Server's Peer ID") +($/:= #js.name-input.placeholder #js"my_name1234") +($/:= #js.server-id-input.placeholder #js"42adwadwa#$021") +($/:= #js.form-submit.type #js"submit") +($/:= #js.form-submit.value #js"Join!") + +(for-each (λ (el) + (#js.join-form.appendChild el) + 0) + (list name-label br-1 name-input + br-2 + server-id-label br-3 server-id-input + br-4 + form-submit)) + +($/:= #js.join-form.onsubmit + (λ () + (start-world (js-string->string #js.name-input.value) + (js-string->string #js.server-id-input.value)) + (#js.join-form.remove))) + +(#js*.document.body.appendChild join-form) \ No newline at end of file From 93ef39dab0a80342f37b096b074be13c690e3271 Mon Sep 17 00:00:00 2001 From: leiDnedyA Date: Thu, 17 Aug 2023 11:17:53 -0400 Subject: [PATCH 5/8] added funny random server peer ids --- examples/chatroom-server.rkt | 90 +++++++++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 6 deletions(-) diff --git a/examples/chatroom-server.rkt b/examples/chatroom-server.rkt index 1407b1e..87c533e 100644 --- a/examples/chatroom-server.rkt +++ b/examples/chatroom-server.rkt @@ -8,10 +8,83 @@ ;; WorldState: ;; (list ListOf ListOf) -;; TODO: -;; Create methods to: -;; - generate mails for all clients -;; - add event to the event list + +;; +;; Funny words courtesy of ChatGPT +;; + +(define funny-adjectives (list "bumbling" + "quizzical" + "wacky" + "zany" + "fluffy" + "bizarre" + "hilarious" + "whimsical" + "absurd" + "goofy" + "ridiculous" + "loopy" + "nutty" + "eccentric" + "silly" + "quirky" + "jovial" + "giggly" + "mirthful" + "haphazard" + "chucklesome" + "fanciful" + "droll" + "boisterous" + "offbeat" + "hysterical" + "peculiar" + "lighthearted" + "playful" + "amusing")) + +(define funny-nouns (list "banana" + "sock-puppet" + "llama" + "rubber-chicken" + "pajamas" + "gobbledygook" + "poodle" + "bubble-wrap" + "tater-tot" + "cheeseburger" + "wiggle" + "snorkel" + "ticklemonster" + "jello" + "balloon-animal" + "slinky" + "spaghetti" + "bumblebee" + "dingleberry" + "flapdoodle" + "doohickey" + "noodle" + "gobbledygook" + "whatchamacallit" + "snickerdoodle" + "popsicle" + "gigglesnort" + "wobble" + "hootenanny" + "noodle")) + +(define (generate-id) + (define adjective (list-ref funny-adjectives + (random (length funny-adjectives)))) + (define noun (list-ref funny-nouns + (random (length funny-nouns)))) + (format "~a-~a" adjective noun)) + +;; +;; Helper functions +;; (define (make-client-list ws) (foldl (lambda (iw result) (append result (list (iworld-name iw)))) '() ws)) @@ -29,6 +102,11 @@ (define client-list (make-client-list ws)) (mail-to-all ws (list 'userlist client-list))) + +;; +;; Event handlers +;; + (define (handle-new ws iw) (define ws* (append ws (list iw))) (define mails (client-list-mails ws*)) @@ -51,9 +129,9 @@ (define (start-universe root) (universe #:dom-root root '() - [server-id "my-server"] + [server-id (generate-id)] [on-new handle-new] [on-msg handle-msg] [on-disconnect handle-disconnect])) -(start-universe) +(start-universe) \ No newline at end of file From bead5ba0357a41e7b4e01922b9f61e86feebcdc6 Mon Sep 17 00:00:00 2001 From: leiDnedyA Date: Thu, 17 Aug 2023 11:51:20 -0400 Subject: [PATCH 6/8] Added join/leave messages to chatroom client --- examples/chatroom-client.rkt | 25 ++++++++++++++++++++++--- examples/chatroom-server.rkt | 3 ++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/examples/chatroom-client.rkt b/examples/chatroom-client.rkt index c2ea6cf..76e4e3f 100644 --- a/examples/chatroom-client.rkt +++ b/examples/chatroom-client.rkt @@ -25,6 +25,13 @@ (define (slice-list l start stop) (take (drop l start) (- stop start))) +(define (list-contains list v) + (number? (index-of list v))) + +(define (not-in-list bigger-list smaller-list) + (list-ref (filter (λ (el) (not (list-contains smaller-list el))) bigger-list) 0)) + + ;; ;; Constants ;; @@ -169,11 +176,23 @@ (define msg-type (list-ref msg 0)) (case msg-type - [(userlist) (set! users (list-ref msg 1))] - [(broadcast) (set! messages (append messages (list msg)))]) + [(userlist) (begin + (define users* (list-ref msg 1)) + + (set! messages + (append messages + (if (> (length users*) (length users)) + (list (list 'join + (list-ref users* + (- (length users*) 1)))) + (list (list 'leave + (not-in-list users users*)))))) + (set! users users*))] + [(broadcast) (set! messages (append messages (list msg)))]) (list username users messages input)) + ;; ;; Start func ;; @@ -189,7 +208,7 @@ ;; -;; Join UI +;; User login UI ;; (define join-form (#js*.document.createElement #js"form")) diff --git a/examples/chatroom-server.rkt b/examples/chatroom-server.rkt index 87c533e..d7c2b4b 100644 --- a/examples/chatroom-server.rkt +++ b/examples/chatroom-server.rkt @@ -44,7 +44,8 @@ "playful" "amusing")) -(define funny-nouns (list "banana" +(define funny-nouns (list "goober" + "banana" "sock-puppet" "llama" "rubber-chicken" From 09d36b27ebe0fe64071155df2ea84dcc6c8bc555 Mon Sep 17 00:00:00 2001 From: leiDnedyA Date: Mon, 21 Aug 2023 09:32:30 -0400 Subject: [PATCH 7/8] Added bouncing-ball example --- examples/bouncing-ball-client.rkt | 85 +++++++++++++++++++ examples/bouncing-ball-server.rkt | 130 ++++++++++++++++++++++++++++++ static/index.html | 2 + 3 files changed, 217 insertions(+) create mode 100644 examples/bouncing-ball-client.rkt create mode 100644 examples/bouncing-ball-server.rkt diff --git a/examples/bouncing-ball-client.rkt b/examples/bouncing-ball-client.rkt new file mode 100644 index 0000000..5b20827 --- /dev/null +++ b/examples/bouncing-ball-client.rkt @@ -0,0 +1,85 @@ +#lang racketscript/base +(require racketscript/htdp/peer-universe + racketscript/htdp/image) + +;; Implementation of bouncing ball example from +;; 2htdp/universe docs +;; ( https://docs.racket-lang.org/teachpack/2htdpuniverse.html ) +;; (ctrl + F search for "Designing the Ball World") + +(define SPEED 5) +(define RADIUS 10) +(define WORLD0 'RESTING) + +(define WIDTH 600) +(define HEIGHT 400) +(define MT (empty-scene WIDTH HEIGHT)) +(define BALL (circle RADIUS 'solid 'blue)) + +(define (move ws) + (define is-active (number? ws)) + (if is-active + (if (<= ws 0) + (make-package 'RESTING #js"done") + (- ws SPEED)) + ws)) + +(define (draw ws) + (cond + [(number? ws) (underlay/xy MT 50 ws BALL)] + [else (underlay/xy MT 50 50 (text "Resting" 24 'blue))])) + +;; The only message that the server send is the your-turn one, +;; so this will always return HEIGHT as the next world state +(define (receive ws msg) + (if (number? ws) + ws + HEIGHT)) + +;; Stops world when ws == "stop" +(define (stop? ws) (equal? ws "stop")) + +(define (handle-key ws key) + (if (equal? key " ") + "stop" ws)) + +(define (start-world client-name server-id) + (big-bang WORLD0 + [on-tick move] + [to-draw draw] + [on-receive receive] + [register server-id] + [name client-name] + [on-key handle-key] + [stop-when stop?])) + +;; +;; User login UI +;; + +(define join-form (#js*.document.createElement #js"form")) +(define server-id-label (#js*.document.createElement #js"label")) +(define br-1 (#js*.document.createElement #js"br")) +(define server-id-input (#js*.document.createElement #js"input")) +(define br-2 (#js*.document.createElement #js"br")) +(define form-submit (#js*.document.createElement #js"input")) + +($/:= #js.server-id-label.innerHTML #js"Server's Peer ID") +($/:= #js.server-id-input.placeholder #js"42adwadwa#$021") +($/:= #js.form-submit.type #js"submit") +($/:= #js.form-submit.value #js"Join!") + +(for-each (λ (el) + (#js.join-form.appendChild el) + 0) + (list server-id-label br-1 server-id-input + br-2 + form-submit)) + +($/:= #js.join-form.onsubmit + (λ () + (start-world "user" + (js-string->string #js.server-id-input.value)) + (#js.join-form.remove))) + +(#js*.document.body.appendChild join-form) \ No newline at end of file diff --git a/examples/bouncing-ball-server.rkt b/examples/bouncing-ball-server.rkt new file mode 100644 index 0000000..4d84d0c --- /dev/null +++ b/examples/bouncing-ball-server.rkt @@ -0,0 +1,130 @@ +#lang racketscript/base + +(require racketscript/htdp/peer-universe + racketscript/htdp/image + racket/list) + + +;; +;; Funny words courtesy of ChatGPT +;; + +(define funny-adjectives (list "bumbling" + "quizzical" + "wacky" + "zany" + "fluffy" + "bizarre" + "hilarious" + "whimsical" + "absurd" + "goofy" + "ridiculous" + "loopy" + "nutty" + "eccentric" + "silly" + "quirky" + "jovial" + "giggly" + "mirthful" + "haphazard" + "chucklesome" + "fanciful" + "droll" + "boisterous" + "offbeat" + "hysterical" + "peculiar" + "lighthearted" + "playful" + "amusing")) + +(define funny-nouns (list "goober" + "banana" + "sock-puppet" + "llama" + "rubber-chicken" + "pajamas" + "gobbledygook" + "poodle" + "bubble-wrap" + "tater-tot" + "cheeseburger" + "wiggle" + "snorkel" + "ticklemonster" + "jello" + "balloon-animal" + "slinky" + "spaghetti" + "bumblebee" + "dingleberry" + "flapdoodle" + "doohickey" + "noodle" + "gobbledygook" + "whatchamacallit" + "snickerdoodle" + "popsicle" + "gigglesnort" + "wobble" + "hootenanny" + "noodle")) + +(define (generate-id) + (define adjective (list-ref funny-adjectives + (random (length funny-adjectives)))) + (define noun (list-ref funny-nouns + (random (length funny-nouns)))) + (format "~a-~a" adjective noun)) + + +;; +;; Helper functions +;; + +(define (make-curr-mail ws) + (define curr-iw (first ws)) + (list (make-mail curr-iw #js"it-is-your-turn"))) + + +;; +;; Event handlers +;; + +(define (handle-new ws iw) + (define ws* (append ws (list iw))) + (define mails (make-curr-mail ws*)) + (define to-remove '()) + (make-bundle ws* mails to-remove)) + +(define (handle-msg ws iw msg) + (define ws* (append (rest ws) (list (first ws)))) + (define mails (make-curr-mail ws*)) + (define to-remove '()) + (make-bundle ws* mails to-remove)) + +(define (handle-disconnect ws iw) + (define ws* (remove iw ws)) + (define mails (make-curr-mail ws*)) + (define to-remove '()) + (make-bundle ws* mails to-remove)) + +(define (handle-tick ws) + (make-bundle ws '() '())) + + +;; +;; Starting server on window load +;; + +(define (start-universe) + (universe '() + [server-id (generate-id)] + [on-new handle-new] + [on-msg handle-msg] + [on-tick handle-tick] + [on-disconnect handle-disconnect])) + +($/:= #js*.window.onload start-universe) \ No newline at end of file diff --git a/static/index.html b/static/index.html index ea994bd..39ae9ec 100644 --- a/static/index.html +++ b/static/index.html @@ -80,6 +80,8 @@
  • Wordle
  • Chatroom Server
  • Chatroom Client
  • +
  • Bouncing Ball Server
  • +
  • Bouncing Ball Client
  • From cff5476318f7215cb3710509aef1da03b0b21e44 Mon Sep 17 00:00:00 2001 From: leiDnedyA Date: Mon, 21 Aug 2023 10:10:32 -0400 Subject: [PATCH 8/8] Added multi-level dropdown menu --- static/index.html | 18 +++++++++++++----- static/style.css | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/static/index.html b/static/index.html index 39ae9ec..9591425 100644 --- a/static/index.html +++ b/static/index.html @@ -63,7 +63,7 @@