Localize ha-relative-time (#1241)

* Localize relative time

* Add mixin

* Pass hass to ha-relative-time

* Remove debug

* Add hass

* Add hass everywhere

* Remove value from translation file

* Add quotes to attributes

* Lint

* Fix in hassio file

* Use current placeholder syntax

* Use correct syntax

* Move to ui.components
This commit is contained in:
c727 2018-06-01 15:55:00 +02:00 committed by Paulus Schoutsen
parent e11cca28fd
commit 1a3966e55f
26 changed files with 70 additions and 57 deletions

View File

@ -30,7 +30,7 @@ class HassioAddonRepository extends NavigateMixin(PolymerElement) {
<template is="dom-repeat" items="[[addons]]" as="addon" sort="sortAddons"> <template is="dom-repeat" items="[[addons]]" as="addon" sort="sortAddons">
<paper-card on-click="addonTapped"> <paper-card on-click="addonTapped">
<div class="card-content"> <div class="card-content">
<hassio-card-content title="[[addon.name]]" description="[[addon.description]]" icon="[[computeIcon(addon)]]" icon-title="[[computeIconTitle(addon)]]" icon-class="[[computeIconClass(addon)]]"></hassio-card-content> <hassio-card-content hass="[[hass]]" title="[[addon.name]]" description="[[addon.description]]" icon="[[computeIcon(addon)]]" icon-title="[[computeIconTitle(addon)]]" icon-class="[[computeIconClass(addon)]]"></hassio-card-content>
</div> </div>
</paper-card> </paper-card>
</template> </template>
@ -41,6 +41,7 @@ class HassioAddonRepository extends NavigateMixin(PolymerElement) {
static get properties() { static get properties() {
return { return {
hass: Object,
repo: Object, repo: Object,
addons: Array, addons: Array,
}; };

View File

@ -15,7 +15,7 @@ class HassioAddonStore extends PolymerElement {
<hassio-repositories-editor hass="[[hass]]" repos="[[repos]]"></hassio-repositories-editor> <hassio-repositories-editor hass="[[hass]]" repos="[[repos]]"></hassio-repositories-editor>
<template is="dom-repeat" items="[[repos]]" as="repo" sort="sortRepos"> <template is="dom-repeat" items="[[repos]]" as="repo" sort="sortRepos">
<hassio-addon-repository repo="[[repo]]" addons="[[computeAddons(repo.slug)]]"></hassio-addon-repository> <hassio-addon-repository hass="[[hass]]" repo="[[repo]]" addons="[[computeAddons(repo.slug)]]"></hassio-addon-repository>
</template> </template>
`; `;
} }

View File

@ -35,7 +35,7 @@ class HassioRepositoriesEditor extends PolymerElement {
<template id="list" is="dom-repeat" items="[[repoList]]" as="repo" sort="sortRepos"> <template id="list" is="dom-repeat" items="[[repoList]]" as="repo" sort="sortRepos">
<paper-card> <paper-card>
<div class="card-content"> <div class="card-content">
<hassio-card-content title="[[repo.name]]" description="[[repo.url]]" icon="hassio:github-circle"></hassio-card-content> <hassio-card-content hass="[[hass]]" title="[[repo.name]]" description="[[repo.url]]" icon="hassio:github-circle"></hassio-card-content>
</div> </div>
<div class="card-actions"> <div class="card-actions">
<ha-call-api-button hass="[[hass]]" path="hassio/supervisor/options" data="[[computeRemoveRepoData(repoList, repo.url)]]" class="warning">Remove</ha-call-api-button> <ha-call-api-button hass="[[hass]]" path="hassio/supervisor/options" data="[[computeRemoveRepoData(repoList, repo.url)]]" class="warning">Remove</ha-call-api-button>

View File

@ -66,7 +66,7 @@ class HassioAddonInfo extends EventsMixin(PolymerElement) {
<template is="dom-if" if="[[computeUpdateAvailable(addon)]]"> <template is="dom-if" if="[[computeUpdateAvailable(addon)]]">
<paper-card heading="Update available! 🎉"> <paper-card heading="Update available! 🎉">
<div class="card-content"> <div class="card-content">
<hassio-card-content title="[[addon.name]] [[addon.last_version]] is available" description="You are currently running version [[addon.version]]" icon="hassio:arrow-up-bold-circle" icon-class="update"></hassio-card-content> <hassio-card-content hass="[[hass]]" title="[[addon.name]] [[addon.last_version]] is available" description="You are currently running version [[addon.version]]" icon="hassio:arrow-up-bold-circle" icon-class="update"></hassio-card-content>
</div> </div>
<div class="card-actions"> <div class="card-actions">
<ha-call-api-button hass="[[hass]]" path="hassio/addons/[[addonSlug]]/update">Update</ha-call-api-button> <ha-call-api-button hass="[[hass]]" path="hassio/addons/[[addonSlug]]/update">Update</ha-call-api-button>

View File

@ -50,7 +50,7 @@ class HassioCardContent extends PolymerElement {
[[description]] [[description]]
</template> </template>
<template is="dom-if" if="[[datetime]]"> <template is="dom-if" if="[[datetime]]">
<ha-relative-time class="addition" datetime="[[datetime]]"></ha-relative-time> <ha-relative-time hass="[[hass]]" class="addition" datetime="[[datetime]]"></ha-relative-time>
</template> </template>
</div> </div>
</div> </div>
@ -59,6 +59,7 @@ class HassioCardContent extends PolymerElement {
static get properties() { static get properties() {
return { return {
hass: Object,
title: String, title: String,
description: String, description: String,
datetime: String, datetime: String,

View File

@ -26,7 +26,7 @@ class HassioAddons extends NavigateMixin(PolymerElement) {
<template is="dom-repeat" items="[[addons]]" as="addon" sort="sortAddons"> <template is="dom-repeat" items="[[addons]]" as="addon" sort="sortAddons">
<paper-card on-click="addonTapped"> <paper-card on-click="addonTapped">
<div class="card-content"> <div class="card-content">
<hassio-card-content title="[[addon.name]]" description="[[addon.description]]" icon="[[computeIcon(addon)]]" icon-title="[[computeIconTitle(addon)]]" icon-class="[[computeIconClass(addon)]]"></hassio-card-content> <hassio-card-content hass="[[hass]]" title="[[addon.name]]" description="[[addon.description]]" icon="[[computeIcon(addon)]]" icon-title="[[computeIconTitle(addon)]]" icon-class="[[computeIconClass(addon)]]"></hassio-card-content>
</div> </div>
</paper-card> </paper-card>
</template> </template>

View File

@ -27,7 +27,7 @@ class HassioHassUpdate extends PolymerElement {
<div class="title">Update available! 🎉</div> <div class="title">Update available! 🎉</div>
<paper-card> <paper-card>
<div class="card-content"> <div class="card-content">
<hassio-card-content title="Home Assistant [[hassInfo.last_version]] is available" description="You are currently running version [[hassInfo.version]]" icon="hassio:home-assistant" icon-class="hassupdate"></hassio-card-content> <hassio-card-content hass="[[hass]]" title="Home Assistant [[hassInfo.last_version]] is available" description="You are currently running version [[hassInfo.version]]" icon="hassio:home-assistant" icon-class="hassupdate"></hassio-card-content>
<template is="dom-if" if="[[error]]"> <template is="dom-if" if="[[error]]">
<div class="error">Error: [[error]]</div> <div class="error">Error: [[error]]</div>
</template> </template>

View File

@ -91,7 +91,7 @@ class HassioSnapshots extends EventsMixin(PolymerElement) {
<template is="dom-repeat" items="[[snapshots]]" as="snapshot" sort="_sortSnapshots"> <template is="dom-repeat" items="[[snapshots]]" as="snapshot" sort="_sortSnapshots">
<paper-card class="pointer" on-click="_snapshotClicked"> <paper-card class="pointer" on-click="_snapshotClicked">
<div class="card-content"> <div class="card-content">
<hassio-card-content title="[[_computeName(snapshot)]]" description="[[_computeDetails(snapshot)]]" datetime="[[snapshot.date]]" icon="[[_computeIcon(snapshot.type)]]" icon-class="snapshot"></hassio-card-content> <hassio-card-content hass="[[hass]]" title="[[_computeName(snapshot)]]" description="[[_computeDetails(snapshot)]]" datetime="[[snapshot.date]]" icon="[[_computeIcon(snapshot.type)]]" icon-class="snapshot"></hassio-card-content>
</div> </div>
</paper-card> </paper-card>
</template> </template>

View File

@ -11,21 +11,26 @@ const tests = [
export default function relativeTime(dateObj) { export default function relativeTime(dateObj) {
let delta = (new Date() - dateObj) / 1000; let delta = (new Date() - dateObj) / 1000;
const format = delta >= 0 ? '%s ago' : 'in %s'; const tense = delta >= 0 ? 'past' : 'future';
delta = Math.abs(delta); delta = Math.abs(delta);
for (let i = 0; i < tests.length; i += 2) { for (let i = 0; i < tests.length; i += 2) {
if (delta < tests[i]) { if (delta < tests[i]) {
delta = Math.floor(delta); delta = Math.floor(delta);
return format.replace( return {
'%s', tense,
delta === 1 ? '1 ' + tests[i + 1] : delta + ' ' + tests[i + 1] + 's' value: delta,
); unit: tests[i + 1]
};
} }
delta /= tests[i]; delta /= tests[i];
} }
delta = Math.floor(delta); delta = Math.floor(delta);
return format.replace('%s', delta === 1 ? '1 week' : delta + ' weeks'); return {
tense,
value: delta,
unit: 'week'
};
} }

View File

@ -62,7 +62,7 @@ class StateInfo extends PolymerElement {
<template is="dom-if" if="[[inDialog]]"> <template is="dom-if" if="[[inDialog]]">
<div class="time-ago"> <div class="time-ago">
<ha-relative-time datetime="[[stateObj.last_changed]]"></ha-relative-time> <ha-relative-time hass="[[hass]]" datetime="[[stateObj.last_changed]]"></ha-relative-time>
</div> </div>
</template> </template>
<template is="dom-if" if="[[!inDialog]]"> <template is="dom-if" if="[[!inDialog]]">
@ -80,14 +80,9 @@ class StateInfo extends PolymerElement {
type: Boolean, type: Boolean,
value: false, value: false,
}, },
hass: Object,
stateObj: { stateObj: Object,
type: Object, inDialog: Boolean
},
inDialog: {
type: Boolean,
},
}; };
} }

View File

@ -3,9 +3,15 @@ import { PolymerElement } from '@polymer/polymer/polymer-element.js';
import relativeTime from '../common/datetime/relative_time.js'; import relativeTime from '../common/datetime/relative_time.js';
class HaRelativeTime extends PolymerElement { import LocalizeMixin from '../mixins/localize-mixin.js';
/*
* @appliesMixin LocalizeMixin
*/
class HaRelativeTime extends LocalizeMixin(PolymerElement) {
static get properties() { static get properties() {
return { return {
hass: Object,
datetime: { datetime: {
type: String, type: String,
observer: 'datetimeChanged', observer: 'datetimeChanged',
@ -16,9 +22,7 @@ class HaRelativeTime extends PolymerElement {
observer: 'datetimeObjChanged', observer: 'datetimeObjChanged',
}, },
parsedDateTime: { parsedDateTime: Object
type: Object,
},
}; };
} }
@ -51,9 +55,15 @@ class HaRelativeTime extends PolymerElement {
} }
updateRelative() { updateRelative() {
var root = dom(this); const root = dom(this);
root.innerHTML = this.parsedDateTime ? if (!this.parsedDateTime) {
relativeTime(this.parsedDateTime) : 'never'; root.innerHTML = this.localize('ui.components.relative_time.never');
} else {
const rel = relativeTime(this.parsedDateTime);
const time = this.localize(`ui.duration.${rel.unit}`, 'count', rel.value);
const relTime = this.localize(`ui.components.relative_time.${rel.tense}`, 'time', time);
root.innerHTML = relTime;
}
} }
} }

View File

@ -28,7 +28,7 @@ class MoreInfoAutomation extends LocalizeMixin(PolymerElement) {
<div> <div>
[[localize('ui.card.automation.last_triggered')]]: [[localize('ui.card.automation.last_triggered')]]:
</div> </div>
<ha-relative-time datetime="[[stateObj.attributes.last_triggered]]"></ha-relative-time> <ha-relative-time hass="[[hass]]" datetime="[[stateObj.attributes.last_triggered]]"></ha-relative-time>
</div> </div>
<div class="actions"> <div class="actions">

View File

@ -15,7 +15,7 @@ class MoreInfoSun extends PolymerElement {
<div class="data-entry layout justified horizontal"> <div class="data-entry layout justified horizontal">
<div class="key"> <div class="key">
<span>[[itemCaption(item)]]</span> <span>[[itemCaption(item)]]</span>
<ha-relative-time datetime-obj="[[itemDate(item)]]"></ha-relative-time> <ha-relative-time hass="[[hass]]" datetime-obj="[[itemDate(item)]]"></ha-relative-time>
</div> </div>
<div class="value">[[itemValue(item)]]</div> <div class="value">[[itemValue(item)]]</div>
</div> </div>
@ -29,10 +29,8 @@ class MoreInfoSun extends PolymerElement {
static get properties() { static get properties() {
return { return {
stateObj: { hass: Object,
type: Object, stateObj: Object,
},
risingDate: { risingDate: {
type: Object, type: Object,
computed: 'computeRising(stateObj)', computed: 'computeRising(stateObj)',

View File

@ -30,12 +30,13 @@ class StateCardClimate extends PolymerElement {
static get stateInfoTemplate() { static get stateInfoTemplate() {
return html` return html`
<state-info state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info> <state-info hass="[[hass]]" state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info>
`; `;
} }
static get properties() { static get properties() {
return { return {
hass: Object,
stateObj: Object, stateObj: Object,
inDialog: { inDialog: {
type: Boolean, type: Boolean,

View File

@ -33,12 +33,13 @@ class StateCardConfigurator extends PolymerElement {
static get stateInfoTemplate() { static get stateInfoTemplate() {
return html` return html`
<state-info state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info> <state-info hass="[[hass]]" state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info>
`; `;
} }
static get properties() { static get properties() {
return { return {
hass: Object,
stateObj: Object, stateObj: Object,
inDialog: { inDialog: {
type: Boolean, type: Boolean,

View File

@ -29,7 +29,7 @@ class StateCardCover extends PolymerElement {
static get stateInfoTemplate() { static get stateInfoTemplate() {
return html` return html`
<state-info state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info> <state-info hass="[[hass]]" state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info>
`; `;
} }

View File

@ -46,7 +46,7 @@ class StateCardDisplay extends LocalizeMixin(PolymerElement) {
static get stateInfoTemplate() { static get stateInfoTemplate() {
return html` return html`
<state-info state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info> <state-info hass="[[hass]]" state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info>
`; `;
} }

View File

@ -51,7 +51,7 @@ class StateCardInputNumber extends mixinBehaviors([
static get stateInfoTemplate() { static get stateInfoTemplate() {
return html` return html`
<state-info state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info> <state-info hass="[[hass]]" state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info>
`; `;
} }

View File

@ -25,7 +25,7 @@ class StateCardInputText extends PolymerElement {
static get stateInfoTemplate() { static get stateInfoTemplate() {
return html` return html`
<state-info state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info> <state-info hass="[[hass]]" state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info>
`; `;
} }
@ -44,14 +44,8 @@ class StateCardInputText extends PolymerElement {
observer: 'stateObjectChanged', observer: 'stateObjectChanged',
}, },
pattern: { pattern: String,
type: String, value: String
},
value: {
type: String,
}
}; };
} }

View File

@ -53,7 +53,7 @@ class StateCardMediaPlayer extends LocalizeMixin(PolymerElement) {
static get stateInfoTemplate() { static get stateInfoTemplate() {
return html` return html`
<state-info state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info> <state-info hass="[[hass]]" state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info>
`; `;
} }

View File

@ -32,7 +32,7 @@ class StateCardScene extends LocalizeMixin(PolymerElement) {
static get stateInfoTemplate() { static get stateInfoTemplate() {
return html` return html`
<state-info state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info> <state-info hass="[[hass]]" state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info>
`; `;
} }

View File

@ -43,7 +43,7 @@ class StateCardScript extends LocalizeMixin(PolymerElement) {
static get stateInfoTemplate() { static get stateInfoTemplate() {
return html` return html`
<state-info state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info> <state-info hass="[[hass]]" state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info>
`; `;
} }

View File

@ -36,7 +36,7 @@ class StateCardTimer extends LocalizeMixin(PolymerElement) {
static get stateInfoTemplate() { static get stateInfoTemplate() {
return html` return html`
<state-info state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info> <state-info hass="[[hass]]" state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info>
`; `;
} }

View File

@ -25,7 +25,7 @@ class StateCardToggle extends PolymerElement {
static get stateInfoTemplate() { static get stateInfoTemplate() {
return html` return html`
<state-info state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info> <state-info hass="[[hass]]" state-obj="[[stateObj]]" in-dialog="[[inDialog]]"></state-info>
`; `;
} }

View File

@ -377,12 +377,19 @@
"entity": "Entity" "entity": "Entity"
} }
}, },
"relative_time": {
"past": "{time} ago",
"future": "In {time}",
"never": "Never"
},
"service-picker": { "service-picker": {
"service": "Service" "service": "Service"
} }
}, },
"duration": { "duration": {
"second": "{count} {count, plural,\n one {second}\n other {seconds}\n}", "second": "{count} {count, plural,\n one {second}\n other {seconds}\n}",
"minute": "{count} {count, plural,\n one {minute}\n other {minutes}\n}",
"hour": "{count} {count, plural,\n one {hour}\n other {hours}\n}",
"day": "{count} {count, plural,\n one {day}\n other {days}\n}", "day": "{count} {count, plural,\n one {day}\n other {days}\n}",
"week": "{count} {count, plural,\n one {week}\n other {weeks}\n}" "week": "{count} {count, plural,\n one {week}\n other {weeks}\n}"
}, },

View File

@ -8,12 +8,12 @@
<body> <body>
<test-fixture id="stateInfoSecondaryLine"> <test-fixture id="stateInfoSecondaryLine">
<template> <template>
<state-info secondary-line><my-elem>text</my-elem></state-info> <state-info hass="[[hass]]" secondary-line><my-elem>text</my-elem></state-info>
</template> </template>
</test-fixture> </test-fixture>
<test-fixture id="stateInfo"> <test-fixture id="stateInfo">
<template> <template>
<state-info></state-info> <state-info hass="[[hass]]"></state-info>
</template> </template>
</test-fixture> </test-fixture>