Various improvements

This commit is contained in:
Ilya Laktyushin 2024-05-25 03:45:32 +04:00
parent edd869c702
commit bb5789234c
5 changed files with 126 additions and 118 deletions

View File

@ -35,9 +35,8 @@ private final class DataAndStorageControllerArguments {
let openBrowserSelection: () -> Void
let openIntents: () -> Void
let toggleEnableSensitiveContent: (Bool) -> Void
let presentSensitiveContentConfirmation: () -> Void
init(openStorageUsage: @escaping () -> Void, openNetworkUsage: @escaping () -> Void, openProxy: @escaping () -> Void, openAutomaticDownloadConnectionType: @escaping (AutomaticDownloadConnectionType) -> Void, resetAutomaticDownload: @escaping () -> Void, toggleVoiceUseLessData: @escaping (Bool) -> Void, openSaveIncoming: @escaping (AutomaticSaveIncomingPeerType) -> Void, toggleSaveEditedPhotos: @escaping (Bool) -> Void, togglePauseMusicOnRecording: @escaping (Bool) -> Void, toggleRaiseToListen: @escaping (Bool) -> Void, toggleDownloadInBackground: @escaping (Bool) -> Void, openBrowserSelection: @escaping () -> Void, openIntents: @escaping () -> Void, toggleEnableSensitiveContent: @escaping (Bool) -> Void, presentSensitiveContentConfirmation: @escaping () -> Void) {
init(openStorageUsage: @escaping () -> Void, openNetworkUsage: @escaping () -> Void, openProxy: @escaping () -> Void, openAutomaticDownloadConnectionType: @escaping (AutomaticDownloadConnectionType) -> Void, resetAutomaticDownload: @escaping () -> Void, toggleVoiceUseLessData: @escaping (Bool) -> Void, openSaveIncoming: @escaping (AutomaticSaveIncomingPeerType) -> Void, toggleSaveEditedPhotos: @escaping (Bool) -> Void, togglePauseMusicOnRecording: @escaping (Bool) -> Void, toggleRaiseToListen: @escaping (Bool) -> Void, toggleDownloadInBackground: @escaping (Bool) -> Void, openBrowserSelection: @escaping () -> Void, openIntents: @escaping () -> Void, toggleEnableSensitiveContent: @escaping (Bool) -> Void) {
self.openStorageUsage = openStorageUsage
self.openNetworkUsage = openNetworkUsage
self.openProxy = openProxy
@ -52,7 +51,6 @@ private final class DataAndStorageControllerArguments {
self.openBrowserSelection = openBrowserSelection
self.openIntents = openIntents
self.toggleEnableSensitiveContent = toggleEnableSensitiveContent
self.presentSensitiveContentConfirmation = presentSensitiveContentConfirmation
}
}
@ -112,7 +110,6 @@ private enum DataAndStorageEntry: ItemListNodeEntry {
case connectionHeader(PresentationTheme, String)
case connectionProxy(PresentationTheme, String, String)
case enableSensitiveContent(String, Bool)
case enableSensitiveContentInfo(String)
var section: ItemListSectionId {
switch self {
@ -130,7 +127,7 @@ private enum DataAndStorageEntry: ItemListNodeEntry {
return DataAndStorageSection.other.rawValue
case .connectionHeader, .connectionProxy:
return DataAndStorageSection.connection.rawValue
case .enableSensitiveContent, .enableSensitiveContentInfo:
case .enableSensitiveContent:
return DataAndStorageSection.enableSensitiveContent.rawValue
}
}
@ -177,14 +174,12 @@ private enum DataAndStorageEntry: ItemListNodeEntry {
return 34
case .raiseToListenInfo:
return 35
case .enableSensitiveContent:
return 36
case .enableSensitiveContentInfo:
return 37
case .connectionHeader:
return 38
return 36
case .connectionProxy:
return 39
return 37
case .enableSensitiveContent:
return 38
}
}
@ -328,12 +323,6 @@ private enum DataAndStorageEntry: ItemListNodeEntry {
} else {
return false
}
case let .enableSensitiveContentInfo(text):
if case .enableSensitiveContentInfo(text) = rhs {
return true
} else {
return false
}
}
}
@ -432,15 +421,9 @@ private enum DataAndStorageEntry: ItemListNodeEntry {
arguments.openProxy()
})
case let .enableSensitiveContent(text, value):
return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enableInteractiveChanges: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
if value {
arguments.toggleEnableSensitiveContent(updatedValue)
} else {
arguments.presentSensitiveContentConfirmation()
}
return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in
arguments.toggleEnableSensitiveContent(value)
}, tag: nil)
case let .enableSensitiveContentInfo(text):
return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section)
}
}
}
@ -644,14 +627,6 @@ private func dataAndStorageControllerEntries(state: DataAndStorageControllerStat
entries.append(.raiseToListen(presentationData.theme, presentationData.strings.Settings_RaiseToListen, data.mediaInputSettings.enableRaiseToSpeak))
entries.append(.raiseToListenInfo(presentationData.theme, presentationData.strings.Settings_RaiseToListenInfo))
#if DEBUG
if let contentSettingsConfiguration = contentSettingsConfiguration { //, contentSettingsConfiguration.canAdjustSensitiveContent {
entries.append(.enableSensitiveContent("Show 18+ Content", contentSettingsConfiguration.sensitiveContentEnabled))
entries.append(.enableSensitiveContentInfo("Do not hide media that contain content suitable only for adults."))
}
#endif
let proxyValue: String
if let proxySettings = data.proxySettings, let activeServer = proxySettings.activeServer, proxySettings.enabled {
switch activeServer.connection {
@ -665,7 +640,13 @@ private func dataAndStorageControllerEntries(state: DataAndStorageControllerStat
}
entries.append(.connectionHeader(presentationData.theme, presentationData.strings.ChatSettings_ConnectionType_Title.uppercased()))
entries.append(.connectionProxy(presentationData.theme, presentationData.strings.SocksProxySetup_Title, proxyValue))
#if DEBUG
if let contentSettingsConfiguration = contentSettingsConfiguration, contentSettingsConfiguration.canAdjustSensitiveContent {
entries.append(.enableSensitiveContent("Display Sensitive Content", contentSettingsConfiguration.sensitiveContentEnabled))
}
#endif
return entries
}
@ -798,8 +779,6 @@ public func dataAndStorageController(context: AccountContext, focusOnItemTag: Da
return DataAndStorageData(automaticMediaDownloadSettings: automaticMediaDownloadSettings, autodownloadSettings: autodownloadSettings, generatedMediaStoreSettings: generatedMediaStoreSettings, mediaInputSettings: mediaInputSettings, voiceCallSettings: voiceCallSettings, proxySettings: proxySettings)
})
var enableSensitiveContentImpl: (() -> Void)?
let arguments = DataAndStorageControllerArguments(openStorageUsage: {
pushControllerImpl?(StorageUsageScreen(context: context, makeStorageUsageExceptionsScreen: { category in
return storageUsageExceptionsScreen(context: context, category: category)
@ -903,22 +882,8 @@ public func dataAndStorageController(context: AccountContext, focusOnItemTag: Da
}
})
updateSensitiveContentDisposable.set(updateRemoteContentSettingsConfiguration(postbox: context.account.postbox, network: context.account.network, sensitiveContentEnabled: value).start())
}, presentSensitiveContentConfirmation: {
let controller = textAlertController(context: context, title: "18+ Content", text: "Confirm that you are over 18 years old and update your settings to see potentially explicit and sensitive content.", actions: [
TextAlertAction(type: .genericAction, title: "Cancel", action: {
}),
TextAlertAction(type: .defaultAction, title: "Confirm", action: {
enableSensitiveContentImpl?()
})
])
presentControllerImpl?(controller, nil)
})
enableSensitiveContentImpl = {
arguments.toggleEnableSensitiveContent(true)
}
let preferencesKey: PostboxViewKey = .preferences(keys: Set([ApplicationSpecificPreferencesKeys.mediaAutoSaveSettings]))
let preferences = context.account.postbox.combinedView(keys: [preferencesKey])
|> map { views -> MediaAutoSaveSettings in

View File

@ -129,9 +129,7 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent {
var peer: EnginePeer?
private var disposable: Disposable?
var cachedChevronImage: (UIImage, PresentationTheme)?
init(
context: AccountContext,
peerId: EnginePeer.Id?
@ -553,8 +551,6 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
private var disposable: Disposable?
private var paymentDisposable = MetaDisposable()
var cachedChevronImage: (UIImage, PresentationTheme)?
init(
context: AccountContext,
starsContext: StarsContext,
@ -696,7 +692,9 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
let topPanel = Child(BlurredBackgroundComponent.self)
let topSeparator = Child(Rectangle.self)
let title = Child(MultilineTextComponent.self)
let balanceText = Child(MultilineTextComponent.self)
let balanceTitle = Child(MultilineTextComponent.self)
let balanceValue = Child(MultilineTextComponent.self)
let balanceIcon = Child(BundleIconComponent.self)
let scrollAction = ActionSlot<CGPoint?>()
@ -765,32 +763,33 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
transition: context.transition
)
let textColor = environment.theme.list.itemPrimaryTextColor
let accentColor = UIColor(rgb: 0x597cf5)
let textFont = Font.regular(14.0)
let boldTextFont = Font.bold(14.0)
let markdownAttributes = MarkdownAttributes(body: MarkdownAttributeSet(font: textFont, textColor: textColor), bold: MarkdownAttributeSet(font: boldTextFont, textColor: textColor), link: MarkdownAttributeSet(font: textFont, textColor: accentColor), linkAttribute: { _ in
return nil
})
if state.cachedChevronImage == nil || state.cachedChevronImage?.1 !== environment.theme {
state.cachedChevronImage = (generateTintedImage(image: UIImage(bundleImageName: "Item List/PremiumIcon"), color: UIColor(rgb: 0xf09903))!, environment.theme)
}
let balanceAttributedString = parseMarkdownIntoAttributedString(" \(strings.Stars_Purchase_Balance)\n # **\(state.starsState?.balance ?? 0)**", attributes: markdownAttributes, textAlignment: .right).mutableCopy() as! NSMutableAttributedString
if let range = balanceAttributedString.string.range(of: "#"), let chevronImage = state.cachedChevronImage?.0 {
balanceAttributedString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: balanceAttributedString.string))
balanceAttributedString.addAttribute(.foregroundColor, value: UIColor(rgb: 0xf09903), range: NSRange(range, in: balanceAttributedString.string))
balanceAttributedString.addAttribute(.baselineOffset, value: 2.0, range: NSRange(range, in: balanceAttributedString.string))
}
let balanceText = balanceText.update(
let balanceTitle = balanceTitle.update(
component: MultilineTextComponent(
text: .plain(balanceAttributedString),
horizontalAlignment: .left,
maximumNumberOfLines: 0
text: .plain(NSAttributedString(
string: environment.strings.Stars_Purchase_Balance,
font: Font.regular(14.0),
textColor: environment.theme.actionSheet.primaryTextColor
)),
maximumNumberOfLines: 1
),
availableSize: CGSize(width: 200, height: context.availableSize.height),
availableSize: context.availableSize,
transition: .immediate
)
let balanceValue = balanceValue.update(
component: MultilineTextComponent(
text: .plain(NSAttributedString(
string: presentationStringsFormattedNumber(Int32(state.starsState?.balance ?? 0), environment.dateTimeFormat.decimalSeparator),
font: Font.semibold(14.0),
textColor: environment.theme.actionSheet.primaryTextColor
)),
maximumNumberOfLines: 1
),
availableSize: context.availableSize,
transition: .immediate
)
let balanceIcon = balanceIcon.update(
component: BundleIconComponent(name: "Premium/Stars/StarSmall", tintColor: nil),
availableSize: context.availableSize,
transition: .immediate
)
@ -890,8 +889,16 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
.opacity(titleAlpha)
)
context.add(balanceText
.position(CGPoint(x: context.availableSize.width - 16.0 - balanceText.size.width / 2.0, y: 28.0))
let navigationHeight = environment.navigationHeight - environment.statusBarHeight
let topBalanceOriginY = environment.statusBarHeight + (navigationHeight - balanceTitle.size.height - balanceValue.size.height) / 2.0
context.add(balanceTitle
.position(CGPoint(x: context.availableSize.width - 16.0 - environment.safeInsets.right - balanceTitle.size.width / 2.0, y: topBalanceOriginY + balanceTitle.size.height / 2.0))
)
context.add(balanceValue
.position(CGPoint(x: context.availableSize.width - 16.0 - environment.safeInsets.right - balanceValue.size.width / 2.0, y: topBalanceOriginY + balanceTitle.size.height + balanceValue.size.height / 2.0))
)
context.add(balanceIcon
.position(CGPoint(x: context.availableSize.width - 16.0 - environment.safeInsets.right - balanceValue.size.width - balanceIcon.size.width / 2.0 - 2.0, y: topBalanceOriginY + balanceTitle.size.height + balanceValue.size.height / 2.0 - UIScreenPixel))
)
return context.availableSize

View File

@ -285,7 +285,7 @@ final class StarsTransactionsListPanelComponent: Component {
component: AnyComponent(ListActionItemComponent(
theme: environment.theme,
title: AnyComponent(VStack(titleComponents, alignment: .left, spacing: 2.0)),
contentInsets: UIEdgeInsets(top: 9.0, left: 0.0, bottom: 8.0, right: 0.0),
contentInsets: UIEdgeInsets(top: 9.0, left: environment.containerInsets.left, bottom: 8.0, right: environment.containerInsets.right),
leftIcon: .custom(AnyComponentWithIdentity(id: "avatar", component: AnyComponent(AvatarComponent(context: component.context, theme: environment.theme, peer: item.transaction.peer))), false),
icon: nil,
accessory: .custom(ListActionItemComponent.CustomAccessory(component: AnyComponentWithIdentity(id: "label", component: AnyComponent(LabelComponent(text: itemLabel))), insets: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 16.0))),
@ -306,7 +306,7 @@ final class StarsTransactionsListPanelComponent: Component {
}
itemTransition.setFrame(view: itemComponentView, frame: itemFrame)
}
let sideInset: CGFloat = 60.0
let sideInset: CGFloat = 60.0 + environment.containerInsets.left
itemTransition.setFrame(view: separatorView, frame: CGRect(x: sideInset, y: itemFrame.maxY, width: itemFrame.width - sideInset, height: UIScreenPixel))
}
}

View File

@ -426,7 +426,6 @@ final class StarsTransactionsScreenComponent: Component {
font: Font.regular(14.0),
textColor: environment.theme.actionSheet.primaryTextColor
)),
horizontalAlignment: .right,
maximumNumberOfLines: 1
)),
environment: {},
@ -441,7 +440,6 @@ final class StarsTransactionsScreenComponent: Component {
font: Font.semibold(14.0),
textColor: environment.theme.actionSheet.primaryTextColor
)),
horizontalAlignment: .right,
maximumNumberOfLines: 1
)),
environment: {},
@ -456,7 +454,7 @@ final class StarsTransactionsScreenComponent: Component {
let navigationHeight = environment.navigationHeight - environment.statusBarHeight
let topBalanceOriginY = environment.statusBarHeight + (navigationHeight - topBalanceTitleSize.height - topBalanceValueSize.height) / 2.0
let topBalanceTitleFrame = CGRect(origin: CGPoint(x: availableSize.width - topBalanceTitleSize.width - 16.0, y: topBalanceOriginY), size: topBalanceTitleSize)
let topBalanceTitleFrame = CGRect(origin: CGPoint(x: availableSize.width - topBalanceTitleSize.width - 16.0 - environment.safeInsets.right, y: topBalanceOriginY), size: topBalanceTitleSize)
if let topBalanceTitleView = self.topBalanceTitleView.view {
if topBalanceTitleView.superview == nil {
topBalanceTitleView.alpha = 0.0
@ -465,7 +463,7 @@ final class StarsTransactionsScreenComponent: Component {
starTransition.setFrame(view: topBalanceTitleView, frame: topBalanceTitleFrame)
}
let topBalanceValueFrame = CGRect(origin: CGPoint(x: availableSize.width - topBalanceValueSize.width - 16.0, y: topBalanceTitleFrame.maxY), size: topBalanceValueSize)
let topBalanceValueFrame = CGRect(origin: CGPoint(x: availableSize.width - topBalanceValueSize.width - 16.0 - environment.safeInsets.right, y: topBalanceTitleFrame.maxY), size: topBalanceValueSize)
if let topBalanceValueView = self.topBalanceValueView.view {
if topBalanceValueView.superview == nil {
topBalanceValueView.alpha = 0.0

View File

@ -11,11 +11,12 @@ import ViewControllerComponent
import SheetComponent
import BalancedTextComponent
import MultilineTextComponent
import BundleIconComponent
import ButtonComponent
import PremiumStarComponent
import ItemListUI
import UndoUI
import AccountContext
import PremiumStarComponent
import ButtonComponent
private final class SheetContent: CombinedComponent {
typealias EnvironmentType = ViewControllerComponentContainer.Environment
@ -55,7 +56,6 @@ private final class SheetContent: CombinedComponent {
final class State: ComponentState {
var cachedCloseImage: (UIImage, PresentationTheme)?
var cachedChevronImage: (UIImage, PresentationTheme)?
var cachedStarImage: (UIImage, PresentationTheme)?
private let context: AccountContext
@ -68,7 +68,12 @@ private final class SheetContent: CombinedComponent {
private(set) var form: BotPaymentForm?
private var optionsDisposable: Disposable?
private(set) var options: [StarsTopUpOption] = []
private(set) var options: [StarsTopUpOption] = [] {
didSet {
self.optionsPromise.set(self.options)
}
}
private let optionsPromise = ValuePromise<[StarsTopUpOption]?>(nil)
var inProgress = false
@ -94,7 +99,7 @@ private final class SheetContent: CombinedComponent {
self.peer = inputData?.2
self.updated(transition: .immediate)
if self.optionsDisposable != nil {
if self.optionsDisposable == nil, let balance = self.balance, balance < self.invoice.totalAmount {
self.optionsDisposable = (context.engine.payments.starsTopUpOptions()
|> deliverOnMainQueue).start(next: { [weak self] options in
guard let self else {
@ -111,12 +116,15 @@ private final class SheetContent: CombinedComponent {
self.optionsDisposable?.dispose()
}
func buy(requestTopUp: (@escaping () -> Void) -> Void, completion: @escaping () -> Void) {
func buy(requestTopUp: @escaping (@escaping () -> Void) -> Void, completion: @escaping () -> Void) {
guard let form, let balance else {
return
}
let action = {
let action = { [weak self] in
guard let self else {
return
}
self.inProgress = true
self.updated()
@ -127,8 +135,21 @@ private final class SheetContent: CombinedComponent {
}
if balance < self.invoice.totalAmount {
requestTopUp({
action()
if self.options.isEmpty {
self.inProgress = true
self.updated()
}
let _ = (self.optionsPromise.get()
|> filter { $0 != nil}
|> take(1)
|> deliverOnMainQueue).startStandalone(next: { [weak self] _ in
if let self {
self.inProgress = false
self.updated()
}
requestTopUp({
action()
})
})
} else {
action()
@ -146,8 +167,10 @@ private final class SheetContent: CombinedComponent {
let closeButton = Child(Button.self)
let title = Child(Text.self)
let text = Child(BalancedTextComponent.self)
let balanceText = Child(MultilineTextComponent.self)
let button = Child(ButtonComponent.self)
let balanceTitle = Child(MultilineTextComponent.self)
let balanceValue = Child(MultilineTextComponent.self)
let balanceIcon = Child(BundleIconComponent.self)
return { context in
let environment = context.environment[EnvironmentType.self]
@ -261,32 +284,47 @@ private final class SheetContent: CombinedComponent {
contentSize.height += text.size.height
contentSize.height += 28.0
if state.cachedChevronImage == nil || state.cachedChevronImage?.1 !== theme {
state.cachedChevronImage = (generateTintedImage(image: UIImage(bundleImageName: "Premium/Stars/StarLarge"), color: UIColor(rgb: 0xf09903))!, theme)
}
let balanceValue = presentationStringsFormattedNumber(Int32(state.balance ?? 0), environment.dateTimeFormat.decimalSeparator)
let balanceAttributedString = NSMutableAttributedString(string: strings.Stars_Transfer_Balance, font: Font.regular(14.0), textColor: textColor)
balanceAttributedString.append(NSMutableAttributedString(string: "\n # \(balanceValue)", font: Font.semibold(16.0), textColor: textColor))
if let range = balanceAttributedString.string.range(of: "#"), let chevronImage = state.cachedChevronImage?.0 {
balanceAttributedString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: balanceAttributedString.string))
balanceAttributedString.addAttribute(.foregroundColor, value: UIColor(rgb: 0xf09903), range: NSRange(range, in: balanceAttributedString.string))
balanceAttributedString.addAttribute(.baselineOffset, value: 2.0, range: NSRange(range, in: balanceAttributedString.string))
}
let balanceText = balanceText.update(
let balanceTitle = balanceTitle.update(
component: MultilineTextComponent(
text: .plain(balanceAttributedString),
horizontalAlignment: .left,
maximumNumberOfLines: 0,
lineSpacing: 0.25
text: .plain(NSAttributedString(
string: environment.strings.Stars_Transfer_Balance,
font: Font.regular(14.0),
textColor: textColor
)),
maximumNumberOfLines: 1
),
availableSize: CGSize(width: constrainedTitleWidth, height: context.availableSize.height),
availableSize: context.availableSize,
transition: .immediate
)
context.add(balanceText
.position(CGPoint(x: 16.0 + balanceText.size.width / 2.0, y: 31.0))
let balanceValue = balanceValue.update(
component: MultilineTextComponent(
text: .plain(NSAttributedString(
string: presentationStringsFormattedNumber(Int32(state.balance ?? 0), environment.dateTimeFormat.decimalSeparator),
font: Font.semibold(16.0),
textColor: textColor
)),
maximumNumberOfLines: 1
),
availableSize: context.availableSize,
transition: .immediate
)
let balanceIcon = balanceIcon.update(
component: BundleIconComponent(name: "Premium/Stars/StarMedium", tintColor: nil),
availableSize: context.availableSize,
transition: .immediate
)
let topBalanceOriginY = 11.0
context.add(balanceTitle
.position(CGPoint(x: 16.0 + environment.safeInsets.left + balanceTitle.size.width / 2.0, y: topBalanceOriginY + balanceTitle.size.height / 2.0))
)
context.add(balanceIcon
.position(CGPoint(x: 16.0 + environment.safeInsets.left + balanceIcon.size.width / 2.0, y: topBalanceOriginY + balanceTitle.size.height + balanceValue.size.height / 2.0 - UIScreenPixel))
)
context.add(balanceValue
.position(CGPoint(x: 16.0 + environment.safeInsets.left + balanceIcon.size.width + 3.0 + balanceValue.size.width / 2.0, y: topBalanceOriginY + balanceTitle.size.height + balanceValue.size.height / 2.0))
)
if state.cachedStarImage == nil || state.cachedStarImage?.1 !== theme {
state.cachedStarImage = (generateTintedImage(image: UIImage(bundleImageName: "Item List/PremiumIcon"), color: .white)!, theme)
}