aboutsummaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/chat.js10
-rw-r--r--src/modules/config.js1
-rw-r--r--src/modules/instance.js8
-rw-r--r--src/modules/statuses.js83
-rw-r--r--src/modules/users.js117
5 files changed, 152 insertions, 67 deletions
diff --git a/src/modules/chat.js b/src/modules/chat.js
index 383ac75c..2804e577 100644
--- a/src/modules/chat.js
+++ b/src/modules/chat.js
@@ -1,12 +1,16 @@
const chat = {
state: {
messages: [],
- channel: {state: ''}
+ channel: {state: ''},
+ socket: null
},
mutations: {
setChannel (state, channel) {
state.channel = channel
},
+ setSocket (state, socket) {
+ state.socket = socket
+ },
addMessage (state, message) {
state.messages.push(message)
state.messages = state.messages.slice(-19, 20)
@@ -16,8 +20,12 @@ const chat = {
}
},
actions: {
+ disconnectFromChat (store) {
+ store.state.socket.disconnect()
+ },
initializeChat (store, socket) {
const channel = socket.channel('chat:public')
+ store.commit('setSocket', socket)
channel.on('new_msg', (msg) => {
store.commit('addMessage', msg)
})
diff --git a/src/modules/config.js b/src/modules/config.js
index 6d8aad35..1666a2c5 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -5,6 +5,7 @@ const browserLocale = (window.navigator.language || 'en').split('-')[0]
const defaultState = {
colors: {},
+ hideMutedPosts: undefined, // instance default
collapseMessageWithSubject: undefined, // instance default
hideAttachments: false,
hideAttachmentsInConv: false,
diff --git a/src/modules/instance.js b/src/modules/instance.js
index 7b67890f..3a559ba0 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -17,6 +17,7 @@ const defaultState = {
showInstanceSpecificPanel: false,
formattingOptionsEnabled: false,
alwaysShowSubjectInput: true,
+ hideMutedPosts: false,
collapseMessageWithSubject: false,
hidePostStats: false,
hideUserStats: false,
@@ -37,6 +38,7 @@ const defaultState = {
emoji: [],
customEmoji: [],
restrictedNicknames: [],
+ postFormats: [],
// Feature-set, apparently, not everything here is reported...
mediaProxyAvailable: false,
@@ -47,7 +49,11 @@ const defaultState = {
// Html stuff
instanceSpecificPanelContent: '',
- tos: ''
+ tos: '',
+
+ // Version Information
+ backendVersion: '',
+ frontendVersion: ''
}
const instance = {
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 826b544c..742eecba 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -1,4 +1,5 @@
-import { remove, slice, each, find, maxBy, minBy, merge, last, isArray } from 'lodash'
+import { remove, slice, each, find, maxBy, minBy, merge, first, last, isArray, omitBy } from 'lodash'
+import { set } from 'vue'
import apiService from '../services/api/api.service.js'
// import parse from '../services/status_parser/status_parser.js'
@@ -10,6 +11,7 @@ const emptyTl = (userId = 0) => ({
visibleStatusesObject: {},
newStatusCount: 0,
maxId: 0,
+ minId: 0,
minVisibleId: 0,
loading: false,
followers: [],
@@ -18,7 +20,7 @@ const emptyTl = (userId = 0) => ({
flushMarker: 0
})
-export const defaultState = {
+export const defaultState = () => ({
allStatuses: [],
allStatusesObject: {},
maxId: 0,
@@ -29,7 +31,8 @@ export const defaultState = {
data: [],
idStore: {},
loading: false,
- error: false
+ error: false,
+ fetcherId: null
},
favorites: new Set(),
error: false,
@@ -44,7 +47,7 @@ export const defaultState = {
tag: emptyTl(),
dms: emptyTl()
}
-}
+})
export const prepareStatus = (status) => {
// Set deleted flag
@@ -70,7 +73,9 @@ const mergeOrAdd = (arr, obj, item) => {
if (oldItem) {
// We already have this, so only merge the new info.
- merge(oldItem, item)
+ // We ignore null values to avoid overwriting existing properties with missing data
+ // we also skip 'user' because that is handled by users module
+ merge(oldItem, omitBy(item, (v, k) => v === null || k === 'user'))
// Reactivity fix.
oldItem.attachments.splice(oldItem.attachments.length)
return {item: oldItem, new: false}
@@ -78,7 +83,7 @@ const mergeOrAdd = (arr, obj, item) => {
// This is a new item, prepare it
prepareStatus(item)
arr.push(item)
- obj[item.id] = item
+ set(obj, item.id, item)
return {item, new: true}
}
}
@@ -117,11 +122,16 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
const timelineObject = state.timelines[timeline]
const maxNew = statuses.length > 0 ? maxBy(statuses, 'id').id : 0
- const older = timeline && maxNew < timelineObject.maxId
+ const minNew = statuses.length > 0 ? minBy(statuses, 'id').id : 0
+ const newer = timeline && maxNew > timelineObject.maxId && statuses.length > 0
+ const older = timeline && (minNew < timelineObject.minId || timelineObject.minId === 0) && statuses.length > 0
- if (timeline && !noIdUpdate && statuses.length > 0 && !older) {
+ if (!noIdUpdate && newer) {
timelineObject.maxId = maxNew
}
+ if (!noIdUpdate && older) {
+ timelineObject.minId = minNew
+ }
// This makes sure that user timeline won't get data meant for other
// user. I.e. opening different user profiles makes request which could
@@ -255,12 +265,9 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
processor(status)
})
- // Keep the visible statuses sorted
+ // Keep the visible statuses sorted
if (timeline) {
sortTimeline(timelineObject)
- if ((older || timelineObject.minVisibleId <= 0) && statuses.length > 0) {
- timelineObject.minVisibleId = minBy(statuses, 'id').id
- }
}
}
@@ -309,18 +316,39 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot
})
}
+const removeStatus = (state, { timeline, userId }) => {
+ const timelineObject = state.timelines[timeline]
+ if (userId) {
+ remove(timelineObject.statuses, { user: { id: userId } })
+ remove(timelineObject.visibleStatuses, { user: { id: userId } })
+ timelineObject.minVisibleId = timelineObject.visibleStatuses.length > 0 ? last(timelineObject.visibleStatuses).id : 0
+ timelineObject.maxId = timelineObject.statuses.length > 0 ? first(timelineObject.statuses).id : 0
+ }
+}
+
export const mutations = {
addNewStatuses,
addNewNotifications,
+ removeStatus,
showNewStatuses (state, { timeline }) {
const oldTimeline = (state.timelines[timeline])
oldTimeline.newStatusCount = 0
oldTimeline.visibleStatuses = slice(oldTimeline.statuses, 0, 50)
oldTimeline.minVisibleId = last(oldTimeline.visibleStatuses).id
+ oldTimeline.minId = oldTimeline.minVisibleId
oldTimeline.visibleStatusesObject = {}
each(oldTimeline.visibleStatuses, (status) => { oldTimeline.visibleStatusesObject[status.id] = status })
},
+ setNotificationFetcher (state, { fetcherId }) {
+ state.notifications.fetcherId = fetcherId
+ },
+ resetStatuses (state) {
+ const emptyState = defaultState()
+ Object.entries(emptyState).forEach(([key, value]) => {
+ state[key] = value
+ })
+ },
clearTimeline (state, { timeline }) {
state.timelines[timeline] = emptyTl(state.timelines[timeline].userId)
},
@@ -335,6 +363,15 @@ export const mutations = {
},
setRetweeted (state, { status, value }) {
const newStatus = state.allStatusesObject[status.id]
+
+ if (newStatus.repeated !== value) {
+ if (value) {
+ newStatus.repeat_num++
+ } else {
+ newStatus.repeat_num--
+ }
+ }
+
newStatus.repeated = value
},
setDeleted (state, { status }) {
@@ -371,7 +408,7 @@ export const mutations = {
}
const statuses = {
- state: defaultState,
+ state: defaultState(),
actions: {
addNewStatuses ({ rootState, commit }, { statuses, showImmediately = false, timeline = false, noIdUpdate = false, userId }) {
commit('addNewStatuses', { statuses, showImmediately, timeline, noIdUpdate, user: rootState.users.currentUser, userId })
@@ -391,6 +428,12 @@ const statuses = {
setNotificationsSilence ({ rootState, commit }, { value }) {
commit('setNotificationsSilence', { value })
},
+ stopFetchingNotifications ({ rootState, commit }) {
+ if (rootState.statuses.notifications.fetcherId) {
+ window.clearInterval(rootState.statuses.notifications.fetcherId)
+ }
+ commit('setNotificationFetcher', { fetcherId: null })
+ },
deleteStatus ({ rootState, commit }, status) {
commit('setDeleted', { status })
apiService.deleteStatus({ id: status.id, credentials: rootState.users.currentUser.credentials })
@@ -399,13 +442,6 @@ const statuses = {
// Optimistic favoriting...
commit('setFavorited', { status, value: true })
apiService.favorite({ id: status.id, credentials: rootState.users.currentUser.credentials })
- .then(response => {
- if (response.ok) {
- return response.json()
- } else {
- return {}
- }
- })
.then(status => {
commit('setFavoritedConfirm', { status })
})
@@ -414,13 +450,6 @@ const statuses = {
// Optimistic favoriting...
commit('setFavorited', { status, value: false })
apiService.unfavorite({ id: status.id, credentials: rootState.users.currentUser.credentials })
- .then(response => {
- if (response.ok) {
- return response.json()
- } else {
- return {}
- }
- })
.then(status => {
commit('setFavoritedConfirm', { status })
})
diff --git a/src/modules/users.js b/src/modules/users.js
index 093af497..1a507d31 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -1,5 +1,5 @@
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
-import { compact, map, each, merge, find } from 'lodash'
+import { compact, map, each, merge, find, last } from 'lodash'
import { set } from 'vue'
import { registerPushNotifications, unregisterPushNotifications } from '../services/push/push.js'
import oauthApi from '../services/new_api/oauth'
@@ -16,9 +16,9 @@ export const mergeOrAdd = (arr, obj, item) => {
} else {
// This is a new item, prepare it
arr.push(item)
- obj[item.id] = item
+ set(obj, item.id, item)
if (item.screen_name && !item.screen_name.includes('@')) {
- obj[item.screen_name] = item
+ set(obj, item.screen_name.toLowerCase(), item)
}
return { item, new: true }
}
@@ -52,23 +52,23 @@ export const mutations = {
state.loggingIn = false
},
// TODO Clean after ourselves?
- addFriends (state, { id, friends, page }) {
+ addFriends (state, { id, friends }) {
const user = state.usersObject[id]
each(friends, friend => {
if (!find(user.friends, { id: friend.id })) {
user.friends.push(friend)
}
})
- user.friendsPage = page + 1
+ user.lastFriendId = last(friends).id
},
- addFollowers (state, { id, followers, page }) {
+ addFollowers (state, { id, followers }) {
const user = state.usersObject[id]
each(followers, follower => {
if (!find(user.followers, { id: follower.id })) {
user.followers.push(follower)
}
})
- user.followersPage = page + 1
+ user.lastFollowerId = last(followers).id
},
// Because frontend doesn't have a reason to keep these stuff in memory
// outside of viewing someones user profile.
@@ -78,7 +78,7 @@ export const mutations = {
return
}
user.friends = []
- user.friendsPage = 0
+ user.lastFriendId = null
},
clearFollowers (state, userId) {
const user = state.usersObject[userId]
@@ -86,15 +86,36 @@ export const mutations = {
return
}
user.followers = []
- user.followersPage = 0
+ user.lastFollowerId = null
},
addNewUsers (state, users) {
each(users, (user) => mergeOrAdd(state.users, state.usersObject, user))
},
- saveBlocks (state, blockIds) {
+ updateUserRelationship (state, relationships) {
+ relationships.forEach((relationship) => {
+ const user = state.usersObject[relationship.id]
+ if (user) {
+ user.follows_you = relationship.followed_by
+ user.following = relationship.following
+ user.muted = relationship.muting
+ user.statusnet_blocking = relationship.blocking
+ }
+ })
+ },
+ updateBlocks (state, blockedUsers) {
+ // Reset statusnet_blocking of all fetched users
+ each(state.users, (user) => { user.statusnet_blocking = false })
+ each(blockedUsers, (user) => mergeOrAdd(state.users, state.usersObject, user))
+ },
+ saveBlockIds (state, blockIds) {
state.currentUser.blockIds = blockIds
},
- saveMutes (state, muteIds) {
+ updateMutes (state, mutedUsers) {
+ // Reset muted of all fetched users
+ each(state.users, (user) => { user.muted = false })
+ each(mutedUsers, (user) => mergeOrAdd(state.users, state.usersObject, user))
+ },
+ saveMuteIds (state, muteIds) {
state.currentUser.muteIds = muteIds
},
setUserForStatus (state, status) {
@@ -122,12 +143,14 @@ export const mutations = {
}
export const getters = {
- userById: state => id =>
- state.users.find(user => user.id === id),
- userByName: state => name =>
- state.users.find(user => user.screen_name &&
- (user.screen_name.toLowerCase() === name.toLowerCase())
- )
+ findUser: state => query => {
+ const result = state.usersObject[query]
+ // In case it's a screen_name, we can try searching case-insensitive
+ if (!result && typeof query === 'string') {
+ return state.usersObject[query.toLowerCase()]
+ }
+ return result
+ }
}
export const defaultState = {
@@ -147,47 +170,59 @@ const users = {
actions: {
fetchUser (store, id) {
return store.rootState.api.backendInteractor.fetchUser({ id })
- .then((user) => store.commit('addNewUsers', [user]))
+ .then((user) => {
+ store.commit('addNewUsers', [user])
+ return user
+ })
+ },
+ fetchUserRelationship (store, id) {
+ return store.rootState.api.backendInteractor.fetchUserRelationship({ id })
+ .then((relationships) => store.commit('updateUserRelationship', relationships))
},
fetchBlocks (store) {
return store.rootState.api.backendInteractor.fetchBlocks()
.then((blocks) => {
- store.commit('saveBlocks', map(blocks, 'id'))
- store.commit('addNewUsers', blocks)
+ store.commit('saveBlockIds', map(blocks, 'id'))
+ store.commit('updateBlocks', blocks)
return blocks
})
},
- blockUser (store, id) {
- return store.rootState.api.backendInteractor.blockUser(id)
- .then((user) => store.commit('addNewUsers', [user]))
+ blockUser (store, userId) {
+ return store.rootState.api.backendInteractor.blockUser(userId)
+ .then((relationship) => {
+ store.commit('updateUserRelationship', [relationship])
+ store.commit('removeStatus', { timeline: 'friends', userId })
+ store.commit('removeStatus', { timeline: 'public', userId })
+ store.commit('removeStatus', { timeline: 'publicAndExternal', userId })
+ })
},
unblockUser (store, id) {
return store.rootState.api.backendInteractor.unblockUser(id)
- .then((user) => store.commit('addNewUsers', [user]))
+ .then((relationship) => store.commit('updateUserRelationship', [relationship]))
},
fetchMutes (store) {
return store.rootState.api.backendInteractor.fetchMutes()
- .then((mutedUsers) => {
- each(mutedUsers, (user) => { user.muted = true })
- store.commit('addNewUsers', mutedUsers)
- store.commit('saveMutes', map(mutedUsers, 'id'))
+ .then((mutes) => {
+ store.commit('updateMutes', mutes)
+ store.commit('saveMuteIds', map(mutes, 'id'))
+ return mutes
})
},
muteUser (store, id) {
- return store.state.api.backendInteractor.setUserMute({ id, muted: true })
- .then((user) => store.commit('addNewUsers', [user]))
+ return store.rootState.api.backendInteractor.muteUser(id)
+ .then((relationship) => store.commit('updateUserRelationship', [relationship]))
},
unmuteUser (store, id) {
- return store.state.api.backendInteractor.setUserMute({ id, muted: false })
- .then((user) => store.commit('addNewUsers', [user]))
+ return store.rootState.api.backendInteractor.unmuteUser(id)
+ .then((relationship) => store.commit('updateUserRelationship', [relationship]))
},
addFriends ({ rootState, commit }, fetchBy) {
return new Promise((resolve, reject) => {
const user = rootState.users.usersObject[fetchBy]
- const page = user.friendsPage || 1
- rootState.api.backendInteractor.fetchFriends({ id: user.id, page })
+ const maxId = user.lastFriendId
+ rootState.api.backendInteractor.fetchFriends({ id: user.id, maxId })
.then((friends) => {
- commit('addFriends', { id: user.id, friends, page })
+ commit('addFriends', { id: user.id, friends })
resolve(friends)
}).catch(() => {
reject()
@@ -196,10 +231,10 @@ const users = {
},
addFollowers ({ rootState, commit }, fetchBy) {
const user = rootState.users.usersObject[fetchBy]
- const page = user.followersPage || 1
- return rootState.api.backendInteractor.fetchFollowers({ id: user.id, page })
+ const maxId = user.lastFollowerId
+ return rootState.api.backendInteractor.fetchFollowers({ id: user.id, maxId })
.then((followers) => {
- commit('addFollowers', { id: user.id, followers, page })
+ commit('addFollowers', { id: user.id, followers })
return followers
})
},
@@ -292,9 +327,12 @@ const users = {
logout (store) {
store.commit('clearCurrentUser')
+ store.dispatch('disconnectFromChat')
store.commit('setToken', false)
store.dispatch('stopFetching', 'friends')
store.commit('setBackendInteractor', backendInteractorService())
+ store.dispatch('stopFetchingNotifications')
+ store.commit('resetStatuses')
},
loginUser (store, accessToken) {
return new Promise((resolve, reject) => {
@@ -319,6 +357,9 @@ const users = {
if (user.token) {
store.dispatch('setWsToken', user.token)
+
+ // Initialize the chat socket.
+ store.dispatch('initializeSocket')
}
// Start getting fresh posts.