Skip to content

Commit

Permalink
Initial implementation of referrals
Browse files Browse the repository at this point in the history
  • Loading branch information
leathalman committed May 23, 2022
1 parent 9412d6e commit 513b7fa
Show file tree
Hide file tree
Showing 89 changed files with 25,691 additions and 17,786 deletions.
8 changes: 8 additions & 0 deletions Jotify.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
F6B9D4CA25B629C800A0446C /* Double+Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6B9D4C925B629C800A0446C /* Double+Date.swift */; };
F6C06D542837108B005AED28 /* DetailOnboardingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6C06D532837108B005AED28 /* DetailOnboardingController.swift */; };
F6C06D5628371416005AED28 /* WelcomeViewOnboardingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6C06D5528371416005AED28 /* WelcomeViewOnboardingController.swift */; };
F6C06D58283833A8005AED28 /* ReferralManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6C06D57283833A8005AED28 /* ReferralManager.swift */; };
F6C06D5A283B0E23005AED28 /* ReferralSettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6C06D59283B0E23005AED28 /* ReferralSettingsController.swift */; };
F6CF5DDF25DAEF2F006E576E /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6CF5DDE25DAEF2F006E576E /* CloudKit.framework */; };
F6CF5DF325DAF38D006E576E /* Jotify.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = F6CF5DF125DAF38D006E576E /* Jotify.xcdatamodeld */; };
F6D2771225C8C00E00ECFCCC /* SettingsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6D2771125C8C00E00ECFCCC /* SettingsCell.swift */; };
Expand Down Expand Up @@ -168,6 +170,8 @@
F6B9D4C925B629C800A0446C /* Double+Date.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+Date.swift"; sourceTree = "<group>"; };
F6C06D532837108B005AED28 /* DetailOnboardingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailOnboardingController.swift; sourceTree = "<group>"; };
F6C06D5528371416005AED28 /* WelcomeViewOnboardingController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomeViewOnboardingController.swift; sourceTree = "<group>"; };
F6C06D57283833A8005AED28 /* ReferralManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReferralManager.swift; sourceTree = "<group>"; };
F6C06D59283B0E23005AED28 /* ReferralSettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReferralSettingsController.swift; sourceTree = "<group>"; };
F6CF5DDC25DAEF2B006E576E /* Jotify.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Jotify.entitlements; sourceTree = "<group>"; };
F6CF5DDE25DAEF2F006E576E /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; };
F6CF5DF225DAF38D006E576E /* Jotify.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Jotify.xcdatamodel; sourceTree = "<group>"; };
Expand Down Expand Up @@ -241,6 +245,7 @@
F67F002925B32F5B00313D61 /* NoteCollection.swift */,
F67F002625B32EEC00313D61 /* DataManager.swift */,
F67F002325B32EE600313D61 /* AuthManager.swift */,
F6C06D57283833A8005AED28 /* ReferralManager.swift */,
);
path = Firebase;
sourceTree = "<group>";
Expand Down Expand Up @@ -442,6 +447,7 @@
F61580172697D3BA00ABB6F6 /* GeneralSettingsController.swift */,
F67AA6CF2783E6FB004BD86E /* CustomizationSettingsController.swift */,
F6DFF0C525C8FF9D004D6468 /* AccountSettingsController.swift */,
F6C06D59283B0E23005AED28 /* ReferralSettingsController.swift */,
);
path = Settings;
sourceTree = "<group>";
Expand Down Expand Up @@ -611,6 +617,7 @@
F62209442602B07A001DFAC1 /* SceneDelegate+Gestures.swift in Sources */,
F69389E32699183E00EF3EED /* SetupController.swift in Sources */,
F67F003825B32F7900313D61 /* NoteCollectionController.swift in Sources */,
F6C06D58283833A8005AED28 /* ReferralManager.swift in Sources */,
F680C9CD269A957000D86EF3 /* ReminderController.swift in Sources */,
F6A5F9462604E5F200E46105 /* DismissKeyboardSwiftUI.swift in Sources */,
F678330E2640F4D6005429FF /* NoteCollectionController+Search.swift in Sources */,
Expand All @@ -624,6 +631,7 @@
F69389D42699158A00EF3EED /* RecentNoteWidget.intentdefinition in Sources */,
F6CF5DF325DAF38D006E576E /* Jotify.xcdatamodeld in Sources */,
F622093D2602B00E001DFAC1 /* LogInView.swift in Sources */,
F6C06D5A283B0E23005AED28 /* ReferralSettingsController.swift in Sources */,
F6F185B225C86ABF001FD5FA /* MasterSettingsController.swift in Sources */,
F66F5C4B267FE3BD004CB9F1 /* GradientAnimator.swift in Sources */,
F6425CC12680D286008C03A2 /* UIColor+StringInterpretor.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<key>RecentNoteWidgetExtension.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>30</integer>
<integer>31</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@ class AuthenticationController: UIViewController {
} else {
AnalyticsManager.logEvent(named: "sign_up", description: "sign_up")
DataManager.createUserSettings { (success) in }
//change rootViewController to PageViewController w/ animation
//check if there was a referral
if let id = UserDefaults.standard.string(forKey: "referralId") {
//there was a referral, id != nil
ReferralManager().grantReferralCredit(referrerId: id)
}
//create referral link and upload it to settings doc in Firestore
ReferralManager().createReferralLink()
self.setRootViewController(duration: 0.2, vc: PageBoyController())
}
}
Expand Down
18 changes: 14 additions & 4 deletions Jotify/Controller/PageBoyController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ class PageBoyController: PageboyViewController, PageboyViewControllerDataSource
}

@objc func disableSwipe(notification: Notification){
print("Swipe is disabled")
// print("Swipe is disabled")
self.isScrollEnabled = false
}

@objc func enableSwipe(notification: Notification){
print("Swipe is enabled")
// print("Swipe is enabled")
self.isScrollEnabled = true
}

Expand All @@ -89,8 +89,18 @@ class PageBoyController: PageboyViewController, PageboyViewControllerDataSource
User.settings = settings
print("Has migrated: \(String(describing: User.settings?.hasMigrated))")
if !(settings!.hasMigrated) && !UserDefaults.standard.bool(forKey: "hasMigrated") {
//notify when notes are fetched from context, CloudKit
NotificationCenter.default.addObserver(self, selector: #selector(self.migrateDataFromCloudKit), name: .NSManagedObjectContextObjectsDidChange, object: MigrationHandler().context)
//ask user if they want to migrate notes
let alertController = UIAlertController(title: "Migrate Notes", message: "Jotify found notes from a previous version. Would you like to migrate your notes, so you can continue to access them?", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "No", style: .destructive, handler: {(action) in
//set these values, so this prompt does not appear on every launch
UserDefaults.standard.setValue(true, forKey: "hasMigrated")
DataManager.updateUserSettings(setting: "hasMigrated", value: true) { (success) in }
}))
alertController.addAction(UIAlertAction(title: "Yes", style: .default, handler: {(action) in
//notify when notes are fetched from context, CloudKit
NotificationCenter.default.addObserver(self, selector: #selector(self.migrateDataFromCloudKit), name: .NSManagedObjectContextObjectsDidChange, object: MigrationHandler().context)
}))
self.present(alertController, animated: true, completion: nil)
}
}
}
Expand Down
10 changes: 9 additions & 1 deletion Jotify/Controller/Settings/MasterSettingsController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class MasterSettingsController: SettingsController {
override func viewDidLoad() {
super.viewDidLoad()
super.sections = ["General"]
super.section1 = ["General", "Customization", "Account"]
super.section1 = ["General", "Customization", "Account", "Referrals"]
navigationItem.title = "Settings"

//disable swiping to create a new note when changing settings
Expand Down Expand Up @@ -56,6 +56,14 @@ class MasterSettingsController: SettingsController {
} else if UIDevice.current.userInterfaceIdiom == .phone {
navigationController?.pushViewController(vc, animated: true)
}
case 3:
let vc = ReferralSettingsController()
if UIDevice.current.userInterfaceIdiom == .pad {
vc.modalPresentationStyle = .formSheet
present(vc, animated: true, completion: nil)
} else if UIDevice.current.userInterfaceIdiom == .phone {
navigationController?.pushViewController(vc, animated: true)
}
default:
print("")
}
Expand Down
116 changes: 116 additions & 0 deletions Jotify/Controller/Settings/ReferralSettingsController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
//
// ReferralSettingsController.swift
// Jotify
//
// Created by Harrison Leath on 5/22/22.
//

import UIKit
import MessageUI

class ReferralSettingsController: UIViewController, MFMessageComposeViewControllerDelegate {

let detailText: UITextView = {
let tv = UITextView()
tv.font = UIFont.systemFont(ofSize: 18, weight: .regular)
tv.textAlignment = .center
tv.backgroundColor = .clear
tv.isUserInteractionEnabled = false
tv.translatesAutoresizingMaskIntoConstraints = false
return tv
}()

lazy var nextButton: UIButton = {
let button = UIButton()
button.setTitleColor(.white, for: .normal)
button.backgroundColor = UIColor.jotifyBlue
button.layer.cornerRadius = 10
button.translatesAutoresizingMaskIntoConstraints = false
button.addTarget(self, action: #selector(shareReferral), for: .touchUpInside)
button.setTitle("Invite Someone", for: .normal)
return button
}()

let wrapper: UIView = {
let view = UIView()
view.backgroundColor = .clear
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()

//press a button to send referral link

override func viewDidLoad() {
super.viewDidLoad()

view.backgroundColor = ColorManager.bgColor

let referrals = User.settings?.referrals ?? 0

detailText.text = "You have \(referrals) referrals. Once you reach 3 referrals, Jotify premium is given automatically!"

view.addSubview(wrapper)
view.addSubview(nextButton)

wrapper.addSubview(detailText)

wrapper.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
wrapper.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
wrapper.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.85).isActive = true
wrapper.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.80).isActive = true


detailText.centerXAnchor.constraint(equalTo: wrapper.centerXAnchor).isActive = true
detailText.topAnchor.constraint(equalTo: wrapper.centerYAnchor).isActive = true
detailText.heightAnchor.constraint(equalToConstant: 400).isActive = true

//to make the text fit relatively ok on iPad
if view.bounds.width * 0.85 > 500 {
detailText.widthAnchor.constraint(equalToConstant: 500).isActive = true
} else {
detailText.widthAnchor.constraint(equalTo: wrapper.widthAnchor).isActive = true
}

nextButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
nextButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -75).isActive = true
nextButton.widthAnchor.constraint(equalToConstant: 250).isActive = true
nextButton.heightAnchor.constraint(equalToConstant: 60).isActive = true
}

@objc func shareReferral() {
let invitationLink = User.settings?.referralLink
let subject = "You should start using Jotify! Use my referreral link: \(invitationLink ?? "nil")"

let messageComposer = MFMessageComposeViewController()
messageComposer.messageComposeDelegate = self
messageComposer.body = subject

if MFMessageComposeViewController.canSendText() {
present(messageComposer, animated: true)
} else {
//TODO: Copy the link to the clipboard and present alert to user telling them this.
UIPasteboard.general.string = subject
let alertController = UIAlertController(title: "Unable to Send", message: "You cannot message from this device, so Jotify copied the referral link to your clipboard.", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: {(action) in }))
self.present(alertController, animated: true, completion: nil)
}

self.playHapticFeedback()
}

func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
if result == .sent {
dismiss(animated: true)
} else if result == .cancelled {
dismiss(animated: true)
} else {
dismiss(animated: true)
//copy link to clipboard and alert user
let invitationLink = User.settings?.referralLink
UIPasteboard.general.string = "You should start using Jotify! Use my referreral link: \(invitationLink ?? "nil")"
let alertController = UIAlertController(title: "Unable to Send", message: "The message failed to send, so Jotify copied the link to your clipboard.", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: {(action) in }))
self.present(alertController, animated: true, completion: nil)
}
}
}
7 changes: 5 additions & 2 deletions Jotify/Controller/SetupController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ class SetupController {
let domain = Bundle.main.bundleIdentifier!
UserDefaults.standard.removePersistentDomain(forName: domain)
UserDefaults.standard.synchronize()
print(Array(UserDefaults.standard.dictionaryRepresentation().keys).count)

UserDefaults.standard.register(defaults: [
"hasMigrated": false,
Expand All @@ -41,6 +40,8 @@ class SetupController {
"useBiometrics": false,
"placeholder": "Tap to start typing or swipe left to right for saved notes...",
"defaultView": 0,
"referrals": 0,
"referralLink": "",
])
}

Expand All @@ -67,16 +68,18 @@ class SetupController {
if previousVersion == currentVersion {
// same version, no update
print("same version")
//TODO: Before launching the beta enable this to wipe all settings and start over...
setupDefaults()

} else {
if previousVersion != nil {
// new version
print("new version")
//show onboarding when user updates to 2.0.0
//TODO: Change this for any version after 2.0.0
SetupController.firstLauch = true
setupWidget()
setupDefaults()

} else {
// first launch
print("first launch")
Expand Down
1 change: 0 additions & 1 deletion Jotify/GradientAnimator/ColorManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ class ColorManager {
//fill an array of indexes that correspond to the array as a parameter
//remove elements from indexes array as they are selected from parameter array
//repeat when indexes is empty
//TODO:: FIX THIS METHOD, DOESNT WORK
@discardableResult static func setNoteColor() -> UIColor {
let count = GradientThemes.All.colors().count
if ColorManager.indexes.count == 0 {
Expand Down
13 changes: 13 additions & 0 deletions Jotify/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>Bundle ID</string>
<key>CFBundleURLSchemes</key>
<array>
<string>com.austinleath.Jotify</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSRequiresIPhoneOS</key>
Expand Down
4 changes: 4 additions & 0 deletions Jotify/Jotify.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
<array>
<string>Default</string>
</array>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:jotify.page.link</string>
</array>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>iCloud.com.austinleath.Jotify</string>
Expand Down
4 changes: 3 additions & 1 deletion Jotify/Model/Firebase/DataManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class DataManager {
"placeholder": "Tap to start typing or swipe left to right for saved notes...",
"hasMigrated": false,
"defaultView": 0,
"referrals": 0,
"referralLink": "",
]) { (error) in
if let error = error {
print("Error deleting document: \(error.localizedDescription)")
Expand All @@ -42,7 +44,7 @@ class DataManager {
completionHandler(nil, false)
} else {
print("Firebase settings retrieved")
let settings = Settings(multilineInputEnabled: snapshot?.get("multilineInputEnabled") as? Bool ?? false, deleteOldNotes: snapshot?.get("deleteOldNotes") as? Bool ?? false, useHaptics: snapshot?.get("useHaptics") as? Bool ?? true, useBiometrics: snapshot?.get("useBiometrics") as? Bool ?? false, placeholder: snapshot?.get("placeholder") as? String ?? "Tap to start typing or swipe left to right for saved notes...", defaultView: snapshot?.get("defaultView") as? Int ?? 0, hasMigrated: snapshot?.get("hasMigrated") as? Bool ?? false)
let settings = Settings(multilineInputEnabled: snapshot?.get("multilineInputEnabled") as? Bool ?? false, deleteOldNotes: snapshot?.get("deleteOldNotes") as? Bool ?? false, useHaptics: snapshot?.get("useHaptics") as? Bool ?? true, useBiometrics: snapshot?.get("useBiometrics") as? Bool ?? false, placeholder: snapshot?.get("placeholder") as? String ?? "Tap to start typing or swipe left to right for saved notes...", defaultView: snapshot?.get("defaultView") as? Int ?? 0, hasMigrated: snapshot?.get("hasMigrated") as? Bool ?? false, referrals: snapshot?.get("referrals") as? Int ?? 0, referralLink: snapshot?.get("referralLink") as? String ?? "")
completionHandler(settings, true)
}
}
Expand Down
Loading

0 comments on commit 513b7fa

Please sign in to comment.