summaryrefslogtreecommitdiff
path: root/frontend/app/views/tile/components/tile.form.js
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2021-03-31 17:37:40 +0200
committerJules Laplace <julescarbon@gmail.com>2021-03-31 17:37:40 +0200
commitcda9c115283be8e4e224f6036ba07e5eca243289 (patch)
treed0b150bf108813873c7b59cc9f9bd9c00ea3eba7 /frontend/app/views/tile/components/tile.form.js
parenta6793f922991d326eeb33cf08b245863218eaef7 (diff)
refactor tile forms into own files. add full-width marquee support
Diffstat (limited to 'frontend/app/views/tile/components/tile.form.js')
-rw-r--r--frontend/app/views/tile/components/tile.form.js795
1 files changed, 39 insertions, 756 deletions
diff --git a/frontend/app/views/tile/components/tile.form.js b/frontend/app/views/tile/components/tile.form.js
index 6a65194..372cd1d 100644
--- a/frontend/app/views/tile/components/tile.form.js
+++ b/frontend/app/views/tile/components/tile.form.js
@@ -16,198 +16,36 @@ import { preloadImage, preloadVideo } from 'app/utils'
import * as pageActions from 'app/views/page/page.actions'
import * as tileActions from 'app/views/tile/tile.actions'
-const SELECT_TYPES = [
- "image", "text", "video", "link", "gradient", "script",
-].map(s => ({ name: s, label: s }))
-
-const ALIGNMENTS = [
- "top_left", "top_center", "top_right",
- "center_left", "center_center", "center_right",
- "bottom_left", "bottom_center", "bottom_right",
-].map(align => ({
- name: align,
- label: align === 'center_center'
- ? 'center'
- : align.replace('_', ' ')
- }))
-
-const REQUIRED_KEYS = {
- image: ['url'],
- video: ['url'],
- text: ['content'],
- link: [],
- gradient: [],
- script: [],
-}
-
-const IMAGE_TILE_STYLES = [
- 'tile', 'cover', 'contain', 'contain no-repeat'
-].map(style => ({ name: style, label: style }))
-
-const VIDEO_STYLES = [
- 'normal', 'cover', 'contain',
-].map(style => ({ name: style, label: style }))
-
-const TEXT_FONT_FAMILIES = [
- 'sans-serif', 'serif', 'fantasy', 'monospace', 'cursive',
-].map(style => ({ name: style, label: style }))
-
-const TEXT_FONT_STYLES = [
- 'normal', 'bold', 'italic', 'bold-italic',
-].map(style => ({ name: style, label: style }))
-
-const CURSORS = [
- { name: 'none', label: 'None', },
- { name: 'hand_up', label: 'Up', },
- { name: 'hand_down', label: 'Down', },
- { name: 'hand_left', label: 'Left', },
- { name: 'hand_right', label: 'Right', },
- { name: 'unclickable', label: 'Unclickable', },
-]
+import {
+ SELECT_TYPES, ALIGNMENTS,
+ REQUIRED_KEYS,
+ IMAGE_TILE_STYLES, VIDEO_STYLES,
+ TEXT_FONT_FAMILIES, TEXT_FONT_STYLES,
+ CURSORS, UNITS,
+ NO_LINK, EXTERNAL_LINK, OPEN_POPUP_LINK, CLOSE_POPUP_LINK,
+ PAGE_LIST_TOP_OPTIONS,
+ NO_POPUP, POPUP_LIST_TOP_OPTIONS,
+} from 'app/views/tile/forms/tile.constants'
-const UNITS = [
- { name: 'px', label: 'pixels' },
- { name: '%', label: 'percent' },
- { name: 'video', label: 'video' },
- { name: 'vmin', label: 'screen min' },
- { name: 'vmax', label: 'screen max' },
-]
+import {
+ TILE_CONSTRUCTORS,
-const NO_LINK = 0
-const EXTERNAL_LINK = -1
-const OPEN_POPUP_LINK = -2
-const CLOSE_POPUP_LINK = -3
-const PAGE_LIST_TOP_OPTIONS = [
- { name: NO_LINK, label: 'No link' },
- { name: EXTERNAL_LINK, label: 'External link' },
- { name: OPEN_POPUP_LINK, label: 'Open popup' },
- { name: CLOSE_POPUP_LINK, label: 'Close popup' },
- { name: -99, label: '──────────', disabled: true },
-]
+ TileImageForm,
+ TileLinkForm,
+ TileTextForm,
+ TileGradientForm,
+ TileScriptForm,
+ TileVideoForm,
-const NO_POPUP = 0
-const POPUP_LIST_TOP_OPTIONS = [
- { name: NO_POPUP, label: 'Select a popup group' },
- { name: -99, label: '──────────', disabled: true },
-]
+ TileHyperlinkForm,
+ TileMiscForm,
+ TileSoundForm,
+ TileTypeForm,
+} from 'app/views/tile/forms'
// target_page_id = Column(Integer, ForeignKey('page.id'), nullable=True)
// https://s3.amazonaws.com/i.asdf.us/im/1c/gradient_gold1-SpringGreen1_1321159749.jpg
-const newImage = (data) => ({
- settings: {
- ...newPosition(),
- is_tiled: false,
- tile_style: 'tile',
- url: "",
- external_link_url: "",
- cursor: 'hand_up',
- },
- type: 'image',
- target_page_id: 0,
- ...data,
-})
-
-const newVideo = (data) => ({
- settings: {
- ...newPosition(),
- video_style: 'cover',
- url: "",
- external_link_url: "",
- cursor: 'none',
- muted: false,
- loop_style: false,
- autoadvance: false,
- loop_section: false,
- loop_start: 0,
- loop_end: 0,
- },
- type: 'video',
- target_page_id: 0,
- ...data,
-})
-
-const newText = (data) => ({
- settings: {
- ...newPosition(),
- content: "",
- font_family: 'sans-serif',
- font_size: 16,
- font_style: 'normal',
- font_color: '#dddddd',
- background_color: 'transparent',
- width: 0,
- height: 0,
- units: 'px',
- external_link_url: "",
- cursor: 'hand_up',
- },
- type: 'text',
- target_page_id: 0,
- ...data,
-})
-
-const newGradient = (data) => ({
- settings: {
- ...newPosition({ width: 100, height: 100 }),
- from_color: '#ffffff',
- from_opacity: 1.0,
- to_color: '#000000',
- to_opacity: 1.0,
- angle: 0,
- stop: 50,
- units: '%',
- external_link_url: "",
- cursor: 'hand_up',
- },
- type: 'gradient',
- target_page_id: 0,
- ...data,
-})
-
-const newLink = (data) => ({
- settings: {
- ...newPosition({ width: 100, height: 100, }),
- external_link_url: "",
- cursor: 'hand_up',
- units: 'px',
- },
- type: 'link',
- target_page_id: 0,
- ...data,
-})
-
-const newScript = (data) => ({
- settings: {
- ...newPosition({ width: 100, height: 100, }),
- },
- type: 'script',
- ...data,
-})
-
-const newPosition = (data) => ({
- x: 0, y: 0,
- width: 0, height: 0,
- rotation: 0, scale: 1,
- opacity: 1,
- units: false,
- align: "center_center",
- has_audio: false,
- audio_on_click_id: 0,
- audio_on_hover_id: 0,
- navigate_when_audio_finishes: false,
- ...data,
-})
-
-const TYPE_CONSTRUCTORS = {
- image: newImage,
- video: newVideo,
- text: newText,
- link: newLink,
- gradient: newGradient,
- script: newScript,
-}
-
class TileForm extends Component {
state = {
title: "",
@@ -252,7 +90,7 @@ class TileForm extends Component {
]
this.setState({ pageList, popupList })
if (isNew) {
- const newTile = newGradient({
+ const newTile = TILE_CONSTRUCTORS.image({
id: "new",
graph_id: graph.show.res.id,
page_id: page.show.res.id,
@@ -292,7 +130,7 @@ class TileForm extends Component {
handleTypeChange(type) {
const { graph, page, temporaryTile } = this.props
- let newTile = TYPE_CONSTRUCTORS[type]({
+ let newTile = TILE_CONSTRUCTORS[type]({
id: temporaryTile.id,
graph_id: temporaryTile.graph_id,
page_id: temporaryTile.page_id,
@@ -455,42 +293,31 @@ class TileForm extends Component {
{'◁'}
</button>
<form onSubmit={this.handleSubmit}>
- <div className="row selects">
- <Select
- name='type'
- selected={temporaryTile.type}
- options={SELECT_TYPES}
- title=''
- onChange={this.handleSelect}
- />
- <Select
- name='align'
- selected={temporaryTile.settings.align}
- options={ALIGNMENTS}
- title=''
- onChange={this.handleAlignment}
- />
- </div>
+
+ <TileTypeForm tile={temporaryTile} errorFields={errorFields} parent={this} />
{this.renderPositionInfo()}
{temporaryTile.type === 'image'
- ? this.renderImageForm()
+ ? <TileImageForm tile={temporaryTile} errorFields={errorFields} parent={this} />
: temporaryTile.type === 'video'
- ? this.renderVideoForm()
+ ? <TileVideoForm tile={temporaryTile} errorFields={errorFields} parent={this} />
: temporaryTile.type === 'text'
- ? this.renderTextForm()
+ ? <TileTextForm tile={temporaryTile} errorFields={errorFields} parent={this} />
: temporaryTile.type === 'link'
- ? this.renderLinkForm()
+ ? <TileLinkForm tile={temporaryTile} errorFields={errorFields} parent={this} />
: temporaryTile.type === 'gradient'
- ? this.renderGradientForm()
+ ? <TileGradientForm tile={temporaryTile} errorFields={errorFields} parent={this} />
: temporaryTile.type === 'script'
- ? this.renderScriptForm()
+ ? <TileScriptForm tile={temporaryTile} errorFields={errorFields} parent={this} />
: ""}
- {this.renderHyperlinkForm()}
- {this.renderMiscForm()}
- {this.renderAudioForm()}
+ <TileHyperlinkForm
+ tile={temporaryTile} errorFields={errorFields} parent={this}
+ pageList={this.state.pageList} popupList={this.state.popupList}
+ />
+ <TileMiscForm tile={temporaryTile} errorFields={errorFields} parent={this} />
+ <TileSoundForm tile={temporaryTile} errorFields={errorFields} parent={this} />
<div className='row buttons'>
<SubmitButton
@@ -529,550 +356,6 @@ class TileForm extends Component {
</div>
)
}
-
- renderImageForm() {
- // const { isNew } = this.props
- const { temporaryTile } = this.props
- const { errorFields } = this.state
- // console.log(temporaryTile.settings)
- return (
- <div>
- <div className='row imageUrl'>
- {temporaryTile.settings.url && <div className='thumb'><img src={temporaryTile.settings.url} /></div>}
- <TextInput
- title=""
- placeholder='http://'
- name="url"
- required
- data={temporaryTile.settings}
- error={errorFields.has('url')}
- onChange={this.handleImageChange}
- autoComplete="off"
- />
- </div>
- <div className='row pair'>
- <Checkbox
- label="Tiled"
- name="is_tiled"
- checked={temporaryTile.settings.is_tiled}
- onChange={this.handleSettingsSelect}
- autoComplete="off"
- />
- {temporaryTile.settings.is_tiled &&
- <Select
- name='tile_style'
- selected={temporaryTile.settings.tile_style || 'tile'}
- options={IMAGE_TILE_STYLES}
- title=''
- onChange={this.handleSettingsSelect}
- />
- }
- </div>
- </div>
- )
- }
-
- renderVideoForm() {
- // const { isNew } = this.props
- const { temporaryTile } = this.props
- const { errorFields } = this.state
- // console.log(temporaryTile.settings)
- return (
- <div>
- <div className='row imageUrl'>
- <TextInput
- title=""
- placeholder='http://'
- name="url"
- required
- data={temporaryTile.settings}
- error={errorFields.has('url')}
- onChange={this.handleVideoChange}
- autoComplete="off"
- />
- </div>
- <div className='row pair with_checkbox'>
- <Select
- name='video_style'
- selected={temporaryTile.settings.video_style || 'none'}
- options={VIDEO_STYLES}
- title=''
- onChange={this.handleSettingsSelect}
- />
- <Checkbox
- label="Loop"
- name="loop"
- checked={temporaryTile.settings.loop}
- onChange={this.handleSettingsSelect}
- autoComplete="off"
- />
- </div>
- <div className='row pair'>
- <Checkbox
- label="Muted"
- name="muted"
- className='short'
- checked={temporaryTile.settings.muted}
- onChange={this.handleSettingsSelect}
- />
- <Checkbox
- label="Autoadvance"
- name="autoadvance"
- className='short'
- checked={temporaryTile.settings.autoadvance}
- onChange={this.handleSettingsSelect}
- />
- </div>
- {!temporaryTile.settings.muted && (
- <Slider
- title='Volume'
- name='volume'
- value={('volume' in temporaryTile.settings) ? temporaryTile.settings.volume : 1.0}
- onChange={this.handleSettingsSelect}
- min={0.0}
- max={1.0}
- step={0.01}
- />
- )}
- {temporaryTile.settings.loop && (
- <div className='row'>
- <Checkbox
- label="Loop section?"
- className='short'
- name="loop_section"
- checked={temporaryTile.settings.loop_section}
- onChange={this.handleSettingsSelect}
- />
- </div>
- )}
- {temporaryTile.settings.loop && temporaryTile.settings.loop_section && (
- <div className='row pair'>
- <TextInput
- title="From"
- placeholder='0:00'
- name="loop_start"
- data={temporaryTile.settings}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- <TextInput
- title="To"
- placeholder='0:00'
- name="loop_end"
- data={temporaryTile.settings}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- </div>
- )}
- </div>
- )
- }
-
- renderTextForm() {
- const { temporaryTile } = this.props
- const { errorFields } = this.state
- return (
- <div>
- <TextArea
- title=""
- name="content"
- required
- data={temporaryTile.settings}
- error={errorFields.has('content')}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- <div className='row font'>
- <Select
- title="Font"
- name='font_family'
- selected={temporaryTile.settings.font_family || 'sans-serif'}
- options={TEXT_FONT_FAMILIES}
- title=''
- onChange={this.handleSettingsSelect}
- />
- <NumberInput
- title=''
- name='font_size'
- data={temporaryTile.settings}
- min={1}
- max={1200}
- error={errorFields.has('font_size')}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- <Select
- name='font_style'
- selected={temporaryTile.settings.font_style || 'normal'}
- options={TEXT_FONT_STYLES}
- title=''
- onChange={this.handleSettingsSelect}
- />
- </div>
- <ColorInput
- title='Text'
- name='font_color'
- data={temporaryTile.settings}
- error={errorFields.has('font_color')}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- <ColorInput
- title='BG'
- name='background_color'
- data={temporaryTile.settings}
- error={errorFields.has('background_color')}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- <div className='row pair'>
- <NumberInput
- title="Width"
- name="width"
- data={temporaryTile.settings}
- min={0}
- max={1200}
- error={errorFields.has('width')}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- <NumberInput
- title="Height"
- name="height"
- data={temporaryTile.settings}
- min={0}
- max={1200}
- error={errorFields.has('height')}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- </div>
- </div>
- )
- }
-
- renderLinkForm() {
- const { temporaryTile } = this.props
- const { errorFields } = this.state
- return (
- <div>
- <div className='row pair'>
- <NumberInput
- title="Width"
- name="width"
- data={temporaryTile.settings}
- min={0}
- max={2400}
- error={errorFields.has('width')}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- <NumberInput
- title="Height"
- name="height"
- data={temporaryTile.settings}
- min={0}
- max={2400}
- error={errorFields.has('height')}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- </div>
- </div>
- )
- }
-
- renderGradientForm() {
- const { temporaryTile } = this.props
- return (
- <div>
- <ColorInput
- title='From'
- name='from_color'
- data={temporaryTile.settings}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- <Slider
- title='Opacity'
- name='from_opacity'
- value={temporaryTile.settings.from_opacity}
- onChange={this.handleSettingsSelect}
- min={0.0}
- max={1.0}
- step={0.01}
- />
- <ColorInput
- title='To'
- name='to_color'
- data={temporaryTile.settings}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- <Slider
- title='Opacity'
- name='to_opacity'
- value={temporaryTile.settings.to_opacity}
- onChange={this.handleSettingsSelect}
- min={0.0}
- max={1.0}
- step={0.01}
- />
- <Slider
- title='Angle'
- name='angle'
- value={temporaryTile.settings.angle}
- onChange={this.handleSettingsSelect}
- min={0.0}
- max={360.0}
- step={0.1}
- />
- <Slider
- title='Stop'
- name='stop'
- value={temporaryTile.settings.stop}
- onChange={this.handleSettingsSelect}
- min={0.0}
- max={100.0}
- step={0.1}
- />
- <div className='row pair'>
- <NumberInput
- title="Width"
- name="width"
- data={temporaryTile.settings}
- min={0}
- max={2400}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- <NumberInput
- title="Height"
- name="height"
- data={temporaryTile.settings}
- min={0}
- max={2400}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- </div>
- </div>
- )
- }
-
- renderScriptForm() {
- const { temporaryTile } = this.props
- const { errorFields } = this.state
- return (
- <div>
- <TextArea
- title=""
- name="content"
- required
- data={temporaryTile.settings}
- error={errorFields.has('content')}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- <div>
- Scripts will be run on the live site when this page loads.
- </div>
- </div>
- )
- }
-
- renderHyperlinkForm() {
- const { temporaryTile } = this.props
- const { pageList, popupList } = this.state
- const isExternalLink = temporaryTile.target_page_id === EXTERNAL_LINK
- const isPopupLink = (
- temporaryTile.target_page_id === OPEN_POPUP_LINK ||
- temporaryTile.target_page_id === CLOSE_POPUP_LINK
- )
- return (
- <div>
- <div className={'row selects'}>
- <Select
- title=''
- name='target_page_id'
- selected={temporaryTile.target_page_id || NO_LINK}
- options={pageList}
- onChange={this.handleSelect}
- />
- <Select
- title=''
- name='cursor'
- selected={temporaryTile.settings.cursor}
- options={CURSORS}
- defaultOption="Cursor"
- onChange={this.handleSettingsSelect}
- />
- </div>
- {isExternalLink && (
- <div>
- <TextInput
- title=""
- placeholder='http://'
- name="external_link_url"
- data={temporaryTile.settings}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- </div>
- )}
- {(temporaryTile.target_page_id === OPEN_POPUP_LINK || temporaryTile.target_page_id === CLOSE_POPUP_LINK) && (
- <div className='row single'>
- <Select
- title="Popup"
- name='target_popup'
- selected={temporaryTile.settings.target_popup || NO_POPUP}
- options={popupList}
- onChange={this.handleSettingsSelect}
- />
- </div>
- )}
- </div>
- )
- }
-
- renderAudioForm() {
- const { temporaryTile } = this.props
- return (
- <div>
- <Checkbox
- label="Sound effects"
- name="has_audio"
- className='short'
- checked={temporaryTile.settings.has_audio}
- onChange={this.handleSettingsSelect}
- />
- {temporaryTile.settings.has_audio && (
- <div>
- <div className='row single'>
- <AudioSelect
- title="On click"
- name="audio_on_click_id"
- selected={temporaryTile.settings.audio_on_click_id}
- onChange={this.handleSettingsSelect}
- />
- </div>
-
- {!!temporaryTile.settings.audio_on_click_id && (
- <Checkbox
- label="Navigate when audio finishes"
- name="navigate_when_audio_finishes"
- className='short'
- checked={temporaryTile.settings.navigate_when_audio_finishes}
- onChange={this.handleSettingsSelect}
- autoComplete="off"
- />
- )}
-
- <div className='row single'>
- <AudioSelect
- title="On hover"
- name="audio_on_hover_id"
- selected={temporaryTile.settings.audio_on_hover_id}
- onChange={this.handleSettingsSelect}
- />
- </div>
- </div>
- )}
- </div>
- )
- }
-
- renderMiscForm() {
- const { temporaryTile } = this.props
- return (
- <div>
- <div className='row single'>
- <Select
- name='units'
- selected={temporaryTile.settings.units || 'px'}
- options={UNITS}
- title='Units'
- onChange={this.handleSettingsSelect}
- />
- </div>
- <Slider
- title='Opacity'
- name='opacity'
- value={temporaryTile.settings.opacity}
- onChange={this.handleSettingsSelect}
- min={0.0}
- max={1.0}
- step={0.01}
- />
- <Slider
- title='Scale'
- name='scale'
- value={temporaryTile.settings.scale}
- onChange={this.handleSettingsSelect}
- min={0.01}
- max={10.0}
- step={0.01}
- />
- <Slider
- title='Rotation'
- name='rotation'
- value={temporaryTile.settings.rotation}
- onChange={this.handleSettingsSelect}
- min={-180.0}
- max={180.0}
- step={1}
- type='int'
- />
- <Checkbox
- label="Element is a Popup"
- name="is_popup"
- className='short'
- checked={temporaryTile.settings.is_popup}
- onChange={this.handleSettingsSelect}
- autoComplete="off"
- />
- {temporaryTile.settings.is_popup && (
- <div className='row single_text'>
- <TextInput
- title="Popup group"
- name="popup_group"
- data={temporaryTile.settings}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- </div>
- )}
- <Checkbox
- label="Wait to appear"
- name="wait_to_appear"
- className='short'
- checked={temporaryTile.settings.wait_to_appear}
- onChange={this.handleSettingsSelect}
- autoComplete="off"
- />
- {temporaryTile.settings.wait_to_appear && (
- <div className='row single_text'>
- <TextInput
- title="Appear after"
- name="appear_after"
- data={temporaryTile.settings}
- onChange={this.handleSettingsChange}
- autoComplete="off"
- />
- </div>
- )}
- <Checkbox
- label="Hide on click"
- name="hide_on_click"
- className='short'
- checked={temporaryTile.settings.hide_on_click}
- onChange={this.handleSettingsSelect}
- autoComplete="off"
- />
- </div>
- )
- }
}
const mapStateToProps = state => ({