mirror of
https://github.com/flarum/framework.git
synced 2025-02-18 09:12:45 +08:00
Composer and replying tweaks/bug-fixes
This commit is contained in:
parent
1db559e4c3
commit
e53b3872c9
|
@ -9,7 +9,7 @@ export default Ember.Component.extend(Ember.Evented, {
|
||||||
|
|
||||||
submitLabel: 'Post Reply',
|
submitLabel: 'Post Reply',
|
||||||
placeholder: '',
|
placeholder: '',
|
||||||
value: '',
|
content: '',
|
||||||
submit: null,
|
submit: null,
|
||||||
loading: false,
|
loading: false,
|
||||||
|
|
||||||
|
@ -29,21 +29,23 @@ export default Ember.Component.extend(Ember.Evented, {
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
submit: function(value) {
|
submit: function(content) {
|
||||||
this.get('submit')(value);
|
this.get('submit')({
|
||||||
|
content: content
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
willExit: function(abort) {
|
willExit: function(abort) {
|
||||||
// If the user has typed something, prompt them before exiting
|
// If the user has typed something, prompt them before exiting
|
||||||
// this composer state.
|
// this composer state.
|
||||||
if (this.get('value') && ! confirm('You have not posted your reply. Do you wish to discard it?')) {
|
if (this.get('content') && ! confirm('You have not posted your reply. Do you wish to discard it?')) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
reset: function() {
|
reset: function() {
|
||||||
this.set('loading', false);
|
this.set('loading', false);
|
||||||
this.set('value', '');
|
this.set('content', '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -27,6 +27,7 @@ export default Ember.Controller.extend(Ember.Evented, {
|
||||||
this.confirmExit().then(function() {
|
this.confirmExit().then(function() {
|
||||||
composer.set('content', null);
|
composer.set('content', null);
|
||||||
Ember.run.next(function() {
|
Ember.run.next(function() {
|
||||||
|
newContent.set('composer', composer);
|
||||||
composer.set('content', newContent);
|
composer.set('content', newContent);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -61,10 +62,10 @@ export default Ember.Controller.extend(Ember.Evented, {
|
||||||
|
|
||||||
hide: function() {
|
hide: function() {
|
||||||
this.set('position', PositionEnum.HIDDEN);
|
this.set('position', PositionEnum.HIDDEN);
|
||||||
var content = this.get('content');
|
},
|
||||||
if (content) {
|
|
||||||
content.send('reset');
|
clearContent: function() {
|
||||||
}
|
this.set('content', null);
|
||||||
},
|
},
|
||||||
|
|
||||||
close: function() {
|
close: function() {
|
||||||
|
@ -75,17 +76,23 @@ export default Ember.Controller.extend(Ember.Evented, {
|
||||||
},
|
},
|
||||||
|
|
||||||
minimize: function() {
|
minimize: function() {
|
||||||
this.set('position', PositionEnum.MINIMIZED);
|
if (this.get('position') !== PositionEnum.HIDDEN) {
|
||||||
|
this.set('position', PositionEnum.MINIMIZED);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
fullscreen: function() {
|
fullscreen: function() {
|
||||||
this.set('position', PositionEnum.FULLSCREEN);
|
if (this.get('position') !== PositionEnum.HIDDEN) {
|
||||||
this.trigger('focus');
|
this.set('position', PositionEnum.FULLSCREEN);
|
||||||
|
this.trigger('focus');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
exitFullscreen: function() {
|
exitFullscreen: function() {
|
||||||
this.set('position', PositionEnum.NORMAL);
|
if (this.get('position') === PositionEnum.FULLSCREEN) {
|
||||||
this.trigger('focus');
|
this.set('position', PositionEnum.NORMAL);
|
||||||
|
this.trigger('focus');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,9 @@ export default Ember.ObjectController.extend(Ember.Evented, {
|
||||||
// Save a reply. This may be called by a composer-reply component that was
|
// Save a reply. This may be called by a composer-reply component that was
|
||||||
// set up on a different discussion, so we require a discussion model to
|
// set up on a different discussion, so we require a discussion model to
|
||||||
// be explicitly passed rather than using the controller's implicit one.
|
// be explicitly passed rather than using the controller's implicit one.
|
||||||
saveReply: function(discussion, content) {
|
// @todo break this down into bite-sized functions so that extensions can
|
||||||
|
// easily override where they please.
|
||||||
|
saveReply: function(discussion, data) {
|
||||||
var controller = this;
|
var controller = this;
|
||||||
var composer = this.get('controllers.composer');
|
var composer = this.get('controllers.composer');
|
||||||
var stream = this.get('stream');
|
var stream = this.get('stream');
|
||||||
|
@ -26,7 +28,7 @@ export default Ember.ObjectController.extend(Ember.Evented, {
|
||||||
controller.get('controllers.application').send('clearAlerts');
|
controller.get('controllers.application').send('clearAlerts');
|
||||||
|
|
||||||
var post = this.store.createRecord('post', {
|
var post = this.store.createRecord('post', {
|
||||||
content: content,
|
content: data.content,
|
||||||
discussion: discussion
|
discussion: discussion
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -91,12 +93,12 @@ export default Ember.ObjectController.extend(Ember.Evented, {
|
||||||
|
|
||||||
// If the composer is already set up for this discussion, then we
|
// If the composer is already set up for this discussion, then we
|
||||||
// don't need to change its content - we can just show it.
|
// don't need to change its content - we can just show it.
|
||||||
if (composer.get('content.discussion') != discussion) {
|
if (!(composer.get('content') instanceof ComposerReply) || composer.get('content.discussion') != discussion) {
|
||||||
composer.switchContent(ComposerReply.create({
|
composer.switchContent(ComposerReply.create({
|
||||||
user: controller.get('session.user'),
|
user: controller.get('session.user'),
|
||||||
discussion: discussion,
|
discussion: discussion,
|
||||||
submit: function(value) {
|
submit: function(data) {
|
||||||
controller.saveReply(discussion, value);
|
controller.saveReply(discussion, data);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
{{ui/controls/item-list items=controls class="composer-header list-inline"}}
|
{{ui/controls/item-list items=controls class="composer-header list-inline"}}
|
||||||
|
|
||||||
<div class="composer-editor">
|
<div class="composer-editor">
|
||||||
{{ui/controls/text-editor submit="submit" value=value placeholder=placeholder submitLabel=submitLabel disabled=loading}}
|
{{ui/controls/text-editor submit="submit" value=content placeholder=placeholder submitLabel=submitLabel disabled=loading}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ui/controls/loading-indicator classNameBindings=":composer-loading loading:active"}}
|
{{ui/controls/loading-indicator classNameBindings=":composer-loading loading:active"}}
|
||||||
|
|
|
@ -6,4 +6,4 @@
|
||||||
{{#if content}}
|
{{#if content}}
|
||||||
{{view content}}
|
{{view content}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -119,9 +119,9 @@ export default Ember.View.extend(Ember.Evented, {
|
||||||
// an element with the class .flexible-height — this element is intended
|
// an element with the class .flexible-height — this element is intended
|
||||||
// to fill up the height of the composer, minus the space taken up by the
|
// to fill up the height of the composer, minus the space taken up by the
|
||||||
// composer's header/footer/etc.
|
// composer's header/footer/etc.
|
||||||
updateContentHeight: function() {
|
setContentHeight: function(height) {
|
||||||
var content = this.$('.composer-content');
|
var content = this.$('.composer-content');
|
||||||
this.$('.flexible-height').height(this.get('computedHeight')
|
this.$('.flexible-height').height(height
|
||||||
- parseInt(content.css('padding-top'))
|
- parseInt(content.css('padding-top'))
|
||||||
- parseInt(content.css('padding-bottom'))
|
- parseInt(content.css('padding-bottom'))
|
||||||
- this.$('.composer-header').outerHeight(true)
|
- this.$('.composer-header').outerHeight(true)
|
||||||
|
@ -144,15 +144,17 @@ export default Ember.View.extend(Ember.Evented, {
|
||||||
// Whenever the composer's computed height changes, update the DOM to
|
// Whenever the composer's computed height changes, update the DOM to
|
||||||
// reflect it.
|
// reflect it.
|
||||||
updateHeight: function() {
|
updateHeight: function() {
|
||||||
if (!this.$()) { return; }
|
Ember.run.scheduleOnce('afterRender', this, function() {
|
||||||
|
this.$().height(this.get('computedHeight'));
|
||||||
var view = this;
|
|
||||||
Ember.run.scheduleOnce('afterRender', function() {
|
|
||||||
view.$().height(view.get('computedHeight'));
|
|
||||||
view.updateContentHeight();
|
|
||||||
});
|
});
|
||||||
}.observes('computedHeight'),
|
}.observes('computedHeight'),
|
||||||
|
|
||||||
|
updateContentHeight: function() {
|
||||||
|
Ember.run.scheduleOnce('afterRender', this, function() {
|
||||||
|
this.setContentHeight(this.get('computedHeight'));
|
||||||
|
});
|
||||||
|
}.observes('computedHeight', 'controller.content'),
|
||||||
|
|
||||||
positionWillChange: function() {
|
positionWillChange: function() {
|
||||||
this.set('oldPosition', this.get('position'));
|
this.set('oldPosition', this.get('position'));
|
||||||
}.observesBefore('position'),
|
}.observesBefore('position'),
|
||||||
|
@ -160,28 +162,28 @@ export default Ember.View.extend(Ember.Evented, {
|
||||||
// Whenever the composer's display state changes, update the DOM to slide
|
// Whenever the composer's display state changes, update the DOM to slide
|
||||||
// it in or out.
|
// it in or out.
|
||||||
positionDidChange: function() {
|
positionDidChange: function() {
|
||||||
var $composer = this.$();
|
|
||||||
if (!$composer) { return; }
|
|
||||||
var view = this;
|
|
||||||
|
|
||||||
// At this stage, the position property has just changed, and the
|
// At this stage, the position property has just changed, and the
|
||||||
// class name hasn't been altered in the DOM. So, we can grab the
|
// class name hasn't been altered in the DOM. So, we can grab the
|
||||||
// composer's current height which we might want to animate from.
|
// composer's current height which we might want to animate from.
|
||||||
// After the DOM has updated, we animate to its new height.
|
// After the DOM has updated, we animate to its new height.
|
||||||
var oldHeight = $composer.height();
|
var $composer = this.$();
|
||||||
|
var oldHeight = $composer ? $composer.height() : 0;
|
||||||
|
|
||||||
Ember.run.scheduleOnce('afterRender', function() {
|
Ember.run.scheduleOnce('afterRender', this, function() {
|
||||||
|
var $composer = this.$();
|
||||||
var newHeight = $composer.height();
|
var newHeight = $composer.height();
|
||||||
|
var view = this;
|
||||||
|
|
||||||
switch (view.get('position')) {
|
switch (this.get('position')) {
|
||||||
case PositionEnum.HIDDEN:
|
case PositionEnum.HIDDEN:
|
||||||
$composer.animate({bottom: -oldHeight}, 'fast', function() {
|
$composer.animate({bottom: -newHeight}, 'fast', function() {
|
||||||
$composer.hide();
|
$composer.hide();
|
||||||
|
view.get('controller').send('clearContent');
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PositionEnum.NORMAL:
|
case PositionEnum.NORMAL:
|
||||||
if (view.get('oldPosition') !== PositionEnum.FULLSCREEN) {
|
if (this.get('oldPosition') !== PositionEnum.FULLSCREEN) {
|
||||||
$composer.show();
|
$composer.show();
|
||||||
$composer.css({height: oldHeight}).animate({bottom: 0, height: newHeight}, 'fast', function() {
|
$composer.css({height: oldHeight}).animate({bottom: 0, height: newHeight}, 'fast', function() {
|
||||||
view.focus();
|
view.focus();
|
||||||
|
@ -196,10 +198,10 @@ export default Ember.View.extend(Ember.Evented, {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (view.get('position') !== PositionEnum.FULLSCREEN) {
|
if (this.get('position') !== PositionEnum.FULLSCREEN) {
|
||||||
view.updateBodyPadding(true);
|
this.updateBodyPadding(true);
|
||||||
}
|
}
|
||||||
view.updateContentHeight();
|
this.setContentHeight(this.get('computedHeight'));
|
||||||
});
|
});
|
||||||
}.observes('position'),
|
}.observes('position'),
|
||||||
|
|
||||||
|
@ -225,7 +227,7 @@ export default Ember.View.extend(Ember.Evented, {
|
||||||
var deltaPixels = event.data.mouseStart - event.clientY;
|
var deltaPixels = event.data.mouseStart - event.clientY;
|
||||||
var height = event.data.heightStart + deltaPixels;
|
var height = event.data.heightStart + deltaPixels;
|
||||||
view.set('height', height);
|
view.set('height', height);
|
||||||
view.updateContentHeight();
|
view.setContentHeight(height);
|
||||||
view.updateBodyPadding();
|
view.updateBodyPadding();
|
||||||
|
|
||||||
localStorage.setItem('composerHeight', height);
|
localStorage.setItem('composerHeight', height);
|
||||||
|
@ -238,7 +240,11 @@ export default Ember.View.extend(Ember.Evented, {
|
||||||
},
|
},
|
||||||
|
|
||||||
focus: function() {
|
focus: function() {
|
||||||
this.$().find(':input:enabled:visible:first').focus();
|
if (this.$().is(':hidden')) { return; }
|
||||||
|
|
||||||
|
Ember.run.scheduleOnce('afterRender', this, function() {
|
||||||
|
this.$().find(':input:enabled:visible:first').focus();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
populateControls: function(controls) {
|
populateControls: function(controls) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user