Skip to content

Commit

Permalink
Update index.html
Browse files Browse the repository at this point in the history
  • Loading branch information
hung319 authored Dec 18, 2024
1 parent 2fa10b2 commit 8b6b2fb
Showing 1 changed file with 188 additions and 70 deletions.
258 changes: 188 additions & 70 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,80 +7,214 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
<style>
:root {
--primary-color: #1e88e5;
--hover-color: #1565c0;
--background-color: #f5f9ff;
}

body {
font-family: Arial, sans-serif;
font-family: 'Segoe UI', Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
text-align: center;
background-color: var(--background-color);
color: #333;
line-height: 1.6;
}

.container {
background-color: white;
padding: 2rem;
border-radius: 15px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
margin-top: 2rem;
}

h1 {
color: var(--primary-color);
margin-bottom: 2rem;
font-size: 2.5rem;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
}

.input-group {
margin: 1.5rem 0;
}

label {
display: block;
margin-bottom: 0.5rem;
color: #555;
font-weight: 500;
}
button, input {
font-size: 18px;
padding: 10px 20px;
margin: 20px 0;

input {
font-size: 1rem;
padding: 0.8rem 1rem;
border: 2px solid #e0e0e0;
border-radius: 8px;
width: 150px;
transition: all 0.3s ease;
}

input:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(30, 136, 229, 0.2);
}

button {
background-color: var(--primary-color);
color: white;
border: none;
padding: 1rem 2rem;
font-size: 1.1rem;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.5px;
margin: 1.5rem 0;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

button:hover {
background-color: var(--hover-color);
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}

button:active {
transform: translateY(0);
}

#status {
margin-top: 20px;
font-style: italic;
margin-top: 1.5rem;
padding: 1rem;
border-radius: 8px;
background-color: rgba(30, 136, 229, 0.1);
color: var(--primary-color);
font-weight: 500;
transition: all 0.3s ease;
}

/* Loading Animation */
.loading {
display: inline-block;
position: relative;
width: 64px;
height: 64px;
display: none;
}

.loading div {
position: absolute;
border: 4px solid var(--primary-color);
opacity: 1;
border-radius: 50%;
animation: loading 1s cubic-bezier(0, 0.2, 0.8, 1) infinite;
}

@keyframes loading {
0% {
top: 28px;
left: 28px;
width: 0;
height: 0;
opacity: 1;
}
100% {
top: -1px;
left: -1px;
width: 58px;
height: 58px;
opacity: 0;
}
}

/* Progress bar */
.progress-bar {
width: 100%;
height: 8px;
background-color: #e0e0e0;
border-radius: 4px;
margin: 1rem 0;
overflow: hidden;
display: none;
}

.progress-bar-fill {
height: 100%;
background-color: var(--primary-color);
width: 0%;
transition: width 0.3s ease;
}
</style>
</head>
<body>
<h1>Tải ảnh NSFW</h1>
<label for="imageCount">Số lượng ảnh tải xuống:</label>
<input type="number" id="imageCount" value="50" min="1" max="100">
<button id="downloadBtn">Tải ảnh và nén ZIP</button>
<div id="status"></div>
<div class="container">
<h1>Tải ảnh NSFW</h1>
<div class="input-group">
<label for="imageCount">Số lượng ảnh tải xuống:</label>
<input type="number" id="imageCount" value="50" min="1" max="100">
</div>
<button id="downloadBtn">
<span class="button-text">Tải ảnh và nén ZIP</span>
</button>
<div class="loading" id="loading">
<div></div>
</div>
<div class="progress-bar" id="progressBar">
<div class="progress-bar-fill" id="progressBarFill"></div>
</div>
<div id="status"></div>
</div>

<script>
const downloadBtn = document.getElementById('downloadBtn');
const status = document.getElementById('status');
const imageCountInput = document.getElementById('imageCount');
const CONCURRENT_LIMIT = 1000;
const API_URL = 'https://waifu.pics/api/nsfw/waifu';
const WORKER_URL = 'https://white-mud-f95d.hoangxg4.workers.dev/?apiUrl=';

const generateRandomString = (length) => {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
};
// Giữ nguyên JavaScript code cũ và thêm các đoạn code mới để xử lý animation

const fetchWithRetry = async (url, options, retries = 3) => {
try {
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response;
} catch (error) {
if (retries > 0) {
console.log(`Retry attempt ${4 - retries}...`);
return fetchWithRetry(url, options, retries - 1);
}
throw error;
}
};
const loading = document.getElementById('loading');
const progressBar = document.getElementById('progressBar');
const progressBarFill = document.getElementById('progressBarFill');

const fetchImage = async () => {
downloadBtn.addEventListener('click', async () => {
const imagesToDownload = parseInt(imageCountInput.value) || 5;
status.textContent = 'Đang tải ảnh...';

// Hiển thị loading và progress bar
loading.style.display = 'inline-block';
progressBar.style.display = 'block';
downloadBtn.disabled = true;

try {
const response = await fetchWithRetry(`${WORKER_URL}${encodeURIComponent(API_URL)}`);
const data = await response.json();
const imageUrl = data.url;
const imageResponse = await fetchWithRetry(`${WORKER_URL}${encodeURIComponent(imageUrl)}`);
const imageBlob = await imageResponse.blob();

const fileName = imageUrl.split('/').pop();
return { imageBlob, fileName };
const zipBlob = await downloadImages(imagesToDownload);

const randomZipName = generateRandomString(10) + '.zip';
saveAs(zipBlob, randomZipName);

status.textContent = `Đã tải xong! Kiểm tra file ZIP (${randomZipName}) của bạn.`;
} catch (error) {
console.error('Lỗi khi tải ảnh:', error);
throw error;
status.textContent = 'Đã xảy ra lỗi khi tải ảnh. Vui lòng thử lại sau.';
console.error('Lỗi:', error);
} finally {
// Ẩn loading và progress bar
loading.style.display = 'none';
progressBar.style.display = 'none';
downloadBtn.disabled = false;
progressBarFill.style.width = '0%';
}
});

// Cập nhật progress bar khi tải ảnh
const updateProgress = (completed, total) => {
const progress = (completed / total) * 100;
progressBarFill.style.width = `${progress}%`;
};

// Sửa đổi hàm downloadImages để cập nhật progress
const downloadImages = async (count) => {
const zip = new JSZip();
let completed = 0;
Expand All @@ -97,6 +231,7 @@ <h1>Tải ảnh NSFW</h1>
zip.file(result.fileName, result.imageBlob);
completed++;
status.textContent = `Đã tải ${completed}/${count} ảnh`;
updateProgress(completed, count);
}
}).catch(error => {
console.error('Lỗi khi tải ảnh:', error);
Expand All @@ -109,23 +244,6 @@ <h1>Tải ảnh NSFW</h1>
await Promise.all(promises);
return zip.generateAsync({ type: 'blob' });
};

downloadBtn.addEventListener('click', async () => {
const imagesToDownload = parseInt(imageCountInput.value) || 5;
status.textContent = 'Đang tải ảnh...';

try {
const zipBlob = await downloadImages(imagesToDownload);

const randomZipName = generateRandomString(10) + '.zip';
saveAs(zipBlob, randomZipName);

status.textContent = `Đã tải xong! Kiểm tra file ZIP (${randomZipName}) của bạn.`;
} catch (error) {
status.textContent = 'Đã xảy ra lỗi khi tải ảnh. Vui lòng thử lại sau.';
console.error('Lỗi:', error);
}
});
</script>
</body>
</html>

0 comments on commit 8b6b2fb

Please sign in to comment.