From 8527f208573b7cf2b98090e60987e8939ca71173 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Thu, 4 Apr 2019 07:06:51 -0400 Subject: [PATCH 01/37] Add Rewards tip icon to all tweets via content script --- .../extension/brave_rewards/BUILD.gn | 3 +- .../_locales/en_US/messages.json | 8 +++ .../extension/brave_rewards/background.ts | 16 +++++ .../extension/brave_rewards/content.css | 6 ++ .../extension/brave_rewards/content.ts | 70 +++++++++++++++++++ .../extension/brave_rewards/manifest.json | 16 +++++ .../extension/extension_static_resources.grd | 1 + 7 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 components/brave_rewards/resources/extension/brave_rewards/content.css create mode 100644 components/brave_rewards/resources/extension/brave_rewards/content.ts diff --git a/components/brave_rewards/resources/extension/brave_rewards/BUILD.gn b/components/brave_rewards/resources/extension/brave_rewards/BUILD.gn index 97ba4b306197..64fe1541f8b6 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/BUILD.gn +++ b/components/brave_rewards/resources/extension/brave_rewards/BUILD.gn @@ -9,7 +9,8 @@ group("brave_rewards") { transpile_web_ui("brave_rewards_panel") { entry_points = [ ["brave_rewards_panel", rebase_path("brave_rewards_panel.tsx")], - ["brave_rewards_panel_background", rebase_path("background.ts")] + ["brave_rewards_panel_background", rebase_path("background.ts")], + ["brave_rewards_panel_content", rebase_path("content.ts")] ] resource_name = "brave_rewards_panel" diff --git a/components/brave_rewards/resources/extension/brave_rewards/_locales/en_US/messages.json b/components/brave_rewards/resources/extension/brave_rewards/_locales/en_US/messages.json index a66d9be7b6bb..659f97a3a022 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/_locales/en_US/messages.json +++ b/components/brave_rewards/resources/extension/brave_rewards/_locales/en_US/messages.json @@ -412,5 +412,13 @@ "adsEarnings": { "message": "earned from ads", "description": "Description text for ad grants in grant details" + }, + "twitterTipsHoverText": { + "message": "Tip", + "description": "Hover text for Twitter tips action" + }, + "twitterTipsIconLabel": { + "message": "Tip", + "description": "Icon label for Twitter tips" } } diff --git a/components/brave_rewards/resources/extension/brave_rewards/background.ts b/components/brave_rewards/resources/extension/brave_rewards/background.ts index 5cb4bfda7dea..bf9588a96f66 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/background.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/background.ts @@ -78,3 +78,19 @@ chrome.runtime.onConnect.addListener(function () { } }) }) + +chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { + const action = typeof msg === 'string' ? msg : msg.type + switch (action) { + case 'rewardsEnabled': { + // Check if rewards is enabled + chrome.braveRewards.getRewardsMainEnabled(function (enabled) { + sendResponse({ enabled: enabled }) + }) + // Must return true for asynchronous calls to sendResponse + return true + } + default: + return false + } +}) diff --git a/components/brave_rewards/resources/extension/brave_rewards/content.css b/components/brave_rewards/resources/extension/brave_rewards/content.css new file mode 100644 index 000000000000..1db9001a13c9 --- /dev/null +++ b/components/brave_rewards/resources/extension/brave_rewards/content.css @@ -0,0 +1,6 @@ +.brave-tip-icon { + margin-top: 5px; + content: url('chrome-extension://__MSG_@@extension_id__/img/bat-16.png'); + width: 16px; + height: 16px; +} diff --git a/components/brave_rewards/resources/extension/brave_rewards/content.ts b/components/brave_rewards/resources/extension/brave_rewards/content.ts new file mode 100644 index 000000000000..8b9a8097981f --- /dev/null +++ b/components/brave_rewards/resources/extension/brave_rewards/content.ts @@ -0,0 +1,70 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Utils +import { getMessage } from './background/api/locale_api' + +const createBraveTipAction = () => { + // Create the tip action + const braveTipAction = document.createElement('div') + braveTipAction.className = 'ProfileTweet-action action-brave-tip' + + // Create the tip button + const braveTipButton = document.createElement('button') + braveTipButton.className = 'ProfileTweet-actionButton u-textUserColorHover js-actionButton' + braveTipButton.type = 'button' + braveTipButton.onclick = function (event) { + alert('Sending a tip!') + } + braveTipAction.appendChild(braveTipButton) + + // Create the tip icon container + const braveTipIconContainer = document.createElement('div') + braveTipIconContainer.className = 'IconContainer js-tooltip' + braveTipIconContainer.setAttribute('data-original-title', getMessage('twitterTipsHoverText')) + braveTipButton.appendChild(braveTipIconContainer) + + // Create the tip icon + const braveTipIcon = document.createElement('span') + braveTipIcon.className = 'Icon Icon--medium brave-tip-icon' + braveTipIconContainer.appendChild(braveTipIcon) + + // Create the tip action count (typically used to present a counter + // associated with the action, but we'll use it to display a static + // action label) + const braveTipActionCount = document.createElement('span') + braveTipActionCount.className = 'ProfileTweet-actionCount' + braveTipButton.appendChild(braveTipActionCount) + + const braveTipActionCountPresentation = document.createElement('span') + braveTipActionCountPresentation.className = 'ProfileTweet-actionCountForPresentation' + braveTipActionCountPresentation.textContent = getMessage('twitterTipsIconLabel') + braveTipActionCount.appendChild(braveTipActionCountPresentation) + + return braveTipAction +} + +const configureBraveTipAction = () => { + chrome.runtime.sendMessage('rewardsEnabled', function (response) { + const tweets = document.getElementsByClassName('tweet') + for (let i = 0; i < tweets.length; ++i) { + const actions = tweets[i].getElementsByClassName('js-actions')[0] + if (actions) { + const braveTipActions = actions.getElementsByClassName('action-brave-tip') + if (response.enabled) { + if (braveTipActions.length === 0) { + actions.appendChild(createBraveTipAction(tweets[i])) + } + } else { + if (braveTipActions.length === 1) { + actions.removeChild(braveTipActions[0]) + } + } + } + } + }) + setTimeout(configureBraveTipAction, 3000) +} + +configureBraveTipAction() diff --git a/components/brave_rewards/resources/extension/brave_rewards/manifest.json b/components/brave_rewards/resources/extension/brave_rewards/manifest.json index 125117fa3db4..d0325b9fb276 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/manifest.json +++ b/components/brave_rewards/resources/extension/brave_rewards/manifest.json @@ -25,6 +25,22 @@ "256": "img/bat-256.png" } }, + "content_scripts": [ + { + "matches": [ + "https://*.twitter.com/*" + ], + "css": [ + "content.css" + ], + "js": [ + "out/brave_rewards_panel_content.bundle.js" + ] + } + ], + "web_accessible_resources": [ + "img/bat-16.png" + ], "icons": { "16": "img/bat-16.png", "32": "img/bat-32.png", diff --git a/components/brave_rewards/resources/extension/extension_static_resources.grd b/components/brave_rewards/resources/extension/extension_static_resources.grd index 143d90f1450f..cb9bedde0749 100644 --- a/components/brave_rewards/resources/extension/extension_static_resources.grd +++ b/components/brave_rewards/resources/extension/extension_static_resources.grd @@ -13,6 +13,7 @@ + From 7e5687bbc453f11e28a94a2d69704a972f8d6459 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Tue, 9 Apr 2019 14:55:39 -0400 Subject: [PATCH 02/37] Show tipping banner when user clicks Tip button on a tweet --- .../extension/brave_rewards/background.ts | 20 +++++++++++ .../extension/brave_rewards/content.ts | 36 +++++++++++++++++-- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/components/brave_rewards/resources/extension/brave_rewards/background.ts b/components/brave_rewards/resources/extension/brave_rewards/background.ts index bf9588a96f66..0927415965ad 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/background.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/background.ts @@ -79,9 +79,29 @@ chrome.runtime.onConnect.addListener(function () { }) }) +const donateNow = (publisher: string, tweetText: string) => { + chrome.tabs.query({ + active: true, + windowId: chrome.windows.WINDOW_ID_CURRENT + }, (tabs) => { + if (!tabs || tabs.length === 0) { + return + } + const tabId = tabs[0].id + if (tabId === undefined) { + return + } + chrome.braveRewards.donateToSite(tabId, publisher) + }) +} + chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { const action = typeof msg === 'string' ? msg : msg.type switch (action) { + case 'donateNow': { + donateNow(msg.publisher, msg.tweetText) + return false + } case 'rewardsEnabled': { // Check if rewards is enabled chrome.braveRewards.getRewardsMainEnabled(function (enabled) { diff --git a/components/brave_rewards/resources/extension/brave_rewards/content.ts b/components/brave_rewards/resources/extension/brave_rewards/content.ts index 8b9a8097981f..d71bbb52ca27 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/content.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/content.ts @@ -5,7 +5,30 @@ // Utils import { getMessage } from './background/api/locale_api' -const createBraveTipAction = () => { +interface TweetMetaData { + name: string, + screenName: string, + userId: string, + tweetText: string +} + +const getTweetMetaData = (tweet: Element): TweetMetaData | null => { + if (!tweet) { + return null + } + const tweetTextElements = tweet.getElementsByClassName('tweet-text') + if (!tweetTextElements || tweetTextElements.length === 0) { + return null + } + return { + name: tweet.getAttribute('data-name') || '', + screenName: tweet.getAttribute('data-screen-name') || '', + userId: tweet.getAttribute('data-user-id') || '', + tweetText: tweetTextElements[0].textContent || '' + } +} + +const createBraveTipAction = (tweet: Element) => { // Create the tip action const braveTipAction = document.createElement('div') braveTipAction.className = 'ProfileTweet-action action-brave-tip' @@ -15,7 +38,16 @@ const createBraveTipAction = () => { braveTipButton.className = 'ProfileTweet-actionButton u-textUserColorHover js-actionButton' braveTipButton.type = 'button' braveTipButton.onclick = function (event) { - alert('Sending a tip!') + const tweetMetaData = getTweetMetaData(tweet) + if (tweetMetaData) { + chrome.runtime.sendMessage({ + type: 'donateNow', + publisher: 'duckduckgo.com', + name: tweetMetaData.name, + screenName: tweetMetaData.screenName, + tweetText: tweetMetaData.tweetText + }) + } } braveTipAction.appendChild(braveTipButton) From 29385bcc9351d55d7f718e831e66918c22b36b3d Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Mon, 15 Apr 2019 09:51:36 -0400 Subject: [PATCH 03/37] Refactor donations dialog to take a dictionary of parameters --- browser/brave_rewards/tip_dialog.cc | 25 +++++++++------------ browser/brave_rewards/tip_dialog.h | 2 +- browser/extensions/api/brave_rewards_api.cc | 15 ++++++++----- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/browser/brave_rewards/tip_dialog.cc b/browser/brave_rewards/tip_dialog.cc index 91c1397e5376..2ae4a60ade63 100644 --- a/browser/brave_rewards/tip_dialog.cc +++ b/browser/brave_rewards/tip_dialog.cc @@ -5,14 +5,14 @@ #include "brave/browser/brave_rewards/tip_dialog.h" -#include #include +#include #include -#include "base/values.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/strings/utf_string_conversions.h" +#include "base/values.h" #include "brave/common/webui_url_constants.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" @@ -37,7 +37,7 @@ constexpr int kDialogMaxHeight = 700; class TipDialogDelegate : public ui::WebDialogDelegate { public: explicit TipDialogDelegate(WebContents* initiator, - std::string publisher_key); + std::unique_ptr params); ~TipDialogDelegate() override; ui::ModalType GetDialogModalType() const override; @@ -53,15 +53,14 @@ class TipDialogDelegate : public ui::WebDialogDelegate { private: WebContents* initiator_; - const std::string publisher_key_; + std::unique_ptr params_; DISALLOW_COPY_AND_ASSIGN(TipDialogDelegate); }; TipDialogDelegate::TipDialogDelegate(WebContents* initiator, - std::string publisher_key) - : initiator_(initiator), - publisher_key_(publisher_key) { + std::unique_ptr params) + : initiator_(initiator), params_(std::move(params)) { } TipDialogDelegate::~TipDialogDelegate() { @@ -111,11 +110,9 @@ void TipDialogDelegate::GetDialogSize(gfx::Size* size) const { } std::string TipDialogDelegate::GetDialogArgs() const { - std::string data; - base::DictionaryValue dialog_args; - dialog_args.SetString("publisherKey", publisher_key_); - base::JSONWriter::Write(dialog_args, &data); - return data; + std::string json; + base::JSONWriter::Write(*params_, &json); + return json; } void TipDialogDelegate::OnDialogClosed( @@ -136,7 +133,7 @@ bool TipDialogDelegate::ShouldShowDialogTitle() const { namespace brave_rewards { void OpenTipDialog(WebContents* initiator, - const std::string& publisher_key) { + std::unique_ptr params) { content::WebContents* outermost_web_contents = guest_view::GuestViewBase::GetTopLevelWebContents(initiator); gfx::Size host_size = outermost_web_contents->GetContainerBounds().size(); @@ -147,7 +144,7 @@ void OpenTipDialog(WebContents* initiator, // resize) ShowConstrainedWebDialogWithAutoResize( initiator->GetBrowserContext(), - std::make_unique(initiator, publisher_key), + std::make_unique(initiator, std::move(params)), initiator, min_size, max_size); } diff --git a/browser/brave_rewards/tip_dialog.h b/browser/brave_rewards/tip_dialog.h index 324691fc39a7..d5944b838048 100644 --- a/browser/brave_rewards/tip_dialog.h +++ b/browser/brave_rewards/tip_dialog.h @@ -15,7 +15,7 @@ class WebContents; namespace brave_rewards { void OpenTipDialog(content::WebContents* initiator, - const std::string& publisher_key); + std::unique_ptr params); } diff --git a/browser/extensions/api/brave_rewards_api.cc b/browser/extensions/api/brave_rewards_api.cc index 94fb60aeee3e..2569ecdfe0ee 100644 --- a/browser/extensions/api/brave_rewards_api.cc +++ b/browser/extensions/api/brave_rewards_api.cc @@ -13,19 +13,19 @@ #include "base/strings/string_number_conversions.h" #include "brave/browser/brave_rewards/tip_dialog.h" #include "brave/common/extensions/api/brave_rewards.h" -#include "brave/components/brave_rewards/browser/rewards_service.h" -#include "brave/components/brave_rewards/browser/rewards_service_factory.h" #include "brave/components/brave_ads/browser/ads_service.h" #include "brave/components/brave_ads/browser/ads_service_factory.h" -#include "content/public/browser/web_contents.h" +#include "brave/components/brave_rewards/browser/rewards_service.h" +#include "brave/components/brave_rewards/browser/rewards_service_factory.h" #include "chrome/browser/extensions/api/tabs/tabs_constants.h" #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/profiles/profile.h" +#include "content/public/browser/web_contents.h" -using brave_rewards::RewardsService; -using brave_rewards::RewardsServiceFactory; using brave_ads::AdsService; using brave_ads::AdsServiceFactory; +using brave_rewards::RewardsService; +using brave_rewards::RewardsServiceFactory; namespace extensions { namespace api { @@ -70,7 +70,10 @@ ExtensionFunction::ResponseAction BraveRewardsTipSiteFunction::Run() { return RespondNow(Error(tabs_constants::kTabNotFoundError, base::NumberToString(params->tab_id))); } - ::brave_rewards::OpenTipDialog(contents, params->publisher_key); + + auto params_dict = std::make_unique(); + params_dict->SetString("publisherKey", params->publisher_key); + ::brave_rewards::OpenTipDialog(contents, std::move(params_dict)); return RespondNow(NoArguments()); } From 149ac70cbb157b3be1e499666145791e3c2ac819 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Mon, 15 Apr 2019 09:56:26 -0400 Subject: [PATCH 04/37] Add DonateToTwitterUser component and small refactor to accomodate it --- browser/extensions/api/brave_rewards_api.cc | 41 ++++++++ browser/extensions/api/brave_rewards_api.h | 11 +++ common/extensions/api/brave_rewards.json | 27 ++++++ .../donate/components/donateToSite.tsx | 57 +++++++++++ .../donate/components/donateToTwitterUser.tsx | 58 +++++++++++ .../components/transientDonationOverlay.tsx | 95 +++++++++++++++++++ .../extension/brave_rewards/background.ts | 9 +- .../extension/brave_rewards/content.ts | 18 +--- .../brave_rewards/resources/tip/brave_tip.tsx | 9 +- .../resources/tip/components/app.tsx | 53 +++++++---- components/definitions/chromel.d.ts | 1 + components/definitions/rewardsTip.d.ts | 7 ++ 12 files changed, 345 insertions(+), 41 deletions(-) create mode 100644 components/brave_rewards/resources/donate/components/donateToSite.tsx create mode 100644 components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx create mode 100644 components/brave_rewards/resources/donate/components/transientDonationOverlay.tsx diff --git a/browser/extensions/api/brave_rewards_api.cc b/browser/extensions/api/brave_rewards_api.cc index 2569ecdfe0ee..a1e5d2a8fba6 100644 --- a/browser/extensions/api/brave_rewards_api.cc +++ b/browser/extensions/api/brave_rewards_api.cc @@ -75,6 +75,47 @@ ExtensionFunction::ResponseAction BraveRewardsTipSiteFunction::Run() { params_dict->SetString("publisherKey", params->publisher_key); ::brave_rewards::OpenTipDialog(contents, std::move(params_dict)); +BraveRewardsDonateToTwitterUserFunction:: + ~BraveRewardsDonateToTwitterUserFunction() { +} + +ExtensionFunction::ResponseAction +BraveRewardsDonateToTwitterUserFunction::Run() { + std::unique_ptr params( + brave_rewards::DonateToTwitterUser::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + + // Sanity check: don't allow donations in private / tor contexts, + // although the command should not have been enabled in the first place. + Profile* profile = Profile::FromBrowserContext(browser_context()); + if (profile->IsOffTheRecord()) { + return RespondNow( + Error("Cannot donate to Twitter user in a private context")); + } + + // Get web contents for this tab + content::WebContents* contents = nullptr; + if (!ExtensionTabUtil::GetTabById( + params->tab_id, + profile, + include_incognito_information(), + nullptr, + nullptr, + &contents, + nullptr)) { + return RespondNow(Error(tabs_constants::kTabNotFoundError, + base::IntToString(params->tab_id))); + } + + auto params_dict = std::make_unique(); + params_dict->SetString("publisherKey", params->publisher_key); + auto tweet_metadata_dict = std::make_unique(); + tweet_metadata_dict->SetString("name", params->name); + tweet_metadata_dict->SetString("screenName", params->screen_name); + tweet_metadata_dict->SetString("tweetText", params->tweet_text); + params_dict->SetDictionary("tweetMetaData", std::move(tweet_metadata_dict)); + ::brave_rewards::OpenDonationDialog(contents, std::move(params_dict)); + return RespondNow(NoArguments()); } diff --git a/browser/extensions/api/brave_rewards_api.h b/browser/extensions/api/brave_rewards_api.h index b3468df2e98a..8e17a77c1f95 100644 --- a/browser/extensions/api/brave_rewards_api.h +++ b/browser/extensions/api/brave_rewards_api.h @@ -36,6 +36,17 @@ class BraveRewardsTipSiteFunction : public UIThreadExtensionFunction { ResponseAction Run() override; }; +class BraveRewardsDonateToTwitterUserFunction + : public UIThreadExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("braveRewards.donateToTwitterUser", UNKNOWN) + + protected: + ~BraveRewardsDonateToTwitterUserFunction() override; + + ResponseAction Run() override; +}; + class BraveRewardsGetPublisherDataFunction : public UIThreadExtensionFunction { public: DECLARE_EXTENSION_FUNCTION("braveRewards.getPublisherData", UNKNOWN) diff --git a/common/extensions/api/brave_rewards.json b/common/extensions/api/brave_rewards.json index 51e260dc07b8..97cdf84f3b5e 100644 --- a/common/extensions/api/brave_rewards.json +++ b/common/extensions/api/brave_rewards.json @@ -354,6 +354,33 @@ } ] }, + { + "name": "donateToTwitterUser", + "type": "function", + "description": "Allow the user to perform a donation to a Twitter user", + "parameters": [ + { + "name": "tabID", + "type": "integer" + }, + { + "name": "publisherKey", + "type": "string" + }, + { + "name": "name", + "type": "string" + }, + { + "name": "screenName", + "type": "string" + }, + { + "name": "tweetText", + "type": "string" + } + ] + }, { "name": "getPublisherData", "type": "function", diff --git a/components/brave_rewards/resources/donate/components/donateToSite.tsx b/components/brave_rewards/resources/donate/components/donateToSite.tsx new file mode 100644 index 000000000000..43e1a3316453 --- /dev/null +++ b/components/brave_rewards/resources/donate/components/donateToSite.tsx @@ -0,0 +1,57 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react' +import { bindActionCreators, Dispatch } from 'redux' +import { connect } from 'react-redux' + +// Components +import Banner from './siteBanner' +import TransientDonationOverlay from './transientDonationOverlay' + +// Utils +import * as rewardsActions from '../actions/donate_actions' + +interface Props extends RewardsDonate.ComponentProps { + publisher: RewardsDonate.Publisher +} + +class DonateToSite extends React.Component { + + get actions () { + return this.props.actions + } + + render () { + const { finished, error } = this.props.rewardsDonateData + + return ( + <> + { + !finished && !error + ? + : null + } + { + finished + ? + : null + } + + ) + } +} + +export const mapStateToProps = (state: RewardsDonate.ApplicationState) => ({ + rewardsDonateData: state.rewardsDonateData +}) + +export const mapDispatchToProps = (dispatch: Dispatch) => ({ + actions: bindActionCreators(rewardsActions, dispatch) +}) + +export default connect( + mapStateToProps, + mapDispatchToProps +)(DonateToSite) diff --git a/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx b/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx new file mode 100644 index 000000000000..1f8844c8334b --- /dev/null +++ b/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx @@ -0,0 +1,58 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react' +import { bindActionCreators, Dispatch } from 'redux' +import { connect } from 'react-redux' + +// Components +import Banner from './siteBanner' +import TransientDonationOverlay from './transientDonationOverlay' + +// Utils +import * as rewardsActions from '../actions/donate_actions' + +interface Props extends RewardsDonate.ComponentProps { + publisher: RewardsDonate.Publisher + tweetMetaData: RewardsDonate.TweetMetaData +} + +class DonateToTwitterUser extends React.Component { + + get actions () { + return this.props.actions + } + + render () { + const { finished, error } = this.props.rewardsDonateData + + return ( + <> + { + !finished && !error + ? + : null + } + { + finished + ? + : null + } + + ) + } +} + +export const mapStateToProps = (state: RewardsDonate.ApplicationState) => ({ + rewardsDonateData: state.rewardsDonateData +}) + +export const mapDispatchToProps = (dispatch: Dispatch) => ({ + actions: bindActionCreators(rewardsActions, dispatch) +}) + +export default connect( + mapStateToProps, + mapDispatchToProps +)(DonateToTwitterUser) diff --git a/components/brave_rewards/resources/donate/components/transientDonationOverlay.tsx b/components/brave_rewards/resources/donate/components/transientDonationOverlay.tsx new file mode 100644 index 000000000000..7c9dd6e96b6c --- /dev/null +++ b/components/brave_rewards/resources/donate/components/transientDonationOverlay.tsx @@ -0,0 +1,95 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react' +import { bindActionCreators, Dispatch } from 'redux' +import { connect } from 'react-redux' + +// Components +import DonationOverlay from 'brave-ui/features/rewards/donationOverlay' + +// Utils +import * as rewardsActions from '../actions/donate_actions' + +interface Props extends RewardsDonate.ComponentProps { + publisher: RewardsDonate.Publisher +} + +class TransientDonationOverlay extends React.Component { + + get actions () { + return this.props.actions + } + + onClose = () => { + this.actions.onCloseDialog() + } + + render () { + let domain = '' + let monthlyDate + const { + currentTipAmount, + currentTipRecurring, + reconcileStamp + } = this.props.rewardsDonateData + + const publisher = this.props.publisher + const publisherKey = publisher && publisher.publisherKey + + if (!publisherKey) { + return null + } + + if (currentTipRecurring && reconcileStamp) { + monthlyDate = new Date(reconcileStamp * 1000).toLocaleDateString() + } + + if (publisher.provider && publisher.name) { + domain = publisher.name + } else { + domain = publisherKey + } + + const verified = publisher.verified + let logo = publisher.logo + + const internalFavicon = /^https:\/\/[a-z0-9-]+\.invalid(\/)?$/ + if (internalFavicon.test(publisher.logo)) { + logo = `chrome://favicon/size/160@2x/${publisher.logo}` + } + + if (!verified) { + logo = '' + } + + setTimeout(() => { + this.onClose() + }, 3000) + + return ( + + ) + } +} + +export const mapStateToProps = (state: RewardsDonate.ApplicationState) => ({ + rewardsDonateData: state.rewardsDonateData +}) + +export const mapDispatchToProps = (dispatch: Dispatch) => ({ + actions: bindActionCreators(rewardsActions, dispatch) +}) + +export default connect( + mapStateToProps, + mapDispatchToProps +)(TransientDonationOverlay) diff --git a/components/brave_rewards/resources/extension/brave_rewards/background.ts b/components/brave_rewards/resources/extension/brave_rewards/background.ts index 0927415965ad..b08601effe09 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/background.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/background.ts @@ -79,7 +79,7 @@ chrome.runtime.onConnect.addListener(function () { }) }) -const donateNow = (publisher: string, tweetText: string) => { +const donateToTwitterUser = (publisherKey: string, name: string, screenName: string, tweetText: string) => { chrome.tabs.query({ active: true, windowId: chrome.windows.WINDOW_ID_CURRENT @@ -91,15 +91,16 @@ const donateNow = (publisher: string, tweetText: string) => { if (tabId === undefined) { return } - chrome.braveRewards.donateToSite(tabId, publisher) + chrome.braveRewards.donateToTwitterUser(tabId, publisherKey, name, screenName, tweetText) }) } chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { const action = typeof msg === 'string' ? msg : msg.type switch (action) { - case 'donateNow': { - donateNow(msg.publisher, msg.tweetText) + case 'donateToTwitterUser': { + const publisherKey = `twitter#channel:${msg.userId}` + donateToTwitterUser(publisherKey, msg.name, msg.screenName, msg.tweetText) return false } case 'rewardsEnabled': { diff --git a/components/brave_rewards/resources/extension/brave_rewards/content.ts b/components/brave_rewards/resources/extension/brave_rewards/content.ts index d71bbb52ca27..87d06f1f2922 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/content.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/content.ts @@ -5,14 +5,7 @@ // Utils import { getMessage } from './background/api/locale_api' -interface TweetMetaData { - name: string, - screenName: string, - userId: string, - tweetText: string -} - -const getTweetMetaData = (tweet: Element): TweetMetaData | null => { +const getTweetMetaData = (tweet: Element): RewardsDonate.TweetMetaData | null => { if (!tweet) { return null } @@ -40,13 +33,8 @@ const createBraveTipAction = (tweet: Element) => { braveTipButton.onclick = function (event) { const tweetMetaData = getTweetMetaData(tweet) if (tweetMetaData) { - chrome.runtime.sendMessage({ - type: 'donateNow', - publisher: 'duckduckgo.com', - name: tweetMetaData.name, - screenName: tweetMetaData.screenName, - tweetText: tweetMetaData.tweetText - }) + const msg = { type: 'donateToTwitterUser', ...tweetMetaData } + chrome.runtime.sendMessage(msg) } } braveTipAction.appendChild(braveTipButton) diff --git a/components/brave_rewards/resources/tip/brave_tip.tsx b/components/brave_rewards/resources/tip/brave_tip.tsx index 4a8196a4f41a..c7d10cf7a32c 100644 --- a/components/brave_rewards/resources/tip/brave_tip.tsx +++ b/components/brave_rewards/resources/tip/brave_tip.tsx @@ -32,11 +32,10 @@ window.cr.define('brave_rewards_tip', function () { } const dialogArgsRaw = chrome.getVariableValue('dialogArguments') - let publisherKey + let dialogArgs try { - const args = JSON.parse(dialogArgsRaw) - chrome.send('brave_rewards_tip.getPublisherBanner', [args.publisherKey]) - publisherKey = args.publisherKey + dialogArgs = JSON.parse(dialogArgsRaw) + chrome.send('brave_rewards_tip.getPublisherBanner', [dialogArgs.publisherKey]) } catch (e) { console.error('Error parsing incoming dialog args', dialogArgsRaw, e) } @@ -44,7 +43,7 @@ window.cr.define('brave_rewards_tip', function () { render( - + , document.getElementById('root')) diff --git a/components/brave_rewards/resources/tip/components/app.tsx b/components/brave_rewards/resources/tip/components/app.tsx index 18c7e18f0ccd..93b138eb2f23 100644 --- a/components/brave_rewards/resources/tip/components/app.tsx +++ b/components/brave_rewards/resources/tip/components/app.tsx @@ -7,14 +7,19 @@ import { bindActionCreators, Dispatch } from 'redux' import { connect } from 'react-redux' // Components -import Banner from './siteBanner' -import DonationOverlay from 'brave-ui/features/rewards/donationOverlay' +import DonateToSite from './donateToSite' +import DonateToTwitterUser from './donateToTwitterUser' // Utils import * as rewardsActions from '../actions/tip_actions' -interface Props extends RewardsTip.ComponentProps { +interface TipDialogArgs { publisherKey: string + tweetMetaData?: RewardsDonate.TweetMetaData +} + +interface Props extends RewardsDonate.ComponentProps { + dialogArgs: TipDialogArgs } export class App extends React.Component { @@ -78,34 +83,48 @@ export class App extends React.Component { logo={logo} /> ) + + isTwitterAccount = (publisherKey: string) => { + return /^twitter#channel:[0-9]+$/.test(publisherKey) } render () { - const { finished, error, publishers } = this.props.rewardsDonateData + const { publishers } = this.props.rewardsDonateData if (!publishers) { return null } - const publisher = publishers[this.props.publisherKey] + const publisherKey = this.props.dialogArgs.publisherKey + const publisher = publishers[publisherKey] if (!publisher) { return null } + let donation + if (this.isTwitterAccount(publisherKey)) { + const tweetMetaData = this.props.dialogArgs.tweetMetaData + if (tweetMetaData) { + donation = ( + + ) + } + } else { + donation = ( + + ) + } + return ( - <> - { - !finished && !error - ? - : null - } - { - finished - ? this.generateTipOverlay(publisher) - : null - } - +
+ {donation} +
) } } diff --git a/components/definitions/chromel.d.ts b/components/definitions/chromel.d.ts index cd9f63acae77..0335405127fb 100644 --- a/components/definitions/chromel.d.ts +++ b/components/definitions/chromel.d.ts @@ -15,6 +15,7 @@ declare namespace chrome.dns { declare namespace chrome.braveRewards { const createWallet: () => {} const tipSite: (tabId: number, publisherKey: string) => {} + const tipTwitterUser: (tabId: number, publisherKey: string, name: string, screenName: string, tweetText: string) => {} const getPublisherData: (windowId: number, url: string, faviconUrl: string, publisherBlob: string | undefined) => {} const getWalletProperties: () => {} const getCurrentReport: () => {} diff --git a/components/definitions/rewardsTip.d.ts b/components/definitions/rewardsTip.d.ts index 2247fce7f7b2..3695030b0a14 100644 --- a/components/definitions/rewardsTip.d.ts +++ b/components/definitions/rewardsTip.d.ts @@ -32,6 +32,13 @@ declare namespace RewardsTip { verified: boolean } + interface TweetMetaData { + name: string + screenName: string + userId: string + tweetText: string + } + export interface WalletProperties { balance: number choices: number[] From 95bafd60cf740fa5d7007c4197ae0c231ca9e530 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Fri, 19 Apr 2019 15:47:30 -0400 Subject: [PATCH 05/37] Add SaveTwitterPublisherInfo and call when displaying twitter tip dialog --- browser/extensions/api/brave_rewards_api.cc | 48 +++++++++++++++++-- browser/extensions/api/brave_rewards_api.h | 8 +++- .../browser/ads_service_impl_unittest.cc | 6 +++ .../brave_rewards/browser/rewards_service.h | 8 ++++ .../browser/rewards_service_impl.cc | 24 ++++++++++ .../browser/rewards_service_impl.h | 10 ++++ .../services/bat_ledger/bat_ledger_impl.cc | 31 ++++++++++++ .../services/bat_ledger/bat_ledger_impl.h | 12 +++++ .../public/interfaces/bat_ledger.mojom | 4 ++ .../include/bat/ledger/ledger.h | 7 +++ .../src/bat/ledger/internal/bat_publishers.cc | 2 + .../src/bat/ledger/internal/ledger_impl.cc | 32 +++++++++++++ .../src/bat/ledger/internal/ledger_impl.h | 12 +++++ .../src/bat/ledger/internal/static_values.h | 1 + 14 files changed, 200 insertions(+), 5 deletions(-) diff --git a/browser/extensions/api/brave_rewards_api.cc b/browser/extensions/api/brave_rewards_api.cc index a1e5d2a8fba6..4f0c9bbbd05f 100644 --- a/browser/extensions/api/brave_rewards_api.cc +++ b/browser/extensions/api/brave_rewards_api.cc @@ -27,6 +27,20 @@ using brave_ads::AdsServiceFactory; using brave_rewards::RewardsService; using brave_rewards::RewardsServiceFactory; +namespace { + +std::string GetTwitterProfileURL(const std::string& screen_name) { + return base::StringPrintf("https://twitter.com/%s/", screen_name.c_str()); +} + +std::string GetTwitterProfileImageURL(const std::string& screen_name) { + return base::StringPrintf( + "https://twitter.com/%s/profile_image?size=original", + screen_name.c_str()); +} + +} // namespace + namespace extensions { namespace api { @@ -75,6 +89,11 @@ ExtensionFunction::ResponseAction BraveRewardsTipSiteFunction::Run() { params_dict->SetString("publisherKey", params->publisher_key); ::brave_rewards::OpenTipDialog(contents, std::move(params_dict)); +BraveRewardsDonateToTwitterUserFunction:: + BraveRewardsDonateToTwitterUserFunction() + : weak_factory_(this) { +} + BraveRewardsDonateToTwitterUserFunction:: ~BraveRewardsDonateToTwitterUserFunction() { } @@ -93,30 +112,51 @@ BraveRewardsDonateToTwitterUserFunction::Run() { Error("Cannot donate to Twitter user in a private context")); } + auto* rewards_service = RewardsServiceFactory::GetForProfile(profile); + if (rewards_service) { + AddRef(); + rewards_service->SaveTwitterPublisherInfo( + params->publisher_key, + params->screen_name, + GetTwitterProfileURL(params->screen_name), + GetTwitterProfileImageURL(params->screen_name), + base::Bind(&BraveRewardsDonateToTwitterUserFunction:: + OnTwitterPublisherInfoSaved, + weak_factory_.GetWeakPtr())); + } + + return RespondNow(NoArguments()); +} + +void BraveRewardsDonateToTwitterUserFunction::OnTwitterPublisherInfoSaved() { + std::unique_ptr params( + brave_rewards::DonateToTwitterUser::Params::Create(*args_)); + // Get web contents for this tab content::WebContents* contents = nullptr; if (!ExtensionTabUtil::GetTabById( params->tab_id, - profile, + Profile::FromBrowserContext(browser_context()), include_incognito_information(), nullptr, nullptr, &contents, nullptr)) { - return RespondNow(Error(tabs_constants::kTabNotFoundError, - base::IntToString(params->tab_id))); + return; } auto params_dict = std::make_unique(); params_dict->SetString("publisherKey", params->publisher_key); + auto tweet_metadata_dict = std::make_unique(); tweet_metadata_dict->SetString("name", params->name); tweet_metadata_dict->SetString("screenName", params->screen_name); tweet_metadata_dict->SetString("tweetText", params->tweet_text); params_dict->SetDictionary("tweetMetaData", std::move(tweet_metadata_dict)); + ::brave_rewards::OpenDonationDialog(contents, std::move(params_dict)); - return RespondNow(NoArguments()); + Release(); } BraveRewardsGetPublisherDataFunction::~BraveRewardsGetPublisherDataFunction() { diff --git a/browser/extensions/api/brave_rewards_api.h b/browser/extensions/api/brave_rewards_api.h index 8e17a77c1f95..649cfb11f1cd 100644 --- a/browser/extensions/api/brave_rewards_api.h +++ b/browser/extensions/api/brave_rewards_api.h @@ -9,9 +9,10 @@ #include #include -#include "extensions/browser/extension_function.h" +#include "base/memory/weak_ptr.h" #include "brave/components/brave_rewards/browser/content_site.h" #include "brave/components/brave_rewards/browser/publisher_banner.h" +#include "extensions/browser/extension_function.h" namespace extensions { namespace api { @@ -39,12 +40,17 @@ class BraveRewardsTipSiteFunction : public UIThreadExtensionFunction { class BraveRewardsDonateToTwitterUserFunction : public UIThreadExtensionFunction { public: + BraveRewardsDonateToTwitterUserFunction(); DECLARE_EXTENSION_FUNCTION("braveRewards.donateToTwitterUser", UNKNOWN) protected: ~BraveRewardsDonateToTwitterUserFunction() override; ResponseAction Run() override; + + private: + base::WeakPtrFactory weak_factory_; + void OnTwitterPublisherInfoSaved(); }; class BraveRewardsGetPublisherDataFunction : public UIThreadExtensionFunction { diff --git a/components/brave_ads/browser/ads_service_impl_unittest.cc b/components/brave_ads/browser/ads_service_impl_unittest.cc index f86fb7553a03..6cb459b0fc15 100644 --- a/components/brave_ads/browser/ads_service_impl_unittest.cc +++ b/components/brave_ads/browser/ads_service_impl_unittest.cc @@ -143,6 +143,12 @@ class MockRewardsService : public RewardsService { brave_rewards::RefreshPublisherCallback)); MOCK_METHOD0(GetAllNotifications, const brave_rewards::RewardsNotificationService::RewardsNotificationsMap&()); + MOCK_METHOD5(SaveTwitterPublisherInfo, + void(const std::string&, + const std::string&, + const std::string&, + const std::string&, + brave_rewards::SaveTwitterPublisherInfoCallback)); }; class AdsServiceTest : public testing::Test { diff --git a/components/brave_rewards/browser/rewards_service.h b/components/brave_rewards/browser/rewards_service.h index 0547ffd02318..9eb611b85ff0 100644 --- a/components/brave_rewards/browser/rewards_service.h +++ b/components/brave_rewards/browser/rewards_service.h @@ -77,6 +77,7 @@ using GetPublisherBannerCallback = base::OnceCallback)>; using RefreshPublisherCallback = base::OnceCallback; +using SaveTwitterPublisherInfoCallback = base::Callback; class RewardsService : public KeyedService { public: @@ -206,6 +207,13 @@ class RewardsService : public KeyedService { virtual const RewardsNotificationService::RewardsNotificationsMap& GetAllNotifications() = 0; + virtual void SaveTwitterPublisherInfo( + const std::string& publisher_key, + const std::string& screen_name, + const std::string& url, + const std::string& favicon_url, + SaveTwitterPublisherInfoCallback callback) = 0; + protected: base::ObserverList observers_; diff --git a/components/brave_rewards/browser/rewards_service_impl.cc b/components/brave_rewards/browser/rewards_service_impl.cc index 2355b8dd35ca..751ed9de1c16 100644 --- a/components/brave_rewards/browser/rewards_service_impl.cc +++ b/components/brave_rewards/browser/rewards_service_impl.cc @@ -1132,6 +1132,15 @@ void RewardsServiceImpl::OnPublisherInfoSaved( } } +void RewardsServiceImpl::OnTwitterPublisherInfoSaved( + SaveTwitterPublisherInfoCallback callback, + int result, + const std::string& json_publisher_info) { + if (Connected()) { + callback.Run(); + } +} + void RewardsServiceImpl::SaveActivityInfo( ledger::PublisherInfoPtr publisher_info, ledger::PublisherInfoCallback callback) { @@ -2241,6 +2250,21 @@ void RewardsServiceImpl::SaveRecurringTip( AsWeakPtr())); } +void RewardsServiceImpl::SaveTwitterPublisherInfo( + const std::string& publisher_key, + const std::string& screen_name, + const std::string& url, + const std::string& favicon_url, + SaveTwitterPublisherInfoCallback callback) { + bat_ledger_->SaveTwitterPublisherInfo( + publisher_key, + screen_name, + url, + favicon_url, + base::BindOnce(&RewardsServiceImpl::OnTwitterPublisherInfoSaved, + AsWeakPtr(), callback)); +} + ledger::PublisherInfoList GetRecurringTipsOnFileTaskRunner( PublisherInfoDatabase* backend) { ledger::PublisherInfoList list; diff --git a/components/brave_rewards/browser/rewards_service_impl.h b/components/brave_rewards/browser/rewards_service_impl.h index 3c4990522bbb..5f120fb28ae8 100644 --- a/components/brave_rewards/browser/rewards_service_impl.h +++ b/components/brave_rewards/browser/rewards_service_impl.h @@ -218,6 +218,13 @@ class RewardsServiceImpl : public RewardsService, void SetContributionAmount(const double amount) const override; + void SaveTwitterPublisherInfo( + const std::string& publisher_key, + const std::string& screen_name, + const std::string& url, + const std::string& favicon_url, + SaveTwitterPublisherInfoCallback callback) override; + // Testing methods void SetLedgerEnvForTesting(); void StartAutoContributeForTest(); @@ -483,6 +490,9 @@ class RewardsServiceImpl : public RewardsService, RefreshPublisherCallback callback, const std::string& publisher_key, bool verified); + void OnTwitterPublisherInfoSaved(SaveTwitterPublisherInfoCallback callback, + int result, + const std::string& json_publisher_info); bool Connected() const; void ConnectionClosed(); diff --git a/components/services/bat_ledger/bat_ledger_impl.cc b/components/services/bat_ledger/bat_ledger_impl.cc index eef82fd04a5e..d579153f29a2 100644 --- a/components/services/bat_ledger/bat_ledger_impl.cc +++ b/components/services/bat_ledger/bat_ledger_impl.cc @@ -511,6 +511,37 @@ void BatLedgerImpl::LoadPublisherInfo( std::bind(BatLedgerImpl::OnLoadPublisherInfo, holder, _1, _2)); } +// static +void BatLedgerImpl::OnSaveTwitterPublisherInfo( + CallbackHolder* holder, + ledger::Result result, + std::unique_ptr info) { + std::string publisher; + if (info) { + publisher = info->ToJson(); + } + + if (holder->is_valid()) { + std::move(holder->get()).Run(result, publisher); + } + + delete holder; +} + +void BatLedgerImpl::SaveTwitterPublisherInfo( + const std::string& publisher_key, + const std::string& screen_name, + const std::string& url, + const std::string& favicon_url, + SaveTwitterPublisherInfoCallback callback) { + auto* holder = new CallbackHolder( + AsWeakPtr(), std::move(callback)); + + ledger_->SaveTwitterPublisherInfo( + publisher_key, screen_name, url, favicon_url, + std::bind(BatLedgerImpl::OnSaveTwitterPublisherInfo, holder, _1, _2)); +} + void BatLedgerImpl::OnRefreshPublisher( CallbackHolder* holder, bool verified) { diff --git a/components/services/bat_ledger/bat_ledger_impl.h b/components/services/bat_ledger/bat_ledger_impl.h index f29f3a1b091d..e9f7d4ac3e60 100644 --- a/components/services/bat_ledger/bat_ledger_impl.h +++ b/components/services/bat_ledger/bat_ledger_impl.h @@ -153,6 +153,13 @@ class BatLedgerImpl : public mojom::BatLedger, const std::string& publisher_key, LoadPublisherInfoCallback callback) override; + void SaveTwitterPublisherInfo( + const std::string& publisher_key, + const std::string& screen_name, + const std::string& url, + const std::string& favicon_url, + SaveTwitterPublisherInfoCallback callback) override; + private: void SetCatalogIssuers(const std::string& info) override; void ConfirmAd(const std::string& info) override; @@ -218,6 +225,11 @@ class BatLedgerImpl : public mojom::BatLedger, ledger::Result result, ledger::PublisherInfoPtr info); + static void OnSaveTwitterPublisherInfo( + CallbackHolder* holder, + ledger::Result result, + std::unique_ptr info); + std::unique_ptr bat_ledger_client_mojo_proxy_; std::unique_ptr ledger_; diff --git a/components/services/bat_ledger/public/interfaces/bat_ledger.mojom b/components/services/bat_ledger/public/interfaces/bat_ledger.mojom index 000195a383b9..1f7d55985460 100644 --- a/components/services/bat_ledger/public/interfaces/bat_ledger.mojom +++ b/components/services/bat_ledger/public/interfaces/bat_ledger.mojom @@ -118,6 +118,10 @@ interface BatLedger { RefreshPublisher(string publisher_key) => (bool verified); StartAutoContribute(); + + SaveTwitterPublisherInfo(string publisher_key, string screen_name, + string url, string favicon_url) => (int32 result, + string publisher_info); }; interface BatLedgerClient { diff --git a/vendor/bat-native-ledger/include/bat/ledger/ledger.h b/vendor/bat-native-ledger/include/bat/ledger/ledger.h index 799f15afac62..e6bdfe8578a4 100644 --- a/vendor/bat-native-ledger/include/bat/ledger/ledger.h +++ b/vendor/bat-native-ledger/include/bat/ledger/ledger.h @@ -287,6 +287,13 @@ class LEDGER_EXPORT Ledger { ledger::OnRefreshPublisherCallback callback) = 0; virtual void StartAutoContribute() = 0; + + virtual void SaveTwitterPublisherInfo( + const std::string& publisher_key, + const std::string& screen_name, + const std::string& url, + const std::string& favicon_url, + PublisherInfoCallback callback) = 0; }; } // namespace ledger diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc index f29590fb1934..758425852f5f 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc @@ -68,6 +68,8 @@ std::string getProviderName(const std::string& publisher_id) { return YOUTUBE_MEDIA_TYPE; } else if (publisher_id.find(TWITCH_MEDIA_TYPE) != std::string::npos) { return TWITCH_MEDIA_TYPE; + } else if (publisher_id.find(TWITTER_MEDIA_TYPE) != std::string::npos) { + return TWITTER_MEDIA_TYPE; } return ""; } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc index 82e9d4743780..3ea8a4b78fa7 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc @@ -1500,6 +1500,38 @@ void LedgerImpl::OnRefreshPublisher( callback); } +void LedgerImpl::SaveTwitterPublisherInfo( + const std::string& publisher_key, + const std::string& screen_name, + const std::string& url, + const std::string& favicon_url, + ledger::PublisherInfoCallback callback) { + auto publisher_info = std::make_unique(); + + publisher_info->id = publisher_key; + publisher_info->duration = 0; + publisher_info->name = screen_name; + publisher_info->url = url; + publisher_info->favicon_url = favicon_url; + publisher_info->provider = TWITTER_MEDIA_TYPE; + publisher_info->verified = bat_publishers_->isVerified(publisher_key); + + ledger_client_->SavePublisherInfo( + std::move(publisher_info), + std::bind(&LedgerImpl::OnTwitterPublisherInfoSavedInternal, + this, + _1, + _2, + callback)); +} + +void LedgerImpl::OnTwitterPublisherInfoSavedInternal( + ledger::Result result, + std::unique_ptr publisher_info, + ledger::PublisherInfoCallback callback) { + callback(result, std::move(publisher_info)); +} + scoped_refptr LedgerImpl::GetTaskRunner() { return task_runner_; } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h index 351ce3a79274..3939ca88c0cc 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h @@ -440,6 +440,13 @@ class LedgerImpl : public ledger::Ledger, const std::string& publisher_key, ledger::OnRefreshPublisherCallback callback) override; + void SaveTwitterPublisherInfo( + const std::string& publisher_key, + const std::string& screen_name, + const std::string& url, + const std::string& favicon_url, + ledger::PublisherInfoCallback callback) override; + private: void AddRecurringPayment(const std::string& publisher_id, const double& value) override; @@ -513,6 +520,11 @@ class LedgerImpl : public ledger::Ledger, ledger::Result result, ledger::PublisherInfoPtr info); + void OnTwitterPublisherInfoSavedInternal( + ledger::Result result, + std::unique_ptr publisher_info, + ledger::PublisherInfoCallback callback); + void DownloadPublisherList( ledger::LoadURLCallback callback); diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/static_values.h b/vendor/bat-native-ledger/src/bat/ledger/internal/static_values.h index 9935fd7ca9f8..20d27b259a7b 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/static_values.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/static_values.h @@ -63,6 +63,7 @@ #define YOUTUBE_MEDIA_TYPE "youtube" #define TWITCH_MEDIA_TYPE "twitch" +#define TWITTER_MEDIA_TYPE "twitter" #define YOUTUBE_PROVIDER_URL "https://www.youtube.com/oembed" #define TWITCH_PROVIDER_URL "https://api.twitch.tv/v5/oembed" #define YOUTUBE_TLD "youtube.com" From e8d5a425d57ea6243412cddbb5beb237d84d7bf3 Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Tue, 23 Apr 2019 18:09:27 +0200 Subject: [PATCH 06/37] Moves logic into native ledger --- browser/extensions/api/brave_rewards_api.cc | 39 ++++----- browser/extensions/api/brave_rewards_api.h | 3 +- common/extensions/api/brave_rewards.json | 2 +- .../browser/ads_service_impl_unittest.cc | 9 +- .../brave_rewards/browser/rewards_service.h | 10 +-- .../browser/rewards_service_impl.cc | 46 +++++----- .../browser/rewards_service_impl.h | 11 +-- .../extension/brave_rewards/background.ts | 9 +- components/definitions/chromel.d.ts | 2 +- .../services/bat_ledger/bat_ledger_impl.cc | 23 +++-- .../services/bat_ledger/bat_ledger_impl.h | 14 ++- .../public/interfaces/bat_ledger.mojom | 3 +- vendor/bat-native-ledger/BUILD.gn | 2 + .../include/bat/ledger/ledger.h | 11 ++- .../src/bat/ledger/internal/bat_get_media.cc | 12 ++- .../src/bat/ledger/internal/bat_get_media.h | 6 ++ .../src/bat/ledger/internal/bat_publishers.cc | 2 - .../src/bat/ledger/internal/ledger_impl.cc | 38 ++------ .../src/bat/ledger/internal/ledger_impl.h | 14 +-- .../src/bat/ledger/internal/media/twitter.cc | 86 +++++++++++++++++++ .../src/bat/ledger/internal/media/twitter.h | 42 +++++++++ .../ledger/internal/media/twitter_unittest.cc | 19 ++++ 22 files changed, 260 insertions(+), 143 deletions(-) create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h create mode 100644 vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter_unittest.cc diff --git a/browser/extensions/api/brave_rewards_api.cc b/browser/extensions/api/brave_rewards_api.cc index 4f0c9bbbd05f..0c1c85601106 100644 --- a/browser/extensions/api/brave_rewards_api.cc +++ b/browser/extensions/api/brave_rewards_api.cc @@ -5,6 +5,7 @@ #include "brave/browser/extensions/api/brave_rewards_api.h" +#include #include #include #include @@ -27,20 +28,6 @@ using brave_ads::AdsServiceFactory; using brave_rewards::RewardsService; using brave_rewards::RewardsServiceFactory; -namespace { - -std::string GetTwitterProfileURL(const std::string& screen_name) { - return base::StringPrintf("https://twitter.com/%s/", screen_name.c_str()); -} - -std::string GetTwitterProfileImageURL(const std::string& screen_name) { - return base::StringPrintf( - "https://twitter.com/%s/profile_image?size=original", - screen_name.c_str()); -} - -} // namespace - namespace extensions { namespace api { @@ -115,23 +102,31 @@ BraveRewardsDonateToTwitterUserFunction::Run() { auto* rewards_service = RewardsServiceFactory::GetForProfile(profile); if (rewards_service) { AddRef(); + std::map args; + args["user_id"] = params->user_id; + args["name"] = params->name; + args["screen_name"] = params->screen_name; rewards_service->SaveTwitterPublisherInfo( - params->publisher_key, - params->screen_name, - GetTwitterProfileURL(params->screen_name), - GetTwitterProfileImageURL(params->screen_name), + args, base::Bind(&BraveRewardsDonateToTwitterUserFunction:: - OnTwitterPublisherInfoSaved, + OnTwitterPublisherInfoSaved, weak_factory_.GetWeakPtr())); } return RespondNow(NoArguments()); } -void BraveRewardsDonateToTwitterUserFunction::OnTwitterPublisherInfoSaved() { +void BraveRewardsDonateToTwitterUserFunction::OnTwitterPublisherInfoSaved( + std::unique_ptr<::brave_rewards::ContentSite> publisher_info) { std::unique_ptr params( brave_rewards::DonateToTwitterUser::Params::Create(*args_)); + if (!publisher_info) { + // TODO(nejczdovc): what should we do in this case? + Release(); + return; + } + // Get web contents for this tab content::WebContents* contents = nullptr; if (!ExtensionTabUtil::GetTabById( @@ -146,10 +141,10 @@ void BraveRewardsDonateToTwitterUserFunction::OnTwitterPublisherInfoSaved() { } auto params_dict = std::make_unique(); - params_dict->SetString("publisherKey", params->publisher_key); + params_dict->SetString("publisherKey", publisher_info->id); auto tweet_metadata_dict = std::make_unique(); - tweet_metadata_dict->SetString("name", params->name); + tweet_metadata_dict->SetString("name", publisher_info->name); tweet_metadata_dict->SetString("screenName", params->screen_name); tweet_metadata_dict->SetString("tweetText", params->tweet_text); params_dict->SetDictionary("tweetMetaData", std::move(tweet_metadata_dict)); diff --git a/browser/extensions/api/brave_rewards_api.h b/browser/extensions/api/brave_rewards_api.h index 649cfb11f1cd..b328df04bba6 100644 --- a/browser/extensions/api/brave_rewards_api.h +++ b/browser/extensions/api/brave_rewards_api.h @@ -50,7 +50,8 @@ class BraveRewardsDonateToTwitterUserFunction private: base::WeakPtrFactory weak_factory_; - void OnTwitterPublisherInfoSaved(); + void OnTwitterPublisherInfoSaved( + std::unique_ptr publisher_info); }; class BraveRewardsGetPublisherDataFunction : public UIThreadExtensionFunction { diff --git a/common/extensions/api/brave_rewards.json b/common/extensions/api/brave_rewards.json index 97cdf84f3b5e..a62c2f73e95e 100644 --- a/common/extensions/api/brave_rewards.json +++ b/common/extensions/api/brave_rewards.json @@ -364,7 +364,7 @@ "type": "integer" }, { - "name": "publisherKey", + "name": "userId", "type": "string" }, { diff --git a/components/brave_ads/browser/ads_service_impl_unittest.cc b/components/brave_ads/browser/ads_service_impl_unittest.cc index 6cb459b0fc15..4e46f2361070 100644 --- a/components/brave_ads/browser/ads_service_impl_unittest.cc +++ b/components/brave_ads/browser/ads_service_impl_unittest.cc @@ -143,12 +143,9 @@ class MockRewardsService : public RewardsService { brave_rewards::RefreshPublisherCallback)); MOCK_METHOD0(GetAllNotifications, const brave_rewards::RewardsNotificationService::RewardsNotificationsMap&()); - MOCK_METHOD5(SaveTwitterPublisherInfo, - void(const std::string&, - const std::string&, - const std::string&, - const std::string&, - brave_rewards::SaveTwitterPublisherInfoCallback)); + MOCK_METHOD2(SaveTwitterPublisherInfo, + void(const std::map&, + brave_rewards::SaveMediaInfoCallback)); }; class AdsServiceTest : public testing::Test { diff --git a/components/brave_rewards/browser/rewards_service.h b/components/brave_rewards/browser/rewards_service.h index 9eb611b85ff0..e267764255b1 100644 --- a/components/brave_rewards/browser/rewards_service.h +++ b/components/brave_rewards/browser/rewards_service.h @@ -77,7 +77,8 @@ using GetPublisherBannerCallback = base::OnceCallback)>; using RefreshPublisherCallback = base::OnceCallback; -using SaveTwitterPublisherInfoCallback = base::Callback; +using SaveMediaInfoCallback = + base::OnceCallback)>; class RewardsService : public KeyedService { public: @@ -208,11 +209,8 @@ class RewardsService : public KeyedService { GetAllNotifications() = 0; virtual void SaveTwitterPublisherInfo( - const std::string& publisher_key, - const std::string& screen_name, - const std::string& url, - const std::string& favicon_url, - SaveTwitterPublisherInfoCallback callback) = 0; + const std::map& args, + SaveMediaInfoCallback callback) = 0; protected: base::ObserverList observers_; diff --git a/components/brave_rewards/browser/rewards_service_impl.cc b/components/brave_rewards/browser/rewards_service_impl.cc index 751ed9de1c16..cd9539621f56 100644 --- a/components/brave_rewards/browser/rewards_service_impl.cc +++ b/components/brave_rewards/browser/rewards_service_impl.cc @@ -1132,15 +1132,6 @@ void RewardsServiceImpl::OnPublisherInfoSaved( } } -void RewardsServiceImpl::OnTwitterPublisherInfoSaved( - SaveTwitterPublisherInfoCallback callback, - int result, - const std::string& json_publisher_info) { - if (Connected()) { - callback.Run(); - } -} - void RewardsServiceImpl::SaveActivityInfo( ledger::PublisherInfoPtr publisher_info, ledger::PublisherInfoCallback callback) { @@ -2250,19 +2241,34 @@ void RewardsServiceImpl::SaveRecurringTip( AsWeakPtr())); } +void RewardsServiceImpl::OnTwitterPublisherInfoSaved( + SaveMediaInfoCallback callback, + int result, + const std::string& json_publisher) { + if (Connected()) { + ledger::Result result_converted = static_cast(result); + std::unique_ptr site; + + if (result_converted == ledger::Result::LEDGER_OK) { + ledger::PublisherInfo publisher; + publisher.loadFromJson(json_publisher); + site = std::make_unique + (PublisherInfoToContentSite(publisher)); + } + + std::move(callback).Run(std::move(site)); + } +} + void RewardsServiceImpl::SaveTwitterPublisherInfo( - const std::string& publisher_key, - const std::string& screen_name, - const std::string& url, - const std::string& favicon_url, - SaveTwitterPublisherInfoCallback callback) { - bat_ledger_->SaveTwitterPublisherInfo( - publisher_key, - screen_name, - url, - favicon_url, + const std::map& args, + SaveMediaInfoCallback callback) { + bat_ledger_->SaveMediaInfo( + "twitter", + mojo::MapToFlatMap(args), base::BindOnce(&RewardsServiceImpl::OnTwitterPublisherInfoSaved, - AsWeakPtr(), callback)); + AsWeakPtr(), + std::move(callback))); } ledger::PublisherInfoList GetRecurringTipsOnFileTaskRunner( diff --git a/components/brave_rewards/browser/rewards_service_impl.h b/components/brave_rewards/browser/rewards_service_impl.h index 5f120fb28ae8..b7f8a586b956 100644 --- a/components/brave_rewards/browser/rewards_service_impl.h +++ b/components/brave_rewards/browser/rewards_service_impl.h @@ -219,11 +219,8 @@ class RewardsServiceImpl : public RewardsService, void SetContributionAmount(const double amount) const override; void SaveTwitterPublisherInfo( - const std::string& publisher_key, - const std::string& screen_name, - const std::string& url, - const std::string& favicon_url, - SaveTwitterPublisherInfoCallback callback) override; + const std::map& args, + SaveMediaInfoCallback callback) override; // Testing methods void SetLedgerEnvForTesting(); @@ -490,9 +487,9 @@ class RewardsServiceImpl : public RewardsService, RefreshPublisherCallback callback, const std::string& publisher_key, bool verified); - void OnTwitterPublisherInfoSaved(SaveTwitterPublisherInfoCallback callback, + void OnTwitterPublisherInfoSaved(SaveMediaInfoCallback callback, int result, - const std::string& json_publisher_info); + const std::string& json_publisher); bool Connected() const; void ConnectionClosed(); diff --git a/components/brave_rewards/resources/extension/brave_rewards/background.ts b/components/brave_rewards/resources/extension/brave_rewards/background.ts index b08601effe09..5176f577123e 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/background.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/background.ts @@ -79,7 +79,7 @@ chrome.runtime.onConnect.addListener(function () { }) }) -const donateToTwitterUser = (publisherKey: string, name: string, screenName: string, tweetText: string) => { +const donateToTwitterUser = (userId: string, name: string, screenName: string, tweetText: string) => { chrome.tabs.query({ active: true, windowId: chrome.windows.WINDOW_ID_CURRENT @@ -91,7 +91,7 @@ const donateToTwitterUser = (publisherKey: string, name: string, screenName: str if (tabId === undefined) { return } - chrome.braveRewards.donateToTwitterUser(tabId, publisherKey, name, screenName, tweetText) + chrome.braveRewards.donateToTwitterUser(tabId, userId, name, screenName, tweetText) }) } @@ -99,13 +99,12 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { const action = typeof msg === 'string' ? msg : msg.type switch (action) { case 'donateToTwitterUser': { - const publisherKey = `twitter#channel:${msg.userId}` - donateToTwitterUser(publisherKey, msg.name, msg.screenName, msg.tweetText) + donateToTwitterUser(msg.userId, msg.name, msg.screenName, msg.tweetText) return false } case 'rewardsEnabled': { // Check if rewards is enabled - chrome.braveRewards.getRewardsMainEnabled(function (enabled) { + chrome.braveRewards.getRewardsMainEnabled(function (enabled: boolean) { sendResponse({ enabled: enabled }) }) // Must return true for asynchronous calls to sendResponse diff --git a/components/definitions/chromel.d.ts b/components/definitions/chromel.d.ts index 0335405127fb..7b417285fae3 100644 --- a/components/definitions/chromel.d.ts +++ b/components/definitions/chromel.d.ts @@ -15,7 +15,7 @@ declare namespace chrome.dns { declare namespace chrome.braveRewards { const createWallet: () => {} const tipSite: (tabId: number, publisherKey: string) => {} - const tipTwitterUser: (tabId: number, publisherKey: string, name: string, screenName: string, tweetText: string) => {} + const tipTwitterUser: (tabId: number, userId: string, name: string, screenName: string, tweetText: string) => {} const getPublisherData: (windowId: number, url: string, faviconUrl: string, publisherBlob: string | undefined) => {} const getWalletProperties: () => {} const getCurrentReport: () => {} diff --git a/components/services/bat_ledger/bat_ledger_impl.cc b/components/services/bat_ledger/bat_ledger_impl.cc index d579153f29a2..914a3ca3f207 100644 --- a/components/services/bat_ledger/bat_ledger_impl.cc +++ b/components/services/bat_ledger/bat_ledger_impl.cc @@ -512,8 +512,8 @@ void BatLedgerImpl::LoadPublisherInfo( } // static -void BatLedgerImpl::OnSaveTwitterPublisherInfo( - CallbackHolder* holder, +void BatLedgerImpl::OnSaveMediaInfoCallback( + CallbackHolder* holder, ledger::Result result, std::unique_ptr info) { std::string publisher; @@ -528,18 +528,17 @@ void BatLedgerImpl::OnSaveTwitterPublisherInfo( delete holder; } -void BatLedgerImpl::SaveTwitterPublisherInfo( - const std::string& publisher_key, - const std::string& screen_name, - const std::string& url, - const std::string& favicon_url, - SaveTwitterPublisherInfoCallback callback) { - auto* holder = new CallbackHolder( +void BatLedgerImpl::SaveMediaInfo( + const std::string& type, + const base::flat_map& args, + SaveMediaInfoCallback callback) { + auto* holder = new CallbackHolder( AsWeakPtr(), std::move(callback)); - ledger_->SaveTwitterPublisherInfo( - publisher_key, screen_name, url, favicon_url, - std::bind(BatLedgerImpl::OnSaveTwitterPublisherInfo, holder, _1, _2)); + ledger_->SaveMediaInfo( + type, + mojo::FlatMapToMap(args), + std::bind(BatLedgerImpl::OnSaveMediaInfoCallback, holder, _1, _2)); } void BatLedgerImpl::OnRefreshPublisher( diff --git a/components/services/bat_ledger/bat_ledger_impl.h b/components/services/bat_ledger/bat_ledger_impl.h index e9f7d4ac3e60..61d06f7bd1ff 100644 --- a/components/services/bat_ledger/bat_ledger_impl.h +++ b/components/services/bat_ledger/bat_ledger_impl.h @@ -153,12 +153,10 @@ class BatLedgerImpl : public mojom::BatLedger, const std::string& publisher_key, LoadPublisherInfoCallback callback) override; - void SaveTwitterPublisherInfo( - const std::string& publisher_key, - const std::string& screen_name, - const std::string& url, - const std::string& favicon_url, - SaveTwitterPublisherInfoCallback callback) override; + void SaveMediaInfo( + const std::string& type, + const base::flat_map& args, + SaveMediaInfoCallback callback) override; private: void SetCatalogIssuers(const std::string& info) override; @@ -225,8 +223,8 @@ class BatLedgerImpl : public mojom::BatLedger, ledger::Result result, ledger::PublisherInfoPtr info); - static void OnSaveTwitterPublisherInfo( - CallbackHolder* holder, + static void OnSaveMediaInfoCallback( + CallbackHolder* holder, ledger::Result result, std::unique_ptr info); diff --git a/components/services/bat_ledger/public/interfaces/bat_ledger.mojom b/components/services/bat_ledger/public/interfaces/bat_ledger.mojom index 1f7d55985460..db50b5d74632 100644 --- a/components/services/bat_ledger/public/interfaces/bat_ledger.mojom +++ b/components/services/bat_ledger/public/interfaces/bat_ledger.mojom @@ -119,8 +119,7 @@ interface BatLedger { StartAutoContribute(); - SaveTwitterPublisherInfo(string publisher_key, string screen_name, - string url, string favicon_url) => (int32 result, + SaveMediaInfo(string type, map args) => (int32 result, string publisher_info); }; diff --git a/vendor/bat-native-ledger/BUILD.gn b/vendor/bat-native-ledger/BUILD.gn index 97eb7594f35d..629e23586d86 100644 --- a/vendor/bat-native-ledger/BUILD.gn +++ b/vendor/bat-native-ledger/BUILD.gn @@ -112,6 +112,8 @@ source_set("ledger") { "src/bat/ledger/internal/media/helper.cc", "src/bat/ledger/internal/media/twitch.h", "src/bat/ledger/internal/media/twitch.cc", + "src/bat/ledger/internal/media/twitter.h", + "src/bat/ledger/internal/media/twitter.cc", "src/bat/ledger/internal/media/youtube.h", "src/bat/ledger/internal/media/youtube.cc", "src/bat/ledger/ledger.cc", diff --git a/vendor/bat-native-ledger/include/bat/ledger/ledger.h b/vendor/bat-native-ledger/include/bat/ledger/ledger.h index e6bdfe8578a4..400bc4d8864a 100644 --- a/vendor/bat-native-ledger/include/bat/ledger/ledger.h +++ b/vendor/bat-native-ledger/include/bat/ledger/ledger.h @@ -62,6 +62,8 @@ using GetTransactionHistoryForThisCycleCallback = using GetExcludedPublishersNumberDBCallback = std::function; using OnWalletPropertiesCallback = std::function)>; +using SaveMediaInfoCallback = std::function)>; using OnRefreshPublisherCallback = std::function; @@ -288,12 +290,9 @@ class LEDGER_EXPORT Ledger { virtual void StartAutoContribute() = 0; - virtual void SaveTwitterPublisherInfo( - const std::string& publisher_key, - const std::string& screen_name, - const std::string& url, - const std::string& favicon_url, - PublisherInfoCallback callback) = 0; + virtual void SaveMediaInfo(const std::string& type, + const std::map& data, + ledger::SaveMediaInfoCallback callback) = 0; }; } // namespace ledger diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc index 63be251c70b2..81bff5753fb4 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc @@ -17,7 +17,8 @@ namespace braveledger_bat_get_media { BatGetMedia::BatGetMedia(bat_ledger::LedgerImpl* ledger): ledger_(ledger), media_youtube_(new braveledger_media::MediaYouTube(ledger)), - media_twitch_(new braveledger_media::MediaTwitch(ledger)) { + media_twitch_(new braveledger_media::MediaTwitch(ledger)), + media_twitter_(new braveledger_media::MediaTwitter(ledger)) { } BatGetMedia::~BatGetMedia() {} @@ -101,4 +102,13 @@ void BatGetMedia::OnMediaActivityError(const ledger::VisitData& visit_data, } } +void BatGetMedia::SaveMediaInfo(const std::string& type, + const std::map& data, + ledger::SaveMediaInfoCallback callback) { + if (type == TWITTER_MEDIA_TYPE) { + media_twitter_->SaveMediaInfo(data, callback); + return; + } +} + } // namespace braveledger_bat_get_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h index fd05080149ef..48d5720f5538 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h @@ -12,6 +12,7 @@ #include "bat/ledger/internal/bat_helper.h" #include "bat/ledger/internal/media/twitch.h" +#include "bat/ledger/internal/media/twitter.h" #include "bat/ledger/internal/media/youtube.h" #include "bat/ledger/ledger.h" @@ -40,6 +41,10 @@ class BatGetMedia { const std::string& type, const std::string& publisher_blob); + void SaveMediaInfo(const std::string& type, + const std::map& data, + ledger::SaveMediaInfoCallback callback); + private: void OnMediaActivityError(const ledger::VisitData& visit_data, const std::string& type, @@ -48,6 +53,7 @@ class BatGetMedia { bat_ledger::LedgerImpl* ledger_; // NOT OWNED std::unique_ptr media_youtube_; std::unique_ptr media_twitch_; + std::unique_ptr media_twitter_; }; } // namespace braveledger_bat_get_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc index 758425852f5f..f29590fb1934 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc @@ -68,8 +68,6 @@ std::string getProviderName(const std::string& publisher_id) { return YOUTUBE_MEDIA_TYPE; } else if (publisher_id.find(TWITCH_MEDIA_TYPE) != std::string::npos) { return TWITCH_MEDIA_TYPE; - } else if (publisher_id.find(TWITTER_MEDIA_TYPE) != std::string::npos) { - return TWITTER_MEDIA_TYPE; } return ""; } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc index 3ea8a4b78fa7..589b484d6ca4 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc @@ -1500,40 +1500,14 @@ void LedgerImpl::OnRefreshPublisher( callback); } -void LedgerImpl::SaveTwitterPublisherInfo( - const std::string& publisher_key, - const std::string& screen_name, - const std::string& url, - const std::string& favicon_url, - ledger::PublisherInfoCallback callback) { - auto publisher_info = std::make_unique(); - - publisher_info->id = publisher_key; - publisher_info->duration = 0; - publisher_info->name = screen_name; - publisher_info->url = url; - publisher_info->favicon_url = favicon_url; - publisher_info->provider = TWITTER_MEDIA_TYPE; - publisher_info->verified = bat_publishers_->isVerified(publisher_key); - - ledger_client_->SavePublisherInfo( - std::move(publisher_info), - std::bind(&LedgerImpl::OnTwitterPublisherInfoSavedInternal, - this, - _1, - _2, - callback)); -} - -void LedgerImpl::OnTwitterPublisherInfoSavedInternal( - ledger::Result result, - std::unique_ptr publisher_info, - ledger::PublisherInfoCallback callback) { - callback(result, std::move(publisher_info)); -} - scoped_refptr LedgerImpl::GetTaskRunner() { return task_runner_; } +void LedgerImpl::SaveMediaInfo(const std::string& type, + const std::map& data, + ledger::SaveMediaInfoCallback callback) { + bat_get_media_->SaveMediaInfo(type, data, callback); +} + } // namespace bat_ledger diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h index 3939ca88c0cc..e75e642d9176 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h @@ -440,12 +440,9 @@ class LedgerImpl : public ledger::Ledger, const std::string& publisher_key, ledger::OnRefreshPublisherCallback callback) override; - void SaveTwitterPublisherInfo( - const std::string& publisher_key, - const std::string& screen_name, - const std::string& url, - const std::string& favicon_url, - ledger::PublisherInfoCallback callback) override; + void SaveMediaInfo(const std::string& type, + const std::map& data, + ledger::SaveMediaInfoCallback callback) override; private: void AddRecurringPayment(const std::string& publisher_id, @@ -520,11 +517,6 @@ class LedgerImpl : public ledger::Ledger, ledger::Result result, ledger::PublisherInfoPtr info); - void OnTwitterPublisherInfoSavedInternal( - ledger::Result result, - std::unique_ptr publisher_info, - ledger::PublisherInfoCallback callback); - void DownloadPublisherList( ledger::LoadURLCallback callback); diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc new file mode 100644 index 000000000000..554afff23fe9 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc @@ -0,0 +1,86 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include +#include +#include + +#include "base/strings/stringprintf.h" +#include "bat/ledger/internal/ledger_impl.h" +#include "bat/ledger/internal/media/helper.h" +#include "bat/ledger/internal/media/twitter.h" + +using std::placeholders::_1; +using std::placeholders::_2; +using std::placeholders::_3; + +namespace braveledger_media { + +MediaTwitter::MediaTwitter(bat_ledger::LedgerImpl* ledger): + ledger_(ledger) { +} + +MediaTwitter::~MediaTwitter() { +} + +// static +std::string MediaTwitter::GetProfileURL(const std::string& screen_name) { + return base::StringPrintf("https://twitter.com/%s/", screen_name.c_str()); +} + +// static +std::string MediaTwitter::GetProfileImageURL(const std::string& screen_name) { + return base::StringPrintf( + "https://twitter.com/%s/profile_image?size=original", + screen_name.c_str()); +} + +// static +std::string MediaTwitter::GetPublisherKey(const std::string& key) { + return (std::string)TWITTER_MEDIA_TYPE + "#channel:" + key; +} + +void MediaTwitter::SaveMediaInfo(const std::map& data, + ledger::SaveMediaInfoCallback callback) { + auto user_id = data.find("user_id"); + auto screen_name = data.find("screen_name"); + if (user_id == data.end() || screen_name == data.end()) { + callback(ledger::Result::LEDGER_ERROR, nullptr); + return; + } + + const std::string publisher_key = GetPublisherKey(user_id->second); + const std::string url = GetProfileURL(screen_name->second); + const std::string favicon_url = GetProfileImageURL(screen_name->second); + + auto name = data.find("name"); + std::string publisher_name = screen_name->second; + if (name != data.end()) { + publisher_name = name->second; + } + + ledger::VisitData visit_data; + visit_data.favicon_url = favicon_url; + visit_data.provider = TWITTER_MEDIA_TYPE; + visit_data.name = publisher_name; + visit_data.url = url; + + // TODO(nejczdovc): SaveMediaVisit needs to have callback + ledger_->SaveMediaVisit(publisher_key, + visit_data, + 0, + 0); + + // Only temp until we create callback + auto publisher_info = std::make_unique(); + publisher_info->id = publisher_key; + publisher_info->name = publisher_name; + publisher_info->favicon_url = favicon_url; + publisher_info->provider = TWITTER_MEDIA_TYPE; + callback(ledger::Result::LEDGER_OK, std::move(publisher_info)); +} + +} // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h new file mode 100644 index 000000000000..92344f7b68a7 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVELEDGER_MEDIA_TWITTER_H_ +#define BRAVELEDGER_MEDIA_TWITTER_H_ + +#include +#include + +#include "base/gtest_prod_util.h" +#include "bat/ledger/ledger.h" + +namespace bat_ledger { +class LedgerImpl; +} + +namespace braveledger_media { + +class MediaTwitter : public ledger::LedgerCallbackHandler { + public: + explicit MediaTwitter(bat_ledger::LedgerImpl* ledger); + + ~MediaTwitter() override; + + void SaveMediaInfo(const std::map& data, + ledger::SaveMediaInfoCallback callback); + + private: + static std::string GetProfileURL(const std::string& screen_name); + + static std::string GetProfileImageURL(const std::string& screen_name); + + static std::string GetPublisherKey(const std::string& key); + + bat_ledger::LedgerImpl* ledger_; // NOT OWNED +}; + +} // namespace braveledger_media + +#endif // BRAVELEDGER_MEDIA_TWITTER_H_ diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter_unittest.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter_unittest.cc new file mode 100644 index 000000000000..63845bd66324 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter_unittest.cc @@ -0,0 +1,19 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "bat/ledger/internal/media/twitter.h" +#include "testing/gtest/include/gtest/gtest.h" + +// npm run test -- brave_unit_tests --filter=MediaTwitterTest.* + +namespace braveledger_media { + +class MediaTwitterTest : public testing::Test { +}; + +TEST(MediaTwitterTest, GetProfileURL) { +} + +} // namespace braveledger_media From f8c05a0d891992fe8c1adee8eae241044000d89f Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Wed, 24 Apr 2019 14:17:14 -0400 Subject: [PATCH 07/37] Add tweetId to TweetMetaData and pass it to donate dialog --- browser/extensions/api/brave_rewards_api.cc | 1 + common/extensions/api/brave_rewards.json | 4 ++++ .../resources/extension/brave_rewards/background.ts | 6 +++--- .../resources/extension/brave_rewards/content.ts | 1 + components/definitions/chromel.d.ts | 2 +- components/definitions/rewardsTip.d.ts | 1 + 6 files changed, 11 insertions(+), 4 deletions(-) diff --git a/browser/extensions/api/brave_rewards_api.cc b/browser/extensions/api/brave_rewards_api.cc index 0c1c85601106..26f9cdee5f4b 100644 --- a/browser/extensions/api/brave_rewards_api.cc +++ b/browser/extensions/api/brave_rewards_api.cc @@ -146,6 +146,7 @@ void BraveRewardsDonateToTwitterUserFunction::OnTwitterPublisherInfoSaved( auto tweet_metadata_dict = std::make_unique(); tweet_metadata_dict->SetString("name", publisher_info->name); tweet_metadata_dict->SetString("screenName", params->screen_name); + tweet_metadata_dict->SetString("tweetId", params->tweet_id); tweet_metadata_dict->SetString("tweetText", params->tweet_text); params_dict->SetDictionary("tweetMetaData", std::move(tweet_metadata_dict)); diff --git a/common/extensions/api/brave_rewards.json b/common/extensions/api/brave_rewards.json index a62c2f73e95e..1b98f63176ec 100644 --- a/common/extensions/api/brave_rewards.json +++ b/common/extensions/api/brave_rewards.json @@ -375,6 +375,10 @@ "name": "screenName", "type": "string" }, + { + "name": "tweetId", + "type": "string" + }, { "name": "tweetText", "type": "string" diff --git a/components/brave_rewards/resources/extension/brave_rewards/background.ts b/components/brave_rewards/resources/extension/brave_rewards/background.ts index 5176f577123e..2648b53ce672 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/background.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/background.ts @@ -79,7 +79,7 @@ chrome.runtime.onConnect.addListener(function () { }) }) -const donateToTwitterUser = (userId: string, name: string, screenName: string, tweetText: string) => { +const donateToTwitterUser = (userId: string, name: string, screenName: string, tweetId: string, tweetText: string) => { chrome.tabs.query({ active: true, windowId: chrome.windows.WINDOW_ID_CURRENT @@ -91,7 +91,7 @@ const donateToTwitterUser = (userId: string, name: string, screenName: string, t if (tabId === undefined) { return } - chrome.braveRewards.donateToTwitterUser(tabId, userId, name, screenName, tweetText) + chrome.braveRewards.donateToTwitterUser(tabId, userId, name, screenName, tweetId, tweetText) }) } @@ -99,7 +99,7 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { const action = typeof msg === 'string' ? msg : msg.type switch (action) { case 'donateToTwitterUser': { - donateToTwitterUser(msg.userId, msg.name, msg.screenName, msg.tweetText) + donateToTwitterUser(msg.userId, msg.name, msg.screenName, msg.tweetId, msg.tweetText) return false } case 'rewardsEnabled': { diff --git a/components/brave_rewards/resources/extension/brave_rewards/content.ts b/components/brave_rewards/resources/extension/brave_rewards/content.ts index 87d06f1f2922..20632d5c1a98 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/content.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/content.ts @@ -17,6 +17,7 @@ const getTweetMetaData = (tweet: Element): RewardsDonate.TweetMetaData | null => name: tweet.getAttribute('data-name') || '', screenName: tweet.getAttribute('data-screen-name') || '', userId: tweet.getAttribute('data-user-id') || '', + tweetId: tweet.getAttribute('data-tweet-id') || '', tweetText: tweetTextElements[0].textContent || '' } } diff --git a/components/definitions/chromel.d.ts b/components/definitions/chromel.d.ts index 7b417285fae3..e21a42c19dda 100644 --- a/components/definitions/chromel.d.ts +++ b/components/definitions/chromel.d.ts @@ -15,7 +15,7 @@ declare namespace chrome.dns { declare namespace chrome.braveRewards { const createWallet: () => {} const tipSite: (tabId: number, publisherKey: string) => {} - const tipTwitterUser: (tabId: number, userId: string, name: string, screenName: string, tweetText: string) => {} + const tipTwitterUser: (tabId: number, userId: string, name: string, screenName: string, tweetId: string, tweetText: string) => {} const getPublisherData: (windowId: number, url: string, faviconUrl: string, publisherBlob: string | undefined) => {} const getWalletProperties: () => {} const getCurrentReport: () => {} diff --git a/components/definitions/rewardsTip.d.ts b/components/definitions/rewardsTip.d.ts index 3695030b0a14..46b159fe8333 100644 --- a/components/definitions/rewardsTip.d.ts +++ b/components/definitions/rewardsTip.d.ts @@ -36,6 +36,7 @@ declare namespace RewardsTip { name: string screenName: string userId: string + tweetId: string tweetText: string } From 35acf1e1f505babd58ee51b872e1336b6ad40afb Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Wed, 24 Apr 2019 14:33:13 -0400 Subject: [PATCH 08/37] Allow retweeting tip --- browser/ui/webui/brave_tip_ui.cc | 53 +++++++++++++++++-- browser/ui/webui/brave_webui_source.cc | 3 ++ .../donate/components/donateToSite.tsx | 2 +- .../donate/components/donateToTwitterUser.tsx | 16 +++++- .../components/transientDonationOverlay.tsx | 11 ++-- .../resources/tip/actions/tip_actions.ts | 4 ++ .../resources/tip/constants/tip_types.ts | 1 + .../resources/tip/reducers/tip_reducer.ts | 5 ++ .../resources/brave_components_strings.grd | 6 +++ 9 files changed, 90 insertions(+), 11 deletions(-) diff --git a/browser/ui/webui/brave_tip_ui.cc b/browser/ui/webui/brave_tip_ui.cc index 032ae04f772f..c2ffa5f06657 100644 --- a/browser/ui/webui/brave_tip_ui.cc +++ b/browser/ui/webui/brave_tip_ui.cc @@ -10,26 +10,30 @@ #include #include "base/memory/weak_ptr.h" +#include "base/strings/utf_string_conversions.h" #include "brave/browser/brave_browser_process_impl.h" #include "brave/browser/ui/webui/basic_ui.h" #include "brave/common/pref_names.h" #include "brave/common/webui_url_constants.h" +#include "brave/components/brave_rewards/browser/publisher_banner.h" +#include "brave/components/brave_rewards/browser/rewards_service.h" +#include "brave/components/brave_rewards/browser/rewards_service_factory.h" +#include "brave/components/brave_rewards/browser/rewards_service_observer.h" #include "brave/components/brave_rewards/resources/grit/brave_rewards_resources.h" #include "brave/components/brave_rewards/resources/grit/brave_tip_generated_map.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/chrome_pages.h" +#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" #include "chrome/browser/ui/webui/constrained_web_dialog_ui.h" #include "chrome/common/pref_names.h" #include "chrome/common/webui_url_constants.h" +#include "components/grit/brave_components_strings.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_service.h" #include "content/public/browser/web_ui_data_source.h" #include "content/public/browser/web_ui_message_handler.h" -#include "brave/components/brave_rewards/browser/rewards_service.h" -#include "brave/components/brave_rewards/browser/rewards_service_factory.h" -#include "brave/components/brave_rewards/browser/rewards_service_observer.h" -#include "brave/components/brave_rewards/browser/publisher_banner.h" +#include "ui/base/l10n/l10n_util.h" using content::WebUIMessageHandler; @@ -56,6 +60,7 @@ class RewardsTipDOMHandler : public WebUIMessageHandler, void OnReconcileStamp(uint64_t reconcile_stamp); void OnGetRecurringTips( std::unique_ptr list); + void TweetTip(const base::ListValue *args); void OnPublisherBanner( std::unique_ptr banner); @@ -115,6 +120,10 @@ void RewardsTipDOMHandler::RegisterMessages() { "brave_rewards_tip.getReconcileStamp", base::BindRepeating(&RewardsTipDOMHandler::GetReconcileStamp, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "brave_rewards_donate.tweetTip", + base::BindRepeating(&RewardsDonateDOMHandler::TweetTip, + base::Unretained(this))); } void RewardsTipDOMHandler::GetPublisherTipData( @@ -331,5 +340,39 @@ void RewardsTipDOMHandler::OnRecurringTipSaved( "brave_rewards_tip.recurringTipSaved", base::Value(success)); } -BraveTipUI::~BraveTipUI() { +BraveDonateUI::~BraveTipUI() { +} + +void RewardsTipDOMHandler::TweetTip(const base::ListValue *args) { + DCHECK_EQ(args->GetSize(), 1U); + const base::DictionaryValue* tweet_metadata_dict = nullptr; + if (!args->GetDictionary(0, &tweet_metadata_dict)) + return; + + // Retrieve the relevant tweet metadata from arguments. + std::string screen_name; + if (!tweet_metadata_dict->GetString("screenName", &screen_name)) + return; + std::string tweet_id; + if (!tweet_metadata_dict->GetString("tweetId", &tweet_id)) + return; + + // Construct the Twitter intent URL for the tip compliment. + std::string comment = l10n_util::GetStringFUTF8( + IDS_BRAVE_REWARDS_LOCAL_COMPLIMENT_TWEET, base::UTF8ToUTF16(screen_name)); + std::string quoted_tweet_url = + base::StringPrintf("https://twitter.com/%s/status/%s", + screen_name.c_str(), tweet_id.c_str()); + std::string intent_url = + base::StringPrintf("https://twitter.com/intent/tweet?url=%s&text=%s", + quoted_tweet_url.c_str(), comment.c_str()); + + // Open a new tab with the prepopulated tweet ready to post. + GURL gurl(intent_url); + chrome::ScopedTabbedBrowserDisplayer browser_displayer( + Profile::FromWebUI(web_ui())); + content::OpenURLParams open_url_params( + gurl, content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false); + browser_displayer.browser()->OpenURL(open_url_params); } diff --git a/browser/ui/webui/brave_webui_source.cc b/browser/ui/webui/brave_webui_source.cc index 156c7bb40481..fbca93ab1f10 100644 --- a/browser/ui/webui/brave_webui_source.cc +++ b/browser/ui/webui/brave_webui_source.cc @@ -569,9 +569,12 @@ void CustomizeWebUIHTMLSource(const std::string &name, { "sendDonation", IDS_BRAVE_UI_SEND_DONATION }, { "siteBannerNoticeNote", IDS_BRAVE_UI_SITE_BANNER_NOTICE_NOTE }, { "siteBannerNoticeText", IDS_BRAVE_UI_SITE_BANNER_NOTICE_TEXT }, + { "tellOthers", IDS_BRAVE_UI_TELL_OTHERS }, { "thankYou", IDS_BRAVE_UI_THANK_YOU }, { "tipText", IDS_BRAVE_UI_TIP_TEXT }, { "tokens", IDS_BRAVE_UI_TOKENS }, + { "tweetNow", IDS_BRAVE_UI_TWEET_NOW }, + { "tweetTipTitle", IDS_BRAVE_UI_TWEET_TIP_TITLE }, { "unVerifiedTextMore", IDS_BRAVE_UI_SITE_UNVERIFIED_TEXT_MORE }, { "walletBalance", IDS_BRAVE_UI_WALLET_BALANCE }, { "welcome", IDS_BRAVE_UI_WELCOME }, diff --git a/components/brave_rewards/resources/donate/components/donateToSite.tsx b/components/brave_rewards/resources/donate/components/donateToSite.tsx index 43e1a3316453..4d0c3e233fa6 100644 --- a/components/brave_rewards/resources/donate/components/donateToSite.tsx +++ b/components/brave_rewards/resources/donate/components/donateToSite.tsx @@ -35,7 +35,7 @@ class DonateToSite extends React.Component { } { finished - ? + ? : null } diff --git a/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx b/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx index 1f8844c8334b..e11ebb2358e2 100644 --- a/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx +++ b/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx @@ -12,6 +12,7 @@ import TransientDonationOverlay from './transientDonationOverlay' // Utils import * as rewardsActions from '../actions/donate_actions' +import { getLocale } from '../../../../common/locale' interface Props extends RewardsDonate.ComponentProps { publisher: RewardsDonate.Publisher @@ -24,19 +25,30 @@ class DonateToTwitterUser extends React.Component { return this.props.actions } + onTweet = () => { + this.actions.onTweet(this.props.tweetMetaData) + this.actions.onCloseDialog() + } + render () { const { finished, error } = this.props.rewardsDonateData + const publisher = this.props.publisher + return ( <> { !finished && !error - ? + ? : null } { finished - ? + ? : null } diff --git a/components/brave_rewards/resources/donate/components/transientDonationOverlay.tsx b/components/brave_rewards/resources/donate/components/transientDonationOverlay.tsx index 7c9dd6e96b6c..8cd0e6edae72 100644 --- a/components/brave_rewards/resources/donate/components/transientDonationOverlay.tsx +++ b/components/brave_rewards/resources/donate/components/transientDonationOverlay.tsx @@ -14,6 +14,8 @@ import * as rewardsActions from '../actions/donate_actions' interface Props extends RewardsDonate.ComponentProps { publisher: RewardsDonate.Publisher + timeout: number + onTweet?: () => void } class TransientDonationOverlay extends React.Component { @@ -64,13 +66,16 @@ class TransientDonationOverlay extends React.Component { logo = '' } - setTimeout(() => { - this.onClose() - }, 3000) + if (this.props.timeout) { + setTimeout(() => { + this.onClose() + }, this.props.timeout) + } return ( action(types.ON_CLOSE_DIALOG) +export const onTweet = (tweetMetaData: RewardsTip.TweetMetaData) => action(types.ON_TWEET, { + tweetMetaData +}) + export const onPublisherBanner = (data: RewardsTip.Publisher) => action(types.ON_PUBLISHER_BANNER, { data }) diff --git a/components/brave_rewards/resources/tip/constants/tip_types.ts b/components/brave_rewards/resources/tip/constants/tip_types.ts index e2a37d2f2cee..fc4e7189cb92 100644 --- a/components/brave_rewards/resources/tip/constants/tip_types.ts +++ b/components/brave_rewards/resources/tip/constants/tip_types.ts @@ -4,6 +4,7 @@ export const enum types { ON_CLOSE_DIALOG = '@@rewards/ON_CLOSE_DIALOG', + ON_TWEET = '@@rewards/ON_TWEET', ON_PUBLISHER_BANNER = '@@rewards/ON_PUBLISHER_BANNER', ON_WALLET_PROPERTIES = '@@rewards/ON_WALLET_PROPERTIES', GET_WALLET_PROPERTIES = '@@rewards/GET_WALLET_PROPERTIES', diff --git a/components/brave_rewards/resources/tip/reducers/tip_reducer.ts b/components/brave_rewards/resources/tip/reducers/tip_reducer.ts index fb361245ab95..2dbd40b799cc 100644 --- a/components/brave_rewards/resources/tip/reducers/tip_reducer.ts +++ b/components/brave_rewards/resources/tip/reducers/tip_reducer.ts @@ -31,6 +31,11 @@ const publishersReducer: Reducer = (state: RewardsTip.State = state.currentTipRecurring = false chrome.send('dialogClose') break + case types.ON_TWEET: + chrome.send('brave_rewards_donate.tweetTip', [ + payload.tweetMetaData + ]) + break case types.ON_PUBLISHER_BANNER: { state = { ...state } if (!state.publishers) { diff --git a/components/resources/brave_components_strings.grd b/components/resources/brave_components_strings.grd index 104038ad9b07..2fb1fd96c04b 100644 --- a/components/resources/brave_components_strings.grd +++ b/components/resources/brave_components_strings.grd @@ -259,6 +259,9 @@ Recover now! Sorry, it appears that this grant has already been claimed. Next monthly tip date + + I just tipped @$1user using the Brave Browser. Check it out at https://brave.com/tips. + Amount: @@ -457,6 +460,7 @@ Settings site sites + Tell others about your tip. Thank you You've just sent a tip to: Tip on like @@ -471,6 +475,8 @@ Turn on Ads This enables both ads and automatic contributions. You can turn them on or off separately at any time. Activate Rewards + Tweet Now + Tip @{{ user }} for their tweet: Type Brave Verified Publisher View Monthly Statement for Details From a5db4df0335d8890687186bc423993b6f44e3c26 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Wed, 24 Apr 2019 14:37:07 -0400 Subject: [PATCH 09/37] Include style info directly in content script --- .../resources/extension/brave_rewards/content.css | 6 ------ .../resources/extension/brave_rewards/content.ts | 6 +++++- .../resources/extension/brave_rewards/manifest.json | 6 ------ .../resources/extension/extension_static_resources.grd | 1 - 4 files changed, 5 insertions(+), 14 deletions(-) delete mode 100644 components/brave_rewards/resources/extension/brave_rewards/content.css diff --git a/components/brave_rewards/resources/extension/brave_rewards/content.css b/components/brave_rewards/resources/extension/brave_rewards/content.css deleted file mode 100644 index 1db9001a13c9..000000000000 --- a/components/brave_rewards/resources/extension/brave_rewards/content.css +++ /dev/null @@ -1,6 +0,0 @@ -.brave-tip-icon { - margin-top: 5px; - content: url('chrome-extension://__MSG_@@extension_id__/img/bat-16.png'); - width: 16px; - height: 16px; -} diff --git a/components/brave_rewards/resources/extension/brave_rewards/content.ts b/components/brave_rewards/resources/extension/brave_rewards/content.ts index 20632d5c1a98..3d9be2691793 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/content.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/content.ts @@ -48,7 +48,11 @@ const createBraveTipAction = (tweet: Element) => { // Create the tip icon const braveTipIcon = document.createElement('span') - braveTipIcon.className = 'Icon Icon--medium brave-tip-icon' + braveTipIcon.className = 'Icon Icon--medium' + braveTipIcon.style.content = 'url(\'data:image/svg+xml;utf8,BAT_icon\')' + braveTipIcon.style.marginTop = '5px' + braveTipIcon.style.width = '16px' + braveTipIcon.style.height = '16px' braveTipIconContainer.appendChild(braveTipIcon) // Create the tip action count (typically used to present a counter diff --git a/components/brave_rewards/resources/extension/brave_rewards/manifest.json b/components/brave_rewards/resources/extension/brave_rewards/manifest.json index d0325b9fb276..66e40e7bef56 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/manifest.json +++ b/components/brave_rewards/resources/extension/brave_rewards/manifest.json @@ -30,17 +30,11 @@ "matches": [ "https://*.twitter.com/*" ], - "css": [ - "content.css" - ], "js": [ "out/brave_rewards_panel_content.bundle.js" ] } ], - "web_accessible_resources": [ - "img/bat-16.png" - ], "icons": { "16": "img/bat-16.png", "32": "img/bat-32.png", diff --git a/components/brave_rewards/resources/extension/extension_static_resources.grd b/components/brave_rewards/resources/extension/extension_static_resources.grd index cb9bedde0749..143d90f1450f 100644 --- a/components/brave_rewards/resources/extension/extension_static_resources.grd +++ b/components/brave_rewards/resources/extension/extension_static_resources.grd @@ -13,7 +13,6 @@ - From 3daca99136782f4b79bef379c922fe95d3c6c8e6 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Wed, 24 Apr 2019 15:47:14 -0400 Subject: [PATCH 10/37] Pass tweet metadata to SiteBanner --- .../resources/donate/components/donateToTwitterUser.tsx | 3 +++ components/brave_rewards/resources/tip/components/app.tsx | 3 ++- .../brave_rewards/resources/tip/components/siteBanner.tsx | 8 +++++++- components/brave_rewards/resources/tip/utils.ts | 4 ++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx b/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx index e11ebb2358e2..d8df9c4727d1 100644 --- a/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx +++ b/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx @@ -34,6 +34,9 @@ class DonateToTwitterUser extends React.Component { const { finished, error } = this.props.rewardsDonateData const publisher = this.props.publisher + const tweetMetaData = this.props.tweetMetaData + publisher.title = getLocale('tweetTipTitle', { user: tweetMetaData.screenName }) + publisher.description = tweetMetaData.tweetText return ( <> diff --git a/components/brave_rewards/resources/tip/components/app.tsx b/components/brave_rewards/resources/tip/components/app.tsx index 93b138eb2f23..9774e140a8b0 100644 --- a/components/brave_rewards/resources/tip/components/app.tsx +++ b/components/brave_rewards/resources/tip/components/app.tsx @@ -12,6 +12,7 @@ import DonateToTwitterUser from './donateToTwitterUser' // Utils import * as rewardsActions from '../actions/tip_actions' +import { isTwitterAccount } from '../utils' interface TipDialogArgs { publisherKey: string @@ -103,7 +104,7 @@ export class App extends React.Component { } let donation - if (this.isTwitterAccount(publisherKey)) { + if (isTwitterAccount(publisherKey)) { const tweetMetaData = this.props.dialogArgs.tweetMetaData if (tweetMetaData) { donation = ( diff --git a/components/brave_rewards/resources/tip/components/siteBanner.tsx b/components/brave_rewards/resources/tip/components/siteBanner.tsx index c57136ab91d2..abeaa1435570 100644 --- a/components/brave_rewards/resources/tip/components/siteBanner.tsx +++ b/components/brave_rewards/resources/tip/components/siteBanner.tsx @@ -160,7 +160,13 @@ class Banner extends React.Component { learnMoreNotice={'https://brave.com/faq-rewards/#unclaimed-funds'} addFundsLink={this.addFundsLink} > - {publisher.description} + { + utils.isTwitterAccount(publisher.publisherKey) + ?
+ {publisher.description} +
+ : publisher.description + } ) } diff --git a/components/brave_rewards/resources/tip/utils.ts b/components/brave_rewards/resources/tip/utils.ts index caf1153ca8ec..3ab3c9f3f06c 100644 --- a/components/brave_rewards/resources/tip/utils.ts +++ b/components/brave_rewards/resources/tip/utils.ts @@ -32,3 +32,7 @@ export const convertProbiToFixed = (probi: string, places: number = 1) => { return result } + +export const isTwitterAccount = (publisherKey: string) => { + return /^twitter#channel:[0-9]+$/.test(publisherKey) +} From 22dc33f06e6eac91d13f47ae55f54b98513fe35a Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Fri, 26 Apr 2019 12:50:32 -0400 Subject: [PATCH 11/37] Add timestamp to TweetMetaData and refactor passing of data --- browser/extensions/api/brave_rewards_api.cc | 23 ++++++---- common/extensions/api/brave_rewards.json | 46 +++++++++++-------- .../extension/brave_rewards/background.ts | 6 +-- .../extension/brave_rewards/content.ts | 8 +++- components/definitions/chromel.d.ts | 2 +- components/definitions/rewardsTip.d.ts | 1 + 6 files changed, 54 insertions(+), 32 deletions(-) diff --git a/browser/extensions/api/brave_rewards_api.cc b/browser/extensions/api/brave_rewards_api.cc index 26f9cdee5f4b..fc0fce74aa39 100644 --- a/browser/extensions/api/brave_rewards_api.cc +++ b/browser/extensions/api/brave_rewards_api.cc @@ -103,9 +103,9 @@ BraveRewardsDonateToTwitterUserFunction::Run() { if (rewards_service) { AddRef(); std::map args; - args["user_id"] = params->user_id; - args["name"] = params->name; - args["screen_name"] = params->screen_name; + args["user_id"] = params->tweet_meta_data.user_id; + args["name"] = params->tweet_meta_data.name; + args["screen_name"] = params->tweet_meta_data.screen_name; rewards_service->SaveTwitterPublisherInfo( args, base::Bind(&BraveRewardsDonateToTwitterUserFunction:: @@ -143,12 +143,17 @@ void BraveRewardsDonateToTwitterUserFunction::OnTwitterPublisherInfoSaved( auto params_dict = std::make_unique(); params_dict->SetString("publisherKey", publisher_info->id); - auto tweet_metadata_dict = std::make_unique(); - tweet_metadata_dict->SetString("name", publisher_info->name); - tweet_metadata_dict->SetString("screenName", params->screen_name); - tweet_metadata_dict->SetString("tweetId", params->tweet_id); - tweet_metadata_dict->SetString("tweetText", params->tweet_text); - params_dict->SetDictionary("tweetMetaData", std::move(tweet_metadata_dict)); + auto tweet_meta_data_dict = std::make_unique(); + tweet_meta_data_dict->SetString("name", publisher_info->name); + tweet_meta_data_dict->SetString("screenName", + params->tweet_meta_data.screen_name); + tweet_meta_data_dict->SetString("userId", params->tweet_meta_data.user_id); + tweet_meta_data_dict->SetString("tweetId", params->tweet_meta_data.tweet_id); + tweet_meta_data_dict->SetInteger("tweetTimestamp", + params->tweet_meta_data.tweet_timestamp); + tweet_meta_data_dict->SetString("tweetText", + params->tweet_meta_data.tweet_text); + params_dict->SetDictionary("tweetMetaData", std::move(tweet_meta_data_dict)); ::brave_rewards::OpenDonationDialog(contents, std::move(params_dict)); diff --git a/common/extensions/api/brave_rewards.json b/common/extensions/api/brave_rewards.json index 1b98f63176ec..0c25ff33e7d6 100644 --- a/common/extensions/api/brave_rewards.json +++ b/common/extensions/api/brave_rewards.json @@ -364,24 +364,34 @@ "type": "integer" }, { - "name": "userId", - "type": "string" - }, - { - "name": "name", - "type": "string" - }, - { - "name": "screenName", - "type": "string" - }, - { - "name": "tweetId", - "type": "string" - }, - { - "name": "tweetText", - "type": "string" + "name": "tweetMetaData", + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "User ID of tweet author" + }, + "name": { + "type": "string", + "description": "Name of tweet author" + }, + "screenName": { + "type": "string", + "description": "Twitter handle of tweet author" + }, + "tweetId": { + "type": "string", + "description": "Unique tweet ID" + }, + "tweetTimestamp": { + "type": "number", + "description": "Timestamp (in milliseconds) of tweet" + }, + "tweetText": { + "type": "string", + "description": "Textual contents of tweet" + } + } } ] }, diff --git a/components/brave_rewards/resources/extension/brave_rewards/background.ts b/components/brave_rewards/resources/extension/brave_rewards/background.ts index 2648b53ce672..51fd4d3f9de4 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/background.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/background.ts @@ -79,7 +79,7 @@ chrome.runtime.onConnect.addListener(function () { }) }) -const donateToTwitterUser = (userId: string, name: string, screenName: string, tweetId: string, tweetText: string) => { +const donateToTwitterUser = (tweetMetaData: RewardsDonate.TweetMetaData) => { chrome.tabs.query({ active: true, windowId: chrome.windows.WINDOW_ID_CURRENT @@ -91,7 +91,7 @@ const donateToTwitterUser = (userId: string, name: string, screenName: string, t if (tabId === undefined) { return } - chrome.braveRewards.donateToTwitterUser(tabId, userId, name, screenName, tweetId, tweetText) + chrome.braveRewards.donateToTwitterUser(tabId, tweetMetaData) }) } @@ -99,7 +99,7 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { const action = typeof msg === 'string' ? msg : msg.type switch (action) { case 'donateToTwitterUser': { - donateToTwitterUser(msg.userId, msg.name, msg.screenName, msg.tweetId, msg.tweetText) + donateToTwitterUser(msg.tweetMetaData) return false } case 'rewardsEnabled': { diff --git a/components/brave_rewards/resources/extension/brave_rewards/content.ts b/components/brave_rewards/resources/extension/brave_rewards/content.ts index 3d9be2691793..83cb7a852a83 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/content.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/content.ts @@ -13,11 +13,17 @@ const getTweetMetaData = (tweet: Element): RewardsDonate.TweetMetaData | null => if (!tweetTextElements || tweetTextElements.length === 0) { return null } + const tweetTimestampElements = tweet.getElementsByClassName('js-short-timestamp') + if (!tweetTimestampElements || tweetTimestampElements.length === 0) { + return null + } + const tweetTimestamp = tweetTimestampElements[0].getAttribute('data-time-ms') || '' return { name: tweet.getAttribute('data-name') || '', screenName: tweet.getAttribute('data-screen-name') || '', userId: tweet.getAttribute('data-user-id') || '', tweetId: tweet.getAttribute('data-tweet-id') || '', + tweetTimestamp: parseInt(tweetTimestamp, 10) || 0, tweetText: tweetTextElements[0].textContent || '' } } @@ -34,7 +40,7 @@ const createBraveTipAction = (tweet: Element) => { braveTipButton.onclick = function (event) { const tweetMetaData = getTweetMetaData(tweet) if (tweetMetaData) { - const msg = { type: 'donateToTwitterUser', ...tweetMetaData } + const msg = { type: 'donateToTwitterUser', tweetMetaData: tweetMetaData } chrome.runtime.sendMessage(msg) } } diff --git a/components/definitions/chromel.d.ts b/components/definitions/chromel.d.ts index e21a42c19dda..692bba8b37d1 100644 --- a/components/definitions/chromel.d.ts +++ b/components/definitions/chromel.d.ts @@ -15,7 +15,7 @@ declare namespace chrome.dns { declare namespace chrome.braveRewards { const createWallet: () => {} const tipSite: (tabId: number, publisherKey: string) => {} - const tipTwitterUser: (tabId: number, userId: string, name: string, screenName: string, tweetId: string, tweetText: string) => {} + const tipTwitterUser: (tabId: number, tweetMetaData: RewardsTip.TweetMetaData) => {} const getPublisherData: (windowId: number, url: string, faviconUrl: string, publisherBlob: string | undefined) => {} const getWalletProperties: () => {} const getCurrentReport: () => {} diff --git a/components/definitions/rewardsTip.d.ts b/components/definitions/rewardsTip.d.ts index 46b159fe8333..321065a4979f 100644 --- a/components/definitions/rewardsTip.d.ts +++ b/components/definitions/rewardsTip.d.ts @@ -37,6 +37,7 @@ declare namespace RewardsTip { screenName: string userId: string tweetId: string + tweetTimestamp: number tweetText: string } From 730bfa20182091205fd56ff6867f9a0b43f8356d Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Sat, 4 May 2019 10:15:39 -0400 Subject: [PATCH 12/37] Add TweetBox component --- .../donate/components/donateToTwitterUser.tsx | 3 +- .../resources/donate/components/tweetBox.tsx | 61 +++++++++++++++++++ .../brave_rewards/resources/img/twitter.svg | 1 + .../resources/tip/components/siteBanner.tsx | 8 +-- 4 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 components/brave_rewards/resources/donate/components/tweetBox.tsx create mode 100644 components/brave_rewards/resources/img/twitter.svg diff --git a/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx b/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx index d8df9c4727d1..580807c05c36 100644 --- a/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx +++ b/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx @@ -36,13 +36,12 @@ class DonateToTwitterUser extends React.Component { const publisher = this.props.publisher const tweetMetaData = this.props.tweetMetaData publisher.title = getLocale('tweetTipTitle', { user: tweetMetaData.screenName }) - publisher.description = tweetMetaData.tweetText return ( <> { !finished && !error - ? + ? : null } { diff --git a/components/brave_rewards/resources/donate/components/tweetBox.tsx b/components/brave_rewards/resources/donate/components/tweetBox.tsx new file mode 100644 index 000000000000..3507f418c459 --- /dev/null +++ b/components/brave_rewards/resources/donate/components/tweetBox.tsx @@ -0,0 +1,61 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react' +import { bindActionCreators, Dispatch } from 'redux' +import { connect } from 'react-redux' + +// Utils +import * as donateActions from '../actions/donate_actions' + +// Assets +const twitterImg = require('../../img/twitter.svg') + +interface Props extends RewardsDonate.ComponentProps { + tweetMetaData: RewardsDonate.TweetMetaData +} + +class TweetBox extends React.Component { + get actions () { + return this.props.actions + } + + formatDate = (date: Date) => { + const dateOptions = { month: 'short', day: 'numeric' } + if (new Date().getFullYear() !== date.getFullYear()) { + dateOptions['year'] = 'numeric' + } + return date.toLocaleString(navigator.language, dateOptions) + } + + render () { + const tweetDate = new Date(this.props.tweetMetaData.tweetTimestamp * 1000) + return ( +
+
+ +
+ {this.formatDate(tweetDate)} +
+
+

+ {this.props.tweetMetaData.tweetText} +

+
+ ) + } +} + +const mapStateToProps = (state: RewardsDonate.ApplicationState) => ({ + rewardsDonateData: state.rewardsDonateData +}) + +const mapDispatchToProps = (dispatch: Dispatch) => ({ + actions: bindActionCreators(donateActions, dispatch) +}) + +export default connect( + mapStateToProps, + mapDispatchToProps +)(TweetBox) diff --git a/components/brave_rewards/resources/img/twitter.svg b/components/brave_rewards/resources/img/twitter.svg new file mode 100644 index 000000000000..2832e7b524aa --- /dev/null +++ b/components/brave_rewards/resources/img/twitter.svg @@ -0,0 +1 @@ +Twitter_Logo_Blue \ No newline at end of file diff --git a/components/brave_rewards/resources/tip/components/siteBanner.tsx b/components/brave_rewards/resources/tip/components/siteBanner.tsx index abeaa1435570..495bee971fe6 100644 --- a/components/brave_rewards/resources/tip/components/siteBanner.tsx +++ b/components/brave_rewards/resources/tip/components/siteBanner.tsx @@ -9,6 +9,7 @@ import { connect } from 'react-redux' // Components import { SiteBanner } from 'brave-ui/features/rewards' import { Provider } from 'brave-ui/features/rewards/profile' +import TweetBox from './tweetBox' // Utils import * as tipActions from '../actions/tip_actions' @@ -16,6 +17,7 @@ import * as utils from '../utils' interface Props extends RewardsTip.ComponentProps { publisher: RewardsTip.Publisher + tweetMetaData?: RewardsTip.TweetMetaData } interface State { @@ -161,10 +163,8 @@ class Banner extends React.Component { addFundsLink={this.addFundsLink} > { - utils.isTwitterAccount(publisher.publisherKey) - ?
- {publisher.description} -
+ this.props.tweetMetaData + ? : publisher.description } From c9376d6b3ae84c4bc538ace3fea7230e0f5ea33c Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Sat, 4 May 2019 10:16:36 -0400 Subject: [PATCH 13/37] Remove isTwitterAccount --- .../resources/tip/components/app.tsx | 18 ++++++++---------- .../brave_rewards/resources/tip/utils.ts | 4 ---- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/components/brave_rewards/resources/tip/components/app.tsx b/components/brave_rewards/resources/tip/components/app.tsx index 9774e140a8b0..f3fd953ab9b2 100644 --- a/components/brave_rewards/resources/tip/components/app.tsx +++ b/components/brave_rewards/resources/tip/components/app.tsx @@ -104,16 +104,14 @@ export class App extends React.Component { } let donation - if (isTwitterAccount(publisherKey)) { - const tweetMetaData = this.props.dialogArgs.tweetMetaData - if (tweetMetaData) { - donation = ( - - ) - } + const tweetMetaData = this.props.dialogArgs.tweetMetaData + if (tweetMetaData) { + donation = ( + + ) } else { donation = ( { return result } - -export const isTwitterAccount = (publisherKey: string) => { - return /^twitter#channel:[0-9]+$/.test(publisherKey) -} From 02734ae49373b190e4a7e8e71a81641416564c46 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Sat, 4 May 2019 10:21:23 -0400 Subject: [PATCH 14/37] Use innerText to get tweet content, get timestamp in seconds --- .../resources/extension/brave_rewards/content.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/components/brave_rewards/resources/extension/brave_rewards/content.ts b/components/brave_rewards/resources/extension/brave_rewards/content.ts index 83cb7a852a83..9103f64da958 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/content.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/content.ts @@ -9,22 +9,28 @@ const getTweetMetaData = (tweet: Element): RewardsDonate.TweetMetaData | null => if (!tweet) { return null } + const tweetTextElements = tweet.getElementsByClassName('tweet-text') if (!tweetTextElements || tweetTextElements.length === 0) { return null } + + const tweetText = tweetTextElements[0] as HTMLElement + const tweetTimestampElements = tweet.getElementsByClassName('js-short-timestamp') if (!tweetTimestampElements || tweetTimestampElements.length === 0) { return null } - const tweetTimestamp = tweetTimestampElements[0].getAttribute('data-time-ms') || '' + + const tweetTimestamp = tweetTimestampElements[0].getAttribute('data-time') || '' + return { name: tweet.getAttribute('data-name') || '', screenName: tweet.getAttribute('data-screen-name') || '', userId: tweet.getAttribute('data-user-id') || '', tweetId: tweet.getAttribute('data-tweet-id') || '', tweetTimestamp: parseInt(tweetTimestamp, 10) || 0, - tweetText: tweetTextElements[0].textContent || '' + tweetText: tweetText.innerText || '' } } From a7a71aa85e58d96b6fb127c7622fe2e3dc00f262 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Tue, 7 May 2019 11:19:29 -0400 Subject: [PATCH 15/37] Pass screenName and other metadata to SiteBanner component --- .../brave_rewards/resources/tip/components/siteBanner.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/brave_rewards/resources/tip/components/siteBanner.tsx b/components/brave_rewards/resources/tip/components/siteBanner.tsx index 495bee971fe6..0c20c32c510f 100644 --- a/components/brave_rewards/resources/tip/components/siteBanner.tsx +++ b/components/brave_rewards/resources/tip/components/siteBanner.tsx @@ -137,6 +137,11 @@ class Banner extends React.Component { logo = `chrome://favicon/size/160@2x/${publisher.logo}` } + let screenName + if (this.props.tweetMetaData) { + screenName = `@${this.props.tweetMetaData.screenName}` + } + if (!verified) { logo = '' } @@ -146,6 +151,7 @@ class Banner extends React.Component { domain={publisher.publisherKey} title={publisher.title} name={publisher.name} + screenName={screenName} provider={publisher.provider as Provider} recurringDonation={this.hasRecurringTip(publisher.publisherKey)} balance={balance.toString() || '0'} From ffca9a1571fa2d5fa32960e4a1ad64ebb451d08e Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Tue, 7 May 2019 11:22:40 -0400 Subject: [PATCH 16/37] Update brave-ui DEPS to point to twitter-tips branch (temporary) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c3cdbe91cad7..0d39f67056f8 100644 --- a/package.json +++ b/package.json @@ -277,7 +277,7 @@ "@types/react-redux": "6.0.4", "@types/redux-logger": "^3.0.7", "awesome-typescript-loader": "^5.2.1", - "brave-ui": "github:brave/brave-ui#079dbadba9c270b975eac1962355914a43935b34", + "brave-ui": "github:emerick/brave-ui#twitter-tips", "css-loader": "^2.1.1", "csstype": "^2.5.5", "deep-freeze-node": "^1.1.3", From b44b2767d04322b5cf8409c802450c7df1b27aed Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Wed, 8 May 2019 07:42:39 +0200 Subject: [PATCH 17/37] Adds twitter setting --- browser/extensions/api/brave_rewards_api.cc | 28 +++++++++++++++ browser/extensions/api/brave_rewards_api.h | 14 ++++++++ browser/ui/webui/brave_rewards_ui.cc | 17 ++++++++++ browser/ui/webui/brave_webui_source.cc | 1 + common/extensions/api/brave_rewards.json | 21 ++++++++++++ .../browser/ads_service_impl_unittest.cc | 5 +++ .../brave_rewards/browser/rewards_service.h | 7 ++++ .../browser/rewards_service_impl.cc | 21 ++++++++++++ .../browser/rewards_service_impl.h | 8 +++++ .../extension/brave_rewards/background.ts | 10 +++++- .../extension/brave_rewards/content.ts | 34 +++++++++++-------- .../resources/ui/actions/rewards_actions.ts | 5 +++ .../resources/ui/components/tipsBox.tsx | 34 +++++++++++++++++++ .../resources/ui/constants/rewards_types.ts | 3 +- .../resources/ui/reducers/rewards_reducer.ts | 21 ++++++++++++ .../brave_rewards/resources/ui/storage.ts | 5 ++- components/definitions/chromel.d.ts | 1 + components/definitions/rewards.d.ts | 3 ++ .../resources/brave_components_strings.grd | 1 + .../services/bat_ledger/bat_ledger_impl.cc | 10 ++++++ .../services/bat_ledger/bat_ledger_impl.h | 6 ++++ .../public/interfaces/bat_ledger.mojom | 4 +++ package-lock.json | 4 +-- .../include/bat/ledger/ledger.h | 4 +++ .../src/bat/ledger/internal/bat_helper.cc | 16 +++++++++ .../src/bat/ledger/internal/bat_helper.h | 1 + .../src/bat/ledger/internal/bat_state.cc | 14 ++++++++ .../src/bat/ledger/internal/bat_state.h | 4 +++ .../src/bat/ledger/internal/ledger_impl.cc | 8 +++++ .../src/bat/ledger/internal/ledger_impl.h | 4 +++ 30 files changed, 295 insertions(+), 19 deletions(-) diff --git a/browser/extensions/api/brave_rewards_api.cc b/browser/extensions/api/brave_rewards_api.cc index fc0fce74aa39..b431800f4ab7 100644 --- a/browser/extensions/api/brave_rewards_api.cc +++ b/browser/extensions/api/brave_rewards_api.cc @@ -577,5 +577,33 @@ BraveRewardsGetAllNotificationsFunction::Run() { return RespondNow(OneArgument(std::move(list))); } +BraveRewardsGetInlineTipSettingFunction:: +~BraveRewardsGetInlineTipSettingFunction() { +} + +ExtensionFunction::ResponseAction +BraveRewardsGetInlineTipSettingFunction::Run() { + std::unique_ptr params( + brave_rewards::GetInlineTipSetting::Params::Create(*args_)); + + Profile* profile = Profile::FromBrowserContext(browser_context()); + RewardsService* rewards_service = + RewardsServiceFactory::GetForProfile(profile); + if (!rewards_service) { + return RespondNow(OneArgument(std::make_unique(false))); + } + + rewards_service->GetInlineTipSetting( + params->key, + base::BindOnce( + &BraveRewardsGetInlineTipSettingFunction::OnInlineTipSetting, + this)); + return RespondLater(); +} + +void BraveRewardsGetInlineTipSettingFunction::OnInlineTipSetting(bool value) { + Respond(OneArgument(std::make_unique(value))); +} + } // namespace api } // namespace extensions diff --git a/browser/extensions/api/brave_rewards_api.h b/browser/extensions/api/brave_rewards_api.h index b328df04bba6..c00487b9acaa 100644 --- a/browser/extensions/api/brave_rewards_api.h +++ b/browser/extensions/api/brave_rewards_api.h @@ -265,6 +265,20 @@ class BraveRewardsGetAllNotificationsFunction : ResponseAction Run() override; }; +class BraveRewardsGetInlineTipSettingFunction : + public UIThreadExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("braveRewards.getInlineTipSetting", UNKNOWN) + + protected: + ~BraveRewardsGetInlineTipSettingFunction() override; + + ResponseAction Run() override; + + private: + void OnInlineTipSetting(bool value); +}; + } // namespace api } // namespace extensions diff --git a/browser/ui/webui/brave_rewards_ui.cc b/browser/ui/webui/brave_rewards_ui.cc index b4b213a8963d..06bdfde6dea1 100644 --- a/browser/ui/webui/brave_rewards_ui.cc +++ b/browser/ui/webui/brave_rewards_ui.cc @@ -115,6 +115,8 @@ class RewardsDOMHandler : public WebUIMessageHandler, void OnGetOneTimeTips( std::unique_ptr list); + void SetInlineTipSetting(const base::ListValue* args); + // RewardsServiceObserver implementation void OnWalletInitialized(brave_rewards::RewardsService* rewards_service, uint32_t result) override; @@ -292,6 +294,9 @@ void RewardsDOMHandler::RegisterMessages() { web_ui()->RegisterMessageCallback("brave_rewards.getExcludedPublishersNumber", base::BindRepeating(&RewardsDOMHandler::GetExcludedPublishersNumber, base::Unretained(this))); + web_ui()->RegisterMessageCallback("brave_rewards.setInlineTipSetting", + base::BindRepeating(&RewardsDOMHandler::SetInlineTipSetting, + base::Unretained(this))); } void RewardsDOMHandler::Init() { @@ -1079,6 +1084,18 @@ void RewardsDOMHandler::OnContributionSaved( "brave_rewards.onContributionSaved", result); } +void RewardsDOMHandler::SetInlineTipSetting(const base::ListValue* args) { + std::string key; + args->GetString(0, &key); + + std::string value; + args->GetString(1, &value); + + if (rewards_service_) { + rewards_service_->SetInlineTipSetting(key, value == "true"); + } +} + } // namespace BraveRewardsUI::BraveRewardsUI(content::WebUI* web_ui, const std::string& name) diff --git a/browser/ui/webui/brave_webui_source.cc b/browser/ui/webui/brave_webui_source.cc index fbca93ab1f10..347c9ac69a8f 100644 --- a/browser/ui/webui/brave_webui_source.cc +++ b/browser/ui/webui/brave_webui_source.cc @@ -244,6 +244,7 @@ void CustomizeWebUIHTMLSource(const std::string &name, { "donationDisabledText1", IDS_BRAVE_REWARDS_LOCAL_DONAT_DISABLED_TEXT1 }, // NOLINT { "donationDisabledText2", IDS_BRAVE_REWARDS_LOCAL_DONAT_DISABLED_TEXT2 }, // NOLINT { "donationNextDate", IDS_BRAVE_REWARDS_LOCAL_DONAT_NEXT_DATE }, + { "donationTipOnLike", IDS_BRAVE_REWARDS_LOCAL_DONAT_TIP_ON_LIKE }, { "panelAddFunds", IDS_BRAVE_REWARDS_LOCAL_PANEL_ADD_FUNDS }, { "panelWithdrawFunds", IDS_BRAVE_REWARDS_LOCAL_PANEL_WITHDRAW_FUNDS }, diff --git a/common/extensions/api/brave_rewards.json b/common/extensions/api/brave_rewards.json index 0c25ff33e7d6..fcab0b78d073 100644 --- a/common/extensions/api/brave_rewards.json +++ b/common/extensions/api/brave_rewards.json @@ -691,6 +691,27 @@ ] } ] + }, + { + "name": "getInlineTipSetting", + "type": "function", + "description": "Gets setting for inline tip for provided key", + "parameters": [ + { + "name": "key", + "value": "string" + }, + { + "type": "function", + "name": "callback", + "parameters": [ + { + "name": "enabled", + "type": "boolean" + } + ] + } + ] } ] } diff --git a/components/brave_ads/browser/ads_service_impl_unittest.cc b/components/brave_ads/browser/ads_service_impl_unittest.cc index 4e46f2361070..2aefdcf57977 100644 --- a/components/brave_ads/browser/ads_service_impl_unittest.cc +++ b/components/brave_ads/browser/ads_service_impl_unittest.cc @@ -146,6 +146,11 @@ class MockRewardsService : public RewardsService { MOCK_METHOD2(SaveTwitterPublisherInfo, void(const std::map&, brave_rewards::SaveMediaInfoCallback)); + MOCK_METHOD2(SetInlineTipSetting, + void(const std::string& key, bool enabled)); + MOCK_METHOD2(GetInlineTipSetting, + void(const std::string& key, + brave_rewards::GetInlineTipSettingCallback callback)); }; class AdsServiceTest : public testing::Test { diff --git a/components/brave_rewards/browser/rewards_service.h b/components/brave_rewards/browser/rewards_service.h index e267764255b1..f8bee6ea4829 100644 --- a/components/brave_rewards/browser/rewards_service.h +++ b/components/brave_rewards/browser/rewards_service.h @@ -79,6 +79,7 @@ using RefreshPublisherCallback = base::OnceCallback; using SaveMediaInfoCallback = base::OnceCallback)>; +using GetInlineTipSettingCallback = base::OnceCallback; class RewardsService : public KeyedService { public: @@ -212,6 +213,12 @@ class RewardsService : public KeyedService { const std::map& args, SaveMediaInfoCallback callback) = 0; + virtual void SetInlineTipSetting(const std::string& key, bool enabled) = 0; + + virtual void GetInlineTipSetting( + const std::string& key, + GetInlineTipSettingCallback callback) = 0; + protected: base::ObserverList observers_; diff --git a/components/brave_rewards/browser/rewards_service_impl.cc b/components/brave_rewards/browser/rewards_service_impl.cc index cd9539621f56..5e6e796f51d8 100644 --- a/components/brave_rewards/browser/rewards_service_impl.cc +++ b/components/brave_rewards/browser/rewards_service_impl.cc @@ -2962,4 +2962,25 @@ RewardsServiceImpl::GetAllNotifications() { return notification_service_->GetAllNotifications(); } +void RewardsServiceImpl::SetInlineTipSetting(const std::string& key, + bool enabled) { + bat_ledger_->SetInlineTipSetting(key, enabled); +} + +void RewardsServiceImpl::GetInlineTipSetting( + const std::string& key, + GetInlineTipSettingCallback callback) { + bat_ledger_->GetInlineTipSetting( + key, + base::BindOnce(&RewardsServiceImpl::OnInlineTipSetting, + AsWeakPtr(), + std::move(callback))); +} + +void RewardsServiceImpl::OnInlineTipSetting( + GetInlineTipSettingCallback callback, + bool enabled) { + std::move(callback).Run(enabled); +} + } // namespace brave_rewards diff --git a/components/brave_rewards/browser/rewards_service_impl.h b/components/brave_rewards/browser/rewards_service_impl.h index b7f8a586b956..919f6350d8c0 100644 --- a/components/brave_rewards/browser/rewards_service_impl.h +++ b/components/brave_rewards/browser/rewards_service_impl.h @@ -222,6 +222,12 @@ class RewardsServiceImpl : public RewardsService, const std::map& args, SaveMediaInfoCallback callback) override; + void SetInlineTipSetting(const std::string& key, bool enabled) override; + + void GetInlineTipSetting( + const std::string& key, + GetInlineTipSettingCallback callback) override; + // Testing methods void SetLedgerEnvForTesting(); void StartAutoContributeForTest(); @@ -325,6 +331,8 @@ class RewardsServiceImpl : public RewardsService, uint32_t result, ledger::PublisherInfoPtr info); + void OnInlineTipSetting(GetInlineTipSettingCallback callback, bool enabled); + // ledger::LedgerClient std::string GenerateGUID() const override; void OnWalletInitialized(ledger::Result result) override; diff --git a/components/brave_rewards/resources/extension/brave_rewards/background.ts b/components/brave_rewards/resources/extension/brave_rewards/background.ts index 51fd4d3f9de4..6c7f8966abfa 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/background.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/background.ts @@ -105,7 +105,15 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { case 'rewardsEnabled': { // Check if rewards is enabled chrome.braveRewards.getRewardsMainEnabled(function (enabled: boolean) { - sendResponse({ enabled: enabled }) + sendResponse({ enabled }) + }) + // Must return true for asynchronous calls to sendResponse + return true + } + case 'inlineTipSetting': { + // Check if rewards is enabled + chrome.braveRewards.getInlineTipSetting(msg.key, function (enabled: boolean) { + sendResponse({ enabled }) }) // Must return true for asynchronous calls to sendResponse return true diff --git a/components/brave_rewards/resources/extension/brave_rewards/content.ts b/components/brave_rewards/resources/extension/brave_rewards/content.ts index 9103f64da958..54a84ef34b7b 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/content.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/content.ts @@ -83,23 +83,29 @@ const createBraveTipAction = (tweet: Element) => { } const configureBraveTipAction = () => { - chrome.runtime.sendMessage('rewardsEnabled', function (response) { - const tweets = document.getElementsByClassName('tweet') - for (let i = 0; i < tweets.length; ++i) { - const actions = tweets[i].getElementsByClassName('js-actions')[0] - if (actions) { - const braveTipActions = actions.getElementsByClassName('action-brave-tip') - if (response.enabled) { - if (braveTipActions.length === 0) { - actions.appendChild(createBraveTipAction(tweets[i])) - } - } else { - if (braveTipActions.length === 1) { - actions.removeChild(braveTipActions[0]) + chrome.runtime.sendMessage('rewardsEnabled', function (rewards) { + const msg = { + type: 'inlineTipSetting', + key: 'twitter' + } + chrome.runtime.sendMessage(msg, function (inlineTip) { + const tweets = document.getElementsByClassName('tweet') + for (let i = 0; i < tweets.length; ++i) { + const actions = tweets[i].getElementsByClassName('js-actions')[0] + if (actions) { + const braveTipActions = actions.getElementsByClassName('action-brave-tip') + if (rewards.enabled && inlineTip.enabled) { + if (braveTipActions.length === 0) { + actions.appendChild(createBraveTipAction(tweets[i])) + } + } else { + if (braveTipActions.length === 1) { + actions.removeChild(braveTipActions[0]) + } } } } - } + }) }) setTimeout(configureBraveTipAction, 3000) } diff --git a/components/brave_rewards/resources/ui/actions/rewards_actions.ts b/components/brave_rewards/resources/ui/actions/rewards_actions.ts index 1c4faed4b1d9..ace57b431813 100644 --- a/components/brave_rewards/resources/ui/actions/rewards_actions.ts +++ b/components/brave_rewards/resources/ui/actions/rewards_actions.ts @@ -200,3 +200,8 @@ export const onContributionSaved = (properties: Rewards.ContributionSaved) => action(types.ON_CONTRIBUTION_SAVED, { properties }) + +export const onInlineTipSettingChange = (key: string, value: boolean) => action(types.ON_INLINE_TIP_SETTINGS_CHANGE, { + key, + value +}) diff --git a/components/brave_rewards/resources/ui/components/tipsBox.tsx b/components/brave_rewards/resources/ui/components/tipsBox.tsx index 2b0a64d4e071..40b507b0db33 100644 --- a/components/brave_rewards/resources/ui/components/tipsBox.tsx +++ b/components/brave_rewards/resources/ui/components/tipsBox.tsx @@ -7,6 +7,7 @@ import { bindActionCreators, Dispatch } from 'redux' import { connect } from 'react-redux' // Components +import { Checkbox, Grid, Column, ControlWrapper } from 'brave-ui/components' import { DisabledContent, Box, @@ -156,6 +157,38 @@ class TipBox extends React.Component { this.setState({ settings: !this.state.settings }) } + onInlineTipSettingChange = (key: string, selected: boolean) => { + this.actions.onInlineTipSettingChange(key, selected) + } + + donationSettingsChild = () => { + let value = this.props.rewardsData.inlineTip + + if (!value) { + value = { + twitter: true + } + } + + return ( + <> + + + + +
{getLocale('donationAbilityTwitter')}
+
+
+
+
+ + ) + } + render () { const { walletInfo, @@ -181,6 +214,7 @@ class TipBox extends React.Component { description={getLocale('donationDesc')} disabledContent={showDisabled ? this.disabledContent() : null} attachedAlert={this.importAlert(walletImported)} + settingsChild={this.donationSettingsChild()} settingsOpened={this.state.settings} onSettingsClick={this.onSettingsToggle} > diff --git a/components/brave_rewards/resources/ui/constants/rewards_types.ts b/components/brave_rewards/resources/ui/constants/rewards_types.ts index 845a0a2160ce..b62d9f39440e 100644 --- a/components/brave_rewards/resources/ui/constants/rewards_types.ts +++ b/components/brave_rewards/resources/ui/constants/rewards_types.ts @@ -61,5 +61,6 @@ export const enum types { GET_REWARDS_MAIN_ENABLED = '@@rewards/GET_REWARDS_MAIN_ENABLED', ON_RECURRING_TIP_SAVED = '@@rewards/ON_RECURRING_TIP_SAVED', ON_RECURRING_TIP_REMOVED = '@@rewards/ON_RECURRING_TIP_REMOVED', - ON_CONTRIBUTION_SAVED = '@@rewards/ON_CONTRIBUTION_SAVED' + ON_CONTRIBUTION_SAVED = '@@rewards/ON_CONTRIBUTION_SAVED', + ON_INLINE_TIP_SETTINGS_CHANGE = '@@rewards/ON_INLINE_TIP_SETTINGS_CHANGE' } diff --git a/components/brave_rewards/resources/ui/reducers/rewards_reducer.ts b/components/brave_rewards/resources/ui/reducers/rewards_reducer.ts index 2113f76cf111..983f8ebb02d7 100644 --- a/components/brave_rewards/resources/ui/reducers/rewards_reducer.ts +++ b/components/brave_rewards/resources/ui/reducers/rewards_reducer.ts @@ -178,6 +178,27 @@ const rewardsReducer: Reducer = (state: Rewards.State } break } + case types.ON_INLINE_TIP_SETTINGS_CHANGE: { + if (!state.inlineTip) { + state.inlineTip = { + twitter: true + } + } + + const key = action.payload.key + const value = action.payload.value + let inlineTip = state.inlineTip + + inlineTip[key] = value + chrome.send('brave_rewards.setInlineTipSetting', [key, value.toString()]) + + state = { + ...state, + inlineTip + } + + break + } } return state diff --git a/components/brave_rewards/resources/ui/storage.ts b/components/brave_rewards/resources/ui/storage.ts index b1675e9a9ec3..a5b09aa52131 100644 --- a/components/brave_rewards/resources/ui/storage.ts +++ b/components/brave_rewards/resources/ui/storage.ts @@ -58,7 +58,10 @@ export const defaultState: Rewards.State = { }, pendingContributionTotal: 0, grants: [], - currentGrant: undefined + currentGrant: undefined, + inlineTip: { + twitter: true + } } const cleanData = (state: Rewards.State) => state diff --git a/components/definitions/chromel.d.ts b/components/definitions/chromel.d.ts index 692bba8b37d1..0f8e5bdaef52 100644 --- a/components/definitions/chromel.d.ts +++ b/components/definitions/chromel.d.ts @@ -74,6 +74,7 @@ declare namespace chrome.braveRewards { } const refreshPublisher: (publisherKey: string, callback: (enabled: boolean, publisherKey: string) => void) => {} const getAllNotifications: (callback: (list: RewardsExtension.Notification[]) => void) => {} + const getInlineTipSetting: (key: string, callback: (enabled: boolean) => void) => {} } declare namespace chrome.rewardsNotifications { diff --git a/components/definitions/rewards.d.ts b/components/definitions/rewards.d.ts index 3fd8dffd2748..d25050f391e3 100644 --- a/components/definitions/rewards.d.ts +++ b/components/definitions/rewards.d.ts @@ -41,6 +41,9 @@ declare namespace Rewards { enabledAds: boolean enabledContribute: boolean enabledMain: boolean + inlineTip: { + twitter: boolean + } firstLoad: boolean | null grants?: Grant[] excludedPublishersNumber: number diff --git a/components/resources/brave_components_strings.grd b/components/resources/brave_components_strings.grd index 2fb1fd96c04b..4e547684b851 100644 --- a/components/resources/brave_components_strings.grd +++ b/components/resources/brave_components_strings.grd @@ -262,6 +262,7 @@ I just tipped @$1user using the Brave Browser. Check it out at https://brave.com/tips. + Enable ability to give tips on ‘Like’ posts Amount: diff --git a/components/services/bat_ledger/bat_ledger_impl.cc b/components/services/bat_ledger/bat_ledger_impl.cc index 914a3ca3f207..2e056f3c2def 100644 --- a/components/services/bat_ledger/bat_ledger_impl.cc +++ b/components/services/bat_ledger/bat_ledger_impl.cc @@ -564,4 +564,14 @@ void BatLedgerImpl::StartAutoContribute() { ledger_->StartAutoContribute(); } +void BatLedgerImpl::SetInlineTipSetting(const std::string& key, bool enabled) { + ledger_->SetInlineTipSetting(key, enabled); +} + +void BatLedgerImpl::GetInlineTipSetting( + const std::string& key, + GetInlineTipSettingCallback callback) { + std::move(callback).Run(ledger_->GetInlineTipSetting(key)); +} + } // namespace bat_ledger diff --git a/components/services/bat_ledger/bat_ledger_impl.h b/components/services/bat_ledger/bat_ledger_impl.h index 61d06f7bd1ff..7e3d513e3dff 100644 --- a/components/services/bat_ledger/bat_ledger_impl.h +++ b/components/services/bat_ledger/bat_ledger_impl.h @@ -158,6 +158,12 @@ class BatLedgerImpl : public mojom::BatLedger, const base::flat_map& args, SaveMediaInfoCallback callback) override; + void SetInlineTipSetting(const std::string& key, bool enabled) override; + + void GetInlineTipSetting( + const std::string& key, + GetInlineTipSettingCallback callback) override; + private: void SetCatalogIssuers(const std::string& info) override; void ConfirmAd(const std::string& info) override; diff --git a/components/services/bat_ledger/public/interfaces/bat_ledger.mojom b/components/services/bat_ledger/public/interfaces/bat_ledger.mojom index db50b5d74632..2f135e0c0ddc 100644 --- a/components/services/bat_ledger/public/interfaces/bat_ledger.mojom +++ b/components/services/bat_ledger/public/interfaces/bat_ledger.mojom @@ -121,6 +121,10 @@ interface BatLedger { SaveMediaInfo(string type, map args) => (int32 result, string publisher_info); + + SetInlineTipSetting(string key, bool enabled); + + GetInlineTipSetting(string key) => (bool enabled); }; interface BatLedgerClient { diff --git a/package-lock.json b/package-lock.json index de38530f1760..bd73fd23ca32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1597,8 +1597,8 @@ } }, "brave-ui": { - "version": "github:brave/brave-ui#079dbadba9c270b975eac1962355914a43935b34", - "from": "github:brave/brave-ui#079dbadba9c270b975eac1962355914a43935b34", + "version": "github:emerick/brave-ui#9f211580b43711d4dbf34e9e786d76bd2bd14c24", + "from": "github:emerick/brave-ui#twitter-tips", "dev": true, "requires": { "@ctrl/tinycolor": "^2.2.1", diff --git a/vendor/bat-native-ledger/include/bat/ledger/ledger.h b/vendor/bat-native-ledger/include/bat/ledger/ledger.h index 400bc4d8864a..b9bfd290b77d 100644 --- a/vendor/bat-native-ledger/include/bat/ledger/ledger.h +++ b/vendor/bat-native-ledger/include/bat/ledger/ledger.h @@ -293,6 +293,10 @@ class LEDGER_EXPORT Ledger { virtual void SaveMediaInfo(const std::string& type, const std::map& data, ledger::SaveMediaInfoCallback callback) = 0; + + virtual void SetInlineTipSetting(const std::string& key, bool enabled) = 0; + + virtual bool GetInlineTipSetting(const std::string& key) = 0; }; } // namespace ledger diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.cc index 67243122211a..ed8f5277a592 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.cc @@ -1507,6 +1507,7 @@ CLIENT_STATE_ST::CLIENT_STATE_ST(const CLIENT_STATE_ST& other) { auto_contribute_ = other.auto_contribute_; rewards_enabled_ = other.rewards_enabled_; current_reconciles_ = other.current_reconciles_; + inline_tip_ = other.inline_tip_; } CLIENT_STATE_ST::~CLIENT_STATE_ST() {} @@ -1625,6 +1626,13 @@ bool CLIENT_STATE_ST::loadFromJson(const std::string & json) { i.Accept(writer); walletProperties_.loadFromJson(sb.GetString()); } + + if (d.HasMember("inlineTip") && d["inlineTip"].IsObject()) { + for (auto & k : d["inlineTip"].GetObject()) { + inline_tip_.insert( + std::make_pair(k.name.GetString(), k.value.GetBool())); + } + } } return !error; @@ -1719,6 +1727,14 @@ void saveToJson(JsonWriter* writer, const CLIENT_STATE_ST& data) { writer->String("walletProperties"); saveToJson(writer, data.walletProperties_); + writer->String("inlineTip"); + writer->StartObject(); + for (auto & p : data.inline_tip_) { + writer->String(p.first.c_str()); + writer->Bool(p.second); + } + writer->EndObject(); + writer->EndObject(); } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.h b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.h index c2087175828d..1aaa15cb923b 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_helper.h @@ -365,6 +365,7 @@ struct CLIENT_STATE_ST { CurrentReconciles current_reconciles_; bool auto_contribute_ = false; bool rewards_enabled_ = false; + std::map inline_tip_; }; struct GRANTS_PROPERTIES_ST { diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_state.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_state.cc index e02944d34d7e..b91d4beeeb22 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_state.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_state.cc @@ -412,4 +412,18 @@ void BatState::SetAddress(std::map addresses) { SaveState(); } +void BatState::SetInlineTipSetting(const std::string& key, bool enabled) { + state_->inline_tip_[key] = enabled; + SaveState(); +} + +bool BatState::GetInlineTipSetting(const std::string& key) const { + if (state_->inline_tip_.find(key) == state_->inline_tip_.end()) { + // not found, all tips are on by default + return true; + } else { + return state_->inline_tip_[key]; + } +} + } // namespace braveledger_bat_state diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_state.h b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_state.h index 06fa80ddd145..4fe6bebbd953 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_state.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_state.h @@ -149,6 +149,10 @@ class BatState { void SetAddress(std::map addresses); + void SetInlineTipSetting(const std::string& key, bool enabled); + + bool GetInlineTipSetting(const std::string& key) const; + private: void SaveState(); diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc index 589b484d6ca4..ec9a5e5a2fc3 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc @@ -1510,4 +1510,12 @@ void LedgerImpl::SaveMediaInfo(const std::string& type, bat_get_media_->SaveMediaInfo(type, data, callback); } +void LedgerImpl::SetInlineTipSetting(const std::string& key, bool enabled) { + bat_state_->SetInlineTipSetting(key, enabled); +} + +bool LedgerImpl::GetInlineTipSetting(const std::string& key) { + return bat_state_->GetInlineTipSetting(key); +} + } // namespace bat_ledger diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h index e75e642d9176..5d92b279202d 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h @@ -444,6 +444,10 @@ class LedgerImpl : public ledger::Ledger, const std::map& data, ledger::SaveMediaInfoCallback callback) override; + void SetInlineTipSetting(const std::string& key, bool enabled) override; + + bool GetInlineTipSetting(const std::string& key) override; + private: void AddRecurringPayment(const std::string& publisher_id, const double& value) override; From 3095dfc1078ac4e854388b5345aeaf88b24d93e1 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Wed, 8 May 2019 14:36:03 -0400 Subject: [PATCH 18/37] Donation -> Tip --- browser/brave_rewards/tip_dialog.cc | 1 + browser/brave_rewards/tip_dialog.h | 5 ++ browser/extensions/api/brave_rewards_api.cc | 31 +++---- browser/extensions/api/brave_rewards_api.h | 10 +-- browser/ui/webui/brave_tip_ui.cc | 10 +-- common/extensions/api/brave_rewards.json | 2 +- .../extension/brave_rewards/background.ts | 8 +- .../extension/brave_rewards/content.ts | 4 +- .../resources/tip/components/app.tsx | 81 +++---------------- .../components/tipSite.tsx} | 16 ++-- .../components/tipTwitterUser.tsx} | 18 ++--- .../components/transientTipOverlay.tsx} | 12 +-- .../{donate => tip}/components/tweetBox.tsx | 10 +-- .../resources/tip/reducers/tip_reducer.ts | 2 +- 14 files changed, 78 insertions(+), 132 deletions(-) rename components/brave_rewards/resources/{donate/components/donateToSite.tsx => tip/components/tipSite.tsx} (68%) rename components/brave_rewards/resources/{donate/components/donateToTwitterUser.tsx => tip/components/tipTwitterUser.tsx} (75%) rename components/brave_rewards/resources/{donate/components/transientDonationOverlay.tsx => tip/components/transientTipOverlay.tsx} (86%) rename components/brave_rewards/resources/{donate => tip}/components/tweetBox.tsx (85%) diff --git a/browser/brave_rewards/tip_dialog.cc b/browser/brave_rewards/tip_dialog.cc index 2ae4a60ade63..82d31db0670d 100644 --- a/browser/brave_rewards/tip_dialog.cc +++ b/browser/brave_rewards/tip_dialog.cc @@ -5,6 +5,7 @@ #include "brave/browser/brave_rewards/tip_dialog.h" +#include #include #include #include diff --git a/browser/brave_rewards/tip_dialog.h b/browser/brave_rewards/tip_dialog.h index d5944b838048..facd4843a3e7 100644 --- a/browser/brave_rewards/tip_dialog.h +++ b/browser/brave_rewards/tip_dialog.h @@ -6,8 +6,13 @@ #ifndef BRAVE_BROWSER_BRAVE_REWARDS_TIP_DIALOG_H_ #define BRAVE_BROWSER_BRAVE_REWARDS_TIP_DIALOG_H_ +#include #include +namespace base { +class DictionaryValue; +} + namespace content { class WebContents; } diff --git a/browser/extensions/api/brave_rewards_api.cc b/browser/extensions/api/brave_rewards_api.cc index b431800f4ab7..2939c98124ba 100644 --- a/browser/extensions/api/brave_rewards_api.cc +++ b/browser/extensions/api/brave_rewards_api.cc @@ -76,27 +76,28 @@ ExtensionFunction::ResponseAction BraveRewardsTipSiteFunction::Run() { params_dict->SetString("publisherKey", params->publisher_key); ::brave_rewards::OpenTipDialog(contents, std::move(params_dict)); -BraveRewardsDonateToTwitterUserFunction:: - BraveRewardsDonateToTwitterUserFunction() - : weak_factory_(this) { + return RespondNow(NoArguments()); +} + +BraveRewardsTipTwitterUserFunction::BraveRewardsTipTwitterUserFunction() + : weak_factory_(this) { } -BraveRewardsDonateToTwitterUserFunction:: - ~BraveRewardsDonateToTwitterUserFunction() { +BraveRewardsTipTwitterUserFunction::~BraveRewardsTipTwitterUserFunction() { } ExtensionFunction::ResponseAction -BraveRewardsDonateToTwitterUserFunction::Run() { - std::unique_ptr params( - brave_rewards::DonateToTwitterUser::Params::Create(*args_)); +BraveRewardsTipTwitterUserFunction::Run() { + std::unique_ptr params( + brave_rewards::TipTwitterUser::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); - // Sanity check: don't allow donations in private / tor contexts, + // Sanity check: don't allow tips in private / tor contexts, // although the command should not have been enabled in the first place. Profile* profile = Profile::FromBrowserContext(browser_context()); if (profile->IsOffTheRecord()) { return RespondNow( - Error("Cannot donate to Twitter user in a private context")); + Error("Cannot tip Twitter user in a private context")); } auto* rewards_service = RewardsServiceFactory::GetForProfile(profile); @@ -108,7 +109,7 @@ BraveRewardsDonateToTwitterUserFunction::Run() { args["screen_name"] = params->tweet_meta_data.screen_name; rewards_service->SaveTwitterPublisherInfo( args, - base::Bind(&BraveRewardsDonateToTwitterUserFunction:: + base::Bind(&BraveRewardsTipTwitterUserFunction:: OnTwitterPublisherInfoSaved, weak_factory_.GetWeakPtr())); } @@ -116,10 +117,10 @@ BraveRewardsDonateToTwitterUserFunction::Run() { return RespondNow(NoArguments()); } -void BraveRewardsDonateToTwitterUserFunction::OnTwitterPublisherInfoSaved( +void BraveRewardsTipTwitterUserFunction::OnTwitterPublisherInfoSaved( std::unique_ptr<::brave_rewards::ContentSite> publisher_info) { - std::unique_ptr params( - brave_rewards::DonateToTwitterUser::Params::Create(*args_)); + std::unique_ptr params( + brave_rewards::TipTwitterUser::Params::Create(*args_)); if (!publisher_info) { // TODO(nejczdovc): what should we do in this case? @@ -155,7 +156,7 @@ void BraveRewardsDonateToTwitterUserFunction::OnTwitterPublisherInfoSaved( params->tweet_meta_data.tweet_text); params_dict->SetDictionary("tweetMetaData", std::move(tweet_meta_data_dict)); - ::brave_rewards::OpenDonationDialog(contents, std::move(params_dict)); + ::brave_rewards::OpenTipDialog(contents, std::move(params_dict)); Release(); } diff --git a/browser/extensions/api/brave_rewards_api.h b/browser/extensions/api/brave_rewards_api.h index c00487b9acaa..f31e3ed54191 100644 --- a/browser/extensions/api/brave_rewards_api.h +++ b/browser/extensions/api/brave_rewards_api.h @@ -37,19 +37,19 @@ class BraveRewardsTipSiteFunction : public UIThreadExtensionFunction { ResponseAction Run() override; }; -class BraveRewardsDonateToTwitterUserFunction +class BraveRewardsTipTwitterUserFunction : public UIThreadExtensionFunction { public: - BraveRewardsDonateToTwitterUserFunction(); - DECLARE_EXTENSION_FUNCTION("braveRewards.donateToTwitterUser", UNKNOWN) + BraveRewardsTipTwitterUserFunction(); + DECLARE_EXTENSION_FUNCTION("braveRewards.tipTwitterUser", UNKNOWN) protected: - ~BraveRewardsDonateToTwitterUserFunction() override; + ~BraveRewardsTipTwitterUserFunction() override; ResponseAction Run() override; private: - base::WeakPtrFactory weak_factory_; + base::WeakPtrFactory weak_factory_; void OnTwitterPublisherInfoSaved( std::unique_ptr publisher_info); }; diff --git a/browser/ui/webui/brave_tip_ui.cc b/browser/ui/webui/brave_tip_ui.cc index c2ffa5f06657..ed4ae935d45b 100644 --- a/browser/ui/webui/brave_tip_ui.cc +++ b/browser/ui/webui/brave_tip_ui.cc @@ -121,8 +121,8 @@ void RewardsTipDOMHandler::RegisterMessages() { base::BindRepeating(&RewardsTipDOMHandler::GetReconcileStamp, base::Unretained(this))); web_ui()->RegisterMessageCallback( - "brave_rewards_donate.tweetTip", - base::BindRepeating(&RewardsDonateDOMHandler::TweetTip, + "brave_rewards_tip.tweetTip", + base::BindRepeating(&RewardsTipDOMHandler::TweetTip, base::Unretained(this))); } @@ -300,6 +300,9 @@ BraveTipUI::BraveTipUI(content::WebUI* web_ui, const std::string& name) handler->Init(); } +BraveTipUI::~BraveTipUI() { +} + void RewardsTipDOMHandler::GetReconcileStamp(const base::ListValue *args) { if (rewards_service_) { rewards_service_->GetReconcileStamp(base::Bind( @@ -340,9 +343,6 @@ void RewardsTipDOMHandler::OnRecurringTipSaved( "brave_rewards_tip.recurringTipSaved", base::Value(success)); } -BraveDonateUI::~BraveTipUI() { -} - void RewardsTipDOMHandler::TweetTip(const base::ListValue *args) { DCHECK_EQ(args->GetSize(), 1U); const base::DictionaryValue* tweet_metadata_dict = nullptr; diff --git a/common/extensions/api/brave_rewards.json b/common/extensions/api/brave_rewards.json index fcab0b78d073..d795328f7c64 100644 --- a/common/extensions/api/brave_rewards.json +++ b/common/extensions/api/brave_rewards.json @@ -355,7 +355,7 @@ ] }, { - "name": "donateToTwitterUser", + "name": "tipTwitterUser", "type": "function", "description": "Allow the user to perform a donation to a Twitter user", "parameters": [ diff --git a/components/brave_rewards/resources/extension/brave_rewards/background.ts b/components/brave_rewards/resources/extension/brave_rewards/background.ts index 6c7f8966abfa..650fc8add216 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/background.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/background.ts @@ -79,7 +79,7 @@ chrome.runtime.onConnect.addListener(function () { }) }) -const donateToTwitterUser = (tweetMetaData: RewardsDonate.TweetMetaData) => { +const tipTwitterUser = (tweetMetaData: RewardsTip.TweetMetaData) => { chrome.tabs.query({ active: true, windowId: chrome.windows.WINDOW_ID_CURRENT @@ -91,15 +91,15 @@ const donateToTwitterUser = (tweetMetaData: RewardsDonate.TweetMetaData) => { if (tabId === undefined) { return } - chrome.braveRewards.donateToTwitterUser(tabId, tweetMetaData) + chrome.braveRewards.tipTwitterUser(tabId, tweetMetaData) }) } chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { const action = typeof msg === 'string' ? msg : msg.type switch (action) { - case 'donateToTwitterUser': { - donateToTwitterUser(msg.tweetMetaData) + case 'tipTwitterUser': { + tipTwitterUser(msg.tweetMetaData) return false } case 'rewardsEnabled': { diff --git a/components/brave_rewards/resources/extension/brave_rewards/content.ts b/components/brave_rewards/resources/extension/brave_rewards/content.ts index 54a84ef34b7b..03c87d30c6cb 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/content.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/content.ts @@ -5,7 +5,7 @@ // Utils import { getMessage } from './background/api/locale_api' -const getTweetMetaData = (tweet: Element): RewardsDonate.TweetMetaData | null => { +const getTweetMetaData = (tweet: Element): RewardsTip.TweetMetaData | null => { if (!tweet) { return null } @@ -46,7 +46,7 @@ const createBraveTipAction = (tweet: Element) => { braveTipButton.onclick = function (event) { const tweetMetaData = getTweetMetaData(tweet) if (tweetMetaData) { - const msg = { type: 'donateToTwitterUser', tweetMetaData: tweetMetaData } + const msg = { type: 'tipTwitterUser', tweetMetaData: tweetMetaData } chrome.runtime.sendMessage(msg) } } diff --git a/components/brave_rewards/resources/tip/components/app.tsx b/components/brave_rewards/resources/tip/components/app.tsx index f3fd953ab9b2..7fb832f90a83 100644 --- a/components/brave_rewards/resources/tip/components/app.tsx +++ b/components/brave_rewards/resources/tip/components/app.tsx @@ -7,19 +7,18 @@ import { bindActionCreators, Dispatch } from 'redux' import { connect } from 'react-redux' // Components -import DonateToSite from './donateToSite' -import DonateToTwitterUser from './donateToTwitterUser' +import TipSite from './tipSite' +import TipTwitterUser from './tipTwitterUser' // Utils import * as rewardsActions from '../actions/tip_actions' -import { isTwitterAccount } from '../utils' interface TipDialogArgs { publisherKey: string - tweetMetaData?: RewardsDonate.TweetMetaData + tweetMetaData?: RewardsTip.TweetMetaData } -interface Props extends RewardsDonate.ComponentProps { +interface Props extends RewardsTip.ComponentProps { dialogArgs: TipDialogArgs } @@ -29,66 +28,6 @@ export class App extends React.Component { return this.props.actions } - onClose = () => { - this.actions.onCloseDialog() - } - - generateTipOverlay = (publisher: RewardsTip.Publisher) => { - let domain = '' - let monthlyDate - const { - currentTipAmount, - currentTipRecurring, - reconcileStamp - } = this.props.rewardsDonateData - - const publisherKey = publisher && publisher.publisherKey - - if (!publisherKey) { - return null - } - - if (currentTipRecurring && reconcileStamp) { - monthlyDate = new Date(reconcileStamp * 1000).toLocaleDateString() - } - - if (publisher.provider && publisher.name) { - domain = publisher.name - } else { - domain = publisherKey - } - - const verified = publisher.verified - let logo = publisher.logo - - const internalFavicon = /^https:\/\/[a-z0-9-]+\.invalid(\/)?$/ - if (internalFavicon.test(publisher.logo)) { - logo = `chrome://favicon/size/160@2x/${publisher.logo}` - } - - if (!verified) { - logo = '' - } - - setTimeout(() => { - this.onClose() - }, 3000) - - return ( - - ) - - isTwitterAccount = (publisherKey: string) => { - return /^twitter#channel:[0-9]+$/.test(publisherKey) - } - render () { const { publishers } = this.props.rewardsDonateData @@ -103,18 +42,18 @@ export class App extends React.Component { return null } - let donation + let tip const tweetMetaData = this.props.dialogArgs.tweetMetaData if (tweetMetaData) { - donation = ( - ) } else { - donation = ( - ) @@ -122,7 +61,7 @@ export class App extends React.Component { return (
- {donation} + {tip}
) } diff --git a/components/brave_rewards/resources/donate/components/donateToSite.tsx b/components/brave_rewards/resources/tip/components/tipSite.tsx similarity index 68% rename from components/brave_rewards/resources/donate/components/donateToSite.tsx rename to components/brave_rewards/resources/tip/components/tipSite.tsx index 4d0c3e233fa6..f4c01b875718 100644 --- a/components/brave_rewards/resources/donate/components/donateToSite.tsx +++ b/components/brave_rewards/resources/tip/components/tipSite.tsx @@ -8,16 +8,16 @@ import { connect } from 'react-redux' // Components import Banner from './siteBanner' -import TransientDonationOverlay from './transientDonationOverlay' +import TransientTipOverlay from './transientTipOverlay' // Utils -import * as rewardsActions from '../actions/donate_actions' +import * as rewardsActions from '../actions/tip_actions' -interface Props extends RewardsDonate.ComponentProps { - publisher: RewardsDonate.Publisher +interface Props extends RewardsTip.ComponentProps { + publisher: RewardsTip.Publisher } -class DonateToSite extends React.Component { +class TipSite extends React.Component { get actions () { return this.props.actions @@ -35,7 +35,7 @@ class DonateToSite extends React.Component { } { finished - ? + ? : null } @@ -43,7 +43,7 @@ class DonateToSite extends React.Component { } } -export const mapStateToProps = (state: RewardsDonate.ApplicationState) => ({ +export const mapStateToProps = (state: RewardsTip.ApplicationState) => ({ rewardsDonateData: state.rewardsDonateData }) @@ -54,4 +54,4 @@ export const mapDispatchToProps = (dispatch: Dispatch) => ({ export default connect( mapStateToProps, mapDispatchToProps -)(DonateToSite) +)(TipSite) diff --git a/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx b/components/brave_rewards/resources/tip/components/tipTwitterUser.tsx similarity index 75% rename from components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx rename to components/brave_rewards/resources/tip/components/tipTwitterUser.tsx index 580807c05c36..e2c079a3affc 100644 --- a/components/brave_rewards/resources/donate/components/donateToTwitterUser.tsx +++ b/components/brave_rewards/resources/tip/components/tipTwitterUser.tsx @@ -8,18 +8,18 @@ import { connect } from 'react-redux' // Components import Banner from './siteBanner' -import TransientDonationOverlay from './transientDonationOverlay' +import TransientTipOverlay from './transientTipOverlay' // Utils -import * as rewardsActions from '../actions/donate_actions' +import * as rewardsActions from '../actions/tip_actions' import { getLocale } from '../../../../common/locale' -interface Props extends RewardsDonate.ComponentProps { - publisher: RewardsDonate.Publisher - tweetMetaData: RewardsDonate.TweetMetaData +interface Props extends RewardsTip.ComponentProps { + publisher: RewardsTip.Publisher + tweetMetaData: RewardsTip.TweetMetaData } -class DonateToTwitterUser extends React.Component { +class TipTwitterUser extends React.Component { get actions () { return this.props.actions @@ -46,7 +46,7 @@ class DonateToTwitterUser extends React.Component { } { finished - ? { } } -export const mapStateToProps = (state: RewardsDonate.ApplicationState) => ({ +export const mapStateToProps = (state: RewardsTip.ApplicationState) => ({ rewardsDonateData: state.rewardsDonateData }) @@ -69,4 +69,4 @@ export const mapDispatchToProps = (dispatch: Dispatch) => ({ export default connect( mapStateToProps, mapDispatchToProps -)(DonateToTwitterUser) +)(TipTwitterUser) diff --git a/components/brave_rewards/resources/donate/components/transientDonationOverlay.tsx b/components/brave_rewards/resources/tip/components/transientTipOverlay.tsx similarity index 86% rename from components/brave_rewards/resources/donate/components/transientDonationOverlay.tsx rename to components/brave_rewards/resources/tip/components/transientTipOverlay.tsx index 8cd0e6edae72..32103e46e9dc 100644 --- a/components/brave_rewards/resources/donate/components/transientDonationOverlay.tsx +++ b/components/brave_rewards/resources/tip/components/transientTipOverlay.tsx @@ -10,15 +10,15 @@ import { connect } from 'react-redux' import DonationOverlay from 'brave-ui/features/rewards/donationOverlay' // Utils -import * as rewardsActions from '../actions/donate_actions' +import * as rewardsActions from '../actions/tip_actions' -interface Props extends RewardsDonate.ComponentProps { - publisher: RewardsDonate.Publisher +interface Props extends RewardsTip.ComponentProps { + publisher: RewardsTip.Publisher timeout: number onTweet?: () => void } -class TransientDonationOverlay extends React.Component { +class TransientTipOverlay extends React.Component { get actions () { return this.props.actions @@ -86,7 +86,7 @@ class TransientDonationOverlay extends React.Component { } } -export const mapStateToProps = (state: RewardsDonate.ApplicationState) => ({ +export const mapStateToProps = (state: RewardsTip.ApplicationState) => ({ rewardsDonateData: state.rewardsDonateData }) @@ -97,4 +97,4 @@ export const mapDispatchToProps = (dispatch: Dispatch) => ({ export default connect( mapStateToProps, mapDispatchToProps -)(TransientDonationOverlay) +)(TransientTipOverlay) diff --git a/components/brave_rewards/resources/donate/components/tweetBox.tsx b/components/brave_rewards/resources/tip/components/tweetBox.tsx similarity index 85% rename from components/brave_rewards/resources/donate/components/tweetBox.tsx rename to components/brave_rewards/resources/tip/components/tweetBox.tsx index 3507f418c459..71dff7e42873 100644 --- a/components/brave_rewards/resources/donate/components/tweetBox.tsx +++ b/components/brave_rewards/resources/tip/components/tweetBox.tsx @@ -7,13 +7,13 @@ import { bindActionCreators, Dispatch } from 'redux' import { connect } from 'react-redux' // Utils -import * as donateActions from '../actions/donate_actions' +import * as tipActions from '../actions/tip_actions' // Assets const twitterImg = require('../../img/twitter.svg') -interface Props extends RewardsDonate.ComponentProps { - tweetMetaData: RewardsDonate.TweetMetaData +interface Props extends RewardsTip.ComponentProps { + tweetMetaData: RewardsTip.TweetMetaData } class TweetBox extends React.Component { @@ -47,12 +47,12 @@ class TweetBox extends React.Component { } } -const mapStateToProps = (state: RewardsDonate.ApplicationState) => ({ +const mapStateToProps = (state: RewardsTip.ApplicationState) => ({ rewardsDonateData: state.rewardsDonateData }) const mapDispatchToProps = (dispatch: Dispatch) => ({ - actions: bindActionCreators(donateActions, dispatch) + actions: bindActionCreators(tipActions, dispatch) }) export default connect( diff --git a/components/brave_rewards/resources/tip/reducers/tip_reducer.ts b/components/brave_rewards/resources/tip/reducers/tip_reducer.ts index 2dbd40b799cc..629b924ecb43 100644 --- a/components/brave_rewards/resources/tip/reducers/tip_reducer.ts +++ b/components/brave_rewards/resources/tip/reducers/tip_reducer.ts @@ -32,7 +32,7 @@ const publishersReducer: Reducer = (state: RewardsTip.State = chrome.send('dialogClose') break case types.ON_TWEET: - chrome.send('brave_rewards_donate.tweetTip', [ + chrome.send('brave_rewards_tip.tweetTip', [ payload.tweetMetaData ]) break From c67d7954ceeb03416b17f6f49748f17a1f7bbd32 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Thu, 9 May 2019 15:44:59 -0400 Subject: [PATCH 19/37] Move TweetBox component to brave-ui --- .../brave_rewards/resources/tip/components/siteBanner.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/brave_rewards/resources/tip/components/siteBanner.tsx b/components/brave_rewards/resources/tip/components/siteBanner.tsx index 0c20c32c510f..8bec5fdbaa44 100644 --- a/components/brave_rewards/resources/tip/components/siteBanner.tsx +++ b/components/brave_rewards/resources/tip/components/siteBanner.tsx @@ -7,9 +7,8 @@ import { bindActionCreators, Dispatch } from 'redux' import { connect } from 'react-redux' // Components -import { SiteBanner } from 'brave-ui/features/rewards' import { Provider } from 'brave-ui/features/rewards/profile' -import TweetBox from './tweetBox' +import { SiteBanner, TweetBox } from 'brave-ui/features/rewards' // Utils import * as tipActions from '../actions/tip_actions' @@ -170,7 +169,7 @@ class Banner extends React.Component { > { this.props.tweetMetaData - ? + ? : publisher.description } From 0a4467e84a30bae16d6496798df0ea91c33a1107 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Fri, 10 May 2019 17:24:41 -0400 Subject: [PATCH 20/37] Ensure intent_url is valid before using it --- browser/ui/webui/brave_tip_ui.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/browser/ui/webui/brave_tip_ui.cc b/browser/ui/webui/brave_tip_ui.cc index ed4ae935d45b..b33ea3548eeb 100644 --- a/browser/ui/webui/brave_tip_ui.cc +++ b/browser/ui/webui/brave_tip_ui.cc @@ -367,8 +367,11 @@ void RewardsTipDOMHandler::TweetTip(const base::ListValue *args) { base::StringPrintf("https://twitter.com/intent/tweet?url=%s&text=%s", quoted_tweet_url.c_str(), comment.c_str()); - // Open a new tab with the prepopulated tweet ready to post. GURL gurl(intent_url); + if (!gurl.is_valid()) + return; + + // Open a new tab with the prepopulated tweet ready to post. chrome::ScopedTabbedBrowserDisplayer browser_displayer( Profile::FromWebUI(web_ui())); content::OpenURLParams open_url_params( From f22a434dbdbe43b4b31e521597fe78315588ac3d Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Mon, 13 May 2019 10:35:54 -0400 Subject: [PATCH 21/37] Don't include incognito info when getting tab --- browser/extensions/api/brave_rewards_api.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/browser/extensions/api/brave_rewards_api.cc b/browser/extensions/api/brave_rewards_api.cc index 2939c98124ba..f1273c9774aa 100644 --- a/browser/extensions/api/brave_rewards_api.cc +++ b/browser/extensions/api/brave_rewards_api.cc @@ -63,7 +63,7 @@ ExtensionFunction::ResponseAction BraveRewardsTipSiteFunction::Run() { if (!ExtensionTabUtil::GetTabById( params->tab_id, profile, - include_incognito_information(), + false, nullptr, nullptr, &contents, @@ -133,7 +133,7 @@ void BraveRewardsTipTwitterUserFunction::OnTwitterPublisherInfoSaved( if (!ExtensionTabUtil::GetTabById( params->tab_id, Profile::FromBrowserContext(browser_context()), - include_incognito_information(), + false, nullptr, nullptr, &contents, From 8d18c41a6e74d338da987edc32d515f010d996c5 Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Tue, 14 May 2019 12:00:05 +0200 Subject: [PATCH 22/37] Add callback to save visit --- .../include/bat/ledger/ledger.h | 5 -- .../src/bat/ledger/internal/bat_publishers.cc | 34 +++++++-- .../src/bat/ledger/internal/bat_publishers.h | 8 ++- .../src/bat/ledger/internal/ledger_impl.cc | 29 +++++++- .../src/bat/ledger/internal/ledger_impl.h | 6 +- .../src/bat/ledger/internal/media/twitch.cc | 69 ++++++++++++++----- .../src/bat/ledger/internal/media/twitch.h | 3 + .../src/bat/ledger/internal/media/twitter.cc | 12 +--- .../src/bat/ledger/internal/media/youtube.cc | 26 ++++++- .../src/bat/ledger/internal/media/youtube.h | 3 + 10 files changed, 148 insertions(+), 47 deletions(-) diff --git a/vendor/bat-native-ledger/include/bat/ledger/ledger.h b/vendor/bat-native-ledger/include/bat/ledger/ledger.h index b9bfd290b77d..1da1a5944996 100644 --- a/vendor/bat-native-ledger/include/bat/ledger/ledger.h +++ b/vendor/bat-native-ledger/include/bat/ledger/ledger.h @@ -226,11 +226,6 @@ class LEDGER_EXPORT Ledger { virtual void RecoverWallet(const std::string& passPhrase) const = 0; - virtual void SaveMediaVisit(const std::string& publisher_id, - const ledger::VisitData& visit_data, - const uint64_t& duration, - const uint64_t window_id) = 0; - virtual void SetPublisherExclude( const std::string& publisher_id, const ledger::PUBLISHER_EXCLUDE& exclude) = 0; diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc index f29590fb1934..bad115b0c31c 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc @@ -85,7 +85,8 @@ void BatPublishers::AddRecurringPayment(const std::string& publisher_id, void BatPublishers::saveVisit(const std::string& publisher_id, const ledger::VisitData& visit_data, const uint64_t& duration, - uint64_t window_id) { + uint64_t window_id, + const ledger::PublisherInfoCallback callback) { if (!ledger_->GetRewardsMainEnabled() || publisher_id.empty()) { return; } @@ -103,6 +104,7 @@ void BatPublishers::saveVisit(const std::string& publisher_id, visit_data, duration, window_id, + callback, _1, _2); ledger_->GetActivityInfo(filter, callbackGetPublishers); @@ -137,12 +139,13 @@ void BatPublishers::saveVisitInternal( ledger::VisitData visit_data, uint64_t duration, uint64_t window_id, + const ledger::PublisherInfoCallback callback, ledger::Result result, ledger::PublisherInfoPtr publisher_info) { DCHECK(result != ledger::Result::TOO_MANY_RESULTS); if (result != ledger::Result::LEDGER_OK && result != ledger::Result::NOT_FOUND) { - // TODO(anyone) error handling + callback(ledger::Result::LEDGER_ERROR, nullptr); return; } bool verified = isVerified(publisher_id); @@ -221,15 +224,20 @@ void BatPublishers::saveVisitInternal( ledger_->SetActivityInfo(std::move(publisher_info)); } - if (panel_info && window_id > 0) { + if (panel_info) { if (panel_info->favicon_url == ledger::_clear_favicon) { panel_info->favicon_url = std::string(); } - OnPanelPublisherInfo(ledger::Result::LEDGER_OK, - std::move(panel_info), - window_id, - visit_data); + auto callback_info = std::make_unique(*panel_info); + callback(ledger::Result::LEDGER_OK, std::move(callback_info)); + + if (window_id > 0) { + OnPanelPublisherInfo(ledger::Result::LEDGER_OK, + std::move(panel_info), + window_id, + visit_data); + } } } @@ -735,6 +743,12 @@ void BatPublishers::getPublisherActivityFromUrl( new_data)); } +void BatPublishers::OnSaveVisitInternal( + ledger::Result result, + std::unique_ptr info) { + // TODO(nejczdovc): handle if needed +} + void BatPublishers::OnPanelPublisherInfo( ledger::Result result, ledger::PublisherInfoPtr info, @@ -745,10 +759,16 @@ void BatPublishers::OnPanelPublisherInfo( } if (result == ledger::Result::NOT_FOUND && !visit_data.domain.empty()) { + auto callback = std::bind(&BatPublishers::OnSaveVisitInternal, + this, + _1, + _2); + saveVisitInternal(visit_data.domain, visit_data, 0, windowId, + callback, result, nullptr); } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.h b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.h index d65dc4d4370c..ae57055c8c84 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.h @@ -38,7 +38,8 @@ class BatPublishers : public ledger::LedgerCallbackHandler { void saveVisit(const std::string& publisher_id, const ledger::VisitData& visit_data, const uint64_t& duration, - uint64_t window_id); + uint64_t window_id, + const ledger::PublisherInfoCallback callback); void AddRecurringPayment(const std::string& publisher_id, const double& value); @@ -144,6 +145,7 @@ class BatPublishers : public ledger::LedgerCallbackHandler { ledger::VisitData visit_data, uint64_t duration, uint64_t window_id, + const ledger::PublisherInfoCallback callback, ledger::Result result, ledger::PublisherInfoPtr publisher_info); @@ -186,6 +188,10 @@ class BatPublishers : public ledger::LedgerCallbackHandler { bool isPublisherVisible( const braveledger_bat_helper::PUBLISHER_ST& publisher_st); + void OnSaveVisitInternal( + ledger::Result result, + std::unique_ptr info); + void OnPanelPublisherInfo( ledger::Result result, ledger::PublisherInfoPtr publisher_info, diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc index ec9a5e5a2fc3..a884fd5237a0 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc @@ -146,17 +146,35 @@ void LedgerImpl::OnShow(uint32_t tab_id, const uint64_t& current_time) { last_shown_tab_id_ = tab_id; } +void LedgerImpl::OnSaveVisit( + ledger::Result result, + std::unique_ptr info) { + // TODO(nejczdovc): handle if needed +} + void LedgerImpl::OnHide(uint32_t tab_id, const uint64_t& current_time) { if (tab_id != last_shown_tab_id_) { return; } + visit_data_iter iter = current_pages_.find(tab_id); if (iter == current_pages_.end() || last_tab_active_time_ == 0) { return; } + DCHECK(last_tab_active_time_); + + auto callback = std::bind(&LedgerImpl::OnSaveVisit, + this, + _1, + _2); + bat_publishers_->saveVisit( - iter->second.tld, iter->second, current_time - last_tab_active_time_, 0); + iter->second.tld, + iter->second, + current_time - last_tab_active_time_, + 0, + callback); last_tab_active_time_ = 0; } @@ -420,13 +438,18 @@ void LedgerImpl::SetMediaPublisherInfo(const std::string& media_key, void LedgerImpl::SaveMediaVisit(const std::string& publisher_id, const ledger::VisitData& visit_data, const uint64_t& duration, - const uint64_t window_id) { + const uint64_t window_id, + const ledger::PublisherInfoCallback callback) { uint64_t new_duration = duration; if (!bat_publishers_->getPublisherAllowVideos()) { new_duration = 0; } - bat_publishers_->saveVisit(publisher_id, visit_data, new_duration, window_id); + bat_publishers_->saveVisit(publisher_id, + visit_data, + new_duration, + window_id, + callback); } void LedgerImpl::SetPublisherExclude( diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h index 5d92b279202d..b5a6ed67e286 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h @@ -234,7 +234,8 @@ class LedgerImpl : public ledger::Ledger, void SaveMediaVisit(const std::string& publisher_id, const ledger::VisitData& visit_data, const uint64_t& duration, - const uint64_t window_id) override; + const uint64_t window_id, + const ledger::PublisherInfoCallback callback); void SetPublisherExclude( const std::string& publisher_id, @@ -459,6 +460,9 @@ class LedgerImpl : public ledger::Ledger, void OnShow(uint32_t tab_id, const uint64_t& current_time) override; + void OnSaveVisit(ledger::Result result, + std::unique_ptr info); + void OnHide(uint32_t tab_id, const uint64_t& current_time) override; void OnForeground(uint32_t tab_id, const uint64_t& current_time) override; diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc index 467901b4bc9b..210f322b3fe3 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc @@ -363,6 +363,12 @@ void MediaTwitch::ProcessActivityFromUrl(uint64_t window_id, } } +void MediaTwitch::OnSaveMediaVisit( + ledger::Result result, + std::unique_ptr info) { + // TODO(nejczdovc): handle if needed +} + void MediaTwitch::OnMediaPublisherInfo( const std::string& media_id, const std::string& media_key, @@ -405,8 +411,6 @@ void MediaTwitch::OnMediaPublisherInfo( updated_visit_data.favicon_url = ""; updated_visit_data.provider = TWITCH_MEDIA_TYPE; - - if (media_id.find("_vod_") != std::string::npos) { // VOD std::vector media_props = @@ -422,18 +426,17 @@ void MediaTwitch::OnMediaPublisherInfo( updated_visit_data.name = new_id; updated_visit_data.url = media_url + "/videos"; - auto callback = std::bind( - &MediaTwitch::OnEmbedResponse, - this, - real_duration, - media_key, - media_url, - updated_visit_data, - window_id, - user_id, - _1, - _2, - _3); + auto callback = std::bind(&MediaTwitch::OnEmbedResponse, + this, + real_duration, + media_key, + media_url, + updated_visit_data, + window_id, + user_id, + _1, + _2, + _3); const std::string url = (std::string)TWITCH_PROVIDER_URL + "?json&url=" + ledger_->URIEncode(oembed_url); @@ -447,10 +450,16 @@ void MediaTwitch::OnMediaPublisherInfo( updated_visit_data.name = media_id; updated_visit_data.url = GetMediaURL(media_id) + "/videos"; + auto callback = std::bind(&MediaTwitch::OnSaveMediaVisit, + this, + _1, + _2); + ledger_->SaveMediaVisit(publisher_key, updated_visit_data, real_duration, - window_id); + window_id, + callback); ledger_->SetMediaPublisherInfo(media_key, publisher_key); } else { ledger::VisitData updated_visit_data(visit_data); @@ -473,7 +482,16 @@ void MediaTwitch::OnMediaPublisherInfo( twitch_events[media_key] = new_event; std::string id = publisher_info->id; - ledger_->SaveMediaVisit(id, updated_visit_data, real_duration, window_id); + auto callback = std::bind(&MediaTwitch::OnSaveMediaVisit, + this, + _1, + _2); + + ledger_->SaveMediaVisit(id, + updated_visit_data, + real_duration, + window_id, + callback); } } @@ -521,7 +539,16 @@ void MediaTwitch::OnEmbedResponse( updated_visit_data.favicon_url = fav_icon; } - ledger_->SaveMediaVisit(id, updated_visit_data, duration, window_id); + auto callback = std::bind(&MediaTwitch::OnSaveMediaVisit, + this, + _1, + _2); + + ledger_->SaveMediaVisit(id, + updated_visit_data, + duration, + window_id, + callback); ledger_->SetMediaPublisherInfo(media_key, id); } @@ -646,10 +673,16 @@ void MediaTwitch::SavePublisherInfo(const uint64_t duration, updated_visit_data.name = publisher_name; updated_visit_data.url = url; + auto callback = std::bind(&MediaTwitch::OnSaveMediaVisit, + this, + _1, + _2); + ledger_->SaveMediaVisit(publisher_id, updated_visit_data, duration, - window_id); + window_id, + callback); if (!media_key.empty()) { ledger_->SetMediaPublisherInfo(media_key, publisher_id); } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h index b3736aec1a6f..34584f8a2052 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h @@ -72,6 +72,9 @@ class MediaTwitch : public ledger::LedgerCallbackHandler { static std::string GetFaviconUrl(const std::string& publisher_blob, const std::string& twitchHandle); + void OnSaveMediaVisit(ledger::Result result, + std::unique_ptr info); + void OnMediaPublisherInfo( const std::string& media_id, const std::string& media_key, diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc index 554afff23fe9..58928da7d942 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc @@ -68,19 +68,11 @@ void MediaTwitter::SaveMediaInfo(const std::map& data, visit_data.name = publisher_name; visit_data.url = url; - // TODO(nejczdovc): SaveMediaVisit needs to have callback ledger_->SaveMediaVisit(publisher_key, visit_data, 0, - 0); - - // Only temp until we create callback - auto publisher_info = std::make_unique(); - publisher_info->id = publisher_key; - publisher_info->name = publisher_name; - publisher_info->favicon_url = favicon_url; - publisher_info->provider = TWITTER_MEDIA_TYPE; - callback(ledger::Result::LEDGER_OK, std::move(publisher_info)); + 0, + callback); } } // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc index 8277957e4c8f..ce73fd7de788 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc @@ -376,6 +376,12 @@ void MediaYouTube::ProcessActivityFromUrl(uint64_t window_id, OnMediaActivityError(visit_data, window_id); } +void MediaYouTube::OnSaveMediaVisit( + ledger::Result result, + std::unique_ptr info) { + // TODO(nejczdovc): handle if needed +} + void MediaYouTube::OnMediaPublisherInfo( const std::string& media_id, const std::string& media_key, @@ -417,7 +423,17 @@ void MediaYouTube::OnMediaPublisherInfo( updated_visit_data.provider = YOUTUBE_MEDIA_TYPE; updated_visit_data.favicon_url = publisher_info->favicon_url; std::string id = publisher_info->id; - ledger_->SaveMediaVisit(id, updated_visit_data, duration, window_id); + + auto callback = std::bind(&MediaYouTube::OnSaveMediaVisit, + this, + _1, + _2); + + ledger_->SaveMediaVisit(id, + updated_visit_data, + duration, + window_id, + callback); } } @@ -545,10 +561,16 @@ void MediaYouTube::SavePublisherInfo(const uint64_t duration, updated_visit_data.name = publisher_name; updated_visit_data.url = url; + auto callback = std::bind(&MediaYouTube::OnSaveMediaVisit, + this, + _1, + _2); + ledger_->SaveMediaVisit(publisher_id, updated_visit_data, duration, - window_id); + window_id, + callback); if (!media_key.empty()) { ledger_->SetMediaPublisherInfo(media_key, publisher_id); } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h index 3e16b2f7d264..f1de18aedc61 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h @@ -71,6 +71,9 @@ class MediaYouTube : public ledger::LedgerCallbackHandler { void OnMediaActivityError(const ledger::VisitData& visit_data, uint64_t window_id); + void OnSaveMediaVisit(ledger::Result result, + std::unique_ptr info); + void OnMediaPublisherInfo( const std::string& media_id, const std::string& media_key, From 977f3f71630974eb0ad60a48295742977c3f47fb Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Tue, 14 May 2019 12:00:50 -0400 Subject: [PATCH 23/37] Add new elements to shadow DOM --- .../extension/brave_rewards/content.ts | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/components/brave_rewards/resources/extension/brave_rewards/content.ts b/components/brave_rewards/resources/extension/brave_rewards/content.ts index 03c87d30c6cb..96c4ed56449c 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/content.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/content.ts @@ -38,10 +38,22 @@ const createBraveTipAction = (tweet: Element) => { // Create the tip action const braveTipAction = document.createElement('div') braveTipAction.className = 'ProfileTweet-action action-brave-tip' + braveTipAction.style.display = 'inline-block' + braveTipAction.style.minWidth = '80px' // Create the tip button const braveTipButton = document.createElement('button') braveTipButton.className = 'ProfileTweet-actionButton u-textUserColorHover js-actionButton' + braveTipButton.style.background = 'transparent' + braveTipButton.style.border = '0' + braveTipButton.style.color = '#657786' + braveTipButton.style.cursor = 'pointer' + braveTipButton.style.display = 'inline-block' + braveTipButton.style.fontSize = '16px' + braveTipButton.style.lineHeight = '1' + braveTipButton.style.outline = '0' + braveTipButton.style.padding = '0 2px' + braveTipButton.style.position = 'relative' braveTipButton.type = 'button' braveTipButton.onclick = function (event) { const tweetMetaData = getTweetMetaData(tweet) @@ -49,22 +61,32 @@ const createBraveTipAction = (tweet: Element) => { const msg = { type: 'tipTwitterUser', tweetMetaData: tweetMetaData } chrome.runtime.sendMessage(msg) } + event.stopPropagation() } - braveTipAction.appendChild(braveTipButton) // Create the tip icon container const braveTipIconContainer = document.createElement('div') braveTipIconContainer.className = 'IconContainer js-tooltip' + braveTipIconContainer.style.display = 'inline-block' + braveTipIconContainer.style.lineHeight = '0' + braveTipIconContainer.style.position = 'relative' + braveTipIconContainer.style.verticalAlign = 'middle' braveTipIconContainer.setAttribute('data-original-title', getMessage('twitterTipsHoverText')) braveTipButton.appendChild(braveTipIconContainer) // Create the tip icon const braveTipIcon = document.createElement('span') braveTipIcon.className = 'Icon Icon--medium' + braveTipIcon.style.background = 'transparent' braveTipIcon.style.content = 'url(\'data:image/svg+xml;utf8,BAT_icon\')' + braveTipIcon.style.display = 'inline-block' + braveTipIcon.style.fontSize = '18px' + braveTipIcon.style.fontStyle = 'normal' + braveTipIcon.style.height = '16px' braveTipIcon.style.marginTop = '5px' + braveTipIcon.style.position = 'relative' + braveTipIcon.style.verticalAlign = 'baseline' braveTipIcon.style.width = '16px' - braveTipIcon.style.height = '16px' braveTipIconContainer.appendChild(braveTipIcon) // Create the tip action count (typically used to present a counter @@ -72,13 +94,26 @@ const createBraveTipAction = (tweet: Element) => { // action label) const braveTipActionCount = document.createElement('span') braveTipActionCount.className = 'ProfileTweet-actionCount' + braveTipActionCount.style.color = '#657786' + braveTipActionCount.style.display = 'inline-block' + braveTipActionCount.style.fontSize = '12px' + braveTipActionCount.style.fontWeight = 'bold' + braveTipActionCount.style.lineHeight = '1' + braveTipActionCount.style.marginLeft = '6px' + braveTipActionCount.style.position = 'relative' + braveTipActionCount.style.verticalAlign = 'text-bottom' braveTipButton.appendChild(braveTipActionCount) + // Create the tip action count presentation const braveTipActionCountPresentation = document.createElement('span') braveTipActionCountPresentation.className = 'ProfileTweet-actionCountForPresentation' braveTipActionCountPresentation.textContent = getMessage('twitterTipsIconLabel') braveTipActionCount.appendChild(braveTipActionCountPresentation) + // Create the shadow DOM root that hosts our injected DOM elements + const shadowRoot = braveTipAction.attachShadow({ mode: 'open' }) + shadowRoot.appendChild(braveTipButton) + return braveTipAction } From 42685d6deecbbb6ef0ffd3b0e7f9130406c37f38 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Tue, 14 May 2019 12:23:45 -0400 Subject: [PATCH 24/37] Correctly handle Twitter-based publishers --- .../bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc index bad115b0c31c..3844f54e54d1 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc @@ -68,6 +68,8 @@ std::string getProviderName(const std::string& publisher_id) { return YOUTUBE_MEDIA_TYPE; } else if (publisher_id.find(TWITCH_MEDIA_TYPE) != std::string::npos) { return TWITCH_MEDIA_TYPE; + } else if (publisher_id.find(TWITTER_MEDIA_TYPE) != std::string::npos) { + return TWITTER_MEDIA_TYPE; } return ""; } From 80c7ecc2dfbab94c78a7b8ba0a65880401af8fc2 Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Wed, 15 May 2019 07:58:19 +0200 Subject: [PATCH 25/37] Handle second visit correctly --- .../include/bat/ledger/ledger.h | 4 +- .../src/bat/ledger/internal/bat_get_media.cc | 2 +- .../src/bat/ledger/internal/bat_get_media.h | 2 +- .../src/bat/ledger/internal/ledger_impl.cc | 2 +- .../src/bat/ledger/internal/ledger_impl.h | 2 +- .../src/bat/ledger/internal/media/twitter.cc | 99 +++++++++++++++++-- .../src/bat/ledger/internal/media/twitter.h | 22 ++++- 7 files changed, 116 insertions(+), 17 deletions(-) diff --git a/vendor/bat-native-ledger/include/bat/ledger/ledger.h b/vendor/bat-native-ledger/include/bat/ledger/ledger.h index 1da1a5944996..91e90bd3bd03 100644 --- a/vendor/bat-native-ledger/include/bat/ledger/ledger.h +++ b/vendor/bat-native-ledger/include/bat/ledger/ledger.h @@ -62,8 +62,6 @@ using GetTransactionHistoryForThisCycleCallback = using GetExcludedPublishersNumberDBCallback = std::function; using OnWalletPropertiesCallback = std::function)>; -using SaveMediaInfoCallback = std::function)>; using OnRefreshPublisherCallback = std::function; @@ -287,7 +285,7 @@ class LEDGER_EXPORT Ledger { virtual void SaveMediaInfo(const std::string& type, const std::map& data, - ledger::SaveMediaInfoCallback callback) = 0; + ledger::PublisherInfoCallback callback) = 0; virtual void SetInlineTipSetting(const std::string& key, bool enabled) = 0; diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc index 81bff5753fb4..6b18d9e3f54e 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc @@ -104,7 +104,7 @@ void BatGetMedia::OnMediaActivityError(const ledger::VisitData& visit_data, void BatGetMedia::SaveMediaInfo(const std::string& type, const std::map& data, - ledger::SaveMediaInfoCallback callback) { + ledger::PublisherInfoCallback callback) { if (type == TWITTER_MEDIA_TYPE) { media_twitter_->SaveMediaInfo(data, callback); return; diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h index 48d5720f5538..0fc5982fc3c8 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h @@ -43,7 +43,7 @@ class BatGetMedia { void SaveMediaInfo(const std::string& type, const std::map& data, - ledger::SaveMediaInfoCallback callback); + ledger::PublisherInfoCallback callback); private: void OnMediaActivityError(const ledger::VisitData& visit_data, diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc index a884fd5237a0..8d4410f1e279 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc @@ -1529,7 +1529,7 @@ scoped_refptr LedgerImpl::GetTaskRunner() { void LedgerImpl::SaveMediaInfo(const std::string& type, const std::map& data, - ledger::SaveMediaInfoCallback callback) { + ledger::PublisherInfoCallback callback) { bat_get_media_->SaveMediaInfo(type, data, callback); } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h index b5a6ed67e286..f0904e2213e7 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h @@ -443,7 +443,7 @@ class LedgerImpl : public ledger::Ledger, void SaveMediaInfo(const std::string& type, const std::map& data, - ledger::SaveMediaInfoCallback callback) override; + ledger::PublisherInfoCallback callback) override; void SetInlineTipSetting(const std::string& key, bool enabled) override; diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc index 58928da7d942..e3a044c2fc95 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc @@ -4,7 +4,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include -#include #include #include @@ -28,11 +27,19 @@ MediaTwitter::~MediaTwitter() { // static std::string MediaTwitter::GetProfileURL(const std::string& screen_name) { + if (screen_name.empty()) { + return std::string(); + } + return base::StringPrintf("https://twitter.com/%s/", screen_name.c_str()); } // static std::string MediaTwitter::GetProfileImageURL(const std::string& screen_name) { + if (screen_name.empty()) { + return std::string(); + } + return base::StringPrintf( "https://twitter.com/%s/profile_image?size=original", screen_name.c_str()); @@ -40,11 +47,24 @@ std::string MediaTwitter::GetProfileImageURL(const std::string& screen_name) { // static std::string MediaTwitter::GetPublisherKey(const std::string& key) { + if (key.empty()) { + return std::string(); + } + return (std::string)TWITTER_MEDIA_TYPE + "#channel:" + key; } +// static +std::string MediaTwitter::GetMediaKey(const std::string& screen_name) { + if (screen_name.empty()) { + return std::string(); + } + + return (std::string)TWITTER_MEDIA_TYPE + "_" + screen_name; +} + void MediaTwitter::SaveMediaInfo(const std::map& data, - ledger::SaveMediaInfoCallback callback) { + ledger::PublisherInfoCallback callback) { auto user_id = data.find("user_id"); auto screen_name = data.find("screen_name"); if (user_id == data.end() || screen_name == data.end()) { @@ -52,9 +72,7 @@ void MediaTwitter::SaveMediaInfo(const std::map& data, return; } - const std::string publisher_key = GetPublisherKey(user_id->second); - const std::string url = GetProfileURL(screen_name->second); - const std::string favicon_url = GetProfileImageURL(screen_name->second); + const std::string media_key = GetMediaKey(screen_name->second); auto name = data.find("name"); std::string publisher_name = screen_name->second; @@ -62,17 +80,80 @@ void MediaTwitter::SaveMediaInfo(const std::map& data, publisher_name = name->second; } + ledger_->GetMediaPublisherInfo( + media_key, + std::bind(&MediaTwitter::OnMediaPublisherInfo, + this, + 0, + user_id->second, + screen_name->second, + publisher_name, + callback, + _1, + _2)); +} + +void MediaTwitter::OnMediaPublisherInfo( + uint64_t window_id, + const std::string& user_id, + const std::string& screen_name, + const std::string& publisher_name, + ledger::PublisherInfoCallback callback, + ledger::Result result, + std::unique_ptr publisher_info) { + if (result != ledger::Result::LEDGER_OK && + result != ledger::Result::NOT_FOUND) { + callback(ledger::Result::LEDGER_ERROR, nullptr); + return; + } + + if (!publisher_info || result == ledger::Result::NOT_FOUND) { + SavePublisherInfo(0, + user_id, + screen_name, + publisher_name, + window_id, + callback); + } else { + // TODO(nejczdovc): we need to check if user is verified, + // but his image was not saved yet, so that we can fix it + callback(result, std::move(publisher_info)); + } +} + +void MediaTwitter::SavePublisherInfo( + const uint64_t duration, + const std::string& user_id, + const std::string& screen_name, + const std::string& publisher_name, + const uint64_t window_id, + ledger::PublisherInfoCallback callback) { + const std::string publisher_key = GetPublisherKey(user_id); + const std::string url = GetProfileURL(screen_name); + const std::string favicon_url = GetProfileImageURL(screen_name); + const std::string media_key = GetMediaKey(screen_name); + + if (publisher_key.empty()) { + callback(ledger::Result::LEDGER_ERROR, nullptr); + BLOG(ledger_, ledger::LogLevel::LOG_ERROR) << + "Publisher key is missing for: " << media_key; + return; + } + ledger::VisitData visit_data; - visit_data.favicon_url = favicon_url; visit_data.provider = TWITTER_MEDIA_TYPE; - visit_data.name = publisher_name; visit_data.url = url; + visit_data.favicon_url = favicon_url; + visit_data.name = publisher_name; ledger_->SaveMediaVisit(publisher_key, visit_data, - 0, - 0, + duration, + window_id, callback); + if (!media_key.empty()) { + ledger_->SetMediaPublisherInfo(media_key, publisher_key); + } } } // namespace braveledger_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h index 92344f7b68a7..fe2bafb7e181 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h @@ -7,6 +7,7 @@ #define BRAVELEDGER_MEDIA_TWITTER_H_ #include +#include #include #include "base/gtest_prod_util.h" @@ -25,7 +26,7 @@ class MediaTwitter : public ledger::LedgerCallbackHandler { ~MediaTwitter() override; void SaveMediaInfo(const std::map& data, - ledger::SaveMediaInfoCallback callback); + ledger::PublisherInfoCallback callback); private: static std::string GetProfileURL(const std::string& screen_name); @@ -34,6 +35,25 @@ class MediaTwitter : public ledger::LedgerCallbackHandler { static std::string GetPublisherKey(const std::string& key); + static std::string GetMediaKey(const std::string& screen_name); + + void OnMediaPublisherInfo( + uint64_t window_id, + const std::string& user_id, + const std::string& screen_name, + const std::string& publisher_name, + ledger::PublisherInfoCallback callback, + ledger::Result result, + std::unique_ptr publisher_info); + + void SavePublisherInfo( + const uint64_t duration, + const std::string& user_id, + const std::string& screen_name, + const std::string& publisher_name, + const uint64_t window_id, + ledger::PublisherInfoCallback callback); + bat_ledger::LedgerImpl* ledger_; // NOT OWNED }; From 4247d109dd33b3341352dc48c85fccac493a4468 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Thu, 16 May 2019 12:27:49 -0400 Subject: [PATCH 26/37] Account for refactoring of PublisherInfo data type --- components/brave_rewards/browser/rewards_service_impl.cc | 8 +++----- components/brave_rewards/browser/rewards_service_impl.h | 2 +- components/services/bat_ledger/bat_ledger_impl.cc | 9 ++------- components/services/bat_ledger/bat_ledger_impl.h | 2 +- .../bat_ledger/public/interfaces/bat_ledger.mojom | 2 +- .../src/bat/ledger/internal/bat_publishers.cc | 4 ++-- .../src/bat/ledger/internal/bat_publishers.h | 2 +- .../src/bat/ledger/internal/ledger_impl.cc | 2 +- .../src/bat/ledger/internal/ledger_impl.h | 2 +- .../src/bat/ledger/internal/media/twitch.cc | 2 +- .../src/bat/ledger/internal/media/twitch.h | 2 +- .../src/bat/ledger/internal/media/twitter.cc | 2 +- .../src/bat/ledger/internal/media/twitter.h | 2 +- .../src/bat/ledger/internal/media/youtube.cc | 2 +- .../src/bat/ledger/internal/media/youtube.h | 2 +- 15 files changed, 19 insertions(+), 26 deletions(-) diff --git a/components/brave_rewards/browser/rewards_service_impl.cc b/components/brave_rewards/browser/rewards_service_impl.cc index 5e6e796f51d8..9da9e21cbbe7 100644 --- a/components/brave_rewards/browser/rewards_service_impl.cc +++ b/components/brave_rewards/browser/rewards_service_impl.cc @@ -2244,16 +2244,14 @@ void RewardsServiceImpl::SaveRecurringTip( void RewardsServiceImpl::OnTwitterPublisherInfoSaved( SaveMediaInfoCallback callback, int result, - const std::string& json_publisher) { + ledger::PublisherInfoPtr publisher) { if (Connected()) { ledger::Result result_converted = static_cast(result); std::unique_ptr site; if (result_converted == ledger::Result::LEDGER_OK) { - ledger::PublisherInfo publisher; - publisher.loadFromJson(json_publisher); - site = std::make_unique - (PublisherInfoToContentSite(publisher)); + site = std::make_unique( + PublisherInfoToContentSite(*publisher)); } std::move(callback).Run(std::move(site)); diff --git a/components/brave_rewards/browser/rewards_service_impl.h b/components/brave_rewards/browser/rewards_service_impl.h index 919f6350d8c0..fd5c2a2a9f53 100644 --- a/components/brave_rewards/browser/rewards_service_impl.h +++ b/components/brave_rewards/browser/rewards_service_impl.h @@ -497,7 +497,7 @@ class RewardsServiceImpl : public RewardsService, bool verified); void OnTwitterPublisherInfoSaved(SaveMediaInfoCallback callback, int result, - const std::string& json_publisher); + ledger::PublisherInfoPtr publisher); bool Connected() const; void ConnectionClosed(); diff --git a/components/services/bat_ledger/bat_ledger_impl.cc b/components/services/bat_ledger/bat_ledger_impl.cc index 2e056f3c2def..578c1881d31e 100644 --- a/components/services/bat_ledger/bat_ledger_impl.cc +++ b/components/services/bat_ledger/bat_ledger_impl.cc @@ -515,14 +515,9 @@ void BatLedgerImpl::LoadPublisherInfo( void BatLedgerImpl::OnSaveMediaInfoCallback( CallbackHolder* holder, ledger::Result result, - std::unique_ptr info) { - std::string publisher; - if (info) { - publisher = info->ToJson(); - } - + ledger::PublisherInfoPtr publisher_info) { if (holder->is_valid()) { - std::move(holder->get()).Run(result, publisher); + std::move(holder->get()).Run(result, std::move(publisher_info)); } delete holder; diff --git a/components/services/bat_ledger/bat_ledger_impl.h b/components/services/bat_ledger/bat_ledger_impl.h index 7e3d513e3dff..2d2183a28b68 100644 --- a/components/services/bat_ledger/bat_ledger_impl.h +++ b/components/services/bat_ledger/bat_ledger_impl.h @@ -232,7 +232,7 @@ class BatLedgerImpl : public mojom::BatLedger, static void OnSaveMediaInfoCallback( CallbackHolder* holder, ledger::Result result, - std::unique_ptr info); + ledger::PublisherInfoPtr info); std::unique_ptr bat_ledger_client_mojo_proxy_; std::unique_ptr ledger_; diff --git a/components/services/bat_ledger/public/interfaces/bat_ledger.mojom b/components/services/bat_ledger/public/interfaces/bat_ledger.mojom index 2f135e0c0ddc..3533022abb74 100644 --- a/components/services/bat_ledger/public/interfaces/bat_ledger.mojom +++ b/components/services/bat_ledger/public/interfaces/bat_ledger.mojom @@ -120,7 +120,7 @@ interface BatLedger { StartAutoContribute(); SaveMediaInfo(string type, map args) => (int32 result, - string publisher_info); + ledger.mojom.PublisherInfo? publisher_info); SetInlineTipSetting(string key, bool enabled); diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc index 3844f54e54d1..7ebdd8b5968d 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.cc @@ -231,7 +231,7 @@ void BatPublishers::saveVisitInternal( panel_info->favicon_url = std::string(); } - auto callback_info = std::make_unique(*panel_info); + auto callback_info = panel_info->Clone(); callback(ledger::Result::LEDGER_OK, std::move(callback_info)); if (window_id > 0) { @@ -747,7 +747,7 @@ void BatPublishers::getPublisherActivityFromUrl( void BatPublishers::OnSaveVisitInternal( ledger::Result result, - std::unique_ptr info) { + ledger::PublisherInfoPtr info) { // TODO(nejczdovc): handle if needed } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.h b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.h index ae57055c8c84..ce47b0384e6b 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_publishers.h @@ -190,7 +190,7 @@ class BatPublishers : public ledger::LedgerCallbackHandler { void OnSaveVisitInternal( ledger::Result result, - std::unique_ptr info); + ledger::PublisherInfoPtr info); void OnPanelPublisherInfo( ledger::Result result, diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc index 8d4410f1e279..e713da258202 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc @@ -148,7 +148,7 @@ void LedgerImpl::OnShow(uint32_t tab_id, const uint64_t& current_time) { void LedgerImpl::OnSaveVisit( ledger::Result result, - std::unique_ptr info) { + ledger::PublisherInfoPtr info) { // TODO(nejczdovc): handle if needed } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h index f0904e2213e7..c0bf94ce36bd 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h @@ -461,7 +461,7 @@ class LedgerImpl : public ledger::Ledger, void OnShow(uint32_t tab_id, const uint64_t& current_time) override; void OnSaveVisit(ledger::Result result, - std::unique_ptr info); + ledger::PublisherInfoPtr info); void OnHide(uint32_t tab_id, const uint64_t& current_time) override; diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc index 210f322b3fe3..71c32eea9a36 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.cc @@ -365,7 +365,7 @@ void MediaTwitch::ProcessActivityFromUrl(uint64_t window_id, void MediaTwitch::OnSaveMediaVisit( ledger::Result result, - std::unique_ptr info) { + ledger::PublisherInfoPtr info) { // TODO(nejczdovc): handle if needed } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h index 34584f8a2052..cbdc5f53a02f 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitch.h @@ -73,7 +73,7 @@ class MediaTwitch : public ledger::LedgerCallbackHandler { const std::string& twitchHandle); void OnSaveMediaVisit(ledger::Result result, - std::unique_ptr info); + ledger::PublisherInfoPtr info); void OnMediaPublisherInfo( const std::string& media_id, diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc index e3a044c2fc95..b6a151c6f108 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc @@ -100,7 +100,7 @@ void MediaTwitter::OnMediaPublisherInfo( const std::string& publisher_name, ledger::PublisherInfoCallback callback, ledger::Result result, - std::unique_ptr publisher_info) { + ledger::PublisherInfoPtr publisher_info) { if (result != ledger::Result::LEDGER_OK && result != ledger::Result::NOT_FOUND) { callback(ledger::Result::LEDGER_ERROR, nullptr); diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h index fe2bafb7e181..ae62650055ea 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h @@ -44,7 +44,7 @@ class MediaTwitter : public ledger::LedgerCallbackHandler { const std::string& publisher_name, ledger::PublisherInfoCallback callback, ledger::Result result, - std::unique_ptr publisher_info); + ledger::PublisherInfoPtr publisher_info); void SavePublisherInfo( const uint64_t duration, diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc index ce73fd7de788..f5bdfddc95c2 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.cc @@ -378,7 +378,7 @@ void MediaYouTube::ProcessActivityFromUrl(uint64_t window_id, void MediaYouTube::OnSaveMediaVisit( ledger::Result result, - std::unique_ptr info) { + ledger::PublisherInfoPtr info) { // TODO(nejczdovc): handle if needed } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h index f1de18aedc61..3aef269d4c82 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/youtube.h @@ -72,7 +72,7 @@ class MediaYouTube : public ledger::LedgerCallbackHandler { uint64_t window_id); void OnSaveMediaVisit(ledger::Result result, - std::unique_ptr info); + ledger::PublisherInfoPtr info); void OnMediaPublisherInfo( const std::string& media_id, From faaa32a3363382ca7d2ee5f4ef164b086da525f2 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Mon, 20 May 2019 11:41:50 -0400 Subject: [PATCH 27/37] Incorporate review feedback --- .../browser/rewards_service_impl.cc | 6 +- .../browser/rewards_service_impl.h | 2 +- .../extension/brave_rewards/BUILD.gn | 2 +- .../extension/brave_rewards/background.ts | 2 +- .../brave_rewards/{content.ts => twitter.ts} | 28 ++++++--- .../brave_rewards/resources/img/twitter.svg | 1 - .../resources/tip/components/app.tsx | 38 ++++++------ .../resources/tip/components/siteBanner.tsx | 16 +++-- .../resources/tip/components/tipSite.tsx | 1 - .../tip/components/transientTipOverlay.tsx | 13 ++-- .../resources/tip/components/tweetBox.tsx | 61 ------------------- .../resources/ui/reducers/rewards_reducer.ts | 5 ++ 12 files changed, 68 insertions(+), 107 deletions(-) rename components/brave_rewards/resources/extension/brave_rewards/{content.ts => twitter.ts} (88%) delete mode 100644 components/brave_rewards/resources/img/twitter.svg delete mode 100644 components/brave_rewards/resources/tip/components/tweetBox.tsx diff --git a/components/brave_rewards/browser/rewards_service_impl.cc b/components/brave_rewards/browser/rewards_service_impl.cc index 9da9e21cbbe7..d1abce8cf1b2 100644 --- a/components/brave_rewards/browser/rewards_service_impl.cc +++ b/components/brave_rewards/browser/rewards_service_impl.cc @@ -2243,8 +2243,12 @@ void RewardsServiceImpl::SaveRecurringTip( void RewardsServiceImpl::OnTwitterPublisherInfoSaved( SaveMediaInfoCallback callback, - int result, + int32_t result, ledger::PublisherInfoPtr publisher) { + if (!Connected()) { + std::move(callback).Run(nullptr); + return; + } if (Connected()) { ledger::Result result_converted = static_cast(result); std::unique_ptr site; diff --git a/components/brave_rewards/browser/rewards_service_impl.h b/components/brave_rewards/browser/rewards_service_impl.h index fd5c2a2a9f53..63b9dd9b1e53 100644 --- a/components/brave_rewards/browser/rewards_service_impl.h +++ b/components/brave_rewards/browser/rewards_service_impl.h @@ -496,7 +496,7 @@ class RewardsServiceImpl : public RewardsService, const std::string& publisher_key, bool verified); void OnTwitterPublisherInfoSaved(SaveMediaInfoCallback callback, - int result, + int32_t result, ledger::PublisherInfoPtr publisher); bool Connected() const; diff --git a/components/brave_rewards/resources/extension/brave_rewards/BUILD.gn b/components/brave_rewards/resources/extension/brave_rewards/BUILD.gn index 64fe1541f8b6..62d5fe446ab6 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/BUILD.gn +++ b/components/brave_rewards/resources/extension/brave_rewards/BUILD.gn @@ -10,7 +10,7 @@ transpile_web_ui("brave_rewards_panel") { entry_points = [ ["brave_rewards_panel", rebase_path("brave_rewards_panel.tsx")], ["brave_rewards_panel_background", rebase_path("background.ts")], - ["brave_rewards_panel_content", rebase_path("content.ts")] + ["brave_rewards_panel_content", rebase_path("twitter.ts")] ] resource_name = "brave_rewards_panel" diff --git a/components/brave_rewards/resources/extension/brave_rewards/background.ts b/components/brave_rewards/resources/extension/brave_rewards/background.ts index 650fc8add216..a28857c4fa99 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/background.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/background.ts @@ -111,7 +111,7 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { return true } case 'inlineTipSetting': { - // Check if rewards is enabled + // Check if inline tip is enabled chrome.braveRewards.getInlineTipSetting(msg.key, function (enabled: boolean) { sendResponse({ enabled }) }) diff --git a/components/brave_rewards/resources/extension/brave_rewards/content.ts b/components/brave_rewards/resources/extension/brave_rewards/twitter.ts similarity index 88% rename from components/brave_rewards/resources/extension/brave_rewards/content.ts rename to components/brave_rewards/resources/extension/brave_rewards/twitter.ts index 96c4ed56449c..2e2b6039ef40 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/content.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/twitter.ts @@ -5,6 +5,8 @@ // Utils import { getMessage } from './background/api/locale_api' +let timeout: any = null + const getTweetMetaData = (tweet: Element): RewardsTip.TweetMetaData | null => { if (!tweet) { return null @@ -129,20 +131,28 @@ const configureBraveTipAction = () => { const actions = tweets[i].getElementsByClassName('js-actions')[0] if (actions) { const braveTipActions = actions.getElementsByClassName('action-brave-tip') - if (rewards.enabled && inlineTip.enabled) { - if (braveTipActions.length === 0) { - actions.appendChild(createBraveTipAction(tweets[i])) - } - } else { - if (braveTipActions.length === 1) { - actions.removeChild(braveTipActions[0]) - } + const tippingEnabled = rewards.enabled && inlineTip.enabled + if (tippingEnabled && braveTipActions.length === 0) { + actions.appendChild(createBraveTipAction(tweets[i])) + } else if (!tippingEnabled && braveTipActions.length === 1) { + actions.removeChild(braveTipActions[0]) } } } }) }) - setTimeout(configureBraveTipAction, 3000) + timeout = setTimeout(configureBraveTipAction, 3000) } +// In order to deal with infinite scrolling and overlays, periodically +// check if injection needs to occur (mitigate the performance cost +// by only running this when the foreground tab is active or visible) +document.addEventListener('visibilitychange', function () { + if (document.hidden) { + clearTimeout(timeout) + } else { + timeout = setTimeout(configureBraveTipAction, 3000) + } +}) + configureBraveTipAction() diff --git a/components/brave_rewards/resources/img/twitter.svg b/components/brave_rewards/resources/img/twitter.svg deleted file mode 100644 index 2832e7b524aa..000000000000 --- a/components/brave_rewards/resources/img/twitter.svg +++ /dev/null @@ -1 +0,0 @@ -Twitter_Logo_Blue \ No newline at end of file diff --git a/components/brave_rewards/resources/tip/components/app.tsx b/components/brave_rewards/resources/tip/components/app.tsx index 7fb832f90a83..5e9d10a0ee8f 100644 --- a/components/brave_rewards/resources/tip/components/app.tsx +++ b/components/brave_rewards/resources/tip/components/app.tsx @@ -23,11 +23,27 @@ interface Props extends RewardsTip.ComponentProps { } export class App extends React.Component { - get actions () { return this.props.actions } + getTipBanner = (publisher: RewardsTip.Publisher, tweetMetaData?: RewardsTip.TweetMetaData) => { + if (tweetMetaData) { + return ( + + ) + } else { + return ( + + ) + } + } + render () { const { publishers } = this.props.rewardsDonateData @@ -35,6 +51,7 @@ export class App extends React.Component { return null } + const tweetMetaData = this.props.dialogArgs.tweetMetaData const publisherKey = this.props.dialogArgs.publisherKey const publisher = publishers[publisherKey] @@ -42,26 +59,9 @@ export class App extends React.Component { return null } - let tip - const tweetMetaData = this.props.dialogArgs.tweetMetaData - if (tweetMetaData) { - tip = ( - - ) - } else { - tip = ( - - ) - } - return (
- {tip} + {this.getTipBanner(publisher, tweetMetaData)}
) } diff --git a/components/brave_rewards/resources/tip/components/siteBanner.tsx b/components/brave_rewards/resources/tip/components/siteBanner.tsx index 8bec5fdbaa44..8af9d3aac690 100644 --- a/components/brave_rewards/resources/tip/components/siteBanner.tsx +++ b/components/brave_rewards/resources/tip/components/siteBanner.tsx @@ -119,6 +119,14 @@ class Banner extends React.Component { return !!recurringDonation } + getScreenName = (tweetMetaData?: RewardsTip.TweetMetaData) => { + if (!tweetMetaData) { + return '' + } + + return `@${tweetMetaData.screenName}` + } + get addFundsLink () { return 'chrome://rewards/#add-funds' } @@ -127,6 +135,7 @@ class Banner extends React.Component { const { walletInfo } = this.props.rewardsDonateData const { balance } = walletInfo + const tweetMetaData = this.props.tweetMetaData const publisher = this.props.publisher const verified = publisher.verified let logo = publisher.logo @@ -136,11 +145,6 @@ class Banner extends React.Component { logo = `chrome://favicon/size/160@2x/${publisher.logo}` } - let screenName - if (this.props.tweetMetaData) { - screenName = `@${this.props.tweetMetaData.screenName}` - } - if (!verified) { logo = '' } @@ -150,7 +154,7 @@ class Banner extends React.Component { domain={publisher.publisherKey} title={publisher.title} name={publisher.name} - screenName={screenName} + screenName={this.getScreenName(tweetMetaData)} provider={publisher.provider as Provider} recurringDonation={this.hasRecurringTip(publisher.publisherKey)} balance={balance.toString() || '0'} diff --git a/components/brave_rewards/resources/tip/components/tipSite.tsx b/components/brave_rewards/resources/tip/components/tipSite.tsx index f4c01b875718..53513d8556b4 100644 --- a/components/brave_rewards/resources/tip/components/tipSite.tsx +++ b/components/brave_rewards/resources/tip/components/tipSite.tsx @@ -18,7 +18,6 @@ interface Props extends RewardsTip.ComponentProps { } class TipSite extends React.Component { - get actions () { return this.props.actions } diff --git a/components/brave_rewards/resources/tip/components/transientTipOverlay.tsx b/components/brave_rewards/resources/tip/components/transientTipOverlay.tsx index 32103e46e9dc..7c38f9cc6d2e 100644 --- a/components/brave_rewards/resources/tip/components/transientTipOverlay.tsx +++ b/components/brave_rewards/resources/tip/components/transientTipOverlay.tsx @@ -19,6 +19,13 @@ interface Props extends RewardsTip.ComponentProps { } class TransientTipOverlay extends React.Component { + componentDidMount () { + if (this.props.timeout) { + setTimeout(() => { + this.onClose() + }, this.props.timeout) + } + } get actions () { return this.props.actions @@ -66,12 +73,6 @@ class TransientTipOverlay extends React.Component { logo = '' } - if (this.props.timeout) { - setTimeout(() => { - this.onClose() - }, this.props.timeout) - } - return ( { - get actions () { - return this.props.actions - } - - formatDate = (date: Date) => { - const dateOptions = { month: 'short', day: 'numeric' } - if (new Date().getFullYear() !== date.getFullYear()) { - dateOptions['year'] = 'numeric' - } - return date.toLocaleString(navigator.language, dateOptions) - } - - render () { - const tweetDate = new Date(this.props.tweetMetaData.tweetTimestamp * 1000) - return ( -
-
- -
- {this.formatDate(tweetDate)} -
-
-

- {this.props.tweetMetaData.tweetText} -

-
- ) - } -} - -const mapStateToProps = (state: RewardsTip.ApplicationState) => ({ - rewardsDonateData: state.rewardsDonateData -}) - -const mapDispatchToProps = (dispatch: Dispatch) => ({ - actions: bindActionCreators(tipActions, dispatch) -}) - -export default connect( - mapStateToProps, - mapDispatchToProps -)(TweetBox) diff --git a/components/brave_rewards/resources/ui/reducers/rewards_reducer.ts b/components/brave_rewards/resources/ui/reducers/rewards_reducer.ts index 983f8ebb02d7..f7f50c6a0fb6 100644 --- a/components/brave_rewards/resources/ui/reducers/rewards_reducer.ts +++ b/components/brave_rewards/resources/ui/reducers/rewards_reducer.ts @@ -187,6 +187,11 @@ const rewardsReducer: Reducer = (state: Rewards.State const key = action.payload.key const value = action.payload.value + + if (!value || value === '') { + break + } + let inlineTip = state.inlineTip inlineTip[key] = value From 100220c8118c0e6494a9fbc5c5bd975224aeb47f Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Tue, 14 May 2019 13:15:52 -0400 Subject: [PATCH 28/37] Allow tweeting any tip --- browser/ui/webui/brave_tip_ui.cc | 48 +++++++++++-------- .../resources/tip/actions/tip_actions.ts | 5 +- .../resources/tip/components/tipSite.tsx | 11 ++++- .../tip/components/tipTwitterUser.tsx | 4 +- .../resources/tip/reducers/tip_reducer.ts | 3 +- .../resources/brave_components_strings.grd | 2 +- 6 files changed, 48 insertions(+), 25 deletions(-) diff --git a/browser/ui/webui/brave_tip_ui.cc b/browser/ui/webui/brave_tip_ui.cc index b33ea3548eeb..379447a86c63 100644 --- a/browser/ui/webui/brave_tip_ui.cc +++ b/browser/ui/webui/brave_tip_ui.cc @@ -278,6 +278,28 @@ void RewardsTipDOMHandler::OnPublisherBanner( "brave_rewards_tip.publisherBanner", result); } +std::string ConstructTweetIntentURL(const std::string& name, + const std::string& tweet_id) { + // If a tweet ID was specified, then compliment the Twitter user and + // quote the original tweet; otherwise, just tweet a generic comment + // about this tip. + std::string intent_url; + std::string comment = l10n_util::GetStringFUTF8( + IDS_BRAVE_REWARDS_LOCAL_COMPLIMENT_TWEET, base::UTF8ToUTF16(name)); + if (!tweet_id.empty()) { + std::string quoted_tweet_url = base::StringPrintf( + "https://twitter.com/%s/status/%s", name.c_str(), tweet_id.c_str()); + intent_url = + base::StringPrintf("https://twitter.com/intent/tweet?url=%s&text=%s", + quoted_tweet_url.c_str(), comment.c_str()); + } else { + intent_url = base::StringPrintf("https://twitter.com/intent/tweet?text=%s", + comment.c_str()); + } + + return intent_url; +} + } // namespace BraveTipUI::BraveTipUI(content::WebUI* web_ui, const std::string& name) @@ -344,30 +366,18 @@ void RewardsTipDOMHandler::OnRecurringTipSaved( } void RewardsTipDOMHandler::TweetTip(const base::ListValue *args) { - DCHECK_EQ(args->GetSize(), 1U); - const base::DictionaryValue* tweet_metadata_dict = nullptr; - if (!args->GetDictionary(0, &tweet_metadata_dict)) - return; + DCHECK_EQ(args->GetSize(), 2U); - // Retrieve the relevant tweet metadata from arguments. - std::string screen_name; - if (!tweet_metadata_dict->GetString("screenName", &screen_name)) + // Retrieve the relevant metadata from arguments. + std::string name; + if (!args->GetString(0, &name)) return; std::string tweet_id; - if (!tweet_metadata_dict->GetString("tweetId", &tweet_id)) + if (!args->GetString(1, &tweet_id)) return; - // Construct the Twitter intent URL for the tip compliment. - std::string comment = l10n_util::GetStringFUTF8( - IDS_BRAVE_REWARDS_LOCAL_COMPLIMENT_TWEET, base::UTF8ToUTF16(screen_name)); - std::string quoted_tweet_url = - base::StringPrintf("https://twitter.com/%s/status/%s", - screen_name.c_str(), tweet_id.c_str()); - std::string intent_url = - base::StringPrintf("https://twitter.com/intent/tweet?url=%s&text=%s", - quoted_tweet_url.c_str(), comment.c_str()); - - GURL gurl(intent_url); + // Construct the Twitter intent URL for the tip comment/compliment. + GURL gurl(ConstructTweetIntentURL(name, tweet_id)); if (!gurl.is_valid()) return; diff --git a/components/brave_rewards/resources/tip/actions/tip_actions.ts b/components/brave_rewards/resources/tip/actions/tip_actions.ts index 9fc690eef262..705f0a935887 100644 --- a/components/brave_rewards/resources/tip/actions/tip_actions.ts +++ b/components/brave_rewards/resources/tip/actions/tip_actions.ts @@ -9,8 +9,9 @@ import { types } from '../constants/tip_types' export const onCloseDialog = () => action(types.ON_CLOSE_DIALOG) -export const onTweet = (tweetMetaData: RewardsTip.TweetMetaData) => action(types.ON_TWEET, { - tweetMetaData +export const onTweet = (name: string, tweetId: string) => action(types.ON_TWEET, { + name, + tweetId }) export const onPublisherBanner = (data: RewardsTip.Publisher) => action(types.ON_PUBLISHER_BANNER, { diff --git a/components/brave_rewards/resources/tip/components/tipSite.tsx b/components/brave_rewards/resources/tip/components/tipSite.tsx index 53513d8556b4..b6ea97b09fe8 100644 --- a/components/brave_rewards/resources/tip/components/tipSite.tsx +++ b/components/brave_rewards/resources/tip/components/tipSite.tsx @@ -22,6 +22,11 @@ class TipSite extends React.Component { return this.props.actions } + onTweet = () => { + this.actions.onTweet(this.props.publisher.name, '') + this.actions.onCloseDialog() + } + render () { const { finished, error } = this.props.rewardsDonateData @@ -34,7 +39,11 @@ class TipSite extends React.Component { } { finished - ? + ? : null } diff --git a/components/brave_rewards/resources/tip/components/tipTwitterUser.tsx b/components/brave_rewards/resources/tip/components/tipTwitterUser.tsx index e2c079a3affc..65a7ccd86e1c 100644 --- a/components/brave_rewards/resources/tip/components/tipTwitterUser.tsx +++ b/components/brave_rewards/resources/tip/components/tipTwitterUser.tsx @@ -26,7 +26,9 @@ class TipTwitterUser extends React.Component { } onTweet = () => { - this.actions.onTweet(this.props.tweetMetaData) + this.actions.onTweet( + `@${this.props.tweetMetaData.screenName}`, + this.props.tweetMetaData.tweetId) this.actions.onCloseDialog() } diff --git a/components/brave_rewards/resources/tip/reducers/tip_reducer.ts b/components/brave_rewards/resources/tip/reducers/tip_reducer.ts index 629b924ecb43..e8267d24ec7a 100644 --- a/components/brave_rewards/resources/tip/reducers/tip_reducer.ts +++ b/components/brave_rewards/resources/tip/reducers/tip_reducer.ts @@ -33,7 +33,8 @@ const publishersReducer: Reducer = (state: RewardsTip.State = break case types.ON_TWEET: chrome.send('brave_rewards_tip.tweetTip', [ - payload.tweetMetaData + payload.name, + payload.tweetId ]) break case types.ON_PUBLISHER_BANNER: { diff --git a/components/resources/brave_components_strings.grd b/components/resources/brave_components_strings.grd index 4e547684b851..2f9011febc4b 100644 --- a/components/resources/brave_components_strings.grd +++ b/components/resources/brave_components_strings.grd @@ -260,7 +260,7 @@ Sorry, it appears that this grant has already been claimed. Next monthly tip date - I just tipped @$1user using the Brave Browser. Check it out at https://brave.com/tips. + I just tipped $1user using the Brave Browser. Check it out at https://brave.com/tips. Enable ability to give tips on ‘Like’ posts From 7df2a0b85839778fcfb8f81fa764f35dd1a68733 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Tue, 21 May 2019 18:58:36 -0400 Subject: [PATCH 29/37] Add browser tests for Twitter tips --- .../browser/rewards_service_browsertest.cc | 121 +++++++++++++++++- 1 file changed, 114 insertions(+), 7 deletions(-) diff --git a/components/brave_rewards/browser/rewards_service_browsertest.cc b/components/brave_rewards/browser/rewards_service_browsertest.cc index dc4c537e5be8..b2325ece17ff 100644 --- a/components/brave_rewards/browser/rewards_service_browsertest.cc +++ b/components/brave_rewards/browser/rewards_service_browsertest.cc @@ -21,10 +21,13 @@ #include "chrome/common/chrome_paths.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/network_session_configurator/common/network_switches.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" #include "content/public/test/browser_test_utils.h" #include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -41,8 +44,25 @@ std::unique_ptr HandleRequest( new net::test_server::BasicHttpResponse()); http_response->set_code(net::HTTP_OK); http_response->set_content_type("text/html"); - http_response->set_content( - "
Hello, world!
"); + if (request.relative_url == "/twitter") { + http_response->set_content( + "" + " " + " " + "
" + "
Hello, Twitter!
" + "
" + " " + ""); + } else { + http_response->set_content( + "" + " " + " " + "
Hello, world!
" + " " + ""); + } return std::move(http_response); } @@ -79,9 +99,22 @@ class BraveRewardsBrowserTest : public InProcessBrowserTest, public: void SetUpOnMainThread() override { InProcessBrowserTest::SetUpOnMainThread(); + host_resolver()->AddRule("*", "127.0.0.1"); content::SetupCrossSiteRedirector(embedded_test_server()); - InitEmbeddedTestServer(); + + // Setup up embedded test server for HTTP requests + embedded_test_server()->RegisterRequestHandler( + base::BindRepeating(&HandleRequest)); + ASSERT_TRUE(embedded_test_server()->Start()); + + // Setup up embedded test server for HTTPS requests + https_server_.reset(new net::EmbeddedTestServer( + net::test_server::EmbeddedTestServer::TYPE_HTTPS)); + https_server_->SetSSLConfig(net::EmbeddedTestServer::CERT_OK); + https_server_->RegisterRequestHandler(base::BindRepeating(&HandleRequest)); + ASSERT_TRUE(https_server_->Start()); + brave::RegisterPathProvider(); ReadTestData(); rewards_service_ = static_cast( @@ -97,11 +130,14 @@ class BraveRewardsBrowserTest : public InProcessBrowserTest, InProcessBrowserTest::TearDown(); } - void InitEmbeddedTestServer() { - embedded_test_server()->RegisterRequestHandler(base::Bind(&HandleRequest)); - ASSERT_TRUE(embedded_test_server()->Start()); + void SetUpCommandLine(base::CommandLine* command_line) override { + // HTTPS server only serves a valid cert for localhost, so this is needed + // to load pages from other hosts without an error + command_line->AppendSwitch(switches::kIgnoreCertificateErrors); } + net::EmbeddedTestServer* https_server() { return https_server_.get(); } + void RunUntilIdle() { base::RunLoop loop; loop.RunUntilIdle(); @@ -531,7 +567,7 @@ class BraveRewardsBrowserTest : public InProcessBrowserTest, content::NotificationService::AllSources()); // Click button to initiate sending a tip - content::EvalJsResult js_result = EvalJs( + content::EvalJsResult js_result = EvalJs( popup_contents, "new Promise((resolve) => {" "let count = 10;" @@ -730,6 +766,30 @@ class BraveRewardsBrowserTest : public InProcessBrowserTest, } } + bool IsTwitterTipsInjected() { + content::EvalJsResult js_result = + EvalJs(contents(), + "new Promise((resolve) => {" + "let count = 10;" + "var interval = setInterval(function() {" + " if (count === 0) {" + " clearInterval(interval);" + " resolve(false);" + " } else {" + " count -= 1;" + " }" + " const braveTipActions" + " = document.querySelectorAll(\".action-brave-tip\");" + " if (braveTipActions && braveTipActions.length === 1) {" + " clearInterval(interval);" + " resolve(true);" + " }" + "}, 500);});", + content::EXECUTE_SCRIPT_DEFAULT_OPTIONS, + content::ISOLATED_WORLD_ID_CONTENT_END); + return js_result.ExtractBool(); + } + void OnWalletInitialized(brave_rewards::RewardsService* rewards_service, uint32_t result) { ASSERT_TRUE(result == ledger::Result::WALLET_CREATED || @@ -796,6 +856,8 @@ class BraveRewardsBrowserTest : public InProcessBrowserTest, MOCK_METHOD1(OnGetReconcileTime, void(int32_t)); MOCK_METHOD1(OnGetShortRetries, void(bool)); + std::unique_ptr https_server_; + brave_rewards::RewardsServiceImpl* rewards_service_; brave_rewards::Grant grant_; @@ -1409,3 +1471,48 @@ IN_PROC_BROWSER_TEST_F(BraveRewardsBrowserTest, // Stop observing the Rewards service rewards_service_->RemoveObserver(this); } + +// Brave tip icon is injected when visiting Twitter +IN_PROC_BROWSER_TEST_F(BraveRewardsBrowserTest, TwitterTipsInjectedOnTwitter) { + // Enable Rewards + EnableRewards(); + + // Navigate to Twitter in a new tab + GURL url = https_server()->GetURL("twitter.com", "/twitter"); + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + + // Ensure that Twitter tips injection is active + EXPECT_TRUE(IsTwitterTipsInjected()); +} + +// Brave tip icon is not injected when visiting Twitter while Brave +// Rewards is disabled +IN_PROC_BROWSER_TEST_F(BraveRewardsBrowserTest, + TwitterTipsNotInjectedWhenRewardsDisabled) { + // Navigate to Twitter in a new tab + GURL url = https_server()->GetURL("twitter.com", "/twitter"); + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + + // Ensure that Twitter tips injection is not active + EXPECT_FALSE(IsTwitterTipsInjected()); +} + +// Brave tip icon is not injected into non-Twitter sites +IN_PROC_BROWSER_TEST_F(BraveRewardsBrowserTest, + TwitterTipsNotInjectedOnNonTwitter) { + // Enable Rewards + EnableRewards(); + + // Navigate to a non-Twitter site in a new tab + GURL url = embedded_test_server()->GetURL("google.com", "/twitter"); + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + + // Ensure that Twitter tips injection is not active + EXPECT_FALSE(IsTwitterTipsInjected()); +} From f592ec256f26d8d114eb5afdffa1c115618327af Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Wed, 22 May 2019 07:47:30 +0200 Subject: [PATCH 30/37] Fixes settings button being visible when rewards is off --- browser/ui/webui/brave_webui_source.cc | 1 - .../brave_rewards/resources/ui/components/tipsBox.tsx | 7 ++++++- components/resources/brave_components_strings.grd | 3 +-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/browser/ui/webui/brave_webui_source.cc b/browser/ui/webui/brave_webui_source.cc index 347c9ac69a8f..fbca93ab1f10 100644 --- a/browser/ui/webui/brave_webui_source.cc +++ b/browser/ui/webui/brave_webui_source.cc @@ -244,7 +244,6 @@ void CustomizeWebUIHTMLSource(const std::string &name, { "donationDisabledText1", IDS_BRAVE_REWARDS_LOCAL_DONAT_DISABLED_TEXT1 }, // NOLINT { "donationDisabledText2", IDS_BRAVE_REWARDS_LOCAL_DONAT_DISABLED_TEXT2 }, // NOLINT { "donationNextDate", IDS_BRAVE_REWARDS_LOCAL_DONAT_NEXT_DATE }, - { "donationTipOnLike", IDS_BRAVE_REWARDS_LOCAL_DONAT_TIP_ON_LIKE }, { "panelAddFunds", IDS_BRAVE_REWARDS_LOCAL_PANEL_ADD_FUNDS }, { "panelWithdrawFunds", IDS_BRAVE_REWARDS_LOCAL_PANEL_WITHDRAW_FUNDS }, diff --git a/components/brave_rewards/resources/ui/components/tipsBox.tsx b/components/brave_rewards/resources/ui/components/tipsBox.tsx index 40b507b0db33..7f409072656f 100644 --- a/components/brave_rewards/resources/ui/components/tipsBox.tsx +++ b/components/brave_rewards/resources/ui/components/tipsBox.tsx @@ -162,6 +162,11 @@ class TipBox extends React.Component { } donationSettingsChild = () => { + const { enabledMain } = this.props.rewardsData + if (!enabledMain) { + return null + } + let value = this.props.rewardsData.inlineTip if (!value) { @@ -174,7 +179,7 @@ class TipBox extends React.Component { <> - + 5 seconds 8 seconds 1 minute - Enable ability to give tips on ‘Like’ posts + Enable content-level tips on these sites YouTube Twitter Tip on the spot as you find gems. @@ -262,7 +262,6 @@ I just tipped $1user using the Brave Browser. Check it out at https://brave.com/tips. - Enable ability to give tips on ‘Like’ posts Amount: From d3efb22eceebd08f6ef0d245d1de2db11b45e506 Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Wed, 22 May 2019 08:00:15 +0200 Subject: [PATCH 31/37] Do not show tweet out button for recurring --- .../resources/tip/components/transientTipOverlay.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/brave_rewards/resources/tip/components/transientTipOverlay.tsx b/components/brave_rewards/resources/tip/components/transientTipOverlay.tsx index 7c38f9cc6d2e..a060ccdd1a3e 100644 --- a/components/brave_rewards/resources/tip/components/transientTipOverlay.tsx +++ b/components/brave_rewards/resources/tip/components/transientTipOverlay.tsx @@ -76,7 +76,7 @@ class TransientTipOverlay extends React.Component { return ( Date: Wed, 22 May 2019 09:00:46 -0400 Subject: [PATCH 32/37] Make timeout optional in TransientTipOverlay component --- components/brave_rewards/resources/tip/components/tipSite.tsx | 1 - .../brave_rewards/resources/tip/components/tipTwitterUser.tsx | 1 - .../resources/tip/components/transientTipOverlay.tsx | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/components/brave_rewards/resources/tip/components/tipSite.tsx b/components/brave_rewards/resources/tip/components/tipSite.tsx index b6ea97b09fe8..62bc437c18e4 100644 --- a/components/brave_rewards/resources/tip/components/tipSite.tsx +++ b/components/brave_rewards/resources/tip/components/tipSite.tsx @@ -41,7 +41,6 @@ class TipSite extends React.Component { finished ? : null diff --git a/components/brave_rewards/resources/tip/components/tipTwitterUser.tsx b/components/brave_rewards/resources/tip/components/tipTwitterUser.tsx index 65a7ccd86e1c..3f1117dea3e8 100644 --- a/components/brave_rewards/resources/tip/components/tipTwitterUser.tsx +++ b/components/brave_rewards/resources/tip/components/tipTwitterUser.tsx @@ -50,7 +50,6 @@ class TipTwitterUser extends React.Component { finished ? : null diff --git a/components/brave_rewards/resources/tip/components/transientTipOverlay.tsx b/components/brave_rewards/resources/tip/components/transientTipOverlay.tsx index a060ccdd1a3e..62f5df468a59 100644 --- a/components/brave_rewards/resources/tip/components/transientTipOverlay.tsx +++ b/components/brave_rewards/resources/tip/components/transientTipOverlay.tsx @@ -14,7 +14,7 @@ import * as rewardsActions from '../actions/tip_actions' interface Props extends RewardsTip.ComponentProps { publisher: RewardsTip.Publisher - timeout: number + timeout?: number onTweet?: () => void } From e3b6501b50a3750a7af240b84ba16a975cb21816 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Wed, 22 May 2019 11:26:55 -0400 Subject: [PATCH 33/37] Move GetTwitterShareURL into ledger --- browser/ui/webui/brave_tip_ui.cc | 47 +++++++++---------- .../browser/ads_service_impl_unittest.cc | 4 ++ .../brave_rewards/browser/rewards_service.h | 6 +++ .../browser/rewards_service_impl.cc | 18 +++++++ .../browser/rewards_service_impl.h | 7 +++ .../services/bat_ledger/bat_ledger_impl.cc | 7 +++ .../services/bat_ledger/bat_ledger_impl.h | 5 ++ .../public/interfaces/bat_ledger.mojom | 3 ++ .../include/bat/ledger/ledger.h | 4 ++ .../src/bat/ledger/internal/bat_get_media.cc | 9 ++++ .../src/bat/ledger/internal/bat_get_media.h | 3 ++ .../src/bat/ledger/internal/ledger_impl.cc | 6 +++ .../src/bat/ledger/internal/ledger_impl.h | 4 ++ .../src/bat/ledger/internal/media/twitter.cc | 25 ++++++++++ .../src/bat/ledger/internal/media/twitter.h | 2 + 15 files changed, 125 insertions(+), 25 deletions(-) diff --git a/browser/ui/webui/brave_tip_ui.cc b/browser/ui/webui/brave_tip_ui.cc index 379447a86c63..fe00015a7260 100644 --- a/browser/ui/webui/brave_tip_ui.cc +++ b/browser/ui/webui/brave_tip_ui.cc @@ -5,6 +5,7 @@ #include "brave/browser/ui/webui/brave_tip_ui.h" +#include #include #include #include @@ -65,6 +66,8 @@ class RewardsTipDOMHandler : public WebUIMessageHandler, void OnPublisherBanner( std::unique_ptr banner); + void OnTwitterShareURL(const std::string& url); + // RewardsServiceObserver implementation void OnWalletProperties( brave_rewards::RewardsService* rewards_service, @@ -278,28 +281,6 @@ void RewardsTipDOMHandler::OnPublisherBanner( "brave_rewards_tip.publisherBanner", result); } -std::string ConstructTweetIntentURL(const std::string& name, - const std::string& tweet_id) { - // If a tweet ID was specified, then compliment the Twitter user and - // quote the original tweet; otherwise, just tweet a generic comment - // about this tip. - std::string intent_url; - std::string comment = l10n_util::GetStringFUTF8( - IDS_BRAVE_REWARDS_LOCAL_COMPLIMENT_TWEET, base::UTF8ToUTF16(name)); - if (!tweet_id.empty()) { - std::string quoted_tweet_url = base::StringPrintf( - "https://twitter.com/%s/status/%s", name.c_str(), tweet_id.c_str()); - intent_url = - base::StringPrintf("https://twitter.com/intent/tweet?url=%s&text=%s", - quoted_tweet_url.c_str(), comment.c_str()); - } else { - intent_url = base::StringPrintf("https://twitter.com/intent/tweet?text=%s", - comment.c_str()); - } - - return intent_url; -} - } // namespace BraveTipUI::BraveTipUI(content::WebUI* web_ui, const std::string& name) @@ -368,6 +349,9 @@ void RewardsTipDOMHandler::OnRecurringTipSaved( void RewardsTipDOMHandler::TweetTip(const base::ListValue *args) { DCHECK_EQ(args->GetSize(), 2U); + if (!rewards_service_) + return; + // Retrieve the relevant metadata from arguments. std::string name; if (!args->GetString(0, &name)) @@ -376,12 +360,25 @@ void RewardsTipDOMHandler::TweetTip(const base::ListValue *args) { if (!args->GetString(1, &tweet_id)) return; - // Construct the Twitter intent URL for the tip comment/compliment. - GURL gurl(ConstructTweetIntentURL(name, tweet_id)); + // Share the tip comment/compliment on Twitter. + std::string comment = l10n_util::GetStringFUTF8( + IDS_BRAVE_REWARDS_LOCAL_COMPLIMENT_TWEET, base::UTF8ToUTF16(name)); + std::map share_url_args; + share_url_args["comment"] = comment; + share_url_args["name"] = name.erase(0, 1); + share_url_args["tweet_id"] = tweet_id; + rewards_service_->GetShareURL( + "twitter", share_url_args, + base::BindOnce(&RewardsTipDOMHandler::OnTwitterShareURL, + base::Unretained(this))); +} + +void RewardsTipDOMHandler::OnTwitterShareURL(const std::string& url) { + GURL gurl(url); if (!gurl.is_valid()) return; - // Open a new tab with the prepopulated tweet ready to post. + // Open a new tab with the prepopulated tweet ready to share. chrome::ScopedTabbedBrowserDisplayer browser_displayer( Profile::FromWebUI(web_ui())); content::OpenURLParams open_url_params( diff --git a/components/brave_ads/browser/ads_service_impl_unittest.cc b/components/brave_ads/browser/ads_service_impl_unittest.cc index 2aefdcf57977..95a0a6859ed2 100644 --- a/components/brave_ads/browser/ads_service_impl_unittest.cc +++ b/components/brave_ads/browser/ads_service_impl_unittest.cc @@ -151,6 +151,10 @@ class MockRewardsService : public RewardsService { MOCK_METHOD2(GetInlineTipSetting, void(const std::string& key, brave_rewards::GetInlineTipSettingCallback callback)); + MOCK_METHOD3(GetShareURL, + void(const std::string& type, + const std::map& args, + brave_rewards::GetShareURLCallback callback)); }; class AdsServiceTest : public testing::Test { diff --git a/components/brave_rewards/browser/rewards_service.h b/components/brave_rewards/browser/rewards_service.h index f8bee6ea4829..0744c17050e5 100644 --- a/components/brave_rewards/browser/rewards_service.h +++ b/components/brave_rewards/browser/rewards_service.h @@ -80,6 +80,7 @@ using RefreshPublisherCallback = using SaveMediaInfoCallback = base::OnceCallback)>; using GetInlineTipSettingCallback = base::OnceCallback; +using GetShareURLCallback = base::OnceCallback; class RewardsService : public KeyedService { public: @@ -219,6 +220,11 @@ class RewardsService : public KeyedService { const std::string& key, GetInlineTipSettingCallback callback) = 0; + virtual void GetShareURL( + const std::string& type, + const std::map& args, + GetShareURLCallback callback) = 0; + protected: base::ObserverList observers_; diff --git a/components/brave_rewards/browser/rewards_service_impl.cc b/components/brave_rewards/browser/rewards_service_impl.cc index d1abce8cf1b2..d4267c1de9f8 100644 --- a/components/brave_rewards/browser/rewards_service_impl.cc +++ b/components/brave_rewards/browser/rewards_service_impl.cc @@ -2985,4 +2985,22 @@ void RewardsServiceImpl::OnInlineTipSetting( std::move(callback).Run(enabled); } +void RewardsServiceImpl::GetShareURL( + const std::string& type, + const std::map& args, + GetShareURLCallback callback) { + bat_ledger_->GetShareURL( + type, + mojo::MapToFlatMap(args), + base::BindOnce(&RewardsServiceImpl::OnShareURL, + AsWeakPtr(), + std::move(callback))); +} + +void RewardsServiceImpl::OnShareURL( + GetShareURLCallback callback, + const std::string& url) { + std::move(callback).Run(url); +} + } // namespace brave_rewards diff --git a/components/brave_rewards/browser/rewards_service_impl.h b/components/brave_rewards/browser/rewards_service_impl.h index 63b9dd9b1e53..3c98ad4db6d5 100644 --- a/components/brave_rewards/browser/rewards_service_impl.h +++ b/components/brave_rewards/browser/rewards_service_impl.h @@ -228,6 +228,11 @@ class RewardsServiceImpl : public RewardsService, const std::string& key, GetInlineTipSettingCallback callback) override; + void GetShareURL( + const std::string& type, + const std::map& args, + GetShareURLCallback callback) override; + // Testing methods void SetLedgerEnvForTesting(); void StartAutoContributeForTest(); @@ -333,6 +338,8 @@ class RewardsServiceImpl : public RewardsService, void OnInlineTipSetting(GetInlineTipSettingCallback callback, bool enabled); + void OnShareURL(GetShareURLCallback callback, const std::string& url); + // ledger::LedgerClient std::string GenerateGUID() const override; void OnWalletInitialized(ledger::Result result) override; diff --git a/components/services/bat_ledger/bat_ledger_impl.cc b/components/services/bat_ledger/bat_ledger_impl.cc index 578c1881d31e..fadebecf8c97 100644 --- a/components/services/bat_ledger/bat_ledger_impl.cc +++ b/components/services/bat_ledger/bat_ledger_impl.cc @@ -569,4 +569,11 @@ void BatLedgerImpl::GetInlineTipSetting( std::move(callback).Run(ledger_->GetInlineTipSetting(key)); } +void BatLedgerImpl::GetShareURL( + const std::string& type, + const base::flat_map& args, + GetShareURLCallback callback) { + std::move(callback).Run(ledger_->GetShareURL(type, mojo::FlatMapToMap(args))); +} + } // namespace bat_ledger diff --git a/components/services/bat_ledger/bat_ledger_impl.h b/components/services/bat_ledger/bat_ledger_impl.h index 2d2183a28b68..3f15c7370ddf 100644 --- a/components/services/bat_ledger/bat_ledger_impl.h +++ b/components/services/bat_ledger/bat_ledger_impl.h @@ -164,6 +164,11 @@ class BatLedgerImpl : public mojom::BatLedger, const std::string& key, GetInlineTipSettingCallback callback) override; + void GetShareURL( + const std::string& type, + const base::flat_map& args, + GetShareURLCallback callback) override; + private: void SetCatalogIssuers(const std::string& info) override; void ConfirmAd(const std::string& info) override; diff --git a/components/services/bat_ledger/public/interfaces/bat_ledger.mojom b/components/services/bat_ledger/public/interfaces/bat_ledger.mojom index 3533022abb74..37337dff3d1d 100644 --- a/components/services/bat_ledger/public/interfaces/bat_ledger.mojom +++ b/components/services/bat_ledger/public/interfaces/bat_ledger.mojom @@ -125,6 +125,9 @@ interface BatLedger { SetInlineTipSetting(string key, bool enabled); GetInlineTipSetting(string key) => (bool enabled); + + GetShareURL(string type, map args) => + (string url); }; interface BatLedgerClient { diff --git a/vendor/bat-native-ledger/include/bat/ledger/ledger.h b/vendor/bat-native-ledger/include/bat/ledger/ledger.h index 91e90bd3bd03..3df02bdce271 100644 --- a/vendor/bat-native-ledger/include/bat/ledger/ledger.h +++ b/vendor/bat-native-ledger/include/bat/ledger/ledger.h @@ -290,6 +290,10 @@ class LEDGER_EXPORT Ledger { virtual void SetInlineTipSetting(const std::string& key, bool enabled) = 0; virtual bool GetInlineTipSetting(const std::string& key) = 0; + + virtual std::string GetShareURL( + const std::string& type, + const std::map& args) = 0; }; } // namespace ledger diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc index 6b18d9e3f54e..99179412b242 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.cc @@ -111,4 +111,13 @@ void BatGetMedia::SaveMediaInfo(const std::string& type, } } +std::string BatGetMedia::GetShareURL( + const std::string& type, + const std::map& args) { + if (type == TWITTER_MEDIA_TYPE) + return media_twitter_->GetShareURL(args); + + return std::string(); +} + } // namespace braveledger_bat_get_media diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h index 0fc5982fc3c8..aac836162280 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/bat_get_media.h @@ -45,6 +45,9 @@ class BatGetMedia { const std::map& data, ledger::PublisherInfoCallback callback); + std::string GetShareURL(const std::string& type, + const std::map& args); + private: void OnMediaActivityError(const ledger::VisitData& visit_data, const std::string& type, diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc index e713da258202..0d86688feeb3 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc @@ -1541,4 +1541,10 @@ bool LedgerImpl::GetInlineTipSetting(const std::string& key) { return bat_state_->GetInlineTipSetting(key); } +std::string LedgerImpl::GetShareURL( + const std::string& type, + const std::map& args) { + return bat_get_media_->GetShareURL(type, args); +} + } // namespace bat_ledger diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h index c0bf94ce36bd..37d2d64f891d 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h @@ -449,6 +449,10 @@ class LedgerImpl : public ledger::Ledger, bool GetInlineTipSetting(const std::string& key) override; + std::string GetShareURL( + const std::string& type, + const std::map& args) override; + private: void AddRecurringPayment(const std::string& publisher_id, const double& value) override; diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc index b6a151c6f108..f9ee08dd414b 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.cc @@ -93,6 +93,31 @@ void MediaTwitter::SaveMediaInfo(const std::map& data, _2)); } +std::string MediaTwitter::GetShareURL( + const std::map& args) { + auto comment = args.find("comment"); + auto name = args.find("name"); + auto tweet_id = args.find("tweet_id"); + if (comment == args.end() || name == args.end() || tweet_id == args.end()) + return std::string(); + + // If a tweet ID was specified, then quote the original tweet along + // with the supplied comment; otherwise, just tweet the comment. + std::string share_url; + if (!tweet_id->second.empty()) { + std::string quoted_tweet_url = + base::StringPrintf("https://twitter.com/%s/status/%s", + name->second.c_str(), tweet_id->second.c_str()); + share_url = + base::StringPrintf("https://twitter.com/intent/tweet?url=%s&text=%s", + quoted_tweet_url.c_str(), comment->second.c_str()); + } else { + share_url = base::StringPrintf("https://twitter.com/intent/tweet?text=%s", + comment->second.c_str()); + } + return share_url; +} + void MediaTwitter::OnMediaPublisherInfo( uint64_t window_id, const std::string& user_id, diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h index ae62650055ea..4e5f72c3f902 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/media/twitter.h @@ -28,6 +28,8 @@ class MediaTwitter : public ledger::LedgerCallbackHandler { void SaveMediaInfo(const std::map& data, ledger::PublisherInfoCallback callback); + std::string GetShareURL(const std::map& args); + private: static std::string GetProfileURL(const std::string& screen_name); From f68b76bde700e092e975353b08d2d137eca33017 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Wed, 22 May 2019 14:57:09 -0400 Subject: [PATCH 34/37] Fix wording of Tweet button --- components/resources/brave_components_strings.grd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/resources/brave_components_strings.grd b/components/resources/brave_components_strings.grd index a1129beb3552..58501e6f4ce7 100644 --- a/components/resources/brave_components_strings.grd +++ b/components/resources/brave_components_strings.grd @@ -475,7 +475,7 @@ Turn on Ads This enables both ads and automatic contributions. You can turn them on or off separately at any time. Activate Rewards - Tweet Now + Tweet Tip @{{ user }} for their tweet: Type Brave Verified Publisher From fce01cc447aa7ff788b648f86d735dc87812a3d2 Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Wed, 22 May 2019 17:38:17 -0400 Subject: [PATCH 35/37] Move Twitter content script and make naming more Twitter-specific --- .../brave_rewards/resources/extension/brave_rewards/BUILD.gn | 2 +- .../extension/brave_rewards/{ => content_scripts}/twitter.ts | 2 +- .../resources/extension/brave_rewards/manifest.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename components/brave_rewards/resources/extension/brave_rewards/{ => content_scripts}/twitter.ts (99%) diff --git a/components/brave_rewards/resources/extension/brave_rewards/BUILD.gn b/components/brave_rewards/resources/extension/brave_rewards/BUILD.gn index 62d5fe446ab6..8d1b78729692 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/BUILD.gn +++ b/components/brave_rewards/resources/extension/brave_rewards/BUILD.gn @@ -10,7 +10,7 @@ transpile_web_ui("brave_rewards_panel") { entry_points = [ ["brave_rewards_panel", rebase_path("brave_rewards_panel.tsx")], ["brave_rewards_panel_background", rebase_path("background.ts")], - ["brave_rewards_panel_content", rebase_path("twitter.ts")] + ["brave_rewards_panel_content_twitter", rebase_path("content_scripts/twitter.ts")] ] resource_name = "brave_rewards_panel" diff --git a/components/brave_rewards/resources/extension/brave_rewards/twitter.ts b/components/brave_rewards/resources/extension/brave_rewards/content_scripts/twitter.ts similarity index 99% rename from components/brave_rewards/resources/extension/brave_rewards/twitter.ts rename to components/brave_rewards/resources/extension/brave_rewards/content_scripts/twitter.ts index 2e2b6039ef40..768a11c321e4 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/twitter.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/content_scripts/twitter.ts @@ -3,7 +3,7 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ // Utils -import { getMessage } from './background/api/locale_api' +import { getMessage } from '../background/api/locale_api' let timeout: any = null diff --git a/components/brave_rewards/resources/extension/brave_rewards/manifest.json b/components/brave_rewards/resources/extension/brave_rewards/manifest.json index 66e40e7bef56..163ec2fe5570 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/manifest.json +++ b/components/brave_rewards/resources/extension/brave_rewards/manifest.json @@ -31,7 +31,7 @@ "https://*.twitter.com/*" ], "js": [ - "out/brave_rewards_panel_content.bundle.js" + "out/brave_rewards_panel_content_twitter.bundle.js" ] } ], From 95e9eabfa44f13cfbf6f48425ddd2a84bbf2e12c Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Wed, 22 May 2019 18:14:49 -0400 Subject: [PATCH 36/37] Avoid potential problems with timer and visibilitychange --- .../extension/brave_rewards/content_scripts/twitter.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/brave_rewards/resources/extension/brave_rewards/content_scripts/twitter.ts b/components/brave_rewards/resources/extension/brave_rewards/content_scripts/twitter.ts index 768a11c321e4..f9980a2f27a6 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/content_scripts/twitter.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/content_scripts/twitter.ts @@ -120,6 +120,7 @@ const createBraveTipAction = (tweet: Element) => { } const configureBraveTipAction = () => { + clearTimeout(timeout) chrome.runtime.sendMessage('rewardsEnabled', function (rewards) { const msg = { type: 'inlineTipSetting', @@ -148,9 +149,8 @@ const configureBraveTipAction = () => { // check if injection needs to occur (mitigate the performance cost // by only running this when the foreground tab is active or visible) document.addEventListener('visibilitychange', function () { - if (document.hidden) { - clearTimeout(timeout) - } else { + clearTimeout(timeout) + if (!document.hidden) { timeout = setTimeout(configureBraveTipAction, 3000) } }) From 09729d5f6709be58917f93e6c855d9b52c2ef9bf Mon Sep 17 00:00:00 2001 From: Emerick Rogul Date: Wed, 22 May 2019 19:18:03 -0400 Subject: [PATCH 37/37] Add button tooltip and hover state --- .../_locales/en_US/messages.json | 2 +- .../brave_rewards/content_scripts/twitter.ts | 9 +- package-lock.json | 88 +++++++++---------- package.json | 2 +- 4 files changed, 53 insertions(+), 48 deletions(-) diff --git a/components/brave_rewards/resources/extension/brave_rewards/_locales/en_US/messages.json b/components/brave_rewards/resources/extension/brave_rewards/_locales/en_US/messages.json index 659f97a3a022..097d5082b1ef 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/_locales/en_US/messages.json +++ b/components/brave_rewards/resources/extension/brave_rewards/_locales/en_US/messages.json @@ -414,7 +414,7 @@ "description": "Description text for ad grants in grant details" }, "twitterTipsHoverText": { - "message": "Tip", + "message": "Tip this tweet", "description": "Hover text for Twitter tips action" }, "twitterTipsIconLabel": { diff --git a/components/brave_rewards/resources/extension/brave_rewards/content_scripts/twitter.ts b/components/brave_rewards/resources/extension/brave_rewards/content_scripts/twitter.ts index f9980a2f27a6..c29c370cc81f 100644 --- a/components/brave_rewards/resources/extension/brave_rewards/content_scripts/twitter.ts +++ b/components/brave_rewards/resources/extension/brave_rewards/content_scripts/twitter.ts @@ -39,9 +39,10 @@ const getTweetMetaData = (tweet: Element): RewardsTip.TweetMetaData | null => { const createBraveTipAction = (tweet: Element) => { // Create the tip action const braveTipAction = document.createElement('div') - braveTipAction.className = 'ProfileTweet-action action-brave-tip' + braveTipAction.className = 'ProfileTweet-action js-tooltip action-brave-tip' braveTipAction.style.display = 'inline-block' braveTipAction.style.minWidth = '80px' + braveTipAction.setAttribute('data-original-title', getMessage('twitterTipsHoverText')) // Create the tip button const braveTipButton = document.createElement('button') @@ -73,7 +74,6 @@ const createBraveTipAction = (tweet: Element) => { braveTipIconContainer.style.lineHeight = '0' braveTipIconContainer.style.position = 'relative' braveTipIconContainer.style.verticalAlign = 'middle' - braveTipIconContainer.setAttribute('data-original-title', getMessage('twitterTipsHoverText')) braveTipButton.appendChild(braveTipIconContainer) // Create the tip icon @@ -116,6 +116,11 @@ const createBraveTipAction = (tweet: Element) => { const shadowRoot = braveTipAction.attachShadow({ mode: 'open' }) shadowRoot.appendChild(braveTipButton) + // Create style element for hover color + const style = document.createElement('style') + style.innerHTML = '.ProfileTweet-actionButton :hover { color: #FB542B }' + shadowRoot.appendChild(style) + return braveTipAction } diff --git a/package-lock.json b/package-lock.json index bd73fd23ca32..d289be2340bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -226,9 +226,9 @@ } }, "@ctrl/tinycolor": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-2.4.0.tgz", - "integrity": "sha512-ZLjdsst8/ENM6spDmh3qPQSM+iDSerTGjA05KhAXog7o/aOa9tn7qzWMeOtJzGaDMmsBLxh4IuZ5GH7nfda9gg==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-2.5.1.tgz", + "integrity": "sha512-I5SD9ii2gh/4/LNyg+dXG6S5B41bZyQyXCldSZxNHMlNnFtDgo1h7Tn/PiCZ8qlRkAFmv+kx1ay/gtTyCVrGcw==", "dev": true }, "@jest/console": { @@ -562,7 +562,7 @@ }, "@types/filewriter": { "version": "0.0.28", - "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.28.tgz", + "resolved": "http://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.28.tgz", "integrity": "sha1-wFTor02d11205jq8dviFFocU1LM=", "dev": true }, @@ -1065,7 +1065,7 @@ }, "array-equal": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", "dev": true }, @@ -1147,7 +1147,7 @@ }, "util": { "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "dev": true, "requires": { @@ -1259,7 +1259,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -1597,8 +1597,8 @@ } }, "brave-ui": { - "version": "github:emerick/brave-ui#9f211580b43711d4dbf34e9e786d76bd2bd14c24", - "from": "github:emerick/brave-ui#twitter-tips", + "version": "github:brave/brave-ui#a2c96712dc69f033a654fee730feac75f0317c8f", + "from": "github:brave/brave-ui#a2c96712dc69f033a654fee730feac75f0317c8f", "dev": true, "requires": { "@ctrl/tinycolor": "^2.2.1", @@ -1637,7 +1637,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { @@ -1679,7 +1679,7 @@ }, "browserify-rsa": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { @@ -1755,7 +1755,7 @@ }, "buffer-equals": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/buffer-equals/-/buffer-equals-1.0.4.tgz", + "resolved": "http://registry.npmjs.org/buffer-equals/-/buffer-equals-1.0.4.tgz", "integrity": "sha1-A1O1T9B/2VZBcGca5vZrnPENJ/U=" }, "buffer-fill": { @@ -2206,7 +2206,7 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { @@ -2219,7 +2219,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { @@ -2347,7 +2347,7 @@ }, "css-select": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", "dev": true, "requires": { @@ -2409,7 +2409,7 @@ }, "d": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { @@ -2606,7 +2606,7 @@ }, "diffie-hellman": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { @@ -2635,7 +2635,7 @@ }, "doctrine": { "version": "0.7.2", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz", + "resolved": "http://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz", "integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=", "dev": true, "requires": { @@ -3257,7 +3257,7 @@ }, "file-loader": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", + "resolved": "http://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==", "dev": true, "requires": { @@ -4490,7 +4490,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -4557,7 +4557,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { @@ -6022,7 +6022,7 @@ }, "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "mississippi": { @@ -6066,7 +6066,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" @@ -6074,7 +6074,7 @@ "dependencies": { "minimist": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" } } @@ -6111,7 +6111,7 @@ }, "mp4-stream": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/mp4-stream/-/mp4-stream-2.0.3.tgz", + "resolved": "http://registry.npmjs.org/mp4-stream/-/mp4-stream-2.0.3.tgz", "integrity": "sha512-5NzgI0+bGakoZEwnIYINXqB3mnewkt3Y7jcvkXsTubnCNUSdM8cpP0Vemxf6FLg0qUN8fydTgNMVAc3QU8B92g==", "requires": { "buffer-alloc": "^1.1.0", @@ -6209,7 +6209,7 @@ }, "next-tick": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, @@ -6295,7 +6295,7 @@ "dependencies": { "buffer": { "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { @@ -6539,7 +6539,7 @@ "dependencies": { "minimist": { "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", "dev": true } @@ -6732,7 +6732,7 @@ }, "path-browserify": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "resolved": "http://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", "dev": true }, @@ -6750,7 +6750,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { @@ -7345,7 +7345,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { "core-util-is": "~1.0.0", @@ -7659,7 +7659,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { @@ -7764,7 +7764,7 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { @@ -8116,7 +8116,7 @@ }, "sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "resolved": "http://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, @@ -8318,7 +8318,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" @@ -8326,7 +8326,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -8341,7 +8341,7 @@ }, "strip-eof": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, @@ -8369,7 +8369,7 @@ }, "fast-deep-equal": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, @@ -8570,7 +8570,7 @@ }, "through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { @@ -8856,7 +8856,7 @@ }, "tty-browserify": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, @@ -9129,7 +9129,7 @@ }, "fast-deep-equal": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, @@ -9267,7 +9267,7 @@ }, "vm-browserify": { "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "resolved": "http://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", "dev": true, "requires": { @@ -9602,7 +9602,7 @@ }, "wrap-ansi": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { @@ -9621,7 +9621,7 @@ }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { diff --git a/package.json b/package.json index 0d39f67056f8..594ebe4ecb03 100644 --- a/package.json +++ b/package.json @@ -277,7 +277,7 @@ "@types/react-redux": "6.0.4", "@types/redux-logger": "^3.0.7", "awesome-typescript-loader": "^5.2.1", - "brave-ui": "github:emerick/brave-ui#twitter-tips", + "brave-ui": "github:brave/brave-ui#a2c96712dc69f033a654fee730feac75f0317c8f", "css-loader": "^2.1.1", "csstype": "^2.5.5", "deep-freeze-node": "^1.1.3",