Merge pull request #59 from trippjoe/t/splash-screen

T/splash screen
This commit is contained in:
tripp 2022-06-18 21:29:18 -04:00 committed by GitHub
commit 1cda948b54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 237 additions and 62 deletions

21
splashscreen.html Normal file
View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Splash</title>
</head>
<body
style="
padding: 0;
margin: 0;
overflow: hidden;
background-image: url(./src/assets/images/logo.png);
background-repeat: no-repeat;
background-size: 100vw;
background-position: top;
"
></body>
</html>

24
src-tauri/Cargo.lock generated
View file

@ -55,7 +55,7 @@ checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
[[package]]
name = "app"
version = "0.2.2"
version = "0.2.3"
dependencies = [
"serde",
"serde_json",
@ -1419,6 +1419,12 @@ dependencies = [
"autocfg",
]
[[package]]
name = "minisign-verify"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "933dca44d65cdd53b355d0b73d380a2ff5da71f87f036053188bf1eab6a19881"
[[package]]
name = "miniz_oxide"
version = "0.5.3"
@ -2668,6 +2674,7 @@ checksum = "81af088a87f908dab3a268f92e3c331e911bed6b1756bbfaeadedfe9dd40fe4f"
dependencies = [
"anyhow",
"attohttpc",
"base64",
"bincode",
"cocoa",
"dirs-next",
@ -2681,6 +2688,7 @@ dependencies = [
"heck 0.4.0",
"http",
"ignore",
"minisign-verify",
"notify-rust",
"objc",
"once_cell",
@ -2706,12 +2714,14 @@ dependencies = [
"tauri-utils",
"tempfile",
"thiserror",
"time",
"tokio",
"url",
"uuid 1.1.1",
"webkit2gtk",
"webview2-com",
"windows 0.37.0",
"zip",
]
[[package]]
@ -2908,6 +2918,7 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd"
dependencies = [
"itoa 1.0.2",
"libc",
"num_threads",
]
@ -3634,3 +3645,14 @@ name = "xml-rs"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
[[package]]
name = "zip"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf225bcf73bb52cbb496e70475c7bd7a3f769df699c0020f6c7bd9a96dcf0b8d"
dependencies = [
"byteorder",
"crc32fast",
"crossbeam-utils",
]

View file

@ -17,7 +17,7 @@ tauri-build = { version = "1.0.0-rc.12", features = [] }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.0.0-rc.14", features = ["api-all", "devtools"] }
tauri = { version = "1.0.0-rc.14", features = ["api-all", "devtools", "updater"] }
[dependencies.tauri-plugin-store]
git = "https://github.com/tauri-apps/tauri-plugin-store"

View file

@ -1,5 +1,6 @@
use std::process::Command;
use tauri::command;
use tauri::Manager;
#[derive(Debug, serde::Serialize)]
pub enum CommandError {
@ -60,3 +61,13 @@ fn open_appdir(dir: String) {
.spawn()
.unwrap();
}
#[tauri::command]
pub async fn close_splashscreen(window: tauri::Window) {
// Close splashscreen
if let Some(splashscreen) = window.get_window("splashscreen") {
splashscreen.close().unwrap();
}
// Show main window
window.get_window("main").unwrap().show().unwrap();
}

View file

@ -6,13 +6,18 @@
use tauri_plugin_store::PluginBuilder;
mod commands;
use commands::close_splashscreen;
use commands::get_highest_simd;
use commands::open_dir;
fn main() {
tauri::Builder::default()
.plugin(PluginBuilder::default().build())
.invoke_handler(tauri::generate_handler![get_highest_simd, open_dir])
.invoke_handler(tauri::generate_handler![
get_highest_simd,
open_dir,
close_splashscreen
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

View file

@ -88,8 +88,20 @@
"height": 600,
"resizable": false,
"fullscreen": false,
"x": 1750,
"y": 0
"visible": false,
"center": true
},
{
"width": 600,
"height": 120,
"center": true,
"decorations": false,
"transparent": true,
"resizable": false,
"fullscreen": false,
"url": "./src/splash/index.html",
"label": "splashscreen",
"visible": true
}
],
"security": {

View file

@ -9,14 +9,20 @@
import Sidebar from "./components/sidebar/Sidebar.svelte";
import Background from "./components/background/Background.svelte";
import { initConfig } from "$lib/config";
import { isInDebugMode } from "$lib/setup";
import { checkRequirements, isInDebugMode } from "$lib/setup";
import { areRequirementsMet } from "$lib/config";
import { closeSplashScreen } from "$lib/commands";
let revokeSpecificActions = false;
// Events
onMount(async () => {
await initConfig();
});
// onMount(async () => {
// await initConfig();
// if (!(await areRequirementsMet())) {
// await checkRequirements();
// }
// await closeSplashScreen();
// });
if (!isInDebugMode()) {
revokeSpecificActions = true;
@ -54,12 +60,10 @@
<Sidebar />
<!-- TODO - pass background component current active game -->
<Background {bgVideo} />
<div class="test">
<div id="main">
<Route path="/" component={Jak1} />
<Route path="/jak1" component={Jak1} />
<Route path="/settings" component={Settings} />
</div>
<div id="main">
<Route path="/" component={Jak1} />
<Route path="/jak1" component={Jak1} />
<Route path="/settings" component={Settings} />
</div>
</div>
</Router>

View file

@ -1,12 +1,12 @@
<script>
import { Console } from "../../stores/InstallStore";
import "./console.css"
import "./console.css";
</script>
<div class="row">
<details>
<summary>Installation Logs</summary>
<div class="logContainer" >
<div class="logContainer">
{#if $Console}
{$Console}
{/if}

View file

@ -7,6 +7,19 @@
font-family: monospace;
}
details {
min-width: 75vw;
max-width: 75vw;
}
summary {
text-align: center;
}
.logContainer {
text-align: start;
}
details > summary:hover {
cursor: pointer;
}

View file

@ -1,14 +1,12 @@
<script type="ts">
import { navigate } from "svelte-navigator";
import { filePrompt } from "$lib/utils/file";
import { setInstallStatus } from "$lib/config";
import { areRequirementsMet, setInstallStatus } from "$lib/config";
import { clearInstallLogs } from "$lib/utils/file";
import {
compileGame,
decompileGameData,
extractAndValidateISO,
isAVXSupported,
isOpenGLVersionSupported,
} from "$lib/setup";
// components
import Progress from "./Progress.svelte";
@ -16,19 +14,8 @@
import { SETUP_ERROR, SupportedGame } from "../../lib/constants";
import { InstallStatus, isInstalling } from "../../stores/InstallStore";
async function areRequirementsMet() {
try {
await isAVXSupported();
await isOpenGLVersionSupported("4.3");
return true;
} catch (err) {
// TODO - MAKE SURE FUNCTIONS USING ENUMS WHEN THROWING ERRORS
// InstallStore.update(err.message);
return false;
}
}
// TODO - set status from inside each install step function
// TODO: MOVE THIS FUNCTION TO THE LIB DIR AND DELETE IMPORTS
async function installProcess() {
let isoPath: string | string[];
isInstalling.update(() => true);
@ -53,18 +40,12 @@
</script>
<div class="content">
<!-- TODO - EXCLUDE REQUIREMENTS MET FROM PROGRESS BAR -->
<Progress />
<div style="text-align:center">
<!-- TODO - STOP THIS FROM RETRIGGER REQUIREMENTS CHECK ON PAGE CHANGE -->
{#if !$isInstalling}
{#await areRequirementsMet() then requirementsMet}
{#if requirementsMet}
<button class="btn" on:click={async () => await installProcess()}>
Setup
</button>
{/if}
{/await}
<button class="btn" on:click={async () => await installProcess()}>
Setup
</button>
{/if}
</div>
</div>

View file

@ -3,7 +3,7 @@
overflow: hidden;
height: 30px;
background-color: #ecf0f1;
width: 75%;
min-width: 45vw;
margin: 20px auto;
}

View file

@ -19,3 +19,11 @@ export async function openDir(dir: string): Promise<void> {
console.log(e);
}
}
export async function closeSplashScreen() {
try {
invoke("close_splashscreen");
} catch (e) {
console.log(e);
}
}

View file

@ -2,6 +2,7 @@ import { createDir, writeFile } from "@tauri-apps/api/fs";
import { appDir, join } from "@tauri-apps/api/path";
import { Store } from "tauri-plugin-store-api";
import { SupportedGame } from "./constants";
import { isAVXSupported } from "./setup";
import { fileExists } from "./utils/file";
class GameConfig {
@ -120,3 +121,32 @@ export async function setInstallStatus(
await store.set("games", gameConfigs);
await store.save();
}
export async function setRequirementsMet(
avx: boolean = null,
openGL: boolean = null
) {
await store.load();
await store.set("requirements", { avx, openGL });
await store.save();
return;
}
/**
* Checks the user config file to see if avx and openGL requirements are met.
*/
export async function areRequirementsMet(): Promise<Boolean> {
await store.load();
let requirements = await store.get("requirements");
if (!requirements.avx) {
console.log("Unsupported AVX");
return false;
}
if (!requirements.openGL) {
console.log("Unsupported OpenGL");
return false;
}
return true;
}

View file

@ -1,23 +1,18 @@
// TODO: update setup status messages to use typescript
export const SETUP_SUCCESS = {
avxSupported: { status: "AVX SUPPORTED", percent: 10 },
openGLSupported: { status: "OPENGL SUPPORTED", percent: 20 },
checkCompatible: { status: "Checking Compatibility", percent: 0 },
awaitingISO: { status: "Awaiting ISO File", percent: 20 },
awaitingISO: { status: "Awaiting ISO File", percent: 0 },
extractingISO: {
status: "Extracting and Validating ISO contents",
percent: 40,
percent: 25,
},
decompiling: { status: "Decompiling the game", percent: 60 },
compiling: { status: "Compiling the game", percent: 80 },
decompiling: { status: "Decompiling the game", percent: 50 },
compiling: { status: "Compiling the game", percent: 75 },
ready: { status: "Ready to Play!", percent: 100 },
};
export const SETUP_ERROR = {
unsupportedAVX: { status: "UNSUPPORTED AVX", percent: -1 },
noISO: { status: "No ISO File Selected!", percent: -1 },
unsupportedOS: { status: "Unsupported OS!", percent: -1 },
unsupportedOpenGL: { status: "UNSUPPORTED OPENGL VERSION", percent: -1 },
};
export const enum SupportedGame {

View file

@ -5,6 +5,7 @@ import { getHighestSimd } from "$lib/commands";
import { InstallStatus } from "../stores/InstallStore";
import { SETUP_SUCCESS, SETUP_ERROR, SupportedGame } from "$lib/constants";
import { appendToInstallErrorLog, appendToInstallLog } from "$lib/utils/file";
import { setRequirementsMet } from "./config";
let debugPath: string;
let sidecarOptions = {};
@ -24,14 +25,11 @@ if (isInDebugMode()) {
export async function isAVXSupported() {
const highestSIMD = await getHighestSimd();
if (highestSIMD === undefined) {
InstallStatus.update(() => SETUP_SUCCESS.avxSupported);
return true;
}
if (highestSIMD.toLowerCase().startsWith("avx")) {
InstallStatus.set(SETUP_SUCCESS.avxSupported);
return true;
}
InstallStatus.update(() => SETUP_ERROR.unsupportedAVX);
throw new Error("UNSUPPORTED AVX");
}
@ -43,9 +41,7 @@ export async function isOpenGLVersionSupported(
version: string
): Promise<boolean> {
if ((await os.platform()) === "darwin") {
InstallStatus.update(() => SETUP_ERROR.unsupportedOS);
throw new Error("Unsupported OS!");
// return RequirementStatus.Unknown;
}
// Otherwise, query for the version
let command = Command.sidecar(
@ -55,13 +51,22 @@ export async function isOpenGLVersionSupported(
);
const output = await command.execute();
if (output.code === 0) {
InstallStatus.update(() => SETUP_SUCCESS.openGLSupported);
return true;
}
InstallStatus.update(() => SETUP_ERROR.unsupportedOpenGL);
throw new Error("UNSUPPORTED OPENGL VERSION");
}
export async function checkRequirements(): Promise<Boolean> {
try {
await isAVXSupported();
await isOpenGLVersionSupported("4.3");
await setRequirementsMet(true, true);
return true;
} catch (err) {
return false;
}
}
/**
* @param {String} filePath
* @returns {Promise<Boolean>}

View file

@ -1,7 +1,7 @@
<script>
// Assets
import { fade } from "svelte/transition";
import { getInstallStatus } from "$lib/config";
import { areRequirementsMet, getInstallStatus } from "$lib/config";
import Setup from "../components/setup/Jak1Setup.svelte";
import Jak1Main from "../components/games/Jak1Main.svelte";
import Console from "../components/console/Console.svelte";
@ -21,8 +21,19 @@
{#if installed}
<Jak1Main />
{:else}
<Setup />
<Console />
<!-- TODO: MOVE THIS ELSE INTO ITS OWN ROUTE -->
{#await areRequirementsMet then requirementsMet}
{#if requirementsMet}
<Setup />
<Console />
{:else}
<!-- TODO: MAKE AN ERROR PAGE TO PROPERLY DISPLAY THE MISSING REQUIREMENT(S) -->
<p>
You do not meet the requirements to play this game: Missing
AVX/OpenGL Support
</p>
{/if}
{/await}
{/if}
{/await}
</div>

16
src/splash/Splash.svelte Normal file
View file

@ -0,0 +1,16 @@
<script>
import { closeSplashScreen } from "$lib/commands";
import { areRequirementsMet, initConfig } from "$lib/config";
import { checkRequirements } from "$lib/setup";
import { onMount } from "svelte";
import "./splash.css";
// Events
onMount(async () => {
await initConfig();
if (!(await areRequirementsMet())) {
await checkRequirements();
}
await closeSplashScreen();
});
</script>

13
src/splash/index.html Normal file
View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="module" src="./splash.js"></script>
<title>Splash</title>
</head>
<body style="padding: 0; margin: 0">
<div id="app"></div>
</body>
</html>

9
src/splash/splash.css Normal file
View file

@ -0,0 +1,9 @@
body {
padding: 0;
margin: 0;
overflow: hidden;
background-image: url("$assets/images/logo.png");
background-repeat: no-repeat;
background-size: 100vw;
background-position: top;
}

7
src/splash/splash.js Normal file
View file

@ -0,0 +1,7 @@
import App from "./Splash.svelte";
const app = new App({
target: document.getElementById("app"),
});
export default app;

View file

@ -48,7 +48,8 @@
"src/lib/constants.ts",
"src/lib/config.ts",
"src/lib/commands.ts",
"src/lib/utils/file.ts"
"src/lib/utils/file.ts",
"src/splash/splash.ts"
],
"references": [
{

View file

@ -1,6 +1,7 @@
import { defineConfig } from "vite";
import { svelte } from "@sveltejs/vite-plugin-svelte";
import { fileURLToPath, URL } from "url";
import { resolve } from "path";
// https://vitejs.dev/config/
export default defineConfig({
@ -12,4 +13,14 @@ export default defineConfig({
},
},
optimizeDeps: { exclude: ["svelte-navigator"] },
build: {
rollupOptions: {
input: {
main: fileURLToPath(new URL("./index.html", import.meta.url)),
splash: fileURLToPath(
new URL("./src/splash/index.html", import.meta.url)
),
},
},
},
});