[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
This commit is contained in:
Ben Halpern 2020-06-09 16:28:16 -04:00 committed by GitHub
parent b4b10a0cd7
commit c1dca335c7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 84 additions and 1 deletions

View file

@ -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();

View file

@ -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;;
}
}

View file

@ -51,6 +51,7 @@ class UserPolicy < ApplicationPolicy
name
password
password_confirmation
payment_pointer
permit_adjacent_sponsors
profile_image
stackoverflow_url

View file

@ -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 %>

View file

@ -35,7 +35,9 @@
<% end %>
<% end %>
<% end %>
<% if @commentable.class.name == "Article" %>
<%= render "shared/payment_pointer", user: @commentable.user %>
<div id="comment-article-indicator" data-article-id="<%= @commentable.id %>">
<% end %>
<% if @root_comment %>

View file

@ -1,4 +1,5 @@
<%= render "shell/top" %>
<div id="base-payment-pointer" data-payment-pointer="<%= SiteConfig.payment_pointer %>" ></div>
<style>.app-shell-loader {display: none;}</style>
<div id="page-content" class="universal-page-content-wrapper <%= view_class %>" data-current-page="<%= current_page %>">
<% if flash[:global_notice] %>

View file

@ -0,0 +1,3 @@
<% if user.payment_pointer.present? %>
<div id="author-payment-pointer" data-payment-pointer="<%= user.payment_pointer %>" ></div>
<% end %>

View file

@ -24,6 +24,24 @@
<%= render "language_settings" %>
<div class="crayons-card grid gap-6 p-6 mb-6">
<header>
<h3 class="mb-2">Web Monetization</h3>
<p>Receive micropayments for time spent reading your posts directly.</p>
</header>
<div class="crayons-notice crayons-notice--warning">
<p>This feature is in beta. Read more about web monetization <a href="https://dev.to/hacksultan/web-monetization-like-i-m-5-1418">here</a>.</p>
</div>
<%= form_for(@user, html: { id: nil, class: "grid gap-4" }) do |f| %>
<div class="crayons-field">
<%= f.label :payment_pointer, "Payment Pointer", class: "crayons-field__label" %>
<%= f.text_field :payment_pointer, class: "crayons-textfield", placeholder: "$pay.somethinglikethis.co/value" %>
</div>
<%= f.hidden_field :tab, value: @tab, id: nil %>
<div><button type="submit" class="crayons-btn">Save Web Monetization Settings</button></div>
<% end %>
</div>
<div class="crayons-card grid gap-6 p-6 mb-6">
<header>
<h3 class="mb-2">Sponsors</h3>

View file

@ -1,5 +1,7 @@
<% title @user.name %>
<%= render "shared/payment_pointer", user: @user %>
<%= content_for :page_meta do %>
<%= render "users/meta" %>
<% end %>

View file

@ -0,0 +1,5 @@
class AddPaymentPointerToUsers < ActiveRecord::Migration[6.0]
def change
add_column :users, :payment_pointer, :string
end
end

View file

@ -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"

View file

@ -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

View file

@ -69,6 +69,18 @@ RSpec.describe "StoriesShow", type: :request do
expect(response.body).not_to include "<span class=\"article-title-preamble\">Hey this is a test</span>"
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)

View file

@ -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