diff --git a/README.md b/README.md
index b6f95bbd..9c0c9d1d 100644
--- a/README.md
+++ b/README.md
@@ -170,3 +170,7 @@ There is an example file [here](documentation/examples/nginx/site.conf).
NB: this example files also serve the static html files with converseJS.
NB: it is recommanded to change ```Access-Control-Allow-Origin``` to something else that ```"*"```.
+
+## Credits
+
+Thanks to David Revoy for his work on Peertube's mascot, [Sepia](https://www.davidrevoy.com/index.php?tag/peertube).
diff --git a/assets/style.css b/assets/style.css
index 8f0c0081..42f448bb 100644
--- a/assets/style.css
+++ b/assets/style.css
@@ -1,4 +1,47 @@
-iframe.peertube-plugin-livechat {
+#peertube-plugin-livechat-container {
+ display: flex;
+ flex-direction: column;
+}
+
+.peertube-plugin-livechat-buttons {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: flex-end;
+}
+
+.peertube-plugin-livechat-button {
+ border: 1px solid black;
+ background-color: var(--mainBackgroundColor);
+ min-height: 32px;
+ min-width: 32px;
+ padding: 0;
+}
+
+.peertube-plugin-livechat-button-icon {
+ background-size: 32px 32px;
+ background-repeat: no-repeat;
+ background-color: transparent;
+ background-position: center center;
+ display: inline-block;
+ height: 100%;
+ width: 100%;
+}
+
+[peertube-plugin-livechat-state="initializing"] {
+ display: none;
+}
+
+[peertube-plugin-livechat-state="open"] .peertube-plugin-livechat-button-open {
+ display: none;
+}
+
+[peertube-plugin-livechat-state="closed"] .peertube-plugin-livechat-button-close {
+ display: none;
+}
+
+#peertube-plugin-livechat-container iframe {
border: 1px solid black;
min-height: 30vh;
+ height: 100%;
}
diff --git a/client/common-client-plugin.js b/client/common-client-plugin.js
index dde51eaa..3e233faf 100644
--- a/client/common-client-plugin.js
+++ b/client/common-client-plugin.js
@@ -5,13 +5,10 @@ function register ({ registerHook, _peertubeHelpers }) {
registerHook({
target: 'action:router.navigation-end',
handler: () => {
- const el = document.querySelector('.peertube-plugin-livechat-init')
- if (el) {
- el.classList.remove('peertube-plugin-livechat-init')
+ const container = document.querySelector('#peertube-plugin-livechat-container')
+ if (container) {
+ container.remove()
}
-
- document.querySelectorAll('.peertube-plugin-livechat-stuff')
- .forEach(dom => dom.remove())
}
})
}
diff --git a/client/videowatch-client-plugin.js b/client/videowatch-client-plugin.js
index 7c227dfd..2ce450b4 100644
--- a/client/videowatch-client-plugin.js
+++ b/client/videowatch-client-plugin.js
@@ -63,21 +63,30 @@ function register ({ registerHook, peertubeHelpers }) {
return iframeUri
}
- function displayButton (buttons, name, label, callback) {
+ function displayButton (buttonContainer, name, label, callback, icon) {
const button = document.createElement('button')
button.classList.add(
- 'action-button',
- 'peertube-plugin-livechat-stuff',
+ 'peertube-plugin-livechat-button',
'peertube-plugin-livechat-button-' + name
)
- button.setAttribute('type', 'button')
- button.textContent = label
button.onclick = callback
- buttons.prepend(button)
+ if (icon) {
+ const iconUrl = peertubeHelpers.getBaseStaticRoute() + '/images/' + icon
+ const iconEl = document.createElement('span')
+ iconEl.classList.add('peertube-plugin-livechat-button-icon')
+ iconEl.setAttribute('style',
+ 'background-image: url(\'' + iconUrl + '\');'
+ )
+ button.prepend(iconEl)
+ button.setAttribute('title', label)
+ } else {
+ button.textContent = label
+ }
+ buttonContainer.append(button)
}
- function displayChatButtons (peertubeHelpers, uuid, showOpenBlank) {
- logger.log('Adding buttons in the DOM...')
+ function insertChatDom (container, peertubeHelpers, uuid, showOpenBlank) {
+ logger.log('Adding livechat in the DOM...')
const p = new Promise((resolve, reject) => {
Promise.all([
peertubeHelpers.translate('Open chat'),
@@ -87,37 +96,31 @@ function register ({ registerHook, peertubeHelpers }) {
const labelOpen = labels[0]
const labelOpenBlank = labels[1]
const labelClose = labels[2]
- const buttons = document.querySelector('.video-actions')
const iframeUri = getIframeUri(uuid)
if (!iframeUri) {
return reject(new Error('No uri, cant display the buttons.'))
}
+
+ const buttonContainer = document.createElement('div')
+ buttonContainer.classList.add('peertube-plugin-livechat-buttons')
+ container.append(buttonContainer)
+
+ displayButton(buttonContainer, 'open', labelOpen, () => openChat(), 'talking.png')
if (showOpenBlank) {
- displayButton(buttons, 'openblank', labelOpenBlank, () => {
+ displayButton(buttonContainer, 'openblank', labelOpenBlank, () => {
closeChat()
window.open(iframeUri)
- })
+ }, 'talking-new-window.png')
}
- displayButton(buttons, 'open', labelOpen, () => openChat())
- displayButton(buttons, 'close', labelClose, () => closeChat())
+ displayButton(buttonContainer, 'close', labelClose, () => closeChat(), 'bye.png')
- toggleShowHideButtons(null)
resolve()
})
})
return p
}
- function toggleShowHideButtons (chatOpened) {
- // showing/hiding buttons...
- document.querySelectorAll('.peertube-plugin-livechat-button-open')
- .forEach(button => (button.style.display = (chatOpened === true || chatOpened === null ? 'none' : '')))
-
- document.querySelectorAll('.peertube-plugin-livechat-button-close')
- .forEach(button => (button.style.display = (chatOpened === false || chatOpened === null ? 'none' : '')))
- }
-
function openChat () {
const p = new Promise((resolve, reject) => {
const uuid = lastUUID
@@ -135,25 +138,27 @@ function register ({ registerHook, peertubeHelpers }) {
const additionalStyles = settings['chat-style'] || ''
logger.info('Opening the chat...')
- const videoWrapper = document.querySelector('#video-wrapper')
+ const container = document.getElementById('peertube-plugin-livechat-container')
+ if (!container) {
+ logger.error('Cant found the livechat container.')
+ return reject(new Error('Cant found the livechat container'))
+ }
+
+ if (container.querySelector('iframe')) {
+ logger.error('Seems that there is already an iframe in the container.')
+ return reject(new Error('Seems that there is already an iframe in the container.'))
+ }
// Creating the iframe...
const iframe = document.createElement('iframe')
iframe.setAttribute('src', iframeUri)
- iframe.classList.add(
- 'peertube-plugin-livechat',
- 'peertube-plugin-livechat-stuff',
- 'peertube-plugin-livechat-iframe-stuff'
- )
iframe.setAttribute('sandbox', 'allow-same-origin allow-scripts allow-popups allow-forms')
iframe.setAttribute('frameborder', '0')
if (additionalStyles) {
iframe.setAttribute('style', additionalStyles)
}
- videoWrapper.append(iframe)
-
- // showing/hiding buttons...
- toggleShowHideButtons(true)
+ container.append(iframe)
+ container.setAttribute('peertube-plugin-livechat-state', 'open')
resolve()
})
@@ -161,25 +166,32 @@ function register ({ registerHook, peertubeHelpers }) {
}
function closeChat () {
- document.querySelectorAll('.peertube-plugin-livechat-iframe-stuff')
+ const container = document.getElementById('peertube-plugin-livechat-container')
+ if (!container) {
+ logger.error('Cant close livechat, container not found.')
+ return
+ }
+ container.querySelectorAll('iframe')
.forEach(dom => dom.remove())
- // showing/hiding buttons...
- toggleShowHideButtons(false)
+ container.setAttribute('peertube-plugin-livechat-state', 'closed')
}
function initChat () {
- const el = document.querySelector('#videojs-wrapper')
- if (!el) {
+ const videoWrapper = document.querySelector('#video-wrapper')
+ if (!videoWrapper) {
logger.error('The required div is not present in the DOM.')
return
}
- if (el.classList.contains('peertube-plugin-livechat-init')) {
+ let container = videoWrapper.querySelector('#peertube-plugin-livechat-container')
+ if (container) {
logger.log('The chat seems already initialized...')
return
}
- // Adding a custom class in the dom, so we know initChat was already called.
- el.classList.add('peertube-plugin-livechat-init')
+ container = document.createElement('div')
+ container.setAttribute('id', 'peertube-plugin-livechat-container')
+ container.setAttribute('peertube-plugin-livechat-state', 'initializing')
+ videoWrapper.append(container)
peertubeHelpers.getSettings().then(s => {
settings = s
@@ -214,11 +226,11 @@ function register ({ registerHook, peertubeHelpers }) {
return
}
- displayChatButtons(peertubeHelpers, uuid, !!settings['chat-open-blank']).then(() => {
+ insertChatDom(container, peertubeHelpers, uuid, !!settings['chat-open-blank']).then(() => {
if (settings['chat-auto-display']) {
openChat()
} else {
- toggleShowHideButtons(false)
+ container.setAttribute('peertube-plugin-livechat-state', 'closed')
}
})
})
diff --git a/package-lock.json b/package-lock.json
index 5bc50721..35bc2119 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "peertube-plugin-livechat",
- "version": "1.0.2",
+ "version": "1.0.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -2920,6 +2920,12 @@
"readable-stream": "^2.0.1"
}
},
+ "memorystream": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
+ "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=",
+ "dev": true
+ },
"micromatch": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
@@ -3147,6 +3153,73 @@
"dev": true,
"optional": true
},
+ "npm-run-all": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz",
+ "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "chalk": "^2.4.1",
+ "cross-spawn": "^6.0.5",
+ "memorystream": "^0.3.1",
+ "minimatch": "^3.0.4",
+ "pidtree": "^0.3.0",
+ "read-pkg": "^3.0.0",
+ "shell-quote": "^1.6.1",
+ "string.prototype.padend": "^3.0.0"
+ },
+ "dependencies": {
+ "load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "requires": {
+ "pify": "^3.0.0"
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ },
+ "read-pkg": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+ "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^4.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^3.0.0"
+ }
+ }
+ }
+ },
"npm-run-path": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
@@ -3464,6 +3537,12 @@
"dev": true,
"optional": true
},
+ "pidtree": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz",
+ "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==",
+ "dev": true
+ },
"pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
@@ -3938,6 +4017,12 @@
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
"dev": true
},
+ "shell-quote": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz",
+ "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==",
+ "dev": true
+ },
"signal-exit": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
@@ -4268,6 +4353,17 @@
"strip-ansi": "^5.1.0"
}
},
+ "string.prototype.padend": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.2.tgz",
+ "integrity": "sha512-/AQFLdYvePENU3W5rgurfWSMU6n+Ww8n/3cUt7E+vPBB/D7YDG8x+qjoFs4M/alR2bW7Qg6xMjVwWUOvuQ0XpQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.2"
+ }
+ },
"string.prototype.trimend": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz",
diff --git a/package.json b/package.json
index 762bf1a6..efe0de6e 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.3.1",
+ "npm-run-all": "^4.1.5",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10"
},
@@ -43,13 +44,18 @@
],
"library": "./main.js",
"scripts": {
+ "clean": "rm -rf dist/*",
"prepare": "npm run build",
- "build": "mkdir -p dist/conversejs && cp -r node_modules/converse.js/dist/* dist/conversejs/ && webpack --mode=production",
+ "build:converse": "mkdir -p dist/conversejs && cp -r node_modules/converse.js/dist/* dist/conversejs/",
+ "build:images": "mkdir -p dist/images && cp public/images/* dist/images/",
+ "build:webpack": "webpack --mode=production",
+ "build": "npm-run-all -s clean -p build:converse build:images build:webpack",
"lint": "npx eslint --ext .js ."
},
"staticDirs": {
"static": "dist/static",
- "conversejs": "dist/conversejs/"
+ "conversejs": "dist/conversejs/",
+ "images": "dist/images/"
},
"translations": {
"fr-FR": "./languages/fr.json"
diff --git a/public/images/.gitkeep b/public/images/.gitkeep
deleted file mode 100644
index e69de29b..00000000
diff --git a/public/images/bye.png b/public/images/bye.png
new file mode 100644
index 00000000..9238964e
Binary files /dev/null and b/public/images/bye.png differ
diff --git a/public/images/bye.svg b/public/images/bye.svg
new file mode 100644
index 00000000..777aebfe
--- /dev/null
+++ b/public/images/bye.svg
@@ -0,0 +1,307 @@
+
+
diff --git a/public/images/talking-new-window.png b/public/images/talking-new-window.png
new file mode 100644
index 00000000..69a6638e
Binary files /dev/null and b/public/images/talking-new-window.png differ
diff --git a/public/images/talking-new-window.svg b/public/images/talking-new-window.svg
new file mode 100644
index 00000000..dc999847
--- /dev/null
+++ b/public/images/talking-new-window.svg
@@ -0,0 +1,533 @@
+
+
diff --git a/public/images/talking.png b/public/images/talking.png
new file mode 100644
index 00000000..9c0791e2
Binary files /dev/null and b/public/images/talking.png differ
diff --git a/public/images/talking.svg b/public/images/talking.svg
new file mode 100644
index 00000000..88032277
--- /dev/null
+++ b/public/images/talking.svg
@@ -0,0 +1,464 @@
+
+