Monorepo for Tangled tangled.org

appview/state: add the ability to remove your avatar #1013

merged opened by anirudh.fi targeting master from icy/tolqpt
Labels

None yet.

assignee

None yet.

Participants 2
AT URI
at://did:plc:hwevmowznbiukdf6uk5dwrrq/sh.tangled.repo.pull/3mcz4xlifg722
+97 -12
Diff #0
+19 -10
appview/pages/templates/user/fragments/editAvatar.html
··· 6 6 hx-swap="none" 7 7 class="flex flex-col gap-2"> 8 8 <label for="avatar-file" class="uppercase p-0"> 9 - Upload avatar 9 + Upload or Remove Avatar 10 10 </label> 11 - <p class="text-sm text-gray-500 dark:text-gray-400">Select an image (PNG or JPEG, max 1MB)</p> 11 + <p class="text-sm text-gray-500 dark:text-gray-400">Upload a new image (PNG or JPEG, max 1MB) or remove your current avatar.</p> 12 12 <input 13 13 type="file" 14 14 id="avatar-file" ··· 23 23 dark:file:bg-gray-700 dark:file:text-gray-300 24 24 hover:file:bg-gray-200 dark:hover:file:bg-gray-600" /> 25 25 <div id="avatar-error" class="text-red-500 dark:text-red-400 text-sm min-h-5"></div> 26 - <div class="flex gap-2 pt-2"> 26 + <div class="flex flex-col gap-2 pt-2"> 27 + <button type="submit" class="btn w-full flex items-center justify-center gap-2"> 28 + <span class="inline-flex gap-2 items-center">{{ i "upload" "size-4" }} upload</span> 29 + <span id="spinner" class="group"> 30 + {{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 31 + </span> 32 + </button> 33 + <button 34 + type="button" 35 + hx-delete="/profile/avatar" 36 + hx-confirm="Are you sure you want to remove your profile picture?" 37 + hx-swap="none" 38 + class="btn w-full flex items-center justify-center gap-2"> 39 + {{ i "trash-2" "size-4" }} 40 + remove avatar 41 + </button> 27 42 <button 28 43 id="cancel-avatar-btn" 29 44 type="button" 30 45 popovertarget="avatar-upload-modal" 31 46 popovertargetaction="hide" 32 - class="btn w-1/2 flex items-center gap-2 text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"> 47 + class="btn w-full flex items-center justify-center gap-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"> 33 48 {{ i "x" "size-4" }} 34 49 cancel 35 50 </button> 36 - <button type="submit" class="btn w-1/2 flex items-center"> 37 - <span class="inline-flex gap-2 items-center">{{ i "upload" "size-4" }} upload</span> 38 - <span id="spinner" class="group"> 39 - {{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 40 - </span> 41 - </button> 42 51 </div> 43 52 </form> 44 53 {{ end }}
+77 -2
appview/state/profile.go
··· 851 851 return 852 852 } 853 853 854 - w.Header().Set("HX-Redirect", r.Header.Get("Referer")) 855 - w.WriteHeader(http.StatusOK) 854 + s.pages.HxRedirect(w, r.Header.Get("Referer")) 855 + } 856 + 857 + func (s *State) RemoveProfileAvatar(w http.ResponseWriter, r *http.Request) { 858 + l := s.logger.With("handler", "RemoveProfileAvatar") 859 + user := s.oauth.GetUser(r) 860 + l = l.With("did", user.Did) 861 + 862 + client, err := s.oauth.AuthorizedClient(r) 863 + if err != nil { 864 + l.Error("failed to get PDS client", "err", err) 865 + s.pages.Notice(w, "avatar-error", "Failed to connect to your PDS") 866 + return 867 + } 868 + 869 + getRecordResp, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.ActorProfileNSID, user.Did, "self") 870 + if err != nil { 871 + l.Error("failed to get current profile record", "err", err) 872 + s.pages.Notice(w, "avatar-error", "Failed to get current profile from your PDS") 873 + return 874 + } 875 + 876 + var profileRecord *tangled.ActorProfile 877 + if getRecordResp.Value != nil { 878 + if val, ok := getRecordResp.Value.Val.(*tangled.ActorProfile); ok { 879 + profileRecord = val 880 + } else { 881 + l.Warn("profile record type assertion failed") 882 + profileRecord = &tangled.ActorProfile{} 883 + } 884 + } else { 885 + l.Warn("no existing profile record") 886 + profileRecord = &tangled.ActorProfile{} 887 + } 888 + 889 + profileRecord.Avatar = nil 890 + 891 + _, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ 892 + Collection: tangled.ActorProfileNSID, 893 + Repo: user.Did, 894 + Rkey: "self", 895 + Record: &lexutil.LexiconTypeDecoder{Val: profileRecord}, 896 + SwapRecord: getRecordResp.Cid, 897 + }) 898 + 899 + if err != nil { 900 + l.Error("failed to update profile record", "err", err) 901 + s.pages.Notice(w, "avatar-error", "Failed to remove avatar from your PDS") 902 + return 903 + } 904 + 905 + l.Info("successfully removed avatar from PDS") 906 + 907 + profile, err := db.GetProfile(s.db, user.Did) 908 + if err != nil { 909 + l.Warn("getting profile data from DB", "err", err) 910 + profile = &models.Profile{Did: user.Did} 911 + } 912 + profile.Avatar = "" 913 + 914 + tx, err := s.db.BeginTx(r.Context(), nil) 915 + if err != nil { 916 + l.Error("failed to start transaction", "err", err) 917 + s.pages.HxRefresh(w) 918 + w.WriteHeader(http.StatusOK) 919 + return 920 + } 921 + 922 + err = db.UpsertProfile(tx, profile) 923 + if err != nil { 924 + l.Error("failed to update profile in DB", "err", err) 925 + s.pages.HxRefresh(w) 926 + w.WriteHeader(http.StatusOK) 927 + return 928 + } 929 + 930 + s.pages.HxRedirect(w, r.Header.Get("Referer")) 856 931 }
+1
appview/state/router.go
··· 166 166 r.Post("/bio", s.UpdateProfileBio) 167 167 r.Post("/pins", s.UpdateProfilePins) 168 168 r.Post("/avatar", s.UploadProfileAvatar) 169 + r.Delete("/avatar", s.RemoveProfileAvatar) 169 170 }) 170 171 171 172 r.Mount("/settings", s.SettingsRouter())

History

1 round 2 comments
sign up or login to add to the discussion
anirudh.fi submitted #0
1 commit
expand
appview/state: add the ability to remove your avatar
3/3 success
expand
expand 2 comments

this works pretty nicely. i think there is an issue with the CDN however... my account oppili.tngl.sh has no profile record but the profile picture renders my old profile picture:

  • link to profile: @oppili.tngl.sh
  • link to avatar: here
pull request successfully merged