From c162de041d6b082f6c9157c639ff21d90f632ebd Mon Sep 17 00:00:00 2001
From: sienori
Date: Fri, 1 May 2020 23:35:48 +0900
Subject: [PATCH] Add listen button
---
src/_locales/en/messages.json | 3 +++
src/popup/components/CopyButton.js | 38 ++++++++++++++++++++++++++
src/popup/components/InputArea.js | 11 ++++++--
src/popup/components/ListenButton.js | 32 ++++++++++++++++++++++
src/popup/components/MediaButtons.js | 40 ----------------------------
src/popup/components/PopupPage.js | 10 +++++--
src/popup/components/ResultArea.js | 10 ++++---
src/popup/icons/speaker.svg | 3 +++
src/popup/styles/CopyButton.scss | 27 +++++++++++++++++++
src/popup/styles/InputArea.scss | 9 +++++++
src/popup/styles/ListenButton.scss | 15 +++++++++++
src/popup/styles/MediaButtons.scss | 33 -----------------------
src/popup/styles/ResultArea.scss | 12 ++++++++-
13 files changed, 162 insertions(+), 81 deletions(-)
create mode 100644 src/popup/components/CopyButton.js
create mode 100644 src/popup/components/ListenButton.js
delete mode 100644 src/popup/components/MediaButtons.js
create mode 100644 src/popup/icons/speaker.svg
create mode 100644 src/popup/styles/CopyButton.scss
create mode 100644 src/popup/styles/ListenButton.scss
delete mode 100644 src/popup/styles/MediaButtons.scss
diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json
index c65165a..f8e2ecd 100644
--- a/src/_locales/en/messages.json
+++ b/src/_locales/en/messages.json
@@ -33,6 +33,9 @@
"copiedLabel": {
"message": "Copied."
},
+ "listenLabel": {
+ "message": "Listen"
+ },
"targetLangLabel": {
"message": "Target language"
},
diff --git a/src/popup/components/CopyButton.js b/src/popup/components/CopyButton.js
new file mode 100644
index 0000000..01b470e
--- /dev/null
+++ b/src/popup/components/CopyButton.js
@@ -0,0 +1,38 @@
+import React, { Component } from "react";
+import browser from "webextension-polyfill";
+import { CopyToClipboard } from "react-copy-to-clipboard";
+import CopyIcon from "../icons/copy.svg";
+import "../styles/CopyButton.scss";
+
+export default class CopyButton extends Component {
+ constructor(props) {
+ super(props);
+ this.state = { isCopied: false };
+ }
+
+ handleCopy = () => {
+ this.setState({ isCopied: true });
+ };
+
+ componentWillReceiveProps(nextProps) {
+ if (this.props.text !== nextProps.text) this.setState({ isCopied: false });
+ }
+
+ render() {
+ const { text } = this.props;
+ if (!text) return null;
+
+ return (
+
+ {this.state.isCopied && (
+ {browser.i18n.getMessage("copiedLabel")}
+ )}
+
+
+
+
+ );
+ }
+}
diff --git a/src/popup/components/InputArea.js b/src/popup/components/InputArea.js
index b97ab06..75f6f3f 100644
--- a/src/popup/components/InputArea.js
+++ b/src/popup/components/InputArea.js
@@ -1,6 +1,7 @@
import React, { Component } from "react";
import ReactDOM from "react-dom";
import browser from "webextension-polyfill";
+import ListenButton from "./ListenButton";
import "../styles/inputArea.scss";
export default class InputArea extends Component {
@@ -16,7 +17,9 @@ export default class InputArea extends Component {
};
shouldComponentUpdate(nextProps) {
- const shouldUpdate = this.props.inputText !== nextProps.inputText;
+ const shouldUpdate =
+ this.props.inputText !== nextProps.inputText ||
+ this.props.sourceLang !== nextProps.sourceLang;
return shouldUpdate;
}
@@ -25,16 +28,20 @@ export default class InputArea extends Component {
};
render() {
+ const { inputText, sourceLang } = this.props;
return (
);
}
diff --git a/src/popup/components/ListenButton.js b/src/popup/components/ListenButton.js
new file mode 100644
index 0000000..feb275c
--- /dev/null
+++ b/src/popup/components/ListenButton.js
@@ -0,0 +1,32 @@
+import React from "react";
+import browser from "webextension-polyfill";
+import log from "loglevel";
+import SpeakerIcon from "../icons/speaker.svg";
+import "../styles/ListenButton.scss";
+
+const logDir = "popup/AudioButton";
+
+const playAudio = async (text, lang) => {
+ const url = `https://translate.google.com/translate_tts?client=tw-ob&q=${encodeURIComponent(
+ text
+ )}&tl=${lang}`;
+ const audio = new Audio(url);
+ audio.load();
+ await audio.play().catch(e => log.error(logDir, "playAudio()", e, url));
+};
+
+export default props => {
+ const { text, lang } = props;
+ const canListen = text && text.length < 200;
+ if (!canListen) return null;
+
+ return (
+
+ );
+};
diff --git a/src/popup/components/MediaButtons.js b/src/popup/components/MediaButtons.js
deleted file mode 100644
index d97b675..0000000
--- a/src/popup/components/MediaButtons.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import React, { Component } from "react";
-import browser from "webextension-polyfill";
-import { CopyToClipboard } from "react-copy-to-clipboard";
-import CopyIcon from "../icons/copy.svg";
-import "../styles/MediaButtons.scss";
-
-export default class CopyButton extends Component {
- constructor(props) {
- super(props);
- this.state = { isCopied: false };
- }
-
- handleCopy = () => {
- this.setState({ isCopied: true });
- };
-
- componentWillReceiveProps(nextProps) {
- if (this.props.resultText !== nextProps.resultText) this.setState({ isCopied: false });
- }
-
- render() {
- const { resultText } = this.props;
- return (
- resultText && (
-
-
- {this.state.isCopied && (
- {browser.i18n.getMessage("copiedLabel")}
- )}
-
-
-
-
-
- )
- );
- }
-}
diff --git a/src/popup/components/PopupPage.js b/src/popup/components/PopupPage.js
index e852c44..04faa4b 100644
--- a/src/popup/components/PopupPage.js
+++ b/src/popup/components/PopupPage.js
@@ -39,6 +39,7 @@ export default class PopupPage extends Component {
inputText: "",
resultText: "",
candidateText: "",
+ sourceLang: "",
statusText: "OK",
tabUrl: "",
isConnected: true,
@@ -93,7 +94,8 @@ export default class PopupPage extends Component {
this.setState({
resultText: result.resultText,
candidateText: result.candidateText,
- statusText: result.statusText
+ statusText: result.statusText,
+ sourceLang: result.sourceLanguage
});
return result;
};
@@ -143,7 +145,11 @@ export default class PopupPage extends Component {
isEnabledOnPage={this.state.isEnabledOnPage}
isConnected={this.state.isConnected}
/>
-
+
{
const regex = /(\n)/g;
@@ -12,7 +13,7 @@ const splitLine = text => {
};
export default props => {
- const { resultText, candidateText, statusText } = props;
+ const { resultText, candidateText, statusText, targetLang } = props;
const isError = statusText !== "OK";
const shouldShowCandidate = getSettings("ifShowCandidate");
@@ -33,7 +34,10 @@ export default props => {
{browser.i18n.getMessage("openInGoogleLabel")}
)}
-
+
+
+
+
);
};
diff --git a/src/popup/icons/speaker.svg b/src/popup/icons/speaker.svg
new file mode 100644
index 0000000..6effb2c
--- /dev/null
+++ b/src/popup/icons/speaker.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/popup/styles/CopyButton.scss b/src/popup/styles/CopyButton.scss
new file mode 100644
index 0000000..0f9d632
--- /dev/null
+++ b/src/popup/styles/CopyButton.scss
@@ -0,0 +1,27 @@
+.copy {
+ display: flex;
+ justify-content: center;
+
+ .copiedText {
+ color: var(--sub-text);
+ font-size: 12px;
+ margin-right: 5px;
+ -moz-user-select: none;
+ -webkit-user-select: none;
+ }
+ .copyButton {
+ padding: 0;
+ border: 0;
+ background-color: var(--main-bg);
+ cursor: pointer;
+
+ svg {
+ height: 16px;
+ width: 16px;
+ fill: var(--sub-text);
+ &:hover {
+ fill: var(--highlight);
+ }
+ }
+ }
+}
diff --git a/src/popup/styles/InputArea.scss b/src/popup/styles/InputArea.scss
index 3700b4a..78b1454 100644
--- a/src/popup/styles/InputArea.scss
+++ b/src/popup/styles/InputArea.scss
@@ -1,5 +1,7 @@
#inputArea {
+ position: relative;
margin: 10px;
+
textarea {
font: inherit;
resize: none;
@@ -23,4 +25,11 @@
textarea:focus {
border-color: var(--highlight);
}
+
+ .listen {
+ position: absolute;
+ height: 16px;
+ right: 5px;
+ bottom: 5px;
+ }
}
diff --git a/src/popup/styles/ListenButton.scss b/src/popup/styles/ListenButton.scss
new file mode 100644
index 0000000..45143d2
--- /dev/null
+++ b/src/popup/styles/ListenButton.scss
@@ -0,0 +1,15 @@
+.listenButton {
+ padding: 0;
+ border: 0;
+ background-color: rgba(0, 0, 0, 0);
+ cursor: pointer;
+
+ svg {
+ height: 16px;
+ width: 16px;
+ fill: var(--sub-text);
+ &:hover {
+ fill: var(--highlight);
+ }
+ }
+}
diff --git a/src/popup/styles/MediaButtons.scss b/src/popup/styles/MediaButtons.scss
deleted file mode 100644
index fd3d2ae..0000000
--- a/src/popup/styles/MediaButtons.scss
+++ /dev/null
@@ -1,33 +0,0 @@
-.mediaButtons {
- display: flex;
- flex-direction: row;
- justify-content: flex-end;
-
- .copy {
- display: flex;
- justify-content: center;
-
- .copiedText {
- color: var(--sub-text);
- font-size: 12px;
- margin-right: 5px;
- -moz-user-select: none;
- -webkit-user-select: none;
- }
- .copyButton {
- padding: 0;
- border: 0;
- background-color: var(--main-bg);
- cursor: pointer;
-
- svg {
- height: 16px;
- width: 16px;
- fill: var(--sub-text);
- &:hover {
- fill: var(--highlight);
- }
- }
- }
- }
-}
diff --git a/src/popup/styles/ResultArea.scss b/src/popup/styles/ResultArea.scss
index af10a20..4d0d34e 100644
--- a/src/popup/styles/ResultArea.scss
+++ b/src/popup/styles/ResultArea.scss
@@ -4,7 +4,7 @@
overflow-y: auto;
word-wrap: break-word;
background-color: var(--main-bg);
- margin: 10px;
+ margin: 10px 10px 3px;
p {
margin: 0;
@@ -35,4 +35,14 @@
}
}
}
+
+ .mediaButtons {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-end;
+ margin-right: 5px;
+ & > * {
+ margin-left: 10px;
+ }
+ }
}