@neoskola/auto-play 0.3.6 → 0.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -37,14 +37,16 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
37
37
|
let titleText = Parser.parseText(text: config.title) ?? "Now Playing"
|
|
38
38
|
let subtitleText = config.subtitle.flatMap { Parser.parseText(text: $0) } ?? ""
|
|
39
39
|
|
|
40
|
-
// Section 1: Bilgi — ders ve kurs adi
|
|
40
|
+
// Section 1: Bilgi — ders ve kurs adi + progress bar accessory
|
|
41
41
|
let infoItem = CPListItem(
|
|
42
42
|
text: titleText,
|
|
43
43
|
detailText: subtitleText,
|
|
44
|
-
image: UIImage(systemName: "music.note")
|
|
44
|
+
image: UIImage(systemName: "music.note")?
|
|
45
|
+
.withTintColor(.systemPurple, renderingMode: .alwaysOriginal),
|
|
45
46
|
accessoryImage: nil,
|
|
46
47
|
accessoryType: .none
|
|
47
48
|
)
|
|
49
|
+
infoItem.isEnabled = false
|
|
48
50
|
let infoSection = CPListSection(
|
|
49
51
|
items: [infoItem],
|
|
50
52
|
header: "Şimdi Oynatılıyor",
|
|
@@ -55,35 +57,40 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
55
57
|
let timeItem = CPListItem(
|
|
56
58
|
text: "Yükleniyor...",
|
|
57
59
|
detailText: nil,
|
|
58
|
-
image: UIImage(systemName: "clock")
|
|
60
|
+
image: UIImage(systemName: "clock")?
|
|
61
|
+
.withTintColor(.systemGray, renderingMode: .alwaysOriginal),
|
|
59
62
|
accessoryImage: nil,
|
|
60
63
|
accessoryType: .none
|
|
61
64
|
)
|
|
65
|
+
timeItem.isEnabled = false
|
|
62
66
|
let timeSection = CPListSection(
|
|
63
67
|
items: [timeItem],
|
|
64
68
|
header: nil,
|
|
65
69
|
sectionIndexTitle: nil
|
|
66
70
|
)
|
|
67
71
|
|
|
68
|
-
// Section 3: Kontroller —
|
|
72
|
+
// Section 3: Kontroller — renkli ikonlar
|
|
69
73
|
let prevItem = CPListItem(
|
|
70
74
|
text: "Önceki Bölüm",
|
|
71
75
|
detailText: nil,
|
|
72
|
-
image: UIImage(systemName: "backward.end.fill")
|
|
76
|
+
image: UIImage(systemName: "backward.end.fill")?
|
|
77
|
+
.withTintColor(.systemBlue, renderingMode: .alwaysOriginal),
|
|
73
78
|
accessoryImage: nil,
|
|
74
79
|
accessoryType: .none
|
|
75
80
|
)
|
|
76
81
|
let playPauseItem = CPListItem(
|
|
77
82
|
text: "Oynat",
|
|
78
83
|
detailText: nil,
|
|
79
|
-
image: UIImage(systemName: "play.circle.fill")
|
|
84
|
+
image: UIImage(systemName: "play.circle.fill")?
|
|
85
|
+
.withTintColor(.systemGreen, renderingMode: .alwaysOriginal),
|
|
80
86
|
accessoryImage: nil,
|
|
81
87
|
accessoryType: .none
|
|
82
88
|
)
|
|
83
89
|
let nextItem = CPListItem(
|
|
84
90
|
text: "Sonraki Bölüm",
|
|
85
91
|
detailText: nil,
|
|
86
|
-
image: UIImage(systemName: "forward.end.fill")
|
|
92
|
+
image: UIImage(systemName: "forward.end.fill")?
|
|
93
|
+
.withTintColor(.systemBlue, renderingMode: .alwaysOriginal),
|
|
87
94
|
accessoryImage: nil,
|
|
88
95
|
accessoryType: .none
|
|
89
96
|
)
|
|
@@ -94,7 +101,7 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
94
101
|
)
|
|
95
102
|
|
|
96
103
|
template = CPListTemplate(
|
|
97
|
-
title:
|
|
104
|
+
title: titleText,
|
|
98
105
|
sections: [infoSection, timeSection, controlSection],
|
|
99
106
|
assistantCellConfiguration: nil,
|
|
100
107
|
id: config.id
|
|
@@ -125,15 +132,17 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
125
132
|
}
|
|
126
133
|
|
|
127
134
|
playPauseItem.handler = { [weak self] _, completion in
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
self.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
DispatchQueue.main.async {
|
|
136
|
+
guard let self = self else { completion(); return }
|
|
137
|
+
if self.config.isPlaying {
|
|
138
|
+
self.pauseAudio()
|
|
139
|
+
self.config.onPause?()
|
|
140
|
+
} else {
|
|
141
|
+
self.resumeAudio()
|
|
142
|
+
self.config.onPlay?()
|
|
143
|
+
}
|
|
144
|
+
completion()
|
|
135
145
|
}
|
|
136
|
-
completion()
|
|
137
146
|
}
|
|
138
147
|
|
|
139
148
|
nextItem.handler = { [weak self] _, completion in
|
|
@@ -148,60 +157,79 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
148
157
|
let titleText = Parser.parseText(text: config.title) ?? "Now Playing"
|
|
149
158
|
let subtitleText = config.subtitle.flatMap { Parser.parseText(text: $0) } ?? ""
|
|
150
159
|
|
|
151
|
-
//
|
|
160
|
+
// Progress hesapla
|
|
161
|
+
let progress = currentDuration > 0 ? currentElapsedTime / currentDuration : 0
|
|
162
|
+
|
|
163
|
+
// Section 1: Bilgi + progress bar accessory
|
|
152
164
|
let infoItem = CPListItem(
|
|
153
165
|
text: titleText,
|
|
154
166
|
detailText: subtitleText,
|
|
155
|
-
image: loadedImage ?? UIImage(systemName: "music.note")
|
|
156
|
-
|
|
167
|
+
image: loadedImage ?? UIImage(systemName: "music.note")?
|
|
168
|
+
.withTintColor(.systemPurple, renderingMode: .alwaysOriginal),
|
|
169
|
+
accessoryImage: drawProgressBarImage(progress: progress),
|
|
157
170
|
accessoryType: .none
|
|
158
171
|
)
|
|
172
|
+
infoItem.isEnabled = false
|
|
159
173
|
let infoSection = CPListSection(
|
|
160
174
|
items: [infoItem],
|
|
161
175
|
header: "Şimdi Oynatılıyor",
|
|
162
176
|
sectionIndexTitle: nil
|
|
163
177
|
)
|
|
164
178
|
|
|
165
|
-
// Section 2: Sure
|
|
179
|
+
// Section 2: Sure + yuzde detay
|
|
166
180
|
let elapsed = formatTime(currentElapsedTime)
|
|
167
181
|
let total = currentDuration > 0 ? formatTime(currentDuration) : "--:--"
|
|
168
182
|
let timeText: String
|
|
169
|
-
let timeIcon:
|
|
183
|
+
let timeIcon: UIImage?
|
|
170
184
|
if config.isPlaying {
|
|
171
185
|
timeText = "\(elapsed) / \(total)"
|
|
172
|
-
timeIcon = "waveform"
|
|
186
|
+
timeIcon = UIImage(systemName: "waveform")?
|
|
187
|
+
.withTintColor(.systemGreen, renderingMode: .alwaysOriginal)
|
|
173
188
|
} else {
|
|
174
189
|
timeText = "Duraklatıldı \(elapsed) / \(total)"
|
|
175
|
-
timeIcon = "pause.circle"
|
|
190
|
+
timeIcon = UIImage(systemName: "pause.circle")?
|
|
191
|
+
.withTintColor(.systemGray, renderingMode: .alwaysOriginal)
|
|
176
192
|
}
|
|
193
|
+
|
|
194
|
+
let progressPercent = currentDuration > 0
|
|
195
|
+
? Int((currentElapsedTime / currentDuration) * 100)
|
|
196
|
+
: 0
|
|
197
|
+
let timeDetailText: String? = currentDuration > 0 ? "%\(progressPercent) tamamlandı" : nil
|
|
198
|
+
|
|
177
199
|
let timeItem = CPListItem(
|
|
178
200
|
text: timeText,
|
|
179
|
-
detailText:
|
|
180
|
-
image:
|
|
201
|
+
detailText: timeDetailText,
|
|
202
|
+
image: timeIcon,
|
|
181
203
|
accessoryImage: nil,
|
|
182
204
|
accessoryType: .none
|
|
183
205
|
)
|
|
206
|
+
timeItem.isEnabled = false
|
|
184
207
|
let timeSection = CPListSection(
|
|
185
208
|
items: [timeItem],
|
|
186
209
|
header: nil,
|
|
187
210
|
sectionIndexTitle: nil
|
|
188
211
|
)
|
|
189
212
|
|
|
190
|
-
// Section 3: Kontroller
|
|
213
|
+
// Section 3: Kontroller — renkli ikonlar
|
|
191
214
|
let prevItem = CPListItem(
|
|
192
215
|
text: "Önceki Bölüm",
|
|
193
216
|
detailText: nil,
|
|
194
|
-
image: UIImage(systemName: "backward.end.fill")
|
|
217
|
+
image: UIImage(systemName: "backward.end.fill")?
|
|
218
|
+
.withTintColor(.systemBlue, renderingMode: .alwaysOriginal),
|
|
195
219
|
accessoryImage: nil,
|
|
196
220
|
accessoryType: .none
|
|
197
221
|
)
|
|
198
222
|
|
|
199
223
|
let playPauseText = config.isPlaying ? "Duraklat" : "Oynat"
|
|
200
|
-
let playPauseIcon = config.isPlaying
|
|
224
|
+
let playPauseIcon: UIImage? = config.isPlaying
|
|
225
|
+
? UIImage(systemName: "pause.circle.fill")?
|
|
226
|
+
.withTintColor(.systemOrange, renderingMode: .alwaysOriginal)
|
|
227
|
+
: UIImage(systemName: "play.circle.fill")?
|
|
228
|
+
.withTintColor(.systemGreen, renderingMode: .alwaysOriginal)
|
|
201
229
|
let playPauseItem = CPListItem(
|
|
202
230
|
text: playPauseText,
|
|
203
231
|
detailText: nil,
|
|
204
|
-
image:
|
|
232
|
+
image: playPauseIcon,
|
|
205
233
|
accessoryImage: nil,
|
|
206
234
|
accessoryType: .none
|
|
207
235
|
)
|
|
@@ -209,7 +237,8 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
209
237
|
let nextItem = CPListItem(
|
|
210
238
|
text: "Sonraki Bölüm",
|
|
211
239
|
detailText: nil,
|
|
212
|
-
image: UIImage(systemName: "forward.end.fill")
|
|
240
|
+
image: UIImage(systemName: "forward.end.fill")?
|
|
241
|
+
.withTintColor(.systemBlue, renderingMode: .alwaysOriginal),
|
|
213
242
|
accessoryImage: nil,
|
|
214
243
|
accessoryType: .none
|
|
215
244
|
)
|
|
@@ -232,6 +261,35 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
232
261
|
return String(format: "%d:%02d", mins, secs)
|
|
233
262
|
}
|
|
234
263
|
|
|
264
|
+
private func drawProgressBarImage(progress: Double) -> UIImage? {
|
|
265
|
+
let size = CPListItem.maximumImageSize
|
|
266
|
+
let renderer = UIGraphicsImageRenderer(size: size)
|
|
267
|
+
return renderer.image { _ in
|
|
268
|
+
let barHeight: CGFloat = 6
|
|
269
|
+
let barY = (size.height - barHeight) / 2
|
|
270
|
+
let cornerRadius = barHeight / 2
|
|
271
|
+
|
|
272
|
+
// Arka plan (gri track)
|
|
273
|
+
let trackPath = UIBezierPath(
|
|
274
|
+
roundedRect: CGRect(x: 2, y: barY, width: size.width - 4, height: barHeight),
|
|
275
|
+
cornerRadius: cornerRadius
|
|
276
|
+
)
|
|
277
|
+
UIColor.systemGray4.setFill()
|
|
278
|
+
trackPath.fill()
|
|
279
|
+
|
|
280
|
+
// Ilerleme (yesil fill)
|
|
281
|
+
let progressWidth = max(0, (size.width - 4) * CGFloat(min(progress, 1.0)))
|
|
282
|
+
if progressWidth > 0 {
|
|
283
|
+
let progressPath = UIBezierPath(
|
|
284
|
+
roundedRect: CGRect(x: 2, y: barY, width: progressWidth, height: barHeight),
|
|
285
|
+
cornerRadius: cornerRadius
|
|
286
|
+
)
|
|
287
|
+
UIColor.systemGreen.setFill()
|
|
288
|
+
progressPath.fill()
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
235
293
|
// MARK: - Native Audio Playback
|
|
236
294
|
|
|
237
295
|
@MainActor
|