diff --git a/client/assets/styles/styles.css b/client/assets/styles/styles.css
index d871153b..a9112f48 100644
--- a/client/assets/styles/styles.css
+++ b/client/assets/styles/styles.css
@@ -368,6 +368,26 @@ header {
transition-timing-function: ease;
}
+.menu-construct .controls {
+ display: flex;
+}
+
+.menu-construct .controls h2 {
+ flex: 1;
+}
+
+.menu-construct .controls button {
+ color: #444;
+ flex: 0;
+ margin: 0;
+ border: none;
+ padding: 0.25em;
+}
+
+.menu-construct .controls button:hover, .menu-construct .controls button:active {
+ color: whitesmoke;
+}
+
.menu-construct .avatar {
background-size: contain;
background-repeat: no-repeat;
diff --git a/client/src/actions.jsx b/client/src/actions.jsx
index 6324b9e0..58a30438 100644
--- a/client/src/actions.jsx
+++ b/client/src/actions.jsx
@@ -1,5 +1,6 @@
export const setAccount = value => ({ type: 'SET_ACCOUNT', value });
export const setConstructs = value => ({ type: 'SET_CONSTRUCTS', value });
+export const setConstructDeleteId = value => ({ type: 'SET_CONSTRUCT_DELETE_ID', value });
export const setItemInfo = value => ({ type: 'SET_ITEM_INFO', value });
export const setSkip = value => ({ type: 'SET_SKIP', value });
export const setVboxHighlight = value => ({ type: 'SET_VBOX_HIGHLIGHT', value });
diff --git a/client/src/components/team.jsx b/client/src/components/team.jsx
index afce6622..c848dbb2 100644
--- a/client/src/components/team.jsx
+++ b/client/src/components/team.jsx
@@ -12,16 +12,22 @@ const idSort = stringSort('id');
const addState = connect(
function receiveState(state) {
- const { ws, constructs, team } = state;
+ const { ws, constructs, team, constructDeleteId } = state;
function sendConstructSpawn(name) {
return ws.sendConstructSpawn(name);
}
+ function sendConstructDelete(id) {
+ return ws.sendConstructDelete(id);
+ }
+
return {
constructs,
+ constructDeleteId,
team,
sendConstructSpawn,
+ sendConstructDelete,
};
},
@@ -31,8 +37,13 @@ const addState = connect(
dispatch(actions.setTeam(constructIds));
}
+ function setDeleteId(id) {
+ dispatch(actions.setConstructDeleteId(id));
+ }
+
return {
setTeam,
+ setDeleteId,
};
}
);
@@ -41,9 +52,13 @@ function Team(args) {
const {
constructs,
team,
+ constructDeleteId,
setTeam,
sendConstructSpawn,
+ sendConstructDelete,
+
+ setDeleteId,
} = args;
if (!constructs) return
;
@@ -71,14 +86,26 @@ function Team(args) {
const borderColour = selected ? COLOURS[colour] : '#000000';
+ function deleteClick(e) {
+ e.stopPropagation();
+ if (constructDeleteId === construct.id) return sendConstructDelete(construct.id);
+ return setDeleteId(construct.id);
+ }
+
+ //
return (
);
});
@@ -89,7 +116,7 @@ function Team(args) {
.map(i => sendConstructSpawn(name)} />);
return (
-
+ setDeleteId(null)}>
{constructPanels}
{spawnButtons}
diff --git a/client/src/keyboard.jsx b/client/src/keyboard.jsx
index 8f7b8c60..3791cbb1 100644
--- a/client/src/keyboard.jsx
+++ b/client/src/keyboard.jsx
@@ -12,6 +12,7 @@ function setupKeys(store) {
key('esc', () => store.dispatch(actions.setItemEquip(null)));
key('esc', () => store.dispatch(actions.setItemUnequip(null)));
key('esc', () => store.dispatch(actions.setVboxHighlight([])));
+ key('esc', () => store.dispatch(actions.setConstructDeleteId(null)));
}
module.exports = setupKeys;
diff --git a/client/src/reducers.jsx b/client/src/reducers.jsx
index 4cf8e721..2498963b 100644
--- a/client/src/reducers.jsx
+++ b/client/src/reducers.jsx
@@ -17,6 +17,7 @@ module.exports = {
activeSkill: createReducer(null, 'SET_ACTIVE_SKILL'),
combiner: createReducer([null, null, null], 'SET_COMBINER'),
constructs: createReducer([], 'SET_CONSTRUCTS'),
+ constructDeleteId: createReducer(null, 'SET_CONSTRUCT_DELETE_ID'),
game: createReducer(null, 'SET_GAME'),
info: createReducer(null, 'SET_INFO'),
instance: createReducer(null, 'SET_INSTANCE'),
diff --git a/client/src/socket.jsx b/client/src/socket.jsx
index 7f277b29..b4a9d826 100644
--- a/client/src/socket.jsx
+++ b/client/src/socket.jsx
@@ -59,6 +59,10 @@ function createSocket(events) {
send({ method: 'construct_spawn', params: { name } });
}
+ function sendConstructDelete(id) {
+ send({ method: 'construct_delete', params: { id } });
+ }
+
function sendGameState(id) {
send({ method: 'game_state', params: { id } });
}
@@ -324,6 +328,7 @@ function createSocket(events) {
sendGameSkill,
sendGameTarget,
sendConstructSpawn,
+ sendConstructDelete,
sendInstanceJoin,
sendInstanceList,
sendInstanceReady,
diff --git a/server/src/construct.rs b/server/src/construct.rs
index e4126e58..5b7f4471 100644
--- a/server/src/construct.rs
+++ b/server/src/construct.rs
@@ -803,7 +803,7 @@ pub fn construct_delete(tx: &mut Transaction, id: Uuid, account_id: Uuid) -> Res
let query = "
DELETE
FROM constructs
- WHERE id = $1;
+ WHERE id = $1
and account = $2;
";
diff --git a/server/src/rpc.rs b/server/src/rpc.rs
index 4dae9901..a9b43ffa 100644
--- a/server/src/rpc.rs
+++ b/server/src/rpc.rs
@@ -12,11 +12,10 @@ use failure::Error;
use failure::err_msg;
use net::Db;
-use construct::{Construct, construct_spawn};
+use construct::{Construct, construct_spawn, construct_delete};
use game::{Game, game_state, game_skill, game_ready};
use account::{Account, account_create, account_login, account_from_token, account_constructs, account_instances};
use skill::{Skill};
-use spec::{Spec};
use instance::{Instance, instance_state, instance_list, instance_new, instance_ready, instance_join};
use vbox::{vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip};
use item::{Item, ItemInfoCtr, item_info};
@@ -72,6 +71,7 @@ impl Rpc {
"account_instances" => Rpc::account_instances(data, &mut tx, account.unwrap(), client),
"construct_spawn" => Rpc::construct_spawn(data, &mut tx, account.unwrap(), client),
+ "construct_delete" => Rpc::construct_delete(data, &mut tx, account.unwrap(), client),
"game_state" => Rpc::game_state(data, &mut tx, account.unwrap(), client),
"game_skill" => Rpc::game_skill(data, &mut tx, account.unwrap(), client),
@@ -175,10 +175,10 @@ impl Rpc {
Ok(construct_list)
}
- fn construct_delete(data: Vec, tx: &mut Transaction, account: Account, client: &mut WebSocket) -> Result {
+ fn construct_delete(data: Vec, tx: &mut Transaction, account: Account, _client: &mut WebSocket) -> Result {
let msg = from_slice::(&data).or(Err(err_msg("invalid params")))?;
- construct_delete(msg.params.id, tx, &account)?;
+ construct_delete(tx, msg.params.id, account.id)?;
let construct_list = RpcResponse {
method: "account_constructs".to_string(),