mirror of
https://github.com/streamyfin/streamyfin.git
synced 2025-08-20 18:37:18 +02:00
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:
66
plugins/with-runtime-framework-headers.js
Normal file
66
plugins/with-runtime-framework-headers.js
Normal file
@@ -0,0 +1,66 @@
|
||||
const { withPodfile } = require("expo/config-plugins");
|
||||
|
||||
const PATCH_START = "## >>> runtime-framework headers";
|
||||
const PATCH_END = "## <<< runtime-framework headers";
|
||||
|
||||
const EXTRA_HDRS = [
|
||||
`\${PODS_CONFIGURATION_BUILD_DIR}/React-RuntimeApple/React_RuntimeApple.framework/Headers`,
|
||||
`\${PODS_CONFIGURATION_BUILD_DIR}/React-RuntimeCore/React_RuntimeCore.framework/Headers`,
|
||||
`\${PODS_CONFIGURATION_BUILD_DIR}/React-jserrorhandler/React_jserrorhandler.framework/Headers`,
|
||||
`\${PODS_CONFIGURATION_BUILD_DIR}/React-jsinspector/jsinspector_modern.framework/Headers`,
|
||||
`\${PODS_CONFIGURATION_BUILD_DIR}/React-runtimescheduler/React_runtimescheduler.framework/Headers`,
|
||||
`\${PODS_CONFIGURATION_BUILD_DIR}/React-performancetimeline/React_performancetimeline.framework/Headers`,
|
||||
`\${PODS_CONFIGURATION_BUILD_DIR}/React-rendererconsistency/React_rendererconsistency.framework/Headers`,
|
||||
];
|
||||
|
||||
function buildPatch() {
|
||||
return [
|
||||
PATCH_START,
|
||||
" extra_hdrs = [",
|
||||
...EXTRA_HDRS.map((h) => ` "${h}",`),
|
||||
" ]",
|
||||
"",
|
||||
" installer.pods_project.targets.each do |t|",
|
||||
" t.build_configurations.each do |cfg|",
|
||||
" cfg.build_settings['HEADER_SEARCH_PATHS'] ||= '$(inherited)'",
|
||||
" cfg.build_settings['HEADER_SEARCH_PATHS'] << \" #{extra_hdrs.join(' ')}\"",
|
||||
" end",
|
||||
" end",
|
||||
PATCH_END,
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
module.exports = function withRuntimeFrameworkHeaders(config) {
|
||||
return withPodfile(config, (config) => {
|
||||
let podfile = config.modResults.contents;
|
||||
|
||||
// 1️⃣ ensure there's a post_install block
|
||||
if (!/^\s*post_install\s+do\s+\|installer\|/m.test(podfile)) {
|
||||
podfile += `
|
||||
|
||||
post_install do |installer|
|
||||
end
|
||||
`;
|
||||
}
|
||||
|
||||
const patch = buildPatch();
|
||||
|
||||
if (podfile.includes(PATCH_START)) {
|
||||
// 🔄 update existing patch
|
||||
podfile = podfile.replace(
|
||||
new RegExp(`${PATCH_START}[\\s\\S]*?${PATCH_END}`),
|
||||
patch,
|
||||
);
|
||||
} else {
|
||||
// ➕ insert right after the post_install opening line
|
||||
podfile = podfile.replace(
|
||||
/^\s*post_install\s+do\s+\|installer\|.*$/m,
|
||||
(match) => `${match}\n\n${patch}`,
|
||||
);
|
||||
}
|
||||
|
||||
console.log("✅ with-runtime-framework-headers: Podfile updated");
|
||||
config.modResults.contents = podfile;
|
||||
return config;
|
||||
});
|
||||
};
|
||||
@@ -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 xcode‑js 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;
|
||||
|
||||
Reference in New Issue
Block a user