import React, { useEffect, useReducer, useRef } from "react";
import filepath from "path";
import ReactCSSTransitionGroup from "react-addons-css-transition-group";
import { MenuBar } from "./menubar";
import { Bundle, Icon, NgIf, Loader, EventEmitter, EventReceiver } from "../../components/";
import { alert, randomString, notify, getMimeType, currentShare } from "../../helpers/";
import { Chromecast } from "../../model/";
import { Pager } from "./pager";
import { t } from "../../locales/";
import "./imageviewer.scss";
import "./pager.scss";
const SmallExif = (props) => (
{(Comp) => }
);
const LargeExif = (props) => (
{(Comp) => }
);
export function ImageViewerComponent({ filename, data, path, subscribe, unsubscribe }) {
const [state, setState] = useReducer((s, a) => {
return { ...s, ...a };
}, {
preload: null,
refresh: 0,
show_exif: false,
is_loaded: false,
draggable: false,
});
const $container = useRef();
const refresh = () => setState({ refresh: state.refresh + 1 });
const shortcut = (e) => {
if (e.keyCode === 27) setState({ show_exif: false });
else if (e.keyCode === 73) setState({ show_exif: !state.show_exif });
};
useEffect(() => {
setState({ is_loaded: false });
subscribe("media::preload", (preload) => {
setState({ preload: preload });
});
document.addEventListener("webkitfullscreenchange", refresh);
document.addEventListener("mozfullscreenchange", refresh);
document.addEventListener("fullscreenchange", refresh);
document.addEventListener("keydown", shortcut);
return () => {
unsubscribe("media::preload");
document.removeEventListener("webkitfullscreenchange", refresh);
document.removeEventListener("mozfullscreenchange", refresh);
document.removeEventListener("fullscreenchange", refresh);
document.removeEventListener("keydown", shortcut);
};
}, [data]);
const chromecastSetup = (event) => {
switch (event.sessionState) {
case cast.framework.SessionState.SESSION_STARTED:
chromecastHandler();
break;
}
};
const chromecastHandler = (event) => {
const session = Chromecast.session();
if (!session) return;
const link = Chromecast.createLink(data);
const media = new chrome.cast.media.MediaInfo(
link,
getMimeType(filename),
);
media.metadata = new chrome.cast.media.PhotoMediaMetadata();
media.metadata.title = filename;
media.metadata.images = [
new chrome.cast.Image(Chromecast.origin() + "/assets/icons/photo.png"),
];
Chromecast.createRequest(media)
.then((req) => session.loadMedia(req))
.catch((err) => {
console.error(err)
notify.send(t("Cannot establish a connection"), "error");
});
};
useEffect(() => {
const context = Chromecast.context();
if (!context) return;
document.getElementById("chromecast-target").append(document.createElement("google-cast-launcher"));
context.addEventListener(
cast.framework.CastContextEventType.SESSION_STATE_CHANGED,
chromecastSetup,
);
chromecastHandler();
return () => {
context.removeEventListener(
cast.framework.CastContextEventType.SESSION_STATE_CHANGED,
chromecastSetup,
);
};
}, []);
const hasExif = (fname) => {
const ext = filepath.extname(fname).toLowerCase().substring(1);
return ["jpg", "jpeg", "tiff", "tif"].indexOf(ext) !== -1;
};
const toggleExif = () => {
if (window.innerWidth < 580) {
alert.now();
} else {
setState({
show_exif: !state.show_exif,
});
}
};
const requestFullScreen = () => {
if ("webkitRequestFullscreen" in document.body) {
$container.current.webkitRequestFullscreen();
} else if ("mozRequestFullScreen" in document.body) {
$container.current.mozRequestFullScreen();
}
};
return (
setState({ is_loaded: true })}
url={data} />
setState({ draggable: files.length > 1 ? true : false })}
next={(e) => setState({ preload: e })} />
);
}
export const ImageViewer = EventReceiver(EventEmitter(ImageViewerComponent));
class ImageFancyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
isError: false,
drag_init: { x: null, t: null },
drag_current: { x: null, t: null },
hasAction: false,
};
this.img = new Image();
this.img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=";
}
UNSAFE_componentWillReceiveProps(nextProp) {
if (nextProp.url !== this.props.url) {
this.setState({
isLoading: true,
isError: false,
drag_current: { x: 0 },
hasAction: false,
});
}
}
onLoad() {
this.setState({ isLoading: false });
this.props.onLoad();
}
onError(w) {
this.setState({ isError: true });
}
imageDragStart(e) {
if(!this.props.draggable) return;
const t = new Date();
if (e.touches) {
this.setState({
drag_init: { x: e.touches[0].clientX, t: t },
hasAction: true,
});
} else {
this.setState({
drag_init: { x: e.pageX, t: t },
hasAction: true,
});
}
if (e.dataTransfer) e.dataTransfer.setDragImage(this.img, 0, 0);
}
imageDragEnd(e) {
const drag_end = {
x: function(dragX, touch) {
if (dragX !== null) return dragX;
if (touch && touch[0]) {
return touch[0].clientX;
}
return 0;
}(e.pageX || null, e.changedTouches || null),
t: new Date(),
};
const direction = function(x_current, x_init) {
if (x_current.t - x_init.t > 200 &&
Math.abs(x_current.x - x_init.x) <
(window.innerWidth < 500 ? window.innerWidth / 3 : 250)) {
return "neutral";
}
return x_current.x > x_init.x ? "right" : "left";
}(drag_end, this.state.drag_init);
if (direction === "left") {
return this.setState({
drag_current: { x: - window.innerWidth },
hasAction: false,
}, () => {
this.props.emit("media::next");
});
} else if (direction === "right") {
return this.setState({
drag_current: { x: + window.innerWidth },
hasAction: false,
}, () => {
this.props.emit("media::previous");
});
}
return this.setState({
drag_current: { x: 0 },
hasAction: false,
});
}
imageDrag(e) {
if (e.pageX > 0) {
this.setState({
drag_current: { x: e.pageX - this.state.drag_init.x },
});
} else if (e.touches && e.touches[0].clientX > 0) {
this.setState({
drag_current: { x: e.touches[0].clientX - this.state.drag_init.x },
});
}
}
render() {
if (this.state.isError) {
return (
{ t("Can't load this picture") }
);
}
if (this.state.isLoading) {
return (
);
}
return (
);
}
}
const ImageFancy = EventEmitter(ImageFancyComponent);
function Img({ src, ...props }) {
const image_url = (url, size) => {
return url+"&size="+parseInt(Math.max(window.innerWidth*size, window.innerHeight*size));
};
if (!src) return null;
return (
);
}