Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #20

Merged
merged 10 commits into from
Apr 9, 2024
Merged

Dev #20

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ flutter {

dependencies {
// flutter_local_notifications plugin requires desugaring
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.2'

// Desugaring causes crashes on Android 12+, adding these `window`
// dependencies fixes the issue until it is resolved in Flutter.
Expand Down
25 changes: 25 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,30 @@
<meta-data
android:name="flutterEmbedding"
android:value="2" />

<!-- Required to show scheduled notifications. -->
<receiver android:exported="false"
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
<receiver android:exported="false"
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
<!-- /end Required to show scheduled notifications. -->

<!-- Required to handle the result of an action on a notification. -->
<receiver android:exported="false"
android:name="com.dexterous.flutterlocalnotifications.ActionBroadcastReceiver" />
</application>

<!-- Required to know when the device is rebooted. This is required to be
able to reschedule notifications upon a reboot. -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<!-- Required to schedule exact alarms. -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
</manifest>
13 changes: 0 additions & 13 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

allprojects {
repositories {
google()
Expand Down
19 changes: 12 additions & 7 deletions android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@ pluginManagement {
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}
settings.ext.flutterSdkPath = flutterSdkPath()
}()

includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

plugins {
id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}

include ":app"
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.1" apply false
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
}

apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle"
include ":app"
5 changes: 2 additions & 3 deletions lib/src/autostart/autostart_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'package:launch_at_startup/launch_at_startup.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:xdg_desktop_portal/xdg_desktop_portal.dart';

import '../core/helpers/helpers.dart';
import '../logs/logging_manager.dart';

/// Service to enable/disable autostart on desktop platforms.
Expand All @@ -15,7 +14,7 @@ class AutostartService {
Future<void> disable() async {
assert(defaultTargetPlatform.isDesktop);

if (runningInFlatpak) {
if (runningInFlatpak()) {
await _setForFlatpak(false);
} else {
await _disableForDesktop();
Expand All @@ -26,7 +25,7 @@ class AutostartService {
Future<void> enable() async {
assert(defaultTargetPlatform.isDesktop);

if (runningInFlatpak) {
if (runningInFlatpak()) {
await _setForFlatpak(true);
} else {
await _enableForDesktop();
Expand Down
37 changes: 37 additions & 0 deletions lib/src/core/constants.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import 'package:flutter/foundation.dart';
import 'package:helpers/helpers.dart';

const String kDonateUrl = 'https://merritt.codes/support/';
const String kPackageId = 'codes.merritt.adventurelist';
const String kRepoUrl = 'https://github.com/Merrit/adventure_list';
Expand Down Expand Up @@ -35,4 +38,38 @@ abstract class AppIcons {
/// Symbolic icon with a red dot indicating a notification, as an ICO.
static const String windowsSymbolicWithNotificationBadge =
'$path/$kPackageId-symbolic-with-notification-badge.ico';

/// Returns the appropriate icon path (or icon name) based on the current platform.
static String platformSpecific({
required bool symbolic,
bool withNotificationBadge = false,
}) {
if (runningInFlatpak() || runningInSnap()) {
// When running in a sandboxed environment the icon must be specified by
// the icon's name, not the path.
return kPackageId;
}

return defaultTargetPlatform.isWindows
? getWindowsIcon(symbolic, withNotificationBadge)
: getLinuxIcon(symbolic, withNotificationBadge);
}

static String getWindowsIcon(bool symbolic, bool withNotificationBadge) {
if (symbolic) {
return withNotificationBadge
? windowsSymbolicWithNotificationBadge
: windowsSymbolic;
} else {
return withNotificationBadge ? windowsWithNotificationBadge : windows;
}
}

static String getLinuxIcon(bool symbolic, bool withNotificationBadge) {
if (symbolic) {
return withNotificationBadge ? linuxSymbolicWithNotificationBadge : linuxSymbolic;
} else {
return withNotificationBadge ? linuxWithNotificationBadge : linux;
}
}
}
4 changes: 0 additions & 4 deletions lib/src/core/helpers/flatpak.dart

This file was deleted.

1 change: 0 additions & 1 deletion lib/src/core/helpers/helpers.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export 'date_time.dart';
export 'error_handler.dart';
export 'flatpak.dart';
66 changes: 49 additions & 17 deletions lib/src/notifications/cubit/notifications_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ class NotificationsCubit extends Cubit<NotificationsState> {
return;
}

if (!state.permissionGranted) {
if (!state.notificationPermissionGranted) {
await _requestPermission();
if (!state.permissionGranted) {
if (!state.notificationPermissionGranted) {
log.t(
'Notifications permission not granted. Not scheduling notification.',
);
Expand Down Expand Up @@ -213,9 +213,9 @@ class NotificationsCubit extends Cubit<NotificationsState> {
return;
}

if (!state.permissionGranted) {
if (!state.notificationPermissionGranted) {
await _requestPermission();
if (!state.permissionGranted) {
if (!state.notificationPermissionGranted) {
log.t(
'Notifications permission not granted. Not showing notification.',
);
Expand Down Expand Up @@ -287,7 +287,7 @@ class NotificationsCubit extends Cubit<NotificationsState> {
Future<void> _requestPermission() async {
// Currently only Android requires permission.
if (defaultTargetPlatform != TargetPlatform.android) {
emit(state.copyWith(permissionGranted: true));
emit(state.copyWith(notificationPermissionGranted: true));
return;
}

Expand All @@ -297,16 +297,38 @@ class NotificationsCubit extends Cubit<NotificationsState> {

if (androidPlugin == null) return;

final bool? permissionGranted = await androidPlugin.requestPermission();
if (permissionGranted == null) return;
// final bool? notificationsPermissionGranted =
// await androidPlugin.requestNotificationsPermission();
// if (notificationsPermissionGranted == null) return;

if (permissionGranted) {
// if (notificationsPermissionGranted) {
// log.i('Notifications permission granted');
// } else {
// log.i('Notifications permission denied');
// }

// emit(state.copyWith(permissionGranted: notificationsPermissionGranted));

final bool notificationsPermissionGranted =
await androidPlugin.requestNotificationsPermission() ?? false;
final bool exactNotificationsPermissionGranted =
await androidPlugin.requestExactAlarmsPermission() ?? false;

if (notificationsPermissionGranted) {
log.i('Notifications permission granted');
} else {
log.i('Notifications permission denied');
}

emit(state.copyWith(permissionGranted: permissionGranted));
if (exactNotificationsPermissionGranted) {
log.i('Exact notifications permission granted');
} else {
log.i('Exact notifications permission denied');
}

emit(state.copyWith(
notificationPermissionGranted: notificationsPermissionGranted,
));
}

/// Schedule a notification on desktop.
Expand Down Expand Up @@ -515,11 +537,16 @@ class NotificationsCubit extends Cubit<NotificationsState> {

/// Set the notification badge on the Linux system tray.
Future<void> _setNotificationBadgeLinuxSystemTray(int count) async {
final icon = (count > 0)
? AppIcons.linuxSymbolicWithNotificationBadge
: AppIcons.linuxSymbolic;
// TODO: This is now identical to the Windows method. Refactor to share code.

final bool withNotificationBadge = count > 0;

final String iconPath = AppIcons.platformSpecific(
symbolic: true,
withNotificationBadge: withNotificationBadge,
);

await SystemTrayManager.instance.setIcon(icon);
await SystemTrayManager.instance.setIcon(iconPath);
}

/// Set the notification badge on Windows.
Expand All @@ -538,11 +565,16 @@ class NotificationsCubit extends Cubit<NotificationsState> {

/// Set the notification badge on the Windows system tray.
Future<void> _setNotificationBadgeWindowsSystemTray(int count) async {
final icon = (count > 0)
? AppIcons.windowsSymbolicWithNotificationBadge
: AppIcons.windowsSymbolic;
// TODO: This is now identical to the Linux method. Refactor to share code.

final bool withNotificationBadge = count > 0;

final String iconPath = AppIcons.platformSpecific(
symbolic: true,
withNotificationBadge: withNotificationBadge,
);

await SystemTrayManager.instance.setIcon(icon);
await SystemTrayManager.instance.setIcon(iconPath);
}
}

Expand Down
10 changes: 8 additions & 2 deletions lib/src/notifications/cubit/notifications_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,24 @@ class NotificationsState with _$NotificationsState {
required bool enabled,
NotificationResponse? notificationResponse,

/// Whether the app has permission to show exact notifications.
required bool notificationExactPermissionGranted,

/// Whether the app has permission to show notifications.
required bool notificationPermissionGranted,

/// The number of overdue tasks.
///
/// Tracked so we don't update the icons if the number hasn't changed.
required int overdueTasksCount,
required bool permissionGranted,
}) = _NotificationsState;

factory NotificationsState.initial() {
return const NotificationsState(
enabled: true,
notificationExactPermissionGranted: false,
notificationPermissionGranted: false,
overdueTasksCount: 0,
permissionGranted: false,
);
}
}
3 changes: 1 addition & 2 deletions lib/src/settings/widgets/settings_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import '../../app/cubit/app_cubit.dart';
import '../../authentication/cubit/authentication_cubit.dart';
import '../../authentication/sign_in_page.dart';
import '../../core/core.dart';
import '../../core/helpers/helpers.dart';
import '../../home_widget/home_widget.dart';
import '../../logs/logging_manager.dart';
import '../../theme/theme.dart';
Expand Down Expand Up @@ -348,7 +347,7 @@ class _CurrentVersionTile extends StatelessWidget {
args: [state.runningVersion],
);

if (runningInFlatpak) {
if (runningInFlatpak()) {
text += ' (Flatpak)';
}

Expand Down
9 changes: 6 additions & 3 deletions lib/src/system_tray/system_tray_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart';
import 'package:tray_manager/tray_manager.dart';

import '../core/core.dart';
import '../logs/logging_manager.dart';
import '../window/window.dart';

/// Manages the system tray icon.
Expand All @@ -16,9 +17,10 @@ class SystemTrayManager {
}

Future<void> initialize() async {
final String iconPath = (defaultTargetPlatform.isWindows) //
? AppIcons.windowsSymbolic
: AppIcons.linuxSymbolic;
final String iconPath = AppIcons.platformSpecific(
symbolic: true,
withNotificationBadge: false,
);

await trayManager.setIcon(iconPath);

Expand All @@ -36,6 +38,7 @@ class SystemTrayManager {

/// Sets the system tray icon.
Future<void> setIcon(String iconPath) async {
log.t('Setting system tray icon to $iconPath');
await trayManager.setIcon(iconPath);
}

Expand Down
Loading
Loading