import 'dart:html' as html; import 'dart:convert'; import 'dart:js_util' as js_util; import '../models/tab_data.dart'; // 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> getTabs() async { try { final result = await _callBrowserAPI('getTabs'); if (result != null) { final List 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> getBookmarks() async { try { final result = await _callBrowserAPI('getBookmarks'); if (result != null) { final List 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> getHistory() async { try { final result = await _callBrowserAPI('getHistory', [100]); if (result != null) { final List 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 switchToTab(String tabId) async { await _callBrowserAPI('switchToTab', [tabId]); } Future openTab(String url) async { await _callBrowserAPI('openTab', [url]); } Future closeTab(String tabId) async { await _callBrowserAPI('closeTab', [tabId]); } Future removeBookmark(String bookmarkId) async { await _callBrowserAPI('removeBookmark', [bookmarkId]); } Future togglePinTab(String tabId, bool pin) async { await _callBrowserAPI('togglePinTab', [tabId, pin]); } Future _callBrowserAPI(String method, [List? 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; } } } // Bridge Flutter app and the browser extension. // // Methods fetching from browser, convert to TabData objects. // // SwitchToTab, openTab, closeTab allow control of tabs programmatically. // // _callBrowserAPI low level JavaScript communication. // // dart:js_util call JavaScript functions exposed by browser extension through window.BrowserAPI. // // Empty results if the API is unavailable. // // Browser specific code separate from UI logic, app easier to maintain. // // Without extension, prints debug messages instead of crashing.