mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 02:44:02 +00:00
feat(scenes): render the data-pack attribution cards from a store
The data-pack presentations keep the Cesium resources, object URLs and pick targets and present each pack's attribution card, with its media player, to the gev-data-packs store; the DataPacks view teleports one panel per set of presentations into the viewer's container with the same markup and inline styles, and stops a removed card's player as it goes.
This commit is contained in:
1 parent
59e3aaa271
commit
e0abf74308
8 files changed
+290
-69
No files matched your search
@@ -0,0 +1,34 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { markRaw, shallowRef } from 'vue';
|
||||
|
||||
/**
|
||||
* The loaded data packs' attribution cards as their view renders them. Each
|
||||
* set of data-pack presentations (src/scenes/dataPacks/presentation.js)
|
||||
* presents its own panel, with a card for each pack and its media player
|
||||
* when the pack is media.
|
||||
*/
|
||||
export const useDataPacksStore = defineStore('gev-data-packs', () => {
|
||||
/**
|
||||
* `[{owner, key, container, cards: [{key, id, title, url, media}]}]`, one
|
||||
* per owner showing cards. `container` is the element the panel sits in;
|
||||
* `media` is `{kind: 'video'|'audio', src}` or null.
|
||||
*/
|
||||
const panels = shallowRef([]);
|
||||
|
||||
/**
|
||||
* @param {object} owner The presentations publishing.
|
||||
* @param {?object} panel Their fresh panel, or null to remove it.
|
||||
*/
|
||||
function publish(owner, panel) {
|
||||
const index = panels.value.findIndex((item) => item.owner === owner);
|
||||
const next = panels.value.slice();
|
||||
if (!panel) {
|
||||
if (index < 0) return;
|
||||
next.splice(index, 1);
|
||||
} else if (index < 0) next.push(markRaw({ ...panel, owner }));
|
||||
else next[index] = markRaw({ ...panel, owner });
|
||||
panels.value = next;
|
||||
}
|
||||
|
||||
return { panels, publish };
|
||||
});
|
||||
@@ -6,6 +6,7 @@ import { useLocationStore } from '../stores/location.js';
|
||||
import { useStatusStore } from '../stores/status.js';
|
||||
import { vClassToggle } from '../rail/classToggle.js';
|
||||
import ImagerySplitView from './panels/ImagerySplitView.vue';
|
||||
import DataPacks from './panels/DataPacks.vue';
|
||||
import SceneInteractions from './panels/SceneInteractions.vue';
|
||||
import SplitFlapText from './panels/SplitFlapText.vue';
|
||||
|
||||
@@ -96,5 +97,6 @@ const vToastText = {
|
||||
</Teleport>
|
||||
|
||||
<ImagerySplitView />
|
||||
<DataPacks />
|
||||
<SceneInteractions />
|
||||
</template>
|
||||
@@ -0,0 +1,45 @@
|
||||
<script setup>
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { t } from '../../../i18n/index.js';
|
||||
import { useDataPacksStore } from '../../stores/dataPacks.js';
|
||||
|
||||
// The loaded data packs' attribution cards, one panel per set of data-pack
|
||||
// presentations (src/scenes/dataPacks/presentation.js), inside the viewer's
|
||||
// container.
|
||||
const { panels } = storeToRefs(useDataPacksStore());
|
||||
|
||||
const panelStyle = {
|
||||
position: 'absolute',
|
||||
right: '10px',
|
||||
bottom: '70px',
|
||||
maxHeight: '40vh',
|
||||
overflowY: 'auto',
|
||||
zIndex: '30',
|
||||
};
|
||||
const cardStyle = {
|
||||
color: '#e3faff',
|
||||
background: '#08141eed',
|
||||
border: '1px solid #2491a8',
|
||||
padding: '8px',
|
||||
margin: '4px',
|
||||
maxWidth: '260px',
|
||||
font: '12px sans-serif',
|
||||
};
|
||||
|
||||
// A removed player stops and lets go of its media, which a detached
|
||||
// element would otherwise keep playing. This runs as Vue renders the
|
||||
// removal, in the same task as the dispose that removed it.
|
||||
const vPackMedia = {
|
||||
beforeUnmount(el) {
|
||||
el.pause();
|
||||
el.removeAttribute('src');
|
||||
el.load();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Teleport v-for="panel in panels" :key="panel.key" :to="panel.container">
|
||||
<div data-director-packs="" :style="panelStyle"><section v-for="card in panel.cards" :key="card.key" :data-director-pack="card.id" :style="cardStyle"><div>{{ card.title }}</div><a v-if="card.url" :href="card.url" target="_blank" rel="noopener noreferrer" style="color: #6eeaff">{{ t('Source') }}</a><video v-if="card.media?.kind === 'video'" v-pack-media controls preload="none" style="width: 240px" :src="card.media.src"></video><audio v-else-if="card.media?.kind === 'audio'" v-pack-media controls preload="none" style="width: 240px" :src="card.media.src"></audio></section></div>
|
||||
</Teleport>
|
||||
</template>
|
||||
Reference in new issue
Block a user