summaryrefslogtreecommitdiffhomepage
path: root/src/adapters
diff options
context:
space:
mode:
Diffstat (limited to 'src/adapters')
-rw-r--r--src/adapters/ws/index.ts9
-rw-r--r--src/adapters/ws/logic.ts19
2 files changed, 28 insertions, 0 deletions
diff --git a/src/adapters/ws/index.ts b/src/adapters/ws/index.ts
index 3713c8c..4dc0104 100644
--- a/src/adapters/ws/index.ts
+++ b/src/adapters/ws/index.ts
@@ -6,6 +6,7 @@ import type {
ConversationStatusChangedMessage,
ExtensionsChangedMessage,
LayoutChangedMessage,
+ TileLayoutChangedMessage,
WsClientMessage,
} from "@dispatch/transport-contract";
import type { SurfaceServerMessage } from "@dispatch/ui-contract";
@@ -40,6 +41,12 @@ export interface SurfaceSocketOptions {
* tree for one workspace. The consumer filters by its active workspace.
*/
onLayout?: (msg: LayoutChangedMessage) => void;
+ /**
+ * Broadcast after every successful home tile-layout write: the FULL
+ * document for one device orientation (wide/tall). The consumer filters by
+ * its active geometry mode.
+ */
+ onTileLayout?: (msg: TileLayoutChangedMessage) => void;
onReopen?: () => void;
socketFactory?: (url: string) => WebSocketLike;
}
@@ -92,6 +99,8 @@ export function createSurfaceSocket(opts: SurfaceSocketOptions): SurfaceSocketHa
opts.onExtensionsChanged?.(msg as ExtensionsChangedMessage);
} else if (msg.type === "layout") {
opts.onLayout?.(msg as LayoutChangedMessage);
+ } else if (msg.type === "tile-layout") {
+ opts.onTileLayout?.(msg as TileLayoutChangedMessage);
} else {
opts.onMessage(msg as SurfaceServerMessage);
}
diff --git a/src/adapters/ws/logic.ts b/src/adapters/ws/logic.ts
index 6cbc559..4dbd173 100644
--- a/src/adapters/ws/logic.ts
+++ b/src/adapters/ws/logic.ts
@@ -6,6 +6,7 @@ import type {
ConversationStatusChangedMessage,
ExtensionsChangedMessage,
LayoutChangedMessage,
+ TileLayoutChangedMessage,
WsClientMessage,
WsServerMessage,
} from "@dispatch/transport-contract";
@@ -28,6 +29,7 @@ const VALID_SERVER_TYPES = new Set([
"conversation.compacted",
"extensions-changed",
"layout",
+ "tile-layout",
]);
/** Serialize a client message to a JSON string for the wire. */
@@ -206,6 +208,23 @@ export function parseServerMessage(data: string): WsServerMessage | null {
};
return msg;
}
+ case "tile-layout": {
+ // Home tile-layout broadcast (the synced home grid): the FULL document
+ // for ONE device orientation. Light shape checks here (the document's
+ // structural validation is the backend's write-time job); the store
+ // filters by its active geometry mode.
+ if (parsed.mode !== "wide" && parsed.mode !== "tall") return null;
+ const data = parsed.data;
+ if (data === null || !isRecord(data) || data.version !== 2 || !Array.isArray(data.tiles)) {
+ return null;
+ }
+ const msg: TileLayoutChangedMessage = {
+ type: "tile-layout",
+ mode: parsed.mode,
+ data: data as unknown as TileLayoutChangedMessage["data"],
+ };
+ return msg;
+ }
default:
return null;
}