Store and use seconds for timeline time comments (#25392)

this will allow us to fully localize it later

PS: we can not migrate back as the old value was a one-way conversion


prepare for  #25213

---
*Sponsored by Kithara Software GmbH*
This commit is contained in:
6543 2023-06-23 14:12:39 +02:00 committed by GitHub
parent a954c93a68
commit b0215c40cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 67 additions and 18 deletions

View file

@ -6,6 +6,7 @@ package issues
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"time" "time"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
@ -173,10 +174,12 @@ func AddTime(user *user_model.User, issue *Issue, amount int64, created time.Tim
} }
if _, err := CreateComment(ctx, &CreateCommentOptions{ if _, err := CreateComment(ctx, &CreateCommentOptions{
Issue: issue, Issue: issue,
Repo: issue.Repo, Repo: issue.Repo,
Doer: user, Doer: user,
Content: util.SecToTime(amount), // Content before v1.21 did store the formated string instead of seconds,
// so use "|" as delimeter to mark the new format
Content: fmt.Sprintf("|%d", amount),
Type: CommentTypeAddTimeManual, Type: CommentTypeAddTimeManual,
TimeID: t.ID, TimeID: t.ID,
}); err != nil { }); err != nil {
@ -251,10 +254,12 @@ func DeleteIssueUserTimes(issue *Issue, user *user_model.User) error {
return err return err
} }
if _, err := CreateComment(ctx, &CreateCommentOptions{ if _, err := CreateComment(ctx, &CreateCommentOptions{
Issue: issue, Issue: issue,
Repo: issue.Repo, Repo: issue.Repo,
Doer: user, Doer: user,
Content: "- " + util.SecToTime(removedTime), // Content before v1.21 did store the formated string instead of seconds,
// so use "|" as delimeter to mark the new format
Content: fmt.Sprintf("|%d", removedTime),
Type: CommentTypeDeleteTimeManual, Type: CommentTypeDeleteTimeManual,
}); err != nil { }); err != nil {
return err return err
@ -280,10 +285,12 @@ func DeleteTime(t *TrackedTime) error {
} }
if _, err := CreateComment(ctx, &CreateCommentOptions{ if _, err := CreateComment(ctx, &CreateCommentOptions{
Issue: t.Issue, Issue: t.Issue,
Repo: t.Issue.Repo, Repo: t.Issue.Repo,
Doer: t.User, Doer: t.User,
Content: "- " + util.SecToTime(t.Time), // Content before v1.21 did store the formated string instead of seconds,
// so use "|" as delimeter to mark the new format
Content: fmt.Sprintf("|%d", t.Time),
Type: CommentTypeDeleteTimeManual, Type: CommentTypeDeleteTimeManual,
}); err != nil { }); err != nil {
return err return err

View file

@ -35,7 +35,7 @@ func TestAddTime(t *testing.T) {
assert.Equal(t, int64(3661), tt.Time) assert.Equal(t, int64(3661), tt.Time)
comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeAddTimeManual, PosterID: 3, IssueID: 1}) comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeAddTimeManual, PosterID: 3, IssueID: 1})
assert.Equal(t, "1 hour 1 minute", comment.Content) assert.Equal(t, "|3661", comment.Content)
} }
func TestGetTrackedTimes(t *testing.T) { func TestGetTrackedTimes(t *testing.T) {

View file

@ -15,7 +15,9 @@ import (
// 1563418 -> 2 weeks 4 days // 1563418 -> 2 weeks 4 days
// 3937125s -> 1 month 2 weeks // 3937125s -> 1 month 2 weeks
// 45677465s -> 1 year 6 months // 45677465s -> 1 year 6 months
func SecToTime(duration int64) string { func SecToTime(durationVal any) string {
duration, _ := ToInt64(durationVal)
formattedTime := "" formattedTime := ""
// The following four variables are calculated by taking // The following four variables are calculated by taking

View file

@ -1647,9 +1647,22 @@ func ViewIssue(ctx *context.Context) {
return return
} }
} else if comment.Type == issues_model.CommentTypeAddTimeManual || } else if comment.Type == issues_model.CommentTypeAddTimeManual ||
comment.Type == issues_model.CommentTypeStopTracking { comment.Type == issues_model.CommentTypeStopTracking ||
comment.Type == issues_model.CommentTypeDeleteTimeManual {
// drop error since times could be pruned from DB.. // drop error since times could be pruned from DB..
_ = comment.LoadTime() _ = comment.LoadTime()
if comment.Content != "" {
// Content before v1.21 did store the formated string instead of seconds,
// so "|" is used as delimeter to mark the new format
if comment.Content[0] != '|' {
// handle old time comments that have formatted text stored
comment.RenderedContent = comment.Content
comment.Content = ""
} else {
// else it's just a duration in seconds to pass on to the frontend
comment.Content = comment.Content[1:]
}
}
} }
if comment.Type == issues_model.CommentTypeClose || comment.Type == issues_model.CommentTypeMergePull { if comment.Type == issues_model.CommentTypeClose || comment.Type == issues_model.CommentTypeMergePull {

View file

@ -11,6 +11,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
) )
// ToComment converts a issues_model.Comment to the api.Comment format // ToComment converts a issues_model.Comment to the api.Comment format
@ -66,6 +67,17 @@ func ToTimelineComment(ctx context.Context, c *issues_model.Comment, doer *user_
return nil return nil
} }
if c.Content != "" {
if (c.Type == issues_model.CommentTypeAddTimeManual ||
c.Type == issues_model.CommentTypeStopTracking ||
c.Type == issues_model.CommentTypeDeleteTimeManual) &&
c.Content[0] == '|' {
// TimeTracking Comments from v1.21 on store the seconds instead of an formated string
// so we check for the "|" delimeter and convert new to legacy format on demand
c.Content = util.SecToTime(c.Content[1:])
}
}
comment := &api.TimelineComment{ comment := &api.TimelineComment{
ID: c.ID, ID: c.ID,
Type: c.Type.String(), Type: c.Type.String(),

View file

@ -263,7 +263,12 @@
{{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}} {{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}}
<div class="detail"> <div class="detail">
{{svg "octicon-clock"}} {{svg "octicon-clock"}}
<span class="text grey muted-links">{{.Content}}</span> {{if .RenderedContent}}
{{/* compatibility with time comments made before v1.21 */}}
<span class="text grey muted-links">{{.RenderedContent}}</span>
{{else}}
<span class="text grey muted-links">{{.Content|Sec2Time}}</span>
{{end}}
</div> </div>
</div> </div>
{{else if eq .Type 14}} {{else if eq .Type 14}}
@ -277,7 +282,12 @@
{{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}} {{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}}
<div class="detail"> <div class="detail">
{{svg "octicon-clock"}} {{svg "octicon-clock"}}
<span class="text grey muted-links">{{.Content}}</span> {{if .RenderedContent}}
{{/* compatibility with time comments made before v1.21 */}}
<span class="text grey muted-links">{{.RenderedContent}}</span>
{{else}}
<span class="text grey muted-links">{{.Content|Sec2Time}}</span>
{{end}}
</div> </div>
</div> </div>
{{else if eq .Type 15}} {{else if eq .Type 15}}
@ -676,7 +686,12 @@
</span> </span>
<div class="detail"> <div class="detail">
{{svg "octicon-clock"}} {{svg "octicon-clock"}}
<span class="text grey muted-links">{{.Content}}</span> {{if .RenderedContent}}
{{/* compatibility with time comments made before v1.21 */}}
<span class="text grey muted-links">{{.RenderedContent}}</span>
{{else}}
<span class="text grey muted-links">- {{.Content|Sec2Time}}</span>
{{end}}
</div> </div>
</div> </div>
{{else if eq .Type 27}} {{else if eq .Type 27}}