From ecfd1545c8abb03b4298c9f08a9776e93b8f32f7 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Sat, 30 Dec 2023 11:17:32 +0000 Subject: [PATCH 1/5] Add the option to prefer all timestamps to be absolute Some admins prefer all timestamps to display the full date instead of relative time. They can do that now by setting ```ini [ui] PREFER_ABSOLUTE_TIMESTAMPS = true ``` Signed-off-by: Yarden Shoham --- custom/conf/app.example.ini | 3 ++ .../config-cheat-sheet.en-us.md | 1 + modules/setting/ui.go | 47 ++++++++++--------- modules/timeutil/datetime.go | 11 +++-- modules/timeutil/since.go | 4 ++ web_src/js/components/DiffCommitSelector.vue | 1 + 6 files changed, 40 insertions(+), 27 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 08f2e0d63fc66..ad8a6e00eebba 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1244,6 +1244,9 @@ LEVEL = Info ;; Change the sort type of the explore pages. ;; Default is "recentupdate", but you also have "alphabetically", "reverselastlogin", "newest", "oldest". ;EXPLORE_PAGING_DEFAULT_SORT = recentupdate +;; +;; Whether to prefer all timestamps to be rendered as absolute. Setting this to false means some timestamps would render as relative. +;PREFER_ABSOLUTE_TIMESTAMPS = false ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index beaa8cfb30245..1bc2ee946de98 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -231,6 +231,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a - `ONLY_SHOW_RELEVANT_REPOS`: **false**: Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used. A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic). - `EXPLORE_PAGING_DEFAULT_SORT`: **recentupdate**: Change the sort type of the explore pages. Valid values are "recentupdate", "alphabetically", "reverselastlogin", "newest" and "oldest" +- `PREFER_ABSOLUTE_TIMESTAMPS`: **false**: Whether to prefer all timestamps to be rendered as absolute. Setting this to false means some timestamps would render as relative. ### UI - Admin (`ui.admin`) diff --git a/modules/setting/ui.go b/modules/setting/ui.go index f94e6206cd995..a47c8caaf5b1a 100644 --- a/modules/setting/ui.go +++ b/modules/setting/ui.go @@ -11,29 +11,30 @@ import ( // UI settings var UI = struct { - ExplorePagingNum int - SitemapPagingNum int - IssuePagingNum int - RepoSearchPagingNum int - MembersPagingNum int - FeedMaxCommitNum int - FeedPagingNum int - PackagesPagingNum int - GraphMaxCommitNum int - CodeCommentLines int - ReactionMaxUserNum int - MaxDisplayFileSize int64 - ShowUserEmail bool - DefaultShowFullName bool - DefaultTheme string - Themes []string - Reactions []string - ReactionsLookup container.Set[string] `ini:"-"` - CustomEmojis []string - CustomEmojisMap map[string]string `ini:"-"` - SearchRepoDescription bool - OnlyShowRelevantRepos bool - ExploreDefaultSort string `ini:"EXPLORE_PAGING_DEFAULT_SORT"` + ExplorePagingNum int + SitemapPagingNum int + IssuePagingNum int + RepoSearchPagingNum int + MembersPagingNum int + FeedMaxCommitNum int + FeedPagingNum int + PackagesPagingNum int + GraphMaxCommitNum int + CodeCommentLines int + ReactionMaxUserNum int + MaxDisplayFileSize int64 + ShowUserEmail bool + DefaultShowFullName bool + DefaultTheme string + Themes []string + Reactions []string + ReactionsLookup container.Set[string] `ini:"-"` + CustomEmojis []string + CustomEmojisMap map[string]string `ini:"-"` + SearchRepoDescription bool + OnlyShowRelevantRepos bool + ExploreDefaultSort string `ini:"EXPLORE_PAGING_DEFAULT_SORT"` + PreferAbsoluteTimestamps bool AmbiguousUnicodeDetection bool diff --git a/modules/timeutil/datetime.go b/modules/timeutil/datetime.go index 83170b374b54c..d254a56a74dae 100644 --- a/modules/timeutil/datetime.go +++ b/modules/timeutil/datetime.go @@ -7,11 +7,12 @@ import ( "fmt" "html" "html/template" + "strings" "time" ) // DateTime renders an absolute time HTML element by datetime. -func DateTime(format string, datetime any) template.HTML { +func DateTime(format string, datetime any, attrs ...string) template.HTML { if p, ok := datetime.(*time.Time); ok { datetime = *p } @@ -48,13 +49,15 @@ func DateTime(format string, datetime any) template.HTML { panic(fmt.Sprintf("Unsupported time type %T", datetime)) } + extraAttrs := strings.Join(attrs, " ") + switch format { case "short": - return template.HTML(fmt.Sprintf(`%s`, datetimeEscaped, textEscaped)) + return template.HTML(fmt.Sprintf(`%s`, extraAttrs, datetimeEscaped, textEscaped)) case "long": - return template.HTML(fmt.Sprintf(`%s`, datetimeEscaped, textEscaped)) + return template.HTML(fmt.Sprintf(`%s`, extraAttrs, datetimeEscaped, textEscaped)) case "full": - return template.HTML(fmt.Sprintf(`%s`, datetimeEscaped, textEscaped)) + return template.HTML(fmt.Sprintf(`%s`, extraAttrs, datetimeEscaped, textEscaped)) } panic(fmt.Sprintf("Unsupported format %s", format)) } diff --git a/modules/timeutil/since.go b/modules/timeutil/since.go index 04fcff54a3384..cf5ebaa738023 100644 --- a/modules/timeutil/since.go +++ b/modules/timeutil/since.go @@ -9,6 +9,7 @@ import ( "strings" "time" + "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/translation" ) @@ -132,6 +133,9 @@ func timeSinceUnix(then, now time.Time, lang translation.Locale) template.HTML { // TimeSince renders relative time HTML given a time.Time func TimeSince(then time.Time, lang translation.Locale) template.HTML { + if setting.UI.PreferAbsoluteTimestamps { + return DateTime("full", then, `class="time-since"`) + } return timeSinceUnix(then, time.Now(), lang) } diff --git a/web_src/js/components/DiffCommitSelector.vue b/web_src/js/components/DiffCommitSelector.vue index 439840c30639f..d13de71982cac 100644 --- a/web_src/js/components/DiffCommitSelector.vue +++ b/web_src/js/components/DiffCommitSelector.vue @@ -247,6 +247,7 @@ export default {
{{ commit.committer_or_author_name }} + {{ commit.time }}
From b3d60f779ca806e3b0fad5339b05c7611fd949c8 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Sat, 30 Dec 2023 12:28:34 +0000 Subject: [PATCH 2/5] Fix tests Signed-off-by: Yarden Shoham --- modules/timeutil/datetime_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/timeutil/datetime_test.go b/modules/timeutil/datetime_test.go index f44b7aaae3c1b..387e6274a785a 100644 --- a/modules/timeutil/datetime_test.go +++ b/modules/timeutil/datetime_test.go @@ -29,17 +29,17 @@ func TestDateTime(t *testing.T) { assert.EqualValues(t, "-", DateTime("short", TimeStamp(0))) actual := DateTime("short", "invalid") - assert.EqualValues(t, `invalid`, actual) + assert.EqualValues(t, `invalid`, actual) actual = DateTime("short", refTimeStr) - assert.EqualValues(t, `2018-01-01T00:00:00Z`, actual) + assert.EqualValues(t, `2018-01-01T00:00:00Z`, actual) actual = DateTime("short", refTime) - assert.EqualValues(t, `2018-01-01`, actual) + assert.EqualValues(t, `2018-01-01`, actual) actual = DateTime("short", refTimeStamp) - assert.EqualValues(t, `2017-12-31`, actual) + assert.EqualValues(t, `2017-12-31`, actual) actual = DateTime("full", refTimeStamp) - assert.EqualValues(t, `2017-12-31 19:00:00 -05:00`, actual) + assert.EqualValues(t, `2017-12-31 19:00:00 -05:00`, actual) } From bbe69c377061499f693eb63eb62bba351f89735f Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Sat, 30 Dec 2023 12:30:41 +0000 Subject: [PATCH 3/5] Clarify description Co-authored-by: delvh Signed-off-by: Yarden Shoham --- custom/conf/app.example.ini | 2 +- docs/content/administration/config-cheat-sheet.en-us.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index ad8a6e00eebba..ff85869425a0d 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1245,7 +1245,7 @@ LEVEL = Info ;; Default is "recentupdate", but you also have "alphabetically", "reverselastlogin", "newest", "oldest". ;EXPLORE_PAGING_DEFAULT_SORT = recentupdate ;; -;; Whether to prefer all timestamps to be rendered as absolute. Setting this to false means some timestamps would render as relative. +;; Whether all timestamps should be rendered as absolute time (i.e. 1970-01-01, 11:59). Setting this to false means some timestamps would render as relative (i.e. 2 days ago). ;PREFER_ABSOLUTE_TIMESTAMPS = false ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 1bc2ee946de98..4cd1096c9e0b4 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -231,7 +231,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a - `ONLY_SHOW_RELEVANT_REPOS`: **false**: Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used. A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic). - `EXPLORE_PAGING_DEFAULT_SORT`: **recentupdate**: Change the sort type of the explore pages. Valid values are "recentupdate", "alphabetically", "reverselastlogin", "newest" and "oldest" -- `PREFER_ABSOLUTE_TIMESTAMPS`: **false**: Whether to prefer all timestamps to be rendered as absolute. Setting this to false means some timestamps would render as relative. +- `PREFER_ABSOLUTE_TIMESTAMPS`: **false**: Whether all timestamps should be rendered as absolute time (i.e. 1970-01-01, 11:59). Setting this to false means some timestamps would render as relative (i.e. 2 days ago). ### UI - Admin (`ui.admin`) From 0504a8c68520e7c8703091cbf9758ae42f1398ac Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Sun, 31 Dec 2023 17:38:45 +0000 Subject: [PATCH 4/5] Switch to PreferredTimestampTense Signed-off-by: Yarden Shoham --- custom/conf/app.example.ini | 5 +- .../config-cheat-sheet.en-us.md | 2 +- modules/setting/ui.go | 88 ++++++++++--------- modules/timeutil/since.go | 2 +- web_src/js/components/DiffCommitSelector.vue | 2 +- 5 files changed, 53 insertions(+), 46 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index ff85869425a0d..c5a3b5ea9f68d 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1245,8 +1245,9 @@ LEVEL = Info ;; Default is "recentupdate", but you also have "alphabetically", "reverselastlogin", "newest", "oldest". ;EXPLORE_PAGING_DEFAULT_SORT = recentupdate ;; -;; Whether all timestamps should be rendered as absolute time (i.e. 1970-01-01, 11:59). Setting this to false means some timestamps would render as relative (i.e. 2 days ago). -;PREFER_ABSOLUTE_TIMESTAMPS = false +;; The tense all timestamps should be rendered as. Possible values are `absolute` time (i.e. 1970-01-01, 11:59) or `mixed` +;; which means some timestamps would render as relative (i.e. 2 days ago). +;PREFERRED_TIMESTAMP_TENSE = mixed ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 4cd1096c9e0b4..89743982b9764 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -231,7 +231,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a - `ONLY_SHOW_RELEVANT_REPOS`: **false**: Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used. A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic). - `EXPLORE_PAGING_DEFAULT_SORT`: **recentupdate**: Change the sort type of the explore pages. Valid values are "recentupdate", "alphabetically", "reverselastlogin", "newest" and "oldest" -- `PREFER_ABSOLUTE_TIMESTAMPS`: **false**: Whether all timestamps should be rendered as absolute time (i.e. 1970-01-01, 11:59). Setting this to false means some timestamps would render as relative (i.e. 2 days ago). +- `PREFERRED_TIMESTAMP_TENSE`: **mixed**: The tense all timestamps should be rendered as. Possible values are `absolute` time (i.e. 1970-01-01, 11:59) or `mixed` which means some timestamps would render as relative (i.e. 2 days ago). ### UI - Admin (`ui.admin`) diff --git a/modules/setting/ui.go b/modules/setting/ui.go index a47c8caaf5b1a..2f9eef93c3bc9 100644 --- a/modules/setting/ui.go +++ b/modules/setting/ui.go @@ -7,34 +7,35 @@ import ( "time" "code.gitea.io/gitea/modules/container" + "code.gitea.io/gitea/modules/log" ) // UI settings var UI = struct { - ExplorePagingNum int - SitemapPagingNum int - IssuePagingNum int - RepoSearchPagingNum int - MembersPagingNum int - FeedMaxCommitNum int - FeedPagingNum int - PackagesPagingNum int - GraphMaxCommitNum int - CodeCommentLines int - ReactionMaxUserNum int - MaxDisplayFileSize int64 - ShowUserEmail bool - DefaultShowFullName bool - DefaultTheme string - Themes []string - Reactions []string - ReactionsLookup container.Set[string] `ini:"-"` - CustomEmojis []string - CustomEmojisMap map[string]string `ini:"-"` - SearchRepoDescription bool - OnlyShowRelevantRepos bool - ExploreDefaultSort string `ini:"EXPLORE_PAGING_DEFAULT_SORT"` - PreferAbsoluteTimestamps bool + ExplorePagingNum int + SitemapPagingNum int + IssuePagingNum int + RepoSearchPagingNum int + MembersPagingNum int + FeedMaxCommitNum int + FeedPagingNum int + PackagesPagingNum int + GraphMaxCommitNum int + CodeCommentLines int + ReactionMaxUserNum int + MaxDisplayFileSize int64 + ShowUserEmail bool + DefaultShowFullName bool + DefaultTheme string + Themes []string + Reactions []string + ReactionsLookup container.Set[string] `ini:"-"` + CustomEmojis []string + CustomEmojisMap map[string]string `ini:"-"` + SearchRepoDescription bool + OnlyShowRelevantRepos bool + ExploreDefaultSort string `ini:"EXPLORE_PAGING_DEFAULT_SORT"` + PreferredTimestampTense string AmbiguousUnicodeDetection bool @@ -68,23 +69,24 @@ var UI = struct { Keywords string } `ini:"ui.meta"` }{ - ExplorePagingNum: 20, - SitemapPagingNum: 20, - IssuePagingNum: 20, - RepoSearchPagingNum: 20, - MembersPagingNum: 20, - FeedMaxCommitNum: 5, - FeedPagingNum: 20, - PackagesPagingNum: 20, - GraphMaxCommitNum: 100, - CodeCommentLines: 4, - ReactionMaxUserNum: 10, - MaxDisplayFileSize: 8388608, - DefaultTheme: `gitea-auto`, - Themes: []string{`gitea-auto`, `gitea-light`, `gitea-dark`}, - Reactions: []string{`+1`, `-1`, `laugh`, `hooray`, `confused`, `heart`, `rocket`, `eyes`}, - CustomEmojis: []string{`git`, `gitea`, `codeberg`, `gitlab`, `github`, `gogs`}, - CustomEmojisMap: map[string]string{"git": ":git:", "gitea": ":gitea:", "codeberg": ":codeberg:", "gitlab": ":gitlab:", "github": ":github:", "gogs": ":gogs:"}, + ExplorePagingNum: 20, + SitemapPagingNum: 20, + IssuePagingNum: 20, + RepoSearchPagingNum: 20, + MembersPagingNum: 20, + FeedMaxCommitNum: 5, + FeedPagingNum: 20, + PackagesPagingNum: 20, + GraphMaxCommitNum: 100, + CodeCommentLines: 4, + ReactionMaxUserNum: 10, + MaxDisplayFileSize: 8388608, + DefaultTheme: `gitea-auto`, + Themes: []string{`gitea-auto`, `gitea-light`, `gitea-dark`}, + Reactions: []string{`+1`, `-1`, `laugh`, `hooray`, `confused`, `heart`, `rocket`, `eyes`}, + CustomEmojis: []string{`git`, `gitea`, `codeberg`, `gitlab`, `github`, `gogs`}, + CustomEmojisMap: map[string]string{"git": ":git:", "gitea": ":gitea:", "codeberg": ":codeberg:", "gitlab": ":gitlab:", "github": ":github:", "gogs": ":gogs:"}, + PreferredTimestampTense: "mixed", AmbiguousUnicodeDetection: true, @@ -143,6 +145,10 @@ func loadUIFrom(rootCfg ConfigProvider) { UI.DefaultShowFullName = sec.Key("DEFAULT_SHOW_FULL_NAME").MustBool(false) UI.SearchRepoDescription = sec.Key("SEARCH_REPO_DESCRIPTION").MustBool(true) + if UI.PreferredTimestampTense != "mixed" && UI.PreferredTimestampTense != "absolute" { + log.Fatal("ui.PREFERRED_TIMESTAMP_TENSE must be either 'mixed' or 'absolute'") + } + // OnlyShowRelevantRepos=false is important for many private/enterprise instances, // because many private repositories do not have "description/topic", users just want to search by their names. UI.OnlyShowRelevantRepos = sec.Key("ONLY_SHOW_RELEVANT_REPOS").MustBool(false) diff --git a/modules/timeutil/since.go b/modules/timeutil/since.go index cf5ebaa738023..1cb3c4f288b2b 100644 --- a/modules/timeutil/since.go +++ b/modules/timeutil/since.go @@ -133,7 +133,7 @@ func timeSinceUnix(then, now time.Time, lang translation.Locale) template.HTML { // TimeSince renders relative time HTML given a time.Time func TimeSince(then time.Time, lang translation.Locale) template.HTML { - if setting.UI.PreferAbsoluteTimestamps { + if setting.UI.PreferredTimestampTense == "absolute" { return DateTime("full", then, `class="time-since"`) } return timeSinceUnix(then, time.Now(), lang) diff --git a/web_src/js/components/DiffCommitSelector.vue b/web_src/js/components/DiffCommitSelector.vue index d13de71982cac..54877a18c0fc5 100644 --- a/web_src/js/components/DiffCommitSelector.vue +++ b/web_src/js/components/DiffCommitSelector.vue @@ -247,7 +247,7 @@ export default {
{{ commit.committer_or_author_name }} - + {{ commit.time }}
From b00611a5c86e693942e6d60f43d1b5f076fade26 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Mon, 1 Jan 2024 12:05:16 +0200 Subject: [PATCH 5/5] Apply suggestions from code review Co-authored-by: delvh --- custom/conf/app.example.ini | 4 ++-- docs/content/administration/config-cheat-sheet.en-us.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index c5a3b5ea9f68d..d58309f141bd5 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1245,8 +1245,8 @@ LEVEL = Info ;; Default is "recentupdate", but you also have "alphabetically", "reverselastlogin", "newest", "oldest". ;EXPLORE_PAGING_DEFAULT_SORT = recentupdate ;; -;; The tense all timestamps should be rendered as. Possible values are `absolute` time (i.e. 1970-01-01, 11:59) or `mixed` -;; which means some timestamps would render as relative (i.e. 2 days ago). +;; The tense all timestamps should be rendered in. Possible values are `absolute` time (i.e. 1970-01-01, 11:59) and `mixed`. +;; `mixed` means most timestamps are rendered in relative time (i.e. 2 days ago). ;PREFERRED_TIMESTAMP_TENSE = mixed ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 89743982b9764..e111ff6db62e0 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -231,7 +231,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a - `ONLY_SHOW_RELEVANT_REPOS`: **false**: Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used. A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic). - `EXPLORE_PAGING_DEFAULT_SORT`: **recentupdate**: Change the sort type of the explore pages. Valid values are "recentupdate", "alphabetically", "reverselastlogin", "newest" and "oldest" -- `PREFERRED_TIMESTAMP_TENSE`: **mixed**: The tense all timestamps should be rendered as. Possible values are `absolute` time (i.e. 1970-01-01, 11:59) or `mixed` which means some timestamps would render as relative (i.e. 2 days ago). +- `PREFERRED_TIMESTAMP_TENSE`: **mixed**: The tense all timestamps should be rendered in. Possible values are `absolute` time (i.e. 1970-01-01, 11:59) and `mixed`. `mixed` means most timestamps are rendered in relative time (i.e. 2 days ago). ### UI - Admin (`ui.admin`)