This commit is contained in:
jsnk 2025-10-26 19:10:23 +01:00
parent 0196144075
commit 6afdbaccc4
4 changed files with 114 additions and 9 deletions

View file

@ -1,4 +1,56 @@
# 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 # browser_tab_manager
# 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 ## Getting Started
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)

View file

@ -0,0 +1,36 @@
### **Message Flow FROM Extension:**
```
Browser Extension
↓ postMessage
window.onMessage
↓ (ExtensionService listening)
setupListener() receives message
↓ filter by source
_handleExtensionMessage()
↓ check action type
Call appropriate callback
onTabsUpdate() / onTrackingStart() / onTrackingStop()
TabManagerHome updates UI
User sees changes!
```
### **Message Flow TO Extension:**
```
User clicks "Track Tabs"
TabManagerHome calls startTracking()
ExtensionService.startTracking()
sendMessage({'action': 'startTracking'})
window.postMessage
Extension receives message
Extension starts tracking
Extension sends back confirmation

View file

@ -11,14 +11,12 @@ import '../models/tab_data.dart';
// ASYNC WAIT // ASYNC WAIT
// return empty if fail // return empty if fail
// try catch no crash // try catch no crash
// final for security, assign once then locked, can't change main data. // final for security, assign once then locked, no change main data.
// API string result // API string result
// dynamic list "ANY" Type // dynamic list "ANY" Type
// decode to list of maps so its ready for use // decode to list of maps so its ready for use
// objects // objects
// a map is EXPLAIN
// .map method DOES
// .toList adding to a list of objects that can be called for the data // .toList adding to a list of objects that can be called for the data
class BrowserApiService { class BrowserApiService {
@ -70,6 +68,16 @@ class BrowserApiService {
return []; return [];
} }
// methods for tab_manager_home
// Future
// void, no return
// gets a string
// async, await
// _callBrowserAPI for data
Future<void> switchToTab(String tabId) async { Future<void> switchToTab(String tabId) async {
await _callBrowserAPI('switchToTab', [tabId]); await _callBrowserAPI('switchToTab', [tabId]);
} }
@ -96,18 +104,17 @@ class BrowserApiService {
// method what to call // method what to call
// optional list args for history "100" // optional list args for history "100"
// a check for browser API // a check for browser API
// js_util call JavaScript functions // js_util call JavaScript functions
// promiseToFuture convert // promiseToFuture convert
// html.window global scope // html.window global scope, javascript BrowserAPI
// extension is a top level javascript // ? allow args to be null
// extension adds BrowserAPI to window as a global
// final result check if args is null // final result check if args is null or something
// call function that fits // call function that fits
// Encode javascript object to drat object // Encode convert javascript object to string
// And that is why json format is fucking genius... // And that is why json format is fucking genius...
Future<String?> _callBrowserAPI(String method, [List<dynamic>? args]) async { Future<String?> _callBrowserAPI(String method, [List<dynamic>? args]) async {
try { try {
if (!js_util.hasProperty(html.window, 'BrowserAPI')) { if (!js_util.hasProperty(html.window, 'BrowserAPI')) {

View file

@ -1,6 +1,16 @@
import 'dart:html' as html; import 'dart:html' as html;
import '../models/tab_data.dart'; import '../models/tab_data.dart';
// communication with browser extension
// Listens for messages
// callbacks to notify UI
// start/stop tracking
// Converts extension
class ExtensionService { class ExtensionService {
Function(List<TabData>)? onTabsUpdate; Function(List<TabData>)? onTabsUpdate;
Function()? onTrackingStart; Function()? onTrackingStart;