#442: a car's pick told the page `replaced`, and the page closed its player bar, so leaving the car with the episode playing left nothing on the phone to pause it. And when the car launched the app, the page loaded later and was never told anything played. Now the app sends `nowPlaying` (the item, its place, playing or not) on a car pick, at the page's `ready`, and on coming forward, and the page's bar takes it up and drives the phone's player. `replaced` is still handled for builds before this one. #443: Shows listed every feed with items, blogs included. Now only feeds with a downloaded file, and an episode only with a downloaded audio file: /media/{id} answers 404 before the download. #444: tests/native-bridge.ts read its failure count before the CarPlay checks, so those could fail and still exit 0. The count is read last now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RqkrVARreS9wxzH5o2rF7N
This commit is contained in:
@@ -43,7 +43,12 @@ final class Bridge: NSObject, WKScriptMessageHandler {
|
||||
playback.onEnded = { [weak self] in self?.send(["t": "ended"]) }
|
||||
playback.onError = { [weak self] msg in self?.send(["t": "error", "message": msg]) }
|
||||
playback.onSlept = { [weak self] in self?.send(["t": "slept"]) }
|
||||
playback.onReplaced = { [weak self] in self?.send(["t": "replaced"]) }
|
||||
playback.onChosen = { [weak self] in self?.sendNowPlaying() }
|
||||
// Again on coming forward: a page frozen while the car chose may have missed it (#442).
|
||||
NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil,
|
||||
queue: .main) { [weak self] _ in
|
||||
MainActor.assumeIsolated { self?.sendNowPlaying() }
|
||||
}
|
||||
Push.onToken = { [weak self] _ in self?.sendPush() }
|
||||
Offline.shared.onChange = { [weak self] in self?.sendKept() }
|
||||
Offline.shared.onFail = { [weak self] path, msg in
|
||||
@@ -57,6 +62,19 @@ final class Bridge: NSObject, WKScriptMessageHandler {
|
||||
"keeping": Offline.shared.downloading.sorted()])
|
||||
}
|
||||
|
||||
/// What is loaded, for the page's player bar to take up (#442): the car's pick, or an episode
|
||||
/// playing when the page loads, as when the app was opened from CarPlay. Without it the sound
|
||||
/// went on with no bar on the phone to pause it.
|
||||
private func sendNowPlaying() {
|
||||
guard let item = playback.current else { return }
|
||||
var m: [String: Any] = ["t": "nowPlaying", "feedId": item.feedId, "guid": item.guid, "enc": item.enc,
|
||||
"title": item.title, "feedTitle": item.feedTitle,
|
||||
"playing": playback.wantsToPlay, "cur": playback.currentTime]
|
||||
if let a = item.artwork { m["artwork"] = a }
|
||||
if let d = playback.duration ?? item.duration.map(Double.init) { m["dur"] = d }
|
||||
send(m)
|
||||
}
|
||||
|
||||
/// For the page to register with ipx (#433), at ready and whenever Apple gives a new one.
|
||||
private func sendPush() {
|
||||
guard let token = Push.token else { return }
|
||||
@@ -78,6 +96,7 @@ final class Bridge: NSObject, WKScriptMessageHandler {
|
||||
if let at = playback.sleepAt { send(["t": "sleep", "left": max(0, at.timeIntervalSinceNow)]) }
|
||||
sendKept()
|
||||
sendPush()
|
||||
sendNowPlaying()
|
||||
case "load":
|
||||
guard let path = m["url"] as? String, let url = Server.resolveForPlayer(path),
|
||||
let enc = m["enc"] as? Int,
|
||||
|
||||
Reference in New Issue
Block a user