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