StopWatch.tsx 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
  2. import { h, Component } from 'preact'
  3. type $TSFixMe = any
  4. function fmtMSS(s: number) {
  5. // eslint-disable-next-line no-return-assign, no-param-reassign
  6. return (s - (s %= 60)) / 60 + (s > 9 ? ':' : ':0') + s
  7. }
  8. class StopWatch extends Component {
  9. private wrapperStyle = {
  10. width: '100%',
  11. height: '100%',
  12. display: 'flex',
  13. } as const
  14. private overlayStyle = {
  15. position: 'absolute',
  16. width: '100%',
  17. height: '100%',
  18. background: 'black',
  19. opacity: 0.7,
  20. } as const
  21. private infoContainerStyle = {
  22. marginLeft: 'auto',
  23. marginRight: 'auto',
  24. marginTop: 'auto',
  25. marginBottom: 'auto',
  26. zIndex: 1,
  27. color: 'white',
  28. } as const
  29. private infotextStyle = {
  30. marginLeft: 'auto',
  31. marginRight: 'auto',
  32. marginBottom: '1rem',
  33. fontSize: '1.5rem',
  34. } as const
  35. private timeStyle = {
  36. display: 'block',
  37. fontWeight: 'bold',
  38. marginLeft: 'auto',
  39. marginRight: 'auto',
  40. fontSize: '3rem',
  41. fontFamily: 'Courier New',
  42. } as const
  43. private timerRunning: boolean = false
  44. private timer?: ReturnType<typeof setTimeout>
  45. constructor(props: $TSFixMe) {
  46. super(props)
  47. this.state = { elapsedTime: 0 }
  48. }
  49. startTimer() {
  50. this.timerTick()
  51. this.timerRunning = true
  52. }
  53. resetTimer() {
  54. clearTimeout(this.timer)
  55. this.setState({ elapsedTime: 0 })
  56. this.timerRunning = false
  57. }
  58. timerTick() {
  59. this.timer = setTimeout(() => {
  60. this.setState((state: $TSFixMe) => ({
  61. elapsedTime: state.elapsedTime + 1,
  62. }))
  63. this.timerTick()
  64. }, 1000)
  65. }
  66. render() {
  67. const { recording, i18n } = { ...this.props } as $TSFixMe
  68. const { elapsedTime } = this.state as $TSFixMe
  69. // second to minutes and seconds
  70. const minAndSec = fmtMSS(elapsedTime)
  71. if (recording && !this.timerRunning) {
  72. this.startTimer()
  73. }
  74. if (!recording && this.timerRunning) {
  75. this.resetTimer()
  76. }
  77. if (recording) {
  78. return (
  79. <div style={this.wrapperStyle}>
  80. <div style={this.overlayStyle} />
  81. <div style={this.infoContainerStyle}>
  82. <div style={this.infotextStyle}>{i18n('recording')}</div>
  83. <div style={this.timeStyle}>{minAndSec}</div>
  84. </div>
  85. </div>
  86. )
  87. }
  88. return null
  89. }
  90. }
  91. export default StopWatch