Browser-Tab-Manager/README.md

469 lines
12 KiB
Markdown
Raw Normal View History

2025-10-26 19:10:23 +01:00
# 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
2025-10-26 19:10:23 +01:00
# Extension
https://drive.google.com/drive/folders/1pAniw90J-cWrH7nMVaxY0pl0TMG63AJA?usp=sharing
Add this folder in developer mode:
Go To:
chrome://extensions/
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Manage Extensions'),
content: Text(
'To manage your Chrome extensions:\n\n'
'1. Open Chrome browser\n'
'2. Type chrome://extensions/ in the address bar\n'
'3. Or click the three dots menu > Extensions > Manage Extensions'
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('OK'),
),
],
),
);
Start Developer mode: In right corner.
Load Unpacked: Add entire folder in left corner.
Start Extension in right corner
## 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 {
2025-10-29 22:45:20 +01:00
String id;
String title;
String url;
String favicon;
DateTime lastAccessed; // When last used
2025-10-29 22:45:20 +01:00
bool isPinned;
String type; // 'tab', 'bookmark', or 'history'
2025-10-29 22:45:20 +01:00
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<String, dynamic> 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<List<TabData>> getTabs() async {
final result = await _callBrowserAPI('getTabs');
// Convert raw data to TabData objects
}
}
```
**KEY CONCEPTS:**
- `async/await`: Handles asynchronous operations
- `Future<T>`: 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<TabManagerHome> {
List<TabData> allItems = []; // ALL data from browser
List<TabData> 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
}
```
2025-10-29 22:45:20 +01:00
**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<TabData> filterItems(
List<TabData> 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(() => {
2025-10-29 22:45:20 +01:00
filteredItems = //filter logic
});
// 4. Flutter rebuilds UI with new filteredItems
}
```
---
## 🌐 Browser API Integration {#browser-api}
### How Browser APIs Work:
```dart
Future<String?> _callBrowserAPI(String method, [List<dynamic>? 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<T>` 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! 🚀