2021-01-25 12:15:33 +01:00
|
|
|
/*
|
|
|
|
* Lightbox window
|
|
|
|
*/
|
2021-02-24 10:40:59 +01:00
|
|
|
|
|
|
|
import Events from './_events';
|
2021-07-19 18:39:21 +02:00
|
|
|
import {
|
|
|
|
Component
|
|
|
|
} from 'react';
|
2021-04-02 11:20:48 +02:00
|
|
|
import Swipe from 'react-easy-swipe';
|
2021-04-02 11:47:45 +02:00
|
|
|
import KeyboardJS from 'keyboardjs';
|
2021-01-30 22:00:13 +01:00
|
|
|
|
2021-07-19 18:39:21 +02:00
|
|
|
import Embed, {
|
|
|
|
defaultProviders
|
|
|
|
} from 'react-tiny-oembed';
|
2021-01-30 22:00:13 +01:00
|
|
|
|
2021-02-24 10:43:39 +01:00
|
|
|
const W = window;
|
|
|
|
|
2021-01-31 01:04:51 +01:00
|
|
|
const InstagramProvider = {
|
2021-02-24 10:38:08 +01:00
|
|
|
provider_name: 'Instagram',
|
|
|
|
provider_url: 'https://instagram.com',
|
|
|
|
endpoints: [{
|
2021-07-19 18:39:21 +02:00
|
|
|
schemes: [
|
|
|
|
'http://instagram.com/*/p/*,',
|
|
|
|
'http://www.instagram.com/*/p/*,',
|
|
|
|
'https://instagram.com/*/p/*,',
|
|
|
|
'https://www.instagram.com/*/p/*,',
|
|
|
|
'http://instagram.com/p/*',
|
|
|
|
'http://instagr.am/p/*',
|
|
|
|
'http://www.instagram.com/p/*',
|
|
|
|
'http://www.instagr.am/p/*',
|
|
|
|
'https://instagram.com/p/*',
|
|
|
|
'https://instagr.am/p/*',
|
|
|
|
'https://www.instagram.com/p/*',
|
|
|
|
'https://www.instagr.am/p/*',
|
|
|
|
'http://instagram.com/tv/*',
|
|
|
|
'http://instagr.am/tv/*',
|
|
|
|
'http://www.instagram.com/tv/*',
|
|
|
|
'http://www.instagr.am/tv/*',
|
|
|
|
'https://instagram.com/tv/*',
|
|
|
|
'https://instagr.am/tv/*',
|
|
|
|
'https://www.instagram.com/tv/*',
|
|
|
|
'https://www.instagr.am/tv/*',
|
|
|
|
],
|
|
|
|
url: 'https://graph.facebook.com/v9.0/instagram_oembed',
|
|
|
|
formats: ['json'],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
schemes: [
|
|
|
|
'http://instagram.com/*/p/*,',
|
|
|
|
'http://www.instagram.com/*/p/*,',
|
|
|
|
'https://instagram.com/*/p/*,',
|
|
|
|
'https://www.instagram.com/*/p/*,',
|
|
|
|
'http://instagram.com/p/*',
|
|
|
|
'http://instagr.am/p/*',
|
|
|
|
'http://www.instagram.com/p/*',
|
|
|
|
'http://www.instagr.am/p/*',
|
|
|
|
'https://instagram.com/p/*',
|
|
|
|
'https://instagr.am/p/*',
|
|
|
|
'https://www.instagram.com/p/*',
|
|
|
|
'https://www.instagr.am/p/*',
|
|
|
|
'http://instagram.com/tv/*',
|
|
|
|
'http://instagr.am/tv/*',
|
|
|
|
'http://www.instagram.com/tv/*',
|
|
|
|
'http://www.instagr.am/tv/*',
|
|
|
|
'https://instagram.com/tv/*',
|
|
|
|
'https://instagr.am/tv/*',
|
|
|
|
'https://www.instagram.com/tv/*',
|
|
|
|
'https://www.instagr.am/tv/*',
|
|
|
|
],
|
|
|
|
url: 'https://api.instagram.com/oembed',
|
|
|
|
formats: ['json'],
|
|
|
|
}, ],
|
2021-01-30 22:00:13 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const axios = require('axios');
|
2021-01-25 12:15:33 +01:00
|
|
|
|
|
|
|
class MetaWindow extends Component {
|
2021-02-24 10:38:08 +01:00
|
|
|
state = {
|
|
|
|
content: '',
|
|
|
|
type: [],
|
|
|
|
shown: false,
|
|
|
|
loading: false,
|
|
|
|
error: false,
|
|
|
|
embed: false,
|
|
|
|
collections: [],
|
|
|
|
current: null,
|
|
|
|
};
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
const ui = this;
|
|
|
|
ui.name = ui.constructor.name;
|
|
|
|
console.log(`${ui.name}: init`);
|
|
|
|
ui.axios = axios;
|
2021-02-24 10:43:39 +01:00
|
|
|
|
2021-02-24 11:04:34 +01:00
|
|
|
W.dispatchEvent(new Event(`{ui.name}.init`));
|
2021-02-24 10:38:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
_currIndex = () => {
|
|
|
|
const ui = this;
|
|
|
|
const el = ui.state.current;
|
|
|
|
const gallery = el.getAttribute('data-gallery');
|
|
|
|
|
|
|
|
return ui.state.collections[gallery].indexOf(el);
|
|
|
|
};
|
|
|
|
|
|
|
|
next = () => {
|
|
|
|
const ui = this;
|
|
|
|
const el = ui.state.current;
|
|
|
|
const gallery = el.getAttribute('data-gallery');
|
|
|
|
|
|
|
|
let i = ui._currIndex();
|
|
|
|
if (i < ui.state.collections[gallery].length - 1) {
|
|
|
|
i++;
|
|
|
|
} else {
|
|
|
|
i = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ui.state.collections[gallery][i].click();
|
2021-02-24 10:40:59 +01:00
|
|
|
|
2021-04-02 11:47:45 +02:00
|
|
|
console.log(`${ui.name}: next`);
|
2021-02-24 11:04:34 +01:00
|
|
|
W.dispatchEvent(new Event(`{ui.name}.next`));
|
2021-02-24 10:38:08 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
prev = () => {
|
|
|
|
const ui = this;
|
|
|
|
const el = ui.state.current;
|
|
|
|
const gallery = el.getAttribute('data-gallery');
|
|
|
|
|
|
|
|
let i = ui._currIndex();
|
|
|
|
if (i > 0) {
|
|
|
|
i--;
|
|
|
|
} else {
|
|
|
|
i = ui.state.collections[gallery].length - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ui.state.collections[gallery][i].click();
|
2021-02-24 10:40:59 +01:00
|
|
|
|
2021-04-02 11:47:45 +02:00
|
|
|
console.log(`${ui.name}: prev`);
|
2021-02-24 11:04:34 +01:00
|
|
|
W.dispatchEvent(new Event(`{ui.name}.prev`));
|
2021-02-24 10:38:08 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
reset = () => {
|
|
|
|
const ui = this;
|
|
|
|
|
|
|
|
ui.setState({
|
|
|
|
content: '',
|
|
|
|
type: [],
|
|
|
|
shown: false,
|
|
|
|
loading: false,
|
|
|
|
error: false,
|
|
|
|
embed: false,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
embed = (link) => {
|
|
|
|
const ui = this;
|
|
|
|
console.log(`${ui.name}: embed`);
|
|
|
|
|
|
|
|
ui.reset();
|
|
|
|
ui.setState({
|
|
|
|
embed: link,
|
|
|
|
loading: false,
|
|
|
|
type: ['embed', 'video'],
|
|
|
|
});
|
|
|
|
ui.show();
|
|
|
|
};
|
|
|
|
|
2021-07-19 18:39:21 +02:00
|
|
|
setCaption = (title) => {
|
|
|
|
const ui = this;
|
|
|
|
console.log(`${ui.name}: setCaption`);
|
|
|
|
|
|
|
|
ui.state.caption = title;
|
|
|
|
};
|
|
|
|
|
|
|
|
getCaption = () => {
|
|
|
|
const ui = this;
|
|
|
|
return {
|
|
|
|
__html: ui.state.caption
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-02-24 10:38:08 +01:00
|
|
|
load = (link) => {
|
|
|
|
const ui = this;
|
|
|
|
const axios = ui.axios;
|
|
|
|
|
|
|
|
ui.reset();
|
2021-07-19 18:39:21 +02:00
|
|
|
ui.setState({
|
|
|
|
loading: true
|
|
|
|
});
|
2021-02-24 10:38:08 +01:00
|
|
|
ui.show();
|
|
|
|
|
|
|
|
axios
|
|
|
|
.get(link, {
|
|
|
|
responseType: 'arraybuffer',
|
|
|
|
})
|
|
|
|
.then((resp) => {
|
|
|
|
// handle success
|
|
|
|
console.log(
|
|
|
|
`${ui.name}: response content-type: ${resp.headers['content-type']}`,
|
|
|
|
);
|
|
|
|
|
|
|
|
switch (resp.headers['content-type']) {
|
|
|
|
case 'image/jpeg':
|
|
|
|
case 'image/png':
|
|
|
|
case 'image/svg+xml':
|
|
|
|
case 'image/bmp':
|
|
|
|
case 'image/gif':
|
|
|
|
case 'image/tiff':
|
|
|
|
case 'image/webp':
|
|
|
|
// irregular types:
|
|
|
|
case 'image/jpg':
|
|
|
|
case 'image/svg':
|
|
|
|
ui.setContent(
|
|
|
|
`<img src="data:${
|
2021-04-02 11:20:48 +02:00
|
|
|
resp.headers['content-type']
|
|
|
|
};base64,${ui._imageEncode(resp.data)}" />`,
|
2021-02-24 10:38:08 +01:00
|
|
|
'image',
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case 'application/json':
|
|
|
|
case 'application/ld+json':
|
|
|
|
// irregular types:
|
|
|
|
case 'application/json; charset=UTF-8':
|
|
|
|
const json = JSON.parse(ui._abToString(resp.data));
|
|
|
|
ui.setContent(`${json['Content']}`, 'text html json');
|
|
|
|
|
|
|
|
break;
|
|
|
|
case 'text/html':
|
|
|
|
case 'application/xhtml+xml':
|
|
|
|
case 'text/plain':
|
|
|
|
// irregular types:
|
|
|
|
case 'text/html; charset=UTF-8':
|
|
|
|
case 'application/xhtml+xml; charset=UTF-8':
|
|
|
|
case 'text/plain; charset=UTF-8':
|
|
|
|
ui.setContent(
|
|
|
|
ui._abToString(resp.data),
|
|
|
|
'text html pajax',
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
console.warn(
|
|
|
|
`${ui.name}: Unknown response content-type!`,
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
}
|
2021-02-24 10:40:59 +01:00
|
|
|
|
2021-02-24 11:04:34 +01:00
|
|
|
W.dispatchEvent(new Event(`{ui.name}.loaded`));
|
2021-02-24 10:38:08 +01:00
|
|
|
})
|
|
|
|
.catch((error) => {
|
|
|
|
console.error(error);
|
|
|
|
|
|
|
|
let msg = '';
|
|
|
|
|
|
|
|
if (error.response) {
|
|
|
|
switch (error.response.status) {
|
|
|
|
case 404:
|
|
|
|
msg = 'Not Found.';
|
|
|
|
break;
|
|
|
|
case 500:
|
|
|
|
msg = 'Server issue, please try again latter.';
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
msg = 'Something went wrong.';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (error.request) {
|
|
|
|
msg = 'No response received';
|
|
|
|
} else {
|
|
|
|
console.warn('Error', error.message);
|
|
|
|
}
|
|
|
|
|
2021-07-19 18:39:21 +02:00
|
|
|
ui.setState({
|
|
|
|
error: msg
|
|
|
|
});
|
2021-02-24 10:40:59 +01:00
|
|
|
|
2021-02-24 11:04:34 +01:00
|
|
|
W.dispatchEvent(new Event(`{ui.name}.error`));
|
2021-02-24 10:38:08 +01:00
|
|
|
})
|
|
|
|
.then(() => {
|
2021-07-19 18:39:21 +02:00
|
|
|
ui.setState({
|
|
|
|
loading: false
|
|
|
|
});
|
2021-02-24 10:38:08 +01:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
_abToString = (arrayBuffer) => {
|
|
|
|
return String.fromCharCode.apply(null, new Uint8Array(arrayBuffer));
|
|
|
|
};
|
|
|
|
|
|
|
|
_imageEncode = (arrayBuffer) => {
|
|
|
|
let u8 = new Uint8Array(arrayBuffer);
|
|
|
|
let b64encoded = btoa(
|
|
|
|
[].reduce.call(
|
|
|
|
new Uint8Array(arrayBuffer),
|
|
|
|
function(p, c) {
|
|
|
|
return p + String.fromCharCode(c);
|
|
|
|
},
|
|
|
|
'',
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
return b64encoded;
|
|
|
|
};
|
|
|
|
|
|
|
|
setContent = (html, type) => {
|
|
|
|
const ui = this;
|
|
|
|
console.log(`${ui.name}: setContent`);
|
|
|
|
|
|
|
|
let typeArr = type ? type : ['html', 'text'];
|
|
|
|
if (!Array.isArray(typeArr)) {
|
|
|
|
typeArr = type.split(' ');
|
|
|
|
}
|
|
|
|
|
2021-07-19 18:39:21 +02:00
|
|
|
ui.setState({
|
|
|
|
content: html,
|
|
|
|
type: typeArr
|
|
|
|
});
|
2021-02-24 10:38:08 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
show = () => {
|
|
|
|
const ui = this;
|
|
|
|
console.log(`${ui.name}: show`);
|
|
|
|
|
2021-07-19 18:39:21 +02:00
|
|
|
ui.setState({
|
|
|
|
shown: true
|
|
|
|
});
|
2021-02-24 11:04:34 +01:00
|
|
|
W.dispatchEvent(new Event(`{ui.name}.show`));
|
2021-02-24 10:38:08 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
hide = () => {
|
|
|
|
const ui = this;
|
|
|
|
|
|
|
|
console.log(`${ui.name}: hide`);
|
2021-04-02 11:47:45 +02:00
|
|
|
|
|
|
|
KeyboardJS.withContext(name, () => {
|
|
|
|
KeyboardJS.unbind('left', ui.prev);
|
|
|
|
KeyboardJS.unbind('right', ui.next);
|
|
|
|
});
|
|
|
|
|
|
|
|
KeyboardJS.setContext('index');
|
|
|
|
|
2021-07-19 18:39:21 +02:00
|
|
|
ui.setState({
|
|
|
|
shown: false
|
|
|
|
});
|
2021-02-24 11:04:34 +01:00
|
|
|
W.dispatchEvent(new Event(`{ui.name}.hide`));
|
2021-02-24 10:38:08 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
getHtml = () => {
|
|
|
|
const ui = this;
|
2021-07-19 18:39:21 +02:00
|
|
|
return {
|
|
|
|
__html: ui.state.content
|
|
|
|
};
|
2021-02-24 10:38:08 +01:00
|
|
|
};
|
|
|
|
|
2021-04-02 11:20:48 +02:00
|
|
|
|
|
|
|
onSwipeMove(position, event) {
|
|
|
|
const ui = this.ui;
|
|
|
|
const x = position.x;
|
|
|
|
|
|
|
|
if (ui.locked || Math.abs(x) < 50) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ui.locked = true;
|
|
|
|
setTimeout(() => {
|
|
|
|
ui.locked = false;
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
if (x > 0) {
|
|
|
|
console.log(`${ui.name}: swipe right`);
|
|
|
|
ui.prev();
|
|
|
|
} else {
|
|
|
|
console.log(`${ui.name}: swipe left`);
|
|
|
|
ui.next();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-24 10:38:08 +01:00
|
|
|
render() {
|
|
|
|
const ui = this;
|
|
|
|
const name = ui.name;
|
|
|
|
|
|
|
|
let navs = null;
|
|
|
|
const el = ui.state.current;
|
2021-04-02 11:47:45 +02:00
|
|
|
KeyboardJS.setContext(name);
|
|
|
|
KeyboardJS.withContext(name, () => {
|
|
|
|
KeyboardJS.unbind('left', ui.prev);
|
|
|
|
KeyboardJS.unbind('right', ui.next);
|
|
|
|
});
|
|
|
|
|
2021-02-24 10:38:08 +01:00
|
|
|
if (el) {
|
|
|
|
const gallery = el.getAttribute('data-gallery');
|
|
|
|
if (gallery && ui.state.collections[gallery].length > 1) {
|
|
|
|
navs = (
|
|
|
|
<nav className="meta-navs">
|
2021-04-02 11:20:48 +02:00
|
|
|
<button
|
|
|
|
className="meta-nav meta-nav-arrow meta-nav-arrow__prev a"
|
|
|
|
onClick={ui.prev}
|
|
|
|
>
|
|
|
|
<i className="fa fas fa-chevron-left"></i>
|
|
|
|
<span className="sr-only">Previous</span>
|
|
|
|
</button>
|
|
|
|
<button
|
|
|
|
className="meta-nav meta-nav-arrow meta-nav-arrow__next a"
|
|
|
|
onClick={ui.next}
|
|
|
|
>
|
|
|
|
<i className="fa fas fa-chevron-right"></i>
|
|
|
|
<span className="sr-only">Next</span>
|
|
|
|
</button>
|
|
|
|
</nav>
|
2021-02-24 10:38:08 +01:00
|
|
|
);
|
2021-04-02 11:47:45 +02:00
|
|
|
|
|
|
|
KeyboardJS.withContext(name, () => {
|
|
|
|
KeyboardJS.bind('left', ui.prev);
|
|
|
|
KeyboardJS.bind('right', ui.next);
|
|
|
|
});
|
2021-02-24 10:38:08 +01:00
|
|
|
}
|
|
|
|
}
|
2021-01-31 01:04:51 +01:00
|
|
|
|
2021-02-24 10:38:08 +01:00
|
|
|
const content = ui.state.embed ? (
|
|
|
|
<section className="meta-wrap typography">
|
2021-04-02 11:20:48 +02:00
|
|
|
<Embed
|
|
|
|
url={ui.state.embed}
|
|
|
|
providers={[...defaultProviders, InstagramProvider]}
|
|
|
|
LoadingFallbackElement=<div className="meta-spinner_embed">
|
|
|
|
... Loading ...
|
|
|
|
</div>
|
|
|
|
/>
|
|
|
|
</section>
|
|
|
|
) : (
|
|
|
|
<section
|
|
|
|
className="meta-wrap typography"
|
|
|
|
dangerouslySetInnerHTML={ui.getHtml()}
|
|
|
|
></section>
|
2021-02-24 10:38:08 +01:00
|
|
|
);
|
2021-01-30 22:00:13 +01:00
|
|
|
|
2021-02-24 10:38:08 +01:00
|
|
|
const className = `meta-${name} meta-${name}__${ui.state.type.join(
|
2021-04-02 11:20:48 +02:00
|
|
|
` meta-${name}__`,
|
|
|
|
)}`;
|
2021-01-30 22:00:13 +01:00
|
|
|
|
2021-02-24 10:38:08 +01:00
|
|
|
const overlayClassName = `meta-${name}-overlay${
|
2021-04-02 11:20:48 +02:00
|
|
|
ui.state.shown ? ` meta-${name}-overlay__open` : ''
|
|
|
|
}${ui.state.loading ? ` meta-${name}-overlay__loading` : ''}${
|
|
|
|
ui.state.error ? ` meta-${name}-overlay__error` : ''
|
|
|
|
}`;
|
2021-01-25 12:15:33 +01:00
|
|
|
|
2021-07-19 18:39:21 +02:00
|
|
|
const caption = ui.state.caption ?
|
|
|
|
<div className="meta-caption" dangerouslySetInnerHTML={ui.getCaption()}></div> :
|
|
|
|
'';
|
|
|
|
|
2021-02-24 10:38:08 +01:00
|
|
|
return (
|
2021-04-02 11:20:48 +02:00
|
|
|
<Swipe className={className} ui={ui} onSwipeMove={ui.onSwipeMove}>
|
|
|
|
<div className={overlayClassName}>
|
|
|
|
<article className="meta-content">
|
|
|
|
{navs}
|
|
|
|
<button
|
|
|
|
className="meta-nav meta-close a"
|
|
|
|
onClick={ui.hide}
|
|
|
|
>
|
|
|
|
<i className="fa fas fa-times"></i>
|
|
|
|
<span className="sr-only">Close</span>
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<div className="meta-spinner">... Loading ...</div>
|
|
|
|
<div className="meta-error alert alert-danger">
|
|
|
|
{ui.state.error}
|
|
|
|
</div>
|
|
|
|
|
|
|
|
{content}
|
2021-07-19 18:39:21 +02:00
|
|
|
|
|
|
|
{caption}
|
2021-04-02 11:20:48 +02:00
|
|
|
</article>
|
|
|
|
</div>
|
|
|
|
</Swipe>
|
2021-02-24 10:38:08 +01:00
|
|
|
);
|
|
|
|
}
|
2021-01-25 12:15:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
export default MetaWindow;
|