Adopt Step 7 language features across SX codebase
112 conversions across 19 .sx files using match, let-match, and pipe operators: match (17): type/value dispatch replacing cond/if chains - lib/vm.sx: HO form dispatch (for-each/map/filter/reduce/some/every?) - lib/tree-tools.sx: node-display, node-matches?, rename, count, replace, free-symbols - lib/types.sx: narrow-type, substitute-in-type, infer-type, resolve-type - web/engine.sx: default-trigger, resolve-target, classify-trigger - web/deps.sx: scan-refs-walk, scan-io-refs-walk let-match (89): dict destructuring replacing (get d "key") patterns - shared/page-functions.sx (20), blog/admin.sx (17), pub-api.sx (13) - events/ layouts/page/tickets/entries/forms (27 total) - specs-explorer.sx (7), federation/social.sx (3), lib/ small files (3) -> pipes (6): replacing triple-chained gets in lib/vm.sx - frame-closure → closure-code → code-bytecode chains Also: lib/vm.sx accessor upgrades (get vm "sp" → vm-sp vm throughout) 2650/2650 tests pass, zero regressions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -92,52 +92,95 @@
|
||||
|
||||
;; --- Data-driven post card (replaces Python _post_card_sx loop) ---
|
||||
|
||||
(defcomp ~social/post-card-from-data (&key (d :as dict) (has-actor :as boolean) (csrf :as string)
|
||||
(like-url :as string) (unlike-url :as string)
|
||||
(boost-url :as string) (unboost-url :as string))
|
||||
(let* ((boosted-by (get d "boosted_by"))
|
||||
(actor-icon (get d "actor_icon"))
|
||||
(actor-name (get d "actor_name"))
|
||||
(initial (or (get d "initial") "?"))
|
||||
(avatar (~shared:misc/avatar
|
||||
:src actor-icon
|
||||
:cls (if actor-icon "w-10 h-10 rounded-full"
|
||||
"w-10 h-10 rounded-full bg-stone-300 flex items-center justify-center text-stone-600 font-bold text-sm")
|
||||
:initial (when (not actor-icon) initial)))
|
||||
(boost (when boosted-by (~social/boost-label :name boosted-by)))
|
||||
(content-sx (if (get d "summary")
|
||||
(~social/content :content (get d "content") :summary (get d "summary"))
|
||||
(~social/content :content (get d "content"))))
|
||||
(original (when (get d "original_url")
|
||||
(~social/original-link :url (get d "original_url"))))
|
||||
(safe-id (get d "safe_id"))
|
||||
(interactions (when has-actor
|
||||
(let* ((oid (get d "object_id"))
|
||||
(ainbox (get d "author_inbox"))
|
||||
(target (str "#interactions-" safe-id))
|
||||
(liked (get d "liked_by_me"))
|
||||
(boosted-me (get d "boosted_by_me"))
|
||||
(l-action (if liked unlike-url like-url))
|
||||
(l-cls (str "flex items-center gap-1 " (if liked "text-red-500 hover:text-red-600" "hover:text-red-500")))
|
||||
(l-icon (if liked "\u2665" "\u2661"))
|
||||
(b-action (if boosted-me unboost-url boost-url))
|
||||
(b-cls (str "flex items-center gap-1 " (if boosted-me "text-green-600 hover:text-green-700" "hover:text-green-600")))
|
||||
(reply-url (get d "reply_url"))
|
||||
(reply (when reply-url (~social/reply-link :url reply-url)))
|
||||
(like-form (~social/like-form
|
||||
:action l-action :target target :oid oid :ainbox ainbox
|
||||
:csrf csrf :cls l-cls :icon l-icon :count (get d "like_count")))
|
||||
(boost-form (~social/boost-form
|
||||
:action b-action :target target :oid oid :ainbox ainbox
|
||||
:csrf csrf :cls b-cls :count (get d "boost_count"))))
|
||||
(div :id (str "interactions-" safe-id)
|
||||
(~social/interaction-buttons :like like-form :boost boost-form :reply reply))))))
|
||||
(~social/post-card
|
||||
:boost boost :avatar avatar
|
||||
:actor-name actor-name :actor-username (get d "actor_username")
|
||||
:domain (get d "domain") :time (get d "time")
|
||||
:content content-sx :original original
|
||||
:interactions interactions)))
|
||||
(defcomp
|
||||
~social/post-card-from-data
|
||||
(&key
|
||||
(d :as dict)
|
||||
(has-actor :as boolean)
|
||||
(csrf :as string)
|
||||
(like-url :as string)
|
||||
(unlike-url :as string)
|
||||
(boost-url :as string)
|
||||
(unboost-url :as string))
|
||||
(let-match
|
||||
{:actor_name actor-name :liked_by_me liked :boosted_by_me boosted-me :time time :actor_username actor-username :domain domain :content content :object_id oid :boosted_by boosted-by :summary summary :original_url original-url :safe_id safe-id :author_inbox ainbox :reply_url reply-url :like_count like-count :boost_count boost-count :actor_icon actor-icon :initial initial*}
|
||||
d
|
||||
(let*
|
||||
((initial (or initial* "?"))
|
||||
(avatar
|
||||
(~shared:misc/avatar
|
||||
:src actor-icon
|
||||
:cls (if
|
||||
actor-icon
|
||||
"w-10 h-10 rounded-full"
|
||||
"w-10 h-10 rounded-full bg-stone-300 flex items-center justify-center text-stone-600 font-bold text-sm")
|
||||
:initial (when (not actor-icon) initial)))
|
||||
(boost (when boosted-by (~social/boost-label :name boosted-by)))
|
||||
(content-sx
|
||||
(if
|
||||
summary
|
||||
(~social/content :content content :summary summary)
|
||||
(~social/content :content content)))
|
||||
(original
|
||||
(when original-url (~social/original-link :url original-url)))
|
||||
(interactions
|
||||
(when
|
||||
has-actor
|
||||
(let*
|
||||
((target (str "#interactions-" safe-id))
|
||||
(l-action (if liked unlike-url like-url))
|
||||
(l-cls
|
||||
(str
|
||||
"flex items-center gap-1 "
|
||||
(if
|
||||
liked
|
||||
"text-red-500 hover:text-red-600"
|
||||
"hover:text-red-500")))
|
||||
(l-icon (if liked "♥" "♡"))
|
||||
(b-action (if boosted-me unboost-url boost-url))
|
||||
(b-cls
|
||||
(str
|
||||
"flex items-center gap-1 "
|
||||
(if
|
||||
boosted-me
|
||||
"text-green-600 hover:text-green-700"
|
||||
"hover:text-green-600")))
|
||||
(reply (when reply-url (~social/reply-link :url reply-url)))
|
||||
(like-form
|
||||
(~social/like-form
|
||||
:action l-action
|
||||
:target target
|
||||
:oid oid
|
||||
:ainbox ainbox
|
||||
:csrf csrf
|
||||
:cls l-cls
|
||||
:icon l-icon
|
||||
:count like-count))
|
||||
(boost-form
|
||||
(~social/boost-form
|
||||
:action b-action
|
||||
:target target
|
||||
:oid oid
|
||||
:ainbox ainbox
|
||||
:csrf csrf
|
||||
:cls b-cls
|
||||
:count boost-count)))
|
||||
(div
|
||||
:id (str "interactions-" safe-id)
|
||||
(~social/interaction-buttons
|
||||
:like like-form
|
||||
:boost boost-form
|
||||
:reply reply))))))
|
||||
(~social/post-card
|
||||
:boost boost
|
||||
:avatar avatar
|
||||
:actor-name actor-name
|
||||
:actor-username actor-username
|
||||
:domain domain
|
||||
:time time
|
||||
:content content-sx
|
||||
:original original
|
||||
:interactions interactions))))
|
||||
|
||||
;; Data-driven timeline items (replaces Python _timeline_items_sx loop)
|
||||
(defcomp ~social/timeline-items-from-data (&key (items :as list) (next-url :as string?) (has-actor :as boolean) (csrf :as string)
|
||||
@@ -174,35 +217,53 @@
|
||||
;; Assembled social nav — replaces Python _social_nav_sx
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defcomp ~social/nav (&key actor)
|
||||
(if (not actor)
|
||||
(~social/nav-choose-username :url (url-for "identity.choose_username_form"))
|
||||
(let* ((rp (request-path))
|
||||
(links (list
|
||||
(dict :endpoint "social.defpage_home_timeline" :label "Timeline")
|
||||
(dict :endpoint "social.defpage_public_timeline" :label "Public")
|
||||
(dict :endpoint "social.defpage_compose_form" :label "Compose")
|
||||
(dict :endpoint "social.defpage_following_list" :label "Following")
|
||||
(dict :endpoint "social.defpage_followers_list" :label "Followers")
|
||||
(dict :endpoint "social.defpage_search" :label "Search"))))
|
||||
(defcomp
|
||||
~social/nav
|
||||
(&key actor)
|
||||
(if
|
||||
(not actor)
|
||||
(~social/nav-choose-username
|
||||
:url (url-for "identity.choose_username_form"))
|
||||
(let*
|
||||
((rp (request-path))
|
||||
(links
|
||||
(list
|
||||
(dict :endpoint "social.defpage_home_timeline" :label "Timeline")
|
||||
(dict :endpoint "social.defpage_public_timeline" :label "Public")
|
||||
(dict :endpoint "social.defpage_compose_form" :label "Compose")
|
||||
(dict :endpoint "social.defpage_following_list" :label "Following")
|
||||
(dict :endpoint "social.defpage_followers_list" :label "Followers")
|
||||
(dict :endpoint "social.defpage_search" :label "Search"))))
|
||||
(~social/nav-bar
|
||||
:items (<>
|
||||
(map (lambda (lnk)
|
||||
(let* ((href (url-for (get lnk "endpoint")))
|
||||
(bold (if (= rp href) " font-bold" "")))
|
||||
(a :href href
|
||||
:class (str "px-2 py-1 rounded hover:bg-stone-200" bold)
|
||||
(get lnk "label"))))
|
||||
(map
|
||||
(lambda
|
||||
(lnk)
|
||||
(let-match
|
||||
{:label label :endpoint endpoint}
|
||||
lnk
|
||||
(let*
|
||||
((href (url-for endpoint))
|
||||
(bold (if (= rp href) " font-bold" "")))
|
||||
(a
|
||||
:href href
|
||||
:class (str "px-2 py-1 rounded hover:bg-stone-200" bold)
|
||||
label))))
|
||||
links)
|
||||
(let* ((notif-url (url-for "social.defpage_notifications"))
|
||||
(notif-bold (if (= rp notif-url) " font-bold" "")))
|
||||
(let*
|
||||
((notif-url (url-for "social.defpage_notifications"))
|
||||
(notif-bold (if (= rp notif-url) " font-bold" "")))
|
||||
(~social/nav-notification-link
|
||||
:href notif-url
|
||||
:cls (str "px-2 py-1 rounded hover:bg-stone-200 relative" notif-bold)
|
||||
:count-url (url-for "social.notification_count")))
|
||||
(a :href (url-for "activitypub.actor_profile" :username (get actor "preferred_username"))
|
||||
:class "px-2 py-1 rounded hover:bg-stone-200"
|
||||
(str "@" (get actor "preferred_username"))))))))
|
||||
(let-match
|
||||
{:preferred_username username}
|
||||
actor
|
||||
(a
|
||||
:href (url-for "activitypub.actor_profile" :username username)
|
||||
:class "px-2 py-1 rounded hover:bg-stone-200"
|
||||
(str "@" username))))))))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; Assembled post card — replaces Python _post_card_sx
|
||||
|
||||
Reference in New Issue
Block a user