architwin 1.13.10 → 1.14.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.
@@ -168,7 +168,6 @@ i18n
168
168
  "General Settings": "General Settings",
169
169
  "UploadImage": "Upload Image",
170
170
  "Unsend": "Unsend",
171
- "PipesMenu": "Pipes",
172
171
  "Pipes": "Pipes",
173
172
  "SelectPipeType": "Select Pipe Type",
174
173
  "AddPipeType": "Add Pipe Type",
@@ -193,11 +192,31 @@ i18n
193
192
  "ConfirmDeletePipeCategory": "Are you sure you want to delete this pipe category?",
194
193
  "DeletePipe": "Delete pipe",
195
194
  "ConfirmDeletePipe": "Are you sure you want to delete this pipe?",
196
- "PipeCategoryName": "Enter pipe type",
195
+ "PipeCategoryName": "Enter pipe type name",
197
196
  "HideShowAllPipes": "Hide/Show All Pipes",
198
- "PipePlaceHolder": "Ex: Gas Pipe",
199
197
  "Pipe": "Pipe",
200
- "Vertex": "Vertex"
198
+ "Vertex": "Vertex",
199
+ "ScreenShare": "Screen Share",
200
+ "Users": "Users",
201
+ "EndSession": "End Session",
202
+ "SharingSpace": "Sharing Space",
203
+ "On": "On",
204
+ "Off": "Off",
205
+ "BackToUserList": "Back to user list",
206
+ "ScreenShareRequestModalMessage": "Waiting for remote screen share confirmation",
207
+ "ScreenShareRequestModalSubMessage": "You are requesting to remotely share your space to",
208
+ "CancelRequest": "Cancel Request",
209
+ "ViewingRemoteSpace": "Viewing Remote Space",
210
+ "LeaveSession": "Leave Session",
211
+ "IsSharingTheirSpace": "Is sharing their space",
212
+ "ToYou": "to you",
213
+ "ViewingInstructions": "During a remote space sharing session, you cannot navigate around the space, only your host has control during the session",
214
+ "Pending": "Pending",
215
+ "NowSharing": "Now Sharing",
216
+ "ConfirmLeaveSession": "画面共有を終了しますか?",
217
+ "ConfirmLeaveSessionReminder": "",
218
+ "InSession": "In Session",
219
+ "Leave": "Leave",
201
220
  }
202
221
  },
203
222
  ja: {
@@ -365,36 +384,55 @@ i18n
365
384
  "Search...": "検索...",
366
385
  "UploadImage": "画像をアップロード",
367
386
  "Unsend": "取り消し",
368
- "PipesMenu": "矢印マーカー",
369
387
  "Pipes": "矢印マーカー",
370
388
  "SelectPipeType": "矢印マーカー種別選択",
371
- "AddPipeType": "配管種別を追加",
372
- "EditPipeType": "配管種別を編集",
373
- "PipeTypeName": "配管種別名",
374
- "CategoryColor": "配管色",
375
- "NoPipesToDisplay": "表示する配管がありません",
376
- "DrawPipe": "配管を描画",
389
+ "AddPipeType": "矢印マーカー種別を追加",
390
+ "EditPipeType": "矢印マーカー種別を編集",
391
+ "PipeTypeName": "矢印マーカー名",
392
+ "CategoryColor": "矢印マーカー色",
393
+ "NoPipesToDisplay": "表示する快感がありません",
394
+ "DrawPipe": " 矢印マーカーを描画",
377
395
  "NoVertexToDisplay": "表示する頂点がありません",
378
- "NoPipesTypeToDisplay": "表示する配管がありません",
396
+ "NoPipesTypeToDisplay": "表示する矢印マーカー種別がありません",
379
397
  "DrawingModeIsActive": "描画モードが適応中",
380
- "PipeSavedSuccessfully": "配管を保存しました",
381
- "SaveTheCurrentPipeBeforeProceeding": "現在描画している配管を保存してから進めてください",
398
+ "PipeSavedSuccessfully": "矢印マーカーを保存しました",
399
+ "SaveTheCurrentPipeBeforeProceeding": "現在描画している矢印マーカーを保存してから進めてください",
382
400
  "CategorySuccessfullySaved": "カテゴリを正常に保存しました",
383
- "PipeDeletedSuccessfully": "配管が正常に削除されました",
401
+ "PipeSuccessfullyDeleted": "矢印マーカーが正常に削除されました!",
384
402
  "CannotDrawNoColorSelected": "描画不可:色を選択していません",
385
403
  "DrawingModeIsNowActive": "描画モードが現在有効です",
386
404
  "DrawingModeIsCurrentlyInactive": "描画モードは現在無効です",
387
- "DeletePipeCategory": "配管種別を削除",
405
+ "DeletePipeCategory": "矢印マーカー種別を削除",
388
406
  "VertexDeletedSuccessfully": "頂点が正常に削除されました",
389
- "PipeCategoryDeletedSuccessfully": "配管種別が正常に削除されました",
390
- "ConfirmDeletePipeCategory": "この配管種別を削除してもよろしいですか?",
391
- "DeletePipe": "配管を削除",
392
- "ConfirmDeletePipe": "この配管を削除してもよろしいですか?",
393
- "PipeCategoryName": "配管種別を入力",
394
- "HideShowAllPipes": "全ての配管を表示/非表示",
395
- "PipePlaceHolder": "配管種別名を入力",
407
+ "PipeCategoryDeletedSuccessfully": "矢印マーカー種別が正常に削除されました!",
408
+ "ConfirmDeletePipeCategory": "この矢印マーカー種別を削除してもよろしいですか?",
409
+ "DeletePipe": "矢印マーカーを削除",
410
+ "ConfirmDeletePipe": "この矢印マーカーを削除してもよろしいですか?",
411
+ "PipeCategoryName": "矢印マーカー種別を入力",
412
+ "HideShowAllPipes": "全ての矢印マーカーを表示/非表示",
396
413
  "Pipe": "矢印マーカー",
397
- "Vertex": "頂点"
414
+ "Vertex": "頂点",
415
+ "Screen Share": "画面共有",
416
+ "Users": "ユーザー",
417
+ "EndSession": "画面共有を終了",
418
+ "SharingSpace": "画面共有",
419
+ "On": "オン",
420
+ "Off": "オフ",
421
+ "BackToUserList": "ユーザリストに戻る",
422
+ "ScreenShareRequestModalMessage": "先方の画面共有参加を待っています",
423
+ "ScreenShareRequestModalSubMessage": "画面共有のリクエストを受信しています",
424
+ "CancelRequest": "リクエストを拒否",
425
+ "ViewingRemoteSpace": "先方のスペースを表示",
426
+ "LeaveSession": "画面共有を終了",
427
+ "IsSharingTheirSpace": "上記のユーザが画面共有をしています",
428
+ "ToYou": "",
429
+ "ViewingInstructions": "画面共有中は供している人しかスペース内を動かすことができません",
430
+ "Pending": "承認待ち",
431
+ "NowSharing": "画面共有開始",
432
+ "ConfirmLeaveSession": "画面共有を終了しますか?",
433
+ "ConfirmLeaveSessionReminder": "",
434
+ "InSession": "共有中",
435
+ "Leave": "終了",
398
436
  }
399
437
  }
400
438
  },
@@ -2,6 +2,8 @@ import { _mpConfig, themeManager } from "../../../architwin";
2
2
  import { renderSidebarContainer } from "./sidebarContainer";
3
3
  import { renderMenuBar, setActiveMenu, clearActiveMenu, getObjectListStatus } from "./menuBar";
4
4
  import { renderObjectListPane, renderObjectCards, removeObjectCard } from "./objectListPane";
5
+ import { renderSpaceUserListPane } from "./spaceUserListPane";
6
+ import { renderViewingRemoteSpace } from "./viewingRemoteSpace";
5
7
  import { renderAddObjectPane } from "./addObjectPane";
6
8
  import { renderTagFormPane, getTagFormData, setTagCategoriesOption, tagFormMode, selectedTag, renderCategoryDropdownOptions, toggleDropdown } from "./tagFormPane";
7
9
  import { renderTagListPane, renderTags, renderTagRow, addClickEventToTagRow, setTagLink, getTagLink, selectedCategoryFilterId, selectedSubCategoryFilterId, filterTagList } from "./tagListPane";
@@ -23,12 +25,13 @@ import { renderRoomTreePane } from "./spacePartition/roomTreePane";
23
25
  import { renderRoomFormPane } from "./spacePartition/roomFormPane";
24
26
  import { renderBasepointCalibratePane } from "./basepointCalibratePane";
25
27
  import { renderGeneralSettingsMenu } from "./generalSettingsMenuPane";
28
+ import { renderScreenSharePane } from "./screenSharePane";
26
29
  import { PipeList } from "./pipeListPane";
27
30
  import { PipeForm } from "./pipeFormPane";
28
31
  const pipeList = new PipeList();
29
32
  const pipeForm = new PipeForm();
30
33
  let iFrame, sidebarContainer;
31
- let menuBar, actionBar, objectListPane, addObjectPane, tagListPane, tagFormPane, addMediaScreenForm, libraryPane, tagMessagingPane, themePane, modelControlPane, actionSettingsPane, roomTreePane, roomFormPane, basepointCalibratePane, generalSettingsPane, pipeListPane, pipeFormPane;
34
+ let menuBar, actionBar, objectListPane, addObjectPane, tagListPane, tagFormPane, addMediaScreenForm, libraryPane, tagMessagingPane, themePane, modelControlPane, actionSettingsPane, roomTreePane, roomFormPane, basepointCalibratePane, generalSettingsPane, spaceUserListPane, viewingRemoteSpace, usersPane, pipeListPane, pipeFormPane;
32
35
  function getIframeElement(iframeId) {
33
36
  if (!iframeId || iframeId === '') {
34
37
  console.error("IframeId is empty or undefined");
@@ -83,6 +86,8 @@ function renderToolbarUI(payload) {
83
86
  iFrame.appendChild(sidebarContainer);
84
87
  menuBar = renderMenuBar(iFrame);
85
88
  objectListPane = renderObjectListPane(payload.objects);
89
+ spaceUserListPane = renderSpaceUserListPane();
90
+ viewingRemoteSpace = renderViewingRemoteSpace();
86
91
  addObjectPane = renderAddObjectPane();
87
92
  tagFormPane = renderTagFormPane();
88
93
  tagListPane = renderTagListPane();
@@ -97,6 +102,7 @@ function renderToolbarUI(payload) {
97
102
  actionSettingsPane = renderActionSettingsPane();
98
103
  basepointCalibratePane = renderBasepointCalibratePane();
99
104
  generalSettingsPane = renderGeneralSettingsMenu();
105
+ usersPane = renderScreenSharePane();
100
106
  pipeListPane = pipeList.renderPane();
101
107
  pipeFormPane = pipeForm.renderPane();
102
108
  renderModal();
@@ -110,11 +116,14 @@ function renderToolbarUI(payload) {
110
116
  sidebarContainer.appendChild(tagMessagingPane);
111
117
  sidebarContainer.appendChild(libraryPane);
112
118
  sidebarContainer.appendChild(objectListPane);
119
+ sidebarContainer.appendChild(spaceUserListPane);
120
+ sidebarContainer.appendChild(viewingRemoteSpace);
113
121
  sidebarContainer.appendChild(addObjectPane);
114
122
  sidebarContainer.appendChild(tagFormPane);
115
123
  sidebarContainer.appendChild(tagListPane);
116
124
  sidebarContainer.appendChild(addMediaScreenForm);
117
125
  sidebarContainer.appendChild(generalSettingsPane);
126
+ sidebarContainer.appendChild(usersPane);
118
127
  sidebarContainer.appendChild(pipeListPane);
119
128
  sidebarContainer.appendChild(pipeFormPane);
120
129
  // Place your new pane
@@ -137,6 +146,9 @@ function renderToolbarUI(payload) {
137
146
  roomFormPane.style.display = 'none';
138
147
  actionSettingsPane.style.display = 'none';
139
148
  generalSettingsPane.style.display = 'none';
149
+ spaceUserListPane.style.display = 'none';
150
+ viewingRemoteSpace.style.display = 'none';
151
+ usersPane.style.display = 'none';
140
152
  pipeListPane.style.display = 'none';
141
153
  pipeFormPane.style.display = 'none';
142
154
  const customTheme = window.localStorage.getItem('customizedTheme');
@@ -5,6 +5,7 @@ export declare let isThemeEnabled: boolean;
5
5
  export declare let isRoomCreationEnabled: boolean;
6
6
  export declare let isBIMEnabled: boolean;
7
7
  export declare let isGeneralSettingsEnabled: boolean;
8
+ export declare let isSpaceScreenSharingEnabled: boolean;
8
9
  export declare let isPipeEnabled: boolean;
9
10
  export declare function renderMenuBar(iFrame: HTMLIFrameElement): HTMLDivElement;
10
11
  export declare function isAdminUser(): void;
@@ -12,6 +12,7 @@ export let isThemeEnabled = true;
12
12
  export let isRoomCreationEnabled = true;
13
13
  export let isBIMEnabled = true;
14
14
  export let isGeneralSettingsEnabled = true;
15
+ export let isSpaceScreenSharingEnabled = true;
15
16
  export let isPipeEnabled = true;
16
17
  export function renderMenuBar(iFrame) {
17
18
  const bimImageIcon = getAssetUrl('bim.png');
@@ -48,7 +49,7 @@ export function renderMenuBar(iFrame) {
48
49
  </div>
49
50
  <div class="at_sidebar_button_icon" style="display:${isPipeEnabled ? 'block' : 'none'}">
50
51
  <span class="mdi mdi-arrow-decision" id="at-pipe-btn" data-cy="at-pipe-btn" target-pane="at-pipe-list-pane"></span>
51
- <div class="at_icon_tooltip" data-cy="at-tooltip-pipe">${i18n.t('PipesMenu')}</div>
52
+ <div class="at_icon_tooltip" data-cy="at-tooltip-pipe">${i18n.t('Pipes')}</div>
52
53
  </div>
53
54
  <div class="at_sidebar_button_icon" style="display:${isThemeEnabled ? 'block' : 'none'}">
54
55
  <span class="mdi mdi-palette" id="at-theme-picker-btn" data-cy="at-theme-picker-btn" target-pane="at-theme-pane"></span>
@@ -66,6 +67,10 @@ export function renderMenuBar(iFrame) {
66
67
  <span class="mdi mdi-cog-outline" id="at-general-setting-btn" data-cy="at-general-setting-btn" target-pane="at-general-setting-pane"></span>
67
68
  <div class="at_icon_tooltip" data-cy="at-tooltip-general-setting">${i18n.t('General Settings')}</div>
68
69
  </div>
70
+ <div class="at_sidebar_button_icon" style="display:${isSpaceScreenSharingEnabled ? 'block' : 'none'}">
71
+ <span class="mdi mdi-monitor-multiple" id="at-screen-share-btn" data-cy="at-screen-share-pane" target-pane="at-screen-share-pane"></span>
72
+ <div class="at_icon_tooltip" data-cy="at-tooltip-screen-share">${i18n.t('Screen Share')}</div>
73
+ </div>
69
74
  `;
70
75
  return menuBarElement;
71
76
  }
@@ -108,6 +113,11 @@ function setMenuItemsStatus() {
108
113
  isGeneralSettingsEnabled = _mpConfig.toolbarConfig.menuItems.generalSetting;
109
114
  log.info("__@ isGeneralSettingsEnabled: ", isGeneralSettingsEnabled);
110
115
  }
116
+ // SCREEN SHARING
117
+ if (menuItems.spaceScreenSharing !== undefined) {
118
+ isSpaceScreenSharingEnabled = _mpConfig.toolbarConfig.menuItems.spaceScreenSharing;
119
+ log.info("__@ isSpaceScreenSharingEnabled: ", isSpaceScreenSharingEnabled);
120
+ }
111
121
  // PIPE CONFIG
112
122
  if (menuItems.pipe !== undefined) {
113
123
  isPipeEnabled = _mpConfig.toolbarConfig.menuItems.pipe;
@@ -136,6 +146,7 @@ export function setActiveMenu(id) {
136
146
  case 'at-settings-btn':
137
147
  case 'at-general-setting-btn':
138
148
  case 'at-pipe-btn':
149
+ case 'at-screen-share-btn':
139
150
  if (parent.classList.contains('at_sidebar_button_icon_active')) {
140
151
  // remove
141
152
  log.info("removing active...");
@@ -37,7 +37,7 @@ export class PipeForm {
37
37
  </div>
38
38
  <div class="">
39
39
  <span class="">${i18n.t('PipeTypeName')}</span>
40
- <input id="at_pipe_type_name_input" class="at_pipe_input" type="text" name="pipe-name" placeholder="${i18n.t('PipePlaceHolder')}" required>
40
+ <input id="at_pipe_type_name_input" class="at_pipe_input" type="text" name="pipe-name" placeholder="${i18n.t('PipeCategoryName')}" required>
41
41
  </div>
42
42
  <div class="at_h-responsive-264">
43
43
  <div class="at_py-3">
@@ -338,7 +338,7 @@ export class PipeForm {
338
338
  if (targetObj) {
339
339
  disposeModel(targetObj);
340
340
  }
341
- notyf.success(`${i18n.t('PipeSuccessfullyDeleted!')}`);
341
+ notyf.success(`${i18n.t('PipeSuccessfullyDeleted')}`);
342
342
  toggleModal(false);
343
343
  }
344
344
  else {
@@ -33,7 +33,7 @@ export class PipeList {
33
33
  <span class="mdi mdi-keyboard at_pull_left at_icon_hover ">
34
34
  ${getShortcutTooltipHTML()}
35
35
  </span>
36
- <span>${i18n.t('PipesMenu')}</span>
36
+ <span>${i18n.t('Pipes')}</span>
37
37
  </div>
38
38
  <div class="at_form_container ">
39
39
  <div class="at_field at_flex_column" style="${_pipeCategories ? '' : 'display: none;'}">
@@ -301,7 +301,7 @@ export class PipeList {
301
301
  if (targetObj) {
302
302
  disposeModel(targetObj);
303
303
  }
304
- notyf.success(`${i18n.t('PipeDeletedSuccessfully')}`);
304
+ notyf.success(`${i18n.t('PipeSuccessfullyDeleted')}`);
305
305
  toggleModal(false);
306
306
  }
307
307
  this.collapse.removeElement(uuid, type);
@@ -7,7 +7,9 @@ export declare function renderOfflineUserRow(user: ScreenShareUser): HTMLTableRo
7
7
  export declare function handleClickEventUserRow(): void;
8
8
  export declare function renderSharingSpaceDetail(user: ScreenShareSessionUser): void;
9
9
  export declare function handleClickEventBackToUserListLink(): void;
10
- export declare function renderScreenShareRequestModal(request: ScreenShareRequest): void;
10
+ export declare function renderScreenShareLeaveConfirmationModal(isUserHost: boolean): void;
11
+ export declare function handleModalCancelButton(): void;
12
+ export declare function handleModalLeaveButton(isHost: boolean): void;
11
13
  export declare function handleInputEventSelectPointerSettings(): void;
12
14
  export declare function handleClickEventEndSessionBtn(): void;
13
15
  export declare function handleScreenShareUsersUpdated(payload: {
@@ -1,4 +1,4 @@
1
- import { _currentSpace, dispatchSpaceEvent } from '../../../architwin';
1
+ import { _currentSpace, _screenSharingHostUser, dispatchSpaceEvent } from '../../../architwin';
2
2
  import { SPACE_EVENTS } from '../../../types';
3
3
  import i18n from './i18n';
4
4
  let _spaceData = null;
@@ -25,7 +25,7 @@ export function renderScreenSharePane() {
25
25
  <table id="at-user-list-table">
26
26
  </table>
27
27
  </div>
28
- <button type="button" id="at-screen-share-end-session-btn" class="at_screen_share_end_session_btn"
28
+ <button type="button" id="at-screen-share-end-session-btn" class="at_SCREEN_SHARE_HOST_END_SESSION_btn"
29
29
  style="display:none;">
30
30
  ${i18n.t('EndSession')}
31
31
  </button>
@@ -36,19 +36,22 @@ export function renderScreenSharePane() {
36
36
  }
37
37
  export function renderUsersList(users) {
38
38
  _onDisplayComponent = 'USER_LIST';
39
- _screenShareUsers = sortUsersByStatus(users);
39
+ _screenShareUsers = [];
40
+ const _offlineUsers = users.filter(u => u.onlineStatus === 'offline');
41
+ const _notOfflineUsers = users.filter(u => u.onlineStatus !== 'offline');
42
+ _screenShareUsers = [..._notOfflineUsers, ..._offlineUsers];
40
43
  const usersListContainer = document.getElementById("at-user-list-table");
41
44
  if (!usersListContainer) {
42
45
  console.error("usersListContainer does not exist in DOM");
43
46
  return;
44
47
  }
45
48
  if (users.length <= 0) {
46
- console.log("No tags to load");
49
+ console.log("No users to load");
47
50
  usersListContainer.innerHTML = ``;
48
51
  return;
49
52
  }
50
53
  usersListContainer.innerHTML = '';
51
- users.forEach(user => {
54
+ _screenShareUsers.forEach(user => {
52
55
  const row = user.onlineStatus !== 'offline' ? renderOnlineUserRow(user) : renderOfflineUserRow(user);
53
56
  usersListContainer.appendChild(row);
54
57
  });
@@ -63,19 +66,19 @@ export function renderOnlineUserRow(user) {
63
66
  const iconOrSharingText = user.onlineStatus === 'in_session'
64
67
  ? `
65
68
  <div class="at_flex at_items_center at_justify_center">
66
- <p>In Session</p>
69
+ <p>${i18n.t('InSession')}</p>
67
70
  </div>
68
71
  `
69
72
  : user.onlineStatus === 'pending'
70
73
  ? `
71
74
  <div class="at_flex at_items_center at_justify_center">
72
- <p>Pending</p>
75
+ <p>${i18n.t('Pending')}</p>
73
76
  </div>
74
77
  `
75
78
  : user.onlineStatus === 'sharing'
76
79
  ? `
77
80
  <div class="at_flex at_items_center at_justify_center">
78
- <p>Now Sharing</p>
81
+ <p>${i18n.t('NowSharing')}</p>
79
82
  </div>
80
83
  `
81
84
  : `
@@ -191,7 +194,7 @@ export function renderSharingSpaceDetail(user) {
191
194
  <span class="mdi mdi-arrow-left"></span>
192
195
  <p> ${i18n.t('BackToUserList')}</p>
193
196
  </div>
194
- <button type="button" id="at-screen-share-end-session-btn" class="at_screen_share_end_session_btn">
197
+ <button type="button" id="at-screen-share-end-session-btn" class="at_SCREEN_SHARE_HOST_END_SESSION_btn">
195
198
  ${i18n.t('EndSession')}
196
199
  </button>
197
200
  </div>
@@ -225,23 +228,31 @@ function recreateUserListContainer() {
225
228
  <table id="at-user-list-table">
226
229
  </table>
227
230
  </div>
228
- <button type="button" id="at-screen-share-end-session-btn" class="at_screen_share_end_session_btn"
231
+ <button type="button" id="at-screen-share-end-session-btn" class="at_button at_ghost at_w-full"
229
232
  style="display:${endSessionBtnVisibility};">
230
- ${i18n.t('End Session')}
233
+ ${i18n.t('EndSession')}
231
234
  </button>
232
235
  `;
233
236
  }
234
- export function renderScreenShareRequestModal(request) {
237
+ export function renderScreenShareLeaveConfirmationModal(isUserHost) {
235
238
  _onDisplayComponent = 'SCREEN_SHARE_REQUEST_MODAL';
239
+ // remove any existing modal first
240
+ const existingModal = document.getElementById('at-screen-share-request-modal');
241
+ if (existingModal) {
242
+ existingModal.remove();
243
+ }
236
244
  const element = document.createElement('dialog');
237
245
  element.setAttribute('id', 'at-screen-share-request-modal');
238
246
  element.classList.add('at_screen_share_request_modal');
239
247
  element.innerHTML = `
240
248
  <div class="at_screen_share_request_modal_content at_flex at_flex_column at_justify_center at_items_center">
241
- <div class="at_screen_share_icon mdi mdi-monitor-multiple"></div>
242
- <h1 class="at_screen_share_request_message">${i18n.t('ScreenShareRequestModalMessage')}</h1>
243
- <p class="at_screen_share_request_sub_message"> ${i18n.t('ScreenShareRequestModalSubMessage')} <strong>${request.user.name}</strong></p>
244
- <button type="button" id="at-screen-share-request-btn" class="at_screen_share_cancel_request_btn">${i18n.t('CancelRequest')}</button>
249
+ <div class="at_screen_share_icon mdi mdi-logout-variant"></div>
250
+ <h1 class="at_screen_share_request_message">${i18n.t('ConfirmLeaveSession')}</h1>
251
+ <p class="at_screen_share_request_sub_message"> ${i18n.t('ConfirmLeaveSessionReminder')}</p>
252
+ <div class="at_flex at_flex_row at_gap_2rem">
253
+ <button type="button" id="at-screen-share-leave-confirmation-cancel-btn" class="at_screen_share_leave_confirmation_cancel_btn">${i18n.t('Cancel')}</button>
254
+ <button type="button" id="at-screen-share-leave-confirmation-leave-btn" class="at_screen_share_leave_confirmation_leave_btn">${i18n.t('Leave')}</button>
255
+ </div>
245
256
  </div>
246
257
  `;
247
258
  // disabled modal dismiss via Esc key
@@ -255,21 +266,61 @@ export function renderScreenShareRequestModal(request) {
255
266
  element.addEventListener('cancel', (event) => {
256
267
  event.preventDefault();
257
268
  });
258
- handleScreenShareCancelRequest(element, request);
259
269
  document.body.appendChild(element);
260
270
  element.showModal();
271
+ // attach button event handlers after modal is created
272
+ handleModalCancelButton();
273
+ handleModalLeaveButton(isUserHost);
261
274
  }
262
- function handleScreenShareCancelRequest(dialogElement, request) {
263
- var _a;
264
- if (dialogElement) {
265
- (_a = dialogElement.querySelector('#at-screen-share-request-btn')) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => {
266
- const cancelRequest = Object.assign(Object.assign({}, request), { status: 'canceled' });
267
- dispatchSpaceEvent(SPACE_EVENTS.SCREEN_SHARE_CANCEL_REQUEST, cancelRequest);
268
- dialogElement.close();
269
- dialogElement.remove();
270
- _onDisplayComponent = 'USER_LIST';
271
- });
272
- }
275
+ export function handleModalCancelButton() {
276
+ const cancelBtn = document.getElementById('at-screen-share-leave-confirmation-cancel-btn');
277
+ if (!cancelBtn)
278
+ return;
279
+ // Check if listener already exists
280
+ if (cancelBtn.dataset.listenerAttached === 'true')
281
+ return;
282
+ cancelBtn.addEventListener('click', () => {
283
+ console.log('Cancel button clicked');
284
+ // Close the modal
285
+ const modal = document.getElementById('at-screen-share-request-modal');
286
+ if (modal) {
287
+ modal.close();
288
+ modal.remove();
289
+ }
290
+ // Reset display component state if needed
291
+ _onDisplayComponent = null;
292
+ });
293
+ cancelBtn.dataset.listenerAttached = 'true';
294
+ }
295
+ export function handleModalLeaveButton(isHost) {
296
+ const leaveBtn = document.getElementById('at-screen-share-leave-confirmation-leave-btn');
297
+ if (!leaveBtn)
298
+ return;
299
+ // Check if listener already exists
300
+ if (leaveBtn.dataset.listenerAttached === 'true')
301
+ return;
302
+ leaveBtn.addEventListener('click', () => {
303
+ console.log('Leave button clicked');
304
+ // Close the modal first
305
+ const modal = document.getElementById('at-screen-share-request-modal');
306
+ if (modal) {
307
+ modal.close();
308
+ modal.remove();
309
+ }
310
+ if (isHost) {
311
+ // execute leave session logic
312
+ removeScreenShareSessionData();
313
+ recreateUserListContainer();
314
+ renderUsersList(_screenShareUsers);
315
+ dispatchSpaceEvent(SPACE_EVENTS.SCREEN_SHARE_HOST_END_SESSION, handleScreenShareEndSessionEvent);
316
+ }
317
+ else {
318
+ dispatchSpaceEvent(SPACE_EVENTS.SCREEN_SHARE_GUEST_LEAVE_SESSION, _screenSharingHostUser);
319
+ }
320
+ // Reset display component state
321
+ _onDisplayComponent = null;
322
+ });
323
+ leaveBtn.dataset.listenerAttached = 'true';
273
324
  }
274
325
  export function handleInputEventSelectPointerSettings() {
275
326
  const select = document.getElementById('at_select_screen_share_pointer');
@@ -284,15 +335,16 @@ export function handleInputEventSelectPointerSettings() {
284
335
  }
285
336
  export function handleClickEventEndSessionBtn() {
286
337
  const button = document.getElementById('at-screen-share-end-session-btn');
287
- if (button) {
288
- button.addEventListener('click', () => {
289
- // internal logic end session
290
- removeScreenShareSessionData();
291
- recreateUserListContainer();
292
- renderUsersList(_screenShareUsers);
293
- dispatchSpaceEvent(SPACE_EVENTS.SCREEN_SHARE_END_SESSION, handleScreenShareEndSessionEvent);
294
- });
295
- }
338
+ if (!button)
339
+ return;
340
+ // check if listener already exists by looking for our marker
341
+ if (button.dataset.listenerAttached === 'true')
342
+ return;
343
+ button.addEventListener('click', () => {
344
+ renderScreenShareLeaveConfirmationModal(true);
345
+ });
346
+ // mark that listener is attached
347
+ button.dataset.listenerAttached = 'true';
296
348
  }
297
349
  export function handleScreenShareUsersUpdated(payload) {
298
350
  _spaceData = payload.space_data;
@@ -25,7 +25,7 @@ export function renderSpaceUserListPane() {
25
25
  id="at-user-pane-end-session-btn"
26
26
  data-cy="at-user-pane-end-session-btn"
27
27
  target-pane="at-add-object-pane">
28
- ${i18n.t('End Session')}
28
+ ${i18n.t('EndSession')}
29
29
  </div>
30
30
  </div>
31
31
 
@@ -7,7 +7,7 @@ export function renderViewingRemoteSpace() {
7
7
  element.setAttribute('data-cy', 'at-viewing-remote-space-pane');
8
8
  element.innerHTML = `
9
9
  <div class="at_panel_header">
10
- <span>${i18n.t('Viewing Remote Space')}</span>
10
+ <span>${i18n.t('ViewingRemoteSpace')}</span>
11
11
  </div>
12
12
 
13
13
  <div id="at-sharing-user-container" >
@@ -15,10 +15,10 @@ export function renderViewingRemoteSpace() {
15
15
 
16
16
  <div class="at_button_row at_justify_center">
17
17
  <div
18
- class="at_button at_ghost at_bg_red_600 at_w-full"
18
+ class="at_button at_ghost at_w-full"
19
19
  id="at-user-leave-session-btn"
20
20
  data-cy="at-user-leave-session-btn">
21
- ${i18n.t('Leave Session')}
21
+ ${i18n.t('LeaveSession')}
22
22
  </div>
23
23
  </div>
24
24
  `;
@@ -55,7 +55,7 @@ export function renderRemoteSpaceViewing(user) {
55
55
  const statusText = document.createElement('div');
56
56
  statusText.className = 'at_text_sm at_text_white';
57
57
  statusText.innerHTML = `
58
- ${i18n.t('Is sharing their space')} ${(_currentSpace === null || _currentSpace === void 0 ? void 0 : _currentSpace.name) || i18n.t('SPACE_NAME')} ${i18n.t('to you')}
58
+ ${i18n.t('IsSharingTheirSpace')} ${(_currentSpace === null || _currentSpace === void 0 ? void 0 : _currentSpace.name) || i18n.t('SPACE_NAME')} ${i18n.t('ToYou')}
59
59
  `;
60
60
  infoWrapper.appendChild(userNameEl);
61
61
  infoWrapper.appendChild(statusText);
@@ -77,6 +77,6 @@ export function renderRemoteSpaceViewing(user) {
77
77
  // === Instructional Text ===
78
78
  const instruction = document.createElement('div');
79
79
  instruction.className = 'at_text_xs at_text_center at_text_white at_opacity_80 at_mb_6';
80
- instruction.textContent = i18n.t('During a remote space sharing session, you cannot navigate around the space, only your host has control during the session');
80
+ instruction.textContent = i18n.t('ViewingInstructions');
81
81
  container.appendChild(instruction);
82
82
  }
@@ -20,6 +20,7 @@ declare function batchAddEventListenerById(ids: Array<string>, callback: EventLi
20
20
  declare function setActiveToolbarItem(itemId: string): void;
21
21
  declare function toggleDisplayPane(targetId: string): Promise<void>;
22
22
  declare function toggleActionBar(state: string): void;
23
+ export declare function handleUserLeaveSessionClick(): void;
23
24
  declare function setupIndividualEventListeners(): void;
24
25
  declare function handleModelVisibility(objId: string): Promise<void>;
25
26
  declare function handleDeleteModel(objId: string): Promise<void>;