diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index bc960aaa7..4e59fc6f3 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -8,6 +8,21 @@ /* Begin PBXBuildFile section */ 2AE2882E4C2B96BFFF9EE27C /* Pods_SignalShareExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0F94C85CB0B235DA37F68ED0 /* Pods_SignalShareExtension.framework */; }; + 34074F5B203D093B004596AE /* NotificationSoundsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34074F59203D093A004596AE /* NotificationSoundsViewController.m */; }; + 34074F61203D0CBE004596AE /* NotificationSounds.m in Sources */ = {isa = PBXBuildFile; fileRef = 34074F5F203D0CBD004596AE /* NotificationSounds.m */; }; + 34074F62203D0CBE004596AE /* NotificationSounds.h in Headers */ = {isa = PBXBuildFile; fileRef = 34074F60203D0CBE004596AE /* NotificationSounds.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 34074FAE203D14D8004596AE /* aurora.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FAD203D14D8004596AE /* aurora.m4r */; }; + 34074FBA203D14F6004596AE /* bamboo.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FAF203D14F3004596AE /* bamboo.m4r */; }; + 34074FBB203D14F6004596AE /* circles.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FB0203D14F4004596AE /* circles.m4r */; }; + 34074FBC203D14F6004596AE /* chord.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FB1203D14F4004596AE /* chord.m4r */; }; + 34074FBD203D14F6004596AE /* complete.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FB2203D14F4004596AE /* complete.m4r */; }; + 34074FBE203D14F6004596AE /* hello.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FB3203D14F4004596AE /* hello.m4r */; }; + 34074FBF203D14F6004596AE /* input.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FB4203D14F4004596AE /* input.m4r */; }; + 34074FC0203D14F6004596AE /* note.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FB5203D14F4004596AE /* note.m4r */; }; + 34074FC1203D14F6004596AE /* popcorn.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FB6203D14F5004596AE /* popcorn.m4r */; }; + 34074FC2203D14F6004596AE /* pulse.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FB7203D14F5004596AE /* pulse.m4r */; }; + 34074FC3203D14F6004596AE /* synth.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FB8203D14F5004596AE /* synth.m4r */; }; + 34074FC4203D14F6004596AE /* keys.m4r in Resources */ = {isa = PBXBuildFile; fileRef = 34074FB9203D14F6004596AE /* keys.m4r */; }; 340B02BA1FA0D6C700F9CFEC /* ConversationViewItemTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 340B02B91FA0D6C700F9CFEC /* ConversationViewItemTest.m */; }; 340CB2271EAC25820001CAA1 /* UpdateGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340CB2261EAC25820001CAA1 /* UpdateGroupViewController.m */; }; 341F2C0F1F2B8AE700D07D6B /* DebugUIMisc.m in Sources */ = {isa = PBXBuildFile; fileRef = 341F2C0E1F2B8AE700D07D6B /* DebugUIMisc.m */; }; @@ -478,6 +493,22 @@ 3400C7951EAF99F4008A8584 /* SelectThreadViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SelectThreadViewController.m; sourceTree = ""; }; 3400C7971EAFB772008A8584 /* ThreadViewHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadViewHelper.h; sourceTree = ""; }; 3400C7981EAFB772008A8584 /* ThreadViewHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThreadViewHelper.m; sourceTree = ""; }; + 34074F59203D093A004596AE /* NotificationSoundsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationSoundsViewController.m; sourceTree = ""; }; + 34074F5A203D093B004596AE /* NotificationSoundsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotificationSoundsViewController.h; sourceTree = ""; }; + 34074F5F203D0CBD004596AE /* NotificationSounds.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationSounds.m; sourceTree = ""; }; + 34074F60203D0CBE004596AE /* NotificationSounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotificationSounds.h; sourceTree = ""; }; + 34074FAD203D14D8004596AE /* aurora.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; name = aurora.m4r; path = Signal/AudioFiles/messageReceivedSounds/aurora.m4r; sourceTree = SOURCE_ROOT; }; + 34074FAF203D14F3004596AE /* bamboo.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; name = bamboo.m4r; path = Signal/AudioFiles/messageReceivedSounds/bamboo.m4r; sourceTree = SOURCE_ROOT; }; + 34074FB0203D14F4004596AE /* circles.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; name = circles.m4r; path = Signal/AudioFiles/messageReceivedSounds/circles.m4r; sourceTree = SOURCE_ROOT; }; + 34074FB1203D14F4004596AE /* chord.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; name = chord.m4r; path = Signal/AudioFiles/messageReceivedSounds/chord.m4r; sourceTree = SOURCE_ROOT; }; + 34074FB2203D14F4004596AE /* complete.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; name = complete.m4r; path = Signal/AudioFiles/messageReceivedSounds/complete.m4r; sourceTree = SOURCE_ROOT; }; + 34074FB3203D14F4004596AE /* hello.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; name = hello.m4r; path = Signal/AudioFiles/messageReceivedSounds/hello.m4r; sourceTree = SOURCE_ROOT; }; + 34074FB4203D14F4004596AE /* input.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; name = input.m4r; path = Signal/AudioFiles/messageReceivedSounds/input.m4r; sourceTree = SOURCE_ROOT; }; + 34074FB5203D14F4004596AE /* note.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; name = note.m4r; path = Signal/AudioFiles/messageReceivedSounds/note.m4r; sourceTree = SOURCE_ROOT; }; + 34074FB6203D14F5004596AE /* popcorn.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; name = popcorn.m4r; path = Signal/AudioFiles/messageReceivedSounds/popcorn.m4r; sourceTree = SOURCE_ROOT; }; + 34074FB7203D14F5004596AE /* pulse.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; name = pulse.m4r; path = Signal/AudioFiles/messageReceivedSounds/pulse.m4r; sourceTree = SOURCE_ROOT; }; + 34074FB8203D14F5004596AE /* synth.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; name = synth.m4r; path = Signal/AudioFiles/messageReceivedSounds/synth.m4r; sourceTree = SOURCE_ROOT; }; + 34074FB9203D14F6004596AE /* keys.m4r */ = {isa = PBXFileReference; lastKnownFileType = file; name = keys.m4r; path = Signal/AudioFiles/messageReceivedSounds/keys.m4r; sourceTree = SOURCE_ROOT; }; 340B02B61F9FD31800F9CFEC /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = translations/he.lproj/Localizable.strings; sourceTree = ""; }; 340B02B91FA0D6C700F9CFEC /* ConversationViewItemTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConversationViewItemTest.m; sourceTree = ""; }; 340CB2221EAC155C0001CAA1 /* ContactsViewHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsViewHelper.h; sourceTree = ""; }; @@ -1086,6 +1117,41 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 34074F54203D0722004596AE /* Sounds */ = { + isa = PBXGroup; + children = ( + 34074F63203D1258004596AE /* messageReceivedSounds */, + 34074F7C203D126D004596AE /* ringtoneSounds */, + ); + path = Sounds; + sourceTree = ""; + }; + 34074F63203D1258004596AE /* messageReceivedSounds */ = { + isa = PBXGroup; + children = ( + 34074FAD203D14D8004596AE /* aurora.m4r */, + 34074FAF203D14F3004596AE /* bamboo.m4r */, + 34074FB1203D14F4004596AE /* chord.m4r */, + 34074FB0203D14F4004596AE /* circles.m4r */, + 34074FB2203D14F4004596AE /* complete.m4r */, + 34074FB3203D14F4004596AE /* hello.m4r */, + 34074FB4203D14F4004596AE /* input.m4r */, + 34074FB9203D14F6004596AE /* keys.m4r */, + 34074FB5203D14F4004596AE /* note.m4r */, + 34074FB6203D14F5004596AE /* popcorn.m4r */, + 34074FB7203D14F5004596AE /* pulse.m4r */, + 34074FB8203D14F5004596AE /* synth.m4r */, + ); + path = messageReceivedSounds; + sourceTree = ""; + }; + 34074F7C203D126D004596AE /* ringtoneSounds */ = { + isa = PBXGroup; + children = ( + ); + path = ringtoneSounds; + sourceTree = ""; + }; 34330A581E7875FB00DF2FB9 /* Fonts */ = { isa = PBXGroup; children = ( @@ -1202,6 +1268,8 @@ 346129921FD1E30000532771 /* migrations */, 347850671FD9B78A007B8332 /* NoopCallMessageHandler.swift */, 347850681FD9B78A007B8332 /* NoopNotificationsManager.swift */, + 34074F60203D0CBE004596AE /* NotificationSounds.h */, + 34074F5F203D0CBD004596AE /* NotificationSounds.m */, 45F170AB1E2F0351003FC1F2 /* OWSAudioSession.swift */, 346129561FD1D74B00532771 /* Release.h */, 346129571FD1D74B00532771 /* Release.m */, @@ -1352,6 +1420,8 @@ 34B3F8571E8DF1700035BE1A /* NotificationSettingsOptionsViewController.m */, 34B3F8581E8DF1700035BE1A /* NotificationSettingsViewController.h */, 34B3F8591E8DF1700035BE1A /* NotificationSettingsViewController.m */, + 34074F5A203D093B004596AE /* NotificationSoundsViewController.h */, + 34074F59203D093A004596AE /* NotificationSoundsViewController.m */, 34CCAF391F0C2748004084F4 /* OWSAddToContactViewController.h */, 34CCAF3A1F0C2748004084F4 /* OWSAddToContactViewController.m */, 347E0B772003CD7400BC2F76 /* OWSBackupExportViewController.h */, @@ -1992,14 +2062,15 @@ D221A093169C9E5E00537ABF /* Signal */ = { isa = PBXGroup; children = ( - B657DDC91911A40500F45B0C /* Signal.entitlements */, 34330A581E7875FB00DF2FB9 /* Fonts */, B633C4FD1A1D190B0059AC12 /* Images */, + B66DBF4919D5BBC8006EA940 /* Images.xcassets */, B67EBF5C19194AC60084CCFD /* Settings.bundle */, + B657DDC91911A40500F45B0C /* Signal.entitlements */, + 34074F54203D0722004596AE /* Sounds */, 76EB03C118170B33006006FC /* src */, - B660F66C1C29867F00687D6E /* test */, D221A094169C9E5E00537ABF /* Supporting Files */, - B66DBF4919D5BBC8006EA940 /* Images.xcassets */, + B660F66C1C29867F00687D6E /* test */, ); path = Signal; sourceTree = ""; @@ -2103,6 +2174,7 @@ 45194F901FD7200000333B2C /* ThreadUtil.h in Headers */, 346129CC1FD2072E00532771 /* NSAttributedString+OWS.h in Headers */, 346129FD1FD5F31400532771 /* OWS102MoveLoggingPreferenceToUserDefaults.h in Headers */, + 34074F62203D0CBE004596AE /* NotificationSounds.h in Headers */, 344F2499200FD03300CFB4F4 /* SharingThreadPickerViewController.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2376,20 +2448,31 @@ B633C5C41A1D190B0059AC12 /* mute_on@2x.png in Resources */, B633C5CE1A1D190B0059AC12 /* quit@2x.png in Resources */, AD83FF441A73426500B5C81A /* audio_pause_button.png in Resources */, + 34074FBF203D14F6004596AE /* input.m4r in Resources */, + 34074FBB203D14F6004596AE /* circles.m4r in Resources */, B6F509971AA53F760068F56A /* Localizable.strings in Resources */, B633C59D1A1D190B0059AC12 /* endcall@2x.png in Resources */, FC5CDF391A3393DD00B47253 /* error_white@2x.png in Resources */, B633C5D21A1D190B0059AC12 /* savephoto@2x.png in Resources */, B10C9B611A7049EC00ECA2BF /* play_icon.png in Resources */, AD83FF401A73426500B5C81A /* audio_pause_button_blue@2x.png in Resources */, + 34074FC3203D14F6004596AE /* synth.m4r in Resources */, + 34074FC4203D14F6004596AE /* keys.m4r in Resources */, B66DBF4A19D5BBC8006EA940 /* Images.xcassets in Resources */, 4517642A1DE939FD00EDB8B9 /* ContactCell.xib in Resources */, + 34074FC1203D14F6004596AE /* popcorn.m4r in Resources */, + 34074FC2203D14F6004596AE /* pulse.m4r in Resources */, AD83FF431A73426500B5C81A /* audio_play_button@2x.png in Resources */, + 34074FBE203D14F6004596AE /* hello.m4r in Resources */, 45CB2FA81CB7146C00E1B343 /* Launch Screen.storyboard in Resources */, 34B3F8781E8DF1700035BE1A /* ContactsPicker.xib in Resources */, + 34074FBA203D14F6004596AE /* bamboo.m4r in Resources */, B633C5C31A1D190B0059AC12 /* mute_off@2x.png in Resources */, AD83FF411A73426500B5C81A /* audio_play_button_blue@2x.png in Resources */, FC5CDF3A1A3393DD00B47253 /* warning_white@2x.png in Resources */, + 34074FBC203D14F6004596AE /* chord.m4r in Resources */, + 34074FC0203D14F6004596AE /* note.m4r in Resources */, + 34074FAE203D14D8004596AE /* aurora.m4r in Resources */, E1370BE018A0686600826894 /* busy.mp3 in Resources */, E1370BE218A0686C00826894 /* failure.mp3 in Resources */, B625CD561ABB589C00E8B23C /* NewMessage.aifc in Resources */, @@ -2405,6 +2488,7 @@ B10C9B5F1A7049EC00ECA2BF /* pause_icon.png in Resources */, AD83FF471A73428300B5C81A /* audio_play_button_blue.png in Resources */, 34330A5E1E787BD800DF2FB9 /* ElegantIcons.ttf in Resources */, + 34074FBD203D14F6004596AE /* complete.m4r in Resources */, AD83FF451A73426500B5C81A /* audio_pause_button@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2782,6 +2866,7 @@ 347850711FDAEB17007B8332 /* OWSUserProfile.m in Sources */, 346129761FD1E0B500532771 /* WeakTimer.swift in Sources */, 346129F81FD5F31400532771 /* OWS100RemoveTSRecipientsMigration.m in Sources */, + 34074F61203D0CBE004596AE /* NotificationSounds.m in Sources */, 346129B51FD1F7E800532771 /* OWSProfileManager.m in Sources */, 346129701FD1D74C00532771 /* Release.m in Sources */, 3478506C1FD9B78A007B8332 /* NoopNotificationsManager.swift in Sources */, @@ -2977,6 +3062,7 @@ 34D1F0B11F867BFC0066283D /* OWSUnreadIndicatorCell.m in Sources */, 34B3F89C1E8DF3270035BE1A /* BlockListViewController.m in Sources */, 34BECE2B1F74C12700D7438D /* DebugUIStress.m in Sources */, + 34074F5B203D093B004596AE /* NotificationSoundsViewController.m in Sources */, 34C42D5B1F45F7A80072EC04 /* OWSNavigationController.m in Sources */, B609597C1C2C0FC6004E8797 /* iRate.m in Sources */, 4574A5D61DD6704700C6B692 /* CallService.swift in Sources */, diff --git a/Signal/AudioFiles/messageReceivedSounds/aurora.m4r b/Signal/AudioFiles/messageReceivedSounds/aurora.m4r new file mode 100644 index 000000000..a9dce516d Binary files /dev/null and b/Signal/AudioFiles/messageReceivedSounds/aurora.m4r differ diff --git a/Signal/AudioFiles/messageReceivedSounds/bamboo.m4r b/Signal/AudioFiles/messageReceivedSounds/bamboo.m4r new file mode 100644 index 000000000..b795043d8 Binary files /dev/null and b/Signal/AudioFiles/messageReceivedSounds/bamboo.m4r differ diff --git a/Signal/AudioFiles/messageReceivedSounds/chord.m4r b/Signal/AudioFiles/messageReceivedSounds/chord.m4r new file mode 100644 index 000000000..89d9c567f Binary files /dev/null and b/Signal/AudioFiles/messageReceivedSounds/chord.m4r differ diff --git a/Signal/AudioFiles/messageReceivedSounds/circles.m4r b/Signal/AudioFiles/messageReceivedSounds/circles.m4r new file mode 100644 index 000000000..81e54a2c5 Binary files /dev/null and b/Signal/AudioFiles/messageReceivedSounds/circles.m4r differ diff --git a/Signal/AudioFiles/messageReceivedSounds/complete.m4r b/Signal/AudioFiles/messageReceivedSounds/complete.m4r new file mode 100644 index 000000000..9bba6dd42 Binary files /dev/null and b/Signal/AudioFiles/messageReceivedSounds/complete.m4r differ diff --git a/Signal/AudioFiles/messageReceivedSounds/hello.m4r b/Signal/AudioFiles/messageReceivedSounds/hello.m4r new file mode 100644 index 000000000..9504e9a0d Binary files /dev/null and b/Signal/AudioFiles/messageReceivedSounds/hello.m4r differ diff --git a/Signal/AudioFiles/messageReceivedSounds/input.m4r b/Signal/AudioFiles/messageReceivedSounds/input.m4r new file mode 100644 index 000000000..5e86616ba Binary files /dev/null and b/Signal/AudioFiles/messageReceivedSounds/input.m4r differ diff --git a/Signal/AudioFiles/messageReceivedSounds/keys.m4r b/Signal/AudioFiles/messageReceivedSounds/keys.m4r new file mode 100644 index 000000000..ebdcb00b6 Binary files /dev/null and b/Signal/AudioFiles/messageReceivedSounds/keys.m4r differ diff --git a/Signal/AudioFiles/messageReceivedSounds/note.m4r b/Signal/AudioFiles/messageReceivedSounds/note.m4r new file mode 100644 index 000000000..5e394836a Binary files /dev/null and b/Signal/AudioFiles/messageReceivedSounds/note.m4r differ diff --git a/Signal/AudioFiles/messageReceivedSounds/popcorn.m4r b/Signal/AudioFiles/messageReceivedSounds/popcorn.m4r new file mode 100644 index 000000000..2c2ca24d1 Binary files /dev/null and b/Signal/AudioFiles/messageReceivedSounds/popcorn.m4r differ diff --git a/Signal/AudioFiles/messageReceivedSounds/pulse.m4r b/Signal/AudioFiles/messageReceivedSounds/pulse.m4r new file mode 100644 index 000000000..8b3777e68 Binary files /dev/null and b/Signal/AudioFiles/messageReceivedSounds/pulse.m4r differ diff --git a/Signal/AudioFiles/messageReceivedSounds/synth.m4r b/Signal/AudioFiles/messageReceivedSounds/synth.m4r new file mode 100644 index 000000000..78cfbe654 Binary files /dev/null and b/Signal/AudioFiles/messageReceivedSounds/synth.m4r differ diff --git a/Signal/AudioFiles/ringtoneSounds/Apex.m4r b/Signal/AudioFiles/ringtoneSounds/Apex.m4r new file mode 100644 index 000000000..d45015588 Binary files /dev/null and b/Signal/AudioFiles/ringtoneSounds/Apex.m4r differ diff --git a/Signal/AudioFiles/ringtoneSounds/Beacon.m4r b/Signal/AudioFiles/ringtoneSounds/Beacon.m4r new file mode 100644 index 000000000..bf83c5533 Binary files /dev/null and b/Signal/AudioFiles/ringtoneSounds/Beacon.m4r differ diff --git a/Signal/AudioFiles/ringtoneSounds/Opening.m4r b/Signal/AudioFiles/ringtoneSounds/Opening.m4r new file mode 100644 index 000000000..9519f33c4 Binary files /dev/null and b/Signal/AudioFiles/ringtoneSounds/Opening.m4r differ diff --git a/Signal/src/ViewControllers/NotificationSettingsViewController.m b/Signal/src/ViewControllers/NotificationSettingsViewController.m index aa4ce9b76..b365d2cf4 100644 --- a/Signal/src/ViewControllers/NotificationSettingsViewController.m +++ b/Signal/src/ViewControllers/NotificationSettingsViewController.m @@ -1,9 +1,10 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "NotificationSettingsViewController.h" #import "NotificationSettingsOptionsViewController.h" +#import "NotificationSoundsViewController.h" #import #import @@ -31,6 +32,19 @@ OWSPreferences *prefs = [Environment preferences]; + OWSTableSection *soundsSection = [OWSTableSection new]; + soundsSection.headerTitle = NSLocalizedString( + @"NOTIFICATIONS_SECTION_SOUNDS", @"Label for settings UI allows user to change the notification sound."); + [soundsSection + addItem:[OWSTableItem + disclosureItemWithText:NSLocalizedString(@"NOTIFICATIONS_ITEM_SOUND", + @"Label for item that allows user to change the notification sound.") + actionBlock:^{ + NotificationSoundsViewController *vc = [NotificationSoundsViewController new]; + [weakSelf.navigationController pushViewController:vc animated:YES]; + }]]; + [contents addSection:soundsSection]; + OWSTableSection *backgroundSection = [OWSTableSection new]; backgroundSection.headerTitle = NSLocalizedString(@"NOTIFICATIONS_SECTION_BACKGROUND", nil); [backgroundSection addItem:[OWSTableItem itemWithCustomCellBlock:^{ diff --git a/Signal/src/ViewControllers/NotificationSoundsViewController.h b/Signal/src/ViewControllers/NotificationSoundsViewController.h new file mode 100644 index 000000000..ceabfc320 --- /dev/null +++ b/Signal/src/ViewControllers/NotificationSoundsViewController.h @@ -0,0 +1,9 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +#import "OWSTableViewController.h" + +@interface NotificationSoundsViewController : OWSTableViewController + +@end diff --git a/Signal/src/ViewControllers/NotificationSoundsViewController.m b/Signal/src/ViewControllers/NotificationSoundsViewController.m new file mode 100644 index 000000000..63eb5f0cc --- /dev/null +++ b/Signal/src/ViewControllers/NotificationSoundsViewController.m @@ -0,0 +1,147 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +#import "NotificationSoundsViewController.h" +#import +#import +#import + +@interface NotificationSoundsViewController () + +@property (nonatomic) BOOL isDirty; + +@property (nonatomic) NotificationSound globalNotificationSound; + +@end + +#pragma mark - + +@implementation NotificationSoundsViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + [self setTitle:NSLocalizedString(@"SETTINGS_NOTIFICATION_SOUND", nil)]; + + OWSPreferences *preferences = [Environment preferences]; + self.globalNotificationSound = preferences.globalNotificationSound; + + [self updateTableContents]; + [self updateNavigationItems]; +} + +- (void)viewDidAppear:(BOOL)animated +{ + [self updateTableContents]; +} + +- (void)updateNavigationItems +{ + self.navigationItem.leftBarButtonItem = + [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop + target:self + action:@selector(cancelWasPressed:)]; + + if (self.isDirty) { + self.navigationItem.rightBarButtonItem = + [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave + target:self + action:@selector(saveWasPressed:)]; + } else { + self.navigationItem.rightBarButtonItem = nil; + } +} + +#pragma mark - Table Contents + +- (void)updateTableContents +{ + OWSTableContents *contents = [OWSTableContents new]; + + __weak NotificationSoundsViewController *weakSelf = self; + + OWSTableSection *soundsSection = [OWSTableSection new]; + soundsSection.headerTitle = NSLocalizedString( + @"NOTIFICATIONS_SECTION_SOUNDS", @"Label for settings UI allows user to change the notification sound."); + for (NSNumber *nsNotificationSound in [NotificationSounds allNotificationSounds]) { + NotificationSound notificationSound = (NotificationSound)nsNotificationSound.intValue; + // TODO: No disclosure, show checkmark. + [soundsSection + addItem:[OWSTableItem + disclosureItemWithText:[NotificationSounds displayNameForNotificationSound:notificationSound] + actionBlock:^{ + [weakSelf notificationSoundWasSelected:notificationSound]; + }]]; + } + + [contents addSection:soundsSection]; + + // OWSTableSection *backgroundSection = [OWSTableSection new]; + // backgroundSection.headerTitle = NSLocalizedString(@"NOTIFICATIONS_SECTION_BACKGROUND", nil); + // [backgroundSection addItem:[OWSTableItem itemWithCustomCellBlock:^{ + // UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 + // reuseIdentifier:@"UITableViewCellStyleValue1"]; + // + // NotificationType notifType = [prefs notificationPreviewType]; + // NSString *detailString = [prefs nameForNotificationPreviewType:notifType]; + // cell.textLabel.text = NSLocalizedString(@"NOTIFICATIONS_SHOW", nil); + // cell.detailTextLabel.text = detailString; + // [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; + // + // return cell; + // } + // actionBlock:^{ + // NotificationSettingsOptionsViewController *vc = + // [NotificationSettingsOptionsViewController new]; + // [weakSelf.navigationController pushViewController:vc + // animated:YES]; + // }]]; + // [contents addSection:backgroundSection]; + // + // OWSTableSection *inAppSection = [OWSTableSection new]; + // inAppSection.headerTitle = NSLocalizedString(@"NOTIFICATIONS_SECTION_INAPP", nil); + // [inAppSection addItem:[OWSTableItem switchItemWithText:NSLocalizedString(@"NOTIFICATIONS_SOUND", nil) + // isOn:[prefs soundInForeground] + // target:weakSelf + // selector:@selector(didToggleSoundNotificationsSwitch:)]]; + // [contents addSection:inAppSection]; + + self.contents = contents; +} + +#pragma mark - Events + +- (void)notificationSoundWasSelected:(NotificationSound)notificationSound +{ + [NotificationSounds playNotificationSound:notificationSound]; + + if (self.globalNotificationSound == notificationSound) { + return; + } + + self.globalNotificationSound = notificationSound; + self.isDirty = YES; + [self updateTableContents]; +} + +//- (void)didToggleSoundNotificationsSwitch:(UISwitch *)sender { +// [Environment.preferences setSoundInForeground:sender.on]; +//} + +- (void)cancelWasPressed:(id)sender +{ + // TODO: Add "discard changes?" alert. + [self dismissViewControllerAnimated:YES completion:nil]; +} + +- (void)saveWasPressed:(id)sender +{ + OWSPreferences *preferences = [Environment preferences]; + preferences.globalNotificationSound = self.globalNotificationSound; + + [self dismissViewControllerAnimated:YES completion:nil]; +} + +@end diff --git a/Signal/src/environment/NotificationsManager.m b/Signal/src/environment/NotificationsManager.m index 7b227f6e0..1269f831f 100644 --- a/Signal/src/environment/NotificationsManager.m +++ b/Signal/src/environment/NotificationsManager.m @@ -8,6 +8,7 @@ #import #import #import +#import #import #import #import @@ -22,7 +23,6 @@ NSString *const kNotificationsManagerNewMesssageSoundName = @"NewMessage.aifc"; @interface NotificationsManager () -@property (nonatomic) SystemSoundID newMessageSound; @property (nonatomic, readonly) NSMutableDictionary *currentNotifications; @property (nonatomic, readonly) NotificationType notificationPreviewType; @@ -43,9 +43,6 @@ NSString *const kNotificationsManagerNewMesssageSoundName = @"NewMessage.aifc"; _currentNotifications = [NSMutableDictionary new]; - NSURL *newMessageURL = [[NSBundle mainBundle] URLForResource:@"NewMessage" withExtension:@"aifc"]; - AudioServicesCreateSystemSoundID((__bridge CFURLRef)newMessageURL, &_newMessageSound); - _notificationHistory = [NSMutableArray new]; OWSSingletonAssert(); @@ -248,7 +245,8 @@ NSString *const kNotificationsManagerNewMesssageSoundName = @"NewMessage.aifc"; [[PushManager sharedManager] presentNotification:notification checkForCancel:NO]; } else { if (shouldPlaySound && [Environment.preferences soundInForeground]) { - AudioServicesPlayAlertSound(_newMessageSound); + NotificationSound notificationSound = [Environment preferences].globalNotificationSound; + [NotificationSounds playNotificationSound:notificationSound]; } } }); @@ -351,7 +349,8 @@ NSString *const kNotificationsManagerNewMesssageSoundName = @"NewMessage.aifc"; [[PushManager sharedManager] presentNotification:notification checkForCancel:YES]; } else { if (shouldPlaySound && [Environment.preferences soundInForeground]) { - AudioServicesPlayAlertSound(_newMessageSound); + NotificationSound notificationSound = [Environment preferences].globalNotificationSound; + [NotificationSounds playNotificationSound:notificationSound]; } } }); diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index 2832ba90c..262a7fcea 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -1146,6 +1146,9 @@ /* No comment provided by engineer. */ "NOTIFICATIONS_FOOTER_WARNING" = "Due to known bugs in Apple's push framework, message previews will only be shown if the message is retrieved within 30 seconds after being sent. The application badge might be inaccurate as a result."; +/* Label for item that allows user to change the notification sound. */ +"NOTIFICATIONS_ITEM_SOUND" = "Sound"; + /* No comment provided by engineer. */ "NOTIFICATIONS_NONE" = "No name or message"; @@ -1155,6 +1158,9 @@ /* No comment provided by engineer. */ "NOTIFICATIONS_SECTION_INAPP" = "In-App Notifications"; +/* Label for settings UI allows user to change the notification sound. */ +"NOTIFICATIONS_SECTION_SOUNDS" = "Sounds"; + /* No comment provided by engineer. */ "NOTIFICATIONS_SENDER_AND_MESSAGE" = "Sender name & message"; @@ -1569,6 +1575,9 @@ /* Title for settings activity */ "SETTINGS_NAV_BAR_TITLE" = "Settings"; +/* No comment provided by engineer. */ +"SETTINGS_NOTIFICATION_SOUND" = "SETTINGS_NOTIFICATION_SOUND"; + /* No comment provided by engineer. */ "SETTINGS_NOTIFICATIONS" = "Notifications"; diff --git a/SignalMessaging/environment/NotificationSounds.h b/SignalMessaging/environment/NotificationSounds.h new file mode 100644 index 000000000..1e4c30327 --- /dev/null +++ b/SignalMessaging/environment/NotificationSounds.h @@ -0,0 +1,24 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +typedef NS_ENUM(NSUInteger, NotificationSound) { + NotificationSound_Aurora = 0, + NotificationSound_Default = NotificationSound_Aurora +}; + +NS_ASSUME_NONNULL_BEGIN + +@interface NotificationSounds : NSObject + +- (instancetype)init NS_UNAVAILABLE; + ++ (NSArray *)allNotificationSounds; + ++ (NSString *)displayNameForNotificationSound:(NotificationSound)notificationSound; + ++ (void)playNotificationSound:(NotificationSound)notificationSound; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SignalMessaging/environment/NotificationSounds.m b/SignalMessaging/environment/NotificationSounds.m new file mode 100644 index 000000000..3c5113278 --- /dev/null +++ b/SignalMessaging/environment/NotificationSounds.m @@ -0,0 +1,109 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +#import "NotificationSounds.h" +#import + +@interface NotificationSounds () + +@property (nonatomic) NSMutableDictionary *systemSoundIDMap; + +@end + +#pragma mark - + +@implementation NotificationSounds + ++ (instancetype)sharedManager +{ + static NotificationSounds *instance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + instance = [[self alloc] initDefault]; + }); + return instance; +} + +- (instancetype)initDefault +{ + self = [super init]; + + if (!self) { + return self; + } + + OWSSingletonAssert(); + + return self; +} + ++ (NSArray *)allNotificationSounds +{ + return @[ + @(NotificationSound_Aurora), + ]; +} + ++ (NSString *)displayNameForNotificationSound:(NotificationSound)notificationSound +{ + // TODO: Should we localize these sound names? + switch (notificationSound) { + case NotificationSound_Aurora: + return @"Aurora"; + } +} + +- (NSURL *)soundURLForNotificationSound:(NotificationSound)notificationSound +{ + NSString *bundlePath = [NSBundle mainBundle].bundlePath; + NSFileManager *fileManager = [NSFileManager defaultManager]; + for (NSString *filename in [fileManager contentsOfDirectoryAtPath:bundlePath error:nil]) { + DDLogInfo(@"%@ filename: %@", self.logTag, filename); + } + [DDLog flushLog]; + + NSURL *_Nullable url; + switch (notificationSound) { + case NotificationSound_Aurora: + url = [[NSBundle mainBundle] URLForResource:@"aurora" withExtension:@"m4r"]; + break; + } + OWSAssert(url); + return url; +} + ++ (void)playNotificationSound:(NotificationSound)notificationSound +{ + [self.sharedManager playNotificationSound:notificationSound]; +} + +- (SystemSoundID)systemSoundIDForNotificationSound:(NotificationSound)notificationSound +{ + @synchronized(self) + { + if (!self.systemSoundIDMap) { + self.systemSoundIDMap = [NSMutableDictionary new]; + } + NSNumber *_Nullable systemSoundID = self.systemSoundIDMap[@(notificationSound)]; + if (!systemSoundID) { + NSURL *soundURL = [self soundURLForNotificationSound:notificationSound]; + SystemSoundID newSystemSoundID; + OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)soundURL, &newSystemSoundID); + if (error) { + OWSFail(@"%@ could not load sound.", self.logTag); + } + systemSoundID = @(newSystemSoundID); + self.systemSoundIDMap[@(notificationSound)] = systemSoundID; + } + return (SystemSoundID)systemSoundID.unsignedIntegerValue; + } +} + +- (void)playNotificationSound:(NotificationSound)notificationSound +{ + SystemSoundID systemSoundID = [self systemSoundIDForNotificationSound:notificationSound]; + AudioServicesPlayAlertSound(systemSoundID); +} + +@end diff --git a/SignalMessaging/utils/OWSPreferences.h b/SignalMessaging/utils/OWSPreferences.h index 4000ae1a9..bee1339e9 100644 --- a/SignalMessaging/utils/OWSPreferences.h +++ b/SignalMessaging/utils/OWSPreferences.h @@ -2,6 +2,8 @@ // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // +#import "NotificationSounds.h" + NS_ASSUME_NONNULL_BEGIN /** @@ -55,6 +57,9 @@ extern NSString *const OWSPreferencesKeyEnableDebugLog; - (void)setIOSUpgradeNagDate:(NSDate *)value; - (nullable NSDate *)iOSUpgradeNagDate; +- (NotificationSound)globalNotificationSound; +- (void)setGlobalNotificationSound:(NotificationSound)notificationSound; + #pragma mark - Calling #pragma mark Callkit diff --git a/SignalMessaging/utils/OWSPreferences.m b/SignalMessaging/utils/OWSPreferences.m index ea084b5fb..050d46491 100644 --- a/SignalMessaging/utils/OWSPreferences.m +++ b/SignalMessaging/utils/OWSPreferences.m @@ -26,6 +26,7 @@ NSString *const OWSPreferencesKeyCallsHideIPAddress = @"CallsHideIPAddress"; NSString *const OWSPreferencesKeyHasDeclinedNoContactsView = @"hasDeclinedNoContactsView"; NSString *const OWSPreferencesKeyIOSUpgradeNagDate = @"iOSUpgradeNagDate"; NSString *const OWSPreferencesKey_IsReadyForAppExtensions = @"isReadyForAppExtensions_5"; +NSString *const OWSPreferencesKey_GlobalNotificationSound = @"GlobalNotificationSound"; @implementation OWSPreferences @@ -169,6 +170,17 @@ NSString *const OWSPreferencesKey_IsReadyForAppExtensions = @"isReadyForAppExten return [self tryGetValueForKey:OWSPreferencesKeyIOSUpgradeNagDate]; } +- (NotificationSound)globalNotificationSound +{ + NSNumber *value = [self tryGetValueForKey:OWSPreferencesKey_GlobalNotificationSound]; + return value ? (NotificationSound)[value intValue] : NotificationSound_Default; +} + +- (void)setGlobalNotificationSound:(NotificationSound)notificationSound +{ + [self setValueForKey:OWSPreferencesKey_GlobalNotificationSound toValue:@(notificationSound)]; +} + #pragma mark - Calling #pragma mark CallKit