Skip to content

Commit

Permalink
TTS improvements (uplift to 1.61.x) (#21162)
Browse files Browse the repository at this point in the history
Uplift of #20896 (squashed) to release
  • Loading branch information
brave-builds authored Dec 1, 2023
1 parent 1ad0d3d commit ce7c14e
Show file tree
Hide file tree
Showing 15 changed files with 530 additions and 197 deletions.
3 changes: 2 additions & 1 deletion browser/speedreader/page_distiller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ void PageDistiller::GetTextToSpeak(TextToSpeechContentCallback callback) {
return std::move(callback).Run(base::Value());
}

constexpr const char16_t kGetTextToSpeak[] = uR"js( extractTextToSpeak() )js";
constexpr const char16_t kGetTextToSpeak[] =
uR"js( speedreaderUtils.extractTextToSpeak() )js";

web_contents_->GetPrimaryMainFrame()->ExecuteJavaScriptInIsolatedWorld(
kGetTextToSpeak,
Expand Down
67 changes: 67 additions & 0 deletions browser/speedreader/speedreader_tab_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ SpeedreaderTabHelper::SpeedreaderTabHelper(content::WebContents* web_contents)
PageDistiller(web_contents) {
dom_distiller::AddObserver(web_contents, this);
speedreader_service_observation_.Observe(GetSpeedreaderService());
tts_player_observation_.Observe(speedreader::TtsPlayer::GetInstance());
}

SpeedreaderTabHelper::~SpeedreaderTabHelper() {
Expand Down Expand Up @@ -221,6 +222,26 @@ void SpeedreaderTabHelper::OnTtsPlayPause(int paragraph_index) {
}
}

void SpeedreaderTabHelper::OnToolbarStateChanged(mojom::MainButtonType button) {
switch (button) {
case mojom::MainButtonType::None:
SetDocumentAttribute("data-toolbar-button", "");
break;
case mojom::MainButtonType::Tune:
SetDocumentAttribute("data-toolbar-button", "tune");
break;
case mojom::MainButtonType::Appearance:
SetDocumentAttribute("data-toolbar-button", "appearance");
break;
case mojom::MainButtonType::TextToSpeech:
SetDocumentAttribute("data-toolbar-button", "tts");
break;
case mojom::MainButtonType::AI:
SetDocumentAttribute("data-toolbar-button", "ai");
break;
}
}

void SpeedreaderTabHelper::ClearPersistedData() {
if (auto* entry = web_contents()->GetController().GetLastCommittedEntry()) {
SpeedreaderExtendedInfoHandler::ClearPersistedData(entry);
Expand Down Expand Up @@ -347,6 +368,10 @@ void SpeedreaderTabHelper::DOMContentLoaded(

render_frame_host->ExecuteJavaScriptInIsolatedWorld(
*kLoadScript, base::DoNothing(), ISOLATED_WORLD_ID_BRAVE_INTERNAL);

for (auto& o : observers_) {
o.OnContentsReady();
}
}

void SpeedreaderTabHelper::OnVisibilityChanged(content::Visibility visibility) {
Expand All @@ -356,6 +381,7 @@ void SpeedreaderTabHelper::OnVisibilityChanged(content::Visibility visibility) {

void SpeedreaderTabHelper::WebContentsDestroyed() {
speedreader_service_observation_.Reset();
tts_player_observation_.Reset();
dom_distiller::RemoveObserver(web_contents(), this);
SetWebContents(nullptr);
HideSpeedreaderBubble();
Expand Down Expand Up @@ -393,6 +419,47 @@ void SpeedreaderTabHelper::OnDistillComplete(DistillationResult result) {
#endif
}

void SpeedreaderTabHelper::OnReadingStart(content::WebContents* web_contents) {
if (!speedreader::DistillStates::IsDistilled(distill_state_)) {
return;
}

constexpr const char16_t kReading[] =
uR"js( speedreaderUtils.setTtsReadingState($1) )js";

const auto script = base::ReplaceStringPlaceholders(
kReading, (web_contents == this->web_contents()) ? u"true" : u"false",
nullptr);

this->web_contents()->GetPrimaryMainFrame()->ExecuteJavaScriptInIsolatedWorld(
script, base::DoNothing(), ISOLATED_WORLD_ID_BRAVE_INTERNAL);
}

void SpeedreaderTabHelper::OnReadingStop(content::WebContents* web_contents) {
OnReadingStart(nullptr);
}

void SpeedreaderTabHelper::OnReadingProgress(content::WebContents* web_contents,
int paragraph_index,
int char_index,
int length) {
if (!speedreader::DistillStates::IsDistilled(distill_state_) ||
web_contents != this->web_contents()) {
return;
}
constexpr const char16_t kHighlight[] =
uR"js( speedreaderUtils.highlightText($1, $2, $3) )js";

const auto script = base::ReplaceStringPlaceholders(
kHighlight,
{base::NumberToString16(paragraph_index),
base::NumberToString16(char_index), base::NumberToString16(length)},
nullptr);

this->web_contents()->GetPrimaryMainFrame()->ExecuteJavaScriptInIsolatedWorld(
script, base::DoNothing(), ISOLATED_WORLD_ID_BRAVE_INTERNAL);
}

void SpeedreaderTabHelper::OnSiteEnableSettingChanged(
content::WebContents* site,
bool enabled_on_site) {
Expand Down
19 changes: 18 additions & 1 deletion browser/speedreader/speedreader_tab_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "brave/components/speedreader/speedreader_service.h"
#include "brave/components/speedreader/speedreader_throttle_delegate.h"
#include "brave/components/speedreader/speedreader_util.h"
#include "brave/components/speedreader/tts_player.h"
#include "components/dom_distiller/content/browser/distillable_page_utils.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
Expand Down Expand Up @@ -51,12 +52,14 @@ class SpeedreaderTabHelper
public SpeedreaderThrottleDelegate,
public mojom::SpeedreaderHost,
public SpeedreaderService::Observer,
public dom_distiller::DistillabilityObserver {
public dom_distiller::DistillabilityObserver,
public speedreader::TtsPlayer::Observer {
public:
struct Observer : public base::CheckedObserver {
~Observer() override = default;

virtual void OnTuneBubbleClosed() {}
virtual void OnContentsReady() {}
};

~SpeedreaderTabHelper() override;
Expand Down Expand Up @@ -100,6 +103,8 @@ class SpeedreaderTabHelper
void OnShowOriginalPage() override;
void OnTtsPlayPause(int index) override;

void OnToolbarStateChanged(mojom::MainButtonType button);

private:
friend class content::WebContentsUserData<SpeedreaderTabHelper>;
explicit SpeedreaderTabHelper(content::WebContents* web_contents);
Expand Down Expand Up @@ -134,6 +139,14 @@ class SpeedreaderTabHelper
std::string TakePageContent() override;
void OnDistillComplete(DistillationResult result) override;

// speedreader::TtsPlayer::Observer:
void OnReadingStart(content::WebContents* web_contents) override;
void OnReadingStop(content::WebContents* web_contents) override;
void OnReadingProgress(content::WebContents* web_contents,
int paragraph_index,
int char_index,
int length) override;

// SpeedreaderService::Observer:
void OnSiteEnableSettingChanged(content::WebContents* site,
bool enabled_on_site) override;
Expand Down Expand Up @@ -172,6 +185,10 @@ class SpeedreaderTabHelper

mojo::AssociatedReceiver<mojom::SpeedreaderHost> receiver_{this};

base::ScopedObservation<speedreader::TtsPlayer,
speedreader::TtsPlayer::Observer>
tts_player_observation_{this};

base::ScopedObservation<SpeedreaderService, SpeedreaderService::Observer>
speedreader_service_observation_{this};

Expand Down
1 change: 1 addition & 0 deletions browser/ui/color/brave_color_id.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
E_CPONLY(kColorSpeedreaderToolbarForeground) \
E_CPONLY(kColorSpeedreaderToolbarButtonHover) \
E_CPONLY(kColorSpeedreaderToolbarButtonActive) \
E_CPONLY(kColorSpeedreaderToolbarButtonActiveText)\
E_CPONLY(kColorSpeedreaderToolbarButtonBorder)
#else
#define BRAVE_SPEEDREADER_COLOR_IDS
Expand Down
13 changes: 9 additions & 4 deletions browser/ui/color/brave_color_mixer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -150,18 +150,23 @@ void AddBraveSpeedreaderColorMixer(ui::ColorProvider* provider,
mixer[kColorSpeedreaderToolbarBorder] = {kColorToolbarContentAreaSeparator};
mixer[kColorSpeedreaderToolbarForeground] = {PickColorContrastingToToolbar(
key, mixer,
leo::GetColor(leo::Color::kColorLegacyText2, leo::Theme::kLight),
leo::GetColor(leo::Color::kColorLegacyText2, leo::Theme::kDark))};
leo::GetColor(leo::Color::kColorIconDefault, leo::Theme::kLight),
leo::GetColor(leo::Color::kColorIconDefault, leo::Theme::kDark))};

mixer[kColorSpeedreaderToolbarButtonHover] = {PickSimilarColorToToolbar(
key, mixer, SkColorSetARGB(0x0D, 0x13, 0x16, 0x20),
SkColorSetARGB(0x59, 0x0A, 0x0B, 0x10))};
mixer[kColorSpeedreaderToolbarButtonActive] = {PickSimilarColorToToolbar(
key, mixer, SkColorSetARGB(0x14, 0x13, 0x16, 0x20),
SkColorSetARGB(0x80, 0x0A, 0x0B, 0x10))};
mixer[kColorSpeedreaderToolbarButtonActiveText] = {PickSimilarColorToToolbar(
key, mixer,
leo::GetColor(leo::Color::kColorIconInteractive, leo::Theme::kLight),
leo::GetColor(leo::Color::kColorIconInteractive, leo::Theme::kDark))};
mixer[kColorSpeedreaderToolbarButtonBorder] = {PickSimilarColorToToolbar(
key, mixer, leo::GetColor(leo::Color::kColorGray20, leo::Theme::kLight),
leo::GetColor(leo::Color::kColorGray10, leo::Theme::kDark))};
key, mixer,
leo::GetColor(leo::Color::kColorDividerSubtle, leo::Theme::kLight),
leo::GetColor(leo::Color::kColorDividerSubtle, leo::Theme::kDark))};
}
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,17 @@ void SpeedreaderToolbarDataHandlerImpl::Forward() {
}
}

void SpeedreaderToolbarDataHandlerImpl::OnToolbarStateChanged(
speedreader::mojom::MainButtonType button) {
current_button_ = button;
if (current_button_ != speedreader::mojom::MainButtonType::TextToSpeech) {
Pause();
}
if (active_tab_helper_) {
active_tab_helper_->OnToolbarStateChanged(current_button_);
}
}

speedreader::SpeedreaderService*
SpeedreaderToolbarDataHandlerImpl::GetSpeedreaderService() {
DCHECK(browser_);
Expand Down Expand Up @@ -249,27 +260,6 @@ void SpeedreaderToolbarDataHandlerImpl::OnReadingStop(
events_->SetPlaybackState(speedreader::mojom::PlaybackState::kStopped);
}

void SpeedreaderToolbarDataHandlerImpl::OnReadingProgress(
content::WebContents* web_contents,
int paragraph_index,
int char_index,
int length) {
if (!web_contents) {
return;
}

constexpr const char16_t kHighlight[] = uR"js( highlightText($1, $2, $3) )js";

const auto script = base::ReplaceStringPlaceholders(
kHighlight,
{base::NumberToString16(paragraph_index),
base::NumberToString16(char_index), base::NumberToString16(length)},
nullptr);

web_contents->GetPrimaryMainFrame()->ExecuteJavaScriptInIsolatedWorld(
script, base::DoNothing(), ISOLATED_WORLD_ID_BRAVE_INTERNAL);
}

void SpeedreaderToolbarDataHandlerImpl::OnTabStripModelChanged(
TabStripModel* tab_strip_model,
const TabStripModelChange& change,
Expand All @@ -281,6 +271,7 @@ void SpeedreaderToolbarDataHandlerImpl::OnTabStripModelChanged(
if (selection.new_contents) {
active_tab_helper_ = speedreader::SpeedreaderTabHelper::FromWebContents(
selection.new_contents);
active_tab_helper_->OnToolbarStateChanged(current_button_);
tab_helper_observation_.Observe(active_tab_helper_);
events_->SetPlaybackState(GetTabPlaybackState());
}
Expand Down Expand Up @@ -314,6 +305,8 @@ void SpeedreaderToolbarDataHandlerImpl::OnThemeChanged() {
color_provider->GetColor(kColorSpeedreaderToolbarButtonHover);
colors->button_active =
color_provider->GetColor(kColorSpeedreaderToolbarButtonActive);
colors->button_active_text =
color_provider->GetColor(kColorSpeedreaderToolbarButtonActiveText);
colors->button_border =
color_provider->GetColor(kColorSpeedreaderToolbarButtonBorder);
events_->OnBrowserThemeChanged(std::move(colors));
Expand All @@ -335,3 +328,9 @@ void SpeedreaderToolbarDataHandlerImpl::OnNativeThemeUpdated(
void SpeedreaderToolbarDataHandlerImpl::OnTuneBubbleClosed() {
events_->OnTuneBubbleClosed();
}

void SpeedreaderToolbarDataHandlerImpl::OnContentsReady() {
if (active_tab_helper_) {
active_tab_helper_->OnToolbarStateChanged(current_button_);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ class SpeedreaderToolbarDataHandlerImpl
void Stop() override;
void Forward() override;

void OnToolbarStateChanged(
speedreader::mojom::MainButtonType button) override;

private:
speedreader::SpeedreaderService* GetSpeedreaderService();
speedreader::TtsPlayer::Controller* GetTtsController();
Expand All @@ -84,10 +87,6 @@ class SpeedreaderToolbarDataHandlerImpl
// speedreader::TtsPlayer::Observer:
void OnReadingStart(content::WebContents* web_contents) override;
void OnReadingStop(content::WebContents* web_contents) override;
void OnReadingProgress(content::WebContents* web_contents,
int paragraph_index,
int char_index,
int length) override;

// TabStripModelObserver:
void OnTabStripModelChanged(
Expand All @@ -106,11 +105,15 @@ class SpeedreaderToolbarDataHandlerImpl

// speedreader::SpeedreaderTabHelper::Observer:
void OnTuneBubbleClosed() override;
void OnContentsReady() override;

raw_ptr<Browser> browser_ = nullptr;
mojo::Receiver<speedreader::mojom::ToolbarDataHandler> receiver_;
mojo::Remote<speedreader::mojom::ToolbarEventsHandler> events_;

speedreader::mojom::MainButtonType current_button_ =
speedreader::mojom::MainButtonType::None;

base::ScopedObservation<speedreader::SpeedreaderService,
speedreader::SpeedreaderService::Observer>
speedreader_service_observation_{this};
Expand Down
11 changes: 11 additions & 0 deletions components/speedreader/common/speedreader_toolbar.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ interface ToolbarDataHandler {
Pause();
Stop();
Forward();

OnToolbarStateChanged(MainButtonType button);
};

interface ToolbarEventsHandler {
Expand Down Expand Up @@ -64,6 +66,15 @@ struct ToolbarColors {
uint32 button_hover;
uint32 button_active;
uint32 button_border;
uint32 button_active_text;
};

enum MainButtonType {
None,
Tune,
Appearance,
TextToSpeech,
AI,
};

// Enum is used in prefs. Be careful when changing or extending.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,12 @@
import * as React from 'react'

import * as S from './style'
import { FontFamily, FontSize, PlaybackSpeed, PlaybackState, ColumnWidth } from '../../api/browser'
import { MainButtonType, FontFamily, FontSize, PlaybackSpeed, PlaybackState, ColumnWidth } from '../../api/browser'
import classnames from '$web-common/classnames'
import { loadTimeData } from '$web-common/loadTimeData'
import Icon from '@brave/leo/react/icon'
import { getLocale } from '$web-common/locale'

export enum MainButtonType {
None,
Tune,
Appearance,
TextToSpeech,
AI
}

const mainButtonsOptions = [
{
id: 'tune',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const Button = styled.button<{inGroup?: boolean}>`
background-color: transparent;
&.is-active {
color: rgb(77, 82, 253);
color: var(--color-button-active-text);
background-color: var(--color-button-active);
}
Expand Down
Loading

0 comments on commit ce7c14e

Please sign in to comment.