1
1
/** @jsxImportSource @emotion /react */
2
- import { useEffect , useMemo , useRef } from 'react' ;
2
+ import { useEffect , useMemo , useRef , useState } from 'react' ;
3
3
import { css } from '@emotion/react' ;
4
4
import { useDispatch , useSelector } from 'react-redux' ;
5
5
import { RootState } from '@/renderer/store' ;
6
6
import { setConfig } from '@/renderer/store/slices/appScreenSlice' ;
7
+ import Grid from '@mui/material/Grid' ;
8
+ import IconButton from '@mui/material/IconButton' ;
9
+ import Tooltip from '@mui/material/Tooltip' ;
10
+ import Replay from '@mui/icons-material/Replay' ;
11
+ import Slider from '@mui/material/Slider' ;
12
+ import Stack from '@mui/material/Stack' ;
13
+ import Pause from '@mui/icons-material/Pause' ;
14
+ import PlayArrow from '@mui/icons-material/PlayArrow' ;
15
+ import VolumeOff from '@mui/icons-material/VolumeOff' ;
16
+ import VolumeUp from '@mui/icons-material/VolumeUp' ;
17
+ import { useTranslation } from 'react-i18next' ;
7
18
8
19
const FlashPlayer = ( { url = '' , autoplay = true , filePath = '' , header = true } ) => {
20
+ const [ t ] = useTranslation ( [ 'menu' ] ) ;
9
21
const player : any = useRef ( ) ;
22
+ const [ rufflePlayer , setRufflePlayer ] : any = useState ( null ) ;
10
23
const dispatch = useDispatch ( ) ;
11
24
const stateAppScreen = useSelector ( ( state : RootState ) => state . appScreen ) ;
12
25
const os = useMemo ( ( ) => stateAppScreen . mainGlobalValues . ENV_OS , [ ] ) ;
13
26
14
- useEffect ( ( ) : any => {
15
- const container = player . current ;
16
- container . innerHTML = '' ;
17
-
18
- let realPath ;
27
+ const realPath = useMemo ( ( ) => {
28
+ let path ;
19
29
if ( os === 'Linux' || os === 'macOS' ) {
20
- realPath = filePath . indexOf ( 'file:' ) === - 1 ? `file:///${ filePath } ` : filePath ;
30
+ path = filePath . indexOf ( 'file:' ) === - 1 ? `file:///${ filePath } ` : filePath ;
31
+ } else {
32
+ path = filePath . replace ( 'file:///' , '' ) ;
33
+ }
34
+ return path ;
35
+ } , [ filePath , os ] ) ;
36
+
37
+ const handlePauseOrPlay = ( ) => {
38
+ if ( ! rufflePlayer ) {
39
+ return ;
40
+ }
41
+
42
+ if ( rufflePlayer . isPlaying ) {
43
+ rufflePlayer . pause ( ) ;
21
44
} else {
22
- realPath = filePath . replace ( 'file:///' , '' ) ;
45
+ rufflePlayer . play ( ) ;
23
46
}
47
+ } ;
48
+
49
+ const handleMute = async ( ) => {
50
+ if ( stateAppScreen . flashVolume === 0 ) {
51
+ rufflePlayer . volume = 1 ;
52
+ await dispatch ( setConfig ( { flashVolume : 100 } ) ) ;
53
+ } else {
54
+ rufflePlayer . volume = 0 ;
55
+ await dispatch ( setConfig ( { flashVolume : 0 } ) ) ;
56
+ }
57
+ } ;
58
+
59
+ const handleVolumeSliderChange = async ( event , newValue ) => {
60
+ rufflePlayer . volume = newValue / 100 ;
61
+ await dispatch ( setConfig ( { flashVolume : newValue } ) ) ;
62
+ } ;
63
+
64
+ const loadFlash = ( ) => {
65
+ rufflePlayer . load ( realPath ) ;
66
+ rufflePlayer . addEventListener ( 'oncontextmenu' , ( e ) => e . preventDefault ( ) ) ;
67
+ } ;
68
+
69
+ useEffect ( ( ) => {
70
+ const ruffle = window . RufflePlayer . newest ( ) ;
71
+ setRufflePlayer ( ruffle . createPlayer ( ) ) ;
72
+ } , [ url , filePath ] ) ;
73
+
74
+ useEffect ( ( ) : any => {
75
+ const container = player . current ;
76
+ container . innerHTML = '' ;
24
77
25
78
window . RufflePlayer = window . RufflePlayer || { } ;
26
79
window . RufflePlayer . config = {
@@ -39,11 +92,14 @@ const FlashPlayer = ({ url = '', autoplay = true, filePath = '', header = true }
39
92
realPath . lastIndexOf ( os === 'Windows' ? '\\' : '/' ) ,
40
93
) } `,
41
94
} ;
42
- const ruffle = window . RufflePlayer . newest ( ) ;
43
- const rPlayer = ruffle . createPlayer ( ) ;
44
- rPlayer . id = 'player' ;
45
- rPlayer . addEventListener ( 'loadedmetadata' , async ( ) => {
46
- const metaData = rPlayer ?. metadata ;
95
+
96
+ if ( ! rufflePlayer ) {
97
+ return ;
98
+ }
99
+
100
+ rufflePlayer . id = 'player' ;
101
+ rufflePlayer . addEventListener ( 'loadedmetadata' , async ( ) => {
102
+ const metaData = rufflePlayer ?. metadata ;
47
103
await dispatch (
48
104
setConfig ( {
49
105
flashFileSwfVer : metaData ?. swfVersion ,
@@ -62,39 +118,95 @@ const FlashPlayer = ({ url = '', autoplay = true, filePath = '', header = true }
62
118
} ) ;
63
119
}
64
120
} ) ;
65
- container . appendChild ( rPlayer ) ;
66
- rPlayer . load ( realPath ) ;
67
- rPlayer . addEventListener ( 'oncontextmenu' , ( e ) => e . preventDefault ( ) ) ;
68
- } , [ url , filePath , stateAppScreen . appConfigEmulatePlayerVersion ] ) ;
121
+
122
+ container . appendChild ( rufflePlayer ) ;
123
+ loadFlash ( ) ;
124
+ } , [ url , filePath , stateAppScreen . appConfigEmulatePlayerVersion , rufflePlayer ] ) ;
69
125
70
126
return (
71
127
< div
72
- id = "main"
73
128
css = { css `
74
- align-items : stretch;
75
- width : 100% ;
76
- height : ${ header ? 'calc(100vh - 42px)' : '100vh' } ;
77
- top : 0 ;
78
- left : 0 ;
79
- right : 0 ;
80
- bottom : 0 ;
81
- background : # 000000 ;
82
- color : white;
83
- # player {
84
- width : 100% ;
85
- height : 100% ;
86
- display : block;
87
- }
88
- # container {
89
- margin : 10px ;
90
- width : 100% ;
91
- height : 100% ;
92
- align-self : center;
93
- }
129
+ height : ${ header ? 'calc(100vh - 40px)' : '100vh' } ;
94
130
` }
95
- ref = { player }
96
- onContextMenu = { ( e ) => e . preventDefault ( ) }
97
- />
131
+ >
132
+ < div
133
+ id = "main"
134
+ css = { css `
135
+ align-items : stretch;
136
+ width : 100% ;
137
+ height : calc (100% - ${ stateAppScreen . appConfigShowPlayerController ? 42 : 0 } px);
138
+ top : 0 ;
139
+ left : 0 ;
140
+ right : 0 ;
141
+ bottom : 0 ;
142
+ background : # 000000 ;
143
+ color : white;
144
+ # player {
145
+ width : 100% ;
146
+ height : 100% ;
147
+ display : block;
148
+ }
149
+ # container {
150
+ margin : 10px ;
151
+ width : 100% ;
152
+ height : 100% ;
153
+ align-self : center;
154
+ }
155
+ ` }
156
+ ref = { player }
157
+ onContextMenu = { ( e ) => e . preventDefault ( ) }
158
+ />
159
+ { stateAppScreen . appConfigShowPlayerController && (
160
+ < Grid
161
+ container
162
+ alignItems = "center"
163
+ css = { css `
164
+ height : 42px ;
165
+ ` }
166
+ >
167
+ < Grid item xs = { 12 } >
168
+ < Grid container alignItems = "center" >
169
+ < Grid item >
170
+ < IconButton
171
+ color = "primary"
172
+ size = "small"
173
+ aria-label = "player-pause-and-play"
174
+ onClick = { handlePauseOrPlay }
175
+ >
176
+ { rufflePlayer ?. isPlaying ? < Pause /> : < PlayArrow /> }
177
+ </ IconButton >
178
+ </ Grid >
179
+ < Grid item >
180
+ < Tooltip title = { t ( 'replay' ) } >
181
+ < IconButton
182
+ size = "small"
183
+ aria-label = "player-replay"
184
+ component = "span"
185
+ onClick = { loadFlash }
186
+ >
187
+ < Replay />
188
+ </ IconButton >
189
+ </ Tooltip >
190
+ </ Grid >
191
+ < Grid item xs = { 6 } md = { 4 } >
192
+ < Stack spacing = { 2 } direction = "row" alignItems = "center" >
193
+ < IconButton size = "small" aria-label = "player-mute" onClick = { handleMute } >
194
+ { stateAppScreen . flashVolume === 0 ? < VolumeOff /> : < VolumeUp /> }
195
+ </ IconButton >
196
+ < Slider
197
+ value = { stateAppScreen . flashVolume }
198
+ defaultValue = { 100 }
199
+ onChange = { handleVolumeSliderChange }
200
+ valueLabelDisplay = "off"
201
+ aria-labelledby = "player-volume"
202
+ />
203
+ </ Stack >
204
+ </ Grid >
205
+ </ Grid >
206
+ </ Grid >
207
+ </ Grid >
208
+ ) }
209
+ </ div >
98
210
) ;
99
211
} ;
100
212
0 commit comments