From a17b76ac75f506f5da6fe8adf9c36632b60d4226 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 26 Sep 2020 14:56:02 +0200 Subject: refactor to use app-rooted js imports --- frontend/app/views/page/components/tile.list.js | 142 ++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 frontend/app/views/page/components/tile.list.js (limited to 'frontend/app/views/page/components/tile.list.js') diff --git a/frontend/app/views/page/components/tile.list.js b/frontend/app/views/page/components/tile.list.js new file mode 100644 index 0000000..c455489 --- /dev/null +++ b/frontend/app/views/page/components/tile.list.js @@ -0,0 +1,142 @@ +import React, { Component } from 'react' +// import { Link } from 'react-router-dom' +import { bindActionCreators } from 'redux' +import { connect } from 'react-redux' +import { ReactSortable } from "react-sortablejs" + +// import actions from 'app/actions' +import * as tileActions from '../../tile/tile.actions' +import * as pageActions from '../../page/page.actions' + +const DOUBLE_CLICK_THRESHOLD = 250 + +class TileList extends Component { + state = { + tiles: [], + lastTargetId: 0, + lastTimeStamp: 0, + } + + // store doubleclick state as a class property because ReactSortable calls setState promiscuously + didDoubleClick = false + + componentDidMount(prevProps) { + const { tiles } = this.props.page.show.res + const { pages } = this.props.graph.show.res + const pageTitles = pages.reduce((a,b) => { + a[b.id] = b.title + return a + }, {}) + this.setState({ tiles: tiles.slice(0).reverse(), pageTitles }) + } + + componentDidUpdate(prevProps, prevState) { + if (this.didDoubleClick) return + const { tiles } = this.state + if (prevState.tiles.length && !pageActions.isSameTileOrder(tiles, prevState.tiles)) { + this.props.pageActions.setTileSortOrder(tiles.slice(0).reverse()) + } + // since we store the full tiles here (reversed!), they might change from under us + // potentially later refactor to only use a sort order / lookup + else if (prevProps.page.show.res.tiles !== this.props.page.show.res.tiles) { + const tileLookup = this.props.page.show.res.tiles.reduce((a,b) => { + a[b.id] = b + return a + }, {}) + const newTiles = this.state.tiles.map(tile => { + return tileLookup[tile.id] + }) + this.setState({ tiles: newTiles }) + } + } + + handleChoose(e) { + const { lastTargetId, lastTimeStamp } = this.state + if (lastTimeStamp + && parseInt(e.item.dataset.id) === lastTargetId + && (e.timeStamp - lastTimeStamp) < DOUBLE_CLICK_THRESHOLD + ) { + // console.log('selected', lastTargetId) + this.didDoubleClick = true + this.props.pageActions.showEditTileForm(lastTargetId) + } else { + this.setState({ + lastTargetId: parseInt(e.item.dataset.id), + lastTimeStamp: e.timeStamp, + }) + } + } + + handleUpdate(newTiles) { + if (this.didDoubleClick) return + this.setState({ tiles: newTiles }) + } + + render() { + const { tiles, pageTitles } = this.state + return ( +
+ this.handleUpdate(newTiles)} + onChoose={e => this.handleChoose(e)} + > + {tiles.map(tile => ( + tile.type === 'image' + ? + : tile.type === 'text' + ? + : tile.type === 'link' + ? + : + ))} + +
+ ) + } +} + +const TileListImage = ({ tile }) => ( +
+
+
+) + +const TileListText = ({ tile }) => ( +
+ {(tile.settings.content || "").substr(0, 100)} +
+) + +const TileListLink = ({ tile, pageTitles }) => ( +
+ + {'Link: '} + {tile.target_page_id === -1 + ? 'External' + : !tile.target_page_id + ? 'No link specified!' + : tile.target_page_id in pageTitles + ? pageTitles[tile.target_page_id] + : 'Error, broken link!'} + +
+) + +const TileListMisc = ({ tile }) => ( +
+ {"Tile: "}{tile.type} +
+) + +const mapStateToProps = state => ({ + graph: state.graph, + page: state.page, +}) + +const mapDispatchToProps = dispatch => ({ + tileActions: bindActionCreators({ ...tileActions }, dispatch), + pageActions: bindActionCreators({ ...pageActions }, dispatch), +}) + +export default connect(mapStateToProps, mapDispatchToProps)(TileList) -- cgit v1.2.3-70-g09d2