Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to Composition API #10

Merged
merged 5 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
"draft": true,
"version": "0.0.0",
"dependencies": {
"@cosmicds/vue-toolkit": "^0.2.0",
"@cosmicds/vue-toolkit": "^0.3.0",
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/vue-fontawesome": "^3.0.5",
"@mdi/font": "^7.4.47",
"@wwtelescope/engine-pinia": "^0.9.0",
"pinia": "^2.1.7",
"vue": "^3.4.15",
"vuetify": "^3.4.11",
"webpack-plugin-vuetify": "^2.0.0"
Expand Down
228 changes: 104 additions & 124 deletions src/MainComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@
<v-col cols="12">
<div class="credits">
<h3>Credits:</h3>
<h4><a href="https://www.cosmicds.cfa.harvard.edu/" target="_blank" rel="noopener noreferrer">CosmicDS</a> Mini Stories Team:</h4>
<h4><a href="https://www.cosmicds.cfa.harvard.edu/" target="_blank" rel="noopener noreferrer">CosmicDS</a> Vue Data Stories Team:</h4>
John Lewis<br>
Jon Carifio<br>
Pat Udomprasert<br>
Expand Down Expand Up @@ -236,143 +236,123 @@
</v-app>
</template>

<script lang="ts">
import { defineComponent, PropType } from "vue";
import { MiniDSBase, BackgroundImageset, skyBackgroundImagesets } from "@cosmicds/vue-toolkit";
import { GotoRADecZoomParams } from "@wwtelescope/engine-pinia";
<script setup lang="ts">
import { ref, reactive, computed, onMounted, nextTick } from "vue";
import { GotoRADecZoomParams, engineStore } from "@wwtelescope/engine-pinia";
import { BackgroundImageset, skyBackgroundImagesets, supportsTouchscreen, blurActiveElement, useWWTKeyboardControls } from "@cosmicds/vue-toolkit";
import { useDisplay } from "vuetify";

type SheetType = "text" | "video";
type CameraParams = Omit<GotoRADecZoomParams, "instant">;
export interface MainComponentProps {
wwtNamespace?: string;
initialCameraParams?: CameraParams;
}

type SheetType = "text" | "video" | null;
const store = engineStore();

export default defineComponent({
extends: MiniDSBase,

props: {
wwtNamespace: {
type: String,
required: true
},
initialCameraParams: {
type: Object as PropType<Omit<GotoRADecZoomParams, 'instant'>>,
default() {
return {
raRad: 0,
decRad: 0,
zoomDeg: 60
};
}
}
},
data() {
const showSplashScreen = new URLSearchParams(window.location.search).get("splash")?.toLowerCase() !== "false";
useWWTKeyboardControls(store);

const touchscreen = supportsTouchscreen();
const { smAndDown } = useDisplay();

const props = withDefaults(defineProps<MainComponentProps>(), {
wwtNamespace: "MainComponent",
initialCameraParams: () => {
return {
showSplashScreen,
backgroundImagesets: [] as BackgroundImageset[],
sheet: null as SheetType,
layersLoaded: false,
positionSet: false,

accentColor: "#ffffff",
buttonColor: "#ffffff",

tab: 0
raRad: 0,
decRad: 0,
zoomDeg: 60
};
},
}
});

mounted() {
this.waitForReady().then(async () => {

this.backgroundImagesets = [...skyBackgroundImagesets];
const splash = new URLSearchParams(window.location.search).get("splash")?.toLowerCase() !== "false";
const showSplashScreen = ref(splash);
const backgroundImagesets = reactive<BackgroundImageset[]>([]);
const sheet = ref<SheetType | null>(null);
const layersLoaded = ref(false);
const positionSet = ref(false);
const accentColor = ref("#ffffff");
const buttonColor = ref("#ffffff");
const tab = ref(0);

onMounted(() => {
store.waitForReady().then(async () => {
skyBackgroundImagesets.forEach(iset => backgroundImagesets.push(iset));
store.gotoRADecZoom({
...props.initialCameraParams,
instant: true
}).then(() => positionSet.value = true);

// If there are layers to set up, do that here!
layersLoaded.value = true;
});
});

this.gotoRADecZoom({
...this.initialCameraParams,
instant: true
}).then(() => this.positionSet = true);
const ready = computed(() => layersLoaded.value && positionSet.value);

// If there are layers to set up, do that here!
this.layersLoaded = true;
/* `isLoading` is a bit redundant here, but it could potentially have independent logic */
const isLoading = computed(() => !ready.value);

});
},
/* Properties related to device/screen characteristics */
const smallSize = computed(() => smAndDown);

computed: {

/**
These properties relate to the state of the mini.
`isLoading` is a bit redundant here, but it could potentially have
independent logic.
*/
ready(): boolean {
return this.layersLoaded && this.positionSet;
},
isLoading(): boolean {
return !this.ready;
},

/**
Properties related to device/screen characteristics
*/
smallSize(): boolean {
return this.$vuetify.display.smAndDown;
},
mobile(): boolean {
return this.smallSize && this.touchscreen;
},

/**
This lets us inject component data into element CSS
*/
cssVars() {
return {
'--accent-color': this.accentColor,
'--app-content-height': this.showTextSheet ? '66%' : '100%',
};
},

/**
Computed flags that control whether the relevant dialogs display.
The `sheet` data member stores which sheet is open, so these are just
computed wrappers around modifying/querying that which can be used as
dialog v-model values
*/
showTextSheet: {
get(): boolean {
return this.sheet === 'text';
},
set(_value: boolean) {
this.selectSheet('text');
}
},
showVideoSheet: {
get(): boolean {
return this.sheet === "video";
},
set(value: boolean) {
this.selectSheet('video');
if (!value) {
const video = document.querySelector("#info-video") as HTMLVideoElement;
video.pause();
}
}
}
/* This lets us inject component data into element CSS */
const cssVars = computed(() => {
return {
"--accent-color": accentColor.value,
"--app-content-height": showTextSheet.value ? "66%" : "100%",
};
});


/**
Computed flags that control whether the relevant dialogs display.
The `sheet` data member stores which sheet is open, so these are just
computed wrappers around modifying/querying that which can be used as
dialog v-model values
*/
const showTextSheet = computed({
get() {
return sheet.value === "text";
},
set(_value: boolean) {
selectSheet("text");
}
});

methods: {
closeSplashScreen() {
this.showSplashScreen = false;
},

selectSheet(name: SheetType) {
if (this.sheet === name) {
this.sheet = null;
this.$nextTick(() => {
this.blurActiveElement();
});
} else {
this.sheet = name;
}
const showVideoSheet = computed({
get() {
return sheet.value === "video";
},
set(value: boolean) {
selectSheet("video");
if (!value) {
const video = document.querySelector("#info-video") as HTMLVideoElement;
video.pause();
}
}
});

/**
This is convenient if there's any other logic that we want to run
when the splash screen is closed
*/
function closeSplashScreen() {
showSplashScreen.value = false;
}

function selectSheet(sheetType: SheetType | null) {
if (sheet.value === sheetType) {
sheet.value = null;
nextTick(() => {
blurActiveElement();
});
} else {
sheet.value = sheetType;
}
}
</script>

<style lang="less">
Expand Down
10 changes: 5 additions & 5 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Vue, { createApp } from "vue";
import Vue, { createApp, type Plugin } from "vue";

import { FundingAcknowledgment, IconButton, CreditLogos } from "@cosmicds/vue-toolkit";
import { FundingAcknowledgement, IconButton, CreditLogos } from "@cosmicds/vue-toolkit";
import MainComponent from "./MainComponent.vue";

import vuetify from "../plugins/vuetify";
Expand All @@ -25,11 +25,11 @@ library.add(faVideo);
const update = (el: HTMLElement, binding: Vue.DirectiveBinding) => el.style.visibility = (binding.value) ? "hidden" : "";

createApp(MainComponent, {
wwtNamespace: "wwt-minids-template"
wwtNamespace: "vue-ds-template"
})

// Plugins
.use(wwtPinia)
.use(wwtPinia as unknown as Plugin<[]>)
.use(vuetify)

// Directives
Expand All @@ -52,7 +52,7 @@ createApp(MainComponent, {
.component("WorldWideTelescope", WWTComponent)
.component('font-awesome-icon', FontAwesomeIcon)
.component('icon-button', IconButton)
.component('funding-acknowledgement', FundingAcknowledgment)
.component('funding-acknowledgement', FundingAcknowledgement)
.component('credit-logos', CreditLogos)

// Mount
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"sourceMap": true,
"baseUrl": ".",
"outDir": "dist",
"noImplicitAny": false,
"paths": {
"@/*": [
"src/*"
Expand All @@ -29,6 +30,6 @@
"include": [
"plugins/*.ts",
"src/**/*.ts",
"src/**/*.vue"
"src/*.vue"
]
}
Loading
Loading