Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

44 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🌐 Zyro Browser

Zyro Browser Architecture Banner

Zyro Tech Stack Badges

Overview β€’ Features β€’ Architecture β€’ Structure β€’ Installation β€’ Platform Channels β€’ Developer

Flutter Dart Node.js FFmpeg Android


🌌 Overview

Zyro Browser is a premium, high-performance mobile web browser for Android built with Flutter, featuring a futuristic Cyber-Bento design language. It combines a high-fidelity Flutter client with a dedicated Node.js/FFmpeg media microservice β€” offering native ad blocking, local internet usage analytics, smart video download, background audio playback, home screen web app installation, page QR sharing, per-site permission management, full-page screenshot capture with PDF export, and a sandboxed extension ecosystem.

✨ Zyro is not a WebView wrapper with a thin UI shell. It is a complete, vertically integrated browser stack β€” from the Android foreground service layer through the Flutter extension engine to the Node.js stream extraction pipeline.


πŸš€ Why Zyro Browser?

Capability Description
🎨 Cyber-Bento Design Glassmorphic, futuristic UI with Outfit typography and a deep indigo/teal/cyan palette
πŸ›‘οΈ Native Ad Blocking Multi-layer request interceptor with 35+ rules blocking ads, trackers, beacons, and popunders
πŸ“Š Ad Block Analytics Persistent per-domain blocked-request counters with daily reset and lifetime totals
πŸ“ˆ Usage Analytics Local-only estimated internet usage by domain with today, monthly, and all-time views
🎡 Background Playback Uninterrupted audio/video via Android MediaSession foreground service with lock-screen controls
🎬 Smart Video Detection JavaScript-based detection across YouTube, Vimeo, Facebook, Instagram, Twitter/X, Dailymotion
πŸ“₯ Media Download Pipeline yt-dlp metadata extraction β†’ adaptive stream download β†’ FFmpeg merge β†’ static file hosting
πŸ“Έ Screenshot Pro Floating capture button with viewport screenshot, full-page scrolling stitch, PNG save, A4 PDF export
πŸ“± Web App Installer Install any website as an Android home screen shortcut with manifest parsing and shortcut lifecycle sync
β–£ Page QR Code Address-bar QR action generates a compact scannable QR popup for the current page URL
πŸ” Website Permissions Per-site allow/ask/block controls for Camera, Microphone, Location, Notifications, and Clipboard
πŸ”Œ Extension Ecosystem Sandboxed extension registry with install/uninstall/enable/disable lifecycle and persistent state
πŸ—‚οΈ Tab Groups Full grouped tab management alongside standalone tabs with session persistence
πŸ•΅οΈ Incognito Mode Global incognito mode with dedicated theme and session isolation
πŸ› οΈ Dev Tools Extension Built-in element inspector, console viewer, network logger, and storage explorer

✨ Feature Matrix

🧭 Browser Core
Feature Status
flutter_inappwebview-powered WebView βœ… Implemented
Multi-tab management (standalone + grouped) βœ… Implemented
Tab session persistence across restarts βœ… Implemented
Tab groups with color labels βœ… Implemented
Incognito mode (global toggle) βœ… Implemented
Undo tab close (5-second window) βœ… Implemented
Desktop mode per tab βœ… Implemented
Find-in-page βœ… Implemented
Smart address bar (search vs. URL routing) βœ… Implemented
Popup window / new tab handling βœ… Implemented
History tracking βœ… Implemented
Bookmark system βœ… Implemented
Reading list βœ… Implemented (in-memory only)
Favorites βœ… Implemented (in-memory only)
Share page βœ… Implemented (share_plus)
Address-bar Page QR Code βœ… Implemented (qr_flutter)
πŸ“ˆ Internet Usage Analytics
Feature Status
WebView request observation βœ… Implemented
Local domain normalization (m., www. grouping) βœ… Implemented
Estimated bytes by website/domain βœ… Implemented
Today, this-month, and all-time totals βœ… Implemented
Top websites sorted by highest usage βœ… Implemented
Domain rows with favicon, usage, percentage, and progress bar βœ… Implemented
Persistent storage via SharedPreferences βœ… Implemented
Clear usage data with confirmation βœ… Implemented
Settings entry: Usage βœ… Implemented
Local-only privacy note βœ… Implemented
πŸ›‘οΈ Ad Blocker
Feature Status
URL-pattern request interception (35+ rules) βœ… Implemented
Tracker / beacon / analytics blocking βœ… Implemented
Google Ads / DoubleClick / Syndication blocking βœ… Implemented
Facebook pixel / GTM / Google Analytics blocking βœ… Implemented
AppNexus, PubMatic, Criteo, Taboola, Outbrain βœ… Implemented
Pop-under / pop-up blocking βœ… Implemented
YouTube ad cosmetic injection βœ… Implemented
Generic cosmetic filter injection βœ… Implemented
Per-domain blocked-request analytics βœ… Implemented
Today-blocked counter with daily reset βœ… Implemented
Lifetime total blocked counter βœ… Implemented
Ad block analytics dashboard (Settings UI) βœ… Implemented
Toggle ad blocker per extension βœ… Implemented
πŸ“Έ Screenshot Pro
Feature Status
Floating screenshot FAB on browser βœ… Implemented
Visible viewport screenshot βœ… Implemented
Full-page scrolling stitch capture (max 16000px height) βœ… Implemented
Scroll-behavior override during capture βœ… Implemented
Scroll-position restoration after capture βœ… Implemented
PNG save to device storage (screenshots subfolder) βœ… Implemented
Multi-page A4 PDF export βœ… Implemented
Native WebView PDF export via zyro/screenshot_pro channel βœ… Implemented
Progress dialog during capture βœ… Implemented
Persistent enable/disable toggle βœ… Implemented
πŸ“± Web App Installer
Feature Status
Web App Manifest detection from DOM βœ… Implemented
Manifest icon download & local caching βœ… Implemented
Bitmap decode + normalization (blank/too-small fallback) βœ… Implemented
Android home screen shortcut pinning (API 26+) βœ… Implemented
Shortcut intent routing back to browser βœ… Implemented
Shortcut URL validation (http/https only) βœ… Implemented
Installed app list (Zyro Apps) βœ… Implemented
Pinned shortcut ID synchronization βœ… Implemented
Shortcut launch handling on cold start βœ… Implemented
Shortcut launch handling on warm resume βœ… Implemented
Shortcut sync against pinned Android shortcuts βœ… Implemented
β–£ Page QR Code
Feature Status
QR icon in the address bar βœ… Implemented
Current-page URL validation (http/https only) βœ… Implemented
Compact QR popup with domain and URL βœ… Implemented
High-contrast QR rendering via qr_flutter βœ… Implemented
Invalid/internal URL snackbar βœ… Implemented
πŸ” Website Permissions Manager
Permission Status
Camera βœ… Implemented
Microphone βœ… Implemented
Location (locationWhenInUse) βœ… Implemented
Notifications βœ… Implemented
Clipboard (read) βœ… Implemented
Allow / Ask every time / Block per domain βœ… Implemented
Persistent storage via SharedPreferences βœ… Implemented
Android runtime permission escalation βœ… Implemented
Per-site permission management UI βœ… Implemented
Per-permission category browser βœ… Implemented
🎡 Background Media Playback
Feature Status
Android foreground service (startForegroundService) βœ… Implemented
MediaSession with transport controls βœ… Implemented
Lock-screen play / pause / next / previous βœ… Implemented
Seek via lock-screen progress bar βœ… Implemented
PARTIAL_WAKE_LOCK (30 min) βœ… Implemented
Notification channel (Importance: Low, no badge) βœ… Implemented
Media state sync (title, website, duration, position) βœ… Implemented
JavaScript bridge: play/pause/next/prev/seek βœ… Implemented
Background player extension toggle βœ… Implemented
Service auto-stop on tab close βœ… Implemented
πŸ“₯ Video Download Engine
Feature Status
Real-time video detection via JavaScript DOM polling βœ… Implemented
YouTube, Vimeo, Facebook, Instagram, Twitter/X, Dailymotion βœ… Implemented
Direct .mp4, .mkv, .webm URL detection βœ… Implemented
yt-dlp metadata extraction (youtube-dl-exec) βœ… Implemented
Adaptive format selection (separate video + audio) βœ… Implemented
Progressive stream detection (video+audio combined) βœ… Implemented
FFmpeg video+audio stream merge βœ… Implemented
FFmpeg audio-only β†’ 320kbps MP3 conversion βœ… Implemented
Background download task with UUID tracking βœ… Implemented
Real-time task status polling βœ… Implemented
Playlist download rejection βœ… Implemented
Floating download HUD βœ… Implemented
Quality selector bottom sheet βœ… Implemented
Download library screen βœ… Implemented
Video height validation after download βœ… Implemented
URL sanitizer (strips tracking params) βœ… Implemented
Android DownloadManager integration βœ… Implemented
MediaStore device storage save βœ… Implemented
Local in-app video player βœ… Implemented
πŸ”Œ Extension Ecosystem
Extension ID Default State
Ad Blocker & Downloader ad_blocker_downloader Installed + Enabled
Dev Tools dev_tools Installed, Disabled
Background Player background_player Installed, Disabled
Dark Reader dark_mode Available (not installed)
KeyGen password_gen Available (not installed)

🧭 Architecture Overview

Zyro Browser Core Architecture Flow

✨ Live data-flow animation β€” glowing dots travel the connector lines to show requests, messages, and files moving through the system in real time.

High-Level System Layers

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         Android Device                               β”‚
β”‚                                                                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ Flutter Application ───────────────────────┐  β”‚
β”‚  β”‚                                                               β”‚  β”‚
β”‚  β”‚   Cyber-Bento UI         Extension Engine                     β”‚  β”‚
β”‚  β”‚   (Widgets/Screens)      (AdBlock, BG Player, Dev Tools)      β”‚  β”‚
β”‚  β”‚                                                               β”‚  β”‚
β”‚  β”‚   ─────────────────── Core Layer ─────────────────────────   β”‚  β”‚
β”‚  β”‚   TabManager β”‚ WebViewWrapper β”‚ BrowserDataManager            β”‚  β”‚
β”‚  β”‚   ExtensionManager β”‚ ScriptEngine                             β”‚  β”‚
β”‚  β”‚                                                               β”‚  β”‚
β”‚  β”‚   ──────────────── Feature Modules ────────────────────────  β”‚  β”‚
β”‚  β”‚   Screenshot Pro β”‚ Web Apps β”‚ Permissions β”‚ Usage Analytics     β”‚  β”‚
β”‚  β”‚   Video Downloader β”‚ Download Library β”‚ Settings β”‚ Page QR       β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                             β”‚ MethodChannels                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚            Native Kotlin (MainActivity.kt)                    β”‚  β”‚
β”‚  β”‚  zyro/downloads β”‚ zyro/screenshot_pro                         β”‚  β”‚
β”‚  β”‚  zyro/web_apps  β”‚ zyro/background_player                      β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                               β”‚                                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚     BackgroundPlayerService.kt (Android Foreground Service)   β”‚  β”‚
β”‚  β”‚     MediaSession β”‚ WakeLock β”‚ NotificationChannel             β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚ HTTP (localhost:3000)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Node.js Media Microservice                         β”‚
β”‚  Express  β”‚  youtube-dl-exec (yt-dlp)  β”‚  fluent-ffmpeg  β”‚  uuid    β”‚
β”‚                                                                      β”‚
β”‚  POST /api/video/metadata  β†’ VideoExtractor β†’ yt-dlp                β”‚
β”‚  POST /api/video/download  β†’ FormatSelector β†’ DownloadManager        β”‚
β”‚                            β†’ MergeService (FFmpeg)                  β”‚
β”‚  GET  /api/video/status/:id β†’ Task state polling                    β”‚
β”‚  GET  /downloads/:file     β†’ Static file serving                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“¦ Project Structure

zyro/
β”‚
β”œβ”€β”€ πŸ“± zyro-frontend/                     Flutter Android application
β”‚   β”œβ”€β”€ lib/
β”‚   β”‚   β”œβ”€β”€ main.dart                     App entry; MultiProvider setup
β”‚   β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”‚   β”œβ”€β”€ tab_manager.dart          Multi-tab + group session manager
β”‚   β”‚   β”‚   β”œβ”€β”€ webview_wrapper.dart      WebView config, JS bridge, intercepts
β”‚   β”‚   β”‚   β”œβ”€β”€ extension_manager.dart    Extension registry + lifecycle
β”‚   β”‚   β”‚   β”œβ”€β”€ browser_data_manager.dart History, bookmarks, downloads, DL polling
β”‚   β”‚   β”‚   β”œβ”€β”€ globals.dart              Global navigator/scaffold keys
β”‚   β”‚   β”‚   β”œβ”€β”€ constants/app_assets.dart Asset path constants
β”‚   β”‚   β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ tab_model.dart        Tab state (url, title, favicon, scroll...)
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ extension_model.dart  Extension definition + lifecycle state
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ bookmark_item.dart
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ history_item.dart
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ download_item.dart
β”‚   β”‚   β”‚   β”‚   └── link_metadata.dart    Long-press link context model
β”‚   β”‚   β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ tab_session_storage_service.dart
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ extension_storage_service.dart
β”‚   β”‚   β”‚   β”‚   └── extension_notification_service.dart
β”‚   β”‚   β”‚   └── theme/
β”‚   β”‚   β”‚       β”œβ”€β”€ app_colors.dart       Color palette (light/dark)
β”‚   β”‚   β”‚       β”œβ”€β”€ app_theme.dart        MaterialApp themes
β”‚   β”‚   β”‚       β”œβ”€β”€ theme_controller.dart
β”‚   β”‚   β”‚       └── theme_storage_service.dart
β”‚   β”‚   β”œβ”€β”€ engine/
β”‚   β”‚   β”‚   β”œβ”€β”€ hooks.dart                BrowserHooks interface
β”‚   β”‚   β”‚   └── script_engine.dart        JS injection coordinator
β”‚   β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”‚   β”œβ”€β”€ screens/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ browser_main.dart     Main browser scaffold
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ tab_switcher.dart     Tab manager UI + groups
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ history_screen.dart
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ bookmarks_screen.dart
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ extensions_screen.dart
β”‚   β”‚   β”‚   β”‚   └── local_video_player_screen.dart
β”‚   β”‚   β”‚   └── widgets/
β”‚   β”‚   β”‚       β”œβ”€β”€ cyber_menu.dart       Cyber-Bento navigation drawer
β”‚   β”‚   β”‚       β”œβ”€β”€ glass_app_bar.dart    Glassmorphic URL/search bar
β”‚   β”‚   β”‚       β”œβ”€β”€ glass_container.dart
β”‚   β”‚   β”‚       └── link_context_menu_sheet.dart
β”‚   β”‚   └── features/
β”‚   β”‚       β”œβ”€β”€ splash/screens/splash_screen.dart
β”‚   β”‚       β”œβ”€β”€ screenshot_pro/
β”‚   β”‚       β”‚   β”œβ”€β”€ controllers/screenshot_pro_controller.dart
β”‚   β”‚       β”‚   β”œβ”€β”€ models/screenshot_capture_result.dart
β”‚   β”‚       β”‚   β”œβ”€β”€ services/
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ screenshot_capture_service.dart    (viewport PNG)
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ full_page_capture_service.dart     (scroll stitch)
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ screenshot_pdf_export_service.dart (A4 PDF export)
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ pdf_export_service.dart
β”‚   β”‚       β”‚   β”‚   └── screenshot_pro_settings_service.dart
β”‚   β”‚       β”‚   β”œβ”€β”€ screens/screenshot_pro_sheet.dart
β”‚   β”‚       β”‚   └── widgets/
β”‚   β”‚       β”‚       β”œβ”€β”€ screenshot_floating_button.dart
β”‚   β”‚       β”‚       β”œβ”€β”€ screenshot_options_sheet.dart
β”‚   β”‚       β”‚       β”œβ”€β”€ screenshot_option_tile.dart
β”‚   β”‚       β”‚       └── capture_progress_dialog.dart
β”‚   β”‚       β”œβ”€β”€ web_apps/
β”‚   β”‚       β”‚   β”œβ”€β”€ controllers/web_app_installer_controller.dart
β”‚   β”‚       β”‚   └── services/web_app_shortcut_channel.dart
β”‚   β”‚       β”œβ”€β”€ permissions/
β”‚   β”‚       β”‚   β”œβ”€β”€ controllers/website_permissions_controller.dart
β”‚   β”‚       β”‚   β”œβ”€β”€ models/
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ permission_enums.dart
β”‚   β”‚       β”‚   β”‚   └── website_permission_rule.dart
β”‚   β”‚       β”‚   β”œβ”€β”€ services/
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ website_permission_manager.dart
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ website_permission_storage_service.dart
β”‚   β”‚       β”‚   β”‚   └── domain_normalizer.dart
β”‚   β”‚       β”‚   β”œβ”€β”€ screens/
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ website_permissions_screen.dart
β”‚   β”‚       β”‚   β”‚   └── permission_category_screen.dart
β”‚   β”‚       β”‚   └── widgets/
β”‚   β”‚       β”‚       β”œβ”€β”€ permission_request_dialog.dart
β”‚   β”‚       β”‚       β”œβ”€β”€ permission_site_tile.dart
β”‚   β”‚       β”‚       β”œβ”€β”€ permission_status_selector.dart
β”‚   β”‚       β”‚       └── permission_summary_card.dart
β”‚   β”‚       β”œβ”€β”€ usage/
β”‚   β”‚       β”‚   β”œβ”€β”€ controllers/usage_controller.dart
β”‚   β”‚       β”‚   β”œβ”€β”€ models/
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ usage_entry.dart
β”‚   β”‚       β”‚   β”‚   └── usage_period.dart
β”‚   β”‚       β”‚   β”œβ”€β”€ services/
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ domain_usage_normalizer.dart
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ usage_format_service.dart
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ usage_storage_service.dart
β”‚   β”‚       β”‚   β”‚   └── usage_tracking_service.dart
β”‚   β”‚       β”‚   β”œβ”€β”€ screens/usage_screen.dart
β”‚   β”‚       β”‚   └── widgets/
β”‚   β”‚       β”‚       β”œβ”€β”€ usage_period_filter.dart
β”‚   β”‚       β”‚       β”œβ”€β”€ usage_progress_bar.dart
β”‚   β”‚       β”‚       β”œβ”€β”€ usage_summary_card.dart
β”‚   β”‚       β”‚       └── usage_website_tile.dart
β”‚   β”‚       β”œβ”€β”€ extensions/
β”‚   β”‚       β”‚   β”œβ”€β”€ ad_blocker/
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ models/ad_block_stats_model.dart
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ services/
β”‚   β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ ad_block_service.dart
β”‚   β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ ad_block_rule_engine.dart     (35+ regex rules)
β”‚   β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ ad_block_stats_service.dart   (analytics)
β”‚   β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ youtube_ad_blocker_service.dart
β”‚   β”‚       β”‚   β”‚   β”‚   └── cosmetic_filter_injector.dart
β”‚   β”‚       β”‚   β”‚   └── widgets/ad_block_settings_stats_widget.dart
β”‚   β”‚       β”‚   β”œβ”€β”€ background_player/
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ background_player_service.dart
β”‚   β”‚       β”‚   β”‚   └── platform/background_player_channel.dart
β”‚   β”‚       β”‚   β”œβ”€β”€ dev_tools/
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ dev_tools_controller.dart
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ dev_tools_extension.dart
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ dev_tools_models.dart
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ dev_tools_service.dart
β”‚   β”‚       β”‚   β”‚   └── widgets/
β”‚   β”‚       β”‚   β”œβ”€β”€ floating_videos/      [Scaffolded β€” not yet implemented]
β”‚   β”‚       β”‚   └── widgets/extension_overview_dialog.dart
β”‚   β”‚       β”œβ”€β”€ video_downloader/
β”‚   β”‚       β”‚   β”œβ”€β”€ controllers/download_controller.dart
β”‚   β”‚       β”‚   β”œβ”€β”€ models/
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ current_playing_video.dart
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ download_request.dart
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ downloaded_video.dart
β”‚   β”‚       β”‚   β”‚   └── video_format.dart
β”‚   β”‚       β”‚   β”œβ”€β”€ services/
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ video_detection_service.dart
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ download_api_service.dart
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ format_mapper_service.dart
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ local_storage_service.dart
β”‚   β”‚       β”‚   β”‚   β”œβ”€β”€ media_store_service.dart
β”‚   β”‚       β”‚   β”‚   └── url_sanitizer_service.dart
β”‚   β”‚       β”‚   └── widgets/
β”‚   β”‚       β”‚       β”œβ”€β”€ floating_download_button.dart
β”‚   β”‚       β”‚       └── quality_selector_sheet.dart
β”‚   β”‚       β”œβ”€β”€ download_library/screens/downloads_screen.dart
β”‚   β”‚       β”œβ”€β”€ video_player/screens/
β”‚   β”‚       └── settings/screens/
β”‚   β”‚           β”œβ”€β”€ settings_screen.dart
β”‚   β”‚           └── developer_info_screen.dart
β”‚   β”œβ”€β”€ assets/logo.png
β”‚   └── android/app/src/main/kotlin/com/example/zyro/
β”‚       β”œβ”€β”€ MainActivity.kt               Platform channel hub
β”‚       β”œβ”€β”€ BackgroundPlayerService.kt    Android foreground media service
β”‚       └── BackgroundPlayerConfirmActivity.kt
β”‚
└── βš™οΈ zyro-backend/                      Node.js media microservice
    β”œβ”€β”€ src/
    β”‚   β”œβ”€β”€ server.js                     Express entry (port 3000)
    β”‚   β”œβ”€β”€ routes/download.routes.js
    β”‚   β”œβ”€β”€ controllers/download.controller.js
    β”‚   β”œβ”€β”€ services/
    β”‚   β”‚   β”œβ”€β”€ videoExtractor.service.js (yt-dlp metadata extraction)
    β”‚   β”‚   β”œβ”€β”€ formatSelector.service.js (adaptive format selection)
    β”‚   β”‚   β”œβ”€β”€ downloadManager.service.js (stream download executor)
    β”‚   β”‚   β”œβ”€β”€ merge.service.js          (FFmpeg merge + MP3 conversion)
    β”‚   β”‚   β”œβ”€β”€ fileManager.service.js    (paths, dirs, verification)
    β”‚   β”‚   └── urlSanitizer.service.js   (URL cleaning)
    β”‚   └── middleware/errorHandler.js
    β”œβ”€β”€ downloads/                        Completed files (static)
    β”œβ”€β”€ temp/                             FFmpeg workspace
    └── package.json

πŸ—οΈ Flutter Architecture

Zyro follows a feature-first, provider-driven architecture:

main.dart β†’ MultiProvider β†’ ZyroApp β†’ SplashScreen β†’ BrowserMainScreen
                β”‚
                β”œβ”€β”€ ThemeController           theme mode persistence
                β”œβ”€β”€ TabManager                tabs + groups + session
                β”œβ”€β”€ BrowserDataManager        history, bookmarks, downloads
                β”œβ”€β”€ ExtensionManager          extension registry + lifecycle
                β”œβ”€β”€ DownloadController        download state + polling
                β”œβ”€β”€ DevToolsController        dev tools state
                β”œβ”€β”€ AdBlockStatsService       ad block analytics
                β”œβ”€β”€ ScreenshotProController   screenshot enable/expand state
                β”œβ”€β”€ WebAppInstallerController installed apps + shortcut sync
                β”œβ”€β”€ WebsitePermissionsController per-site permission rules
                └── UsageTrackingService      local usage estimates by domain

State Management: Flutter Provider / ChangeNotifier throughout. Persistence: SharedPreferences for all state (tabs, extensions, theme, permissions, ad block stats, screenshot settings, web apps, usage analytics). Navigation: Named navigatorKey with globalScaffoldKey for cross-context snackbar delivery. Font: Outfit (Google Fonts) via GoogleFonts.outfit(). Icons: lucide_icons for consistent iconography.


πŸ“‘ Platform Channels

All Flutter↔Android communication is via MethodChannel in MainActivity.kt:

Channel Direction Methods
zyro/downloads Flutter→Native enqueueDownload, queryDownload
zyro/screenshot_pro Flutter→Native exportWebViewPdf
zyro/web_apps Bidirectional pinWebAppShortcut, getPinnedShortcutIds, getInitialShortcutUrl ↙ webAppShortcutLaunched
zyro/background_player Bidirectional startService, updateState, stopService ↙ play, pause, next, previous, seekTo

🎨 Cyber-Bento UI System

Design Tokens

Token Light Dark
Background #F8FAFC #0B0F19
Surface #F1F5F9 #161F30
Card #FFFFFF #1E293B
Primary #4F46E5 Indigo #6366F1 Indigo
Secondary #0D9488 Teal #14B8A6 Teal
Accent #06B6D4 Cyan #22D3EE Cyan
Danger #EF4444 #EF4444

Key UI Components

Component Description
GlassAppBar Glassmorphic address/search bar with smart URL/search routing
PageQrCodeDialog Compact current-page QR popup launched from the address bar
CyberMenu Slide-out Bento navigation drawer with logo, quick actions, and nav links
GlassContainer Reusable frosted-glass surface primitive
TabSwitcherScreen Full-screen tab manager with group support and undo close
LinkContextMenuSheet Long-press sheet: open, new tab, copy, share, download, inspect
FloatingDownloadButton Animated FAB shown when a downloadable video is detected
ScreenshotFloatingButton Expandable FAB with mini-actions for viewport and full-page capture
QualitySelectorSheet Format/quality picker bottom sheet for video downloads

Themes

  • Light Theme β€” Clean white/slate with indigo primary accents
  • Dark Theme β€” Deep navy/slate with indigo/teal/cyan neon accents
  • Incognito Theme β€” Forced dark mode with session isolation

βš™οΈ Node.js Backend Architecture

API Endpoints

Method Endpoint Description
POST /api/video/metadata Extract video metadata + format list via yt-dlp
POST /api/video/download Start async download task; returns taskId
GET /api/video/status/:taskId Poll task state and progress
GET /downloads/:filename Serve completed media file statically
GET / Health check

Download Task State Machine

extracting β†’ downloading_video β†’ downloading_audio β†’ merging β†’ completed
                                                             β†˜ failed

FFmpeg Workflows

Mode Input Operation Output
Video + Audio Separate adaptive streams -c:v copy -c:a aac -shortest .mp4 / .webm
Audio Only Audio stream -acodec libmp3lame -ab 320k .mp3
Progressive Single stream (video+audio) Direct download, no FFmpeg .mp4

πŸ“Έ Screenshot Pro Workflow

User taps Screenshot FAB
        β”‚
        β”œβ”€β”€β–Ά Viewport Screenshot
        β”‚       controller.takeScreenshot() β†’ PNG bytes
        β”‚       MediaStoreService.getSaveDirectoryPath('screenshots')
        β”‚       File.writeAsBytes() β†’ SnackBar notification
        β”‚
        └──▢ Full Page Capture
                β”œβ”€β”€ Save current scrollY
                β”œβ”€β”€ Inject scroll-behavior:auto style override
                β”œβ”€β”€ Calculate scroll positions (viewport-step increments)
                β”œβ”€β”€ For each offset: scroll β†’ wait 420ms β†’ takeScreenshot()
                β”œβ”€β”€ img.decodePng() β†’ stitch: img.copyCrop() + compositeImage()
                β”œβ”€β”€ Restore scrollY + remove style override
                └── Save stitched PNG
                          β”‚
                          └──▢ PDF Export (optional)
                                  β”œβ”€β”€ Calculate A4 printable area + scale
                                  β”œβ”€β”€ Slice image into page-height strips
                                  β”œβ”€β”€ pw.Document().addPage() per strip
                                  └── File.writeAsBytes(pdf.save())

πŸ“± Web App Installation Workflow

Page load β†’ WebAppInstallerController detects manifest
        β”œβ”€β”€ Fetch <link rel="manifest"> via JS evaluation
        β”œβ”€β”€ HTTP GET manifest.json β†’ parse name, icons, start_url, scope
        β”œβ”€β”€ Select best icon β†’ HTTP download β†’ local file cache
        └── Bitmap decode + normalize (blank/too-small detection)

User taps "Add to Home Screen"
        └── zyro/web_apps β†’ pinWebAppShortcut(id, name, url, iconPath)
                └── MainActivity.kt:
                        β”œβ”€β”€ ShortcutManager.isRequestPinShortcutSupported
                        β”œβ”€β”€ BitmapFactory.decodeFile(iconPath)
                        β”œβ”€β”€ normalizeShortcutBitmap() β€” resize + round-rect clip
                        β”œβ”€β”€ ShortcutInfo.Builder β†’ setIntent(openWebAppAction)
                        └── ShortcutManager.requestPinShortcut()

Shortcut tap on home screen
        └── MainActivity.onCreate / onNewIntent
                β”œβ”€β”€ handleWebAppShortcutIntent() β†’ extract web_app_url
                β”œβ”€β”€ pendingWebAppUrl cached until Flutter engine ready
                └── webAppChannel.invokeMethod("webAppShortcutLaunched", {url})
                          └── WebAppShortcutLaunchBridge β†’ TabManager.openUrl()

πŸ›‘οΈ Ad Blocker Architecture

WebView shouldInterceptRequest(url)
        └── AdBlockService.interceptRequest(url, requestType, sourceUrl)
                β”œβ”€β”€ [extension disabled] β†’ return null (allow)
                └── AdBlockRuleEngine.match(url)
                        β”œβ”€β”€ Normalize to lowercase; extract sourceDomain
                        β”œβ”€β”€ Iterate 35+ compiled RegExp rules
                        β”œβ”€β”€ [matched] β†’ AdBlockStatsService.recordBlockedEvent(url)
                        β”‚       β”œβ”€β”€ domainBlockedCounts[domain]++
                        β”‚       β”œβ”€β”€ totalBlocked++ / todayBlocked++
                        β”‚       └── SharedPreferences save (async)
                        └── [not matched] β†’ return null (allow)

WebView onPageStarted / onPageFinished / onUrlChanged
        └── ScriptEngine β†’ AdBlockService.getInjectedScripts(url)
                β”œβ”€β”€ [youtube.com] β†’ YouTubeAdBlockerService.cosmeticScript
                └── [other] β†’ CosmeticFilterInjector.cosmeticScript

πŸ“ˆ Internet Usage Analytics Workflow

WebView shouldInterceptRequest(url)
        β”œβ”€β”€ AdBlockService.interceptRequest(url)
        β”œβ”€β”€ [blocked] β†’ do not count usage
        └── [allowed] β†’ UsageTrackingService.observeRequest(url, sourceUrl)
                β”œβ”€β”€ DomainUsageNormalizer.normalize(url)
                β”‚       └── www.youtube.com / m.youtube.com β†’ youtube.com
                β”œβ”€β”€ Content-Length if available, otherwise safe byte estimate
                β”œβ”€β”€ De-duplicate same URL estimate within the current minute
                β”œβ”€β”€ UsageEntry.record()
                β”‚       β”œβ”€β”€ totalBytes
                β”‚       β”œβ”€β”€ monthlyBytes
                β”‚       β”œβ”€β”€ todayBytes
                β”‚       β”œβ”€β”€ requestCount
                β”‚       └── lastVisitedAt
                └── UsageStorageService β†’ SharedPreferences

Settings β†’ Usage
        β”œβ”€β”€ Total data this month
        β”œβ”€β”€ Total data today
        β”œβ”€β”€ Today / This Month / All Time filters
        β”œβ”€β”€ Top domains sorted by usage
        └── Clear usage data confirmation

Usage values are estimates when response sizes are not exposed by the WebView request callback. Downloads and media requests observed inside the WebView are attributed to their source/request domain; internal app routes, local files, extension assets, screenshots, QR generation, and app UI assets are skipped.

Privacy note: Usage Analytics are stored locally on your device and are used only to show your browsing data usage inside Zyro.


🎡 Background Media Playback Architecture

Flutter BackgroundPlayerService.dart
        └── BackgroundPlayerChannel β†’ zyro/background_player β†’ startService
                └── BackgroundPlayerService.kt (Android)
                        β”œβ”€β”€ PowerManager.WakeLock (30 min, PARTIAL_WAKE_LOCK)
                        β”œβ”€β”€ NotificationChannel (IMPORTANCE_LOW)
                        └── MediaSession("ZyroMediaSession")
                                β”œβ”€β”€ setMetadata(title, website, duration)
                                β”œβ”€β”€ setPlaybackState(position)
                                └── Callback: onPlay/onPause/onNext/onPrev/onSeekTo
                                        β†’ onMediaAction β†’ invokeMethod β†’ Flutter
                                                β†’ JS: media.play() / media.pause() /
                                                  nextBtn.click() / media.currentTime

🎬 Video Download Pipeline

VideoDetectionService.detectionScript β†’ DOM polls <video> elements
        └── videoDetected event β†’ Flutter β†’ FloatingDownloadButton appears

User β–Ό β†’ QualitySelectorSheet β†’ selects format + mode

DownloadController β†’ POST /api/video/download
        └── Node.js:
                β”œβ”€β”€ yt-dlp: extractMetadata(url) β†’ formats[]
                β”œβ”€β”€ formatSelector.selectFormats(formatId, mode)
                β”œβ”€β”€ [audio]      downloadStream β†’ convertToMp3 (FFmpeg)
                β”œβ”€β”€ [progressive] downloadStream (no merge)
                └── [adaptive]   downloadStream(video) + downloadStream(audio)
                                 β†’ mergeStreams (FFmpeg)
                                 β†’ verifyVideoHeight()
        β–Ό task.state = 'completed'
Flutter polls GET /api/video/status/:taskId
        └── BrowserDataManager β†’ zyro/downloads β†’ Android DownloadManager β†’ MediaStore

πŸ” Website Permissions Architecture

WebViewWrapper onPermissionRequest(origin, resources[])
        └── WebsitePermissionManager.resolve(context, origin, permissionType)
                β”œβ”€β”€ DomainNormalizer.normalize(origin) β†’ domain
                β”œβ”€β”€ WebsitePermissionsController.ruleFor(domain, type)
                β”œβ”€β”€ [block] β†’ return false (deny silently)
                β”œβ”€β”€ [allow] β†’ requestAndroidPermission β†’ return result
                └── [null/ask] β†’ PermissionRequestDialog.show()
                        └── User: Allow / Ask / Block
                                β†’ WebsitePermissionsController.upsert(rule)
                                β†’ SharedPreferences
                                β†’ requestAndroidPermission(type)

πŸ”§ Browser Engine Details

Setting Value
Engine flutter_inappwebview v6.1.5
JavaScript Enabled
JS Handlers videoStateUpdate, mediaProgress, devToolsLog
Request Interception shouldOverrideUrlLoading + shouldInterceptRequest
Page Lifecycle Hooks onPageStarted, onProgressChanged, onPageFinished, onUpdateVisitedHistory
Popup Handling onCreateWindow β†’ new tab
Permission Handling onPermissionRequest β†’ WebsitePermissionManager
Context Menu onContextMenuActionItemClicked β†’ LinkContextMenuSheet
User Agent Default; per-tab desktop mode toggle

πŸš€ Installation & Running

Prerequisites

Requirement Version
Flutter SDK ^3.10 (Dart ^3.10.7)
Android SDK minSdk 21, targetSdk 34+
Node.js 18+
FFmpeg Latest stable β€” must be on system PATH
yt-dlp Auto-installed via youtube-dl-exec npm package
Device Android physical/emulator with USB Debugging

1️⃣ Clone the Repository

git clone https://github.com/Ashish6298/zyro.git
cd zyro

2️⃣ Run the Backend Microservice

cd zyro-backend
npm install
npm run dev
# Zyro Downloader Backend running on port 3000

FFmpeg must be on PATH. Verify with ffmpeg -version.

3️⃣ Run the Flutter Frontend

cd zyro-frontend
flutter pub get
flutter run

Backend URL: On a physical device, update DownloadApiService base URL from localhost to your development machine's LAN IP address.

Build Release APK

cd zyro-frontend
flutter build apk --release
# Output: build/app/outputs/flutter-apk/app-release.apk

⚑ Browser Engine Optimizations

🌐 Navigation Engine

  • Smart URL routing (search vs. URL)
  • Popup interception β†’ new tab
  • Back/forward navigation per tab
  • Undo closed tab (5-second window)
  • Desktop/mobile user-agent toggle

🎯 User Experience

  • Glassmorphic responsive components
  • Per-tab scroll position persistence
  • Tab group color labels
  • BouncingScrollPhysics in lists
  • Outfit typography + Lucide icons

πŸš€ Performance & Stability

  • Cached provider refs in WebViewWrapper
  • handleTabClosed() on WebView dispose
  • Session saved for non-incognito only
  • Async SharedPreferences writes
  • Download poller auto-cancels on finish

πŸ”’ Browser Security & Privacy

Feature Implementation
Incognito mode Global toggle β€” separate ThemeMode, session not persisted
Ad/tracker blocking 35+ regex rules at WebView request interception level
Per-site permissions Granular allow/ask/block per domain per resource type
Usage analytics Stored locally on device via SharedPreferences; never sent to a server
Download URL sanitization Strip UTM/tracking params before yt-dlp extraction
Playlist download rejection Reject YouTube playlist URLs without v= parameter
Video height validation FFmpeg-verified output resolution after merge
Shortcut URL validation Only http:// and https:// accepted for web app shortcuts

πŸ“Š Technology Stack

Layer Package / Technology Role
Flutter flutter_inappwebview ^6.1.5 WebView engine
Flutter provider ^6.1.2 State management
Flutter google_fonts ^6.2.1 Typography (Outfit)
Flutter lucide_icons ^0.257.0 Icon set
Flutter shared_preferences ^2.5.5 Local persistence
Flutter path_provider ^2.1.2 File system paths
Flutter permission_handler ^11.4.0 Android permissions
Flutter image ^4.8.0 PNG decode/encode/stitch
Flutter pdf ^3.11.3 PDF document generation
Flutter qr_flutter 4.1.0 Address-bar current-page QR rendering
Flutter http ^1.2.1 HTTP client (manifest/icon fetch)
Flutter url_launcher ^6.2.5 External URL launch
Flutter share_plus ^7.2.2 Native share sheet
Flutter youtube_explode_dart ^2.2.2 YouTube utilities
Flutter uuid ^4.3.3 UUID generation
Flutter video_player ^2.9.2 In-app video playback
Android Kotlin MediaSession Lock-screen media controls
Android Kotlin ShortcutManager Home screen shortcut pinning
Android Kotlin DownloadManager System download integration
Android Kotlin PowerManager.WakeLock CPU awake during background play
Node.js express ^4.19.2 REST API server
Node.js youtube-dl-exec ^3.0.2 yt-dlp wrapper
Node.js fluent-ffmpeg ^2.1.3 FFmpeg merge + MP3 conversion
Node.js uuid ^9.0.1 Task ID generation
Node.js cors ^2.8.5 CORS for Flutter client

πŸ—ΊοΈ Future Roadmap

Items below are not currently implemented.

  • Floating Videos / PiP β€” directory scaffolded, no implementation yet
  • Dark Reader extension β€” registered in registry, script not yet active
  • KeyGen extension β€” registered in registry, not yet active
  • iOS support β€” Flutter project scaffolded; native channels are Android-only
  • Reading list & Favorites persistence (currently in-memory only)
  • Bookmarks import / export
  • Extension SDK for third-party extensions
  • Backend rate limiting and authentication

⚠️ Known Limitations

  • iOS: Native channel implementations (BackgroundPlayerService, ShortcutManager, DownloadManager) are Android-specific. The app will not function correctly on iOS.
  • Floating Videos (PiP): floating_videos directory is scaffolded but contains no implementation files.
  • Reading List & Favorites: In-memory only β€” resets on app restart.
  • Backend Reachability: Physical devices must point DownloadApiService to the LAN IP instead of localhost.
  • yt-dlp Maintenance: Depends on yt-dlp to parse platforms. Frequent YouTube changes may temporarily break extraction.
  • FFmpeg PATH: fluent-ffmpeg requires FFmpeg on the system PATH; fails silently if absent.

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/your-feature-name
  3. Commit your changes
  4. Push and open a Pull Request against main

Please follow the existing feature-first directory structure and document any new platform channel methods in this README.


πŸ“„ License

This project is licensed under the MIT License.


πŸ‘¨β€πŸ’» Developer

Ashish Goswami



"Passionate about building modern applications, browser technologies, and user-focused digital products."


Website Vault

Website Vault is a local-first organization feature that gives every website/domain its own vault for important saved material. Users can keep website-related pages, links, screenshots, PDFs, downloads, notes, receipts, invoices, tracking pages, order pages, and other useful references grouped by domain instead of manually searching across downloads, history, bookmarks, and screenshots.

Key Capabilities

Capability Description
Quick Actions entry Website Vault is available from the existing Quick Actions page with the same Cyber-Bento visual language
Domain dashboard Lists websites/domains with saved item counts, latest activity, storage usage, favicons, and category chips
Domain details Shows saved vault items grouped by Screenshots, PDFs, Links, Downloads, Notes, Receipts/Invoices, and Pages
Search and filtering Search by domain, title, URL, tags, note text, and saved item name; filter items by type inside a domain
Save current page Save the active page/link directly into the current website vault
Screenshot Pro integration Saved screenshots and PDFs can be associated with the source website vault
Download integration Downloaded files can be linked to the source website when the source URL is available
Manual entries Add notes and useful links directly from the Website Vault screen
Item actions Open, Share, Rename, Delete, and Copy Link where applicable
Safe deletion Deleting a vault item removes only the vault entry unless the user explicitly confirms local file deletion

Data Model

Website Vault uses WebsiteVaultItem, WebsiteVaultDomainSummary, and WebsiteVaultType models under lib/features/website_vault/models/.

Metadata is persisted locally through the app's existing local persistence approach, and vault files are organized under a clear domain-based folder structure such as:

Zyro/Vault/<domain>/

Privacy

Website Vault is stored locally on your device. Vault metadata and saved files are not uploaded to a server.



🌐 Built with Flutter, Node.js & FFmpeg Β β€’Β  Crafted by Ashish Goswami

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages