Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remember whether the welcome screen was seen #2375

Merged
merged 6 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion frontend/controller/actions/identity.js
Original file line number Diff line number Diff line change
Expand Up @@ -668,5 +668,6 @@ export default (sbp('sbp/selectors/register', {
return sbp('okTurtles.eventQueue/queueEvent', 'ACTIONS-LOGIN', ['gi.actions/identity/_private/logout', ...params])
},
...encryptedAction('gi.actions/identity/saveFileDeleteToken', L('Failed to save delete tokens for the attachments.')),
...encryptedAction('gi.actions/identity/removeFileDeleteToken', L('Failed to remove delete tokens for the attachments.'))
...encryptedAction('gi.actions/identity/removeFileDeleteToken', L('Failed to remove delete tokens for the attachments.')),
...encryptedAction('gi.actions/identity/setGroupAttributes', L('Failed to set group attributes.'))
}): string[])
9 changes: 8 additions & 1 deletion frontend/controller/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@ Vue.use(Router)
*/
const homeGuard = {
guard: (to, from) => !!store.state.currentGroupId,
redirect: (to, from) => ({ path: store.getters.ourProfileActive ? '/dashboard' : '/pending-approval' })
redirect: (to, from) => ({
path:
// If we haven't accepted the invite OR we haven't clicked 'Awesome' on
// the welcome screen, redirect to the '/pending-approval' page
(store.getters.ourProfileActive && store.getters.currentIdentityState?.groups?.[store.state.currentGroupId]?.seenWelcomeScreen)
corrideat marked this conversation as resolved.
Show resolved Hide resolved
? '/dashboard'
: '/pending-approval'
})
}

const loginGuard = {
Expand Down
22 changes: 21 additions & 1 deletion frontend/model/contracts/identity.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { L } from '@common/common.js'
import sbp from '@sbp/sbp'
import { arrayOf, boolean, object, objectMaybeOf, objectOf, optional, string, stringMax, unionOf } from '~/frontend/model/contracts/misc/flowTyper.js'
import { arrayOf, boolean, object, objectMaybeOf, objectOf, optional, string, stringMax, unionOf, validatorFrom } from '~/frontend/model/contracts/misc/flowTyper.js'
import { LEFT_GROUP } from '~/frontend/utils/events.js'
import { Secret } from '~/shared/domains/chelonia/Secret.js'
import { findForeignKeysByContractID, findKeyIdByName } from '~/shared/domains/chelonia/utils.js'
Expand Down Expand Up @@ -359,6 +359,26 @@ sbp('chelonia/defineContract', {
delete state.fileDeleteTokens[manifestCid]
}
}
},
'gi.contracts/identity/setGroupAttributes': {
validate: objectOf({
groupContractID: string,
attributes: objectMaybeOf({
seenWelcomeScreen: validatorFrom((v) => v === true)
})
}),
process ({ data }, { state }) {
const { groupContractID, attributes } = data
if (!has(state.groups, groupContractID) || state.groups[groupContractID].hasLeft) {
throw new Error('Can\'t set attributes of groups you\'re not a member of')
}
if (attributes.seenWelcomeScreen) {
if (state.groups[groupContractID].seenWelcomeScreen) {
throw new Error('seenWelcomeScreen already set')
}
state.groups[groupContractID].seenWelcomeScreen = attributes.seenWelcomeScreen
}
}
}
},
methods: {
Expand Down
14 changes: 12 additions & 2 deletions frontend/views/components/GroupWelcome.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
</template>

<script>
import { mapGetters } from 'vuex'
import sbp from '@sbp/sbp'
import { mapGetters, mapState } from 'vuex'
import Avatar from '@components/Avatar.vue'
import ConfettiAnimation from '@components/confetti-animation/ConfettiAnimation.vue'

Expand All @@ -41,7 +42,8 @@ export default ({
$v: { type: Object }
},
computed: {
...mapGetters(['groupSettings'])
...mapState(['currentGroupId']),
...mapGetters(['groupSettings', 'ourIdentityContractId'])
},
data () {
return {
Expand All @@ -52,6 +54,14 @@ export default ({
toDashboard () {
if (this.isButtonClicked) return
this.isButtonClicked = true
const groupContractID = this.currentGroupId
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering whether this should be here, or if instead it should be done on the /dashboard page on onMounted. Maybe it doesn't matter.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pros of doing it here: it's only done once (for users). Pros of doing it in the /dashboard page: we don't need to change the commands.js in the tests. Cons of doing it in the /dashboard page: need to do this check every time.

sbp('gi.actions/identity/setGroupAttributes', {
contractID: this.ourIdentityContractId,
data: {
groupContractID,
attributes: { seenWelcomeScreen: true }
}
}).catch(e => console.warn('[GroupWelcome.vue] Error setting seenWelcomeScreen attribute', groupContractID, e))
this.$router.push({ path: '/dashboard' })
}
}
Expand Down
20 changes: 17 additions & 3 deletions test/cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,15 @@ Cypress.Commands.add('giLogin', (username, {
}).then(() => {
if (firstLoginAfterJoinGroup) {
const router = sbp('controller/router')
const state = sbp('state/vuex/state')
if (router.history.current.path === '/dashboard') return
return router.push({ path: '/dashboard' }) // .catch(() => {})
return sbp('gi.actions/identity/setGroupAttributes', {
contractID: state.loggedIn.identityContractID,
data: {
groupContractID: state.currentGroupId,
attributes: { seenWelcomeScreen: true }
}
}).then(() => router.push({ path: '/dashboard' })) // .catch(() => {})
}
})
})
Expand Down Expand Up @@ -331,7 +338,7 @@ Cypress.Commands.add('giCreateGroup', (name, {

const timeoutId = setTimeout(() => {
reject(new Error('[cypress] Timed out waiting for JOINED_GROUP event and active profile status'))
}, 5000)
}, 15000)

const cID = await sbp('gi.app/group/createAndSwitch', {
data: {
Expand All @@ -347,7 +354,14 @@ Cypress.Commands.add('giCreateGroup', (name, {
}).then(() => {
const router = sbp('controller/router')
if (router.history.current.path === '/dashboard') return
return router.push({ path: '/dashboard' })
const state = sbp('state/vuex/state')
return sbp('gi.actions/identity/setGroupAttributes', {
contractID: state.loggedIn.identityContractID,
data: {
groupContractID: state.currentGroupId,
attributes: { seenWelcomeScreen: true }
}
}).then(() => router.push({ path: '/dashboard' }))
corrideat marked this conversation as resolved.
Show resolved Hide resolved
})
})
cy.url().should('eq', `${API_URL}/app/dashboard`)
Expand Down