fixed bug where lock was never released, attributes look better now, can be accees on other devices
This commit is contained in:
parent
b270a95434
commit
400954babc
@ -1 +1 @@
|
||||
export const API_BASE = "http://127.0.0.1:3010";
|
||||
export const API_BASE = `http://${window.location.hostname}:3010`;
|
||||
@ -85,48 +85,39 @@
|
||||
</div>
|
||||
|
||||
<h2>Attributes</h2>
|
||||
<div class="info-container">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<label for={"field-Agility"}>Agility</label>
|
||||
<input id={"field-Agility"} type="number" bind:value={characterData.Attributes.Agility} min=0 max=100/>
|
||||
</td>
|
||||
<td>
|
||||
<label for={"field-Body"}>Body</label>
|
||||
<input id={"field-Body"} type="number" bind:value={characterData.Attributes.Body} min=0 max=100/>
|
||||
</td>
|
||||
<td>
|
||||
<label for={"field-Charisma"}>Charisma</label>
|
||||
<input id={"field-Charisma"} type="number" bind:value={characterData.Attributes.Charisma} min=0 max=100/>
|
||||
</td>
|
||||
<td>
|
||||
<label for={"field-Edge"}>Edge</label>
|
||||
<input id={"field-Edge"} type="number" bind:value={characterData.Attributes.Edge} min=0 max=100/>
|
||||
</td>
|
||||
<td>Agility</td>
|
||||
<td><input id={"field-Agility"} type="number" bind:value={characterData.Attributes.Agility} min=0 max=100/></td>
|
||||
<td>Body</td>
|
||||
<td><input id={"field-Body"} type="number" bind:value={characterData.Attributes.Body} min=0 max=100/> </td>
|
||||
<td>Charisma</td>
|
||||
<td><input id={"field-Charisma"} type="number" bind:value={characterData.Attributes.Charisma} min=0 max=100/></td>
|
||||
<td>Edge</td>
|
||||
<td><input id={"field-Edge"} type="number" bind:value={characterData.Attributes.Edge} min=0 max=100/> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for={"field-Essence"}>Essence</label>
|
||||
<input id={"field-Essence"} type="number" bind:value={characterData.Attributes.Essence} min=0 max=100/>
|
||||
</td>
|
||||
<td>
|
||||
<label for={"field-Initiative"}>Initiative</label>
|
||||
<input id={"field-Initiative"} type="number" bind:value={characterData.Attributes.Initiative} min=0 max=100/>
|
||||
</td>
|
||||
<td>
|
||||
<label for={"field-Charisma"}>Charisma</label>
|
||||
<input id={"field-Charisma"} type="number" bind:value={characterData.Attributes.Charisma} min=0 max=100/>
|
||||
</td>
|
||||
<td>
|
||||
<label for={"field-Edge"}>Edge</label>
|
||||
<input id={"field-Edge"} type="number" bind:value={characterData.Attributes.Edge} min=0 max=100/>
|
||||
</td>
|
||||
<td>Essence</td>
|
||||
<td><input id={"field-Essence"} type="number" bind:value={characterData.Attributes.Essence} min=0 max=100/></td>
|
||||
<td>Initiative</td>
|
||||
<td><input id={"field-Initiative"} type="number" bind:value={characterData.Attributes.Initiative} min=0 max=100/> </td>
|
||||
<td>Intuition</td>
|
||||
<td><input id={"field-Charisma"} type="number" bind:value={characterData.Attributes.Intuition} min=0 max=100/></td>
|
||||
<td>Logic</td>
|
||||
<td><input id={"field-Edge"} type="number" bind:value={characterData.Attributes.Logic} min=0 max=100/> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Reaction</td>
|
||||
<td><input id={"field-Initiative"} type="number" bind:value={characterData.Attributes.Reaction} min=0 max=100/></td>
|
||||
<td>Strength</td>
|
||||
<td><input id={"field-Charisma"} type="number" bind:value={characterData.Attributes.Strength} min=0 max=100/></td>
|
||||
<td>Willpower</td>
|
||||
<td><input id={"field-Edge"} type="number" bind:value={characterData.Attributes.Willpower} min=0 max=100/></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2>Skills</h2>
|
||||
<table>
|
||||
|
||||
@ -1,2 +1,8 @@
|
||||
<h1>Welcome to SvelteKit</h1>
|
||||
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
onMount(() => {
|
||||
goto('/shadowrun', { replaceState: true });
|
||||
});
|
||||
</script>
|
||||
70
src/main.cpp
70
src/main.cpp
@ -37,74 +37,6 @@ std::string get_mime_type(const std::string& path) {
|
||||
|
||||
int main() {
|
||||
crow::SimpleApp app;
|
||||
/*
|
||||
CROW_ROUTE(app, "/")([] {
|
||||
auto data = utils::loadFile("templates/index.html");
|
||||
if (data.empty())
|
||||
return crow::response(404);
|
||||
return crow::response(data);
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/static/<string>")([](const std::string& file) {
|
||||
auto data = utils::loadFile("static/" + file);
|
||||
if (data.empty())
|
||||
return crow::response(404);
|
||||
return crow::response(data);
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/templates/<string>")([](const std::string& file) {
|
||||
auto data = utils::loadFile("templates/" + file);
|
||||
if (data.empty())
|
||||
return crow::response(404);
|
||||
return crow::response(data);
|
||||
});
|
||||
|
||||
// Static file redirector
|
||||
CROW_ROUTE(app, "/redirect")
|
||||
(login::login_required([](const crow::request& req) {
|
||||
auto file_param = req.url_params.get("file");
|
||||
if (!file_param) {
|
||||
return crow::response(400, "Missing 'file' parameter");
|
||||
}
|
||||
|
||||
std::string filepath = "/templates/";
|
||||
filepath += utils::urlDecode(file_param); // Optional: decode %20 etc.
|
||||
|
||||
crow::response res;
|
||||
res.code = 204;
|
||||
res.add_header("HX-Redirect", filepath);
|
||||
return res;
|
||||
}));
|
||||
|
||||
CROW_ROUTE(app, "/status")(login::login_required([](const crow::request& req) {
|
||||
auto table = create_service_table();
|
||||
return crow::response{table.htmx()};
|
||||
}));
|
||||
|
||||
CROW_ROUTE(app, "/toggle-service").methods(crow::HTTPMethod::Post)
|
||||
(login::login_required([](const crow::request& req) {
|
||||
auto body = utils::getBodyName(req.body);
|
||||
if (!body.has_value())
|
||||
return crow::response(400);
|
||||
|
||||
const string& serviceName = body.value();
|
||||
|
||||
auto opt_settings = AppSettings::loadAppSettings();
|
||||
|
||||
HtmxTableRow row;
|
||||
if (opt_settings.has_value()) {
|
||||
auto& settings = opt_settings.value();
|
||||
const auto& service_id = settings.getId(serviceName).value_or(serviceName);
|
||||
|
||||
systemd::toggle_service(service_id);
|
||||
row = create_service_table_row(serviceName, service_id);
|
||||
}
|
||||
else {
|
||||
row = create_error_table_row(opt_settings.error());
|
||||
}
|
||||
return crow::response{row.htmx()};
|
||||
}));
|
||||
*/
|
||||
const filesystem::path build_dir = "frontend/build/"; // <-- set your build folder
|
||||
|
||||
// Root route
|
||||
@ -184,5 +116,5 @@ int main() {
|
||||
}
|
||||
*/
|
||||
app.loglevel(crow::LogLevel::INFO);
|
||||
app.port(httpPort).multithreaded().run();
|
||||
app.bindaddr("0.0.0.0").port(httpPort).multithreaded().run();
|
||||
}
|
||||
|
||||
@ -34,80 +34,6 @@ static crow::response rsp(const std::string& msg){
|
||||
|
||||
void initApi(crow::SimpleApp& app)
|
||||
{
|
||||
/*
|
||||
CROW_ROUTE(app, "/api/shadowrun/submit-character").methods("POST"_method)
|
||||
(login::login_required([](const crow::request& req) {
|
||||
auto params = parse_query_string(req.body);
|
||||
|
||||
auto name_data = params["Character-Info_Name"];
|
||||
if (name_data.empty()){
|
||||
CROW_LOG_WARNING << "Character without name submited, will not be saved";
|
||||
return rsp("Failed : Character without name submited, will not be saved");
|
||||
}
|
||||
|
||||
auto key = getKeyOfCharacter(name_data);
|
||||
if (key < 0){
|
||||
CROW_LOG_ERROR << "Failed to create id of character : " << name_data;
|
||||
return rsp("Failed to create id of character");
|
||||
}
|
||||
|
||||
vector<pair<const string, const string>> idValues;
|
||||
idValues.reserve(ShadowrunCharacterForm::m_formIds.size());
|
||||
|
||||
auto checkboxes = std::set<string>(ShadowrunCharacterForm::m_checkboxIds.begin(), ShadowrunCharacterForm::m_checkboxIds.end());
|
||||
for (auto& id : ShadowrunCharacterForm::m_formIds) {
|
||||
auto data = params[id];
|
||||
if(!data.empty()){
|
||||
idValues.push_back(make_pair(id, data));
|
||||
if (checkboxes.contains(id)){
|
||||
checkboxes.erase(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// append the checkboxes
|
||||
for (auto& checkbox : checkboxes){
|
||||
idValues.push_back(make_pair(checkbox, "0"));
|
||||
}
|
||||
|
||||
if (!storeCharacterData(key, idValues)){
|
||||
CROW_LOG_ERROR << "Failed to store character data of " << name_data;
|
||||
return rsp("Failed to store character data");
|
||||
};
|
||||
return rsp(format("Character {} submitted successfully", name_data));
|
||||
}));
|
||||
|
||||
CROW_ROUTE(app, "/api/shadowrun/character-form")
|
||||
(login::login_required([](const crow::request& req) {
|
||||
auto query = crow::query_string(req.url_params);
|
||||
std::string name = query.get("name") ? query.get("name") : "";
|
||||
|
||||
auto data = getCharacterDataMap(getKeyOfCharacter(name));
|
||||
|
||||
return crow::response{ShadowrunCharacterForm(data).htmx()};
|
||||
}));
|
||||
*/
|
||||
CROW_ROUTE(app, "/api/shadowrun/character-list")
|
||||
(login::login_required([](const crow::request& req) {
|
||||
std::ostringstream html;
|
||||
|
||||
// Simulated character database
|
||||
auto characters = getCharacters();
|
||||
html << "<form hx-get='/api/shadowrun/character-form' hx-target='#form-container' hx-params='*'>"
|
||||
<< "<label>Character Name: "
|
||||
<< "<select name='name'>";
|
||||
|
||||
for (const auto& character : characters) {
|
||||
html << "<option value='" << character.name << "'>" << character.name << "</option>";
|
||||
}
|
||||
|
||||
html << "</select></label>"
|
||||
<< "<button type='submit'>Load Character</button>"
|
||||
<< "</form>";
|
||||
|
||||
return crow::response{html.str()};
|
||||
}));
|
||||
|
||||
CROW_ROUTE(app, "/api/shadowrun/characters")
|
||||
([&]() {
|
||||
auto characters = getCharacters();
|
||||
|
||||
@ -12,40 +12,36 @@ int64_t createCharacter(const string& name){
|
||||
if (name.empty())
|
||||
return -1;
|
||||
|
||||
int64_t id;
|
||||
auto db = dbpool.acquire();
|
||||
|
||||
auto character = db->get_all<ShadowrunCharacter>(
|
||||
where(c(&ShadowrunCharacter::name) == name),
|
||||
limit(1)
|
||||
auto character = db->get_optional<ShadowrunCharacter>(
|
||||
where(c(&ShadowrunCharacter::name) == name)
|
||||
);
|
||||
|
||||
if (!character.empty()) {
|
||||
return character[0].id;
|
||||
if (character.has_value()) {
|
||||
id = character.value().id;
|
||||
} else {
|
||||
auto c = newShadowrunCharacter(name);
|
||||
return db->insert(c);
|
||||
id = db->insert(c);
|
||||
}
|
||||
dbpool.release(db);
|
||||
return id;
|
||||
}
|
||||
|
||||
std::vector<ShadowrunCharacter> getCharacters(){
|
||||
auto db = dbpool.acquire();
|
||||
return db->get_all<ShadowrunCharacter>();
|
||||
auto characters = db->get_all<ShadowrunCharacter>();
|
||||
dbpool.release(db);
|
||||
return characters;
|
||||
}
|
||||
|
||||
optional<ShadowrunCharacter> getChracter(int id)
|
||||
{
|
||||
auto db = dbpool.acquire();
|
||||
auto character = db->get_all<ShadowrunCharacter>(
|
||||
where(c(&ShadowrunCharacter::id) == id),
|
||||
limit(1)
|
||||
);
|
||||
if (character.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
else {
|
||||
return character[0];
|
||||
}
|
||||
optional<ShadowrunCharacter> character = db->get_optional<ShadowrunCharacter>(id);
|
||||
dbpool.release(db);
|
||||
return character;
|
||||
}
|
||||
|
||||
vector<ShadowrunCharacterData> getChracterData(int character_id)
|
||||
@ -54,10 +50,12 @@ vector<ShadowrunCharacterData> getChracterData(int character_id)
|
||||
auto characterData = db->get_all<ShadowrunCharacterData>(
|
||||
where(c(&ShadowrunCharacterData::character_id) == character_id)
|
||||
);
|
||||
dbpool.release(db);
|
||||
return characterData;
|
||||
}
|
||||
|
||||
int storeCharacterData(int characterId, const Type type, const string& json){
|
||||
int id;
|
||||
auto db = dbpool.acquire();
|
||||
auto characterData = db->get_all<ShadowrunCharacterData>(
|
||||
where(
|
||||
@ -67,7 +65,7 @@ int storeCharacterData(int characterId, const Type type, const string& json){
|
||||
|
||||
if(characterData.empty()){
|
||||
ShadowrunCharacterData character = newShadowrunCharacterData(characterId, type, json);
|
||||
return db->insert(character);
|
||||
id = db->insert(character);
|
||||
}
|
||||
else {
|
||||
if (characterData.size() > 1){
|
||||
@ -77,21 +75,26 @@ int storeCharacterData(int characterId, const Type type, const string& json){
|
||||
character.json = json;
|
||||
character.updated_at = utils::currentTime();
|
||||
db->update(character);
|
||||
return character.id;
|
||||
id = character.id;
|
||||
}
|
||||
dbpool.release(db);
|
||||
return id;
|
||||
}
|
||||
|
||||
int storeCharacterData(const ShadowrunCharacterData& data){
|
||||
int id;
|
||||
auto db = dbpool.acquire();
|
||||
auto characterData = db->get_optional<ShadowrunCharacterData>(data.id);
|
||||
|
||||
if(!characterData.has_value()){
|
||||
return db->insert(data);
|
||||
id = db->insert(data);
|
||||
}
|
||||
else {
|
||||
db->update(data);
|
||||
return data.id;
|
||||
id = data.id;
|
||||
}
|
||||
dbpool.release(db);
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user