Skip to content

Commit

Permalink
only show apps that have notified before in notifying apps screen
Browse files Browse the repository at this point in the history
  • Loading branch information
crc-32 committed Jul 6, 2024
1 parent 18e20db commit 0dac866
Show file tree
Hide file tree
Showing 12 changed files with 420 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package io.rebble.cobble.bridges.common
import io.rebble.cobble.bridges.FlutterBridge
import io.rebble.cobble.bridges.ui.BridgeLifecycleController
import io.rebble.cobble.pigeons.Pigeons
import io.rebble.cobble.shared.database.dao.CachedPackageInfoDao
import io.rebble.libpebblecommon.packets.blobdb.PushNotification
import io.rebble.libpebblecommon.services.notification.NotificationService
import kotlinx.coroutines.CoroutineScope
Expand All @@ -12,7 +13,8 @@ import javax.inject.Inject
class NotificationsFlutterBridge @Inject constructor(
bridgeLifecycleController: BridgeLifecycleController,
private val notificationService: NotificationService,
private val coroutineScope: CoroutineScope
private val coroutineScope: CoroutineScope,
private val cachedPackageInfoDao: CachedPackageInfoDao,
) : FlutterBridge, Pigeons.NotificationsControl {
init {
bridgeLifecycleController.setupControl(Pigeons.NotificationsControl::setup, this)
Expand All @@ -26,4 +28,17 @@ class NotificationsFlutterBridge @Inject constructor(
))
}
}

override fun getNotificationPackages(result: Pigeons.Result<MutableList<Pigeons.NotifyingPackage>>) {
coroutineScope.launch {
result.success(
cachedPackageInfoDao.getAll().map {
Pigeons.NotifyingPackage.Builder()
.setPackageId(it.id)
.setPackageName(it.name)
.build()
}.toMutableList()
)
}
}
}
5 changes: 5 additions & 0 deletions android/app/src/main/kotlin/io/rebble/cobble/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import dagger.Module
import dagger.Provides
import io.rebble.cobble.errors.GlobalExceptionHandler
import io.rebble.cobble.shared.database.AppDatabase
import io.rebble.cobble.shared.database.dao.CachedPackageInfoDao
import io.rebble.cobble.shared.database.dao.PersistedNotificationDao
import io.rebble.cobble.shared.datastore.KMPPrefs
import io.rebble.cobble.shared.datastore.createDataStore
Expand Down Expand Up @@ -50,5 +51,9 @@ abstract class AppModule {
fun providePersistedNotificationDao(context: Context): PersistedNotificationDao {
return AppDatabase.instance().persistedNotificationDao()
}
@Provides
fun provideCachedPackageInfoDao(context: Context): CachedPackageInfoDao {
return AppDatabase.instance().cachedPackageInfoDao()
}
}
}
131 changes: 130 additions & 1 deletion android/app/src/main/kotlin/io/rebble/cobble/pigeons/Pigeons.java
Original file line number Diff line number Diff line change
Expand Up @@ -2831,6 +2831,79 @@ ArrayList<Object> toList() {
}
}

/** Generated class from Pigeon that represents data sent in messages. */
public static final class NotifyingPackage {
private @NonNull String packageId;

public @NonNull String getPackageId() {
return packageId;
}

public void setPackageId(@NonNull String setterArg) {
if (setterArg == null) {
throw new IllegalStateException("Nonnull field \"packageId\" is null.");
}
this.packageId = setterArg;
}

private @NonNull String packageName;

public @NonNull String getPackageName() {
return packageName;
}

public void setPackageName(@NonNull String setterArg) {
if (setterArg == null) {
throw new IllegalStateException("Nonnull field \"packageName\" is null.");
}
this.packageName = setterArg;
}

/** Constructor is non-public to enforce null safety; use Builder. */
NotifyingPackage() {}

public static final class Builder {

private @Nullable String packageId;

public @NonNull Builder setPackageId(@NonNull String setterArg) {
this.packageId = setterArg;
return this;
}

private @Nullable String packageName;

public @NonNull Builder setPackageName(@NonNull String setterArg) {
this.packageName = setterArg;
return this;
}

public @NonNull NotifyingPackage build() {
NotifyingPackage pigeonReturn = new NotifyingPackage();
pigeonReturn.setPackageId(packageId);
pigeonReturn.setPackageName(packageName);
return pigeonReturn;
}
}

@NonNull
ArrayList<Object> toList() {
ArrayList<Object> toListResult = new ArrayList<Object>(2);
toListResult.add(packageId);
toListResult.add(packageName);
return toListResult;
}

static @NonNull NotifyingPackage fromList(@NonNull ArrayList<Object> list) {
NotifyingPackage pigeonResult = new NotifyingPackage();
Object packageId = list.get(0);
pigeonResult.setPackageId((String) packageId);
Object packageName = list.get(1);
pigeonResult.setPackageName((String) packageName);
return pigeonResult;
}
}

public interface Result<T> {
@SuppressWarnings("UnknownNullness")
void success(T result);
Expand Down Expand Up @@ -4061,14 +4134,43 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable UiConnecti
}
}
}

private static class NotificationsControlCodec extends StandardMessageCodec {
public static final NotificationsControlCodec INSTANCE = new NotificationsControlCodec();

private NotificationsControlCodec() {}

@Override
protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
switch (type) {
case (byte) 128:
return NotifyingPackage.fromList((ArrayList<Object>) readValue(buffer));
default:
return super.readValueOfType(type, buffer);
}
}

@Override
protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
if (value instanceof NotifyingPackage) {
stream.write(128);
writeValue(stream, ((NotifyingPackage) value).toList());
} else {
super.writeValue(stream, value);
}
}
}

/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
public interface NotificationsControl {

void sendTestNotification();

void getNotificationPackages(@NonNull Result<List<NotifyingPackage>> result);

/** The codec used by NotificationsControl. */
static @NonNull MessageCodec<Object> getCodec() {
return new StandardMessageCodec();
return NotificationsControlCodec.INSTANCE;
}
/**Sets up an instance of `NotificationsControl` to handle messages through the `binaryMessenger`. */
static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable NotificationsControl api) {
Expand All @@ -4094,6 +4196,33 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable Notificati
channel.setMessageHandler(null);
}
}
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger, "dev.flutter.pigeon.NotificationsControl.getNotificationPackages", getCodec());
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
ArrayList<Object> wrapped = new ArrayList<Object>();
Result<List<NotifyingPackage>> resultCallback =
new Result<List<NotifyingPackage>>() {
public void success(List<NotifyingPackage> result) {
wrapped.add(0, result);
reply.reply(wrapped);
}

public void error(Throwable error) {
ArrayList<Object> wrappedError = wrapError(error);
reply.reply(wrappedError);
}
};

api.getNotificationPackages(resultCallback);
});
} else {
channel.setMessageHandler(null);
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ interface CachedPackageInfoDao {

@Query("SELECT * FROM CachedPackageInfo WHERE id = :packageId")
suspend fun getPackageInfo(packageId: String): CachedPackageInfo?

@Query("SELECT * FROM CachedPackageInfo")
suspend fun getAll(): List<CachedPackageInfo>
}
11 changes: 11 additions & 0 deletions ios/Runner/Pigeon/Pigeons.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ NS_ASSUME_NONNULL_BEGIN
@class AppLogEntry;
@class OAuthResult;
@class NotifChannelPigeon;
@class NotifyingPackage;

/// Pigeon only supports classes as return/receive type.
/// That is why we must wrap primitive types into wrapper
Expand Down Expand Up @@ -326,6 +327,15 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, strong, nullable) NSNumber * delete;
@end

@interface NotifyingPackage : NSObject
/// `init` unavailable to enforce nonnull fields, see the `make` class method.
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)makeWithPackageId:(NSString *)packageId
packageName:(NSString *)packageName;
@property(nonatomic, copy) NSString * packageId;
@property(nonatomic, copy) NSString * packageName;
@end

/// The codec used by ScanCallbacks.
NSObject<FlutterMessageCodec> *ScanCallbacksGetCodec(void);

Expand Down Expand Up @@ -486,6 +496,7 @@ NSObject<FlutterMessageCodec> *NotificationsControlGetCodec(void);

@protocol NotificationsControl
- (void)sendTestNotificationWithError:(FlutterError *_Nullable *_Nonnull)error;
- (void)getNotificationPackagesWithCompletion:(void (^)(NSArray<NotifyingPackage *> *_Nullable, FlutterError *_Nullable))completion;
@end

extern void NotificationsControlSetup(id<FlutterBinaryMessenger> binaryMessenger, NSObject<NotificationsControl> *_Nullable api);
Expand Down
93 changes: 92 additions & 1 deletion ios/Runner/Pigeon/Pigeons.m
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,12 @@ + (nullable NotifChannelPigeon *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end

@interface NotifyingPackage ()
+ (NotifyingPackage *)fromList:(NSArray *)list;
+ (nullable NotifyingPackage *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end

@implementation BooleanWrapper
+ (instancetype)makeWithValue:(nullable NSNumber *)value {
BooleanWrapper* pigeonResult = [[BooleanWrapper alloc] init];
Expand Down Expand Up @@ -984,6 +990,33 @@ - (NSArray *)toList {
}
@end

@implementation NotifyingPackage
+ (instancetype)makeWithPackageId:(NSString *)packageId
packageName:(NSString *)packageName {
NotifyingPackage* pigeonResult = [[NotifyingPackage alloc] init];
pigeonResult.packageId = packageId;
pigeonResult.packageName = packageName;
return pigeonResult;
}
+ (NotifyingPackage *)fromList:(NSArray *)list {
NotifyingPackage *pigeonResult = [[NotifyingPackage alloc] init];
pigeonResult.packageId = GetNullableObjectAtIndex(list, 0);
NSAssert(pigeonResult.packageId != nil, @"");
pigeonResult.packageName = GetNullableObjectAtIndex(list, 1);
NSAssert(pigeonResult.packageName != nil, @"");
return pigeonResult;
}
+ (nullable NotifyingPackage *)nullableFromList:(NSArray *)list {
return (list) ? [NotifyingPackage fromList:list] : nil;
}
- (NSArray *)toList {
return @[
(self.packageId ?: [NSNull null]),
(self.packageName ?: [NSNull null]),
];
}
@end

@interface ScanCallbacksCodecReader : FlutterStandardReader
@end
@implementation ScanCallbacksCodecReader
Expand Down Expand Up @@ -2320,9 +2353,50 @@ void UiConnectionControlSetup(id<FlutterBinaryMessenger> binaryMessenger, NSObje
}
}
}
@interface NotificationsControlCodecReader : FlutterStandardReader
@end
@implementation NotificationsControlCodecReader
- (nullable id)readValueOfType:(UInt8)type {
switch (type) {
case 128:
return [NotifyingPackage fromList:[self readValue]];
default:
return [super readValueOfType:type];
}
}
@end

@interface NotificationsControlCodecWriter : FlutterStandardWriter
@end
@implementation NotificationsControlCodecWriter
- (void)writeValue:(id)value {
if ([value isKindOfClass:[NotifyingPackage class]]) {
[self writeByte:128];
[self writeValue:[value toList]];
} else {
[super writeValue:value];
}
}
@end

@interface NotificationsControlCodecReaderWriter : FlutterStandardReaderWriter
@end
@implementation NotificationsControlCodecReaderWriter
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
return [[NotificationsControlCodecWriter alloc] initWithData:data];
}
- (FlutterStandardReader *)readerWithData:(NSData *)data {
return [[NotificationsControlCodecReader alloc] initWithData:data];
}
@end

NSObject<FlutterMessageCodec> *NotificationsControlGetCodec(void) {
static FlutterStandardMessageCodec *sSharedObject = nil;
sSharedObject = [FlutterStandardMessageCodec sharedInstance];
static dispatch_once_t sPred = 0;
dispatch_once(&sPred, ^{
NotificationsControlCodecReaderWriter *readerWriter = [[NotificationsControlCodecReaderWriter alloc] init];
sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
});
return sSharedObject;
}

Expand All @@ -2344,6 +2418,23 @@ void NotificationsControlSetup(id<FlutterBinaryMessenger> binaryMessenger, NSObj
[channel setMessageHandler:nil];
}
}
{
FlutterBasicMessageChannel *channel =
[[FlutterBasicMessageChannel alloc]
initWithName:@"dev.flutter.pigeon.NotificationsControl.getNotificationPackages"
binaryMessenger:binaryMessenger
codec:NotificationsControlGetCodec()];
if (api) {
NSCAssert([api respondsToSelector:@selector(getNotificationPackagesWithCompletion:)], @"NotificationsControl api (%@) doesn't respond to @selector(getNotificationPackagesWithCompletion:)", api);
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
[api getNotificationPackagesWithCompletion:^(NSArray<NotifyingPackage *> *_Nullable output, FlutterError *_Nullable error) {
callback(wrapResult(output, error));
}];
}];
} else {
[channel setMessageHandler:nil];
}
}
}
@interface IntentControlCodecReader : FlutterStandardReader
@end
Expand Down
Loading

0 comments on commit 0dac866

Please sign in to comment.