diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 8c36053a3b..a43e57a77b 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -9739,8 +9739,8 @@ Sorry for the inconvenience."; "Story.PrivacyTooltipSelectedContacts.Contacts_1" = "1 contact"; "Story.PrivacyTooltipSelectedContacts.Contacts_any" = "%@ contacts"; -"Story.Privacy.GrayListSelect" = "[Select people]() who will never see your stories."; -"Story.Privacy.GrayListSelected" = "[%@]() will never see your stories."; +"Story.Privacy.GrayListSelect" = "[Select people]() who will never see any of your stories."; +"Story.Privacy.GrayListSelected" = "[%@]() will never see any of your stories."; "Story.Privacy.GrayListPeople_1" = "1 person"; "Story.Privacy.GrayListPeople_any" = "%@ people"; diff --git a/submodules/DrawingUI/Sources/DrawingEntitiesView.swift b/submodules/DrawingUI/Sources/DrawingEntitiesView.swift index 2eca9aeac9..67a763fb8d 100644 --- a/submodules/DrawingUI/Sources/DrawingEntitiesView.swift +++ b/submodules/DrawingUI/Sources/DrawingEntitiesView.swift @@ -301,10 +301,16 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView { return CGSize(width: width, height: width) } - public func prepareNewEntity(_ entity: DrawingEntity, setup: Bool = true, relativeTo: DrawingEntity? = nil) { - let center = self.startPosition(relativeTo: relativeTo, onlyVertical: entity is DrawingTextEntity) + public func prepareNewEntity(_ entity: DrawingEntity, setup: Bool = true, relativeTo: DrawingEntity? = nil, scale: CGFloat? = nil, position: CGPoint? = nil) { + var center = self.startPosition(relativeTo: relativeTo, onlyVertical: entity is DrawingTextEntity) + if let position { + center = position + } let rotation = self.getEntityInitialRotation() - let zoomScale = 1.0 / (self.drawingView?.zoomScale ?? 1.0) + var zoomScale = 1.0 / (self.drawingView?.zoomScale ?? 1.0) + if let scale { + zoomScale = scale + } if let shape = entity as? DrawingSimpleShapeEntity { shape.position = center @@ -357,7 +363,7 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView { if setup { location.rotation = rotation location.referenceDrawingSize = self.size - location.width = floor(self.size.width * 0.9) + location.width = floor(self.size.width * 0.85) location.scale = zoomScale } } @@ -471,7 +477,7 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView { return newEntity } - func remove(uuid: UUID, animated: Bool = false, announce: Bool = true) { + public func remove(uuid: UUID, animated: Bool = false, announce: Bool = true) { if let view = self.getView(for: uuid) { if self.selectedEntityView === view { self.selectedEntityView = nil @@ -671,6 +677,12 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView { } } } + selectionView.longPressed = { [weak self, weak entityView] in + if let self, let entityView { + let entityViews = self.subviews.filter { $0 is DrawingEntityView } + self.requestedMenuForEntityView(entityView, entityViews.last === entityView) + } + } entityView.selectionView = selectionView self.selectionContainerView?.addSubview(selectionView) } @@ -1015,6 +1027,7 @@ public class DrawingEntitySelectionView: UIView { public var tapGestureRecognizer: UITapGestureRecognizer? var tapped: () -> Void = { } + var longPressed: () -> Void = { } override init(frame: CGRect) { super.init(frame: frame) diff --git a/submodules/DrawingUI/Sources/DrawingLocationEntity.swift b/submodules/DrawingUI/Sources/DrawingLocationEntity.swift index 45378521bf..5edc40be4b 100644 --- a/submodules/DrawingUI/Sources/DrawingLocationEntity.swift +++ b/submodules/DrawingUI/Sources/DrawingLocationEntity.swift @@ -20,11 +20,11 @@ private func generateIcon(style: DrawingLocationEntity.Style) -> UIImage? { let blue: UIColor if case .black = style { - green = UIColor(rgb: 0x39e69a) - blue = UIColor(rgb: 0x1c9ae0) + green = UIColor(rgb: 0x3EF588) + blue = UIColor(rgb: 0x4FAAFF) } else { - green = UIColor(rgb: 0x1eb67a) - blue = UIColor(rgb: 0x1d9ae2) + green = UIColor(rgb: 0x1EBD5E) + blue = UIColor(rgb: 0x1C92FF) } var locations: [CGFloat] = [0.0, 1.0] @@ -32,7 +32,7 @@ private func generateIcon(style: DrawingLocationEntity.Style) -> UIImage? { let colorSpace = CGColorSpaceCreateDeviceRGB() let gradient = CGGradient(colorsSpace: colorSpace, colors: colorsArray, locations: &locations)! - context.drawLinearGradient(gradient, start: CGPoint(x: size.width, y: 0.0), end: CGPoint(x: 0.0, y: 0.0), options: CGGradientDrawingOptions()) + context.drawLinearGradient(gradient, start: CGPoint(x: size.width, y: size.height), end: CGPoint(x: 0.0, y: 0.0), options: CGGradientDrawingOptions()) } else { context.setFillColor(UIColor.white.cgColor) context.fill(CGRect(origin: .zero, size: size)) @@ -46,6 +46,8 @@ public final class DrawingLocationEntityView: DrawingEntityView, UITextViewDeleg } let backgroundView: UIView + let blurredBackgroundView: BlurredBackgroundView + let textView: DrawingTextView let iconView: UIImageView @@ -53,6 +55,9 @@ public final class DrawingLocationEntityView: DrawingEntityView, UITextViewDeleg self.backgroundView = UIView() self.backgroundView.clipsToBounds = true + self.blurredBackgroundView = BlurredBackgroundView(color: UIColor(white: 0.0, alpha: 0.25), enableBlur: true) + self.blurredBackgroundView.clipsToBounds = true + self.textView = DrawingTextView(frame: .zero) self.textView.clipsToBounds = false @@ -70,6 +75,8 @@ public final class DrawingLocationEntityView: DrawingEntityView, UITextViewDeleg self.textView.keyboardAppearance = .dark self.textView.autocorrectionType = .default self.textView.spellCheckingType = .no + self.textView.textContainer.maximumNumberOfLines = 2 + self.textView.textContainer.lineBreakMode = .byTruncatingTail self.iconView = UIImageView() @@ -77,6 +84,7 @@ public final class DrawingLocationEntityView: DrawingEntityView, UITextViewDeleg self.textView.delegate = self self.addSubview(self.backgroundView) + self.addSubview(self.blurredBackgroundView) self.addSubview(self.textView) self.addSubview(self.iconView) @@ -92,7 +100,7 @@ public final class DrawingLocationEntityView: DrawingEntityView, UITextViewDeleg self.textView.setNeedsLayersUpdate() var result = self.textView.sizeThatFits(CGSize(width: self.locationEntity.width, height: .greatestFiniteMagnitude)) self.textSize = result - result.width = floorToScreenPixels(max(224.0, ceil(result.width) + 20.0) + result.height * 0.5) + result.width = floorToScreenPixels(max(224.0, ceil(result.width) + 20.0) + result.height * 0.55) result.height = ceil(result.height * 1.2); return result; } @@ -109,10 +117,12 @@ public final class DrawingLocationEntityView: DrawingEntityView, UITextViewDeleg public override func layoutSubviews() { super.layoutSubviews() - let iconSize = floor(self.bounds.height * 0.6) - self.iconView.frame = CGRect(origin: CGPoint(x: floor(iconSize * 0.2), y: floorToScreenPixels((self.bounds.height - iconSize) / 2.0)), size: CGSize(width: iconSize, height: iconSize)) + let iconSize = min(76.0, floor(self.bounds.height * 0.6)) + self.iconView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels(iconSize * 0.25), y: floorToScreenPixels((self.bounds.height - iconSize) / 2.0)), size: CGSize(width: iconSize, height: iconSize)) self.textView.frame = CGRect(origin: CGPoint(x: self.bounds.width - self.textSize.width, y: floorToScreenPixels((self.bounds.height - self.textSize.height) / 2.0)), size: self.textSize) self.backgroundView.frame = self.bounds + self.blurredBackgroundView.frame = self.bounds + self.blurredBackgroundView.update(size: self.bounds.size, transition: .immediate) } override func selectedTapAction() -> Bool { @@ -127,29 +137,27 @@ public final class DrawingLocationEntityView: DrawingEntityView, UITextViewDeleg case .black: updatedStyle = .transparent case .transparent: - updatedStyle = .white + updatedStyle = .blur case .blur: updatedStyle = .white } self.locationEntity.style = updatedStyle -// if let snapshotView = self.snapshotView(afterScreenUpdates: false) { -// self.addSubview(snapshotView) -// -// snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak snapshotView] _ in -// snapshotView?.removeFromSuperview() -// }) -// self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) -// } self.update() return true } private var displayFontSize: CGFloat { + var textFontSize: CGFloat = 0.07 + let textLength = self.locationEntity.title.count + if textLength > 10 { + textFontSize = max(0.01, 0.07 - CGFloat(textLength - 10) / 100.0) + } + let minFontSize = max(10.0, max(self.locationEntity.referenceDrawingSize.width, self.locationEntity.referenceDrawingSize.height) * 0.025) let maxFontSize = max(10.0, max(self.locationEntity.referenceDrawingSize.width, self.locationEntity.referenceDrawingSize.height) * 0.25) - let fontSize = minFontSize + (maxFontSize - minFontSize) * 0.07 + let fontSize = minFontSize + (maxFontSize - minFontSize) * textFontSize return fontSize } @@ -162,10 +170,11 @@ public final class DrawingLocationEntityView: DrawingEntityView, UITextViewDeleg let font = Font.with(size: fontSize, design: .camera, weight: .semibold) text.addAttribute(.font, value: font, range: range) + text.addAttribute(.kern, value: -1.5 as NSNumber, range: range) self.textView.font = font let paragraphStyle = NSMutableParagraphStyle() - paragraphStyle.alignment = .right + paragraphStyle.alignment = .left text.addAttribute(.paragraphStyle, value: paragraphStyle, range: range) let textColor: UIColor @@ -192,17 +201,25 @@ public final class DrawingLocationEntityView: DrawingEntityView, UITextViewDeleg case .white: self.textView.textColor = .black self.backgroundView.backgroundColor = .white + self.backgroundView.isHidden = false + self.blurredBackgroundView.isHidden = true case .black: self.textView.textColor = .white self.backgroundView.backgroundColor = .black + self.backgroundView.isHidden = false + self.blurredBackgroundView.isHidden = true case .transparent: self.textView.textColor = .white self.backgroundView.backgroundColor = UIColor(rgb: 0x000000, alpha: 0.2) + self.backgroundView.isHidden = false + self.blurredBackgroundView.isHidden = true case .blur: self.textView.textColor = .white - self.backgroundView.backgroundColor = UIColor(rgb: 0x000000, alpha: 0.2) + self.backgroundView.isHidden = true + self.backgroundView.backgroundColor = UIColor(rgb: 0xffffff) + self.blurredBackgroundView.isHidden = false } - self.textView.textAlignment = .right + self.textView.textAlignment = .left self.updateText() @@ -214,8 +231,10 @@ public final class DrawingLocationEntityView: DrawingEntityView, UITextViewDeleg } self.backgroundView.layer.cornerRadius = self.textSize.height * 0.18 + self.blurredBackgroundView.layer.cornerRadius = self.backgroundView.layer.cornerRadius if #available(iOS 13.0, *) { self.backgroundView.layer.cornerCurve = .continuous + self.blurredBackgroundView.layer.cornerCurve = .continuous } super.update(animated: animated) @@ -264,6 +283,8 @@ final class DrawingLocationEntititySelectionView: DrawingEntitySelectionView { private let leftHandle = SimpleShapeLayer() private let rightHandle = SimpleShapeLayer() + private var longPressGestureRecognizer: UILongPressGestureRecognizer? + override init(frame: CGRect) { let handleBounds = CGRect(origin: .zero, size: entitySelectionViewHandleSize) let handles = [ @@ -296,6 +317,10 @@ final class DrawingLocationEntititySelectionView: DrawingEntitySelectionView { entityView.onSnapUpdated(type, snapped) } } + + let longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.handleLongPress(_:))) + self.addGestureRecognizer(longPressGestureRecognizer) + self.longPressGestureRecognizer = longPressGestureRecognizer } required init?(coder: NSCoder) { @@ -318,6 +343,12 @@ final class DrawingLocationEntititySelectionView: DrawingEntitySelectionView { private let snapTool = DrawingEntitySnapTool() + @objc private func handleLongPress(_ gestureRecognizer: UILongPressGestureRecognizer) { + if case .began = gestureRecognizer.state { + self.longPressed() + } + } + private var currentHandle: CALayer? override func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) { guard let entityView = self.entityView, let entity = entityView.entity as? DrawingLocationEntity else { @@ -329,6 +360,9 @@ final class DrawingLocationEntititySelectionView: DrawingEntitySelectionView { self.tapGestureRecognizer?.isEnabled = false self.tapGestureRecognizer?.isEnabled = true + self.longPressGestureRecognizer?.isEnabled = false + self.longPressGestureRecognizer?.isEnabled = true + self.snapTool.maybeSkipFromStart(entityView: entityView, position: entity.position) if let sublayers = self.layer.sublayers { diff --git a/submodules/DrawingUI/Sources/DrawingScreen.swift b/submodules/DrawingUI/Sources/DrawingScreen.swift index 7c92b04869..b92e9a5907 100644 --- a/submodules/DrawingUI/Sources/DrawingScreen.swift +++ b/submodules/DrawingUI/Sources/DrawingScreen.swift @@ -2445,6 +2445,7 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController, U } }, onTextEditingEnded: { _ in }, + editEntity: { _ in }, getCurrentImage: { [weak controller] in return controller?.getCurrentImage() }, @@ -2961,6 +2962,7 @@ public final class DrawingToolsInteraction { private let onInteractionUpdated: (Bool) -> Void private let onTextEditingEnded: (Bool) -> Void + private let editEntity: (DrawingEntity) -> Void public let getCurrentImage: () -> UIImage? private let getControllerNode: () -> ASDisplayNode? @@ -2990,6 +2992,7 @@ public final class DrawingToolsInteraction { updateColor: @escaping (DrawingColor) -> Void, onInteractionUpdated: @escaping (Bool) -> Void, onTextEditingEnded: @escaping (Bool) -> Void, + editEntity: @escaping (DrawingEntity) -> Void, getCurrentImage: @escaping () -> UIImage?, getControllerNode: @escaping () -> ASDisplayNode?, present: @escaping (ViewController, PresentationContextType, Any?) -> Void, @@ -3006,6 +3009,7 @@ public final class DrawingToolsInteraction { self.updateColor = updateColor self.onInteractionUpdated = onInteractionUpdated self.onTextEditingEnded = onTextEditingEnded + self.editEntity = editEntity self.getCurrentImage = getCurrentImage self.getControllerNode = getControllerNode self.present = present @@ -3066,7 +3070,14 @@ public final class DrawingToolsInteraction { self.entitiesView.remove(uuid: entityView.entity.uuid, animated: true) } })) - if let entityView = entityView as? DrawingTextEntityView { + if let entityView = entityView as? DrawingLocationEntityView { + actions.append(ContextMenuAction(content: .text(title: presentationData.strings.Paint_Edit, accessibilityLabel: presentationData.strings.Paint_Edit), action: { [weak self, weak entityView] in + if let self, let entityView { + self.editEntity(entityView.entity) + self.entitiesView.selectEntity(entityView.entity) + } + })) + } else if let entityView = entityView as? DrawingTextEntityView { actions.append(ContextMenuAction(content: .text(title: presentationData.strings.Paint_Edit, accessibilityLabel: presentationData.strings.Paint_Edit), action: { [weak self, weak entityView] in if let self, let entityView { entityView.beginEditing(accessoryView: self.textEditAccessoryView) @@ -3117,11 +3128,8 @@ public final class DrawingToolsInteraction { self.isActive = false } - public func insertEntity(_ entity: DrawingEntity, scale: CGFloat? = nil) { - self.entitiesView.prepareNewEntity(entity) - if let scale { - entity.scale = scale - } + public func insertEntity(_ entity: DrawingEntity, scale: CGFloat? = nil, position: CGPoint? = nil) { + self.entitiesView.prepareNewEntity(entity, scale: scale, position: position) self.entitiesView.add(entity) self.entitiesView.selectEntity(entity, animate: !(entity is DrawingTextEntity)) diff --git a/submodules/Geocoding/Sources/Geocoding.swift b/submodules/Geocoding/Sources/Geocoding.swift index 909196c4a4..01f9f939f7 100644 --- a/submodules/Geocoding/Sources/Geocoding.swift +++ b/submodules/Geocoding/Sources/Geocoding.swift @@ -70,7 +70,8 @@ public struct ReverseGeocodedPlacemark { public func reverseGeocodeLocation(latitude: Double, longitude: Double) -> Signal { return Signal { subscriber in let geocoder = CLGeocoder() - geocoder.reverseGeocodeLocation(CLLocation(latitude: latitude, longitude: longitude), completionHandler: { placemarks, _ in + let locale = Locale(identifier: "en-US") + geocoder.reverseGeocodeLocation(CLLocation(latitude: latitude, longitude: longitude), preferredLocale: locale, completionHandler: { placemarks, _ in if let placemarks = placemarks, let placemark = placemarks.first { let result: ReverseGeocodedPlacemark if placemark.thoroughfare == nil && placemark.locality == nil && placemark.country == nil { diff --git a/submodules/LocationResources/Sources/VenueIconResources.swift b/submodules/LocationResources/Sources/VenueIconResources.swift index 16d1ed09c2..2577be7779 100644 --- a/submodules/LocationResources/Sources/VenueIconResources.swift +++ b/submodules/LocationResources/Sources/VenueIconResources.swift @@ -150,7 +150,7 @@ public func venueIcon(engine: TelegramEngine, type: String, background: Bool) -> let backgroundColor: UIColor let foregroundColor: UIColor - if type.isEmpty, let customArguments = arguments.custom as? VenueIconArguments { + if type.isEmpty || type == "building/default", let customArguments = arguments.custom as? VenueIconArguments { backgroundColor = customArguments.defaultBackgroundColor foregroundColor = customArguments.defaultForegroundColor } else { diff --git a/submodules/LocationUI/Sources/LocationActionListItem.swift b/submodules/LocationUI/Sources/LocationActionListItem.swift index 9ea4463ca8..a55ab08c8e 100644 --- a/submodules/LocationUI/Sources/LocationActionListItem.swift +++ b/submodules/LocationUI/Sources/LocationActionListItem.swift @@ -265,6 +265,7 @@ final class LocationActionListItemNode: ListViewItemNode { strongSelf.highlightedBackgroundNode.backgroundColor = item.presentationData.theme.list.itemHighlightedBackgroundColor } + var arguments: TransformImageCustomArguments? if let updatedIcon = updatedIcon { switch updatedIcon { case .location: @@ -279,6 +280,10 @@ final class LocationActionListItemNode: ListViewItemNode { strongSelf.iconNode.isHidden = true strongSelf.venueIconNode.isHidden = false strongSelf.venueIconNode.setSignal(venueIcon(engine: item.engine, type: venue.venue?.type ?? "", background: true)) + + if venue.venue?.id == "city" { + arguments = VenueIconArguments(defaultBackgroundColor: item.presentationData.theme.chat.inputPanel.actionControlFillColor, defaultForegroundColor: .white) + } } if updatedIcon == .stopLiveLocation { @@ -292,7 +297,7 @@ final class LocationActionListItemNode: ListViewItemNode { strongSelf.wavesNode?.color = item.presentationData.theme.chat.inputPanel.actionControlForegroundColor } - let iconApply = iconLayout(TransformImageArguments(corners: ImageCorners(), imageSize: CGSize(width: iconSize, height: iconSize), boundingSize: CGSize(width: iconSize, height: iconSize), intrinsicInsets: UIEdgeInsets())) + let iconApply = iconLayout(TransformImageArguments(corners: ImageCorners(), imageSize: CGSize(width: iconSize, height: iconSize), boundingSize: CGSize(width: iconSize, height: iconSize), intrinsicInsets: UIEdgeInsets(), custom: arguments)) iconApply() let titleNode = titleApply() diff --git a/submodules/LocationUI/Sources/LocationInfoListItem.swift b/submodules/LocationUI/Sources/LocationInfoListItem.swift index aea066e37b..915a36b7f0 100644 --- a/submodules/LocationUI/Sources/LocationInfoListItem.swift +++ b/submodules/LocationUI/Sources/LocationInfoListItem.swift @@ -342,7 +342,7 @@ final class LocationInfoListItemNode: ListViewItemNode { shapes.append(.roundedRectLine(startPoint: CGPoint(x: directionsWidth + directionsSpacing, y: 0.0), width: directionsWidth, diameter: 32.0)) shapes.append(.roundedRectLine(startPoint: CGPoint(x: directionsWidth + directionsSpacing + directionsWidth + directionsSpacing, y: 0.0), width: directionsWidth, diameter: 32.0)) - shimmerNode.update(backgroundColor: item.presentationData.theme.list.itemBlocksBackgroundColor, foregroundColor: item.presentationData.theme.list.mediaPlaceholderColor, shimmeringColor: item.presentationData.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4), shapes: shapes, size: shimmerNode.frame.size) + shimmerNode.update(backgroundColor: item.presentationData.theme.list.plainBackgroundColor, foregroundColor: item.presentationData.theme.list.mediaPlaceholderColor, shimmeringColor: item.presentationData.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4), shapes: shapes, size: shimmerNode.frame.size) } else if let shimmerNode = strongSelf.placeholderNode { strongSelf.placeholderNode = nil shimmerNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak shimmerNode] _ in diff --git a/submodules/LocationUI/Sources/LocationPickerControllerNode.swift b/submodules/LocationUI/Sources/LocationPickerControllerNode.swift index 7618bb426c..a68645f6a0 100644 --- a/submodules/LocationUI/Sources/LocationPickerControllerNode.swift +++ b/submodules/LocationUI/Sources/LocationPickerControllerNode.swift @@ -27,6 +27,7 @@ private struct LocationPickerTransaction { } private enum LocationPickerEntryId: Hashable { + case city case location case liveLocation case header @@ -35,7 +36,8 @@ private enum LocationPickerEntryId: Hashable { } private enum LocationPickerEntry: Comparable, Identifiable { - case location(PresentationTheme, String, String, TelegramMediaMap?, Int64?, String?, CLLocationCoordinate2D?, String?) + case city(PresentationTheme, String, String, TelegramMediaMap?, Int64?, String?, CLLocationCoordinate2D?, String?) + case location(PresentationTheme, String, String, TelegramMediaMap?, Int64?, String?, CLLocationCoordinate2D?, String?, Bool) case liveLocation(PresentationTheme, String, String, CLLocationCoordinate2D?) case header(PresentationTheme, String) case venue(PresentationTheme, TelegramMediaMap?, Int64?, String?, Int) @@ -43,23 +45,31 @@ private enum LocationPickerEntry: Comparable, Identifiable { var stableId: LocationPickerEntryId { switch self { - case .location: - return .location - case .liveLocation: - return .liveLocation - case .header: - return .header - case let .venue(_, venue, _, _, index): - return .venue(venue?.venue?.id ?? "\(index)") - case .attribution: - return .attribution + case .city: + return .city + case .location: + return .location + case .liveLocation: + return .liveLocation + case .header: + return .header + case let .venue(_, venue, _, _, index): + return .venue(venue?.venue?.id ?? "\(index)") + case .attribution: + return .attribution } } static func ==(lhs: LocationPickerEntry, rhs: LocationPickerEntry) -> Bool { switch lhs { - case let .location(lhsTheme, lhsTitle, lhsSubtitle, lhsVenue, lhsQueryId, lhsResultId, lhsCoordinate, lhsName): - if case let .location(rhsTheme, rhsTitle, rhsSubtitle, rhsVenue, rhsQueryId, rhsResultId, rhsCoordinate, rhsName) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle, lhsSubtitle == rhsSubtitle, lhsVenue?.venue?.id == rhsVenue?.venue?.id, lhsQueryId == rhsQueryId && lhsResultId == rhsResultId, lhsCoordinate == rhsCoordinate, lhsName == rhsName { + case let .city(lhsTheme, lhsTitle, lhsSubtitle, lhsVenue, lhsQueryId, lhsResultId, lhsCoordinate, lhsName): + if case let .city(rhsTheme, rhsTitle, rhsSubtitle, rhsVenue, rhsQueryId, rhsResultId, rhsCoordinate, rhsName) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle, lhsSubtitle == rhsSubtitle, lhsVenue?.venue?.id == rhsVenue?.venue?.id, lhsQueryId == rhsQueryId && lhsResultId == rhsResultId, lhsCoordinate == rhsCoordinate, lhsName == rhsName { + return true + } else { + return false + } + case let .location(lhsTheme, lhsTitle, lhsSubtitle, lhsVenue, lhsQueryId, lhsResultId, lhsCoordinate, lhsName, lhsIsTop): + if case let .location(rhsTheme, rhsTitle, rhsSubtitle, rhsVenue, rhsQueryId, rhsResultId, rhsCoordinate, rhsName, rhsIsTop) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle, lhsSubtitle == rhsSubtitle, lhsVenue?.venue?.id == rhsVenue?.venue?.id, lhsQueryId == rhsQueryId && lhsResultId == rhsResultId, lhsCoordinate == rhsCoordinate, lhsName == rhsName, lhsIsTop == rhsIsTop { return true } else { return false @@ -93,30 +103,37 @@ private enum LocationPickerEntry: Comparable, Identifiable { static func <(lhs: LocationPickerEntry, rhs: LocationPickerEntry) -> Bool { switch lhs { + case .city: + switch rhs { + case .city: + return false + case .location, .liveLocation, .header, .venue, .attribution: + return true + } case .location: switch rhs { - case .location: + case .city, .location: return false case .liveLocation, .header, .venue, .attribution: return true } case .liveLocation: switch rhs { - case .location, .liveLocation: + case .city, .location, .liveLocation: return false case .header, .venue, .attribution: return true } case .header: switch rhs { - case .location, .liveLocation, .header: + case .city, .location, .liveLocation, .header: return false case .venue, .attribution: return true } case let .venue(_, _, _, _, lhsIndex): switch rhs { - case .location, .liveLocation, .header: + case .city, .location, .liveLocation, .header: return false case let .venue(_, _, _, _, rhsIndex): return lhsIndex < rhsIndex @@ -130,7 +147,21 @@ private enum LocationPickerEntry: Comparable, Identifiable { func item(engine: TelegramEngine, presentationData: PresentationData, interaction: LocationPickerInteraction?) -> ListViewItem { switch self { - case let .location(_, title, subtitle, venue, queryId, resultId, coordinate, name): + case let .city(_, title, subtitle, _, _, _, coordinate, name): + let icon: LocationActionListItemIcon + if let name { + icon = .venue(TelegramMediaMap(latitude: 0, longitude: 0, heading: nil, accuracyRadius: nil, geoPlace: nil, venue: MapVenue(title: name, address: "City", provider: nil, id: "city", type: "building/default"), liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil)) + } else { + icon = .location + } + return LocationActionListItem(presentationData: ItemListPresentationData(presentationData), engine: engine, title: title, subtitle: subtitle, icon: icon, beginTimeAndTimeout: nil, action: { + if let coordinate = coordinate { + interaction?.sendLocation(coordinate, name) + } + }, highlighted: { highlighted in + interaction?.updateSendActionHighlight(highlighted) + }) + case let .location(_, title, subtitle, venue, queryId, resultId, coordinate, name, isTop): let icon: LocationActionListItemIcon if let venue = venue { icon = .venue(venue) @@ -144,7 +175,9 @@ private enum LocationPickerEntry: Comparable, Identifiable { interaction?.sendLocation(coordinate, name) } }, highlighted: { highlighted in - interaction?.updateSendActionHighlight(highlighted) + if isTop { + interaction?.updateSendActionHighlight(highlighted) + } }) case let .liveLocation(_, title, subtitle, coordinate): return LocationActionListItem(presentationData: ItemListPresentationData(presentationData), engine: engine, title: title, subtitle: subtitle, icon: .liveLocation, beginTimeAndTimeout: nil, action: { @@ -227,7 +260,8 @@ struct LocationPickerState { var mapMode: LocationMapMode var displayingMapModeOptions: Bool var selectedLocation: LocationPickerLocation - var address: String? + var city: String? + var street: String? var forceSelection: Bool var searchingVenuesAround: Bool @@ -235,7 +269,8 @@ struct LocationPickerState { self.mapMode = .map self.displayingMapModeOptions = false self.selectedLocation = .none - self.address = nil + self.city = nil + self.street = nil self.forceSelection = false self.searchingVenuesAround = false } @@ -552,7 +587,7 @@ final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationM case .pick: title = presentationData.strings.Map_SetThisLocation } - entries.append(.location(presentationData.theme, title, address ?? presentationData.strings.Map_Locating, nil, nil, nil, coordinate, state.address)) + entries.append(.location(presentationData.theme, title, address ?? presentationData.strings.Map_Locating, nil, nil, nil, coordinate, state.street, true)) case .selecting: let title: String switch strongSelf.mode { @@ -565,7 +600,7 @@ final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationM case .pick: title = presentationData.strings.Map_SetThisLocation } - entries.append(.location(presentationData.theme, title, presentationData.strings.Map_Locating, nil, nil, nil, nil, nil)) + entries.append(.location(presentationData.theme, title, presentationData.strings.Map_Locating, nil, nil, nil, nil, nil, true)) case let .venue(venue, queryId, resultId): let title: String switch strongSelf.mode { @@ -574,14 +609,16 @@ final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationM case .pick: title = presentationData.strings.Map_SetThisPlace } - entries.append(.location(presentationData.theme, title, venue.venue?.title ?? "", venue, queryId, resultId, venue.coordinate, nil)) + entries.append(.location(presentationData.theme, title, venue.venue?.title ?? "", venue, queryId, resultId, venue.coordinate, nil, true)) case .none: let title: String + var coordinate = userLocation?.coordinate switch strongSelf.mode { case .share: if source == .story { - if strongSelf.controller?.initialLocation != nil { + if let initialLocation = strongSelf.controller?.initialLocation { title = "Add This Location" + coordinate = initialLocation } else { title = "Add My Current Location" } @@ -591,7 +628,16 @@ final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationM case .pick: title = presentationData.strings.Map_SetThisLocation } - entries.append(.location(presentationData.theme, title, (userLocation?.horizontalAccuracy).flatMap { presentationData.strings.Map_AccurateTo(stringForDistance(strings: presentationData.strings, distance: $0)).string } ?? presentationData.strings.Map_Locating, nil, nil, nil, userLocation?.coordinate, state.address)) + if source == .story { + if state.city != "" { + entries.append(.city(presentationData.theme, state.city ?? presentationData.strings.Map_Locating, "City", nil, nil, nil, coordinate, state.city)) + } + if state.street != "" { + entries.append(.location(presentationData.theme, state.street ?? presentationData.strings.Map_Locating, "Street", nil, nil, nil, coordinate, state.street, false)) + } + } else { + entries.append(.location(presentationData.theme, title, (userLocation?.horizontalAccuracy).flatMap { presentationData.strings.Map_AccurateTo(stringForDistance(strings: presentationData.strings, distance: $0)).string } ?? presentationData.strings.Map_Locating, nil, nil, nil, coordinate, state.street, true)) + } } if case .share(_, _, true) = mode { @@ -737,28 +783,67 @@ final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationM if address.isEmpty { address = presentationData.strings.Map_Unknown } - let name = placemark?.city ?? "" + var cityName: String? + var streetName: String? + if let city = placemark?.city, let country = placemark?.country { + cityName = "\(city), \(country)" + } else { + cityName = "" + } + if let street = placemark?.street { + if let city = placemark?.city { + streetName = "\(street), \(city)" + } else { + streetName = street + } + } else { + streetName = "" + } + if streetName == "" && cityName == "" { + streetName = "Location" + } strongSelf.updateState { state in var state = state state.selectedLocation = .location(coordinate, address) - state.address = name + state.city = cityName + state.street = streetName return state } } })) } else { - if case .none = state.selectedLocation, let location = userLocation, state.address == nil { - strongSelf.geocodingDisposable.set((reverseGeocodeLocation(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude) + let coordinate = controller.initialLocation ?? userLocation?.coordinate + if case .none = state.selectedLocation, let coordinate, state.city == nil { + strongSelf.geocodingDisposable.set((reverseGeocodeLocation(latitude: coordinate.latitude, longitude: coordinate.longitude) |> deliverOnMainQueue).start(next: { [weak self] placemark in if let strongSelf = self { var address = placemark?.fullAddress ?? "" if address.isEmpty { address = presentationData.strings.Map_Unknown } - let name = placemark?.city ?? "" + var cityName: String? + var streetName: String? + if let city = placemark?.city, let country = placemark?.country { + cityName = "\(city), \(country)" + } else { + cityName = "" + } + if let street = placemark?.street { + if let city = placemark?.city { + streetName = "\(street), \(city)" + } else { + streetName = street + } + } else { + streetName = "" + } + if streetName == "" && cityName == "" { + streetName = "Location" + } strongSelf.updateState { state in var state = state - state.address = name + state.city = cityName + state.street = streetName return state } } diff --git a/submodules/LocationUI/Sources/LocationViewController.swift b/submodules/LocationUI/Sources/LocationViewController.swift index 130ee9ffcb..248efc4415 100644 --- a/submodules/LocationUI/Sources/LocationViewController.swift +++ b/submodules/LocationUI/Sources/LocationViewController.swift @@ -530,9 +530,17 @@ public final class LocationViewController: ViewController { self.controllerNode.showAll() } + private var didDismiss = false + public override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + if !self.didDismiss { + self.didDismiss = true + self.dismissed() + } + } + public override func dismiss(completion: (() -> Void)? = nil) { super.dismiss(completion: completion) - self.dismissed() } } diff --git a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift index cce72ea417..3e9f63bb56 100644 --- a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift @@ -395,7 +395,7 @@ enum PremiumPerk: CaseIterable { case .translation: return strings.Premium_Translation case .stories: - return "" + return "Upgraded Stories" } } @@ -430,7 +430,7 @@ enum PremiumPerk: CaseIterable { case .translation: return strings.Premium_TranslationInfo case .stories: - return "Be one of the first to share your stories with your contacts or an unlimited audience." + return "Priority order, stealth mode, permanent views history and more." } } @@ -465,7 +465,7 @@ enum PremiumPerk: CaseIterable { case .translation: return "Premium/Perk/Translation" case .stories: - return "Premium/Perk/Translation" + return "Premium/Perk/Stories" } } } @@ -473,6 +473,7 @@ enum PremiumPerk: CaseIterable { struct PremiumIntroConfiguration { static var defaultValue: PremiumIntroConfiguration { return PremiumIntroConfiguration(perks: [ + .stories, .doubleLimits, .moreUpload, .fasterDownload, diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift index 95a74a4c93..111af875ad 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift @@ -784,6 +784,8 @@ private func apiInputPrivacyRules(privacy: EngineStoryPrivacy, transaction: Tran if !privacyUsers.isEmpty { if case .contacts = privacy.base { privacyRules.append(.inputPrivacyValueDisallowUsers(users: privacyUsers)) + } else if case .everyone = privacy.base { + privacyRules.append(.inputPrivacyValueDisallowUsers(users: privacyUsers)) } else { privacyRules.append(.inputPrivacyValueAllowUsers(users: privacyUsers)) } diff --git a/submodules/TelegramUI/Components/MediaEditor/Sources/Drawing/DrawingLocationEntity.swift b/submodules/TelegramUI/Components/MediaEditor/Sources/Drawing/DrawingLocationEntity.swift index 2d22fdee12..7851d40e70 100644 --- a/submodules/TelegramUI/Components/MediaEditor/Sources/Drawing/DrawingLocationEntity.swift +++ b/submodules/TelegramUI/Components/MediaEditor/Sources/Drawing/DrawingLocationEntity.swift @@ -46,7 +46,11 @@ public final class DrawingLocationEntity: DrawingEntity, Codable { public var referenceDrawingSize: CGSize public var position: CGPoint public var width: CGFloat - public var scale: CGFloat + public var scale: CGFloat { + didSet { + self.scale = min(2.5, self.scale) + } + } public var rotation: CGFloat public var center: CGPoint { @@ -82,9 +86,6 @@ public final class DrawingLocationEntity: DrawingEntity, Codable { self.title = try container.decode(String.self, forKey: .title) self.style = try container.decode(Style.self, forKey: .style) - let locationData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .location) - self.location = TelegramMediaMap(decoder: PostboxDecoder(buffer: MemoryBuffer(data: locationData.data))) - if let locationData = try container.decodeIfPresent(Data.self, forKey: .location) { self.location = PostboxDecoder(buffer: MemoryBuffer(data: locationData)).decodeRootObject() as! TelegramMediaMap } else { diff --git a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift index 4e129a9d72..0a02fc1b5f 100644 --- a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift +++ b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift @@ -2045,6 +2045,13 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate }).start() } }, + editEntity: { [weak self] entity in + if let self { + if let location = entity as? DrawingLocationEntity { + self.presentLocationPicker(location) + } + } + }, getCurrentImage: { [weak self] in guard let self else { return nil @@ -2700,7 +2707,7 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate controller.push(galleryController) } - func presentLocationPicker() { + func presentLocationPicker(_ existingEntity: DrawingLocationEntity? = nil) { guard let controller = self.controller else { return } @@ -2716,15 +2723,21 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate } else { title = address ?? "Location" } + let position = existingEntity?.position + let scale = existingEntity?.scale ?? 1.0 + if let existingEntity { + self.entitiesView.remove(uuid: existingEntity.uuid, animated: true) + } self.interaction?.insertEntity( DrawingLocationEntity( title: title, - style: .white, + style: existingEntity?.style ?? .white, location: location, queryId: queryId, resultId: resultId ), - scale: 1.0 + scale: scale, + position: position ) } }) diff --git a/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/ContextResultPanelComponent.swift b/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/ContextResultPanelComponent.swift index 6a0facc439..2d96d9672c 100644 --- a/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/ContextResultPanelComponent.swift +++ b/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/ContextResultPanelComponent.swift @@ -186,10 +186,10 @@ final class ContextResultPanelComponent: Component { let visibleBounds = self.scrollView.bounds.insetBy(dx: 0.0, dy: -200.0) - var synchronousLoad = false - if let hint = transition.userData(PeerListItemComponent.TransitionHint.self) { - synchronousLoad = hint.synchronousLoad - } +// var synchronousLoad = false +// if let hint = transition.userData(PeerListItemComponent.TransitionHint.self) { +// synchronousLoad = hint.synchronousLoad +// } var validIds: [AnyHashable] = [] if let range = itemLayout.visibleItems(for: visibleBounds), case let .mentions(peers) = component.results { @@ -241,16 +241,16 @@ final class ContextResultPanelComponent: Component { containerSize: itemFrame.size ) if let itemView = visibleItem.view { - var animateIn = false +// var animateIn = false if itemView.superview == nil { - animateIn = true +// animateIn = true self.scrollView.addSubview(itemView) } itemTransition.setFrame(view: itemView, frame: itemFrame) - if animateIn, synchronousLoad { - itemView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) - } +// if animateIn { +// itemView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) +// } } } } @@ -274,8 +274,8 @@ final class ContextResultPanelComponent: Component { } func update(component: ContextResultPanelComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: Transition) -> CGSize { - //let itemUpdated = self.component?.results != component.results - + var transition = transition + let previousComponent = self.component self.component = component self.state = state @@ -306,6 +306,10 @@ final class ContextResultPanelComponent: Component { containerSize: CGSize(width: availableSize.width, height: 1000.0) ) + if previousComponent?.results != component.results { + transition = transition.withUserData(PeerListItemComponent.TransitionHint(synchronousLoad: true)) + } + let itemLayout = ItemLayout( containerSize: CGSize(width: availableSize.width, height: minimizedHeight), bottomInset: 0.0, diff --git a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift index 28763eab75..01136c8f93 100644 --- a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift +++ b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift @@ -942,7 +942,7 @@ final class ShareWithPeersScreenComponent: Component { let base: EngineStoryPrivacy.Base? switch categoryId { case .everyone: - base = nil + base = .everyone case .contacts: base = .contacts case .closeFriends: @@ -1740,7 +1740,7 @@ final class ShareWithPeersScreenComponent: Component { case .nobody: title = environment.strings.Story_Privacy_CategorySelectedContacts case .everyone: - title = "" + title = environment.strings.Story_Privacy_ExcludedPeople } case .search: title = "" @@ -2435,19 +2435,35 @@ public class ShareWithPeersScreen: ViewControllerComponentContainer { var categoryItems: [ShareWithPeersScreenComponent.CategoryItem] = [] var optionItems: [ShareWithPeersScreenComponent.OptionItem] = [] if case let .stories(editing) = stateContext.subject { - categoryItems.append(ShareWithPeersScreenComponent.CategoryItem( - id: .everyone, - title: presentationData.strings.Story_Privacy_CategoryEveryone, - icon: "Media Editor/Privacy/Everyone", - iconColor: .blue, - actionTitle: nil - )) - var peerNames = "" if let peers = stateContext.stateValue?.peers, !peers.isEmpty { peerNames = String(peers.map { $0.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) }.joined(separator: ", ")) } + var everyoneSubtitle = presentationData.strings.Story_Privacy_ExcludePeople + if initialPrivacy.base == .everyone, initialPrivacy.additionallyIncludePeers.count > 0 { + if initialPrivacy.additionallyIncludePeers.count == 1 { + if !peerNames.isEmpty { + everyoneSubtitle = presentationData.strings.Story_Privacy_ExcludePeopleExceptNames(peerNames).string + } else { + everyoneSubtitle = presentationData.strings.Story_Privacy_ExcludePeopleExcept(1) + } + } else { + if !peerNames.isEmpty { + everyoneSubtitle = presentationData.strings.Story_Privacy_ExcludePeopleExceptNames(peerNames).string + } else { + everyoneSubtitle = presentationData.strings.Story_Privacy_ExcludePeopleExcept(Int32(initialPrivacy.additionallyIncludePeers.count)) + } + } + } + categoryItems.append(ShareWithPeersScreenComponent.CategoryItem( + id: .everyone, + title: presentationData.strings.Story_Privacy_CategoryEveryone, + icon: "Media Editor/Privacy/Everyone", + iconColor: .blue, + actionTitle: everyoneSubtitle + )) + var contactsSubtitle = presentationData.strings.Story_Privacy_ExcludePeople if initialPrivacy.base == .contacts, initialPrivacy.additionallyIncludePeers.count > 0 { if initialPrivacy.additionallyIncludePeers.count == 1 { diff --git a/submodules/TelegramUI/Components/Stories/PeerListItemComponent/Sources/PeerListItemComponent.swift b/submodules/TelegramUI/Components/Stories/PeerListItemComponent/Sources/PeerListItemComponent.swift index 5fe7060678..2b726efb00 100644 --- a/submodules/TelegramUI/Components/Stories/PeerListItemComponent/Sources/PeerListItemComponent.swift +++ b/submodules/TelegramUI/Components/Stories/PeerListItemComponent/Sources/PeerListItemComponent.swift @@ -275,6 +275,8 @@ public final class PeerListItemComponent: Component { let themeUpdated = self.component?.theme !== component.theme + self.avatarButtonView.isUserInteractionEnabled = component.openStories != nil + var hasSelectionUpdated = false if let previousComponent = self.component { switch previousComponent.selectionState { diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index ee2c33815c..9d979c642a 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -775,8 +775,7 @@ public final class StoryItemSetContainerComponent: Component { @objc private func tapGesture(_ recognizer: UITapGestureRecognizer) { if case .ended = recognizer.state, let component = self.component, let itemLayout = self.itemLayout { - if let menuController = self.sendMessageContext.menuController { - menuController.dismiss(animated: true) + if let _ = self.sendMessageContext.menuController { return } if self.hasActiveDeactivateableInput() { @@ -823,7 +822,7 @@ public final class StoryItemSetContainerComponent: Component { let rotatedX = tx * cosTheta - ty * sinTheta let rotatedY = tx * sinTheta + ty * cosTheta - return abs(rotatedX) <= area.coordinates.width / 100.0 * referenceSize.width / 2.0 && abs(rotatedY) <= area.coordinates.height / 100.0 * referenceSize.height / 2.0 + return abs(rotatedX) <= area.coordinates.width / 100.0 * referenceSize.width / 2.0 * 1.1 && abs(rotatedY) <= area.coordinates.height / 100.0 * referenceSize.height / 2.0 * 1.1 } for area in component.slice.item.storyItem.mediaAreas { @@ -3619,6 +3618,7 @@ public final class StoryItemSetContainerComponent: Component { self.presentPrivacyTooltip(privacy: privacy) self.privacyController = nil + self.rewindCurrentItem() self.updateIsProgressPaused() }, editCategory: { [weak self] privacy, _, _ in diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift index fc983ca109..ddf0a11d78 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift @@ -67,7 +67,7 @@ final class StoryItemSetContainerSendMessage { weak var actionSheet: ViewController? weak var statusController: ViewController? weak var lookupController: UIViewController? - weak var menuController: UIViewController? + weak var menuController: ViewController? var isViewingAttachedStickers = false var currentTooltipUpdateTimer: Foundation.Timer? @@ -3113,16 +3113,18 @@ final class StoryItemSetContainerSendMessage { view?.updateModalTransitionFactor(1.0, transition: .animated(duration: 0.5, curve: .spring)) locationController.dismissed = { [weak view] in view?.updateModalTransitionFactor(0.0, transition: .animated(duration: 0.5, curve: .spring)) - view?.updateIsProgressPaused() + Queue.mainQueue().after(0.3, { + view?.updateIsProgressPaused() + }) } controller?.push(locationController) })) } let referenceSize = view.controlsContainerView.frame.size - let size = CGSize(width: 16.0, height: 16.0) - var frame = CGRect(x: mediaArea.coordinates.x / 100.0 * referenceSize.width - size.width / 2.0, y: (mediaArea.coordinates.y - mediaArea.coordinates.height * 0.5) / 100.0 * referenceSize.height - size.height / 2.0, width: size.width, height: size.height) - frame = frame.offsetBy(dx: 0.0, dy: view.controlsContainerView.frame.minY) + let size = CGSize(width: 16.0, height: mediaArea.coordinates.height / 100.0 * referenceSize.height * 1.1) + var frame = CGRect(x: mediaArea.coordinates.x / 100.0 * referenceSize.width - size.width / 2.0, y: mediaArea.coordinates.y / 100.0 * referenceSize.height - size.height / 2.0, width: size.width, height: size.height) + frame = view.controlsContainerView.convert(frame, to: nil) let node = controller.displayNode let menuController = ContextMenuController(actions: actions) @@ -3132,7 +3134,7 @@ final class StoryItemSetContainerSendMessage { in: .window(.root), with: ContextMenuControllerPresentationArguments(sourceNodeAndRect: { [weak node] in if let node { - return (node, frame, node, CGRect(origin: .zero, size: referenceSize)) + return (node, frame, node, CGRect(origin: .zero, size: referenceSize).insetBy(dx: 0.0, dy: 64.0)) } else { return nil } diff --git a/submodules/TranslateUI/Sources/LanguageSelectionController.swift b/submodules/TranslateUI/Sources/LanguageSelectionController.swift index 0f00678760..a9d2e4ea86 100644 --- a/submodules/TranslateUI/Sources/LanguageSelectionController.swift +++ b/submodules/TranslateUI/Sources/LanguageSelectionController.swift @@ -90,7 +90,7 @@ private struct LanguageSelectionControllerState: Equatable { var toLanguage: String } -public func languageSelectionController(context: AccountContext, fromLanguage: String, toLanguage: String, completion: @escaping (String, String) -> Void) -> ViewController { +public func languageSelectionController(context: AccountContext, forceTheme: PresentationTheme? = nil, fromLanguage: String, toLanguage: String, completion: @escaping (String, String) -> Void) -> ViewController { let statePromise = ValuePromise(LanguageSelectionControllerState(section: .translation, fromLanguage: fromLanguage, toLanguage: toLanguage), ignoreRepeated: true) let stateValue = Atomic(value: LanguageSelectionControllerState(section: .translation, fromLanguage: fromLanguage, toLanguage: toLanguage)) let updateState: ((LanguageSelectionControllerState) -> LanguageSelectionControllerState) -> Void = { f in @@ -149,6 +149,10 @@ public func languageSelectionController(context: AccountContext, fromLanguage: S let signal = combineLatest(queue: Queue.mainQueue(), context.sharedContext.presentationData, statePromise.get()) |> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in + var presentationData = presentationData + if let forceTheme { + presentationData = presentationData.withUpdated(theme: forceTheme) + } let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .sectionControl([presentationData.strings.Translate_Languages_Original, presentationData.strings.Translate_Languages_Translation], 1), leftNavigationButton: ItemListNavigationButton(content: .none, style: .regular, enabled: false, action: {}), rightNavigationButton: ItemListNavigationButton(content: .text(presentationData.strings.Common_Done), style: .bold, enabled: true, action: { completion(state.fromLanguage, state.toLanguage) dismissImpl?() diff --git a/submodules/TranslateUI/Sources/TranslateScreen.swift b/submodules/TranslateUI/Sources/TranslateScreen.swift index 68d096e956..66cd55f4be 100644 --- a/submodules/TranslateUI/Sources/TranslateScreen.swift +++ b/submodules/TranslateUI/Sources/TranslateScreen.swift @@ -1043,8 +1043,8 @@ public class TranslateScreen: ViewController { changeLanguageImpl = { [weak self] fromLang, toLang, completion in let pushController = self?.pushController let presentController = self?.presentController - let controller = languageSelectionController(context: context, fromLanguage: fromLang, toLanguage: toLang, completion: { fromLang, toLang in - let controller = TranslateScreen(context: context, text: text, canCopy: canCopy, fromLanguage: fromLang, toLanguage: toLang, isExpanded: true) + let controller = languageSelectionController(context: context, forceTheme: forceTheme, fromLanguage: fromLang, toLanguage: toLang, completion: { fromLang, toLang in + let controller = TranslateScreen(context: context, forceTheme: forceTheme, text: text, canCopy: canCopy, fromLanguage: fromLang, toLanguage: toLang, isExpanded: true) controller.pushController = pushController ?? { _ in } controller.presentController = presentController ?? { _ in } presentController?(controller)