mirror of
https://github.com/wassname/talk.git
synced 2026-07-14 11:18:50 +08:00
Support lazy rendering (#2109)
* feat: support lazy rendering * fix: added new env var to onbuild args * review: apply suggestions
This commit is contained in:
@@ -11,6 +11,7 @@ ONBUILD ARG TALK_DEFAULT_LANG=en
|
||||
ONBUILD ARG TALK_WHITELISTED_LANGUAGES
|
||||
ONBUILD ARG TALK_PLUGINS_JSON
|
||||
ONBUILD ARG TALK_WEBPACK_SOURCE_MAP
|
||||
ONBUILD ARG TALK_DEFAULT_LAZY_RENDER
|
||||
|
||||
# Bundle app source
|
||||
ONBUILD COPY . /usr/src/app
|
||||
|
||||
@@ -3,6 +3,7 @@ import pym from 'pym.js';
|
||||
import EventEmitter from 'eventemitter2';
|
||||
import { buildUrl } from 'coral-framework/utils/url';
|
||||
import Snackbar from './Snackbar';
|
||||
import onIntersect from './onIntersect';
|
||||
import {
|
||||
createStorage,
|
||||
connectStorageToPym,
|
||||
@@ -50,15 +51,62 @@ export default class Stream {
|
||||
...opts
|
||||
} = config;
|
||||
|
||||
this.onAuthChanged = onAuthChanged;
|
||||
this.el = el;
|
||||
this.talkBaseUrl = talkBaseUrl;
|
||||
this.opts = opts;
|
||||
|
||||
this.emitter = new EventEmitter({ wildcard: true });
|
||||
this.pym = new pym.Parent(el.id, buildStreamIframeUrl(talkBaseUrl, query), {
|
||||
title: opts.title,
|
||||
id: `${el.id}_iframe`,
|
||||
name: `${el.id}_iframe`,
|
||||
});
|
||||
this.snackBar = new Snackbar(snackBarStyles || {});
|
||||
this.emitter = new EventEmitter({ wildcard: true });
|
||||
// Attach to the events emitted by the pym parent.
|
||||
if (events) {
|
||||
events(this.emitter);
|
||||
}
|
||||
if (config.lazy || process.env.TALK_DEFAULT_LAZY_RENDER === 'TRUE') {
|
||||
const renderOnIntersect = () => onIntersect(this.el, () => this.render());
|
||||
if (!window.IntersectionObserver) {
|
||||
// Include a polyfill for the intersection observer.
|
||||
import('intersection-observer')
|
||||
.then(() => {
|
||||
// Polyfill applied.
|
||||
renderOnIntersect();
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(e);
|
||||
// Loading polyfill failed, just render it directly.
|
||||
this.render();
|
||||
});
|
||||
} else {
|
||||
// No need for polyfill.
|
||||
renderOnIntersect();
|
||||
}
|
||||
} else {
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
|
||||
assertRendered() {
|
||||
if (!this.pym) {
|
||||
throw new Error('Stream Embed must be rendered first');
|
||||
}
|
||||
}
|
||||
|
||||
isRendered() {
|
||||
return !!this.pym;
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.pym) {
|
||||
throw new Error('Stream Embed already rendered');
|
||||
}
|
||||
this.pym = new pym.Parent(
|
||||
this.el.id,
|
||||
buildStreamIframeUrl(this.talkBaseUrl, this.query),
|
||||
{
|
||||
title: this.opts.title,
|
||||
id: `${this.el.id}_iframe`,
|
||||
name: `${this.el.id}_iframe`,
|
||||
}
|
||||
);
|
||||
|
||||
// Workaround: IOS Safari ignores `width` but respects `min-width` value.
|
||||
this.pym.el.firstChild.style.width = '1px';
|
||||
@@ -73,19 +121,14 @@ export default class Stream {
|
||||
}
|
||||
});
|
||||
|
||||
// Attach to the events emitted by the pym parent.
|
||||
if (events) {
|
||||
events(this.emitter);
|
||||
}
|
||||
|
||||
this.pym.onMessage('getConfig', () => {
|
||||
this.pym.sendMessage('config', JSON.stringify(opts));
|
||||
this.pym.sendMessage('config', JSON.stringify(this.opts));
|
||||
});
|
||||
|
||||
// If the auth changes, and someone is listening for it, then re-emit it.
|
||||
if (onAuthChanged) {
|
||||
if (this.onAuthChanged) {
|
||||
this.pym.onMessage('coral-auth-changed', message => {
|
||||
onAuthChanged(message ? JSON.parse(message) : null);
|
||||
this.onAuthChanged(message ? JSON.parse(message) : null);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -163,22 +206,27 @@ export default class Stream {
|
||||
}
|
||||
|
||||
enablePluginsDebug() {
|
||||
this.assertRendered();
|
||||
this.pym.sendMessage('enablePluginsDebug');
|
||||
}
|
||||
|
||||
disablePluginsDebug() {
|
||||
this.assertRendered();
|
||||
this.pym.sendMessage('disablePluginsDebug');
|
||||
}
|
||||
|
||||
login(token) {
|
||||
this.assertRendered();
|
||||
this.pym.sendMessage('login', token);
|
||||
}
|
||||
|
||||
logout() {
|
||||
this.assertRendered();
|
||||
this.pym.sendMessage('logout');
|
||||
}
|
||||
|
||||
remove() {
|
||||
this.assertRendered();
|
||||
// Remove the event listeners.
|
||||
document.removeEventListener('click', this.handleClick.bind(this));
|
||||
this.emitter.removeAllListeners();
|
||||
@@ -191,6 +239,7 @@ export default class Stream {
|
||||
}
|
||||
|
||||
handleClick() {
|
||||
this.assertRendered();
|
||||
this.pym.sendMessage('click');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ export class Talk {
|
||||
* @param {String} [config.asset_url] - Asset URL
|
||||
* @param {String} [config.asset_id] - Asset ID
|
||||
* @param {String} [config.auth_token] - (optional) A jwt representing the session
|
||||
* @param {String} [config.lazy] - (optional) If set the stream will only render lazily.
|
||||
* @return {Object}
|
||||
*
|
||||
* Example:
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
export default function onIntersect(el, callback) {
|
||||
if (!IntersectionObserver) {
|
||||
// tslint:disable-next-line:no-console
|
||||
console.warn('IntersectionObserver not available');
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
const options = {
|
||||
rootMargin: '100px',
|
||||
threshold: 1.0,
|
||||
};
|
||||
|
||||
const observer = new IntersectionObserver(entries => {
|
||||
if (entries[0].isIntersecting) {
|
||||
observer.disconnect();
|
||||
callback();
|
||||
}
|
||||
}, options);
|
||||
observer.observe(el);
|
||||
}
|
||||
@@ -237,6 +237,7 @@
|
||||
"eslint-plugin-mocha": "^4.11.0",
|
||||
"husky": "^0.14.3",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"intersection-observer": "^0.5.1",
|
||||
"jest-junit": "^3.6.0",
|
||||
"lint-staged": "^7.2.0",
|
||||
"mocha": "^3.1.2",
|
||||
|
||||
@@ -159,6 +159,9 @@ const config = {
|
||||
'process.env': {
|
||||
VERSION: `"${require('./package.json').version}"`,
|
||||
NODE_ENV: `${JSON.stringify(process.env.NODE_ENV)}`,
|
||||
TALK_DEFAULT_LAZY_RENDER: `${JSON.stringify(
|
||||
process.env.TALK_DEFAULT_LAZY_RENDER
|
||||
)}`,
|
||||
},
|
||||
}),
|
||||
new webpack.EnvironmentPlugin({
|
||||
|
||||
@@ -6042,6 +6042,11 @@ interpret@^1.0.0, interpret@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
|
||||
integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=
|
||||
|
||||
intersection-observer@^0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/intersection-observer/-/intersection-observer-0.5.1.tgz#e340fc56ce74290fe2b2394d1ce88c4353ac6dfa"
|
||||
integrity sha512-Zd7Plneq82kiXFixs7bX62YnuZ0BMRci9br7io88LwDyF3V43cQMI+G5IiTlTNTt+LsDUppl19J/M2Fp9UkH6g==
|
||||
|
||||
invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
|
||||
|
||||
Reference in New Issue
Block a user