Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MBL-1288] Update pledge CTA #2000

Merged
merged 8 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ final class PledgeViewCTAContainerView: UIView {

private lazy var termsTextView: UITextView = { UITextView(frame: .zero) |> \.delegate .~ self }()

private lazy var pledgeImmediatelyLabel: UILabel = {
UILabel(frame: .zero)
|> \.translatesAutoresizingMaskIntoConstraints .~ false
}()

private lazy var disclaimerStackView: UIStackView = {
UIStackView(frame: .zero)
|> \.translatesAutoresizingMaskIntoConstraints .~ false
Expand Down Expand Up @@ -84,6 +89,10 @@ final class PledgeViewCTAContainerView: UIView {
_ = self.termsTextView
|> termsTextViewStyle

self.pledgeImmediatelyLabel.attributedText = pledgeImmediatelyText()
self.pledgeImmediatelyLabel.numberOfLines = 0
self.pledgeImmediatelyLabel.textAlignment = .center

_ = self.disclaimerStackView
|> disclaimerStackViewStyle

Expand Down Expand Up @@ -139,6 +148,8 @@ final class PledgeViewCTAContainerView: UIView {
self.submitButton.rac.hidden = self.viewModel.outputs.submitButtonIsHidden
self.submitButton.rac.title = self.viewModel.outputs.submitButtonTitle
self.submitButton.rac.enabled = self.viewModel.outputs.submitButtonIsEnabled

self.pledgeImmediatelyLabel.rac.hidden = self.viewModel.outputs.pledgeImmediatelyLabelIsHidden
}

// MARK: - Configuration
Expand All @@ -157,7 +168,7 @@ final class PledgeViewCTAContainerView: UIView {
_ = ([self.continueButton, self.submitButton, self.applePayButton], self.ctaStackView)
|> ksr_addArrangedSubviewsToStackView()

_ = ([self.termsTextView], self.disclaimerStackView)
_ = ([self.pledgeImmediatelyLabel, self.termsTextView], self.disclaimerStackView)
|> ksr_addArrangedSubviewsToStackView()

_ = ([self.ctaStackView, self.disclaimerStackView], self.rootStackView)
Expand Down Expand Up @@ -241,7 +252,8 @@ private let ctaStackViewStyle: StackViewStyle = { stackView in

private let disclaimerStackViewStyle: StackViewStyle = { stackView in
stackView
|> \.axis .~ .horizontal
|> \.axis .~ .vertical
|> \.spacing .~ Styles.grid(2)
|> \.layoutMargins .~ UIEdgeInsets.init(
top: Styles.grid(0),
left: Styles.grid(5),
Expand Down Expand Up @@ -292,3 +304,55 @@ private func attributedTermsText() -> NSAttributedString? {

return checkoutAttributedLink(with: string)
}

private func pledgeImmediatelyText() -> NSAttributedString? {
let rawText = Strings.Your_payment_method_will_be_charged()

guard let text = try? NSMutableAttributedString(
data: Data(rawText.utf8),
options: [
.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue
],
documentAttributes: nil
) else {
return nil
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will the helper method simpleHtmlAttributedString do what you need, here? Or is the custom implementation required?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh nice find! I looked for something like this but clearly not hard enough - I really wasn't expecting us to already handle strings like this.


let attributes: String.Attributes = [
.font: UIFont.ksr_caption2(),
.foregroundColor: UIColor.ksr_support_400
]

let fullRange = (text.string as NSString).range(of: text.string)
text.addAttributes(attributes, range: fullRange)

let boldRanges = getBoldRangesFromHtmlTags(plainString: text.string, htmlString: rawText)
for range in boldRanges {
text.addAttribute(.font, value: UIFont.ksr_caption2().bolded, range: range)
}

return text
}

private func getBoldRangesFromHtmlTags(plainString: String, htmlString: String) -> [NSRange] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This should live in String+SimpleHTML or another utility file, feels too general purpose for the pledge container. (If it doesn't already exist elsewhere).

let stringWithoutHtml = plainString as NSString
var boldRanges: [NSRange] = []

var currentString = htmlString as NSString
while currentString.contains("<b>") {
let startTagRange = currentString.range(of: "<b>")
let endTagRange = currentString.range(of: "</b>")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: will this code break/infinite loop if there's no closing </b>?


// Calculate range of bolded text in the string without html tags.
let location = startTagRange.location
let length = endTagRange.location - (location + startTagRange.length)
let toBold = NSRange(location: location, length: length)
boldRanges.append(toBold)

let processedSubstring = stringWithoutHtml.substring(to: toBold.location + toBold.length)
let remainingHtml = currentString.substring(from: endTagRange.location + endTagRange.length)
currentString = (processedSubstring + remainingHtml) as NSString
}
return boldRanges
}
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ final class RewardAddOnSelectionViewController: UIViewController {
.observeValues { [weak self] data in
guard let self else { return }

if featurePostCampaignPledgeEnabled(), data.project.isInPostCampaignPledgingPhase {
if data.context == .latePledge {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice 👍

self.goToConfirmDetails(data: data)
} else {
self.goToPledge(data: data)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ final class RewardsCollectionViewController: UICollectionViewController {
.observeValues { [weak self] data in
guard let self else { return }

if featurePostCampaignPledgeEnabled(), data.project.isInPostCampaignPledgingPhase {
if data.context == .latePledge {
self.goToConfirmDetails(data: data)
} else {
self.goToPledge(data: data)
Expand Down
1 change: 1 addition & 0 deletions Kickstarter-iOS/Locales/Base.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,7 @@
"Your_message_has_been_sent" = "Your message has been sent!";
"Your_name_displayed" = "Your name is always displayed on your profile.";
"Your_payment_method_was_successfully_charged" = "Your payment method was successfully charged.";
"Your_payment_method_will_be_charged" = "Your payment method will be <b>charged immediately</b> upon pledge. Your pledge cannot be <b>canceled or modified</b>.";
"Your_payment_method_will_be_charged_immediately" = "Your payment method will be charged immediately upon pledge and you’ll receive a confirmation email at %{user_email}. Your pledge cannot be canceled or modified.";
"Your_pledge" = "Your pledge";
"Your_pledge_amount" = "Your pledge amount";
Expand Down
11 changes: 6 additions & 5 deletions Kickstarter-iOS/Locales/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
"Check_out_these_handpicked_projects" = "Sieh dir dieses speziell für dich ausgesuchten Projekte an.";
"Check_your_inbox_to_complete_this_simple_step" = "Sieh bitte in deinem Posteingang nach und schließe diesen einfachen Schritt ab.";
"Check_your_payment_details" = "Überprüfe die Daten deiner Zahlungsweise";
"Checkout" = "Checkout";
"Checkout" = "Kasse";
"Choose_another_reward" = "Andere Belohnung auswählen";
"Chooses_location_for_shipping" = "Legt %{location} als Versandort fest.";
"Chosen_just_for_you" = "Speziell für dich ausgewählt";
Expand All @@ -126,7 +126,7 @@
"Complete_payment" = "Zahlung abschließen";
"Confirm" = "Bestätigen";
"Confirm_password" = "Neues Passwort bestätigen";
"Confirm_your_pledge_details" = "Confirm your pledge details";
"Confirm_your_pledge_details" = "Bestätige die Details zu deinem Finanzierungsbeitrag";
"Connect_with_Facebook_to_follow_friends_and_get_notified" = "Verknüpfe dein Konto mit Facebook - du kannst deinen Freunden folgen und wirst benachrichtigt, sobald sie ein Projekt veröffentlichen oder unterstützen.";
"Contact_backer" = "Unterstützer kontaktieren";
"Contact_creator" = "Projektgründer kontaktieren";
Expand Down Expand Up @@ -596,7 +596,7 @@
"Select_this_reward" = "Diese Belohnung wählen";
"Select_this_reward_instead" = "Diese Belohnung auswählen";
"Select_up_to_five" = "Wähle bis zu fünf aus den unten stehenden Optionen aus.";
"Select_your_reward" = "Select your reward";
"Select_your_reward" = "Belohnung auswählen";
"Selected" = "Ausgewählt";
"Selected_card" = "Ausgewählte Karte";
"Selected_reward" = "Gewählte Belohnung";
Expand Down Expand Up @@ -800,7 +800,7 @@
"You_canceled_your_pledge_for_this_project" = "Du hast den Finanzierungsbeitrag für dieses Projekt zurückgezogen.";
"You_cant_use_this_credit_card_to_back_a_project_from_project_country" = "Diese Karte kann nicht verwendet werden, um ein Projekt aus dem folgenden Land zu unterstützen: %{project_country}.";
"You_have_successfully_backed_project_html" = "Dank deiner Unterstützung ist <b>%{project_name}</b> seiner Verwirklichung einen Schritt näher. Sag es weiter!";
"You_have_successfully_pledged_to_project_post_campaign_html" = "<p>You have successfully pledged to <b>%{project_name}</b>. Your pledge of <b>%{pledge_total}</b> has been collected.</p>\n<p>You’ll receive a confirmation email at %{user_email} when your rewards are ready to fulfill so that you can finalize and pay shipping and tax.</p>\n<p>This project is now one step closer to a reality, thanks to you. Spread the word!</p>";
"You_have_successfully_pledged_to_project_post_campaign_html" = "<p>Du hast <b>%{project_name}</b> mit deinem Beitrag erfolgreich unterstützt. Dein Beitrag in Höhe von <b>%{pledge_total}</b> wurde eingezogen.</p>\n<p>Du erhältst eine E-Mail an %{user_email}, wenn deine Belohnungen zur Erfüllung bereit sind, damit du alles finalisieren und für Versand und Steuern zahlen kannst.</p>\n<p>Dank dir ist dieses Projekt seiner Realisierung einen Schritt nähergekommen. Erzähl auch deinen Freunden und Bekannten davon!</p>";
"You_launched_this_project_on_launch_date" = "Du hast dieses Projekt am %{launch_date} veröffentlicht. Tools für Projektgründer findest du auf unserer Website.";
"You_need_to_pledge_at_least_reward_minimum_for_this_reward" = "Diese Belohnung hat einen Mindestfinanzierungsbeitrag von %{reward_minimum}.";
"You_pledged_on_date" = "<b>Finanzierungsbeitrag geleistet</b> im %{pledge_date}";
Expand All @@ -815,7 +815,8 @@
"Your_message_has_been_sent" = "Deine Nachricht wurde versandt!";
"Your_name_displayed" = "Dein Name wird auf deinem Profil angezeigt.";
"Your_payment_method_was_successfully_charged" = "Deine Zahlungsmethode wurde erfolgreich belastet.";
"Your_payment_method_will_be_charged_immediately" = "Your payment method will be charged immediately upon pledge and you’ll receive a confirmation email at %{user_email}. Your pledge cannot be canceled or modified.";
"Your_payment_method_will_be_charged" = "Your payment method will be <b>charged immediately</b> upon pledge. Your pledge cannot be <b>canceled or modified</b>.";
"Your_payment_method_will_be_charged_immediately" = "Deine Zahlungsmethode wird umgehend belastet und du erhältst eine Bestätigungs-E-Mail an %{user_email}. Dein Beitrag kann nicht storniert oder geändert werden.";
"Your_pledge" = "Dein Beitrag";
"Your_pledge_amount" = "Dein Beitrag:";
"Your_pledge_details" = "Einzelheiten deines Beitrags";
Expand Down
11 changes: 6 additions & 5 deletions Kickstarter-iOS/Locales/es.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
"Check_out_these_handpicked_projects" = "Echa un vistazo a estos proyectos seleccionados exclusivamente para ti.";
"Check_your_inbox_to_complete_this_simple_step" = "Revisa tu bandeja de entrada para completar este simple paso.";
"Check_your_payment_details" = "Revisa tu información de pago";
"Checkout" = "Checkout";
"Checkout" = "Pago";
"Choose_another_reward" = "Elegir otra recompensa";
"Chooses_location_for_shipping" = "Destino determinado: %{location}.";
"Chosen_just_for_you" = "Elegidos especialmente para ti";
Expand All @@ -126,7 +126,7 @@
"Complete_payment" = "Completar pago";
"Confirm" = "Confirmar";
"Confirm_password" = "Confirmar nueva contraseña";
"Confirm_your_pledge_details" = "Confirm your pledge details";
"Confirm_your_pledge_details" = "Confirma los datos de tu contribución";
"Connect_with_Facebook_to_follow_friends_and_get_notified" = "Si te conectas via Facebook puedes seguir a tus amigos y te avisaremos cada vez que publican o patrocinan un proyecto.";
"Contact_backer" = "Contacta al patrocinador";
"Contact_creator" = "Comunicarse con el creador";
Expand Down Expand Up @@ -596,7 +596,7 @@
"Select_this_reward" = "Seleccionar esta recompensa";
"Select_this_reward_instead" = "Selecciona esta recompensa";
"Select_up_to_five" = "Selecciona hasta cinco de las opciones que aparecen a continuación.";
"Select_your_reward" = "Select your reward";
"Select_your_reward" = "Selecciona tu recompensa";
"Selected" = "Seleccionada";
"Selected_card" = "Tarjeta seleccionada";
"Selected_reward" = "Recompensa seleccionada";
Expand Down Expand Up @@ -800,7 +800,7 @@
"You_canceled_your_pledge_for_this_project" = "Has cancelado tu contribución a este proyecto.";
"You_cant_use_this_credit_card_to_back_a_project_from_project_country" = "No puedes usar esta tarjeta de crédito para patrocinar un proyecto de %{project_country}.";
"You_have_successfully_backed_project_html" = "Has patrocinado <b>%{project_name}</b> con éxito. Gracias a ti, este proyecto está ahora un paso más cerca de hacerse realidad. ¡Corre la voz!";
"You_have_successfully_pledged_to_project_post_campaign_html" = "<p>You have successfully pledged to <b>%{project_name}</b>. Your pledge of <b>%{pledge_total}</b> has been collected.</p>\n<p>You’ll receive a confirmation email at %{user_email} when your rewards are ready to fulfill so that you can finalize and pay shipping and tax.</p>\n<p>This project is now one step closer to a reality, thanks to you. Spread the word!</p>";
"You_have_successfully_pledged_to_project_post_campaign_html" = "<p>Has patrocinado <b>%{project_name}</b> con éxito y tu contribución por <b>%{pledge_total}</b> se ha recaudado.</p>\n<p>Recibirás la confirmación en %{user_email} cuando estemos por entregarte las recompensas para que puedas pagar los costos de envío e impuestos.</p>\n<p>Gracias a ti, este proyecto está ahora un paso más cerca de hacerse realidad. ¡Ayuda a correr la voz!</p>";
"You_launched_this_project_on_launch_date" = "Publicaste el proyecto el %{launch_date}. Encuentra las herramientas para creadores en nuestro sitio web.";
"You_need_to_pledge_at_least_reward_minimum_for_this_reward" = "Debes contribuir, al menos, %{reward_minimum} para obtener esta recompensa.";
"You_pledged_on_date" = "<b>Contribuiste</b> el %{pledge_date}";
Expand All @@ -815,7 +815,8 @@
"Your_message_has_been_sent" = "Se envió tu mensaje.";
"Your_name_displayed" = "Tu nombre siempre se muestra en tu perfil.";
"Your_payment_method_was_successfully_charged" = "Se efectuó el cargo a tu método de pago.";
"Your_payment_method_will_be_charged_immediately" = "Your payment method will be charged immediately upon pledge and you’ll receive a confirmation email at %{user_email}. Your pledge cannot be canceled or modified.";
"Your_payment_method_will_be_charged" = "Your payment method will be <b>charged immediately</b> upon pledge. Your pledge cannot be <b>canceled or modified</b>.";
"Your_payment_method_will_be_charged_immediately" = "Al hacer la contribución, se hará el cargo inmediatamente a tu método de pago y recibirás un correo electrónico de confirmación en %{user_email}. Tu contribución no puede cancelarse ni modificarse.";
"Your_pledge" = "Tu contribución";
"Your_pledge_amount" = "Monto de tu contribución:";
"Your_pledge_details" = "Los detalles de tu contribución";
Expand Down
1 change: 1 addition & 0 deletions Kickstarter-iOS/Locales/fr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,7 @@
"Your_message_has_been_sent" = "Votre message a été envoyé.";
"Your_name_displayed" = "Votre nom s'affichera toujours sur votre profil.";
"Your_payment_method_was_successfully_charged" = "Votre moyen de paiement a bien été débité.";
"Your_payment_method_will_be_charged" = "Your payment method will be <b>charged immediately</b> upon pledge. Your pledge cannot be <b>canceled or modified</b>.";
"Your_payment_method_will_be_charged_immediately" = "La somme sera immédiatement prélevée sur votre moyen de paiement et vous recevrez une confirmation à l'adresse %{user_email}. Cet engagement ne pourra être ni annulé, ni modifié.";
"Your_pledge" = "Mon engagement";
"Your_pledge_amount" = "Montant engagé :";
Expand Down
11 changes: 6 additions & 5 deletions Kickstarter-iOS/Locales/ja.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
"Check_out_these_handpicked_projects" = "あなたにピッタリの Kickstarter イチオシのプロジェクトをご覧ください。";
"Check_your_inbox_to_complete_this_simple_step" = "メールの受信箱をチェックしてこの簡単手続きを完了してください。";
"Check_your_payment_details" = "お支払い情報をご確認ください";
"Checkout" = "Checkout";
"Checkout" = "チェックアウト";
"Choose_another_reward" = "他のリワードを選択";
"Chooses_location_for_shipping" = "配送先%{location} を選択";
"Chosen_just_for_you" = "あなたのために選びました";
Expand All @@ -126,7 +126,7 @@
"Complete_payment" = "支払いを完了";
"Confirm" = "確定する";
"Confirm_password" = "新しいパスワードの確認";
"Confirm_your_pledge_details" = "Confirm your pledge details";
"Confirm_your_pledge_details" = "プレッジの詳細を確認";
"Connect_with_Facebook_to_follow_friends_and_get_notified" = "Facebookとリンクさせ、友達がプロジェクトを作成したりバックしたりした際に通知を受け取る";
"Contact_backer" = "バッカーに連絡する";
"Contact_creator" = "クリエイターに連絡";
Expand Down Expand Up @@ -596,7 +596,7 @@
"Select_this_reward" = "このリワードを選ぶ";
"Select_this_reward_instead" = "このリワードを選択";
"Select_up_to_five" = "以下のオプションから最大5つをお選びください。";
"Select_your_reward" = "Select your reward";
"Select_your_reward" = "リワードの選択";
"Selected" = "選択済み";
"Selected_card" = "選択済みのカード";
"Selected_reward" = "選択したリワード";
Expand Down Expand Up @@ -800,7 +800,7 @@
"You_canceled_your_pledge_for_this_project" = "このプロジェクトのプレッジはキャンセルされました。";
"You_cant_use_this_credit_card_to_back_a_project_from_project_country" = "%{project_country} のプロジェクトをバックするのにこのクレジットカードを利用することはできません。";
"You_have_successfully_backed_project_html" = "<b>%{project_name}</b>へのバックが完了しました。このプロジェクトは、成功に一歩近づきました!ありがとうございます。";
"You_have_successfully_pledged_to_project_post_campaign_html" = "<p>You have successfully pledged to <b>%{project_name}</b>. Your pledge of <b>%{pledge_total}</b> has been collected.</p>\n<p>You’ll receive a confirmation email at %{user_email} when your rewards are ready to fulfill so that you can finalize and pay shipping and tax.</p>\n<p>This project is now one step closer to a reality, thanks to you. Spread the word!</p>";
"You_have_successfully_pledged_to_project_post_campaign_html" = "<p><b>%{project_name}</b>にプレッジしました。これに伴い、<b>%{pledge_total}</b>のプレッジが収集されました。</p>\n<p>リワード配送の準備が整い次第、%{user_email} 宛てに確認メールが届き、配送料と税金の最終確認とお支払いを行うことができます。</p>\n<p>あなたのプレッジのおかげで、このプロジェクトが実現へと一歩近づきました。ありがとうございます。ぜひこのプロジェクトを沢山の人に知ってもらいましょう!</p>";
"You_launched_this_project_on_launch_date" = "%{launch_date} にこのプロジェクトをローンチしました。クリエイター向けツールにアクセスするには、Kickstarter ウェブサイトにアクセスしてください!";
"You_need_to_pledge_at_least_reward_minimum_for_this_reward" = "このリワードには、最低%{reward_minimum}のプレッジが必要です。";
"You_pledged_on_date" = "%{pledge_date} に<b>プレッジ</b>";
Expand All @@ -815,7 +815,8 @@
"Your_message_has_been_sent" = "メッセージが送信されました!";
"Your_name_displayed" = "あなたの名前はプロフィールに常に表示されます。";
"Your_payment_method_was_successfully_charged" = "支払方法の登録完了。";
"Your_payment_method_will_be_charged_immediately" = "Your payment method will be charged immediately upon pledge and you’ll receive a confirmation email at %{user_email}. Your pledge cannot be canceled or modified.";
"Your_payment_method_will_be_charged" = "Your payment method will be <b>charged immediately</b> upon pledge. Your pledge cannot be <b>canceled or modified</b>.";
"Your_payment_method_will_be_charged_immediately" = "お支払い方法にはプレッジ時にただちに請求が行われ、その確認メールが %{user_email} 宛てに送られます。プレッジをキャンセルまたは変更することはできません。";
"Your_pledge" = "プレッジ";
"Your_pledge_amount" = "プレッジ額:";
"Your_pledge_details" = "プレッジの詳細";
Expand Down