mirror of
https://github.com/alexankitty/Myrient-Search-Engine.git
synced 2026-01-15 16:33:15 -03:00
add load spinner
add flag icons add console icons
This commit is contained in:
22
lib/consoleicons.js
Normal file
22
lib/consoleicons.js
Normal file
@@ -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 `<img class='console' src='/proxy-image?url=${encodeURIComponent(this.getConsoleImage(console))}'>`
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
41
lib/flag.js
Normal file
41
lib/flag.js
Normal file
@@ -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 `<img class="flag" src="${this.getFlagPath(string)}"></img>`
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
13
server.js
13
server.js
@@ -22,6 +22,8 @@ import i18n, { locales } from "./config/i18n.js";
|
|||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
import { optimizeDatabaseKws } from "./lib/dboptimize.js";
|
import { optimizeDatabaseKws } from "./lib/dboptimize.js";
|
||||||
import MetadataSearch from "./lib/metadatasearch.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 categoryListPath = "./lib/categories.json";
|
||||||
let nonGameTermsPath = "./lib/nonGameTerms.json";
|
let nonGameTermsPath = "./lib/nonGameTerms.json";
|
||||||
@@ -33,6 +35,8 @@ let crawlTime = 0;
|
|||||||
let queryCount = 0;
|
let queryCount = 0;
|
||||||
let fileCount = 0;
|
let fileCount = 0;
|
||||||
let indexPage = "pages/index";
|
let indexPage = "pages/index";
|
||||||
|
let flags = new Flag();
|
||||||
|
let consoleIcons = new ConsoleIcons(emulatorsData);
|
||||||
|
|
||||||
// Initialize databases
|
// Initialize databases
|
||||||
await initDB();
|
await initDB();
|
||||||
@@ -200,7 +204,8 @@ app.get("/search", async function (req, res) {
|
|||||||
if (settings.combineWith != "AND") {
|
if (settings.combineWith != "AND") {
|
||||||
delete settings.combineWith;
|
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.pageSize = loadOldResults ? 100 : 10;
|
||||||
settings.page = pageNum - 1;
|
settings.page = pageNum - 1;
|
||||||
settings.sort = req.query.o || "";
|
settings.sort = req.query.o || "";
|
||||||
@@ -225,6 +230,8 @@ app.get("/search", async function (req, res) {
|
|||||||
indexing: search.indexing,
|
indexing: search.indexing,
|
||||||
urlPrefix: urlPrefix,
|
urlPrefix: urlPrefix,
|
||||||
settings: settings,
|
settings: settings,
|
||||||
|
flags: flags,
|
||||||
|
consoleIcons: consoleIcons
|
||||||
};
|
};
|
||||||
let page = loadOldResults ? "resultsold" : "results";
|
let page = loadOldResults ? "resultsold" : "results";
|
||||||
options = buildOptions(page, options);
|
options = buildOptions(page, options);
|
||||||
@@ -259,7 +266,7 @@ app.get("/lucky", async function (req, res) {
|
|||||||
app.get("/settings", function (req, res) {
|
app.get("/settings", function (req, res) {
|
||||||
let options = { defaultSettings: defaultSettings };
|
let options = { defaultSettings: defaultSettings };
|
||||||
let page = "settings";
|
let page = "settings";
|
||||||
options.oldSettingsAvailable = metadataSearch.authorized
|
options.oldSettingsAvailable = metadataSearch.authorized;
|
||||||
options = buildOptions(page, options);
|
options = buildOptions(page, options);
|
||||||
res.render(indexPage, options);
|
res.render(indexPage, options);
|
||||||
});
|
});
|
||||||
@@ -328,6 +335,8 @@ app.get("/info/:id", async function (req, res) {
|
|||||||
}
|
}
|
||||||
let options = {
|
let options = {
|
||||||
romFile: romInfo[0],
|
romFile: romInfo[0],
|
||||||
|
flags: flags,
|
||||||
|
consoleIcons: consoleIcons
|
||||||
};
|
};
|
||||||
let page = "info";
|
let page = "info";
|
||||||
options = buildOptions(page, options);
|
options = buildOptions(page, options);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<div class="col-12 col-lg-10 col-xl-8">
|
<div class="col-12 col-lg-10 col-xl-8">
|
||||||
<div class="col-12 text-center">
|
<div class="col-12 text-center">
|
||||||
<h2 class="text-white"><%= metadata.title %></h2>
|
<h2 class="text-white"><%= metadata.title %></h2>
|
||||||
<p class="text-secondary"><%= file.category %></p>
|
<p class="text-secondary"><%= file.category %> <%- consoleIcons.createConsoleImage(file.category) %></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="row ml-1">
|
<div class="row ml-1">
|
||||||
<img class="coverart col-md d-block mx-auto" src="<%= coverUrl %>" href="<%= file.path %>">
|
<img class="coverart col-md d-block mx-auto" src="<%= coverUrl %>" href="<%= file.path %>">
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
<% } %>
|
<% } %>
|
||||||
<% if(file.region) {%>
|
<% if(file.region) {%>
|
||||||
<div>
|
<div>
|
||||||
<p><span class="info"><%= __('search.region') %></span> <%= file.region %></p>
|
<p><span class="info"><%= __('search.region') %></span> <%= file.region %> <%- flags.createFlag(file.region) %></p>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
<% if(metadata.genre) {%>
|
<% if(metadata.genre) {%>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
%>
|
%>
|
||||||
<link rel="stylesheet" href="/public/css/result.css">
|
<link rel="stylesheet" href="/public/css/result.css">
|
||||||
<div class="row w-100 m-0">
|
<div class="row w-100 m-0">
|
||||||
<form class="ml-2 form-inline w-100" action="/search">
|
<form id="searchform" class="ml-2 form-inline w-100" action="/search">
|
||||||
<div class="w-100 align-items-center">
|
<div class="w-100 align-items-center">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<input type="hidden" name="s" id="searchSettings">
|
<input type="hidden" name="s" id="searchSettings">
|
||||||
<input id="search" type="text" class="w-50 form-control bg-dark text-white ml-2" name="q" value="<%= query %>" autocomplete="off" placeholder="<%= __('search.placeholder') %>">
|
<input id="search" type="text" class="w-50 form-control bg-dark text-white ml-2" name="q" value="<%= query %>" autocomplete="off" placeholder="<%= __('search.placeholder') %>">
|
||||||
<button type="submit" class="btn btn-secondary ml-2"><%= __('search.button') %></button>
|
<button type="submit" class="btn btn-secondary ml-2"><div id="loading" class="hidden spinner-border text-dark" role="status"></div><%= __('search.button') %></button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<ul class="SuggestionList col-sm-12" id="suggestionList" style="width: 50%;left: 195px;"></ul>
|
<ul class="SuggestionList col-sm-12" id="suggestionList" style="width: 50%;left: 195px;"></ul>
|
||||||
@@ -91,4 +91,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script defer>
|
||||||
|
$( "#searchform" ).on( "submit", function( event ) {
|
||||||
|
$("#loading").removeClass('hidden')
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<input type="hidden" name="s" id="searchSettings">
|
<input type="hidden" name="s" id="searchSettings">
|
||||||
<input id="search" type="text" class="w-50 form-control bg-dark text-white ml-2" name="q" value="<%= query %>" autocomplete="off" placeholder="<%= __('search.placeholder') %>">
|
<input id="search" type="text" class="w-50 form-control bg-dark text-white ml-2" name="q" value="<%= query %>" autocomplete="off" placeholder="<%= __('search.placeholder') %>">
|
||||||
<button type="submit" class="btn btn-secondary ml-2"><%= __('search.button') %></button>
|
<button type="submit" class="btn btn-secondary ml-2"><div id="loading" class="hidden spinner-border text-dark" role="status"></div><%= __('search.button') %></button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<ul class="SuggestionList col-sm-12" id="suggestionList" style="width: 50%;left: 195px;"></ul>
|
<ul class="SuggestionList col-sm-12" id="suggestionList" style="width: 50%;left: 195px;"></ul>
|
||||||
@@ -175,4 +175,9 @@
|
|||||||
// window.location = location.protocol + '//' + location.host + location.pathname + '?' + URLParams.toString()
|
// window.location = location.protocol + '//' + location.host + location.pathname + '?' + URLParams.toString()
|
||||||
// })
|
// })
|
||||||
// })
|
// })
|
||||||
|
</script>
|
||||||
|
<script defer>
|
||||||
|
$( "#searchform" ).on( "submit", function( event ) {
|
||||||
|
$("#loading").removeClass('hidden')
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -5,17 +5,22 @@
|
|||||||
<%= __('nav.search') %>!
|
<%= __('nav.search') %>!
|
||||||
</pre>
|
</pre>
|
||||||
<div class="text-center text-white">
|
<div class="text-center text-white">
|
||||||
<form>
|
<form id="searchform">
|
||||||
<input type="hidden" name="s" id="searchSettings">
|
<input type="hidden" name="s" id="searchSettings">
|
||||||
<input type="hidden" name="old" id="oldResults">
|
<input type="hidden" name="old" id="oldResults">
|
||||||
<input id="search" type="text" style="width: 80%;display: inline;" class="form-control bg-dark text-white mb-2"
|
<input id="search" type="text" style="width: 80%;display: inline;" class="form-control bg-dark text-white mb-2"
|
||||||
name="q" autocomplete="off" placeholder="<%= __('search.placeholder') %>">
|
name="q" autocomplete="off" placeholder="<%= __('search.placeholder') %>">
|
||||||
<ul class="SuggestionList col-sm-12" id="suggestionList" style="width: 78%;left: 11%;"></ul>
|
<ul class="SuggestionList col-sm-12" id="suggestionList" style="width: 78%;left: 11%;"></ul>
|
||||||
<div>
|
<div>
|
||||||
<button type="submit" formaction="/search" class="btn btn-secondary"><%= __('search.button') %></button>
|
<button type="submit" formaction="/search" class="btn btn-secondary"><div id="loading" class="hidden spinner-border text-dark" role="status"></div><%= __('search.button') %></button>
|
||||||
<button type="submit" formaction="/lucky" class="btn btn-secondary"><%= __('search.lucky') %></button>
|
<button type="submit" formaction="/lucky" class="btn btn-secondary"><%= __('search.lucky') %></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script defer>
|
||||||
|
$( "#searchform" ).on( "submit", function( event ) {
|
||||||
|
$("#loading").removeClass('hidden')
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -8,10 +8,10 @@
|
|||||||
<img class="coverart" src="<%= coverUrl %>" href="<%= file.path %>">
|
<img class="coverart" src="<%= coverUrl %>" href="<%= file.path %>">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md">
|
<div class="col-md">
|
||||||
<p class="title"><a href="<%= file.path %>"><%= metadata.title || file.filename %></a></p>
|
<p class="title"><a href="/info/<%=file.id %>"><%= metadata.title || file.filename %></a></p>
|
||||||
<p class="info"><span class="infoitem badge badge-secondary"><%= __('search.released') %>: <%= metadata.releasedate || file.date %></span>
|
<p class="info"><span class="infoitem badge badge-secondary"><%= __('search.released') %> <%= metadata.releasedate || file.date %></span>
|
||||||
<span class="infoitem badge badge-secondary"><%= __('search.region') %> <%= file.region %></span>
|
<span class="infoitem badge badge-secondary"><%= __('search.region') %> <%= file.region %> <%- flags.createFlag(file.region) %></span>
|
||||||
<span class="infoitem badge badge-secondary"><%= __('search.platform') %> <%= file.category %></span>
|
<span class="infoitem badge badge-secondary"><%= __('search.platform') %> <%= file.category %> <%- consoleIcons.createConsoleImage(file.category) %></span>
|
||||||
<% if(metadata.genre){ %>
|
<% if(metadata.genre){ %>
|
||||||
<span class="infoitem badge badge-secondary"><%= __('search.genre') %> <%= JSON.parse(metadata.genre).join(' / ') %></span>
|
<span class="infoitem badge badge-secondary"><%= __('search.genre') %> <%= JSON.parse(metadata.genre).join(' / ') %></span>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|||||||
@@ -43,4 +43,11 @@
|
|||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
height: auto;
|
height: auto;
|
||||||
width: 240px;
|
width: 240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.console {
|
||||||
|
height: 1.5rem;
|
||||||
|
}
|
||||||
|
.text-secondary{
|
||||||
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
@@ -20,13 +20,14 @@
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #f0a400;
|
color: #f0a400;
|
||||||
margin-bottom: 0!important;
|
margin-bottom: 0!important;
|
||||||
|
font-size: 1.25em;
|
||||||
}
|
}
|
||||||
.title a {
|
.title a {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #f0a400;
|
color: #f0a400;
|
||||||
}
|
}
|
||||||
.info {
|
.info {
|
||||||
font-size: 0.8em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
.file {
|
.file {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
@@ -36,7 +37,21 @@
|
|||||||
}
|
}
|
||||||
.infoitem{
|
.infoitem{
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
|
padding-left: 0.5em;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
height: 1.75em;
|
||||||
|
vertical-align: middle;
|
||||||
|
align-content: center;
|
||||||
}
|
}
|
||||||
.cover{
|
.cover{
|
||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
|
.flag{
|
||||||
|
height: 1.25em;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.console {
|
||||||
|
height: 1.25em;
|
||||||
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
@@ -144,3 +144,18 @@ td a {
|
|||||||
position: relative;
|
position: relative;
|
||||||
z-index: 9999 !important;
|
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;
|
||||||
|
}
|
||||||
32
views/public/js/video.js
Normal file
32
views/public/js/video.js
Normal file
@@ -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,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user