Various fixes

This commit is contained in:
Ilya Laktyushin 2026-02-03 15:27:06 +04:00
parent bbad57434f
commit 2ba1f6183e
10 changed files with 113 additions and 74 deletions

View file

@ -15697,8 +15697,8 @@ Error: %8$@";
"Gift.Craft.Info.Paragraph3.Title" = "Affect the Result";
"Gift.Craft.Info.Paragraph3.Text" = "Use gifts with the same attribute to boost it's chance.";
"Gift.Craft.Info.Understood" = "Understood";
"Gift.Craft.Unavailable.Title" = "Try Later";
"Gift.Craft.Unavailable.Text" = "You will be able to craft this gift on %@.";
"Gift.Craft.Unavailable.Title" = "Crafting Unavailable";
"Gift.Craft.Unavailable.Text" = "This gift will become available for crafting on **%@**.";
"Gift.Craft.Error.NotAvailable" = "One of the gifts is not available for crafting.";
"Gift.Craft.Select.Title" = "Select Gifts";

View file

@ -623,7 +623,7 @@ public final class ResizableSheetComponent<ChildEnvironmentType: Sendable & Equa
environment: {},
containerSize: CGSize(width: containerSize.width - 66.0 * 2.0, height: 66.0)
)
let titleItemFrame = CGRect(origin: CGPoint(x: rawSideInset + floorToScreenPixels((containerSize.width - titleItemSize.width)) / 2.0, y: floorToScreenPixels(36.0 - titleItemSize.height * 0.5)), size: titleItemSize)
let titleItemFrame = CGRect(origin: CGPoint(x: rawSideInset + floorToScreenPixels((containerSize.width - titleItemSize.width)) / 2.0, y: floorToScreenPixels(38.0 - titleItemSize.height * 0.5)), size: titleItemSize)
if let view = titleItemView.view {
if view.superview == nil {
self.navigationBarContainer.addSubview(view)

View file

@ -132,6 +132,7 @@ swift_library(
"//submodules/TelegramUI/Components/Calls/VideoChatMicButtonComponent",
"//submodules/TelegramUI/Components/AlertComponent",
"//submodules/TelegramUI/Components/AlertComponent/AlertInputFieldComponent",
"//submodules/TelegramUI/Components/GlassControls",
],
visibility = [
"//visibility:public",

View file

@ -13,6 +13,7 @@ import BalancedTextComponent
import TelegramPresentationData
import TelegramStringFormatting
import Markdown
import GlassControls
private final class ScheduleVideoChatSheetContentComponent: Component {
typealias EnvironmentType = ViewControllerComponentContainer.Environment
@ -33,8 +34,8 @@ private final class ScheduleVideoChatSheetContentComponent: Component {
}
final class View: UIView {
private let button = ComponentView<Empty>()
private let cancelButton = ComponentView<Empty>()
private let buttons = ComponentView<Empty>()
private let actionButton = ComponentView<Empty>()
private let title = ComponentView<Empty>()
private let mainText = ComponentView<Empty>()
@ -110,6 +111,43 @@ private final class ScheduleVideoChatSheetContentComponent: Component {
var contentHeight: CGFloat = 0.0
contentHeight += 16.0
let buttonsSize = self.buttons.update(
transition: transition,
component: AnyComponent(
GlassControlPanelComponent(
theme: environment.theme,
leftItem: GlassControlPanelComponent.Item(
items: [
GlassControlGroupComponent.Item(
id: AnyHashable("close"),
content: .icon("Navigation/Close"),
action: { [weak self] in
guard let component = self?.component else {
return
}
component.dismiss()
}
)
],
background: .panel
),
centralItem: nil,
rightItem: nil,
centerAlignmentIfPossible: true,
isDark: true
)
),
environment: {},
containerSize: CGSize(width: availableSize.width - 16.0 * 2.0, height: 44.0)
)
if let buttonsView = self.buttons.view {
if buttonsView.superview == nil {
self.addSubview(buttonsView)
}
transition.setFrame(view: buttonsView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - buttonsSize.width) * 0.5), y: contentHeight), size: buttonsSize))
}
contentHeight += buttonsSize.height
let titleString = NSMutableAttributedString()
titleString.append(NSAttributedString(string: environment.strings.VideoChat_ScheduleButtonTitle, font: Font.semibold(17.0), textColor: environment.theme.list.itemPrimaryTextColor))
@ -126,9 +164,8 @@ private final class ScheduleVideoChatSheetContentComponent: Component {
if titleView.superview == nil {
self.addSubview(titleView)
}
transition.setFrame(view: titleView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - titleSize.width) * 0.5), y: contentHeight), size: titleSize))
transition.setFrame(view: titleView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - titleSize.width) * 0.5), y: contentHeight - buttonsSize.height * 0.5 - titleSize.height * 0.5), size: titleSize))
}
contentHeight += titleSize.height
contentHeight += 16.0
let pickerView: UIDatePicker
@ -221,17 +258,20 @@ private final class ScheduleVideoChatSheetContentComponent: Component {
transition.setFrame(view: mainTextView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - mainTextSize.width) * 0.5), y: contentHeight), size: mainTextSize))
}
contentHeight += mainTextSize.height
contentHeight += 10.0
contentHeight += 32.0
var buttonContents: [AnyComponentWithIdentity<Empty>] = []
buttonContents.append(AnyComponentWithIdentity(id: AnyHashable(0 as Int), component: AnyComponent(
Text(text: buttonTitle, font: Font.semibold(17.0), color: environment.theme.list.itemCheckColors.foregroundColor)
)))
let buttonTransition = transition
let buttonSize = self.button.update(
let buttonInsets = ContainerViewLayout.concentricInsets(bottomInset: environment.safeInsets.bottom, innerDiameter: 52.0, sideInset: 30.0)
let buttonSize = self.actionButton.update(
transition: buttonTransition,
component: AnyComponent(ButtonComponent(
background: ButtonComponent.Background(
style: .glass,
color: UIColor(rgb: 0x3252EF),
foreground: .white,
pressedColor: UIColor(rgb: 0x3252EF).withMultipliedAlpha(0.8)
@ -250,56 +290,17 @@ private final class ScheduleVideoChatSheetContentComponent: Component {
}
)),
environment: {},
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 50.0)
containerSize: CGSize(width: availableSize.width - buttonInsets.left - buttonInsets.right, height: 52.0)
)
let buttonFrame = CGRect(origin: CGPoint(x: sideInset, y: contentHeight), size: buttonSize)
if let buttonView = self.button.view {
let buttonFrame = CGRect(origin: CGPoint(x: buttonInsets.left, y: contentHeight), size: buttonSize)
if let buttonView = self.actionButton.view {
if buttonView.superview == nil {
self.addSubview(buttonView)
}
transition.setFrame(view: buttonView, frame: buttonFrame)
}
contentHeight += buttonSize.height
contentHeight += 10.0
let cancelButtonSize = self.cancelButton.update(
transition: buttonTransition,
component: AnyComponent(ButtonComponent(
background: ButtonComponent.Background(
color: UIColor(rgb: 0x2B2B2F),
foreground: .white,
pressedColor: UIColor(rgb: 0x2B2B2F).withMultipliedAlpha(0.8)
),
content: AnyComponentWithIdentity(id: AnyHashable(0 as Int), component: AnyComponent(
Text(text: environment.strings.Common_Cancel, font: Font.semibold(17.0), color: environment.theme.list.itemPrimaryTextColor)
)),
isEnabled: true,
tintWhenDisabled: false,
displaysProgress: false,
action: { [weak self] in
guard let self, let component = self.component else {
return
}
component.dismiss()
}
)),
environment: {},
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 50.0)
)
let cancelButtonFrame = CGRect(origin: CGPoint(x: sideInset, y: contentHeight), size: cancelButtonSize)
if let cancelButtonView = self.cancelButton.view {
if cancelButtonView.superview == nil {
self.addSubview(cancelButtonView)
}
transition.setFrame(view: cancelButtonView, frame: cancelButtonFrame)
}
contentHeight += cancelButtonSize.height
if environment.safeInsets.bottom.isZero {
contentHeight += 16.0
} else {
contentHeight += environment.safeInsets.bottom + 14.0
}
contentHeight += buttonInsets.bottom
return CGSize(width: availableSize.width, height: contentHeight)
}
@ -407,7 +408,8 @@ private final class ScheduleVideoChatSheetScreenComponent: Component {
})
}
)),
backgroundColor: .color(UIColor(rgb: 0x1C1C1E)),
style: .glass,
backgroundColor: .color(UIColor(rgb: 0x1c1c1e)),
animateOut: self.sheetAnimateOut
)),
environment: {

View file

@ -1517,6 +1517,7 @@ private final class SheetContainerComponent: CombinedComponent {
let state = context.state
let strings = environment.strings
let dateTimeFormat = environment.dateTimeFormat
if externalState.displayFailure {
state.displayFailure = true
@ -1846,6 +1847,9 @@ private final class SheetContainerComponent: CombinedComponent {
if let navigationController = controller()?.navigationController {
var text: String = strings.Login_UnknownError
switch error {
case let .tooEarly(canCraftDate):
let dateString = stringForFullDate(timestamp: canCraftDate, strings: strings, dateTimeFormat: dateTimeFormat)
text = strings.Gift_Craft_Unavailable_Text(dateString).string
case .unavailable:
text = strings.Gift_Craft_Error_NotAvailable
default:

View file

@ -87,7 +87,7 @@ final class SelectGiftPageContent: Component {
private var craftStateDisposable: Disposable?
private var availableGifts: [GiftItem] = []
private var giftMap: [Int64: GiftItem] = [:]
private var giftMap: [Int64: ProfileGiftsContext.State.StarGift] = [:]
private var availableSize: CGSize?
private var currentBounds: CGRect?
@ -203,11 +203,27 @@ final class SelectGiftPageContent: Component {
isEditing: false,
mode: .grid,
action: { [weak self] in
guard let self, let component = self.component else {
guard let self, let component = self.component, let environment = self.environment else {
return
}
HapticFeedback().impact(.light)
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
if let profileGift = self.giftMap[gift.gift.id], let canCraftDate = profileGift.canCraftAt, currentTime < canCraftDate {
let dateString = stringForFullDate(timestamp: canCraftDate, strings: environment.strings, dateTimeFormat: environment.dateTimeFormat)
let alertController = textAlertController(
context: component.context,
title: environment.strings.Gift_Craft_Unavailable_Title,
text: environment.strings.Gift_Craft_Unavailable_Text(dateString).string,
actions: [
TextAlertAction(type: .defaultAction, title: environment.strings.Common_OK, action: {})
],
parseMarkdown: true
)
environment.controller()?.present(alertController, in: .window(.root))
return
}
component.selectGift(gift)
component.dismiss()
},
@ -322,7 +338,6 @@ final class SelectGiftPageContent: Component {
self.availableGifts = [
initialGiftItem
]
self.giftMap = [initialGiftItem.gift.id: initialGiftItem]
self.craftStateDisposable = (component.craftContext.state
|> deliverOnMainQueue).start(next: { [weak self] state in
@ -332,32 +347,28 @@ final class SelectGiftPageContent: Component {
self.craftState = state
var items: [GiftItem] = []
var map: [Int64: GiftItem] = [:]
var foundInitial = false
var giftMap: [Int64: ProfileGiftsContext.State.StarGift] = [:]
var existingIds = Set<Int64>()
for gift in state.gifts {
guard let reference = gift.reference, case let .unique(uniqueGift) = gift.gift else {
guard let reference = gift.reference, case let .unique(uniqueGift) = gift.gift, !existingIds.contains(uniqueGift.id) else {
continue
}
existingIds.insert(uniqueGift.id)
let giftItem = GiftItem(
gift: uniqueGift,
reference: reference
)
map[uniqueGift.id] = giftItem
if uniqueGift.id == component.gift.id {
foundInitial = true
} else {
if component.selectedGiftIds.contains(uniqueGift.id) {
continue
}
items.append(giftItem)
giftMap[uniqueGift.id] = gift
if component.selectedGiftIds.contains(uniqueGift.id) {
continue
}
items.append(giftItem)
}
if !foundInitial {
map[initialGiftItem.gift.id] = initialGiftItem
}
self.availableGifts = items
self.giftMap = map
self.giftMap = giftMap
self.state?.updated(transition: .spring(duration: 0.4))
})

View file

@ -1536,9 +1536,18 @@ private final class GiftViewSheetContent: CombinedComponent {
controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: nil, text: presentationData.strings.Conversation_LinkCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
})))
if let _ = arguments.canCraftDate {
var canCraft = false
if let data = self.context.currentAppConfiguration.with({ $0 }).data {
if let _ = data["ios_enable_crafting"] {
canCraft = true
} else if let isDev = data["dev"] as? Double, isDev == 1.0 {
canCraft = true
}
}
if let _ = arguments.canCraftDate, canCraft {
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Gift_View_Context_Craft, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Link"), color: theme.contextMenu.primaryColor)
return generateTintedImage(image: UIImage(bundleImageName: "Premium/Craft/Craft"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] c, _ in
c?.dismiss(completion: nil)

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "craft.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -251,7 +251,7 @@ private final class SheetContent: CombinedComponent {
return { context in
let environment = context.environment[ViewControllerComponentContainer.Environment.self].value
let state = context.state
let theme = environment.theme
let theme = environment.theme.withModalBlocksBackground()
let strings = environment.strings
let topInset: CGFloat = environment.navigationHeight - 35.0