Merge remote-tracking branch 'upstream/develop' into mastoapi/actions

* upstream/develop: (87 commits)
  review
  Update attachment normalizer
  Add fallback for attachments uploaded via the other platforms
  Get correct mimetype through entity_normalizer
  Set default parameter
  Switch to mastoapi for posting status and uploading media
  Revert changes
  prevent text pasting if image is pasted
  remove border radius of suggested emojis
  #450 - dispatch login after saved state is loaded
  #448 - fix timeline fetch error when status text is null
  #451 - add class to username span
  No need to fetch mutes on load anymore 🙌
  switch to mastoapi
  switch to mastoapi
  masto api sends muted property now
  No need to fetch user data using old api anymore 🎉
  Switch to mastoapi
  reactivity fixes
  less hackery, more direct usage of mastoapi
  ...
This commit is contained in:
Henry Jameson 2019-03-25 21:12:15 +02:00
commit 0ffd43954e
86 changed files with 1499 additions and 741 deletions

View file

@ -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)
})

View file

@ -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,

View file

@ -18,6 +18,7 @@ const defaultState = {
scopeOptionsEnabled: true,
formattingOptionsEnabled: false,
alwaysShowSubjectInput: true,
hideMutedPosts: false,
collapseMessageWithSubject: false,
hidePostStats: false,
hideUserStats: false,
@ -48,7 +49,11 @@ const defaultState = {
// Html stuff
instanceSpecificPanelContent: '',
tos: ''
tos: '',
// Version Information
backendVersion: '',
frontendVersion: ''
}
const instance = {

View file

@ -1,4 +1,5 @@
import { remove, slice, each, find, maxBy, minBy, merge, first, 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'
@ -72,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}
@ -80,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}
}
}
@ -333,6 +336,7 @@ export const mutations = {
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 })
},

View file

@ -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 }
}
@ -91,10 +91,31 @@ export const mutations = {
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,39 +170,51 @@ 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) => {
@ -292,6 +327,7 @@ const users = {
logout (store) {
store.commit('clearCurrentUser')
store.dispatch('disconnectFromChat')
store.commit('setToken', false)
store.dispatch('stopFetching', 'friends')
store.commit('setBackendInteractor', backendInteractorService())
@ -321,6 +357,9 @@ const users = {
if (user.token) {
store.dispatch('setWsToken', user.token)
// Initialize the chat socket.
store.dispatch('initializeSocket')
}
// Start getting fresh posts.