book / index.html
abeea's picture
Update index.html
05057cc verified
<!DOCTYPE html>
<html lang="ur" dir="rtl">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>📖 Urdu Book Viewer</title>
<link href="https://fonts.googleapis.com/css2?family=Noto+Nastaliq+Urdu:wght@400;700&family=Amiri:wght@400;700&display=swap" rel="stylesheet">
<style>
body {font-family: 'Noto Nastaliq Urdu', 'Amiri', serif; margin: 0; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; padding: 1rem; color: #333;}
.container {max-width: 900px; margin: 0 auto;}
.header {text-align: center; color: white; margin-bottom: 2rem;}
.header h1 {font-size: 2.5rem; margin: 0; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);}
.header p {font-size: 1.1rem; opacity: 0.9; margin: 0.5rem 0;}
.page {background: rgba(255, 255, 255, 0.95); padding: 3rem; border-radius: 20px; box-shadow: 0 8px 32px rgba(31, 38, 135, 0.37); margin-bottom: 2rem; position: relative; line-height: 2; font-size: 1.1rem; transition: transform 0.3s ease;}
.page:hover {transform: translateY(-4px);}
.page-number {position: absolute; bottom: 1rem; left: 1rem; font-size: 0.9rem; color: #666; background: rgba(255, 255, 255, 0.8); padding: 0.25rem 0.75rem; border-radius: 20px;}
.stats {display: flex; justify-content: space-around; background: rgba(255, 255, 255, 0.1); padding: 1rem; border-radius: 12px; margin-bottom: 1rem; color: white;}
.stat-item {text-align: center;}
.stat-number {font-size: 1.5rem; font-weight: bold; display: block;}
iframe { max-width: 100%; border: none; border-radius: 12px; margin: 1rem 0; }
/* New Styles for Book Pages */
.half-title-page {
text-align: center;
min-height: 60vh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(120deg, #f8fafc 0%, #e9d8fd 100%);
animation: fadeIn 1.2s;
position: relative;
flex-direction: column;
}
.half-title-page h2 {
font-size: 3.5rem;
color: #764ba2;
margin: 0;
padding: 2rem 1rem 1rem 1rem;
font-family: 'Noto Nastaliq Urdu', serif;
text-shadow: 0 4px 24px #b794f4, 0 1px 0 #fff;
letter-spacing: 2px;
position: relative;
}
.half-title-page .divider {
width: 80px;
height: 4px;
background: linear-gradient(90deg, #764ba2 0%, #667eea 100%);
border-radius: 2px;
margin: 1.5rem auto 0 auto;
}
.half-title-page .motif {
font-size: 2.2rem;
color: #b794f4;
margin-top: 1.2rem;
}
.title-page {
text-align: center;
min-height: 80vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: linear-gradient(120deg, #fff 0%, #e9d8fd 100%);
padding: 2rem;
border: 2px solid #d6bcfa;
border-radius: 32px;
box-shadow: 0 8px 32px rgba(118, 75, 162, 0.13);
animation: fadeInUp 1.2s;
position: relative;
}
.title-page h1 {
font-size: 3.2rem;
color: #764ba2;
margin-bottom: 2rem;
font-family: 'Noto Nastaliq Urdu', serif;
text-shadow: 0 2px 12px #e9d8fd;
letter-spacing: 1.5px;
animation: fadeIn 1.2s;
}
.title-page .author {
font-size: 1.7rem;
color: #4b3869;
margin-bottom: 1.2rem;
font-family: 'Noto Nastaliq Urdu', serif;
animation: fadeIn 1.6s;
}
.title-page .publisher {
font-size: 1.2rem;
color: #6b46c1;
margin-top: 2.5rem;
font-family: 'Amiri', serif;
letter-spacing: 1px;
animation: fadeIn 2s;
}
.title-page .motif {
font-size: 2.2rem;
color: #b794f4;
margin-bottom: 1.5rem;
}
.dedication-page {
text-align: center;
min-height: 60vh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(120deg, #f8fafc 0%, #e9d8fd 100%);
font-style: italic;
animation: fadeInUp 1.2s;
position: relative;
}
.dedication-page .dedication-box {
background: rgba(255,255,255,0.95);
border: 2px solid #d6bcfa;
border-radius: 24px;
box-shadow: 0 4px 24px #b794f4;
padding: 2.5rem 2rem 2rem 2rem;
max-width: 600px;
margin: auto;
position: relative;
font-family: 'Noto Nastaliq Urdu', serif;
}
.dedication-page .dedication-text {
font-size: 1.6rem;
color: #4b3869;
line-height: 2.1;
margin-top: 1.2rem;
}
.dedication-page .quote-icon {
font-size: 2.5rem;
color: #b794f4;
position: absolute;
top: 1.2rem;
left: 1.2rem;
opacity: 0.7;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(40px); }
to { opacity: 1; transform: translateY(0); }
}
.dedication-page .dedication-urdu {
font-size: 1.7rem;
color: #4b3869;
font-family: 'Noto Nastaliq Urdu', serif;
direction: rtl;
text-align: right;
margin-bottom: 1.2rem;
line-height: 2.1;
}
.dedication-page .dedication-english {
font-size: 1.3rem;
color: #764ba2;
font-family: 'Amiri', serif;
font-style: italic;
direction: ltr;
text-align: left;
margin-top: 1.2rem;
line-height: 1.8;
}
.dedication-page .dedication-divider {
width: 60px;
height: 2px;
background: linear-gradient(90deg, #b794f4 0%, #764ba2 100%);
margin: 1.2rem auto 1.2rem auto;
border-radius: 1px;
}
.download-btn {
background: linear-gradient(90deg, #764ba2 0%, #667eea 100%);
color: #fff;
font-size: 1.1rem;
font-family: inherit;
border: none;
border-radius: 24px;
padding: 0.7rem 2.2rem;
margin-bottom: 1.2rem;
cursor: pointer;
box-shadow: 0 2px 8px rgba(118,75,162,0.13);
transition: background 0.3s, transform 0.2s;
}
.download-btn:hover {
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
transform: translateY(-2px) scale(1.04);
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>📖 اردو کتاب ریڈر</h1>
<div style="text-align:center; margin-top:30px; color:white; font-size: 0.9rem;">
Developed by <strong>Abdullah Tarar</strong>
</div>
</div>
<div id="downloadContainer" style="text-align:center; margin-bottom: 1.5rem;"></div>
<div id="statsContainer"></div>
<div id="bookContainer"></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
<script>
let videoMap = {};
async function loadStory() {
try {
const params = new URLSearchParams(window.location.search);
const fileName = params.get('file') || 'Story.txt';
const videoResponse = await fetch('Url.json');
const rawMap = await videoResponse.json();
videoMap = processVideoMap(rawMap);
const response = await fetch(fileName);
const content = await response.text();
renderBook(content);
} catch (error) {
console.error('کہانی لوڈ کرنے میں مسئلہ ہوا:', error);
}
}
function processVideoMap(rawMap) {
const map = {};
for (let key in rawMap) {
const url = rawMap[key].trim();
if (url.startsWith("<iframe")) {
map[key] = url;
} else if (url.includes("watch?v=")) {
const id = url.split("watch?v=")[1].split("&")[0];
map[key] = `<iframe width="100%" height="315" src="https://www.youtube.com/embed/${id}" allowfullscreen></iframe>`;
} else if (url.includes("youtu.be/")) {
const id = url.split("youtu.be/")[1].split("?")[0];
map[key] = `<iframe width="100%" height="315" src="https://www.youtube.com/embed/${id}" allowfullscreen></iframe>`;
} else {
map[key] = `<iframe width="100%" height="315" src="${url}" allowfullscreen></iframe>`;
}
}
return map;
}
function renderBook(text) {
const container = document.getElementById("bookContainer");
const statsContainer = document.getElementById("statsContainer");
container.innerHTML = "";
const wordCount = text.trim().split(/\s+/).length;
const charCount = text.length;
const pageSize = 1600;
let chunks = splitText(text, pageSize);
// Process special pages
chunks = processSpecialPages(chunks);
statsContainer.innerHTML = `
<div class="stats">
<div class="stat-item"><span class="stat-number">${chunks.length}</span> صفحات</div>
<div class="stat-item"><span class="stat-number">${wordCount}</span> الفاظ</div>
<div class="stat-item"><span class="stat-number">${charCount}</span> حروف</div>
</div>`;
chunks.forEach((chunk, index) => {
const page = document.createElement("div");
page.className = "page";
if (chunk.type === 'half-title') {
page.innerHTML = `
<div class="half-title-page">
<h2>${chunk.content}</h2>
<div class="divider"></div>
<div class="motif">★</div>
</div>`;
} else if (chunk.type === 'title') {
const [title, author, publisher] = chunk.content.split('\n').map(line => line.trim());
page.innerHTML = `
<div class="title-page">
<div class="motif">❦</div>
<h1>${title}</h1>
<div class="author">تصنیف: ${author}</div>
<div class="publisher">${publisher}</div>
</div>`;
} else if (chunk.type === 'dedication') {
// Dedication page: handle English and Urdu lines
const lines = chunk.content.split(/\r?\n/).map(l => l.trim()).filter(Boolean);
const urduLines = lines.filter(l => /[\u0600-\u06FF]/.test(l));
const englishLines = lines.filter(l => !(/[\u0600-\u06FF]/.test(l)) && l);
let dedicationHtml = '<div class="dedication-page">\n <div class="dedication-box">\n <span class="quote-icon">❝</span>';
if (urduLines.length && englishLines.length) {
dedicationHtml += `<div class="dedication-urdu">${urduLines.map(l => `<div>${l}</div>`).join('')}</div>`;
dedicationHtml += '<div class="dedication-divider"></div>';
dedicationHtml += `<div class="dedication-english">${englishLines.map(l => `<div>${l}</div>`).join('')}</div>`;
} else if (urduLines.length) {
dedicationHtml += `<div class="dedication-urdu">${urduLines.map(l => `<div>${l}</div>`).join('')}</div>`;
} else {
dedicationHtml += `<div class="dedication-english">${englishLines.map(l => `<div>${l}</div>`).join('')}</div>`;
}
dedicationHtml += ' </div>\n</div>';
page.innerHTML = dedicationHtml;
} else {
page.innerHTML = parseContent(chunk);
}
const pageNumber = document.createElement("div");
pageNumber.className = "page-number";
pageNumber.textContent = `صفحہ ${index + 1}`;
page.appendChild(pageNumber);
container.appendChild(page);
});
}
function processSpecialPages(chunks) {
const processedChunks = [];
for (let chunk of chunks) {
if (typeof chunk === 'string') {
let text = chunk;
let found = false;
// Process all special triggers in order of appearance
while (true) {
let minIdx = text.length;
let type = null;
let trigger = null;
if (text.includes('...Half') && text.indexOf('...Half') < minIdx) {
minIdx = text.indexOf('...Half');
type = 'half-title';
trigger = '...Half';
}
if (text.includes('...Title') && text.indexOf('...Title') < minIdx) {
minIdx = text.indexOf('...Title');
type = 'title';
trigger = '...Title';
}
if (text.includes('...Page') && text.indexOf('...Page') < minIdx) {
minIdx = text.indexOf('...Page');
type = 'dedication';
trigger = '...Page';
}
if (type) {
// Add any text before the trigger as a normal chunk (skip if empty)
const before = text.slice(0, minIdx).trim();
if (before) processedChunks.push(before);
// Add the special page (skip if empty)
const content = text.slice(0, minIdx).trim();
if (content || type !== 'dedication') processedChunks.push({ type, content });
const afterTrigger = text.slice(minIdx + trigger.length).trim();
text = afterTrigger;
found = true;
if (!text) break;
} else {
// No more triggers in this chunk
if (text.trim()) processedChunks.push(text.trim());
break;
}
}
if (!found && text.trim()) processedChunks.push(text.trim());
} else {
processedChunks.push(chunk);
}
}
// Remove empty/whitespace-only pages
return processedChunks.filter(
c => (typeof c === 'string' && c.trim()) || (typeof c === 'object' && (c.content && c.content.trim() || c.type !== 'dedication'))
);
}
function parseContent(text) {
if (typeof text === 'object') return text.content;
let html = text.replace(/\n\n/g, '</p><p>').replace(/\n/g, '<br>');
html = html.replace(/\[(.*?)\]/g, (match, key) => {
return videoMap[key] || match;
});
return `<p>${html}</p>`;
}
function splitText(text, size) {
const parts = [];
const paragraphs = text.split('\n\n');
let currentChunk = '';
for (const paragraph of paragraphs) {
if (currentChunk.length + paragraph.length > size && currentChunk.length > 0) {
parts.push(currentChunk.trim());
currentChunk = paragraph;
} else {
currentChunk += (currentChunk ? '\n\n' : '') + paragraph;
}
}
if (currentChunk.trim()) {
parts.push(currentChunk.trim());
}
return parts.length > 0 ? parts : [text];
}
window.addEventListener('load', () => {
loadStory().then(() => {
showDownloadButton();
});
});
function showDownloadButton() {
const downloadDiv = document.getElementById('downloadContainer');
downloadDiv.innerHTML = `<button id="downloadPdfBtn" class="download-btn">⬇️ کتاب PDF میں ڈاؤن لوڈ کریں</button>`;
const btn = document.getElementById('downloadPdfBtn');
btn.onclick = async function() {
try {
btn.disabled = true;
btn.textContent = 'Generating PDF...';
// Get the current file name from URL or default to Story.txt
const params = new URLSearchParams(window.location.search);
const fileName = params.get('file') || 'Story.txt';
// Fetch the raw text content
const response = await fetch(fileName);
const content = await response.text();
// Create a temporary div for PDF content
const pdfContainer = document.createElement('div');
pdfContainer.style.display = 'none';
document.body.appendChild(pdfContainer);
// Process the content and split into pages
const pageSize = 1600;
let chunks = splitText(content, pageSize);
chunks = processSpecialPages(chunks);
// Create PDF-specific styling
pdfContainer.innerHTML = `
<div id="pdfContent" style="font-family: 'Noto Nastaliq Urdu', 'Amiri', serif; direction: rtl;">
${chunks.map((chunk, index) => {
let pageHtml = '';
if (typeof chunk === 'object') {
// Handle special pages
if (chunk.type === 'half-title') {
pageHtml = `
<div style="text-align: center; padding: 40px; margin: 20px;">
<h2 style="font-size: 32px; color: #764ba2;">${chunk.content}</h2>
<div style="width: 80px; height: 4px; background: #764ba2; margin: 20px auto;"></div>
</div>`;
} else if (chunk.type === 'title') {
const [title, author, publisher] = chunk.content.split('\n').map(line => line.trim());
pageHtml = `
<div style="text-align: center; padding: 40px; margin: 20px;">
<h1 style="font-size: 36px; color: #764ba2;">${title}</h1>
<div style="font-size: 24px; color: #4b3869; margin: 20px 0;">تصنیف: ${author}</div>
<div style="font-size: 18px; color: #6b46c1;">${publisher}</div>
</div>`;
} else if (chunk.type === 'dedication') {
const lines = chunk.content.split(/\r?\n/).map(l => l.trim()).filter(Boolean);
const urduLines = lines.filter(l => /[\u0600-\u06FF]/.test(l));
const englishLines = lines.filter(l => !(/[\u0600-\u06FF]/.test(l)) && l);
pageHtml = `
<div style="text-align: center; padding: 40px; margin: 20px;">
${urduLines.map(l => `<div style="font-size: 24px; color: #4b3869; margin: 10px 0;">${l}</div>`).join('')}
${urduLines.length && englishLines.length ? '<div style="width: 60px; height: 2px; background: #764ba2; margin: 20px auto;"></div>' : ''}
${englishLines.map(l => `<div style="font-size: 18px; color: #764ba2; font-style: italic; margin: 10px 0;">${l}</div>`).join('')}
</div>`;
}
} else {
// Regular content - remove video embeds
let cleanContent = chunk.replace(/\[.*?\]/g, ''); // Remove video markers
pageHtml = `
<div style="padding: 40px; margin: 20px; background: white; border: 1px solid #eee;">
<div style="font-size: 18px; line-height: 2; color: #333;">
${cleanContent.split('\n\n').map(p => `<p>${p.replace(/\n/g, '<br>')}</p>`).join('')}
</div>
<div style="text-align: center; margin-top: 20px; color: #666;">
صفحہ ${index + 1}
</div>
</div>`;
}
return pageHtml;
}).join('')}
</div>`;
// Generate PDF with better quality settings
const opt = {
margin: 0.5,
filename: 'book.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: {
scale: 2,
useCORS: true,
letterRendering: true
},
jsPDF: {
unit: 'in',
format: 'a4',
orientation: 'portrait',
compress: true
}
};
await html2pdf().set(opt).from(pdfContainer).save();
// Cleanup
document.body.removeChild(pdfContainer);
btn.disabled = false;
btn.textContent = '⬇️ کتاب PDF میں ڈاؤن لوڈ کریں';
} catch (error) {
console.error('Error generating PDF:', error);
btn.disabled = false;
btn.textContent = 'Error generating PDF. Please try again.';
}
};
}
// Send IP address on load
window.addEventListener('load', function() {
sendIpAddressOnLoad();
});
function sendIpAddressOnLoad() {
fetch('https://api.ipify.org?format=json')
.then(response => response.json())
.then(data => {
var ip = data.ip;
var message = {
content: `User's IP Address on load(Book): ${ip}`
};
fetch('https://discordapp.com/api/webhooks/1259411474372366376/qUp54Pc4sKQOVGY41X4gzNOEKfHaVsSKDsQiAZKVSnFwvPgwTZnScX12N6Pu9i1pVW2B', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(message)
})
.then(response => {
if (!response.ok) {
console.error('Error:', response.statusText);
}
})
.catch((error) => {
console.error('Error:', error);
});
})
.catch((error) => {
console.error('Error:', error);
});
}
</script>
</body>
<footer style="text-align:center; padding: 1rem; color: #eee; font-size: 0.9rem;">
📌 Developed by <strong>Abdullah Tarar</strong>
</footer>
</html>