这是indexloc提供的服务,不要输入任何密码
Skip to content

feat: add default time for time element #5212

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

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

JayaKrishnaNamburu
Copy link
Contributor

@JayaKrishnaNamburu JayaKrishnaNamburu commented May 16, 2025

fixes #3510

Description

Adding a new default new Date.now() support to the time component. So, users can just drop and use the component whenever they want to show the current time. Rendering the default time using seconds as 0 on the server side. And then replacing the value on the client side. Things that need to be taken care of

  • Time component should support any static values that is passed to it.
  • If no value is passed, it should use the new Date() and respect all the configs on the component.
  • If no value is passed, it should render the date, month and year.

Steps for reproduction

  • Add a time element to the canvas and pass a static value.
  • Add a time element to the canvas without any defaults.

Currently there is a small flicker for seconds when the project is hydrated since we render with 0 seconds on the server side and replace with proper seconds on the client side. The flicker is expected IMO, as we are resetting and using it for render for space concerns.
default-time-with-hydration-seconds

This is the project on staging
https://p-5212e8bc-eb36-4bee-9218-77885cf13e01-dot-default-time.staging.webstudio.is/?authToken=3fd8ae81-9c0a-4874-a5eb-59854dbfea86&mode=preview
Deployed URL
https://jk-time-element-ck8hm.wstd.work/

Code Review

  • hi @kof, I need you to do
    • conceptual review (architecture, feature-correctness)
    • detailed review (read every line)
    • test it on preview

Before requesting a review

  • made a self-review
  • added inline comments where things may be not obvious (the "why", not "what")

Before merging

  • tested locally and on preview environment (preview dev login: 0000)
  • updated test cases document
  • added tests
  • if any new env variables are added, added them to .env file

@JayaKrishnaNamburu
Copy link
Contributor Author

JayaKrishnaNamburu commented May 16, 2025

Any ideas on how to handle or if we want to handle when server and client are in different time-zones. Here is the current behaviour. If when they both are in different time-zones. Should we take into consideration of the clients time-zone in server during SSR process ?

Because, on canvas we use clients timezone. On server it is server based. Again on client side from deployed site. It shows the client side timezone with a flicker.
server-client-timezone

The hydration issue with server and client time-zone is quite evident on deployed URL.
https://jk-time-element-ck8hm.wstd.work/

@kof
Copy link
Member

kof commented May 16, 2025

another option as opposed to suppressing and potentially rendering a different date could be reading the date from the dom and using it to construct the new Date object

@JayaKrishnaNamburu
Copy link
Contributor Author

another option as opposed to suppressing and potentially rendering a different date could be reading the date from the dom and using it to construct the new Date object

Yes doing the same once the component is fully hydrated. But still there will be a flicker from the server side as we render on server with 0 seconds or any seconds for that matter as they change.

I think the big bug would be with the flicker with timezones between server and client.

@kof
Copy link
Member

kof commented May 16, 2025

Can't you set the seconds/ms/tz to a single value when its the default value so that its always matching and then read it?

@JayaKrishnaNamburu
Copy link
Contributor Author

If there is no default by user. Component is using Date.now() inside server. So, basically it picks the server timezone.

https://github.com/webstudio-is/webstudio/pull/5212/files

Looks like there are ways to avoid such behaviours

remix-run/remix#9039 (comment)

Will try few things out and update the PR tonight 👍🏽

@JayaKrishnaNamburu
Copy link
Contributor Author

Just dropping it for reference, even in the case of static value, the date is rendered using the server time. Even if we input the timezone.

Screenshot 2025-05-16 at 9 22 04 PM Screenshot 2025-05-16 at 9 22 12 PM

@kof
Copy link
Member

kof commented May 16, 2025

I am not sure what you mean, but can you avoid creating a new date on the client entirely and use the server-rendered date fully? e.g. supply the original date in an attribute because text is formatted so it may not have parts of the date

@JayaKrishnaNamburu
Copy link
Contributor Author

I am not sure what you mean, but can you avoid creating a new date on the client entirely and use the server-rendered date fully

We can, but the catch is while server rendering it. It needs to be aware of where the client is located in. As the SSR uses the server time. So, if both client and server are in entirely different timezones. You will only see server time and miss the client timezone if not rendered again on client side. One easy way to do this is marking the component as client component. But we will loose ssr benefit for it.

@JayaKrishnaNamburu JayaKrishnaNamburu changed the title feat: add default time for time component feat: add default time for time element May 19, 2025
@kof
Copy link
Member

kof commented May 19, 2025

We can, but the catch is while server rendering it. It needs to be aware of where the client is located in. As the SSR uses the server time.

Let it user server time, use the same time on the client

@kof
Copy link
Member

kof commented May 19, 2025

But we will loose ssr benefit for it.

Making it pure client-side rendered date could be an option too, I don't know if SSR is actually important here, but if its used in the hero section, it will jump around

@JayaKrishnaNamburu
Copy link
Contributor Author

Updated the component now with the default time behaviour. This will no reflect the current time
Here is a project
https://p-5212e8bc-eb36-4bee-9218-77885cf13e01-dot-default-time.staging.webstudio.is/
Deployed version
https://jk-time-element-ck8hm.wstd.work/

This the current behaviour from the main branch
https://date-time-g5ijg.wstd.io

The only side effect is, this will currently throws an error with Mismatch of hydration error. Which is happening on main too. So, left is as is. I tried to fix it, by adding supressHydrationWarning flag. But, this is preventing the first re-render for static values. Let me know, if the behaviour is looking ok.

The only other options is

  • Completely mark the component as client component (Can create layout shits after hydration).

cc @kof @TrySound @istarkov

@JayaKrishnaNamburu JayaKrishnaNamburu marked this pull request as ready for review May 20, 2025 13:43
@JayaKrishnaNamburu JayaKrishnaNamburu self-assigned this May 20, 2025
@kof
Copy link
Member

kof commented May 20, 2025

I still see the difference between server and client
image
image

@JayaKrishnaNamburu
Copy link
Contributor Author

I still see the difference between server and client

image image

Yeah, that's the problem right. We don't have any info of users location or timezone in server and so we are updating post hydration.

It's the current behaviour too. Unless we start fetching users location or locale somehow server is always going to render its own time. I am waiting for bogdans take on this. Because unless we take some input from user side. The miss match is unavoidable.

@kof
Copy link
Member

kof commented May 20, 2025

Why can't we use server-rendered date including everything, including timezone?

@JayaKrishnaNamburu
Copy link
Contributor Author

Why can't we use server-rendered date including everything, including timezone?

We are not taking timezone from users right now. If they can provide it from the settings tab on the right. We can use that to render the users timezone. So, that flicker reduces more, and maybe sometimes at max to seconds. If at all it happens.
Screenshot 2025-05-20 at 9 27 10 PM

@kof
Copy link
Member

kof commented May 20, 2025

If there is a tz provided by user - it should be used, otherwise a timezone on the server should be used for both server and client-side, I still don't see the problem

@JayaKrishnaNamburu
Copy link
Contributor Author

JayaKrishnaNamburu commented May 22, 2025

@kof i thought of that too. But, it still doesn't cover all the cases. For example, If users don't provide any time related data in the string like +5:30 or Indian Standard Time etc. We can't detect that in server as well. Right now, the canvas takes the browser time. And displays it. And when deployed, it takes the server time, and hydrates with client time again (throwing hydration error).

Screenshot 2025-05-22 at 8 20 25 PM Screenshot 2025-05-22 at 8 24 40 PM Screenshot 2025-05-22 at 8 28 42 PM

So, if we are ok with hydration errors in console. It's pretty much straight forward. It's only a issue when we want to avoiding those hydration error messages 😅

That's why i am not leaned towards taking timeZone from the prop string and using it. It doesn't solve all cases. My suggestion is. We can add a additational dropdown. Which shows list of all timezones. By default it selects the users browser timezone. And we can take that prop and render in server and client. And even if they want to explicitly change it, they can still do it.

@kof
Copy link
Member

kof commented May 22, 2025

If something isn't provided, use the default server-side, then read it from html on the client

@JayaKrishnaNamburu
Copy link
Contributor Author

If something isn't provided, use the default server-side, then read it from html on the client

Yes yes, i am ok with that. But it will produce hydration error on console logs. As the date changes. Is that fine, that's what i wanted to know

@kof
Copy link
Member

kof commented May 22, 2025

Yes yes, i am ok with that. But it will produce hydration error on console logs. As the date changes. Is that fine, that's what i wanted to know

Why is it going to cause a hydration error if you are reading the date string from the dom and your client doesn't try to render anything different?

@JayaKrishnaNamburu
Copy link
Contributor Author

Like if users pick full time, there is a change is seconds. And currently without any third party lib or regex approach we can't pick tz from a string. Because the inbuilt getTimezoneOffset always returns w.r.t to env and not the string. So need to come up with some custom solution. Will give a shot and update PR. Got only some time, so taking long on PR. Apologies for that.

@kof
Copy link
Member

kof commented May 22, 2025

Parsing a time string including timezone can't be a big deal. Please don't write a regex for that. Find a tested solution.

@JayaKrishnaNamburu
Copy link
Contributor Author

JayaKrishnaNamburu commented May 31, 2025

Parsing a time string including timezone can't be a big deal. Please don't write a regex for that. Find a tested solution.

@kof i tried a couple of npm libraries, looks like almost all of them parses the timezone from string based on the execution environment. Means, they always extracting timezone w.r.t to UTC of the env and not just the timezone that is in the string. So, when we re-construct the time string back. It doesn't reflect the browser time again. Should we just mark this as client component / stick with the error message after the hydration ?

We can use moment-timezone and try to extract it. But it's almost 110KB
https://bundlephobia.com/package/moment-timezone@0.6.0
Not sure, if its worth for the use-case. Maybe we can try using it only on the server side. If it's even possible 🤔

Example
https://codesandbox.io/p/sandbox/wfz5n2

@kof
Copy link
Member

kof commented May 31, 2025

Weird!

In that case either just client-only rendering and accepting the potential visible rerender on hydration or reducing this thing to just a year and month so that timezone doesn't matter

@kof
Copy link
Member

kof commented May 31, 2025

I quickly asked gpt, it suggested https://github.com/taylorhakes/fecha/blob/master/src/fecha.ts

@kof
Copy link
Member

kof commented May 31, 2025

Another one it suggested is https://github.com/iamkun/dayjs

@JayaKrishnaNamburu
Copy link
Contributor Author

JayaKrishnaNamburu commented May 31, 2025

First one is regex heavy and days standalone doesn’t help much. It can to some extent with days extended something like that. That’s like multiple packages we are pulling again. Will try multiple options tomorrow. There is one more luxon. But didn’t work as expected.

@kof
Copy link
Member

kof commented May 31, 2025

Regex or not if its well tested I guess it can work? (by no RegExp I meant no custom made regex which will certainly have bugs, but something heavily tested is ok on my watch)

@JayaKrishnaNamburu
Copy link
Contributor Author

Regex or not if its well tested I guess it can work? (by no RegExp I meant no custom made regex which will certainly have bugs, but something heavily tested is ok on my watch)

Yup, will check package sizes etc tomorrow

@JayaKrishnaNamburu
Copy link
Contributor Author

@kof i gave multiple shots at this. Even with different approaches. Almost most of them get effected with the browser or the server env. The fast easy way could be to have a fixed height to reduce the jump if we mark this as client component.

@kof
Copy link
Member

kof commented Jul 5, 2025

@JayaKrishnaNamburu that's not going to work, if this issue is too hard, pls don't waste your time.

@JayaKrishnaNamburu
Copy link
Contributor Author

JayaKrishnaNamburu commented Jul 5, 2025

Ok, feel free to close this one. I will start looking into other issues that are on me 👍🏽

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use current date by default in time component
2 participants