mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-12 12:06:16 -08:00
fix(playback): keep the saved Embedded MPV player when the mpv check is inconclusive
On Linux native-view the support check runs `mpv --version` by bare name and waits for the login shell PATH first. Since #1784 that lookup is asynchronous with a 10 s budget; when it ran out, the check ran on the inherited PATH and answered a plain `supported: false`. The settings store took that as a verdict and persisted the default player over a saved Embedded MPV selection. The main process probed again once the shell answered, but nothing restored the setting. `EmbeddedMpvSupport` now carries `inconclusive`. The native service sets it on a missing mpv while its probe has only seen the inherited PATH; the IPC handler declares that state before probing and registers the re-probe before the check, so a throwing check cannot leave it stuck. Every other answer stays final. Consumers no longer settle on an inconclusive answer: the settings store keeps the saved player, and the command palette and the settings search probe again on their next use instead of caching it for the session. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
8e1cb05913
commit
417eaf5005
14 files changed
+545
-16
No files matched your search
@@ -142,6 +142,7 @@ describe('SettingsSearchService', () => {
|
||||
|
||||
function probeWith(support: {
|
||||
supported: boolean;
|
||||
inconclusive?: boolean;
|
||||
frameCopyAvailable?: boolean;
|
||||
}) {
|
||||
const getEmbeddedMpvSupport = jest
|
||||
@@ -186,6 +187,32 @@ describe('SettingsSearchService', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('asks again after an inconclusive answer and keeps the final one', async () => {
|
||||
// A slow login shell: mpv was looked up before its PATH arrived.
|
||||
const getEmbeddedMpvSupport = probeWith({
|
||||
supported: false,
|
||||
inconclusive: true,
|
||||
});
|
||||
const { service } = setup({
|
||||
...DESKTOP,
|
||||
supportsEmbeddedMpv: true,
|
||||
});
|
||||
const entries = () => service.visibleEntries().map(({ id }) => id);
|
||||
|
||||
await service.ensureEmbeddedMpvSupportLoaded();
|
||||
expect(entries()).not.toContain('embedded-mpv-extra-options');
|
||||
|
||||
// The shell answered meanwhile, and mpv is there.
|
||||
getEmbeddedMpvSupport.mockResolvedValue({
|
||||
platform: 'linux',
|
||||
supported: true,
|
||||
});
|
||||
await service.ensureEmbeddedMpvSupportLoaded();
|
||||
expect(entries()).toContain('embedded-mpv-extra-options');
|
||||
expect(service.ensureEmbeddedMpvSupportLoaded()).toBeUndefined();
|
||||
expect(getEmbeddedMpvSupport).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('does not probe where the runtime has no embedded MPV bridge', () => {
|
||||
const getEmbeddedMpvSupport = probeWith({ supported: true });
|
||||
const { service } = setup(DESKTOP);
|
||||
|
||||
@@ -66,7 +66,8 @@ export class SettingsSearchService {
|
||||
* searchable. Returns the pending probe, or `undefined` when there is
|
||||
* nothing to wait for. Call it lazily (palette open, settings page),
|
||||
* never from shell bootstrap: supported desktop builds may load the
|
||||
* native addon while answering.
|
||||
* native addon while answering. An inconclusive answer is used until
|
||||
* the next call, which probes again.
|
||||
*/
|
||||
ensureEmbeddedMpvSupportLoaded(): Promise<void> | undefined {
|
||||
if (this.embeddedMpvSupportChecked) {
|
||||
@@ -88,7 +89,9 @@ export class SettingsSearchService {
|
||||
.then((support) => this.embeddedMpvSupport.set(support))
|
||||
.catch(() => this.embeddedMpvSupport.set(null))
|
||||
.finally(() => {
|
||||
this.embeddedMpvSupportChecked = true;
|
||||
this.embeddedMpvSupportChecked =
|
||||
!this.embeddedMpvSupport()?.inconclusive;
|
||||
this.embeddedMpvSupportLoad = undefined;
|
||||
});
|
||||
return this.embeddedMpvSupportLoad;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user