@@ -36,6 +36,7 @@ struct AudioControllerView: View {
3636 @AppStorage ( " DedeUserID__ckMd5 " ) var dedeUserID__ckMd5 = " "
3737 @AppStorage ( " SESSDATA " ) var sessdata = " "
3838 @AppStorage ( " bili_jct " ) var biliJct = " "
39+ @AppStorage ( " isFastFowardUsedBefore " ) var isFastFowardUsedBefore = false
3940 @Namespace var coverScaleNamespace
4041 @State var currentPlaybackTime = globalAudioPlayer. currentTime ( ) . seconds
4142 @State var currentItemTotalTime = 0.0
@@ -46,30 +47,101 @@ struct AudioControllerView: View {
4647 @State var playbackBehavior = PlaybackBehavior . pause
4748 @State var backgroundImageUrl : URL ?
4849 @State var videoName = " "
50+ @State var backwardTaps = 0
51+ @State var backwardTapsSnapshot = 0
52+ @State var forwardTaps = 0 //双击屏幕右侧的点击计数器
53+ @State var forwardTapsSnapshop = 0
54+ @State var forwardTimer : Timer ?
55+ @State var backwardTimer : Timer ?
4956 var body : some View {
5057 NavigationStack {
5158 ZStack {
52- if let backgroundImageUrl {
53- WebImage ( url: backgroundImageUrl, options: [ . progressiveLoad, . scaleDownLargeImages] )
54- . placeholder {
55- RoundedRectangle ( cornerRadius: 14 )
56- . frame ( width: 120 , height: 80 )
57- . foregroundColor ( Color ( hex: 0x3D3D3D ) )
58- . redacted ( reason: . placeholder)
59+ HStack {
60+ Rectangle ( )
61+ . frame ( width: 45 )
62+ . opacity ( kViewMinimumRenderableOpacity)
63+ . onTapGesture ( perform: {
64+ if currentPlaybackTime - 10 > 0 {
65+ forwardTaps = 0
66+ backwardTaps += 1
67+ backwardTapsSnapshot = backwardTaps
68+ if backwardTaps > 1 {
69+ globalAudioPlayer. seek ( to: CMTime ( seconds: currentPlaybackTime - 10 , preferredTimescale: 60000 ) ,
70+ toleranceBefore: . zero,
71+ toleranceAfter: . zero)
72+ }
73+ }
74+ } )
75+ Spacer ( )
76+ Rectangle ( )
77+ . frame ( width: 45 )
78+ . opacity ( kViewMinimumRenderableOpacity)
79+ . onTapGesture ( perform: {
80+ if currentPlaybackTime + 10 < currentItemTotalTime {
81+ backwardTaps = 0
82+ forwardTaps += 1
83+ forwardTapsSnapshop = forwardTaps
84+ if forwardTaps > 1 {
85+ globalAudioPlayer. seek ( to: CMTime ( seconds: currentPlaybackTime + 10 , preferredTimescale: 60000 ) ,
86+ toleranceBefore: . zero,
87+ toleranceAfter: . zero)
88+ }
89+ }
90+ } )
91+ }
92+ . ignoresSafeArea ( . container)
93+ . frame ( height: 120 )
94+ . offset ( y: - 20 )
95+ . onChange ( of: forwardTaps, perform: { value in
96+ if forwardTaps != 0 {
97+ forwardTimer? . invalidate ( )
98+ forwardTimer = Timer . scheduledTimer ( withTimeInterval: 0.75 , repeats: false ) { value in
99+ if forwardTapsSnapshop == forwardTaps {
100+ forwardTaps = 0
101+ }
102+ forwardTapsSnapshop = forwardTaps
103+ }
104+ }
105+ } )
106+ . onChange ( of: backwardTaps, perform: { value in
107+ if backwardTaps != 0 {
108+ backwardTimer? . invalidate ( )
109+ backwardTimer = Timer . scheduledTimer ( withTimeInterval: 0.75 , repeats: false ) { _ in
110+ // if forwardTapsSnapshop == forwardTaps {
111+ // forwardTaps = 0
112+ // }
113+ if backwardTapsSnapshot == backwardTaps {
114+ backwardTaps = 0
115+ }
116+ // forwardTapsSnapshop = forwardTaps
117+
59118 }
60- . resizable ( )
61- . cornerRadius ( 10 )
62- . scaledToFit ( )
63- . frame ( width: 120 , height: 80 )
64- . shadow ( color: . black. opacity ( 0.5 ) , radius: 5 , x: 1 , y: 2 )
65- . offset ( y: - 24 )
66- } else {
67- RoundedRectangle ( cornerRadius: 14 )
68- . frame ( width: 120 , height: 80 )
69- . foregroundColor ( Color ( hex: 0x3D3D3D ) )
70- . redacted ( reason: . placeholder)
71- . offset ( y: - 24 )
119+ }
120+ } )
121+ Group {
122+ if let backgroundImageUrl {
123+ WebImage ( url: backgroundImageUrl, options: [ . progressiveLoad, . scaleDownLargeImages] )
124+ . placeholder {
125+ RoundedRectangle ( cornerRadius: 14 )
126+ . frame ( width: 120 , height: 80 )
127+ . foregroundColor ( Color ( hex: 0x3D3D3D ) )
128+ . redacted ( reason: . placeholder)
129+ }
130+ . resizable ( )
131+ . cornerRadius ( 10 )
132+ . scaledToFit ( )
133+ . frame ( width: 120 , height: 80 )
134+ . shadow ( color: . black. opacity ( 0.5 ) , radius: 5 , x: 1 , y: 2 )
135+ . offset ( y: - 24 )
136+ } else {
137+ RoundedRectangle ( cornerRadius: 14 )
138+ . frame ( width: 120 , height: 80 )
139+ . foregroundColor ( Color ( hex: 0x3D3D3D ) )
140+ . redacted ( reason: . placeholder)
141+ . offset ( y: - 24 )
142+ }
72143 }
144+
73145 // Audio Controls
74146 VStack {
75147 Spacer ( )
@@ -170,7 +242,7 @@ struct AudioControllerView: View {
170242 }
171243 . ignoresSafeArea ( )
172244 }
173- . navigationTitle ( videoName)
245+ . navigationTitle ( backwardTaps > 1 ? ( Text ( " 快退 \( 10 * ( backwardTaps - 1 ) ) s " ) ) : ( forwardTaps > 1 ? Text ( " 快进 \( 10 * ( forwardTaps - 1 ) ) s " ) : Text ( videoName) ) )
174246 . modifier ( BlurBackground ( imageUrl: backgroundImageUrl) )
175247 }
176248 . onAppear {
@@ -229,7 +301,7 @@ struct AudioControllerView: View {
229301 Circle ( )
230302 . fill ( Color . gray)
231303 . scaleEffect ( configuration. isPressed ? 0.9 : 1 )
232- . opacity ( configuration. isPressed ? 0.4 : 0.0100000002421438702673861521 )
304+ . opacity ( configuration. isPressed ? 0.4 : kViewMinimumRenderableOpacity )
233305 configuration. label
234306 . scaleEffect ( configuration. isPressed ? 0.9 : 1 )
235307 }
0 commit comments