forked from kaverti/website
332 lines
7.9 KiB
JavaScript
332 lines
7.9 KiB
JavaScript
import AjaxErrorHandler from '../../assets/js/errorHandler'
|
|
|
|
const state = {
|
|
thread: '',
|
|
category: null,
|
|
threadId: undefined,
|
|
PollQuestionId: null,
|
|
posts: [],
|
|
postNotification: null,
|
|
locked: false,
|
|
reply: {
|
|
username: '',
|
|
id: null
|
|
},
|
|
editor: {
|
|
show: false,
|
|
loading: false,
|
|
value: ''
|
|
},
|
|
mentions: [],
|
|
loadingPosts: false,
|
|
nextURL: '',
|
|
previousURL: '',
|
|
nextPostsCount: 10,
|
|
previousPostsCount: 0,
|
|
totalPostsCount: 0,
|
|
selectedPosts: [],
|
|
removePostsButtonLoading: false,
|
|
showRemovePostsButton: false
|
|
}
|
|
|
|
const getters = {
|
|
sortedPosts (state) {
|
|
return state.posts.sort((a, b) => {
|
|
return new Date(a.createdAt) - new Date(b.createdAt)
|
|
})
|
|
}
|
|
}
|
|
|
|
const actions = {
|
|
deleteThread ({ state }, vue) {
|
|
vue.axios
|
|
.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/thread/' + state.threadId)
|
|
.then(() => {
|
|
vue.$router.push('/')
|
|
})
|
|
.catch(AjaxErrorHandler(vue.$store))
|
|
},
|
|
removePostsAsync ({ state, commit }, vue) {
|
|
commit('setRemovePostsButtonLoading', true)
|
|
|
|
let promises = state.selectedPosts.map(id => vue.axios.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/post/' + id))
|
|
|
|
Promise.all(promises)
|
|
.then(() => {
|
|
commit('setRemovePostsButtonLoading', false)
|
|
commit('setShowRemovePostsButton', false)
|
|
|
|
state.posts = state.posts.map(post => {
|
|
if(state.selectedPosts.includes(post.id)) {
|
|
post.content = '<p>[This post has been removed by an administrator]</p>'
|
|
}
|
|
|
|
return post
|
|
})
|
|
state.selectedPosts = []
|
|
})
|
|
.catch(e => {
|
|
commit('setRemovePostsButtonLoading', false)
|
|
commit('setShowRemovePostsButton', false)
|
|
AjaxErrorHandler(vue.$store)(e)
|
|
})
|
|
},
|
|
addPostAsync ({ state, commit }, vue) {
|
|
let content = state.editor.value
|
|
state.mentions.forEach(mention => {
|
|
let regexp = new RegExp('(^|\\s)@' + mention + '($|\\s)')
|
|
content = content.replace(regexp, `$1[@${mention}](https://kaverti.com/u/${mention})$2`)
|
|
})
|
|
|
|
var post = {
|
|
content,
|
|
mentions: state.mentions,
|
|
threadId: +vue.$route.params.id
|
|
};
|
|
|
|
if(state.reply.id) {
|
|
post.replyingToId = state.reply.id;
|
|
}
|
|
|
|
commit('setThreadEditorLoading', true)
|
|
|
|
vue.axios
|
|
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/post', post)
|
|
.then(res => {
|
|
commit('setThreadEditorLoading', false)
|
|
commit('addPost', res.data);
|
|
commit('addReplyBubble', res.data)
|
|
commit('setThreadEditorValue', '');
|
|
commit('setThreadEditorState', false);
|
|
commit('setTotalPostsCount', state.totalPostsCount+1)
|
|
commit({
|
|
type: 'setReply',
|
|
username: '',
|
|
id: ''
|
|
});
|
|
})
|
|
.catch(e => {
|
|
commit('setThreadEditorLoading', false)
|
|
AjaxErrorHandler(vue.$store)(e)
|
|
})
|
|
},
|
|
loadInitialPostsAsync ({ commit, dispatch }, vue) {
|
|
commit('setPosts', [])
|
|
commit('setThread', { name: 'Loading...' })
|
|
dispatch('setTitle', 'Loading...')
|
|
|
|
let postNumber = vue.$route.params.post_number
|
|
let apiURL = process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/thread/' + vue.$route.params.id
|
|
|
|
if(postNumber !== undefined) {
|
|
apiURL += '?postNumber=' + postNumber
|
|
}
|
|
|
|
vue.axios
|
|
.get(apiURL)
|
|
.then(res => {
|
|
|
|
commit('setThread', res.data)
|
|
dispatch('setTitle', res.data.title)
|
|
commit('setNextURL', res.data.meta.nextURL)
|
|
commit('setLocked', res.data.locked)
|
|
commit('setPreviousURL', res.data.meta.previousURL)
|
|
commit('setNextURL', res.data.meta.nextURL)
|
|
commit('setPreviousURL', res.data.meta.previousURL)
|
|
commit('setPostCounts', res.data.meta)
|
|
commit('setTotalPostsCount', res.data.postsCount)
|
|
commit('setPosts', res.data.Posts)
|
|
|
|
vue.$router.replace({ name: 'thread-post', params: {
|
|
post_number: postNumber || 0,
|
|
slug: res.data.slug
|
|
}});
|
|
|
|
if(postNumber !== undefined) {
|
|
vue.highlightPost(+postNumber)
|
|
}
|
|
}).catch(e => {
|
|
if(e.response.status === 400) {
|
|
commit('set404Page', true)
|
|
} else {
|
|
AjaxErrorHandler(vue.$store)(e)
|
|
}
|
|
})
|
|
},
|
|
loadPostsAsync ({ state, commit }, { vue, previous }) {
|
|
let URL
|
|
|
|
if(previous) {
|
|
commit('setLoadingPostsState', 'previous')
|
|
URL = state.previousURL
|
|
} else {
|
|
commit('setLoadingPostsState', 'next')
|
|
URL = state.nextURL
|
|
}
|
|
|
|
if(URL === null) {
|
|
commit('setLoadingPostsState', false)
|
|
} else {
|
|
vue.axios
|
|
.get(URL)
|
|
.then(res => {
|
|
let currentPostsIds = state.posts.map(p => p.id)
|
|
let filteredPosts =
|
|
res.data.Posts.filter(p => !currentPostsIds.includes(p.id))
|
|
|
|
commit('setLoadingPostsState', false)
|
|
|
|
if(previous) {
|
|
let last = filteredPosts.slice(-1)[0]
|
|
|
|
commit('prependPosts', filteredPosts)
|
|
commit('setPreviousURL', res.data.meta.previousURL)
|
|
|
|
if(last) {
|
|
vue.scrollTo(last.postNumber)
|
|
}
|
|
} else {
|
|
commit('addPost', filteredPosts)
|
|
commit('setNextURL', res.data.meta.nextURL)
|
|
}
|
|
|
|
commit('setPostCounts', res.data.meta)
|
|
})
|
|
.catch((e) => {
|
|
console.log(e)
|
|
AjaxErrorHandler(vue.$store)
|
|
})
|
|
}
|
|
},
|
|
loadNewPostsSinceLoad ({ state, commit }, post) {
|
|
if(state.nextPostsCount < 10) {
|
|
let nextURL = state.nextURL
|
|
let baseURL = process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/thread/' + state.threadId + '?limit=10&from='
|
|
|
|
commit('incrementNextPostsCount')
|
|
|
|
if(nextURL === null) {
|
|
commit('setNextURL', baseURL + (post.postNumber-1))
|
|
}
|
|
}
|
|
},
|
|
setThreadLockedState ({ state, commit }, vue) {
|
|
vue.axios
|
|
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/thread/' + state.threadId, { locked: !state.locked })
|
|
.then(() => {
|
|
commit('setLocked', !state.locked)
|
|
})
|
|
.catch((e) => {
|
|
console.log(e)
|
|
AjaxErrorHandler(vue.$store)
|
|
})
|
|
}
|
|
}
|
|
|
|
const mutations = {
|
|
setReply (state, payload) {
|
|
state.reply.username = payload.username;
|
|
state.reply.id = payload.id;
|
|
|
|
if(payload.quote) {
|
|
state.editor.value = payload.quote;
|
|
}
|
|
},
|
|
'thread/setPostNotification': (state, post) => {
|
|
state.postNotification = post
|
|
},
|
|
addPost (state, post) {
|
|
if(Array.isArray(post)) {
|
|
state.posts.push(...post)
|
|
} else {
|
|
state.posts.push(post)
|
|
}
|
|
},
|
|
prependPosts (state, posts) {
|
|
state.posts.unshift(...posts)
|
|
},
|
|
addReplyBubble (state, post) {
|
|
let repliedToPost = {}, index
|
|
|
|
if(post.replyId) {
|
|
state.posts.forEach((p, i) => {
|
|
if(p.id === post.replyId) {
|
|
index = i
|
|
repliedToPost = p
|
|
}
|
|
})
|
|
|
|
repliedToPost.Replies.push(post)
|
|
|
|
state.posts.splice(index, 1, repliedToPost)
|
|
}
|
|
},
|
|
setThreadEditorValue (state, value) {
|
|
state.editor.value = value
|
|
},
|
|
setThreadEditorLoading (state, value) {
|
|
state.editor.loading = value
|
|
},
|
|
setThreadEditorState (state, value) {
|
|
state.editor.show = value
|
|
},
|
|
setLoadingPostsState (state, value) {
|
|
state.loadingPosts = value
|
|
},
|
|
setPosts (state, value) {
|
|
state.posts = value
|
|
},
|
|
setThread (state, obj) {
|
|
state.thread = obj.name
|
|
state.content = obj.content
|
|
state.title = obj.title
|
|
state.threadId = obj.id
|
|
state.PollQuestionId = obj.PollQuestionId
|
|
state.category = obj.Category
|
|
},
|
|
setNextURL (state, URL) {
|
|
state.nextURL = URL
|
|
},
|
|
setPreviousURL (state, URL) {
|
|
state.previousURL = URL
|
|
},
|
|
setPostCounts (state, meta) {
|
|
state.previousPostsCount = meta.previousPostsCount
|
|
state.nextPostsCount = meta.nextPostsCount
|
|
},
|
|
setTotalPostsCount (state, count) {
|
|
state.totalPostsCount = count
|
|
},
|
|
incrementNextPostsCount (state) {
|
|
state.nextPostsCount++
|
|
},
|
|
setMentions (state, mentions) {
|
|
state.mentions = mentions
|
|
},
|
|
setLocked (state, value) {
|
|
state.locked = value
|
|
},
|
|
setSelectedPosts (state, id ) {
|
|
let index = state.selectedPosts.indexOf(id)
|
|
|
|
if(index > -1) {
|
|
state.selectedPosts.splice(index, 1)
|
|
} else {
|
|
state.selectedPosts.push(id)
|
|
}
|
|
},
|
|
setRemovePostsButtonLoading (state, value) {
|
|
state.removePostsButtonLoading = value
|
|
},
|
|
setShowRemovePostsButton (state, value) {
|
|
state.showRemovePostsButton = value
|
|
}
|
|
}
|
|
|
|
export default {
|
|
state,
|
|
getters,
|
|
actions,
|
|
mutations
|
|
}
|