import React, { Component } from 'react' import { Route } from 'react-router-dom' import { bindActionCreators } from 'redux' import { connect } from 'react-redux' import { session } from 'app/session' import actions from 'app/actions' import * as pageActions from 'app/views/page/page.actions' import * as tileActions from 'app/views/tile/tile.actions' import { Loader } from 'app/common' import { clamp, dist } from 'app/utils' import TileHandle from 'app/views/tile/components/tile.handle' const defaultState = { dragging: false, bounds: null, videoBounds: null, mouseX: 0, mouseY: 0, box: { x: 0, y: 0, w: 0, h: 0, }, tile: null, cursors: {}, } class PageEditor extends Component { state = { ...defaultState, } constructor() { super() // bind these events in the constructor, so we can remove event listeners later this.handleMouseDown = this.handleMouseDown.bind(this) this.handleMouseMove = this.handleMouseMove.bind(this) this.handleMouseUp = this.handleMouseUp.bind(this) this.handleWindowResize = this.handleWindowResize.bind(this) this.handlePlaybackEnded = this.handlePlaybackEnded.bind(this) this.pageRef = React.createRef() } getBoundingClientRect() { if (!this.pageRef.current) return null const rect = this.pageRef.current.getBoundingClientRect() const scrollTop = document.body.scrollTop || document.body.parentNode.scrollTop const scrollLeft = document.body.scrollLeft || document.body.parentNode.scrollLeft const bounds = { top: rect.top + scrollTop, left: rect.left + scrollLeft, width: rect.width, height: rect.height, } console.log("bounds", bounds) return bounds } componentDidMount() { document.body.addEventListener('mousemove', this.handleMouseMove) document.body.addEventListener('mouseup', this.handleMouseUp) window.addEventListener('resize', this.handleWindowResize) const bounds = this.getBoundingClientRect() let cursors = this.props.graph.show.res.uploads .filter(upload => upload.tag === 'cursor') .reduce((a,b) => { a[b.id] = b return a }, {}) this.setState({ bounds, cursors }) } componentDidUpdate(prevProps) { if (!this.state.bounds) { this.setState({ bounds: this.getBoundingClientRect() }) } } handleWindowResize() { this.setState({ bounds: this.getBoundingClientRect() }) } handlePlaybackEnded() { // } handleMouseDown(e, tile) { if (e.metaKey || e.ctrlKey || e.altKey || e.button !== 0) return const bounds = this.getBoundingClientRect() const mouseX = e.pageX const mouseY = e.pageY // let w = 128 / bounds.width // let h = 16 / bounds.height let { x, y } = tile.settings // x = clamp(x, 0, 1) // y = clamp(y, 0, 1) this.setState({ tile, draggingBox: true, bounds, mouseX, mouseY, box: { dx: 0, dy: 0, // x, y, // w, h, }, initialBox: { // x, y, // w, h, } }) } handleMouseMove(e) { const { dragging, draggingBox, bounds, mouseX, mouseY, initialBox, box } = this.state if (draggingBox) { e.preventDefault() let { x, y, w, h } = initialBox let dx = (e.pageX - mouseX) let dy = (e.pageY - mouseY) this.setState({ box: { dx, dy, // x: clamp(x + (dx / bounds.width), 0, 1.0 - w), // y: clamp(y + (dy / bounds.height), 0, 1.0 - h), // w, h, } }) } } handleMouseUp(e) { // const { actions } = this.props const { temporaryTile } = this.props const { dragging, draggingBox, bounds, box, tile } = this.state if (!dragging && !draggingBox) return e.preventDefault() // const { x, y, w, h } = box const { dx, dy } = box let url = window.location.pathname this.setState({ tile: null, box: null, initialBox: null, dragging: false, draggingBox: false, }) // console.log(page) if (dist(0, 0, dx, dy) < 2) { return } const updatedTile = { ...tile, target_page_id: tile.target_page_id || 0, settings: { ...tile.settings, x: tile.settings.x + dx, y: tile.settings.y + dy, } } if (temporaryTile && tile.id === temporaryTile.id) { this.props.tileActions.updateTemporaryTile(updatedTile) } if (tile.id !== 'new') { console.log(updatedTile) this.props.pageActions.updatePageTile(updatedTile) actions.tile.update(updatedTile) } } render() { if (!this.state.bounds || (!this.props.page.show.res && !this.props.page.show.res.tiles)) { return (
) } const { temporaryTile } = this.props const currentTile = this.state.tile const currentBox = this.state.box const { res } = this.props.page.show const { settings } = res const pageStyle = { backgroundColor: settings ? settings.background_color : '#000000' } const videoBounds = (res.tiles && res.tiles.length && res.tiles[0].type === 'video') ? { width: res.tiles[0].settings.width, height: res.tiles[0].settings.height, } : this.state.bounds return (
{res.tiles && res.tiles.map(tile => { if (!this.props.page.editor.showingPopups && tile.settings.is_popup) return if (temporaryTile && temporaryTile.id === tile.id) { tile = temporaryTile } return ( this.handleMouseDown(e, tile)} onDoubleClick={e => this.props.pageActions.showEditTileForm(tile.id)} onMouseEnter={e => {}} onMouseLeave={e => {}} onPlaybackEnded={this.handlePlaybackEnded} /> ) })} {!!(temporaryTile && temporaryTile.id === 'new') && ( this.handleMouseDown(e, temporaryTile)} onMouseEnter={e => {}} onMouseLeave={e => {}} onPlaybackEnded={this.handlePlaybackEnded} /> )}
) } } const mapStateToProps = state => ({ graph: state.graph, page: state.page, temporaryTile: state.tile.temporaryTile, }) const mapDispatchToProps = dispatch => ({ pageActions: bindActionCreators({ ...pageActions }, dispatch), tileActions: bindActionCreators({ ...tileActions }, dispatch), }) export default connect(mapStateToProps, mapDispatchToProps)(PageEditor)