Skip to content

Commit

Permalink
expo
Browse files Browse the repository at this point in the history
  • Loading branch information
JGreenlee committed Aug 14, 2024
1 parent 14f72de commit 19a7b35
Show file tree
Hide file tree
Showing 65 changed files with 21,956 additions and 309 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ www/dist/
config.xml
package.json
coverage/

/.expo/
/ios/
/android/
32 changes: 32 additions & 0 deletions app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"expo": {
"entryPoint": "./www/js/App.tsx",
"ios": {
"bundleIdentifier": "edu.berkeley.eecs.emission"
},
"android": {
"package": "edu.berkeley.eecs.emission"
},
"splash": {
"image": "./resources/splash.png",
"backgroundColor": "#EEEEEE"
},
"icon": "./resources/icon.png",
"plugins": [
[
"expo-build-properties",
{
"android": {
"compileSdkVersion": 34,
"targetSdkVersion": 34
}
}
],
[
"expo-gradle-ext-vars", {
"VERSION_CODE": "1"
}
]
]
}
}
16 changes: 9 additions & 7 deletions bin/configure_xml_and_json.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
const fs = require('fs');

var copyInlinedFiles = function(inlineString) {
var selConfigXml = "config."+inlineString+".xml";
var selPkgJson = "package."+inlineString+".json";
fs.copyFileSync(selConfigXml, "config.xml");
fs.copyFileSync(selPkgJson, "package.json");

console.log("Copied "+selConfigXml+" -> config.xml and "+
selPkgJson + " -> package.json");
[['config', 'xml'], ['package', 'json']].forEach(([prefix, ext]) => {
const selFile = prefix+"."+inlineString+"."+ext;
if (fs.existsSync(selFile)) {
fs.copyFileSync(selFile, prefix+"."+ext);
console.log("Copied "+selFile+" -> "+prefix+"."+ext);
} else {
console.log("File "+selFile+" does not exist, skipping");
}
});
}

if (process.argv.length != 3) {
Expand Down
21 changes: 21 additions & 0 deletions bin/reset_native_modules.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

PACKAGE=$1

# if they didn't pass a package, loop through all the modules and reinstall them
if [[ $# -eq 0 ]]; then
echo "Uninstalling all packages and reinstalling them from local modules"
for dir in ./modules/*; do
if [ -d "$dir" ]; then
package=$(basename $dir)
rm -rf ./node_modules/$package
npm uninstall $package && npm i ./modules/$package
fi
done
else
# if they passed a package only reinstall that package
echo "Uninstalling $PACKAGE and reinstalling it from local modules"
npm uninstall $PACKAGE && npm i ./modules/$PACKAGE
fi

echo "Done"
18 changes: 18 additions & 0 deletions metro.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { getDefaultConfig } = require('expo/metro-config');

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);

config.resolver = {
...config.resolver,
unstable_enablePackageExports: true,
resolveRequest: (context, moduleName, platform) => {
if (moduleName == 'libxslt') {
return { type: 'empty' };
}
// Optionally, chain to the standard Metro resolver.
return context.resolveRequest(context, moduleName, platform);
}
};

module.exports = config;
66 changes: 66 additions & 0 deletions modules/withLocalizedStrings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
const { AndroidConfig, withStringsXml } = require('expo/config-plugins');

function withLocalizedStrings(config, filepath) {
return withStringsXml(config, config => {
config.modResults = setStrings(config.modResults, value);
return config;
});
}

function setStrings(strings, value) {
// Helper to add string.xml JSON items or overwrite existing items with the same name.
return AndroidConfig.Strings.setStringItem(
[
// XML represented as JSON
// <string name="expo_custom_value" translatable="false">value</string>
{ $: { name: 'expo_custom_value', translatable: 'false' }, _: value },
],
strings
);
AndroidConfig.Strings.
}

module.exports = withLocalizedStrings;

const fs = require('fs');
const path = require('path');
const { withStringsXml, AndroidConfig } = require('@expo/config-plugins');
const xml2js = require('xml2js');
const builder = new xml2js.Builder({ headless: true });

const localesFilepath = '../locales';

function withAndroidLocalizedName(config, filepath) {
return withStringsXml(config,
async config => {
// which folders are in the 'localesFilepath' directory?
const locales = await fs.promises.readdir(localesFilepath);

const projectRoot = config.modRequest.projectRoot;
const resPath = await AndroidConfig.Paths.getResourceFolderAsync(projectRoot);
for (const locale of Object.keys(config.locales ?? {})) {
const json = await fs.promises.readFile(config.locales[locale]);
const strings = JSON.parse(json);
const resources = [];
for (const key of Object.keys(strings)) {
// Skip values that are not marked for translation or simply do not exist
// because gradle does not like them
const untranslated = config.modResults.resources.string?.find(item =>
item.$.name === key && item.$.translatable !== false);
if (untranslated)
resources.push({ string: { $: { name: key }, _: strings[key] } });
}
if (resources.length) {
await fs.promises.mkdir(path.resolve(resPath, `values-${locale}`), { recursive: true });
await fs.promises.writeFile(
path.resolve(resPath, `values-${locale}`, 'strings.xml'),
builder.buildObject({ resources })
);
}
}
return config;
},
);
};

module.exports = withAndroidLocalizedName;
62 changes: 62 additions & 0 deletions modules/your-module/android/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
buildscript {
repositories {
google()
mavenCentral()
}

dependencies {
classpath "com.android.tools.build:gradle:7.2.1"
}
}

apply plugin: "com.android.library"

def getExtOrIntegerDefault(name) {
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["YourModule_" + name]).toInteger()
}

android {
namespace "com.yourmodule"

sourceSets {
main {
manifest.srcFile "src/main/AndroidManifest.xml"
}
}

compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")

defaultConfig {
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")

}

buildTypes {
release {
minifyEnabled false
}
}

lintOptions {
disable "GradleCompatible"
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

repositories {
mavenCentral()
google()
}


dependencies {
// For < 0.71, this will be from the local maven repo
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+"
}
2 changes: 2 additions & 0 deletions modules/your-module/android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.yourmodule;

import androidx.annotation.NonNull;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@ReactModule(name = YourModuleModule.TAG)
class YourModuleModule extends ReactContextBaseJavaModule {
public static final String TAG = "YourModule";

public YourModuleModule(ReactApplicationContext reactContext) {
super(reactContext);
}

@Override
@NonNull
public String getName() {
return TAG;
}

// Example method
// See https://reactnative.dev/docs/native-modules-android
@ReactMethod
public void multiply(double a, double b, Promise promise) {
promise.resolve("R.string.hello_world");
}
}

public class YourModulePackage implements ReactPackage {
@NonNull
@Override
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new YourModuleModule(reactContext));
return modules;
}

@NonNull
@Override
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
12 changes: 12 additions & 0 deletions modules/your-module/ios/YourModule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

#ifdef RCT_NEW_ARCH_ENABLED
#import "RNYourModuleSpec.h"

@interface YourModule : NSObject <NativeYourModuleSpec>
#else
#import <React/RCTBridgeModule.h>

@interface YourModule : NSObject <RCTBridgeModule>
#endif

@end
19 changes: 19 additions & 0 deletions modules/your-module/ios/YourModule.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#import "YourModule.h"

@implementation YourModule
RCT_EXPORT_MODULE()

// Example method
// See // https://reactnative.dev/docs/native-modules-ios
RCT_EXPORT_METHOD(multiply:(double)a
b:(double)b
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)
{
NSNumber *result = @(a * b + 2);

resolve(result);
}


@end
24 changes: 24 additions & 0 deletions modules/your-module/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { NativeModules, Platform } from 'react-native';

const LINKING_ERROR =
`The package 'your-module' doesn't seem to be linked. Make sure: \n\n` +
Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
'- You rebuilt the app after installing the package\n' +
'- You are not using Expo Go\n';

const YourModule = NativeModules.YourModule
? NativeModules.YourModule
: new Proxy(
{},
{
get() {
throw new Error(LINKING_ERROR);
},
}
);

export default {
multiply(a: number, b: number): Promise<number> {
return YourModule.multiply(a, b);
}
};
21 changes: 21 additions & 0 deletions modules/your-module/your-module.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require "json"

package = JSON.parse(File.read(File.join(__dir__, "package.json")))

Pod::Spec.new do |s|
s.name = "your-module"
s.version = package["version"]
s.summary = package["description"]
s.homepage = package["homepage"]
s.license = package["license"]
s.authors = package["author"]

s.platforms = { :ios => min_ios_version_supported }
s.source = { :git => "https://github.com/JGreenlee/your-module.git", :tag => "#{s.version}" }

s.source_files = "ios/**/*.{h,m,mm}"

install_modules_dependencies(s)
s.dependency "React-Core"

end
Loading

0 comments on commit 19a7b35

Please sign in to comment.