Skip to content

Commit

Permalink
Finished Allow custom sounds per sender #991
Browse files Browse the repository at this point in the history
  • Loading branch information
guodong323 authored and tmolitor-stud-tu committed Apr 21, 2024
1 parent d7bd73a commit d9d1e0e
Show file tree
Hide file tree
Showing 24 changed files with 729 additions and 22 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 4 additions & 0 deletions Monal/Classes/ContactDetails.swift
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ struct ContactDetails: View {
NavigationLink(destination: LazyClosureView(BackgroundSettings(contact:contact, delegate:delegate))) {
Text("Change Chat Background")
}

NavigationLink(destination: LazyClosureView(SoundsSettingView(contact:contact, delegate:delegate))) {
Text("Sounds")
}
}
.listStyle(.plain)

Expand Down
11 changes: 10 additions & 1 deletion Monal/Classes/DataLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ extern NSString* const kMessageTypeFiletransfer;
-(BOOL) hasContactRequestForContact:(MLContact*) contact;
-(NSMutableArray*) allContactRequests;
-(void) addContactRequest:(MLContact *) requestor;
-(void) deleteContactRequest:(MLContact *) requestor;
-(void) deleteContactRequest:(MLContact *) requestor;

#pragma mark Contact info

Expand All @@ -106,6 +106,15 @@ extern NSString* const kMessageTypeFiletransfer;
-(BOOL) saveMessageDraft:(NSString*) buddy forAccount:(NSNumber*) accountNo withComment:(NSString*) comment;
-(NSString*) loadMessageDraft:(NSString*) buddy forAccount:(NSNumber*) accountNo;

#pragma mark - sound
-(void) setAlertSoundWithAccountId:(NSString*) accountId buddyId:(NSString*) buddyId soundName:(NSString*) soundName soundData:(NSData*) soundData isCustom:(NSNumber*) custom;
-(NSData*) getSoundDataForAccountId:(NSString*) accountId buddyId:(NSString*) buddyId;
-(NSString*) getSoundNameForAccountId:(NSString*) accountId buddyId:(NSString*) buddyId;
-(NSNumber*) getIsCustomSoundForAccountId:(NSString*) accountId buddyId:(NSString*) buddyId;
-(void) checkAndCreateAlertSoundsTable;
-(void) deleteSoundForAccountId:(NSString*) accountId buddyId:(NSString*) buddyId;
-(void) deleteSoundsForBuddyId:(NSString *)buddyId;

#pragma mark - MUC

-(BOOL) initMuc:(NSString*) room forAccountId:(NSNumber*) accountNo andMucNick:(NSString* _Nullable) mucNick;
Expand Down
202 changes: 202 additions & 0 deletions Monal/Classes/DataLayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -2522,4 +2522,206 @@ -(NSArray*) searchResultOfHistoryMessageWithKeyWords:(NSString*) keyword between
}];
}

#pragma mark - sounds

-(void) setAlertSoundWithAccountId:(NSString*) accountId buddyId:(NSString* )buddyId soundName:(NSString*) soundName soundData:(NSData*) soundData isCustom:(NSNumber*) custom
{
if(!soundName || !soundData)
{
return;
}
BOOL isAccountIdDefault = [accountId isEqualToString:@"Default"];
BOOL isBuddyIdGlobal = [buddyId isEqualToString:@"global"];

NSMutableArray* arguments = [NSMutableArray array];
if(!isAccountIdDefault)
{
[arguments addObject:accountId];
}
if(!isBuddyIdGlobal)
{
[arguments addObject:buddyId];
}

NSString* accountIdCondition = isAccountIdDefault ? @"account_id IS NULL" : @"account_id = ?";
NSString* buddyIdCondition = isBuddyIdGlobal ? @"buddy_id IS NULL" : @"buddy_id = ?";

[self.db voidWriteTransaction:^{
NSString* selectSql = [NSString stringWithFormat:@"SELECT COUNT(*) FROM alertsounds WHERE %@ AND %@;", accountIdCondition, buddyIdCondition];
id countResult = [self.db executeScalar:selectSql andArguments:arguments];
NSInteger count = [countResult integerValue];

if(count > 0)
{
NSString* whereClause = @"";
NSMutableArray* arguments = [NSMutableArray arrayWithObjects:soundName, soundData, custom, nil];

if ([accountId isEqualToString:@"Default"] && [buddyId isEqualToString:@"global"])
{
whereClause = @"account_id IS NULL AND buddy_id IS NULL";
}
else if([accountId isEqualToString:@"Default"])
{
whereClause = @"account_id IS NULL AND buddy_id = ?";
[arguments addObject:buddyId];
}
else if([buddyId isEqualToString:@"global"])
{
whereClause = @"account_id = ? AND buddy_id IS NULL";
[arguments addObject:accountId];
}
else
{
whereClause = @"account_id = ? AND buddy_id = ?";
[arguments addObjectsFromArray:@[accountId, buddyId]];
}
NSString* updateSql = [NSString stringWithFormat:@"UPDATE alertsounds SET soundname = ?, sounddata = ?, customsound = ? WHERE %@", whereClause];
[self.db executeNonQuery:updateSql andArguments:arguments];
}
else
{
NSString* insertSql = @"INSERT INTO alertsounds (account_id, buddy_id, soundname, sounddata, customsound) VALUES (?, ?, ?, ?, ?);";
NSArray* insertArguments = @[isAccountIdDefault ? [NSNull null] : accountId, isBuddyIdGlobal ? [NSNull null] : buddyId, soundName, soundData, custom];
[self.db executeNonQuery:insertSql andArguments:insertArguments];
}
}];
}


-(NSString*) getSoundNameForAccountId:(NSString*) accountId buddyId:(NSString*) buddyId
{
return [self.db idReadTransaction:^id{
NSString* accountIdCondition = [accountId isEqualToString:@"Default"] ? @"IS NULL" : @"= ?";
NSString* buddyIdCondition = [buddyId isEqualToString:@"global"] ? @"IS NULL" : @"= ?";

NSString* query = [NSString stringWithFormat:@"SELECT soundname FROM alertsounds WHERE account_id %@ AND buddy_id %@ LIMIT 1;", accountIdCondition, buddyIdCondition];

NSMutableArray* arguments = [[NSMutableArray alloc] init];
if (![accountId isEqualToString:@"Default"])
{
[arguments addObject:accountId];
}
if (![buddyId isEqualToString:@"global"])
{
[arguments addObject:buddyId];
}
id queryResult = [self.db executeScalar:query andArguments:arguments];
NSString* soundName = queryResult ? [NSString stringWithFormat:@"%@", queryResult] : nil;
return soundName;
}];
}

-(NSData*) getSoundDataForAccountId:(NSString*) accountId buddyId:(NSString*) buddyId
{
return [self.db idReadTransaction:^id{
NSString* accountIdCondition = [accountId isEqualToString:@"Default"] ? @"IS NULL" : @"= ?";
NSString* buddyIdCondition = [buddyId isEqualToString:@"global"] ? @"IS NULL" : @"= ?";

NSString* query = [NSString stringWithFormat:@"SELECT sounddata FROM alertsounds WHERE account_id %@ AND buddy_id %@ LIMIT 1;", accountIdCondition, buddyIdCondition];

NSMutableArray* arguments = [[NSMutableArray alloc] init];
if(![accountId isEqualToString:@"Default"])
{
[arguments addObject:accountId];
}
if(![buddyId isEqualToString:@"global"])
{
[arguments addObject:buddyId];
}

id queryResult = [self.db executeScalar:query andArguments:arguments];
NSData* soundData = [NSData dataWithData:queryResult];
return soundData;
}];
}

-(NSNumber*) getIsCustomSoundForAccountId:(NSString*) accountId buddyId:(NSString*) buddyId
{
return [self.db idReadTransaction:^id{
NSString* accountIdCondition = [accountId isEqualToString:@"Default"] ? @"IS NULL" : @"= ?";
NSString* buddyIdCondition = [buddyId isEqualToString:@"global"] ? @"IS NULL" : @"= ?";

NSString* query = [NSString stringWithFormat:@"SELECT customsound FROM alertsounds WHERE account_id %@ AND buddy_id %@ LIMIT 1;", accountIdCondition, buddyIdCondition];

NSMutableArray* arguments = [[NSMutableArray alloc] init];
if(![accountId isEqualToString:@"Default"])
{
[arguments addObject:accountId];
}
if(![buddyId isEqualToString:@"global"])
{
[arguments addObject:buddyId];
}

id queryResult = [self.db executeScalar:query andArguments:arguments];
NSNumber* customSound = queryResult;
return customSound;
}];
}

-(void) checkAndCreateAlertSoundsTable
{
[self.db idReadTransaction:^id{
NSString* checkTableExistsQuery = @"SELECT name FROM sqlite_master WHERE type='table' AND name='alertsounds';";
id tableExistsResult = [self.db executeScalar:checkTableExistsQuery];

if(!tableExistsResult)
{
NSString* createTableQuery = @"CREATE TABLE alertsounds (alertsound_id INTEGER PRIMARY KEY, account_id VARCHAR, buddy_id VARCHAR, soundname VARCHAR, sounddata BLOB, customsound INTEGER);";

[self.db executeNonQuery:createTableQuery];

NSLog(@"alertsounds table created.");
}
else
{
NSLog(@"alertsounds table already exists.");
}
return nil;
}];
}


-(void) deleteSoundForAccountId:(NSString *) accountId buddyId:(NSString *) buddyId
{
[self.db voidWriteTransaction:^{
BOOL isAccountIdDefault = [accountId isEqualToString:@"Default"];
BOOL isBuddyIdGlobal = [buddyId isEqualToString:@"global"];

NSMutableArray* arguments = [NSMutableArray array];
NSString* query;

if(isAccountIdDefault && isBuddyIdGlobal)
{
query = @"DELETE FROM alertsounds WHERE account_id IS NULL AND buddy_id IS NULL;";
}
else if(isAccountIdDefault)
{
query = @"DELETE FROM alertsounds WHERE account_id IS NULL AND buddy_id = ?;";
[arguments addObject:buddyId];
}
else if(isBuddyIdGlobal)
{
query = @"DELETE FROM alertsounds WHERE account_id = ? AND buddy_id IS NULL;";
[arguments addObject:accountId];
}
else
{
query = @"DELETE FROM alertsounds WHERE account_id = ? AND buddy_id = ?;";
[arguments addObject:accountId];
[arguments addObject:buddyId];
}
[self.db executeNonQuery:query andArguments:arguments];
}];
}

-(void) deleteSoundsForBuddyId:(NSString *) buddyId
{
[self.db voidWriteTransaction:^{
NSString *query = @"DELETE FROM alertsounds WHERE buddy_id = ?;";
NSArray *arguments = @[buddyId];
[self.db executeNonQuery:query andArguments:arguments];
}];
}

@end
1 change: 1 addition & 0 deletions Monal/Classes/MLNotificationManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#import <UserNotifications/UserNotifications.h>
#import "MLConstants.h"
#import "DataLayer.h"
#import "MLSoundManager.h"

/**
Singleton object that will handle all sliders, alerts and sounds. listens for new message notification.
Expand Down
36 changes: 18 additions & 18 deletions Monal/Classes/MLNotificationManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -337,16 +337,16 @@ -(void) playNotificationSoundForMessage:(MLMessage*) message withSound:(BOOL) so

if(sound && [[HelperTools defaultsDB] boolForKey:@"Sound"])
{
NSString* filename = [[HelperTools defaultsDB] objectForKey:@"AlertSoundFile"];
if(filename)
NSString* senderJID = [message.buddyName lowercaseString];
NSString* receiverJID = account.connectionProperties.identity.jid;
NSString* soundName = [[MLSoundManager sharedInstance] getSoundNameForSenderJID:senderJID andReceiverJID:receiverJID];
if([soundName isEqualToString:@""])
{
content.sound = [UNNotificationSound soundNamed:[NSString stringWithFormat:@"AlertSounds/%@.aif", filename]];
DDLogDebug(@"Using user configured alert sound: %@", content.sound);
content.sound = [UNNotificationSound defaultSound];
}
else
{
content.sound = [UNNotificationSound defaultSound];
DDLogDebug(@"Using default alert sound: %@", content.sound);
content.sound = [UNNotificationSound soundNamed:soundName];
}
}
else
Expand Down Expand Up @@ -470,16 +470,16 @@ -(void) showModernNotificationForMessage:(MLMessage*) message withSound:(BOOL) s

if(sound && [[HelperTools defaultsDB] boolForKey:@"Sound"])
{
NSString* filename = [[HelperTools defaultsDB] objectForKey:@"AlertSoundFile"];
if(filename)
NSString* senderJID = [message.buddyName lowercaseString];
NSString* receiverJID = account.connectionProperties.identity.jid;
NSString* soundName = [[MLSoundManager sharedInstance] getSoundNameForSenderJID:senderJID andReceiverJID:receiverJID];
if([soundName isEqualToString:@""])
{
content.sound = [UNNotificationSound soundNamed:[NSString stringWithFormat:@"AlertSounds/%@.aif", filename]];
DDLogDebug(@"Using user configured alert sound: %@", content.sound);
content.sound = [UNNotificationSound defaultSound];
}
else
{
content.sound = [UNNotificationSound defaultSound];
DDLogDebug(@"Using default alert sound: %@", content.sound);
content.sound = [UNNotificationSound soundNamed:soundName];
}
}
else
Expand Down Expand Up @@ -732,16 +732,16 @@ -(void) showLegacyNotificationForMessage:(MLMessage*) message withSound:(BOOL) s

if(sound && [[HelperTools defaultsDB] boolForKey:@"Sound"])
{
NSString* filename = [[HelperTools defaultsDB] objectForKey:@"AlertSoundFile"];
if(filename)
NSString* senderJID = [message.buddyName lowercaseString];
NSString* receiverJID = contact.contactJid;
NSString* soundName = [[MLSoundManager sharedInstance] getSoundNameForSenderJID:senderJID andReceiverJID:receiverJID];
if([soundName isEqualToString:@""])
{
content.sound = [UNNotificationSound soundNamed:[NSString stringWithFormat:@"AlertSounds/%@.aif", filename]];
DDLogDebug(@"Using user configured alert sound: %@", content.sound);
content.sound = [UNNotificationSound defaultSound];
}
else
{
content.sound = [UNNotificationSound defaultSound];
DDLogDebug(@"Using default alert sound: %@", content.sound);
content.sound = [UNNotificationSound soundNamed:soundName];
}
}
else
Expand Down
8 changes: 5 additions & 3 deletions Monal/Classes/MLSettingsTableViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ @interface MLSettingsTableViewController () {

@end

@implementation MLSettingsTableViewController
@implementation MLSettingsTableViewController


-(IBAction) close:(id) sender
Expand Down Expand Up @@ -337,9 +337,11 @@ -(void)tableView:(UITableView*) tableView didSelectRowAtIndexPath:(NSIndexPath*)
[self showDetailViewController:backgroundSettingsController sender:self];
break;
}
case SoundsRow:
[self performSegueWithIdentifier:@"showSounds" sender:self];
case SoundsRow: {
UIViewController* soundSettingsController =[[SwiftuiInterface new] makeSoundSettings:nil];
[self showDetailViewController:soundSettingsController sender:self];
break;
}
default:
unreachable();
}
Expand Down
31 changes: 31 additions & 0 deletions Monal/Classes/MLSoundManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// MLSoundManager.h
// Monal
//
// Created by 阿栋 on 3/29/24.
// Copyright © 2024 monal-im.org. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@class MLContact;

@interface MLSoundManager : NSObject


@property (nonatomic, strong) NSString* _Nullable selectedSound;


+ (MLSoundManager*) sharedInstance;
-(NSArray<NSString*>*) listBundledSounds;
-(NSData*) getSoundDataForSenderJID:(NSString*) senderJID andReceiverJID:(NSString*) receiverJID;
-(NSString*) getSoundNameForSenderJID:(NSString*) senderJID andReceiverJID:(NSString*) receiverJID;
-(void) saveSoundData:(NSData*) soundData forSenderJID:(NSString*) senderJID andReceiverJID:(NSString*) receiverJID WithSoundFileName:(NSString*) filename isCustomSound:(NSNumber*) isCustom;
-(NSNumber*) getIsCustomSoundForAccountId:(NSString*) accountId buddyId:(NSString*) buddyId;
-(void) deleteContactForAccountId:(NSString*) accountId;
@end

NS_ASSUME_NONNULL_END

Loading

0 comments on commit d9d1e0e

Please sign in to comment.