fix: tv playback (#820)

Signed-off-by: Lance Chant <13349722+lancechant@users.noreply.github.com>
Signed-off-by: lancechant <13349722+lancechant@users.noreply.github.com>
Co-authored-by: Fredrik Burmester <fredrik.burmester@gmail.com>
Co-authored-by: Uruk <contact@uruk.dev>
Co-authored-by: Gauvain <68083474+Gauvino@users.noreply.github.com>
This commit is contained in:
lance chant
2025-08-07 10:12:40 +02:00
committed by GitHub
parent 89fd7f0e34
commit 89b34eddc1
68 changed files with 1412 additions and 1786 deletions

View File

@@ -1,48 +1,66 @@
const { withAppDelegate } = require("@expo/config-plugins");
const { withAppDelegate, withXcodeProject } = require("@expo/config-plugins");
const fs = require("node:fs");
const path = require("node:path");
function withRNBackgroundDownloader(expoConfig) {
return withAppDelegate(expoConfig, async (appDelegateConfig) => {
const { modResults: appDelegate } = appDelegateConfig;
const appDelegateLines = appDelegate.contents.split("\n");
// Define the code to be added to AppDelegate.mm
const backgroundDownloaderImport =
"#import <RNBackgroundDownloader.h> // Required by react-native-background-downloader. Generated by expoPlugins/withRNBackgroundDownloader.js";
const backgroundDownloaderDelegate = `\n// Delegate method required by react-native-background-downloader. Generated by expoPlugins/withRNBackgroundDownloader.js
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)(void))completionHandler
{
[RNBackgroundDownloader setCompletionHandlerWithIdentifier:identifier completionHandler:completionHandler];
}`;
// Find the index of the AppDelegate import statement
const importIndex = appDelegateLines.findIndex((line) =>
/^#import "AppDelegate.h"/.test(line),
);
// Find the index of the last line before the @end statement
const endStatementIndex = appDelegateLines.findIndex((line) =>
/@end/.test(line),
);
// Insert the import statement if it's not already present
if (!appDelegate.contents.includes(backgroundDownloaderImport)) {
appDelegateLines.splice(importIndex + 1, 0, backgroundDownloaderImport);
}
// Insert the delegate method above the @end statement
if (!appDelegate.contents.includes(backgroundDownloaderDelegate)) {
appDelegateLines.splice(
endStatementIndex,
0,
backgroundDownloaderDelegate,
/** @param {import("@expo/config-plugins").ExpoConfig} config */
function withRNBackgroundDownloader(config) {
/* 1⃣ Add handleEventsForBackgroundURLSession to AppDelegate.swift */
config = withAppDelegate(config, (mod) => {
const tag = "handleEventsForBackgroundURLSession";
if (!mod.modResults.contents.includes(tag)) {
mod.modResults.contents = mod.modResults.contents.replace(
/\}\s*$/, // insert before final }
`
func application(
_ application: UIApplication,
handleEventsForBackgroundURLSession identifier: String,
completionHandler: @escaping () -> Void
) {
RNBackgroundDownloader.setCompletionHandlerWithIdentifier(identifier, completionHandler: completionHandler)
}
}`,
);
}
// Update the contents of the AppDelegate file
appDelegate.contents = appDelegateLines.join("\n");
return appDelegateConfig;
return mod;
});
/* 2⃣ Ensure bridging header exists & is attached to *every* app target */
config = withXcodeProject(config, (mod) => {
const project = mod.modResults;
const projectName = config.name || "App";
// Fix: Go up one more directory to get to ios/, not ios/ProjectName.xcodeproj/
const iosDir = path.dirname(path.dirname(project.filepath));
const headerRel = `${projectName}/${projectName}-Bridging-Header.h`;
const headerAbs = path.join(iosDir, headerRel);
// create / append import if missing
let headerText = "";
try {
headerText = fs.readFileSync(headerAbs, "utf8");
} catch (error) {
if (error.code !== "ENOENT") {
throw error;
}
}
if (!headerText.includes("RNBackgroundDownloader.h")) {
fs.mkdirSync(path.dirname(headerAbs), { recursive: true });
fs.appendFileSync(headerAbs, '#import "RNBackgroundDownloader.h"\n');
}
// Expo 53's xcodejs doesn't expose pbxTargets().
// Setting the property once at the project level is sufficient.
["Debug", "Release"].forEach((cfg) =>
project.updateBuildProperty(
"SWIFT_OBJC_BRIDGING_HEADER",
"Streamyfin/Streamyfin-Bridging-Header.h",
cfg,
),
);
return mod;
});
return config;
}
module.exports = withRNBackgroundDownloader;