aboutsummaryrefslogtreecommitdiff
path: root/src/components/search/search.js
blob: 877d6f300fd718d9d336180812132ab8a29bb3d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import FollowCard from '../follow_card/follow_card.vue'
import Conversation from '../conversation/conversation.vue'
import Status from '../status/status.vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
import map from 'lodash/map'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
  faCircleNotch,
  faSearch
} from '@fortawesome/free-solid-svg-icons'
import { uniqBy } from 'lodash'

library.add(
  faCircleNotch,
  faSearch
)

const Search = {
  components: {
    FollowCard,
    Conversation,
    Status,
    TabSwitcher
  },
  props: [
    'query'
  ],
  data () {
    return {
      loaded: false,
      loading: false,
      searchTerm: this.query || '',
      userIds: [],
      statuses: [],
      hashtags: [],
      currenResultTab: 'statuses',

      statusesOffset: 0,
      lastStatusFetchCount: 0,
      lastQuery: ''
    }
  },
  computed: {
    users () {
      return this.userIds.map(userId => this.$store.getters.findUser(userId))
    },
    visibleStatuses () {
      const allStatusesObject = this.$store.state.statuses.allStatusesObject

      return this.statuses.filter(status =>
        allStatusesObject[status.id] && !allStatusesObject[status.id].deleted
      )
    }
  },
  mounted () {
    this.search(this.query)
  },
  watch: {
    query (newValue) {
      this.searchTerm = newValue
      this.search(newValue)
    }
  },
  methods: {
    newQuery (query) {
      this.$router.push({ name: 'search', query: { query } })
      this.$refs.searchInput.focus()
    },
    search (query, searchType = null) {
      if (!query) {
        this.loading = false
        return
      }

      this.loading = true
      this.$refs.searchInput.blur()
      if (this.lastQuery !== query) {
        this.userIds = []
        this.hashtags = []
        this.statuses = []

        this.statusesOffset = 0
        this.lastStatusFetchCount = 0
      }

      this.$store.dispatch('search', { q: query, resolve: true, offset: this.statusesOffset, type: searchType })
        .then(data => {
          this.loading = false

          const oldLength = this.statuses.length

          // Always append to old results. If new results are empty, this doesn't change anything
          this.userIds = this.userIds.concat(map(data.accounts, 'id'))
          this.statuses = uniqBy(this.statuses.concat(data.statuses), 'id')
          this.hashtags = this.hashtags.concat(data.hashtags)

          this.currenResultTab = this.getActiveTab()
          this.loaded = true

          // Offset from whatever we already have
          this.statusesOffset = this.statuses.length
          // Because the amount of new statuses can actually be zero, compare to old lenght instead
          this.lastStatusFetchCount = this.statuses.length - oldLength
          this.lastQuery = query
        })
    },
    resultCount (tabName) {
      const length = this[tabName].length
      return length === 0 ? '' : ` (${length})`
    },
    onResultTabSwitch (key) {
      this.currenResultTab = key
    },
    getActiveTab () {
      if (this.visibleStatuses.length > 0) {
        return 'statuses'
      } else if (this.users.length > 0) {
        return 'people'
      } else if (this.hashtags.length > 0) {
        return 'hashtags'
      }

      return 'statuses'
    },
    lastHistoryRecord (hashtag) {
      return hashtag.history && hashtag.history[0]
    }
  }
}

export default Search