diff --git a/images/icon-paste.svg b/images/icon-paste.svg new file mode 100644 index 000000000..d7de9a489 --- /dev/null +++ b/images/icon-paste.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/js/background.js b/js/background.js index 20d023f26..870942002 100644 --- a/js/background.js +++ b/js/background.js @@ -116,6 +116,7 @@ 'warning.svg', 'x.svg', 'x_white.svg', + 'icon-paste.svg', 'loki/loki_icon_text.png', 'loki/loki_icon_128.png', ]); diff --git a/js/views/main_header_view.js b/js/views/main_header_view.js index 7a7470e12..ab3e46626 100644 --- a/js/views/main_header_view.js +++ b/js/views/main_header_view.js @@ -10,8 +10,6 @@ templateName: 'main-header-placeholder', events: { 'click .main-header-title-wrapper': 'onClick', - 'click .edit-name': 'onEditProfile', - 'click .copy-key': 'onCopyKey', }, initialize(options) { this.ourNumber = textsecure.storage.user.getNumber(); diff --git a/stylesheets/_modules.scss b/stylesheets/_modules.scss index aa3050134..4a011d833 100644 --- a/stylesheets/_modules.scss +++ b/stylesheets/_modules.scss @@ -2333,6 +2333,17 @@ @include color-svg('../images/x-16.svg', $color-gray-60); } +.module-main-header__search__copy-from-clipboard { + position: absolute; + right: 16px; + top: 5px; + width: 20px; + height: 22px; + opacity: 0.8; + cursor: pointer; + @include color-svg('../images/icon-paste.svg', $color-gray-60); +} + // Module: Image .module-image { diff --git a/ts/components/MainHeader.tsx b/ts/components/MainHeader.tsx index bedd2f394..946077894 100644 --- a/ts/components/MainHeader.tsx +++ b/ts/components/MainHeader.tsx @@ -13,6 +13,9 @@ import { ContactName } from './conversation/ContactName'; import { cleanSearchTerm } from '../util/cleanSearchTerm'; import { LocalizerType } from '../types/Util'; +import { clipboard } from 'electron'; + +import { validateNumber } from '../types/PhoneNumber'; interface MenuItem { id: string; @@ -56,6 +59,7 @@ export class MainHeader extends React.Component { event: React.FormEvent ) => void; private readonly clearSearchBound: () => void; + private readonly copyFromClipboardBound: () => void; private readonly handleKeyUpBound: ( event: React.KeyboardEvent ) => void; @@ -69,16 +73,23 @@ export class MainHeader extends React.Component { this.state = { expanded: false, hasPass: null, + clipboardText: '', menuItems: [], }; this.updateSearchBound = this.updateSearch.bind(this); this.clearSearchBound = this.clearSearch.bind(this); + this.copyFromClipboardBound = this.copyFromClipboard.bind(this); this.handleKeyUpBound = this.handleKeyUp.bind(this); this.setFocusBound = this.setFocus.bind(this); this.inputRef = React.createRef(); this.debouncedSearch = debounce(this.search.bind(this), 20); + + setInterval(() => { + const clipboardText = clipboard.readText(); + this.setState({ clipboardText }); + }, 100); } public componentWillMount() { @@ -136,6 +147,13 @@ export class MainHeader extends React.Component { this.setFocus(); } + public copyFromClipboard() { + const { clipboardText } = this.state; + + this.props.updateSearchTerm(clipboardText); + this.debouncedSearch(clipboardText); + } + public handleKeyUp(event: React.KeyboardEvent) { const { clearSearch } = this.props; @@ -233,6 +251,15 @@ export class MainHeader extends React.Component { ); } + private shouldShowPaste() { + const { searchTerm, i18n } = this.props; + const { clipboardText } = this.state; + + const error = validateNumber(clipboardText, i18n); + + return !searchTerm && !error; + } + private renderSearch() { const { searchTerm, i18n } = this.props; @@ -248,6 +275,13 @@ export class MainHeader extends React.Component { value={searchTerm} onChange={this.updateSearchBound} /> + {this.shouldShowPaste() ? ( + + ) : null}