Display all threads

pull/404/head
Niels Andriesse 4 years ago
parent 69a9e2c76f
commit 4e487dd368

@ -165,6 +165,7 @@
B8041A9525C8FA1D003C2166 /* MediaLoaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8041A9425C8FA1D003C2166 /* MediaLoaderView.swift */; };
B8041AA725C90927003C2166 /* TypingIndicatorCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8041AA625C90927003C2166 /* TypingIndicatorCell.swift */; };
B80A579F23DFF1F300876683 /* NewClosedGroupVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B80A579E23DFF1F300876683 /* NewClosedGroupVC.swift */; };
B817AD9A26436593009DF825 /* SimplifiedConversationCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B817AD9926436593009DF825 /* SimplifiedConversationCell.swift */; };
B81D25C426157F40004D1FE1 /* storage-seed-3.crt in Resources */ = {isa = PBXBuildFile; fileRef = B81D25B926157F20004D1FE1 /* storage-seed-3.crt */; };
B81D25C526157F40004D1FE1 /* storage-seed-1.crt in Resources */ = {isa = PBXBuildFile; fileRef = B81D25B726157F20004D1FE1 /* storage-seed-1.crt */; };
B81D25C626157F40004D1FE1 /* public-loki-foundation.crt in Resources */ = {isa = PBXBuildFile; fileRef = B81D25B826157F20004D1FE1 /* public-loki-foundation.crt */; };
@ -1157,6 +1158,7 @@
B8041A9425C8FA1D003C2166 /* MediaLoaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaLoaderView.swift; sourceTree = "<group>"; };
B8041AA625C90927003C2166 /* TypingIndicatorCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypingIndicatorCell.swift; sourceTree = "<group>"; };
B80A579E23DFF1F300876683 /* NewClosedGroupVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewClosedGroupVC.swift; sourceTree = "<group>"; };
B817AD9926436593009DF825 /* SimplifiedConversationCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimplifiedConversationCell.swift; sourceTree = "<group>"; };
B81D25B726157F20004D1FE1 /* storage-seed-1.crt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "storage-seed-1.crt"; sourceTree = "<group>"; };
B81D25B826157F20004D1FE1 /* public-loki-foundation.crt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "public-loki-foundation.crt"; sourceTree = "<group>"; };
B81D25B926157F20004D1FE1 /* storage-seed-3.crt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "storage-seed-3.crt"; sourceTree = "<group>"; };
@ -1990,6 +1992,7 @@
34480B341FD0929200BC14EF /* ShareAppExtensionContext.h */,
34480B351FD0929200BC14EF /* ShareAppExtensionContext.m */,
C3ADC66026426688005F1414 /* ShareVC.swift */,
B817AD9926436593009DF825 /* SimplifiedConversationCell.swift */,
);
path = SessionShareExtension;
sourceTree = "<group>";
@ -4416,6 +4419,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B817AD9A26436593009DF825 /* SimplifiedConversationCell.swift in Sources */,
4535186B1FC635DD00210559 /* ShareViewController.swift in Sources */,
34480B361FD0929200BC14EF /* ShareAppExtensionContext.m in Sources */,
C3ADC66126426688005F1414 /* ShareVC.swift in Sources */,

@ -1,9 +1,30 @@
import SessionUIKit
final class ShareVC : UIViewController, AppModeManagerDelegate {
final class ShareVC : UIViewController, UITableViewDataSource, AppModeManagerDelegate {
@IBOutlet private var logoImageView: UIImageView!
private var areVersionMigrationsComplete = false
private var threads: YapDatabaseViewMappings!
private var threadViewModelCache: [String:ThreadViewModel] = [:] // Thread ID to ThreadViewModel
private var threadCount: UInt {
threads.numberOfItems(inGroup: TSInboxGroup)
}
private lazy var dbConnection: YapDatabaseConnection = {
let result = OWSPrimaryStorage.shared().newDatabaseConnection()
result.objectCacheLimit = 500
return result
}()
private lazy var tableView: UITableView = {
let result = UITableView()
result.backgroundColor = .clear
result.separatorStyle = .none
result.register(SimplifiedConversationCell.self, forCellReuseIdentifier: SimplifiedConversationCell.reuseIdentifier)
result.showsVerticalScrollIndicator = false
return result
}()
// MARK: Lifecycle
override func loadView() {
super.loadView()
@ -130,7 +151,21 @@ final class ShareVC : UIViewController, AppModeManagerDelegate {
}
private func setUpViewHierarchy() {
// Threads
dbConnection.beginLongLivedReadTransaction() // Freeze the connection for use on the main thread (this gives us a stable data source that doesn't change until we tell it to)
threads = YapDatabaseViewMappings(groups: [ TSInboxGroup ], view: TSThreadDatabaseViewExtensionName) // The extension should be registered at this point
threads.setIsReversed(true, forGroup: TSInboxGroup)
dbConnection.read { transaction in
self.threads.update(with: transaction) // Perform the initial update
}
// Logo
logoImageView.alpha = 0
// Table view
tableView.dataSource = self
view.addSubview(tableView)
tableView.pin(to: view)
// Reload
reload()
}
@objc
@ -159,7 +194,6 @@ final class ShareVC : UIViewController, AppModeManagerDelegate {
}
// MARK: App Mode
public func getCurrentAppMode() -> AppMode {
guard let window = self.view.window else { return .light }
let userInterfaceStyle = window.traitCollection.userInterfaceStyle
@ -170,4 +204,50 @@ final class ShareVC : UIViewController, AppModeManagerDelegate {
public func setCurrentAppMode(to appMode: AppMode) {
return // Not applicable to share extensions
}
// MARK: Table View Data Source
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Int(threadCount)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: SimplifiedConversationCell.reuseIdentifier) as! SimplifiedConversationCell
cell.threadViewModel = threadViewModel(at: indexPath.row)
return cell
}
// MARK: Updating
private func reload() {
AssertIsOnMainThread()
dbConnection.beginLongLivedReadTransaction() // Jump to the latest commit
dbConnection.read { transaction in
self.threads.update(with: transaction)
}
threadViewModelCache.removeAll()
tableView.reloadData()
}
// MARK: Convenience
private func thread(at index: Int) -> TSThread? {
var thread: TSThread? = nil
dbConnection.read { transaction in
let ext = transaction.ext(TSThreadDatabaseViewExtensionName) as! YapDatabaseViewTransaction
thread = ext.object(atRow: UInt(index), inSection: 0, with: self.threads) as! TSThread?
}
return thread
}
private func threadViewModel(at index: Int) -> ThreadViewModel? {
guard let thread = thread(at: index) else { return nil }
if let cachedThreadViewModel = threadViewModelCache[thread.uniqueId!] {
return cachedThreadViewModel
} else {
var threadViewModel: ThreadViewModel? = nil
dbConnection.read { transaction in
threadViewModel = ThreadViewModel(thread: thread, transaction: transaction)
}
threadViewModelCache[thread.uniqueId!] = threadViewModel
return threadViewModel
}
}
}

@ -0,0 +1,92 @@
import UIKit
import SessionUIKit
final class SimplifiedConversationCell : UITableViewCell {
var threadViewModel: ThreadViewModel! { didSet { update() } }
static let reuseIdentifier = "SimplifiedConversationCell"
// MARK: UI Components
private lazy var accentLineView: UIView = {
let result = UIView()
result.backgroundColor = Colors.destructive
return result
}()
private lazy var profilePictureView = ProfilePictureView()
private lazy var displayNameLabel: UILabel = {
let result = UILabel()
result.font = .boldSystemFont(ofSize: Values.mediumFontSize)
result.textColor = Colors.text
result.lineBreakMode = .byTruncatingTail
return result
}()
// MARK: Initialization
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setUpViewHierarchy()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setUpViewHierarchy()
}
private func setUpViewHierarchy() {
// Background color
backgroundColor = Colors.cellBackground
// Highlight color
let selectedBackgroundView = UIView()
selectedBackgroundView.backgroundColor = Colors.cellSelected
self.selectedBackgroundView = selectedBackgroundView
// Accent line view
accentLineView.set(.width, to: Values.accentLineThickness)
accentLineView.set(.height, to: 68)
// Profile picture view
let profilePictureViewSize = Values.mediumProfilePictureSize
profilePictureView.set(.width, to: profilePictureViewSize)
profilePictureView.set(.height, to: profilePictureViewSize)
profilePictureView.size = profilePictureViewSize
// Main stack view
let stackView = UIStackView(arrangedSubviews: [ accentLineView, profilePictureView, displayNameLabel ])
stackView.axis = .horizontal
stackView.alignment = .center
stackView.spacing = Values.mediumSpacing
addSubview(stackView)
stackView.pin(to: self)
}
// MARK: Updating
private func update() {
AssertIsOnMainThread()
guard let thread = threadViewModel?.threadRecord else { return }
let isBlocked: Bool
if let thread = thread as? TSContactThread {
isBlocked = SSKEnvironment.shared.blockingManager.isRecipientIdBlocked(thread.contactSessionID())
} else {
isBlocked = false
}
accentLineView.alpha = isBlocked ? 1 : 0
profilePictureView.update(for: thread)
displayNameLabel.text = getDisplayName()
}
private func getDisplayName() -> String {
if threadViewModel.isGroupThread {
if threadViewModel.name.isEmpty {
return "Unknown Group"
} else {
return threadViewModel.name
}
} else {
if threadViewModel.threadRecord.isNoteToSelf() {
return NSLocalizedString("NOTE_TO_SELF", comment: "")
} else {
let hexEncodedPublicKey = threadViewModel.contactSessionID!
return Storage.shared.getContact(with: hexEncodedPublicKey)?.displayName(for: .regular) ?? hexEncodedPublicKey
}
}
}
}
Loading…
Cancel
Save