mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Various fixes
This commit is contained in:
parent
f6ff9b86d0
commit
5d25d2bb8a
11 changed files with 96 additions and 33 deletions
|
|
@ -8939,3 +8939,5 @@ Sorry for the inconvenience.";
|
|||
"ChatList.ClearSavedMessagesConfirmation" = "Are you sure you want to delete all your saved messages?";
|
||||
|
||||
"Conversation.Translation.Settings" = "Settings";
|
||||
"GroupPermission.NotAvailableInDiscussionGroups" = "This permission is not available in discussion groups.";
|
||||
"GroupPermission.NotAvailableInGeoGroups" = "This permission is not available in location-based groups.";
|
||||
|
|
|
|||
|
|
@ -665,7 +665,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||
if threadId == 1 {
|
||||
titleTopicIconContent = .image(image: PresentationResourcesChatList.generalTopicSmallIcon(theme))
|
||||
} else if let fileId = iconId, fileId != 0 {
|
||||
titleTopicIconContent = .animation(content: .customEmoji(fileId: fileId), size: CGSize(width: 36.0, height: 36.0), placeholderColor: theme.list.mediaPlaceholderColor, themeColor: theme.list.itemAccentColor, loopMode: .count(2))
|
||||
titleTopicIconContent = .animation(content: .customEmoji(fileId: fileId), size: CGSize(width: 36.0, height: 36.0), placeholderColor: theme.list.mediaPlaceholderColor, themeColor: theme.list.itemAccentColor, loopMode: .count(0))
|
||||
} else {
|
||||
titleTopicIconContent = .topic(title: String(title.string.prefix(1)), color: iconColor, size: CGSize(width: 18.0, height: 18.0))
|
||||
}
|
||||
|
|
@ -2778,7 +2778,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||
if threadInfo.id == 1 {
|
||||
avatarIconContent = .image(image: PresentationResourcesChatList.generalTopicIcon(item.presentationData.theme))
|
||||
} else if let fileId = threadInfo.info.icon, fileId != 0 {
|
||||
avatarIconContent = .animation(content: .customEmoji(fileId: fileId), size: CGSize(width: 48.0, height: 48.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(2))
|
||||
avatarIconContent = .animation(content: .customEmoji(fileId: fileId), size: CGSize(width: 48.0, height: 48.0), placeholderColor: item.presentationData.theme.list.mediaPlaceholderColor, themeColor: item.presentationData.theme.list.itemAccentColor, loopMode: .count(0))
|
||||
} else {
|
||||
avatarIconContent = .topic(title: String(threadInfo.info.title.prefix(1)), color: threadInfo.info.iconColor, size: CGSize(width: 32.0, height: 32.0))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ public final class JoinLinkPreviewController: ViewController {
|
|||
strongSelf.isGroup = !invite.flags.isBroadcast
|
||||
strongSelf.controllerNode.setRequestPeer(image: invite.photoRepresentation, title: invite.title, about: invite.about, memberCount: invite.participantsCount, isGroup: !invite.flags.isBroadcast)
|
||||
} else {
|
||||
let data = JoinLinkPreviewData(isGroup: invite.participants != nil, isJoined: false)
|
||||
let data = JoinLinkPreviewData(isGroup: !invite.flags.isBroadcast, isJoined: false)
|
||||
strongSelf.controllerNode.setInvitePeer(image: invite.photoRepresentation, title: invite.title, memberCount: invite.participantsCount, members: invite.participants?.map({ $0 }) ?? [], data: data)
|
||||
}
|
||||
case let .alreadyJoined(peer):
|
||||
|
|
|
|||
|
|
@ -461,7 +461,7 @@ public final class LegacyPaintEntityRenderer: NSObject, TGPhotoPaintEntityRender
|
|||
}
|
||||
}
|
||||
|
||||
func gcd(_ a: Int32, _ b: Int32) -> Int32 {
|
||||
func gcd(_ a: Int64, _ b: Int64) -> Int64 {
|
||||
let remainder = a % b
|
||||
if remainder != 0 {
|
||||
return gcd(b, remainder)
|
||||
|
|
@ -470,7 +470,7 @@ public final class LegacyPaintEntityRenderer: NSObject, TGPhotoPaintEntityRender
|
|||
}
|
||||
}
|
||||
|
||||
func lcm(_ x: Int32, _ y: Int32) -> Int32 {
|
||||
func lcm(_ x: Int64, _ y: Int64) -> Int64 {
|
||||
return x / gcd(x, y) * y
|
||||
}
|
||||
|
||||
|
|
@ -480,7 +480,7 @@ public final class LegacyPaintEntityRenderer: NSObject, TGPhotoPaintEntityRender
|
|||
let minDuration: Double = 3.0
|
||||
if durations.count > 1 {
|
||||
let reduced = durations.reduce(1.0) { lhs, rhs -> Double in
|
||||
return Double(lcm(Int32(lhs * 10.0), Int32(rhs * 10.0)))
|
||||
return Double(lcm(Int64(lhs * 10.0), Int64(rhs * 10.0)))
|
||||
}
|
||||
result = min(6.0, Double(reduced) / 10.0)
|
||||
} else if let duration = durations.first {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
|
|||
|
||||
private let modalPresentation: Bool
|
||||
|
||||
private let coverNode: ASDisplayNode
|
||||
private var backgroundCustomNode: ASDisplayNode?
|
||||
private let backgroundDimNode: ASDisplayNode
|
||||
private let backgroundImageNode: ASImageNode
|
||||
|
|
@ -70,6 +71,9 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
|
|||
self.arguments = arguments
|
||||
self.modalPresentation = modalPresentation
|
||||
|
||||
self.coverNode = ASDisplayNode()
|
||||
self.coverNode.backgroundColor = .black
|
||||
|
||||
self.backgroundImageNode = ASImageNode()
|
||||
self.backgroundImageNode.contentMode = .scaleToFill
|
||||
|
||||
|
|
@ -140,6 +144,7 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
|
|||
}
|
||||
}
|
||||
|
||||
self.addSubnode(self.coverNode)
|
||||
self.addSubnode(self.backgroundImageNode)
|
||||
self.addSubnode(self.backgroundDimNode)
|
||||
self.addSubnode(self.iconNode)
|
||||
|
|
@ -238,8 +243,10 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
|
|||
color3 = baseColor.withMultiplied(hue: 1.029, saturation: 0.729, brightness: 1.231)
|
||||
color4 = baseColor.withMultiplied(hue: 1.034, saturation: 0.583, brightness: 1.043)
|
||||
}
|
||||
self.coverNode.backgroundColor = color3
|
||||
self.background = CustomPasscodeBackground(size: size, colors: [color1, color2, color3, color4], inverted: false)
|
||||
case let .gradient(gradient):
|
||||
self.coverNode.backgroundColor = gradient.colors.first.flatMap { UIColor(rgb: $0) }
|
||||
self.background = CustomPasscodeBackground(size: size, colors: gradient.colors.compactMap { UIColor(rgb: $0) }, inverted: (gradient.settings.intensity ?? 0) < 0)
|
||||
case .image, .file:
|
||||
if let image = chatControllerBackgroundImage(theme: self.theme, wallpaper: self.wallpaper, mediaBox: self.accountManager.mediaBox, composed: false, knockoutMode: false) {
|
||||
|
|
@ -252,6 +259,7 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
|
|||
}
|
||||
}
|
||||
default:
|
||||
self.coverNode.backgroundColor = self.theme.passcode.backgroundColors.bottomColor
|
||||
self.background = GradientPasscodeBackground(size: size, backgroundColors: self.theme.passcode.backgroundColors.colors, buttonColor: self.theme.passcode.buttonColor)
|
||||
}
|
||||
|
||||
|
|
@ -355,6 +363,8 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
|
|||
}
|
||||
|
||||
func animateIn(iconFrame: CGRect, completion: @escaping () -> Void = {}) {
|
||||
self.coverNode.isHidden = true
|
||||
|
||||
let effect = self.theme.overallDarkAppearance ? UIBlurEffect(style: .dark) : UIBlurEffect(style: .light)
|
||||
UIView.animate(withDuration: 0.3, animations: {
|
||||
if #available(iOS 9.0, *) {
|
||||
|
|
@ -386,6 +396,8 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
|
|||
self.biometricButtonNode.isHidden = true
|
||||
|
||||
self.titleNode.setAttributedText(NSAttributedString(string: self.strings.Passcode_AppLockedAlert.replacingOccurrences(of: "\n", with: " "), font: titleFont, textColor: .white), animation: .slideIn, completion: {
|
||||
self.coverNode.isHidden = false
|
||||
|
||||
self.subtitleNode.isHidden = false
|
||||
self.inputFieldNode.isHidden = false
|
||||
self.keyboardNode.isHidden = false
|
||||
|
|
@ -447,6 +459,10 @@ final class PasscodeEntryControllerNode: ASDisplayNode {
|
|||
self.validLayout = layout
|
||||
|
||||
self.updateBackground()
|
||||
|
||||
let maxSide = max(layout.size.width, layout.size.height)
|
||||
let coverSize = CGSize(width: maxSide, height: maxSide)
|
||||
self.coverNode.frame = CGRect(origin: CGPoint(x: round((layout.size.width - coverSize.width) / 2.0), y: round((layout.size.height - coverSize.height) / 2.0)), size: coverSize)
|
||||
|
||||
let bounds = CGRect(origin: CGPoint(), size: layout.size)
|
||||
transition.updateFrame(node: self.backgroundImageNode, frame: bounds)
|
||||
|
|
|
|||
|
|
@ -547,6 +547,11 @@ private func channelPermissionsControllerEntries(context: AccountContext, presen
|
|||
var entries: [ChannelPermissionsEntry] = []
|
||||
|
||||
if let channel = view.peers[view.peerId] as? TelegramChannel, let participants = participants, let cachedData = view.cachedData as? CachedChannelData, let defaultBannedRights = channel.defaultBannedRights {
|
||||
var isDiscussion = false
|
||||
if case .group = channel.info, case let .known(peerId) = cachedData.linkedDiscussionPeerId, peerId != nil {
|
||||
isDiscussion = true
|
||||
}
|
||||
|
||||
let effectiveRightsFlags: TelegramChatBannedRightsFlags
|
||||
if let modifiedRightsFlags = state.modifiedRightsFlags {
|
||||
effectiveRightsFlags = modifiedRightsFlags
|
||||
|
|
@ -558,7 +563,7 @@ private func channelPermissionsControllerEntries(context: AccountContext, presen
|
|||
var rightIndex: Int = 0
|
||||
for (rights, correspondingAdminRight) in allGroupPermissionList(peer: .channel(channel), expandMedia: false) {
|
||||
var enabled = true
|
||||
if channel.addressName != nil && publicGroupRestrictedPermissions.contains(rights) {
|
||||
if (channel.addressName != nil || channel.flags.contains(.hasGeo) || isDiscussion) && publicGroupRestrictedPermissions.contains(rights) {
|
||||
enabled = false
|
||||
}
|
||||
if !channel.hasPermission(.inviteMembers) {
|
||||
|
|
@ -938,7 +943,17 @@ public func channelPermissionsController(context: AccountContext, updatedPresent
|
|||
} else if right.contains(.banAddMembers) {
|
||||
text = presentationData.strings.GroupPermission_AddMembersNotAvailable
|
||||
} else {
|
||||
text = presentationData.strings.GroupPermission_NotAvailableInPublicGroups
|
||||
var isDiscussion = false
|
||||
if case .group = channel.info, let cachedData = view.cachedData as? CachedChannelData, case let .known(peerId) = cachedData.linkedDiscussionPeerId, peerId != nil {
|
||||
isDiscussion = true
|
||||
}
|
||||
if channel.flags.contains(.hasGeo) {
|
||||
text = presentationData.strings.GroupPermission_NotAvailableInGeoGroups
|
||||
} else if isDiscussion {
|
||||
text = presentationData.strings.GroupPermission_NotAvailableInDiscussionGroups
|
||||
} else {
|
||||
text = presentationData.strings.GroupPermission_NotAvailableInPublicGroups
|
||||
}
|
||||
}
|
||||
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||
break
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ public extension TelegramChannel {
|
|||
if let defaultBannedRights = self.defaultBannedRights, defaultBannedRights.flags.contains(.banChangeInfo) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
return true
|
||||
}
|
||||
case .addAdmins:
|
||||
if let adminRights = self.adminRights, adminRights.rights.contains(.canAddAdmins) {
|
||||
|
|
|
|||
|
|
@ -396,7 +396,7 @@ private final class TopicIconSelectionComponent: Component {
|
|||
component: AnyComponent(EntityKeyboardComponent(
|
||||
theme: component.theme,
|
||||
strings: component.strings,
|
||||
isContentInFocus: true,
|
||||
isContentInFocus: false,
|
||||
containerInsets: UIEdgeInsets(top: topPanelHeight - 34.0, left: 0.0, bottom: 0.0, right: 0.0),
|
||||
topPanelInsets: UIEdgeInsets(top: 0.0, left: 4.0, bottom: 0.0, right: 4.0),
|
||||
emojiContent: component.emojiContent,
|
||||
|
|
|
|||
|
|
@ -1467,7 +1467,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
|||
break
|
||||
}
|
||||
}
|
||||
if let file = media as? TelegramMediaFile, !chatPresentationInterfaceState.copyProtectionEnabled && !message.isCopyProtected() {
|
||||
if let file = media as? TelegramMediaFile, !isCopyProtected {
|
||||
if file.isVideo {
|
||||
if file.isAnimated && !file.isVideoSticker {
|
||||
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_SaveGif, icon: { theme in
|
||||
|
|
@ -1518,11 +1518,9 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
|||
f(.dismissWithoutContent)
|
||||
})))
|
||||
}
|
||||
|
||||
|
||||
if data.messageActions.options.contains(.forward) {
|
||||
if chatPresentationInterfaceState.copyProtectionEnabled || message.isCopyProtected() {
|
||||
|
||||
} else {
|
||||
if !isCopyProtected {
|
||||
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_ContextMenuForward, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Forward"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
|
|
|
|||
|
|
@ -1298,8 +1298,12 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
|||
}
|
||||
}
|
||||
|
||||
if !needsShareButton, let author = item.message.author as? TelegramUser, let _ = author.botInfo, !item.message.media.isEmpty && !(item.message.media.first is TelegramMediaAction) {
|
||||
needsShareButton = true
|
||||
if !needsShareButton, let author = item.message.author as? TelegramUser, let _ = author.botInfo {
|
||||
if !item.message.media.isEmpty && !(item.message.media.first is TelegramMediaAction) {
|
||||
needsShareButton = true
|
||||
} else if author.id == PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(92386307)) {
|
||||
needsShareButton = true
|
||||
}
|
||||
}
|
||||
var mayHaveSeparateCommentsButton = false
|
||||
if !needsShareButton {
|
||||
|
|
|
|||
|
|
@ -1850,27 +1850,43 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL
|
|||
interaction.editingOpenPreHistorySetup()
|
||||
}))
|
||||
|
||||
do {
|
||||
let label: String
|
||||
if let cachedData = data.cachedData as? CachedGroupData, case let .known(allowedReactions) = cachedData.allowedReactions {
|
||||
switch allowedReactions {
|
||||
case .all:
|
||||
label = presentationData.strings.PeerInfo_LabelAllReactions
|
||||
case .empty:
|
||||
label = presentationData.strings.PeerInfo_ReactionsDisabled
|
||||
case let .limited(reactions):
|
||||
label = "\(reactions.count)"
|
||||
}
|
||||
} else {
|
||||
label = ""
|
||||
|
||||
let label: String
|
||||
if let cachedData = data.cachedData as? CachedGroupData, case let .known(allowedReactions) = cachedData.allowedReactions {
|
||||
switch allowedReactions {
|
||||
case .all:
|
||||
label = presentationData.strings.PeerInfo_LabelAllReactions
|
||||
case .empty:
|
||||
label = presentationData.strings.PeerInfo_ReactionsDisabled
|
||||
case let .limited(reactions):
|
||||
label = "\(reactions.count)"
|
||||
}
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemReactions, label: .text(label), text: presentationData.strings.PeerInfo_Reactions, icon: UIImage(bundleImageName: "Settings/Menu/Reactions"), action: {
|
||||
interaction.editingOpenReactionsSetup()
|
||||
}))
|
||||
} else {
|
||||
label = ""
|
||||
}
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemReactions, label: .text(label), text: presentationData.strings.PeerInfo_Reactions, icon: UIImage(bundleImageName: "Settings/Menu/Reactions"), action: {
|
||||
interaction.editingOpenReactionsSetup()
|
||||
}))
|
||||
|
||||
canViewAdminsAndBanned = true
|
||||
} else if case let .admin(rights, _) = group.role {
|
||||
let label: String
|
||||
if let cachedData = data.cachedData as? CachedGroupData, case let .known(allowedReactions) = cachedData.allowedReactions {
|
||||
switch allowedReactions {
|
||||
case .all:
|
||||
label = presentationData.strings.PeerInfo_LabelAllReactions
|
||||
case .empty:
|
||||
label = presentationData.strings.PeerInfo_ReactionsDisabled
|
||||
case let .limited(reactions):
|
||||
label = "\(reactions.count)"
|
||||
}
|
||||
} else {
|
||||
label = ""
|
||||
}
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemReactions, label: .text(label), text: presentationData.strings.PeerInfo_Reactions, icon: UIImage(bundleImageName: "Settings/Menu/Reactions"), action: {
|
||||
interaction.editingOpenReactionsSetup()
|
||||
}))
|
||||
|
||||
if rights.rights.contains(.canInviteUsers) {
|
||||
let invitesText: String
|
||||
if let count = data.invitations?.count, count > 0 {
|
||||
|
|
@ -3440,10 +3456,16 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||
}))
|
||||
}
|
||||
|
||||
var previousTimestamp: Double?
|
||||
self.headerNode.displayPremiumIntro = { [weak self] sourceView, _, _, _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let currentTimestamp = CACurrentMediaTime()
|
||||
if let previousTimestamp, currentTimestamp < previousTimestamp + 1.0 {
|
||||
return
|
||||
}
|
||||
previousTimestamp = currentTimestamp
|
||||
|
||||
let animationCache = context.animationCache
|
||||
let animationRenderer = context.animationRenderer
|
||||
|
|
@ -3494,10 +3516,16 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||
} else {
|
||||
screenData = peerInfoScreenData(context: context, peerId: peerId, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, isSettings: self.isSettings, hintGroupInCommon: hintGroupInCommon, existingRequestsContext: requestsContext, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder)
|
||||
|
||||
var previousTimestamp: Double?
|
||||
self.headerNode.displayPremiumIntro = { [weak self] sourceView, peerStatus, emojiStatusFileAndPack, white in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let currentTimestamp = CACurrentMediaTime()
|
||||
if let previousTimestamp, currentTimestamp < previousTimestamp + 1.0 {
|
||||
return
|
||||
}
|
||||
previousTimestamp = currentTimestamp
|
||||
|
||||
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: strongSelf.context.currentAppConfiguration.with { $0 })
|
||||
guard !premiumConfiguration.isPremiumDisabled else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue