Added tour
This commit is contained in:
parent
ed67f14f6f
commit
455e88f183
@ -4,7 +4,7 @@
|
|||||||
<button class="button-bar__button button" :class="{ 'button-bar__button--on': layoutSettings.showNavigationBar }" @click="toggleNavigationBar()" v-title="'Toggle navigation bar'">
|
<button class="button-bar__button button" :class="{ 'button-bar__button--on': layoutSettings.showNavigationBar }" @click="toggleNavigationBar()" v-title="'Toggle navigation bar'">
|
||||||
<icon-navigation-bar></icon-navigation-bar>
|
<icon-navigation-bar></icon-navigation-bar>
|
||||||
</button>
|
</button>
|
||||||
<button class="button-bar__button button" :class="{ 'button-bar__button--on': layoutSettings.showSidePreview }" @click="toggleSidePreview()" v-title="'Toggle side preview'">
|
<button class="button-bar__button button" :class="{ 'button-bar__button--on': layoutSettings.showSidePreview }" tour-step-anchor="editor" @click="toggleSidePreview()" v-title="'Toggle side preview'">
|
||||||
<icon-side-preview></icon-side-preview>
|
<icon-side-preview></icon-side-preview>
|
||||||
</button>
|
</button>
|
||||||
<button class="button-bar__button button" @click="toggleEditor(false)" v-title="'Reader mode'">
|
<button class="button-bar__button button" @click="toggleEditor(false)" v-title="'Reader mode'">
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<div class="layout__panel layout__panel--explorer" v-show="styles.showExplorer" :aria-hidden="!styles.showExplorer" :style="{width: styles.layoutOverflow ? '100%' : constants.explorerWidth + 'px'}">
|
<div class="layout__panel layout__panel--explorer" v-show="styles.showExplorer" :aria-hidden="!styles.showExplorer" :style="{width: styles.layoutOverflow ? '100%' : constants.explorerWidth + 'px'}">
|
||||||
<explorer></explorer>
|
<explorer></explorer>
|
||||||
</div>
|
</div>
|
||||||
<div class="layout__panel flex flex--column" :style="{width: styles.innerWidth + 'px'}">
|
<div class="layout__panel flex flex--column" tour-step-anchor="welcome,end" :style="{width: styles.innerWidth + 'px'}">
|
||||||
<div class="layout__panel layout__panel--navigation-bar" v-show="styles.showNavigationBar" :style="{height: constants.navigationBarHeight + 'px'}">
|
<div class="layout__panel layout__panel--navigation-bar" v-show="styles.showNavigationBar" :style="{height: constants.navigationBarHeight + 'px'}">
|
||||||
<navigation-bar></navigation-bar>
|
<navigation-bar></navigation-bar>
|
||||||
</div>
|
</div>
|
||||||
@ -44,6 +44,7 @@
|
|||||||
<side-bar></side-bar>
|
<side-bar></side-bar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<tour v-if="!layoutSettings.welcomeTourFinished"></tour>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -56,6 +57,7 @@ import Explorer from './Explorer';
|
|||||||
import SideBar from './SideBar';
|
import SideBar from './SideBar';
|
||||||
import Editor from './Editor';
|
import Editor from './Editor';
|
||||||
import Preview from './Preview';
|
import Preview from './Preview';
|
||||||
|
import Tour from './Tour';
|
||||||
import StickyComment from './gutters/StickyComment';
|
import StickyComment from './gutters/StickyComment';
|
||||||
import CurrentDiscussion from './gutters/CurrentDiscussion';
|
import CurrentDiscussion from './gutters/CurrentDiscussion';
|
||||||
import FindReplace from './FindReplace';
|
import FindReplace from './FindReplace';
|
||||||
@ -70,6 +72,7 @@ export default {
|
|||||||
SideBar,
|
SideBar,
|
||||||
Editor,
|
Editor,
|
||||||
Preview,
|
Preview,
|
||||||
|
Tour,
|
||||||
StickyComment,
|
StickyComment,
|
||||||
CurrentDiscussion,
|
CurrentDiscussion,
|
||||||
FindReplace,
|
FindReplace,
|
||||||
@ -85,6 +88,9 @@ export default {
|
|||||||
'constants',
|
'constants',
|
||||||
'styles',
|
'styles',
|
||||||
]),
|
]),
|
||||||
|
...mapGetters('data', [
|
||||||
|
'layoutSettings',
|
||||||
|
]),
|
||||||
showFindReplace() {
|
showFindReplace() {
|
||||||
return !!this.$store.state.findReplace.type;
|
return !!this.$store.state.findReplace.type;
|
||||||
},
|
},
|
||||||
|
@ -36,8 +36,8 @@
|
|||||||
<modal-inner v-else aria-label="Dialog">
|
<modal-inner v-else aria-label="Dialog">
|
||||||
<div class="modal__content" v-html="config.content"></div>
|
<div class="modal__content" v-html="config.content"></div>
|
||||||
<div class="modal__button-bar">
|
<div class="modal__button-bar">
|
||||||
<button v-if="config.rejectText" class="button" @click="config.reject()">{{config.rejectText}}</button>
|
<button class="button" v-if="config.rejectText" @click="config.reject()">{{config.rejectText}}</button>
|
||||||
<button v-if="config.resolveText" class="button" @click="config.resolve()">{{config.resolveText}}</button>
|
<button class="button" v-if="config.resolveText" @click="config.resolve()">{{config.resolveText}}</button>
|
||||||
</div>
|
</div>
|
||||||
</modal-inner>
|
</modal-inner>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
<nav class="navigation-bar" :class="{'navigation-bar--editor': styles.showEditor && !revisionContent}">
|
<nav class="navigation-bar" :class="{'navigation-bar--editor': styles.showEditor && !revisionContent}">
|
||||||
<!-- Explorer -->
|
<!-- Explorer -->
|
||||||
<div class="navigation-bar__inner navigation-bar__inner--left navigation-bar__inner--button">
|
<div class="navigation-bar__inner navigation-bar__inner--left navigation-bar__inner--button">
|
||||||
<button class="navigation-bar__button button" @click="toggleExplorer()" v-title="'Toggle explorer'"><icon-folder></icon-folder></button>
|
<button class="navigation-bar__button button" tour-step-anchor="explorer" @click="toggleExplorer()" v-title="'Toggle explorer'"><icon-folder></icon-folder></button>
|
||||||
</div>
|
</div>
|
||||||
<!-- Side bar -->
|
<!-- Side bar -->
|
||||||
<div class="navigation-bar__inner navigation-bar__inner--right navigation-bar__inner--button">
|
<div class="navigation-bar__inner navigation-bar__inner--right navigation-bar__inner--button">
|
||||||
<button class="navigation-bar__button navigation-bar__button--stackedit button" @click="toggleSideBar()" v-title="'Toggle side bar'"><icon-provider provider-id="stackedit"></icon-provider></button>
|
<button class="navigation-bar__button navigation-bar__button--stackedit button" tour-step-anchor="menu" @click="toggleSideBar()" v-title="'Toggle side bar'"><icon-provider provider-id="stackedit"></icon-provider></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="navigation-bar__inner navigation-bar__inner--right navigation-bar__inner--title flex flex--row">
|
<div class="navigation-bar__inner navigation-bar__inner--right navigation-bar__inner--title flex flex--row">
|
||||||
<!-- Spinner -->
|
<!-- Spinner -->
|
||||||
|
218
src/components/Tour.vue
Normal file
218
src/components/Tour.vue
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tour" @keyup.esc="skip">
|
||||||
|
<div class="tour-step" :class="'tour-step--' + step" :style="stepStyle">
|
||||||
|
<div class="tour-step__inner" v-if="step === 'welcome'">
|
||||||
|
<h2>Welcome to StackEdit!</h2>
|
||||||
|
<p>Greater, lighter, faster... StackEdit 5 is here!</p>
|
||||||
|
<p>Please click <b>Next</b> to take a quick tour.</p>
|
||||||
|
<div class="tour-step__button-bar">
|
||||||
|
<button class="button" @click="finish">Skip</button>
|
||||||
|
<button class="button" @click="next">Next</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tour-step__inner" v-else-if="step === 'editor'">
|
||||||
|
<h2>Your Markdown editor</h2>
|
||||||
|
<p>StackEdit renders your Markdown into HTML in real-time.</p>
|
||||||
|
<p>Click <icon-side-preview></icon-side-preview> to toggle the side preview.</p>
|
||||||
|
<div class="tour-step__button-bar">
|
||||||
|
<button class="button" @click="finish">Skip</button>
|
||||||
|
<button class="button" @click="next">Next</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tour-step__inner" v-else-if="step === 'explorer'">
|
||||||
|
<h2>File explorer</h2>
|
||||||
|
<p>StackEdit can manage multiple files and folders in a workspace.</p>
|
||||||
|
<p>Click <icon-folder></icon-folder> to open the file explorer.</p>
|
||||||
|
<div class="tour-step__button-bar">
|
||||||
|
<button class="button" @click="finish">Skip</button>
|
||||||
|
<button class="button" @click="next">Next</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tour-step__inner" v-else-if="step === 'menu'">
|
||||||
|
<h2>Do a lot more!</h2>
|
||||||
|
<p>StackEdit can also synchronize and publish your files, manage collaborative workspaces...</p>
|
||||||
|
<p>Click <icon-provider provider-id="stackedit"></icon-provider> to explore the menu.</p>
|
||||||
|
<div class="tour-step__button-bar">
|
||||||
|
<button class="button" @click="finish">Skip</button>
|
||||||
|
<button class="button" @click="next">Next</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tour-step__inner" v-else-if="step === 'end'">
|
||||||
|
<h2>Enjoy!</h2>
|
||||||
|
<p>If you like StackEdit, please rate 5 stars on the <a target="_blank" href="https://chrome.google.com/webstore/detail/stackedit/iiooodelglhkcpgbajoejffhijaclcdg/reviews">Chrome Web Store</a>.</p>
|
||||||
|
<p>You can also star the project on <a target="_blank" href="https://github.com/benweet/stackedit">GitHub</a>.</p>
|
||||||
|
<div class="tour-step__button-bar">
|
||||||
|
<button class="button" @click="finish">Ok</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
const steps = [
|
||||||
|
'welcome',
|
||||||
|
'editor',
|
||||||
|
'explorer',
|
||||||
|
'menu',
|
||||||
|
'end',
|
||||||
|
];
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data: () => ({
|
||||||
|
stepIdx: 0,
|
||||||
|
stepStyles: {},
|
||||||
|
}),
|
||||||
|
computed: {
|
||||||
|
step() {
|
||||||
|
return steps[this.stepIdx];
|
||||||
|
},
|
||||||
|
stepStyle() {
|
||||||
|
return this.stepStyles[this.step] || {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updatePositions() {
|
||||||
|
document.querySelectorAll('[tour-step-anchor]').cl_each((anchorElt) => {
|
||||||
|
const anchorRect = anchorElt.getBoundingClientRect();
|
||||||
|
const anchorSteps = (anchorElt.getAttribute('tour-step-anchor') || '').split(',');
|
||||||
|
anchorSteps.forEach((step) => {
|
||||||
|
const style = {
|
||||||
|
top: `${anchorRect.top + (anchorRect.height / 2)}px`,
|
||||||
|
left: `${anchorRect.left + (anchorRect.width / 2)}px`,
|
||||||
|
};
|
||||||
|
switch (step) {
|
||||||
|
case 'welcome':
|
||||||
|
case 'end': {
|
||||||
|
style.top = `${anchorRect.top}px`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'editor':
|
||||||
|
case 'menu': {
|
||||||
|
style.left = `${anchorRect.left}px`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'explorer': {
|
||||||
|
style.left = `${anchorRect.left + anchorRect.width}px`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Vue.set(this.stepStyles, step, style);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
finish() {
|
||||||
|
this.$store.dispatch('data/patchLayoutSettings', {
|
||||||
|
welcomeTourFinished: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
next() {
|
||||||
|
this.stepIdx += 1;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$watch(
|
||||||
|
() => this.$store.getters['layout/styles'],
|
||||||
|
() => this.updatePositions(),
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import 'common/variables.scss';
|
||||||
|
|
||||||
|
.tour {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-step {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tour-step-background: mix(#fafafa, $selection-highlighting-color, 80%);
|
||||||
|
$tour-step-width: 220px;
|
||||||
|
|
||||||
|
.tour-step__inner {
|
||||||
|
position: absolute;
|
||||||
|
background-color: $tour-step-background;
|
||||||
|
padding: 1.75em 1.75em 1.25em;
|
||||||
|
font-size: 0.9em;
|
||||||
|
line-height: 1.33;
|
||||||
|
width: $tour-step-width;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: $border-radius-base;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon,
|
||||||
|
.icon-provider {
|
||||||
|
width: 1.25em;
|
||||||
|
height: 1.25em;
|
||||||
|
vertical-align: bottom;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-step--welcome &,
|
||||||
|
.tour-step--end & {
|
||||||
|
left: -$tour-step-width/2;
|
||||||
|
top: 30px;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
bottom: -10px;
|
||||||
|
right: 0;
|
||||||
|
border-top: 10px solid $tour-step-background;
|
||||||
|
border-left: 10px solid transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-step--editor &,
|
||||||
|
.tour-step--menu & {
|
||||||
|
right: 15px;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
top: 0;
|
||||||
|
right: -10px;
|
||||||
|
border-top: 10px solid $tour-step-background;
|
||||||
|
border-right: 10px solid transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-step--explorer & {
|
||||||
|
left: 15px;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
top: 0;
|
||||||
|
left: -10px;
|
||||||
|
border-top: 10px solid $tour-step-background;
|
||||||
|
border-left: 10px solid transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-step__button-bar {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,7 +1,7 @@
|
|||||||
# File properties can contain metadata used
|
# File properties can contain metadata used
|
||||||
# for your publications (Wordpress, Blogger...).
|
# for your publications (Wordpress, Blogger...).
|
||||||
|
|
||||||
# For example:
|
# For example:
|
||||||
|
|
||||||
#title: My article
|
#title: My article
|
||||||
#author:
|
#author:
|
||||||
#tags: Tag 1, Tag 2
|
#tags: Tag 1, Tag 2
|
||||||
|
@ -10,4 +10,5 @@ export default () => ({
|
|||||||
findCaseSensitive: false,
|
findCaseSensitive: false,
|
||||||
findUseRegexp: false,
|
findUseRegexp: false,
|
||||||
sideBarPanel: 'menu',
|
sideBarPanel: 'menu',
|
||||||
|
welcomeTourFinished: false,
|
||||||
});
|
});
|
||||||
|
@ -12,7 +12,7 @@ const minTitleMaxWidth = 200;
|
|||||||
|
|
||||||
const constants = {
|
const constants = {
|
||||||
editorMinWidth: 320,
|
editorMinWidth: 320,
|
||||||
explorerWidth: 250,
|
explorerWidth: 260,
|
||||||
gutterWidth: 250,
|
gutterWidth: 250,
|
||||||
sideBarWidth: 280,
|
sideBarWidth: 280,
|
||||||
navigationBarHeight: 44,
|
navigationBarHeight: 44,
|
||||||
|
@ -100,7 +100,7 @@ export default {
|
|||||||
}),
|
}),
|
||||||
signInForSponsorship: ({ dispatch }, { onResolve }) => dispatch('open', {
|
signInForSponsorship: ({ dispatch }, { onResolve }) => dispatch('open', {
|
||||||
type: 'signInForSponsorship',
|
type: 'signInForSponsorship',
|
||||||
content: `<p>You have to sign in with Google to enable your sponsorship.</p>
|
content: `<p>You have to sign in with Google to sponsor.</p>
|
||||||
<div class="modal__info"><b>Note:</b> This will sync your main workspace.</div>`,
|
<div class="modal__info"><b>Note:</b> This will sync your main workspace.</div>`,
|
||||||
resolveText: 'Ok, sign in',
|
resolveText: 'Ok, sign in',
|
||||||
rejectText: 'Cancel',
|
rejectText: 'Cancel',
|
||||||
|
Loading…
Reference in New Issue
Block a user