CommentDate Migration to Pack tag (#19025)

* migration init

* create an initializers directory

* remove console log

* migrate localDateTime functions and remove comment date from asset pipeline

* add unit test

* add one more

* year test
This commit is contained in:
Lawrence 2023-02-03 13:40:17 -06:00 committed by GitHub
parent 605ebbfa3b
commit 3186f7ae2d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 156 additions and 4 deletions

View file

@ -3,7 +3,7 @@
initializeAllTagEditButtons, initializeUserFollowButts,
initializeCommentsPage,
initializeArticleDate, initializeArticleReactions, initNotifications,
initializeCommentDate, initializeSettings,
initializeSettings,
initializeCommentPreview, initializeRuntimeBanner,
initializeTimeFixer, initializeDashboardSort,
initializeArchivedPostFilter, initializeCreditsPage,
@ -20,7 +20,6 @@ function callInitializers() {
initializeArticleDate();
initializeArticleReactions();
initNotifications();
initializeCommentDate();
initializeSettings();
initializeCommentPreview();
initializeTimeFixer();

View file

@ -451,6 +451,14 @@ function updateCommentsCount() {
commentsSidebarCountDiv.innerHTML = `${commentsCountData}`;
}
function initializeCommentDate() {
const commentsDates = document.querySelectorAll('.comment-date time');
if (commentsDates) {
addLocalizedDateTimeToElementsTitles(commentsDates, 'datetime');
}
}
function handleHiddenComments(commentableType){
const currentUser = userData();
const commentableAuthorIds = [];

View file

@ -0,0 +1,3 @@
import { initializeCommentDate } from "./initializers/initializeCommentDate";
initializeCommentDate();

View file

@ -0,0 +1,9 @@
import { addLocalizedDateTimeToElementsTitles } from "../../utilities/localDateTime";
export function initializeCommentDate() {
const commentsDates = document.querySelectorAll('.comment-date time');
if (commentsDates) {
addLocalizedDateTimeToElementsTitles(commentsDates, 'datetime');
}
}

View file

@ -0,0 +1,26 @@
import {timestampToLocalDateTime, addLocalizedDateTimeToElementsTitles } from '@utilities/localDateTime';
describe('LocalDateTime Utilities', () => {
it('should return empty string when no timestamp', () => {
const localTime = timestampToLocalDateTime(null, null, null)
expect(localTime).toEqual('');
});
it('should return readable date string', () => {
const localTime = timestampToLocalDateTime('2019-05-03T16:02:50.908Z', 'default', {})
expect(localTime).toEqual('5/3/2019');
});
it('should return formatted year when year option added', () => {
const localTime = timestampToLocalDateTime('2019-05-03T16:02:50.908Z', 'default', {year: '2-digit'})
expect(localTime).toEqual('19');
});
it('should add datetime attribute to element', () => {
document.body.setAttribute('datetime', 2222)
addLocalizedDateTimeToElementsTitles(document.querySelectorAll("body"), 'datetime')
// eslint-disable-next-line no-prototype-builtins
expect(document.querySelector('body').attributes.hasOwnProperty('datetime')).toBe(true);
});
});

View file

@ -0,0 +1,107 @@
/* Local date/time utilities */
/*
Convert string timestamp to local time, using the given locale.
timestamp should be something like '2019-05-03T16:02:50.908Z'
locale can be `navigator.language` or a custom locale. defaults to 'default'
options are `Intl.DateTimeFormat` options
see <https://developer.mozilla.org//docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat>
for more information.
*/
export function timestampToLocalDateTime(timestamp, locale, options) {
if (!timestamp) {
return '';
}
try {
const time = new Date(timestamp);
const formattedTime = new Intl.DateTimeFormat(
locale || 'default',
options,
).format(time);
return options.year === '2-digit'
? formattedTime.replace(', ', " '")
: formattedTime;
} catch (e) {
return '';
}
}
export function addLocalizedDateTimeToElementsTitles(elements, timestampAttribute) {
for (let i = 0; i < elements.length; i += 1) {
const element = elements[i];
// get UTC timestamp set by the server
const timestamp = element.getAttribute(timestampAttribute || 'datetime');
if (timestamp) {
// add a full datetime to the element title, visible on hover.
// `navigator.language` is used to allow the date to be localized
// according to the browser's locale
// see <https://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/language>
const localDateTime = timestampToLocalDateTimeLong(timestamp);
element.setAttribute('title', localDateTime);
}
}
}
export function localizeTimeElements(elements, timeOptions) {
for (let i = 0; i < elements.length; i += 1) {
const element = elements[i];
const timestamp = element.getAttribute('datetime');
if (timestamp) {
const localDateTime = timestampToLocalDateTime(
timestamp,
navigator.language,
timeOptions,
);
element.textContent = localDateTime;
}
}
}
function timestampToLocalDateTimeLong(timestamp) {
// example: "Wednesday, April 3, 2019, 2:55:14 PM"
return timestampToLocalDateTime(timestamp, navigator.language, {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
});
}
function timestampToLocalDateTimeShort(timestamp) {
// example: "10 Dec 2018" if it is not the current year
// example: "6 Sep" if it is the current year
if (timestamp) {
const currentYear = new Date().getFullYear();
const givenYear = new Date(timestamp).getFullYear();
const timeOptions = {
day: 'numeric',
month: 'short',
};
if (givenYear !== currentYear) {
timeOptions.year = 'numeric';
}
return timestampToLocalDateTime(timestamp, navigator.language, timeOptions);
}
return '';
}
if (typeof globalThis !== 'undefined') {
globalThis.timestampToLocalDateTimeLong = timestampToLocalDateTimeLong; // eslint-disable-line no-undef
globalThis.timestampToLocalDateTimeShort = timestampToLocalDateTimeShort; // eslint-disable-line no-undef
}

View file

@ -20,9 +20,9 @@
<%= render "layouts/styles", qualifier: "main" %>
<%= javascript_include_tag "base", defer: true %>
<% if user_signed_in? %>
<%= javascript_packs_with_chunks_tag "base", "Search", "runtimeBanner", "onboardingRedirectCheck", "contentDisplayPolicy", "baseTracking", defer: true %>
<%= javascript_packs_with_chunks_tag "base", "baseInitializers", "Search", "runtimeBanner", "onboardingRedirectCheck", "contentDisplayPolicy", "baseTracking", defer: true %>
<% else %>
<%= javascript_packs_with_chunks_tag "base", "Search", "runtimeBanner", "baseTracking", defer: true %>
<%= javascript_packs_with_chunks_tag "base", "baseInitializers", "Search", "runtimeBanner", "baseTracking", defer: true %>
<% end %>
<%= yield(:page_meta) %>
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">