Attachment menu improvements

This commit is contained in:
Ilya Laktyushin
2022-02-15 16:01:20 +03:00
parent 2933b08433
commit 95b6b44d0a
74 changed files with 215 additions and 3829 deletions

View File

@@ -7266,3 +7266,10 @@ Sorry for the inconvenience.";
"Attachment.SelectFromGallery" = "Select from Gallery";
"Attachment.SelectFromFiles" = "Select from Files";
"Attachment.SelectedMedia_1" = "%@ Selected";
"Attachment.SelectedMedia_2" = "%@ Selected";
"Attachment.SelectedMedia_3_10" = "%@ Selected";
"Attachment.SelectedMedia_any" = "%@ Selected";
"Attachment.SelectedMedia_many" = "%@ Selected";
"Attachment.SelectedMedia_0" = "%@ Selected";

View File

@@ -245,9 +245,9 @@ public class AttachmentController: ViewController {
}
if ascending {
strongSelf.container.container.view.layer.animatePosition(from: CGPoint(x: 70.0, y: 0.0), to: CGPoint(), duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
strongSelf.container.container.view.layer.animatePosition(from: CGPoint(x: 70.0, y: 0.0), to: CGPoint(), duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
} else {
strongSelf.container.container.view.layer.animatePosition(from: CGPoint(x: -70.0, y: 0.0), to: CGPoint(), duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
strongSelf.container.container.view.layer.animatePosition(from: CGPoint(x: -70.0, y: 0.0), to: CGPoint(), duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
}
snapshotView?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { [weak snapshotView] _ in
@@ -258,7 +258,7 @@ public class AttachmentController: ViewController {
if let layout = strongSelf.validLayout {
strongSelf.switchingController = true
strongSelf.containerLayoutUpdated(layout, transition: .animated(duration: 0.4, curve: .spring))
strongSelf.containerLayoutUpdated(layout, transition: .animated(duration: 0.3, curve: .spring))
strongSelf.switchingController = false
}
}

View File

@@ -51,7 +51,6 @@
#import <LegacyComponents/SGraphNode.h>
#import <LegacyComponents/SGraphObjectNode.h>
#import <LegacyComponents/TGActionMediaAttachment.h>
#import <LegacyComponents/TGAlphacode.h>
#import <LegacyComponents/TGAnimationBlockDelegate.h>
#import <LegacyComponents/TGAttachmentCameraView.h>
#import <LegacyComponents/TGAttachmentCarouselItemView.h>
@@ -107,7 +106,6 @@
#import <LegacyComponents/TGFullscreenContainerView.h>
#import <LegacyComponents/TGGameMediaAttachment.h>
#import <LegacyComponents/TGGifConverter.h>
#import <LegacyComponents/TGGradientLabel.h>
#import <LegacyComponents/TGHacks.h>
#import <LegacyComponents/TGIconSwitchView.h>
#import <LegacyComponents/TGImageBlur.h>
@@ -119,16 +117,11 @@
#import <LegacyComponents/TGImageMediaAttachment.h>
#import <LegacyComponents/TGImageUtils.h>
#import <LegacyComponents/TGImageView.h>
#import <LegacyComponents/TGInputTextTag.h>
#import <LegacyComponents/TGInstantPage.h>
#import <LegacyComponents/TGInvoiceMediaAttachment.h>
#import <LegacyComponents/TGItemMenuSheetPreviewView.h>
#import <LegacyComponents/TGItemPreviewController.h>
#import <LegacyComponents/TGItemPreviewView.h>
#import <LegacyComponents/TGKeyCommand.h>
#import <LegacyComponents/TGKeyCommandController.h>
#import <LegacyComponents/TGLabel.h>
#import <LegacyComponents/TGLetteredAvatarView.h>
#import <LegacyComponents/TGListsTableView.h>
#import <LegacyComponents/TGLiveUploadInterface.h>
#import <LegacyComponents/TGLocalMessageMetaMediaAttachment.h>
@@ -249,7 +242,6 @@
#import <LegacyComponents/TGProgressWindow.h>
#import <LegacyComponents/TGProxyWindow.h>
#import <LegacyComponents/TGRTLScreenEdgePanGestureRecognizer.h>
#import <LegacyComponents/TGRemoteImageView.h>
#import <LegacyComponents/TGReplyMarkupAttachment.h>
#import <LegacyComponents/TGReplyMessageMediaAttachment.h>
#import <LegacyComponents/TGStaticBackdropAreaData.h>
@@ -258,13 +250,11 @@
#import <LegacyComponents/TGStickerPack.h>
#import <LegacyComponents/TGStickerPackReference.h>
#import <LegacyComponents/TGStringUtils.h>
#import <LegacyComponents/TGSuggestionContext.h>
#import <LegacyComponents/TGTextCheckingResult.h>
#import <LegacyComponents/TGTimerTarget.h>
#import <LegacyComponents/TGToolbarButton.h>
#import <LegacyComponents/TGTooltipView.h>
#import <LegacyComponents/TGUnsupportedMediaAttachment.h>
#import <LegacyComponents/TGUser.h>
#import <LegacyComponents/TGViaUserAttachment.h>
#import <LegacyComponents/TGVideoEditAdjustments.h>
#import <LegacyComponents/TGVideoInfo.h>

View File

@@ -1,12 +0,0 @@
#import <Foundation/Foundation.h>
@class SSignal;
@interface TGAlphacodeEntry : NSObject
@property (nonatomic, strong, readonly) NSString *emoji;
@property (nonatomic, strong, readonly) NSString *code;
- (instancetype)initWithEmoji:(NSString *)emoji code:(NSString *)code;
@end

View File

@@ -6,7 +6,6 @@
@class TGMediaSelectionContext;
@class TGMediaEditingContext;
@class TGSuggestionContext;
@class TGViewController;
@class TGAttachmentCameraView;
@class TGVideoEditAdjustments;
@@ -22,7 +21,6 @@
@property (nonatomic, readonly) TGMediaSelectionContext *selectionContext;
@property (nonatomic, readonly) TGMediaEditingContext *editingContext;
@property (nonatomic, strong) TGSuggestionContext *suggestionContext;
@property (nonatomic, strong) id<TGPhotoPaintStickersContext> stickersContext;
@property (nonatomic) bool allowCaptions;
@property (nonatomic) bool allowCaptionEntities;

View File

@@ -8,7 +8,6 @@
@class TGCameraPreviewView;
@class TGMediaSelectionContext;
@class TGMediaEditingContext;
@class TGSuggestionContext;
@class TGVideoEditAdjustments;
@protocol TGPhotoPaintStickersContext;
@@ -42,7 +41,6 @@ typedef enum {
@property (nonatomic, assign) bool hasSilentPosting;
@property (nonatomic, assign) bool hasSchedule;
@property (nonatomic, assign) bool reminder;
@property (nonatomic, strong) TGSuggestionContext *suggestionContext;
@property (nonatomic, strong) id<TGPhotoPaintStickersContext> stickersContext;
@property (nonatomic, assign) bool shortcut;

View File

@@ -24,7 +24,7 @@
@property (nonatomic, copy) void (^presentScheduleController)(void (^)(int32_t));
@property (nonatomic, copy) void (^presentTimerController)(void (^)(int32_t));
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context image:(UIImage *)image images:(NSArray *)images parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext hasCaptions:(bool)hasCaptions hasTimer:(bool)hasTimer hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder recipientName:(NSString *)recipientName;
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context image:(UIImage *)image images:(NSArray *)images parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext hasCaptions:(bool)hasCaptions hasTimer:(bool)hasTimer hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder recipientName:(NSString *)recipientName;
- (void)present;

View File

@@ -7,14 +7,13 @@
@class TGMediaSelectionContext;
@class TGMediaEditingContext;
@class TGSuggestionContext;
@protocol TGMediaSelectableItem;
@protocol TGPhotoPaintStickersContext;
@interface TGClipboardMenu : NSObject
+ (TGMenuSheetController *)presentInParentController:(TGViewController *)parentController context:(id<LegacyComponentsContext>)context images:(NSArray *)images allowGrouping:(bool)allowGrouping hasCaption:(bool)hasCaption hasTimer:(bool)hasTimer hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder recipientName:(NSString *)recipientName suggestionContext:(TGSuggestionContext *)suggestionContext stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext presentScheduleController:(void (^)(void(^)(int32_t)))presentScheduleController presentTimerController:(void (^)(void(^)(int32_t)))presentTimerController completed:(void (^)(TGMediaSelectionContext *selectionContext, TGMediaEditingContext *editingContext, id<TGMediaSelectableItem> currentItem, bool silentPosting, int32_t scheduleTime))completed dismissed:(void (^)(void))dismissed sourceView:(UIView *)sourceView sourceRect:(CGRect (^)(void))sourceRect;
+ (TGMenuSheetController *)presentInParentController:(TGViewController *)parentController context:(id<LegacyComponentsContext>)context images:(NSArray *)images allowGrouping:(bool)allowGrouping hasCaption:(bool)hasCaption hasTimer:(bool)hasTimer hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder recipientName:(NSString *)recipientName stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext presentScheduleController:(void (^)(void(^)(int32_t)))presentScheduleController presentTimerController:(void (^)(void(^)(int32_t)))presentTimerController completed:(void (^)(TGMediaSelectionContext *selectionContext, TGMediaEditingContext *editingContext, id<TGMediaSelectableItem> currentItem, bool silentPosting, int32_t scheduleTime))completed dismissed:(void (^)(void))dismissed sourceView:(UIView *)sourceView sourceRect:(CGRect (^)(void))sourceRect;
+ (NSArray *)resultSignalsForSelectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext currentItem:(id<TGMediaSelectableItem>)currentItem descriptionGenerator:(id (^)(id, NSAttributedString *,
NSString *))descriptionGenerator;

View File

@@ -13,7 +13,6 @@
+ (NSString *)stringForPreciseDate:(int)date;
+ (NSString *)stringForMessageListDate:(int)date;
+ (NSString *)stringForApproximateDate:(int)date;
+ (NSString *)stringForRelativeLastSeen:(int)date;
+ (NSString *)stringForRelativeUpdate:(int)date;
+ (NSString *)stringForFullDate:(int)date;
+ (NSString *)stringForCallsListDate:(int)date;

View File

@@ -1,11 +0,0 @@
#import <UIKit/UIKit.h>
@interface TGGradientLabel : UIView
@property (nonatomic, strong) UIFont *font;
@property (nonatomic, strong) NSString *text;
@property (nonatomic) int topColor;
@property (nonatomic) int bottomColor;
@property (nonatomic) UIColor *textColor;
@end

View File

@@ -1,21 +0,0 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface TGInputTextTag : NSTextAttachment
@property (nonatomic, readonly) int64_t uniqueId;
@property (nonatomic, readonly) bool left;
@property (nonatomic, strong, readonly) id attachment;
- (instancetype)initWithUniqueId:(int64_t)uniqueId left:(bool)left attachment:(id)attachment;
@end
@interface TGInputTextTagAndRange : NSObject
@property (nonatomic, strong, readonly) TGInputTextTag *tag;
@property (nonatomic) NSRange range;
- (instancetype)initWithTag:(TGInputTextTag *)tag range:(NSRange)range;
@end

View File

@@ -1,25 +0,0 @@
#import "TGItemPreviewView.h"
#import <LegacyComponents/LegacyComponentsContext.h>
@interface TGItemMenuSheetPreviewView : TGItemPreviewView
{
UIView *_containerView;
}
@property (nonatomic, assign) bool presentActionsImmediately;
@property (nonatomic, assign) bool dontBlurOnPresentation;
@property (nonatomic, readonly) bool actionsPresented;
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context frame:(CGRect)frame;
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context mainItemViews:(NSArray *)mainItemViews actionItemViews:(NSArray *)actionItemViews;
- (void)setupWithMainItemViews:(NSArray *)mainItemViews actionItemViews:(NSArray *)actionItemViews;
- (void)setActionItemViews:(NSArray *)actionsView animated:(bool)animated;
- (void)performCommit;
- (void)performDismissal;
- (void)presentActions:(void (^)(void))animationBlock;
@end

View File

@@ -1,19 +0,0 @@
#import <UIKit/UIKit.h>
#import <LegacyComponents/LegacyComponentsContext.h>
#import <LegacyComponents/TGOverlayController.h>
@class TGItemPreviewView;
@interface TGItemPreviewController : TGOverlayController
@property (nonatomic, copy) void (^onDismiss)(void);
@property (nonatomic, copy) CGPoint (^sourcePointForItem)(id item);
@property (nonatomic, readonly) TGItemPreviewView *previewView;
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context parentController:(TGViewController *)parentController previewView:(TGItemPreviewView *)previewView;
- (void)dismiss;
- (void)dismissImmediately;
@end

View File

@@ -1,31 +0,0 @@
#import <UIKit/UIKit.h>
@interface TGItemPreviewView : UIView
@property (nonatomic, readonly) UIView *dimView;
@property (nonatomic, readonly) UIView *wrapperView;
@property (nonatomic, copy) CGPoint (^sourcePointForItem)(id item);
@property (nonatomic, copy) void (^onDismiss)(void);
@property (nonatomic, copy) void (^willDismiss)(void);
@property (nonatomic, assign) bool eccentric;
@property (nonatomic, strong) id item;
@property (nonatomic, assign) bool isLocked;
@property (nonatomic, assign) UIEdgeInsets safeAreaInset;
- (void)animateAppear;
- (void)animateDismiss:(void (^)())completion;
- (void)_handlePanOffset:(CGFloat)offset;
- (void)_handlePressEnded;
- (bool)_maybeLockWithVelocity:(CGFloat)velocity;
- (CGPoint)_wrapperViewContainerCenter;
- (void)_didAppear;
- (void)_willDisappear;
@end

View File

@@ -1,16 +0,0 @@
#import "TGRemoteImageView.h"
@interface TGLetteredAvatarView : TGRemoteImageView
- (void)setSingleFontSize:(CGFloat)singleFontSize doubleFontSize:(CGFloat)doubleFontSize useBoldFont:(bool)useBoldFont;
- (void)setFirstName:(NSString *)firstName lastName:(NSString *)lastName;
- (void)setTitle:(NSString *)title;
- (void)setTitleNeedsDisplay;
- (void)loadUserPlaceholderWithSize:(CGSize)size uid:(int64_t)uid firstName:(NSString *)firstName lastName:(NSString *)lastName placeholder:(UIImage *)placeholder;
- (void)loadGroupPlaceholderWithSize:(CGSize)size conversationId:(int64_t)conversationId title:(NSString *)title placeholder:(UIImage *)placeholder;
- (void)loadSavedMessagesWithSize:(CGSize)size placeholder:(UIImage *)placeholder;
@end

View File

@@ -2,7 +2,6 @@
#import <LegacyComponents/LegacyComponentsContext.h>
#import <LegacyComponents/TGMediaAssetsLibrary.h>
#import <LegacyComponents/TGSuggestionContext.h>
#import <LegacyComponents/TGMediaAssetsUtils.h>
@@ -53,7 +52,6 @@ typedef enum
@property (nonatomic, readonly) TGMediaEditingContext *editingContext;
@property (nonatomic, readonly) TGMediaSelectionContext *selectionContext;
@property (nonatomic, strong) TGSuggestionContext *suggestionContext;
@property (nonatomic, strong) id<TGPhotoPaintStickersContext> stickersContext;
@property (nonatomic, assign) bool localMediaCacheEnabled;
@property (nonatomic, assign) bool captionsEnabled;

View File

@@ -1,7 +1,5 @@
#import <LegacyComponents/TGViewController.h>
#import <LegacyComponents/TGSuggestionContext.h>
@class TGMediaPickerLayoutMetrics;
@class TGMediaSelectionContext;
@class TGMediaEditingContext;
@@ -19,7 +17,6 @@
TGMediaPickerSelectionGestureRecognizer *_selectionGestureRecognizer;
}
@property (nonatomic, strong) TGSuggestionContext *suggestionContext;
@property (nonatomic, strong) id<TGPhotoPaintStickersContext> stickersContext;
@property (nonatomic, assign) bool localMediaCacheEnabled;
@property (nonatomic, assign) bool captionsEnabled;

View File

@@ -8,7 +8,6 @@
@protocol TGPhotoPaintStickersContext;
@class TGMediaSelectionContext;
@class TGMediaEditingContext;
@class TGSuggestionContext;
@class TGMediaPickerGallerySelectedItemsModel;
@interface TGMediaPickerGalleryInterfaceView : UIView <TGModernGalleryInterfaceView>
@@ -42,7 +41,6 @@
- (void)setSelectedItemsModel:(TGMediaPickerGallerySelectedItemsModel *)selectedItemsModel;
- (void)setEditorTabPressed:(void (^)(TGPhotoEditorTab tab))editorTabPressed;
- (void)setSuggestionContext:(TGSuggestionContext *)suggestionContext;
- (void)setThumbnailSignalForItem:(SSignal *(^)(id))thumbnailSignalForItem;

View File

@@ -17,8 +17,6 @@
@protocol TGPhotoPaintStickersContext;
@class TGSuggestionContext;
@interface TGMediaPickerGalleryModel : TGModernGalleryModel
@property (nonatomic, copy) void (^willFinishEditingItem)(id<TGMediaEditableItem> item, id<TGMediaEditAdjustments> adjustments, id temporaryRep, bool hasChanges);
@@ -45,7 +43,6 @@
@property (nonatomic, copy) NSInteger (^externalSelectionCount)(void);
@property (nonatomic, readonly) TGMediaSelectionContext *selectionContext;
@property (nonatomic, strong) TGSuggestionContext *suggestionContext;
@property (nonatomic, strong) id<TGPhotoPaintStickersContext> stickersContext;
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context items:(NSArray *)items focusItem:(id<TGModernGalleryItem>)focusItem selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions hasSelectionPanel:(bool)hasSelectionPanel hasCamera:(bool)hasCamera recipientName:(NSString *)recipientName;

View File

@@ -3,6 +3,7 @@
#import <LegacyComponents/TGModernGalleryEditableItem.h>
#import <AVFoundation/AVFoundation.h>
@class TGMediaAssetFetchResult;
@protocol TGMediaEditAdjustments;
@interface TGMediaPickerGalleryVideoItem : TGMediaPickerGalleryItem <TGModernGallerySelectableItem, TGModernGalleryEditableItem>
@@ -12,3 +13,13 @@
- (SSignal *)durationSignal;
@end
@interface TGMediaPickerGalleryFetchResultItem : TGMediaPickerGalleryItem <TGModernGallerySelectableItem, TGModernGalleryEditableItem>
@property (nonatomic, readonly) TGMediaPickerGalleryItem<TGModernGallerySelectableItem, TGModernGalleryEditableItem> *backingItem;
- (instancetype)initWithFetchResult:(TGMediaAssetFetchResult *)fetchResult index:(NSUInteger)index;
@end

View File

@@ -6,7 +6,6 @@
@class TGMediaSelectionContext;
@class TGMediaEditingContext;
@class TGSuggestionContext;
@class TGMediaPickerGalleryItem;
@class TGMediaAssetFetchResult;
@class TGMediaAssetMomentList;
@@ -32,9 +31,9 @@
@property (nonatomic, copy) void (^presentScheduleController)(void (^)(int32_t));
@property (nonatomic, copy) void (^presentTimerController)(void (^)(int32_t));
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item fetchResult:(TGMediaAssetFetchResult *)fetchResult parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions inhibitMute:(bool)inhibitMute asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit recipientName:(NSString *)recipientName hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext;
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item fetchResult:(TGMediaAssetFetchResult *)fetchResult parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions inhibitMute:(bool)inhibitMute asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit recipientName:(NSString *)recipientName hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext;
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item momentList:(TGMediaAssetMomentList *)momentList parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions inhibitMute:(bool)inhibitMute asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext;
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item momentList:(TGMediaAssetMomentList *)momentList parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions inhibitMute:(bool)inhibitMute asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext;
- (void)present;
- (void)updateWithFetchResult:(TGMediaAssetFetchResult *)fetchResult;

View File

@@ -1,7 +1,6 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class TGSuggestionContext;
@protocol TGPhotoPaintStickersContext;
@protocol TGCaptionPanelView;
@@ -18,8 +17,6 @@
@property (nonatomic, assign) CGFloat contentAreaHeight;
@property (nonatomic, assign) bool allowEntities;
@property (nonatomic, strong) TGSuggestionContext *suggestionContext;
@property (nonatomic, copy) UIView *(^panelParentView)(void);
@property (nonatomic, copy) void (^panelFocused)(void);

View File

@@ -8,7 +8,6 @@
@class SSignal;
@class PGCameraShotMetadata;
@class TGSuggestionContext;
@class TGPhotoEditorController;
@class AVPlayer;
@@ -26,7 +25,6 @@ typedef enum {
@interface TGPhotoEditorController : TGOverlayController
@property (nonatomic, strong) TGSuggestionContext *suggestionContext;
@property (nonatomic, strong) TGMediaEditingContext *editingContext;
@property (nonatomic, strong) id<TGPhotoPaintStickersContext> stickersContext;

View File

@@ -1,73 +0,0 @@
#import <UIKit/UIKit.h>
#import <LegacyComponents/ActionStage.h>
#import <LegacyComponents/TGCache.h>
#define TG_CACHE_INPLACE false
typedef enum {
TGRemoteImageContentHintLargeFile = 1,
TGRemoteImageContentHintSaveToGallery = 2,
TGRemoteImageContentHintLoadFromDiskSynchronously = 4,
TGRemoteImageContentHintBlurRemote = 8
} TGRemoteImageContentHints;
@class TGRemoteImageView;
typedef UIImage *(^TGImageProcessor)(UIImage *);
typedef UIImage *(^TGImageUniversalProcessor)(NSString *, UIImage *);
typedef void (^TGImageProgressHandler)(TGRemoteImageView *imageView, float progress);
@interface TGRemoteImageView : UIImageView
<ASWatcher>
@property (nonatomic, strong) ASHandle *actionHandle;
@property (nonatomic, strong) NSString *reuseIdentifier;
@property (nonatomic, strong) TGCache *cache;
@property (nonatomic) bool useCache;
@property (nonatomic) int contentHints;
@property (nonatomic) id userProperties;
@property (nonatomic) bool fadeTransition;
@property (nonatomic) NSTimeInterval fadeTransitionDuration;
@property (nonatomic) bool allowThumbnailCache;
#if TGRemoteImageUseContents
@property (nonatomic, strong) UIImage *image;
#endif
@property (nonatomic, strong) UIView *placeholderOverlay;
@property (nonatomic, strong) NSString *currentUrl;
@property (nonatomic, strong) NSString *currentFilter;
@property (nonatomic, copy) TGImageProgressHandler progressHandler;
@property (nonatomic) int cancelTimeout;
+ (void)throttleDownProcessing;
+ (void)registerImageUniversalProcessor:(TGImageUniversalProcessor)universalProcessor withBaseName:(NSString *)baseName;
+ (void)registerImageProcessor:(TGImageProcessor)imageProcessor withName:(NSString *)name;
+ (TGImageProcessor)imageProcessorForName:(NSString *)name;
+ (void)setSharedCache:(TGCache *)cache;
+ (TGCache *)sharedCache;
- (UIImage *)currentImage;
- (UIImage *)currentPlaceholderImage;
- (void)tryFillCache:(NSMutableDictionary *)dict;
- (void)loadImage:(UIImage *)image;
- (void)loadImage:(NSString *)url filter:(NSString *)filter placeholder:(UIImage *)placeholder;
- (void)loadImage:(NSString *)url filter:(NSString *)filter placeholder:(UIImage *)placeholder forceFade:(bool)forceFade;
- (void)loadPlaceholder:(UIImage *)placeholder;
- (void)cancelLoading;
+ (UIImage *)imageFromCache:(NSString *)url filter:(NSString *)filter cache:(TGCache *)cache;
+ (NSString *)preloadImage:(NSString *)url filter:(NSString *)filter blurIfRemote:(bool)blurIfRemote cache:(TGCache *)cache allowThumbnailCache:(bool)allowThumbnailCache watcher:(id<ASWatcher>)watcher;
- (void)prepareForRecycle;
- (void)prepareForReuse;
@end

View File

@@ -1,11 +0,0 @@
#import <Foundation/Foundation.h>
@class SSignal;
@interface TGSuggestionContext : NSObject
@property (nonatomic, copy) SSignal *(^userListSignal)(NSString *mention);
@property (nonatomic, copy) SSignal *(^hashtagListSignal)(NSString *hashtag);
@property (nonatomic, copy) SSignal *(^alphacodeSignal)(NSString *alphacode, NSString *languageCode);
@end

View File

@@ -1,133 +0,0 @@
#import <Foundation/Foundation.h>
#import <LegacyComponents/PSCoding.h>
#import <LegacyComponents/TGBotInfo.h>
typedef enum {
TGUserSexUnknown = 0,
TGUserSexMale = 1,
TGUserSexFemale = 2
} TGUserSex;
typedef enum {
TGUserPresenceValueLately = -2,
TGUserPresenceValueWithinAWeek = -3,
TGUserPresenceValueWithinAMonth = -4,
TGUserPresenceValueALongTimeAgo = -5
} TGUserPresenceValue;
typedef struct {
bool online;
int lastSeen;
int temporaryLastSeen;
} TGUserPresence;
typedef enum {
TGUserLinkKnown = 1,
TGUserLinkForeignRequested = 2,
TGUserLinkForeignMutual = 4,
TGUserLinkMyRequested = 8,
TGUserLinkMyContact = 16,
TGUserLinkForeignHasPhone = 32
} TGUserLink;
typedef enum {
TGUserFieldUid = 1,
TGUserFieldPhoneNumber = 2,
TGUserFieldPhoneNumberHash = 4,
TGUserFieldFirstName = 8,
TGUserFieldLastName = 16,
TGUserFieldPhonebookFirstName = 32,
TGUserFieldPhonebookLastName = 64,
TGUserFieldSex = 128,
TGUserFieldPhotoUrlSmall = 256,
TGUserFieldPhotoUrlMedium = 512,
TGUserFieldPhotoUrlBig = 1024,
TGUserFieldPresenceLastSeen = 2048,
TGUserFieldPresenceOnline = 4096,
TGUserFieldUsername = 8192,
TGUserFieldOther = 8192 * 2
} TGUserFields;
typedef enum {
TGUserKindGeneric = 0,
TGUserKindBot = 1,
TGUserKindSmartBot = 2
} TGUserKind;
typedef enum {
TGBotKindGeneric = 0,
TGBotKindPrivate = 1
} TGBotKind;
@class TGNotificationPrivacyAccountSetting;
#define TGUserFieldsAllButPresenceMask (TGUserFieldUid | TGUserFieldPhoneNumber | TGUserFieldPhoneNumberHash | TGUserFieldFirstName| TGUserFieldLastName | TGUserFieldPhonebookFirstName | TGUserFieldPhonebookLastName | TGUserFieldSex | TGUserFieldPhotoUrlSmall | TGUserFieldPhotoUrlMedium | TGUserFieldPhotoUrlBig)
@interface TGUser : NSObject <PSCoding>
@property (nonatomic) int64_t uid;
@property (nonatomic, strong) NSString *phoneNumber;
@property (nonatomic) int64_t phoneNumberHash;
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSString *userName;
@property (nonatomic, strong) NSString *phonebookFirstName;
@property (nonatomic, strong) NSString *phonebookLastName;
@property (nonatomic) TGUserSex sex;
@property (nonatomic) NSString *photoUrlSmall;
@property (nonatomic) NSString *photoUrlMedium;
@property (nonatomic) NSString *photoUrlBig;
@property (nonatomic) NSData *photoFileReferenceSmall;
@property (nonatomic) NSData *photoFileReferenceBig;
@property (nonatomic, strong, readonly) NSString *photoFullUrlSmall;
@property (nonatomic, strong, readonly) NSString *photoFullUrlBig;
@property (nonatomic) TGUserPresence presence;
@property (nonatomic) int contactId;
@property (nonatomic) int32_t kind;
@property (nonatomic) int32_t botKind;
@property (nonatomic) int32_t botInfoVersion;
@property (nonatomic) int32_t flags;
@property (nonatomic) bool isVerified;
@property (nonatomic) bool hasExplicitContent;
@property (nonatomic, strong) NSString *restrictionReason;
@property (nonatomic, strong) NSString *contextBotPlaceholder;
@property (nonatomic) bool isContextBot;
@property (nonatomic, strong) NSDictionary *customProperties;
@property (nonatomic) bool minimalRepresentation;
@property (nonatomic, strong) NSString *about;
@property (nonatomic) bool botInlineGeo;
@property (nonatomic, readonly) bool isBot;
@property (nonatomic, readonly) bool isDeleted;
- (id)copyWithZone:(NSZone *)zone;
- (bool)hasAnyName;
- (NSString *)realFirstName;
- (NSString *)realLastName;
- (NSString *)displayName;
- (NSString *)displayRealName;
- (NSString *)displayFirstName;
- (NSString *)compactName;
- (NSString *)formattedPhoneNumber;
- (bool)isEqualToUser:(TGUser *)anotherUser;
- (int)differenceFromUser:(TGUser *)anotherUser;
+ (TGUserPresence)approximatePresenceFromPresence:(TGUserPresence)presence currentTime:(NSTimeInterval)currentTime;
@end

View File

@@ -1,14 +0,0 @@
#import "TGAlphacode.h"
@implementation TGAlphacodeEntry
- (instancetype)initWithEmoji:(NSString *)emoji code:(NSString *)code {
self = [super init];
if (self != nil) {
_emoji = emoji;
_code = code;
}
return self;
}
@end

View File

@@ -839,7 +839,7 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500;
if ([cell isKindOfClass:[TGAttachmentAssetCell class]])
thumbnailImage = cell.imageView.image;
TGMediaPickerModernGalleryMixin *mixin = [[TGMediaPickerModernGalleryMixin alloc] initWithContext:_context item:asset fetchResult:_fetchResult parentController:self.parentController thumbnailImage:thumbnailImage selectionContext:_selectionContext editingContext:_editingContext suggestionContext:self.suggestionContext hasCaptions:(_allowCaptions && !_forProfilePhoto) allowCaptionEntities:self.allowCaptionEntities hasTimer:self.hasTimer onlyCrop:self.onlyCrop inhibitDocumentCaptions:_inhibitDocumentCaptions inhibitMute:self.inhibitMute asFile:self.asFile itemsLimit:TGAttachmentDisplayedAssetLimit recipientName:self.recipientName hasSilentPosting:self.hasSilentPosting hasSchedule:self.hasSchedule reminder:self.reminder stickersContext:self.stickersContext];
TGMediaPickerModernGalleryMixin *mixin = [[TGMediaPickerModernGalleryMixin alloc] initWithContext:_context item:asset fetchResult:_fetchResult parentController:self.parentController thumbnailImage:thumbnailImage selectionContext:_selectionContext editingContext:_editingContext hasCaptions:(_allowCaptions && !_forProfilePhoto) allowCaptionEntities:self.allowCaptionEntities hasTimer:self.hasTimer onlyCrop:self.onlyCrop inhibitDocumentCaptions:_inhibitDocumentCaptions inhibitMute:self.inhibitMute asFile:self.asFile itemsLimit:TGAttachmentDisplayedAssetLimit recipientName:self.recipientName hasSilentPosting:self.hasSilentPosting hasSchedule:self.hasSchedule reminder:self.reminder stickersContext:self.stickersContext];
mixin.presentScheduleController = self.presentScheduleController;
mixin.presentTimerController = self.presentTimerController;
__weak TGAttachmentCarouselItemView *weakSelf = self;

View File

@@ -1531,7 +1531,6 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
TGMediaPickerGalleryModel *model = [[TGMediaPickerGalleryModel alloc] initWithContext:windowContext items:galleryItems focusItem:focusItem selectionContext:_items.count > 1 ? selectionContext : nil editingContext:editingContext hasCaptions:self.allowCaptions allowCaptionEntities:self.allowCaptionEntities hasTimer:self.hasTimer onlyCrop:_intent == TGCameraControllerPassportIntent || _intent == TGCameraControllerPassportIdIntent || _intent == TGCameraControllerPassportMultipleIntent inhibitDocumentCaptions:self.inhibitDocumentCaptions hasSelectionPanel:true hasCamera:hasCamera recipientName:self.recipientName];
model.inhibitMute = self.inhibitMute;
model.controller = galleryController;
model.suggestionContext = self.suggestionContext;
model.stickersContext = self.stickersContext;
__weak TGModernGalleryController *weakGalleryController = galleryController;

View File

@@ -10,7 +10,6 @@
#import <LegacyComponents/TGMediaEditingContext.h>
#import <LegacyComponents/TGMediaSelectionContext.h>
#import <LegacyComponents/TGSuggestionContext.h>
#import <LegacyComponents/TGMediaAsset.h>
#import <LegacyComponents/TGMediaAssetFetchResult.h>
@@ -39,7 +38,7 @@
@implementation TGClipboardGalleryMixin
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context image:(UIImage *)image images:(NSArray *)images parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext hasCaptions:(bool)hasCaptions hasTimer:(bool)hasTimer hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder recipientName:(NSString *)recipientName
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context image:(UIImage *)image images:(NSArray *)images parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext hasCaptions:(bool)hasCaptions hasTimer:(bool)hasTimer hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder recipientName:(NSString *)recipientName
{
self = [super init];
if (self != nil)
@@ -68,7 +67,6 @@
TGClipboardGalleryModel *model = [[TGClipboardGalleryModel alloc] initWithContext:_context images:images focusIndex:focusIndex selectionContext:selectionContext editingContext:editingContext stickersContext:stickersContext hasCaptions:hasCaptions hasTimer:hasTimer hasSelectionPanel:false recipientName:recipientName];
_galleryModel = model;
model.controller = modernGallery;
model.suggestionContext = suggestionContext;
model.willFinishEditingItem = ^(id<TGMediaEditableItem> editableItem, id<TGMediaEditAdjustments> adjustments, id representation, bool hasChanges)
{
__strong TGClipboardGalleryMixin *strongSelf = weakSelf;

View File

@@ -24,7 +24,6 @@
@property (nonatomic, readonly, strong) TGMediaPickerGallerySelectedItemsModel *selectedItemsModel;
@property (nonatomic, readonly) TGMediaSelectionContext *selectionContext;
@property (nonatomic, strong) TGSuggestionContext *suggestionContext;
@property (nonatomic, strong) id<TGPhotoPaintStickersContext> stickersContext;
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context images:(NSArray *)images focusIndex:(NSUInteger)focusIndex selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext hasCaptions:(bool)hasCaptions hasTimer:(bool)hasTimer hasSelectionPanel:(bool)hasSelectionPanel recipientName:(NSString *)recipientName;

View File

@@ -171,12 +171,6 @@
return self;
}
- (void)setSuggestionContext:(TGSuggestionContext *)suggestionContext
{
_suggestionContext = suggestionContext;
[_interfaceView setSuggestionContext:suggestionContext];
}
- (NSInteger)selectionCount
{
return _selectedItemsModel.selectedCount;
@@ -326,7 +320,6 @@
controller.editingContext = _editingContext;
controller.stickersContext = _stickersContext;
self.editorController = controller;
controller.suggestionContext = self.suggestionContext;
controller.willFinishEditing = ^(id<TGMediaEditAdjustments> adjustments, id temporaryRep, bool hasChanges)
{
__strong TGClipboardGalleryModel *strongSelf = weakSelf;

View File

@@ -9,7 +9,7 @@
@implementation TGClipboardMenu
+ (TGMenuSheetController *)presentInParentController:(TGViewController *)parentController context:(id<LegacyComponentsContext>)context images:(NSArray *)images allowGrouping:(bool)allowGrouping hasCaption:(bool)hasCaption hasTimer:(bool)hasTimer hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder recipientName:(NSString *)recipientName suggestionContext:(TGSuggestionContext *)suggestionContext stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext presentScheduleController:(void (^)(void(^)(int32_t)))presentScheduleController presentTimerController:(void (^)(void(^)(int32_t)))presentTimerController completed:(void (^)(TGMediaSelectionContext *selectionContext, TGMediaEditingContext *editingContext, id<TGMediaSelectableItem> currentItem, bool silentPosting, int32_t scheduleTime))completed dismissed:(void (^)(void))dismissed sourceView:(UIView *)sourceView sourceRect:(CGRect (^)(void))sourceRect
+ (TGMenuSheetController *)presentInParentController:(TGViewController *)parentController context:(id<LegacyComponentsContext>)context images:(NSArray *)images allowGrouping:(bool)allowGrouping hasCaption:(bool)hasCaption hasTimer:(bool)hasTimer hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder recipientName:(NSString *)recipientName stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext presentScheduleController:(void (^)(void(^)(int32_t)))presentScheduleController presentTimerController:(void (^)(void(^)(int32_t)))presentTimerController completed:(void (^)(TGMediaSelectionContext *selectionContext, TGMediaEditingContext *editingContext, id<TGMediaSelectableItem> currentItem, bool silentPosting, int32_t scheduleTime))completed dismissed:(void (^)(void))dismissed sourceView:(UIView *)sourceView sourceRect:(CGRect (^)(void))sourceRect
{
bool centered = false;
if (sourceRect == nil)
@@ -42,7 +42,6 @@
TGClipboardPreviewItemView *previewItem = [[TGClipboardPreviewItemView alloc] initWithContext:context images:images allowGrouping:allowGrouping];
__weak TGClipboardPreviewItemView *weakPreviewItem = previewItem;
previewItem.stickersContext = stickersContext;
previewItem.suggestionContext = suggestionContext;
previewItem.parentController = parentController;
previewItem.allowCaptions = hasCaption;
previewItem.hasTimer = hasTimer;

View File

@@ -2,7 +2,6 @@
@class TGMediaSelectionContext;
@class TGMediaEditingContext;
@class TGSuggestionContext;
@protocol TGPhotoPaintStickersContext;
@@ -20,7 +19,6 @@
@property (nonatomic, readonly) TGMediaSelectionContext *selectionContext;
@property (nonatomic, readonly) TGMediaEditingContext *editingContext;
@property (nonatomic, strong) TGSuggestionContext *suggestionContext;
@property (nonatomic, strong) id<TGPhotoPaintStickersContext> stickersContext;
@property (nonatomic, copy) void (^selectionChanged)(NSUInteger);

View File

@@ -270,7 +270,7 @@ const CGFloat TGClipboardPreviewEdgeInset = 8.0f;
if ([cell isKindOfClass:[TGClipboardPreviewCell class]])
thumbnailImage = cell.imageView.image;
TGClipboardGalleryMixin *mixin = [[TGClipboardGalleryMixin alloc] initWithContext:_context image:image images:_images parentController:self.parentController thumbnailImage:thumbnailImage selectionContext:_selectionContext editingContext:_editingContext suggestionContext:self.suggestionContext stickersContext:self.stickersContext hasCaptions:self.allowCaptions hasTimer:self.hasTimer hasSilentPosting:self.hasSilentPosting hasSchedule:self.hasSchedule reminder:self.reminder recipientName:self.recipientName];
TGClipboardGalleryMixin *mixin = [[TGClipboardGalleryMixin alloc] initWithContext:_context image:image images:_images parentController:self.parentController thumbnailImage:thumbnailImage selectionContext:_selectionContext editingContext:_editingContext stickersContext:self.stickersContext hasCaptions:self.allowCaptions hasTimer:self.hasTimer hasSilentPosting:self.hasSilentPosting hasSchedule:self.hasSchedule reminder:self.reminder recipientName:self.recipientName];
mixin.presentScheduleController = self.presentScheduleController;
mixin.presentTimerController = self.presentTimerController;

View File

@@ -3,7 +3,6 @@
#import "LegacyComponentsInternal.h"
#import "TGStringUtils.h"
#import "TGUser.h"
#import "TGLocalization.h"
static bool value_dateHas12hFormat = false;
@@ -455,61 +454,6 @@ static inline NSString *dialogTimeFormat()
return [[NSString alloc] initWithFormat:TGLocalized(@"LastSeen.YesterdayAt"), timeString];
}
+ (NSString *)stringForRelativeLastSeen:(int)date
{
if (date == -1)
return TGLocalized(@"Presence.invisible");
else if (date == TGUserPresenceValueLately)
return TGLocalized(@"LastSeen.Lately");
else if (date == TGUserPresenceValueWithinAWeek)
return TGLocalized(@"LastSeen.WithinAWeek");
else if (date == TGUserPresenceValueWithinAMonth)
return TGLocalized(@"LastSeen.WithinAMonth");
else if (date == TGUserPresenceValueALongTimeAgo)
return TGLocalized(@"LastSeen.ALongTimeAgo");
else if (date <= 0)
return TGLocalized(@"Presence.offline");
time_t t = date;
struct tm timeinfo;
localtime_r(&t, &timeinfo);
time_t t_now;
time(&t_now);
struct tm timeinfo_now;
localtime_r(&t_now, &timeinfo_now);
if (timeinfo.tm_year != timeinfo_now.tm_year)
return [[NSString alloc] initWithFormat:TGLocalized(@"LastSeen.AtDate"), [self stringForFullDateWithDay:timeinfo.tm_mday month:timeinfo.tm_mon + 1 year:timeinfo.tm_year]];
else
{
int dayDiff = timeinfo.tm_yday - timeinfo_now.tm_yday;
int minutesDiff = (int)((t_now - date) / 60);
int hoursDiff = (int)((t_now - date) / (60 * 60));
if (dayDiff == 0 && hoursDiff <= 23)
{
if (minutesDiff < 1)
return TGLocalized(@"LastSeen.JustNow");
else if (minutesDiff < 60)
{
return [legacyEffectiveLocalization() getPluralized:@"LastSeen.MinutesAgo" count:(int32_t)minutesDiff];
}
else
{
return [legacyEffectiveLocalization() getPluralized:@"LastSeen.HoursAgo" count:(int32_t)hoursDiff];
}
}
else if (dayDiff == -1)
return [self stringForLastSeenYesterday:dayDiff == 0 hours:timeinfo.tm_hour minutes:timeinfo.tm_min];
else
return [[NSString alloc] initWithFormat:TGLocalized(@"LastSeen.AtDate"), [self stringForFullDateWithDay:timeinfo.tm_mday month:timeinfo.tm_mon + 1 year:timeinfo.tm_year]];
}
return nil;
}
+ (NSString *)stringForRelativeUpdate:(int)date
{
time_t t = date;

View File

@@ -1,163 +0,0 @@
#import "TGGradientLabel.h"
#import "LegacyComponentsInternal.h"
@interface TGGradientLabel ()
{
CGSize _textSize;
void *_offscreenMemory;
int _offscreenContextWidth;
int _offscreenContextHeight;
int _offscreenContextStride;
CGContextRef _offscreenContext;
}
@end
@implementation TGGradientLabel
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.opaque = false;
}
return self;
}
- (void)sizeToFit
{
if (_text == nil || _font == nil)
return;
_textSize = [self.text boundingRectWithSize:CGSizeMake(1000.0f, 1000.0f) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: _font} context:nil].size;
CGRect frame = self.frame;
frame.size = _textSize;
self.frame = frame;
}
- (void)setText:(NSString *)text
{
NSString *tmpText = text;
if (text.length == 1)
{
unichar c = [text characterAtIndex:0];
if (c >= 'a' && c <= 'z')
{
c += 'A' - 'a';
tmpText = [[NSString alloc] initWithCharacters:&c length:1];
}
}
else if (text.length == 3)
{
unichar c[3] = {[text characterAtIndex:0], [text characterAtIndex:1], [text characterAtIndex:2]};
if (c[0] >= 'a' && c[0] <= 'z')
c[0] += 'A' - 'a';
if (c[2] >= 'a' && c[2] <= 'z')
c[2] += 'A' - 'a';
tmpText = [[NSString alloc] initWithCharacters:c length:3];
}
_text = tmpText;
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)__unused rect
{
if (_text.length == 0 || _font == nil)
return;
bool nonEmpty = false;
for (int i = (int)_text.length - 1; i >= 0; i--)
{
if ([_text characterAtIndex:i] != ' ')
{
nonEmpty = true;
break;
}
}
if (!nonEmpty)
return;
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect bounds = self.bounds;
if (bounds.size.width < FLT_EPSILON || bounds.size.height < FLT_EPSILON)
return;
int offscreenWidth = (int)bounds.size.width;
int offscreenHeight = (int)bounds.size.height;
if (offscreenWidth != _offscreenContextWidth || offscreenHeight != _offscreenContextHeight)
{
if (_offscreenMemory != NULL)
{
free(_offscreenMemory);
_offscreenMemory = NULL;
}
if (_offscreenContext != NULL)
{
CFRelease(_offscreenContext);
_offscreenContext = NULL;
}
_offscreenContextWidth = offscreenWidth;
_offscreenContextHeight = offscreenHeight;
_offscreenContextStride = ((4 * _offscreenContextWidth + 31) & (~31));
_offscreenMemory = malloc(_offscreenContextStride * _offscreenContextHeight);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
_offscreenContext = CGBitmapContextCreate(_offscreenMemory, _offscreenContextWidth, _offscreenContextHeight, 8, _offscreenContextStride, colorSpace, bitmapInfo);
CGColorSpaceRelease(colorSpace);
}
if (_textColor != nil)
{
CGPoint drawingOffset = CGPointMake(CGFloor((bounds.size.width - _textSize.width) / 2.0f), CGFloor((bounds.size.height - _textSize.height) / 2.0f));
CGContextSetFillColorWithColor(context, _textColor.CGColor);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[_text drawAtPoint:drawingOffset withFont:_font];
#pragma clang diagnostic pop
}
else
{
CGContextSetTextDrawingMode(context, kCGTextClip);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[_text drawAtPoint:CGPointMake(CGFloor((bounds.size.width - _textSize.width) / 2.0f), CGFloor((bounds.size.height - _textSize.height) / 2.0f)) withFont:_font];
#pragma clang diagnostic pop
CGColorRef colors[2] = {
CGColorRetain(UIColorRGB(_topColor).CGColor),
CGColorRetain(UIColorRGB(_bottomColor).CGColor)
};
CFArrayRef colorsArray = CFArrayCreate(kCFAllocatorDefault, (const void **)&colors, 2, NULL);
CGFloat locations[2] = {0.0f, 1.0f};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, colorsArray, (CGFloat const *)&locations);
CFRelease(colorsArray);
CFRelease(colors[0]);
CFRelease(colors[1]);
CGColorSpaceRelease(colorSpace);
CGContextDrawLinearGradient(context, gradient, CGPointMake(0.0f, 0.0f), CGPointMake(0.0f, bounds.size.height), 0);
CFRelease(gradient);
}
}
@end

View File

@@ -1,59 +0,0 @@
#import "TGInputTextTag.h"
#import <CoreText/CoreText.h>
@implementation TGInputTextTag
- (instancetype)initWithUniqueId:(int64_t)uniqueId left:(bool)left attachment:(id)attachment {
static NSData *imageData = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
UIGraphicsBeginImageContextWithOptions(CGSizeMake(1.0f, 1.0f), false, 0.0f);
imageData = UIImagePNGRepresentation(UIGraphicsGetImageFromCurrentImageContext());
UIGraphicsEndImageContext();
});
self = [super initWithData:imageData ofType:@"public.image"];
if (self != nil) {
_uniqueId = uniqueId;
_left = left;
_attachment = attachment;
}
return self;
}
- (NSTextAttachment *)textAttachment {
static UIImage *image = nil;
static NSData *imageData = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
UIGraphicsBeginImageContextWithOptions(CGSizeMake(1.0f, 1.0f), false, 0.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
CGContextFillRect(context, CGRectMake(0.0f, 0.0f, 2.0f, 9.0f));
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
imageData = UIImagePNGRepresentation(image);
});
return nil;
}
- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)__unused textContainer proposedLineFragment:(CGRect)__unused lineFrag glyphPosition:(CGPoint)__unused position characterIndex:(NSUInteger)__unused charIndex {
return CGRectZero;
}
@end
@implementation TGInputTextTagAndRange
- (instancetype)initWithTag:(TGInputTextTag *)tag range:(NSRange)range {
self = [super init];
if (self != nil) {
_tag = tag;
_range = range;
}
return self;
}
@end

View File

@@ -1,757 +0,0 @@
#import "TGItemMenuSheetPreviewView.h"
#import "TGMenuSheetView.h"
#import "LegacyComponentsInternal.h"
#import <LegacyComponents/TGImageUtils.h>
#import <LegacyComponents/TGHacks.h>
#import <objc/runtime.h>
#import "TGMenuSheetController.h"
const CGFloat TGItemMenuSheetPreviewLockThreshold = 45.0f;
const CGFloat TGItemMenuSheetPreviewLockVelocityThreshold = 800.0f;
const CGFloat TGItemMenuSheetPreviewPeekScale = 0.95f;
const CGFloat TGItemMenuSheetPreviewArrowVisibleThreshold = -24.0f;
typedef enum
{
TGItemMenuTransitionTypeSimplified,
TGItemMenuTransitionTypeLegacy
} TGItemMenuTransitionType;
@interface TGItemMenuSheetPreviewView () <UIGestureRecognizerDelegate>
{
UIView *_blurView;
UIView *_blurDimView;
UIImageView *_shadowView;
UIButton *_dismissButton;
UIImageView *_arrowView;
TGMenuSheetView *_mainSheetView;
TGMenuSheetView *_actionsSheetView;
bool _actionsWerePresented;
bool _actionsAnimatingDismiss;
bool _dismissByVelocity;
UIPanGestureRecognizer *_panGestureRecognizer;
CGPoint _gestureStartLocation;
bool _wasPanning;
bool _shouldPassPanOffset;
TGMenuSheetItemView *_panHandlingItemView;
bool _actionsWerePresentedOnGestureStart;
id<LegacyComponentsContext> _context;
TGMenuSheetPallete *_pallete;
}
@end
@implementation TGItemMenuSheetPreviewView
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context frame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self != nil)
{
self.clipsToBounds = true;
_context = context;
if ([[LegacyComponentsGlobals provider] respondsToSelector:@selector(menuSheetPallete)])
_pallete = [[LegacyComponentsGlobals provider] menuSheetPallete];
TGItemMenuTransitionType type = [self _transitionType];
if (type != TGItemMenuTransitionTypeLegacy)
{
UIBlurEffect *effect = nil;
if (type == TGItemMenuTransitionTypeSimplified)
effect = _pallete.isDark ? [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark] : [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
_blurView = [[UIVisualEffectView alloc] initWithEffect:effect];
[self addSubview:_blurView];
if (type == TGItemMenuTransitionTypeSimplified)
_blurView.alpha = 0.0f;
[self.dimView removeFromSuperview];
_blurDimView = [[UIView alloc] initWithFrame:self.bounds];
_blurDimView.alpha = 0.0f;
_blurDimView.backgroundColor = UIColorRGBA(0x000000, 0.1f);
[self addSubview:_blurDimView];
}
else
{
self.dimView.backgroundColor = UIColorRGBA(0x000000, 0.2f);
}
}
return self;
}
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context mainItemViews:(NSArray *)mainItemViews actionItemViews:(NSArray *)actionItemViews
{
self = [self initWithContext:context frame:CGRectZero];
if (self != nil)
{
[self setupWithMainItemViews:mainItemViews actionItemViews:actionItemViews];
}
return self;
}
- (void)setupWithMainItemViews:(NSArray *)mainItemViews actionItemViews:(NSArray *)actionItemViews
{
[self bringSubviewToFront:self.wrapperView];
[_containerView removeFromSuperview];
_containerView = [[UIView alloc] init];
[self.wrapperView addSubview:_containerView];
bool requiresShadow = mainItemViews.count > 0;
for (TGMenuSheetItemView *itemView in mainItemViews)
{
if (itemView.requiresClearBackground)
{
requiresShadow = false;
break;
}
}
if (requiresShadow && _shadowView == nil)
{
_shadowView = [[UIImageView alloc] init];
_shadowView.image = [TGComponentsImageNamed(@"PreviewSheetShadow") resizableImageWithCapInsets:UIEdgeInsetsMake(42.0f, 42.0f, 42.0f, 42.0f)];
[_containerView addSubview:_shadowView];
}
[_dismissButton removeFromSuperview];
_dismissButton = [[UIButton alloc] initWithFrame:self.bounds];
_dismissButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[_dismissButton addTarget:self action:@selector(dismissButtonPressed) forControlEvents:UIControlEventTouchUpInside];
[_containerView addSubview:_dismissButton];
[_mainSheetView removeFromSuperview];
_mainSheetView = [[TGMenuSheetView alloc] initWithContext:_context pallete:_pallete itemViews:mainItemViews sizeClass:UIUserInterfaceSizeClassCompact dark:false borderless:false];
__weak TGItemMenuSheetPreviewView *weakSelf = self;
void (^menuRelayout)(void) = ^
{
__strong TGItemMenuSheetPreviewView *strongSelf = weakSelf;
if (strongSelf == nil)
return;
strongSelf->_mainSheetView.frame = [strongSelf _mainViewFrameExpanded:strongSelf.presentActionsImmediately];
};
_mainSheetView.menuRelayout = menuRelayout;
[_arrowView removeFromSuperview];
_arrowView = [[UIImageView alloc] initWithImage:TGComponentsImageNamed(@"PreviewUpArrow")];
_arrowView.alpha = 0.0f;
[_mainSheetView addSubview:_arrowView];
if (actionItemViews.count > 0)
{
[_actionsSheetView removeFromSuperview];
_actionsSheetView = [[TGMenuSheetView alloc] initWithContext:_context pallete:_pallete itemViews:actionItemViews sizeClass:UIUserInterfaceSizeClassCompact dark:false borderless:false];
_actionsSheetView.hidden = true;
}
}
- (void)setActionItemViews:(NSArray *)__unused actionsView animated:(bool)__unused animated
{
}
- (TGItemMenuTransitionType)_transitionType
{
static dispatch_once_t onceToken;
static TGItemMenuTransitionType type;
dispatch_once(&onceToken, ^
{
CGSize screenSize = TGScreenSize();
if (iosMajorVersion() < 8 || (NSInteger)screenSize.height == 480)
type = TGItemMenuTransitionTypeLegacy;
else
type = TGItemMenuTransitionTypeSimplified;
});
return type;
}
- (void)dismissButtonPressed
{
[self performDismissal];
}
- (void)prepareSheetViews
{
CGSize referenceSize = [_context fullscreenBounds].size;
CGFloat minSide = MIN(referenceSize.width, referenceSize.height);
_mainSheetView.menuWidth = minSide;
_actionsSheetView.menuWidth = minSide;
[_containerView addSubview:_mainSheetView];
if (_actionsSheetView != nil)
[_containerView addSubview:_actionsSheetView];
_mainSheetView.frame = [self _mainViewFrameExpanded:self.presentActionsImmediately];
_shadowView.frame = [self _shadowFrame];
[_mainSheetView layoutSubviews];
_actionsSheetView.frame = [self _actionsViewFrameExpanded:false];
[_actionsSheetView layoutSubviews];
_arrowView.frame = CGRectMake((_mainSheetView.frame.size.width - _arrowView.frame.size.width) / 2.0f, -14.0f, _arrowView.frame.size.width, _arrowView.frame.size.height);
[_mainSheetView menuWillAppearAnimated:true];
[_actionsSheetView menuWillAppearAnimated:true];
}
- (CGRect)_shadowFrame
{
CGRect frame = _mainSheetView.frame;
frame.origin.x -= 6.5f;
frame.size.width += 13.0f;
frame.origin.y -= 6.0f;
frame.size.height += 13.0f;
return frame;
}
- (void)animateAppear
{
self.wrapperView.frame = self.bounds;
_containerView.frame = self.wrapperView.bounds;
[self prepareSheetViews];
[super animateAppear];
void (^completionBlock)(BOOL) = ^(__unused BOOL finished)
{
if (self.presentActionsImmediately)
{
[_mainSheetView menuDidAppearAnimated:true];
[_actionsSheetView menuDidAppearAnimated:true];
[self _initializeInternalGestureRecognizer];
}
};
if (!self.dontBlurOnPresentation || self.presentActionsImmediately)
{
[_context setApplicationStatusBarAlpha:0.0f];
[self performAppearBackgroundTransition:completionBlock];
}
if (self.presentActionsImmediately)
{
[self addSubview:_actionsSheetView];
[self _presentActions:nil];
}
}
- (void)animateDismiss:(void (^)())completion
{
[self.wrapperView addSubview:_containerView];
[super animateDismiss:completion];
void (^completionBlock)(void) = ^
{
[_mainSheetView menuDidDisappearAnimated:true];
[_actionsSheetView menuDidDisappearAnimated:true];
};
[self performDisappearBackgroundTransition:completionBlock];
}
- (void)performAppearBackgroundTransition:(void (^)(BOOL))completionBlock
{
TGItemMenuTransitionType type = [self _transitionType];
if (type == TGItemMenuTransitionTypeSimplified)
{
[UIView animateWithDuration:0.22 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^
{
_blurView.alpha = 1.0f;
} completion:completionBlock];
}
else
{
if (completionBlock != nil)
completionBlock(true);
}
}
- (void)performDisappearBackgroundTransition:(void (^)(void))completionBlock
{
TGItemMenuTransitionType type = [self _transitionType];
if (type == TGItemMenuTransitionTypeSimplified)
{
[UIView animateWithDuration:0.22 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^
{
[_context setApplicationStatusBarAlpha:1.0f];
_blurView.alpha = 0.0f;
} completion:^(__unused BOOL finished)
{
completionBlock();
}];
}
else
{
[_context setApplicationStatusBarAlpha:1.0f];
completionBlock();
}
}
- (void)_didAppear
{
[self addSubview:_containerView];
if (self.presentActionsImmediately || self.isLocked)
return;
[UIView animateWithDuration:0.25 animations:^
{
_arrowView.alpha = 1.0f;
}];
}
- (void)_willDisappear
{
[UIView animateWithDuration:0.16 animations:^
{
_arrowView.alpha = 0.0f;
}];
[_mainSheetView menuWillDisappearAnimated:true];
[_actionsSheetView menuWillDisappearAnimated:true];
}
- (void)setArrowHidden:(bool)hidden animated:(bool)animated
{
if (animated)
{
[UIView animateWithDuration:0.25 animations:^
{
_arrowView.alpha = hidden ? 0.0f : 1.0f;
}];
}
else
{
_arrowView.alpha = hidden ? 0.0f : 1.0f;
}
}
- (void)_handlePanOffset:(CGFloat)offset
{
CGFloat centerDelta = [self _mainViewFrameExpanded:false].origin.y - [self _mainViewFrameExpanded:true].origin.y;
CGFloat appliedOffset = [self swipeOffsetForOffset:offset];
CGRect frame = [self _mainViewFrameExpanded:_actionsWerePresentedOnGestureStart];
frame.origin.y += appliedOffset;
_mainSheetView.frame = frame;
_shadowView.frame = [self _shadowFrame];
[self setArrowHidden:(appliedOffset < TGItemMenuSheetPreviewArrowVisibleThreshold || _actionsPresented) animated:true];
if (!_actionsPresented)
{
if ((centerDelta > TGItemMenuSheetPreviewLockThreshold && (appliedOffset * -1) > centerDelta) || (centerDelta < TGItemMenuSheetPreviewLockThreshold && (appliedOffset * -1) > TGItemMenuSheetPreviewLockThreshold))
{
[self _presentActions:nil];
}
}
else if (!_actionsAnimatingDismiss)
{
CGRect expandedActionsFrame = [self _actionsViewFrameExpanded:true];
CGFloat diff = CGRectGetMaxY(_mainSheetView.frame) - 10.0f - CGRectGetMinY(expandedActionsFrame);
if (diff > 0)
{
expandedActionsFrame.origin.y += diff;
_actionsSheetView.frame = expandedActionsFrame;
}
if (appliedOffset >= 50.0f)
[self dismissActions];
}
}
- (void)_handlePressEnded
{
[self _initializeInternalGestureRecognizer];
if (!self.presentActionsImmediately)
{
[_mainSheetView menuDidAppearAnimated:true];
[_actionsSheetView menuDidAppearAnimated:true];
}
[self _centerMainSheetView];
}
- (bool)_maybeLockWithVelocity:(CGFloat)velocity
{
if (velocity < -TGItemMenuSheetPreviewLockVelocityThreshold)
{
[self _initializeInternalGestureRecognizer];
[self _presentActions:nil];
[self _centerMainSheetView];
return true;
}
return false;
}
- (void)_initializeInternalGestureRecognizer
{
if (_panGestureRecognizer != nil)
return;
_panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
_panGestureRecognizer.delegate = self;
[self addGestureRecognizer:_panGestureRecognizer];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if (gestureRecognizer == _panGestureRecognizer)
{
NSString *viewClassName = NSStringFromClass(otherGestureRecognizer.view.class);
if ([viewClassName rangeOfString:@"WKScroll"].location != NSNotFound)
{
return true;
}
return false;
}
return false;
}
- (void)handlePan:(UIPanGestureRecognizer *)gestureRecognizer
{
CGPoint location = [gestureRecognizer locationInView:self];
CGPoint velocity = [gestureRecognizer velocityInView:self];
CGFloat offset = location.y - _gestureStartLocation.y;
switch (gestureRecognizer.state)
{
case UIGestureRecognizerStateBegan:
{
_actionsWerePresented = _actionsPresented;
_actionsWerePresentedOnGestureStart = _actionsPresented;
_gestureStartLocation = location;
_panHandlingItemView = nil;
for (TGMenuSheetItemView *itemView in _mainSheetView.itemViews)
{
if (itemView.handlesPan)
{
_shouldPassPanOffset = true;
_panHandlingItemView = itemView;
break;
}
}
}
break;
case UIGestureRecognizerStateChanged:
{
bool shouldPan = _shouldPassPanOffset && [_panHandlingItemView passPanOffset:0];
if (!shouldPan)
{
_wasPanning = false;
[self _handlePanOffset:0];
}
else
{
if (!_wasPanning)
{
_gestureStartLocation = location;
_wasPanning = true;
offset = 0;
}
}
if (!_shouldPassPanOffset || shouldPan)
[self _handlePanOffset:offset];
}
break;
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled:
{
bool allowDismissal = !_shouldPassPanOffset || _wasPanning;
if (_actionsPresented && velocity.y < TGItemMenuSheetPreviewLockVelocityThreshold)
{
[self _centerMainSheetView];
}
else if (allowDismissal)
{
_dismissByVelocity = _actionsPresented;
[self performDismissal];
}
}
break;
default:
break;
}
}
#pragma mark -
- (void)_centerMainSheetView
{
[self setArrowHidden:_actionsPresented animated:true];
void (^changeBlock)(void) = ^
{
_mainSheetView.frame = [self _mainViewFrameExpanded:true];
_shadowView.frame = [self _shadowFrame];
if (_actionsPresented && !_actionsAnimatingDismiss)
_actionsSheetView.frame = [self _actionsViewFrameExpanded:true];
};
void (^completionBlock)(BOOL) = ^(BOOL finished)
{
if (finished)
{
if (_actionsSheetView.superview != _containerView)
[_containerView addSubview:_actionsSheetView];
}
};
if (iosMajorVersion() >= 7)
{
[UIView animateWithDuration:0.44 delay:0.0 usingSpringWithDamping:0.72f initialSpringVelocity:0.0f options:UIViewAnimationOptionAllowUserInteraction animations:changeBlock completion:nil];
}
else
{
[UIView animateWithDuration:0.3 delay:0.0 options:0 animations:changeBlock completion:completionBlock];
}
}
- (CGRect)_mainViewFrameExpanded:(bool)expanded
{
CGSize menuSize = _mainSheetView.menuSize;
CGRect rect = CGRectMake((_containerView.frame.size.width - menuSize.width) / 2.0f, (_containerView.frame.size.height - menuSize.height) / 2.0f, menuSize.width, menuSize.height);
if (expanded)
{
CGRect actionsViewRect = [self _actionsViewFrameExpanded:true];
rect.origin.y = MIN(rect.origin.y, actionsViewRect.origin.y - rect.size.height + 10.0f);
}
return rect;
}
- (CGRect)_actionsViewFrameExpanded:(bool)expanded
{
CGSize menuSize = _actionsSheetView.menuSize;
CGRect rect = CGRectMake((_containerView.frame.size.width - menuSize.width) / 2.0f, _containerView.frame.size.height, menuSize.width, menuSize.height);
if (expanded)
rect.origin.y = _containerView.frame.size.height - rect.size.height - self.safeAreaInset.bottom;
return rect;
}
- (CGFloat)swipeOffsetForOffset:(CGFloat)offset
{
if (offset < 0)
return [self rubberBandedOffsetForOffset:offset bandingStart:0.0f coefficient:0.4f range:600.0f];
else if ((_actionsPresented || _actionsWerePresented) && offset > 0.0f)
return [self rubberBandedOffsetForOffset:offset bandingStart:0.0f coefficient:0.3f range:480.0f];
else if (!_actionsPresented && offset > 0.0f)
return [self rubberBandedOffsetForOffset:offset bandingStart:0.0f coefficient:0.12f range:320.0f];
else
return offset;
}
- (CGFloat)rubberBandedOffsetForOffset:(CGFloat)offset bandingStart:(CGFloat)bandingStart coefficient:(CGFloat)coefficient range:(CGFloat)range
{
CGFloat bandedOffset = offset - bandingStart;
return bandingStart + (1.0f - (1.0f / ((bandedOffset * coefficient / range) + 1.0f))) * range;
}
- (void)presentActions:(void (^)(void))animationBlock
{
[self _initializeInternalGestureRecognizer];
[self performAppearBackgroundTransition:nil];
[self addSubview:_actionsSheetView];
[self _presentActions:animationBlock];
}
- (void)_presentActions:(void (^)(void))animationBlock
{
if (_actionsPresented || _actionsAnimatingDismiss)
return;
_actionsPresented = true;
_actionsWerePresented = true;
_actionsSheetView.hidden = false;
void (^changeBlock)(void) = ^
{
_actionsSheetView.frame = [self _actionsViewFrameExpanded:true];
if (animationBlock != nil)
animationBlock();
};
void (^completionBlock)(BOOL) = ^(BOOL finished)
{
if (finished)
{
if (_actionsSheetView.superview != _containerView)
[_containerView addSubview:_actionsSheetView];
}
};
if (iosMajorVersion() >= 7)
{
[UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.8f initialSpringVelocity:0.0f options:0 animations:changeBlock completion:completionBlock];
}
else
{
[UIView animateWithDuration:0.3 delay:0.0 options:0 animations:changeBlock completion:completionBlock];
}
}
- (void)dismissActions
{
_actionsAnimatingDismiss = true;
void (^changeBlock)(void) = ^
{
_actionsSheetView.frame = [self _actionsViewFrameExpanded:false];
};
void (^completionBlock)(BOOL) = ^(BOOL finished)
{
_actionsAnimatingDismiss = false;
_actionsPresented = false;
_actionsSheetView.hidden = true;
if (_panGestureRecognizer != nil && _panGestureRecognizer.state != UIGestureRecognizerStateChanged)
[self performDismissal];
};
if (iosMajorVersion() >= 7)
{
[UIView animateWithDuration:0.3 delay:0.0 usingSpringWithDamping:1.5 initialSpringVelocity:0.0 options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowAnimatedContent animations:changeBlock completion:completionBlock];
}
else
{
[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowAnimatedContent animations:changeBlock completion:completionBlock];
}
}
- (void)performCommit
{
if (self.willDismiss != nil)
self.willDismiss();
void (^changeBlock)(void) = ^
{
_mainSheetView.frame = CGRectMake(_mainSheetView.frame.origin.x, -_mainSheetView.frame.size.height, _mainSheetView.frame.size.width, _mainSheetView.frame.size.height);
_shadowView.frame = [self _shadowFrame];
_actionsSheetView.frame = [self _actionsViewFrameExpanded:false];
};
void (^completionBlock)(BOOL) = ^(BOOL finished)
{
_mainSheetView.hidden = true;
_actionsSheetView.hidden = true;
[self animateDismiss:^
{
if (self.onDismiss != nil)
self.onDismiss();
}];
};
if (iosMajorVersion() >= 7)
{
[UIView animateWithDuration:0.3 delay:0.0 usingSpringWithDamping:1.5 initialSpringVelocity:0.0 options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowAnimatedContent animations:changeBlock completion:completionBlock];
}
else
{
[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowAnimatedContent animations:changeBlock completion:completionBlock];
}
}
- (void)performDismissal
{
if (self.willDismiss != nil)
self.willDismiss();
if (_actionsPresented)
{
[self addSubview:_actionsSheetView];
void (^changeBlock)(void) = ^
{
if (!_actionsAnimatingDismiss)
_actionsSheetView.frame = [self _actionsViewFrameExpanded:false];
if (_actionsAnimatingDismiss || _dismissByVelocity)
{
_mainSheetView.frame = [self _mainViewFrameExpanded:false];
_shadowView.frame = [self _shadowFrame];
}
};
if (iosMajorVersion() >= 7)
{
[UIView animateWithDuration:0.24 delay:0.0 usingSpringWithDamping:1.5 initialSpringVelocity:0.0 options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowAnimatedContent animations:changeBlock completion:nil];
}
else
{
[UIView animateWithDuration:0.2 delay:0.0 options:0 animations:changeBlock completion:nil];
}
TGDispatchAfter(0.15, dispatch_get_main_queue(), ^
{
[self animateDismiss:^
{
if (self.onDismiss != nil)
self.onDismiss();
}];
});
}
else
{
[self animateDismiss:^
{
if (self.onDismiss != nil)
self.onDismiss();
}];
}
}
- (bool)isLocked
{
return _actionsPresented;
}
- (void)layoutSubviews
{
[super layoutSubviews];
_blurView.frame = self.bounds;
_blurDimView.frame = self.bounds;
}
@end

View File

@@ -1,152 +0,0 @@
#import "TGItemPreviewController.h"
#import "LegacyComponentsInternal.h"
#import "TGViewController.h"
#import "TGItemPreviewView.h"
#import "TGOverlayControllerWindow.h"
@interface TGItemPreviewController ()
{
bool _autorotationWasEnabled;
id<LegacyComponentsContext> _context;
}
@end
@implementation TGItemPreviewController
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context parentController:(TGViewController *)parentController previewView:(TGItemPreviewView *)previewView
{
self = [self initWithContext:context];
if (self != nil)
{
_context = context;
_previewView = previewView;
_previewView.safeAreaInset = [TGViewController safeAreaInsetForOrientation:[LegacyComponentsGlobals provider].applicationStatusBarOrientation hasOnScreenNavigation:false];
TGOverlayControllerWindow *window = [[TGOverlayControllerWindow alloc] initWithManager:[context makeOverlayWindowManager] parentController:parentController contentController:self keepKeyboard:true];
window.windowLevel = UIWindowLevelStatusBar;
window.tag = 0xbeef;
window.userInteractionEnabled = previewView.userInteractionEnabled;
window.hidden = false;
__weak TGItemPreviewController *weakSelf = self;
_previewView.onDismiss = ^
{
__strong TGItemPreviewController *strongSelf = weakSelf;
if (strongSelf != nil)
[strongSelf dismissImmediately];
};
_previewView.willDismiss = ^{
__strong TGItemPreviewController *strongSelf = weakSelf;
if (strongSelf != nil && strongSelf.onDismiss != nil)
{
void (^onDismiss)(void) = [strongSelf.onDismiss copy];
strongSelf.onDismiss = nil;
onDismiss();
}
};
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
}
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewDidLayoutSubviews
{
self.view.frame = [_context fullscreenBounds];
}
- (void)applicationDidBecomeActive:(NSNotification *)__unused notification
{
[self.view.window makeKeyAndVisible];
}
- (CGPoint (^)(id))sourcePointForItem
{
return _previewView.sourcePointForItem;
}
- (void)setSourcePointForItem:(CGPoint (^)(id))sourcePointForItem
{
_previewView.sourcePointForItem = [sourcePointForItem copy];
}
- (void)loadView
{
[super loadView];
_previewView.frame = self.view.bounds;
_previewView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:_previewView];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
_autorotationWasEnabled = [TGViewController autorotationAllowed];
[TGViewController disableAutorotation];
[_previewView animateAppear];
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
[self.view.window.layer removeAnimationForKey:@"backgroundColor"];
[CATransaction begin];
[CATransaction setDisableActions:true];
self.view.window.layer.backgroundColor = [UIColor clearColor].CGColor;
[CATransaction commit];
for (UIView *view in self.view.window.subviews)
{
if (view != self.view)
{
[view removeFromSuperview];
break;
}
}
}
- (void)dismiss
{
if (self.onDismiss != nil)
{
void (^onDismiss)(void) = [self.onDismiss copy];
self.onDismiss = nil;
onDismiss();
}
[_previewView animateDismiss:^
{
[self dismissImmediately];
}];
}
- (void)_handlePanOffset:(CGFloat)offset
{
[_previewView _handlePanOffset:offset];
}
- (void)dismissImmediately
{
[super dismiss];
if (_autorotationWasEnabled)
[TGViewController enableAutorotation];
if (self.onDismiss != nil)
self.onDismiss();
}
@end

View File

@@ -1,147 +0,0 @@
#import "TGItemPreviewView.h"
#import "LegacyComponentsInternal.h"
@interface TGItemPreviewView ()
{
bool _disappearing;
}
@end
@implementation TGItemPreviewView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self != nil)
{
_dimView = [[UIView alloc] init];
_dimView.backgroundColor = [UIColor colorWithWhite:1.0f alpha:0.7f];
_dimView.alpha = 0.0f;
[self addSubview:_dimView];
_wrapperView = [[UIView alloc] init];
_wrapperView.alpha = 0.0f;
[self addSubview:_wrapperView];
}
return self;
}
- (void)animateAppear
{
_wrapperView.frame = self.bounds;
CGPoint transitionInPoint = CGPointZero;
if (self.sourcePointForItem != nil)
transitionInPoint = self.sourcePointForItem(self.item);
bool animatedCenter = false;
if (!CGPointEqualToPoint(transitionInPoint, CGPointZero))
{
_wrapperView.center = transitionInPoint;
animatedCenter = true;
}
_dimView.alpha = 0.0f;
_wrapperView.transform = CGAffineTransformMakeScale(0.1f, 0.1f);
void (^changeBlock)(void) = ^
{
_dimView.alpha = 1.0f;
_wrapperView.alpha = 1.0f;
_wrapperView.transform = CGAffineTransformIdentity;
if (animatedCenter)
_wrapperView.center = [self _wrapperViewContainerCenter];
};
void (^completionBlock)(BOOL) = ^(__unused BOOL finished)
{
if (finished && !_disappearing)
[self _didAppear];
};
if (iosMajorVersion() < 8)
{
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:changeBlock completion:completionBlock];
}
else
{
[UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.72f initialSpringVelocity:0.0f options:0 animations:changeBlock completion:completionBlock];
}
}
- (void)animateDismiss:(void (^)())completion
{
CGPoint transitionOutPoint = CGPointZero;
if (self.sourcePointForItem != nil)
transitionOutPoint = self.sourcePointForItem(self.item);
[self _willDisappear];
_disappearing = true;
[UIView animateWithDuration:0.2 animations:^
{
_dimView.alpha = 0.0f;
_wrapperView.transform = CGAffineTransformMakeScale(0.3f, 0.3f);
_wrapperView.alpha = 0.0f;
if (!CGPointEqualToPoint(transitionOutPoint, CGPointZero))
_wrapperView.center = transitionOutPoint;
} completion:^(__unused BOOL finished)
{
if (completion)
completion();
}];
}
- (void)_didAppear
{
}
- (void)_willDisappear
{
}
- (CGPoint)_wrapperViewContainerCenter
{
CGRect bounds = self.bounds;
CGFloat y = bounds.size.height / 2.0f;
if (bounds.size.height > bounds.size.width && self.eccentric)
y = bounds.size.height / 3.0f;
return CGPointMake(bounds.size.width / 2.0f, y);
}
- (void)_handlePanOffset:(CGFloat)__unused offset
{
}
- (void)_handlePressEnded
{
}
- (bool)_maybeLockWithVelocity:(CGFloat)__unused velocity
{
return false;
}
- (void)layoutSubviews
{
[super layoutSubviews];
CGRect previousBounds = _dimView.bounds;
if (!CGRectEqualToRect(self.bounds, previousBounds))
{
_dimView.frame = self.bounds;
_wrapperView.center = [self _wrapperViewContainerCenter];
}
}
@end

View File

@@ -1,236 +0,0 @@
#import "TGLetteredAvatarView.h"
#import "LegacyComponentsInternal.h"
#import "TGFont.h"
#import "TGImageUtils.h"
#import <LegacyComponents/TGImageManager.h>
#import "TGGradientLabel.h"
@interface TGLetteredAvatarView ()
{
TGGradientLabel *_label;
UIFont *_singleFont;
UIFont *_doubleFont;
bool _usingSingleFont;
CGFloat _singleSize;
CGFloat _doubleSize;
}
@end
@implementation TGLetteredAvatarView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self != nil)
{
if (@available(iOS 11.0, *)) {
self.accessibilityIgnoresInvertColors = true;
}
_label = [[TGGradientLabel alloc] init];
_label.backgroundColor = [UIColor clearColor];
[self addSubview:_label];
}
return self;
}
- (void)setSingleFontSize:(CGFloat)singleFontSize doubleFontSize:(CGFloat)doubleFontSize useBoldFont:(bool)__unused useBoldFont
{
if (ABS(singleFontSize - _singleSize) < FLT_EPSILON && ABS(doubleFontSize - _doubleSize) < FLT_EPSILON)
return;
_singleSize = singleFontSize;
_doubleSize = doubleFontSize;
_singleFont = [TGFont roundedFontOfSize:singleFontSize];
_doubleFont = _singleFont;
}
- (void)loadImage:(UIImage *)image
{
_label.hidden = true;
[super loadImage:image];
}
- (void)loadImage:(NSString *)url filter:(NSString *)filter placeholder:(UIImage *)placeholder forceFade:(bool)forceFade
{
_label.hidden = true;
[super loadImage:url filter:filter placeholder:placeholder forceFade:forceFade];
}
static bool isEmojiCharacter(NSString *singleChar)
{
const unichar high = [singleChar characterAtIndex:0];
if (0xd800 <= high && high <= 0xdbff && singleChar.length >= 2)
{
const unichar low = [singleChar characterAtIndex:1];
const int codepoint = ((high - 0xd800) * 0x400) + (low - 0xdc00) + 0x10000;
return (0x1d000 <= codepoint && codepoint <= 0x1f77f);
}
return (0x2100 <= high && high <= 0x27bf);
}
- (NSString *)_cleanedUpString:(NSString *)string
{
NSMutableString *__block buffer = [NSMutableString stringWithCapacity:string.length];
[string enumerateSubstringsInRange:NSMakeRange(0, string.length)
options:NSStringEnumerationByComposedCharacterSequences
usingBlock: ^(NSString* substring, __unused NSRange substringRange, __unused NSRange enclosingRange, __unused BOOL* stop)
{
[buffer appendString:isEmojiCharacter(substring) ? @"" : substring];
}];
return buffer;
}
- (void)setFirstName:(NSString *)firstName lastName:(NSString *)lastName
{
if (!_label.hidden)
{
NSString *cleanFirstName = [self _cleanedUpString:firstName];
NSString *cleanLastName = [self _cleanedUpString:lastName];
if (cleanFirstName.length != 0 && cleanLastName.length != 0)
_label.text = [[NSString alloc] initWithFormat:@"%@\u200B%@", [cleanFirstName substringToIndex:1], [cleanLastName substringToIndex:1]];
else if (cleanFirstName.length != 0)
_label.text = [cleanFirstName substringToIndex:1];
else if (cleanLastName.length != 0)
_label.text = [cleanLastName substringToIndex:1];
else
_label.text = @" ";
if (cleanFirstName.length != 0 && cleanLastName.length != 0)
{
_label.text = [[NSString alloc] initWithFormat:@"%@\u200B%@", [cleanFirstName substringToIndex:1], [cleanLastName substringToIndex:1]];
}
else if (cleanFirstName.length != 0)
{
_label.text = [cleanFirstName substringToIndex:1];
}
else if (cleanLastName.length != 0)
{
_label.text = [cleanLastName substringToIndex:1];
}
else
_label.text = @" ";
[_label sizeToFit];
CGSize labelSize = _label.frame.size;
CGSize boundsSize = self.bounds.size;
labelSize.height = boundsSize.height;
_label.frame = CGRectMake(TGRetinaFloor((boundsSize.width - labelSize.width) / 2.0f), CGFloor((boundsSize.height - labelSize.height) / 2.0f), labelSize.width, labelSize.height);
}
}
- (void)setTitle:(NSString *)title
{
NSString *cleanTitle = [self _cleanedUpString:title];
_label.text = cleanTitle.length >= 1 ? [cleanTitle substringToIndex:1] : @" ";
[_label sizeToFit];
[self setNeedsLayout];
}
- (void)setTitleNeedsDisplay
{
if (!_label.hidden)
[_label setNeedsDisplay];
}
- (void)loadSavedMessagesWithSize:(CGSize)size placeholder:(UIImage *)placeholder
{
_label.text = @"";
NSString *placeholderUri = [[NSString alloc] initWithFormat:@"placeholder://?type=saved-messages&w=%d&h=%d" PRId32 "", (int)size.width, (int)size.height];
if (!TGStringCompare([self currentUrl], placeholderUri))
[super loadImage:placeholderUri filter:nil placeholder:placeholder];
_label.hidden = true;
}
- (void)loadUserPlaceholderWithSize:(CGSize)size uid:(int64_t)uid firstName:(NSString *)firstName lastName:(NSString *)lastName placeholder:(UIImage *)placeholder
{
_label.font = _doubleFont;
_usingSingleFont = false;
NSString *cleanFirstName = [self _cleanedUpString:firstName];
NSString *cleanLastName = [self _cleanedUpString:lastName];
if (cleanFirstName.length != 0 && cleanLastName.length != 0)
{
_label.text = [[NSString alloc] initWithFormat:@"%@\u200B%@", [cleanFirstName substringToIndex:1], [cleanLastName substringToIndex:1]];
}
else if (cleanFirstName.length != 0)
{
_label.text = [cleanFirstName substringToIndex:1];
}
else if (cleanLastName.length != 0)
{
_label.text = [cleanLastName substringToIndex:1];
}
else
_label.text = @" ";
_label.textColor = [UIColor whiteColor];
[_label sizeToFit];
[self setNeedsLayout];
NSString *placeholderUri = [[NSString alloc] initWithFormat:@"placeholder://?type=user-avatar&w=%d&h=%d&uid=%" PRId32 "", (int)size.width, (int)size.height, (int32_t)uid];
if (!TGStringCompare([self currentUrl], placeholderUri))
[super loadImage:placeholderUri filter:nil placeholder:placeholder];
_label.hidden = false;
}
typedef struct
{
int top;
int bottom;
} TGGradientColors;
- (void)loadGroupPlaceholderWithSize:(CGSize)size conversationId:(int64_t)conversationId title:(NSString *)title placeholder:(UIImage *)placeholder
{
_label.font = _singleFont;
_usingSingleFont = true;
NSString *cleanTitle = [self _cleanedUpString:title];
_label.text = cleanTitle.length >= 1 ? [cleanTitle substringToIndex:1] : @" ";
if (conversationId == 0)
_label.textColor = [UIColor whiteColor];
else
_label.textColor = [UIColor whiteColor];
[_label sizeToFit];
CGSize labelSize = _label.frame.size;
CGSize boundsSize = self.bounds.size;
labelSize.height = boundsSize.height;
_label.frame = CGRectMake(TGRetinaFloor((boundsSize.width - labelSize.width) / 2.0f), CGFloor((boundsSize.height - labelSize.height) / 2.0f), labelSize.width, labelSize.height);
[super loadImage:[[NSString alloc] initWithFormat:@"placeholder://?type=group-avatar&w=%d&h=%d&cid=%" PRId64 "", (int)size.width, (int)size.height, conversationId] filter:nil placeholder:placeholder];
_label.hidden = false;
}
- (void)layoutSubviews
{
[super layoutSubviews];
CGSize labelSize = _label.frame.size;
CGSize boundsSize = self.bounds.size;
labelSize.height = boundsSize.height;
_label.frame = CGRectMake(TGScreenPixelFloor((boundsSize.width - labelSize.width) / 2.0f), TGScreenPixelFloor((boundsSize.height - labelSize.height) / 2.0f), labelSize.width, labelSize.height);
}
@end

View File

@@ -246,7 +246,6 @@
pickerController = [[TGMediaAssetsPickerController alloc] initWithContext:strongController->_context assetsLibrary:strongController.assetsLibrary assetGroup:group intent:intent selectionContext:inhibitSelection ? nil : strongController->_selectionContext editingContext:strongController->_editingContext saveEditedPhotos:strongController->_saveEditedPhotos];
pickerController.pallete = strongController.pallete;
}
pickerController.suggestionContext = strongController.suggestionContext;
pickerController.stickersContext = strongController.stickersContext;
pickerController.localMediaCacheEnabled = strongController.localMediaCacheEnabled;
pickerController.captionsEnabled = strongController.captionsEnabled;
@@ -286,12 +285,6 @@
return assetsController;
}
- (void)setSuggestionContext:(TGSuggestionContext *)suggestionContext
{
_suggestionContext = suggestionContext;
self.pickerController.suggestionContext = suggestionContext;
}
- (void)setStickersContext:(id<TGPhotoPaintStickersContext>)stickersContext
{
_stickersContext = stickersContext;

View File

@@ -149,6 +149,18 @@
NSUInteger index = [self.selectionContext indexOfItem:(id<TGMediaSelectableItem>)cell.item];
[cell.checkButton setNumber:index];
}
NSString *title;
if (self.selectionContext.count > 0) {
title = [legacyEffectiveLocalization() getPluralized:@"Attachment.SelectedMedia" count:(int32_t)self.selectionContext.count];
} else {
if (_intent == TGMediaAssetsControllerSendMediaIntent) {
title = TGLocalized(@"Attachment.Gallery");
} else {
title = _assetGroup.title;
}
}
[self setTitle:title];
}
- (void)viewDidLoad
@@ -343,9 +355,9 @@
};
}
- (TGMediaPickerModernGalleryMixin *)_galleryMixinForContext:(id<LegacyComponentsContext>)context item:(id)item thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities inhibitDocumentCaptions:(bool)inhibitDocumentCaptions asFile:(bool)asFile
- (TGMediaPickerModernGalleryMixin *)_galleryMixinForContext:(id<LegacyComponentsContext>)context item:(id)item thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities inhibitDocumentCaptions:(bool)inhibitDocumentCaptions asFile:(bool)asFile
{
return [[TGMediaPickerModernGalleryMixin alloc] initWithContext:context item:item fetchResult:_fetchResult parentController:self thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext suggestionContext:suggestionContext hasCaptions:hasCaptions allowCaptionEntities:allowCaptionEntities hasTimer:self.hasTimer onlyCrop:self.onlyCrop inhibitDocumentCaptions:inhibitDocumentCaptions inhibitMute:self.inhibitMute asFile:asFile itemsLimit:0 recipientName:self.recipientName hasSilentPosting:self.hasSilentPosting hasSchedule:self.hasSchedule reminder:self.reminder stickersContext:self.stickersContext];
return [[TGMediaPickerModernGalleryMixin alloc] initWithContext:context item:item fetchResult:_fetchResult parentController:self thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext hasCaptions:hasCaptions allowCaptionEntities:allowCaptionEntities hasTimer:self.hasTimer onlyCrop:self.onlyCrop inhibitDocumentCaptions:inhibitDocumentCaptions inhibitMute:self.inhibitMute asFile:asFile itemsLimit:0 recipientName:self.recipientName hasSilentPosting:self.hasSilentPosting hasSchedule:self.hasSchedule reminder:self.reminder stickersContext:self.stickersContext];
}
- (TGMediaPickerModernGalleryMixin *)galleryMixinForIndexPath:(NSIndexPath *)indexPath previewMode:(bool)previewMode outAsset:(TGMediaAsset **)outAsset
@@ -362,7 +374,7 @@
bool asFile = (_intent == TGMediaAssetsControllerSendFileIntent);
TGMediaPickerModernGalleryMixin *mixin = [self _galleryMixinForContext:_context item:asset thumbnailImage:thumbnailImage selectionContext:self.selectionContext editingContext:self.editingContext suggestionContext:self.suggestionContext hasCaptions:self.captionsEnabled allowCaptionEntities:self.allowCaptionEntities inhibitDocumentCaptions:self.inhibitDocumentCaptions asFile:asFile];
TGMediaPickerModernGalleryMixin *mixin = [self _galleryMixinForContext:_context item:asset thumbnailImage:thumbnailImage selectionContext:self.selectionContext editingContext:self.editingContext hasCaptions:self.captionsEnabled allowCaptionEntities:self.allowCaptionEntities inhibitDocumentCaptions:self.inhibitDocumentCaptions asFile:asFile];
mixin.presentScheduleController = self.presentScheduleController;
mixin.presentTimerController = self.presentTimerController;
__weak TGMediaAssetsPickerController *weakSelf = self;

View File

@@ -4,7 +4,6 @@
@interface TGMediaGroupsController : TGViewController
@property (nonatomic, strong) TGSuggestionContext *suggestionContext;
@property (nonatomic, assign) bool localMediaCacheEnabled;
@property (nonatomic, assign) bool liveVideoUploadEnabled;
@property (nonatomic, assign) bool captionsEnabled;

View File

@@ -1,7 +0,0 @@
#import "TGMediaPickerGalleryItem.h"
#import "TGModernGallerySelectableItem.h"
#import "TGModernGalleryEditableItem.h"
@interface TGMediaPickerGalleryGifItem : TGMediaPickerGalleryItem <TGModernGallerySelectableItem, TGModernGalleryEditableItem>
@end

View File

@@ -1,37 +0,0 @@
#import "TGMediaPickerGalleryGifItem.h"
#import "TGMediaPickerGalleryGifItemView.h"
#import "TGMediaAsset+TGMediaEditableItem.h"
@implementation TGMediaPickerGalleryGifItem
@synthesize selectionContext;
@synthesize editingContext;
@synthesize stickersContext;
- (NSString *)uniqueId
{
return self.asset.uniqueIdentifier;
}
- (id<TGMediaSelectableItem>)selectableMediaItem
{
return self.asset;
}
- (id<TGMediaEditableItem>)editableMediaItem
{
return self.asset;
}
- (TGPhotoEditorTab)toolbarTabs
{
return TGPhotoEditorNoneTab;
}
- (Class)viewClass
{
return [TGMediaPickerGalleryGifItemView class];
}
@end

View File

@@ -1,8 +0,0 @@
#import <LegacyComponents/TGModernGalleryItemView.h>
#import "TGModernGalleryImageItemImageView.h"
@interface TGMediaPickerGalleryGifItemView : TGModernGalleryItemView
@property (nonatomic, strong) TGModernGalleryImageItemImageView *imageView;
@end

View File

@@ -1,284 +0,0 @@
#import "TGMediaPickerGalleryGifItemView.h"
#import "LegacyComponentsInternal.h"
#import "TGFont.h"
#import "TGStringUtils.h"
#import "TGMediaPickerGalleryGifItem.h"
#import <LegacyComponents/TGPhotoEditorUtils.h>
#import "TGModernAnimatedImagePlayer.h"
#import <LegacyComponents/TGMessageImageViewOverlayView.h>
#import <LegacyComponents/TGMediaAssetImageSignals.h>
#import <LegacyComponents/TGMediaSelectionContext.h>
@interface TGMediaPickerGalleryGifItemView ()
{
UIView *_containerView;
CGSize _imageSize;
UITapGestureRecognizer *_tapGestureRecognizer;
SMetaDisposable *_gifDataDisposable;
TGModernAnimatedImagePlayer *_player;
TGMessageImageViewOverlayView *_progressView;
bool _progressVisible;
void (^_currentAvailabilityObserver)(bool);
UILabel *_fileInfoLabel;
SMetaDisposable *_attributesDisposable;
bool _imageAvailable;
}
@end
@implementation TGMediaPickerGalleryGifItemView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self != nil)
{
_containerView = [[UIView alloc] initWithFrame:self.bounds];
_containerView.clipsToBounds = true;
[self addSubview:_containerView];
_imageView = [[TGModernGalleryImageItemImageView alloc] init];
[_containerView addSubview:_imageView];
_fileInfoLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 20)];
_fileInfoLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
_fileInfoLabel.backgroundColor = [UIColor clearColor];
_fileInfoLabel.font = TGSystemFontOfSize(13.0f);
_fileInfoLabel.textAlignment = NSTextAlignmentCenter;
_fileInfoLabel.textColor = [UIColor whiteColor];
_tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap)];
[_containerView addGestureRecognizer:_tapGestureRecognizer];
_gifDataDisposable = [[SMetaDisposable alloc] init];
}
return self;
}
- (void)dealloc
{
[_gifDataDisposable dispose];
[_attributesDisposable dispose];
}
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
if (_containerView == nil)
return;
_containerView.frame = self.bounds;
[self _layoutPlayerView];
}
- (void)prepareForRecycle
{
[_imageView reset];
[_player stop];
_player = nil;
_imageAvailable = false;
[self setProgressVisible:false value:0.0f animated:false];
}
- (void)setItem:(TGMediaPickerGalleryGifItem *)item synchronously:(bool)synchronously
{
[super setItem:item synchronously:synchronously];
_imageSize = item.asset.originalSize;
[self _layoutPlayerView];
if (item.asset == nil)
{
[self.imageView reset];
}
else
{
SSignal *imageSignal = [TGMediaAssetImageSignals imageForAsset:(TGMediaAsset *)item.asset imageType:(item.immediateThumbnailImage != nil) ? TGMediaAssetImageTypeScreen : TGMediaAssetImageTypeFastScreen size:CGSizeMake(1280, 1280)];
if (item.immediateThumbnailImage != nil)
imageSignal = [[SSignal single:item.immediateThumbnailImage] then:imageSignal];
[self.imageView setSignal:imageSignal];
__weak TGMediaPickerGalleryGifItemView *weakSelf = self;
[_gifDataDisposable setDisposable:[[TGMediaAssetImageSignals imageDataForAsset:(TGMediaAsset *)item.asset] startWithNext:^(id next)
{
__strong TGMediaPickerGalleryGifItemView *strongSelf = weakSelf;
if (strongSelf == nil)
return;
if ([next isKindOfClass:[NSNumber class]])
{
float value = [next floatValue];
[strongSelf setProgressVisible:value < 1.0f - FLT_EPSILON value:value animated:true];
}
else if ([next isKindOfClass:[TGMediaAssetImageData class]])
{
[strongSelf setProgressVisible:false value:1.0f animated:true];
TGMediaAssetImageData *data = (TGMediaAssetImageData *)next;
[strongSelf _playWithData:data.imageData];
strongSelf->_imageAvailable = true;
if (strongSelf->_currentAvailabilityObserver != nil)
strongSelf->_currentAvailabilityObserver(true);
}
}]];
}
if (!item.asFile)
return;
_fileInfoLabel.text = nil;
if (_attributesDisposable == nil)
_attributesDisposable = [[SMetaDisposable alloc] init];
__weak TGMediaPickerGalleryGifItemView *weakSelf = self;
[_attributesDisposable setDisposable:[[[TGMediaAssetImageSignals fileAttributesForAsset:(TGMediaAsset *)item.asset] deliverOn:[SQueue mainQueue]] startWithNext:^(TGMediaAssetImageFileAttributes *next)
{
__strong TGMediaPickerGalleryGifItemView *strongSelf = weakSelf;
if (strongSelf == nil)
return;
NSString *extension = @"GIF";
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];
}]];
}
- (void)_playWithData:(NSData *)data
{
[self.imageView setSignal:nil];
_player = [[TGModernAnimatedImagePlayer alloc] initWithSize:_imageSize data:data];
__weak TGMediaPickerGalleryGifItemView *weakSelf = self;
_player.frameReady = ^(UIImage *image)
{
__strong TGMediaPickerGalleryGifItemView *strongSelf = weakSelf;
if (strongSelf != nil)
[strongSelf->_imageView loadUri:@"embedded-image://" withOptions:@{TGImageViewOptionEmbeddedImage: image}];
};
[_player play];
}
- (void)singleTap
{
if ([self.item conformsToProtocol:@protocol(TGModernGallerySelectableItem)])
{
TGMediaSelectionContext *selectionContext = ((id<TGModernGallerySelectableItem>)self.item).selectionContext;
id<TGMediaSelectableItem> item = ((id<TGModernGallerySelectableItem>)self.item).selectableMediaItem;
[selectionContext toggleItemSelection:item animated:true sender:nil success:nil];
}
else
{
id<TGModernGalleryItemViewDelegate> delegate = self.delegate;
if ([delegate respondsToSelector:@selector(itemViewDidRequestInterfaceShowHide:)])
[delegate itemViewDidRequestInterfaceShowHide:self];
}
}
- (void)setProgressVisible:(bool)progressVisible value:(CGFloat)value animated:(bool)animated
{
_progressVisible = progressVisible;
if (progressVisible && _progressView == nil)
{
_progressView = [[TGMessageImageViewOverlayView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 50.0f, 50.0f)];
_progressView.userInteractionEnabled = false;
_progressView.frame = (CGRect){{CGFloor((self.frame.size.width - _progressView.frame.size.width) / 2.0f), CGFloor((self.frame.size.height - _progressView.frame.size.height) / 2.0f)}, _progressView.frame.size};
}
if (progressVisible)
{
if (_progressView.superview == nil)
[_containerView addSubview:_progressView];
_progressView.alpha = 1.0f;
}
else if (_progressView.superview != nil)
{
if (animated)
{
[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^
{
_progressView.alpha = 0.0f;
} completion:^(BOOL finished)
{
if (finished)
[_progressView removeFromSuperview];
}];
}
else
[_progressView removeFromSuperview];
}
[_progressView setProgress:value cancelEnabled:false animated:animated];
}
- (SSignal *)contentAvailabilityStateSignal
{
__weak TGMediaPickerGalleryGifItemView *weakSelf = self;
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
{
__strong TGMediaPickerGalleryGifItemView *strongSelf = weakSelf;
if (strongSelf != nil)
{
[subscriber putNext:@(strongSelf->_imageAvailable)];
strongSelf->_currentAvailabilityObserver = ^(bool available)
{
[subscriber putNext:@(available)];
};
}
return nil;
}];
}
- (UIView *)footerView
{
if (((TGMediaPickerGalleryItem *)self.item).asFile)
return _fileInfoLabel;
return nil;
}
- (void)_layoutPlayerView
{
if (CGSizeEqualToSize(_imageSize, CGSizeZero))
return;
CGSize fittedSize = TGScaleToSize(_imageSize, self.frame.size);
_imageView.frame = CGRectMake((self.frame.size.width - fittedSize.width) / 2.0f, (self.frame.size.height - fittedSize.height) / 2.0f, fittedSize.width, fittedSize.height);
}
- (UIView *)transitionView
{
return _containerView;
}
- (CGRect)transitionViewContentRect
{
return [_imageView convertRect:_imageView.bounds toView:[self transitionView]];
}
@end

View File

@@ -427,11 +427,6 @@
_captionMixin.allowEntities = allowCaptionEntities;
}
- (void)setSuggestionContext:(TGSuggestionContext *)suggestionContext
{
_captionMixin.suggestionContext = suggestionContext;
}
- (void)setClosePressed:(void (^)())closePressed
{
_closePressed = [closePressed copy];

View File

@@ -11,6 +11,7 @@
#import "TGModernGalleryEditableItemView.h"
#import "TGMediaPickerGalleryItem.h"
#import <LegacyComponents/TGModernGalleryZoomableItemView.h>
#import "TGMediaPickerGalleryVideoItem.h"
#import "TGMediaPickerGalleryVideoItemView.h"
#import "TGModernMediaListItem.h"
@@ -100,12 +101,6 @@
return self;
}
- (void)setSuggestionContext:(TGSuggestionContext *)suggestionContext
{
_suggestionContext = suggestionContext;
[_interfaceView setSuggestionContext:suggestionContext];
}
- (NSInteger)selectionCount
{
if (self.externalSelectionCount != nil)
@@ -185,7 +180,6 @@
{
__weak TGMediaPickerGalleryModel *weakSelf = self;
_interfaceView = [[TGMediaPickerGalleryInterfaceView alloc] initWithContext:_context focusItem:_initialFocusItem selectionContext:_selectionContext editingContext:_editingContext stickersContext:_stickersContext hasSelectionPanel:_hasSelectionPanel hasCameraButton:_hasCamera recipientName:_recipientName];
[_interfaceView setSuggestionContext:_suggestionContext];
_interfaceView.hasCaptions = _hasCaptions;
_interfaceView.allowCaptionEntities = _allowCaptionEntities;
_interfaceView.hasTimer = _hasTimer;
@@ -410,7 +404,6 @@
controller.editingContext = _editingContext;
controller.stickersContext = _stickersContext;
self.editorController = controller;
controller.suggestionContext = self.suggestionContext;
controller.willFinishEditing = ^(id<TGMediaEditAdjustments> adjustments, id temporaryRep, bool hasChanges)
{
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;

View File

@@ -16,6 +16,8 @@
#import <LegacyComponents/TGMediaSelectionContext.h>
#import <LegacyComponents/PGPhotoEditorValues.h>
#import <LegacyComponents/TGMediaPickerGalleryVideoItem.h>
#import "TGMediaPickerGalleryPhotoItem.h"
#import "TGPhotoEntitiesContainerView.h"
@@ -27,6 +29,7 @@
@interface TGMediaPickerGalleryPhotoItemView ()
{
TGMediaPickerGalleryFetchResultItem *_fetchItem;
SMetaDisposable *_facesDisposable;
UILabel *_fileInfoLabel;
@@ -123,8 +126,21 @@
[self setProgressVisible:false value:0.0f animated:false];
}
- (id<TGModernGalleryItem>)item {
if (_fetchItem != nil) {
return _fetchItem;
} else {
return _item;
}
}
- (void)setItem:(TGMediaPickerGalleryPhotoItem *)item synchronously:(bool)synchronously
{
if ([item isKindOfClass:[TGMediaPickerGalleryFetchResultItem class]]) {
_fetchItem = (TGMediaPickerGalleryFetchResultItem *)item;
item = (TGMediaPickerGalleryPhotoItem *)[_fetchItem backingItem];
}
[super setItem:item synchronously:synchronously];
_entitiesContainerView.stickersContext = item.stickersContext;

View File

@@ -2,8 +2,13 @@
#import "LegacyComponentsInternal.h"
#import "TGMediaPickerGalleryPhotoItem.h"
#import "TGMediaPickerGalleryPhotoItemView.h"
#import "TGMediaPickerGalleryVideoItemView.h"
#import <LegacyComponents/TGMediaAssetFetchResult.h>
#import "TGMediaAsset+TGMediaEditableItem.h"
#import "TGCameraCapturedVideo.h"
#import <LegacyComponents/AVURLAsset+TGMediaItem.h>
@@ -100,3 +105,107 @@
}
@end
@implementation TGMediaPickerGalleryFetchResultItem
{
TGMediaPickerGalleryItem<TGModernGallerySelectableItem, TGModernGalleryEditableItem> *_backingItem;
TGMediaAssetFetchResult *_fetchResult;
NSUInteger _index;
}
@synthesize selectionContext;
@synthesize editingContext;
@synthesize stickersContext;
- (instancetype)initWithFetchResult:(TGMediaAssetFetchResult *)fetchResult index:(NSUInteger)index {
self = [super init];
if (self != nil) {
_fetchResult = fetchResult;
_index = index;
}
return self;
}
- (TGMediaPickerGalleryItem<TGModernGallerySelectableItem, TGModernGalleryEditableItem> *)backingItem {
if (_backingItem == nil) {
TGMediaAsset *asset = [_fetchResult assetAtIndex:_index];
TGMediaPickerGalleryItem<TGModernGallerySelectableItem, TGModernGalleryEditableItem> *backingItem = nil;
switch (asset.type)
{
case TGMediaAssetVideoType:
{
backingItem = [[TGMediaPickerGalleryVideoItem alloc] initWithAsset:(id<TGMediaEditableItem,TGMediaSelectableItem>)asset];
}
break;
case TGMediaAssetGifType:
{
TGCameraCapturedVideo *convertedAsset = [[TGCameraCapturedVideo alloc] initWithAsset:asset livePhoto:false];
backingItem = [[TGMediaPickerGalleryVideoItem alloc] initWithAsset:convertedAsset];
}
break;
default:
{
backingItem = [[TGMediaPickerGalleryPhotoItem alloc] initWithAsset:(id<TGMediaEditableItem,TGMediaSelectableItem>)asset];
}
break;
}
backingItem.selectionContext = self.selectionContext;
backingItem.editingContext = self.editingContext;
backingItem.stickersContext = self.stickersContext;
backingItem.asFile = self.asFile;
_backingItem = backingItem;
}
return _backingItem;
}
- (TGMediaAsset *)asset {
return self.backingItem.asset;
}
- (NSString *)uniqueId
{
if (self.asset != nil)
return self.asset.uniqueIdentifier;
return nil;
}
- (id<TGMediaSelectableItem>)selectableMediaItem
{
if (self.asset != nil)
return self.asset;
return nil;
}
- (id<TGMediaEditableItem>)editableMediaItem
{
if (self.asset != nil)
return self.asset;
return nil;
}
- (TGPhotoEditorTab)toolbarTabs
{
return self.backingItem.toolbarTabs;
}
- (Class)viewClass
{
return self.backingItem.viewClass;
}
- (BOOL)isEqual:(id)object
{
return [object isKindOfClass:[TGMediaPickerGalleryFetchResultItem class]] && (self.backingItem != nil && TGObjectCompare(self.backingItem, ((TGMediaPickerGalleryFetchResultItem *)object).backingItem));
}
@end

View File

@@ -45,6 +45,8 @@
@interface TGMediaPickerGalleryVideoItemView() <TGMediaPickerGalleryVideoScrubberDataSource, TGMediaPickerGalleryVideoScrubberDelegate>
{
TGMediaPickerGalleryFetchResultItem *_fetchItem;
UIView *_containerView;
TGModernGalleryVideoContentView *_videoContentView;
UIView *_playerWrapperView;
@@ -385,6 +387,11 @@
- (void)setItem:(TGMediaPickerGalleryVideoItem *)item synchronously:(bool)synchronously
{
if ([item isKindOfClass:[TGMediaPickerGalleryFetchResultItem class]]) {
_fetchItem = (TGMediaPickerGalleryFetchResultItem *)item;
item = (TGMediaPickerGalleryVideoItem *)[_fetchItem backingItem];
}
bool itemChanged = ![item isEqual:self.item];
bool itemIdChanged = item.uniqueId != self.item.uniqueId;

View File

@@ -9,13 +9,11 @@
#import "TGMediaPickerGalleryPhotoItem.h"
#import "TGMediaPickerGalleryVideoItem.h"
#import "TGMediaPickerGalleryVideoItemView.h"
#import "TGMediaPickerGalleryGifItem.h"
#import "TGMediaPickerSendActionSheetController.h"
#import <LegacyComponents/TGMediaEditingContext.h>
#import <LegacyComponents/TGMediaSelectionContext.h>
#import <LegacyComponents/TGSuggestionContext.h>
#import <LegacyComponents/TGMediaAsset.h>
#import <LegacyComponents/TGMediaAssetFetchResult.h>
@@ -42,17 +40,17 @@
@implementation TGMediaPickerModernGalleryMixin
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item fetchResult:(TGMediaAssetFetchResult *)fetchResult parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions inhibitMute:(bool)inhibitMute asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit recipientName:(NSString *)recipientName hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item fetchResult:(TGMediaAssetFetchResult *)fetchResult parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions inhibitMute:(bool)inhibitMute asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit recipientName:(NSString *)recipientName hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext
{
return [self initWithContext:context item:item fetchResult:fetchResult momentList:nil parentController:parentController thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext suggestionContext:suggestionContext hasCaptions:hasCaptions allowCaptionEntities:allowCaptionEntities hasTimer:hasTimer onlyCrop:onlyCrop inhibitDocumentCaptions:inhibitDocumentCaptions inhibitMute:inhibitMute asFile:asFile itemsLimit:itemsLimit recipientName:recipientName hasSilentPosting:hasSilentPosting hasSchedule:hasSchedule reminder:reminder stickersContext:stickersContext];
return [self initWithContext:context item:item fetchResult:fetchResult momentList:nil parentController:parentController thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext hasCaptions:hasCaptions allowCaptionEntities:allowCaptionEntities hasTimer:hasTimer onlyCrop:onlyCrop inhibitDocumentCaptions:inhibitDocumentCaptions inhibitMute:inhibitMute asFile:asFile itemsLimit:itemsLimit recipientName:recipientName hasSilentPosting:hasSilentPosting hasSchedule:hasSchedule reminder:reminder stickersContext:stickersContext];
}
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item momentList:(TGMediaAssetMomentList *)momentList parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions inhibitMute:(bool)inhibitMute asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item momentList:(TGMediaAssetMomentList *)momentList parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions inhibitMute:(bool)inhibitMute asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext
{
return [self initWithContext:context item:item fetchResult:nil momentList:momentList parentController:parentController thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext suggestionContext:suggestionContext hasCaptions:hasCaptions allowCaptionEntities:allowCaptionEntities hasTimer:hasTimer onlyCrop:onlyCrop inhibitDocumentCaptions:inhibitDocumentCaptions inhibitMute:inhibitMute asFile:asFile itemsLimit:itemsLimit recipientName:nil hasSilentPosting:hasSilentPosting hasSchedule:hasSchedule reminder:reminder stickersContext:stickersContext];
return [self initWithContext:context item:item fetchResult:nil momentList:momentList parentController:parentController thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext hasCaptions:hasCaptions allowCaptionEntities:allowCaptionEntities hasTimer:hasTimer onlyCrop:onlyCrop inhibitDocumentCaptions:inhibitDocumentCaptions inhibitMute:inhibitMute asFile:asFile itemsLimit:itemsLimit recipientName:nil hasSilentPosting:hasSilentPosting hasSchedule:hasSchedule reminder:reminder stickersContext:stickersContext];
}
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item fetchResult:(TGMediaAssetFetchResult *)fetchResult momentList:(TGMediaAssetMomentList *)momentList parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions inhibitMute:(bool)inhibitMute asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit recipientName:(NSString *)recipientName hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item fetchResult:(TGMediaAssetFetchResult *)fetchResult momentList:(TGMediaAssetMomentList *)momentList parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions inhibitMute:(bool)inhibitMute asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit recipientName:(NSString *)recipientName hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext
{
self = [super init];
if (self != nil)
@@ -91,7 +89,6 @@
model.stickersContext = stickersContext;
model.inhibitMute = inhibitMute;
model.controller = modernGallery;
model.suggestionContext = suggestionContext;
model.willFinishEditingItem = ^(id<TGMediaEditableItem> editableItem, id<TGMediaEditAdjustments> adjustments, id representation, bool hasChanges)
{
__strong TGMediaPickerModernGalleryMixin *strongSelf = weakSelf;
@@ -363,34 +360,32 @@
for (NSUInteger i = 0; i < count; i++)
{
TGMediaAsset *asset = [fetchResult assetAtIndex:i];
TGMediaPickerGalleryItem<TGModernGallerySelectableItem, TGModernGalleryEditableItem> *galleryItem = nil;
switch (asset.type)
{
case TGMediaAssetVideoType:
{
galleryItem = [[TGMediaPickerGalleryVideoItem alloc] initWithAsset:(id<TGMediaEditableItem,TGMediaSelectableItem>)asset];
}
break;
case TGMediaAssetGifType:
{
TGCameraCapturedVideo *convertedAsset = [[TGCameraCapturedVideo alloc] initWithAsset:asset livePhoto:false];
galleryItem = [[TGMediaPickerGalleryVideoItem alloc] initWithAsset:convertedAsset];
}
break;
default:
{
// if (asset.subtypes & TGMediaAssetSubtypePhotoLive)
// galleryItem = [[TGMediaPickerGalleryVideoItem alloc] initWithAsset:asset];
// else
galleryItem = [[TGMediaPickerGalleryPhotoItem alloc] initWithAsset:(id<TGMediaEditableItem,TGMediaSelectableItem>)asset];
}
break;
}
// TGMediaAsset *asset = [fetchResult assetAtIndex:i];
//
// TGMediaPickerGalleryItem<TGModernGallerySelectableItem, TGModernGalleryEditableItem> *galleryItem = nil;
// switch (asset.type)
// {
// case TGMediaAssetVideoType:
// {
// galleryItem = [[TGMediaPickerGalleryVideoItem alloc] initWithAsset:(id<TGMediaEditableItem,TGMediaSelectableItem>)asset];
// }
// break;
//
// case TGMediaAssetGifType:
// {
// TGCameraCapturedVideo *convertedAsset = [[TGCameraCapturedVideo alloc] initWithAsset:asset livePhoto:false];
// galleryItem = [[TGMediaPickerGalleryVideoItem alloc] initWithAsset:convertedAsset];
// }
// break;
//
// default:
// {
// galleryItem = [[TGMediaPickerGalleryPhotoItem alloc] initWithAsset:(id<TGMediaEditableItem,TGMediaSelectableItem>)asset];
// }
// break;
// }
TGMediaPickerGalleryFetchResultItem *galleryItem = [[TGMediaPickerGalleryFetchResultItem alloc] initWithFetchResult:fetchResult index:i];
galleryItem.selectionContext = selectionContext;
galleryItem.editingContext = editingContext;
galleryItem.stickersContext = stickersContext;

View File

@@ -4,7 +4,6 @@
#import <LegacyComponents/TGObserverProxy.h>
#import "TGSuggestionContext.h"
#import "TGPhotoPaintStickersContext.h"
@interface TGPhotoCaptionInputMixin ()

View File

@@ -129,7 +129,6 @@
TGMediaPickerGalleryModel *model = [[TGMediaPickerGalleryModel alloc] initWithContext:windowContext items:@[galleryItem] focusItem:galleryItem selectionContext:nil editingContext:editingContext hasCaptions:true allowCaptionEntities:true hasTimer:false onlyCrop:false inhibitDocumentCaptions:false hasSelectionPanel:false hasCamera:false recipientName:recipientName];
model.controller = galleryController;
model.stickersContext = stickersContext;
//model.suggestionContext = self.suggestionContext;
model.willFinishEditingItem = ^(id<TGMediaEditableItem> editableItem, id<TGMediaEditAdjustments> adjustments, id representation, bool hasChanges)
{

View File

@@ -1,517 +0,0 @@
#import "TGRemoteImageView.h"
#import <QuartzCore/QuartzCore.h>
#import "TGCache.h"
#import <LegacyComponents/SGraphObjectNode.h>
#import <LegacyComponents/TGImageManager.h>
static TGCache *sharedCache = nil;
@interface TGRemoteImageView ()
@property (atomic, strong) NSString *path;
@property (atomic, strong) NSString *currentCacheUrl;
@property (nonatomic, strong) UIImageView *placeholderView;
@end
@implementation TGRemoteImageView
+ (NSMutableDictionary *)imageProcessors
{
static NSMutableDictionary *dictionary = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
{
dictionary = [[NSMutableDictionary alloc] init];
});
return dictionary;
}
+ (NSMutableDictionary *)universalImageProcessors
{
static NSMutableDictionary *dictionary = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
{
dictionary = [[NSMutableDictionary alloc] init];
});
return dictionary;
}
+ (void)throttleDownProcessing
{
}
+ (void)registerImageUniversalProcessor:(TGImageUniversalProcessor)universalProcessor withBaseName:(NSString *)baseName
{
[[TGRemoteImageView universalImageProcessors] setObject:[universalProcessor copy] forKey:baseName];
}
+ (void)registerImageProcessor:(TGImageProcessor)imageProcessor withName:(NSString *)name
{
[[TGRemoteImageView imageProcessors] setObject:[imageProcessor copy] forKey:name];
}
+ (TGImageProcessor)imageProcessorForName:(NSString *)name
{
TGImageProcessor processor = [[TGRemoteImageView imageProcessors] objectForKey:name];
if (processor != nil)
return processor;
NSRange range = [name rangeOfString:@":"];
if (range.location != NSNotFound)
{
NSString *baseName = [name substringToIndex:range.location];
TGImageUniversalProcessor universalProcessor = [[TGRemoteImageView universalImageProcessors] objectForKey:baseName];
if (universalProcessor != nil)
{
return ^UIImage *(UIImage *source)
{
return universalProcessor(name, source);
};
}
}
return nil;
}
+ (void)setSharedCache:(TGCache *)cache
{
sharedCache = cache;
}
+ (TGCache *)sharedCache
{
return sharedCache;
}
#pragma mark - Implementation
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
_actionHandle = [[ASHandle alloc] initWithDelegate:self releaseOnMainThread:true];
_fadeTransitionDuration = 0.14;
_useCache = true;
}
return self;
}
- (void)dealloc
{
[_actionHandle reset];
[self cancelLoading];
}
- (void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
{
self.userInteractionEnabled = true;
[super addGestureRecognizer:gestureRecognizer];
}
- (void)setFadeTransition:(bool)fadeTransition
{
if (fadeTransition != _fadeTransition)
{
if (fadeTransition && _placeholderView == nil)
{
_placeholderView = [[UIImageView alloc] init];
_placeholderView.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
_placeholderView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[_placeholderView setContentMode:self.contentMode];
[self addSubview:_placeholderView];
}
else if (!fadeTransition && _placeholderView != nil)
{
[_placeholderView removeFromSuperview];
_placeholderView = nil;
}
_fadeTransition = fadeTransition;
}
}
- (void)setContentMode:(UIViewContentMode)contentMode
{
if (_placeholderView != nil)
[_placeholderView setContentMode:contentMode];
[super setContentMode:contentMode];
}
- (void)setPlaceholderOverlay:(UIView *)placeholderOverlay
{
if (_placeholderOverlay != nil)
{
[_placeholderOverlay removeFromSuperview];
_placeholderOverlay = nil;
}
_placeholderOverlay = placeholderOverlay;
[_placeholderView addSubview:placeholderOverlay];
}
- (void)prepareForRecycle
{
[self cancelLoading];
self.image = nil;
if (_placeholderOverlay != nil)
{
[_placeholderOverlay removeFromSuperview];
_placeholderOverlay = nil;
}
}
- (void)prepareForReuse
{
[self cancelLoading];
self.image = nil;
}
- (UIImage *)currentImage
{
return self.image;
}
- (UIImage *)currentPlaceholderImage
{
return _placeholderView.image;
}
- (void)tryFillCache:(NSMutableDictionary *)dict
{
if (_currentUrl == nil)
return;
UIImage *currentImage = [self currentImage];
if (currentImage != nil)
{
NSString *key = _currentFilter == nil ? _currentUrl : [[NSString alloc] initWithFormat:@"{filter:%@}%@", _currentFilter, _currentUrl];
if (key != nil)
[dict setObject:currentImage forKey:key];
}
}
- (void)loadImage:(UIImage *)image
{
[self cancelLoading];
self.image = image;
if (_placeholderView != nil)
{
[_placeholderView.layer removeAllAnimations];
_placeholderView.image = nil;
_placeholderView.hidden = true;
_placeholderView.alpha = 0.0f;
}
}
- (void)loadImage:(NSString *)url filter:(NSString *)filter placeholder:(UIImage *)placeholder
{
[self loadImage:url filter:filter placeholder:placeholder forceFade:false];
}
- (void)loadImage:(NSString *)url filter:(NSString *)filter placeholder:(UIImage *)placeholder forceFade:(bool)forceFade
{
[self cancelLoading];
self.currentUrl = url;
self.currentFilter = filter;
TGCache *cache = _cache != nil ? _cache : [TGRemoteImageView sharedCache];
NSString *trimmedUrl = url;
NSArray *components = [trimmedUrl componentsSeparatedByString:@"_"];
if (components.count >= 5)
trimmedUrl = [NSString stringWithFormat:@"%@_%@_%@_%@", components[0], components[1], components[2], components[3]];
NSString *cacheUrl = filter == nil ? trimmedUrl : [[NSString alloc] initWithFormat:@"{filter:%@}%@", filter, trimmedUrl];
self.currentCacheUrl = cacheUrl;
UIImage *image = [cache cachedImage:cacheUrl availability:TGCacheMemory];
if (image == nil)
image = [[TGImageManager instance] loadImageSyncWithUri:url canWait:false decode:true acceptPartialData:false asyncTaskId:NULL progress:nil partialCompletion:nil completion:nil];
if (image == nil && (_contentHints & TGRemoteImageContentHintLoadFromDiskSynchronously))
{
UIImage *managerImage = [[TGImageManager instance] loadImageSyncWithUri:url canWait:true decode:filter == nil acceptPartialData:false asyncTaskId:NULL progress:nil partialCompletion:nil completion:nil];
if (managerImage == nil)
managerImage = [cache cachedImage:url availability:TGCacheDisk];
if (managerImage != nil)
{
if (filter != nil)
{
TGImageProcessor procesor = [TGRemoteImageView imageProcessorForName:filter];
if (procesor != nil)
image = procesor(managerImage);
}
else
image = managerImage;
}
}
if (image != nil)
{
if (_contentHints & TGRemoteImageContentHintSaveToGallery)
{
[ActionStageInstance() requestActor:[[NSString alloc] initWithFormat:@"/tg/checkImageStored/(%lu)", (unsigned long)[url hash]] options:[[NSDictionary alloc] initWithObjectsAndKeys:url, @"url", nil] watcher:self];
}
if (forceFade)
{
self.image = image;
if (_placeholderView != nil)
{
[_placeholderView.layer removeAllAnimations];
UIView *placeholderView = _placeholderView;
_placeholderView.alpha = 1.0f;
_placeholderView.hidden = false;
if (placeholder != nil)
_placeholderView.image = placeholder;
[UIView animateWithDuration:_fadeTransitionDuration animations:^{
placeholderView.alpha = 0.0f;
} completion:^(BOOL finished)
{
if (finished)
placeholderView.hidden = true;
}];
}
}
else
{
self.image = image;
if (_placeholderView != nil)
{
[_placeholderView.layer removeAllAnimations];
_placeholderView.image = nil;
_placeholderView.hidden = true;
_placeholderView.alpha = 0.0f;
}
}
if (_progressHandler)
_progressHandler(self, 1.0f);
}
else
{
if (_allowThumbnailCache)
{
UIImage *thumbnail = [cache cachedThumbnail:cacheUrl];
if (thumbnail != nil)
placeholder = thumbnail;
}
if (_placeholderView != nil)
{
self.image = nil;
[_placeholderView.layer removeAllAnimations];
_placeholderView.image = placeholder;
_placeholderView.hidden = false;
_placeholderView.alpha = 1.0f;
}
else
{
self.image = placeholder;
}
if (filter != nil)
self.path = [NSString stringWithFormat:@"/img/({filter:%@}%@)", filter, url];
else
self.path = [NSString stringWithFormat:@"/img/(%@)", url];
NSMutableDictionary *options = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithInt:_cancelTimeout], @"cancelTimeout", cache, @"cache", [NSNumber numberWithBool:_useCache], @"useCache", [NSNumber numberWithBool:_allowThumbnailCache], @"allowThumbnailCache", [[NSNumber alloc] initWithInt:_contentHints], @"contentHints", nil];
if (_userProperties != nil)
[options setObject:_userProperties forKey:@"userProperties"];
if (_contentHints & TGRemoteImageContentHintBlurRemote)
options[@"blurIfRemote"] = @(true);
[ActionStageInstance() requestActor:self.path options:options watcher:self];
}
}
- (void)loadPlaceholder:(UIImage *)placeholder
{
if (!_placeholderView.hidden)
_placeholderView.image = placeholder;
}
- (void)cancelLoading
{
if (self.path != nil)
{
ASHandle *actionHandle = _actionHandle;
NSString *path = self.path;
[ActionStageInstance() dispatchOnStageQueue:^
{
[ActionStageInstance() removeWatcherByHandle:actionHandle fromPath:path];
}];
self.image = nil;
if (_placeholderView != nil)
{
[_placeholderView.layer removeAllAnimations];
}
self.path = nil;
}
self.currentUrl = nil;
self.currentFilter = nil;
}
+ (UIImage *)imageFromCache:(NSString *)url filter:(NSString *)filter cache:(TGCache *)cache
{
TGCache *usingCache = cache != nil ? cache : [TGRemoteImageView sharedCache];
UIImage *image = nil;
if (filter == nil)
image = [usingCache cachedImage:url availability:TGCacheMemory];
else
image = [usingCache cachedImage:[[NSString alloc] initWithFormat:@"{filter:%@}%@", filter, url] availability:TGCacheMemory];
return image;
}
+ (NSString *)preloadImage:(NSString *)url filter:(NSString *)filter blurIfRemote:(bool)blurIfRemote cache:(TGCache *)cache allowThumbnailCache:(bool)allowThumbnailCache watcher:(id<ASWatcher>)watcher
{
TGCache *usingCache = cache != nil ? cache : [TGRemoteImageView sharedCache];
UIImage *image = nil;
if (filter == nil)
image = [usingCache cachedImage:url availability:TGCacheMemory];
else
image = [usingCache cachedImage:[[NSString alloc] initWithFormat:@"{filter:%@}%@", filter, url] availability:TGCacheMemory];
if (image == nil)
{
NSString *path = nil;
if (filter != nil)
path = [NSString stringWithFormat:@"/img/({filter:%@}%@)", filter, url];
else
path = [NSString stringWithFormat:@"/img/(%@)", url];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:0], @"cancelTimeout", usingCache, @"cache", [NSNumber numberWithBool:allowThumbnailCache], @"forceMemoryCache", @(TG_CACHE_INPLACE), @"allowThumbnailCache", @(blurIfRemote), @"blurIfRemote", nil];
[ActionStageInstance() requestActor:path options:options watcher:watcher];
return path;
}
return nil;
}
- (void)actorMessageReceived:(NSString *)path messageType:(NSString *)messageType message:(id)message
{
if ([messageType isEqualToString:@"progress"])
{
dispatch_async(dispatch_get_main_queue(), ^
{
if (_progressHandler == nil)
return;
if (self.path != nil && [path isEqualToString:self.path])
{
if (_progressHandler)
_progressHandler(self, [message floatValue]);
}
});
}
}
- (void)actorReportedProgress:(NSString *)path progress:(float)progress
{
dispatch_async(dispatch_get_main_queue(), ^
{
if (_progressHandler == nil)
return;
if (self.path != nil && [path isEqualToString:self.path])
{
if (_progressHandler)
_progressHandler(self, progress);
}
});
}
- (void)actorCompleted:(int)resultCode path:(NSString *)path result:(id)result
{
dispatch_async(dispatch_get_main_queue(), ^
{
if (self.path != nil && [path isEqualToString:self.path])
{
if (resultCode == ASStatusSuccess && result != nil)
{
if (_contentHints & TGRemoteImageContentHintSaveToGallery)
{
[ActionStageInstance() requestActor:[[NSString alloc] initWithFormat:@"/tg/checkImageStored/(%lu)", (unsigned long)[self.currentUrl hash]] options:[[NSDictionary alloc] initWithObjectsAndKeys:self.currentUrl, @"url", nil] watcher:self];
}
UIImage *image = ((SGraphObjectNode *)result).object;
if (image != nil)
{
#if TG_CACHE_INPLACE
if (_useCache)
{
TGCache *cache = _cache != nil ? _cache : [TGRemoteImageView sharedCache];
[cache cacheImage:image withData:nil url:self.currentCacheUrl availability:TGCacheMemory];
}
#endif
self.image = image;
if (_placeholderView != nil)
{
//[_placeholderView.layer removeAllAnimations];
if (_fadeTransitionDuration < FLT_EPSILON)
{
_placeholderView.alpha = 0.0f;
_placeholderView.hidden = true;
}
else
{
UIView *placeholderView = _placeholderView;
[UIView animateWithDuration:_fadeTransitionDuration animations:^
{
placeholderView.alpha = 0.0f;
} completion:^(BOOL finished)
{
if (finished)
placeholderView.hidden = true;
}];
}
}
}
}
else
{
self.currentUrl = nil;
self.currentFilter = nil;
}
if (_progressHandler)
_progressHandler(self, 1.0f);
self.path = nil;
}
/*else if (self.path != nil && ![path isEqualToString:self.path])
{
TGLegacyLog(@"Received wrong path: <<<%@>>> vs <<<%@>>>", self.path, path);
}*/
});
}
@end

View File

@@ -1,5 +0,0 @@
#import "TGSuggestionContext.h"
@implementation TGSuggestionContext
@end

View File

@@ -1,470 +0,0 @@
#import "TGUser.h"
#import "LegacyComponentsInternal.h"
#import "TGStringUtils.h"
#import "TGPhoneUtils.h"
#import "NSObject+TGLock.h"
#import "PSKeyValueCoder.h"
#import "TGConversation.h"
#import "TGMediaOriginInfo.h"
#import "TGImageInfo.h"
typedef enum {
TGUserFlagVerified = (1 << 0),
TGUserFlagHasExplicitContent = (1 << 1),
TGUserFlagIsContextBot = (1 << 2),
TGUserFlagMinimalRepresentation = (1 << 3),
TGUserFlagBotInlineGeo = (1 << 4)
} TGUserFlags;
@interface TGUser ()
{
bool _contactIdInitialized;
bool _formattedPhoneInitialized;
TG_SYNCHRONIZED_DEFINE(_cachedValues);
}
@property (nonatomic, strong) NSString *cachedFormattedNumber;
@end
@implementation TGUser
- (instancetype)init {
self = [super init];
if (self != nil) {
TG_SYNCHRONIZED_INIT(_cachedValues);
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder
{
self = [super init];
if (self != nil)
{
TG_SYNCHRONIZED_INIT(_cachedValues);
_kind = [coder decodeInt32ForCKey:"k"];
if (_kind == TGUserKindBot || _kind == TGUserKindSmartBot)
{
_botInfoVersion = [coder decodeInt32ForCKey:"biv"];
_botKind = [coder decodeInt32ForCKey:"bk"];
}
_flags = [coder decodeInt32ForCKey:"f"];
_restrictionReason = [coder decodeStringForCKey:"rr"];
if ([self isContextBot]) {
_contextBotPlaceholder = [coder decodeStringForCKey:"cbp"];
}
_about = [coder decodeStringForCKey:"a"];
_photoFileReferenceSmall = [coder decodeDataCorCKey:"frs"];
_photoFileReferenceBig = [coder decodeDataCorCKey:"frb"];
}
return self;
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder
{
[coder encodeInt32:_kind forCKey:"k"];
if (_kind == TGUserKindBot || _kind == TGUserKindSmartBot)
{
[coder encodeInt32:_botInfoVersion forCKey:"biv"];
[coder encodeInt32:_botKind forCKey:"bk"];
}
[coder encodeInt32:_flags forCKey:"f"];
[coder encodeString:_restrictionReason forCKey:"rr"];
if ([self isContextBot]) {
[coder encodeString:_contextBotPlaceholder forCKey:"cbp"];
}
[coder encodeString:_about forCKey:"a"];
[coder encodeData:_photoFileReferenceSmall forCKey:"frs"];
[coder encodeData:_photoFileReferenceBig forCKey:"frb"];
}
- (id)copyWithZone:(NSZone *)__unused zone
{
TGUser *user = [[TGUser alloc] init];
user.uid = _uid;
user.phoneNumber = _phoneNumber;
user.phoneNumberHash = _phoneNumberHash;
user.firstName = _firstName;
user.lastName = _lastName;
user.userName = _userName;
user.phonebookFirstName = _phonebookFirstName;
user.phonebookLastName = _phonebookLastName;
user.sex = _sex;
user.photoUrlSmall = _photoUrlSmall;
user.photoUrlMedium = _photoUrlMedium;
user.photoUrlBig = _photoUrlBig;
user.photoFileReferenceSmall = _photoFileReferenceSmall;
user.photoFileReferenceBig = _photoFileReferenceBig;
user.presence = _presence;
user.customProperties = _customProperties;
user.contactId = _contactId;
user->_contactIdInitialized = _contactIdInitialized;
user->_formattedPhoneInitialized = _formattedPhoneInitialized;
user.cachedFormattedNumber = _cachedFormattedNumber;
user->_kind = _kind;
user->_botInfoVersion = _botInfoVersion;
user->_botKind = _botKind;
user->_flags = _flags;
user->_restrictionReason = _restrictionReason;
user->_contextBotPlaceholder = _contextBotPlaceholder;
return user;
}
- (bool)hasAnyName
{
return _firstName.length != 0 || _lastName.length != 0 || _phonebookFirstName.length != 0 || _phonebookLastName.length != 0;
}
- (bool)isBot {
return _kind == TGUserKindBot || _kind == TGUserKindSmartBot;
}
- (bool)isDeleted {
return (_phonebookFirstName.length != 0 || _phonebookLastName.length != 0) ? false : ((_firstName.length != 0 || _lastName.length != 0) ? false : (_phoneNumber.length == 0 ? true : false));
}
- (NSString *)firstName
{
return (_phonebookFirstName.length != 0 || _phonebookLastName.length != 0) ? _phonebookFirstName : ((_firstName.length != 0 || _lastName.length != 0) ? _firstName : (_phoneNumber.length == 0 ? TGLocalized(@"User.DeletedAccount") : [self formattedPhoneNumber]));
}
- (NSString *)lastName
{
return (_phonebookFirstName.length != 0 || _phonebookLastName.length != 0) ? _phonebookLastName : ((_firstName.length != 0 || _lastName.length != 0) ? _lastName : nil);
}
- (NSString *)realFirstName
{
return _firstName;
}
- (NSString *)realLastName
{
return _lastName;
}
- (NSString *)displayName
{
NSString *firstName = self.firstName;
NSString *lastName = self.lastName;
if (firstName != nil && firstName.length != 0 && lastName != nil && lastName.length != 0)
{
if (TGIsKorean())
return [[NSString alloc] initWithFormat:@"%@ %@", lastName, firstName];
else
return [[NSString alloc] initWithFormat:@"%@ %@", firstName, lastName];
}
else if (firstName != nil && firstName.length != 0)
return firstName;
else if (lastName != nil && lastName.length != 0)
return lastName;
return @"";
}
- (NSString *)displayRealName
{
NSString *firstName = self.realFirstName;
NSString *lastName = self.realLastName;
if (firstName != nil && firstName.length != 0 && lastName != nil && lastName.length != 0)
return [[NSString alloc] initWithFormat:@"%@ %@", firstName, lastName];
else if (firstName != nil && firstName.length != 0)
return firstName;
else if (lastName != nil && lastName.length != 0)
return lastName;
return @"";
}
- (NSString *)displayFirstName
{
NSString *firstName = self.firstName;
if (firstName.length != 0)
return firstName;
return self.lastName;
}
- (NSString *)compactName
{
NSString *firstName = self.firstName;
NSString *lastName = self.lastName;
if (firstName != nil && firstName.length != 0 && lastName != nil && lastName.length != 0)
return [[NSString alloc] initWithFormat:@"%@.%@", [firstName substringToIndex:1], lastName];
else if (firstName != nil && firstName.length != 0)
return firstName;
else if (lastName != nil && lastName.length != 0)
return lastName;
return @"";
}
- (void)setPhoneNumber:(NSString *)phoneNumber
{
TG_SYNCHRONIZED_BEGIN(_cachedValues);
_phoneNumber = phoneNumber;
_contactIdInitialized = false;
_formattedPhoneInitialized = false;
TG_SYNCHRONIZED_END(_cachedValues);
}
- (int)contactId
{
if (!_contactIdInitialized)
{
int contactId = 0;
if (_phoneNumber != nil && _phoneNumber.length != 0)
contactId = phoneMatchHash(_phoneNumber);
TG_SYNCHRONIZED_BEGIN(_cachedValues);
_contactId = contactId;
_contactIdInitialized = true;
TG_SYNCHRONIZED_END(_cachedValues);
}
return _contactId;
}
- (NSString *)formattedPhoneNumber
{
if (_formattedPhoneInitialized)
return _cachedFormattedNumber;
else
{
NSString *cachedFormattedNumber = nil;
if (_phoneNumber.length != 0)
cachedFormattedNumber = [TGPhoneUtils formatPhone:_phoneNumber forceInternational:true];
TG_SYNCHRONIZED_BEGIN(_cachedValues);
_cachedFormattedNumber = cachedFormattedNumber;
_formattedPhoneInitialized = true;
TG_SYNCHRONIZED_END(_cachedValues);
return cachedFormattedNumber;
}
}
- (BOOL)isEqual:(id)object
{
return [object isKindOfClass:[TGUser class]] && [self isEqualToUser:object];
}
- (bool)isEqualToUser:(TGUser *)anotherUser
{
if (anotherUser.uid == _uid &&
((anotherUser.realFirstName == nil && _firstName == nil) || [anotherUser.realFirstName isEqualToString:_firstName]) &&
((anotherUser.realLastName == nil && _lastName == nil) || [anotherUser.realLastName isEqualToString:_lastName]) &&
anotherUser.sex == _sex &&
((anotherUser.phonebookFirstName == nil && _phonebookFirstName == nil) || [anotherUser.phonebookFirstName isEqualToString:_phonebookFirstName]) &&
((anotherUser.phonebookLastName == nil && _phonebookLastName == nil) || [anotherUser.phonebookLastName isEqualToString:_phonebookLastName]) &&
((anotherUser.phoneNumber == nil && _phoneNumber == nil) || [anotherUser.phoneNumber isEqualToString:_phoneNumber]) &&
anotherUser.phoneNumberHash == _phoneNumberHash &&
((anotherUser.photoUrlSmall == nil && _photoUrlSmall == nil) || [anotherUser.photoUrlSmall isEqualToString:_photoUrlSmall]) &&
((anotherUser.photoUrlMedium == nil && _photoUrlMedium == nil) || [anotherUser.photoUrlMedium isEqualToString:_photoUrlMedium]) &&
((anotherUser.photoUrlBig == nil && _photoUrlBig == nil) || [anotherUser.photoUrlBig isEqualToString:_photoUrlBig]) && TGObjectCompare(anotherUser.photoFileReferenceSmall, _photoFileReferenceSmall) && TGObjectCompare(anotherUser.photoFileReferenceBig, _photoFileReferenceBig) && anotherUser.presence.online == _presence.online && anotherUser.presence.lastSeen == _presence.lastSeen && TGStringCompare(_userName, anotherUser.userName) && anotherUser.kind == _kind && anotherUser.botKind == _botKind &&
TGStringCompare(_restrictionReason, anotherUser.restrictionReason))
{
return true;
}
return false;
}
- (int)differenceFromUser:(TGUser *)anotherUser
{
int difference = 0;
if (_uid != anotherUser.uid)
difference |= TGUserFieldUid;
if ((_phoneNumber == nil) != (anotherUser.phoneNumber == nil) || (_phoneNumber != nil && ![_phoneNumber isEqualToString:anotherUser.phoneNumber]))
difference |= TGUserFieldPhoneNumber;
if (_phoneNumberHash != anotherUser.phoneNumberHash)
difference |= TGUserFieldPhoneNumberHash;
if ((_firstName == nil) != (anotherUser.realFirstName == nil) || (_firstName != nil && ![_firstName isEqualToString:anotherUser.realFirstName]))
difference |= TGUserFieldFirstName;
if ((_lastName == nil) != (anotherUser.realLastName == nil) || (_lastName != nil && ![_lastName isEqualToString:anotherUser.realLastName]))
difference |= TGUserFieldLastName;
if (!TGStringCompare(_userName, anotherUser.userName))
difference |= TGUserFieldUsername;
if ((_phonebookFirstName == nil) != (anotherUser.phonebookFirstName == nil) || (_phonebookFirstName != nil && ![_phonebookFirstName isEqualToString:anotherUser.phonebookFirstName]))
difference |= TGUserFieldPhonebookFirstName;
if ((_phonebookLastName == nil) != (anotherUser.phonebookLastName == nil) || (_phonebookLastName != nil && ![_phonebookLastName isEqualToString:anotherUser.phonebookLastName]))
difference |= TGUserFieldPhonebookLastName;
if (_sex != anotherUser.sex)
difference |= TGUserFieldSex;
if ((_photoUrlSmall == nil) != (anotherUser.photoUrlSmall == nil) || (_photoUrlSmall != nil && ![_photoUrlSmall isEqualToString:anotherUser.photoUrlSmall]))
difference |= TGUserFieldPhotoUrlSmall;
if ((_photoUrlMedium == nil) != (anotherUser.photoUrlMedium == nil) || (_photoUrlMedium != nil && ![_photoUrlMedium isEqualToString:anotherUser.photoUrlMedium]))
difference |= TGUserFieldPhotoUrlMedium;
if ((_photoUrlBig == nil) != (anotherUser.photoUrlBig == nil) || (_photoUrlBig != nil && ![_photoUrlBig isEqualToString:anotherUser.photoUrlBig]))
difference |= TGUserFieldPhotoUrlBig;
if (_presence.lastSeen != anotherUser.presence.lastSeen)
difference |= TGUserFieldPresenceLastSeen;
if (_presence.online != anotherUser.presence.online)
difference |= TGUserFieldPresenceOnline;
if (anotherUser.kind != _kind)
difference |= TGUserFieldOther;
if (anotherUser.botKind != _botKind)
difference |= TGUserFieldOther;
if (anotherUser.flags != _flags) {
difference |= TGUserFieldOther;
}
if (!TGStringCompare(anotherUser.restrictionReason, _restrictionReason)) {
difference |= TGUserFieldOther;
}
if (!TGStringCompare(anotherUser.contextBotPlaceholder, _contextBotPlaceholder)) {
difference |= TGUserFieldOther;
}
return difference;
}
+ (TGUserPresence)approximatePresenceFromPresence:(TGUserPresence)presence currentTime:(NSTimeInterval)currentTime
{
if (presence.lastSeen <= 0)
return presence;
if (presence.lastSeen >= (int)(currentTime - 60 * 60 * 24 * 4))
return (TGUserPresence){.online = false, .lastSeen = TGUserPresenceValueLately, .temporaryLastSeen = 0};
else if (presence.lastSeen >= (int)(currentTime - 60 * 60 * 24 * 4))
return (TGUserPresence){.online = false, .lastSeen = TGUserPresenceValueWithinAWeek, .temporaryLastSeen = 0};
else if (presence.lastSeen >= (int)(currentTime - 60 * 60 * 24 * 31))
return (TGUserPresence){.online = false, .lastSeen = TGUserPresenceValueWithinAMonth, .temporaryLastSeen = 0};
return (TGUserPresence){.online = false, .lastSeen = TGUserPresenceValueALongTimeAgo, .temporaryLastSeen = 0};
}
- (bool)isVerified {
return _flags & TGUserFlagVerified;
}
- (void)setIsVerified:(bool)isVerified {
if (isVerified) {
_flags |= TGUserFlagVerified;
} else {
_flags &= ~TGUserFlagVerified;
}
}
- (bool)isContextBot {
return _flags & TGUserFlagIsContextBot;
}
- (void)setIsContextBot:(bool)isContextBot {
if (isContextBot) {
_flags |= TGUserFlagIsContextBot;
} else {
_flags &= ~TGUserFlagIsContextBot;
}
}
- (bool)hasExplicitContent {
return _flags & TGConversationFlagHasExplicitContent;
}
- (void)setHasExplicitContent:(bool)hasExplicitContent {
if (hasExplicitContent) {
_flags |= TGConversationFlagHasExplicitContent;
} else {
_flags &= ~TGConversationFlagHasExplicitContent;
}
}
- (bool)minimalRepresentation {
return _flags & TGUserFlagMinimalRepresentation;
}
- (void)setMinimalRepresentation:(bool)minimalRepresentation {
if (minimalRepresentation) {
_flags |= TGUserFlagMinimalRepresentation;
} else {
_flags &= ~TGUserFlagMinimalRepresentation;
}
}
- (bool)botInlineGeo {
return _flags & TGUserFlagBotInlineGeo;
}
- (void)setBotInlineGeo:(bool)botInlineGeo {
if (botInlineGeo) {
_flags |= TGUserFlagBotInlineGeo;
} else {
_flags &= ~TGUserFlagBotInlineGeo;
}
}
- (NSString *)photoFullUrlSmall
{
NSString *finalAvatarUrl = self.photoUrlSmall;
if (finalAvatarUrl.length == 0)
return finalAvatarUrl;
int64_t volumeId = 0;
int32_t localId = 0;
if (extractFileUrlComponents(self.photoUrlSmall, NULL, &volumeId, &localId, NULL))
{
NSString *key = [NSString stringWithFormat:@"%lld_%d", volumeId, localId];
NSDictionary *fileReferences = nil;
if (self.photoFileReferenceSmall != nil) {
fileReferences = @{ key: self.photoFileReferenceSmall };
}
TGMediaOriginInfo *originInfo = [TGMediaOriginInfo mediaOriginInfoWithFileReference:self.photoFileReferenceSmall fileReferences:fileReferences userId:_uid offset:0];
finalAvatarUrl = [finalAvatarUrl stringByAppendingFormat:@"_o%@", [originInfo stringRepresentation]];
}
return finalAvatarUrl;
}
- (NSString *)photoFullUrlBig
{
NSString *finalAvatarUrl = self.photoUrlBig;
if (finalAvatarUrl.length == 0)
return finalAvatarUrl;
int64_t volumeId = 0;
int32_t localId = 0;
if (extractFileUrlComponents(self.photoUrlBig, NULL, &volumeId, &localId, NULL))
{
NSString *key = [NSString stringWithFormat:@"%lld_%d", volumeId, localId];
NSDictionary *fileReferences = nil;
if (self.photoFileReferenceBig != nil) {
fileReferences = @{ key: self.photoFileReferenceBig };
}
TGMediaOriginInfo *originInfo = [TGMediaOriginInfo mediaOriginInfoWithFileReference:self.photoFileReferenceBig fileReferences:fileReferences userId:_uid offset:0];
finalAvatarUrl = [finalAvatarUrl stringByAppendingFormat:@"_o%@", [originInfo stringRepresentation]];
}
return finalAvatarUrl;
}
@end

View File

@@ -23,7 +23,6 @@ swift_library(
"//submodules/LocalMediaResources:LocalMediaResources",
"//submodules/SearchPeerMembers:SearchPeerMembers",
"//submodules/SaveToCameraRoll:SaveToCameraRoll",
"//submodules/LegacyMediaPickerUI/LegacyImageProcessors:LegacyImageProcessors",
"//submodules/AnimatedStickerNode:AnimatedStickerNode",
"//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
"//submodules/StickerResources:StickerResources",

View File

@@ -1,26 +0,0 @@
objc_library(
name = "LegacyImageProcessors",
enable_modules = True,
module_name = "LegacyImageProcessors",
srcs = glob([
"Sources/**/*.m",
"Sources/**/*.h",
]),
hdrs = glob([
"PublicHeaders/**/*.h",
]),
includes = [
"PublicHeaders",
],
deps = [
"//submodules/LegacyComponents:LegacyComponents",
],
sdk_frameworks = [
"Foundation",
"UIKit",
],
visibility = [
"//visibility:public",
],
)

View File

@@ -1,5 +0,0 @@
#import <Foundation/Foundation.h>
@interface LegacyImageProcessors : NSObject
@end

View File

@@ -1,56 +0,0 @@
#import <LegacyImageProcessors/LegacyImageProcessors.h>
#import <LegacyComponents/LegacyComponents.h>
@implementation LegacyImageProcessors
+ (void)load {
[TGRemoteImageView registerImageUniversalProcessor:^UIImage *(NSString *name, UIImage *source) {
CGSize size = CGSizeZero;
int n = 7;
bool invalid = false;
for (int i = n; i < (int)name.length; i++) {
unichar c = [name characterAtIndex:i];
if (c == 'x')
{
if (i == n)
invalid = true;
else
{
size.width = [[name substringWithRange:NSMakeRange(n, i - n)] intValue];
n = i + 1;
}
break;
}
else if (c < '0' || c > '9')
{
invalid = true;
break;
}
}
if (!invalid)
{
for (int i = n; i < (int)name.length; i++)
{
unichar c = [name characterAtIndex:i];
if (c < '0' || c > '9')
{
invalid = true;
break;
}
else if (i == (int)name.length - 1)
{
size.height = [[name substringFromIndex:n] intValue];
}
}
}
if (!invalid)
{
return TGScaleAndRoundCornersWithOffsetAndFlags(source, size, CGPointZero, size, (int)size.width / 2, nil, false, nil, TGScaleImageScaleSharper);
}
return nil;
} withBaseName:@"circle"];
}
@end

View File

@@ -187,7 +187,6 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, chatLocati
let carouselItem = TGAttachmentCarouselItemView(context: parentController.context, camera: PGCamera.cameraAvailable(), selfPortrait: false, forProfilePhoto: false, assetType: TGMediaAssetAnyType, saveEditedPhotos: !isSecretChat && saveEditedPhotos, allowGrouping: editMediaOptions == nil && allowGrouping, allowSelection: editMediaOptions == nil, allowEditing: true, document: false, selectionLimit: selectionLimit)!
carouselItemView = carouselItem
carouselItem.stickersContext = paintStickersContext
carouselItem.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id, chatLocation: chatLocation)
carouselItem.recipientName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
var openedCamera = false
controller.willDismiss = { [weak carouselItem] _ in
@@ -474,8 +473,6 @@ public func presentLegacyPasteMenu(context: AccountContext, peer: Peer, chatLoca
let recipientName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
legacyController.enableSizeClassSignal = true
let suggestionContext = legacySuggestionContext(context: context, peerId: peer.id, chatLocation: chatLocation)
let paintStickersContext = LegacyPaintStickersContext(context: context)
paintStickersContext.captionPanelView = {
@@ -489,7 +486,7 @@ public func presentLegacyPasteMenu(context: AccountContext, peer: Peer, chatLoca
})
}
let controller = TGClipboardMenu.present(inParentController: emptyController, context: legacyController.context, images: images, allowGrouping: allowGrouping, hasCaption: true, hasTimer: hasTimer, hasSilentPosting: hasSilentPosting, hasSchedule: hasSchedule, reminder: peer.id == context.account.peerId, recipientName: recipientName, suggestionContext: suggestionContext, stickersContext: paintStickersContext, presentScheduleController: { done in
let controller = TGClipboardMenu.present(inParentController: emptyController, context: legacyController.context, images: images, allowGrouping: allowGrouping, hasCaption: true, hasTimer: hasTimer, hasSilentPosting: hasSilentPosting, hasSchedule: hasSchedule, reminder: peer.id == context.account.peerId, recipientName: recipientName, stickersContext: paintStickersContext, presentScheduleController: { done in
presentSchedulePicker { time in
done?(time)
}

View File

@@ -36,7 +36,6 @@ public func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, co
controller.captionsEnabled = captionsEnabled
controller.inhibitDocumentCaptions = false
controller.stickersContext = paintStickersContext
controller.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id, chatLocation: chatLocation)
if peer.id != context.account.peerId {
if peer is TelegramUser {
controller.hasTimer = hasSchedule

View File

@@ -1,98 +0,0 @@
import Foundation
import UIKit
import TelegramCore
import Postbox
import SwiftSignalKit
import LegacyComponents
import LegacyUI
import SearchPeerMembers
import AccountContext
public func legacySuggestionContext(context: AccountContext, peerId: PeerId, chatLocation: ChatLocation) -> TGSuggestionContext {
let suggestionContext = TGSuggestionContext()
suggestionContext.userListSignal = { query in
return SSignal { subscriber in
if let query = query {
let disposable = searchPeerMembers(context: context, peerId: peerId, chatLocation: chatLocation, query: query, scope: .mention).start(next: { peers in
let users = NSMutableArray()
for peer in peers {
if case let .user(peer) = peer {
let user = TGUser()
user.uid = peer.id.id._internalGetInt64Value()
user.firstName = peer.firstName
user.lastName = peer.lastName
user.userName = peer.addressName
if let representation = smallestImageRepresentation(peer.photo) {
user.photoUrlSmall = legacyImageLocationUri(resource: representation.resource)
}
users.add(user)
}
}
subscriber.putNext(users)
subscriber.putCompletion()
})
return SBlockDisposable {
disposable.dispose()
}
} else {
subscriber.putNext(NSArray())
subscriber.putCompletion()
return nil
}
}
}
suggestionContext.hashtagListSignal = { query in
return SSignal { subscriber in
let disposable = (context.engine.messages.recentlyUsedHashtags() |> map { hashtags -> [String] in
let normalizedQuery = query?.lowercased()
var result: [String] = []
if let normalizedQuery = normalizedQuery {
for hashtag in hashtags {
if hashtag.lowercased().hasPrefix(normalizedQuery) {
result.append(hashtag)
}
}
}
return result
}
|> take(1)
|> deliverOnMainQueue).start(next: { hashtags in
subscriber.putNext(hashtags)
subscriber.putCompletion()
})
return SBlockDisposable {
disposable.dispose()
}
}
}
suggestionContext.alphacodeSignal = { query, inputLanguageCode in
guard let query = query, let inputLanguageCode = inputLanguageCode else {
return SSignal.complete()
}
return SSignal { subscriber in
let disposable = (context.engine.stickers.searchEmojiKeywords(inputLanguageCode: inputLanguageCode, query: query, completeMatch: query.count < 3)
|> map { keywords -> [TGAlphacodeEntry] in
var result: [TGAlphacodeEntry] = []
for keyword in keywords {
for emoticon in keyword.emoticons {
result.append(TGAlphacodeEntry(emoji: emoticon, code: keyword.keyword))
}
}
return result
}).start(next: { result in
subscriber.putNext(result)
subscriber.putCompletion()
}, error: nil, completed: {
subscriber.putCompletion()
})
return SBlockDisposable {
disposable.dispose()
}
}
}
return suggestionContext
}

View File

@@ -1,78 +0,0 @@
import Foundation
import UIKit
import LegacyComponents
import Postbox
import TelegramCore
import SwiftSignalKit
final class LegacyImageDownloadActor: ASActor {
private let disposable = MetaDisposable()
deinit {
self.disposable.dispose()
}
override static func genericPath() -> String! {
return "/img/@";
}
override func execute(_ options: [AnyHashable : Any]!) {
let actualPath = self.path as NSString
var url: String
var processor: TGImageProcessor?
var cacheUrl: String
if actualPath.hasPrefix("/img/({filter:") {
let range = actualPath.range(of: "}")
if range.location == NSNotFound {
ActionStageInstance().nodeRetrieveFailed(self.path)
return
}
let processorName = actualPath.substring(with: NSMakeRange(14, range.location - 14))
processor = TGRemoteImageView.imageProcessor(forName: processorName)
url = actualPath.substring(with: NSMakeRange(range.location + 1, actualPath.length - range.location - 1 - 1))
cacheUrl = "{filter:\(processorName)}\(url)"
}
else {
url = actualPath.substring(with: NSMakeRange(6, actualPath.length - 6 - 1))
cacheUrl = url
}
if url.hasPrefix("placeholder://") {
let path = self.path
let token = TGImageManager.instance().beginLoadingImageAsync(withUri: url, decode: true, progress: nil, partialCompletion: nil, completion: { image in
ActionStageInstance().actionCompleted(path, result: SGraphObjectNode(object: image))
})
let disposable = ActionDisposable {
TGImageManager.instance().cancelTask(withId: token)
}
self.disposable.set(disposable)
} else if let resource = resourceFromLegacyImageUri(url) {
let disposables = DisposableSet()
self.disposable.set(disposables)
if let account = legacyContextGet()?.account {
let path = self.path
disposables.add(account.postbox.mediaBox.resourceData(resource).start(next: { data in
if data.complete {
ActionStageInstance().globalStageDispatchQueue().async {
if let image = UIImage(contentsOfFile: data.path) {
var updatedImage: UIImage? = image
if let processor = processor {
updatedImage = processor(image)
}
TGRemoteImageView.sharedCache().cacheImage(updatedImage, with: nil, url: cacheUrl, availability: Int32(TGCacheMemory.rawValue))
ActionStageInstance().actionCompleted(path, result: SGraphObjectNode(object: updatedImage))
}
}
}
}))
disposables.add(account.postbox.mediaBox.fetchedResource(resource, parameters: nil).start())
}
}
}
override func cancel() {
self.disposable.dispose()
}
}

View File

@@ -1,47 +0,0 @@
import Foundation
import UIKit
import Postbox
import TelegramCore
public func legacyImageLocationUri(resource: MediaResource) -> String? {
if let resource = resource as? CloudPeerPhotoSizeMediaResource {
return resource.id.stringRepresentation
}
return nil
}
private let legacyImageUriExpr = try? NSRegularExpression(pattern: "telegram-peer-photo-size-([-\\d]+)-([-\\d]+)-([-\\d]+)-([-\\d]+)-([-\\d]+)", options: [])
public func resourceFromLegacyImageUri(_ uri: String) -> MediaResource? {
guard let legacyImageUriExpr = legacyImageUriExpr else {
return nil
}
let matches = legacyImageUriExpr.matches(in: uri, options: [], range: NSRange(location: 0, length: uri.count))
if let match = matches.first {
let nsString = uri as NSString
let datacenterId = nsString.substring(with: match.range(at: 1))
let photoId = nsString.substring(with: match.range(at: 2))
let size = nsString.substring(with: match.range(at: 3))
let volumeId = nsString.substring(with: match.range(at: 4))
let localId = nsString.substring(with: match.range(at: 5))
guard let nDatacenterId = Int32(datacenterId) else {
return nil
}
guard let nPhotoId = Int64(photoId) else {
return nil
}
guard let nSizeSpec = Int32(size), let sizeSpec = CloudPeerPhotoSizeSpec(rawValue: nSizeSpec) else {
return nil
}
guard let nVolumeId = Int64(volumeId) else {
return nil
}
guard let nLocalId = Int32(localId) else {
return nil
}
return CloudPeerPhotoSizeMediaResource(datacenterId: nDatacenterId, photoId: nPhotoId, sizeSpec: sizeSpec, volumeId: nVolumeId, localId: nLocalId)
}
return nil
}

View File

@@ -1,121 +0,0 @@
import Foundation
import UIKit
import LegacyComponents
import Postbox
import TelegramCore
import SwiftSignalKit
import Display
private let gradientColors: [NSArray] = [
[UIColor(rgb: 0xff516a).cgColor, UIColor(rgb: 0xff885e).cgColor],
[UIColor(rgb: 0xffa85c).cgColor, UIColor(rgb: 0xffcd6a).cgColor],
[UIColor(rgb: 0x54cb68).cgColor, UIColor(rgb: 0xa0de7e).cgColor],
[UIColor(rgb: 0x2a9ef1).cgColor, UIColor(rgb: 0x72d5fd).cgColor],
[UIColor(rgb: 0x665fff).cgColor, UIColor(rgb: 0x82b1ff).cgColor],
[UIColor(rgb: 0xd669ed).cgColor, UIColor(rgb: 0xe0a2f3).cgColor]
]
private let grayscaleColors: NSArray = [
UIColor(rgb: 0xefefef).cgColor, UIColor(rgb: 0xeeeeee).cgColor
]
private let sharedImageCache = TGMemoryImageCache(softMemoryLimit: 2 * 1024 * 1024, hardMemoryLimit: 3 * 1024 * 1024)!
final class LegacyPeerAvatarPlaceholderDataSource: TGImageDataSource {
private let account: () -> Account?
init(account: @escaping () -> Account?) {
self.account = account
super.init()
}
override func canHandleUri(_ uri: String!) -> Bool {
if let uri = uri {
if uri.hasPrefix("placeholder://") {
return true
}
}
return false
}
override func loadDataSync(withUri uri: String!, canWait: Bool, acceptPartialData: Bool, asyncTaskId: AutoreleasingUnsafeMutablePointer<AnyObject?>!, progress: ((Float) -> Void)!, partialCompletion: ((TGDataResource?) -> Void)!, completion: ((TGDataResource?) -> Void)!) -> TGDataResource! {
if let image = sharedImageCache.image(forKey: uri, attributes: nil) {
return TGDataResource(image: image, decoded: true)
}
return nil
}
override func loadDataAsync(withUri uri: String!, progress: ((Float) -> Void)!, partialCompletion: ((TGDataResource?) -> Void)!, completion: ((TGDataResource?) -> Void)!) -> Any! {
if let account = self.account() {
let signal: Signal<Never, NoError> = Signal { subscriber in
let args: [AnyHashable : Any]
let argumentsString = String(uri[uri.index(uri.startIndex, offsetBy: "placeholder://?".count)...])
args = TGStringUtils.argumentDictionary(inUrlString: argumentsString)!
guard let width = Int((args["w"] as! String)), width > 1 else {
return EmptyDisposable
}
guard let height = Int((args["h"] as! String)), height > 1 else {
return EmptyDisposable
}
var peerId = PeerId(0)
if let uid = args["uid"] as? String, let nUid = Int64(uid) {
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(nUid))
} else if let cid = args["cid"] as? String, let nCid = Int64(cid) {
peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(nCid))
}
let image = generateImage(CGSize(width: CGFloat(width), height: CGFloat(height)), rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
context.beginPath()
context.addEllipse(in: CGRect(x: 0.0, y: 0.0, width: size.width, height:
size.height))
context.clip()
let colorIndex: Int
if peerId.id._internalGetInt64Value() == 0 {
colorIndex = -1
} else {
colorIndex = abs(Int(clamping: account.peerId.id._internalGetInt64Value() &+ peerId.id._internalGetInt64Value()))
}
let colorsArray: NSArray
if colorIndex == -1 {
colorsArray = grayscaleColors
} else {
colorsArray = gradientColors[colorIndex % gradientColors.count]
}
var locations: [CGFloat] = [1.0, 0.2];
let colorSpace = CGColorSpaceCreateDeviceRGB()
let gradient = CGGradient(colorsSpace: colorSpace, colors: colorsArray, locations: &locations)!
context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions())
context.setBlendMode(.normal)
})
sharedImageCache.setImage(image, forKey: uri, attributes: nil)
completion?(TGDataResource(image: image, decoded: true))
subscriber.putCompletion()
return EmptyDisposable
}
return (signal |> runOn(Queue.concurrentDefaultQueue())).start()
} else {
return nil
}
}
override func cancelTask(byId taskId: Any!) {
if let disposable = taskId as? Disposable {
disposable.dispose()
}
}
}

View File

@@ -314,11 +314,5 @@ public func initializeLegacyComponents(application: UIApplication?, currentSizeC
freedomInit()
TGRemoteImageView.setSharedCache(TGCache())
TGImageDataSource.register(LegacyPeerAvatarPlaceholderDataSource(account: {
return legacyContext?.account
}))
ASActor.registerClass(LegacyImageDownloadActor.self)
LegacyComponentsGlobals.setProvider(LegacyComponentsGlobalsProviderImpl())
}

View File

@@ -81,7 +81,6 @@ func presentedLegacyCamera(context: AccountContext, peer: Peer, chatLocation: Ch
controller.allowCaptionEntities = true
controller.allowGrouping = mediaGrouping
controller.inhibitDocumentCaptions = false
controller.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id, chatLocation: chatLocation)
controller.recipientName = EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
if peer.id != context.account.peerId {
if peer is TelegramUser {

View File

@@ -6,6 +6,13 @@ import TelegramPresentationData
import LegacyUI
import PhoneNumberFormat
private func legacyImageLocationUri(resource: MediaResource) -> String? {
if let resource = resource as? CloudPeerPhotoSizeMediaResource {
return resource.id.stringRepresentation
}
return nil
}
func makePeerIdFromBridgeIdentifier(_ identifier: Int64) -> PeerId? {
if identifier < 0 && identifier > Int32.min {
return PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(-identifier))

View File

@@ -340,9 +340,6 @@ func presentLegacyWebSearchGallery(context: AccountContext, peer: EnginePeer?, c
let model = TGMediaPickerGalleryModel(context: legacyController.context, items: items, focus: focusItem, selectionContext: selectionContext, editingContext: editingContext, hasCaptions: false, allowCaptionEntities: true, hasTimer: false, onlyCrop: false, inhibitDocumentCaptions: false, hasSelectionPanel: false, hasCamera: false, recipientName: peer?.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder))!
model.stickersContext = paintStickersContext
if let peer = peer, let chatLocation = chatLocation {
model.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id, chatLocation: chatLocation)
}
controller.model = model
model.controller = controller
model.useGalleryImageAsEditableItemImage = true