diff options
author | silverwind <me@silverwind.io> | 2024-03-12 23:37:02 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-12 22:37:02 +0000 |
commit | 857243bed7f9dccdc597c2941df41e821781cb0f (patch) | |
tree | 2472a56ed5eff0f212a200d72ba707407c68097f | |
parent | 225fc405283a21c9ef966aa0bf8dabfe687804a8 (diff) | |
download | gitea-857243bed7f9dccdc597c2941df41e821781cb0f.tar.gz gitea-857243bed7f9dccdc597c2941df41e821781cb0f.zip |
Fix date rendering by adding `<gitea-absolute-date>` (#29725)
Alternative to: https://github.com/go-gitea/gitea/pull/29698
Fixes: https://github.com/go-gitea/gitea/issues/29034
<img width="278" alt="image"
src="https://github.com/go-gitea/gitea/assets/115237/12ecd967-2723-410d-8a28-a1b0f41b7bba">
It also fixes a secondary issue that we were showing timestamp tooltips
over date, which makes no sense, so these are now gone as well:
<img width="284" alt="image"
src="https://github.com/go-gitea/gitea/assets/115237/a70432f3-97b6-41e6-b202-b53b76924a66">
-rw-r--r-- | modules/timeutil/datetime.go | 16 | ||||
-rw-r--r-- | modules/timeutil/datetime_test.go | 14 | ||||
-rw-r--r-- | templates/devtest/gitea-ui.tmpl | 10 | ||||
-rw-r--r-- | web_src/js/webcomponents/GiteaAbsoluteDate.js | 40 | ||||
-rw-r--r-- | web_src/js/webcomponents/webcomponents.js | 1 |
5 files changed, 67 insertions, 14 deletions
diff --git a/modules/timeutil/datetime.go b/modules/timeutil/datetime.go index 62b94f7cf4..50c8d44f13 100644 --- a/modules/timeutil/datetime.go +++ b/modules/timeutil/datetime.go @@ -51,18 +51,16 @@ func DateTime(format string, datetime any, extraAttrs ...string) template.HTML { attrs := make([]string, 0, 10+len(extraAttrs)) attrs = append(attrs, extraAttrs...) - attrs = append(attrs, `data-tooltip-content`, `data-tooltip-interactive="true"`) - attrs = append(attrs, `format="datetime"`, `weekday=""`, `year="numeric"`) + attrs = append(attrs, `weekday=""`, `year="numeric"`) switch format { - case "short": - attrs = append(attrs, `month="short"`, `day="numeric"`) - case "long": - attrs = append(attrs, `month="long"`, `day="numeric"`) - case "full": - attrs = append(attrs, `month="short"`, `day="numeric"`, `hour="numeric"`, `minute="numeric"`, `second="numeric"`) + case "short", "long": // date only + attrs = append(attrs, `month="`+format+`"`, `day="numeric"`) + return template.HTML(fmt.Sprintf(`<gitea-absolute-date %s date="%s">%s</gitea-absolute-date>`, strings.Join(attrs, " "), datetimeEscaped, textEscaped)) + case "full": // full date including time + attrs = append(attrs, `format="datetime"`, `month="short"`, `day="numeric"`, `hour="numeric"`, `minute="numeric"`, `second="numeric"`, `data-tooltip-content`, `data-tooltip-interactive="true"`) + return template.HTML(fmt.Sprintf(`<relative-time %s datetime="%s">%s</relative-time>`, strings.Join(attrs, " "), datetimeEscaped, textEscaped)) default: panic(fmt.Sprintf("Unsupported format %s", format)) } - return template.HTML(fmt.Sprintf(`<relative-time %s datetime="%s">%s</relative-time>`, strings.Join(attrs, " "), datetimeEscaped, textEscaped)) } diff --git a/modules/timeutil/datetime_test.go b/modules/timeutil/datetime_test.go index 26494b8475..39aecbc43b 100644 --- a/modules/timeutil/datetime_test.go +++ b/modules/timeutil/datetime_test.go @@ -18,6 +18,7 @@ func TestDateTime(t *testing.T) { defer test.MockVariableValue(&setting.DefaultUILocation, testTz)() refTimeStr := "2018-01-01T00:00:00Z" + refDateStr := "2018-01-01" refTime, _ := time.Parse(time.RFC3339, refTimeStr) refTimeStamp := TimeStamp(refTime.Unix()) @@ -27,17 +28,20 @@ func TestDateTime(t *testing.T) { assert.EqualValues(t, "-", DateTime("short", TimeStamp(0))) actual := DateTime("short", "invalid") - assert.EqualValues(t, `<relative-time data-tooltip-content data-tooltip-interactive="true" format="datetime" weekday="" year="numeric" month="short" day="numeric" datetime="invalid">invalid</relative-time>`, actual) + assert.EqualValues(t, `<gitea-absolute-date weekday="" year="numeric" month="short" day="numeric" date="invalid">invalid</gitea-absolute-date>`, actual) actual = DateTime("short", refTimeStr) - assert.EqualValues(t, `<relative-time data-tooltip-content data-tooltip-interactive="true" format="datetime" weekday="" year="numeric" month="short" day="numeric" datetime="2018-01-01T00:00:00Z">2018-01-01T00:00:00Z</relative-time>`, actual) + assert.EqualValues(t, `<gitea-absolute-date weekday="" year="numeric" month="short" day="numeric" date="2018-01-01T00:00:00Z">2018-01-01T00:00:00Z</gitea-absolute-date>`, actual) actual = DateTime("short", refTime) - assert.EqualValues(t, `<relative-time data-tooltip-content data-tooltip-interactive="true" format="datetime" weekday="" year="numeric" month="short" day="numeric" datetime="2018-01-01T00:00:00Z">2018-01-01</relative-time>`, actual) + assert.EqualValues(t, `<gitea-absolute-date weekday="" year="numeric" month="short" day="numeric" date="2018-01-01T00:00:00Z">2018-01-01</gitea-absolute-date>`, actual) + + actual = DateTime("short", refDateStr) + assert.EqualValues(t, `<gitea-absolute-date weekday="" year="numeric" month="short" day="numeric" date="2018-01-01">2018-01-01</gitea-absolute-date>`, actual) actual = DateTime("short", refTimeStamp) - assert.EqualValues(t, `<relative-time data-tooltip-content data-tooltip-interactive="true" format="datetime" weekday="" year="numeric" month="short" day="numeric" datetime="2017-12-31T19:00:00-05:00">2017-12-31</relative-time>`, actual) + assert.EqualValues(t, `<gitea-absolute-date weekday="" year="numeric" month="short" day="numeric" date="2017-12-31T19:00:00-05:00">2017-12-31</gitea-absolute-date>`, actual) actual = DateTime("full", refTimeStamp) - assert.EqualValues(t, `<relative-time data-tooltip-content data-tooltip-interactive="true" format="datetime" weekday="" year="numeric" month="short" day="numeric" hour="numeric" minute="numeric" second="numeric" datetime="2017-12-31T19:00:00-05:00">2017-12-31 19:00:00 -05:00</relative-time>`, actual) + assert.EqualValues(t, `<relative-time weekday="" year="numeric" format="datetime" month="short" day="numeric" hour="numeric" minute="numeric" second="numeric" data-tooltip-content data-tooltip-interactive="true" datetime="2017-12-31T19:00:00-05:00">2017-12-31 19:00:00 -05:00</relative-time>`, actual) } diff --git a/templates/devtest/gitea-ui.tmpl b/templates/devtest/gitea-ui.tmpl index ccf188609c..e551572b96 100644 --- a/templates/devtest/gitea-ui.tmpl +++ b/templates/devtest/gitea-ui.tmpl @@ -111,6 +111,16 @@ </div> <div> + <h1>GiteaAbsoluteDate</h1> + <div><gitea-absolute-date date="2024-03-11" year="numeric" day="numeric" month="short"></gitea-absolute-date></div> + <div><gitea-absolute-date date="2024-03-11" year="numeric" day="numeric" month="long"></gitea-absolute-date></div> + <div><gitea-absolute-date date="2024-03-11" year="" day="numeric" month="numeric"></gitea-absolute-date></div> + <div><gitea-absolute-date date="2024-03-11" year="" day="numeric" month="numeric" weekday="long"></gitea-absolute-date></div> + <div><gitea-absolute-date date="2024-03-11T19:00:00-05:00" year="" day="numeric" month="numeric" weekday="long"></gitea-absolute-date></div> + <div class="tw-text-text-light-2">relative-time: <relative-time format="datetime" datetime="2024-03-11" year="" day="numeric" month="numeric"></relative-time></div> + </div> + + <div> <h1>LocaleNumber</h1> <div>{{ctx.Locale.PrettyNumber 1}}</div> <div>{{ctx.Locale.PrettyNumber 12}}</div> diff --git a/web_src/js/webcomponents/GiteaAbsoluteDate.js b/web_src/js/webcomponents/GiteaAbsoluteDate.js new file mode 100644 index 0000000000..660aa99d07 --- /dev/null +++ b/web_src/js/webcomponents/GiteaAbsoluteDate.js @@ -0,0 +1,40 @@ +window.customElements.define('gitea-absolute-date', class extends HTMLElement { + static observedAttributes = ['date', 'year', 'month', 'weekday', 'day']; + + update = () => { + const year = this.getAttribute('year') ?? ''; + const month = this.getAttribute('month') ?? ''; + const weekday = this.getAttribute('weekday') ?? ''; + const day = this.getAttribute('day') ?? ''; + const lang = this.closest('[lang]')?.getAttribute('lang') || + this.ownerDocument.documentElement.getAttribute('lang') || + ''; + + // only extract the `yyyy-mm-dd` part. When converting to Date, it will become midnight UTC and when rendered + // as localized date, will have a offset towards UTC, which we remove to shift the timestamp to midnight in the + // localized date. We should eventually use `Temporal.PlainDate` which will make the correction unnecessary. + // - https://stackoverflow.com/a/14569783/808699 + // - https://tc39.es/proposal-temporal/docs/plaindate.html + const date = new Date(this.getAttribute('date').substring(0, 10)); + const correctedDate = new Date(date.getTime() - date.getTimezoneOffset() * -60000); + + if (!this.shadowRoot) this.attachShadow({mode: 'open'}); + this.shadowRoot.textContent = correctedDate.toLocaleString(lang ?? [], { + ...(year && {year}), + ...(month && {month}), + ...(weekday && {weekday}), + ...(day && {day}), + }); + }; + + attributeChangedCallback(_name, oldValue, newValue) { + if (!this.initialized || oldValue === newValue) return; + this.update(); + } + + connectedCallback() { + this.initialized = false; + this.update(); + this.initialized = true; + } +}); diff --git a/web_src/js/webcomponents/webcomponents.js b/web_src/js/webcomponents/webcomponents.js index 916a588db6..03348d895f 100644 --- a/web_src/js/webcomponents/webcomponents.js +++ b/web_src/js/webcomponents/webcomponents.js @@ -3,3 +3,4 @@ import './polyfill.js'; import '@github/relative-time-element'; import './GiteaOriginUrl.js'; +import './GiteaAbsoluteDate.js'; |