-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add local time to hover cards based on user location #1249
Conversation
Oof, big PR :) Thanks! I have 2 concerns though:
|
|
It looks pretty good though; we probably can't get anything better than Google's APIs. Perhaps we can just cache the locations and avoid the current user's |
Yeah, I'll find a better solution than Would |
We can skip moment-timezone entirely by just reading the
The offset is in seconds and can be combined with Once we have the correct Side note: Those APIs give a crazy amount of info. Gotta love google for this stuff. I wish they included the simple timezone info in a single call though.
|
try { | ||
const location = getLocationFromHovercard( | ||
Array.from(hoverCardMutation.addedNodes) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The past 10 lines can probably be replaced with a select('.Popover .octicon-location')
+ .nextSibling.textContent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Brilliant.
return timezoneResponse; | ||
} catch (error) { | ||
return null; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to catch here, let it bubble up
|
||
function createTimezoneRequestURL(lat, lng) { | ||
const timezoneAPI = 'https://maps.googleapis.com/maps/api/timezone/json?location='; | ||
return `${timezoneAPI}${lat},${lng}×tamp=1331161200&sensor=false`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the timestamp should be Date.now() / 1000
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's just me, but this request seems to fail more often with Date.now() / 1000
🤔
/> | ||
</svg> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be moved to icons.js
.
As per #1099:
- The extra classes should be removed. They can probably be added to a parent or via
.classList.add()
version
andviewbox
also can be removed
const time = moment.tz(moment(), timeZoneId).format('HH:mm'); | ||
const abbr = moment.tz(timeZoneId).zoneAbbr(); | ||
hoverCard.append(clockIcon()); | ||
hoverCard.append(domify(`${time} ${abbr}`)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
append
accepts plain strings and multiple elements, so it can be:
hoverCard.append(clockIcon(), `${time} ${abbr}`);
} | ||
} catch (e) { | ||
// Silently fail when there are too many API requests | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need suppress the errors. If it's not working we should probably show why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will fail when either the timezoneAPI
or the locationAPI
request fails due to too many requests, but the requests often succeed on the next mouseover. How do you want to handle this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd let it go to the console for now. Perhaps it can use onetime
to show the error in the console once per load at least, so it doesn't fail completely silently and doesn't spam the console with errors.
But @sindresorhus perhaps can give better advice on expected error handling.
observer.observe(document.querySelector('div.Popover-message'), { | ||
attributes: true, | ||
childList: true | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can listen to it directly:
delegate('[data-hydro-view]', 'view', addTime)
The only annoyance is that view
is fired after 500ms, for whatever reason:
setTimeout(function() {
if (document.body && document.body.contains(e)) {
var t = a.query(e, "[data-hovercard-tracking]").getAttribute("data-hovercard-tracking");
if (t) {
var n = {
event_type: "user-hovercard-load"
};
n.dimensions = JSON.parse(t),
Yr(n)
}
var r = a.query(e, "[data-hydro-view]");
i.fire(r, "view")
}
}, 500)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only annoyance is that view is fired after 500ms, for whatever reason
I think this won't be an issue if we cache the requests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah I think we might need a way to make it faster?
So @bfred-it, you suggested that we only show the local time and remove the timezone abbreviation, correct? I'll start working on removing |
const location = select('.Popover .octicon-location').nextSibling.textContent.trim(); | ||
const timeZone = await getTimezone(location); | ||
|
||
if (timeZone) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an off by one issue here that I haven't figured out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean?
Probably because GitHub notices you're hovering the same item over and over and doesn't update the item... but it still fires the "view" event. You'll just have to do a |
|
||
const now = new Date(Date.now()); | ||
|
||
if (document.body.hasAttribute(username)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's probably a better way of doing this.
When you're a good point you can remove "WIP" from the title and I'll review again |
Requesting reviews because this adds two API calls to Google servers and new permissions. |
They dropped the `view` event
@@ -60,5 +63,5 @@ async function updateHovercard() { | |||
} | |||
|
|||
export default async function () { | |||
delegate('[data-hydro-view]', 'view', updateHovercard); | |||
observeEl('.Popover-message', updateHovercard); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bfred-it Curious, why did you make this switch back?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They dropped the view
event
The time should not be faded in if it's already cached. Then we should just show it right away. |
@sindresorhus should the timezone be relative to GMT (whatever we get from
How do you display that though? Usually it's written as "+1" but you're asking to also show the timezone, so that'd be confusing.
Thanks to these lines, there's no way to tell... other than manually tracking the time it took to |
Relative to UTC.
We would be explicit then:
Could just make it return a "tuple": return [isCached, locationOffsets.get(location)]; |
I was thinking of just showing the local time without a timezone indicator so let's say person A is in Italy and person B is in Greece (1 hour time difference). So if it is 16:00 in Italy and Person A hovers on Person B, they will see 17:00. We'll need a timezone indicator if we want to refer to an absolute timestamp like a rocket launch window. If we refer to a local time somewhere, it should be like when you ask Google what's the time somewhere and Google shows you the local time with no timezone modifier. |
@hkdobrev Google does show the timezone: |
All options are valid, we just have to decide what's useful in this context.
If we answer this question we might get closer to what we should show: Why would I want to know the time for a specific person? I would want to know:
To counter my own point, I made this a while ago. It uses absolute times: https://time.bfred.it/ |
Let's go with this. I thought I needed the UTC time zone, but I can't think of what I would use it for when I know how many hours away from me and the local time. Like you said, we can display the full info in the If it's a different day, maybe we can also include the name of the day here, to make it quicker to scan: |
Giving this a bump... |
Sorry, I've been pretty busy recently. I'll try and finish this PR soon. Anyone else is welcome to push to my branch too! |
@jorgegonzalez Do you think you will finish this at some point or should we close? :) |
@sindresorhus let me try and finish it this weekend. I've been swamped since I started working. |
Closes #1233.
Still need to add some padding as well as a clock icon like in the linked issue, any suggestions for that?
One of the issues with this solution is that nothing will render if too many API requests are made to get the user's location and timezone info, so I just made it silently fail. Any input is appreciated.