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