Merge commit 'b71275482055b2b59ab41da9080fde4a843f98c3' into 189layer

This commit is contained in:
Mikhail Filimonov
2024-09-24 15:12:03 -03:00
129 changed files with 5749 additions and 1194 deletions

View File

@@ -0,0 +1,82 @@
import Foundation
import Postbox
import SwiftSignalKit
import TelegramApi
import MtProtoKit
public enum ReportContentResult {
public struct Option: Equatable {
public let text: String
public let option: Data
}
case options(title: String, options: [Option])
case addComment(optional: Bool, option: Data)
case reported
}
public enum ReportContentError {
case generic
case messageIdRequired
}
public enum ReportContentSubject: Equatable {
case peer(EnginePeer.Id)
case messages([EngineMessage.Id])
case stories(EnginePeer.Id, [Int32])
var peerId: EnginePeer.Id {
switch self {
case let .peer(peerId):
return peerId
case let .messages(messageIds):
return messageIds.first!.peerId
case let .stories(peerId, _):
return peerId
}
}
}
func _internal_reportContent(account: Account, subject: ReportContentSubject, option: Data?, message: String?) -> Signal<ReportContentResult, ReportContentError> {
return account.postbox.transaction { transaction -> Signal<ReportContentResult, ReportContentError> in
guard let peer = transaction.getPeer(subject.peerId), let inputPeer = apiInputPeer(peer) else {
return .fail(.generic)
}
let request: Signal<Api.ReportResult, MTRpcError>
if case let .stories(_, ids) = subject {
request = account.network.request(Api.functions.stories.report(peer: inputPeer, id: ids, option: Buffer(data: option), message: message ?? ""))
} else {
var ids: [Int32] = []
if case let .messages(messageIds) = subject {
ids = messageIds.map { $0.id }
}
request = account.network.request(Api.functions.messages.report(peer: inputPeer, id: ids, option: Buffer(data: option), message: message ?? ""))
}
return request
|> mapError { error -> ReportContentError in
if error.errorDescription == "MESSAGE_ID_REQUIRED" {
return .messageIdRequired
}
return .generic
}
|> map { result -> ReportContentResult in
switch result {
case let .reportResultChooseOption(title, options):
return .options(title: title, options: options.map {
switch $0 {
case let .messageReportOption(text, option):
return ReportContentResult.Option(text: text, option: option.makeData())
}
})
case let .reportResultAddComment(flags, option):
return .addComment(optional: (flags & (1 << 0)) != 0, option: option.makeData())
case .reportResultReported:
return .reported
}
}
}
|> castError(ReportContentError.self)
|> switchToLatest
}

View File

@@ -1463,6 +1463,10 @@ public extension TelegramEngine {
return _internal_reportAdMessage(account: self.account, peerId: peerId, opaqueId: opaqueId, option: option)
}
public func reportContent(subject: ReportContentSubject, option: Data?, message: String?) -> Signal<ReportContentResult, ReportContentError> {
return _internal_reportContent(account: self.account, subject: subject, option: option, message: message)
}
public func updateExtendedMedia(messageIds: [EngineMessage.Id]) -> Signal<Never, NoError> {
return _internal_updateExtendedMedia(account: self.account, messageIds: messageIds)
}

View File

@@ -238,6 +238,7 @@ private final class ProfileGiftsContextImpl {
private let peerId: PeerId
private let disposable = MetaDisposable()
private let actionDisposable = MetaDisposable()
private var gifts: [ProfileGiftsContext.State.StarGift] = []
private var count: Int32?
@@ -258,6 +259,7 @@ private final class ProfileGiftsContextImpl {
deinit {
self.disposable.dispose()
self.actionDisposable.dispose()
}
func loadMore() {
@@ -315,6 +317,27 @@ private final class ProfileGiftsContextImpl {
}
}
func updateStarGiftAddedToProfile(messageId: EngineMessage.Id, added: Bool) {
self.actionDisposable.set(
_internal_updateStarGiftAddedToProfile(account: self.account, messageId: messageId, added: added).startStrict()
)
if let index = self.gifts.firstIndex(where: { $0.messageId == messageId }) {
self.gifts[index] = self.gifts[index].withSavedToProfile(added)
}
self.pushState()
}
func convertStarGift(messageId: EngineMessage.Id) {
self.actionDisposable.set(
_internal_convertStarGift(account: self.account, messageId: messageId).startStrict()
)
if let count = self.count {
self.count = max(0, count - 1)
}
self.gifts.removeAll(where: { $0.messageId == messageId })
self.pushState()
}
private func pushState() {
self.stateValue.set(.single(ProfileGiftsContext.State(gifts: self.gifts, count: self.count, dataState: self.dataState)))
}
@@ -332,6 +355,20 @@ public final class ProfileGiftsContext {
public let nameHidden: Bool
public let savedToProfile: Bool
public let convertStars: Int64?
public func withSavedToProfile(_ savedToProfile: Bool) -> StarGift {
return StarGift(
gift: self.gift,
fromPeer: self.fromPeer,
date: self.date,
text: self.text,
entities: self.entities,
messageId: self.messageId,
nameHidden: self.nameHidden,
savedToProfile: savedToProfile,
convertStars: self.convertStars
)
}
}
public enum DataState: Equatable {
@@ -373,6 +410,18 @@ public final class ProfileGiftsContext {
impl.loadMore()
}
}
public func updateStarGiftAddedToProfile(messageId: EngineMessage.Id, added: Bool) {
self.impl.with { impl in
impl.updateStarGiftAddedToProfile(messageId: messageId, added: added)
}
}
public func convertStarGift(messageId: EngineMessage.Id) {
self.impl.with { impl in
impl.convertStarGift(messageId: messageId)
}
}
}
private extension ProfileGiftsContext.State.StarGift {

View File

@@ -468,7 +468,7 @@ private final class StarsContextImpl {
}
var transactions = state.transactions
if addTransaction {
transactions.insert(.init(flags: [.isLocal], id: "\(arc4random())", count: balance, date: Int32(Date().timeIntervalSince1970), peer: .appStore, title: nil, description: nil, photo: nil, transactionDate: nil, transactionUrl: nil, paidMessageId: nil, giveawayMessageId: nil, media: [], subscriptionPeriod: nil), at: 0)
transactions.insert(.init(flags: [.isLocal], id: "\(arc4random())", count: balance, date: Int32(Date().timeIntervalSince1970), peer: .appStore, title: nil, description: nil, photo: nil, transactionDate: nil, transactionUrl: nil, paidMessageId: nil, giveawayMessageId: nil, media: [], subscriptionPeriod: nil, starGift: nil), at: 0)
}
self.updateState(StarsContext.State(flags: [.isPendingBalance], balance: max(0, state.balance + balance), subscriptions: state.subscriptions, canLoadMoreSubscriptions: state.canLoadMoreSubscriptions, transactions: transactions, canLoadMoreTransactions: state.canLoadMoreTransactions, isLoading: state.isLoading))
@@ -490,7 +490,7 @@ private final class StarsContextImpl {
private extension StarsContext.State.Transaction {
init?(apiTransaction: Api.StarsTransaction, peerId: EnginePeer.Id?, transaction: Transaction) {
switch apiTransaction {
case let .starsTransaction(apiFlags, id, stars, date, transactionPeer, title, description, photo, transactionDate, transactionUrl, _, messageId, extendedMedia, subscriptionPeriod, giveawayPostId):
case let .starsTransaction(apiFlags, id, stars, date, transactionPeer, title, description, photo, transactionDate, transactionUrl, _, messageId, extendedMedia, subscriptionPeriod, giveawayPostId, starGift):
let parsedPeer: StarsContext.State.Transaction.Peer
var paidMessageId: MessageId?
var giveawayMessageId: MessageId?
@@ -544,7 +544,7 @@ private extension StarsContext.State.Transaction {
let media = extendedMedia.flatMap({ $0.compactMap { textMediaAndExpirationTimerFromApiMedia($0, PeerId(0)).media } }) ?? []
let _ = subscriptionPeriod
self.init(flags: flags, id: id, count: stars, date: date, peer: parsedPeer, title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), transactionDate: transactionDate, transactionUrl: transactionUrl, paidMessageId: paidMessageId, giveawayMessageId: giveawayMessageId, media: media, subscriptionPeriod: subscriptionPeriod)
self.init(flags: flags, id: id, count: stars, date: date, peer: parsedPeer, title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), transactionDate: transactionDate, transactionUrl: transactionUrl, paidMessageId: paidMessageId, giveawayMessageId: giveawayMessageId, media: media, subscriptionPeriod: subscriptionPeriod, starGift: starGift.flatMap { StarGift(apiStarGift: $0) })
}
}
}
@@ -613,6 +613,7 @@ public final class StarsContext {
public let giveawayMessageId: MessageId?
public let media: [Media]
public let subscriptionPeriod: Int32?
public let starGift: StarGift?
public init(
flags: Flags,
@@ -628,7 +629,8 @@ public final class StarsContext {
paidMessageId: MessageId?,
giveawayMessageId: MessageId?,
media: [Media],
subscriptionPeriod: Int32?
subscriptionPeriod: Int32?,
starGift: StarGift?
) {
self.flags = flags
self.id = id
@@ -644,6 +646,7 @@ public final class StarsContext {
self.giveawayMessageId = giveawayMessageId
self.media = media
self.subscriptionPeriod = subscriptionPeriod
self.starGift = starGift
}
public static func == (lhs: Transaction, rhs: Transaction) -> Bool {
@@ -689,6 +692,9 @@ public final class StarsContext {
if lhs.subscriptionPeriod != rhs.subscriptionPeriod {
return false
}
if lhs.starGift != rhs.starGift {
return false
}
return true
}
}

View File

@@ -148,42 +148,44 @@ func _internal_reportPeerPhoto(account: Account, peerId: PeerId, reason: ReportR
}
func _internal_reportPeerMessages(account: Account, messageIds: [MessageId], reason: ReportReason, message: String) -> Signal<Void, NoError> {
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
let groupedIds = messagesIdsGroupedByPeerId(messageIds)
let signals = groupedIds.values.compactMap { ids -> Signal<Void, NoError>? in
guard let peerId = ids.first?.peerId, let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) else {
return nil
}
return account.network.request(Api.functions.messages.report(peer: inputPeer, id: ids.map { $0.id }, reason: reason.apiReason, message: message))
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse)
}
|> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
}
}
return combineLatest(signals)
|> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
}
} |> switchToLatest
return .complete()
// return account.postbox.transaction { transaction -> Signal<Void, NoError> in
// let groupedIds = messagesIdsGroupedByPeerId(messageIds)
// let signals = groupedIds.values.compactMap { ids -> Signal<Void, NoError>? in
// guard let peerId = ids.first?.peerId, let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) else {
// return nil
// }
// return account.network.request(Api.functions.messages.report(peer: inputPeer, id: ids.map { $0.id }, reason: reason.apiReason, message: message))
// |> `catch` { _ -> Signal<Api.Bool, NoError> in
// return .single(.boolFalse)
// }
// |> mapToSignal { _ -> Signal<Void, NoError> in
// return .complete()
// }
// }
//
// return combineLatest(signals)
// |> mapToSignal { _ -> Signal<Void, NoError> in
// return .complete()
// }
// } |> switchToLatest
}
func _internal_reportPeerStory(account: Account, peerId: PeerId, storyId: Int32, reason: ReportReason, message: String) -> Signal<Void, NoError> {
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
return account.network.request(Api.functions.stories.report(peer: inputPeer, id: [storyId], reason: reason.apiReason, message: message))
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse)
}
|> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
}
} else {
return .complete()
}
} |> switchToLatest
return .complete()
// return account.postbox.transaction { transaction -> Signal<Void, NoError> in
// if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
// return account.network.request(Api.functions.stories.report(peer: inputPeer, id: [storyId], reason: reason.apiReason, message: message))
// |> `catch` { _ -> Signal<Api.Bool, NoError> in
// return .single(.boolFalse)
// }
// |> mapToSignal { _ -> Signal<Void, NoError> in
// return .complete()
// }
// } else {
// return .complete()
// }
// } |> switchToLatest
}
func _internal_reportPeerReaction(account: Account, authorId: PeerId, messageId: MessageId) -> Signal<Never, NoError> {