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

New purchase flow buy course #1082

Merged
merged 21 commits into from
Dec 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 48 additions & 16 deletions Stepic.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions Stepic/Images.xcassets/CourseInfoPurchaseModal/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "CourseInfoPurchaseModalPurchaseFail.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "CourseInfoPurchaseModalPurchaseFailExclamationMark.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "CourseInfoPurchaseModalPurchaseSuccess.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
Binary file not shown.
2 changes: 1 addition & 1 deletion Stepic/Info-Develop.plist
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>390</string>
<string>391</string>
<key>FacebookAppID</key>
<string>171127739724012</string>
<key>FacebookDisplayName</key>
Expand Down
2 changes: 1 addition & 1 deletion Stepic/Info-Production.plist
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>390</string>
<string>391</string>
<key>FacebookAppID</key>
<string>171127739724012</string>
<key>FacebookDisplayName</key>
Expand Down
2 changes: 1 addition & 1 deletion Stepic/Info-Release.plist
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>390</string>
<string>391</string>
<key>FacebookAppID</key>
<string>171127739724012</string>
<key>FacebookDisplayName</key>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ extension Course {
}
}

var reviewSummaryId: Int? {
var reviewSummaryID: Int? {
get {
managedReviewSummaryId?.intValue
}
Expand Down Expand Up @@ -215,7 +215,7 @@ extension Course {
}
}

var progressId: String? {
var progressID: String? {
get {
managedProgressId
}
Expand All @@ -233,7 +233,7 @@ extension Course {
}
}

var lastStepId: String? {
var lastStepID: String? {
set(id) {
self.managedLastStepId = id
}
Expand Down
6 changes: 3 additions & 3 deletions Stepic/Legacy/Model/Entities/Course/Course.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,12 @@ final class Course: NSManagedObject, ManagedObject, IDFetchable {
self.audience = json[JSONKey.targetAudience.rawValue].stringValue
self.requirements = json[JSONKey.requirements.rawValue].stringValue
self.slug = json[JSONKey.slug.rawValue].string
self.progressId = json[JSONKey.progress.rawValue].string
self.lastStepId = json[JSONKey.lastStep.rawValue].string
self.progressID = json[JSONKey.progress.rawValue].string
self.lastStepID = json[JSONKey.lastStep.rawValue].string
self.scheduleType = json[JSONKey.scheduleType.rawValue].string
self.learnersCount = json[JSONKey.learnersCount.rawValue].int
self.totalUnits = json[JSONKey.totalUnits.rawValue].intValue
self.reviewSummaryId = json[JSONKey.reviewSummary.rawValue].int
self.reviewSummaryID = json[JSONKey.reviewSummary.rawValue].int
self.sectionsArray = json[JSONKey.sections.rawValue].arrayObject as! [Int]
self.instructorsArray = json[JSONKey.instructors.rawValue].arrayObject as! [Int]
self.authorsArray = json[JSONKey.authors.rawValue].arrayObject as? [Int] ?? []
Expand Down
18 changes: 16 additions & 2 deletions Stepic/Legacy/Model/PlainObjects/CoursePayment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ final class CoursePayment: JSONSerializable {
var isPaid = false
var data: Data?
var paymentProviderStringValue: String = PaymentProvider.apple.rawValue
var promoCode: String?

var status: Status? {
Status(rawValue: self.statusStringValue)
Expand All @@ -35,13 +36,23 @@ final class CoursePayment: JSONSerializable {
dict[JSONKey.data.rawValue] = JSON(data)
}

if let promoCode = self.promoCode {
dict[JSONKey.promoCode.rawValue] = JSON(promoCode)
}

return dict
}

init(courseID: Course.IdType, data: Data, paymentProvider: PaymentProvider = .apple) {
init(
courseID: Course.IdType,
data: Data,
paymentProvider: PaymentProvider = .apple,
promoCode: String?
) {
self.courseID = courseID
self.data = data
self.paymentProviderStringValue = paymentProvider.rawValue
self.promoCode = promoCode
}

init(json: JSON) {
Expand All @@ -58,6 +69,7 @@ final class CoursePayment: JSONSerializable {
self.isPaid = json[JSONKey.isPaid.rawValue].boolValue
self.data = json[JSONKey.data.rawValue].dictionaryObject
self.paymentProviderStringValue = json[JSONKey.paymentProvider.rawValue].stringValue
self.promoCode = json[JSONKey.promoCode.rawValue].string
}

enum Status: String {
Expand Down Expand Up @@ -99,6 +111,7 @@ final class CoursePayment: JSONSerializable {
case isPaid = "is_paid"
case data = "data"
case paymentProvider = "payment_provider"
case promoCode = "promo_code"
}
}

Expand All @@ -113,7 +126,8 @@ extension CoursePayment: CustomStringConvertible {
statusStringValue: \(self.statusStringValue), \
isPaid: \(self.isPaid), \
data: \(String(describing: self.data)), \
paymentProviderStringValue: \(self.paymentProviderStringValue))
paymentProviderStringValue: \(self.paymentProviderStringValue), \
promoCode: \(String(describing: self.promoCode)))
"""
}
}
27 changes: 26 additions & 1 deletion Stepic/Legacy/Model/RemoteConfig/RemoteConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ final class RemoteConfig {

private static let defaultCoursePurchaseFlowType = CoursePurchaseFlowType.web

private static let defaultPurchaseFlowDisclaimerRussian = """
В цену включена комиссия App Store и НДС. Оплачивая доступ к этому курсу вы соглашаетесь с условиями \
<a href=\"https://welcome.stepik.org/ru/payment-terms\">пользовательского соглашения</a>.
"""
private static let defaultPurchaseFlowDisclaimerEnglish = """
The price includes commission from App Store and VAT. By paying for access to this course you agree to the \
<a href=\"https://welcome.stepik.org/en/payment-terms\">user agreement</a>.
"""

static let shared = RemoteConfig(delegate: DebugRemoteConfig.shared)

weak var delegate: RemoteConfigDelegate?
Expand All @@ -30,7 +39,9 @@ final class RemoteConfig {
Key.searchResultsQueryParams.rawValue: NSDictionary(dictionary: ["is_popular": "true", "is_public": "true"]),
Key.isCoursePricesEnabled.rawValue: NSNumber(value: false),
Key.isCourseRevenueAvailable.rawValue: NSNumber(value: false),
Key.purchaseFlow.rawValue: NSString(string: Self.defaultCoursePurchaseFlowType.rawValue)
Key.purchaseFlow.rawValue: NSString(string: Self.defaultCoursePurchaseFlowType.rawValue),
Key.purchaseFlowDisclaimerRussian.rawValue: NSString(string: Self.defaultPurchaseFlowDisclaimerRussian),
Key.purchaseFlowDisclaimerEnglish.rawValue: NSString(string: Self.defaultPurchaseFlowDisclaimerEnglish)
]

var showStreaksNotificationTrigger: ShowStreaksNotificationTrigger {
Expand Down Expand Up @@ -100,6 +111,16 @@ final class RemoteConfig {
return Self.defaultCoursePurchaseFlowType
}

var purchaseFlowDisclaimer: String {
if Locale.current.languageCode == "ru" {
return self.getStringValueFromDelegateOrRemoteConfigForKey(.purchaseFlowDisclaimerRussian)
?? Self.defaultPurchaseFlowDisclaimerRussian
} else {
return self.getStringValueFromDelegateOrRemoteConfigForKey(.purchaseFlowDisclaimerEnglish)
?? Self.defaultPurchaseFlowDisclaimerEnglish
}
}

init(delegate: RemoteConfigDelegate? = nil) {
self.delegate = delegate

Expand Down Expand Up @@ -212,6 +233,8 @@ final class RemoteConfig {
case isCoursePricesEnabled = "is_course_prices_enabled_ios"
case isCourseRevenueAvailable = "is_course_revenue_available_ios"
case purchaseFlow = "purchase_flow_ios"
case purchaseFlowDisclaimerRussian = "purchase_flow_ios_disclaimer_ru"
case purchaseFlowDisclaimerEnglish = "purchase_flow_ios_disclaimer_en"

var valueDataType: ValueDataType {
switch self {
Expand All @@ -231,6 +254,8 @@ final class RemoteConfig {
return .string
case .purchaseFlow:
return .string
case .purchaseFlowDisclaimerRussian, .purchaseFlowDisclaimerEnglish:
return .string
}
}

Expand Down
2 changes: 1 addition & 1 deletion Stepic/Legacy/Services/CourseSubscriber.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ final class CourseSubscriber: CourseSubscriberProtocol {
) -> Promise<Course> {
Promise<Course> { seal in
_ = ApiDataDownloader.enrollments.joinCourse(course, delete: unsubscribe, success: { [weak self] in
guard let progressID = course.progressId else {
guard let progressID = course.progressID else {
seal.reject(CourseSubscriptionError.badResponseFormat)
return
}
Expand Down
2 changes: 1 addition & 1 deletion Stepic/Legacy/TransitionRouters/LastStepRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ final class LastStepRouter {
}

guard course.canContinue,
let lastStepID = course.lastStepId else {
let lastStepID = course.lastStepID else {
return self.fallbackToSyllabus(
courseID: course.id,
courseViewSource: viewSource,
Expand Down
8 changes: 6 additions & 2 deletions Stepic/Sources/Controllers/ContactSupportController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ import SVProgressHUD
import UIKit

final class ContactSupportController: NSObject {
private let subject: String

private weak var presentationController: UIViewController?
private let userAccountService: UserAccountServiceProtocol

init(
subject: String = NSLocalizedString("ContactSupportSubject", comment: ""),
presentationController: UIViewController,
userAccountService: UserAccountServiceProtocol
userAccountService: UserAccountServiceProtocol = UserAccountService()
) {
self.subject = subject
self.presentationController = presentationController
self.userAccountService = userAccountService
}
Expand All @@ -23,7 +27,7 @@ final class ContactSupportController: NSObject {
mailComposeViewController.mailComposeDelegate = self

mailComposeViewController.setToRecipients(["support@stepik.org"])
mailComposeViewController.setSubject(NSLocalizedString("ContactSupportSubject", comment: ""))
mailComposeViewController.setSubject(self.subject)
mailComposeViewController.setMessageBody(self.makeMessageBody(), isHTML: false)

self.presentationController?.present(mailComposeViewController, animated: true)
Expand Down
36 changes: 36 additions & 0 deletions Stepic/Sources/Controllers/PanModalPresentableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,32 @@ class PanModalPresentableViewController: UIViewController, PanModalPresentable {
return .contentHeight(scrollView.contentSize.height)
}

var cornerRadius: CGFloat { 8.0 }

var springDamping: CGFloat { 0.8 }

var transitionAnimationOptions: UIView.AnimationOptions {
[.curveEaseInOut, .allowUserInteraction, .beginFromCurrentState]
}

var panModalBackgroundColor: UIColor { .black.withAlphaComponent(0.7) }

var dragIndicatorBackgroundColor: UIColor { .lightGray }

var anchorModalToLongForm: Bool { false }

var allowsDragToDismiss: Bool { true }

var allowsTapToDismiss: Bool { true }

var isUserInteractionEnabled: Bool { true }

var isHapticFeedbackEnabled: Bool { true }

var shouldRoundTopCorners: Bool { self.isPanModalPresented }

var showDragIndicator: Bool { self.shouldRoundTopCorners }

var isShortFormEnabled = true

var currentPresentationState: PanModalPresentationController.PresentationState?
Expand Down Expand Up @@ -50,6 +74,14 @@ class PanModalPresentableViewController: UIViewController, PanModalPresentable {
)
}

func shouldRespond(to panModalGestureRecognizer: UIPanGestureRecognizer) -> Bool { true }

func willRespond(to panModalGestureRecognizer: UIPanGestureRecognizer) {}

func shouldTransition(to state: PanModalPresentationController.PresentationState) -> Bool { true }

func shouldPrioritize(panModalGestureRecognizer: UIPanGestureRecognizer) -> Bool { false }

func willTransition(to state: PanModalPresentationController.PresentationState) {
self.currentPresentationState = state

Expand All @@ -62,6 +94,10 @@ class PanModalPresentableViewController: UIViewController, PanModalPresentable {
self.panModalSetNeedsLayoutUpdate()
}

func panModalWillDismiss() {}

func panModalDidDismiss() {}

private func updateAdditionalSafeAreaInsets() {
self.additionalSafeAreaInsets = UIApplication.shared.delegate?.window??.safeAreaInsets ?? .zero
}
Expand Down
Binary file modified Stepic/Sources/Frameworks/InAppPurchases/IAPPaymentsCache.swift
Binary file not shown.
Loading