aboutsummaryrefslogtreecommitdiff
path: root/src/components/TutorialPane.vue
diff options
context:
space:
mode:
authorTerry Truong <terry06890@gmail.com>2022-09-13 19:59:06 +1000
committerTerry Truong <terry06890@gmail.com>2022-09-13 20:00:17 +1000
commit23b5cc80ba02936659564dd03b173d3214ce5978 (patch)
treecdf6a183d1a0bfcb45a924585b764c723dd67b55 /src/components/TutorialPane.vue
parente382d4173c990a49a9ef3db1b3681763a3e2e908 (diff)
Use Vue Composition API and ESLint
Diffstat (limited to 'src/components/TutorialPane.vue')
-rw-r--r--src/components/TutorialPane.vue193
1 files changed, 90 insertions, 103 deletions
diff --git a/src/components/TutorialPane.vue b/src/components/TutorialPane.vue
index 2803498..4c24bae 100644
--- a/src/components/TutorialPane.vue
+++ b/src/components/TutorialPane.vue
@@ -2,7 +2,7 @@
<div :style="styles" class="relative flex flex-col justify-between">
<close-icon @click.stop="onClose" class="absolute top-2 right-2 w-8 h-8 hover:cursor-pointer"/>
<h1 class="text-center text-lg font-bold pt-3 pb-2">
- {{stage == 0 ? 'Welcome' : `Tutorial (Step ${stage} of ${lastStage})`}}
+ {{stage == 0 ? 'Welcome' : `Tutorial (Step ${stage} of ${LAST_STAGE})`}}
</h1>
<transition name="fade" mode="out-in">
<div v-if="stage == 0" :style="contentStyles">
@@ -58,119 +58,106 @@
Prev
</s-button>
<s-button :class="{invisible: !hidNextPrevOnce && stage == 1}"
- @click="stage != lastStage ? onNextClick() : onClose()" :style="buttonStyles">
- {{stage != lastStage ? 'Next' : 'Finish'}}
+ @click="stage != LAST_STAGE ? onNextClick() : onClose()" :style="buttonStyles">
+ {{stage != LAST_STAGE ? 'Next' : 'Finish'}}
</s-button>
</template>
</div>
</div>
</template>
-<script lang="ts">
-import {defineComponent, PropType} from 'vue';
+<script setup lang="ts">
+import {ref, computed, watch, onMounted, PropType} from 'vue';
import SButton from './SButton.vue';
import CloseIcon from './icon/CloseIcon.vue';
import {Action, UiOptions} from '../lib';
-export default defineComponent({
- props: {
- actionsDone: {type: Object as PropType<Set<Action>>, required: true},
- // Used to avoid disabling actions already done
- triggerFlag: {type: Boolean, required: true},
- // Used to indicate that a tutorial-requested 'trigger' action has been done
- skipWelcome: {type: Boolean, default: false},
- uiOpts: {type: Object as PropType<UiOptions>, required: true},
- },
- data(){
- return {
- stage: 0, // Indicates the current step of the tutorial (stage 0 is the welcome message)
- lastStage: 9,
- disabledOnce: false, // Set to true after disabling features at stage 1
- stageActions: [
- // Specifies, for stages 1+, what action to enable (can repeat an action to enable nothing new)
- 'expand', 'collapse', 'expandToView', 'unhideAncestor',
- 'tileInfo', 'search', 'autoMode', 'settings', 'help',
- ] as Action[],
- hidNextPrevOnce: false, // Used to hide prev/next buttons when initially at stage 1
- };
- },
- computed: {
- styles(): Record<string,string> {
- return {
- backgroundColor: this.uiOpts.bgColorDark,
- color: this.uiOpts.textColor,
- };
- },
- contentStyles(): Record<string,string> {
- return {
- padding: '0 0.5cm',
- overflow: 'auto',
- textAlign: 'center',
- };
- },
- buttonStyles(): Record<string,string> {
- return {
- color: this.uiOpts.textColor,
- backgroundColor: this.uiOpts.bgColor,
- };
- },
- touchDevice(): boolean {
- return this.uiOpts.touchDevice;
- },
- },
- methods: {
- onStartTutorial(){
- this.stage = 1;
- },
- onSkipTutorial(){
- this.$emit('skip');
- this.$emit('close');
- },
- onPrevClick(){
- this.stage = Math.max(1, this.stage - 1);
- },
- onNextClick(){
- this.stage = Math.min(this.stage + 1, this.lastStage);
- },
- onClose(){
- this.$emit('close');
- },
- },
- watch: {
- stage(newVal, oldVal){
- // If starting tutorial, disable 'all' actions
- if (newVal == 1 && !this.disabledOnce){
- for (let action of this.stageActions){
- if (action != null && !this.actionsDone.has(action)){
- this.uiOpts.disabledActions.add(action);
- }
- }
- this.disabledOnce = true;
- }
- // Enable action for this stage
- this.uiOpts.disabledActions.delete(this.stageActions[this.stage - 1]);
- // Notify of new trigger-action
- this.$emit('stage-chg', this.stageActions[this.stage - 1]);
- // After stage 1, show prev/next buttons
- if (newVal == 2){
- this.hidNextPrevOnce = true;
- }
- },
- // Called when a trigger-action is done, and advances to the next stage
- triggerFlag(){
- if (this.stage < this.lastStage){
- this.onNextClick();
- } else {
- this.onClose();
+// Props + events
+const props = defineProps({
+ actionsDone: {type: Object as PropType<Set<Action>>, required: true},
+ // Used to avoid disabling actions already done
+ triggerFlag: {type: Boolean, required: true},
+ // Used to indicate that a tutorial-requested 'trigger' action has been done
+ skipWelcome: {type: Boolean, default: false},
+ uiOpts: {type: Object as PropType<UiOptions>, required: true},
+});
+const touchDevice = computed(() => props.uiOpts.touchDevice);
+const emit = defineEmits(['close', 'stage-chg', 'skip']);
+
+// For tutorial stage
+const stage = ref(props.skipWelcome ? 1 : 0);
+ // Indicates the current step of the tutorial (stage 0 is the welcome message)
+const LAST_STAGE = 9;
+const STAGE_ACTIONS = [
+ // Specifies, for stages 1+, what action to enable (can repeat an action to enable nothing new)
+ 'expand', 'collapse', 'expandToView', 'unhideAncestor',
+ 'tileInfo', 'search', 'autoMode', 'settings', 'help',
+] as Action[];
+let disabledOnce = false; // Set to true after disabling features at stage 1
+const hidNextPrevOnce = ref(false); // Used to hide prev/next buttons when initially at stage 1
+
+// For stage changes
+function onStartTutorial(){
+ stage.value = 1;
+}
+function onSkipTutorial(){
+ emit('skip');
+ emit('close');
+}
+function onPrevClick(){
+ stage.value = Math.max(1, stage.value - 1);
+}
+function onNextClick(){
+ stage.value = Math.min(stage.value + 1, LAST_STAGE);
+}
+function onClose(){
+ emit('close');
+}
+function onStageChange(){
+ // If starting tutorial, disable 'all' actions
+ if (stage.value == 1 && !disabledOnce){
+ for (let action of STAGE_ACTIONS){
+ if (action != null && !props.actionsDone.has(action)){
+ props.uiOpts.disabledActions.add(action);
}
- },
- },
- created(){
- if (this.skipWelcome){
- this.stage += 1;
}
- },
- components: {CloseIcon, SButton, },
- emits: ['close', 'stage-chg', 'skip', ],
+ disabledOnce = true;
+ }
+ // Enable action for this stage
+ props.uiOpts.disabledActions.delete(STAGE_ACTIONS[stage.value - 1]);
+ // Notify of new trigger-action
+ emit('stage-chg', STAGE_ACTIONS[stage.value - 1]);
+ // After stage 1, show prev/next buttons
+ if (stage.value == 2){
+ hidNextPrevOnce.value = true;
+ }
+}
+onMounted(() => {
+ if (props.skipWelcome){
+ onStageChange();
+ }
+})
+watch(stage, onStageChange);
+watch(() => props.triggerFlag, () => {
+ if (stage.value < LAST_STAGE){
+ onNextClick();
+ } else {
+ onClose();
+ }
});
+
+// Styles
+const styles = computed(() => ({
+ backgroundColor: props.uiOpts.bgColorDark,
+ color: props.uiOpts.textColor,
+}));
+const contentStyles = {
+ padding: '0 0.5cm',
+ overflow: 'auto',
+ textAlign: 'center',
+};
+const buttonStyles = computed(() => ({
+ color: props.uiOpts.textColor,
+ backgroundColor: props.uiOpts.bgColor,
+}));
</script>