From 7c9797c7066ffc3317a10bc041925343f609d353 Mon Sep 17 00:00:00 2001 From: Evan Morikawa Date: Fri, 13 Mar 2015 15:55:52 -0400 Subject: [PATCH] feat(composer): don't prompt for attachment if in quoted text Test Plan: edgehill --test Reviewers: bengotow Reviewed By: bengotow Differential Revision: https://review.inboxapp.com/D1290 --- .../composer/lib/composer-view.cjsx | 15 +++++++++++++-- .../composer/spec/inbox-composer-view-spec.cjsx | 4 +++- .../message-list/lib/email-frame.cjsx | 2 +- .../message-list/lib/message-item.cjsx | 2 +- spec-inbox/utils-spec.coffee | 6 +++--- src/flux/models/utils.coffee | 17 +++++++++++------ 6 files changed, 32 insertions(+), 14 deletions(-) diff --git a/internal_packages/composer/lib/composer-view.cjsx b/internal_packages/composer/lib/composer-view.cjsx index c292bc45c..69befdc29 100644 --- a/internal_packages/composer/lib/composer-view.cjsx +++ b/internal_packages/composer/lib/composer-view.cjsx @@ -1,7 +1,8 @@ React = require 'react' _ = require 'underscore-plus' -{Actions, +{Utils, + Actions, UndoManager, DraftStore, FileUploadStore, @@ -306,7 +307,7 @@ ComposerView = React.createClass warnings = [] if draft.subject.length is 0 warnings.push('without a subject line') - if (draft.files ? []).length is 0 and draft.body.toLowerCase().indexOf('attach') >= 0 + if (draft.files ? []).length is 0 and @_hasAttachment(draft.body) warnings.push('without an attachment') if warnings.length > 0 and not options.force @@ -322,6 +323,16 @@ ComposerView = React.createClass Actions.sendDraft(@props.localId) + _hasAttachment: (body) -> + body = body.toLowerCase().trim() + attachIndex = body.indexOf("attach") + if attachIndex >= 0 + quotedTextIndex = Utils.quotedTextIndex(body) + if quotedTextIndex >= 0 + return (attachIndex < quotedTextIndex) + else return true + else return false + _destroyDraft: -> Actions.destroyDraft(@props.localId) diff --git a/internal_packages/composer/spec/inbox-composer-view-spec.cjsx b/internal_packages/composer/spec/inbox-composer-view-spec.cjsx index 9bf15a269..d9641ca87 100644 --- a/internal_packages/composer/spec/inbox-composer-view-spec.cjsx +++ b/internal_packages/composer/spec/inbox-composer-view-spec.cjsx @@ -216,7 +216,7 @@ describe "populated composer", -> expect(dialogArgs.buttons).toEqual ['Cancel', 'Send Anyway'] noWarn = (body) -> - useDraft.call @, subject: "Subject", to: [u1], body: "Sup yo" + useDraft.call @, subject: "Subject", to: [u1], body: body makeComposer.call(@); @composer._sendDraft() expect(Actions.sendDraft).toHaveBeenCalled() expect(@dialog.showMessageBox).not.toHaveBeenCalled() @@ -224,9 +224,11 @@ describe "populated composer", -> it "warns", -> warn.call(@, "Check out the attached file") it "warns", -> warn.call(@, "I've added an attachment") it "warns", -> warn.call(@, "I'm going to attach the file") + it "warns", -> warn.call(@, "Hey attach me
sup
") it "doesn't warn", -> noWarn.call(@, "sup yo") it "doesn't warn", -> noWarn.call(@, "Look at the file") + it "doesn't warn", -> noWarn.call(@, "Hey there
attach
") it "doesn't show a warning if you've attached a file", -> useDraft.call @, diff --git a/internal_packages/message-list/lib/email-frame.cjsx b/internal_packages/message-list/lib/email-frame.cjsx index f34d94eec..6f65f1b31 100644 --- a/internal_packages/message-list/lib/email-frame.cjsx +++ b/internal_packages/message-list/lib/email-frame.cjsx @@ -170,7 +170,7 @@ EmailFrame = React.createClass if @props.showQuotedText email else - Utils.withoutQuotedText(email) + Utils.stripQuotedText(email) _onClick: (e) -> e.preventDefault() diff --git a/internal_packages/message-list/lib/message-item.cjsx b/internal_packages/message-list/lib/message-item.cjsx index f44773476..abca776a0 100644 --- a/internal_packages/message-list/lib/message-item.cjsx +++ b/internal_packages/message-list/lib/message-item.cjsx @@ -78,7 +78,7 @@ MessageItem = React.createClass _quotedTextClasses: -> React.addons.classSet "quoted-text-control": true - 'no-quoted-text': !Utils.containsQuotedText(@props.message.body) + 'no-quoted-text': (Utils.quotedTextIndex(@props.message.body).length is 0) 'show-quoted-text': @state.showQuotedText _renderMessageActionsInline: -> diff --git a/spec-inbox/utils-spec.coffee b/spec-inbox/utils-spec.coffee index 910687c7e..701a44c85 100644 --- a/spec-inbox/utils-spec.coffee +++ b/spec-inbox/utils-spec.coffee @@ -3,15 +3,15 @@ Utils = require '../src/flux/models/utils' describe "quoted text", -> it "should be correct for a google calendar invite", -> body = """

Recruiting Email Weekly Blastoff

Turn those cold leads into phone screens! You can make this go super fast by queueing up your drafts before hand and just sending them out during this time.
When
Fri Feb 27, 2015 5pm – 5:30pm Pacific Time
Calendar
Ben Gotow
Who
Michael Grinich - organizer
Kartik Talwar
team
Rob McQueen
Evan Morikawa
Christine Spang
Karim Hamidou
nilas.com@allusers.d.calendar.google.com
Makala Keys
Eben Freeman
Jennie Lees
Ben Gotow
Kavya Joshi

Going?    - -     

Invitation from Google Calendar

You are receiving this email at the account ben@nilas.com because you are subscribed for invitations on calendar Ben Gotow.

To stop receiving these emails, please log in to https://www.google.com/calendar/ and change your notification settings for this calendar.

""" - expect(Utils.containsQuotedText(body)).toBe(false) + expect(Utils.quotedTextIndex(body)).toBe(-1) it "should be correct when email contains

tags", -> body = """

Hi Ben

Please goto the Workspaces Console > Directories.

Then, select the Directory and "Deregister".&nbsp; After you deregister the Directory from Workspaces, you should then be able to goto Directory Services and remove the Directory.

Ben

""" - expect(Utils.containsQuotedText(body)).toBe(false) - expect(Utils.withoutQuotedText(body)).toBe(body) + expect(Utils.quotedTextIndex(body)).toBe(-1) + expect(Utils.stripQuotedText(body)).toBe(body) describe "subjectWithPrefix", -> it "should replace an existing Re:", -> diff --git a/src/flux/models/utils.coffee b/src/flux/models/utils.coffee index 21435a627..b15f6bbe8 100644 --- a/src/flux/models/utils.coffee +++ b/src/flux/models/utils.coffee @@ -103,7 +103,9 @@ Utils = else return "#{prefix} #{subject}" - containsQuotedText: (html) -> + # A wrapper around String#search(). Returns the index of the first match + # or returns -1 if there are no matches + quotedTextIndex: (html) -> # I know this is gross - one day we'll replace it with a nice system. return false unless html @@ -114,12 +116,15 @@ Utils = /[\n|>]On .* wrote:[\n|<]/, #On ... wrote: on it's own line /.gmail_quote/ # gmail quote class class ] + for regex in regexs - return true if html.match(regex) - return false - - withoutQuotedText: (html) -> - return html unless Utils.containsQuotedText(html) + foundIndex = html.search(regex) + if foundIndex >= 0 then return foundIndex + + return -1 + + stripQuotedText: (html) -> + return html if Utils.quotedTextIndex(html) is -1 # Split the email into lines and remove lines that begin with > or > lines = html.split(/(\n|]*>)/)