code.gitea.io/gitea@v1.21.7/routers/web/repo/issue_stopwatch.go (about) 1 // Copyright 2017 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package repo 5 6 import ( 7 "net/http" 8 "strings" 9 10 "code.gitea.io/gitea/models/db" 11 issues_model "code.gitea.io/gitea/models/issues" 12 "code.gitea.io/gitea/modules/context" 13 "code.gitea.io/gitea/modules/eventsource" 14 ) 15 16 // IssueStopwatch creates or stops a stopwatch for the given issue. 17 func IssueStopwatch(c *context.Context) { 18 issue := GetActionIssue(c) 19 if c.Written() { 20 return 21 } 22 23 var showSuccessMessage bool 24 25 if !issues_model.StopwatchExists(c, c.Doer.ID, issue.ID) { 26 showSuccessMessage = true 27 } 28 29 if !c.Repo.CanUseTimetracker(issue, c.Doer) { 30 c.NotFound("CanUseTimetracker", nil) 31 return 32 } 33 34 if err := issues_model.CreateOrStopIssueStopwatch(c, c.Doer, issue); err != nil { 35 c.ServerError("CreateOrStopIssueStopwatch", err) 36 return 37 } 38 39 if showSuccessMessage { 40 c.Flash.Success(c.Tr("repo.issues.tracker_auto_close")) 41 } 42 43 url := issue.Link() 44 c.Redirect(url, http.StatusSeeOther) 45 } 46 47 // CancelStopwatch cancel the stopwatch 48 func CancelStopwatch(c *context.Context) { 49 issue := GetActionIssue(c) 50 if c.Written() { 51 return 52 } 53 if !c.Repo.CanUseTimetracker(issue, c.Doer) { 54 c.NotFound("CanUseTimetracker", nil) 55 return 56 } 57 58 if err := issues_model.CancelStopwatch(c, c.Doer, issue); err != nil { 59 c.ServerError("CancelStopwatch", err) 60 return 61 } 62 63 stopwatches, err := issues_model.GetUserStopwatches(c, c.Doer.ID, db.ListOptions{}) 64 if err != nil { 65 c.ServerError("GetUserStopwatches", err) 66 return 67 } 68 if len(stopwatches) == 0 { 69 eventsource.GetManager().SendMessage(c.Doer.ID, &eventsource.Event{ 70 Name: "stopwatches", 71 Data: "{}", 72 }) 73 } 74 75 url := issue.Link() 76 c.Redirect(url, http.StatusSeeOther) 77 } 78 79 // GetActiveStopwatch is the middleware that sets .ActiveStopwatch on context 80 func GetActiveStopwatch(ctx *context.Context) { 81 if strings.HasPrefix(ctx.Req.URL.Path, "/api") { 82 return 83 } 84 85 if !ctx.IsSigned { 86 return 87 } 88 89 _, sw, issue, err := issues_model.HasUserStopwatch(ctx, ctx.Doer.ID) 90 if err != nil { 91 ctx.ServerError("HasUserStopwatch", err) 92 return 93 } 94 95 if sw == nil || sw.ID == 0 { 96 return 97 } 98 99 ctx.Data["ActiveStopwatch"] = StopwatchTmplInfo{ 100 issue.Link(), 101 issue.Repo.FullName(), 102 issue.Index, 103 sw.Seconds() + 1, // ensure time is never zero in ui 104 } 105 } 106 107 // StopwatchTmplInfo is a view on a stopwatch specifically for template rendering 108 type StopwatchTmplInfo struct { 109 IssueLink string 110 RepoSlug string 111 IssueIndex int64 112 Seconds int64 113 }