/
BirdLeon
/
pcsocial
Обзор
Документация
Войти
/
BirdLeon
/
pcsocial
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
JS/utils.js
427 строк
12 KB
BirdLeon
create: README-1.md, ИНСТРУКЦИЯ.txt, ПОЛНАЯ_ДОКУМЕНТАЦИЯ.md, New file, auth.js, feed.js, main.js, messages.js, profile.js, utils.js, responsive.css, styles.css, index.html, logo.png, logo.svg, database.sql
23 фев 2026, 18:54
Верифицирован
23 фев 2026, 18:54
76579db
Код
Авторство
О чём код?
/* ==================== UTILS.JS - УТИЛИТЫ И ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ==================== */ // API Helper class APIHelper { static async request(endpoint, options = {}) { const url = `${API_BASE}${endpoint}`; const headers = { 'Content-Type': 'application/json', ...options.headers }; const token = getAuthToken(); if (token) { headers['Authorization'] = `Bearer ${token}`; } try { const response = await fetch(url, { ...options, headers, timeout: API_TIMEOUT }); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } return await response.json(); } catch (error) { console.error('API Error:', error); throw error; } } static get(endpoint, options = {}) { return this.request(endpoint, { method: 'GET', ...options }); } static post(endpoint, data, options = {}) { return this.request(endpoint, { method: 'POST', body: JSON.stringify(data), ...options }); } static put(endpoint, data, options = {}) { return this.request(endpoint, { method: 'PUT', body: JSON.stringify(data), ...options }); } static delete(endpoint, options = {}) { return this.request(endpoint, { method: 'DELETE', ...options }); } } // Date/Time utilities const DateUtils = { formatDate(date) { return new Date(date).toLocaleDateString('ru-RU'); }, formatTime(date) { return new Date(date).toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' }); }, formatDateTime(date) { const now = new Date(); const then = new Date(date); const diffMs = now - then; const diffMins = Math.floor(diffMs / 60000); const diffHours = Math.floor(diffMs / 3600000); const diffDays = Math.floor(diffMs / 86400000); if (diffMins < 1) return 'только что'; if (diffMins < 60) return `${diffMins} мин назад`; if (diffHours < 24) return `${diffHours} часов назад`; if (diffDays < 7) return `${diffDays} дней назад`; return this.formatDate(date); }, getTimeUntil(futureDate) { const now = new Date(); const future = new Date(futureDate); const diffMs = future - now; if (diffMs < 0) return 'истекло'; const days = Math.floor(diffMs / 86400000); const hours = Math.floor((diffMs % 86400000) / 3600000); const minutes = Math.floor((diffMs % 3600000) / 60000); if (days > 0) return `${days}д ${hours}ч`; if (hours > 0) return `${hours}ч ${minutes}м`; return `${minutes}м`; } }; // String utilities const StringUtils = { truncate(str, length = 50) { return str.length > length ? str.substring(0, length) + '...' : str; }, capitalize(str) { return str.charAt(0).toUpperCase() + str.slice(1); }, escapeHtml(text) { const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return text.replace(/[&<>"']/g, m => map[m]); }, unescapeHtml(text) { const map = { '&': '&', '<': '<', '>': '>', '"': '"', ''': "'" }; return text.replace(/&[a-z]+;/g, m => map[m] || m); }, slugify(str) { return str.toLowerCase() .trim() .replace(/[^\w\s-]/g, '') .replace(/[\s_-]+/g, '-') .replace(/^-+|-+$/g, ''); }, highlightMatches(text, query) { const regex = new RegExp(`(${query})`, 'gi'); return text.replace(regex, '<mark>$1</mark>'); }, getHashtags(text) { const hashtags = text.match(/#[\w]+/g) || []; return hashtags.map(tag => tag.substring(1)); }, getMentions(text) { const mentions = text.match(/@[\w]+/g) || []; return mentions.map(mention => mention.substring(1)); } }; // Storage utilities const StorageUtils = { setItem(key, value) { try { localStorage.setItem(key, JSON.stringify(value)); } catch (error) { console.error('Storage error:', error); } }, getItem(key, defaultValue = null) { try { const item = localStorage.getItem(key); return item ? JSON.parse(item) : defaultValue; } catch (error) { console.error('Storage error:', error); return defaultValue; } }, removeItem(key) { try { localStorage.removeItem(key); } catch (error) { console.error('Storage error:', error); } }, clear() { try { localStorage.clear(); } catch (error) { console.error('Storage error:', error); } } }; // Validation utilities const ValidationUtils = { isEmail(email) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); }, isUsername(username) { return /^[a-zA-Z0-9_]{3,20}$/.test(username); }, isPassword(password) { return password.length >= 6; }, isPhone(phone) { return /^\+?[\d\s\-()]+$/.test(phone); }, isURL(url) { try { new URL(url); return true; } catch { return false; } }, isEmpty(value) { return !value || (typeof value === 'string' && value.trim() === ''); }, isCreditCard(number) { return /^\d{13,19}$/.test(number.replace(/\D/g, '')); } }; // File utilities const FileUtils = { getFileExtension(filename) { return filename.split('.').pop().toLowerCase(); }, getFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]; }, isImageFile(filename) { const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg']; return imageExtensions.includes(this.getFileExtension(filename)); }, isVideoFile(filename) { const videoExtensions = ['mp4', 'webm', 'mov', 'avi', 'mkv']; return videoExtensions.includes(this.getFileExtension(filename)); }, isAudioFile(filename) { const audioExtensions = ['mp3', 'wav', 'flac', 'aac', 'ogg']; return audioExtensions.includes(this.getFileExtension(filename)); } }; // Image utilities const ImageUtils = { loadImage(url) { return new Promise((resolve, reject) => { const img = new Image(); img.onload = () => resolve(img); img.onerror = () => reject(new Error('Failed to load image')); img.src = url; }); }, resizeImage(file, maxWidth, maxHeight) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (e) => { const img = new Image(); img.onload = () => { const canvas = document.createElement('canvas'); let width = img.width; let height = img.height; if (width > height) { if (width > maxWidth) { height *= maxWidth / width; width = maxWidth; } } else { if (height > maxHeight) { width *= maxHeight / height; height = maxHeight; } } canvas.width = width; canvas.height = height; canvas.getContext('2d').drawImage(img, 0, 0, width, height); canvas.toBlob(resolve, 'image/jpeg', 0.8); }; img.src = e.target.result; }; reader.readAsDataURL(file); }); } }; // Browser utilities const BrowserUtils = { getOS() { const userAgent = navigator.userAgent.toLowerCase(); if (userAgent.indexOf('win') > -1) return 'Windows'; if (userAgent.indexOf('mac') > -1) return 'macOS'; if (userAgent.indexOf('linux') > -1) return 'Linux'; if (userAgent.indexOf('android') > -1) return 'Android'; if (userAgent.indexOf('iphone') > -1) return 'iOS'; return 'Unknown'; }, getBrowser() { const userAgent = navigator.userAgent; if (userAgent.indexOf('Firefox') > -1) return 'Firefox'; if (userAgent.indexOf('Chrome') > -1) return 'Chrome'; if (userAgent.indexOf('Safari') > -1) return 'Safari'; if (userAgent.indexOf('MSIE') > -1 || userAgent.indexOf('Trident') > -1) return 'IE'; return 'Unknown'; }, isMobile() { return /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()); }, isOnline() { return navigator.onLine; }, hasNotificationSupport() { return 'Notification' in window; }, requestNotificationPermission() { if ('Notification' in window && Notification.permission === 'default') { Notification.requestPermission(); } } }; // Analytics (placeholder) const Analytics = { trackEvent(category, action, label, value) { console.log('Event tracked:', { category, action, label, value }); // Implement with Google Analytics or similar }, trackPageView(page) { console.log('Page view tracked:', page); // Implement with Google Analytics or similar }, trackError(error) { console.error('Error tracked:', error); // Send to error tracking service } }; // Notification utilities const NotificationUtils = { show(title, options = {}) { if ('Notification' in window && Notification.permission === 'granted') { new Notification(title, { icon: 'assets/images/logo.svg', ...options }); } }, showFromPage(title, options = {}) { const notification = document.createElement('div'); notification.className = 'notification-toast'; notification.innerHTML = ` <div style="padding: 15px; background: ${options.color || '#333'}; color: white; border-radius: 8px;"> <strong>${title}</strong> ${options.message ? `<p>${options.message}</p>` : ''} </div> `; notification.style.cssText = ` position: fixed; top: 20px; right: 20px; z-index: 9999; animation: slideInRight 0.3s ease; `; document.body.appendChild(notification); setTimeout(() => { notification.style.animation = 'slideOutRight 0.3s ease'; setTimeout(() => notification.remove(), 300); }, options.duration || 3000); } }; // Performance monitoring const PerformanceMonitor = { startMeasure(name) { performance.mark(`${name}-start`); }, endMeasure(name) { performance.mark(`${name}-end`); performance.measure(name, `${name}-start`, `${name}-end`); const measure = performance.getEntriesByName(name)[0]; console.log(`${name}: ${measure.duration.toFixed(2)}ms`); } }; // Export all utilities window.APIHelper = APIHelper; window.DateUtils = DateUtils; window.StringUtils = StringUtils; window.StorageUtils = StorageUtils; window.ValidationUtils = ValidationUtils; window.FileUtils = FileUtils; window.ImageUtils = ImageUtils; window.BrowserUtils = BrowserUtils; window.Analytics = Analytics; window.NotificationUtils = NotificationUtils; window.PerformanceMonitor = PerformanceMonitor;