/* global Metamaps, $, Hogan, Bloodhound */ import Active from './Active' import Create from './Create' import Filter from './Filter' import Router from './Router' /* * Metamaps.Backbone * Metamaps.Erb * Metamaps.Maps */ const GlobalUI = { notifyTimeout: null, lightbox: null, init: function () { var self = GlobalUI; self.Search.init(); self.CreateMap.init(); self.Account.init(); if ($('#toast').html().trim()) self.notifyUser($('#toast').html()) //bind lightbox clicks $('.openLightbox').click(function (event) { self.openLightbox($(this).attr('data-open')); event.preventDefault(); return false; }); $('#lightbox_screen, #lightbox_close').click(self.closeLightbox); // initialize global backbone models and collections if (Active.Mapper) Active.Mapper = new Metamaps.Backbone.Mapper(Active.Mapper); var myCollection = Metamaps.Maps.Mine ? Metamaps.Maps.Mine : []; var sharedCollection = Metamaps.Maps.Shared ? Metamaps.Maps.Shared : []; var starredCollection = Metamaps.Maps.Starred ? Metamaps.Maps.Starred : []; var mapperCollection = []; var mapperOptionsObj = {id: 'mapper', sortBy: 'updated_at' }; if (Metamaps.Maps.Mapper) { mapperCollection = Metamaps.Maps.Mapper.models; mapperOptionsObj.mapperId = Metamaps.Maps.Mapper.id; } var featuredCollection = Metamaps.Maps.Featured ? Metamaps.Maps.Featured : []; var activeCollection = Metamaps.Maps.Active ? Metamaps.Maps.Active : []; Metamaps.Maps.Mine = new Metamaps.Backbone.MapsCollection(myCollection, {id: 'mine', sortBy: 'updated_at' }); Metamaps.Maps.Shared = new Metamaps.Backbone.MapsCollection(sharedCollection, {id: 'shared', sortBy: 'updated_at' }); Metamaps.Maps.Starred = new Metamaps.Backbone.MapsCollection(starredCollection, {id: 'starred', sortBy: 'updated_at' }); // 'Mapper' refers to another mapper Metamaps.Maps.Mapper = new Metamaps.Backbone.MapsCollection(mapperCollection, mapperOptionsObj); Metamaps.Maps.Featured = new Metamaps.Backbone.MapsCollection(featuredCollection, {id: 'featured', sortBy: 'updated_at' }); Metamaps.Maps.Active = new Metamaps.Backbone.MapsCollection(activeCollection, {id: 'active', sortBy: 'updated_at' }); }, showDiv: function (selector) { $(selector).show() $(selector).animate({ opacity: 1 }, 200, 'easeOutCubic') }, hideDiv: function (selector) { $(selector).animate({ opacity: 0 }, 200, 'easeInCubic', function () { $(this).hide() }) }, openLightbox: function (which) { var self = GlobalUI; $('.lightboxContent').hide(); $('#' + which).show(); self.lightbox = which; $('#lightbox_overlay').show(); var heightOfContent = '-' + ($('#lightbox_main').height() / 2) + 'px'; // animate the content in from the bottom $('#lightbox_main').animate({ 'top': '50%', 'margin-top': heightOfContent }, 200, 'easeOutCubic'); // fade the black overlay in $('#lightbox_screen').animate({ 'opacity': '0.42' }, 200); if (which == "switchMetacodes") { Create.isSwitchingSet = true; } }, closeLightbox: function (event) { var self = GlobalUI; if (event) event.preventDefault(); // animate the lightbox content offscreen $('#lightbox_main').animate({ 'top': '100%', 'margin-top': '0' }, 200, 'easeInCubic'); // fade the black overlay out $('#lightbox_screen').animate({ 'opacity': '0.0' }, 200, function () { $('#lightbox_overlay').hide(); }); if (self.lightbox === 'forkmap') GlobalUI.CreateMap.reset('fork_map'); if (self.lightbox === 'newmap') GlobalUI.CreateMap.reset('new_map'); if (Create && Create.isSwitchingSet) { Create.cancelMetacodeSetSwitch(); } self.lightbox = null; }, notifyUser: function (message, leaveOpen) { var self = GlobalUI; $('#toast').html(message) self.showDiv('#toast') clearTimeout(self.notifyTimeOut); if (!leaveOpen) { self.notifyTimeOut = setTimeout(function () { self.hideDiv('#toast') }, 8000); } }, clearNotify: function() { var self = GlobalUI; clearTimeout(self.notifyTimeOut); self.hideDiv('#toast') }, shareInvite: function(inviteLink) { window.prompt("To copy the invite link, press: Ctrl+C, Enter", inviteLink); } } GlobalUI.CreateMap = { newMap: null, emptyMapForm: "", emptyForkMapForm: "", topicsToMap: [], synapsesToMap: [], init: function () { var self = GlobalUI.CreateMap; self.newMap = new Metamaps.Backbone.Map({ permission: 'commons' }); self.bindFormEvents(); self.emptyMapForm = $('#new_map').html(); }, bindFormEvents: function () { var self = GlobalUI.CreateMap; $('.new_map input, .new_map div').unbind('keypress').bind('keypress', function(event) { if (event.keyCode === 13) self.submit() }) $('.new_map button.cancel').unbind().bind('click', function (event) { event.preventDefault(); GlobalUI.closeLightbox(); }); $('.new_map button.submitMap').unbind().bind('click', self.submit); // bind permission changer events on the createMap form $('.permIcon').unbind().bind('click', self.switchPermission); }, closeSuccess: function () { $('#mapCreatedSuccess').fadeOut(300, function(){ $(this).remove(); }); }, generateSuccessMessage: function (id) { var stringStart = "
SUCCESS!
Your map has been created. Do you want to: Go to your new map"; stringStart += "ORStay on this "; var page = Active.Map ? 'map' : 'page'; var stringEnd = "
"; return stringStart + page + stringEnd; }, switchPermission: function () { var self = GlobalUI.CreateMap; self.newMap.set('permission', $(this).attr('data-permission')); $(this).siblings('.permIcon').find('.mapPermIcon').removeClass('selected'); $(this).find('.mapPermIcon').addClass('selected'); var permText = $(this).find('.tip').html(); $(this).parents('.new_map').find('.permText').html(permText); }, submit: function (event) { if (event) event.preventDefault(); var self = GlobalUI.CreateMap; if (GlobalUI.lightbox === 'forkmap') { self.newMap.set('topicsToMap', self.topicsToMap); self.newMap.set('synapsesToMap', self.synapsesToMap); } var formId = GlobalUI.lightbox === 'forkmap' ? '#fork_map' : '#new_map'; var $form = $(formId); self.newMap.set('name', $form.find('#map_name').val()); self.newMap.set('desc', $form.find('#map_desc').val()); if (self.newMap.get('name').length===0){ self.throwMapNameError(); return; } self.newMap.save(null, { success: self.success // TODO add error message }); GlobalUI.closeLightbox(); GlobalUI.notifyUser('Working...'); }, throwMapNameError: function () { var self = GlobalUI.CreateMap; var formId = GlobalUI.lightbox === 'forkmap' ? '#fork_map' : '#new_map'; var $form = $(formId); var message = $("
Please enter a map name...
"); $form.find('#map_name').after(message); setTimeout(function(){ message.fadeOut('fast', function(){ message.remove(); }); }, 5000); }, success: function (model) { var self = GlobalUI.CreateMap; //push the new map onto the collection of 'my maps' Metamaps.Maps.Mine.add(model); var formId = GlobalUI.lightbox === 'forkmap' ? '#fork_map' : '#new_map'; var form = $(formId); GlobalUI.clearNotify(); $('#wrapper').append(self.generateSuccessMessage(model.id)); }, reset: function (id) { var self = GlobalUI.CreateMap; var form = $('#' + id); if (id === "fork_map") { self.topicsToMap = []; self.synapsesToMap = []; form.html(self.emptyForkMapForm); } else { form.html(self.emptyMapForm); } self.bindFormEvents(); self.newMap = new Metamaps.Backbone.Map({ permission: 'commons' }); return false; }, } GlobalUI.Account = { isOpen: false, changing: false, init: function () { var self = GlobalUI.Account; $('.sidebarAccountIcon').click(self.toggleBox); $('.sidebarAccountBox').click(function(event){ event.stopPropagation(); }); $('body').click(self.close); }, toggleBox: function (event) { var self = GlobalUI.Account; if (self.isOpen) self.close(); else self.open(); event.stopPropagation(); }, open: function () { var self = GlobalUI.Account; Filter.close(); $('.sidebarAccountIcon .tooltipsUnder').addClass('hide'); if (!self.isOpen && !self.changing) { self.changing = true; $('.sidebarAccountBox').fadeIn(200, function () { self.changing = false; self.isOpen = true; $('.sidebarAccountBox #user_email').focus(); }); } }, close: function () { var self = GlobalUI.Account; $('.sidebarAccountIcon .tooltipsUnder').removeClass('hide'); if (!self.changing) { self.changing = true; $('.sidebarAccountBox #user_email').blur(); $('.sidebarAccountBox').fadeOut(200, function () { self.changing = false; self.isOpen = false; }); } } } GlobalUI.Search = { locked: false, isOpen: false, limitTopicsToMe: false, limitMapsToMe: false, timeOut: null, changing: false, optionsInitialized: false, init: function () { var self = GlobalUI.Search; 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 // bind the hover events $(".sidebarSearch").hover(function () { self.open() }, function () { self.close(800, false) }); $('.sidebarSearchIcon').click(function (e) { $('.sidebarSearchField').focus(); }); $('.sidebarSearch').click(function (e) { e.stopPropagation(); }); $('body').click(function (e) { self.close(0, false); }); // open if the search is closed and user hits ctrl+/ // close if they hit ESC $('body').bind('keyup', function (e) { switch (e.which) { case 191: if ((e.ctrlKey && !self.isOpen) || (e.ctrlKey && self.locked)) { self.open(true); // true for focus } break; case 27: if (self.isOpen) { self.close(0, true); } break; default: break; //console.log(e.which); } }); self.startTypeahead(); }, lock: function() { var self = GlobalUI.Search; self.locked = true; }, unlock: function() { var self = GlobalUI.Search; self.locked = false; }, open: function (focus) { var self = GlobalUI.Search; clearTimeout(self.timeOut); if (!self.isOpen && !self.changing && !self.locked) { self.changing = true; $('.sidebarSearch .twitter-typeahead, .sidebarSearch .tt-hint, .sidebarSearchField').animate({ width: '400px' }, 300, function () { if (focus) $('.sidebarSearchField').focus(); $('.sidebarSearchField, .sidebarSearch .tt-hint').css({ padding: '7px 10px 3px 10px', width: '380px' }); self.changing = false; self.isOpen = true; }); } }, close: function (closeAfter, bypass) { // for now return var self = GlobalUI.Search; self.timeOut = setTimeout(function () { if (!self.locked && !self.changing && self.isOpen && (bypass || $('.sidebarSearchField.tt-input').val() == '')) { self.changing = true; $('.sidebarSearchField, .sidebarSearch .tt-hint').css({ padding: '7px 0 3px 0', width: '400px' }); $('.sidebarSearch .twitter-typeahead, .sidebarSearch .tt-hint, .sidebarSearchField').animate({ width: '0' }, 300, function () { $('.sidebarSearchField').typeahead('val', ''); $('.sidebarSearchField').blur(); self.changing = false; self.isOpen = false; }); } }, closeAfter); }, startTypeahead: function () { var self = GlobalUI.Search; var mapheader = Active.Mapper ? '

Maps

' : '

Maps

'; var topicheader = Active.Mapper ? '

Topics

' : '

Topics

'; var mapperheader = '

Mappers

'; var topics = { name: 'topics', limit: 9999, display: function(s) { return s.label; }, templates: { notFound: function(s) { return Hogan.compile(topicheader + $('#topicSearchTemplate').html()).render({ value: "No results", label: "No results", typeImageURL: Metamaps.Erb['icons/wildcard.png'], rtype: "noresult" }); }, header: topicheader, suggestion: function(s) { return Hogan.compile($('#topicSearchTemplate').html()).render(s); }, }, source: new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'), queryTokenizer: Bloodhound.tokenizers.whitespace, remote: { url: '/search/topics', prepare: function(query, settings) { 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: function(s) { return s.label; }, templates: { notFound: function(s) { return Hogan.compile(mapheader + $('#mapSearchTemplate').html()).render({ value: "No results", label: "No results", rtype: "noresult" }); }, header: mapheader, suggestion: function(s) { return Hogan.compile($('#mapSearchTemplate').html()).render(s); }, }, source: new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'), queryTokenizer: Bloodhound.tokenizers.whitespace, remote: { url: '/search/maps', prepare: function(query, settings) { 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: function(s) { return s.label; }, templates: { notFound: function(s) { return Hogan.compile(mapperheader + $('#mapperSearchTemplate').html()).render({ value: "No results", label: "No results", rtype: "noresult", profile: Metamaps.Erb['user.png'] }); }, header: mapperheader, suggestion: function(s) { 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 $('.sidebarSearchField').bind('typeahead:render', function (event) { 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); } }); $(window).resize(function () { 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 $('.sidebarSearch button.addToMap').click(function (event) { event.stopPropagation(); }); // make sure that when you click on 'limit to me' or 'toggle section' it works $('.sidebarSearchField.tt-input').keyup(function(){ if ($('.sidebarSearchField.tt-input').val() === '') { self.hideLoader(); } else { self.showLoader(); } }); }, handleResultClick: function (event, datum, dataset) { var self = GlobalUI.Search; self.hideLoader(); if (["topic", "map", "mapper"].indexOf(datum.rtype) !== -1) { self.close(0, true); if (datum.rtype == "topic") { Router.topics(datum.id); } else if (datum.rtype == "map") { Router.maps(datum.id); } else if (datum.rtype == "mapper") { Router.explore("mapper", datum.id); } } }, initSearchOptions: function () { var self = GlobalUI.Search; function toggleResultSet(set) { 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'); } } $('.limitToMe').unbind().bind("change", function (e) { 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 $('.minimizeMapperResults').unbind().click(function (e) { toggleResultSet.call(this, 'mappers'); }); $('.minimizeTopicResults').unbind().click(function (e) { toggleResultSet.call(this, 'topics'); }); $('.minimizeMapResults').unbind().click(function (e) { toggleResultSet.call(this, 'maps'); }); }, hideLoader: function () { $('#searchLoading').hide(); }, showLoader: function () { $('#searchLoading').show(); } } export default GlobalUI