Skip to content
This repository has been archived by the owner on Sep 8, 2023. It is now read-only.

Commit

Permalink
Implement reference preview rendering
Browse files Browse the repository at this point in the history
Signed-off-by: Julius Härtl <[email protected]>
  • Loading branch information
juliusknorr committed Aug 10, 2022
1 parent f793ecb commit 0138d44
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 1 deletion.
63 changes: 63 additions & 0 deletions src/ReferenceWidget.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<template>
<div>
<div v-if="noAccess">
<p>You may not have acces to this reference!</p>
</div>

<div v-else-if="reference && hasCustomWidget" ref="customWidget" class="widget-custom" />

<div v-else-if="reference && reference.openGraphObject && !hasCustomWidget" class="widget-default">
<div v-if="reference.openGraphObject.thumb" class="widget-default--image" :style="{ 'backgroundImage': 'url(' + reference.openGraphObject.thumb + ')' }" />
<p class="widget-default--title">
<strong>{{ reference.openGraphObject.name }}</strong>
</p>
<p class="widget-default--description">
{{ reference.openGraphObject.description }}
</p>
<p class="widget-default--link">
<a :href="reference.openGraphObject.link" target="_blank">{{ reference.openGraphObject.link }}</a>
</p>
</div>
</div>
</template>
<script>
import { renderWidget, isWidgetRegistered } from './widgets.js'
export default {
name: 'ReferenceWidget',
props: {
reference: {
type: Object
}
},
data() {
return {}
},
computed: {
hasCustomWidget() {
return isWidgetRegistered(this.reference.richObjectType)
},
noAccess() {
return this.reference && !this.reference.accessible
}
},
mounted() {
this.renderWidget()
},
methods: {
renderWidget() {
console.log(this.firstReference)
if (this.$refs.customWidget) {
this.$refs.customWidget.innerHTML = ''
}
if (this?.reference?.richObjectType === 'open-graph') {
return
}
this.$nextTick(() => {
// Waiting for the ref to become available
renderWidget(this.reference.richObjectType, this.reference.richObject, this.$refs.customWidget)
})
}
}
}
</script>
88 changes: 88 additions & 0 deletions src/References.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<template>
<div :class="{'icon-loading': loading }">
<div v-for="reference in displayedReferences" :key="reference.openGraphObject.id">
<ReferenceWidget :reference="reference" />
</div>
</div>
</template>
<script>
import ReferenceWidget from './ReferenceWidget.vue'
export default {
name: 'References',
components: { ReferenceWidget },
props: {
text: {
type: String,
default: ''
},
referenceData: {
type: Object
},
limit: {
type: Number,
default: 5
}
},
data() {
return {
references: null,
loading: true
}
},
computed: {
firstReference() {
return this.references ? Object.values(this.references)[0] : null
},
displayedReferences() {
return this.references ? Object.values(this.references).slice(0, this.limit) : null
},
hasCustomWidget() {
return (reference) => !!widgets[reference.richObjectType]
},
noAccess() {
return (reference) => reference && !reference.accessible
}
},
watch: {
text: 'fetch'
},
mounted() {
this.fetch()
},
methods: {
fetch() {
this.loading = true
if (this.referenceData) {
this.references = this.referenceData
this.loading = false
return
}
fetch('http://nextcloud.dev.local/ocs/v2.php/references/extract?format=json', {
method: 'POST',
body: JSON.stringify({
text: this.text,
resolve: true,
requesttoken: window.oc_requesttoken,
limit: this.limit
}),
headers: {
'Content-Type': 'application/json',
requesttoken: window.oc_requesttoken
}
})
.then(response => response.json())
.then(json => {
console.log(json)
this.references = json.ocs.data.references
this.loading = false
})
.catch(error => {
console.error(error)
this.loading = false
})
}
}
}
</script>
21 changes: 20 additions & 1 deletion src/RichText.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
-->

<script>
import References from './References.vue'
import unified from 'unified'
import markdown from 'remark-parse'
import breaks from 'remark-breaks'
Expand Down Expand Up @@ -64,6 +65,9 @@ function pluginComponent() {
export default {
name: 'RichText',
components: {
References
},
props: {
text: {
type: String,
Expand All @@ -75,6 +79,14 @@ export default {
return {}
}
},
referenceLimit: {
type: Number,
default: 0
},
/** Provide data upfront to avoid extra http request */
references: {
type: Object
},
markdownCssClasses: {
type: Object,
default: () => {
Expand Down Expand Up @@ -219,7 +231,14 @@ export default {
.processSync(this.text)
.result
return h('div', { class: 'rich-text--wrapper' }, [renderedMarkdown])
return h('div', { class: 'rich-text--wrapper' }, [
renderedMarkdown,
this.referenceLimit > 0
? h('div', { class: 'rich-text--reference-widget' }, [
h(References, { props: { text: this.text, referenceData: this.references } })
])
: null
])
}
}
</script>
Expand Down
45 changes: 45 additions & 0 deletions src/widgets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

// TODO globally expose
const widgets = {}

const registerWidget = (id, callback) => {
if (widgets[id]) {
console.error('Widget for id ' + id + ' already registered')
return
}

widgets[id] = {
id,
callback
}
}

const renderWidget = (id, richObjectData, el) => {
if (id === 'open-graph') {
return
}

if (!widgets[id]) {
console.error('Widget for id ' + id + ' not registered')
return
}

widgets[id].callback(richObjectData, el)
}

const isWidgetRegistered = (id) => {
return !!widgets[id]
}

registerWidget('file', (richObjectData, el) => {
const node = document.createElement('strong')
const textnode = document.createTextNode('Custom file widget: ' + richObjectData.name + '')
node.appendChild(textnode)
el.appendChild(node)
})

export {
registerWidget,
renderWidget,
isWidgetRegistered
}

0 comments on commit 0138d44

Please sign in to comment.