Skip to content

Instantly share code, notes, and snippets.

@LinusBorg
Last active Jun 15, 2019
Embed
What would you like to do?
Pseudocode example for a reddit discussion about the proposed Vue 3 composition RFC
/* eslint-disable */
import {
value,
created,
beforeDestroy,
inject
} from 'vue'
import loggingService from 'services/logging'
export function usePresentation({
openAction,
closeAction,
getErrorMessage
}) {
const loadingState = value(false)
created(async () => {
loadingState.value = true
await handlePresentationAction(openAction, getErrorMessage)
loadingState.value = false
})
beforeDestory(async () => {
loadingState.value = true
await handlePresentationAction(closeAction, getErrorMessage)
loadingState.value = false
})
return loadingState
}
function handlePresentationAction(action, getErrorMessage) {
const id = inject('$route').params.presentationId
return action(id)
.catch(err => {
loggingService.error(err)
showErrorModal(err, getErrorMessage)
})
}
function showErrorModal(err) {
// open point in RFC: how do we handle prototype extensions
// like your `this.$modal`?
// Here I assume we will use inject for such features
// more heavily in the future
const modal = inject('$modal')
const router = inject('router')
const errorCode = mapRawErrorToErrorCode(err)
modal.alert({
message: getErrorMessage(errorCode),
onConfirm: () => {
router.push('/file-selection-page')
}
})
}
function mapRawErrorToErrorCode(err) { /*...*/ }
<template>
<!-- eslint-disable -->
<spinner v-if="showSpinner"></spinner>
<presentation-player v-else :page-data="$store.state.presentationPageData"></presentation-player>
</template>
<script>
/* eslint-disable */
import webSocketService from 'services/websocket'
import { usePresentation } from './base'
export default {
components: {
Spinner: require(/* */).default,
PresentationPlayer: require(/* */).default
},
setup() {
const open = (id) => {
return this.$store.dispatch('openPresentation', { id, role: 'presenter', accessToken: presenterAccessToken })
.then(() => this.$store.dispatch('selectPage', 1))
.then(() => webSocketService.send('presentation-opened', id))
}
const close = (id) => {
return this.$store.dispatch('closePresentation', { id, role: 'presenter', accessToken: presenterAccessToken })
.then(() => webSocketService.send('presentation-closed', id))
}
const getErrorMessage = (errCode) => { /* ... */ }
const showSpinner = usePresentation({
open,
close,
getErrorMessage
})
return {
showSpinner,
}
},
}
</script>
<template>
<!-- eslint-disable -->
<spinner v-if="showSpinner"></spinner>
<template v-else>
<presentation-player :page-data="$store.state.presentationPageData"></presentation-player>
<onboarding-overlay></onboarding-overlay>
</template>
</template>
<script>
/* eslint-disable */
import { usePresentation } from './base'
export default {
components: {
Spinner: require(/* */).default,
PresentationPlayer: require(/* */).default,
OnboardingOverlay: require(/* */).default
},
setup(props) {
const open = (id) => {
return this.$store.dispatch('openPresentation', { id, role: 'viewer', accessToken: viewerAccessToken })
}
const close =(id) => {
// close the presentation as a "Viewer" using fewer privileges on the presentation file
return this.$store.dispatch('closePresentation', { id, role: 'presenter', accessToken: viewerAccessToken })
}
const getErrorMessage = (errorCode) => {
return /* ... */
}
const showSpinner = usePresentation({
open,
close,
getErrorMessage
})
return {
showSpinner,
}
},
}
</script>
<style lang="scss" scoped>
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment