mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-05 11:39:48 +02:00
538 lines
19 KiB
JavaScript
538 lines
19 KiB
JavaScript
if (typeof Settings === "undefined") {
|
|
Settings = {};
|
|
}
|
|
|
|
$.extend(Settings, {
|
|
DEPRECATED_CLASS: 'deprecated-setting',
|
|
TRIGGER_CHANGE_CLASS: 'trigger-change',
|
|
DATA_ROW_CLASS: 'value-row',
|
|
DATA_COL_CLASS: 'value-col',
|
|
DATA_CATEGORY_CLASS: 'value-category',
|
|
ADD_ROW_BUTTON_CLASS: 'add-row',
|
|
ADD_ROW_SPAN_CLASSES: 'glyphicon glyphicon-plus add-row',
|
|
DEL_ROW_BUTTON_CLASS: 'del-row',
|
|
DEL_ROW_SPAN_CLASSES: 'glyphicon glyphicon-remove del-row',
|
|
ADD_CATEGORY_BUTTON_CLASS: 'add-category',
|
|
ADD_CATEGORY_SPAN_CLASSES: 'glyphicon glyphicon-plus add-category',
|
|
TOGGLE_CATEGORY_COLUMN_CLASS: 'toggle-category',
|
|
TOGGLE_CATEGORY_SPAN_CLASS: 'toggle-category-icon',
|
|
TOGGLE_CATEGORY_SPAN_CLASSES: 'glyphicon toggle-category-icon',
|
|
TOGGLE_CATEGORY_EXPANDED_CLASS: 'glyphicon-triangle-bottom',
|
|
TOGGLE_CATEGORY_CONTRACTED_CLASS: 'glyphicon-triangle-right',
|
|
DEL_CATEGORY_BUTTON_CLASS: 'del-category',
|
|
DEL_CATEGORY_SPAN_CLASSES: 'glyphicon glyphicon-remove del-category',
|
|
MOVE_UP_BUTTON_CLASS: 'move-up',
|
|
MOVE_UP_SPAN_CLASSES: 'glyphicon glyphicon-chevron-up move-up',
|
|
MOVE_DOWN_BUTTON_CLASS: 'move-down',
|
|
MOVE_DOWN_SPAN_CLASSES: 'glyphicon glyphicon-chevron-down move-down',
|
|
TABLE_BUTTONS_CLASS: 'buttons',
|
|
ADD_DEL_BUTTONS_CLASS: 'add-del-buttons',
|
|
ADD_DEL_BUTTONS_CLASSES: 'buttons add-del-buttons',
|
|
REORDER_BUTTONS_CLASS: 'reorder-buttons',
|
|
REORDER_BUTTONS_CLASSES: 'buttons reorder-buttons',
|
|
NEW_ROW_CLASS: 'new-row',
|
|
CONNECT_ACCOUNT_BTN_ID: 'connect-account-btn',
|
|
DISCONNECT_ACCOUNT_BTN_ID: 'disconnect-account-btn',
|
|
CREATE_DOMAIN_ID_BTN_ID: 'create-domain-btn',
|
|
CHOOSE_DOMAIN_ID_BTN_ID: 'choose-domain-btn',
|
|
GET_TEMPORARY_NAME_BTN_ID: 'get-temp-name-btn',
|
|
DOMAIN_ID_SELECTOR: '[name="metaverse.id"]',
|
|
ACCESS_TOKEN_SELECTOR: '[name="metaverse.access_token"]',
|
|
PLACES_TABLE_ID: 'places-table',
|
|
ADD_PLACE_BTN_ID: 'add-place-btn',
|
|
FORM_ID: 'settings-form',
|
|
INVALID_ROW_CLASS: 'invalid-input',
|
|
DATA_ROW_INDEX: 'data-row-index',
|
|
CONTENT_ARCHIVES_PANEL_ID: 'content_archives',
|
|
UPLOAD_CONTENT_BACKUP_PANEL_ID: 'upload_content',
|
|
INSTALLED_CONTENT: 'installed_content'
|
|
});
|
|
|
|
var URLs = {
|
|
// STABLE METAVERSE_URL: https://metaverse.highfidelity.com
|
|
// STAGING METAVERSE_URL: https://staging.highfidelity.com
|
|
DEFAULT_METAVERSE_URL: "https://mv.overte.org/server",
|
|
CDN_URL: 'https://cdn-1.vircadia.com/eu-c-1',
|
|
PLACE_URL: 'https://xr.place'
|
|
};
|
|
|
|
var Strings = {
|
|
LOADING_SETTINGS_ERROR: "There was a problem loading the domain settings.\nPlease refresh the page to try again.",
|
|
|
|
CHOOSE_DOMAIN_BUTTON: "Choose from my domains",
|
|
CREATE_DOMAIN_BUTTON: "Create new domain ID",
|
|
CREATE_DOMAIN_SUCCESS_JUST_CONNECTED: "We connected your Directory Services account and created a new domain ID for this machine.",
|
|
CREATE_DOMAIN_SUCCESS: "We created a new domain ID for this machine.",
|
|
|
|
// When a place modification fails, they will be brought back to the previous
|
|
// dialog with new path still set, allowing them to retry immediately, and without
|
|
// having to type the new path in again.
|
|
EDIT_PLACE_TITLE: "Modify Viewpoint or Path",
|
|
EDIT_PLACE_ERROR: "Failed to update Viewpoint or Path for this Place Name. Please try again.",
|
|
EDIT_PLACE_CONFIRM_BUTTON: "Save",
|
|
EDIT_PLACE_CONFIRM_BUTTON_PENDING: "Saving...",
|
|
EDIT_PLACE_CANCEL_BUTTON: "Cancel",
|
|
|
|
REMOVE_PLACE_TITLE: "Are you sure you want to remove <strong>{{place}}</strong> and its path information?",
|
|
REMOVE_PLACE_ERROR: "Failed to remove Place Name and its Path information.",
|
|
REMOVE_PLACE_DELETE_BUTTON: "This action removes your Place Name",
|
|
REMOVE_PLACE_DELETE_BUTTON_PENDING: "Deleting...",
|
|
REMOVE_PLACE_CANCEL_BUTTON: "Cancel",
|
|
|
|
ADD_PLACE_TITLE: "Choose a place",
|
|
ADD_PLACE_MESSAGE: "Choose a Place Name that you own or register a new Place Name.",
|
|
ADD_PLACE_CONFIRM_BUTTON: "Save",
|
|
ADD_PLACE_CONFIRM_BUTTON_PENDING: "Saving...",
|
|
ADD_PLACE_CANCEL_BUTTON: "Cancel",
|
|
ADD_PLACE_UNKNOWN_ERROR: "There was an error adding this Place Name. Try saving again",
|
|
|
|
ADD_PLACE_NO_PLACES_MESSAGE: "You don't have any Place Names registered. Once you have a Place Name, reopen this window to select it.",
|
|
ADD_PLACE_NO_PLACES_BUTTON: "Create new place",
|
|
ADD_PLACE_UNABLE_TO_LOAD_ERROR: "We were unable to load your place names. Please try again later.",
|
|
ADD_PLACE_LOADING_DIALOG: "Loading your places...",
|
|
|
|
ADD_PLACE_NOT_CONNECTED_TITLE: "Access token required",
|
|
ADD_PLACE_NOT_CONNECTED_MESSAGE: "You must have an access token to query your Directory Services places.<br><br>Please follow the instructions on the settings page to add an access token.",
|
|
};
|
|
|
|
var DOMAIN_ID_TYPE_NONE = 0;
|
|
var DOMAIN_ID_TYPE_TEMP = 1;
|
|
var DOMAIN_ID_TYPE_FULL = 2;
|
|
var DOMAIN_ID_TYPE_UNKNOWN = 3;
|
|
|
|
function swalAreYouSure(text, confirmButtonText, callback) {
|
|
swal({
|
|
title: "Are you sure?",
|
|
text: text,
|
|
type: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonText: confirmButtonText,
|
|
closeOnConfirm: false
|
|
}, callback);
|
|
}
|
|
|
|
function domainIDIsSet() {
|
|
if (typeof Settings.data.values.metaverse !== 'undefined' &&
|
|
typeof Settings.data.values.metaverse.id !== 'undefined') {
|
|
|
|
return Settings.data.values.metaverse.id.length > 0;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function getCurrentDomainIDType() {
|
|
if (!domainIDIsSet()) {
|
|
return DOMAIN_ID_TYPE_NONE;
|
|
}
|
|
if (typeof DomainInfo === 'undefined') {
|
|
return DOMAIN_ID_TYPE_UNKNOWN;
|
|
}
|
|
if (DomainInfo !== null) {
|
|
// Disabled because detecting as temp domain... and we're not even using temp domains right now.
|
|
// if (DomainInfo.name !== undefined) {
|
|
// return DOMAIN_ID_TYPE_TEMP;
|
|
// }
|
|
return DOMAIN_ID_TYPE_FULL;
|
|
}
|
|
return DOMAIN_ID_TYPE_UNKNOWN;
|
|
}
|
|
|
|
function isCloudDomain() {
|
|
|
|
if (!domainIDIsSet()) {
|
|
return false;
|
|
}
|
|
if (typeof DomainInfo === 'undefined') {
|
|
return false;
|
|
}
|
|
if (DomainInfo === null) {
|
|
return false;
|
|
}
|
|
if (typeof DomainInfo.cloud_domain !== "boolean") {
|
|
return false;
|
|
}
|
|
return DomainInfo.cloud_domain;
|
|
}
|
|
|
|
function showLoadingDialog(msg) {
|
|
var message = '<div class="text-center">';
|
|
message += '<span class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></span> ' + msg;
|
|
message += '</div>';
|
|
|
|
return bootbox.dialog({
|
|
message: message,
|
|
closeButton: false
|
|
});
|
|
}
|
|
|
|
function sendUpdatePlaceRequest(id, path, domainID, clearDomainID, onSuccess, onError) {
|
|
var data = {
|
|
place_id: id,
|
|
path: path
|
|
};
|
|
if (domainID) {
|
|
data.domain_id = domainID;
|
|
}
|
|
if (clearDomainID) {
|
|
data.domain_id = null;
|
|
}
|
|
$.ajax({
|
|
url: '/api/places',
|
|
type: 'PUT',
|
|
data: data,
|
|
success: onSuccess,
|
|
error: onError
|
|
});
|
|
}
|
|
|
|
var pendingDomainRequest = null;
|
|
function getDomainFromAPI(callback) {
|
|
if (pendingDomainRequest !== null) {
|
|
pendingDomainRequest.success(callback);
|
|
pendingDomainRequest.error(function() { callback({ status: 'fail' }) });
|
|
return pendingDomainRequest;
|
|
}
|
|
|
|
if (callback === undefined) {
|
|
callback = function() {};
|
|
}
|
|
|
|
if (!domainIDIsSet()) {
|
|
callback({ status: 'fail' });
|
|
return null;
|
|
} else {
|
|
var domainID = Settings.data.values.metaverse.id;
|
|
}
|
|
|
|
pendingDomainRequest = $.ajax({
|
|
url: "/api/domains/" + domainID,
|
|
dataType: 'json',
|
|
success: function(data) {
|
|
pendingDomainRequest = null;
|
|
|
|
if (data.status === 'success') {
|
|
DomainInfo = data.domain;
|
|
} else {
|
|
DomainInfo = null;
|
|
}
|
|
callback(data);
|
|
},
|
|
error: function() {
|
|
pendingDomainRequest = null;
|
|
|
|
DomainInfo = null;
|
|
callback({ status: 'fail' });
|
|
}
|
|
});
|
|
|
|
return pendingDomainRequest;
|
|
}
|
|
|
|
function chooseFromMetaversePlaces(accessToken, forcePathTo, onSuccessfullyAdded) {
|
|
if (accessToken) {
|
|
getMetaverseUrl(function(metaverse_url) {
|
|
|
|
var loadingDialog = showLoadingDialog(Strings.ADD_PLACE_LOADING_DIALOG);
|
|
|
|
function loadPlaces() {
|
|
$.ajax("/api/places", {
|
|
dataType: 'json',
|
|
jsonp: false,
|
|
success: function(data) {
|
|
if (data.status == 'success') {
|
|
var modal_buttons = {
|
|
cancel: {
|
|
label: Strings.ADD_PLACE_CANCEL_BUTTON,
|
|
className: 'add-place-cancel-button btn-default'
|
|
}
|
|
};
|
|
|
|
var dialog;
|
|
var modal_body;
|
|
if (data.data.places.length) {
|
|
var places_by_id = {};
|
|
|
|
modal_body = $('<div>');
|
|
|
|
modal_body.append($("<p>Choose a place name that you own or <a href='" + metaverse_url + "/user/places' target='_blank'>register a new place name</a></p>"));
|
|
|
|
var currentDomainIDType = getCurrentDomainIDType();
|
|
if (currentDomainIDType === DOMAIN_ID_TYPE_TEMP) {
|
|
var warning = "<div class='domain-loading-error alert alert-warning'>";
|
|
warning += "If you choose a place name it will replace your current temporary place name.";
|
|
warning += "</div>";
|
|
modal_body.append(warning);
|
|
}
|
|
|
|
// setup a select box for the returned places
|
|
modal_body.append($("<label for='place-name-select'>Places</label>"));
|
|
place_select = $("<select id='place-name-select' class='form-control'></select>");
|
|
_.each(data.data.places, function(place) {
|
|
places_by_id[place.id] = place;
|
|
place_select.append("<option value='" + place.id + "'>" + place.name + "</option>");
|
|
})
|
|
modal_body.append(place_select);
|
|
modal_body.append($("<p id='place-name-warning' class='warning-text' style='display: none'>This place name already points to a place or path. Saving this would overwrite the previous settings associated with it.</p>"));
|
|
|
|
if (forcePathTo === undefined || forcePathTo === null) {
|
|
var path = "<div class='form-group'>";
|
|
path += "<label for='place-path-input' class='control-label'>Path or Viewpoint</label>";
|
|
path += "<input type='text' id='place-path-input' class='form-control' value='/'>";
|
|
path += "</div>";
|
|
modal_body.append($(path));
|
|
}
|
|
|
|
var place_select = modal_body.find("#place-name-select")
|
|
place_select.change(function(ev) {
|
|
var warning = modal_body.find("#place-name-warning");
|
|
var place = places_by_id[$(this).val()];
|
|
if (place === undefined || place.pointee === null) {
|
|
warning.hide();
|
|
} else {
|
|
warning.show();
|
|
}
|
|
});
|
|
place_select.trigger('change');
|
|
|
|
modal_buttons["success"] = {
|
|
label: Strings.ADD_PLACE_CONFIRM_BUTTON,
|
|
className: 'add-place-confirm-button btn btn-primary',
|
|
callback: function() {
|
|
var placeID = $('#place-name-select').val();
|
|
// set the place ID on the form
|
|
$(Settings.place_ID_SELECTOR).val(placeID).change();
|
|
|
|
if (forcePathTo === undefined || forcePathTo === null) {
|
|
var placePath = $('#place-path-input').val();
|
|
} else {
|
|
var placePath = forcePathTo;
|
|
}
|
|
|
|
$('.add-place-confirm-button').attr('disabled', 'disabled');
|
|
$('.add-place-confirm-button').html(Strings.ADD_PLACE_CONFIRM_BUTTON_PENDING);
|
|
$('.add-place-cancel-button').attr('disabled', 'disabled');
|
|
|
|
function finalizeSaveDomainID(domainID) {
|
|
var jsonSettings = {
|
|
metaverse: {
|
|
id: domainID
|
|
}
|
|
}
|
|
var dialog = showLoadingDialog("Waiting for Domain Server to restart...");
|
|
$.ajax('/settings.json', {
|
|
data: JSON.stringify(jsonSettings),
|
|
contentType: 'application/json',
|
|
type: 'POST'
|
|
}).done(function(data) {
|
|
if (data.status == "success") {
|
|
waitForDomainServerRestart(function() {
|
|
dialog.modal('hide');
|
|
if (onSuccessfullyAdded) {
|
|
onSuccessfullyAdded(places_by_id[placeID].name, domainID);
|
|
}
|
|
});
|
|
} else {
|
|
bootbox.alert("Failed to add place");
|
|
}
|
|
}).fail(function() {
|
|
bootbox.alert("Failed to add place");
|
|
});
|
|
}
|
|
|
|
// If domainID is not specified, the current domain id will be used.
|
|
function finishSettingUpPlace(domainID) {
|
|
sendUpdatePlaceRequest(
|
|
placeID,
|
|
placePath,
|
|
domainID,
|
|
false,
|
|
function(data) {
|
|
dialog.modal('hide')
|
|
if (domainID) {
|
|
$(Settings.DOMAIN_ID_SELECTOR).val(domainID).change();
|
|
finalizeSaveDomainID(domainID);
|
|
} else {
|
|
if (onSuccessfullyAdded) {
|
|
onSuccessfullyAdded(places_by_id[placeID].name);
|
|
}
|
|
}
|
|
},
|
|
function(data) {
|
|
$('.add-place-confirm-button').removeAttr('disabled');
|
|
$('.add-place-confirm-button').html(Strings.ADD_PLACE_CONFIRM_BUTTON);
|
|
$('.add-place-cancel-button').removeAttr('disabled');
|
|
bootbox.alert(Strings.ADD_PLACE_UNKNOWN_ERROR);
|
|
}
|
|
);
|
|
}
|
|
|
|
function maybeCreateNewDomainID() {
|
|
console.log("Maybe creating domain id", currentDomainIDType)
|
|
if (currentDomainIDType === DOMAIN_ID_TYPE_FULL) {
|
|
finishSettingUpPlace();
|
|
} else {
|
|
sendCreateDomainRequest(function(domainID) {
|
|
console.log("Created domain", domainID);
|
|
finishSettingUpPlace(domainID);
|
|
}, function() {
|
|
$('.add-place-confirm-button').removeAttr('disabled');
|
|
$('.add-place-confirm-button').html(Strings.ADD_PLACE_CONFIRM_BUTTON);
|
|
$('.add-place-cancel-button').removeAttr('disabled');
|
|
bootbox.alert(Strings.ADD_PLACE_UNKNOWN_ERROR);
|
|
});
|
|
}
|
|
}
|
|
|
|
maybeCreateNewDomainID();
|
|
|
|
return false;
|
|
}
|
|
}
|
|
} else {
|
|
modal_buttons["success"] = {
|
|
label: Strings.ADD_PLACE_NO_PLACES_BUTTON,
|
|
callback: function() {
|
|
window.open(metaverse_url + "/user/places", '_blank');
|
|
}
|
|
}
|
|
modal_body = Strings.ADD_PLACE_NO_PLACES_MESSAGE;
|
|
}
|
|
dialog = bootbox.dialog({
|
|
title: Strings.ADD_PLACE_TITLE,
|
|
message: modal_body,
|
|
closeButton: false,
|
|
buttons: modal_buttons,
|
|
onEscape: true
|
|
});
|
|
} else {
|
|
bootbox.alert(Strings.ADD_PLACE_UNABLE_TO_LOAD_ERROR);
|
|
}
|
|
},
|
|
error: function() {
|
|
bootbox.alert(Strings.ADD_PLACE_UNABLE_TO_LOAD_ERROR);
|
|
},
|
|
complete: function() {
|
|
loadingDialog.modal('hide');
|
|
}
|
|
});
|
|
}
|
|
|
|
var domainType = getCurrentDomainIDType();
|
|
if (domainType !== DOMAIN_ID_TYPE_UNKNOWN) {
|
|
loadPlaces();
|
|
} else {
|
|
getDomainFromAPI(function(data) {
|
|
if (data.status === 'success') {
|
|
var domainType = getCurrentDomainIDType();
|
|
loadPlaces();
|
|
} else {
|
|
loadingDialog.modal('hide');
|
|
bootbox.confirm("We were not able to load your domain information from the Directory Services. Would you like to retry?", function(response) {
|
|
if (response) {
|
|
chooseFromMetaversePlaces(accessToken, forcePathTo, onSuccessfullyAdded);
|
|
}
|
|
});
|
|
}
|
|
})
|
|
}
|
|
});
|
|
} else {
|
|
bootbox.alert({
|
|
title: Strings.ADD_PLACE_NOT_CONNECTED_TITLE,
|
|
message: Strings.ADD_PLACE_NOT_CONNECTED_MESSAGE
|
|
})
|
|
}
|
|
}
|
|
|
|
function sendCreateDomainRequest(onSuccess, onError) {
|
|
$.ajax({
|
|
url: '/api/domains',
|
|
dataType: 'json',
|
|
type: 'POST',
|
|
data: { label: "" },
|
|
success: function(data) {
|
|
onSuccess(data.domain.id);
|
|
},
|
|
error: onError
|
|
});
|
|
}
|
|
|
|
function waitForDomainServerRestart(callback) {
|
|
function checkForDomainUp() {
|
|
$.ajax('', {
|
|
success: function() {
|
|
callback();
|
|
},
|
|
error: function() {
|
|
setTimeout(checkForDomainUp, 50);
|
|
}
|
|
});
|
|
}
|
|
|
|
setTimeout(checkForDomainUp, 10);
|
|
|
|
}
|
|
|
|
function prepareAccessTokenPrompt(callback) {
|
|
swal({
|
|
title: "Connect Account",
|
|
type: "input",
|
|
text: "Paste your created access token here." +
|
|
"</br></br>If you did not successfully create an access token click cancel below and attempt to connect your account again.</br></br>",
|
|
showCancelButton: true,
|
|
closeOnConfirm: false,
|
|
html: true
|
|
}, function(inputValue){
|
|
if (inputValue === false) {
|
|
return false;
|
|
}
|
|
|
|
if (inputValue === "") {
|
|
swal.showInputError("Please paste your access token in the input field.")
|
|
return false
|
|
}
|
|
|
|
if (callback) {
|
|
callback(inputValue);
|
|
}
|
|
|
|
swal.close();
|
|
});
|
|
}
|
|
|
|
function createDomainIDPrompt(callback) {
|
|
swal({
|
|
title: 'Finish Registering Domain',
|
|
type: 'input',
|
|
text: 'Enter a label for this Domain Server.</br></br>This will help you identify which domain ID belongs to which server.</br></br>This is a required step for registration.</br></br>Acceptable characters are [A-Z][a-z0-9]+-_.</br',
|
|
showCancelButton: true,
|
|
confirmButtonText: "Create",
|
|
closeOnConfirm: false,
|
|
html: true
|
|
}, function (inputValue) {
|
|
if (inputValue === false) {
|
|
return false;
|
|
}
|
|
|
|
if (inputValue === "") {
|
|
swal.showInputError("Please enter a valid label for your machine.");
|
|
return false;
|
|
}
|
|
|
|
if (callback) {
|
|
callback(inputValue);
|
|
}
|
|
});
|
|
}
|
|
|
|
function getMetaverseUrl(callback) {
|
|
$.ajax('/api/metaverse_info', {
|
|
success: function(data) {
|
|
callback(data.metaverse_url);
|
|
},
|
|
error: function() {
|
|
callback(URLs.DEFAULT_METAVERSE_URL);
|
|
}
|
|
});
|
|
}
|