parent
42423f50ec
commit
43702e5ba0
|
@ -141,6 +141,11 @@ class APIRequestBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
APIRequestBuilder withIds(List<int> ids) {
|
||||||
|
_addArg('with_ids=${ids.join(',')}');
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/// Executes the API request and returns the JSON data
|
/// Executes the API request and returns the JSON data
|
||||||
Future<Map<String, dynamic>> fetch() async {
|
Future<Map<String, dynamic>> fetch() async {
|
||||||
if (api.apiKey == null || api.apiUrl == null) {
|
if (api.apiKey == null || api.apiUrl == null) {
|
||||||
|
|
|
@ -16,13 +16,16 @@ import 'api/api.dart';
|
||||||
// fetching a large list
|
// fetching a large list
|
||||||
const FETCH_MAX_POSTS = 1000;
|
const FETCH_MAX_POSTS = 1000;
|
||||||
|
|
||||||
|
// Store these globally so our notification handler can access them
|
||||||
|
BuildContext? globalContext;
|
||||||
|
final api = FeverAPI();
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
setupBackgroundTasks();
|
setupBackgroundTasks();
|
||||||
runApp(MyApp());
|
runApp(MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatelessWidget {
|
||||||
final api = FeverAPI();
|
|
||||||
SharedPreferences? prefs;
|
SharedPreferences? prefs;
|
||||||
|
|
||||||
MyApp({super.key});
|
MyApp({super.key});
|
||||||
|
@ -60,6 +63,7 @@ class MyApp extends StatelessWidget {
|
||||||
themeMode: ThemeMode.system,
|
themeMode: ThemeMode.system,
|
||||||
home: FutureBuilder<bool>(
|
home: FutureBuilder<bool>(
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
|
globalContext = context;
|
||||||
if (snapshot.hasData && prefs != null) {
|
if (snapshot.hasData && prefs != null) {
|
||||||
return MyHomePage(title: 'Feet', api: api, prefs: prefs!);
|
return MyHomePage(title: 'Feet', api: api, prefs: prefs!);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:feet/api/api.dart';
|
import 'package:feet/api/api.dart';
|
||||||
|
import 'package:feet/main.dart';
|
||||||
|
import 'package:feet/pages/article.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
|
@ -79,9 +81,11 @@ void callbackDispatcher() {
|
||||||
}
|
}
|
||||||
|
|
||||||
await FlutterLocalNotificationsPlugin().show(
|
await FlutterLocalNotificationsPlugin().show(
|
||||||
Random().nextInt(10000000), // Can't use the post ID here because FreshRSS's IDs are too large
|
Random().nextInt(
|
||||||
|
10000000), // Can't use the post ID here because FreshRSS's IDs are too large
|
||||||
feed != null ? 'New post - ${feed.title}' : 'New post',
|
feed != null ? 'New post - ${feed.title}' : 'New post',
|
||||||
item.title,
|
item.title,
|
||||||
|
payload: 'item/${item.id}',
|
||||||
NotificationDetails(
|
NotificationDetails(
|
||||||
android: AndroidNotificationDetails(
|
android: AndroidNotificationDetails(
|
||||||
'new_posts',
|
'new_posts',
|
||||||
|
@ -117,6 +121,35 @@ void setupBackgroundTasks() async {
|
||||||
|
|
||||||
await Permission.notification.request();
|
await Permission.notification.request();
|
||||||
|
|
||||||
|
await FlutterLocalNotificationsPlugin().initialize(
|
||||||
|
const InitializationSettings(
|
||||||
|
android: AndroidInitializationSettings('@mipmap/ic_launcher'),
|
||||||
|
),
|
||||||
|
onSelectNotification: handleNotificationClick,
|
||||||
|
);
|
||||||
|
|
||||||
|
var launchDetails =
|
||||||
|
await FlutterLocalNotificationsPlugin().getNotificationAppLaunchDetails();
|
||||||
|
|
||||||
|
if (launchDetails?.payload != null && launchDetails!.payload!.isNotEmpty) {
|
||||||
|
handleNotificationClick(launchDetails.payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test notification
|
||||||
|
//if (kDebugMode) {
|
||||||
|
// await FlutterLocalNotificationsPlugin().show(
|
||||||
|
// Random().nextInt(1000000),
|
||||||
|
// "Test Notification",
|
||||||
|
// "Test Notification Body",
|
||||||
|
// const NotificationDetails(
|
||||||
|
// android: AndroidNotificationDetails(
|
||||||
|
// 'new_posts',
|
||||||
|
// 'New posts',
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// payload: "item/1675609277381551");
|
||||||
|
//}
|
||||||
|
|
||||||
// Runs every 15 minutes
|
// Runs every 15 minutes
|
||||||
await Workmanager().registerPeriodicTask(
|
await Workmanager().registerPeriodicTask(
|
||||||
'fetch_notifications',
|
'fetch_notifications',
|
||||||
|
@ -125,3 +158,47 @@ void setupBackgroundTasks() async {
|
||||||
initialDelay: const Duration(seconds: 60),
|
initialDelay: const Duration(seconds: 60),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> handleNotificationClick(String? payload) async {
|
||||||
|
print("Notification click: $payload");
|
||||||
|
if (globalContext == null) {
|
||||||
|
print("Global context not available.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (payload == null) {
|
||||||
|
print("Didn't receive a payload");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (payload.startsWith('item/')) {
|
||||||
|
if (!api.loggedIn()) {
|
||||||
|
print("API client is not logged in");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var id = toInt(payload.split('/')[1]);
|
||||||
|
var item = api.cache.items.get(id);
|
||||||
|
if (item == null) {
|
||||||
|
var res = await api.request().withItems().withIds([id]).execute();
|
||||||
|
item = api.cache.items.get(id);
|
||||||
|
if (item == null) throw 'Didn\'t receive item $id from API: $res';
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigator.of(globalContext!).push(
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => ArticlePage(article: item!),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!item.isRead) {
|
||||||
|
await api
|
||||||
|
.request()
|
||||||
|
.markItem(item, ItemMarkType.read)
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print("Error while handling notification click: $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue