Files
cloudron-box/src/views/settings.js

447 lines
14 KiB
JavaScript
Raw Normal View History

2018-01-22 13:01:38 -08:00
'use strict';
angular.module('Application').controller('SettingsController', ['$scope', '$location', '$rootScope', '$timeout', 'Client', 'AppStore', function ($scope, $location, $rootScope, $timeout, Client, AppStore) {
2018-08-03 10:09:04 -07:00
Client.onReady(function () { if (!Client.getUserInfo().admin) $location.path('/'); });
2018-01-22 13:01:38 -08:00
$scope.client = Client;
$scope.user = Client.getUserInfo();
$scope.config = Client.getConfig();
$scope.caasConfig = {};
2018-01-22 13:01:38 -08:00
$scope.appstoreConfig = {};
$scope.installedApps = Client.getInstalledApps();
2018-01-22 13:01:38 -08:00
$scope.currency = null;
$scope.availableRegions = [];
$scope.currentRegionSlug = null;
$scope.availablePlans = [];
$scope.currentPlan = null;
$scope.subscription = null;
2018-01-22 13:01:38 -08:00
2018-03-09 00:32:34 -08:00
$scope.prettyProviderName = function (provider) {
switch (provider) {
case 'caas': return 'Managed Cloudron';
default: return provider;
2018-03-09 00:32:34 -08:00
}
};
$scope.update = {
error: {},
busy: false,
show: function (form) {
$scope.update.error.generic = null;
$scope.update.busy = false;
form.$setPristine();
form.$setUntouched();
if (!$scope.config.update.box.sourceTarballUrl) {
$('#setupSubscriptionModal').modal('show');
} else {
$('#updateModal').modal('show');
}
},
submit: function () {
$scope.update.error.generic = null;
$scope.update.busy = true;
Client.update(function (error) {
if (error) {
if (error.statusCode === 409) {
$scope.update.error.generic = 'Please try again later. The Cloudron is creating a backup at the moment.';
} else {
$scope.update.error.generic = error.message;
console.error('Unable to update.', error);
}
$scope.update.busy = false;
return;
}
window.location.href = '/update.html';
});
}
};
2018-01-22 13:01:38 -08:00
$scope.planChange = {
busy: false,
error: {},
password: '',
requestedPlan: null,
showChangePlan: function () {
$('#planChangeModal').modal('show');
},
planChangeReset: function () {
$scope.planChange.error.password = null;
$scope.planChange.password = '';
$scope.planChangeForm.$setPristine();
$scope.planChangeForm.$setUntouched();
},
doChangePlan: function () {
$scope.planChange.busy = true;
var options = {
size: $scope.planChange.requestedPlan.slug,
name: $scope.planChange.requestedPlan.name,
price: $scope.planChange.requestedPlan.price,
region: $scope.currentRegionSlug
};
Client.changePlan(options, $scope.planChange.password, function (error) {
$scope.planChange.busy = false;
if (error) {
2018-06-18 18:57:00 -07:00
if (error.statusCode === 403) {
2018-01-22 13:01:38 -08:00
$scope.planChange.error.password = true;
$scope.planChange.password = '';
$scope.planChangeForm.password.$setPristine();
$('#inputPlanChangePassword').focus();
} else {
console.error('Unable to change plan.', error);
}
} else {
$scope.planChange.planChangeReset();
$('#planChangeModal').modal('hide');
window.location.href = '/update.html';
}
$scope.planChange.busy = false;
});
}
};
$scope.avatarChange = {
busy: false,
error: {},
avatar: null,
availableAvatars: [{
file: null,
data: null,
url: '/img/avatars/avatar_0.png',
}, {
file: null,
data: null,
url: '/img/avatars/rubber-duck.png'
}, {
file: null,
data: null,
url: '/img/avatars/carrot.png'
}, {
file: null,
data: null,
url: '/img/avatars/cup.png'
}, {
file: null,
data: null,
url: '/img/avatars/football.png'
}, {
file: null,
data: null,
url: '/img/avatars/owl.png'
}, {
file: null,
data: null,
url: '/img/avatars/space-rocket.png'
}, {
file: null,
data: null,
url: '/img/avatars/armchair.png'
}, {
file: null,
data: null,
url: '/img/avatars/cap.png'
}, {
file: null,
data: null,
url: '/img/avatars/pan.png'
}, {
file: null,
data: null,
url: '/img/avatars/meat.png'
}, {
file: null,
data: null,
url: '/img/avatars/umbrella.png'
}, {
file: null,
data: null,
url: '/img/avatars/jar.png'
}],
getBlobFromImg: function (img, callback) {
var size = 256;
var canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
var imageDimensionRatio = img.width / img.height;
var canvasDimensionRatio = canvas.width / canvas.height;
var renderableHeight, renderableWidth, xStart, yStart;
if (imageDimensionRatio > canvasDimensionRatio) {
renderableHeight = canvas.height;
renderableWidth = img.width * (renderableHeight / img.height);
xStart = (canvas.width - renderableWidth) / 2;
yStart = 0;
} else if (imageDimensionRatio < canvasDimensionRatio) {
renderableWidth = canvas.width;
renderableHeight = img.height * (renderableWidth / img.width);
xStart = 0;
yStart = (canvas.height - renderableHeight) / 2;
} else {
renderableHeight = canvas.height;
renderableWidth = canvas.width;
xStart = 0;
yStart = 0;
}
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, xStart, yStart, renderableWidth, renderableHeight);
canvas.toBlob(callback);
},
doChangeAvatar: function () {
$scope.avatarChange.error.avatar = null;
$scope.avatarChange.busy = true;
var img = document.getElementById('previewAvatar');
$scope.avatarChange.avatar.file = $scope.avatarChange.getBlobFromImg(img, function (blob) {
Client.changeCloudronAvatar(blob, function (error) {
if (error) {
console.error('Unable to change cloudron avatar.', error);
} else {
Client.resetAvatar();
}
$('#avatarChangeModal').modal('hide');
$scope.avatarChange.avatarChangeReset();
});
});
},
setPreviewAvatar: function (avatar) {
$scope.avatarChange.avatar = avatar;
},
avatarChangeReset: function () {
$scope.avatarChange.error.avatar = null;
$scope.avatarChange.avatar = null;
$scope.avatarChange.busy = false;
},
showChangeAvatar: function () {
$scope.avatarChange.avatarChangeReset();
$('#avatarChangeModal').modal('show');
},
showCustomAvatarSelector: function () {
$('#avatarFileInput').click();
}
};
$scope.s3like = function (provider) {
return provider === 's3' || provider === 'minio' || provider === 's3-v4-compat' || provider === 'exoscale-sos' || provider === 'digitalocean-spaces';
};
$scope.autoUpdate = {
busy: false,
success: false,
error: '',
pattern: '',
currentPattern: '',
checkNow: function () {
$scope.autoUpdate.busy = true;
Client.checkForUpdates(function (error) {
if (error) $scope.autoUpdate.error = error.message;
$scope.autoUpdate.busy = false;
});
},
submit: function () {
if ($scope.autoUpdate.pattern === $scope.autoUpdate.currentPattern) return;
$scope.autoUpdate.error = '';
$scope.autoUpdate.busy = true;
$scope.autoUpdate.success = false;
Client.setAppAutoupdatePattern($scope.autoUpdate.pattern, function (error) {
2018-01-22 13:01:38 -08:00
if (error) $scope.autoUpdate.error = error.message;
else $scope.autoUpdate.currentPattern = $scope.autoUpdate.pattern;
$scope.autoUpdate.busy = false;
$scope.autoUpdate.success = true;
});
}
};
function getAutoupdatePattern() {
Client.getAppAutoupdatePattern(function (error, result) {
2018-01-22 13:01:38 -08:00
if (error) return console.error(error);
$scope.autoUpdate.currentPattern = result.pattern;
$scope.autoUpdate.pattern = result.pattern;
});
}
function getSubscription() {
AppStore.getSubscription($scope.appstoreConfig, function (error, result) {
if (error) return console.error(error);
$scope.subscription = result;
2018-01-22 13:01:38 -08:00
// also reload the subscription on the main controller
$scope.$parent.fetchAppstoreProfileAndSubscription(function () {});
2018-01-22 13:01:38 -08:00
// check again to give more immediate feedback once a subscription was setup
if (result.plan.id === 'free') $timeout(getSubscription, 10000);
});
}
function getPlans() {
AppStore.getSizes(function (error, result) {
if (error) return console.error(error);
var found = false;
var SIZE_SLUGS = [ '512mb', '1gb', '2gb', '4gb', '8gb', '16gb', '32gb', '48gb', '64gb' ];
result = result.filter(function (size) {
// only show plans bigger than the current size
if (found) return true;
found = SIZE_SLUGS.indexOf(size.slug) > SIZE_SLUGS.indexOf($scope.caasConfig.plan.slug);
2018-01-22 13:01:38 -08:00
return found;
});
angular.copy(result, $scope.availablePlans);
// prepend the current plan
$scope.availablePlans.unshift($scope.caasConfig.plan);
2018-01-22 13:01:38 -08:00
$scope.planChange.requestedPlan = $scope.availablePlans[0]; // need the reference to preselect
AppStore.getRegions(function (error, result) {
if (error) return console.error(error);
angular.copy(result, $scope.availableRegions);
$scope.currentRegionSlug = $scope.caasConfig.region;
2018-01-22 13:01:38 -08:00
});
});
}
$('#avatarFileInput').get(0).onchange = function (event) {
var fr = new FileReader();
fr.onload = function () {
$scope.$apply(function () {
var tmp = {
file: event.target.files[0],
data: fr.result,
url: null
};
$scope.avatarChange.availableAvatars.push(tmp);
$scope.avatarChange.setPreviewAvatar(tmp);
});
};
fr.readAsDataURL(event.target.files[0]);
};
$scope.cloudronNameChange = {
busy: false,
error: {},
name: '',
reset: function () {
$scope.cloudronNameChange.busy = false;
$scope.cloudronNameChange.error.name = null;
$scope.cloudronNameChange.name = '';
$scope.cloudronNameChangeForm.$setUntouched();
$scope.cloudronNameChangeForm.$setPristine();
},
show: function () {
$scope.cloudronNameChange.reset();
$scope.cloudronNameChange.name = $scope.config.cloudronName;
$('#cloudronNameChangeModal').modal('show');
},
submit: function () {
$scope.cloudronNameChange.error.name = null;
$scope.cloudronNameChange.busy = true;
Client.changeCloudronName($scope.cloudronNameChange.name, function (error) {
$scope.cloudronNameChange.busy = false;
if (error) {
if (error.statusCode === 400) {
$scope.cloudronNameChange.error.name = 'Invalid name';
$scope.cloudronNameChange.name = '';
$('#inputCloudronName').focus();
$scope.cloudronNameChangeForm.password.$setPristine();
} else {
console.error('Unable to change name.', error);
return;
}
}
$scope.cloudronNameChange.reset();
$('#cloudronNameChangeModal').modal('hide');
Client.refreshConfig();
});
}
};
Client.onReady(function () {
getAutoupdatePattern();
if ($scope.config.provider === 'caas') {
Client.getCaasConfig(function (error, caasConfig) {
if (error) return console.error(error);
$scope.caasConfig = caasConfig;
2018-01-22 13:01:38 -08:00
getPlans();
$scope.currentPlan = caasConfig.plan;
$scope.currency = caasConfig.currency === 'eur' ? '€' : '$';
});
2018-01-22 13:01:38 -08:00
} else {
Client.getAppstoreConfig(function (error, appstoreConfig) {
2018-01-22 13:01:38 -08:00
if (error) return console.error(error);
if (!appstoreConfig.token) return;
2018-01-22 13:01:38 -08:00
AppStore.getProfile(appstoreConfig.token, function (error, result) {
if (error) return console.error(error);
2018-01-22 13:01:38 -08:00
// assign late to avoid UI flicketing on update
appstoreConfig.profile = result;
$scope.appstoreConfig = appstoreConfig;
2018-01-22 13:01:38 -08:00
getSubscription();
});
2018-01-22 13:01:38 -08:00
});
}
});
// setup all the dialog focus handling
['planChangeModal', 'appstoreLoginModal', 'cloudronNameChangeModal'].forEach(function (id) {
2018-01-22 13:01:38 -08:00
$('#' + id).on('shown.bs.modal', function () {
$(this).find("[autofocus]:first").focus();
});
});
$('.modal-backdrop').remove();
}]);