# Main Commands flutter run -d chrome flutter run -d web-server --web-port=8080 flutter devices flutter run -d chrome --release flutter run -d chrome --debug flutter build web flutter clean flutter pub get flutter run -d chrome # browser_tab_manager # Extension https://drive.google.com/drive/folders/1pAniw90J-cWrH7nMVaxY0pl0TMG63AJA?usp=sharing Add this folder in developer mode: Go To: chrome://extensions/ To manage your Chrome extensions 1. Open Chrome browser 2. Type chrome://extensions/ in the address bar 3. Or click the three dots menu > Extensions > Manage Extensions' Start Developer mode: In right corner. Load Unpacked: Add entire folder in left corner. Start Extension in right corner header after the search bar. ## Getting Started - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) - [online documentation](https://docs.flutter.dev/) ## 📋 Table of Contents 1. [App Architecture Overview](#architecture) 2. [Entry Point - main.dart](#main-dart) 3. [Data Layer - Models](#models) 4. [Service Layer](#services) 5. [UI Layer - Screens](#screens) 6. [Component Layer - Widgets](#widgets) 7. [Utilities & Constants](#utilities) 8. [Data Flow & State Management](#data-flow) 9. [Browser API Integration](#browser-api) 10. [Extension Communication](#extension-comm) --- ## 🏗️ App Architecture Overview {#architecture} ``` ┌─────────────────────────────────────────┐ │ main.dart │ │ (App Entry Point) │ └─────────────────┬───────────────────────┘ │ ┌─────────────────▼───────────────────────┐ │ TabManagerHome │ │ (Main Screen State) │ └─────┬─────────────────────────────┬─────┘ │ │ ┌─────▼─────┐ ┌─────▼─────┐ │ Services │ │ Widgets │ │ Layer │ │ Layer │ └─────┬─────┘ └─────┬─────┘ │ │ ┌─────▼─────┐ ┌─────▼─────┐ │ Models │ │ Utils & │ │ Layer │ │ Constants │ └───────────┘ └───────────┘ ``` ### Key Concepts: - **Separation of Concerns**: Each layer has specific responsibilities - **Unidirectional Data Flow**: Data flows down, events flow up - **State Management**: Centralized in TabManagerHome using setState() - **Service Communication**: Browser APIs and Extension messaging --- ## 🚀 Entry Point - main.dart {#main-dart} ```dart void main() { runApp(const BrowserTabManagerApp()); } ``` 1. `main()` is the entry point of every Dart/Flutter app 2. `runApp()` tells Flutter to start the app with our root widget 3. Creates the widget tree and starts the rendering engine ```dart class BrowserTabManagerApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Browser Tab Manager', theme: ThemeData(...), home: const TabManagerHome(), ); } } ``` **BREAKDOWN:** - `StatelessWidget`: Never changes its appearance based on internal state - `MaterialApp`: Root widget that provides Material Design theming - `theme` & `darkTheme`: Define app-wide visual styling - `home`: The first screen users see (TabManagerHome) --- ## 📊 Data Layer - Models {#models} ### TabData Model (`models/tab_data.dart`) ```dart class TabData { String id; String title; String url; String favicon; DateTime lastAccessed; // When last used bool isPinned; String type; // 'tab', 'bookmark', or 'history' int? visitCount; // (nullable) String? folder; // Bookmark folder (nullable) } ``` **PURPOSE:** - **Data Structure**: Represents all types of browser items uniformly - **Type Safety**: Dart ensures correct data types ### Factory Constructor: ```dart factory TabData.fromJson(Map json) => TabData( id: json['id'].toString(), title: json['title'] ?? 'Untitled', // ?? means "if null, use default" // ... more fields ); ``` **WHAT IT DOES:** - Converts JSON data from browser APIs into TabData objects - Handles missing/null values gracefully with defaults - Standardizes different API response formats --- ## 🔧 Service Layer {#services} ### BrowserApiService (`services/browser_api_service.dart`) ```dart class BrowserApiService { Future> getTabs() async { final result = await _callBrowserAPI('getTabs'); // Convert raw data to TabData objects } } ``` **KEY CONCEPTS:** - `async/await`: Handles asynchronous operations - `Future`: Represents a value that will be available later - **Abstraction**: Hides complex browser API details ### ExtensionService (`services/extension_service.dart`) ```dart void setupListener() { html.window.onMessage.listen((event) => { // Handle messages from browser extension }); } ``` **PURPOSE:** - **Communication Bridge**: Between web app and browser extension - **Event-Driven**: Responds to messages from extension - **Callback Pattern**: Uses function pointers for responses --- ## 🎨 UI Layer - Screens {#screens} ### TabManagerHome (`screens/tab_manager_home.dart`) This is the **BRAIN** of the application - it manages all state and coordinates everything. #### State Variables: ```dart class _TabManagerHomeState extends State { List allItems = []; // ALL data from browser List filteredItems = []; // DISPLAYED data (after search/filter) bool isGridView = true; // View mode toggle String sortBy = 'recent'; // Current sort method String filterType = 'all'; // Current filter bool isLoading = true; // Loading spinner state bool extensionMode = false; // Extension tracking mode } ``` #### Key Methods: **initState()** - Runs when widget is created: ```dart @override void initState() { super.initState(); // Call parent setup _setupExtensionService(); // Start listening for extension _loadAllData(); // Load browser data searchController.addListener(_filterItems); // Watch search input } ``` **setState()** updates UI: ```dart setState(() { allItems = newData; // Change state _filterItems(); // Update filtered view }); // Flutter automatically rebuilds UI after setState finishes ``` --- ## 🧩 Component Layer - Widgets {#widgets} ### ItemCard (`widgets/item_card.dart`) **STATELESS WIDGET** - Displays data, doesn't manage state: ```dart class ItemCard extends StatelessWidget { final TabData item; // Data from parent final VoidCallback onTap; // Function to call when tapped @override Widget build(BuildContext context) { return Card( child: InkWell( onTap: onTap, // Call parent's function child: // ... UI layout ), ); } } ``` **DATA FLOW:** 1. Parent passes data and callback functions 2. Widget displays the data 3. User interaction calls parent's functions 4. Parent updates state and rebuilds widget with new data ### SearchBar (`widgets/search_bar.dart`) ```dart TextField( controller: controller, // Links to parent's TextEditingController onChanged: (text) => { // Calls parent when text changes // Parent handles the search logic }, ) ``` --- ## 🛠️ Utilities & Constants {#utilities} ### Helpers (`utils/helpers.dart`) ```dart static List filterItems( List items, String query, String filterType, ) { return items.where((item) => { // Filter logic here }).toList(); } ``` **PURPOSE:** - **Pure Functions**: Same input always produces same output - **Reusable Logic**: Can be used anywhere in the app - **Testing**: Easy to unit test ### Constants (`constants/app_constants.dart`) ```dart class AppConstants { static const Color primaryColor = Color(0xFF0175C2); static const String extensionSource = 'tab-tracker-extension'; } ``` **BENEFITS:** - **Single Source of Truth**: Change value in one place - **Type Safety**: Compile-time checking - **Maintainability**: Easy to update app-wide settings --- ## 🔄 Data Flow & State Management {#data-flow} ### Complete Data Flow Cycle: ``` 1. User Action (tap, type, click) ↓ 2. Widget calls parent function ↓ 3. Parent updates state with setState() ↓ 4. Flutter rebuilds widget tree ↓ 5. UI reflects new state ``` ### Example: Search Flow ```dart // 1. User types in search bar SearchBar(onChanged: (text) => { // 2. SearchBar calls parent's function _filterItems(); }); // 3. Parent filters data and updates state void _filterItems() { setState(() => { filteredItems = //filter logic }); // 4. Flutter rebuilds UI with new filteredItems } ``` --- ## 🌐 Browser API Integration {#browser-api} ### How Browser APIs Work: ```dart Future _callBrowserAPI(String method, [List? args]) async { // 1. Check if browser API exists if (!js_util.hasProperty(html.window, 'BrowserAPI')) { return null; // Development mode } // 2. Get the API object from browser final browserAPI = js_util.getProperty(html.window, 'BrowserAPI'); // 3. Call the specific method final result = await js_util.promiseToFuture( js_util.callMethod(function, 'call', [browserAPI, ...args]) ); return json.encode(result); // 4. Return as JSON string } ``` **STEPS:** 1. **Check Availability**: Is the browser API injected? 2. **Get Reference**: Access the API object 3. **Call Method**: Execute with parameters 4. **Handle Response**: Convert to usable format --- ## 📡 Extension Communication {#extension-comm} ### Message Passing System: ```dart // SENDING to extension: html.window.postMessage({ 'source': 'tab-tracker-webapp', 'action': 'startTracking' }, '*'); // RECEIVING from extension: html.window.onMessage.listen((event) => { final data = event.data; if (data['source'] == 'tab-tracker-extension') { _handleExtensionMessage(data); } }); ``` **COMMUNICATION FLOW:** ``` Web App ←→ Browser Window ←→ Extension ``` ### Message Types: - `startTracking`: Begin tab monitoring - `stopTracking`: Stop tab monitoring - `updateTabs`: Extension sends current tabs - `getStatus`: Request current state --- ## 🎯 Key Learning Points ### 1. **State Management Pattern** - State lives in parent components - Children receive data and callback functions - setState() triggers UI rebuilds ### 2. **Async Programming** - `async/await` for non-blocking operations - `Future` represents eventual values - Error handling with try/catch ### 3. **Widget Communication** - Parent-to-child: Pass data via constructor - Child-to-parent: Pass callback functions - Sibling-to-sibling: Through common parent ### 4. **Service Layer Benefits** - Separates business logic from UI - Makes testing easier - Provides clean abstractions ### 5. **Browser Integration** - JavaScript interop for browser APIs - Message passing for extension communication - Graceful degradation for development mode --- ## 🔍 Next Steps for Deep Learning 1. **Trace a complete user action** from UI tap to state update 2. **Follow data transformation** from browser API to UI display 3. **Understand lifecycle methods** and when they're called 4. **Practice modifying** one small feature at a time 5. **Add logging** to see the flow in action This architecture provides a solid foundation for building complex, maintainable Flutter web applications! 🚀