Merge pull request #651 from ZogStriP/change-title-background-when-composer-requirements-are-not-met

Change Title background to red when requirements are not met
This commit is contained in:
Sam 2013-04-07 15:11:10 -07:00
commit 3ba0bf6d5d
7 changed files with 104 additions and 76 deletions

View File

@ -18,8 +18,8 @@ Discourse.ComposerController = Discourse.Controller.extend({
this.get('content').importQuote();
},
resetDraftStatus: function() {
this.get('content').resetDraftStatus();
updateDraftStatus: function() {
this.get('content').updateDraftStatus();
},
appendText: function(text) {

View File

@ -31,43 +31,43 @@ Discourse.Composer = Discourse.Model.extend({
this.set('archetypeId', Discourse.get('site.default_archetype'));
},
creatingTopic: (function() {
creatingTopic: function() {
return this.get('action') === CREATE_TOPIC;
}).property('action'),
}.property('action'),
creatingPrivateMessage: (function() {
creatingPrivateMessage: function() {
return this.get('action') === PRIVATE_MESSAGE;
}).property('action'),
}.property('action'),
editingPost: (function() {
editingPost: function() {
return this.get('action') === EDIT;
}).property('action'),
}.property('action'),
replyingToTopic: (function() {
replyingToTopic: function() {
return this.get('action') === REPLY;
}).property('action'),
}.property('action'),
viewOpen: (function() {
viewOpen: function() {
return this.get('composeState') === OPEN;
}).property('composeState'),
}.property('composeState'),
archetype: (function() {
archetype: function() {
return this.get('archetypes').findProperty('id', this.get('archetypeId'));
}).property('archetypeId'),
}.property('archetypeId'),
archetypeChanged: (function() {
archetypeChanged: function() {
return this.set('metaData', Em.Object.create());
}).observes('archetype'),
}.observes('archetype'),
editTitle: (function() {
editTitle: function() {
if (this.get('creatingTopic') || this.get('creatingPrivateMessage')) return true;
if (this.get('editingPost') && this.get('post.post_number') === 1) return true;
return false;
}).property('editingPost', 'creatingTopic', 'post.post_number'),
}.property('editingPost', 'creatingTopic', 'post.post_number'),
togglePreview: function() {
this.toggleProperty('showPreview');
return Discourse.KeyValueStore.set({ key: 'showPreview', value: this.get('showPreview') });
Discourse.KeyValueStore.set({ key: 'showPreview', value: this.get('showPreview') });
},
// Import a quote from the post
@ -97,7 +97,7 @@ Discourse.Composer = Discourse.Model.extend({
},
// Determine the appropriate title for this action
actionTitle: (function() {
actionTitle: function() {
var topic = this.get('topic');
var postLink, topicLink;
@ -128,28 +128,26 @@ Discourse.Composer = Discourse.Model.extend({
}
switch (this.get('action')) {
case PRIVATE_MESSAGE:
return Em.String.i18n('topic.private_message');
case CREATE_TOPIC:
return Em.String.i18n('topic.create_long');
case PRIVATE_MESSAGE: return Em.String.i18n('topic.private_message');
case CREATE_TOPIC: return Em.String.i18n('topic.create_long');
case REPLY:
case EDIT:
if (postDescription) return postDescription;
if (topic) return Em.String.i18n('post.reply_topic', { link: topicLink });
}
}).property('action', 'post', 'topic', 'topic.title'),
}.property('action', 'post', 'topic', 'topic.title'),
toggleText: (function() {
toggleText: function() {
return this.get('showPreview') ? Em.String.i18n('composer.hide_preview') : Em.String.i18n('composer.show_preview');
}).property('showPreview'),
}.property('showPreview'),
hidePreview: (function() {
hidePreview: function() {
return !this.get('showPreview');
}).property('showPreview'),
}.property('showPreview'),
// Whether to disable the post button
cantSubmitPost: (function() {
cantSubmitPost: function() {
// Can't submit while loading
if (this.get('loading')) return true;
@ -167,29 +165,22 @@ Discourse.Composer = Discourse.Model.extend({
if (this.get('replyLength') < Discourse.SiteSettings.min_post_length) return true;
return false;
}).property('loading', 'editTitle', 'titleLength', 'targetUsernames', 'replyLength'),
}.property('loading', 'editTitle', 'titleLength', 'targetUsernames', 'replyLength'),
// The text for the save button
saveText: (function() {
saveText: function() {
switch (this.get('action')) {
case EDIT:
return Em.String.i18n('composer.save_edit');
case REPLY:
return Em.String.i18n('composer.reply');
case CREATE_TOPIC:
return Em.String.i18n('composer.create_topic');
case PRIVATE_MESSAGE:
return Em.String.i18n('composer.create_pm');
case EDIT: return Em.String.i18n('composer.save_edit');
case REPLY: return Em.String.i18n('composer.reply');
case CREATE_TOPIC: return Em.String.i18n('composer.create_topic');
case PRIVATE_MESSAGE: return Em.String.i18n('composer.create_pm');
}
}).property('action'),
}.property('action'),
hasMetaData: (function() {
hasMetaData: function() {
var metaData = this.get('metaData');
if (!this.get('metaData')) {
return false;
}
return Em.empty(Em.keys(this.get('metaData')));
}).property('metaData'),
return metaData ? Em.empty(Em.keys(this.get('metaData'))) : false;
}.property('metaData'),
wouldLoseChanges: function() {
return this.get('reply') !== this.get('originalText');
@ -277,8 +268,7 @@ Discourse.Composer = Discourse.Model.extend({
},
save: function(opts) {
if (this.get('editingPost')) return this.editPost(opts);
return this.createPost(opts);
return this.get('editingPost') ? this.editPost(opts) : this.createPost(opts);
},
// When you edit a post
@ -458,31 +448,57 @@ Discourse.Composer = Discourse.Model.extend({
this.set('draftStatus', Em.String.i18n('composer.saving_draft_tip'));
var composer = this;
return Discourse.Draft.save(this.get('draftKey'), this.get('draftSequence'), data).then((function() {
composer.set('draftStatus', Em.String.i18n('composer.saved_draft_tip'));
}), (function() {
composer.set('draftStatus', Em.String.i18n('composer.drafts_offline'));
}));
// try to save the draft
return Discourse.Draft.save(this.get('draftKey'), this.get('draftSequence'), data)
.then(function() {
composer.set('draftStatus', Em.String.i18n('composer.saved_draft_tip'));
}, function() {
composer.set('draftStatus', Em.String.i18n('composer.drafts_offline'));
});
},
resetDraftStatus: (function() {
updateDraftStatus: function() {
var $title = $('#reply-title'),
$reply = $('#wmd-input');
// 'title' is focused
if ($('#reply-title').is(':focus')) {
var titleDiff = Discourse.SiteSettings.min_topic_title_length - this.get('titleLength');
if ($title.is(':focus')) {
var titleDiff = this.get('missingTitleCharacters');
if (titleDiff > 0) {
return this.set('draftStatus', Em.String.i18n('composer.min_length.need_more_for_title', { n: titleDiff }));
}
// 'reply' is focused
} else if ($('#wmd-input').is(':focus')) {
var replyDiff = Discourse.SiteSettings.min_post_length - this.get('replyLength');
} else if ($reply.is(':focus')) {
var replyDiff = this.get('missingReplyCharacters');
if (replyDiff > 0) {
return this.set('draftStatus', Em.String.i18n('composer.min_length.need_more_for_reply', { n: replyDiff }));
}
}
// hide the counters if the currently focused text field is OK
this.set('draftStatus', null);
}).observes('replyLength', 'titleLength'),
}.observes('missingTitleCharacters', 'missingReplyCharacters'),
/**
Number of missing characters in the title until valid.
@property missingTitleCharacters
**/
missingTitleCharacters: function() {
return Discourse.SiteSettings.min_topic_title_length - this.get('titleLength');
}.property('titleLength'),
/**
Number of missing characters in the reply until valid.
@property missingReplyCharacters
**/
missingReplyCharacters: function() {
return Discourse.SiteSettings.min_post_length - this.get('replyLength');
}.property('replyLength'),
/**
Computes the length of the title minus non-significant whitespaces

View File

@ -50,8 +50,6 @@ Discourse.TopicList = Discourse.Model.extend({
unseen: true,
highlight: true
});
console.log(newTopic);
this.get('inserted').unshiftObject(newTopic);
}

View File

@ -17,10 +17,7 @@ Discourse.PreferencesRoute = Discourse.RestrictedUserRoute.extend({
},
setupController: function(controller) {
console.log('prefereces');
controller.set('content', this.controllerFor('user').get('content'));
}
});

View File

@ -50,7 +50,7 @@
</div>
{{#if Discourse.currentUser}}
<a href="#" {{action togglePreview target="controller"}} class='toggle-preview'>{{{content.toggleText}}}</a>
<div class='saving-draft'></div>
<div class='draft-status'></div>
{{#if view.loadingImage}}
<div id="image-uploading">
{{i18n image_selector.uploading_image}} {{view.uploadProgress}}% <a id="cancel-image-upload">{{i18n cancel}}</a>

View File

@ -27,7 +27,7 @@ Discourse.ComposerView = Discourse.View.extend({
}.property('content.composeState'),
draftStatus: function() {
this.$('.saving-draft').text(this.get('content.draftStatus') || "");
this.$('.draft-status').text(this.get('content.draftStatus') || "");
}.observes('content.draftStatus'),
// Disable fields when we're loading
@ -40,8 +40,7 @@ Discourse.ComposerView = Discourse.View.extend({
}.observes('loading'),
postMade: function() {
if (this.present('controller.createdPost')) return 'created-post';
return null;
return this.present('controller.createdPost') ? 'created-post' : null;
}.property('content.createdPost'),
observeReplyChanges: function() {
@ -87,7 +86,7 @@ Discourse.ComposerView = Discourse.View.extend({
focusIn: function() {
var controller = this.get('controller');
if(controller) controller.resetDraftStatus();
if (controller) controller.updateDraftStatus();
},
resize: function() {
@ -123,9 +122,9 @@ Discourse.ComposerView = Discourse.View.extend({
},
didInsertElement: function() {
var replyControl = $('#reply-control');
replyControl.DivResizer({ resize: this.resize, onDrag: this.movePanels });
Discourse.TransitionHelper.after(replyControl, this.resize);
var $replyControl = $('#reply-control');
$replyControl.DivResizer({ resize: this.resize, onDrag: this.movePanels });
Discourse.TransitionHelper.after($replyControl, this.resize);
},
click: function() {
@ -260,11 +259,26 @@ Discourse.ComposerView = Discourse.View.extend({
return true;
});
$('#reply-title').keyup(function() {
var $replyTitle = $('#reply-title');
$replyTitle.keyup(function() {
saveDraft();
// removes the red background once the requirements are met
if (_this.get('controller.content.missingTitleCharacters') <= 0) {
$replyTitle.removeClass("requirements-not-met");
}
return true;
});
// when the title field loses the focus...
$replyTitle.blur(function(){
// ...and the requirements are not met (ie. the minimum number of characters)
if (_this.get('controller.content.missingTitleCharacters') > 0) {
// then, "redify" the background
$replyTitle.toggleClass("requirements-not-met", true);
}
});
// In case it's still bound somehow
$uploadTarget.fileupload('destroy');
$uploadTarget.off();

View File

@ -55,7 +55,10 @@
}
#reply-control {
.toggle-preview, .saving-draft, #image-uploading {
.requirements-not-met {
background-color: rgba(255, 0, 0, 0.12);
}
.toggle-preview, .draft-status, #image-uploading {
position: absolute;
bottom: -31px;
margin-top: 0px;
@ -69,7 +72,7 @@
font-size: 12px;
color: darken($gray, 40);
}
.saving-draft {
.draft-status {
right: 51%;
color: lighten($black, 60);
}