diff --git a/lib/services/database.dart b/lib/services/database.dart index f2f3718..2c2bd4f 100644 --- a/lib/services/database.dart +++ b/lib/services/database.dart @@ -1,15 +1,32 @@ +import 'dart:io'; import 'package:sqflite/sqflite.dart'; class Sqlite { static Future initDb() async { var databasesPath = await getDatabasesPath(); String path = '$databasesPath/mylibrary.db'; + bool isMobile = Platform.isAndroid || Platform.isIOS; - Database dbInstance = await openDatabase(path, version: 1, - 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)'); - }); + Database dbInstance = await openDatabase( + path, + version: 2, + 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)'); + if (isMobile) { + await db.execute( + 'CREATE TABLE bookposition (fileName TEXT PRIMARY KEY,position TEXT)'); + } + }, + onUpgrade: (db, oldVersion, newVersion) async { + List isTableExist = await db.query('sqlite_master', + where: 'name = ?', whereArgs: ['bookposition']); + if (isMobile && isTableExist.isEmpty) { + await db.execute( + 'CREATE TABLE bookposition (fileName TEXT PRIMARY KEY,position TEXT)'); + } + }, + ); return dbInstance; } } @@ -118,4 +135,26 @@ class MyLibraryDb { }); return myBookList.reversed.toList(); } + + Future saveBookState(String fileName, String position) async { + await dbInstance.insert( + 'bookposition', + {'fileName': fileName, 'position': position}, + conflictAlgorithm: ConflictAlgorithm.replace, + ); + } + + Future getBookState(String fileName) async { + List> data = await dbInstance + .query('bookposition', where: 'fileName = ?', whereArgs: [fileName]); + List dataList = List.generate(data.length, (i) { + return {'fileName': data[i]['fileName'], 'position': data[i]['position']}; + }); + if (dataList.isNotEmpty) { + print(dataList); + return dataList[0]['position']; + } else { + return null; + } + } } diff --git a/lib/state/state.dart b/lib/state/state.dart index 8696819..9ff2349 100644 --- a/lib/state/state.dart +++ b/lib/state/state.dart @@ -125,6 +125,16 @@ final deleteFileFromMyLib = final pdfCurrentPage = StateProvider.autoDispose((ref) => 0); final totalPdfPage = StateProvider.autoDispose((ref) => 0); +Future savePdfState(String fileName, WidgetRef ref) async { + String position = ref.watch(pdfCurrentPage).toString(); + await ref.watch(dbProvider).saveBookState(fileName, position); +} + +final getBookPosition = + FutureProvider.family.autoDispose((ref, fileName) async { + return await ref.read(dbProvider).getBookState(fileName); +}); + final filePathProvider = FutureProvider.family((ref, fileName) async { String path = await getFilePath(fileName); diff --git a/lib/ui/epub_viewer.dart b/lib/ui/epub_viewer.dart index 930107d..726e389 100644 --- a/lib/ui/epub_viewer.dart +++ b/lib/ui/epub_viewer.dart @@ -19,7 +19,7 @@ class _EpubViewState extends ConsumerState { Widget build(BuildContext context) { final filePath = ref.watch(filePathProvider(widget.fileName)); return filePath.when(data: (data) { - return EpubViewer(filePath: data); + return EpubViewer(filePath: data, fileName: widget.fileName); }, error: (error, stack) { return Scaffold( appBar: AppBar( @@ -49,17 +49,19 @@ class _EpubViewState extends ConsumerState { } } -class EpubViewer extends StatefulWidget { - const EpubViewer({Key? key, required this.filePath}) : super(key: key); +class EpubViewer extends ConsumerStatefulWidget { + const EpubViewer({Key? key, required this.filePath, required this.fileName}) + : super(key: key); final String filePath; + final String fileName; @override // ignore: library_private_types_in_public_api _EpubViewerState createState() => _EpubViewerState(); } -class _EpubViewerState extends State { +class _EpubViewerState extends ConsumerState { late EpubController _epubReaderController; @override diff --git a/lib/ui/pdf_viewer.dart b/lib/ui/pdf_viewer.dart index 9476522..08c766c 100644 --- a/lib/ui/pdf_viewer.dart +++ b/lib/ui/pdf_viewer.dart @@ -2,7 +2,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_pdfview/flutter_pdfview.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:openlib/state/state.dart' - show filePathProvider, pdfCurrentPage, totalPdfPage; + show + filePathProvider, + pdfCurrentPage, + totalPdfPage, + savePdfState, + getBookPosition; import 'package:url_launcher/url_launcher.dart'; import 'dart:io' show Platform; @@ -20,7 +25,7 @@ class _PdfViewState extends ConsumerState { Widget build(BuildContext context) { final filePath = ref.watch(filePathProvider(widget.fileName)); return filePath.when(data: (data) { - return PdfViewer(filePath: data); + return PdfViewer(filePath: data, fileName: widget.fileName); }, error: (error, stack) { return Scaffold( appBar: AppBar( @@ -51,9 +56,11 @@ class _PdfViewState extends ConsumerState { } class PdfViewer extends ConsumerStatefulWidget { - const PdfViewer({Key? key, required this.filePath}) : super(key: key); + const PdfViewer({Key? key, required this.filePath, required this.fileName}) + : super(key: key); final String filePath; + final String fileName; @override ConsumerState createState() => _PdfViewerState(); @@ -62,6 +69,19 @@ class PdfViewer extends ConsumerStatefulWidget { class _PdfViewerState extends ConsumerState { late PDFViewController controller; + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + if (Platform.isAndroid || Platform.isIOS) { + savePdfState(widget.fileName, ref); + } + super.dispose(); + } + Future _openPdfWithDefaultViewer(String fileName) async { debugPrint("Opening : $fileName"); final fileUrl = Uri.parse(fileName); @@ -127,17 +147,47 @@ class _PdfViewerState extends ConsumerState { : [], ), body: isMobile - ? PDFView( - swipeHorizontal: true, - fitEachPage: true, - fitPolicy: FitPolicy.BOTH, - filePath: widget.filePath, - onViewCreated: (controller) { - this.controller = controller; + ? ref.watch(getBookPosition(widget.fileName)).when( + data: (data) { + return PDFView( + swipeHorizontal: true, + fitEachPage: true, + fitPolicy: FitPolicy.BOTH, + filePath: widget.filePath, + onViewCreated: (controller) { + this.controller = controller; + }, + defaultPage: int.parse(data ?? '0'), + onPageChanged: (page, total) { + ref.read(pdfCurrentPage.notifier).state = page ?? 0; + ref.read(totalPdfPage.notifier).state = total ?? 0; + }, + ); }, - onPageChanged: (page, total) { - ref.read(pdfCurrentPage.notifier).state = page ?? 0; - ref.read(totalPdfPage.notifier).state = total ?? 0; + error: (error, stackTrace) { + return PDFView( + swipeHorizontal: true, + fitEachPage: true, + fitPolicy: FitPolicy.BOTH, + filePath: widget.filePath, + onViewCreated: (controller) { + this.controller = controller; + }, + onPageChanged: (page, total) { + ref.read(pdfCurrentPage.notifier).state = page ?? 0; + ref.read(totalPdfPage.notifier).state = total ?? 0; + }, + ); + }, + loading: () { + return Center( + child: SizedBox( + width: 25, + height: 25, + child: CircularProgressIndicator( + color: Theme.of(context).colorScheme.secondary, + ), + )); }, ) : Center(