Various fixes

This commit is contained in:
Ilya Laktyushin 2021-02-25 23:12:58 +04:00
parent 3e83207ec5
commit 3992f1c8b3
25 changed files with 4627 additions and 4583 deletions

View File

@ -6153,3 +6153,5 @@ Sorry for the inconvenience.";
"Conversation.UsersTooMuchError" = "Sorry, this group is full."; "Conversation.UsersTooMuchError" = "Sorry, this group is full.";
"Conversation.UploadFileTooLarge" = "File could not be sent, because it is larger than 2 GB.\n\nYou can send as many files as you like, but each must be smaller than 2 GB."; "Conversation.UploadFileTooLarge" = "File could not be sent, because it is larger than 2 GB.\n\nYou can send as many files as you like, but each must be smaller than 2 GB.";
"Channel.AddUserLeftError" = "Sorry, if a person is no longer part of a channel, you need to be in their Telegram contacts in order to add them back.\n\nNote that they can still join via the channel's invite link as long as they are not in the Removed Users list.";

View File

@ -911,15 +911,20 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
if let strongSelf = self, !messages.isEmpty { if let strongSelf = self, !messages.isEmpty {
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
var generalMessageContentKind: MessageContentKind? var generalMessageContentKind: MessageContentKind?
var beganContentKindScanning = false
var messageContentKinds = Set<MessageContentKindKey>()
for message in messages { for message in messages {
let currentKind = messageContentKind(contentSettings: strongSelf.context.currentContentSettings.with { $0 }, message: message, strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder, accountPeerId: strongSelf.context.account.peerId) let currentKind = messageContentKind(contentSettings: strongSelf.context.currentContentSettings.with { $0 }, message: message, strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder, accountPeerId: strongSelf.context.account.peerId)
if generalMessageContentKind == nil || generalMessageContentKind == currentKind { if beganContentKindScanning && currentKind != generalMessageContentKind {
generalMessageContentKind = currentKind
} else {
generalMessageContentKind = nil generalMessageContentKind = nil
break } else if !beganContentKindScanning || currentKind == generalMessageContentKind {
beganContentKindScanning = true
generalMessageContentKind = currentKind
} }
messageContentKinds.insert(currentKind.key)
} }
var preferredAction = ShareControllerPreferredAction.default var preferredAction = ShareControllerPreferredAction.default
if let generalMessageContentKind = generalMessageContentKind { if let generalMessageContentKind = generalMessageContentKind {
switch generalMessageContentKind { switch generalMessageContentKind {
@ -928,6 +933,8 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
default: default:
break break
} }
} else if messageContentKinds.count == 2 && messageContentKinds.contains(.image) && messageContentKinds.contains(.video) {
preferredAction = .saveToCameraRoll
} }
if messages.count == 1 { if messages.count == 1 {

View File

@ -164,7 +164,11 @@ open class ZoomableContentGalleryItemNode: GalleryItemNode, UIScrollViewDelegate
self.centerScrollViewContents(transition: transition) self.centerScrollViewContents(transition: transition)
self.ignoreZoom = false self.ignoreZoom = false
let updatedZoomScale = self.scrollNode.view.zoomScale != self.scrollNode.view.minimumZoomScale
self.scrollNode.view.zoomScale = self.scrollNode.view.minimumZoomScale self.scrollNode.view.zoomScale = self.scrollNode.view.minimumZoomScale
if !updatedZoomScale {
self.scrollViewDidZoom(self.scrollNode.view)
}
self.ignoreZoomTransition = nil self.ignoreZoomTransition = nil
} }

View File

@ -4,7 +4,7 @@
#define GPUImageRotationSwapsWidthAndHeight(rotation) ((rotation) == kGPUImageRotateLeft || (rotation) == kGPUImageRotateRight || (rotation) == kGPUImageRotateRightFlipVertical || (rotation) == kGPUImageRotateRightFlipHorizontal) #define GPUImageRotationSwapsWidthAndHeight(rotation) ((rotation) == kGPUImageRotateLeft || (rotation) == kGPUImageRotateRight || (rotation) == kGPUImageRotateRightFlipVertical || (rotation) == kGPUImageRotateRightFlipHorizontal)
typedef enum { kGPUImageNoRotation, kGPUImageRotateLeft, kGPUImageRotateRight, kGPUImageFlipVertical, kGPUImageFlipHorizonal, kGPUImageRotateRightFlipVertical, kGPUImageRotateRightFlipHorizontal, kGPUImageRotate180 } GPUImageRotationMode; typedef enum { kGPUImageNoRotation, kGPUImageRotateLeft, kGPUImageRotateRight, kGPUImageFlipVertical, kGPUImageFlipHorizonal, kGPUImageRotateRightFlipVertical, kGPUImageRotateRightFlipHorizontal, kGPUImageRotate180, kGPUImageRotate180FlipHorizontal } GPUImageRotationMode;
@interface GPUImageContext : NSObject @interface GPUImageContext : NSObject

View File

@ -284,6 +284,13 @@ NSString *const kGPUImagePassthroughFragmentShaderString = SHADER_STRING
0.0f, 0.0f, 0.0f, 0.0f,
}; };
static const GLfloat rotate180HorizontalFlipTextureCoordinates[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
};
switch(rotationMode) switch(rotationMode)
{ {
case kGPUImageNoRotation: return noRotationTextureCoordinates; case kGPUImageNoRotation: return noRotationTextureCoordinates;
@ -294,6 +301,7 @@ NSString *const kGPUImagePassthroughFragmentShaderString = SHADER_STRING
case kGPUImageRotateRightFlipVertical: return rotateRightVerticalFlipTextureCoordinates; case kGPUImageRotateRightFlipVertical: return rotateRightVerticalFlipTextureCoordinates;
case kGPUImageRotateRightFlipHorizontal: return rotateRightHorizontalFlipTextureCoordinates; case kGPUImageRotateRightFlipHorizontal: return rotateRightHorizontalFlipTextureCoordinates;
case kGPUImageRotate180: return rotate180TextureCoordinates; case kGPUImageRotate180: return rotate180TextureCoordinates;
case kGPUImageRotate180FlipHorizontal: return rotate180HorizontalFlipTextureCoordinates;
} }
} }
@ -642,6 +650,11 @@ NSString *const kGPUImagePassthroughFragmentShaderString = SHADER_STRING
rotatedPoint.x = 1.0f - pointToRotate.x; rotatedPoint.x = 1.0f - pointToRotate.x;
rotatedPoint.y = 1.0f - pointToRotate.y; rotatedPoint.y = 1.0f - pointToRotate.y;
}; break; }; break;
case kGPUImageRotate180FlipHorizontal:
{
rotatedPoint.x = pointToRotate.x;
rotatedPoint.y = 1.0f - pointToRotate.y;
}; break;
} }
return rotatedPoint; return rotatedPoint;

View File

@ -214,7 +214,7 @@
_rotationMode = cropMirrored ? kGPUImageRotateRightFlipHorizontal : kGPUImageRotateRight; _rotationMode = cropMirrored ? kGPUImageRotateRightFlipHorizontal : kGPUImageRotateRight;
break; break;
case UIImageOrientationDown: case UIImageOrientationDown:
_rotationMode = kGPUImageRotate180; _rotationMode = cropMirrored ? kGPUImageRotate180FlipHorizontal : kGPUImageRotate180;
break; break;
case UIImageOrientationUp: case UIImageOrientationUp:
if (cropMirrored) if (cropMirrored)

View File

@ -285,6 +285,13 @@
0.0f, 1.0f, 0.0f, 1.0f,
}; };
static const GLfloat rotate180HorizontalFlipTextureCoordinates[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
};
switch(rotationMode) switch(rotationMode)
{ {
case kGPUImageNoRotation: return noRotationTextureCoordinates; case kGPUImageNoRotation: return noRotationTextureCoordinates;
@ -295,6 +302,7 @@
case kGPUImageRotateRightFlipVertical: return rotateRightVerticalFlipTextureCoordinates; case kGPUImageRotateRightFlipVertical: return rotateRightVerticalFlipTextureCoordinates;
case kGPUImageRotateRightFlipHorizontal: return rotateRightHorizontalFlipTextureCoordinates; case kGPUImageRotateRightFlipHorizontal: return rotateRightHorizontalFlipTextureCoordinates;
case kGPUImageRotate180: return rotate180TextureCoordinates; case kGPUImageRotate180: return rotate180TextureCoordinates;
case kGPUImageRotate180FlipHorizontal: return rotate180HorizontalFlipTextureCoordinates;
} }
} }

View File

@ -118,16 +118,20 @@ NSString *const kYUVVideoRangeConversionForLAFragmentShaderString = SHADER_STRIN
- (GPUImageRotationMode)rotationForTrack:(AVAsset *)asset { - (GPUImageRotationMode)rotationForTrack:(AVAsset *)asset {
AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
CGAffineTransform trackTransform = [videoTrack preferredTransform]; CGAffineTransform t = [videoTrack preferredTransform];
if (trackTransform.a == -1 && trackTransform.d == -1) { if (t.a == -1 && t.d == -1) {
return kGPUImageRotate180; return kGPUImageRotate180;
} else if (trackTransform.a == 1 && trackTransform.d == 1) { } else if (t.a == 1 && t.d == 1) {
return kGPUImageNoRotation; return kGPUImageNoRotation;
} else if (trackTransform.b == -1 && trackTransform.c == 1) { } else if (t.b == -1 && t.c == 1) {
return kGPUImageRotateLeft; return kGPUImageRotateLeft;
} else if (t.a == -1 && t.d == 1) {
return kGPUImageFlipHorizonal;
} else if (t.a == 1 && t.d == -1) {
return kGPUImageRotate180FlipHorizontal;
} else { } else {
if (trackTransform.c == 1) { if (t.c == 1) {
return kGPUImageRotateRightFlipVertical; return kGPUImageRotateRightFlipVertical;
} else { } else {
return kGPUImageRotateRight; return kGPUImageRotateRight;

View File

@ -593,28 +593,30 @@ UIImageOrientation TGVideoOrientationForAsset(AVAsset *asset, bool *mirrored)
{ {
AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] firstObject]; AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] firstObject];
CGAffineTransform t = videoTrack.preferredTransform; CGAffineTransform t = videoTrack.preferredTransform;
double videoRotation = atan2((float)t.b, (float)t.a);
if (mirrored != NULL) if (t.a == -1 && t.d == -1) {
{
CGFloat scaleX = sqrt(t.a * t.a + t.c * t.c);
CGFloat scaleY = sqrt(t.b * t.b + t.d * t.d);
CGSize scale = CGSizeMake(scaleX, scaleY);
*mirrored = (scale.width < 0);
}
if (fabs(videoRotation - M_PI) < FLT_EPSILON) {
return UIImageOrientationLeft; return UIImageOrientationLeft;
} else if (fabs(videoRotation - M_PI_2) < FLT_EPSILON) { } else if (t.a == 1 && t.d == 1) {
if (t.c == 1 && mirrored != NULL) { return UIImageOrientationRight;
} else if (t.b == -1 && t.c == 1) {
return UIImageOrientationDown;
} else if (t.a == -1 && t.d == 1) {
if (mirrored != NULL) {
*mirrored = true;
}
return UIImageOrientationLeft;
} else if (t.a == 1 && t.d == -1) {
if (mirrored != NULL) {
*mirrored = true; *mirrored = true;
} }
return UIImageOrientationUp;
} else if (fabs(videoRotation + M_PI_2) < FLT_EPSILON) {
return UIImageOrientationDown;
} else {
return UIImageOrientationRight; return UIImageOrientationRight;
} else {
if (t.c == 1) {
if (mirrored != NULL) {
*mirrored = true;
}
}
return UIImageOrientationUp;
} }
} }

View File

@ -530,7 +530,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) -
} }
} }
} }
if estimatedSize > 5 * 1024 * 1024 { if estimatedSize > 10 * 1024 * 1024 {
fileAttributes.append(.hintFileIsLarge) fileAttributes.append(.hintFileIsLarge)
} }

View File

@ -1049,11 +1049,20 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi
case .tooMuchJoined: case .tooMuchJoined:
text = presentationData.strings.Group_ErrorSupergroupConversionNotPossible text = presentationData.strings.Group_ErrorSupergroupConversionNotPossible
case .restricted: case .restricted:
if let peer = adminView.peers[adminView.peerId] { if let admin = adminView.peers[adminView.peerId] {
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(peer.compactDisplayTitle, peer.compactDisplayTitle).0 switch channel.info {
case .broadcast:
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(admin.compactDisplayTitle, admin.compactDisplayTitle).0
case .group:
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(admin.compactDisplayTitle, admin.compactDisplayTitle).0
}
} }
case .notMutualContact: case .notMutualContact:
if case .broadcast = channel.info {
text = presentationData.strings.Channel_AddUserLeftError
} else {
text = presentationData.strings.GroupInfo_AddUserLeftError text = presentationData.strings.GroupInfo_AddUserLeftError
}
default: default:
break break
} }
@ -1119,17 +1128,28 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi
return current.withUpdatedUpdating(true) return current.withUpdatedUpdating(true)
} }
updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: context.account, peerId: peerId, memberId: adminId, adminRights: TelegramChatAdminRights(rights: updateFlags), rank: updateRank) |> deliverOnMainQueue).start(error: { error in updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: context.account, peerId: peerId, memberId: adminId, adminRights: TelegramChatAdminRights(rights: updateFlags), rank: updateRank) |> deliverOnMainQueue).start(error: { error in
if case let .addMemberError(error) = error, let admin = adminView.peers[adminView.peerId] { if case let .addMemberError(addMemberError) = error, let admin = adminView.peers[adminView.peerId] {
if case .restricted = error { var text = presentationData.strings.Login_UnknownError
var text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(admin.compactDisplayTitle, admin.compactDisplayTitle).0 switch addMemberError {
if case .group = channel.info { case .tooMuchJoined:
text = presentationData.strings.Group_ErrorSupergroupConversionNotPossible
case .restricted:
switch channel.info {
case .broadcast:
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(admin.compactDisplayTitle, admin.compactDisplayTitle).0
case .group:
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(admin.compactDisplayTitle, admin.compactDisplayTitle).0 text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(admin.compactDisplayTitle, admin.compactDisplayTitle).0
} }
presentControllerImpl?(textAlertController(context: context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) case .notMutualContact:
} else if case .tooMuchJoined = error { if case .broadcast = channel.info {
let text = presentationData.strings.Invite_ChannelsTooMuch text = presentationData.strings.Channel_AddUserLeftError
presentControllerImpl?(textAlertController(context: context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) } else {
text = presentationData.strings.GroupInfo_AddUserLeftError
} }
default:
break
}
presentControllerImpl?(textAlertController(context: context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
} else if case .adminsTooMuch = error { } else if case .adminsTooMuch = error {
let text: String let text: String
if case .broadcast = channel.info { if case .broadcast = channel.info {
@ -1146,7 +1166,7 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi
})) }))
} }
} }
} else if let group = channelView.peers[channelView.peerId] as? TelegramGroup { } else if let _ = channelView.peers[channelView.peerId] as? TelegramGroup {
var updateFlags: TelegramChatAdminRightsFlags? var updateFlags: TelegramChatAdminRightsFlags?
var updateRank: String? var updateRank: String?
updateState { current in updateState { current in
@ -1163,12 +1183,7 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi
} }
let maskRightsFlags: TelegramChatAdminRightsFlags = .groupSpecific let maskRightsFlags: TelegramChatAdminRightsFlags = .groupSpecific
let defaultFlags: TelegramChatAdminRightsFlags let defaultFlags = maskRightsFlags.subtracting([.canBeAnonymous, .canAddAdmins])
if case .creator = group.role {
defaultFlags = maskRightsFlags.subtracting(.canBeAnonymous)
} else {
defaultFlags = maskRightsFlags.subtracting(.canAddAdmins).subtracting(.canBeAnonymous)
}
if updateFlags == nil { if updateFlags == nil {
updateFlags = defaultFlags updateFlags = defaultFlags

View File

@ -370,6 +370,10 @@ public func channelMembersController(context: AccountContext, peerId: PeerId) ->
} }
}).start(error: { [weak contactsController] error in }).start(error: { [weak contactsController] error in
let presentationData = context.sharedContext.currentPresentationData.with { $0 } let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let _ = (context.account.postbox.transaction { transaction in
return transaction.getPeer(peerId)
}
|> deliverOnMainQueue).start(next: { peer in
let text: String let text: String
switch error { switch error {
case .limitExceeded: case .limitExceeded:
@ -381,16 +385,15 @@ public func channelMembersController(context: AccountContext, peerId: PeerId) ->
case .restricted: case .restricted:
text = presentationData.strings.Channel_ErrorAddBlocked text = presentationData.strings.Channel_ErrorAddBlocked
case .notMutualContact: case .notMutualContact:
if let peer = peer as? TelegramChannel, case .broadcast = peer.info {
text = presentationData.strings.Channel_AddUserLeftError
} else {
text = presentationData.strings.GroupInfo_AddUserLeftError text = presentationData.strings.GroupInfo_AddUserLeftError
case let .bot(memberId):
let _ = (context.account.postbox.transaction { transaction in
return transaction.getPeer(peerId)
} }
|> deliverOnMainQueue).start(next: { peer in case let .bot(memberId):
guard let peer = peer as? TelegramChannel else { guard let peer = peer as? TelegramChannel else {
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
contactsController?.dismiss() contactsController?.dismiss()
return return
} }
@ -407,7 +410,6 @@ public func channelMembersController(context: AccountContext, peerId: PeerId) ->
} }
contactsController?.dismiss() contactsController?.dismiss()
})
return return
case .botDoesntSupportGroups: case .botDoesntSupportGroups:
text = presentationData.strings.Channel_BotDoesntSupportGroups text = presentationData.strings.Channel_BotDoesntSupportGroups
@ -416,6 +418,7 @@ public func channelMembersController(context: AccountContext, peerId: PeerId) ->
} }
presentControllerImpl?(textAlertController(context: context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) presentControllerImpl?(textAlertController(context: context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
contactsController?.dismiss() contactsController?.dismiss()
})
})) }))
presentControllerImpl?(contactsController, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) presentControllerImpl?(contactsController, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))

View File

@ -128,7 +128,7 @@ private func preparedShareItem(account: Account, to peerId: PeerId, value: [Stri
let estimatedSize = TGMediaVideoConverter.estimatedSize(for: preset, duration: finalDuration, hasAudio: true) let estimatedSize = TGMediaVideoConverter.estimatedSize(for: preset, duration: finalDuration, hasAudio: true)
let resource = LocalFileVideoMediaResource(randomId: arc4random64(), path: asset.url.path, adjustments: resourceAdjustments) let resource = LocalFileVideoMediaResource(randomId: arc4random64(), path: asset.url.path, adjustments: resourceAdjustments)
return standaloneUploadedFile(account: account, peerId: peerId, text: "", source: .resource(.standalone(resource: resource)), mimeType: "video/mp4", attributes: [.Video(duration: Int(finalDuration), size: PixelDimensions(width: Int32(finalDimensions.width), height: Int32(finalDimensions.height)), flags: flags)], hintFileIsLarge: estimatedSize > 5 * 1024 * 1024) return standaloneUploadedFile(account: account, peerId: peerId, text: "", source: .resource(.standalone(resource: resource)), mimeType: "video/mp4", attributes: [.Video(duration: Int(finalDuration), size: PixelDimensions(width: Int32(finalDimensions.width), height: Int32(finalDimensions.height)), flags: flags)], hintFileIsLarge: estimatedSize > 10 * 1024 * 1024)
|> mapError { _ -> Void in |> mapError { _ -> Void in
return Void() return Void()
} }
@ -192,7 +192,7 @@ private func preparedShareItem(account: Account, to peerId: PeerId, value: [Stri
mimeType = "animation/gif" mimeType = "animation/gif"
attributes = [.ImageSize(size: PixelDimensions(width: Int32(dimensions.width), height: Int32(dimensions.height))), .Animated, .FileName(fileName: fileName ?? "animation.gif")] attributes = [.ImageSize(size: PixelDimensions(width: Int32(dimensions.width), height: Int32(dimensions.height))), .Animated, .FileName(fileName: fileName ?? "animation.gif")]
} }
return standaloneUploadedFile(account: account, peerId: peerId, text: "", source: .data(data), mimeType: mimeType, attributes: attributes, hintFileIsLarge: data.count > 5 * 1024 * 1024) return standaloneUploadedFile(account: account, peerId: peerId, text: "", source: .data(data), mimeType: mimeType, attributes: attributes, hintFileIsLarge: data.count > 10 * 1024 * 1024)
|> mapError { _ -> Void in return Void() } |> mapError { _ -> Void in return Void() }
|> mapToSignal { event -> Signal<PreparedShareItem, Void> in |> mapToSignal { event -> Signal<PreparedShareItem, Void> in
switch event { switch event {
@ -223,7 +223,7 @@ private func preparedShareItem(account: Account, to peerId: PeerId, value: [Stri
thumbnailData = jpegData thumbnailData = jpegData
} }
return standaloneUploadedFile(account: account, peerId: peerId, text: "", source: .data(data), thumbnailData: thumbnailData, mimeType: mimeType, attributes: [.FileName(fileName: fileName ?? "file")], hintFileIsLarge: data.count > 5 * 1024 * 1024) return standaloneUploadedFile(account: account, peerId: peerId, text: "", source: .data(data), thumbnailData: thumbnailData, mimeType: mimeType, attributes: [.FileName(fileName: fileName ?? "file")], hintFileIsLarge: data.count > 10 * 1024 * 1024)
|> mapError { _ -> Void in return Void() } |> mapError { _ -> Void in return Void() }
|> mapToSignal { event -> Signal<PreparedShareItem, Void> in |> mapToSignal { event -> Signal<PreparedShareItem, Void> in
switch event { switch event {
@ -247,7 +247,7 @@ private func preparedShareItem(account: Account, to peerId: PeerId, value: [Stri
waveform = MemoryBuffer(data: waveformData) waveform = MemoryBuffer(data: waveformData)
} }
return standaloneUploadedFile(account: account, peerId: peerId, text: "", source: .data(audioData), mimeType: "audio/ogg", attributes: [.Audio(isVoice: isVoice, duration: Int(duration), title: title, performer: artist, waveform: waveform), .FileName(fileName: fileName)], hintFileIsLarge: audioData.count > 5 * 1024 * 1024) return standaloneUploadedFile(account: account, peerId: peerId, text: "", source: .data(audioData), mimeType: "audio/ogg", attributes: [.Audio(isVoice: isVoice, duration: Int(duration), title: title, performer: artist, waveform: waveform), .FileName(fileName: fileName)], hintFileIsLarge: audioData.count > 10 * 1024 * 1024)
|> mapError { _ -> Void in return Void() } |> mapError { _ -> Void in return Void() }
|> mapToSignal { event -> Signal<PreparedShareItem, Void> in |> mapToSignal { event -> Signal<PreparedShareItem, Void> in
switch event { switch event {

View File

@ -140,7 +140,6 @@ final class StickerPackPreviewGridItemNode: GridItemNode {
if self.currentState == nil || self.currentState!.0 !== account || self.currentState!.1 != stickerItem || self.isEmpty != isEmpty { if self.currentState == nil || self.currentState!.0 !== account || self.currentState!.1 != stickerItem || self.isEmpty != isEmpty {
if let stickerItem = stickerItem { if let stickerItem = stickerItem {
if let _ = stickerItem.file.dimensions {
if stickerItem.file.isAnimatedSticker { if stickerItem.file.isAnimatedSticker {
let dimensions = stickerItem.file.dimensions ?? PixelDimensions(width: 512, height: 512) let dimensions = stickerItem.file.dimensions ?? PixelDimensions(width: 512, height: 512)
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: account.postbox, file: stickerItem.file, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0)))) self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: account.postbox, file: stickerItem.file, small: false, size: dimensions.cgSize.aspectFitted(CGSize(width: 160.0, height: 160.0))))
@ -167,7 +166,6 @@ final class StickerPackPreviewGridItemNode: GridItemNode {
self.imageNode.setSignal(chatMessageSticker(account: account, file: stickerItem.file, small: true)) self.imageNode.setSignal(chatMessageSticker(account: account, file: stickerItem.file, small: true))
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, fileReference: stickerPackFileReference(stickerItem.file), resource: chatMessageStickerResource(file: stickerItem.file, small: true)).start()) self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, fileReference: stickerPackFileReference(stickerItem.file), resource: chatMessageStickerResource(file: stickerItem.file, small: true)).start())
} }
}
} else { } else {
if let placeholderNode = self.placeholderNode { if let placeholderNode = self.placeholderNode {
if isEmpty { if isEmpty {

View File

@ -887,7 +887,11 @@ public final class VoiceChatController: ViewController {
case .restricted: case .restricted:
text = presentationData.strings.Channel_ErrorAddBlocked text = presentationData.strings.Channel_ErrorAddBlocked
case .notMutualContact: case .notMutualContact:
if case .broadcast = groupPeer.info {
text = presentationData.strings.Channel_AddUserLeftError
} else {
text = presentationData.strings.GroupInfo_AddUserLeftError text = presentationData.strings.GroupInfo_AddUserLeftError
}
case .botDoesntSupportGroups: case .botDoesntSupportGroups:
text = presentationData.strings.Channel_BotDoesntSupportGroups text = presentationData.strings.Channel_BotDoesntSupportGroups
case .tooMuchBots: case .tooMuchBots:
@ -952,15 +956,9 @@ public final class VoiceChatController: ViewController {
self?.controller?.present(textAlertController(context: context, title: nil, text: presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(peer.compactDisplayTitle, peer.compactDisplayTitle).0, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) self?.controller?.present(textAlertController(context: context, title: nil, text: presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(peer.compactDisplayTitle, peer.compactDisplayTitle).0, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
}) })
case .notMutualContact: case .notMutualContact:
let _ = (strongSelf.context.account.postbox.loadedPeerWithId(peer.id) strongSelf.controller?.present(textAlertController(context: context, title: nil, text: presentationData.strings.GroupInfo_AddUserLeftError, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|> deliverOnMainQueue).start(next: { peer in
self?.controller?.present(textAlertController(context: context, title: nil, text: presentationData.strings.GroupInfo_AddUserLeftError, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
})
case .tooManyChannels: case .tooManyChannels:
let _ = (strongSelf.context.account.postbox.loadedPeerWithId(peer.id) strongSelf.controller?.present(textAlertController(context: context, title: nil, text: presentationData.strings.Invite_ChannelsTooMuch, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|> deliverOnMainQueue).start(next: { peer in
self?.controller?.present(textAlertController(context: context, title: nil, text: presentationData.strings.Invite_ChannelsTooMuch, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
})
case .groupFull, .generic: case .groupFull, .generic:
strongSelf.controller?.present(textAlertController(context: strongSelf.context, forceTheme: strongSelf.darkTheme, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) strongSelf.controller?.present(textAlertController(context: strongSelf.context, forceTheme: strongSelf.darkTheme, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
} }

View File

@ -192,7 +192,7 @@ public enum ChatHistoryImport {
case invalidChatType case invalidChatType
case userBlocked case userBlocked
case limitExceeded case limitExceeded
case userIsNotMutualContact case notMutualContact
} }
public static func checkPeerImport(account: Account, peerId: PeerId) -> Signal<CheckPeerImportResult, CheckPeerImportError> { public static func checkPeerImport(account: Account, peerId: PeerId) -> Signal<CheckPeerImportResult, CheckPeerImportError> {
@ -217,7 +217,7 @@ public enum ChatHistoryImport {
} else if error.errorDescription == "USER_IS_BLOCKED" { } else if error.errorDescription == "USER_IS_BLOCKED" {
return .userBlocked return .userBlocked
} else if error.errorDescription == "USER_NOT_MUTUAL_CONTACT" { } else if error.errorDescription == "USER_NOT_MUTUAL_CONTACT" {
return .userBlocked return .notMutualContact
} else if error.errorDescription == "FLOOD_WAIT" { } else if error.errorDescription == "FLOOD_WAIT" {
return .limitExceeded return .limitExceeded
} else { } else {

View File

@ -529,7 +529,7 @@ private final class PeerExportedInvitationsContextImpl {
} }
private func updateCache() { private func updateCache() {
guard self.hasLoadedOnce && !self.isLoadingMore else { guard self.isMainList && self.hasLoadedOnce && !self.isLoadingMore else {
return return
} }

View File

@ -202,6 +202,8 @@ public func updateChannelAdminRights(account: Account, peerId: PeerId, adminId:
} }
|> map { [$0] } |> map { [$0] }
) )
} else if error.errorDescription == "USER_NOT_MUTUAL_CONTACT" {
return .fail(.addMemberError(.notMutualContact))
} else if error.errorDescription == "USER_PRIVACY_RESTRICTED" { } else if error.errorDescription == "USER_PRIVACY_RESTRICTED" {
return .fail(.addMemberError(.restricted)) return .fail(.addMemberError(.restricted))
} else if error.errorDescription == "USER_CHANNELS_TOO_MUCH" { } else if error.errorDescription == "USER_CHANNELS_TOO_MUCH" {

View File

@ -623,7 +623,7 @@ private func uploadedMediaFileContent(network: Network, postbox: Postbox, auxili
hintFileIsLarge = true hintFileIsLarge = true
break loop break loop
default: default:
break loop break
} }
} }

View File

@ -984,7 +984,7 @@ func peerInfoHeaderButtons(peer: Peer?, cachedData: CachedPeerData?, isOpenedFro
if isOpenedFromChat { if isOpenedFromChat {
result.append(.search) result.append(.search)
} }
if isSecretChat && !isContact { if (isSecretChat && !isContact) || user.flags.contains(.isSupport) {
} else { } else {
result.append(.more) result.append(.more)
} }
@ -1043,7 +1043,7 @@ func peerInfoHeaderButtons(peer: Peer?, cachedData: CachedPeerData?, isOpenedFro
if channel.isVerified || channel.adminRights != nil || channel.flags.contains(.isCreator) { if channel.isVerified || channel.adminRights != nil || channel.flags.contains(.isCreator) {
canReport = false canReport = false
} }
if !canReport && !canViewStats && displayLeave { if !canReport && !canViewStats {
displayMore = false displayMore = false
} }
if displayMore { if displayMore {

View File

@ -1147,33 +1147,6 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
items[section] = [] items[section] = []
} }
// if let data = data, let notificationSettings = data.notificationSettings {
// let notificationsLabel: String
// let soundLabel: String
// if case let .muted(until) = notificationSettings.muteState, until >= Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970) {
// if until < Int32.max - 1 {
// notificationsLabel = stringForRemainingMuteInterval(strings: presentationData.strings, muteInterval: until)
// } else {
// notificationsLabel = presentationData.strings.UserInfo_NotificationsDisabled
// }
// } else {
// notificationsLabel = presentationData.strings.UserInfo_NotificationsEnabled
// }
//
// let globalNotificationSettings: GlobalNotificationSettings = data.globalNotificationSettings ?? GlobalNotificationSettings.defaultSettings
// soundLabel = localizedPeerNotificationSoundString(strings: presentationData.strings, sound: notificationSettings.messageSound, default: globalNotificationSettings.effective.privateChats.sound)
//
// items[.notifications]!.append(PeerInfoScreenDisclosureItem(id: 0, label: .text(notificationsLabel), text: presentationData.strings.GroupInfo_Notifications, action: {
// interaction.editingOpenNotificationSettings()
// }))
// items[.notifications]!.append(PeerInfoScreenDisclosureItem(id: 1, label: .text(soundLabel), text: presentationData.strings.GroupInfo_Sound, action: {
// interaction.editingOpenSoundSettings()
// }))
// items[.notifications]!.append(PeerInfoScreenSwitchItem(id: 2, text: presentationData.strings.Notification_Exceptions_PreviewAlwaysOn, value: notificationSettings.displayPreviews != .hide, toggled: { value in
// interaction.editingToggleShowMessageText(value)
// }))
// }
if let data = data { if let data = data {
if let _ = data.peer as? TelegramUser { if let _ = data.peer as? TelegramUser {
let ItemDelete = 0 let ItemDelete = 0
@ -1194,8 +1167,8 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
if channel.flags.contains(.isCreator) { if channel.flags.contains(.isCreator) {
let linkText: String let linkText: String
if let username = channel.username { if let _ = channel.username {
linkText = "@\(username)" linkText = presentationData.strings.Channel_Setup_TypePublic
} else { } else {
linkText = presentationData.strings.Channel_Setup_TypePrivate linkText = presentationData.strings.Channel_Setup_TypePrivate
} }
@ -6589,7 +6562,13 @@ func presentAddMembers(context: AccountContext, parentController: ViewController
case .notMutualContact: case .notMutualContact:
let _ = (context.account.postbox.loadedPeerWithId(memberId) let _ = (context.account.postbox.loadedPeerWithId(memberId)
|> deliverOnMainQueue).start(next: { peer in |> deliverOnMainQueue).start(next: { peer in
parentController?.present(textAlertController(context: context, title: nil, text: presentationData.strings.GroupInfo_AddUserLeftError, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) let text: String
if let peer = peer as? TelegramChannel, case .broadcast = peer.info {
text = presentationData.strings.Channel_AddUserLeftError
} else {
text = presentationData.strings.GroupInfo_AddUserLeftError
}
parentController?.present(textAlertController(context: context, title: nil, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
}) })
return .complete() return .complete()
case .tooManyChannels: case .tooManyChannels:
@ -6708,7 +6687,14 @@ func presentAddMembers(context: AccountContext, parentController: ViewController
break break
} }
} else if peers.count == 1, case .notMutualContact = error { } else if peers.count == 1, case .notMutualContact = error {
parentController?.present(textAlertController(context: context, title: nil, text: presentationData.strings.GroupInfo_AddUserLeftError, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) let text: String
if let peer = groupPeer as? TelegramChannel, case .broadcast = peer.info {
text = presentationData.strings.Channel_AddUserLeftError
} else {
text = presentationData.strings.GroupInfo_AddUserLeftError
}
parentController?.present(textAlertController(context: context, title: nil, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
} else if case .tooMuchJoined = error { } else if case .tooMuchJoined = error {
parentController?.present(textAlertController(context: context, title: nil, text: presentationData.strings.Invite_ChannelsTooMuch, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) parentController?.present(textAlertController(context: context, title: nil, text: presentationData.strings.Invite_ChannelsTooMuch, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
} }

View File

@ -744,7 +744,7 @@ public class ShareRootControllerImpl {
errorText = presentationData.strings.ChatImportActivity_ErrorUserBlocked errorText = presentationData.strings.ChatImportActivity_ErrorUserBlocked
case .limitExceeded: case .limitExceeded:
errorText = presentationData.strings.ChatImportActivity_ErrorLimitExceeded errorText = presentationData.strings.ChatImportActivity_ErrorLimitExceeded
case .userIsNotMutualContact: case .notMutualContact:
errorText = presentationData.strings.ChatImport_UserErrorNotMutual errorText = presentationData.strings.ChatImport_UserErrorNotMutual
} }
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: { let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
@ -868,7 +868,7 @@ public class ShareRootControllerImpl {
errorText = presentationData.strings.ChatImportActivity_ErrorUserBlocked errorText = presentationData.strings.ChatImportActivity_ErrorUserBlocked
case .limitExceeded: case .limitExceeded:
errorText = presentationData.strings.ChatImportActivity_ErrorLimitExceeded errorText = presentationData.strings.ChatImportActivity_ErrorLimitExceeded
case .userIsNotMutualContact: case .notMutualContact:
errorText = presentationData.strings.ChatImport_UserErrorNotMutual errorText = presentationData.strings.ChatImport_UserErrorNotMutual
} }
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: { let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
@ -989,7 +989,7 @@ public class ShareRootControllerImpl {
errorText = presentationData.strings.ChatImportActivity_ErrorUserBlocked errorText = presentationData.strings.ChatImportActivity_ErrorUserBlocked
case .limitExceeded: case .limitExceeded:
errorText = presentationData.strings.ChatImportActivity_ErrorLimitExceeded errorText = presentationData.strings.ChatImportActivity_ErrorLimitExceeded
case .userIsNotMutualContact: case .notMutualContact:
errorText = presentationData.strings.ChatImport_UserErrorNotMutual errorText = presentationData.strings.ChatImport_UserErrorNotMutual
} }
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: { let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {

View File

@ -508,7 +508,6 @@ private struct UrlHandlingConfiguration {
} }
static func with(appConfiguration: AppConfiguration) -> UrlHandlingConfiguration { static func with(appConfiguration: AppConfiguration) -> UrlHandlingConfiguration {
//let urlAuthDomains = data["url_auth_domains"] as? [String]
if let data = appConfiguration.data, let token = data["autologin_token"] as? String, let domains = data["autologin_domains"] as? [String] { if let data = appConfiguration.data, let token = data["autologin_token"] as? String, let domains = data["autologin_domains"] as? [String] {
return UrlHandlingConfiguration(token: token, domains: domains, urlAuthDomains: []) return UrlHandlingConfiguration(token: token, domains: domains, urlAuthDomains: [])
} else { } else {
@ -525,9 +524,11 @@ public func resolveUrlImpl(account: Account, url: String) -> Signal<ResolvedUrl,
let urlHandlingConfiguration = UrlHandlingConfiguration.with(appConfiguration: appConfiguration) let urlHandlingConfiguration = UrlHandlingConfiguration.with(appConfiguration: appConfiguration)
var url = url var url = url
if !url.contains("://") && !url.hasPrefix("tel:") && !url.hasPrefix("mailto:") && !url.hasPrefix("calshow:") {
if !(url.hasPrefix("http") || url.hasPrefix("https")) { if !(url.hasPrefix("http") || url.hasPrefix("https")) {
url = "http://\(url)" url = "http://\(url)"
} }
}
if let urlValue = URL(string: url), let host = urlValue.host?.lowercased() { if let urlValue = URL(string: url), let host = urlValue.host?.lowercased() {
if urlHandlingConfiguration.domains.contains(host), var components = URLComponents(string: url) { if urlHandlingConfiguration.domains.contains(host), var components = URLComponents(string: url) {
components.scheme = "https" components.scheme = "https"