This repository has no description
0

Configure Feed

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

core / appview / xrpc / focus.go
3.0 kB 119 lines
1package xrpc 2 3import ( 4 "encoding/json" 5 "net/http" 6 7 "tangled.org/core/api/tangled" 8 "tangled.org/core/appview/db" 9 "tangled.org/core/appview/models" 10 xrpcerr "tangled.org/core/xrpc/errors" 11) 12 13func (x *Xrpc) FocusBegin(w http.ResponseWriter, r *http.Request) { 14 l := x.Logger.With("handler", "FocusBegin") 15 16 did, ok := actorDid(r) 17 if !ok { 18 writeError(w, xrpcerr.MissingActorDidError, http.StatusForbidden) 19 return 20 } 21 22 if err := db.BeginFocus(x.DB, did); err != nil { 23 l.Error("failed to begin focus", "err", err) 24 writeError(w, errInternal, http.StatusInternalServerError) 25 return 26 } 27 28 item, err := db.GetNextFocusItem(x.DB, did) 29 if err != nil { 30 l.Error("failed to get first focus item", "err", err) 31 _ = db.EndFocus(x.DB, did) 32 writeError(w, errInternal, http.StatusInternalServerError) 33 return 34 } 35 36 if item == nil { 37 _ = db.EndFocus(x.DB, did) 38 x.writeJSON(w, &tangled.TempFocusBeginSession_Output{}) 39 return 40 } 41 42 out := &tangled.TempFocusBeginSession_Output{NotificationId: &item.ID} 43 setFocusSubject(item, &out.RepoDid, &out.IssueAt, &out.PullAt) 44 45 x.writeJSON(w, out) 46} 47 48func (x *Xrpc) FocusNext(w http.ResponseWriter, r *http.Request) { 49 l := x.Logger.With("handler", "FocusNext") 50 51 did, ok := actorDid(r) 52 if !ok { 53 writeError(w, xrpcerr.MissingActorDidError, http.StatusForbidden) 54 return 55 } 56 57 var input tangled.TempFocusNextItem_Input 58 if err := json.NewDecoder(r.Body).Decode(&input); err != nil { 59 writeError(w, errBadRequestBody, http.StatusBadRequest) 60 return 61 } 62 63 if err := db.MarkNotificationRead(x.DB, input.CurrentId, did); err != nil { 64 l.Warn("failed to mark notification read", "id", input.CurrentId, "err", err) 65 } 66 67 item, err := db.GetNextFocusItem(x.DB, did) 68 if err != nil { 69 l.Error("failed to get next focus item", "err", err) 70 writeError(w, errInternal, http.StatusInternalServerError) 71 return 72 } 73 74 if item == nil { 75 _ = db.EndFocus(x.DB, did) 76 x.writeJSON(w, &tangled.TempFocusNextItem_Output{}) 77 return 78 } 79 80 out := &tangled.TempFocusNextItem_Output{NotificationId: &item.ID} 81 setFocusSubject(item, &out.RepoDid, &out.IssueAt, &out.PullAt) 82 83 x.writeJSON(w, out) 84} 85 86func (x *Xrpc) FocusEnd(w http.ResponseWriter, r *http.Request) { 87 l := x.Logger.With("handler", "FocusEnd") 88 89 did, ok := actorDid(r) 90 if !ok { 91 writeError(w, xrpcerr.MissingActorDidError, http.StatusForbidden) 92 return 93 } 94 95 if err := db.EndFocus(x.DB, did); err != nil { 96 l.Error("failed to end focus", "err", err) 97 writeError(w, errInternal, http.StatusInternalServerError) 98 return 99 } 100 101 w.WriteHeader(http.StatusOK) 102} 103 104// setFocusSubject fills the repo did and (issue|pull) at-uri of a focus item so 105// the client can navigate to it. 106func setFocusSubject(n *models.NotificationWithEntity, repoDid, issueAt, pullAt **string) { 107 if n.Repo != nil { 108 s := n.Repo.RepoDid 109 *repoDid = &s 110 } 111 if n.Issue != nil { 112 s := n.Issue.AtUri().String() 113 *issueAt = &s 114 } 115 if n.Pull != nil { 116 s := n.Pull.AtUri().String() 117 *pullAt = &s 118 } 119}