summaryrefslogtreecommitdiffhomepage
path: root/gui/src/renderer/components/ClipboardLabel.tsx
blob: 2131e884df33e8a1b8e6b186f68a918976db91df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import * as React from 'react';
import styled from 'styled-components';
import { messages } from '../../shared/gettext';
import log from '../../shared/logging';
import { Scheduler } from '../../shared/scheduler';

interface IProps {
  value: string;
  displayValue?: string;
  delay: number;
  message?: string;
  className?: string;
}

interface IState {
  showsMessage: boolean;
}

const Label = styled.span({
  cursor: 'pointer',
});

export default class ClipboardLabel extends React.Component<IProps, IState> {
  public static defaultProps: Partial<IProps> = {
    delay: 3000,
  };

  public state: IState = {
    showsMessage: false,
  };

  private scheduler = new Scheduler();

  public componentWillUnmount() {
    this.scheduler.cancel();
  }

  public render() {
    const message = this.props.message ?? messages.gettext('COPIED TO CLIPBOARD!');
    const displayValue = this.props.displayValue ?? this.props.value;
    return (
      <Label className={this.props.className} onClick={this.handlePress}>
        {this.state.showsMessage ? message : displayValue}
      </Label>
    );
  }

  private handlePress = async () => {
    try {
      await navigator.clipboard.writeText(this.props.value);
      this.scheduler.schedule(() => this.setState({ showsMessage: false }), this.props.delay);
      this.setState({ showsMessage: true });
    } catch (error) {
      log.error(`Failed to copy to clipboard: ${error.message}`);
    }
  };
}