diff --git a/client/lib/mixins/lock/README.md b/client/lib/mixins/lock/README.md deleted file mode 100644 index d61687285a50c..0000000000000 --- a/client/lib/mixins/lock/README.md +++ /dev/null @@ -1,53 +0,0 @@ -Lock -==== - - -A simple non-async lock object inspired by the mutex (Mutual Exclusion) locks found in concurrency control programming ([Wikipedia](https://en.wikipedia.org/wiki/Lock_(computer_science))). - -It emits `change` upon successful locking or unlocking, and hence works nicely with the `data-observe` mixin. - - -### Why? - -Potential use cases: - -- If you have several entities that need to access a limited resource that can only be used by one entity at a time — e.g. entities performing atomic sets of reads & writes to a certain file. - -- More generally, if you need to enforce an arbitrary constraint across a set of entities, such as state that may be held by no more than one entity at a time. See `my-sites/menus` for an actual example. - - -### Usage - -Lock has React components in mind, but is by no means limited to them. - -```js -var Lock = require( 'lock' ), - lock = new Lock(); - -lock.lock( entity1 ); // entity1 holds the lock, as confirmed by true return value -lock.lock( entity2 ); // fails, as confirmed by false return value - -[ entity1, entity2 ].forEach( function( entity ) { - if ( lock.hasLock( entity ) ) { - entity.say( "omg, I am sooo exclusive" ); - entity.doExclusiveThing(); - lock.unlock( entity ); // now now, learn to share - } else { - entity.say( "Not my turn" ); - } -} ); -``` - -Consider naming your Lock instance something more meaningful, like `resourceBroker` — or even `resource` if you mix the Lock into the resource you seek to manage. - - -### Caveats - -Be careful not to "lose" the instance currently holding the lock. In the case of React components, consider adding something like: - -```js -componentWillUnmount: function() { - this.props.lock.unlock( this, { silent: true } ); -}, -``` - diff --git a/client/lib/mixins/lock/index.js b/client/lib/mixins/lock/index.js deleted file mode 100644 index 8ecd28a6398db..0000000000000 --- a/client/lib/mixins/lock/index.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Internal dependencies - */ -var Emitter = require( 'lib/mixins/emitter' ); - - -/** - * Lock component - * - * @api public - */ -function Lock() { - this.instance = null; -} - -/** - * Mixins - */ -Emitter( Lock.prototype ); - - -Lock.prototype.isLocked = function() { - return !! this.instance; -}; - - -Lock.prototype.hasLock = function( instance ) { - return instance === this.instance; -}; - - -Lock.prototype.mustWait = function( instance ) { - return this.isLocked() && ! this.hasLock( instance ); -}; - - -Lock.prototype.lock = function( instance ) { - if ( ! this.instance ) { - this.instance = instance; - this.emit( 'change' ); - return true; - } - return false; -}; - - -Lock.prototype.unlock = function( instance, opts ) { - opts = opts || {}; - if ( instance === this.instance ) { - this.instance = null; - if ( ! opts.silent ) { - this.emit( 'change' ); - } - return true; - } - return false; -}; - - -module.exports = Lock; diff --git a/client/my-sites/menus/main.jsx b/client/my-sites/menus/main.jsx index 0be6301258a76..90f147ab8b38c 100644 --- a/client/my-sites/menus/main.jsx +++ b/client/my-sites/menus/main.jsx @@ -16,7 +16,6 @@ var protectForm = require( 'lib/mixins/protect-form' ), SidebarNavigation = require( 'my-sites/sidebar-navigation' ), Main = require( 'components/main' ), Menu = require( './menu' ), - Lock = require( 'lib/mixins/lock' ), MenuSaveButton = require( './menus-save-button' ), EmptyContent = require( 'components/empty-content' ), LoadingPlaceholder = require( './loading-placeholder' ), @@ -237,7 +236,6 @@ var Menus = React.createClass( { selectedMenu={ selectedMenu } selectedLocation={ selectedLocation } siteMenus={ this.props.siteMenus } - itemsLock={ new Lock() } setBusy={ this.setBusy } confirmDiscard={ this.confirmDiscard.bind( null, 'menu' ) } />; } diff --git a/client/my-sites/menus/menu-item-list.jsx b/client/my-sites/menus/menu-item-list.jsx index a5aa074e90dc0..33c5049c16938 100644 --- a/client/my-sites/menus/menu-item-list.jsx +++ b/client/my-sites/menus/menu-item-list.jsx @@ -50,7 +50,8 @@ var MenuItemList = React.createClass( { item={ menuItem } items={ menuItem.items } depth={ this.props.depth + 1 } - lock={ this.props.lock } + getEditItem={ this.props.getEditItem } + setEditItem={ this.props.setEditItem } moveState={ this.props.moveState } doMoveItem={ this.props.doMoveItem } addState={ this.props.addState } @@ -100,22 +101,18 @@ var MenuItem = React.createClass( { }; }, - componentWillUnmount: function() { - this.props.lock.unlock( this, { silent: true } ); - }, - edit: function() { - this.props.lock.lock( this ); + this.props.setEditItem( this.props.item.id ); }, cancelCurrentOperation: function() { - this.props.lock.unlock( this ); + this.props.setEditItem( null ); this.props.doMoveItem( 'cancel' ); this.props.doAddItem( 'cancel' ); }, startMoveItem: function() { - this.props.lock.unlock( this ); + this.props.setEditItem( null ); this.props.doMoveItem( 'setSource', this.props.item.id ); }, @@ -141,7 +138,7 @@ var MenuItem = React.createClass( { }, isEditing: function() { - return this.props.lock.hasLock( this ); + return this.props.getEditItem() === this.props.item.id; }, addNewItemInProgress: function() { @@ -149,7 +146,7 @@ var MenuItem = React.createClass( { }, canEdit: function() { - return ! this.props.lock.mustWait( this ) && + return ! this.props.getEditItem() && ! this.props.moveState.moving && ! this.addNewItemInProgress() && ! this.props.confirmDeleteItem; @@ -380,7 +377,8 @@ var MenuItem = React.createClass( { depth={ this.props.depth } menuData={ this.props.menuData } items={ this.props.items } - lock={ this.props.lock } + setEditItem={ this.props.setEditItem } + getEditItem={ this.props.getEditItem } moveState={ this.props.moveState } doMoveItem={ this.props.doMoveItem } addState={ this.props.addState } diff --git a/client/my-sites/menus/menu.jsx b/client/my-sites/menus/menu.jsx index bd432d1de8908..2cba2c015ea9a 100644 --- a/client/my-sites/menus/menu.jsx +++ b/client/my-sites/menus/menu.jsx @@ -21,7 +21,7 @@ var protectForm = require( 'lib/mixins/protect-form' ), */ var Menu = React.createClass( { - mixins: [ protectForm.mixin, observe( 'itemsLock' ) ], + mixins: [ protectForm.mixin ], MOUSE_DRAG_STEP_PIXELS: 16, @@ -29,7 +29,8 @@ var Menu = React.createClass( { return { moveState: {}, addState: {}, - confirmDeleteItem: null + confirmDeleteItem: null, + editItemId: null }; }, @@ -190,11 +191,16 @@ var Menu = React.createClass( { this.setState( { confirmDeleteItem: id } ); }, - renderAddTip: function() { - var isNotEditing = this.props.itemsLock.isLocked && - ! this.props.itemsLock.isLocked(); + setEditItem: function( itemId ) { + this.setState( { editItemId: itemId } ); + }, - return isNotEditing ? + getEditItem: function() { + return this.state.editItemId; + }, + + renderAddTip: function() { + return ! this.getEditItem() ?