Enable/update group call action based on current call and thread
This commit is contained in:
parent
485e12e6c4
commit
d93c19abe7
@ -7,6 +7,7 @@ import SignalRingRTC
|
||||
import PromiseKit
|
||||
|
||||
// All Observer methods will be invoked from the main thread.
|
||||
@objc(OWSCallServiceObserver)
|
||||
protocol CallServiceObserver: class {
|
||||
/**
|
||||
* Fired whenever the call changes.
|
||||
@ -138,6 +139,7 @@ public final class CallService: NSObject {
|
||||
private var observers = WeakArray<CallServiceObserver>()
|
||||
|
||||
// The observer-related methods should be invoked on the main thread.
|
||||
@objc
|
||||
func addObserverAndSyncState(observer: CallServiceObserver) {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
@ -148,6 +150,7 @@ public final class CallService: NSObject {
|
||||
}
|
||||
|
||||
// The observer-related methods should be invoked on the main thread.
|
||||
@objc
|
||||
func removeObserver(_ observer: CallServiceObserver) {
|
||||
AssertIsOnMainThread()
|
||||
observers.removeAll { $0 === observer }
|
||||
|
||||
@ -92,6 +92,7 @@ public class SignalCall: NSObject, CallManagerCallReference {
|
||||
didSet { AssertIsOnMainThread() }
|
||||
}
|
||||
|
||||
@objc
|
||||
public let thread: TSThread?
|
||||
|
||||
public var error: CallError?
|
||||
|
||||
@ -44,6 +44,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
- (void)conversationCell:(ConversationViewCell *)cell didEndLongpress:(id<ConversationViewItem>)viewItem;
|
||||
- (void)conversationCell:(ConversationViewCell *)cell didTapReactions:(id<ConversationViewItem>)viewItem;
|
||||
- (BOOL)conversationCellHasPendingMessageRequest:(ConversationViewCell *)cell;
|
||||
@property (nonatomic, readonly) BOOL isCallingSupported;
|
||||
|
||||
#pragma mark - Selection
|
||||
|
||||
|
||||
@ -791,6 +791,7 @@ typedef void (^SystemMessageActionBlock)(void);
|
||||
case RPRecentCallTypeIncomingAnsweredElsewhere:
|
||||
case RPRecentCallTypeIncomingDeclinedElsewhere:
|
||||
case RPRecentCallTypeIncomingBusyElsewhere:
|
||||
// If delegate is nil, include the action. This way we always oversize instead of undersize.
|
||||
if ([self.delegate conversationCellHasPendingMessageRequest:self]) {
|
||||
return nil;
|
||||
}
|
||||
@ -800,6 +801,7 @@ typedef void (^SystemMessageActionBlock)(void);
|
||||
accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME(self, @"call_back")];
|
||||
case RPRecentCallTypeOutgoing:
|
||||
case RPRecentCallTypeOutgoingMissed:
|
||||
// If delegate is nil, include the action. This way we always oversize instead of undersize.
|
||||
if ([self.delegate conversationCellHasPendingMessageRequest:self]) {
|
||||
return nil;
|
||||
}
|
||||
@ -815,21 +817,20 @@ typedef void (^SystemMessageActionBlock)(void);
|
||||
|
||||
- (nullable SystemMessageAction *)actionForGroupCall:(OWSGroupCallMessage *)groupCallMessage
|
||||
{
|
||||
// TODO: Check if the current call belongs to this thread.
|
||||
if (self.callService.currentCall != nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Assume the current thread supports calling if we have no delegate. This ensures we always
|
||||
// overestimate cell measurement in cases where the current thread doesn't support calling.
|
||||
BOOL isCallingSupported = !self.delegate || self.delegate.isCallingSupported;
|
||||
BOOL isCallActive = (!groupCallMessage.hasEnded && groupCallMessage.joinedMemberAddresses.count > 0);
|
||||
|
||||
// TODO: Respect -canCall from ConversationViewController
|
||||
// TODO: "Return to call" if for the current thread. Hide the action is currently in a call
|
||||
// For now we'll just check the feature flag
|
||||
BOOL canCall = SSKFeatureFlags.groupCalling;
|
||||
if (isCallingSupported && isCallActive) {
|
||||
NSString *currentCallThreadId = self.callService.currentCall.thread.uniqueId;
|
||||
BOOL isCurrentCallForThread = [currentCallThreadId isEqualToString:self.viewItem.thread.uniqueId];
|
||||
|
||||
NSString *joinTitle = NSLocalizedString(@"GROUP_CALL_JOIN_BUTTON", "Button to join an ongoing group call");
|
||||
NSString *returnTitle = NSLocalizedString(@"CALL_RETURN_BUTTON", "Button to return to the current call");
|
||||
NSString *actionTitle = isCurrentCallForThread ? returnTitle : joinTitle;
|
||||
|
||||
if (isCallActive && canCall) {
|
||||
__weak typeof(self) wSelf = self;
|
||||
NSString *actionTitle = NSLocalizedString(@"GROUP_CALL_JOIN_BUTTON", "Button to join an ongoing group call");
|
||||
return [SystemMessageAction actionWithTitle:actionTitle
|
||||
block:^{ [wSelf.delegate handleGroupCallTap]; }
|
||||
accessibilityIdentifier:actionTitle];
|
||||
|
||||
@ -1935,7 +1935,11 @@ typedef enum : NSUInteger {
|
||||
|
||||
- (void)handleGroupCallTap
|
||||
{
|
||||
[self showGroupCallLobby];
|
||||
if ([self.callService.currentCall.thread.uniqueId isEqualToString:self.thread.uniqueId]) {
|
||||
// TODO
|
||||
} else {
|
||||
[self showGroupCallLobby];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateSystemContactWithAddress:(SignalServiceAddress *)address
|
||||
@ -2281,6 +2285,11 @@ typedef enum : NSUInteger {
|
||||
return self.threadViewModel.hasPendingMessageRequest;
|
||||
}
|
||||
|
||||
- (BOOL)isCallingSupported
|
||||
{
|
||||
return [self canCall];
|
||||
}
|
||||
|
||||
- (BOOL)isShowingSelectionUI
|
||||
{
|
||||
return self.uiMode == ConversationUIMode_Selection;
|
||||
|
||||
@ -144,7 +144,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface ConversationViewModel () <UIDatabaseSnapshotDelegate>
|
||||
@interface ConversationViewModel () <UIDatabaseSnapshotDelegate, OWSCallServiceObserver>
|
||||
|
||||
@property (nonatomic, weak) id<ConversationViewModelDelegate> delegate;
|
||||
|
||||
@ -241,6 +241,11 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
return [OWSProfileManager shared];
|
||||
}
|
||||
|
||||
- (CallService *)callService
|
||||
{
|
||||
return AppEnvironment.shared.callService;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)addNotificationListeners
|
||||
@ -265,6 +270,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
selector:@selector(localProfileDidChange:)
|
||||
name:kNSNotificationNameLocalProfileDidChange
|
||||
object:nil];
|
||||
[self.callService addObserverAndSyncStateWithObserver:self];
|
||||
}
|
||||
|
||||
- (void)profileWhitelistDidChange:(NSNotification *)notification
|
||||
@ -326,6 +332,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self.callService removeObserver:self];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
@ -1279,6 +1286,12 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
viewItem.senderProfileName = [self.profileManager fullNameForAddress:infoMessage.profileChangeAddress
|
||||
transaction:transaction];
|
||||
}
|
||||
} else if (interactionType == OWSInteractionType_Call) {
|
||||
NSString *activeCallThreadId = self.callService.currentCall.thread.uniqueId;
|
||||
BOOL isAnotherThreadInCall = activeCallThreadId && ![self.thread.uniqueId isEqualToString:activeCallThreadId];
|
||||
|
||||
BOOL wasCollapsed = viewItem.shouldCollapseSystemMessageAction;
|
||||
viewItem.shouldCollapseSystemMessageAction = wasCollapsed || isAnotherThreadInCall;
|
||||
}
|
||||
|
||||
uint64_t collapseCutoffTimestamp = [NSDate ows_millisecondsSince1970ForDate:self.collapseCutoffDate];
|
||||
@ -1494,6 +1507,18 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
return !self.canLoadOlderItems;
|
||||
}
|
||||
|
||||
#pragma mark - <OWSCallServiceObserver>
|
||||
|
||||
- (void)didUpdateCallFrom:(nullable SignalCall *)oldValue to:(nullable SignalCall *)newValue
|
||||
{
|
||||
// If the call state changed for the current thread, we may want to hide the Call action.
|
||||
// When registering, CallObserver sends the currentCall synchronously. Since we register
|
||||
// during -viewDidLoad, ordering gets a bit messed up. It's okay if we async for a bit later.
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self updateForTransientItems];
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -481,6 +481,9 @@
|
||||
/* notification body */
|
||||
"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Missed call because the caller's safety number changed.";
|
||||
|
||||
/* Button to return to the current call */
|
||||
"CALL_RETURN_BUTTON" = "Return To Call";
|
||||
|
||||
/* Call setup status label after outgoing call times out */
|
||||
"CALL_SCREEN_STATUS_NO_ANSWER" = "No Answer";
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user