diff --git a/pub/tree/src/js/components/Async.coffee b/pub/tree/src/js/components/Async.coffee index 4ac091065..4b7b52f67 100644 --- a/pub/tree/src/js/components/Async.coffee +++ b/pub/tree/src/js/components/Async.coffee @@ -63,5 +63,5 @@ module.exports = (queries, Child, load=_load)-> recl if not @getHashElement() # onmount? setTimeout @scrollHash,0 React.createElement Child, - (_.extend {}, @props, @state.got), + (_.extend {}, @props, @state.got, ref:"loaded"), @props.children diff --git a/pub/tree/src/js/components/BodyComponent.coffee b/pub/tree/src/js/components/BodyComponent.coffee index 4d212f152..dce525236 100644 --- a/pub/tree/src/js/components/BodyComponent.coffee +++ b/pub/tree/src/js/components/BodyComponent.coffee @@ -63,21 +63,28 @@ extras = render: -> (div {className:"footer"}, (p {}, "This page was served by Urbit.")) -Edit = query {mime:'m'}, recl +Edit = query {spur:'t',mime:'m'}, recl displayName: "Edit" + doneEditing: -> + txt = $(@getDOMNode()).find('.CodeMirror')[0].CodeMirror.getValue() # XX refs + if txt is @props.mime.octs + return @props.unsetEdit false + TreeActions.saveFile @props.spur, txt, => @props.unsetEdit() + @props.setPending() + render: -> {mite,octs} = @props.mime rele codemirror, {value:octs, mode:mite, readOnly:false, autofocus:true} -Add = recl +Add = query {spur:'t',path:'t'}, recl displayName: "Add" - getInitialState: -> edit:false - onClick: -> @setState edit:true + getInitialState: -> input:false + onClick: -> @setState input:true componentDidUpdate: -> - if @state.edit + if @state.input $(@getDOMNode()).focus() render: -> - unless @state.edit + unless @state.input button {@onClick}, "Add" else input {type:"text",onKeyDown:(e)=> @@ -96,7 +103,7 @@ Add = recl mime:{mite:"text/x-markdown",octs:'# '+value} body:{gn:"div",ga:{},c:[{gn:"h1",ga:{},c:[value]}]} } - @setState edit:false + @setState input:false } module.exports = query { @@ -105,26 +112,41 @@ module.exports = query { path:'t' meta:'j' sein:'t' - spur:'t' }, recl displayName: "Body" - getInitialState: -> edit: document.location.hash is "#edit" + isOwn: -> urb.user? and urb.user is urb.ship + getInitialState: -> edit: @isOwn() and document.location.hash is "#edit" + + pauseWasp: -> + @urb_onupdate = urb.onupdate + urb.onupdate = => @urb_updated = arguments + resumeWasp: -> + if @urb_onupdate + urb.onupdate = @urb_onupdate + delete @urb_onupdate + if @urb_updated + urb.onupdate.apply urb, @urb_updated + + setPending: -> @setState edit:"pending" setEdit: -> @hash = document.location.hash document.location.hash = "#edit" # XX generic state<->hash binding @setState edit:true - urb.onupdate = -> # disable autoreload - unsetEdit: -> + @pauseWasp() + unsetEdit: (mod)-> document.location.hash = @hash ? "" - document.location.reload() # XX sigh - # @setState edit:false + if mod isnt false + document.location.reload() + else + @resumeWasp() + @setState edit:false doDelete: -> TreeActions.deleteFile @props.spur, => @unsetEdit() @setState edit:"gone" render: -> className = clas (@props.meta.layout?.split ',') - own = urb.user and urb.user is urb.ship + own = @isOwn() extra = (name,props={})=> if @props.meta[name]? then rele extras[name], props @@ -136,11 +158,11 @@ module.exports = query { body = div {}, rele load, {} editButton = button {onClick: => @setEdit()}, "Edit" when true - body = rele Edit, {} + body = rele Edit, {ref:"editor",@setPending,@unsetEdit} onClick = => - txt = $(@getDOMNode()).find('.CodeMirror')[0].CodeMirror.getValue() # XX refs - TreeActions.saveFile @props.spur, txt, => @unsetEdit() - @setState edit:"pending" + {loaded} = @refs.editor.refs # components/Async + if loaded? then loaded.doneEditing() + else @unsetEdit false editButton = button {onClick}, "Done" (div { @@ -154,6 +176,6 @@ module.exports = query { if own then button {onClick: => @doDelete()}, "Delete" body extra 'next', {dataPath:@props.sein,curr:@props.name} - if own then rele Add,{spur:@props.spur, path:@props.path} + if own then rele Add, {} extra 'footer' ) diff --git a/pub/tree/src/js/main.js b/pub/tree/src/js/main.js index 79294ac05..10d27ac00 100644 --- a/pub/tree/src/js/main.js +++ b/pub/tree/src/js/main.js @@ -445,7 +445,9 @@ module.exports = function(queries, Child, load) { } }, render: function() { - return div({}, this.filterQueries() != null ? React.createElement(load, this.props) : (!this.getHashElement() ? setTimeout(this.scrollHash, 0) : void 0, React.createElement(Child, _.extend({}, this.props, this.state.got), this.props.children))); + return div({}, this.filterQueries() != null ? React.createElement(load, this.props) : (!this.getHashElement() ? setTimeout(this.scrollHash, 0) : void 0, React.createElement(Child, _.extend({}, this.props, this.state.got, { + ref: "loaded" + }), this.props.children))); } }); }; @@ -553,9 +555,23 @@ extras = { }; Edit = query({ + spur: 't', mime: 'm' }, recl({ displayName: "Edit", + doneEditing: function() { + var txt; + txt = $(this.getDOMNode()).find('.CodeMirror')[0].CodeMirror.getValue(); + if (txt === this.props.mime.octs) { + return this.props.unsetEdit(false); + } + TreeActions.saveFile(this.props.spur, txt, (function(_this) { + return function() { + return _this.props.unsetEdit(); + }; + })(this)); + return this.props.setPending(); + }, render: function() { var mite, octs, ref1; ref1 = this.props.mime, mite = ref1.mite, octs = ref1.octs; @@ -568,25 +584,28 @@ Edit = query({ } })); -Add = recl({ +Add = query({ + spur: 't', + path: 't' +}, recl({ displayName: "Add", getInitialState: function() { return { - edit: false + input: false }; }, onClick: function() { return this.setState({ - edit: true + input: true }); }, componentDidUpdate: function() { - if (this.state.edit) { + if (this.state.input) { return $(this.getDOMNode()).focus(); } }, render: function() { - if (!this.state.edit) { + if (!this.state.input) { return button({ onClick: this.onClick }, "Add"); @@ -624,7 +643,7 @@ Add = recl({ } }); return _this.setState({ - edit: false + input: false }); } }; @@ -632,34 +651,65 @@ Add = recl({ }); } } -}); +})); module.exports = query({ body: 'r', name: 't', path: 't', meta: 'j', - sein: 't', - spur: 't' + sein: 't' }, recl({ displayName: "Body", + isOwn: function() { + return (urb.user != null) && urb.user === urb.ship; + }, getInitialState: function() { return { - edit: document.location.hash === "#edit" + edit: this.isOwn() && document.location.hash === "#edit" }; }, + pauseWasp: function() { + this.urb_onupdate = urb.onupdate; + return urb.onupdate = (function(_this) { + return function() { + return _this.urb_updated = arguments; + }; + })(this); + }, + resumeWasp: function() { + if (this.urb_onupdate) { + urb.onupdate = this.urb_onupdate; + delete this.urb_onupdate; + if (this.urb_updated) { + return urb.onupdate.apply(urb, this.urb_updated); + } + } + }, + setPending: function() { + return this.setState({ + edit: "pending" + }); + }, setEdit: function() { this.hash = document.location.hash; document.location.hash = "#edit"; this.setState({ edit: true }); - return urb.onupdate = function() {}; + return this.pauseWasp(); }, - unsetEdit: function() { + unsetEdit: function(mod) { var ref1; document.location.hash = (ref1 = this.hash) != null ? ref1 : ""; - return document.location.reload(); + if (mod !== false) { + return document.location.reload(); + } else { + this.resumeWasp(); + return this.setState({ + edit: false + }); + } }, doDelete: function() { TreeActions.deleteFile(this.props.spur, (function(_this) { @@ -674,7 +724,7 @@ module.exports = query({ render: function() { var body, className, editButton, extra, onClick, own, ref1; className = clas((ref1 = this.props.meta.layout) != null ? ref1.split(',') : void 0); - own = urb.user && urb.user === urb.ship; + own = this.isOwn(); extra = (function(_this) { return function(name, props) { if (props == null) { @@ -708,17 +758,20 @@ module.exports = query({ }, "Edit"); break; case true: - body = rele(Edit, {}); + body = rele(Edit, { + ref: "editor", + setPending: this.setPending, + unsetEdit: this.unsetEdit + }); onClick = (function(_this) { return function() { - var txt; - txt = $(_this.getDOMNode()).find('.CodeMirror')[0].CodeMirror.getValue(); - TreeActions.saveFile(_this.props.spur, txt, function() { - return _this.unsetEdit(); - }); - return _this.setState({ - edit: "pending" - }); + var loaded; + loaded = _this.refs.editor.refs.loaded; + if (loaded != null) { + return loaded.doneEditing(); + } else { + return _this.unsetEdit(false); + } }; })(this); editButton = button({ @@ -740,10 +793,7 @@ module.exports = query({ }, "Delete") : void 0, body, extra('next', { dataPath: this.props.sein, curr: this.props.name - }), own ? rele(Add, { - spur: this.props.spur, - path: this.props.path - }) : void 0, extra('footer')); + }), own ? rele(Add, {}) : void 0, extra('footer')); } }));