Files
FEDEO/mobile/plugins/with-share-intent-multifile.js

159 lines
6.0 KiB
JavaScript

const fs = require('node:fs');
const path = require('node:path');
const { withAppDelegate, withInfoPlist, withXcodeProject } = require('@expo/config-plugins');
const SHARE_EXTENSION_DIRECTORY = 'InFEDEOhochladen';
const SIRI_INTENTS_FILE = 'FEDEOSiriIntents.swift';
function replaceOnce(source, search, replacement, label) {
if (!source.includes(search)) {
throw new Error(`Multi-File-Patch konnte ${label} nicht finden.`);
}
return source.replace(search, replacement);
}
module.exports = function withShareIntentMultifile(config) {
config = withInfoPlist(config, (modConfig) => {
modConfig.modResults.INAlternativeAppNames = [
{
INAlternativeAppName: 'Fedeo',
INAlternativeAppNamePronunciationHint: 'Feh-deh-oh',
},
{
INAlternativeAppName: 'FEDEO Aufgaben',
INAlternativeAppNamePronunciationHint: 'Feh-deh-oh Aufgaben',
},
];
return modConfig;
});
config = withAppDelegate(config, (modConfig) => {
let source = modConfig.modResults.contents;
if (!source.includes('import AppIntents')) {
source = source.replace('import Expo\n', 'import AppIntents\nimport Expo\n');
}
if (!source.includes('FEDEOAppShortcuts.updateAppShortcutParameters()')) {
source = replaceOnce(
source,
' ) -> Bool {\n',
' ) -> Bool {\n if #available(iOS 16.0, *) {\n FEDEOAppShortcuts.updateAppShortcutParameters()\n }\n',
'die Siri-Shortcut-Aktualisierung im AppDelegate'
);
}
modConfig.modResults.contents = source;
return modConfig;
});
return withXcodeProject(config, async (modConfig) => {
const siriTemplatePath = path.join(__dirname, 'ios', SIRI_INTENTS_FILE);
const siriDestinationPath = path.join(modConfig.modRequest.platformProjectRoot, 'FEDEO', SIRI_INTENTS_FILE);
fs.copyFileSync(siriTemplatePath, siriDestinationPath);
const project = modConfig.modResults;
const appTarget = project.pbxTargetByName('FEDEO');
const appGroup = project.pbxGroupByName('FEDEO');
const appTargetUUID = Object.entries(project.pbxNativeTargetSection()).find(
([key, entry]) => !key.endsWith('_comment') && entry === appTarget
)?.[0];
const appGroupUUID = Object.entries(project.hash.project.objects.PBXGroup).find(
([key, entry]) => !key.endsWith('_comment') && entry === appGroup
)?.[0];
const fileReferences = project.pbxFileReferenceSection();
const siriFileExists = Object.values(fileReferences).some(
(entry) => entry && typeof entry === 'object' && String(entry.path || entry.name || '').includes(SIRI_INTENTS_FILE)
);
if (!siriFileExists) {
if (!appTargetUUID || !appGroupUUID) {
throw new Error('FEDEO-App-Target für Siri App Intents wurde nicht gefunden.');
}
project.addSourceFile(
`FEDEO/${SIRI_INTENTS_FILE}`,
{ target: appTargetUUID },
appGroupUUID
);
}
const controllerPath = path.join(
modConfig.modRequest.platformProjectRoot,
SHARE_EXTENSION_DIRECTORY,
'ShareViewController.swift'
);
let source = fs.readFileSync(controllerPath, 'utf8');
source = replaceOnce(
source,
' var sharedText: [String] = []\n',
' var sharedText: [String] = []\n var processedMediaAttachmentCount = 0\n',
'den Attachment-Zähler'
);
const imageCompletion = ` // If this is the last item, save imagesData in userDefaults and redirect to host app
if index == (content.attachments?.count)! - 1 {
let userDefaults = UserDefaults(suiteName: self.hostAppGroupIdentifier)
userDefaults?.set(self.toData(data: self.sharedMedia), forKey: self.sharedKey)
userDefaults?.synchronize()
self.redirectToHostApp(type: .media)
}`;
source = replaceOnce(
source,
imageCompletion,
' self.finishMediaAttachment(content: content, type: .media)',
'den Abschluss der Bildverarbeitung'
);
source = replaceOnce(
source,
imageCompletion,
' self.finishMediaAttachment(content: content, type: .media)',
'den Abschluss der Videoverarbeitung'
);
const fileCompletion = ` if index == (content.attachments?.count)! - 1 {
let userDefaults = UserDefaults(suiteName: self.hostAppGroupIdentifier)
userDefaults?.set(self.toData(data: self.sharedMedia), forKey: self.sharedKey)
userDefaults?.synchronize()
self.redirectToHostApp(type: .file)
}`;
source = replaceOnce(
source,
fileCompletion,
' self.finishMediaAttachment(content: content, type: .file)',
'den Abschluss der Dateiverarbeitung'
);
const redirectMethod = ' private func redirectToHostApp(type: RedirectType) {';
const completionMethod = ` private func finishMediaAttachment(content: NSExtensionItem, type: RedirectType) {
processedMediaAttachmentCount += 1
let expectedMediaAttachmentCount = content.attachments?.filter { attachment in
attachment.hasItemConformingToTypeIdentifier(imageContentType)
|| attachment.hasItemConformingToTypeIdentifier(videoContentType)
|| attachment.hasItemConformingToTypeIdentifier(vcardContentType)
|| attachment.hasItemConformingToTypeIdentifier(fileURLType)
|| attachment.hasItemConformingToTypeIdentifier(pkpassContentType)
|| attachment.hasItemConformingToTypeIdentifier(pdfContentType)
}.count ?? 0
guard processedMediaAttachmentCount == expectedMediaAttachmentCount else { return }
let userDefaults = UserDefaults(suiteName: hostAppGroupIdentifier)
userDefaults?.set(toData(data: sharedMedia), forKey: sharedKey)
userDefaults?.synchronize()
redirectToHostApp(type: type)
}
`;
source = replaceOnce(
source,
redirectMethod,
completionMethod + redirectMethod,
'die Weiterleitungsmethode'
);
fs.writeFileSync(controllerPath, source);
return modConfig;
});
};