Merge branch 'master' into thevalueweb
This commit is contained in:
commit
96cee3cf21
27 changed files with 316 additions and 276 deletions
|
@ -1 +1 @@
|
|||
https://github.com/heroku/heroku-buildpack-ruby.git
|
||||
https://github.com/heroku/heroku-buildpack-ruby.git
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -19,3 +19,5 @@ log/*.log
|
|||
tmp
|
||||
|
||||
.DS_Store
|
||||
|
||||
.vagrant
|
||||
|
|
|
@ -49,7 +49,7 @@ Driessen][git-branching-model]. Here's an overview:
|
|||
changing all the time. It's important that any changes you make are based on
|
||||
the most recent version of metamaps, since it's possible that something may
|
||||
have changed that breaks your pull request or invalidates its need.
|
||||
4. Make sure you have a [Contributor License Agreement][cla] on file.
|
||||
4. Make sure you have a [Contributor License Agreement](http://caa.metamaps.cc) on file.
|
||||
5. Read on ...
|
||||
|
||||
|
||||
|
@ -59,7 +59,7 @@ Before we can accept any contributions to Metamaps, we first require that all
|
|||
individuals or companies agree to our Contributor License Agreement (CLA). The e-mail
|
||||
address used in the pull request will be used to check if a CLA has already been
|
||||
filed, so be sure to list all email addresses that you might use to submit your
|
||||
pull requests when filling it out. Our CLA can be found [here][cla].
|
||||
pull requests when filling it out. Our CLA can be found [here](http://caa.metamaps.cc).
|
||||
|
||||
### Testing and Linting
|
||||
|
||||
|
|
2
Procfile
2
Procfile
|
@ -1 +1 @@
|
|||
web: bundle exec rails server -p $PORT
|
||||
web: bundle exec rails server -p $PORT
|
||||
|
|
42
README.md
42
README.md
|
@ -1,6 +1,8 @@
|
|||
Metamaps
|
||||
=======
|
||||
|
||||
[![Join the chat at https://gitter.im/metamaps/metamaps_gen002](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/metamaps/metamaps_gen002?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
Welcome to the Metamaps GitHub repo.
|
||||
|
||||
## About
|
||||
|
@ -15,18 +17,40 @@ To get connected with the community interested in Metamaps, join our [Google+ co
|
|||
|
||||
## Installation
|
||||
|
||||
Depending on which OS you are using, the instructions for getting set up with a local installation of the Metamaps software will vary. Because the software has both Node.js components, and RubyOnRails, getting set up with your local copy can take 1 to 2 hours.
|
||||
If you are on Mac or Ubuntu you can use the following instructions to quickly get a local copy of metamaps up and running using a Vagrant virtualbox. Don't be intimidated, it's easy!
|
||||
```
|
||||
git clone git@github.com:metamaps/metamaps_gen002.git
|
||||
```
|
||||
Now ensure you have VirtualBox and Vagrant installed on your computer
|
||||
```
|
||||
cd metamaps_gen002
|
||||
./configure.sh
|
||||
```
|
||||
This will do all the setup steps to make Metamaps work with a bit of behind the scenes ninja magick.
|
||||
|
||||
To start servers which will run metamaps you can then run:
|
||||
```
|
||||
./bin/start
|
||||
```
|
||||
To stop them:
|
||||
```
|
||||
./bin/stop
|
||||
```
|
||||
With your webservers running, open a web browser and go to `http://localhost:3000`
|
||||
|
||||
You can sign in with the default account
|
||||
email: `user@user.com`
|
||||
password: `toolsplusconsciousness`
|
||||
OR create a new account at `/join`, and use access code `qwertyui`
|
||||
|
||||
Start mapping and programming!
|
||||
|
||||
While we are still figuring out vagrant for Windows, there is an older set of instructions below
|
||||
- [For Windows][windows-installation]
|
||||
- [For Ubuntu][ubuntu-installation]
|
||||
- [For Mac][mac-installation]
|
||||
|
||||
## Contributing
|
||||
|
||||
Cloning this repository directly is primarily for those wishing to contribute to our codebase. Check out our [contributing instructions][contributing] to get involved.
|
||||
|
||||
## Documentation
|
||||
|
||||
- TODO
|
||||
|
||||
## Community
|
||||
|
||||
|
@ -41,7 +65,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
The license can be read [here][license].
|
||||
|
||||
Copyright (c) 2014 Connor Turland
|
||||
Copyright (c) 2015 Connor Turland
|
||||
|
||||
|
||||
[site-blog]: http://blog.metamaps.cc
|
||||
|
@ -51,5 +75,3 @@ Copyright (c) 2014 Connor Turland
|
|||
[contributing]: https://github.com/metamaps/metamaps_gen002/blob/master/CONTRIBUTING.md
|
||||
[contributing-issues]: https://github.com/metamaps/metamaps_gen002/blob/master/CONTRIBUTING.md#reporting-bugs-and-other-issues
|
||||
[windows-installation]: https://github.com/metamaps/metamaps_gen002/blob/master/WindowsInstallation.md
|
||||
[mac-installation]: https://github.com/metamaps/metamaps_gen002/blob/master/MacInstallation.md
|
||||
[ubuntu-installation]: https://github.com/metamaps/metamaps_gen002/blob/master/UbuntuInstallation.md
|
||||
|
|
|
@ -40,29 +40,7 @@ alright now we can download metamaps from the master using git
|
|||
|
||||
git clone https://github.com/metamaps/metamaps_gen002.git
|
||||
|
||||
now there is a couple other things we are going to need which is phantomjs, nodejs, postgresql, libpq-dev and redis-server
|
||||
|
||||
|
||||
// 64 bit ubuntu
|
||||
cd /usr/local/share
|
||||
sudo wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.7-linux-x86_64.tar.bz2
|
||||
sudo tar xjf phantomjs-1.9.7-linux-x86_64.tar.bz2
|
||||
sudo ln -s /usr/local/share/phantomjs-1.9.7-linux-x86_64/bin/phantomjs /usr/local/share/phantomjs
|
||||
sudo ln -s /usr/local/share/phantomjs-1.9.7-linux-x86_64/bin/phantomjs /usr/local/bin/phantomjs
|
||||
sudo ln -s /usr/local/share/phantomjs-1.9.7-linux-x86_64/bin/phantomjs /usr/bin/phantomjs
|
||||
|
||||
|
||||
// 32 bit ubuntu
|
||||
cd /usr/local/share
|
||||
sudo wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.7-linux-i686.tar.bz2
|
||||
sudo tar xjf phantomjs-1.9.7-linux-i686.tar.bz2
|
||||
sudo ln -s /usr/local/share/phantomjs-1.9.7-linux-i686/bin/phantomjs /usr/local/share/phantomjs
|
||||
sudo ln -s /usr/local/share/phantomjs-1.9.7-linux-i686/bin/phantomjs /usr/local/bin/phantomjs
|
||||
sudo ln -s /usr/local/share/phantomjs-1.9.7-linux-i686/bin/phantomjs /usr/bin/phantomjs
|
||||
|
||||
// on either running
|
||||
phantomjs -v
|
||||
// will confirm it's installed
|
||||
now there is a couple other things we are going to need which is nodejs, postgresql, libpq-dev and redis-server
|
||||
|
||||
sudo apt-get install nodejs
|
||||
|
||||
|
@ -113,7 +91,7 @@ Execute the server:
|
|||
|
||||
rails s
|
||||
|
||||
and dont forget to run the two other servers, for sidekiq, and realtime...
|
||||
and dont forget to run the other server for realtime...
|
||||
open a new terminal
|
||||
navigate to ./realtime and run
|
||||
|
||||
|
@ -121,11 +99,6 @@ navigate to ./realtime and run
|
|||
npm install
|
||||
nodejs realtime-server.js
|
||||
|
||||
open a new terminal
|
||||
navigate to the main directory and run
|
||||
|
||||
sidekiq
|
||||
|
||||
Now you're all set enjoy your personal server of metamaps :)
|
||||
|
||||
Navigate your browser to localhost:3000 once you have the server running
|
||||
|
|
43
Vagrantfile
vendored
Normal file
43
Vagrantfile
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
$script = <<SCRIPT
|
||||
|
||||
# install base req's
|
||||
sudo apt-get update
|
||||
sudo apt-get install git curl -y
|
||||
|
||||
# rvm and ruby
|
||||
su - vagrant -c 'curl -sSL https://rvm.io/mpapis.asc | gpg --import -'
|
||||
su - vagrant -c 'curl -sSL https://get.rvm.io | bash -s stable --ruby=2.1.3'
|
||||
|
||||
# install some other deps
|
||||
sudo apt-get install nodejs -y
|
||||
sudo apt-get install npm -y
|
||||
sudo apt-get install postgresql -y
|
||||
sudo apt-get install libpq-dev -y
|
||||
sudo apt-get install redis-server -y
|
||||
|
||||
# Install node
|
||||
ln -fs /usr/bin/nodejs /usr/bin/node
|
||||
|
||||
# install forever for running the node server
|
||||
sudo npm install forever -g
|
||||
|
||||
# set the postgres password
|
||||
sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '3112';"
|
||||
|
||||
SCRIPT
|
||||
|
||||
VAGRANTFILE_API_VERSION = "2"
|
||||
|
||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
config.vm.box = "trusty64"
|
||||
config.vm.box_url = "http://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box"
|
||||
config.vm.network :forwarded_port, guest: 3000, host: 3000
|
||||
config.vm.network :forwarded_port, guest: 5001, host: 5001
|
||||
config.vm.network "private_network", ip: "10.0.1.11"
|
||||
config.vm.synced_folder ".", "/vagrant", :nfs => true
|
||||
|
||||
config.vm.provision "shell", inline: $script
|
||||
end
|
File diff suppressed because one or more lines are too long
|
@ -2449,6 +2449,7 @@ Extras.Classes.Navigation = new Class({
|
|||
if(!this.config.zooming) return;
|
||||
|
||||
// START METAMAPS CODE
|
||||
e.preventDefault();
|
||||
if (e.target.id != 'infovis-canvas') return;
|
||||
if (Metamaps.Create.newTopic.beingCreated) return;
|
||||
// END METAMAPS CODE
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Metamaps.Backbone = {};
|
||||
Metamaps.Backbone.Map = Backbone.Model.extend({
|
||||
urlRoot: '/maps',
|
||||
blacklist: ['created_at', 'updated_at', 'user_name', 'contributor_count', 'topic_count', 'synapse_count', 'topics', 'synapses', 'mappings', 'mappers'],
|
||||
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);
|
||||
},
|
||||
|
@ -169,23 +169,30 @@ Metamaps.Backbone.MapsCollection = Backbone.Collection.extend({
|
|||
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 () {
|
||||
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";
|
||||
if (collection.length - numBefore < 20) {
|
||||
self.page = "loadedAll";
|
||||
}
|
||||
else self.page += 1;
|
||||
self.trigger('successOnFetch');
|
||||
self.trigger('successOnFetch', cb);
|
||||
},
|
||||
error: function (collection, response, options) {
|
||||
// you can pass additional options to the event you trigger here as well
|
||||
|
@ -194,7 +201,7 @@ Metamaps.Backbone.MapsCollection = Backbone.Collection.extend({
|
|||
});
|
||||
}
|
||||
else {
|
||||
self.trigger('successOnFetch');
|
||||
self.trigger('successOnFetch', cb);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1758,7 +1758,9 @@ Metamaps.JIT = {
|
|||
var posChild = adj.nodeTo.pos.getc(true);
|
||||
|
||||
//plot arrow edge
|
||||
if (directionCat == "none") {
|
||||
if (!direction) {
|
||||
// render nothing for this arrow if the direction couldn't be retrieved
|
||||
} else if (directionCat == "none") {
|
||||
edgeHelper.line.render({
|
||||
x: pos.x,
|
||||
y: pos.y
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
"maps/:id": "maps" // #maps/7
|
||||
},
|
||||
home: function () {
|
||||
|
||||
clearTimeout(Metamaps.routerTimeoutId);
|
||||
|
||||
if (Metamaps.Active.Mapper) document.title = 'Explore Active Maps | Metamaps';
|
||||
else document.title = 'Home | Metamaps';
|
||||
|
||||
|
@ -21,6 +22,11 @@
|
|||
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) {
|
||||
|
||||
|
@ -37,10 +43,10 @@
|
|||
|
||||
Metamaps.Views.exploreMaps.setCollection( Metamaps.Maps.Active );
|
||||
if (Metamaps.Maps.Active.length === 0) {
|
||||
Metamaps.Maps.Active.getMaps(); // this will trigger an explore maps render
|
||||
Metamaps.Maps.Active.getMaps(navigate); // this will trigger an explore maps render
|
||||
}
|
||||
else {
|
||||
Metamaps.Views.exploreMaps.render();
|
||||
Metamaps.Views.exploreMaps.render(navigate);
|
||||
}
|
||||
}
|
||||
// logged out home page
|
||||
|
@ -54,9 +60,7 @@
|
|||
Metamaps.GlobalUI.Search.close(0, true);
|
||||
|
||||
Metamaps.Famous.maps.hide();
|
||||
setTimeout(function(){
|
||||
Metamaps.Router.navigate("");
|
||||
}, 500);
|
||||
Metamaps.routerTimeoutId = setTimeout(navigate, 500);
|
||||
}
|
||||
|
||||
Metamaps.Famous.viz.hide();
|
||||
|
@ -66,7 +70,8 @@
|
|||
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);
|
||||
|
@ -107,18 +112,32 @@
|
|||
}
|
||||
|
||||
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(); // this will trigger an explore maps render
|
||||
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();
|
||||
Metamaps.Views.exploreMaps.fetchUserThenRender(navigateTimeout);
|
||||
}
|
||||
else {
|
||||
Metamaps.Views.exploreMaps.render();
|
||||
Metamaps.Views.exploreMaps.render(navigateTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,7 +158,8 @@
|
|||
Metamaps.Active.Topic = null;
|
||||
},
|
||||
maps: function (id) {
|
||||
|
||||
clearTimeout(Metamaps.routerTimeoutId);
|
||||
|
||||
document.title = 'Map ' + id + ' | Metamaps';
|
||||
|
||||
Metamaps.currentSection = "map";
|
||||
|
@ -172,6 +192,7 @@
|
|||
Metamaps.Map.launch(id);
|
||||
},
|
||||
topics: function (id) {
|
||||
clearTimeout(Metamaps.routerTimeoutId);
|
||||
|
||||
document.title = 'Topic ' + id + ' | Metamaps';
|
||||
|
||||
|
|
|
@ -54,10 +54,15 @@ Metamaps.Views.init = function () {
|
|||
this.listenTo(this.collection, 'successOnFetch', this.handleSuccess);
|
||||
this.listenTo(this.collection, 'errorOnFetch', this.handleError);
|
||||
},
|
||||
render: function (mapperObj) {
|
||||
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
|
||||
|
@ -76,57 +81,47 @@ Metamaps.Views.init = function () {
|
|||
this.$el.append('<div class="clearfloat"></div>');
|
||||
var m = Metamaps.Famous.maps.surf;
|
||||
m.setContent(this.el);
|
||||
setTimeout(function(){
|
||||
|
||||
var updateHeight = function(){
|
||||
var height = $(that.el).height() + 32 + 56;
|
||||
m.setSize([undefined, height]);
|
||||
}, 100);
|
||||
Metamaps.Famous.maps.lock = false;
|
||||
if (cb) cb();
|
||||
};
|
||||
|
||||
if (!initialized) {
|
||||
m.deploy(m._currTarget);
|
||||
initialized = true;
|
||||
setTimeout(function(){
|
||||
var height = $(that.el).height() + 32 + 56;
|
||||
m.setSize([undefined, height]);
|
||||
}, 100);
|
||||
setTimeout(updateHeight, 100);
|
||||
} else {
|
||||
setTimeout(updateHeight, 100);
|
||||
}
|
||||
|
||||
Metamaps.Loading.hide();
|
||||
|
||||
clearTimeout(Metamaps.routerTimeoutFunctionIds);
|
||||
Metamaps.routerTimeoutId = setTimeout((function(localCurrentPage){ return function(){
|
||||
var path = (Metamaps.currentSection == "") ? "" : "/explore/" + localCurrentPage;
|
||||
|
||||
// alter url if for mapper profile page
|
||||
if (that.collection && that.collection.mapperId) {
|
||||
path += "/" + that.collection.mapperId;
|
||||
}
|
||||
|
||||
Metamaps.Router.navigate(path);
|
||||
}})(Metamaps.currentPage), 500);
|
||||
},
|
||||
handleSuccess: function () {
|
||||
handleSuccess: function (cb) {
|
||||
var that = this;
|
||||
|
||||
if (this.collection && this.collection.id === "mapper") {
|
||||
this.fetchUserThenRender();
|
||||
this.fetchUserThenRender(cb);
|
||||
}
|
||||
else {
|
||||
this.render();
|
||||
this.render(cb);
|
||||
}
|
||||
},
|
||||
handleError: function () {
|
||||
console.log('error loading maps!'); //TODO
|
||||
},
|
||||
fetchUserThenRender: function () {
|
||||
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);
|
||||
that.render(response, cb);
|
||||
},
|
||||
error: function () {
|
||||
|
||||
that.render(cb);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -356,10 +356,13 @@ Metamaps.Backbone.init = function () {
|
|||
return Metamaps.Topics.get(this.get('node2_id'));
|
||||
},
|
||||
getDirection: function () {
|
||||
return [
|
||||
this.getTopic1().get('node').id,
|
||||
this.getTopic2().get('node').id
|
||||
];
|
||||
var t1 = this.getTopic1(),
|
||||
t2 = this.getTopic2();
|
||||
|
||||
return t1 && t2 ? [
|
||||
t1.get('node').id,
|
||||
t2.get('node').id
|
||||
] : false;
|
||||
},
|
||||
getMapping: function () {
|
||||
|
||||
|
@ -893,7 +896,6 @@ Metamaps.TopicCard = {
|
|||
});
|
||||
var embedlyEl = $('<a/>', {
|
||||
id: 'embedlyLink',
|
||||
'data-card-chrome': '0',
|
||||
'data-card-description': '0',
|
||||
href: text
|
||||
}).html(text);
|
||||
|
@ -1176,7 +1178,7 @@ Metamaps.TopicCard = {
|
|||
|
||||
nodeValues.attachmentsHidden = '';
|
||||
if (topic.get('link') && topic.get('link')!== '') {
|
||||
nodeValues.embeds = '<a href="' + topic.get('link') + '" id="embedlyLink" target="_blank" data-card-chrome="0" data-card-description="0">';
|
||||
nodeValues.embeds = '<a href="' + topic.get('link') + '" id="embedlyLink" target="_blank" data-card-description="0">';
|
||||
nodeValues.embeds += topic.get('link');
|
||||
nodeValues.embeds += '</a><div id="embedlyLinkLoader"></div>';
|
||||
nodeValues.attachmentsHidden = 'hidden';
|
||||
|
@ -1652,8 +1654,8 @@ Metamaps.Visualize = {
|
|||
$jit.ForceDirected.Plot.NodeTypes.implement(Metamaps.JIT.ForceDirected.nodeSettings);
|
||||
$jit.ForceDirected.Plot.EdgeTypes.implement(Metamaps.JIT.ForceDirected.edgeSettings);
|
||||
|
||||
FDSettings.width = $(document).width();
|
||||
FDSettings.height = $(document).height();
|
||||
FDSettings.width = $('body').width();
|
||||
FDSettings.height = $('body').height();
|
||||
|
||||
self.mGraph = new $jit.ForceDirected(FDSettings);
|
||||
|
||||
|
@ -1666,32 +1668,56 @@ Metamaps.Visualize = {
|
|||
self.mGraph.graph.empty();
|
||||
}
|
||||
|
||||
Metamaps.Loading.hide();
|
||||
// load JSON data, if it's not empty
|
||||
if (!self.loadLater) {
|
||||
//load JSON data.
|
||||
var rootIndex = 0;
|
||||
if (Metamaps.Active.Topic) {
|
||||
var node = _.find(Metamaps.JIT.vizData, function(node){
|
||||
return node.id === Metamaps.Active.Topic.id;
|
||||
});
|
||||
rootIndex = _.indexOf(Metamaps.JIT.vizData, node);
|
||||
}
|
||||
self.mGraph.loadJSON(Metamaps.JIT.vizData, rootIndex);
|
||||
//compute positions and plot.
|
||||
self.computePositions();
|
||||
self.mGraph.busy = true;
|
||||
if (self.type == "RGraph") {
|
||||
self.mGraph.fx.animate(Metamaps.JIT.RGraph.animate);
|
||||
} else if (self.type == "ForceDirected") {
|
||||
self.mGraph.animate(Metamaps.JIT.ForceDirected.animateSavedLayout);
|
||||
} else if (self.type == "ForceDirected3D") {
|
||||
self.mGraph.animate(Metamaps.JIT.ForceDirected.animateFDLayout);
|
||||
function runAnimation() {
|
||||
Metamaps.Loading.hide();
|
||||
// load JSON data, if it's not empty
|
||||
if (!self.loadLater) {
|
||||
//load JSON data.
|
||||
var rootIndex = 0;
|
||||
if (Metamaps.Active.Topic) {
|
||||
var node = _.find(Metamaps.JIT.vizData, function(node){
|
||||
return node.id === Metamaps.Active.Topic.id;
|
||||
});
|
||||
rootIndex = _.indexOf(Metamaps.JIT.vizData, node);
|
||||
}
|
||||
self.mGraph.loadJSON(Metamaps.JIT.vizData, rootIndex);
|
||||
//compute positions and plot.
|
||||
self.computePositions();
|
||||
self.mGraph.busy = true;
|
||||
if (self.type == "RGraph") {
|
||||
self.mGraph.fx.animate(Metamaps.JIT.RGraph.animate);
|
||||
} else if (self.type == "ForceDirected") {
|
||||
self.mGraph.animate(Metamaps.JIT.ForceDirected.animateSavedLayout);
|
||||
} else if (self.type == "ForceDirected3D") {
|
||||
self.mGraph.animate(Metamaps.JIT.ForceDirected.animateFDLayout);
|
||||
}
|
||||
}
|
||||
}
|
||||
// hold until all the needed metacode images are loaded
|
||||
// hold for a maximum of 80 passes, or 4 seconds of waiting time
|
||||
var tries = 0;
|
||||
function hold() {
|
||||
var unique = _.uniq(Metamaps.Topics.models, function (metacode) { return metacode.get('metacode_id'); }),
|
||||
requiredMetacodes = _.map(unique, function (metacode) { return metacode.get('metacode_id'); }),
|
||||
loadedCount = 0;
|
||||
|
||||
_.each(requiredMetacodes, function (metacode_id) {
|
||||
var metacode = Metamaps.Metacodes.get(metacode_id),
|
||||
img = metacode ? metacode.get('image') : false;
|
||||
|
||||
if (img && (img.complete || (typeof img.naturalWidth !== "undefined" && img.naturalWidth !== 0))) {
|
||||
loadedCount += 1;
|
||||
}
|
||||
});
|
||||
|
||||
if (loadedCount === requiredMetacodes.length || tries > 80) runAnimation();
|
||||
else setTimeout(function(){ tries++; hold() }, 50);
|
||||
}
|
||||
hold();
|
||||
|
||||
// update the url now that the map is ready
|
||||
setTimeout(function(){
|
||||
clearTimeout(Metamaps.routerTimeoutId);
|
||||
Metamaps.routerTimeoutId = setTimeout(function(){
|
||||
var m = Metamaps.Active.Map;
|
||||
var t = Metamaps.Active.Topic;
|
||||
|
||||
|
@ -2748,14 +2774,20 @@ Metamaps.Control = {
|
|||
|
||||
var node = Metamaps.Visualize.mGraph.graph.getNode(nodeid);
|
||||
var topic = node.getData('topic');
|
||||
var topicid = topic.id;
|
||||
var mapping = node.getData('mapping');
|
||||
topic.destroy();
|
||||
Metamaps.Mappings.remove(mapping);
|
||||
$(document).trigger(Metamaps.JIT.events.deleteTopic, [{
|
||||
topicid: topicid
|
||||
}]);
|
||||
Metamaps.Control.hideNode(nodeid);
|
||||
|
||||
var permToDelete = Metamaps.Active.Mapper.id === topic.get('user_id');
|
||||
if (permToDelete) {
|
||||
var topicid = topic.id;
|
||||
var mapping = node.getData('mapping');
|
||||
topic.destroy();
|
||||
Metamaps.Mappings.remove(mapping);
|
||||
$(document).trigger(Metamaps.JIT.events.deleteTopic, [{
|
||||
topicid: topicid
|
||||
}]);
|
||||
Metamaps.Control.hideNode(nodeid);
|
||||
} else {
|
||||
Metamaps.GlobalUI.notifyUser('Only topics you created can be deleted');
|
||||
}
|
||||
},
|
||||
removeSelectedNodes: function () { // refers to removing topics permanently from a map
|
||||
|
||||
|
@ -2811,10 +2843,6 @@ Metamaps.Control = {
|
|||
hideNode: function (nodeid) {
|
||||
var node = Metamaps.Visualize.mGraph.graph.getNode(nodeid);
|
||||
var graph = Metamaps.Visualize.mGraph;
|
||||
if (nodeid == Metamaps.Visualize.mGraph.root) { // && Metamaps.Visualize.type === "RGraph"
|
||||
var newroot = _.find(graph.graph.nodes, function(n){ return n.id !== nodeid; });
|
||||
graph.root = newroot ? newroot.id : null;
|
||||
}
|
||||
|
||||
Metamaps.Control.deselectNode(node);
|
||||
|
||||
|
@ -2829,6 +2857,10 @@ Metamaps.Control = {
|
|||
duration: 500
|
||||
});
|
||||
setTimeout(function () {
|
||||
if (nodeid == Metamaps.Visualize.mGraph.root) { // && Metamaps.Visualize.type === "RGraph"
|
||||
var newroot = _.find(graph.graph.nodes, function(n){ return n.id !== nodeid; });
|
||||
graph.root = newroot ? newroot.id : null;
|
||||
}
|
||||
Metamaps.Visualize.mGraph.graph.removeNode(nodeid);
|
||||
}, 500);
|
||||
Metamaps.Filter.checkMetacodes();
|
||||
|
@ -2907,27 +2939,33 @@ Metamaps.Control = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (edge.getData("synapses").length - 1 === 0) {
|
||||
Metamaps.Control.hideEdge(edge);
|
||||
}
|
||||
|
||||
var index = edge.getData("displayIndex") ? edge.getData("displayIndex") : 0;
|
||||
|
||||
var synapse = edge.getData("synapses")[index];
|
||||
var mapping = edge.getData("mappings")[index];
|
||||
var synapseid = synapse.id;
|
||||
synapse.destroy();
|
||||
|
||||
var permToDelete = Metamaps.Active.Mapper.id === synapse.get('user_id');
|
||||
if (permToDelete) {
|
||||
if (edge.getData("synapses").length - 1 === 0) {
|
||||
Metamaps.Control.hideEdge(edge);
|
||||
}
|
||||
|
||||
var synapseid = synapse.id;
|
||||
synapse.destroy();
|
||||
|
||||
// the server will destroy the mapping, we just need to remove it here
|
||||
Metamaps.Mappings.remove(mapping);
|
||||
edge.getData("mappings").splice(index, 1);
|
||||
edge.getData("synapses").splice(index, 1);
|
||||
if (edge.getData("displayIndex")) {
|
||||
delete edge.data.$displayIndex;
|
||||
// the server will destroy the mapping, we just need to remove it here
|
||||
Metamaps.Mappings.remove(mapping);
|
||||
edge.getData("mappings").splice(index, 1);
|
||||
edge.getData("synapses").splice(index, 1);
|
||||
if (edge.getData("displayIndex")) {
|
||||
delete edge.data.$displayIndex;
|
||||
}
|
||||
$(document).trigger(Metamaps.JIT.events.deleteSynapse, [{
|
||||
synapseid: synapseid
|
||||
}]);
|
||||
} else {
|
||||
Metamaps.GlobalUI.notifyUser('Only synapses you created can be deleted');
|
||||
}
|
||||
$(document).trigger(Metamaps.JIT.events.deleteSynapse, [{
|
||||
synapseid: synapseid
|
||||
}]);
|
||||
},
|
||||
removeSelectedEdges: function () {
|
||||
var l = Metamaps.Selected.Edges.length,
|
||||
|
@ -4705,7 +4743,7 @@ Metamaps.Map.InfoBox = {
|
|||
|
||||
var map = Metamaps.Active.Map;
|
||||
|
||||
var obj = map.pick("permission","contributor_count","topic_count","synapse_count","created_at","updated_at");
|
||||
var obj = map.pick("permission","contributor_count","topic_count","synapse_count");
|
||||
|
||||
var isCreator = map.authorizePermissionChange(Metamaps.Active.Mapper);
|
||||
var canEdit = map.authorizeToEdit(Metamaps.Active.Mapper);
|
||||
|
@ -4719,6 +4757,8 @@ Metamaps.Map.InfoBox = {
|
|||
obj["contributor_image"] = Metamaps.Mappers.length > 0 ? Metamaps.Mappers.models[0].get("image") : "/assets/user.png";
|
||||
obj["contributor_list"] = self.createContributorList();
|
||||
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" : "";
|
||||
|
@ -4793,8 +4833,7 @@ Metamaps.Map.InfoBox = {
|
|||
createContributorList: function () {
|
||||
var self = Metamaps.Map.InfoBox;
|
||||
|
||||
var string = "";
|
||||
console.log("hello!!")
|
||||
var string = "";
|
||||
string += "<ul>";
|
||||
|
||||
Metamaps.Mappers.each(function(m){
|
||||
|
@ -4802,7 +4841,6 @@ Metamaps.Map.InfoBox = {
|
|||
});
|
||||
|
||||
string += "</ul>";
|
||||
console.log(string);
|
||||
return string;
|
||||
},
|
||||
updateNumbers: function () {
|
||||
|
|
|
@ -2724,7 +2724,7 @@ and it won't be important on password protected instances */
|
|||
color: #999;
|
||||
}
|
||||
#upYourSkillz {
|
||||
margin: 0 68px;
|
||||
margin: 0 67px;
|
||||
}
|
||||
#moreResources {
|
||||
padding: 16px 0 0 0;
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
/* logo */
|
||||
|
||||
.footer {
|
||||
z-index: 3;
|
||||
z-index: 3 !important; /* important necessary for firefox */
|
||||
}
|
||||
|
||||
.logo {
|
||||
|
@ -1041,7 +1041,7 @@
|
|||
.sidebarCollaborateIcon div:after, .sidebarFilterIcon div:after, .sidebarForkIcon div:after, .addMap div:after, .sidebarAccountIcon .tooltipsUnder:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 128%;
|
||||
top: 129%;
|
||||
margin-top: -30px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
|
@ -1053,7 +1053,7 @@
|
|||
.mapInfoIcon div:after, .openCheatsheet div:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 77%;
|
||||
top: 76%;
|
||||
left: 41%;
|
||||
margin-top: 5px;
|
||||
width: 0;
|
||||
|
@ -1187,7 +1187,7 @@
|
|||
color: #F5F5F5;
|
||||
padding: 16px;
|
||||
border-radius: 2px;
|
||||
z-index: 1;
|
||||
z-index: 1 !important; /* important necessary for firefox */
|
||||
font-size: 14px;
|
||||
line-height:14px;
|
||||
}
|
||||
|
|
|
@ -47,16 +47,16 @@ class SynapsesController < ApplicationController
|
|||
# DELETE synapses/:id
|
||||
def destroy
|
||||
@current = current_user
|
||||
@synapse = Synapse.find(params[:id]).authorize_to_edit(@current)
|
||||
@synapse = Synapse.find(params[:id]).authorize_to_delete(@current)
|
||||
|
||||
@synapse.mappings.each do |m|
|
||||
|
||||
m.map.touch(:updated_at)
|
||||
|
||||
m.delete
|
||||
if @synapse
|
||||
@synapse.mappings.each do |m|
|
||||
m.map.touch(:updated_at)
|
||||
m.delete
|
||||
end
|
||||
|
||||
@synapse.delete
|
||||
end
|
||||
|
||||
@synapse.delete if @synapse
|
||||
|
||||
respond_to do |format|
|
||||
format.json { head :no_content }
|
||||
|
|
|
@ -198,7 +198,7 @@ class TopicsController < ApplicationController
|
|||
# DELETE topics/:id
|
||||
def destroy
|
||||
@current = current_user
|
||||
@topic = Topic.find(params[:id]).authorize_to_edit(@current)
|
||||
@topic = Topic.find(params[:id]).authorize_to_delete(@current)
|
||||
|
||||
if @topic
|
||||
@synapses = @topic.synapses
|
||||
|
@ -228,7 +228,7 @@ class TopicsController < ApplicationController
|
|||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.js { render :json => "success" }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -76,9 +76,9 @@ class Map < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def as_json(options={})
|
||||
json = super(:methods =>[:user_name, :user_image, :topic_count, :synapse_count, :contributor_count, :screenshot_url], :except => [:screenshot_content_type, :screenshot_file_size, :screenshot_file_name, :screenshot_updated_at, :created_at, :updated_at])
|
||||
json[:created_at] = self.created_at_str
|
||||
json[:updated_at] = self.updated_at_str
|
||||
json = super(:methods =>[:user_name, :user_image, :topic_count, :synapse_count, :contributor_count, :screenshot_url], :except => [:screenshot_content_type, :screenshot_file_size, :screenshot_file_name, :screenshot_updated_at])
|
||||
json[:created_at_clean] = self.created_at_str
|
||||
json[:updated_at_clean] = self.updated_at_str
|
||||
json
|
||||
end
|
||||
|
||||
|
|
|
@ -39,6 +39,13 @@ class Synapse < ActiveRecord::Base
|
|||
end
|
||||
return self
|
||||
end
|
||||
|
||||
def authorize_to_delete(user)
|
||||
if (self.user != user)
|
||||
return false
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
# returns Boolean if user allowed to view Topic, Synapse, or Map
|
||||
def authorize_to_view(user)
|
||||
|
|
|
@ -110,6 +110,13 @@ class Topic < ActiveRecord::Base
|
|||
end
|
||||
return self
|
||||
end
|
||||
|
||||
def authorize_to_delete(user)
|
||||
if (self.user != user)
|
||||
return false
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
# returns Boolean if user allowed to view Topic, Synapse, or Map
|
||||
def authorize_to_view(user)
|
||||
|
|
2
bin/start
Executable file
2
bin/start
Executable file
|
@ -0,0 +1,2 @@
|
|||
#start rails server and realtime node server
|
||||
vagrant ssh --command "cd /vagrant; rails s -d; forever start ./realtime/realtime-server.js"
|
2
bin/stop
Executable file
2
bin/stop
Executable file
|
@ -0,0 +1,2 @@
|
|||
# stop rails server and node server
|
||||
vagrant ssh --command "cd /vagrant; kill -9 $(cat tmp/pids/server.pid); forever stopall"
|
|
@ -1,71 +0,0 @@
|
|||
FILE /app/views/layouts/application.html.erb
|
||||
<head>
|
||||
...
|
||||
<%= javascript_include_tag "application" %>
|
||||
<% if (controller_name == "maps" || controller_name == "topics") && action_name == "show" %>
|
||||
<%= javascript_include_tag "compileMapPages" %>
|
||||
<% end %>
|
||||
...
|
||||
</head>
|
||||
|
||||
WHAT DOES IT MEAN?
|
||||
|
||||
|
||||
____________________________________________________________________
|
||||
|
||||
FILE /app/assets/javascripts/application.js
|
||||
...
|
||||
//= require jquery
|
||||
//= require jquery-ui
|
||||
//= require jquery_ujs
|
||||
//= require ./orderedLibraries/underscore
|
||||
//= require ./orderedLibraries/backbone
|
||||
//= require_directory ./librariesForAllPages
|
||||
//= require ./metamaps/Metamaps.GlobalUI
|
||||
//= require ./metamaps/Metamaps.Backbone
|
||||
|
||||
WHAT DOES IT MEAN?
|
||||
|
||||
|
||||
____________________________________________________________________
|
||||
|
||||
FILE /app/assets/javascripts/compileMapPages.js
|
||||
...
|
||||
//= require ./librariesForMapPages/cloudcarousel
|
||||
//= require ./librariesForMapPages/socket.io
|
||||
//= require ./metamaps/JIT
|
||||
//= require ./metamaps/Metamaps
|
||||
//= require ./metamaps/Metamaps.JIT
|
||||
|
||||
WHAT DOES IT MEAN?
|
||||
|
||||
|
||||
|
||||
____________________________________________________________________
|
||||
|
||||
FILE /app/assets/javascripts/metamaps/Metamaps.GlobalUI.js
|
||||
|
||||
var Metamaps = {};
|
||||
...
|
||||
$(document).ready(function () {
|
||||
for (var prop in Metamaps) {
|
||||
|
||||
// this runs the init function within each sub-object on the Metamaps one
|
||||
if (Metamaps.hasOwnProperty(prop) &&
|
||||
Metamaps[prop].hasOwnProperty('init') &&
|
||||
typeof (Metamaps[prop].init) == 'function'
|
||||
) {
|
||||
Metamaps[prop].init();
|
||||
}
|
||||
}
|
||||
});
|
||||
Metamaps.GlobalUI = {
|
||||
...
|
||||
};
|
||||
|
||||
WHAT DOES IT MEAN?
|
||||
|
||||
|
||||
|
||||
____________________________________________________________________
|
||||
|
16
configure.sh
Executable file
16
configure.sh
Executable file
|
@ -0,0 +1,16 @@
|
|||
# Make sure we've got NFS handy.
|
||||
if [ $(uname) == 'Linux' ] && [ ! -e /etc/init.d/nfs-kernel-server ]; then
|
||||
sudo apt-get install -y nfs-common nfs-kernel-server rpcbind
|
||||
fi
|
||||
|
||||
# Vagrant up
|
||||
vagrant up
|
||||
|
||||
# Bundle!
|
||||
vagrant ssh --command "cd /vagrant; bundle install";
|
||||
|
||||
# copy the db config
|
||||
vagrant ssh --command "cd /vagrant; cp config/database.yml.default config/database.yml";
|
||||
|
||||
# Rake all the things
|
||||
vagrant ssh --command "cd /vagrant; rake db:create; rake db:schema:load; rake db:fixtures:load"
|
|
@ -206,15 +206,24 @@ Metamaps.Famous.build = function () {
|
|||
f.maps.mod.setTransform(Transform.translate(window.innerWidth, 94, 0));
|
||||
};
|
||||
var mapsScroll = new Scrollview();
|
||||
mapsScroll._scroller.on('edgeHit', function(data){
|
||||
if (data.position > 0 &&
|
||||
f.maps.lock = false;
|
||||
mapsScroll._eventInput.on('update', _.throttle(function(data) {
|
||||
var bottom = f.maps.surf.getSize()[1], // how far down it goes
|
||||
pos = mapsScroll.getPosition(), // how far down you are
|
||||
containerSize = f.maps.mod.getSize()[1], // height of the viewable area
|
||||
distanceToBottom = bottom - (pos + containerSize),
|
||||
triggerDistance = 700;
|
||||
|
||||
if (!f.maps.lock &&
|
||||
distanceToBottom < triggerDistance &&
|
||||
Metamaps.Views &&
|
||||
Metamaps.Views.exploreMaps &&
|
||||
Metamaps.Views.exploreMaps.collection &&
|
||||
Metamaps.Views.exploreMaps.collection.page != "loadedAll") {
|
||||
f.maps.lock = true;
|
||||
Metamaps.Views.exploreMaps.collection.getMaps();
|
||||
}
|
||||
});
|
||||
}, 500));
|
||||
f.maps.resetScroll = function() {
|
||||
// set the scrollView back to the top
|
||||
mapsScroll._physicsEngine.detachAll();
|
||||
|
|
|
@ -1,45 +1,9 @@
|
|||
/*var http = require('http'),
|
||||
express = require('express'),
|
||||
port = process.env.PORT || 5001,
|
||||
app = express(),
|
||||
server = http.createServer(app).listen(port),
|
||||
io = require('socket.io').listen(server);
|
||||
|
||||
console.log(port);
|
||||
|
||||
app.configure(function() {
|
||||
app.use(function(req, res, next) {
|
||||
res.header('Access-Control-Allow-Origin', '*');
|
||||
res.header('Access-Control-Allow-Methods', 'GET, OPTIONS');
|
||||
res.header('Access-Control-Allow-Headers', 'Content-Type');
|
||||
return next();
|
||||
});
|
||||
}); */
|
||||
|
||||
//var rtg = require("url").parse("redis://redistogo:0ca046a3d56533cc162e2447db383192@pearlfish.redistogo.com:9060/"),
|
||||
//redis = require('redis').createClient(rtg.port, rtg.hostname, {no_ready_check: true});
|
||||
|
||||
var io = require('socket.io').listen(5001);
|
||||
//var redis = require('redis').createClient();
|
||||
|
||||
//redis.auth(rtg.auth.split(":")[1], function() {
|
||||
// start();
|
||||
//});
|
||||
|
||||
function start() {
|
||||
//redis.subscribe('maps');
|
||||
|
||||
io.on('connection', function (socket) {
|
||||
|
||||
// this will ping everyone on a map with updates to the map
|
||||
/*redis.on('message', function (channel, message) {
|
||||
console.log(message);
|
||||
var m = JSON.parse(message);
|
||||
var room = 'maps-' + m.mapid;
|
||||
|
||||
socket.emit(room, m);
|
||||
});*/
|
||||
|
||||
// this will ping a new person with awareness of who's already on the map
|
||||
socket.on('updateNewMapperList', function (data) {
|
||||
var existingUser = {
|
||||
|
|
Loading…
Reference in a new issue