mirror of
https://github.com/dstark5/Openlib.git
synced 2025-05-17 22:46:00 +08:00
feat: add a setting for the destination folder of downloaded books
This commit is contained in:
@ -26,8 +26,7 @@ import 'package:openlib/state/state.dart'
|
||||
themeModeProvider,
|
||||
openPdfWithExternalAppProvider,
|
||||
userAgentProvider,
|
||||
cookieProvider,
|
||||
dbProvider;
|
||||
cookieProvider;
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
@ -37,13 +36,15 @@ void main() async {
|
||||
databaseFactory = databaseFactoryFfi;
|
||||
}
|
||||
|
||||
Database initDb = await Sqlite.initDb();
|
||||
MyLibraryDb dataBase = MyLibraryDb(dbInstance: initDb);
|
||||
bool isDarkMode = await dataBase.getPreference('darkMode');
|
||||
bool openPdfwithExternalapp =
|
||||
await dataBase.getPreference('openPdfwithExternalApp');
|
||||
bool openEpubwithExternalapp =
|
||||
await dataBase.getPreference('openEpubwithExternalApp');
|
||||
MyLibraryDb dataBase = MyLibraryDb.instance;
|
||||
bool isDarkMode =
|
||||
await dataBase.getPreference('darkMode') == 0 ? false : true;
|
||||
bool openPdfwithExternalapp = await dataBase
|
||||
.getPreference('openPdfwithExternalApp')
|
||||
.catchError((e) => print(e)) ==
|
||||
0
|
||||
? false
|
||||
: true;
|
||||
|
||||
String browserUserAgent = await dataBase.getBrowserOptions('userAgent');
|
||||
String browserCookie = await dataBase.getBrowserOptions('cookie');
|
||||
@ -59,7 +60,6 @@ void main() async {
|
||||
runApp(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
dbProvider.overrideWithValue(dataBase),
|
||||
themeModeProvider.overrideWith(
|
||||
(ref) => isDarkMode ? ThemeMode.dark : ThemeMode.light),
|
||||
openPdfWithExternalAppProvider
|
||||
|
@ -50,12 +50,79 @@ class MyBook {
|
||||
}
|
||||
|
||||
class MyLibraryDb {
|
||||
Database dbInstance;
|
||||
static final MyLibraryDb instance = MyLibraryDb._internal();
|
||||
static Database? _database;
|
||||
MyLibraryDb._internal();
|
||||
|
||||
Future<Database> get database async {
|
||||
if (_database != null) {
|
||||
return _database!;
|
||||
}
|
||||
_database = await _initDatabase();
|
||||
return _database!;
|
||||
}
|
||||
|
||||
Future<Database> _initDatabase() async {
|
||||
final databasePath = await getDatabasesPath();
|
||||
final path = '$databasePath/mylibrary.db';
|
||||
final bool isMobile = Platform.isAndroid || Platform.isIOS;
|
||||
|
||||
return await openDatabase(
|
||||
path,
|
||||
version: 5,
|
||||
onCreate: (Database db, int version) async {
|
||||
await db.execute(
|
||||
'CREATE TABLE mybooks (id TEXT PRIMARY KEY, title TEXT,author TEXT,thumbnail TEXT,link TEXT,publisher TEXT,info TEXT,format TEXT,description TEXT)');
|
||||
await db.execute(
|
||||
'CREATE TABLE preferences (name TEXT PRIMARY KEY,value TEXT)');
|
||||
if (isMobile || true) {
|
||||
// TODO: Breaks getBrowserOptions() on Mac
|
||||
await db.execute(
|
||||
'CREATE TABLE bookposition (fileName TEXT PRIMARY KEY,position TEXT)');
|
||||
await db.execute(
|
||||
'CREATE TABLE browserOptions (name TEXT PRIMARY KEY,value TEXT)');
|
||||
}
|
||||
},
|
||||
onUpgrade: (db, oldVersion, newVersion) async {
|
||||
List<dynamic> isTableExist = await db.query('sqlite_master',
|
||||
where: 'name = ?', whereArgs: ['bookposition']);
|
||||
List<dynamic> isPreferenceTableExist = await db.query('sqlite_master',
|
||||
where: 'name = ?', whereArgs: ['preferences']);
|
||||
List<dynamic> isbrowserOptionsExist = await db.query('sqlite_master',
|
||||
where: 'name = ?', whereArgs: ['browserOptions']);
|
||||
if (isPreferenceTableExist.isEmpty) {
|
||||
await db.execute(
|
||||
'CREATE TABLE preferences (name TEXT PRIMARY KEY,value TEXT)');
|
||||
}
|
||||
if (isMobile && isTableExist.isEmpty) {
|
||||
await db.execute(
|
||||
'CREATE TABLE bookposition (fileName TEXT PRIMARY KEY,position TEXT)');
|
||||
}
|
||||
if (isMobile && isbrowserOptionsExist.isEmpty) {
|
||||
await db.execute(
|
||||
'CREATE TABLE browserOptions (name TEXT PRIMARY KEY,value TEXT)');
|
||||
}
|
||||
},
|
||||
onOpen: (db) async {
|
||||
final bookStorageDefaultDirectory =
|
||||
await getBookStorageDefaultDirectory;
|
||||
await db.execute(
|
||||
"INSERT OR IGNORE INTO preferences (name, value) VALUES ('darkMode', 0)");
|
||||
await db.execute(
|
||||
"INSERT OR IGNORE INTO preferences (name, value) VALUES ('openPdfwithExternalApp', 0)");
|
||||
await db.execute(
|
||||
"INSERT OR IGNORE INTO preferences (name, value) VALUES ('openEpubwithExternalApp', 0)");
|
||||
await db.execute(
|
||||
"INSERT OR IGNORE INTO preferences (name, value) VALUES ('bookStorageDirectory', '$bookStorageDefaultDirectory')");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Database dbInstance;
|
||||
String tableName = 'mybooks';
|
||||
|
||||
MyLibraryDb({required this.dbInstance});
|
||||
|
||||
Future<void> insert(MyBook book) async {
|
||||
final dbInstance = await instance.database;
|
||||
await dbInstance.insert(
|
||||
tableName,
|
||||
book.toMap(),
|
||||
@ -64,6 +131,7 @@ class MyLibraryDb {
|
||||
}
|
||||
|
||||
Future<void> delete(String id) async {
|
||||
final dbInstance = await instance.database;
|
||||
await dbInstance.delete(
|
||||
tableName,
|
||||
where: 'id = ?',
|
||||
@ -72,6 +140,7 @@ class MyLibraryDb {
|
||||
}
|
||||
|
||||
Future<MyBook?> getId(String id) async {
|
||||
final dbInstance = await instance.database;
|
||||
List<Map<String, dynamic>> data =
|
||||
await dbInstance.query(tableName, where: 'id = ?', whereArgs: [id]);
|
||||
List<MyBook> book = listMapToMyBook(data);
|
||||
@ -82,6 +151,7 @@ class MyLibraryDb {
|
||||
}
|
||||
|
||||
Future<bool> checkIdExists(String id) async {
|
||||
final dbInstance = await instance.database;
|
||||
List<Map<String, dynamic>> data =
|
||||
await dbInstance.query(tableName, where: 'id = ?', whereArgs: [id]);
|
||||
List<MyBook> book = listMapToMyBook(data);
|
||||
@ -92,6 +162,7 @@ class MyLibraryDb {
|
||||
}
|
||||
|
||||
Future<List<MyBook>> getAll() async {
|
||||
final dbInstance = await instance.database;
|
||||
final List<Map<String, dynamic>> maps = await dbInstance.query(tableName);
|
||||
return listMapToMyBook(maps);
|
||||
}
|
||||
@ -113,6 +184,7 @@ class MyLibraryDb {
|
||||
}
|
||||
|
||||
Future<void> saveBookState(String fileName, String position) async {
|
||||
final dbInstance = await instance.database;
|
||||
await dbInstance.insert(
|
||||
'bookposition',
|
||||
{'fileName': fileName, 'position': position},
|
||||
@ -121,6 +193,7 @@ class MyLibraryDb {
|
||||
}
|
||||
|
||||
Future<void> deleteBookState(String fileName) async {
|
||||
final dbInstance = await instance.database;
|
||||
await dbInstance.delete(
|
||||
'bookposition',
|
||||
where: 'fileName = ?',
|
||||
@ -129,6 +202,7 @@ class MyLibraryDb {
|
||||
}
|
||||
|
||||
Future<String?> getBookState(String fileName) async {
|
||||
final dbInstance = await instance.database;
|
||||
List<Map<String, dynamic>> data = await dbInstance
|
||||
.query('bookposition', where: 'fileName = ?', whereArgs: [fileName]);
|
||||
List<dynamic> dataList = List.generate(data.length, (i) {
|
||||
@ -141,29 +215,45 @@ class MyLibraryDb {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> savePreference(String name, bool value) async {
|
||||
int boolInt = value ? 1 : 0;
|
||||
Future<void> savePreference(String name, dynamic value) async {
|
||||
switch (value.runtimeType) {
|
||||
case bool:
|
||||
value = value ? 1 : 0;
|
||||
break;
|
||||
case int || String:
|
||||
break;
|
||||
default:
|
||||
throw 'Invalid type';
|
||||
}
|
||||
Database dbInstance = await instance.database;
|
||||
await dbInstance.insert(
|
||||
'preferences',
|
||||
{'name': name, 'value': boolInt},
|
||||
{'name': name, 'value': value},
|
||||
conflictAlgorithm: ConflictAlgorithm.replace,
|
||||
);
|
||||
}
|
||||
|
||||
Future<bool> getPreference(String name) async {
|
||||
Future<dynamic> getPreference(String name) async {
|
||||
Database dbInstance = await instance.database;
|
||||
List<Map<String, dynamic>> data = await dbInstance
|
||||
.query('preferences', where: 'name = ?', whereArgs: [name]);
|
||||
List<dynamic> dataList = List.generate(data.length, (i) {
|
||||
return {'name': data[i]['name'], 'value': data[i]['value']};
|
||||
});
|
||||
if (dataList.isNotEmpty) {
|
||||
return dataList[0]['value'] == 0 ? false : true;
|
||||
} else {
|
||||
return false;
|
||||
// Convert to int if possible
|
||||
int? preference = int.tryParse(dataList[0]['value']);
|
||||
if (preference != null) {
|
||||
return preference;
|
||||
}
|
||||
// Return string value if not int
|
||||
return dataList[0]['value'];
|
||||
}
|
||||
throw "Preference $name not found";
|
||||
}
|
||||
|
||||
Future<void> setBrowserOptions(String name, String value) async {
|
||||
final dbInstance = await instance.database;
|
||||
await dbInstance.insert(
|
||||
'browserOptions',
|
||||
{'name': name, 'value': value},
|
||||
@ -172,6 +262,7 @@ class MyLibraryDb {
|
||||
}
|
||||
|
||||
Future<String> getBrowserOptions(String name) async {
|
||||
final dbInstance = await instance.database;
|
||||
List<Map<String, dynamic>> data = await dbInstance
|
||||
.query('browserOptions', where: 'name = ?', whereArgs: [name]);
|
||||
List<dynamic> dataList = List.generate(data.length, (i) {
|
||||
|
@ -7,11 +7,13 @@ import 'package:dio/dio.dart';
|
||||
|
||||
// Project imports:
|
||||
import 'package:openlib/services/database.dart' show MyLibraryDb;
|
||||
import 'files.dart';
|
||||
|
||||
MyLibraryDb dataBase = MyLibraryDb.instance;
|
||||
|
||||
Future<String> _getFilePath(String fileName) async {
|
||||
final path = await getAppDirectoryPath;
|
||||
return '$path/$fileName';
|
||||
String bookStorageDirectory =
|
||||
await dataBase.getPreference('bookStorageDirectory');
|
||||
return '$bookStorageDirectory/$fileName';
|
||||
}
|
||||
|
||||
List<String> _reorderMirrors(List<String> mirrors) {
|
||||
@ -114,8 +116,9 @@ Future<void> downloadFile(
|
||||
Future<bool> verifyFileCheckSum(
|
||||
{required String md5Hash, required String format}) async {
|
||||
try {
|
||||
final path = await getAppDirectoryPath;
|
||||
final filePath = '$path/$md5Hash.$format';
|
||||
final bookStorageDirectory =
|
||||
await dataBase.getPreference('bookStorageDirectory');
|
||||
final filePath = '$bookStorageDirectory/$md5Hash.$format';
|
||||
final file = File(filePath);
|
||||
final stream = file.openRead();
|
||||
final hash = await md5.bind(stream).first;
|
||||
|
@ -6,8 +6,12 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
// Project imports:
|
||||
import 'package:openlib/services/database.dart';
|
||||
import 'package:openlib/state/state.dart' show myLibraryProvider;
|
||||
|
||||
Future<String> get getAppDirectoryPath async {
|
||||
MyLibraryDb dataBase = MyLibraryDb.instance;
|
||||
|
||||
Future<String> get getBookStorageDefaultDirectory async {
|
||||
if (Platform.isAndroid) {
|
||||
final directory = await getExternalStorageDirectory();
|
||||
return directory!.path;
|
||||
@ -47,8 +51,9 @@ Future<void> deleteFile(String filePath) async {
|
||||
}
|
||||
|
||||
Future<String> getFilePath(String fileName) async {
|
||||
String appDirPath = await getAppDirectoryPath;
|
||||
String filePath = '$appDirPath/$fileName';
|
||||
final bookStorageDirectory =
|
||||
await dataBase.getPreference('bookStorageDirectory');
|
||||
String filePath = '$bookStorageDirectory/$fileName';
|
||||
bool isExists = await isFileExists(filePath);
|
||||
if (isExists == true) {
|
||||
return filePath;
|
||||
@ -60,10 +65,11 @@ Future<void> deleteFileWithDbData(
|
||||
FutureProviderRef ref, String md5, String format) async {
|
||||
try {
|
||||
String fileName = '$md5.$format';
|
||||
String appDirPath = await getAppDirectoryPath;
|
||||
await deleteFile('$appDirPath/$fileName');
|
||||
await ref.read(dbProvider).delete(md5);
|
||||
await ref.read(dbProvider).deleteBookState(fileName);
|
||||
final bookStorageDirectory =
|
||||
await dataBase.getPreference('bookStorageDirectory');
|
||||
await deleteFile('$bookStorageDirectory/$fileName');
|
||||
await dataBase.delete(md5);
|
||||
await dataBase.deleteBookState(fileName);
|
||||
// ignore: unused_result
|
||||
ref.refresh(myLibraryProvider);
|
||||
} catch (e) {
|
||||
|
@ -14,6 +14,8 @@ import 'package:openlib/services/database.dart';
|
||||
import 'package:openlib/services/files.dart';
|
||||
import 'package:openlib/services/open_library.dart';
|
||||
|
||||
MyLibraryDb dataBase = MyLibraryDb.instance;
|
||||
|
||||
//Provider for dropdownbutton in search page
|
||||
|
||||
Map<String, String> typeValues = {
|
||||
@ -151,15 +153,13 @@ final downloadState =
|
||||
final checkSumState = StateProvider.autoDispose<CheckSumProcessState>(
|
||||
(ref) => CheckSumProcessState.waiting);
|
||||
|
||||
final dbProvider = Provider<MyLibraryDb>((ref) => throw UnimplementedError());
|
||||
|
||||
final myLibraryProvider = FutureProvider((ref) async {
|
||||
return await ref.read(dbProvider).getAll();
|
||||
return dataBase.getAll();
|
||||
});
|
||||
|
||||
final checkIdExists =
|
||||
FutureProvider.family.autoDispose<bool, String>((ref, id) async {
|
||||
return await ref.read(dbProvider).checkIdExists(id);
|
||||
return await dataBase.checkIdExists(id);
|
||||
});
|
||||
|
||||
class FileName {
|
||||
@ -179,18 +179,18 @@ final totalPdfPage = StateProvider.autoDispose<int>((ref) => 0);
|
||||
|
||||
Future<void> savePdfState(String fileName, WidgetRef ref) async {
|
||||
String position = ref.watch(pdfCurrentPage).toString();
|
||||
await ref.watch(dbProvider).saveBookState(fileName, position);
|
||||
await dataBase.saveBookState(fileName, position);
|
||||
}
|
||||
|
||||
Future<void> saveEpubState(
|
||||
String fileName, String? position, WidgetRef ref) async {
|
||||
String pos = position ?? '';
|
||||
await ref.watch(dbProvider).saveBookState(fileName, pos);
|
||||
await dataBase.saveBookState(fileName, pos);
|
||||
}
|
||||
|
||||
final getBookPosition =
|
||||
FutureProvider.family.autoDispose<String?, String>((ref, fileName) async {
|
||||
return await ref.read(dbProvider).getBookState(fileName);
|
||||
return await dataBase.getBookState(fileName);
|
||||
});
|
||||
|
||||
final openPdfWithExternalAppProvider = StateProvider<bool>((ref) => false);
|
||||
|
@ -34,7 +34,6 @@ import 'package:openlib/state/state.dart'
|
||||
CheckSumProcessState,
|
||||
downloadState,
|
||||
checkSumState,
|
||||
dbProvider,
|
||||
checkIdExists,
|
||||
myLibraryProvider;
|
||||
|
||||
@ -246,7 +245,9 @@ Future<void> downloadFileWidget(
|
||||
ref.read(downloadProgressProvider.notifier).state = rcv / total;
|
||||
|
||||
if (rcv / total == 1.0) {
|
||||
await ref.read(dbProvider).insert(MyBook(
|
||||
MyLibraryDb dataBase = MyLibraryDb.instance;
|
||||
|
||||
await dataBase.insert(MyBook(
|
||||
id: data.md5,
|
||||
title: data.title,
|
||||
author: data.author,
|
||||
|
@ -16,7 +16,7 @@ import 'package:openlib/services/files.dart' show getFilePath;
|
||||
import 'package:openlib/ui/components/snack_bar_widget.dart';
|
||||
|
||||
import 'package:openlib/state/state.dart'
|
||||
show filePathProvider, saveEpubState, dbProvider, getBookPosition;
|
||||
show filePathProvider, saveEpubState, getBookPosition;
|
||||
|
||||
Future<void> launchEpubViewer(
|
||||
{required String fileName,
|
||||
@ -24,7 +24,9 @@ Future<void> launchEpubViewer(
|
||||
required WidgetRef ref}) async {
|
||||
if (Platform.isAndroid || Platform.isIOS) {
|
||||
String path = await getFilePath(fileName);
|
||||
String? epubConfig = await ref.read(dbProvider).getBookState(fileName);
|
||||
MyLibraryDb dataBase = MyLibraryDb.instance;
|
||||
|
||||
String? epubConfig = await dataBase.getBookState(fileName);
|
||||
await OpenFile.open(path);
|
||||
} else {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) {
|
||||
|
@ -6,8 +6,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
// Project imports:
|
||||
import 'package:openlib/services/database.dart';
|
||||
import 'package:openlib/state/state.dart' show dbProvider;
|
||||
|
||||
import 'package:openlib/ui/components/book_info_widget.dart';
|
||||
import 'package:openlib/ui/components/file_buttons_widget.dart';
|
||||
|
||||
@ -26,7 +24,9 @@ class BookPage extends StatelessWidget {
|
||||
),
|
||||
body: Consumer(
|
||||
builder: (BuildContext context, WidgetRef ref, _) {
|
||||
final bookInfo = ref.read(dbProvider).getId(id);
|
||||
MyLibraryDb dataBase = MyLibraryDb.instance;
|
||||
|
||||
final bookInfo = dataBase.getId(id);
|
||||
|
||||
return FutureBuilder(
|
||||
future: bookInfo,
|
||||
|
@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
// Package imports:
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
@ -16,13 +17,42 @@ import 'package:openlib/ui/about_page.dart';
|
||||
import 'package:openlib/ui/components/page_title_widget.dart';
|
||||
|
||||
import 'package:openlib/state/state.dart'
|
||||
show themeModeProvider, openPdfWithExternalAppProvider, dbProvider;
|
||||
show themeModeProvider, openPdfWithExternalAppProvider;
|
||||
|
||||
Future<void> requestStoragePermission() async {
|
||||
bool permissionGranted = false;
|
||||
// Check whether the device is running Android 11 or higher
|
||||
DeviceInfoPlugin plugin = DeviceInfoPlugin();
|
||||
AndroidDeviceInfo android = await plugin.androidInfo;
|
||||
// Android < 11
|
||||
if (android.version.sdkInt < 33) {
|
||||
if (await Permission.storage.request().isGranted) {
|
||||
permissionGranted = true;
|
||||
} else if (await Permission.storage.request().isPermanentlyDenied) {
|
||||
await openAppSettings();
|
||||
}
|
||||
}
|
||||
// Android > 11
|
||||
else {
|
||||
if (await Permission.manageExternalStorage.request().isGranted) {
|
||||
permissionGranted = true;
|
||||
} else if (await Permission.manageExternalStorage
|
||||
.request()
|
||||
.isPermanentlyDenied) {
|
||||
await openAppSettings();
|
||||
} else if (await Permission.manageExternalStorage.request().isDenied) {
|
||||
permissionGranted = false;
|
||||
}
|
||||
}
|
||||
print("Storage permission status: $permissionGranted");
|
||||
}
|
||||
|
||||
class SettingsPage extends ConsumerWidget {
|
||||
const SettingsPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
MyLibraryDb dataBase = MyLibraryDb.instance;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 5, right: 5, top: 10),
|
||||
child: SingleChildScrollView(
|
||||
@ -49,8 +79,7 @@ class SettingsPage extends ConsumerWidget {
|
||||
onChanged: (bool value) {
|
||||
ref.read(themeModeProvider.notifier).state =
|
||||
value == true ? ThemeMode.dark : ThemeMode.light;
|
||||
ref.read(dbProvider).savePreference('darkMode', value);
|
||||
|
||||
dataBase.savePreference('darkMode', value);
|
||||
if (Platform.isAndroid) {
|
||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
||||
systemNavigationBarColor:
|
||||
@ -77,13 +106,31 @@ class SettingsPage extends ConsumerWidget {
|
||||
onChanged: (bool value) {
|
||||
ref.read(openPdfWithExternalAppProvider.notifier).state =
|
||||
value;
|
||||
ref
|
||||
.read(dbProvider)
|
||||
.savePreference('openPdfwithExternalApp', value);
|
||||
dataBase.savePreference('openPdfwithExternalApp', value);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
_PaddedContainer(
|
||||
onClick: () async {
|
||||
String? pickedDirectory =
|
||||
await FilePicker.platform.getDirectoryPath();
|
||||
// TODO: Attempt moving existing books to the new directory
|
||||
await requestStoragePermission();
|
||||
dataBase.savePreference(
|
||||
'bookStorageDirectory', pickedDirectory);
|
||||
},
|
||||
children: [
|
||||
Text(
|
||||
"Change storage path",
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context).colorScheme.tertiary,
|
||||
),
|
||||
),
|
||||
Icon(Icons.folder),
|
||||
]),
|
||||
_PaddedContainer(
|
||||
onClick: () {
|
||||
Navigator.push(context,
|
||||
|
@ -12,7 +12,7 @@ import 'package:webview_cookie_manager/webview_cookie_manager.dart'
|
||||
as cookiejar;
|
||||
|
||||
import 'package:openlib/state/state.dart'
|
||||
show cookieProvider, userAgentProvider, dbProvider, bookInfoProvider;
|
||||
show cookieProvider, userAgentProvider, bookInfoProvider;
|
||||
|
||||
class Webview extends ConsumerStatefulWidget {
|
||||
const Webview({super.key, required this.url});
|
||||
@ -28,6 +28,7 @@ class _WebviewState extends ConsumerState<Webview> {
|
||||
final cookieManager = cookiejar.WebviewCookieManager();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
MyLibraryDb dataBase = MyLibraryDb.instance;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
automaticallyImplyLeading: false,
|
||||
@ -37,11 +38,12 @@ class _WebviewState extends ConsumerState<Webview> {
|
||||
child: WebViewWidget(
|
||||
controller: controller
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
..setBackgroundColor(const Color(0x00000000))
|
||||
// ..setBackgroundColor(const Color(
|
||||
// 0x00000000)) // TODO: Crashes macOS app. https://github.com/flutter/flutter/issues/153773
|
||||
..loadRequest(Uri.parse(widget.url))
|
||||
..getUserAgent().then((value) {
|
||||
ref.read(userAgentProvider.notifier).state = value!;
|
||||
ref.read(dbProvider).setBrowserOptions('userAgent', value);
|
||||
dataBase.setBrowserOptions('userAgent', value);
|
||||
})
|
||||
..setNavigationDelegate(NavigationDelegate(
|
||||
onPageStarted: (url) async {
|
||||
@ -64,9 +66,7 @@ class _WebviewState extends ConsumerState<Webview> {
|
||||
|
||||
ref.read(cookieProvider.notifier).state = cfClearance;
|
||||
|
||||
await ref
|
||||
.read(dbProvider)
|
||||
.setBrowserOptions('cookie', cfClearance);
|
||||
await dataBase.setBrowserOptions('cookie', cfClearance);
|
||||
|
||||
ref.invalidate(bookInfoProvider);
|
||||
|
||||
|
@ -5,12 +5,14 @@
|
||||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import device_info_plus
|
||||
import path_provider_foundation
|
||||
import sqflite
|
||||
import url_launcher_macos
|
||||
import webview_flutter_wkwebview
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
|
24
pubspec.lock
24
pubspec.lock
@ -137,6 +137,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
device_info_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: device_info_plus
|
||||
sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.1.2"
|
||||
device_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_platform_interface
|
||||
sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.1"
|
||||
dio:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -917,6 +933,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.5.4"
|
||||
win32_registry:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32_registry
|
||||
sha256: "723b7f851e5724c55409bb3d5a32b203b3afe8587eaf5dafb93a5fed8ecda0d6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.4"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -62,6 +62,7 @@ dependencies:
|
||||
dev: ^1.0.0
|
||||
crypto: ^3.0.3
|
||||
file_picker: ^8.1.2
|
||||
device_info_plus: ^10.1.2
|
||||
|
||||
dev_dependencies:
|
||||
import_sorter: ^4.6.0
|
||||
|
Reference in New Issue
Block a user