dependencies: Remove XDate.

It’s even more unmaintained than Moment and doesn’t add any
functionality we don’t already have.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2021-02-05 12:20:14 -08:00 committed by Steve Howell
parent 952a8aa5fd
commit 9896782fd1
27 changed files with 154 additions and 204 deletions

View File

@ -337,14 +337,11 @@ run_test("user_last_seen_time_status", () => {
presence.last_active_date = (user_id) => {
assert.equal(user_id, old_user.user_id);
return {
clone: () => "date-stub",
};
return new Date(1526137743000);
};
timerender.last_seen_status_from_date = (date) => {
assert.equal(date, "date-stub");
assert.deepEqual(date, new Date(1526137743000));
return "May 12";
};

View File

@ -3,6 +3,7 @@
const {strict: assert} = require("assert");
const {JSDOM} = require("jsdom");
const MockDate = require("mockdate");
const rewiremock = require("rewiremock/node");
const {stub_templates} = require("../zjsunit/handlebars");
@ -71,6 +72,9 @@ set_global("ui_util", {});
document.location.protocol = "https:";
document.location.host = "foo.com";
const fake_now = 555;
MockDate.set(new Date(fake_now * 1000));
zrequire("zcommand");
zrequire("compose_ui");
const peer_data = zrequire("peer_data");
@ -745,11 +749,9 @@ run_test("send_message", () => {
};
const server_message_id = 127;
const fake_now = 555;
local_message.insert_message = (message) => {
assert.equal(message.timestamp, fake_now);
};
local_message.now = () => fake_now;
markdown.apply_markdown = () => {};
markdown.add_topic_links = () => {};
@ -1950,3 +1952,5 @@ run_test("test_video_chat_button_toggle", () => {
compose.initialize();
assert.equal($("#below-compose-content .video_link").visible(), true);
});
MockDate.reset();

View File

@ -2,8 +2,6 @@
const {strict: assert} = require("assert");
const XDate = require("xdate");
const {stub_templates} = require("../zjsunit/handlebars");
const {set_global, with_field, zrequire} = require("../zjsunit/namespace");
const {run_test} = require("../zjsunit/test");
@ -307,7 +305,7 @@ run_test("format_drafts", (override) => {
const stub_render_now = timerender.render_now;
timerender.render_now = function (time) {
return stub_render_now(time, new XDate(1549958107000));
return stub_render_now(time, new Date(1549958107000));
};
stub_templates((template_name, data) => {

View File

@ -2,17 +2,20 @@
const {strict: assert} = require("assert");
const MockDate = require("mockdate");
const {set_global, zrequire} = require("../zjsunit/namespace");
const {run_test} = require("../zjsunit/test");
const {make_zjquery} = require("../zjsunit/zjquery");
set_global("$", make_zjquery());
set_global("local_message", {});
set_global("markdown", {});
set_global("local_message", {
now: () => "timestamp",
});
set_global("page_params", {});
const fake_now = 555;
MockDate.set(new Date(fake_now * 1000));
zrequire("echo");
const people = zrequire("people");
@ -207,7 +210,7 @@ run_test("insert_local_message", () => {
local_message.insert_message = (message) => {
assert.equal(message.display_recipient, "general");
assert.equal(message.timestamp, "timestamp");
assert.equal(message.timestamp, fake_now);
assert.equal(message.sender_email, "iago@zulip.com");
assert.equal(message.sender_full_name, "Iago");
assert.equal(message.sender_id, 123);
@ -248,3 +251,5 @@ run_test("insert_local_message", () => {
assert(apply_markdown_called);
assert(insert_message_called);
});
MockDate.reset();

View File

@ -405,7 +405,6 @@ run_test("user_timezone", () => {
page_params.twenty_four_hour_time = true;
assert.equal(people.get_user_time(me.user_id), "0:09");
expected_pref.format = "h:mm A";
page_params.twenty_four_hour_time = false;
assert.equal(people.get_user_time(me.user_id), "12:09 AM");
});

View File

@ -2,8 +2,6 @@
const {strict: assert} = require("assert");
const XDate = require("xdate");
const {set_global, zrequire} = require("../zjsunit/namespace");
const {run_test} = require("../zjsunit/test");
@ -183,7 +181,7 @@ run_test("set_presence_info", () => {
last_active: recent,
});
assert.equal(presence.get_status(alice.user_id), "active");
assert.deepEqual(presence.last_active_date(alice.user_id), new XDate(recent * 1000));
assert.deepEqual(presence.last_active_date(alice.user_id), new Date(recent * 1000));
assert.deepEqual(presence.presence_info.get(fred.user_id), {status: "idle", last_active: now});
assert.equal(presence.get_status(fred.user_id), "idle");
@ -288,7 +286,7 @@ run_test("last_active_date", () => {
assert.equal(presence.last_active_date(unknown_id), undefined);
assert.equal(presence.last_active_date(fred.user_id), undefined);
assert.deepEqual(presence.last_active_date(alice.user_id), new XDate(500 * 1000));
assert.deepEqual(presence.last_active_date(alice.user_id), new Date(500 * 1000));
});
run_test("update_info_from_event", () => {

View File

@ -7,7 +7,6 @@ const {run_test} = require("../zjsunit/test");
const {make_zjquery} = require("../zjsunit/zjquery");
set_global("$", make_zjquery());
set_global("XDate", zrequire("XDate", "xdate"));
zrequire("timerender");
zrequire("settings_muting");

View File

@ -2,8 +2,8 @@
const {strict: assert} = require("assert");
const {add} = require("date-fns");
const MockDate = require("mockdate");
const XDate = require("xdate");
const {set_global, zrequire} = require("../zjsunit/namespace");
const {run_test} = require("../zjsunit/test");
@ -17,7 +17,7 @@ set_global("page_params", {
zrequire("timerender");
run_test("render_now_returns_today", () => {
const today = new XDate(1555091573000); // Friday 4/12/2019 5:52:53 PM (UTC+0)
const today = new Date(1555091573000); // Friday 4/12/2019 5:52:53 PM (UTC+0)
const expected = {
time_str: i18n.t("Today"),
formal_time_str: "Friday, April 12, 2019",
@ -30,8 +30,8 @@ run_test("render_now_returns_today", () => {
});
run_test("render_now_returns_yesterday", () => {
const today = new XDate(1555091573000); // Friday 4/12/2019 5:52:53 PM (UTC+0)
const yesterday = today.clone().addDays(-1);
const today = new Date(1555091573000); // Friday 4/12/2019 5:52:53 PM (UTC+0)
const yesterday = add(today, {days: -1});
const expected = {
time_str: i18n.t("Yesterday"),
formal_time_str: "Thursday, April 11, 2019",
@ -44,8 +44,8 @@ run_test("render_now_returns_yesterday", () => {
});
run_test("render_now_returns_year", () => {
const today = new XDate(1555091573000); // Friday 4/12/2019 5:52:53 PM (UTC+0)
const year_ago = today.clone().addYears(-1);
const today = new Date(1555091573000); // Friday 4/12/2019 5:52:53 PM (UTC+0)
const year_ago = add(today, {years: -1});
const expected = {
time_str: "Apr 12, 2018",
formal_time_str: "Thursday, April 12, 2018",
@ -58,8 +58,8 @@ run_test("render_now_returns_year", () => {
});
run_test("render_now_returns_month_and_day", () => {
const today = new XDate(1555091573000); // Friday 4/12/2019 5:52:53 PM (UTC+0)
const three_months_ago = today.clone().addMonths(-3, true);
const today = new Date(1555091573000); // Friday 4/12/2019 5:52:53 PM (UTC+0)
const three_months_ago = add(today, {months: -3});
const expected = {
time_str: "Jan 12",
formal_time_str: "Saturday, January 12, 2019",
@ -72,22 +72,22 @@ run_test("render_now_returns_month_and_day", () => {
});
run_test("render_now_returns_year_with_year_boundary", () => {
const today = new XDate(1555091573000); // Friday 4/12/2019 5:52:53 PM (UTC+0)
const three_months_ago = today.clone().addMonths(-6, true);
const today = new Date(1555091573000); // Friday 4/12/2019 5:52:53 PM (UTC+0)
const six_months_ago = add(today, {months: -6});
const expected = {
time_str: "Oct 12, 2018",
formal_time_str: "Friday, October 12, 2018",
needs_update: false,
};
const actual = timerender.render_now(three_months_ago, today);
const actual = timerender.render_now(six_months_ago, today);
assert.equal(actual.time_str, expected.time_str);
assert.equal(actual.formal_time_str, expected.formal_time_str);
assert.equal(actual.needs_update, expected.needs_update);
});
run_test("render_date_renders_time_html", () => {
const today = new XDate(1555091573000); // Friday 4/12/2019 5:52:53 PM (UTC+0)
const message_time = today.clone();
const today = new Date(1555091573000); // Friday 4/12/2019 5:52:53 PM (UTC+0)
const message_time = today;
const expected_html = i18n.t("Today");
const attrs = {};
@ -110,9 +110,9 @@ run_test("render_date_renders_time_html", () => {
});
run_test("render_date_renders_time_above_html", () => {
const today = new XDate(1555091573000); // Friday 4/12/2019 5:52:53 PM (UTC+0)
const message_time = today.clone();
const message_time_above = today.clone().addDays(-1);
const today = new Date(1555091573000); // Friday 4/12/2019 5:52:53 PM (UTC+0)
const message_time = today;
const message_time_above = add(today, {days: -1});
const span_stub = $("<span />");
@ -244,60 +244,59 @@ run_test("set_full_datetime", () => {
run_test("last_seen_status_from_date", () => {
// Set base_date to March 1 2016 12.30 AM (months are zero based)
let base_date = new XDate(2016, 2, 1, 0, 30);
let base_date = new Date(2016, 2, 1, 0, 30);
function assert_same(modifier, expected_status) {
let past_date = base_date.clone();
past_date = modifier(past_date);
function assert_same(duration, expected_status) {
const past_date = add(base_date, duration);
const actual_status = timerender.last_seen_status_from_date(past_date, base_date);
assert.equal(actual_status, expected_status);
}
assert_same((d) => d.addSeconds(-20), i18n.t("Just now"));
assert_same({seconds: -20}, i18n.t("Just now"));
assert_same((d) => d.addMinutes(-1), i18n.t("Just now"));
assert_same({minutes: -1}, i18n.t("Just now"));
assert_same((d) => d.addMinutes(-2), i18n.t("Just now"));
assert_same({minutes: -2}, i18n.t("Just now"));
assert_same((d) => d.addMinutes(-30), i18n.t("30 minutes ago"));
assert_same({minutes: -30}, i18n.t("30 minutes ago"));
assert_same((d) => d.addHours(-1), i18n.t("Yesterday"));
assert_same({hours: -1}, i18n.t("Yesterday"));
assert_same((d) => d.addHours(-2), i18n.t("Yesterday"));
assert_same({hours: -2}, i18n.t("Yesterday"));
assert_same((d) => d.addHours(-20), i18n.t("Yesterday"));
assert_same({hours: -20}, i18n.t("Yesterday"));
assert_same((d) => d.addDays(-1), i18n.t("Yesterday"));
assert_same({days: -1}, i18n.t("Yesterday"));
assert_same((d) => d.addDays(-2), i18n.t("2 days ago"));
assert_same({days: -2}, i18n.t("2 days ago"));
assert_same((d) => d.addDays(-61), i18n.t("61 days ago"));
assert_same({days: -61}, i18n.t("61 days ago"));
assert_same((d) => d.addDays(-300), i18n.t("May 06,\u00A02015"));
assert_same({days: -300}, i18n.t("May 06,\u00A02015"));
assert_same((d) => d.addDays(-366), i18n.t("Mar 01,\u00A02015"));
assert_same({days: -366}, i18n.t("Mar 01,\u00A02015"));
assert_same((d) => d.addYears(-3), i18n.t("Mar 01,\u00A02013"));
assert_same({years: -3}, i18n.t("Mar 01,\u00A02013"));
// Set base_date to May 1 2016 12.30 AM (months are zero based)
base_date = new XDate(2016, 4, 1, 0, 30);
base_date = new Date(2016, 4, 1, 0, 30);
assert_same((d) => d.addDays(-91), i18n.t("Jan\u00A031"));
assert_same({days: -91}, i18n.t("Jan\u00A031"));
// Set base_date to May 1 2016 10.30 PM (months are zero based)
base_date = new XDate(2016, 4, 2, 23, 30);
base_date = new Date(2016, 4, 2, 23, 30);
assert_same((d) => d.addHours(-1), i18n.t("An hour ago"));
assert_same({hours: -1}, i18n.t("An hour ago"));
assert_same((d) => d.addHours(-2), i18n.t("2 hours ago"));
assert_same({hours: -2}, i18n.t("2 hours ago"));
assert_same((d) => d.addHours(-12), i18n.t("12 hours ago"));
assert_same({hours: -12}, i18n.t("12 hours ago"));
assert_same((d) => d.addHours(-24), i18n.t("Yesterday"));
assert_same({hours: -24}, i18n.t("Yesterday"));
});
run_test("set_full_datetime", () => {
let time = new XDate(1549958107000); // Tuesday 2/12/2019 07:55:07 AM (UTC+0)
let time = new Date(1549958107000); // Tuesday 2/12/2019 07:55:07 AM (UTC+0)
let time_str = timerender.stringify_time(time);
let expected = "07:55";
assert.equal(time_str, expected);
@ -307,7 +306,7 @@ run_test("set_full_datetime", () => {
expected = "7:55 AM";
assert.equal(time_str, expected);
time = new XDate(1549979707000); // Tuesday 2/12/2019 13:55:07 PM (UTC+0)
time = new Date(1549979707000); // Tuesday 2/12/2019 13:55:07 PM (UTC+0)
page_params.twenty_four_hour_time = false;
time_str = timerender.stringify_time(time);
expected = "1:55 PM";

View File

@ -74,7 +74,6 @@
"webpack-cli": "^3.3.2",
"webpack4-bundle-tracker": "^0.0.1-beta",
"winchan": "^0.2.1",
"xdate": "^0.8.2",
"xvfb": "^0.4.0",
"zxcvbn": "^4.4.2"
},

View File

@ -1,27 +1,24 @@
"use strict";
const {format, isSameDay} = require("date-fns");
const _ = require("lodash");
const XDate = require("xdate");
const render_archive_message_group = require("../templates/archive_message_group.hbs");
function should_separate_into_groups(current_msg_time, next_msg_time) {
const current_time = new XDate(current_msg_time * 1000);
const next_time = new XDate(next_msg_time * 1000);
return current_time.toDateString() !== next_time.toDateString();
return isSameDay(current_msg_time * 1000, next_msg_time * 1000);
}
function all_message_timestamps_to_human_readable() {
$(".message_time").each(function () {
const time = new XDate(Number.parseInt($(this).text(), 10) * 1000);
$(this).text(time.toString("h:mm TT"));
$(this).text(format(Number.parseInt($(this).text(), 10) * 1000, "h:mm a"));
});
}
exports.initialize = function () {
const all_message_groups = [];
let current_message_group = {};
const today = new XDate();
const today = new Date();
const recipient_and_topic = $("#display_recipient").html();
const stream_name = recipient_and_topic.split("-")[0];
const topic = recipient_and_topic.split("-")[1];
@ -33,8 +30,8 @@ exports.initialize = function () {
current_message_group.background_color = recipient_color;
function separate_into_groups(current_message_row, cur_msg_time, next_msg_time) {
const time = new XDate(next_msg_time * 1000);
const prev_time = new XDate(cur_msg_time * 1000);
const time = new Date(next_msg_time * 1000);
const prev_time = new Date(cur_msg_time * 1000);
current_message_group.message_containers.push(current_message_row[0].outerHTML);
const date_element = timerender.render_date(prev_time, undefined, today)[0];
current_message_group.date = date_element.outerHTML;
@ -73,7 +70,7 @@ exports.initialize = function () {
return;
}
current_message_group.message_containers.push(current_message_row[0].outerHTML);
const time = new XDate(cur_msg_time * 1000);
const time = new Date(cur_msg_time * 1000);
const date_element = timerender.render_date(time, undefined, today)[0];
current_message_group.date = date_element.outerHTML;
});

View File

@ -1,7 +1,5 @@
"use strict";
const XDate = require("xdate");
const render_settings_upload_space_stats = require("../templates/settings/upload_space_stats.hbs");
const render_uploaded_files_list = require("../templates/uploaded_files_list.hbs");
@ -112,7 +110,7 @@ function render_attachments_ui() {
function format_attachment_data(new_attachments) {
for (const attachment of new_attachments) {
const time = new XDate(attachment.create_time);
const time = new Date(attachment.create_time);
attachment.create_time_str = timerender.render_now(time).time_str;
attachment.size_str = exports.bytes_to_size(attachment.size);
}

View File

@ -173,7 +173,7 @@ exports.user_last_seen_time_status = function (user_id) {
if (last_active_date === undefined) {
return i18n.t("More than 2 weeks ago");
}
return timerender.last_seen_status_from_date(last_active_date.clone());
return timerender.last_seen_status_from_date(last_active_date);
};
exports.info_for = function (user_id) {

View File

@ -2,7 +2,6 @@
const {subDays} = require("date-fns");
const Handlebars = require("handlebars/runtime");
const XDate = require("xdate");
const render_draft_table_body = require("../templates/draft_table_body.hbs");
@ -221,7 +220,7 @@ exports.remove_old_drafts = function () {
exports.format_draft = function (draft) {
const id = draft.id;
let formatted;
const time = new XDate(draft.updatedAt);
const time = new Date(draft.updatedAt);
let time_stamp = timerender.render_now(time).time_str;
if (time_stamp === i18n.t("Today")) {
time_stamp = timerender.stringify_time(time);

View File

@ -129,7 +129,7 @@ exports.insert_local_message = function (message_request, local_id_float) {
message.sender_email = people.my_current_email();
message.sender_full_name = people.my_full_name();
message.avatar_url = page_params.avatar_url;
message.timestamp = local_message.now();
message.timestamp = Date.now() / 1000;
message.local_id = local_id_float.toString();
message.locally_echoed = true;
message.id = local_id_float;

View File

@ -1,7 +1,5 @@
"use strict";
const XDate = require("xdate");
let is_floating_recipient_bar_showing = false;
function top_offset(elem) {
@ -98,8 +96,8 @@ exports.get_date = function (elem) {
return undefined;
}
const time = new XDate(message.timestamp * 1000);
const today = new XDate();
const time = new Date(message.timestamp * 1000);
const today = new Date();
const rendered_date = timerender.render_date(time, undefined, today)[0].outerHTML;
return rendered_date;

View File

@ -1,17 +1,9 @@
"use strict";
const XDate = require("xdate");
function truncate_precision(float) {
return Number.parseFloat(float.toFixed(3));
}
exports.now = function () {
const timestamp = new XDate().getTime() / 1000;
return timestamp;
};
exports.insert_message = function (message) {
// It is a little bit funny to go through the message_events
// codepath, but it's sort of the idea behind local echo that

View File

@ -1,7 +1,6 @@
"use strict";
const ClipboardJS = require("clipboard");
const XDate = require("xdate");
const render_message_edit_form = require("../templates/message_edit_form.hbs");
const render_topic_edit_form = require("../templates/topic_edit_form.hbs");
@ -32,8 +31,6 @@ const editability_types = {
exports.editability_types = editability_types;
function is_topic_editable(message, edit_limit_seconds_buffer = 0) {
const now = new XDate();
if (!page_params.realm_allow_message_editing) {
// If message editing is disabled, so is topic editing.
return false;
@ -55,7 +52,7 @@ function is_topic_editable(message, edit_limit_seconds_buffer = 0) {
return (
page_params.realm_community_topic_editing_limit_seconds +
edit_limit_seconds_buffer +
now.diffSeconds(message.timestamp * 1000) >
(message.timestamp - Date.now() / 1000) >
0
);
}
@ -94,11 +91,10 @@ function get_editability(message, edit_limit_seconds_buffer = 0) {
return editability_types.NO;
}
const now = new XDate();
if (
page_params.realm_message_content_edit_limit_seconds +
edit_limit_seconds_buffer +
now.diffSeconds(message.timestamp * 1000) >
(message.timestamp - Date.now() / 1000) >
0 &&
message.sent_by_me
) {
@ -134,15 +130,13 @@ exports.get_deletability = function (message) {
return true;
}
if (page_params.realm_allow_message_deleting) {
const now = new XDate();
if (
page_params.realm_message_content_delete_limit_seconds +
now.diffSeconds(message.timestamp * 1000) >
if (
page_params.realm_allow_message_deleting &&
page_params.realm_message_content_delete_limit_seconds +
(message.timestamp - Date.now() / 1000) >
0
) {
return true;
}
) {
return true;
}
return false;
};
@ -420,10 +414,9 @@ function edit_message(row, raw_content) {
// If you change this number also change edit_limit_buffer in
// zerver.views.message_edit.update_message_backend
const min_seconds_to_edit = 10;
const now = new XDate();
let seconds_left =
page_params.realm_message_content_edit_limit_seconds +
now.diffSeconds(message.timestamp * 1000);
(message.timestamp - Date.now() / 1000);
seconds_left = Math.floor(Math.max(seconds_left, min_seconds_to_edit));
// I believe this needs to be defined outside the countdown_timer, since

View File

@ -1,6 +1,6 @@
"use strict";
const XDate = require("xdate");
const {format, isSameDay} = require("date-fns");
const render_message_edit_history = require("../templates/message_edit_history.hbs");
@ -12,16 +12,15 @@ exports.fetch_and_render_message_history = function (message) {
data: {message_id: JSON.stringify(message.id)},
success(data) {
const content_edit_history = [];
let prev_datestamp = null;
let prev_time = null;
for (const [index, msg] of data.message_history.entries()) {
// Format times and dates nicely for display
const time = new XDate(msg.timestamp * 1000);
const datestamp = time.toDateString();
const time = new Date(msg.timestamp * 1000);
const item = {
timestamp: timerender.stringify_time(time),
display_date: time.toString("MMMM d, yyyy"),
show_date_row: datestamp !== prev_datestamp,
display_date: format(time, "MMMM d, yyyy"),
show_date_row: prev_time === null || !isSameDay(time, prev_time),
};
if (msg.user_id) {
@ -51,7 +50,7 @@ exports.fetch_and_render_message_history = function (message) {
content_edit_history.push(item);
prev_datestamp = datestamp;
prev_time = time;
}
$("#message-history").attr("data-message-id", message.id);
$("#message-history").html(

View File

@ -1,7 +1,7 @@
"use strict";
const {isSameDay} = require("date-fns");
const _ = require("lodash");
const XDate = require("xdate");
const render_bookend = require("../templates/bookend.hbs");
const render_message_group = require("../templates/message_group.hbs");
@ -16,10 +16,7 @@ function same_day(earlier_msg, later_msg) {
if (earlier_msg === undefined || later_msg === undefined) {
return false;
}
const earlier_time = new XDate(earlier_msg.msg.timestamp * 1000);
const later_time = new XDate(later_msg.msg.timestamp * 1000);
return earlier_time.toDateString() === later_time.toDateString();
return isSameDay(earlier_msg.msg.timestamp * 1000, later_msg.msg.timestamp * 1000);
}
function same_sender(a, b) {
@ -37,20 +34,20 @@ function same_recipient(a, b) {
}
function render_group_display_date(group, message_container) {
const time = new XDate(message_container.msg.timestamp * 1000);
const today = new XDate();
const time = new Date(message_container.msg.timestamp * 1000);
const today = new Date();
const date_element = timerender.render_date(time, undefined, today)[0];
group.date = date_element.outerHTML;
}
function update_group_date_divider(group, message_container, prev) {
const time = new XDate(message_container.msg.timestamp * 1000);
const today = new XDate();
const time = new Date(message_container.msg.timestamp * 1000);
const today = new Date();
if (prev !== undefined) {
const prev_time = new XDate(prev.msg.timestamp * 1000);
if (time.toDateString() !== prev_time.toDateString()) {
const prev_time = new Date(prev.msg.timestamp * 1000);
if (!isSameDay(time, prev_time)) {
// NB: group_date_divider_html is HTML, inserted into the document without escaping.
group.group_date_divider_html = timerender.render_date(
time,
@ -87,9 +84,9 @@ function update_message_date_divider(opts) {
return;
}
const prev_time = new XDate(prev_msg_container.msg.timestamp * 1000);
const curr_time = new XDate(curr_msg_container.msg.timestamp * 1000);
const today = new XDate();
const prev_time = new Date(prev_msg_container.msg.timestamp * 1000);
const curr_time = new Date(curr_msg_container.msg.timestamp * 1000);
const today = new Date();
curr_msg_container.want_date_divider = true;
curr_msg_container.date_divider_html = timerender.render_date(
@ -100,7 +97,7 @@ function update_message_date_divider(opts) {
}
function set_timestr(message_container) {
const time = new XDate(message_container.msg.timestamp * 1000);
const time = new Date(message_container.msg.timestamp * 1000);
message_container.timestr = timerender.stringify_time(time);
}
@ -182,8 +179,8 @@ class MessageListView {
last_edit_timestamp = message_container.msg.last_edit_timestamp;
}
if (last_edit_timestamp !== undefined) {
const last_edit_time = new XDate(last_edit_timestamp * 1000);
const today = new XDate();
const last_edit_time = new Date(last_edit_timestamp * 1000);
const today = new Date();
return (
timerender.render_date(last_edit_time, undefined, today)[0].textContent +
" at " +

View File

@ -1,7 +1,5 @@
"use strict";
const XDate = require("xdate");
const {FoldDict} = require("./fold_dict");
const muted_topics = new Map();
@ -42,7 +40,7 @@ exports.get_muted_topics = function () {
const stream = stream_data.maybe_get_stream_name(stream_id);
for (const topic of sub_dict.keys()) {
const date_muted = sub_dict.get(topic);
const date_muted_str = timerender.render_now(new XDate(date_muted)).time_str;
const date_muted_str = timerender.render_now(new Date(date_muted)).time_str;
topics.push({
stream_id,
stream,

View File

@ -1,7 +1,5 @@
"use strict";
const XDate = require("xdate");
const people = require("./people");
// This module just manages data. See activity.js for
@ -245,8 +243,7 @@ exports.last_active_date = function (user_id) {
return undefined;
}
const date = new XDate(info.last_active * 1000);
return date;
return new Date(info.last_active * 1000);
};
exports.initialize = function (params) {

View File

@ -1,7 +1,5 @@
"use strict";
const XDate = require("xdate");
const render_recent_topic_row = require("../templates/recent_topic_row.hbs");
const render_recent_topics_filters = require("../templates/recent_topics_filters.hbs");
const render_recent_topics_body = require("../templates/recent_topics_table.hbs");
@ -167,7 +165,7 @@ function format_topic(topic_data) {
return {};
}
const topic = last_msg.topic;
const time = new XDate(last_msg.timestamp * 1000);
const time = new Date(last_msg.timestamp * 1000);
const last_msg_time = timerender.last_seen_status_from_date(time);
const full_datetime = timerender.get_full_datetime(time);

View File

@ -1,7 +1,5 @@
"use strict";
const XDate = require("xdate");
const render_admin_export_list = require("../templates/admin_export_list.hbs");
const people = require("./people");
@ -39,13 +37,13 @@ exports.populate_exports_table = function (exports) {
if (failed_timestamp !== null) {
failed_timestamp = timerender.last_seen_status_from_date(
new XDate(failed_timestamp * 1000),
new Date(failed_timestamp * 1000),
);
}
if (deleted_timestamp !== null) {
deleted_timestamp = timerender.last_seen_status_from_date(
new XDate(deleted_timestamp * 1000),
new Date(deleted_timestamp * 1000),
);
}
@ -55,7 +53,7 @@ exports.populate_exports_table = function (exports) {
acting_user: people.get_full_name(data.acting_user_id),
// Convert seconds -> milliseconds
event_time: timerender.last_seen_status_from_date(
new XDate(data.export_time * 1000),
new Date(data.export_time * 1000),
),
url: data.export_url,
time_failed: failed_timestamp,

View File

@ -1,24 +1,18 @@
"use strict";
const {format, parseISO, isValid} = require("date-fns");
const XDate = require("xdate");
const {
differenceInMinutes,
differenceInCalendarDays,
format,
formatISO,
isValid,
parseISO,
startOfToday,
} = require("date-fns");
let next_timerender_id = 0;
const set_to_start_of_day = function (time) {
return time.setMilliseconds(0).setSeconds(0).setMinutes(0).setHours(0);
};
function calculate_days_old_from_time(time, today) {
const start_of_today = set_to_start_of_day(today ? today.clone() : new XDate());
const start_of_other_day = set_to_start_of_day(time.clone());
const days_old = Math.round(start_of_other_day.diffDays(start_of_today));
const is_older_year = start_of_today.getFullYear() - start_of_other_day.getFullYear() > 0;
return {days_old, is_older_year};
}
// Given an XDate object 'time', returns an object:
// Given a Date object 'time', returns an object:
// {
// time_str: a string for the current human-formatted version
// formal_time_str: a string for the current formally formatted version
@ -26,13 +20,13 @@ function calculate_days_old_from_time(time, today) {
// needs_update: a boolean for if it will need to be updated when the
// day changes
// }
exports.render_now = function (time, today) {
exports.render_now = function (time, today = new Date()) {
let time_str = "";
let needs_update = false;
// render formal time to be used as title attr tooltip
// "\xa0" is U+00A0 NO-BREAK SPACE.
// Can't use &nbsp; as that represents the literal string "&nbsp;".
const formal_time_str = time.toString("dddd,\u00A0MMMM\u00A0d,\u00A0yyyy");
const formal_time_str = format(time, "EEEE,\u00A0MMMM\u00A0d,\u00A0yyyy");
// How many days old is 'time'? 0 = today, 1 = yesterday, 7 = a
// week ago, -1 = tomorrow, etc.
@ -40,7 +34,7 @@ exports.render_now = function (time, today) {
// Presumably the result of diffDays will be an integer in this
// case, but round it to be sure before comparing to integer
// constants.
const {days_old, is_older_year} = calculate_days_old_from_time(time, today);
const days_old = differenceInCalendarDays(today, time);
if (days_old === 0) {
time_str = i18n.t("Today");
@ -48,15 +42,15 @@ exports.render_now = function (time, today) {
} else if (days_old === 1) {
time_str = i18n.t("Yesterday");
needs_update = true;
} else if (is_older_year) {
} else if (time.getFullYear() !== today.getFullYear()) {
// For long running servers, searching backlog can get ambiguous
// without a year stamp. Only show year if message is from an older year
time_str = time.toString("MMM\u00A0dd,\u00A0yyyy");
time_str = format(time, "MMM\u00A0dd,\u00A0yyyy");
needs_update = false;
} else {
// For now, if we get a message from tomorrow, we don't bother
// rewriting the timestamp when it gets to be tomorrow.
time_str = time.toString("MMM\u00A0dd");
time_str = format(time, "MMM\u00A0dd");
needs_update = false;
}
return {
@ -67,19 +61,16 @@ exports.render_now = function (time, today) {
};
// Current date is passed as an argument for unit testing
exports.last_seen_status_from_date = function (last_active_date, current_date) {
if (typeof current_date === "undefined") {
current_date = new XDate();
}
const minutes = Math.floor(last_active_date.diffMinutes(current_date));
exports.last_seen_status_from_date = function (last_active_date, current_date = new Date()) {
const minutes = differenceInMinutes(current_date, last_active_date);
if (minutes <= 2) {
return i18n.t("Just now");
}
if (minutes < 60) {
return i18n.t("__minutes__ minutes ago", {minutes});
}
const {days_old, is_older_year} = calculate_days_old_from_time(last_active_date, current_date);
const days_old = differenceInCalendarDays(current_date, last_active_date);
const hours = Math.floor(minutes / 60);
if (days_old === 0) {
@ -95,27 +86,31 @@ exports.last_seen_status_from_date = function (last_active_date, current_date) {
if (days_old < 90) {
return i18n.t("__days_old__ days ago", {days_old});
} else if (days_old > 90 && days_old < 365 && !is_older_year) {
} else if (
days_old > 90 &&
days_old < 365 &&
last_active_date.getFullYear() === current_date.getFullYear()
) {
// Online more than 90 days ago, in the same year
return i18n.t("__last_active_date__", {
last_active_date: last_active_date.toString("MMM\u00A0dd"),
last_active_date: format(last_active_date, "MMM\u00A0dd"),
});
}
return i18n.t("__last_active_date__", {
last_active_date: last_active_date.toString("MMM\u00A0dd,\u00A0yyyy"),
last_active_date: format(last_active_date, "MMM\u00A0dd,\u00A0yyyy"),
});
};
// List of the dates that need to be updated when the day changes.
// Each timestamp is represented as a list of length 2:
// [id of the span element, XDate representing the time]
// [id of the span element, Date representing the time]
let update_list = [];
// The time at the beginning of the next day, when the timestamps are updated.
// Represented as an XDate with hour, minute, second, millisecond 0.
let next_update;
// The time at the beginning of the day, when the timestamps were updated.
// Represented as a Date with hour, minute, second, millisecond 0.
let last_update;
exports.initialize = function () {
next_update = set_to_start_of_day(new XDate()).addDays(1);
last_update = startOfToday();
};
// time_above is an optional argument, to support dates that look like:
@ -143,7 +138,7 @@ function render_date_span(elem, rendered_time, rendered_time_above) {
return elem.attr("title", rendered_time.formal_time_str);
}
// Given an XDate object 'time', return a DOM node that initially
// Given an Date object 'time', return a DOM node that initially
// displays the human-formatted date, and is updated automatically as
// necessary (e.g. changing "Today" to "Yesterday" to "Jul 1").
// If two dates are given, it renders them as:
@ -186,8 +181,8 @@ exports.render_markdown_timestamp = function (time, text) {
// This isn't expected to be called externally except manually for
// testing purposes.
exports.update_timestamps = function () {
const now = new XDate();
if (now >= next_update) {
const today = startOfToday();
if (today !== last_update) {
const to_process = update_list;
update_list = [];
@ -201,9 +196,9 @@ exports.update_timestamps = function () {
for (const element of elements) {
const time = entry.time;
const time_above = entry.time_above;
const rendered_time = exports.render_now(time);
const rendered_time = exports.render_now(time, today);
if (time_above) {
const rendered_time_above = exports.render_now(time_above);
const rendered_time_above = exports.render_now(time_above, today);
render_date_span($(element), rendered_time, rendered_time_above);
} else {
render_date_span($(element), rendered_time);
@ -218,7 +213,7 @@ exports.update_timestamps = function () {
}
}
next_update = set_to_start_of_day(now.clone().addDays(1));
last_update = today;
}
};
@ -227,7 +222,7 @@ setInterval(exports.update_timestamps, 60 * 1000);
// Transform a Unix timestamp into a ISO 8601 formatted date string.
// Example: 1978-10-31T13:37:42Z
exports.get_full_time = function (timestamp) {
return new XDate(timestamp * 1000).toISOString();
return formatISO(timestamp * 1000);
};
exports.get_timestamp_for_flatpickr = (timestring) => {
@ -247,9 +242,9 @@ exports.get_timestamp_for_flatpickr = (timestring) => {
exports.stringify_time = function (time) {
if (page_params.twenty_four_hour_time) {
return time.toString("HH:mm");
return format(time, "HH:mm");
}
return time.toString("h:mm TT");
return format(time, "h:mm a");
};
// this is for rendering absolute time based off the preferences for twenty-four
@ -318,7 +313,7 @@ exports.get_full_datetime = function (time) {
};
};
// XDate.toLocaleDateString and XDate.toLocaleTimeString are
// Date.toLocaleDateString and Date.toLocaleTimeString are
// expensive, so we delay running the following code until we need
// the full date and time strings.
exports.set_full_datetime = function timerender_set_full_datetime(message, time_elem) {
@ -326,7 +321,7 @@ exports.set_full_datetime = function timerender_set_full_datetime(message, time_
return;
}
const time = new XDate(message.timestamp * 1000);
const time = new Date(message.timestamp * 1000);
const full_datetime = exports.get_full_datetime(time);
message.full_date_str = full_datetime.date;

View File

@ -1,7 +1,5 @@
"use strict";
const XDate = require("xdate");
let last_mention_count = 0;
function do_new_messages_animation(li) {
@ -67,7 +65,7 @@ exports.should_display_bankruptcy_banner = function () {
return false;
}
const now = new XDate(true).getTime() / 1000;
const now = Date.now() / 1000;
if (
page_params.unread_msgs.count > 500 &&
now - page_params.furthest_read_time > 60 * 60 * 24 * 2

View File

@ -43,4 +43,4 @@ API_FEATURE_LEVEL = 38
# historical commits sharing the same major version, in which case a
# minor version bump suffices.
PROVISION_VERSION = '125.0'
PROVISION_VERSION = '126.0'

View File

@ -13367,11 +13367,6 @@ ws@^7.2.3:
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.2.tgz#782100048e54eb36fe9843363ab1c68672b261dd"
integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==
xdate@^0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/xdate/-/xdate-0.8.2.tgz#d7b033c00485d02695baf0044f4eacda3fc961a3"
integrity sha1-17AzwASF0CaVuvAET06s2j/JYaM=
xml-name-validator@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"