Show sending status on 'My Story' row
This commit is contained in:
parent
5d21020614
commit
ac9265cf8d
@ -12,10 +12,12 @@ class MyStoryCell: UITableViewCell {
|
||||
|
||||
let titleLabel = UILabel()
|
||||
let titleChevron = UIImageView()
|
||||
let timestampLabel = UILabel()
|
||||
let subtitleLabel = UILabel()
|
||||
let avatarView = ConversationAvatarView(sizeClass: .fiftySix, localUserDisplayMode: .asUser, useAutolayout: true)
|
||||
let attachmentThumbnail = UIView()
|
||||
|
||||
let failedIconView = UIImageView()
|
||||
|
||||
let addStoryButton = OWSButton()
|
||||
|
||||
let contentHStackView = UIStackView()
|
||||
@ -36,12 +38,21 @@ class MyStoryCell: UITableViewCell {
|
||||
|
||||
titleChevron.image = chevronImage.withRenderingMode(.alwaysTemplate)
|
||||
|
||||
let hStack = UIStackView(arrangedSubviews: [titleLabel, titleChevron])
|
||||
hStack.axis = .horizontal
|
||||
hStack.alignment = .center
|
||||
hStack.spacing = 6
|
||||
let titleStack = UIStackView(arrangedSubviews: [titleLabel, titleChevron])
|
||||
titleStack.axis = .horizontal
|
||||
titleStack.alignment = .center
|
||||
titleStack.spacing = 6
|
||||
|
||||
let vStack = UIStackView(arrangedSubviews: [hStack, timestampLabel])
|
||||
failedIconView.autoSetDimension(.width, toSize: 16)
|
||||
failedIconView.contentMode = .scaleAspectFit
|
||||
failedIconView.tintColor = .ows_accentRed
|
||||
|
||||
let subtitleStack = UIStackView(arrangedSubviews: [failedIconView, subtitleLabel])
|
||||
subtitleStack.axis = .horizontal
|
||||
subtitleStack.alignment = .center
|
||||
subtitleStack.spacing = 6
|
||||
|
||||
let vStack = UIStackView(arrangedSubviews: [titleStack, subtitleStack])
|
||||
vStack.axis = .vertical
|
||||
vStack.alignment = .leading
|
||||
|
||||
@ -66,7 +77,7 @@ class MyStoryCell: UITableViewCell {
|
||||
}
|
||||
|
||||
func configure(with model: MyStoryViewModel, addStoryAction: @escaping () -> Void) {
|
||||
configureTimestamp(with: model)
|
||||
configureSubtitle(with: model)
|
||||
|
||||
titleLabel.font = .ows_dynamicTypeHeadline
|
||||
titleLabel.textColor = Theme.primaryTextColor
|
||||
@ -114,13 +125,24 @@ class MyStoryCell: UITableViewCell {
|
||||
}
|
||||
}
|
||||
|
||||
func configureTimestamp(with model: MyStoryViewModel) {
|
||||
timestampLabel.font = .ows_dynamicTypeSubheadline
|
||||
timestampLabel.textColor = Theme.secondaryTextAndIconColor
|
||||
if let latestMessageTimestamp = model.latestMessageTimestamp {
|
||||
timestampLabel.text = DateUtil.formatTimestampRelatively(latestMessageTimestamp)
|
||||
func configureSubtitle(with model: MyStoryViewModel) {
|
||||
subtitleLabel.font = .ows_dynamicTypeSubheadline
|
||||
subtitleLabel.textColor = Theme.secondaryTextAndIconColor
|
||||
failedIconView.image = Theme.iconImage(.error16)
|
||||
|
||||
if model.sendingCount > 0 {
|
||||
let format = NSLocalizedString("STORY_SENDING_%d", tableName: "PluralAware", comment: "Indicates that N stories are currently sending")
|
||||
subtitleLabel.text = .localizedStringWithFormat(format, model.sendingCount)
|
||||
failedIconView.isHiddenInStackView = !model.hasFailedSends
|
||||
} else if model.hasFailedSends {
|
||||
failedIconView.isHiddenInStackView = false
|
||||
subtitleLabel.text = NSLocalizedString("STORY_SEND_FAILED", comment: "Text indicating that the story send has failed")
|
||||
} else if let latestMessageTimestamp = model.latestMessageTimestamp {
|
||||
subtitleLabel.text = DateUtil.formatTimestampRelatively(latestMessageTimestamp)
|
||||
failedIconView.isHiddenInStackView = true
|
||||
} else {
|
||||
timestampLabel.text = nil
|
||||
subtitleLabel.text = nil
|
||||
failedIconView.isHiddenInStackView = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,12 +10,19 @@ struct MyStoryViewModel: Dependencies {
|
||||
|
||||
let latestMessageAttachment: StoryThumbnailView.Attachment?
|
||||
let latestMessageTimestamp: UInt64?
|
||||
let sendingCount: UInt64
|
||||
let hasFailedSends: Bool
|
||||
|
||||
let secondLatestMessageAttachment: StoryThumbnailView.Attachment?
|
||||
|
||||
init(messages: [StoryMessage], transaction: SDSAnyReadTransaction) {
|
||||
let sortedFilteredMessages = messages.sorted { $0.timestamp < $1.timestamp }
|
||||
self.messages = sortedFilteredMessages
|
||||
sendingCount = messages.reduce(0) {
|
||||
$0 + ([.sending, .pending].contains($1.sendingState) ? 1 : 0)
|
||||
}
|
||||
hasFailedSends = messages.contains { $0.sendingState == .failed }
|
||||
|
||||
let sortedFilteredMessages = messages.sorted { $0.timestamp < $1.timestamp }.prefix(2)
|
||||
self.messages = Array(sortedFilteredMessages)
|
||||
|
||||
if let latestMessage = sortedFilteredMessages.last {
|
||||
latestMessageAttachment = .from(latestMessage.attachment, transaction: transaction)
|
||||
|
||||
@ -76,7 +76,7 @@ class StoriesViewController: OWSViewController, StoryListDataSourceDelegate {
|
||||
case .myStory:
|
||||
guard let cell = self.tableView.cellForRow(at: indexPath) as? MyStoryCell else { continue }
|
||||
guard let model = self.dataSource.myStory else { continue }
|
||||
cell.configureTimestamp(with: model)
|
||||
cell.configureSubtitle(with: model)
|
||||
case .visibleStories, .hiddenStories:
|
||||
guard let cell = self.tableView.cellForRow(at: indexPath) as? StoryCell else { continue }
|
||||
guard let model = self.model(for: indexPath) else { continue }
|
||||
|
||||
@ -74,7 +74,7 @@ class StoryListDataSource: NSObject, Dependencies {
|
||||
let (listStories, outgoingStories) = Self.databaseStorage.read {
|
||||
(
|
||||
StoryFinder.storiesForListView(transaction: $0),
|
||||
StoryFinder.outgoingStories(limit: 2, transaction: $0)
|
||||
StoryFinder.outgoingStories(transaction: $0)
|
||||
)
|
||||
}
|
||||
let myStoryModel = Self.databaseStorage.read { MyStoryViewModel(messages: outgoingStories, transaction: $0) }
|
||||
@ -429,7 +429,7 @@ class StoryListDataSource: NSObject, Dependencies {
|
||||
) -> MyStoryViewModel? {
|
||||
let oldStoryModel = oldModel.myStory
|
||||
let outgoingStories = Self.databaseStorage.read {
|
||||
StoryFinder.outgoingStories(limit: 2, transaction: $0)
|
||||
StoryFinder.outgoingStories(transaction: $0)
|
||||
}
|
||||
let myStoryChanged = changedMessageRowIds.intersection(outgoingStories.map { $0.id! }).count > 0
|
||||
|| Set(oldStoryModel?.messages.map { $0.uniqueId } ?? []) != Set(outgoingStories.map { $0.uniqueId })
|
||||
@ -458,7 +458,7 @@ class StoryListDataSource: NSObject, Dependencies {
|
||||
// My story should never go away after being loaded, but for the sake of completeness...
|
||||
tableView.deleteRows(at: [IndexPath(row: 0, section: Section.myStory.rawValue)], with: .automatic)
|
||||
} else if changes.myStoryChanged {
|
||||
tableView.reloadRows(at: [IndexPath(row: 0, section: Section.myStory.rawValue)], with: .automatic)
|
||||
tableView.reloadRows(at: [IndexPath(row: 0, section: Section.myStory.rawValue)], with: .none)
|
||||
}
|
||||
|
||||
// Visible stories section is always visible, directly apply changes.
|
||||
|
||||
@ -1149,6 +1149,22 @@
|
||||
<string>%d Excluded</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>STORY_SENDING_%d</key>
|
||||
<dict>
|
||||
<key>NSStringLocalizedFormatKey</key>
|
||||
<string>%#@caption@</string>
|
||||
<key>caption</key>
|
||||
<dict>
|
||||
<key>NSStringFormatSpecTypeKey</key>
|
||||
<string>NSStringPluralRuleType</string>
|
||||
<key>NSStringFormatValueTypeKey</key>
|
||||
<string>d</string>
|
||||
<key>one</key>
|
||||
<string>Sending...</string>
|
||||
<key>other</key>
|
||||
<string>Sending %d...</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>STORY_VIEWS_COUNT_%d</key>
|
||||
<dict>
|
||||
<key>NSStringLocalizedFormatKey</key>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user