Signed-off-by: Anirudh Oppiliappan anirudh@tangled.org
+19
-10
appview/pages/templates/user/fragments/editAvatar.html
+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
+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
}
History
1 round
2 comments
anirudh.fi
submitted
#0
1 commit
expand
collapse
appview/state: add the ability to remove your avatar
Signed-off-by: Anirudh Oppiliappan <anirudh@tangled.org>
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: