architwin 1.0.87 → 1.0.88

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.
package/README.md CHANGED
@@ -311,6 +311,8 @@ Or programmatically using methods defined in this library.
311
311
 
312
312
  ## Executing methods on specific App Phases
313
313
 
314
+ **WARNING:** This feature is deprecated, subscribe using [Space Events](#subscribing-to-space-events) instead
315
+
314
316
  Your application may need to execute certain methods during the initialization of your 3D space. For example, you may want to use`addObjectToSpace()` method to render a model to your 3D space the moment the 3D space becomes interactive. While you can always just invoke the function after the `connectSpace()` method there may be times where this will cause an error as the `connectSpace()` method which is an async method, may have not finished initializing the necessary internal variables that allow other methods to work properly. When you invoke the `connectSpace()` method, the library does some internal validation and then goes to several phases to render your 3D space and make it interactive. These phases are the following:
315
317
 
316
318
  **ARCHTWIN APP PHASES**
@@ -323,7 +325,7 @@ You can also view the technical diagram of how this work below:
323
325
 
324
326
  <img src="https://drive.google.com/uc?id=1I_NuuI_PWkRzB0DueCmBCBH-1V_upiOB" width="400" height="300" />
325
327
 
326
- To invoke a function from your application during one of the phases. Simple pass the function name as a parameter in the `connectSpace()` method. Make sure to not add a parenthesis to your function name when you pass it as a parameter to avoid invoking the function prematurely.
328
+ To invoke a function from your application during one of the phases. Simply pass the function name as a parameter in the `connectSpace()` method. Make sure to not add a parenthesis to your function name when you pass it as a parameter to avoid invoking the function prematurely.
327
329
 
328
330
  *Example:*
329
331
 
@@ -1875,6 +1877,20 @@ atwin.setVideoPlayback('play', randomMediaScreen.component.planeElement)
1875
1877
 
1876
1878
  You can use the [transform controls](#transforming-objects) to change the position, scale, and rotation of the media screen using the mouse cursor.
1877
1879
 
1880
+ #### Hiding expand/dock buttons of Media Screens
1881
+
1882
+ Media screens by default will display a dock button on each corner of the displayed media that allows you to dock the media screen in the 4 corners of your FOV inside a space. To hide these buttons, you may add the following in your config object.
1883
+
1884
+ ```typescript
1885
+ const config = {
1886
+ //other configs
1887
+ mediaScreenConfig: {
1888
+ showExpandButton: false
1889
+ }
1890
+ }
1891
+
1892
+ ```
1893
+
1878
1894
  ### Setting Video Playback in the Space
1879
1895
 
1880
1896
  Setting video playback refers to the act of adjusting various controls associated with the playback of a video in the space. It involves manipulating controls such as pause, play, mute, and unmute to modify the playback behavior according to user's preferences.
@@ -45,7 +45,10 @@ i18n
45
45
  "ScreenshotSaved": "Screenshot saved to downloads folder",
46
46
  "SuccessCopyTagLink": "Successfully copied tag link to clipboard",
47
47
  "NoMessages": "No messages",
48
- "AddObject": "Add Object"
48
+ "AddObject": "Add Object",
49
+ "ConfirmDeleteTag": "Are you sure you want to delete this tag? This action cannot be reversed",
50
+ "DeleteTag": "Delete Tag",
51
+ "YesDelete": "Yes, delete"
49
52
  }
50
53
  },
51
54
  ja: {
@@ -85,7 +88,10 @@ i18n
85
88
  "ScreenshotSaved": "スクショをダウンロードフォルダに保存しました",
86
89
  "SuccessCopyTagLink": "タグURLをクリップボードに保存しました",
87
90
  "NoMessages": "メッセージがありません",
88
- "AddObject": "追加"
91
+ "AddObject": "追加",
92
+ "ConfirmDeleteTag": "この操作は取り消すことができません。このタグを削除しますか?",
93
+ "DeleteTag": "タグ削除",
94
+ "YesDelete": "削除"
89
95
  }
90
96
  }
91
97
  },
@@ -9,7 +9,8 @@ import { setActiveThemeCard } from "./themePane";
9
9
  import { setActiveCard, setActiveLibraryCard, clearActiveCard, clearActiveLibraryCard } from "./card";
10
10
  import { renderRecepientOptions, renderTagMessages, createTagMessage, setTagMessagingDetails } from "./tagMessagingPane";
11
11
  import { clearTagFormDropdown } from "./tagFormPane";
12
+ import { toggleModal } from "./modal";
12
13
  import './i18n';
13
14
  declare let actionBar: HTMLElement;
14
15
  declare function renderToolbarUI(payload: IToolbarData): void;
15
- export { actionBar, tagFormMode, selectedTag, renderToolbarUI, renderObjectCards, setActiveMenu, clearActiveMenu, setActiveActionBtn, renderLibraryCards, renderTags, getTagFormData, renderTagRow, addClickEventToTagRow, setTagCategoriesOption, setActiveThemeCard, setActiveCard, setActiveLibraryCard, clearActiveCard, clearActiveLibraryCard, removeObjectCard, renderRecepientOptions, renderTagMessages, createTagMessage, renderCategoryDropdownOptions, toggleDropdown, setTagLink, getTagLink, setTagMessagingDetails, clearTagFormDropdown, getObjectListStatus };
16
+ export { actionBar, tagFormMode, selectedTag, renderToolbarUI, renderObjectCards, setActiveMenu, clearActiveMenu, setActiveActionBtn, renderLibraryCards, renderTags, getTagFormData, renderTagRow, addClickEventToTagRow, setTagCategoriesOption, setActiveThemeCard, setActiveCard, setActiveLibraryCard, clearActiveCard, clearActiveLibraryCard, removeObjectCard, renderRecepientOptions, renderTagMessages, createTagMessage, renderCategoryDropdownOptions, toggleDropdown, setTagLink, getTagLink, setTagMessagingDetails, clearTagFormDropdown, getObjectListStatus, toggleModal };
@@ -13,6 +13,7 @@ import { renderThemePane, setActiveThemeCard } from "./themePane";
13
13
  import { setActiveCard, setActiveLibraryCard, clearActiveCard, clearActiveLibraryCard } from "./card";
14
14
  import { renderRecepientOptions, renderTagMessages, createTagMessage, setTagMessagingDetails } from "./tagMessagingPane";
15
15
  import { clearTagFormDropdown } from "./tagFormPane";
16
+ import { renderModal, toggleModal } from "./modal";
16
17
  import { getURLParams } from "../../../utils";
17
18
  import './i18n';
18
19
  import i18n from './i18n';
@@ -71,6 +72,7 @@ function renderToolbarUI(payload) {
71
72
  libraryPane = renderLibraryPane();
72
73
  tagMessagingPane = renderTagMessagingPane();
73
74
  themePane = renderThemePane();
75
+ renderModal();
74
76
  sidebarContainer.appendChild(actionBar);
75
77
  sidebarContainer.appendChild(themePane);
76
78
  sidebarContainer.appendChild(tagMessagingPane);
@@ -93,4 +95,4 @@ function renderToolbarUI(payload) {
93
95
  tagMessagingPane.style.display = 'none';
94
96
  themePane.style.display = 'none';
95
97
  }
96
- export { actionBar, tagFormMode, selectedTag, renderToolbarUI, renderObjectCards, setActiveMenu, clearActiveMenu, setActiveActionBtn, renderLibraryCards, renderTags, getTagFormData, renderTagRow, addClickEventToTagRow, setTagCategoriesOption, setActiveThemeCard, setActiveCard, setActiveLibraryCard, clearActiveCard, clearActiveLibraryCard, removeObjectCard, renderRecepientOptions, renderTagMessages, createTagMessage, renderCategoryDropdownOptions, toggleDropdown, setTagLink, getTagLink, setTagMessagingDetails, clearTagFormDropdown, getObjectListStatus };
98
+ export { actionBar, tagFormMode, selectedTag, renderToolbarUI, renderObjectCards, setActiveMenu, clearActiveMenu, setActiveActionBtn, renderLibraryCards, renderTags, getTagFormData, renderTagRow, addClickEventToTagRow, setTagCategoriesOption, setActiveThemeCard, setActiveCard, setActiveLibraryCard, clearActiveCard, clearActiveLibraryCard, removeObjectCard, renderRecepientOptions, renderTagMessages, createTagMessage, renderCategoryDropdownOptions, toggleDropdown, setTagLink, getTagLink, setTagMessagingDetails, clearTagFormDropdown, getObjectListStatus, toggleModal };
@@ -0,0 +1,4 @@
1
+ export declare let activeModal: boolean;
2
+ export declare function renderModal(): void;
3
+ export declare function toggleModal(visible?: boolean): void;
4
+ export declare function setModalAction(label: string, callback: Function): Promise<void>;
@@ -0,0 +1,68 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import i18n from './i18n';
11
+ export let activeModal = false;
12
+ export function renderModal() {
13
+ const element = document.createElement('div');
14
+ element.setAttribute('id', 'at-modal-overlay');
15
+ element.setAttribute('data-cy', 'at-modal-overlay');
16
+ element.innerHTML = `
17
+ <div class="at_modal">
18
+ <div>
19
+ <div class="at_modal-close-button at_close-icon">&times;</div>
20
+ </div>
21
+ <div class="at_modal-content">
22
+ <h2 class="at_modal-content-heading" id="at-modal-content-heading">${i18n.t('DeleteTag')}</h2>
23
+ <p class="at_modal-content-subheading" id="at-modal-content-subheading">
24
+ ${i18n.t('ConfirmDeleteTag')}
25
+ </p>
26
+ <div>
27
+ <button class="at_close-button at_modal-accept-button">${i18n.t('YesDelete')}</button>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ `;
32
+ document.body.appendChild(element);
33
+ const modalOverlay = document.getElementById('at-modal-overlay');
34
+ const modalClose = document.querySelector('.at_modal-close-button');
35
+ if (modalClose) {
36
+ modalClose.addEventListener('click', (event) => {
37
+ modalOverlay.style.display = 'none';
38
+ });
39
+ }
40
+ }
41
+ export function toggleModal(visible = true) {
42
+ const modalOverlay = document.getElementById('at-modal-overlay');
43
+ if (!modalOverlay) {
44
+ console.error("Modal overly is undefined");
45
+ return;
46
+ }
47
+ if (visible) {
48
+ modalOverlay.style.display = 'block';
49
+ return;
50
+ }
51
+ modalOverlay.style.display = 'none';
52
+ return;
53
+ }
54
+ export function setModalAction(label, callback) {
55
+ return __awaiter(this, void 0, void 0, function* () {
56
+ const modalAcceptBtn = document.querySelector('.at_modal-accept-button');
57
+ if (modalAcceptBtn) {
58
+ if (label) {
59
+ modalAcceptBtn.textContent = label;
60
+ }
61
+ if (callback) {
62
+ modalAcceptBtn.onclick = () => __awaiter(this, void 0, void 0, function* () {
63
+ yield callback();
64
+ });
65
+ }
66
+ }
67
+ });
68
+ }
@@ -12,6 +12,7 @@ import { batchAddEventListenerByClassName, toggleDisplayPane } from "../../event
12
12
  import { convertToCssRgb } from "../../../utils";
13
13
  import { gotoTag, disposeTag, dispatchSpaceEvent, _tags, getUserAssignedCategories } from "../../../architwin";
14
14
  import { initFormData, toggleDropdown } from "./tagFormPane";
15
+ import { toggleModal, setModalAction } from "./modal";
15
16
  import { Notyf } from 'notyf';
16
17
  import { _tagCategories } from "../../../architwin";
17
18
  import i18n from './i18n';
@@ -177,20 +178,25 @@ export function renderTags(tags, showOwnTagsOnly = false) {
177
178
  //@ts-ignore
178
179
  const tag = document.getElementById(event.target.id);
179
180
  if (tag) {
180
- const tagId = tag.getAttribute('tag-id');
181
- if (tagId && tagId !== null) {
182
- console.log("TAG DELETE", tagId, _tags);
183
- const targetTag = _tags.find(tag => tag.json_data.id.toString() == tagId);
184
- yield disposeTag({ tagId: tagId });
185
- const tagRow = document.getElementById(`at-tag-row-${tagId}`);
186
- tagRow.remove();
187
- const payload = { tag: targetTag };
188
- dispatchSpaceEvent(SPACE_EVENTS.TAG_DISPOSED, payload);
189
- notify.success("Successfully deleted tag");
190
- }
191
- else {
192
- notify.error("Tag id not found!");
193
- }
181
+ toggleModal();
182
+ setModalAction('Yes, delete', () => __awaiter(this, void 0, void 0, function* () {
183
+ const tagId = tag.getAttribute('tag-id');
184
+ if (tagId && tagId !== null) {
185
+ console.log("TAG DELETE", tagId, _tags);
186
+ const targetTag = _tags.find(tag => tag.json_data.id.toString() == tagId);
187
+ yield disposeTag({ tagId: tagId });
188
+ const tagRow = document.getElementById(`at-tag-row-${tagId}`);
189
+ tagRow.remove();
190
+ const payload = { tag: targetTag };
191
+ dispatchSpaceEvent(SPACE_EVENTS.TAG_DISPOSED, payload);
192
+ toggleModal(false);
193
+ notify.success("Successfully deleted tag");
194
+ }
195
+ else {
196
+ toggleModal(false);
197
+ notify.error("Tag id not found!");
198
+ }
199
+ }));
194
200
  }
195
201
  }));
196
202
  batchAddEventListenerByClassName('at_tag_row', (event) => __awaiter(this, void 0, void 0, function* () {
@@ -20,7 +20,7 @@ export function renderTagMessagingPane() {
20
20
  element.innerHTML = `
21
21
  <div class="at_panel_header">
22
22
  <div class="at_button_row at_justify_between">
23
- <div>
23
+ <div class="at_grouped_center">
24
24
  <div class="at_colored-indicator" id="at-tag-color-messaging" style="background-color:rgb(0,0,0)"></div>
25
25
  <span id='at-tag-name-messaging'>${i18n.t('TagName')}</span>
26
26
  </div>
@@ -752,6 +752,7 @@ function handleViewTagMessage(payload) {
752
752
  const eventId = "at-message-tag-" + payload;
753
753
  console.log("eventId: ", eventId);
754
754
  yield toggleDisplayPane('at-expand-btn');
755
+ setActiveMenu('at-expand-btn');
755
756
  yield toggleDisplayPane(eventId);
756
757
  }
757
758
  catch (error) {
@@ -26,7 +26,7 @@ class PlaneImage {
26
26
  type: '',
27
27
  url: null,
28
28
  visible: true,
29
- isFirstLoad: true,
29
+ isFirstLoad: true
30
30
  };
31
31
  this.events = {
32
32
  'INTERACTION.CLICK': true,
@@ -83,7 +83,16 @@ class PlaneImage {
83
83
  side: THREE.DoubleSide,
84
84
  });
85
85
  this.mesh = new THREE.Mesh(geometry, material);
86
- _screenPositions.forEach(i => createExpandModel(this.context, this.mesh, i, this.expandBtnPositions));
86
+ if (_mpConfig && _mpConfig.mediaScreenConfig && _mpConfig.mediaScreenConfig.showExpandButton !== undefined) {
87
+ if (_mpConfig.mediaScreenConfig.showExpandButton) {
88
+ console.log("Mediascreen expand button is enabled");
89
+ _screenPositions.forEach(i => createExpandModel(this.context, this.mesh, i, this.expandBtnPositions));
90
+ }
91
+ }
92
+ else {
93
+ console.log("Mediascreen expand button is enabled");
94
+ _screenPositions.forEach(i => createExpandModel(this.context, this.mesh, i, this.expandBtnPositions));
95
+ }
87
96
  createDismissExpandModel(this.context, this.mesh, this.dismissExpandBtnPosition);
88
97
  this.renderFitScreenModel();
89
98
  this.mesh.name = this.inputs.name;
@@ -272,8 +281,16 @@ class PlaneVideo {
272
281
  this.playButtonModel.visible = true;
273
282
  this.pauseButtonModel.visible = false;
274
283
  });
275
- _screenPositions.forEach(i => createExpandModel(this.context, this.mesh, i, this.expandBtnPositions));
276
- createDismissExpandModel(this.context, this.mesh, this.dismissExpandBtnPosition);
284
+ if (_mpConfig && _mpConfig.mediaScreenConfig && _mpConfig.mediaScreenConfig.showExpandButton !== undefined) {
285
+ if (_mpConfig.mediaScreenConfig.showExpandButton) {
286
+ _screenPositions.forEach(i => createExpandModel(this.context, this.mesh, i, this.expandBtnPositions));
287
+ createDismissExpandModel(this.context, this.mesh, this.dismissExpandBtnPosition);
288
+ }
289
+ }
290
+ else {
291
+ _screenPositions.forEach(i => createExpandModel(this.context, this.mesh, i, this.expandBtnPositions));
292
+ createDismissExpandModel(this.context, this.mesh, this.dismissExpandBtnPosition);
293
+ }
277
294
  this.mesh.name = this.inputs.name;
278
295
  // add mesh to scene
279
296
  this.outputs.objectRoot = this.mesh;
package/lib/types.d.ts CHANGED
@@ -561,6 +561,7 @@ export interface ISharedScreen {
561
561
  width?: number;
562
562
  height?: number;
563
563
  otherData?: any;
564
+ showExpandButton?: boolean;
564
565
  }
565
566
  export interface SpaceAvatar {
566
567
  id?: number;
@@ -832,6 +833,12 @@ export interface TagMessage {
832
833
  created_on?: any;
833
834
  modified_on?: any;
834
835
  }
836
+ export interface ModalContent {
837
+ title: string;
838
+ subtitle: string | undefined;
839
+ content: HTMLElement | undefined;
840
+ action: HTMLElement | undefined;
841
+ }
835
842
  export declare const enum IO_PARTICIPANT_COLORS {
836
843
  GREEN = "GREEN",
837
844
  BLUE = "BLUE",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "architwin",
3
- "version": "1.0.87",
3
+ "version": "1.0.88",
4
4
  "description": "ArchiTwin Library for Matterport",
5
5
  "main": "./lib/architwin.js",
6
6
  "types": "./lib/architwin.d.ts",
@@ -257,14 +257,20 @@
257
257
  .at_panel_header {
258
258
  text-align: right;
259
259
  font-size: larger;
260
- width: 100%;
260
+ /* width: 100%; */
261
261
  color: var(--text-color-light);
262
- padding: .4em .2em;
262
+ padding: .0em .2em;
263
263
  border-bottom: solid 1px white;
264
264
  margin: .2em;
265
265
  max-height: 2.5em;
266
266
  }
267
267
 
268
+ .at_grouped_center {
269
+ display: flex;
270
+ flex-direction: row;
271
+ align-items: center;
272
+ }
273
+
268
274
  .at_scrollable_container table {
269
275
  width: 100%;
270
276
  }
@@ -296,6 +302,7 @@
296
302
  border-radius: 50%;
297
303
  border: solid black 1px;
298
304
  display: inline-block;
305
+ margin-right: 0.5em;
299
306
  }
300
307
 
301
308
  .at_table_button_row {
@@ -305,6 +312,7 @@
305
312
  justify-content: space-between;
306
313
  align-items: auto;
307
314
  align-content: start;
315
+ margin-right: 0.5em;
308
316
  }
309
317
 
310
318
  /*Form Classes*/
@@ -386,8 +394,9 @@
386
394
  border: 0;
387
395
  font-weight: bolder;
388
396
  color: white;
389
- padding: 8px 6px;
390
- margin-top: 4px;
397
+ padding: /*8px*/ 0px 6px;
398
+ /* margin-top: 4px; */
399
+ margin-bottom: 2px;
391
400
  border-radius: var(--border-radius);
392
401
  border-bottom: solid white 2px;
393
402
  }
@@ -739,7 +748,7 @@
739
748
  .at_chat_bubble {
740
749
  display: flex;
741
750
  max-width: 70%;
742
- margin: 10px;
751
+ margin: 2px 10px 10px 10px;
743
752
  padding: 10px;
744
753
  border-radius: 15px;
745
754
  word-wrap: break-word; /* Wrap long words */
@@ -805,4 +814,108 @@
805
814
  .at_send_chat_button:hover {
806
815
  background-color: var(--bg-accent);
807
816
  color: var(--text-color-light);
808
- }
817
+ }
818
+
819
+ /* MODAL CLASSES */
820
+
821
+ #at-modal-overlay {
822
+ display: none;
823
+ position: fixed;
824
+ top: 0;
825
+ left: 0;
826
+ width: 100%;
827
+ height: 100%;
828
+ background: rgba(0,0,0,0.8);
829
+ animation: slide-down 0.3s ease;
830
+ animation-fill-mode: forwards;
831
+ transform: translateY(-100%);
832
+ }
833
+
834
+ @keyframes slide-down {
835
+ from {
836
+ transform: translateY(-100%);
837
+ }
838
+ to {
839
+ transform: translateY(0);
840
+ }
841
+ }
842
+
843
+ .at_modal {
844
+ max-width: 480px;
845
+ height: 260px;
846
+ max-height: 300px;
847
+ margin: 200px auto;
848
+ background-color: #ffff;
849
+ border-radius: 5px;
850
+ padding: 0rem 1rem;
851
+ animation:scale-up-center .4s cubic-bezier(.39,.575,.565,1.000) both
852
+ }
853
+
854
+ @keyframes scale-up-center {
855
+ 0% {
856
+ transform: scale(.5)
857
+ }
858
+ 100% {
859
+ transform: scale(1)
860
+ }
861
+ }
862
+
863
+ .at_close-icon {
864
+ font-size: 2rem;
865
+ text-align: right;
866
+ cursor: pointer;
867
+ }
868
+
869
+ .at_modal-content {
870
+ text-align: center;
871
+ padding-top: 10px;
872
+ }
873
+
874
+ .at_modal-content-heading {
875
+ font-size: 2rem;
876
+ font-weight: bolder;
877
+ margin-top: 0;
878
+ }
879
+
880
+ .at_modal-content-subheading {
881
+ font-size: 1.2rem;
882
+ line-height: 1.5;
883
+ padding: 8px;
884
+ }
885
+
886
+ .at_close-button,
887
+ .at_open-modal-btn {
888
+ background-color: #d51a4c;
889
+ color: #ffff;
890
+ border-radius: 3px;
891
+ cursor: pointer;
892
+ font-size: 1.2rem;
893
+ padding: 8px 1rem;
894
+ margin-top: 1rem;
895
+ outline: none;
896
+ border: none;
897
+ text-transform: uppercase;
898
+ font-weight: 600;
899
+ }
900
+
901
+ .at_close-button:hover {
902
+ background-color: #c73259;
903
+ outline: #fff;
904
+ }
905
+
906
+ .at_open-modal-btn:hover,
907
+ .at_open-modal-btn:focus{
908
+ background-color: #ffff;
909
+ color: #4E56EE;
910
+ border: 1px solid #4E56EE;
911
+ }
912
+
913
+ @media screen and (max-width: 540px) {
914
+
915
+ .at_modal {
916
+ max-width: 300px;
917
+ height: 320px;
918
+ padding: 0rem 1rem;
919
+ }
920
+
921
+ }