metamaps--metamaps/frontend/src/Metamaps/GlobalUI/Search.js

251 lines
8.6 KiB
JavaScript
Raw Normal View History

2016-10-02 14:37:38 +00:00
/* global $, Hogan, Bloodhound, CanvasLoader */
2016-09-29 16:20:16 +00:00
react-router and rebuild app structure in react (#1091) * initial restructuring * stuff * lock version number * just keep using current mapinfobox * fix map upperRightUI layout * make mapsWidth work and add mobile * remove filterBoxOpen for now * redo the mobile menu in react * get account menu and invite lightbox working * fixed maps scrolling * make other routes work * fix signed out home page * fix accountbox toggling * add metacode edit routes * lots of fixes * fix map chat layout and tab bug * improve topic card readability and fix dragging bug * fixup mapchat stuff * fix up navigation to use react-router * jquery no longer handling access requests * handle case where user hasn't loaded yet * this shouldn't have been removed * add frame for topic view * rewrite map instructions * fix toast (and sign out bug) * fix apps pages and missing routes * made our request invite page look nice * filter box in react * forgot to add one proptype * remove extra comments * handle page title and mobile title updates * reenable google analytics * make filterbox use onclickoutside * reenable topic view in react * fix csrf auth token * fix little homepage styling issue * try putting preparevizdata in a timeout * installing render log to count * little fixes * fixup filters * make filter map function names more readable * eslint helps * renaming for clarity * use onclickoutside for account/sign in box * add some logging to see whether this is source of many renders * turns out chatview was heavily hogging memory * tiimeout not needed
2017-03-16 21:58:56 +00:00
import { browserHistory } from 'react-router'
2016-09-29 16:20:16 +00:00
import Active from '../Active'
const Search = {
locked: false,
isOpen: false,
limitTopicsToMe: false,
limitMapsToMe: false,
changing: false,
optionsInitialized: false,
2016-11-07 20:25:08 +00:00
init: function(serverData) {
2016-09-29 16:20:16 +00:00
var self = Search
2016-10-03 00:32:37 +00:00
self.wildcardIconUrl = serverData['icons/wildcard.png']
self.userIconUrl = serverData['user.png']
// this is similar to Metamaps.Loading, but it's for the search element
react-router and rebuild app structure in react (#1091) * initial restructuring * stuff * lock version number * just keep using current mapinfobox * fix map upperRightUI layout * make mapsWidth work and add mobile * remove filterBoxOpen for now * redo the mobile menu in react * get account menu and invite lightbox working * fixed maps scrolling * make other routes work * fix signed out home page * fix accountbox toggling * add metacode edit routes * lots of fixes * fix map chat layout and tab bug * improve topic card readability and fix dragging bug * fixup mapchat stuff * fix up navigation to use react-router * jquery no longer handling access requests * handle case where user hasn't loaded yet * this shouldn't have been removed * add frame for topic view * rewrite map instructions * fix toast (and sign out bug) * fix apps pages and missing routes * made our request invite page look nice * filter box in react * forgot to add one proptype * remove extra comments * handle page title and mobile title updates * reenable google analytics * make filterbox use onclickoutside * reenable topic view in react * fix csrf auth token * fix little homepage styling issue * try putting preparevizdata in a timeout * installing render log to count * little fixes * fixup filters * make filter map function names more readable * eslint helps * renaming for clarity * use onclickoutside for account/sign in box * add some logging to see whether this is source of many renders * turns out chatview was heavily hogging memory * tiimeout not needed
2017-03-16 21:58:56 +00:00
if (!document.getElementById('searchLoading')) return
2016-09-29 16:20:16 +00:00
var loader = new CanvasLoader('searchLoading')
loader.setColor('#4fb5c0') // default is '#000000'
loader.setDiameter(24) // default is 40
loader.setDensity(41) // default is 40
loader.setRange(0.9) // default is 1.3
loader.show() // Hidden by default
2016-11-07 20:25:08 +00:00
$('.sidebarSearchIcon').click(function(e) {
2016-09-29 16:20:16 +00:00
$('.sidebarSearchField').focus()
})
2016-11-07 20:25:08 +00:00
$('.sidebarSearch').click(function(e) {
2016-09-29 16:20:16 +00:00
e.stopPropagation()
})
self.startTypeahead()
},
2016-09-30 03:32:58 +00:00
focus: function() {
$('.sidebarSearchField').focus()
2016-09-29 16:20:16 +00:00
},
2016-11-07 20:25:08 +00:00
startTypeahead: function() {
2016-09-29 16:20:16 +00:00
var self = Search
var mapheader = Active.Mapper ? '<div class="searchMapsHeader searchHeader"><h3 class="search-heading">Maps</h3><input type="checkbox" class="limitToMe" id="limitMapsToMe"></input><label for="limitMapsToMe" class="limitToMeLabel">added by me</label><div class="minimizeResults minimizeMapResults"></div><div class="clearfloat"></div></div>' : '<div class="searchMapsHeader searchHeader"><h3 class="search-heading">Maps</h3><div class="minimizeResults minimizeMapResults"></div><div class="clearfloat"></div></div>'
var topicheader = Active.Mapper ? '<div class="searchTopicsHeader searchHeader"><h3 class="search-heading">Topics</h3><input type="checkbox" class="limitToMe" id="limitTopicsToMe"></input><label for="limitTopicsToMe" class="limitToMeLabel">added by me</label><div class="minimizeResults minimizeTopicResults"></div><div class="clearfloat"></div></div>' : '<div class="searchTopicsHeader searchHeader"><h3 class="search-heading">Topics</h3><div class="minimizeResults minimizeTopicResults"></div><div class="clearfloat"></div></div>'
var mapperheader = '<div class="searchMappersHeader searchHeader"><h3 class="search-heading">Mappers</h3><div class="minimizeResults minimizeMapperResults"></div><div class="clearfloat"></div></div>'
var topics = {
name: 'topics',
limit: 9999,
display: s => s.label,
templates: {
2016-11-07 20:25:08 +00:00
notFound: function(s) {
2016-09-29 16:20:16 +00:00
return Hogan.compile(topicheader + $('#topicSearchTemplate').html()).render({
value: 'No results',
label: 'No results',
2016-10-03 00:32:37 +00:00
typeImageURL: self.wildcardIconUrl,
2016-09-29 16:20:16 +00:00
rtype: 'noresult'
})
},
header: topicheader,
2016-11-07 20:25:08 +00:00
suggestion: function(s) {
2016-09-29 16:20:16 +00:00
return Hogan.compile($('#topicSearchTemplate').html()).render(s)
}
},
source: new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/search/topics',
2016-11-07 20:25:08 +00:00
prepare: function(query, settings) {
2016-09-29 16:20:16 +00:00
settings.url += '?term=' + query
if (Active.Mapper && self.limitTopicsToMe) {
settings.url += '&user=' + Active.Mapper.id.toString()
}
return settings
}
}
})
}
var maps = {
name: 'maps',
limit: 9999,
display: s => s.label,
templates: {
2016-11-07 20:25:08 +00:00
notFound: function(s) {
2016-09-29 16:20:16 +00:00
return Hogan.compile(mapheader + $('#mapSearchTemplate').html()).render({
value: 'No results',
label: 'No results',
rtype: 'noresult'
})
},
header: mapheader,
2016-11-07 20:25:08 +00:00
suggestion: function(s) {
2016-09-29 16:20:16 +00:00
return Hogan.compile($('#mapSearchTemplate').html()).render(s)
}
},
source: new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/search/maps',
2016-11-07 20:25:08 +00:00
prepare: function(query, settings) {
2016-09-29 16:20:16 +00:00
settings.url += '?term=' + query
if (Active.Mapper && self.limitMapsToMe) {
settings.url += '&user=' + Active.Mapper.id.toString()
}
return settings
}
}
})
}
var mappers = {
name: 'mappers',
limit: 9999,
display: s => s.label,
templates: {
2016-11-07 20:25:08 +00:00
notFound: function(s) {
2016-09-29 16:20:16 +00:00
return Hogan.compile(mapperheader + $('#mapperSearchTemplate').html()).render({
value: 'No results',
label: 'No results',
rtype: 'noresult',
2016-10-03 00:32:37 +00:00
profile: self.userIconUrl
2016-09-29 16:20:16 +00:00
})
},
header: mapperheader,
2016-11-07 20:25:08 +00:00
suggestion: function(s) {
2016-09-29 16:20:16 +00:00
return Hogan.compile($('#mapperSearchTemplate').html()).render(s)
}
},
source: new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/search/mappers?term=%QUERY',
wildcard: '%QUERY'
}
})
}
// Take all that crazy setup data and put it together into one beautiful typeahead call!
$('.sidebarSearchField').typeahead(
{
highlight: true
},
[topics, maps, mappers]
)
// Set max height of the search results box to prevent it from covering bottom left footer
2016-11-07 20:25:08 +00:00
$('.sidebarSearchField').bind('typeahead:render', function(event) {
2016-09-29 16:20:16 +00:00
self.initSearchOptions()
self.hideLoader()
var h = $(window).height()
$('.tt-dropdown-menu').css('max-height', h - 100)
if (self.limitTopicsToMe) {
$('#limitTopicsToMe').prop('checked', true)
}
if (self.limitMapsToMe) {
$('#limitMapsToMe').prop('checked', true)
}
})
2016-11-07 20:25:08 +00:00
$(window).resize(function() {
2016-09-29 16:20:16 +00:00
var h = $(window).height()
$('.tt-dropdown-menu').css('max-height', h - 100)
})
// tell the autocomplete to launch a new tab with the topic, map, or mapper you clicked on
$('.sidebarSearchField').bind('typeahead:select', self.handleResultClick)
// don't do it, if they clicked on a 'addToMap' button
2016-11-07 20:25:08 +00:00
$('.sidebarSearch button.addToMap').click(function(event) {
2016-09-29 16:20:16 +00:00
event.stopPropagation()
})
// make sure that when you click on 'limit to me' or 'toggle section' it works
2016-11-07 20:25:08 +00:00
$('.sidebarSearchField.tt-input').keyup(function() {
2016-09-29 16:20:16 +00:00
if ($('.sidebarSearchField.tt-input').val() === '') {
self.hideLoader()
} else {
self.showLoader()
}
})
},
2016-11-07 20:25:08 +00:00
handleResultClick: function(event, datum, dataset) {
2016-09-29 16:20:16 +00:00
var self = Search
self.hideLoader()
if (['topic', 'map', 'mapper'].indexOf(datum.rtype) !== -1) {
if (datum.rtype === 'topic') {
react-router and rebuild app structure in react (#1091) * initial restructuring * stuff * lock version number * just keep using current mapinfobox * fix map upperRightUI layout * make mapsWidth work and add mobile * remove filterBoxOpen for now * redo the mobile menu in react * get account menu and invite lightbox working * fixed maps scrolling * make other routes work * fix signed out home page * fix accountbox toggling * add metacode edit routes * lots of fixes * fix map chat layout and tab bug * improve topic card readability and fix dragging bug * fixup mapchat stuff * fix up navigation to use react-router * jquery no longer handling access requests * handle case where user hasn't loaded yet * this shouldn't have been removed * add frame for topic view * rewrite map instructions * fix toast (and sign out bug) * fix apps pages and missing routes * made our request invite page look nice * filter box in react * forgot to add one proptype * remove extra comments * handle page title and mobile title updates * reenable google analytics * make filterbox use onclickoutside * reenable topic view in react * fix csrf auth token * fix little homepage styling issue * try putting preparevizdata in a timeout * installing render log to count * little fixes * fixup filters * make filter map function names more readable * eslint helps * renaming for clarity * use onclickoutside for account/sign in box * add some logging to see whether this is source of many renders * turns out chatview was heavily hogging memory * tiimeout not needed
2017-03-16 21:58:56 +00:00
browserHistory.push(`/topics/${datum.id}`)
2016-09-29 16:20:16 +00:00
} else if (datum.rtype === 'map') {
react-router and rebuild app structure in react (#1091) * initial restructuring * stuff * lock version number * just keep using current mapinfobox * fix map upperRightUI layout * make mapsWidth work and add mobile * remove filterBoxOpen for now * redo the mobile menu in react * get account menu and invite lightbox working * fixed maps scrolling * make other routes work * fix signed out home page * fix accountbox toggling * add metacode edit routes * lots of fixes * fix map chat layout and tab bug * improve topic card readability and fix dragging bug * fixup mapchat stuff * fix up navigation to use react-router * jquery no longer handling access requests * handle case where user hasn't loaded yet * this shouldn't have been removed * add frame for topic view * rewrite map instructions * fix toast (and sign out bug) * fix apps pages and missing routes * made our request invite page look nice * filter box in react * forgot to add one proptype * remove extra comments * handle page title and mobile title updates * reenable google analytics * make filterbox use onclickoutside * reenable topic view in react * fix csrf auth token * fix little homepage styling issue * try putting preparevizdata in a timeout * installing render log to count * little fixes * fixup filters * make filter map function names more readable * eslint helps * renaming for clarity * use onclickoutside for account/sign in box * add some logging to see whether this is source of many renders * turns out chatview was heavily hogging memory * tiimeout not needed
2017-03-16 21:58:56 +00:00
browserHistory.push(`/maps/${datum.id}`)
2016-09-29 16:20:16 +00:00
} else if (datum.rtype === 'mapper') {
react-router and rebuild app structure in react (#1091) * initial restructuring * stuff * lock version number * just keep using current mapinfobox * fix map upperRightUI layout * make mapsWidth work and add mobile * remove filterBoxOpen for now * redo the mobile menu in react * get account menu and invite lightbox working * fixed maps scrolling * make other routes work * fix signed out home page * fix accountbox toggling * add metacode edit routes * lots of fixes * fix map chat layout and tab bug * improve topic card readability and fix dragging bug * fixup mapchat stuff * fix up navigation to use react-router * jquery no longer handling access requests * handle case where user hasn't loaded yet * this shouldn't have been removed * add frame for topic view * rewrite map instructions * fix toast (and sign out bug) * fix apps pages and missing routes * made our request invite page look nice * filter box in react * forgot to add one proptype * remove extra comments * handle page title and mobile title updates * reenable google analytics * make filterbox use onclickoutside * reenable topic view in react * fix csrf auth token * fix little homepage styling issue * try putting preparevizdata in a timeout * installing render log to count * little fixes * fixup filters * make filter map function names more readable * eslint helps * renaming for clarity * use onclickoutside for account/sign in box * add some logging to see whether this is source of many renders * turns out chatview was heavily hogging memory * tiimeout not needed
2017-03-16 21:58:56 +00:00
browserHistory.push(`/explore/mapper/${datum.id}`)
2016-09-29 16:20:16 +00:00
}
}
},
2016-11-07 20:25:08 +00:00
initSearchOptions: function() {
2016-09-29 16:20:16 +00:00
var self = Search
2016-11-07 20:25:08 +00:00
function toggleResultSet(set) {
2016-09-29 16:20:16 +00:00
var s = $('.tt-dataset-' + set + ' .tt-suggestion, .tt-dataset-' + set + ' .resultnoresult')
if (s.is(':visible')) {
s.hide()
$(this).removeClass('minimizeResults').addClass('maximizeResults')
} else {
s.show()
$(this).removeClass('maximizeResults').addClass('minimizeResults')
}
}
2016-11-07 20:25:08 +00:00
$('.limitToMe').unbind().bind('change', function(e) {
2016-09-29 16:20:16 +00:00
if ($(this).attr('id') === 'limitTopicsToMe') {
self.limitTopicsToMe = !self.limitTopicsToMe
}
if ($(this).attr('id') === 'limitMapsToMe') {
self.limitMapsToMe = !self.limitMapsToMe
}
// set the value of the search equal to itself to retrigger the
// autocomplete event
var searchQuery = $('.sidebarSearchField.tt-input').val()
$('.sidebarSearchField').typeahead('val', '')
.typeahead('val', searchQuery)
})
// when the user clicks minimize section, hide the results for that section
2016-11-07 20:25:08 +00:00
$('.minimizeMapperResults').unbind().click(function(e) {
2016-09-29 16:20:16 +00:00
toggleResultSet.call(this, 'mappers')
})
2016-11-07 20:25:08 +00:00
$('.minimizeTopicResults').unbind().click(function(e) {
2016-09-29 16:20:16 +00:00
toggleResultSet.call(this, 'topics')
})
2016-11-07 20:25:08 +00:00
$('.minimizeMapResults').unbind().click(function(e) {
2016-09-29 16:20:16 +00:00
toggleResultSet.call(this, 'maps')
})
},
2016-11-07 20:25:08 +00:00
hideLoader: function() {
2016-09-29 16:20:16 +00:00
$('#searchLoading').hide()
},
2016-11-07 20:25:08 +00:00
showLoader: function() {
2016-09-29 16:20:16 +00:00
$('#searchLoading').show()
}
}
export default Search