index.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. 'use client'
  2. import { useState } from 'react'
  3. import { t } from 'i18next'
  4. import { useParams, usePathname } from 'next/navigation'
  5. import s from './style.module.css'
  6. import Tooltip from '@/app/components/base/tooltip'
  7. import Loading from '@/app/components/base/loading'
  8. import { AudioPlayerManager } from '@/app/components/base/audio-btn/audio.player.manager'
  9. type AudioBtnProps = {
  10. id?: string
  11. voice?: string
  12. value?: string
  13. className?: string
  14. isAudition?: boolean
  15. noCache?: boolean
  16. }
  17. type AudioState = 'initial' | 'loading' | 'playing' | 'paused' | 'ended'
  18. const AudioBtn = ({
  19. id,
  20. voice,
  21. value,
  22. className,
  23. isAudition,
  24. }: AudioBtnProps) => {
  25. const [audioState, setAudioState] = useState<AudioState>('initial')
  26. const params = useParams()
  27. const pathname = usePathname()
  28. const audio_finished_call = (event: string): any => {
  29. switch (event) {
  30. case 'ended':
  31. setAudioState('ended')
  32. break
  33. case 'paused':
  34. setAudioState('ended')
  35. break
  36. case 'loaded':
  37. setAudioState('loading')
  38. break
  39. case 'play':
  40. setAudioState('playing')
  41. break
  42. case 'error':
  43. setAudioState('ended')
  44. break
  45. }
  46. }
  47. let url = ''
  48. let isPublic = false
  49. if (params.token) {
  50. url = '/text-to-audio'
  51. isPublic = true
  52. }
  53. else if (params.appId) {
  54. if (pathname.search('explore/installed') > -1)
  55. url = `/installed-apps/${params.appId}/text-to-audio`
  56. else
  57. url = `/apps/${params.appId}/text-to-audio`
  58. }
  59. const handleToggle = async () => {
  60. if (audioState === 'playing' || audioState === 'loading') {
  61. setTimeout(() => setAudioState('paused'), 1)
  62. AudioPlayerManager.getInstance().getAudioPlayer(url, isPublic, id, value, voice, audio_finished_call).pauseAudio()
  63. }
  64. else {
  65. setTimeout(() => setAudioState('loading'), 1)
  66. AudioPlayerManager.getInstance().getAudioPlayer(url, isPublic, id, value, voice, audio_finished_call).playAudio()
  67. }
  68. }
  69. const tooltipContent = {
  70. initial: t('appApi.play'),
  71. ended: t('appApi.play'),
  72. paused: t('appApi.pause'),
  73. playing: t('appApi.playing'),
  74. loading: t('appApi.loading'),
  75. }[audioState]
  76. return (
  77. <div className={`inline-flex items-center justify-center ${(audioState === 'loading' || audioState === 'playing') ? 'mr-1' : className}`}>
  78. <Tooltip
  79. popupContent={tooltipContent}
  80. >
  81. <button
  82. disabled={audioState === 'loading'}
  83. className={`box-border w-6 h-6 flex items-center justify-center cursor-pointer ${isAudition ? 'p-0.5' : 'p-0 rounded-md bg-white'}`}
  84. onClick={handleToggle}
  85. >
  86. {audioState === 'loading'
  87. ? (
  88. <div className='w-full h-full rounded-md flex items-center justify-center'>
  89. <Loading />
  90. </div>
  91. )
  92. : (
  93. <div className={`w-full h-full rounded-md flex items-center justify-center ${!isAudition ? 'hover:bg-gray-50' : 'hover:bg-gray-50'}`}>
  94. <div className={`w-4 h-4 ${(audioState === 'playing') ? s.pauseIcon : s.playIcon}`}></div>
  95. </div>
  96. )}
  97. </button>
  98. </Tooltip>
  99. </div>
  100. )
  101. }
  102. export default AudioBtn