APPROVIDEO is a modern web application built with the following technology stack:
- Vanilla JavaScript for core functionality
- Tailwind CSS for styling
- LocalForage for client-side data persistence
- Supabase as the backend database and video storage solution
- UI Framework: Vanilla JavaScript with Tailwind CSS
- Custom components built without framework dependencies
- Responsive design using Tailwind utility classes
- Gradient-based theming for visual consistency
-
Client-side Storage:
- LocalForage implementation for offline-capable data access
- Caching strategy for frequently accessed video metadata
- State management for category and tag filtering
-
Backend Integration:
- Supabase real-time database connection
- Video metadata synchronization
- Category and tag relationship management
- Header-based navigation with icon categories
- Dynamic content loading based on category selection
- Fallback views for empty category states
- Subcategory filtering capability
- Metadata display panels for video information
- Tag integration within panels
- Expandable/collapsible panel design
- Efficient loading patterns for video lists
- Hierarchical tag structure
- Category-tag relationships
- Tag-based filtering and search
- Click-through navigation via tags
-
Initial Load:
Supabase -> LocalForage Cache -> UI Display
-
Category Navigation:
User Click -> Category Filter -> LocalForage Query -> UI Update
-
Video Loading:
Panel Selection -> Video Metadata Fetch -> Player Initialization
// Example category loading implementation
async function loadCategory(categoryId) {
try {
// Check local cache first
const cachedData = await localforage.getItem(`category_${categoryId}`);
if (cachedData) {
return renderVideoList(cachedData);
}
// Fetch from Supabase if not in cache
const { data, error } = await supabase
.from('videos')
.select('*')
.eq('category', categoryId);
if (error) throw error;
// Cache the results
await localforage.setItem(`category_${categoryId}`, data);
return renderVideoList(data);
} catch (error) {
handleEmptyState(categoryId);
}
}
function handleEmptyState(categoryId) {
const container = document.querySelector('.video-container');
container.innerHTML = `
<div class="empty-state">
<p>No videos available in this category</p>
<button onclick="showRecommended()">
View Recommended Videos
</button>
</div>
`;
}
-
Caching Strategy:
- Implement aggressive caching for video metadata
- Use LocalForage for offline-first capability
- Regular cache invalidation for fresh content
-
Loading Optimization:
- Lazy loading for video panels
- Progressive loading for category views
- Preloading for anticipated user actions
-
Resource Management:
- Efficient video player initialization
- Memory management for video instances
- Cleanup routines for unused resources
-
Planned Features:
- Enhanced tag navigation system
- Advanced filtering capabilities
- Improved category failover handling
- User preference persistence
-
Technical Debt:
- Refactor category loading for better performance
- Implement comprehensive error handling
- Optimize LocalForage usage patterns
-
Regular Tasks:
- Cache cleanup routines
- Database synchronization checks
- Performance monitoring
- Error logging and analysis
-
Update Procedures:
- Document version control
- Database schema migrations
- Client-side cache invalidation
- Feature flag management
constructor()
- Initialize properties and start appinit()
- Setup initial state and load videossetupEventListeners()
- Attach event handlers
loadVideos()
- Fetch videos from SupabaseshowSkeletonLoader()
- Show loading placeholdercreateSkeletonCard()
- Create loading placeholder cardrenderVideos(videos)
- Display video gridcreateVideoCard(video)
- Create single video cardrenderPanels(panels)
- Render video panels sectionrenderTags(tags)
- Render video tagsshowError(message)
- Display error message
setupInfiniteScroll()
- Handle infinite scrollinghandleCategoryClick(button)
- Handle category selectionresetAndReload()
- Reset view and reload videosgetCategoryIcon(category)
- Get icon for category
filterAndSortVideos()
- Filter and sort video listrenderCategories(videos)
- Render category sectionshandleVideoDetailClick(e)
- Handle video detail viewcloseVideoDetail()
- Close video detail viewhandleCategoryClick(e)
- Handle category selection
getRandomColor()
- Get random color for UI elementsgetRandomSize()
- Get random size for UI elementsupdateURLAndFilter(category, tag)
- Update URL parameters and filterclearSearchAndFilter(category, tag)
- Clear search and filter state
document.addEventListener('DOMContentLoaded', () => {
// Initialize PublicVideoPortal
new PublicVideoPortal();
// Setup category navigation
const mainCategories = document.querySelectorAll('.group > a');
const mondrianBox = document.getElementById('mondrian-box');
const subcategoryLinks = document.getElementById('subcategory-links');
// ... setup event listeners
});
safeHtml.escape(str)
- Escape HTML special characterssafeHtml.escapeObject(obj)
- Escape object properties
- Supabase client configuration and setup
- Search input changes
- Category button clicks
- Sort select changes
- Infinite scroll detection
- Profile dropdown toggle
- Dark mode toggle
- Subcategory selection
- Video detail view
- URL parameter handling
- Each function should handle one specific task
- Event listeners should be properly cleaned up when needed
- Error handling should be consistent throughout
- DOM queries should be cached when possible
- Performance considerations for infinite scroll
- Proper sanitization of user input and database data
This structure follows these design patterns:
- Single Responsibility Principle
- Event Delegation
- Progressive Enhancement
- Responsive Loading
- Error Boundary Pattern
SAFEUTILS
-________________
The provided SafeHtmlUtils class is a well-written utility for safely handling HTML content and preventing XSS attacks. Here's a breakdown and some potential areas for improvement:
Breakdown:
Constructor: Creates a map of HTML entity equivalents for efficient escaping.
escape(str): Escapes special characters in a string using a regular expression and the character map. Handles potential null/undefined inputs and errors.
escapeObject(obj): Recursively escapes string properties within an object. Catches errors and returns the original object if an error occurs.
createElement(tag, attributes, content): Creates a safe HTML element with escaped content, attributes, and optional content (which can be a string or an array of strings). Handles errors.
createLink(url, text, attributes): Creates a safe anchor tag with escaped URL, text content, and additional attributes. Adds rel="noopener noreferrer" for security.
sanitizeClasses(classes): Validates and sanitizes a CSS class string by removing any non-alphanumeric characters, underscores, hyphens, and spaces. Handles errors.TILS
-________________
The provided SafeHtmlUtils class is a well-written utility for safely handling HTML content and preventing XSS attacks. Here's a breakdown and some potential areas for improvement:
Breakdown:
Constructor: Creates a map of HTML entity equivalents for efficient escaping.
escape(str): Escapes special characters in a string using a regular expression and the character map. Handles potential null/undefined inputs and errors.
escapeObject(obj): Recursively escapes string properties within an object. Catches errors and returns the original object if an error occurs.
createElement(tag, attributes, content): Creates a safe HTML element with escaped content, attributes, and optional content (which can be a string or an array of strings). Handles errors.
createLink(url, text, attributes): Creates a safe anchor tag with escaped URL, text content, and additional attributes. Adds rel="noopener noreferrer" for security.
sanitizeClasses(classes): Validates and sanitizes a CSS class string by removing any non-alphanumeric characters, underscores, hyphens, and spaces. Handles errors.