diff --git a/CHANGELOG.md b/CHANGELOG.md index a8d34c35..ef522ca8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ If you haven't upgraded to v6.0.0 yet, please read v6.0.0 changelog first. ### New Features +### New features + +* Share chat link popup: add an option to generate an iframe. + ### Changes * Minimum Peertube version is now v4.2.0. diff --git a/client/videowatch/share.ts b/client/videowatch/share.ts index d6e1b251..0d930f67 100644 --- a/client/videowatch/share.ts +++ b/client/videowatch/share.ts @@ -5,12 +5,15 @@ import { getIframeUri, UriOptions } from './uri' import { isAutoColorsAvailable } from 'shared/lib/autocolors' interface ShareForm { + shareString: HTMLInputElement + openButton: HTMLButtonElement + copyButton: HTMLButtonElement readonly: HTMLInputElement withscroll: HTMLInputElement transparent: HTMLInputElement readonlyOptions: HTMLElement - url: HTMLInputElement autoColors?: HTMLInputElement + generateIframe: HTMLInputElement } async function shareChatUrl (registerOptions: RegisterClientOptions, settings: any, video: Video): Promise { @@ -26,7 +29,9 @@ async function shareChatUrl (registerOptions: RegisterClientOptions, settings: a labelCopied, labelError, labelOpen, - labelAutocolors + labelAutocolors, + labelGenerateIframe, + labelChatFor ] = await Promise.all([ peertubeHelpers.translate('Share chat link'), peertubeHelpers.translate('Read-only'), @@ -38,7 +43,9 @@ async function shareChatUrl (registerOptions: RegisterClientOptions, settings: a peertubeHelpers.translate('Link copied'), peertubeHelpers.translate('Error'), peertubeHelpers.translate('Open'), - peertubeHelpers.translate('Use current theme colors') + peertubeHelpers.translate('Use current theme colors'), + peertubeHelpers.translate('Generate an iframe to embed the chat in a website'), + peertubeHelpers.translate('Chat for live stream:') ]) const defaultUri = getIframeUri(registerOptions, settings, video) @@ -53,24 +60,24 @@ async function shareChatUrl (registerOptions: RegisterClientOptions, settings: a container.classList.add('peertube-plugin-livechat-shareurl-modal') - const divUrl = document.createElement('div') - divUrl.classList.add('livechat-shareurl-copy') - const url = document.createElement('input') - url.setAttribute('type', 'text') - url.setAttribute('readonly', '') - url.setAttribute('autocomplete', 'off') - url.setAttribute('placeholder', '') - url.classList.add('form-control', 'readonly') - divUrl.append(url) - const copy = document.createElement('button') - copy.classList.add('btn', 'btn-outline-secondary', 'text-uppercase') - copy.textContent = labelCopy - divUrl.append(copy) - const open = document.createElement('button') - open.classList.add('btn', 'btn-outline-secondary', 'text-uppercase') - open.textContent = labelOpen - divUrl.append(open) - container.append(divUrl) + const divShareString = document.createElement('div') + divShareString.classList.add('livechat-shareurl-copy') + const shareString = document.createElement('input') + shareString.setAttribute('type', 'text') + shareString.setAttribute('readonly', '') + shareString.setAttribute('autocomplete', 'off') + shareString.setAttribute('placeholder', '') + shareString.classList.add('form-control', 'readonly') + divShareString.append(shareString) + const copyButton = document.createElement('button') + copyButton.classList.add('btn', 'btn-outline-secondary', 'text-uppercase') + copyButton.textContent = labelCopy + divShareString.append(copyButton) + const openButton = document.createElement('button') + openButton.classList.add('btn', 'btn-outline-secondary', 'text-uppercase') + openButton.textContent = labelOpen + divShareString.append(openButton) + container.append(divShareString) const divTips = document.createElement('div') divTips.textContent = tipsOBS @@ -115,6 +122,13 @@ async function shareChatUrl (registerOptions: RegisterClientOptions, settings: a divCustom.append(label) } + const generateIframe = document.createElement('input') + generateIframe.setAttribute('type', 'checkbox') + const generateIframeLabelEl = document.createElement('label') + generateIframeLabelEl.textContent = labelGenerateIframe + generateIframeLabelEl.prepend(generateIframe) + divCustom.append(generateIframeLabelEl) + readonly.onclick = () => { renderContent(container) } @@ -124,39 +138,47 @@ async function shareChatUrl (registerOptions: RegisterClientOptions, settings: a transparent.onclick = () => { renderContent(container) } - if (autoColors) { autoColors.onclick = () => { renderContent(container) } } - - url.onclick = () => { - url.select() - url.setSelectionRange(0, 99999) /* For mobile devices */ + generateIframe.onclick = () => { + renderContent(container) } - copy.onclick = () => { - url.select() - url.setSelectionRange(0, 99999) /* For mobile devices */ - navigator.clipboard.writeText(url.value).then(() => { + shareString.onclick = () => { + shareString.select() + shareString.setSelectionRange(0, 99999) /* For mobile devices */ + } + + copyButton.onclick = () => { + shareString.select() + shareString.setSelectionRange(0, 99999) /* For mobile devices */ + navigator.clipboard.writeText(shareString.value).then(() => { peertubeHelpers.notifier.success(labelCopied) }, () => { peertubeHelpers.notifier.error(labelError) }) } - open.onclick = () => { - window.open(url.value) + openButton.onclick = () => { + // Don't open the url if it is an iframe! + if (shareString.value.startsWith('http')) { + window.open(shareString.value) + } } form = { + shareString, + copyButton, + openButton, readonly, withscroll, transparent, readonlyOptions, - url, - autoColors + autoColors, + generateIframe } restore(form) } @@ -185,8 +207,24 @@ async function shareChatUrl (registerOptions: RegisterClientOptions, settings: a form.transparent.disabled = true form.readonlyOptions.classList.add('livechat-shareurl-custom-readonly-disabled') } - const iframeUri = getIframeUri(registerOptions, settings, video, uriOptions) - form.url.setAttribute('value', iframeUri ?? '') + let shareStringValue = getIframeUri(registerOptions, settings, video, uriOptions) + if (form.generateIframe.checked) { + form.openButton.disabled = true + if (shareStringValue) { + // To properly escape all attributes, we are constructing an HTMLIframeElement + const iframe = document.createElement('iframe') + iframe.setAttribute('src', shareStringValue) + iframe.setAttribute('title', labelChatFor + ' ' + video.name) + iframe.setAttribute('sandbox', 'allow-same-origin allow-scripts allow-popups allow-forms') + iframe.setAttribute('width', '560') + iframe.setAttribute('height', '315') + iframe.setAttribute('frameborder', '0') + shareStringValue = iframe.outerHTML + } + } else { + form.openButton.disabled = false + } + form.shareString.setAttribute('value', shareStringValue ?? '') } function save (form: ShareForm): void { @@ -198,7 +236,8 @@ async function shareChatUrl (registerOptions: RegisterClientOptions, settings: a readonly: !!form.readonly.checked, withscroll: !!form.withscroll.checked, transparent: !!form.transparent.checked, - autocolors: !!form.autoColors?.checked + autocolors: !!form.autoColors?.checked, + generateIframe: !!form.generateIframe.checked } window.localStorage.setItem('peertube-plugin-livechat-shareurl', JSON.stringify(v)) } @@ -223,6 +262,7 @@ async function shareChatUrl (registerOptions: RegisterClientOptions, settings: a if (form.autoColors) { form.autoColors.checked = !!v.autocolors } + form.generateIframe.checked = !!v.generateIframe } catch (err) { logger.error(err as string) } diff --git a/languages/ca.json b/languages/ca.json index e6231209..a27a0379 100644 --- a/languages/ca.json +++ b/languages/ca.json @@ -13,5 +13,7 @@ "Link copied": false, "Error": false, "Open": false, - "Use current theme colors": false + "Use current theme colors": false, + "Generate an iframe to embed the chat in a website": false, + "Chat for live stream": false } diff --git a/languages/de.json b/languages/de.json index 7e031f5f..679e7b9c 100644 --- a/languages/de.json +++ b/languages/de.json @@ -13,5 +13,7 @@ "Link copied": "Link kopiert", "Error": "Fehler", "Open": "Öffnen", - "Use current theme colors": "Die derzeitigen Themenfarben nutzen" + "Use current theme colors": "Die derzeitigen Themenfarben nutzen", + "Generate an iframe to embed the chat in a website": false, + "Chat for live stream": false } diff --git a/languages/eo.json b/languages/eo.json index 3c15c9a9..98c4c540 100644 --- a/languages/eo.json +++ b/languages/eo.json @@ -13,5 +13,7 @@ "Link copied": "Ligilo kopiata", "Error": "Eraro", "Open": "Malfermi", - "Use current theme colors": "Uzi koloroj el la nuna etoso" + "Use current theme colors": "Uzi koloroj el la nuna etoso", + "Generate an iframe to embed the chat in a website": false, + "Chat for live stream": false } diff --git a/languages/es.json b/languages/es.json index 28c4bd04..9ed3bf5b 100644 --- a/languages/es.json +++ b/languages/es.json @@ -13,5 +13,7 @@ "Link copied": "Enlace copiado", "Error": "Error", "Open": "Abrir", - "Use current theme colors": "Utilizar los colores del tema actual" + "Use current theme colors": "Utilizar los colores del tema actual", + "Generate an iframe to embed the chat in a website": false, + "Chat for live stream": false } diff --git a/languages/eu.json b/languages/eu.json index 8cdd2bff..b275b0f6 100644 --- a/languages/eu.json +++ b/languages/eu.json @@ -13,5 +13,7 @@ "Link copied": "Esteka kopiatu da", "Error": "Errorea", "Open": "Ireki", - "Use current theme colors": "Erabili uneko itxuraren koloreak" + "Use current theme colors": "Erabili uneko itxuraren koloreak", + "Generate an iframe to embed the chat in a website": false, + "Chat for live stream": false } diff --git a/languages/fr.json b/languages/fr.json index 0da1f632..af3c565e 100644 --- a/languages/fr.json +++ b/languages/fr.json @@ -13,5 +13,7 @@ "Link copied": "Lien copié", "Error": "Erreur", "Open": "Ouvrir", - "Use current theme colors": "Utiliser les couleurs du thème courant" + "Use current theme colors": "Utiliser les couleurs du thème courant", + "Generate an iframe to embed the chat in a website": "Générer une iframe pour intégrer le tchat dans un site web", + "Chat for live stream:": "Tchat pour le direct :" } diff --git a/languages/it.json b/languages/it.json index a82e0e4f..46389476 100644 --- a/languages/it.json +++ b/languages/it.json @@ -13,5 +13,7 @@ "Link copied": false, "Error": false, "Open": false, - "Use current theme colors": false + "Use current theme colors": false, + "Generate an iframe to embed the chat in a website": false, + "Chat for live stream": false } diff --git a/languages/ja.json b/languages/ja.json index 9221c860..785f64ca 100644 --- a/languages/ja.json +++ b/languages/ja.json @@ -13,5 +13,7 @@ "Link copied": "リンクをコピーしました", "Error": "エラー", "Open": "開く", - "Use current theme colors": "現在のテーマカラーを使用する" + "Use current theme colors": "現在のテーマカラーを使用する", + "Generate an iframe to embed the chat in a website": false, + "Chat for live stream": false } diff --git a/languages/oc.json b/languages/oc.json index 0fa3d728..206b74a5 100644 --- a/languages/oc.json +++ b/languages/oc.json @@ -13,5 +13,7 @@ "Link copied": "Ligam copiat", "Error": "Error", "Open": "Dobrir", - "Use current theme colors": "Utilizar las colors del tèma actual" + "Use current theme colors": "Utilizar las colors del tèma actual" , + "Generate an iframe to embed the chat in a website": false, + "Chat for live stream": false } diff --git a/languages/pl.json b/languages/pl.json index 1c07374a..08f4b369 100644 --- a/languages/pl.json +++ b/languages/pl.json @@ -13,5 +13,7 @@ "Link copied": false, "Error": false, "Open": false, - "Use current theme colors": false + "Use current theme colors": false, + "Generate an iframe to embed the chat in a website": false, + "Chat for live stream": false }