diff --git a/addon/controllers/messages_base.js b/addon/controllers/messages_base.js index 1b4f20fb..5c1eed86 100644 --- a/addon/controllers/messages_base.js +++ b/addon/controllers/messages_base.js @@ -13,12 +13,18 @@ export default Ember.Controller.extend({ sortedElements: Ember.computed.sort("messagesAndVersions", "sortProperties"), isItemThread: Ember.computed.notEmpty("item"), - autoMarkAsRead: Ember.on('init', - Ember.observer('isActive', 'messages.[]', 'messages.@each.state', function() { - if (this.get('isActive')) { - Ember.run.debounce(this, this.markConversationAsRead, 1500); + autoMarkAsRead: Ember.on( + "init", + Ember.observer( + "isActive", + "messages.[]", + "messages.@each.state", + function() { + if (this.get("isActive")) { + Ember.run.debounce(this, this.markConversationAsRead, 1500); + } } - }) + ) ), disabled: Ember.computed("offer.isCancelled", "item.isDraft", function() { @@ -35,9 +41,9 @@ export default Ember.Controller.extend({ messages: Ember.computed("allMessages.[]", "offer", "item", function() { var messages = this.get("allMessages"); - messages = this.get("isItemThread") ? - messages.filterBy("itemId", this.get("item.id")) : - messages + messages = this.get("isItemThread") + ? messages.filterBy("itemId", this.get("item.id")) + : messages .filterBy("offerId", this.get("offer.id")) .filterBy("item", null); return messages.filter(m => { @@ -139,14 +145,30 @@ export default Ember.Controller.extend({ }, actions: { + setMessageContext: function(message) { + this.set("body", message.parsedText); + this.set("displayText", message.displayText); + }, + sendMessage() { // To hide soft keyboard Ember.$("textarea").trigger("blur"); this.set("inProgress", true); - var values = this.getProperties("body", "offer", "item", "isPrivate"); - values.itemId = this.get("item.id"); - values.offerId = this.get("offer.id"); + var values = this.getProperties("offer", "item", "isPrivate"); + values.body = this.get("body"); + values.body = Ember.Handlebars.Utils.escapeExpression(values.body || ""); + values.body = values.body.replace(/(\r\n|\n|\r)/gm, "
"); + values.parsedBody = this.get("displayText"); + const itemId = this.get("item.id"); + const offerId = this.get("offer.id"); + if (itemId) { + values.messageableType = "Item"; + values.messageableId = itemId; + } else { + values.messageableType = "Offer"; + values.messageableId = offerId; + } values.createdAt = new Date(); values.sender = this.store.peekRecord( "user", diff --git a/app/components/variable-height-textarea.js b/app/components/variable-height-textarea.js deleted file mode 100644 index fe532563..00000000 --- a/app/components/variable-height-textarea.js +++ /dev/null @@ -1,87 +0,0 @@ -import Ember from 'ember'; -import config from './../config/environment'; - -export default Ember.TextArea.extend({ - tagName: "textarea", - attributeBindings: ["disabled"], - disabled: false, - cordova: Ember.inject.service(), - - valueChanged: Ember.observer('value', function () { - var _this = this; - var textarea = _this.element; - - if(textarea) { - Ember.run.once(function(){ - // auto-resize height of textarea $('textarea')[0]. - if (textarea.scrollHeight < 120) { - Ember.$(textarea) - .css({'height':'auto','overflow-y':'hidden'}) - .height(textarea.scrollHeight - 15); - - var parent = _this.get('parentDiv'); - var grandParentDiv = Ember.$(`.${parent}`).closest(".review_item "); - if(grandParentDiv.length === 0) { - - // auto-move textarea by chaning margin of parentDiv - var paddingSize = config.cordova.enabled ? 5 : (textarea.scrollHeight - 40); - Ember.$(`.${parent}`) - .css({'padding-bottom': (paddingSize > 0 ? paddingSize : 0) }); - - // scrolling down to bottom of page - if(_this.get("value") !== ""){ - window.scrollTo(0, document.body.scrollHeight); - } - } - - } else { - Ember.$(textarea) - .css({'height':'auto','overflow-y':'auto'}) - .height(105); - } - }); - } - }), - - didInsertElement() { - var _this = this; - var parent = _this.get('parentDiv'); - var grandParentDiv = Ember.$(`.${parent}`).closest(".review_item "); - - // Apply only in Donor Cordova App. - if(grandParentDiv.length === 0 && config.cordova.enabled) { - - var msgTextbox = Ember.$(Ember.$(_this.element).closest(".message-textbar")); - - Ember.run.scheduleOnce('afterRender', this, function(){ - - var isIOS = _this.get("cordova").isIOS(); - - var height = isIOS ? 55 : 30; - Ember.$(".message-footer").height(height); - - Ember.$(_this.element).focus(function(){ - - if(isIOS) { - if(document.body.scrollHeight === Ember.$(window).height()) { - Ember.$(".message-footer").addClass("message_footer_small_page"); - } else { - Ember.$(".message-footer").removeClass("message_footer_small_page"); - } - msgTextbox.css({'position': 'relative'}); - } else { - var positionVal = document.body.scrollHeight === Ember.$(window).height() ? 'fixed' : 'relative'; - } - - window.scrollTo(0, document.body.scrollHeight); - }); - - Ember.$(_this.element).blur(function(){ - msgTextbox.css({'position':'fixed'}); - }); - }); - - } - } - -}); diff --git a/app/helpers/apply-line-break.js b/app/helpers/apply-line-break.js index d19d7634..a3f0089f 100644 --- a/app/helpers/apply-line-break.js +++ b/app/helpers/apply-line-break.js @@ -1,12 +1,7 @@ import Ember from "ember"; export default Ember.Helper.helper(function(value) { - var text; - if(/<[a-z][\s\S]*>/i.test(value)) { - text = value; - } else { - text = Ember.Handlebars.Utils.escapeExpression(value); - text = text.replace(/(\r\n|\n|\r)/gm, '
'); - } - return new Ember.Handlebars.SafeString(text); + value = new Ember.Handlebars.SafeString(value[0] || "").string; + value = value.replace(/(\r\n|\n|\r)/gm, "
"); + return new Ember.String.htmlSafe(value); }); diff --git a/app/models/message.js b/app/models/message.js index 55ea7cc0..d946dded 100644 --- a/app/models/message.js +++ b/app/models/message.js @@ -21,6 +21,34 @@ export default DS.Model.extend({ var session = getOwner(this).lookup("service:session"); return this.get("sender.id") === session.get("currentUser.id"); }), + messageableType: attr("string"), + messageableId: attr("string"), + lookup: attr("string"), + parsedBody: Ember.computed("body", function() { + let body = this.get("body"); + let lookup = this.get("lookup"); + lookup = JSON.parse(lookup); + Object.keys(lookup).forEach(key => { + body = body.replace( + new RegExp(`\\[:${key}\\]`, "g"), + `@${lookup[key].display_name}` + ); + }); + return body; + }), + + plainBody: Ember.computed("body", function() { + let body = this.get("body"); + let lookup = this.get("lookup"); + lookup = JSON.parse(lookup); + Object.keys(lookup).forEach(key => { + body = body.replace( + new RegExp(`\\[:${key}\\]`, "g"), + lookup[key].display_name + ); + }); + return body; + }), isMessage: Ember.computed("this", function() { return true; diff --git a/app/serializers/application.js b/app/serializers/application.js index d70ee6a2..734eb8e9 100644 --- a/app/serializers/application.js +++ b/app/serializers/application.js @@ -1,14 +1,49 @@ -import { ActiveModelSerializer } from 'active-model-adapter'; +import { ActiveModelSerializer } from "active-model-adapter"; +import _ from "npm:lodash"; // Polymorphic associations are not supported in ember-data beta version: // refer: https://github.com/emberjs/data/issues/1574 -export default ActiveModelSerializer.extend({ +function normalize(payload) { + const key = + (payload.hasOwnProperty("messages") && "messages") || + (payload.hasOwnProperty("message") && "message"); + if (key) { + const messages = Array.isArray(payload[key]) + ? payload[key] + : Array(payload[key]); + messages.forEach(m => { + m[`${m.messageable_type.toLowerCase()}`] = m.messageable_id; + }); + } + + const messages = _.flatten([payload.messages, payload.message]).filter( + _.identity + ); + + _.each(messages, m => { + m[`${m.messageable_type.toLowerCase()}`] = m.messageable_id; + if (typeof m.lookup === "object") { + m.lookup = JSON.stringify(m.lookup); + } + }); +} + +export default ActiveModelSerializer.extend({ keyForAttribute: function(attr, method) { if (attr === "addressable") { return "addressable_id"; } return this._super(attr, method); + }, + normalizeResponse(store, primaryModelClass, payload, id, requestType) { + normalize(payload); + return this._super(...arguments); + }, + + pushPayload(store, payload) { + normalize(payload); + return this._super(...arguments); } }); diff --git a/app/styles/templates/_message_template.scss b/app/styles/templates/_message_template.scss index 3b7b6f22..131f7bd5 100644 --- a/app/styles/templates/_message_template.scss +++ b/app/styles/templates/_message_template.scss @@ -1,5 +1,6 @@ .message-textbar { padding-top: 0rem !important; + width: 50rem; } .message_bubble_box { @@ -74,6 +75,7 @@ } .message-section { + .icon-empty-items { color: $body-font-color; } diff --git a/app/styles/templates/components/_message_box.scss b/app/styles/templates/components/_message_box.scss index 2ccbef33..042d8803 100644 --- a/app/styles/templates/components/_message_box.scss +++ b/app/styles/templates/components/_message_box.scss @@ -2,6 +2,10 @@ display: block; } +.tribute-container { + margin-top: 1rem; +} + #messageBox { display: block; opacity: 1; diff --git a/app/templates/message_template.hbs b/app/templates/message_template.hbs index c05f8b1e..641e3c13 100644 --- a/app/templates/message_template.hbs +++ b/app/templates/message_template.hbs @@ -21,7 +21,7 @@ {{display-datetime message.createdAt format="HH:mm"}} - {{{apply-line-break message.body}}} + {{{apply-line-break message.parsedBody}}} {{else}}
@@ -35,8 +35,9 @@
-