@pickleball/expo-sdk 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/LICENSE +21 -0
- package/README.md +75 -0
- package/app.plugin.js +6 -0
- package/dist/chunk-VHLUJQG5.js +17 -0
- package/dist/index.cjs +6284 -0
- package/dist/index.d.cts +1436 -0
- package/dist/index.d.ts +1436 -0
- package/dist/index.js +6186 -0
- package/dist/plugin.cjs +153 -0
- package/dist/plugin.d.cts +21 -0
- package/dist/plugin.d.ts +21 -0
- package/dist/plugin.js +131 -0
- package/dist/version.cjs +35 -0
- package/dist/version.d.cts +4 -0
- package/dist/version.d.ts +4 -0
- package/dist/version.js +6 -0
- package/package.json +126 -0
- package/src/contracts.ts +211 -0
- package/src/engine.ts +1332 -0
- package/src/errors.ts +128 -0
- package/src/http-session-provider.ts +259 -0
- package/src/index.ts +16 -0
- package/src/livekit-room-adapter.ts +353 -0
- package/src/livestream-screen.tsx +980 -0
- package/src/match/contracts.ts +137 -0
- package/src/match/engine.ts +702 -0
- package/src/match/persistence/default-store.native.ts +20 -0
- package/src/match/persistence/default-store.ts +11 -0
- package/src/match/persistence/index.ts +6 -0
- package/src/match/persistence/memory-driver.ts +255 -0
- package/src/match/persistence/migrations.ts +40 -0
- package/src/match/persistence/sqlite-driver.ts +348 -0
- package/src/match/persistence/store.ts +497 -0
- package/src/match/persistence/types.ts +98 -0
- package/src/match/provider.tsx +728 -0
- package/src/match/remote/deduplicator.ts +54 -0
- package/src/match/remote/encoding.ts +12 -0
- package/src/match/remote/hid-gesture.ts +61 -0
- package/src/match/remote/index.ts +5 -0
- package/src/match/remote/native-service.ts +62 -0
- package/src/match/remote/parser.ts +134 -0
- package/src/match/remote/types.ts +116 -0
- package/src/match/replay.ts +102 -0
- package/src/match/state.ts +72 -0
- package/src/match/validation.ts +375 -0
- package/src/match/voice/assets/court-left.wav +0 -0
- package/src/match/voice/assets/court-right.wav +0 -0
- package/src/match/voice/assets/court-switch.wav +0 -0
- package/src/match/voice/assets/game-point.wav +0 -0
- package/src/match/voice/assets/game-won.wav +0 -0
- package/src/match/voice/assets/match-won.wav +0 -0
- package/src/match/voice/assets/number-0.wav +0 -0
- package/src/match/voice/assets/number-1.wav +0 -0
- package/src/match/voice/assets/number-10.wav +0 -0
- package/src/match/voice/assets/number-11.wav +0 -0
- package/src/match/voice/assets/number-12.wav +0 -0
- package/src/match/voice/assets/number-13.wav +0 -0
- package/src/match/voice/assets/number-14.wav +0 -0
- package/src/match/voice/assets/number-15.wav +0 -0
- package/src/match/voice/assets/number-16.wav +0 -0
- package/src/match/voice/assets/number-17.wav +0 -0
- package/src/match/voice/assets/number-18.wav +0 -0
- package/src/match/voice/assets/number-19.wav +0 -0
- package/src/match/voice/assets/number-2.wav +0 -0
- package/src/match/voice/assets/number-20.wav +0 -0
- package/src/match/voice/assets/number-3.wav +0 -0
- package/src/match/voice/assets/number-30.wav +0 -0
- package/src/match/voice/assets/number-4.wav +0 -0
- package/src/match/voice/assets/number-40.wav +0 -0
- package/src/match/voice/assets/number-5.wav +0 -0
- package/src/match/voice/assets/number-50.wav +0 -0
- package/src/match/voice/assets/number-6.wav +0 -0
- package/src/match/voice/assets/number-60.wav +0 -0
- package/src/match/voice/assets/number-7.wav +0 -0
- package/src/match/voice/assets/number-70.wav +0 -0
- package/src/match/voice/assets/number-8.wav +0 -0
- package/src/match/voice/assets/number-80.wav +0 -0
- package/src/match/voice/assets/number-9.wav +0 -0
- package/src/match/voice/assets/number-90.wav +0 -0
- package/src/match/voice/assets/number-lam.wav +0 -0
- package/src/match/voice/assets/number-mot.wav +0 -0
- package/src/match/voice/assets/score-deu-0.wav +0 -0
- package/src/match/voice/assets/score-deu-1.wav +0 -0
- package/src/match/voice/assets/score-deu-10.wav +0 -0
- package/src/match/voice/assets/score-deu-11.wav +0 -0
- package/src/match/voice/assets/score-deu-12.wav +0 -0
- package/src/match/voice/assets/score-deu-13.wav +0 -0
- package/src/match/voice/assets/score-deu-14.wav +0 -0
- package/src/match/voice/assets/score-deu-15.wav +0 -0
- package/src/match/voice/assets/score-deu-16.wav +0 -0
- package/src/match/voice/assets/score-deu-17.wav +0 -0
- package/src/match/voice/assets/score-deu-18.wav +0 -0
- package/src/match/voice/assets/score-deu-19.wav +0 -0
- package/src/match/voice/assets/score-deu-2.wav +0 -0
- package/src/match/voice/assets/score-deu-20.wav +0 -0
- package/src/match/voice/assets/score-deu-3.wav +0 -0
- package/src/match/voice/assets/score-deu-30.wav +0 -0
- package/src/match/voice/assets/score-deu-4.wav +0 -0
- package/src/match/voice/assets/score-deu-40.wav +0 -0
- package/src/match/voice/assets/score-deu-5.wav +0 -0
- package/src/match/voice/assets/score-deu-50.wav +0 -0
- package/src/match/voice/assets/score-deu-6.wav +0 -0
- package/src/match/voice/assets/score-deu-60.wav +0 -0
- package/src/match/voice/assets/score-deu-7.wav +0 -0
- package/src/match/voice/assets/score-deu-70.wav +0 -0
- package/src/match/voice/assets/score-deu-8.wav +0 -0
- package/src/match/voice/assets/score-deu-80.wav +0 -0
- package/src/match/voice/assets/score-deu-9.wav +0 -0
- package/src/match/voice/assets/score-deu-90.wav +0 -0
- package/src/match/voice/assets/score-deu-lam.wav +0 -0
- package/src/match/voice/assets/score-deu-mot.wav +0 -0
- package/src/match/voice/assets/server-1.wav +0 -0
- package/src/match/voice/assets/server-2.wav +0 -0
- package/src/match/voice/assets/service-change.wav +0 -0
- package/src/match/voice/assets/test-speaker.wav +0 -0
- package/src/match/voice/audio.ts +231 -0
- package/src/match/voice/bundled-assets.native.ts +47 -0
- package/src/match/voice/bundled-assets.ts +3 -0
- package/src/match/voice/gemini-engine.ts +167 -0
- package/src/match/voice/index.ts +7 -0
- package/src/match/voice/phrases.ts +185 -0
- package/src/match/voice/scheduler.ts +205 -0
- package/src/match/voice/service.ts +147 -0
- package/src/match/voice/types.ts +118 -0
- package/src/native-runtime.ts +241 -0
- package/src/plugin.ts +145 -0
- package/src/provider.tsx +176 -0
- package/src/version.ts +4 -0
package/dist/plugin.cjs
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/plugin.ts
|
|
21
|
+
var plugin_exports = {};
|
|
22
|
+
__export(plugin_exports, {
|
|
23
|
+
default: () => plugin_default,
|
|
24
|
+
injectHidVolumeMainActivity: () => injectHidVolumeMainActivity
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(plugin_exports);
|
|
27
|
+
var import_config_plugins = require("expo/config-plugins");
|
|
28
|
+
var import_promises = require("fs/promises");
|
|
29
|
+
var import_node_path = require("path");
|
|
30
|
+
|
|
31
|
+
// package.json
|
|
32
|
+
var version = "0.1.1";
|
|
33
|
+
|
|
34
|
+
// src/version.ts
|
|
35
|
+
var PICKLEBALL_EXPO_SDK_VERSION = version;
|
|
36
|
+
|
|
37
|
+
// src/plugin.ts
|
|
38
|
+
var ANDROID_PERMISSIONS = [
|
|
39
|
+
"android.permission.ACCESS_NETWORK_STATE",
|
|
40
|
+
"android.permission.BLUETOOTH",
|
|
41
|
+
"android.permission.BLUETOOTH_ADMIN",
|
|
42
|
+
"android.permission.BLUETOOTH_SCAN",
|
|
43
|
+
"android.permission.BLUETOOTH_CONNECT",
|
|
44
|
+
"android.permission.ACCESS_FINE_LOCATION",
|
|
45
|
+
"android.permission.CAMERA",
|
|
46
|
+
"android.permission.INTERNET",
|
|
47
|
+
"android.permission.MODIFY_AUDIO_SETTINGS",
|
|
48
|
+
"android.permission.RECORD_AUDIO",
|
|
49
|
+
"android.permission.WAKE_LOCK"
|
|
50
|
+
];
|
|
51
|
+
function injectHidVolumeMainActivity(source) {
|
|
52
|
+
if (source.includes("PickleballRemoteHidDispatcher.dispatch(event)")) return source;
|
|
53
|
+
if (!/class\s+MainActivity\s*:\s*ReactActivity\(\)\s*\{/.test(source)) {
|
|
54
|
+
throw new Error("Pickleball HID volume integration requires a generated Kotlin MainActivity");
|
|
55
|
+
}
|
|
56
|
+
if (/override\s+fun\s+dispatchKeyEvent/.test(source)) {
|
|
57
|
+
throw new Error("MainActivity already overrides dispatchKeyEvent; forward it to PickleballRemoteHidDispatcher manually");
|
|
58
|
+
}
|
|
59
|
+
let updated = source;
|
|
60
|
+
if (!updated.includes("import android.view.KeyEvent")) {
|
|
61
|
+
updated = updated.replace(/(package\s+[^\n]+\n)/, "$1\nimport android.view.KeyEvent\nimport expo.modules.pickleballremote.PickleballRemoteHidDispatcher\n");
|
|
62
|
+
}
|
|
63
|
+
const closing = updated.lastIndexOf("}");
|
|
64
|
+
return `${updated.slice(0, closing)}
|
|
65
|
+
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
|
66
|
+
if (PickleballRemoteHidDispatcher.dispatch(event)) return true
|
|
67
|
+
return super.dispatchKeyEvent(event)
|
|
68
|
+
}
|
|
69
|
+
${updated.slice(closing)}`;
|
|
70
|
+
}
|
|
71
|
+
async function findMainActivity(directory) {
|
|
72
|
+
for (const entry of await (0, import_promises.readdir)(directory, { withFileTypes: true })) {
|
|
73
|
+
const path = (0, import_node_path.join)(directory, entry.name);
|
|
74
|
+
if (entry.isDirectory()) {
|
|
75
|
+
const found = await findMainActivity(path);
|
|
76
|
+
if (found) return found;
|
|
77
|
+
} else if (entry.name === "MainActivity.kt") return path;
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
var withPickleballLive = (config, props = {}) => {
|
|
82
|
+
const cameraPermission = props?.cameraPermission ?? "Allow $(PRODUCT_NAME) to use the camera for livestreaming.";
|
|
83
|
+
const microphonePermission = props?.microphonePermission ?? "Allow $(PRODUCT_NAME) to use the microphone for livestreaming.";
|
|
84
|
+
const bluetoothPermission = props?.bluetoothPermission ?? "Cho ph\xE9p $(PRODUCT_NAME) d\xF9ng Bluetooth \u0111\u1EC3 nh\u1EADn thao t\xE1c t\u1EEB n\xFAt \u0111i\u1EC1u khi\u1EC3n tr\xEAn s\xE2n.";
|
|
85
|
+
config = (0, import_config_plugins.withPlugins)(config, [
|
|
86
|
+
["@livekit/react-native-expo-plugin", props?.liveKit]
|
|
87
|
+
]);
|
|
88
|
+
config.ios = { ...config.ios, bitcode: false };
|
|
89
|
+
config = (0, import_config_plugins.withInfoPlist)(config, (mod) => {
|
|
90
|
+
mod.modResults.NSCameraUsageDescription = cameraPermission;
|
|
91
|
+
mod.modResults.NSMicrophoneUsageDescription = microphonePermission;
|
|
92
|
+
mod.modResults.NSBluetoothAlwaysUsageDescription = bluetoothPermission;
|
|
93
|
+
return mod;
|
|
94
|
+
});
|
|
95
|
+
config = import_config_plugins.AndroidConfig.Permissions.withPermissions(config, [
|
|
96
|
+
...ANDROID_PERMISSIONS
|
|
97
|
+
]);
|
|
98
|
+
config = (0, import_config_plugins.withAndroidManifest)(config, (mod) => {
|
|
99
|
+
const manifest = mod.modResults.manifest;
|
|
100
|
+
const existing = manifest["uses-permission"] ?? [];
|
|
101
|
+
const requiredAttributes = {
|
|
102
|
+
"android.permission.BLUETOOTH": { "android:maxSdkVersion": "30" },
|
|
103
|
+
"android.permission.BLUETOOTH_ADMIN": { "android:maxSdkVersion": "30" },
|
|
104
|
+
"android.permission.ACCESS_FINE_LOCATION": { "android:maxSdkVersion": "30" },
|
|
105
|
+
"android.permission.BLUETOOTH_SCAN": {
|
|
106
|
+
"android:usesPermissionFlags": "neverForLocation"
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const byName = /* @__PURE__ */ new Map();
|
|
110
|
+
for (const entry of existing) {
|
|
111
|
+
const name = entry.$?.["android:name"];
|
|
112
|
+
if (name && !byName.has(name)) byName.set(name, entry);
|
|
113
|
+
}
|
|
114
|
+
for (const permission of ANDROID_PERMISSIONS) {
|
|
115
|
+
const entry = byName.get(permission) ?? { $: { "android:name": permission } };
|
|
116
|
+
entry.$ = {
|
|
117
|
+
"android:name": permission,
|
|
118
|
+
...requiredAttributes[permission] ?? {}
|
|
119
|
+
};
|
|
120
|
+
byName.set(permission, entry);
|
|
121
|
+
}
|
|
122
|
+
const requiredNames = new Set(ANDROID_PERMISSIONS);
|
|
123
|
+
manifest["uses-permission"] = [
|
|
124
|
+
...existing.filter((entry) => {
|
|
125
|
+
const name = entry.$?.["android:name"];
|
|
126
|
+
return !name || !requiredNames.has(name);
|
|
127
|
+
}),
|
|
128
|
+
...ANDROID_PERMISSIONS.map((name) => byName.get(name))
|
|
129
|
+
];
|
|
130
|
+
return mod;
|
|
131
|
+
});
|
|
132
|
+
if (props?.consumeHidVolumeKeys !== false) {
|
|
133
|
+
config = (0, import_config_plugins.withDangerousMod)(config, ["android", async (mod) => {
|
|
134
|
+
const root = (0, import_node_path.join)(mod.modRequest.platformProjectRoot, "app", "src", "main", "java");
|
|
135
|
+
const path = await findMainActivity(root);
|
|
136
|
+
if (!path) throw new Error("Generated Android MainActivity.kt was not found");
|
|
137
|
+
const source = await (0, import_promises.readFile)(path, "utf8");
|
|
138
|
+
const updated = injectHidVolumeMainActivity(source);
|
|
139
|
+
if (updated !== source) await (0, import_promises.writeFile)(path, updated);
|
|
140
|
+
return mod;
|
|
141
|
+
}]);
|
|
142
|
+
}
|
|
143
|
+
return config;
|
|
144
|
+
};
|
|
145
|
+
var plugin_default = (0, import_config_plugins.createRunOncePlugin)(
|
|
146
|
+
withPickleballLive,
|
|
147
|
+
"@pickleball/expo-sdk",
|
|
148
|
+
PICKLEBALL_EXPO_SDK_VERSION
|
|
149
|
+
);
|
|
150
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
151
|
+
0 && (module.exports = {
|
|
152
|
+
injectHidVolumeMainActivity
|
|
153
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ConfigPlugin } from 'expo/config-plugins';
|
|
2
|
+
|
|
3
|
+
interface PickleballLivePluginProps {
|
|
4
|
+
cameraPermission?: string;
|
|
5
|
+
microphonePermission?: string;
|
|
6
|
+
bluetoothPermission?: string;
|
|
7
|
+
consumeHidVolumeKeys?: boolean;
|
|
8
|
+
liveKit?: {
|
|
9
|
+
android?: {
|
|
10
|
+
audioType?: string;
|
|
11
|
+
enableScreenShareService?: boolean;
|
|
12
|
+
};
|
|
13
|
+
ios?: {
|
|
14
|
+
enableMultitaskingCameraAccess?: boolean;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
declare function injectHidVolumeMainActivity(source: string): string;
|
|
19
|
+
declare const _default: ConfigPlugin<PickleballLivePluginProps | undefined>;
|
|
20
|
+
|
|
21
|
+
export { type PickleballLivePluginProps, _default as default, injectHidVolumeMainActivity };
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ConfigPlugin } from 'expo/config-plugins';
|
|
2
|
+
|
|
3
|
+
interface PickleballLivePluginProps {
|
|
4
|
+
cameraPermission?: string;
|
|
5
|
+
microphonePermission?: string;
|
|
6
|
+
bluetoothPermission?: string;
|
|
7
|
+
consumeHidVolumeKeys?: boolean;
|
|
8
|
+
liveKit?: {
|
|
9
|
+
android?: {
|
|
10
|
+
audioType?: string;
|
|
11
|
+
enableScreenShareService?: boolean;
|
|
12
|
+
};
|
|
13
|
+
ios?: {
|
|
14
|
+
enableMultitaskingCameraAccess?: boolean;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
declare function injectHidVolumeMainActivity(source: string): string;
|
|
19
|
+
declare const _default: ConfigPlugin<PickleballLivePluginProps | undefined>;
|
|
20
|
+
|
|
21
|
+
export { type PickleballLivePluginProps, _default as default, injectHidVolumeMainActivity };
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PICKLEBALL_EXPO_SDK_VERSION
|
|
3
|
+
} from "./chunk-VHLUJQG5.js";
|
|
4
|
+
|
|
5
|
+
// src/plugin.ts
|
|
6
|
+
import {
|
|
7
|
+
AndroidConfig,
|
|
8
|
+
createRunOncePlugin,
|
|
9
|
+
withAndroidManifest,
|
|
10
|
+
withDangerousMod,
|
|
11
|
+
withInfoPlist,
|
|
12
|
+
withPlugins
|
|
13
|
+
} from "expo/config-plugins";
|
|
14
|
+
import { readdir, readFile, writeFile } from "fs/promises";
|
|
15
|
+
import { join } from "path";
|
|
16
|
+
var ANDROID_PERMISSIONS = [
|
|
17
|
+
"android.permission.ACCESS_NETWORK_STATE",
|
|
18
|
+
"android.permission.BLUETOOTH",
|
|
19
|
+
"android.permission.BLUETOOTH_ADMIN",
|
|
20
|
+
"android.permission.BLUETOOTH_SCAN",
|
|
21
|
+
"android.permission.BLUETOOTH_CONNECT",
|
|
22
|
+
"android.permission.ACCESS_FINE_LOCATION",
|
|
23
|
+
"android.permission.CAMERA",
|
|
24
|
+
"android.permission.INTERNET",
|
|
25
|
+
"android.permission.MODIFY_AUDIO_SETTINGS",
|
|
26
|
+
"android.permission.RECORD_AUDIO",
|
|
27
|
+
"android.permission.WAKE_LOCK"
|
|
28
|
+
];
|
|
29
|
+
function injectHidVolumeMainActivity(source) {
|
|
30
|
+
if (source.includes("PickleballRemoteHidDispatcher.dispatch(event)")) return source;
|
|
31
|
+
if (!/class\s+MainActivity\s*:\s*ReactActivity\(\)\s*\{/.test(source)) {
|
|
32
|
+
throw new Error("Pickleball HID volume integration requires a generated Kotlin MainActivity");
|
|
33
|
+
}
|
|
34
|
+
if (/override\s+fun\s+dispatchKeyEvent/.test(source)) {
|
|
35
|
+
throw new Error("MainActivity already overrides dispatchKeyEvent; forward it to PickleballRemoteHidDispatcher manually");
|
|
36
|
+
}
|
|
37
|
+
let updated = source;
|
|
38
|
+
if (!updated.includes("import android.view.KeyEvent")) {
|
|
39
|
+
updated = updated.replace(/(package\s+[^\n]+\n)/, "$1\nimport android.view.KeyEvent\nimport expo.modules.pickleballremote.PickleballRemoteHidDispatcher\n");
|
|
40
|
+
}
|
|
41
|
+
const closing = updated.lastIndexOf("}");
|
|
42
|
+
return `${updated.slice(0, closing)}
|
|
43
|
+
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
|
44
|
+
if (PickleballRemoteHidDispatcher.dispatch(event)) return true
|
|
45
|
+
return super.dispatchKeyEvent(event)
|
|
46
|
+
}
|
|
47
|
+
${updated.slice(closing)}`;
|
|
48
|
+
}
|
|
49
|
+
async function findMainActivity(directory) {
|
|
50
|
+
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
51
|
+
const path = join(directory, entry.name);
|
|
52
|
+
if (entry.isDirectory()) {
|
|
53
|
+
const found = await findMainActivity(path);
|
|
54
|
+
if (found) return found;
|
|
55
|
+
} else if (entry.name === "MainActivity.kt") return path;
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
var withPickleballLive = (config, props = {}) => {
|
|
60
|
+
const cameraPermission = props?.cameraPermission ?? "Allow $(PRODUCT_NAME) to use the camera for livestreaming.";
|
|
61
|
+
const microphonePermission = props?.microphonePermission ?? "Allow $(PRODUCT_NAME) to use the microphone for livestreaming.";
|
|
62
|
+
const bluetoothPermission = props?.bluetoothPermission ?? "Cho ph\xE9p $(PRODUCT_NAME) d\xF9ng Bluetooth \u0111\u1EC3 nh\u1EADn thao t\xE1c t\u1EEB n\xFAt \u0111i\u1EC1u khi\u1EC3n tr\xEAn s\xE2n.";
|
|
63
|
+
config = withPlugins(config, [
|
|
64
|
+
["@livekit/react-native-expo-plugin", props?.liveKit]
|
|
65
|
+
]);
|
|
66
|
+
config.ios = { ...config.ios, bitcode: false };
|
|
67
|
+
config = withInfoPlist(config, (mod) => {
|
|
68
|
+
mod.modResults.NSCameraUsageDescription = cameraPermission;
|
|
69
|
+
mod.modResults.NSMicrophoneUsageDescription = microphonePermission;
|
|
70
|
+
mod.modResults.NSBluetoothAlwaysUsageDescription = bluetoothPermission;
|
|
71
|
+
return mod;
|
|
72
|
+
});
|
|
73
|
+
config = AndroidConfig.Permissions.withPermissions(config, [
|
|
74
|
+
...ANDROID_PERMISSIONS
|
|
75
|
+
]);
|
|
76
|
+
config = withAndroidManifest(config, (mod) => {
|
|
77
|
+
const manifest = mod.modResults.manifest;
|
|
78
|
+
const existing = manifest["uses-permission"] ?? [];
|
|
79
|
+
const requiredAttributes = {
|
|
80
|
+
"android.permission.BLUETOOTH": { "android:maxSdkVersion": "30" },
|
|
81
|
+
"android.permission.BLUETOOTH_ADMIN": { "android:maxSdkVersion": "30" },
|
|
82
|
+
"android.permission.ACCESS_FINE_LOCATION": { "android:maxSdkVersion": "30" },
|
|
83
|
+
"android.permission.BLUETOOTH_SCAN": {
|
|
84
|
+
"android:usesPermissionFlags": "neverForLocation"
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const byName = /* @__PURE__ */ new Map();
|
|
88
|
+
for (const entry of existing) {
|
|
89
|
+
const name = entry.$?.["android:name"];
|
|
90
|
+
if (name && !byName.has(name)) byName.set(name, entry);
|
|
91
|
+
}
|
|
92
|
+
for (const permission of ANDROID_PERMISSIONS) {
|
|
93
|
+
const entry = byName.get(permission) ?? { $: { "android:name": permission } };
|
|
94
|
+
entry.$ = {
|
|
95
|
+
"android:name": permission,
|
|
96
|
+
...requiredAttributes[permission] ?? {}
|
|
97
|
+
};
|
|
98
|
+
byName.set(permission, entry);
|
|
99
|
+
}
|
|
100
|
+
const requiredNames = new Set(ANDROID_PERMISSIONS);
|
|
101
|
+
manifest["uses-permission"] = [
|
|
102
|
+
...existing.filter((entry) => {
|
|
103
|
+
const name = entry.$?.["android:name"];
|
|
104
|
+
return !name || !requiredNames.has(name);
|
|
105
|
+
}),
|
|
106
|
+
...ANDROID_PERMISSIONS.map((name) => byName.get(name))
|
|
107
|
+
];
|
|
108
|
+
return mod;
|
|
109
|
+
});
|
|
110
|
+
if (props?.consumeHidVolumeKeys !== false) {
|
|
111
|
+
config = withDangerousMod(config, ["android", async (mod) => {
|
|
112
|
+
const root = join(mod.modRequest.platformProjectRoot, "app", "src", "main", "java");
|
|
113
|
+
const path = await findMainActivity(root);
|
|
114
|
+
if (!path) throw new Error("Generated Android MainActivity.kt was not found");
|
|
115
|
+
const source = await readFile(path, "utf8");
|
|
116
|
+
const updated = injectHidVolumeMainActivity(source);
|
|
117
|
+
if (updated !== source) await writeFile(path, updated);
|
|
118
|
+
return mod;
|
|
119
|
+
}]);
|
|
120
|
+
}
|
|
121
|
+
return config;
|
|
122
|
+
};
|
|
123
|
+
var plugin_default = createRunOncePlugin(
|
|
124
|
+
withPickleballLive,
|
|
125
|
+
"@pickleball/expo-sdk",
|
|
126
|
+
PICKLEBALL_EXPO_SDK_VERSION
|
|
127
|
+
);
|
|
128
|
+
export {
|
|
129
|
+
plugin_default as default,
|
|
130
|
+
injectHidVolumeMainActivity
|
|
131
|
+
};
|
package/dist/version.cjs
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/version.ts
|
|
21
|
+
var version_exports = {};
|
|
22
|
+
__export(version_exports, {
|
|
23
|
+
PICKLEBALL_EXPO_SDK_VERSION: () => PICKLEBALL_EXPO_SDK_VERSION
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(version_exports);
|
|
26
|
+
|
|
27
|
+
// package.json
|
|
28
|
+
var version = "0.1.1";
|
|
29
|
+
|
|
30
|
+
// src/version.ts
|
|
31
|
+
var PICKLEBALL_EXPO_SDK_VERSION = version;
|
|
32
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
33
|
+
0 && (module.exports = {
|
|
34
|
+
PICKLEBALL_EXPO_SDK_VERSION
|
|
35
|
+
});
|
package/dist/version.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pickleball/expo-sdk",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Foreground livestream engine, React hooks, UI, and Expo config plugin for Pickleball Live",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/Cabinfood/livestream-pickleball.git",
|
|
9
|
+
"directory": "packages/expo-sdk"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/Cabinfood/livestream-pickleball#readme",
|
|
12
|
+
"bugs": "https://github.com/Cabinfood/livestream-pickleball/issues",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.cjs",
|
|
15
|
+
"module": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"react-native": "./src/index.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"react-native": "./src/index.ts",
|
|
21
|
+
"import": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"default": "./dist/index.js"
|
|
24
|
+
},
|
|
25
|
+
"require": {
|
|
26
|
+
"types": "./dist/index.d.cts",
|
|
27
|
+
"default": "./dist/index.cjs"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"./plugin": {
|
|
31
|
+
"import": {
|
|
32
|
+
"types": "./dist/plugin.d.ts",
|
|
33
|
+
"default": "./dist/plugin.js"
|
|
34
|
+
},
|
|
35
|
+
"require": {
|
|
36
|
+
"types": "./dist/plugin.d.cts",
|
|
37
|
+
"default": "./dist/plugin.cjs"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"./version": {
|
|
41
|
+
"react-native": "./src/version.ts",
|
|
42
|
+
"import": {
|
|
43
|
+
"types": "./dist/version.d.ts",
|
|
44
|
+
"default": "./dist/version.js"
|
|
45
|
+
},
|
|
46
|
+
"require": {
|
|
47
|
+
"types": "./dist/version.d.cts",
|
|
48
|
+
"default": "./dist/version.cjs"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"files": [
|
|
53
|
+
"dist",
|
|
54
|
+
"src",
|
|
55
|
+
"app.plugin.js",
|
|
56
|
+
"README.md",
|
|
57
|
+
"LICENSE",
|
|
58
|
+
"CHANGELOG.md"
|
|
59
|
+
],
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public"
|
|
62
|
+
},
|
|
63
|
+
"keywords": [
|
|
64
|
+
"expo",
|
|
65
|
+
"react-native",
|
|
66
|
+
"livekit",
|
|
67
|
+
"livestream",
|
|
68
|
+
"video"
|
|
69
|
+
],
|
|
70
|
+
"sideEffects": [
|
|
71
|
+
"./dist/native-runtime.*"
|
|
72
|
+
],
|
|
73
|
+
"peerDependencies": {
|
|
74
|
+
"@livekit/react-native": ">=2.11.1 <3",
|
|
75
|
+
"@livekit/react-native-webrtc": ">=144.1.1 <145",
|
|
76
|
+
"@react-native-community/netinfo": ">=11 <13",
|
|
77
|
+
"expo": ">=56 <58",
|
|
78
|
+
"expo-audio": ">=56 <58",
|
|
79
|
+
"expo-file-system": ">=56 <58",
|
|
80
|
+
"expo-keep-awake": ">=55 <58",
|
|
81
|
+
"expo-sqlite": ">=55 <58",
|
|
82
|
+
"livekit-client": ">=2.20.1 <3",
|
|
83
|
+
"react": ">=19 <20",
|
|
84
|
+
"react-native": ">=0.85 <0.87",
|
|
85
|
+
"react-native-safe-area-context": ">=5 <6"
|
|
86
|
+
},
|
|
87
|
+
"dependencies": {
|
|
88
|
+
"@livekit/react-native-expo-plugin": "1.0.2",
|
|
89
|
+
"expo-speech": "^57.0.1",
|
|
90
|
+
"@pickleball/remote-native": "0.1.0",
|
|
91
|
+
"@pickleball/voice-native": "0.1.0"
|
|
92
|
+
},
|
|
93
|
+
"devDependencies": {
|
|
94
|
+
"@expo/config-plugins": "~57.0.0",
|
|
95
|
+
"@livekit/react-native": "2.11.1",
|
|
96
|
+
"@livekit/react-native-webrtc": "144.1.1",
|
|
97
|
+
"@react-native-community/netinfo": "12.0.1",
|
|
98
|
+
"@testing-library/react-native": "^13.3.3",
|
|
99
|
+
"@types/jest": "^29.5.14",
|
|
100
|
+
"@types/node": "^22.15.0",
|
|
101
|
+
"@types/react": "~19.2.2",
|
|
102
|
+
"expo": "57.0.4",
|
|
103
|
+
"expo-audio": "57.0.2",
|
|
104
|
+
"expo-file-system": "57.0.0",
|
|
105
|
+
"expo-keep-awake": "57.0.0",
|
|
106
|
+
"expo-sqlite": "57.0.0",
|
|
107
|
+
"jest": "^29.7.0",
|
|
108
|
+
"jest-expo": "~57.0.0",
|
|
109
|
+
"livekit-client": "2.20.1",
|
|
110
|
+
"react": "19.2.3",
|
|
111
|
+
"react-dom": "19.2.3",
|
|
112
|
+
"react-native": "0.86.0",
|
|
113
|
+
"react-native-safe-area-context": "~5.7.0",
|
|
114
|
+
"react-test-renderer": "19.2.3",
|
|
115
|
+
"tsup": "^8.5.0",
|
|
116
|
+
"typescript": "^5.8.0",
|
|
117
|
+
"@pickleball/shared": "0.1.0"
|
|
118
|
+
},
|
|
119
|
+
"scripts": {
|
|
120
|
+
"build": "tsup src/index.ts src/plugin.ts src/version.ts --format esm,cjs --dts --clean --external react --external react-native --external expo --external expo-sqlite --external livekit-client --external @livekit/react-native --external @livekit/react-native-webrtc",
|
|
121
|
+
"test": "jest --runInBand",
|
|
122
|
+
"typecheck": "tsc --noEmit",
|
|
123
|
+
"verify:pack": "node scripts/verify-pack.mjs",
|
|
124
|
+
"verify:consumer": "node scripts/verify-consumer.mjs"
|
|
125
|
+
}
|
|
126
|
+
}
|