auto-detect listings, player skip

This commit is contained in:
Jon Dough
2024-01-27 15:09:07 +05:30
parent b2283a33f9
commit fa4714cfc3
7 changed files with 73 additions and 72 deletions

2
.gitignore vendored
View File

@@ -1,7 +1,7 @@
.env
node_modules
static_assets
host_info.json
favourites_info.json
*.js
package-lock.json
build

View File

@@ -30,7 +30,9 @@ Make sure to set a master password! See `.env.example`. Enter in the master pass
# Tips
## Adding media
Add it to the relevant static directory (`/static_assets/anime_assets`, `/static_assets/manga_assets`, or `/static_assets/music_assets`), and create an entry for it in `host_info.json`. See `host_info.json.example` for an example.
Add it to the relevant static directory (`/static_assets/anime_assets`, `/static_assets/manga_assets`, or `/static_assets/music_assets`), and just rerun `npm run build`.
To mark it as a favourite, create an entry for it in `favourites_info.json`. See `favourites_info.json.example` for an example.
## Hosting Multiple TOR Hidden Services
If you are running multiple TOR hidden services, you will need to modify the [.torrc file](https://stackoverflow.com/questions/14321214/how-to-run-multiple-tor-processes-at-once-with-different-exit-ips#18895491).

View File

@@ -2,17 +2,20 @@ import * as path from 'path';
import { readdirSync } from 'fs';
import { Renderer } from './ryuji.js';
import { Builder } from './saki.js';
import _host_info from './host_info.json';
import _favourites_info from './favourites_info.json';
//todo: music?
interface Listing {
name: string;
type: "anime" | "manga" | "music";
interface FavouritesInfo {
favourites: {
listing: boolean; //whether to mark entire listing as favourite
chapters: string[]; //favourite chapters
}; //marked as not optional here, but in the actual host_info.json file, it is optional
};
}
interface Listing extends FavouritesInfo {
name: string;
type: "anime" | "manga" | "music";
}
interface DirectoryVars {
@@ -37,20 +40,27 @@ interface MangaVars {
prev_chapter?: string | boolean;
}
const listings: Listing[] = _host_info.listings.map(
(listing: any) =>
//add empty "favourites" if not present in the json
listing.favourites ? listing : {
...listing,
favourites: {
listing: false,
chapters: []
}
}
).filter(
(listing: any): listing is Listing =>
typeof listing.name === "string" && (listing?.type === "anime" || listing?.type === "manga" || listing?.type === "music")
);
const favourites_info: Record<string, FavouritesInfo> = _favourites_info;
let listings: Listing[] = [];
//add listings from static_assets/anime_assets
for (let listing_type of ["anime", "manga", "music"]) {
listings.push(...readdirSync(path.join(__dirname, `/static_assets/${listing_type}_assets`)).map(
(listing_name: string) =>
({
name: listing_name,
type: listing_type,
favourites: {
listing: favourites_info[listing_name] ? favourites_info[listing_name].favourites.listing : false,
chapters: favourites_info[listing_name] ? favourites_info[listing_name].favourites.chapters : [],
}
})
).filter(
(listing: any): listing is Listing =>
typeof listing.name === "string" && (listing?.type === "anime" || listing?.type === "manga" || listing?.type === "music")
));
}
let renderer: Renderer = new Renderer("templates", "components");
let builder: Builder = new Builder("/build");

View File

@@ -0,0 +1,31 @@
{
"senpai-wa-otokonoko": {
"favourites": {
"listing": true,
"chapters": [
"c001",
"c099"
]
}
}
"bocchi-the-boulder": {
"favourites": {
"listing": true,
"chapters": []
}
},
"not-buna": {
"favourites": {
"listing": false,
"chapters": [
"aira"
]
}
},
"arizona-philips": {
"favourites": {
"listing": true,
"chapters": []
}
}
}

View File

@@ -1,44 +0,0 @@
{
"listings": [
{
"name": "senpai-wa-otokonoko",
"type": "manga",
"favourites": {
"listing": true,
"chapters": ["c001"]
}
},
{
"name": "shiitake-simulation",
"type": "manga"
},
{
"name": "bocchi-the-boulder",
"type": "anime",
"favourites": {
"listing": true,
"chapters": []
}
},
{
"name": "yoroshiku",
"type": "music"
},
{
"name": "not-buna",
"type": "music",
"favourites": {
"listing": false,
"chapters": ["aira"]
}
},
{
"name": "arizona-philips",
"type": "music",
"favourites": {
"listing": true,
"chapters": []
}
}
]
}

View File

@@ -89,10 +89,10 @@ export class Renderer {
if (recursion_layer > 5) throw Error("Components more than 5 layers deep, components may be referencing each other in infinite loop.");
if (typeof exp_parts[1] !== "string") throw Error("`component:` statement missing component file name afterwards");
let file_name: string = exp_parts[1];
if (!file_name.includes(".")) {
file_name += this.file_extension;
}
rendered += this.render_template(Renderer.concat_path(this.components_dir, file_name), vars, recursion_layer+1);
if (!file_name.includes(".")) {
file_name += this.file_extension;
}
rendered += this.render_template(Renderer.concat_path(this.components_dir, file_name), vars, recursion_layer+1);
} else if (exp_parts[0] === "for") {
if (for_loops[for_loops.length-1]?.index === index) {
//for loop already exists, just continue and do nothing

View File

@@ -7,7 +7,6 @@
<style>
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
@@ -34,6 +33,8 @@
<br>
<audio id="audio" type="audio/mpeg" controls>
</audio>
<br>
<input type="button" value="Skip Song" onclick="next_song()"/>
</div>
<!--I would use <details> here, but maybe too abusive-->
<div>
@@ -74,7 +75,7 @@
played.push(played);
audio_ele.src = `/music_assets/${random_song_start}.mp3`;
//"ended" event
audio_ele.addEventListener("ended", () => {
function next_song() {
const not_played = playable_songs.filter((song) => !played.includes(song));
if (not_played.length === 0) return;
let random_song_next = not_played[Math.floor(Math.random() * not_played.length)];
@@ -82,7 +83,8 @@
played.push(random_song_next);
audio_ele.src = `/music_assets/${random_song_next}.mp3`;
audio_ele.play();
});
}
audio_ele.addEventListener("ended", next_song);
//show filters toggle
const show_filters = document.getElementById("show-filters");
function filter_check() {