dedicated directory for story web version
Some checks failed
build-story-editor / build_linux (push) Has been cancelled
build-story-editor / build_win32 (push) Has been cancelled
Deploy / deploy (push) Has been cancelled

This commit is contained in:
anthony@rabine.fr 2025-01-10 22:04:39 +01:00
parent 432d72c80c
commit 0ad614699c
15 changed files with 204 additions and 137 deletions

View file

@ -1,39 +0,0 @@
import apiClient from './classes/api-client.js'
import eventBus from './classes/event-bus.js';
import storage from './classes/storage.js';
import { render } from 'preact';
import { html } from 'htm/preact';
import TopMenu from './components/TopMenu.js'
import ParametersDialog from './components/ParametersDialog.js';
export function App() {
this.params = storage.getItem('server') || {
serverUrl: '127.0.0.1',
serverPort: 8081,
};
storage.setItem('server', this.params);
// try to connect to the server
apiClient.setBaseUrl(`http://${this.params.serverUrl}:${this.params.serverPort}/api/v1`);
apiClient.get('/library/list')
.then(data => {
console.log('Server is up and running', data);
eventBus.publish('server-state-changed', {connected: true});
})
.catch(error => {
console.error('Server is down', error);
eventBus.publish('server-state-changed', {connected: false});
});
return html`
<${TopMenu} />
<${ParametersDialog} />
`;
}
render(html`<${App} />`, document.getElementById('app'));

View file

@ -1,84 +0,0 @@
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="title" content="OpenStoryTeller Web Player">
<meta name="description" content="OpenStoryTeller Web Player">
<meta name="keywords" content="story, player, teller">
<title>OpenStoryTeller Web Player</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="main.css">
<script type="importmap">
{
"imports": {
"preact": "https://esm.sh/preact@10.23.1",
"preact/hooks": "https://esm.sh/preact@10.23.1/hooks",
"htm/preact": "https://esm.sh/htm@3.1.1/preact?external=preact"
}
}
</script>
<!-- Favicon -->
<link rel="shortcut icon" href="https://www.raylib.com/favicon.ico">
<style>
body {
line-height: 1;
font-family: 'Inter', sans-serif;
margin: 0;
padding: 0;
line-height: 1.6;
}
canvas.emscripten { border: 0px none; background-color: black; display: inline; }
#canvas-container {
width: 100%;
text-align:center;
}
</style>
</head>
<body style="min-width: min-content;">
<main>
<div id="app"></div>
<div id="canvas-container" class="block fixed">
<canvas class=emscripten id=canvas oncontextmenu=event.preventDefault() tabindex=-1></canvas>
</div>
<p id="output" />
</main>
<script>
var Module = {
print: (function() {
var element = document.getElementById('output');
if (element) element.value = ''; // clear browser cache
return function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
console.log(text);
if (element) {
element.value += text + "\n";
element.scrollTop = element.scrollHeight; // focus on bottom
}
};
})(),
canvas: (function() {
var canvas = document.getElementById('canvas');
return canvas;
})(),
locateFile: function(s) {
return 'bin/' + s;
}
};
</script>
<script async type="text/javascript" src="bin/story-player.js"></script>
<script src="app.js" type="module"></script>
</body>
</html>

55
story-player-web/app.js Normal file
View file

@ -0,0 +1,55 @@
import apiClient from './classes/api-client.js'
import eventBus from './classes/event-bus.js';
import storage from './classes/storage.js';
import { render } from 'preact';
import { createContext } from "preact";
import { html } from 'htm/preact';
import TopMenu from './components/TopMenu.js'
import ParametersDialog from './components/ParametersDialog.js';
import StoryPlayer from './components/StoryPlayer.js';
import StoriesList from './components/StoriesList.js';
export const AppContext = createContext("appContext");
export function App() {
const DefaultContext = {
stories: []
};
this.params = storage.getItem('server') || {
serverUrl: '127.0.0.1',
serverPort: 8081,
};
storage.setItem('server', this.params);
// try to connect to the server
apiClient.setBaseUrl(`http://${this.params.serverUrl}:${this.params.serverPort}/api/v1`);
apiClient.get('/library/list')
.then(data => {
console.log('Server is up and running', data);
eventBus.publish('server-state-changed', {connected: true});
})
.catch(error => {
console.log('Server is down');
eventBus.publish('server-state-changed', {connected: false});
});
return html`
<AppContext.Provider value="${DefaultContext}">
<${TopMenu} />
<${ParametersDialog} />
<div style="display: flex; flex-direction:row;">
<${StoryPlayer} />
<${StoriesList} />
</div>
</AppContext.Provider>
`;
}
render(html`<${App} />`, document.getElementById('app'));

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View file

@ -8,6 +8,9 @@ class ApiClient {
}
async request(endpoint, method = 'GET', data = null, headers = {}) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 5000);
const config = {
method,
headers: {
@ -20,17 +23,18 @@ class ApiClient {
config.body = JSON.stringify(data);
}
try {
const response = await fetch(`${this.baseURL}${endpoint}`, config);
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.message || 'Something went wrong');
const promise = fetch(`${this.baseURL}${endpoint}`, config).then(async (response) => {
const data = await response.json();
if (response.ok) {
return data;
} else {
return Promise.reject(data);
}
return await response.json();
} catch (error) {
console.error('API request error:', error);
throw error;
}
});
return promise.finally(() => clearTimeout(timeout));
}
get(endpoint, headers = {}) {

View file

@ -0,0 +1,59 @@
import { html } from 'htm/preact';
import eventBus from '../classes/event-bus.js';
import { useState } from 'preact/hooks';
function StoriesList() {
return html`
<style>
.card-container {
max-height: 80vh;
overflow-y: auto;
padding: 20px;
}
.card {
display: flex;
align-items: center;
}
.card-content {
flex: 1;
margin-right: 20px;
}
.card-title {
font-size: 1.2em;
margin: 0 0 10px 0;
font-weight: bold;
}
.card-description {
font-size: 0.9em;
margin: 0;
}
.card-image {
width: 120px;
height: 90px;
object-fit: cover;
border-radius: 10px;
}
</style>
<div>
<div class="card-container">
<div class="block card">
<div class="card-content">
<h2 class="card-title">Titre de la Carte 1</h2>
<p class="card-description">Description de la carte 1. Voici une brève description pour cette carte.</p>
</div>
<img src="https://placehold.co/100x75" alt="Image de la carte 1" class="card-image" />
</div>
</div>
</div>
`;
}
export default StoriesList;

View file

@ -0,0 +1,26 @@
import { html } from 'htm/preact';
import eventBus from '../classes/event-bus.js';
import { useState } from 'preact/hooks';
function StoryPlayer() {
return html`
<style>
</style>
<div style="width: 400px; height: 500px;">
<div class="block fixed" style="width: 320px; height: 240px;">
</div>
<div style="display: flex; ">
<div class="block accent btn"></div>
<div class="block accent btn"></div>
<div class="block accent btn"></div>
<div class="block accent btn"></div>
</div>
</div>
`;
}
export default StoryPlayer;

View file

@ -56,9 +56,7 @@ function TopMenu() {
</style>
<div class="flexRow">
<${MessageComponent} show=${error} message=${message} />
<div class="block accent" onClick="${handleClick}">
Paramètres
</div>
<div class="block accent btn" onClick="${handleClick}">Paramètres</div>
</div>
`;
}

View file

@ -0,0 +1,45 @@
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="title" content="OpenStoryTeller Web Player">
<meta name="description" content="OpenStoryTeller Web Player">
<meta name="keywords" content="story, player, teller">
<title>OpenStoryTeller Web Player</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="main.css">
<script type="importmap">
{
"imports": {
"preact": "https://esm.sh/preact@10.23.1",
"preact/hooks": "https://esm.sh/preact@10.23.1/hooks",
"htm/preact": "https://esm.sh/htm@3.1.1/preact?external=preact"
}
}
</script>
<link rel="shortcut icon" href="https://www.raylib.com/favicon.ico">
<style>
body {
line-height: 1;
font-family: 'Inter', sans-serif;
margin: 0;
padding: 0;
line-height: 1.6;
}
</style>
</head>
<body style="min-width: min-content;">
<div id="app"></div>
<script src="storyvm.js"></script>
<script src="app.js" type="module"></script>
</body>
</html>

View file

@ -199,7 +199,6 @@ body {
border-radius: 3px;
padding: 4px 8px;
background: var(--block-background-color);
font-weight: bold;
cursor: pointer;
box-sizing: border-box;
@ -283,6 +282,10 @@ body {
cursor: initial !important;
}
.block.btn {
font-weight: bold;
}
/* FIXED STYLES */
.block.fixed:hover,
.block.fixed:hover::before,