mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-28 19:05:49 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
685c3f95a2
@ -1 +1 @@
|
||||
44eed22b384449bcec8962f2fddbfebd
|
||||
3a64b94cc76109006731756f85403c85
|
||||
|
||||
@ -680,7 +680,7 @@ private final class NotificationServiceHandler {
|
||||
Logger.shared.logToConsole = loggingSettings.logToConsole
|
||||
Logger.shared.redactSensitiveData = loggingSettings.redactSensitiveData
|
||||
|
||||
let networkArguments = NetworkInitializationArguments(apiId: apiId, apiHash: apiHash, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0, voipVersions: [], appData: .single(buildConfig.bundleData(withAppToken: nil, signatureDict: nil)), autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider(), resolvedDeviceName: nil)
|
||||
let networkArguments = NetworkInitializationArguments(apiId: apiId, apiHash: apiHash, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0, voipVersions: [], appData: .single(buildConfig.bundleData(withAppToken: nil, signatureDict: nil)), autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider(), deviceModelName: nil)
|
||||
|
||||
let isLockedMessage: String?
|
||||
if let data = try? Data(contentsOf: URL(fileURLWithPath: appLockStatePath(rootPath: rootPath))), let state = try? JSONDecoder().decode(LockState.self, from: data), isAppLocked(state: state) {
|
||||
|
||||
@ -174,7 +174,7 @@ class DefaultIntentHandler: INExtension, INSendMessageIntentHandling, INSearchFo
|
||||
if let accountCache = accountCache {
|
||||
account = .single(accountCache)
|
||||
} else {
|
||||
account = currentAccount(allocateIfNotExists: false, networkArguments: NetworkInitializationArguments(apiId: apiId, apiHash: apiHash, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0, voipVersions: [], appData: .single(buildConfig.bundleData(withAppToken: nil, signatureDict: nil)), autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider(), resolvedDeviceName: nil), supplementary: true, manager: accountManager, rootPath: rootPath, auxiliaryMethods: accountAuxiliaryMethods, encryptionParameters: encryptionParameters)
|
||||
account = currentAccount(allocateIfNotExists: false, networkArguments: NetworkInitializationArguments(apiId: apiId, apiHash: apiHash, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0, voipVersions: [], appData: .single(buildConfig.bundleData(withAppToken: nil, signatureDict: nil)), autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider(), deviceModelName: nil), supplementary: true, manager: accountManager, rootPath: rootPath, auxiliaryMethods: accountAuxiliaryMethods, encryptionParameters: encryptionParameters)
|
||||
|> mapToSignal { account -> Signal<Account?, NoError> in
|
||||
if let account = account {
|
||||
switch account {
|
||||
|
||||
@ -1643,6 +1643,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
let batteryPercentage = Int(batteryLevel * 100.0)
|
||||
|
||||
self.dismissAllUndoControllers()
|
||||
//TODO:localize
|
||||
self.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "lowbattery_30", scale: 1.0, colors: [:], title: "Power Saving mode enabled", text: "\(batteryPercentage)% battery remaining.", customUndoText: "Disable"), elevatedLayout: false, action: { [weak self] action in
|
||||
if case .undo = action, let self {
|
||||
let _ = updateMediaDownloadSettingsInteractively(accountManager: self.context.sharedContext.accountManager, { settings in
|
||||
|
||||
@ -595,7 +595,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
|
||||
let titleSize = self.titleLabelNode.updateLayout(CGSize(width: maxTextWidth, height: 100.0))
|
||||
|
||||
//TODO:localize
|
||||
var text = "read"
|
||||
var text = ""
|
||||
if let timestamp = item.timestamp {
|
||||
let dateText = humanReadableStringForTimestamp(strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, timestamp: timestamp, alwaysShowTime: false, allowYesterday: true, format: HumanReadableStringFormat(
|
||||
dateFormatString: { value in
|
||||
@ -619,12 +619,12 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
|
||||
}
|
||||
self.textLabelNode.attributedText = NSAttributedString(string: text, font: Font.regular(15.0), textColor: presentationData.theme.contextMenu.secondaryColor)
|
||||
let textSize = self.textLabelNode.updateLayout(CGSize(width: maxTextWidth - 18.0, height: 100.0))
|
||||
self.textLabelNode.isHidden = !self.displayReadTimestamps
|
||||
self.textLabelNode.isHidden = !self.displayReadTimestamps && !text.isEmpty
|
||||
|
||||
let textSpacing: CGFloat = 2.0
|
||||
let contentHeight: CGFloat
|
||||
|
||||
if self.displayReadTimestamps {
|
||||
if self.displayReadTimestamps && !text.isEmpty {
|
||||
contentHeight = titleSize.height + textSpacing + textSize.height
|
||||
} else {
|
||||
contentHeight = titleSize.height
|
||||
@ -642,7 +642,7 @@ public final class ReactionListContextMenuContent: ContextControllerItemsContent
|
||||
let iconSize = CGSize(width: floor(readImage.size.width * fraction), height: floor(readImage.size.height * fraction))
|
||||
self.readIconView.frame = CGRect(origin: CGPoint(x: titleFrame.minX, y: textFrame.minY + 4.0 - UIScreenPixel), size: iconSize)
|
||||
}
|
||||
self.readIconView.isHidden = !self.displayReadTimestamps
|
||||
self.readIconView.isHidden = !self.displayReadTimestamps && !text.isEmpty
|
||||
|
||||
if let credibilityIconView = self.credibilityIconView, let credibilityIconSize = credibilityIconSize {
|
||||
if let credibilityIconComponentView = credibilityIconView.view {
|
||||
|
||||
@ -905,6 +905,35 @@ public extension ContainedViewLayoutTransition {
|
||||
}
|
||||
}
|
||||
|
||||
func updateTintColor(layer: CALayer, color: UIColor, completion: ((Bool) -> Void)? = nil) {
|
||||
if let current = layer.layerTintColor, current == color.cgColor {
|
||||
completion?(true)
|
||||
return
|
||||
}
|
||||
|
||||
switch self {
|
||||
case .immediate:
|
||||
layer.layerTintColor = color.cgColor
|
||||
completion?(true)
|
||||
case let .animated(duration, curve):
|
||||
let previousColor: CGColor = layer.layerTintColor ?? UIColor.clear.cgColor
|
||||
layer.layerTintColor = color.cgColor
|
||||
|
||||
layer.animate(
|
||||
from: previousColor,
|
||||
to: color.cgColor,
|
||||
keyPath: "contentsMultiplyColor",
|
||||
timingFunction: curve.timingFunction,
|
||||
duration: duration,
|
||||
delay: 0.0,
|
||||
mediaTimingFunction: curve.mediaTimingFunction,
|
||||
removeOnCompletion: true,
|
||||
additive: false,
|
||||
completion: completion
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func updateContentsRect(layer: CALayer, contentsRect: CGRect, completion: ((Bool) -> Void)? = nil) {
|
||||
if layer.contentsRect == contentsRect {
|
||||
if let completion = completion {
|
||||
|
||||
@ -14,7 +14,7 @@ public enum DeviceMetrics: CaseIterable, Equatable {
|
||||
var cpuCount: UInt32 = 0
|
||||
sysctlbyname("hw.ncpu", &cpuCount, &length, nil, 0)
|
||||
|
||||
self.isGraphicallyCapable = cpuCount >= 6
|
||||
self.isGraphicallyCapable = cpuCount >= 4
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -40,6 +40,7 @@
|
||||
@property (nonatomic, assign) CGFloat dotSize;
|
||||
|
||||
@property (nonatomic, assign) bool enablePanHandling;
|
||||
@property (nonatomic, assign) bool enableEdgeTap;
|
||||
|
||||
- (void)setValue:(CGFloat)value animated:(BOOL)animated;
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ const CGFloat TGPhotoEditorSliderViewInternalMargin = 7.0f;
|
||||
|
||||
UIPanGestureRecognizer *_panGestureRecognizer;
|
||||
UITapGestureRecognizer *_tapGestureRecognizer;
|
||||
UITapGestureRecognizer *_edgeTapGestureRecognizer;
|
||||
UITapGestureRecognizer *_doubleTapGestureRecognizer;
|
||||
|
||||
UIColor *_backColor;
|
||||
@ -75,6 +76,10 @@ const CGFloat TGPhotoEditorSliderViewInternalMargin = 7.0f;
|
||||
_tapGestureRecognizer.enabled = false;
|
||||
[self addGestureRecognizer:_tapGestureRecognizer];
|
||||
|
||||
_edgeTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleEdgeTap:)];
|
||||
_edgeTapGestureRecognizer.enabled = false;
|
||||
[self addGestureRecognizer:_edgeTapGestureRecognizer];
|
||||
|
||||
_doubleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
|
||||
_doubleTapGestureRecognizer.numberOfTapsRequired = 2;
|
||||
[self addGestureRecognizer:_doubleTapGestureRecognizer];
|
||||
@ -195,7 +200,7 @@ const CGFloat TGPhotoEditorSliderViewInternalMargin = 7.0f;
|
||||
}
|
||||
|
||||
if (self.displayEdges) {
|
||||
CGContextSetFillColorWithColor(context, _startColor.CGColor);
|
||||
CGContextSetFillColorWithColor(context, _backColor.CGColor);
|
||||
[self drawRectangle:endFrame cornerRadius:self.trackCornerRadius context:context];
|
||||
}
|
||||
|
||||
@ -510,6 +515,46 @@ const CGFloat TGPhotoEditorSliderViewInternalMargin = 7.0f;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setEnableEdgeTap:(bool)enableEdgeTap {
|
||||
_enableEdgeTap = enableEdgeTap;
|
||||
_edgeTapGestureRecognizer.enabled = enableEdgeTap;
|
||||
}
|
||||
|
||||
- (void)handleEdgeTap:(UITapGestureRecognizer *)gestureRecognizer {
|
||||
bool changed = false;
|
||||
|
||||
if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
|
||||
CGPoint touchLocation = [gestureRecognizer locationInView:self];
|
||||
CGFloat edgeWidth = 16.0f;
|
||||
if (touchLocation.x < edgeWidth || touchLocation.x > self.bounds.size.width - edgeWidth) {
|
||||
CGRect knobRect = CGRectInset(self.knobView.frame, -8.0, -8.0);
|
||||
if (!CGRectContainsPoint(knobRect, touchLocation)) {
|
||||
if (touchLocation.x < edgeWidth) {
|
||||
[self setValue:_minimumValue];
|
||||
} else {
|
||||
[self setValue:_maximumValue];
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (self.interactionBegan != nil)
|
||||
self.interactionBegan();
|
||||
|
||||
[self setNeedsLayout];
|
||||
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
||||
|
||||
if (self.interactionEnded != nil)
|
||||
self.interactionEnded();
|
||||
|
||||
[_feedbackGenerator selectionChanged];
|
||||
[_feedbackGenerator prepare];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleDoubleTap:(UITapGestureRecognizer *)__unused gestureRecognizer
|
||||
{
|
||||
if (self.reset != nil)
|
||||
|
||||
@ -235,7 +235,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
self.scrollingArea = SparseItemGridScrollingArea()
|
||||
|
||||
self.cameraActivateAreaNode = AccessibilityAreaNode()
|
||||
self.cameraActivateAreaNode.accessibilityLabel = self.presentationData.strings.MediaPicker_VoiceOver_Camera
|
||||
self.cameraActivateAreaNode.accessibilityLabel = "Camera"
|
||||
self.cameraActivateAreaNode.accessibilityTraits = [.button]
|
||||
|
||||
super.init()
|
||||
|
||||
@ -55,7 +55,7 @@
|
||||
|
||||
@property (nonatomic) int32_t apiId;
|
||||
@property (nonatomic, strong, readonly) NSString * _Nullable deviceModel;
|
||||
@property (nonatomic, strong, readonly) NSDictionary<NSString *, NSString *> * _Nullable resolvedDeviceName;
|
||||
@property (nonatomic, strong, readonly) NSString * _Nullable deviceModelName;
|
||||
|
||||
@property (nonatomic, strong, readonly) NSString * _Nullable systemVersion;
|
||||
@property (nonatomic, strong) NSString * _Nullable appVersion;
|
||||
@ -83,6 +83,6 @@
|
||||
- (MTApiEnvironment * _Nonnull)withUpdatedNetworkSettings:(MTNetworkSettings * _Nullable)networkSettings;
|
||||
- (MTApiEnvironment * _Nonnull)withUpdatedSystemCode:(NSData * _Nullable)systemCode;
|
||||
|
||||
-(id _Nonnull)initWithResolvedDeviceName:(NSDictionary<NSString *, NSString *> * _Nullable)resolvedDeviceName;
|
||||
-(id _Nonnull)initWithDeviceModelName:(NSString * _Nullable)deviceModelName;
|
||||
|
||||
@end
|
||||
|
||||
@ -428,7 +428,7 @@ static NSData *base64_decode(NSString *str) {
|
||||
@implementation MTApiEnvironment
|
||||
|
||||
-(instancetype)init {
|
||||
self = [self initWithResolvedDeviceName:nil];
|
||||
self = [self initWithDeviceModelName:nil];
|
||||
if (self != nil)
|
||||
{
|
||||
|
||||
@ -436,22 +436,16 @@ static NSData *base64_decode(NSString *str) {
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id _Nonnull)initWithResolvedDeviceName:(NSDictionary<NSString *, NSString *> * _Nullable)resolvedDeviceName {
|
||||
-(id _Nonnull)initWithDeviceModelName:(NSString * _Nullable)deviceModelName {
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
if (resolvedDeviceName != nil) {
|
||||
NSString *model = [self platformString];
|
||||
NSString* resolved = resolvedDeviceName[model];
|
||||
if (resolved != nil) {
|
||||
_deviceModel = resolved;
|
||||
} else {
|
||||
_deviceModel = model;
|
||||
}
|
||||
if (deviceModelName != nil) {
|
||||
_deviceModel = deviceModelName;
|
||||
} else {
|
||||
_deviceModel = [self platformString];
|
||||
}
|
||||
_resolvedDeviceName = resolvedDeviceName;
|
||||
_deviceModelName = deviceModelName;
|
||||
#if TARGET_OS_IPHONE
|
||||
_systemVersion = [[UIDevice currentDevice] systemVersion];
|
||||
#else
|
||||
@ -803,7 +797,7 @@ NSString *suffix = @"";
|
||||
}
|
||||
|
||||
- (MTApiEnvironment *)withUpdatedLangPackCode:(NSString *)langPackCode {
|
||||
MTApiEnvironment *result = [[MTApiEnvironment alloc] initWithResolvedDeviceName:_resolvedDeviceName];
|
||||
MTApiEnvironment *result = [[MTApiEnvironment alloc] initWithDeviceModelName:_deviceModelName];
|
||||
|
||||
result.apiId = self.apiId;
|
||||
result.appVersion = self.appVersion;
|
||||
@ -827,7 +821,7 @@ NSString *suffix = @"";
|
||||
}
|
||||
|
||||
- (instancetype)copyWithZone:(NSZone *)__unused zone {
|
||||
MTApiEnvironment *result = [[MTApiEnvironment alloc] initWithResolvedDeviceName:_resolvedDeviceName];
|
||||
MTApiEnvironment *result = [[MTApiEnvironment alloc] initWithDeviceModelName:_deviceModelName];
|
||||
|
||||
result.apiId = self.apiId;
|
||||
result.appVersion = self.appVersion;
|
||||
@ -851,7 +845,7 @@ NSString *suffix = @"";
|
||||
}
|
||||
|
||||
- (MTApiEnvironment *)withUpdatedSocksProxySettings:(MTSocksProxySettings *)socksProxySettings {
|
||||
MTApiEnvironment *result = [[MTApiEnvironment alloc] initWithResolvedDeviceName:_resolvedDeviceName];
|
||||
MTApiEnvironment *result = [[MTApiEnvironment alloc] initWithDeviceModelName:_deviceModelName];
|
||||
|
||||
result.apiId = self.apiId;
|
||||
result.appVersion = self.appVersion;
|
||||
@ -875,7 +869,7 @@ NSString *suffix = @"";
|
||||
}
|
||||
|
||||
- (MTApiEnvironment *)withUpdatedNetworkSettings:(MTNetworkSettings *)networkSettings {
|
||||
MTApiEnvironment *result = [[MTApiEnvironment alloc] initWithResolvedDeviceName:_resolvedDeviceName];
|
||||
MTApiEnvironment *result = [[MTApiEnvironment alloc] initWithDeviceModelName:_deviceModelName];
|
||||
|
||||
result.apiId = self.apiId;
|
||||
result.appVersion = self.appVersion;
|
||||
@ -899,7 +893,7 @@ NSString *suffix = @"";
|
||||
}
|
||||
|
||||
- (MTApiEnvironment *)withUpdatedSystemCode:(NSData *)systemCode {
|
||||
MTApiEnvironment *result = [[MTApiEnvironment alloc] initWithResolvedDeviceName:_resolvedDeviceName];
|
||||
MTApiEnvironment *result = [[MTApiEnvironment alloc] initWithDeviceModelName:_deviceModelName];
|
||||
|
||||
result.apiId = self.apiId;
|
||||
result.appVersion = self.appVersion;
|
||||
|
||||
@ -17,8 +17,8 @@ enum ItemType: CaseIterable {
|
||||
case loopStickers
|
||||
case loopEmoji
|
||||
case fullTranslucency
|
||||
case extendBackgroundWork
|
||||
case autodownloadInBackground
|
||||
case extendBackgroundWork
|
||||
|
||||
var settingsKeyPath: WritableKeyPath<EnergyUsageSettings, Bool> {
|
||||
switch self {
|
||||
@ -63,7 +63,7 @@ enum ItemType: CaseIterable {
|
||||
case .loopEmoji:
|
||||
return (
|
||||
"Settings/Power/PowerIconEmoji",
|
||||
"Emoli Animations",
|
||||
"Emoji Animations",
|
||||
"Loop animated emoji in messages, reactions, statuses."
|
||||
)
|
||||
case .fullTranslucency:
|
||||
@ -242,7 +242,7 @@ private func energeSavingSettingsScreenEntries(
|
||||
|
||||
entries.append(.itemsHeader)
|
||||
for type in ItemType.allCases {
|
||||
entries.append(.item(index: entries.count, type: type, value: settings.energyUsageSettings[keyPath: type.settingsKeyPath], enabled: itemsEnabled))
|
||||
entries.append(.item(index: entries.count, type: type, value: settings.energyUsageSettings[keyPath: type.settingsKeyPath] && itemsEnabled, enabled: itemsEnabled))
|
||||
}
|
||||
|
||||
return entries
|
||||
|
||||
@ -73,6 +73,7 @@ class EnergyUsageBatteryLevelItemNode: ListViewItemNode {
|
||||
|
||||
private let batteryImage: UIImage?
|
||||
private let batteryBackgroundNode: ASImageNode
|
||||
private let batteryForegroundNode: ASImageNode
|
||||
|
||||
private var item: EnergyUsageBatteryLevelItem?
|
||||
private var layoutParams: ListViewItemLayoutParams?
|
||||
@ -96,6 +97,7 @@ class EnergyUsageBatteryLevelItemNode: ListViewItemNode {
|
||||
|
||||
self.batteryImage = UIImage(bundleImageName: "Settings/UsageBatteryFrame")
|
||||
self.batteryBackgroundNode = ASImageNode()
|
||||
self.batteryForegroundNode = ASImageNode()
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
|
||||
@ -103,12 +105,14 @@ class EnergyUsageBatteryLevelItemNode: ListViewItemNode {
|
||||
self.addSubnode(self.rightTextNode)
|
||||
self.addSubnode(self.centerTextNode)
|
||||
self.addSubnode(self.batteryBackgroundNode)
|
||||
self.addSubnode(self.batteryForegroundNode)
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
let sliderView = TGPhotoEditorSliderView()
|
||||
sliderView.enableEdgeTap = true
|
||||
sliderView.enablePanHandling = true
|
||||
sliderView.trackCornerRadius = 1.0
|
||||
sliderView.lineSize = 4.0
|
||||
@ -223,6 +227,7 @@ class EnergyUsageBatteryLevelItemNode: ListViewItemNode {
|
||||
centralMeasureText = "When Below 99%"
|
||||
strongSelf.batteryBackgroundNode.isHidden = false
|
||||
}
|
||||
strongSelf.batteryForegroundNode.isHidden = strongSelf.batteryBackgroundNode.isHidden
|
||||
strongSelf.centerTextNode.attributedText = NSAttributedString(string: centralText, font: Font.regular(16.0), textColor: item.theme.list.itemPrimaryTextColor)
|
||||
strongSelf.centerMeasureTextNode.attributedText = NSAttributedString(string: centralMeasureText, font: Font.regular(16.0), textColor: item.theme.list.itemPrimaryTextColor)
|
||||
|
||||
@ -254,15 +259,41 @@ class EnergyUsageBatteryLevelItemNode: ListViewItemNode {
|
||||
let contentRect = CGRect(origin: CGPoint(x: 3.0, y: (size.height - 9.0) * 0.5), size: CGSize(width: 20.8, height: 9.0))
|
||||
context.addPath(UIBezierPath(roundedRect: contentRect, cornerRadius: 2.0).cgPath)
|
||||
context.clip()
|
||||
|
||||
context.setFillColor(UIColor(rgb: 0xFF3B30).cgColor)
|
||||
context.addPath(UIBezierPath(roundedRect: CGRect(origin: contentRect.origin, size: CGSize(width: contentRect.width * CGFloat(item.value) / 100.0, height: contentRect.height)), cornerRadius: 1.0).cgPath)
|
||||
context.fillPath()
|
||||
}
|
||||
|
||||
UIGraphicsPopContext()
|
||||
})
|
||||
strongSelf.batteryForegroundNode.image = generateImage(frameImage.size, rotatedContext: { size, context in
|
||||
UIGraphicsPushContext(context)
|
||||
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
let contentRect = CGRect(origin: CGPoint(x: 3.0, y: (size.height - 9.0) * 0.5), size: CGSize(width: 20.8, height: 9.0))
|
||||
context.addPath(UIBezierPath(roundedRect: contentRect, cornerRadius: 2.0).cgPath)
|
||||
context.clip()
|
||||
|
||||
context.setFillColor(UIColor.white.cgColor)
|
||||
context.addPath(UIBezierPath(roundedRect: CGRect(origin: contentRect.origin, size: CGSize(width: contentRect.width * CGFloat(item.value) / 100.0, height: contentRect.height)), cornerRadius: 1.0).cgPath)
|
||||
context.fillPath()
|
||||
|
||||
UIGraphicsPopContext()
|
||||
})
|
||||
|
||||
let batteryColor: UIColor
|
||||
if item.value <= 20 {
|
||||
batteryColor = UIColor(rgb: 0xFF3B30)
|
||||
} else {
|
||||
batteryColor = item.theme.list.itemSwitchColors.positiveColor
|
||||
}
|
||||
|
||||
if strongSelf.batteryForegroundNode.layer.layerTintColor == nil {
|
||||
strongSelf.batteryForegroundNode.layer.layerTintColor = batteryColor.cgColor
|
||||
} else {
|
||||
ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut).updateTintColor(layer: strongSelf.batteryForegroundNode.layer, color: batteryColor)
|
||||
}
|
||||
|
||||
strongSelf.batteryBackgroundNode.frame = CGRect(origin: CGPoint(x: centerFrame.minX + centerMeasureTextSize.width + 4.0, y: floor(centerFrame.midY - frameImage.size.height * 0.5)), size: frameImage.size)
|
||||
strongSelf.batteryForegroundNode.frame = strongSelf.batteryBackgroundNode.frame
|
||||
}
|
||||
|
||||
if let sliderView = strongSelf.sliderView {
|
||||
|
||||
@ -143,9 +143,9 @@ private final class KeepMediaDurationPickerItemNode: ListViewItemNode {
|
||||
|
||||
sliderView.value = CGFloat(value)
|
||||
sliderView.backgroundColor = item.theme.list.itemBlocksBackgroundColor
|
||||
sliderView.backColor = item.theme.list.itemSwitchColors.frameColor
|
||||
sliderView.startColor = item.theme.list.itemSwitchColors.frameColor
|
||||
sliderView.trackColor = item.theme.list.itemAccentColor
|
||||
sliderView.backColor = item.theme.list.itemSwitchColors.frameColor.blitOver(item.theme.list.itemBlocksBackgroundColor, alpha: 1.0)
|
||||
sliderView.startColor = item.theme.list.itemSwitchColors.frameColor.blitOver(item.theme.list.itemBlocksBackgroundColor, alpha: 1.0)
|
||||
sliderView.trackColor = item.theme.list.itemAccentColor.blitOver(item.theme.list.itemBlocksBackgroundColor, alpha: 1.0)
|
||||
sliderView.knobImage = PresentationResourcesItemList.knobImage(item.theme)
|
||||
|
||||
sliderView.frame = CGRect(origin: CGPoint(x: params.leftInset + 15.0, y: 37.0), size: CGSize(width: params.width - params.leftInset - params.rightInset - 15.0 * 2.0, height: 44.0))
|
||||
|
||||
@ -57,6 +57,7 @@ private final class ThemeSettingsControllerArguments {
|
||||
let openTextSize: () -> Void
|
||||
let openBubbleSettings: () -> Void
|
||||
let openPowerSavingSettings: () -> Void
|
||||
let openStickersAndEmoji: () -> Void
|
||||
let toggleLargeEmoji: (Bool) -> Void
|
||||
let disableAnimations: (Bool) -> Void
|
||||
let selectAppIcon: (PresentationAppIcon) -> Void
|
||||
@ -64,7 +65,7 @@ private final class ThemeSettingsControllerArguments {
|
||||
let themeContextAction: (Bool, PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void
|
||||
let colorContextAction: (Bool, PresentationThemeReference, ThemeSettingsColorOption?, ASDisplayNode, ContextGesture?) -> Void
|
||||
|
||||
init(context: AccountContext, selectTheme: @escaping (PresentationThemeReference) -> Void, openThemeSettings: @escaping () -> Void, openWallpaperSettings: @escaping () -> Void, selectAccentColor: @escaping (PresentationThemeAccentColor?) -> Void, openAccentColorPicker: @escaping (PresentationThemeReference, Bool) -> Void, toggleNightTheme: @escaping (Bool) -> Void, openAutoNightTheme: @escaping () -> Void, openTextSize: @escaping () -> Void, openBubbleSettings: @escaping () -> Void, openPowerSavingSettings: @escaping () -> Void, toggleLargeEmoji: @escaping (Bool) -> Void, disableAnimations: @escaping (Bool) -> Void, selectAppIcon: @escaping (PresentationAppIcon) -> Void, editTheme: @escaping (PresentationCloudTheme) -> Void, themeContextAction: @escaping (Bool, PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void, colorContextAction: @escaping (Bool, PresentationThemeReference, ThemeSettingsColorOption?, ASDisplayNode, ContextGesture?) -> Void) {
|
||||
init(context: AccountContext, selectTheme: @escaping (PresentationThemeReference) -> Void, openThemeSettings: @escaping () -> Void, openWallpaperSettings: @escaping () -> Void, selectAccentColor: @escaping (PresentationThemeAccentColor?) -> Void, openAccentColorPicker: @escaping (PresentationThemeReference, Bool) -> Void, toggleNightTheme: @escaping (Bool) -> Void, openAutoNightTheme: @escaping () -> Void, openTextSize: @escaping () -> Void, openBubbleSettings: @escaping () -> Void, openPowerSavingSettings: @escaping () -> Void, openStickersAndEmoji: @escaping () -> Void, toggleLargeEmoji: @escaping (Bool) -> Void, disableAnimations: @escaping (Bool) -> Void, selectAppIcon: @escaping (PresentationAppIcon) -> Void, editTheme: @escaping (PresentationCloudTheme) -> Void, themeContextAction: @escaping (Bool, PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void, colorContextAction: @escaping (Bool, PresentationThemeReference, ThemeSettingsColorOption?, ASDisplayNode, ContextGesture?) -> Void) {
|
||||
self.context = context
|
||||
self.selectTheme = selectTheme
|
||||
self.openThemeSettings = openThemeSettings
|
||||
@ -76,6 +77,7 @@ private final class ThemeSettingsControllerArguments {
|
||||
self.openTextSize = openTextSize
|
||||
self.openBubbleSettings = openBubbleSettings
|
||||
self.openPowerSavingSettings = openPowerSavingSettings
|
||||
self.openStickersAndEmoji = openStickersAndEmoji
|
||||
self.toggleLargeEmoji = toggleLargeEmoji
|
||||
self.disableAnimations = disableAnimations
|
||||
self.selectAppIcon = selectAppIcon
|
||||
@ -101,6 +103,7 @@ public enum ThemeSettingsEntryTag: ItemListItemTag {
|
||||
case accentColor
|
||||
case icon
|
||||
case powerSaving
|
||||
case stickersAndEmoji
|
||||
case largeEmoji
|
||||
case animations
|
||||
|
||||
@ -126,6 +129,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
case iconHeader(PresentationTheme, String)
|
||||
case iconItem(PresentationTheme, PresentationStrings, [PresentationAppIcon], Bool, String?)
|
||||
case powerSaving
|
||||
case stickersAndEmoji
|
||||
case otherHeader(PresentationTheme, String)
|
||||
case largeEmoji(PresentationTheme, String, Bool)
|
||||
case animations(PresentationTheme, String, Bool)
|
||||
@ -141,7 +145,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
return ThemeSettingsControllerSection.message.rawValue
|
||||
case .iconHeader, .iconItem:
|
||||
return ThemeSettingsControllerSection.icon.rawValue
|
||||
case .powerSaving:
|
||||
case .powerSaving, .stickersAndEmoji:
|
||||
return ThemeSettingsControllerSection.message.rawValue
|
||||
case .otherHeader, .largeEmoji, .animations, .animationsInfo:
|
||||
return ThemeSettingsControllerSection.other.rawValue
|
||||
@ -170,18 +174,20 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
return 8
|
||||
case .powerSaving:
|
||||
return 9
|
||||
case .iconHeader:
|
||||
case .stickersAndEmoji:
|
||||
return 10
|
||||
case .iconItem:
|
||||
case .iconHeader:
|
||||
return 11
|
||||
case .otherHeader:
|
||||
case .iconItem:
|
||||
return 12
|
||||
case .largeEmoji:
|
||||
case .otherHeader:
|
||||
return 13
|
||||
case .animations:
|
||||
case .largeEmoji:
|
||||
return 14
|
||||
case .animationsInfo:
|
||||
case .animations:
|
||||
return 15
|
||||
case .animationsInfo:
|
||||
return 16
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,6 +265,12 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case .stickersAndEmoji:
|
||||
if case .stickersAndEmoji = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .otherHeader(lhsTheme, lhsText):
|
||||
if case let .otherHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
||||
return true
|
||||
@ -338,6 +350,11 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, icon: nil, title: "Animations", label: "", labelStyle: .text, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
arguments.openPowerSavingSettings()
|
||||
})
|
||||
case .stickersAndEmoji:
|
||||
//TODO:localize
|
||||
return ItemListDisclosureItem(presentationData: presentationData, icon: nil, title: "Stickers and Emoji", label: "", labelStyle: .text, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
arguments.openStickersAndEmoji()
|
||||
})
|
||||
case let .otherHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .largeEmoji(_, title, value):
|
||||
@ -397,6 +414,7 @@ private func themeSettingsControllerEntries(presentationData: PresentationData,
|
||||
entries.append(.textSize(presentationData.theme, strings.Appearance_TextSizeSetting, textSizeValue))
|
||||
entries.append(.bubbleSettings(presentationData.theme, strings.Appearance_BubbleCornersSetting, ""))
|
||||
entries.append(.powerSaving)
|
||||
entries.append(.stickersAndEmoji)
|
||||
|
||||
if !availableAppIcons.isEmpty {
|
||||
entries.append(.iconHeader(presentationData.theme, strings.Appearance_AppIcon.uppercased()))
|
||||
@ -460,6 +478,9 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
let removedThemeIndexesPromise = Promise<Set<Int64>>(Set())
|
||||
let removedThemeIndexes = Atomic<Set<Int64>>(value: Set())
|
||||
|
||||
let archivedPacks = Promise<[ArchivedStickerPackItem]?>()
|
||||
archivedPacks.set(.single(nil) |> then(context.engine.stickers.archivedStickerPacks() |> map(Optional.init)))
|
||||
|
||||
let animatedEmojiStickers = context.engine.stickers.loadedStickerPack(reference: .animatedEmoji, forceActualized: false)
|
||||
|> map { animatedEmoji -> [String: [StickerPackItem]] in
|
||||
var animatedEmojiStickers: [String: [StickerPackItem]] = [:]
|
||||
@ -515,6 +536,11 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
})
|
||||
}, openPowerSavingSettings: {
|
||||
pushControllerImpl?(energySavingSettingsScreen(context: context))
|
||||
}, openStickersAndEmoji: {
|
||||
let _ = (archivedPacks.get() |> take(1) |> deliverOnMainQueue).start(next: { archivedStickerPacks in
|
||||
pushControllerImpl?(installedStickerPacksController(context: context, mode: .general, archivedPacks: archivedStickerPacks, updatedPacks: { _ in
|
||||
}))
|
||||
})
|
||||
}, toggleLargeEmoji: { largeEmoji in
|
||||
let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
return current.withUpdatedLargeEmoji(largeEmoji)
|
||||
|
||||
@ -68,6 +68,7 @@
|
||||
@[@"492960", @"492960", @13, @(STPCardBrandVisa)],
|
||||
@[@"8600", @"8600", @16, @(STPCardBrandOther)],
|
||||
@[@"9860", @"9860", @16, @(STPCardBrandOther)],
|
||||
@[@"2", @"2", @16, @(STPCardBrandUnknown)],
|
||||
];
|
||||
NSMutableArray *binRanges = [NSMutableArray array];
|
||||
for (NSArray *range in ranges) {
|
||||
|
||||
@ -153,13 +153,14 @@ static NSString * _Nonnull stringByRemovingCharactersFromSet(NSString * _Nonnull
|
||||
return STPCardValidationStateIncomplete;
|
||||
}
|
||||
|
||||
BOOL isValidLuhn = [self stringIsValidLuhn:sanitizedNumber];
|
||||
return isValidLuhn ? STPCardValidationStateValid : STPCardValidationStateInvalid;
|
||||
//BOOL isValidLuhn = [self stringIsValidLuhn:sanitizedNumber];
|
||||
//return isValidLuhn ? STPCardValidationStateValid : STPCardValidationStateInvalid;
|
||||
|
||||
/*STPBINRange *binRange = [STPBINRange mostSpecificBINRangeForNumber:sanitizedNumber];
|
||||
STPBINRange *binRange = [STPBINRange mostSpecificBINRangeForNumber:sanitizedNumber];
|
||||
if (binRange.brand == STPCardBrandUnknown && validatingCardBrand) {
|
||||
return STPCardValidationStateInvalid;
|
||||
//return STPCardValidationStateInvalid;
|
||||
}
|
||||
|
||||
if (sanitizedNumber.length == binRange.length) {
|
||||
BOOL isValidLuhn = [self stringIsValidLuhn:sanitizedNumber];
|
||||
return isValidLuhn ? STPCardValidationStateValid : STPCardValidationStateInvalid;
|
||||
@ -167,7 +168,7 @@ static NSString * _Nonnull stringByRemovingCharactersFromSet(NSString * _Nonnull
|
||||
return STPCardValidationStateInvalid;
|
||||
} else {
|
||||
return STPCardValidationStateIncomplete;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
+ (STPCardValidationState)validationStateForCard:(nonnull STPCardParams *)card inCurrentYear:(NSInteger)currentYear currentMonth:(NSInteger)currentMonth {
|
||||
|
||||
@ -432,8 +432,8 @@ public struct NetworkInitializationArguments {
|
||||
public let appData: Signal<Data?, NoError>
|
||||
public let autolockDeadine: Signal<Int32?, NoError>
|
||||
public let encryptionProvider: EncryptionProvider
|
||||
public let resolvedDeviceName:[String: String]?
|
||||
public init(apiId: Int32, apiHash: String, languagesCategory: String, appVersion: String, voipMaxLayer: Int32, voipVersions: [CallSessionManagerImplementationVersion], appData: Signal<Data?, NoError>, autolockDeadine: Signal<Int32?, NoError>, encryptionProvider: EncryptionProvider, resolvedDeviceName:[String: String]?) {
|
||||
public let deviceModelName:String?
|
||||
public init(apiId: Int32, apiHash: String, languagesCategory: String, appVersion: String, voipMaxLayer: Int32, voipVersions: [CallSessionManagerImplementationVersion], appData: Signal<Data?, NoError>, autolockDeadine: Signal<Int32?, NoError>, encryptionProvider: EncryptionProvider, deviceModelName:String?) {
|
||||
self.apiId = apiId
|
||||
self.apiHash = apiHash
|
||||
self.languagesCategory = languagesCategory
|
||||
@ -443,7 +443,7 @@ public struct NetworkInitializationArguments {
|
||||
self.appData = appData
|
||||
self.autolockDeadine = autolockDeadine
|
||||
self.encryptionProvider = encryptionProvider
|
||||
self.resolvedDeviceName = resolvedDeviceName
|
||||
self.deviceModelName = deviceModelName
|
||||
}
|
||||
}
|
||||
#if os(iOS)
|
||||
@ -458,7 +458,7 @@ func initializedNetwork(accountId: AccountRecordId, arguments: NetworkInitializa
|
||||
|
||||
let serialization = Serialization()
|
||||
|
||||
var apiEnvironment = MTApiEnvironment(resolvedDeviceName: arguments.resolvedDeviceName)
|
||||
var apiEnvironment = MTApiEnvironment(deviceModelName: arguments.deviceModelName)
|
||||
|
||||
apiEnvironment.apiId = arguments.apiId
|
||||
apiEnvironment.langPack = arguments.languagesCategory
|
||||
|
||||
@ -370,7 +370,7 @@ func applyUpdateGroupMessages(postbox: Postbox, stateManager: AccountStateManage
|
||||
mapping.append((message, MessageIndex(id: id, timestamp: storeMessage.timestamp), storeMessage))
|
||||
}
|
||||
} else {
|
||||
assertionFailure()
|
||||
// assertionFailure()
|
||||
}
|
||||
} else {
|
||||
assertionFailure()
|
||||
|
||||
@ -141,7 +141,7 @@ public extension Peer {
|
||||
var isDeleted: Bool {
|
||||
switch self {
|
||||
case let user as TelegramUser:
|
||||
return user.firstName == nil && user.lastName == nil && user.phone == nil
|
||||
return user.firstName == nil && user.lastName == nil
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ public func selectReactionFillStaticColor(theme: PresentationTheme, wallpaper: T
|
||||
|
||||
public func dateFillNeedsBlur(theme: PresentationTheme, wallpaper: TelegramWallpaper) -> Bool {
|
||||
if !DeviceMetrics.performance.isGraphicallyCapable {
|
||||
//return false
|
||||
return false
|
||||
}
|
||||
|
||||
if case .builtin = wallpaper {
|
||||
|
||||
@ -381,7 +381,7 @@ private final class SendInviteLinkScreenComponent: Component {
|
||||
maximumNumberOfLines: 0
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 1000.0)
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0 - 16.0 * 2.0, height: 1000.0)
|
||||
)
|
||||
let descriptionTextFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - descriptionTextSize.width) * 0.5), y: contentHeight), size: descriptionTextSize)
|
||||
if let descriptionTextView = self.descriptionText.view {
|
||||
|
||||
@ -483,7 +483,7 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
||||
Logger.shared.log("data", "can't deserialize")
|
||||
}
|
||||
return data
|
||||
}, autolockDeadine: autolockDeadine, encryptionProvider: OpenSSLEncryptionProvider(), resolvedDeviceName: nil)
|
||||
}, autolockDeadine: autolockDeadine, encryptionProvider: OpenSSLEncryptionProvider(), deviceModelName: nil)
|
||||
|
||||
guard let appGroupUrl = maybeAppGroupUrl else {
|
||||
self.mainWindow?.presentNative(UIAlertController(title: nil, message: "Error 2", preferredStyle: .alert))
|
||||
|
||||
@ -138,7 +138,7 @@ public final class NotificationViewControllerImpl {
|
||||
return nil
|
||||
})
|
||||
|
||||
sharedAccountContext = SharedAccountContextImpl(mainWindow: nil, sharedContainerPath: self.initializationData.appGroupPath, basePath: rootPath, encryptionParameters: ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: self.initializationData.encryptionParameters.0)!, salt: ValueBoxEncryptionParameters.Salt(data: self.initializationData.encryptionParameters.1)!), accountManager: accountManager, appLockContext: appLockContext, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: self.initializationData.apiId, apiHash: self.initializationData.apiHash, languagesCategory: self.initializationData.languagesCategory, appVersion: self.initializationData.appVersion, voipMaxLayer: 0, voipVersions: [], appData: .single(self.initializationData.bundleData), autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider(), resolvedDeviceName: nil), hasInAppPurchases: false, rootPath: rootPath, legacyBasePath: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), firebaseSecretStream: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in }, appDelegate: nil)
|
||||
sharedAccountContext = SharedAccountContextImpl(mainWindow: nil, sharedContainerPath: self.initializationData.appGroupPath, basePath: rootPath, encryptionParameters: ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: self.initializationData.encryptionParameters.0)!, salt: ValueBoxEncryptionParameters.Salt(data: self.initializationData.encryptionParameters.1)!), accountManager: accountManager, appLockContext: appLockContext, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: self.initializationData.apiId, apiHash: self.initializationData.apiHash, languagesCategory: self.initializationData.languagesCategory, appVersion: self.initializationData.appVersion, voipMaxLayer: 0, voipVersions: [], appData: .single(self.initializationData.bundleData), autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider(), deviceModelName: nil), hasInAppPurchases: false, rootPath: rootPath, legacyBasePath: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), firebaseSecretStream: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in }, appDelegate: nil)
|
||||
|
||||
presentationDataPromise.set(sharedAccountContext!.presentationData)
|
||||
}
|
||||
|
||||
@ -841,7 +841,7 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p
|
||||
interaction.openPaymentMethod()
|
||||
}))*/
|
||||
|
||||
let stickersLabel: String
|
||||
/*let stickersLabel: String
|
||||
if let settings = data.globalSettings {
|
||||
stickersLabel = settings.unreadTrendingStickerPacks > 0 ? "\(settings.unreadTrendingStickerPacks)" : ""
|
||||
} else {
|
||||
@ -849,7 +849,7 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p
|
||||
}
|
||||
items[.advanced]!.append(PeerInfoScreenDisclosureItem(id: 5, label: .badge(stickersLabel, presentationData.theme.list.itemAccentColor), text: presentationData.strings.ChatSettings_StickersAndReactions, icon: PresentationResourcesSettings.stickers, action: {
|
||||
interaction.openSettings(.stickers)
|
||||
}))
|
||||
}))*/
|
||||
|
||||
if let settings = data.globalSettings {
|
||||
if settings.hasPassport {
|
||||
@ -10543,67 +10543,99 @@ func presentAddMembersImpl(context: AccountContext, updatedPresentationData: (in
|
||||
return .complete()
|
||||
}
|
||||
} else {
|
||||
return context.engine.peers.addGroupMember(peerId: groupPeer.id, memberId: memberId)
|
||||
|> deliverOnMainQueue
|
||||
|> `catch` { error -> Signal<Void, NoError> in
|
||||
switch error {
|
||||
case .generic:
|
||||
return .complete()
|
||||
case .privacy:
|
||||
let _ = (context.account.postbox.loadedPeerWithId(memberId)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(peer).compactDisplayTitle, EnginePeer(peer).compactDisplayTitle).string, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
})
|
||||
return .complete()
|
||||
case .notMutualContact:
|
||||
let _ = (context.account.postbox.loadedPeerWithId(memberId)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
let text: String
|
||||
if let peer = peer as? TelegramChannel, case .broadcast = peer.info {
|
||||
text = presentationData.strings.Channel_AddUserLeftError
|
||||
} else {
|
||||
text = presentationData.strings.GroupInfo_AddUserLeftError
|
||||
}
|
||||
parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
})
|
||||
return .complete()
|
||||
case .tooManyChannels:
|
||||
let _ = (context.account.postbox.loadedPeerWithId(memberId)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Invite_ChannelsTooMuch, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
})
|
||||
return .complete()
|
||||
case .groupFull:
|
||||
let signal = context.engine.peers.convertGroupToSupergroup(peerId: groupPeer.id)
|
||||
|> map(Optional.init)
|
||||
|> `catch` { error -> Signal<PeerId?, NoError> in
|
||||
switch error {
|
||||
case .tooManyChannels:
|
||||
Queue.mainQueue().async {
|
||||
parentController?.push(oldChannelsController(context: context, intent: .upgrade))
|
||||
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.ExportedInvitation(id: groupPeer.id))
|
||||
|> mapToSignal { exportedInvitation in
|
||||
return context.engine.peers.addGroupMember(peerId: groupPeer.id, memberId: memberId)
|
||||
|> deliverOnMainQueue
|
||||
|> `catch` { error -> Signal<Void, NoError> in
|
||||
if let exportedInvitation, let link = exportedInvitation.link {
|
||||
let failedPeerIds: [(PeerId, AddGroupMemberError)] = [(memberId, error)]
|
||||
let _ = (context.engine.data.get(
|
||||
EngineDataList(failedPeerIds.compactMap { item -> EnginePeer.Id? in
|
||||
return item.0
|
||||
}.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { peerItems in
|
||||
let peers = peerItems.compactMap { $0 }
|
||||
if !peers.isEmpty, let contactsController, let navigationController = contactsController.navigationController as? NavigationController {
|
||||
var viewControllers = navigationController.viewControllers
|
||||
|
||||
let inviteScreen = SendInviteLinkScreen(context: context, link: link, peers: peers)
|
||||
|
||||
if let index = viewControllers.firstIndex(where: { $0 === contactsController }) {
|
||||
viewControllers.remove(at: index)
|
||||
viewControllers.append(inviteScreen)
|
||||
navigationController.setViewControllers(viewControllers, animated: true)
|
||||
} else {
|
||||
navigationController.pushViewController(inviteScreen)
|
||||
}
|
||||
} else {
|
||||
contactsController?.dismiss()
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { upgradedPeerId -> Signal<PeerId?, NoError> in
|
||||
guard let upgradedPeerId = upgradedPeerId else {
|
||||
return .single(nil)
|
||||
}
|
||||
return context.peerChannelMemberCategoriesContextsManager.addMember(engine: context.engine, peerId: upgradedPeerId, memberId: memberId)
|
||||
|> `catch` { _ -> Signal<Never, NoError> in
|
||||
return .complete()
|
||||
}
|
||||
|> mapToSignal { _ -> Signal<PeerId?, NoError> in
|
||||
}
|
||||
|> then(.single(upgradedPeerId))
|
||||
}
|
||||
|> deliverOnMainQueue
|
||||
|> mapToSignal { _ -> Signal<Void, NoError> in
|
||||
})
|
||||
|
||||
return .complete()
|
||||
}
|
||||
return signal
|
||||
|
||||
switch error {
|
||||
case .generic:
|
||||
return .complete()
|
||||
case .privacy:
|
||||
let _ = (context.account.postbox.loadedPeerWithId(memberId)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(peer).compactDisplayTitle, EnginePeer(peer).compactDisplayTitle).string, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
})
|
||||
return .complete()
|
||||
case .notMutualContact:
|
||||
let _ = (context.account.postbox.loadedPeerWithId(memberId)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
let text: String
|
||||
if let peer = peer as? TelegramChannel, case .broadcast = peer.info {
|
||||
text = presentationData.strings.Channel_AddUserLeftError
|
||||
} else {
|
||||
text = presentationData.strings.GroupInfo_AddUserLeftError
|
||||
}
|
||||
parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
})
|
||||
return .complete()
|
||||
case .tooManyChannels:
|
||||
let _ = (context.account.postbox.loadedPeerWithId(memberId)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Invite_ChannelsTooMuch, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
})
|
||||
return .complete()
|
||||
case .groupFull:
|
||||
let signal = context.engine.peers.convertGroupToSupergroup(peerId: groupPeer.id)
|
||||
|> map(Optional.init)
|
||||
|> `catch` { error -> Signal<PeerId?, NoError> in
|
||||
switch error {
|
||||
case .tooManyChannels:
|
||||
Queue.mainQueue().async {
|
||||
parentController?.push(oldChannelsController(context: context, intent: .upgrade))
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { upgradedPeerId -> Signal<PeerId?, NoError> in
|
||||
guard let upgradedPeerId = upgradedPeerId else {
|
||||
return .single(nil)
|
||||
}
|
||||
return context.peerChannelMemberCategoriesContextsManager.addMember(engine: context.engine, peerId: upgradedPeerId, memberId: memberId)
|
||||
|> `catch` { _ -> Signal<Never, NoError> in
|
||||
return .complete()
|
||||
}
|
||||
|> mapToSignal { _ -> Signal<PeerId?, NoError> in
|
||||
}
|
||||
|> then(.single(upgradedPeerId))
|
||||
}
|
||||
|> deliverOnMainQueue
|
||||
|> mapToSignal { _ -> Signal<Void, NoError> in
|
||||
return .complete()
|
||||
}
|
||||
return signal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,7 +239,7 @@ public class ShareRootControllerImpl {
|
||||
return nil
|
||||
})
|
||||
|
||||
let sharedContext = SharedAccountContextImpl(mainWindow: nil, sharedContainerPath: self.initializationData.appGroupPath, basePath: rootPath, encryptionParameters: ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: self.initializationData.encryptionParameters.0)!, salt: ValueBoxEncryptionParameters.Salt(data: self.initializationData.encryptionParameters.1)!), accountManager: accountManager, appLockContext: appLockContext, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: self.initializationData.apiId, apiHash: self.initializationData.apiHash, languagesCategory: self.initializationData.languagesCategory, appVersion: self.initializationData.appVersion, voipMaxLayer: 0, voipVersions: [], appData: .single(self.initializationData.bundleData), autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider(), resolvedDeviceName: nil), hasInAppPurchases: false, rootPath: rootPath, legacyBasePath: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), firebaseSecretStream: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in }, appDelegate: nil)
|
||||
let sharedContext = SharedAccountContextImpl(mainWindow: nil, sharedContainerPath: self.initializationData.appGroupPath, basePath: rootPath, encryptionParameters: ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: self.initializationData.encryptionParameters.0)!, salt: ValueBoxEncryptionParameters.Salt(data: self.initializationData.encryptionParameters.1)!), accountManager: accountManager, appLockContext: appLockContext, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: self.initializationData.apiId, apiHash: self.initializationData.apiHash, languagesCategory: self.initializationData.languagesCategory, appVersion: self.initializationData.appVersion, voipMaxLayer: 0, voipVersions: [], appData: .single(self.initializationData.bundleData), autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider(), deviceModelName: nil), hasInAppPurchases: false, rootPath: rootPath, legacyBasePath: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), firebaseSecretStream: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in }, appDelegate: nil)
|
||||
presentationDataPromise.set(sharedContext.presentationData)
|
||||
internalContext = InternalContext(sharedContext: sharedContext)
|
||||
globalInternalContext = internalContext
|
||||
|
||||
@ -244,9 +244,9 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
self.currentInAppNotificationSettings = Atomic(value: initialPresentationDataAndSettings.inAppNotificationSettings)
|
||||
|
||||
if automaticEnergyUsageShouldBeOnNow(settings: self.currentAutomaticMediaDownloadSettings) {
|
||||
self.energyUsageSettings = self.currentAutomaticMediaDownloadSettings.energyUsageSettings
|
||||
self.energyUsageSettings = EnergyUsageSettings.powerSavingDefault
|
||||
} else {
|
||||
self.energyUsageSettings = EnergyUsageSettings.default
|
||||
self.energyUsageSettings = self.currentAutomaticMediaDownloadSettings.energyUsageSettings
|
||||
}
|
||||
|
||||
let presentationData: Signal<PresentationData, NoError> = .single(initialPresentationDataAndSettings.presentationData)
|
||||
@ -389,17 +389,17 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
strongSelf.currentAutomaticMediaDownloadSettings = next
|
||||
|
||||
if automaticEnergyUsageShouldBeOnNow(settings: next) {
|
||||
strongSelf.energyUsageSettings = next.energyUsageSettings
|
||||
strongSelf.energyUsageSettings = EnergyUsageSettings.powerSavingDefault
|
||||
} else {
|
||||
strongSelf.energyUsageSettings = EnergyUsageSettings.default
|
||||
strongSelf.energyUsageSettings = next.energyUsageSettings
|
||||
}
|
||||
strongSelf.energyUsageAutomaticDisposable.set((automaticEnergyUsageShouldBeOn(settings: next)
|
||||
|> deliverOnMainQueue).start(next: { value in
|
||||
if let strongSelf = self {
|
||||
if value {
|
||||
strongSelf.energyUsageSettings = next.energyUsageSettings
|
||||
strongSelf.energyUsageSettings = EnergyUsageSettings.powerSavingDefault
|
||||
} else {
|
||||
strongSelf.energyUsageSettings = EnergyUsageSettings.default
|
||||
strongSelf.energyUsageSettings = next.energyUsageSettings
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
@ -283,6 +283,19 @@ public struct EnergyUsageSettings: Codable, Equatable {
|
||||
)
|
||||
}
|
||||
|
||||
public static var powerSavingDefault: EnergyUsageSettings {
|
||||
return EnergyUsageSettings(
|
||||
activationThreshold: 10,
|
||||
autoplayVideo: false,
|
||||
autoplayGif: false,
|
||||
loopStickers: false,
|
||||
loopEmoji: false,
|
||||
fullTranslucency: false,
|
||||
extendBackgroundWork: false,
|
||||
autodownloadInBackground: false
|
||||
)
|
||||
}
|
||||
|
||||
public var activationThreshold: Int32
|
||||
|
||||
public var autoplayVideo: Bool
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"app": "9.4.2",
|
||||
"app": "9.5",
|
||||
"bazel": "5.3.1",
|
||||
"xcode": "14.2"
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user