code.gitea.io/gitea@v1.21.7/routers/api/v1/notify/user.go (about) 1 // Copyright 2020 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package notify 5 6 import ( 7 "net/http" 8 "time" 9 10 activities_model "code.gitea.io/gitea/models/activities" 11 "code.gitea.io/gitea/modules/context" 12 "code.gitea.io/gitea/modules/structs" 13 "code.gitea.io/gitea/services/convert" 14 ) 15 16 // ListNotifications list users's notification threads 17 func ListNotifications(ctx *context.APIContext) { 18 // swagger:operation GET /notifications notification notifyGetList 19 // --- 20 // summary: List users's notification threads 21 // consumes: 22 // - application/json 23 // produces: 24 // - application/json 25 // parameters: 26 // - name: all 27 // in: query 28 // description: If true, show notifications marked as read. Default value is false 29 // type: boolean 30 // - name: status-types 31 // in: query 32 // description: "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned." 33 // type: array 34 // collectionFormat: multi 35 // items: 36 // type: string 37 // - name: subject-type 38 // in: query 39 // description: "filter notifications by subject type" 40 // type: array 41 // collectionFormat: multi 42 // items: 43 // type: string 44 // enum: [issue,pull,commit,repository] 45 // - name: since 46 // in: query 47 // description: Only show notifications updated after the given time. This is a timestamp in RFC 3339 format 48 // type: string 49 // format: date-time 50 // - name: before 51 // in: query 52 // description: Only show notifications updated before the given time. This is a timestamp in RFC 3339 format 53 // type: string 54 // format: date-time 55 // - name: page 56 // in: query 57 // description: page number of results to return (1-based) 58 // type: integer 59 // - name: limit 60 // in: query 61 // description: page size of results 62 // type: integer 63 // responses: 64 // "200": 65 // "$ref": "#/responses/NotificationThreadList" 66 opts := getFindNotificationOptions(ctx) 67 if ctx.Written() { 68 return 69 } 70 71 totalCount, err := activities_model.CountNotifications(ctx, opts) 72 if err != nil { 73 ctx.InternalServerError(err) 74 return 75 } 76 77 nl, err := activities_model.GetNotifications(ctx, opts) 78 if err != nil { 79 ctx.InternalServerError(err) 80 return 81 } 82 err = nl.LoadAttributes(ctx) 83 if err != nil { 84 ctx.InternalServerError(err) 85 return 86 } 87 88 ctx.SetTotalCountHeader(totalCount) 89 ctx.JSON(http.StatusOK, convert.ToNotifications(ctx, nl)) 90 } 91 92 // ReadNotifications mark notification threads as read, unread, or pinned 93 func ReadNotifications(ctx *context.APIContext) { 94 // swagger:operation PUT /notifications notification notifyReadList 95 // --- 96 // summary: Mark notification threads as read, pinned or unread 97 // consumes: 98 // - application/json 99 // produces: 100 // - application/json 101 // parameters: 102 // - name: last_read_at 103 // in: query 104 // description: Describes the last point that notifications were checked. Anything updated since this time will not be updated. 105 // type: string 106 // format: date-time 107 // required: false 108 // - name: all 109 // in: query 110 // description: If true, mark all notifications on this repo. Default value is false 111 // type: string 112 // required: false 113 // - name: status-types 114 // in: query 115 // description: "Mark notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread." 116 // type: array 117 // collectionFormat: multi 118 // items: 119 // type: string 120 // required: false 121 // - name: to-status 122 // in: query 123 // description: Status to mark notifications as, Defaults to read. 124 // type: string 125 // required: false 126 // responses: 127 // "205": 128 // "$ref": "#/responses/NotificationThreadList" 129 130 lastRead := int64(0) 131 qLastRead := ctx.FormTrim("last_read_at") 132 if len(qLastRead) > 0 { 133 tmpLastRead, err := time.Parse(time.RFC3339, qLastRead) 134 if err != nil { 135 ctx.Error(http.StatusBadRequest, "Parse", err) 136 return 137 } 138 if !tmpLastRead.IsZero() { 139 lastRead = tmpLastRead.Unix() 140 } 141 } 142 opts := &activities_model.FindNotificationOptions{ 143 UserID: ctx.Doer.ID, 144 UpdatedBeforeUnix: lastRead, 145 } 146 if !ctx.FormBool("all") { 147 statuses := ctx.FormStrings("status-types") 148 opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread"}) 149 } 150 nl, err := activities_model.GetNotifications(ctx, opts) 151 if err != nil { 152 ctx.InternalServerError(err) 153 return 154 } 155 156 targetStatus := statusStringToNotificationStatus(ctx.FormString("to-status")) 157 if targetStatus == 0 { 158 targetStatus = activities_model.NotificationStatusRead 159 } 160 161 changed := make([]*structs.NotificationThread, 0, len(nl)) 162 163 for _, n := range nl { 164 notif, err := activities_model.SetNotificationStatus(ctx, n.ID, ctx.Doer, targetStatus) 165 if err != nil { 166 ctx.InternalServerError(err) 167 return 168 } 169 _ = notif.LoadAttributes(ctx) 170 changed = append(changed, convert.ToNotificationThread(ctx, notif)) 171 } 172 173 ctx.JSON(http.StatusResetContent, changed) 174 }