Skip to content
Snippets Groups Projects
SearchBar.vue 7.05 KiB
Newer Older
  • Learn to ignore specific revisions
  • <template>
      <div class="ui fluid category search">
    
        <slot></slot><div class="ui icon input">
    
          <input ref="search" type="search" class="prompt" name="search" :placeholder="labels.placeholder" @keydown.esc="$event.target.blur()">
    
          <i class="search icon"></i>
        </div>
        <div class="results"></div>
    
        <GlobalEvents
          @keydown.shift.f.prevent.exact="focusSearch"
        />
    
      </div>
    </template>
    
    <script>
    import jQuery from 'jquery'
    import router from '@/router'
    
    import lodash from '@/lodash'
    
    import GlobalEvents from "@/components/utils/global-events"
    
      components: {
      GlobalEvents,
      },
    
    Eliot Berriot's avatar
    Eliot Berriot committed
      computed: {
        labels () {
          return {
    
    Jo Vuit's avatar
    Jo Vuit committed
            placeholder: this.$pgettext('Sidebar/Search/Input.Placeholder', 'Search for artists, albums, tracks…')
    
    jovuit's avatar
    jovuit committed
        let artistLabel = this.$pgettext('*/*/*/Noun', 'Artist')
        let albumLabel = this.$pgettext('*/*/*', 'Album')
        let trackLabel = this.$pgettext('*/*/*/Noun', 'Track')
    
        let tagLabel = this.$pgettext('*/*/*/Noun', 'Tag')
    
        var searchQuery;
    
        jQuery(this.$el).keypress(function(e) {
          if(e.which == 13) {
    
            // Cancel any API search request to backend…
    
            jQuery(this.$el).search('cancel query');
    
            // Go direct to the artist page…
    
            router.push("/library/artists?query=" + searchQuery + "&page=1&paginateBy=25&ordering=name");
    	}
        });
    
    
    
        jQuery(this.$el).search({
          type: 'category',
          minCharacters: 3,
    
          showNoResults: true,
          error: {
            noResultsHeader: this.$pgettext('Sidebar/Search/Error', 'No matches found'),
            noResults: this.$pgettext('Sidebar/Search/Error.Label', 'Sorry, there are no results for this search')
          },
    
            jQuery(self.$el).search("set value", searchQuery)
    
            jQuery(self.$el).search("hide results")
            return false
    
          onSearchQuery (query) {
            self.$emit('search')
    
          apiSettings: {
            beforeXHR: function (xhrObject) {
    
              if (!self.$store.state.auth.authenticated) {
                return xhrObject
              }
    
              xhrObject.setRequestHeader('Authorization', self.$store.getters['auth/header'])
    
              return xhrObject
            },
            onResponse: function (initialResponse) {
    
              let objId = self.extractObjId(searchQuery)
    
              let isEmptyResults = true
    
                {
                  code: 'federation',
                  name: self.$pgettext('*/*/*', 'Federation'),
                },
    
                {
                  code: 'podcasts',
                  name: self.$pgettext('*/*/*', 'Podcasts'),
                },
    
                  route: 'library.artists.detail',
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                  name: artistLabel,
    
                  getTitle (r) {
                    return r.name
                  },
                  getDescription (r) {
                    return ''
    
                  },
                  getId (t) {
                    return t.id
    
                  route: 'library.albums.detail',
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                  name: albumLabel,
    
                  getTitle (r) {
                    return r.title
                  },
                  getDescription (r) {
    
                  },
                  getId (t) {
                    return t.id
    
                  route: 'library.tracks.detail',
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                  name: trackLabel,
    
                  getTitle (r) {
                    return r.title
                  },
                  getDescription (r) {
    
                    if (r.album) {
                      return `${r.album.artist.name} - ${r.album.title}`
                    } else {
                      return r.artist.name
                    }
    
                  },
                  getId (t) {
                    return t.id
                  }
                },
                {
                  code: 'tags',
                  route: 'library.tags.detail',
                  name: tagLabel,
                  getTitle (r) {
    
                  },
                  getDescription (r) {
                    return ''
                  },
                  getId (t) {
                    return t.name
    
                  }
                }
              ]
              categories.forEach(category => {
                results[category.code] = {
                  name: category.name,
                  results: []
                }
    
                if (category.code === 'federation') {
    
                  if (objId) {
                    isEmptyResults = false
                    let searchMessage = self.$pgettext('Search/*/*', 'Search on the fediverse')
                    results['federation'] = {
                      name: self.$pgettext('*/*/*', 'Federation'),
                      results: [{
                        title: searchMessage,
                        routerUrl: {
                          name: 'search',
                          query: {
                            id: objId,
                          }
                        }
                      }]
                    }
                  }
                }
    
                else if (category.code === 'podcasts') {
                  if (objId) {
                    isEmptyResults = false
                    let searchMessage = self.$pgettext('Search/*/*', 'Subscribe to podcast via RSS')
                    results['podcasts'] = {
                      name: self.$pgettext('*/*/*', 'Podcasts'),
                      results: [{
                        title: searchMessage,
                        routerUrl: {
                          name: 'search',
                          query: {
                            id: objId,
                            type: "rss"
                          }
                        }
                      }]
                    }
                  }
                }
    
                else {
                  initialResponse[category.code].forEach(result => {
                    isEmptyResults = false
                    let id = category.getId(result)
                    results[category.code].results.push({
                      title: category.getTitle(result),
                      id,
                      routerUrl: {
                        name: category.route,
                        params: {
                          id
                        }
                      },
                      description: category.getDescription(result)
                    })
    
                results: isEmptyResults ? {} : results
              }
    
            url: this.$store.getters['instance/absoluteUrl']('api/v1/search?query={query}')
    
      },
      methods: {
        focusSearch () {
          this.$refs.search.focus()
        },
    
        extractObjId (query) {
          query = lodash.trim(query)
          query = lodash.trim(query, '@')
          if (query.indexOf(' ') > -1) {
            return
          }
          if (query.startsWith('http://') || query.startsWith('https://')) {
            return query
          }
          if (query.split('@').length > 1) {
            return query
          }
        }
    
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    </style>