From ee1dc427ce456a8abd726b09d62bacbdae916320 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Sun, 10 Jan 2021 23:44:49 -0600 Subject: [PATCH] build --- admin/Gemfile | 2 +- admin/Gemfile.lock | 9 ++ admin/app/admin/jam_ruby_users.rb | 35 +++--- admin/app/admin/subscription_override.rb | 2 +- ruby/lib/jam_ruby/models/user.rb | 2 +- web/Gemfile | 1 + web/Gemfile.lock | 9 ++ .../CurrentSubscription.js.jsx.coffee | 106 +++++++++++++++++- .../JamTrackLandingScreen.js.jsx.coffee | 2 +- .../PopupJamTrackPlayer.js.jsx.coffee | 2 +- .../AccountSubscriptionScreen.scss | 14 +++ web/app/controllers/api_recurly_controller.rb | 10 +- web/app/views/corps/faqs.html.erb | 2 +- web/app/views/corps/features.html.erb | 2 +- web/app/views/corps/videos.html.erb | 4 +- web/app/views/dialogs/_banner.html.slim | 4 - 16 files changed, 169 insertions(+), 37 deletions(-) diff --git a/admin/Gemfile b/admin/Gemfile index cae7f7e72..c07af8f93 100644 --- a/admin/Gemfile +++ b/admin/Gemfile @@ -85,7 +85,7 @@ gem 'zip-codes' gem 'email_validator' gem 'best_in_place' #, github: 'bernat/best_in_place' gem 'auto_strip_attributes', '2.6.0' - +gem 'elasticsearch' #group :libv8 do # gem 'libv8', "~> 4.5.95" diff --git a/admin/Gemfile.lock b/admin/Gemfile.lock index 3983afb54..e11ac010b 100644 --- a/admin/Gemfile.lock +++ b/admin/Gemfile.lock @@ -153,6 +153,14 @@ GEM domain_name (0.5.20170404) unf (>= 0.0.5, < 1.0.0) dotenv (2.2.1) + elasticsearch (7.5.0) + elasticsearch-api (= 7.5.0) + elasticsearch-transport (= 7.5.0) + elasticsearch-api (7.5.0) + multi_json + elasticsearch-transport (7.5.0) + faraday (>= 0.14, < 1) + multi_json email_validator (1.6.0) activemodel erubis (2.7.0) @@ -631,6 +639,7 @@ DEPENDENCIES country-select database_cleaner devise + elasticsearch email_validator eventmachine (= 1.2.3) execjs (= 1.4.0) diff --git a/admin/app/admin/jam_ruby_users.rb b/admin/app/admin/jam_ruby_users.rb index 41381f456..fff7b460d 100644 --- a/admin/app/admin/jam_ruby_users.rb +++ b/admin/app/admin/jam_ruby_users.rb @@ -225,7 +225,7 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do 'sets secret override to give user a free plan (link goes to another page)' end div do - link_to("Give No-Payment Plan", edit_admin_subscription_path(user.id)) + link_to("Give No-Payment Plan", edit_admin_user_override_path(user.id)) end end @@ -234,16 +234,25 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do 'Change Plan Actions' end h4 do - 'Change desired plan xactly as if the user did it on /client#/accounts/subscription' + 'Change desired plan exactly as if the user did it on /client#/accounts/subscription' end div do - link_to("change plan to silver", change_to_plan_admin_user_path(user.id, plan_code: 'jamsubsilver'), :data => {:confirm => 'Are you sure?'}) + link_to("change plan to silver monthly", change_to_plan_admin_user_path(user.id, plan_code: 'jamsubsilver'), :data => {:confirm => 'Are you sure?'}) end div do - link_to("change plan to gold", change_to_plan_admin_user_path(user.id, plan_code: 'jamsubgold'), :data => {:confirm => 'Are you sure?'}) + link_to("change plan to gold monthly", change_to_plan_admin_user_path(user.id, plan_code: 'jamsubgold'), :data => {:confirm => 'Are you sure?'}) end div do - link_to("change plan to platinum", change_to_plan_admin_user_path(user.id, plan_code: 'jamsubplatinum'), :data => {:confirm => 'Are you sure?'}) + link_to("change plan to platinum monthly", change_to_plan_admin_user_path(user.id, plan_code: 'jamsubplatinum'), :data => {:confirm => 'Are you sure?'}) + end + div do + link_to("change plan to silver yearly", change_to_plan_admin_user_path(user.id, plan_code: 'jamsubsilveryearly'), :data => {:confirm => 'Are you sure?'}) + end + div do + link_to("change plan to gold yearly", change_to_plan_admin_user_path(user.id, plan_code: 'jamsubgoldyearly'), :data => {:confirm => 'Are you sure?'}) + end + div do + link_to("change plan to platinum yearly", change_to_plan_admin_user_path(user.id, plan_code: 'jamsubplatinumyearly'), :data => {:confirm => 'Are you sure?'}) end div do link_to("change plan to free", change_to_plan_admin_user_path(user.id, plan_code: ''), :data => {:confirm => 'Are you sure?'}) @@ -416,23 +425,17 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do links << link_to("Edit", edit_resource_path(user), :class => "member_link edit_link") links end - column "ID" do |user| - link_to(truncate(user.id, {:length => 12}), - resource_path(user), - {:title => user.id}) - end + column "Email" do |user| link_to user.email, resource_path(user) end - column :admin + column :subscription_plan_code + column :desired_plan_code column :created_at - column :musician do |user| - user.musician? ? true : false - end - column :city - column :state column :first_name column :last_name + column :city + column :state end controller do diff --git a/admin/app/admin/subscription_override.rb b/admin/app/admin/subscription_override.rb index 78bbb5c36..8831c66cf 100644 --- a/admin/app/admin/subscription_override.rb +++ b/admin/app/admin/subscription_override.rb @@ -1,4 +1,4 @@ -ActiveAdmin.register User, :as => 'Subscription' do +ActiveAdmin.register User, :as => 'User_Override' do menu :label => 'Subscription', :parent => 'Users' diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index 04b8a2cbc..ee73d9bbe 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -1045,7 +1045,7 @@ module JamRuby user.reset_password_token = SecureRandom.urlsafe_base64 user.reset_password_token_created = Time.now - user.save + user.save(validate:false) reset_url = "#{base_uri}/reset_password_token?token=#{user.reset_password_token}&email=#{CGI.escape(email)}" UserMailer.password_reset(user, reset_url).deliver_now diff --git a/web/Gemfile b/web/Gemfile index 4238b00b0..9f7c35692 100644 --- a/web/Gemfile +++ b/web/Gemfile @@ -119,6 +119,7 @@ gem 'zip-codes' gem 'email_validator' #gem "browserify-rails", "~> 0.7" +gem 'elasticsearch' if ENV['FASTER_PATH'] == '1' # https://github.com/danielpclark/faster_path diff --git a/web/Gemfile.lock b/web/Gemfile.lock index 3a3873f27..d64fd95f1 100644 --- a/web/Gemfile.lock +++ b/web/Gemfile.lock @@ -152,6 +152,14 @@ GEM domain_name (0.5.20170404) unf (>= 0.0.5, < 1.0.0) dotenv (2.2.1) + elasticsearch (7.4.0) + elasticsearch-api (= 7.4.0) + elasticsearch-transport (= 7.4.0) + elasticsearch-api (7.4.0) + multi_json + elasticsearch-transport (7.4.0) + faraday + multi_json em-websocket (0.5.1) eventmachine (>= 0.12.9) http_parser.rb (~> 0.6.0) @@ -767,6 +775,7 @@ DEPENDENCIES coffee-script-source (= 1.12.2) database_cleaner (= 1.3.0) devise (= 3.3.0) + elasticsearch em-websocket (>= 0.4.0) email_validator eventmachine (= 1.2.3) diff --git a/web/app/assets/javascripts/react-components/CurrentSubscription.js.jsx.coffee b/web/app/assets/javascripts/react-components/CurrentSubscription.js.jsx.coffee index 18c7fa05f..ff8fe5184 100644 --- a/web/app/assets/javascripts/react-components/CurrentSubscription.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/CurrentSubscription.js.jsx.coffee @@ -32,8 +32,20 @@ AppStore = context.AppStore return subscriptionCode.price return "Unknown plan code=#{plan_code}" + getDisplayCycle:(plan_code) -> + if plan_code == '' + plan_code = null + for subscriptionCode in gon.global.subscription_codes + if plan_code == subscriptionCode.id + if subscriptionCode.cycle == "year" + return "annual" + else + return subscriptionCode.cycle + "ly" + return "Unknown plan code=#{plan_code}" + onPlanChanged: (e) -> val = e.target.value + @originalPlan = this.currentPlan() @setState({selectedPlan: val}) currentPlan: () -> @@ -48,13 +60,16 @@ AppStore = context.AppStore onSubmit: (event) -> if event event.preventDefault() - @performSubmit() + @prePerformSubmit() onChangeSubmit: (form) -> if @state.updating return - @performSubmit() + @prePerformSubmit() + cancelChangePlan:() -> + console.log("cancel change plan", @originalPlan) + @setState({selectedPlan: @originalPlan }) # user selects button on main page onUpdatePaymentMethod: () -> if gon.isNativeClient @@ -68,10 +83,40 @@ AppStore = context.AppStore else window.location.href = "/client#/account/paymentHistory" - performSubmit: () -> + prePerformSubmit:() -> if !@state.selectedPlan? return + message = null + if this.props.subscription.subscription + if this.state.selectedPlan == null || this.state.selectedPlan == '' + message = "

You have chosen to go back down to the FREE PLAN. Your subscription will be canceled, and you will keep your plan until the end of the current billing cycle.

" + else + message = "

You have selected the #{this.getDisplayNameTier(this.state.selectedPlan).toUpperCase()} #{this.getDisplayCycle(this.state.selectedPlan).toUpperCase()} PLAN and will be charged US$#{this.getDisplayNamePrice(this.state.selectedPlan)} on the start of next billing cycle.

" + else + if this.state.selectedPlan == null || this.state.selectedPlan == '' + @performSubmit() + return + else + message = "

You have selected the #{this.getDisplayNameTier(this.state.selectedPlan).toUpperCase()} #{this.getDisplayCycle(this.state.selectedPlan).toUpperCase()} PLAN and will be charged US$#{this.getDisplayNamePrice(this.state.selectedPlan)} .

" + + buttons = [] + buttons.push({ + name: 'CANCEL', + buttonStyle: 'button-grey', + click: (() => (@cancelChangePlan())) + }) + buttons.push({ + name: 'CONFIRM', + buttonStyle: 'button-orange', + click: (() => (@performSubmit())) + }) + context.JK.Banner.show({ + title: "Confirm Plan Change", + html: message, + buttons: buttons}) + + performSubmit: () -> @setState({updating: true}) #SubscriptionActions.changeSubscription(this.state.selectedPlan) rest.changeSubscription(this.state.selectedPlan).done((subscription) => @@ -138,6 +183,44 @@ AppStore = context.AppStore document.querySelector('#change-subscription-form').addEventListener('submit', @onChangeSubmit.bind(this)) + + getTimeRemaining: (t) -> + + if t < 0 + t = -t + + seconds = Math.floor( (t/1000) % 60 ); + minutes = Math.floor( (t/1000/60) % 60 ); + hours = Math.floor( (t/(1000*60*60)) % 24 ); + days = Math.floor( t/(1000*60*60*24) ); + + return { + 'total': t, + 'days': days, + 'hours': hours, + 'minutes': minutes, + 'seconds': seconds + }; + + + displayTime: (until_time) -> + + untilTime = @getTimeRemaining(until_time * 1000) + + timeString = '' + if untilTime.days != 0 + timeString += "#{untilTime.days} days, " + if untilTime.hours != 0 || timeString.length > 0 + timeString += "#{untilTime.hours} hours, " + if untilTime.minutes != 0 || timeString.length > 0 + timeString += "#{untilTime.minutes} minutes, " + if untilTime.seconds != 0 || timeString.length > 0 + timeString += "#{untilTime.seconds} seconds" + + if timeString == '' + 'now!' + timeString + comparePlans: (e) -> if context.JK.clientType() == 'client' context.JK.popExternalLink("https://jamkazam.freshdesk.com/support/solutions/articles/66000122535-what-are-jamkazam-s-free-vs-premium-features-") @@ -158,7 +241,7 @@ AppStore = context.AppStore plan_codes.push(``) for plan in yearlies plan_codes.push(``) - plansJsx = `` + plansJsx = `` changeClass = 'button-orange update-plan' if !@state.selectedPlan? || @state.updating @@ -225,6 +308,20 @@ AppStore = context.AppStore billingAddendum = `However, your cancelled {effective_plan_name} plan is still active until the end of the billing cycle.`# `

You will be billed a final time at the {this.getDisplayNameTier(this.props.subscription.subscription.plan.plan_code)} at end of this billing cycle.
` else billingAddendum = null + if @props.subscription.subscription_rules.remaining_month_play_time + remaining_month_play_time = @props.subscription.subscription_rules.remaining_month_play_time + until_time = new Date() + until_time = new Date(until_time.getTime() + remaining_month_play_time * 1000) + #until_time.setSeconds(until_time.getSeconds() + @subscriptionRules.remaining_month_play_time) + playtime = `
+ +

You have {this.displayTime(remaining_month_play_time)} time remaining this month. Only the time you spend in a session with 2 or more people uses your session play time.

+
` + else + playtime = `
+ +

You have unlimited play time.

+
` `

Subscription:

@@ -246,6 +343,7 @@ AppStore = context.AppStore

{explanation} {billingAddendum}

{warning}
+ {playtime} BACK{update_payment_btn}
diff --git a/web/app/assets/javascripts/react-components/JamTrackLandingScreen.js.jsx.coffee b/web/app/assets/javascripts/react-components/JamTrackLandingScreen.js.jsx.coffee index 50909d46e..5250832f0 100644 --- a/web/app/assets/javascripts/react-components/JamTrackLandingScreen.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/JamTrackLandingScreen.js.jsx.coffee @@ -30,7 +30,7 @@ rest = context.JK.Rest() else howTo = `
- The fastest way to start playing with your JamTracks is to open them below and use our custom mix feature to play them back in your browser. To access the full set of JamTrack features, install our free app. To learn more about all you can do with JamTracks, check out our JamTracks help docs. + The fastest way to start playing with your JamTracks is to open them below and use our custom mix feature to play them back in your browser. To access the full set of JamTrack features, install our free app. To learn more about all you can do with JamTracks, check out our JamTracks help docs.
` diff --git a/web/app/assets/javascripts/react-components/PopupJamTrackPlayer.js.jsx.coffee b/web/app/assets/javascripts/react-components/PopupJamTrackPlayer.js.jsx.coffee index 2a5411a8f..146229a8f 100644 --- a/web/app/assets/javascripts/react-components/PopupJamTrackPlayer.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/PopupJamTrackPlayer.js.jsx.coffee @@ -487,7 +487,7 @@ mixins.push(Reflux.listenTo(UserStore, 'onUserChanged')) helpful resources
- read a web player help article
+ read a web player help article
that explains how to use all the features of this web player
diff --git a/web/app/assets/stylesheets/client/react-components/AccountSubscriptionScreen.scss b/web/app/assets/stylesheets/client/react-components/AccountSubscriptionScreen.scss index 648959359..b7e53dca7 100644 --- a/web/app/assets/stylesheets/client/react-components/AccountSubscriptionScreen.scss +++ b/web/app/assets/stylesheets/client/react-components/AccountSubscriptionScreen.scss @@ -7,6 +7,9 @@ height: 100%; } + p { + line-height:1.25; + } * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; @@ -223,5 +226,16 @@ .update-payment-method { float:right; } + .play-time { + label { + margin-bottom:8px; + } + margin-top:30px; + margin-bottom:30px; + width:35rem; + } + .playtime { + font-weight:bold; + } } } diff --git a/web/app/controllers/api_recurly_controller.rb b/web/app/controllers/api_recurly_controller.rb index ee4ed0fd6..6338d6ded 100644 --- a/web/app/controllers/api_recurly_controller.rb +++ b/web/app/controllers/api_recurly_controller.rb @@ -155,7 +155,8 @@ class ApiRecurlyController < ApiController admin_override_plan_code: current_user.admin_override_plan_code, admin_override_ends_at: current_user.admin_override_ends_at, in_trial: !current_user.subscription_trial_ended?, - trial_ends_at: current_user.subscription_trial_ends_at + trial_ends_at: current_user.subscription_trial_ends_at, + subscription_rules: current_user.subscription_rules }, :status => 200 rescue RecurlyClientError => x render json: {:message => x.inspect, errors: x.errors}, :status => 404 @@ -175,7 +176,6 @@ class ApiRecurlyController < ApiController subscription, account = @client.find_subscription(current_user) past_due = account && account.has_past_due_invoice has_billing_info = !account.nil? && !account[:billing_info].nil? - render :json => { past_due: past_due, subscription: subscription, has_billing_info: has_billing_info, @@ -184,7 +184,8 @@ class ApiRecurlyController < ApiController admin_override_plan_code: current_user.admin_override_plan_code, admin_override_ends_at: current_user.admin_override_ends_at, in_trial: !current_user.subscription_trial_ended?, - trial_ends_at: current_user.subscription_trial_ends_at + trial_ends_at: current_user.subscription_trial_ends_at, + subscription_rules: current_user.subscription_rules, }, :status => 200 end @@ -226,7 +227,8 @@ class ApiRecurlyController < ApiController admin_override_plan_code: current_user.admin_override_plan_code, admin_override_ends_at: current_user.admin_override_ends_at, in_trial: !current_user.subscription_trial_ended?, - trial_ends_at: current_user.subscription_trial_ends_at + trial_ends_at: current_user.subscription_trial_ends_at, + subscription_rules: current_user.subscription_rules } end rescue RecurlyClientError => x diff --git a/web/app/views/corps/faqs.html.erb b/web/app/views/corps/faqs.html.erb index 1941d4bdd..438a69856 100644 --- a/web/app/views/corps/faqs.html.erb +++ b/web/app/views/corps/faqs.html.erb @@ -4,5 +4,5 @@

Frequently Asked Questions

- The JamKazam FAQ can be found on our support site here: JamKazam Frequently Asked Questions. + The JamKazam FAQ can be found on our support site here: JamKazam Frequently Asked Questions.

\ No newline at end of file diff --git a/web/app/views/corps/features.html.erb b/web/app/views/corps/features.html.erb index f06dfc52f..8582cd7fe 100644 --- a/web/app/views/corps/features.html.erb +++ b/web/app/views/corps/features.html.erb @@ -4,7 +4,7 @@

Features & Benefits

- Musicians can enjoy four major features of the new JamKazam service, as described below. Also, several Tutorial Videos are available to see how various features work in more detail. + Musicians can enjoy four major features of the new JamKazam service, as described below. Also, several Tutorial Videos are available to see how various features work in more detail.


diff --git a/web/app/views/corps/videos.html.erb b/web/app/views/corps/videos.html.erb index 53c604383..ba1026248 100644 --- a/web/app/views/corps/videos.html.erb +++ b/web/app/views/corps/videos.html.erb @@ -4,7 +4,7 @@

Videos

- For a great introduction to the service, please watch the JamKazam Overview video. + For a great introduction to the service, please watch the JamKazam Overview video.

@@ -23,5 +23,5 @@

- Also, several Tutorial Videos are available to see how various features work in more detail. + Also, several Tutorial Videos are available to see how various features work in more detail.

\ No newline at end of file diff --git a/web/app/views/dialogs/_banner.html.slim b/web/app/views/dialogs/_banner.html.slim index 6c6c47c9d..fd1000ca7 100644 --- a/web/app/views/dialogs/_banner.html.slim +++ b/web/app/views/dialogs/_banner.html.slim @@ -59,8 +59,4 @@ script type='text/template' id='template-mixer-mode-change' span.definition Note on Audio Files div The volume control on any audio file is always both the master and personal volume control, regardless of the current mode. br - div - | For more detailed information on this topic, read our knowledge base article on  - a rel="external" href="https://jamkazam.desk.com/customer/portal/articles/1757233-using-personal-vs-master-mix-controls" Configuring Master and Personal Mixes in a Session - | . br \ No newline at end of file