mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Various fixes
This commit is contained in:
parent
2af0b2a8b7
commit
9fbd857506
@ -14749,6 +14749,9 @@ Sorry for the inconvenience.";
|
||||
"AgeVerification.Text.GB" = "To access this content, you must confirm you are at least **18** years old as required by UK law.\n\nThis is a one-time process using your phone's camera. Your selfie will not be stored by Telegram.";
|
||||
"AgeVerification.Verify" = "Verify My Age";
|
||||
|
||||
"AgeVerification.Unavailable.Title" = "18+";
|
||||
"AgeVerification.Unavailable.Text" = "This media may contain sensitive content suitable only for adults.";
|
||||
|
||||
"AgeVerification.Success.Title" = "Age check passed!";
|
||||
"AgeVerification.Success.Text" = "You can now view this content.";
|
||||
|
||||
|
@ -912,12 +912,6 @@ public func dataAndStorageController(context: AccountContext, focusOnItemTag: Da
|
||||
}
|
||||
})
|
||||
updateSensitiveContentDisposable.set(updateRemoteContentSettingsConfiguration(postbox: context.account.postbox, network: context.account.network, sensitiveContentEnabled: value).start())
|
||||
|
||||
if !value {
|
||||
let _ = updateAgeVerificationState(engine: context.engine, { _ in
|
||||
return AgeVerificationState(verificationPassed: false)
|
||||
}).start()
|
||||
}
|
||||
}
|
||||
if value {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
@ -2143,6 +2143,28 @@ public final class ProfileGiftsContext {
|
||||
collectionIds: self.collectionIds
|
||||
)
|
||||
}
|
||||
|
||||
public func withCollectionIds(_ collectionIds: [Int32]?) -> StarGift {
|
||||
return StarGift(
|
||||
gift: self.gift,
|
||||
reference: self.reference,
|
||||
fromPeer: self.fromPeer,
|
||||
date: self.date,
|
||||
text: self.text,
|
||||
entities: self.entities,
|
||||
nameHidden: self.nameHidden,
|
||||
savedToProfile: self.savedToProfile,
|
||||
pinnedToTop: self.pinnedToTop,
|
||||
convertStars: self.convertStars,
|
||||
canUpgrade: self.canUpgrade,
|
||||
canExportDate: self.canExportDate,
|
||||
upgradeStars: self.upgradeStars,
|
||||
transferStars: self.transferStars,
|
||||
canTransferDate: self.canTransferDate,
|
||||
canResaleDate: self.canResaleDate,
|
||||
collectionIds: collectionIds
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
public enum DataState: Equatable {
|
||||
|
@ -190,10 +190,15 @@ private func _internal_reorderStarGiftCollections(account: Account, peerId: Engi
|
||||
}
|
||||
}
|
||||
|
||||
private func _internal_updateStarGiftCollection(account: Account, peerId: EnginePeer.Id, collectionId: Int32, giftsContext: ProfileGiftsContext?, actions: [ProfileGiftsCollectionsContext.UpdateAction]) -> Signal<StarGiftCollection?, NoError> {
|
||||
private func _internal_updateStarGiftCollection(account: Account, peerId: EnginePeer.Id, collectionId: Int32, giftsContext: ProfileGiftsContext?, allGiftsContext: ProfileGiftsContext?, actions: [ProfileGiftsCollectionsContext.UpdateAction]) -> Signal<StarGiftCollection?, NoError> {
|
||||
for action in actions {
|
||||
switch action {
|
||||
case let .addGifts(gifts):
|
||||
let gifts = gifts.map { gift in
|
||||
var collectionIds = gift.collectionIds ?? []
|
||||
collectionIds.append(collectionId)
|
||||
return gift.withCollectionIds(collectionIds)
|
||||
}
|
||||
giftsContext?.insertStarGifts(gifts: gifts)
|
||||
case let .removeGifts(gifts):
|
||||
giftsContext?.removeStarGifts(references: gifts)
|
||||
@ -294,6 +299,7 @@ public final class ProfileGiftsCollectionsContext {
|
||||
private let queue: Queue = .mainQueue()
|
||||
private let account: Account
|
||||
private let peerId: EnginePeer.Id
|
||||
private weak var allGiftsContext: ProfileGiftsContext?
|
||||
|
||||
private let disposable = MetaDisposable()
|
||||
|
||||
@ -306,9 +312,10 @@ public final class ProfileGiftsCollectionsContext {
|
||||
return self.stateValue.get()
|
||||
}
|
||||
|
||||
public init(account: Account, peerId: EnginePeer.Id) {
|
||||
public init(account: Account, peerId: EnginePeer.Id, allGiftsContext: ProfileGiftsContext?) {
|
||||
self.account = account
|
||||
self.peerId = peerId
|
||||
self.allGiftsContext = allGiftsContext
|
||||
|
||||
self.reload()
|
||||
}
|
||||
@ -362,7 +369,7 @@ public final class ProfileGiftsCollectionsContext {
|
||||
|
||||
public func updateCollection(id: Int32, actions: [UpdateAction]) -> Signal<StarGiftCollection?, NoError> {
|
||||
let giftsContext = self.giftsContextForCollection(id: id)
|
||||
return _internal_updateStarGiftCollection(account: self.account, peerId: self.peerId, collectionId: id, giftsContext: giftsContext, actions: actions)
|
||||
return _internal_updateStarGiftCollection(account: self.account, peerId: self.peerId, collectionId: id, giftsContext: giftsContext, allGiftsContext: self.allGiftsContext, actions: actions)
|
||||
|> deliverOn(self.queue)
|
||||
|> afterNext { [weak self] collection in
|
||||
guard let self else {
|
||||
|
@ -398,127 +398,92 @@ func generateCloseButtonImage(backgroundColor: UIColor, foregroundColor: UIColor
|
||||
|
||||
public func presentAgeVerification(context: AccountContext, parentController: ViewController, completion: @escaping () -> Void) {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let _ = (context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Configuration.ApplicationSpecificPreference(key: ApplicationSpecificPreferencesKeys.ageVerificationState)
|
||||
) |> deliverOnMainQueue).start(next: { [weak parentController] ageVerificationStatePreference in
|
||||
let state = ageVerificationStatePreference?.get(AgeVerificationState.self) ?? AgeVerificationState.default
|
||||
if state.verificationPassed {
|
||||
completion()
|
||||
} else {
|
||||
let miniappPromise = Promise<EnginePeer?>(nil)
|
||||
var useVerifyAgeBot = false
|
||||
if let value = context.currentAppConfiguration.with({ $0 }).data?["force_verify_age_bot"] as? Bool, value {
|
||||
useVerifyAgeBot = value
|
||||
}
|
||||
if useVerifyAgeBot, let verifyAgeBotUsername = context.currentAppConfiguration.with({ $0 }).data?["verify_age_bot_username"] as? String {
|
||||
miniappPromise.set(context.engine.peers.resolvePeerByName(name: verifyAgeBotUsername, referrer: nil)
|
||||
|> mapToSignal { result in
|
||||
if case let .result(peer) = result {
|
||||
return .single(peer)
|
||||
let _ = (contentSettingsConfiguration(network: context.account.network)
|
||||
|> deliverOnMainQueue).start(next: { [weak parentController] settings in
|
||||
if !settings.canAdjustSensitiveContent {
|
||||
let alertController = textAlertController(
|
||||
context: context,
|
||||
title: presentationData.strings.AgeVerification_Unavailable_Title,
|
||||
text: presentationData.strings.AgeVerification_Unavailable_Text,
|
||||
actions: []
|
||||
)
|
||||
parentController?.present(alertController, in: .window(.root))
|
||||
return
|
||||
}
|
||||
let miniappPromise = Promise<EnginePeer?>(nil)
|
||||
var useVerifyAgeBot = false
|
||||
if let value = context.currentAppConfiguration.with({ $0 }).data?["force_verify_age_bot"] as? Bool, value {
|
||||
useVerifyAgeBot = value
|
||||
}
|
||||
if useVerifyAgeBot, let verifyAgeBotUsername = context.currentAppConfiguration.with({ $0 }).data?["verify_age_bot_username"] as? String {
|
||||
miniappPromise.set(context.engine.peers.resolvePeerByName(name: verifyAgeBotUsername, referrer: nil)
|
||||
|> mapToSignal { result in
|
||||
if case let .result(peer) = result {
|
||||
return .single(peer)
|
||||
}
|
||||
return .complete()
|
||||
})
|
||||
}
|
||||
let infoScreen = AgeVerificationScreen(context: context, completion: { [weak parentController] check, availability in
|
||||
if check {
|
||||
var requiredAge = 18
|
||||
if let value = context.currentAppConfiguration.with({ $0 }).data?["verify_age_min"] as? Double {
|
||||
requiredAge = Int(value)
|
||||
}
|
||||
|
||||
let success = { [weak parentController] in
|
||||
completion()
|
||||
|
||||
let navigationController = parentController?.navigationController
|
||||
Queue.mainQueue().after(2.0) {
|
||||
let controller = UndoOverlayController(presentationData: presentationData, content: .actionSucceeded(title: presentationData.strings.AgeVerification_Success_Title, text: presentationData.strings.AgeVerification_Success_Text, cancel: nil, destructive: false), action: { _ in return true })
|
||||
(navigationController?.viewControllers.last as? ViewController)?.present(controller, in: .current)
|
||||
}
|
||||
return .complete()
|
||||
})
|
||||
}
|
||||
let infoScreen = AgeVerificationScreen(context: context, completion: { [weak parentController] check, availability in
|
||||
if check {
|
||||
var requiredAge = 18
|
||||
if let value = context.currentAppConfiguration.with({ $0 }).data?["verify_age_min"] as? Double {
|
||||
requiredAge = Int(value)
|
||||
}
|
||||
|
||||
let success = { [weak parentController] in
|
||||
let _ = updateAgeVerificationState(engine: context.engine, { _ in
|
||||
return AgeVerificationState(verificationPassed: true)
|
||||
}).start()
|
||||
completion()
|
||||
|
||||
let navigationController = parentController?.navigationController
|
||||
Queue.mainQueue().after(2.0) {
|
||||
let controller = UndoOverlayController(presentationData: presentationData, content: .actionSucceeded(title: presentationData.strings.AgeVerification_Success_Title, text: presentationData.strings.AgeVerification_Success_Text, cancel: nil, destructive: false), action: { _ in return true })
|
||||
(navigationController?.viewControllers.last as? ViewController)?.present(controller, in: .current)
|
||||
}
|
||||
}
|
||||
|
||||
let failure = { [weak parentController] in
|
||||
let controller = UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_banned", scale: 0.066, colors: [:], title: presentationData.strings.AgeVerification_Fail_Title, text: presentationData.strings.AgeVerification_Fail_Text, customUndoText: nil, timeout: nil), action: { _ in return true })
|
||||
parentController?.present(controller, in: .current)
|
||||
}
|
||||
|
||||
let _ = (miniappPromise.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
if let peer, let parentController {
|
||||
context.sharedContext.openWebApp(
|
||||
context: context,
|
||||
parentController: parentController,
|
||||
updatedPresentationData: nil,
|
||||
botPeer: peer,
|
||||
chatPeer: nil,
|
||||
threadId: nil,
|
||||
buttonText: "",
|
||||
url: "",
|
||||
simple: true,
|
||||
source: .generic,
|
||||
skipTermsOfService: true,
|
||||
payload: nil,
|
||||
verifyAgeCompletion: { age in
|
||||
if age >= requiredAge {
|
||||
success()
|
||||
} else {
|
||||
failure()
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
let scanScreen = FaceScanScreen(context: context, availability: availability, completion: { age in
|
||||
}
|
||||
|
||||
let failure = { [weak parentController] in
|
||||
let controller = UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_banned", scale: 0.066, colors: [:], title: presentationData.strings.AgeVerification_Fail_Title, text: presentationData.strings.AgeVerification_Fail_Text, customUndoText: nil, timeout: nil), action: { _ in return true })
|
||||
parentController?.present(controller, in: .current)
|
||||
}
|
||||
|
||||
let _ = (miniappPromise.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
if let peer, let parentController {
|
||||
context.sharedContext.openWebApp(
|
||||
context: context,
|
||||
parentController: parentController,
|
||||
updatedPresentationData: nil,
|
||||
botPeer: peer,
|
||||
chatPeer: nil,
|
||||
threadId: nil,
|
||||
buttonText: "",
|
||||
url: "",
|
||||
simple: true,
|
||||
source: .generic,
|
||||
skipTermsOfService: true,
|
||||
payload: nil,
|
||||
verifyAgeCompletion: { age in
|
||||
if age >= requiredAge {
|
||||
success()
|
||||
} else {
|
||||
failure()
|
||||
}
|
||||
})
|
||||
parentController?.push(scanScreen)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
parentController?.push(infoScreen)
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
let scanScreen = FaceScanScreen(context: context, availability: availability, completion: { age in
|
||||
if age >= requiredAge {
|
||||
success()
|
||||
} else {
|
||||
failure()
|
||||
}
|
||||
})
|
||||
parentController?.push(scanScreen)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
parentController?.push(infoScreen)
|
||||
})
|
||||
}
|
||||
|
||||
public func updateAgeVerificationState(engine: TelegramEngine, _ f: @escaping (AgeVerificationState) -> AgeVerificationState) -> Signal<Never, NoError> {
|
||||
return engine.preferences.update(id: ApplicationSpecificPreferencesKeys.ageVerificationState, { entry in
|
||||
let currentSettings: AgeVerificationState
|
||||
if let entry = entry?.get(AgeVerificationState.self) {
|
||||
currentSettings = entry
|
||||
} else {
|
||||
currentSettings = .default
|
||||
}
|
||||
return SharedPreferencesEntry(f(currentSettings))
|
||||
})
|
||||
}
|
||||
|
||||
public struct AgeVerificationState: Equatable, Codable {
|
||||
public var verificationPassed: Bool
|
||||
|
||||
public static var `default`: AgeVerificationState {
|
||||
return AgeVerificationState(verificationPassed: false)
|
||||
}
|
||||
|
||||
public init(verificationPassed: Bool) {
|
||||
self.verificationPassed = verificationPassed
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||
|
||||
self.verificationPassed = (try container.decode(Int32.self, forKey: "verificationPassed")) != 0
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: StringCodingKey.self)
|
||||
|
||||
try container.encode((self.verificationPassed ? 1 : 0) as Int32, forKey: "verificationPassed")
|
||||
}
|
||||
}
|
||||
|
@ -1082,7 +1082,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
if case .user = kind {
|
||||
if isMyProfile || userPeerId != context.account.peerId {
|
||||
profileGiftsContext = existingProfileGiftsContext ?? ProfileGiftsContext(account: context.account, peerId: userPeerId)
|
||||
profileGiftsCollectionsContext = existingProfileGiftsCollectionsContext ?? ProfileGiftsCollectionsContext(account: context.account, peerId: userPeerId)
|
||||
profileGiftsCollectionsContext = existingProfileGiftsCollectionsContext ?? ProfileGiftsCollectionsContext(account: context.account, peerId: userPeerId, allGiftsContext: profileGiftsContext)
|
||||
} else {
|
||||
profileGiftsContext = nil
|
||||
profileGiftsCollectionsContext = nil
|
||||
@ -1629,7 +1629,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
}
|
||||
|
||||
let profileGiftsContext = ProfileGiftsContext(account: context.account, peerId: peerId)
|
||||
let profileGiftsCollectionsContext = ProfileGiftsCollectionsContext(account: context.account, peerId: peerId)
|
||||
let profileGiftsCollectionsContext = ProfileGiftsCollectionsContext(account: context.account, peerId: peerId, allGiftsContext: profileGiftsContext)
|
||||
|
||||
let personalChannel = peerInfoPersonalOrLinkedChannel(context: context, peerId: peerId, isSettings: false)
|
||||
|
||||
|
@ -538,8 +538,6 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
)
|
||||
self.parentController?.presentInGlobalOverlay(contextController)
|
||||
}
|
||||
|
||||
|
||||
|
||||
func updateScrolling(interactive: Bool = false, transition: ComponentTransition) {
|
||||
if let params = self.currentParams {
|
||||
@ -590,12 +588,12 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
)
|
||||
)),
|
||||
isReorderable: collections.count > 1,
|
||||
contextAction: { [weak self] sourceNode, gesture in
|
||||
contextAction: canEditCollections ? { [weak self] sourceNode, gesture in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.openCollectionContextMenu(id: collection.id, sourceNode: sourceNode, gesture: gesture)
|
||||
}
|
||||
} : nil
|
||||
))
|
||||
}
|
||||
|
||||
@ -1024,6 +1022,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
let undoController = UndoOverlayController(
|
||||
presentationData: currentParams.presentationData,
|
||||
content: .sticker(context: self.context, file: giftFile, loop: false, title: nil, text: text, undoText: nil, customAction: nil),
|
||||
elevatedLayout: true,
|
||||
action: { _ in return true }
|
||||
)
|
||||
self.parentController?.present(undoController, in: .current)
|
||||
@ -1302,8 +1301,43 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Context_RemoveFromCollection, textColor: .destructive, textLayout: .twoLinesMax, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Peer Info/Gifts/RemoveFromCollection"), color: theme.contextMenu.destructiveColor) }, action: { [weak self] c, f in
|
||||
f(.default)
|
||||
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
if let reference = gift.reference {
|
||||
let _ = self?.profileGiftsCollections.removeGifts(id: id, gifts: [reference]).start()
|
||||
let _ = self.profileGiftsCollections.removeGifts(id: id, gifts: [reference]).start()
|
||||
}
|
||||
|
||||
var giftFile: TelegramMediaFile?
|
||||
var giftTitle: String?
|
||||
switch gift.gift {
|
||||
case let .generic(gift):
|
||||
giftFile = gift.file
|
||||
case let .unique(uniqueGift):
|
||||
giftTitle = uniqueGift.title + " #\(presentationStringsFormattedNumber(uniqueGift.number, currentParams.presentationData.dateTimeFormat.groupingSeparator))"
|
||||
for attribute in uniqueGift.attributes {
|
||||
if case let .model(_, file, _) = attribute {
|
||||
giftFile = file
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let giftFile, let collection = self.collections?.first(where: { $0.id == id }) {
|
||||
let text: String
|
||||
if let giftTitle {
|
||||
text = currentParams.presentationData.strings.PeerInfo_Gifts_RemovedFromCollectionUnique(giftTitle, collection.title).string
|
||||
} else {
|
||||
text = currentParams.presentationData.strings.PeerInfo_Gifts_RemovedFromCollection(collection.title).string
|
||||
}
|
||||
|
||||
let undoController = UndoOverlayController(
|
||||
presentationData: currentParams.presentationData,
|
||||
content: .sticker(context: self.context, file: giftFile, loop: false, title: nil, text: text, undoText: nil, customAction: nil),
|
||||
elevatedLayout: true,
|
||||
action: { _ in return true }
|
||||
)
|
||||
self.parentController?.present(undoController, in: .current)
|
||||
}
|
||||
})))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user