mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-15 17:12:59 -04:00
crocs
This commit is contained in:
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
@@ -12,7 +12,7 @@
|
|||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
<!-- site-metadata:inject -->
|
<!-- site-metadata:inject -->
|
||||||
<!-- analytics:inject -->
|
<!-- analytics:inject -->
|
||||||
<script type="module" crossorigin src="/assets/index-r7XMuw_k.js"></script>
|
<script type="module" crossorigin src="/assets/index-D8T7esRs.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-7PpZTwSc.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-7PpZTwSc.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -84,10 +84,29 @@ function listGrantedRoversForRequester(requesterKey) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function applySocketGrantCache(socket) {
|
function applySocketGrantCache(socket) {
|
||||||
if (!socket) return;
|
if (!socket) return false;
|
||||||
socket.data = socket.data || {};
|
socket.data = socket.data || {};
|
||||||
const requesterKey = buildRequesterKey(socket);
|
const requesterKey = buildRequesterKey(socket);
|
||||||
socket.data.privateClosedAccessRovers = listGrantedRoversForRequester(requesterKey);
|
const nextRoverIds = listGrantedRoversForRequester(requesterKey).sort();
|
||||||
|
const previousRoverIds = Array.isArray(socket.data.privateClosedAccessRovers)
|
||||||
|
? socket.data.privateClosedAccessRovers
|
||||||
|
: [];
|
||||||
|
const requesterChanged = socket.data.privateAccessRequesterKey !== requesterKey;
|
||||||
|
const grantsChanged = previousRoverIds.length !== nextRoverIds.length
|
||||||
|
|| previousRoverIds.some((roverId, index) => String(roverId) !== String(nextRoverIds[index]));
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remember both inputs that determine the socket's private-access projection.
|
||||||
|
The requester key matters even when both identities currently have no grants,
|
||||||
|
because pending requests in the session payload are also keyed by requester.
|
||||||
|
Returning whether either input changed lets transport hooks avoid announcing
|
||||||
|
a false state change for ordinary live identity-setting updates.
|
||||||
|
*/
|
||||||
|
socket.data.privateAccessRequesterKey = requesterKey;
|
||||||
|
if (grantsChanged) {
|
||||||
|
socket.data.privateClosedAccessRovers = nextRoverIds;
|
||||||
|
}
|
||||||
|
return requesterChanged || grantsChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshAllSocketGrantCaches() {
|
function refreshAllSocketGrantCaches() {
|
||||||
|
|||||||
@@ -71,8 +71,15 @@ function registerPrivateRoverAccessHooks(deps) {
|
|||||||
socket.on('privateRover:requestAccess', handleRequest);
|
socket.on('privateRover:requestAccess', handleRequest);
|
||||||
socket.on('session:privateRover:requestAccess', handleRequest);
|
socket.on('session:privateRover:requestAccess', handleRequest);
|
||||||
socket.on('session:identify', () => {
|
socket.on('session:identify', () => {
|
||||||
applySocketGrantCache(socket);
|
/*
|
||||||
requestEvents.emit('change', { reason: 'identify', socketId: socket.id });
|
session:identify also carries unrelated live preferences such as audio
|
||||||
|
adjustments. Only publish a private-access change when identification
|
||||||
|
actually moved this socket to a different requester or grant set; a
|
||||||
|
no-op event must not fan out a full session sync to every connection.
|
||||||
|
*/
|
||||||
|
if (applySocketGrantCache(socket)) {
|
||||||
|
requestEvents.emit('change', { reason: 'identify', socketId: socket.id });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,15 @@ export function useSettings() {
|
|||||||
|
|
||||||
export function useSettingsNamespace(namespace, defaults = {}) {
|
export function useSettingsNamespace(namespace, defaults = {}) {
|
||||||
const { data, status, setNamespace } = useSettings();
|
const { data, status, setNamespace } = useSettings();
|
||||||
const value = data[namespace] ?? defaults ?? {};
|
/*
|
||||||
|
Defaults describe the initial shape of a namespace; they are not live state.
|
||||||
|
Keep the first supplied value in lazy hook state because callers naturally pass object
|
||||||
|
literals. Returning each newly-created literal while the namespace is absent
|
||||||
|
would make an unchanged setting appear to change on every parent render and
|
||||||
|
could retrigger effects that synchronize settings to the server.
|
||||||
|
*/
|
||||||
|
const [initialDefaults] = useState(() => defaults ?? {});
|
||||||
|
const value = data[namespace] ?? initialDefaults;
|
||||||
|
|
||||||
const save = useCallback(
|
const save = useCallback(
|
||||||
(update) => {
|
(update) => {
|
||||||
@@ -89,9 +97,14 @@ export function useSettingsNamespace(namespace, defaults = {}) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const reset = useCallback(() => {
|
const reset = useCallback(() => {
|
||||||
const base = typeof defaults === 'object' ? { ...defaults } : defaults;
|
/*
|
||||||
|
Reset uses the same stable initial defaults exposed above. This keeps the
|
||||||
|
namespace contract consistent even if a caller recreates its defaults
|
||||||
|
object during later renders.
|
||||||
|
*/
|
||||||
|
const base = typeof initialDefaults === 'object' ? { ...initialDefaults } : initialDefaults;
|
||||||
setNamespace(namespace, () => base ?? {});
|
setNamespace(namespace, () => base ?? {});
|
||||||
}, [defaults, namespace, setNamespace]);
|
}, [initialDefaults, namespace, setNamespace]);
|
||||||
|
|
||||||
return { value, status, save, replace, reset };
|
return { value, status, save, replace, reset };
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user