Skip to content
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
84 changes: 64 additions & 20 deletions FightPandemics.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

108 changes: 108 additions & 0 deletions FightPandemics/Features/Feed/Card/AllFeedScreen.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
//
// FeedViewCell.swift
// FightPandemics
//
// Created by Onyekachi Ezeoke on 03/06/2020.
//
// Copyright (c) 2020 FightPandemics
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import UIKit

class AllFeedScreen: BaseCell {
lazy var collectionView: UICollectionView = {
let layout = createLayout()
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.backgroundColor = .white
return collectionView
}()

var dataSource: UICollectionViewDiffableDataSource<Section, Post>!
private let refreshControl = UIRefreshControl()

override func setupViews() {
collectionView.register(cellType: FeedCell.self)
collectionView.makeSubview(of: self)
.top(to: \.topAnchor)
.leading(to: \.leadingAnchor)
.trailing(to: \.trailingAnchor)
.bottom(to: \.bottomAnchor)

dataSource = UICollectionViewDiffableDataSource<Section, Post>(collectionView: collectionView, cellProvider: { (collectionView, indexPath, post) -> UICollectionViewCell? in

guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FeedCell.reuseIdentifier, for: indexPath) as? FeedCell else {
return UICollectionViewCell()
}

// TODO: The if statement will be removed later, it was added to visualize what we have currently
if indexPath.item == 0 {
cell.backgroundColor = .orange
} else if indexPath.item == 1 {
cell.backgroundColor = .blue
} else if indexPath.item == 2 {
cell.backgroundColor = .green
}
cell.post = post
return cell
})
collectionView.dataSource = dataSource
fetchPost()
configureRefreshControl()
}

func fetchPost() {
// TODO: The network call will happen here and the fetched post data will be appended to the snapshot
let posts: [Post] = [.init(id: 1), .init(id: 2)]
var snapShot = NSDiffableDataSourceSnapshot<Section, Post>()
snapShot.appendSections([.main])
snapShot.appendItems(posts)
dataSource.apply(snapShot)
}

private func configureRefreshControl() {
collectionView.refreshControl = refreshControl
refreshControl.addTarget(self, action: #selector(refreshFeedData), for: .valueChanged)
}

@objc private func refreshFeedData() {
// Call fetchPost() to fetch new data

// Call this when the data has been fetched to stop the refresh animation
DispatchQueue.main.async {
self.refreshControl.endRefreshing()
}
}

private func createLayout() -> UICollectionViewLayout {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)

let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .absolute(342))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
subitems: [item])

let section = NSCollectionLayoutSection(group: group)

let layout = UICollectionViewCompositionalLayout(section: section)
return layout
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//
// FeedViewCell.swift
// BaseCell.swift
// FightPandemics
//
// Created by Onyekachi Ezeoke on 03/06/2020.
// Created by Onyekachi Ezeoke on 16/07/2020.
//
// Copyright (c) 2020 FightPandemics
//
Expand All @@ -26,13 +26,15 @@

import UIKit

class FeedViewCell: UICollectionViewCell {
static let reuseIdentifier = String(describing: self)
class BaseCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}

required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

func setupViews() {}
}
33 changes: 33 additions & 0 deletions FightPandemics/Features/Feed/Card/FeedCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// FeedCell.swift
// FightPandemics
//
// Created by Onyekachi Ezeoke on 16/07/2020.
//
// Copyright (c) 2020 FightPandemics
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import UIKit

class FeedCell: BaseCell {
// TODO: This will be handled with view model
var post: Post?
override func setupViews() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

import UIKit

class FeedMenuBar: UIView {
class MenuBar: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
Expand All @@ -53,10 +53,10 @@ class FeedMenuBar: UIView {
var horizontalBarViewLeftConstraint: NSLayoutConstraint?
}

private extension FeedMenuBar {
private extension MenuBar {
func setupViews() {
backgroundColor = .white
menuCollectionView.register(FeedMenuCell.self, forCellWithReuseIdentifier: FeedMenuCell.reuseIdentifier)
menuCollectionView.register(cellType: MenuCell.self)

let selectedIndex = IndexPath(row: 0, section: 0)
menuCollectionView.selectItem(at: selectedIndex, animated: false, scrollPosition: .left)
Expand All @@ -75,13 +75,13 @@ private extension FeedMenuBar {
}
}

extension FeedMenuBar: UICollectionViewDataSource {
extension MenuBar: UICollectionViewDataSource {
func collectionView(_: UICollectionView, numberOfItemsInSection _: Int) -> Int {
return menuOptions.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FeedMenuCell.reuseIdentifier, for: indexPath) as? FeedMenuCell else {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MenuCell.reuseIdentifier, for: indexPath) as? MenuCell else {
return UICollectionViewCell()
}
let text = menuOptions[indexPath.row]
Expand All @@ -90,7 +90,7 @@ extension FeedMenuBar: UICollectionViewDataSource {
}
}

extension FeedMenuBar: UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
extension MenuBar: UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
func collectionView(_: UICollectionView, didSelectItemAt indexPath: IndexPath) {
feedViewController?.scrollToMenuItem(at: indexPath.row)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,7 @@

import UIKit

class FeedMenuCell: UICollectionViewCell {
static let reuseIdentifier = String(describing: self)
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}

required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

class MenuCell: BaseCell {
let titleLabel = UILabel()
private let bottomLinerView = UIView()

Expand All @@ -56,7 +46,7 @@ class FeedMenuCell: UICollectionViewCell {
}
}

private func setupViews() {
override func setupViews() {
backgroundColor = .white
titleLabel.font = Fonts.poppinsRegular.customFont(size: 16)
titleLabel.textColor = #colorLiteral(red: 0.1568627451, green: 0.1568627451, blue: 0.1568627451, alpha: 1)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//
// FeedPostDataSource.swift
// OfferFeedScreen.swift
// FightPandemics
//
// Created by Onyekachi Ezeoke on 03/06/2020.
// Created by Onyekachi Ezeoke on 16/07/2020.
//
// Copyright (c) 2020 FightPandemics
//
Expand All @@ -26,21 +26,17 @@

import UIKit

class FeedPostDataSource: NSObject, UITableViewDataSource {
private let posts: [String]
var controller: FeedViewController?

init(posts: [String], controller: FeedViewController) {
self.posts = posts
self.controller = controller
}

func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int {
return posts.count
class OfferFeedScreen: AllFeedScreen {
override func setupViews() {
super.setupViews()
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
return cell
override func fetchPost() {
// TODO: The network call will happen here and the fetched post data will be appended to the snapshot
let posts: [Post] = [.init(id: 1), .init(id: 2), .init(id: 3)]
var snapShot = NSDiffableDataSourceSnapshot<Section, Post>()
snapShot.appendSections([.main])
snapShot.appendItems(posts)
dataSource.apply(snapShot)
}
}
43 changes: 43 additions & 0 deletions FightPandemics/Features/Feed/Card/RequestFeedScreen.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// RequestFeedScreen.swift
// FightPandemics
//
// Created by Onyekachi Ezeoke on 16/07/2020.
//
// Copyright (c) 2020 FightPandemics
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import UIKit

class RequestFeedScreen: AllFeedScreen {
override func setupViews() {
super.setupViews()
fetchPost()
}

override func fetchPost() {
// TODO: The network call will happen here and the fetched post data will be appended to the snapshot
let posts: [Post] = [.init(id: 1)]
var snapShot = NSDiffableDataSourceSnapshot<Section, Post>()
snapShot.appendSections([.main])
snapShot.appendItems(posts)
dataSource.apply(snapShot)
}
}
19 changes: 2 additions & 17 deletions FightPandemics/Features/Feed/Feed.storyboard
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="8Kr-t0-QTc">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="8Kr-t0-QTc">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
Expand All @@ -22,20 +22,5 @@
</objects>
<point key="canvasLocation" x="349" y="138"/>
</scene>
<!--Feed Prototype View Controller-->
<scene sceneID="wDH-Lj-i3z">
<objects>
<viewController storyboardIdentifier="FeedPrototypeViewController" id="v9m-3e-Gkt" customClass="FeedPrototypeViewController" customModule="FightPandemics" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="JLB-gU-ie3">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<viewLayoutGuide key="safeArea" id="Bo9-8W-TOF"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="tnJ-fc-7WK" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="348" y="806"/>
</scene>
</scenes>
</document>
Loading