Open kendrick opened 3 years ago
@kidroca, I may do some concepting of this in a local branch in the next week or two. Is monitoring this in a Context
that wraps the app is the right way to approach it? In a vanilla/web-components app, I was thinking of writing to localStorage
instead… but there may be a better way. Would love your thoughts on those approaches.
To be able to use this with a Context
- the user of the design system would have to wrap their app with the context.
This makes the library harder to use. Right now you can just use the components, even without wrapping the app with e Theme - we fallback to the default
If this would be put in Context
it should also be optional as users might not wrap with it at all
Can this information be derived on the fly though? Maybe we can capture the logic that computes this in a separate file and use it wherever we need to Example - the Image component
Using localStorage
would be OK to keep an initial value, but it won't work to notify components on change - storage change events are transmitted only to other tabs, so you can't use that to notify a change in a key to the current tab.
This means you'll need to setup something global that would serve as a pub/sub for these events
If that's the case I'll just skip the whole localStorage
part and just have a file with the following interface
let listeners: Set<(e: Event) => void> = new Set();
/* The latest connection state, this might be a custom format we use internally */
let state: NetworkInformation = navigator.connection
export const getState = (): NetworkInformation => state
export const addListener = (cb: (e: Event) => void) => {
listeners.add(cb)
return () => listeners.delete(cb);
}
export const waitToBeOnline = (): Promise<unknown> => {
let unsubscribe: () => void;
const promise = new Promise((resolve: Function) => {
unsubscribe = addListener((event) => {
// Some condition that satisfies the connection requirements
if (event.data.downlink > 1) {
resolve();
}
});
});
promise.finally(() => unsubscribe());
return promise;
}
// Have one global listener and delegate to the rest
state.addEventListener('change', (e) => {
state = e.data;
listeners.forEach(callback => callback(e));
})
This would allow us to import the file wherever needed and hook to network state It should work for React and web-components projects
waitToBeOnline
can use window.addEventListener('online', ...)
If this would be put in
Context
it should also be optional as users might not wrap with it at all
Absolutely—there may be lots of apps that assume an always-connected environment (for use at Compassion’s headquarters, for instance) that wouldn’t need to be bothered with an additional context.
Can this information be derived on the fly though?
A hook-driven approach might be perfect, especially if its internals could be used outside of React apps. I’ll start there. 😄
Behavior
Components and apps built with the design system should respect neighbors’ data usage preferences and should fail gracefully if bandwidth is low or nonexistent.
Connectivity metadata should be exposed globally via a design system object so that its presence can be depended on from within any component or in any area of an app built with the design system.
For instance, if a neighbor has indicated a preference to reduce data usage via
NetworkInformation.saveData
, experiences built with the design system should take that into account.Similarly, if a slow connection is detected via
NetworkInformation
properties likertt
oreffectiveType
, experiences built with the design system should offer the neighbor an opportunity to accomplish a task now (selecting videos to upload, for instance) while deferring the data-heavy portion (like performing the upload) until the neighbor indicates they’re ready.Resources
react-adaptive-hooks
take many of these considerations into accountContext
s for sharing data globally