18 Commits

Author SHA1 Message Date
546805be20 updated packages 2023-09-03 07:46:52 -07:00
250f0f8b7b openwith support 2023-09-03 07:29:57 -07:00
f0d0178a2d added openwith feature 2023-09-02 05:38:27 -07:00
f4f86a1353 openwith feature added 2023-09-02 04:59:01 -07:00
93013fe6bb added open with feature 2023-09-02 03:53:03 -07:00
1de126104d Migated to new epub viewer for android and ios 2023-08-30 00:56:02 -07:00
e4c8ddaa88 fixed crashing 2023-08-29 06:36:55 -07:00
82798bb749 added resume reading in new epub reader 2023-08-29 06:24:20 -07:00
16fc051219 added new epub reader 2023-08-29 05:23:38 -07:00
da399604bf added new epub viewer 2023-08-27 23:28:33 -07:00
1b87e89470 finished settings and dark theme 2023-08-25 05:20:13 -07:00
0db7794455 added about page 2023-08-25 05:02:47 -07:00
6b31a63e86 adjusted bottombar transitions 2023-08-24 23:17:02 -07:00
27061a1922 added db to persist theme modes 2023-08-24 23:12:30 -07:00
162ea41196 theme change added 2023-08-23 01:18:12 -07:00
010dc1dfdb added dark mode 2023-08-23 01:02:21 -07:00
b2a1be7a7e init settings page design 2023-08-22 23:29:07 -07:00
1507656944 settings page 2023-08-22 20:13:03 -07:00
24 changed files with 811 additions and 188 deletions

View File

@ -79,6 +79,8 @@ android {
// Signing with the debug keys for now, so `flutter run --release` works.
// replace with "debug" when running on debug version
signingConfig signingConfigs.release
minifyEnabled false
shrinkResources false
}
}
}

View File

@ -1,6 +1,22 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEOS" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29"/>
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
</intent>
</queries>
<application
android:label="Openlib"
android:name="${applicationName}"

View File

@ -3,15 +3,22 @@ import 'dart:io' show Platform;
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_nav_bar/google_nav_bar.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:openlib/ui/extensions.dart';
import 'package:openlib/ui/themes.dart';
import 'package:openlib/ui/trending_page.dart';
import 'package:openlib/ui/search_page.dart';
import 'package:openlib/ui/mylibrary_page.dart';
import 'package:openlib/ui/settings_page.dart';
import 'package:openlib/services/database.dart' show Sqlite, MyLibraryDb;
import 'package:openlib/services/files.dart'
show moveFilesToAndroidInternalStorage;
import 'package:openlib/state/state.dart'
show selectedIndexProvider, dbProvider;
show
selectedIndexProvider,
themeModeProvider,
openPdfWithExternalAppProvider,
openEpubWithExternalAppProvider,
dbProvider;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
@ -21,19 +28,38 @@ void main() async {
databaseFactory = databaseFactoryFfi;
}
Database db = await Sqlite.initDb();
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');
if (Platform.isAndroid) {
await moveFilesToAndroidInternalStorage();
}
runApp(
ProviderScope(
overrides: [dbProvider.overrideWithValue(MyLibraryDb(dbInstance: db))],
overrides: [
dbProvider.overrideWithValue(dataBase),
themeModeProvider.overrideWith(
(ref) => isDarkMode ? ThemeMode.dark : ThemeMode.light),
openPdfWithExternalAppProvider
.overrideWith((ref) => openPdfwithExternalapp),
openEpubWithExternalAppProvider
.overrideWith((ref) => openEpubwithExternalapp)
],
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
class MyApp extends ConsumerWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
Widget build(BuildContext context, WidgetRef ref) {
return MaterialApp(
builder: (BuildContext context, Widget? child) {
return MediaQuery(
@ -45,32 +71,9 @@ class MyApp extends StatelessWidget {
},
debugShowCheckedModeBanner: false,
title: 'Openlib',
theme: ThemeData(
primaryColor: Colors.white,
colorScheme: ColorScheme.light(
primary: Colors.white,
secondary: '#FB0101'.toColor(),
tertiary: Colors.black,
tertiaryContainer: '#F2F2F2'.toColor(),
),
textTheme: const TextTheme(
displayLarge: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 21,
),
displayMedium: TextStyle(
fontSize: 13,
fontWeight: FontWeight.bold,
color: Colors.black,
overflow: TextOverflow.ellipsis,
),
),
fontFamily: GoogleFonts.nunito().fontFamily,
useMaterial3: true,
textSelectionTheme: TextSelectionThemeData(
selectionColor: '#FB0101'.toColor(),
selectionHandleColor: '#FB0101'.toColor())),
theme: lightTheme,
darkTheme: darkTheme,
themeMode: ref.watch(themeModeProvider),
home: const HomePage(),
);
}
@ -87,7 +90,8 @@ class _HomePageState extends ConsumerState<HomePage> {
static const List<Widget> _widgetOptions = <Widget>[
TrendingPage(),
SearchPage(),
MyLibraryPage()
MyLibraryPage(),
SettingsPage()
];
@override
@ -111,14 +115,14 @@ class _HomePageState extends ConsumerState<HomePage> {
color: Theme.of(context).colorScheme.secondary,
),
tabMargin: const EdgeInsets.fromLTRB(13, 6, 13, 2.5),
curve: Curves.easeInOut, // tab animation curves
duration: const Duration(milliseconds: 150),
curve: Curves.easeIn,
duration: const Duration(milliseconds: 125),
gap: 5,
color: const Color.fromARGB(255, 255, 255, 255),
activeColor: const Color.fromARGB(255, 255, 255, 255),
iconSize: 21, // tab button icon size
iconSize: 19, // tab button icon size
tabBackgroundColor: Theme.of(context).colorScheme.secondary,
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 6.5),
padding: const EdgeInsets.symmetric(horizontal: 13, vertical: 6.5),
tabs: const [
GButton(
icon: Icons.trending_up,
@ -127,7 +131,7 @@ class _HomePageState extends ConsumerState<HomePage> {
textStyle: TextStyle(
fontWeight: FontWeight.w900,
color: Colors.white,
fontSize: 13,
fontSize: 11,
),
),
GButton(
@ -137,7 +141,7 @@ class _HomePageState extends ConsumerState<HomePage> {
textStyle: TextStyle(
fontWeight: FontWeight.w900,
color: Colors.white,
fontSize: 13,
fontSize: 11,
),
),
GButton(
@ -147,7 +151,17 @@ class _HomePageState extends ConsumerState<HomePage> {
textStyle: TextStyle(
fontWeight: FontWeight.w900,
color: Colors.white,
fontSize: 13,
fontSize: 11,
),
),
GButton(
icon: Icons.build,
text: 'Settings',
iconColor: Colors.white,
textStyle: TextStyle(
fontWeight: FontWeight.w900,
color: Colors.white,
fontSize: 11,
),
),
],

View File

@ -9,10 +9,12 @@ class Sqlite {
Database dbInstance = await openDatabase(
path,
version: 2,
version: 3,
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 BOOLEAN)');
if (isMobile) {
await db.execute(
'CREATE TABLE bookposition (fileName TEXT PRIMARY KEY,position TEXT)');
@ -21,6 +23,12 @@ class Sqlite {
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']);
if (isPreferenceTableExist.isEmpty) {
await db.execute(
'CREATE TABLE preferences (name TEXT PRIMARY KEY,value BOOLEAN)');
}
if (isMobile && isTableExist.isEmpty) {
await db.execute(
'CREATE TABLE bookposition (fileName TEXT PRIMARY KEY,position TEXT)');
@ -164,4 +172,26 @@ class MyLibraryDb {
return null;
}
}
Future<void> savePreference(String name, bool value) async {
int boolInt = value ? 1 : 0;
await dbInstance.insert(
'preferences',
{'name': name, 'value': boolInt},
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<bool> getPreference(String name) async {
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;
}
}
}

View File

@ -1,9 +1,9 @@
import 'package:path_provider/path_provider.dart';
import 'package:dio/dio.dart';
import 'files.dart';
Future<String> _getFilePath(String fileName) async {
final path = await getApplicationDocumentsDirectory();
return '${path.path}/$fileName';
final path = await getAppDirectoryPath;
return '$path/$fileName';
}
List<String> _reorderMirrors(List<String> mirrors) {

View File

@ -4,8 +4,32 @@ import 'package:path_provider/path_provider.dart';
import 'package:openlib/state/state.dart' show dbProvider, myLibraryProvider;
Future<String> get getAppDirectoryPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
if (Platform.isAndroid) {
final directory = await getExternalStorageDirectory();
return directory!.path;
} else {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
}
Future<void> moveFilesToAndroidInternalStorage() async {
try {
final directory = await getApplicationDocumentsDirectory();
final directoryExternal = await getExternalStorageDirectory();
List<FileSystemEntity> files = Directory(directory.path).listSync();
for (var element in files) {
if ((element.path.contains('pdf')) || element.path.contains('epub')) {
String fileName = element.path.split('/').last;
File file = File(element.path);
file.copySync('${directoryExternal!.path}/$fileName');
file.deleteSync();
}
}
} catch (e) {
// ignore: avoid_print
print(e);
}
}
Future<bool> isFileExists(String filePath) async {

View File

@ -1,4 +1,5 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:openlib/services/database.dart';
import 'package:dio/dio.dart';
@ -31,6 +32,8 @@ Map<String, String> sortValues = {
final selectedIndexProvider = StateProvider<int>((ref) => 0);
final themeModeProvider = StateProvider<ThemeMode>((ref) => ThemeMode.light);
final selectedTypeState = StateProvider<String>((ref) => "All");
final getTypeValue = Provider.autoDispose<String>((ref) {
@ -141,6 +144,9 @@ final getBookPosition =
return await ref.read(dbProvider).getBookState(fileName);
});
final openPdfWithExternalAppProvider = StateProvider<bool>((ref) => false);
final openEpubWithExternalAppProvider = StateProvider<bool>((ref) => false);
final filePathProvider =
FutureProvider.family<String, String>((ref, fileName) async {
String path = await getFilePath(fileName);

131
lib/ui/about_page.dart Normal file
View File

@ -0,0 +1,131 @@
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:openlib/ui/components/snack_bar_widget.dart';
import 'package:openlib/ui/components/page_title_widget.dart';
class AboutPage extends StatelessWidget {
const AboutPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.primary,
title: const Text("Openlib"),
titleTextStyle: Theme.of(context).textTheme.displayLarge,
),
body: const SingleChildScrollView(
physics: BouncingScrollPhysics(),
scrollDirection: Axis.vertical,
child: Padding(
padding: EdgeInsets.only(left: 5, right: 5, top: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TitleText("About"),
Padding(
padding:
EdgeInsets.only(left: 7, right: 7, top: 13, bottom: 10),
child: Text(
"An Open source app to download and read books from shadow library (Anna`s Archive)",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
),
Padding(
padding: EdgeInsets.only(left: 7, right: 7, top: 10),
child: Text(
"Version",
style: TextStyle(fontSize: 19, fontWeight: FontWeight.bold),
),
),
Padding(
padding: EdgeInsets.only(left: 7, right: 7, top: 5),
child: Text(
"1.0.1",
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Colors.grey),
),
),
Padding(
padding: EdgeInsets.only(left: 7, right: 7, top: 15),
child: Text(
"Github",
style: TextStyle(fontSize: 19, fontWeight: FontWeight.bold),
),
),
_UrlText(
text: 'Open Github Page',
url: 'https://github.com/dstark5/Openlib',
),
_UrlText(
text: 'Contribute To Openlib',
url:
'https://github.com/dstark5/Openlib/blob/main/CONTRIBUTING.md'),
_UrlText(
text: 'Report An Issue',
url: 'https://github.com/dstark5/Openlib/issues'),
Padding(
padding: EdgeInsets.only(left: 7, right: 7, top: 15),
child: Text(
"Licence",
style: TextStyle(fontSize: 19, fontWeight: FontWeight.bold),
),
),
_UrlText(
text: "GPL v3.0 license",
url: 'https://www.gnu.org/licenses/gpl-3.0.en.html'),
],
),
),
),
);
}
}
class _UrlText extends StatelessWidget {
const _UrlText({Key? key, required this.text, required this.url})
: super(key: key);
final String url;
final String text;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 7, right: 7, top: 5),
child: InkWell(
onTap: () async {
final Uri uri = Uri.parse(url);
if (!await launchUrl(uri, mode: LaunchMode.externalApplication)) {
// ignore: use_build_context_synchronously
showSnackBar(context: context, message: 'Could not launch $uri');
}
},
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
text,
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Colors.blueAccent,
),
),
const SizedBox(
width: 2,
),
const Icon(
Icons.launch,
size: 17,
color: Colors.blueAccent,
)
],
),
),
);
}
}

View File

@ -200,7 +200,7 @@ class _ShowDialog extends ConsumerWidget {
height: 255,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
color: Theme.of(context).colorScheme.tertiaryContainer,
),
padding: const EdgeInsets.fromLTRB(20, 20, 20, 20),
child: SingleChildScrollView(
@ -208,14 +208,14 @@ class _ShowDialog extends ConsumerWidget {
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.all(8),
Padding(
padding: const EdgeInsets.all(8),
child: Text(
"Downloading Book",
style: TextStyle(
fontSize: 19,
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 54, 54, 54),
color: Theme.of(context).colorScheme.tertiary,
decoration: TextDecoration.none),
),
),
@ -223,10 +223,13 @@ class _ShowDialog extends ConsumerWidget {
padding: const EdgeInsets.all(8),
child: Text(
title,
style: const TextStyle(
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.bold,
color: Colors.black54,
color: Theme.of(context)
.colorScheme
.tertiary
.withAlpha(170),
decoration: TextDecoration.none),
overflow: TextOverflow.ellipsis,
maxLines: 2,
@ -259,7 +262,10 @@ class _ShowDialog extends ConsumerWidget {
borderRadius: const BorderRadius.all(Radius.circular(50)),
child: LinearProgressIndicator(
color: Theme.of(context).colorScheme.secondary,
backgroundColor: Colors.black26,
backgroundColor: Theme.of(context)
.colorScheme
.tertiary
.withAlpha(50),
value: downloadProgress,
minHeight: 4,
),

View File

@ -81,10 +81,10 @@ class BookInfoCard extends StatelessWidget {
children: [
Text(
title,
style: const TextStyle(
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Colors.black,
color: Theme.of(context).colorScheme.tertiary,
),
overflow: TextOverflow.ellipsis,
maxLines: 2,
@ -94,7 +94,8 @@ class BookInfoCard extends StatelessWidget {
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: "#4D4D4D".toColor(),
color:
Theme.of(context).textTheme.headlineMedium?.color,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
@ -104,7 +105,7 @@ class BookInfoCard extends StatelessWidget {
style: TextStyle(
fontSize: 11,
fontWeight: FontWeight.bold,
color: "#7B7B7B".toColor(),
color: Theme.of(context).textTheme.headlineSmall?.color,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:openlib/ui/extensions.dart';
import 'package:cached_network_image/cached_network_image.dart';
class BookInfoWidget extends StatelessWidget {
@ -11,6 +10,9 @@ class BookInfoWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
String description = data.description.toString().length < 3
? "No Description available"
: data.description.toString();
return SingleChildScrollView(
physics: const BouncingScrollPhysics(),
scrollDirection: Axis.vertical,
@ -65,28 +67,32 @@ class BookInfoWidget extends StatelessWidget {
text: data.title,
fontSize: 19,
topPadding: 15,
color: Colors.black,
color: Theme.of(context).colorScheme.tertiary,
maxLines: 7,
),
_TopPaddedText(
text: data.publisher ?? "unknown",
fontSize: 15,
topPadding: 7,
color: "#595E60".toColor(),
color: Theme.of(context).textTheme.headlineMedium!.color!,
maxLines: 4,
),
_TopPaddedText(
text: data.author ?? "unknown",
fontSize: 13,
topPadding: 7,
color: "#7F7F7F".toColor(),
color: Theme.of(context).textTheme.headlineSmall!.color!,
maxLines: 3,
),
_TopPaddedText(
text: data.info ?? "",
fontSize: 11,
topPadding: 9,
color: "#A9A8A2".toColor(),
color: Theme.of(context)
.textTheme
.headlineSmall!
.color!
.withAlpha(155),
maxLines: 4,
),
// child slot of page
@ -108,11 +114,12 @@ class BookInfoWidget extends StatelessWidget {
Padding(
padding: const EdgeInsets.only(top: 7, bottom: 10),
child: Text(
data.description ?? "",
description,
style: TextStyle(
fontSize: 11,
fontWeight: FontWeight.bold,
color: "#6B6B6B".toColor(),
color:
Theme.of(context).colorScheme.tertiary.withAlpha(150),
letterSpacing: 1.5,
),
),

View File

@ -26,7 +26,7 @@ class ShowDeleteDialog extends ConsumerWidget {
height: 219,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
color: Theme.of(context).colorScheme.tertiaryContainer,
),
padding: const EdgeInsets.fromLTRB(20, 50, 20, 20),
child: SingleChildScrollView(
@ -34,25 +34,28 @@ class ShowDeleteDialog extends ConsumerWidget {
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.all(8),
Padding(
padding: const EdgeInsets.all(8),
child: Text(
"Delete Book",
style: TextStyle(
fontSize: 19,
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 54, 54, 54),
color: Theme.of(context).colorScheme.tertiary,
decoration: TextDecoration.none),
),
),
const Padding(
padding: EdgeInsets.all(8),
Padding(
padding: const EdgeInsets.all(8),
child: Text(
"This is permanent and cannot be undone",
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.bold,
color: Colors.black54,
color: Theme.of(context)
.colorScheme
.tertiary
.withAlpha(170),
decoration: TextDecoration.none),
overflow: TextOverflow.ellipsis,
maxLines: 2,
@ -88,14 +91,14 @@ class ShowDeleteDialog extends ConsumerWidget {
onDelete();
},
child: const Padding(
padding: EdgeInsets.all(5.0),
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Text(
'Delete',
style: TextStyle(
fontSize: 11,
fontWeight: FontWeight.bold,
color: Colors.black,
color: Theme.of(context).colorScheme.tertiary,
),
),
),

View File

@ -1,10 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:openlib/ui/components/delete_dialog_widget.dart';
import 'package:openlib/ui/epub_viewer.dart';
import 'package:openlib/ui/pdf_viewer.dart';
import 'package:openlib/ui/epub_viewer.dart' show launchEpubViewer;
import 'package:openlib/ui/pdf_viewer.dart' show launchPdfViewer;
class FileOpenAndDeleteButtons extends StatelessWidget {
class FileOpenAndDeleteButtons extends ConsumerWidget {
final String id;
final String format;
final Function onDelete;
@ -17,7 +18,7 @@ class FileOpenAndDeleteButtons extends StatelessWidget {
: super(key: key);
@override
Widget build(BuildContext context) {
Widget build(BuildContext context, WidgetRef ref) {
return Padding(
padding: const EdgeInsets.only(top: 21, bottom: 21),
child: Row(
@ -27,30 +28,19 @@ class FileOpenAndDeleteButtons extends StatelessWidget {
TextButton(
style: TextButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.secondary,
textStyle: const TextStyle(
textStyle: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w900,
color: Colors.white,
color: Theme.of(context).colorScheme.primary,
)),
onPressed: () => {
if (format == 'pdf')
{
Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) {
return PdfView(
fileName: '$id.$format',
);
}))
}
else
{
Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) {
return EpubViewerWidget(
fileName: '$id.$format',
);
}))
}
onPressed: () async {
if (format == 'pdf') {
await launchPdfViewer(
fileName: '$id.$format', context: context, ref: ref);
} else {
await launchEpubViewer(
fileName: '$id.$format', context: context, ref: ref);
}
},
child: const Padding(
padding: EdgeInsets.fromLTRB(17, 8, 17, 8),
@ -82,14 +72,14 @@ class FileOpenAndDeleteButtons extends StatelessWidget {
);
});
},
child: const Padding(
padding: EdgeInsets.all(5.3),
child: Padding(
padding: const EdgeInsets.all(5.3),
child: Text(
'Delete',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.bold,
color: Colors.black,
color: Theme.of(context).colorScheme.tertiary,
),
),
),

View File

@ -1,10 +1,67 @@
import 'dart:io';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:epub_view/epub_view.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:vocsy_epub_viewer/epub_viewer.dart';
import 'package:open_file/open_file.dart';
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, getBookPosition;
show
filePathProvider,
saveEpubState,
dbProvider,
getBookPosition,
openEpubWithExternalAppProvider;
Future<void> launchEpubViewer(
{required String fileName,
required BuildContext context,
required WidgetRef ref}) async {
if (Platform.isAndroid || Platform.isIOS) {
String path = await getFilePath(fileName);
String? epubConfig = await ref.read(dbProvider).getBookState(fileName);
bool openWithExternalApp = ref.watch(openEpubWithExternalAppProvider);
if (openWithExternalApp) {
await OpenFile.open(path);
} else {
try {
VocsyEpub.setConfig(
// ignore: use_build_context_synchronously
themeColor: const Color.fromARGB(255, 210, 15, 1),
identifier: "iosBook",
scrollDirection: EpubScrollDirection.HORIZONTAL,
);
if ((epubConfig?.isNotEmpty ?? true) &&
(epubConfig != null) &&
(!(epubConfig.startsWith('epubcfi')))) {
VocsyEpub.open(path,
lastLocation: EpubLocator.fromJson(json.decode(epubConfig)));
} else {
VocsyEpub.open(path);
}
VocsyEpub.locatorStream.listen((locator) async {
await saveEpubState(fileName, locator, ref);
// convert locator from string to json and save to your database to be retrieved later
});
} catch (e) {
// ignore: use_build_context_synchronously
showSnackBar(context: context, message: 'Unable to open pdf!');
}
}
} else {
Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) {
return EpubViewerWidget(
fileName: fileName,
);
}));
}
}
class EpubViewerWidget extends ConsumerStatefulWidget {
const EpubViewerWidget({super.key, required this.fileName});

View File

@ -21,6 +21,7 @@ class MyLibraryPage extends ConsumerWidget {
return Padding(
padding: const EdgeInsets.only(left: 5, right: 5, top: 10),
child: CustomScrollView(
physics: const BouncingScrollPhysics(),
slivers: <Widget>[
const SliverToBoxAdapter(
child: TitleText("My Library"),

View File

@ -7,10 +7,31 @@ import 'package:openlib/state/state.dart'
pdfCurrentPage,
totalPdfPage,
savePdfState,
openPdfWithExternalAppProvider,
getBookPosition;
import 'package:url_launcher/url_launcher.dart';
import 'package:open_file/open_file.dart';
import 'dart:io' show Platform;
import 'package:openlib/services/files.dart' show getFilePath;
Future<void> launchPdfViewer(
{required String fileName,
required BuildContext context,
required WidgetRef ref}) async {
bool openWithExternalApp = ref.watch(openPdfWithExternalAppProvider);
if (openWithExternalApp) {
String path = await getFilePath(fileName);
await OpenFile.open(path);
} else {
Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) {
return PdfView(
fileName: fileName,
);
}));
}
}
class PdfView extends ConsumerStatefulWidget {
const PdfView({super.key, required this.fileName});

View File

@ -42,12 +42,14 @@ class SearchPage extends ConsumerWidget {
cursorColor: Theme.of(context).colorScheme.secondary,
decoration: InputDecoration(
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black45, width: 2),
borderSide: BorderSide(color: Colors.grey, width: 2),
borderRadius: BorderRadius.all(Radius.circular(50)),
),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black54, width: 2),
borderRadius: BorderRadius.all(Radius.circular(50)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).colorScheme.tertiary,
width: 2),
borderRadius: const BorderRadius.all(Radius.circular(50)),
),
suffixIcon: IconButton(
padding: const EdgeInsets.only(right: 5),
@ -88,12 +90,14 @@ class SearchPage extends ConsumerWidget {
color: Theme.of(context).colorScheme.secondary,
),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black54, width: 2),
borderSide: BorderSide(color: Colors.grey, width: 2),
borderRadius: BorderRadius.all(Radius.circular(50)),
),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black54, width: 2),
borderRadius: BorderRadius.all(Radius.circular(50)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).colorScheme.tertiary,
width: 2),
borderRadius: const BorderRadius.all(Radius.circular(50)),
),
),
icon: const Icon(Icons.arrow_drop_down),
@ -105,7 +109,8 @@ class SearchPage extends ConsumerWidget {
value: value,
child: Text(
value,
style: const TextStyle(fontSize: 12),
style: const TextStyle(
fontSize: 12, fontWeight: FontWeight.bold),
),
);
}).toList(),
@ -128,12 +133,14 @@ class SearchPage extends ConsumerWidget {
color: Theme.of(context).colorScheme.secondary,
),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black45, width: 2),
borderSide: BorderSide(color: Colors.grey, width: 2),
borderRadius: BorderRadius.all(Radius.circular(50)),
),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black54, width: 2),
borderRadius: BorderRadius.all(Radius.circular(50)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).colorScheme.tertiary,
width: 2),
borderRadius: const BorderRadius.all(Radius.circular(50)),
),
),
value: dropdownSortValue,
@ -144,7 +151,8 @@ class SearchPage extends ConsumerWidget {
value: value,
child: Text(
value,
style: const TextStyle(fontSize: 12),
style: const TextStyle(
fontSize: 12, fontWeight: FontWeight.bold),
),
);
}).toList(),

155
lib/ui/settings_page.dart Normal file
View File

@ -0,0 +1,155 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:openlib/ui/components/page_title_widget.dart';
import 'package:openlib/ui/about_page.dart';
import 'package:openlib/state/state.dart'
show
themeModeProvider,
openPdfWithExternalAppProvider,
openEpubWithExternalAppProvider,
dbProvider;
class SettingsPage extends ConsumerWidget {
const SettingsPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
return Padding(
padding: const EdgeInsets.only(left: 5, right: 5, top: 10),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const TitleText("Settings"),
_PaddedContainer(
children: [
Text(
"Dark Mode",
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.tertiary,
),
),
Switch(
// This bool value toggles the switch.
value: ref.watch(themeModeProvider) == ThemeMode.dark,
activeColor: Colors.red,
onChanged: (bool value) {
ref.read(themeModeProvider.notifier).state =
value == true ? ThemeMode.dark : ThemeMode.light;
ref.read(dbProvider).savePreference('darkMode', value);
},
)
],
),
_PaddedContainer(
children: [
Text(
"Open PDF with External Reader",
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.tertiary,
),
),
Switch(
// This bool value toggles the switch.
value: ref.watch(openPdfWithExternalAppProvider),
activeColor: Colors.red,
onChanged: (bool value) {
ref.read(openPdfWithExternalAppProvider.notifier).state =
value;
ref
.read(dbProvider)
.savePreference('openPdfwithExternalApp', value);
},
)
],
),
_PaddedContainer(
children: [
Text(
"Open Epub with External Reader",
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.tertiary,
),
),
Switch(
// This bool value toggles the switch.
value: ref.watch(
openEpubWithExternalAppProvider,
),
activeColor: Colors.red,
onChanged: (bool value) {
ref.read(openEpubWithExternalAppProvider.notifier).state =
value;
ref
.read(dbProvider)
.savePreference('openEpubwithExternalApp', value);
},
)
],
),
_PaddedContainer(
onClick: () {
Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) {
return const AboutPage();
}));
},
children: [
Text(
"About",
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.tertiary,
),
),
],
)
],
),
),
);
}
}
class _PaddedContainer extends StatelessWidget {
const _PaddedContainer({Key? key, this.onClick, required this.children})
: super(key: key);
final VoidCallback? onClick;
final List<Widget> children;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 5, right: 5, top: 10),
child: InkWell(
onTap: onClick,
child: Container(
height: 61,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Theme.of(context).colorScheme.tertiaryContainer,
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: children,
),
),
),
),
);
}
}

72
lib/ui/themes.dart Normal file
View File

@ -0,0 +1,72 @@
import 'package:flutter/material.dart';
import 'package:openlib/ui/extensions.dart';
import 'package:google_fonts/google_fonts.dart';
ThemeData lightTheme = ThemeData(
primaryColor: Colors.white,
colorScheme: ColorScheme.light(
primary: Colors.white,
secondary: '#FB0101'.toColor(),
tertiary: Colors.black,
tertiaryContainer: '#F2F2F2'.toColor(),
),
textTheme: TextTheme(
displayLarge: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 21,
),
displayMedium: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.bold,
color: Colors.black,
overflow: TextOverflow.ellipsis,
),
headlineMedium: TextStyle(
color: "#595E60".toColor(),
),
headlineSmall: TextStyle(
color: "#7F7F7F".toColor(),
)),
fontFamily: GoogleFonts.nunito().fontFamily,
useMaterial3: true,
textSelectionTheme: TextSelectionThemeData(
selectionColor: '#FB0101'.toColor(),
selectionHandleColor: '#FB0101'.toColor(),
),
);
ThemeData darkTheme = ThemeData(
primaryColor: Colors.black,
colorScheme: ColorScheme.dark(
primary: Colors.black,
secondary: '#FB0101'.toColor(),
tertiary: Colors.white,
tertiaryContainer: '#2B2B2B'.toColor(),
),
textTheme: TextTheme(
displayLarge: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 21,
),
displayMedium: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.bold,
color: Colors.white,
overflow: TextOverflow.ellipsis,
),
headlineMedium: TextStyle(
color: "#F5F5F5".toColor(),
),
headlineSmall: TextStyle(
color: "#E8E2E2".toColor(),
),
),
fontFamily: GoogleFonts.nunito().fontFamily,
useMaterial3: true,
textSelectionTheme: TextSelectionThemeData(
selectionColor: '#FB0101'.toColor(),
selectionHandleColor: '#FB0101'.toColor(),
),
);

View File

@ -21,6 +21,7 @@ class TrendingPage extends ConsumerWidget {
return Padding(
padding: const EdgeInsets.only(left: 5, right: 5, top: 10),
child: CustomScrollView(
physics: const BouncingScrollPhysics(),
slivers: [
const SliverToBoxAdapter(
child: TitleText("Trending"),
@ -45,10 +46,9 @@ class TrendingPage extends ConsumerWidget {
);
}));
},
child: Container(
child: SizedBox(
width: double.infinity,
height: double.infinity,
color: const Color.fromARGB(255, 255, 255, 255),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,

View File

@ -5,10 +5,10 @@ packages:
dependency: transitive
description:
name: archive
sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a"
sha256: "49b1fad315e57ab0bbc15bcbb874e83116a1d78f77ebd500a4af6c9407d6b28e"
url: "https://pub.dev"
source: hosted
version: "3.3.7"
version: "3.3.8"
args:
dependency: transitive
description:
@ -93,10 +93,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
version: "1.17.1"
version: "1.17.2"
convert:
dependency: transitive
description:
@ -125,10 +125,10 @@ packages:
dependency: "direct main"
description:
name: cupertino_icons
sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
url: "https://pub.dev"
source: hosted
version: "1.0.5"
version: "1.0.6"
dev:
dependency: "direct main"
description:
@ -141,10 +141,10 @@ packages:
dependency: "direct main"
description:
name: dio
sha256: "3866d67f93523161b643187af65f5ac08bc991a5bcdaf41a2d587fe4ccb49993"
sha256: ce75a1b40947fea0a0e16ce73337122a86762e38b982e1ccb909daa3b9bc4197
url: "https://pub.dev"
source: hosted
version: "5.3.0"
version: "5.3.2"
epub_view:
dependency: "direct main"
description:
@ -181,10 +181,10 @@ packages:
dependency: transitive
description:
name: ffi
sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
url: "https://pub.dev"
source: hosted
version: "2.0.2"
version: "2.1.0"
file:
dependency: transitive
description:
@ -234,10 +234,10 @@ packages:
dependency: "direct dev"
description:
name: flutter_lints
sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4"
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
url: "https://pub.dev"
source: hosted
version: "2.0.2"
version: "2.0.3"
flutter_pdfview:
dependency: "direct main"
description:
@ -250,10 +250,10 @@ packages:
dependency: "direct main"
description:
name: flutter_riverpod
sha256: b83ac5827baadefd331ea1d85110f34645827ea234ccabf53a655f41901a9bf4
sha256: b04d4e9435a563673746ccb328d22018c6c9496bb547e11dd56c1b0cc9829fe5
url: "https://pub.dev"
source: hosted
version: "2.3.6"
version: "2.3.10"
flutter_svg:
dependency: "direct main"
description:
@ -364,18 +364,18 @@ packages:
dependency: transitive
description:
name: matcher
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.15"
version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.2.0"
version: "0.5.0"
meta:
dependency: transitive
description:
@ -392,6 +392,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.2"
open_file:
dependency: "direct main"
description:
name: open_file
sha256: a5a32d44acb7c899987d0999e1e3cbb0a0f1adebbf41ac813ec6d2d8faa0af20
url: "https://pub.dev"
source: hosted
version: "3.3.2"
path:
dependency: transitive
description:
@ -412,50 +420,90 @@ packages:
dependency: "direct main"
description:
name: path_provider
sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2"
sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
url: "https://pub.dev"
source: hosted
version: "2.0.15"
version: "2.1.1"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86"
sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1"
url: "https://pub.dev"
source: hosted
version: "2.0.27"
version: "2.2.0"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "916731ccbdce44d545414dd9961f26ba5fbaa74bcbb55237d8e65a623a8c7297"
sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
url: "https://pub.dev"
source: hosted
version: "2.2.4"
version: "2.3.1"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev"
source: hosted
version: "2.1.11"
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec"
sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
url: "https://pub.dev"
source: hosted
version: "2.0.6"
version: "2.1.1"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96"
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
url: "https://pub.dev"
source: hosted
version: "2.1.7"
version: "2.2.1"
permission_handler:
dependency: "direct main"
description:
name: permission_handler
sha256: "63e5216aae014a72fe9579ccd027323395ce7a98271d9defa9d57320d001af81"
url: "https://pub.dev"
source: hosted
version: "10.4.3"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
sha256: d74e77a5ecd38649905db0a7d05ef16bed42ff263b9efb73ed794317c5764ec3
url: "https://pub.dev"
source: hosted
version: "10.3.4"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5"
url: "https://pub.dev"
source: hosted
version: "9.1.4"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
sha256: "7c6b1500385dd1d2ca61bb89e2488ca178e274a69144d26bbd65e33eae7c02a9"
url: "https://pub.dev"
source: hosted
version: "3.11.3"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098
url: "https://pub.dev"
source: hosted
version: "0.1.3"
petitparser:
dependency: transitive
description:
@ -468,18 +516,18 @@ packages:
dependency: transitive
description:
name: platform
sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102
url: "https://pub.dev"
source: hosted
version: "3.1.0"
version: "3.1.2"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc"
sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
url: "https://pub.dev"
source: hosted
version: "2.1.4"
version: "2.1.6"
pointycastle:
dependency: transitive
description:
@ -500,10 +548,10 @@ packages:
dependency: transitive
description:
name: riverpod
sha256: "80e48bebc83010d5e67a11c9514af6b44bbac1ec77b4333c8ea65dbc79e2d8ef"
sha256: "6c0a2c30c04206ac05494bcccd8148b76866e1a9248a5a8c84ca7b16fbcb3f6a"
url: "https://pub.dev"
source: hosted
version: "2.3.6"
version: "2.3.10"
rxdart:
dependency: transitive
description:
@ -529,10 +577,18 @@ packages:
dependency: transitive
description:
name: source_span
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
sprintf:
dependency: transitive
description:
name: sprintf
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
sqflite:
dependency: "direct main"
description:
@ -577,10 +633,10 @@ packages:
dependency: transitive
description:
name: state_notifier
sha256: "8fe42610f179b843b12371e40db58c9444f8757f8b69d181c97e50787caed289"
sha256: b8677376aa54f2d7c58280d5a007f9e8774f1968d1fb1c096adcb4792fba29bb
url: "https://pub.dev"
source: hosted
version: "0.7.2+1"
version: "1.0.0"
stream_channel:
dependency: transitive
description:
@ -617,10 +673,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
version: "0.5.1"
version: "0.6.0"
typed_data:
dependency: transitive
description:
@ -641,74 +697,74 @@ packages:
dependency: "direct main"
description:
name: url_launcher
sha256: "781bd58a1eb16069412365c98597726cd8810ae27435f04b3b4d3a470bacd61e"
sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27"
url: "https://pub.dev"
source: hosted
version: "6.1.12"
version: "6.1.14"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: "3dd2388cc0c42912eee04434531a26a82512b9cb1827e0214430c9bcbddfe025"
sha256: b04af59516ab45762b2ca6da40fa830d72d0f6045cd97744450b73493fa76330
url: "https://pub.dev"
source: hosted
version: "6.0.38"
version: "6.1.0"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2"
sha256: "7c65021d5dee51813d652357bc65b8dd4a6177082a9966bc8ba6ee477baa795f"
url: "https://pub.dev"
source: hosted
version: "6.1.4"
version: "6.1.5"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5"
sha256: b651aad005e0cb06a01dbd84b428a301916dc75f0e7ea6165f80057fee2d8e8e
url: "https://pub.dev"
source: hosted
version: "3.0.5"
version: "3.0.6"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: "1c4fdc0bfea61a70792ce97157e5cc17260f61abbe4f39354513f39ec6fd73b1"
sha256: b55486791f666e62e0e8ff825e58a023fd6b1f71c49926483f1128d3bbd8fe88
url: "https://pub.dev"
source: hosted
version: "3.0.6"
version: "3.0.7"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: bfdfa402f1f3298637d71ca8ecfe840b4696698213d5346e9d12d4ab647ee2ea
sha256: "95465b39f83bfe95fcb9d174829d6476216f2d548b79c38ab2506e0458787618"
url: "https://pub.dev"
source: hosted
version: "2.1.3"
version: "2.1.5"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: cc26720eefe98c1b71d85f9dc7ef0cada5132617046369d9dc296b3ecaa5cbb4
sha256: "2942294a500b4fa0b918685aff406773ba0a4cd34b7f42198742a94083020ce5"
url: "https://pub.dev"
source: hosted
version: "2.0.18"
version: "2.0.20"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "7967065dd2b5fccc18c653b97958fdf839c5478c28e767c61ee879f4e7882422"
sha256: "95fef3129dc7cfaba2bc3d5ba2e16063bb561fc6d78e63eee16162bc70029069"
url: "https://pub.dev"
source: hosted
version: "3.0.7"
version: "3.0.8"
uuid:
dependency: transitive
description:
name: uuid
sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
sha256: e03928880bdbcbf496fb415573f5ab7b1ea99b9b04f669c01104d085893c3134
url: "https://pub.dev"
source: hosted
version: "3.0.7"
version: "4.0.0"
vector_graphics:
dependency: transitive
description:
@ -741,22 +797,38 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
vocsy_epub_viewer:
dependency: "direct main"
description:
name: vocsy_epub_viewer
sha256: "30aab4a5be22e8c98f22fed3345f6989caaca861178c38cab2a8b8cd66ad53de"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
web:
dependency: transitive
description:
name: web
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
url: "https://pub.dev"
source: hosted
version: "0.1.4-beta"
win32:
dependency: transitive
description:
name: win32
sha256: dfdf0136e0aa7a1b474ea133e67cb0154a0acd2599c4f3ada3b49d38d38793ee
sha256: "9e82a402b7f3d518fb9c02d0e9ae45952df31b9bf34d77baf19da2de03fc2aaa"
url: "https://pub.dev"
source: hosted
version: "5.0.5"
version: "5.0.7"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: e0b1147eec179d3911f1f19b59206448f78195ca1d20514134e10641b7d7fbff
sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2"
url: "https://pub.dev"
source: hosted
version: "1.0.1"
version: "1.0.3"
xml:
dependency: transitive
description:
@ -774,5 +846,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.0.5 <4.0.0"
flutter: ">=3.10.0"
dart: ">=3.1.0 <4.0.0"
flutter: ">=3.13.0"

View File

@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1
version: 1.0.1+1
environment:
sdk: '>=3.0.5 <4.0.0'
@ -36,6 +36,7 @@ dependencies:
epub_view: ^3.2.0
flutter_pdfview: ^1.2.7
vocsy_epub_viewer: ^2.0.0
# syncfusion_flutter_pdfviewer: ^22.2.5
# pdfx: ^2.4.0
@ -44,6 +45,8 @@ dependencies:
sqflite: ^2.3.0
path_provider: ^2.0.15
permission_handler: ^10.4.3
open_file: ^3.3.2
flutter_svg: ^2.0.7
google_fonts: ^5.1.0

View File

@ -6,9 +6,12 @@
#include "generated_plugin_registrant.h"
#include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
}

View File

@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
permission_handler_windows
url_launcher_windows
)