[MM-41185]: new API to mark thread as unread (#19951)
* [MM-41185]: new API to mark thread as unread
Until now we mark a thread as read/unread by sending a timestamp to the
server. This created some issues when marking a thread as unread from a
post. We needed to send the post.create_at - 1 as a timestamp but we
didn't do so consistently.
This commit adds a new API to set a thread as unread by post id.
Making all clients agnostic of the timestamp, and thus solving consistency issues.
Endpoint: /api/v4/users/{user_id}/teams/{team_id}/threads/{thread_id}/set_unread/{post_id}
* Updates client.go adding SetThreadUnreadByPostId
* Guards endpoint behind read channel permission
* Returns status 400 if post_id not belong in thread
* Root post as post_id should be permitted
Этот коммит содержится в:
37
api4/user.go
37
api4/user.go
@@ -102,6 +102,7 @@ func (api *API) InitUser() {
|
||||
api.BaseRoutes.UserThread.Handle("/following", api.APISessionRequired(followThreadByUser)).Methods("PUT")
|
||||
api.BaseRoutes.UserThread.Handle("/following", api.APISessionRequired(unfollowThreadByUser)).Methods("DELETE")
|
||||
api.BaseRoutes.UserThread.Handle("/read/{timestamp:[0-9]+}", api.APISessionRequired(updateReadStateThreadByUser)).Methods("PUT")
|
||||
api.BaseRoutes.UserThread.Handle("/set_unread/{post_id:[A-Za-z0-9]+}", api.APISessionRequired(setUnreadThreadByPostId)).Methods("POST")
|
||||
}
|
||||
|
||||
func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
@@ -3097,6 +3098,42 @@ func updateReadStateThreadByUser(c *Context, w http.ResponseWriter, r *http.Requ
|
||||
auditRec.Success()
|
||||
}
|
||||
|
||||
func setUnreadThreadByPostId(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.RequireUserId().RequireThreadId().RequirePostId().RequireTeamId()
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("setUnreadThreadByPostId", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("user_id", c.Params.UserId)
|
||||
auditRec.AddMeta("thread_id", c.Params.ThreadId)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
auditRec.AddMeta("post_id", c.Params.PostId)
|
||||
|
||||
if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
|
||||
c.SetPermissionError(model.PermissionEditOtherUsers)
|
||||
return
|
||||
}
|
||||
|
||||
if !c.App.SessionHasPermissionToChannelByPost(*c.AppContext.Session(), c.Params.ThreadId, model.PermissionReadChannel) {
|
||||
c.SetPermissionError(model.PermissionReadChannel)
|
||||
return
|
||||
}
|
||||
|
||||
thread, err := c.App.UpdateThreadReadForUserByPost(c.AppContext.Session().Id, c.Params.UserId, c.Params.TeamId, c.Params.ThreadId, c.Params.PostId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(w).Encode(thread); err != nil {
|
||||
mlog.Warn("Error while writing response", mlog.Err(err))
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
}
|
||||
|
||||
func unfollowThreadByUser(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.RequireUserId().RequireThreadId().RequireTeamId()
|
||||
if c.Err != nil {
|
||||
|
||||
Ссылка в новой задаче
Block a user