Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions modules/timeutil/datetime.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,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, render using <gitea-locale-date>
attrs = append(attrs, `month="`+format+`"`, `day="numeric"`)
return template.HTML(fmt.Sprintf(`<gitea-locale-date %s date="%s">%s</gitea-locale-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"`)
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))
}
14 changes: 9 additions & 5 deletions modules/timeutil/datetime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())

Expand All @@ -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-locale-date data-tooltip-content data-tooltip-interactive="true" weekday="" year="numeric" month="short" day="numeric" date="invalid">invalid</gitea-locale-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-locale-date data-tooltip-content data-tooltip-interactive="true" weekday="" year="numeric" month="short" day="numeric" date="2018-01-01T00:00:00Z">2018-01-01T00:00:00Z</gitea-locale-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-locale-date data-tooltip-content data-tooltip-interactive="true" weekday="" year="numeric" month="short" day="numeric" date="2018-01-01T00:00:00Z">2018-01-01</gitea-locale-date>`, actual)

actual = DateTime("short", refDateStr)
assert.EqualValues(t, `<gitea-locale-date data-tooltip-content data-tooltip-interactive="true" weekday="" year="numeric" month="short" day="numeric" date="2018-01-01">2018-01-01</gitea-locale-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-locale-date data-tooltip-content data-tooltip-interactive="true" weekday="" year="numeric" month="short" day="numeric" date="2017-12-31T19:00:00-05:00">2017-12-31</gitea-locale-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 data-tooltip-content data-tooltip-interactive="true" weekday="" year="numeric" format="datetime" 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)
}
10 changes: 10 additions & 0 deletions templates/devtest/gitea-ui.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,16 @@
<div><gitea-origin-url data-url="/test/url"></gitea-origin-url></div>
</div>

<div>
<h1>GiteaLocaleDate</h1>
<div><gitea-locale-date date="2024-03-11" year="numeric" day="numeric" month="short"></gitea-locale-date></div>
<div><gitea-locale-date date="2024-03-11" year="numeric" day="numeric" month="long"></gitea-locale-date></div>
<div><gitea-locale-date date="2024-03-11" year="" day="numeric" month="numeric"></gitea-locale-date></div>
<div><gitea-locale-date date="2024-03-11" year="" day="numeric" month="numeric" weekday="long"></gitea-locale-date></div>
<div><gitea-locale-date date="2024-03-11T19:00:00-05:00" year="" day="numeric" month="numeric" weekday="long"></gitea-locale-date></div>
<div class="tw-text-red">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>
Expand Down
40 changes: 40 additions & 0 deletions web_src/js/webcomponents/GiteaLocaleDate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
window.customElements.define('gitea-locale-date', class extends HTMLElement {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not extend <relative-time>?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We aren't replacing https://github.com/github/relative-time-element, we are just adding another custom element to render absolute dates in locale format.

Copy link
Member Author

@silverwind silverwind Mar 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, and to answer specifically: <relative-time> is not meant to be passed dates, only datetimes. So it's currently unsuitable for the date rendering and I'm not sure whether upstream would accept a date parameter as it would increase internal complexity of the component a lot.

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
const date = new Date(this.getAttribute('date').substring(0, 10));

// apply negative timezone offset because `new Date()` above assumes that `yyyy-mm-dd` is
// a UTC date, so the local date will have a offset towards UTC which we reverse here.
// Ref: https://stackoverflow.com/a/14569783/808699
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;
}
});
1 change: 1 addition & 0 deletions web_src/js/webcomponents/webcomponents.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ import './polyfill.js';

import '@github/relative-time-element';
import './GiteaOriginUrl.js';
import './GiteaLocaleDate.js';