|
41 | 41 | const bucketDownlink = d => |
42 | 42 | Number.isFinite(d) ? Math.ceil(d) : null; |
43 | 43 |
|
| 44 | + // Combine network capability (RTT + bandwidth) and user/device preferences |
| 45 | + // (Save-Data, low battery) into a delivery stance. |
| 46 | + // |
| 47 | + // Exposes: |
| 48 | + // - obs.connectionCapability: 'strong'|'moderate'|'weak' |
| 49 | + // - obs.conservationPreference: 'conserve'|'neutral' |
| 50 | + // - obs.deliveryMode: 'rich'|'cautious'|'lite' |
| 51 | + // - obs.canShowRichMedia: boolean |
| 52 | + // - obs.shouldAvoidRichMedia: boolean |
| 53 | + const recomputeDelivery = () => { |
| 54 | + const o = window.obs || {}; |
| 55 | + |
| 56 | + // Capability from network only (RTT + bandwidth) |
| 57 | + const bw = typeof o.downlinkBucket === 'number' ? o.downlinkBucket : null; |
| 58 | + const lowRTT = o.rttCategory === 'low'; |
| 59 | + const highRTT = o.rttCategory === 'high'; |
| 60 | + const highBW = bw != null && bw >= 8; // 1Mbps buckets |
| 61 | + const lowBW = bw != null && bw <= 5; |
| 62 | + |
| 63 | + o.connectionCapability = (lowRTT && highBW) |
| 64 | + ? 'strong' |
| 65 | + : (highRTT || lowBW) |
| 66 | + ? 'weak' |
| 67 | + : 'moderate'; |
| 68 | + |
| 69 | + // Preference/context (user choice + device state) |
| 70 | + const conserve = (o.dataSaver === true) || (o.batteryLow === true); |
| 71 | + o.conservationPreference = conserve ? 'conserve' : 'neutral'; |
| 72 | + |
| 73 | + // Combined delivery stance we key behaviour from |
| 74 | + const rich = !conserve && o.connectionCapability === 'strong'; |
| 75 | + const avoid = conserve || o.connectionCapability === 'weak'; |
| 76 | + o.deliveryMode = rich ? 'rich' : (avoid ? 'lite' : 'cautious'); |
| 77 | + |
| 78 | + // Convenience booleans |
| 79 | + o.canShowRichMedia = (o.deliveryMode === 'rich'); |
| 80 | + o.shouldAvoidRichMedia = (o.deliveryMode === 'lite'); |
| 81 | + |
| 82 | + // Add classes to the `html` element for each of our delivery stances. |
| 83 | + ['strong','moderate','weak'].forEach(t => { |
| 84 | + html.classList.remove(`has-connection-capability-${t}`); |
| 85 | + }); |
| 86 | + html.classList.add(`has-connection-capability-${o.connectionCapability}`); |
| 87 | + |
| 88 | + // Preference classes (new) + remove legacy |
| 89 | + ['conserve','neutral'].forEach(t => { |
| 90 | + html.classList.remove(`has-conservation-preference-${t}`); |
| 91 | + }); |
| 92 | + html.classList.add(`has-conservation-preference-${o.conservationPreference}`); |
| 93 | + |
| 94 | + // Delivery classes (new) + remove legacy |
| 95 | + ['rich','cautious','lite'].forEach(t => { |
| 96 | + html.classList.remove(`has-delivery-mode-${t}`); |
| 97 | + }); |
| 98 | + html.classList.add(`has-delivery-mode-${o.deliveryMode}`); |
| 99 | + }; |
| 100 | + |
44 | 101 | // Run this function on demand to grab fresh data from the Network Information |
45 | 102 | // API. |
46 | 103 | const refreshConnectionStatus = () => { |
|
78 | 135 | const isHigh = downlinkBucket >= 8; |
79 | 136 | html.classList.toggle('has-bandwidth-low', isLow); |
80 | 137 | html.classList.toggle('has-bandwidth-high', isHigh); |
81 | | - |
82 | | - // Somewhat opinionated decision to mark low latency and high downlink |
83 | | - // connections as strong, and high latency and low downlink connections as |
84 | | - // weak. |
85 | | - const latencyIsLow = window.obs.rttCategory === 'low'; |
86 | | - const latencyIsHigh = window.obs.rttCategory === 'high'; |
87 | | - const bandwidthIsLow = isLow; |
88 | | - const bandwidthIsHigh = isHigh; |
89 | | - html.classList.toggle('has-connection-strong', latencyIsLow && bandwidthIsHigh); |
90 | | - html.classList.toggle('has-connection-weak', latencyIsHigh && bandwidthIsLow); |
91 | | - |
92 | 138 | } |
93 | 139 |
|
94 | 140 | // We don’t do anything with it, but get maximum estimated `downlink` while |
95 | 141 | // we’re here. |
96 | 142 | if ('downlinkMax' in connection) { |
97 | 143 | window.obs.downlinkMax = connection.downlinkMax; |
98 | 144 | } |
| 145 | + |
| 146 | + // Update delivery stance combining capability and preferences. |
| 147 | + recomputeDelivery(); |
99 | 148 | }; |
100 | 149 |
|
101 | 150 | // Run the connection function immediately. |
|
130 | 179 | const isCharging = !!charging; |
131 | 180 | window.obs.batteryCharging = isCharging; |
132 | 181 | html.classList.toggle('has-battery-charging', isCharging); |
| 182 | + |
| 183 | + // Update delivery stance combining capability and preferences. |
| 184 | + recomputeDelivery(); |
133 | 185 | }; |
134 | 186 |
|
135 | 187 | // Battery metrics (best‑effort and privacy‑respecting). |
|
0 commit comments