mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-04-06 21:35:53 +00:00
Fixes
fix localeWithStrings globally (#30)
Fix badge on zoomed devices. closes #9
Hide channel bottom panel closes #27
Another attempt to fix badge on some Zoomed devices
Force System Share sheet tg://sg/debug
fixes for device badge
New Crowdin updates (#34)
* New translations sglocalizable.strings (Chinese Traditional)
* New translations sglocalizable.strings (Chinese Simplified)
* New translations sglocalizable.strings (Chinese Traditional)
Fix input panel hidden on selection (#31)
* added if check for selectionState != nil
* same order of subnodes
Revert "Fix input panel hidden on selection (#31)"
This reverts commit e8a8bb1496.
Fix input panel for channels Closes #37
Quickly share links with system's share menu
force tabbar when editing
increase height for correct animation
New translations sglocalizable.strings (Ukrainian) (#38)
Hide Post Story button
Fix 10.15.1
Fix archive option for long-tap
Enable in-app Safari
Disable some unsupported purchases
disableDeleteChatSwipeOption + refactor restart alert
Hide bot in suggestions list
Fix merge v11.0
Fix exceptions for safari webview controller
New Crowdin updates (#47)
* New translations sglocalizable.strings (Romanian)
* New translations sglocalizable.strings (French)
* New translations sglocalizable.strings (Spanish)
* New translations sglocalizable.strings (Afrikaans)
* New translations sglocalizable.strings (Arabic)
* New translations sglocalizable.strings (Catalan)
* New translations sglocalizable.strings (Czech)
* New translations sglocalizable.strings (Danish)
* New translations sglocalizable.strings (German)
* New translations sglocalizable.strings (Greek)
* New translations sglocalizable.strings (Finnish)
* New translations sglocalizable.strings (Hebrew)
* New translations sglocalizable.strings (Hungarian)
* New translations sglocalizable.strings (Italian)
* New translations sglocalizable.strings (Japanese)
* New translations sglocalizable.strings (Korean)
* New translations sglocalizable.strings (Dutch)
* New translations sglocalizable.strings (Norwegian)
* New translations sglocalizable.strings (Polish)
* New translations sglocalizable.strings (Portuguese)
* New translations sglocalizable.strings (Serbian (Cyrillic))
* New translations sglocalizable.strings (Swedish)
* New translations sglocalizable.strings (Turkish)
* New translations sglocalizable.strings (Vietnamese)
* New translations sglocalizable.strings (Indonesian)
* New translations sglocalizable.strings (Hindi)
* New translations sglocalizable.strings (Uzbek)
New Crowdin updates (#49)
* New translations sglocalizable.strings (Arabic)
* New translations sglocalizable.strings (Arabic)
New translations sglocalizable.strings (Russian) (#51)
Call confirmation
WIP Settings search
Settings Search
Localize placeholder
Update AccountUtils.swift
mark mutual contact
Align back context action to left
New Crowdin updates (#54)
* New translations sglocalizable.strings (Chinese Simplified)
* New translations sglocalizable.strings (Chinese Traditional)
* New translations sglocalizable.strings (Ukrainian)
Independent Playground app for simulator
New translations sglocalizable.strings (Ukrainian) (#55)
Playground UIKit base and controllers
Inject SwiftUI view with overflow to AsyncDisplayKit
Launch Playgound project on simulator
Create .swiftformat
Move Playground to example
Update .swiftformat
Init SwiftUIViewController
wip
New translations sglocalizable.strings (Chinese Traditional) (#57)
Xcode 16 fixes
Fix
New translations sglocalizable.strings (Italian) (#59)
New translations sglocalizable.strings (Chinese Simplified) (#63)
Force disable CallKit integration due to missing NSE Entitlement
Fix merge
Fix whole chat translator
Sweetpad config
Bump version
11.3.1 fixes
Mutual contact placement fix
Disable Video PIP swipe
Update versions.json
Fix PIP crash
646 lines
26 KiB
Objective-C
646 lines
26 KiB
Objective-C
#import "TGMediaPickerGalleryModel.h"
|
|
|
|
#import "TGMediaPickerGallerySelectedItemsModel.h"
|
|
|
|
#import "LegacyComponentsInternal.h"
|
|
|
|
#import <LegacyComponents/TGModernGalleryController.h>
|
|
#import <LegacyComponents/TGModernGalleryItem.h>
|
|
#import "TGModernGallerySelectableItem.h"
|
|
#import "TGModernGalleryEditableItem.h"
|
|
#import "TGModernGalleryEditableItemView.h"
|
|
#import "TGMediaPickerGalleryItem.h"
|
|
#import <LegacyComponents/TGModernGalleryZoomableItemView.h>
|
|
#import "TGMediaPickerGalleryVideoItem.h"
|
|
#import "TGMediaPickerGalleryVideoItemView.h"
|
|
|
|
#import "TGModernMediaListItem.h"
|
|
#import "TGModernMediaListSelectableItem.h"
|
|
|
|
#import <LegacyComponents/PGPhotoEditorValues.h>
|
|
|
|
#import <LegacyComponents/TGSecretTimerMenu.h>
|
|
|
|
@interface TGMediaPickerGalleryModel ()
|
|
{
|
|
TGMediaPickerGalleryInterfaceView *_interfaceView;
|
|
|
|
id<TGModernGalleryEditableItem> _itemBeingEdited;
|
|
TGMediaEditingContext *_editingContext;
|
|
|
|
id<LegacyComponentsContext> _context;
|
|
|
|
id<TGModernGalleryItem> _initialFocusItem;
|
|
bool _hasCaptions;
|
|
bool _allowCaptionEntities;
|
|
bool _hasTimer;
|
|
bool _onlyCrop;
|
|
bool _hasSelectionPanel;
|
|
bool _inhibitDocumentCaptions;
|
|
NSString *_recipientName;
|
|
bool _hasCamera;
|
|
bool _isScheduledMessages;
|
|
bool _canShowTelescope;
|
|
bool _canSendTelescope;
|
|
}
|
|
|
|
@property (nonatomic, weak) TGPhotoEditorController *editorController;
|
|
|
|
@end
|
|
|
|
@implementation TGMediaPickerGalleryModel
|
|
|
|
- (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 isScheduledMessages:(bool)isScheduledMessages canShowTelescope:(bool)canShowTelescope canSendTelescope:(bool)canSendTelescope
|
|
{
|
|
self = [super init];
|
|
if (self != nil)
|
|
{
|
|
_context = context;
|
|
|
|
[self _replaceItems:items focusingOnItem:focusItem];
|
|
|
|
_editingContext = editingContext;
|
|
_selectionContext = selectionContext;
|
|
|
|
_initialFocusItem = focusItem;
|
|
_hasCaptions = hasCaptions;
|
|
_allowCaptionEntities = allowCaptionEntities;
|
|
_hasTimer = hasTimer;
|
|
_onlyCrop = onlyCrop;
|
|
_hasSelectionPanel = hasSelectionPanel;
|
|
_inhibitDocumentCaptions = inhibitDocumentCaptions;
|
|
_recipientName = recipientName;
|
|
_hasCamera = hasCamera;
|
|
_isScheduledMessages = isScheduledMessages;
|
|
_canSendTelescope = canSendTelescope;
|
|
_canShowTelescope = canShowTelescope;
|
|
|
|
__weak TGMediaPickerGalleryModel *weakSelf = self;
|
|
if (selectionContext != nil)
|
|
{
|
|
if (_hasCamera)
|
|
{
|
|
NSMutableArray *selectableItems = [[NSMutableArray alloc] init];
|
|
for (TGMediaPickerGalleryItem *item in items)
|
|
{
|
|
[selectableItems addObject:item.asset];
|
|
}
|
|
_selectedItemsModel = [[TGMediaPickerGallerySelectedItemsModel alloc] initWithSelectionContext:selectionContext items:selectableItems];
|
|
}
|
|
else
|
|
{
|
|
_selectedItemsModel = [[TGMediaPickerGallerySelectedItemsModel alloc] initWithSelectionContext:selectionContext];
|
|
}
|
|
_selectedItemsModel.selectionUpdated = ^(bool reload, bool incremental, bool add, NSInteger index)
|
|
{
|
|
__strong TGMediaPickerGalleryModel *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];
|
|
};
|
|
}
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (NSInteger)selectionCount
|
|
{
|
|
if (self.externalSelectionCount != nil)
|
|
return self.externalSelectionCount();
|
|
|
|
return _selectedItemsModel.selectedCount;
|
|
}
|
|
|
|
- (void)setCurrentItem:(id<TGMediaSelectableItem>)item direction:(TGModernGalleryScrollAnimationDirection)direction
|
|
{
|
|
if (![(id)item conformsToProtocol:@protocol(TGMediaSelectableItem)])
|
|
return;
|
|
|
|
id<TGMediaSelectableItem> targetSelectableItem = (id<TGMediaSelectableItem>)item;
|
|
|
|
__block NSUInteger newIndex = NSNotFound;
|
|
[self.items enumerateObjectsUsingBlock:^(id<TGModernGalleryItem> galleryItem, NSUInteger idx, BOOL *stop)
|
|
{
|
|
if ([galleryItem conformsToProtocol:@protocol(TGModernGallerySelectableItem)])
|
|
{
|
|
id<TGMediaSelectableItem> selectableItem = ((id<TGModernGallerySelectableItem>)galleryItem).selectableMediaItem;
|
|
|
|
if ([selectableItem.uniqueIdentifier isEqual:targetSelectableItem.uniqueIdentifier])
|
|
{
|
|
newIndex = idx;
|
|
*stop = true;
|
|
}
|
|
}
|
|
}];
|
|
|
|
TGModernGalleryController *galleryController = self.controller;
|
|
[galleryController setCurrentItemIndex:newIndex direction:direction animated:false];
|
|
}
|
|
|
|
- (void)setCurrentItemWithIndex:(NSUInteger)index
|
|
{
|
|
if (_selectedItemsModel == nil)
|
|
return;
|
|
|
|
TGModernGalleryController *galleryController = self.controller;
|
|
|
|
if (![galleryController.currentItem conformsToProtocol:@protocol(TGModernGallerySelectableItem)])
|
|
return;
|
|
|
|
id<TGModernGallerySelectableItem> currentGalleryItem = (id<TGModernGallerySelectableItem>)galleryController.currentItem;
|
|
|
|
__block NSUInteger currentSelectedItemIndex = NSNotFound;
|
|
[_selectedItemsModel.items enumerateObjectsUsingBlock:^(id<TGMediaSelectableItem> item, NSUInteger index, BOOL *stop)
|
|
{
|
|
if ([item.uniqueIdentifier isEqualToString:currentGalleryItem.selectableMediaItem.uniqueIdentifier])
|
|
{
|
|
currentSelectedItemIndex = index;
|
|
*stop = true;
|
|
}
|
|
}];
|
|
|
|
id<TGMediaSelectableItem> item = _selectedItemsModel.items[index];
|
|
|
|
TGModernGalleryScrollAnimationDirection direction = TGModernGalleryScrollAnimationDirectionLeft;
|
|
if (currentSelectedItemIndex < index)
|
|
direction = TGModernGalleryScrollAnimationDirectionRight;
|
|
|
|
[self setCurrentItem:item direction:direction];
|
|
}
|
|
|
|
- (UIView <TGModernGalleryInterfaceView> *)interfaceView
|
|
{
|
|
if (_interfaceView != nil)
|
|
return _interfaceView;
|
|
|
|
return [self createInterfaceView];
|
|
}
|
|
|
|
- (UIView <TGModernGalleryInterfaceView> *)createInterfaceView
|
|
{
|
|
if (_interfaceView == nil)
|
|
{
|
|
__weak TGMediaPickerGalleryModel *weakSelf = self;
|
|
_interfaceView = [[TGMediaPickerGalleryInterfaceView alloc] initWithContext:_context focusItem:_initialFocusItem selectionContext:_selectionContext editingContext:_editingContext stickersContext:_stickersContext hasSelectionPanel:_hasSelectionPanel hasCameraButton:_hasCamera recipientName:_recipientName isScheduledMessages:_isScheduledMessages canShowTelescope:_canShowTelescope canSendTelescope:_canSendTelescope];
|
|
_interfaceView.hasCaptions = _hasCaptions;
|
|
_interfaceView.allowCaptionEntities = _allowCaptionEntities;
|
|
_interfaceView.hasTimer = _hasTimer;
|
|
_interfaceView.onlyCrop = _onlyCrop;
|
|
_interfaceView.inhibitDocumentCaptions = _inhibitDocumentCaptions;
|
|
_interfaceView.inhibitMute = _inhibitMute;
|
|
[_interfaceView setEditorTabPressed:^(TGPhotoEditorTab tab)
|
|
{
|
|
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return;
|
|
|
|
__strong TGModernGalleryController *controller = strongSelf.controller;
|
|
if ([controller.currentItem conformsToProtocol:@protocol(TGModernGalleryEditableItem)])
|
|
[strongSelf presentPhotoEditorForItem:(id<TGModernGalleryEditableItem>)controller.currentItem tab:tab];
|
|
}];
|
|
_interfaceView.photoStripItemSelected = ^(NSInteger index)
|
|
{
|
|
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return;
|
|
|
|
[strongSelf setCurrentItemWithIndex:index];
|
|
};
|
|
_interfaceView.captionSet = ^(id<TGModernGalleryItem> item, NSAttributedString *caption)
|
|
{
|
|
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
|
if (strongSelf == nil || strongSelf.saveItemCaption == nil)
|
|
return;
|
|
|
|
__strong TGModernGalleryController *controller = strongSelf.controller;
|
|
if ([controller.currentItem conformsToProtocol:@protocol(TGModernGalleryEditableItem)])
|
|
strongSelf.saveItemCaption(((id<TGModernGalleryEditableItem>)item).editableMediaItem, caption);
|
|
};
|
|
_interfaceView.timerRequested = ^
|
|
{
|
|
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return;
|
|
|
|
__strong TGModernGalleryController *controller = strongSelf.controller;
|
|
id<TGMediaEditableItem> editableMediaItem = ((id<TGModernGalleryEditableItem>)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 TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return;
|
|
|
|
if (value == nil)
|
|
[[NSUserDefaults standardUserDefaults] removeObjectForKey:lastValueKey];
|
|
else
|
|
[[NSUserDefaults standardUserDefaults] setObject:value forKey:lastValueKey];
|
|
|
|
if (value.integerValue != 0)
|
|
{
|
|
__strong TGModernGalleryController *controller = strongSelf.controller;
|
|
id<TGMediaSelectableItem> selectableItem = nil;
|
|
if ([controller.currentItem conformsToProtocol:@protocol(TGModernGallerySelectableItem)])
|
|
{
|
|
selectableItem = ((id<TGModernGallerySelectableItem>)controller.currentItem).selectableMediaItem;
|
|
|
|
if (selectableItem != nil) {
|
|
[strongSelf->_selectionContext setItem:selectableItem selected:true animated:false sender:nil];
|
|
}
|
|
}
|
|
}
|
|
|
|
[strongSelf->_editingContext setTimer:value forItem:editableMediaItem];
|
|
} dismissed:^
|
|
{
|
|
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
|
if (strongSelf != nil)
|
|
[strongSelf->_interfaceView setAllInterfaceHidden:false delay:0.0f animated:true];
|
|
} sourceView:controller.view sourceRect:^CGRect
|
|
{
|
|
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return CGRectZero;
|
|
|
|
__strong TGModernGalleryController *controller = strongSelf.controller;
|
|
return [strongSelf->_interfaceView.timerButton convertRect:strongSelf->_interfaceView.timerButton.bounds toView:controller.view];
|
|
}];
|
|
};
|
|
|
|
if (@available(iOS 11.0, *)) {
|
|
_interfaceView.accessibilityIgnoresInvertColors = true;
|
|
}
|
|
}
|
|
return _interfaceView;
|
|
}
|
|
|
|
- (UIView *)referenceViewForItem:(id<TGModernGalleryItem>)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;
|
|
}
|
|
}
|
|
else if ([galleryItemView isKindOfClass:[TGMediaPickerGalleryVideoItemView class]])
|
|
{
|
|
TGMediaPickerGalleryVideoItemView *videoItemView = (TGMediaPickerGalleryVideoItemView *)galleryItemView;
|
|
|
|
if (frame != NULL)
|
|
*frame = [videoItemView transitionViewContentRect];
|
|
|
|
return (UIView *)videoItemView;
|
|
}
|
|
|
|
return nil;
|
|
}
|
|
|
|
- (void)updateHiddenItem
|
|
{
|
|
TGModernGalleryController *galleryController = self.controller;
|
|
|
|
for (TGModernGalleryItemView *itemView in galleryController.visibleItemViews)
|
|
{
|
|
if ([itemView conformsToProtocol:@protocol(TGModernGalleryEditableItemView)])
|
|
[(TGModernGalleryItemView <TGModernGalleryEditableItemView> *)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 <TGModernGalleryEditableItemView> *)itemView setItem:_itemBeingEdited synchronously:true];
|
|
if (self.itemsUpdated != nil)
|
|
self.itemsUpdated(_itemBeingEdited);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)presentPhotoEditorForItem:(id<TGModernGalleryEditableItem>)item tab:(TGPhotoEditorTab)tab
|
|
{
|
|
[self presentPhotoEditorForItem:item tab:tab snapshots:@[] fromRect:CGRectZero];
|
|
}
|
|
|
|
- (void)presentPhotoEditorForItem:(id<TGModernGalleryEditableItem>)item tab:(TGPhotoEditorTab)tab snapshots:(NSArray *)snapshots fromRect:(CGRect)fromRect
|
|
{
|
|
__weak TGMediaPickerGalleryModel *weakSelf = self;
|
|
|
|
if (_itemBeingEdited != nil)
|
|
return;
|
|
|
|
_itemBeingEdited = item;
|
|
|
|
id<TGMediaEditAdjustments> adjustments = [item.editingContext adjustmentsForItem:item.editableMediaItem];
|
|
|
|
NSAttributedString *caption = [item.editingContext captionForItem:item.editableMediaItem];
|
|
|
|
CGRect refFrame = CGRectZero;
|
|
UIView *editorReferenceView = [self referenceViewForItem:item frame:&refFrame];
|
|
if (!CGRectEqualToRect(fromRect, CGRectZero)) {
|
|
refFrame = fromRect;
|
|
}
|
|
UIView *referenceView = nil;
|
|
UIImage *screenImage = nil;
|
|
UIView *referenceParentView = nil;
|
|
UIImage *image = nil;
|
|
|
|
UIView<TGPhotoDrawingEntitiesView> *entitiesView = nil;
|
|
|
|
id<TGMediaEditableItem> editableMediaItem = item.editableMediaItem;
|
|
|
|
bool isVideo = false;
|
|
if ([editorReferenceView isKindOfClass:[UIImageView class]])
|
|
{
|
|
screenImage = [(UIImageView *)editorReferenceView image];
|
|
referenceView = editorReferenceView;
|
|
|
|
if ([editorReferenceView.subviews.firstObject.subviews.firstObject.subviews.firstObject conformsToProtocol:@protocol(TGPhotoDrawingEntitiesView)]) {
|
|
entitiesView = editorReferenceView.subviews.firstObject.subviews.firstObject.subviews.firstObject;
|
|
}
|
|
}
|
|
else if ([editorReferenceView isKindOfClass:[TGMediaPickerGalleryVideoItemView class]])
|
|
{
|
|
TGMediaPickerGalleryVideoItemView *videoItemView = (TGMediaPickerGalleryVideoItemView *)editorReferenceView;
|
|
[videoItemView prepareForEditing];
|
|
|
|
refFrame = [videoItemView editorTransitionViewRect];
|
|
screenImage = [videoItemView transitionImage];
|
|
image = [videoItemView screenImage];
|
|
referenceView = [[UIImageView alloc] initWithImage:screenImage];
|
|
referenceParentView = editorReferenceView;
|
|
|
|
entitiesView = [videoItemView entitiesView];
|
|
|
|
isVideo = true;
|
|
|
|
editableMediaItem = videoItemView.editableMediaItem;
|
|
}
|
|
|
|
if (self.useGalleryImageAsEditableItemImage && self.storeOriginalImageForItem != nil)
|
|
self.storeOriginalImageForItem(item.editableMediaItem, screenImage);
|
|
|
|
TGPhotoEditorControllerIntent intent = isVideo ? TGPhotoEditorControllerVideoIntent : TGPhotoEditorControllerGenericIntent;
|
|
TGPhotoEditorController *controller = [[TGPhotoEditorController alloc] initWithContext:_context item:editableMediaItem intent:intent adjustments:adjustments caption:caption screenImage:screenImage availableTabs:_interfaceView.currentTabs selectedTab:tab];
|
|
controller.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
controller.entitiesView = entitiesView;
|
|
controller.editingContext = _editingContext;
|
|
controller.stickersContext = _stickersContext;
|
|
self.editorController = controller;
|
|
controller.willFinishEditing = ^(id<TGMediaEditAdjustments> adjustments, id temporaryRep, bool hasChanges)
|
|
{
|
|
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return;
|
|
|
|
strongSelf->_itemBeingEdited = nil;
|
|
|
|
if (strongSelf.willFinishEditingItem != nil)
|
|
strongSelf.willFinishEditingItem(item.editableMediaItem, adjustments, temporaryRep, hasChanges);
|
|
};
|
|
|
|
void (^didFinishEditingItem)(id<TGMediaEditableItem>item, id<TGMediaEditAdjustments> adjustments, UIImage *resultImage, UIImage *thumbnailImage) = self.didFinishEditingItem;
|
|
controller.didFinishEditing = ^(id<TGMediaEditAdjustments> adjustments, UIImage *resultImage, UIImage *thumbnailImage, bool hasChanges, void(^commit)(void))
|
|
{
|
|
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
|
if (strongSelf == nil) {
|
|
TGLegacyLog(@"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(editableMediaItem, adjustments, resultImage, thumbnailImage);
|
|
}
|
|
}
|
|
|
|
if ([editorReferenceView isKindOfClass:[TGMediaPickerGalleryVideoItemView class]])
|
|
{
|
|
TGMediaPickerGalleryVideoItemView *videoItemView = (TGMediaPickerGalleryVideoItemView *)editorReferenceView;
|
|
[videoItemView setScrubbingPanelApperanceLocked:false];
|
|
[videoItemView presentScrubbingPanelAfterReload:hasChanges];
|
|
}
|
|
|
|
commit();
|
|
};
|
|
|
|
controller.didFinishRenderingFullSizeImage = ^(UIImage *image)
|
|
{
|
|
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return;
|
|
|
|
if (strongSelf.didFinishRenderingFullSizeImage != nil)
|
|
strongSelf.didFinishRenderingFullSizeImage(editableMediaItem, image);
|
|
};
|
|
|
|
controller.captionSet = ^(NSAttributedString *caption)
|
|
{
|
|
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return;
|
|
|
|
if (strongSelf.saveItemCaption != nil)
|
|
strongSelf.saveItemCaption(item.editableMediaItem, caption);
|
|
};
|
|
|
|
controller.requestToolbarsHidden = ^(bool hidden, bool animated)
|
|
{
|
|
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return;
|
|
|
|
[strongSelf.interfaceView setToolbarsHidden:hidden animated:animated];
|
|
};
|
|
|
|
controller.beginTransitionIn = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView)
|
|
{
|
|
__strong TGMediaPickerGalleryModel *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 TGMediaPickerGalleryModel *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, __unused bool saving)
|
|
{
|
|
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return nil;
|
|
|
|
[strongSelf.interfaceView editorTransitionOut];
|
|
|
|
CGRect refFrame;
|
|
UIView *referenceView = [strongSelf referenceViewForItem:item frame:&refFrame];
|
|
if ([referenceView isKindOfClass:[TGMediaPickerGalleryVideoItemView class]])
|
|
{
|
|
TGMediaPickerGalleryVideoItemView *videoItemView = (TGMediaPickerGalleryVideoItemView *)referenceView;
|
|
refFrame = [videoItemView editorTransitionViewRect];
|
|
UIImage *screenImage = [videoItemView transitionImage];
|
|
*parentView = referenceView;
|
|
referenceView = [[UIImageView alloc] initWithImage:screenImage];
|
|
}
|
|
|
|
*referenceFrame = refFrame;
|
|
|
|
return referenceView;
|
|
};
|
|
|
|
controller.finishedTransitionOut = ^(__unused bool saved)
|
|
{
|
|
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return;
|
|
|
|
if (strongSelf.editorClosed != nil)
|
|
strongSelf.editorClosed();
|
|
|
|
[strongSelf updateHiddenItem];
|
|
|
|
UIView *referenceView = [strongSelf referenceViewForItem:item frame:NULL];
|
|
if ([referenceView isKindOfClass:[TGMediaPickerGalleryVideoItemView class]])
|
|
[(TGMediaPickerGalleryVideoItemView *)referenceView returnFromEditing];
|
|
|
|
if (iosMajorVersion() >= 7)
|
|
[strongSelf.controller setNeedsStatusBarAppearanceUpdate];
|
|
else {
|
|
[_context setStatusBarHidden:false withAnimation:UIStatusBarAnimationNone];
|
|
}
|
|
|
|
if (@available(iOS 11.0, *)) {
|
|
[strongSelf.controller setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
|
|
}
|
|
};
|
|
|
|
controller.requestThumbnailImage = ^SSignal *(id<TGMediaEditableItem> editableItem)
|
|
{
|
|
return [editableItem thumbnailImageSignal];
|
|
};
|
|
|
|
controller.requestOriginalScreenSizeImage = ^SSignal *(id<TGMediaEditableItem> editableItem, NSTimeInterval position)
|
|
{
|
|
return [editableItem screenImageSignal:position];
|
|
};
|
|
|
|
controller.requestOriginalFullSizeImage = ^SSignal *(id<TGMediaEditableItem> editableItem, NSTimeInterval position)
|
|
{
|
|
if (editableItem.isVideo) {
|
|
if ([editableItem isKindOfClass:[TGMediaAsset class]]) {
|
|
return [TGMediaAssetImageSignals avAssetForVideoAsset:(TGMediaAsset *)editableItem allowNetworkAccess:true];
|
|
} else if ([editableItem isKindOfClass:[TGCameraCapturedVideo class]]) {
|
|
return ((TGCameraCapturedVideo *)editableItem).avAsset;
|
|
} else {
|
|
return [editableItem originalImageSignal:position];
|
|
}
|
|
} else {
|
|
return [editableItem originalImageSignal:position];
|
|
}
|
|
};
|
|
|
|
controller.requestAdjustments = ^id<TGMediaEditAdjustments> (id<TGMediaEditableItem> editableItem)
|
|
{
|
|
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
|
if (strongSelf != nil && strongSelf.requestAdjustments != nil)
|
|
return strongSelf.requestAdjustments(editableItem);
|
|
|
|
return nil;
|
|
};
|
|
|
|
controller.requestImage = ^
|
|
{
|
|
return image;
|
|
};
|
|
|
|
[self.controller addChildViewController:controller];
|
|
[self.controller.view addSubview:controller.view];
|
|
|
|
for (UIView *view in snapshots) {
|
|
[self.controller.view addSubview:view];
|
|
[UIView animateWithDuration:0.3 animations:^{
|
|
view.alpha = 0.0;
|
|
} completion:^(__unused BOOL finished) {
|
|
[view removeFromSuperview];
|
|
}];
|
|
}
|
|
}
|
|
|
|
- (void)_replaceItems:(NSArray *)items focusingOnItem:(id<TGModernGalleryItem>)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
|