-
-
Notifications
You must be signed in to change notification settings - Fork 29
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
feat: NetworkStatus
#117
base: main
Are you sure you want to change the base?
feat: NetworkStatus
#117
Conversation
|
built with Refined Cloudflare Pages Action⚡ Cloudflare Pages Deployment
|
chore: add .idea to gitignore chore: clean up chore: clean up
e94cd51
to
e529bf5
Compare
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.
Nice one!
Left some small nitpicks.
More broadly, I don't want to speak for the maintainers, but looking at the current naming/API patterns of the codebase my assumption is the use
prefix is being reserved for functions that accept a callback to observe changes.
I'd probably either rework so it can be used like:
useNetworkStatus((data) => {
// do something with new data
});
or keep it essentially the same as the current implementation, but change it to a NetworkStatus
class (classes also seem to be the pattern for encapsulating reactive state in this repo).
const networkStatus = new NetworkStatus();
Second makes most sense to me, but you could potentially even have both if you really wanted. Hopefully maintainers can give guidance.
packages/runed/src/lib/utilities/useNetworkStatus/useNetworkStatus.svelte.ts
Outdated
Show resolved
Hide resolved
packages/runed/src/lib/utilities/useNetworkStatus/useNetworkStatus.svelte.ts
Outdated
Show resolved
Hide resolved
packages/runed/src/lib/utilities/useNetworkStatus/useNetworkStatus.svelte.ts
Outdated
Show resolved
Hide resolved
refactor: refactor the way event listeners are removed on unmount
f72ffda
to
c9f45b2
Compare
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.
Thanks for taking the time to contribute this! Left some notes!
packages/runed/src/lib/utilities/useNetworkStatus/useNetworkStatus.svelte.ts
Outdated
Show resolved
Hide resolved
packages/runed/src/lib/utilities/useNetworkStatus/useNetworkStatus.svelte.ts
Outdated
Show resolved
Hide resolved
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.
Looking great! Just passing observations until maintainers can provide a proper review :)
packages/runed/src/lib/utilities/NetworkStatus/NetworkStatus.svelte.ts
Outdated
Show resolved
Hide resolved
Part of me wonders if we should just include a What do you all think? Great job with the implementation @michal-weglarz! |
Why the previous property? Do you think it'd be common enough that its warranted over just using the Previous utility? |
After thinking about it more, you're right. I think it might just create bloat that isn't always necessary, so it's best to leverage other utilities if necessary, as in the example. Disregard that one! |
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.
Awesome stuff! Some minor changes needed
packages/runed/src/lib/utilities/NetworkStatus/NetworkStatus.svelte.ts
Outdated
Show resolved
Hide resolved
); | ||
#online: boolean = $state(false); | ||
#updatedAt: Date = $state(new Date()); | ||
#downlink?: NetworkInformation["downlink"] = $state(); |
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.
Can't these be deriveds that depend on connection?
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.
Actually, can't we just use gets that use connection? Why do we need these individual fields?
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.
Can we get the updated state without these? If connection
or its properties, or online
/offline
status changes (e.g., random internet disconnection), how will the client be notified?
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.
connection can be a state, since all of the other ones are just set from it. then updateStatus
updates connection, and that's it
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 pushed the commit where I simplified the state by depending solely on the derived connection. Seems like it's working exactly the same as before so definitely a great suggestion :)
packages/runed/src/lib/utilities/NetworkStatus/NetworkStatus.svelte.ts
Outdated
Show resolved
Hide resolved
|
||
```ts | ||
const networkStatus = new NetworkStatus(); | ||
const previousNetworkStatus = new Previous(() => ({ |
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.
tbh its a bit of a shame we can't spread here 🤔
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.
@TGlide this is literally what made me consider doing the previous
for the user for this one so they wouldn't have to do line by line. The only way I see being able to spread is exposing a $derived
property on the class that is basically an object with all those props networkStatus.obj
or networkStatus.all
but idk how it feels or if it's worth the extra bloat tbh
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.
Hmm tbh its probably fine. Most of these properties are just being proxied within the connection property, so you could just use that
|
||
<DemoContainer> | ||
{#if networkStatus.isSupported} | ||
<pre>{JSON.stringify(networkStatusCombined, null, 2)}</pre> |
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.
@huntabyte is it too hard to get syntax highlighting here?
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.
@TGlide, uhh, we could hack it a bit, but without hacks, we'd need to ship Shiki to the browser.
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 then!
I've noticed an issue with updating the We could use something like this to check again if the value is up to date: #updateStatus = () => {
if (!this.#navigator) return;
this.#online = this.#navigator.onLine;
this.#updatedAt = new Date();
setTimeout(() => {
if (!this.#navigator) return;
const newOnlineStatus = this.#navigator.onLine;
if (this.#online !== newOnlineStatus) {
this.#online = newOnlineStatus;
this.#updatedAt = new Date();
}
}, 100);
}; From my manual testing, this approach indeed mitigates the problem described above. However, it seems a little brittle. Would you be fine with adding it to the code, or do you see any other potential fix? EDIT. constructor() {
onMount(() => {
this.#updateStatus();
useEventListener(window, "online", this.#updateStatus, { passive: true });
useEventListener(window, "offline", this.#updateStatus, { passive: true });
if (this.#connection) {
useEventListener(this.#connection, "change", this.#updateStatus, { passive: true });
}
});
} This would probably be a better solution, but the handling of React-hookz/web solves this by only storing the timestamp of the moment when the status changes to online/offline. This approach doesn't include timestamps of any other updates. |
Hi all 👋
I thought it might be useful to have this
useNetworkStatus
utility to get the current status of the network connection at any time. It could be used to inform users that they have a bad connection, or that they have temporarily lost access to the internet altogether. I also added theupdatedAt
property, which can be used, for example, to show how much time users were offline before coming back online (please, see the attached demo).It's heavily inspired by useNetworkState from React-Hookz/web.
This hasn't been discussed in a separate feature request yet, so feel free to reject this PR if you think this utility doesn't belong in the library.
Demo in Chrome:
use-network-status-chrome-demo.mov
Demo in Safari/Firefox:
use-network-stastus-firefox-safari-demo.mov
The returned status always includes
online
andupdatedAt
.Other properties are returned based on the NetworkInformation interface and depend on your browser's compatibility.