all repos — felt @ 4ba6c9315fa06c4b0b01cd16b0629d37ef6e2a54

virtual tabletop for dungeons and dragons (and similar) using Go, MongoDB, and websockets

can write tokens to the db and get them back
Iris Lightshard nilix@nilfm.cc
commit

4ba6c9315fa06c4b0b01cd16b0629d37ef6e2a54

parent

01fccb55f077384bbb47b0525bf0de41b34929ca

M admin/admin.goadmin/admin.go

@@ -48,7 +48,7 @@

if dbAdapter.CheckTable(tableKey) { mapUrl, _ := dbAdapter.GetMapImageUrl(tableKey) auxMessage, _ := dbAdapter.GetAuxMessage(tableKey) - tokens, _ := dbAdapter.GetTokens(tableKey, true) + tokens, _ := dbAdapter.GetTokens(tableKey, false) diceRolls, _ := dbAdapter.GetDiceRolls(tableKey) AddContextValue(req, "tableData", models.Table{
M gametable/server.gogametable/server.go

@@ -272,14 +272,16 @@ return err

} } if tableMsg.Token != nil { - t := *tableMsg.Token + t := tableMsg.Token + strId := "" + if t.Id != nil { + strId = *t.Id + } + fmt.Println(strId +"::" + t.Name + "::" + t.Sprite) if t.Id == nil { - id, err := self.dbAdapter.CreateToken(key, t) - if err == nil { - *tableMsg.Token.Id = id - } else { - return err - } + id, err := self.dbAdapter.CreateToken(key, *t) + t.Id = &id + return err } else { if t.X == nil && t.Y == nil && !t.Active { err := self.dbAdapter.DestroyToken(key, *t.Id)
M mongodb/adapter.gomongodb/adapter.go

@@ -319,6 +319,8 @@ }

func (self *DbEngine) CreateToken(table models.TableKey, token models.Token) (string, error) { tables := self.db.Collection("tables") + id := primitive.NewObjectID().Hex() + token.Id = &id if tables != nil { var result models.Table err := tables.FindOneAndUpdate(

@@ -332,8 +334,7 @@ {"$push", bson.D{{"tokens", token}}},

}, ).Decode(&result) if err == nil { - newId := result.Tokens[len(result.Tokens)-1].Id - return *newId, nil + return id, err } else { return "", err }
M static/admin.jsstatic/admin.js

@@ -18,7 +18,7 @@ const tokenAspect = document.getElementById("tokenKeepAspect");

const aspectLockLabel = document.getElementById("aspectLockLabel"); const tokenZone = document.getElementById("tokenZone"); -async function getTable(name, pass) { +async function rebindUi(name, pass) { try { const headers = new Headers(); headers.set('Authorization', 'Bearer ' + adminToken.access_token);

@@ -72,7 +72,7 @@ tokenListHTML += `<li>${parts[parts.length - 1]} <a href="${t}" target="_blank">view</a> <button onclick="deleteImg('${t}')">Delete</button></li>\n`

} tokenListHTML += "</ul>"; fillSpriteDropdown(tokens); - redrawTokenMasterList(); + } else { tokenListHTML += "<label>Sprites couldn't be retrieved</label>" }

@@ -85,15 +85,6 @@ console.log(res.status);

} } catch (err) { setErr(`${err.name}: ${err.message}`); - } -} - -function redrawTokenMasterList() { - if (tokenZone) { - const headers = new Headers(); - headers.set('Authorization', 'Bearer ' + adminToken.access_token); - - const res = await fetch(`/` } }

@@ -225,9 +216,21 @@ resizeMarkers();

*/ // really though we have to send it on the websocket and wait for it to come back - - + const [x, y] = getCascadingPos(); + sendToken({ + w: w, + h: h, + ox:oX, + oy:oY, + x: x, + y: y, + sprite: img, + name: name, + active: false} + ); + return; } + setErr("All token fields are required"); } function publishAuxMsg() {

@@ -267,7 +270,7 @@ body: data,

}); if (res.ok) { // refresh so we can see the new entry in the list - getTable(tableKey.name, tableKey.passcode); + rebindUi(tableKey.name, tableKey.passcode); } else { throw new Error("Something went wrong uploading the map BG..."); }

@@ -291,7 +294,7 @@ body: data,

}); if (res.ok) { // refresh so we can see the new entry in the list - getTable(tableKey.name, tableKey.passcode); + rebindUi(tableKey.name, tableKey.passcode); } else { throw new Error("Something went wrong uploading the token sprite..."); }

@@ -317,7 +320,7 @@ });

if (res.ok) { // refresh UI - getTable(tableKey.name, tableKey.passcode); + rebindUi(tableKey.name, tableKey.passcode); } else { throw new Error ("Something went wrong deleting the image..."); }

@@ -363,7 +366,7 @@ if (res.ok) {

const tableList = await res.json(); let tableListHTML = "<ul>\n"; for (const t of tableList) { - tableListHTML += `<li><a href="#" onclick="getTable('${t.name}','${t.passcode}');return false;">${t.name}</a></li>\n` + tableListHTML += `<li><a href="#" onclick="rebindUi('${t.name}','${t.passcode}');return false;">${t.name}</a></li>\n` } tableListHTML += "</ul>" adminZone.innerHTML = tableListHTML;
M static/index.htmlstatic/index.html

@@ -9,7 +9,9 @@ <link href="./style.css" rel="stylesheet" />

</head> <body> <div id="map"></div> + <div id="errWrapper" style='display:none'><button id="closeErr" onclick="closeErr()">x</button><div id="errDiv"></div></div> + <nav> <section id="user_section"> <details class="ui_win"><summary>identity</summary>

@@ -27,44 +29,49 @@ </details><br/>

<div id="tabletop" style="display:none;"> <details id="dice_win" class="ui_win"><summary>dice</summary> - <select id="num_dice"> - <option>1</option> - <option>2</option> - <option>3</option> - <option>4</option> - <option>5</option> - <option>6</option> - <option>7</option> - <option>8</option> - <option>9</option> - <option>10</option> - <option>11</option> - <option>12</option> - <option>13</option> - <option>14</option> - <option>15</option> - <option>16</option> - <option>17</option> - <option>18</option> - <option>19</option> - <option>20</option> - </select> - <label for="dice_faces">d</label> - <select id="dice_faces"> - <option>4</option> - <option selected>6</option> - <option>8</option> - <option>10</option> - <option>12</option> - <option>20</option> - </select> - <input id="dice_note"><button id="dice_submit" onclick="rollDice()">Roll</button> - <div id="dice_log"></div> + <select id="num_dice"> + <option>1</option> + <option>2</option> + <option>3</option> + <option>4</option> + <option>5</option> + <option>6</option> + <option>7</option> + <option>8</option> + <option>9</option> + <option>10</option> + <option>11</option> + <option>12</option> + <option>13</option> + <option>14</option> + <option>15</option> + <option>16</option> + <option>17</option> + <option>18</option> + <option>19</option> + <option>20</option> + </select> + <label for="dice_faces">d</label> + <select id="dice_faces"> + <option>4</option> + <option selected>6</option> + <option>8</option> + <option>10</option> + <option>12</option> + <option>20</option> + </select> + <input id="dice_note"><button id="dice_submit" onclick="rollDice()">Roll</button> + <div id="dice_log"></div> </details><br/> + <details class="ui_win"><summary>status</summary><pre id="aux"></pre></details><br/> + + <details class="ui_win"><summary>token select</summary> + <div id="token_select"></div> + </details><br/> </div> + </section> - <section id="admin_section"> <details class="ui_win admin_win"><summary>admin</summary>

@@ -74,6 +81,7 @@ <button type="submit" id="admin_login" onclick="doLogin();">Login</button>

</form> </details> <br/> + <div id="adminWrapper" style="display:none;"> <details id="admin_table_win" class="ui_win admin_win"><summary>table</summary> <button onclick="setTableCreateFormVisible(true)">New Table</button>
M static/map.jsstatic/map.js

@@ -36,10 +36,10 @@ });

} function getCascadingPos() { - const topLeft = worldBounds[0]; + const topLeft = [0,0]; const n = tokens.length; - topLeft[1] += (n+1)*5; - topLeft[0] -= (n+1)*5; + topLeft[1] += (n)*Math.random()*10 - 5; + topLeft[0] -= (n)*Math.random()*10 - 5; return topLeft; }
M static/style.cssstatic/style.css

@@ -112,6 +112,7 @@

#auxMsgZone { width: 100%; padding:0.2em; + height: 8em; } #adminWrapper {