mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Bot preview improvements
This commit is contained in:
parent
df31800dcd
commit
b67485c260
@ -552,7 +552,8 @@ public final class SparseItemGrid: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var contentBottomOffset: CGFloat {
|
var contentBottomOffset: CGFloat {
|
||||||
return -self.scrollView.contentOffset.y + self.scrollView.contentSize.height
|
let bottomInset = self.layout?.containerLayout.insets.bottom ?? 0.0
|
||||||
|
return -self.scrollView.contentOffset.y + self.scrollView.contentSize.height - bottomInset
|
||||||
}
|
}
|
||||||
|
|
||||||
let coveringOffsetUpdated: (Viewport, ContainedViewLayoutTransition) -> Void
|
let coveringOffsetUpdated: (Viewport, ContainedViewLayoutTransition) -> Void
|
||||||
|
@ -1363,6 +1363,15 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let navigationController = parentController.navigationController as? NavigationController, let minimizedContainer = navigationController.minimizedContainer {
|
||||||
|
for controller in minimizedContainer.controllers {
|
||||||
|
if let controller = controller as? AttachmentController, let mainController = controller.mainController as? WebAppController, mainController.botId == user.id && mainController.source == .generic {
|
||||||
|
navigationController.maximizeViewController(controller, animated: true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
context.sharedContext.openWebApp(
|
context.sharedContext.openWebApp(
|
||||||
context: context,
|
context: context,
|
||||||
parentController: parentController,
|
parentController: parentController,
|
||||||
|
@ -1629,6 +1629,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
public private(set) var isSelectionModeActive: Bool
|
public private(set) var isSelectionModeActive: Bool
|
||||||
|
|
||||||
private var currentParams: (size: CGSize, topInset: CGFloat, sideInset: CGFloat, bottomInset: CGFloat, deviceMetrics: DeviceMetrics, visibleHeight: CGFloat, isScrollingLockedAtTop: Bool, expandProgress: CGFloat, navigationHeight: CGFloat, presentationData: PresentationData)?
|
private var currentParams: (size: CGSize, topInset: CGFloat, sideInset: CGFloat, bottomInset: CGFloat, deviceMetrics: DeviceMetrics, visibleHeight: CGFloat, isScrollingLockedAtTop: Bool, expandProgress: CGFloat, navigationHeight: CGFloat, presentationData: PresentationData)?
|
||||||
|
private var listBottomInset: CGFloat?
|
||||||
|
|
||||||
private let ready = Promise<Bool>()
|
private let ready = Promise<Bool>()
|
||||||
private var didSetReady: Bool = false
|
private var didSetReady: Bool = false
|
||||||
@ -2053,10 +2054,17 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
return SparseItemGrid.ShimmerColors(background: 0xffffff, foreground: 0xffffff)
|
return SparseItemGrid.ShimmerColors(background: 0xffffff, foreground: 0xffffff)
|
||||||
}
|
}
|
||||||
|
|
||||||
let backgroundColor = presentationData.theme.list.mediaPlaceholderColor
|
if case .botPreview = scope {
|
||||||
let foregroundColor = presentationData.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.6)
|
let backgroundColor = presentationData.theme.list.plainBackgroundColor
|
||||||
|
let foregroundColor = presentationData.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.6)
|
||||||
return SparseItemGrid.ShimmerColors(background: backgroundColor.argb, foreground: foregroundColor.argb)
|
|
||||||
|
return SparseItemGrid.ShimmerColors(background: backgroundColor.argb, foreground: foregroundColor.argb)
|
||||||
|
} else {
|
||||||
|
let backgroundColor = presentationData.theme.list.mediaPlaceholderColor
|
||||||
|
let foregroundColor = presentationData.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.6)
|
||||||
|
|
||||||
|
return SparseItemGrid.ShimmerColors(background: backgroundColor.argb, foreground: foregroundColor.argb)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.itemGridBinding.updateShimmerLayersImpl = { [weak self] layer in
|
self.itemGridBinding.updateShimmerLayersImpl = { [weak self] layer in
|
||||||
@ -3396,7 +3404,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
}
|
}
|
||||||
if case .botPreview = self.scope, self.canManageStories {
|
if case .botPreview = self.scope, self.canManageStories {
|
||||||
self.updateBotPreviewLanguageTab(size: currentParams.size, topInset: currentParams.topInset, transition: transition)
|
self.updateBotPreviewLanguageTab(size: currentParams.size, topInset: currentParams.topInset, transition: transition)
|
||||||
self.updateBotPreviewFooter(size: currentParams.size, bottomInset: currentParams.bottomInset, transition: transition)
|
self.updateBotPreviewFooter(size: currentParams.size, bottomInset: 0.0, transition: transition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3664,7 +3672,11 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.emptyAction?()
|
if self.canAddMoreBotPreviews() {
|
||||||
|
self.emptyAction?()
|
||||||
|
} else {
|
||||||
|
self.presentUnableToAddMorePreviewsAlert()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
additionalActionTitle: isMainLanguage ? "Create a Translation" : nil,
|
additionalActionTitle: isMainLanguage ? "Create a Translation" : nil,
|
||||||
additionalAction: { [weak self] in
|
additionalAction: { [weak self] in
|
||||||
@ -3680,7 +3692,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
environment: {},
|
environment: {},
|
||||||
containerSize: CGSize(width: size.width, height: 1000.0)
|
containerSize: CGSize(width: size.width, height: 1000.0)
|
||||||
)
|
)
|
||||||
let botPreviewFooterFrame = CGRect(origin: CGPoint(x: floor((size.width - botPreviewFooterSize.width) * 0.5), y: self.itemGrid.contentBottomOffset - botPreviewFooterSize.height - bottomInset), size: botPreviewFooterSize)
|
let botPreviewFooterFrame = CGRect(origin: CGPoint(x: floor((size.width - botPreviewFooterSize.width) * 0.5), y: self.itemGrid.contentBottomOffset + 16.0), size: botPreviewFooterSize)
|
||||||
if let botPreviewFooterView = botPreviewFooter.view {
|
if let botPreviewFooterView = botPreviewFooter.view {
|
||||||
if botPreviewFooterView.superview == nil {
|
if botPreviewFooterView.superview == nil {
|
||||||
self.view.addSubview(botPreviewFooterView)
|
self.view.addSubview(botPreviewFooterView)
|
||||||
@ -3746,16 +3758,16 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
transition.updateFrame(layer: barBackgroundLayer, frame: CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: gridTopInset)))
|
transition.updateFrame(layer: barBackgroundLayer, frame: CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: gridTopInset)))
|
||||||
}
|
}
|
||||||
|
|
||||||
let defaultBottomInset = bottomInset
|
var listBottomInset = bottomInset
|
||||||
var bottomInset = bottomInset
|
var bottomInset = bottomInset
|
||||||
|
|
||||||
if case .botPreview = self.scope, self.canManageStories {
|
if case .botPreview = self.scope, self.canManageStories {
|
||||||
updateBotPreviewLanguageTab(size: size, topInset: topInset, transition: transition)
|
updateBotPreviewLanguageTab(size: size, topInset: topInset, transition: transition)
|
||||||
gridTopInset += 50.0
|
gridTopInset += 50.0
|
||||||
|
|
||||||
updateBotPreviewFooter(size: size, bottomInset: defaultBottomInset, transition: transition)
|
updateBotPreviewFooter(size: size, bottomInset: 0.0, transition: transition)
|
||||||
if let botPreviewFooterView = self.botPreviewFooter?.view {
|
if let botPreviewFooterView = self.botPreviewFooter?.view {
|
||||||
bottomInset += 18.0 + botPreviewFooterView.bounds.height
|
listBottomInset += 18.0 + botPreviewFooterView.bounds.height
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3886,6 +3898,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
selectionPanelTransition.setFrame(view: selectionPanelView, frame: selectionPanelFrame)
|
selectionPanelTransition.setFrame(view: selectionPanelView, frame: selectionPanelFrame)
|
||||||
}
|
}
|
||||||
bottomInset = selectionPanelSize.height
|
bottomInset = selectionPanelSize.height
|
||||||
|
listBottomInset += selectionPanelSize.height
|
||||||
} else if self.isProfileEmbedded, let selectedIds = self.itemInteraction.selectedIds, self.canManageStories, case .botPreview = self.scope {
|
} else if self.isProfileEmbedded, let selectedIds = self.itemInteraction.selectedIds, self.canManageStories, case .botPreview = self.scope {
|
||||||
let selectionPanel: ComponentView<Empty>
|
let selectionPanel: ComponentView<Empty>
|
||||||
var selectionPanelTransition = ComponentTransition(transition)
|
var selectionPanelTransition = ComponentTransition(transition)
|
||||||
@ -3932,6 +3945,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
selectionPanelTransition.setFrame(view: selectionPanelView, frame: selectionPanelFrame)
|
selectionPanelTransition.setFrame(view: selectionPanelView, frame: selectionPanelFrame)
|
||||||
}
|
}
|
||||||
bottomInset = selectionPanelSize.height
|
bottomInset = selectionPanelSize.height
|
||||||
|
listBottomInset += selectionPanelSize.height
|
||||||
} else if let selectionPanel = self.selectionPanel {
|
} else if let selectionPanel = self.selectionPanel {
|
||||||
self.selectionPanel = nil
|
self.selectionPanel = nil
|
||||||
if let selectionPanelView = selectionPanel.view {
|
if let selectionPanelView = selectionPanel.view {
|
||||||
@ -4039,7 +4053,11 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.emptyAction?()
|
if self.canAddMoreBotPreviews() {
|
||||||
|
self.emptyAction?()
|
||||||
|
} else {
|
||||||
|
self.presentUnableToAddMorePreviewsAlert()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
additionalActionTitle: self.canManageStories ? (isMainLanguage ? "Create a Translation" : "Delete this Translation") : nil,
|
additionalActionTitle: self.canManageStories ? (isMainLanguage ? "Create a Translation" : "Delete this Translation") : nil,
|
||||||
additionalAction: {
|
additionalAction: {
|
||||||
@ -4133,11 +4151,12 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.itemGrid.pinchEnabled = items.count > 2 && !self.isReordering
|
self.itemGrid.pinchEnabled = items.count > 2 && !self.isReordering
|
||||||
self.itemGrid.update(size: size, insets: UIEdgeInsets(top: gridTopInset, left: sideInset, bottom: bottomInset, right: sideInset), useSideInsets: !isList, scrollIndicatorInsets: UIEdgeInsets(top: 0.0, left: sideInset, bottom: bottomInset, right: sideInset), lockScrollingAtTop: isScrollingLockedAtTop, fixedItemHeight: fixedItemHeight, fixedItemAspect: fixedItemAspect, adjustForSmallCount: adjustForSmallCount, items: items, theme: self.itemGridBinding.chatPresentationData.theme.theme, synchronous: wasFirstTime ? .full : .none, transition: animateGridItems ? .spring(duration: 0.35) : .immediate)
|
self.itemGrid.update(size: size, insets: UIEdgeInsets(top: gridTopInset, left: sideInset, bottom: listBottomInset, right: sideInset), useSideInsets: !isList, scrollIndicatorInsets: UIEdgeInsets(top: 0.0, left: sideInset, bottom: bottomInset, right: sideInset), lockScrollingAtTop: isScrollingLockedAtTop, fixedItemHeight: fixedItemHeight, fixedItemAspect: fixedItemAspect, adjustForSmallCount: adjustForSmallCount, items: items, theme: self.itemGridBinding.chatPresentationData.theme.theme, synchronous: wasFirstTime ? .full : .none, transition: animateGridItems ? .spring(duration: 0.35) : .immediate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.listBottomInset = listBottomInset
|
||||||
if case .botPreview = self.scope, self.canManageStories {
|
if case .botPreview = self.scope, self.canManageStories {
|
||||||
updateBotPreviewFooter(size: size, bottomInset: defaultBottomInset, transition: transition)
|
updateBotPreviewFooter(size: size, bottomInset: 0.0, transition: transition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4238,7 +4257,8 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func presentAddBotPreviewLanguage() {
|
private func presentAddBotPreviewLanguage() {
|
||||||
self.parentController?.push(LanguageSelectionScreen(context: self.context, selectLocalization: { [weak self] info in
|
let excludeIds: [String] = self.currentBotPreviewLanguages.map(\.id)
|
||||||
|
self.parentController?.push(LanguageSelectionScreen(context: self.context, excludeIds: excludeIds, selectLocalization: { [weak self] info in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -4246,6 +4266,14 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func presentUnableToAddMorePreviewsAlert() {
|
||||||
|
//TODO:localize
|
||||||
|
self.parentController?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: "You can add at most \(self.maxBotPreviewCount) previews.", actions: [
|
||||||
|
TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {
|
||||||
|
})
|
||||||
|
], parseMarkdown: true), in: .window(.root))
|
||||||
|
}
|
||||||
|
|
||||||
public func presentDeleteBotPreviewLanguage() {
|
public func presentDeleteBotPreviewLanguage() {
|
||||||
//TODO:localize
|
//TODO:localize
|
||||||
self.parentController?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: "Delete Translation", text: "Are you sure you want to delete this translation?", actions: [
|
self.parentController?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: "Delete Translation", text: "Are you sure you want to delete this translation?", actions: [
|
||||||
|
@ -11,6 +11,7 @@ import SearchUI
|
|||||||
|
|
||||||
public class LanguageSelectionScreen: ViewController {
|
public class LanguageSelectionScreen: ViewController {
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
|
private let excludeIds: [String]
|
||||||
private let selectLocalization: (LocalizationInfo) -> Void
|
private let selectLocalization: (LocalizationInfo) -> Void
|
||||||
|
|
||||||
private var controllerNode: LanguageSelectionScreenNode {
|
private var controllerNode: LanguageSelectionScreenNode {
|
||||||
@ -29,8 +30,9 @@ public class LanguageSelectionScreen: ViewController {
|
|||||||
|
|
||||||
private var previousContentOffset: ListViewVisibleContentOffset?
|
private var previousContentOffset: ListViewVisibleContentOffset?
|
||||||
|
|
||||||
public init(context: AccountContext, selectLocalization: @escaping (LocalizationInfo) -> Void) {
|
public init(context: AccountContext, excludeIds: [String] = [], selectLocalization: @escaping (LocalizationInfo) -> Void) {
|
||||||
self.context = context
|
self.context = context
|
||||||
|
self.excludeIds = excludeIds
|
||||||
self.selectLocalization = selectLocalization
|
self.selectLocalization = selectLocalization
|
||||||
|
|
||||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
@ -92,7 +94,7 @@ public class LanguageSelectionScreen: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override public func loadDisplayNode() {
|
override public func loadDisplayNode() {
|
||||||
self.displayNode = LanguageSelectionScreenNode(context: self.context, presentationData: self.presentationData, navigationBar: self.navigationBar!, requestActivateSearch: { [weak self] in
|
self.displayNode = LanguageSelectionScreenNode(context: self.context, presentationData: self.presentationData, navigationBar: self.navigationBar!, excludeIds: self.excludeIds, requestActivateSearch: { [weak self] in
|
||||||
self?.activateSearch()
|
self?.activateSearch()
|
||||||
}, requestDeactivateSearch: { [weak self] in
|
}, requestDeactivateSearch: { [weak self] in
|
||||||
self?.deactivateSearch()
|
self?.deactivateSearch()
|
||||||
|
@ -294,6 +294,7 @@ final class LanguageSelectionScreenNode: ViewControllerTracingNode {
|
|||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
private var presentationData: PresentationData
|
private var presentationData: PresentationData
|
||||||
private weak var navigationBar: NavigationBar?
|
private weak var navigationBar: NavigationBar?
|
||||||
|
private let excludeIds: [String]
|
||||||
private let requestActivateSearch: () -> Void
|
private let requestActivateSearch: () -> Void
|
||||||
private let requestDeactivateSearch: () -> Void
|
private let requestDeactivateSearch: () -> Void
|
||||||
private let present: (ViewController, Any?) -> Void
|
private let present: (ViewController, Any?) -> Void
|
||||||
@ -316,11 +317,12 @@ final class LanguageSelectionScreenNode: ViewControllerTracingNode {
|
|||||||
|
|
||||||
private var currentListState: LocalizationListState?
|
private var currentListState: LocalizationListState?
|
||||||
|
|
||||||
init(context: AccountContext, presentationData: PresentationData, navigationBar: NavigationBar, requestActivateSearch: @escaping () -> Void, requestDeactivateSearch: @escaping () -> Void, present: @escaping (ViewController, Any?) -> Void, push: @escaping (ViewController) -> Void, selectLocalization: @escaping (LocalizationInfo) -> Void) {
|
init(context: AccountContext, presentationData: PresentationData, navigationBar: NavigationBar, excludeIds: [String], requestActivateSearch: @escaping () -> Void, requestDeactivateSearch: @escaping () -> Void, present: @escaping (ViewController, Any?) -> Void, push: @escaping (ViewController) -> Void, selectLocalization: @escaping (LocalizationInfo) -> Void) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.presentationData = presentationData
|
self.presentationData = presentationData
|
||||||
self.presentationDataValue.set(.single(presentationData))
|
self.presentationDataValue.set(.single(presentationData))
|
||||||
self.navigationBar = navigationBar
|
self.navigationBar = navigationBar
|
||||||
|
self.excludeIds = excludeIds
|
||||||
self.requestActivateSearch = requestActivateSearch
|
self.requestActivateSearch = requestActivateSearch
|
||||||
self.requestDeactivateSearch = requestDeactivateSearch
|
self.requestDeactivateSearch = requestDeactivateSearch
|
||||||
self.present = present
|
self.present = present
|
||||||
@ -362,6 +364,12 @@ final class LanguageSelectionScreenNode: ViewControllerTracingNode {
|
|||||||
var entries: [LanguageListEntry] = []
|
var entries: [LanguageListEntry] = []
|
||||||
var existingIds = Set<String>()
|
var existingIds = Set<String>()
|
||||||
|
|
||||||
|
var localizationListState = localizationListState
|
||||||
|
localizationListState.availableOfficialLocalizations = localizationListState.availableOfficialLocalizations.filter {
|
||||||
|
!strongSelf.excludeIds.contains($0.languageCode)
|
||||||
|
}
|
||||||
|
localizationListState.availableSavedLocalizations = []
|
||||||
|
|
||||||
if !localizationListState.availableOfficialLocalizations.isEmpty {
|
if !localizationListState.availableOfficialLocalizations.isEmpty {
|
||||||
strongSelf.currentListState = localizationListState
|
strongSelf.currentListState = localizationListState
|
||||||
|
|
||||||
|
@ -976,6 +976,7 @@ open class SpaceWarpView4: UIView, SpaceWarpView {
|
|||||||
meshView.frame = CGRect(origin: CGPoint(), size: size)
|
meshView.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
|
||||||
let pixelStep = CGPoint()
|
let pixelStep = CGPoint()
|
||||||
|
//let pixelStep = CGPoint(x: CGFloat(resolution.x) * 0.33, y: CGFloat(resolution.y) * 0.33)
|
||||||
let itemSize = CGSize(width: size.width / CGFloat(resolution.x), height: size.height / CGFloat(resolution.y))
|
let itemSize = CGSize(width: size.width / CGFloat(resolution.x), height: size.height / CGFloat(resolution.y))
|
||||||
|
|
||||||
let params = RippleParams(amplitude: 26.0, frequency: 15.0, decay: 8.0, speed: 1400.0)
|
let params = RippleParams(amplitude: 26.0, frequency: 15.0, decay: 8.0, speed: 1400.0)
|
||||||
|
@ -6617,7 +6617,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
component.reorder()
|
component.reorder()
|
||||||
})))
|
})))
|
||||||
items.append(.action(ContextMenuActionItem(text: "Delete", textColor: .destructive, icon: { theme in
|
items.append(.action(ContextMenuActionItem(text: "Delete", textColor: .destructive, icon: { theme in
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Edit"), color: theme.contextMenu.destructiveColor)
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor)
|
||||||
}, action: { [weak self] _, a in
|
}, action: { [weak self] _, a in
|
||||||
a(.default)
|
a(.default)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user