From 4df03a346579fd013615244fffca1a0345046a47 Mon Sep 17 00:00:00 2001 From: "m.huber" Date: Tue, 20 Jun 2023 15:32:58 +0200 Subject: [PATCH 01/10] store and use seconds for timeline time comments this will alow us to fully localize it later PS: we can not migrate back as the old value was a one-way conversion --- models/issues/tracked_time.go | 3 ++- templates/repo/issue/view_content/comments.tmpl | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/models/issues/tracked_time.go b/models/issues/tracked_time.go index 698014afeba54..a16d0ac90bc0e 100644 --- a/models/issues/tracked_time.go +++ b/models/issues/tracked_time.go @@ -6,6 +6,7 @@ package issues import ( "context" "errors" + "fmt" "time" "code.gitea.io/gitea/models/db" @@ -176,7 +177,7 @@ func AddTime(user *user_model.User, issue *Issue, amount int64, created time.Tim Issue: issue, Repo: issue.Repo, Doer: user, - Content: util.SecToTime(amount), + Content: fmt.Sprintf("|%d", amount), Type: CommentTypeAddTimeManual, TimeID: t.ID, }); err != nil { diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index bfcd292f44c32..a37ad8c60adb2 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -263,7 +263,12 @@ {{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}}
{{svg "octicon-clock"}} - {{.Content}} + {{if .RenderedContent}} + {{/* compatibility with time comments made before v1.21 */}} + {{.RenderedContent}} + {{else}} + {{.Content|Sec2Time}} + {{end}}
{{else if eq .Type 14}} @@ -277,7 +282,12 @@ {{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}}
{{svg "octicon-clock"}} - {{.Content}} + {{if .RenderedContent}} + {{/* compatibility with time comments made before v1.21 */}} + {{.RenderedContent}} + {{else}} + {{.Content|Sec2Time}} + {{end}}
{{else if eq .Type 15}} From c0e96f3bec75c4586bae8f8b362343d6f5ec0362 Mon Sep 17 00:00:00 2001 From: "m.huber" Date: Tue, 20 Jun 2023 15:48:53 +0200 Subject: [PATCH 02/10] next --- models/issues/tracked_time.go | 4 ++-- routers/web/repo/issue.go | 17 +++++++++++++++++ templates/repo/issue/view_content/comments.tmpl | 7 ++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/models/issues/tracked_time.go b/models/issues/tracked_time.go index a16d0ac90bc0e..023c0141860bc 100644 --- a/models/issues/tracked_time.go +++ b/models/issues/tracked_time.go @@ -255,7 +255,7 @@ func DeleteIssueUserTimes(issue *Issue, user *user_model.User) error { Issue: issue, Repo: issue.Repo, Doer: user, - Content: "- " + util.SecToTime(removedTime), + Content: fmt.Sprint(removedTime), Type: CommentTypeDeleteTimeManual, }); err != nil { return err @@ -284,7 +284,7 @@ func DeleteTime(t *TrackedTime) error { Issue: t.Issue, Repo: t.Issue.Repo, Doer: t.User, - Content: "- " + util.SecToTime(t.Time), + Content: fmt.Sprint(t.Time), Type: CommentTypeDeleteTimeManual, }); err != nil { return err diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 49ba753a7d34e..57168ac1989f1 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -1650,6 +1650,23 @@ func ViewIssue(ctx *context.Context) { comment.Type == issues_model.CommentTypeStopTracking { // drop error since times could be pruned from DB.. _ = comment.LoadTime() + if comment.Content != "" { + 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:] + } + } + } else if comment.Type == issues_model.CommentTypeDeleteTimeManual && comment.Content != "" { + if comment.Content[0] == '-' { + // handle old time comments that have formatted text stored + comment.RenderedContent = comment.Content + comment.Content = "" + } + // else it's just a duration in seconds to pass on to the frontend } if comment.Type == issues_model.CommentTypeClose || comment.Type == issues_model.CommentTypeMergePull { diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index a37ad8c60adb2..d9c9cda7a249d 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -686,7 +686,12 @@
{{svg "octicon-clock"}} - {{.Content}} + {{if .RenderedContent}} + {{/* compatibility with time comments made before v1.21 */}} + {{.RenderedContent}} + {{else}} + - {{.Content|Sec2Time}} + {{end}}
{{else if eq .Type 27}} From 5e0e77c3e54974d04e65c6c7997095d59e2e13a8 Mon Sep 17 00:00:00 2001 From: "m.huber" Date: Tue, 20 Jun 2023 15:59:57 +0200 Subject: [PATCH 03/10] need helper until we convert time in frontend --- modules/templates/util_string.go | 6 ++++++ templates/repo/issue/view_content/comments.tmpl | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/templates/util_string.go b/modules/templates/util_string.go index 459380aee5312..02a2a630c3a5d 100644 --- a/modules/templates/util_string.go +++ b/modules/templates/util_string.go @@ -4,6 +4,7 @@ package templates import ( + "strconv" "strings" "code.gitea.io/gitea/modules/base" @@ -36,3 +37,8 @@ func (su *StringUtils) Join(a []string, sep string) string { func (su *StringUtils) EllipsisString(s string, max int) string { return base.EllipsisString(s, max) } + +func (su *StringUtils) ToInt(s string, max int) int64 { + i, _ := strconv.ParseInt(s, 10, 64) + return i +} diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index d9c9cda7a249d..7e8e6bb61d1eb 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -267,7 +267,7 @@ {{/* compatibility with time comments made before v1.21 */}} {{.RenderedContent}} {{else}} - {{.Content|Sec2Time}} + {{.Content|StringUtils.ToInt|Sec2Time}} {{end}} @@ -286,7 +286,7 @@ {{/* compatibility with time comments made before v1.21 */}} {{.RenderedContent}} {{else}} - {{.Content|Sec2Time}} + {{.Content|StringUtils.ToInt|Sec2Time}} {{end}} @@ -690,7 +690,7 @@ {{/* compatibility with time comments made before v1.21 */}} {{.RenderedContent}} {{else}} - - {{.Content|Sec2Time}} + - {{.Content|StringUtils.ToInt|Sec2Time}} {{end}} From 3b4a0b81456ff4096cc45e94bcaa15a659807c5b Mon Sep 17 00:00:00 2001 From: "m.huber" Date: Tue, 20 Jun 2023 16:02:21 +0200 Subject: [PATCH 04/10] ... --- modules/templates/util_string.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/templates/util_string.go b/modules/templates/util_string.go index 02a2a630c3a5d..b19c45df5172e 100644 --- a/modules/templates/util_string.go +++ b/modules/templates/util_string.go @@ -38,7 +38,7 @@ func (su *StringUtils) EllipsisString(s string, max int) string { return base.EllipsisString(s, max) } -func (su *StringUtils) ToInt(s string, max int) int64 { +func (su *StringUtils) ToInt(s string) int64 { i, _ := strconv.ParseInt(s, 10, 64) return i } From b2cc1eed9699c19ac30edb16864d98213dfbba49 Mon Sep 17 00:00:00 2001 From: "m.huber" Date: Tue, 20 Jun 2023 16:35:01 +0200 Subject: [PATCH 05/10] non breaking API --- services/convert/issue_comment.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/services/convert/issue_comment.go b/services/convert/issue_comment.go index 2810c6c9bc91b..476de0bb43e99 100644 --- a/services/convert/issue_comment.go +++ b/services/convert/issue_comment.go @@ -5,12 +5,14 @@ package convert import ( "context" + "strconv" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/util" ) // ToComment converts a issues_model.Comment to the api.Comment format @@ -66,6 +68,22 @@ func ToTimelineComment(ctx context.Context, c *issues_model.Comment, doer *user_ return nil } + // for time tracking comments, we now store seconds + // so convert them for the API + if c.Content != "" { + if (c.Type == issues_model.CommentTypeAddTimeManual || + c.Type == issues_model.CommentTypeStopTracking) && + c.Content[0] == '|' { + i, _ := strconv.ParseInt(c.Content[1:], 10, 64) + c.Content = util.SecToTime(i) + } else if c.Type == issues_model.CommentTypeDeleteTimeManual { + if c.Content[0] != '-' { + i, _ := strconv.ParseInt(c.Content, 10, 64) + c.Content = "- " + util.SecToTime(i) + } + } + } + comment := &api.TimelineComment{ ID: c.ID, Type: c.Type.String(), From 99fbd23f1fcbae07428d0226ff5cd1f6dc57ba9a Mon Sep 17 00:00:00 2001 From: "m.huber" Date: Tue, 20 Jun 2023 16:38:01 +0200 Subject: [PATCH 06/10] code format --- services/convert/issue_comment.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/services/convert/issue_comment.go b/services/convert/issue_comment.go index 476de0bb43e99..15152e16f1780 100644 --- a/services/convert/issue_comment.go +++ b/services/convert/issue_comment.go @@ -76,11 +76,10 @@ func ToTimelineComment(ctx context.Context, c *issues_model.Comment, doer *user_ c.Content[0] == '|' { i, _ := strconv.ParseInt(c.Content[1:], 10, 64) c.Content = util.SecToTime(i) - } else if c.Type == issues_model.CommentTypeDeleteTimeManual { - if c.Content[0] != '-' { - i, _ := strconv.ParseInt(c.Content, 10, 64) - c.Content = "- " + util.SecToTime(i) - } + } else if c.Type == issues_model.CommentTypeDeleteTimeManual && + c.Content[0] != '-' { + i, _ := strconv.ParseInt(c.Content, 10, 64) + c.Content = "- " + util.SecToTime(i) } } From 81ba06a2da8ffa9e10965aef6d227c690f0eea44 Mon Sep 17 00:00:00 2001 From: "m.huber" Date: Tue, 20 Jun 2023 17:26:51 +0200 Subject: [PATCH 07/10] adjust test --- models/issues/tracked_time_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/issues/tracked_time_test.go b/models/issues/tracked_time_test.go index baa170b201265..37ba1cfdc4903 100644 --- a/models/issues/tracked_time_test.go +++ b/models/issues/tracked_time_test.go @@ -35,7 +35,7 @@ func TestAddTime(t *testing.T) { assert.Equal(t, int64(3661), tt.Time) 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) { From bbda83242af7def75b460a25976c748759ddd15f Mon Sep 17 00:00:00 2001 From: "m.huber" Date: Wed, 21 Jun 2023 01:44:33 +0200 Subject: [PATCH 08/10] document in code as descriptive as posible --- models/issues/tracked_time.go | 24 +++++++++++++++--------- routers/web/repo/issue.go | 2 ++ services/convert/issue_comment.go | 6 ++++-- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/models/issues/tracked_time.go b/models/issues/tracked_time.go index 023c0141860bc..cda5d0b74c492 100644 --- a/models/issues/tracked_time.go +++ b/models/issues/tracked_time.go @@ -174,9 +174,11 @@ func AddTime(user *user_model.User, issue *Issue, amount int64, created time.Tim } if _, err := CreateComment(ctx, &CreateCommentOptions{ - Issue: issue, - Repo: issue.Repo, - Doer: user, + Issue: issue, + Repo: issue.Repo, + Doer: user, + // 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, TimeID: t.ID, @@ -252,9 +254,11 @@ func DeleteIssueUserTimes(issue *Issue, user *user_model.User) error { return err } if _, err := CreateComment(ctx, &CreateCommentOptions{ - Issue: issue, - Repo: issue.Repo, - Doer: user, + Issue: issue, + Repo: issue.Repo, + Doer: user, + // Content before v1.21 did store the formated string instead of seconds, + // the legacy format starts with '- ' Content: fmt.Sprint(removedTime), Type: CommentTypeDeleteTimeManual, }); err != nil { @@ -281,9 +285,11 @@ func DeleteTime(t *TrackedTime) error { } if _, err := CreateComment(ctx, &CreateCommentOptions{ - Issue: t.Issue, - Repo: t.Issue.Repo, - Doer: t.User, + Issue: t.Issue, + Repo: t.Issue.Repo, + Doer: t.User, + // Content before v1.21 did store the formated string instead of seconds, + // the legacy format starts with '- ' Content: fmt.Sprint(t.Time), Type: CommentTypeDeleteTimeManual, }); err != nil { diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 57168ac1989f1..7954cbb21d8f2 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -1651,6 +1651,8 @@ func ViewIssue(ctx *context.Context) { // drop error since times could be pruned from DB.. _ = 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 diff --git a/services/convert/issue_comment.go b/services/convert/issue_comment.go index 15152e16f1780..7328acc181fae 100644 --- a/services/convert/issue_comment.go +++ b/services/convert/issue_comment.go @@ -68,16 +68,18 @@ func ToTimelineComment(ctx context.Context, c *issues_model.Comment, doer *user_ return nil } - // for time tracking comments, we now store seconds - // so convert them for the API if c.Content != "" { if (c.Type == issues_model.CommentTypeAddTimeManual || c.Type == issues_model.CommentTypeStopTracking) && 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 i, _ := strconv.ParseInt(c.Content[1:], 10, 64) c.Content = util.SecToTime(i) } else if 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 legacy format via "-" indicator and convert new to legacy format on demand i, _ := strconv.ParseInt(c.Content, 10, 64) c.Content = "- " + util.SecToTime(i) } From cd4e9c46029fc685cf24ef5c1a46e1913bdeb86b Mon Sep 17 00:00:00 2001 From: "m.huber" Date: Fri, 23 Jun 2023 13:31:22 +0200 Subject: [PATCH 09/10] rm helper and use any --- modules/templates/util_string.go | 6 ------ modules/util/sec_to_time.go | 4 +++- templates/repo/issue/view_content/comments.tmpl | 6 +++--- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/modules/templates/util_string.go b/modules/templates/util_string.go index b19c45df5172e..459380aee5312 100644 --- a/modules/templates/util_string.go +++ b/modules/templates/util_string.go @@ -4,7 +4,6 @@ package templates import ( - "strconv" "strings" "code.gitea.io/gitea/modules/base" @@ -37,8 +36,3 @@ func (su *StringUtils) Join(a []string, sep string) string { func (su *StringUtils) EllipsisString(s string, max int) string { return base.EllipsisString(s, max) } - -func (su *StringUtils) ToInt(s string) int64 { - i, _ := strconv.ParseInt(s, 10, 64) - return i -} diff --git a/modules/util/sec_to_time.go b/modules/util/sec_to_time.go index 017ed45f8c040..ad0fb1a68b4a7 100644 --- a/modules/util/sec_to_time.go +++ b/modules/util/sec_to_time.go @@ -15,7 +15,9 @@ import ( // 1563418 -> 2 weeks 4 days // 3937125s -> 1 month 2 weeks // 45677465s -> 1 year 6 months -func SecToTime(duration int64) string { +func SecToTime(durationVal any) string { + duration, _ := ToInt64(durationVal) + formattedTime := "" // The following four variables are calculated by taking diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index 0e87b8c63c4bb..5dbd530fa560b 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -267,7 +267,7 @@ {{/* compatibility with time comments made before v1.21 */}} {{.RenderedContent}} {{else}} - {{.Content|StringUtils.ToInt|Sec2Time}} + {{.Content|Sec2Time}} {{end}} @@ -286,7 +286,7 @@ {{/* compatibility with time comments made before v1.21 */}} {{.RenderedContent}} {{else}} - {{.Content|StringUtils.ToInt|Sec2Time}} + {{.Content|Sec2Time}} {{end}} @@ -690,7 +690,7 @@ {{/* compatibility with time comments made before v1.21 */}} {{.RenderedContent}} {{else}} - - {{.Content|StringUtils.ToInt|Sec2Time}} + - {{.Content|Sec2Time}} {{end}} From b6423ef8b103edd174451d899c4d2540bf09fc3a Mon Sep 17 00:00:00 2001 From: "m.huber" Date: Fri, 23 Jun 2023 13:40:29 +0200 Subject: [PATCH 10/10] use '|' for CommentTypeDeleteTimeManual too --- models/issues/tracked_time.go | 8 ++++---- routers/web/repo/issue.go | 10 ++-------- services/convert/issue_comment.go | 13 +++---------- 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/models/issues/tracked_time.go b/models/issues/tracked_time.go index cda5d0b74c492..1d7592926bc5c 100644 --- a/models/issues/tracked_time.go +++ b/models/issues/tracked_time.go @@ -258,8 +258,8 @@ func DeleteIssueUserTimes(issue *Issue, user *user_model.User) error { Repo: issue.Repo, Doer: user, // Content before v1.21 did store the formated string instead of seconds, - // the legacy format starts with '- ' - Content: fmt.Sprint(removedTime), + // so use "|" as delimeter to mark the new format + Content: fmt.Sprintf("|%d", removedTime), Type: CommentTypeDeleteTimeManual, }); err != nil { return err @@ -289,8 +289,8 @@ func DeleteTime(t *TrackedTime) error { Repo: t.Issue.Repo, Doer: t.User, // Content before v1.21 did store the formated string instead of seconds, - // the legacy format starts with '- ' - Content: fmt.Sprint(t.Time), + // so use "|" as delimeter to mark the new format + Content: fmt.Sprintf("|%d", t.Time), Type: CommentTypeDeleteTimeManual, }); err != nil { return err diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index f7ebcfea000df..7d8ec3a6f3198 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -1647,7 +1647,8 @@ func ViewIssue(ctx *context.Context) { return } } 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.. _ = comment.LoadTime() if comment.Content != "" { @@ -1662,13 +1663,6 @@ func ViewIssue(ctx *context.Context) { comment.Content = comment.Content[1:] } } - } else if comment.Type == issues_model.CommentTypeDeleteTimeManual && comment.Content != "" { - if comment.Content[0] == '-' { - // handle old time comments that have formatted text stored - comment.RenderedContent = comment.Content - comment.Content = "" - } - // else it's just a duration in seconds to pass on to the frontend } if comment.Type == issues_model.CommentTypeClose || comment.Type == issues_model.CommentTypeMergePull { diff --git a/services/convert/issue_comment.go b/services/convert/issue_comment.go index 7328acc181fae..db48faa69e694 100644 --- a/services/convert/issue_comment.go +++ b/services/convert/issue_comment.go @@ -5,7 +5,6 @@ package convert import ( "context" - "strconv" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" @@ -70,18 +69,12 @@ func ToTimelineComment(ctx context.Context, c *issues_model.Comment, doer *user_ if c.Content != "" { if (c.Type == issues_model.CommentTypeAddTimeManual || - c.Type == issues_model.CommentTypeStopTracking) && + 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 - i, _ := strconv.ParseInt(c.Content[1:], 10, 64) - c.Content = util.SecToTime(i) - } else if 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 legacy format via "-" indicator and convert new to legacy format on demand - i, _ := strconv.ParseInt(c.Content, 10, 64) - c.Content = "- " + util.SecToTime(i) + c.Content = util.SecToTime(c.Content[1:]) } }