Skip to content

Commit

Permalink
[MIM-1356] Add part for video embed of vimeo and youtube (#2212)
Browse files Browse the repository at this point in the history
Add part for video embed of vimeo and youtube
  • Loading branch information
omsaggau authored Nov 9, 2023
1 parent 10b0183 commit 4d8b46a
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/main/resources/assets/styles/_videoEmbed.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.xp-part.video-embed {
width: 100%;
height: 0;
padding-bottom: calc(100% / (16 / 9));
position: relative;

h2 {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
}

// Need a placeholder that can fill space in edit mode if video does not show.
// After ID is added in config a page refresh is needed to see the video in edit mode
// Seems CS removes web-components when updating the page in edit mode
&::before {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: block;
height: 80%;
width: 90%;
background-color: $ssb-dark-5;
}
}
1 change: 1 addition & 0 deletions src/main/resources/assets/styles/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ $container-max-widths: (
@import "./employee";
@import "./employeeList";
@import "./project";
@import "./videoEmbed";

body {
-moz-osx-font-smoothing: grayscale;
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ declare global {
export type Table = _PartComponent<"mimir:table">
export type UpcomingReleases = _PartComponent<"mimir:upcomingReleases">
export type Variables = _PartComponent<"mimir:variables">
export type VideoEmbed = _PartComponent<"mimir:videoEmbed">
}

namespace LayoutComponent {
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/site/i18n/phrases.properties
Original file line number Diff line number Diff line change
Expand Up @@ -486,3 +486,5 @@ project.collaborators = Samarbeidspartnere
project.publications = Publikasjoner
project.projectPhrase = Prosjekt
project.model = Modell

videoEmbed.play = Spill av
2 changes: 2 additions & 0 deletions src/main/resources/site/i18n/phrases_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -486,3 +486,5 @@ project.collaborators = Collaborators
project.publications = Publications
project.projectPhrase = Project
project.model = Model

videoEmbed.play = Play video
2 changes: 2 additions & 0 deletions src/main/resources/site/i18n/phrases_nn.properties
Original file line number Diff line number Diff line change
Expand Up @@ -480,3 +480,5 @@ project.collaborators = Samarbeidspartnarar
project.publications = Publikasjonar
project.projectPhrase = Prosjekt
project.model = Modell

videoEmbed.play = Spel av
98 changes: 98 additions & 0 deletions src/main/resources/site/parts/videoEmbed/videoEmbed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { getComponent, getContent } from '/lib/xp/portal'
import { localize } from '/lib/xp/i18n'

export function get(): XP.Response {
const currentContent = getContent()
if (!currentContent) throw Error('No page found')

const locale = currentContent.language || 'no'

const component = getComponent<XP.PartComponent.VideoEmbed>()
if (!component) throw Error('No part found')

const { provider, title } = component.config
const selectedProvider = provider._selected
if (!selectedProvider) {
return missingConfig()
}

if (selectedProvider === 'vimeo') {
const value = provider?.vimeo?.value
if (!value) return missingConfig()

return {
body: renderVimeo(provider?.vimeo?.value, title, locale),
pageContributions: {
bodyEnd: [
'<script type="module" src="https://cdn.jsdelivr.net/npm/@slightlyoff/[email protected]/lite-vimeo.js"></script>',
],
},
}
} else if (selectedProvider === 'youtube') {
const value = provider?.youtube?.value
if (!value) return missingConfig()

return {
body: renderYoutube(provider?.youtube?.value, title, locale),
pageContributions: {
bodyEnd: [
'<script type="module" src="https://cdn.jsdelivr.net/npm/@justinribeiro/[email protected]/lite-youtube.js"></script>',
],
},
}
}
return {
body: missingConfig(`Ukjent provider ${selectedProvider}`),
}
}

function renderVimeo(value: string, title: string, locale: string) {
const id = extractVimeoId(value)

if (!id) return missingConfig('Ugyldig Vimeo URL / ID').body

return wrapInDiv(`
<lite-vimeo
videoid="${id}"
videoplay="${localize({ key: 'videoEmbed.play', locale })}"
videotitle="${title}"
></lite-vimeo>`)
}

function extractVimeoId(value: string) {
if (value.match(/^\d+$/)) return value

const matchFromUrl = value.match(
/(?:http:|https:|)\/\/(?:player.|www.)?vimeo\.com\/(?:video\/|embed\/|watch\?\S*v=|v\/)?(\d*)/im
)
if (!matchFromUrl) return null
return matchFromUrl[1]
}

function renderYoutube(value: string, title: string, locale: string) {
const id = extractYoutubeId(value)

if (!id) return missingConfig('Ugyldig Youtube URL / ID').body

return wrapInDiv(`
<lite-youtube
videoid="${id}"
videoplay="${localize({ key: 'videoEmbed.play', locale })}"
videotitle="${title}"
></lite-vimeo>`)
}

function extractYoutubeId(value: string) {
const matchFromUrl = value.match(/(.*?)(^|\/|v=)([a-z0-9_-]{11})(.*)?/im)

if (!matchFromUrl) return null
return matchFromUrl[3]
}

function missingConfig(message = 'Mangler konfigurasjon') {
return { body: wrapInDiv(`<h2>Videoembed: ${message}</h2>`) }
}

function wrapInDiv(value: string) {
return `<div class="xp-part video-embed">${value}</div>`
}
35 changes: 35 additions & 0 deletions src/main/resources/site/parts/videoEmbed/videoEmbed.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<part>
<display-name>Videoembed</display-name>
<form>
<input name="title" type="TextLine">
<label>Tittel på video (UU)</label>
<occurrences minimum="1" maximum="1"/>
</input>
<option-set name="provider">
<label>Platform</label>
<occurrences minimum="1" maximum="1"/>
<options minimum="1" maximum="1">
<option name="vimeo">
<label>Vimeo</label>
<items>
<input name="value" type="TextLine">
<label>URL / ID</label>
<occurrences minimum="1" maximum="1"/>
<help-text>URL eller ID til videoen på Vimeo, støttede formater: 389682203, https://www.vimeo.com/389682203, https://player.vimeo.com/video/389682203</help-text>
</input>
</items>
</option>
<option name="youtube">
<label>Youtube</label>
<items>
<input name="value" type="TextArea">
<label>URL / ID</label>
<occurrences minimum="1" maximum="1"/>
<help-text>URL eller ID til videoen på Youtube, støttede formater: eL28YW-Y06o, https://www.youtube.com/watch?v=eL28YW-Y06o, http://youtube.com/watch?v=eL28YW-Y06o, https://www.youtube.com/embed/eL28YW-Y06o, https://youtu.be/eL28YW-Y06o</help-text>
</input>
</items>
</option>
</options>
</option-set>
</form>
</part>

0 comments on commit 4d8b46a

Please sign in to comment.