mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-11 19:46:16 -08:00
fix(electron): skip the login shell PATH wait for Flatpak host launches
In Flatpak, players start through `flatpak-spawn --host`, which resolves the name with the host's PATH; the sandbox's login shell lookup cannot change it. The launch handlers now decide from the same launch context the player uses: no wait in flatpak-host mode, otherwise only for a bare player name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e60a65b3d0
commit
dbdec94685
2 files changed
+52
-14
No files matched your search
@@ -4,6 +4,11 @@ jest.mock('electron', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('fs', () => {
|
||||
const actual = jest.requireActual<typeof import('fs')>('fs');
|
||||
return { ...actual, existsSync: jest.fn(actual.existsSync) };
|
||||
});
|
||||
|
||||
jest.mock('child_process', () => ({
|
||||
spawn: jest.fn(),
|
||||
}));
|
||||
@@ -37,6 +42,7 @@ jest.mock('../services/stalker-playback-context.service', () => ({
|
||||
import { ipcMain } from 'electron';
|
||||
import { spawn, type ChildProcess } from 'child_process';
|
||||
import { EventEmitter } from 'events';
|
||||
import * as fs from 'fs';
|
||||
import {
|
||||
MPV_PLAYER_PATH,
|
||||
store,
|
||||
@@ -528,6 +534,39 @@ describe('external player launch handlers', () => {
|
||||
}
|
||||
);
|
||||
|
||||
it.each(['OPEN_MPV_PLAYER', 'OPEN_VLC_PLAYER'])(
|
||||
'%s does not wait for a Flatpak host launch of a bare name',
|
||||
async (channel) => {
|
||||
const originalPlatform = process.platform;
|
||||
const existsSync = fs.existsSync as unknown as jest.Mock;
|
||||
existsSync.mockImplementation(
|
||||
(candidate: unknown) => String(candidate) === '/.flatpak-info'
|
||||
);
|
||||
Object.defineProperty(process, 'platform', { value: 'linux' });
|
||||
configurePlayerPath(channel, 'player-on-host-path');
|
||||
try {
|
||||
await launchUntilSpawn(
|
||||
channel,
|
||||
new Promise<void>(() => undefined),
|
||||
async () => {
|
||||
await waitForSpawnCallCount(1);
|
||||
expect(waitForLoginShellPath).not.toHaveBeenCalled();
|
||||
expect(
|
||||
(spawn as unknown as jest.Mock).mock.calls[0][0]
|
||||
).toBe('flatpak-spawn');
|
||||
}
|
||||
);
|
||||
} finally {
|
||||
existsSync.mockImplementation(
|
||||
jest.requireActual<typeof import('fs')>('fs').existsSync
|
||||
);
|
||||
Object.defineProperty(process, 'platform', {
|
||||
value: originalPlatform,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
it.each(['OPEN_MPV_PLAYER', 'OPEN_VLC_PLAYER'])(
|
||||
'%s starts a configured executable path without waiting',
|
||||
async (channel) => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ipcMain } from 'electron';
|
||||
import {
|
||||
CLOSE_EXTERNAL_PLAYER_SESSION,
|
||||
type ExternalPlayerName,
|
||||
PLAYBACK_SET_KEEP_AWAKE,
|
||||
PlayerContentInfo,
|
||||
} from '@iptvnator/shared/interfaces';
|
||||
@@ -12,10 +13,8 @@ import {
|
||||
VLC_PLAYER_PATH,
|
||||
} from '../services/store.service';
|
||||
import {
|
||||
getDefaultMpvPath,
|
||||
getDefaultVlcPath,
|
||||
normalizeCustomPlayerPath,
|
||||
normalizePlayerPathForStore,
|
||||
resolveExternalPlayerLaunchContext as resolveLaunchContext,
|
||||
} from './external-player-launch-context';
|
||||
import {
|
||||
externalPlayerSessions,
|
||||
@@ -43,10 +42,16 @@ export {
|
||||
/**
|
||||
* A player resolved to a bare name (no configured path, no well-known
|
||||
* install found) is looked up through PATH, so it waits for the login shell
|
||||
* PATH; a path to an executable starts right away.
|
||||
* PATH; a path to an executable starts right away. So does a Flatpak host
|
||||
* launch: `flatpak-spawn --host` resolves the name with the host's PATH,
|
||||
* which the sandbox's login shell lookup cannot change.
|
||||
*/
|
||||
async function waitForPathIfBareName(playerPath: string): Promise<void> {
|
||||
if (!/[\\/]/.test(playerPath)) {
|
||||
async function waitForPathIfBareName(
|
||||
player: ExternalPlayerName,
|
||||
configuredPath: string | undefined
|
||||
): Promise<void> {
|
||||
const context = resolveLaunchContext(player, configuredPath);
|
||||
if (context.mode !== 'flatpak-host' && !/[\\/]/.test(context.playerPath)) {
|
||||
await waitForLoginShellPath();
|
||||
}
|
||||
}
|
||||
@@ -71,10 +76,7 @@ ipcMain.handle(
|
||||
startTime?: number,
|
||||
headers?: Record<string, string>
|
||||
) => {
|
||||
await waitForPathIfBareName(
|
||||
normalizeCustomPlayerPath(store.get(MPV_PLAYER_PATH)) ??
|
||||
getDefaultMpvPath()
|
||||
);
|
||||
await waitForPathIfBareName('mpv', store.get(MPV_PLAYER_PATH));
|
||||
return openMpvPlayer({
|
||||
url,
|
||||
title,
|
||||
@@ -118,10 +120,7 @@ ipcMain.handle(
|
||||
startTime?: number,
|
||||
headers?: Record<string, string>
|
||||
) => {
|
||||
await waitForPathIfBareName(
|
||||
normalizeCustomPlayerPath(store.get(VLC_PLAYER_PATH)) ??
|
||||
getDefaultVlcPath()
|
||||
);
|
||||
await waitForPathIfBareName('vlc', store.get(VLC_PLAYER_PATH));
|
||||
return openVlcPlayer({
|
||||
url,
|
||||
title,
|
||||
|
||||
Reference in new issue
Block a user