Strated to work on dialogs: getAll is done, need to add other functionality and change design

This commit is contained in:
Darya Rednikina 2019-05-03 22:52:03 +03:00
parent 6850d7679c
commit a32c3421d1
8 changed files with 287 additions and 180 deletions

View File

@ -570,7 +570,7 @@
<scene sceneID="6Td-bq-Ebf">
<objects>
<tableViewController storyboardIdentifier="PeopleToWriteViewController" id="rUc-Tv-hWE" customClass="PeopleToWriteViewController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="PDb-NB-Ey6">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" allowsSelectionDuringEditing="YES" allowsMultipleSelection="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="PDb-NB-Ey6">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>

View File

@ -61,5 +61,7 @@ let addToChannelVCId = "AddToChannelVC"
let taggsSelectionViewController = "TaggsSelectionViewController"
let dialogViewController = "DialogViewController"
let blueSystemColor = UIColor(red: 0, green: 137/255, blue: 249/255, alpha: 0.5)

View File

@ -35,9 +35,9 @@ class MessagesCoordinator: BaseCoordinator {
vc?.navigationController?.pushViewController(newVC, animated: true)
}
vc.onDialogDisplay = { [weak vc, unowned self] in
vc.onDialogDisplay = { [weak vc, unowned self] _ in
let newVC = self.storyboard.instantiateViewController(withIdentifier: dialogVC) as! DialogViewController
newVC.currentDialog = $0
//newVC.currentDialog = $0
vc?.navigationController?.pushViewController(newVC, animated: true)
}
navigationController?.viewControllers = [vc]

View File

@ -11,82 +11,57 @@ import UIKit
class DialogViewController: UITableViewController {
var onInfoShow: (()->())?
var currentDialog: (id: Int, name: String)?
var group: Model.Group?
override func viewDidLoad() {
super.viewDidLoad()
if let person = currentDialog {
navigationItem.title = person.name
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
if let id = group {
navigationItem.title = "🌌 \(id.id) \(id.name)"
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Info", style: .plain, target: self, action: #selector(moveToInfoVC))
}
}
@objc func moveToInfoVC(){
}
var currentMessagesInChat: [Model.LastMessage]? {
didSet {
tableView.reloadData()
}
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 0
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 0
return currentMessagesInChat?.count ?? 0
}
/*
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
// Configure the cell...
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let group = group {
Model.getMessagesForGroupChat(chat: group.id) { [unowned self] in
self.currentMessagesInChat = $0
}
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.detailTextLabel?.text = currentMessagesInChat![indexPath.row].body.markdown
cell.textLabel?.text = "\(currentMessagesInChat![indexPath.row].author)"
return cell
}
*/
/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}

View File

@ -11,11 +11,15 @@ import UIKit
class MessagesViewController: UITableViewController {
// curreent Active which can be displayed
var currentActiveDialogs: [(id: Int, name: String)] = [(id: Int, name: String)]()
var currentActiveDialogs: [Model.Dialog] = [] {
didSet{
tableView.reloadData()
}
}
var onUserDisplayList: (()->())?
var onDialogDisplay: (((id: Int, name: String))->())?
var onDialogDisplay: ((Model.Dialog)->())?
let searchC = UISearchController(searchResultsController: nil)
@ -39,10 +43,12 @@ class MessagesViewController: UITableViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
Model.getChatAll { [weak self] in
self?.currentActiveDialogs = $0
}
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
@ -56,8 +62,14 @@ class MessagesViewController: UITableViewController {
{
let cell = tableView.dequeueReusableCell(withIdentifier: "MessagesCell", for: indexPath)
cell.textLabel?.text = currentActiveDialogs[indexPath.row].name
cell.detailTextLabel?.text = "from \(currentActiveDialogs[indexPath.row].name) some message is displayed here..."
switch currentActiveDialogs[indexPath.row].self {
case .groupChat(let group):
cell.textLabel?.text = group.group.name
cell.detailTextLabel?.text = group.lastMessage.body.markdown
case .userChat(let userChat):
cell.textLabel?.text = "\(userChat.user)"
cell.detailTextLabel?.text = userChat.lastMessage.body.markdown
}
return cell
}
@ -65,49 +77,4 @@ class MessagesViewController: UITableViewController {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
onDialogDisplay?(currentActiveDialogs[indexPath.row])
}
/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}

View File

@ -14,17 +14,24 @@ class PeopleToWriteViewController: UITableViewController {
let searchC = UISearchController(searchResultsController: nil)
let users = [(id: 9,name: "Anna Mikhaleva")]
let users = Model.Channels.fullPeople
var chosenUsers: [Int: Model.UserPermission] = [:]
override func viewDidLoad() {
super.viewDidLoad()
tableView.isEditing = true
self.navigationItem.title = "People"
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(newMessage))
self.navigationItem.largeTitleDisplayMode = .never
self.navigationItem.searchController = searchC
self.navigationItem.hidesSearchBarWhenScrolling = false
}
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(true, animated: animated)
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
@ -37,72 +44,33 @@ class PeopleToWriteViewController: UITableViewController {
return users.count
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
chosenUsers[users[indexPath.row].id] = Model.UserPermission(isAdmin: false)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "peopleToWriteCell", for: indexPath)
cell.textLabel?.text = users[indexPath.row].name
cell.textLabel?.text = users[indexPath.row].fullName()
cell.detailTextLabel?.text = "\(users[indexPath.row].id)"
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
navigationController?.popViewController(animated: true)
guard let _ = self.navigationController?.viewControllers.lastIndex(of: self) else
@objc func newMessage()
{
if chosenUsers.count != 0
{
(navigationController?.viewControllers.last as? MessagesViewController)?.currentActiveDialogs.append(users[indexPath.row])
(navigationController?.viewControllers.last as? MessagesViewController)?.onDialogDisplay?(users[indexPath.row])
return
navigationController?.popViewController(animated: false)
var group = Model.Group(users: chosenUsers, name: "Untitled", id: 0)
Model.createGroupChat(from: group) { [unowned self] (id) in
let vc = self.storyboard?.instantiateViewController(withIdentifier: dialogViewController) as! DialogViewController
group.id = id
vc.group = group
self.navigationController?.pushViewController(vc, animated: true)
}
}
}
/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}

View File

@ -27,7 +27,8 @@ struct CompletionTree: Codable {
}
}
static func getValues(tree: CompletionTree) -> [String] {
static func getValues(tree: CompletionTree) -> [String]
{
var out = [String]()
if let treeVal = tree.value {

View File

@ -51,9 +51,9 @@ class Model{
static let messagesUserChatURL = URL(string: "\(baseUrl)/messages/userChat")!
struct QueryPosts: Codable {
struct QueryPosts<T: Codable>: Codable {
var users: [Int: Users]
var response: [Posts]
var response: [T]
}
struct Posts: Codable {
@ -269,7 +269,7 @@ class Model{
guard let json = response.data else { return }
guard let newQueery = try? decoder.decode(QueryPosts.self, from: json) else { print("no")
guard let newQueery = try? decoder.decode(QueryPosts<Posts>.self, from: json) else { print("no")
return }
idUser = newQueery.users
@ -319,7 +319,7 @@ class Model{
guard let json = response.data else { return }
guard let newPost = try? decoder.decode(QueryPosts.self, from: json) else { return }
guard let newPost = try? decoder.decode(QueryPosts<Posts>.self, from: json) else { return }
completion(newPost.response)
}
@ -377,7 +377,7 @@ class Model{
guard let json = response.data else { return }
guard let newQueery = try? decoder.decode(QueryPosts.self, from: json) else { return }
guard let newQueery = try? decoder.decode(QueryPosts<Posts>.self, from: json) else { return }
idUser = newQueery.users
completion((newQueery.users, newQueery.response))
@ -539,7 +539,7 @@ class Model{
guard let json = response.data else { return }
guard let newQueery = try? decoder.decode(QueryPosts.self, from: json) else { return }
guard let newQueery = try? decoder.decode(QueryPosts<Posts>.self, from: json) else { return }
// idUser = newQueery.users
completion((newQueery.users, newQueery.response))
@ -550,11 +550,205 @@ class Model{
AF.request(URLRequest(url: hashTagTreeURL)).responseJSON {
(response) in
isValidTocken?(response.response?.statusCode ?? 498)
guard let json = response.data else { return }
guard let tree = try? decoder.decode(CompletionTree.self, from: json) else { return }
completion(tree)
}
}
static func getChatAll(limit: Int = 10, exclusiveFrom: Int? = nil, request: [Int] = [], completion: @escaping (([Dialog])->()))
{
let req = GeneralRequest<[Int]>(limit: limit, exclusiveFrom: exclusiveFrom, request: request)
var request = URLRequest(url: chatsGetAllURL)
request.httpMethod = "POST"
request.httpBody = try? JSONEncoder().encode(req)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
AF.request(request).responseJSON { response in
isValidTocken?(response.response?.statusCode ?? 498)
guard let json = response.data else { return }
let dialogs = try! decoder.decode(QueryPosts<Dialog>.self, from: json)
print(dialogs.response)
completion(dialogs.response)
}
}
enum Dialog: Codable
{
case groupChat(GroupChat)
case userChat(UserChat)
private enum DialogKeys: CodingKey{
case groupChat
case userChat
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: DialogKeys.self)
if container.contains(.groupChat){
self = .groupChat(try GroupChat(from: container.superDecoder(forKey: .groupChat)))
} else if container.contains(.userChat){
self = .userChat(try UserChat(from: container.superDecoder(forKey: .userChat)))
} else {
throw DecodingError.keyNotFound(DialogKeys.groupChat, DecodingError.Context(codingPath: container.codingPath, debugDescription: "hz"))
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: DialogKeys.self)
switch self{
case .groupChat(let chat):
try chat.encode(to: container.superEncoder(forKey: .groupChat))
case .userChat(let chat):
try chat.encode(to: container.superEncoder(forKey: .userChat))
}
}
}
struct GroupChat: Codable {
var group: Group
var lastMessage: LastMessage
}
struct UserChat: Codable {
var user: Int
var lastMessage: LastMessage
}
struct Group: Codable {
var users: [Int: UserPermission]
var name: String
var id: Int
}
struct UserPermission: Codable {
var isAdmin: Bool
}
struct LastMessage: Codable {
var body: Attachments
var destination: MessageDestination
var time: String
var author: Int
var id: Int
private enum MessageCodingKeys: CodingKey{
case user
case group
case body
case time
case author
case id
}
init(from decoder: Decoder) throws
{
let container = try decoder.container(keyedBy: MessageCodingKeys.self)
time = try container.decode(String.self, forKey: .time)
body = try container.decode(Attachments.self, forKey: .body)
author = try container.decode(Int.self, forKey: .author)
id = try container.decode(Int.self, forKey: .id)
if container.contains(.user){
destination = MessageDestination.userChatDestination(try Int(from: container.superDecoder(forKey: .user)))
} else if container.contains(.group){
destination = MessageDestination.groupChatDestination(try Int(from: container.superDecoder(forKey: .group)))
} else {
throw DecodingError.keyNotFound(MessageCodingKeys.group, DecodingError.Context(codingPath: container.codingPath, debugDescription: "hz gr"))
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: MessageCodingKeys.self)
try container.encode(time, forKey: .time)
try container.encode(id, forKey: .id)
try container.encode(author, forKey: .author)
try container.encode(body, forKey: .body)
switch destination {
case .userChatDestination(let uId):
try uId.encode(to: container.superEncoder(forKey: .user))
case .groupChatDestination(let gId):
try gId.encode(to: container.superEncoder(forKey: .group))
}
}
}
enum MessageDestination: Codable
{
func encode(to encoder: Encoder) throws
{
var container = encoder.container(keyedBy: MessCodingKeys.self)
switch self {
case .userChatDestination(let uId):
try uId.encode(to: container.superEncoder(forKey: .user))
case .groupChatDestination(let gId):
try gId.encode(to: container.superEncoder(forKey: .group))
}
}
init(from decoder: Decoder) throws
{
let container = try decoder.container(keyedBy: MessCodingKeys.self)
if container.contains(.user){
self = .userChatDestination(try Int(from: container.superDecoder(forKey: .user)))
} else if container.contains(.group){
self = .groupChatDestination(try Int(from: container.superDecoder(forKey: .group)))
} else {
throw DecodingError.keyNotFound(MessCodingKeys.group, DecodingError.Context(codingPath: container.codingPath, debugDescription: "hz gr"))
}
}
enum MessCodingKeys: CodingKey{
case user
case group
}
case userChatDestination(Int)
case groupChatDestination(Int)
}
static func createGroupChat(from group: Group, completion: @escaping ((Int)->())) {
let req = group
var request = URLRequest(url: createGroupChatURL)
request.httpMethod = "POST"
request.httpBody = try? JSONEncoder().encode(req)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
AF.request(request).response { (response) in
isValidTocken?(response.response?.statusCode ?? 498)
guard let json = response.data else { return }
let stringInt = String.init(data: json, encoding: String.Encoding.utf8)
let intId = Int.init(stringInt!)
completion(intId!)
}
}
static func getMessagesForGroupChat(chat id: Int, exclusiveFrom: Int? = nil, limit l: Int = 10, direction: String = "backward", completion: @escaping (([LastMessage])->()))
{
let req = GeneralRequest<Int>(direction: direction, limit: l, exclusiveFrom: exclusiveFrom, request: id)
var request = URLRequest(url: messagesGetGroupChatURL)
request.httpMethod = "POST"
request.httpBody = try? JSONEncoder().encode(req)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
AF.request(request).response { (response) in
isValidTocken?(response.response?.statusCode ?? 498)
guard let json = response.data else { return }
guard let messages = try? decoder.decode([LastMessage].self, from: json) else { return }
completion(messages)
}
}
}