skillbox/client/src/pages/module/module.vue

227 lines
6.1 KiB
Vue

<template>
<module
:module="module"
@editNote="editNote"
@addNote="addNote"
@bookmark="bookmark"
/>
</template>
<script>
import Module from '@/components/modules/Module';
import UPDATE_LAST_MODULE_MUTATION from '@/graphql/gql/mutations/updateLastModule.gql';
import UPDATE_MODULE_BOOKMARK_MUTATION from '@/graphql/gql/mutations/updateModuleBookmark.gql';
// import ME_QUERY from '@/graphql/gql/meQuery.gql';
import MODULE_FRAGMENT from '@/graphql/gql/fragments/moduleParts.gql';
import SCROLL_POSITION from '@/graphql/gql/local/scrollPosition.gql';
import SCROLL_TO_MUTATION from '@/graphql/gql/local/mutations/scrollTo.gql';
import meMixin from '@/mixins/me';
import MODULE_DETAILS_QUERY from '@/graphql/gql/queries/modules/moduleDetailsQuery.gql';
import ME_QUERY from '@/graphql/gql/queries/meQuery.gql';
import {setModuleEditMode} from '@/graphql/cache-operations';
export default {
mixins: [meMixin],
components: {
Module,
},
data() {
return {
module: {},
updateSent: false
};
},
beforeRouteLeave(to, from, next) {
// toggle edit mode if leavind the module subtree
if(this.module.inEditMode && to.path.indexOf('/module/') === -1) {
setModuleEditMode(this.module.slug, false);
}
next();
},
apollo: {
module() {
return {
query: MODULE_DETAILS_QUERY,
variables: {
slug: this.$route.params.slug,
},
result({data: {module: {id}}}) {
if (!this.updateSent) {
this.$log.debug(`=== updating result for module ${id} ===`);
this.updateLastVisitedModule(id);
this.updateSent = true;
}
},
fetchPolicy: 'cache-first',
};
},
scrollPosition: {
query: SCROLL_POSITION,
},
},
methods: {
updateLastVisitedModule(moduleId) {
this.$log.debug(`updating last visited module for module ${moduleId}`);
if (!moduleId) {
this.$log.warn('no module id');
return;
}
if (this.me.lastModule && this.me.lastModule.id === moduleId) {
this.$log.debug('same module already set as last module');
return;
}
this.$apollo.mutate({
mutation: UPDATE_LAST_MODULE_MUTATION,
variables: {
input: {
id: moduleId,
},
},
update: (store, {data: {updateLastModule: {lastModule}}}) => {
const {id, slug} = lastModule;
this.$log.debug('updating last module', id, slug);
const query = ME_QUERY;
let {me} = store.readQuery({
query,
});
// me.lastModule = {
// id,
// slug,
// __typename: 'ModuleNode',
// };
let edges = [...me.recentModules.edges];
const foundIndex = edges.findIndex(edge => edge.node.slug === slug);
if (foundIndex > -1) {
edges = [...edges.slice(0, foundIndex), ...edges.slice(foundIndex + 1, edges.length)];
}
edges = [
{
node: lastModule,
__typename: 'ModuleNodeEdge',
},
...edges.slice(0, 2),
];
const recentModules = {
__typename: 'ModuleNodeConnection',
edges
};
const data = {
me: {
...me,
recentModules,
lastModule: {
...lastModule,
// todo: do we really need this? shouldn't the lastModule property already include this?
'__typename': 'ModuleNode'
}
}
};
store.writeQuery({
query,
data
});
},
});
},
bookmark(bookmarked) {
const slug = this.module.slug;
this.$apollo.mutate({
mutation: UPDATE_MODULE_BOOKMARK_MUTATION,
variables: {
input: {
module: slug,
bookmarked,
},
},
update: (store) => {
const fragment = MODULE_FRAGMENT;
const id = store.identify({
__typename: 'ModuleNode',
slug: slug
});
const module = store.readFragment({
fragment,
id,
});
let bookmark;
if (bookmarked) {
bookmark = {
__typename: 'ModuleBookmarkNode',
note: null,
};
} else {
bookmark = null;
}
const data = {
...module,
bookmark
};
store.writeFragment({
data,
fragment,
id,
});
},
optimisticResponse: {
__typename: 'Mutation',
updateModuleBookmark: {
__typename: 'UpdateModuleBookmarkPayload',
success: true,
},
},
});
},
addNote(id) {
this.$store.dispatch('addNote', {
content: id,
parent: this.module.slug,
type: 'module'
});
},
editNote() {
this.$store.dispatch('editNote', this.module.bookmark.note);
},
scrollTo() {
if (this.scrollPosition && this.scrollPosition.scrollTo) {
let options = {
container: 'body',
easing: 'ease',
offset: -60,
x: false,
y: true,
};
setTimeout(() => {
this.$scrollTo(`[data-scrollto="${this.scrollPosition.scrollTo}"]`, 1000, options);
this.$apollo.mutate({
mutation: SCROLL_TO_MUTATION,
variables: {
scrollTo: '',
},
});
}, 250); // unfortunately this timeout is needed as it is hard to tell when everything is rendered
}
},
},
};
</script>
<style scoped lang="scss">
</style>