diff --git a/lib/consoleicons.js b/lib/consoleicons.js
new file mode 100644
index 0000000..74c99f1
--- /dev/null
+++ b/lib/consoleicons.js
@@ -0,0 +1,22 @@
+export default class ConsoleIcons {
+ constructor(consoleData){
+ this.consoleData = consoleData
+ }
+
+ getConsoleImage(console){
+ return this.consoleData[console]?.icon
+ }
+ ifConsoleExists(console){
+ return this.consoleData[console] ? true : false
+ }
+ createConsoleImage(console){
+ //fixups
+ console = console.replace('Sony PlayStation', 'PlayStation')
+ console = console.replace('Microsoft Xbox', 'Xbox')
+ console = console.replace(/^Xbox$/, 'Xbox Classic')
+ if(this.ifConsoleExists(console)){
+ return ``
+ }
+ return ''
+ }
+}
\ No newline at end of file
diff --git a/lib/flag.js b/lib/flag.js
new file mode 100644
index 0000000..9ff6b55
--- /dev/null
+++ b/lib/flag.js
@@ -0,0 +1,41 @@
+import path from "path";
+import { fileURLToPath } from "url";
+import fs from "fs";
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+const flagsDir = path.join(__dirname, "../views/public/images/flags");
+
+
+export default class Flags {
+ constructor() {
+ this.flags = this.getAvailableFlags();
+ this.basePath = '/public/images/flags/'
+ }
+
+ getAvailableFlags() {
+ try {
+ return fs
+ .readdirSync(flagsDir)
+ .filter((file) => file.endsWith(".png"))
+ .map((file) => path.basename(file, ".png"));
+ } catch (error) {
+ console.error("Error reading flags directory:", error);
+ return [];
+ }
+ }
+
+ ifFlagExists(string){
+ return this.flags.includes(string)
+ }
+
+ getFlagPath(string){
+ return `${this.basePath}${string}.png`
+ }
+
+ createFlag(string){
+ if(this.ifFlagExists(string)){
+ return `
`
+ }
+ return ''
+ }
+}
diff --git a/server.js b/server.js
index 0d51271..c141caf 100644
--- a/server.js
+++ b/server.js
@@ -22,6 +22,8 @@ import i18n, { locales } from "./config/i18n.js";
import { v4 as uuidv4 } from "uuid";
import { optimizeDatabaseKws } from "./lib/dboptimize.js";
import MetadataSearch from "./lib/metadatasearch.js";
+import Flag from "./lib/flag.js";
+import ConsoleIcons from "./lib/consoleicons.js";
let categoryListPath = "./lib/categories.json";
let nonGameTermsPath = "./lib/nonGameTerms.json";
@@ -33,6 +35,8 @@ let crawlTime = 0;
let queryCount = 0;
let fileCount = 0;
let indexPage = "pages/index";
+let flags = new Flag();
+let consoleIcons = new ConsoleIcons(emulatorsData);
// Initialize databases
await initDB();
@@ -200,7 +204,8 @@ app.get("/search", async function (req, res) {
if (settings.combineWith != "AND") {
delete settings.combineWith;
}
- let loadOldResults = req.query.old === "true" || !metadataSearch.authorized ? true : false
+ let loadOldResults =
+ req.query.old === "true" || !metadataSearch.authorized ? true : false;
settings.pageSize = loadOldResults ? 100 : 10;
settings.page = pageNum - 1;
settings.sort = req.query.o || "";
@@ -225,6 +230,8 @@ app.get("/search", async function (req, res) {
indexing: search.indexing,
urlPrefix: urlPrefix,
settings: settings,
+ flags: flags,
+ consoleIcons: consoleIcons
};
let page = loadOldResults ? "resultsold" : "results";
options = buildOptions(page, options);
@@ -259,7 +266,7 @@ app.get("/lucky", async function (req, res) {
app.get("/settings", function (req, res) {
let options = { defaultSettings: defaultSettings };
let page = "settings";
- options.oldSettingsAvailable = metadataSearch.authorized
+ options.oldSettingsAvailable = metadataSearch.authorized;
options = buildOptions(page, options);
res.render(indexPage, options);
});
@@ -328,6 +335,8 @@ app.get("/info/:id", async function (req, res) {
}
let options = {
romFile: romInfo[0],
+ flags: flags,
+ consoleIcons: consoleIcons
};
let page = "info";
options = buildOptions(page, options);
diff --git a/views/pages/info.ejs b/views/pages/info.ejs
index d8e3844..f6a0554 100644
--- a/views/pages/info.ejs
+++ b/views/pages/info.ejs
@@ -17,7 +17,7 @@
<%= file.category %>
+<%= file.category %> <%- consoleIcons.createConsoleImage(file.category) %>
<%= __('search.region') %> <%= file.region %>
+<%= __('search.region') %> <%= file.region %> <%- flags.createFlag(file.region) %>
<%= metadata.title || file.filename %>
-<%= __('search.released') %>: <%= metadata.releasedate || file.date %> - <%= __('search.region') %> <%= file.region %> - <%= __('search.platform') %> <%= file.category %> +
<%= metadata.title || file.filename %>
+<%= __('search.released') %> <%= metadata.releasedate || file.date %> + <%= __('search.region') %> <%= file.region %> <%- flags.createFlag(file.region) %> + <%= __('search.platform') %> <%= file.category %> <%- consoleIcons.createConsoleImage(file.category) %> <% if(metadata.genre){ %> <%= __('search.genre') %> <%= JSON.parse(metadata.genre).join(' / ') %> <% } %> diff --git a/views/public/css/info.css b/views/public/css/info.css index 1cc0c99..91a95f7 100644 --- a/views/public/css/info.css +++ b/views/public/css/info.css @@ -43,4 +43,11 @@ object-fit: contain; height: auto; width: 240px; +} + +.console { + height: 1.5rem; +} +.text-secondary{ + font-size: 1.5rem; } \ No newline at end of file diff --git a/views/public/css/result.css b/views/public/css/result.css index 2788683..4794632 100644 --- a/views/public/css/result.css +++ b/views/public/css/result.css @@ -20,13 +20,14 @@ font-weight: bold; color: #f0a400; margin-bottom: 0!important; + font-size: 1.25em; } .title a { font-weight: bold; color: #f0a400; } .info { - font-size: 0.8em; + font-size: 1em; } .file { font-size: 0.8em; @@ -36,7 +37,21 @@ } .infoitem{ margin-right: 0; + padding-left: 0.5em; + padding-right: 0.5em; + height: 1.75em; + vertical-align: middle; + align-content: center; } .cover{ margin-left: 1rem; +} +.flag{ + height: 1.25em; + vertical-align: middle; +} + +.console { + height: 1.25em; + vertical-align: middle; } \ No newline at end of file diff --git a/views/public/css/style.css b/views/public/css/style.css index 136009f..e9865f3 100644 --- a/views/public/css/style.css +++ b/views/public/css/style.css @@ -144,3 +144,18 @@ td a { position: relative; z-index: 9999 !important; } +.flag { + object-fit: contain; +} +.console { + object-fit: contain; +} +.spinner-border { + height: 1rem; + width: 1rem; + margin-right: 0.25em; + vertical-align: sub; +} +.hidden { + display: none; +} \ No newline at end of file diff --git a/views/public/js/video.js b/views/public/js/video.js new file mode 100644 index 0000000..9b5371a --- /dev/null +++ b/views/public/js/video.js @@ -0,0 +1,32 @@ +// index.js +const videos = []; +const tag = document.createElement("script"); +const firstScriptTag = document.getElementsByTagName("script")[0]; + +tag.src = "https://www.youtube.com/iframe_api"; +firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); + +// YouTube wants this function, don't rename it +function onYouTubeIframeAPIReady() { + const slides = Array.from(document.querySelectorAll(".carousel-item")); + slides.forEach((slide, index) => { + // does this slide have a video? + const video = slide.querySelector(".video-player"); + if (video && video.dataset) { + const player = createPlayer({ + id: video.id, + videoId: video.dataset.videoId, + }); + videos.push({ player, index }); + } + }); +} + +function createPlayer(playerInfo) { + return new YT.Player(playerInfo.id, { + videoId: playerInfo.videoId, + playerVars: { + showinfo: 0, + }, + }); +} \ No newline at end of file