227 lines
6.1 KiB
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>
|