diff --git a/submodules/AvatarNode/Sources/AvatarNode.swift b/submodules/AvatarNode/Sources/AvatarNode.swift index 86256cc0b4..92cdcfe761 100644 --- a/submodules/AvatarNode/Sources/AvatarNode.swift +++ b/submodules/AvatarNode/Sources/AvatarNode.swift @@ -449,7 +449,12 @@ public final class AvatarNode: ASDisplayNode { colorsArray = grayscaleColors } } else if colorIndex == -1 { - colorsArray = grayscaleColors + if let parameters = parameters as? AvatarNodeParameters, let theme = parameters.theme { + let colors = theme.chatList.unpinnedArchiveAvatarColor.backgroundColors.colors + colorsArray = [colors.1.cgColor, colors.0.cgColor] + } else { + colorsArray = grayscaleColors + } } else { colorsArray = gradientColors[colorIndex % gradientColors.count] } diff --git a/submodules/Display/Display/ListView.swift b/submodules/Display/Display/ListView.swift index 70ad620f7f..ea7a37522d 100644 --- a/submodules/Display/Display/ListView.swift +++ b/submodules/Display/Display/ListView.swift @@ -3799,9 +3799,9 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture if node.apparentHeight > self.visibleSize.height - self.insets.top - self.insets.bottom { if node.frame.maxY > self.visibleSize.height - self.insets.bottom { self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: ListViewDeleteAndInsertOptions(), scrollToItem: ListViewScrollToItem(index: index, position: ListViewScrollPosition.bottom(-overflow), animated: animated, curve: ListViewAnimationCurve.Default(duration: 0.25), directionHint: ListViewScrollToItemDirectionHint.Down), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in }) - }/* else if node.frame.minY < self.insets.top { - self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: ListViewDeleteAndInsertOptions(), scrollToItem: ListViewScrollToItem(index: index, position: ListViewScrollPosition.top(0.0), animated: true, curve: ListViewAnimationCurve.Default(duration: 0.25), directionHint: ListViewScrollToItemDirectionHint.Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in }) - }*/ + } else if node.frame.minY < self.insets.top && overflow > 0.0 { + self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: ListViewDeleteAndInsertOptions(), scrollToItem: ListViewScrollToItem(index: index, position: ListViewScrollPosition.top(-overflow), animated: true, curve: ListViewAnimationCurve.Default(duration: 0.25), directionHint: ListViewScrollToItemDirectionHint.Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in }) + } } else { if self.experimentalSnapScrollToItem { self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: ListViewDeleteAndInsertOptions(), scrollToItem: ListViewScrollToItem(index: index, position: ListViewScrollPosition.visible, animated: animated, curve: ListViewAnimationCurve.Default(duration: nil), directionHint: ListViewScrollToItemDirectionHint.Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in }) diff --git a/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift b/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift index 8f168ee150..c8018f245a 100644 --- a/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift +++ b/submodules/ItemListPeerItem/Sources/ItemListPeerItem.swift @@ -563,8 +563,8 @@ public class ItemListPeerItemNode: ItemListRevealOptionsItemNode, ItemListItemNo let (labelLayout, labelApply) = makeLabelLayout(TextNodeLayoutArguments(attributedString: labelAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 16.0 - editingOffset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 12.0 - editingOffset - rightInset - labelLayout.size.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - let (statusLayout, statusApply) = makeStatusLayout(TextNodeLayoutArguments(attributedString: statusAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 8.0 - editingOffset - rightInset - labelLayout.size.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 12.0 - editingOffset - rightInset - labelLayout.size.width - labelInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let (statusLayout, statusApply) = makeStatusLayout(TextNodeLayoutArguments(attributedString: statusAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 8.0 - editingOffset - rightInset - labelLayout.size.width - labelInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) var insets = itemListNeighborsGroupedInsets(neighbors) if !item.hasTopGroupInset { diff --git a/submodules/LiveLocationPositionNode/Sources/ChatMessageLiveLocationPositionNode.swift b/submodules/LiveLocationPositionNode/Sources/ChatMessageLiveLocationPositionNode.swift index a0b99ae1b0..ce9b4ead41 100644 --- a/submodules/LiveLocationPositionNode/Sources/ChatMessageLiveLocationPositionNode.swift +++ b/submodules/LiveLocationPositionNode/Sources/ChatMessageLiveLocationPositionNode.swift @@ -148,8 +148,10 @@ public final class ChatMessageLiveLocationPositionNode: ASDisplayNode { strongSelf.iconNode.setSignal(venueIcon(postbox: context.account.postbox, type: updatedVenueType, background: false)) } + + let arguments = VenueIconArguments(defaultForegroundColor: theme.chat.inputPanel.actionControlForegroundColor) let iconSize = CGSize(width: 44.0, height: 44.0) - let apply = iconLayout(TransformImageArguments(corners: ImageCorners(), imageSize: iconSize, boundingSize: iconSize, intrinsicInsets: UIEdgeInsets())) + let apply = iconLayout(TransformImageArguments(corners: ImageCorners(), imageSize: iconSize, boundingSize: iconSize, intrinsicInsets: UIEdgeInsets(), custom: arguments)) apply() strongSelf.iconNode.frame = CGRect(origin: CGPoint(x: 9.0, y: 14.0), size: iconSize) diff --git a/submodules/LocationResources/Sources/VenueIconResources.swift b/submodules/LocationResources/Sources/VenueIconResources.swift index e4261cb88e..4384acda86 100644 --- a/submodules/LocationResources/Sources/VenueIconResources.swift +++ b/submodules/LocationResources/Sources/VenueIconResources.swift @@ -154,6 +154,20 @@ public func venueIconColor(type: String) -> UIColor { return randomColors[index] } +public struct VenueIconArguments: TransformImageCustomArguments { + let defaultForegroundColor: UIColor + + public init(defaultForegroundColor: UIColor) { + self.defaultForegroundColor = defaultForegroundColor + } + + public func serialized() -> NSArray { + let array = NSMutableArray() + array.add(self.defaultForegroundColor) + return array + } +} + public func venueIcon(postbox: Postbox, type: String, background: Bool) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { let isBuiltinIcon = ["", "home", "work"].contains(type) let data: Signal = isBuiltinIcon ? .single(nil) : venueIconData(postbox: postbox, resource: VenueIconResource(type: type)) @@ -167,8 +181,13 @@ public func venueIcon(postbox: Postbox, type: String, background: Bool) -> Signa } let backgroundColor = venueIconColor(type: type) - let foregroundColor = UIColor.white - + let foregroundColor: UIColor + if type.isEmpty, let customArguments = arguments.custom as? VenueIconArguments { + foregroundColor = customArguments.defaultForegroundColor + } else { + foregroundColor = UIColor.white + } + context.withFlippedContext { c in if background { c.setFillColor(backgroundColor.cgColor) diff --git a/submodules/LocationUI/Sources/LocationActionListItem.swift b/submodules/LocationUI/Sources/LocationActionListItem.swift index 20082b8dcd..52ac179b82 100644 --- a/submodules/LocationUI/Sources/LocationActionListItem.swift +++ b/submodules/LocationUI/Sources/LocationActionListItem.swift @@ -73,7 +73,7 @@ private func generateLiveLocationIcon(theme: PresentationTheme) -> UIImage { context.scaleBy(x: 1.0, y: -1.0) context.translateBy(x: -size.width / 2.0, y: -size.height / 2.0) - if let image = generateTintedImage(image: UIImage(bundleImageName: "Location/SendLiveLocationIcon"), color: theme.chat.inputPanel.actionControlForegroundColor) { + if let image = generateTintedImage(image: UIImage(bundleImageName: "Location/SendLiveLocationIcon"), color: .white) { context.draw(image.cgImage!, in: CGRect(origin: CGPoint(x: floor((size.width - image.size.width) / 2.0), y: floor((size.height - image.size.height) / 2.0)), size: image.size)) } }! diff --git a/submodules/LocationUI/Sources/LocationAnnotation.swift b/submodules/LocationUI/Sources/LocationAnnotation.swift index 490994ab4c..4dd1184bac 100644 --- a/submodules/LocationUI/Sources/LocationAnnotation.swift +++ b/submodules/LocationUI/Sources/LocationAnnotation.swift @@ -97,6 +97,7 @@ class LocationPinAnnotationView: MKAnnotationView { var strokeLabelNode: ImmediateTextNode? var labelNode: ImmediateTextNode? + var initialized = false var appeared = false var animating = false @@ -203,6 +204,11 @@ class LocationPinAnnotationView: MKAnnotationView { if annotation.forcedSelection { self.setSelected(true, animated: false) } + + if self.initialized && !self.appeared { + self.appeared = true + self.animateAppearance() + } } } } @@ -211,6 +217,7 @@ class LocationPinAnnotationView: MKAnnotationView { override func prepareForReuse() { self.smallNode.isHidden = true self.backgroundNode.isHidden = false + self.appeared = false } override func setSelected(_ selected: Bool, animated: Bool) { @@ -516,6 +523,10 @@ class LocationPinAnnotationView: MKAnnotationView { } func animateAppearance() { + guard let annotation = self.annotation as? LocationPinAnnotation, annotation.location != nil && !annotation.forcedSelection else { + return + } + self.smallNode.transform = CATransform3DMakeScale(0.1, 0.1, 1.0) let avatarNodeTransform = self.avatarNode?.transform @@ -546,8 +557,13 @@ class LocationPinAnnotationView: MKAnnotationView { let smallIconApply = smallIconLayout(TransformImageArguments(corners: ImageCorners(), imageSize: self.smallIconNode.bounds.size, boundingSize: self.smallIconNode.bounds.size, intrinsicInsets: UIEdgeInsets())) smallIconApply() + var arguments: VenueIconArguments? + if let annotation = self.annotation as? LocationPinAnnotation { + arguments = VenueIconArguments(defaultForegroundColor: annotation.theme.chat.inputPanel.actionControlForegroundColor) + } + let iconLayout = self.iconNode.asyncLayout() - let iconApply = iconLayout(TransformImageArguments(corners: ImageCorners(), imageSize: self.iconNode.bounds.size, boundingSize: self.iconNode.bounds.size, intrinsicInsets: UIEdgeInsets())) + let iconApply = iconLayout(TransformImageArguments(corners: ImageCorners(), imageSize: self.iconNode.bounds.size, boundingSize: self.iconNode.bounds.size, intrinsicInsets: UIEdgeInsets(), custom: arguments)) iconApply() if let avatarNode = self.avatarNode { @@ -558,10 +574,8 @@ class LocationPinAnnotationView: MKAnnotationView { if !self.appeared { self.appeared = true - - if let annotation = annotation as? LocationPinAnnotation, annotation.location != nil && !annotation.forcedSelection { - self.animateAppearance() - } + self.initialized = true + self.animateAppearance() } } } diff --git a/submodules/LocationUI/Sources/LocationMapNode.swift b/submodules/LocationUI/Sources/LocationMapNode.swift index 9b5a11475b..7fd7152b2f 100644 --- a/submodules/LocationUI/Sources/LocationMapNode.swift +++ b/submodules/LocationUI/Sources/LocationMapNode.swift @@ -120,7 +120,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate { } } - func setMapCenter(coordinate: CLLocationCoordinate2D, span: MKCoordinateSpan = defaultMapSpan, offset: CGPoint = CGPoint(), isUserLocation: Bool = false, animated: Bool = false) { + func setMapCenter(coordinate: CLLocationCoordinate2D, span: MKCoordinateSpan = defaultMapSpan, offset: CGPoint = CGPoint(), isUserLocation: Bool = false, hidePicker: Bool = false, animated: Bool = false) { let region = MKCoordinateRegion(center: coordinate, span: span) self.ignoreRegionChanges = true if offset == CGPoint() { @@ -136,7 +136,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate { self.returnedToUserLocation = true self.pickerAnnotationView?.setRaised(true, animated: true) } - } else if self.hasPickerAnnotation, let customUserLocationAnnotationView = self.customUserLocationAnnotationView, customUserLocationAnnotationView.isHidden { + } else if self.hasPickerAnnotation, let customUserLocationAnnotationView = self.customUserLocationAnnotationView, customUserLocationAnnotationView.isHidden, hidePicker { self.pickerAnnotationContainerView.isHidden = true customUserLocationAnnotationView.setSelected(false, animated: false) customUserLocationAnnotationView.isHidden = false diff --git a/submodules/LocationUI/Sources/LocationPickerController.swift b/submodules/LocationUI/Sources/LocationPickerController.swift index e60f9e19ba..1a150f9c18 100644 --- a/submodules/LocationUI/Sources/LocationPickerController.swift +++ b/submodules/LocationUI/Sources/LocationPickerController.swift @@ -196,13 +196,7 @@ public final class LocationPickerController: ViewController { guard let strongSelf = self else { return } - strongSelf.controllerNode.updateState { state in - var state = state - state.displayingMapModeOptions = false - state.selectedLocation = .none - state.searchingVenuesAround = false - return state - } + strongSelf.controllerNode.goToUserLocation() }, goToCoordinate: { [weak self] coordinate in guard let strongSelf = self else { return diff --git a/submodules/LocationUI/Sources/LocationPickerControllerNode.swift b/submodules/LocationUI/Sources/LocationPickerControllerNode.swift index a7fc4e163c..e94d1847b4 100644 --- a/submodules/LocationUI/Sources/LocationPickerControllerNode.swift +++ b/submodules/LocationUI/Sources/LocationPickerControllerNode.swift @@ -412,16 +412,18 @@ final class LocationPickerControllerNode: ViewControllerTracingNode { } ) - let foundVenues: Signal<[TelegramMediaMap]?, NoError> = .single(nil) + let foundVenues: Signal<([TelegramMediaMap], CLLocation)?, NoError> = .single(nil) |> then( self.searchVenuesPromise.get() |> distinctUntilChanged - |> mapToSignal { coordinate -> Signal<[TelegramMediaMap]?, NoError> in + |> mapToSignal { coordinate -> Signal<([TelegramMediaMap], CLLocation)?, NoError> in if let coordinate = coordinate { return (.single(nil) |> then( nearbyVenues(account: context.account, latitude: coordinate.latitude, longitude: coordinate.longitude) - |> map (Optional.init) + |> map { venues -> ([TelegramMediaMap], CLLocation)? in + return (venues, CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)) + } )) } else { return .single(nil) @@ -435,8 +437,10 @@ final class LocationPickerControllerNode: ViewControllerTracingNode { let previousEntries = Atomic<[LocationPickerEntry]?>(value: nil) self.disposable = (combineLatest(self.presentationDataPromise.get(), self.statePromise.get(), userLocation, venues, foundVenues) - |> deliverOnMainQueue).start(next: { [weak self] presentationData, state, userLocation, venues, foundVenues in + |> deliverOnMainQueue).start(next: { [weak self] presentationData, state, userLocation, venues, foundVenuesAndLocation in if let strongSelf = self { + let (foundVenues, foundVenuesLocation) = foundVenuesAndLocation ?? (nil, nil) + var entries: [LocationPickerEntry] = [] switch state.selectedLocation { case let .location(coordinate, address): @@ -483,7 +487,7 @@ final class LocationPickerControllerNode: ViewControllerTracingNode { entries.append(.header(presentationData.theme, presentationData.strings.Map_ChooseAPlace.uppercased())) - var displayedVenues = state.searchingVenuesAround ? foundVenues : venues + var displayedVenues = foundVenues != nil || state.searchingVenuesAround ? foundVenues : venues if let venues = displayedVenues { var index: Int = 0 for venue in venues { @@ -513,10 +517,8 @@ final class LocationPickerControllerNode: ViewControllerTracingNode { strongSelf.headerNode.mapNode.setMapCenter(coordinate: userLocation.coordinate, isUserLocation: true, animated: previousUserLocation != nil) } strongSelf.headerNode.mapNode.resetAnnotationSelection() - strongSelf.searchVenuesPromise.set(.single(nil)) case .selecting: strongSelf.headerNode.mapNode.resetAnnotationSelection() - strongSelf.searchVenuesPromise.set(.single(nil)) case let .location(coordinate, address): var updateMap = false switch previousState.selectedLocation { @@ -530,16 +532,22 @@ final class LocationPickerControllerNode: ViewControllerTracingNode { break } if updateMap { - strongSelf.headerNode.mapNode.setMapCenter(coordinate: coordinate, isUserLocation: false, animated: true) + strongSelf.headerNode.mapNode.setMapCenter(coordinate: coordinate, isUserLocation: false, hidePicker: false, animated: true) strongSelf.headerNode.mapNode.switchToPicking(animated: false) } if address != nil { - displayingPlacesButton = foundVenues == nil + if foundVenues == nil { + displayingPlacesButton = true + } else if let previousLocation = foundVenuesLocation { + let currentLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude) + if currentLocation.distance(from: previousLocation) > 500 { + displayingPlacesButton = true + } + } } case let .venue(venue): - strongSelf.headerNode.mapNode.setMapCenter(coordinate: venue.coordinate, animated: true) - strongSelf.searchVenuesPromise.set(.single(nil)) + strongSelf.headerNode.mapNode.setMapCenter(coordinate: venue.coordinate, hidePicker: true, animated: true) } strongSelf.headerNode.updateState(mapMode: state.mapMode, displayingMapModeOptions: state.displayingMapModeOptions, displayingPlacesButton: displayingPlacesButton, animated: true) @@ -656,21 +664,16 @@ final class LocationPickerControllerNode: ViewControllerTracingNode { var state = state state.displayingMapModeOptions = false state.selectedLocation = annotation?.location.flatMap { .venue($0) } ?? .none - state.searchingVenuesAround = false + if annotation == nil { + state.searchingVenuesAround = false + } return state } } self.headerNode.mapNode.userLocationAnnotationSelected = { [weak self] in - guard let strongSelf = self else { - return - } - strongSelf.updateState { state in - var state = state - state.displayingMapModeOptions = false - state.selectedLocation = .none - state.searchingVenuesAround = false - return state + if let strongSelf = self { + strongSelf.goToUserLocation() } } } @@ -856,8 +859,20 @@ final class LocationPickerControllerNode: ViewControllerTracingNode { self.shadeNode.backgroundColor = highlighted ? self.presentationData.theme.list.itemHighlightedBackgroundColor : self.presentationData.theme.list.plainBackgroundColor } + func goToUserLocation() { + self.searchVenuesPromise.set(.single(nil)) + self.updateState { state in + var state = state + state.displayingMapModeOptions = false + state.selectedLocation = .none + state.searchingVenuesAround = false + return state + } + } + func requestPlacesAtSelectedLocation() { if case let .location(coordinate, _) = self.state.selectedLocation { + self.headerNode.mapNode.setMapCenter(coordinate: coordinate, animated: true) self.searchVenuesPromise.set(.single(coordinate)) self.updateState { state in var state = state diff --git a/submodules/MapResourceToAvatarSizes/Sources/MapResourceToAvatarSizes.swift b/submodules/MapResourceToAvatarSizes/Sources/MapResourceToAvatarSizes.swift index 9c4963d8dd..c42f510e76 100644 --- a/submodules/MapResourceToAvatarSizes/Sources/MapResourceToAvatarSizes.swift +++ b/submodules/MapResourceToAvatarSizes/Sources/MapResourceToAvatarSizes.swift @@ -15,7 +15,13 @@ public func mapResourceToAvatarSizes(postbox: Postbox, resource: MediaResource, } var result: [Int: Data] = [:] for i in 0 ..< representations.count { - if let scaledImage = generateScaledImage(image: image, size: representations[i].dimensions.cgSize, scale: 1.0), let scaledData = scaledImage.jpegData(compressionQuality: 0.8) { + let size: CGSize + if representations[i].dimensions.width == 80 { + size = CGSize(width: 160.0, height: 160.0) + } else { + size = representations[i].dimensions.cgSize + } + if let scaledImage = generateScaledImage(image: image, size: size, scale: 1.0), let scaledData = scaledImage.jpegData(compressionQuality: 0.8) { result[i] = scaledData } } diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift index b2715bf6cd..3040fedb0c 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift @@ -105,11 +105,7 @@ final class ThemeAccentColorController: ViewController { } } - if case .background = mode { - self.title = self.presentationData.strings.Wallpaper_Title - } else { - self.navigationItem.titleView = self.segmentedTitleView - } + self.navigationItem.titleView = self.segmentedTitleView self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: UIView()) } @@ -238,9 +234,11 @@ final class ThemeAccentColorController: ViewController { } } - let _ = (self.context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.presentationThemeSettings]) - |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] sharedData in + let _ = (combineLatest( + self.context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.presentationThemeSettings]) |> take(1), + telegramWallpapers(postbox: context.account.postbox, network: context.account.network) |> take(1) + ) + |> deliverOnMainQueue).start(next: { [weak self] sharedData, wallpapers in guard let strongSelf = self else { return } @@ -250,7 +248,7 @@ final class ThemeAccentColorController: ViewController { var initialWallpaper: TelegramWallpaper? var backgroundColors: (UIColor, UIColor?)? var patternWallpaper: TelegramWallpaper? - var patternIntensity: Int32 = 50 + var patternIntensity: Int32 = 40 var motion = false let messageColors: (UIColor, UIColor?)? var defaultMessagesColor: UIColor? @@ -263,7 +261,7 @@ final class ThemeAccentColorController: ViewController { return } if case let .file(file) = wallpaper, file.isPattern { - var patternColor = UIColor(rgb: 0xd6e2ee, alpha: 0.5) + var patternColor = UIColor(rgb: 0xd6e2ee, alpha: 0.4) var bottomColor: UIColor? if let color = file.settings.color { if let intensity = file.settings.intensity { @@ -291,7 +289,7 @@ final class ThemeAccentColorController: ViewController { if let themeReference = strongSelf.mode.themeReference { accentColor = settings.themeSpecificAccentColors[themeReference.index]?.color ?? defaultDayAccentColor - let wallpaper: TelegramWallpaper + var wallpaper: TelegramWallpaper if let customWallpaper = settings.themeSpecificChatWallpapers[themeReference.index] { wallpaper = customWallpaper } else { @@ -307,6 +305,21 @@ final class ThemeAccentColorController: ViewController { wallpaper = theme.chat.defaultWallpaper } + if case let .builtin(settings) = wallpaper { + var defaultPatternWallpaper: TelegramWallpaper? + + for wallpaper in wallpapers { + if case let .file(file) = wallpaper, file.slug == "JqSUrO0-mFIBAAAAWwTvLzoWGQI" { + defaultPatternWallpaper = wallpaper + break + } + } + + if let defaultPatternWallpaper = defaultPatternWallpaper { + wallpaper = defaultPatternWallpaper.withUpdatedSettings(WallpaperSettings(blur: settings.blur, motion: settings.motion, color: 0xd6e2ee, bottomColor: nil, intensity: 25, rotation: nil)) + } + } + if !wallpaper.isColorOrGradient && !ignoreDefaultWallpaper { initialWallpaper = wallpaper } @@ -338,6 +351,10 @@ final class ThemeAccentColorController: ViewController { let wallpaper = wallpaper ?? theme.chat.defaultWallpaper extractWallpaperParameters(wallpaper) + if !wallpaper.isColorOrGradient { + initialWallpaper = wallpaper + } + let topMessageColor = theme.chat.message.outgoing.bubble.withWallpaper.fill let bottomMessageColor = theme.chat.message.outgoing.bubble.withWallpaper.gradientFill diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift index 06212bb676..4e71b8e8bf 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift @@ -63,7 +63,7 @@ struct ThemeColorState { self.preview = false self.previousPatternWallpaper = nil self.patternWallpaper = nil - self.patternIntensity = 50 + self.patternIntensity = 40 self.motion = false self.defaultMessagesColor = nil self.messagesColors = nil @@ -491,28 +491,22 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate strongSelf.backgroundColor = UIColor(rgb: UInt32(bitPattern: value)) strongSelf.immediateBackgroundNode.backgroundColor = UIColor(rgb: UInt32(bitPattern: value)) strongSelf.immediateBackgroundNode.image = nil - strongSelf.immediateBackgroundNode.isHidden = false strongSelf.signalBackgroundNode.isHidden = true strongSelf.patternWallpaper = nil } else if let wallpaperImage = wallpaperImage { strongSelf.immediateBackgroundNode.image = wallpaperImage - strongSelf.immediateBackgroundNode.isHidden = false strongSelf.signalBackgroundNode.isHidden = true strongSelf.patternWallpaper = nil } else if let wallpaperSignal = wallpaperSignal { strongSelf.signalBackgroundNode.contentMode = .scaleToFill - strongSelf.immediateBackgroundNode.isHidden = false strongSelf.signalBackgroundNode.isHidden = false if case let .file(file) = wallpaper, let (layout, _, _) = strongSelf.validLayout { var dispatch = false if let previousWallpaper = strongSelf.patternWallpaper, case let .file(previousFile) = previousWallpaper, file.id == previousFile.id { dispatch = true - } else { - strongSelf.patternWallpaper = wallpaper - strongSelf.signalBackgroundNode.setSignal(wallpaperSignal) } if dispatch { @@ -541,6 +535,11 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate let imageApply = makeImageLayout(TransformImageArguments(corners: ImageCorners(), imageSize: layout.size, boundingSize: layout.size, intrinsicInsets: UIEdgeInsets(), custom: patternArguments)) let _ = imageApply() } + + if !dispatch { + strongSelf.signalBackgroundNode.setSignal(wallpaperSignal) + strongSelf.patternWallpaper = wallpaper + } } else { strongSelf.signalBackgroundNode.setSignal(wallpaperSignal) strongSelf.patternWallpaper = nil @@ -1043,6 +1042,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate updated.patternWallpaper = nil updated.displayPatternPanel = false } else { + updated.colorPanelCollapsed = false updated.displayPatternPanel = true if current.patternWallpaper == nil, let wallpaper = wallpaper { updated.patternWallpaper = wallpaper @@ -1056,7 +1056,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate }, animated: true) if appeared { - self.patternPanelNode.didAppear(initialWallpaper: wallpaper) + self.patternPanelNode.didAppear(initialWallpaper: wallpaper, intensity: self.state.patternIntensity) } } diff --git a/submodules/SettingsUI/Sources/Themes/ThemeColorsGridController.swift b/submodules/SettingsUI/Sources/Themes/ThemeColorsGridController.swift index 1d64872306..87c5221f9f 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeColorsGridController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeColorsGridController.swift @@ -129,6 +129,7 @@ final class ThemeColorsGridController: ViewController { }, presentColorPicker: { [weak self] in if let strongSelf = self { let _ = (strongSelf.context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.presentationThemeSettings]) + |> take(1) |> deliverOnMainQueue).start(next: { [weak self] sharedData in guard let strongSelf = self else { return @@ -144,10 +145,23 @@ final class ThemeColorsGridController: ViewController { } let controller = ThemeAccentColorController(context: strongSelf.context, mode: .background(themeReference: themeReference)) - controller.navigationPresentation = .modalInLargeLayout controller.completion = { [weak self] in if let strongSelf = self, let navigationController = strongSelf.navigationController as? NavigationController { - let _ = navigationController.popViewController(animated: true) + var controllers = navigationController.viewControllers + controllers = controllers.filter { controller in + if controller is ThemeColorsGridController { + return false + } + return true + } + navigationController.setViewControllers(controllers, animated: false) + controllers = controllers.filter { controller in + if controller is ThemeAccentColorController { + return false + } + return true + } + navigationController.setViewControllers(controllers, animated: true) } } strongSelf.push(controller) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift index 7fcb29126c..4ef49fd500 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift @@ -563,27 +563,40 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The return } - let controller = ThemeAccentColorController(context: context, mode: .edit(theme: theme, wallpaper: nil, defaultThemeReference: nil, create: true, completion: { result in - let controller = editThemeController(context: context, mode: .create(result), navigateToChat: { peerId in - if let navigationController = getNavigationControllerImpl?() { - context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId))) - } - }) - updateControllersImpl?({ controllers in - var controllers = controllers - controllers = controllers.filter { controller in - if controller is ThemeAccentColorController { - return false - } - return true - } - controllers.append(controller) - return controllers - }) - })) + let resolvedWallpaper: Signal + if case let .file(file) = theme.chat.defaultWallpaper, file.id == 0 { + resolvedWallpaper = cachedWallpaper(account: context.account, slug: file.slug, settings: file.settings) + |> map { cachedWallpaper -> TelegramWallpaper in + return cachedWallpaper?.wallpaper ?? theme.chat.defaultWallpaper + } + } else { + resolvedWallpaper = .single(theme.chat.defaultWallpaper) + } - c.dismiss(completion: { - pushControllerImpl?(controller) + let _ = (resolvedWallpaper + |> deliverOnMainQueue).start(next: { wallpaper in + let controller = ThemeAccentColorController(context: context, mode: .edit(theme: theme, wallpaper: wallpaper, defaultThemeReference: nil, create: true, completion: { result in + let controller = editThemeController(context: context, mode: .create(result), navigateToChat: { peerId in + if let navigationController = getNavigationControllerImpl?() { + context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId))) + } + }) + updateControllersImpl?({ controllers in + var controllers = controllers + controllers = controllers.filter { controller in + if controller is ThemeAccentColorController { + return false + } + return true + } + controllers.append(controller) + return controllers + }) + })) + + c.dismiss(completion: { + pushControllerImpl?(controller) + }) }) }))) } @@ -835,9 +848,12 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The public final class ThemeSettingsCrossfadeController: ViewController { private let snapshotView: UIView? - public init() { - self.snapshotView = (UIScreen.main as? UIView)?.snapshotContentTree() //UIScreen.main.snapshotView(afterScreenUpdates: false) - + public init(view: UIView? = nil) { + if let view = view { + self.snapshotView = view.snapshotContentTree() + } else { + self.snapshotView = UIScreen.main.snapshotView(afterScreenUpdates: false) + } super.init(navigationBarPresentationData: nil) self.statusBar.statusBarStyle = .Ignore diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift index 38dbb80104..3006b9664b 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift @@ -133,25 +133,21 @@ private func generateBorderImage(theme: PresentationTheme, bordered: Bool, selec } else { let image = generateImage(CGSize(width: 32.0, height: 32.0), rotatedContext: { size, context in let bounds = CGRect(origin: CGPoint(), size: size) - context.setFillColor(theme.list.itemBlocksBackgroundColor.cgColor) - context.fill(bounds) - - context.setBlendMode(.clear) - if selected { - context.fillEllipse(in: bounds.insetBy(dx: 5.0, dy: 5.0)) - } else { - context.fillEllipse(in: bounds.insetBy(dx: 1.0, dy: 1.0)) - } - context.setBlendMode(.normal) + context.clear(bounds) let lineWidth: CGFloat if selected { + lineWidth = 2.0 + context.setLineWidth(lineWidth) + context.setStrokeColor(theme.list.itemBlocksBackgroundColor.cgColor) + + context.strokeEllipse(in: bounds.insetBy(dx: 3.0 + lineWidth / 2.0, dy: 3.0 + lineWidth / 2.0)) + var accentColor = theme.list.itemAccentColor if accentColor.rgb == 0xffffff { accentColor = UIColor(rgb: 0x999999) } context.setStrokeColor(accentColor.cgColor) - lineWidth = 2.0 } else { context.setStrokeColor(theme.list.disclosureArrowColor.withAlphaComponent(0.4).cgColor) lineWidth = 1.0 @@ -291,7 +287,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode { let imageSize = CGSize(width: 98.0, height: 62.0) strongSelf.imageNode.frame = CGRect(origin: CGPoint(x: 10.0, y: 14.0), size: imageSize) - let applyLayout = makeImageLayout(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets(), emptyColor: .clear)) + let applyLayout = makeImageLayout(TransformImageArguments(corners: ImageCorners(radius: 16.0), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets(), emptyColor: .clear)) applyLayout() strongSelf.overlayNode.frame = CGRect(origin: CGPoint(x: 9.0, y: 13.0), size: CGSize(width: 100.0, height: 64.0)) @@ -398,7 +394,7 @@ private func preparedTransition(context: AccountContext, action: @escaping (Pres return ThemeSettingsThemeItemNodeTransition(deletions: deletions, insertions: insertions, updates: updates) } -private func ensureThemeVisible(listNode: ListView, themeReference: PresentationThemeReference, animated: Bool) { +private func ensureThemeVisible(listNode: ListView, themeReference: PresentationThemeReference, animated: Bool) -> Bool { var resultNode: ThemeSettingsThemeItemIconNode? listNode.forEachItemNode { node in if resultNode == nil, let node = node as? ThemeSettingsThemeItemIconNode { @@ -408,7 +404,10 @@ private func ensureThemeVisible(listNode: ListView, themeReference: Presentation } } if let resultNode = resultNode { - listNode.ensureItemNodeVisible(resultNode, animated: animated, overflow: 56.0) + listNode.ensureItemNodeVisible(resultNode, animated: animated, overflow: 57.0) + return true + } else { + return false } } @@ -466,21 +465,25 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode { } private func dequeueTransition() { - guard let _ = self.item, let transition = self.enqueuedTransitions.first else { + guard let item = self.item, let transition = self.enqueuedTransitions.first else { return } self.enqueuedTransitions.remove(at: 0) var options = ListViewDeleteAndInsertOptions() + if self.initialized { + options.insert(.AnimateInsertion) + } - self.listNode.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, updateSizeAndInsets: nil, updateOpaqueState: nil, completion: { [weak self] _ in - if let strongSelf = self, let item = strongSelf.item { - if !strongSelf.initialized { - strongSelf.initialized = true - ensureThemeVisible(listNode: strongSelf.listNode, themeReference: item.currentTheme, animated: false) - } + var scrollToItem: ListViewScrollToItem? + if !self.initialized { + if let index = item.themes.firstIndex(where: { $0.index == item.currentTheme.index }) { + scrollToItem = ListViewScrollToItem(index: index, position: .bottom(-57.0), animated: false, curve: .Default(duration: 0.0), directionHint: .Down) + self.initialized = true } - }) + } + + self.listNode.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, scrollToItem: scrollToItem, updateSizeAndInsets: nil, updateOpaqueState: nil, completion: { _ in }) } func asyncLayout() -> (_ item: ThemeSettingsThemeItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) { @@ -555,9 +558,9 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode { listInsets.top += params.leftInset + 4.0 listInsets.bottom += params.rightInset + 4.0 - strongSelf.listNode.bounds = CGRect(x: 0.0, y: 0.0, width: layoutSize.height, height: layoutSize.width) - strongSelf.listNode.position = CGPoint(x: layoutSize.width / 2.0, y: layoutSize.height / 2.0) - strongSelf.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous], scrollToItem: nil, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: CGSize(width: layoutSize.height, height: layoutSize.width), insets: listInsets, duration: 0.0, curve: .Default(duration: nil)), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in }) + strongSelf.listNode.bounds = CGRect(x: 0.0, y: 0.0, width: contentSize.height, height: contentSize.width) + strongSelf.listNode.position = CGPoint(x: contentSize.width / 2.0, y: contentSize.height / 2.0) + strongSelf.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous], scrollToItem: nil, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: CGSize(width: contentSize.height, height: contentSize.width), insets: listInsets, duration: 0.0, curve: .Default(duration: nil)), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in }) var entries: [ThemeSettingsThemeEntry] = [] var index: Int = 0 diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift index c2607874c9..a28dfc23cd 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift @@ -157,10 +157,8 @@ public class WallpaperGalleryController: ViewController { private var overlayNode: WallpaperGalleryOverlayNode? private var messageNodes: [ListViewItemNode]? private var toolbarNode: WallpaperGalleryToolbarNode? - private var colorPanelNode: WallpaperColorPanelNode? private var patternPanelNode: WallpaperPatternPanelNode? - private var colorPanelEnabled = false private var patternPanelEnabled = false public init(context: AccountContext, source: WallpaperListSource) { @@ -204,7 +202,6 @@ public class WallpaperGalleryController: ViewController { entries = [.contextResult(result)] centralEntryIndex = 0 case let .customColor(color): - self.colorPanelEnabled = true let initialColor = color ?? 0x000000 entries = [.wallpaper(.color(initialColor), nil)] centralEntryIndex = 0 @@ -338,19 +335,7 @@ public class WallpaperGalleryController: ViewController { self.overlayNode = overlayNode self.galleryNode.overlayNode = overlayNode self.galleryNode.addSubnode(overlayNode) - - let colorPanelNode = WallpaperColorPanelNode(theme: presentationData.theme, strings: presentationData.strings) - colorPanelNode.colorsChanged = { [weak self] color, _, ended in - if let strongSelf = self , let color = color { - strongSelf.updateEntries(color: color, preview: !ended) - } - } - if case let .customColor(colorValue) = self.source, let color = colorValue { - //colorPanelNode.color = UIColor(rgb: UInt32(bitPattern: color)) - } - self.colorPanelNode = colorPanelNode - overlayNode.addSubnode(colorPanelNode) - + let toolbarNode = WallpaperGalleryToolbarNode(theme: presentationData.theme, strings: presentationData.strings, doneButtonType: .set) self.toolbarNode = toolbarNode overlayNode.addSubnode(toolbarNode) @@ -632,12 +617,7 @@ public class WallpaperGalleryController: ViewController { topMessageText = presentationData.strings.WallpaperPreview_CustomColorTopText bottomMessageText = presentationData.strings.WallpaperPreview_CustomColorBottomText } - - if self.colorPanelEnabled { - topMessageText = presentationData.strings.WallpaperPreview_CustomColorTopText - bottomMessageText = presentationData.strings.WallpaperPreview_CustomColorBottomText - } - + let message1 = 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[otherPeerId], text: bottomMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []) items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, message: message1, theme: self.presentationData.theme, strings: self.presentationData.strings, wallpaper: currentWallpaper, fontSize: self.presentationData.fontSize, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil)) @@ -680,10 +660,6 @@ public class WallpaperGalleryController: ViewController { if let messageNodes = self.messageNodes { var bottomOffset: CGFloat = layout.size.height - bottomInset - 9.0 - if self.colorPanelEnabled { - } else { - bottomOffset -= 66.0 - } for itemNode in messageNodes { transition.updateFrame(node: itemNode, frame: CGRect(origin: CGPoint(x: 0.0, y: bottomOffset - itemNode.frame.height), size: itemNode.frame.size)) bottomOffset -= itemNode.frame.height @@ -707,16 +683,6 @@ public class WallpaperGalleryController: ViewController { var bottomInset = layout.intrinsicInsets.bottom + 49.0 let standardInputHeight = layout.deviceMetrics.keyboardHeight(inLandscape: false) let height = max(standardInputHeight, layout.inputHeight ?? 0.0) - bottomInset + 47.0 - if let colorPanelNode = self.colorPanelNode { - var colorPanelFrame = CGRect(x: 0.0, y: layout.size.height, width: layout.size.width, height: height) - if self.colorPanelEnabled { - colorPanelFrame.origin = CGPoint(x: 0.0, y: layout.size.height - bottomInset - height) - bottomInset += height - } - - transition.updateFrame(node: colorPanelNode, frame: colorPanelFrame) - colorPanelNode.updateLayout(size: colorPanelFrame.size, transition: transition) - } let currentPatternPanelNode: WallpaperPatternPanelNode if let patternPanelNode = self.patternPanelNode { @@ -739,6 +705,7 @@ public class WallpaperGalleryController: ViewController { patternPanelFrame.origin = CGPoint(x: 0.0, y: layout.size.height - bottomInset - panelHeight) bottomInset += panelHeight } + bottomInset += 66.0 transition.updateFrame(node: currentPatternPanelNode, frame: patternPanelFrame) currentPatternPanelNode.updateLayout(size: patternPanelFrame.size, transition: transition) diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift index 7abc84af85..0e7e024bb3 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift @@ -688,7 +688,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode { var additionalYOffset: CGFloat = 0.0 if self.patternButtonNode.isSelected { - additionalYOffset = -190.0 + additionalYOffset = -235.0 } let leftButtonFrame = CGRect(origin: CGPoint(x: floor(layout.size.width / 2.0 - buttonSize.width - 10.0) + offset.x, y: layout.size.height - 49.0 - layout.intrinsicInsets.bottom - 54.0 + offset.y + additionalYOffset), size: buttonSize) diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperPatternPanelNode.swift b/submodules/SettingsUI/Sources/Themes/WallpaperPatternPanelNode.swift index 9e8ff0bfc8..531ed2e4be 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperPatternPanelNode.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperPatternPanelNode.swift @@ -168,7 +168,11 @@ final class WallpaperPatternPanelNode: ASDisplayNode { } if let subnodes = strongSelf.scrollNode.subnodes { for case let subnode as SettingsThemeWallpaperNode in subnodes { - subnode.setSelected(node === subnode, animated: true) + let selected = node === subnode + subnode.setSelected(selected, animated: true) + if selected { + strongSelf.scrollToNode(subnode, animated: true) + } } } } @@ -206,7 +210,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode { } } - func didAppear(initialWallpaper: TelegramWallpaper? = nil) { + func didAppear(initialWallpaper: TelegramWallpaper? = nil, intensity: Int32? = nil) { var wallpaper = initialWallpaper ?? self.wallpapers.first if let wallpaper = wallpaper { @@ -216,23 +220,38 @@ final class WallpaperPatternPanelNode: ASDisplayNode { } self.currentWallpaper = wallpaper - self.sliderView?.value = 40.0 + self.sliderView?.value = CGFloat(intensity ?? 40) self.scrollNode.view.contentOffset = CGPoint() + var selectedNode: SettingsThemeWallpaperNode? if let subnodes = self.scrollNode.subnodes { for case let subnode as SettingsThemeWallpaperNode in subnodes { var selected = false if case let .file(file) = subnode.wallpaper, file.id == selectedFileId { selected = true + selectedNode = subnode } subnode.setSelected(selected, animated: false) } } - + if initialWallpaper == nil, let wallpaper = self.currentWallpaper, let sliderView = self.sliderView { self.patternChanged?(wallpaper, Int32(sliderView.value), false) } + + if let selectedNode = selectedNode { + self.scrollToNode(selectedNode) + } + } + } + + private func scrollToNode(_ node: SettingsThemeWallpaperNode, animated: Bool = false) { + let bounds = self.scrollNode.view.bounds + let frame = node.frame.insetBy(dx: -48.0, dy: 0.0) + + if frame.minX < bounds.minX || frame.maxX > bounds.maxX { + self.scrollNode.view.scrollRectToVisible(frame, animated: animated) } } diff --git a/submodules/TelegramPermissionsUI/Sources/PermissionController.swift b/submodules/TelegramPermissionsUI/Sources/PermissionController.swift index 6964197836..e43f4b9f96 100644 --- a/submodules/TelegramPermissionsUI/Sources/PermissionController.swift +++ b/submodules/TelegramPermissionsUI/Sources/PermissionController.swift @@ -15,6 +15,8 @@ public final class PermissionController: ViewController { private var state: PermissionControllerContent? private var splashScreen = false + private var locationManager: LocationManager? + private var controllerNode: PermissionControllerNode { return self.displayNode as! PermissionControllerNode } @@ -185,11 +187,15 @@ public final class PermissionController: ViewController { case let .nearbyLocation(status): self.title = self.presentationData.strings.Permissions_PeopleNearbyTitle_v0 + if self.locationManager == nil { + self.locationManager = LocationManager() + } + self.allow = { [weak self] in if let strongSelf = self { switch status { case .requestable: - DeviceAccess.authorizeAccess(to: .location(.tracking), presentationData: strongSelf.context.sharedContext.currentPresentationData.with { $0 }, { [weak self] result in + DeviceAccess.authorizeAccess(to: .location(.tracking), locationManager: strongSelf.locationManager, presentationData: strongSelf.context.sharedContext.currentPresentationData.with { $0 }, { [weak self] result in self?.proceed?(result) }) case .denied, .unreachable: diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift index 4a72514c1a..de169248f8 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift @@ -61,7 +61,6 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit ) list = list.withUpdated( itemAccentColor: accentColor, - itemDisclosureActions: list.itemDisclosureActions.withUpdated(accent: list.itemDisclosureActions.accent.withUpdated(fillColor: accentColor)), itemCheckColors: list.itemCheckColors.withUpdated(fillColor: accentColor, foregroundColor: secondaryBadgeTextColor), itemBarChart: list.itemBarChart.withUpdated(color1: accentColor) ) diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift index 7b11115f77..43201ff25d 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift @@ -36,8 +36,15 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme var inputBackgroundColor: UIColor? var buttonStrokeColor: UIColor? + var suggestedWallpaper: TelegramWallpaper? + var bubbleColors = bubbleColors if bubbleColors == nil, editing { + if let accentColor = accentColor { + let color = accentColor.withMultiplied(hue: 1.024, saturation: 0.573, brightness: 0.18) + suggestedWallpaper = .color(Int32(bitPattern: color.rgb)) + } + let accentColor = accentColor ?? defaultDarkTintedAccentColor let bottomColor = accentColor.withMultiplied(hue: 1.019, saturation: 0.731, brightness: 0.59) let topColor = bottomColor.withMultiplied(hue: 0.966, saturation: 0.61, brightness: 0.98) @@ -217,6 +224,8 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme } else { defaultWallpaper = .color(Int32(bitPattern: backgroundColors.0.rgb)) } + } else if let forcedWallpaper = suggestedWallpaper { + defaultWallpaper = forcedWallpaper } var outgoingBubbleFillColor: UIColor? diff --git a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift index 366dfa1ca5..47014f6095 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift @@ -21,9 +21,10 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ac var chat = theme.chat var actionSheet = theme.actionSheet - var bubbleColors = bubbleColors var outgoingAccent: UIColor? var suggestedWallpaper: TelegramWallpaper? + + var bubbleColors = bubbleColors if bubbleColors == nil, editing { if day { let accentColor = accentColor ?? defaultDayAccentColor diff --git a/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift b/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift index 5375b2543d..0e18340c01 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift @@ -39,9 +39,9 @@ extension TelegramWallpaper: Codable { case "builtin": self = .builtin(WallpaperSettings()) default: - let options = ["motion", "blur"] + let optionKeys = ["motion", "blur"] - if [6,7].contains(value.count), let color = UIColor(hexString: value) { + if value.count == 6, let color = UIColor(hexString: value) { self = .color(Int32(bitPattern: color.rgb)) } else { let components = value.components(separatedBy: " ") @@ -54,7 +54,15 @@ extension TelegramWallpaper: Codable { blur = true } - if components.count >= 2 && components.count <= 4 && [6,7].contains(components[0].count) && !options.contains(components[0]) && [6,7].contains(components[1].count) && !options.contains(components[1]), let topColor = UIColor(hexString: components[0]), let bottomColor = UIColor(hexString: components[1]) { + if components.count >= 2 && components.count <= 5 && components[0].count == 6 && !optionKeys.contains(components[0]) && components[1].count == 6 && !optionKeys.contains(components[1]), let topColor = UIColor(hexString: components[0]), let bottomColor = UIColor(hexString: components[1]) { + + var rotation: Int32? + if components.count > 2, components[2].count <= 3, let value = Int32(components[2]) { + if value >= 0 && value < 360 { + rotation = value + } + } + self = .gradient(Int32(bitPattern: topColor.rgb), Int32(bitPattern: bottomColor.rgb), WallpaperSettings(blur: blur, motion: motion)) } else { var slug: String? @@ -68,7 +76,7 @@ extension TelegramWallpaper: Codable { if components.count > 1 { for i in 1 ..< components.count { let component = components[i] - if options.contains(component) { + if optionKeys.contains(component) { continue } if component.count == 6, let value = UIColor(hexString: component) { @@ -110,6 +118,9 @@ extension TelegramWallpaper: Codable { var components: [String] = [] components.append(String(format: "%06x", topColor)) components.append(String(format: "%06x", bottomColor)) + if let rotation = settings.rotation { + components.append("\(rotation)") + } if settings.motion { components.append("motion") } @@ -130,6 +141,9 @@ extension TelegramWallpaper: Codable { if let bottomColor = file.settings.bottomColor { components.append(String(format: "%06x", bottomColor)) } + if let rotation = file.settings.rotation { + components.append("\(rotation)") + } } if file.settings.motion { components.append("motion") diff --git a/submodules/TelegramPresentationData/Sources/WallpaperUtils.swift b/submodules/TelegramPresentationData/Sources/WallpaperUtils.swift index b0918ec960..ae81d73b1a 100644 --- a/submodules/TelegramPresentationData/Sources/WallpaperUtils.swift +++ b/submodules/TelegramPresentationData/Sources/WallpaperUtils.swift @@ -22,7 +22,7 @@ public extension TelegramWallpaper { var isColorOrGradient: Bool { switch self { - case .color, .gradient: + case .color, .gradient: return true default: return false diff --git a/submodules/TelegramUI/TelegramUI/CreateChannelController.swift b/submodules/TelegramUI/TelegramUI/CreateChannelController.swift index 30493d6001..9cb387fbfb 100644 --- a/submodules/TelegramUI/TelegramUI/CreateChannelController.swift +++ b/submodules/TelegramUI/TelegramUI/CreateChannelController.swift @@ -139,9 +139,10 @@ private enum CreateChannelEntry: ItemListNodeEntry { let arguments = arguments as! CreateChannelArguments switch self { case let .channelInfo(theme, strings, dateTimeFormat, peer, state, avatar): - return ItemListAvatarAndNameInfoItem(accountContext: arguments.context, presentationData: presentationData, dateTimeFormat: dateTimeFormat, mode: .generic, peer: peer, presence: nil, cachedData: nil, state: state, sectionId: ItemListSectionId(self.section), style: .blocks(withTopInset: false, withExtendedBottomInset: false), editingNameUpdated: { editingName in + return ItemListAvatarAndNameInfoItem(accountContext: arguments.context, presentationData: presentationData, dateTimeFormat: dateTimeFormat, mode: .editSettings, peer: peer, presence: nil, cachedData: nil, state: state, sectionId: ItemListSectionId(self.section), style: .blocks(withTopInset: false, withExtendedBottomInset: false), editingNameUpdated: { editingName in arguments.updateEditingName(editingName) }, avatarTapped: { + arguments.changeProfilePhoto() }, updatingImage: avatar, tag: CreateChannelEntryTag.info) case let .setProfilePhoto(theme, text): return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: ItemListSectionId(self.section), style: .blocks, action: { @@ -188,7 +189,6 @@ private func CreateChannelEntries(presentationData: PresentationData, state: Cre let peer = TelegramGroup(id: PeerId(namespace: -1, id: 0), title: state.editingName.composedTitle, photo: [], participantCount: 0, role: .creator(rank: nil), membership: .Member, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0) entries.append(.channelInfo(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, groupInfoState, state.avatar)) - entries.append(.setProfilePhoto(presentationData.theme, presentationData.strings.Channel_UpdatePhotoItem)) entries.append(.descriptionSetup(presentationData.theme, presentationData.strings.Channel_Edit_AboutItem, state.editingDescriptionText)) entries.append(.descriptionInfo(presentationData.theme, presentationData.strings.Channel_About_Help)) diff --git a/submodules/TelegramUI/TelegramUI/CreateGroupController.swift b/submodules/TelegramUI/TelegramUI/CreateGroupController.swift index d18162efae..e78968ab6a 100644 --- a/submodules/TelegramUI/TelegramUI/CreateGroupController.swift +++ b/submodules/TelegramUI/TelegramUI/CreateGroupController.swift @@ -300,7 +300,6 @@ private func createGroupEntries(presentationData: PresentationData, state: Creat let peer = TelegramGroup(id: PeerId(namespace: -1, id: 0), title: state.editingName.composedTitle, photo: [], participantCount: 0, role: .creator(rank: nil), membership: .Member, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0) entries.append(.groupInfo(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, groupInfoState, state.avatar)) - //entries.append(.setProfilePhoto(presentationData.theme, presentationData.strings.GroupInfo_SetGroupPhoto)) var peers: [Peer] = [] for peerId in peerIds { diff --git a/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift b/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift index a051e0ee50..9c5191fe37 100644 --- a/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift +++ b/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift @@ -283,15 +283,24 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool { case let .map(mapMedia): params.dismissInput() - let controllerParams = LocationViewParams(sendLiveLocation: { location in - let outMessage: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: location), replyToMessageId: nil, localGroupingKey: nil) +// let controllerParams = LocationViewParams(sendLiveLocation: { location in +// let outMessage: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: location), replyToMessageId: nil, localGroupingKey: nil) +// params.enqueueMessage(outMessage) +// }, stopLiveLocation: { +// params.context.liveLocationManager?.cancelLiveLocation(peerId: params.message.id.peerId) +// }, openUrl: params.openUrl, openPeer: { peer in +// params.openPeer(peer, .info) +// }) +// let controller = LocationViewController(context: params.context, mapMedia: mapMedia, params: controllerParams) + let controller = legacyLocationController(message: params.message, mapMedia: mapMedia, context: params.context, openPeer: { peer in + params.openPeer(peer, .info) + }, sendLiveLocation: { coordinate, period in + let outMessage: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: TelegramMediaMap(latitude: coordinate.latitude, longitude: coordinate.longitude, geoPlace: nil, venue: nil, liveBroadcastingTimeout: period)), replyToMessageId: nil, localGroupingKey: nil) params.enqueueMessage(outMessage) }, stopLiveLocation: { params.context.liveLocationManager?.cancelLiveLocation(peerId: params.message.id.peerId) - }, openUrl: params.openUrl, openPeer: { peer in - params.openPeer(peer, .info) - }) - let controller = LocationViewController(context: params.context, mapMedia: mapMedia, params: controllerParams) + }, openUrl: params.openUrl) + controller.navigationPresentation = .modal params.navigationController?.pushViewController(controller) return true case let .stickerPack(reference): diff --git a/submodules/WallpaperResources/Sources/WallpaperResources.swift b/submodules/WallpaperResources/Sources/WallpaperResources.swift index ad593d4c3d..d84c5da42b 100644 --- a/submodules/WallpaperResources/Sources/WallpaperResources.swift +++ b/submodules/WallpaperResources/Sources/WallpaperResources.swift @@ -1233,7 +1233,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the c.translateBy(x: -drawingRect.width / 2.0, y: -drawingRect.height / 2.0) c.draw(outgoing!.cgImage!, in: CGRect(x: 9.0, y: 12.0, width: 57.0, height: 16.0)) } - + addCorners(context, arguments: arguments) return context } }