Skip to content

Commit 8c13ed1

Browse files
author
Igors Nemenonoks
committed
Initial commit
0 parents  commit 8c13ed1

File tree

65 files changed

+3248
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+3248
-0
lines changed

.gitignore

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Xcode
2+
#
3+
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4+
5+
## Build generated
6+
build/
7+
DerivedData/
8+
9+
## Various settings
10+
*.pbxuser
11+
!default.pbxuser
12+
*.mode1v3
13+
!default.mode1v3
14+
*.mode2v3
15+
!default.mode2v3
16+
*.perspectivev3
17+
!default.perspectivev3
18+
xcuserdata/
19+
20+
## Other
21+
*.moved-aside
22+
*.xcuserstate
23+
*.xcworkspace
24+
.DS_Store
25+
26+
## Obj-C/Swift specific
27+
*.hmap
28+
*.ipa
29+
*.dSYM.zip
30+
*.dSYM
31+
32+
## Playgrounds
33+
timeline.xctimeline
34+
playground.xcworkspace
35+
36+
# Swift Package Manager
37+
#
38+
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
39+
# Packages/
40+
.build/
41+
42+
# CocoaPods
43+
#
44+
# We recommend against adding the Pods directory to your .gitignore. However
45+
# you should judge for yourself, the pros and cons are mentioned at:
46+
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
47+
#
48+
Pods/
49+
50+
# Carthage
51+
#
52+
# Add this line if you want to avoid checking in source code from Carthage dependencies.
53+
# Carthage/Checkouts
54+
55+
Carthage/Build
56+
57+
# fastlane
58+
#
59+
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
60+
# screenshots whenever they are needed.
61+
# For more information about the recommended setup visit:
62+
# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
63+
64+
fastlane/report.xml
65+
fastlane/Preview.html
66+
fastlane/screenshots
67+
fastlane/test_output
68+
.idea
69+
FailureDiffs/
70+
*.mobileprovision
71+
*.cer
72+
fastlane/README.md

.swiftlint.yml

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
disabled_rules:
2+
- force_cast
3+
- force_try
4+
- missing_docs
5+
opt_in_rules:
6+
- empty_count
7+
included:
8+
- Classes
9+
excluded:
10+
- Pods
11+
12+
function_parameter_count: 7
13+
line_length: 210
14+
type_body_length:
15+
- 300
16+
- 400
17+
file_length:
18+
warning: 500
19+
error: 1200
20+
type_name:
21+
min_length: 3
22+
max_length:
23+
warning: 40
24+
error: 50
25+
excluded: iPhone
26+
function_body_length:
27+
warning: 50
28+
error: 70
29+
cyclomatic_complexity:
30+
warning: 15
31+
error: 25
32+
large_tuple:
33+
warning: 4
34+
error: 6
35+
identifier_name:
36+
min_length:
37+
warning: 1
38+
excluded:
39+
- id
40+
- URL
41+
- GlobalAPIKey
42+
reporter: "xcode" #(xcode, json, csv, checkstyle, junit)

Classes/AppDelegate.swift

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//
2+
// AppDelegate.swift
3+
// Spendo
4+
//
5+
// Created by Igors Nemenonoks on 10/05/2019.
6+
// Copyright © 2019 Chili Labs. All rights reserved.
7+
//
8+
9+
import UIKit
10+
import RxFlow
11+
import RxSwift
12+
13+
@UIApplicationMain
14+
class AppDelegate: UIResponder, UIApplicationDelegate {
15+
16+
var window: UIWindow?
17+
let coordinator = FlowCoordinator()
18+
let bag = DisposeBag()
19+
20+
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
21+
guard let window = self.window else { return false }
22+
23+
Typography.registerAllStyles()
24+
let appFlow = AppFlow(withWindow: window)
25+
26+
self.coordinator.coordinate(flow: appFlow, with: AppStepper())
27+
28+
return true
29+
}
30+
31+
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
32+
//
33+
}
34+
35+
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
36+
//
37+
}
38+
39+
func applicationWillResignActive(_ application: UIApplication) {
40+
//
41+
}
42+
43+
func applicationDidEnterBackground(_ application: UIApplication) {
44+
//
45+
}
46+
47+
func applicationWillEnterForeground(_ application: UIApplication) {
48+
//
49+
}
50+
51+
func applicationDidBecomeActive(_ application: UIApplication) {
52+
//
53+
}
54+
55+
func applicationWillTerminate(_ application: UIApplication) {
56+
//
57+
}
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
//
2+
// BaseMagazineLayoutVC.swift
3+
// Spendo
4+
//
5+
// Created by Igors Nemenonoks on 11/05/2020.
6+
// Copyright © 2020 Chili Labs. All rights reserved.
7+
//
8+
9+
import UIKit
10+
import MagazineLayout
11+
import RxSwift
12+
import RxCocoa
13+
import SnapKit
14+
15+
protocol PBaseMagazineLayoutVC: UICollectionViewDelegateMagazineLayout, UICollectionViewDataSource {
16+
var sections: Binder<[MagazineLayoutSection]> { get }
17+
var collectionView: UICollectionView { get }
18+
func didSelectItem<DataType: Diffable, CellType: ConfigurableCell>() -> Observable<MagazineCellConfigurator<DataType, CellType>>
19+
}
20+
21+
class BaseMagazineLayoutVC: UIViewController, PBaseMagazineLayoutVC {
22+
23+
var sections: Binder<[MagazineLayoutSection]> {
24+
return Binder(self) { vc, items in
25+
vc._sections.accept(items)
26+
}
27+
}
28+
29+
fileprivate let _sections = BehaviorRelay(value: [MagazineLayoutSection]())
30+
31+
//published when cell got selected
32+
private let selectPublisher = PublishRelay<CellConfigurator>()
33+
private lazy var cellsRegistrator = CollectionViewCellsRegistrator(collectionView: self.collectionView)
34+
35+
private let bag = DisposeBag()
36+
37+
// Collection view
38+
lazy var collectionView: UICollectionView = {
39+
let layout = MagazineLayout()
40+
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
41+
collectionView.dataSource = self
42+
collectionView.delegate = self
43+
collectionView.backgroundColor = .white
44+
collectionView.contentInsetAdjustmentBehavior = .always
45+
return collectionView
46+
}()
47+
48+
override func viewDidLoad() {
49+
super.viewDidLoad()
50+
51+
self.view.backgroundColor = .white
52+
self.view.insertSubview(self.collectionView, at: 0)
53+
54+
self.collectionView.translatesAutoresizingMaskIntoConstraints = false
55+
self.collectionView.snp.makeConstraints { $0.edges.equalTo(0) }
56+
57+
self._sections.subscribe(onNext: { [weak self] sections in
58+
self?.cellsRegistrator.registerCells(for: sections)
59+
}).disposed(by: bag)
60+
}
61+
62+
func didSelectItem<DataType: Diffable, CellType: ConfigurableCell>() -> Observable<MagazineCellConfigurator<DataType, CellType>> {
63+
return self.selectPublisher
64+
.filter({ (configurator) -> Bool in
65+
return configurator is MagazineCellConfigurator<DataType, CellType>
66+
})
67+
.map { configurator -> MagazineCellConfigurator<DataType, CellType> in
68+
return configurator as! MagazineCellConfigurator<DataType, CellType>
69+
}
70+
}
71+
}
72+
73+
extension BaseMagazineLayoutVC: UICollectionViewDelegateMagazineLayout {
74+
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeModeForItemAt indexPath: IndexPath) -> MagazineLayoutItemSizeMode {
75+
return self._sections.value[indexPath.section].items[indexPath.row].sizeMode
76+
}
77+
78+
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, visibilityModeForHeaderInSectionAtIndex index: Int) -> MagazineLayoutHeaderVisibilityMode {
79+
return self._sections.value[index].header.visibilityMode
80+
}
81+
82+
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, visibilityModeForFooterInSectionAtIndex index: Int) -> MagazineLayoutFooterVisibilityMode {
83+
return self._sections.value[index].footer.visibilityMode
84+
}
85+
// swiftlint:disable line_length
86+
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, visibilityModeForBackgroundInSectionAtIndex index: Int) -> MagazineLayoutBackgroundVisibilityMode {
87+
return self._sections.value[index].background.visibilityMode
88+
}
89+
90+
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, horizontalSpacingForItemsInSectionAtIndex index: Int) -> CGFloat {
91+
return self._sections.value[index].itemsInset.right
92+
}
93+
94+
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, verticalSpacingForElementsInSectionAtIndex index: Int) -> CGFloat {
95+
return self._sections.value[index].itemsInset.bottom
96+
}
97+
98+
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetsForSectionAtIndex index: Int) -> UIEdgeInsets {
99+
return self._sections.value[index].sectionInset
100+
}
101+
102+
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetsForItemsInSectionAtIndex index: Int) -> UIEdgeInsets {
103+
return self._sections.value[index].itemsInset
104+
}
105+
}
106+
extension BaseMagazineLayoutVC: UICollectionViewDataSource {
107+
108+
func numberOfSections(in collectionView: UICollectionView) -> Int {
109+
return self._sections.value.count
110+
}
111+
112+
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
113+
return self._sections.value[section].items.count
114+
}
115+
116+
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
117+
let cellConfigurator = self._sections.value[indexPath.section].items[indexPath.row]
118+
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: type(of: cellConfigurator).cellReuseIdentifier, for: indexPath)
119+
cellConfigurator.configure(cell: cell)
120+
return cell
121+
}
122+
123+
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
124+
125+
let section = _sections.value[indexPath.section]
126+
if let sectionItem = section.header.item, kind == MagazineLayout.SupplementaryViewKind.sectionHeader {
127+
let cell = collectionView.dequeueReusableSupplementaryView(ofKind: MagazineLayout.SupplementaryViewKind.sectionHeader,
128+
withReuseIdentifier: type(of: sectionItem).cellReuseIdentifier,
129+
for: indexPath)
130+
sectionItem.configure(cell: cell)
131+
return cell
132+
} else if let sectionItem = section.footer.item, kind == MagazineLayout.SupplementaryViewKind.sectionFooter {
133+
let cell = collectionView.dequeueReusableSupplementaryView(ofKind: MagazineLayout.SupplementaryViewKind.sectionFooter,
134+
withReuseIdentifier: type(of: sectionItem).cellReuseIdentifier,
135+
for: indexPath)
136+
sectionItem.configure(cell: cell)
137+
return cell
138+
}
139+
140+
fatalError("Not supported")
141+
}
142+
143+
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
144+
self.selectPublisher.accept(self._sections.value[indexPath.section].items[indexPath.row])
145+
self._sections.value[indexPath.section].items[indexPath.row].didSelect()
146+
}
147+
}

0 commit comments

Comments
 (0)