Last Updated

100%
<!-- Default -->
<span class="js-last-updated" data-tstamp="1566213446">
    19.08.2019 - 13:17 Uhr
</span>

<!-- Date -->
<span class="js-last-updated" data-date="2019-10-09T13:17:49+02:00">
    19.08.2019 - 13:17 Uhr
</span>

<!-- Default -->
<span class="js-last-updated" data-tstamp="{{ tstamp }}">
    {{ datetime }}
</span>

<!-- Date -->
<span class="js-last-updated" data-date="{{ date }}">
    {{ datetime }}
</span>
/* Default */
{
  "additionalClasses": "",
  "tstamp": "1566213446",
  "datetime": "19.08.2019 - 13:17 Uhr"
}

/* Date */
{
  "additionalClasses": "",
  "tstamp": "1566213446",
  "datetime": "19.08.2019 - 13:17 Uhr",
  "date": "2019-10-09T13:17:49+02:00"
}

  • Content:
    import dayjs from 'dayjs';
    import relativeTime from 'dayjs/plugin/relativeTime';
    import dayOfYear from 'dayjs/plugin/dayOfYear';
    import 'dayjs/locale/de';
    
    dayjs.locale('de');
    dayjs.extend(relativeTime);
    dayjs.extend(dayOfYear);
    
    const h01 = 3600;
    const h06 = 21600;
    const h24 = 86400;
    
    class LastUpdated {
      /**
       * @param {Object} element
       * @param {Number} [datetime]
       */
      constructor(element, datetime) {
        let compare;
        if (!datetime) {
          compare = Math.floor(Date.now() / 1000);
        } else {
          compare = datetime;
        }
    
        let timestamp;
        if (element.dataset.date) {
          timestamp = Math.floor(Date.parse(element.dataset.date) / 1000);
        } else if (element.dataset.tstamp) {
          timestamp = element.dataset.tstamp;
        } else {
          return;
        }
    
        const text = this.convert(timestamp, compare);
        if (text) {
          // eslint-disable-next-line no-param-reassign
          element.innerText = text;
        }
      }
    
      /**
       * @param {Number} timestamp
       * @param {Number} compare
       * @return {String}
       */
      // eslint-disable-next-line class-methods-use-this
      convert(timestamp, compare) {
        const diff = compare - timestamp;
    
        if (diff > h24) {
          return '';
        }
    
        if (diff > h06) {
          // Today or yesterday?
          const prefix = dayjs.unix(compare)
            .dayOfYear() === dayjs.unix(timestamp)
            .dayOfYear() ? 'Heute, ' : 'Gestern, ';
    
          // dayjs(.localizedFormat) seems to NOT be capable of displaying localized suffix "Uhr" in
          // analogy to AM/PM
          return `${prefix + dayjs.unix(timestamp).format('H:mm')} Uhr`;
        }
    
        // Every timespan smaller than 6h hours can be handled with dayjs.relativeTime
        return dayjs.unix(timestamp)
          .from(dayjs.unix(compare));
      }
    }
    
    export { h01, h06, h24 };
    export default LastUpdated;
    
  • URL: /components/raw/last-updated/last-updated.js
  • Filesystem Path: src/patterns/20-components/last-updated/last-updated.js
  • Size: 1.8 KB
  • Content:
    import LastUpdated, { h01, h06, h24 } from './last-updated';
    
    describe('The last updated component', () => {
      test('does not touch the element when neither tstamp nor date a present', () => {
        const element = {
          dataset: {},
        };
        new LastUpdated(element);
        expect(element).toEqual(element);
      });
    
      describe('called with the property tstamp', () => {
        test('a few seconds ago', () => {
          const element = {
            dataset: {
              tstamp: Math.floor(Date.now() / 1000),
            },
          };
    
          new LastUpdated(element);
    
          expect(element.innerText).toBe('vor wenigen Sekunden');
        });
    
        test('under six hours', () => {
          let element = {
            dataset: {
              tstamp: Math.floor(Date.now() / 1000) - h06 + 20,
            },
          };
    
          new LastUpdated(element);
    
          expect(element.innerText).toMatch(/^vor 6 Stunden$/);
    
          element = {
            dataset: {
              tstamp: Math.floor(Date.now() / 1000) - h06 + h01,
            },
          };
    
          new LastUpdated(element);
    
          expect(element.innerText).toMatch(/^vor 5 Stunden$/);
        });
    
    
        test('under twenty four hours', () => {
          let element = {
            dataset: {
              tstamp: Math.floor(Date.now() / 1000) - h24 + 20,
            },
          };
    
          new LastUpdated(element);
    
          expect(element.innerText).toMatch(/^Gestern, \d+:\d+ Uhr$/);
    
          element = {
            dataset: {
              tstamp: Math.floor(Date.now() / 1000) - h06 - 20,
            },
          };
    
          new LastUpdated(element);
    
          expect(element.innerText).toMatch(/^Heute, \d+:\d+ Uhr$/);
        });
    
        test('above twenty four hours', () => {
          const element = {
            dataset: {
              tstamp: Math.floor(Date.now() / 1000) - h24 - 20,
            },
          };
    
          new LastUpdated(element);
    
          expect(element.innerText).toBeUndefined();
        });
      });
    
      describe('called with the property date', () => {
        test('a few seconds ago', () => {
          const test = '2019-10-09T13:17:49+02:00';
          const now = Math.floor(Date.parse(test) / 1000);
          const element = {
            dataset: {
              date: test,
            },
          };
    
          new LastUpdated(element, now);
    
          expect(element.innerText).toBe('vor wenigen Sekunden');
        });
    
        test('under six hours', () => {
          const test = '2019-10-09T07:17:49+02:00';
          const now = Math.floor(Date.parse('2019-10-09T13:17:49+02:00') / 1000);
          const element = {
            dataset: {
              date: test,
            },
          };
    
          new LastUpdated(element, now);
    
          expect(element.innerText).toMatch(/^vor 6 Stunden$/);
        });
    
        test('under six hours with different timezones', () => {
          const articleDate = '2019-10-09T07:17:49+02:00';
          const nowDate = Math.floor(Date.parse('2019-10-09T07:17:49+01:00') / 1000);
          const element = {
            dataset: {
              date: articleDate,
            },
          };
    
          new LastUpdated(element, nowDate);
    
          expect(element.innerText).toMatch(/^vor einer Stunde$/);
        });
    
        test('under twenty four hours', () => {
          const test = '2019-10-08T10:17:49+02:00';
          const now = Math.floor(Date.parse('2019-10-09T07:17:49+02:00') / 1000);
          const element = {
            dataset: {
              date: test,
            },
          };
    
          new LastUpdated(element, now);
    
          expect(element.innerText).toMatch(/^Gestern, \d+:\d+ Uhr$/);
        });
    
        test('above twenty four hours', () => {
          const test = '2019-10-08T07:17:49+02:00';
          const now = Math.floor(Date.parse('2019-10-09T10:17:49+02:00') / 1000);
          const element = {
            dataset: {
              date: test,
            },
          };
    
          new LastUpdated(element, now);
          expect(element.innerText).toBeUndefined();
        });
      });
    });
    
  • URL: /components/raw/last-updated/last-updated.test.js
  • Filesystem Path: src/patterns/20-components/last-updated/last-updated.test.js
  • Size: 3.7 KB

There are no notes for this item.