Various improvements

This commit is contained in:
Ilya Laktyushin 2023-10-09 22:00:39 +04:00
parent 56aff0306e
commit d6f9cfcc84
7 changed files with 79 additions and 21 deletions

View File

@ -580,8 +580,8 @@ open class ItemListController: ViewController, KeyShortcutResponder, Presentable
}
}
public func ensureItemNodeVisible(_ itemNode: ListViewItemNode, animated: Bool = true, curve: ListViewAnimationCurve = .Default(duration: 0.25)) {
(self.displayNode as! ItemListControllerNode).listNode.ensureItemNodeVisible(itemNode, animated: animated, curve: curve)
public func ensureItemNodeVisible(_ itemNode: ListViewItemNode, animated: Bool = true, overflow: CGFloat = 0.0, atTop: Bool = false, curve: ListViewAnimationCurve = .Default(duration: 0.25)) {
(self.displayNode as! ItemListControllerNode).listNode.ensureItemNodeVisible(itemNode, animated: animated, overflow: overflow, atTop: atTop, curve: curve)
}
public func afterLayout(_ f: @escaping () -> Void) {

View File

@ -389,7 +389,7 @@ open class ItemListControllerNode: ASDisplayNode {
}
case .unknown, .none:
if let headerItemNode = strongSelf.headerItemNode {
headerItemNode.updateContentOffset(0.0, transition: .immediate)
headerItemNode.updateContentOffset(1000.0, transition: .immediate)
strongSelf.navigationBar.updateBackgroundAlpha(0.0, transition: .immediate)
} else {
strongSelf.navigationBar.updateBackgroundAlpha(1.0, transition: .immediate)

View File

@ -27,14 +27,16 @@ private final class CreateGiveawayControllerArguments {
let openPeersSelection: () -> Void
let openChannelsSelection: () -> Void
let openPremiumIntro: () -> Void
let scrollToDate: () -> Void
init(context: AccountContext, updateState: @escaping ((CreateGiveawayControllerState) -> CreateGiveawayControllerState) -> Void, dismissInput: @escaping () -> Void, openPeersSelection: @escaping () -> Void, openChannelsSelection: @escaping () -> Void, openPremiumIntro: @escaping () -> Void) {
init(context: AccountContext, updateState: @escaping ((CreateGiveawayControllerState) -> CreateGiveawayControllerState) -> Void, dismissInput: @escaping () -> Void, openPeersSelection: @escaping () -> Void, openChannelsSelection: @escaping () -> Void, openPremiumIntro: @escaping () -> Void, scrollToDate: @escaping () -> Void) {
self.context = context
self.updateState = updateState
self.dismissInput = dismissInput
self.openPeersSelection = openPeersSelection
self.openChannelsSelection = openChannelsSelection
self.openPremiumIntro = openPremiumIntro
self.scrollToDate = scrollToDate
}
}
@ -49,7 +51,7 @@ private enum CreateGiveawaySection: Int32 {
}
private enum CreateGiveawayEntryTag: ItemListItemTag {
case usage
case date
func isEqual(to other: ItemListItemTag) -> Bool {
if let other = other as? CreateGiveawayEntryTag, self == other {
@ -409,11 +411,20 @@ private enum CreateGiveawayEntry: ItemListNodeEntry {
}
return ItemListDisclosureItem(presentationData: presentationData, title: "Ends", label: text, labelStyle: active ? .coloredText(theme.list.itemAccentColor) : .text, sectionId: self.section, style: .blocks, disclosureStyle: .none, action: {
arguments.dismissInput()
var focus = false
arguments.updateState { state in
var updatedState = state
updatedState.pickingTimeLimit = !state.pickingTimeLimit
if updatedState.pickingTimeLimit {
focus = true
}
return updatedState
}
if focus {
Queue.mainQueue().after(0.1) {
arguments.scrollToDate()
}
}
})
case let .timeCustomPicker(_, dateTimeFormat, date):
return ItemListDatePickerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, date: date, sectionId: self.section, style: .blocks, updated: { date in
@ -422,7 +433,7 @@ private enum CreateGiveawayEntry: ItemListNodeEntry {
updatedState.time = date
return updatedState
})
})
}, tag: CreateGiveawayEntryTag.date)
case let .timeInfo(_, text):
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
case let .durationHeader(_, text):
@ -626,6 +637,7 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio
var openPremiumIntroImpl: (() -> Void)?
var presentControllerImpl: ((ViewController) -> Void)?
var pushControllerImpl: ((ViewController) -> Void)?
var scrollToDateImpl: (() -> Void)?
var dismissImpl: (() -> Void)?
var dismissInputImpl: (() -> Void)?
@ -639,6 +651,8 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio
openChannelsSelectionImpl?()
}, openPremiumIntro: {
openPremiumIntroImpl?()
}, scrollToDate: {
scrollToDateImpl?()
})
let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData
@ -867,9 +881,6 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio
}
})
} else {
let alertController = textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Premium_Purchase_ErrorUnknown, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})])
presentControllerImpl?(alertController)
updateState { state in
var updatedState = state
updatedState.updating = false
@ -903,6 +914,15 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio
}
}
)
controller.dismissed = {
updateState { state in
var updatedState = state
if updatedState.peers.isEmpty {
updatedState.mode = .giveaway
}
return updatedState
}
}
pushControllerImpl?(controller)
})
}
@ -937,5 +957,27 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio
pushControllerImpl?(controller)
}
scrollToDateImpl = { [weak controller] in
controller?.afterLayout({
guard let controller = controller else {
return
}
var resultItemNode: ListViewItemNode?
let _ = controller.frameForItemNode({ listItemNode in
if let itemNode = listItemNode as? ItemListItemNode {
if let tag = itemNode.tag as? CreateGiveawayEntryTag, tag == .date {
resultItemNode = listItemNode
return true
}
}
return false
})
if let resultItemNode = resultItemNode {
controller.ensureItemNodeVisible(resultItemNode, overflow: 120.0, atTop: true)
}
})
}
return controller
}

View File

@ -260,7 +260,7 @@ class GiftOptionItemNode: ItemListRevealOptionsItemNode {
let titleAttributedString = NSAttributedString(string: item.title, font: titleFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor)
let statusAttributedString = NSAttributedString(string: item.subtitle ?? "", font: statusFont, textColor: item.subtitleActive ? item.presentationData.theme.list.itemAccentColor : item.presentationData.theme.list.itemSecondaryTextColor)
let badgeAttributedString = NSAttributedString(string: item.badge ?? "", font: Font.with(size: 14.0, design: .round, weight: .semibold), textColor: item.presentationData.theme.list.itemCheckColors.foregroundColor)
let badgeAttributedString = NSAttributedString(string: item.badge ?? "", font: Font.with(size: 13.0, design: .round, weight: .semibold), textColor: item.presentationData.theme.list.itemCheckColors.foregroundColor)
let labelColor: UIColor
let labelFont: UIFont
@ -450,7 +450,7 @@ class GiftOptionItemNode: ItemListRevealOptionsItemNode {
var badgeOffset: CGFloat = 0.0
if badgeLayout.size.width > 0.0 {
let badgeFrame = CGRect(origin: CGPoint(x: leftInset + editingOffset + avatarInset + 2.0, y: strongSelf.titleNode.frame.maxY + titleSpacing), size: badgeLayout.size)
let badgeBackgroundFrame = badgeFrame.insetBy(dx: -2.0, dy: -2.0)
let badgeBackgroundFrame = badgeFrame.insetBy(dx: -3.0, dy: -2.0)
let badgeBackgroundNode: ASImageNode
if let current = strongSelf.badgeBackgroundNode {
@ -491,7 +491,7 @@ class GiftOptionItemNode: ItemListRevealOptionsItemNode {
strongSelf.containerNode.addSubnode(iconNode)
strongSelf.labelBackgroundNode = backgroundNode
strongSelf.labelIconNode = backgroundNode
strongSelf.labelIconNode = iconNode
}
if let icon = iconNode.image {

View File

@ -22,6 +22,7 @@ public struct UserLimitsConfiguration: Equatable {
public let maxStoriesWeeklyCount: Int32
public let maxStoriesMonthlyCount: Int32
public let maxStoriesSuggestedReactions: Int32
public let maxGiveawayChannelsCount: Int32
public static var defaultValue: UserLimitsConfiguration {
return UserLimitsConfiguration(
@ -44,7 +45,8 @@ public struct UserLimitsConfiguration: Equatable {
maxExpiringStoriesCount: 3,
maxStoriesWeeklyCount: 7,
maxStoriesMonthlyCount: 30,
maxStoriesSuggestedReactions: 1
maxStoriesSuggestedReactions: 1,
maxGiveawayChannelsCount: 10
)
}
@ -68,7 +70,8 @@ public struct UserLimitsConfiguration: Equatable {
maxExpiringStoriesCount: Int32,
maxStoriesWeeklyCount: Int32,
maxStoriesMonthlyCount: Int32,
maxStoriesSuggestedReactions: Int32
maxStoriesSuggestedReactions: Int32,
maxGiveawayChannelsCount: Int32
) {
self.maxPinnedChatCount = maxPinnedChatCount
self.maxArchivedPinnedChatCount = maxArchivedPinnedChatCount
@ -90,6 +93,7 @@ public struct UserLimitsConfiguration: Equatable {
self.maxStoriesWeeklyCount = maxStoriesWeeklyCount
self.maxStoriesMonthlyCount = maxStoriesMonthlyCount
self.maxStoriesSuggestedReactions = maxStoriesSuggestedReactions
self.maxGiveawayChannelsCount = maxGiveawayChannelsCount
}
}
@ -134,5 +138,6 @@ extension UserLimitsConfiguration {
self.maxStoriesWeeklyCount = getValue("stories_sent_weekly_limit", orElse: defaultValue.maxStoriesWeeklyCount)
self.maxStoriesMonthlyCount = getValue("stories_sent_monthly_limit", orElse: defaultValue.maxStoriesMonthlyCount)
self.maxStoriesSuggestedReactions = getValue("stories_suggested_reactions_limit", orElse: defaultValue.maxStoriesMonthlyCount)
self.maxGiveawayChannelsCount = getGeneralValue("giveaway_add_peers_max", orElse: defaultValue.maxGiveawayChannelsCount)
}
}

View File

@ -56,6 +56,7 @@ public enum EngineConfiguration {
public let maxStoriesWeeklyCount: Int32
public let maxStoriesMonthlyCount: Int32
public let maxStoriesSuggestedReactions: Int32
public let maxGiveawayChannelsCount: Int32
public static var defaultValue: UserLimits {
return UserLimits(UserLimitsConfiguration.defaultValue)
@ -81,7 +82,8 @@ public enum EngineConfiguration {
maxExpiringStoriesCount: Int32,
maxStoriesWeeklyCount: Int32,
maxStoriesMonthlyCount: Int32,
maxStoriesSuggestedReactions: Int32
maxStoriesSuggestedReactions: Int32,
maxGiveawayChannelsCount: Int32
) {
self.maxPinnedChatCount = maxPinnedChatCount
self.maxArchivedPinnedChatCount = maxArchivedPinnedChatCount
@ -103,6 +105,7 @@ public enum EngineConfiguration {
self.maxStoriesWeeklyCount = maxStoriesWeeklyCount
self.maxStoriesMonthlyCount = maxStoriesMonthlyCount
self.maxStoriesSuggestedReactions = maxStoriesSuggestedReactions
self.maxGiveawayChannelsCount = maxGiveawayChannelsCount
}
}
}
@ -159,7 +162,8 @@ public extension EngineConfiguration.UserLimits {
maxExpiringStoriesCount: userLimitsConfiguration.maxExpiringStoriesCount,
maxStoriesWeeklyCount: userLimitsConfiguration.maxStoriesWeeklyCount,
maxStoriesMonthlyCount: userLimitsConfiguration.maxStoriesMonthlyCount,
maxStoriesSuggestedReactions: userLimitsConfiguration.maxStoriesSuggestedReactions
maxStoriesSuggestedReactions: userLimitsConfiguration.maxStoriesSuggestedReactions,
maxGiveawayChannelsCount: userLimitsConfiguration.maxGiveawayChannelsCount
)
}
}

View File

@ -1452,8 +1452,9 @@ final class ShareWithPeersScreenComponent: Component {
}
}
let index = self.selectedPeers.firstIndex(of: peer.id)
let togglePeer = {
if let index = self.selectedPeers.firstIndex(of: peer.id) {
if let index {
self.selectedPeers.remove(at: index)
self.updateSelectedGroupPeers()
} else {
@ -1462,11 +1463,12 @@ final class ShareWithPeersScreenComponent: Component {
update()
}
if peer.id.isGroupOrChannel {
if case .channels = component.stateContext.subject, self.selectedPeers.count >= 10 {
if case .channels = component.stateContext.subject, self.selectedPeers.count >= component.context.userLimits.maxGiveawayChannelsCount, index == nil {
self.hapticFeedback.error()
return
}
if case .channels = component.stateContext.subject {
if case let .channel(channel) = peer, channel.addressName == nil, !self.selectedPeers.contains(peer.id) {
if case let .channel(channel) = peer, channel.addressName == nil, index == nil {
let alertController = textAlertController(
context: component.context,
forceTheme: environment.theme,
@ -1488,7 +1490,8 @@ final class ShareWithPeersScreenComponent: Component {
update()
}
} else {
if case .members = component.stateContext.subject, self.selectedPeers.count >= 10 {
if case .members = component.stateContext.subject, self.selectedPeers.count >= 10, index == nil {
self.hapticFeedback.error()
return
}
togglePeer()
@ -2359,7 +2362,7 @@ final class ShareWithPeersScreenComponent: Component {
case .channels:
title = "Add Channels"
actionButtonTitle = "Save Channels"
subtitle = "select up to 10 channels"
subtitle = "select up to \(component.context.userLimits.maxGiveawayChannelsCount) channels"
}
let titleComponent: AnyComponent<Empty>
@ -2982,6 +2985,10 @@ public class ShareWithPeersScreen: ViewControllerComponentContainer {
}
deinit {
if !self.isDismissed {
self.isDismissed = true
self.dismissed()
}
}
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {