Skip to content

Commit

Permalink
feat: app links now work only on /g/
Browse files Browse the repository at this point in the history
  • Loading branch information
LacticWhale committed Nov 30, 2022
1 parent 6450c5d commit ce06077
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 199 deletions.
8 changes: 6 additions & 2 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,12 @@
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data android:scheme="http" android:host="nhentai.net" />
<data android:scheme="https" android:host="nhentai.net" />
<data android:scheme="http"
android:host="nhentai.net"
android:pathPrefix="/g/" />
<data android:scheme="https"
android:host="nhentai.net"
android:pathPrefix="/g/" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
Expand Down
5 changes: 5 additions & 0 deletions lib/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ class HttpClientWithCookies with HttpClientMixin implements HttpClient {
return cachedCookie = cfClearance.first;
}

Future<void> clearCookies() async {
cachedCookie = null;
return cookieManager.clearCookies();
}

@override
Future<HttpClientRequest> getUrl(Uri url) async {
final request = await super.openUrl('GET', url);
Expand Down
238 changes: 96 additions & 142 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import 'dart:async';
import 'dart:io';

import 'package:app_links/app_links.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_settings_screens/flutter_settings_screens.dart';
import 'package:nhentai/data_model.dart';
import 'package:uni_links/uni_links.dart';

import 'api.dart';
import 'prefs.dart';
import 'screen/pages/book.dart';
import 'screen/pages/home.dart';
import 'widgets/tag_block.dart';
import 'screen/webview/nhentai.net.dart';

Storage storage = Storage();
Preferences preferences = Preferences(storage: storage);
Expand All @@ -26,50 +26,34 @@ void main() async {
DeviceOrientation.portraitDown,
]);

runApp(const MyApp());
runApp(
MaterialApp(
title: 'NhentaiApp',
darkTheme: ThemeData(
colorScheme: const ColorScheme(
brightness: Brightness.dark,
primary: Colors.pink,
background: Color.fromARGB(0xff, 0x1f, 0x1f, 0x1f),
onPrimary: Colors.black,
secondary: Colors.white,
onSecondary: Colors.black,
error: Colors.red,
onError: Colors.black,
onBackground: Colors.black,
surface: Colors.pink,
surfaceVariant: Color.fromARGB(0xff, 0x1f, 0x1f, 0x1f),
onSurface: Colors.black,
),
),
home: const MyApp(),
),
);
}

// class MyApp extends StatelessWidget {
// const MyApp({super.key});

// static final String userAgent = 'nhentai_app/1.0.0+dev.3 ${Platform.operatingSystem}';

// static Map<String, String> get headers => {
// 'set-cookies': (api.client as HttpClientWithCookies).cachedCookie.toString(),
// 'User-Agent': MyApp.userAgent,
// };

// @override
// Widget build(BuildContext context) => MaterialApp(
// title: 'Flutter Demo',
// darkTheme: ThemeData(
// colorScheme: const ColorScheme(
// brightness: Brightness.dark,
// primary: Colors.pink,
// background: Color.fromARGB(0xff, 0x1f, 0x1f, 0x1f),
// onPrimary: Colors.black,
// secondary: Colors.white,
// onSecondary: Colors.black,
// error: Colors.red,
// onError: Colors.black,
// onBackground: Colors.black,
// surface: Colors.pink,
// surfaceVariant: Color.fromARGB(0xff, 0x1f, 0x1f, 0x1f),
// onSurface: Colors.black,
// ),
// ),
// home: HomePage(
// includedTags: storage.selectedTagsBox.values
// .where((tag) => tag.state == TagState.included),
// excludedTags: storage.selectedTagsBox.values
// .where((tag) => tag.state == TagState.excluded),
// ),
// );
// }
class MyApp extends StatefulWidget {
const MyApp({super.key});

static final String userAgent = 'nhentai_app/1.0.0+dev.3 ${Platform.operatingSystem}';
static final String userAgent = 'nhentai_app/1.0.1 ${Platform.operatingSystem}';

static Map<String, String> get headers => {
'set-cookies': (api.client as HttpClientWithCookies).cachedCookie.toString(),
Expand All @@ -81,111 +65,88 @@ class MyApp extends StatefulWidget {
}

class _MyAppState extends State<MyApp> {
final _navigatorKey = GlobalKey<NavigatorState>();
late AppLinks _appLinks;
StreamSubscription<Uri>? _linkSubscription;
String? _initialPath;

@override
void initState() {
super.initState();

initDeepLinks();
}

@override
void dispose() {
_linkSubscription?.cancel();

super.dispose();
// ignore: discarded_futures
initUniLinks();
}

Future<void> initDeepLinks() async {
_appLinks = AppLinks();

final appLink = await _appLinks.getInitialAppLink();
if (appLink != null) {
if (kDebugMode) {
print('getInitialAppLink: $appLink');
}
openAppLink(appLink);
Future<void> initUniLinks() async {
try {
_initialPath = Uri.tryParse(await getInitialLink() ?? '/')?.path ?? '/';
} on PlatformException {
_initialPath = '/';
}

_linkSubscription = _appLinks.uriLinkStream.listen((uri) {
if (kDebugMode) {
print('onAppLink: $uri');
}
openAppLink(uri);
});
}

Future<void> openAppLink(Uri uri) async {
if(kDebugMode) {
print(_navigatorKey.currentState);
print(uri.path);
}
_navigatorKey.currentState?.pushNamed(uri.path);
setState(() { });
}

@override
Widget build(BuildContext context) => MaterialApp(
title: 'NhentaiApp',
darkTheme: ThemeData(
colorScheme: const ColorScheme(
brightness: Brightness.dark,
primary: Colors.pink,
background: Color.fromARGB(0xff, 0x1f, 0x1f, 0x1f),
onPrimary: Colors.black,
secondary: Colors.white,
onSecondary: Colors.black,
error: Colors.red,
onError: Colors.black,
onBackground: Colors.black,
surface: Colors.pink,
surfaceVariant: Color.fromARGB(0xff, 0x1f, 0x1f, 0x1f),
onSurface: Colors.black,
Widget build(BuildContext context) {
if(_initialPath == null)
return const Material(
child: Center(
child: CircularProgressIndicator(),
),
),
navigatorKey: _navigatorKey,
initialRoute: '/',
onGenerateRoute: (settings) {
final routeName = settings.name;
if(kDebugMode)
print('Route: $routeName $settings');
if (routeName != null) {
if (routeName.startsWith('/g/')) {
if(kDebugMode)
print('loading book');
return MaterialPageRoute(
builder: (context) => LoadBook(id: int.tryParse(routeName.substring(3)) ?? -1),
);
}

return MaterialPageRoute(
builder: (context) => const HomePage(),
settings: settings,
);
}
},
);
);
else if(_initialPath!.startsWith('/g/')) {
final id = int.tryParse(_initialPath!.substring(_initialPath!.indexOf('/g/') + 3));
if(id == null)
return Material(
child: Center(
child: Text(_initialPath ?? ''),
),
);
return LoadBook(
id: id,
);
} else if(_initialPath == '/') {
return const HomePage();
} else
return Material(
child: Center(
child: Text(_initialPath ?? ''),
),
);
}
}

class LoadBook extends StatelessWidget {
class LoadBook extends StatefulWidget {
const LoadBook({
required this.id,
super.key,
super.key,
});

final int id;

@override
State<StatefulWidget> createState() => LoadBookState();

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(IntProperty('id', id));
}

}

class LoadBookState extends State<LoadBook> {
@override
Widget build(BuildContext context) => FutureBuilder<Book?>(
future: getBook(id),
// ignore: discarded_futures
future: getBook(widget.id),
builder: (context, snapshot) {
if(kDebugMode)
print(id);
print(widget.id);
if(snapshot.connectionState != ConnectionState.done)
return const Material(child: SafeArea(child: Center(child: CircularProgressIndicator(),)),);
else if(snapshot.data == null) {
else if(snapshot.data != null)
return BookPage(book: snapshot.data!);
else
return Material(
child: SafeArea(
child: Scaffold(
Expand All @@ -197,39 +158,32 @@ class LoadBook extends StatelessWidget {
),
],
),
body: Center(child: Text('Book $id not found.')),
body: Center(child: Text('Book ${widget.id} not found.')),
floatingActionButton: Card(
child: TextButton(
child: const Text('Update cookies.'),
onPressed: () async {
(api.client as HttpClientWithCookies)
.cookieManager
.clearCookies()
.then((value) {
Navigator.pushReplacement(
context,
MaterialPageRoute<void>(
builder: (context) => LoadBook(id: id,),
),
);
});
},
onPressed: () async => (api.client as HttpClientWithCookies)
.clearCookies()
.then((value) => Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => const NHentaiWebView(),
),
),).then((value) async => Navigator.pushReplacement(
context,
MaterialPageRoute<void>(
builder: (context) => LoadBook(id: widget.id),
),
),
),
),
),
),
),
);
}
else
return BookPage(book: snapshot.data!);
},
);

Future<Book?> getBook(int id) async => id == -1 ? null : api.getBook(id);
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(IntProperty('id', id));
}
Future<Book?> getBook(int id) async => id == -1 ? null : api.getBook(id);

}
Loading

0 comments on commit ce06077

Please sign in to comment.