2016-04-14 14:01:21 +08:00
/* global Metamaps, $ */
2016-09-22 18:31:56 +08:00
import Active from './Active'
import AutoLayout from './AutoLayout'
import Create from './Create'
import Filter from './Filter'
import GlobalUI from './GlobalUI'
import JIT from './JIT'
import Realtime from './Realtime'
import Selected from './Selected'
import SynapseCard from './SynapseCard'
import TopicCard from './TopicCard'
import Visualize from './Visualize'
2016-04-14 14:01:21 +08:00
/ *
* Metamaps . Map . js . erb
*
* Dependencies :
2016-09-22 18:31:56 +08:00
* - Metamaps . Backbone
2016-04-24 11:50:35 -04:00
* - Metamaps . Erb
* - Metamaps . Loading
2016-04-14 14:01:21 +08:00
* - Metamaps . Mappers
* - Metamaps . Mappings
2016-09-22 18:31:56 +08:00
* - Metamaps . Maps
2016-04-14 14:01:21 +08:00
* - Metamaps . Messages
2016-09-22 18:31:56 +08:00
* - Metamaps . Router
2016-04-14 14:01:21 +08:00
* - Metamaps . Synapses
* - Metamaps . Topics
*
* Major sub - modules :
* - Metamaps . Map . CheatSheet
* - Metamaps . Map . InfoBox
* /
2016-09-22 18:31:56 +08:00
window . Metamaps = window . Metamaps || { }
2016-04-14 14:01:21 +08:00
Metamaps . Map = {
events : {
editedByActiveMapper : 'Metamaps:Map:events:editedByActiveMapper'
} ,
init : function ( ) {
var self = Metamaps . Map
// prevent right clicks on the main canvas, so as to not get in the way of our right clicks
$ ( '#center-container' ) . bind ( 'contextmenu' , function ( e ) {
return false
} )
2016-08-31 16:58:49 -04:00
$ ( '.starMap' ) . click ( function ( ) {
if ( $ ( this ) . is ( '.starred' ) ) self . unstar ( )
else self . star ( )
} )
2016-04-14 14:01:21 +08:00
$ ( '.sidebarFork' ) . click ( function ( ) {
self . fork ( )
} )
2016-09-22 18:31:56 +08:00
GlobalUI . CreateMap . emptyForkMapForm = $ ( '#fork_map' ) . html ( )
2016-04-14 14:01:21 +08:00
2016-08-31 16:58:49 -04:00
self . updateStar ( )
2016-04-14 14:01:21 +08:00
self . InfoBox . init ( )
self . CheatSheet . init ( )
$ ( document ) . on ( Metamaps . Map . events . editedByActiveMapper , self . editedByActiveMapper )
} ,
launch : function ( id ) {
var bb = Metamaps . Backbone
var start = function ( data ) {
2016-09-22 18:31:56 +08:00
Active . Map = new bb . Map ( data . map )
2016-04-14 14:01:21 +08:00
Metamaps . Mappers = new bb . MapperCollection ( data . mappers )
2016-04-24 11:50:35 -04:00
Metamaps . Collaborators = new bb . MapperCollection ( data . collaborators )
2016-04-14 14:01:21 +08:00
Metamaps . Topics = new bb . TopicCollection ( data . topics )
Metamaps . Synapses = new bb . SynapseCollection ( data . synapses )
Metamaps . Mappings = new bb . MappingCollection ( data . mappings )
Metamaps . Messages = data . messages
2016-08-31 16:58:49 -04:00
Metamaps . Stars = data . stars
2016-04-14 14:01:21 +08:00
Metamaps . Backbone . attachCollectionEvents ( )
2016-09-22 18:31:56 +08:00
var map = Active . Map
var mapper = Active . Mapper
2016-04-14 14:01:21 +08:00
// add class to .wrapper for specifying whether you can edit the map
if ( map . authorizeToEdit ( mapper ) ) {
$ ( '.wrapper' ) . addClass ( 'canEditMap' )
}
// add class to .wrapper for specifying if the map can
// be collaborated on
if ( map . get ( 'permission' ) === 'commons' ) {
$ ( '.wrapper' ) . addClass ( 'commonsMap' )
}
2016-08-31 16:58:49 -04:00
Metamaps . Map . updateStar ( )
2016-04-14 14:01:21 +08:00
// set filter mapper H3 text
$ ( '#filter_by_mapper h3' ) . html ( 'MAPPERS' )
// build and render the visualization
2016-09-22 18:31:56 +08:00
Visualize . type = 'ForceDirected'
JIT . prepareVizData ( )
2016-04-14 14:01:21 +08:00
// update filters
2016-09-22 18:31:56 +08:00
Filter . reset ( )
2016-04-14 14:01:21 +08:00
// reset selected arrays
2016-09-22 18:31:56 +08:00
Selected . reset ( )
2016-04-14 14:01:21 +08:00
// set the proper mapinfobox content
Metamaps . Map . InfoBox . load ( )
// these three update the actual filter box with the right list items
2016-09-22 18:31:56 +08:00
Filter . checkMetacodes ( )
Filter . checkSynapses ( )
Filter . checkMappers ( )
2016-04-14 14:01:21 +08:00
2016-09-22 18:31:56 +08:00
Realtime . startActiveMap ( )
2016-04-14 14:01:21 +08:00
Metamaps . Loading . hide ( )
2016-08-12 04:04:18 +00:00
// for mobile
$ ( '#header_content' ) . html ( map . get ( 'name' ) )
2016-04-14 14:01:21 +08:00
}
$ . ajax ( {
url : '/maps/' + id + '/contains.json' ,
success : start
} )
} ,
end : function ( ) {
2016-09-22 18:31:56 +08:00
if ( Active . Map ) {
2016-04-14 14:01:21 +08:00
$ ( '.wrapper' ) . removeClass ( 'canEditMap commonsMap' )
2016-09-22 18:31:56 +08:00
AutoLayout . resetSpiral ( )
2016-04-14 14:01:21 +08:00
$ ( '.rightclickmenu' ) . remove ( )
2016-09-22 18:31:56 +08:00
TopicCard . hideCard ( )
SynapseCard . hideCard ( )
Create . newTopic . hide ( true ) // true means force (and override pinned)
Create . newSynapse . hide ( )
Filter . close ( )
2016-04-14 14:01:21 +08:00
Metamaps . Map . InfoBox . close ( )
2016-09-22 18:31:56 +08:00
Realtime . endActiveMap ( )
2016-04-14 14:01:21 +08:00
}
} ,
2016-08-31 16:58:49 -04:00
updateStar : function ( ) {
2016-09-22 18:31:56 +08:00
if ( ! Active . Mapper || ! Metamaps . Stars ) return
2016-08-31 16:58:49 -04:00
// update the star/unstar icon
2016-09-22 18:31:56 +08:00
if ( Metamaps . Stars . find ( function ( s ) { return s . user _id === Active . Mapper . id } ) ) {
2016-08-31 16:58:49 -04:00
$ ( '.starMap' ) . addClass ( 'starred' )
$ ( '.starMap .tooltipsAbove' ) . html ( 'Unstar' )
} else {
$ ( '.starMap' ) . removeClass ( 'starred' )
$ ( '.starMap .tooltipsAbove' ) . html ( 'Star' )
}
} ,
star : function ( ) {
var self = Metamaps . Map
2016-09-22 18:31:56 +08:00
if ( ! Active . Map ) return
$ . post ( '/maps/' + Active . Map . id + '/star' )
Metamaps . Stars . push ( { user _id : Active . Mapper . id , map _id : Active . Map . id } )
Metamaps . Maps . Starred . add ( Active . Map )
GlobalUI . notifyUser ( 'Map is now starred' )
2016-08-31 16:58:49 -04:00
self . updateStar ( )
} ,
unstar : function ( ) {
var self = Metamaps . Map
2016-09-22 18:31:56 +08:00
if ( ! Active . Map ) return
$ . post ( '/maps/' + Active . Map . id + '/unstar' )
Metamaps . Stars = Metamaps . Stars . filter ( function ( s ) { return s . user _id != Active . Mapper . id } )
Metamaps . Maps . Starred . remove ( Active . Map )
2016-08-31 16:58:49 -04:00
self . updateStar ( )
} ,
2016-04-14 14:01:21 +08:00
fork : function ( ) {
2016-09-22 18:31:56 +08:00
GlobalUI . openLightbox ( 'forkmap' )
2016-04-14 14:01:21 +08:00
var nodes _data = '' ,
synapses _data = ''
var nodes _array = [ ]
var synapses _array = [ ]
// collect the unfiltered topics
2016-09-22 18:31:56 +08:00
Visualize . mGraph . graph . eachNode ( function ( n ) {
2016-04-14 14:01:21 +08:00
// if the opacity is less than 1 then it's filtered
if ( n . getData ( 'alpha' ) === 1 ) {
var id = n . getData ( 'topic' ) . id
nodes _array . push ( id )
var x , y
if ( n . pos . x && n . pos . y ) {
x = n . pos . x
y = n . pos . y
} else {
var x = Math . cos ( n . pos . theta ) * n . pos . rho
var y = Math . sin ( n . pos . theta ) * n . pos . rho
}
nodes _data += id + '/' + x + '/' + y + ','
}
} )
// collect the unfiltered synapses
Metamaps . Synapses . each ( function ( synapse ) {
var desc = synapse . get ( 'desc' )
2016-09-22 18:31:56 +08:00
var descNotFiltered = Filter . visible . synapses . indexOf ( desc ) > - 1
2016-04-14 14:01:21 +08:00
// make sure that both topics are being added, otherwise, it
// doesn't make sense to add the synapse
var topicsNotFiltered = nodes _array . indexOf ( synapse . get ( 'node1_id' ) ) > - 1
topicsNotFiltered = topicsNotFiltered && nodes _array . indexOf ( synapse . get ( 'node2_id' ) ) > - 1
if ( descNotFiltered && topicsNotFiltered ) {
synapses _array . push ( synapse . id )
}
} )
synapses _data = synapses _array . join ( )
nodes _data = nodes _data . slice ( 0 , - 1 )
2016-09-22 18:31:56 +08:00
GlobalUI . CreateMap . topicsToMap = nodes _data
GlobalUI . CreateMap . synapsesToMap = synapses _data
2016-04-14 14:01:21 +08:00
} ,
leavePrivateMap : function ( ) {
2016-09-22 18:31:56 +08:00
var map = Active . Map
2016-04-14 14:01:21 +08:00
Metamaps . Maps . Active . remove ( map )
Metamaps . Maps . Featured . remove ( map )
Metamaps . Router . home ( )
2016-09-22 18:31:56 +08:00
GlobalUI . notifyUser ( 'Sorry! That map has been changed to Private.' )
2016-04-14 14:01:21 +08:00
} ,
2016-04-24 11:50:35 -04:00
cantEditNow : function ( ) {
2016-09-22 18:31:56 +08:00
Realtime . turnOff ( true ) ; // true is for 'silence'
GlobalUI . notifyUser ( 'Map was changed to Public. Editing is disabled.' )
Active . Map . trigger ( 'changeByOther' )
2016-04-14 14:01:21 +08:00
} ,
2016-04-24 11:50:35 -04:00
canEditNow : function ( ) {
var confirmString = "You've been granted permission to edit this map. "
2016-04-14 14:01:21 +08:00
confirmString += 'Do you want to reload and enable realtime collaboration?'
var c = confirm ( confirmString )
if ( c ) {
2016-09-22 18:31:56 +08:00
Metamaps . Router . maps ( Active . Map . id )
2016-04-14 14:01:21 +08:00
}
} ,
editedByActiveMapper : function ( ) {
2016-09-22 18:31:56 +08:00
if ( Active . Mapper ) {
Metamaps . Mappers . add ( Active . Mapper )
2016-04-14 14:01:21 +08:00
}
} ,
exportImage : function ( ) {
var canvas = { }
canvas . canvas = document . createElement ( 'canvas' )
canvas . canvas . width = 1880 // 960
canvas . canvas . height = 1260 // 630
canvas . scaleOffsetX = 1
canvas . scaleOffsetY = 1
canvas . translateOffsetY = 0
canvas . translateOffsetX = 0
canvas . denySelected = true
canvas . getSize = function ( ) {
if ( this . size ) return this . size
var canvas = this . canvas
return this . size = {
width : canvas . width ,
height : canvas . height
}
}
canvas . scale = function ( x , y ) {
var px = this . scaleOffsetX * x ,
py = this . scaleOffsetY * y
var dx = this . translateOffsetX * ( x - 1 ) / px ,
dy = this . translateOffsetY * ( y - 1 ) / py
this . scaleOffsetX = px
this . scaleOffsetY = py
this . getCtx ( ) . scale ( x , y )
this . translate ( dx , dy )
}
canvas . translate = function ( x , y ) {
var sx = this . scaleOffsetX ,
sy = this . scaleOffsetY
this . translateOffsetX += x * sx
this . translateOffsetY += y * sy
this . getCtx ( ) . translate ( x , y )
}
canvas . getCtx = function ( ) {
return this . canvas . getContext ( '2d' )
}
// center it
canvas . getCtx ( ) . translate ( 1880 / 2 , 1260 / 2 )
2016-09-22 18:31:56 +08:00
var mGraph = Visualize . mGraph
2016-04-14 14:01:21 +08:00
var id = mGraph . root
var root = mGraph . graph . getNode ( id )
var T = ! ! root . visited
// pass true to avoid basing it on a selection
2016-09-22 18:31:56 +08:00
JIT . zoomExtents ( null , canvas , true )
2016-04-14 14:01:21 +08:00
var c = canvas . canvas ,
ctx = canvas . getCtx ( ) ,
scale = canvas . scaleOffsetX
// draw a grey background
ctx . fillStyle = '#d8d9da'
var xPoint = ( - ( c . width / scale ) / 2 ) - ( canvas . translateOffsetX / scale ) ,
yPoint = ( - ( c . height / scale ) / 2 ) - ( canvas . translateOffsetY / scale )
ctx . fillRect ( xPoint , yPoint , c . width / scale , c . height / scale )
// draw the graph
mGraph . graph . eachNode ( function ( node ) {
var nodeAlpha = node . getData ( 'alpha' )
node . eachAdjacency ( function ( adj ) {
var nodeTo = adj . nodeTo
if ( ! ! nodeTo . visited === T && node . drawn && nodeTo . drawn ) {
mGraph . fx . plotLine ( adj , canvas )
}
} )
if ( node . drawn ) {
mGraph . fx . plotNode ( node , canvas )
}
if ( ! mGraph . labelsHidden ) {
if ( node . drawn && nodeAlpha >= 0.95 ) {
mGraph . labels . plotLabel ( canvas , node )
} else {
mGraph . labels . hideLabel ( node , false )
}
}
node . visited = ! T
} )
var imageData = {
encoded _image : canvas . canvas . toDataURL ( )
}
2016-09-22 18:31:56 +08:00
var map = Active . Map
2016-04-14 14:01:21 +08:00
var today = new Date ( )
var dd = today . getDate ( )
var mm = today . getMonth ( ) + 1 ; // January is 0!
var yyyy = today . getFullYear ( )
if ( dd < 10 ) {
dd = '0' + dd
}
if ( mm < 10 ) {
mm = '0' + mm
}
today = mm + '/' + dd + '/' + yyyy
var mapName = map . get ( 'name' ) . split ( ' ' ) . join ( [ separator = '-' ] )
var downloadMessage = ''
downloadMessage += 'Captured map screenshot! '
downloadMessage += "<a href='" + imageData . encoded _image + "' "
downloadMessage += "download='metamap-" + map . id + '-' + mapName + '-' + today + ".png'>DOWNLOAD</a>"
2016-09-22 18:31:56 +08:00
GlobalUI . notifyUser ( downloadMessage )
2016-04-14 14:01:21 +08:00
$ . ajax ( {
type : 'POST' ,
dataType : 'json' ,
2016-09-22 18:31:56 +08:00
url : '/maps/' + Active . Map . id + '/upload_screenshot' ,
2016-04-14 14:01:21 +08:00
data : imageData ,
success : function ( data ) {
console . log ( 'successfully uploaded map screenshot' )
} ,
error : function ( ) {
console . log ( 'failed to save map screenshot' )
}
} )
}
}
/ *
*
* CHEATSHEET
*
* /
Metamaps . Map . CheatSheet = {
init : function ( ) {
// tab the cheatsheet
$ ( '#cheatSheet' ) . tabs ( )
$ ( '#quickReference' ) . tabs ( ) . addClass ( 'ui-tabs-vertical ui-helper-clearfix' )
$ ( '#quickReference .ui-tabs-nav li' ) . removeClass ( 'ui-corner-top' ) . addClass ( 'ui-corner-left' )
// id = the id of a vimeo video
var switchVideo = function ( element , id ) {
$ ( '.tutorialItem' ) . removeClass ( 'active' )
$ ( element ) . addClass ( 'active' )
$ ( '#tutorialVideo' ) . attr ( 'src' , '//player.vimeo.com/video/' + id )
}
$ ( '#gettingStarted' ) . click ( function ( ) {
// switchVideo(this,'88334167')
} )
$ ( '#upYourSkillz' ) . click ( function ( ) {
// switchVideo(this,'100118167')
} )
$ ( '#advancedMapping' ) . click ( function ( ) {
// switchVideo(this,'88334167')
} )
}
} ; // end Metamaps.Map.CheatSheet
/ *
*
* INFOBOX
*
* /
Metamaps . Map . InfoBox = {
isOpen : false ,
changing : false ,
selectingPermission : false ,
2016-04-24 11:50:35 -04:00
changePermissionText : "<div class='tooltips'>As the creator, you can change the permission of this map, and the permission of all the topics and synapses you have authority to change will change as well.</div>" ,
2016-04-14 14:01:21 +08:00
nameHTML : '<span class="best_in_place best_in_place_name" id="best_in_place_map_{{id}}_name" data-url="/maps/{{id}}" data-object="map" data-attribute="name" data-type="textarea" data-activator="#mapInfoName">{{name}}</span>' ,
descHTML : '<span class="best_in_place best_in_place_desc" id="best_in_place_map_{{id}}_desc" data-url="/maps/{{id}}" data-object="map" data-attribute="desc" data-nil="Click to add description..." data-type="textarea" data-activator="#mapInfoDesc">{{desc}}</span>' ,
init : function ( ) {
var self = Metamaps . Map . InfoBox
$ ( '.mapInfoIcon' ) . click ( self . toggleBox )
$ ( '.mapInfoBox' ) . click ( function ( event ) {
event . stopPropagation ( )
} )
$ ( 'body' ) . click ( self . close )
2016-08-16 08:03:06 -04:00
self . attachEventListeners ( )
2016-04-24 11:50:35 -04:00
2016-04-14 14:01:21 +08:00
self . generateBoxHTML = Hogan . compile ( $ ( '#mapInfoBoxTemplate' ) . html ( ) )
2016-08-16 08:03:06 -04:00
var querystring = window . location . search . replace ( /^\?/ , '' )
if ( querystring == 'new' ) {
self . open ( )
2016-08-30 16:59:29 -04:00
$ ( '.mapInfoBox' ) . addClass ( 'mapRequestTitle' )
2016-08-16 08:03:06 -04:00
}
2016-04-14 14:01:21 +08:00
} ,
toggleBox : function ( event ) {
var self = Metamaps . Map . InfoBox
if ( self . isOpen ) self . close ( )
else self . open ( )
event . stopPropagation ( )
} ,
open : function ( ) {
var self = Metamaps . Map . InfoBox
$ ( '.mapInfoIcon div' ) . addClass ( 'hide' )
if ( ! self . isOpen && ! self . changing ) {
self . changing = true
$ ( '.mapInfoBox' ) . fadeIn ( 200 , function ( ) {
self . changing = false
self . isOpen = true
} )
}
} ,
close : function ( ) {
var self = Metamaps . Map . InfoBox
$ ( '.mapInfoIcon div' ) . removeClass ( 'hide' )
if ( ! self . changing ) {
self . changing = true
$ ( '.mapInfoBox' ) . fadeOut ( 200 , function ( ) {
self . changing = false
self . isOpen = false
self . hidePermissionSelect ( )
$ ( '.mapContributors .tip' ) . hide ( )
} )
}
} ,
load : function ( ) {
var self = Metamaps . Map . InfoBox
2016-09-22 18:31:56 +08:00
var map = Active . Map
2016-04-14 14:01:21 +08:00
2016-04-24 11:50:35 -04:00
var obj = map . pick ( 'permission' , 'topic_count' , 'synapse_count' )
2016-04-14 14:01:21 +08:00
2016-09-22 18:31:56 +08:00
var isCreator = map . authorizePermissionChange ( Active . Mapper )
var canEdit = map . authorizeToEdit ( Active . Mapper )
2016-04-24 11:50:35 -04:00
var relevantPeople = map . get ( 'permission' ) === 'commons' ? Metamaps . Mappers : Metamaps . Collaborators
2016-04-14 14:01:21 +08:00
var shareable = map . get ( 'permission' ) !== 'private'
obj [ 'name' ] = canEdit ? Hogan . compile ( self . nameHTML ) . render ( { id : map . id , name : map . get ( 'name' ) } ) : map . get ( 'name' )
obj [ 'desc' ] = canEdit ? Hogan . compile ( self . descHTML ) . render ( { id : map . id , desc : map . get ( 'desc' ) } ) : map . get ( 'desc' )
obj [ 'map_creator_tip' ] = isCreator ? self . changePermissionText : ''
2016-04-24 11:50:35 -04:00
obj [ 'contributor_count' ] = relevantPeople . length
obj [ 'contributors_class' ] = relevantPeople . length > 1 ? 'multiple' : ''
obj [ 'contributors_class' ] += relevantPeople . length === 2 ? ' mTwo' : ''
obj [ 'contributor_image' ] = relevantPeople . length > 0 ? relevantPeople . models [ 0 ] . get ( 'image' ) : Metamaps . Erb [ 'user.png' ]
2016-04-14 14:01:21 +08:00
obj [ 'contributor_list' ] = self . createContributorList ( )
2016-04-24 11:50:35 -04:00
2016-04-14 14:01:21 +08:00
obj [ 'user_name' ] = isCreator ? 'You' : map . get ( 'user_name' )
obj [ 'created_at' ] = map . get ( 'created_at_clean' )
obj [ 'updated_at' ] = map . get ( 'updated_at_clean' )
var classes = isCreator ? 'yourMap' : ''
classes += canEdit ? ' canEdit' : ''
classes += shareable ? ' shareable' : ''
$ ( '.mapInfoBox' ) . removeClass ( 'shareable yourMap canEdit' )
. addClass ( classes )
. html ( self . generateBoxHTML . render ( obj ) )
self . attachEventListeners ( )
} ,
attachEventListeners : function ( ) {
var self = Metamaps . Map . InfoBox
$ ( '.mapInfoBox.canEdit .best_in_place' ) . best _in _place ( )
// because anyone who can edit the map can change the map title
var bipName = $ ( '.mapInfoBox .best_in_place_name' )
bipName . unbind ( 'best_in_place:activate' ) . bind ( 'best_in_place:activate' , function ( ) {
var $el = bipName . find ( 'textarea' )
var el = $el [ 0 ]
$el . attr ( 'maxlength' , '140' )
$ ( '.mapInfoName' ) . append ( '<div class="nameCounter forMap"></div>' )
var callback = function ( data ) {
$ ( '.nameCounter.forMap' ) . html ( data . all + '/140' )
}
Countable . live ( el , callback )
} )
bipName . unbind ( 'best_in_place:deactivate' ) . bind ( 'best_in_place:deactivate' , function ( ) {
$ ( '.nameCounter.forMap' ) . remove ( )
} )
$ ( '.mapInfoName .best_in_place_name' ) . unbind ( 'ajax:success' ) . bind ( 'ajax:success' , function ( ) {
var name = $ ( this ) . html ( )
2016-09-22 18:31:56 +08:00
Active . Map . set ( 'name' , name )
Active . Map . trigger ( 'saved' )
2016-08-17 10:00:37 -04:00
// mobile menu
$ ( '#header_content' ) . html ( name )
2016-08-30 16:59:29 -04:00
$ ( '.mapInfoBox' ) . removeClass ( 'mapRequestTitle' )
document . title = name + ' | Metamaps'
2016-04-14 14:01:21 +08:00
} )
$ ( '.mapInfoDesc .best_in_place_desc' ) . unbind ( 'ajax:success' ) . bind ( 'ajax:success' , function ( ) {
var desc = $ ( this ) . html ( )
2016-09-22 18:31:56 +08:00
Active . Map . set ( 'desc' , desc )
Active . Map . trigger ( 'saved' )
2016-04-14 14:01:21 +08:00
} )
$ ( '.yourMap .mapPermission' ) . unbind ( ) . click ( self . onPermissionClick )
// .yourMap in the unbind/bind is just a namespace for the events
// not a reference to the class .yourMap on the .mapInfoBox
$ ( '.mapInfoBox.yourMap' ) . unbind ( '.yourMap' ) . bind ( 'click.yourMap' , self . hidePermissionSelect )
$ ( '.yourMap .mapInfoDelete' ) . unbind ( ) . click ( self . deleteActiveMap )
$ ( '.mapContributors span, #mapContribs' ) . unbind ( ) . click ( function ( event ) {
$ ( '.mapContributors .tip' ) . toggle ( )
event . stopPropagation ( )
} )
$ ( '.mapContributors .tip' ) . unbind ( ) . click ( function ( event ) {
event . stopPropagation ( )
} )
$ ( '.mapContributors .tip li a' ) . click ( Metamaps . Router . intercept )
$ ( '.mapInfoBox' ) . unbind ( '.hideTip' ) . bind ( 'click.hideTip' , function ( ) {
$ ( '.mapContributors .tip' ) . hide ( )
} )
2016-04-24 11:50:35 -04:00
self . addTypeahead ( )
} ,
addTypeahead : function ( ) {
var self = Metamaps . Map . InfoBox
2016-09-22 18:31:56 +08:00
if ( ! Active . Map ) return
2016-04-24 11:50:35 -04:00
// for autocomplete
var collaborators = {
name : 'collaborators' ,
limit : 9999 ,
display : function ( s ) { return s . label ; } ,
templates : {
notFound : function ( s ) {
return Hogan . compile ( $ ( '#collaboratorSearchTemplate' ) . html ( ) ) . render ( {
value : "No results" ,
label : "No results" ,
rtype : "noresult" ,
profile : Metamaps . Erb [ 'user.png' ] ,
} ) ;
} ,
suggestion : function ( s ) {
return Hogan . compile ( $ ( '#collaboratorSearchTemplate' ) . html ( ) ) . render ( s ) ;
} ,
} ,
source : new Bloodhound ( {
datumTokenizer : Bloodhound . tokenizers . obj . whitespace ( 'value' ) ,
queryTokenizer : Bloodhound . tokenizers . whitespace ,
remote : {
url : '/search/mappers?term=%QUERY' ,
wildcard : '%QUERY' ,
} ,
} )
}
// for adding map collaborators, who will have edit rights
2016-09-22 18:31:56 +08:00
if ( Active . Mapper && Active . Mapper . id === Active . Map . get ( 'user_id' ) ) {
2016-04-24 11:50:35 -04:00
$ ( '.collaboratorSearchField' ) . typeahead (
{
highlight : false ,
} ,
[ collaborators ]
)
$ ( '.collaboratorSearchField' ) . bind ( 'typeahead:select' , self . handleResultClick )
$ ( '.mapContributors .removeCollaborator' ) . click ( function ( ) {
self . removeCollaborator ( parseInt ( $ ( this ) . data ( 'id' ) ) )
} )
}
} ,
removeCollaborator : function ( collaboratorId ) {
var self = Metamaps . Map . InfoBox
Metamaps . Collaborators . remove ( Metamaps . Collaborators . get ( collaboratorId ) )
var mapperIds = Metamaps . Collaborators . models . map ( function ( mapper ) { return mapper . id } )
2016-09-22 18:31:56 +08:00
$ . post ( '/maps/' + Active . Map . id + '/access' , { access : mapperIds } )
2016-04-24 11:50:35 -04:00
self . updateNumbers ( )
} ,
addCollaborator : function ( newCollaboratorId ) {
var self = Metamaps . Map . InfoBox
if ( Metamaps . Collaborators . get ( newCollaboratorId ) ) {
2016-09-22 18:31:56 +08:00
GlobalUI . notifyUser ( 'That user already has access' )
2016-04-24 11:50:35 -04:00
return
}
function callback ( mapper ) {
Metamaps . Collaborators . add ( mapper )
var mapperIds = Metamaps . Collaborators . models . map ( function ( mapper ) { return mapper . id } )
2016-09-22 18:31:56 +08:00
$ . post ( '/maps/' + Active . Map . id + '/access' , { access : mapperIds } )
2016-04-24 11:50:35 -04:00
var name = Metamaps . Collaborators . get ( newCollaboratorId ) . get ( 'name' )
2016-09-22 18:31:56 +08:00
GlobalUI . notifyUser ( name + ' will be notified by email' )
2016-04-24 11:50:35 -04:00
self . updateNumbers ( )
}
$ . getJSON ( '/users/' + newCollaboratorId + '.json' , callback )
} ,
handleResultClick : function ( event , item ) {
var self = Metamaps . Map . InfoBox
self . addCollaborator ( item . id )
$ ( '.collaboratorSearchField' ) . typeahead ( 'val' , '' )
2016-04-14 14:01:21 +08:00
} ,
updateNameDescPerm : function ( name , desc , perm ) {
2016-08-30 16:59:29 -04:00
$ ( '.mapInfoBox' ) . removeClass ( 'mapRequestTitle' )
2016-04-14 14:01:21 +08:00
$ ( '.mapInfoName .best_in_place_name' ) . html ( name )
$ ( '.mapInfoDesc .best_in_place_desc' ) . html ( desc )
$ ( '.mapInfoBox .mapPermission' ) . removeClass ( 'commons public private' ) . addClass ( perm )
} ,
createContributorList : function ( ) {
var self = Metamaps . Map . InfoBox
2016-09-22 18:31:56 +08:00
var relevantPeople = Active . Map . get ( 'permission' ) === 'commons' ? Metamaps . Mappers : Metamaps . Collaborators
var activeMapperIsCreator = Active . Mapper && Active . Mapper . id === Active . Map . get ( 'user_id' )
2016-04-14 14:01:21 +08:00
var string = ''
string += '<ul>'
2016-04-24 11:50:35 -04:00
relevantPeople . each ( function ( m ) {
2016-09-22 18:31:56 +08:00
var isCreator = Active . Map . get ( 'user_id' ) === m . get ( 'id' )
2016-04-24 11:50:35 -04:00
string += '<li><a href="/explore/mapper/' + m . get ( 'id' ) + '">' + '<img class="rtUserImage" width="25" height="25" src="' + m . get ( 'image' ) + '" />' + m . get ( 'name' )
if ( isCreator ) string += ' (creator)'
string += '</a>'
if ( activeMapperIsCreator && ! isCreator ) string += '<span class="removeCollaborator" data-id="' + m . get ( 'id' ) + '"></span>'
string += '</li>'
2016-04-14 14:01:21 +08:00
} )
string += '</ul>'
2016-04-24 11:50:35 -04:00
if ( activeMapperIsCreator ) {
string += '<div class="collabSearchField"><span class="addCollab"></span><input class="collaboratorSearchField" placeholder="Add a collaborator!"></input></div>'
}
2016-04-14 14:01:21 +08:00
return string
} ,
updateNumbers : function ( ) {
2016-09-22 18:31:56 +08:00
if ( ! Active . Map ) return
2016-08-08 21:46:05 +08:00
2016-04-14 14:01:21 +08:00
var self = Metamaps . Map . InfoBox
2016-09-22 18:31:56 +08:00
var mapper = Active . Mapper
var relevantPeople = Active . Map . get ( 'permission' ) === 'commons' ? Metamaps . Mappers : Metamaps . Collaborators
2016-04-14 14:01:21 +08:00
var contributors _class = ''
2016-04-24 11:50:35 -04:00
if ( relevantPeople . length === 2 ) contributors _class = 'multiple mTwo'
else if ( relevantPeople . length > 2 ) contributors _class = 'multiple'
2016-04-14 14:01:21 +08:00
2016-04-24 11:50:35 -04:00
var contributors _image = Metamaps . Erb [ 'user.png' ]
if ( relevantPeople . length > 0 ) {
2016-04-14 14:01:21 +08:00
// get the first contributor and use their image
2016-04-24 11:50:35 -04:00
contributors _image = relevantPeople . models [ 0 ] . get ( 'image' )
2016-04-14 14:01:21 +08:00
}
$ ( '.mapContributors img' ) . attr ( 'src' , contributors _image ) . removeClass ( 'multiple mTwo' ) . addClass ( contributors _class )
2016-04-24 11:50:35 -04:00
$ ( '.mapContributors span' ) . text ( relevantPeople . length )
2016-04-14 14:01:21 +08:00
$ ( '.mapContributors .tip' ) . html ( self . createContributorList ( ) )
2016-04-24 11:50:35 -04:00
self . addTypeahead ( )
$ ( '.mapContributors .tip' ) . unbind ( ) . click ( function ( event ) {
event . stopPropagation ( )
} )
2016-04-14 14:01:21 +08:00
$ ( '.mapTopics' ) . text ( Metamaps . Topics . length )
$ ( '.mapSynapses' ) . text ( Metamaps . Synapses . length )
$ ( '.mapEditedAt' ) . html ( '<span>Last edited: </span>' + Metamaps . Util . nowDateFormatted ( ) )
} ,
onPermissionClick : function ( event ) {
var self = Metamaps . Map . InfoBox
if ( ! self . selectingPermission ) {
self . selectingPermission = true
$ ( this ) . addClass ( 'minimize' ) // this line flips the drop down arrow to a pull up arrow
if ( $ ( this ) . hasClass ( 'commons' ) ) {
$ ( this ) . append ( '<ul class="permissionSelect"><li class="public"></li><li class="private"></li></ul>' )
} else if ( $ ( this ) . hasClass ( 'public' ) ) {
$ ( this ) . append ( '<ul class="permissionSelect"><li class="commons"></li><li class="private"></li></ul>' )
} else if ( $ ( this ) . hasClass ( 'private' ) ) {
$ ( this ) . append ( '<ul class="permissionSelect"><li class="commons"></li><li class="public"></li></ul>' )
}
$ ( '.mapPermission .permissionSelect li' ) . click ( self . selectPermission )
event . stopPropagation ( )
}
} ,
hidePermissionSelect : function ( ) {
var self = Metamaps . Map . InfoBox
self . selectingPermission = false
$ ( '.mapPermission' ) . removeClass ( 'minimize' ) // this line flips the pull up arrow to a drop down arrow
$ ( '.mapPermission .permissionSelect' ) . remove ( )
} ,
selectPermission : function ( event ) {
var self = Metamaps . Map . InfoBox
self . selectingPermission = false
var permission = $ ( this ) . attr ( 'class' )
2016-09-22 18:31:56 +08:00
Active . Map . save ( {
2016-04-14 14:01:21 +08:00
permission : permission
} )
2016-09-22 18:31:56 +08:00
Active . Map . updateMapWrapper ( )
2016-04-14 14:01:21 +08:00
shareable = permission === 'private' ? '' : 'shareable'
$ ( '.mapPermission' ) . removeClass ( 'commons public private minimize' ) . addClass ( permission )
$ ( '.mapPermission .permissionSelect' ) . remove ( )
$ ( '.mapInfoBox' ) . removeClass ( 'shareable' ) . addClass ( shareable )
event . stopPropagation ( )
} ,
deleteActiveMap : function ( ) {
var confirmString = 'Are you sure you want to delete this map? '
confirmString += 'This action is irreversible. It will not delete the topics and synapses on the map.'
var doIt = confirm ( confirmString )
2016-09-22 18:31:56 +08:00
var map = Active . Map
var mapper = Active . Mapper
2016-04-14 14:01:21 +08:00
var authorized = map . authorizePermissionChange ( mapper )
if ( doIt && authorized ) {
Metamaps . Map . InfoBox . close ( )
Metamaps . Maps . Active . remove ( map )
Metamaps . Maps . Featured . remove ( map )
Metamaps . Maps . Mine . remove ( map )
2016-04-24 11:50:35 -04:00
Metamaps . Maps . Shared . remove ( map )
2016-04-14 14:01:21 +08:00
map . destroy ( )
Metamaps . Router . home ( )
2016-09-22 18:31:56 +08:00
GlobalUI . notifyUser ( 'Map eliminated!' )
2016-04-14 14:01:21 +08:00
}
else if ( ! authorized ) {
alert ( "Hey now. We can't just go around willy nilly deleting other people's maps now can we? Run off and find something constructive to do, eh?" )
}
}
} ; // end Metamaps.Map.InfoBox
2016-09-22 15:21:59 +08:00
export default Metamaps . Map