isaikr 0.0.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/README.md +35 -0
- package/cdn/api.js +19 -0
- package/cdn/character.js +254 -0
- package/cdn/chat.js +33 -0
- package/cdn/code-editor.js +1131 -0
- package/cdn/community-compose.js +270 -0
- package/cdn/games/2048/index.html +12 -0
- package/cdn/games/breakout/index.html +13 -0
- package/cdn/games/clicker/index.html +26 -0
- package/cdn/games/flappy/index.html +11 -0
- package/cdn/games/memory/index.html +34 -0
- package/cdn/games/pong/index.html +13 -0
- package/cdn/games/reaction/index.html +38 -0
- package/cdn/games/runner/index.html +11 -0
- package/cdn/games/snake/index.html +11 -0
- package/cdn/games/tetris/index.html +14 -0
- package/cdn/games/whack/index.html +8 -0
- package/cdn/go.js +126 -0
- package/cdn/go2.js +127 -0
- package/cdn/header3_behavior.js +1167 -0
- package/cdn/header3_layout.js +1004 -0
- package/cdn/header3_layout.js.bak +1004 -0
- package/cdn/header3_style.css +3524 -0
- package/cdn/header3_style.css.bak +3514 -0
- package/cdn/lang.js +198 -0
- package/cdn/loading.js +143 -0
- package/cdn/loading2.js +144 -0
- package/cdn/local-model.js +2941 -0
- package/cdn/main.js +4 -0
- package/cdn/main_asset.js +1849 -0
- package/cdn/main_asset.js.bak +6999 -0
- package/cdn/main_index.css +287 -0
- package/cdn/re_board3.css +733 -0
- package/cdn/re_board3.js +734 -0
- package/cdn/re_chat_tts.js +652 -0
- package/cdn/re_local_runtime.js +2246 -0
- package/cdn/re_local_runtime.js.bak +2246 -0
- package/cdn/re_share.js +577 -0
- package/cdn/re_voice.js +542 -0
- package/cdn/utils.js +36 -0
- package/cdn/view.js +321 -0
- package/header3_behavior.js +804 -0
- package/header3_layout.js +998 -0
- package/header3_style.css +2740 -0
- package/index.js +0 -0
- package/lang.js +179 -0
- package/main_asset.js +2416 -0
- package/main_index.css +274 -0
- package/package.json +14 -0
- package/re_chat_tts.js +1419 -0
- package/re_voice.js +430 -0
package/cdn/re_share.js
ADDED
|
@@ -0,0 +1,577 @@
|
|
|
1
|
+
const reShareConfig = window.__ISAI_RE_SHARE_CONFIG__ || {};
|
|
2
|
+
window.savedPrompt = String(reShareConfig.savedPrompt || '').trim();
|
|
3
|
+
const isSharedView = String(reShareConfig.viewId || '');
|
|
4
|
+
|
|
5
|
+
window.addEventListener('load', () => {
|
|
6
|
+
const sharedImg = String(reShareConfig.ogImage || '');
|
|
7
|
+
if (isSharedView && sharedImg && !sharedImg.includes('isailogo2.png')) {
|
|
8
|
+
setTimeout(() => {
|
|
9
|
+
if (typeof setMode === 'function') setMode('image');
|
|
10
|
+
const img = document.getElementById('preview-img');
|
|
11
|
+
const container = document.getElementById('img-preview-container');
|
|
12
|
+
if (img) img.src = sharedImg;
|
|
13
|
+
if (container) {
|
|
14
|
+
container.classList.add('active');
|
|
15
|
+
container.style.setProperty('display', 'block', 'important');
|
|
16
|
+
}
|
|
17
|
+
const appGrid = document.getElementById('app-container');
|
|
18
|
+
if (appGrid) appGrid.style.setProperty('display', 'none', 'important');
|
|
19
|
+
}, 100);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
window.currentShareCache = {};
|
|
24
|
+
window.ISAI_TEMP_SOCIAL_EXPIRE_MINUTES = Math.max(3, Math.min(60, Number(window.ISAI_TEMP_SOCIAL_EXPIRE_MINUTES || 10) || 10));
|
|
25
|
+
|
|
26
|
+
function getCharacterShareI18n() {
|
|
27
|
+
return (window.__ISAI_CHARACTER_SHARE_I18N__ && typeof window.__ISAI_CHARACTER_SHARE_I18N__ === 'object')
|
|
28
|
+
? window.__ISAI_CHARACTER_SHARE_I18N__
|
|
29
|
+
: {};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getImageReportI18n() {
|
|
33
|
+
return (window.__ISAI_IMAGE_REPORT_I18N__ && typeof window.__ISAI_IMAGE_REPORT_I18N__ === 'object')
|
|
34
|
+
? window.__ISAI_IMAGE_REPORT_I18N__
|
|
35
|
+
: {};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getSharePromptText() {
|
|
39
|
+
const inputElement = document.getElementById('prompt-input');
|
|
40
|
+
let promptText = inputElement ? String(inputElement.value || '').trim() : '';
|
|
41
|
+
if (!promptText || promptText === '...') {
|
|
42
|
+
promptText = window.currentImagePrompt || window.savedPrompt || 'AI Generated Art';
|
|
43
|
+
}
|
|
44
|
+
return promptText.replace(/\s-\s\d{4}-\d{2}-\d{2}.*$/, '').trim();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function buildShareCacheKey(currentSrc, promptText, options = {}) {
|
|
48
|
+
const persona = (options && typeof options.persona === 'object' && options.persona) ? options.persona : {};
|
|
49
|
+
return [
|
|
50
|
+
String(options.storageMode || 'imgur_if_needed'),
|
|
51
|
+
String(options.shareKind || 'gallery'),
|
|
52
|
+
options.reuseExistingPage === false ? 'new' : 'reuse',
|
|
53
|
+
String(currentSrc || ''),
|
|
54
|
+
String(promptText || ''),
|
|
55
|
+
String(persona.name || ''),
|
|
56
|
+
String(persona.age || ''),
|
|
57
|
+
String(persona.personality || ''),
|
|
58
|
+
String(persona.speech_style || persona.speechStyle || '')
|
|
59
|
+
].join('||');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function getShareCacheEntry(cacheKey) {
|
|
63
|
+
if (!cacheKey) return null;
|
|
64
|
+
return window.currentShareCache[cacheKey] || null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function setShareCacheEntry(cacheKey, value) {
|
|
68
|
+
if (!cacheKey) return;
|
|
69
|
+
window.currentShareCache[cacheKey] = value;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function getCurrentShareContext() {
|
|
73
|
+
const base = (window.__ISAI_SHARE_CONTEXT__ && typeof window.__ISAI_SHARE_CONTEXT__ === 'object')
|
|
74
|
+
? window.__ISAI_SHARE_CONTEXT__
|
|
75
|
+
: {};
|
|
76
|
+
const params = new URLSearchParams(window.location.search);
|
|
77
|
+
return {
|
|
78
|
+
id: Number(base.id || 0) || 0,
|
|
79
|
+
shareId: String(base.shareId || params.get('v') || '').trim(),
|
|
80
|
+
shareKind: String(base.shareKind || '').trim(),
|
|
81
|
+
isShared: !!(base.isShared || params.get('v')),
|
|
82
|
+
hasPersona: !!base.hasPersona
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function isExistingImageSharePost() {
|
|
87
|
+
return !!getCurrentShareContext().isShared;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function syncImageModalActionButtons() {
|
|
91
|
+
const isShared = isExistingImageSharePost();
|
|
92
|
+
const characterBtn = document.getElementById('image-modal-character-share-btn');
|
|
93
|
+
const reportBtn = document.getElementById('image-modal-report-btn');
|
|
94
|
+
if (characterBtn) characterBtn.classList.toggle('hidden', isShared);
|
|
95
|
+
if (reportBtn) reportBtn.classList.toggle('hidden', !isShared);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async function getProcessedBlob(imageUrl, maxWidth = 1200) {
|
|
99
|
+
const response = await fetch(imageUrl);
|
|
100
|
+
const originalBlob = await response.blob();
|
|
101
|
+
const mimeType = originalBlob.type || 'image/png';
|
|
102
|
+
|
|
103
|
+
if (mimeType === 'image/gif') {
|
|
104
|
+
return originalBlob;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return new Promise((resolve, reject) => {
|
|
108
|
+
const img = new Image();
|
|
109
|
+
img.crossOrigin = 'Anonymous';
|
|
110
|
+
img.src = URL.createObjectURL(originalBlob);
|
|
111
|
+
img.onload = () => {
|
|
112
|
+
const canvas = document.createElement('canvas');
|
|
113
|
+
let width = img.width;
|
|
114
|
+
let height = img.height;
|
|
115
|
+
if (width > maxWidth) {
|
|
116
|
+
height = Math.round((height * maxWidth) / width);
|
|
117
|
+
width = maxWidth;
|
|
118
|
+
}
|
|
119
|
+
canvas.width = width;
|
|
120
|
+
canvas.height = height;
|
|
121
|
+
const ctx = canvas.getContext('2d');
|
|
122
|
+
if (mimeType === 'image/jpeg') {
|
|
123
|
+
ctx.fillStyle = '#fff';
|
|
124
|
+
ctx.fillRect(0, 0, width, height);
|
|
125
|
+
}
|
|
126
|
+
ctx.drawImage(img, 0, 0, width, height);
|
|
127
|
+
canvas.toBlob((blob) => {
|
|
128
|
+
if (blob) resolve(blob);
|
|
129
|
+
else reject(new Error('Canvas failed'));
|
|
130
|
+
}, mimeType, 0.95);
|
|
131
|
+
};
|
|
132
|
+
img.onerror = () => reject(new Error('Image Load Failed'));
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function getImageUploadFilename(prefix, blob) {
|
|
137
|
+
const mime = String(blob && blob.type ? blob.type : '').toLowerCase();
|
|
138
|
+
const extMap = {
|
|
139
|
+
'image/jpeg': 'jpg',
|
|
140
|
+
'image/jpg': 'jpg',
|
|
141
|
+
'image/png': 'png',
|
|
142
|
+
'image/webp': 'webp',
|
|
143
|
+
'image/gif': 'gif'
|
|
144
|
+
};
|
|
145
|
+
return `${prefix}.${extMap[mime] || 'png'}`;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async function uploadImageToImgur(currentSrc) {
|
|
149
|
+
const processedBlob = await getProcessedBlob(currentSrc, 1200);
|
|
150
|
+
const formData = new FormData();
|
|
151
|
+
formData.append('image', processedBlob, getImageUploadFilename('isai-share-upload', processedBlob));
|
|
152
|
+
|
|
153
|
+
const keyRes = await fetch('get_key.php');
|
|
154
|
+
const keyData = await keyRes.json();
|
|
155
|
+
const myClientId = keyData.clientId;
|
|
156
|
+
|
|
157
|
+
const imgurRes = await fetch('https://api.imgur.com/3/image', {
|
|
158
|
+
method: 'POST',
|
|
159
|
+
headers: { 'Authorization': 'Client-ID ' + myClientId },
|
|
160
|
+
body: formData
|
|
161
|
+
});
|
|
162
|
+
const imgurData = await imgurRes.json();
|
|
163
|
+
|
|
164
|
+
if (!imgurData.success || !imgurData.data || !imgurData.data.link) {
|
|
165
|
+
throw new Error('Imgur Upload Failed');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
finalImageUrl: imgurData.data.link,
|
|
170
|
+
tempImageExpiresAt: ''
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async function uploadImageToTemporaryShare(currentSrc, expiresMinutes = window.ISAI_TEMP_SOCIAL_EXPIRE_MINUTES) {
|
|
175
|
+
const processedBlob = await getProcessedBlob(currentSrc, 1200);
|
|
176
|
+
const formData = new FormData();
|
|
177
|
+
formData.append('image', processedBlob, getImageUploadFilename('isai-social-temp', processedBlob));
|
|
178
|
+
formData.append('expires_minutes', String(expiresMinutes));
|
|
179
|
+
|
|
180
|
+
const uploadRes = await fetch('re_store.php?action=upload_temp_share_image', {
|
|
181
|
+
method: 'POST',
|
|
182
|
+
body: formData
|
|
183
|
+
});
|
|
184
|
+
const uploadData = await uploadRes.json();
|
|
185
|
+
|
|
186
|
+
if (!uploadData || !uploadData.success || !uploadData.url) {
|
|
187
|
+
throw new Error((uploadData && uploadData.error) || 'Temporary Upload Failed');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
finalImageUrl: uploadData.url,
|
|
192
|
+
tempImageExpiresAt: uploadData.expires_at || ''
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function normalizeCharacterPersonaForShare(rawPersona, promptText) {
|
|
197
|
+
const source = (rawPersona && typeof rawPersona === 'object') ? rawPersona : {};
|
|
198
|
+
const clampText = (value, maxLen) => {
|
|
199
|
+
const text = String(value || '').replace(/\r/g, '').trim();
|
|
200
|
+
if (!text) return '';
|
|
201
|
+
return text.length > maxLen ? text.slice(0, maxLen) : text;
|
|
202
|
+
};
|
|
203
|
+
const ageRaw = Number(source.age || 0);
|
|
204
|
+
const age = Number.isFinite(ageRaw) && ageRaw >= 19 && ageRaw <= 120 ? Math.floor(ageRaw) : 0;
|
|
205
|
+
return {
|
|
206
|
+
name: clampText(source.name, 80),
|
|
207
|
+
age,
|
|
208
|
+
personality: clampText(source.personality, 300),
|
|
209
|
+
speech_style: clampText(source.speech_style || source.speechStyle, 300),
|
|
210
|
+
background: clampText(source.background || promptText, 420),
|
|
211
|
+
opening_line: clampText(source.opening_line || source.openingLine, 320),
|
|
212
|
+
locale: clampText(source.locale || '', 10)
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
async function uploadAndSaveImage(currentSrc, promptText, options = {}) {
|
|
217
|
+
const storageMode = String(options.storageMode || 'imgur_if_needed').toLowerCase();
|
|
218
|
+
const shareKind = String(options.shareKind || 'gallery').toLowerCase();
|
|
219
|
+
const reuseExistingPage = options.reuseExistingPage !== false;
|
|
220
|
+
const persona = normalizeCharacterPersonaForShare(options.persona, promptText);
|
|
221
|
+
const hasPersona = !!(persona.name || persona.personality || persona.age >= 19);
|
|
222
|
+
const cacheKey = buildShareCacheKey(currentSrc, promptText, { storageMode, shareKind, reuseExistingPage, persona });
|
|
223
|
+
|
|
224
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
225
|
+
const existingV = urlParams.get('v');
|
|
226
|
+
if (existingV && reuseExistingPage) {
|
|
227
|
+
return {
|
|
228
|
+
shareId: existingV,
|
|
229
|
+
finalImageUrl: currentSrc,
|
|
230
|
+
shareKind
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const cached = getShareCacheEntry(cacheKey);
|
|
235
|
+
if (cached && cached.shareId) {
|
|
236
|
+
return cached;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
let finalImageUrl = currentSrc;
|
|
240
|
+
let tempImageExpiresAt = '';
|
|
241
|
+
if (storageMode === 'temporary') {
|
|
242
|
+
const tempResult = await uploadImageToTemporaryShare(finalImageUrl, window.ISAI_TEMP_SOCIAL_EXPIRE_MINUTES);
|
|
243
|
+
finalImageUrl = tempResult.finalImageUrl;
|
|
244
|
+
tempImageExpiresAt = tempResult.tempImageExpiresAt || '';
|
|
245
|
+
} else if (storageMode === 'imgur') {
|
|
246
|
+
const imgurResult = await uploadImageToImgur(finalImageUrl);
|
|
247
|
+
finalImageUrl = imgurResult.finalImageUrl;
|
|
248
|
+
} else if (storageMode === 'imgur_if_needed' && (finalImageUrl.startsWith('blob:') || finalImageUrl.startsWith('data:'))) {
|
|
249
|
+
const imgurResult = await uploadImageToImgur(finalImageUrl);
|
|
250
|
+
finalImageUrl = imgurResult.finalImageUrl;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const dbRes = await fetch('re_store.php?action=save_share', {
|
|
254
|
+
method: 'POST',
|
|
255
|
+
headers: { 'Content-Type': 'application/json' },
|
|
256
|
+
body: JSON.stringify({
|
|
257
|
+
prompt: promptText,
|
|
258
|
+
image_url: finalImageUrl,
|
|
259
|
+
share_kind: shareKind,
|
|
260
|
+
temp_image_expires_at: tempImageExpiresAt,
|
|
261
|
+
persona: hasPersona ? persona : null
|
|
262
|
+
})
|
|
263
|
+
});
|
|
264
|
+
const data = await dbRes.json();
|
|
265
|
+
|
|
266
|
+
if (!data || !data.success) {
|
|
267
|
+
throw new Error((data && data.error) || 'DB Save Failed');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const result = {
|
|
271
|
+
dbId: Number(data.id || 0) || 0,
|
|
272
|
+
shareId: data.share_id,
|
|
273
|
+
finalImageUrl,
|
|
274
|
+
shareKind,
|
|
275
|
+
tempImageExpiresAt
|
|
276
|
+
};
|
|
277
|
+
setShareCacheEntry(cacheKey, result);
|
|
278
|
+
return result;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
async function shareCurrentResult() {
|
|
282
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
283
|
+
const currentV = urlParams.get('v');
|
|
284
|
+
|
|
285
|
+
if (currentV) {
|
|
286
|
+
const shareUrl = window.location.origin + window.location.pathname + '?v=' + currentV;
|
|
287
|
+
navigator.clipboard.writeText(shareUrl);
|
|
288
|
+
if (typeof showToast === 'function') showToast('留곹겕媛 蹂듭궗?섏뿀?듬땲??');
|
|
289
|
+
else alert('留곹겕媛 蹂듭궗?섏뿀?듬땲??');
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const imgElement = document.getElementById('preview-img');
|
|
294
|
+
if (!imgElement || !imgElement.src || imgElement.src.includes('isailogo2.png')) {
|
|
295
|
+
if (typeof showToast === 'function') showToast('No image to save.');
|
|
296
|
+
else alert('?대?吏媛 ?놁뒿?덈떎.');
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const promptText = getSharePromptText();
|
|
301
|
+
if (typeof showLoader === 'function') showLoader(true);
|
|
302
|
+
if (typeof showToast === 'function') showToast('Saving to Gallery...');
|
|
303
|
+
|
|
304
|
+
try {
|
|
305
|
+
const result = await uploadAndSaveImage(imgElement.src, promptText, {
|
|
306
|
+
storageMode: 'imgur_if_needed',
|
|
307
|
+
shareKind: 'gallery',
|
|
308
|
+
reuseExistingPage: true
|
|
309
|
+
});
|
|
310
|
+
const shareUrl = window.location.origin + window.location.pathname + '?v=' + result.shareId;
|
|
311
|
+
navigator.clipboard.writeText(shareUrl);
|
|
312
|
+
const newUrl = window.location.pathname + '?v=' + result.shareId;
|
|
313
|
+
window.history.pushState({ path: newUrl }, '', newUrl);
|
|
314
|
+
if (window.__ISAI_SHARE_CONTEXT__) {
|
|
315
|
+
window.__ISAI_SHARE_CONTEXT__.id = Number(result.dbId || window.__ISAI_SHARE_CONTEXT__.id || 0) || 0;
|
|
316
|
+
window.__ISAI_SHARE_CONTEXT__.shareId = result.shareId;
|
|
317
|
+
window.__ISAI_SHARE_CONTEXT__.shareKind = 'gallery';
|
|
318
|
+
window.__ISAI_SHARE_CONTEXT__.isShared = true;
|
|
319
|
+
}
|
|
320
|
+
syncImageModalActionButtons();
|
|
321
|
+
if (typeof showToast === 'function') showToast('Saved Successfully!');
|
|
322
|
+
} catch (e) {
|
|
323
|
+
console.error(e);
|
|
324
|
+
if (typeof showToast === 'function') showToast('Error: ' + e.message);
|
|
325
|
+
else alert('Error: ' + e.message);
|
|
326
|
+
} finally {
|
|
327
|
+
if (typeof showLoader === 'function') showLoader(false);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
async function shareToSocial(platform) {
|
|
332
|
+
const imgElement = document.getElementById('preview-img');
|
|
333
|
+
if (!imgElement || !imgElement.src || imgElement.src.includes('isailogo2.png')) {
|
|
334
|
+
alert('怨듭쑀??肄섑뀗痢좉? ?놁뒿?덈떎.');
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const promptText = getSharePromptText();
|
|
339
|
+
const shareWindow = window.open('about:blank', '_blank', 'width=600,height=600');
|
|
340
|
+
|
|
341
|
+
try {
|
|
342
|
+
const result = await uploadAndSaveImage(imgElement.src, promptText, {
|
|
343
|
+
storageMode: 'temporary',
|
|
344
|
+
shareKind: 'social_temp',
|
|
345
|
+
reuseExistingPage: false
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
const baseUrl = window.location.origin + window.location.pathname;
|
|
349
|
+
const shareUrl = baseUrl + '?v=' + result.shareId;
|
|
350
|
+
const proxiedImgUrl = window.location.origin + '/proxy_img.php?url=' + encodeURIComponent(result.finalImageUrl);
|
|
351
|
+
|
|
352
|
+
const encodedUrl = encodeURIComponent(shareUrl);
|
|
353
|
+
const encodedText = encodeURIComponent(promptText);
|
|
354
|
+
const encodedImg = encodeURIComponent(proxiedImgUrl);
|
|
355
|
+
|
|
356
|
+
let snsUrl = '';
|
|
357
|
+
switch (platform) {
|
|
358
|
+
case 'pinterest': snsUrl = `https://www.pinterest.com/pin/create/button/?url=${encodedUrl}&media=${encodedImg}&description=${encodedText}`; break;
|
|
359
|
+
case 'x': snsUrl = `https://twitter.com/intent/tweet?text=${encodedText}&url=${encodedUrl}`; break;
|
|
360
|
+
case 'threads': snsUrl = `https://www.threads.net/intent/post?text=${encodedText}%20${encodedUrl}`; break;
|
|
361
|
+
case 'facebook': snsUrl = `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`; break;
|
|
362
|
+
case 'tumblr': snsUrl = `https://www.tumblr.com/widgets/share/tool?posttype=link&title=${encodedText}&canonicalUrl=${encodedUrl}`; break;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (snsUrl) shareWindow.location.href = snsUrl;
|
|
366
|
+
else shareWindow.close();
|
|
367
|
+
} catch (e) {
|
|
368
|
+
console.error(e);
|
|
369
|
+
if (shareWindow) shareWindow.close();
|
|
370
|
+
alert('怨듭쑀 以??ㅻ쪟媛 諛쒖깮?덉뒿?덈떎: ' + e.message);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
async function saveCurrentResultToGallery() {
|
|
375
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
376
|
+
const currentV = urlParams.get('v');
|
|
377
|
+
|
|
378
|
+
if (currentV) {
|
|
379
|
+
if (typeof showToast === 'function') showToast('Already saved as a post.');
|
|
380
|
+
else alert('Already saved as a post.');
|
|
381
|
+
return { shareId: currentV, alreadySaved: true };
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const imgElement = document.getElementById('preview-img');
|
|
385
|
+
if (!imgElement || !imgElement.src || imgElement.src.includes('isailogo2.png')) {
|
|
386
|
+
if (typeof showToast === 'function') showToast('No image to save.');
|
|
387
|
+
else alert('No image available.');
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const promptText = getSharePromptText();
|
|
392
|
+
if (typeof showLoader === 'function') showLoader(true);
|
|
393
|
+
if (typeof showToast === 'function') showToast('Saving post...');
|
|
394
|
+
|
|
395
|
+
try {
|
|
396
|
+
const result = await uploadAndSaveImage(imgElement.src, promptText, {
|
|
397
|
+
storageMode: 'imgur_if_needed',
|
|
398
|
+
shareKind: 'gallery',
|
|
399
|
+
reuseExistingPage: true
|
|
400
|
+
});
|
|
401
|
+
const newUrl = window.location.pathname + '?v=' + result.shareId;
|
|
402
|
+
window.history.pushState({ path: newUrl }, '', newUrl);
|
|
403
|
+
if (window.__ISAI_SHARE_CONTEXT__) {
|
|
404
|
+
window.__ISAI_SHARE_CONTEXT__.id = Number(result.dbId || window.__ISAI_SHARE_CONTEXT__.id || 0) || 0;
|
|
405
|
+
window.__ISAI_SHARE_CONTEXT__.shareId = result.shareId;
|
|
406
|
+
window.__ISAI_SHARE_CONTEXT__.shareKind = 'gallery';
|
|
407
|
+
window.__ISAI_SHARE_CONTEXT__.isShared = true;
|
|
408
|
+
}
|
|
409
|
+
syncImageModalActionButtons();
|
|
410
|
+
if (typeof showToast === 'function') showToast('Post created successfully!');
|
|
411
|
+
return { ...result, alreadySaved: false };
|
|
412
|
+
} catch (e) {
|
|
413
|
+
console.error(e);
|
|
414
|
+
if (typeof showToast === 'function') showToast('Error: ' + e.message);
|
|
415
|
+
else alert('Error: ' + e.message);
|
|
416
|
+
throw e;
|
|
417
|
+
} finally {
|
|
418
|
+
if (typeof showLoader === 'function') showLoader(false);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function openCharacterShareModal() {
|
|
423
|
+
const i18n = getCharacterShareI18n();
|
|
424
|
+
if (isExistingImageSharePost()) {
|
|
425
|
+
if (typeof showToast === 'function') showToast('Already posted image. Use report instead.');
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
const modal = document.getElementById('character-share-modal');
|
|
429
|
+
const imgElement = document.getElementById('preview-img');
|
|
430
|
+
if (!modal || !imgElement || !imgElement.src || imgElement.src.includes('isailogo2.png')) {
|
|
431
|
+
if (typeof showToast === 'function') showToast('No image available.');
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
const preview = document.getElementById('character-share-preview');
|
|
435
|
+
const promptView = document.getElementById('character-share-prompt');
|
|
436
|
+
const nameField = document.getElementById('character-share-name');
|
|
437
|
+
const ageField = document.getElementById('character-share-age');
|
|
438
|
+
const personalityField = document.getElementById('character-share-personality');
|
|
439
|
+
const speechField = document.getElementById('character-share-speech');
|
|
440
|
+
const promptText = getSharePromptText();
|
|
441
|
+
if (preview) preview.src = imgElement.src;
|
|
442
|
+
if (promptView) promptView.textContent = promptText || i18n.noPrompt || 'No prompt';
|
|
443
|
+
if (nameField) nameField.value = '';
|
|
444
|
+
if (ageField) ageField.value = '19';
|
|
445
|
+
if (personalityField) personalityField.value = '';
|
|
446
|
+
if (speechField) speechField.value = '';
|
|
447
|
+
modal.classList.remove('hidden');
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
function closeCharacterShareModal() {
|
|
451
|
+
const modal = document.getElementById('character-share-modal');
|
|
452
|
+
if (modal) modal.classList.add('hidden');
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
async function createCharacterSharePost() {
|
|
456
|
+
const i18n = getCharacterShareI18n();
|
|
457
|
+
const imgElement = document.getElementById('preview-img');
|
|
458
|
+
if (!imgElement || !imgElement.src || imgElement.src.includes('isailogo2.png')) {
|
|
459
|
+
if (typeof showToast === 'function') showToast('No image available.');
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
const promptText = getSharePromptText();
|
|
463
|
+
const name = String(document.getElementById('character-share-name')?.value || '').trim();
|
|
464
|
+
const age = Number(document.getElementById('character-share-age')?.value || 0);
|
|
465
|
+
const personality = String(document.getElementById('character-share-personality')?.value || '').trim();
|
|
466
|
+
const speechStyle = String(document.getElementById('character-share-speech')?.value || '').trim();
|
|
467
|
+
if (!name) {
|
|
468
|
+
if (typeof showToast === 'function') showToast(i18n.nameRequired || 'Please enter a character name.');
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
if (!Number.isFinite(age) || age < 19) {
|
|
472
|
+
if (typeof showToast === 'function') showToast(i18n.ageRequired || 'Character age must be 19 or older.');
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
if (!personality) {
|
|
476
|
+
if (typeof showToast === 'function') showToast(i18n.personalityRequired || 'Please enter the character personality.');
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
if (typeof showLoader === 'function') showLoader(true);
|
|
480
|
+
if (typeof showToast === 'function') showToast(i18n.creating || 'Character post is being created...');
|
|
481
|
+
try {
|
|
482
|
+
const result = await uploadAndSaveImage(imgElement.src, promptText, {
|
|
483
|
+
storageMode: 'imgur',
|
|
484
|
+
shareKind: 'character',
|
|
485
|
+
reuseExistingPage: false,
|
|
486
|
+
persona: {
|
|
487
|
+
name,
|
|
488
|
+
age,
|
|
489
|
+
personality,
|
|
490
|
+
speech_style: speechStyle,
|
|
491
|
+
background: promptText
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
const newUrl = window.location.pathname + '?v=' + result.shareId;
|
|
495
|
+
window.history.pushState({ path: newUrl }, '', newUrl);
|
|
496
|
+
if (window.__ISAI_SHARE_CONTEXT__) {
|
|
497
|
+
window.__ISAI_SHARE_CONTEXT__.id = Number(result.dbId || window.__ISAI_SHARE_CONTEXT__.id || 0) || 0;
|
|
498
|
+
window.__ISAI_SHARE_CONTEXT__.shareId = result.shareId;
|
|
499
|
+
window.__ISAI_SHARE_CONTEXT__.shareKind = 'character';
|
|
500
|
+
window.__ISAI_SHARE_CONTEXT__.isShared = true;
|
|
501
|
+
window.__ISAI_SHARE_CONTEXT__.hasPersona = true;
|
|
502
|
+
}
|
|
503
|
+
syncImageModalActionButtons();
|
|
504
|
+
closeCharacterShareModal();
|
|
505
|
+
if (typeof showToast === 'function') showToast(i18n.created || 'Character post created successfully!');
|
|
506
|
+
} catch (e) {
|
|
507
|
+
console.error(e);
|
|
508
|
+
if (typeof showToast === 'function') showToast('Error: ' + e.message);
|
|
509
|
+
else alert('Error: ' + e.message);
|
|
510
|
+
} finally {
|
|
511
|
+
if (typeof showLoader === 'function') showLoader(false);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
function openImageShareReportModal() {
|
|
516
|
+
const context = getCurrentShareContext();
|
|
517
|
+
if (!context.isShared || !context.id) {
|
|
518
|
+
if (typeof showToast === 'function') showToast('Saved image post not found.');
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
const modal = document.getElementById('image-report-modal');
|
|
522
|
+
const textarea = document.getElementById('image-report-reason');
|
|
523
|
+
if (textarea) textarea.value = '';
|
|
524
|
+
if (modal) modal.classList.remove('hidden');
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
function closeImageShareReportModal() {
|
|
528
|
+
const modal = document.getElementById('image-report-modal');
|
|
529
|
+
if (modal) modal.classList.add('hidden');
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
async function submitImageShareReport() {
|
|
533
|
+
const i18n = getImageReportI18n();
|
|
534
|
+
const context = getCurrentShareContext();
|
|
535
|
+
const textarea = document.getElementById('image-report-reason');
|
|
536
|
+
const reason = String(textarea?.value || '').trim();
|
|
537
|
+
if (!context.isShared || !context.id) {
|
|
538
|
+
if (typeof showToast === 'function') showToast('Saved image post not found.');
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
if (!reason) {
|
|
542
|
+
if (typeof showToast === 'function') showToast(i18n.placeholder || 'Write the reason for this report');
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
try {
|
|
546
|
+
const res = await fetch('re_store.php?action=submit_content_report', {
|
|
547
|
+
method: 'POST',
|
|
548
|
+
headers: { 'Content-Type': 'application/json' },
|
|
549
|
+
body: JSON.stringify({
|
|
550
|
+
target_type: 'gallery',
|
|
551
|
+
target_id: context.id,
|
|
552
|
+
reason
|
|
553
|
+
})
|
|
554
|
+
});
|
|
555
|
+
const data = await res.json();
|
|
556
|
+
if (!data || !data.success) {
|
|
557
|
+
throw new Error((data && data.error) || 'REPORT_FAILED');
|
|
558
|
+
}
|
|
559
|
+
closeImageShareReportModal();
|
|
560
|
+
if (data.deleted) {
|
|
561
|
+
if (typeof showToast === 'function') showToast(i18n.deleted || 'The post was removed after repeated reports.');
|
|
562
|
+
window.setTimeout(() => {
|
|
563
|
+
window.location.href = '/';
|
|
564
|
+
}, 700);
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
if (typeof showToast === 'function') {
|
|
568
|
+
showToast(data.reported ? (i18n.reported || 'Report submitted.') : (i18n.duplicate || 'You already reported this post this month.'));
|
|
569
|
+
}
|
|
570
|
+
} catch (error) {
|
|
571
|
+
console.error(error);
|
|
572
|
+
if (typeof showToast === 'function') showToast(i18n.error || 'An error occurred while submitting the report.');
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
window.addEventListener('DOMContentLoaded', syncImageModalActionButtons);
|
|
577
|
+
window.addEventListener('popstate', syncImageModalActionButtons);
|