Bot preview improvements

This commit is contained in:
Isaac 2024-07-26 00:03:54 +08:00
parent df31800dcd
commit b67485c260
7 changed files with 68 additions and 19 deletions

View File

@ -552,7 +552,8 @@ public final class SparseItemGrid: ASDisplayNode {
}
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

View File

@ -1363,6 +1363,15 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
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: context,
parentController: parentController,

View File

@ -1629,6 +1629,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
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 listBottomInset: CGFloat?
private let ready = Promise<Bool>()
private var didSetReady: Bool = false
@ -2053,10 +2054,17 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
return SparseItemGrid.ShimmerColors(background: 0xffffff, foreground: 0xffffff)
}
let backgroundColor = presentationData.theme.list.mediaPlaceholderColor
let foregroundColor = presentationData.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.6)
return SparseItemGrid.ShimmerColors(background: backgroundColor.argb, foreground: foregroundColor.argb)
if case .botPreview = scope {
let backgroundColor = presentationData.theme.list.plainBackgroundColor
let foregroundColor = presentationData.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.6)
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
@ -3396,7 +3404,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
}
if case .botPreview = self.scope, self.canManageStories {
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 {
return
}
self.emptyAction?()
if self.canAddMoreBotPreviews() {
self.emptyAction?()
} else {
self.presentUnableToAddMorePreviewsAlert()
}
},
additionalActionTitle: isMainLanguage ? "Create a Translation" : nil,
additionalAction: { [weak self] in
@ -3680,7 +3692,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
environment: {},
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 botPreviewFooterView.superview == nil {
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)))
}
let defaultBottomInset = bottomInset
var listBottomInset = bottomInset
var bottomInset = bottomInset
if case .botPreview = self.scope, self.canManageStories {
updateBotPreviewLanguageTab(size: size, topInset: topInset, transition: transition)
gridTopInset += 50.0
updateBotPreviewFooter(size: size, bottomInset: defaultBottomInset, transition: transition)
updateBotPreviewFooter(size: size, bottomInset: 0.0, transition: transition)
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)
}
bottomInset = selectionPanelSize.height
listBottomInset += selectionPanelSize.height
} else if self.isProfileEmbedded, let selectedIds = self.itemInteraction.selectedIds, self.canManageStories, case .botPreview = self.scope {
let selectionPanel: ComponentView<Empty>
var selectionPanelTransition = ComponentTransition(transition)
@ -3932,6 +3945,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
selectionPanelTransition.setFrame(view: selectionPanelView, frame: selectionPanelFrame)
}
bottomInset = selectionPanelSize.height
listBottomInset += selectionPanelSize.height
} else if let selectionPanel = self.selectionPanel {
self.selectionPanel = nil
if let selectionPanelView = selectionPanel.view {
@ -4039,7 +4053,11 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
guard let self else {
return
}
self.emptyAction?()
if self.canAddMoreBotPreviews() {
self.emptyAction?()
} else {
self.presentUnableToAddMorePreviewsAlert()
}
},
additionalActionTitle: self.canManageStories ? (isMainLanguage ? "Create a Translation" : "Delete this Translation") : nil,
additionalAction: {
@ -4133,11 +4151,12 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
}
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 {
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() {
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 {
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() {
//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: [

View File

@ -11,6 +11,7 @@ import SearchUI
public class LanguageSelectionScreen: ViewController {
private let context: AccountContext
private let excludeIds: [String]
private let selectLocalization: (LocalizationInfo) -> Void
private var controllerNode: LanguageSelectionScreenNode {
@ -29,8 +30,9 @@ public class LanguageSelectionScreen: ViewController {
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.excludeIds = excludeIds
self.selectLocalization = selectLocalization
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
@ -92,7 +94,7 @@ public class LanguageSelectionScreen: ViewController {
}
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()
}, requestDeactivateSearch: { [weak self] in
self?.deactivateSearch()

View File

@ -294,6 +294,7 @@ final class LanguageSelectionScreenNode: ViewControllerTracingNode {
private let context: AccountContext
private var presentationData: PresentationData
private weak var navigationBar: NavigationBar?
private let excludeIds: [String]
private let requestActivateSearch: () -> Void
private let requestDeactivateSearch: () -> Void
private let present: (ViewController, Any?) -> Void
@ -316,11 +317,12 @@ final class LanguageSelectionScreenNode: ViewControllerTracingNode {
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.presentationData = presentationData
self.presentationDataValue.set(.single(presentationData))
self.navigationBar = navigationBar
self.excludeIds = excludeIds
self.requestActivateSearch = requestActivateSearch
self.requestDeactivateSearch = requestDeactivateSearch
self.present = present
@ -362,6 +364,12 @@ final class LanguageSelectionScreenNode: ViewControllerTracingNode {
var entries: [LanguageListEntry] = []
var existingIds = Set<String>()
var localizationListState = localizationListState
localizationListState.availableOfficialLocalizations = localizationListState.availableOfficialLocalizations.filter {
!strongSelf.excludeIds.contains($0.languageCode)
}
localizationListState.availableSavedLocalizations = []
if !localizationListState.availableOfficialLocalizations.isEmpty {
strongSelf.currentListState = localizationListState

View File

@ -976,6 +976,7 @@ open class SpaceWarpView4: UIView, SpaceWarpView {
meshView.frame = CGRect(origin: CGPoint(), size: size)
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 params = RippleParams(amplitude: 26.0, frequency: 15.0, decay: 8.0, speed: 1400.0)

View File

@ -6617,7 +6617,7 @@ public final class StoryItemSetContainerComponent: Component {
component.reorder()
})))
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
a(.default)