mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-08 08:31:13 +00:00
Fix ref duration
This commit is contained in:
parent
7eed291fbf
commit
ef3b593aa6
@ -589,6 +589,18 @@ func _internal_removeChatManagingBot(account: Account, chatId: EnginePeer.Id) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func formatPermille(_ value: Int32) -> String {
|
||||||
|
return formatPermille(Int(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func formatPermille(_ value: Int) -> String {
|
||||||
|
if value % 10 == 0 {
|
||||||
|
return "\(value / 10)"
|
||||||
|
} else {
|
||||||
|
return String(format: "%.1f", Double(value) / 10.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func _internal_updateStarRefProgram(account: Account, id: EnginePeer.Id, program: (commissionPermille: Int32, durationMonths: Int32?)?) -> Signal<Never, NoError> {
|
func _internal_updateStarRefProgram(account: Account, id: EnginePeer.Id, program: (commissionPermille: Int32, durationMonths: Int32?)?) -> Signal<Never, NoError> {
|
||||||
return account.postbox.transaction { transaction -> Api.InputUser? in
|
return account.postbox.transaction { transaction -> Api.InputUser? in
|
||||||
return transaction.getPeer(id).flatMap(apiInputUser)
|
return transaction.getPeer(id).flatMap(apiInputUser)
|
||||||
|
@ -176,10 +176,10 @@ final class AffiliateProgramSetupScreenComponent: Component {
|
|||||||
let programPermille: Int32 = Int32(self.commissionPermille)
|
let programPermille: Int32 = Int32(self.commissionPermille)
|
||||||
let programDuration: Int32? = self.durationValue == Int(Int32.max) ? nil : Int32(self.durationValue)
|
let programDuration: Int32? = self.durationValue == Int(Int32.max) ? nil : Int32(self.durationValue)
|
||||||
|
|
||||||
let commissionTitle: String = "\(programPermille / 10)%"
|
let commissionTitle: String = "\(formatPermille(programPermille))%"
|
||||||
let durationTitle: String
|
let durationTitle: String
|
||||||
if let durationMonths = programDuration {
|
if let durationMonths = programDuration {
|
||||||
durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (24 * 60 * 60))
|
durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (30 * 24 * 60 * 60))
|
||||||
} else {
|
} else {
|
||||||
durationTitle = "Lifetime"
|
durationTitle = "Lifetime"
|
||||||
}
|
}
|
||||||
@ -378,7 +378,7 @@ If you end your affiliate program:
|
|||||||
}
|
}
|
||||||
UIPasteboard.general.string = bot.url
|
UIPasteboard.general.string = bot.url
|
||||||
let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 })
|
let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 })
|
||||||
self.environment?.controller()?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(bot.commissionPermille / 10)%** of what people who use it spend in **\(bot.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
self.environment?.controller()?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(formatPermille(bot.commissionPermille))%** of what people who use it spend in **\(bot.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
))
|
))
|
||||||
@ -557,13 +557,15 @@ If you end your affiliate program:
|
|||||||
self.commissionPermille = 10
|
self.commissionPermille = 10
|
||||||
self.commissionSliderValue = 0.0
|
self.commissionSliderValue = 0.0
|
||||||
self.commissionMinPermille = 10
|
self.commissionMinPermille = 10
|
||||||
self.durationValue = 10
|
self.durationValue = 1
|
||||||
|
self.durationMinValue = 0
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.commissionPermille = 10
|
self.commissionPermille = 10
|
||||||
self.commissionSliderValue = 0.0
|
self.commissionSliderValue = 0.0
|
||||||
self.commissionMinPermille = 10
|
self.commissionMinPermille = 10
|
||||||
self.durationValue = 10
|
self.durationValue = 1
|
||||||
|
self.durationMinValue = 0
|
||||||
}
|
}
|
||||||
case .connectedPrograms:
|
case .connectedPrograms:
|
||||||
self.connectedStarBotListDisposable = (component.context.engine.peers.requestConnectedStarRefBots(
|
self.connectedStarBotListDisposable = (component.context.engine.peers.requestConnectedStarRefBots(
|
||||||
@ -875,7 +877,7 @@ If you end your affiliate program:
|
|||||||
minValue: commissionMinSliderValue,
|
minValue: commissionMinSliderValue,
|
||||||
lowerBoundTitle: "1%",
|
lowerBoundTitle: "1%",
|
||||||
upperBoundTitle: "90%",
|
upperBoundTitle: "90%",
|
||||||
title: "\(self.commissionPermille / 10)%",
|
title: "\(formatPermille(self.commissionPermille))%",
|
||||||
valueUpdated: { [weak self] value in
|
valueUpdated: { [weak self] value in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
@ -1183,11 +1185,11 @@ If you end your affiliate program:
|
|||||||
for item in connectedStarBotList.items {
|
for item in connectedStarBotList.items {
|
||||||
let durationTitle: String
|
let durationTitle: String
|
||||||
if let durationMonths = item.durationMonths {
|
if let durationMonths = item.durationMonths {
|
||||||
durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (24 * 60 * 60))
|
durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (30 * 24 * 60 * 60))
|
||||||
} else {
|
} else {
|
||||||
durationTitle = "Lifetime"
|
durationTitle = "Lifetime"
|
||||||
}
|
}
|
||||||
let commissionTitle = "\(item.commissionPermille / 10)%"
|
let commissionTitle = "\(formatPermille(item.commissionPermille))%"
|
||||||
|
|
||||||
let itemContextAction: (EnginePeer, ContextExtractedContentContainingView, ContextGesture?) -> Void = { [weak self] peer, sourceView, gesture in
|
let itemContextAction: (EnginePeer, ContextExtractedContentContainingView, ContextGesture?) -> Void = { [weak self] peer, sourceView, gesture in
|
||||||
guard let self, let component = self.component, let environment = self.environment else {
|
guard let self, let component = self.component, let environment = self.environment else {
|
||||||
@ -1249,7 +1251,7 @@ If you end your affiliate program:
|
|||||||
let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 })
|
let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 })
|
||||||
|
|
||||||
UIPasteboard.general.string = item.url
|
UIPasteboard.general.string = item.url
|
||||||
environment.controller()?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(item.commissionPermille / 10)%** of what people who use it spend in **\(item.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
environment.controller()?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(formatPermille(item.commissionPermille))%** of what people who use it spend in **\(item.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||||
})))
|
})))
|
||||||
|
|
||||||
itemList.append(.action(ContextMenuActionItem(text: "Leave", textColor: .destructive, icon: { theme in
|
itemList.append(.action(ContextMenuActionItem(text: "Leave", textColor: .destructive, icon: { theme in
|
||||||
@ -1364,17 +1366,21 @@ If you end your affiliate program:
|
|||||||
do {
|
do {
|
||||||
var suggestedSectionItems: [AnyComponentWithIdentity<Empty>] = []
|
var suggestedSectionItems: [AnyComponentWithIdentity<Empty>] = []
|
||||||
if suggestedStarBotListItems.isEmpty {
|
if suggestedStarBotListItems.isEmpty {
|
||||||
suggestedSectionItems.append(AnyComponentWithIdentity(id: "empty", component: AnyComponent(TransformContents(
|
suggestedSectionItems.append(AnyComponentWithIdentity(id: "empty", component: AnyComponent(ZStack([
|
||||||
content: AnyComponent(),
|
AnyComponentWithIdentity(id: 0, component: AnyComponent(Rectangle(color: .clear, width: nil, height: 100.0))),
|
||||||
fixedSize: CGSize(width: 1.0, height: 100.0),
|
AnyComponentWithIdentity(id: 1, component: AnyComponent(MultilineTextComponent(
|
||||||
translation: CGPoint()
|
text: .plain(NSAttributedString(string: "No available programs yet.\nPlease check the page later.", font: Font.regular(15.0), textColor: environment.theme.list.itemSecondaryTextColor)),
|
||||||
))))
|
horizontalAlignment: .center,
|
||||||
|
maximumNumberOfLines: 0,
|
||||||
|
lineSpacing: 0.2
|
||||||
|
)))
|
||||||
|
]))))
|
||||||
}
|
}
|
||||||
for item in suggestedStarBotListItems {
|
for item in suggestedStarBotListItems {
|
||||||
let commissionTitle = "\(item.program.commissionPermille / 10)%"
|
let commissionTitle = "\(formatPermille(item.program.commissionPermille))%"
|
||||||
let durationTitle: String
|
let durationTitle: String
|
||||||
if let durationMonths = item.program.durationMonths {
|
if let durationMonths = item.program.durationMonths {
|
||||||
durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (24 * 60 * 60))
|
durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (30 * 24 * 60 * 60))
|
||||||
} else {
|
} else {
|
||||||
durationTitle = "Lifetime"
|
durationTitle = "Lifetime"
|
||||||
}
|
}
|
||||||
@ -1467,20 +1473,17 @@ If you end your affiliate program:
|
|||||||
))))
|
))))
|
||||||
}
|
}
|
||||||
|
|
||||||
let suggestedProgramsSectionSize = self.suggestedProgramsSection.update(
|
var suggestedHeaderItems: [AnyComponentWithIdentity<Empty>] = []
|
||||||
transition: transition,
|
suggestedHeaderItems.append(AnyComponentWithIdentity(id: 0, component: AnyComponent(MultilineTextComponent(
|
||||||
component: AnyComponent(ListSectionComponent(
|
|
||||||
theme: environment.theme,
|
|
||||||
header: AnyComponent(HStack([
|
|
||||||
AnyComponentWithIdentity(id: 0, component: AnyComponent(MultilineTextComponent(
|
|
||||||
text: .plain(NSAttributedString(
|
text: .plain(NSAttributedString(
|
||||||
string: "PROGRAMS",
|
string: "PROGRAMS",
|
||||||
font: Font.regular(13.0),
|
font: Font.regular(13.0),
|
||||||
textColor: environment.theme.list.freeTextColor
|
textColor: environment.theme.list.freeTextColor
|
||||||
)),
|
)),
|
||||||
maximumNumberOfLines: 0
|
maximumNumberOfLines: 0
|
||||||
))),
|
))))
|
||||||
AnyComponentWithIdentity(id: 1, component: AnyComponent(BotSectionSortButtonComponent(
|
if suggestedStarBotListItems.count > 1 {
|
||||||
|
suggestedHeaderItems.append(AnyComponentWithIdentity(id: 1, component: AnyComponent(BotSectionSortButtonComponent(
|
||||||
theme: environment.theme,
|
theme: environment.theme,
|
||||||
strings: environment.strings,
|
strings: environment.strings,
|
||||||
sortMode: self.suggestedSortMode,
|
sortMode: self.suggestedSortMode,
|
||||||
@ -1490,8 +1493,14 @@ If you end your affiliate program:
|
|||||||
}
|
}
|
||||||
self.openSortModeMenu(sourceView: sourceView)
|
self.openSortModeMenu(sourceView: sourceView)
|
||||||
}
|
}
|
||||||
)))
|
))))
|
||||||
], spacing: 4.0, alignment: .alternatingLeftRight)),
|
}
|
||||||
|
|
||||||
|
let suggestedProgramsSectionSize = self.suggestedProgramsSection.update(
|
||||||
|
transition: transition,
|
||||||
|
component: AnyComponent(ListSectionComponent(
|
||||||
|
theme: environment.theme,
|
||||||
|
header: AnyComponent(HStack(suggestedHeaderItems, spacing: 4.0, alignment: .alternatingLeftRight)),
|
||||||
footer: nil,
|
footer: nil,
|
||||||
items: suggestedSectionItems,
|
items: suggestedSectionItems,
|
||||||
displaySeparators: true
|
displaySeparators: true
|
||||||
@ -1506,22 +1515,15 @@ If you end your affiliate program:
|
|||||||
self.scrollView.addSubview(suggestedProgramsSectionView)
|
self.scrollView.addSubview(suggestedProgramsSectionView)
|
||||||
}
|
}
|
||||||
transition.setFrame(view: suggestedProgramsSectionView, frame: suggestedProgramsSectionFrame)
|
transition.setFrame(view: suggestedProgramsSectionView, frame: suggestedProgramsSectionFrame)
|
||||||
if !suggestedStarBotListItems.isEmpty {
|
|
||||||
suggestedProgramsSectionView.isHidden = false
|
|
||||||
} else {
|
|
||||||
suggestedProgramsSectionView.isHidden = true
|
|
||||||
}
|
|
||||||
|
|
||||||
suggestedProgramsSectionView.contentViewImpl.alpha = self.isSuggestedSortModeUpdating ? 0.6 : 1.0
|
suggestedProgramsSectionView.contentViewImpl.alpha = self.isSuggestedSortModeUpdating ? 0.6 : 1.0
|
||||||
suggestedProgramsSectionView.contentViewImpl.isUserInteractionEnabled = !self.isSuggestedSortModeUpdating
|
suggestedProgramsSectionView.contentViewImpl.isUserInteractionEnabled = !self.isSuggestedSortModeUpdating
|
||||||
}
|
}
|
||||||
if !suggestedStarBotListItems.isEmpty {
|
|
||||||
contentHeight += suggestedProgramsSectionSize.height
|
contentHeight += suggestedProgramsSectionSize.height
|
||||||
contentHeight += sectionSpacing
|
contentHeight += sectionSpacing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let contentSize = CGSize(width: availableSize.width, height: contentHeight)
|
let contentSize = CGSize(width: availableSize.width, height: contentHeight)
|
||||||
if self.scrollView.frame != CGRect(origin: CGPoint(), size: availableSize) {
|
if self.scrollView.frame != CGRect(origin: CGPoint(), size: availableSize) {
|
||||||
|
@ -637,7 +637,7 @@ private final class JoinAffiliateProgramScreenComponent: Component {
|
|||||||
))
|
))
|
||||||
),
|
),
|
||||||
AnyComponentWithIdentity(id: 1, component: AnyComponent(MultilineTextComponent(
|
AnyComponentWithIdentity(id: 1, component: AnyComponent(MultilineTextComponent(
|
||||||
text: .plain(NSAttributedString(string: "\(component.commissionPermille / 10)%", font: Font.regular(13.0), textColor: environment.theme.list.itemCheckColors.foregroundColor))
|
text: .plain(NSAttributedString(string: "\(formatPermille(component.commissionPermille))%", font: Font.regular(13.0), textColor: environment.theme.list.itemCheckColors.foregroundColor))
|
||||||
)))
|
)))
|
||||||
], spacing: 2.0)),
|
], spacing: 2.0)),
|
||||||
insets: UIEdgeInsets(top: 3.0, left: 6.0, bottom: 3.0, right: 6.0),
|
insets: UIEdgeInsets(top: 3.0, left: 6.0, bottom: 3.0, right: 6.0),
|
||||||
@ -766,7 +766,7 @@ private final class JoinAffiliateProgramScreenComponent: Component {
|
|||||||
contentHeight += linkIconBackgroundSize.height + 21.0
|
contentHeight += linkIconBackgroundSize.height + 21.0
|
||||||
}
|
}
|
||||||
|
|
||||||
let commissionTitle = "\(component.commissionPermille / 10)%"
|
let commissionTitle = "\(formatPermille(component.commissionPermille))%"
|
||||||
let durationTitle: String
|
let durationTitle: String
|
||||||
if let durationMonths = component.programDuration {
|
if let durationMonths = component.programDuration {
|
||||||
durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (24 * 60 * 60))
|
durationTitle = timeIntervalString(strings: environment.strings, value: durationMonths * (24 * 60 * 60))
|
||||||
|
@ -1445,12 +1445,12 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
|||||||
}
|
}
|
||||||
//TODO:localize
|
//TODO:localize
|
||||||
let programTitleValue: String
|
let programTitleValue: String
|
||||||
programTitleValue = "\(starRefProgram.commissionPermille / 10)%"
|
programTitleValue = "\(formatPermille(starRefProgram.commissionPermille))%"
|
||||||
//TODO:localize
|
//TODO:localize
|
||||||
items[.botAffiliateProgram]!.append(PeerInfoScreenDisclosureItem(id: 0, label: .labelBadge(programTitleValue), additionalBadgeLabel: nil, text: "Affiliate Program", icon: PresentationResourcesSettings.affiliateProgram, action: {
|
items[.botAffiliateProgram]!.append(PeerInfoScreenDisclosureItem(id: 0, label: .labelBadge(programTitleValue), additionalBadgeLabel: nil, text: "Affiliate Program", icon: PresentationResourcesSettings.affiliateProgram, action: {
|
||||||
interaction.editingOpenAffiliateProgram()
|
interaction.editingOpenAffiliateProgram()
|
||||||
}))
|
}))
|
||||||
items[.botAffiliateProgram]!.append(PeerInfoScreenCommentItem(id: 1, text: "Share a link to \(EnginePeer.user(user).compactDisplayTitle) with your friends and and earn \(starRefProgram.commissionPermille / 10)% of their spending there."))
|
items[.botAffiliateProgram]!.append(PeerInfoScreenCommentItem(id: 1, text: "Share a link to \(EnginePeer.user(user).compactDisplayTitle) with your friends and and earn \(formatPermille(starRefProgram.commissionPermille))% of their spending there."))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1963,7 +1963,7 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL
|
|||||||
//TODO:localize
|
//TODO:localize
|
||||||
let programTitleValue: PeerInfoScreenDisclosureItem.Label
|
let programTitleValue: PeerInfoScreenDisclosureItem.Label
|
||||||
if let cachedData = data.cachedData as? CachedUserData, let starRefProgram = cachedData.starRefProgram, starRefProgram.endDate == nil {
|
if let cachedData = data.cachedData as? CachedUserData, let starRefProgram = cachedData.starRefProgram, starRefProgram.endDate == nil {
|
||||||
programTitleValue = .labelBadge("\(starRefProgram.commissionPermille / 10)%")
|
programTitleValue = .labelBadge("\(formatPermille(starRefProgram.commissionPermille))%")
|
||||||
} else {
|
} else {
|
||||||
programTitleValue = .text("Off")
|
programTitleValue = .text("Off")
|
||||||
}
|
}
|
||||||
@ -8662,7 +8662,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
//TODO:localize
|
//TODO:localize
|
||||||
UIPasteboard.general.string = result.url
|
UIPasteboard.general.string = result.url
|
||||||
let presentationData = self.context.sharedContext.currentPresentationData.with({ $0 })
|
let presentationData = self.context.sharedContext.currentPresentationData.with({ $0 })
|
||||||
self.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(result.commissionPermille / 10)%** of what people who use it spend in **\(result.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
self.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(formatPermille(result.commissionPermille))%** of what people who use it spend in **\(result.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
@ -8695,7 +8695,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
}
|
}
|
||||||
UIPasteboard.general.string = result.url
|
UIPasteboard.general.string = result.url
|
||||||
let presentationData = self.context.sharedContext.currentPresentationData.with({ $0 })
|
let presentationData = self.context.sharedContext.currentPresentationData.with({ $0 })
|
||||||
self.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(result.commissionPermille / 10)%** of what people who use it spend in **\(result.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
self.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(title: "Link copied to clipboard", text: "Share this link and earn **\(formatPermille(result.commissionPermille))%** of what people who use it spend in **\(result.peer.compactDisplayTitle)**!"), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
))
|
))
|
||||||
|
@ -407,7 +407,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
|||||||
//TODO:localize
|
//TODO:localize
|
||||||
isRefProgram = true
|
isRefProgram = true
|
||||||
if transaction.starrefPeerId == nil {
|
if transaction.starrefPeerId == nil {
|
||||||
titleText = "\(starrefCommissionPermille / 10)% Commission"
|
titleText = "\(formatPermille(starrefCommissionPermille))% Commission"
|
||||||
} else {
|
} else {
|
||||||
titleText = transaction.title ?? "Product"
|
titleText = transaction.title ?? "Product"
|
||||||
}
|
}
|
||||||
@ -987,7 +987,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
|||||||
tableItems.append(.init(
|
tableItems.append(.init(
|
||||||
id: "commission",
|
id: "commission",
|
||||||
title: "Commission",
|
title: "Commission",
|
||||||
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: "\(starrefCommissionPermille / 10)%", font: tableFont, textColor: tableTextColor))
|
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: "\(formatPermille(starrefCommissionPermille))%", font: tableFont, textColor: tableTextColor))
|
||||||
)),
|
)),
|
||||||
insets: UIEdgeInsets(top: 0.0, left: 12.0, bottom: 0.0, right: 5.0)
|
insets: UIEdgeInsets(top: 0.0, left: 12.0, bottom: 0.0, right: 5.0)
|
||||||
))
|
))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user