@neoskola/auto-play 0.2.9 → 0.2.10
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.
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridNowPlayingTemplate.kt +10 -0
- package/ios/hybrid/HybridNowPlayingTemplate.swift +17 -0
- package/ios/templates/NowPlayingTemplate.swift +67 -2
- package/ios/utils/NowPlayingSessionManager.swift +49 -0
- package/lib/specs/NowPlayingTemplate.nitro.d.ts +1 -0
- package/lib/templates/NowPlayingTemplate.d.ts +1 -0
- package/lib/templates/NowPlayingTemplate.js +3 -0
- package/nitrogen/generated/android/c++/JHybridNowPlayingTemplateSpec.cpp +15 -0
- package/nitrogen/generated/android/c++/JHybridNowPlayingTemplateSpec.hpp +1 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridNowPlayingTemplateSpec.kt +4 -0
- package/nitrogen/generated/ios/c++/HybridNowPlayingTemplateSpecSwift.hpp +8 -0
- package/nitrogen/generated/ios/swift/HybridNowPlayingTemplateSpec.swift +1 -0
- package/nitrogen/generated/ios/swift/HybridNowPlayingTemplateSpec_cxx.swift +19 -0
- package/nitrogen/generated/shared/c++/HybridNowPlayingTemplateSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridNowPlayingTemplateSpec.hpp +1 -0
- package/package.json +1 -1
- package/src/specs/NowPlayingTemplate.nitro.ts +1 -0
- package/src/templates/NowPlayingTemplate.ts +4 -0
|
@@ -33,4 +33,14 @@ class HybridNowPlayingTemplate : HybridNowPlayingTemplateSpec() {
|
|
|
33
33
|
template.updateInfo(title, subtitle)
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
+
|
|
37
|
+
override fun updateNowPlayingTemplateElapsedTime(
|
|
38
|
+
templateId: String,
|
|
39
|
+
elapsedTime: Double,
|
|
40
|
+
duration: Double
|
|
41
|
+
): Promise<Unit> {
|
|
42
|
+
return Promise.async {
|
|
43
|
+
// Android Auto manages its own playback UI
|
|
44
|
+
}
|
|
45
|
+
}
|
|
36
46
|
}
|
|
@@ -41,4 +41,21 @@ class HybridNowPlayingTemplate: HybridNowPlayingTemplateSpec {
|
|
|
41
41
|
await template.updateInfo(title: title, subtitle: subtitle)
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
func updateNowPlayingTemplateElapsedTime(
|
|
46
|
+
templateId: String,
|
|
47
|
+
elapsedTime: Double,
|
|
48
|
+
duration: Double
|
|
49
|
+
) throws -> Promise<Void> {
|
|
50
|
+
return Promise.async {
|
|
51
|
+
guard
|
|
52
|
+
let template = TemplateStore.getTemplate(templateId: templateId)
|
|
53
|
+
as? NowPlayingTemplate
|
|
54
|
+
else {
|
|
55
|
+
throw AutoPlayError.templateNotFound(templateId)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
await template.updateElapsedTime(elapsedTime: elapsedTime, duration: duration)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
44
61
|
}
|
|
@@ -5,6 +5,9 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
5
5
|
var template: CPNowPlayingTemplate
|
|
6
6
|
var config: NowPlayingTemplateConfig
|
|
7
7
|
private var loadedImage: UIImage?
|
|
8
|
+
private var isSetupComplete = false
|
|
9
|
+
private var currentElapsedTime: Double = 0
|
|
10
|
+
private var currentDuration: Double = 0
|
|
8
11
|
|
|
9
12
|
var autoDismissMs: Double? {
|
|
10
13
|
return config.autoDismissMs
|
|
@@ -22,12 +25,17 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
22
25
|
|
|
23
26
|
// Constructor runs on the JS thread. Dispatch all CarPlay UI setup to main thread.
|
|
24
27
|
// CPNowPlayingTemplate.shared is Apple's singleton — must be modified on main thread.
|
|
25
|
-
// This also ensures MPNowPlayingInfoCenter and MPRemoteCommandCenter are configured
|
|
26
|
-
// even if push() is never called (CarPlay shows "Now Playing" bar automatically).
|
|
27
28
|
DispatchQueue.main.async { [weak self] in
|
|
28
29
|
guard let self = self else { return }
|
|
30
|
+
|
|
31
|
+
// Activate AVAudioSession FIRST — iOS needs this to recognize the app
|
|
32
|
+
// as a media player before MPNowPlayingInfoCenter metadata is meaningful.
|
|
33
|
+
NowPlayingSessionManager.shared.ensureSessionActive()
|
|
34
|
+
|
|
29
35
|
self.setupNowPlayingButtons()
|
|
30
36
|
self.updateNowPlayingInfo()
|
|
37
|
+
self.isSetupComplete = true
|
|
38
|
+
|
|
31
39
|
if let image = config.image {
|
|
32
40
|
self.loadImageAsync(image: image)
|
|
33
41
|
}
|
|
@@ -71,6 +79,13 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
71
79
|
nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork
|
|
72
80
|
}
|
|
73
81
|
|
|
82
|
+
// Include duration and elapsed time for the progress bar
|
|
83
|
+
if currentDuration > 0 {
|
|
84
|
+
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = currentDuration
|
|
85
|
+
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = currentElapsedTime
|
|
86
|
+
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = config.isPlaying ? 1.0 : 0.0
|
|
87
|
+
}
|
|
88
|
+
|
|
74
89
|
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
|
|
75
90
|
|
|
76
91
|
setupRemoteCommandCenter()
|
|
@@ -108,6 +123,18 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
108
123
|
self?.config.onSkipBackward?()
|
|
109
124
|
return .success
|
|
110
125
|
}
|
|
126
|
+
|
|
127
|
+
commandCenter.changePlaybackPositionCommand.isEnabled = true
|
|
128
|
+
commandCenter.changePlaybackPositionCommand.removeTarget(nil)
|
|
129
|
+
commandCenter.changePlaybackPositionCommand.addTarget { [weak self] event in
|
|
130
|
+
guard let self = self,
|
|
131
|
+
let positionEvent = event as? MPChangePlaybackPositionCommandEvent else {
|
|
132
|
+
return .commandFailed
|
|
133
|
+
}
|
|
134
|
+
self.currentElapsedTime = positionEvent.positionTime
|
|
135
|
+
self.updateNowPlayingInfo()
|
|
136
|
+
return .success
|
|
137
|
+
}
|
|
111
138
|
}
|
|
112
139
|
|
|
113
140
|
private func loadImageAsync(image: Variant_GlyphImage_AssetImage) {
|
|
@@ -158,11 +185,35 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
158
185
|
commandCenter.pauseCommand.removeTarget(nil)
|
|
159
186
|
commandCenter.skipForwardCommand.removeTarget(nil)
|
|
160
187
|
commandCenter.skipBackwardCommand.removeTarget(nil)
|
|
188
|
+
commandCenter.changePlaybackPositionCommand.removeTarget(nil)
|
|
189
|
+
|
|
190
|
+
// Clear now playing info so CarPlay hides the Now Playing bar
|
|
191
|
+
MPNowPlayingInfoCenter.default().nowPlayingInfo = nil
|
|
192
|
+
MPNowPlayingInfoCenter.default().playbackState = .stopped
|
|
161
193
|
}
|
|
162
194
|
|
|
163
195
|
@MainActor
|
|
164
196
|
func updatePlaybackState(isPlaying: Bool) {
|
|
165
197
|
config.isPlaying = isPlaying
|
|
198
|
+
|
|
199
|
+
// Ensure AVAudioSession is active — required for CarPlay Now Playing bar
|
|
200
|
+
NowPlayingSessionManager.shared.ensureSessionActive()
|
|
201
|
+
|
|
202
|
+
// If constructor's DispatchQueue.main.async hasn't run yet,
|
|
203
|
+
// nowPlayingInfo could be nil. Set it up now to fix the race condition.
|
|
204
|
+
if !isSetupComplete {
|
|
205
|
+
setupNowPlayingButtons()
|
|
206
|
+
updateNowPlayingInfo()
|
|
207
|
+
isSetupComplete = true
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Update playback rate in existing nowPlayingInfo
|
|
211
|
+
if var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo {
|
|
212
|
+
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = isPlaying ? 1.0 : 0.0
|
|
213
|
+
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = currentElapsedTime
|
|
214
|
+
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
|
|
215
|
+
}
|
|
216
|
+
|
|
166
217
|
MPNowPlayingInfoCenter.default().playbackState = isPlaying ? .playing : .paused
|
|
167
218
|
}
|
|
168
219
|
|
|
@@ -172,4 +223,18 @@ class NowPlayingTemplate: AutoPlayTemplate {
|
|
|
172
223
|
config.subtitle = AutoText(text: subtitle, distance: nil, duration: nil)
|
|
173
224
|
updateNowPlayingInfo()
|
|
174
225
|
}
|
|
226
|
+
|
|
227
|
+
@MainActor
|
|
228
|
+
func updateElapsedTime(elapsedTime: Double, duration: Double) {
|
|
229
|
+
self.currentElapsedTime = elapsedTime
|
|
230
|
+
self.currentDuration = duration
|
|
231
|
+
|
|
232
|
+
// Update only time-related fields without rebuilding everything
|
|
233
|
+
if var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo {
|
|
234
|
+
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = duration
|
|
235
|
+
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = elapsedTime
|
|
236
|
+
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = config.isPlaying ? 1.0 : 0.0
|
|
237
|
+
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
|
|
238
|
+
}
|
|
239
|
+
}
|
|
175
240
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import AVFoundation
|
|
2
|
+
|
|
3
|
+
/// Manages AVAudioSession activation for CarPlay Now Playing integration.
|
|
4
|
+
/// iOS requires an explicit AVAudioSession.setCategory(.playback) + setActive(true)
|
|
5
|
+
/// for MPNowPlayingInfoCenter to be recognized by the system and the Now Playing
|
|
6
|
+
/// bar to appear in CarPlay.
|
|
7
|
+
class NowPlayingSessionManager {
|
|
8
|
+
static let shared = NowPlayingSessionManager()
|
|
9
|
+
|
|
10
|
+
private var isSessionActivated = false
|
|
11
|
+
|
|
12
|
+
private init() {}
|
|
13
|
+
|
|
14
|
+
/// Ensures AVAudioSession is configured for playback and activated.
|
|
15
|
+
/// Safe to call multiple times — only activates once.
|
|
16
|
+
func ensureSessionActive() {
|
|
17
|
+
guard !isSessionActivated else { return }
|
|
18
|
+
|
|
19
|
+
let session = AVAudioSession.sharedInstance()
|
|
20
|
+
|
|
21
|
+
do {
|
|
22
|
+
try session.setCategory(
|
|
23
|
+
.playback,
|
|
24
|
+
mode: .default,
|
|
25
|
+
options: []
|
|
26
|
+
)
|
|
27
|
+
try session.setActive(true)
|
|
28
|
+
isSessionActivated = true
|
|
29
|
+
print("[NowPlayingSessionManager] AVAudioSession activated with .playback category")
|
|
30
|
+
} catch {
|
|
31
|
+
print("[NowPlayingSessionManager] Failed to activate AVAudioSession: \(error)")
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/// Deactivates the audio session.
|
|
36
|
+
func deactivateSession() {
|
|
37
|
+
guard isSessionActivated else { return }
|
|
38
|
+
|
|
39
|
+
let session = AVAudioSession.sharedInstance()
|
|
40
|
+
|
|
41
|
+
do {
|
|
42
|
+
try session.setActive(false, options: .notifyOthersOnDeactivation)
|
|
43
|
+
isSessionActivated = false
|
|
44
|
+
print("[NowPlayingSessionManager] AVAudioSession deactivated")
|
|
45
|
+
} catch {
|
|
46
|
+
print("[NowPlayingSessionManager] Failed to deactivate AVAudioSession: \(error)")
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -10,5 +10,6 @@ export interface NowPlayingTemplate extends HybridObject<{
|
|
|
10
10
|
createNowPlayingTemplate(config: NowPlayingTemplateConfig): void;
|
|
11
11
|
updateNowPlayingTemplatePlaybackState(templateId: string, isPlaying: boolean): Promise<void>;
|
|
12
12
|
updateNowPlayingTemplateInfo(templateId: string, title: string, subtitle: string): Promise<void>;
|
|
13
|
+
updateNowPlayingTemplateElapsedTime(templateId: string, elapsedTime: number, duration: number): Promise<void>;
|
|
13
14
|
}
|
|
14
15
|
export {};
|
|
@@ -22,4 +22,5 @@ export declare class NowPlayingTemplate extends Template<NowPlayingTemplateConfi
|
|
|
22
22
|
constructor(config: NowPlayingTemplateConfig);
|
|
23
23
|
updatePlaybackState(isPlaying: boolean): Promise<void>;
|
|
24
24
|
updateNowPlayingInfo(title: string, subtitle: string): Promise<void>;
|
|
25
|
+
updateElapsedTime(elapsedTime: number, duration: number): Promise<void>;
|
|
25
26
|
}
|
|
@@ -19,4 +19,7 @@ export class NowPlayingTemplate extends Template {
|
|
|
19
19
|
updateNowPlayingInfo(title, subtitle) {
|
|
20
20
|
return HybridNowPlayingTemplate.updateNowPlayingTemplateInfo(this.id, title, subtitle);
|
|
21
21
|
}
|
|
22
|
+
updateElapsedTime(elapsedTime, duration) {
|
|
23
|
+
return HybridNowPlayingTemplate.updateNowPlayingTemplateElapsedTime(this.id, elapsedTime, duration);
|
|
24
|
+
}
|
|
22
25
|
}
|
|
@@ -113,5 +113,20 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
113
113
|
return __promise;
|
|
114
114
|
}();
|
|
115
115
|
}
|
|
116
|
+
std::shared_ptr<Promise<void>> JHybridNowPlayingTemplateSpec::updateNowPlayingTemplateElapsedTime(const std::string& templateId, double elapsedTime, double duration) {
|
|
117
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* templateId */, double /* elapsedTime */, double /* duration */)>("updateNowPlayingTemplateElapsedTime");
|
|
118
|
+
auto __result = method(_javaPart, jni::make_jstring(templateId), elapsedTime, duration);
|
|
119
|
+
return [&]() {
|
|
120
|
+
auto __promise = Promise<void>::create();
|
|
121
|
+
__result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& /* unit */) {
|
|
122
|
+
__promise->resolve();
|
|
123
|
+
});
|
|
124
|
+
__result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
|
|
125
|
+
jni::JniException __jniError(__throwable);
|
|
126
|
+
__promise->reject(std::make_exception_ptr(__jniError));
|
|
127
|
+
});
|
|
128
|
+
return __promise;
|
|
129
|
+
}();
|
|
130
|
+
}
|
|
116
131
|
|
|
117
132
|
} // namespace margelo::nitro::swe::iternio::reactnativeautoplay
|
|
@@ -57,6 +57,7 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
57
57
|
void createNowPlayingTemplate(const NowPlayingTemplateConfig& config) override;
|
|
58
58
|
std::shared_ptr<Promise<void>> updateNowPlayingTemplatePlaybackState(const std::string& templateId, bool isPlaying) override;
|
|
59
59
|
std::shared_ptr<Promise<void>> updateNowPlayingTemplateInfo(const std::string& templateId, const std::string& title, const std::string& subtitle) override;
|
|
60
|
+
std::shared_ptr<Promise<void>> updateNowPlayingTemplateElapsedTime(const std::string& templateId, double elapsedTime, double duration) override;
|
|
60
61
|
|
|
61
62
|
private:
|
|
62
63
|
friend HybridBase;
|
|
@@ -57,6 +57,10 @@ abstract class HybridNowPlayingTemplateSpec: HybridObject() {
|
|
|
57
57
|
@DoNotStrip
|
|
58
58
|
@Keep
|
|
59
59
|
abstract fun updateNowPlayingTemplateInfo(templateId: String, title: String, subtitle: String): Promise<Unit>
|
|
60
|
+
|
|
61
|
+
@DoNotStrip
|
|
62
|
+
@Keep
|
|
63
|
+
abstract fun updateNowPlayingTemplateElapsedTime(templateId: String, elapsedTime: Double, duration: Double): Promise<Unit>
|
|
60
64
|
|
|
61
65
|
private external fun initHybrid(): HybridData
|
|
62
66
|
|
|
@@ -106,6 +106,14 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
106
106
|
auto __value = std::move(__result.value());
|
|
107
107
|
return __value;
|
|
108
108
|
}
|
|
109
|
+
inline std::shared_ptr<Promise<void>> updateNowPlayingTemplateElapsedTime(const std::string& templateId, double elapsedTime, double duration) override {
|
|
110
|
+
auto __result = _swiftPart.updateNowPlayingTemplateElapsedTime(templateId, std::forward<decltype(elapsedTime)>(elapsedTime), std::forward<decltype(duration)>(duration));
|
|
111
|
+
if (__result.hasError()) [[unlikely]] {
|
|
112
|
+
std::rethrow_exception(__result.error());
|
|
113
|
+
}
|
|
114
|
+
auto __value = std::move(__result.value());
|
|
115
|
+
return __value;
|
|
116
|
+
}
|
|
109
117
|
|
|
110
118
|
private:
|
|
111
119
|
ReactNativeAutoPlay::HybridNowPlayingTemplateSpec_cxx _swiftPart;
|
|
@@ -17,6 +17,7 @@ public protocol HybridNowPlayingTemplateSpec_protocol: HybridObject {
|
|
|
17
17
|
func createNowPlayingTemplate(config: NowPlayingTemplateConfig) throws -> Void
|
|
18
18
|
func updateNowPlayingTemplatePlaybackState(templateId: String, isPlaying: Bool) throws -> Promise<Void>
|
|
19
19
|
func updateNowPlayingTemplateInfo(templateId: String, title: String, subtitle: String) throws -> Promise<Void>
|
|
20
|
+
func updateNowPlayingTemplateElapsedTime(templateId: String, elapsedTime: Double, duration: Double) throws -> Promise<Void>
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
public extension HybridNowPlayingTemplateSpec_protocol {
|
|
@@ -165,4 +165,23 @@ open class HybridNowPlayingTemplateSpec_cxx {
|
|
|
165
165
|
return bridge.create_Result_std__shared_ptr_Promise_void___(__exceptionPtr)
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
|
+
|
|
169
|
+
@inline(__always)
|
|
170
|
+
public final func updateNowPlayingTemplateElapsedTime(templateId: std.string, elapsedTime: Double, duration: Double) -> bridge.Result_std__shared_ptr_Promise_void___ {
|
|
171
|
+
do {
|
|
172
|
+
let __result = try self.__implementation.updateNowPlayingTemplateElapsedTime(templateId: String(templateId), elapsedTime: elapsedTime, duration: duration)
|
|
173
|
+
let __resultCpp = { () -> bridge.std__shared_ptr_Promise_void__ in
|
|
174
|
+
let __promise = bridge.create_std__shared_ptr_Promise_void__()
|
|
175
|
+
let __promiseHolder = bridge.wrap_std__shared_ptr_Promise_void__(__promise)
|
|
176
|
+
__result
|
|
177
|
+
.then({ __result in __promiseHolder.resolve() })
|
|
178
|
+
.catch({ __error in __promiseHolder.reject(__error.toCpp()) })
|
|
179
|
+
return __promise
|
|
180
|
+
}()
|
|
181
|
+
return bridge.create_Result_std__shared_ptr_Promise_void___(__resultCpp)
|
|
182
|
+
} catch (let __error) {
|
|
183
|
+
let __exceptionPtr = __error.toCpp()
|
|
184
|
+
return bridge.create_Result_std__shared_ptr_Promise_void___(__exceptionPtr)
|
|
185
|
+
}
|
|
186
|
+
}
|
|
168
187
|
}
|
|
@@ -17,6 +17,7 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
17
17
|
prototype.registerHybridMethod("createNowPlayingTemplate", &HybridNowPlayingTemplateSpec::createNowPlayingTemplate);
|
|
18
18
|
prototype.registerHybridMethod("updateNowPlayingTemplatePlaybackState", &HybridNowPlayingTemplateSpec::updateNowPlayingTemplatePlaybackState);
|
|
19
19
|
prototype.registerHybridMethod("updateNowPlayingTemplateInfo", &HybridNowPlayingTemplateSpec::updateNowPlayingTemplateInfo);
|
|
20
|
+
prototype.registerHybridMethod("updateNowPlayingTemplateElapsedTime", &HybridNowPlayingTemplateSpec::updateNowPlayingTemplateElapsedTime);
|
|
20
21
|
});
|
|
21
22
|
}
|
|
22
23
|
|
|
@@ -54,6 +54,7 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
54
54
|
virtual void createNowPlayingTemplate(const NowPlayingTemplateConfig& config) = 0;
|
|
55
55
|
virtual std::shared_ptr<Promise<void>> updateNowPlayingTemplatePlaybackState(const std::string& templateId, bool isPlaying) = 0;
|
|
56
56
|
virtual std::shared_ptr<Promise<void>> updateNowPlayingTemplateInfo(const std::string& templateId, const std::string& title, const std::string& subtitle) = 0;
|
|
57
|
+
virtual std::shared_ptr<Promise<void>> updateNowPlayingTemplateElapsedTime(const std::string& templateId, double elapsedTime, double duration) = 0;
|
|
57
58
|
|
|
58
59
|
protected:
|
|
59
60
|
// Hybrid Setup
|
package/package.json
CHANGED
|
@@ -8,4 +8,5 @@ export interface NowPlayingTemplate extends HybridObject<{ android: 'kotlin'; io
|
|
|
8
8
|
createNowPlayingTemplate(config: NowPlayingTemplateConfig): void;
|
|
9
9
|
updateNowPlayingTemplatePlaybackState(templateId: string, isPlaying: boolean): Promise<void>;
|
|
10
10
|
updateNowPlayingTemplateInfo(templateId: string, title: string, subtitle: string): Promise<void>;
|
|
11
|
+
updateNowPlayingTemplateElapsedTime(templateId: string, elapsedTime: number, duration: number): Promise<void>;
|
|
11
12
|
}
|
|
@@ -59,4 +59,8 @@ export class NowPlayingTemplate extends Template<
|
|
|
59
59
|
public updateNowPlayingInfo(title: string, subtitle: string) {
|
|
60
60
|
return HybridNowPlayingTemplate.updateNowPlayingTemplateInfo(this.id, title, subtitle);
|
|
61
61
|
}
|
|
62
|
+
|
|
63
|
+
public updateElapsedTime(elapsedTime: number, duration: number) {
|
|
64
|
+
return HybridNowPlayingTemplate.updateNowPlayingTemplateElapsedTime(this.id, elapsedTime, duration);
|
|
65
|
+
}
|
|
62
66
|
}
|