" // Data
})
-
+
if (!isLocked) {
if (setting.can_order) {
html += "
"
}
-
+
// populate rows in the table from existing values
var row_num = 1
-
+
_.each(setting_value, function(row, indexOrName) {
- html += "
"
-
+ html += "
"
+
if (setting.numbered === true) {
html += "
" + row_num + "
"
}
-
+
if (setting.key) {
html += "
" + indexOrName + "
"
}
-
+
_.each(setting.columns, function(col) {
html += "
"
-
+
if (isArray) {
rowIsObject = setting.columns.length > 1
colValue = rowIsObject ? row[col.name] : row
html += colValue
-
+
// for arrays we add a hidden input to this td so that values can be posted appropriately
- html += ""
} else if (row.hasOwnProperty(col.name)) {
- html += row[col.name]
+ html += row[col.name]
}
-
+
html += "
"
})
-
+
if (!isLocked) {
if (setting.can_order) {
html += "
"
}
-
+
html += "
"
-
+
row_num++
})
-
+
// populate inputs in the table for new values
if (!isLocked) {
html += makeTableInputs(setting)
}
html += "
"
-
+
return html;
}
function makeTableInputs(setting) {
var html = "
"
-
+
if (setting.numbered === true) {
html += "
"
}
-
+
if (setting.key) {
html += "
\
\
"
}
-
+
_.each(setting.columns, function(col) {
html += "
\
\
"
})
-
+
if (setting.can_order) {
html += "
"
}
html += "
"
html += "
"
-
+
return html
}
function badgeSidebarForDifferences(changedElement) {
// figure out which group this input is in
var panelParentID = changedElement.closest('.panel').attr('id')
-
+
// if the panel contains non-grouped settings, the initial value is Settings.initialValues
var isGrouped = $(panelParentID).hasClass('grouped');
if (isGrouped) {
var initialPanelJSON = Settings.initialValues[panelParentID];
-
+
// get a JSON representation of that section
var panelJSON = form2js(panelParentID, ".", false, cleanupFormValues, true)[panelParentID];
} else {
@@ -407,32 +403,32 @@ function badgeSidebarForDifferences(changedElement) {
}
var badgeValue = 0
-
+
// badge for any settings we have that are not the same or are not present in initialValues
for (var setting in panelJSON) {
- if ((!_.has(initialPanelJSON, setting) && panelJSON[setting] !== "") ||
- (!_.isEqual(panelJSON[setting], initialPanelJSON[setting])
+ if ((!_.has(initialPanelJSON, setting) && panelJSON[setting] !== "") ||
+ (!_.isEqual(panelJSON[setting], initialPanelJSON[setting])
&& (panelJSON[setting] !== "" || _.has(initialPanelJSON, setting)))) {
badgeValue += 1
}
}
-
+
// update the list-group-item badge to have the new value
if (badgeValue == 0) {
badgeValue = ""
}
-
+
$("a[href='#" + panelParentID + "'] .badge").html(badgeValue);
}
function addTableRow(add_glyphicon) {
var row = $(add_glyphicon).closest('tr')
-
+
var table = row.parents('table')
var isArray = table.data('setting-type') === 'array'
-
+
var columns = row.parent().children('.' + Settings.DATA_ROW_CLASS)
-
+
if (!isArray) {
// Check key spaces
var key = row.children(".key").children("input").val()
@@ -453,7 +449,7 @@ function addTableRow(add_glyphicon) {
return
}
}
-
+
// Check empty fields
var empty = false;
_.each(row.children('.' + Settings.DATA_COL_CLASS + ' input'), function(element) {
@@ -462,23 +458,23 @@ function addTableRow(add_glyphicon) {
return
}
})
-
+
if (empty) {
showErrorMessage("Error", "Empty field(s)")
return
}
-
+
var input_clone = row.clone()
-
+
// Change input row to data row
var table = row.parents("table")
- var setting_name = table.attr("name")
+ var setting_name = table.attr("name")
var full_name = setting_name + "." + key
row.addClass(Settings.DATA_ROW_CLASS + " " + Settings.NEW_ROW_CLASS)
row.removeClass("inputs")
-
+
_.each(row.children(), function(element) {
- if ($(element).hasClass("numbered")) {
+ if ($(element).hasClass("numbered")) {
// Index row
var numbers = columns.children(".numbered")
if (numbers.length > 0) {
@@ -498,88 +494,88 @@ function addTableRow(add_glyphicon) {
var input = $(element).children("input")
$(element).html(input.val())
input.remove()
- } else if ($(element).hasClass(Settings.DATA_COL_CLASS)) {
+ } else if ($(element).hasClass(Settings.DATA_COL_CLASS)) {
// Hide inputs
var input = $(element).children("input")
input.attr("type", "hidden")
-
+
if (isArray) {
var row_index = row.siblings('.' + Settings.DATA_ROW_CLASS).length
var key = $(element).attr('name')
-
+
// are there multiple columns or just one?
// with multiple we have an array of Objects, with one we have an array of whatever the value type is
var num_columns = row.children('.' + Settings.DATA_COL_CLASS).length
- input.attr("name", setting_name + "[" + row_index + "]" + (num_columns > 1 ? "." + key : ""))
+ input.attr("name", setting_name + "[" + row_index + "]" + (num_columns > 1 ? "." + key : ""))
} else {
input.attr("name", full_name + "." + $(element).attr("name"))
}
-
+
input.attr("data-changed", "true")
-
+
$(element).append(input.val())
} else {
console.log("Unknown table element")
}
})
-
+
input_clone.find('input').each(function(){
$(this).val($(this).attr('data-default'));
});
-
+
if (isArray) {
updateDataChangedForSiblingRows(row, true)
-
+
// the addition of any table row should remove the empty-array-row
row.siblings('.empty-array-row').remove()
}
-
+
badgeSidebarForDifferences($(table))
-
+
row.parent().append(input_clone)
}
function deleteTableRow(delete_glyphicon) {
var row = $(delete_glyphicon).closest('tr')
-
+
var table = $(row).closest('table')
var isArray = table.data('setting-type') === 'array'
-
+
row.empty();
-
+
if (!isArray) {
- row.html("");
} else {
if (table.find('.' + Settings.DATA_ROW_CLASS).length > 1) {
updateDataChangedForSiblingRows(row)
-
+
// this isn't the last row - we can just remove it
row.remove()
} else {
// this is the last row, we can't remove it completely since we need to post an empty array
-
+
row.removeClass(Settings.DATA_ROW_CLASS).removeClass(Settings.NEW_ROW_CLASS)
row.addClass('empty-array-row')
-
- row.html("");
}
}
-
+
// we need to fire a change event on one of the remaining inputs so that the sidebar badge is updated
badgeSidebarForDifferences($(table))
}
function moveTableRow(move_glyphicon, move_up) {
var row = $(move_glyphicon).closest('tr')
-
+
var table = $(row).closest('table')
var isArray = table.data('setting-type') === 'array'
if (!isArray) {
return;
}
-
+
if (move_up) {
var prev_row = row.prev()
if (prev_row.hasClass(Settings.DATA_ROW_CLASS)) {
@@ -591,7 +587,7 @@ function moveTableRow(move_glyphicon, move_up) {
next_row.after(row)
}
}
-
+
// we need to fire a change event on one of the remaining inputs so that the sidebar badge is updated
badgeSidebarForDifferences($(table))
}
@@ -599,23 +595,23 @@ function moveTableRow(move_glyphicon, move_up) {
function updateDataChangedForSiblingRows(row, forceTrue) {
// anytime a new row is added to an array we need to set data-changed for all sibling row inputs to true
// unless it matches the inital set of values
-
+
if (!forceTrue) {
// figure out which group this row is in
var panelParentID = row.closest('.panel').attr('id')
// get the short name for the setting from the table
var tableShortName = row.closest('table').data('short-name')
-
+
// get a JSON representation of that section
var panelSettingJSON = form2js(panelParentID, ".", false, cleanupFormValues, true)[panelParentID][tableShortName]
var initialPanelSettingJSON = Settings.initialValues[panelParentID][tableShortName]
-
+
// if they are equal, we don't need data-changed
isTrue = !_.isEqual(panelSettingJSON, initialPanelSettingJSON)
} else {
isTrue = true
}
-
+
row.siblings('.' + Settings.DATA_ROW_CLASS).each(function(){
var hiddenInput = $(this).find('td.' + Settings.DATA_COL_CLASS + ' input')
if (isTrue) {
@@ -631,19 +627,19 @@ function showRestartModal() {
backdrop: 'static',
keyboard: false
});
-
+
var secondsElapsed = 0;
var numberOfSecondsToWait = 3;
-
+
var refreshSpan = $('span#refresh-time')
refreshSpan.html(numberOfSecondsToWait + " seconds");
-
+
// call ourselves every 1 second to countdown
var refreshCountdown = setInterval(function(){
secondsElapsed++;
secondsLeft = numberOfSecondsToWait - secondsElapsed
refreshSpan.html(secondsLeft + (secondsLeft == 1 ? " second" : " seconds"))
-
+
if (secondsElapsed == numberOfSecondsToWait) {
location.reload(true);
clearInterval(refreshCountdown);
@@ -666,22 +662,22 @@ function showErrorMessage(title, message) {
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
data_web_domains_url = "https://metaverse.highfidelity.com/api/v1/domains?access_token="
$.getJSON(data_web_domains_url + Settings.initialValues.metaverse.access_token, function(data){
-
+
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.
You do not have any domains in your High Fidelity account." +
+ 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",
message: modal_body,
buttons: modal_buttons
})
-
+
// 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.
" +
+ 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"
})
diff --git a/domain-server/resources/web/stats/js/underscore-keypath.min.js b/domain-server/resources/web/js/underscore-keypath.min.js
similarity index 100%
rename from domain-server/resources/web/stats/js/underscore-keypath.min.js
rename to domain-server/resources/web/js/underscore-keypath.min.js
diff --git a/domain-server/resources/web/settings/index.shtml b/domain-server/resources/web/settings/index.shtml
index ad6ed0f41c..9bbf913b1a 100644
--- a/domain-server/resources/web/settings/index.shtml
+++ b/domain-server/resources/web/settings/index.shtml
@@ -5,7 +5,7 @@
-
+
-
+
-
+
-
+
-
+
@@ -90,6 +92,7 @@
+
diff --git a/domain-server/resources/web/stats/index.shtml b/domain-server/resources/web/stats/index.shtml
index dc7fe9678f..13967d4e36 100644
--- a/domain-server/resources/web/stats/index.shtml
+++ b/domain-server/resources/web/stats/index.shtml
@@ -9,6 +9,6 @@
-
+
diff --git a/libraries/shared/src/HifiConfigVariantMap.cpp b/libraries/shared/src/HifiConfigVariantMap.cpp
index c92260210e..3fe5d9ec3f 100644
--- a/libraries/shared/src/HifiConfigVariantMap.cpp
+++ b/libraries/shared/src/HifiConfigVariantMap.cpp
@@ -72,7 +72,7 @@ QVariantMap HifiConfigVariantMap::mergeCLParametersWithJSONConfig(const QStringL
int configIndex = argumentList.indexOf(CONFIG_FILE_OPTION);
QString configFilePath;
-
+
if (configIndex != -1) {
// we have a config file - try and read it
configFilePath = argumentList[configIndex + 1];
@@ -82,8 +82,8 @@ QVariantMap HifiConfigVariantMap::mergeCLParametersWithJSONConfig(const QStringL
QCoreApplication::organizationName(),
QCoreApplication::applicationName());
}
-
-
+
+
return mergedMap;
}
@@ -94,23 +94,23 @@ HifiConfigVariantMap::HifiConfigVariantMap() :
_userConfig(),
_mergedConfig()
{
-
+
}
void HifiConfigVariantMap::loadMasterAndUserConfig(const QStringList& argumentList) {
// check if there is a master config file
const QString MASTER_CONFIG_FILE_OPTION = "--master-config";
-
+
int masterConfigIndex = argumentList.indexOf(MASTER_CONFIG_FILE_OPTION);
if (masterConfigIndex != -1) {
QString masterConfigFilepath = argumentList[masterConfigIndex + 1];
-
+
loadMapFromJSONFile(_masterConfig, masterConfigFilepath);
}
-
+
// load the user config
const QString USER_CONFIG_FILE_OPTION = "--user-config";
-
+
int userConfigIndex = argumentList.indexOf(USER_CONFIG_FILE_OPTION);
if (userConfigIndex != -1) {
_userConfigFilename = argumentList[userConfigIndex + 1];
@@ -119,26 +119,26 @@ void HifiConfigVariantMap::loadMasterAndUserConfig(const QStringList& argumentLi
QCoreApplication::organizationName(),
QCoreApplication::applicationName());
}
-
+
loadMapFromJSONFile(_userConfig, _userConfigFilename);
-
+
// the merged config is initially matched to the master config
_mergedConfig = _masterConfig;
-
+
// then we merge in anything missing from the user config
addMissingValuesToExistingMap(_mergedConfig, _userConfig);
}
void HifiConfigVariantMap::loadMapFromJSONFile(QVariantMap& existingMap, const QString& filename) {
QFile configFile(filename);
-
+
if (configFile.exists()) {
qCDebug(shared) << "Reading JSON config file at" << filename;
configFile.open(QIODevice::ReadOnly);
-
+
QJsonDocument configDocument = QJsonDocument::fromJson(configFile.readAll());
existingMap = configDocument.toVariant().toMap();
-
+
} else {
qCDebug(shared) << "Could not find JSON config file at" << filename;
}
@@ -148,7 +148,7 @@ void HifiConfigVariantMap::addMissingValuesToExistingMap(QVariantMap& existingMa
foreach(const QString& key, newMap.keys()) {
if (existingMap.contains(key)) {
// if this is just a regular value, we're done - we don't ovveride
-
+
if (newMap[key].canConvert(QMetaType::QVariantMap) && existingMap[key].canConvert(QMetaType::QVariantMap)) {
// there's a variant map below and the existing map has one too, so we need to keep recursing
addMissingValuesToExistingMap(*static_cast(existingMap[key].data()), newMap[key].toMap());
@@ -159,11 +159,11 @@ void HifiConfigVariantMap::addMissingValuesToExistingMap(QVariantMap& existingMa
}
}
-const QVariant* valueForKeyPath(QVariantMap& variantMap, const QString& keyPath) {
+QVariant* valueForKeyPath(QVariantMap& variantMap, const QString& keyPath) {
int dotIndex = keyPath.indexOf('.');
-
+
QString firstKey = (dotIndex == -1) ? keyPath : keyPath.mid(0, dotIndex);
-
+
if (variantMap.contains(firstKey)) {
if (dotIndex == -1) {
return &variantMap[firstKey];
@@ -171,6 +171,6 @@ const QVariant* valueForKeyPath(QVariantMap& variantMap, const QString& keyPath)
return valueForKeyPath(*static_cast(variantMap[firstKey].data()), keyPath.mid(dotIndex + 1));
}
}
-
+
return NULL;
}
diff --git a/libraries/shared/src/HifiConfigVariantMap.h b/libraries/shared/src/HifiConfigVariantMap.h
index 6bdeb15589..3566f446a2 100644
--- a/libraries/shared/src/HifiConfigVariantMap.h
+++ b/libraries/shared/src/HifiConfigVariantMap.h
@@ -17,26 +17,26 @@
class HifiConfigVariantMap {
public:
static QVariantMap mergeCLParametersWithJSONConfig(const QStringList& argumentList);
-
+
HifiConfigVariantMap();
void loadMasterAndUserConfig(const QStringList& argumentList);
-
+
const QVariantMap& getMasterConfig() const { return _masterConfig; }
QVariantMap& getUserConfig() { return _userConfig; }
QVariantMap& getMergedConfig() { return _mergedConfig; }
-
+
const QString& getUserConfigFilename() const { return _userConfigFilename; }
private:
QString _userConfigFilename;
-
+
QVariantMap _masterConfig;
QVariantMap _userConfig;
QVariantMap _mergedConfig;
-
+
void loadMapFromJSONFile(QVariantMap& existingMap, const QString& filename);
void addMissingValuesToExistingMap(QVariantMap& existingMap, const QVariantMap& newMap);
};
-const QVariant* valueForKeyPath(QVariantMap& variantMap, const QString& keyPath);
+QVariant* valueForKeyPath(QVariantMap& variantMap, const QString& keyPath);
#endif // hifi_HifiConfigVariantMap_h