]> source.dussan.org Git - gitea.git/commitdiff
Fix date rendering by adding `<gitea-absolute-date>` (#29725) (#29747)
authorGiteabot <teabot@gitea.io>
Wed, 13 Mar 2024 00:04:58 +0000 (08:04 +0800)
committerGitHub <noreply@github.com>
Wed, 13 Mar 2024 00:04:58 +0000 (01:04 +0100)
Backport #29725 by @silverwind

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">

Co-authored-by: silverwind <me@silverwind.io>
modules/timeutil/datetime.go
modules/timeutil/datetime_test.go
templates/devtest/gitea-ui.tmpl
web_src/js/webcomponents/GiteaAbsoluteDate.js [new file with mode: 0644]
web_src/js/webcomponents/webcomponents.js

index 62b94f7cf481cd8f358f03d1dd5e84a9e230637a..50c8d44f132beaaf9c59d160c4412884b9ecbf26 100644 (file)
@@ -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))
 }
index 26494b84754f9582c0db65206c0109d8e990b0ed..39aecbc43bdf6468ad481991ac243f7fcbf06b62 100644 (file)
@@ -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)
 }
index 73293ddf485c366380010928910477a8ad9286bb..63e6a5ac994a0118cd251aa3fb2ac3114b095c79 100644 (file)
                <div><gitea-origin-url data-url="/test/url"></gitea-origin-url></div>
        </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>
diff --git a/web_src/js/webcomponents/GiteaAbsoluteDate.js b/web_src/js/webcomponents/GiteaAbsoluteDate.js
new file mode 100644 (file)
index 0000000..660aa99
--- /dev/null
@@ -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;
+  }
+});
index 916a588db64bf6fee206a1da3ab9f71981aa284e..03348d895fe4a981423f43f9ffb5e2c617ef920a 100644 (file)
@@ -3,3 +3,4 @@ import './polyfill.js';
 
 import '@github/relative-time-element';
 import './GiteaOriginUrl.js';
+import './GiteaAbsoluteDate.js';