<commit_before>/* @flow */
'use strict'

import Relay from 'react-relay'
import React from 'react'
import { View, StyleSheet, TouchableHighlight, LayoutAnimation, Text, Image, Dimensions } from 'react-native'

import Spinner from '../../spinner'
import Grid from '../../artwork_grids/generic_grid'
import Header from './artwork_rail_header'
import Separator from '../../separator'
import colors from '../../../../data/colors'
import SwitchBoard from '../../../modules/switch_board'
import fragments from './relay_fragments'

const isPad = Dimensions.get('window').width > 700

const additionalContentRails = [
  'followed_artists',
  'saved_works',
  'live_auctions',
  'current_fairs',
  'genes',
  'generic_gene',
]

class ArtworkRail extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      expanded: false,
      gridHeight: 0,
    }
  }

  componentDidMount() {
    this.props.relay.setVariables({ fetchContent: true })
  }

  expand = () => {
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)
    this.setState({ expanded: true })
  }

  hasAdditionalContent() {
    return additionalContentRails.indexOf(this.props.rail.key) > -1
  }

  handleViewAll = () => {
    const context = this.props.rail.context
    const key = this.props.rail.key

    let url = null
    switch (key) {
      case 'followed_artists':
        url = '/me/notifications'
        break
      case 'related_artists':
        url = context && context.artist.href
        break
      case 'saved_works':
        url = '/user/saves#saved-artworks'
        break
      case 'genes':
      case 'generic_gene':
      case 'current_fairs':
      case 'live_auctions':
        url = context && context.href
        break
    }

    if (url) { SwitchBoard.presentNavigationViewController(this, url) }
  }


  onGridLayout(event) {
    this.setState({ gridHeight: event.nativeEvent.layout.height })
  }

  expandable() {
    return this.props.rail.results.length > (isPad ? 3 : 6)
  }

  mainContainerHeight() {
    // includes height of View All button (if present), the separator, and a 30px margin
    const supplementaryHeight = this.hasAdditionalContent() ? 101 : 30

    if (this.expandable()) {
      const initialRailHeight = isPad ? 410 : 510
      return this.state.expanded ? this.state.gridHeight + supplementaryHeight : initialRailHeight
    } else {
      return this.state.gridHeight + supplementaryHeight
    }
  }

  gridContainerHeight() {
    if (this.expandable()) {
      const initialInternalViewHeight = isPad ? 420 : 520
      return this.state.expanded ? this.state.gridHeight : initialInternalViewHeight
    } else {
      return this.state.gridHeight
    }
  }

  renderGrid() {
    return (
      <View style={[styles.gridContainer, { height: this.gridContainerHeight() }]}>
        <View onLayout={this.onGridLayout.bind(this)}>
          <Grid artworks={this.props.rail.results}/>
        </View>
      </View>
    )
  }

  renderViewAllButton() {
    if (this.expandable() && !this.state.expanded) { return }

    if (this.hasAdditionalContent()) {
      return (
        <TouchableHighlight style={styles.viewAllButton} onPress={this.handleViewAll} underlayColor={'gray'}>
          <Text style={styles.viewAllText}>VIEW ALL</Text>
        </TouchableHighlight>
      )
    }

      // otherwise, use a spacer view
      return <View style={{ height: 30 }} />
    }

  renderExpansionButton() {
    if (this.expandable() && !this.state.expanded) {
      return (
        <TouchableHighlight style={styles.expansionButton} onPress={this.expand} underlayColor={'white'}>
            <Image style={{height: 8, width: 15, alignSelf: 'center'}} source={require('../../../../images/chevron.png')} />
        </TouchableHighlight>
      )
    }
  }

  renderModuleResults() {
    if (this.props.rail.results && this.props.rail.results.length) {
      return (
        <View style={[styles.container, { height: this.mainContainerHeight() }]}>
          { this.renderGrid() }
          { this.renderViewAllButton() }
          <Separator style={{marginTop: this.state.expanded ? 20 : 0 }}/>
          { this.renderExpansionButton() }
        </View>
      )
    } else if (this.props.rail.results) {
      // temporary; for those pesky empty rails on staging
      return null
    } else {
      return <Spinner style={{ flex: 1 }} />
    }
  }

  render() {
    const sideMargin = isPad ? 40 : 20
    return (
      <View style={{ marginBottom: 20 }}>
        <Header rail={this.props.rail}/>
        <View style={{ marginLeft: sideMargin, marginRight: sideMargin, minHeight: 400 }}>
          { this.renderModuleResults() }
        </View>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: 'white',
  },
  gridContainer: {
    overflow: 'hidden',
  },
  expansionButton: {
    height: 40,
    width: 40,
    backgroundColor: 'white',
    borderColor: colors['gray-regular'],
    borderWidth: 1,
    borderRadius: 30,
    alignSelf: 'center',
    top: -20,
    justifyContent: 'center'
  },
  viewAllButton: {
    width: 240,
    height: 40,
    backgroundColor: 'black',
    alignSelf: 'center',
    justifyContent: 'center',
    marginBottom: 30,
    marginTop: 30,
  },
  viewAllText: {
    color: 'white',
    textAlign: 'center',
    fontSize: 14,
    fontFamily: 'Avant Garde Gothic ITCW01Dm',
  }
})

export default Relay.createContainer(ArtworkRail, {
  initialVariables: {
    fetchContent: false,
  },

  fragments: {
    rail: () => Relay.QL`
      fragment on HomePageArtworkModule {
        ${Header.getFragment('rail')}
        key
        context {
          ${fragments.relatedArtistFragment}
          ${fragments.geneFragment}
          ${fragments.auctionFragment}
          ${fragments.fairFragment}
        }
        results @include(if: $fetchContent) {
          ${Grid.getFragment('artworks')}
        }
      }
    `,
  }
})
<commit_msg>[Home] Use minHeight only during content loading to prevent margin issues<commit_after>/* @flow */
'use strict'

import Relay from 'react-relay'
import React from 'react'
import { View, StyleSheet, TouchableHighlight, LayoutAnimation, Text, Image, Dimensions } from 'react-native'

import Spinner from '../../spinner'
import Grid from '../../artwork_grids/generic_grid'
import Header from './artwork_rail_header'
import Separator from '../../separator'
import colors from '../../../../data/colors'
import SwitchBoard from '../../../modules/switch_board'
import fragments from './relay_fragments'

const isPad = Dimensions.get('window').width > 700

const additionalContentRails = [
  'followed_artists',
  'saved_works',
  'live_auctions',
  'current_fairs',
  'genes',
  'generic_gene',
]

class ArtworkRail extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      expanded: false,
      gridHeight: 0,
    }
  }

  componentDidMount() {
    this.props.relay.setVariables({ fetchContent: true })
  }

  expand = () => {
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)
    this.setState({ expanded: true })
  }

  hasAdditionalContent() {
    return additionalContentRails.indexOf(this.props.rail.key) > -1
  }

  handleViewAll = () => {
    const context = this.props.rail.context
    const key = this.props.rail.key

    let url = null
    switch (key) {
      case 'followed_artists':
        url = '/me/notifications'
        break
      case 'related_artists':
        url = context && context.artist.href
        break
      case 'saved_works':
        url = '/user/saves#saved-artworks'
        break
      case 'genes':
      case 'generic_gene':
      case 'current_fairs':
      case 'live_auctions':
        url = context && context.href
        break
    }

    if (url) { SwitchBoard.presentNavigationViewController(this, url) }
  }


  onGridLayout(event) {
    this.setState({ gridHeight: event.nativeEvent.layout.height })
  }

  expandable() {
    return this.props.rail.results.length > (isPad ? 3 : 6)
  }

  mainContainerHeight() {
    // includes height of View All button (if present), the separator, and a 30px margin
    const supplementaryHeight = this.hasAdditionalContent() ? 101 : 30

    if (this.expandable()) {
      const initialRailHeight = isPad ? 410 : 510
      return this.state.expanded ? this.state.gridHeight + supplementaryHeight : initialRailHeight
    } else {
      return this.state.gridHeight + supplementaryHeight
    }
  }

  gridContainerHeight() {
    if (this.expandable()) {
      const initialInternalViewHeight = isPad ? 420 : 520
      return this.state.expanded ? this.state.gridHeight : initialInternalViewHeight
    } else {
      return this.state.gridHeight
    }
  }

  renderGrid() {
    return (
      <View style={[styles.gridContainer, { height: this.gridContainerHeight() }]}>
        <View onLayout={this.onGridLayout.bind(this)}>
          <Grid artworks={this.props.rail.results}/>
        </View>
      </View>
    )
  }

  renderViewAllButton() {
    if (this.expandable() && !this.state.expanded) { return }

    if (this.hasAdditionalContent()) {
      return (
        <TouchableHighlight style={styles.viewAllButton} onPress={this.handleViewAll} underlayColor={'gray'}>
          <Text style={styles.viewAllText}>VIEW ALL</Text>
        </TouchableHighlight>
      )
    }

      // otherwise, use a spacer view
      return <View style={{ height: 30 }} />
    }

  renderExpansionButton() {
    if (this.expandable() && !this.state.expanded) {
      return (
        <TouchableHighlight style={styles.expansionButton} onPress={this.expand} underlayColor={'white'}>
            <Image style={{height: 8, width: 15, alignSelf: 'center'}} source={require('../../../../images/chevron.png')} />
        </TouchableHighlight>
      )
    }
  }

  renderModuleResults() {
    if (this.props.rail.results && this.props.rail.results.length) {
      return (
        <View style={[styles.container, { height: this.mainContainerHeight() }]}>
          { this.renderGrid() }
          { this.renderViewAllButton() }
          <Separator style={{marginTop: this.state.expanded ? 20 : 0 }}/>
          { this.renderExpansionButton() }
        </View>
      )
    } else if (this.props.rail.results) {
      // temporary; for those pesky empty rails on staging
      return null
    } else {
      return <Spinner style={{ flex: 1 }} />
    }
  }

  render() {
    const sideMargin = isPad ? 40 : 20
    const style = { marginLeft: sideMargin, marginRight: sideMargin }
    if (!this.props.relay.variables.fetchContent) {
      // if there's no content, set minHeight to prevent spinners from all the rails showing
      style.minHeight = 500
    }
    return (
      <View style={{ marginBottom: 20 }}>
        <Header rail={this.props.rail}/>
        <View style={style}>
          { this.renderModuleResults() }
        </View>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: 'white',
  },
  gridContainer: {
    overflow: 'hidden',
  },
  expansionButton: {
    height: 40,
    width: 40,
    backgroundColor: 'white',
    borderColor: colors['gray-regular'],
    borderWidth: 1,
    borderRadius: 30,
    alignSelf: 'center',
    top: -20,
    justifyContent: 'center'
  },
  viewAllButton: {
    width: 240,
    height: 40,
    backgroundColor: 'black',
    alignSelf: 'center',
    justifyContent: 'center',
    marginBottom: 30,
    marginTop: 30,
  },
  viewAllText: {
    color: 'white',
    textAlign: 'center',
    fontSize: 14,
    fontFamily: 'Avant Garde Gothic ITCW01Dm',
  }
})

export default Relay.createContainer(ArtworkRail, {
  initialVariables: {
    fetchContent: false,
  },

  fragments: {
    rail: () => Relay.QL`
      fragment on HomePageArtworkModule {
        ${Header.getFragment('rail')}
        key
        context {
          ${fragments.relatedArtistFragment}
          ${fragments.geneFragment}
          ${fragments.auctionFragment}
          ${fragments.fairFragment}
        }
        results @include(if: $fetchContent) {
          ${Grid.getFragment('artworks')}
        }
      }
    `,
  }
})

{'fraction_non_alphanumeric': 0.1344178785637992, 'fraction_numerical': 0.010845452304658615, 'mean_word_length': 2.6334328358208956, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5893893', 'n_tokens_mistral': 3875, 'n_tokens_neox': 3664, 'n_words': 800}