mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 09:01:03 -08:00
* feat(packaging): register IPTVnator as the .m3u/.m3u8 handler Every runtime path for an OS-supplied playlist existed, but no packaging metadata claimed the file types — so the OS never offered IPTVnator as a handler and `open-file` could not fire from Finder. `fileAssociations` declares one entry per extension. Electron Builder derives all three platform registrations from it: macOS `CFBundleDocumentTypes` (the prerequisite for `open-file`), the NSIS registry entries, and, on Linux, the desktop entry's `MimeType` plus `/usr/share/mime/packages/iptvnator.xml` for deb/rpm/pacman. Neither platform needs a dedicated icon — both fall back to the app icon. Declaring `MimeType` under `linux.desktop.entry` would not have worked: Electron Builder assigns the association-derived value *after* spreading that object, so an explicit key there is silently overwritten. The per-association `mimeType` fields produce the same entry through the supported path. Registering the types also exposes a gap in the delivery side. The generated Linux `Exec` ends in `%U`, so file managers hand over a percent-encoded `file://` URI rather than a path, which `createPlaylistOpenRequest` would have resolved into a bogus relative path. It now decodes a `file://` candidate before the extension check. Suppressing the `%U` instead would mean putting an exec code in `linux.executableArgs`, which also passes it to the app as a real argument. Verified on macOS against a signed packaged bundle: Launch Services lists the app as a `public.m3u-playlist` handler, and an LS-initiated open imports the playlist both on a cold launch and against the already-running process. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(playlist): open every playlist of a multi-file selection `%U` is the plural exec code, so selecting several playlists in a Linux file manager is one launch carrying one argument per file. Both argv paths called `extractPlaylistOpenRequestFromArgv`, which returned at the first match, so everything after the first playlist was silently discarded — a gap this PR itself opened by making the desktop entry reachable in the first place. The extractor is now plural and returns every match in argument order, and the queue gained `enqueueAll` so a selection is pushed under a single flush: a delivery that fails partway leaves the untouched remainder queued in arrival order rather than interleaved. Covered by unit tests over a mixed argv (percent-encoded `file://` URI, a non-playlist argument, a second URI) and by a new Electron E2E that launches with two playlist arguments and asserts both are imported. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
193 lines
5.4 KiB
JSON
193 lines
5.4 KiB
JSON
{
|
|
"appId": "com.fourgray.iptvnator",
|
|
"productName": "IPTVnator",
|
|
"artifactName": "${name}-${version}-${os}-${arch}.${ext}",
|
|
"fileAssociations": [
|
|
{
|
|
"ext": "m3u",
|
|
"name": "M3U Playlist",
|
|
"description": "IPTV playlist",
|
|
"mimeType": "audio/x-mpegurl",
|
|
"role": "Viewer"
|
|
},
|
|
{
|
|
"ext": "m3u8",
|
|
"name": "M3U8 Playlist",
|
|
"description": "IPTV playlist",
|
|
"mimeType": "application/vnd.apple.mpegurl",
|
|
"role": "Viewer"
|
|
}
|
|
],
|
|
"publish": [
|
|
{
|
|
"provider": "github",
|
|
"owner": "4gray",
|
|
"repo": "iptvnator"
|
|
}
|
|
],
|
|
"directories": {
|
|
"buildResources": "dist/apps",
|
|
"output": "dist/executables"
|
|
},
|
|
"files": [
|
|
{
|
|
"from": "dist/apps/remote-control-web",
|
|
"to": "remote-control-web",
|
|
"filter": ["**/*"]
|
|
},
|
|
"electron-backend/**/*",
|
|
"!electron-backend/native{,/**/*}",
|
|
"web/**/*",
|
|
"!**/*.map"
|
|
],
|
|
"asarUnpack": [
|
|
"**/better-sqlite3/**",
|
|
"**/bindings/**",
|
|
"**/file-uri-to-path/**",
|
|
"**/*.node",
|
|
"**/*.dylib",
|
|
"**/*.dll",
|
|
"**/*.so",
|
|
"**/*.so.*",
|
|
"**/embedded-mpv-runtime.json"
|
|
],
|
|
"extraMetadata": {
|
|
"name": "iptvnator",
|
|
"productName": "IPTVnator",
|
|
"main": "electron-backend/main.js"
|
|
},
|
|
"extraResources": ["dist/apps/electron-backend/workers"],
|
|
"mac": {
|
|
"target": [
|
|
{
|
|
"target": "dmg",
|
|
"arch": ["x64", "arm64"]
|
|
},
|
|
{
|
|
"target": "zip",
|
|
"arch": ["x64", "arm64"]
|
|
}
|
|
],
|
|
"category": "public.app-category.video",
|
|
"forceCodeSigning": true,
|
|
"gatekeeperAssess": false,
|
|
"hardenedRuntime": true,
|
|
"entitlements": "apps/electron-backend/macos/entitlements.mac.plist",
|
|
"entitlementsInherit": "apps/electron-backend/macos/entitlements.mac.inherit.plist",
|
|
"notarize": true,
|
|
"icon": "apps/web/src/assets/icons/favicon.icns"
|
|
},
|
|
"linux": {
|
|
"category": "Video",
|
|
"executableName": "iptvnator",
|
|
"executableArgs": ["--ozone-platform=x11"],
|
|
"desktop": {
|
|
"entry": {
|
|
"StartupWMClass": "iptvnator"
|
|
}
|
|
},
|
|
"target": [
|
|
{
|
|
"target": "AppImage",
|
|
"arch": ["x64", "armv7l", "arm64"]
|
|
},
|
|
{
|
|
"target": "deb",
|
|
"arch": ["x64", "armv7l", "arm64"]
|
|
},
|
|
{
|
|
"target": "Snap",
|
|
"arch": ["x64", "armv7l"]
|
|
},
|
|
{
|
|
"target": "rpm",
|
|
"arch": ["x64"]
|
|
},
|
|
{
|
|
"target": "pacman",
|
|
"arch": ["x64"]
|
|
},
|
|
{
|
|
"target": "flatpak",
|
|
"arch": ["x64"]
|
|
}
|
|
],
|
|
"artifactName": "${name}-${version}-${os}-${arch}.${ext}",
|
|
"icon": "apps/web/src/assets/icons"
|
|
},
|
|
"flatpak": {
|
|
"branch": "stable",
|
|
"runtime": "org.freedesktop.Platform",
|
|
"runtimeVersion": "24.08",
|
|
"sdk": "org.freedesktop.Sdk",
|
|
"base": "org.electronjs.Electron2.BaseApp",
|
|
"baseVersion": "24.08",
|
|
"finishArgs": [
|
|
"--socket=wayland",
|
|
"--socket=x11",
|
|
"--share=ipc",
|
|
"--device=dri",
|
|
"--socket=pulseaudio",
|
|
"--filesystem=home",
|
|
"--share=network",
|
|
"--talk-name=org.freedesktop.Notifications",
|
|
"--talk-name=org.freedesktop.Flatpak"
|
|
],
|
|
"files": [
|
|
[
|
|
"apps/electron-backend/linux/com.fourgray.iptvnator.metainfo.xml",
|
|
"/share/metainfo/com.fourgray.iptvnator.metainfo.xml"
|
|
]
|
|
]
|
|
},
|
|
"afterPack": "./tools/packaging/electron-after-pack.cjs",
|
|
"snap": {
|
|
"base": "core22",
|
|
"confinement": "strict",
|
|
"grade": "stable",
|
|
"summary": "IPTV application for M3U playlists, Xtream Codes API, and Stalker portals",
|
|
"executableArgs": ["--ozone-platform=x11"],
|
|
"plugs": [
|
|
"default",
|
|
{
|
|
"graphics-core22": {
|
|
"interface": "content",
|
|
"target": "$SNAP/graphics",
|
|
"default-provider": "mesa-core22"
|
|
}
|
|
},
|
|
{
|
|
"shared-memory": {
|
|
"interface": "shared-memory",
|
|
"private": true
|
|
}
|
|
}
|
|
],
|
|
"environment": {
|
|
"DISABLE_WAYLAND": "1"
|
|
},
|
|
"layout": {
|
|
"/usr/share/libdrm": {
|
|
"bind": "$SNAP/graphics/libdrm"
|
|
},
|
|
"/usr/share/drirc.d": {
|
|
"symlink": "$SNAP/graphics/drirc.d"
|
|
}
|
|
}
|
|
},
|
|
"win": {
|
|
"compression": "maximum",
|
|
"target": [
|
|
{
|
|
"target": "nsis",
|
|
"arch": ["x64", "ia32"]
|
|
}
|
|
],
|
|
"artifactName": "${name}-${version}-windows-${arch}-setup.${ext}",
|
|
"icon": "apps/web/src/assets/icons/icon.png"
|
|
},
|
|
"nsis": {
|
|
"artifactName": "${name}-${version}-windows-${arch}-setup.${ext}"
|
|
}
|
|
}
|