Skip to content

Instantly share code, notes, and snippets.

@x8BitRain
Last active March 29, 2024 11:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save x8BitRain/030a654ccc70588e8482c195d0f0cdcd to your computer and use it in GitHub Desktop.
Save x8BitRain/030a654ccc70588e8482c195d0f0cdcd to your computer and use it in GitHub Desktop.
<template>
<div class="notifications" :style="notificationStyle">
<div class="notifications__top">
<TransitionGroup name="notificationViewFade">
<LoadSavedPlanNotification
v-if="notificationState[NOTIFICATION_TYPES.LOAD_IDB_CONFIG]?.open"
:payload="
notificationState[NOTIFICATION_TYPES.LOAD_IDB_CONFIG].payload!
"
:close="() => close(NOTIFICATION_TYPES.LOAD_IDB_CONFIG)"
:data-test-id="NOTIFICATION_TYPES.LOAD_IDB_CONFIG"
/>
</TransitionGroup>
</div>
<div class="spacer"></div>
<div class="notifications__bottom">
<TransitionGroup name="notificationViewFade">
<FirstPersonControlsNotification
v-if="
notificationState[NOTIFICATION_TYPES.FIRST_PERSON_CONTROLS]?.open
"
:payload="
notificationState[NOTIFICATION_TYPES.FIRST_PERSON_CONTROLS].payload!
"
:close="() => close(NOTIFICATION_TYPES.FIRST_PERSON_CONTROLS)"
:data-test-id="NOTIFICATION_TYPES.FIRST_PERSON_CONTROLS"
/>
</TransitionGroup>
</div>
</div>
</template>
<script setup lang="ts">
import LoadSavedPlanNotification from '@/common/components/notifications/LoadSavedPlanNotification.vue';
import { useStore } from 'vuex';
import type { StoreState } from '@/common/store';
import {
NOTIFICATION_SHOW_TIMEOUTS,
NOTIFICATION_TYPES,
type NotificationData,
type NotificationsStore,
} from '@/common/components/utils/-utils/notifications';
import { computed, ref } from 'vue';
import {
SDK_TO_UI_EVENTS,
useSDKEventEmitterListener,
} from '@/common/composables/use-sdk-event-emitter-listener';
import { COMMON_UI_STATE_MUTATIONS } from '@/common/store/common-ui-state';
import FirstPersonControlsNotification from '@/common/components/notifications/FirstPersonControlsNotification.vue';
import type { Enumify } from '@/common/utils/types';
// Dependencies
const store = useStore<StoreState>();
// Data
const notificationState = ref<NotificationsStore>({
[NOTIFICATION_TYPES.LOAD_IDB_CONFIG]: {
open: true,
},
[NOTIFICATION_TYPES.FIRST_PERSON_CONTROLS]: {
open: true,
showMs: NOTIFICATION_SHOW_TIMEOUTS.MEDIUM,
},
});
// Listeners
useSDKEventEmitterListener(
SDK_TO_UI_EVENTS.SET_NOTIFICATION_STATE,
(notificationStateData): void =>
setNotificationState(notificationStateData as NotificationData),
);
// Computed
const notificationStyle = computed(() => {
const { isDesktop, isPlanner } = store.state.uiState;
const { isFullscreen, interactionsExpanded } = store.state.plannerUiState;
const noInteractions = isFullscreen || !interactionsExpanded;
let top;
let bottom;
if (isDesktop) {
top = isPlanner ? '9rem' : '11rem';
if (noInteractions) {
bottom = isPlanner ? '12rem' : '17rem';
} else {
bottom = isPlanner ? '16rem' : '16rem';
}
} else {
top = isPlanner ? '9rem' : '9rem';
if (noInteractions) {
bottom = '9rem';
} else {
bottom = isPlanner ? '19rem' : '19rem';
}
}
return {
width: noInteractions ? '100%' : 'calc(100% - 30rem)',
'grid-template-rows': `${top} auto ${bottom}`,
};
});
// Methods
const setNotificationVisibleState = () => {
const hasOpenNotification = Object.values(notificationState.value).some(
(notification) => notification.open,
);
store.commit(
COMMON_UI_STATE_MUTATIONS.SET_NOTIFICATION_VISIBLE,
hasOpenNotification,
);
};
const setNotificationState = (notificationStateData: NotificationData) => {
const key = (notificationStateData as NotificationData)?.notification;
Object.assign(notificationState.value[key!], notificationStateData);
setNotificationVisibleState();
if (notificationStateData.showMs && key) {
startHideTimer(notificationStateData.showMs, key);
}
};
const close = (type: keyof NotificationsStore) => {
notificationState.value[type].open = false;
setNotificationVisibleState();
};
const startHideTimer = (
time: number,
key: Enumify<typeof NOTIFICATION_TYPES>,
) => {
setTimeout(() => {
close(key);
}, time);
};
</script>
<style scoped lang="scss">
@import '@/configurator/components/utils/-utils/InteractionContainer.module.scss';
@import '@/common/components/collection-view/-utils/CollectionView.helper';
@import '@/common/styles/variables';
@import '@/common/styles/mixins';
@import '@/common/styles/notifications';
.notifications {
display: grid;
grid-auto-columns: 1fr;
grid-auto-rows: 1fr;
grid-template-columns: 1fr;
grid-template-rows: 8rem auto 8rem;
gap: 0;
grid-template-areas:
'.'
'.'
'.';
width: 100%;
position: absolute;
top: 0;
left: 0;
transition: width 0.7s;
height: 100%;
z-index: 500;
pointer-events: none;
@include desktop {
width: calc(100% - $interaction_desktop_width);
}
}
.spacer {
height: 100%;
}
.notifications__top,
.notifications__bottom {
display: flex;
width: 100%;
justify-content: center;
}
.notifications__top {
align-items: end;
}
.notifications__bottom {
align-items: start;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment