mirror of
https://bitbucket.org/grumdrig/pq-web.git
synced 2026-09-29 00:34:00 -06:00
Button to load character saves plus a little warning about data loss
This commit is contained in:
committed by
Eric Fredricksen
parent
b1fa424302
commit
0286ac1338
+44
-8
@@ -13,10 +13,16 @@
|
|||||||
|
|
||||||
.brag {
|
.brag {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.brag, #buttonline td {
|
||||||
background-color: #ddddff;
|
background-color: #ddddff;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
border: solid 2px #ccccee;
|
border: solid 2px #ccccee;
|
||||||
}
|
}
|
||||||
|
.bragtable {
|
||||||
|
display: inline-block;
|
||||||
|
border-spacing: 20px;
|
||||||
|
}
|
||||||
.lit {
|
.lit {
|
||||||
border: solid 2px #66ccee;
|
border: solid 2px #66ccee;
|
||||||
}
|
}
|
||||||
@@ -49,6 +55,7 @@ p {
|
|||||||
#newc {
|
#newc {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.brag a, .brag a:visited {
|
.brag a, .brag a:visited {
|
||||||
color: blue;
|
color: blue;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@@ -77,11 +84,30 @@ a.save {
|
|||||||
img {
|
img {
|
||||||
border-style: none;
|
border-style: none;
|
||||||
}
|
}
|
||||||
#dropinfo {
|
.dropinfo {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-size: smaller;
|
/* font-size: smaller;*/
|
||||||
|
border: solid 1px #888;
|
||||||
|
width: 600px;
|
||||||
|
margin: auto;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
background-color: #f8f0ee;
|
||||||
|
border-radius: 0.3rem;
|
||||||
|
}
|
||||||
|
.dropinfo div {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
color: #222;
|
||||||
|
padding: 2px 6px 2px 6px;
|
||||||
|
border: solid 1px #888;
|
||||||
|
font-family: -apple-system, Tahoma, Helvetica, sans-serif;
|
||||||
|
border-radius: 0.3rem;
|
||||||
|
cursor: pointer;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 13.33333px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@@ -94,20 +120,30 @@ img {
|
|||||||
|
|
||||||
<h1>Character Roster</h1>
|
<h1>Character Roster</h1>
|
||||||
|
|
||||||
<p id="roster" class="banter">
|
<p id="roster" class="banter"></p>
|
||||||
</p>
|
|
||||||
|
|
||||||
<table class="brag">
|
<table class=bragtable>
|
||||||
<tr>
|
<tr id=buttonline>
|
||||||
<td id="newc">
|
<td id="newc">
|
||||||
<b>New Character</b><br>
|
<b>New Character</b><br>
|
||||||
<img src="dicebar.jpg" alt="four dice"><br>
|
<img src="dicebar.jpg" alt="progress on dice pips"><br>
|
||||||
<button id="roll">Roll One Up</button>
|
<button id="roll">Roll One Up</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p id=dropinfo>You can also drop a saved game file on this page to add it to your roster.</p>
|
|
||||||
|
<div class=dropinfo>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
Your character data exists only in this browser and will disappear if the browser data is cleared.
|
||||||
|
You can save a backup by clicking a character's <span style="font-style:normal">💾</span> icon.
|
||||||
|
To load a saved game in this browser, drop a game save file onto this page, or use this button:
|
||||||
|
</div><div>
|
||||||
|
<input id=pickup type=file accept=".pqw" multiple hidden></input>
|
||||||
|
<label id=uploader for=pickup>Load a Saved Game</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div align="center" id="nabar">
|
<div align="center" id="nabar">
|
||||||
<a href="/">Home</a> ·
|
<a href="/">Home</a> ·
|
||||||
|
|||||||
@@ -1,143 +1,160 @@
|
|||||||
|
|
||||||
function b64_decode(value) {
|
function b64_decode(value) {
|
||||||
return JSON.parse(decodeURIComponent(escape(atob(value))));
|
return JSON.parse(decodeURIComponent(escape(atob(value))));
|
||||||
}
|
}
|
||||||
|
|
||||||
function b64_stringify(value) {
|
function b64_stringify(value) {
|
||||||
return btoa(unescape(encodeURIComponent(JSON.stringify(value))));
|
return btoa(unescape(encodeURIComponent(JSON.stringify(value))));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function dropGuy(sheet) {
|
||||||
|
try {
|
||||||
|
sheet = sheet.replace(/\s/g, "");
|
||||||
|
sheet = b64_decode(sheet);
|
||||||
|
storage.loadRoster(games => {
|
||||||
|
if (!games[sheet.Traits.Name] ||
|
||||||
|
confirm(`A character named ${sheet.Traits.Name} already exists. Overwrite it?`)) {
|
||||||
|
storage.addToRoster(sheet, () => storage.loadRoster(loadGames));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
setTimeout(() => alert("Invalid character data", 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function load() {
|
function load() {
|
||||||
|
|
||||||
if (!window.localStorage) {
|
if (!window.localStorage) {
|
||||||
roster.html("<b>Hrumph:</b> This browser does not support local storage. You can still play fast and loose: your character will live only as long as the game stays running in your browser.");
|
roster.html("<b>Hrumph:</b> This browser does not support local storage. You can still play fast and loose: your character will live only as long as the game stays running in your browser.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
storage.loadRoster(loadGames);
|
storage.loadRoster(loadGames);
|
||||||
|
|
||||||
window.addEventListener("dragover", e => {
|
window.addEventListener("dragover", e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.dataTransfer.dropEffect = "copy";
|
e.dataTransfer.dropEffect = "copy";
|
||||||
});
|
});
|
||||||
window.addEventListener("drop", e => {
|
window.addEventListener("drop", e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopImmediatePropagation();
|
e.stopImmediatePropagation();
|
||||||
let files = e.dataTransfer.files;
|
let files = e.dataTransfer.files;
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
files[i].text().then(sheet => {
|
files[i].text().then(dropGuy);
|
||||||
try {
|
}
|
||||||
sheet = sheet.replace(/\s/g, "");
|
});
|
||||||
sheet = b64_decode(sheet);
|
|
||||||
storage.loadRoster(games => {
|
|
||||||
if (!games[sheet.Traits.Name] ||
|
|
||||||
confirm(`A character named ${sheet.Traits.Name} already exists. Overwrite it?`)) {
|
|
||||||
storage.addToRoster(sheet, () => storage.loadRoster(loadGames));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch(err) {
|
|
||||||
console.log(err);
|
|
||||||
setTimeout(() => alert("Invalid character data", 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
document.getElementById('pickup').addEventListener('change', e => {
|
||||||
|
for (const file of e.target.files) {
|
||||||
|
console.log(file);
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.readAsText(file, "UTF-8");
|
||||||
|
reader.onload = function (evt) {
|
||||||
|
dropGuy(evt.target.result);
|
||||||
|
}
|
||||||
|
reader.onerror = function (evt) {
|
||||||
|
console.log("error reading file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.target.value = '';
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadGames(games) {
|
function loadGames(games) {
|
||||||
var roster = $("#roster");
|
var roster = $("#roster");
|
||||||
roster.empty();
|
roster.empty();
|
||||||
|
|
||||||
var newone = window.location.href.split('#')[1];
|
var newone = window.location.href.split('#')[1];
|
||||||
|
|
||||||
var count = 0;
|
var count = 0;
|
||||||
|
|
||||||
$.each(games, function (key, c) {
|
$.each(games, function (key, c) {
|
||||||
var name = c.Traits.Name;
|
var name = c.Traits.Name;
|
||||||
|
|
||||||
var br = brag(c);
|
var br = brag(c);
|
||||||
roster.append(br);
|
roster.append(br);
|
||||||
br.find("a.go").attr("href", "main.html#" + escape(name));
|
br.find("a.go").attr("href", "main.html#" + escape(name));
|
||||||
|
|
||||||
br.find("a.x").click(function () {
|
br.find("a.x").click(function () {
|
||||||
if (confirm("Terminate " + Pick(["faithful","noble","loyal","brave"])+
|
if (confirm("Terminate " + Pick(["faithful","noble","loyal","brave"])+
|
||||||
" " + name + "?")) {
|
" " + name + "?")) {
|
||||||
delete games[name];
|
delete games[name];
|
||||||
storage.storeRoster(games);
|
storage.storeRoster(games);
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
br.find("a.sheet").click(function () {
|
br.find("a.sheet").click(function () {
|
||||||
alert(template($("#sheet").html(), games[name]));
|
alert(template($("#sheet").html(), games[name]));
|
||||||
// TODO: put in a window or whatev
|
// TODO: put in a window or whatev
|
||||||
});
|
});
|
||||||
|
|
||||||
br.find("a.save").attr("href",
|
br.find("a.save").attr("href",
|
||||||
`data:text/plain;name=${name}.pqw,${b64_stringify(c)}`);
|
`data:text/plain;name=${name}.pqw,${b64_stringify(c)}`);
|
||||||
br.find("a.save").attr("download", `${name}.pqw`);
|
br.find("a.save").attr("download", `${name}.pqw`);
|
||||||
|
|
||||||
if (name === newone)
|
if (name === newone)
|
||||||
br.addClass("lit");
|
br.addClass("lit");
|
||||||
|
|
||||||
br.click(e => {
|
br.click(e => {
|
||||||
if (e.altKey) {
|
if (e.altKey) {
|
||||||
let text = b64_stringify(c);
|
let text = b64_stringify(c);
|
||||||
text = text.match(/.{1,80}/g).join('\n');
|
text = text.match(/.{1,80}/g).join('\n');
|
||||||
$("dialog#copy pre").text(text);
|
$("dialog#copy pre").text(text);
|
||||||
$("dialog#copy span").text(name);
|
$("dialog#copy span").text(name);
|
||||||
sel = window.getSelection();
|
sel = window.getSelection();
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
let range = document.createRange();
|
let range = document.createRange();
|
||||||
range.selectNodeContents($("dialog#copy pre")[0]);
|
range.selectNodeContents($("dialog#copy pre")[0]);
|
||||||
sel.removeAllRanges();
|
sel.removeAllRanges();
|
||||||
sel.addRange(range);
|
sel.addRange(range);
|
||||||
}, 1);
|
}, 1);
|
||||||
$("dialog#copy")[0].showModal();
|
$("dialog#copy")[0].showModal();
|
||||||
// window.prompt("Copy to clipboard", text);
|
// window.prompt("Copy to clipboard", text);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
br.find("a.go").attr("data-downloadurl", `text/plain:${name}.pqw:data:text/plain,${b64_stringify(c)}`);
|
br.find("a.go").attr("data-downloadurl", `text/plain:${name}.pqw:data:text/plain,${b64_stringify(c)}`);
|
||||||
|
|
||||||
++count;
|
++count;
|
||||||
});
|
});
|
||||||
if (!count)
|
if (!count)
|
||||||
roster.html("<i>Games you start can be loaded from this page, but no saved games were found. Roll up a new character to get started.</i>");
|
roster.html("<i>Games you start can be loaded from this page, but no saved games were found. Roll up a new character to get started.</i>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function brag(sheet) {
|
function brag(sheet) {
|
||||||
var brag = $(template($("#badge").html(), sheet));
|
var brag = $(template($("#badge").html(), sheet));
|
||||||
if (sheet.motto) {
|
if (sheet.motto) {
|
||||||
brag.find(".bs").text('"' + sheet.motto + '"');
|
brag.find(".bs").text('"' + sheet.motto + '"');
|
||||||
}
|
}
|
||||||
if (sheet.online) {
|
if (sheet.online) {
|
||||||
brag.addClass("online");
|
brag.addClass("online");
|
||||||
brag.find(".bs").text("Realm of " + sheet.online.realm);
|
brag.find(".bs").text("Realm of " + sheet.online.realm);
|
||||||
brag.find(".icon.go").html("✿");
|
brag.find(".icon.go").html("✿");
|
||||||
}
|
}
|
||||||
return brag;
|
return brag;
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearRoster() {
|
function clearRoster() {
|
||||||
storage.storeRoster({}, load);
|
storage.storeRoster({}, load);
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
|
||||||
load();
|
load();
|
||||||
|
|
||||||
$("#roll").click(function () {
|
$("#roll").click(function () {
|
||||||
window.location = "newguy.html";
|
window.location = "newguy.html";
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#test").click(function () {
|
$("#test").click(function () {
|
||||||
window.location = "newguy.html?sold";
|
window.location = "newguy.html?sold";
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#clear").click(clearRoster);
|
$("#clear").click(clearRoster);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user