Merge branch 'develop'

This commit is contained in:
Devin Howard 2016-04-15 11:51:40 +08:00
commit 5a60135392
15 changed files with 932 additions and 854 deletions

View file

@ -25,6 +25,7 @@
//= require ./src/views/room
//= require ./src/JIT
//= require ./src/Metamaps
//= require ./src/Metamaps.Admin
//= require ./src/Metamaps.Import
//= require ./src/Metamaps.JIT
//= require_directory ./shims

View file

@ -0,0 +1,54 @@
/* global Metamaps, $ */
/*
* Metamaps.Admin.js.erb
*
* Dependencies: none!
*/
Metamaps.Admin = {
selectMetacodes: [],
allMetacodes: [],
init: function () {
var self = Metamaps.Admin
$('#metacodes_value').val(self.selectMetacodes.toString())
},
selectAll: function () {
var self = Metamaps.Admin
$('.editMetacodes li').removeClass('toggledOff')
self.selectMetacodes = self.allMetacodes.slice(0)
$('#metacodes_value').val(self.selectMetacodes.toString())
},
deselectAll: function () {
var self = Metamaps.Admin
$('.editMetacodes li').addClass('toggledOff')
self.selectMetacodes = []
$('#metacodes_value').val(0)
},
liClickHandler: function () {
var self = Metamaps.Admin
if ($(this).attr('class') != 'toggledOff') {
$(this).addClass('toggledOff')
var value_to_remove = $(this).attr('id')
self.selectMetacodes.splice(self.selectMetacodes.indexOf(value_to_remove), 1)
$('#metacodes_value').val(self.selectMetacodes.toString())
}
else if ($(this).attr('class') == 'toggledOff') {
$(this).removeClass('toggledOff')
self.selectMetacodes.push($(this).attr('id'))
$('#metacodes_value').val(self.selectMetacodes.toString())
}
},
validate: function () {
var self = Metamaps.Admin
if (self.selectMetacodes.length == 0) {
alert('Would you pretty please select at least one metacode for the set?')
return false
}
}
}

View file

@ -1,247 +1,256 @@
Metamaps.Backbone = {};
/* global Metamaps, Backbone, _, $ */
/*
* Metamaps.Backbone.js.erb
*
* Dependencies:
* - Metamaps.Active
* - Metamaps.Loading
* - Metamaps.Map
* - Metamaps.Mapper
* - Metamaps.Realtime
*/
Metamaps.Backbone = {}
Metamaps.Backbone.Map = Backbone.Model.extend({
urlRoot: '/maps',
blacklist: ['created_at', 'updated_at', 'created_at_clean', 'updated_at_clean', 'user_name', 'contributor_count', 'topic_count', 'synapse_count', 'topics', 'synapses', 'mappings', 'mappers'],
toJSON: function (options) {
return _.omit(this.attributes, this.blacklist);
},
save: function (key, val, options) {
urlRoot: '/maps',
blacklist: ['created_at', 'updated_at', 'created_at_clean', 'updated_at_clean', 'user_name', 'contributor_count', 'topic_count', 'synapse_count', 'topics', 'synapses', 'mappings', 'mappers'],
toJSON: function (options) {
return _.omit(this.attributes, this.blacklist)
},
save: function (key, val, options) {
var attrs
var attrs;
// Handle both `"key", value` and `{key: value}` -style arguments.
if (key == null || typeof key === 'object') {
attrs = key;
options = val;
} else {
(attrs = {})[key] = val;
}
var newOptions = options || {};
var s = newOptions.success;
newOptions.success = function (model, response, opt) {
if (s) s(model, response, opt);
model.trigger('saved');
};
return Backbone.Model.prototype.save.call(this, attrs, newOptions);
},
initialize: function () {
this.on('changeByOther', this.updateView);
this.on('saved', this.savedEvent);
},
savedEvent: function() {
Metamaps.Realtime.sendMapChange(this);
},
authorizeToEdit: function (mapper) {
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'));
},
fetchContained: function () {
var bb = Metamaps.Backbone;
var that = this;
var start = function (data) {
that.set('mappers', new bb.MapperCollection(data.mappers));
that.set('topics', new bb.TopicCollection(data.topics));
that.set('synapses', new bb.SynapseCollection(data.synapses));
that.set('mappings', new bb.MappingCollection(data.mappings));
};
var e = $.ajax({
url: "/maps/" + this.id + "/contains.json",
success: start,
error: errorFunc,
async: false
});
},
getTopics: function () {
if (!this.get('topics')) {
this.fetchContained();
}
return this.get('topics');
},
getSynapses: function () {
if (!this.get('synapses')) {
this.fetchContained();
}
return this.get('synapses');
},
getMappings: function () {
if (!this.get('mappings')) {
this.fetchContained();
}
return this.get('mappings');
},
getMappers: function () {
if (!this.get('mappers')) {
this.fetchContained();
}
return this.get('mappers');
},
attrForCards: function () {
function capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
var n = this.get('name');
var d = this.get('desc');
var maxNameLength = 32;
var maxDescLength = 118;
var truncatedName = n ? (n.length > maxNameLength ? n.substring(0, maxNameLength) + "..." : n) : "";
var truncatedDesc = d ? (d.length > maxDescLength ? d.substring(0, maxDescLength) + "..." : d) : "";
var obj = {
id: this.id,
name: truncatedName,
fullName: n,
desc: truncatedDesc,
permission: this.get("permission") ? capitalize(this.get("permission")) : "Commons",
editPermission: this.authorizeToEdit(Metamaps.Active.Mapper) ? 'canEdit' : 'cannotEdit',
contributor_count_number: '<span class="cCountColor">' + this.get('contributor_count') + '</span>',
contributor_count_string: this.get('contributor_count') == 1 ? ' contributor' : ' contributors',
topic_count_number: '<span class="tCountColor">' + this.get('topic_count') + '</span>',
topic_count_string: this.get('topic_count') == 1 ? ' topic' : ' topics',
synapse_count_number: '<span class="sCountColor">' + this.get('synapse_count') + '</span>',
synapse_count_string: this.get('synapse_count') == 1 ? ' synapse' : ' synapses',
screenshot: '<img src="' + this.get('screenshot_url') + '" />'
};
return obj;
},
updateView: function() {
var map = Metamaps.Active.Map;
var isActiveMap = this.id === map.id;
var authorized = map && map.authorizeToEdit(Metamaps.Active.Mapper) ? 'canEditMap' : '';
var commonsMap = map && map.get('permission') === 'commons' ? 'commonsMap' : '';
if (isActiveMap) {
Metamaps.Map.InfoBox.updateNameDescPerm(this.get('name'), this.get('desc'), this.get('permission'));
this.updateMapWrapper();
}
},
updateMapWrapper: function() {
var map = Metamaps.Active.Map;
var isActiveMap = this.id === map.id;
var authorized = map && map.authorizeToEdit(Metamaps.Active.Mapper) ? 'canEditMap' : '';
var commonsMap = map && map.get('permission') === 'commons' ? 'commonsMap' : '';
if (isActiveMap) {
$('.wrapper').removeClass('canEditMap commonsMap').addClass(authorized + ' ' + commonsMap);
}
// Handle both `"key", value` and `{key: value}` -style arguments.
if (key == null || typeof key === 'object') {
attrs = key
options = val
} else {
(attrs = {})[key] = val
}
});
var newOptions = options || {}
var s = newOptions.success
newOptions.success = function (model, response, opt) {
if (s) s(model, response, opt)
model.trigger('saved')
}
return Backbone.Model.prototype.save.call(this, attrs, newOptions)
},
initialize: function () {
this.on('changeByOther', this.updateView)
this.on('saved', this.savedEvent)
},
savedEvent: function () {
Metamaps.Realtime.sendMapChange(this)
},
authorizeToEdit: function (mapper) {
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'))
},
fetchContained: function () {
var bb = Metamaps.Backbone
var that = this
var start = function (data) {
that.set('mappers', new bb.MapperCollection(data.mappers))
that.set('topics', new bb.TopicCollection(data.topics))
that.set('synapses', new bb.SynapseCollection(data.synapses))
that.set('mappings', new bb.MappingCollection(data.mappings))
}
$.ajax({
url: '/maps/' + this.id + '/contains.json',
success: start,
async: false
})
},
getTopics: function () {
if (!this.get('topics')) {
this.fetchContained()
}
return this.get('topics')
},
getSynapses: function () {
if (!this.get('synapses')) {
this.fetchContained()
}
return this.get('synapses')
},
getMappings: function () {
if (!this.get('mappings')) {
this.fetchContained()
}
return this.get('mappings')
},
getMappers: function () {
if (!this.get('mappers')) {
this.fetchContained()
}
return this.get('mappers')
},
attrForCards: function () {
function capitalize (string) {
return string.charAt(0).toUpperCase() + string.slice(1)
}
var n = this.get('name')
var d = this.get('desc')
var maxNameLength = 32
var maxDescLength = 118
var truncatedName = n ? (n.length > maxNameLength ? n.substring(0, maxNameLength) + '...' : n) : ''
var truncatedDesc = d ? (d.length > maxDescLength ? d.substring(0, maxDescLength) + '...' : d) : ''
var obj = {
id: this.id,
name: truncatedName,
fullName: n,
desc: truncatedDesc,
permission: this.get('permission') ? capitalize(this.get('permission')) : 'Commons',
editPermission: this.authorizeToEdit(Metamaps.Active.Mapper) ? 'canEdit' : 'cannotEdit',
contributor_count_number: '<span class="cCountColor">' + this.get('contributor_count') + '</span>',
contributor_count_string: this.get('contributor_count') === 1 ? ' contributor' : ' contributors',
topic_count_number: '<span class="tCountColor">' + this.get('topic_count') + '</span>',
topic_count_string: this.get('topic_count') === 1 ? ' topic' : ' topics',
synapse_count_number: '<span class="sCountColor">' + this.get('synapse_count') + '</span>',
synapse_count_string: this.get('synapse_count') === 1 ? ' synapse' : ' synapses',
screenshot: '<img src="' + this.get('screenshot_url') + '" />'
}
return obj
},
updateView: function () {
var map = Metamaps.Active.Map
var isActiveMap = this.id === map.id
if (isActiveMap) {
Metamaps.Map.InfoBox.updateNameDescPerm(this.get('name'), this.get('desc'), this.get('permission'))
this.updateMapWrapper()
}
},
updateMapWrapper: function () {
var map = Metamaps.Active.Map
var isActiveMap = this.id === map.id
var authorized = map && map.authorizeToEdit(Metamaps.Active.Mapper) ? 'canEditMap' : ''
var commonsMap = map && map.get('permission') === 'commons' ? 'commonsMap' : ''
if (isActiveMap) {
$('.wrapper').removeClass('canEditMap commonsMap').addClass(authorized + ' ' + commonsMap)
}
}
})
Metamaps.Backbone.MapsCollection = Backbone.Collection.extend({
model: Metamaps.Backbone.Map,
initialize: function(models, options) {
this.id = options.id;
this.sortBy = options.sortBy;
model: Metamaps.Backbone.Map,
initialize: function (models, options) {
this.id = options.id
this.sortBy = options.sortBy
if (options.mapperId) {
this.mapperId = options.mapperId;
}
// this.page represents the NEXT page to fetch
this.page = models.length > 0 ? (models.length < 20 ? "loadedAll" : 2) : 1;
},
url: function() {
if (!this.mapperId) {
return '/explore/' + this.id + '.json';
}
else {
return '/explore/mapper/' + this.mapperId + '.json';
}
},
comparator: function (a, b) {
a = a.get(this.sortBy);
b = b.get(this.sortBy);
var temp;
if (this.sortBy === 'name') {
a = a ? a.toLowerCase() : "";
b = b ? b.toLowerCase() : "";
}
else {
// this is for updated_at and created_at
temp = a;
a = b;
b = temp;
a = (new Date(a)).getTime();
b = (new Date(b)).getTime();
}
return a > b ? 1 : a < b ? -1 : 0;
},
getMaps: function (cb) {
var self = this;
Metamaps.Loading.show();
if (this.page != "loadedAll") {
var numBefore = this.length;
this.fetch({
remove: false,
silent: true,
data: { page: this.page },
success: function (collection, response, options) {
// you can pass additional options to the event you trigger here as well
if (collection.length - numBefore < 20) {
self.page = "loadedAll";
}
else self.page += 1;
self.trigger('successOnFetch', cb);
},
error: function (collection, response, options) {
// you can pass additional options to the event you trigger here as well
self.trigger('errorOnFetch');
}
});
}
else {
self.trigger('successOnFetch', cb);
}
if (options.mapperId) {
this.mapperId = options.mapperId
}
});
// this.page represents the NEXT page to fetch
this.page = models.length > 0 ? (models.length < 20 ? 'loadedAll' : 2) : 1
},
url: function () {
if (!this.mapperId) {
return '/explore/' + this.id + '.json'
} else {
return '/explore/mapper/' + this.mapperId + '.json'
}
},
comparator: function (a, b) {
a = a.get(this.sortBy)
b = b.get(this.sortBy)
var temp
if (this.sortBy === 'name') {
a = a ? a.toLowerCase() : ''
b = b ? b.toLowerCase() : ''
} else {
// this is for updated_at and created_at
temp = a
a = b
b = temp
a = (new Date(a)).getTime()
b = (new Date(b)).getTime()
}
return a > b ? 1 : a < b ? -1 : 0
},
getMaps: function (cb) {
var self = this
Metamaps.Loading.show()
if (this.page !== 'loadedAll') {
var numBefore = this.length
this.fetch({
remove: false,
silent: true,
data: { page: this.page },
success: function (collection, response, options) {
// you can pass additional options to the event you trigger here as well
if (collection.length - numBefore < 20) {
self.page = 'loadedAll'
} else {
self.page += 1
}
self.trigger('successOnFetch', cb)
},
error: function (collection, response, options) {
// you can pass additional options to the event you trigger here as well
self.trigger('errorOnFetch')
}
})
} else {
self.trigger('successOnFetch', cb)
}
}
})
Metamaps.Backbone.Message = Backbone.Model.extend({
urlRoot: '/messages',
blacklist: ['created_at', 'updated_at'],
toJSON: function (options) {
return _.omit(this.attributes, this.blacklist);
},
prepareLiForFilter: function () {
/*var li = '';
li += '<li 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;*/
}
});
urlRoot: '/messages',
blacklist: ['created_at', 'updated_at'],
toJSON: function (options) {
return _.omit(this.attributes, this.blacklist)
},
prepareLiForFilter: function () {
/* var li = ''
* li += '<li 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
*/
}
})
Metamaps.Backbone.MessageCollection = Backbone.Collection.extend({
model: Metamaps.Backbone.Message,
url: '/messages'
});
model: Metamaps.Backbone.Message,
url: '/messages'
})
Metamaps.Backbone.Mapper = Backbone.Model.extend({
urlRoot: '/users',
blacklist: ['created_at', 'updated_at'],
toJSON: function (options) {
return _.omit(this.attributes, this.blacklist);
},
prepareLiForFilter: function () {
var li = '';
li += '<li 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;
}
});
urlRoot: '/users',
blacklist: ['created_at', 'updated_at'],
toJSON: function (options) {
return _.omit(this.attributes, this.blacklist)
},
prepareLiForFilter: function () {
var li = ''
li += '<li 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
}
})
Metamaps.Backbone.MapperCollection = Backbone.Collection.extend({
model: Metamaps.Backbone.Mapper,
url: '/users'
});
model: Metamaps.Backbone.Mapper,
url: '/users'
})

View file

@ -1,3 +1,9 @@
/*
* Metamaps.Debug.js.erb
*
* Dependencies: none!
*/
Metamaps.Debug = function() {
console.debug(Metamaps)
console.debug(`Metamaps Version: ${Metamaps.VERSION}`)

View file

@ -1,25 +1,17 @@
/* global Metamaps, $ */
/*
* Example tab-separated input:
* Some fields will be ignored
*
* Topics
* Id Name Metacode X Y Description Link User Permission
* 8 topic8 Action -231 131 admin commons
* 5 topic Action -229 -131 admin commons
* 7 topic7.1 Action -470 -55 hey admin commons
* 2 topic2 Event -57 -63 admin commons
* 1 topic1 Catalyst -51 50 admin commons
* 6 topic6 Action -425 63 admin commons
*
* Synapses
* Topic1 Topic2 Category Description User Permission
* 6 2 from-to admin commons
* 6 1 from-to admin commons
* 6 5 from-to admin commons
* 2 7 from-to admin commons
* 8 6 from-to admin commons
* 8 1 from-to admin commons
* Metamaps.Import.js.erb
*
* Dependencies:
* - Metamaps.Active
* - Metamaps.Backbone
* - Metamaps.Famous // TODO remove dependency
* - Metamaps.Map
* - Metamaps.Mappings
* - Metamaps.Metacodes
* - Metamaps.Synapses
* - Metamaps.Topics
*/
Metamaps.Import = {
@ -30,61 +22,61 @@ Metamaps.Import = {
synapseWhitelist: [
'topic1', 'topic2', 'category', 'desc', 'description', 'permission'
],
cidMappings: {}, //to be filled by import_id => cid mappings
cidMappings: {}, // to be filled by import_id => cid mappings
init: function() {
var self = Metamaps.Import;
init: function () {
var self = Metamaps.Import
$('body').bind('paste', function(e) {
if (e.target.tagName === "INPUT") return;
$('body').bind('paste', function (e) {
if (e.target.tagName === 'INPUT') return
var text = e.originalEvent.clipboardData.getData('text/plain');
var text = e.originalEvent.clipboardData.getData('text/plain')
var results;
var results
if (text.trimLeft()[0] === '{') {
try {
results = JSON.parse(text);
results = JSON.parse(text)
} catch (e) {
results = false;
results = false
}
} else {
results = self.parseTabbedString(text);
results = self.parseTabbedString(text)
}
if (results === false) return;
if (results === false) return
var topics = results.topics;
var synapses = results.synapses;
var topics = results.topics
var synapses = results.synapses
if (topics.length > 0 || synapses.length > 0) {
if (confirm("Are you sure you want to create " + topics.length +
" new topics and " + synapses.length + " new synapses?")) {
self.importTopics(topics);
self.importSynapses(synapses);
}//if
}//if
});
if (window.confirm('Are you sure you want to create ' + topics.length +
' new topics and ' + synapses.length + ' new synapses?')) {
self.importTopics(topics)
self.importSynapses(synapses)
} // if
} // if
})
},
abort: function(message) {
console.error(message);
abort: function (message) {
console.error(message)
},
simplify: function(string) {
return string
simplify: function (string) {
return string
.replace(/(^\s*|\s*$)/g, '')
.toLowerCase();
},
.toLowerCase()
},
parseTabbedString: function(text) {
var self = Metamaps.Import;
parseTabbedString: function (text) {
var self = Metamaps.Import
// determine line ending and split lines
var delim = "\n";
if (text.indexOf("\r\n") !== -1) {
delim = "\r\n";
} else if (text.indexOf("\r") !== -1) {
delim = "\r";
}//if
var delim = '\n'
if (text.indexOf('\r\n') !== -1) {
delim = '\r\n'
} else if (text.indexOf('\r') !== -1) {
delim = '\r'
} // if
var STATES = {
ABORT: -1,
@ -92,226 +84,223 @@ Metamaps.Import = {
TOPICS_NEED_HEADERS: 1,
SYNAPSES_NEED_HEADERS: 2,
TOPICS: 3,
SYNAPSES: 4,
};
SYNAPSES: 4
}
// state & lines determine parser behaviour
var state = STATES.UNKNOWN;
var lines = text.split(delim);
var state = STATES.UNKNOWN
var lines = text.split(delim)
var results = { topics: [], synapses: [] }
var topicHeaders = [];
var synapseHeaders = [];
var topicHeaders = []
var synapseHeaders = []
lines.forEach(function(line_raw, index) {
var line = line_raw.split("\t");
var noblanks = line.filter(function(elt) {
return elt !== "";
});
switch(state) {
lines.forEach(function (line_raw, index) {
var line = line_raw.split('\t')
var noblanks = line.filter(function (elt) {
return elt !== ''
})
switch (state) {
case STATES.UNKNOWN:
if (noblanks.length === 0) {
state = STATES.UNKNOWN;
break;
state = STATES.UNKNOWN
break
} else if (noblanks.length === 1 && self.simplify(line[0]) === 'topics') {
state = STATES.TOPICS_NEED_HEADERS;
break;
state = STATES.TOPICS_NEED_HEADERS
break
} else if (noblanks.length === 1 && self.simplify(line[0]) === 'synapses') {
state = STATES.SYNAPSES_NEED_HEADERS;
break;
state = STATES.SYNAPSES_NEED_HEADERS
break
}
state = STATES.TOPICS_NEED_HEADERS;
state = STATES.TOPICS_NEED_HEADERS
// FALL THROUGH - if we're not sure what to do, pretend
// we're on the TOPICS_NEED_HEADERS state and parse some headers
case STATES.TOPICS_NEED_HEADERS:
case STATES.TOPICS_NEED_HEADERS: // eslint-disable-line
if (noblanks.length < 2) {
self.abort("Not enough topic headers on line " + index);
state = STATES.ABORT;
self.abort('Not enough topic headers on line ' + index)
state = STATES.ABORT
}
topicHeaders = line.map(function(header, index) {
return header.toLowerCase().replace('description', 'desc');
});
state = STATES.TOPICS;
break;
topicHeaders = line.map(function (header, index) {
return header.toLowerCase().replace('description', 'desc')
})
state = STATES.TOPICS
break
case STATES.SYNAPSES_NEED_HEADERS:
if (noblanks.length < 2) {
self.abort("Not enough synapse headers on line " + index);
state = STATES.ABORT;
self.abort('Not enough synapse headers on line ' + index)
state = STATES.ABORT
}
synapseHeaders = line.map(function(header, index) {
return header.toLowerCase().replace('description', 'desc');
});
state = STATES.SYNAPSES;
break;
synapseHeaders = line.map(function (header, index) {
return header.toLowerCase().replace('description', 'desc')
})
state = STATES.SYNAPSES
break
case STATES.TOPICS:
if (noblanks.length === 0) {
state = STATES.UNKNOWN;
state = STATES.UNKNOWN
} else if (noblanks.length === 1 && line[0].toLowerCase() === 'topics') {
state = STATES.TOPICS_NEED_HEADERS;
state = STATES.TOPICS_NEED_HEADERS
} else if (noblanks.length === 1 && line[0].toLowerCase() === 'synapses') {
state = STATES.SYNAPSES_NEED_HEADERS;
state = STATES.SYNAPSES_NEED_HEADERS
} else {
var topic = {};
line.forEach(function(field, index) {
var header = topicHeaders[index];
if (self.topicWhitelist.indexOf(header) === -1) return;
topic[header] = field;
var topic = {}
line.forEach(function (field, index) {
var header = topicHeaders[index]
if (self.topicWhitelist.indexOf(header) === -1) return
topic[header] = field
if (['id', 'x', 'y'].indexOf(header) !== -1) {
topic[header] = parseInt(topic[header]);
}//if
});
results.topics.push(topic);
topic[header] = parseInt(topic[header])
} // if
})
results.topics.push(topic)
}
break;
break
case STATES.SYNAPSES:
if (noblanks.length === 0) {
state = STATES.UNKNOWN;
state = STATES.UNKNOWN
} else if (noblanks.length === 1 && line[0].toLowerCase() === 'topics') {
state = STATES.TOPICS_NEED_HEADERS;
state = STATES.TOPICS_NEED_HEADERS
} else if (noblanks.length === 1 && line[0].toLowerCase() === 'synapses') {
state = STATES.SYNAPSES_NEED_HEADERS;
state = STATES.SYNAPSES_NEED_HEADERS
} else {
var synapse = {};
line.forEach(function(field, index) {
var header = synapseHeaders[index];
if (self.synapseWhitelist.indexOf(header) === -1) return;
synapse[header] = field;
var synapse = {}
line.forEach(function (field, index) {
var header = synapseHeaders[index]
if (self.synapseWhitelist.indexOf(header) === -1) return
synapse[header] = field
if (['id', 'topic1', 'topic2'].indexOf(header) !== -1) {
synapse[header] = parseInt(synapse[header]);
}//if
});
results.synapses.push(synapse);
synapse[header] = parseInt(synapse[header])
} // if
})
results.synapses.push(synapse)
}
break;
break
case STATES.ABORT:
;
default:
self.abort("Invalid state while parsing import data. Check code.");
state = STATES.ABORT;
self.abort('Invalid state while parsing import data. Check code.')
state = STATES.ABORT
}
});
})
if (state === STATES.ABORT) {
return false;
return false
} else {
return results;
return results
}
},
importTopics: function(parsedTopics) {
var self = Metamaps.Import;
importTopics: function (parsedTopics) {
var self = Metamaps.Import
// up to 25 topics: scale 100
// up to 81 topics: scale 200
// up to 169 topics: scale 300
var scale = Math.floor((Math.sqrt(parsedTopics.length) - 1) / 4) * 100;
if (scale < 100) scale = 100;
var autoX = -scale;
var autoY = -scale;
var scale = Math.floor((Math.sqrt(parsedTopics.length) - 1) / 4) * 100
if (scale < 100) scale = 100
var autoX = -scale
var autoY = -scale
parsedTopics.forEach(function(topic) {
var x, y;
parsedTopics.forEach(function (topic) {
var x, y
if (topic.x && topic.y) {
x = topic.x;
y = topic.y;
x = topic.x
y = topic.y
} else {
x = autoX;
y = autoY;
autoX += 50;
x = autoX
y = autoY
autoX += 50
if (autoX > scale) {
autoY += 50;
autoX = -scale;
autoY += 50
autoX = -scale
}
}
self.createTopicWithParameters(
topic.name, topic.metacode, topic.permission,
topic.desc, topic.link, x, y, topic.id
);
});
)
})
},
importSynapses: function(parsedSynapses) {
var self = Metamaps.Import;
importSynapses: function (parsedSynapses) {
var self = Metamaps.Import
parsedSynapses.forEach(function(synapse) {
//only createSynapseWithParameters once both topics are persisted
var topic1 = Metamaps.Topics.get(self.cidMappings[synapse.topic1]);
var topic2 = Metamaps.Topics.get(self.cidMappings[synapse.topic2]);
// only createSynapseWithParameters once both topics are persisted
var topic1 = Metamaps.Topics.get(self.cidMappings[synapse.topic1])
var topic2 = Metamaps.Topics.get(self.cidMappings[synapse.topic2])
if (!topic1 || !topic2) {
console.error("One of the two topics doesn't exist!")
console.error(synapse)
return true;
return true
}
var synapse_created = false
topic1.once('sync', function() {
topic1.once('sync', function () {
if (topic1.id && topic2.id && !synapse_created) {
synapse_created = true
self.createSynapseWithParameters(
synapse.desc, synapse.category, synapse.permission,
topic1, topic2
);
}//if
});
topic2.once('sync', function() {
)
} // if
})
topic2.once('sync', function () {
if (topic1.id && topic2.id && !synapse_created) {
synapse_created = true
self.createSynapseWithParameters(
synapse.desc, synapse.category, synapse.permission,
topic1, topic2
);
}//if
});
});
)
} // if
})
})
},
createTopicWithParameters: function(name, metacode_name, permission, desc,
link, xloc, yloc, import_id) {
var self = Metamaps.Import;
$(document).trigger(Metamaps.Map.events.editedByActiveMapper);
var metacode = Metamaps.Metacodes.where({name: metacode_name})[0] || null;
if (metacode === null) return console.error("metacode not found");
createTopicWithParameters: function (name, metacode_name, permission, desc,
link, xloc, yloc, import_id) {
var self = Metamaps.Import
$(document).trigger(Metamaps.Map.events.editedByActiveMapper)
var metacode = Metamaps.Metacodes.where({name: metacode_name})[0] || null
if (metacode === null) return console.error('metacode not found')
var topic = new Metamaps.Backbone.Topic({
name: name,
metacode_id: metacode.id,
permission: permission || Metamaps.Active.Map.get('permission'),
desc: desc,
link: link,
});
Metamaps.Topics.add(topic);
self.cidMappings[import_id] = topic.cid;
link: link
})
Metamaps.Topics.add(topic)
self.cidMappings[import_id] = topic.cid
var mapping = new Metamaps.Backbone.Mapping({
xloc: xloc,
yloc: yloc,
mappable_id: topic.cid,
mappable_type: "Topic",
});
Metamaps.Mappings.add(mapping);
xloc: xloc,
yloc: yloc,
mappable_id: topic.cid,
mappable_type: 'Topic'
})
Metamaps.Mappings.add(mapping)
// this function also includes the creation of the topic in the database
Metamaps.Topic.renderTopic(mapping, topic, true, true);
Metamaps.Topic.renderTopic(mapping, topic, true, true)
Metamaps.Famous.viz.hideInstructions();
Metamaps.Famous.viz.hideInstructions()
},
createSynapseWithParameters: function(description, category, permission,
topic1, topic2) {
var self = Metamaps.Import;
var node1 = topic1.get('node');
var node2 = topic2.get('node');
createSynapseWithParameters: function (description, category, permission,
topic1, topic2) {
var node1 = topic1.get('node')
var node2 = topic2.get('node')
if (!topic1.id || !topic2.id) {
console.error("missing topic id when creating synapse")
return;
}//if
console.error('missing topic id when creating synapse')
return
} // if
var synapse = new Metamaps.Backbone.Synapse({
desc: description,
@ -319,15 +308,15 @@ Metamaps.Import = {
permission: permission,
node1_id: topic1.id,
node2_id: topic2.id
});
Metamaps.Synapses.add(synapse);
})
Metamaps.Synapses.add(synapse)
var mapping = new Metamaps.Backbone.Mapping({
mappable_type: "Synapse",
mappable_id: synapse.cid,
});
Metamaps.Mappings.add(mapping);
mappable_type: 'Synapse',
mappable_id: synapse.cid
})
Metamaps.Mappings.add(mapping)
Metamaps.Synapse.renderSynapse(mapping, synapse, node1, node2, true);
},
};
Metamaps.Synapse.renderSynapse(mapping, synapse, node1, node2, true)
}
}

View file

@ -1,262 +1,270 @@
(function () {
/* global Metamaps, Backbone, $ */
Metamaps.currentPage = "";
/*
* Metamaps.Router.js.erb
*
* Dependencies:
* - Metamaps.Active
* - Metamaps.Famous
* - Metamaps.GlobalUI
* - Metamaps.JIT
* - Metamaps.Loading
* - Metamaps.Map
* - Metamaps.Maps
* - Metamaps.Topic
* - Metamaps.Views
* - Metamaps.Visualize
*/
var Router = Backbone.Router.extend({
routes: {
"": "home", // #home
"explore/:section": "explore", // #explore/active
"explore/:section/:id": "explore", // #explore/mapper/1234
"maps/:id": "maps" // #maps/7
},
home: function () {
clearTimeout(Metamaps.routerTimeoutId);
;(function () {
var Router = Backbone.Router.extend({
routes: {
'': 'home', // #home
'explore/:section': 'explore', // #explore/active
'explore/:section/:id': 'explore', // #explore/mapper/1234
'maps/:id': 'maps' // #maps/7
},
home: function () {
clearTimeout(Metamaps.Router.timeoutId)
if (Metamaps.Active.Mapper) document.title = 'Explore Active Maps | Metamaps';
else document.title = 'Home | Metamaps';
if (Metamaps.Active.Mapper) document.title = 'Explore Active Maps | Metamaps'
else document.title = 'Home | Metamaps'
Metamaps.currentSection = "";
Metamaps.currentPage = "";
$('.wrapper').removeClass('mapPage topicPage');
Metamaps.Router.currentSection = ''
Metamaps.Router.currentPage = ''
$('.wrapper').removeClass('mapPage topicPage')
var classes = Metamaps.Active.Mapper ? "homePage explorePage" : "homePage";
$('.wrapper').addClass(classes);
var classes = Metamaps.Active.Mapper ? 'homePage explorePage' : 'homePage'
$('.wrapper').addClass(classes)
var navigate = function() {
Metamaps.routerTimeoutId = setTimeout(function() {
Metamaps.Router.navigate("");
}, 300);
};
// all this only for the logged in home page
if (Metamaps.Active.Mapper) {
Metamaps.Famous.yield.hide();
Metamaps.Famous.explore.set('active');
Metamaps.Famous.maps.resetScroll(); // sets the scroll back to the top
Metamaps.Famous.explore.show();
var navigate = function () {
Metamaps.Router.timeoutId = setTimeout(function () {
Metamaps.Router.navigate('')
}, 300)
}
// all this only for the logged in home page
if (Metamaps.Active.Mapper) {
Metamaps.Famous.yield.hide()
Metamaps.Famous.maps.show();
Metamaps.Famous.explore.set('active')
Metamaps.Famous.maps.resetScroll() // sets the scroll back to the top
Metamaps.Famous.explore.show()
Metamaps.GlobalUI.Search.open();
Metamaps.GlobalUI.Search.lock();
Metamaps.Famous.maps.show()
Metamaps.Views.exploreMaps.setCollection( Metamaps.Maps.Active );
if (Metamaps.Maps.Active.length === 0) {
Metamaps.Maps.Active.getMaps(navigate); // this will trigger an explore maps render
}
else {
Metamaps.Views.exploreMaps.render(navigate);
}
}
// logged out home page
else {
Metamaps.Famous.yield.show();
Metamaps.Famous.explore.hide();
Metamaps.GlobalUI.Search.open()
Metamaps.GlobalUI.Search.lock()
Metamaps.GlobalUI.Search.unlock();
Metamaps.GlobalUI.Search.close(0, true);
Metamaps.Famous.maps.hide();
Metamaps.routerTimeoutId = setTimeout(navigate, 500);
}
Metamaps.Famous.viz.hide();
Metamaps.Map.end();
Metamaps.Topic.end();
Metamaps.Active.Map = null;
Metamaps.Active.Topic = null;
},
explore: function (section, id) {
clearTimeout(Metamaps.routerTimeoutId);
// just capitalize the variable section
// either 'featured', 'mapper', or 'active'
var capitalize = section.charAt(0).toUpperCase() + section.slice(1);
if (section === "featured" || section === "active") {
document.title = 'Explore ' + capitalize + ' Maps | Metamaps';
}
else if (section === "mapper") {
$.ajax({
url: "/users/" + id + ".json",
success: function (response) {
document.title = response.name + ' | Metamaps';
},
error: function () {
}
});
}
else if (section === "mine") {
document.title = 'Explore My Maps | Metamaps';
}
$('.wrapper').removeClass('homePage mapPage topicPage');
$('.wrapper').addClass('explorePage');
Metamaps.currentSection = "explore";
Metamaps.currentPage = section;
// this will mean it's a mapper page being loaded
if (id) {
if (Metamaps.Maps.Mapper.mapperId !== id) {
// empty the collection if we are trying to load the maps
// collection of a different mapper than we had previously
Metamaps.Maps.Mapper.reset();
Metamaps.Maps.Mapper.page = 1;
}
Metamaps.Maps.Mapper.mapperId = id;
}
Metamaps.Views.exploreMaps.setCollection( Metamaps.Maps[capitalize] );
var navigate = function(){
var path = "/explore/" + Metamaps.currentPage;
// alter url if for mapper profile page
if (Metamaps.currentPage == "mapper") {
path += "/" + Metamaps.Maps.Mapper.mapperId;
}
Metamaps.Router.navigate(path);
};
var navigateTimeout = function() {
Metamaps.routerTimeoutId = setTimeout(navigate, 300);
};
if (Metamaps.Maps[capitalize].length === 0) {
Metamaps.Loading.show();
setTimeout(function(){
Metamaps.Maps[capitalize].getMaps(navigate); // this will trigger an explore maps render
}, 300); // wait 300 milliseconds till the other animations are done to do the fetch
}
else {
if (id) {
Metamaps.Views.exploreMaps.fetchUserThenRender(navigateTimeout);
}
else {
Metamaps.Views.exploreMaps.render(navigateTimeout);
}
}
Metamaps.GlobalUI.Search.open();
Metamaps.GlobalUI.Search.lock();
Metamaps.Famous.yield.hide();
Metamaps.Famous.maps.resetScroll(); // sets the scroll back to the top
Metamaps.Famous.maps.show();
Metamaps.Famous.explore.set(section, id);
Metamaps.Famous.explore.show();
Metamaps.Famous.viz.hide();
Metamaps.Map.end();
Metamaps.Topic.end();
Metamaps.Active.Map = null;
Metamaps.Active.Topic = null;
},
maps: function (id) {
clearTimeout(Metamaps.routerTimeoutId);
document.title = 'Map ' + id + ' | Metamaps';
Metamaps.currentSection = "map";
Metamaps.currentPage = id;
$('.wrapper').removeClass('homePage explorePage topicPage');
$('.wrapper').addClass('mapPage');
// another class will be added to wrapper if you
// can edit this map '.canEditMap'
Metamaps.Famous.yield.hide();
Metamaps.Famous.maps.hide();
Metamaps.Famous.explore.hide();
// clear the visualization, if there was one, before showing its div again
if (Metamaps.Visualize.mGraph) {
Metamaps.Visualize.mGraph.graph.empty();
Metamaps.Visualize.mGraph.plot();
Metamaps.JIT.centerMap(Metamaps.Visualize.mGraph.canvas);
}
Metamaps.Famous.viz.show();
Metamaps.Topic.end();
Metamaps.Active.Topic = null;
Metamaps.GlobalUI.Search.unlock();
Metamaps.GlobalUI.Search.close(0, true);
Metamaps.Loading.show();
Metamaps.Map.end();
Metamaps.Map.launch(id);
},
topics: function (id) {
clearTimeout(Metamaps.routerTimeoutId);
document.title = 'Topic ' + id + ' | Metamaps';
Metamaps.currentSection = "topic";
Metamaps.currentPage = id;
$('.wrapper').removeClass('homePage explorePage mapPage');
$('.wrapper').addClass('topicPage');
Metamaps.Famous.yield.hide();
Metamaps.Famous.maps.hide();
Metamaps.Famous.explore.hide();
// clear the visualization, if there was one, before showing its div again
if (Metamaps.Visualize.mGraph) {
Metamaps.Visualize.mGraph.graph.empty();
Metamaps.Visualize.mGraph.plot();
Metamaps.JIT.centerMap(Metamaps.Visualize.mGraph.canvas);
}
Metamaps.Famous.viz.show();
Metamaps.Map.end();
Metamaps.Active.Map = null;
Metamaps.GlobalUI.Search.unlock();
Metamaps.GlobalUI.Search.close(0, true);
Metamaps.Topic.end();
Metamaps.Topic.launch(id);
Metamaps.Views.exploreMaps.setCollection(Metamaps.Maps.Active)
if (Metamaps.Maps.Active.length === 0) {
Metamaps.Maps.Active.getMaps(navigate) // this will trigger an explore maps render
} else {
Metamaps.Views.exploreMaps.render(navigate)
}
});
Metamaps.Router = new Router();
} else {
// logged out home page
Metamaps.Famous.yield.show()
Metamaps.Famous.explore.hide()
Metamaps.Router.intercept = function (evt) {
var segments;
Metamaps.GlobalUI.Search.unlock()
Metamaps.GlobalUI.Search.close(0, true)
var href = {
prop: $(this).prop("href"),
attr: $(this).attr("href")
};
var root = location.protocol + "//" + location.host + Backbone.history.options.root;
if (href.prop && href.prop === root) href.attr = "";
if (href.prop && href.prop.slice(0, root.length) === root) {
evt.preventDefault();
Metamaps.Famous.maps.hide()
Metamaps.Router.timeoutId = setTimeout(navigate, 500)
}
segments = href.attr.split('/');
segments.splice(0,1); // pop off the element created by the first /
Metamaps.Famous.viz.hide()
Metamaps.Map.end()
Metamaps.Topic.end()
Metamaps.Active.Map = null
Metamaps.Active.Topic = null
},
explore: function (section, id) {
clearTimeout(Metamaps.Router.timeoutId)
if (href.attr === "") Metamaps.Router.home();
else {
Metamaps.Router[segments[0]](segments[1], segments[2]);
}
// just capitalize the variable section
// either 'featured', 'mapper', or 'active'
var capitalize = section.charAt(0).toUpperCase() + section.slice(1)
if (section === 'featured' || section === 'active') {
document.title = 'Explore ' + capitalize + ' Maps | Metamaps'
} else if (section === 'mapper') {
$.ajax({
url: '/users/' + id + '.json',
success: function (response) {
document.title = response.name + ' | Metamaps'
},
error: function () {}
})
} else if (section === 'mine') {
document.title = 'Explore My Maps | Metamaps'
}
$('.wrapper').removeClass('homePage mapPage topicPage')
$('.wrapper').addClass('explorePage')
Metamaps.Router.currentSection = 'explore'
Metamaps.Router.currentPage = section
// this will mean it's a mapper page being loaded
if (id) {
if (Metamaps.Maps.Mapper.mapperId !== id) {
// empty the collection if we are trying to load the maps
// collection of a different mapper than we had previously
Metamaps.Maps.Mapper.reset()
Metamaps.Maps.Mapper.page = 1
}
};
Metamaps.Maps.Mapper.mapperId = id
}
Metamaps.Router.init = function () {
Backbone.history.start({
silent: true,
pushState: true,
root: '/'
});
$(document).on("click", "a:not([data-bypass])", Metamaps.Router.intercept);
};
})();
Metamaps.Views.exploreMaps.setCollection(Metamaps.Maps[capitalize])
var navigate = function () {
var path = '/explore/' + Metamaps.Router.currentPage
// alter url if for mapper profile page
if (Metamaps.Router.currentPage === 'mapper') {
path += '/' + Metamaps.Maps.Mapper.mapperId
}
Metamaps.Router.navigate(path)
}
var navigateTimeout = function () {
Metamaps.Router.timeoutId = setTimeout(navigate, 300)
}
if (Metamaps.Maps[capitalize].length === 0) {
Metamaps.Loading.show()
setTimeout(function () {
Metamaps.Maps[capitalize].getMaps(navigate) // this will trigger an explore maps render
}, 300) // wait 300 milliseconds till the other animations are done to do the fetch
} else {
if (id) {
Metamaps.Views.exploreMaps.fetchUserThenRender(navigateTimeout)
} else {
Metamaps.Views.exploreMaps.render(navigateTimeout)
}
}
Metamaps.GlobalUI.Search.open()
Metamaps.GlobalUI.Search.lock()
Metamaps.Famous.yield.hide()
Metamaps.Famous.maps.resetScroll() // sets the scroll back to the top
Metamaps.Famous.maps.show()
Metamaps.Famous.explore.set(section, id)
Metamaps.Famous.explore.show()
Metamaps.Famous.viz.hide()
Metamaps.Map.end()
Metamaps.Topic.end()
Metamaps.Active.Map = null
Metamaps.Active.Topic = null
},
maps: function (id) {
clearTimeout(Metamaps.Router.timeoutId)
document.title = 'Map ' + id + ' | Metamaps'
Metamaps.Router.currentSection = 'map'
Metamaps.Router.currentPage = id
$('.wrapper').removeClass('homePage explorePage topicPage')
$('.wrapper').addClass('mapPage')
// another class will be added to wrapper if you
// can edit this map '.canEditMap'
Metamaps.Famous.yield.hide()
Metamaps.Famous.maps.hide()
Metamaps.Famous.explore.hide()
// clear the visualization, if there was one, before showing its div again
if (Metamaps.Visualize.mGraph) {
Metamaps.Visualize.mGraph.graph.empty()
Metamaps.Visualize.mGraph.plot()
Metamaps.JIT.centerMap(Metamaps.Visualize.mGraph.canvas)
}
Metamaps.Famous.viz.show()
Metamaps.Topic.end()
Metamaps.Active.Topic = null
Metamaps.GlobalUI.Search.unlock()
Metamaps.GlobalUI.Search.close(0, true)
Metamaps.Loading.show()
Metamaps.Map.end()
Metamaps.Map.launch(id)
},
topics: function (id) {
clearTimeout(Metamaps.Router.timeoutId)
document.title = 'Topic ' + id + ' | Metamaps'
Metamaps.Router.currentSection = 'topic'
Metamaps.Router.currentPage = id
$('.wrapper').removeClass('homePage explorePage mapPage')
$('.wrapper').addClass('topicPage')
Metamaps.Famous.yield.hide()
Metamaps.Famous.maps.hide()
Metamaps.Famous.explore.hide()
// clear the visualization, if there was one, before showing its div again
if (Metamaps.Visualize.mGraph) {
Metamaps.Visualize.mGraph.graph.empty()
Metamaps.Visualize.mGraph.plot()
Metamaps.JIT.centerMap(Metamaps.Visualize.mGraph.canvas)
}
Metamaps.Famous.viz.show()
Metamaps.Map.end()
Metamaps.Active.Map = null
Metamaps.GlobalUI.Search.unlock()
Metamaps.GlobalUI.Search.close(0, true)
Metamaps.Topic.end()
Metamaps.Topic.launch(id)
}
})
Metamaps.Router = new Router()
Metamaps.Router.currentPage = ''
Metamaps.Router.currentSection = undefined
Metamaps.Router.timeoutId = undefined
Metamaps.Router.intercept = function (evt) {
var segments
var href = {
prop: $(this).prop('href'),
attr: $(this).attr('href')
}
var root = window.location.protocol + '//' + window.location.host + Backbone.history.options.root
if (href.prop && href.prop === root) href.attr = ''
if (href.prop && href.prop.slice(0, root.length) === root) {
evt.preventDefault()
segments = href.attr.split('/')
segments.splice(0, 1) // pop off the element created by the first /
if (href.attr === '') {
Metamaps.Router.home()
} else {
Metamaps.Router[segments[0]](segments[1], segments[2])
}
}
}
Metamaps.Router.init = function () {
Backbone.history.start({
silent: true,
pushState: true,
root: '/'
})
$(document).on('click', 'a:not([data-bypass])', Metamaps.Router.intercept)
}
})()

View file

@ -1,133 +1,129 @@
(function () {
Metamaps.Views = {};
/* global Metamaps, $, Hogan, Backbone */
/*
* Metamaps.Views.js.erb
*
* Dependencies:
* - Metamaps.Famous
* - Metamaps.Loading
*/
Metamaps.Views = {
initialized: false
}
var initialized = false;
Metamaps.Views.init = function () {
Metamaps.Views.MapperCard = Backbone.View.extend({
template: Hogan.compile($('#mapperCardTemplate').html()),
Metamaps.Views.MapperCard = Backbone.View.extend({
tagNamea: 'div',
template: Hogan.compile( $('#mapperCardTemplate').html() ),
className: 'mapper',
tagNamea: "div",
render: function () {
this.$el.html(this.template.render(this.model))
return this
}
})
className: "mapper",
Metamaps.Views.MapCard = Backbone.View.extend({
template: Hogan.compile($('#mapCardTemplate').html()),
render: function () {
this.$el.html( this.template.render(this.model) );
return this;
tagName: 'div',
className: 'map',
id: function () {
return this.model.id
},
initialize: function () {
this.listenTo(this.model, 'change', this.render)
},
render: function () {
this.$el.html(this.template.render(this.model.attrForCards()))
return this
}
})
var MapsWrapper = Backbone.View.extend({
initialize: function (opts) {},
setCollection: function (collection) {
if (this.collection) this.stopListening(this.collection)
this.collection = collection
this.listenTo(this.collection, 'add', this.render)
this.listenTo(this.collection, 'successOnFetch', this.handleSuccess)
this.listenTo(this.collection, 'errorOnFetch', this.handleError)
},
render: function (mapperObj, cbArg) {
var that = this
if (typeof mapperObj === 'function') {
var cb = mapperObj
mapperObj = null
}
this.el.innerHTML = ''
// in case it is a page where we have to display the mapper card
if (mapperObj) {
var view = new Metamaps.Views.MapperCard({ model: mapperObj })
that.el.appendChild(view.render().el)
}
this.collection.each(function (map) {
var view = new Metamaps.Views.MapCard({ model: map })
that.el.appendChild(view.render().el)
})
this.$el.append('<div class="clearfloat"></div>')
var m = Metamaps.Famous.maps.surf
m.setContent(this.el)
var updateHeight = function () {
var height = $(that.el).height() + 32 + 56
m.setSize([undefined, height])
Metamaps.Famous.maps.lock = false
if (cb) cb()
}
if (!Metamaps.Views.initialized) {
m.deploy(m._currTarget)
Metamaps.Views.initialized = true
setTimeout(updateHeight, 100)
} else {
setTimeout(updateHeight, 100)
}
Metamaps.Loading.hide()
},
handleSuccess: function (cb) {
if (this.collection && this.collection.id === 'mapper') {
this.fetchUserThenRender(cb)
} else {
this.render(cb)
}
},
handleError: function () {
console.log('error loading maps!') // TODO
},
fetchUserThenRender: function (cb) {
var that = this
// first load the mapper object and then call the render function
$.ajax({
url: '/users/' + this.collection.mapperId + '/details.json',
success: function (response) {
that.render(response, cb)
},
error: function () {
that.render(cb)
}
});
})
}
})
Metamaps.Views.MapCard = Backbone.View.extend({
template: Hogan.compile( $('#mapCardTemplate').html() ),
tagName: "div",
className: "map",
id: function() {
return this.model.id;
},
initialize: function () {
this.listenTo(this.model, "change", this.render);
},
render: function () {
this.$el.html( this.template.render(this.model.attrForCards()) );
return this;
}
});
var mapsWrapper = Backbone.View.extend({
initialize: function (opts) {
},
setCollection: function (collection) {
if (this.collection) this.stopListening(this.collection);
this.collection = collection;
this.listenTo(this.collection, 'add', this.render);
this.listenTo(this.collection, 'successOnFetch', this.handleSuccess);
this.listenTo(this.collection, 'errorOnFetch', this.handleError);
},
render: function (mapperObj, cb) {
var that = this;
if (typeof mapperObj === "function") {
var cb = mapperObj;
mapperObj = null;
}
this.el.innerHTML = "";
// in case it is a page where we have to display the mapper card
if (mapperObj) {
var view = new Metamaps.Views.MapperCard({ model: mapperObj });
that.el.appendChild( view.render().el );
}
this.collection.each(function (map) {
var view = new Metamaps.Views.MapCard({ model: map });
that.el.appendChild( view.render().el );
});
this.$el.append('<div class="clearfloat"></div>');
var m = Metamaps.Famous.maps.surf;
m.setContent(this.el);
var updateHeight = function(){
var height = $(that.el).height() + 32 + 56;
m.setSize([undefined, height]);
Metamaps.Famous.maps.lock = false;
if (cb) cb();
};
if (!initialized) {
m.deploy(m._currTarget);
initialized = true;
setTimeout(updateHeight, 100);
} else {
setTimeout(updateHeight, 100);
}
Metamaps.Loading.hide();
},
handleSuccess: function (cb) {
var that = this;
if (this.collection && this.collection.id === "mapper") {
this.fetchUserThenRender(cb);
}
else {
this.render(cb);
}
},
handleError: function () {
console.log('error loading maps!'); //TODO
},
fetchUserThenRender: function (cb) {
var that = this;
// first load the mapper object and then call the render function
$.ajax({
url: "/users/" + this.collection.mapperId + "/details.json",
success: function (response) {
that.render(response, cb);
},
error: function () {
that.render(cb);
}
});
}
});
Metamaps.Views.exploreMaps = new mapsWrapper();
};
})();
Metamaps.Views.exploreMaps = new MapsWrapper()
}

View file

@ -1772,8 +1772,8 @@ Metamaps.Visualize = {
hold();
// update the url now that the map is ready
clearTimeout(Metamaps.routerTimeoutId);
Metamaps.routerTimeoutId = setTimeout(function(){
clearTimeout(Metamaps.Router.timeoutId);
Metamaps.Router.timeoutId = setTimeout(function(){
var m = Metamaps.Active.Map;
var t = Metamaps.Active.Topic;
@ -2270,6 +2270,7 @@ Metamaps.Realtime = {
invited: Metamaps.Active.Mapper.id,
inviter: userid
});
$.post('/maps/' + Metamaps.Active.Map.id + '/events/conversation');
self.joinCall();
Metamaps.GlobalUI.clearNotify();
},
@ -5516,57 +5517,3 @@ Metamaps.Mapper = {
});
}
}; // end Metamaps.Mapper
/*
*
* ADMIN
*
*/
Metamaps.Admin = {
selectMetacodes: [],
allMetacodes: [],
init: function () {
var self = Metamaps.Admin;
$('#metacodes_value').val(self.selectMetacodes.toString());
},
selectAll: function () {
var self = Metamaps.Admin;
$('.editMetacodes li').removeClass('toggledOff');
self.selectMetacodes = self.allMetacodes.slice(0);
$('#metacodes_value').val(self.selectMetacodes.toString());
},
deselectAll: function () {
var self = Metamaps.Admin;
$('.editMetacodes li').addClass('toggledOff');
self.selectMetacodes = [];
$('#metacodes_value').val(0);
},
liClickHandler: function () {
var self = Metamaps.Admin;
if ($(this).attr('class') != 'toggledOff') {
$(this).addClass('toggledOff');
var value_to_remove = $(this).attr('id');
self.selectMetacodes.splice(self.selectMetacodes.indexOf(value_to_remove), 1);
$('#metacodes_value').val(self.selectMetacodes.toString());
}
else if ($(this).attr('class') == 'toggledOff') {
$(this).removeClass('toggledOff');
self.selectMetacodes.push($(this).attr('id'));
$('#metacodes_value').val(self.selectMetacodes.toString());
}
},
validate: function () {
var self = Metamaps.Admin;
if (self.selectMetacodes.length == 0) {
alert('Would you pretty please select at least one metacode for the set?');
return false;
}
}
};

View file

@ -1,7 +1,7 @@
class MapsController < ApplicationController
before_action :require_user, only: [:create, :update, :screenshot, :destroy]
after_action :verify_authorized, except: [:activemaps, :featuredmaps, :mymaps, :usermaps]
before_action :require_user, only: [:create, :update, :screenshot, :events, :destroy]
after_action :verify_authorized, except: [:activemaps, :featuredmaps, :mymaps, :usermaps, :events]
after_action :verify_policy_scoped, only: [:activemaps, :featuredmaps, :mymaps, :usermaps]
respond_to :html, :json, :csv
@ -102,6 +102,24 @@ class MapsController < ApplicationController
end
end
# POST maps/:id/events/:event
def events
map = Map.find(params[:id])
authorize map
valid_event = false
if params[:event] == 'conversation'
Events::ConversationStartedOnMap.publish!(map, current_user)
valid_event = true
end
respond_to do |format|
format.json {
head :ok if valid_event
head :bad_request if not valid_event
}
end
end
# GET maps/:id/contains
def contains

View file

@ -1,5 +1,5 @@
class Event < ActiveRecord::Base
KINDS = %w[topic_added_to_map synapse_added_to_map]
KINDS = %w[conversation_started_on_map topic_added_to_map synapse_added_to_map]
#has_many :notifications, dependent: :destroy
belongs_to :eventable, polymorphic: true

View file

@ -0,0 +1,18 @@
class Events::ConversationStartedOnMap < Event
#after_create :notify_users!
def self.publish!(map, user)
create!(kind: "conversation_started_on_map",
eventable: map,
map: map,
user: user)
end
private
#def notify_users!
# unless comment_vote.user == comment_vote.comment_user
# notify!(comment_vote.comment_user)
# end
#end
end

View file

@ -37,7 +37,7 @@ Webhooks::Slack::Base = Struct.new(:event) do
#end
def view_map_on_metamaps(text = nil)
"<#{map_url(eventable.map)}|#{text || eventable.map.name}>"
"<#{map_url(event.map)}|#{text || event.map.name}>"
end
#def view_discussion_on_loomio(params = {})

View file

@ -0,0 +1,27 @@
class Webhooks::Slack::ConversationStartedOnMap < Webhooks::Slack::Base
def text
"There is a live conversation starting on map *#{event.map.name}*. #{view_map_on_metamaps('Join in!')}"
end
# todo: it would be sweet if it sends it with the metacode as the icon_url
def attachment_fallback
"" #{}"*#{eventable.name}*\n#{eventable.description}\n"
end
def attachment_title
"" #proposal_link(eventable)
end
def attachment_text
"" # "#{eventable.description}\n"
end
def attachment_fields
[{
title: "nothing",
value: "nothing"
}] #[motion_vote_field]
end
end

View file

@ -35,6 +35,10 @@ class MapPolicy < ApplicationPolicy
show?
end
def events?
show?
end
def contains?
show?
end

View file

@ -37,14 +37,15 @@ Metamaps::Application.routes.draw do
resources :maps, except: [:index, :new, :edit]
get 'maps/:id/export', to: 'maps#export'
post 'maps/:id/events/:event', to: 'maps#events'
get 'maps/:id/contains', to: 'maps#contains', as: :contains
post 'maps/:id/upload_screenshot', to: 'maps#screenshot', as: :screenshot
get 'explore/active', to: 'maps#activemaps'
get 'explore/featured', to: 'maps#featuredmaps'
get 'explore/mine', to: 'maps#mymaps'
get 'explore/mapper/:id', to: 'maps#usermaps'
get 'maps/:id/contains', to: 'maps#contains', as: :contains
post 'maps/:id/upload_screenshot', to: 'maps#screenshot', as: :screenshot
devise_for :users, controllers: { registrations: 'users/registrations', passwords: 'users/passwords', sessions: 'devise/sessions' }, :skip => :sessions