mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-04 21:41:45 +00:00
Merge commit '7b5f9a89b2d88fc75f7e7941c9114624574f40a3'
This commit is contained in:
commit
64ab80da02
@ -973,7 +973,7 @@ public protocol MediaEditorScreenResult {
|
||||
|
||||
public protocol TelegramRootControllerInterface: NavigationController {
|
||||
@discardableResult
|
||||
func openStoryCamera(customTarget: Stories.PendingTarget?, transitionIn: StoryCameraTransitionIn?, transitionedIn: @escaping () -> Void, transitionOut: @escaping (Stories.PendingTarget?, Bool) -> StoryCameraTransitionOut?) -> StoryCameraTransitionInCoordinator?
|
||||
func openStoryCamera(customTarget: Stories.PendingTarget?, resumeLiveStream: Bool, transitionIn: StoryCameraTransitionIn?, transitionedIn: @escaping () -> Void, transitionOut: @escaping (Stories.PendingTarget?, Bool) -> StoryCameraTransitionOut?) -> StoryCameraTransitionInCoordinator?
|
||||
func proceedWithStoryUpload(target: Stories.PendingTarget, results: [MediaEditorScreenResult], existingMedia: EngineMedia?, forwardInfo: Stories.PendingForwardInfo?, externalState: MediaEditorTransitionOutExternalState, commit: @escaping (@escaping () -> Void) -> Void)
|
||||
|
||||
func getContactsController() -> ViewController?
|
||||
|
||||
@ -2909,6 +2909,11 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
var premiumNeeded = false
|
||||
var hasActiveCall = false
|
||||
var hasActiveGroupCall = false
|
||||
var hasLiveStream = false
|
||||
|
||||
if let componentView = self.chatListHeaderView(), let storyPeerListView = componentView.storyPeerListView(), storyPeerListView.isLiveStreaming {
|
||||
hasLiveStream = true
|
||||
}
|
||||
|
||||
let storiesCountLimit = self.context.userLimits.maxExpiringStoriesCount
|
||||
var storiesCount = 0
|
||||
@ -2938,7 +2943,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
}
|
||||
|
||||
if reachedCountLimit {
|
||||
if !hasLiveStream && reachedCountLimit {
|
||||
let context = self.context
|
||||
var replaceImpl: ((ViewController) -> Void)?
|
||||
let controller = PremiumLimitScreen(context: context, subject: .expiringStories, count: Int32(storiesCount), action: {
|
||||
@ -2955,7 +2960,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
return
|
||||
}
|
||||
|
||||
if premiumNeeded || hasActiveCall || hasActiveGroupCall {
|
||||
if !hasLiveStream && (premiumNeeded || hasActiveCall || hasActiveGroupCall) {
|
||||
if let storyCameraTooltip = self.storyCameraTooltip {
|
||||
self.storyCameraTooltip = nil
|
||||
storyCameraTooltip.dismiss()
|
||||
@ -3042,7 +3047,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
|
||||
if let rootController = self.context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface {
|
||||
let coordinator = rootController.openStoryCamera(customTarget: nil, transitionIn: cameraTransitionIn, transitionedIn: {}, transitionOut: self.storyCameraTransitionOut())
|
||||
let coordinator = rootController.openStoryCamera(customTarget: nil, resumeLiveStream: hasLiveStream, transitionIn: cameraTransitionIn, transitionedIn: {}, transitionOut: self.storyCameraTransitionOut())
|
||||
coordinator?.animateIn()
|
||||
}
|
||||
}
|
||||
@ -6420,7 +6425,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
if let current = self.storyCameraTransitionInCoordinator {
|
||||
coordinator = current
|
||||
} else {
|
||||
coordinator = rootController.openStoryCamera(customTarget: nil, transitionIn: nil, transitionedIn: {}, transitionOut: { [weak self] target, _ in
|
||||
coordinator = rootController.openStoryCamera(customTarget: nil, resumeLiveStream: false, transitionIn: nil, transitionedIn: {}, transitionOut: { [weak self] target, _ in
|
||||
guard let self, let target else {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -155,6 +155,19 @@ final class CameraLiveStreamComponent: Component {
|
||||
self.storyContentState = state
|
||||
self.state?.updated()
|
||||
})
|
||||
|
||||
self.inputMediaNodeDataPromise.set(
|
||||
ChatEntityKeyboardInputNode.inputData(
|
||||
context: component.context,
|
||||
chatPeerId: nil,
|
||||
areCustomEmojiEnabled: true,
|
||||
hasTrending: true,
|
||||
hasSearch: true,
|
||||
hideBackground: true,
|
||||
maskEdge: .clip,
|
||||
sendGif: nil
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
if let storyContentState = self.storyContentState, let slice = storyContentState.slice {
|
||||
|
||||
@ -374,6 +374,11 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
}
|
||||
|
||||
if let controller = getController() {
|
||||
if controller.resumeLiveStream {
|
||||
controller.updateCameraState({ $0.updatedMode(.live).updatedIsWaitingForStream(true) }, update: false, transition: .immediate)
|
||||
self.startLiveStream(rtmp: false)
|
||||
}
|
||||
|
||||
if let customTarget = controller.customTarget {
|
||||
self.sendAsPeerId = customTarget
|
||||
self.isCustomTarget = true
|
||||
@ -1080,6 +1085,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
})
|
||||
}
|
||||
|
||||
private var storyListContext: PeerExpiringStoryListContext?
|
||||
func startLiveStream(rtmp: Bool) {
|
||||
guard let controller = self.getController() else {
|
||||
return
|
||||
@ -1117,41 +1123,36 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
})
|
||||
}
|
||||
|
||||
// let _ = (self.context.engine.messages.storySubscriptions(isHidden: false)
|
||||
// |> take(1)
|
||||
// |> deliverOnMainQueue).start(next: { [weak self, weak controller] subscriptions in
|
||||
// guard let self else {
|
||||
// return
|
||||
// }
|
||||
// if subscriptions.accountItem?.hasLiveItems == true {
|
||||
// let storyList = PeerExpiringStoryListContext(account: self.context.account, peerId: peerId)
|
||||
// let _ = (storyList.state
|
||||
// |> filter { !$0.isLoading }
|
||||
// |> take(1)
|
||||
// |> deliverOnMainQueue).start(next: { [weak self, weak controller] state in
|
||||
// guard let self else {
|
||||
// return
|
||||
// }
|
||||
// for item in state.items.reversed() {
|
||||
// let _ = (self.context.engine.messages.getStory(peerId: peerId, id: item.id)
|
||||
// |> deliverOnMainQueue).start(next: { [weak self, weak controller] item in
|
||||
// guard let self, let item else {
|
||||
// return
|
||||
// }
|
||||
// if case .liveStream = item.media {
|
||||
// self.liveStreamStory = item
|
||||
// controller?.updateCameraState({ $0.updatedIsStreaming(true) }, transition: .spring(duration: 0.4))
|
||||
// self.updated(transition: .immediate)
|
||||
// return
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// startNewStream()
|
||||
// })
|
||||
// } else {
|
||||
let _ = (self.context.engine.messages.storySubscriptions(isHidden: false)
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self, weak controller] subscriptions in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if subscriptions.accountItem?.hasLiveItems == true {
|
||||
let storyList = PeerExpiringStoryListContext(account: self.context.account, peerId: peerId)
|
||||
self.storyListContext = storyList
|
||||
let _ = (storyList.state
|
||||
|> filter { !$0.isLoading }
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self, weak controller] state in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
for item in state.items.reversed() {
|
||||
if case let .item(item) = item, case .liveStream = item.media {
|
||||
self.liveStreamStory = item
|
||||
controller?.updateCameraState({ $0.updatedIsStreaming(true) }, transition: .spring(duration: 0.4))
|
||||
self.updated(transition: .immediate)
|
||||
return
|
||||
}
|
||||
}
|
||||
startNewLiveStream()
|
||||
})
|
||||
} else {
|
||||
startNewLiveStream()
|
||||
// }
|
||||
// })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func endLiveStream() {
|
||||
@ -2815,7 +2816,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if let code = filteredCodes.first, !self.cameraState.isCollageEnabled && self.cameraState.recording == CameraState.Recording.none {
|
||||
if let code = filteredCodes.first, !self.cameraState.isCollageEnabled && self.cameraState.recording == CameraState.Recording.none && self.cameraState.mode != .live {
|
||||
self.controller?.updateFocusedCode(code)
|
||||
} else {
|
||||
self.controller?.updateFocusedCode(nil)
|
||||
@ -3915,6 +3916,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
||||
private let context: AccountContext
|
||||
fileprivate let mode: Mode
|
||||
fileprivate let customTarget: EnginePeer.Id?
|
||||
fileprivate let resumeLiveStream: Bool
|
||||
fileprivate let holder: CameraHolder?
|
||||
fileprivate let transitionIn: TransitionIn?
|
||||
fileprivate let transitionOut: (Bool) -> TransitionOut?
|
||||
@ -3972,15 +3974,18 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
||||
|
||||
public var isEmbedded = false
|
||||
|
||||
fileprivate func updateCameraState(_ f: (CameraState) -> CameraState, transition: ComponentTransition) {
|
||||
fileprivate func updateCameraState(_ f: (CameraState) -> CameraState, update: Bool = true, transition: ComponentTransition) {
|
||||
self.node.cameraState = f(self.node.cameraState)
|
||||
self.node.requestUpdateLayout(transition: transition)
|
||||
if update {
|
||||
self.node.requestUpdateLayout(transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
public init(
|
||||
context: AccountContext,
|
||||
mode: Mode,
|
||||
customTarget: EnginePeer.Id? = nil,
|
||||
resumeLiveStream: Bool = false,
|
||||
holder: CameraHolder? = nil,
|
||||
transitionIn: TransitionIn?,
|
||||
transitionOut: @escaping (Bool) -> TransitionOut?,
|
||||
@ -3989,6 +3994,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
||||
self.context = context
|
||||
self.mode = mode
|
||||
self.customTarget = customTarget
|
||||
self.resumeLiveStream = resumeLiveStream
|
||||
self.holder = holder
|
||||
self.transitionIn = transitionIn
|
||||
self.transitionOut = transitionOut
|
||||
@ -4030,7 +4036,7 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
||||
super.displayNodeDidLoad()
|
||||
|
||||
self.node.didAppear = { [weak self] in
|
||||
guard let self else {
|
||||
guard let self, !self.resumeLiveStream else {
|
||||
return
|
||||
}
|
||||
self.postingAvailabilityDisposable = (self.postingAvailabilityPromise.get()
|
||||
|
||||
@ -634,7 +634,7 @@ public final class GiftItemComponent: Component {
|
||||
if case let .starGift(gift, _) = component.subject, gift.flags.contains(.isAuction) {
|
||||
buttonColor = component.theme.overallDarkAppearance ? UIColor(rgb: 0xffc337) : UIColor(rgb: 0xd3720a)
|
||||
//todo:localize
|
||||
price = "Place a Bid"
|
||||
price = "Join"
|
||||
} else {
|
||||
if priceValue.contains("#") {
|
||||
buttonColor = component.theme.overallDarkAppearance ? UIColor(rgb: 0xffc337) : UIColor(rgb: 0xd3720a)
|
||||
|
||||
@ -10646,7 +10646,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
}
|
||||
|
||||
if let rootController = self.context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface {
|
||||
let coordinator = rootController.openStoryCamera(customTarget: self.peerId == self.context.account.peerId ? nil : .peer(self.peerId), transitionIn: cameraTransitionIn, transitionedIn: {}, transitionOut: self.storyCameraTransitionOut())
|
||||
let coordinator = rootController.openStoryCamera(customTarget: self.peerId == self.context.account.peerId ? nil : .peer(self.peerId), resumeLiveStream: false, transitionIn: cameraTransitionIn, transitionedIn: {}, transitionOut: self.storyCameraTransitionOut())
|
||||
coordinator?.animateIn()
|
||||
}
|
||||
case .channelBoostRequired:
|
||||
|
||||
@ -310,7 +310,7 @@ final class PeerInfoStoryGridScreenComponent: Component {
|
||||
return
|
||||
}
|
||||
if let rootController = component.context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface {
|
||||
let coordinator = rootController.openStoryCamera(customTarget: nil, transitionIn: nil, transitionedIn: {}, transitionOut: { _, _ in return nil })
|
||||
let coordinator = rootController.openStoryCamera(customTarget: nil, resumeLiveStream: false, transitionIn: nil, transitionedIn: {}, transitionOut: { _, _ in return nil })
|
||||
coordinator?.animateIn()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1147,13 +1147,21 @@ final class StoryItemContentComponent: Component {
|
||||
if self.liveCallStatsDisposable == nil {
|
||||
self.liveCallStatsDisposable = (mediaStreamCall.members
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] members in
|
||||
guard let self, let environment = self.environment else {
|
||||
guard let self, let component = self.component, let environment = self.environment else {
|
||||
return
|
||||
}
|
||||
//TODO:localize
|
||||
let subtitle: String
|
||||
if let members {
|
||||
subtitle = "\(max(1, members.totalCount)) watching"
|
||||
var totalCount = members.totalCount
|
||||
if component.isEmbeddedInCamera {
|
||||
totalCount -= 1
|
||||
}
|
||||
if totalCount == 0 && component.isEmbeddedInCamera {
|
||||
subtitle = "no viewers"
|
||||
} else {
|
||||
subtitle = "\(max(1, totalCount)) watching"
|
||||
}
|
||||
} else {
|
||||
subtitle = "loading..."
|
||||
}
|
||||
|
||||
@ -533,6 +533,18 @@ public final class StoryPeerListComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
public var isLiveStreaming: Bool {
|
||||
guard let component = self.component else {
|
||||
return false
|
||||
}
|
||||
for itemSet in self.sortedItems {
|
||||
if itemSet.peer.id == component.context.account.peerId, itemSet.hasLiveItems {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public func transitionViewForItem(peerId: EnginePeer.Id) -> (UIView, StoryContainerScreen.TransitionView)? {
|
||||
if self.collapsedButton.isUserInteractionEnabled {
|
||||
return nil
|
||||
|
||||
@ -301,7 +301,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
public func openStoryCamera(customTarget: Stories.PendingTarget?, transitionIn: StoryCameraTransitionIn?, transitionedIn: @escaping () -> Void, transitionOut: @escaping (Stories.PendingTarget?, Bool) -> StoryCameraTransitionOut?) -> StoryCameraTransitionInCoordinator? {
|
||||
public func openStoryCamera(customTarget: Stories.PendingTarget?, resumeLiveStream: Bool, transitionIn: StoryCameraTransitionIn?, transitionedIn: @escaping () -> Void, transitionOut: @escaping (Stories.PendingTarget?, Bool) -> StoryCameraTransitionOut?) -> StoryCameraTransitionInCoordinator? {
|
||||
guard let controller = self.viewControllers.last as? ViewController else {
|
||||
return nil
|
||||
}
|
||||
@ -335,6 +335,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon
|
||||
context: context,
|
||||
mode: .story,
|
||||
customTarget: mediaEditorCustomTarget,
|
||||
resumeLiveStream: resumeLiveStream,
|
||||
transitionIn: transitionIn.flatMap {
|
||||
if let sourceView = $0.sourceView {
|
||||
return CameraScreenImpl.TransitionIn(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user