diff --git a/app/assets/javascripts/discourse/app/components/user-card-contents.js b/app/assets/javascripts/discourse/app/components/user-card-contents.js index 629545601ae..7b92e86011d 100644 --- a/app/assets/javascripts/discourse/app/components/user-card-contents.js +++ b/app/assets/javascripts/discourse/app/components/user-card-contents.js @@ -72,7 +72,10 @@ export default Component.extend(CardContentsBase, CanCheckEmails, CleansUp, { @discourseComputed("user") userTimezone(user) { - return user.resolvedTimezone(); + if (!this.showUserLocalTime) { + return; + } + return user.resolvedTimezone(this.currentUser); }, @discourseComputed("userTimezone") diff --git a/app/assets/javascripts/discourse/app/controllers/bookmark.js b/app/assets/javascripts/discourse/app/controllers/bookmark.js index 7d86ed2b74a..4e9e6c3c780 100644 --- a/app/assets/javascripts/discourse/app/controllers/bookmark.js +++ b/app/assets/javascripts/discourse/app/controllers/bookmark.js @@ -73,7 +73,7 @@ export default Controller.extend(ModalFunctionality, { customReminderTime: this._defaultCustomReminderTime(), lastCustomReminderDate: null, lastCustomReminderTime: null, - userTimezone: this.currentUser.resolvedTimezone(), + userTimezone: this.currentUser.resolvedTimezone(this.currentUser), showOptions: false, options: {}, model: this.model || {} diff --git a/app/assets/javascripts/discourse/app/initializers/topic-footer-buttons.js b/app/assets/javascripts/discourse/app/initializers/topic-footer-buttons.js index 7751be37a11..54d08532042 100644 --- a/app/assets/javascripts/discourse/app/initializers/topic-footer-buttons.js +++ b/app/assets/javascripts/discourse/app/initializers/topic-footer-buttons.js @@ -109,7 +109,7 @@ export default { return I18n.t("bookmarked.help.unbookmark_with_reminder", { reminder_at: formattedReminderTime( bookmark_reminder_at, - currentUser.resolvedTimezone() + currentUser.resolvedTimezone(currentUser) ) }); } diff --git a/app/assets/javascripts/discourse/app/models/bookmark.js b/app/assets/javascripts/discourse/app/models/bookmark.js index 44daca7cdd4..fd882645835 100644 --- a/app/assets/javascripts/discourse/app/models/bookmark.js +++ b/app/assets/javascripts/discourse/app/models/bookmark.js @@ -113,7 +113,7 @@ const Bookmark = RestModel.extend({ formattedReminder(bookmarkReminderAt, currentUser) { return formattedReminderTime( bookmarkReminderAt, - currentUser.resolvedTimezone() + currentUser.resolvedTimezone(currentUser) ).capitalize(); }, diff --git a/app/assets/javascripts/discourse/app/models/user.js b/app/assets/javascripts/discourse/app/models/user.js index 6f4cf5dfcfe..fc98218426e 100644 --- a/app/assets/javascripts/discourse/app/models/user.js +++ b/app/assets/javascripts/discourse/app/models/user.js @@ -849,17 +849,21 @@ const User = RestModel.extend({ ); }, - resolvedTimezone() { - if (this._timezone) { + resolvedTimezone(currentUser) { + if (this.hasSavedTimezone()) { return this._timezone; } - this.changeTimezone(moment.tz.guess()); - ajax(userPath(this.username + ".json"), { - type: "PUT", - dataType: "json", - data: { timezone: this._timezone } - }); + // only change the timezone and save it if we are + // looking at our own user + if (currentUser.id === this.id) { + this.changeTimezone(moment.tz.guess()); + ajax(userPath(this.username + ".json"), { + type: "PUT", + dataType: "json", + data: { timezone: this._timezone } + }); + } return this._timezone; }, @@ -868,6 +872,13 @@ const User = RestModel.extend({ this._timezone = tz; }, + hasSavedTimezone() { + if (this._timezone) { + return true; + } + return false; + }, + calculateMutedIds(notificationLevel, id, type) { const muted_ids = this.get(type); if (notificationLevel === NotificationLevels.MUTED) { diff --git a/app/assets/javascripts/discourse/app/widgets/post-menu.js b/app/assets/javascripts/discourse/app/widgets/post-menu.js index 376772c237c..00c859717c0 100644 --- a/app/assets/javascripts/discourse/app/widgets/post-menu.js +++ b/app/assets/javascripts/discourse/app/widgets/post-menu.js @@ -302,7 +302,7 @@ registerButton("bookmark", attrs => { if (attrs.bookmarkReminderAt) { let formattedReminder = formattedReminderTime( attrs.bookmarkReminderAt, - Discourse.currentUser.resolvedTimezone() + Discourse.currentUser.resolvedTimezone(Discourse.currentUser) ); title = "bookmarks.created_with_reminder"; titleOptions.date = formattedReminder; diff --git a/test/javascripts/acceptance/bookmarks-test.js b/test/javascripts/acceptance/bookmarks-test.js index 762cd1ee071..83781f7ffb1 100644 --- a/test/javascripts/acceptance/bookmarks-test.js +++ b/test/javascripts/acceptance/bookmarks-test.js @@ -205,7 +205,7 @@ test("Editing a bookmark", async assert => { mockSuccessfulBookmarkPost(assert); await visit("/t/internationalization-localization/280"); - let now = moment.tz(loggedInUser().resolvedTimezone()); + let now = moment.tz(loggedInUser().resolvedTimezone(loggedInUser())); let tomorrow = now.add(1, "day").format("YYYY-MM-DD"); await openBookmarkModal(); await fillIn("input#bookmark-name", "Test name"); @@ -234,7 +234,7 @@ test("Editing a bookmark that has a Later Today reminder, and it is before 6pm t mockSuccessfulBookmarkPost(assert); let clock = fakeTime( "2020-05-04T13:00:00", - loggedInUser().resolvedTimezone() + loggedInUser().resolvedTimezone(loggedInUser()) ); await timeStep(clock, () => visit("/t/internationalization-localization/280") diff --git a/test/javascripts/acceptance/user-card-test.js b/test/javascripts/acceptance/user-card-test.js index f15bbd3a7ab..8ba3c95caca 100644 --- a/test/javascripts/acceptance/user-card-test.js +++ b/test/javascripts/acceptance/user-card-test.js @@ -64,6 +64,29 @@ QUnit.test("user card local time", async assert => { ); }); +QUnit.test( + "user card local time - does not update timezone for another user", + async assert => { + User.current().changeTimezone("Australia/Brisbane"); + let cardResponse = _.clone(userFixtures["/u/charlie/card.json"]); + delete cardResponse.user.timezone; + + pretender.get("/u/charlie/card.json", () => [ + 200, + { "Content-Type": "application/json" }, + cardResponse + ]); + + await visit("/t/internationalization-localization/280"); + await click("a[data-user-card=charlie]:first"); + + assert.not( + exists(".user-card .local-time"), + "it does not show the local time if the user card returns a null/undefined timezone for another user" + ); + } +); + acceptance("User Card", { loggedIn: true }); QUnit.test("user card", async assert => { diff --git a/test/javascripts/controllers/bookmark-test.js b/test/javascripts/controllers/bookmark-test.js index 246d10dd4d2..0474215f4ab 100644 --- a/test/javascripts/controllers/bookmark-test.js +++ b/test/javascripts/controllers/bookmark-test.js @@ -114,7 +114,9 @@ QUnit.test( function(assert) { let dt = moment.tz( "2019-12-11T11:37:16", - BookmarkController.currentUser.resolvedTimezone() + BookmarkController.currentUser.resolvedTimezone( + BookmarkController.currentUser + ) ); assert.equal( @@ -208,7 +210,9 @@ QUnit.test( moment .tz( "2028-12-12 08:00", - BookmarkController.currentUser.resolvedTimezone() + BookmarkController.currentUser.resolvedTimezone( + BookmarkController.currentUser + ) ) .toString(), "the custom date and time are parsed correctly with default time" diff --git a/test/javascripts/models/user-test.js b/test/javascripts/models/user-test.js index 90dcef574ec..97632b148f1 100644 --- a/test/javascripts/models/user-test.js +++ b/test/javascripts/models/user-test.js @@ -71,7 +71,7 @@ QUnit.test("canMangeGroup", assert => { QUnit.test("resolvedTimezone", assert => { const tz = "Australia/Brisbane"; - let user = User.create({ timezone: tz, username: "chuck" }); + let user = User.create({ timezone: tz, username: "chuck", id: 111 }); let stub = sandbox.stub(moment.tz, "guess").returns("America/Chicago"); pretender.put("/u/chuck.json", () => { @@ -80,7 +80,7 @@ QUnit.test("resolvedTimezone", assert => { let spy = sandbox.spy(ajaxlib, "ajax"); assert.equal( - user.resolvedTimezone(), + user.resolvedTimezone(user), tz, "if the user already has a timezone return it" ); @@ -88,9 +88,9 @@ QUnit.test("resolvedTimezone", assert => { spy.notCalled, "if the user already has a timezone do not call AJAX update" ); - user = User.create({ username: "chuck" }); + user = User.create({ username: "chuck", id: 111 }); assert.equal( - user.resolvedTimezone(), + user.resolvedTimezone(user), "America/Chicago", "if the user has no timezone guess it with moment" ); @@ -102,6 +102,22 @@ QUnit.test("resolvedTimezone", assert => { }), "if the user has no timezone save it with an AJAX update" ); + + let otherUser = User.create({ username: "howardhamlin", id: 999 }); + assert.equal( + otherUser.resolvedTimezone(user), + null, + "if the user has no timezone and the user is not the current user, do NOT guess with moment" + ); + assert.not( + spy.calledWith("/u/howardhamlin.json", { + type: "PUT", + dataType: "json", + data: { timezone: "America/Chicago" } + }), + "if the user has no timezone, and the user is not the current user, do NOT save it with an AJAX update" + ); + stub.restore(); });