kopia lustrzana https://github.com/FacilMap/facilmap
Replace index page by a map where you can optionally start a pad
rodzic
7b97b59e00
commit
54657ef048
|
@ -1,3 +1,6 @@
|
||||||
RewriteEngine on
|
RewriteEngine on
|
||||||
|
|
||||||
|
RewriteRule ^$ build/index.html
|
||||||
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !-f
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
RewriteRule ^.+$ build/index.html
|
RewriteRule ^.+$ build/index.html
|
|
@ -29,7 +29,6 @@ var FacilPad = {
|
||||||
});
|
});
|
||||||
|
|
||||||
fp.app.run([ "$rootScope", "fpUtils", function($rootScope, fpUtils) {
|
fp.app.run([ "$rootScope", "fpUtils", function($rootScope, fpUtils) {
|
||||||
$rootScope.padId = location.pathname.match(/[^\/]*$/)[0];
|
|
||||||
$rootScope.urlPrefix = location.protocol + "//" + location.host + location.pathname.replace(/[^\/]*$/, "");
|
$rootScope.urlPrefix = location.protocol + "//" + location.host + location.pathname.replace(/[^\/]*$/, "");
|
||||||
|
|
||||||
$rootScope.round = fpUtils.round;
|
$rootScope.round = fpUtils.round;
|
||||||
|
@ -79,14 +78,19 @@ var FacilPad = {
|
||||||
};
|
};
|
||||||
|
|
||||||
fp.app.controller("PadCtrl", function($scope, fpMap, $timeout) {
|
fp.app.controller("PadCtrl", function($scope, fpMap, $timeout) {
|
||||||
|
$scope.padId = location.pathname.match(/[^\/]*$/)[0];
|
||||||
|
|
||||||
$timeout(function() {
|
$timeout(function() {
|
||||||
var map = fpMap.getMap("map");
|
var map = fpMap.getMap("map");
|
||||||
|
|
||||||
if(map.socket.padData)
|
|
||||||
$scope.padName = map.socket.padData.name;
|
|
||||||
map.socket.$watch("padData.name", function(newVal) {
|
map.socket.$watch("padData.name", function(newVal) {
|
||||||
$scope.padName = newVal;
|
$scope.padName = newVal;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
map.socket.$watch("padId", function(padId) {
|
||||||
|
if(padId)
|
||||||
|
history.replaceState(null, "", $scope.urlPrefix + padId);
|
||||||
|
});
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<img src="spinner.gif" alt="Loading…">
|
<img src="spinner.gif" alt="Loading…">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fp-map-disabled-cover" ng-show="!loaded || disconnected"></div>
|
<div class="fp-map-disabled-cover" ng-show="disconnected || serverError"></div>
|
||||||
<div class="fp-map-loading" ng-hide="loaded">
|
<div class="fp-map-loading" ng-hide="loaded || serverError">
|
||||||
Loading...
|
Loading...
|
||||||
</div>
|
</div>
|
|
@ -19,20 +19,18 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
ret.initMap = function(el, id, padId) {
|
ret.initMap = function(el, id, padId) {
|
||||||
return maps[id] = new Map(el, id, padId);
|
return maps[id] = new Map(el, padId);
|
||||||
};
|
};
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
function Map(el, id, padId) {
|
function Map(el, padId) {
|
||||||
var map = this;
|
var map = this;
|
||||||
|
|
||||||
map.el = el;
|
map.el = el;
|
||||||
map.mapEvents = $rootScope.$new(true); /* Event types: click, layerchange */
|
map.mapEvents = $rootScope.$new(true); /* Event types: click, layerchange */
|
||||||
map.socket = fpSocket(padId);
|
map.socket = fpSocket(padId);
|
||||||
|
|
||||||
//map.socket.id = id; // To be in scope for template
|
|
||||||
|
|
||||||
map.layers = { };
|
map.layers = { };
|
||||||
[
|
[
|
||||||
L.tileLayer("http://korona.geog.uni-heidelberg.de/tiles/roads/x={x}&y={y}&z={z}", {
|
L.tileLayer("http://korona.geog.uni-heidelberg.de/tiles/roads/x={x}&y={y}&z={z}", {
|
||||||
|
@ -91,9 +89,12 @@
|
||||||
direction: "right"
|
direction: "right"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var scope = map.socket.$new();
|
||||||
|
scope.loaded = false;
|
||||||
|
|
||||||
var tpl = $($templateCache.get("map/map/map.html"));
|
var tpl = $($templateCache.get("map/map/map.html"));
|
||||||
el.append(tpl);
|
el.append(tpl);
|
||||||
$compile(tpl)(map.socket);
|
$compile(tpl)(scope);
|
||||||
|
|
||||||
map.map = L.map(el.find(".fp-map")[0]);
|
map.map = L.map(el.find(".fp-map")[0]);
|
||||||
|
|
||||||
|
@ -268,18 +269,22 @@
|
||||||
|
|
||||||
fpMapLegend(map);
|
fpMapLegend(map);
|
||||||
|
|
||||||
var loadedWatcher = map.socket.$watch("loaded", function(loaded) {
|
if(padId) {
|
||||||
if(loaded) {
|
var loadedWatcher = map.socket.$watch("padData", function(padData) {
|
||||||
setTimeout(function() {
|
if(padData != null) {
|
||||||
map.displayView(map.socket.padData.defaultView);
|
|
||||||
}, 0);
|
|
||||||
loadedWatcher();
|
loadedWatcher();
|
||||||
|
map.displayView(padData.defaultView);
|
||||||
|
scope.loaded = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
map.displayView();
|
||||||
|
scope.loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
var errorMessage = null;
|
var errorMessage = null;
|
||||||
map.socket.$watch("disconnected", function(disconnected) {
|
map.socket.$watch("disconnected", function(disconnected) {
|
||||||
if(disconnected && !errorMessage)
|
if(disconnected && !errorMessage && !map.socket.serverError)
|
||||||
errorMessage = map.messages.showMessage("danger", "The connection to the server was lost.");
|
errorMessage = map.messages.showMessage("danger", "The connection to the server was lost.");
|
||||||
else if(!disconnected && errorMessage) {
|
else if(!disconnected && errorMessage) {
|
||||||
errorMessage.close();
|
errorMessage.close();
|
||||||
|
@ -287,7 +292,15 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
map.socket.$watch("serverError", function(serverError) {
|
||||||
|
if(serverError) {
|
||||||
|
errorMessage && errorMessage.close();
|
||||||
|
map.messages.showMessage("danger", serverError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
map.map.on("moveend", function() {
|
map.map.on("moveend", function() {
|
||||||
|
if(map.socket.padId)
|
||||||
map.socket.updateBbox(fpUtils.leafletToFpBbox(map.map.getBounds(), map.map.getZoom()));
|
map.socket.updateBbox(fpUtils.leafletToFpBbox(map.map.getBounds(), map.map.getZoom()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,38 @@
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button class="close" ng-click="$dismiss()"><span aria-hidden="true">×</span></button>
|
<button class="close" ng-click="$dismiss()"><span aria-hidden="true">×</span></button>
|
||||||
<h3 class="modal-title">Pad settings</h3>
|
<h3 class="modal-title">{{create ? 'Start collaborative map' : 'Pad settings'}}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<form class="form-horizontal">
|
<form class="form-horizontal">
|
||||||
<div uib-alert class="alert-danger" ng-show="error">{{error}}</div>
|
<div uib-alert class="alert-danger" ng-show="error">{{error}}</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="pad-link-input" class="col-sm-3 control-label">Link</label>
|
<label for="pad-link-input" class="col-sm-3 control-label">Edit-only Link</label>
|
||||||
<div class="col-sm-9"><input id="pad-link-input" value="{{urlPrefix}}{{padId}}" class="form-control" readonly /></div>
|
<div class="col-sm-9">
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-addon">{{urlPrefix}}</span>
|
||||||
|
<input id="pad-link-input" ng-model="writeId" class="form-control" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="pad-rolink-input" class="col-sm-3 control-label">Read-only link</label>
|
<label for="pad-rolink-input" class="col-sm-3 control-label">Read-only link</label>
|
||||||
<div class="col-sm-9"><input id="pad-rolink-input" value="{{urlPrefix}}{{padData.id}}" class="form-control" readonly /></div>
|
<div class="col-sm-9">
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-addon">{{urlPrefix}}</span>
|
||||||
|
<input id="pad-rolink-input" ng-model="readId" class="form-control" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="pad-name-input" class="col-sm-3 control-label">Pad name</label>
|
<label for="pad-name-input" class="col-sm-3 control-label">Pad name</label>
|
||||||
<div class="col-sm-9"><input id="pad-name-input" ng-model="padData.name" class="form-control" /></div>
|
<div class="col-sm-9"><input id="pad-name-input" ng-model="padName" class="form-control" /></div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-default" ng-click="$dismiss()">Cancel</button>
|
<button type="button" class="btn btn-default" ng-click="$dismiss()">Cancel</button>
|
||||||
<button type="button" class="btn btn-primary" ng-click="save()">Save</button>
|
<button type="button" class="btn btn-primary" ng-click="save()">{{create ? 'Create' : 'Save'}}</button>
|
||||||
</div>
|
</div>
|
|
@ -3,23 +3,30 @@
|
||||||
fp.app.factory("fpMapPad", function($uibModal, fpUtils) {
|
fp.app.factory("fpMapPad", function($uibModal, fpUtils) {
|
||||||
return function(map) {
|
return function(map) {
|
||||||
var ret = {
|
var ret = {
|
||||||
editPadSettings : function() {
|
createPad : function() {
|
||||||
|
ret.editPadSettings(true);
|
||||||
|
},
|
||||||
|
editPadSettings : function(create) {
|
||||||
var dialog = $uibModal.open({
|
var dialog = $uibModal.open({
|
||||||
templateUrl: "map/pad/pad-settings.html",
|
templateUrl: "map/pad/pad-settings.html",
|
||||||
scope: map.socket,
|
scope: map.socket,
|
||||||
controller: "fpMapPadSettingsCtrl",
|
controller: "fpMapPadSettingsCtrl",
|
||||||
size: "lg",
|
size: "lg",
|
||||||
resolve: {
|
resolve: {
|
||||||
map: function() { return map; }
|
map: function() { return map; },
|
||||||
|
create: function() { return create; }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(!create) {
|
||||||
|
// TODO: use child scope!
|
||||||
var preserve = fpUtils.preserveObject(map.socket, "padData", "padData", function() {
|
var preserve = fpUtils.preserveObject(map.socket, "padData", "padData", function() {
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
});
|
});
|
||||||
|
|
||||||
dialog.result.then(preserve.leave.bind(preserve), preserve.revert.bind(preserve));
|
dialog.result.then(preserve.leave.bind(preserve), preserve.revert.bind(preserve));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -43,16 +50,43 @@
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
fp.app.controller("fpMapPadSettingsCtrl", function($scope, map) {
|
fp.app.controller("fpMapPadSettingsCtrl", function($scope, map, create, fpUtils) {
|
||||||
|
$scope.create = create;
|
||||||
|
|
||||||
|
if(create) {
|
||||||
|
$scope.writeId = fpUtils.generateRandomPadId(14);
|
||||||
|
$scope.readId = fpUtils.generateRandomPadId(12);
|
||||||
|
$scope.padName = "New FacilPad";
|
||||||
|
} else {
|
||||||
|
$scope.writeId = map.socket.padData.writeId;
|
||||||
|
$scope.readId = map.socket.padData.id;
|
||||||
|
$scope.padName = map.socket.padData.name;
|
||||||
|
}
|
||||||
|
|
||||||
$scope.save = function() {
|
$scope.save = function() {
|
||||||
var padData = $.extend({ }, map.socket.padData);
|
var newData = {
|
||||||
delete padData.defaultView;
|
name: $scope.padName,
|
||||||
map.socket.emit("editPad", padData, function(err) {
|
id: $scope.readId,
|
||||||
|
writeId: $scope.writeId
|
||||||
|
};
|
||||||
|
|
||||||
|
if(create) {
|
||||||
|
map.socket.emit("createPad", newData, function(err) {
|
||||||
|
if(err)
|
||||||
|
return $scope.error = err;
|
||||||
|
|
||||||
|
map.socket.updateBbox(fpUtils.leafletToFpBbox(map.map.getBounds(), map.map.getZoom()));
|
||||||
|
|
||||||
|
$scope.$close();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
map.socket.emit("editPad", newData, function(err) {
|
||||||
if(err)
|
if(err)
|
||||||
return $scope.error = err;
|
return $scope.error = err;
|
||||||
|
|
||||||
$scope.$close();
|
$scope.$close();
|
||||||
});
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,10 @@
|
||||||
<nav class="navbar navbar-default" ng-class="{'hidden-xs': !showXs}">
|
<nav class="navbar navbar-default" ng-class="{'hidden-xs': !showXs}">
|
||||||
<div class="container-fluid" id="fp-toolbox-content">
|
<div class="container-fluid" id="fp-toolbox-content">
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
<li role="presentation" uib-dropdown ng-if="!readonly">
|
<li role="presentation" ng-if="!padId">
|
||||||
|
<a href="javascript:" ng-click="startPad()">Start collaborative map</a>
|
||||||
|
</li>
|
||||||
|
<li role="presentation" uib-dropdown ng-if="!readonly && padId">
|
||||||
<a href="javascript:" id="toolbox-add-dropdown" uib-dropdown-toggle role="button">Add <span class="caret"></span></a>
|
<a href="javascript:" id="toolbox-add-dropdown" uib-dropdown-toggle role="button">Add <span class="caret"></span></a>
|
||||||
<ul uib-dropdown-menu aria-labelledby="toolbox-add-dropdown">
|
<ul uib-dropdown-menu aria-labelledby="toolbox-add-dropdown">
|
||||||
<li ng-repeat="type in types"><a href="javascript:" ng-click="addObject(type)">{{type.name}}</a></li>
|
<li ng-repeat="type in types"><a href="javascript:" ng-click="addObject(type)">{{type.name}}</a></li>
|
||||||
|
@ -11,7 +14,7 @@
|
||||||
<li><a href="javascript:" ng-click="editObjectTypes()">Manage types</a></li>
|
<li><a href="javascript:" ng-click="editObjectTypes()">Manage types</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li role="presentation" uib-dropdown>
|
<li role="presentation" uib-dropdown ng-if="padId">
|
||||||
<a href="javascript:" id="toolbox-views-dropdown" uib-dropdown-toggle role="button">Saved views <span class="caret"></span></a>
|
<a href="javascript:" id="toolbox-views-dropdown" uib-dropdown-toggle role="button">Saved views <span class="caret"></span></a>
|
||||||
<ul uib-dropdown-menu aria-labelledby="toolbox-views-dropdown">
|
<ul uib-dropdown-menu aria-labelledby="toolbox-views-dropdown">
|
||||||
<li ng-repeat="(id, view) in views"><a href="javascript:" ng-click="displayView(view)">{{view.name}}</a></li>
|
<li ng-repeat="(id, view) in views"><a href="javascript:" ng-click="displayView(view)">{{view.name}}</a></li>
|
||||||
|
@ -36,9 +39,9 @@
|
||||||
<ul uib-dropdown-menu aria-labelledby="toolbox-layers-dropdown" class="dropdown-menu-right">
|
<ul uib-dropdown-menu aria-labelledby="toolbox-layers-dropdown" class="dropdown-menu-right">
|
||||||
<!--<li ng-if="!readonly"><a href="javascript:" ng-click="openDialog('copy-pad-dialog')">Copy pad</a></li>-->
|
<!--<li ng-if="!readonly"><a href="javascript:" ng-click="openDialog('copy-pad-dialog')">Copy pad</a></li>-->
|
||||||
<!--<li><a href="javascript:" ng-click="importFile()">Import File</a></li>-->
|
<!--<li><a href="javascript:" ng-click="importFile()">Import File</a></li>-->
|
||||||
<li><a href="javascript:" ng-click="exportGpx()">Export GPX</a></li>
|
<li ng-if="padId"><a href="javascript:" ng-click="exportGpx()">Export GPX</a></li>
|
||||||
<li><a href="javascript:" ng-click="showTable()">View as table</a></li>
|
<li ng-if="padId"><a href="javascript:" ng-click="showTable()">View as table</a></li>
|
||||||
<li ng-if="!readonly"><a href="javascript:" ng-click="editPadSettings()">Settings</a></li>
|
<li ng-if="!readonly && padId"><a href="javascript:" ng-click="editPadSettings()">Settings</a></li>
|
||||||
<li><a href="javascript:" ng-click="showAbout()">About FacilPad</a></li>
|
<li><a href="javascript:" ng-click="showAbout()">About FacilPad</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -43,6 +43,10 @@
|
||||||
map.aboutUi.showAbout();
|
map.aboutUi.showAbout();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
scope.startPad = function() {
|
||||||
|
map.padUi.createPad();
|
||||||
|
};
|
||||||
|
|
||||||
var ret = {
|
var ret = {
|
||||||
div: $($templateCache.get("map/toolbox/toolbox.html"))
|
div: $($templateCache.get("map/toolbox/toolbox.html"))
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
return function(padId) {
|
return function(padId) {
|
||||||
var scope = $rootScope.$new();
|
var scope = $rootScope.$new();
|
||||||
|
|
||||||
scope.padId = padId;
|
|
||||||
scope.padData = null;
|
scope.padData = null;
|
||||||
scope.readonly = null;
|
scope.readonly = null;
|
||||||
scope.markers = { };
|
scope.markers = { };
|
||||||
|
@ -41,16 +40,21 @@
|
||||||
return socket.emit.apply(socket, arguments);
|
return socket.emit.apply(socket, arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
scope.on("serverError", function(data) {
|
||||||
|
scope.serverError = data;
|
||||||
|
});
|
||||||
|
|
||||||
scope.on("padData", function(data) {
|
scope.on("padData", function(data) {
|
||||||
scope.padData = data;
|
scope.padData = data;
|
||||||
|
|
||||||
if(data.writable != null)
|
if(data.writable != null)
|
||||||
scope.readonly = !data.writable;
|
scope.readonly = !data.writable;
|
||||||
|
|
||||||
scope.disconnected = false;
|
var id = scope.readonly ? data.id : data.writeId;
|
||||||
|
if(id != null)
|
||||||
|
scope.padId = id;
|
||||||
|
|
||||||
if(!scope.loaded)
|
scope.disconnected = false;
|
||||||
scope.loaded = true;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
scope.on("marker", function(data) {
|
scope.on("marker", function(data) {
|
||||||
|
@ -128,17 +132,31 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
scope.on("reconnect", function() {
|
scope.on("reconnect", function() {
|
||||||
|
if(scope.padId)
|
||||||
scope.emit("setPadId", scope.padId);
|
scope.emit("setPadId", scope.padId);
|
||||||
|
else
|
||||||
|
scope.disconnected = false; // Otherwise it gets set when padData arrives
|
||||||
|
|
||||||
|
if(scope.bbox)
|
||||||
scope.emit("updateBbox", scope.bbox);
|
scope.emit("updateBbox", scope.bbox);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
scope.setPadId = function(padId) {
|
||||||
|
if(scope.padId != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
scope.padId = padId;
|
||||||
|
scope.emit("setPadId", padId);
|
||||||
|
};
|
||||||
|
|
||||||
scope.updateBbox = function(bbox) {
|
scope.updateBbox = function(bbox) {
|
||||||
scope.emit("updateBbox", bbox);
|
scope.emit("updateBbox", bbox);
|
||||||
|
|
||||||
scope.bbox = bbox;
|
scope.bbox = bbox;
|
||||||
};
|
};
|
||||||
|
|
||||||
scope.emit("setPadId", scope.padId);
|
if(padId)
|
||||||
|
scope.setPadId(padId);
|
||||||
|
|
||||||
scope.$on("$destroy", function() {
|
scope.$on("$destroy", function() {
|
||||||
socket.removeAllListeners();
|
socket.removeAllListeners();
|
||||||
|
|
|
@ -7,9 +7,12 @@
|
||||||
var LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
var LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
var LENGTH = 12;
|
var LENGTH = 12;
|
||||||
|
|
||||||
fpUtils.generateRandomPadId = function() {
|
fpUtils.generateRandomPadId = function(length) {
|
||||||
|
if(length == null)
|
||||||
|
length = LENGTH;
|
||||||
|
|
||||||
var randomPadId = "";
|
var randomPadId = "";
|
||||||
for(var i=0; i<LENGTH; i++) {
|
for(var i=0; i<length; i++) {
|
||||||
randomPadId += LETTERS[Math.floor(Math.random() * LETTERS.length)];
|
randomPadId += LETTERS[Math.floor(Math.random() * LETTERS.length)];
|
||||||
}
|
}
|
||||||
return randomPadId;
|
return randomPadId;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<html ng-controller="PadCtrl">
|
<html ng-controller="PadCtrl">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title fp-title="padName + ' – FacilPad'">FacilPad</title>
|
<title fp-title="padName ? padName + ' – FacilPad' : 'FacilPad'">FacilPad</title>
|
||||||
<meta name="robots" content="index,nofollow" />
|
<meta name="robots" content="index,nofollow" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||||
<link rel="shortcut icon" href="assets/img/favicon.png">
|
<link rel="shortcut icon" href="assets/img/favicon.png">
|
||||||
|
@ -20,61 +20,17 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="introContainer">
|
|
||||||
<h1>FacilPad</h1>
|
|
||||||
<p>Welcome to FacilPad.</p>
|
|
||||||
<noscript><p><strong>FacilPad requires JavaScript to work.</strong></p></noscript>
|
<noscript><p><strong>FacilPad requires JavaScript to work.</strong></p></noscript>
|
||||||
<p><a id="create-pad-link" rel="nofollow">Create a new pad</a></p>
|
<div id="loading" ng-if="false">Loading...</div>
|
||||||
</div>
|
|
||||||
<div id="loading" style="display:none">Loading...</div>
|
|
||||||
<div id="mapContainer" style="display:none">
|
|
||||||
<div id="map" fp-map fp-pad-id="{{padId}}"></div>
|
<div id="map" fp-map fp-pad-id="{{padId}}"></div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
var interval = setInterval(function() {
|
||||||
var loaded = 0;
|
if(window.angular != null && window.io != null) {
|
||||||
|
|
||||||
var l = document.getElementById("create-pad-link");
|
|
||||||
|
|
||||||
var LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
||||||
var LENGTH = 12;
|
|
||||||
|
|
||||||
var randomPadId = "";
|
|
||||||
for(var i=0; i<LENGTH; i++) {
|
|
||||||
randomPadId += LETTERS[Math.floor(Math.random() * LETTERS.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
l.href = randomPadId;
|
|
||||||
|
|
||||||
l.onclick = function() {
|
|
||||||
if(window.history && history.pushState) {
|
|
||||||
history.pushState(null, null, randomPadId);
|
|
||||||
check();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var interval = setInterval(check, 100);
|
|
||||||
|
|
||||||
function check() {
|
|
||||||
if(loaded == 0 && !location.pathname.match(/\/$/)) {
|
|
||||||
document.getElementById("introContainer").style.display = "none";
|
|
||||||
document.getElementById("loading").style.display = "";
|
|
||||||
|
|
||||||
loaded = 1;
|
|
||||||
}
|
|
||||||
if(loaded == 1 && window.FacilPad != null && window.io != null && $("#map").css("height") == "100%") {
|
|
||||||
$("#introContainer,#loading").remove();
|
|
||||||
$("#map").unwrap();
|
|
||||||
angular.bootstrap(document, [ "facilpad" ]);
|
|
||||||
loaded = 2;
|
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
|
angular.bootstrap(document, [ "facilpad" ]);
|
||||||
}
|
}
|
||||||
}
|
}, 100);
|
||||||
|
|
||||||
check();
|
|
||||||
})();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- inject:js -->
|
<!-- inject:js -->
|
||||||
|
|
|
@ -16,22 +16,29 @@ function getPadData(padId, callback) {
|
||||||
if(err)
|
if(err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
else if(data != null)
|
else if(data != null)
|
||||||
return callback(null, utils.extend(JSON.parse(JSON.stringify(data)), { writable: true, writeId: null }));
|
return callback(null, utils.extend(JSON.parse(JSON.stringify(data)), { writable: true }));
|
||||||
|
|
||||||
backend.getPadData(padId, function(err, data) {
|
backend.getPadData(padId, function(err, data) {
|
||||||
if(err || data != null)
|
if(err)
|
||||||
return callback(err, utils.extend(JSON.parse(JSON.stringify(data)), { writable: false, writeId: null }));
|
return callback(err);
|
||||||
|
|
||||||
backend.createPad(utils.generateRandomId(10), padId, function(err, data) {
|
if(data == null)
|
||||||
|
return callback("This pad does not exist.");
|
||||||
|
|
||||||
|
return callback(null, utils.extend(JSON.parse(JSON.stringify(data)), { writable: false, writeId: null }));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPad(data, callback) {
|
||||||
|
backend.createPad(data, function(err, data) {
|
||||||
if(err)
|
if(err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
async.each(DEFAULT_TYPES, function(it, next) {
|
async.each(DEFAULT_TYPES, function(it, next) {
|
||||||
backend.createType(data.id, it, next);
|
backend.createType(data.id, it, next);
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
callback(err, utils.extend(JSON.parse(JSON.stringify(data)), { writable: true, writeId: null }));
|
callback(err, utils.extend(JSON.parse(JSON.stringify(data)), { writable: true }));
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -41,7 +48,17 @@ function updatePadData(padId, data, callback) {
|
||||||
if(err)
|
if(err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
listeners.notifyPadListeners(padId, "padData", data);
|
listeners.notifyPadListeners(padId, "padData", function(listener) {
|
||||||
|
var dataClone = JSON.parse(JSON.stringify(data));
|
||||||
|
if(!listener.writable)
|
||||||
|
dataClone.writeId = null;
|
||||||
|
|
||||||
|
return dataClone;
|
||||||
|
});
|
||||||
|
|
||||||
|
if(data.id && data.id != padId)
|
||||||
|
listeners.changePadId(padId, data.id);
|
||||||
|
|
||||||
callback(null, data);
|
callback(null, data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -350,8 +367,8 @@ function _setLinePoints(padId, lineId, trackPoints, callback) {
|
||||||
if(err)
|
if(err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
listeners.notifyPadListeners(padId, "linePoints", function(bboxWithZoom) {
|
listeners.notifyPadListeners(padId, "linePoints", function(listener) {
|
||||||
return { reset: true, id: lineId, trackPoints : (bboxWithZoom ? routing.prepareForBoundingBox(trackPoints, bboxWithZoom) : [ ]) };
|
return { reset: true, id: lineId, trackPoints : (listener && listener.bbox ? routing.prepareForBoundingBox(trackPoints, listener.bbox) : [ ]) };
|
||||||
});
|
});
|
||||||
|
|
||||||
callback(null);
|
callback(null);
|
||||||
|
@ -478,8 +495,8 @@ function _calculateRouting(line, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getMarkerDataFunc(marker) {
|
function _getMarkerDataFunc(marker) {
|
||||||
return function(bbox) {
|
return function(listener) {
|
||||||
if(!bbox || !utils.isInBbox(marker, bbox))
|
if(!listener || !listener.bbox || !utils.isInBbox(marker, listener.bbox))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return marker;
|
return marker;
|
||||||
|
@ -513,6 +530,7 @@ function _getLinePoints(lineId, bboxWithZoom, callback) {
|
||||||
module.exports = {
|
module.exports = {
|
||||||
connect : backend.connect,
|
connect : backend.connect,
|
||||||
getPadData : getPadData,
|
getPadData : getPadData,
|
||||||
|
createPad : createPad,
|
||||||
updatePadData : updatePadData,
|
updatePadData : updatePadData,
|
||||||
getViews : getViews,
|
getViews : getViews,
|
||||||
createView : createView,
|
createView : createView,
|
||||||
|
|
|
@ -62,9 +62,9 @@ function _makeNotNullForeignKey(type, field, error) {
|
||||||
/* Pads */
|
/* Pads */
|
||||||
|
|
||||||
var Pad = conn.define("Pad", {
|
var Pad = conn.define("Pad", {
|
||||||
id : { type: Sequelize.STRING, allowNull: false, unique: "padId", primaryKey: true },
|
id : { type: Sequelize.STRING, allowNull: false, unique: "padId", primaryKey: true, validate: { is: /^.+$/ } },
|
||||||
name: { type: Sequelize.TEXT, allowNull: true, get: function() { return this.getDataValue("name") || "New FacilPad"; } },
|
name: { type: Sequelize.TEXT, allowNull: true, get: function() { return this.getDataValue("name") || "New FacilPad"; } },
|
||||||
writeId: { type: Sequelize.STRING, allowNull: false, unique: "padId" }
|
writeId: { type: Sequelize.STRING, allowNull: false, unique: "padId", validate: { is: /^.+$/ } }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -262,8 +262,8 @@ function getPadDataByWriteId(writeId, callback) {
|
||||||
_promiseComplete(Pad.findOne({ where: { writeId: writeId }, include: [ { model: View, as: "defaultView" } ] }), callback);
|
_promiseComplete(Pad.findOne({ where: { writeId: writeId }, include: [ { model: View, as: "defaultView" } ] }), callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createPad(padId, writeId, callback) {
|
function createPad(data, callback) {
|
||||||
_promiseComplete(Pad.create({ id: padId, writeId: writeId }), callback);
|
_promiseComplete(Pad.create(data), callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePadData(padId, data, callback) {
|
function updatePadData(padId, data, callback) {
|
||||||
|
@ -272,7 +272,7 @@ function updatePadData(padId, data, callback) {
|
||||||
_promiseComplete(Pad.update(data, { where: { id: padId } }), next);
|
_promiseComplete(Pad.update(data, { where: { id: padId } }), next);
|
||||||
},
|
},
|
||||||
function(affectedNumber, next) {
|
function(affectedNumber, next) {
|
||||||
getPadData(padId, next);
|
getPadData(data.id || padId, next);
|
||||||
}
|
}
|
||||||
], callback);
|
], callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ function notifyPadListeners(padId, eventType, getData) {
|
||||||
var isFunc = (typeof getData == "function");
|
var isFunc = (typeof getData == "function");
|
||||||
|
|
||||||
( listeners[padId] || [ ]).forEach(function(listener) {
|
( listeners[padId] || [ ]).forEach(function(listener) {
|
||||||
var data = isFunc ? getData(listener.bbox) : getData;
|
var data = isFunc ? getData(listener) : getData;
|
||||||
if(data == null)
|
if(data == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -34,8 +34,21 @@ function removePadListener(listener) {
|
||||||
listeners[listener.padId] = l.slice(0, idx).concat(l.slice(idx+1));
|
listeners[listener.padId] = l.slice(0, idx).concat(l.slice(idx+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function changePadId(oldPadId, newPadId) {
|
||||||
|
if(oldPadId == newPadId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
listeners[newPadId] = listeners[oldPadId];
|
||||||
|
delete listeners[oldPadId];
|
||||||
|
|
||||||
|
listeners[newPadId].forEach(function(listener) {
|
||||||
|
listener.padId = newPadId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
notifyPadListeners : notifyPadListeners,
|
notifyPadListeners : notifyPadListeners,
|
||||||
addPadListener : addPadListener,
|
addPadListener : addPadListener,
|
||||||
removePadListener: removePadListener
|
removePadListener: removePadListener,
|
||||||
|
changePadId: changePadId
|
||||||
};
|
};
|
|
@ -66,19 +66,7 @@ database.connect(function(err) {
|
||||||
if(err)
|
if(err)
|
||||||
return _sendData(socket, "padData", err);
|
return _sendData(socket, "padData", err);
|
||||||
|
|
||||||
socket.padId = data.id;
|
_setPadId(socket, data);
|
||||||
socket.writable = data.writable;
|
|
||||||
listeners.addPadListener(socket);
|
|
||||||
|
|
||||||
_sendData(socket, "padData", null, data);
|
|
||||||
_sendStreamData(socket, "view", database.getViews(socket.padId));
|
|
||||||
_sendStreamData(socket, "type", database.getTypes(socket.padId));
|
|
||||||
_sendStreamData(socket, "line", database.getPadLines(socket.padId));
|
|
||||||
|
|
||||||
if(socket.bbox) { // In case bbox is set while fetching pad data
|
|
||||||
_sendStreamData(socket, "marker", database.getPadMarkers(socket.padId, socket.bbox));
|
|
||||||
_sendStreamData(socket, "linePoints", database.getLinePoints(socket.padId, socket.bbox));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -103,8 +91,25 @@ database.connect(function(err) {
|
||||||
listeners.removePadListener(socket);
|
listeners.removePadListener(socket);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
createPad : function(data, callback) {
|
||||||
|
if(!utils.stripObject(data, { name: "string", defaultViewId: "number", id: "string", writeId: "string" }))
|
||||||
|
return callback("Invalid parameters.");
|
||||||
|
|
||||||
|
if(socket.padId)
|
||||||
|
return callback("Pad already loaded.");
|
||||||
|
|
||||||
|
database.createPad(data, function(err, padData) {
|
||||||
|
if(err)
|
||||||
|
return callback(err);
|
||||||
|
|
||||||
|
_setPadId(socket, padData);
|
||||||
|
|
||||||
|
callback(null, padData);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
editPad : function(data, callback) {
|
editPad : function(data, callback) {
|
||||||
if(!utils.stripObject(data, { name: "string", defaultViewId: "number" }))
|
if(!utils.stripObject(data, { name: "string", defaultViewId: "number", id: "string", writeId: "string" }))
|
||||||
return callback("Invalid parameters.");
|
return callback("Invalid parameters.");
|
||||||
|
|
||||||
if(!socket.writable)
|
if(!socket.writable)
|
||||||
|
@ -241,6 +246,9 @@ database.connect(function(err) {
|
||||||
},
|
},
|
||||||
|
|
||||||
exportGpx : function(data, callback) {
|
exportGpx : function(data, callback) {
|
||||||
|
if(socket.padId == null)
|
||||||
|
return callback("No pad ID set.");
|
||||||
|
|
||||||
gpx.exportGpx(socket.padId, data.useTracks, callback);
|
gpx.exportGpx(socket.padId, data.useTracks, callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -278,7 +286,9 @@ database.connect(function(err) {
|
||||||
function _sendData(socket, eventName, err, data) {
|
function _sendData(socket, eventName, err, data) {
|
||||||
if(err) {
|
if(err) {
|
||||||
console.warn("_sendData", err, err.stack);
|
console.warn("_sendData", err, err.stack);
|
||||||
return socket.emit("error", err);
|
socket.emit("serverError", err);
|
||||||
|
socket.disconnect();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.emit(eventName, data);
|
socket.emit(eventName, data);
|
||||||
|
@ -293,3 +303,19 @@ function _sendStreamData(socket, eventName, stream) {
|
||||||
socket.emit("error", err);
|
socket.emit("error", err);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _setPadId(socket, data) {
|
||||||
|
socket.padId = data.id;
|
||||||
|
socket.writable = data.writable;
|
||||||
|
listeners.addPadListener(socket);
|
||||||
|
|
||||||
|
_sendData(socket, "padData", null, data);
|
||||||
|
_sendStreamData(socket, "view", database.getViews(socket.padId));
|
||||||
|
_sendStreamData(socket, "type", database.getTypes(socket.padId));
|
||||||
|
_sendStreamData(socket, "line", database.getPadLines(socket.padId));
|
||||||
|
|
||||||
|
if(socket.bbox) { // In case bbox is set while fetching pad data
|
||||||
|
_sendStreamData(socket, "marker", database.getPadMarkers(socket.padId, socket.bbox));
|
||||||
|
_sendStreamData(socket, "linePoints", database.getLinePoints(socket.padId, socket.bbox));
|
||||||
|
}
|
||||||
|
}
|
Ładowanie…
Reference in New Issue