mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-27 00:55:16 -07:00
fix(jellyfin): fix discovery loop, device identity, tray state, and Disc
- Derive device identity from OS hostname; remove legacy configurable client/device fields - Prevent discovery playback from reloading active item, misreporting pause state, and duplicate overlay restores - Restart stale tray discovery sessions without re-login when server drops SubMiner cast target - Sync tray discovery checkbox state on Linux after CLI/startup/remote-session changes - Stop Discord presence falling back to stream URLs; prime title before tokenized stream loads - Fix picker library discovery when log level is above info - Fix config.example.jsonc trailing commas and array formatting
This commit is contained in:
@@ -75,7 +75,10 @@ test('loads defaults when config is missing', () => {
|
||||
assert.equal(config.jellyfin.remoteControlEnabled, true);
|
||||
assert.equal(config.jellyfin.remoteControlAutoConnect, true);
|
||||
assert.equal(config.jellyfin.autoAnnounce, false);
|
||||
assert.equal(config.jellyfin.remoteControlDeviceName, 'SubMiner');
|
||||
assert.equal('clientName' in config.jellyfin, false);
|
||||
assert.equal('remoteControlDeviceName' in config.jellyfin, false);
|
||||
assert.equal('deviceId' in config.jellyfin, false);
|
||||
assert.equal('clientVersion' in config.jellyfin, false);
|
||||
assert.equal(config.ai.enabled, false);
|
||||
assert.equal(config.ai.apiKeyCommand, '');
|
||||
assert.equal(config.texthooker.openBrowser, false);
|
||||
@@ -832,7 +835,7 @@ test('parses anilist.characterDictionary.collapsibleSections booleans and warns
|
||||
);
|
||||
});
|
||||
|
||||
test('parses jellyfin remote control fields', () => {
|
||||
test('parses jellyfin remote control fields and ignores legacy identity fields', () => {
|
||||
const dir = makeTempDir();
|
||||
fs.writeFileSync(
|
||||
path.join(dir, 'config.jsonc'),
|
||||
@@ -843,6 +846,7 @@ test('parses jellyfin remote control fields', () => {
|
||||
"remoteControlEnabled": true,
|
||||
"remoteControlAutoConnect": true,
|
||||
"autoAnnounce": true,
|
||||
"clientName": "Custom Client",
|
||||
"remoteControlDeviceName": "SubMiner"
|
||||
}
|
||||
}`,
|
||||
@@ -857,7 +861,8 @@ test('parses jellyfin remote control fields', () => {
|
||||
assert.equal(config.jellyfin.remoteControlEnabled, true);
|
||||
assert.equal(config.jellyfin.remoteControlAutoConnect, true);
|
||||
assert.equal(config.jellyfin.autoAnnounce, true);
|
||||
assert.equal(config.jellyfin.remoteControlDeviceName, 'SubMiner');
|
||||
assert.equal('clientName' in config.jellyfin, false);
|
||||
assert.equal('remoteControlDeviceName' in config.jellyfin, false);
|
||||
});
|
||||
|
||||
test('parses jellyfin.enabled and remoteControlEnabled disabled combinations', () => {
|
||||
@@ -2469,6 +2474,8 @@ test('template generator includes known keys', () => {
|
||||
assert.match(output, /"startupWarmups":/);
|
||||
assert.match(output, /"updates":/);
|
||||
assert.match(output, /"youtube":/);
|
||||
assert.doesNotMatch(output, /"deviceId":/);
|
||||
assert.doesNotMatch(output, /"clientVersion":/);
|
||||
assert.doesNotMatch(output, /"youtubeSubgen":/);
|
||||
assert.match(output, /"characterDictionary":\s*\{/);
|
||||
assert.match(output, /"preserveLineBreaks": false/);
|
||||
|
||||
@@ -130,14 +130,10 @@ export const INTEGRATIONS_DEFAULT_CONFIG: Pick<
|
||||
serverUrl: '',
|
||||
recentServers: [],
|
||||
username: '',
|
||||
deviceId: 'subminer',
|
||||
clientName: 'SubMiner',
|
||||
clientVersion: '0.1.0',
|
||||
defaultLibraryId: '',
|
||||
remoteControlEnabled: true,
|
||||
remoteControlAutoConnect: true,
|
||||
autoAnnounce: false,
|
||||
remoteControlDeviceName: 'SubMiner',
|
||||
pullPictures: false,
|
||||
iconCacheDir: '/tmp/subminer-jellyfin-icons',
|
||||
directPlayPreferred: true,
|
||||
|
||||
@@ -548,26 +548,6 @@ export function buildIntegrationConfigOptionRegistry(
|
||||
defaultValue: defaultConfig.jellyfin.username,
|
||||
description: 'Default Jellyfin username used during CLI login.',
|
||||
},
|
||||
{
|
||||
path: 'jellyfin.deviceId',
|
||||
kind: 'string',
|
||||
defaultValue: defaultConfig.jellyfin.deviceId,
|
||||
description:
|
||||
'Stable device identifier sent on the Jellyfin authentication handshake; primarily internal.',
|
||||
},
|
||||
{
|
||||
path: 'jellyfin.clientName',
|
||||
kind: 'string',
|
||||
defaultValue: defaultConfig.jellyfin.clientName,
|
||||
description: 'Client name sent on the Jellyfin authentication handshake; primarily internal.',
|
||||
},
|
||||
{
|
||||
path: 'jellyfin.clientVersion',
|
||||
kind: 'string',
|
||||
defaultValue: defaultConfig.jellyfin.clientVersion,
|
||||
description:
|
||||
'Client version sent on the Jellyfin authentication handshake; primarily internal.',
|
||||
},
|
||||
{
|
||||
path: 'jellyfin.defaultLibraryId',
|
||||
kind: 'string',
|
||||
@@ -593,12 +573,6 @@ export function buildIntegrationConfigOptionRegistry(
|
||||
description:
|
||||
'When enabled, automatically trigger remote announce/visibility check on websocket connect.',
|
||||
},
|
||||
{
|
||||
path: 'jellyfin.remoteControlDeviceName',
|
||||
kind: 'string',
|
||||
defaultValue: defaultConfig.jellyfin.remoteControlDeviceName,
|
||||
description: 'Device name reported for Jellyfin remote control sessions.',
|
||||
},
|
||||
{
|
||||
path: 'jellyfin.pullPictures',
|
||||
kind: 'boolean',
|
||||
|
||||
@@ -371,9 +371,6 @@ export function applyIntegrationConfig(context: ResolveContext): void {
|
||||
const stringKeys = [
|
||||
'serverUrl',
|
||||
'username',
|
||||
'deviceId',
|
||||
'clientName',
|
||||
'clientVersion',
|
||||
'defaultLibraryId',
|
||||
'iconCacheDir',
|
||||
'transcodeVideoCodec',
|
||||
|
||||
@@ -59,7 +59,6 @@ test('settings registry hides removed modal-only fields', () => {
|
||||
'shortcuts.multiCopyTimeoutMs',
|
||||
'anilist.characterDictionary.profileScope',
|
||||
'jellyfin.directPlayContainers',
|
||||
'jellyfin.remoteControlDeviceName',
|
||||
]) {
|
||||
assert.equal(
|
||||
fields.some((candidate) => candidate.configPath === path),
|
||||
@@ -246,10 +245,7 @@ test('settings registry hides app-managed and inactive config surfaces', () => {
|
||||
'controller.preferredGamepadLabel',
|
||||
'controller.profiles',
|
||||
'youtubeSubgen.whisperBin',
|
||||
'jellyfin.clientVersion',
|
||||
'jellyfin.defaultLibraryId',
|
||||
'jellyfin.deviceId',
|
||||
'jellyfin.clientName',
|
||||
'subtitleSidebar.toggleKey',
|
||||
'jellyfin.recentServers',
|
||||
]) {
|
||||
|
||||
@@ -68,12 +68,8 @@ export const LEGACY_HIDDEN_CONFIG_PATHS = [
|
||||
'anilist.characterDictionary.profileScope',
|
||||
'jellyfin.accessToken',
|
||||
'jellyfin.userId',
|
||||
'jellyfin.clientName',
|
||||
'jellyfin.clientVersion',
|
||||
'jellyfin.defaultLibraryId',
|
||||
'jellyfin.deviceId',
|
||||
'jellyfin.directPlayContainers',
|
||||
'jellyfin.remoteControlDeviceName',
|
||||
'controller.buttonIndices',
|
||||
'shortcuts.multiCopyTimeoutMs',
|
||||
'subtitleSidebar.toggleKey',
|
||||
|
||||
Reference in New Issue
Block a user