mirror of
https://github.com/open-goal/launcher.git
synced 2024-10-19 14:47:36 -04:00
switch to doT templates and related cleanup
This commit is contained in:
parent
58627414f5
commit
87e50f2edb
|
@ -1,42 +0,0 @@
|
|||
// TODO some minimal templating might help - https://olado.github.io/doT/index.html
|
||||
|
||||
export const jak1_sidebar = `<div class="games">
|
||||
<div class="jak-1 nav-item active">
|
||||
<a data-tooltip="Jak & Daxter: The Precursor Legacy">
|
||||
<img src="src/assets/images/jak-tpl.png">
|
||||
</a>
|
||||
</div>
|
||||
<div class="jak-2 nav-item">
|
||||
<a data-tooltip="Jak 2">
|
||||
<img src="src/assets/images/jak-2.png">
|
||||
</a>
|
||||
</div>
|
||||
<div class="jak-3 nav-item">
|
||||
<a data-tooltip="Jak 3">
|
||||
<img src="src/assets/images/jak-3.png">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="spacer"></div>
|
||||
|
||||
<div class="controls">
|
||||
<div class="console nav-item">
|
||||
<a data-tooltip="Toggle Debug Console">
|
||||
<i class="bi bi-terminal-fill"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="settings nav-item">
|
||||
<a data-tooltip="Settings">
|
||||
<i class="bi bi-sliders" key="settings"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
export const jak1_main = `<div class="flex-center">
|
||||
<div class="logo">
|
||||
<img id="logo" width="65%" src="src/assets/images/logo.png">
|
||||
</div>
|
||||
|
||||
<div class="buttons" id="launcherControls"></div>
|
||||
</div>`;
|
48
index.html
48
index.html
|
@ -11,54 +11,12 @@
|
|||
<body>
|
||||
<div class="video-container">
|
||||
<div class="overlay"></div>
|
||||
<video id="background" src="src/assets/videos/background.mp4" autoplay muted loop></video>
|
||||
<video id="backgroundVideo" src="src/assets/videos/background.mp4" autoplay muted loop></video>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="sidebar">
|
||||
<div class="games">
|
||||
<div class="jak-1 nav-item active">
|
||||
<a data-tooltip="Jak & Daxter: The Precursor Legacy">
|
||||
<img src="src/assets/images/jak-tpl.png">
|
||||
</a>
|
||||
</div>
|
||||
<div class="jak-2 nav-item disabled">
|
||||
<a data-tooltip="Jak 2 - Not Available!">
|
||||
<img src="src/assets/images/jak-2.png">
|
||||
</a>
|
||||
</div>
|
||||
<div class="jak-3 nav-item disabled">
|
||||
<a data-tooltip="Jak 3 - Not Available!">
|
||||
<img src="src/assets/images/jak-3.png">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="spacer"></div>
|
||||
|
||||
<div class="controls">
|
||||
<div class="console nav-item">
|
||||
<a data-tooltip="Toggle Debug Console">
|
||||
<i class="bi bi-terminal-fill"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="settings nav-item">
|
||||
<a data-tooltip="Settings">
|
||||
<i class="bi bi-sliders" key="settings"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="main">
|
||||
<div class="flex-center">
|
||||
<div class="logo">
|
||||
<img id="logo" width="65%" src="src/assets/images/logo.png">
|
||||
</div>
|
||||
|
||||
<div class="buttons" id="launcherControls"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="sidebar"></div>
|
||||
<div id="main"></div>
|
||||
</div>
|
||||
|
||||
<script defer type="module" src="/main.js"></script>
|
||||
|
|
110
main.js
110
main.js
|
@ -1,67 +1,35 @@
|
|||
import './style.css'
|
||||
import { actions, general_pane, files_pane, links_pane } from './components/settings/settings';
|
||||
import { jak1_main, jak1_sidebar } from './components/jak1/jak1';
|
||||
import { isoSeries } from './src/utils/iso';
|
||||
import { launchGame } from './src/utils/launch';
|
||||
import { getInstallStatus } from './src/utils/store';
|
||||
import { initConfig, getInstallStatus, getLastActiveGame, SupportedGame } from './src/config/config';
|
||||
import { mainTemplate } from './src/views/main.dot';
|
||||
import { sidebarTemplate } from './src/views/sidebar.dot';
|
||||
|
||||
const sidebar = document.querySelector('.sidebar');
|
||||
// Main App Startup Routine
|
||||
(async function () {
|
||||
// Create the default or load the config
|
||||
await initConfig();
|
||||
// Render the App
|
||||
await renderApp();
|
||||
}());
|
||||
|
||||
sidebar.onclick = e => {
|
||||
switch (e.target.getAttribute('key')) {
|
||||
case 'return':
|
||||
document.querySelector('.main').innerHTML = jak1_main;
|
||||
document.querySelector('.sidebar').innerHTML = jak1_sidebar;
|
||||
break;
|
||||
case 'settings':
|
||||
document.querySelector('.main').innerHTML = general_pane;
|
||||
document.querySelector('.sidebar').innerHTML = actions;
|
||||
break;
|
||||
case 'general':
|
||||
document.querySelector('.main').innerHTML = general_pane;
|
||||
break;
|
||||
case 'links':
|
||||
document.querySelector('.main').innerHTML = links_pane;
|
||||
break;
|
||||
case 'files':
|
||||
document.querySelector('.main').innerHTML = files_pane;
|
||||
break;
|
||||
}
|
||||
renderControls();
|
||||
}
|
||||
// Main App Rendering Handler
|
||||
async function renderApp() {
|
||||
const activeGame = await getLastActiveGame();
|
||||
const gameInstalled = await getInstallStatus(activeGame);
|
||||
document.getElementById("sidebar").innerHTML = sidebarTemplate({
|
||||
jak1Active: activeGame.name == SupportedGame.Jak1.name,
|
||||
jak2Active: activeGame.name == SupportedGame.Jak2.name,
|
||||
jak3Active: activeGame.name == SupportedGame.Jak3.name,
|
||||
jakxActive: activeGame.name == SupportedGame.JakX.name,
|
||||
});
|
||||
document.getElementById("main").innerHTML = mainTemplate({
|
||||
gameInstalled: gameInstalled
|
||||
});
|
||||
|
||||
class SupportedGame {
|
||||
static Jak1 = new SupportedGame("Jak 1")
|
||||
static Jak2 = new SupportedGame("Jak 2")
|
||||
static Jak3 = new SupportedGame("Jak 3")
|
||||
static JakX = new SupportedGame("Jak X")
|
||||
|
||||
constructor(name) {
|
||||
this.name = name
|
||||
}
|
||||
}
|
||||
|
||||
async function isGameSetup(supportedGame) {
|
||||
if (supportedGame == SupportedGame.Jak1) {
|
||||
// TODO - check the installation directory and such, wherever that ends up being
|
||||
const isInstalled = await getInstallStatus(supportedGame.name);
|
||||
return isInstalled;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - detect last played game, right now its assumed that jak 1 is always selected by default
|
||||
let activeGame = SupportedGame.Jak1;
|
||||
|
||||
renderControls();
|
||||
|
||||
export async function renderControls() {
|
||||
if (document.getElementById("launcherControls") == undefined) {
|
||||
return;
|
||||
}
|
||||
if (await isGameSetup(activeGame)) {
|
||||
document.getElementById("launcherControls").innerHTML = `<button id="configBtn">CONFIG</button><button id="playBtn">PLAY</button>`;
|
||||
// Setup Event Handlers
|
||||
if (gameInstalled) {
|
||||
document.getElementById("playBtn").onclick = () => {
|
||||
launchGame();
|
||||
}
|
||||
|
@ -69,9 +37,33 @@ export async function renderControls() {
|
|||
// TODO
|
||||
}
|
||||
} else {
|
||||
document.getElementById("launcherControls").innerHTML = `<button id="setupBtn">SETUP</button>`;
|
||||
document.getElementById("setupBtn").onclick = () => {
|
||||
isoSeries();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
|
||||
// TODO - not cleaned up yet!
|
||||
sidebar.onclick = e => {
|
||||
switch (e.target.getAttribute('key')) {
|
||||
case 'return':
|
||||
document.getElementById('main').innerHTML = jak1_main;
|
||||
document.getElementById('sidebar').innerHTML = jak1_sidebar;
|
||||
break;
|
||||
case 'settings':
|
||||
document.getElementById('main').innerHTML = general_pane;
|
||||
document.getElementById('sidebar').innerHTML = actions;
|
||||
break;
|
||||
case 'general':
|
||||
document.getElementById('main').innerHTML = general_pane;
|
||||
break;
|
||||
case 'links':
|
||||
document.getElementById('main').innerHTML = links_pane;
|
||||
break;
|
||||
case 'files':
|
||||
document.getElementById('main').innerHTML = files_pane;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
12
package-lock.json
generated
12
package-lock.json
generated
|
@ -10,6 +10,7 @@
|
|||
"dependencies": {
|
||||
"@tauri-apps/api": "^1.0.0-rc.3",
|
||||
"bootstrap-icons": "^1.8.1",
|
||||
"dot": "^2.0.0-beta.1",
|
||||
"tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -2288,6 +2289,12 @@
|
|||
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/dot": {
|
||||
"version": "2.0.0-beta.1",
|
||||
"resolved": "https://registry.npmjs.org/dot/-/dot-2.0.0-beta.1.tgz",
|
||||
"integrity": "sha512-kxM7fSnNQTXOmaeGuBSXM8O3fEsBb7XSDBllkGbRwa0lJSJTxxDE/4eSNGLKZUmlFw0f1vJ5qSV2BljrgQtgIA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dot-prop": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
|
||||
|
@ -8682,6 +8689,11 @@
|
|||
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
|
||||
"dev": true
|
||||
},
|
||||
"dot": {
|
||||
"version": "2.0.0-beta.1",
|
||||
"resolved": "https://registry.npmjs.org/dot/-/dot-2.0.0-beta.1.tgz",
|
||||
"integrity": "sha512-kxM7fSnNQTXOmaeGuBSXM8O3fEsBb7XSDBllkGbRwa0lJSJTxxDE/4eSNGLKZUmlFw0f1vJ5qSV2BljrgQtgIA=="
|
||||
},
|
||||
"dot-prop": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
"dependencies": {
|
||||
"@tauri-apps/api": "^1.0.0-rc.3",
|
||||
"bootstrap-icons": "^1.8.1",
|
||||
"dot": "^2.0.0-beta.1",
|
||||
"tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store"
|
||||
}
|
||||
}
|
||||
|
|
90
src/config/config.js
Normal file
90
src/config/config.js
Normal file
|
@ -0,0 +1,90 @@
|
|||
import { createDir, readTextFile, writeFile } from '@tauri-apps/api/fs';
|
||||
import { appDir, join } from '@tauri-apps/api/path';
|
||||
|
||||
import { Store } from 'tauri-plugin-store-api';
|
||||
|
||||
export class SupportedGame {
|
||||
static Jak1 = new SupportedGame("Jak 1")
|
||||
static Jak2 = new SupportedGame("Jak 2")
|
||||
static Jak3 = new SupportedGame("Jak 3")
|
||||
static JakX = new SupportedGame("Jak X")
|
||||
|
||||
constructor(name) {
|
||||
this.name = name
|
||||
}
|
||||
|
||||
static fromName(name) {
|
||||
switch (name) {
|
||||
case this.Jak1.name:
|
||||
return this.Jak1;
|
||||
case this.Jak2.name:
|
||||
return this.Jak2;
|
||||
case this.Jak3.name:
|
||||
return this.Jak3;
|
||||
case this.JakX.name:
|
||||
return this.JakX;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const key_lastActiveGame = "lastActiveGame";
|
||||
const store = new Store('settings.json');
|
||||
|
||||
// TODO - a general -- does a file exist function -- would be nice
|
||||
|
||||
export async function initConfig() {
|
||||
const path = await join(await appDir(), 'settings.json');
|
||||
try {
|
||||
await readTextFile(path);
|
||||
} catch (error) {
|
||||
console.log('[Launcher]: Settings file not found or could not be loaded!');
|
||||
await createDir(await appDir(), { recursive: true });
|
||||
const initSettings = {
|
||||
[SupportedGame.Jak1.name]: { "installed": false },
|
||||
[SupportedGame.Jak2.name]: { "installed": false },
|
||||
[SupportedGame.Jak3.name]: { "installed": false },
|
||||
[key_lastActiveGame]: SupportedGame.Jak1.name
|
||||
};
|
||||
await writeFile({ contents: JSON.stringify(initSettings, null, 2), path: path });
|
||||
console.log('[Launcher]: Settings file initialized');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {SupportedGame} supportedGame
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
export async function getInstallStatus(supportedGame) {
|
||||
await store.load();
|
||||
const val = await store.get(supportedGame.name);
|
||||
if (val == null || !'installed' in val) {
|
||||
return false;
|
||||
}
|
||||
return val.installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<SupportedGame>}
|
||||
*/
|
||||
export async function getLastActiveGame() {
|
||||
await store.load();
|
||||
const game = await store.get(key_lastActiveGame);
|
||||
if (game == null) {
|
||||
return SupportedGame.Jak1;
|
||||
}
|
||||
return SupportedGame.fromName(game);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {SupportedGame} supportedGame
|
||||
* @param {boolean} installed
|
||||
* @returns
|
||||
*/
|
||||
export async function setInstallStatus(supportedGame, installed) {
|
||||
await store.load();
|
||||
await store.set(supportedGame.name, { "installed": installed });
|
||||
await store.save();
|
||||
}
|
|
@ -2,7 +2,7 @@ import { message } from "@tauri-apps/api/dialog";
|
|||
import { platform } from "@tauri-apps/api/os";
|
||||
import { appDir, join } from "@tauri-apps/api/path";
|
||||
import { Command } from "@tauri-apps/api/shell";
|
||||
import { setInstallStatus } from '../utils/store';
|
||||
import { setInstallStatus } from '../config/config';
|
||||
|
||||
export async function buildGame() {
|
||||
const userPlatform = await platform();
|
||||
|
@ -24,7 +24,7 @@ export async function buildGame() {
|
|||
console.log(`Compiler finished with code ${data.code} and signal ${data.signal}`);
|
||||
if (data.code === 0) {
|
||||
message('Game Ready to play!');
|
||||
setInstallStatus();
|
||||
setInstallStatus(SupportedGame.Jak1, true);
|
||||
return 'Compiler finished';
|
||||
} else {
|
||||
message('Game Ready to play!');
|
||||
|
@ -69,4 +69,4 @@ export async function launchGame() {
|
|||
|
||||
const child = await launch.spawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
import { Store } from 'tauri-plugin-store-api';
|
||||
import { renderControls } from '../../main';
|
||||
import { createDir, readTextFile, writeFile } from '@tauri-apps/api/fs';
|
||||
import { appDir, join } from '@tauri-apps/api/path';
|
||||
|
||||
const store = new Store('settings.json');
|
||||
|
||||
// TODO - a general -- does a file exist function -- would be nice
|
||||
|
||||
(async function initStore() {
|
||||
const path = await join(await appDir(), 'settings.json');
|
||||
try {
|
||||
await readTextFile(path);
|
||||
} catch (error) {
|
||||
await createDir(await appDir(), { recursive: true });
|
||||
const initSettings = {
|
||||
"Jak 1": { "installed": false },
|
||||
"Jak 2": { "installed": false },
|
||||
"Jak 3": { "installed": false }
|
||||
};
|
||||
const x = await writeFile({ contents: JSON.stringify(initSettings, null, 2), path: path });
|
||||
console.log('Created settings.json file');
|
||||
// once again probably not a good idea to use this render function here
|
||||
renderControls();
|
||||
}
|
||||
})();
|
||||
|
||||
export async function getInstallStatus(game) {
|
||||
await store.load();
|
||||
const { installed } = await store.get(game);
|
||||
return installed;
|
||||
}
|
||||
|
||||
export async function setInstallStatus() {
|
||||
await store.load();
|
||||
await store.set("Jak 1", { "installed": true });
|
||||
await store.save();
|
||||
// calling this render function from here is probably a bad idea but im not sure how else to rerender the page
|
||||
renderControls();
|
||||
return;
|
||||
}
|
17
src/views/main.dot.js
Normal file
17
src/views/main.dot.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import * as doT from 'dot';
|
||||
|
||||
export let mainTemplate = doT.template(`
|
||||
<div class="flex-center">
|
||||
<div class="logo">
|
||||
<img id="logo" width="65%" src="src/assets/images/logo.png">
|
||||
</div>
|
||||
<div class="buttons" id="launcherControls">
|
||||
{{? it.gameInstalled }}
|
||||
<button id="configBtn">CONFIG</button>
|
||||
<button id="playBtn">PLAY</button>
|
||||
{{?? true }}
|
||||
<button id="setupBtn">SETUP</button>
|
||||
{{?}}
|
||||
</div>
|
||||
</div>
|
||||
`);
|
34
src/views/sidebar.dot.js
Normal file
34
src/views/sidebar.dot.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
import * as doT from 'dot';
|
||||
|
||||
export let sidebarTemplate = doT.template(`
|
||||
<div class="games">
|
||||
<div class="jak-1 nav-item{{? it.jak1Active }} active{{?? true}} disabled{{?}}">
|
||||
<a data-tooltip="Jak & Daxter: The Precursor Legacy">
|
||||
<img src="src/assets/images/jak-tpl.png">
|
||||
</a>
|
||||
</div>
|
||||
<div class="jak-2 nav-item{{? it.jak2Active }} active{{?? true}} disabled{{?}}">
|
||||
<a data-tooltip="Jak 2 - Not Available!">
|
||||
<img src="src/assets/images/jak-2.png">
|
||||
</a>
|
||||
</div>
|
||||
<div class="jak-3 nav-item{{? it.jak3Active }} active{{?? true}} disabled{{?}}">
|
||||
<a data-tooltip="Jak 3 - Not Available!">
|
||||
<img src="src/assets/images/jak-3.png">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
<div class="controls">
|
||||
<div class="console nav-item">
|
||||
<a data-tooltip="Toggle Debug Console">
|
||||
<i class="bi bi-terminal-fill"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="settings nav-item">
|
||||
<a data-tooltip="Settings">
|
||||
<i class="bi bi-sliders" key="settings"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
|
@ -46,7 +46,7 @@ body {
|
|||
opacity: 0.35;
|
||||
}
|
||||
|
||||
#background {
|
||||
#backgroundVideo {
|
||||
z-index: -1;
|
||||
height: 100vh;
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ body {
|
|||
display: flex;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
#sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
|
@ -66,7 +66,7 @@ body {
|
|||
max-width: 10vw;
|
||||
}
|
||||
|
||||
.sidebar:hover {
|
||||
#sidebar:hover {
|
||||
opacity: 100%;
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ body {
|
|||
font-size: 35px;
|
||||
}
|
||||
|
||||
.main {
|
||||
#main {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
|
|
Loading…
Reference in a new issue