mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-11 10:53:14 +01:00
Compare commits
2 commits
0ad614699c
...
59921fe9fd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59921fe9fd | ||
|
|
c23176796f |
12 changed files with 176 additions and 51 deletions
|
|
@ -104,7 +104,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
int OutputsCount(const std::string &nodeId) const
|
int OutputsCount(const std::string &nodeId) const
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (const auto & l : m_links)
|
for (const auto & l : m_links)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,8 @@ void StoryProject::New(const std::string &uuid, const std::string &library_path)
|
||||||
|
|
||||||
std::filesystem::create_directories(m_assetsPath);
|
std::filesystem::create_directories(m_assetsPath);
|
||||||
|
|
||||||
|
CreatePage(MainUuid());
|
||||||
|
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -422,7 +424,7 @@ bool StoryProject::Load(ResourceManager &manager)
|
||||||
|
|
||||||
if (j.contains("pages"))
|
if (j.contains("pages"))
|
||||||
{
|
{
|
||||||
ModelFromJson(j["pages"]);
|
ModelFromJson(j);
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -433,6 +435,11 @@ bool StoryProject::Load(ResourceManager &manager)
|
||||||
std::cout << e.what() << std::endl;
|
std::cout << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_pages.size() == 0)
|
||||||
|
{
|
||||||
|
CreatePage(MainUuid());
|
||||||
|
}
|
||||||
|
|
||||||
return m_initialized;
|
return m_initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,11 @@ public:
|
||||||
|
|
||||||
StoryNode *m_tree;
|
StoryNode *m_tree;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
std::string MainUuid() const {
|
||||||
|
return "490745ab-df4d-476d-ae27-027e94b8ee0a";
|
||||||
|
}
|
||||||
|
|
||||||
void New(const std::string &uuid, const std::string &library_path);
|
void New(const std::string &uuid, const std::string &library_path);
|
||||||
std::filesystem::path BinaryFileName() const;
|
std::filesystem::path BinaryFileName() const;
|
||||||
bool GenerateScript(std::string &codeStr);
|
bool GenerateScript(std::string &codeStr);
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,7 @@ $MyArray DV8 10 ; array of 10 bytes
|
||||||
StoryProject proj(m_log);
|
StoryProject proj(m_log);
|
||||||
ResourceManager res(m_log);
|
ResourceManager res(m_log);
|
||||||
|
|
||||||
std::shared_ptr<StoryPage> page = proj.CreatePage("main");
|
std::shared_ptr<StoryPage> page = proj.CreatePage(proj.MainUuid());
|
||||||
|
|
||||||
|
|
||||||
proj.New(uuid, outputDir);
|
proj.New(uuid, outputDir);
|
||||||
|
|
@ -396,7 +396,7 @@ bool PackArchive::ConvertJsonStudioToOst(const std::string &basePath, const std:
|
||||||
StoryProject proj(m_log);
|
StoryProject proj(m_log);
|
||||||
ResourceManager res(m_log);
|
ResourceManager res(m_log);
|
||||||
|
|
||||||
std::shared_ptr<StoryPage> page = proj.CreatePage("main");
|
std::shared_ptr<StoryPage> page = proj.CreatePage(proj.MainUuid());
|
||||||
|
|
||||||
if (j.contains("title"))
|
if (j.contains("title"))
|
||||||
{
|
{
|
||||||
|
|
@ -428,7 +428,7 @@ bool PackArchive::ConvertJsonStudioToOst(const std::string &basePath, const std:
|
||||||
|
|
||||||
for (const auto & n : j["stageNodes"])
|
for (const auto & n : j["stageNodes"])
|
||||||
{
|
{
|
||||||
auto node = proj.CreateNode("main", "media-node");
|
auto node = proj.CreateNode(proj.MainUuid(), "media-node");
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -37,14 +37,14 @@ NodeEditorWindow::~NodeEditorWindow()
|
||||||
m_story.reset();
|
m_story.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::string gMainUuid = "490745ab-df4d-476d-ae27-027e94b8ee0a";
|
|
||||||
|
|
||||||
void NodeEditorWindow::Initialize()
|
void NodeEditorWindow::Initialize()
|
||||||
{
|
{
|
||||||
m_pages.clear();
|
m_pages.clear();
|
||||||
m_callStack.clear();
|
m_callStack.clear();
|
||||||
|
|
||||||
m_currentPage = std::make_shared<NodeEditorPage>(gMainUuid, "Main");
|
m_currentPage = std::make_shared<NodeEditorPage>(m_story->MainUuid(), "Main");
|
||||||
m_pages.push_back(m_currentPage);
|
m_pages.push_back(m_currentPage);
|
||||||
m_callStack.push_back(m_currentPage);
|
m_callStack.push_back(m_currentPage);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ private:
|
||||||
|
|
||||||
bool m_loaded{false};
|
bool m_loaded{false};
|
||||||
|
|
||||||
// "main" is the entry point editor context. You always need to create one.
|
// "MainUuid" is the entry point editor context. You always need to create one.
|
||||||
// Then each function can have its own editor context, for example if you want to create multiple graphs.
|
// Then each function can have its own editor context, for example if you want to create multiple graphs.
|
||||||
// the key is main, or the UUID of the function
|
// the key is main, or the UUID of the function
|
||||||
std::list<std::shared_ptr<NodeEditorPage>> m_pages;
|
std::list<std::shared_ptr<NodeEditorPage>> m_pages;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ void ResourcesWindow::ChooseFile()
|
||||||
m_showImportDialog = false;
|
m_showImportDialog = false;
|
||||||
// open Dialog Simple
|
// open Dialog Simple
|
||||||
IGFD::FileDialogConfig config;
|
IGFD::FileDialogConfig config;
|
||||||
config.path = ".";
|
config.path = m_story.BuildFullAssetsPath("");
|
||||||
config.countSelectionMax = 1;
|
config.countSelectionMax = 1;
|
||||||
config.sidePaneWidth = 350.0f;
|
config.sidePaneWidth = 350.0f;
|
||||||
config.flags = ImGuiFileDialogFlags_Modal;
|
config.flags = ImGuiFileDialogFlags_Modal;
|
||||||
|
|
@ -50,7 +50,18 @@ void ResourcesWindow::ChooseFile()
|
||||||
|
|
||||||
std::filesystem::path p(filePathName);
|
std::filesystem::path p(filePathName);
|
||||||
std::filesystem::path p2 = m_story.BuildFullAssetsPath( p.filename().generic_string());
|
std::filesystem::path p2 = m_story.BuildFullAssetsPath( p.filename().generic_string());
|
||||||
std::filesystem::copy(p, p2, std::filesystem::copy_options::overwrite_existing);
|
|
||||||
|
bool allowCopy = true;
|
||||||
|
// On ne copie pas le fichier sur lui-même
|
||||||
|
if (std::filesystem::exists(p) && std::filesystem::exists(p2))
|
||||||
|
{
|
||||||
|
allowCopy = !std::filesystem::equivalent(p, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allowCopy)
|
||||||
|
{
|
||||||
|
std::filesystem::copy(p, p2, std::filesystem::copy_options::overwrite_existing);
|
||||||
|
}
|
||||||
|
|
||||||
auto res = std::make_shared<Resource>();
|
auto res = std::make_shared<Resource>();
|
||||||
|
|
||||||
|
|
|
||||||
47
story-player-web/app-context.js
Normal file
47
story-player-web/app-context.js
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
import { createContext } from "preact";
|
||||||
|
import { useState } from 'preact/hooks';
|
||||||
|
import { html } from 'htm/preact';
|
||||||
|
|
||||||
|
const AppContext = createContext();
|
||||||
|
|
||||||
|
const AppProvider = ({ children }) => {
|
||||||
|
const [state, setState] = useState({
|
||||||
|
stories: [
|
||||||
|
{ uuid: "9339d121-ea93-4cc4-9738-9979d43505d0", title: 'Lorem Ipsum', cover: "https://picsum.photos/200/300", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mattis est lectus, scelerisque lobortis neque cursus id. Vestibulum id mollis magna. Etiam vitae est ut mi rutrum congue. Vestibulum a finibus orci. Nunc mattis, risus quis venenatis sagittis, nulla sem sagittis lectus, nec luctus eros neque ut lorem. Nam porttitor a augue vitae venenatis. Vivamus orci nunc, scelerisque ut lacus a, lobortis efficitur nunc. " },
|
||||||
|
{ uuid: "9339d121-ea93-4cc4-9738-9979d43505d0", title: 'Lorem Ipsum', cover: "https://picsum.photos/200/300", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mattis est lectus, scelerisque lobortis neque cursus id. Vestibulum id mollis magna. Etiam vitae est ut mi rutrum congue. Vestibulum a finibus orci. Nunc mattis, risus quis venenatis sagittis, nulla sem sagittis lectus, nec luctus eros neque ut lorem. Nam porttitor a augue vitae venenatis. Vivamus orci nunc, scelerisque ut lacus a, lobortis efficitur nunc. " },
|
||||||
|
{ uuid: "9339d121-ea93-4cc4-9738-9979d43505d0", title: 'Lorem Ipsum', cover: "https://picsum.photos/200/300", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mattis est lectus, scelerisque lobortis neque cursus id. Vestibulum id mollis magna. Etiam vitae est ut mi rutrum congue. Vestibulum a finibus orci. Nunc mattis, risus quis venenatis sagittis, nulla sem sagittis lectus, nec luctus eros neque ut lorem. Nam porttitor a augue vitae venenatis. Vivamus orci nunc, scelerisque ut lacus a, lobortis efficitur nunc. " },
|
||||||
|
{ uuid: "9339d121-ea93-4cc4-9738-9979d43505d0", title: 'Lorem Ipsum', cover: "https://picsum.photos/200/300", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mattis est lectus, scelerisque lobortis neque cursus id. Vestibulum id mollis magna. Etiam vitae est ut mi rutrum congue. Vestibulum a finibus orci. Nunc mattis, risus quis venenatis sagittis, nulla sem sagittis lectus, nec luctus eros neque ut lorem. Nam porttitor a augue vitae venenatis. Vivamus orci nunc, scelerisque ut lacus a, lobortis efficitur nunc. " },
|
||||||
|
{ uuid: "9339d121-ea93-4cc4-9738-9979d43505d0", title: 'Lorem Ipsum', cover: "https://picsum.photos/200/300", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mattis est lectus, scelerisque lobortis neque cursus id. Vestibulum id mollis magna. Etiam vitae est ut mi rutrum congue. Vestibulum a finibus orci. Nunc mattis, risus quis venenatis sagittis, nulla sem sagittis lectus, nec luctus eros neque ut lorem. Nam porttitor a augue vitae venenatis. Vivamus orci nunc, scelerisque ut lacus a, lobortis efficitur nunc. " },
|
||||||
|
{ uuid: "9339d121-ea93-4cc4-9738-9979d43505d0", title: 'Lorem Ipsum', cover: "https://picsum.photos/200/300", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mattis est lectus, scelerisque lobortis neque cursus id. Vestibulum id mollis magna. Etiam vitae est ut mi rutrum congue. Vestibulum a finibus orci. Nunc mattis, risus quis venenatis sagittis, nulla sem sagittis lectus, nec luctus eros neque ut lorem. Nam porttitor a augue vitae venenatis. Vivamus orci nunc, scelerisque ut lacus a, lobortis efficitur nunc. " },
|
||||||
|
{ uuid: "9339d121-ea93-4cc4-9738-9979d43505d0", title: 'Lorem Ipsum', cover: "https://picsum.photos/200/300", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mattis est lectus, scelerisque lobortis neque cursus id. Vestibulum id mollis magna. Etiam vitae est ut mi rutrum congue. Vestibulum a finibus orci. Nunc mattis, risus quis venenatis sagittis, nulla sem sagittis lectus, nec luctus eros neque ut lorem. Nam porttitor a augue vitae venenatis. Vivamus orci nunc, scelerisque ut lacus a, lobortis efficitur nunc. " },
|
||||||
|
{ uuid: "9339d121-ea93-4cc4-9738-9979d43505d0", title: 'Lorem Ipsum', cover: "https://picsum.photos/200/300", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mattis est lectus, scelerisque lobortis neque cursus id. Vestibulum id mollis magna. Etiam vitae est ut mi rutrum congue. Vestibulum a finibus orci. Nunc mattis, risus quis venenatis sagittis, nulla sem sagittis lectus, nec luctus eros neque ut lorem. Nam porttitor a augue vitae venenatis. Vivamus orci nunc, scelerisque ut lacus a, lobortis efficitur nunc. " },
|
||||||
|
{ uuid: "9339d121-ea93-4cc4-9738-9979d43505d0", title: 'Lorem Ipsum', cover: "https://picsum.photos/200/300", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mattis est lectus, scelerisque lobortis neque cursus id. Vestibulum id mollis magna. Etiam vitae est ut mi rutrum congue. Vestibulum a finibus orci. Nunc mattis, risus quis venenatis sagittis, nulla sem sagittis lectus, nec luctus eros neque ut lorem. Nam porttitor a augue vitae venenatis. Vivamus orci nunc, scelerisque ut lacus a, lobortis efficitur nunc. " },
|
||||||
|
{ uuid: "9339d121-ea93-4cc4-9738-9979d43505d0", title: 'Lorem Ipsum', cover: "https://picsum.photos/200/300", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mattis est lectus, scelerisque lobortis neque cursus id. Vestibulum id mollis magna. Etiam vitae est ut mi rutrum congue. Vestibulum a finibus orci. Nunc mattis, risus quis venenatis sagittis, nulla sem sagittis lectus, nec luctus eros neque ut lorem. Nam porttitor a augue vitae venenatis. Vivamus orci nunc, scelerisque ut lacus a, lobortis efficitur nunc. " },
|
||||||
|
{ uuid: "9339d121-ea93-4cc4-9738-9979d43505d0", title: 'Lorem Ipsum', cover: "https://picsum.photos/200/300", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mattis est lectus, scelerisque lobortis neque cursus id. Vestibulum id mollis magna. Etiam vitae est ut mi rutrum congue. Vestibulum a finibus orci. Nunc mattis, risus quis venenatis sagittis, nulla sem sagittis lectus, nec luctus eros neque ut lorem. Nam porttitor a augue vitae venenatis. Vivamus orci nunc, scelerisque ut lacus a, lobortis efficitur nunc. " },
|
||||||
|
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
const setStories = (stories) => {
|
||||||
|
setState(prevState => ({
|
||||||
|
...prevState,
|
||||||
|
stories: [...stories ],
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
// // Fonction pour changer les paramètres
|
||||||
|
// const updateSettings = (newSettings) => {
|
||||||
|
// setState(prevState => ({
|
||||||
|
// ...prevState,
|
||||||
|
// settings: { ...prevState.settings, ...newSettings },
|
||||||
|
// }));
|
||||||
|
// };
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<${AppContext.Provider} value=${{ state, setStories }}>
|
||||||
|
${children}
|
||||||
|
</${AppContext.Provider}>
|
||||||
|
`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { AppProvider, AppContext };
|
||||||
|
|
@ -1,46 +1,46 @@
|
||||||
|
// Preact
|
||||||
|
import { useContext, useEffect } from 'preact/hooks';
|
||||||
|
import { render } from 'preact';
|
||||||
|
import { html } from 'htm/preact';
|
||||||
|
|
||||||
|
// Classes
|
||||||
import apiClient from './classes/api-client.js'
|
import apiClient from './classes/api-client.js'
|
||||||
import eventBus from './classes/event-bus.js';
|
import eventBus from './classes/event-bus.js';
|
||||||
import storage from './classes/storage.js';
|
import storage from './classes/storage.js';
|
||||||
|
|
||||||
|
// Components
|
||||||
import { render } from 'preact';
|
|
||||||
import { createContext } from "preact";
|
|
||||||
import { html } from 'htm/preact';
|
|
||||||
import TopMenu from './components/TopMenu.js'
|
import TopMenu from './components/TopMenu.js'
|
||||||
import ParametersDialog from './components/ParametersDialog.js';
|
import ParametersDialog from './components/ParametersDialog.js';
|
||||||
import StoryPlayer from './components/StoryPlayer.js';
|
import StoryPlayer from './components/StoryPlayer.js';
|
||||||
import StoriesList from './components/StoriesList.js';
|
import StoriesList from './components/StoriesList.js';
|
||||||
|
|
||||||
export const AppContext = createContext("appContext");
|
// Project
|
||||||
|
import { AppProvider, AppContext } from './app-context.js';
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
|
// const { setStories } = useContext(AppContext);
|
||||||
const DefaultContext = {
|
|
||||||
stories: []
|
|
||||||
};
|
|
||||||
|
|
||||||
this.params = storage.getItem('server') || {
|
this.params = storage.getItem('server') || {
|
||||||
serverUrl: '127.0.0.1',
|
serverUrl: '127.0.0.1',
|
||||||
serverPort: 8081,
|
serverPort: 8081,
|
||||||
};
|
};
|
||||||
|
|
||||||
storage.setItem('server', this.params);
|
// The useEffect hook with an empty dependency array simulates the componentDidMount lifecycle method.
|
||||||
|
// It runs the provided function after the component is first rendered.
|
||||||
// try to connect to the server
|
// This is a good place to perform data fetching or initial setup.
|
||||||
apiClient.setBaseUrl(`http://${this.params.serverUrl}:${this.params.serverPort}/api/v1`);
|
useEffect(() => {
|
||||||
apiClient.get('/library/list')
|
console.log("App ready");
|
||||||
.then(data => {
|
return () => {
|
||||||
console.log('Server is up and running', data);
|
console.log("App unmount");
|
||||||
eventBus.publish('server-state-changed', {connected: true});
|
}
|
||||||
})
|
}, []);
|
||||||
.catch(error => {
|
|
||||||
console.log('Server is down');
|
|
||||||
eventBus.publish('server-state-changed', {connected: false});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
storage.setItem('server', this.params);
|
||||||
|
apiClient.setBaseUrl(`http://${this.params.serverUrl}:${this.params.serverPort}/api/v1`);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<AppContext.Provider value="${DefaultContext}">
|
<${AppProvider}>
|
||||||
<${TopMenu} />
|
<${TopMenu} />
|
||||||
<${ParametersDialog} />
|
<${ParametersDialog} />
|
||||||
|
|
||||||
|
|
@ -48,7 +48,7 @@ export function App() {
|
||||||
<${StoryPlayer} />
|
<${StoryPlayer} />
|
||||||
<${StoriesList} />
|
<${StoriesList} />
|
||||||
</div>
|
</div>
|
||||||
</AppContext.Provider>
|
</${AppProvider}>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,60 @@
|
||||||
import { html } from 'htm/preact';
|
import { html } from 'htm/preact';
|
||||||
|
|
||||||
|
// Classes
|
||||||
import eventBus from '../classes/event-bus.js';
|
import eventBus from '../classes/event-bus.js';
|
||||||
import { useState } from 'preact/hooks';
|
import apiClient from '../classes/api-client.js';
|
||||||
|
|
||||||
|
import { AppContext } from '../app-context.js';
|
||||||
|
import { useContext, useEffect } from 'preact/hooks'
|
||||||
|
|
||||||
|
|
||||||
function StoriesList() {
|
function StoriesList() {
|
||||||
|
|
||||||
|
const { state, setStories } = useContext(AppContext);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("Fetch stories");
|
||||||
|
getStories();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
console.log("Component will unmount");
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
function getStories() {
|
||||||
|
|
||||||
|
// try to connect to the server
|
||||||
|
|
||||||
|
apiClient.get('/library/list')
|
||||||
|
.then(data => {
|
||||||
|
console.log('Server is up and running', data);
|
||||||
|
eventBus.publish('server-state-changed', {connected: true});
|
||||||
|
setStories(data);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log('Api error: ' + error);
|
||||||
|
eventBus.publish('server-state-changed', {connected: false});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClickOnStory() {
|
||||||
|
console.log("Clicked")
|
||||||
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<style>
|
<style>
|
||||||
.card-container {
|
.card-container {
|
||||||
max-height: 80vh;
|
max-height: 80vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: 20px;
|
padding: 4px;
|
||||||
|
width: 400px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-content {
|
.card-content {
|
||||||
|
|
@ -33,6 +71,12 @@ function StoriesList() {
|
||||||
.card-description {
|
.card-description {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
width: 220px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-image {
|
.card-image {
|
||||||
|
|
@ -42,16 +86,18 @@ function StoriesList() {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div>
|
<div style="max-height: 400px; overflow-y: auto; border: 1px solid #ccc; ">
|
||||||
<div class="card-container">
|
${state.stories.map(story => html`
|
||||||
<div class="block card">
|
<div class="card-container" onClick="${handleClickOnStory}">
|
||||||
<div class="card-content">
|
<div class="block card">
|
||||||
<h2 class="card-title">Titre de la Carte 1</h2>
|
<div class="card-content">
|
||||||
<p class="card-description">Description de la carte 1. Voici une brève description pour cette carte.</p>
|
<h2 class="card-title">${story.title}</h2>
|
||||||
|
<p class="card-description">${story.description}</p>
|
||||||
|
</div>
|
||||||
|
<img src="https://placehold.co/100x75" alt="Image de la carte 1" class="card-image" />
|
||||||
</div>
|
</div>
|
||||||
<img src="https://placehold.co/100x75" alt="Image de la carte 1" class="card-image" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
`)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,18 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
|
--block-accent-color: #3a5ec5;
|
||||||
|
|
||||||
|
/* --block-text-color: #f8f8f8;
|
||||||
|
--block-background-color: #222;
|
||||||
|
--block-accent-color: #f2d12e;
|
||||||
|
--block-shadow-color: #555; */
|
||||||
|
|
||||||
|
background: #abcdef;
|
||||||
|
/* margin: 4px auto;
|
||||||
|
max-width: 800px;
|
||||||
|
color: #222;
|
||||||
|
--block-accent-color: #3a5ec5; */
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
@ -42,4 +54,4 @@
|
||||||
<script src="storyvm.js"></script>
|
<script src="storyvm.js"></script>
|
||||||
<script src="app.js" type="module"></script>
|
<script src="app.js" type="module"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
/* Extra styles to make the demo look nicer.
|
/* Extra styles to make the demo look nicer.
|
||||||
* Feel free to look around! */
|
* Feel free to look around! */
|
||||||
|
|
||||||
main {
|
|
||||||
margin: 4px auto;
|
|
||||||
max-width: 800px;
|
|
||||||
color: #222;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 824px) {
|
@media only screen and (max-width: 824px) {
|
||||||
main {
|
main {
|
||||||
|
|
@ -52,3 +47,5 @@ a {
|
||||||
input {
|
input {
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue