diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 05d4612..84c8ec2 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -154,29 +154,6 @@ jobs: run: | echo "${{ secrets.ANDROID_KEYSTORE_BASE64 }}" | base64 -d > android/app/withyou-release-key.keystore - - name: Patch app/build.gradle with signing config - run: | - cd android/app - python3 -c " - import re - with open('build.gradle', 'r') as f: - content = f.read() - release_signing = ''' - signingConfigs { - release { - storeFile file(WITHYOU_UPLOAD_STORE_FILE) - storePassword WITHYOU_UPLOAD_STORE_PASSWORD - keyAlias WITHYOU_UPLOAD_KEY_ALIAS - keyPassword WITHYOU_UPLOAD_KEY_PASSWORD - } - } - ''' - content = content.replace('signingConfigs {}', release_signing) - content = content.replace('signingConfig signingConfigs.debug', 'signingConfig signingConfigs.release') - with open('build.gradle', 'w') as f: - f.write(content) - " - - name: Configure Gradle with Aliyun Maven mirror run: | cd android @@ -291,10 +268,10 @@ jobs: run: | cd android cat >> gradle.properties << SIGNING_PROPS - WITHYOU_UPLOAD_STORE_FILE=withyou-release-key.keystore - WITHYOU_UPLOAD_STORE_PASSWORD=${{ secrets.ANDROID_KEYSTORE_PASSWORD }} - WITHYOU_UPLOAD_KEY_ALIAS=withyou-key - WITHYOU_UPLOAD_KEY_PASSWORD=${{ secrets.ANDROID_KEY_PASSWORD }} + MYAPP_UPLOAD_STORE_FILE=withyou-release-key.keystore + MYAPP_UPLOAD_STORE_PASSWORD=${{ secrets.ANDROID_KEYSTORE_PASSWORD }} + MYAPP_UPLOAD_KEY_ALIAS=withyou-key + MYAPP_UPLOAD_KEY_PASSWORD=${{ secrets.ANDROID_KEY_PASSWORD }} SIGNING_PROPS - name: Build Android release APK (arm64 only) diff --git a/assets/icon.png b/assets/icon.png index 7766a29..02ca22d 100644 Binary files a/assets/icon.png and b/assets/icon.png differ diff --git a/assets/splash-icon.png b/assets/splash-icon.png index 7766a29..02ca22d 100644 Binary files a/assets/splash-icon.png and b/assets/splash-icon.png differ diff --git a/metro.config.js b/metro.config.js index b9c2726..e26af8a 100644 --- a/metro.config.js +++ b/metro.config.js @@ -19,6 +19,35 @@ config.resolver.alias = { // Ensure platform-specific files are resolved correctly config.resolver.platforms = ['ios', 'android', 'native', 'web']; +// Web shims for native-only React Native APIs that don't exist in react-native-web. +// Packages like react-native-pager-view import codegenNativeComponent from +// react-native/Libraries/Utilities/codegenNativeComponent, which calls +// requireNativeComponent internally. On web (react-native-web), these APIs +// don't exist, causing "(0 , _reactNativeWebDistIndex.requireNativeComponent) +// is not a function". +const webShimPaths = [ + 'react-native/Libraries/Utilities/codegenNativeComponent', + 'react-native/Libraries/Utilities/codegenNativeCommands', + 'react-native/Libraries/Types/CodegenTypes', +]; + +const originalResolveRequest = config.resolver.resolveRequest; +const shimDir = path.resolve(__dirname, 'web-shims'); + +config.resolver.resolveRequest = (context, moduleName, platform) => { + if (platform === 'web' && webShimPaths.some((p) => moduleName.endsWith(p))) { + const shimName = moduleName.replace('react-native/Libraries/', ''); + return { + type: 'sourceFile', + filePath: path.join(shimDir, 'react-native', 'Libraries', shimName + '.js'), + }; + } + if (originalResolveRequest) { + return originalResolveRequest(context, moduleName, platform); + } + return context.resolveRequest(context, moduleName, platform); +}; + // NOTE: enhanceMiddleware is marked as deprecated in Metro's types, // but there's currently no official alternative for custom dev server headers. // For production, configure COEP/COOP headers on your hosting platform. @@ -31,4 +60,4 @@ config.server.enhanceMiddleware = (middleware) => { }; }; -module.exports = config; +module.exports = config; \ No newline at end of file diff --git a/web-shims/react-native/Libraries/Types/CodegenTypes.js b/web-shims/react-native/Libraries/Types/CodegenTypes.js new file mode 100644 index 0000000..9370f9e --- /dev/null +++ b/web-shims/react-native/Libraries/Types/CodegenTypes.js @@ -0,0 +1,17 @@ +const Double = Number; +const Int32 = Number; +const Float = Number; +const WithDefault = (type, defaultValue) => type; + +module.exports = { + Double, + Float, + Int32, + WithDefault, + DirectEventHandler: () => null, + BubblingEventHandler: () => null, + Stringish: String, + ColorValue: null, + HandledState: String, + WithSpringAnimation: (type) => type, +}; \ No newline at end of file diff --git a/web-shims/react-native/Libraries/Utilities/codegenNativeCommands.js b/web-shims/react-native/Libraries/Utilities/codegenNativeCommands.js new file mode 100644 index 0000000..6724381 --- /dev/null +++ b/web-shims/react-native/Libraries/Utilities/codegenNativeCommands.js @@ -0,0 +1,15 @@ +function codegenNativeCommands(options) { + const commands = {}; + if (options && options.supportedCommands) { + options.supportedCommands.forEach((commandName) => { + commands[commandName] = (ref, ...args) => { + if (ref && ref.current && typeof ref.current[commandName] === 'function') { + ref.current[commandName](...args); + } + }; + }); + } + return commands; +} + +module.exports = codegenNativeCommands; \ No newline at end of file diff --git a/web-shims/react-native/Libraries/Utilities/codegenNativeComponent.js b/web-shims/react-native/Libraries/Utilities/codegenNativeComponent.js new file mode 100644 index 0000000..a7ee2bf --- /dev/null +++ b/web-shims/react-native/Libraries/Utilities/codegenNativeComponent.js @@ -0,0 +1,18 @@ +const React = require('react'); + +function codegenNativeComponent(componentName, options) { + const componentNameClean = componentName + .replace(/^RNC/, '') + .replace(/^RNS/, '') + .replace(/^RN/, ''); + + const NativeComponent = React.forwardRef((props, ref) => { + const { children, ...rest } = props; + return React.createElement('div', { ...rest, ref, 'data-native-component': componentNameClean }, children); + }); + NativeComponent.displayName = componentName; + + return NativeComponent; +} + +module.exports = codegenNativeComponent; \ No newline at end of file