$(document).ready(function(){
var qs = (function(a) {
if (a == "") return {};
var b = {};
for (var i = 0; i < a.length; ++i)
{
var p=a[i].split('=', 2);
if (p.length == 1) {
b[p[0]] = "";
} else {
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
}
return b;
})(window.location.search.substr(1).split('&'));
// define extra groups to add to description, with their splice index
Settings.extraGroups = {
1: {
html_id: 'places',
label: 'Places'
},
"-1": {
html_id: 'settings_backup',
label: 'Settings Backup'
}
}
Settings.afterReloadActions = function() {
// append the domain selection modal
appendDomainIDButtons();
// call our method to setup the HF account button
setupHFAccountButton();
// call our method to setup the place names table
setupPlacesTable();
setupDomainNetworkingSettings();
// setupDomainLabelSetting();
setupSettingsBackup();
if (domainIDIsSet()) {
// now, ask the API for what places, if any, point to this domain
reloadDomainInfo();
// we need to ask the API what a shareable name for this domain is
getShareName(function(success, shareName) {
if (success) {
var shareLink = "https://hifi.place/" + shareName;
$('#visit-domain-link').attr("href", shareLink).show();
}
});
}
if (Settings.data.values.wizard.cloud_domain) {
$('#manage-cloud-domains-link').show();
var cloudWizardExit = qs["cloud-wizard-exit"];
if (cloudWizardExit != undefined) {
$('#cloud-domains-alert').show();
}
}
handleAction();
}
Settings.handlePostSettings = function(formJSON) {
// check if we've set the basic http password
if (formJSON["security"]) {
var password = formJSON["security"]["http_password"];
var verify_password = formJSON["security"]["verify_http_password"];
// if they've only emptied out the default password field, we should go ahead and acknowledge
// the verify password field
if (password != undefined && verify_password == undefined) {
verify_password = "";
}
// if we have a password and its verification, convert it to sha256 for comparison
if (password != undefined && verify_password != undefined) {
formJSON["security"]["http_password"] = sha256_digest(password);
formJSON["security"]["verify_http_password"] = sha256_digest(verify_password);
if (password == verify_password) {
delete formJSON["security"]["verify_http_password"];
} else {
bootbox.alert({ "message": "Passwords must match!", "title": "Password Error" });
return false;
}
}
}
console.log("----- handlePostSettings() called ------");
console.log(formJSON);
if (formJSON["security"]) {
var username = formJSON["security"]["http_username"];
var password = formJSON["security"]["http_password"];
if ((password == sha256_digest("")) && (username == undefined || (username && username.length != 0))) {
swal({
title: "Are you sure?",
text: "You have entered a blank password with a non-blank username. Are you sure you want to require a blank password?",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#5cb85c",
confirmButtonText: "Yes!",
closeOnConfirm: true
},
function () {
formJSON["security"]["http_password"] = "";
postSettings(formJSON);
});
return;
}
}
postSettings(formJSON);
};
$('#' + Settings.FORM_ID).on('click', '#' + Settings.CREATE_DOMAIN_ID_BTN_ID, function(){
$(this).blur();
showDomainCreationAlert(false);
})
$('#' + Settings.FORM_ID).on('click', '#' + Settings.CHOOSE_DOMAIN_ID_BTN_ID, function(){
$(this).blur();
chooseFromHighFidelityDomains($(this))
});
$('#' + Settings.FORM_ID).on('click', '#' + Settings.GET_TEMPORARY_NAME_BTN_ID, function(){
$(this).blur();
createTemporaryDomain();
});
$('#' + Settings.FORM_ID).on('click', '#' + Settings.DISCONNECT_ACCOUNT_BTN_ID, function(e){
$(this).blur();
disonnectHighFidelityAccount();
e.preventDefault();
});
$('#' + Settings.FORM_ID).on('click', '#' + Settings.CONNECT_ACCOUNT_BTN_ID, function(e){
$(this).blur();
prepareAccessTokenPrompt(function(accessToken) {
// we have an access token - set the access token input with this and save settings
$(Settings.ACCESS_TOKEN_SELECTOR).val(accessToken).change();
saveSettings();
});
});
function accessTokenIsSet() {
if (typeof Settings.data.values.metaverse !== 'undefined' &&
typeof Settings.data.values.metaverse.access_token !== 'undefined') {
return Settings.data.values.metaverse.access_token.length > 0;
} else {
return false;
}
}
function getShareName(callback) {
getDomainFromAPI(function(data){
// check if we have owner_places (for a real domain) or a name (for a temporary domain)
if (data && data.status == "success") {
var shareName;
if (data.domain.default_place_name) {
shareName = data.domain.default_place_name;
} else if (data.domain.name) {
shareName = data.domain.name;
} else if (data.domain.network_address) {
shareName = data.domain.network_address;
if (data.domain.network_port !== 40102) {
shareName += ':' + data.domain.network_port;
}
}
callback(true, shareName);
} else {
callback(false);
}
})
}
function handleAction() {
// check if we were passed an action to handle
var action = qs["action"];
if (action == "share") {
// figure out if we already have a stored domain ID
if (domainIDIsSet()) {
// we need to ask the API what a shareable name for this domain is
getShareName(function(success, shareName){
if (success) {
var shareLink = "hifi://" + shareName;
console.log(shareLink);
// show a dialog with a copiable share URL
swal({
title: "Share",
type: "input",
inputPlaceholder: shareLink,
inputValue: shareLink,
text: "Copy this URL to invite friends to your domain.",
closeOnConfirm: true
});
$('.sweet-alert input').select();
} else {
// show an error alert
swal({
title: '',
type: 'error',
text: "There was a problem retreiving domain information from High Fidelity API.",
confirmButtonText: 'Try again',
showCancelButton: true,
closeOnConfirm: false
}, function(isConfirm){
if (isConfirm) {
// they want to try getting domain share info again
showSpinnerAlert("Requesting domain information...")
handleAction();
} else {
swal.close();
}
});
}
});
} else {
// no domain ID present, just show the share dialog
createTemporaryDomain();
}
}
}
function setupHFAccountButton() {
var hasAccessToken = accessTokenIsSet();
var el;
if (hasAccessToken) {
el = "
";
el += "High Fidelity Account Connected";
el += "";
el += "
";
el = $(el);
} else {
// setup an object for the settings we want our button to have
var buttonSetting = {
type: 'button',
name: 'connected_account',
label: 'Connected Account',
}
buttonSetting.help = "";
buttonSetting.classes = "btn-primary";
buttonSetting.button_label = "Connect High Fidelity Account";
buttonSetting.html_id = Settings.CONNECT_ACCOUNT_BTN_ID;
buttonSetting.href = URLs.METAVERSE_URL + "/user/tokens/new?for_domain_server=true";
// since we do not have an access token we change hide domain ID and auto networking settings
// without an access token niether of them can do anything
$("[data-keypath='metaverse.id']").hide();
// use the existing getFormGroup helper to ask for a button
el = viewHelpers.getFormGroup('', buttonSetting, Settings.data.values);
}
// add the button group to the top of the metaverse panel
$('#metaverse .panel-body').prepend(el);
}
function disonnectHighFidelityAccount() {
// the user clicked on the disconnect account btn - give them a sweet alert to make sure this is what they want to do
swal({
title: "Are you sure?",
text: "This will remove your domain-server OAuth access token."
+ "This could cause your domain to appear offline and no longer be reachable via any place names.",
type: "warning",
html: true,
showCancelButton: true
}, function(){
// we need to post to settings to clear the access-token
$(Settings.ACCESS_TOKEN_SELECTOR).val('').change();
// reset the domain id to get a new temporary name
$(Settings.DOMAIN_ID_SELECTOR).val('').change();
saveSettings();
});
}
function showDomainCreationAlert(justConnected) {
swal({
title: 'Create new domain ID',
type: 'input',
text: 'Enter a label this machine.This will help you identify which domain ID belongs to which machine.',
showCancelButton: true,
confirmButtonText: "Create",
closeOnConfirm: false,
html: true
}, function(inputValue){
if (inputValue === false) {
swal.close();
// user cancelled domain ID creation - if we're supposed to save after cancel then save here
if (justConnected) {
saveSettings();
}
} else {
// we're going to change the alert to a new one with a spinner while we create this domain
showSpinnerAlert('Creating domain ID');
createNewDomainID(inputValue, justConnected);
}
});
}
function createNewDomainID(label, justConnected) {
// get the JSON object ready that we'll use to create a new domain
var domainJSON = {
"label": label
}
$.post("/api/domains", domainJSON, function(data){
// we successfully created a domain ID, set it on that field
var domainID = data.domain.id;
console.log("Setting domain id to ", data, domainID);
$(Settings.DOMAIN_ID_SELECTOR).val(domainID).change();
if (justConnected) {
var successText = Strings.CREATE_DOMAIN_SUCCESS_JUST_CONNECTED
} else {
var successText = Strings.CREATE_DOMAIN_SUCCESS;
}
successText += "Click the button below to save your new settings and restart your domain-server.";
// show a sweet alert to say we are all finished up and that we need to save
swal({
title: 'Success!',
type: 'success',
text: successText,
html: true,
confirmButtonText: 'Save'
}, function(){
saveSettings();
});
}, 'json').fail(function(){
var errorText = "There was a problem creating your new domain ID. Do you want to try again or";
if (justConnected) {
errorText += " just save your new access token?You can always create a new domain ID later.";
} else {
errorText += " cancel?"
}
// we failed to create the new domain ID, show a sweet-alert that lets them try again or cancel
swal({
title: '',
type: 'error',
text: errorText,
html: true,
confirmButtonText: 'Try again',
showCancelButton: true,
closeOnConfirm: false
}, function(isConfirm){
if (isConfirm) {
// they want to try creating a domain ID again
showDomainCreationAlert(justConnected);
} else {
// they want to cancel
if (justConnected) {
// since they just connected we need to save the access token here
saveSettings();
}
}
});
});
}
function createDomainSpinner() {
var spinner = '
';
spinner += 'Loading ';
spinner += '
';
return spinner;
}
function createDomainLoadingError(message) {
var errorEl = $("");
errorEl.append(message + " ");
var retryLink = $("Please click here to try again.");
retryLink.click(function(ev) {
ev.preventDefault();
reloadDomainInfo();
});
errorEl.append(retryLink);
return errorEl;
}
function showOrHideLabel() {
var type = getCurrentDomainIDType();
var shouldShow = accessTokenIsSet() && (type === DOMAIN_ID_TYPE_FULL || type === DOMAIN_ID_TYPE_UNKNOWN);
$(".panel#label").toggle(shouldShow);
$("li a[href='#label']").parent().toggle(shouldShow);
return shouldShow;
}
function setupDomainLabelSetting() {
showOrHideLabel();
var html = "
");
addRow.find(".place-add").click(function(ev) {
ev.preventDefault();
chooseFromHighFidelityPlaces(Settings.initialValues.metaverse.access_token, null, function(placeName, newDomainID) {
if (newDomainID) {
Settings.data.values.metaverse.id = newDomainID;
var domainIDEl = $("[data-keypath='metaverse.id']");
domainIDEl.val(newDomainID);
Settings.initialValues.metaverse.id = newDomainID;
badgeForDifferences(domainIDEl);
}
reloadDomainInfo();
});
});
$('#' + Settings.PLACES_TABLE_ID + " tbody").append(addRow);
}
function chooseFromHighFidelityDomains(clickedButton) {
// setup the modal to help user pick their domain
if (Settings.initialValues.metaverse.access_token) {
// add a spinner to the choose button
clickedButton.html("Loading domains...");
clickedButton.attr('disabled', 'disabled');
// get a list of user domains from data-web
$.ajax({
url: "/api/domains",
dataType: 'json',
jsonp: false,
success: function(data){
var modal_buttons = {
cancel: {
label: 'Cancel',
className: 'btn-default'
}
}
if (data.data.domains.length) {
// setup a select box for the returned domains
modal_body = "
Choose the High Fidelity domain you want this domain-server to represent. This will set your domain ID on the settings page.
";
domain_select = $("");
_.each(data.data.domains, function(domain){
var domainString = "";
if (domain.label) {
domainString += '"' + domain.label+ '" - ';
}
domainString += domain.id;
domain_select.append("");
})
modal_body += "" + domain_select[0].outerHTML
modal_buttons["success"] = {
label: 'Choose domain',
callback: function() {
domainID = $('#domain-name-select').val()
// set the domain ID on the form
$(Settings.DOMAIN_ID_SELECTOR).val(domainID).change();
}
}
} else {
modal_buttons["success"] = {
label: 'Create new domain',
callback: function() {
window.open(URLs.METAVERSE_URL + "/user/domains", '_blank');
}
}
modal_body = "
You do not have any domains in your High Fidelity account." +
"
Go to your domains page to create a new one. Once your domain is created re-open this dialog to select it.
"
}
bootbox.dialog({
title: "Choose matching domain",
onEscape: true,
message: modal_body,
buttons: modal_buttons
})
},
error: function() {
bootbox.alert("Failed to retrieve your domains from the High Fidelity Metaverse");
},
complete: function() {
// remove the spinner from the choose button
clickedButton.html("Choose from my domains")
clickedButton.removeAttr('disabled')
}
});
} else {
bootbox.alert({
message: "You must have an access token to query your High Fidelity domains.
" +
"Please follow the instructions on the settings page to add an access token.",
title: "Access token required"
})
}
}
function createTemporaryDomain() {
swal({
title: 'Create temporary place name',
text: "This will create a temporary place name and domain ID"
+ " so other users can easily connect to your domain."
+ "In order to make your domain reachable, this will also enable full automatic networking.",
showCancelButton: true,
confirmButtonText: 'Create',
closeOnConfirm: false,
html: true
}, function(isConfirm){
if (isConfirm) {
showSpinnerAlert('Creating temporary place name');
// make a get request to get a temporary domain
$.post(URLs.METAVERSE_URL + '/api/v1/domains/temporary', function(data){
if (data.status == "success") {
var domain = data.data.domain;
// we should have a new domain ID - set it on the domain ID value
$(Settings.DOMAIN_ID_SELECTOR).val(domain.id).change();
// we also need to make sure auto networking is set to full
$('[data-hidden-input="metaverse.automatic_networking"]').val("full").change();
swal({
type: 'success',
title: 'Success!',
text: "We have created a temporary name and domain ID for you."
+ "Your temporary place name is " + domain.name + "."
+ "Press the button below to save your new settings and restart your domain-server.",
confirmButtonText: 'Save',
html: true
}, function(){
saveSettings();
});
}
});
}
});
}
var RESTORE_SETTINGS_UPLOAD_ID = 'restore-settings-button';
var RESTORE_SETTINGS_FILE_ID = 'restore-settings-file';
// when the restore button is clicked, AJAX send the settings file to DS
// to restore its settings
$('body').on('click', '#' + RESTORE_SETTINGS_UPLOAD_ID, function(e){
e.preventDefault();
var files = $('#' + RESTORE_SETTINGS_FILE_ID).prop('files');
var fileFormData = new FormData();
fileFormData.append('restore-file', files[0]);
showSpinnerAlert("Restoring Settings");
$.ajax({
url: '/settings/restore',
type: 'POST',
processData: false,
contentType: false,
dataType: 'json',
data: fileFormData
}).done(function(data, textStatus, jqXHR) {
swal.close();
showRestartModal();
}).fail(function(jqXHR, textStatus, errorThrown) {
showErrorMessage(
"Error",
"There was a problem restoring domain settings.\n"
+ "Please ensure that your current domain settings are valid and try again."
);
reloadSettings();
});
});
$('body').on('change', '#' + RESTORE_SETTINGS_FILE_ID, function() {
if ($(this).val()) {
$('#' + RESTORE_SETTINGS_UPLOAD_ID).attr('disabled', false);
}
});
function setupSettingsBackup() {
// construct the HTML needed for the settings backup panel
var html = "
";
html += "";
html += "Download this domain's settings to quickly configure another domain or to restore them later";
html += "Download Domain Settings";
html += "
";
html += "
";
html += "";
html += "Upload a settings configuration to quickly configure this domain";
html += " Note: Your domain's settings will be replaced by the settings you upload";
html += "";
html += "";
html += "
";
$('#settings_backup .panel-body').html(html);
// add an upload button to the footer to kick off the upload form
}
});