diff --git a/services/web/TpdsWorker.coffee b/services/web/TpdsWorker.coffee index 5ffc1e303d..cfc5dcd875 100644 --- a/services/web/TpdsWorker.coffee +++ b/services/web/TpdsWorker.coffee @@ -33,26 +33,50 @@ processingFuncs = else callback() - pipeStreamFrom: (options, callback)-> + pipeStreamFrom: (options, _callback)-> + callback = (args...) -> + _callback(args...) + _callback = () -> + if options.filePath == "/droppy/main.tex" request options.streamOrigin, (err,res, body)-> logger.log options:options, body:body + origin = request(options.streamOrigin) + + cancelled = false + gotResponse = false + origin.on 'response', (res) -> + return if cancelled + gotResponse = true + if 200 <= res.statusCode < 300 + dest = request(options) + origin.pipe(dest) + + dest.on "error", (err)-> + logger.error err:err, options:options, "something went wrong in pipeStreamFrom dest" + callback(err) + + dest.on 'end', callback + else + error = new Error("received non-success status code: #{res.statusCode}") + logger.error err: error, options: options, "something went wrong connecting to origin" + callback(error) + origin.on 'error', (err)-> + return if cancelled + gotResponse = true logger.error err:err, options:options, "something went wrong in pipeStreamFrom origin" - if err? - callback(err) - else - callback() - dest = request(options) - origin.pipe(dest) - dest.on "error", (err)-> - logger.error err:err, options:options, "something went wrong in pipeStreamFrom dest" - if err? - callback(err) - else - callback() - dest.on 'end', callback + callback(err) + + setTimeout () -> + return if gotResponse + cancelled = true + error = new Error("timeout") + logger.error err: error, options: options, "timeout" + callback(error) + , 2000 + workerRegistration = (groupKey, method, options, callback)-> diff --git a/services/web/app/views/layout.jade b/services/web/app/views/layout.jade index 74ac1276cd..a849944252 100644 --- a/services/web/app/views/layout.jade +++ b/services/web/app/views/layout.jade @@ -28,7 +28,7 @@ html(itemscope, itemtype='http://schema.org/Product') ga('send', 'pageview'); - else script(type='text/javascript') - window.ga = function() {}; + window.ga = function() { console.log("Sending to GA", arguments) }; script window.csrfToken = "#{csrfToken}"; diff --git a/services/web/app/views/templates.jade b/services/web/app/views/templates.jade index cb582e7c42..aaccdbde8a 100644 --- a/services/web/app/views/templates.jade +++ b/services/web/app/views/templates.jade @@ -434,6 +434,15 @@ i.icon-remove .change-list-area .track-changes-diff + .track-changes-upgrade-popup(style="display: none;") + .message.show-when-owner + p You need to upgrade your plan to use the History feature. + button.btn.btn-primary.start-free-trial Start free trial + .message.show-when-not-owner + p Please ask the project owner to upgrade to use the History feature. + .track-changes-upgrade-control(style="display: none;") + .message History is not yet enabled for this project. + button.btn.btn-primary.btn-large.upgrade Enable History script(type='text/template')#trackChangesDiffTemplate .track-changes-diff-toolbar.btn-toolbar @@ -463,6 +472,12 @@ ul.change-list.nav.nav-pills.nav-stacked li.loading-changes Loading... li.empty-message You haven't made any changes yet! + li.track-changes-upgrade-oneweek(style="display: none;") + p We only store one week of changes for free accounts. + p.show-when-owner Upgrade for an unlimited history. + p.show-when-owner + button.btn.btn-primary.start-free-trial Start free trial + p.show-when-not-owner Please ask the project owner to upgrade. script(type='text/template')#hotKeysListTemplate .hotkeys diff --git a/services/web/public/coffee/account/AccountManager.coffee b/services/web/public/coffee/account/AccountManager.coffee index 2120ce35bc..5329d36de3 100644 --- a/services/web/public/coffee/account/AccountManager.coffee +++ b/services/web/public/coffee/account/AccountManager.coffee @@ -25,8 +25,19 @@ define [ },{ text: "Enter Billing Information" class: "btn-primary" - callback: () -> - window.location = "/user/subscription/new?planCode=student_free_trial" + callback: () => + options.onUpgrade?() + @gotoSubscriptionsPage() + }] + + gotoSubscriptionsPage: () -> + window.open("/user/subscription/new?planCode=student_free_trial") + Modal.createModal + title: "Please refresh" + message: "Please refresh this page after starting your free trial. This will make sure all of your features are enabled." + buttons: [{ + text: "OK" + class: "" }] showUpgradeDialog: (ide, options = {}) -> diff --git a/services/web/public/coffee/analytics/AnalyticsManager.coffee b/services/web/public/coffee/analytics/AnalyticsManager.coffee index 9b2bc49702..e06cf264c3 100644 --- a/services/web/public/coffee/analytics/AnalyticsManager.coffee +++ b/services/web/public/coffee/analytics/AnalyticsManager.coffee @@ -1,4 +1,6 @@ -define () -> +define [ + "libs/md5" +], () -> class AnalyticsManager constructor: (@ide) -> @ide.editor.on "update:doc", () => @@ -14,3 +16,18 @@ define () -> ga('send', 'event', 'editor-interaction', 'single-compile') if @compileCount == 3 ga('send', 'event', 'editor-interaction', 'multi-compile') + + getABTestBucket: (test_name, buckets = []) -> + hash = CryptoJS.MD5("#{@ide.user.get("id")}:#{test_name}") + bucketIndex = parseInt(hash.toString().slice(0,2), 16) % buckets.length + return buckets[bucketIndex] + + startABTest: (test_name, buckets = []) -> + value = @getABTestBucket(test_name, buckets) + ga('send', 'event', 'ab_tests', test_name, "viewed-#{value}") + return value + + endABTest: (test_name, buckets = []) -> + value = @getABTestBucket(test_name, buckets) + ga('send', 'event', 'ab_tests', test_name, "converted-#{value}") + return value \ No newline at end of file diff --git a/services/web/public/coffee/pdf/CompiledView.coffee b/services/web/public/coffee/pdf/CompiledView.coffee index cae6cbb948..9c3684aa18 100644 --- a/services/web/public/coffee/pdf/CompiledView.coffee +++ b/services/web/public/coffee/pdf/CompiledView.coffee @@ -90,7 +90,7 @@ define [ logButtonHtml = "Logs" if compileErrors? - for error in compileErrors.all + for error in compileErrors.errors.concat(compileErrors.warnings).concat(compileErrors.typesetting) errorView = new LatexErrorView(@options.manager.ide, error) errorView.render() @errorViews.push(errorView) diff --git a/services/web/public/coffee/project-members/ProjectMembersManager.coffee b/services/web/public/coffee/project-members/ProjectMembersManager.coffee index 82ff4bfdcc..d597345777 100644 --- a/services/web/public/coffee/project-members/ProjectMembersManager.coffee +++ b/services/web/public/coffee/project-members/ProjectMembersManager.coffee @@ -76,17 +76,18 @@ define [ @ide.socket.emit "removeUserFromProject", member.id addMember: (email, privileges) -> + console.log "Adding member", email @ide.socket.emit "addUserToProject", email, privileges, (error, added) => if error? @ide.showGenericServerErrorMessage() return if !added + console.log "got response", error, added ga('send', 'event', 'subscription-funnel', 'askToUpgrade', "projectMemebrs") AccountManager.askToUpgrade @ide, why: "to add additional collaborators" onUpgrade: () => ga('send', 'event', 'subscription-funnel', 'upgraded-free-trial', "projectMemebrs") - @addMember(email, privileges) afterMemberRemoved: (memberId) -> for member in @members.models diff --git a/services/web/public/coffee/track-changes/ChangeListView.coffee b/services/web/public/coffee/track-changes/ChangeListView.coffee index 80a0fb0915..1212faa1fe 100644 --- a/services/web/public/coffee/track-changes/ChangeListView.coffee +++ b/services/web/public/coffee/track-changes/ChangeListView.coffee @@ -40,6 +40,9 @@ define [ overflow: "scroll" this + remove: () -> + @undelegateEvents() + addItem: (model) -> index = @collection.indexOf(model) previousModel = @collection.models[index - 1] @@ -208,6 +211,17 @@ define [ else @$el.addClass("first-in-day") + @$(".change-selector-from").tooltip({ + title: "Show back to this change", + placement: "left", + animation: false + }) + @$(".change-selector-to").tooltip({ + title: "Show up to this change", + placement: "left", + animation: false + }) + return this onClick: (e) -> diff --git a/services/web/public/coffee/track-changes/TrackChangesManager.coffee b/services/web/public/coffee/track-changes/TrackChangesManager.coffee index ab27d883a1..393163c781 100644 --- a/services/web/public/coffee/track-changes/TrackChangesManager.coffee +++ b/services/web/public/coffee/track-changes/TrackChangesManager.coffee @@ -3,10 +3,11 @@ define [ "track-changes/models/Diff" "track-changes/ChangeListView" "track-changes/DiffView" + "account/AccountManager" "utils/Modal" "models/Doc" "moment" -], (ChangeList, Diff, ChangeListView, DiffView, Modal, Doc, moment) -> +], (ChangeList, Diff, ChangeListView, DiffView, AccountManager, Modal, Doc, moment) -> class TrackChangesManager template: $("#trackChangesPanelTemplate").html() @@ -43,12 +44,15 @@ define [ @doc_id = doc_id @updateDiff() + AB_BUCKETS: ["control", "one-week", "pop-up"] show: () -> @changes = new ChangeList([], project_id: @project_id, ide: @ide) + if @changeListView? + @changeListView.remove() @changeListView = new ChangeListView( - collection : @changes, - el : @$el.find(".change-list-area") + el: @$el.find(".change-list-area") + collection: @changes ) @changeListView.render() @changeListView.loadUntilFull (error) => @@ -57,6 +61,8 @@ define [ @changeListView.on "change_diff", (fromIndex, toIndex) => @selectDocAndUpdateDiff(fromIndex, toIndex) + @showUpgradeView() + if @diffView? @diffView.remove() @@ -65,6 +71,26 @@ define [ @ide.fileViewManager.disable() @enable() + showUpgradeView: () -> + @upgradeType ||= @ide.analyticsManager.startABTest('track-changes-upgrade', @AB_BUCKETS) + @$el.find("button.upgrade").off "click.track-changes" + @$el.find("button.start-free-trial").off "click.track-changes" + @$el.find("button.upgrade").on "click.track-changes", () => @askToUpgrade() + @$el.find("button.start-free-trial").on "click.track-changes", () => @gotoFreeTrial() + + if !@ide.project.get("features").versioning + if @upgradeType == "pop-up" + @$el.find(".track-changes-upgrade-popup").show() + else if @upgradeType == "control" + @$el.find(".track-changes-upgrade-control").show() + else if @upgradeType == "one-week" + @$el.find(".track-changes-upgrade-oneweek").show() + + if @ide.project.get("owner") == @ide.user + @$el.find(".show-when-not-owner").hide() + else + @$el.find(".show-when-owner").hide() + hide: () -> @ide.editor.enable() @ide.fileViewManager.enable() @@ -191,4 +217,17 @@ define [ disable: () -> @enabled = false + askToUpgrade: () -> + ga('send', 'event', 'subscription-funnel', 'askToUpgrade', "trackchanges") + ga('send', 'event', 'ab_tests', 'track-changes-upgrade', "prompted-to-upgrade-#{@upgradeType}") + AccountManager.askToUpgrade @ide, + onUpgrade: () => + @ide.analyticsManager.endABTest('track-changes-upgrade', @AB_BUCKETS) + ga('send', 'event', 'subscription-funnel', 'upgraded-free-trial', "trackchanges") + + gotoFreeTrial: () -> + AccountManager.gotoSubscriptionsPage() + @ide.analyticsManager.endABTest('track-changes-upgrade', @AB_BUCKETS) + ga('send', 'event', 'subscription-funnel', 'upgraded-free-trial', "trackchanges") + return TrackChangesManager diff --git a/services/web/public/stylesheets/less/trackchanges.less b/services/web/public/stylesheets/less/trackchanges.less index b27a81802d..f9f12bbcc8 100644 --- a/services/web/public/stylesheets/less/trackchanges.less +++ b/services/web/public/stylesheets/less/trackchanges.less @@ -79,6 +79,39 @@ } } + .track-changes-upgrade-control, .track-changes-upgrade-popup { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + z-index: 100; + } + + .track-changes-upgrade-popup { + background-color: rgba(128,128,128,0.4); + .message { + margin: auto; + margin-top: 200px; + padding: 10px 10px 14px 10px; + width: 400px; + font-weight: bold; + text-align: center; + background-color: white; + .border-radius(8px); + } + } + + .track-changes-upgrade-control { + background-color: #eeeeee; + text-align: center; + .message { + font-size: 18px; + margin: 12px; + margin-top: 36px; + } + } + .deleted-change-background, .deleted-change-foreground, .inserted-change-background, @@ -193,6 +226,10 @@ } li.loading-changes, li.empty-message { padding: 6px; + cursor: default; + &:hover { + background-color: inherit; + } } li.selected-change { background-color: #eaeaea; @@ -242,6 +279,11 @@ } } } + li.track-changes-upgrade-oneweek { + padding: 15px; + background-color: rgb(255, 251, 210); + cursor: default; + } } ul.change-list.hover-state { li { @@ -256,6 +298,7 @@ li.hover-selected { .change-selectors { .range { + top: 0; background-color: #999; } }