diff --git a/LegacyComponents.xcodeproj/project.pbxproj b/LegacyComponents.xcodeproj/project.pbxproj index de6fa474bb..34c4cfc119 100644 --- a/LegacyComponents.xcodeproj/project.pbxproj +++ b/LegacyComponents.xcodeproj/project.pbxproj @@ -7,6 +7,15 @@ objects = { /* Begin PBXBuildFile section */ + 09750F761F2FA816001B9886 /* SSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09750F741F2FA5E8001B9886 /* SSignalKit.framework */; }; + 09750FB71F30DB0E001B9886 /* TGClipboardGalleryModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 09750FAF1F30DB0E001B9886 /* TGClipboardGalleryModel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 09750FB81F30DB0E001B9886 /* TGClipboardGalleryModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 09750FB01F30DB0E001B9886 /* TGClipboardGalleryModel.m */; }; + 09750FC11F30DCDC001B9886 /* TGClipboardGalleryPhotoItemView.h in Headers */ = {isa = PBXBuildFile; fileRef = 09750FBF1F30DCDC001B9886 /* TGClipboardGalleryPhotoItemView.h */; }; + 09750FC21F30DCDC001B9886 /* TGClipboardGalleryPhotoItemView.m in Sources */ = {isa = PBXBuildFile; fileRef = 09750FC01F30DCDC001B9886 /* TGClipboardGalleryPhotoItemView.m */; }; + 09750FC51F30DD52001B9886 /* TGClipboardGalleryPhotoItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 09750FC31F30DD52001B9886 /* TGClipboardGalleryPhotoItem.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 09750FC61F30DD52001B9886 /* TGClipboardGalleryPhotoItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 09750FC41F30DD52001B9886 /* TGClipboardGalleryPhotoItem.m */; }; + 09750FCD1F30E53A001B9886 /* TGClipboardGalleryMixin.h in Headers */ = {isa = PBXBuildFile; fileRef = 09750FCB1F30E53A001B9886 /* TGClipboardGalleryMixin.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 09750FCE1F30E53A001B9886 /* TGClipboardGalleryMixin.m in Sources */ = {isa = PBXBuildFile; fileRef = 09750FCC1F30E53A001B9886 /* TGClipboardGalleryMixin.m */; }; D017772C1F1F8F100044446D /* LegacyComponents.h in Headers */ = {isa = PBXBuildFile; fileRef = D017772A1F1F8F100044446D /* LegacyComponents.h */; settings = {ATTRIBUTES = (Public, ); }; }; D01777511F1F8FE60044446D /* LegacyComponentsGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777381F1F8FE60044446D /* LegacyComponentsGlobals.h */; settings = {ATTRIBUTES = (Public, ); }; }; D01777531F1F8FE60044446D /* PSCoding.h in Headers */ = {isa = PBXBuildFile; fileRef = D017773A1F1F8FE60044446D /* PSCoding.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -197,7 +206,6 @@ D01779001F20D0040044446D /* TGColor.m in Sources */ = {isa = PBXBuildFile; fileRef = D01778FE1F20D0040044446D /* TGColor.m */; }; D01779031F20D16B0044446D /* FreedomUIKit.h in Headers */ = {isa = PBXBuildFile; fileRef = D01779011F20D16B0044446D /* FreedomUIKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; D01779041F20D16B0044446D /* FreedomUIKit.m in Sources */ = {isa = PBXBuildFile; fileRef = D01779021F20D16B0044446D /* FreedomUIKit.m */; }; - D01779071F20E0DF0044446D /* SSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D01779061F20E0DF0044446D /* SSignalKit.framework */; }; D017790A1F20F3F90044446D /* TGImageBlur.h in Headers */ = {isa = PBXBuildFile; fileRef = D01779081F20F3F90044446D /* TGImageBlur.h */; settings = {ATTRIBUTES = (Public, ); }; }; D017790B1F20F3F90044446D /* TGImageBlur.m in Sources */ = {isa = PBXBuildFile; fileRef = D01779091F20F3F90044446D /* TGImageBlur.m */; }; D017790E1F20F4370044446D /* UIImage+TG.h in Headers */ = {isa = PBXBuildFile; fileRef = D017790C1F20F4370044446D /* UIImage+TG.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1069,6 +1077,15 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 09750F741F2FA5E8001B9886 /* SSignalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SSignalKit.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Telegraph-grvwvmixbmcefwboxkzfazvpcrxb/Build/Products/Release Hockeyapp-iphonesimulator/SSignalKit.framework"; sourceTree = ""; }; + 09750FAF1F30DB0E001B9886 /* TGClipboardGalleryModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGClipboardGalleryModel.h; sourceTree = ""; }; + 09750FB01F30DB0E001B9886 /* TGClipboardGalleryModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGClipboardGalleryModel.m; sourceTree = ""; }; + 09750FBF1F30DCDC001B9886 /* TGClipboardGalleryPhotoItemView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGClipboardGalleryPhotoItemView.h; sourceTree = ""; }; + 09750FC01F30DCDC001B9886 /* TGClipboardGalleryPhotoItemView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGClipboardGalleryPhotoItemView.m; sourceTree = ""; }; + 09750FC31F30DD52001B9886 /* TGClipboardGalleryPhotoItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGClipboardGalleryPhotoItem.h; sourceTree = ""; }; + 09750FC41F30DD52001B9886 /* TGClipboardGalleryPhotoItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGClipboardGalleryPhotoItem.m; sourceTree = ""; }; + 09750FCB1F30E53A001B9886 /* TGClipboardGalleryMixin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGClipboardGalleryMixin.h; sourceTree = ""; }; + 09750FCC1F30E53A001B9886 /* TGClipboardGalleryMixin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGClipboardGalleryMixin.m; sourceTree = ""; }; D01777271F1F8F100044446D /* LegacyComponents.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LegacyComponents.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D017772A1F1F8F100044446D /* LegacyComponents.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LegacyComponents.h; sourceTree = ""; }; D017772B1F1F8F100044446D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -1261,7 +1278,6 @@ D01778FE1F20D0040044446D /* TGColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGColor.m; sourceTree = ""; }; D01779011F20D16B0044446D /* FreedomUIKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FreedomUIKit.h; sourceTree = ""; }; D01779021F20D16B0044446D /* FreedomUIKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FreedomUIKit.m; sourceTree = ""; }; - D01779061F20E0DF0044446D /* SSignalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SSignalKit.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Telegraph-abpnqywbgzpiroddlkjvwntprzrz/Build/Products/Debug-iphonesimulator/SSignalKit.framework"; sourceTree = ""; }; D01779081F20F3F90044446D /* TGImageBlur.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGImageBlur.h; sourceTree = ""; }; D01779091F20F3F90044446D /* TGImageBlur.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGImageBlur.m; sourceTree = ""; }; D017790C1F20F4370044446D /* UIImage+TG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+TG.h"; sourceTree = ""; }; @@ -2137,13 +2153,28 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D01779071F20E0DF0044446D /* SSignalKit.framework in Frameworks */, + 09750F761F2FA816001B9886 /* SSignalKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 09750FAE1F30DAE1001B9886 /* Clipboard Menu */ = { + isa = PBXGroup; + children = ( + 09750FAF1F30DB0E001B9886 /* TGClipboardGalleryModel.h */, + 09750FB01F30DB0E001B9886 /* TGClipboardGalleryModel.m */, + 09750FBF1F30DCDC001B9886 /* TGClipboardGalleryPhotoItemView.h */, + 09750FC01F30DCDC001B9886 /* TGClipboardGalleryPhotoItemView.m */, + 09750FC31F30DD52001B9886 /* TGClipboardGalleryPhotoItem.h */, + 09750FC41F30DD52001B9886 /* TGClipboardGalleryPhotoItem.m */, + 09750FCB1F30E53A001B9886 /* TGClipboardGalleryMixin.h */, + 09750FCC1F30E53A001B9886 /* TGClipboardGalleryMixin.m */, + ); + name = "Clipboard Menu"; + sourceTree = ""; + }; D017771D1F1F8F100044446D = { isa = PBXGroup; children = ( @@ -2194,6 +2225,7 @@ D07BCB031F2B63D700ED97AA /* Passcode */, D07BCB2A1F2B65C400ED97AA /* Wallpapers */, D07BCB3F1F2B69D400ED97AA /* Embed Video */, + 09750FAE1F30DAE1001B9886 /* Clipboard Menu */, D017772A1F1F8F100044446D /* LegacyComponents.h */, D017772B1F1F8F100044446D /* Info.plist */, ); @@ -2518,7 +2550,7 @@ D01779051F20E0DE0044446D /* Frameworks */ = { isa = PBXGroup; children = ( - D01779061F20E0DF0044446D /* SSignalKit.framework */, + 09750F741F2FA5E8001B9886 /* SSignalKit.framework */, ); name = Frameworks; sourceTree = ""; @@ -3491,6 +3523,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 09750FCD1F30E53A001B9886 /* TGClipboardGalleryMixin.h in Headers */, + 09750FB71F30DB0E001B9886 /* TGClipboardGalleryModel.h in Headers */, D07BC9A61F2A49E300ED97AA /* TGItemPreviewView.h in Headers */, D07BC8A51F2A37A500ED97AA /* TGPhotoAvatarCropController.h in Headers */, D0177A001F2139980044446D /* POPLayerExtras.h in Headers */, @@ -3801,6 +3835,7 @@ D017783E1F1F961D0044446D /* TGDocumentAttributeImageSize.h in Headers */, D07BC8181F2A2C0B00ED97AA /* PGPhotoHistogram.h in Headers */, D07BC92F1F2A3BA600ED97AA /* TGPhotoEntitiesContainerView.h in Headers */, + 09750FC51F30DD52001B9886 /* TGClipboardGalleryPhotoItem.h in Headers */, D017780F1F1F961D0044446D /* TGMessageEntity.h in Headers */, D07BC9581F2A3EBF00ED97AA /* TGModernConversationAssociatedInputPanel.h in Headers */, D017795C1F2103440044446D /* PGPhotoEditorValues.h in Headers */, @@ -3959,6 +3994,7 @@ D07BC9011F2A380D00ED97AA /* TGPaintBrushPreview.h in Headers */, D0177AA71F22239A0044446D /* TGModernGalleryController.h in Headers */, D07BC99D1F2A494000ED97AA /* TGStickerCollectionViewCell.h in Headers */, + 09750FC11F30DCDC001B9886 /* TGClipboardGalleryPhotoItemView.h in Headers */, D07BC7BE1F2A2BDD00ED97AA /* PGPhotoToolComposer.h in Headers */, D07BC8141F2A2C0B00ED97AA /* PGPhotoFilterThumbnailManager.h in Headers */, D07BCB6A1F2B6A5600ED97AA /* TGEmbedSoundCloudPlayerView.h in Headers */, @@ -4223,6 +4259,7 @@ D07BCA061F2A9A2B00ED97AA /* TGMediaPickerGalleryVideoItem.m in Sources */, D07BCB1C1F2B646A00ED97AA /* TGPasscodePinDotView.m in Sources */, D01778411F1F961D0044446D /* TGDocumentAttributeSticker.m in Sources */, + 09750FCE1F30E53A001B9886 /* TGClipboardGalleryMixin.m in Sources */, D07BC6F81F2A19A700ED97AA /* TGCameraShutterButton.m in Sources */, D01779481F20FFF60044446D /* TGMediaAssetGroup.m in Sources */, D01779171F20F4500044446D /* TGStaticBackdropImageData.m in Sources */, @@ -4394,6 +4431,7 @@ D07BC6EE1F2A19A700ED97AA /* TGCameraFlashControl.m in Sources */, D017797C1F21075C0044446D /* TGModernCache.m in Sources */, D07BCBF21F2B72DC00ED97AA /* STKDataSourceWrapper.m in Sources */, + 09750FC61F30DD52001B9886 /* TGClipboardGalleryPhotoItem.m in Sources */, D017783D1F1F961D0044446D /* TGDocumentAttributeFilename.m in Sources */, D017796C1F2103DB0044446D /* TGPhotoPaintEntity.m in Sources */, D07BCBF41F2B72DC00ED97AA /* STKHTTPDataSource.m in Sources */, @@ -4509,6 +4547,7 @@ D0177AC61F23D92C0044446D /* ActionStage.mm in Sources */, D07BC78B1F2A2B3700ED97AA /* TGPhotoEditorTintToolView.m in Sources */, D07BC6FA1F2A19A700ED97AA /* TGCameraTimeCodeView.m in Sources */, + 09750FB81F30DB0E001B9886 /* TGClipboardGalleryModel.m in Sources */, D07BC8C41F2A37EC00ED97AA /* TGPhotoPaintController.m in Sources */, D07BC7A51F2A2B8900ED97AA /* GPUImageContext.m in Sources */, D07BC9081F2A380D00ED97AA /* TGPaintEllipticalBrush.m in Sources */, @@ -4554,6 +4593,7 @@ D017775F1F1F8FE60044446D /* TGBotComandInfo.m in Sources */, D01777FE1F1F961D0044446D /* TGMessageGroup.m in Sources */, D01778121F1F961D0044446D /* TGMessageEntityBold.m in Sources */, + 09750FC21F30DCDC001B9886 /* TGClipboardGalleryPhotoItemView.m in Sources */, D01779001F20D0040044446D /* TGColor.m in Sources */, D01778201F1F961D0044446D /* TGMessageEntityMentionName.m in Sources */, D07BCAAF1F2B45DA00ED97AA /* TGFileUtils.m in Sources */, @@ -4734,6 +4774,11 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)/../../thirdparty/SSignalKit", + "$(inherited)", + ); INFOPLIST_FILE = LegacyComponents/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 6.0; @@ -4756,6 +4801,11 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)/../../thirdparty/SSignalKit", + "$(inherited)", + ); INFOPLIST_FILE = LegacyComponents/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 6.0; @@ -4830,6 +4880,11 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)/../../thirdparty/SSignalKit", + "$(inherited)", + ); INFOPLIST_FILE = LegacyComponents/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 6.0; @@ -4898,6 +4953,11 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)/../../thirdparty/SSignalKit", + "$(inherited)", + ); INFOPLIST_FILE = LegacyComponents/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 6.0; @@ -4972,6 +5032,11 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)/../../thirdparty/SSignalKit", + "$(inherited)", + ); INFOPLIST_FILE = LegacyComponents/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 6.0; @@ -5040,6 +5105,11 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)/../../thirdparty/SSignalKit", + "$(inherited)", + ); INFOPLIST_FILE = LegacyComponents/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 6.0; diff --git a/LegacyComponents/LegacyComponents.h b/LegacyComponents/LegacyComponents.h index d1d030a2d0..53363466df 100644 --- a/LegacyComponents/LegacyComponents.h +++ b/LegacyComponents/LegacyComponents.h @@ -275,3 +275,6 @@ FOUNDATION_EXPORT const unsigned char LegacyComponentsVersionString[]; #import #import #import + +#import +#import diff --git a/LegacyComponents/TGClipboardGalleryMixin.h b/LegacyComponents/TGClipboardGalleryMixin.h new file mode 100644 index 0000000000..91029a936f --- /dev/null +++ b/LegacyComponents/TGClipboardGalleryMixin.h @@ -0,0 +1,26 @@ +#import +#import + +#import + +@class TGClipboardGalleryPhotoItem; + +@interface TGClipboardGalleryMixin : NSObject + +@property (nonatomic, copy) void (^itemFocused)(TGClipboardGalleryPhotoItem *); + +@property (nonatomic, copy) void (^willTransitionIn)(); +@property (nonatomic, copy) void (^willTransitionOut)(); +@property (nonatomic, copy) void (^didTransitionOut)(); +@property (nonatomic, copy) UIView *(^referenceViewForItem)(TGClipboardGalleryPhotoItem *); + +@property (nonatomic, copy) void (^completeWithItem)(TGClipboardGalleryPhotoItem *item); + +@property (nonatomic, copy) void (^editorOpened)(void); +@property (nonatomic, copy) void (^editorClosed)(void); + +- (instancetype)initWithContext:(id)context image:(UIImage *)image images:(NSArray *)images parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions hasTimer:(bool)hasTimer recipientName:(NSString *)recipientName; + +- (void)present; + +@end diff --git a/LegacyComponents/TGClipboardGalleryMixin.m b/LegacyComponents/TGClipboardGalleryMixin.m new file mode 100644 index 0000000000..50ec36f9d7 --- /dev/null +++ b/LegacyComponents/TGClipboardGalleryMixin.m @@ -0,0 +1,190 @@ +#import "TGClipboardGalleryMixin.h" + +#import + +#import +#import "TGClipboardGalleryPhotoItem.h" +#import "TGClipboardGalleryModel.h" + +#import +#import +#import + +#import +#import +#import +#import + +@interface TGClipboardGalleryMixin () +{ + TGMediaEditingContext *_editingContext; + bool _asFile; + + __weak TGViewController *_parentController; + __weak TGModernGalleryController *_galleryController; + TGModernGalleryController *_strongGalleryController; + + NSUInteger _itemsLimit; + + id _context; +} + +@property (nonatomic, weak, readonly) TGClipboardGalleryModel *galleryModel; + +@end + +@implementation TGClipboardGalleryMixin + +- (instancetype)initWithContext:(id)context image:(UIImage *)image images:(NSArray *)images parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions hasTimer:(bool)hasTimer recipientName:(NSString *)recipientName +{ + self = [super init]; + if (self != nil) + { + _context = context; + _parentController = parentController; + _editingContext = editingContext; + + __weak TGClipboardGalleryMixin *weakSelf = self; + + TGModernGalleryController *modernGallery = [[TGModernGalleryController alloc] initWithContext:_context]; + _galleryController = modernGallery; + _strongGalleryController = modernGallery; + modernGallery.isImportant = true; + + __block NSUInteger focusIndex = 0; + [images enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL * _Nonnull stop) + { + if (obj == image) + { + focusIndex = idx; + *stop = true; + } + }]; + + TGClipboardGalleryModel *model = [[TGClipboardGalleryModel alloc] initWithContext:_context images:images focusIndex:focusIndex selectionContext:selectionContext editingContext:editingContext hasCaptions:hasCaptions hasTimer:hasTimer hasSelectionPanel:false recipientName:recipientName]; + _galleryModel = model; + model.controller = modernGallery; + model.suggestionContext = suggestionContext; + model.willFinishEditingItem = ^(id editableItem, id adjustments, id representation, bool hasChanges) + { + __strong TGClipboardGalleryMixin *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + if (hasChanges) + { + [editingContext setAdjustments:adjustments forItem:editableItem]; + [editingContext setTemporaryRep:representation forItem:editableItem]; + } + + if (selectionContext != nil && adjustments != nil && [editableItem conformsToProtocol:@protocol(TGMediaSelectableItem)]) + [selectionContext setItem:(id)editableItem selected:true]; + }; + + model.didFinishEditingItem = ^(id editableItem, __unused id adjustments, UIImage *resultImage, UIImage *thumbnailImage) + { + [editingContext setImage:resultImage thumbnailImage:thumbnailImage forItem:editableItem synchronous:false]; + }; + + model.didFinishRenderingFullSizeImage = ^(id editableItem, UIImage *resultImage) + { + [editingContext setFullSizeImage:resultImage forItem:editableItem]; + }; + + model.saveItemCaption = ^(id editableItem, NSString *caption) + { + [editingContext setCaption:caption forItem:editableItem]; + + if (selectionContext != nil && caption.length > 0 && [editableItem conformsToProtocol:@protocol(TGMediaSelectableItem)]) + [selectionContext setItem:(id)editableItem selected:true]; + }; + + [model.interfaceView updateSelectionInterface:selectionContext.count counterVisible:(selectionContext.count > 0) animated:false]; + model.interfaceView.donePressed = ^(TGClipboardGalleryPhotoItem *item) + { + __strong TGClipboardGalleryMixin *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + strongSelf->_galleryModel.dismiss(true, false); + + if (strongSelf.completeWithItem != nil) + strongSelf.completeWithItem(item); + }; + + modernGallery.model = model; + modernGallery.itemFocused = ^(TGClipboardGalleryPhotoItem *item) + { + __strong TGClipboardGalleryMixin *strongSelf = weakSelf; + if (strongSelf != nil && strongSelf.itemFocused != nil) + strongSelf.itemFocused(item); + }; + + modernGallery.beginTransitionIn = ^UIView *(TGClipboardGalleryPhotoItem *item, TGModernGalleryItemView *itemView) + { + __strong TGClipboardGalleryMixin *strongSelf = weakSelf; + if (strongSelf == nil) + return nil; + + if (strongSelf.willTransitionIn != nil) + strongSelf.willTransitionIn(); + + if (strongSelf.referenceViewForItem != nil) + return strongSelf.referenceViewForItem(item); + + return nil; + }; + + modernGallery.finishedTransitionIn = ^(__unused TGClipboardGalleryPhotoItem *item, __unused TGModernGalleryItemView *itemView) + { + __strong TGClipboardGalleryMixin *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + [strongSelf->_galleryModel.interfaceView setSelectedItemsModel:strongSelf->_galleryModel.selectedItemsModel]; + }; + + modernGallery.beginTransitionOut = ^UIView *(TGClipboardGalleryPhotoItem *item, TGModernGalleryItemView *itemView) + { + __strong TGClipboardGalleryMixin *strongSelf = weakSelf; + if (strongSelf != nil) + { + if (strongSelf.willTransitionOut != nil) + strongSelf.willTransitionOut(); + + if (strongSelf.referenceViewForItem != nil) + return strongSelf.referenceViewForItem(item); + } + return nil; + }; + + modernGallery.completedTransitionOut = ^ + { + __strong TGClipboardGalleryMixin *strongSelf = weakSelf; + if (strongSelf != nil && strongSelf.didTransitionOut != nil) + strongSelf.didTransitionOut(); + }; + } + return self; +} + +- (void)present +{ + _galleryModel.editorOpened = self.editorOpened; + _galleryModel.editorClosed = self.editorClosed; + + [_galleryController setPreviewMode:false]; + + TGOverlayControllerWindow *controllerWindow = [[TGOverlayControllerWindow alloc] initWithParentController:_parentController contentController:_galleryController]; + controllerWindow.hidden = false; + _galleryController.view.clipsToBounds = true; + + _strongGalleryController = nil; +} + +- (UIViewController *)galleryController +{ + return _galleryController; +} + +@end diff --git a/LegacyComponents/TGClipboardGalleryModel.h b/LegacyComponents/TGClipboardGalleryModel.h new file mode 100644 index 0000000000..f7e329bc9a --- /dev/null +++ b/LegacyComponents/TGClipboardGalleryModel.h @@ -0,0 +1,31 @@ +#import + +#import +#import + +#import + +#import + +@interface TGClipboardGalleryModel : TGModernGalleryModel + +@property (nonatomic, copy) void (^willFinishEditingItem)(id item, id adjustments, id temporaryRep, bool hasChanges); +@property (nonatomic, copy) void (^didFinishEditingItem)(iditem, id adjustments, UIImage *resultImage, UIImage *thumbnailImage); +@property (nonatomic, copy) void (^didFinishRenderingFullSizeImage)(id item, UIImage *fullSizeImage); + +@property (nonatomic, copy) void (^saveItemCaption)(id item, NSString *caption); + +@property (nonatomic, copy) void (^editorOpened)(void); +@property (nonatomic, copy) void (^editorClosed)(void); + +@property (nonatomic, weak) TGModernGalleryController *controller; + +@property (nonatomic, readonly, strong) TGMediaPickerGalleryInterfaceView *interfaceView; +@property (nonatomic, readonly, strong) TGMediaPickerGallerySelectedItemsModel *selectedItemsModel; + +@property (nonatomic, readonly) TGMediaSelectionContext *selectionContext; +@property (nonatomic, strong) TGSuggestionContext *suggestionContext; + +- (instancetype)initWithContext:(id)context images:(NSArray *)images focusIndex:(NSUInteger)focusIndex selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext hasCaptions:(bool)hasCaptions hasTimer:(bool)hasTimer hasSelectionPanel:(bool)hasSelectionPanel recipientName:(NSString *)recipientName; + +@end diff --git a/LegacyComponents/TGClipboardGalleryModel.m b/LegacyComponents/TGClipboardGalleryModel.m new file mode 100644 index 0000000000..da20f15e00 --- /dev/null +++ b/LegacyComponents/TGClipboardGalleryModel.m @@ -0,0 +1,503 @@ +#import "TGClipboardGalleryModel.h" + +#import "TGMediaPickerGallerySelectedItemsModel.h" + +#import "LegacyComponentsInternal.h" + +#import +#import +#import "TGModernGallerySelectableItem.h" +#import "TGModernGalleryEditableItem.h" +#import "TGModernGalleryEditableItemView.h" +#import + +#import "TGClipboardGalleryPhotoItem.h" + +#import "TGModernMediaListItem.h" +#import "TGModernMediaListSelectableItem.h" + +#import + +#import + +@interface TGClipboardGalleryModel () +{ + id _itemBeingEdited; + TGMediaEditingContext *_editingContext; + + id _context; +} + +@property (nonatomic, weak) TGPhotoEditorController *editorController; + +@end + +@implementation TGClipboardGalleryModel + +- (instancetype)initWithContext:(id)context images:(NSArray *)images focusIndex:(NSUInteger)focusIndex selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext hasCaptions:(bool)hasCaptions hasTimer:(bool)hasTimer hasSelectionPanel:(bool)hasSelectionPanel recipientName:(NSString *)recipientName +{ + self = [super init]; + if (self != nil) + { + _context = context; + + NSMutableArray *items = [[NSMutableArray alloc] init]; + TGClipboardGalleryPhotoItem *focusItem = nil; + NSUInteger i = 0; + for (UIImage *image in images) + { + TGClipboardGalleryPhotoItem *item = [[TGClipboardGalleryPhotoItem alloc] initWithImage:image]; + item.selectionContext = selectionContext; + item.editingContext = editingContext; + [items addObject:item]; + + if (i == focusIndex) + focusItem = item; + + i++; + } + + [self _replaceItems:items focusingOnItem:focusItem]; + + _editingContext = editingContext; + _selectionContext = selectionContext; + + __weak TGClipboardGalleryModel *weakSelf = self; + if (selectionContext != nil) + { + _selectedItemsModel = [[TGMediaPickerGallerySelectedItemsModel alloc] initWithSelectionContext:selectionContext]; + _selectedItemsModel.selectionUpdated = ^(bool reload, bool incremental, bool add, NSInteger index) + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + [strongSelf.interfaceView updateSelectionInterface:[strongSelf selectionCount] counterVisible:([strongSelf selectionCount] > 0) animated:incremental]; + [strongSelf.interfaceView updateSelectedPhotosView:reload incremental:incremental add:add index:index]; + }; + } + + _interfaceView = [[TGMediaPickerGalleryInterfaceView alloc] initWithContext:_context focusItem:focusItem selectionContext:selectionContext editingContext:editingContext hasSelectionPanel:hasSelectionPanel recipientName:recipientName]; + _interfaceView.hasCaptions = hasCaptions; + _interfaceView.hasTimer = hasTimer; + [_interfaceView setEditorTabPressed:^(TGPhotoEditorTab tab) + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + __strong TGModernGalleryController *controller = strongSelf.controller; + if ([controller.currentItem conformsToProtocol:@protocol(TGModernGalleryEditableItem)]) + [strongSelf presentPhotoEditorForItem:(id)controller.currentItem tab:tab]; + }]; + _interfaceView.photoStripItemSelected = ^(NSInteger index) + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + [strongSelf setCurrentItemWithIndex:index]; + }; + _interfaceView.captionSet = ^(id item, NSString *caption) + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil || strongSelf.saveItemCaption == nil) + return; + + __strong TGModernGalleryController *controller = strongSelf.controller; + if ([controller.currentItem conformsToProtocol:@protocol(TGModernGalleryEditableItem)]) + strongSelf.saveItemCaption(((id)item).editableMediaItem, caption); + }; + _interfaceView.timerRequested = ^ + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + __strong TGModernGalleryController *controller = strongSelf.controller; + id editableMediaItem = ((id)controller.currentItem).editableMediaItem; + + NSString *description = editableMediaItem.isVideo ? TGLocalized(@"SecretTimer.VideoDescription") : TGLocalized(@"SecretTimer.ImageDescription"); + + NSString *lastValueKey = @"mediaPickerLastTimerValue_v0"; + NSNumber *value = [strongSelf->_editingContext timerForItem:editableMediaItem]; + if (value == nil) + value = [[NSUserDefaults standardUserDefaults] objectForKey:lastValueKey]; + + [TGSecretTimerMenu presentInParentController:controller context:strongSelf->_context dark:true description:description values:[TGSecretTimerMenu secretMediaTimerValues] value:value completed:^(NSNumber *value) + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + if (value == nil) + [[NSUserDefaults standardUserDefaults] removeObjectForKey:lastValueKey]; + else + [[NSUserDefaults standardUserDefaults] setObject:value forKey:lastValueKey]; + + [strongSelf->_editingContext setTimer:value forItem:editableMediaItem]; + + if (value.integerValue != 0) + { + __strong TGModernGalleryController *controller = strongSelf.controller; + id selectableItem = nil; + if ([controller.currentItem conformsToProtocol:@protocol(TGModernGallerySelectableItem)]) + { + selectableItem = ((id)controller.currentItem).selectableMediaItem; + + if (selectableItem != nil) + [strongSelf->_selectionContext setItem:selectableItem selected:true animated:false sender:nil]; + } + } + } dismissed:^ + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf != nil) + [strongSelf->_interfaceView setAllInterfaceHidden:false delay:0.0f animated:true]; + } sourceView:controller.view sourceRect:^CGRect + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil) + return CGRectZero; + + __strong TGModernGalleryController *controller = strongSelf.controller; + return [strongSelf->_interfaceView.timerButton convertRect:strongSelf->_interfaceView.timerButton.bounds toView:controller.view]; + }]; + }; + } + return self; +} + +- (void)setSuggestionContext:(TGSuggestionContext *)suggestionContext +{ + _suggestionContext = suggestionContext; + [_interfaceView setSuggestionContext:suggestionContext]; +} + +- (NSInteger)selectionCount +{ + return _selectedItemsModel.selectedCount; +} + +- (void)setCurrentItem:(id)item direction:(TGModernGalleryScrollAnimationDirection)direction +{ + if (![(id)item conformsToProtocol:@protocol(TGMediaSelectableItem)]) + return; + + id targetSelectableItem = (id)item; + + __block NSUInteger newIndex = NSNotFound; + [self.items enumerateObjectsUsingBlock:^(id galleryItem, NSUInteger idx, BOOL *stop) + { + if ([galleryItem conformsToProtocol:@protocol(TGModernGallerySelectableItem)]) + { + id selectableItem = ((id)galleryItem).selectableMediaItem; + + if ([selectableItem.uniqueIdentifier isEqual:targetSelectableItem.uniqueIdentifier]) + { + newIndex = idx; + *stop = true; + } + } + }]; + + TGModernGalleryController *galleryController = self.controller; + [galleryController setCurrentItemIndex:newIndex direction:direction animated:true]; +} + +- (void)setCurrentItemWithIndex:(NSUInteger)index +{ + if (_selectedItemsModel == nil) + return; + + TGModernGalleryController *galleryController = self.controller; + + if (![galleryController.currentItem conformsToProtocol:@protocol(TGModernGallerySelectableItem)]) + return; + + id currentGalleryItem = (id)galleryController.currentItem; + + __block NSUInteger currentSelectedItemIndex = NSNotFound; + [_selectedItemsModel.items enumerateObjectsUsingBlock:^(id item, NSUInteger index, BOOL *stop) + { + if ([item.uniqueIdentifier isEqualToString:currentGalleryItem.selectableMediaItem.uniqueIdentifier]) + { + currentSelectedItemIndex = index; + *stop = true; + } + }]; + + id item = _selectedItemsModel.items[index]; + + TGModernGalleryScrollAnimationDirection direction = TGModernGalleryScrollAnimationDirectionLeft; + if (currentSelectedItemIndex < index) + direction = TGModernGalleryScrollAnimationDirectionRight; + + [self setCurrentItem:item direction:direction]; +} + +- (UIView *)createInterfaceView +{ + return _interfaceView; +} + +- (UIView *)referenceViewForItem:(id)item frame:(CGRect *)frame +{ + TGModernGalleryController *galleryController = self.controller; + TGModernGalleryItemView *galleryItemView = [galleryController itemViewForItem:item]; + + if ([galleryItemView isKindOfClass:[TGModernGalleryZoomableItemView class]]) + { + TGModernGalleryZoomableItemView *zoomableItemView = (TGModernGalleryZoomableItemView *)galleryItemView; + + if (zoomableItemView.contentView != nil) + { + if (frame != NULL) + *frame = [zoomableItemView transitionViewContentRect]; + + return (UIImageView *)zoomableItemView.transitionContentView; + } + } + + return nil; +} + +- (void)updateHiddenItem +{ + TGModernGalleryController *galleryController = self.controller; + + for (TGModernGalleryItemView *itemView in galleryController.visibleItemViews) + { + if ([itemView conformsToProtocol:@protocol(TGModernGalleryEditableItemView)]) + [(TGModernGalleryItemView *)itemView setHiddenAsBeingEdited:[itemView.item isEqual:_itemBeingEdited]]; + } +} + +- (void)updateEditedItemView +{ + TGModernGalleryController *galleryController = self.controller; + + for (TGModernGalleryItemView *itemView in galleryController.visibleItemViews) + { + if ([itemView conformsToProtocol:@protocol(TGModernGalleryEditableItemView)]) + { + if ([itemView.item isEqual:_itemBeingEdited]) + { + [(TGModernGalleryItemView *)itemView setItem:_itemBeingEdited synchronously:true]; + if (self.itemsUpdated != nil) + self.itemsUpdated(_itemBeingEdited); + } + } + } +} + +- (void)presentPhotoEditorForItem:(id)item tab:(TGPhotoEditorTab)tab +{ + __weak TGClipboardGalleryModel *weakSelf = self; + + if (_itemBeingEdited != nil) + return; + + _itemBeingEdited = item; + + PGPhotoEditorValues *editorValues = (PGPhotoEditorValues *)[item.editingContext adjustmentsForItem:item.editableMediaItem]; + + NSString *caption = [item.editingContext captionForItem:item.editableMediaItem]; + + CGRect refFrame = CGRectZero; + UIView *editorReferenceView = [self referenceViewForItem:item frame:&refFrame]; + UIView *referenceView = nil; + UIImage *screenImage = nil; + UIView *referenceParentView = nil; + UIImage *image = nil; + + bool isVideo = false; + if ([editorReferenceView isKindOfClass:[UIImageView class]]) + { + screenImage = [(UIImageView *)editorReferenceView image]; + referenceView = editorReferenceView; + } + + TGPhotoEditorControllerIntent intent = isVideo ? TGPhotoEditorControllerVideoIntent : TGPhotoEditorControllerGenericIntent; + TGPhotoEditorController *controller = [[TGPhotoEditorController alloc] initWithContext:_context item:item.editableMediaItem intent:intent adjustments:editorValues caption:caption screenImage:screenImage availableTabs:_interfaceView.currentTabs selectedTab:tab]; + controller.editingContext = _editingContext; + self.editorController = controller; + controller.suggestionContext = self.suggestionContext; + controller.willFinishEditing = ^(id adjustments, id temporaryRep, bool hasChanges) + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + strongSelf->_itemBeingEdited = nil; + + if (strongSelf.willFinishEditingItem != nil) + strongSelf.willFinishEditingItem(item.editableMediaItem, adjustments, temporaryRep, hasChanges); + }; + + void (^didFinishEditingItem)(iditem, id adjustments, UIImage *resultImage, UIImage *thumbnailImage) = self.didFinishEditingItem; + controller.didFinishEditing = ^(id adjustments, UIImage *resultImage, UIImage *thumbnailImage, bool hasChanges) + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil) { + TGLog(@"controller.didFinishEditing strongSelf == nil"); + } + +#ifdef DEBUG + if (adjustments != nil && hasChanges && !isVideo) + NSAssert(resultImage != nil, @"resultImage should not be nil"); +#endif + + if (hasChanges) + { + if (didFinishEditingItem != nil) { + didFinishEditingItem(item.editableMediaItem, adjustments, resultImage, thumbnailImage); + } + } + }; + + controller.didFinishRenderingFullSizeImage = ^(UIImage *image) + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + if (strongSelf.didFinishRenderingFullSizeImage != nil) + strongSelf.didFinishRenderingFullSizeImage(item.editableMediaItem, image); + }; + + controller.captionSet = ^(NSString *caption) + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + if (strongSelf.saveItemCaption != nil) + strongSelf.saveItemCaption(item.editableMediaItem, caption); + }; + + controller.requestToolbarsHidden = ^(bool hidden, bool animated) + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + [strongSelf.interfaceView setToolbarsHidden:hidden animated:animated]; + }; + + controller.beginTransitionIn = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView) + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil) + return nil; + + if (strongSelf.editorOpened != nil) + strongSelf.editorOpened(); + + [strongSelf updateHiddenItem]; + [strongSelf.interfaceView editorTransitionIn]; + + *referenceFrame = refFrame; + + if (referenceView.superview == nil) + *parentView = referenceParentView; + + if (iosMajorVersion() >= 7) + [strongSelf.controller setNeedsStatusBarAppearanceUpdate]; + else + [_context setStatusBarHidden:true withAnimation:UIStatusBarAnimationNone]; + + return referenceView; + }; + + controller.finishedTransitionIn = ^ + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + TGModernGalleryController *galleryController = strongSelf.controller; + TGModernGalleryItemView *galleryItemView = [galleryController itemViewForItem:strongSelf->_itemBeingEdited]; + if (![galleryItemView isKindOfClass:[TGModernGalleryZoomableItemView class]]) + return; + + TGModernGalleryZoomableItemView *zoomableItemView = (TGModernGalleryZoomableItemView *)galleryItemView; + [zoomableItemView reset]; + }; + + controller.beginTransitionOut = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView) + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil) + return nil; + + [strongSelf.interfaceView editorTransitionOut]; + + CGRect refFrame; + UIView *referenceView = [strongSelf referenceViewForItem:item frame:&refFrame]; + + *referenceFrame = refFrame; + + return referenceView; + }; + + controller.finishedTransitionOut = ^(__unused bool saved) + { + __strong TGClipboardGalleryModel *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + if (strongSelf.editorClosed != nil) + strongSelf.editorClosed(); + + [strongSelf updateHiddenItem]; + + if (iosMajorVersion() >= 7) + [strongSelf.controller setNeedsStatusBarAppearanceUpdate]; + else { + [_context setStatusBarHidden:false withAnimation:UIStatusBarAnimationNone]; + } + }; + + controller.requestThumbnailImage = ^SSignal *(id editableItem) + { + return [editableItem thumbnailImageSignal]; + }; + + controller.requestOriginalScreenSizeImage = ^SSignal *(id editableItem, NSTimeInterval position) + { + return [editableItem screenImageSignal:position]; + }; + + controller.requestOriginalFullSizeImage = ^SSignal *(id editableItem, NSTimeInterval position) + { + return [editableItem originalImageSignal:position]; + }; + + controller.requestImage = ^ + { + return image; + }; + + [self.controller addChildViewController:controller]; + [self.controller.view addSubview:controller.view]; +} + +- (void)_replaceItems:(NSArray *)items focusingOnItem:(id)item +{ + [super _replaceItems:items focusingOnItem:item]; + + TGModernGalleryController *controller = self.controller; + + NSArray *itemViews = [controller.visibleItemViews copy]; + for (TGModernGalleryItemView *itemView in itemViews) + [itemView setItem:itemView.item synchronously:false]; +} + +- (bool)_shouldAutorotate +{ + TGPhotoEditorController *editorController = self.editorController; + return (!editorController || [editorController shouldAutorotate]); +} + +@end diff --git a/LegacyComponents/TGClipboardGalleryPhotoItem.h b/LegacyComponents/TGClipboardGalleryPhotoItem.h new file mode 100644 index 0000000000..97065641fd --- /dev/null +++ b/LegacyComponents/TGClipboardGalleryPhotoItem.h @@ -0,0 +1,10 @@ +#import +#import + +@interface TGClipboardGalleryPhotoItem : NSObject + +@property (nonatomic, strong) UIImage *image; + +- (instancetype)initWithImage:(UIImage *)image; + +@end diff --git a/LegacyComponents/TGClipboardGalleryPhotoItem.m b/LegacyComponents/TGClipboardGalleryPhotoItem.m new file mode 100644 index 0000000000..4c93487802 --- /dev/null +++ b/LegacyComponents/TGClipboardGalleryPhotoItem.m @@ -0,0 +1,55 @@ +#import "TGClipboardGalleryPhotoItem.h" +#import "TGClipboardGalleryPhotoItemView.h" + +#import "LegacyComponentsInternal.h" + +#import "UIImage+TGMediaEditableItem.h" + +@implementation TGClipboardGalleryPhotoItem + +@synthesize selectionContext; +@synthesize editingContext; + +- (instancetype)initWithImage:(UIImage *)image +{ + self = [super init]; + if (self != nil) + { + _image = image; + } + return self; +} + +- (NSString *)uniqueId +{ + return self.image.uniqueIdentifier; +} + +- (id)selectableMediaItem +{ + return self.image; +} + +- (id)editableMediaItem +{ + return self.image; +} + +- (TGPhotoEditorTab)toolbarTabs +{ + return TGPhotoEditorCropTab | TGPhotoEditorToolsTab | TGPhotoEditorPaintTab | TGPhotoEditorTimerTab; +} + + +- (Class)viewClass +{ + return [TGClipboardGalleryPhotoItemView class]; +} + +- (BOOL)isEqual:(id)object +{ + return [object isKindOfClass:[TGClipboardGalleryPhotoItem class]] && TGObjectCompare(_image, ((TGClipboardGalleryPhotoItem *)object)->_image); +} + + +@end diff --git a/LegacyComponents/TGClipboardGalleryPhotoItemView.h b/LegacyComponents/TGClipboardGalleryPhotoItemView.h new file mode 100644 index 0000000000..9646d8f683 --- /dev/null +++ b/LegacyComponents/TGClipboardGalleryPhotoItemView.h @@ -0,0 +1,11 @@ +#import +#import "TGModernGalleryEditableItemView.h" +#import "TGModernGalleryImageItemImageView.h" + +@interface TGClipboardGalleryPhotoItemView : TGModernGalleryZoomableItemView + +@property (nonatomic) CGSize imageSize; + +@property (nonatomic, strong) TGModernGalleryImageItemImageView *imageView; + +@end diff --git a/LegacyComponents/TGClipboardGalleryPhotoItemView.m b/LegacyComponents/TGClipboardGalleryPhotoItemView.m new file mode 100644 index 0000000000..30a8a7d724 --- /dev/null +++ b/LegacyComponents/TGClipboardGalleryPhotoItemView.m @@ -0,0 +1,208 @@ +#import "TGClipboardGalleryPhotoItemView.h" + +#import "LegacyComponentsInternal.h" +#import "TGFont.h" +#import "TGStringUtils.h" + +#import + +#import + +#import +#import +#import + +#import + +#import "TGClipboardGalleryPhotoItem.h" + +@interface TGClipboardGalleryPhotoItemView () +{ + UIView *_temporaryRepView; + + SMetaDisposable *_attributesDisposable; +} +@end + +@implementation TGClipboardGalleryPhotoItemView + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self != nil) + { + _imageView = [[TGModernGalleryImageItemImageView alloc] init]; + [self.scrollView addSubview:_imageView]; + } + return self; +} + +- (void)dealloc +{ + [_attributesDisposable dispose]; +} + +- (void)setHiddenAsBeingEdited:(bool)hidden +{ + self.imageView.hidden = hidden; + _temporaryRepView.hidden = hidden; +} + +- (void)prepareForRecycle +{ + _imageView.hidden = false; + [_imageView reset]; +} + +- (void)setItem:(TGClipboardGalleryPhotoItem *)item synchronously:(bool)synchronously +{ + [super setItem:item synchronously:synchronously]; + + _imageSize = item.image.size; + [self reset]; + + if (item.image == nil) + { + [self.imageView reset]; + } + else + { + __weak TGClipboardGalleryPhotoItemView *weakSelf = self; + void (^fadeOutRepView)(void) = ^ + { + __strong TGClipboardGalleryPhotoItemView *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + if (strongSelf->_temporaryRepView == nil) + return; + + UIView *repView = strongSelf->_temporaryRepView; + strongSelf->_temporaryRepView = nil; + [UIView animateWithDuration:0.2f animations:^ + { + repView.alpha = 0.0f; + } completion:^(__unused BOOL finished) + { + [repView removeFromSuperview]; + }]; + }; + + SSignal *assetSignal = [SSignal single:item.image]; + + SSignal *imageSignal = assetSignal; + if (item.editingContext != nil) + { + imageSignal = [[[item.editingContext imageSignalForItem:item.editableMediaItem] deliverOn:[SQueue mainQueue]] mapToSignal:^SSignal *(id result) + { + __strong TGClipboardGalleryPhotoItemView *strongSelf = weakSelf; + if (strongSelf == nil) + return [SSignal complete]; + + if (result == nil) + { + return [[assetSignal deliverOn:[SQueue mainQueue]] afterNext:^(__unused id next) + { + fadeOutRepView(); + }]; + } + else if ([result isKindOfClass:[UIView class]]) + { + [strongSelf _setTemporaryRepView:result]; + return [[SSignal single:nil] deliverOn:[SQueue mainQueue]]; + } + else + { + return [[[SSignal single:result] deliverOn:[SQueue mainQueue]] afterNext:^(__unused id next) + { + fadeOutRepView(); + }]; + } + }]; + } + + + [self.imageView setSignal:[[imageSignal deliverOn:[SQueue mainQueue]] afterNext:^(id next) + { + __strong TGClipboardGalleryPhotoItemView *strongSelf = weakSelf; + if (strongSelf == nil) + return; + + if ([next isKindOfClass:[UIImage class]]) + strongSelf->_imageSize = ((UIImage *)next).size; + + [strongSelf reset]; + }]]; + } +} + +- (void)_setTemporaryRepView:(UIView *)view +{ + [_temporaryRepView removeFromSuperview]; + _temporaryRepView = view; + + _imageSize = TGScaleToSize(view.frame.size, self.containerView.frame.size); + + view.hidden = self.imageView.hidden; + view.frame = CGRectMake((self.containerView.frame.size.width - _imageSize.width) / 2.0f, (self.containerView.frame.size.height - _imageSize.height) / 2.0f, _imageSize.width, _imageSize.height); + + [self.containerView addSubview:view]; +} + +- (void)singleTap +{ + if ([self.item conformsToProtocol:@protocol(TGModernGallerySelectableItem)]) + { + TGMediaSelectionContext *selectionContext = ((id)self.item).selectionContext; + id item = ((id)self.item).selectableMediaItem; + + [selectionContext toggleItemSelection:item animated:true sender:nil]; + } + else + { + id delegate = self.delegate; + if ([delegate respondsToSelector:@selector(itemViewDidRequestInterfaceShowHide:)]) + [delegate itemViewDidRequestInterfaceShowHide:self]; + } +} + +- (UIView *)footerView +{ + return nil; +} + +- (SSignal *)contentAvailabilityStateSignal +{ + return [SSignal single:@true]; +} + +- (CGSize)contentSize +{ + return _imageSize; +} + +- (UIView *)contentView +{ + return _imageView; +} + +- (UIView *)transitionContentView +{ + if (_temporaryRepView != nil) + return _temporaryRepView; + + return [self contentView]; +} + +- (UIView *)transitionView +{ + return self.containerView; +} + +- (CGRect)transitionViewContentRect +{ + UIView *contentView = [self transitionContentView]; + return [contentView convertRect:contentView.bounds toView:[self transitionView]]; +} + +@end diff --git a/LegacyComponents/TGMediaPickerGalleryInterfaceView.m b/LegacyComponents/TGMediaPickerGalleryInterfaceView.m index 18f470959d..b7a040d173 100644 --- a/LegacyComponents/TGMediaPickerGalleryInterfaceView.m +++ b/LegacyComponents/TGMediaPickerGalleryInterfaceView.m @@ -338,7 +338,7 @@ _selectedPhotosView.selectedItemsModel = selectedItemsModel; [_selectedPhotosView reloadData]; - if (selectedItemsModel != nil) + if (selectedItemsModel != nil && _selectedPhotosView != nil) _photoCounterButton.userInteractionEnabled = true; } diff --git a/LegacyComponents/TGNavigationController.h b/LegacyComponents/TGNavigationController.h index b543c1f485..b5d0fdfdba 100644 --- a/LegacyComponents/TGNavigationController.h +++ b/LegacyComponents/TGNavigationController.h @@ -26,6 +26,7 @@ typedef enum { @property (nonatomic) bool showCallStatusBar; @property (nonatomic) CGFloat currentAdditionalNavigationBarHeight; +@property (nonatomic) bool forceAdditionalNavigationBarHeight; + (TGNavigationController *)navigationControllerWithControllers:(NSArray *)controllers; + (TGNavigationController *)navigationControllerWithControllers:(NSArray *)controllers navigationBarClass:(Class)navigationBarClass; diff --git a/LegacyComponents/TGNavigationController.m b/LegacyComponents/TGNavigationController.m index 87db336a01..c188d0341b 100644 --- a/LegacyComponents/TGNavigationController.m +++ b/LegacyComponents/TGNavigationController.m @@ -516,7 +516,7 @@ static UIView *findDimmingView(UIView *view) - (void)setupPlayerOnControllers:(NSArray *)controllers { - if (_displayPlayer && [[self navigationBar] isKindOfClass:[TGNavigationBar class]]) + if ((_displayPlayer || _forceAdditionalNavigationBarHeight) && [[self navigationBar] isKindOfClass:[TGNavigationBar class]]) { for (id maybeController in controllers) { @@ -525,7 +525,7 @@ static UIView *findDimmingView(UIView *view) TGViewController *controller = maybeController; [controller setAdditionalNavigationBarHeight:_currentAdditionalNavigationBarHeight]; } - else if ([maybeController isKindOfClass:[UITabBarController class]] && [maybeController conformsToProtocol:@protocol(TGNavigationControllerTabsController)]) + else if (_displayPlayer && [maybeController isKindOfClass:[UITabBarController class]] && [maybeController conformsToProtocol:@protocol(TGNavigationControllerTabsController)]) { [self setupPlayerOnControllers:((UITabBarController *)maybeController).viewControllers]; } @@ -535,7 +535,7 @@ static UIView *findDimmingView(UIView *view) - (void)updatePlayerOnControllers { - if (_displayPlayer && [[self navigationBar] isKindOfClass:[TGNavigationBar class]]) + if ((_displayPlayer || _forceAdditionalNavigationBarHeight) && [[self navigationBar] isKindOfClass:[TGNavigationBar class]]) { for (id maybeController in [self viewControllers]) { @@ -543,7 +543,7 @@ static UIView *findDimmingView(UIView *view) { [((TGViewController *)maybeController) setAdditionalNavigationBarHeight:_currentAdditionalNavigationBarHeight]; } - else if ([maybeController isKindOfClass:[UITabBarController class]] && [maybeController conformsToProtocol:@protocol(TGNavigationControllerTabsController)]) + else if (_displayPlayer && [maybeController isKindOfClass:[UITabBarController class]] && [maybeController conformsToProtocol:@protocol(TGNavigationControllerTabsController)]) { for (id controller in ((UITabBarController *)maybeController).viewControllers) { diff --git a/LegacyComponents/UIImage+TGMediaEditableItem.h b/LegacyComponents/UIImage+TGMediaEditableItem.h index 924b503d87..c5d50ba48c 100644 --- a/LegacyComponents/UIImage+TGMediaEditableItem.h +++ b/LegacyComponents/UIImage+TGMediaEditableItem.h @@ -1,6 +1,7 @@ #import #import +#import -@interface UIImage (TGMediaEditableItem) +@interface UIImage (TGMediaEditableItem) @end