This commit is contained in:
Ali 2023-06-27 15:22:14 +03:00
parent c7efe5e6bb
commit 620d555cba
10 changed files with 94 additions and 24 deletions

View File

@ -2604,6 +2604,18 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
})
})))
} else {
items.append(.action(ContextMenuActionItem(text: "Send Message", icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/MessageBubble"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] c, _ in
c.dismiss(completion: {
guard let self, let navigationController = self.navigationController as? NavigationController else {
return
}
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer)))
})
})))
items.append(.action(ContextMenuActionItem(text: "View Profile", icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/User"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] c, _ in

View File

@ -13,6 +13,7 @@ public extension Stories {
case entities
case pin
case privacy
case isForwardingDisabled
case period
case randomId
}
@ -24,6 +25,7 @@ public extension Stories {
public let entities: [MessageTextEntity]
public let pin: Bool
public let privacy: EngineStoryPrivacy
public let isForwardingDisabled: Bool
public let period: Int32
public let randomId: Int64
@ -35,6 +37,7 @@ public extension Stories {
entities: [MessageTextEntity],
pin: Bool,
privacy: EngineStoryPrivacy,
isForwardingDisabled: Bool,
period: Int32,
randomId: Int64
) {
@ -45,6 +48,7 @@ public extension Stories {
self.entities = entities
self.pin = pin
self.privacy = privacy
self.isForwardingDisabled = isForwardingDisabled
self.period = period
self.randomId = randomId
}
@ -62,6 +66,7 @@ public extension Stories {
self.entities = try container.decode([MessageTextEntity].self, forKey: .entities)
self.pin = try container.decode(Bool.self, forKey: .pin)
self.privacy = try container.decode(EngineStoryPrivacy.self, forKey: .privacy)
self.isForwardingDisabled = try container.decodeIfPresent(Bool.self, forKey: .isForwardingDisabled) ?? false
self.period = try container.decode(Int32.self, forKey: .period)
self.randomId = try container.decode(Int64.self, forKey: .randomId)
}
@ -80,6 +85,7 @@ public extension Stories {
try container.encode(self.entities, forKey: .entities)
try container.encode(self.pin, forKey: .pin)
try container.encode(self.privacy, forKey: .privacy)
try container.encode(self.isForwardingDisabled, forKey: .isForwardingDisabled)
try container.encode(self.period, forKey: .period)
try container.encode(self.randomId, forKey: .randomId)
}
@ -106,6 +112,9 @@ public extension Stories {
if lhs.privacy != rhs.privacy {
return false
}
if lhs.isForwardingDisabled != rhs.isForwardingDisabled {
return false
}
if lhs.period != rhs.period {
return false
}
@ -260,7 +269,7 @@ final class PendingStoryManager {
self.currentPendingItemContext = pendingItemContext
let stableId = firstItem.stableId
pendingItemContext.disposable = (_internal_uploadStoryImpl(postbox: self.postbox, network: self.network, accountPeerId: self.accountPeerId, stateManager: self.stateManager, messageMediaPreuploadManager: self.messageMediaPreuploadManager, revalidationContext: self.revalidationContext, auxiliaryMethods: self.auxiliaryMethods, stableId: stableId, media: firstItem.media, text: firstItem.text, entities: firstItem.entities, pin: firstItem.pin, privacy: firstItem.privacy, period: Int(firstItem.period), randomId: firstItem.randomId)
pendingItemContext.disposable = (_internal_uploadStoryImpl(postbox: self.postbox, network: self.network, accountPeerId: self.accountPeerId, stateManager: self.stateManager, messageMediaPreuploadManager: self.messageMediaPreuploadManager, revalidationContext: self.revalidationContext, auxiliaryMethods: self.auxiliaryMethods, stableId: stableId, media: firstItem.media, text: firstItem.text, entities: firstItem.entities, pin: firstItem.pin, privacy: firstItem.privacy, isForwardingDisabled: firstItem.isForwardingDisabled, period: Int(firstItem.period), randomId: firstItem.randomId)
|> deliverOn(self.queue)).start(next: { [weak self] event in
guard let `self` = self else {
return

View File

@ -125,6 +125,7 @@ public enum Stories {
case isExpired
case isPublic
case isCloseFriends
case isForwardingDisabled
}
public let id: Int32
@ -139,6 +140,7 @@ public enum Stories {
public let isExpired: Bool
public let isPublic: Bool
public let isCloseFriends: Bool
public let isForwardingDisabled: Bool
public init(
id: Int32,
@ -152,7 +154,8 @@ public enum Stories {
isPinned: Bool,
isExpired: Bool,
isPublic: Bool,
isCloseFriends: Bool
isCloseFriends: Bool,
isForwardingDisabled: Bool
) {
self.id = id
self.timestamp = timestamp
@ -166,6 +169,7 @@ public enum Stories {
self.isExpired = isExpired
self.isPublic = isPublic
self.isCloseFriends = isCloseFriends
self.isForwardingDisabled = isForwardingDisabled
}
public init(from decoder: Decoder) throws {
@ -189,6 +193,7 @@ public enum Stories {
self.isExpired = try container.decodeIfPresent(Bool.self, forKey: .isExpired) ?? false
self.isPublic = try container.decodeIfPresent(Bool.self, forKey: .isPublic) ?? false
self.isCloseFriends = try container.decodeIfPresent(Bool.self, forKey: .isCloseFriends) ?? false
self.isForwardingDisabled = try container.decodeIfPresent(Bool.self, forKey: .isForwardingDisabled) ?? false
}
public func encode(to encoder: Encoder) throws {
@ -213,6 +218,7 @@ public enum Stories {
try container.encode(self.isExpired, forKey: .isExpired)
try container.encode(self.isPublic, forKey: .isPublic)
try container.encode(self.isCloseFriends, forKey: .isCloseFriends)
try container.encode(self.isForwardingDisabled, forKey: .isForwardingDisabled)
}
public static func ==(lhs: Item, rhs: Item) -> Bool {
@ -260,6 +266,9 @@ public enum Stories {
if lhs.isCloseFriends != rhs.isCloseFriends {
return false
}
if lhs.isForwardingDisabled != rhs.isForwardingDisabled {
return false
}
return true
}
@ -680,7 +689,7 @@ private func apiInputPrivacyRules(privacy: EngineStoryPrivacy, transaction: Tran
return privacyRules
}
func _internal_uploadStory(account: Account, media: EngineStoryInputMedia, text: String, entities: [MessageTextEntity], pin: Bool, privacy: EngineStoryPrivacy, period: Int, randomId: Int64) {
func _internal_uploadStory(account: Account, media: EngineStoryInputMedia, text: String, entities: [MessageTextEntity], pin: Bool, privacy: EngineStoryPrivacy, isForwardingDisabled: Bool, period: Int, randomId: Int64) {
let inputMedia = prepareUploadStoryContent(account: account, media: media)
let _ = (account.postbox.transaction { transaction in
@ -702,6 +711,7 @@ func _internal_uploadStory(account: Account, media: EngineStoryInputMedia, text:
entities: entities,
pin: pin,
privacy: privacy,
isForwardingDisabled: isForwardingDisabled,
period: Int32(period),
randomId: randomId
))
@ -747,7 +757,7 @@ private func _internal_putPendingStoryIdMapping(accountPeerId: PeerId, stableId:
}
}
func _internal_uploadStoryImpl(postbox: Postbox, network: Network, accountPeerId: PeerId, stateManager: AccountStateManager, messageMediaPreuploadManager: MessageMediaPreuploadManager, revalidationContext: MediaReferenceRevalidationContext, auxiliaryMethods: AccountAuxiliaryMethods, stableId: Int32, media: Media, text: String, entities: [MessageTextEntity], pin: Bool, privacy: EngineStoryPrivacy, period: Int, randomId: Int64) -> Signal<StoryUploadResult, NoError> {
func _internal_uploadStoryImpl(postbox: Postbox, network: Network, accountPeerId: PeerId, stateManager: AccountStateManager, messageMediaPreuploadManager: MessageMediaPreuploadManager, revalidationContext: MediaReferenceRevalidationContext, auxiliaryMethods: AccountAuxiliaryMethods, stableId: Int32, media: Media, text: String, entities: [MessageTextEntity], pin: Bool, privacy: EngineStoryPrivacy, isForwardingDisabled: Bool, period: Int, randomId: Int64) -> Signal<StoryUploadResult, NoError> {
let (contentSignal, originalMedia) = uploadedStoryContent(postbox: postbox, network: network, media: media, accountPeerId: accountPeerId, messageMediaPreuploadManager: messageMediaPreuploadManager, revalidationContext: revalidationContext, auxiliaryMethods: auxiliaryMethods)
return contentSignal
|> mapToSignal { result -> Signal<StoryUploadResult, NoError> in
@ -787,6 +797,10 @@ func _internal_uploadStoryImpl(postbox: Postbox, network: Network, accountPeerId
flags |= 1 << 3
if isForwardingDisabled {
flags |= 1 << 4
}
return network.request(Api.functions.stories.sendStory(
flags: flags,
media: inputMedia,
@ -835,7 +849,8 @@ func _internal_uploadStoryImpl(postbox: Postbox, network: Network, accountPeerId
isPinned: item.isPinned,
isExpired: item.isExpired,
isPublic: item.isPublic,
isCloseFriends: item.isCloseFriends
isCloseFriends: item.isCloseFriends,
isForwardingDisabled: item.isForwardingDisabled
)
if let entry = CodableEntry(Stories.StoredItem.item(updatedItem)) {
items.append(StoryItemsTableEntry(value: entry, id: item.id, expirationTimestamp: updatedItem.expirationTimestamp))
@ -983,7 +998,8 @@ func _internal_editStoryPrivacy(account: Account, id: Int32, privacy: EngineStor
isPinned: item.isPinned,
isExpired: item.isExpired,
isPublic: item.isPublic,
isCloseFriends: item.isCloseFriends
isCloseFriends: item.isCloseFriends,
isForwardingDisabled: item.isForwardingDisabled
)
if let entry = CodableEntry(Stories.StoredItem.item(updatedItem)) {
transaction.setStory(id: storyId, value: entry)
@ -1005,7 +1021,8 @@ func _internal_editStoryPrivacy(account: Account, id: Int32, privacy: EngineStor
isPinned: item.isPinned,
isExpired: item.isExpired,
isPublic: item.isPublic,
isCloseFriends: item.isCloseFriends
isCloseFriends: item.isCloseFriends,
isForwardingDisabled: item.isForwardingDisabled
)
if let entry = CodableEntry(Stories.StoredItem.item(updatedItem)) {
items[index] = StoryItemsTableEntry(value: entry, id: item.id, expirationTimestamp: updatedItem.expirationTimestamp)
@ -1136,7 +1153,8 @@ func _internal_updateStoriesArePinned(account: Account, ids: [Int32: EngineStory
isPinned: isPinned,
isExpired: item.isExpired,
isPublic: item.isPublic,
isCloseFriends: item.isCloseFriends
isCloseFriends: item.isCloseFriends,
isForwardingDisabled: item.isForwardingDisabled
)
if let entry = CodableEntry(Stories.StoredItem.item(updatedItem)) {
items[index] = StoryItemsTableEntry(value: entry, id: item.id, expirationTimestamp: updatedItem.expirationTimestamp)
@ -1157,7 +1175,8 @@ func _internal_updateStoriesArePinned(account: Account, ids: [Int32: EngineStory
isPinned: isPinned,
isExpired: item.isExpired,
isPublic: item.isPublic,
isCloseFriends: item.isCloseFriends
isCloseFriends: item.isCloseFriends,
isForwardingDisabled: item.isForwardingDisabled
)
updatedItems.append(updatedItem)
}
@ -1253,6 +1272,7 @@ extension Stories.StoredItem {
let isExpired = (flags & (1 << 6)) != 0
let isPublic = (flags & (1 << 7)) != 0
let isCloseFriends = (flags & (1 << 8)) != 0
let isForwardingDisabled = (flags & (1 << 10)) != 0
let item = Stories.Item(
id: id,
@ -1266,7 +1286,8 @@ extension Stories.StoredItem {
isPinned: isPinned,
isExpired: isExpired,
isPublic: isPublic,
isCloseFriends: isCloseFriends
isCloseFriends: isCloseFriends,
isForwardingDisabled: isForwardingDisabled
)
self = .item(item)
} else {

View File

@ -44,8 +44,9 @@ public final class EngineStoryItem: Equatable {
public let isPublic: Bool
public let isPending: Bool
public let isCloseFriends: Bool
public let isForwardingDisabled: Bool
public init(id: Int32, timestamp: Int32, expirationTimestamp: Int32, media: EngineMedia, text: String, entities: [MessageTextEntity], views: Views?, privacy: EngineStoryPrivacy?, isPinned: Bool, isExpired: Bool, isPublic: Bool, isPending: Bool, isCloseFriends: Bool) {
public init(id: Int32, timestamp: Int32, expirationTimestamp: Int32, media: EngineMedia, text: String, entities: [MessageTextEntity], views: Views?, privacy: EngineStoryPrivacy?, isPinned: Bool, isExpired: Bool, isPublic: Bool, isPending: Bool, isCloseFriends: Bool, isForwardingDisabled: Bool) {
self.id = id
self.timestamp = timestamp
self.expirationTimestamp = expirationTimestamp
@ -59,6 +60,7 @@ public final class EngineStoryItem: Equatable {
self.isPublic = isPublic
self.isPending = isPending
self.isCloseFriends = isCloseFriends
self.isForwardingDisabled = isForwardingDisabled
}
public static func ==(lhs: EngineStoryItem, rhs: EngineStoryItem) -> Bool {
@ -101,6 +103,9 @@ public final class EngineStoryItem: Equatable {
if lhs.isCloseFriends != rhs.isCloseFriends {
return false
}
if lhs.isForwardingDisabled != rhs.isForwardingDisabled {
return false
}
return true
}
}
@ -129,7 +134,8 @@ extension EngineStoryItem {
isPinned: self.isPinned,
isExpired: self.isExpired,
isPublic: self.isPublic,
isCloseFriends: self.isCloseFriends
isCloseFriends: self.isCloseFriends,
isForwardingDisabled: self.isForwardingDisabled
)
}
}
@ -487,7 +493,8 @@ public final class PeerStoryListContext {
isExpired: item.isExpired,
isPublic: item.isPublic,
isPending: false,
isCloseFriends: item.isCloseFriends
isCloseFriends: item.isCloseFriends,
isForwardingDisabled: item.isForwardingDisabled
)
items.append(mappedItem)
}
@ -593,7 +600,8 @@ public final class PeerStoryListContext {
isExpired: item.isExpired,
isPublic: item.isPublic,
isPending: false,
isCloseFriends: item.isCloseFriends
isCloseFriends: item.isCloseFriends,
isForwardingDisabled: item.isForwardingDisabled
)
storyItems.append(mappedItem)
}
@ -726,7 +734,8 @@ public final class PeerStoryListContext {
isExpired: item.isExpired,
isPublic: item.isPublic,
isPending: false,
isCloseFriends: item.isCloseFriends
isCloseFriends: item.isCloseFriends,
isForwardingDisabled: item.isForwardingDisabled
)
finalUpdatedState = updatedState
}
@ -764,7 +773,8 @@ public final class PeerStoryListContext {
isExpired: item.isExpired,
isPublic: item.isPublic,
isPending: false,
isCloseFriends: item.isCloseFriends
isCloseFriends: item.isCloseFriends,
isForwardingDisabled: item.isForwardingDisabled
))
updatedState.items.sort(by: { lhs, rhs in
return lhs.timestamp > rhs.timestamp
@ -911,7 +921,8 @@ public final class PeerExpiringStoryListContext {
isExpired: item.isExpired,
isPublic: item.isPublic,
isPending: false,
isCloseFriends: item.isCloseFriends
isCloseFriends: item.isCloseFriends,
isForwardingDisabled: item.isForwardingDisabled
)
items.append(.item(mappedItem))
}

View File

@ -966,7 +966,8 @@ public extension TelegramEngine {
isPinned: item.isPinned,
isExpired: item.isExpired,
isPublic: item.isPublic,
isCloseFriends: item.isCloseFriends
isCloseFriends: item.isCloseFriends,
isForwardingDisabled: item.isForwardingDisabled
))
if let entry = CodableEntry(updatedItem) {
currentItems[i] = StoryItemsTableEntry(value: entry, id: updatedItem.id, expirationTimestamp: updatedItem.expirationTimestamp)
@ -980,8 +981,8 @@ public extension TelegramEngine {
}
}
public func uploadStory(media: EngineStoryInputMedia, text: String, entities: [MessageTextEntity], pin: Bool, privacy: EngineStoryPrivacy, period: Int, randomId: Int64) {
_internal_uploadStory(account: self.account, media: media, text: text, entities: entities, pin: pin, privacy: privacy, period: period, randomId: randomId)
public func uploadStory(media: EngineStoryInputMedia, text: String, entities: [MessageTextEntity], pin: Bool, privacy: EngineStoryPrivacy, isForwardingDisabled: Bool, period: Int, randomId: Int64) {
_internal_uploadStory(account: self.account, media: media, text: text, entities: entities, pin: pin, privacy: privacy, isForwardingDisabled: isForwardingDisabled, period: period, randomId: randomId)
}
public func lookUpPendingStoryIdMapping(stableId: Int32) -> Int32? {

View File

@ -141,7 +141,7 @@ final class StoryItemContentComponent: Component {
useLargeThumbnail: true,
autoFetchFullSizeThumbnail: true,
tempFilePath: nil,
captureProtected: false,
captureProtected: component.item.isForwardingDisabled,
hintDimensions: file.dimensions?.cgSize,
storeAfterDownload: nil,
displayImage: false
@ -494,6 +494,7 @@ final class StoryItemContentComponent: Component {
if imageSize.height < availableSize.height && imageSize.height >= availableSize.height - 5.0 {
imageSize.height = availableSize.height
}
self.imageNode.captureProtected = component.item.isForwardingDisabled
let apply = self.imageNode.asyncLayout()(TransformImageArguments(
corners: ImageCorners(),
imageSize: imageSize,

View File

@ -1523,7 +1523,7 @@ public final class StoryItemSetContainerComponent: Component {
self.state?.updated(transition: .immediate)
},
timeoutAction: nil,
forwardAction: component.slice.item.storyItem.isPublic ? { [weak self] in
forwardAction: component.slice.item.storyItem.isPublic && !component.slice.item.storyItem.isForwardingDisabled ? { [weak self] in
guard let self else {
return
}

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "messagebubble.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 4.66502C7.88795 4.66502 4.66502 7.68163 4.66502 11.2727C4.66502 13.329 5.61495 15.016 7.28375 16.2378C7.50459 16.3995 7.61824 16.6447 7.67716 16.8096C7.74628 17.003 7.78941 17.2274 7.80119 17.4635C7.82475 17.9355 7.72531 18.5159 7.37618 19.0511C7.32109 19.1355 7.26431 19.2162 7.20737 19.2928C7.45008 19.2413 7.68743 19.1624 7.88779 19.05C8.43439 18.7435 8.78169 18.4401 9.03437 18.2083C9.05375 18.1905 9.07401 18.1718 9.0949 18.1524C9.19597 18.0589 9.3118 17.9516 9.41317 17.8755C9.51328 17.8003 9.80413 17.5892 10.1854 17.6767C10.7649 17.8096 11.3728 17.8805 12 17.8805C16.1121 17.8805 19.335 14.8639 19.335 11.2727C19.335 7.68163 16.1121 4.66502 12 4.66502ZM6.17873 19.351C6.17875 19.3509 6.18007 19.3512 6.18254 19.3518C6.17992 19.3513 6.1787 19.351 6.17873 19.351ZM6.49475 20.1245C6.49316 20.1271 6.49223 20.1284 6.49219 20.1284C6.49214 20.1284 6.49293 20.1271 6.49475 20.1245ZM3.33502 11.2727C3.33502 6.83064 7.27554 3.33502 12 3.33502C16.7245 3.33502 20.665 6.83064 20.665 11.2727C20.665 15.7149 16.7245 19.2105 12 19.2105C11.3532 19.2105 10.7221 19.1455 10.1145 19.022C10.0893 19.0448 10.0598 19.0721 10.0238 19.1052C9.99742 19.1295 9.9676 19.157 9.93357 19.1883C9.64507 19.453 9.2118 19.8324 8.53835 20.21C8.00052 20.5117 7.38987 20.636 6.91077 20.6797C6.66653 20.702 6.44116 20.7047 6.25548 20.6946C6.16291 20.6897 6.07427 20.6812 5.9943 20.6688C5.92695 20.6584 5.82187 20.6389 5.72037 20.5963C5.60837 20.5493 5.41843 20.4446 5.30536 20.2201C5.18416 19.9794 5.22417 19.7499 5.27201 19.6141C5.31662 19.4875 5.38558 19.3872 5.43085 19.3263C5.48061 19.2594 5.53686 19.1946 5.58714 19.1386C5.62942 19.0915 5.6727 19.0445 5.71667 18.9967C5.89442 18.8038 6.08334 18.5986 6.26224 18.3244C6.43214 18.0639 6.48498 17.7728 6.47285 17.5298C6.46678 17.4083 6.44507 17.3141 6.42472 17.2571C6.42464 17.2569 6.42456 17.2567 6.42448 17.2565C4.49565 15.8148 3.33502 13.7665 3.33502 11.2727ZM6.40689 17.2161C6.407 17.2159 6.40865 17.2184 6.41149 17.2244C6.4082 17.2193 6.40678 17.2163 6.40689 17.2161ZM10.2318 18.9257C10.2316 18.9262 10.2262 18.9301 10.2162 18.9357C10.2269 18.9279 10.2319 18.9251 10.2318 18.9257Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -361,7 +361,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon
case let .image(image, dimensions):
if let imageData = compressImageToJPEG(image, quality: 0.7) {
let entities = generateChatInputTextEntities(caption)
self.context.engine.messages.uploadStory(media: .image(dimensions: dimensions, data: imageData), text: caption.string, entities: entities, pin: privacy.archive, privacy: privacy.privacy, period: privacy.timeout, randomId: randomId)
self.context.engine.messages.uploadStory(media: .image(dimensions: dimensions, data: imageData), text: caption.string, entities: entities, pin: privacy.archive, privacy: privacy.privacy, isForwardingDisabled: false, period: privacy.timeout, randomId: randomId)
Queue.mainQueue().justDispatch {
commit({})
}
@ -384,7 +384,7 @@ public final class TelegramRootController: NavigationController, TelegramRootCon
}
let imageData = firstFrameImage.flatMap { compressImageToJPEG($0, quality: 0.6) }
let entities = generateChatInputTextEntities(caption)
self.context.engine.messages.uploadStory(media: .video(dimensions: dimensions, duration: duration, resource: resource, firstFrameImageData: imageData), text: caption.string, entities: entities, pin: privacy.archive, privacy: privacy.privacy, period: privacy.timeout, randomId: randomId)
self.context.engine.messages.uploadStory(media: .video(dimensions: dimensions, duration: duration, resource: resource, firstFrameImageData: imageData), text: caption.string, entities: entities, pin: privacy.archive, privacy: privacy.privacy, isForwardingDisabled: false, period: privacy.timeout, randomId: randomId)
Queue.mainQueue().justDispatch {
commit({})
}