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

154 lines
4.2 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
2025-10-25 12:56:41 +02:00
// result LATER
// API takes time so Future as a Type
2025-10-23 03:49:28 +02:00
// ASYNC WAIT
// return empty if fail
2025-10-25 12:56:41 +02:00
// try catch no crash
2025-10-26 19:10:23 +01:00
// final for security, assign once then locked, no change main data.
2025-10-25 12:56:41 +02:00
// API string result
2025-10-23 03:49:28 +02:00
2025-10-25 12:56:41 +02:00
// dynamic list "ANY" Type
// decode to list of maps so its ready for use
// objects
// .toList adding to a list of objects that can be called for the data
2025-10-23 03:49:28 +02:00
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 [];
}
2025-10-26 19:10:23 +01:00
// methods for tab_manager_home
// Future
// void, no return
// gets a string
// async, await
// _callBrowserAPI for data
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]);
}
2025-10-25 12:56:41 +02:00
// _callBrowserAPI bridging
// Future
// return string or ? null
// method what to call
// optional list args for history "100"
// a check for browser API
2025-10-26 19:10:23 +01:00
2025-10-25 12:56:41 +02:00
// js_util call JavaScript functions
// promiseToFuture convert
2025-10-26 19:10:23 +01:00
// html.window global scope, javascript BrowserAPI
// ? allow args to be null
2025-10-25 12:56:41 +02:00
2025-10-26 19:10:23 +01:00
// final result check if args is null or something
2025-10-25 12:56:41 +02:00
// call function that fits
2025-10-26 19:10:23 +01:00
// Encode convert javascript object to string
2025-10-25 12:56:41 +02:00
// And that is why json format is fucking genius...
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-25 12:56:41 +02:00
// SwitchToTab, openTab, closeTab allow control of tabs.
//
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.