stat2025 commited on
Commit
c8f1631
·
verified ·
1 Parent(s): 9c56050

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +12 -190
index.html CHANGED
@@ -101,197 +101,19 @@
101
  </div>
102
 
103
  <script>
104
- const filesInput = document.getElementById("files");
105
- const mergeBtn = document.getElementById("mergeBtn");
106
- const statusDiv = document.getElementById("status");
107
- const fileListDiv = document.getElementById("fileList");
108
- const outputNameInput = document.getElementById("outputName");
 
 
 
 
 
 
 
109
 
110
- // نخزن جميع الملفات المختارة من عدة محاولات اختيار
111
- let selectedFiles = [];
112
-
113
- function setStatus(msg, type = "") {
114
- statusDiv.textContent = msg;
115
- statusDiv.className = "status" + (type ? " " + type : "");
116
- if (!msg) statusDiv.className = "status";
117
- }
118
-
119
- function renderFileList(files) {
120
- if (!files.length) {
121
- fileListDiv.classList.add("hidden");
122
- fileListDiv.innerHTML = "";
123
- return;
124
- }
125
- fileListDiv.classList.remove("hidden");
126
- fileListDiv.innerHTML = `
127
- <div class="file-list-header">
128
- <span>الملفات المختارة: ${files.length}</span>
129
- <span class="file-note">سيتم الدمج حسب الترتيب الأبجدي لاسم الملف.</span>
130
- </div>
131
- <ul class="file-list-ul">
132
- ${files
133
- .map(
134
- (f, i) => `
135
- <li>
136
- <span class="index">${i + 1}</span>
137
- <span class="name">${f.name}</span>
138
- <span class="size">${(f.size / 1024).toFixed(1)} كيلوبايت</span>
139
- </li>`
140
- )
141
- .join("")}
142
- </ul>
143
- `;
144
- }
145
-
146
- function detectMode(files) {
147
- const allImages = files.every(f => f.type.startsWith("image/"));
148
- const allPDFs = files.every(
149
- f =>
150
- f.type === "application/pdf" ||
151
- f.name.toLowerCase().endsWith(".pdf")
152
- );
153
- if (allImages) return "images";
154
- if (allPDFs) return "pdfs";
155
- return null;
156
- }
157
-
158
- function downloadPdf(bytes, filename) {
159
- const blob = new Blob([bytes], { type: "application/pdf" });
160
- const url = URL.createObjectURL(blob);
161
- const a = document.createElement("a");
162
- a.href = url;
163
- a.download = filename;
164
- document.body.appendChild(a);
165
- a.click();
166
- a.remove();
167
- URL.revokeObjectURL(url);
168
- }
169
-
170
- // إضافة ملفات على دفعات (مفيد للجوال)
171
- filesInput.addEventListener("change", () => {
172
- const newFiles = Array.from(filesInput.files || []);
173
- if (!newFiles.length) return;
174
-
175
- // دمج بدون تكرار (اسم + حجم + تاريخ التعديل)
176
- const map = new Map();
177
- [...selectedFiles, ...newFiles].forEach(f => {
178
- const key = `${f.name}|${f.size}|${f.lastModified}`;
179
- if (!map.has(key)) map.set(key, f);
180
- });
181
-
182
- selectedFiles = Array.from(map.values()).sort((a, b) =>
183
- a.name.localeCompare(b.name, undefined, { numeric: true })
184
- );
185
-
186
- renderFileList(selectedFiles);
187
- setStatus("");
188
-
189
- // إفراغ input حتى نسمح باختيار دفعة جديدة
190
- filesInput.value = "";
191
- });
192
-
193
- mergeBtn.addEventListener("click", async () => {
194
- const files = [...selectedFiles];
195
-
196
- if (!files.length) {
197
- setStatus("الرجاء اختيار الملفات أولاً.", "error");
198
- return;
199
- }
200
-
201
- const mode = detectMode(files);
202
- if (!mode) {
203
- setStatus(
204
- "يجب أن تكون جميع الملفات صورًا فقط أو جميعها PDF فقط في العملية الواحدة.",
205
- "error"
206
- );
207
- return;
208
- }
209
-
210
- // ترتيب نهائي حسب الاسم
211
- files.sort((a, b) =>
212
- a.name.localeCompare(b.name, undefined, { numeric: true })
213
- );
214
- renderFileList(files);
215
-
216
- try {
217
- setStatus("جاري معالجة الملفات...", "loading");
218
- mergeBtn.disabled = true;
219
- mergeBtn.classList.add("disabled");
220
-
221
- if (mode === "images") {
222
- const pdfDoc = await PDFLib.PDFDocument.create();
223
-
224
- for (const file of files) {
225
- const bytes = await file.arrayBuffer();
226
- const lower = file.name.toLowerCase();
227
- let image;
228
-
229
- if (
230
- file.type === "image/jpeg" ||
231
- file.type === "image/jpg" ||
232
- lower.endsWith(".jpg") ||
233
- lower.endsWith(".jpeg")
234
- ) {
235
- image = await pdfDoc.embedJpg(bytes);
236
- } else {
237
- image = await pdfDoc.embedPng(bytes);
238
- }
239
-
240
- const imgWidth = image.width;
241
- const imgHeight = image.height;
242
- const pageWidth = 595.28; // A4
243
- const pageHeight = 841.89; // A4
244
-
245
- const page = pdfDoc.addPage([pageWidth, pageHeight]);
246
- const scale = Math.min(pageWidth / imgWidth, pageHeight / imgHeight);
247
- const drawWidth = imgWidth * scale;
248
- const drawHeight = imgHeight * scale;
249
- const x = (pageWidth - drawWidth) / 2;
250
- const y = (pageHeight - drawHeight) / 2;
251
-
252
- page.drawImage(image, { x, y, width: drawWidth, height: drawHeight });
253
- }
254
-
255
- const pdfBytes = await pdfDoc.save();
256
- const outName =
257
- (outputNameInput.value || "merged-images.pdf").trim() ||
258
- "merged-images.pdf";
259
- downloadPdf(pdfBytes, outName);
260
- setStatus("تم إنشاء ملف PDF من الصور بنجاح.", "ok");
261
- }
262
-
263
- if (mode === "pdfs") {
264
- const pdfDoc = await PDFLib.PDFDocument.create();
265
-
266
- for (const file of files) {
267
- const bytes = await file.arrayBuffer();
268
- const donorPdf = await PDFLib.PDFDocument.load(bytes);
269
- const pages = await pdfDoc.copyPages(
270
- donorPdf,
271
- donorPdf.getPageIndices()
272
- );
273
- pages.forEach(p => pdfDoc.addPage(p));
274
- }
275
-
276
- const pdfBytes = await pdfDoc.save();
277
- const outName =
278
- (outputNameInput.value || "merged-pdfs.pdf").trim() ||
279
- "merged-pdfs.pdf";
280
- downloadPdf(pdfBytes, outName);
281
- setStatus("تم دمج ملفات PDF بنجاح.", "ok");
282
- }
283
-
284
- // بعد الانتهاء: تنظيف
285
- selectedFiles = [];
286
- renderFileList([]);
287
- } catch (err) {
288
- console.error(err);
289
- setStatus("حدث خطأ أثناء المعالجة. تأكد من الملفات وحاول مرة أخرى.", "error");
290
- } finally {
291
- mergeBtn.disabled = false;
292
- mergeBtn.classList.remove("disabled");
293
- }
294
- });
295
  </script>
296
  </body>
297
  </html>
 
101
  </div>
102
 
103
  <script>
104
+ .delete-btn {
105
+ background: none;
106
+ border: none;
107
+ cursor: pointer;
108
+ font-size: 14px;
109
+ transition: 0.2s;
110
+ }
111
+
112
+ .delete-btn:hover {
113
+ color: #b91c1c;
114
+ transform: scale(1.1);
115
+ }
116
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  </script>
118
  </body>
119
  </html>