This commit is contained in:
j3d1 2026-08-19 16:45:20 +02:00
parent 6d2167ac66
commit 4787acd8eb
23 changed files with 1241 additions and 25 deletions

View file

@ -72,6 +72,8 @@ export default createStore({
remember: false,
friends: [],
friendProfiles: {},
groups: [],
groupInvites: [],
item_map: {},
home_servers: null,
all_friends_servers: null,
@ -104,6 +106,12 @@ export default createStore({
setFriendProfiles(state, profiles) {
state.friendProfiles = profiles;
},
setGroups(state, groups) {
state.groups = groups;
},
setGroupInvites(state, invites) {
state.groupInvites = invites;
},
setHomeServers(state, home_servers) {
state.home_servers = home_servers;
},
@ -479,6 +487,75 @@ export default createStore({
const servers = await dispatch('getHomeServers')
return await servers.delete(getters.signAuth, '/api/friends/' + id + '/')
},
// Groups are only ever hosted on the current user's own home backend for now (see
// docs/design-in-progress/groups-mvp.md) - a remote member's edit/delete rights on a
// group-owned item work regardless, but "My Groups" has no way to discover a group hosted
// elsewhere, so every group action below talks to getHomeServers rather than resolving a
// per-group domain.
async fetchGroups({commit, dispatch, getters}) {
const servers = await dispatch('getHomeServers')
const data = await servers.get(getters.signAuth, '/api/groups/')
commit('setGroups', data)
return data
},
async fetchGroup({dispatch, getters}, {id}) {
const servers = await dispatch('getHomeServers')
return await servers.get(getters.signAuth, '/api/groups/' + id + '/')
},
async createGroup({dispatch, getters}, {name}) {
const servers = await dispatch('getHomeServers')
return await servers.post(getters.signAuth, '/api/groups/', {name})
},
async removeGroupMember({dispatch, getters}, {groupId, identityId}) {
const servers = await dispatch('getHomeServers')
return await servers.delete(getters.signAuth, '/api/groups/' + groupId + '/members/' + identityId + '/')
},
async fetchGroupInvites({commit, dispatch, getters}) {
const servers = await dispatch('getHomeServers')
const data = await servers.get(getters.signAuth, '/api/groupinvites/')
commit('setGroupInvites', data)
return data
},
async inviteToGroup({state, dispatch, getters}, {groupId, groupHandle, invitee}) {
const home_servers = await dispatch('getHomeServers')
const home_reply = await home_servers.post(
getters.signAuth, '/api/groups/' + groupId + '/invites/', {invitee})
if (!home_reply.secret) {
return false
}
const invitee_servers = await dispatch('getFriendServers', {username: invitee})
await invitee_servers.post(getters.signAuth, '/api/groupinvites/', {
group: groupHandle,
inviter: state.user,
inviter_key: nacl.to_hex(state.keypair.signPk),
invitee,
secret: home_reply.secret
})
return true
},
async acceptGroupInvite({state, dispatch, getters}, invite) {
const group_domain = invite.group.split('@')[1]
const group_servers = await dispatch('getFriendServers', {username: 'x@' + group_domain})
await group_servers.post(getters.signAuth, '/api/group_invites/accept/', {
group: invite.group,
invitee: state.user,
invitee_key: nacl.to_hex(state.keypair.signPk),
secret: invite.secret
})
const home_servers = await dispatch('getHomeServers')
await home_servers.delete(getters.signAuth, '/api/groupinvites/' + invite.id + '/')
return true
},
async declineGroupInvite({dispatch, getters}, invite) {
const servers = await dispatch('getHomeServers')
return await servers.delete(getters.signAuth, '/api/groupinvites/' + invite.id + '/')
},
async fetchGroupInventoryItems({commit, dispatch, getters}, groupId) {
const servers = await dispatch('getHomeServers')
const items = await servers.get(getters.signAuth, '/api/inventory_items/?group=' + groupId)
commit('setInventoryItems', {url: '/group/' + groupId, items})
return items
},
async fetchFiles({state, commit, dispatch, getters}) {
if (state.last_load.files > Date.now() - 1000 * 60 * 60 * 24) {
return state.files
@ -708,6 +785,7 @@ export default createStore({
inventory_items(state) {
return state.item_map['/'] || []
},
groupInventoryItems: (state) => (groupId) => state.item_map['/group/' + groupId] || [],
loaded_items(state) {
return Object.entries(state.item_map).reduce((acc, [url, items]) => {
return acc.concat(items)