git.iko.soy/dashared/GDproject
on master help sign in
Changed creation of new channels A LOT. But still search inside people and hashtags is left (and also preview - make get Anon channel). Fixed pagination and something else.
caebb61Darya Rednikina
GDproject.xcodeproj/project.pbxproj+8
@@ -15,6 +15,8 @@
15 125BD57D22171D2A008A3575 /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD57C22171D2A008A3575 /* ProfileViewController.swift */; };
15 125BD57D22171D2A008A3575 /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD57C22171D2A008A3575 /* ProfileViewController.swift */; };
16 125BD57F22171D73008A3575 /* Extentions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD57E22171D73008A3575 /* Extentions.swift */; };
16 125BD57F22171D73008A3575 /* Extentions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD57E22171D73008A3575 /* Extentions.swift */; };
17 125BD5812217314A008A3575 /* NewsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD5802217314A008A3575 /* NewsVC.swift */; };
17 125BD5812217314A008A3575 /* NewsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 125BD5802217314A008A3575 /* NewsVC.swift */; };
18+ 1261BB93227B364C003898CF /* ChannelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1261BB92227B364C003898CF /* ChannelViewController.swift */; };
19+ 1261BB95227B3991003898CF /* AddToChannelVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1261BB94227B3991003898CF /* AddToChannelVC.swift */; };
18 1288B5CE221F1158002BE6B1 /* DataStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1288B5CD221F1158002BE6B1 /* DataStorage.swift */; };
20 1288B5CE221F1158002BE6B1 /* DataStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1288B5CD221F1158002BE6B1 /* DataStorage.swift */; };
19 1291BE2D2221312D009D3F23 /* ChannelsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */; };
21 1291BE2D2221312D009D3F23 /* ChannelsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */; };
20 1291BE342221569B009D3F23 /* TabbarCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE332221569B009D3F23 /* TabbarCoordinator.swift */; };
22 1291BE342221569B009D3F23 /* TabbarCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE332221569B009D3F23 /* TabbarCoordinator.swift */; };
@@ -102,6 +104,8 @@
102 125BD57C22171D2A008A3575 /* ProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = "<group>"; };
104 125BD57C22171D2A008A3575 /* ProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = "<group>"; };
103 125BD57E22171D73008A3575 /* Extentions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extentions.swift; sourceTree = "<group>"; };
105 125BD57E22171D73008A3575 /* Extentions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extentions.swift; sourceTree = "<group>"; };
104 125BD5802217314A008A3575 /* NewsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsVC.swift; sourceTree = "<group>"; };
106 125BD5802217314A008A3575 /* NewsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsVC.swift; sourceTree = "<group>"; };
107+ 1261BB92227B364C003898CF /* ChannelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelViewController.swift; sourceTree = "<group>"; };
108+ 1261BB94227B3991003898CF /* AddToChannelVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddToChannelVC.swift; sourceTree = "<group>"; };
105 1288B5CD221F1158002BE6B1 /* DataStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataStorage.swift; sourceTree = "<group>"; };
109 1288B5CD221F1158002BE6B1 /* DataStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataStorage.swift; sourceTree = "<group>"; };
106 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelsCoordinator.swift; sourceTree = "<group>"; };
110 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelsCoordinator.swift; sourceTree = "<group>"; };
107 1291BE332221569B009D3F23 /* TabbarCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabbarCoordinator.swift; sourceTree = "<group>"; };
111 1291BE332221569B009D3F23 /* TabbarCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabbarCoordinator.swift; sourceTree = "<group>"; };
@@ -297,6 +301,8 @@
297 12E36DD322156519006FCDD7 /* News and channels */ = {
301 12E36DD322156519006FCDD7 /* News and channels */ = {
298 isa = PBXGroup;
302 isa = PBXGroup;
299 children = (
303 children = (
304+ 1261BB92227B364C003898CF /* ChannelViewController.swift */,
305+ 1261BB94227B3991003898CF /* AddToChannelVC.swift */,
300 12D7D134221C42B700B35452 /* ChannelController.swift */,
306 12D7D134221C42B700B35452 /* ChannelController.swift */,
301 121A8971226B1EAC005EE599 /* AnonimousChannelController.swift */,
307 121A8971226B1EAC005EE599 /* AnonimousChannelController.swift */,
302 12D7D132221C321600B35452 /* ChannelListController.swift */,
308 12D7D132221C321600B35452 /* ChannelListController.swift */,
@@ -423,8 +429,10 @@
423 12BA4B9F224102B700DF93D7 /* LogInCoordinator.swift in Sources */,
429 12BA4B9F224102B700DF93D7 /* LogInCoordinator.swift in Sources */,
424 12F3D6B22241097B00A69214 /* ProfileCoordinator.swift in Sources */,
430 12F3D6B22241097B00A69214 /* ProfileCoordinator.swift in Sources */,
425 125BD57D22171D2A008A3575 /* ProfileViewController.swift in Sources */,
431 125BD57D22171D2A008A3575 /* ProfileViewController.swift in Sources */,
432+ 1261BB95227B3991003898CF /* AddToChannelVC.swift in Sources */,
426 12DB7FDB2218590C0096878E /* InfoCell.swift in Sources */,
433 12DB7FDB2218590C0096878E /* InfoCell.swift in Sources */,
427 12DB7FD922181E660096878E /* BasicInfoCell.swift in Sources */,
434 12DB7FD922181E660096878E /* BasicInfoCell.swift in Sources */,
435+ 1261BB93227B364C003898CF /* ChannelViewController.swift in Sources */,
428 12D7D135221C42B700B35452 /* ChannelController.swift in Sources */,
436 12D7D135221C42B700B35452 /* ChannelController.swift in Sources */,
429 12E36D9C221424EA006FCDD7 /* AppDelegate.swift in Sources */,
437 12E36D9C221424EA006FCDD7 /* AppDelegate.swift in Sources */,
430 12BA4B9D224101E700DF93D7 /* BaseCoordinator.swift in Sources */,
438 12BA4B9D224101E700DF93D7 /* BaseCoordinator.swift in Sources */,
GDproject/Base.lproj/Main.storyboard+78−1
@@ -546,10 +546,86 @@
546 </objects>
546 </objects>
547 <point key="canvasLocation" x="4336" y="937"/>
547 <point key="canvasLocation" x="4336" y="937"/>
548 </scene>
548 </scene>
549+ <!--Channel View Controller-->
550+ <scene sceneID="myW-UY-uGB">
551+ <objects>
552+ <tableViewController storyboardIdentifier="ChannelViewController" id="M45-Em-JMM" customClass="ChannelViewController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
553+ <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="poy-7L-m8s">
554+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
555+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
556+ <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
557+ <prototypes>
558+ <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="titleCell" id="x0n-Is-bsF" customClass="TitleCell" customModule="GDproject" customModuleProvider="target">
559+ <rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
560+ <autoresizingMask key="autoresizingMask"/>
561+ <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="x0n-Is-bsF" id="5aI-NN-BRQ">
562+ <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
563+ <autoresizingMask key="autoresizingMask"/>
564+ <subviews>
565+ <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Name the channel" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="jTk-cs-cpn">
566+ <rect key="frame" x="16" y="7" width="343" height="30"/>
567+ <constraints>
568+ <constraint firstAttribute="height" constant="30" id="ZDL-Wx-W4e"/>
569+ </constraints>
570+ <nil key="textColor"/>
571+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
572+ <textInputTraits key="textInputTraits"/>
573+ </textField>
574+ </subviews>
575+ <constraints>
576+ <constraint firstAttribute="trailing" secondItem="jTk-cs-cpn" secondAttribute="trailing" constant="16" id="KLT-Mg-Igg"/>
577+ <constraint firstAttribute="bottom" secondItem="jTk-cs-cpn" secondAttribute="bottom" constant="6.5" id="Yuh-81-wLm"/>
578+ <constraint firstItem="jTk-cs-cpn" firstAttribute="leading" secondItem="5aI-NN-BRQ" secondAttribute="leading" constant="16" id="tx2-BD-LW1"/>
579+ <constraint firstItem="jTk-cs-cpn" firstAttribute="top" secondItem="5aI-NN-BRQ" secondAttribute="top" constant="7" id="ufD-Sr-H0c"/>
580+ </constraints>
581+ </tableViewCellContentView>
582+ <connections>
583+ <outlet property="titleLabel" destination="jTk-cs-cpn" id="ysU-SK-thv"/>
584+ </connections>
585+ </tableViewCell>
586+ </prototypes>
587+ <sections/>
588+ <connections>
589+ <outlet property="dataSource" destination="M45-Em-JMM" id="zIt-LL-u3B"/>
590+ <outlet property="delegate" destination="M45-Em-JMM" id="8oD-9d-gx0"/>
591+ </connections>
592+ </tableView>
593+ </tableViewController>
594+ <placeholder placeholderIdentifier="IBFirstResponder" id="W3K-lW-jpq" userLabel="First Responder" sceneMemberID="firstResponder"/>
595+ </objects>
596+ <point key="canvasLocation" x="5531" y="656"/>
597+ </scene>
598+ <!--Add To ChannelVC-->
599+ <scene sceneID="Qir-mq-wma">
600+ <objects>
601+ <tableViewController storyboardIdentifier="AddToChannelVC" id="sZD-zJ-IzQ" customClass="AddToChannelVC" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
602+ <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="yj4-wM-mw1">
603+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
604+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
605+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
606+ <prototypes>
607+ <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="xMi-Gz-AGg">
608+ <rect key="frame" x="0.0" y="28" width="375" height="44"/>
609+ <autoresizingMask key="autoresizingMask"/>
610+ <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="xMi-Gz-AGg" id="Lj0-2E-Ai9">
611+ <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
612+ <autoresizingMask key="autoresizingMask"/>
613+ </tableViewCellContentView>
614+ </tableViewCell>
615+ </prototypes>
616+ <connections>
617+ <outlet property="dataSource" destination="sZD-zJ-IzQ" id="RJA-hG-8Bd"/>
618+ <outlet property="delegate" destination="sZD-zJ-IzQ" id="zlr-yK-CDk"/>
619+ </connections>
620+ </tableView>
621+ </tableViewController>
622+ <placeholder placeholderIdentifier="IBFirstResponder" id="kT3-kK-tSX" userLabel="First Responder" sceneMemberID="firstResponder"/>
623+ </objects>
624+ <point key="canvasLocation" x="6287" y="653"/>
625+ </scene>
549 <!--Posts-->
626 <!--Posts-->
550 <scene sceneID="RSd-UJ-34B">
627 <scene sceneID="RSd-UJ-34B">
551 <objects>
628 <objects>
552− <placeholder placeholderIdentifier="IBFirstResponder" id="POV-5T-jeQ" userLabel="First Responder" sceneMemberID="firstResponder"/>
553 <navigationController storyboardIdentifier="navChannels" automaticallyAdjustsScrollViewInsets="NO" id="NuV-ZG-ld2" sceneMemberID="viewController">
629 <navigationController storyboardIdentifier="navChannels" automaticallyAdjustsScrollViewInsets="NO" id="NuV-ZG-ld2" sceneMemberID="viewController">
554 <tabBarItem key="tabBarItem" title="Posts" image="5" selectedImage="5" id="dH2-sL-YsR"/>
630 <tabBarItem key="tabBarItem" title="Posts" image="5" selectedImage="5" id="dH2-sL-YsR"/>
555 <toolbarItems/>
631 <toolbarItems/>
@@ -559,6 +635,7 @@
559 </navigationBar>
635 </navigationBar>
560 <nil name="viewControllers"/>
636 <nil name="viewControllers"/>
561 </navigationController>
637 </navigationController>
638+ <placeholder placeholderIdentifier="IBFirstResponder" id="POV-5T-jeQ" userLabel="First Responder" sceneMemberID="firstResponder"/>
562 </objects>
639 </objects>
563 <point key="canvasLocation" x="1089" y="-306"/>
640 <point key="canvasLocation" x="1089" y="-306"/>
564 </scene>
641 </scene>
GDproject/Constants.swift+4
@@ -55,5 +55,9 @@ let profileViewController = "ProfileViewController"
55
55
56let simplifiedChannelsList = "SimplifiedChannelsList"
56let simplifiedChannelsList = "SimplifiedChannelsList"
57
57
58+let channelViewControllerId = "ChannelViewController"
59+
60+let addToChannelVCId = "AddToChannelVC"
61+
58let blueSystemColor = UIColor(red: 0, green: 137/255, blue: 249/255, alpha: 0.5)
62let blueSystemColor = UIColor(red: 0, green: 137/255, blue: 249/255, alpha: 0.5)
59
63
GDproject/Controller/ News and channels/AddToChannelVC.swiftnew file+117
@@ -0,0 +1,117 @@
1+//
2+// AddToChannelVC.swift
3+// GDproject
4+//
5+// Created by cstore on 02/05/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import UIKit
10+
11+enum DataSourse{
12+ case people, tags
13+}
14+
15+class AddToChannelVC: UITableViewController {
16+
17+ var channel: Model.Channels?
18+ var dataSourse: DataSourse = .people
19+ weak var update: UpdatableChannel?
20+
21+ // data sources for people and hashtags
22+ var dataSourcePeople: [Model.Users] = Model.Channels.fullPeople
23+ var fullTags: [String] = CompletionTree.getCompletion(tree: Model.hashTagTree!, word: "")
24+
25+
26+ var reloadtable: Bool = false {
27+ didSet{
28+ tableView.reloadData()
29+ }
30+ }
31+
32+ let searchC = UISearchController(searchResultsController: nil)
33+
34+ override func viewDidLoad() {
35+ super.viewDidLoad()
36+
37+ tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
38+ self.navigationItem.searchController = searchC
39+ navigationItem.largeTitleDisplayMode = .never
40+ self.navigationItem.hidesSearchBarWhenScrolling = false
41+
42+ }
43+
44+ override func viewWillDisappear(_ animated: Bool) {
45+ super.viewWillDisappear(animated)
46+
47+ update?.updateChannel(with: channel!)
48+ }
49+ // MARK: - Table view data source
50+
51+ override func numberOfSections(in tableView: UITableView) -> Int {
52+ return 1
53+ }
54+
55+ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
56+ switch dataSourse {
57+ case .people:
58+ return dataSourcePeople.count
59+ default:
60+ return fullTags.count
61+ }
62+ }
63+
64+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
65+ {
66+ let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
67+
68+ switch dataSourse {
69+ case .people:
70+ cell.textLabel?.text = dataSourcePeople[indexPath.row].fullName()
71+ if channel!.people.contains(dataSourcePeople[indexPath.row].id) {
72+ cell.backgroundColor = #colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1)
73+ } else {
74+ cell.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
75+ }
76+ default:
77+ cell.textLabel?.text = "# \(fullTags[indexPath.row])"
78+ if channel!.tags.contains(fullTags[indexPath.row]) {
79+ cell.backgroundColor = #colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1)
80+ } else {
81+ cell.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
82+ }
83+ }
84+
85+ cell.selectionStyle = .none
86+
87+ return cell
88+ }
89+
90+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
91+ if let cell = tableView.cellForRow(at: indexPath) {
92+ switch dataSourse {
93+ case .people:
94+ if cell.backgroundColor == #colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1) {
95+ let filtered = channel!.people.filter{ $0 != dataSourcePeople[indexPath.row].id }
96+ channel?.people = filtered
97+ cell.backgroundColor = #colorLiteral(red: 0.9999960065, green: 1, blue: 1, alpha: 1)
98+ } else {
99+ channel?.people.append(dataSourcePeople[indexPath.row].id)
100+ cell.backgroundColor = #colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1)
101+ }
102+ default: //tags
103+ if cell.backgroundColor == #colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1) {
104+ let filtered = channel!.tags.filter{
105+ !fullTags[indexPath.row].contains($0)
106+ }
107+ channel?.tags = filtered
108+ cell.backgroundColor = #colorLiteral(red: 0.9999960065, green: 1, blue: 1, alpha: 1)
109+ } else {
110+ channel?.tags.append(fullTags[indexPath.row])
111+ cell.backgroundColor = #colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1)
112+ }
113+ }
114+ }
115+ }
116+
117+}
GDproject/Controller/ News and channels/ChannelListController.swift+1−1
@@ -84,7 +84,7 @@ class ChannelListController: UITableViewController {
84 askForUpdates()
84 askForUpdates()
85 }
85 }
86
86
87− private func askForUpdates(){
87+ func askForUpdates(){
88 Model.channelsList { [weak self] (channels) in
88 Model.channelsList { [weak self] (channels) in
89 self?.dataSource = [ChannelListController.generalChannel] + channels
89 self?.dataSource = [ChannelListController.generalChannel] + channels
90 self?.toReload = true
90 self?.toReload = true
GDproject/Controller/ News and channels/ChannelViewController.swiftnew file+195
@@ -0,0 +1,195 @@
1+//
2+// ChannelViewController.swift
3+// MessageApp
4+//
5+// Created by cstore on 02/05/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import UIKit
10+
11+protocol UpdatableName: class{
12+ func updateName(with name: String)
13+}
14+
15+protocol UpdatableChannel: class{
16+ func updateChannel(with channel: Model.Channels)
17+}
18+
19+class ChannelViewController: UITableViewController, UpdatableName, UpdatableChannel {
20+
21+ func updateName(with name: String){
22+ channel?.name = name
23+ }
24+
25+ func updateChannel(with channel: Model.Channels) {
26+ self.channel = channel
27+ }
28+
29+ var channel: Model.Channels?
30+
31+ // func to show preview of the current channel
32+ var onShowingPreview: ((Model.Channels)->())?
33+
34+ override func viewDidLoad()
35+ {
36+ super.viewDidLoad()
37+
38+ navigationItem.rightBarButtonItems = [ UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(showPreview)), self.editButtonItem]
39+ navigationItem.largeTitleDisplayMode = .never
40+ tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
41+ tableView.register(UITableViewCell.self, forCellReuseIdentifier: "searchCell")
42+ }
43+
44+ override func viewWillAppear(_ animated: Bool) {
45+ super.viewWillAppear(animated)
46+ tableView.reloadData()
47+ }
48+ // TODO: update channel
49+ override func viewWillDisappear(_ animated: Bool) {
50+
51+ defer {
52+ super.viewWillDisappear(animated)
53+ }
54+
55+ guard let _ = self.navigationController?.viewControllers.lastIndex(of: self) else {
56+ if let _ = channel?.id
57+ {
58+ Model.updateChannel(with: channel!)
59+ } else {
60+ Model.createChannel(with: channel!)
61+ }
62+ return
63+ }
64+ // nou
65+ }
66+
67+ @objc func showPreview(){
68+ if let channel = channel {
69+ onShowingPreview?(channel)
70+ }
71+ }
72+
73+ // MARK: - Table view data source
74+
75+ override func numberOfSections(in tableView: UITableView) -> Int {
76+ return 3
77+ }
78+
79+ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
80+ switch section {
81+ case 1:
82+ return (channel?.people.count ?? 0) + 1
83+ case 2:
84+ return (channel?.tags.count ?? 0) + 1
85+ default:
86+ return 1
87+ }
88+ }
89+
90+ override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
91+ switch section {
92+ case 1:
93+ return "People"
94+ case 2:
95+ return "Tags"
96+ default:
97+ return "Title"
98+ }
99+ }
100+
101+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
102+
103+ switch indexPath.section{
104+ case 1 , 2:
105+ return whichCell(tableView, cellForRowAt: indexPath)
106+ default:
107+ let cell = tableView.dequeueReusableCell(withIdentifier: "titleCell") as! TitleCell
108+
109+ cell.fill(title: channel?.name)
110+ cell.update = self
111+
112+ return cell
113+ }
114+ }
115+
116+ private func whichCell(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
117+ {
118+ let row = indexPath.row
119+ let section = indexPath.section
120+
121+ if row == 0
122+ {
123+ let cell = tableView.dequeueReusableCell(withIdentifier: "searchCell")!
124+ cell.textLabel?.text = "Add more"
125+ cell.accessoryType = .disclosureIndicator
126+ return cell
127+ }
128+
129+ let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
130+
131+ if section == 1 {
132+ cell.textLabel?.text = Model.Channels.fullPeopleDict[channel?.people[row-1] ?? 0]?.fullName()
133+ } else {
134+ cell.textLabel?.text = "# \(channel!.tags[row-1])"
135+ }
136+
137+ return cell
138+ }
139+
140+ override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
141+ {
142+ if editingStyle == UITableViewCell.EditingStyle.delete {
143+ if indexPath.section == 1 {
144+ channel?.people.remove(at: indexPath.row-1)
145+ } else {
146+ channel?.tags.remove(at: indexPath.row-1)
147+ }
148+ }
149+
150+ tableView.reloadData()
151+ }
152+
153+ override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
154+ if indexPath.row == 0 {
155+ return false
156+ }
157+
158+ return true
159+ }
160+
161+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
162+ {
163+ if indexPath.row == 0 && indexPath.section != 0
164+ {
165+ let vc = storyboard?.instantiateViewController(withIdentifier: addToChannelVCId) as! AddToChannelVC
166+
167+ vc.dataSourse = indexPath.section == 1 ? .people : .tags
168+ vc.channel = channel
169+ vc.update = self
170+
171+ navigationController?.pushViewController(vc, animated: true)
172+ }
173+ }
174+}
175+
176+
177+class TitleCell: UITableViewCell, UITextFieldDelegate {
178+
179+ @IBOutlet weak var titleLabel: UITextField!
180+
181+ weak var update: UpdatableName?
182+
183+ override func awakeFromNib() {
184+ super.awakeFromNib()
185+ }
186+
187+ func fill(title: String?){
188+ titleLabel.text = title
189+ titleLabel.addTarget(self, action: #selector(changedText(_:)), for: .editingChanged)
190+ }
191+
192+ @objc func changedText(_ textField: UITextField){
193+ update?.updateName(with: textField.text!)
194+ }
195+}
GDproject/Controller/ News and channels/NewsController.swift+1−2
@@ -53,10 +53,9 @@ class NewsController: UIViewController, UISearchControllerDelegate, UpdateableWi
53
53
54 news.viewController = self
54 news.viewController = self
55 news.type = type == .NEWS ? .NEWS : type!
55 news.type = type == .NEWS ? .NEWS : type!
56+ news.currChannel = channel
56
57
57 setUpNavigationItemsforPosts()
58 setUpNavigationItemsforPosts()
58−
59− //setUpBanner()
60 }
59 }
61
60
62 func setUpSearchContr(){
61 func setUpSearchContr(){
GDproject/Controller/ News and channels/NewsVC.swift+16−5
@@ -45,6 +45,8 @@ class NewsVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
45 }
45 }
46 }
46 }
47
47
48+ var currChannel : Model.Channels?
49+
48 var dataSourse: [Model.Posts] = [] {
50 var dataSourse: [Model.Posts] = [] {
49 didSet {
51 didSet {
50 cellDataSourse = dataSourse.map { PostCellData(attributedData: PostCellData.create(with: $0.body)) }
52 cellDataSourse = dataSourse.map { PostCellData(attributedData: PostCellData.create(with: $0.body)) }
@@ -115,11 +117,20 @@ class NewsVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
115 // pagination
117 // pagination
116 if indexPath.row == cellDataSourse.count - 1 && prevLast != indexPath.row
118 if indexPath.row == cellDataSourse.count - 1 && prevLast != indexPath.row
117 {
119 {
120+ if let ch = currChannel, let id = ch.id, ch.id != -1{
118− // check this!
121+ // check this!
122+ Model.getChannel(with: id, on: 10, from: dataSourse.last?.id )
123+ { [weak self] in
124+ self?.dataSourse.append(contentsOf: $0.posts)
125+ $0.users.forEach { self?.dictionary[$0.key] = $0.value }
126+ }
127+ } else {
128+ // check this!
119− Model.getLast(on: 10, from: dataSourse.last?.id )
129+ Model.getLast(on: 10, from: dataSourse.last?.id )
120− { [weak self] in
130+ { [weak self] in
121− self?.dataSourse.append(contentsOf: $0.posts)
131+ self?.dataSourse.append(contentsOf: $0.posts)
122− $0.users.forEach { self?.dictionary[$0.key] = $0.value }
132+ $0.users.forEach { self?.dictionary[$0.key] = $0.value }
133+ }
123 }
134 }
124
135
125 prevLast = indexPath.row
136 prevLast = indexPath.row
GDproject/Controller/Coordinators/ChannelsCoordinator.swift+10−7
@@ -32,6 +32,8 @@ class ChannelsCoordinator: BaseCoordinator{
32 self.navigationController?.pushViewController(self.presentNewsController(with: channel), animated: true)
32 self.navigationController?.pushViewController(self.presentNewsController(with: channel), animated: true)
33 }
33 }
34
34
35+ channels.askForUpdates()
36+
35 channels.onEditingModeBegins = { [unowned self] (channel, indexPath) in
37 channels.onEditingModeBegins = { [unowned self] (channel, indexPath) in
36 let vc = self.presentChannelController(with: channel)
38 let vc = self.presentChannelController(with: channel)
37 self.navigationController?.pushViewController(vc, animated: true)
39 self.navigationController?.pushViewController(vc, animated: true)
@@ -45,8 +47,8 @@ class ChannelsCoordinator: BaseCoordinator{
45 /// Function that presents channel controller
47 /// Function that presents channel controller
46 ///
48 ///
47 /// - Parameter channel: channel that needs to be displayed
49 /// - Parameter channel: channel that needs to be displayed
48− func presentChannelController(with channel: Model.Channels? = nil) -> ChannelController {
50+ func presentChannelController(with channel: Model.Channels? = nil) -> ChannelViewController {
49− let mainContentVC = storyboard.instantiateViewController(withIdentifier: channelControllerId) as! ChannelController
51+ let mainContentVC = storyboard.instantiateViewController(withIdentifier: channelViewControllerId) as! ChannelViewController
50
52
51 // to show preview we need to instantiate newsController but with different functionality
53 // to show preview we need to instantiate newsController but with different functionality
52 mainContentVC.onShowingPreview = { [weak mainContentVC, unowned self] ch in
54 mainContentVC.onShowingPreview = { [weak mainContentVC, unowned self] ch in
@@ -57,7 +59,8 @@ class ChannelsCoordinator: BaseCoordinator{
57 return mainContentVC
59 return mainContentVC
58 }
60 }
59
61
60− func presentNewsController(with channel: Model.Channels? = nil, previewMode: Bool = false) -> NewsController {
62+ func presentNewsController(with channel: Model.Channels? = nil, previewMode: Bool = false) -> NewsController
63+ {
61 let mainContentVC = storyboard.instantiateViewController(withIdentifier: newsController) as! NewsController
64 let mainContentVC = storyboard.instantiateViewController(withIdentifier: newsController) as! NewsController
62 mainContentVC.channel = channel
65 mainContentVC.channel = channel
63
66
@@ -75,14 +78,14 @@ class ChannelsCoordinator: BaseCoordinator{
75 print("anon with \($0.0.count) users")
78 print("anon with \($0.0.count) users")
76 }
79 }
77
80
78− mainContentVC.changedChannelName = {
79− [weak mainContentVC] (title) in mainContentVC?.navigationItem.title = title
80− }
81−
82 mainContentVC.navigationItem.rightBarButtonItems = [UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(writePost(_:)))
81 mainContentVC.navigationItem.rightBarButtonItems = [UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(writePost(_:)))
83 ]
82 ]
84 }
83 }
85
84
85+ mainContentVC.changedChannelName = {
86+ [weak mainContentVC] (title) in mainContentVC?.navigationItem.title = title
87+ }
88+
86 return mainContentVC
89 return mainContentVC
87 }
90 }
88
91
GDproject/Simple model/Model.swift+10−10
@@ -112,6 +112,9 @@ class Model{
112 var firstName: String
112 var firstName: String
113 var id: Int
113 var id: Int
114
114
115+ func fullName() -> String {
116+ return "\(firstName) \(lastName)"
117+ }
115 }
118 }
116
119
117 struct Attachments: Codable {
120 struct Attachments: Codable {
@@ -209,10 +212,10 @@ class Model{
209 }
212 }
210 }
213 }
211
214
212− struct PostsLastRequest: Codable {
215+ struct PostsLastRequest<T: Codable>: Codable {
213 var limit: Int
216 var limit: Int
214 var exclusiveFrom: Int?
217 var exclusiveFrom: Int?
215− var request: [Int] = []
218+ var request: T
216
219
217 enum CodingKeys: String, CodingKey {
220 enum CodingKeys: String, CodingKey {
218 case limit
221 case limit
@@ -230,7 +233,7 @@ class Model{
230
233
231 static func getLast(on limit: Int = 10, from pointInTime: Int? = nil, completion: @escaping (((users:[Int: Users], posts:[Posts]))->()))
234 static func getLast(on limit: Int = 10, from pointInTime: Int? = nil, completion: @escaping (((users:[Int: Users], posts:[Posts]))->()))
232 {
235 {
233− let postRequest = PostsLastRequest(limit: limit, exclusiveFrom: pointInTime, request: [])
236+ let postRequest = PostsLastRequest<[Int]>(limit: limit, exclusiveFrom: pointInTime, request: [])
234
237
235 var request = URLRequest(url: postsLastURL)
238 var request = URLRequest(url: postsLastURL)
236 request.httpBody = try? JSONEncoder().encode(postRequest)
239 request.httpBody = try? JSONEncoder().encode(postRequest)
@@ -333,13 +336,10 @@ class Model{
333 }
336 }
334
337
335 // get channel (with id): in responce -- PostQuery
338 // get channel (with id): in responce -- PostQuery
336− static func getChannel(with channelId: Int, completion: @escaping (((users:[Int: Users], posts:[Posts]))->())){
339+ static func getChannel(with channelId: Int, on limit: Int = 10, from pointInTime: Int? = nil, completion: @escaping (((users:[Int: Users], posts:[Posts]))->()))
337− let json = [
340+ {
338− "request" : channelId,
341+ let postRequest = PostsLastRequest<Int>(limit: limit, exclusiveFrom: pointInTime, request: channelId)
339− "limit": 10
342+ let jsonData = try? JSONEncoder().encode(postRequest)
340− ]
341−
342− let jsonData = try? JSONSerialization.data(withJSONObject: json)
343
343
344 var request = URLRequest(url: channelsGetURL)
344 var request = URLRequest(url: channelsGetURL)
345 request.httpMethod = "POST"
345 request.httpMethod = "POST"