diff --git a/gaseous-server/Classes/Metadata/Communications.cs b/gaseous-server/Classes/Metadata/Communications.cs index d3adc16..fb14572 100644 --- a/gaseous-server/Classes/Metadata/Communications.cs +++ b/gaseous-server/Classes/Metadata/Communications.cs @@ -224,6 +224,22 @@ namespace gaseous_server.Classes.Metadata return await IGDBAPI(Endpoint, Fields, Query); } + + case HttpStatusCode.Unauthorized: + Logging.Log(Logging.LogType.Information, "API Connection", "IGDB API unauthorised error while accessing endpoint " + Endpoint + ". Waiting " + RateLimitAvoidanceWait + " milliseconds and resetting IGDB client.", apiEx); + + Thread.Sleep(RateLimitAvoidanceWait); + + igdb = new IGDBClient( + // Found in Twitch Developer portal for your app + Config.IGDB.ClientId, + Config.IGDB.Secret + ); + + RetryAttempts += 1; + + return await IGDBAPI(Endpoint, Fields, Query); + default: Logging.Log(Logging.LogType.Warning, "API Connection", "Exception when accessing endpoint " + Endpoint, apiEx); throw; diff --git a/gaseous-server/Controllers/V1.1/GamesController.cs b/gaseous-server/Controllers/V1.1/GamesController.cs index 516c0ef..333d51e 100644 --- a/gaseous-server/Controllers/V1.1/GamesController.cs +++ b/gaseous-server/Controllers/V1.1/GamesController.cs @@ -522,7 +522,7 @@ FROM // get count int RecordCount = dbResponse.Rows.Count; - + // compile data for return int pageOffset = pageSize * (pageNumber - 1); for (int i = pageOffset; i < dbResponse.Rows.Count; i++) @@ -546,10 +546,33 @@ FROM RetVal.Add(retMinGame); } + // build alpha list + Dictionary AlphaList = new Dictionary(); + int CurrentPage = 0; + int NextPageIndex = 0; + for (int i = 0; i < dbResponse.Rows.Count; i++) + { + string firstChar = dbResponse.Rows[i]["NameThe"].ToString().Substring(0, 1).ToUpperInvariant(); + if (!"ABCDEFGHIJKLMNOPQRSTUVWXYZ".Contains(firstChar)) + { + firstChar = "#"; + } + if (!AlphaList.ContainsKey(firstChar)) + { + AlphaList.Add(firstChar, CurrentPage); + } + if (NextPageIndex == i) + { + NextPageIndex += pageSize; + CurrentPage += 1; + } + } + GameReturnPackage gameReturn = new GameReturnPackage { Count = RecordCount, - Games = RetVal + Games = RetVal, + AlphaList = AlphaList }; return gameReturn; @@ -577,6 +600,7 @@ FROM public int Count { get; set; } public List Games { get; set; } = new List(); + public Dictionary AlphaList { get; set; } } } } \ No newline at end of file diff --git a/gaseous-server/wwwroot/pages/home.html b/gaseous-server/wwwroot/pages/home.html index b0a11f3..f0ff2b7 100644 --- a/gaseous-server/wwwroot/pages/home.html +++ b/gaseous-server/wwwroot/pages/home.html @@ -27,6 +27,9 @@
+
+
+
diff --git a/gaseous-server/wwwroot/scripts/gamesformating.js b/gaseous-server/wwwroot/scripts/gamesformating.js index b032446..994ba50 100644 --- a/gaseous-server/wwwroot/scripts/gamesformating.js +++ b/gaseous-server/wwwroot/scripts/gamesformating.js @@ -112,6 +112,9 @@ function formatGamesPanel(targetElement, result, pageNumber, pageSize, forceScro var pager = document.getElementById('games_pager'); pager.style.display = 'none'; + var alphaPager = document.getElementById('games_library_alpha_pager'); + alphaPager.innerHTML = ''; + switch(pageMode) { case 'infinite': if (result.games.length == pageSize) { @@ -126,6 +129,14 @@ function formatGamesPanel(targetElement, result, pageNumber, pageSize, forceScro break; case 'paged': + for (const [key, value] of Object.entries(result.alphaList)) { + var letterPager = document.createElement('span'); + letterPager.className = 'games_library_alpha_pager_letter'; + letterPager.setAttribute('onclick', 'executeFilter1_1(' + value + ');'); + letterPager.innerHTML = key; + alphaPager.appendChild(letterPager); + } + if (result.count > pageSize) { // add some padding to the bottom of the games list var loadPageButton = document.createElement("div"); @@ -134,6 +145,16 @@ function formatGamesPanel(targetElement, result, pageNumber, pageSize, forceScro var pageCount = Math.ceil(result.count / pageSize); + // add first page button + var firstPage = document.createElement('span'); + firstPage.innerHTML = '|<'; + if (pageNumber == 1) { + firstPage.className = 'games_pager_number_disabled'; + } else { + firstPage.className = 'games_pager_number'; + firstPage.setAttribute('onclick', 'executeFilter1_1(1);'); + } + // add previous page button var prevPage = document.createElement('span'); prevPage.innerHTML = '<'; @@ -187,10 +208,22 @@ function formatGamesPanel(targetElement, result, pageNumber, pageSize, forceScro nextPage.setAttribute('onclick', 'executeFilter1_1(' + (pageNumber + 1) + ');'); } + // add last page button + var lastPage = document.createElement('span'); + lastPage.innerHTML = '>|'; + if (pageNumber == pageCount) { + lastPage.className = 'games_pager_number_disabled'; + } else { + lastPage.className = 'games_pager_number'; + lastPage.setAttribute('onclick', 'executeFilter1_1(' + pageCount + ');'); + } + pager.innerHTML = ''; + pager.appendChild(firstPage); pager.appendChild(prevPage); pager.appendChild(pageNumbers); pager.appendChild(nextPage); + pager.appendChild(lastPage); pager.style.display = ''; } @@ -236,30 +269,36 @@ function IsInView() { $(window).scroll(IsInView); -function renderGameIcon(gameObject, showTitle, showRatings, showClassification, classificationDisplayOrder, useSmallCover) { +function renderGameIcon(gameObject, showTitle, showRatings, showClassification, classificationDisplayOrder, useSmallCover, listView) { + if (listView == undefined) { + listView = false; + } + + var classes = getViewModeClasses(listView); + var gameBox = document.createElement('div'); gameBox.id = "game_tile_" + gameObject.id; if (useSmallCover == true) { - gameBox.className = 'game_tile game_tile_small'; + gameBox.className = classes['game_tile game_tile_small']; } else { - gameBox.className = 'game_tile'; + gameBox.className = classes['game_tile']; } gameBox.setAttribute('onclick', 'window.location.href = "/index.html?page=game&id=' + gameObject.id + '";'); var gameImageBox = document.createElement('div'); - gameImageBox.className = 'game_tile_box'; + gameImageBox.className = classes['game_tile_box']; var gameImage = document.createElement('img'); if (useSmallCover == true) { - gameImage.className = 'game_tile_image game_tile_image_small lazy'; + gameImage.className = classes['game_tile_image game_tile_image_small lazy']; } else { - gameImage.className = 'game_tile_image lazy'; + gameImage.className = classes['game_tile_image lazy']; } gameImage.src = '/images/unknowngame.png'; if (gameObject.cover) { gameImage.setAttribute('data-src', '/api/v1.1/Games/' + gameObject.id + '/cover/image/cover_big/' + gameObject.cover.imageId + '.jpg'); } else { - gameImage.className = 'game_tile_image unknown'; + gameImage.className = classes['game_tile_image unknown']; } gameImageBox.appendChild(gameImage); @@ -287,13 +326,13 @@ function renderGameIcon(gameObject, showTitle, showRatings, showClassification, if (gameObject.hasSavedGame == true) { var gameSaveIcon = document.createElement('img'); gameSaveIcon.src = '/images/SaveStates.png'; - gameSaveIcon.className = 'game_tile_box_savedgame savedstateicon'; + gameSaveIcon.className = classes['game_tile_box_savedgame savedstateicon']; gameImageBox.appendChild(gameSaveIcon); } if (gameObject.totalRating || displayClassification == true) { var gameImageRatingBanner = document.createElement('div'); - gameImageRatingBanner.className = 'game_tile_box_ratingbanner'; + gameImageRatingBanner.className = classes['game_tile_box_ratingbanner']; if (showRatings == true || displayClassification == true) { if (showRatings == true) { @@ -314,7 +353,7 @@ function renderGameIcon(gameObject, showTitle, showRatings, showClassification, if (displayClassification == true) { var gameImageClassificationLogo = document.createElement('img'); gameImageClassificationLogo.src = classificationPath; - gameImageClassificationLogo.className = 'rating_image_overlay'; + gameImageClassificationLogo.className = classes['rating_image_overlay']; gameImageBox.appendChild(gameImageClassificationLogo); } } @@ -323,10 +362,40 @@ function renderGameIcon(gameObject, showTitle, showRatings, showClassification, if (showTitle == true) { var gameBoxTitle = document.createElement('div'); - gameBoxTitle.class = 'game_tile_label'; + gameBoxTitle.className = classes['game_tile_label']; gameBoxTitle.innerHTML = gameObject.name; gameBox.appendChild(gameBoxTitle); } return gameBox; +} + +function getViewModeClasses(listView) { + if (listView == false) { + return { + "game_tile game_tile_small": "game_tile game_tile_small", + "game_tile": "game_tile", + "game_tile_box": "game_tile_box", + "game_tile_image game_tile_image_small lazy": "game_tile_image game_tile_image_small lazy", + "game_tile_image lazy": "game_tile_image lazy", + "game_tile_image unknown": "game_tile_image unknown", + "game_tile_box_savedgame savedstateicon": "game_tile_box_savedgame savedstateicon", + "game_tile_box_ratingbanner": "game_tile_box_ratingbanner", + "rating_image_overlay": "rating_image_overlay", + "game_tile_label": "game_tile_label" + }; + } else { + return { + "game_tile game_tile_small": "game_tile_row game_tile_small", + "game_tile": "game_tile_row", + "game_tile_box": "game_tile_box_row", + "game_tile_image game_tile_image_small lazy": "game_tile_image_row game_tile_image_small lazy", + "game_tile_image lazy": "game_tile_image_row lazy", + "game_tile_image unknown": "game_tile_image_row unknown", + "game_tile_box_savedgame savedstateicon": "game_tile_box_savedgame_row savedstateicon", + "game_tile_box_ratingbanner": "game_tile_box_ratingbanner_row", + "rating_image_overlay": "rating_image_overlay_row", + "game_tile_label": "game_tile_label_row" + }; + } } \ No newline at end of file diff --git a/gaseous-server/wwwroot/styles/style.css b/gaseous-server/wwwroot/styles/style.css index 34d1015..238c03c 100644 --- a/gaseous-server/wwwroot/styles/style.css +++ b/gaseous-server/wwwroot/styles/style.css @@ -352,12 +352,13 @@ input[id='filter_panel_userrating_max'] { #games_pager { position: fixed; - bottom: 50px; + bottom: 0px; left: 50%; transform: translate(-50%, 0); border-style: solid; border-width: 1px; - border-radius: 7px; + border-top-left-radius: 7px; + border-top-right-radius: 7px; border-color: rgba(0, 22, 56, 0.8); padding-left: 20px; padding-right: 20px; @@ -469,6 +470,7 @@ input[id='filter_panel_userrating_max'] { #games_library { display: block; + margin-right: 50px; /* width: 90%; */ /* border-style: solid; border-width: 1px; @@ -489,7 +491,40 @@ input[id='filter_panel_userrating_max'] { width: 100%; text-align: center; padding-top: 10px; - height: 100px; + height: 55px; +} + +#games_library_alpha_box { + position: fixed; + right: 0px; + top: 120px; + bottom: 0px; + width: 50px; + overflow-x: auto; + overflow-y: auto; + /* display: flex; */ + justify-content: center; + align-items: center; +} + +#games_library_alpha_pager { + width: 50px; + justify-content: center; + align-items: center; +} + +.games_library_alpha_pager_letter { + display: block; + font-family: Commodore64; + font-size: 14px; + text-align: center; + padding-top: 7px; + padding-bottom: 7px; +} + +.games_library_alpha_pager_letter:hover { + cursor: pointer; + background-color: blue; } .game_tile { @@ -534,6 +569,22 @@ input[id='filter_panel_userrating_max'] { border: 1px solid #2b2b2b; } +.game_tile_row { + padding: 5px; + display: block; + position: relative; + width: auto; + min-height: 100px; + align-items: left; + vertical-align: top; +} + +.game_tile_row:hover { + cursor: pointer; + text-decoration: underline; + background-color: #2b2b2b; +} + .game_tile_box { position: relative; display: inline-block; @@ -541,6 +592,14 @@ input[id='filter_panel_userrating_max'] { max-height: 200px; } +.game_tile_box_row { + position: absolute; + display: inline-block; + padding: 10px; + left: 0px; + right: 0px; +} + .game_tile_box_ratingbanner { position: absolute; bottom: 0px; @@ -557,12 +616,40 @@ input[id='filter_panel_userrating_max'] { -webkit-backdrop-filter: blur(8px); } +.game_tile_box_ratingbanner_row { + position: absolute; + left: 80%; + top: 10px; + bottom: 10px; + right: 10px; + width: 20%; + line-height: 80px; + background-color: transparent; +} + +.game_tile_label_row { + position: absolute; + text-align: left; + vertical-align: middle; + left: 110px; + top: 0px; + bottom: 0px; + width: 50%; + line-height: 100px; +} + .game_tile_box_savedgame { position: absolute; top: 1px; right: 5px; } +.game_tile_box_savedgame_row { + position: absolute; + top: 30%; + right: 10px; +} + .game_tile_image { max-width: 200px; min-width: 150px; @@ -574,10 +661,26 @@ input[id='filter_panel_userrating_max'] { -moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); } +.game_tile_image_row { + max-width: 75px; + min-width: 50px; + max-height: 75px; + min-height: 75px; + margin-left: 10px; + background-color: transparent; + box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); + -webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); + -moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); +} + .game_tile_image, .unknown { background-color: transparent; } +.game_tile_image_row, .unknown { + background-color: transparent; +} + .game_tile_image_small { min-width: 50px; min-height: 50px; @@ -680,6 +783,13 @@ input[id='filter_panel_userrating_max'] { bottom: 5px; } +.rating_image_overlay_row { + position: absolute; + left: 50%; + top: 25px; + height: 50px; +} + #gamescreenshots { background-color: black; padding: 10px;