mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
1fcaab4e87
28 changed files with 191 additions and 62 deletions
|
|
@ -80,7 +80,7 @@ final class GlobalOverlayPresentationContext {
|
|||
}
|
||||
|
||||
if updateTrackingNode {
|
||||
self.currentTrackingNode?.removeFromSupernode()
|
||||
/*self.currentTrackingNode?.removeFromSupernode()
|
||||
let trackingNode = HierarchyTrackingNode({ [weak self] value in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
|
|
@ -91,7 +91,7 @@ final class GlobalOverlayPresentationContext {
|
|||
})
|
||||
|
||||
self.currentTrackingNode = trackingNode
|
||||
keyboardView.layer.addSublayer(trackingNode.layer)
|
||||
keyboardView.layer.addSublayer(trackingNode.layer)*/
|
||||
}
|
||||
return keyboardWindow
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,26 @@ private func getFirstResponder(_ view: UIView) -> UIView? {
|
|||
}
|
||||
}
|
||||
|
||||
private func isViewVisibleInHierarchy(_ view: UIView, _ initial: Bool = true) -> Bool {
|
||||
guard let window = view.window else {
|
||||
return false
|
||||
}
|
||||
if view.isHidden || view.alpha == 0.0 {
|
||||
return false
|
||||
}
|
||||
if view.superview === window {
|
||||
return true
|
||||
} else if let superview = view.superview {
|
||||
if initial && view.frame.minY >= superview.frame.height {
|
||||
return false
|
||||
} else {
|
||||
return isViewVisibleInHierarchy(superview, false)
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
class KeyboardManager {
|
||||
private let host: StatusBarHost
|
||||
|
||||
|
|
@ -44,6 +64,9 @@ class KeyboardManager {
|
|||
guard let keyboardView = self.host.keyboardView else {
|
||||
return 0.0
|
||||
}
|
||||
if !isViewVisibleInHierarchy(keyboardView) {
|
||||
return 0.0
|
||||
}
|
||||
return keyboardView.bounds.height
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -347,6 +347,13 @@ public func nativeWindowHostView() -> (UIWindow & WindowHost, WindowHostView, UI
|
|||
rootViewController.viewDidAppear(false)
|
||||
|
||||
let aboveStatusbarWindow = AboveStatusBarWindow(frame: UIScreen.main.bounds)
|
||||
aboveStatusbarWindow.supportedOrientations = { [weak rootViewController] in
|
||||
if let rootViewController = rootViewController {
|
||||
return rootViewController.supportedInterfaceOrientations
|
||||
} else {
|
||||
return .portrait
|
||||
}
|
||||
}
|
||||
|
||||
let hostView = WindowHostView(containerView: rootViewController.view, eventView: window, aboveStatusBarView: rootViewController.view, isRotating: {
|
||||
return window.isRotating()
|
||||
|
|
|
|||
|
|
@ -155,22 +155,26 @@ static void setNilField(CustomBlurEffect *object, NSString *name) {
|
|||
}
|
||||
|
||||
UIBlurEffect *makeCustomZoomBlurEffect() {
|
||||
NSString *string = [@[@"_", @"UI", @"Custom", @"BlurEffect"] componentsJoinedByString:@""];
|
||||
CustomBlurEffect *result = (CustomBlurEffect *)[NSClassFromString(string) effectWithStyle:0];
|
||||
|
||||
setField(result, encodeText(@"tfuCmvsSbejvt;", -1), 10.0);
|
||||
setField(result, encodeText(@"tfu[ppn;", -1), 0.015);
|
||||
setNilField(result, encodeText(@"tfuDpmpsUjou;", -1));
|
||||
setField(result, encodeText(@"tfuDpmpsUjouBmqib;", -1), 0.0);
|
||||
setField(result, encodeText(@"tfuEbslfojohUjouBmqib;", -1), 0.0);
|
||||
setField(result, encodeText(@"tfuHsbztdbmfUjouBmqib;", -1), 0.0);
|
||||
setField(result, encodeText(@"tfuTbuvsbujpoEfmubGbdups;", -1), 1.0);
|
||||
|
||||
if ([UIScreen mainScreen].scale > 2.5f) {
|
||||
setField(result, encodeText(@"setScale:", 0), 0.3);
|
||||
if (@available(iOS 11.0, *)) {
|
||||
NSString *string = [@[@"_", @"UI", @"Custom", @"BlurEffect"] componentsJoinedByString:@""];
|
||||
CustomBlurEffect *result = (CustomBlurEffect *)[NSClassFromString(string) effectWithStyle:0];
|
||||
|
||||
setField(result, encodeText(@"tfuCmvsSbejvt;", -1), 10.0);
|
||||
setField(result, encodeText(@"tfu[ppn;", -1), 0.015);
|
||||
setNilField(result, encodeText(@"tfuDpmpsUjou;", -1));
|
||||
setField(result, encodeText(@"tfuDpmpsUjouBmqib;", -1), 0.0);
|
||||
setField(result, encodeText(@"tfuEbslfojohUjouBmqib;", -1), 0.0);
|
||||
setField(result, encodeText(@"tfuHsbztdbmfUjouBmqib;", -1), 0.0);
|
||||
setField(result, encodeText(@"tfuTbuvsbujpoEfmubGbdups;", -1), 1.0);
|
||||
|
||||
if ([UIScreen mainScreen].scale > 2.5f) {
|
||||
setField(result, encodeText(@"setScale:", 0), 0.3);
|
||||
} else {
|
||||
setField(result, encodeText(@"setScale:", 0), 0.5);
|
||||
}
|
||||
|
||||
return result;
|
||||
} else {
|
||||
setField(result, encodeText(@"setScale:", 0), 0.5);
|
||||
return [UIBlurEffect effectWithStyle:UIBlurEffectStyleRegular];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,4 +36,6 @@ void applyKeyboardAutocorrection();
|
|||
|
||||
@interface AboveStatusBarWindow : UIWindow
|
||||
|
||||
@property (nonatomic, copy) UIInterfaceOrientationMask (^ _Nullable supportedOrientations)(void);
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -311,6 +311,8 @@ void applyKeyboardAutocorrection() {
|
|||
|
||||
@interface AboveStatusBarWindowController : UIViewController
|
||||
|
||||
@property (nonatomic, copy) UIInterfaceOrientationMask (^ _Nullable supportedOrientations)(void);
|
||||
|
||||
@end
|
||||
|
||||
@implementation AboveStatusBarWindowController
|
||||
|
|
@ -330,6 +332,10 @@ void applyKeyboardAutocorrection() {
|
|||
[self viewDidLoad];
|
||||
}
|
||||
|
||||
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
|
||||
return UIInterfaceOrientationMaskPortrait;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation AboveStatusBarWindow
|
||||
|
|
@ -348,6 +354,11 @@ void applyKeyboardAutocorrection() {
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void)setSupportedOrientations:(UIInterfaceOrientationMask (^)(void))supportedOrientations {
|
||||
_supportedOrientations = [supportedOrientations copy];
|
||||
((AboveStatusBarWindowController *)self.rootViewController).supportedOrientations = _supportedOrientations;
|
||||
}
|
||||
|
||||
- (BOOL)shouldAffectStatusBarAppearance {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,6 @@ import AccountContext
|
|||
|
||||
public protocol GalleryItemTransitionNode: class {
|
||||
func isAvailableForGalleryTransition() -> Bool
|
||||
func isAvailableForInstantPageTransition() -> Bool
|
||||
var decoration: UniversalVideoDecoration? { get }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if let result = result {
|
||||
if let result = result, strongSelf.scrubbingFrames {
|
||||
switch result {
|
||||
case .waitingForData:
|
||||
strongSelf.footerContentNode.setFramePreviewImageIsLoading()
|
||||
|
|
@ -922,7 +922,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||
videoNode.continuePlayingWithoutSound()
|
||||
}
|
||||
}
|
||||
} else if let _ = node.0 as? GalleryItemTransitionNode, videoNode.hasAttachedContext {
|
||||
} else if let instantNode = node.0 as? GalleryItemTransitionNode, instantNode.isAvailableForInstantPageTransition(), videoNode.hasAttachedContext {
|
||||
copyView.removeFromSuperview()
|
||||
|
||||
let previousFrame = videoNode.frame
|
||||
|
|
|
|||
|
|
@ -86,6 +86,10 @@ final class InstantPagePlayableVideoNode: ASDisplayNode, InstantPageNode, Galler
|
|||
return true
|
||||
}
|
||||
|
||||
func isAvailableForInstantPageTransition() -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||
case optimizeDatabase(PresentationTheme)
|
||||
case photoPreview(PresentationTheme, Bool)
|
||||
case knockoutWallpaper(PresentationTheme, Bool)
|
||||
case gradientBubbles(PresentationTheme, Bool)
|
||||
case versionInfo(PresentationTheme)
|
||||
|
||||
var section: ItemListSectionId {
|
||||
|
|
@ -81,7 +82,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||
return DebugControllerSection.logging.rawValue
|
||||
case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory, .crashOnSlowQueries:
|
||||
return DebugControllerSection.experiments.rawValue
|
||||
case .clearTips, .reimport, .resetData, .resetDatabase, .resetHoles, .resetBiometricsData, .optimizeDatabase, .photoPreview, .knockoutWallpaper:
|
||||
case .clearTips, .reimport, .resetData, .resetDatabase, .resetHoles, .resetBiometricsData, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .gradientBubbles:
|
||||
return DebugControllerSection.experiments.rawValue
|
||||
case .versionInfo:
|
||||
return DebugControllerSection.info.rawValue
|
||||
|
|
@ -132,8 +133,10 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||
return 19
|
||||
case .knockoutWallpaper:
|
||||
return 20
|
||||
case .versionInfo:
|
||||
case .gradientBubbles:
|
||||
return 21
|
||||
case .versionInfo:
|
||||
return 22
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -501,6 +504,16 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||
})
|
||||
}).start()
|
||||
})
|
||||
case let .gradientBubbles(theme, value):
|
||||
return ItemListSwitchItem(theme: theme, title: "Gradient", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
|
||||
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in
|
||||
var settings = settings as? ExperimentalUISettings ?? ExperimentalUISettings.defaultSettings
|
||||
settings.gradientBubbles = value
|
||||
return settings
|
||||
})
|
||||
}).start()
|
||||
})
|
||||
case let .versionInfo(theme):
|
||||
let bundle = Bundle.main
|
||||
let bundleId = bundle.bundleIdentifier ?? ""
|
||||
|
|
@ -540,6 +553,7 @@ private func debugControllerEntries(presentationData: PresentationData, loggingS
|
|||
entries.append(.optimizeDatabase(presentationData.theme))
|
||||
entries.append(.photoPreview(presentationData.theme, experimentalSettings.chatListPhotos))
|
||||
entries.append(.knockoutWallpaper(presentationData.theme, experimentalSettings.knockoutWallpaper))
|
||||
entries.append(.gradientBubbles(presentationData.theme, experimentalSettings.gradientBubbles))
|
||||
|
||||
entries.append(.versionInfo(presentationData.theme))
|
||||
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
|||
let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: currentTheme, accentColor: color, serviceBackgroundColor: defaultServiceBackgroundColor, baseColor: nil, preview: true)
|
||||
|
||||
let wallpaper = context.sharedContext.currentPresentationData.with { $0 }.chatWallpaper
|
||||
let _ = PresentationResourcesChat.principalGraphics(mediaBox: context.account.postbox.mediaBox, knockoutWallpaper: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: theme, wallpaper: wallpaper)
|
||||
let _ = PresentationResourcesChat.principalGraphics(mediaBox: context.account.postbox.mediaBox, knockoutWallpaper: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: theme, wallpaper: wallpaper, gradientBubbles: context.sharedContext.immediateExperimentalUISettings.gradientBubbles)
|
||||
|
||||
return theme
|
||||
}
|
||||
|
|
|
|||
|
|
@ -408,6 +408,11 @@ public final class PresentationCallImpl: PresentationCall {
|
|||
if let error = error {
|
||||
if error.domain == "com.apple.CallKit.error.incomingcall" && (error.code == -3 || error.code == 3) {
|
||||
Logger.shared.log("PresentationCall", "reportIncomingCall device in DND mode")
|
||||
Queue.mainQueue().async {
|
||||
if let strongSelf = self {
|
||||
strongSelf.callSessionManager.drop(internalId: strongSelf.internalId, reason: .busy)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Logger.shared.log("PresentationCall", "reportIncomingCall error \(error)")
|
||||
Queue.mainQueue().async {
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ public final class BlockedPeersContext {
|
|||
}
|
||||
|
||||
deinit {
|
||||
assert(Queue.mainQueue().isCurrent())
|
||||
self.disposable.dispose()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -699,12 +699,7 @@ private final class MediaReferenceRevalidationContextImpl {
|
|||
}
|
||||
}
|
||||
}
|
||||
}, { [weak self] _ in
|
||||
/*queue.async {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
}*/
|
||||
}, { _ in
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -413,7 +413,9 @@ func fetchRemoteMessage(postbox: Postbox, source: FetchMessageHistoryHoleSource,
|
|||
return .single(nil)
|
||||
}
|
||||
let signal: Signal<Api.messages.Messages, MTRpcError>
|
||||
if id.peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
if id.namespace == Namespaces.Message.ScheduledCloud {
|
||||
signal = source.request(Api.functions.messages.getScheduledMessages(peer: peer.inputPeer, id: [id.id]))
|
||||
} else if id.peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
if let channel = peer.inputChannel {
|
||||
signal = source.request(Api.functions.channels.getMessages(channel: channel, id: [Api.InputMessage.inputMessageID(id: id.id)]))
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,13 @@ public func setSecretChatMessageAutoremoveTimeoutInteractively(account: Account,
|
|||
|
||||
public func addSecretChatMessageScreenshot(account: Account, peerId: PeerId) -> Signal<Void, NoError> {
|
||||
return account.postbox.transaction { transaction -> Void in
|
||||
if let peer = transaction.getPeer(peerId) as? TelegramSecretChat, let state = transaction.getPeerChatState(peerId) as? SecretChatState {
|
||||
if let _ = transaction.getPeer(peerId) as? TelegramSecretChat, let state = transaction.getPeerChatState(peerId) as? SecretChatState {
|
||||
switch state.embeddedState {
|
||||
case .handshake, .terminated:
|
||||
return
|
||||
default:
|
||||
break
|
||||
}
|
||||
let _ = enqueueMessages(transaction: transaction, account: account, peerId: peerId, messages: [(true, .message(text: "", attributes: [], mediaReference: .standalone(media: TelegramMediaAction(action: TelegramMediaActionType.historyScreenshot)), replyToMessageId: nil, localGroupingKey: nil))])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ public func telegramThemes(postbox: Postbox, network: Network, forceUpdate: Bool
|
|||
public enum GetThemeError {
|
||||
case generic
|
||||
case unsupported
|
||||
case slugInvalid
|
||||
}
|
||||
|
||||
public func getTheme(account: Account, slug: String) -> Signal<TelegramTheme, GetThemeError> {
|
||||
|
|
@ -100,6 +101,9 @@ public func getTheme(account: Account, slug: String) -> Signal<TelegramTheme, Ge
|
|||
if error.errorDescription == "THEME_FORMAT_INVALID" {
|
||||
return .unsupported
|
||||
}
|
||||
if error.errorDescription == "THEME_SLUG_INVALID" {
|
||||
return .slugInvalid
|
||||
}
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { theme -> Signal<TelegramTheme, GetThemeError> in
|
||||
|
|
@ -260,7 +264,7 @@ private func uploadTheme(account: Account, resource: MediaResource, thumbnailDat
|
|||
|
||||
public enum CreateThemeError {
|
||||
case generic
|
||||
case slugOccupied
|
||||
case slugInvalid
|
||||
}
|
||||
|
||||
public enum CreateThemeResult {
|
||||
|
|
@ -276,7 +280,12 @@ public func createTheme(account: Account, title: String, resource: MediaResource
|
|||
case let .complete(file):
|
||||
if let resource = file.resource as? CloudDocumentMediaResource {
|
||||
return account.network.request(Api.functions.account.createTheme(slug: "", title: title, document: .inputDocument(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference))))
|
||||
|> mapError { _ in return CreateThemeError.generic }
|
||||
|> mapError { error in
|
||||
if error.errorDescription == "THEME_SLUG_INVALID" {
|
||||
return .slugInvalid
|
||||
}
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { apiTheme -> Signal<CreateThemeResult, CreateThemeError> in
|
||||
if let theme = TelegramTheme(apiTheme: apiTheme) {
|
||||
return account.postbox.transaction { transaction -> CreateThemeResult in
|
||||
|
|
@ -315,9 +324,12 @@ public func updateTheme(account: Account, theme: TelegramTheme, title: String?,
|
|||
if let _ = title {
|
||||
flags |= 1 << 1
|
||||
}
|
||||
if let _ = slug {
|
||||
if let slug = slug, !slug.isEmpty {
|
||||
flags |= 1 << 0
|
||||
}
|
||||
if let _ = resource {
|
||||
flags |= 1 << 2
|
||||
}
|
||||
let uploadSignal: Signal<UploadThemeResult?, UploadThemeError>
|
||||
if let resource = resource {
|
||||
flags |= 1 << 2
|
||||
|
|
@ -348,9 +360,9 @@ public func updateTheme(account: Account, theme: TelegramTheme, title: String?,
|
|||
}
|
||||
|
||||
return account.network.request(Api.functions.account.updateTheme(flags: flags, theme: .inputTheme(id: theme.id, accessHash: theme.accessHash), slug: slug, title: title, document: inputDocument))
|
||||
|> mapError { error -> CreateThemeError in
|
||||
if error.errorDescription.hasPrefix("THEME_SLUG_OCCUPIED") {
|
||||
return .slugOccupied
|
||||
|> mapError { error in
|
||||
if error.errorDescription == "THEME_SLUG_INVALID" {
|
||||
return .slugInvalid
|
||||
}
|
||||
return .generic
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,6 +231,8 @@
|
|||
D033FEB41E61F3C000644997 /* ReportPeer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D033FEB21E61F3C000644997 /* ReportPeer.swift */; };
|
||||
D033FEB61E61F3F900644997 /* BlockedPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D033FEB51E61F3F900644997 /* BlockedPeers.swift */; };
|
||||
D033FEB71E61F3F900644997 /* BlockedPeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D033FEB51E61F3F900644997 /* BlockedPeers.swift */; };
|
||||
D03413F1231323CE00B555F3 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09B4A9B5230FBB2B005C2E08 /* Theme.swift */; };
|
||||
D03413F3231325B300B555F3 /* Themes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09B4A9B3230FB70B005C2E08 /* Themes.swift */; };
|
||||
D035732F22B5C24F00F0920D /* TelegramApi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D035732E22B5C24F00F0920D /* TelegramApi.framework */; };
|
||||
D0380DBA204EF306000414AB /* MessageMediaPreuploadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0380DB9204EF306000414AB /* MessageMediaPreuploadManager.swift */; };
|
||||
D0380DBB204EF306000414AB /* MessageMediaPreuploadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0380DB9204EF306000414AB /* MessageMediaPreuploadManager.swift */; };
|
||||
|
|
@ -2530,6 +2532,8 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D03413F3231325B300B555F3 /* Themes.swift in Sources */,
|
||||
D03413F1231323CE00B555F3 /* Theme.swift in Sources */,
|
||||
D04D21382306ECF600609388 /* FormatPhoneNumber.m in Sources */,
|
||||
D021E7E82306EC03002F8BD1 /* OutgoingScheduleInfoMessageAttribute.swift in Sources */,
|
||||
D021E7E92306EC03002F8BD1 /* ScheduledMessages.swift in Sources */,
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ public final class PrincipalThemeEssentialGraphics {
|
|||
public let incomingBubbleGradientImage: UIImage?
|
||||
public let outgoingBubbleGradientImage: UIImage?
|
||||
|
||||
init(mediaBox: MediaBox, presentationTheme: PresentationTheme, wallpaper initialWallpaper: TelegramWallpaper, preview: Bool = false, knockoutMode: Bool) {
|
||||
init(mediaBox: MediaBox, presentationTheme: PresentationTheme, wallpaper initialWallpaper: TelegramWallpaper, preview: Bool = false, knockoutMode: Bool, gradientBubbles: Bool) {
|
||||
let theme = presentationTheme.chat
|
||||
var wallpaper = initialWallpaper
|
||||
|
||||
|
|
@ -173,7 +173,7 @@ public final class PrincipalThemeEssentialGraphics {
|
|||
}
|
||||
|
||||
var outgoingGradientColors: (UIColor, UIColor)?
|
||||
if false, let baseColor = presentationTheme.baseColor {
|
||||
if gradientBubbles, let baseColor = presentationTheme.baseColor {
|
||||
if presentationTheme.baseColor == .custom {
|
||||
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -67,11 +67,11 @@ public struct PresentationResourcesChat {
|
|||
})
|
||||
}
|
||||
|
||||
public static func principalGraphics(mediaBox: MediaBox, knockoutWallpaper: Bool, theme: PresentationTheme, wallpaper: TelegramWallpaper) -> PrincipalThemeEssentialGraphics {
|
||||
public static func principalGraphics(mediaBox: MediaBox, knockoutWallpaper: Bool, theme: PresentationTheme, wallpaper: TelegramWallpaper, gradientBubbles: Bool) -> PrincipalThemeEssentialGraphics {
|
||||
let hasWallpaper = !wallpaper.isEmpty
|
||||
let key: PresentationResourceKey = !hasWallpaper ? PresentationResourceKey.chatPrincipalThemeEssentialGraphicsWithoutWallpaper : PresentationResourceKey.chatPrincipalThemeEssentialGraphicsWithWallpaper
|
||||
return theme.object(key.rawValue, { theme in
|
||||
return PrincipalThemeEssentialGraphics(mediaBox: mediaBox, presentationTheme: theme, wallpaper: wallpaper, preview: theme.preview, knockoutMode: knockoutWallpaper)
|
||||
return PrincipalThemeEssentialGraphics(mediaBox: mediaBox, presentationTheme: theme, wallpaper: wallpaper, preview: theme.preview, knockoutMode: knockoutWallpaper, gradientBubbles: gradientBubbles)
|
||||
}) as! PrincipalThemeEssentialGraphics
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6552,7 +6552,24 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
self.chatDisplayNode.dismissInput()
|
||||
|
||||
if let peer = peer as? TelegramChannel, let username = peer.username, !username.isEmpty {
|
||||
self.present(peerReportOptionsController(context: self.context, subject: .peer(peer.id), present: { [weak self] c, a in
|
||||
let actionSheet = ActionSheetController(presentationTheme: self.presentationData.theme)
|
||||
|
||||
var items: [ActionSheetItem] = []
|
||||
items.append(ActionSheetButtonItem(title: self.presentationData.strings.Conversation_ReportSpamAndLeave, color: .destructive, action: { [weak self, weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
if let strongSelf = self {
|
||||
strongSelf.deleteChat(reportChatSpam: true)
|
||||
}
|
||||
}))
|
||||
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
||||
ActionSheetButtonItem(title: self.presentationData.strings.Common_Cancel, color: .accent, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
})
|
||||
])])
|
||||
|
||||
self.present(actionSheet, in: .window(.root))
|
||||
|
||||
/*self.present(peerReportOptionsController(context: self.context, subject: .peer(peer.id), present: { [weak self] c, a in
|
||||
self?.present(c, in: .window(.root))
|
||||
}, completion: { [weak self] success in
|
||||
guard let strongSelf = self, success else {
|
||||
|
|
@ -6560,7 +6577,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
}
|
||||
let _ = removePeerChat(account: strongSelf.context.account, peerId: chatPeer.id, reportChatSpam: false).start()
|
||||
(strongSelf.navigationController as? NavigationController)?.filterController(strongSelf, animated: true)
|
||||
}), in: .window(.root))
|
||||
}), in: .window(.root))*/
|
||||
} else if let _ = peer as? TelegramUser {
|
||||
let presentationData = self.presentationData
|
||||
let controller = ActionSheetController(presentationTheme: presentationData.theme)
|
||||
|
|
|
|||
|
|
@ -568,9 +568,11 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||
var immediatelyLayoutInputNodeAndAnimateAppearance = false
|
||||
var inputNodeHeightAndOverflow: (CGFloat, CGFloat)?
|
||||
if let inputNode = inputNodeForChatPresentationIntefaceState(self.chatPresentationInterfaceState, context: self.context, currentNode: self.inputNode, interfaceInteraction: self.interfaceInteraction, inputMediaNode: self.inputMediaNode, controllerInteraction: self.controllerInteraction, inputPanelNode: self.inputPanelNode) {
|
||||
if let _ = self.inputPanelNode as? ChatTextInputPanelNode {
|
||||
self.context.sharedContext.mainWindow?.simulateKeyboardDismiss(transition: .animated(duration: 0.5, curve: .spring))
|
||||
//inputTextPanelNode.ensureUnfocused()
|
||||
if let inputPanelNode = self.inputPanelNode as? ChatTextInputPanelNode {
|
||||
if inputPanelNode.isFocused {
|
||||
self.context.sharedContext.mainWindow?.simulateKeyboardDismiss(transition: .animated(duration: 0.5, curve: .spring))
|
||||
//inputTextPanelNode.ensureUnfocused()
|
||||
}
|
||||
}
|
||||
if let inputMediaNode = inputNode as? ChatMediaInputNode, self.inputMediaNode == nil {
|
||||
self.inputMediaNode = inputMediaNode
|
||||
|
|
@ -646,8 +648,10 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||
if let inputPanelNode = inputPanelForChatPresentationIntefaceState(self.chatPresentationInterfaceState, context: self.context, currentPanel: self.inputPanelNode, textInputPanelNode: self.textInputPanelNode, interfaceInteraction: self.interfaceInteraction), !previewing {
|
||||
if inputPanelNode !== self.inputPanelNode {
|
||||
if let inputTextPanelNode = self.inputPanelNode as? ChatTextInputPanelNode {
|
||||
self.context.sharedContext.mainWindow?.simulateKeyboardDismiss(transition: .animated(duration: 0.5, curve: .spring))
|
||||
//inputTextPanelNode.ensureUnfocused()
|
||||
if inputTextPanelNode.isFocused {
|
||||
self.context.sharedContext.mainWindow?.simulateKeyboardDismiss(transition: .animated(duration: 0.5, curve: .spring))
|
||||
//inputTextPanelNode.ensureUnfocused()
|
||||
}
|
||||
let _ = inputTextPanelNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, maxHeight: layout.size.height - insets.top - insets.bottom, transition: transition, interfaceState: self.chatPresentationInterfaceState, metrics: layout.metrics)
|
||||
}
|
||||
dismissedInputPanelNode = self.inputPanelNode
|
||||
|
|
@ -1037,6 +1041,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||
apparentNavigateButtonsFrame.origin.y += verticalOffset
|
||||
}
|
||||
|
||||
let previousInputPanelBackgroundFrame = self.inputPanelBackgroundNode.frame
|
||||
transition.updateFrame(node: self.inputPanelBackgroundNode, frame: apparentInputBackgroundFrame)
|
||||
transition.updateFrame(node: self.inputPanelBackgroundSeparatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: apparentInputBackgroundFrame.origin.y - UIScreenPixel), size: CGSize(width: apparentInputBackgroundFrame.size.width, height: UIScreenPixel)))
|
||||
transition.updateFrame(node: self.navigateButtons, frame: apparentNavigateButtonsFrame)
|
||||
|
|
@ -1050,7 +1055,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||
|
||||
if let inputPanelNode = self.inputPanelNode, let apparentInputPanelFrame = apparentInputPanelFrame, !inputPanelNode.frame.equalTo(apparentInputPanelFrame) {
|
||||
if immediatelyLayoutInputPanelAndAnimateAppearance {
|
||||
inputPanelNode.frame = apparentInputPanelFrame.offsetBy(dx: 0.0, dy: apparentInputPanelFrame.height)
|
||||
inputPanelNode.frame = apparentInputPanelFrame.offsetBy(dx: 0.0, dy: apparentInputPanelFrame.height + previousInputPanelBackgroundFrame.maxY - apparentInputBackgroundFrame.maxY)
|
||||
inputPanelNode.alpha = 0.0
|
||||
}
|
||||
|
||||
|
|
@ -1427,9 +1432,11 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||
if self.chatPresentationInterfaceStateRequiresInputFocus(chatPresentationInterfaceState) {
|
||||
self.ensureInputViewFocused()
|
||||
} else {
|
||||
if let _ = self.inputPanelNode as? ChatTextInputPanelNode {
|
||||
self.context.sharedContext.mainWindow?.simulateKeyboardDismiss(transition: .animated(duration: 0.5, curve: .spring))
|
||||
//inputTextPanelNode.ensureUnfocused()
|
||||
if let inputPanelNode = self.inputPanelNode as? ChatTextInputPanelNode {
|
||||
if inputPanelNode.isFocused {
|
||||
self.context.sharedContext.mainWindow?.simulateKeyboardDismiss(transition: .animated(duration: 0.5, curve: .spring))
|
||||
//inputTextPanelNode.ensureUnfocused()
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -276,7 +276,15 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode
|
|||
|
||||
if let subnodes = self.subnodes {
|
||||
for node in subnodes {
|
||||
if node !== self.accessoryItemNode {
|
||||
if let contextNode = node as? ContextContentContainingNode {
|
||||
if let contextSubnodes = contextNode.contentNode.subnodes {
|
||||
for contextSubnode in contextSubnodes {
|
||||
if contextSubnode !== self.accessoryItemNode {
|
||||
contextSubnode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if node !== self.accessoryItemNode {
|
||||
node.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
|
|
@ -1493,7 +1501,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode
|
|||
|
||||
let layout = ListViewItemNodeLayout(contentSize: layoutSize, insets: layoutInsets)
|
||||
|
||||
let graphics = PresentationResourcesChat.principalGraphics(mediaBox: item.context.account.postbox.mediaBox, knockoutWallpaper: item.context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper)
|
||||
let graphics = PresentationResourcesChat.principalGraphics(mediaBox: item.context.account.postbox.mediaBox, knockoutWallpaper: item.context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper, gradientBubbles: item.context.sharedContext.immediateExperimentalUISettings.gradientBubbles)
|
||||
|
||||
var updatedMergedTop = mergedBottom
|
||||
var updatedMergedBottom = mergedTop
|
||||
|
|
@ -2686,7 +2694,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode
|
|||
if self.highlightedState != highlighted {
|
||||
self.highlightedState = highlighted
|
||||
if let backgroundType = self.backgroundType {
|
||||
let graphics = PresentationResourcesChat.principalGraphics(mediaBox: item.context.account.postbox.mediaBox, knockoutWallpaper: item.context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper)
|
||||
let graphics = PresentationResourcesChat.principalGraphics(mediaBox: item.context.account.postbox.mediaBox, knockoutWallpaper: item.context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper, gradientBubbles: item.context.sharedContext.immediateExperimentalUISettings.gradientBubbles)
|
||||
|
||||
if highlighted {
|
||||
self.backgroundNode.setType(type: backgroundType, highlighted: true, graphics: graphics, maskMode: self.contextSourceNode.isExtractedToContextPreview, transition: .immediate)
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
|
|||
|
||||
let themeUpdated = presentationData.theme != currentTheme || type != currentType
|
||||
|
||||
let graphics = PresentationResourcesChat.principalGraphics(mediaBox: context.account.postbox.mediaBox, knockoutWallpaper: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper)
|
||||
let graphics = PresentationResourcesChat.principalGraphics(mediaBox: context.account.postbox.mediaBox, knockoutWallpaper: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, gradientBubbles: context.sharedContext.immediateExperimentalUISettings.gradientBubbles)
|
||||
let offset: CGFloat = -UIScreenPixel
|
||||
|
||||
switch type {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ final class ChatMessageDateHeaderNode: ListViewItemHeaderNode {
|
|||
|
||||
self.transform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0)
|
||||
|
||||
let graphics = PresentationResourcesChat.principalGraphics(mediaBox: context.account.postbox.mediaBox, knockoutWallpaper: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper)
|
||||
let graphics = PresentationResourcesChat.principalGraphics(mediaBox: context.account.postbox.mediaBox, knockoutWallpaper: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, gradientBubbles: context.sharedContext.immediateExperimentalUISettings.gradientBubbles)
|
||||
|
||||
self.backgroundNode.image = graphics.dateStaticBackground
|
||||
self.stickBackgroundNode.image = graphics.dateFloatingBackground
|
||||
|
|
@ -173,7 +173,7 @@ final class ChatMessageDateHeaderNode: ListViewItemHeaderNode {
|
|||
}
|
||||
|
||||
func updatePresentationData(_ presentationData: ChatPresentationData, context: AccountContext) {
|
||||
let graphics = PresentationResourcesChat.principalGraphics(mediaBox: context.account.postbox.mediaBox, knockoutWallpaper: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper)
|
||||
let graphics = PresentationResourcesChat.principalGraphics(mediaBox: context.account.postbox.mediaBox, knockoutWallpaper: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, gradientBubbles: context.sharedContext.immediateExperimentalUISettings.gradientBubbles)
|
||||
|
||||
self.backgroundNode.image = graphics.dateStaticBackground
|
||||
self.stickBackgroundNode.image = graphics.dateFloatingBackground
|
||||
|
|
|
|||
|
|
@ -434,7 +434,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
|||
if hasThumbnail {
|
||||
fileIconImage = nil
|
||||
} else {
|
||||
let principalGraphics = PresentationResourcesChat.principalGraphics(mediaBox: context.account.postbox.mediaBox, knockoutWallpaper: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper)
|
||||
let principalGraphics = PresentationResourcesChat.principalGraphics(mediaBox: context.account.postbox.mediaBox, knockoutWallpaper: context.sharedContext.immediateExperimentalUISettings.knockoutWallpaper, theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, gradientBubbles: context.sharedContext.immediateExperimentalUISettings.gradientBubbles)
|
||||
|
||||
fileIconImage = incoming ? principalGraphics.radialIndicatorFileIconIncoming : principalGraphics.radialIndicatorFileIconOutgoing
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,6 +153,10 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||
return self.automaticPlayback ?? false
|
||||
}
|
||||
|
||||
func isAvailableForInstantPageTransition() -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
|
|
|
|||
|
|
@ -8,17 +8,19 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry {
|
|||
public var crashOnLongQueries: Bool
|
||||
public var chatListPhotos: Bool
|
||||
public var knockoutWallpaper: Bool
|
||||
public var gradientBubbles: Bool
|
||||
|
||||
public static var defaultSettings: ExperimentalUISettings {
|
||||
return ExperimentalUISettings(keepChatNavigationStack: false, skipReadHistory: false, crashOnLongQueries: false, chatListPhotos: false, knockoutWallpaper: false)
|
||||
return ExperimentalUISettings(keepChatNavigationStack: false, skipReadHistory: false, crashOnLongQueries: false, chatListPhotos: false, knockoutWallpaper: false, gradientBubbles: false)
|
||||
}
|
||||
|
||||
public init(keepChatNavigationStack: Bool, skipReadHistory: Bool, crashOnLongQueries: Bool, chatListPhotos: Bool, knockoutWallpaper: Bool) {
|
||||
public init(keepChatNavigationStack: Bool, skipReadHistory: Bool, crashOnLongQueries: Bool, chatListPhotos: Bool, knockoutWallpaper: Bool, gradientBubbles: Bool) {
|
||||
self.keepChatNavigationStack = keepChatNavigationStack
|
||||
self.skipReadHistory = skipReadHistory
|
||||
self.crashOnLongQueries = crashOnLongQueries
|
||||
self.chatListPhotos = chatListPhotos
|
||||
self.knockoutWallpaper = knockoutWallpaper
|
||||
self.gradientBubbles = gradientBubbles
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
|
|
@ -27,6 +29,7 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry {
|
|||
self.crashOnLongQueries = decoder.decodeInt32ForKey("crashOnLongQueries", orElse: 0) != 0
|
||||
self.chatListPhotos = decoder.decodeInt32ForKey("chatListPhotos", orElse: 0) != 0
|
||||
self.knockoutWallpaper = decoder.decodeInt32ForKey("knockoutWallpaper", orElse: 0) != 0
|
||||
self.gradientBubbles = decoder.decodeInt32ForKey("gradientBubbles", orElse: 0) != 0
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
|
|
@ -35,6 +38,7 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry {
|
|||
encoder.encodeInt32(self.crashOnLongQueries ? 1 : 0, forKey: "crashOnLongQueries")
|
||||
encoder.encodeInt32(self.chatListPhotos ? 1 : 0, forKey: "chatListPhotos")
|
||||
encoder.encodeInt32(self.knockoutWallpaper ? 1 : 0, forKey: "knockoutWallpaper")
|
||||
encoder.encodeInt32(self.gradientBubbles ? 1 : 0, forKey: "gradientBubbles")
|
||||
}
|
||||
|
||||
public func isEqual(to: PreferencesEntry) -> Bool {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue