Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
corrideat committed Oct 31, 2024
1 parent 332e8cb commit 6fd370f
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 55 deletions.
3 changes: 2 additions & 1 deletion frontend/controller/actions/group.js
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,8 @@ export default (sbp('sbp/selectors/register', {
}
}

sbp('okTurtles.events/emit', JOINED_GROUP, { identityContractID: userID, contractID: params.contractID })
await sbp('chelonia/contract/wait', params.contractID)
sbp('okTurtles.events/emit', JOINED_GROUP, { identityContractID: userID, groupContractID: params.contractID })
// We don't have the secret keys and we're not waiting for OP_KEY_SHARE
// This means that we've been removed from the group
} else if (!hasSecretKeys && !pendingKeyShares) {
Expand Down
1 change: 1 addition & 0 deletions frontend/controller/app/identity.js
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ export default (sbp('sbp/selectors/register', {
}

// updating the 'lastLoggedIn' field is done as a periodic notification
await sbp('chelonia/contract/sync', identityContractID)
return identityContractID
} catch (e) {
console.error('gi.app/identity/login failed!', e)
Expand Down
2 changes: 1 addition & 1 deletion frontend/controller/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const groupGuard = {
const pendingApprovalGuard = {
guard: (to, from) => store.state.currentGroupId && !store.getters.ourProfileActive,
redirect: (to, from) => {
console.error('@@@@redirect pa guard', store.state.currentGroupId, !store.getters.ourProfileActive)
console.error('@@@@redirect pa guard', store.state.currentGroupId, !store.getters.ourProfileActive, to, from, new Error().stack)
return ({ path: '/pending-approval' })
}
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/model/chatroom/getters.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const getters: { [x: string]: (state: Object, getters: { [x: string]: any }, roo
if (shouldFindDMToMyself) return chatRoomSettings.isDMToMyself
else {
const cPartners = chatRoomSettings.partners.map(partner => partner.contractID)
return cPartners.length === partners.length && union(cPartners, partners).length === partners.length
return cPartners.length === partners.length && union(cPartners, ((partners: any): string[])).length === partners.length
}
})
}
Expand Down
1 change: 1 addition & 0 deletions frontend/model/notifications/messageReceivePostEffect.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ async function messageReceivePostEffect ({
icon,
path
})
// `MESSAGE_RECEIVE` should be forwarded to the tab
shouldSoundMessage && sbp('okTurtles.events/emit', MESSAGE_RECEIVE)
}

Expand Down
1 change: 1 addition & 0 deletions shared/domains/chelonia/chelonia.js
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,7 @@ export default (sbp('sbp/selectors/register', {
},
// resolves when all pending actions for these contractID(s) finish
'chelonia/contract/wait': function (contractIDs?: string | string[]): Promise<*> {
console.error('@@@wait', new Error().stack)
const listOfIds = contractIDs
? (typeof contractIDs === 'string' ? [contractIDs] : contractIDs)
: Object.keys(sbp(this.config.stateSelector).contracts)
Expand Down
90 changes: 47 additions & 43 deletions shared/domains/chelonia/localSelectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,57 +28,61 @@ export default (sbp('sbp/selectors/register', {
reactiveSet: Function,
reactiveDel: Function
}) => {
sbp('okTurtles.events/on', EVENT_HANDLED, async (contractID, message) => {
const { contractState, cheloniaState } = await sbp('chelonia/contract/fullState', contractID)
const externalState = sbp(stateSelector)
if (cheloniaState) {
if (!externalState.contracts) {
reactiveSet(externalState, 'contracts', Object.create(null))
sbp('okTurtles.events/on', EVENT_HANDLED, (contractID, message) => {
sbp('okTurtles.eventQueue/queueEvent', EVENT_HANDLED, async () => {
const { contractState, cheloniaState } = await sbp('chelonia/contract/fullState', contractID)
const externalState = sbp(stateSelector)
if (cheloniaState) {
if (!externalState.contracts) {
reactiveSet(externalState, 'contracts', Object.create(null))
}
reactiveSet(externalState.contracts, contractID, cloneDeep(cheloniaState))
} else if (externalState.contracts) {
reactiveDel(externalState.contracts, contractID)
}
if (contractState) {
reactiveSet(externalState, contractID, cloneDeep(contractState))
} else {
reactiveDel(externalState, contractID)
}
reactiveSet(externalState.contracts, contractID, cloneDeep(cheloniaState))
} else if (externalState.contracts) {
reactiveDel(externalState.contracts, contractID)
}
if (contractState) {
reactiveSet(externalState, contractID, cloneDeep(contractState))
} else {
reactiveDel(externalState, contractID)
}

// This EVENT_HANDLED_READY event lets the current context (e.g., tab)
// know that an event has been processed _and_ committed to the state
// (as opposed to EVENT_HANDLED, which means the event was processed by
// _Chelonia_ but state changes may not be reflected in the current tab
// yet).
sbp('okTurtles.events/emit', EVENT_HANDLED_READY, contractID, message)
// This EVENT_HANDLED_READY event lets the current context (e.g., tab)
// know that an event has been processed _and_ committed to the state
// (as opposed to EVENT_HANDLED, which means the event was processed by
// _Chelonia_ but state changes may not be reflected in the current tab
// yet).
sbp('okTurtles.events/emit', EVENT_HANDLED_READY, contractID, message)
})
})

sbp('okTurtles.events/on', CONTRACTS_MODIFIED, async (subscriptionSet) => {
const states = await sbp('chelonia/contract/fullState', subscriptionSet)
const vuexState = sbp('state/vuex/state')
sbp('okTurtles.events/on', CONTRACTS_MODIFIED, (subscriptionSet) => {
sbp('okTurtles.eventQueue/queueEvent', EVENT_HANDLED, async () => {
const states = await sbp('chelonia/contract/fullState', subscriptionSet)
const vuexState = sbp('state/vuex/state')

if (!vuexState.contracts) {
reactiveSet(vuexState, 'contracts', Object.create(null))
}
if (!vuexState.contracts) {
reactiveSet(vuexState, 'contracts', Object.create(null))
}

const oldContracts = Object.keys(vuexState.contracts)
const oldContractsToRemove = oldContracts.filter(x => !subscriptionSet.includes(x))
const newContracts = subscriptionSet.filter(x => !oldContracts.includes(x))
const oldContracts = Object.keys(vuexState.contracts)
const oldContractsToRemove = oldContracts.filter(x => !subscriptionSet.includes(x))
const newContracts = subscriptionSet.filter(x => !oldContracts.includes(x))

oldContractsToRemove.forEach(contractID => {
reactiveDel(vuexState.contracts, contractID)
reactiveDel(vuexState, contractID)
})
for (const contractID of newContracts) {
const { contractState, cheloniaState } = states[contractID]
if (cheloniaState) {
reactiveSet(vuexState.contracts, contractID, cloneDeep(cheloniaState))
oldContractsToRemove.forEach(contractID => {
reactiveDel(vuexState.contracts, contractID)
reactiveDel(vuexState, contractID)
})
for (const contractID of newContracts) {
const { contractState, cheloniaState } = states[contractID]
if (cheloniaState) {
reactiveSet(vuexState.contracts, contractID, cloneDeep(cheloniaState))
}
if (contractState) {
reactiveSet(vuexState, contractID, cloneDeep(contractState))
}
}
if (contractState) {
reactiveSet(vuexState, contractID, cloneDeep(contractState))
}
}
sbp('okTurtles.events/emit', CONTRACTS_MODIFIED_READY, subscriptionSet)
sbp('okTurtles.events/emit', CONTRACTS_MODIFIED_READY, subscriptionSet)
})
})
}
}): string[])
24 changes: 15 additions & 9 deletions test/cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,16 +242,19 @@ Cypress.Commands.add('giLogin', (username, {
cy.getByDT('app').should('have.attr', 'data-ready', 'true')

cy.window().its('sbp').then(sbp => {
const joinedGroupPromise = new Promise((resolve) => {
const joinedGroupPromise = new Promise((resolve, reject) => {
if (firstLoginAfterJoinGroup) {
const eventHandler = ({ groupContractID }) => {
sbp('okTurtles.events/off', JOINED_GROUP, eventHandler)
const invervalId = setInterval(() => {
sbp('chelonia/contract/retain', groupContractID, { ephemeral: true }).then(() => new Promise(resolve => setTimeout(resolve, 1000))).then(() => {
if (sbp('state/vuex/getters').ourProfileActive) {
clearInterval(invervalId)
resolve(sbp('chelonia/contract/wait', groupContractID))
resolve()
} else {
reject(new Error('Expected our profile to be active (giLogin)'))
}
}, 5)
}).finally(() => {
sbp('chelonia/contract/release', groupContractID, { ephemeral: true })
})
}

sbp('okTurtles.events/on', JOINED_GROUP, eventHandler)
Expand Down Expand Up @@ -352,13 +355,16 @@ Cypress.Commands.add('giCreateGroup', (name, {
const eventHandler = ({ groupContractID }) => {
if (groupContractID === cID) {
sbp('okTurtles.events/off', JOINED_GROUP, eventHandler)
const invervalId = setInterval(() => {
sbp('chelonia/contract/retain', groupContractID, { ephemeral: true }).then(() => sbp('okTurtles.eventQueue/queueEvent', 'event-handled', Boolean)).then(() => {
if (sbp('state/vuex/state').currentGroupId === groupContractID && sbp('state/vuex/getters').ourProfileActive) {
clearInterval(invervalId)
clearTimeout(timeoutId)
resolve(sbp('chelonia/contract/wait', groupContractID))
resolve()
} else {
reject(new Error('Expected our profile to be active (giCreateGroup)'))
}
}, 5)
}).finally(() => {
sbp('chelonia/contract/release', groupContractID, { ephemeral: true })
})
}
}
sbp('okTurtles.events/on', JOINED_GROUP, eventHandler)
Expand Down

0 comments on commit 6fd370f

Please sign in to comment.