@neoskola/auto-play 0.3.4 → 0.3.6

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.
@@ -33,7 +33,17 @@ class NowPlayingTemplate(context: CarContext, config: NowPlayingTemplateConfig)
33
33
  .build()
34
34
  )
35
35
 
36
- // Play/Pause button
36
+ // Onceki Bolum butonu
37
+ config.onPreviousTrack?.let { prevTrack ->
38
+ paneBuilder.addAction(
39
+ Action.Builder()
40
+ .setTitle(CarText.create("Önceki"))
41
+ .setOnClickListener { prevTrack() }
42
+ .build()
43
+ )
44
+ }
45
+
46
+ // Play/Pause butonu
37
47
  val playPauseTitle = if (config.isPlaying) "Duraklat" else "Oynat"
38
48
  paneBuilder.addAction(
39
49
  Action.Builder()
@@ -48,12 +58,12 @@ class NowPlayingTemplate(context: CarContext, config: NowPlayingTemplateConfig)
48
58
  .build()
49
59
  )
50
60
 
51
- // Skip backward button
52
- config.onSkipBackward?.let { skipBack ->
61
+ // Sonraki Bolum butonu
62
+ config.onNextTrack?.let { nextTrack ->
53
63
  paneBuilder.addAction(
54
64
  Action.Builder()
55
- .setTitle(CarText.create("30s Geri"))
56
- .setOnClickListener { skipBack() }
65
+ .setTitle(CarText.create("Sonraki"))
66
+ .setOnClickListener { nextTrack() }
57
67
  .build()
58
68
  )
59
69
  }
@@ -3,7 +3,7 @@ import MediaPlayer
3
3
  import AVFoundation
4
4
 
5
5
  class NowPlayingTemplate: AutoPlayTemplate {
6
- var template: CPNowPlayingTemplate
6
+ var template: CPListTemplate
7
7
  var config: NowPlayingTemplateConfig
8
8
  private var loadedImage: UIImage?
9
9
  private var isSetupComplete = false
@@ -34,19 +34,79 @@ class NowPlayingTemplate: AutoPlayTemplate {
34
34
  init(config: NowPlayingTemplateConfig) {
35
35
  self.config = config
36
36
 
37
- template = CPNowPlayingTemplate.shared
38
- initTemplate(template: template, id: config.id)
37
+ let titleText = Parser.parseText(text: config.title) ?? "Now Playing"
38
+ let subtitleText = config.subtitle.flatMap { Parser.parseText(text: $0) } ?? ""
39
+
40
+ // Section 1: Bilgi — ders ve kurs adi
41
+ let infoItem = CPListItem(
42
+ text: titleText,
43
+ detailText: subtitleText,
44
+ image: UIImage(systemName: "music.note"),
45
+ accessoryImage: nil,
46
+ accessoryType: .none
47
+ )
48
+ let infoSection = CPListSection(
49
+ items: [infoItem],
50
+ header: "Şimdi Oynatılıyor",
51
+ sectionIndexTitle: nil
52
+ )
53
+
54
+ // Section 2: Sure bilgisi
55
+ let timeItem = CPListItem(
56
+ text: "Yükleniyor...",
57
+ detailText: nil,
58
+ image: UIImage(systemName: "clock"),
59
+ accessoryImage: nil,
60
+ accessoryType: .none
61
+ )
62
+ let timeSection = CPListSection(
63
+ items: [timeItem],
64
+ header: nil,
65
+ sectionIndexTitle: nil
66
+ )
67
+
68
+ // Section 3: Kontroller — onceki, oynat/duraklat, sonraki
69
+ let prevItem = CPListItem(
70
+ text: "Önceki Bölüm",
71
+ detailText: nil,
72
+ image: UIImage(systemName: "backward.end.fill"),
73
+ accessoryImage: nil,
74
+ accessoryType: .none
75
+ )
76
+ let playPauseItem = CPListItem(
77
+ text: "Oynat",
78
+ detailText: nil,
79
+ image: UIImage(systemName: "play.circle.fill"),
80
+ accessoryImage: nil,
81
+ accessoryType: .none
82
+ )
83
+ let nextItem = CPListItem(
84
+ text: "Sonraki Bölüm",
85
+ detailText: nil,
86
+ image: UIImage(systemName: "forward.end.fill"),
87
+ accessoryImage: nil,
88
+ accessoryType: .none
89
+ )
90
+ let controlSection = CPListSection(
91
+ items: [prevItem, playPauseItem, nextItem],
92
+ header: nil,
93
+ sectionIndexTitle: nil
94
+ )
95
+
96
+ template = CPListTemplate(
97
+ title: "Now Playing",
98
+ sections: [infoSection, timeSection, controlSection],
99
+ assistantCellConfiguration: nil,
100
+ id: config.id
101
+ )
102
+
103
+ // Handler'lari ayarla
104
+ setupListItemHandlers(prevItem: prevItem, playPauseItem: playPauseItem, nextItem: nextItem)
39
105
 
40
- // Constructor runs on the JS thread. Dispatch all CarPlay UI setup to main thread.
41
- // CPNowPlayingTemplate.shared is Apple's singleton — must be modified on main thread.
42
106
  DispatchQueue.main.async { [weak self] in
43
107
  guard let self = self else { return }
44
-
45
- // Activate AVAudioSession FIRST — iOS needs this to recognize the app
46
- // as a media player before MPNowPlayingInfoCenter metadata is meaningful.
47
108
  NowPlayingSessionManager.shared.ensureSessionActive()
48
-
49
- self.setupNowPlayingButtons()
109
+ self.setupRemoteCommandCenter()
50
110
  self.updateNowPlayingInfo()
51
111
  self.isSetupComplete = true
52
112
 
@@ -56,6 +116,122 @@ class NowPlayingTemplate: AutoPlayTemplate {
56
116
  }
57
117
  }
58
118
 
119
+ // MARK: - List Item Handlers
120
+
121
+ private func setupListItemHandlers(prevItem: CPListItem, playPauseItem: CPListItem, nextItem: CPListItem) {
122
+ prevItem.handler = { [weak self] _, completion in
123
+ self?.config.onPreviousTrack?()
124
+ completion()
125
+ }
126
+
127
+ playPauseItem.handler = { [weak self] _, completion in
128
+ guard let self = self else { completion(); return }
129
+ if self.config.isPlaying {
130
+ self.pauseAudio()
131
+ self.config.onPause?()
132
+ } else {
133
+ self.resumeAudio()
134
+ self.config.onPlay?()
135
+ }
136
+ completion()
137
+ }
138
+
139
+ nextItem.handler = { [weak self] _, completion in
140
+ self?.config.onNextTrack?()
141
+ completion()
142
+ }
143
+ }
144
+
145
+ // MARK: - Player UI
146
+
147
+ private func updatePlayerUI() {
148
+ let titleText = Parser.parseText(text: config.title) ?? "Now Playing"
149
+ let subtitleText = config.subtitle.flatMap { Parser.parseText(text: $0) } ?? ""
150
+
151
+ // Section 1: Bilgi
152
+ let infoItem = CPListItem(
153
+ text: titleText,
154
+ detailText: subtitleText,
155
+ image: loadedImage ?? UIImage(systemName: "music.note"),
156
+ accessoryImage: nil,
157
+ accessoryType: .none
158
+ )
159
+ let infoSection = CPListSection(
160
+ items: [infoItem],
161
+ header: "Şimdi Oynatılıyor",
162
+ sectionIndexTitle: nil
163
+ )
164
+
165
+ // Section 2: Sure
166
+ let elapsed = formatTime(currentElapsedTime)
167
+ let total = currentDuration > 0 ? formatTime(currentDuration) : "--:--"
168
+ let timeText: String
169
+ let timeIcon: String
170
+ if config.isPlaying {
171
+ timeText = "\(elapsed) / \(total)"
172
+ timeIcon = "waveform"
173
+ } else {
174
+ timeText = "Duraklatıldı \(elapsed) / \(total)"
175
+ timeIcon = "pause.circle"
176
+ }
177
+ let timeItem = CPListItem(
178
+ text: timeText,
179
+ detailText: nil,
180
+ image: UIImage(systemName: timeIcon),
181
+ accessoryImage: nil,
182
+ accessoryType: .none
183
+ )
184
+ let timeSection = CPListSection(
185
+ items: [timeItem],
186
+ header: nil,
187
+ sectionIndexTitle: nil
188
+ )
189
+
190
+ // Section 3: Kontroller
191
+ let prevItem = CPListItem(
192
+ text: "Önceki Bölüm",
193
+ detailText: nil,
194
+ image: UIImage(systemName: "backward.end.fill"),
195
+ accessoryImage: nil,
196
+ accessoryType: .none
197
+ )
198
+
199
+ let playPauseText = config.isPlaying ? "Duraklat" : "Oynat"
200
+ let playPauseIcon = config.isPlaying ? "pause.circle.fill" : "play.circle.fill"
201
+ let playPauseItem = CPListItem(
202
+ text: playPauseText,
203
+ detailText: nil,
204
+ image: UIImage(systemName: playPauseIcon),
205
+ accessoryImage: nil,
206
+ accessoryType: .none
207
+ )
208
+
209
+ let nextItem = CPListItem(
210
+ text: "Sonraki Bölüm",
211
+ detailText: nil,
212
+ image: UIImage(systemName: "forward.end.fill"),
213
+ accessoryImage: nil,
214
+ accessoryType: .none
215
+ )
216
+
217
+ setupListItemHandlers(prevItem: prevItem, playPauseItem: playPauseItem, nextItem: nextItem)
218
+
219
+ let controlSection = CPListSection(
220
+ items: [prevItem, playPauseItem, nextItem],
221
+ header: nil,
222
+ sectionIndexTitle: nil
223
+ )
224
+
225
+ template.updateSections([infoSection, timeSection, controlSection])
226
+ }
227
+
228
+ private func formatTime(_ seconds: Double) -> String {
229
+ guard !seconds.isNaN && !seconds.isInfinite && seconds >= 0 else { return "0:00" }
230
+ let mins = Int(seconds) / 60
231
+ let secs = Int(seconds) % 60
232
+ return String(format: "%d:%02d", mins, secs)
233
+ }
234
+
59
235
  // MARK: - Native Audio Playback
60
236
 
61
237
  @MainActor
@@ -73,12 +249,11 @@ class NowPlayingTemplate: AutoPlayTemplate {
73
249
  NowPlayingSessionManager.shared.ensureSessionActive()
74
250
  config.isPlaying = true
75
251
  updateNowPlayingInfo()
252
+ updatePlayerUI()
76
253
  MPNowPlayingInfoCenter.default().playbackState = .playing
77
254
 
78
255
  print("[NowPlayingTemplate] Downloading audio: \(url)")
79
256
 
80
- // Download file first, then play from local — R2/Cloudflare CDN streaming
81
- // causes FigFilePlayer errors with AVPlayer, local playback is reliable
82
257
  downloadTask = URLSession.shared.downloadTask(with: audioURL) { [weak self] tempURL, response, error in
83
258
  guard let self = self else { return }
84
259
 
@@ -92,7 +267,6 @@ class NowPlayingTemplate: AutoPlayTemplate {
92
267
  return
93
268
  }
94
269
 
95
- // Move to a persistent temp location (URLSession deletes the file after this block)
96
270
  let localURL = FileManager.default.temporaryDirectory
97
271
  .appendingPathComponent("carplay_audio_\(UUID().uuidString).mp3")
98
272
 
@@ -121,7 +295,6 @@ class NowPlayingTemplate: AutoPlayTemplate {
121
295
  let asset = AVURLAsset(url: localURL)
122
296
  playerItem = AVPlayerItem(asset: asset)
123
297
 
124
- // KVO: detect duration as soon as asset loads (critical for progress bar)
125
298
  statusObservation = playerItem?.observe(\.status, options: [.new]) { [weak self] item, _ in
126
299
  guard item.status == .readyToPlay else {
127
300
  if item.status == .failed {
@@ -135,6 +308,7 @@ class NowPlayingTemplate: AutoPlayTemplate {
135
308
  if !duration.isNaN && !duration.isInfinite && duration > 0 {
136
309
  self.currentDuration = duration
137
310
  self.updateNowPlayingInfo()
311
+ self.updatePlayerUI()
138
312
  print("[NowPlayingTemplate] Duration resolved via KVO: \(duration)s")
139
313
  }
140
314
  }
@@ -147,7 +321,6 @@ class NowPlayingTemplate: AutoPlayTemplate {
147
321
  player?.seek(to: time)
148
322
  }
149
323
 
150
- // Periodic time observer (every 1 second) for MPNowPlayingInfoCenter updates
151
324
  let interval = CMTime(seconds: 1.0, preferredTimescale: 600)
152
325
  timeObserver = player?.addPeriodicTimeObserver(
153
326
  forInterval: interval,
@@ -156,7 +329,6 @@ class NowPlayingTemplate: AutoPlayTemplate {
156
329
  self?.handleTimeUpdate(time: time)
157
330
  }
158
331
 
159
- // Playback finished notification
160
332
  didFinishObserver = NotificationCenter.default.addObserver(
161
333
  forName: .AVPlayerItemDidPlayToEndTime,
162
334
  object: playerItem,
@@ -165,7 +337,6 @@ class NowPlayingTemplate: AutoPlayTemplate {
165
337
  self?.handlePlaybackFinished()
166
338
  }
167
339
 
168
- // Progress report timer (every 30 seconds) — calls JS callback for backend reporting
169
340
  progressReportTimer = Timer.scheduledTimer(
170
341
  withTimeInterval: 30.0,
171
342
  repeats: true
@@ -190,10 +361,8 @@ class NowPlayingTemplate: AutoPlayTemplate {
190
361
  currentDuration = duration
191
362
  }
192
363
 
193
- // Use existing info or create fresh if nil (race condition safety)
194
364
  var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo ?? [String: Any]()
195
365
 
196
- // Ensure title/artist are present if this is a fresh dictionary
197
366
  if nowPlayingInfo[MPMediaItemPropertyTitle] == nil {
198
367
  let titleText = Parser.parseText(text: config.title) ?? ""
199
368
  nowPlayingInfo[MPMediaItemPropertyTitle] = titleText
@@ -209,6 +378,9 @@ class NowPlayingTemplate: AutoPlayTemplate {
209
378
  nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = config.isPlaying ? 1.0 : 0.0
210
379
  MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
211
380
 
381
+ // Update custom player UI
382
+ updatePlayerUI()
383
+
212
384
  // 95% completion check
213
385
  if !completionFired && currentDuration > 0 && currentTime / currentDuration >= 0.95 {
214
386
  completionFired = true
@@ -226,7 +398,7 @@ class NowPlayingTemplate: AutoPlayTemplate {
226
398
  private func handlePlaybackFinished() {
227
399
  config.isPlaying = false
228
400
  MPNowPlayingInfoCenter.default().playbackState = .stopped
229
- // Fire completion if not already fired
401
+ updatePlayerUI()
230
402
  if !completionFired {
231
403
  completionFired = true
232
404
  config.onComplete?()
@@ -239,6 +411,7 @@ class NowPlayingTemplate: AutoPlayTemplate {
239
411
  player?.pause()
240
412
  config.isPlaying = false
241
413
  updatePlaybackState(isPlaying: false)
414
+ updatePlayerUI()
242
415
  reportProgress()
243
416
  }
244
417
 
@@ -248,6 +421,7 @@ class NowPlayingTemplate: AutoPlayTemplate {
248
421
  player?.play()
249
422
  config.isPlaying = true
250
423
  updatePlaybackState(isPlaying: true)
424
+ updatePlayerUI()
251
425
  }
252
426
 
253
427
  @MainActor
@@ -272,6 +446,7 @@ class NowPlayingTemplate: AutoPlayTemplate {
272
446
  cleanupPlayer()
273
447
  config.isPlaying = false
274
448
  MPNowPlayingInfoCenter.default().playbackState = .stopped
449
+ updatePlayerUI()
275
450
  }
276
451
 
277
452
  private func cleanupPlayer() {
@@ -298,29 +473,7 @@ class NowPlayingTemplate: AutoPlayTemplate {
298
473
  }
299
474
  }
300
475
 
301
- // MARK: - CarPlay UI
302
-
303
- private func setupNowPlayingButtons() {
304
- var buttons: [CPNowPlayingButton] = []
305
-
306
- let skipBackButton = CPNowPlayingImageButton(
307
- image: UIImage(systemName: "gobackward.30")!
308
- ) { [weak self] _ in
309
- self?.seekBackward(seconds: 30)
310
- self?.config.onSkipBackward?()
311
- }
312
- buttons.append(skipBackButton)
313
-
314
- let skipForwardButton = CPNowPlayingImageButton(
315
- image: UIImage(systemName: "goforward.30")!
316
- ) { [weak self] _ in
317
- self?.seekForward(seconds: 30)
318
- self?.config.onSkipForward?()
319
- }
320
- buttons.append(skipForwardButton)
321
-
322
- template.updateNowPlayingButtons(buttons)
323
- }
476
+ // MARK: - Now Playing Info & Remote Commands
324
477
 
325
478
  private func updateNowPlayingInfo() {
326
479
  let titleText = Parser.parseText(text: config.title) ?? ""
@@ -339,7 +492,6 @@ class NowPlayingTemplate: AutoPlayTemplate {
339
492
  nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork
340
493
  }
341
494
 
342
- // Include duration and elapsed time for the progress bar
343
495
  if currentDuration > 0 {
344
496
  nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = currentDuration
345
497
  nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = currentElapsedTime
@@ -347,8 +499,6 @@ class NowPlayingTemplate: AutoPlayTemplate {
347
499
  }
348
500
 
349
501
  MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
350
-
351
- setupRemoteCommandCenter()
352
502
  }
353
503
 
354
504
  private func setupRemoteCommandCenter() {
@@ -388,6 +538,22 @@ class NowPlayingTemplate: AutoPlayTemplate {
388
538
  return .success
389
539
  }
390
540
 
541
+ // Sonraki bolum
542
+ commandCenter.nextTrackCommand.isEnabled = true
543
+ commandCenter.nextTrackCommand.removeTarget(nil)
544
+ commandCenter.nextTrackCommand.addTarget { [weak self] _ in
545
+ self?.config.onNextTrack?()
546
+ return .success
547
+ }
548
+
549
+ // Onceki bolum
550
+ commandCenter.previousTrackCommand.isEnabled = true
551
+ commandCenter.previousTrackCommand.removeTarget(nil)
552
+ commandCenter.previousTrackCommand.addTarget { [weak self] _ in
553
+ self?.config.onPreviousTrack?()
554
+ return .success
555
+ }
556
+
391
557
  commandCenter.changePlaybackPositionCommand.isEnabled = true
392
558
  commandCenter.changePlaybackPositionCommand.removeTarget(nil)
393
559
  commandCenter.changePlaybackPositionCommand.addTarget { [weak self] event in
@@ -399,6 +565,7 @@ class NowPlayingTemplate: AutoPlayTemplate {
399
565
  self.player?.seek(to: time)
400
566
  self.currentElapsedTime = positionEvent.positionTime
401
567
  self.updateNowPlayingInfo()
568
+ self.updatePlayerUI()
402
569
  return .success
403
570
  }
404
571
  }
@@ -414,6 +581,7 @@ class NowPlayingTemplate: AutoPlayTemplate {
414
581
  DispatchQueue.main.async {
415
582
  self.loadedImage = uiImage
416
583
  self.updateNowPlayingInfo()
584
+ self.updatePlayerUI()
417
585
  }
418
586
  }.resume()
419
587
  }
@@ -423,7 +591,7 @@ class NowPlayingTemplate: AutoPlayTemplate {
423
591
 
424
592
  @MainActor
425
593
  func invalidate() {
426
- setupNowPlayingButtons()
594
+ updatePlayerUI()
427
595
  updateNowPlayingInfo()
428
596
 
429
597
  if loadedImage == nil, let image = config.image {
@@ -456,9 +624,10 @@ class NowPlayingTemplate: AutoPlayTemplate {
456
624
  commandCenter.pauseCommand.removeTarget(nil)
457
625
  commandCenter.skipForwardCommand.removeTarget(nil)
458
626
  commandCenter.skipBackwardCommand.removeTarget(nil)
627
+ commandCenter.nextTrackCommand.removeTarget(nil)
628
+ commandCenter.previousTrackCommand.removeTarget(nil)
459
629
  commandCenter.changePlaybackPositionCommand.removeTarget(nil)
460
630
 
461
- // Clear now playing info so CarPlay hides the Now Playing bar
462
631
  MPNowPlayingInfoCenter.default().nowPlayingInfo = nil
463
632
  MPNowPlayingInfoCenter.default().playbackState = .stopped
464
633
  }
@@ -466,19 +635,14 @@ class NowPlayingTemplate: AutoPlayTemplate {
466
635
  @MainActor
467
636
  func updatePlaybackState(isPlaying: Bool) {
468
637
  config.isPlaying = isPlaying
469
-
470
- // Ensure AVAudioSession is active — required for CarPlay Now Playing bar
471
638
  NowPlayingSessionManager.shared.ensureSessionActive()
472
639
 
473
- // If constructor's DispatchQueue.main.async hasn't run yet,
474
- // nowPlayingInfo could be nil. Set it up now to fix the race condition.
475
640
  if !isSetupComplete {
476
- setupNowPlayingButtons()
641
+ updatePlayerUI()
477
642
  updateNowPlayingInfo()
478
643
  isSetupComplete = true
479
644
  }
480
645
 
481
- // Update playback rate — use existing info or create fresh if nil
482
646
  var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo ?? [String: Any]()
483
647
 
484
648
  if nowPlayingInfo[MPMediaItemPropertyTitle] == nil {
@@ -501,6 +665,7 @@ class NowPlayingTemplate: AutoPlayTemplate {
501
665
  config.title = AutoText(text: title, distance: nil, duration: nil)
502
666
  config.subtitle = AutoText(text: subtitle, distance: nil, duration: nil)
503
667
  updateNowPlayingInfo()
668
+ updatePlayerUI()
504
669
  }
505
670
 
506
671
  @MainActor
@@ -508,7 +673,6 @@ class NowPlayingTemplate: AutoPlayTemplate {
508
673
  self.currentElapsedTime = elapsedTime
509
674
  self.currentDuration = duration
510
675
 
511
- // Update time-related fields — use existing info or create fresh if nil
512
676
  var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo ?? [String: Any]()
513
677
 
514
678
  if nowPlayingInfo[MPMediaItemPropertyTitle] == nil {
@@ -523,5 +687,7 @@ class NowPlayingTemplate: AutoPlayTemplate {
523
687
  nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = elapsedTime
524
688
  nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = config.isPlaying ? 1.0 : 0.0
525
689
  MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
690
+
691
+ updatePlayerUI()
526
692
  }
527
693
  }
@@ -13,6 +13,8 @@ export interface NitroNowPlayingTemplateConfig extends TemplateConfig {
13
13
  onPause?: () => void;
14
14
  onSkipForward?: () => void;
15
15
  onSkipBackward?: () => void;
16
+ onNextTrack?: () => void;
17
+ onPreviousTrack?: () => void;
16
18
  onComplete?: () => void;
17
19
  onProgressUpdate?: (currentTime: number, duration: number) => void;
18
20
  onPlaybackFinished?: () => void;
@@ -85,6 +85,10 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
85
85
  jni::local_ref<JFunc_void::javaobject> onSkipForward = this->getFieldValue(fieldOnSkipForward);
86
86
  static const auto fieldOnSkipBackward = clazz->getField<JFunc_void::javaobject>("onSkipBackward");
87
87
  jni::local_ref<JFunc_void::javaobject> onSkipBackward = this->getFieldValue(fieldOnSkipBackward);
88
+ static const auto fieldOnNextTrack = clazz->getField<JFunc_void::javaobject>("onNextTrack");
89
+ jni::local_ref<JFunc_void::javaobject> onNextTrack = this->getFieldValue(fieldOnNextTrack);
90
+ static const auto fieldOnPreviousTrack = clazz->getField<JFunc_void::javaobject>("onPreviousTrack");
91
+ jni::local_ref<JFunc_void::javaobject> onPreviousTrack = this->getFieldValue(fieldOnPreviousTrack);
88
92
  static const auto fieldOnComplete = clazz->getField<JFunc_void::javaobject>("onComplete");
89
93
  jni::local_ref<JFunc_void::javaobject> onComplete = this->getFieldValue(fieldOnComplete);
90
94
  static const auto fieldOnProgressUpdate = clazz->getField<JFunc_void_double_double::javaobject>("onProgressUpdate");
@@ -181,6 +185,24 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
181
185
  return JNICallable<JFunc_void, void()>(std::move(onSkipBackwardRef));
182
186
  }
183
187
  }()) : std::nullopt,
188
+ onNextTrack != nullptr ? std::make_optional([&]() -> std::function<void()> {
189
+ if (onNextTrack->isInstanceOf(JFunc_void_cxx::javaClassStatic())) [[likely]] {
190
+ auto downcast = jni::static_ref_cast<JFunc_void_cxx::javaobject>(onNextTrack);
191
+ return downcast->cthis()->getFunction();
192
+ } else {
193
+ auto onNextTrackRef = jni::make_global(onNextTrack);
194
+ return JNICallable<JFunc_void, void()>(std::move(onNextTrackRef));
195
+ }
196
+ }()) : std::nullopt,
197
+ onPreviousTrack != nullptr ? std::make_optional([&]() -> std::function<void()> {
198
+ if (onPreviousTrack->isInstanceOf(JFunc_void_cxx::javaClassStatic())) [[likely]] {
199
+ auto downcast = jni::static_ref_cast<JFunc_void_cxx::javaobject>(onPreviousTrack);
200
+ return downcast->cthis()->getFunction();
201
+ } else {
202
+ auto onPreviousTrackRef = jni::make_global(onPreviousTrack);
203
+ return JNICallable<JFunc_void, void()>(std::move(onPreviousTrackRef));
204
+ }
205
+ }()) : std::nullopt,
184
206
  onComplete != nullptr ? std::make_optional([&]() -> std::function<void()> {
185
207
  if (onComplete->isInstanceOf(JFunc_void_cxx::javaClassStatic())) [[likely]] {
186
208
  auto downcast = jni::static_ref_cast<JFunc_void_cxx::javaobject>(onComplete);
@@ -217,7 +239,7 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
217
239
  */
218
240
  [[maybe_unused]]
219
241
  static jni::local_ref<JNowPlayingTemplateConfig::javaobject> fromCpp(const NowPlayingTemplateConfig& value) {
220
- using JSignature = JNowPlayingTemplateConfig(jni::alias_ref<jni::JString>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<jni::JDouble>, jni::alias_ref<JAutoText>, jni::alias_ref<JAutoText>, jni::alias_ref<jni::JString>, jni::alias_ref<jni::JString>, jni::alias_ref<JVariant_GlyphImage_AssetImage>, jboolean, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<JFunc_void_double_double::javaobject>, jni::alias_ref<JFunc_void::javaobject>);
242
+ using JSignature = JNowPlayingTemplateConfig(jni::alias_ref<jni::JString>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<jni::JDouble>, jni::alias_ref<JAutoText>, jni::alias_ref<JAutoText>, jni::alias_ref<jni::JString>, jni::alias_ref<jni::JString>, jni::alias_ref<JVariant_GlyphImage_AssetImage>, jboolean, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<JFunc_void_double_double::javaobject>, jni::alias_ref<JFunc_void::javaobject>);
221
243
  static const auto clazz = javaClassStatic();
222
244
  static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
223
245
  return create(
@@ -239,6 +261,8 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
239
261
  value.onPause.has_value() ? JFunc_void_cxx::fromCpp(value.onPause.value()) : nullptr,
240
262
  value.onSkipForward.has_value() ? JFunc_void_cxx::fromCpp(value.onSkipForward.value()) : nullptr,
241
263
  value.onSkipBackward.has_value() ? JFunc_void_cxx::fromCpp(value.onSkipBackward.value()) : nullptr,
264
+ value.onNextTrack.has_value() ? JFunc_void_cxx::fromCpp(value.onNextTrack.value()) : nullptr,
265
+ value.onPreviousTrack.has_value() ? JFunc_void_cxx::fromCpp(value.onPreviousTrack.value()) : nullptr,
242
266
  value.onComplete.has_value() ? JFunc_void_cxx::fromCpp(value.onComplete.value()) : nullptr,
243
267
  value.onProgressUpdate.has_value() ? JFunc_void_double_double_cxx::fromCpp(value.onProgressUpdate.value()) : nullptr,
244
268
  value.onPlaybackFinished.has_value() ? JFunc_void_cxx::fromCpp(value.onPlaybackFinished.value()) : nullptr
@@ -70,6 +70,12 @@ data class NowPlayingTemplateConfig(
70
70
  val onSkipBackward: Func_void?,
71
71
  @DoNotStrip
72
72
  @Keep
73
+ val onNextTrack: Func_void?,
74
+ @DoNotStrip
75
+ @Keep
76
+ val onPreviousTrack: Func_void?,
77
+ @DoNotStrip
78
+ @Keep
73
79
  val onComplete: Func_void?,
74
80
  @DoNotStrip
75
81
  @Keep
@@ -81,8 +87,8 @@ data class NowPlayingTemplateConfig(
81
87
  /**
82
88
  * Create a new instance of NowPlayingTemplateConfig from Kotlin
83
89
  */
84
- constructor(id: String, onWillAppear: ((animated: Boolean?) -> Unit)?, onWillDisappear: ((animated: Boolean?) -> Unit)?, onDidAppear: ((animated: Boolean?) -> Unit)?, onDidDisappear: ((animated: Boolean?) -> Unit)?, onPopped: (() -> Unit)?, autoDismissMs: Double?, title: AutoText, subtitle: AutoText?, courseId: String, lessonId: String, image: Variant_GlyphImage_AssetImage?, isPlaying: Boolean, onPlay: (() -> Unit)?, onPause: (() -> Unit)?, onSkipForward: (() -> Unit)?, onSkipBackward: (() -> Unit)?, onComplete: (() -> Unit)?, onProgressUpdate: ((currentTime: Double, duration: Double) -> Unit)?, onPlaybackFinished: (() -> Unit)?):
85
- this(id, onWillAppear?.let { Func_void_std__optional_bool__java(it) }, onWillDisappear?.let { Func_void_std__optional_bool__java(it) }, onDidAppear?.let { Func_void_std__optional_bool__java(it) }, onDidDisappear?.let { Func_void_std__optional_bool__java(it) }, onPopped?.let { Func_void_java(it) }, autoDismissMs, title, subtitle, courseId, lessonId, image, isPlaying, onPlay?.let { Func_void_java(it) }, onPause?.let { Func_void_java(it) }, onSkipForward?.let { Func_void_java(it) }, onSkipBackward?.let { Func_void_java(it) }, onComplete?.let { Func_void_java(it) }, onProgressUpdate?.let { Func_void_double_double_java(it) }, onPlaybackFinished?.let { Func_void_java(it) })
90
+ constructor(id: String, onWillAppear: ((animated: Boolean?) -> Unit)?, onWillDisappear: ((animated: Boolean?) -> Unit)?, onDidAppear: ((animated: Boolean?) -> Unit)?, onDidDisappear: ((animated: Boolean?) -> Unit)?, onPopped: (() -> Unit)?, autoDismissMs: Double?, title: AutoText, subtitle: AutoText?, courseId: String, lessonId: String, image: Variant_GlyphImage_AssetImage?, isPlaying: Boolean, onPlay: (() -> Unit)?, onPause: (() -> Unit)?, onSkipForward: (() -> Unit)?, onSkipBackward: (() -> Unit)?, onNextTrack: (() -> Unit)?, onPreviousTrack: (() -> Unit)?, onComplete: (() -> Unit)?, onProgressUpdate: ((currentTime: Double, duration: Double) -> Unit)?, onPlaybackFinished: (() -> Unit)?):
91
+ this(id, onWillAppear?.let { Func_void_std__optional_bool__java(it) }, onWillDisappear?.let { Func_void_std__optional_bool__java(it) }, onDidAppear?.let { Func_void_std__optional_bool__java(it) }, onDidDisappear?.let { Func_void_std__optional_bool__java(it) }, onPopped?.let { Func_void_java(it) }, autoDismissMs, title, subtitle, courseId, lessonId, image, isPlaying, onPlay?.let { Func_void_java(it) }, onPause?.let { Func_void_java(it) }, onSkipForward?.let { Func_void_java(it) }, onSkipBackward?.let { Func_void_java(it) }, onNextTrack?.let { Func_void_java(it) }, onPreviousTrack?.let { Func_void_java(it) }, onComplete?.let { Func_void_java(it) }, onProgressUpdate?.let { Func_void_double_double_java(it) }, onPlaybackFinished?.let { Func_void_java(it) })
86
92
 
87
93
  private companion object {
88
94
  /**
@@ -92,8 +98,8 @@ data class NowPlayingTemplateConfig(
92
98
  @Keep
93
99
  @Suppress("unused")
94
100
  @JvmStatic
95
- private fun fromCpp(id: String, onWillAppear: Func_void_std__optional_bool_?, onWillDisappear: Func_void_std__optional_bool_?, onDidAppear: Func_void_std__optional_bool_?, onDidDisappear: Func_void_std__optional_bool_?, onPopped: Func_void?, autoDismissMs: Double?, title: AutoText, subtitle: AutoText?, courseId: String, lessonId: String, image: Variant_GlyphImage_AssetImage?, isPlaying: Boolean, onPlay: Func_void?, onPause: Func_void?, onSkipForward: Func_void?, onSkipBackward: Func_void?, onComplete: Func_void?, onProgressUpdate: Func_void_double_double?, onPlaybackFinished: Func_void?): NowPlayingTemplateConfig {
96
- return NowPlayingTemplateConfig(id, onWillAppear, onWillDisappear, onDidAppear, onDidDisappear, onPopped, autoDismissMs, title, subtitle, courseId, lessonId, image, isPlaying, onPlay, onPause, onSkipForward, onSkipBackward, onComplete, onProgressUpdate, onPlaybackFinished)
101
+ private fun fromCpp(id: String, onWillAppear: Func_void_std__optional_bool_?, onWillDisappear: Func_void_std__optional_bool_?, onDidAppear: Func_void_std__optional_bool_?, onDidDisappear: Func_void_std__optional_bool_?, onPopped: Func_void?, autoDismissMs: Double?, title: AutoText, subtitle: AutoText?, courseId: String, lessonId: String, image: Variant_GlyphImage_AssetImage?, isPlaying: Boolean, onPlay: Func_void?, onPause: Func_void?, onSkipForward: Func_void?, onSkipBackward: Func_void?, onNextTrack: Func_void?, onPreviousTrack: Func_void?, onComplete: Func_void?, onProgressUpdate: Func_void_double_double?, onPlaybackFinished: Func_void?): NowPlayingTemplateConfig {
102
+ return NowPlayingTemplateConfig(id, onWillAppear, onWillDisappear, onDidAppear, onDidDisappear, onPopped, autoDismissMs, title, subtitle, courseId, lessonId, image, isPlaying, onPlay, onPause, onSkipForward, onSkipBackward, onNextTrack, onPreviousTrack, onComplete, onProgressUpdate, onPlaybackFinished)
97
103
  }
98
104
  }
99
105
  }
@@ -19,7 +19,7 @@ public extension NowPlayingTemplateConfig {
19
19
  /**
20
20
  * Create a new instance of `NowPlayingTemplateConfig`.
21
21
  */
22
- init(id: String, onWillAppear: ((_ animated: Bool?) -> Void)?, onWillDisappear: ((_ animated: Bool?) -> Void)?, onDidAppear: ((_ animated: Bool?) -> Void)?, onDidDisappear: ((_ animated: Bool?) -> Void)?, onPopped: (() -> Void)?, autoDismissMs: Double?, title: AutoText, subtitle: AutoText?, courseId: String, lessonId: String, image: Variant_GlyphImage_AssetImage?, isPlaying: Bool, onPlay: (() -> Void)?, onPause: (() -> Void)?, onSkipForward: (() -> Void)?, onSkipBackward: (() -> Void)?, onComplete: (() -> Void)?, onProgressUpdate: ((_ currentTime: Double, _ duration: Double) -> Void)?, onPlaybackFinished: (() -> Void)?) {
22
+ init(id: String, onWillAppear: ((_ animated: Bool?) -> Void)?, onWillDisappear: ((_ animated: Bool?) -> Void)?, onDidAppear: ((_ animated: Bool?) -> Void)?, onDidDisappear: ((_ animated: Bool?) -> Void)?, onPopped: (() -> Void)?, autoDismissMs: Double?, title: AutoText, subtitle: AutoText?, courseId: String, lessonId: String, image: Variant_GlyphImage_AssetImage?, isPlaying: Bool, onPlay: (() -> Void)?, onPause: (() -> Void)?, onSkipForward: (() -> Void)?, onSkipBackward: (() -> Void)?, onNextTrack: (() -> Void)?, onPreviousTrack: (() -> Void)?, onComplete: (() -> Void)?, onProgressUpdate: ((_ currentTime: Double, _ duration: Double) -> Void)?, onPlaybackFinished: (() -> Void)?) {
23
23
  self.init(std.string(id), { () -> bridge.std__optional_std__function_void_std__optional_bool_____animated______ in
24
24
  if let __unwrappedValue = onWillAppear {
25
25
  return bridge.create_std__optional_std__function_void_std__optional_bool_____animated______({ () -> bridge.Func_void_std__optional_bool_ in
@@ -126,6 +126,24 @@ public extension NowPlayingTemplateConfig {
126
126
  } else {
127
127
  return .init()
128
128
  }
129
+ }(), { () -> bridge.std__optional_std__function_void____ in
130
+ if let __unwrappedValue = onNextTrack {
131
+ return bridge.create_std__optional_std__function_void____({ () -> bridge.Func_void in
132
+ let __closureWrapper = Func_void(__unwrappedValue)
133
+ return bridge.create_Func_void(__closureWrapper.toUnsafe())
134
+ }())
135
+ } else {
136
+ return .init()
137
+ }
138
+ }(), { () -> bridge.std__optional_std__function_void____ in
139
+ if let __unwrappedValue = onPreviousTrack {
140
+ return bridge.create_std__optional_std__function_void____({ () -> bridge.Func_void in
141
+ let __closureWrapper = Func_void(__unwrappedValue)
142
+ return bridge.create_Func_void(__closureWrapper.toUnsafe())
143
+ }())
144
+ } else {
145
+ return .init()
146
+ }
129
147
  }(), { () -> bridge.std__optional_std__function_void____ in
130
148
  if let __unwrappedValue = onComplete {
131
149
  return bridge.create_std__optional_std__function_void____({ () -> bridge.Func_void in
@@ -600,6 +618,70 @@ public extension NowPlayingTemplateConfig {
600
618
  }
601
619
  }
602
620
 
621
+ var onNextTrack: (() -> Void)? {
622
+ @inline(__always)
623
+ get {
624
+ return { () -> (() -> Void)? in
625
+ if bridge.has_value_std__optional_std__function_void____(self.__onNextTrack) {
626
+ let __unwrapped = bridge.get_std__optional_std__function_void____(self.__onNextTrack)
627
+ return { () -> () -> Void in
628
+ let __wrappedFunction = bridge.wrap_Func_void(__unwrapped)
629
+ return { () -> Void in
630
+ __wrappedFunction.call()
631
+ }
632
+ }()
633
+ } else {
634
+ return nil
635
+ }
636
+ }()
637
+ }
638
+ @inline(__always)
639
+ set {
640
+ self.__onNextTrack = { () -> bridge.std__optional_std__function_void____ in
641
+ if let __unwrappedValue = newValue {
642
+ return bridge.create_std__optional_std__function_void____({ () -> bridge.Func_void in
643
+ let __closureWrapper = Func_void(__unwrappedValue)
644
+ return bridge.create_Func_void(__closureWrapper.toUnsafe())
645
+ }())
646
+ } else {
647
+ return .init()
648
+ }
649
+ }()
650
+ }
651
+ }
652
+
653
+ var onPreviousTrack: (() -> Void)? {
654
+ @inline(__always)
655
+ get {
656
+ return { () -> (() -> Void)? in
657
+ if bridge.has_value_std__optional_std__function_void____(self.__onPreviousTrack) {
658
+ let __unwrapped = bridge.get_std__optional_std__function_void____(self.__onPreviousTrack)
659
+ return { () -> () -> Void in
660
+ let __wrappedFunction = bridge.wrap_Func_void(__unwrapped)
661
+ return { () -> Void in
662
+ __wrappedFunction.call()
663
+ }
664
+ }()
665
+ } else {
666
+ return nil
667
+ }
668
+ }()
669
+ }
670
+ @inline(__always)
671
+ set {
672
+ self.__onPreviousTrack = { () -> bridge.std__optional_std__function_void____ in
673
+ if let __unwrappedValue = newValue {
674
+ return bridge.create_std__optional_std__function_void____({ () -> bridge.Func_void in
675
+ let __closureWrapper = Func_void(__unwrappedValue)
676
+ return bridge.create_Func_void(__closureWrapper.toUnsafe())
677
+ }())
678
+ } else {
679
+ return .init()
680
+ }
681
+ }()
682
+ }
683
+ }
684
+
603
685
  var onComplete: (() -> Void)? {
604
686
  @inline(__always)
605
687
  get {
@@ -62,13 +62,15 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
62
62
  std::optional<std::function<void()>> onPause SWIFT_PRIVATE;
63
63
  std::optional<std::function<void()>> onSkipForward SWIFT_PRIVATE;
64
64
  std::optional<std::function<void()>> onSkipBackward SWIFT_PRIVATE;
65
+ std::optional<std::function<void()>> onNextTrack SWIFT_PRIVATE;
66
+ std::optional<std::function<void()>> onPreviousTrack SWIFT_PRIVATE;
65
67
  std::optional<std::function<void()>> onComplete SWIFT_PRIVATE;
66
68
  std::optional<std::function<void(double /* currentTime */, double /* duration */)>> onProgressUpdate SWIFT_PRIVATE;
67
69
  std::optional<std::function<void()>> onPlaybackFinished SWIFT_PRIVATE;
68
70
 
69
71
  public:
70
72
  NowPlayingTemplateConfig() = default;
71
- explicit NowPlayingTemplateConfig(std::string id, std::optional<std::function<void(std::optional<bool> /* animated */)>> onWillAppear, std::optional<std::function<void(std::optional<bool> /* animated */)>> onWillDisappear, std::optional<std::function<void(std::optional<bool> /* animated */)>> onDidAppear, std::optional<std::function<void(std::optional<bool> /* animated */)>> onDidDisappear, std::optional<std::function<void()>> onPopped, std::optional<double> autoDismissMs, AutoText title, std::optional<AutoText> subtitle, std::string courseId, std::string lessonId, std::optional<std::variant<GlyphImage, AssetImage>> image, bool isPlaying, std::optional<std::function<void()>> onPlay, std::optional<std::function<void()>> onPause, std::optional<std::function<void()>> onSkipForward, std::optional<std::function<void()>> onSkipBackward, std::optional<std::function<void()>> onComplete, std::optional<std::function<void(double /* currentTime */, double /* duration */)>> onProgressUpdate, std::optional<std::function<void()>> onPlaybackFinished): id(id), onWillAppear(onWillAppear), onWillDisappear(onWillDisappear), onDidAppear(onDidAppear), onDidDisappear(onDidDisappear), onPopped(onPopped), autoDismissMs(autoDismissMs), title(title), subtitle(subtitle), courseId(courseId), lessonId(lessonId), image(image), isPlaying(isPlaying), onPlay(onPlay), onPause(onPause), onSkipForward(onSkipForward), onSkipBackward(onSkipBackward), onComplete(onComplete), onProgressUpdate(onProgressUpdate), onPlaybackFinished(onPlaybackFinished) {}
73
+ explicit NowPlayingTemplateConfig(std::string id, std::optional<std::function<void(std::optional<bool> /* animated */)>> onWillAppear, std::optional<std::function<void(std::optional<bool> /* animated */)>> onWillDisappear, std::optional<std::function<void(std::optional<bool> /* animated */)>> onDidAppear, std::optional<std::function<void(std::optional<bool> /* animated */)>> onDidDisappear, std::optional<std::function<void()>> onPopped, std::optional<double> autoDismissMs, AutoText title, std::optional<AutoText> subtitle, std::string courseId, std::string lessonId, std::optional<std::variant<GlyphImage, AssetImage>> image, bool isPlaying, std::optional<std::function<void()>> onPlay, std::optional<std::function<void()>> onPause, std::optional<std::function<void()>> onSkipForward, std::optional<std::function<void()>> onSkipBackward, std::optional<std::function<void()>> onNextTrack, std::optional<std::function<void()>> onPreviousTrack, std::optional<std::function<void()>> onComplete, std::optional<std::function<void(double /* currentTime */, double /* duration */)>> onProgressUpdate, std::optional<std::function<void()>> onPlaybackFinished): id(id), onWillAppear(onWillAppear), onWillDisappear(onWillDisappear), onDidAppear(onDidAppear), onDidDisappear(onDidDisappear), onPopped(onPopped), autoDismissMs(autoDismissMs), title(title), subtitle(subtitle), courseId(courseId), lessonId(lessonId), image(image), isPlaying(isPlaying), onPlay(onPlay), onPause(onPause), onSkipForward(onSkipForward), onSkipBackward(onSkipBackward), onNextTrack(onNextTrack), onPreviousTrack(onPreviousTrack), onComplete(onComplete), onProgressUpdate(onProgressUpdate), onPlaybackFinished(onPlaybackFinished) {}
72
74
  };
73
75
 
74
76
  } // namespace margelo::nitro::swe::iternio::reactnativeautoplay
@@ -98,6 +100,8 @@ namespace margelo::nitro {
98
100
  JSIConverter<std::optional<std::function<void()>>>::fromJSI(runtime, obj.getProperty(runtime, "onPause")),
99
101
  JSIConverter<std::optional<std::function<void()>>>::fromJSI(runtime, obj.getProperty(runtime, "onSkipForward")),
100
102
  JSIConverter<std::optional<std::function<void()>>>::fromJSI(runtime, obj.getProperty(runtime, "onSkipBackward")),
103
+ JSIConverter<std::optional<std::function<void()>>>::fromJSI(runtime, obj.getProperty(runtime, "onNextTrack")),
104
+ JSIConverter<std::optional<std::function<void()>>>::fromJSI(runtime, obj.getProperty(runtime, "onPreviousTrack")),
101
105
  JSIConverter<std::optional<std::function<void()>>>::fromJSI(runtime, obj.getProperty(runtime, "onComplete")),
102
106
  JSIConverter<std::optional<std::function<void(double, double)>>>::fromJSI(runtime, obj.getProperty(runtime, "onProgressUpdate")),
103
107
  JSIConverter<std::optional<std::function<void()>>>::fromJSI(runtime, obj.getProperty(runtime, "onPlaybackFinished"))
@@ -122,6 +126,8 @@ namespace margelo::nitro {
122
126
  obj.setProperty(runtime, "onPause", JSIConverter<std::optional<std::function<void()>>>::toJSI(runtime, arg.onPause));
123
127
  obj.setProperty(runtime, "onSkipForward", JSIConverter<std::optional<std::function<void()>>>::toJSI(runtime, arg.onSkipForward));
124
128
  obj.setProperty(runtime, "onSkipBackward", JSIConverter<std::optional<std::function<void()>>>::toJSI(runtime, arg.onSkipBackward));
129
+ obj.setProperty(runtime, "onNextTrack", JSIConverter<std::optional<std::function<void()>>>::toJSI(runtime, arg.onNextTrack));
130
+ obj.setProperty(runtime, "onPreviousTrack", JSIConverter<std::optional<std::function<void()>>>::toJSI(runtime, arg.onPreviousTrack));
125
131
  obj.setProperty(runtime, "onComplete", JSIConverter<std::optional<std::function<void()>>>::toJSI(runtime, arg.onComplete));
126
132
  obj.setProperty(runtime, "onProgressUpdate", JSIConverter<std::optional<std::function<void(double, double)>>>::toJSI(runtime, arg.onProgressUpdate));
127
133
  obj.setProperty(runtime, "onPlaybackFinished", JSIConverter<std::optional<std::function<void()>>>::toJSI(runtime, arg.onPlaybackFinished));
@@ -152,6 +158,8 @@ namespace margelo::nitro {
152
158
  if (!JSIConverter<std::optional<std::function<void()>>>::canConvert(runtime, obj.getProperty(runtime, "onPause"))) return false;
153
159
  if (!JSIConverter<std::optional<std::function<void()>>>::canConvert(runtime, obj.getProperty(runtime, "onSkipForward"))) return false;
154
160
  if (!JSIConverter<std::optional<std::function<void()>>>::canConvert(runtime, obj.getProperty(runtime, "onSkipBackward"))) return false;
161
+ if (!JSIConverter<std::optional<std::function<void()>>>::canConvert(runtime, obj.getProperty(runtime, "onNextTrack"))) return false;
162
+ if (!JSIConverter<std::optional<std::function<void()>>>::canConvert(runtime, obj.getProperty(runtime, "onPreviousTrack"))) return false;
155
163
  if (!JSIConverter<std::optional<std::function<void()>>>::canConvert(runtime, obj.getProperty(runtime, "onComplete"))) return false;
156
164
  if (!JSIConverter<std::optional<std::function<void(double, double)>>>::canConvert(runtime, obj.getProperty(runtime, "onProgressUpdate"))) return false;
157
165
  if (!JSIConverter<std::optional<std::function<void()>>>::canConvert(runtime, obj.getProperty(runtime, "onPlaybackFinished"))) return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neoskola/auto-play",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "Android Auto and Apple CarPlay for react-native",
5
5
  "main": "lib/index",
6
6
  "module": "lib/index",
@@ -24,6 +24,8 @@ export interface NitroNowPlayingTemplateConfig extends TemplateConfig {
24
24
  onPause?: () => void;
25
25
  onSkipForward?: () => void;
26
26
  onSkipBackward?: () => void;
27
+ onNextTrack?: () => void;
28
+ onPreviousTrack?: () => void;
27
29
  onComplete?: () => void;
28
30
  onProgressUpdate?: (currentTime: number, duration: number) => void;
29
31
  onPlaybackFinished?: () => void;