Update app2.js
Browse files
app2.js
CHANGED
@@ -8,87 +8,33 @@ dotenv.config();
|
|
8 |
|
9 |
const config = {
|
10 |
maxTextLength: 100,
|
11 |
-
|
12 |
-
|
13 |
-
iPhoneUserAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1'
|
14 |
};
|
15 |
|
16 |
let defaultBrowser, defaultPage, iPhoneBrowser, iPhonePage;
|
17 |
|
18 |
-
const createBrowserContext = async (isIPhone = false) => {
|
19 |
-
const browser = await chromium.launch({ headless: true });
|
20 |
-
const contextOptions = isIPhone ? {
|
21 |
-
...devices['iPhone 13'],
|
22 |
-
deviceScaleFactor: 2,
|
23 |
-
isMobile: true,
|
24 |
-
hasTouch: true,
|
25 |
-
userAgent: config.iPhoneUserAgent,
|
26 |
-
forcedColors: 'none',
|
27 |
-
viewport: { width: 390, height: 844 } // iPhone 13 dimensions
|
28 |
-
} : {
|
29 |
-
viewport: config.viewport,
|
30 |
-
userAgent: config.defaultUserAgent
|
31 |
-
};
|
32 |
-
|
33 |
-
const context = await browser.newContext(contextOptions);
|
34 |
-
|
35 |
-
// Block unnecessary resources
|
36 |
-
await context.route('**/*', (route) => {
|
37 |
-
const url = route.request().url();
|
38 |
-
if (url.endsWith('.png') || url.endsWith('.jpg') || url.includes('google-analytics')) {
|
39 |
-
return route.abort();
|
40 |
-
}
|
41 |
-
route.continue();
|
42 |
-
});
|
43 |
-
|
44 |
-
const page = await context.newPage();
|
45 |
-
|
46 |
-
// Add iPhone-specific styles for emoji if needed
|
47 |
-
if (isIPhone) {
|
48 |
-
await page.addStyleTag({
|
49 |
-
content: `
|
50 |
-
@font-face {
|
51 |
-
font-family: "Apple Color Emoji";
|
52 |
-
src: local("Apple Color Emoji");
|
53 |
-
}
|
54 |
-
* {
|
55 |
-
font-family: "Apple Color Emoji", -apple-system, BlinkMacSystemFont, "SF Pro", "SF Pro Display", system-ui, sans-serif !important;
|
56 |
-
-webkit-font-smoothing: antialiased;
|
57 |
-
text-rendering: optimizeLegibility;
|
58 |
-
}
|
59 |
-
#textInput, #textOverlay {
|
60 |
-
font-family: "Apple Color Emoji", -apple-system, BlinkMacSystemFont, "SF Pro", "SF Pro Display", system-ui, sans-serif !important;
|
61 |
-
}
|
62 |
-
`
|
63 |
-
});
|
64 |
-
}
|
65 |
-
|
66 |
-
await page.goto('https://www.bratgenerator.com/', {
|
67 |
-
waitUntil: 'networkidle',
|
68 |
-
timeout: 30000
|
69 |
-
});
|
70 |
-
|
71 |
-
try {
|
72 |
-
await page.click('#onetrust-accept-btn-handler', { timeout: 2000 });
|
73 |
-
} catch {}
|
74 |
-
|
75 |
-
await page.evaluate(() => setupTheme('white'));
|
76 |
-
|
77 |
-
return { browser, page };
|
78 |
-
};
|
79 |
-
|
80 |
const utils = {
|
81 |
async initialize() {
|
82 |
if (!defaultBrowser) {
|
83 |
-
|
84 |
-
|
85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
}
|
87 |
},
|
88 |
|
89 |
async generateBrat(text) {
|
90 |
await defaultPage.fill('#textInput', text);
|
91 |
-
await defaultPage.waitForTimeout(500);
|
92 |
const overlay = defaultPage.locator('#textOverlay');
|
93 |
return overlay.screenshot({ timeout: 5000 });
|
94 |
},
|
@@ -101,17 +47,128 @@ const utils = {
|
|
101 |
const utils2 = {
|
102 |
async initialize() {
|
103 |
if (!iPhoneBrowser) {
|
104 |
-
|
105 |
-
|
106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
}
|
108 |
},
|
109 |
|
110 |
async generateBrat(text) {
|
111 |
await iPhonePage.fill('#textInput', text);
|
112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
const overlay = iPhonePage.locator('#textOverlay');
|
114 |
-
return overlay.screenshot({
|
|
|
|
|
|
|
115 |
},
|
116 |
|
117 |
async close() {
|
|
|
8 |
|
9 |
const config = {
|
10 |
maxTextLength: 100,
|
11 |
+
defaultViewport: { width: 1920, height: 1080 },
|
12 |
+
iPhoneViewport: { width: 390, height: 844 }
|
|
|
13 |
};
|
14 |
|
15 |
let defaultBrowser, defaultPage, iPhoneBrowser, iPhonePage;
|
16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
const utils = {
|
18 |
async initialize() {
|
19 |
if (!defaultBrowser) {
|
20 |
+
defaultBrowser = await chromium.launch({ headless: true });
|
21 |
+
const context = await defaultBrowser.newContext({
|
22 |
+
viewport: config.defaultViewport
|
23 |
+
});
|
24 |
+
defaultPage = await context.newPage();
|
25 |
+
await defaultPage.goto('https://www.bratgenerator.com/', {
|
26 |
+
waitUntil: 'networkidle'
|
27 |
+
});
|
28 |
+
try {
|
29 |
+
await defaultPage.click('#onetrust-accept-btn-handler', { timeout: 2000 });
|
30 |
+
} catch {}
|
31 |
+
await defaultPage.evaluate(() => setupTheme('white'));
|
32 |
}
|
33 |
},
|
34 |
|
35 |
async generateBrat(text) {
|
36 |
await defaultPage.fill('#textInput', text);
|
37 |
+
await defaultPage.waitForTimeout(500);
|
38 |
const overlay = defaultPage.locator('#textOverlay');
|
39 |
return overlay.screenshot({ timeout: 5000 });
|
40 |
},
|
|
|
47 |
const utils2 = {
|
48 |
async initialize() {
|
49 |
if (!iPhoneBrowser) {
|
50 |
+
iPhoneBrowser = await chromium.launch({ headless: true });
|
51 |
+
|
52 |
+
// Buat context dengan konfigurasi iPhone yang spesifik
|
53 |
+
const context = await iPhoneBrowser.newContext({
|
54 |
+
...devices['iPhone 13 Pro'],
|
55 |
+
locale: 'en-US',
|
56 |
+
deviceScaleFactor: 3,
|
57 |
+
isMobile: true,
|
58 |
+
hasTouch: true,
|
59 |
+
colorScheme: 'light',
|
60 |
+
forcedColors: 'none',
|
61 |
+
viewport: config.iPhoneViewport,
|
62 |
+
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1'
|
63 |
+
});
|
64 |
+
|
65 |
+
iPhonePage = await context.newPage();
|
66 |
+
|
67 |
+
// Inject necessary meta tags and CSS
|
68 |
+
await iPhonePage.route('**/*', async route => {
|
69 |
+
if (route.request().resourceType() === 'document') {
|
70 |
+
const response = await route.fetch();
|
71 |
+
const text = await response.text();
|
72 |
+
const modifiedHtml = text.replace('</head>',
|
73 |
+
`<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
74 |
+
<style>
|
75 |
+
@font-face {
|
76 |
+
font-family: 'Apple Color Emoji';
|
77 |
+
src: local('Apple Color Emoji');
|
78 |
+
unicode-range: U+1F300-1F9FF;
|
79 |
+
}
|
80 |
+
* {
|
81 |
+
font-family: -apple-system !important;
|
82 |
+
}
|
83 |
+
#textInput, #textOverlay {
|
84 |
+
font-family: -apple-system !important;
|
85 |
+
-webkit-text-size-adjust: 100%;
|
86 |
+
text-size-adjust: 100%;
|
87 |
+
}
|
88 |
+
.emoji {
|
89 |
+
font-family: 'Apple Color Emoji' !important;
|
90 |
+
}
|
91 |
+
</style>
|
92 |
+
</head>`
|
93 |
+
);
|
94 |
+
route.fulfill({
|
95 |
+
response,
|
96 |
+
body: modifiedHtml,
|
97 |
+
headers: {
|
98 |
+
...response.headers(),
|
99 |
+
'content-type': 'text/html'
|
100 |
+
}
|
101 |
+
});
|
102 |
+
} else {
|
103 |
+
route.continue();
|
104 |
+
}
|
105 |
+
});
|
106 |
+
|
107 |
+
await iPhonePage.goto('https://www.bratgenerator.com/', {
|
108 |
+
waitUntil: 'networkidle',
|
109 |
+
timeout: 30000
|
110 |
+
});
|
111 |
+
|
112 |
+
// Set viewport dan emulasi perangkat
|
113 |
+
await iPhonePage.setViewportSize(config.iPhoneViewport);
|
114 |
+
|
115 |
+
// Inject script untuk mengubah emoji
|
116 |
+
await iPhonePage.addScriptTag({
|
117 |
+
content: `
|
118 |
+
function replaceWithEmojiSpans() {
|
119 |
+
const textInput = document.querySelector('#textInput');
|
120 |
+
const textOverlay = document.querySelector('#textOverlay');
|
121 |
+
|
122 |
+
if (textInput && textOverlay) {
|
123 |
+
const emojiRegex = /[\u{1F300}-\u{1F9FF}]/gu;
|
124 |
+
const wrapEmojisWithSpan = (text) => {
|
125 |
+
return text.replace(emojiRegex, match =>
|
126 |
+
'<span class="emoji">' + match + '</span>'
|
127 |
+
);
|
128 |
+
};
|
129 |
+
|
130 |
+
const originalHandler = textInput.oninput;
|
131 |
+
textInput.oninput = function(e) {
|
132 |
+
if (originalHandler) originalHandler.call(this, e);
|
133 |
+
textOverlay.innerHTML = wrapEmojisWithSpan(this.value);
|
134 |
+
};
|
135 |
+
}
|
136 |
+
}
|
137 |
+
replaceWithEmojiSpans();
|
138 |
+
`
|
139 |
+
});
|
140 |
+
|
141 |
+
try {
|
142 |
+
await iPhonePage.click('#onetrust-accept-btn-handler', { timeout: 2000 });
|
143 |
+
} catch {}
|
144 |
+
|
145 |
+
await iPhonePage.evaluate(() => setupTheme('white'));
|
146 |
}
|
147 |
},
|
148 |
|
149 |
async generateBrat(text) {
|
150 |
await iPhonePage.fill('#textInput', text);
|
151 |
+
|
152 |
+
// Tunggu animasi dan render selesai
|
153 |
+
await iPhonePage.waitForTimeout(1000);
|
154 |
+
|
155 |
+
// Pastikan emoji sudah di-wrap dengan span
|
156 |
+
await iPhonePage.evaluate((text) => {
|
157 |
+
const textOverlay = document.querySelector('#textOverlay');
|
158 |
+
const emojiRegex = /[\u{1F300}-\u{1F9FF}]/gu;
|
159 |
+
const wrappedText = text.replace(emojiRegex, match =>
|
160 |
+
'<span class="emoji">' + match + '</span>'
|
161 |
+
);
|
162 |
+
textOverlay.innerHTML = wrappedText;
|
163 |
+
}, text);
|
164 |
+
|
165 |
+
await iPhonePage.waitForTimeout(500);
|
166 |
+
|
167 |
const overlay = iPhonePage.locator('#textOverlay');
|
168 |
+
return overlay.screenshot({
|
169 |
+
timeout: 5000,
|
170 |
+
scale: 'device'
|
171 |
+
});
|
172 |
},
|
173 |
|
174 |
async close() {
|