create-pika-minigame 1.1.0 → 1.3.0
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/bin/cli.js +15 -31
- package/package.json +1 -1
- package/templates/README.md +3 -5
- package/templates/dev/MockHost.ts +49 -21
package/bin/cli.js
CHANGED
|
@@ -103,42 +103,33 @@ function patchPodfile(projectDir) {
|
|
|
103
103
|
|
|
104
104
|
let content = fs.readFileSync(podfilePath, 'utf8');
|
|
105
105
|
|
|
106
|
-
// Add fmt
|
|
106
|
+
// Add fmt auto-patch to post_install
|
|
107
107
|
const fmtFix = `
|
|
108
|
-
# Fix fmt
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
108
|
+
# Fix fmt consteval issue with newer Xcode (auto-patch)
|
|
109
|
+
fmt_base_h = File.join(__dir__, 'Pods/fmt/include/fmt/base.h')
|
|
110
|
+
if File.exist?(fmt_base_h)
|
|
111
|
+
content = File.read(fmt_base_h)
|
|
112
|
+
patched = content.gsub(
|
|
113
|
+
/#elif defined\\(__apple_build_version__\\) && __apple_build_version__ < \\d+L/,
|
|
114
|
+
'#elif defined(__apple_build_version__)'
|
|
115
|
+
)
|
|
116
|
+
if content != patched
|
|
117
|
+
File.write(fmt_base_h, patched)
|
|
118
|
+
Pod::UI.puts "Patched fmt/base.h for Xcode compatibility".green
|
|
113
119
|
end
|
|
114
120
|
end`;
|
|
115
121
|
|
|
116
|
-
// Insert
|
|
122
|
+
// Insert after react_native_post_install
|
|
117
123
|
if (content.includes('react_native_post_install')) {
|
|
118
124
|
content = content.replace(
|
|
119
125
|
/(react_native_post_install\([^)]+\))/,
|
|
120
126
|
`$1\n${fmtFix}`
|
|
121
127
|
);
|
|
122
128
|
fs.writeFileSync(podfilePath, content);
|
|
123
|
-
log.success('Patched Podfile with fmt fix');
|
|
129
|
+
log.success('Patched Podfile with auto fmt fix');
|
|
124
130
|
}
|
|
125
131
|
}
|
|
126
132
|
|
|
127
|
-
function createPostInstallScript(projectDir) {
|
|
128
|
-
const scriptContent = `#!/bin/bash
|
|
129
|
-
# Fix fmt consteval issue for Xcode compatibility
|
|
130
|
-
FMT_BASE_H="ios/Pods/fmt/include/fmt/base.h"
|
|
131
|
-
if [ -f "$FMT_BASE_H" ]; then
|
|
132
|
-
sed -i '' 's/__apple_build_version__ < 14000029L/__apple_build_version__/' "$FMT_BASE_H"
|
|
133
|
-
echo "Patched fmt base.h for Xcode compatibility"
|
|
134
|
-
fi
|
|
135
|
-
`;
|
|
136
|
-
|
|
137
|
-
const scriptPath = path.join(projectDir, 'scripts', 'fix-fmt.sh');
|
|
138
|
-
fs.mkdirSync(path.join(projectDir, 'scripts'), { recursive: true });
|
|
139
|
-
fs.writeFileSync(scriptPath, scriptContent);
|
|
140
|
-
fs.chmodSync(scriptPath, '755');
|
|
141
|
-
}
|
|
142
133
|
|
|
143
134
|
function main() {
|
|
144
135
|
const args = process.argv.slice(2);
|
|
@@ -225,7 +216,6 @@ ${colors.reset}
|
|
|
225
216
|
// Step 3: Patch Podfile for fmt compatibility
|
|
226
217
|
log.step(3, 'Patching for Xcode compatibility...');
|
|
227
218
|
patchPodfile(targetDir);
|
|
228
|
-
createPostInstallScript(targetDir);
|
|
229
219
|
|
|
230
220
|
// Step 4: Update package.json with additional dependencies
|
|
231
221
|
log.step(4, 'Updating package.json...');
|
|
@@ -240,11 +230,7 @@ ${colors.reset}
|
|
|
240
230
|
'react-native-safe-area-context': '4.12.0',
|
|
241
231
|
};
|
|
242
232
|
|
|
243
|
-
|
|
244
|
-
...pkg.scripts,
|
|
245
|
-
'fix-fmt': './scripts/fix-fmt.sh',
|
|
246
|
-
'postinstall:ios': 'cd ios && pod install && cd .. && npm run fix-fmt',
|
|
247
|
-
};
|
|
233
|
+
// No additional scripts needed - fmt fix is automatic in Podfile
|
|
248
234
|
|
|
249
235
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
250
236
|
|
|
@@ -258,7 +244,6 @@ ${colors.bright}Next steps:${colors.reset}
|
|
|
258
244
|
${colors.cyan}cd ${projectName}${colors.reset}
|
|
259
245
|
${colors.cyan}npm install --legacy-peer-deps${colors.reset}
|
|
260
246
|
${colors.cyan}cd ios && pod install && cd ..${colors.reset}
|
|
261
|
-
${colors.cyan}./scripts/fix-fmt.sh${colors.reset} ${colors.yellow}# Fix Xcode compatibility${colors.reset}
|
|
262
247
|
${colors.cyan}npm run ios${colors.reset}
|
|
263
248
|
|
|
264
249
|
${colors.bright}Available commands:${colors.reset}
|
|
@@ -271,7 +256,6 @@ ${colors.bright}Project structure:${colors.reset}
|
|
|
271
256
|
|
|
272
257
|
src/ Game source code (edit this!)
|
|
273
258
|
dev/ Development helpers (MockHost)
|
|
274
|
-
scripts/ Build scripts
|
|
275
259
|
|
|
276
260
|
Happy coding! ${colors.yellow}🎮${colors.reset}
|
|
277
261
|
`);
|
package/package.json
CHANGED
package/templates/README.md
CHANGED
|
@@ -8,12 +8,9 @@ Pika Mini-Game built with React Native 0.77
|
|
|
8
8
|
# Install dependencies
|
|
9
9
|
npm install --legacy-peer-deps
|
|
10
10
|
|
|
11
|
-
# iOS setup
|
|
11
|
+
# iOS setup (auto-patches Xcode compatibility)
|
|
12
12
|
cd ios && pod install && cd ..
|
|
13
13
|
|
|
14
|
-
# Fix Xcode compatibility (IMPORTANT!)
|
|
15
|
-
./scripts/fix-fmt.sh
|
|
16
|
-
|
|
17
14
|
# Run
|
|
18
15
|
npm run ios
|
|
19
16
|
```
|
|
@@ -142,8 +139,9 @@ const App: React.FC<GameProps> = ({ host }) => {
|
|
|
142
139
|
|
|
143
140
|
### Xcode fmt errors
|
|
144
141
|
|
|
142
|
+
Re-run pod install (it auto-patches):
|
|
145
143
|
```bash
|
|
146
|
-
|
|
144
|
+
cd ios && rm -rf Pods Podfile.lock && pod install && cd ..
|
|
147
145
|
# Then in Xcode: Cmd+Shift+K (Clean), Cmd+R (Run)
|
|
148
146
|
```
|
|
149
147
|
|
|
@@ -9,6 +9,19 @@ import { HostBridge, PronunciationResult } from '../src/types';
|
|
|
9
9
|
|
|
10
10
|
// Simulate recording state
|
|
11
11
|
let isRecording = false;
|
|
12
|
+
let recordingStartTime = 0;
|
|
13
|
+
|
|
14
|
+
// Configure mock behavior (edit these for testing)
|
|
15
|
+
const MOCK_CONFIG = {
|
|
16
|
+
// Set to a number (0-100) to always return this score, or null for random
|
|
17
|
+
fixedScore: null as number | null,
|
|
18
|
+
// Minimum recording time in ms (like real API)
|
|
19
|
+
minRecordingMs: 700,
|
|
20
|
+
// Simulate network delay range [min, max] ms
|
|
21
|
+
networkDelay: [800, 1300] as [number, number],
|
|
22
|
+
// Chance to throw error (0-1), set > 0 to test error handling
|
|
23
|
+
errorChance: 0,
|
|
24
|
+
};
|
|
12
25
|
|
|
13
26
|
/**
|
|
14
27
|
* Generate a random score for testing different UI states.
|
|
@@ -43,41 +56,56 @@ export const mockHost: HostBridge = {
|
|
|
43
56
|
}
|
|
44
57
|
console.log('[MockHost] 🎤 Recording started...');
|
|
45
58
|
isRecording = true;
|
|
59
|
+
recordingStartTime = Date.now();
|
|
46
60
|
// Simulate recording initialization delay
|
|
47
61
|
await delay(100);
|
|
48
62
|
},
|
|
49
63
|
|
|
50
|
-
stopAndCheck: async (
|
|
64
|
+
stopAndCheck: async (targetText: string): Promise<PronunciationResult> => {
|
|
51
65
|
if (!isRecording) {
|
|
52
66
|
console.warn('[MockHost] Not recording');
|
|
53
67
|
throw new Error('Not recording');
|
|
54
68
|
}
|
|
55
69
|
|
|
56
|
-
|
|
70
|
+
const elapsed = Date.now() - recordingStartTime;
|
|
71
|
+
console.log(`[MockHost] 🛑 Recording stopped (${elapsed}ms). Checking: "${targetText}"`);
|
|
57
72
|
isRecording = false;
|
|
58
73
|
|
|
59
|
-
//
|
|
60
|
-
|
|
74
|
+
// Check minimum recording time (like real API)
|
|
75
|
+
if (elapsed < MOCK_CONFIG.minRecordingMs) {
|
|
76
|
+
throw new Error('Giữ nút lâu hơn (1–2 giây) rồi nói to, rõ nhé.');
|
|
77
|
+
}
|
|
61
78
|
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
79
|
+
// Simulate random errors for testing
|
|
80
|
+
if (MOCK_CONFIG.errorChance > 0 && Math.random() < MOCK_CONFIG.errorChance) {
|
|
81
|
+
throw new Error('Chưa nghe rõ, thử lại nhé');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Simulate network delay
|
|
85
|
+
const [minDelay, maxDelay] = MOCK_CONFIG.networkDelay;
|
|
86
|
+
await delay(minDelay + Math.random() * (maxDelay - minDelay));
|
|
87
|
+
|
|
88
|
+
// Split into words (real API does this)
|
|
89
|
+
const wordList = targetText.trim().split(/\s+/);
|
|
90
|
+
|
|
91
|
+
// Generate scores for each word
|
|
92
|
+
const words = wordList.map((word) => {
|
|
93
|
+
const letters = generateLetterScores(word);
|
|
94
|
+
// Use fixed score if configured, otherwise use average of letters
|
|
95
|
+
const wordScore = MOCK_CONFIG.fixedScore ?? Math.round(
|
|
96
|
+
letters.reduce((sum, l) => sum + l.score, 0) / letters.length
|
|
97
|
+
);
|
|
98
|
+
return { word, score: wordScore, letters };
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Total score is average of all words
|
|
102
|
+
const totalScore = MOCK_CONFIG.fixedScore ?? Math.round(
|
|
103
|
+
words.reduce((sum, w) => sum + w.score, 0) / words.length
|
|
67
104
|
);
|
|
68
105
|
|
|
69
|
-
console.log(`[MockHost] ✅ Score: ${totalScore}`);
|
|
70
|
-
|
|
71
|
-
return {
|
|
72
|
-
totalScore,
|
|
73
|
-
words: [
|
|
74
|
-
{
|
|
75
|
-
word: targetWord,
|
|
76
|
-
score: wordScore,
|
|
77
|
-
letters,
|
|
78
|
-
},
|
|
79
|
-
],
|
|
80
|
-
};
|
|
106
|
+
console.log(`[MockHost] ✅ Score: ${totalScore} (${words.length} word${words.length > 1 ? 's' : ''})`);
|
|
107
|
+
|
|
108
|
+
return { totalScore, words };
|
|
81
109
|
},
|
|
82
110
|
|
|
83
111
|
cancel: async () => {
|