122 lines
No EOL
3.4 KiB
Dart
122 lines
No EOL
3.4 KiB
Dart
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<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;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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. |