realtime and filter box styling

This commit is contained in:
Connor Turland 2014-09-03 19:05:25 -04:00
parent 1ccaccdb32
commit eedd3736cf
13 changed files with 339 additions and 442 deletions

View file

@ -1,262 +0,0 @@
/*
* textillate.js
* http://jschr.github.com/textillate
* MIT licensed
*
* Copyright (C) 2012-2013 Jordan Schroter
*/
(function ($) {
"use strict";
function isInEffect (effect) {
return /In/.test(effect) || $.inArray(effect, $.fn.textillate.defaults.inEffects) >= 0;
};
function isOutEffect (effect) {
return /Out/.test(effect) || $.inArray(effect, $.fn.textillate.defaults.outEffects) >= 0;
};
// custom get data api method
function getData (node) {
var attrs = node.attributes || []
, data = {};
if (!attrs.length) return data;
$.each(attrs, function (i, attr) {
if (/^data-in-*/.test(attr.nodeName)) {
data.in = data.in || {};
data.in[attr.nodeName.replace(/data-in-/, '')] = attr.nodeValue;
} else if (/^data-out-*/.test(attr.nodeName)) {
data.out = data.out || {};
data.out[attr.nodeName.replace(/data-out-/, '')] = attr.nodeValue;
} else if (/^data-*/.test(attr.nodeName)) {
data[attr.nodeName] = attr.nodeValue;
}
})
return data;
}
function shuffle (o) {
for (var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
}
function animate ($c, effect, cb) {
$c.addClass('animated ' + effect)
.css('visibility', 'visible')
.show();
$c.one('animationend webkitAnimationEnd oAnimationEnd', function () {
$c.removeClass('animated ' + effect);
cb && cb();
});
}
function animateChars ($chars, options, cb) {
var that = this
, count = $chars.length;
if (!count) {
cb && cb();
return;
}
if (options.shuffle) $chars = shuffle($chars);
if (options.reverse) $chars = $chars.toArray().reverse();
$.each($chars, function (i, c) {
var $char = $(c);
function complete () {
if (isInEffect(options.effect)) {
$char.css('visibility', 'visible');
} else if (isOutEffect(options.effect)) {
$char.css('visibility', 'hidden');
}
count -= 1;
if (!count && cb) cb();
}
var delay = options.sync ? options.delay : options.delay * i * options.delayScale;
$char.text() ?
setTimeout(function () { animate($char, options.effect, complete) }, delay) :
complete();
});
};
var Textillate = function (element, options) {
var base = this
, $element = $(element);
base.init = function () {
base.$texts = $element.find(options.selector);
if (!base.$texts.length) {
base.$texts = $('<ul class="texts"><li>' + $element.html() + '</li></ul>');
$element.html(base.$texts);
}
base.$texts.hide();
base.$current = $('<span>')
.text(base.$texts.find(':first-child').html())
.prependTo($element);
if (isInEffect(options.effect)) {
base.$current.css('visibility', 'hidden');
} else if (isOutEffect(options.effect)) {
base.$current.css('visibility', 'visible');
}
base.setOptions(options);
setTimeout(function () {
base.options.autoStart && base.start();
}, base.options.initialDelay)
};
base.setOptions = function (options) {
base.options = options;
};
base.triggerEvent = function (name) {
var e = $.Event(name + '.tlt', { data: base });
$element.trigger(e);
return e;
};
base.in = function (index, cb) {
index = index || 0;
var $elem = base.$texts.find(':nth-child(' + (index + 1) + ')')
, options = $.extend({}, base.options, getData($elem))
, $chars;
base.triggerEvent('inAnimationBegin');
base.$current
.text($elem.html())
.lettering('words');
base.$current.find('[class^="word"]')
.css({
'display': 'inline-block',
// fix for poor ios performance
'-webkit-transform': 'translate3d(0,0,0)',
'-moz-transform': 'translate3d(0,0,0)',
'-o-transform': 'translate3d(0,0,0)',
'transform': 'translate3d(0,0,0)'
})
.each(function () { $(this).lettering() });
$chars = base.$current
.find('[class^="char"]')
.css('display', 'inline-block');
if (isInEffect(options.in.effect)) {
$chars.css('visibility', 'hidden');
} else if (isOutEffect(options.in.effect)) {
$chars.css('visibility', 'visible');
}
base.currentIndex = index;
animateChars($chars, options.in, function () {
base.triggerEvent('inAnimationEnd');
if (options.in.callback) options.in.callback();
if (cb) cb(base);
});
};
base.out = function (cb) {
var $elem = base.$texts.find(':nth-child(' + (base.currentIndex + 1) + ')')
, $chars = base.$current.find('[class^="char"]')
, options = $.extend({}, base.options, getData($elem));
base.triggerEvent('outAnimationBegin');
animateChars($chars, options.out, function () {
base.triggerEvent('outAnimationEnd');
if (options.out.callback) options.out.callback();
if (cb) cb(base);
});
};
base.start = function (index) {
base.triggerEvent('start');
(function run (index) {
base.in(index, function () {
var length = base.$texts.children().length;
index += 1;
if (!base.options.loop && index >= length) {
if (base.options.callback) base.options.callback();
base.triggerEvent('end');
} else {
index = index % length;
setTimeout(function () {
base.out(function () {
run(index)
});
}, base.options.minDisplayTime);
}
});
}(index || 0));
};
base.init();
}
$.fn.textillate = function (settings, args) {
return this.each(function () {
var $this = $(this)
, data = $this.data('textillate')
, options = $.extend(true, {}, $.fn.textillate.defaults, getData(this), typeof settings == 'object' && settings);
if (!data) {
$this.data('textillate', (data = new Textillate(this, options)));
} else if (typeof settings == 'string') {
data[settings].apply(data, [].concat(args));
} else {
data.setOptions.call(data, options);
}
})
};
$.fn.textillate.defaults = {
selector: '.texts',
loop: false,
minDisplayTime: 2000,
initialDelay: 0,
in: {
effect: 'fadeInLeftBig',
delayScale: 1.5,
delay: 50,
sync: false,
reverse: false,
shuffle: false,
callback: function () {}
},
out: {
effect: 'hinge',
delayScale: 1.5,
delay: 50,
sync: false,
reverse: false,
shuffle: false,
callback: function () {}
},
autoStart: true,
inEffects: [],
outEffects: [ 'hinge' ],
callback: function () {}
};
}(jQuery));

View file

@ -9,6 +9,10 @@ Metamaps.Backbone.Map = Backbone.Model.extend({
if (mapper && (this.get('permission') === "commons" || this.get('user_id') === mapper.get('id'))) return true;
else return false;
},
authorizePermissionChange: function (mapper) {
if (mapper && this.get('user_id') === mapper.get('id')) return true;
else return false;
},
getUser: function () {
return Metamaps.Mapper.get(this.get('user_id'));
},
@ -133,7 +137,7 @@ Metamaps.Backbone.Mapper = Backbone.Model.extend({
prepareLiForFilter: function () {
var li = '';
li += '<li data-id="' + this.id.toString() + '">';
li += '<img src="/assets/icons/person.png" data-id="' + this.id.toString() + '"';
li += '<img src="' + this.get("image") + '" data-id="' + this.id.toString() + '"';
li += ' alt="' + this.get('name') + '" />';
li += '<p>' + this.get('name') + '</p></li>';
return li;

View file

@ -78,7 +78,6 @@ Metamaps.GlobalUI = {
// initialize global backbone models and collections
if (Metamaps.Active.Mapper) Metamaps.Active.Mapper = new Metamaps.Backbone.Mapper(Metamaps.Active.Mapper);
Metamaps.Mappers = new Metamaps.Backbone.MapperCollection([Metamaps.Active.Mapper]);
var myCollection = Metamaps.Maps.Mine ? Metamaps.Maps.Mine : [];
var featuredCollection = Metamaps.Maps.Featured ? Metamaps.Maps.Featured : [];
@ -437,9 +436,9 @@ Metamaps.GlobalUI.Search = {
startTypeahead: function () {
var self = Metamaps.GlobalUI.Search;
var mapheader = Metamaps.Active.Mapper ? '<h3 class="search-header">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>' : '<h3 class="search-header">Maps</h3><div class="minimizeResults minimizeMapResults"></div><div class="clearfloat"></div>';
var topicheader = Metamaps.Active.Mapper ? '<h3 class="search-header">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>' : '<h3 class="search-header">Topics</h3><div class="minimizeResults minimizeTopicResults"></div><div class="clearfloat"></div>';
var mapperheader = '<h3 class="search-header">Mappers</h3><div class="minimizeResults minimizeMapperResults"></div><div class="clearfloat"></div>';
var mapheader = Metamaps.Active.Mapper ? '<div class="searchTopicsHeader 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="searchTopicsHeader searchHeader"><h3 class="search-heading">Maps</h3><div class="minimizeResults minimizeMapResults"></div><div class="clearfloat"></div></div>';
var topicheader = Metamaps.Active.Mapper ? '<div class="searchMapsHeader 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="searchMapsHeader 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',
@ -516,6 +515,7 @@ Metamaps.GlobalUI.Search = {
filter: function (dataset) {
if (dataset.length == 0) {
dataset.push({
profile: "/assets/user.png",
value: "No results",
label: "No results",
rtype: "noresult"

View file

@ -196,7 +196,7 @@ Metamaps.Backbone.init = function () {
prepareLiForFilter: function () {
var li = '';
li += '<li data-id="' + this.get('desc') + '">';
li += '<img src="/assets/synapsevisualize.png"';
li += '<img src="/assets/synapse16.png"';
li += ' alt="synapse icon" />';
li += '<p>' + this.get('desc') + '</p></li>';
return li;
@ -306,31 +306,44 @@ Metamaps.Backbone.init = function () {
Metamaps.Metacodes = Metamaps.Metacodes ? new self.MetacodeCollection(Metamaps.Metacodes) : new self.MetacodeCollection();
Metamaps.Topics = Metamaps.Topics ? new self.TopicCollection(Metamaps.Topics) : new self.TopicCollection();
Metamaps.Topics.on("add remove", function(topic){
Metamaps.Filter.checkMetacodes();
Metamaps.Filter.checkMappers();
});
Metamaps.Synapses = Metamaps.Synapses ? new self.SynapseCollection(Metamaps.Synapses) : new self.SynapseCollection();
Metamaps.Synapses.on("add remove", function(synapse){
Metamaps.Filter.checkSynapses();
Metamaps.Filter.checkMappers();
});
Metamaps.Mappers = Metamaps.Mappers ? new self.MapperCollection(Metamaps.Mappers) : new self.MapperCollection();
if (Metamaps.Active.Map) {
Metamaps.Mappings = Metamaps.Mappings ? new self.MappingCollection(Metamaps.Mappings) : new self.MappingCollection();
Metamaps.Mappings.on("add remove", function(synapse){
Metamaps.Filter.checkMetacodes();
Metamaps.Filter.checkMappers();
});
Metamaps.Active.Map = new self.Map(Metamaps.Active.Map);
}
if (Metamaps.Active.Topic) Metamaps.Active.Topic = new self.Topic(Metamaps.Active.Topic);
//attach collection event listeners
self.attachCollectionEvents = function () {
Metamaps.Topics.on("add remove", function(topic){
Metamaps.Map.InfoBox.updateNumbers();
Metamaps.Filter.checkMetacodes();
Metamaps.Filter.checkMappers();
});
Metamaps.Synapses.on("add remove", function(synapse){
Metamaps.Map.InfoBox.updateNumbers();
Metamaps.Filter.checkSynapses();
Metamaps.Filter.checkMappers();
});
if (Metamaps.Active.Map) {
Metamaps.Mappings.on("add remove", function(mapping){
Metamaps.Map.InfoBox.updateNumbers();
Metamaps.Filter.checkSynapses();
Metamaps.Filter.checkMetacodes();
Metamaps.Filter.checkMappers();
});
}
}
self.attachCollectionEvents();
}; // end Metamaps.Backbone.init
@ -615,7 +628,6 @@ Metamaps.Create = {
Metamaps.TopicCard = {
openTopicCard: null, //stores the JIT local ID of the topic with the topic card open
linkActionsString: '<div class="linkActions"><div id="linkshare">share</div><div id="linkremove">remove</div> </div>',
init: function () {
// initialize best_in_place editing
@ -1333,6 +1345,14 @@ Metamaps.Util = {
}
return b + s;
},
nowDateFormatted: function () {
var date = new Date(Date.now());
var month = (date.getMonth() + 1) < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1);
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
var year = date.getFullYear();
return month + '/' + day + '/' + year;
},
decodeEntities: function (desc) {
var str, temp = document.createElement('p');
temp.innerHTML = desc; //browser handles the topics
@ -1380,7 +1400,8 @@ Metamaps.Realtime = {
init: function () {
var self = Metamaps.Realtime;
$(".realtimeOnOff").click(self.toggle);
$(".rtOn").click(self.turnOn);
$(".rtOff").click(self.turnOff);
$('.sidebarCollaborateIcon').click(self.toggleBox);
$('.sidebarCollaborateBox').click(function(event){
@ -1391,7 +1412,7 @@ Metamaps.Realtime = {
var mapperm = Metamaps.Active.Map && Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
if (mapperm) {
self.socket = io.connect('http://gentle-savannah-1303.herokuapp.com');
self.socket = io.connect('http://localhost:5001');
self.socket.on('connect', function () {
console.log('socket connected');
self.setupSocket();
@ -1431,20 +1452,25 @@ Metamaps.Realtime = {
});
}
},
toggle: function () {
turnOn: function () {
var self = Metamaps.Realtime;
if (!self.status) {
self.sendRealtimeOn();
$(this).html('ON').removeClass('rtOff').addClass('rtOn');
$(".rtMapperSelf").removeClass('littleRtOff').addClass('littleRtOn');
} else {
self.sendRealtimeOff();
$(this).html('OFF').removeClass('rtOn').addClass('rtOff');
$(".rtMapperSelf").removeClass('littleRtOn').addClass('littleRtOff');
self.status = true;
$(".sidebarCollaborateIcon").addClass("blue");
}
},
turnOff: function () {
var self = Metamaps.Realtime;
if (self.status) {
self.sendRealtimeOff();
$(".rtMapperSelf").removeClass('littleRtOn').addClass('littleRtOff');
self.status = false;
$(".sidebarCollaborateIcon").removeClass("blue");
}
self.status = !self.status;
$(".sidebarCollaborateIcon").toggleClass("blue");
},
setupSocket: function () {
var self = Metamaps.Realtime;
@ -1454,6 +1480,7 @@ Metamaps.Realtime = {
socket.emit('newMapperNotify', {
userid: myId,
username: Metamaps.Active.Mapper.get("name"),
userimage: Metamaps.Active.Mapper.get("image"),
mapid: Metamaps.Active.Map.id
});
@ -1504,6 +1531,7 @@ Metamaps.Realtime = {
// data.userid
// data.username
// data.userimage
// data.userrealtime
self.mappersOnMap[data.userid] = {
@ -1516,7 +1544,11 @@ Metamaps.Realtime = {
mapperListItem += data.userid;
mapperListItem += '" class="rtMapper littleRt';
mapperListItem += onOff;
mapperListItem += '">' + data.username + '</li>';
mapperListItem += '">';
mapperListItem += '<img src="' + data.userimage + '" width="24" height="24" class="rtUserImage" />';
mapperListItem += data.username;
mapperListItem += '<div class="littleJuntoIcon"></div>';
mapperListItem += '</li>';
$('#mapper' + data.userid).remove();
$('.realtimeMapperList ul').append(mapperListItem);
@ -1527,13 +1559,19 @@ Metamaps.Realtime = {
// data.userid
// data.username
// data.userimage
self.mappersOnMap[data.userid] = {
name: data.username,
realtime: true
};
var mapperListItem = '<li id="mapper' + data.userid + '" class="rtMapper littleRtOn">' + data.username + '</li>';
var mapperListItem = '<li id="mapper' + data.userid + '" class="rtMapper littleRtOn">';
mapperListItem += '<img src="' + data.userimage + '" width="24" height="24" class="rtUserImage" />';
mapperListItem += data.username;
mapperListItem += '<div class="littleJuntoIcon"></div>';
mapperListItem += '</li>';
$('#mapper' + data.userid).remove();
$('.realtimeMapperList ul').append(mapperListItem);
@ -1543,6 +1581,7 @@ Metamaps.Realtime = {
var update = {
userToNotify: data.userid,
username: Metamaps.Active.Mapper.get("name"),
userimage: Metamaps.Active.Mapper.get("image"),
userid: Metamaps.Active.Mapper.id,
userrealtime: self.status,
mapid: Metamaps.Active.Map.id
@ -2070,7 +2109,8 @@ Metamaps.Filter = {
if (!self.isOpen && !self.changing) {
self.changing = true;
$('.sidebarFilterBox').fadeIn(200, function () {
var height = $(document).height() - 108;
$('.sidebarFilterBox').css('max-height', height + 'px').fadeIn(200, function () {
self.changing = false;
self.isOpen = true;
});
@ -2177,6 +2217,8 @@ Metamaps.Filter = {
$('#filter_by_' + listToModify + ' li[data-id="' + identifier + '"]').fadeOut('fast',function(){
$(this).remove();
});
index = self.visible[filtersToUser].indexOf(identifier);
self.visible[filtersToUse].splice(index, 1);
});
var model, li, jQueryLi;
@ -2192,7 +2234,8 @@ Metamaps.Filter = {
li = model.prepareLiForFilter();
jQueryLi = $(li).hide();
$('li', '#filter_by_' + listToModify + ' ul').add(jQueryLi.fadeIn("fast"))
.sort(sortAlpha).appendTo('#filter_by_' + listToModify + ' ul');
.sort(sortAlpha).appendTo('#filter_by_' + listToModify + ' ul');
self.visible[filtersToUse].push(identifier);
});
// update the list of filters with the new list we just generated
@ -2272,12 +2315,10 @@ Metamaps.Filter = {
},
toggleMapper: function () {
var self = Metamaps.Filter;
self.toggleLi.call(this, 'mappers');
},
toggleSynapse: function () {
var self = Metamaps.Filter;
self.toggleLi.call(this, 'synapses');
},
passFilters: function () {
@ -2313,6 +2354,7 @@ Metamaps.Filter = {
}
else {
if (n) {
// TODO quick deselect node
n.setData('alpha', 0, 'end');
}
else console.log(topic);
@ -2334,12 +2376,13 @@ Metamaps.Filter = {
if (passesSynapse && passesMapper) {
if (e) {
e.setData('alpha', 1, 'end');
e.setData('alpha', 0.4, 'end');
}
else console.log(synapse);
}
else {
if (e) {
// TODO quick deselect edge
e.setData('alpha', 0, 'end');
}
else console.log(synapse);
@ -2350,7 +2393,7 @@ Metamaps.Filter = {
Metamaps.Visualize.mGraph.fx.animate({
modes: ['node-property:alpha',
'edge-property:alpha'],
duration: 500
duration: 200
});
}
}; // end Metamaps.Filter
@ -2553,6 +2596,7 @@ Metamaps.Topic = {
Metamaps.Active.Topic = new bb.Topic(data.topic);
Metamaps.Topics = new bb.TopicCollection([data.topic].concat(data.relatives));
Metamaps.Synapses = new bb.SynapseCollection(data.synapses);
Metamaps.Backbone.attachCollectionEvents();
// build and render the visualization
Metamaps.Visualize.type = "RGraph";
@ -2884,6 +2928,7 @@ Metamaps.Map = {
Metamaps.Topics = new bb.TopicCollection(data.topics);
Metamaps.Synapses = new bb.SynapseCollection(data.synapses);
Metamaps.Mappings = new bb.MappingCollection(data.mappings);
Metamaps.Backbone.attachCollectionEvents();
// build and render the visualization
Metamaps.Visualize.type = "ForceDirected";
@ -2893,6 +2938,9 @@ Metamaps.Map = {
Metamaps.Filter.reset();
Metamaps.Filter.initializeFilterData(); // this sets all the visible filters to true
// set the proper mapinfobox content
Metamaps.Map.InfoBox.load();
// these three update the actual filter box with the right list items
Metamaps.Filter.checkMetacodes();
Metamaps.Filter.checkSynapses();
@ -2968,23 +3016,22 @@ Metamaps.Map.InfoBox = {
isOpen: false,
changing: false,
selectingPermission: false,
changePermissionText: "<div class='tip'>As the creator, you can change the permission of this map, but the permissions of the topics and synapses on it must be changed independently.</div>",
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="input">{{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">{{desc}}</span>',
deleteHTML: "<a href='/maps/{{id}}' class='delete' data-bypass='true' data-confirm='Delete this map (nodes and synapses will remain)?' data-method='delete' rel='nofollow'>Delete</a>",
init: function () {
var self = Metamaps.Map.InfoBox;
// because anyone who can edit the map can change the map title
$('.mapInfoName .best_in_place_name').bind("ajax:success", function () {
var name = $(this).html();
$('.mapName').html(name);
Metamaps.Active.Map.set('name', name);
});
$('.yourMap .mapPermission').click(self.onPermissionClick);
$('.mapInfoIcon').click(self.toggleBox);
$('.mapInfoBox').click(function(event){
event.stopPropagation();
});
$('body').click(self.close);
self.attachEventListeners();
self.generateBoxHTML = Hogan.compile($('#mapInfoBoxTemplate').html());
},
toggleBox: function (event) {
var self = Metamaps.Map.InfoBox;
@ -3016,6 +3063,66 @@ Metamaps.Map.InfoBox = {
});
}
},
load: function () {
var self = Metamaps.Map.InfoBox;
var map = Metamaps.Active.Map;
var obj = map.pick("permission","contributor_count","topic_count","synapse_count","created_at","updated_at");
var isCreator = map.authorizePermissionChange(Metamaps.Active.Mapper);
var canEdit = map.authorizeToEdit(Metamaps.Active.Mapper);
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 : "";
obj["delete"] = isCreator ? Hogan.compile(self.deleteHTML).render({id: map.id}) : "";
obj["contributor_list"] = self.createContributorList();
obj["user_name"] = isCreator ? "you" : map.get("user_name");
var classes = isCreator ? "yourMap" : "";
classes += canEdit ? " canEdit" : "";
$(".mapInfoBox").removeClass("yourMap canEdit")
.addClass(classes)
.html(self.generateBoxHTML.render(obj));
self.attachEventListeners();
},
attachEventListeners: function () {
var self = Metamaps.Map.InfoBox;
$('.mapInfoBox .best_in_place').best_in_place();
// because anyone who can edit the map can change the map title
$('.mapInfoName .best_in_place_name').unbind("ajax:success").bind("ajax:success", function () {
var name = $(this).html();
$('.mapName').html(name);
Metamaps.Active.Map.set('name', name);
});
$('.yourMap .mapPermission').unbind().click(self.onPermissionClick);
},
createContributorList: function () {
var self = Metamaps.Map.InfoBox;
var mapperNames = Metamaps.Mappers.pluck("name");
return mapperNames.length > 0 ? mapperNames.join(", ") : "No one has added anything yet.";
},
updateNumbers: function () {
var self = Metamaps.Map.InfoBox;
var mapper = Metamaps.Active.Mapper;
if (mapper && Metamaps.Mappers.get(mapper.id) === undefined) {
Metamaps.Mappers.add(mapper);
}
$('.mapContributors').text(Metamaps.Mappers.length)
.append('<div class="tip">' + self.createContributorList() + '</div>');
$('.mapTopics').text(Metamaps.Topics.length);
$('.mapSynapses').text(Metamaps.Synapses.length);
$('.mapEditedAt').html('Last edited ' + Metamaps.Util.nowDateFormatted());
},
onPermissionClick: function () {
var self = Metamaps.Map.InfoBox;

View file

@ -85,8 +85,6 @@ body {
font-family: 'din-medium', helvetica, sans-serif;
color: #424242;
}
h1,
h2,
h3,
@ -95,19 +93,6 @@ h5,
h6 {
font-weight: normal;
}
h1 {
display: block;
text-align: left;
font-family: "vinyl", sans-serif;
}
h2 {
display: block;
text-align: center;
font-family: "katarine-web", sans-serif;
background: url('black_bg.png');
font-size: 24px;
line-height: 35px;
}
a {
color: #424242;
text-decoration: none;
@ -677,10 +662,8 @@ label[for="user_remember_me"] {
.sidebarFilterBox {
display:none;
height: 400px;
width: 320px;
padding: 10px;
text-align: center;
width: 304px;
padding: 16px 0;
overflow-y: auto;
}
h3.filterBox {
@ -689,53 +672,78 @@ h3.filterBox {
}
.sidebarFilterBox span {
float: right;
background: #15bad4;
padding: 1px 4px;
border-radius: 2px;
margin-left: 5px;
margin-right: 5px;
cursor: pointer;
font-size:12px;
}
.sidebarFilterBox span:hover {
color: #00BCD4;
}
.sidebarFilterBox ul {
list-style: none;
}
.sidebarFilterBox li {
float: left;
width: 61px;
height: 70px;
width: 72px;
height: 72px;
cursor: pointer;
text-align: center;
}
.sidebarFilterBox li:hover {
background: #000;
}
.sidebarFilterBox li img {
background-color: rgba(255, 255, 255, 0.1);
width: 45px;
height: 45px;
margin: 0 auto;
#filter_by_mapper li img {
width: 40px;
height: 40px;
border-radius: 20px;
margin: 8px auto;
}
#filter_by_metacode li img {
width: 40px;
height: 40px;
margin: 8px auto;
}
#filter_by_synapse li img {
width: 16px;
height: 16px;
margin: 8px auto;
}
.sidebarFilterBox li p {
font-size: 11px;
line-height: 11px;
font-family: arial, sans-serif;
font-family: 'din-regular', helvetica, sans-serif;
}
.sidebarFilterBox li.toggledOff {
opacity: 0.4;
}
.sidebarFilterBox h2 {
font-size: 18px;
margin-left: 16px;
line-height: 18px;
}
.sidebarFilterBox h3 {
text-align: left;
text-transform: uppercase;
font-weight: bold;
font-size:14px;
float:left;
}
.filterBySection {
margin-left:16px;
width: 288px;
border-top: 1px solid #BDBDBD;
padding-top:8px;
margin-top:8px;
}
#filter_by_metacode {
border-bottom: 1px solid black;
margin: 5px;
}
#filter_by_mapper {
margin: 5px auto;
}
#filter_by_synapse {
margin: 5px auto;
border-bottom: 1px solid black;
}
/* end filter by metacode */
@ -748,52 +756,66 @@ h3.filterBox {
.sidebarCollaborateBox {
display: none;
height: auto;
width: auto;
padding: 10px;
min-width: 180px;
padding: 16px;
width: 238px;
}
h3.realtimeBoxTitle {
margin-bottom: 10px;
text-align: left;
float: left;
font-family: 'Lato', helvetica, sans-serif;
font-size:18px;
line-height:18px;
}
.sidebarCollaborateBox .realtimeOnOff {
float: left;
float: right;
padding: 4px;
border-radius: 2px;
margin-left: 12px;
cursor: pointer;
width: 31px;
text-align: center;
font-size:12px;
}
.sidebarCollaborateBox .realtimeOnOff:hover {
color: #00bcd4;
}
.sidebarCollaborateBox .rtOff {
background: white;
color: black;
}
.sidebarCollaborateBox .rtOff:hover {
padding: 3px;
border: 1px solid #15bad4;
}
.sidebarCollaborateBox .rtOn {
background: #15bad4;
color: white;
}
.realtimeMapperList .rtMapper {
list-style-type: none;
white-space: nowrap;
padding: 2px 5px 2px 30px;
overflow: hidden;
text-overflow: ellipsis;
padding: 9px 32px;
display: block;
background-size: 26px 26px;
background-repeat: no-repeat;
background-position: 4px center;
margin-bottom: 5px;
height: 14px;
font-family: 'din-regular', helvetica, sans-serif;
font-size: 14px;
line-height: 14px;
position: relative;
}
.realtimeMapperList .littleRtOff {
background-image: url('junto24.png');
.rtUserImage {
position: absolute;
top: 4px;
left: 0;
border-radius: 12px;
}
.realtimeMapperList .littleRtOn {
background-image: url('junto24.png');
.littleJuntoIcon {
width: 24px;
height:24px;
position: absolute;
top: 4px;
right: 0;
background-image: url('junto24_sprite.png');
}
.realtimeMapperList .littleRtOff .littleJuntoIcon {
background-position: 0 0;
}
.realtimeMapperList .littleRtOn .littleJuntoIcon {
background-position: -24px 0;
}
/* end collaborate */
@ -1116,7 +1138,7 @@ float: left;
background-position: 13px center;
}
.mapSynapses {
background-image: url(synapse32tmcard.png);
background-image: url(synapse32.png);
background-position: 13px center;
}
.mapInfoBox .mapPermission {
@ -1126,23 +1148,26 @@ float: left;
padding: 0;
margin: 8px 30px 8px 10px;
position: relative;
background-image: url(permissions32_sprite.png);
}
.mapInfoBox .mapPermission.commons {
background-image: url(CO32.png);
background-position: 0 0;
}
.mapInfoBox .mapPermission.public {
background-image: url(PU32.png);
background-position: -64px 0;
}
.mapInfoBox .mapPermission.private {
background-image: url(PR32.png);
background-position: -32px 0;
}
.yourMap .mapPermission:hover {
background-image: url(arrowexpand.png);
background-image: url(arrowdown_sprite.png);
cursor: pointer;
background-position: center -11px;
}
.yourMap .mapPermission.minimize {
background-image: url(arrowcollapse.png) !important;
background-image: url(arrowdown_sprite.png) !important;
cursor: pointer;
background-position: center -11px;
}
.mapInfoBox .mapPermission .permissionSelect {
list-style: none;
@ -1155,25 +1180,25 @@ float: left;
width: 32px;
height: 32px;
background-repeat: no-repeat;
background-position: center center;
background-image: url(permissions32_sprite.png);
}
.mapInfoBox .mapPermission .permissionSelect .commons {
background-image: url(CO32.png);
background-position: 0 0;
}
.mapInfoBox .mapPermission .permissionSelect .public {
background-image: url(PU32.png);
background-position: -64px 0;
}
.mapInfoBox .mapPermission .permissionSelect .private {
background-image: url(PR32.png);
background-position: -32px 0;
}
.mapInfoBox .mapPermission .permissionSelect .commons:hover {
background-image: url(CO32b.png);
background-position: 0 -32px;
}
.mapInfoBox .mapPermission .permissionSelect .public:hover {
background-image: url(PU32b.png);
background-position: -64px -32px;
}
.mapInfoBox .mapPermission .permissionSelect .private:hover {
background-image: url(PR32b.png);
background-position: -32px -32px;
}
.mapInfoBox .mapInfoDesc {
font-family: helvetica, sans-serif;
@ -1182,6 +1207,7 @@ float: left;
height: 106px;
font-size: 14px;
line-height: 16px;
overflow-y: auto;
}
.mapInfoBox .mapInfoMeta {
height: 35px;

View file

@ -202,19 +202,31 @@
font-family: 'din-medium', helvetica, sans-serif;
}
.sidebarSearch .tt-dropdown-menu {
left: -35px !important;
background: #0F1519;
min-width: 440px;
width: 440px;
overflow-y: scroll;
top: 40px !important;
background: #FFF;
width: 472px;
overflow-y: auto;
overflow-x: hidden;
box-shadow: 0 1px 1.5px rgba(0,0,0,0.12), 0 1px 1px rgba(0,0,0,0.24);
}
.searchHeader {
height: 42px;
width: 100%;
}
.searchTopicsHeader {
background: #4fc4a8;
}
.searchMapsHeader {
background: #994fc0;
}
.searchMappersHeader {
background: #c04f4f;
}
.sidebarSearch .tt-dropdown-menu h3 {
font-family: 'vinyl', helvetica, sans-serif;
text-transform: uppercase;
font-style: italic;
font-size: 20px;
line-height: 20px;
color: #F5F5F5;
font-size: 18px;
line-height: 18px;
margin: 10px 0 3px 10px;
float: left;
}
@ -246,15 +258,14 @@
cursor: pointer;
}
.sidebarSearch .tt-suggestions {
font-family: 'LatoLight', helvetica, sans-serif;
overflow: visible;
}
.sidebarSearch .tt-suggestion {
background: #2A343C;
background: #FFF;
}
.sidebarSearch .tt-is-under-cursor,
.sidebarSearch .tt-is-under-mouse-cursor {
background: #0E161D;
background: #E0E0E0;
}
.sidebarSearch .tt-dataset-maps .tt-is-under-cursor .resultmap,
.sidebarSearch .tt-dataset-maps .tt-is-under-mouse-cursor .resultmap,
@ -264,9 +275,10 @@
}
.sidebarSearch .tt-suggestion .icon {
float: left;
width: 36px;
height: 36px;
width: 32px;
height: 32px;
margin-right: 5px;
border-radius:16px;
}
.sidebarSearch .topicMetacode {
float: left;
@ -274,8 +286,8 @@
max-width: 70px;
}
.sidebarSearch .tt-dataset-topics .topicIcon {
width: 36px;
height: 36px;
width: 32px;
height: 32px;
}
.sidebarSearch .tt-dataset-topics .tt-is-under-cursor .topicIcon,
.sidebarSearch .tt-dataset-topics .tt-is-under-mouse-cursor .topicIcon {
@ -296,9 +308,7 @@
text-align: center;
}
.sidebarSearch .tt-dataset-mappers .tt-suggestion .icon {
width: 28px;
height: 28px;
padding: 4px;
margin: 4px 9px 4px 4px;
}
.sidebarSearch .resultText {
width: 225px;
@ -308,14 +318,12 @@
}
.sidebarSearch .resultTitle {
font-weight: normal;
font-family: 'LatoRegular';
font-size: 18px;
line-height: 22px;
width: 100%;
padding-top: 8px;
}
.sidebarSearch .resultDesc {
font-family: 'LatoItalic';
font-size: 14px;
line-height: 16px;
width: 100%;
@ -481,7 +489,7 @@
position: fixed;
top: 10px;
right: 24px;
z-index:3;
z-index:4;
}
.upperRightUI .upperRightEl {

View file

@ -8,6 +8,7 @@ module UsersHelper
user['id'] = u.id
user['label'] = u.name
user['value'] = u.name
user['profile'] = u.image.url(:thumb)
user['mapCount'] = u.maps.count
user['rtype'] = "mapper"

View file

@ -23,7 +23,8 @@ class User < ActiveRecord::Base
:thumb => ['100x100>', :png],
:square => ['200x200#', :png],
:round => ['200x200#', :png]
}
},
:default_url => "/assets/user.png"
#, :convert_options => {:round => Proc.new{self.convert_options}}

View file

@ -6,7 +6,7 @@
<div class="templates">
<script type="text/template" id="mapInfoBoxTemplate">
<div class="mapInfoName">{{name}}</div>
<div class="mapInfoName">{{{name}}}</div>
<div class="mapInfoStat">
<div class="infoStatIcon mapContributors hoverForTip">
@ -20,21 +20,21 @@
{{synapse_count}}
</div>
<div class="infoStatIcon mapPermission {{permission}} hoverForTip">
{{map_creator_tip}}
{{{map_creator_tip}}}
</div>
<div class="clearfloat"></div>
</div>
<div class="mapInfoDesc">
{{desc}}
{{{desc}}}
</div>
<div class="mapInfoMeta">
<p>Created by {{user_name}} on {{created_at}}</p>
<p>Last edited {{updated_at}}</p>
<p class="mapCreatedAt">Created by {{user_name}} on {{created_at}}</p>
<p class="mapEditedAt">Last edited {{updated_at}}</p>
</div>
<div class="mapInfoDelete">
{{delete}}
{{{delete}}}
</div>
</script>
@ -43,15 +43,15 @@
<div class="permission {{editPermission}}"> <!-- must be canEdit or cannotEdit -->
<div class="mapCard">
<span class="title">
<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">{{name}}</span>
{{name}}
</span>
<div class="mapScreenshot">
<img src="https://dl.dropboxusercontent.com/u/13307147/map%20screengrab%20blur-02.png">
</div>
<div class="scroll">
<div class="desc">
<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">{{desc}}</span>
<div class="clearfloat"></div>
{{desc}}
<div class="clearfloat"></div>
</div>
</div>
<div class="mapMetadata">
@ -107,7 +107,7 @@
<script type="text/template" id="mapSearchTemplate">
<div class="result{{rtype}}">
<img class="icon" src="/assets/map.png">
<img class="icon" src="/assets/metamap32c.png">
<div class="resultText">
<p class="resultTitle">{{label}}</p>
<p class="resultDesc">{{description}}</p>
@ -138,7 +138,7 @@
<script type="text/template" id="mapperSearchTemplate">
<div class="result{{rtype}}">
<img class="icon" width="28" height="28" src="/assets/MMCCicon_mapper.png">
<img class="icon" width="32" height="32" src="{{profile}}">
<div class="resultText">
<p class="resultTitle">{{label}}</p>
</div>

View file

@ -23,13 +23,16 @@
<div class="sidebarCollaborate upperRightEl">
<div class="sidebarCollaborateIcon upperRightIcon blue"></div>
<div class="sidebarCollaborateBox upperRightBox">
<h3 class="realtimeBoxTitle">Realtime: </h3>
<h3 class="realtimeBoxTitle">REALTIME</h3>
<span class="realtimeOnOff rtOff">OFF</span>
<span class="realtimeOnOff rtOn">ON</span>
<div class="clearfloat"></div>
<div class="realtimeMapperList">
<ul>
<li class="rtMapper littleRtOn rtMapperSelf">
<%= image_tag user.image.url(:thumb), :size => "24x24", :class => "rtUserImage" %>
<%= user.name %> (me)
<div class="littleJuntoIcon"></div>
</li>
</ul>
</div>

View file

@ -41,8 +41,8 @@
<% end %>
<div class="mapInfoMeta">
<p>Created by <%= @map.user == user ? "you" : @map.user.name %> on <%= @map.created_at.strftime("%m/%d/%Y") %></p>
<p>Last edited <%= @map.updated_at.strftime("%m/%d/%Y") %></p>
<p class="mapCreatedAt">Created by <%= @map.user == user ? "you" : @map.user.name %> on <%= @map.created_at.strftime("%m/%d/%Y") %></p>
<p class="mapEditedAt">Last edited <%= @map.updated_at.strftime("%m/%d/%Y") %></p>
</div>
<div class="mapInfoDelete">

View file

@ -44,43 +44,50 @@
end
@synapses.each_with_index do |synapse, index|
@synapselist += '<li data-id="' + synapse.desc + '">'
@synapselist += '<img src="/assets/synapsevisualize.png" alt="synapse icon" /><p>' + synapse.desc
@synapselist += '<img src="/assets/synapse16.png" alt="synapse icon" /><p>' + synapse.desc
@synapselist += '</p></li>'
end
@mappers.each_with_index do |mapper, index|
@mapperlist += '<li data-id="' + mapper.id.to_s + '">'
@mapperlist += '<img src="/assets/icons/person.png" data-id="' + mapper.id.to_s + '" alt="' + mapper.name + '" />'
@mapperlist += '<img src="' + mapper.image.url(:thumb) + '" data-id="' + mapper.id.to_s + '" alt="' + mapper.name + '" />'
@mapperlist += '<p>' + mapper.name + '</p></li>'
end
end
%>
<div class="filterBox">
<div class="clearfloat"></div>
<div id="filter_by_metacode">
<h3>metacodes</h3><span class="showAll showAllMetacodes">all</span> <span class="hideAll hideAllMetacodes">none</span>
<br>
<ul>
<%= @metacodelist.html_safe %>
</ul>
<h2>FILTER BY</h2>
<div id="filter_by_mapper" class="filterBySection">
<h3>MAPPERS</h3>
<span class="hideAll hideAllMappers">NONE</span>
<span class="showAll showAllMappers">ALL</span>
<div class="clearfloat"></div>
</div>
<div id="filter_by_synapse">
<h3>synapses</h3> <span class="showAll showAllSynapses">all</span> <span class="hideAll hideAllSynapses">none</span>
<br>
<ul>
<%= @synapselist.html_safe %>
</ul>
<div class="clearfloat"></div>
</div>
<div id="filter_by_mapper">
<h3>mappers</h3><span class="showAll showAllMappers">all</span> <span class="hideAll hideAllMappers">none</span>
<br>
<ul>
<%= @mapperlist.html_safe %>
</ul>
<div class="clearfloat"></div>
</div>
<div id="filter_by_metacode" class="filterBySection">
<h3>METACODES</h3>
<span class="hideAll hideAllMetacodes">NONE</span>
<span class="showAll showAllMetacodes">ALL</span>
<div class="clearfloat"></div>
<ul>
<%= @metacodelist.html_safe %>
</ul>
<div class="clearfloat"></div>
</div>
<div id="filter_by_synapse" class="filterBySection">
<h3>SYNAPSES</h3>
<span class="hideAll hideAllSynapses">NONE</span>
<span class="showAll showAllSynapses">ALL</span>
<div class="clearfloat"></div>
<ul>
<%= @synapselist.html_safe %>
</ul>
<div class="clearfloat"></div>
</div>
</div> <!-- end .filterBox -->

View file

@ -45,7 +45,8 @@ function start() {
var existingUser = {
userid: data.userid,
username: data.username,
userrealtime: data.userrealtime
userrealtime: data.userrealtime,
userimage: data.userimage
};
socket.broadcast.emit(data.userToNotify + '-' + data.mapid + '-UpdateMapperList', existingUser);
});
@ -58,7 +59,8 @@ function start() {
var newUser = {
userid: data.userid,
username: data.username
username: data.username,
userimage: data.userimage
};
socket.broadcast.emit('maps-' + data.mapid + '-newmapper', newUser);