From 3ced42c15f53ac99e3c82d0000276804b84e12bf Mon Sep 17 00:00:00 2001 From: Vincent Velociter Date: Fri, 2 Feb 2024 16:48:20 +0100 Subject: [PATCH] Update ios badge after receiving a data message --- ios/Runner/AppDelegate.swift | 21 ++++++++++++++++++++ lib/main.dart | 11 +++++++++++ lib/src/notification_service.dart | 11 +++++++++++ lib/src/utils/badge_service.dart | 32 +++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 lib/src/utils/badge_service.dart diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 70693e4a8c..a75879bf1a 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -7,6 +7,27 @@ import Flutter _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { + + let controller : FlutterViewController = window?.rootViewController as! FlutterViewController + let badgeChannel = FlutterMethodChannel(name: "mobile.lichess.org/badge", + binaryMessenger: controller.binaryMessenger) + + badgeChannel.setMethodCallHandler({ + (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in + guard call.method == "setBadge" else { + result(FlutterMethodNotImplemented) + return + } + + if let args = call.arguments as? Dictionary, + let badge = args["badge"] as? Int { + UIApplication.shared.applicationIconBadgeNumber = badge + result(nil) + } else { + result(FlutterError(code: "bad_args", message: "bad arguments", details: nil)) + } + }) + GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } diff --git a/lib/main.dart b/lib/main.dart index 4f03a2dd80..8662de4984 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -15,6 +15,7 @@ import 'package:lichess_mobile/src/model/common/id.dart'; import 'package:lichess_mobile/src/model/correspondence/correspondence_game_storage.dart'; import 'package:lichess_mobile/src/model/correspondence/offline_correspondence_game.dart'; import 'package:lichess_mobile/src/model/game/playable_game.dart'; +import 'package:lichess_mobile/src/utils/badge_service.dart'; import 'package:lichess_mobile/src/utils/layout.dart'; import 'package:path/path.dart' as path; import 'package:sqflite/sqflite.dart'; @@ -118,4 +119,14 @@ Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { conflictAlgorithm: ConflictAlgorithm.replace, ); } + + // update badge + final badge = message.data['lichess.iosBadge'] as String?; + if (badge != null) { + try { + badgeService.setBadge(int.parse(badge)); + } catch (e) { + debugPrint('Could not parse badge: $badge'); + } + } } diff --git a/lib/src/notification_service.dart b/lib/src/notification_service.dart index d32eb597f4..8739890a41 100644 --- a/lib/src/notification_service.dart +++ b/lib/src/notification_service.dart @@ -8,6 +8,7 @@ import 'package:lichess_mobile/src/model/auth/auth_session.dart'; import 'package:lichess_mobile/src/model/common/id.dart'; import 'package:lichess_mobile/src/model/correspondence/correspondence_service.dart'; import 'package:lichess_mobile/src/model/game/playable_game.dart'; +import 'package:lichess_mobile/src/utils/badge_service.dart'; import 'package:logging/logging.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; @@ -87,5 +88,15 @@ class NotificationService { } ref.read(correspondenceServiceProvider).updateGame(fullId, game); } + + // update badge + final badge = message.data['lichess.iosBadge'] as String?; + if (badge != null) { + try { + badgeService.setBadge(int.parse(badge)); + } catch (e) { + _log.severe('Could not parse badge: $badge'); + } + } } } diff --git a/lib/src/utils/badge_service.dart b/lib/src/utils/badge_service.dart new file mode 100644 index 0000000000..c30b049158 --- /dev/null +++ b/lib/src/utils/badge_service.dart @@ -0,0 +1,32 @@ +import 'dart:async'; + +import 'package:flutter/services.dart'; +import 'package:logging/logging.dart'; + +final badgeService = BadgeService(Logger('BadgeService')); + +class BadgeService { + static const _channel = MethodChannel('mobile.lichess.org/badge'); + + const BadgeService(this._log); + + final Logger _log; + + Future setBadge(int value) async { + try { + await _channel.invokeMethod('setBadge', { + 'badge': value, + }); + } on PlatformException catch (e) { + _log.severe(e); + } + } + + Future clearBadge() async { + try { + await _channel.invokeMethod('setBadge', 0); + } on PlatformException catch (e) { + _log.severe(e); + } + } +}