You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

issue_stopwatch.go 2.4KB

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