From c1dca335c7bc90dc0e9cd89d879af22d4dc681f4 Mon Sep 17 00:00:00 2001 From: Ben Halpern Date: Tue, 9 Jun 2020 16:28:16 -0400 Subject: [PATCH] [deploy] Allow users to set a payment pointer for their content (#8304) * Initial user payment pointer work * Finalize functionality and tests * Fix schema * Update app/views/shared/_payment_pointer.html.erb * Add function to list --- app/assets/javascripts/initializePage.js | 3 ++- .../initializers/initializePaymentPointers.js | 11 +++++++++++ app/policies/user_policy.rb | 1 + app/views/articles/show.html.erb | 2 ++ app/views/comments/index.html.erb | 2 ++ app/views/layouts/application.html.erb | 1 + app/views/shared/_payment_pointer.html.erb | 3 +++ app/views/users/_misc.html.erb | 18 ++++++++++++++++++ app/views/users/show.html.erb | 2 ++ ...00605170430_add_payment_pointer_to_users.rb | 5 +++++ db/schema.rb | 1 + spec/requests/comments_spec.rb | 12 ++++++++++++ spec/requests/stories_show_spec.rb | 12 ++++++++++++ spec/requests/user/user_profile_spec.rb | 12 ++++++++++++ 14 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/initializers/initializePaymentPointers.js create mode 100644 app/views/shared/_payment_pointer.html.erb create mode 100644 db/migrate/20200605170430_add_payment_pointer_to_users.rb diff --git a/app/assets/javascripts/initializePage.js b/app/assets/javascripts/initializePage.js index 8d25dc7b7..e57e64811 100644 --- a/app/assets/javascripts/initializePage.js +++ b/app/assets/javascripts/initializePage.js @@ -10,7 +10,7 @@ initializeUserProfilePage, initializePodcastPlayback, initializeDrawerSliders, initializeHeroBannerClose, initializeOnboardingTaskCard, initScrolling, nextPage:writable, fetching:writable, done:writable, adClicked:writable, - initializeSpecialNavigationFunctionality, initializeBroadcast + initializePaymentPointers, initializeSpecialNavigationFunctionality, initializeBroadcast */ function callInitializers() { @@ -38,6 +38,7 @@ function callInitializers() { initializeSpecialNavigationFunctionality(); initializeBaseTracking(); + initializePaymentPointers(); initializeTouchDevice(); initializeCommentsPage(); initializeArticleDate(); diff --git a/app/assets/javascripts/initializers/initializePaymentPointers.js b/app/assets/javascripts/initializers/initializePaymentPointers.js new file mode 100644 index 000000000..b5c33af5d --- /dev/null +++ b/app/assets/javascripts/initializers/initializePaymentPointers.js @@ -0,0 +1,11 @@ +function initializePaymentPointers() { + var userPointer = document.getElementById('author-payment-pointer'); + var basePointer = document.getElementById('base-payment-pointer'); + var meta = document.querySelector("meta[name='monetization']"); + + if (userPointer) { + meta.content = userPointer.dataset.paymentPointer; + } else { + meta.content = basePointer.dataset.paymentPointer;; + } +} diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index cf6d38879..e914dcc75 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -51,6 +51,7 @@ class UserPolicy < ApplicationPolicy name password password_confirmation + payment_pointer permit_adjacent_sponsors profile_image stackoverflow_url diff --git a/app/views/articles/show.html.erb b/app/views/articles/show.html.erb index 82ce52013..a1d7e10ef 100644 --- a/app/views/articles/show.html.erb +++ b/app/views/articles/show.html.erb @@ -1,5 +1,7 @@ <% title @article.title_with_query_preamble(user_signed_in?) %> +<%= render "shared/payment_pointer", user: @article.user %> + <%= render "shared/webcomponents_loader_script" %> <% if user_signed_in? %> <%= javascript_packs_with_chunks_tag "clipboardCopy", "webShare", "articlePage", "articleModerationTools", defer: true %> diff --git a/app/views/comments/index.html.erb b/app/views/comments/index.html.erb index 268141337..b4747b310 100644 --- a/app/views/comments/index.html.erb +++ b/app/views/comments/index.html.erb @@ -35,7 +35,9 @@ <% end %> <% end %> <% end %> + <% if @commentable.class.name == "Article" %> + <%= render "shared/payment_pointer", user: @commentable.user %>
<% end %> <% if @root_comment %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 715079388..2371106e4 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -1,4 +1,5 @@ <%= render "shell/top" %> +
<% if flash[:global_notice] %> diff --git a/app/views/shared/_payment_pointer.html.erb b/app/views/shared/_payment_pointer.html.erb new file mode 100644 index 000000000..124d61a2e --- /dev/null +++ b/app/views/shared/_payment_pointer.html.erb @@ -0,0 +1,3 @@ +<% if user.payment_pointer.present? %> +
+<% end %> diff --git a/app/views/users/_misc.html.erb b/app/views/users/_misc.html.erb index d65a7c044..794d2e1ff 100644 --- a/app/views/users/_misc.html.erb +++ b/app/views/users/_misc.html.erb @@ -24,6 +24,24 @@ <%= render "language_settings" %> +
+
+

Web Monetization

+

Receive micropayments for time spent reading your posts directly.

+
+
+

This feature is in beta. Read more about web monetization here.

+
+ <%= form_for(@user, html: { id: nil, class: "grid gap-4" }) do |f| %> +
+ <%= f.label :payment_pointer, "Payment Pointer", class: "crayons-field__label" %> + <%= f.text_field :payment_pointer, class: "crayons-textfield", placeholder: "$pay.somethinglikethis.co/value" %> +
+ <%= f.hidden_field :tab, value: @tab, id: nil %> +
+ <% end %> +
+

Sponsors

diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 95cbfd147..3610f17c0 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -1,5 +1,7 @@ <% title @user.name %> +<%= render "shared/payment_pointer", user: @user %> + <%= content_for :page_meta do %> <%= render "users/meta" %> <% end %> diff --git a/db/migrate/20200605170430_add_payment_pointer_to_users.rb b/db/migrate/20200605170430_add_payment_pointer_to_users.rb new file mode 100644 index 000000000..7a73e6916 --- /dev/null +++ b/db/migrate/20200605170430_add_payment_pointer_to_users.rb @@ -0,0 +1,5 @@ +class AddPaymentPointerToUsers < ActiveRecord::Migration[6.0] + def change + add_column :users, :payment_pointer, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index df1a8e738..e868911a8 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1229,6 +1229,7 @@ ActiveRecord::Schema.define(version: 2020_06_08_175130) do t.string "old_username" t.boolean "onboarding_package_requested", default: false t.datetime "organization_info_updated_at" + t.string "payment_pointer" t.boolean "permit_adjacent_sponsors", default: true t.string "profile_image" t.datetime "profile_updated_at", default: "2017-01-01 05:00:00" diff --git a/spec/requests/comments_spec.rb b/spec/requests/comments_spec.rb index 2c01e5dbe..2f8f5a396 100644 --- a/spec/requests/comments_spec.rb +++ b/spec/requests/comments_spec.rb @@ -24,6 +24,18 @@ RSpec.describe "Comments", type: :request do expect(response.body).to include("FULL DISCUSSION") end + it "renders user payment pointer if set" do + article.user.update_column(:payment_pointer, "test-pointer-for-comments") + get "#{article.path}/comments" + expect(response.body).to include "author-payment-pointer" + expect(response.body).to include "test-pointer-for-comments" + end + + it "does not render payment pointer if not set" do + get "#{article.path}/comments" + expect(response.body).not_to include "author-payment-pointer" + end + context "when the comment is a root" do it "does not display top of thread button" do get comment.path diff --git a/spec/requests/stories_show_spec.rb b/spec/requests/stories_show_spec.rb index da378a280..d536e96ce 100644 --- a/spec/requests/stories_show_spec.rb +++ b/spec/requests/stories_show_spec.rb @@ -69,6 +69,18 @@ RSpec.describe "StoriesShow", type: :request do expect(response.body).not_to include "Hey this is a test" end + it "renders user payment pointer if set" do + article.user.update_column(:payment_pointer, "this-is-a-pointer") + get article.path + expect(response.body).to include "author-payment-pointer" + expect(response.body).to include "this-is-a-pointer" + end + + it "does not render payment pointer if not set" do + get article.path + expect(response.body).not_to include "author-payment-pointer" + end + it "renders second and third users if present" do # 3rd user doesn't seem to get rendered for some reason user2 = create(:user) diff --git a/spec/requests/user/user_profile_spec.rb b/spec/requests/user/user_profile_spec.rb index 22ef2a221..8b1397f5e 100644 --- a/spec/requests/user/user_profile_spec.rb +++ b/spec/requests/user/user_profile_spec.rb @@ -69,6 +69,18 @@ RSpec.describe "UserProfiles", type: :request do expect(response.body).not_to include("/feed/#{user.username}") end + it "renders user payment pointer if set" do + user.update_column(:payment_pointer, "test-payment-pointer") + get "/#{user.username}" + expect(response.body).to include "author-payment-pointer" + expect(response.body).to include "test-payment-pointer" + end + + it "does not render payment pointer if not set" do + get "/#{user.username}" + expect(response.body).not_to include "author-payment-pointer" + end + context "when organization" do it "renders organization page if org" do get organization.path