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(),