<commit_before>import React from 'react';
import {
  ActivityIndicator,
  Keyboard,
  ListView,
  NativeModules,
  Platform,
  ScrollView,
  StyleSheet,
  Text,
  TouchableHighlight,
  View,
} from 'react-native';
import TouchableNativeFeedbackSafe from '@exponent/react-native-touchable-native-feedback-safe';

import Colors from '../constants/Colors';
import ExUrls from 'ExUrls';
import Layout from '../constants/Layout';
import ProfileCard from '../components/ProfileCard';
import ProjectCard from '../components/ProjectCard';
import SharedStyles from '../constants/SharedStyles';

let { ExponentKernel } = NativeModules;

const SectionIds = [
  'UserSearchResult',
  'AppSearchResult',
];

function resultsAreEmpty(results) {
  if (!results) {
    return true;
  }

  if (!results.UserSearchResult && !results.AppSearchResult) {
    return true;
  }

  return false;
}

export default class SearchResults extends React.Component {
  state = {
    dataSource: new ListView.DataSource({
      sectionHeaderHasChanged: (s1, s2) => s1 !== s2,
      rowHasChanged: (r1, r2) => r1 !== r2,
      lastQueryHadNoResults: false,
    }),
  }

  componentWillMount() {
    this._maybeUpdateDataSource(this.props);
  }

  componentWillReceiveProps(nextProps) {
    this._maybeSetPreviousQueryNoResults(nextProps);
    this._maybeUpdateDataSource(nextProps);
  }

  render() {
    return (
      <View style={{flex: 1}}>
        {this._renderContent()}
        {this._maybeRenderLoading()}
      </View>
    );
  }

  // PLEASE DO NOT MAKE FUN OF ME :<
  // I will improve this soon - Brent
  _maybeSetPreviousQueryNoResults = (newProps) => {
    if (newProps.query.length < 2) {
      if (this.state.lastQueryHadNoResults) {
        this.setState({lastQueryHadNoResults: false});
      }

      return;
    }

    if (!this.props.data.loading && this.props.query.length < 2) {
      return;
    }

    if (newProps.loading) {
      return;
    }

    if (resultsAreEmpty(newProps.results)) {
      if (!this.state.lastQueryHadNoResults) {
        this.setState({lastQueryHadNoResults: true});
      }
    } else  {
      if (this.state.lastQueryHadNoResults) {
        this.setState({lastQueryHadNoResults: false});
      }
    }
  }

  _maybeUpdateDataSource = (newProps) => {
    if (newProps.data.results !== this.props.data.results) {
      let { dataSource } = this.state;
      let { results } = newProps.data;
      results = results || {};
      results.UserSearchResult = results.UserSearchResult || [];
      results.AppSearchResult = results.AppSearchResult || [];

      let newDataSource = dataSource.cloneWithRowsAndSections(
        results,
        SectionIds,
      );

      this.setState({ dataSource: newDataSource });
    }
  }

  _maybeRenderLoading = () => {
    // if (this.props.data.loading) {
    //   return (
    //     <View style={[StyleSheet.absoluteFill, {padding: 30, alignItems: 'center'}]} pointerEvents="none">
    //       <ActivityIndicator />
    //     </View>
    //   );
    // }
  }

  _renderContent = () => {
    if (this.state.dataSource.getRowCount() === 0 &&
        (!this.props.data.loading || this.state.lastQueryHadNoResults) &&
        this.props.query.length >= 2) {
      return (
        <ScrollView
          keyboardShouldPersistTaps="always"
          keyboardDismissMode="on-drag"
          style={styles.scrollContainer}>
          <View style={[SharedStyles.sectionLabelContainer, {backgroundColor: Colors.greyBackground, marginTop: 7,}]}>
            <Text style={SharedStyles.sectionLabelText}>
              NO RESULTS FOUND
            </Text>
          </View>

          <TouchableNativeFeedbackSafe
            onPress={this._handleOpenUrl}
            fallback={TouchableHighlight}
            underlayColor="#b7b7b7"
            style={styles.cardContainer}>
            <Text style={styles.cardTitleText}>
              Tap to attempt to open project at:
            </Text>
            <Text style={styles.urlText}>
              {this.props.query}
            </Text>
          </TouchableNativeFeedbackSafe>
        </ScrollView>
      );
    } else {
      return (
        <ListView
          keyboardShouldPersistTaps="always"
          keyboardDismissMode="on-drag"
          dataSource={this.state.dataSource}
          renderRow={this._renderRow}
          renderSectionHeader={this._renderSectionHeader}
          contentContainerStyle={{paddingTop: 5, paddingBottom: 15}}
          style={{flex: 1, backgroundColor: Colors.greyBackground}}
        />
      );
    }
  }

  _handleOpenUrl = () => {
    Keyboard.dismiss();
    let url = ExUrls.normalizeUrl(this.props.query);
    if (ExponentKernel) {
      // don't validate that we can open the url, just go ahead and try it.
      ExponentKernel.openURL(url);
    } else {
      Linking.openURL(url);
    }
  }


  _renderSectionHeader = (sectionData, sectionId) => {<commit_msg>Only call ExponentKernel.openURL when it is defined<commit_after>import React from 'react';
import {
  ActivityIndicator,
  Keyboard,
  ListView,
  NativeModules,
  Platform,
  ScrollView,
  StyleSheet,
  Text,
  TouchableHighlight,
  View,
} from 'react-native';
import TouchableNativeFeedbackSafe from '@exponent/react-native-touchable-native-feedback-safe';

import Colors from '../constants/Colors';
import ExUrls from 'ExUrls';
import Layout from '../constants/Layout';
import ProfileCard from '../components/ProfileCard';
import ProjectCard from '../components/ProjectCard';
import SharedStyles from '../constants/SharedStyles';

let { ExponentKernel } = NativeModules;

const SectionIds = [
  'UserSearchResult',
  'AppSearchResult',
];

function resultsAreEmpty(results) {
  if (!results) {
    return true;
  }

  if (!results.UserSearchResult && !results.AppSearchResult) {
    return true;
  }

  return false;
}

export default class SearchResults extends React.Component {
  state = {
    dataSource: new ListView.DataSource({
      sectionHeaderHasChanged: (s1, s2) => s1 !== s2,
      rowHasChanged: (r1, r2) => r1 !== r2,
      lastQueryHadNoResults: false,
    }),
  }

  componentWillMount() {
    this._maybeUpdateDataSource(this.props);
  }

  componentWillReceiveProps(nextProps) {
    this._maybeSetPreviousQueryNoResults(nextProps);
    this._maybeUpdateDataSource(nextProps);
  }

  render() {
    return (
      <View style={{flex: 1}}>
        {this._renderContent()}
        {this._maybeRenderLoading()}
      </View>
    );
  }

  // PLEASE DO NOT MAKE FUN OF ME :<
  // I will improve this soon - Brent
  _maybeSetPreviousQueryNoResults = (newProps) => {
    if (newProps.query.length < 2) {
      if (this.state.lastQueryHadNoResults) {
        this.setState({lastQueryHadNoResults: false});
      }

      return;
    }

    if (!this.props.data.loading && this.props.query.length < 2) {
      return;
    }

    if (newProps.loading) {
      return;
    }

    if (resultsAreEmpty(newProps.results)) {
      if (!this.state.lastQueryHadNoResults) {
        this.setState({lastQueryHadNoResults: true});
      }
    } else  {
      if (this.state.lastQueryHadNoResults) {
        this.setState({lastQueryHadNoResults: false});
      }
    }
  }

  _maybeUpdateDataSource = (newProps) => {
    if (newProps.data.results !== this.props.data.results) {
      let { dataSource } = this.state;
      let { results } = newProps.data;
      results = results || {};
      results.UserSearchResult = results.UserSearchResult || [];
      results.AppSearchResult = results.AppSearchResult || [];

      let newDataSource = dataSource.cloneWithRowsAndSections(
        results,
        SectionIds,
      );

      this.setState({ dataSource: newDataSource });
    }
  }

  _maybeRenderLoading = () => {
    // if (this.props.data.loading) {
    //   return (
    //     <View style={[StyleSheet.absoluteFill, {padding: 30, alignItems: 'center'}]} pointerEvents="none">
    //       <ActivityIndicator />
    //     </View>
    //   );
    // }
  }

  _renderContent = () => {
    if (this.state.dataSource.getRowCount() === 0 &&
        (!this.props.data.loading || this.state.lastQueryHadNoResults) &&
        this.props.query.length >= 2) {
      return (
        <ScrollView
          keyboardShouldPersistTaps="always"
          keyboardDismissMode="on-drag"
          style={styles.scrollContainer}>
          <View style={[SharedStyles.sectionLabelContainer, {backgroundColor: Colors.greyBackground, marginTop: 7,}]}>
            <Text style={SharedStyles.sectionLabelText}>
              NO RESULTS FOUND
            </Text>
          </View>

          <TouchableNativeFeedbackSafe
            onPress={this._handleOpenUrl}
            fallback={TouchableHighlight}
            underlayColor="#b7b7b7"
            style={styles.cardContainer}>
            <Text style={styles.cardTitleText}>
              Tap to attempt to open project at:
            </Text>
            <Text style={styles.urlText}>
              {this.props.query}
            </Text>
          </TouchableNativeFeedbackSafe>
        </ScrollView>
      );
    } else {
      return (
        <ListView
          keyboardShouldPersistTaps="always"
          keyboardDismissMode="on-drag"
          dataSource={this.state.dataSource}
          renderRow={this._renderRow}
          renderSectionHeader={this._renderSectionHeader}
          contentContainerStyle={{paddingTop: 5, paddingBottom: 15}}
          style={{flex: 1, backgroundColor: Colors.greyBackground}}
        />
      );
    }
  }

  _handleOpenUrl = () => {
    Keyboard.dismiss();
    let url = ExUrls.normalizeUrl(this.props.query);
    if (ExponentKernel && ExponentKernel.openURL) {
      // don't validate that we can open the url, just go ahead and try it.
      ExponentKernel.openURL(url);
    } else {
      Linking.openURL(url);
    }
  }


  _renderSectionHeader = (sectionData, sectionId) => {
{'fraction_non_alphanumeric': 0.12573395424174935, 'fraction_numerical': 0.004656813120064791, 'mean_word_length': 2.562567616300036, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 57, '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': '4920302', 'n_tokens_mistral': 2967, 'n_tokens_neox': 2910, 'n_words': 547}