diff --git a/www/js/services/utils-services.js b/www/js/services/utils-services.js
index af46cf9b0f6d2ea46a480630fba3b5444ec6da7c..5a058037662fb25f88b06294fa364a945d4f78e5 100644
--- a/www/js/services/utils-services.js
+++ b/www/js/services/utils-services.js
@@ -26,17 +26,17 @@ angular.module('cesium.utils.services', [])
var
loadingTextCache=null,
CONST = {
- MAX_HEIGHT: 400,
- MAX_WIDTH: 400,
- THUMB_MAX_HEIGHT: 100,
- THUMB_MAX_WIDTH: 100
+ MAX_HEIGHT: 480,
+ MAX_WIDTH: 640,
+ THUMB_MAX_HEIGHT: 200,
+ THUMB_MAX_WIDTH: 200
},
data = {
smallscreen: screenmatch.bind('xs, sm', $rootScope)
},
exports,
raw = {}
- ;
+ ;
function alertError(err, subtitle) {
if (!err) {
@@ -45,45 +45,45 @@ angular.module('cesium.utils.services', [])
return $q(function(resolve) {
$translate([err, subtitle, 'ERROR.POPUP_TITLE', 'ERROR.UNKNOWN_ERROR', 'COMMON.BTN_OK'])
- .then(function (translations) {
- var message = err.message || translations[err];
- return $ionicPopup.show({
- template: '<p>' + (message || translations['ERROR.UNKNOWN_ERROR']) + '</p>',
- title: translations['ERROR.POPUP_TITLE'],
- subTitle: translations[subtitle],
- buttons: [
- {
- text: '<b>'+translations['COMMON.BTN_OK']+'</b>',
- type: 'button-assertive',
- onTap: function(e) {
- resolve(e);
+ .then(function (translations) {
+ var message = err.message || translations[err];
+ return $ionicPopup.show({
+ template: '<p>' + (message || translations['ERROR.UNKNOWN_ERROR']) + '</p>',
+ title: translations['ERROR.POPUP_TITLE'],
+ subTitle: translations[subtitle],
+ buttons: [
+ {
+ text: '<b>'+translations['COMMON.BTN_OK']+'</b>',
+ type: 'button-assertive',
+ onTap: function(e) {
+ resolve(e);
+ }
}
- }
- ]
+ ]
+ });
});
- });
});
}
function alertInfo(message, subtitle) {
return $q(function(resolve) {
$translate([message, subtitle, 'INFO.POPUP_TITLE', 'COMMON.BTN_OK'])
- .then(function (translations) {
- $ionicPopup.show({
- template: '<p>' + translations[message] + '</p>',
- title: translations['INFO.POPUP_TITLE'],
- subTitle: translations[subtitle],
- buttons: [
- {
- text: translations['COMMON.BTN_OK'],
- type: 'button-positive',
- onTap: function(e) {
- resolve(e);
+ .then(function (translations) {
+ $ionicPopup.show({
+ template: '<p>' + translations[message] + '</p>',
+ title: translations['INFO.POPUP_TITLE'],
+ subTitle: translations[subtitle],
+ buttons: [
+ {
+ text: translations['COMMON.BTN_OK'],
+ type: 'button-positive',
+ onTap: function(e) {
+ resolve(e);
+ }
}
- }
- ]
+ ]
+ });
});
- });
});
}
@@ -243,41 +243,82 @@ angular.module('cesium.utils.services', [])
function getSelectionText(){
var selectedText = "";
if (window.getSelection){ // all modern browsers and IE9+
- selectedText = $window.getSelection().toString();
+ selectedText = $window.getSelection().toString();
}
return selectedText;
}
function imageOnLoadResize(resolve, reject, thumbnail) {
return function(event) {
- var width = event.target.width;
- var height = event.target.height;
- var maxWidth = (thumbnail ? CONST.THUMB_MAX_WIDTH : CONST.MAX_WIDTH);
- var maxHeight = (thumbnail ? CONST.THUMB_MAX_HEIGHT : CONST.MAX_HEIGHT);
-
- if (width > height) {
- if (width > maxWidth) {
- height *= maxWidth / width;
- width = maxWidth;
- }
- } else {
- if (height > maxHeight) {
- width *= maxHeight / height;
- height = maxHeight;
- }
+ var width = event.target.width,
+ height = event.target.height,
+ maxWidth = (thumbnail ? CONST.THUMB_MAX_WIDTH : CONST.MAX_WIDTH),
+ maxHeight = (thumbnail ? CONST.THUMB_MAX_HEIGHT : CONST.MAX_HEIGHT)
+ ;
+
+ var canvas = document.createElement("canvas");
+ var ctx;
+
+ // Thumbnail: resize and crop (to the expected size)
+ if (thumbnail) {
+
+ // landscape
+ if (width > height) {
+ width *= maxHeight / height;
+ height = maxHeight;
+ }
+
+ // portrait
+ else {
+ height *= maxWidth / width;
+ width = maxWidth;
+ }
+ canvas.width = maxWidth;
+ canvas.height = maxHeight;
+ ctx = canvas.getContext("2d");
+ var xoffset = Math.trunc((maxWidth - width) / 2 + 0.5);
+ var yoffset = Math.trunc((maxHeight - height) / 2 + 0.5);
+ ctx.drawImage(event.target,
+ xoffset, // x1
+ yoffset, // y1
+ maxWidth + -2 * xoffset, // x2
+ maxHeight + -2 * yoffset // y2
+ );
+ }
+
+ // Resize, but keep the full image
+ else {
+
+ // landscape
+ if (width > height) {
+ if (width > maxWidth) {
+ height *= maxWidth / width;
+ width = maxWidth;
}
- var canvas = document.createElement("canvas");
- canvas.width = width;
- canvas.height = height;
- var ctx = canvas.getContext("2d");
- ctx.drawImage(event.target, 0, 0, canvas.width, canvas.height);
+ }
- var dataurl = canvas.toDataURL();
+ // portrait
+ else {
+ if (height > maxHeight) {
+ width *= maxHeight / height;
+ height = maxHeight;
+ }
+ }
- canvas.remove();
+ canvas.width = width;
+ canvas.height = height;
+ ctx = canvas.getContext("2d");
- resolve(dataurl);
- };
+ // Resize the whole image
+ ctx.drawImage(event.target, 0, 0, canvas.width, canvas.height);
+ }
+
+ var dataurl = canvas.toDataURL();
+
+ canvas.remove();
+
+ resolve(dataurl);
+ };
}
function resizeImageFromFile(file, thumbnail) {
@@ -387,34 +428,34 @@ angular.module('cesium.utils.services', [])
angular.merge(popover.scope, options.bindings);
$timeout(function() { // This is need for Firefox
popover.show(event)
- .then(function() {
- var element;
- // Auto select text
- if (options.autoselect) {
- element = document.querySelectorAll(options.autoselect)[0];
- if (element) {
- if ($window.getSelection && !$window.getSelection().toString()) {
- element.setSelectionRange(0, element.value.length);
- element.focus();
- }
- else {
- element.focus();
+ .then(function() {
+ var element;
+ // Auto select text
+ if (options.autoselect) {
+ element = document.querySelectorAll(options.autoselect)[0];
+ if (element) {
+ if ($window.getSelection && !$window.getSelection().toString()) {
+ element.setSelectionRange(0, element.value.length);
+ element.focus();
+ }
+ else {
+ element.focus();
+ }
}
}
- }
- else {
- // Auto focus on a element
- if (options.autofocus) {
- element = document.querySelectorAll(options.autofocus)[0];
- if (element) element.focus();
+ else {
+ // Auto focus on a element
+ if (options.autofocus) {
+ element = document.querySelectorAll(options.autofocus)[0];
+ if (element) element.focus();
+ }
}
- }
- popover.scope.$parent.$emit('popover.shown');
+ popover.scope.$parent.$emit('popover.shown');
- // Callback 'afterShow'
- if (options.afterShow) options.afterShow(popover);
- });
+ // Callback 'afterShow'
+ if (options.afterShow) options.afterShow(popover);
+ });
});
};
@@ -424,9 +465,9 @@ angular.module('cesium.utils.services', [])
delete options.scope.popovers[options.templateUrl];
// Remove the popover
popover.remove()
- // Workaround for issue #244
- // See also https://github.com/driftyco/ionic-v1/issues/71
- // and https://github.com/driftyco/ionic/issues/9069
+ // Workaround for issue #244
+ // See also https://github.com/driftyco/ionic-v1/issues/71
+ // and https://github.com/driftyco/ionic/issues/9069
.then(function() {
var bodyEl = angular.element($window.document.querySelectorAll('body')[0]);
bodyEl.removeClass('popover-open');
@@ -628,7 +669,7 @@ angular.module('cesium.utils.services', [])
function motionDelegate(delegate, ionListClass) {
var motionTimeout = isSmallScreen() ? 100 : 10;
var defaultSelector = '.list.{0} .item, .list .{0} .item'.format(ionListClass, ionListClass);
- return {
+ return {
ionListClass: ionListClass,
show: function(options) {
options = options || {};
@@ -688,8 +729,8 @@ angular.module('cesium.utils.services', [])
ripple: motionDelegate(ionicMaterialMotion.ripple, 'animate-ripple'),
slideUp: motionDelegate(ionicMaterialMotion.slideUp, 'slide-up'),
fadeIn: motionDelegate(function(options) {
- toggleOn(options);
- }, 'fade-in'),
+ toggleOn(options);
+ }, 'fade-in'),
toggleOn: toggleOn,
toggleOff: toggleOff
};
@@ -743,10 +784,8 @@ angular.module('cesium.utils.services', [])
}, timeout || 900);
}
-
-
csSettings.api.data.on.changed($rootScope, function(data) {
- setEffects(data.uiEffects);
+ setEffects(data.uiEffects);
});
exports = {
diff --git a/www/plugins/es/js/controllers/common-controllers.js b/www/plugins/es/js/controllers/common-controllers.js
index 330c40e0aa69c5ffb8e93fbb7b9cfdf2b650544e..5b4e5bde214ac36ccacbff5079bb8a24f5e5f841 100644
--- a/www/plugins/es/js/controllers/common-controllers.js
+++ b/www/plugins/es/js/controllers/common-controllers.js
@@ -51,19 +51,23 @@ function ESPicturesEditController($scope, UIUtils, $q, Device) {
};
$scope.fileChanged = function(event) {
+ if (!event.target.files || !event.target.files.length) return;
UIUtils.loading.show();
- return $q(function(resolve, reject) {
- var file = event.target.files[0];
- UIUtils.image.resizeFile(file)
- .then(function(imageData) {
- $scope.pictures.push({
- src: imageData,
- isnew: true // use to prevent visibility hidden (if animation)
- });
- UIUtils.loading.hide(100);
- resolve();
+ var file = event.target.files[0];
+ return UIUtils.image.resizeFile(file)
+ .then(function(imageData) {
+ $scope.pictures.push({
+ src: imageData,
+ isnew: true // use to prevent visibility hidden (if animation)
});
- });
+ event.target.value = ""; // reset input[type=file]
+ UIUtils.loading.hide(100);
+ })
+ .catch(function(err) {
+ console.error(err);
+ event.target.value = ""; // reset input[type=file]
+ UIUtils.loading.hide();
+ });
};
$scope.removePicture = function(index){
@@ -141,7 +145,7 @@ function ESCategoryModalController($scope, UIUtils, $timeout, parameters) {
-function ESCommentsController($scope, $filter, $state, $focus, UIUtils) {
+function ESCommentsController($scope, $filter, $state, $focus, $timeout, $anchorScroll, UIUtils) {
'ngInject';
$scope.loading = true;
@@ -150,8 +154,12 @@ function ESCommentsController($scope, $filter, $state, $focus, UIUtils) {
$scope.comments = {};
$scope.$on('$recordView.enter', function(e, state) {
+ // First enter
+ if ($scope.loading) {
+ $scope.anchor = state && state.stateParams.anchor;
+ }
// second call (when using cached view)
- if (!$scope.loading && $scope.id) {
+ else if (!$scope.loading && $scope.id) {
$scope.load($scope.id, {animate: false});
}
});
@@ -159,15 +167,21 @@ function ESCommentsController($scope, $filter, $state, $focus, UIUtils) {
$scope.$on('$recordView.load', function(event, id, service) {
$scope.id = id || $scope.id;
$scope.service = service || $scope.service;
- console.debug("[ES] [comment] Initialized service with: " + service.id);
+ console.debug("[ES] [comment] Will use {" + service.index + "} service");
if ($scope.id) {
- $scope.load($scope.id);
+ $scope.load($scope.id)
+ .then(function() {
+ // Scroll to anchor
+ $scope.scrollToAnchor();
+ });
}
});
$scope.load = function(id, options) {
options = options || {};
options.from = options.from || 0;
+ // If anchor has been defined, load all comments
+ options.size = options.size || ($scope.anchor && -1/*all*/);
options.size = options.size || $scope.defaultCommentSize;
options.animate = angular.isDefined(options.animate) ? options.animate : true;
options.loadAvatarAllParent = angular.isDefined(options.loadAvatarAllParent) ? options.loadAvatarAllParent : true;
@@ -202,6 +216,25 @@ function ESCommentsController($scope, $filter, $state, $focus, UIUtils) {
}
});
+ $scope.scrollToAnchor = function() {
+ if (!$scope.anchor) return;
+ var elemList = document.getElementsByName($scope.anchor);
+ // Waiting for the element
+ if (!elemList || !elemList.length) {
+ return $timeout($scope.scrollToAnchor, 500);
+ }
+ // If many, remove all anchor except the last one
+ for (var i = 0; i<elemList.length-1; i++) {
+ angular.element(elemList[i]).remove();
+ }
+ // Scroll to the anchor
+ $anchorScroll($scope.anchor);
+ // Remove the anchor. This will the CSS class 'positive-100-bg' on the comment
+ $timeout(function () {
+ $scope.anchor = null;
+ }, 1500);
+ };
+
$scope.showMore = function(){
var from = 0;
var size = -1;
@@ -355,8 +388,6 @@ function ESSocialsEditController($scope, $focus, $filter, UIUtils, SocialUtils)
selector: '#social-' + $filter('formatSlug')(social.url),
startVelocity: 10000
});
-
-
};
$scope.editSocialNetwork = function(index) {
@@ -381,9 +412,9 @@ function ESSocialsEditController($scope, $focus, $filter, UIUtils, SocialUtils)
function ESSocialsViewController($scope) {
'ngInject';
- $scope.openSocial = function($event, social) {
- $event.stopPropagation();
- return $scope.openLink($event, social.url, {
+ $scope.openSocial = function(event, social) {
+ event.stopPropagation();
+ return $scope.openLink(event, social.url, {
type: social.type
});
};
@@ -482,7 +513,6 @@ function ESPositionEditController($scope, csConfig, esGeo, ModalUtils) {
.catch(function(err) {
console.error(err); // Silent
loadingCurrentPosition = false;
- //$scope.form.geoPoint.$setValidity('required', false);
});
}
@@ -507,22 +537,24 @@ function ESPositionEditController($scope, csConfig, esGeo, ModalUtils) {
});
};
- $scope.onCityChanged = function() {
- if ($scope.loading) return;
- if ($scope.form) {
- $scope.form.$valid = undefined;
- }
- if ($scope.formPosition.enable) {
- return $scope.tryToLocalize();
- }
- };
+ $scope.onCityChanged = function() {
+ if ($scope.loading) return;
+ if ($scope.formPosition.enable) {
+ if ($scope.formData.geoPoint) {
+ // Invalidate the position
+ $scope.formData.geoPoint.lat = undefined;
+ $scope.formData.geoPoint.lon = undefined;
+ }
+ return $scope.tryToLocalize();
+ }
+ };
$scope.onUseGeopointChanged = function() {
if ($scope.loading) return;
if (!$scope.formPosition.enable) {
if ($scope.formData.geoPoint) {
- $scope.formData.geoPoint = null;
- //$scope.form.geoPoint.$setValidity('required', true);
+ $scope.formData.geoPoint.lat = undefined;
+ $scope.formData.geoPoint.lon = undefined;
$scope.dirty = true;
}
}
@@ -696,7 +728,7 @@ function ESLookupPositionController($scope, $q, csConfig, esGeo, ModalUtils) {
};
}
-function ESSearchPositionItemController($scope, $q, $timeout, ModalUtils, csConfig, esGeo) {
+function ESSearchPositionItemController($scope, $timeout, ModalUtils, csConfig, esGeo) {
'ngInject';
// The default country used for address localisation
@@ -780,15 +812,20 @@ function ESSearchPositionItemController($scope, $q, $timeout, ModalUtils, csConf
$scope.showDropdown = function() {
var text = $scope.search.location && $scope.search.location.trim();
if (!text || text.length < minLength) {
- $scope.locations = undefined;
- return $q.when(); // nothing to search
+ return $scope.hideDropdown(true/*force, if still loading*/);
}
+ // Compute a request id, to apply response only if current request
+ var requestId = ($scope.requestId && $scope.requestId + 1) || 1;
+ $scope.requestId = requestId;
+
loadingPosition = true;
// Execute the given query
return esGeo.point.searchByAddress(text)
.then(function(res) {
+ if ($scope.requestId != requestId) return; // Skip apply if not same request:
+
loadingPosition = false;
$scope.locations = res||[];
$scope.license = res && res.length && res[0].license;
@@ -800,6 +837,7 @@ function ESSearchPositionItemController($scope, $q, $timeout, ModalUtils, csConf
};
$scope.hideDropdown = function(force) {
+ // force, even if still loading
if (force) {
$scope.locations = undefined;
$scope.selectLocationIndex = -1;
diff --git a/www/plugins/map/js/controllers/user-controllers.js b/www/plugins/map/js/controllers/user-controllers.js
index 9fff394e579b9fed2a53f95ccdf11c76feb01ac6..5b429c2e5ed9531fca8050bdfbaca42372a7a01d 100644
--- a/www/plugins/map/js/controllers/user-controllers.js
+++ b/www/plugins/map/js/controllers/user-controllers.js
@@ -9,7 +9,16 @@ angular.module('cesium.map.user.controllers', ['cesium.services', 'cesium.map.se
PluginServiceProvider
- .extendState('app.user_edit_profile', {
+ .extendState('app.edit_profile', {
+ points: {
+ 'after-position': {
+ templateUrl: 'plugins/map/templates/user/edit_profile_extend.html',
+ controller: 'MapEditProfileViewCtrl'
+ }
+ }
+ })
+
+ .extendState('app.edit_profile_by_id', {
points: {
'after-position': {
templateUrl: 'plugins/map/templates/user/edit_profile_extend.html',