Simplify websocket comms for grid and improve builder socket
This commit is contained in:
parent
0bebacc741
commit
3794d8e204
|
@ -2,7 +2,7 @@ import { getFrontendStore } from "./store/frontend"
|
|||
import { getAutomationStore } from "./store/automation"
|
||||
import { getTemporalStore } from "./store/temporal"
|
||||
import { getThemeStore } from "./store/theme"
|
||||
import { getUsersStore } from "./store/users"
|
||||
import { getUserStore } from "./store/users"
|
||||
import { derived } from "svelte/store"
|
||||
import { findComponent, findComponentPath } from "./componentUtils"
|
||||
import { RoleUtils } from "@budibase/frontend-core"
|
||||
|
@ -13,7 +13,7 @@ export const store = getFrontendStore()
|
|||
export const automationStore = getAutomationStore()
|
||||
export const themeStore = getThemeStore()
|
||||
export const temporalStore = getTemporalStore()
|
||||
export const usersStore = getUsersStore()
|
||||
export const userStore = getUserStore()
|
||||
|
||||
// Setup history for screens
|
||||
export const screenHistoryStore = createHistoryStore({
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
selectedComponent,
|
||||
screenHistoryStore,
|
||||
automationHistoryStore,
|
||||
userStore,
|
||||
} from "builderStore"
|
||||
import {
|
||||
datasources,
|
||||
|
@ -85,9 +86,6 @@ const INITIAL_FRONTEND_STATE = {
|
|||
// Onboarding
|
||||
onboarding: false,
|
||||
tourNodes: null,
|
||||
|
||||
// Multi user collab
|
||||
users: [],
|
||||
}
|
||||
|
||||
export const getFrontendStore = () => {
|
||||
|
@ -122,7 +120,6 @@ export const getFrontendStore = () => {
|
|||
initialise: async pkg => {
|
||||
const { layouts, screens, application, clientLibPath, hasLock } = pkg
|
||||
websocket = createBuilderWebsocket()
|
||||
|
||||
await store.actions.components.refreshDefinitions(application.appId)
|
||||
|
||||
// Reset store state
|
||||
|
|
|
@ -1,10 +1,43 @@
|
|||
import { writable } from "svelte/store"
|
||||
import { writable, get } from "svelte/store"
|
||||
|
||||
export const getUsersStore = () => {
|
||||
const initialValue = {
|
||||
users: [],
|
||||
export const getUserStore = () => {
|
||||
const store = writable([])
|
||||
|
||||
const init = users => {
|
||||
store.set(users)
|
||||
}
|
||||
const store = writable(initialValue)
|
||||
|
||||
return store
|
||||
const updateUser = user => {
|
||||
console.log(user)
|
||||
const $users = get(store)
|
||||
if (!$users.some(x => x.id === user.id)) {
|
||||
store.set([...$users, user])
|
||||
} else {
|
||||
store.update(state => {
|
||||
const index = state.findIndex(x => x.id === user.id)
|
||||
state[index] = user
|
||||
return state.slice()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const removeUser = user => {
|
||||
store.update(state => {
|
||||
return state.filter(x => x.id !== user.id)
|
||||
})
|
||||
}
|
||||
|
||||
const reset = () => {
|
||||
store.set([])
|
||||
}
|
||||
|
||||
return {
|
||||
...store,
|
||||
actions: {
|
||||
init,
|
||||
updateUser,
|
||||
removeUser,
|
||||
reset,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
import { createWebsocket } from "@budibase/frontend-core"
|
||||
import { store } from "builderStore"
|
||||
import { userStore } from "builderStore"
|
||||
|
||||
export const createBuilderWebsocket = () => {
|
||||
const socket = createWebsocket("/socket/builder")
|
||||
|
||||
socket.on("connect", () => {
|
||||
socket.emit("get-users", null, response => {
|
||||
console.log("conntected!", response.users)
|
||||
store.update(state => ({
|
||||
...state,
|
||||
users: response.users,
|
||||
}))
|
||||
userStore.actions.init(response.users)
|
||||
})
|
||||
})
|
||||
|
||||
socket.on("user-update", user => {})
|
||||
|
||||
socket.on("user-disconnect", user => {})
|
||||
|
||||
socket.on("user-update", userStore.actions.updateUser)
|
||||
socket.on("user-disconnect", userStore.actions.removeUser)
|
||||
socket.on("connect_error", err => {
|
||||
console.log("Failed to connect to builder websocket:", err.message)
|
||||
})
|
||||
|
||||
return socket
|
||||
return {
|
||||
...socket,
|
||||
disconnect: () => {
|
||||
socket?.disconnect()
|
||||
userStore.actions.reset()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
allowDeleteRows={!isUsersTable}
|
||||
schemaOverrides={isUsersTable ? userSchemaOverrides : null}
|
||||
on:updatetable={e => tables.updateTable(e.detail)}
|
||||
showAvatars={false}
|
||||
>
|
||||
<svelte:fragment slot="controls">
|
||||
{#if isInternal}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { store, automationStore } from "builderStore"
|
||||
import { store, automationStore, userStore } from "builderStore"
|
||||
import { roles, flags } from "stores/backend"
|
||||
import { auth } from "stores/portal"
|
||||
import { TENANT_FEATURE_FLAGS, isEnabled } from "helpers/featureFlags"
|
||||
|
@ -209,7 +209,7 @@
|
|||
{/if}
|
||||
</div>
|
||||
<div class="toprightnav">
|
||||
<UserAvatars users={$store.users} />
|
||||
<UserAvatars users={$userStore} />
|
||||
<AppActions {application} />
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
export let allowExpandRows = true
|
||||
export let allowEditRows = true
|
||||
export let allowDeleteRows = true
|
||||
export let collaboration = true
|
||||
export let showAvatars = true
|
||||
|
||||
// Unique identifier for DOM nodes inside this instance
|
||||
const rand = Math.random()
|
||||
|
@ -98,7 +100,11 @@
|
|||
export const getContext = () => context
|
||||
|
||||
// Initialise websocket for multi-user
|
||||
onMount(() => createGridWebsocket(context))
|
||||
onMount(() => {
|
||||
if (collaboration) {
|
||||
return createGridWebsocket(context)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<div
|
||||
|
@ -119,7 +125,9 @@
|
|||
<RowHeightButton />
|
||||
</div>
|
||||
<div class="controls-right">
|
||||
<UserAvatars />
|
||||
{#if showAvatars}
|
||||
<UserAvatars />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{#if $loaded}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { get } from "svelte/store"
|
|||
import { createWebsocket } from "../../../utils"
|
||||
|
||||
export const createGridWebsocket = context => {
|
||||
const { rows, tableId, users, userId, focusedCellId } = context
|
||||
const { rows, tableId, users, focusedCellId } = context
|
||||
const socket = createWebsocket("/socket/grid")
|
||||
|
||||
const connectToTable = tableId => {
|
||||
|
@ -13,7 +13,6 @@ export const createGridWebsocket = context => {
|
|||
socket.emit("select-table", tableId, response => {
|
||||
// handle initial connection info
|
||||
users.set(response.users)
|
||||
userId.set(response.id)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -2,56 +2,28 @@ import { writable, get, derived } from "svelte/store"
|
|||
|
||||
export const createStores = () => {
|
||||
const users = writable([])
|
||||
const userId = writable(null)
|
||||
|
||||
// Enrich users with unique colours
|
||||
const enrichedUsers = derived(
|
||||
[users, userId],
|
||||
([$users, $userId]) => {
|
||||
return (
|
||||
$users
|
||||
.slice()
|
||||
// Place current user first
|
||||
.sort((a, b) => {
|
||||
if (a.id === $userId) {
|
||||
return -1
|
||||
} else if (b.id === $userId) {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
})
|
||||
)
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
return {
|
||||
users: {
|
||||
...users,
|
||||
subscribe: enrichedUsers.subscribe,
|
||||
},
|
||||
userId,
|
||||
users,
|
||||
}
|
||||
}
|
||||
|
||||
export const deriveStores = context => {
|
||||
const { users, userId } = context
|
||||
const { users, focusedCellId } = context
|
||||
|
||||
// Generate a lookup map of cell ID to the user that has it selected, to make
|
||||
// lookups inside cells extremely fast
|
||||
const selectedCellMap = derived(
|
||||
[users, userId],
|
||||
([$enrichedUsers, $userId]) => {
|
||||
[users, focusedCellId],
|
||||
([$users, $focusedCellId]) => {
|
||||
let map = {}
|
||||
$enrichedUsers.forEach(user => {
|
||||
if (user.focusedCellId && user.id !== $userId) {
|
||||
$users.forEach(user => {
|
||||
if (user.focusedCellId && user.focusedCellId !== $focusedCellId) {
|
||||
map[user.focusedCellId] = user
|
||||
}
|
||||
})
|
||||
return map
|
||||
},
|
||||
{}
|
||||
}
|
||||
)
|
||||
|
||||
const updateUser = user => {
|
||||
|
|
|
@ -34,7 +34,6 @@ export default class GridSocket extends Socket {
|
|||
const sockets = await this.io.in(currentRoom).fetchSockets()
|
||||
callback({
|
||||
users: sockets.map(socket => socket.data.user),
|
||||
id: user.id,
|
||||
})
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in New Issue