Various UI fixes

This commit is contained in:
Ilya Laktyushin 2019-07-28 10:43:33 +02:00
parent a53de39bf5
commit 27bed10d32
71 changed files with 3798 additions and 3286 deletions

View File

@ -295,6 +295,7 @@ class NotificationService: UNNotificationServiceExtension {
var peerId: PeerId? var peerId: PeerId?
var messageId: Int32? var messageId: Int32?
var silent = false
if let msgId = dict["msg_id"] as? String { if let msgId = dict["msg_id"] as? String {
userInfo["msg_id"] = msgId userInfo["msg_id"] = msgId
@ -318,6 +319,9 @@ class NotificationService: UNNotificationServiceExtension {
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: id) peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: id)
} }
} }
if let silentValue = dict["silent"] as? String {
silent = silentValue == "1"
}
var attachment: ParsedMediaAttachment? var attachment: ParsedMediaAttachment?
var attachmentData: Data? var attachmentData: Data?
@ -412,6 +416,9 @@ class NotificationService: UNNotificationServiceExtension {
self.bestAttemptContent?.body = alert self.bestAttemptContent?.body = alert
} else if let alert = aps["alert"] as? [AnyHashable: Any] { } else if let alert = aps["alert"] as? [AnyHashable: Any] {
self.bestAttemptContent?.title = alert["title"] as? String ?? "" self.bestAttemptContent?.title = alert["title"] as? String ?? ""
if let title = self.bestAttemptContent?.title, !title.isEmpty && silent {
self.bestAttemptContent?.title = "\(title) 🔕"
}
self.bestAttemptContent?.subtitle = alert["subtitle"] as? String ?? "" self.bestAttemptContent?.subtitle = alert["subtitle"] as? String ?? ""
self.bestAttemptContent?.body = alert["body"] as? String ?? "" self.bestAttemptContent?.body = alert["body"] as? String ?? ""
} }

View File

@ -57,7 +57,7 @@
</AdditionalOptions> </AdditionalOptions>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "DebugHockeyapp" buildConfiguration = "DebugAppStoreLLC"
selectedDebuggerIdentifier = "" selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn" selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0" launchStyle = "0"
@ -67,8 +67,12 @@
debugServiceExtension = "internal" debugServiceExtension = "internal"
allowLocationSimulation = "YES" allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2"> launchAutomaticallySubstyle = "2">
<BuildableProductRunnable <RemoteRunnable
runnableDebuggingMode = "0"> runnableDebuggingMode = "0"
BundleIdentifier = "ph.telegra.Telegraph"
RemotePath = "/var/containers/Bundle/Application/55A21437-4A06-4605-92A7-D3EAFF455129/Telegram.app">
</RemoteRunnable>
<MacroExpansion>
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "D008599B1B28189D00EAF753" BlueprintIdentifier = "D008599B1B28189D00EAF753"
@ -76,7 +80,7 @@
BlueprintName = "Telegram-iOS" BlueprintName = "Telegram-iOS"
ReferencedContainer = "container:Telegram-iOS.xcodeproj"> ReferencedContainer = "container:Telegram-iOS.xcodeproj">
</BuildableReference> </BuildableReference>
</BuildableProductRunnable> </MacroExpansion>
<AdditionalOptions> <AdditionalOptions>
</AdditionalOptions> </AdditionalOptions>
</LaunchAction> </LaunchAction>

View File

@ -4487,39 +4487,6 @@ Any member of this group will be able to see messages in the channel.";
"Chat.MultipleTextMessagesDisabled" = "Slowmode is enabled. You can't send multiple messages at once."; "Chat.MultipleTextMessagesDisabled" = "Slowmode is enabled. You can't send multiple messages at once.";
"StickerPacksSettings.AnimatedStickersInfo" = "Animated stickers in a chat will play continuously."; "StickerPacksSettings.AnimatedStickersInfo" = "Animated stickers in a chat will play continuously.";
"Appearance.ThemePreview.ChatList.1.Name" = "Eva Summer";
"Appearance.ThemePreview.ChatList.1.Text" = "Text";
"Appearance.ThemePreview.ChatList.2.Name" = "Your inner Competition";
"Appearance.ThemePreview.ChatList.2.Text" = "Hey";
"Appearance.ThemePreview.ChatList.3.Name" = "Mike Apple";
"Appearance.ThemePreview.ChatList.3.Text" = "Mike Apple";
"Appearance.ThemePreview.ChatList.4.Name" = "Paul Newman";
"Appearance.ThemePreview.ChatList.4.Text" = "Any ideas?";
"Appearance.ThemePreview.ChatList.5.Name" = "Old Pirates";
"Appearance.ThemePreview.ChatList.5.Text" = "Yo-ho-ho";
"Appearance.ThemePreview.ChatList.6.Name" = "Kate Bright";
"Appearance.ThemePreview.ChatList.6.Text" = "Hola!";
"Appearance.ThemePreview.ChatList.7.Name" = "What";
"Appearance.ThemePreview.ChatList.7.Text" = "Hola!";
"Appearance.ThemePreview.ChatList.8.Name" = "What";
"Appearance.ThemePreview.ChatList.8.Text" = "Hola!";
"Appearance.ThemePreview.Chat.1.Text" = "Reminds me of a Chinese proverb: the best time to plant a tree was 20 years ago. The second best time is now.";
"Appearance.ThemePreview.Chat.1.ReplyName" = "Alex Cassio";
"Appearance.ThemePreview.Chat.1.ReplyText" = "Mark Twain said that ☝️";
"Appearance.ThemePreview.Chat.2.Text" = "Mark Twain said that ☝️";
"Appearance.ThemePreview.Chat.3.Text" = "Twenty years from now you will be more disappointed by the things that you didn't do than by the ones you did do, so throw off the bowlines, sail away from safe harboor, catch the trade winds in your sails.";
"Appearance.ThemePreview.Chat.4.Text" = "Nearly missed the sunrise.";
"Conversation.Owner" = "owner"; "Conversation.Owner" = "owner";
"Group.EditAdmin.RankTitle" = "CUSTOM TITLE"; "Group.EditAdmin.RankTitle" = "CUSTOM TITLE";
@ -4528,3 +4495,6 @@ Any member of this group will be able to see messages in the channel.";
"Group.EditAdmin.RankAdminPlaceholder" = "admin"; "Group.EditAdmin.RankAdminPlaceholder" = "admin";
"Conversation.SendMessage.SendSilently" = "Send Without Sound"; "Conversation.SendMessage.SendSilently" = "Send Without Sound";
"Appearance.ThemeCarouselTintedNight" = "Tinted Night";
"Appearance.ThemeCarouselNewNight" = "Night";

View File

@ -1,5 +1,6 @@
import Foundation import Foundation
import UIKit import UIKit
import AudioToolbox
public enum ImpactHapticFeedbackStyle: Hashable { public enum ImpactHapticFeedbackStyle: Hashable {
case light case light
@ -13,35 +14,77 @@ private final class HapticFeedbackImpl {
[.light: UIImpactFeedbackGenerator(style: .light), [.light: UIImpactFeedbackGenerator(style: .light),
.medium: UIImpactFeedbackGenerator(style: .medium), .medium: UIImpactFeedbackGenerator(style: .medium),
.heavy: UIImpactFeedbackGenerator(style: .heavy)] }() .heavy: UIImpactFeedbackGenerator(style: .heavy)] }()
private lazy var selectionGenerator = { UISelectionFeedbackGenerator() }()
private lazy var notificationGenerator = { UINotificationFeedbackGenerator() }() private lazy var selectionGenerator: UISelectionFeedbackGenerator? = {
let generator = UISelectionFeedbackGenerator()
generator.prepare()
var string = generator.debugDescription
string.removeLast()
let number = string.suffix(1)
if number == "1" {
return generator
} else {
return nil
}
}()
private lazy var notificationGenerator: UINotificationFeedbackGenerator? = {
let generator = UINotificationFeedbackGenerator()
generator.prepare()
var string = generator.debugDescription
string.removeLast()
let number = string.suffix(1)
if number == "1" {
return generator
} else {
return nil
}
}()
func prepareTap() { func prepareTap() {
self.selectionGenerator.prepare() if let selectionGenerator = self.selectionGenerator {
selectionGenerator.prepare()
}
} }
func tap() { func tap() {
self.selectionGenerator.selectionChanged() if let selectionGenerator = self.selectionGenerator {
selectionGenerator.selectionChanged()
}
} }
func prepareImpact(_ style: ImpactHapticFeedbackStyle) { func prepareImpact(_ style: ImpactHapticFeedbackStyle) {
self.impactGenerator[style]?.prepare() if let impactGenerator = self.impactGenerator[style] {
impactGenerator.prepare()
}
} }
func impact(_ style: ImpactHapticFeedbackStyle) { func impact(_ style: ImpactHapticFeedbackStyle) {
self.impactGenerator[style]?.impactOccurred() if let impactGenerator = self.impactGenerator[style] {
impactGenerator.impactOccurred()
}
} }
func success() { func success() {
self.notificationGenerator.notificationOccurred(.success) if let notificationGenerator = self.notificationGenerator {
notificationGenerator.notificationOccurred(.success)
} else {
AudioServicesPlaySystemSound(1520)
}
} }
func prepareError() { func prepareError() {
self.notificationGenerator.prepare() if let notificationGenerator = self.notificationGenerator {
notificationGenerator.prepare()
}
} }
func error() { func error() {
self.notificationGenerator.notificationOccurred(.error) if let notificationGenerator = self.notificationGenerator {
notificationGenerator.notificationOccurred(.error)
} else {
AudioServicesPlaySystemSound(1521)
}
} }
@objc dynamic func f() { @objc dynamic func f() {

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -28,12 +28,13 @@
@property (nonatomic) bool asFile; @property (nonatomic) bool asFile;
@property (nonatomic) bool inhibitMute; @property (nonatomic) bool inhibitMute;
@property (nonatomic) bool disableStickers; @property (nonatomic) bool disableStickers;
@property (nonatomic) bool hasSilentPosting;
@property (nonatomic, strong) NSArray *underlyingViews; @property (nonatomic, strong) NSArray *underlyingViews;
@property (nonatomic, assign) bool openEditor; @property (nonatomic, assign) bool openEditor;
@property (nonatomic, copy) void (^cameraPressed)(TGAttachmentCameraView *cameraView); @property (nonatomic, copy) void (^cameraPressed)(TGAttachmentCameraView *cameraView);
@property (nonatomic, copy) void (^sendPressed)(TGMediaAsset *currentItem, bool asFiles); @property (nonatomic, copy) void (^sendPressed)(TGMediaAsset *currentItem, bool asFiles, bool silentPosting);
@property (nonatomic, copy) void (^avatarCompletionBlock)(UIImage *image); @property (nonatomic, copy) void (^avatarCompletionBlock)(UIImage *image);
@property (nonatomic, copy) void (^editorOpened)(void); @property (nonatomic, copy) void (^editorOpened)(void);

View File

@ -264,7 +264,7 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500;
{ {
if (strongSelf->_selectionContext.allowGrouping) if (strongSelf->_selectionContext.allowGrouping)
[[NSUserDefaults standardUserDefaults] setObject:@(!strongSelf->_selectionContext.grouping) forKey:@"TG_mediaGroupingDisabled_v0"]; [[NSUserDefaults standardUserDefaults] setObject:@(!strongSelf->_selectionContext.grouping) forKey:@"TG_mediaGroupingDisabled_v0"];
strongSelf.sendPressed(nil, false); strongSelf.sendPressed(nil, false, false);
} }
}]; }];
[_sendMediaItemView setHidden:true animated:false]; [_sendMediaItemView setHidden:true animated:false];
@ -276,7 +276,7 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500;
{ {
__strong TGAttachmentCarouselItemView *strongSelf = weakSelf; __strong TGAttachmentCarouselItemView *strongSelf = weakSelf;
if (strongSelf != nil && strongSelf.sendPressed != nil) if (strongSelf != nil && strongSelf.sendPressed != nil)
strongSelf.sendPressed(nil, true); strongSelf.sendPressed(nil, true, false);
}]; }];
_sendFileItemView.requiresDivider = false; _sendFileItemView.requiresDivider = false;
[_sendFileItemView setHidden:true animated:false]; [_sendFileItemView setHidden:true animated:false];
@ -774,14 +774,14 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500;
strongSelf->_galleryMixin = nil; strongSelf->_galleryMixin = nil;
}; };
mixin.completeWithItem = ^(TGMediaPickerGalleryItem *item) mixin.completeWithItem = ^(TGMediaPickerGalleryItem *item, bool silentPosting)
{ {
__strong TGAttachmentCarouselItemView *strongSelf = weakSelf; __strong TGAttachmentCarouselItemView *strongSelf = weakSelf;
if (strongSelf != nil && strongSelf.sendPressed != nil) if (strongSelf != nil && strongSelf.sendPressed != nil)
{ {
if (strongSelf->_selectionContext.allowGrouping) if (strongSelf->_selectionContext.allowGrouping)
[[NSUserDefaults standardUserDefaults] setObject:@(!strongSelf->_selectionContext.grouping) forKey:@"TG_mediaGroupingDisabled_v0"]; [[NSUserDefaults standardUserDefaults] setObject:@(!strongSelf->_selectionContext.grouping) forKey:@"TG_mediaGroupingDisabled_v0"];
strongSelf.sendPressed(item.asset, strongSelf.asFile); strongSelf.sendPressed(item.asset, strongSelf.asFile, silentPosting);
} }
}; };
@ -801,7 +801,7 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500;
if ([cell isKindOfClass:[TGAttachmentAssetCell class]]) if ([cell isKindOfClass:[TGAttachmentAssetCell class]])
thumbnailImage = cell.imageView.image; 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]; 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];
__weak TGAttachmentCarouselItemView *weakSelf = self; __weak TGAttachmentCarouselItemView *weakSelf = self;
mixin.thumbnailSignalForItem = ^SSignal *(id item) mixin.thumbnailSignalForItem = ^SSignal *(id item)

View File

@ -35,6 +35,7 @@ typedef enum {
@property (nonatomic, assign) bool inhibitMultipleCapture; @property (nonatomic, assign) bool inhibitMultipleCapture;
@property (nonatomic, assign) bool inhibitMute; @property (nonatomic, assign) bool inhibitMute;
@property (nonatomic, assign) bool hasTimer; @property (nonatomic, assign) bool hasTimer;
@property (nonatomic, assign) bool hasSilentPosting;
@property (nonatomic, strong) TGSuggestionContext *suggestionContext; @property (nonatomic, strong) TGSuggestionContext *suggestionContext;
@property (nonatomic, assign) bool shortcut; @property (nonatomic, assign) bool shortcut;

View File

@ -1620,6 +1620,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
controller.shouldStoreAssets = self.shouldStoreCapturedAssets; controller.shouldStoreAssets = self.shouldStoreCapturedAssets;
controller.suggestionContext = self.suggestionContext; controller.suggestionContext = self.suggestionContext;
controller.hasTimer = self.hasTimer; controller.hasTimer = self.hasTimer;
controller.hasSilentPosting = self.hasSilentPosting;
__weak TGCameraPhotoPreviewController *weakController = controller; __weak TGCameraPhotoPreviewController *weakController = controller;
controller.beginTransitionIn = ^CGRect controller.beginTransitionIn = ^CGRect

View File

@ -23,6 +23,7 @@
@property (nonatomic, strong) TGSuggestionContext *suggestionContext; @property (nonatomic, strong) TGSuggestionContext *suggestionContext;
@property (nonatomic, assign) bool shouldStoreAssets; @property (nonatomic, assign) bool shouldStoreAssets;
@property (nonatomic, assign) bool hasTimer; @property (nonatomic, assign) bool hasTimer;
@property (nonatomic, assign) bool hasSilentPosting;
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context image:(UIImage *)image metadata:(PGCameraShotMetadata *)metadata recipientName:(NSString *)recipientName saveCapturedMedia:(bool)saveCapturedMedia saveEditedPhotos:(bool)saveEditedPhotos; - (instancetype)initWithContext:(id<LegacyComponentsContext>)context image:(UIImage *)image metadata:(PGCameraShotMetadata *)metadata recipientName:(NSString *)recipientName saveCapturedMedia:(bool)saveCapturedMedia saveEditedPhotos:(bool)saveEditedPhotos;
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context image:(UIImage *)image metadata:(PGCameraShotMetadata *)metadata recipientName:(NSString *)recipientName backButtonTitle:(NSString *)backButtonTitle doneButtonTitle:(NSString *)doneButtonTitle saveCapturedMedia:(bool)saveCapturedMedia saveEditedPhotos:(bool)saveEditedPhotos; - (instancetype)initWithContext:(id<LegacyComponentsContext>)context image:(UIImage *)image metadata:(PGCameraShotMetadata *)metadata recipientName:(NSString *)recipientName backButtonTitle:(NSString *)backButtonTitle doneButtonTitle:(NSString *)doneButtonTitle saveCapturedMedia:(bool)saveCapturedMedia saveEditedPhotos:(bool)saveEditedPhotos;

View File

@ -255,9 +255,6 @@ const CGFloat TGClipboardPreviewEdgeInset = 8.0f;
if (strongSelf != nil && strongSelf.sendPressed != nil) if (strongSelf != nil && strongSelf.sendPressed != nil)
strongSelf.sendPressed(item.image); strongSelf.sendPressed(item.image);
}; };
//mixin.editorOpened = self.editorOpened;
//mixin.editorClosed = self.editorClosed;
} }
- (TGClipboardGalleryMixin *)galleryMixinForIndexPath:(NSIndexPath *)indexPath - (TGClipboardGalleryMixin *)galleryMixinForIndexPath:(NSIndexPath *)indexPath

View File

@ -55,6 +55,7 @@ typedef enum
@property (nonatomic, assign) bool hasTimer; @property (nonatomic, assign) bool hasTimer;
@property (nonatomic, assign) bool onlyCrop; @property (nonatomic, assign) bool onlyCrop;
@property (nonatomic, assign) bool inhibitMute; @property (nonatomic, assign) bool inhibitMute;
@property (nonatomic, assign) bool hasSilentPosting;
@property (nonatomic, assign) bool liveVideoUploadEnabled; @property (nonatomic, assign) bool liveVideoUploadEnabled;
@property (nonatomic, assign) bool shouldShowFileTipIfNeeded; @property (nonatomic, assign) bool shouldShowFileTipIfNeeded;
@ -63,7 +64,7 @@ typedef enum
@property (nonatomic, copy) NSDictionary *(^descriptionGenerator)(id, NSString *, NSArray *, NSString *); @property (nonatomic, copy) NSDictionary *(^descriptionGenerator)(id, NSString *, NSArray *, NSString *);
@property (nonatomic, copy) void (^avatarCompletionBlock)(UIImage *image); @property (nonatomic, copy) void (^avatarCompletionBlock)(UIImage *image);
@property (nonatomic, copy) void (^completionBlock)(NSArray *signals); @property (nonatomic, copy) void (^completionBlock)(NSArray *signals, bool silentPosting);
@property (nonatomic, copy) void (^singleCompletionBlock)(id<TGMediaEditableItem> item, TGMediaEditingContext *editingContext); @property (nonatomic, copy) void (^singleCompletionBlock)(id<TGMediaEditableItem> item, TGMediaEditingContext *editingContext);
@property (nonatomic, copy) void (^dismissalBlock)(void); @property (nonatomic, copy) void (^dismissalBlock)(void);
@property (nonatomic, copy) void (^selectionBlock)(TGMediaAsset *asset, UIImage *); @property (nonatomic, copy) void (^selectionBlock)(TGMediaAsset *asset, UIImage *);
@ -81,7 +82,7 @@ typedef enum
- (NSArray *)resultSignalsWithCurrentItem:(TGMediaAsset *)currentItem descriptionGenerator:(id (^)(id, NSString *, NSArray *, NSString *))descriptionGenerator; - (NSArray *)resultSignalsWithCurrentItem:(TGMediaAsset *)currentItem descriptionGenerator:(id (^)(id, NSString *, NSArray *, NSString *))descriptionGenerator;
- (void)completeWithAvatarImage:(UIImage *)image; - (void)completeWithAvatarImage:(UIImage *)image;
- (void)completeWithCurrentItem:(TGMediaAsset *)currentItem; - (void)completeWithCurrentItem:(TGMediaAsset *)currentItem silentPosting:(bool)silentPosting;
- (void)dismiss; - (void)dismiss;

View File

@ -121,6 +121,7 @@
pickerController.recipientName = recipientName; pickerController.recipientName = recipientName;
pickerController.hasTimer = strongController.hasTimer; pickerController.hasTimer = strongController.hasTimer;
pickerController.onlyCrop = strongController.onlyCrop; pickerController.onlyCrop = strongController.onlyCrop;
pickerController.hasSilentPosting = strongController.hasSilentPosting;
[strongController pushViewController:pickerController animated:true]; [strongController pushViewController:pickerController animated:true];
}; };
[groupsController loadViewIfNeeded]; [groupsController loadViewIfNeeded];
@ -200,6 +201,12 @@
self.pickerController.hasTimer = hasTimer; self.pickerController.hasTimer = hasTimer;
} }
- (void)setHasSilentPosting:(bool)hasSilentPosting
{
_hasSilentPosting = hasSilentPosting;
self.pickerController.hasSilentPosting = hasSilentPosting;
}
- (void)setOnlyCrop:(bool)onlyCrop - (void)setOnlyCrop:(bool)onlyCrop
{ {
_onlyCrop = onlyCrop; _onlyCrop = onlyCrop;
@ -444,7 +451,7 @@
{ {
__strong TGMediaAssetsController *strongSelf = weakSelf; __strong TGMediaAssetsController *strongSelf = weakSelf;
if (strongSelf != nil) if (strongSelf != nil)
[strongSelf completeWithCurrentItem:nil]; [strongSelf completeWithCurrentItem:nil silentPosting:false];
}; };
} }
@ -525,12 +532,12 @@
self.avatarCompletionBlock(image); self.avatarCompletionBlock(image);
} }
- (void)completeWithCurrentItem:(TGMediaAsset *)currentItem - (void)completeWithCurrentItem:(TGMediaAsset *)currentItem silentPosting:(bool)silentPosting
{ {
if (self.completionBlock != nil) if (self.completionBlock != nil)
{ {
NSArray *signals = [self resultSignalsWithCurrentItem:currentItem descriptionGenerator:self.descriptionGenerator]; NSArray *signals = [self resultSignalsWithCurrentItem:currentItem descriptionGenerator:self.descriptionGenerator];
self.completionBlock(signals); self.completionBlock(signals, silentPosting);
} }
else if (self.singleCompletionBlock != nil) else if (self.singleCompletionBlock != nil)
{ {

View File

@ -124,7 +124,7 @@
- (TGMediaPickerModernGalleryMixin *)_galleryMixinForItem:(id)item thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaption allowCaptionEntities:(bool)allowCaptionEntities asFile:(bool)asFile - (TGMediaPickerModernGalleryMixin *)_galleryMixinForItem:(id)item thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaption allowCaptionEntities:(bool)allowCaptionEntities asFile:(bool)asFile
{ {
return [[TGMediaPickerModernGalleryMixin alloc] initWithContext:_context item:item momentList:_momentList parentController:self thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext suggestionContext:suggestionContext hasCaptions:hasCaption allowCaptionEntities:allowCaptionEntities hasTimer:false onlyCrop:false inhibitDocumentCaptions:false inhibitMute:false asFile:asFile itemsLimit:0]; return [[TGMediaPickerModernGalleryMixin alloc] initWithContext:_context item:item momentList:_momentList parentController:self thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext suggestionContext:suggestionContext hasCaptions:hasCaption allowCaptionEntities:allowCaptionEntities hasTimer:false onlyCrop:false inhibitDocumentCaptions:false inhibitMute:false asFile:asFile itemsLimit:0 hasSilentPosting:false];
} }
- (id)_itemAtIndexPath:(NSIndexPath *)indexPath - (id)_itemAtIndexPath:(NSIndexPath *)indexPath

View File

@ -309,19 +309,19 @@
strongSelf->_galleryMixin = nil; strongSelf->_galleryMixin = nil;
}; };
mixin.completeWithItem = ^(TGMediaPickerGalleryItem *item) mixin.completeWithItem = ^(TGMediaPickerGalleryItem *item, bool silentPosting)
{ {
__strong TGMediaAssetsPickerController *strongSelf = weakSelf; __strong TGMediaAssetsPickerController *strongSelf = weakSelf;
if (strongSelf == nil) if (strongSelf == nil)
return; return;
[(TGMediaAssetsController *)strongSelf.navigationController completeWithCurrentItem:item.asset]; [(TGMediaAssetsController *)strongSelf.navigationController completeWithCurrentItem:item.asset silentPosting:silentPosting];
}; };
} }
- (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 suggestionContext:(TGSuggestionContext *)suggestionContext 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]; 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];
} }
- (TGMediaPickerModernGalleryMixin *)galleryMixinForIndexPath:(NSIndexPath *)indexPath previewMode:(bool)previewMode outAsset:(TGMediaAsset **)outAsset - (TGMediaPickerModernGalleryMixin *)galleryMixinForIndexPath:(NSIndexPath *)indexPath previewMode:(bool)previewMode outAsset:(TGMediaAsset **)outAsset

View File

@ -27,6 +27,7 @@
@property (nonatomic, assign) bool onlyCrop; @property (nonatomic, assign) bool onlyCrop;
@property (nonatomic, assign) bool inhibitMute; @property (nonatomic, assign) bool inhibitMute;
@property (nonatomic, strong) NSString *recipientName; @property (nonatomic, strong) NSString *recipientName;
@property (nonatomic, assign) bool hasSilentPosting;
@property (nonatomic, strong) TGMediaAssetsPallete *pallete; @property (nonatomic, strong) TGMediaAssetsPallete *pallete;

View File

@ -14,6 +14,7 @@
@property (nonatomic, copy) void (^captionSet)(id<TGModernGalleryItem>, NSString *, NSArray *); @property (nonatomic, copy) void (^captionSet)(id<TGModernGalleryItem>, NSString *, NSArray *);
@property (nonatomic, copy) void (^donePressed)(id<TGModernGalleryItem>); @property (nonatomic, copy) void (^donePressed)(id<TGModernGalleryItem>);
@property (nonatomic, copy) void (^doneLongPressed)(id<TGModernGalleryItem>);
@property (nonatomic, copy) void (^photoStripItemSelected)(NSInteger index); @property (nonatomic, copy) void (^photoStripItemSelected)(NSInteger index);
@ -32,6 +33,7 @@
@property (nonatomic, assign) bool capturing; @property (nonatomic, assign) bool capturing;
@property (nonatomic, readonly) TGPhotoEditorTab currentTabs; @property (nonatomic, readonly) TGPhotoEditorTab currentTabs;
@property (nonatomic, readonly) CGRect doneButtonFrame;
@property (nonatomic, readonly) UIView *timerButton; @property (nonatomic, readonly) UIView *timerButton;

View File

@ -137,9 +137,19 @@
if (strongSelf == nil) if (strongSelf == nil)
return; return;
[strongSelf.window endEditing:true]; [strongSelf.window endEditing:true];
strongSelf->_donePressed(strongSelf->_currentItem); strongSelf->_donePressed(strongSelf->_currentItem);
}; };
void(^toolbarDoneLongPressed)(id) = ^(id sender)
{
__strong TGMediaPickerGalleryInterfaceView *strongSelf = weakSelf;
if (strongSelf == nil)
return;
[strongSelf.window endEditing:true];
if (strongSelf->_doneLongPressed != nil)
strongSelf->_doneLongPressed(strongSelf->_currentItem);
};
_muteButton = [[TGModernButton alloc] initWithFrame:CGRectMake(0, 0, 39.0f, 39.0f)]; _muteButton = [[TGModernButton alloc] initWithFrame:CGRectMake(0, 0, 39.0f, 39.0f)];
_muteButton.hidden = true; _muteButton.hidden = true;
@ -342,11 +352,13 @@
_portraitToolbarView = [[TGPhotoToolbarView alloc] initWithBackButton:TGPhotoEditorBackButtonBack doneButton:TGPhotoEditorDoneButtonSend solidBackground:false]; _portraitToolbarView = [[TGPhotoToolbarView alloc] initWithBackButton:TGPhotoEditorBackButtonBack doneButton:TGPhotoEditorDoneButtonSend solidBackground:false];
_portraitToolbarView.cancelPressed = toolbarCancelPressed; _portraitToolbarView.cancelPressed = toolbarCancelPressed;
_portraitToolbarView.donePressed = toolbarDonePressed; _portraitToolbarView.donePressed = toolbarDonePressed;
_portraitToolbarView.doneLongPressed = toolbarDoneLongPressed;
[_wrapperView addSubview:_portraitToolbarView]; [_wrapperView addSubview:_portraitToolbarView];
_landscapeToolbarView = [[TGPhotoToolbarView alloc] initWithBackButton:TGPhotoEditorBackButtonBack doneButton:TGPhotoEditorDoneButtonSend solidBackground:false]; _landscapeToolbarView = [[TGPhotoToolbarView alloc] initWithBackButton:TGPhotoEditorBackButtonBack doneButton:TGPhotoEditorDoneButtonSend solidBackground:false];
_landscapeToolbarView.cancelPressed = toolbarCancelPressed; _landscapeToolbarView.cancelPressed = toolbarCancelPressed;
_landscapeToolbarView.donePressed = toolbarDonePressed; _landscapeToolbarView.donePressed = toolbarDonePressed;
_landscapeToolbarView.doneLongPressed = toolbarDoneLongPressed;
[_wrapperView addSubview:_landscapeToolbarView]; [_wrapperView addSubview:_landscapeToolbarView];
} }
return self; return self;
@ -1736,4 +1748,12 @@
itemFooterView.frame = itemFooterViewFrame; itemFooterView.frame = itemFooterViewFrame;
} }
- (CGRect)doneButtonFrame {
if (UIDeviceOrientationIsPortrait([self interfaceOrientation])) {
return [_portraitToolbarView.doneButton convertRect:_portraitToolbarView.doneButton.bounds toView:nil];
} else {
return [_landscapeToolbarView.doneButton convertRect:_landscapeToolbarView.doneButton.bounds toView:nil];
}
}
@end @end

View File

@ -22,14 +22,14 @@
@property (nonatomic, copy) void (^didTransitionOut)(); @property (nonatomic, copy) void (^didTransitionOut)();
@property (nonatomic, copy) UIView *(^referenceViewForItem)(TGMediaPickerGalleryItem *); @property (nonatomic, copy) UIView *(^referenceViewForItem)(TGMediaPickerGalleryItem *);
@property (nonatomic, copy) void (^completeWithItem)(TGMediaPickerGalleryItem *item); @property (nonatomic, copy) void (^completeWithItem)(TGMediaPickerGalleryItem *item, bool silentPosting);
@property (nonatomic, copy) void (^editorOpened)(void); @property (nonatomic, copy) void (^editorOpened)(void);
@property (nonatomic, copy) void (^editorClosed)(void); @property (nonatomic, copy) void (^editorClosed)(void);
- (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; - (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;
- (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; - (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;
- (void)present; - (void)present;
- (void)updateWithFetchResult:(TGMediaAssetFetchResult *)fetchResult; - (void)updateWithFetchResult:(TGMediaAssetFetchResult *)fetchResult;

View File

@ -9,6 +9,8 @@
#import "TGMediaPickerGalleryVideoItemView.h" #import "TGMediaPickerGalleryVideoItemView.h"
#import "TGMediaPickerGalleryGifItem.h" #import "TGMediaPickerGalleryGifItem.h"
#import "TGMediaPickerSendActionSheetController.h"
#import <LegacyComponents/TGMediaEditingContext.h> #import <LegacyComponents/TGMediaEditingContext.h>
#import <LegacyComponents/TGMediaSelectionContext.h> #import <LegacyComponents/TGMediaSelectionContext.h>
#import <LegacyComponents/TGSuggestionContext.h> #import <LegacyComponents/TGSuggestionContext.h>
@ -37,17 +39,17 @@
@implementation TGMediaPickerModernGalleryMixin @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 - (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
{ {
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]; 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];
} }
- (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 - (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
{ {
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]; 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];
} }
- (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 - (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
{ {
self = [super init]; self = [super init];
if (self != nil) if (self != nil)
@ -134,7 +136,41 @@
strongSelf->_galleryModel.dismiss(true, false); strongSelf->_galleryModel.dismiss(true, false);
if (strongSelf.completeWithItem != nil) if (strongSelf.completeWithItem != nil)
strongSelf.completeWithItem(item); strongSelf.completeWithItem(item, false);
};
model.interfaceView.doneLongPressed = ^(TGMediaPickerGalleryItem *item) {
__strong TGMediaPickerModernGalleryMixin *strongSelf = weakSelf;
if (strongSelf == nil || !hasSilentPosting)
return;
UIImpactFeedbackGenerator *generator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium];
[generator impactOccurred];
TGMediaPickerSendActionSheetController *controller = [[TGMediaPickerSendActionSheetController alloc] initWithContext:strongSelf->_context sendButtonFrame:strongSelf.galleryModel.interfaceView.doneButtonFrame];
controller.send = ^{
__strong TGMediaPickerModernGalleryMixin *strongSelf = weakSelf;
if (strongSelf == nil)
return;
strongSelf->_galleryModel.dismiss(true, false);
if (strongSelf.completeWithItem != nil)
strongSelf.completeWithItem(item, false);
};
controller.sendSilently = ^{
__strong TGMediaPickerModernGalleryMixin *strongSelf = weakSelf;
if (strongSelf == nil)
return;
strongSelf->_galleryModel.dismiss(true, false);
if (strongSelf.completeWithItem != nil)
strongSelf.completeWithItem(item, true);
};
TGOverlayControllerWindow *controllerWindow = [[TGOverlayControllerWindow alloc] initWithManager:[strongSelf->_context makeOverlayWindowManager] parentController:strongSelf->_parentController contentController:controller];
controllerWindow.hidden = false;
}; };
modernGallery.model = model; modernGallery.model = model;

View File

@ -0,0 +1,14 @@
#import <LegacyComponents/TGOverlayController.h>
NS_ASSUME_NONNULL_BEGIN
@interface TGMediaPickerSendActionSheetController : TGOverlayController
@property (nonatomic, copy) void (^send)(void);
@property (nonatomic, copy) void (^sendSilently)(void);
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context sendButtonFrame:(CGRect)sendButtonFrame;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,202 @@
#import "TGMediaPickerSendActionSheetController.h"
#import "LegacyComponentsInternal.h"
#import "TGFont.h"
#import "TGImageUtils.h"
#import "TGModernButton.h"
#import "TGMediaAssetsController.h"
@interface TGMediaPickerSendActionSheetController ()
{
id<LegacyComponentsContext> _context;
CGRect _sendButtonFrame;
bool _autorotationWasEnabled;
UIVisualEffectView *_effectView;
TGModernButton *_sendButton;
UIView *_containerView;
TGModernButton *_buttonView;
UILabel *_buttonLabel;
UIImageView *_buttonIcon;
}
@end
@implementation TGMediaPickerSendActionSheetController
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context sendButtonFrame:(CGRect)sendButtonFrame {
self = [super initWithContext:context];
if (self != nil) {
_context = context;
_sendButtonFrame = sendButtonFrame;
}
return self;
}
- (void)loadView {
[super loadView];
_effectView = [[UIVisualEffectView alloc] initWithEffect:nil];
if (iosMajorVersion() >= 9) {
_effectView.effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
}
[self.view addSubview:_effectView];
_containerView = [[UIView alloc] init];
_containerView.backgroundColor = UIColorRGB(0x1f1f1f);
_containerView.clipsToBounds = true;
_containerView.layer.cornerRadius = 12.0;
[self.view addSubview:_containerView];
__weak TGMediaPickerSendActionSheetController *weakSelf = self;
_buttonView = [[TGModernButton alloc] init];
_buttonView.adjustsImageWhenHighlighted = false;
_buttonView.highlitedChanged = ^(bool highlighted) {
__strong TGMediaPickerSendActionSheetController *strongSelf = weakSelf;
if (strongSelf != nil) {
if (highlighted) {
strongSelf->_buttonView.backgroundColor = UIColorRGB(0x363636);
} else {
strongSelf->_buttonView.backgroundColor = [UIColor clearColor];
}
}
};
[_buttonView addTarget:self action:@selector(sendSilentlyPressed) forControlEvents:UIControlEventTouchUpInside];
[_containerView addSubview:_buttonView];
_buttonLabel = [[UILabel alloc] init];
_buttonLabel.font = TGSystemFontOfSize(17.0f);
_buttonLabel.text = TGLocalized(@"Conversation.SendMessage.SendSilently");
_buttonLabel.textColor = [UIColor whiteColor];
[_buttonLabel sizeToFit];
_buttonLabel.userInteractionEnabled = false;
[_containerView addSubview:_buttonLabel];
_buttonIcon = [[UIImageView alloc] init];
_buttonIcon.image = TGTintedImage(TGComponentsImageNamed(@"MediaMute"), [UIColor whiteColor]);
[_buttonIcon sizeToFit];
[_containerView addSubview:_buttonIcon];
TGMediaAssetsPallete *pallete = nil;
if ([[LegacyComponentsGlobals provider] respondsToSelector:@selector(mediaAssetsPallete)])
pallete = [[LegacyComponentsGlobals provider] mediaAssetsPallete];
UIImage *doneImage = pallete != nil ? pallete.sendIconImage : TGComponentsImageNamed(@"PhotoPickerSendIcon");
_sendButton = [[TGModernButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 33.0, 33.0)];
_sendButton.adjustsImageWhenDisabled = false;
_sendButton.adjustsImageWhenHighlighted = false;
[_sendButton setImage:doneImage forState:UIControlStateNormal];
[_sendButton addTarget:self action:@selector(sendPressed) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_sendButton];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
_autorotationWasEnabled = [TGViewController autorotationAllowed];
[TGViewController disableAutorotation];
[self animateIn];
}
- (void)viewDidLoad {
[super viewDidLoad];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] init];
[tapRecognizer addTarget:self action:@selector(dimTapGesture)];
[_effectView addGestureRecognizer:tapRecognizer];
}
- (void)dimTapGesture {
[self animateOut:true];
}
- (BOOL)prefersStatusBarHidden {
return true;
}
- (bool)statusBarShouldBeHidden {
return true;
}
- (void)animateIn {
if (_effectView.effect != nil) {
_effectView.alpha = 0.0f;
}
[UIView animateWithDuration:0.3 animations:^{
if (_effectView.effect == nil) {
_effectView.effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
} else {
_effectView.alpha = 1.0f;
}
}];
CGPoint targetPosition = _containerView.center;
_containerView.center = CGPointMake(targetPosition.x + 160.0, targetPosition.y + 44.0);
[UIView animateWithDuration:0.3 delay:0.0 options:7 << 16 animations:^{
_containerView.center = targetPosition;
} completion:nil];
_containerView.alpha = 0.0f;
[UIView animateWithDuration:0.3 animations:^{
_containerView.alpha = 1.0f;
}];
}
- (void)animateOut:(bool)cancel {
[UIView animateWithDuration:0.3 animations:^{
if (iosMajorVersion() >= 9) {
_effectView.effect = nil;
} else {
_effectView.alpha = 0.0f;
}
_containerView.alpha = 0.0f;
} completion:^(BOOL finished) {
if (!cancel) {
[self dismiss];
}
}];
if (cancel) {
[UIView animateWithDuration:0.3 delay:0.0 options:7 << 16 animations:^{
_containerView.center = CGPointMake(_containerView.center.x + 160.0, _containerView.center.y + 44.0);
} completion:^(bool finished) {
[self dismiss];
}];
}
if (_autorotationWasEnabled) {
[TGViewController enableAutorotation];
}
}
- (void)viewDidLayoutSubviews {
_effectView.frame = self.view.bounds;
_sendButton.frame = _sendButtonFrame;
_buttonLabel.frame = CGRectMake(16.0, 11.0, _buttonLabel.frame.size.width, _buttonLabel.frame.size.height);
CGFloat containerWidth = MAX(240.0, _buttonLabel.frame.size.width + 84.0);
_containerView.frame = CGRectMake(CGRectGetMaxX(_sendButtonFrame) - containerWidth - 8.0, _sendButtonFrame.origin.y - 44.0 - 4.0, containerWidth, 44.0);
_buttonView.frame = _containerView.bounds;
_buttonIcon.frame = CGRectMake(_containerView.frame.size.width - _buttonIcon.frame.size.width - 12.0, 9.0, _buttonIcon.frame.size.width, _buttonIcon.frame.size.height);
}
- (void)sendPressed {
[self animateOut:false];
if (self.send != nil)
self.send();
}
- (void)sendSilentlyPressed {
[self animateOut:false];
if (self.sendSilently != nil)
self.sendSilently();
}
@end

View File

@ -67,7 +67,7 @@
[TGPassportAttachMenu _displayCameraWithView:cameraView menuController:strongController parentController:strongParentController context:context intent:intent uploadAction:uploadAction]; [TGPassportAttachMenu _displayCameraWithView:cameraView menuController:strongController parentController:strongParentController context:context intent:intent uploadAction:uploadAction];
}; };
carouselItem.sendPressed = ^(TGMediaAsset *currentItem, __unused bool asFiles) carouselItem.sendPressed = ^(TGMediaAsset *currentItem, __unused bool asFiles, __unused bool silentPosting)
{ {
__strong TGMenuSheetController *strongController = weakController; __strong TGMenuSheetController *strongController = weakController;
if (strongController == nil) if (strongController == nil)

View File

@ -75,7 +75,6 @@
pallete = [[LegacyComponentsGlobals provider] mediaAssetsPallete]; pallete = [[LegacyComponentsGlobals provider] mediaAssetsPallete];
doneImage = pallete != nil ? pallete.sendIconImage : TGComponentsImageNamed(@"PhotoPickerSendIcon"); doneImage = pallete != nil ? pallete.sendIconImage : TGComponentsImageNamed(@"PhotoPickerSendIcon");
//buttonSize = CGSizeMake(52.0f, 52.0f);
} }
break; break;
} }
@ -89,7 +88,7 @@
[_backgroundView addSubview:_doneButton]; [_backgroundView addSubview:_doneButton];
_longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(doneButtonLongPressed:)]; _longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(doneButtonLongPressed:)];
_longPressGestureRecognizer.minimumPressDuration = 0.65; _longPressGestureRecognizer.minimumPressDuration = 0.4;
[_doneButton addGestureRecognizer:_longPressGestureRecognizer]; [_doneButton addGestureRecognizer:_longPressGestureRecognizer];
} }
return self; return self;

View File

@ -21,6 +21,8 @@
0916FEA820A1EA7B0084A755 /* TGPassportScanView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0916FEA620A1EA7B0084A755 /* TGPassportScanView.m */; }; 0916FEA820A1EA7B0084A755 /* TGPassportScanView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0916FEA620A1EA7B0084A755 /* TGPassportScanView.m */; };
0916FEAB20A1EBFA0084A755 /* TGPassportMRZ.m in Sources */ = {isa = PBXBuildFile; fileRef = 0916FEA920A1EBF90084A755 /* TGPassportMRZ.m */; }; 0916FEAB20A1EBFA0084A755 /* TGPassportMRZ.m in Sources */ = {isa = PBXBuildFile; fileRef = 0916FEA920A1EBF90084A755 /* TGPassportMRZ.m */; };
0916FEAC20A1EBFA0084A755 /* TGPassportMRZ.h in Headers */ = {isa = PBXBuildFile; fileRef = 0916FEAA20A1EBFA0084A755 /* TGPassportMRZ.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0916FEAC20A1EBFA0084A755 /* TGPassportMRZ.h in Headers */ = {isa = PBXBuildFile; fileRef = 0916FEAA20A1EBFA0084A755 /* TGPassportMRZ.h */; settings = {ATTRIBUTES = (Public, ); }; };
092A65C922EC4ADC0032E20C /* TGMediaPickerSendActionSheetController.h in Headers */ = {isa = PBXBuildFile; fileRef = 092A65C722EC4ADC0032E20C /* TGMediaPickerSendActionSheetController.h */; };
092A65CA22EC4ADC0032E20C /* TGMediaPickerSendActionSheetController.m in Sources */ = {isa = PBXBuildFile; fileRef = 092A65C822EC4ADC0032E20C /* TGMediaPickerSendActionSheetController.m */; };
09750F761F2FA816001B9886 /* SSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09750F741F2FA5E8001B9886 /* SSignalKit.framework */; }; 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, ); }; }; 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 */; }; 09750FB81F30DB0E001B9886 /* TGClipboardGalleryModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 09750FB01F30DB0E001B9886 /* TGClipboardGalleryModel.m */; };
@ -1190,6 +1192,8 @@
0916FEA620A1EA7B0084A755 /* TGPassportScanView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TGPassportScanView.m; sourceTree = "<group>"; }; 0916FEA620A1EA7B0084A755 /* TGPassportScanView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TGPassportScanView.m; sourceTree = "<group>"; };
0916FEA920A1EBF90084A755 /* TGPassportMRZ.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGPassportMRZ.m; sourceTree = "<group>"; }; 0916FEA920A1EBF90084A755 /* TGPassportMRZ.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGPassportMRZ.m; sourceTree = "<group>"; };
0916FEAA20A1EBFA0084A755 /* TGPassportMRZ.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGPassportMRZ.h; sourceTree = "<group>"; }; 0916FEAA20A1EBFA0084A755 /* TGPassportMRZ.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGPassportMRZ.h; sourceTree = "<group>"; };
092A65C722EC4ADC0032E20C /* TGMediaPickerSendActionSheetController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TGMediaPickerSendActionSheetController.h; sourceTree = "<group>"; };
092A65C822EC4ADC0032E20C /* TGMediaPickerSendActionSheetController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TGMediaPickerSendActionSheetController.m; sourceTree = "<group>"; };
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 = "<group>"; }; 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 = "<group>"; };
09750FAF1F30DB0E001B9886 /* TGClipboardGalleryModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGClipboardGalleryModel.h; sourceTree = "<group>"; }; 09750FAF1F30DB0E001B9886 /* TGClipboardGalleryModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGClipboardGalleryModel.h; sourceTree = "<group>"; };
09750FB01F30DB0E001B9886 /* TGClipboardGalleryModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGClipboardGalleryModel.m; sourceTree = "<group>"; }; 09750FB01F30DB0E001B9886 /* TGClipboardGalleryModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGClipboardGalleryModel.m; sourceTree = "<group>"; };
@ -3525,6 +3529,8 @@
D07BCA4A1F2A9DAB00ED97AA /* TGModernAnimatedImagePlayer.m */, D07BCA4A1F2A9DAB00ED97AA /* TGModernAnimatedImagePlayer.m */,
D07BCA4D1F2A9DDD00ED97AA /* FLAnimatedImage.h */, D07BCA4D1F2A9DDD00ED97AA /* FLAnimatedImage.h */,
D07BCA4E1F2A9DDD00ED97AA /* FLAnimatedImage.m */, D07BCA4E1F2A9DDD00ED97AA /* FLAnimatedImage.m */,
092A65C722EC4ADC0032E20C /* TGMediaPickerSendActionSheetController.h */,
092A65C822EC4ADC0032E20C /* TGMediaPickerSendActionSheetController.m */,
); );
name = "Media Picker"; name = "Media Picker";
sourceTree = "<group>"; sourceTree = "<group>";
@ -4412,6 +4418,7 @@
D07BCB641F2B6A5600ED97AA /* TGEmbedPlayerScrubber.h in Headers */, D07BCB641F2B6A5600ED97AA /* TGEmbedPlayerScrubber.h in Headers */,
D07BCAF31F2B509200ED97AA /* TGAttachmentAssetCell.h in Headers */, D07BCAF31F2B509200ED97AA /* TGAttachmentAssetCell.h in Headers */,
D07BC8951F2A375800ED97AA /* TGPhotoCropControl.h in Headers */, D07BC8951F2A375800ED97AA /* TGPhotoCropControl.h in Headers */,
092A65C922EC4ADC0032E20C /* TGMediaPickerSendActionSheetController.h in Headers */,
D07BC73B1F2A2A7D00ED97AA /* PGPhotoEditorRawDataOutput.h in Headers */, D07BC73B1F2A2A7D00ED97AA /* PGPhotoEditorRawDataOutput.h in Headers */,
D01778B61F1FFFE30044446D /* TGToolbarButton.h in Headers */, D01778B61F1FFFE30044446D /* TGToolbarButton.h in Headers */,
D07BCBB71F2B6F6300ED97AA /* CBCoubNew.h in Headers */, D07BCBB71F2B6F6300ED97AA /* CBCoubNew.h in Headers */,
@ -5063,6 +5070,7 @@
D01778161F1F961D0044446D /* TGMessageEntityCode.m in Sources */, D01778161F1F961D0044446D /* TGMessageEntityCode.m in Sources */,
D07BC7281F2A2A5300ED97AA /* UICollectionView+Utils.m in Sources */, D07BC7281F2A2A5300ED97AA /* UICollectionView+Utils.m in Sources */,
D07BCB671F2B6A5600ED97AA /* TGEmbedPlayerState.m in Sources */, D07BCB671F2B6A5600ED97AA /* TGEmbedPlayerState.m in Sources */,
092A65CA22EC4ADC0032E20C /* TGMediaPickerSendActionSheetController.m in Sources */,
D07BCA911F2B443700ED97AA /* TGMediaAssetsMomentsController.m in Sources */, D07BCA911F2B443700ED97AA /* TGMediaAssetsMomentsController.m in Sources */,
D07BCBC41F2B6F6300ED97AA /* CBJSONCoubMapper.m in Sources */, D07BCBC41F2B6F6300ED97AA /* CBJSONCoubMapper.m in Sources */,
D07BC7871F2A2B3700ED97AA /* TGPhotoEditorTabController.m in Sources */, D07BC7871F2A2B3700ED97AA /* TGPhotoEditorTabController.m in Sources */,

View File

@ -2,11 +2,13 @@
#define Lottie_h #define Lottie_h
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
@interface LottieInstance : NSObject @interface LottieInstance : NSObject
@property (nonatomic, readonly) int32_t frameCount; @property (nonatomic, readonly) int32_t frameCount;
@property (nonatomic, readonly) int32_t frameRate; @property (nonatomic, readonly) int32_t frameRate;
@property (nonatomic, readonly) CGSize dimensions;
- (instancetype _Nullable)initWithData:(NSData * _Nonnull)data cacheKey:(NSString * _Nonnull)cacheKey; - (instancetype _Nullable)initWithData:(NSData * _Nonnull)data cacheKey:(NSString * _Nonnull)cacheKey;
- (void)renderFrameWithIndex:(int32_t)index into:(uint8_t * _Nonnull)buffer width:(int32_t)width height:(int32_t)height; - (void)renderFrameWithIndex:(int32_t)index into:(uint8_t * _Nonnull)buffer width:(int32_t)width height:(int32_t)height;

View File

@ -21,6 +21,16 @@
_frameCount = (int32_t)_animation->totalFrame(); _frameCount = (int32_t)_animation->totalFrame();
_frameRate = (int32_t)_animation->frameRate(); _frameRate = (int32_t)_animation->frameRate();
size_t width = 0;
size_t height = 0;
_animation->size(width, height);
if (width > 1024 || height > 1024) {
return nil;
}
_dimensions = CGSizeMake(width, height);
if ((_frameRate > 60) || _animation->duration() > 4.5) { if ((_frameRate > 60) || _animation->duration() > 4.5) {
return nil; return nil;
} }

View File

@ -172,7 +172,6 @@ public func channelAdminLogEvents(postbox: Postbox, network: Network, peerId: Pe
action = .updatePinned(rendered) action = .updatePinned(rendered)
} }
} }
case let .channelAdminLogEventActionEditMessage(prev, new): case let .channelAdminLogEventActionEditMessage(prev, new):
if let prev = StoreMessage(apiMessage: prev), let prevRendered = locallyRenderedMessage(message: prev, peers: peers), let new = StoreMessage(apiMessage: new), let newRendered = locallyRenderedMessage(message: new, peers: peers) { if let prev = StoreMessage(apiMessage: prev), let prevRendered = locallyRenderedMessage(message: prev, peers: peers), let new = StoreMessage(apiMessage: new), let newRendered = locallyRenderedMessage(message: new, peers: peers) {
action = .editMessage(prev: prevRendered, new: newRendered) action = .editMessage(prev: prevRendered, new: newRendered)

View File

@ -215,7 +215,7 @@ private func makeDarkPresentationTheme(accentColor: UIColor) -> PresentationThem
inputTextColor: .white, inputTextColor: .white,
inputControlColor: UIColor(rgb: 0x7b7b7b), inputControlColor: UIColor(rgb: 0x7b7b7b),
actionControlFillColor: accentColor, actionControlFillColor: accentColor,
actionControlForegroundColor: .white, actionControlForegroundColor: badgeTextColor,
primaryTextColor: .white, primaryTextColor: .white,
secondaryTextColor: UIColor(rgb: 0xffffff, alpha: 0.5), secondaryTextColor: UIColor(rgb: 0xffffff, alpha: 0.5),
mediaRecordingDotColor: destructiveColor, mediaRecordingDotColor: destructiveColor,

View File

@ -253,7 +253,7 @@ public func currentPresentationDataAndSettings(accountManager: AccountManager) -
let parameters = AutomaticThemeSwitchParameters(settings: themeSettings.automaticThemeSwitchSetting) let parameters = AutomaticThemeSwitchParameters(settings: themeSettings.automaticThemeSwitchSetting)
if automaticThemeShouldSwitchNow(parameters, currentTheme: themeSettings.theme) { if automaticThemeShouldSwitchNow(parameters, currentTheme: themeSettings.theme) {
effectiveTheme = themeSettings.themeTintColors ? .builtin(.nightAccent) : .builtin(.night) effectiveTheme = .builtin(themeSettings.automaticThemeSwitchSetting.theme)
} else { } else {
effectiveTheme = themeSettings.theme effectiveTheme = themeSettings.theme
} }
@ -513,7 +513,7 @@ public func updatedPresentationData(accountManager: AccountManager, applicationI
var effectiveChatWallpaper: TelegramWallpaper = currentWallpaper var effectiveChatWallpaper: TelegramWallpaper = currentWallpaper
if shouldSwitch { if shouldSwitch {
let automaticTheme: PresentationThemeReference = themeSettings.themeTintColors ? .builtin(.nightAccent) : .builtin(.night) let automaticTheme: PresentationThemeReference = .builtin(themeSettings.automaticThemeSwitchSetting.theme)
if let themeSpecificWallpaper = themeSettings.themeSpecificChatWallpapers[automaticTheme.index] { if let themeSpecificWallpaper = themeSettings.themeSpecificChatWallpapers[automaticTheme.index] {
effectiveChatWallpaper = themeSpecificWallpaper effectiveChatWallpaper = themeSpecificWallpaper
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -72,6 +72,11 @@ enum AnimatedStickerMode {
case direct case direct
} }
enum AnimatedStickerPlaybackMode {
case once
case loop
}
private final class AnimatedStickerFrame { private final class AnimatedStickerFrame {
let data: Data let data: Data
let type: AnimationRendererFrameType let type: AnimationRendererFrameType
@ -214,7 +219,7 @@ private final class AnimatedStickerDirectFrameSource: AnimatedStickerFrameSource
self.width = width self.width = width
self.height = height self.height = height
self.currentFrame = 0 self.currentFrame = 0
guard let rawData = TGGUnzipData(data, 2 * 1024 * 1024) else { guard let rawData = TGGUnzipData(data, 8 * 1024 * 1024) else {
return nil return nil
} }
guard let animation = LottieInstance(data: rawData, cacheKey: "") else { guard let animation = LottieInstance(data: rawData, cacheKey: "") else {
@ -292,6 +297,7 @@ final class AnimatedStickerNode: ASDisplayNode {
private var renderer: (AnimationRenderer & ASDisplayNode)? private var renderer: (AnimationRenderer & ASDisplayNode)?
private var isPlaying: Bool = false private var isPlaying: Bool = false
private var playbackMode: AnimatedStickerPlaybackMode = .loop
var visibility = false { var visibility = false {
didSet { didSet {
@ -342,8 +348,9 @@ final class AnimatedStickerNode: ASDisplayNode {
self.renderer?.frame = CGRect(origin: CGPoint(), size: self.bounds.size) self.renderer?.frame = CGRect(origin: CGPoint(), size: self.bounds.size)
self.addSubnode(self.renderer!) self.addSubnode(self.renderer!)
} }
func setup(account: Account, resource: MediaResource, width: Int, height: Int, mode: AnimatedStickerMode) { func setup(account: Account, resource: MediaResource, width: Int, height: Int, playbackMode: AnimatedStickerPlaybackMode = .loop, mode: AnimatedStickerMode) {
self.playbackMode = playbackMode
switch mode { switch mode {
case .direct: case .direct:
self.disposable.set((account.postbox.mediaBox.resourceData(resource) self.disposable.set((account.postbox.mediaBox.resourceData(resource)
@ -411,7 +418,7 @@ final class AnimatedStickerNode: ASDisplayNode {
timerHolder.swap(nil)?.invalidate() timerHolder.swap(nil)?.invalidate()
let timer = SwiftSignalKit.Timer(timeout: 1.0 / Double(frameSource.frameRate), repeat: true, completion: { let timer = SwiftSignalKit.Timer(timeout: 1.0 / Double(frameSource.frameRate), repeat: true, completion: {
let maybeFrame = frameQueue.syncWith { frameQueue in let maybeFrame = frameQueue.syncWith { frameQueue in
return frameQueue.take() return frameQueue.take()
} }
if let maybeFrame = maybeFrame, let frame = maybeFrame { if let maybeFrame = maybeFrame, let frame = maybeFrame {

View File

@ -3,6 +3,7 @@ import UIKit
import SwiftSignalKit import SwiftSignalKit
import Postbox import Postbox
import Display import Display
import TelegramCore
import AVFoundation import AVFoundation
import Lottie import Lottie
import TelegramUIPrivateModule import TelegramUIPrivateModule
@ -11,6 +12,59 @@ import GZip
import RLottie import RLottie
import MobileCoreServices import MobileCoreServices
public struct LocalBundleResourceId: MediaResourceId {
public let name: String
public let ext: String
public var uniqueId: String {
return "local-bundle-\(self.name)-\(self.ext)"
}
public var hashValue: Int {
return self.name.hashValue
}
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? LocalBundleResourceId {
return self.name == to.name && self.ext == to.ext
} else {
return false
}
}
}
public class LocalBundleResource: TelegramMediaResource {
public let name: String
public let ext: String
public init(name: String, ext: String) {
self.name = name
self.ext = ext
}
public required init(decoder: PostboxDecoder) {
self.name = decoder.decodeStringForKey("n", orElse: "")
self.ext = decoder.decodeStringForKey("e", orElse: "")
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeString(self.name, forKey: "n")
encoder.encodeString(self.ext, forKey: "e")
}
public var id: MediaResourceId {
return LocalBundleResourceId(name: self.name, ext: self.ext)
}
public func isEqual(to: MediaResource) -> Bool {
if let to = to as? LocalBundleResourceId {
return self.name == to.name && self.ext == to.ext
} else {
return false
}
}
}
func fetchCompressedLottieFirstFrameAJpeg(data: Data, size: CGSize, cacheKey: String) -> Signal<TempBoxFile, NoError> { func fetchCompressedLottieFirstFrameAJpeg(data: Data, size: CGSize, cacheKey: String) -> Signal<TempBoxFile, NoError> {
return Signal({ subscriber in return Signal({ subscriber in
let queue = Queue() let queue = Queue()
@ -22,7 +76,7 @@ func fetchCompressedLottieFirstFrameAJpeg(data: Data, size: CGSize, cacheKey: St
return return
} }
let decompressedData = TGGUnzipData(data, 2 * 1024 * 1024) let decompressedData = TGGUnzipData(data, 8 * 1024 * 1024)
if let decompressedData = decompressedData, let player = LottieInstance(data: decompressedData, cacheKey: cacheKey) { if let decompressedData = decompressedData, let player = LottieInstance(data: decompressedData, cacheKey: cacheKey) {
if cancelled.with({ $0 }) { if cancelled.with({ $0 }) {
return return
@ -117,7 +171,7 @@ func experimentalConvertCompressedLottieToCombinedMp4(data: Data, size: CGSize,
var deltaTime: Double = 0 var deltaTime: Double = 0
var compressionTime: Double = 0 var compressionTime: Double = 0
let decompressedData = TGGUnzipData(data, 2 * 1024 * 1024) let decompressedData = TGGUnzipData(data, 8 * 1024 * 1024)
if let decompressedData = decompressedData, let player = LottieInstance(data: decompressedData, cacheKey: cacheKey) { if let decompressedData = decompressedData, let player = LottieInstance(data: decompressedData, cacheKey: cacheKey) {
let endFrame = Int(player.frameCount) let endFrame = Int(player.frameCount)

View File

@ -367,6 +367,8 @@ private enum ChannelAdminEntry: ItemListNodeEntry {
case let .rank(theme, placeholder, text, enabled): case let .rank(theme, placeholder, text, enabled):
return ItemListSingleLineInputItem(theme: theme, title: NSAttributedString(string: "", textColor: .black), text: text, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: true), spacing: 0.0, clearButton: enabled, enabled: enabled, tag: ChannelAdminEntryTag.rank, sectionId: self.section, textUpdated: { updatedText in return ItemListSingleLineInputItem(theme: theme, title: NSAttributedString(string: "", textColor: .black), text: text, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: true), spacing: 0.0, clearButton: enabled, enabled: enabled, tag: ChannelAdminEntryTag.rank, sectionId: self.section, textUpdated: { updatedText in
arguments.updateRank(text, updatedText) arguments.updateRank(text, updatedText)
}, shouldUpdateText: { text in
return !text.containsEmoji
}, updatedFocus: { focus in }, updatedFocus: { focus in
arguments.updateFocusedOnRank(focus) arguments.updateFocusedOnRank(focus)
}, action: { }, action: {

View File

@ -4664,14 +4664,14 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
let inputText = strongSelf.presentationInterfaceState.interfaceState.effectiveInputState.inputText let inputText = strongSelf.presentationInterfaceState.interfaceState.effectiveInputState.inputText
let controller = legacyAttachmentMenu(context: strongSelf.context, peer: peer, editMediaOptions: editMediaOptions, saveEditedPhotos: settings.storeEditedPhotos, allowGrouping: true, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, parentController: legacyController, recentlyUsedInlineBots: strongSelf.recentlyUsedInlineBotsValue, initialCaption: inputText.string, openGallery: { let controller = legacyAttachmentMenu(context: strongSelf.context, peer: peer, editMediaOptions: editMediaOptions, saveEditedPhotos: settings.storeEditedPhotos, allowGrouping: true, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, parentController: legacyController, recentlyUsedInlineBots: strongSelf.recentlyUsedInlineBotsValue, initialCaption: inputText.string, openGallery: {
self?.presentMediaPicker(fileMode: false, editingMedia: editMediaOptions != nil, completion: { signals in self?.presentMediaPicker(fileMode: false, editingMedia: editMediaOptions != nil, completion: { signals, silentPosting in
if !inputText.string.isEmpty { if !inputText.string.isEmpty {
//strongSelf.clearInputText() //strongSelf.clearInputText()
} }
if editMediaOptions != nil { if editMediaOptions != nil {
self?.editMessageMediaWithLegacySignals(signals) self?.editMessageMediaWithLegacySignals(signals)
} else { } else {
self?.enqueueMediaMessages(signals: signals) self?.enqueueMediaMessages(signals: signals, silentPosting: silentPosting)
} }
}) })
}, openCamera: { [weak self] cameraView, menuController in }, openCamera: { [weak self] cameraView, menuController in
@ -4681,7 +4681,7 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
if editMediaOptions != nil { if editMediaOptions != nil {
strongSelf.editMessageMediaWithLegacySignals(signals!) strongSelf.editMessageMediaWithLegacySignals(signals!)
} else { } else {
strongSelf.enqueueMediaMessages(signals: signals) strongSelf.enqueueMediaMessages(signals: signals, silentPosting: false)
} }
if !inputText.string.isEmpty { if !inputText.string.isEmpty {
//strongSelf.clearInputText() //strongSelf.clearInputText()
@ -4713,14 +4713,14 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
return return
} }
strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: nil, text: strongSelf.presentationData.strings.Chat_AttachmentMultipleFilesDisabled, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: nil, text: strongSelf.presentationData.strings.Chat_AttachmentMultipleFilesDisabled, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
}, sendMessagesWithSignals: { [weak self] signals in }, sendMessagesWithSignals: { [weak self] signals, silentPosting in
if !inputText.string.isEmpty { if !inputText.string.isEmpty {
//strongSelf.clearInputText() //strongSelf.clearInputText()
} }
if editMediaOptions != nil { if editMediaOptions != nil {
self?.editMessageMediaWithLegacySignals(signals!) self?.editMessageMediaWithLegacySignals(signals!)
} else { } else {
self?.enqueueMediaMessages(signals: signals) self?.enqueueMediaMessages(signals: signals, silentPosting: silentPosting)
} }
}, selectRecentlyUsedInlineBot: { [weak self] peer in }, selectRecentlyUsedInlineBot: { [weak self] peer in
if let strongSelf = self, let addressName = peer.addressName { if let strongSelf = self, let addressName = peer.addressName {
@ -4756,11 +4756,11 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
ActionSheetButtonItem(title: self.presentationData.strings.Conversation_FilePhotoOrVideo, action: { [weak self, weak actionSheet] in ActionSheetButtonItem(title: self.presentationData.strings.Conversation_FilePhotoOrVideo, action: { [weak self, weak actionSheet] in
actionSheet?.dismissAnimated() actionSheet?.dismissAnimated()
if let strongSelf = self { if let strongSelf = self {
strongSelf.presentMediaPicker(fileMode: true, editingMedia: editingMessage, completion: { signals in strongSelf.presentMediaPicker(fileMode: true, editingMedia: editingMessage, completion: { signals, silentPosting in
if editingMessage { if editingMessage {
self?.editMessageMediaWithLegacySignals(signals) self?.editMessageMediaWithLegacySignals(signals)
} else { } else {
self?.enqueueMediaMessages(signals: signals) self?.enqueueMediaMessages(signals: signals, silentPosting: silentPosting)
} }
}) })
} }
@ -4824,7 +4824,7 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
self.present(actionSheet, in: .window(.root)) self.present(actionSheet, in: .window(.root))
} }
private func presentMediaPicker(fileMode: Bool, editingMedia: Bool, completion: @escaping ([Any]) -> Void) { private func presentMediaPicker(fileMode: Bool, editingMedia: Bool, completion: @escaping ([Any], Bool) -> Void) {
let postbox = self.context.account.postbox let postbox = self.context.account.postbox
let _ = (self.context.sharedContext.accountManager.transaction { transaction -> Signal<(GeneratedMediaStoreSettings, SearchBotsConfiguration), NoError> in let _ = (self.context.sharedContext.accountManager.transaction { transaction -> Signal<(GeneratedMediaStoreSettings, SearchBotsConfiguration), NoError> in
let entry = transaction.getSharedData(ApplicationSpecificSharedDataKeys.generatedMediaStoreSettings) as? GeneratedMediaStoreSettings let entry = transaction.getSharedData(ApplicationSpecificSharedDataKeys.generatedMediaStoreSettings) as? GeneratedMediaStoreSettings
@ -4857,7 +4857,7 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
configureLegacyAssetPicker(controller, context: strongSelf.context, peer: peer, initialCaption: inputText.string, presentWebSearch: { [weak self, weak legacyController] in configureLegacyAssetPicker(controller, context: strongSelf.context, peer: peer, initialCaption: inputText.string, presentWebSearch: { [weak self, weak legacyController] in
if let strongSelf = self { if let strongSelf = self {
let controller = WebSearchController(context: strongSelf.context, peer: peer, configuration: searchBotsConfiguration, mode: .media(completion: { results, selectionState, editingState in let controller = WebSearchController(context: strongSelf.context, peer: peer, configuration: searchBotsConfiguration, mode: .media(completion: { results, selectionState, editingState, silentPosting in
if let legacyController = legacyController { if let legacyController = legacyController {
legacyController.dismiss() legacyController.dismiss()
} }
@ -4867,7 +4867,7 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
} }
}, enqueueMediaMessages: { signals in }, enqueueMediaMessages: { signals in
if let strongSelf = self { if let strongSelf = self {
strongSelf.enqueueMediaMessages(signals: signals) strongSelf.enqueueMediaMessages(signals: signals, silentPosting: silentPosting)
} }
}) })
})) }))
@ -4880,10 +4880,10 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: nil, text: strongSelf.presentationData.strings.Chat_AttachmentLimitExceeded, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: nil, text: strongSelf.presentationData.strings.Chat_AttachmentLimitExceeded, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
}) })
controller.descriptionGenerator = legacyAssetPickerItemGenerator() controller.descriptionGenerator = legacyAssetPickerItemGenerator()
controller.completionBlock = { [weak legacyController, weak self] signals in controller.completionBlock = { [weak legacyController] signals, silentPosting in
if let legacyController = legacyController { if let legacyController = legacyController {
legacyController.dismiss() legacyController.dismiss()
completion(signals!) completion(signals!, silentPosting)
} }
} }
controller.dismissalBlock = { [weak legacyController] in controller.dismissalBlock = { [weak legacyController] in
@ -4912,14 +4912,14 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
} }
|> deliverOnMainQueue).start(next: { [weak self] configuration in |> deliverOnMainQueue).start(next: { [weak self] configuration in
if let strongSelf = self { if let strongSelf = self {
let controller = WebSearchController(context: strongSelf.context, peer: peer, configuration: configuration, mode: .media(completion: { [weak self] results, selectionState, editingState in let controller = WebSearchController(context: strongSelf.context, peer: peer, configuration: configuration, mode: .media(completion: { [weak self] results, selectionState, editingState, silentPosting in
legacyEnqueueWebSearchMessages(selectionState, editingState, enqueueChatContextResult: { [weak self] result in legacyEnqueueWebSearchMessages(selectionState, editingState, enqueueChatContextResult: { [weak self] result in
if let strongSelf = self { if let strongSelf = self {
strongSelf.enqueueChatContextResult(results, result, hideVia: true) strongSelf.enqueueChatContextResult(results, result, hideVia: true)
} }
}, enqueueMediaMessages: { [weak self] signals in }, enqueueMediaMessages: { [weak self] signals in
if let strongSelf = self { if let strongSelf = self {
strongSelf.enqueueMediaMessages(signals: signals) strongSelf.enqueueMediaMessages(signals: signals, silentPosting: silentPosting)
} }
}) })
})) }))
@ -5135,11 +5135,12 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
} }
} }
private func enqueueMediaMessages(signals: [Any]?) { private func enqueueMediaMessages(signals: [Any]?, silentPosting: Bool) {
if case .peer = self.chatLocation { if case .peer = self.chatLocation {
self.enqueueMediaMessageDisposable.set((legacyAssetPickerEnqueueMessages(account: self.context.account, signals: signals!) self.enqueueMediaMessageDisposable.set((legacyAssetPickerEnqueueMessages(account: self.context.account, signals: signals!)
|> deliverOnMainQueue).start(next: { [weak self] messages in |> deliverOnMainQueue).start(next: { [weak self] messages in
if let strongSelf = self { if let strongSelf = self {
let messages = strongSelf.transformEnqueueMessages(messages, silentPosting: silentPosting)
let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId
strongSelf.chatDisplayNode.setupSendActionOnViewUpdate({ strongSelf.chatDisplayNode.setupSendActionOnViewUpdate({
if let strongSelf = self { if let strongSelf = self {
@ -5163,7 +5164,7 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
if let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer { if let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer {
strongSelf.chatDisplayNode.dismissInput() strongSelf.chatDisplayNode.dismissInput()
let _ = presentLegacyPasteMenu(context: strongSelf.context, peer: peer, saveEditedPhotos: settings.storeEditedPhotos, allowGrouping: true, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, images: images, sendMessagesWithSignals: { signals in let _ = presentLegacyPasteMenu(context: strongSelf.context, peer: peer, saveEditedPhotos: settings.storeEditedPhotos, allowGrouping: true, theme: strongSelf.presentationData.theme, strings: strongSelf.presentationData.strings, images: images, sendMessagesWithSignals: { signals in
self?.enqueueMediaMessages(signals: signals) self?.enqueueMediaMessages(signals: signals, silentPosting: false)
}, present: { [weak self] controller, arguments in }, present: { [weak self] controller, arguments in
if let strongSelf = self { if let strongSelf = self {
strongSelf.present(controller, in: .window(.root), with: arguments) strongSelf.present(controller, in: .window(.root), with: arguments)
@ -6475,7 +6476,7 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
let sourceRect = rect.insetBy(dx: -2.0, dy: -2.0) let sourceRect = rect.insetBy(dx: -2.0, dy: -2.0)
gallery.containerLayoutUpdated(ContainerViewLayout(size: CGSize(width: self.view.bounds.size.width, height: self.view.bounds.size.height), metrics: LayoutMetrics(), intrinsicInsets: UIEdgeInsets(), safeInsets: UIEdgeInsets(), statusBarHeight: nil, inputHeight: nil, standardInputHeight: 216.0, inputHeightIsInteractivellyChanging: false, inVoiceOver: false), transition: .immediate) gallery.containerLayoutUpdated(ContainerViewLayout(size: CGSize(width: self.view.bounds.size.width, height: self.view.bounds.size.height), metrics: LayoutMetrics(), intrinsicInsets: UIEdgeInsets(), safeInsets: UIEdgeInsets(), statusBarHeight: nil, inputHeight: nil, standardInputHeight: 216.0, inputHeightIsInteractivellyChanging: false, inVoiceOver: false), transition: .immediate)
return (gallery, sourceRect) return (gallery, sourceRect)
case let .instantPage(gallery, centralIndex, galleryMedia): case .instantPage:
break break
} }
} }

View File

@ -112,7 +112,7 @@ final class ChatListControllerNode: ASDisplayNode {
switch isEmptyState { switch isEmptyState {
case .empty(true): case .empty(true):
if strongSelf.chatListEmptyIndicator == nil { if strongSelf.chatListEmptyIndicator == nil {
let chatListEmptyIndicator = ActivityIndicator(type: .custom(strongSelf.presentationData.theme.list.itemAccentColor, 22.0, 1.0, false)) let chatListEmptyIndicator = ActivityIndicator(type: .custom(strongSelf.presentationData.theme.list.itemSecondaryTextColor, 22.0, 1.0, false))
strongSelf.chatListEmptyIndicator = chatListEmptyIndicator strongSelf.chatListEmptyIndicator = chatListEmptyIndicator
strongSelf.insertSubnode(chatListEmptyIndicator, belowSubnode: strongSelf.chatListNode) strongSelf.insertSubnode(chatListEmptyIndicator, belowSubnode: strongSelf.chatListNode)
if let (layout, navigationHeight, visualNavigationHeight) = strongSelf.containerLayout { if let (layout, navigationHeight, visualNavigationHeight) = strongSelf.containerLayout {

View File

@ -120,15 +120,15 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
self.telegramFile = telegramFile self.telegramFile = telegramFile
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, file: telegramFile, small: false, size: CGSize(width: 384.0, height: 384.0), thumbnail: false)) self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: item.context.account.postbox, file: telegramFile, small: false, size: CGSize(width: 384.0, height: 384.0), thumbnail: false))
self.updateVisibility() self.updateVisibility()
if self.visibilityStatus && false {
self.didSetUpAnimationNode = true
self.animationNode.setup(account: item.context.account, resource: telegramFile.resource, width: 384, height: 384, mode: .cached)
}
self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, fileReference: .message(message: MessageReference(item.message), media: telegramFile)).start()) self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, fileReference: .message(message: MessageReference(item.message), media: telegramFile)).start())
} }
break break
} }
} }
if self.telegramFile == nil {
self.updateVisibility()
}
} }
func updateVisibility() { func updateVisibility() {
@ -142,12 +142,25 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
self.animationNode.visibility = isPlaying self.animationNode.visibility = isPlaying
if let item = self.item, isPlaying, !self.didSetUpAnimationNode { if let item = self.item, isPlaying, !self.didSetUpAnimationNode {
self.didSetUpAnimationNode = true self.didSetUpAnimationNode = true
var telegramFile: TelegramMediaFile?
for media in item.message.media { for media in item.message.media {
if let telegramFile = media as? TelegramMediaFile { if let file = media as? TelegramMediaFile {
self.animationNode.setup(account: item.context.account, resource: telegramFile.resource, width: 384, height: 384, mode: .cached) telegramFile = file
break break
} }
} }
if let telegramFile = telegramFile {
self.animationNode.setup(account: item.context.account, resource: telegramFile.resource, width: 384, height: 384, mode: .cached)
} else if item.message.text == "👍" {
self.animationNode.setup(account: item.context.account, resource: LocalBundleResource(name: "thumbsup", ext: "tgs"), width: 384, height: 384, mode: .cached)
} else if item.message.text == "😂" {
self.animationNode.setup(account: item.context.account, resource: LocalBundleResource(name: "lol", ext: "tgs"), width: 384, height: 384, mode: .cached)
} else if item.message.text == "😒" {
self.animationNode.setup(account: item.context.account, resource: LocalBundleResource(name: "meh", ext: "tgs"), width: 384, height: 384, mode: .cached)
} else if item.message.text == "❤️" {
self.animationNode.setup(account: item.context.account, resource: LocalBundleResource(name: "heart", ext: "tgs"), width: 384, height: 384, mode: .cached)
}
} }
} }
} }
@ -179,6 +192,8 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
} else if let thumbnailSize = telegramFile.previewRepresentations.first?.dimensions { } else if let thumbnailSize = telegramFile.previewRepresentations.first?.dimensions {
imageSize = thumbnailSize.aspectFitted(displaySize) imageSize = thumbnailSize.aspectFitted(displaySize)
} }
} else {
imageSize = CGSize(width: floor(displaySize.width * 0.683), height: floor(displaySize.height * 0.683))
} }
let avatarInset: CGFloat let avatarInset: CGFloat

View File

@ -869,7 +869,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
case .admin: case .admin:
string = item.presentationData.strings.Conversation_Admin string = item.presentationData.strings.Conversation_Admin
case let .custom(rank): case let .custom(rank):
string = rank string = rank.trimmingEmojis
} }
adminBadgeString = NSAttributedString(string: " \(string)", font: inlineBotPrefixFont, textColor: messageTheme.secondaryTextColor) adminBadgeString = NSAttributedString(string: " \(string)", font: inlineBotPrefixFont, textColor: messageTheme.secondaryTextColor)
} else if authorIsChannel { } else if authorIsChannel {

View File

@ -386,7 +386,11 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible {
} }
if viewClassName == ChatMessageBubbleItemNode.self && self.presentationData.largeEmoji && self.message.elligibleForLargeEmoji && messageIsElligibleForLargeEmoji(self.message) { if viewClassName == ChatMessageBubbleItemNode.self && self.presentationData.largeEmoji && self.message.elligibleForLargeEmoji && messageIsElligibleForLargeEmoji(self.message) {
viewClassName = ChatMessageStickerItemNode.self if ["👍", "😂", "😒", "❤️"].contains(self.message.text) {
viewClassName = ChatMessageAnimatedStickerItemNode.self
} else {
viewClassName = ChatMessageStickerItemNode.self
}
} }
let configure = { let configure = {

View File

@ -28,8 +28,6 @@ final class ChatSendMessageActionSheetController: ViewController {
self.statusBar.statusBarStyle = .Hide self.statusBar.statusBarStyle = .Hide
self.statusBar.ignoreInCall = true self.statusBar.ignoreInCall = true
self.lockOrientation = true
} }
required init(coder aDecoder: NSCoder) { required init(coder aDecoder: NSCoder) {
@ -64,6 +62,15 @@ final class ChatSendMessageActionSheetController: ViewController {
super.containerLayoutUpdated(layout, transition: transition) super.containerLayoutUpdated(layout, transition: transition)
self.controllerNode.containerLayoutUpdated(layout, transition: transition) self.controllerNode.containerLayoutUpdated(layout, transition: transition)
if !self.lockOrientation {
self.lockOrientation = true
if layout.size.width > layout.size.height {
self.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .landscape)
} else {
self.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
}
}
} }
override public func dismiss(completion: (() -> Void)? = nil) { override public func dismiss(completion: (() -> Void)? = nil) {

View File

@ -59,7 +59,7 @@ private final class ActionSheetItemNode: ASDisplayNode {
func updateLayout(maxWidth: CGFloat) -> (CGFloat, CGFloat, (CGFloat) -> Void) { func updateLayout(maxWidth: CGFloat) -> (CGFloat, CGFloat, (CGFloat) -> Void) {
let leftInset: CGFloat = 16.0 let leftInset: CGFloat = 16.0
let rightInset: CGFloat = 76.0 let rightInset: CGFloat = 46.0
let titleSize = self.titleNode.updateLayout(CGSize(width: maxWidth - leftInset - rightInset, height: .greatestFiniteMagnitude)) let titleSize = self.titleNode.updateLayout(CGSize(width: maxWidth - leftInset - rightInset, height: .greatestFiniteMagnitude))
let height: CGFloat = 44.0 let height: CGFloat = 44.0
@ -67,7 +67,7 @@ private final class ActionSheetItemNode: ASDisplayNode {
self.titleNode.frame = CGRect(origin: CGPoint(x: leftInset, y: floor((height - titleSize.height) / 2.0)), size: titleSize) self.titleNode.frame = CGRect(origin: CGPoint(x: leftInset, y: floor((height - titleSize.height) / 2.0)), size: titleSize)
if let image = self.iconNode.image { if let image = self.iconNode.image {
self.iconNode.frame = CGRect(origin: CGPoint(x: width - floor((rightInset - image.size.width) / 2.0) - 10.0, y: floor((height - image.size.height) / 2.0)), size: image.size) self.iconNode.frame = CGRect(origin: CGPoint(x: width - image.size.width - 12.0, y: floor((height - image.size.height) / 2.0)), size: image.size)
} }
self.separatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: height - UIScreenPixel), size: CGSize(width: width, height: UIScreenPixel)) self.separatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: height - UIScreenPixel), size: CGSize(width: width, height: UIScreenPixel))
@ -90,7 +90,8 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
private let send: (() -> Void)? private let send: (() -> Void)?
private let cancel: (() -> Void)? private let cancel: (() -> Void)?
private let coverNode: ASDisplayNode private let textCoverNode: ASDisplayNode
private let buttonCoverNode: ASDisplayNode
private let effectView: UIVisualEffectView private let effectView: UIVisualEffectView
private let dimNode: ASDisplayNode private let dimNode: ASDisplayNode
@ -101,7 +102,8 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
private let messageClipNode: ASDisplayNode private let messageClipNode: ASDisplayNode
private let messageBackgroundNode: ASImageNode private let messageBackgroundNode: ASImageNode
private let messageTextNode: EditableTextNode private let fromMessageTextNode: EditableTextNode
private let toMessageTextNode: EditableTextNode
private let scrollNode: ASScrollNode private let scrollNode: ASScrollNode
private var validLayout: ContainerViewLayout? private var validLayout: ContainerViewLayout?
@ -114,12 +116,13 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
self.send = send self.send = send
self.cancel = cancel self.cancel = cancel
self.coverNode = ASDisplayNode() self.textCoverNode = ASDisplayNode()
self.buttonCoverNode = ASDisplayNode()
self.effectView = UIVisualEffectView() self.effectView = UIVisualEffectView()
if #available(iOS 9.0, *) { if #available(iOS 9.0, *) {
} else { } else {
if presentationData.theme.chatList.searchBarKeyboardColor == .dark { if self.presentationData.theme.chatList.searchBarKeyboardColor == .dark {
self.effectView.effect = UIBlurEffect(style: .dark) self.effectView.effect = UIBlurEffect(style: .dark)
} else { } else {
self.effectView.effect = UIBlurEffect(style: .light) self.effectView.effect = UIBlurEffect(style: .light)
@ -136,6 +139,8 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
} }
self.sendButtonNode = HighlightableButtonNode() self.sendButtonNode = HighlightableButtonNode()
self.sendButtonNode.imageNode.displayWithoutProcessing = false
self.sendButtonNode.imageNode.displaysAsynchronously = false
self.sendButtonNode.setImage(PresentationResourcesChat.chatInputPanelSendButtonImage(self.presentationData.theme), for: []) self.sendButtonNode.setImage(PresentationResourcesChat.chatInputPanelSendButtonImage(self.presentationData.theme), for: [])
self.messageClipNode = ASDisplayNode() self.messageClipNode = ASDisplayNode()
@ -143,8 +148,11 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
self.messageClipNode.transform = CATransform3DMakeScale(1.0, -1.0, 1.0) self.messageClipNode.transform = CATransform3DMakeScale(1.0, -1.0, 1.0)
self.messageBackgroundNode = ASImageNode() self.messageBackgroundNode = ASImageNode()
self.messageBackgroundNode.isUserInteractionEnabled = true self.messageBackgroundNode.isUserInteractionEnabled = true
self.messageTextNode = EditableTextNode() self.fromMessageTextNode = EditableTextNode()
self.messageTextNode.isUserInteractionEnabled = false self.fromMessageTextNode.isUserInteractionEnabled = false
self.toMessageTextNode = EditableTextNode()
self.toMessageTextNode.alpha = 0.0
self.toMessageTextNode.isUserInteractionEnabled = false
self.scrollNode = ASScrollNode() self.scrollNode = ASScrollNode()
self.scrollNode.transform = CATransform3DMakeScale(1.0, -1.0, 1.0) self.scrollNode.transform = CATransform3DMakeScale(1.0, -1.0, 1.0)
@ -162,13 +170,21 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
super.init() super.init()
self.coverNode.backgroundColor = self.presentationData.theme.chat.inputPanel.inputBackgroundColor self.textCoverNode.backgroundColor = self.presentationData.theme.chat.inputPanel.inputBackgroundColor
self.addSubnode(self.coverNode) self.addSubnode(self.textCoverNode)
self.buttonCoverNode.backgroundColor = self.presentationData.theme.chat.inputPanel.panelBackgroundColor
self.addSubnode(self.buttonCoverNode)
self.sendButtonNode.setImage(PresentationResourcesChat.chatInputPanelSendButtonImage(self.presentationData.theme), for: []) self.sendButtonNode.setImage(PresentationResourcesChat.chatInputPanelSendButtonImage(self.presentationData.theme), for: [])
self.sendButtonNode.addTarget(self, action: #selector(sendButtonPressed), forControlEvents: .touchUpInside) self.sendButtonNode.addTarget(self, action: #selector(sendButtonPressed), forControlEvents: .touchUpInside)
self.messageTextNode.attributedText = textInputNode.attributedText self.fromMessageTextNode.attributedText = textInputNode.attributedText
if let toAttributedText = textInputNode.attributedText?.mutableCopy() as? NSMutableAttributedString {
toAttributedText.addAttribute(NSAttributedStringKey.foregroundColor, value: self.presentationData.theme.chat.message.outgoing.primaryTextColor, range: NSMakeRange(0, (toAttributedText.string as NSString).length))
self.toMessageTextNode.attributedText = toAttributedText
}
self.messageBackgroundNode.contentMode = .scaleToFill self.messageBackgroundNode.contentMode = .scaleToFill
let graphics = PresentationResourcesChat.principalGraphics(self.presentationData.theme, wallpaper: self.presentationData.chatWallpaper) let graphics = PresentationResourcesChat.principalGraphics(self.presentationData.theme, wallpaper: self.presentationData.chatWallpaper)
@ -184,7 +200,8 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
self.addSubnode(self.sendButtonNode) self.addSubnode(self.sendButtonNode)
self.scrollNode.addSubnode(self.messageClipNode) self.scrollNode.addSubnode(self.messageClipNode)
self.messageClipNode.addSubnode(self.messageBackgroundNode) self.messageClipNode.addSubnode(self.messageBackgroundNode)
self.messageClipNode.addSubnode(self.messageTextNode) self.messageClipNode.addSubnode(self.fromMessageTextNode)
self.messageClipNode.addSubnode(self.toMessageTextNode)
self.contentNodes.forEach(self.contentContainerNode.addSubnode) self.contentNodes.forEach(self.contentContainerNode.addSubnode)
} }
@ -248,10 +265,14 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
self.dimNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4) self.dimNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4)
self.contentContainerNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) self.contentContainerNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
self.messageBackgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) self.messageBackgroundNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3)
self.fromMessageTextNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false)
self.toMessageTextNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3, removeOnCompletion: false)
if let layout = self.validLayout { if let layout = self.validLayout {
let duration = 0.6 let duration = 0.6
self.sendButtonNode.layer.animateScale(from: 0.75, to: 1.0, duration: 0.2, timingFunction: kCAMediaTimingFunctionLinear, removeOnCompletion: false) self.sendButtonNode.layer.animateScale(from: 0.75, to: 1.0, duration: 0.2, timingFunction: kCAMediaTimingFunctionLinear)
self.sendButtonNode.layer.animatePosition(from: self.sendButtonFrame.center, to: self.sendButtonNode.position, duration: duration, timingFunction: kCAMediaTimingFunctionSpring) self.sendButtonNode.layer.animatePosition(from: self.sendButtonFrame.center, to: self.sendButtonNode.position, duration: duration, timingFunction: kCAMediaTimingFunctionSpring)
let initialWidth = self.textFieldFrame.width + 32.0 let initialWidth = self.textFieldFrame.width + 32.0
@ -273,7 +294,10 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
self.messageBackgroundNode.layer.animateBounds(from: fromFrame, to: self.messageBackgroundNode.bounds, duration: duration, timingFunction: kCAMediaTimingFunctionSpring) self.messageBackgroundNode.layer.animateBounds(from: fromFrame, to: self.messageBackgroundNode.bounds, duration: duration, timingFunction: kCAMediaTimingFunctionSpring)
self.messageBackgroundNode.layer.animatePosition(from: CGPoint(x: (initialWidth - self.messageClipNode.bounds.width) / 2.0, y: delta), to: CGPoint(), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, additive: true) self.messageBackgroundNode.layer.animatePosition(from: CGPoint(x: (initialWidth - self.messageClipNode.bounds.width) / 2.0, y: delta), to: CGPoint(), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
self.messageTextNode.layer.animatePosition(from: CGPoint(x: 0.0, y: delta * 2.0), to: CGPoint(), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
let textOffset = self.textInputNode.textView.contentSize.height - self.textInputNode.textView.contentOffset.y - self.textInputNode.textView.frame.height
self.fromMessageTextNode.layer.animatePosition(from: CGPoint(x: 0.0, y: delta * 2.0 + textOffset), to: CGPoint(), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
self.toMessageTextNode.layer.animatePosition(from: CGPoint(x: 0.0, y: delta * 2.0 + textOffset), to: CGPoint(), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
self.contentContainerNode.layer.animatePosition(from: CGPoint(x: 160.0, y: 0.0), to: CGPoint(), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, additive: true) self.contentContainerNode.layer.animatePosition(from: CGPoint(x: 160.0, y: 0.0), to: CGPoint(), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
self.contentContainerNode.layer.animateScale(from: 0.45, to: 1.0, duration: duration, timingFunction: kCAMediaTimingFunctionSpring) self.contentContainerNode.layer.animateScale(from: 0.45, to: 1.0, duration: duration, timingFunction: kCAMediaTimingFunctionSpring)
@ -290,7 +314,8 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
let intermediateCompletion: () -> Void = { [weak self] in let intermediateCompletion: () -> Void = { [weak self] in
if completedEffect && completedButton && completedBubble && completedAlpha { if completedEffect && completedButton && completedBubble && completedAlpha {
self?.coverNode.isHidden = true self?.textCoverNode.isHidden = true
self?.buttonCoverNode.isHidden = true
completion() completion()
} }
} }
@ -309,12 +334,14 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
self.contentContainerNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in }) self.contentContainerNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in })
if cancel { if cancel {
self.fromMessageTextNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3, delay: 0.15, removeOnCompletion: false)
self.toMessageTextNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, delay: 0.15, removeOnCompletion: false)
self.messageBackgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, delay: 0.15, removeOnCompletion: false, completion: { _ in self.messageBackgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, delay: 0.15, removeOnCompletion: false, completion: { _ in
completedAlpha = true completedAlpha = true
intermediateCompletion() intermediateCompletion()
}) })
} else { } else {
self.coverNode.isHidden = true self.textCoverNode.isHidden = true
self.messageClipNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { _ in self.messageClipNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { _ in
completedAlpha = true completedAlpha = true
intermediateCompletion() intermediateCompletion()
@ -330,6 +357,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
}) })
if !cancel { if !cancel {
self.buttonCoverNode.isHidden = true
self.sendButtonNode.layer.animateScale(from: 1.0, to: 0.2, duration: 0.2, timingFunction: kCAMediaTimingFunctionLinear, removeOnCompletion: false) self.sendButtonNode.layer.animateScale(from: 1.0, to: 0.2, duration: 0.2, timingFunction: kCAMediaTimingFunctionLinear, removeOnCompletion: false)
self.sendButtonNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, timingFunction: kCAMediaTimingFunctionLinear, removeOnCompletion: false) self.sendButtonNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, timingFunction: kCAMediaTimingFunctionLinear, removeOnCompletion: false)
} }
@ -349,11 +377,14 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
completedBubble = true completedBubble = true
intermediateCompletion() intermediateCompletion()
}) })
self.messageClipNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: (self.messageClipNode.bounds.width - initialWidth) / 2.0, y: clipDelta), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, additive: true) self.messageClipNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: (self.messageClipNode.bounds.width - initialWidth) / 2.0, y: clipDelta + self.scrollNode.view.contentOffset.y), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, additive: true)
self.messageBackgroundNode.layer.animateBounds(from: self.messageBackgroundNode.bounds, to: toFrame, duration: duration, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false) self.messageBackgroundNode.layer.animateBounds(from: self.messageBackgroundNode.bounds, to: toFrame, duration: duration, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false)
self.messageBackgroundNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: (initialWidth - self.messageClipNode.bounds.width) / 2.0, y: delta), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, additive: true) self.messageBackgroundNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: (initialWidth - self.messageClipNode.bounds.width) / 2.0, y: delta), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, additive: true)
self.messageTextNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: delta * 2.0), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, additive: true)
let textOffset = self.textInputNode.textView.contentSize.height - self.textInputNode.textView.contentOffset.y - self.textInputNode.textView.frame.height
self.fromMessageTextNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: delta * 2.0 + textOffset), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, additive: true)
self.toMessageTextNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: delta * 2.0 + textOffset), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, additive: true)
} }
self.contentContainerNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 160.0, y: 0.0), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, additive: true) self.contentContainerNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 160.0, y: 0.0), duration: duration, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, additive: true)
@ -364,7 +395,8 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
self.validLayout = layout self.validLayout = layout
transition.updateFrame(node: self.coverNode, frame: self.textFieldFrame) transition.updateFrame(node: self.textCoverNode, frame: self.textFieldFrame)
transition.updateFrame(node: self.buttonCoverNode, frame: self.sendButtonFrame.offsetBy(dx: 1.0, dy: 0.0))
transition.updateFrame(view: self.effectView, frame: CGRect(origin: CGPoint(), size: layout.size)) transition.updateFrame(view: self.effectView, frame: CGRect(origin: CGPoint(), size: layout.size))
transition.updateFrame(node: self.dimNode, frame: CGRect(origin: CGPoint(), size: layout.size)) transition.updateFrame(node: self.dimNode, frame: CGRect(origin: CGPoint(), size: layout.size))
@ -384,7 +416,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
let insets = layout.insets(options: [.statusBar, .input]) let insets = layout.insets(options: [.statusBar, .input])
let inputHeight = layout.inputHeight ?? 0.0 let inputHeight = layout.inputHeight ?? 0.0
var contentOrigin = CGPoint(x: layout.size.width - sideInset - contentSize.width, y: layout.size.height - 6.0 - insets.bottom - contentSize.height) var contentOrigin = CGPoint(x: layout.size.width - sideInset - contentSize.width - layout.safeInsets.right, y: layout.size.height - 6.0 - insets.bottom - contentSize.height)
if inputHeight > 0.0 { if inputHeight > 0.0 {
contentOrigin.y += 60.0 contentOrigin.y += 60.0
} }
@ -398,7 +430,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
} }
let initialSendButtonFrame = self.sendButtonFrame let initialSendButtonFrame = self.sendButtonFrame
var sendButtonFrame = CGRect(origin: CGPoint(x: layout.size.width - initialSendButtonFrame.width + 1.0 - UIScreenPixel, y: layout.size.height - insets.bottom - initialSendButtonFrame.height), size: initialSendButtonFrame.size) var sendButtonFrame = CGRect(origin: CGPoint(x: layout.size.width - initialSendButtonFrame.width + 1.0 - UIScreenPixel - layout.safeInsets.right, y: layout.size.height - insets.bottom - initialSendButtonFrame.height), size: initialSendButtonFrame.size)
if inputHeight.isZero { if inputHeight.isZero {
sendButtonFrame.origin.y -= 60.0 sendButtonFrame.origin.y -= 60.0
} }
@ -438,7 +470,8 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
var textFrame = self.textFieldFrame var textFrame = self.textFieldFrame
textFrame.origin = CGPoint(x: 13.0, y: 6.0 - UIScreenPixel) textFrame.origin = CGPoint(x: 13.0, y: 6.0 - UIScreenPixel)
textFrame.size.height = self.textInputNode.textView.contentSize.height textFrame.size.height = self.textInputNode.textView.contentSize.height
self.messageTextNode.frame = textFrame self.fromMessageTextNode.frame = textFrame
self.toMessageTextNode.frame = textFrame
} }
@objc private func dimTapGesture(_ recognizer: UITapGestureRecognizer) { @objc private func dimTapGesture(_ recognizer: UITapGestureRecognizer) {

View File

@ -14,6 +14,13 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode {
var sendButtonLongPressed: (() -> Void)? var sendButtonLongPressed: (() -> Void)?
private var gestureRecognizer: UILongPressGestureRecognizer?
var sendButtonLongPressEnabled = false {
didSet {
self.gestureRecognizer?.isEnabled = self.sendButtonLongPressEnabled
}
}
init(theme: PresentationTheme, presentController: @escaping (ViewController) -> Void) { init(theme: PresentationTheme, presentController: @escaping (ViewController) -> Void) {
self.micButton = ChatTextInputMediaRecordingButton(theme: theme, presentController: presentController) self.micButton = ChatTextInputMediaRecordingButton(theme: theme, presentController: presentController)
self.sendButton = HighlightTrackingButton() self.sendButton = HighlightTrackingButton()
@ -29,10 +36,20 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode {
self.sendButton.highligthedChanged = { [weak self] highlighted in self.sendButton.highligthedChanged = { [weak self] highlighted in
if let strongSelf = self { if let strongSelf = self {
if highlighted { if strongSelf.sendButtonHasApplyIcon || !strongSelf.sendButtonLongPressEnabled {
strongSelf.sendButton.layer.animateScale(from: 1.0, to: 0.75, duration: 0.7, removeOnCompletion: false) if highlighted {
} else if let presentationLayer = strongSelf.sendButton.layer.presentation() { strongSelf.layer.removeAnimation(forKey: "opacity")
strongSelf.sendButton.layer.animateScale(from: CGFloat((presentationLayer.value(forKeyPath: "transform.scale.y") as? NSNumber)?.floatValue ?? 1.0), to: 1.0, duration: 0.25, removeOnCompletion: false) strongSelf.alpha = 0.4
} else {
strongSelf.alpha = 1.0
strongSelf.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
}
} else {
if highlighted {
strongSelf.sendButton.layer.animateScale(from: 1.0, to: 0.75, duration: 0.4, removeOnCompletion: false)
} else if let presentationLayer = strongSelf.sendButton.layer.presentation() {
strongSelf.sendButton.layer.animateScale(from: CGFloat((presentationLayer.value(forKeyPath: "transform.scale.y") as? NSNumber)?.floatValue ?? 1.0), to: 1.0, duration: 0.25, removeOnCompletion: false)
}
} }
} }
} }
@ -42,17 +59,17 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode {
self.addSubnode(self.expandMediaInputButton) self.addSubnode(self.expandMediaInputButton)
} }
override func didLoad() { override func didLoad() {
super.didLoad() super.didLoad()
let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.handleLongPress(_:))) let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.handleLongPress(_:)))
gestureRecognizer.minimumPressDuration = 0.7 gestureRecognizer.minimumPressDuration = 0.4
self.gestureRecognizer = gestureRecognizer
self.sendButton.addGestureRecognizer(gestureRecognizer) self.sendButton.addGestureRecognizer(gestureRecognizer)
} }
@objc func handleLongPress(_ gestureRecognizer: UILongPressGestureRecognizer) { @objc func handleLongPress(_ gestureRecognizer: UILongPressGestureRecognizer) {
if gestureRecognizer.state == .began { if !self.sendButtonHasApplyIcon && gestureRecognizer.state == .began {
self.sendButtonLongPressed?() self.sendButtonLongPressed?()
} }
} }

View File

@ -732,6 +732,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
} }
self.textPlaceholderNode.frame = CGRect(origin: self.textPlaceholderNode.frame.origin, size: placeholderSize) self.textPlaceholderNode.frame = CGRect(origin: self.textPlaceholderNode.frame.origin, size: placeholderSize)
} }
self.actionButtons.sendButtonLongPressEnabled = peer.id != interfaceState.accountPeerId && peer.id.namespace != Namespaces.Peer.SecretChat
} }
let sendButtonHasApplyIcon = interfaceState.interfaceState.editMessage != nil let sendButtonHasApplyIcon = interfaceState.interfaceState.editMessage != nil

View File

@ -150,7 +150,7 @@ func uploadCustomWallpaper(context: AccountContext, wallpaper: WallpaperGalleryE
let _ = (updatePresentationThemeSettingsInteractively(accountManager: accountManager, { current in let _ = (updatePresentationThemeSettingsInteractively(accountManager: accountManager, { current in
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
themeSpecificChatWallpapers[current.theme.index] = wallpaper themeSpecificChatWallpapers[current.theme.index] = wallpaper
return PresentationThemeSettings(chatWallpaper: wallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, themeTintColors: current.themeTintColors, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) return PresentationThemeSettings(chatWallpaper: wallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
})).start() })).start()
} }

View File

@ -483,11 +483,6 @@ private enum DebugControllerEntry: ItemListNodeEntry {
guard let strings = try? encoder.encode(theme), let _ = try? strings.write(toFile: path, atomically: true, encoding: .utf8) else { guard let strings = try? encoder.encode(theme), let _ = try? strings.write(toFile: path, atomically: true, encoding: .utf8) else {
return return
} }
// let encoder = JSONEncoder()
// guard let data = try? encoder.encode(theme), let _ = try? data.write(to: URL(fileURLWithPath: path)) else {
// return
// }
let controller = PeerSelectionController(context: context, filter: [.onlyWriteable, .excludeDisabled]) let controller = PeerSelectionController(context: context, filter: [.onlyWriteable, .excludeDisabled])
controller.peerSelected = { [weak controller] peerId in controller.peerSelected = { [weak controller] peerId in

View File

@ -93,6 +93,16 @@ extension String {
return emojis return emojis
} }
var trimmingEmojis: String {
var string: String = ""
self.enumerateSubstrings(in: self.startIndex ..< self.endIndex, options: .byComposedCharacterSequences) { substring, _, _, _ in
if let substring = substring, !substring.containsEmoji {
string.append(substring)
}
}
return string
}
var normalizedEmoji: String { var normalizedEmoji: String {
var string = "" var string = ""

View File

@ -112,7 +112,19 @@ public func fetchCachedResourceRepresentation(account: Account, resource: MediaR
} else if let representation = representation as? CachedEmojiRepresentation { } else if let representation = representation as? CachedEmojiRepresentation {
return fetchEmojiRepresentation(account: account, resource: resource, representation: representation) return fetchEmojiRepresentation(account: account, resource: resource, representation: representation)
} else if let representation = representation as? CachedAnimatedStickerRepresentation { } else if let representation = representation as? CachedAnimatedStickerRepresentation {
return account.postbox.mediaBox.resourceData(resource, option: .complete(waitUntilFetchStatus: false)) let data: Signal<MediaResourceData, NoError>
if let resource = resource as? LocalBundleResource {
data = Signal { subscriber in
if let path = frameworkBundle.path(forResource: resource.name, ofType: resource.ext), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: [.mappedRead]) {
subscriber.putNext(MediaResourceData(path: path, offset: 0, size: data.count, complete: true))
subscriber.putCompletion()
}
return EmptyDisposable
}
} else {
data = account.postbox.mediaBox.resourceData(resource, option: .complete(waitUntilFetchStatus: false))
}
return data
|> mapToSignal { data -> Signal<CachedMediaResourceRepresentationResult, NoError> in |> mapToSignal { data -> Signal<CachedMediaResourceRepresentationResult, NoError> in
if !data.complete { if !data.complete {
return .complete() return .complete()

View File

@ -531,9 +531,9 @@ private enum GroupInfoEntry: ItemListNodeEntry {
let label: String? let label: String?
switch memberStatus { switch memberStatus {
case let .owner(rank): case let .owner(rank):
label = rank ?? strings.GroupInfo_LabelOwner label = rank?.trimmingEmojis ?? strings.GroupInfo_LabelOwner
case let .admin(rank): case let .admin(rank):
label = rank ?? strings.GroupInfo_LabelAdmin label = rank?.trimmingEmojis ?? strings.GroupInfo_LabelAdmin
case .member: case .member:
label = nil label = nil
} }

View File

@ -26,11 +26,12 @@ class ItemListSingleLineInputItem: ListViewItem, ItemListItem {
let sectionId: ItemListSectionId let sectionId: ItemListSectionId
let action: () -> Void let action: () -> Void
let textUpdated: (String) -> Void let textUpdated: (String) -> Void
let shouldUpdateText: (String) -> Bool
let processPaste: ((String) -> String)? let processPaste: ((String) -> String)?
let updatedFocus: ((Bool) -> Void)? let updatedFocus: ((Bool) -> Void)?
let tag: ItemListItemTag? let tag: ItemListItemTag?
init(theme: PresentationTheme, title: NSAttributedString, text: String, placeholder: String, type: ItemListSingleLineInputItemType = .regular(capitalization: true, autocorrection: true), returnKeyType: UIReturnKeyType = .`default`, spacing: CGFloat = 0.0, clearButton: Bool = false, enabled: Bool = true, tag: ItemListItemTag? = nil, sectionId: ItemListSectionId, textUpdated: @escaping (String) -> Void, processPaste: ((String) -> String)? = nil, updatedFocus: ((Bool) -> Void)? = nil, action: @escaping () -> Void) { init(theme: PresentationTheme, title: NSAttributedString, text: String, placeholder: String, type: ItemListSingleLineInputItemType = .regular(capitalization: true, autocorrection: true), returnKeyType: UIReturnKeyType = .`default`, spacing: CGFloat = 0.0, clearButton: Bool = false, enabled: Bool = true, tag: ItemListItemTag? = nil, sectionId: ItemListSectionId, textUpdated: @escaping (String) -> Void, shouldUpdateText: @escaping (String) -> Bool = { _ in return true }, processPaste: ((String) -> String)? = nil, updatedFocus: ((Bool) -> Void)? = nil, action: @escaping () -> Void) {
self.theme = theme self.theme = theme
self.title = title self.title = title
self.text = text self.text = text
@ -43,6 +44,7 @@ class ItemListSingleLineInputItem: ListViewItem, ItemListItem {
self.tag = tag self.tag = tag
self.sectionId = sectionId self.sectionId = sectionId
self.textUpdated = textUpdated self.textUpdated = textUpdated
self.shouldUpdateText = shouldUpdateText
self.processPaste = processPaste self.processPaste = processPaste
self.updatedFocus = updatedFocus self.updatedFocus = updatedFocus
self.action = action self.action = action
@ -351,6 +353,10 @@ class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDelegate, It
} }
@objc internal func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { @objc internal func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let item = self.item, !item.shouldUpdateText(string) {
return false
}
if string.count > 1, let item = self.item, let processPaste = item.processPaste { if string.count > 1, let item = self.item, let processPaste = item.processPaste {
let result = processPaste(string) let result = processPaste(string)
if result != string { if result != string {

View File

@ -8,7 +8,7 @@ import TelegramCore
import TelegramPresentationData import TelegramPresentationData
import DeviceAccess import DeviceAccess
func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaOptions: MessageMediaEditingOptions?, saveEditedPhotos: Bool, allowGrouping: Bool, theme: PresentationTheme, strings: PresentationStrings, parentController: LegacyController, recentlyUsedInlineBots: [Peer], initialCaption: String, openGallery: @escaping () -> Void, openCamera: @escaping (TGAttachmentCameraView?, TGMenuSheetController?) -> Void, openFileGallery: @escaping () -> Void, openWebSearch: @escaping () -> Void, openMap: @escaping () -> Void, openContacts: @escaping () -> Void, openPoll: @escaping () -> Void, presentSelectionLimitExceeded: @escaping () -> Void, presentCantSendMultipleFiles: @escaping () -> Void, sendMessagesWithSignals: @escaping ([Any]?) -> Void, selectRecentlyUsedInlineBot: @escaping (Peer) -> Void) -> TGMenuSheetController { func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaOptions: MessageMediaEditingOptions?, saveEditedPhotos: Bool, allowGrouping: Bool, theme: PresentationTheme, strings: PresentationStrings, parentController: LegacyController, recentlyUsedInlineBots: [Peer], initialCaption: String, openGallery: @escaping () -> Void, openCamera: @escaping (TGAttachmentCameraView?, TGMenuSheetController?) -> Void, openFileGallery: @escaping () -> Void, openWebSearch: @escaping () -> Void, openMap: @escaping () -> Void, openContacts: @escaping () -> Void, openPoll: @escaping () -> Void, presentSelectionLimitExceeded: @escaping () -> Void, presentCantSendMultipleFiles: @escaping () -> Void, sendMessagesWithSignals: @escaping ([Any]?, Bool) -> Void, selectRecentlyUsedInlineBot: @escaping (Peer) -> Void) -> TGMenuSheetController {
let isSecretChat = peer.id.namespace == Namespaces.Peer.SecretChat let isSecretChat = peer.id.namespace == Namespaces.Peer.SecretChat
let controller = TGMenuSheetController(context: parentController.context, dark: false)! let controller = TGMenuSheetController(context: parentController.context, dark: false)!
@ -58,10 +58,13 @@ func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaOptions:
carouselItem.selectionLimitExceeded = { carouselItem.selectionLimitExceeded = {
presentSelectionLimitExceeded() presentSelectionLimitExceeded()
} }
if (peer is TelegramUser) && peer.id != context.account.peerId { if peer.id != context.account.peerId {
carouselItem.hasTimer = true if peer is TelegramUser {
carouselItem.hasTimer = true
}
carouselItem.hasSilentPosting = !isSecretChat
} }
carouselItem.sendPressed = { [weak controller, weak carouselItem] currentItem, asFiles in carouselItem.sendPressed = { [weak controller, weak carouselItem] currentItem, asFiles, silentPosting in
if let controller = controller, let carouselItem = carouselItem { if let controller = controller, let carouselItem = carouselItem {
let intent: TGMediaAssetsControllerIntent = asFiles ? TGMediaAssetsControllerSendFileIntent : TGMediaAssetsControllerSendMediaIntent let intent: TGMediaAssetsControllerIntent = asFiles ? TGMediaAssetsControllerSendFileIntent : TGMediaAssetsControllerSendMediaIntent
let signals = TGMediaAssetsController.resultSignals(for: carouselItem.selectionContext, editingContext: carouselItem.editingContext, intent: intent, currentItem: currentItem, storeAssets: true, useMediaCache: false, descriptionGenerator: legacyAssetPickerItemGenerator(), saveEditedPhotos: saveEditedPhotos) let signals = TGMediaAssetsController.resultSignals(for: carouselItem.selectionContext, editingContext: carouselItem.editingContext, intent: intent, currentItem: currentItem, storeAssets: true, useMediaCache: false, descriptionGenerator: legacyAssetPickerItemGenerator(), saveEditedPhotos: saveEditedPhotos)
@ -69,7 +72,7 @@ func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaOptions:
presentCantSendMultipleFiles() presentCantSendMultipleFiles()
} else { } else {
controller.dismiss(animated: true) controller.dismiss(animated: true)
sendMessagesWithSignals(signals) sendMessagesWithSignals(signals, silentPosting)
} }
} }
}; };
@ -181,8 +184,12 @@ func presentLegacyPasteMenu(context: AccountContext, peer: Peer, saveEditedPhoto
legacyController.bind(controller: navigationController) legacyController.bind(controller: navigationController)
var hasTimer = false var hasTimer = false
if (peer is TelegramUser) && peer.id != context.account.peerId { var hasSilentPosting = false
hasTimer = true if peer.id != context.account.peerId {
if peer is TelegramUser {
hasTimer = true
}
hasSilentPosting = true
} }
let recipientName = peer.displayTitle let recipientName = peer.displayTitle

View File

@ -55,8 +55,11 @@ func presentedLegacyCamera(context: AccountContext, peer: Peer, cameraView: TGAt
controller.inhibitDocumentCaptions = false controller.inhibitDocumentCaptions = false
controller.suggestionContext = legacySuggestionContext(account: context.account, peerId: peer.id) controller.suggestionContext = legacySuggestionContext(account: context.account, peerId: peer.id)
controller.recipientName = peer.displayTitle controller.recipientName = peer.displayTitle
if (peer is TelegramUser) && peer.id != context.account.peerId { if peer.id != context.account.peerId {
controller.hasTimer = true if peer is TelegramUser {
controller.hasTimer = true
}
controller.hasSilentPosting = true
} }
let screenSize = parentController.view.bounds.size let screenSize = parentController.view.bounds.size

View File

@ -53,15 +53,19 @@ private final class LegacyComponentsOverlayWindowManagerImpl: NSObject, LegacyCo
func bindController(_ controller: UIViewController!) { func bindController(_ controller: UIViewController!) {
self.contentController = controller self.contentController = controller
if controller.prefersStatusBarHidden {
self.controller?.statusBar.statusBarStyle = .Hide
}
controller.state_setNeedsStatusBarAppearanceUpdate({ [weak self, weak controller] in controller.state_setNeedsStatusBarAppearanceUpdate({ [weak self, weak controller] in
if let parentController = self?.parentController, let controller = controller { if let parentController = self?.parentController, let controller = controller {
if parentController.statusBar.statusBarStyle != .Hide { if parentController.statusBar.statusBarStyle != .Hide && !controller.prefersStatusBarHidden {
self?.controller?.statusBar.statusBarStyle = StatusBarStyle(systemStyle: controller.preferredStatusBarStyle) self?.controller?.statusBar.statusBarStyle = StatusBarStyle(systemStyle: controller.preferredStatusBarStyle)
} }
} }
}) })
if let parentController = self.parentController { if let parentController = self.parentController {
if parentController.statusBar.statusBarStyle != .Hide { if parentController.statusBar.statusBarStyle != .Hide && !controller.prefersStatusBarHidden {
self.controller?.statusBar.statusBarStyle = StatusBarStyle(systemStyle: controller.preferredStatusBarStyle) self.controller?.statusBar.statusBarStyle = StatusBarStyle(systemStyle: controller.preferredStatusBarStyle)
} }
} }

View File

@ -15,11 +15,16 @@ func guessMimeTypeByFileExtension(_ ext: String) -> String {
} }
func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, context: AccountContext, peer: Peer, captionsEnabled: Bool = true, storeCreatedAssets: Bool = true, showFileTooltip: Bool = false, initialCaption: String, presentWebSearch: (() -> Void)?, presentSelectionLimitExceeded: @escaping () -> Void) { func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, context: AccountContext, peer: Peer, captionsEnabled: Bool = true, storeCreatedAssets: Bool = true, showFileTooltip: Bool = false, initialCaption: String, presentWebSearch: (() -> Void)?, presentSelectionLimitExceeded: @escaping () -> Void) {
let isSecretChat = peer.id.namespace == Namespaces.Peer.SecretChat
controller.captionsEnabled = captionsEnabled controller.captionsEnabled = captionsEnabled
controller.inhibitDocumentCaptions = false controller.inhibitDocumentCaptions = false
controller.suggestionContext = legacySuggestionContext(account: context.account, peerId: peer.id) controller.suggestionContext = legacySuggestionContext(account: context.account, peerId: peer.id)
if (peer is TelegramUser) && peer.id != context.account.peerId { if peer.id != context.account.peerId {
controller.hasTimer = true if peer is TelegramUser {
controller.hasTimer = true
}
controller.hasSilentPosting = !isSecretChat
} }
controller.dismissalBlock = { controller.dismissalBlock = {
} }

View File

@ -130,10 +130,7 @@ private func chatMessageGalleryControllerData(context: AccountContext, message:
if let file = galleryMedia as? TelegramMediaFile { if let file = galleryMedia as? TelegramMediaFile {
if let fileName = file.fileName { if let fileName = file.fileName {
let ext = (fileName as NSString).pathExtension.lowercased() let ext = (fileName as NSString).pathExtension.lowercased()
if ext == "tgios-theme" { if ext == "wav" || ext == "opus" {
return .theme(file)
}
else if ext == "wav" || ext == "opus" {
return .audio(file) return .audio(file)
} else if ext == "json", let fileSize = file.size, fileSize < 1024 * 1024 { } else if ext == "json", let fileSize = file.size, fileSize < 1024 * 1024 {
if let path = context.account.postbox.mediaBox.completedResourcePath(file.resource), let _ = LOTComposition(filePath: path) { if let path = context.account.postbox.mediaBox.completedResourcePath(file.resource), let _ = LOTComposition(filePath: path) {

View File

@ -288,6 +288,15 @@ private func themeAutoNightSettingsControllerEntries(theme: PresentationTheme, s
entries.append(.settingInfo(theme, strings.AutoNightTheme_AutomaticHelp("\(Int(threshold * 100.0))").0.replacingOccurrences(of: "%%", with: "%"))) entries.append(.settingInfo(theme, strings.AutoNightTheme_AutomaticHelp("\(Int(threshold * 100.0))").0.replacingOccurrences(of: "%%", with: "%")))
} }
switch switchSetting.trigger {
case .none:
break
case .timeBased, .brightness:
entries.append(.themeHeader(theme, strings.AutoNightTheme_PreferredTheme))
entries.append(.themeNightBlue(theme, strings.Appearance_ThemeCarouselTintedNight, switchSetting.theme == .nightAccent))
entries.append(.themeNight(theme, strings.Appearance_ThemeCarouselNewNight, switchSetting.theme == .night))
}
return entries return entries
} }

View File

@ -189,7 +189,7 @@ final class ThemeGridController: ViewController {
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
themeSpecificChatWallpapers[current.theme.index] = fallbackWallpaper themeSpecificChatWallpapers[current.theme.index] = fallbackWallpaper
return PresentationThemeSettings(chatWallpaper: fallbackWallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, themeTintColors: current.themeTintColors, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) return PresentationThemeSettings(chatWallpaper: fallbackWallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
})).start() })).start()
break break
} }
@ -261,7 +261,7 @@ final class ThemeGridController: ViewController {
} else { } else {
wallpaper = .builtin(WallpaperSettings()) wallpaper = .builtin(WallpaperSettings())
} }
return PresentationThemeSettings(chatWallpaper: wallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: [:], themeTintColors: current.themeTintColors, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) return PresentationThemeSettings(chatWallpaper: wallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: [:], fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
}) })
}).start() }).start()

View File

@ -89,7 +89,7 @@ final class ThemePreviewController: ViewController {
current = PresentationThemeSettings.defaultSettings current = PresentationThemeSettings.defaultSettings
} }
return PresentationThemeSettings(chatWallpaper: .color(0xffffff), theme: .builtin(.day), themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, themeTintColors: current.themeTintColors, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) return PresentationThemeSettings(chatWallpaper: .color(0xffffff), theme: .builtin(.day), themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
}) })
}).start(completed: { [weak self] in }).start(completed: { [weak self] in
if let strongSelf = self { if let strongSelf = self {

View File

@ -130,16 +130,13 @@ class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
let peers = SimpleDictionary<PeerId, Peer>() let peers = SimpleDictionary<PeerId, Peer>()
let messages = SimpleDictionary<MessageId, Message>() let messages = SimpleDictionary<MessageId, Message>()
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: 1) let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: 1)
let peer1 = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: []) let peer1 = TelegramUser(id: peerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [])
let peer2 = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: []) let peer2 = TelegramUser(id: peerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [])
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: PeerId(namespace: 0, id: 1), namespace: 0, id: 0), timestamp: 66003)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66003, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer1, text: "", attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer1), combinedReadState: nil, notificationSettings: nil, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
// items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: PeerId(namespace: 0, id: 2), namespace: 0, id: 0), timestamp: 66000)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer1, text: "", attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer2), combinedReadState: nil, notificationSettings: nil, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: PeerId(namespace: 0, id: 1), namespace: 0, id: 0), timestamp: 66003)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66003, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer1, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer1), combinedReadState: nil, notificationSettings: nil, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: PeerId(namespace: 0, id: 2), namespace: 0, id: 0), timestamp: 66000)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer1, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer2), combinedReadState: nil, notificationSettings: nil, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
let params = ListViewItemLayoutParams(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right) let params = ListViewItemLayoutParams(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right)
if let chatNodes = self.chatNodes { if let chatNodes = self.chatNodes {
@ -189,27 +186,27 @@ class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
let otherPeerId = self.context.account.peerId let otherPeerId = self.context.account.peerId
var peers = SimpleDictionary<PeerId, Peer>() var peers = SimpleDictionary<PeerId, Peer>()
var messages = SimpleDictionary<MessageId, Message>() var messages = SimpleDictionary<MessageId, Message>()
peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_1_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: []) peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [])
peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_1_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: []) peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [])
let replyMessageId = MessageId(peerId: peerId, namespace: 0, id: 3) let replyMessageId = MessageId(peerId: peerId, namespace: 0, id: 3)
messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_ReplyText, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []) messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
let controllerInteraction = ChatControllerInteraction.default let controllerInteraction = ChatControllerInteraction.default
let chatPresentationData = ChatPresentationData(theme: ChatPresentationThemeData(theme: self.previewTheme, wallpaper: self.previewTheme.chat.defaultWallpaper), fontSize: self.presentationData.fontSize, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameDisplayOrder: self.presentationData.nameDisplayOrder, disableAnimations: false, largeEmoji: false) let chatPresentationData = ChatPresentationData(theme: ChatPresentationThemeData(theme: self.previewTheme, wallpaper: self.previewTheme.chat.defaultWallpaper), fontSize: self.presentationData.fontSize, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameDisplayOrder: self.presentationData.nameDisplayOrder, disableAnimations: false, largeEmoji: false)
items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66003, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [ReplyMessageAttribute(messageId: replyMessageId)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false)) items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 4, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 4), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66003, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: "", attributes: [ReplyMessageAttribute(messageId: replyMessageId)], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false))
items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66002, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_2_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false)) items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 3, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 3), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66002, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false))
items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false)) items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false))
let voiceAttributes: [TelegramMediaFileAttribute] = [.Audio(isVoice: true, duration: 14, title: nil, performer: nil, waveform: MemoryBuffer())] let voiceAttributes: [TelegramMediaFileAttribute] = [.Audio(isVoice: true, duration: 14, title: nil, performer: nil, waveform: MemoryBuffer())]
let voiceMedia = TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: LocalFileMediaResource(fileId: 0), previewRepresentations: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: nil, attributes: voiceAttributes) let voiceMedia = TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: LocalFileMediaResource(fileId: 0), previewRepresentations: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: nil, attributes: voiceAttributes)
items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false, forcedResourceStatus: FileMediaResourceStatus(mediaStatus: .playbackStatus(.playing), fetchStatus: .Local)), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false)) items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false, forcedResourceStatus: FileMediaResourceStatus(mediaStatus: .playbackStatus(.playing), fetchStatus: .Local)), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: "", attributes: [], media: [voiceMedia], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false))
items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_4_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false)) items.append(ChatMessageItem(presentationData: chatPresentationData, context: self.context, chatLocation: .peer(peerId), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .contact, automaticDownloadNetworkType: .cellular, isRecentActions: false), controllerInteraction: controllerInteraction, content: .message(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: "", attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), read: true, selection: .none, attributes: ChatMessageEntryAttributes(rank: nil, isContact: false)), disableDate: false))
let params = ListViewItemLayoutParams(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right) let params = ListViewItemLayoutParams(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right)
if let messageNodes = self.messageNodes { if let messageNodes = self.messageNodes {

View File

@ -392,12 +392,12 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
chatWallpaper = theme.chat.defaultWallpaper chatWallpaper = theme.chat.defaultWallpaper
} }
return PresentationThemeSettings(chatWallpaper: chatWallpaper, theme: theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, themeTintColors: current.themeTintColors, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) return PresentationThemeSettings(chatWallpaper: chatWallpaper, theme: theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
}) })
}).start() }).start()
}, selectFontSize: { size in }, selectFontSize: { size in
let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
return PresentationThemeSettings(chatWallpaper: current.chatWallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, themeTintColors: current.themeTintColors, fontSize: size, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) return PresentationThemeSettings(chatWallpaper: current.chatWallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, fontSize: size, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
}).start() }).start()
}, openWallpaperSettings: { }, openWallpaperSettings: {
pushControllerImpl?(ThemeGridController(context: context)) pushControllerImpl?(ThemeGridController(context: context))
@ -420,7 +420,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
updateState { $0.withDisplayColorSlider(false) } updateState { $0.withDisplayColorSlider(false) }
} }
return PresentationThemeSettings(chatWallpaper: chatWallpaper, theme: current.theme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, themeTintColors: current.themeTintColors, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) return PresentationThemeSettings(chatWallpaper: chatWallpaper, theme: current.theme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
}).start() }).start()
}, toggleColorSlider: { forceHidden in }, toggleColorSlider: { forceHidden in
updateState { $0.withDisplayColorSlider(forceHidden ? false : !$0.displayColorSlider) } updateState { $0.withDisplayColorSlider(forceHidden ? false : !$0.displayColorSlider) }
@ -428,11 +428,11 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
pushControllerImpl?(themeAutoNightSettingsController(context: context)) pushControllerImpl?(themeAutoNightSettingsController(context: context))
}, toggleLargeEmoji: { largeEmoji in }, toggleLargeEmoji: { largeEmoji in
let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
return PresentationThemeSettings(chatWallpaper: current.chatWallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, themeTintColors: current.themeTintColors, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: largeEmoji, disableAnimations: current.disableAnimations) return PresentationThemeSettings(chatWallpaper: current.chatWallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: largeEmoji, disableAnimations: current.disableAnimations)
}).start() }).start()
}, disableAnimations: { value in }, disableAnimations: { value in
let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
return PresentationThemeSettings(chatWallpaper: current.chatWallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, themeTintColors: current.themeTintColors, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: value) return PresentationThemeSettings(chatWallpaper: current.chatWallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: value)
}).start() }).start()
}, selectAppIcon: { name in }, selectAppIcon: { name in
currentAppIconName.set(name) currentAppIconName.set(name)

View File

@ -359,9 +359,9 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode {
case .day: case .day:
name = item.strings.Appearance_ThemeCarouselDay name = item.strings.Appearance_ThemeCarouselDay
case .night: case .night:
name = "Night" //item.strings.Appearance_ThemeCarouselNight name = item.strings.Appearance_ThemeCarouselNewNight
case .nightAccent: case .nightAccent:
name = "Tinted Night" //item.strings.Appearance_ThemeCarouselNightBlue name = item.strings.Appearance_ThemeCarouselTintedNight
} }
} else { } else {
name = nil name = nil

View File

@ -380,7 +380,7 @@ class WallpaperGalleryController: ViewController {
let _ = (updatePresentationThemeSettingsInteractively(accountManager: strongSelf.context.sharedContext.accountManager, { current in let _ = (updatePresentationThemeSettingsInteractively(accountManager: strongSelf.context.sharedContext.accountManager, { current in
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
themeSpecificChatWallpapers[current.theme.index] = wallpaper themeSpecificChatWallpapers[current.theme.index] = wallpaper
return PresentationThemeSettings(chatWallpaper: wallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, themeTintColors: current.themeTintColors, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) return PresentationThemeSettings(chatWallpaper: wallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
}) |> deliverOnMainQueue).start(completed: { }) |> deliverOnMainQueue).start(completed: {
self?.dismiss(forceAway: true) self?.dismiss(forceAway: true)
}) })

View File

@ -139,7 +139,7 @@ final class WallpaperUploadManager {
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
themeSpecificChatWallpapers[current.theme.index] = updatedWallpaper themeSpecificChatWallpapers[current.theme.index] = updatedWallpaper
return PresentationThemeSettings(chatWallpaper: updatedWallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, themeTintColors: current.themeTintColors, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) return PresentationThemeSettings(chatWallpaper: updatedWallpaper, theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
})).start() })).start()
} }
} }

View File

@ -55,7 +55,7 @@ enum WebSearchMode {
} }
enum WebSearchControllerMode { enum WebSearchControllerMode {
case media(completion: (ChatContextResultCollection, TGMediaSelectionContext, TGMediaEditingContext) -> Void) case media(completion: (ChatContextResultCollection, TGMediaSelectionContext, TGMediaEditingContext, Bool) -> Void)
case avatar(initialQuery: String?, completion: (UIImage) -> Void) case avatar(initialQuery: String?, completion: (UIImage) -> Void)
var mode: WebSearchMode { var mode: WebSearchMode {
@ -231,7 +231,7 @@ final class WebSearchController: ViewController {
selectionState.setItem(currentItem, selected: true) selectionState.setItem(currentItem, selected: true)
} }
if case let .media(sendSelected) = mode { if case let .media(sendSelected) = mode {
sendSelected(results, selectionState, editingState) sendSelected(results, selectionState, editingState, false)
} }
} }
}, avatarCompleted: { result in }, avatarCompleted: { result in

View File

@ -34,6 +34,10 @@
091BEAB3214552D9003AEA30 /* Vision.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D02DADBE2138D76F00116225 /* Vision.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 091BEAB3214552D9003AEA30 /* Vision.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D02DADBE2138D76F00116225 /* Vision.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
0921F60B228C8765001A13D7 /* ItemListPlaceholderItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0921F60A228C8765001A13D7 /* ItemListPlaceholderItem.swift */; }; 0921F60B228C8765001A13D7 /* ItemListPlaceholderItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0921F60A228C8765001A13D7 /* ItemListPlaceholderItem.swift */; };
0921F60E228EE000001A13D7 /* ChatMessageActionUrlAuthController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0921F60D228EE000001A13D7 /* ChatMessageActionUrlAuthController.swift */; }; 0921F60E228EE000001A13D7 /* ChatMessageActionUrlAuthController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0921F60D228EE000001A13D7 /* ChatMessageActionUrlAuthController.swift */; };
092A65CE22EC98B10032E20C /* meh.tgs in Resources */ = {isa = PBXBuildFile; fileRef = 092A65CB22EC98AF0032E20C /* meh.tgs */; };
092A65CF22EC98B10032E20C /* lol.tgs in Resources */ = {isa = PBXBuildFile; fileRef = 092A65CC22EC98AF0032E20C /* lol.tgs */; };
092A65D022EC98B10032E20C /* thumbsup.tgs in Resources */ = {isa = PBXBuildFile; fileRef = 092A65CD22EC98B00032E20C /* thumbsup.tgs */; };
092A65D322ED6F8D0032E20C /* heart.tgs in Resources */ = {isa = PBXBuildFile; fileRef = 092A65D222ED6F8C0032E20C /* heart.tgs */; };
092F368D2154AAEA001A9F49 /* SFCompactRounded-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 092F368C2154AAE9001A9F49 /* SFCompactRounded-Semibold.otf */; }; 092F368D2154AAEA001A9F49 /* SFCompactRounded-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 092F368C2154AAE9001A9F49 /* SFCompactRounded-Semibold.otf */; };
092F36902157AB46001A9F49 /* ItemListCallListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 092F368F2157AB46001A9F49 /* ItemListCallListItem.swift */; }; 092F36902157AB46001A9F49 /* ItemListCallListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 092F368F2157AB46001A9F49 /* ItemListCallListItem.swift */; };
09310D32213ED5FC0020033A /* anim_ungroup.json in Resources */ = {isa = PBXBuildFile; fileRef = 09310D1A213BC5DE0020033A /* anim_ungroup.json */; }; 09310D32213ED5FC0020033A /* anim_ungroup.json in Resources */ = {isa = PBXBuildFile; fileRef = 09310D1A213BC5DE0020033A /* anim_ungroup.json */; };
@ -1266,6 +1270,10 @@
091954782294754E00E11046 /* AnimatedStickerUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatedStickerUtils.swift; sourceTree = "<group>"; }; 091954782294754E00E11046 /* AnimatedStickerUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatedStickerUtils.swift; sourceTree = "<group>"; };
0921F60A228C8765001A13D7 /* ItemListPlaceholderItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemListPlaceholderItem.swift; sourceTree = "<group>"; }; 0921F60A228C8765001A13D7 /* ItemListPlaceholderItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemListPlaceholderItem.swift; sourceTree = "<group>"; };
0921F60D228EE000001A13D7 /* ChatMessageActionUrlAuthController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageActionUrlAuthController.swift; sourceTree = "<group>"; }; 0921F60D228EE000001A13D7 /* ChatMessageActionUrlAuthController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageActionUrlAuthController.swift; sourceTree = "<group>"; };
092A65CB22EC98AF0032E20C /* meh.tgs */ = {isa = PBXFileReference; lastKnownFileType = file; path = meh.tgs; sourceTree = "<group>"; };
092A65CC22EC98AF0032E20C /* lol.tgs */ = {isa = PBXFileReference; lastKnownFileType = file; path = lol.tgs; sourceTree = "<group>"; };
092A65CD22EC98B00032E20C /* thumbsup.tgs */ = {isa = PBXFileReference; lastKnownFileType = file; path = thumbsup.tgs; sourceTree = "<group>"; };
092A65D222ED6F8C0032E20C /* heart.tgs */ = {isa = PBXFileReference; lastKnownFileType = file; path = heart.tgs; sourceTree = "<group>"; };
092F368C2154AAE9001A9F49 /* SFCompactRounded-Semibold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SFCompactRounded-Semibold.otf"; sourceTree = "<group>"; }; 092F368C2154AAE9001A9F49 /* SFCompactRounded-Semibold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SFCompactRounded-Semibold.otf"; sourceTree = "<group>"; };
092F368F2157AB46001A9F49 /* ItemListCallListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemListCallListItem.swift; sourceTree = "<group>"; }; 092F368F2157AB46001A9F49 /* ItemListCallListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemListCallListItem.swift; sourceTree = "<group>"; };
09310D1A213BC5DE0020033A /* anim_ungroup.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = anim_ungroup.json; sourceTree = "<group>"; }; 09310D1A213BC5DE0020033A /* anim_ungroup.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = anim_ungroup.json; sourceTree = "<group>"; };
@ -2589,6 +2597,17 @@
name = "Animated Stickers"; name = "Animated Stickers";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
092A65D122EC98B30032E20C /* Emoji */ = {
isa = PBXGroup;
children = (
092A65CC22EC98AF0032E20C /* lol.tgs */,
092A65CB22EC98AF0032E20C /* meh.tgs */,
092A65CD22EC98B00032E20C /* thumbsup.tgs */,
092A65D222ED6F8C0032E20C /* heart.tgs */,
);
path = Emoji;
sourceTree = "<group>";
};
092F368B2154AAD6001A9F49 /* Fonts */ = { 092F368B2154AAD6001A9F49 /* Fonts */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -3243,6 +3262,7 @@
D0471B521EFD8EBC0074D609 /* Resources */ = { D0471B521EFD8EBC0074D609 /* Resources */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
092A65D122EC98B30032E20C /* Emoji */,
09E2D9ED226F1AF300EA0AA4 /* Emoji.mapping */, 09E2D9ED226F1AF300EA0AA4 /* Emoji.mapping */,
D0955FB32191278C00F89427 /* PresentationStrings.mapping */, D0955FB32191278C00F89427 /* PresentationStrings.mapping */,
09310D13213BC5DE0020033A /* Animations */, 09310D13213BC5DE0020033A /* Animations */,
@ -5270,6 +5290,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
09874E4F21078FA100E190B8 /* Generic.html in Resources */, 09874E4F21078FA100E190B8 /* Generic.html in Resources */,
092A65CE22EC98B10032E20C /* meh.tgs in Resources */,
09874E5021078FA100E190B8 /* GenericUserScript.js in Resources */, 09874E5021078FA100E190B8 /* GenericUserScript.js in Resources */,
09874E5121078FA100E190B8 /* Instagram.html in Resources */, 09874E5121078FA100E190B8 /* Instagram.html in Resources */,
09874E5221078FA100E190B8 /* Twitch.html in Resources */, 09874E5221078FA100E190B8 /* Twitch.html in Resources */,
@ -5322,6 +5343,7 @@
D0E9BAAC1F056F4C00F079A4 /* stp_card_jcb@3x.png in Resources */, D0E9BAAC1F056F4C00F079A4 /* stp_card_jcb@3x.png in Resources */,
D0E9BA911F056F4C00F079A4 /* stp_card_amex@2x.png in Resources */, D0E9BA911F056F4C00F079A4 /* stp_card_amex@2x.png in Resources */,
D0E9BA931F056F4C00F079A4 /* stp_card_amex_template@2x.png in Resources */, D0E9BA931F056F4C00F079A4 /* stp_card_amex_template@2x.png in Resources */,
092A65CF22EC98B10032E20C /* lol.tgs in Resources */,
D0E9BAA91F056F4C00F079A4 /* stp_card_form_front@2x.png in Resources */, D0E9BAA91F056F4C00F079A4 /* stp_card_form_front@2x.png in Resources */,
D0E9BAA41F056F4C00F079A4 /* stp_card_discover_template@3x.png in Resources */, D0E9BAA41F056F4C00F079A4 /* stp_card_discover_template@3x.png in Resources */,
D0E9BAA81F056F4C00F079A4 /* stp_card_form_back@3x.png in Resources */, D0E9BAA81F056F4C00F079A4 /* stp_card_form_back@3x.png in Resources */,
@ -5335,12 +5357,14 @@
D0E9BA9C1F056F4C00F079A4 /* stp_card_cvc_amex@3x.png in Resources */, D0E9BA9C1F056F4C00F079A4 /* stp_card_cvc_amex@3x.png in Resources */,
D0E9BA991F056F4C00F079A4 /* stp_card_cvc@2x.png in Resources */, D0E9BA991F056F4C00F079A4 /* stp_card_cvc@2x.png in Resources */,
D0471B541EFD8ECA0074D609 /* currencies.json in Resources */, D0471B541EFD8ECA0074D609 /* currencies.json in Resources */,
092A65D022EC98B10032E20C /* thumbsup.tgs in Resources */,
0947350E2275D72100EA2312 /* anim_hide.json in Resources */, 0947350E2275D72100EA2312 /* anim_hide.json in Resources */,
D0E9BAB21F056F4C00F079A4 /* stp_card_mastercard_template@3x.png in Resources */, D0E9BAB21F056F4C00F079A4 /* stp_card_mastercard_template@3x.png in Resources */,
D0E9BA981F056F4C00F079A4 /* stp_card_applepay_template@3x.png in Resources */, D0E9BA981F056F4C00F079A4 /* stp_card_applepay_template@3x.png in Resources */,
D0E9BAA51F056F4C00F079A4 /* stp_card_form_applepay@2x.png in Resources */, D0E9BAA51F056F4C00F079A4 /* stp_card_form_applepay@2x.png in Resources */,
D0E9BAB81F056F4C00F079A4 /* stp_card_visa_template@3x.png in Resources */, D0E9BAB81F056F4C00F079A4 /* stp_card_visa_template@3x.png in Resources */,
D0AF797822C2E26500CECCB8 /* meson.build in Resources */, D0AF797822C2E26500CECCB8 /* meson.build in Resources */,
092A65D322ED6F8D0032E20C /* heart.tgs in Resources */,
D0E9BA9B1F056F4C00F079A4 /* stp_card_cvc_amex@2x.png in Resources */, D0E9BA9B1F056F4C00F079A4 /* stp_card_cvc_amex@2x.png in Resources */,
D0E9BAB61F056F4C00F079A4 /* stp_card_visa@3x.png in Resources */, D0E9BAB61F056F4C00F079A4 /* stp_card_visa@3x.png in Resources */,
D0E9BAA61F056F4C00F079A4 /* stp_card_form_applepay@3x.png in Resources */, D0E9BAA61F056F4C00F079A4 /* stp_card_form_applepay@3x.png in Resources */,

View File

@ -213,7 +213,7 @@ public enum PresentationThemeBaseColor: Int32, CaseIterable {
case .blue: case .blue:
values = (UIColor(rgb: 0x394cb5), UIColor(rgb: 0x7fd3fb)) values = (UIColor(rgb: 0x394cb5), UIColor(rgb: 0x7fd3fb))
case .cyan: case .cyan:
values = (UIColor(rgb: 0x00c2ed), UIColor(rgb: 0x00c2ed)) values = (UIColor(rgb: 0x3472a8), UIColor(rgb: 0x76e8e8))
case .green: case .green:
values = (UIColor(rgb: 0x608236), UIColor(rgb: 0xb1e786)) values = (UIColor(rgb: 0x608236), UIColor(rgb: 0xb1e786))
case .pink: case .pink:
@ -227,7 +227,7 @@ public enum PresentationThemeBaseColor: Int32, CaseIterable {
case .yellow: case .yellow:
values = (UIColor(rgb: 0xdda23a), UIColor(rgb: 0xfbe589)) values = (UIColor(rgb: 0xdda23a), UIColor(rgb: 0xfbe589))
case .gray: case .gray:
values = (UIColor(rgb: 0x6d839e), UIColor(rgb: 0x6d839e)) values = (UIColor(rgb: 0x595b70), UIColor(rgb: 0x829199))
case .black: case .black:
values = (UIColor(rgb: 0x000000), UIColor(rgb: 0x000000)) values = (UIColor(rgb: 0x000000), UIColor(rgb: 0x000000))
case .white: case .white:
@ -274,7 +274,6 @@ public struct PresentationThemeSettings: PreferencesEntry {
public var theme: PresentationThemeReference public var theme: PresentationThemeReference
public var themeSpecificAccentColors: [Int64: PresentationThemeAccentColor] public var themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]
public var themeSpecificChatWallpapers: [Int64: TelegramWallpaper] public var themeSpecificChatWallpapers: [Int64: TelegramWallpaper]
public var themeTintColors: Bool
public var fontSize: PresentationFontSize public var fontSize: PresentationFontSize
public var automaticThemeSwitchSetting: AutomaticThemeSwitchSetting public var automaticThemeSwitchSetting: AutomaticThemeSwitchSetting
public var largeEmoji: Bool public var largeEmoji: Bool
@ -304,15 +303,14 @@ public struct PresentationThemeSettings: PreferencesEntry {
} }
public static var defaultSettings: PresentationThemeSettings { public static var defaultSettings: PresentationThemeSettings {
return PresentationThemeSettings(chatWallpaper: .builtin(WallpaperSettings()), theme: .builtin(.dayClassic), themeSpecificAccentColors: [:], themeSpecificChatWallpapers: [:], themeTintColors: false, fontSize: .regular, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting(trigger: .none, theme: .nightAccent), largeEmoji: true, disableAnimations: true) return PresentationThemeSettings(chatWallpaper: .builtin(WallpaperSettings()), theme: .builtin(.dayClassic), themeSpecificAccentColors: [:], themeSpecificChatWallpapers: [:], fontSize: .regular, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting(trigger: .none, theme: .nightAccent), largeEmoji: true, disableAnimations: true)
} }
public init(chatWallpaper: TelegramWallpaper, theme: PresentationThemeReference, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], themeTintColors: Bool, fontSize: PresentationFontSize, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting, largeEmoji: Bool, disableAnimations: Bool) { public init(chatWallpaper: TelegramWallpaper, theme: PresentationThemeReference, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], fontSize: PresentationFontSize, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting, largeEmoji: Bool, disableAnimations: Bool) {
self.chatWallpaper = chatWallpaper self.chatWallpaper = chatWallpaper
self.theme = theme self.theme = theme
self.themeSpecificAccentColors = themeSpecificAccentColors self.themeSpecificAccentColors = themeSpecificAccentColors
self.themeSpecificChatWallpapers = themeSpecificChatWallpapers self.themeSpecificChatWallpapers = themeSpecificChatWallpapers
self.themeTintColors = themeTintColors
self.fontSize = fontSize self.fontSize = fontSize
self.automaticThemeSwitchSetting = automaticThemeSwitchSetting self.automaticThemeSwitchSetting = automaticThemeSwitchSetting
self.largeEmoji = largeEmoji self.largeEmoji = largeEmoji
@ -360,8 +358,6 @@ public struct PresentationThemeSettings: PreferencesEntry {
self.themeSpecificAccentColors[PresentationThemeReference.builtin(.day).index] = PresentationThemeAccentColor(baseColor: baseColor, value: 0.5) self.themeSpecificAccentColors[PresentationThemeReference.builtin(.day).index] = PresentationThemeAccentColor(baseColor: baseColor, value: 0.5)
} }
self.themeTintColors = decoder.decodeBoolForKey("themeTintColors", orElse: false)
self.fontSize = PresentationFontSize(rawValue: decoder.decodeInt32ForKey("f", orElse: PresentationFontSize.regular.rawValue)) ?? .regular self.fontSize = PresentationFontSize(rawValue: decoder.decodeInt32ForKey("f", orElse: PresentationFontSize.regular.rawValue)) ?? .regular
self.automaticThemeSwitchSetting = (decoder.decodeObjectForKey("automaticThemeSwitchSetting", decoder: { AutomaticThemeSwitchSetting(decoder: $0) }) as? AutomaticThemeSwitchSetting) ?? AutomaticThemeSwitchSetting(trigger: .none, theme: .nightAccent) self.automaticThemeSwitchSetting = (decoder.decodeObjectForKey("automaticThemeSwitchSetting", decoder: { AutomaticThemeSwitchSetting(decoder: $0) }) as? AutomaticThemeSwitchSetting) ?? AutomaticThemeSwitchSetting(trigger: .none, theme: .nightAccent)
self.largeEmoji = decoder.decodeBoolForKey("largeEmoji", orElse: true) self.largeEmoji = decoder.decodeBoolForKey("largeEmoji", orElse: true)
@ -377,7 +373,6 @@ public struct PresentationThemeSettings: PreferencesEntry {
encoder.encodeObjectDictionary(self.themeSpecificChatWallpapers, forKey: "themeSpecificChatWallpapers", keyEncoder: { key, encoder in encoder.encodeObjectDictionary(self.themeSpecificChatWallpapers, forKey: "themeSpecificChatWallpapers", keyEncoder: { key, encoder in
encoder.encodeInt64(key, forKey: "k") encoder.encodeInt64(key, forKey: "k")
}) })
encoder.encodeBool(self.themeTintColors, forKey: "themeTintColors")
encoder.encodeInt32(self.fontSize.rawValue, forKey: "f") encoder.encodeInt32(self.fontSize.rawValue, forKey: "f")
encoder.encodeObject(self.automaticThemeSwitchSetting, forKey: "automaticThemeSwitchSetting") encoder.encodeObject(self.automaticThemeSwitchSetting, forKey: "automaticThemeSwitchSetting")
encoder.encodeBool(self.largeEmoji, forKey: "largeEmoji") encoder.encodeBool(self.largeEmoji, forKey: "largeEmoji")
@ -393,7 +388,7 @@ public struct PresentationThemeSettings: PreferencesEntry {
} }
public static func ==(lhs: PresentationThemeSettings, rhs: PresentationThemeSettings) -> Bool { public static func ==(lhs: PresentationThemeSettings, rhs: PresentationThemeSettings) -> Bool {
return lhs.chatWallpaper == rhs.chatWallpaper && lhs.theme == rhs.theme && lhs.themeSpecificAccentColors == rhs.themeSpecificAccentColors && lhs.themeSpecificChatWallpapers == rhs.themeSpecificChatWallpapers && lhs.themeTintColors == rhs.themeTintColors && lhs.fontSize == rhs.fontSize && lhs.automaticThemeSwitchSetting == rhs.automaticThemeSwitchSetting && lhs.largeEmoji == rhs.largeEmoji && lhs.disableAnimations == rhs.disableAnimations return lhs.chatWallpaper == rhs.chatWallpaper && lhs.theme == rhs.theme && lhs.themeSpecificAccentColors == rhs.themeSpecificAccentColors && lhs.themeSpecificChatWallpapers == rhs.themeSpecificChatWallpapers && lhs.fontSize == rhs.fontSize && lhs.automaticThemeSwitchSetting == rhs.automaticThemeSwitchSetting && lhs.largeEmoji == rhs.largeEmoji && lhs.disableAnimations == rhs.disableAnimations
} }
} }