mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Conference updates
This commit is contained in:
parent
7b1c4595b8
commit
cd30285d87
@ -108,7 +108,8 @@ public final class CallListController: TelegramBaseController {
|
|||||||
self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style
|
self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style
|
||||||
|
|
||||||
if case .tab = self.mode {
|
if case .tab = self.mode {
|
||||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.callPressed))
|
//self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.callPressed))
|
||||||
|
self.navigationItem.rightBarButtonItem = nil
|
||||||
|
|
||||||
let icon: UIImage?
|
let icon: UIImage?
|
||||||
if useSpecialTabBarIcons() {
|
if useSpecialTabBarIcons() {
|
||||||
@ -191,7 +192,7 @@ public final class CallListController: TelegramBaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.callPressed))
|
//self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.callPressed))
|
||||||
case .navigation:
|
case .navigation:
|
||||||
if self.editingMode {
|
if self.editingMode {
|
||||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Done, style: .done, target: self, action: #selector(self.donePressed))
|
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Done, style: .done, target: self, action: #selector(self.donePressed))
|
||||||
@ -383,7 +384,8 @@ public final class CallListController: TelegramBaseController {
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
strongSelf.navigationItem.setLeftBarButton(UIBarButtonItem(title: strongSelf.presentationData.strings.Common_Edit, style: .plain, target: strongSelf, action: #selector(strongSelf.editPressed)), animated: true)
|
strongSelf.navigationItem.setLeftBarButton(UIBarButtonItem(title: strongSelf.presentationData.strings.Common_Edit, style: .plain, target: strongSelf, action: #selector(strongSelf.editPressed)), animated: true)
|
||||||
strongSelf.navigationItem.setRightBarButton(UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(strongSelf.presentationData.theme), style: .plain, target: self, action: #selector(strongSelf.callPressed)), animated: true)
|
//strongSelf.navigationItem.setRightBarButton(UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(strongSelf.presentationData.theme), style: .plain, target: self, action: #selector(strongSelf.callPressed)), animated: true)
|
||||||
|
strongSelf.navigationItem.setRightBarButton(nil, animated: true)
|
||||||
}
|
}
|
||||||
case .navigation:
|
case .navigation:
|
||||||
if strongSelf.editingMode {
|
if strongSelf.editingMode {
|
||||||
@ -399,9 +401,9 @@ public final class CallListController: TelegramBaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, createGroupCall: { [weak self] in
|
}, openNewCall: { [weak self] in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.createGroupCall(peerIds: [], isVideo: false)
|
strongSelf.callPressed()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -652,7 +654,8 @@ public final class CallListController: TelegramBaseController {
|
|||||||
switch self.mode {
|
switch self.mode {
|
||||||
case .tab:
|
case .tab:
|
||||||
self.navigationItem.setLeftBarButton(UIBarButtonItem(title: self.presentationData.strings.Common_Edit, style: .plain, target: self, action: #selector(self.editPressed)), animated: true)
|
self.navigationItem.setLeftBarButton(UIBarButtonItem(title: self.presentationData.strings.Common_Edit, style: .plain, target: self, action: #selector(self.editPressed)), animated: true)
|
||||||
self.navigationItem.setRightBarButton(UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.callPressed)), animated: true)
|
self.navigationItem.setRightBarButton(nil, animated: true)
|
||||||
|
//self.navigationItem.setRightBarButton(UIBarButtonItem(image: PresentationResourcesRootController.navigationCallIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.callPressed)), animated: true)
|
||||||
case .navigation:
|
case .navigation:
|
||||||
self.navigationItem.setLeftBarButton(nil, animated: true)
|
self.navigationItem.setLeftBarButton(nil, animated: true)
|
||||||
self.navigationItem.setRightBarButton(UIBarButtonItem(title: self.presentationData.strings.Common_Edit, style: .plain, target: self, action: #selector(self.editPressed)), animated: true)
|
self.navigationItem.setRightBarButton(UIBarButtonItem(title: self.presentationData.strings.Common_Edit, style: .plain, target: self, action: #selector(self.editPressed)), animated: true)
|
||||||
|
@ -67,16 +67,16 @@ final class CallListNodeInteraction {
|
|||||||
let delete: ([EngineMessage.Id]) -> Void
|
let delete: ([EngineMessage.Id]) -> Void
|
||||||
let updateShowCallsTab: (Bool) -> Void
|
let updateShowCallsTab: (Bool) -> Void
|
||||||
let openGroupCall: (EnginePeer.Id) -> Void
|
let openGroupCall: (EnginePeer.Id) -> Void
|
||||||
let createGroupCall: () -> Void
|
let openNewCall: () -> Void
|
||||||
|
|
||||||
init(setMessageIdWithRevealedOptions: @escaping (EngineMessage.Id?, EngineMessage.Id?) -> Void, call: @escaping (EngineMessage) -> Void, openInfo: @escaping (EnginePeer.Id, [EngineMessage]) -> Void, delete: @escaping ([EngineMessage.Id]) -> Void, updateShowCallsTab: @escaping (Bool) -> Void, openGroupCall: @escaping (EnginePeer.Id) -> Void, createGroupCall: @escaping () -> Void) {
|
init(setMessageIdWithRevealedOptions: @escaping (EngineMessage.Id?, EngineMessage.Id?) -> Void, call: @escaping (EngineMessage) -> Void, openInfo: @escaping (EnginePeer.Id, [EngineMessage]) -> Void, delete: @escaping ([EngineMessage.Id]) -> Void, updateShowCallsTab: @escaping (Bool) -> Void, openGroupCall: @escaping (EnginePeer.Id) -> Void, openNewCall: @escaping () -> Void) {
|
||||||
self.setMessageIdWithRevealedOptions = setMessageIdWithRevealedOptions
|
self.setMessageIdWithRevealedOptions = setMessageIdWithRevealedOptions
|
||||||
self.call = call
|
self.call = call
|
||||||
self.openInfo = openInfo
|
self.openInfo = openInfo
|
||||||
self.delete = delete
|
self.delete = delete
|
||||||
self.updateShowCallsTab = updateShowCallsTab
|
self.updateShowCallsTab = updateShowCallsTab
|
||||||
self.openGroupCall = openGroupCall
|
self.openGroupCall = openGroupCall
|
||||||
self.createGroupCall = createGroupCall
|
self.openNewCall = openNewCall
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,10 +125,10 @@ private func mappedInsertEntries(context: AccountContext, presentationData: Item
|
|||||||
}), directionHint: entry.directionHint)
|
}), directionHint: entry.directionHint)
|
||||||
case let .displayTabInfo(_, text):
|
case let .displayTabInfo(_, text):
|
||||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: 0), directionHint: entry.directionHint)
|
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: 0), directionHint: entry.directionHint)
|
||||||
case .createGroupCall:
|
case .openNewCall:
|
||||||
//TODO:localize
|
//TODO:localize
|
||||||
let item = ItemListPeerActionItem(presentationData: presentationData, style: showSettings ? .blocks : .plain, icon: PresentationResourcesItemList.linkIcon(presentationData.theme), title: "New Call Link", hasSeparator: false, sectionId: 1, noInsets: true, editing: false, action: {
|
let item = ItemListPeerActionItem(presentationData: presentationData, style: showSettings ? .blocks : .plain, icon: .none, title: "New Call", hasSeparator: false, sectionId: 1, height: .generic, noInsets: true, editing: false, action: {
|
||||||
nodeInteraction.createGroupCall()
|
nodeInteraction.openNewCall()
|
||||||
})
|
})
|
||||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint)
|
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint)
|
||||||
case let .groupCall(peer, _, isActive):
|
case let .groupCall(peer, _, isActive):
|
||||||
@ -150,10 +150,10 @@ private func mappedUpdateEntries(context: AccountContext, presentationData: Item
|
|||||||
}), directionHint: entry.directionHint)
|
}), directionHint: entry.directionHint)
|
||||||
case let .displayTabInfo(_, text):
|
case let .displayTabInfo(_, text):
|
||||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: 0), directionHint: entry.directionHint)
|
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: 0), directionHint: entry.directionHint)
|
||||||
case .createGroupCall:
|
case .openNewCall:
|
||||||
//TODO:localize
|
//TODO:localize
|
||||||
let item = ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.linkIcon(presentationData.theme), title: "New Call Link", sectionId: 1, noInsets: true, editing: false, action: {
|
let item = ItemListPeerActionItem(presentationData: presentationData, icon: .none, title: "New Call", sectionId: 1, height: .generic, noInsets: true, editing: false, action: {
|
||||||
nodeInteraction.createGroupCall()
|
nodeInteraction.openNewCall()
|
||||||
})
|
})
|
||||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint)
|
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint)
|
||||||
case let .groupCall(peer, _, isActive):
|
case let .groupCall(peer, _, isActive):
|
||||||
@ -224,7 +224,7 @@ final class CallListControllerNode: ASDisplayNode {
|
|||||||
|
|
||||||
private let call: (EngineMessage) -> Void
|
private let call: (EngineMessage) -> Void
|
||||||
private let joinGroupCall: (EnginePeer.Id, EngineGroupCallDescription) -> Void
|
private let joinGroupCall: (EnginePeer.Id, EngineGroupCallDescription) -> Void
|
||||||
private let createGroupCall: () -> Void
|
private let openNewCall: () -> Void
|
||||||
private let openInfo: (EnginePeer.Id, [EngineMessage]) -> Void
|
private let openInfo: (EnginePeer.Id, [EngineMessage]) -> Void
|
||||||
private let emptyStateUpdated: (Bool) -> Void
|
private let emptyStateUpdated: (Bool) -> Void
|
||||||
private let emptyStatePromise = Promise<Bool>()
|
private let emptyStatePromise = Promise<Bool>()
|
||||||
@ -234,7 +234,7 @@ final class CallListControllerNode: ASDisplayNode {
|
|||||||
|
|
||||||
private var previousContentOffset: ListViewVisibleContentOffset?
|
private var previousContentOffset: ListViewVisibleContentOffset?
|
||||||
|
|
||||||
init(controller: CallListController, context: AccountContext, mode: CallListControllerMode, presentationData: PresentationData, call: @escaping (EngineMessage) -> Void, joinGroupCall: @escaping (EnginePeer.Id, EngineGroupCallDescription) -> Void, openInfo: @escaping (EnginePeer.Id, [EngineMessage]) -> Void, emptyStateUpdated: @escaping (Bool) -> Void, createGroupCall: @escaping () -> Void) {
|
init(controller: CallListController, context: AccountContext, mode: CallListControllerMode, presentationData: PresentationData, call: @escaping (EngineMessage) -> Void, joinGroupCall: @escaping (EnginePeer.Id, EngineGroupCallDescription) -> Void, openInfo: @escaping (EnginePeer.Id, [EngineMessage]) -> Void, emptyStateUpdated: @escaping (Bool) -> Void, openNewCall: @escaping () -> Void) {
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.context = context
|
self.context = context
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
@ -243,7 +243,7 @@ final class CallListControllerNode: ASDisplayNode {
|
|||||||
self.joinGroupCall = joinGroupCall
|
self.joinGroupCall = joinGroupCall
|
||||||
self.openInfo = openInfo
|
self.openInfo = openInfo
|
||||||
self.emptyStateUpdated = emptyStateUpdated
|
self.emptyStateUpdated = emptyStateUpdated
|
||||||
self.createGroupCall = createGroupCall
|
self.openNewCall = openNewCall
|
||||||
self.currentState = CallListNodeState(presentationData: ItemListPresentationData(presentationData), dateTimeFormat: presentationData.dateTimeFormat, disableAnimations: true, editing: false, messageIdWithRevealedOptions: nil)
|
self.currentState = CallListNodeState(presentationData: ItemListPresentationData(presentationData), dateTimeFormat: presentationData.dateTimeFormat, disableAnimations: true, editing: false, messageIdWithRevealedOptions: nil)
|
||||||
self.statePromise = ValuePromise(self.currentState, ignoreRepeated: true)
|
self.statePromise = ValuePromise(self.currentState, ignoreRepeated: true)
|
||||||
|
|
||||||
@ -447,11 +447,11 @@ final class CallListControllerNode: ASDisplayNode {
|
|||||||
strongSelf.joinGroupCall(peerId, activeCall)
|
strongSelf.joinGroupCall(peerId, activeCall)
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}, createGroupCall: { [weak self] in
|
}, openNewCall: { [weak self] in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
strongSelf.createGroupCall()
|
strongSelf.openNewCall()
|
||||||
})
|
})
|
||||||
|
|
||||||
let viewProcessingQueue = self.viewProcessingQueue
|
let viewProcessingQueue = self.viewProcessingQueue
|
||||||
@ -517,27 +517,17 @@ final class CallListControllerNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
|
|
||||||
let canCreateGroupCall = context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.App())
|
|
||||||
|> map { configuration -> Bool in
|
|
||||||
var isConferencePossible = true
|
|
||||||
if let data = configuration.data, let value = data["ios_enable_conference"] as? Double {
|
|
||||||
isConferencePossible = value != 0.0
|
|
||||||
}
|
|
||||||
return isConferencePossible
|
|
||||||
}
|
|
||||||
|
|
||||||
let callListNodeViewTransition = combineLatest(
|
let callListNodeViewTransition = combineLatest(
|
||||||
callListViewUpdate,
|
callListViewUpdate,
|
||||||
self.statePromise.get(),
|
self.statePromise.get(),
|
||||||
groupCalls,
|
groupCalls,
|
||||||
showCallsTab,
|
showCallsTab,
|
||||||
currentGroupCallPeerId,
|
currentGroupCallPeerId
|
||||||
canCreateGroupCall
|
|
||||||
)
|
)
|
||||||
|> mapToQueue { (updateAndType, state, groupCalls, showCallsTab, currentGroupCallPeerId, canCreateGroupCall) -> Signal<CallListNodeListViewTransition, NoError> in
|
|> mapToQueue { (updateAndType, state, groupCalls, showCallsTab, currentGroupCallPeerId) -> Signal<CallListNodeListViewTransition, NoError> in
|
||||||
let (update, type) = updateAndType
|
let (update, type) = updateAndType
|
||||||
|
|
||||||
let processedView = CallListNodeView(originalView: update.view, filteredEntries: callListNodeEntriesForView(view: update.view, canCreateGroupCall: canCreateGroupCall && mode == .tab, groupCalls: groupCalls, state: state, showSettings: showSettings, showCallsTab: showCallsTab, isRecentCalls: type == .all, currentGroupCallPeerId: currentGroupCallPeerId), presentationData: state.presentationData)
|
let processedView = CallListNodeView(originalView: update.view, filteredEntries: callListNodeEntriesForView(view: update.view, displayOpenNewCall: mode == .tab, groupCalls: groupCalls, state: state, showSettings: showSettings, showCallsTab: showCallsTab, isRecentCalls: type == .all, currentGroupCallPeerId: currentGroupCallPeerId), presentationData: state.presentationData)
|
||||||
let previous = previousView.swap(processedView)
|
let previous = previousView.swap(processedView)
|
||||||
let previousType = previousType.swap(type)
|
let previousType = previousType.swap(type)
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ enum CallListNodeEntry: Comparable, Identifiable {
|
|||||||
enum SortIndex: Comparable {
|
enum SortIndex: Comparable {
|
||||||
case displayTab
|
case displayTab
|
||||||
case displayTabInfo
|
case displayTabInfo
|
||||||
case createGroupCall
|
case openNewCall
|
||||||
case groupCall(EnginePeer.Id, String)
|
case groupCall(EnginePeer.Id, String)
|
||||||
case message(EngineMessage.Index)
|
case message(EngineMessage.Index)
|
||||||
case hole(EngineMessage.Index)
|
case hole(EngineMessage.Index)
|
||||||
@ -41,7 +41,7 @@ enum CallListNodeEntry: Comparable, Identifiable {
|
|||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case .createGroupCall:
|
case .openNewCall:
|
||||||
switch rhs {
|
switch rhs {
|
||||||
case .displayTab, .displayTabInfo:
|
case .displayTab, .displayTabInfo:
|
||||||
return false
|
return false
|
||||||
@ -50,7 +50,7 @@ enum CallListNodeEntry: Comparable, Identifiable {
|
|||||||
}
|
}
|
||||||
case let .groupCall(lhsPeerId, lhsTitle):
|
case let .groupCall(lhsPeerId, lhsTitle):
|
||||||
switch rhs {
|
switch rhs {
|
||||||
case .displayTab, .displayTabInfo, .createGroupCall:
|
case .displayTab, .displayTabInfo, .openNewCall:
|
||||||
return false
|
return false
|
||||||
case let .groupCall(rhsPeerId, rhsTitle):
|
case let .groupCall(rhsPeerId, rhsTitle):
|
||||||
if lhsTitle == rhsTitle {
|
if lhsTitle == rhsTitle {
|
||||||
@ -63,7 +63,7 @@ enum CallListNodeEntry: Comparable, Identifiable {
|
|||||||
}
|
}
|
||||||
case let .hole(lhsIndex):
|
case let .hole(lhsIndex):
|
||||||
switch rhs {
|
switch rhs {
|
||||||
case .displayTab, .displayTabInfo, .groupCall, .createGroupCall:
|
case .displayTab, .displayTabInfo, .groupCall, .openNewCall:
|
||||||
return false
|
return false
|
||||||
case let .hole(rhsIndex):
|
case let .hole(rhsIndex):
|
||||||
return lhsIndex < rhsIndex
|
return lhsIndex < rhsIndex
|
||||||
@ -72,7 +72,7 @@ enum CallListNodeEntry: Comparable, Identifiable {
|
|||||||
}
|
}
|
||||||
case let .message(lhsIndex):
|
case let .message(lhsIndex):
|
||||||
switch rhs {
|
switch rhs {
|
||||||
case .displayTab, .displayTabInfo, .groupCall, .createGroupCall:
|
case .displayTab, .displayTabInfo, .groupCall, .openNewCall:
|
||||||
return false
|
return false
|
||||||
case let .hole(rhsIndex):
|
case let .hole(rhsIndex):
|
||||||
return lhsIndex < rhsIndex
|
return lhsIndex < rhsIndex
|
||||||
@ -86,7 +86,7 @@ enum CallListNodeEntry: Comparable, Identifiable {
|
|||||||
|
|
||||||
case displayTab(PresentationTheme, String, Bool)
|
case displayTab(PresentationTheme, String, Bool)
|
||||||
case displayTabInfo(PresentationTheme, String)
|
case displayTabInfo(PresentationTheme, String)
|
||||||
case createGroupCall
|
case openNewCall
|
||||||
case groupCall(peer: EnginePeer, editing: Bool, isActive: Bool)
|
case groupCall(peer: EnginePeer, editing: Bool, isActive: Bool)
|
||||||
case messageEntry(topMessage: EngineMessage, messages: [EngineMessage], theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, editing: Bool, hasActiveRevealControls: Bool, displayHeader: Bool, missed: Bool)
|
case messageEntry(topMessage: EngineMessage, messages: [EngineMessage], theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, editing: Bool, hasActiveRevealControls: Bool, displayHeader: Bool, missed: Bool)
|
||||||
case holeEntry(index: EngineMessage.Index, theme: PresentationTheme)
|
case holeEntry(index: EngineMessage.Index, theme: PresentationTheme)
|
||||||
@ -97,8 +97,8 @@ enum CallListNodeEntry: Comparable, Identifiable {
|
|||||||
return .displayTab
|
return .displayTab
|
||||||
case .displayTabInfo:
|
case .displayTabInfo:
|
||||||
return .displayTabInfo
|
return .displayTabInfo
|
||||||
case .createGroupCall:
|
case .openNewCall:
|
||||||
return .createGroupCall
|
return .openNewCall
|
||||||
case let .groupCall(peer, _, _):
|
case let .groupCall(peer, _, _):
|
||||||
return .groupCall(peer.id, peer.compactDisplayTitle)
|
return .groupCall(peer.id, peer.compactDisplayTitle)
|
||||||
case let .messageEntry(message, _, _, _, _, _, _, _, _):
|
case let .messageEntry(message, _, _, _, _, _, _, _, _):
|
||||||
@ -114,7 +114,7 @@ enum CallListNodeEntry: Comparable, Identifiable {
|
|||||||
return .setting(0)
|
return .setting(0)
|
||||||
case .displayTabInfo:
|
case .displayTabInfo:
|
||||||
return .setting(1)
|
return .setting(1)
|
||||||
case .createGroupCall:
|
case .openNewCall:
|
||||||
return .setting(2)
|
return .setting(2)
|
||||||
case let .groupCall(peer, _, _):
|
case let .groupCall(peer, _, _):
|
||||||
return .groupCall(peer.id)
|
return .groupCall(peer.id)
|
||||||
@ -143,8 +143,8 @@ enum CallListNodeEntry: Comparable, Identifiable {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case .createGroupCall:
|
case .openNewCall:
|
||||||
if case .createGroupCall = rhs {
|
if case .openNewCall = rhs {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@ -212,7 +212,7 @@ enum CallListNodeEntry: Comparable, Identifiable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func callListNodeEntriesForView(view: EngineCallList, canCreateGroupCall: Bool, groupCalls: [EnginePeer], state: CallListNodeState, showSettings: Bool, showCallsTab: Bool, isRecentCalls: Bool, currentGroupCallPeerId: EnginePeer.Id?) -> [CallListNodeEntry] {
|
func callListNodeEntriesForView(view: EngineCallList, displayOpenNewCall: Bool, groupCalls: [EnginePeer], state: CallListNodeState, showSettings: Bool, showCallsTab: Bool, isRecentCalls: Bool, currentGroupCallPeerId: EnginePeer.Id?) -> [CallListNodeEntry] {
|
||||||
var result: [CallListNodeEntry] = []
|
var result: [CallListNodeEntry] = []
|
||||||
for entry in view.items {
|
for entry in view.items {
|
||||||
switch entry {
|
switch entry {
|
||||||
@ -237,8 +237,8 @@ func callListNodeEntriesForView(view: EngineCallList, canCreateGroupCall: Bool,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if canCreateGroupCall {
|
if displayOpenNewCall {
|
||||||
result.append(.createGroupCall)
|
result.append(.openNewCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
if showSettings {
|
if showSettings {
|
||||||
|
@ -210,6 +210,11 @@ private final class PendingConferenceInvitationContext {
|
|||||||
case ringing
|
case ringing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum InvitationError {
|
||||||
|
case generic
|
||||||
|
case privacy(peer: EnginePeer?)
|
||||||
|
}
|
||||||
|
|
||||||
private let engine: TelegramEngine
|
private let engine: TelegramEngine
|
||||||
private var requestDisposable: Disposable?
|
private var requestDisposable: Disposable?
|
||||||
private var stateDisposable: Disposable?
|
private var stateDisposable: Disposable?
|
||||||
@ -218,19 +223,12 @@ private final class PendingConferenceInvitationContext {
|
|||||||
private var hadMessage: Bool = false
|
private var hadMessage: Bool = false
|
||||||
private var didNotifyEnded: Bool = false
|
private var didNotifyEnded: Bool = false
|
||||||
|
|
||||||
init(engine: TelegramEngine, reference: InternalGroupCallReference, peerId: PeerId, isVideo: Bool, onStateUpdated: @escaping (State) -> Void, onEnded: @escaping (Bool) -> Void) {
|
init(engine: TelegramEngine, reference: InternalGroupCallReference, peerId: PeerId, isVideo: Bool, onStateUpdated: @escaping (State) -> Void, onEnded: @escaping (Bool) -> Void, onError: @escaping (InvitationError) -> Void) {
|
||||||
self.engine = engine
|
self.engine = engine
|
||||||
self.requestDisposable = (engine.calls.inviteConferenceCallParticipant(reference: reference, peerId: peerId, isVideo: isVideo).startStrict(next: { [weak self] messageId in
|
self.requestDisposable = ((engine.calls.inviteConferenceCallParticipant(reference: reference, peerId: peerId, isVideo: isVideo) |> deliverOnMainQueue).startStrict(next: { [weak self] messageId in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
guard let messageId else {
|
|
||||||
if !self.didNotifyEnded {
|
|
||||||
self.didNotifyEnded = true
|
|
||||||
onEnded(false)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
self.messageId = messageId
|
self.messageId = messageId
|
||||||
|
|
||||||
onStateUpdated(.ringing)
|
onStateUpdated(.ringing)
|
||||||
@ -296,6 +294,24 @@ private final class PendingConferenceInvitationContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}, error: { [weak self] error in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.didNotifyEnded {
|
||||||
|
self.didNotifyEnded = true
|
||||||
|
onEnded(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
let mappedError: InvitationError
|
||||||
|
switch error {
|
||||||
|
case .privacy(let peer):
|
||||||
|
mappedError = .privacy(peer: peer)
|
||||||
|
default:
|
||||||
|
mappedError = .generic
|
||||||
|
}
|
||||||
|
onError(mappedError)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -792,6 +808,8 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
|
|
||||||
private let e2eContext: ConferenceCallE2EContext?
|
private let e2eContext: ConferenceCallE2EContext?
|
||||||
|
|
||||||
|
private var lastErrorAlertTimestamp: Double = 0.0
|
||||||
|
|
||||||
init(
|
init(
|
||||||
accountContext: AccountContext,
|
accountContext: AccountContext,
|
||||||
audioSession: ManagedAudioSession,
|
audioSession: ManagedAudioSession,
|
||||||
@ -3536,6 +3554,33 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
onEnded: { success in
|
onEnded: { success in
|
||||||
didEndAlready = true
|
didEndAlready = true
|
||||||
onEnded?(success)
|
onEnded?(success)
|
||||||
|
},
|
||||||
|
onError: { [weak self] error in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let timestamp = CACurrentMediaTime()
|
||||||
|
if self.lastErrorAlertTimestamp > timestamp - 1.0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.lastErrorAlertTimestamp = timestamp
|
||||||
|
|
||||||
|
let presentationData = self.accountContext.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: defaultDarkColorPresentationTheme)
|
||||||
|
|
||||||
|
//TODO:localize
|
||||||
|
var errorText = "An error occurred"
|
||||||
|
switch error {
|
||||||
|
case let .privacy(peer):
|
||||||
|
if let peer {
|
||||||
|
errorText = presentationData.strings.Call_PrivacyErrorMessage(peer.compactDisplayTitle).string
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
self.accountContext.sharedContext.mainWindow?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [
|
||||||
|
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})
|
||||||
|
]), on: .root, blockInteraction: false, completion: {})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if !didEndAlready {
|
if !didEndAlready {
|
||||||
|
@ -882,13 +882,19 @@ func _internal_joinGroupCall(account: Account, peerId: PeerId?, joinAs: PeerId?,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func _internal_inviteConferenceCallParticipant(account: Account, reference: InternalGroupCallReference, peerId: EnginePeer.Id, isVideo: Bool) -> Signal<MessageId?, NoError> {
|
public enum InviteConferenceCallParticipantError {
|
||||||
|
case generic
|
||||||
|
case privacy(peer: EnginePeer?)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _internal_inviteConferenceCallParticipant(account: Account, reference: InternalGroupCallReference, peerId: EnginePeer.Id, isVideo: Bool) -> Signal<MessageId, InviteConferenceCallParticipantError> {
|
||||||
return account.postbox.transaction { transaction -> Api.InputUser? in
|
return account.postbox.transaction { transaction -> Api.InputUser? in
|
||||||
return transaction.getPeer(peerId).flatMap(apiInputUser)
|
return transaction.getPeer(peerId).flatMap(apiInputUser)
|
||||||
}
|
}
|
||||||
|> mapToSignal { inputPeer -> Signal<MessageId?, NoError> in
|
|> castError(InviteConferenceCallParticipantError.self)
|
||||||
|
|> mapToSignal { inputPeer -> Signal<MessageId, InviteConferenceCallParticipantError> in
|
||||||
guard let inputPeer else {
|
guard let inputPeer else {
|
||||||
return .complete()
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags: Int32 = 0
|
var flags: Int32 = 0
|
||||||
@ -897,17 +903,26 @@ func _internal_inviteConferenceCallParticipant(account: Account, reference: Inte
|
|||||||
}
|
}
|
||||||
return account.network.request(Api.functions.phone.inviteConferenceCallParticipant(flags: flags, call: reference.apiInputGroupCall, userId: inputPeer))
|
return account.network.request(Api.functions.phone.inviteConferenceCallParticipant(flags: flags, call: reference.apiInputGroupCall, userId: inputPeer))
|
||||||
|> map(Optional.init)
|
|> map(Optional.init)
|
||||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
|> `catch` { error -> Signal<Api.Updates?, InviteConferenceCallParticipantError> in
|
||||||
return .single(nil)
|
if error.errorDescription == "USER_PRIVACY_RESTRICTED" {
|
||||||
|
return account.postbox.transaction { transaction -> InviteConferenceCallParticipantError in
|
||||||
|
return .privacy(peer: transaction.getPeer(peerId).flatMap(EnginePeer.init))
|
||||||
}
|
}
|
||||||
|> mapToSignal { result -> Signal<MessageId?, NoError> in
|
|> castError(InviteConferenceCallParticipantError.self)
|
||||||
|
|> mapToSignal { error -> Signal<Api.Updates?, InviteConferenceCallParticipantError> in
|
||||||
|
return .fail(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return .fail(.generic)
|
||||||
|
}
|
||||||
|
|> mapToSignal { result -> Signal<MessageId, InviteConferenceCallParticipantError> in
|
||||||
if let result {
|
if let result {
|
||||||
account.stateManager.addUpdates(result)
|
account.stateManager.addUpdates(result)
|
||||||
if let message = result.messageIds.first {
|
if let message = result.messageIds.first {
|
||||||
return .single(message)
|
return .single(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return .single(nil)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ public extension TelegramEngine {
|
|||||||
return _internal_sendConferenceCallBroadcast(account: self.account, callId: callId, accessHash: accessHash, block: block)
|
return _internal_sendConferenceCallBroadcast(account: self.account, callId: callId, accessHash: accessHash, block: block)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func inviteConferenceCallParticipant(reference: InternalGroupCallReference, peerId: EnginePeer.Id, isVideo: Bool) -> Signal<EngineMessage.Id?, NoError> {
|
public func inviteConferenceCallParticipant(reference: InternalGroupCallReference, peerId: EnginePeer.Id, isVideo: Bool) -> Signal<EngineMessage.Id, InviteConferenceCallParticipantError> {
|
||||||
return _internal_inviteConferenceCallParticipant(account: self.account, reference: reference, peerId: peerId, isVideo: isVideo)
|
return _internal_inviteConferenceCallParticipant(account: self.account, reference: reference, peerId: peerId, isVideo: isVideo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user