Monorepo for Tangled
0

Configure Feed

Select the types of activity you want to include in your feed.

appview/pages: htmxify keys handlers

Signed-off-by: oppiliappan <me@oppi.li>

oppiliappan (Jul 7, 2026, 5:44 PM +0100) 488e120e f596566d

+25 -19
+1 -1
appview/pages/templates/layouts/profilebase.html
··· 30 30 {{ end }} 31 31 32 32 {{ define "content" }} 33 - {{ if not .Card.HasProfile }} 33 + {{ if not .Card.IsTangledUser }} 34 34 <section class="bg-white dark:bg-gray-800 px-2 py-6 md:p-6 rounded w-full dark:text-white shadow-sm"> 35 35 <div class="flex items-center gap-6 p-4"> 36 36 <img class="w-28 h-28 shrink-0 object-cover rounded-full" src="{{ profileAvatarUrl .Card.Profile "" }}" />
+8 -9
appview/pages/templates/user/settings/fragments/keyListing.html
··· 1 1 {{ define "user/settings/fragments/keyListing" }} 2 - {{ $root := index . 0 }} 3 - {{ $key := index . 1 }} 4 - <div id="key-{{$key.Name}}" class="flex items-center justify-between p-2"> 2 + <div id="key-{{.Name}}" class="flex items-center justify-between p-2"> 5 3 <div class="hover:no-underline flex flex-col gap-1 text min-w-0 max-w-[80%]"> 6 4 <div class="flex items-center gap-2"> 7 5 <span>{{ i "key" "w-4" "h-4" }}</span> 8 6 <span class="font-bold"> 9 - {{ $key.Name }} 7 + {{ .Name }} 10 8 </span> 11 9 </div> 12 10 <span class="font-mono text-sm text-gray-500 dark:text-gray-400"> 13 - {{ sshFingerprint $key.Key }} 11 + {{ sshFingerprint .Key }} 14 12 </span> 15 13 <div class="flex flex-wrap text-sm items-center gap-1 text-gray-500 dark:text-gray-400"> 16 - <span>added {{ template "repo/fragments/time" $key.Created }}</span> 14 + <span>added {{ template "repo/fragments/time" .Created }}</span> 17 15 </div> 18 16 </div> 19 17 <button 20 18 class="btn text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 gap-2 group" 21 19 title="Delete key" 22 - hx-delete="/settings/keys?name={{urlquery $key.Name}}&rkey={{urlquery $key.Rkey}}" 23 - hx-swap="none" 24 - hx-confirm="Are you sure you want to delete the key {{ $key.Name }}?" 20 + hx-delete="/settings/keys?name={{urlquery .Name}}&rkey={{urlquery .Rkey}}" 21 + hx-target="closest div" 22 + hx-swap="delete" 23 + hx-confirm="Are you sure you want to delete the key {{ .Name }}?" 25 24 > 26 25 {{ i "trash-2" "w-5 h-5" }} 27 26 <span class="hidden md:inline">Delete</span>
+5 -7
appview/pages/templates/user/settings/keys.html
··· 29 29 {{ template "addKeyButton" . }} 30 30 </div> 31 31 </div> 32 - <div class="flex flex-col rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700 w-full"> 32 + <div id="keys-list" class="flex flex-col rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700 w-full [&:not(:has(*))]:hidden"> 33 33 {{ range .PubKeys }} 34 - {{ template "user/settings/fragments/keyListing" (list $ .) }} 35 - {{ else }} 36 - <div class="flex items-center justify-center p-2 text-gray-500"> 37 - No keys added yet 38 - </div> 34 + {{ template "user/settings/fragments/keyListing" . }} 39 35 {{ end }} 40 36 </div> 41 37 {{ end }} ··· 60 56 <form 61 57 hx-put="/settings/keys" 62 58 hx-indicator="#spinner" 63 - hx-swap="none" 59 + hx-target="#keys-list" 60 + hx-swap="beforeend" 61 + hx-on:keyadded="this.reset(); this.closest('[popover]').hidePopover()" 64 62 class="flex flex-col gap-2" 65 63 > 66 64 <label for="key-name" class="text-lg font-medium p-0">
+11 -2
appview/settings/settings.go
··· 275 275 IsDeactivated: isDeactivated, 276 276 HandleOpen: r.URL.Query().Get("handle") == "1", 277 277 }) 278 + if err != nil { 279 + s.Logger.Error("failed to render settings page", "err", err) 280 + } 278 281 } 279 282 280 283 func (s *Settings) notificationsSettings(w http.ResponseWriter, r *http.Request) { ··· 680 683 return 681 684 } 682 685 683 - s.Pages.HxLocation(w, "/settings/keys") 686 + // return just the new key row so the client appends it in place. the 687 + // keyadded trigger lets the form reset/close only on success (errors go 688 + // through Notice, which also returns 200). 689 + w.Header().Set("HX-Trigger", "keyadded") 690 + if err := s.Pages.KeyFragment(w, pubKey); err != nil { 691 + s.Logger.Error("failed to render key fragment", "err", err) 692 + } 684 693 return 685 694 686 695 case http.MethodDelete: ··· 728 737 } 729 738 s.Logger.Info("deleted key successfully", "name", name) 730 739 731 - s.Pages.HxLocation(w, "/settings/keys") 740 + w.WriteHeader(http.StatusOK) 732 741 return 733 742 } 734 743 }