Browser-Tab-Manager/lib/services/browser_api_service.dart

122 lines
3.4 KiB
Dart
Raw Normal View History

import 'dart:html' as html;
import 'dart:convert';
import 'dart:js_util' as js_util;
import '../models/tab_data.dart';
2025-10-23 03:49:28 +02:00
// communication with the browser API
// list of TabData objects
// results LATER
// API takes time so future
// ASYNC WAIT
// return empty if fail
// final cannot be changed
class BrowserApiService {
Future<List<TabData>> getTabs() async {
try {
final result = await _callBrowserAPI('getTabs');
if (result != null) {
final List<dynamic> data = json.decode(result);
return data.map((item) {
item['type'] = 'tab';
return TabData.fromJson(item);
}).toList();
}
} catch (e) {
print('Error getting tabs: $e');
}
return [];
}
Future<List<TabData>> getBookmarks() async {
try {
final result = await _callBrowserAPI('getBookmarks');
if (result != null) {
final List<dynamic> data = json.decode(result);
return data.map((item) {
item['type'] = 'bookmark';
return TabData.fromJson(item);
}).toList();
}
} catch (e) {
print('Error getting bookmarks: $e');
}
return [];
}
Future<List<TabData>> getHistory() async {
try {
final result = await _callBrowserAPI('getHistory', [100]);
if (result != null) {
final List<dynamic> data = json.decode(result);
return data.map((item) {
item['type'] = 'history';
return TabData.fromJson(item);
}).toList();
}
} catch (e) {
print('Error getting history: $e');
}
return [];
}
Future<void> switchToTab(String tabId) async {
await _callBrowserAPI('switchToTab', [tabId]);
}
Future<void> openTab(String url) async {
await _callBrowserAPI('openTab', [url]);
}
Future<void> closeTab(String tabId) async {
await _callBrowserAPI('closeTab', [tabId]);
}
Future<void> removeBookmark(String bookmarkId) async {
await _callBrowserAPI('removeBookmark', [bookmarkId]);
}
Future<void> togglePinTab(String tabId, bool pin) async {
await _callBrowserAPI('togglePinTab', [tabId, pin]);
}
Future<String?> _callBrowserAPI(String method, [List<dynamic>? args]) async {
try {
if (!js_util.hasProperty(html.window, 'BrowserAPI')) {
print('BrowserAPI not found - running in development mode');
return null;
}
final browserAPI = js_util.getProperty(html.window, 'BrowserAPI');
final function = js_util.getProperty(browserAPI, method);
final result = args == null
? await js_util.promiseToFuture(js_util.callMethod(function, 'call', [browserAPI]))
: await js_util.promiseToFuture(js_util.callMethod(function, 'call', [browserAPI, ...args]));
return json.encode(result);
} catch (e) {
print('Error calling $method: $e');
return null;
}
}
}
2025-10-23 03:49:28 +02:00
// Bridge Flutter app and the browser extension.
//
2025-10-23 03:49:28 +02:00
// Methods fetching from browser, convert to TabData objects.
//
2025-10-23 03:49:28 +02:00
// SwitchToTab, openTab, closeTab allow control of tabs programmatically.
//
2025-10-23 03:49:28 +02:00
// _callBrowserAPI low level JavaScript communication.
//
2025-10-23 03:49:28 +02:00
// dart:js_util call JavaScript functions exposed by browser extension through window.BrowserAPI.
//
2025-10-23 03:49:28 +02:00
// Empty results if the API is unavailable.
//
2025-10-23 03:49:28 +02:00
// Browser specific code separate from UI logic, app easier to maintain.
//
2025-10-23 03:49:28 +02:00
// Without extension, prints debug messages instead of crashing.