@unityevolv/ofiskit-ui-map 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +34 -0
  3. package/dist/Announcer.d.ts +21 -0
  4. package/dist/Announcer.d.ts.map +1 -0
  5. package/dist/Announcer.js +32 -0
  6. package/dist/Announcer.js.map +1 -0
  7. package/dist/CallAudio.d.ts +32 -0
  8. package/dist/CallAudio.d.ts.map +1 -0
  9. package/dist/CallAudio.js +72 -0
  10. package/dist/CallAudio.js.map +1 -0
  11. package/dist/CallControls.d.ts +60 -0
  12. package/dist/CallControls.d.ts.map +1 -0
  13. package/dist/CallControls.js +62 -0
  14. package/dist/CallControls.js.map +1 -0
  15. package/dist/CallTiles.d.ts +48 -0
  16. package/dist/CallTiles.d.ts.map +1 -0
  17. package/dist/CallTiles.js +134 -0
  18. package/dist/CallTiles.js.map +1 -0
  19. package/dist/DevicePanel.d.ts +32 -0
  20. package/dist/DevicePanel.d.ts.map +1 -0
  21. package/dist/DevicePanel.js +133 -0
  22. package/dist/DevicePanel.js.map +1 -0
  23. package/dist/Knocks.d.ts +46 -0
  24. package/dist/Knocks.d.ts.map +1 -0
  25. package/dist/Knocks.js +46 -0
  26. package/dist/Knocks.js.map +1 -0
  27. package/dist/OfficeMap.d.ts +69 -0
  28. package/dist/OfficeMap.d.ts.map +1 -0
  29. package/dist/OfficeMap.js +222 -0
  30. package/dist/OfficeMap.js.map +1 -0
  31. package/dist/Overflow.d.ts +41 -0
  32. package/dist/Overflow.d.ts.map +1 -0
  33. package/dist/Overflow.js +82 -0
  34. package/dist/Overflow.js.map +1 -0
  35. package/dist/PersonAvatar.d.ts +32 -0
  36. package/dist/PersonAvatar.d.ts.map +1 -0
  37. package/dist/PersonAvatar.js +80 -0
  38. package/dist/PersonAvatar.js.map +1 -0
  39. package/dist/Reactions.d.ts +47 -0
  40. package/dist/Reactions.d.ts.map +1 -0
  41. package/dist/Reactions.js +61 -0
  42. package/dist/Reactions.js.map +1 -0
  43. package/dist/RoomBar.d.ts +43 -0
  44. package/dist/RoomBar.d.ts.map +1 -0
  45. package/dist/RoomBar.js +120 -0
  46. package/dist/RoomBar.js.map +1 -0
  47. package/dist/Share.d.ts +74 -0
  48. package/dist/Share.d.ts.map +1 -0
  49. package/dist/Share.js +115 -0
  50. package/dist/Share.js.map +1 -0
  51. package/dist/StatusControl.d.ts +25 -0
  52. package/dist/StatusControl.d.ts.map +1 -0
  53. package/dist/StatusControl.js +77 -0
  54. package/dist/StatusControl.js.map +1 -0
  55. package/dist/controls.d.ts +32 -0
  56. package/dist/controls.d.ts.map +1 -0
  57. package/dist/controls.js +24 -0
  58. package/dist/controls.js.map +1 -0
  59. package/dist/hooks.d.ts +60 -0
  60. package/dist/hooks.d.ts.map +1 -0
  61. package/dist/hooks.js +182 -0
  62. package/dist/hooks.js.map +1 -0
  63. package/dist/index.d.ts +45 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +45 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/layout.d.ts +65 -0
  68. package/dist/layout.d.ts.map +1 -0
  69. package/dist/layout.js +93 -0
  70. package/dist/layout.js.map +1 -0
  71. package/dist/placement.d.ts +70 -0
  72. package/dist/placement.d.ts.map +1 -0
  73. package/dist/placement.js +83 -0
  74. package/dist/placement.js.map +1 -0
  75. package/dist/sounds.d.ts +30 -0
  76. package/dist/sounds.d.ts.map +1 -0
  77. package/dist/sounds.js +125 -0
  78. package/dist/sounds.js.map +1 -0
  79. package/dist/status.d.ts +47 -0
  80. package/dist/status.d.ts.map +1 -0
  81. package/dist/status.js +65 -0
  82. package/dist/status.js.map +1 -0
  83. package/dist/theme.d.ts +27 -0
  84. package/dist/theme.d.ts.map +1 -0
  85. package/dist/theme.js +57 -0
  86. package/dist/theme.js.map +1 -0
  87. package/dist/tileLayout.d.ts +27 -0
  88. package/dist/tileLayout.d.ts.map +1 -0
  89. package/dist/tileLayout.js +41 -0
  90. package/dist/tileLayout.js.map +1 -0
  91. package/dist/useCall.d.ts +107 -0
  92. package/dist/useCall.d.ts.map +1 -0
  93. package/dist/useCall.js +238 -0
  94. package/dist/useCall.js.map +1 -0
  95. package/dist/useShare.d.ts +54 -0
  96. package/dist/useShare.d.ts.map +1 -0
  97. package/dist/useShare.js +114 -0
  98. package/dist/useShare.js.map +1 -0
  99. package/dist/useSounds.d.ts +31 -0
  100. package/dist/useSounds.d.ts.map +1 -0
  101. package/dist/useSounds.js +56 -0
  102. package/dist/useSounds.js.map +1 -0
  103. package/package.json +25 -0
@@ -0,0 +1,54 @@
1
+ import type { OfficeState, OfisClient, Sharer } from '@unityevolv/ofiskit-realtime-client';
2
+ import type { CallMedia } from './useCall.js';
3
+ /**
4
+ * What the share looks like on this screen, and what happens to the view when one
5
+ * starts.
6
+ *
7
+ * Who is sharing comes from the **call** rather than from anybody's device flags,
8
+ * because the call holds one slot and asking it is how every screen in the room
9
+ * agrees about whose screen is on them. The stream comes from the adapter, like
10
+ * every other stream, so nothing here knows which provider delivered it.
11
+ */
12
+ export interface Share {
13
+ /** Whoever is sharing in the room you are standing in, or nobody. */
14
+ sharedBy: Sharer | null;
15
+ /** True when the share is this device's own, which is drawn differently. */
16
+ mine: boolean;
17
+ /** The share itself, once it has arrived. Null while it is on its way. */
18
+ stream: MediaStream | null;
19
+ }
20
+ export interface UseShareOptions {
21
+ /** Whether the call is filling the window, and how to change that. */
22
+ callView: boolean;
23
+ setCallView(next: boolean): void;
24
+ /**
25
+ * The call is always full size here, so a share has nothing to switch.
26
+ *
27
+ * On a phone the call view is not a preference but a rule. Following a share
28
+ * there would save "full size" as the layout to go back to and then write it
29
+ * into the remembered preference when the share ended, so the next time the same
30
+ * person opened the office on a wide screen it would open in call view.
31
+ */
32
+ fixed?: boolean;
33
+ }
34
+ export declare function useShare(client: OfisClient, state: OfficeState, media: CallMedia, options: UseShareOptions): Share;
35
+ /**
36
+ * Everybody's view follows the share, and then gives itself back.
37
+ *
38
+ * A share is the one thing in the office that is worth interrupting a layout for:
39
+ * somebody has put something on screen to be looked at, and a person sitting in map
40
+ * view would otherwise never see it. So every client switches to the call, and when
41
+ * the share ends every client goes back to whatever it was doing — which is the half
42
+ * that makes the switch acceptable rather than annoying.
43
+ *
44
+ * **A default and not a lock.** Switching back to the map during a share is allowed
45
+ * and is remembered: the layout is only restored for somebody who stayed where they
46
+ * were put, because restoring it for anybody else would be overriding a choice they
47
+ * made a moment ago.
48
+ */
49
+ export declare function useShareView(options: {
50
+ sharing: boolean;
51
+ callView: boolean;
52
+ setCallView(next: boolean): void;
53
+ }): void;
54
+ //# sourceMappingURL=useShare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useShare.d.ts","sourceRoot":"","sources":["../src/useShare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAA;AAO1F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE7C;;;;;;;;GAQG;AAEH,MAAM,WAAW,KAAK;IACpB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,4EAA4E;IAC5E,IAAI,EAAE,OAAO,CAAA;IACb,0EAA0E;IAC1E,MAAM,EAAE,WAAW,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,QAAQ,EAAE,OAAO,CAAA;IACjB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;IAChC;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,wBAAgB,QAAQ,CACtB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,eAAe,GACvB,KAAK,CA0EP;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;CACjC,GAAG,IAAI,CAgCP"}
@@ -0,0 +1,114 @@
1
+ import { sharerIn, yourRoom } from '@unityevolv/ofiskit-realtime-client';
2
+ import { useCallback, useEffect, useRef } from 'react';
3
+ import { useAnnounce } from './Announcer.js';
4
+ import { useClientEvents } from './hooks.js';
5
+ import { describeShare } from './Share.js';
6
+ export function useShare(client, state, media, options) {
7
+ const announce = useAnnounce();
8
+ const roomId = yourRoom(state);
9
+ const sharedBy = roomId ? sharerIn(state, roomId) : null;
10
+ const mine = sharedBy?.deviceId === state.you.deviceId;
11
+ const stream = !sharedBy
12
+ ? null
13
+ : mine
14
+ ? media.local.screen
15
+ : (media.peers.get(sharedBy.deviceId)?.screen ?? null);
16
+ useShareView({
17
+ sharing: sharedBy !== null && !options.fixed,
18
+ callView: options.callView,
19
+ setCallView: options.setCallView,
20
+ });
21
+ /*
22
+ * A share starting or stopping, said once.
23
+ *
24
+ * Politely: it is a change to what is on screen rather than something that needs
25
+ * to interrupt whoever is talking. Named, because "somebody is sharing" is no use
26
+ * in a room of four people — and said at all because a screen appearing is
27
+ * invisible to exactly the person who most needs to know it happened.
28
+ */
29
+ const said = useRef(null);
30
+ const yourDeviceId = state.you.deviceId;
31
+ useEffect(() => {
32
+ const before = said.current;
33
+ // The same share, reported again by another diff: the slot is identified by who
34
+ // holds it and since when, so a re-render is not an event.
35
+ if (before?.deviceId === sharedBy?.deviceId && before?.startedAt === sharedBy?.startedAt) {
36
+ return;
37
+ }
38
+ said.current = sharedBy;
39
+ // Both sentences are said when one share replaces another, because both things
40
+ // happened: one screen went away and a different one arrived.
41
+ if (before && before.deviceId !== yourDeviceId && before.displayName) {
42
+ announce(describeShare(before.displayName, false));
43
+ }
44
+ // Never your own: the banner already says it, and announcing it would be
45
+ // telling somebody what they just did.
46
+ if (sharedBy && sharedBy.deviceId !== yourDeviceId && sharedBy.displayName) {
47
+ announce(describeShare(sharedBy.displayName, true));
48
+ }
49
+ }, [announce, sharedBy, yourDeviceId]);
50
+ /*
51
+ * Your own share being taken over, said assertively.
52
+ *
53
+ * The one share message that interrupts, because it is the one that changes what
54
+ * the person is doing rather than what they are looking at: somebody who thinks
55
+ * they are still presenting will carry on talking about a screen nobody can see.
56
+ */
57
+ useClientEvents(client, useCallback((event) => {
58
+ if (event.type !== 'share.ended')
59
+ return;
60
+ const who = state.people.get(event.byUserId)?.displayName;
61
+ announce(who
62
+ ? `${who} is sharing now, so your screen share stopped.`
63
+ : 'Somebody else is sharing now, so your screen share stopped.', 'assertive');
64
+ }, [announce, state.people]));
65
+ return { sharedBy, mine, stream };
66
+ }
67
+ /**
68
+ * Everybody's view follows the share, and then gives itself back.
69
+ *
70
+ * A share is the one thing in the office that is worth interrupting a layout for:
71
+ * somebody has put something on screen to be looked at, and a person sitting in map
72
+ * view would otherwise never see it. So every client switches to the call, and when
73
+ * the share ends every client goes back to whatever it was doing — which is the half
74
+ * that makes the switch acceptable rather than annoying.
75
+ *
76
+ * **A default and not a lock.** Switching back to the map during a share is allowed
77
+ * and is remembered: the layout is only restored for somebody who stayed where they
78
+ * were put, because restoring it for anybody else would be overriding a choice they
79
+ * made a moment ago.
80
+ */
81
+ export function useShareView(options) {
82
+ const { sharing, callView, setCallView } = options;
83
+ /** What the view was before the share, or null when no share is running. */
84
+ const saved = useRef(null);
85
+ /** Whether a share was running last time this ran, so only changes act. */
86
+ const was = useRef(false);
87
+ useEffect(() => {
88
+ /*
89
+ * Only the two moments that matter: a share starting and a share ending.
90
+ *
91
+ * The current view is a dependency because the effect reads it, and the guard is
92
+ * what keeps that from mattering: somebody changing their own view mid-share runs
93
+ * this again and it does nothing, which is the whole of "a default, not a lock".
94
+ */
95
+ if (sharing === was.current)
96
+ return;
97
+ was.current = sharing;
98
+ if (sharing) {
99
+ saved.current = callView;
100
+ if (!callView)
101
+ setCallView(true);
102
+ return;
103
+ }
104
+ if (saved.current === null)
105
+ return;
106
+ const previous = saved.current;
107
+ saved.current = null;
108
+ // Their own choice stands. Somebody who went back to the map during the share has
109
+ // already said what they want to be looking at.
110
+ if (callView)
111
+ setCallView(previous);
112
+ }, [callView, sharing, setCallView]);
113
+ }
114
+ //# sourceMappingURL=useShare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useShare.js","sourceRoot":"","sources":["../src/useShare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { OfficeState, OfisClient } from '@unityevolv/ofiskit-realtime-client';
2
+ import { type Sounds } from './sounds.js';
3
+ /**
4
+ * When the office makes a sound.
5
+ *
6
+ * Three moments, each one about somebody reaching you:
7
+ * - somebody knocks on the door of the room you are in — a knock;
8
+ * - somebody walks into the room you are in — a chime;
9
+ * - the room you knocked on lets you in — a chime.
10
+ *
11
+ * And the times it stays quiet, which matter as much:
12
+ * - arrivals in reception, which is where everybody arrives — a chime every time
13
+ * somebody walked into the office would be noise, not news;
14
+ * - a knock the server marked silent, because everybody inside is on do not
15
+ * disturb;
16
+ * - anything at all while you are on do not disturb yourself;
17
+ * - your own moves, which you do not need telling about;
18
+ * - everything, when the person has turned sounds off.
19
+ */
20
+ export interface UseSoundsOptions {
21
+ /** The person's own switch. On by default in the app, and remembered per device. */
22
+ enabled: boolean;
23
+ /** Rooms where arrivals make no sound: reception, where everybody lands. */
24
+ quietRoomIds: readonly string[];
25
+ /** The speaker chosen for calls, so the office's sounds come out of the same place. */
26
+ speakerDeviceId?: string;
27
+ /** Injected in tests; the browser's own sounds otherwise. */
28
+ sounds?: Sounds;
29
+ }
30
+ export declare function useSounds(client: OfisClient, state: OfficeState, options: UseSoundsOptions): void;
31
+ //# sourceMappingURL=useSounds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSounds.d.ts","sourceRoot":"","sources":["../src/useSounds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAA;AAKlF,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,aAAa,CAAA;AAEvD;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,oFAAoF;IACpF,OAAO,EAAE,OAAO,CAAA;IAChB,4EAA4E;IAC5E,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;IAC/B,uFAAuF;IACvF,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAyDjG"}
@@ -0,0 +1,56 @@
1
+ import { peopleIn, you as yourPresence, yourRoom } from '@unityevolv/ofiskit-realtime-client';
2
+ import { useCallback, useEffect, useRef } from 'react';
3
+ import { useClientEvents } from './hooks.js';
4
+ import { createSounds } from './sounds.js';
5
+ export function useSounds(client, state, options) {
6
+ const sounds = useRef(options.sounds ?? null);
7
+ const play = useCallback((which) => {
8
+ sounds.current ??= createSounds();
9
+ sounds.current[which]();
10
+ }, []);
11
+ const { enabled, quietRoomIds, speakerDeviceId } = options;
12
+ const doNotDisturb = yourPresence(state)?.status === 'dnd';
13
+ const quiet = !enabled || doNotDisturb;
14
+ useEffect(() => {
15
+ sounds.current?.useSpeaker(speakerDeviceId);
16
+ }, [speakerDeviceId]);
17
+ useClientEvents(client, useCallback((event) => {
18
+ if (quiet)
19
+ return;
20
+ if (event.type === 'knock' && !event.silent)
21
+ play('knock');
22
+ if (event.type === 'admitted')
23
+ play('chime');
24
+ }, [play, quiet]));
25
+ /*
26
+ * Arrivals, noticed as a change in who is in your room.
27
+ *
28
+ * Compared against the last time the room was looked at, and only when you are
29
+ * still in the same room: when you move, everybody in the new room is "new", and
30
+ * none of them arrived.
31
+ */
32
+ const roomId = yourRoom(state);
33
+ const others = roomId
34
+ ? peopleIn(state, roomId)
35
+ .map((person) => person.userId)
36
+ .filter((userId) => userId !== state.you.userId)
37
+ .sort()
38
+ : [];
39
+ const key = others.join(',');
40
+ const last = useRef({
41
+ roomId: null,
42
+ people: new Set(),
43
+ });
44
+ useEffect(() => {
45
+ const before = last.current;
46
+ const now = { roomId, people: new Set(key ? key.split(',') : []) };
47
+ last.current = now;
48
+ if (quiet || !roomId || before.roomId !== roomId)
49
+ return;
50
+ if (quietRoomIds.includes(roomId))
51
+ return;
52
+ if ([...now.people].some((userId) => !before.people.has(userId)))
53
+ play('chime');
54
+ }, [key, play, quiet, quietRoomIds, roomId]);
55
+ }
56
+ //# sourceMappingURL=useSounds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSounds.js","sourceRoot":"","sources":["../src/useSounds.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@unityevolv/ofiskit-ui-map",
3
+ "version": "0.1.0",
4
+ "description": "The office you can see: the map, room bars, avatars, video tiles, the call controls and the status control. React DOM, built on unitykit.",
5
+ "license": "AGPL-3.0-only",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" } },
10
+ "files": ["dist"],
11
+ "sideEffects": false,
12
+ "publishConfig": { "access": "public" },
13
+ "repository": { "type": "git", "url": "git+https://github.com/UnityEvolv/ofis-kit.git", "directory": "packages/ui-map" },
14
+ "scripts": { "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit" },
15
+ "dependencies": {
16
+ "@unityevolv/ofiskit-presence-store": "0.1.0",
17
+ "@unityevolv/ofiskit-realtime-client": "0.1.0",
18
+ "@unityevolv/ofiskit-template": "0.1.0"
19
+ },
20
+ "peerDependencies": {
21
+ "@unityevolv/unitykit": ">=0.1.0",
22
+ "react": ">=18.0.0",
23
+ "react-dom": ">=18.0.0"
24
+ }
25
+ }