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/LocationPickerControllerNode.swift b/submodules/LocationUI/Sources/LocationPickerControllerNode.swift index 4e5b958bfc..7caa6e9527 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,6 +36,7 @@ private enum LocationPickerEntryId: Hashable { } private enum LocationPickerEntry: Comparable, Identifiable { + case city(PresentationTheme, String, String, TelegramMediaMap?, Int64?, String?, CLLocationCoordinate2D?, String?) case location(PresentationTheme, String, String, TelegramMediaMap?, Int64?, String?, CLLocationCoordinate2D?, String?) case liveLocation(PresentationTheme, String, String, CLLocationCoordinate2D?) case header(PresentationTheme, String) @@ -43,21 +45,29 @@ 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 .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): 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 { return true @@ -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,6 +147,20 @@ private enum LocationPickerEntry: Comparable, Identifiable { func item(engine: TelegramEngine, presentationData: PresentationData, interaction: LocationPickerInteraction?) -> ListViewItem { switch self { + 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): let icon: LocationActionListItemIcon if let venue = venue { @@ -227,7 +258,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 +267,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 +585,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)) case .selecting: let title: String switch strongSelf.mode { @@ -593,7 +626,12 @@ 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, coordinate, state.address)) + if source == .story { + entries.append(.city(presentationData.theme, state.city ?? presentationData.strings.Map_Locating, "City", nil, nil, nil, coordinate, state.city)) + entries.append(.location(presentationData.theme, state.street ?? presentationData.strings.Map_Locating, "Street", nil, nil, nil, coordinate, state.street)) + } 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)) + } } if case .share(_, _, true) = mode { @@ -739,18 +777,26 @@ 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)" + } + if let street = placemark?.street, let city = placemark?.city { + streetName = "\(street), \(city)" + } strongSelf.updateState { state in var state = state state.selectedLocation = .location(coordinate, address) - state.address = name + state.city = cityName + state.street = streetName return state } } })) } else { let coordinate = controller.initialLocation ?? userLocation?.coordinate - if case .none = state.selectedLocation, let coordinate, state.address == nil { + 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 { @@ -758,10 +804,18 @@ 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)" + } + if let street = placemark?.street, let city = placemark?.city { + streetName = "\(street), \(city)" + } strongSelf.updateState { state in var state = state - state.address = name + state.city = cityName + state.street = streetName return state } } 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/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift index 7da63c30e2..06fa7c66ba 100644 --- a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift +++ b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift @@ -2919,7 +2919,8 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate controller.presentLocationPicker = { [weak self, weak controller] in if let self { controller?.dismiss(animated: true) - self.presentLocationPicker() + let existingEntity = self.entitiesView.getView(where: { $0 is DrawingLocationEntityView })?.entity as? DrawingLocationEntity + self.presentLocationPicker(existingEntity) } } self.stickerScreen = controller diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index c41f20aa8b..7da31228f6 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -3554,6 +3554,7 @@ public final class StoryItemSetContainerComponent: Component { self.presentPrivacyTooltip(privacy: privacy) self.privacyController = nil + self.rewindCurrentItem() self.updateIsProgressPaused() }, editCategory: { [weak self] privacy, _, _ in