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
97ec1faf13
commit
97303351ed
@ -37,6 +37,7 @@ typedef enum
|
||||
@property (nonatomic, readonly) bool representsBurst;
|
||||
@property (nonatomic, readonly) NSString *uniformTypeIdentifier;
|
||||
@property (nonatomic, readonly) NSString *fileName;
|
||||
@property (nonatomic, readonly) NSInteger fileSize;
|
||||
|
||||
@property (nonatomic, readonly) TGMediaAssetType type;
|
||||
@property (nonatomic, readonly) TGMediaAssetSubtype subtypes;
|
||||
|
@ -64,6 +64,16 @@
|
||||
return self.backingAsset.representsBurst;
|
||||
}
|
||||
|
||||
- (NSInteger)fileSize {
|
||||
if (self.backingAsset != nil) {
|
||||
PHAssetResource *resource = [PHAssetResource assetResourcesForAsset:self.backingAsset].firstObject;
|
||||
if (resource != nil) {
|
||||
return [[resource valueForKey:@"fileSize"] integerValue];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (NSString *)uniformTypeIdentifier
|
||||
{
|
||||
if (self.backingAsset != nil)
|
||||
|
@ -409,23 +409,17 @@
|
||||
{
|
||||
SSignal *attributesSignal = [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
|
||||
{
|
||||
PHImageRequestID token = [[PHImageManager defaultManager] requestImageDataForAsset:asset.backingAsset options:nil resultHandler:^(NSData *data, NSString *dataUTI, __unused UIImageOrientation orientation, NSDictionary *info)
|
||||
{
|
||||
NSURL *fileUrl = info[@"PHImageFileURLKey"];
|
||||
|
||||
TGMediaAssetImageFileAttributes *attributes = [[TGMediaAssetImageFileAttributes alloc] init];
|
||||
attributes.fileName = fileUrl.absoluteString.lastPathComponent;
|
||||
attributes.fileUTI = dataUTI;
|
||||
attributes.dimensions = asset.dimensions;
|
||||
attributes.fileSize = data.length;
|
||||
|
||||
[subscriber putNext:attributes];
|
||||
[subscriber putCompletion];
|
||||
}];
|
||||
TGMediaAssetImageFileAttributes *attributes = [[TGMediaAssetImageFileAttributes alloc] init];
|
||||
attributes.fileName = asset.fileName;
|
||||
attributes.fileUTI = asset.uniformTypeIdentifier;
|
||||
attributes.dimensions = asset.dimensions;
|
||||
attributes.fileSize = asset.fileSize;
|
||||
|
||||
[subscriber putNext:attributes];
|
||||
[subscriber putCompletion];
|
||||
|
||||
return [[SBlockDisposable alloc] initWithBlock:^
|
||||
{
|
||||
[[PHImageManager defaultManager] cancelImageRequest:token];
|
||||
}];
|
||||
}];
|
||||
|
||||
|
@ -256,7 +256,11 @@
|
||||
NSString *fileSize = [TGStringUtils stringForFileSize:next.fileSize precision:2];
|
||||
NSString *dimensions = [NSString stringWithFormat:@"%dx%d", (int)next.dimensions.width, (int)next.dimensions.height];
|
||||
|
||||
strongSelf->_fileInfoLabel.text = [NSString stringWithFormat:@"%@ • %@ • %@", extension, fileSize, dimensions];
|
||||
if (next.fileSize > 0) {
|
||||
strongSelf->_fileInfoLabel.text = [NSString stringWithFormat:@"%@ • %@ • %@", extension, fileSize, dimensions];
|
||||
} else {
|
||||
strongSelf->_fileInfoLabel.text = dimensions;
|
||||
}
|
||||
}]];
|
||||
}
|
||||
}
|
||||
|
@ -122,8 +122,33 @@ class LocationPinAnnotationLayer: CALayer {
|
||||
}
|
||||
}
|
||||
|
||||
private func addPulseAnimations(layer: CALayer) {
|
||||
let scaleAnimation = CAKeyframeAnimation(keyPath: "transform.scale")
|
||||
scaleAnimation.values = [0.0 as NSNumber, 0.72 as NSNumber, 1.0 as NSNumber, 1.0 as NSNumber]
|
||||
scaleAnimation.keyTimes = [0.0 as NSNumber, 0.49 as NSNumber, 0.88 as NSNumber, 1.0 as NSNumber]
|
||||
scaleAnimation.duration = 3.0
|
||||
scaleAnimation.repeatCount = Float.infinity
|
||||
scaleAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)
|
||||
scaleAnimation.beginTime = 1.0
|
||||
layer.add(scaleAnimation, forKey: "pulse-scale")
|
||||
|
||||
let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
|
||||
opacityAnimation.values = [1.0 as NSNumber, 0.2 as NSNumber, 0.0 as NSNumber, 0.0 as NSNumber]
|
||||
opacityAnimation.keyTimes = [0.0 as NSNumber, 0.4 as NSNumber, 0.62 as NSNumber, 1.0 as NSNumber]
|
||||
opacityAnimation.duration = 3.0
|
||||
opacityAnimation.repeatCount = Float.infinity
|
||||
opacityAnimation.beginTime = 1.0
|
||||
layer.add(opacityAnimation, forKey: "pulse-opacity")
|
||||
}
|
||||
|
||||
private func removePulseAnimations(layer: CALayer) {
|
||||
layer.removeAnimation(forKey: "pulse-scale")
|
||||
layer.removeAnimation(forKey: "pulse-opacity")
|
||||
}
|
||||
|
||||
class LocationPinAnnotationView: MKAnnotationView {
|
||||
let shadowNode: ASImageNode
|
||||
let pulseNode: ASImageNode
|
||||
let backgroundNode: ASImageNode
|
||||
let arrowNode: ASImageNode
|
||||
let smallNode: ASImageNode
|
||||
@ -138,6 +163,8 @@ class LocationPinAnnotationView: MKAnnotationView {
|
||||
var appeared = false
|
||||
var animating = false
|
||||
|
||||
var hasPulse = false
|
||||
|
||||
override class var layerClass: AnyClass {
|
||||
return LocationPinAnnotationLayer.self
|
||||
}
|
||||
@ -155,6 +182,11 @@ class LocationPinAnnotationView: MKAnnotationView {
|
||||
self.shadowNode.bounds = CGRect(origin: CGPoint(), size: image.size)
|
||||
}
|
||||
|
||||
self.pulseNode = ASImageNode()
|
||||
self.pulseNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: 120.0, height: 120.0))
|
||||
self.pulseNode.image = generateFilledCircleImage(diameter: 120.0, color: UIColor(rgb: 0x007aff, alpha: 0.27))
|
||||
self.pulseNode.isHidden = true
|
||||
|
||||
self.arrowNode = ASImageNode()
|
||||
self.arrowNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: 88.0, height: 88.0))
|
||||
self.arrowNode.image = generateHeadingArrowImage()
|
||||
@ -612,6 +644,8 @@ class LocationPinAnnotationView: MKAnnotationView {
|
||||
}
|
||||
|
||||
self.dotNode.position = CGPoint()
|
||||
self.pulseNode.position = CGPoint()
|
||||
self.arrowNode.position = CGPoint()
|
||||
self.smallNode.position = CGPoint()
|
||||
self.shadowNode.position = CGPoint(x: UIScreenPixel, y: self.isRaised ? -66.0 : -36.0)
|
||||
self.backgroundNode.position = CGPoint(x: self.shadowNode.frame.width / 2.0, y: self.shadowNode.frame.height / 2.0)
|
||||
|
@ -411,6 +411,10 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan
|
||||
index += 1
|
||||
}
|
||||
|
||||
if subject.id.peerId.namespace != Namespaces.Peer.CloudUser {
|
||||
proximityNotification = state.proximityRadius != nil
|
||||
}
|
||||
|
||||
let previousEntries = previousEntries.swap(entries)
|
||||
let previousState = previousState.swap(state)
|
||||
|
||||
|
@ -7170,7 +7170,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
let fileId = arc4random64()
|
||||
let mimeType = guessMimeTypeByFileExtension((item.fileName as NSString).pathExtension)
|
||||
var previewRepresentations: [TelegramMediaImageRepresentation] = []
|
||||
if mimeType == "application/pdf" {
|
||||
if mimeType.hasPrefix("image/") || mimeType == "application/pdf" {
|
||||
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 320, height: 320), resource: ICloudFileResource(urlData: item.urlData, thumbnail: true), progressiveSizes: []))
|
||||
}
|
||||
var attributes: [TelegramMediaFileAttribute] = []
|
||||
@ -7183,7 +7183,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
let message: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: file), replyToMessageId: replyMessageId, localGroupingKey: groupingKey)
|
||||
messages.append(message)
|
||||
}
|
||||
if let _ = groupingKey, results.count % 10 == 0 {
|
||||
if let _ = groupingKey, messages.count % 10 == 0 {
|
||||
groupingKey = arc4random64()
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ enum ChatMessageBubbleRelativePosition {
|
||||
enum NeighbourSpacing {
|
||||
case `default`
|
||||
case condensed
|
||||
case overlap
|
||||
case overlap(CGFloat)
|
||||
}
|
||||
|
||||
case None(ChatMessageBubbleMergeStatus)
|
||||
|
@ -64,7 +64,7 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([
|
||||
} else {
|
||||
var neighborSpacing: ChatMessageBubbleRelativePosition.NeighbourSpacing = .default
|
||||
if previousItemIsFile {
|
||||
neighborSpacing = .overlap
|
||||
neighborSpacing = .overlap(file.isMusic ? 14.0 : 5.0)
|
||||
}
|
||||
isFile = true
|
||||
hasFiles = true
|
||||
@ -229,12 +229,15 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
func willUpdateIsExtractedToContextPreview(isExtractedToContextPreview: Bool, transition: ContainedViewLayoutTransition) {
|
||||
if isExtractedToContextPreview {
|
||||
var offset: CGFloat = 0.0
|
||||
var inset: CGFloat = 0.0
|
||||
var type: ChatMessageBackgroundType
|
||||
if let currentParams = self.currentParams, case .incoming = currentParams.backgroundType {
|
||||
type = .incoming(.Extracted)
|
||||
offset += 5.0
|
||||
offset = -5.0
|
||||
inset = 5.0
|
||||
} else {
|
||||
type = .outgoing(.Extracted)
|
||||
inset = 5.0
|
||||
}
|
||||
|
||||
if let _ = self.backgroundNode {
|
||||
@ -250,7 +253,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
}
|
||||
|
||||
if let currentParams = self.currentParams {
|
||||
let backgroundFrame = CGRect(x: currentParams.contentOrigin.x - offset, y: 0.0, width: currentParams.size.width + offset, height: currentParams.size.height)
|
||||
let backgroundFrame = CGRect(x: currentParams.contentOrigin.x + offset, y: 0.0, width: currentParams.size.width + inset, height: currentParams.size.height)
|
||||
self.backgroundNode?.updateLayout(size: backgroundFrame.size, transition: .immediate)
|
||||
self.backgroundNode?.frame = backgroundFrame
|
||||
}
|
||||
@ -1783,13 +1786,20 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
var contentNodesHeight: CGFloat = 0.0
|
||||
var totalContentNodesHeight: CGFloat = 0.0
|
||||
|
||||
let smallContainerGroupOverlap: CGFloat = 5.0
|
||||
let largeContainerGroupOverlap: CGFloat = 14.0
|
||||
var nextContainerGroupOverlap = smallContainerGroupOverlap
|
||||
var currentContainerGroupOverlap: CGFloat = 0.0
|
||||
|
||||
var mosaicStatusOrigin: CGPoint?
|
||||
for i in 0 ..< contentNodePropertiesAndFinalize.count {
|
||||
let (properties, _, finalize, contentGroupId, itemSelection) = contentNodePropertiesAndFinalize[i]
|
||||
let (properties, position, finalize, contentGroupId, itemSelection) = contentNodePropertiesAndFinalize[i]
|
||||
|
||||
if let position = position, case let .linear(top, bottom) = position {
|
||||
if case let .Neighbour(_, _, spacing) = top, case let .overlap(overlap) = spacing {
|
||||
currentContainerGroupOverlap = overlap
|
||||
}
|
||||
if case let .Neighbour(_, _, spacing) = bottom, case let .overlap(overlap) = spacing {
|
||||
currentContainerGroupOverlap = overlap
|
||||
}
|
||||
}
|
||||
|
||||
if let mosaicRange = mosaicRange, mosaicRange.contains(i), let (framesAndPositions, size) = calculatedGroupFramesAndSize {
|
||||
let mosaicIndex = i - mosaicRange.lowerBound
|
||||
@ -1823,11 +1833,11 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
if let containerGroupId = currentContainerGroupId {
|
||||
var overlapOffset: CGFloat = 0.0
|
||||
if !contentContainerNodeFrames.isEmpty {
|
||||
overlapOffset = smallContainerGroupOverlap
|
||||
overlapOffset = currentContainerGroupOverlap
|
||||
}
|
||||
contentContainerNodeFrames.append((containerGroupId, CGRect(x: 0.0, y: headerSize.height + totalContentNodesHeight - contentNodesHeight - overlapOffset, width: maxContentWidth, height: contentNodesHeight), currentItemSelection))
|
||||
if !overlapOffset.isZero {
|
||||
totalContentNodesHeight -= smallContainerGroupOverlap
|
||||
totalContentNodesHeight -= currentContainerGroupOverlap
|
||||
}
|
||||
if contentGroupId == nil {
|
||||
totalContentNodesHeight += 3.0
|
||||
@ -1849,11 +1859,11 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
if let containerGroupId = currentContainerGroupId {
|
||||
var overlapOffset: CGFloat = 0.0
|
||||
if !contentContainerNodeFrames.isEmpty {
|
||||
overlapOffset = smallContainerGroupOverlap
|
||||
overlapOffset = currentContainerGroupOverlap
|
||||
}
|
||||
contentContainerNodeFrames.append((containerGroupId, CGRect(x: 0.0, y: headerSize.height + totalContentNodesHeight - contentNodesHeight - overlapOffset, width: maxContentWidth, height: contentNodesHeight), currentItemSelection))
|
||||
if !overlapOffset.isZero {
|
||||
totalContentNodesHeight -= smallContainerGroupOverlap
|
||||
totalContentNodesHeight -= currentContainerGroupOverlap
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -993,7 +993,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
||||
self.cutoutNode = cutoutNode
|
||||
self.insertSubnode(cutoutNode, aboveSubnode: statusNode)
|
||||
|
||||
cutoutNode.frame = streamingCacheStatusFrame.insetBy(dx: -1.5, dy: -1.5)
|
||||
cutoutNode.frame = streamingCacheStatusFrame.insetBy(dx: -(1.0 + UIScreenPixel), dy: -(1.0 + UIScreenPixel))
|
||||
|
||||
if animated {
|
||||
cutoutNode.layer.animateScale(from: 0.001, to: 1.0, duration: 0.2)
|
||||
|
@ -230,7 +230,10 @@ func fetchICloudFileResource(resource: ICloudFileResource) -> Signal<MediaResour
|
||||
if resource.thumbnail {
|
||||
let tempFile = TempBox.shared.tempFile(fileName: "thumb.jpg")
|
||||
var data = Data()
|
||||
if let image = generatePdfPreviewImage(url: url, size: CGSize(width: 256, height: 256.0)), let jpegData = image.jpegData(compressionQuality: 0.5) {
|
||||
|
||||
if let imageData = try? Data(contentsOf: url, options: .mappedIfSafe), let originalImage = UIImage(data: imageData), let image = generateScaledImage(image: originalImage, size: originalImage.size.fitted(CGSize(width: 256, height: 256.0))), let jpegData = image.jpegData(compressionQuality: 0.5) {
|
||||
data = jpegData
|
||||
} else if let image = generatePdfPreviewImage(url: url, size: CGSize(width: 256, height: 256.0)), let jpegData = image.jpegData(compressionQuality: 0.5) {
|
||||
data = jpegData
|
||||
}
|
||||
if let _ = try? data.write(to: URL(fileURLWithPath: tempFile.path)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user