Files
gaseous-server/gaseous-server/wwwroot/pages/dialogs/collectionedit.html
2024-01-31 07:28:07 +11:00

676 lines
27 KiB
HTML

<input id="collection_name" type="text" placeholder="Collection Name" style="width: 80%; font-size: 2em;" />
<input id="collection_description" type="text" placeholder="Description" style="width: 80%; margin-top: 5px;" />
<div style="position: absolute; top: 90px; right: 5px; left: 10px; bottom: 5px;">
<div style="position: relative; width: 100%; height: 100%;">
<table style="position: absolute; top: 0px; left: 0px; bottom: 0px; width: 40%;">
<tr>
<td>
<h3>Filter</h3>
</td>
</tr>
</table>
<div id="collection_filter_box" style="position: absolute; top: 40px; left: 0px; bottom: 5px; width: 40%; max-width: 40%; overflow-x: scroll;">
<table style="width: 100%;">
<tr>
<th style="width: 25%;">Platforms</th>
<td><select id="collection_platform" style="width: 100%;" multiple="multiple"></select></td>
</tr>
<tr>
<th>Genres</th>
<td><select id="collection_genres" style="width: 100%;" multiple="multiple"></select></td>
</tr>
<tr>
<th>Players</th>
<td><select id="collection_players" style="width: 100%;" multiple="multiple"></select></td>
</tr>
<tr>
<th>Player Perspectives</th>
<td><select id="collection_playerperspectives" style="width: 100%;" multiple="multiple"></select></td>
</tr>
<tr>
<th>Themes</th>
<td><select id="collection_themes" style="width: 100%;" multiple="multiple"></select></td>
</tr>
<tr>
<th>Rating</th>
<td>
<input id="collection_userrating_min" type="number" placeholder="0" min="0" max="100">
<input id="collection_userrating_max" type="number" placeholder="100" min="0" max="100">
</td>
</tr>
<tr>
<td colspan="2">
<h3>Options</h3>
</td>
</tr>
<tr>
<th>Maximum ROMs per platform</th>
<td><input id="collection_maxroms" type="number" placeholder="0"></td>
</tr>
<tr>
<th>Maximum size per platform (bytes)</th>
<td><input id="collection_maxplatformsize" type="number" placeholder="0" step="1048576" oninput="DisplayFormattedBytes('collection_maxplatformsize', 'maxplatformsize_label');"><span id="maxplatformsize_label" style="margin-left: 10px;"></span></td>
</tr>
<tr>
<th>Maximum collection size (bytes)</th>
<td><input id="collection_maxcollectionsize" type="number" placeholder="0" step="1048576" oninput="DisplayFormattedBytes('collection_maxcollectionsize', 'maxcollectionsize_label');"><span id="maxcollectionsize_label" style="margin-left: 10px;"></span></td></td>
</tr>
<tr>
<th>Directory Layout</th>
<td>
<select id="collection_directorylayout" style="width: 100%;" data-minimum-results-for-search="Infinity" onchange="DisplayDirectoryLabel();">
<option id="collection_directorylayout_gaseous" selected="selected" value="Gaseous">Standard</option>
<option id="collection_directorylayout_retropie" value="RetroPie">RetroPie</option>
</select>
</td>
</tr>
<tr>
<td>
</td>
<td>
<span id="collection_directorylayout_gaseous_label" name="collection_directorylayout_label">
<p>Standard layout: /&lt;IGDB Platform Slug&gt;/&lt;IGDB Game Slug&gt;/Game ROMs</p>
<p>Example: /genesis-slash-megadrive/sonic-the-hedgehog/Sonic the Hedgehog.smd</p>
</span>
<span id="collection_directorylayout_retropie_label" style="display: none;" name="collection_directorylayout_label">
<p>RetroPie layout: /roms/&lt;RetroPie Platform Label&gt;/Game ROMs</p>
<p>Example: /roms/megadrive/Sonic the Hedgehog.smd</p>
</span>
</td>
</tr>
<tr>
<th>
Include BIOS files (if available)
</th>
<td>
<select id="collection_includebios" style="width: 100%;" data-minimum-results-for-search="Infinity">
<option id="collection_includebios_yes" selected="selected" value="true">Yes</option>
<option id="collection_includebios_no" value="false">No</option>
</select>
</td>
</tr>
<tr id="collection_includebios_label">
<td></td>
<td>
BIOS files for each platform will be stored in /BIOS
</td>
</tr>
<!-- <tr>
<th>
Archive format
</th>
<td>
<select id="collection_archiveformat" style="width: 100%;">
<option id="collection_archiveformat_zip" selected="selected" value="Zip">Zip</option>
<option id="collection_archiveformat_rar" value="RAR">RAR</option>
<option id="collection_archiveformat_7z" value="SevenZip">7z</option>
</select>
</td>
</tr> -->
</table>
</div>
<table style="position: absolute; top: 0px; right: 0px; bottom: 0px; width: 60%;">
<tr>
<td>
<h3>Collection</h3>
</td>
</tr>
</table>
<div id="collectionedit_previewbox" style="position: absolute; top: 40px; right: 0px; bottom: 60px; width: 60%; overflow-x: scroll;">
<div id="collectionedit_previewbox_content" style="margin: 5px;">
</div>
</div>
<div id="collectionedit_previewbox_size" style="position: absolute; right: 10px; bottom: 30px; width: 60%; height: 20px; text-align: right;">
</div>
<div id="collectionedit_previewbox_controls" style="position: absolute; right: 10px; bottom: 0px; width: 60%; height: 25px; text-align: right;">
<button id="collectionedit_preview" onclick="GetPreview();">Preview</button>
<button id="collectionedit_cancel" onclick="closeDialog();">Cancel</button>
<button id="collectionedit_ok" onclick="SaveCollection();">Ok</button>
</div>
</div>
</div>
<script type="text/javascript">
var headerToRemove = document.getElementById('modal-heading');
if (headerToRemove) {
headerToRemove.parentNode.removeChild(headerToRemove);
}
var modalContent = document.getElementsByClassName('modal-content');
if (!modalContent[0].classList.contains('collections_modal')) {
modalContent[0].classList.add('collections_modal');
}
// setup dropdowns
$('#collection_platform').select2({
ajax: {
url: '/api/v1.1/Filter',
processResults: function (data) {
var filter = data['platforms'];
var arr = [];
for (var i = 0; i < filter.length; i++) {
arr.push({
id: filter[i].id,
text: filter[i].name
});
}
return {
results: arr
};
}
}
});
$('#collection_genres').select2({
ajax: {
url: '/api/v1.1/Filter',
processResults: function (data) {
var filter = data['genres'];
var arr = [];
for (var i = 0; i < filter.length; i++) {
arr.push({
id: filter[i].id,
text: filter[i].name
});
}
return {
results: arr
};
}
}
});
$('#collection_players').select2({
ajax: {
url: '/api/v1.1/Filter',
processResults: function (data) {
var filter = data['gamemodes'];
var arr = [];
for (var i = 0; i < filter.length; i++) {
arr.push({
id: filter[i].id,
text: filter[i].name
});
}
return {
results: arr
};
}
}
});
$('#collection_playerperspectives').select2({
ajax: {
url: '/api/v1.1/Filter',
processResults: function (data) {
var filter = data['playerperspectives'];
var arr = [];
for (var i = 0; i < filter.length; i++) {
arr.push({
id: filter[i].id,
text: filter[i].name
});
}
return {
results: arr
};
}
}
});
$('#collection_themes').select2({
ajax: {
url: '/api/v1.1/Filter',
processResults: function (data) {
var filter = data['themes'];
var arr = [];
for (var i = 0; i < filter.length; i++) {
arr.push({
id: filter[i].id,
text: filter[i].name
});
}
return {
results: arr
};
}
}
});
$('#collection_directorylayout').select2();
$('#collection_includebios').select2();
if (modalVariables) {
var modalAlwaysInclude = [];
// edit mode
ajaxCall(
'/api/v1.1/Collections/' + modalVariables,
'GET',
function(result) {
if (result.name) { document.getElementById('collection_name').value = result.name; }
if (result.description) { document.getElementById('collection_description').value = result.description; }
if (result.minimumRating != -1) { document.getElementById('collection_userrating_min').value = result.minimumRating; }
if (result.maximumRating != -1) { document.getElementById('collection_userrating_max').value = result.maximumRating; }
if (result.maximumRomsPerPlatform != -1) { document.getElementById('collection_maxroms').value = result.maximumRomsPerPlatform; }
if (result.maximumBytesPerPlatform != -1) { document.getElementById('collection_maxplatformsize').value = result.maximumBytesPerPlatform; }
if (result.maximumCollectionSizeInBytes != -1) { document.getElementById('collection_maxcollectionsize').value = result.maximumCollectionSizeInBytes; }
if (result.folderStructure) {
$('#collection_directorylayout').val(result.folderStructure).trigger('change');
}
$('#collection_includebios').val(result.includeBIOSFiles.toString()).trigger('change');
modalAlwaysInclude = result.alwaysInclude;
console.log(JSON.stringify(modalAlwaysInclude));
// fill select2 controls
$.ajax(
{
url: '/api/v1.1/Filter',
type: 'GET',
indexValue: result,
dataType: 'json',
contentType: 'application/json',
success: function (data) {
// platforms
for (var i = 0; i < data.platforms.length; i++) {
if (this.indexValue.platforms.includes(data.platforms[i].id)) {
var newOption = new Option(data.platforms[i].name, data.platforms[i].id, true, true);
$('#collection_platform').append(newOption).trigger('change');
}
}
// genres
for (var i = 0; i < data.genres.length; i++) {
if (this.indexValue.genres.includes(data.genres[i].id)) {
var newOption = new Option(data.genres[i].name, data.genres[i].id, true, true);
$('#collection_genres').append(newOption).trigger('change');
}
}
// players
for (var i = 0; i < data.gamemodes.length; i++) {
if (this.indexValue.players.includes(data.gamemodes[i].id)) {
var newOption = new Option(data.gamemodes[i].name, data.gamemodes[i].id, true, true);
$('#collection_players').append(newOption).trigger('change');
}
}
// playerperspectives
for (var i = 0; i < data.playerperspectives.length; i++) {
if (this.indexValue.playerPerspectives.includes(data.playerperspectives[i].id)) {
var newOption = new Option(data.playerperspectives[i].name, data.playerperspectives[i].id, true, true);
$('#collection_playerperspectives').append(newOption).trigger('change');
}
}
// themes
for (var i = 0; i < data.themes.length; i++) {
if (this.indexValue.themes.includes(data.themes[i].id)) {
var newOption = new Option(data.themes[i].name, data.themes[i].id, true, true);
$('#collection_themes').append(newOption).trigger('change');
}
}
// generate preview
GetPreview();
},
error: function (error) {
console.log(`Error ${error}`);
}
}
);
}
);
} else {
// new mode
}
function SaveCollection() {
var item = GenerateCollectionItem();
if (modalVariables) {
// existing object - save over the top
item.id = modalVariables;
ajaxCall(
'/api/v1.1/Collections/' + modalVariables,
'PATCH',
function(result) {
location.reload();
},
function(error) {
alert(error);
},
JSON.stringify(item)
);
} else {
// new object
ajaxCall(
'/api/v1.1/Collections',
'POST',
function(result) {
location.reload();
},
function(error) {
alert(error);
},
JSON.stringify(item)
);
}
}
function GenerateCollectionItem() {
var platforms = GetDropDownIds('#collection_platform');
var genres = GetDropDownIds('#collection_genres');
var players = GetDropDownIds('#collection_players');
var playerperspectives = GetDropDownIds('#collection_playerperspectives');
var themes = GetDropDownIds('#collection_themes');
var alwaysInclude = [];
var alwaysIncludeSelections = document.getElementsByName('collections_preview_always');
if (alwaysIncludeSelections.length > 0) {
for (var i = 0; i < alwaysIncludeSelections.length; i++) {
if (alwaysIncludeSelections[i].value != "None") {
var alwaysIncludeItem = {
"platformId": Number(alwaysIncludeSelections[i].getAttribute('data-platform')),
"gameId": Number(alwaysIncludeSelections[i].getAttribute('data-game')),
"inclusionState": alwaysIncludeSelections[i].value
};
alwaysInclude.push(alwaysIncludeItem);
}
}
} else {
alwaysInclude = modalAlwaysInclude;
}
modalAlwaysInclude = alwaysInclude;
if (!alwaysInclude) {
alwaysInclude = [];
}
var item = {
"name": document.getElementById('collection_name').value,
"description": document.getElementById('collection_description').value,
"platforms": platforms,
"genres": genres,
"players": players,
"playerPerspectives": playerperspectives,
"themes": themes,
"minimumRating": GetNumberFieldValue('collection_userrating_min'),
"maximumRating": GetNumberFieldValue('collection_userrating_max'),
"maximumRomsPerPlatform": GetNumberFieldValue('collection_maxroms'),
"maximumBytesPerPlatform": GetNumberFieldValue('collection_maxplatformsize'),
"maximumCollectionSizeInBytes": GetNumberFieldValue('collection_maxcollectionsize'),
"folderStructure": GetNumberFieldValue('collection_directorylayout', "Standard"),
"includeBIOSFiles": GetBooleanFieldValue('collection_includebios'),
"alwaysInclude": alwaysInclude
}
console.log("Item: " + JSON.stringify(item));
return item;
}
function GetPreview() {
var item = GenerateCollectionItem();
ajaxCall(
'/api/v1.1/Collections/Preview',
'POST',
function(result) {
DisplayPreview(result, 'collectionedit_previewbox_content');
},
function(error) {
console.log(JSON.stringify(error));
},
JSON.stringify(item)
);
}
function GetDropDownIds(objectName) {
var obj = $(objectName).select2('data');
if (obj.length > 0) {
var ids = [];
for (var i = 0; i < obj.length; i++) {
ids.push(obj[i].id);
}
return ids;
} else {
return [];
}
}
function GetNumberFieldValue(objectName, defaultValue) {
var obj = document.getElementById(objectName);
var objVal = obj.value;
if (objVal) {
return objVal;
} else {
if (defaultValue) {
return defaultValue;
} else {
return -1;
}
}
}
function GetBooleanFieldValue(objectName) {
var obj = document.getElementById(objectName);
var objVal = obj.value;
if (objVal == "false") {
return false;
} else {
return true;
}
}
function DisplayPreview(data, targetDiv) {
console.log(data);
var container = document.getElementById(targetDiv);
container.innerHTML = '';
if (data.collection) {
var collectionTable = document.createElement('table');
collectionTable.setAttribute('cellspacing', 0);
collectionTable.style.width = '100%';
// loop the platforms
for (var p = 0; p < data.collection.length; p++) {
var platformItem = data.collection[p];
var platformLabelRow = document.createElement('tr');
var platformLabelCell = document.createElement('th');
platformLabelCell.setAttribute('colspan', 2);
platformLabelCell.className = 'collections_preview_platform_header';
platformLabelCell.innerHTML = '<span style="float: right;">' + formatBytes(platformItem.romSize) + '</span>' + platformItem.name;
platformLabelRow.appendChild(platformLabelCell);
collectionTable.appendChild(platformLabelRow);
var bgaltindex = 0;
// loop the games
for (var g = 0; g < platformItem.games.length; g++) {
var gameItem = platformItem.games[g];
var bgalt = '';
if (bgaltindex == 1) {
bgaltindex = 0;
bgalt = 'bgalt1';
} else {
bgaltindex = 1;
bgalt = 'bgalt0';
}
var gameItemRow = document.createElement('tr');
gameItemRow.className = bgalt;
// game title
var gameTitleCell = document.createElement('th');
gameTitleCell.setAttribute('colspan', 2);
gameTitleCell.className = 'collections_preview_gametitlecell';
// game always include popup
var gameTitleInclusion = document.createElement('select');
gameTitleInclusion.id = 'collections_preview_always_' + platformItem.id + '_' + gameItem.id;
gameTitleInclusion.name = 'collections_preview_always';
gameTitleInclusion.setAttribute('data-platform', platformItem.id);
gameTitleInclusion.setAttribute('data-game', gameItem.id);
gameTitleInclusion.style.float = 'right';
var gameTitleInclusionOptions = [
{
"value": "None",
"text": "Automatic"
},
{
"value": "AlwaysInclude",
"text": "Always Include"
},
{
"value": "AlwaysExclude",
"text": "Always Exclude"
}
];
for (var i = 0; i < gameTitleInclusionOptions.length; i++) {
var gameTitleInclusionOption = document.createElement('option');
gameTitleInclusionOption.value = gameTitleInclusionOptions[i].value;
gameTitleInclusionOption.innerHTML = gameTitleInclusionOptions[i].text;
if (gameItem.inclusionStatus) {
if (gameItem.inclusionStatus.inclusionState == gameTitleInclusionOptions[i].value) {
gameTitleInclusionOption.selected = 'selected';
}
}
gameTitleInclusion.appendChild(gameTitleInclusionOption);
}
gameTitleCell.appendChild(gameTitleInclusion);
// game title label
var gameTitleLabel = document.createElement('span');
gameTitleLabel.innerHTML = gameItem.name;
gameTitleCell.appendChild(gameTitleLabel);
gameItemRow.appendChild(gameTitleCell);
// game cover
var gameDetailRow = document.createElement('tr');
gameDetailRow.className = bgalt;
var gameCoverCell = document.createElement('td');
gameCoverCell.className = 'collections_preview_gamecovercell';
var gameImage = document.createElement('img');
gameImage.className = 'game_tile_image game_tile_image_small lazy';
gameImage.src = '/images/unknowngame.png';
if (gameItem.cover) {
gameImage.setAttribute('data-src', '/api/v1.1/Games/' + gameItem.id + '/cover/image/cover_small/' + gameItem.coverItem.imageId + '.jpg');
} else {
gameImage.className = 'game_tile_image game_tile_image_small unknown';
}
gameCoverCell.appendChild(gameImage);
gameDetailRow.appendChild(gameCoverCell);
// game detail
var gameDetailCell = document.createElement('td');
gameDetailCell.className = 'collections_preview_gamedetailcell';
// loop roms
for (var r = 0; r < gameItem.roms.length; r++) {
var romItem = gameItem.roms[r];
var romLabel = document.createElement('p');
romLabel.innerHTML = romItem.name;
gameDetailCell.appendChild(romLabel);
}
gameDetailRow.appendChild(gameDetailCell);
collectionTable.appendChild(gameItemRow);
collectionTable.appendChild(gameDetailRow);
}
}
container.appendChild(collectionTable);
var collectionSize = document.getElementById('collectionedit_previewbox_size');
collectionSize.innerHTML = "Estimated uncompressed collection size: " + formatBytes(data.collectionProjectedSizeBytes);
}
$('#collectionedit_previewbox .lazy').Lazy({
scrollDirection: 'vertical',
effect: 'fadeIn',
visibleOnly: true,
appendScroll: $('#collectionedit_previewbox')
});
}
function DisplayFormattedBytes(inputElement, labelElement) {
var src = document.getElementById(inputElement);
var label = document.getElementById(labelElement);
if (src.value) {
label.innerHTML = formatBytes(src.value);
} else {
label.innerHTML = '';
}
}
function DisplayDirectoryLabel() {
// hide all labels
var directoryLayoutLabels = document.getElementsByName('collection_directorylayout_label');
for (var i = 0; i < directoryLayoutLabels.length; i++) {
directoryLayoutLabels[i].style.display = 'none';
}
// display the label associated with the selection
var directoryLayoutMode = document.getElementById('collection_directorylayout').value;
var labelToDisplay = '';
if (directoryLayoutMode) {
switch(directoryLayoutMode) {
case "Gaseous":
// standard mode
labelToDisplay = 'collection_directorylayout_gaseous_label';
break;
case "RetroPie":
labelToDisplay = 'collection_directorylayout_retropie_label'
break;
}
document.getElementById(labelToDisplay).style.display = '';
}
}
</script>