mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-22 16:21:00 +00:00
Sensitive attachments
This commit is contained in:
parent
40b795cd7e
commit
cc370af881
25 changed files with 250 additions and 136 deletions
|
@ -62,7 +62,11 @@ extension ContentDatabase {
|
||||||
t.column("pinned", .boolean)
|
t.column("pinned", .boolean)
|
||||||
}
|
}
|
||||||
|
|
||||||
try db.create(table: "statusShowMoreToggle") { t in
|
try db.create(table: "statusShowContentToggle") { t in
|
||||||
|
t.column("statusId", .text).primaryKey().references("statusRecord", onDelete: .cascade)
|
||||||
|
}
|
||||||
|
|
||||||
|
try db.create(table: "statusShowAttachmentsToggle") { t in
|
||||||
t.column("statusId", .text).primaryKey().references("statusRecord", onDelete: .cascade)
|
t.column("statusId", .text).primaryKey().references("statusRecord", onDelete: .cascade)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,37 +149,56 @@ public extension ContentDatabase {
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
func toggleShowMore(id: Status.Id) -> AnyPublisher<Never, Error> {
|
func toggleShowContent(id: Status.Id) -> AnyPublisher<Never, Error> {
|
||||||
databaseWriter.writePublisher {
|
databaseWriter.writePublisher {
|
||||||
if let toggle = try StatusShowMoreToggle
|
if let toggle = try StatusShowContentToggle
|
||||||
.filter(StatusShowMoreToggle.Columns.statusId == id)
|
.filter(StatusShowContentToggle.Columns.statusId == id)
|
||||||
.fetchOne($0) {
|
.fetchOne($0) {
|
||||||
try toggle.delete($0)
|
try toggle.delete($0)
|
||||||
} else {
|
} else {
|
||||||
try StatusShowMoreToggle(statusId: id).save($0)
|
try StatusShowContentToggle(statusId: id).save($0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.ignoreOutput()
|
.ignoreOutput()
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
func showMore(ids: Set<Status.Id>) -> AnyPublisher<Never, Error> {
|
func toggleShowAttachments(id: Status.Id) -> AnyPublisher<Never, Error> {
|
||||||
|
databaseWriter.writePublisher {
|
||||||
|
if let toggle = try StatusShowAttachmentsToggle
|
||||||
|
.filter(StatusShowAttachmentsToggle.Columns.statusId == id)
|
||||||
|
.fetchOne($0) {
|
||||||
|
try toggle.delete($0)
|
||||||
|
} else {
|
||||||
|
try StatusShowAttachmentsToggle(statusId: id).save($0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ignoreOutput()
|
||||||
|
.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
func expand(ids: Set<Status.Id>) -> AnyPublisher<Never, Error> {
|
||||||
databaseWriter.writePublisher {
|
databaseWriter.writePublisher {
|
||||||
for id in ids {
|
for id in ids {
|
||||||
try StatusShowMoreToggle(statusId: id).save($0)
|
try StatusShowContentToggle(statusId: id).save($0)
|
||||||
|
try StatusShowAttachmentsToggle(statusId: id).save($0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.ignoreOutput()
|
.ignoreOutput()
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
func showLess(ids: Set<Status.Id>) -> AnyPublisher<Never, Error> {
|
func collapse(ids: Set<Status.Id>) -> AnyPublisher<Never, Error> {
|
||||||
databaseWriter.writePublisher(
|
databaseWriter.writePublisher {
|
||||||
updates: StatusShowMoreToggle
|
try StatusShowContentToggle
|
||||||
.filter(ids.contains(StatusShowMoreToggle.Columns.statusId))
|
.filter(ids.contains(StatusShowContentToggle.Columns.statusId))
|
||||||
.deleteAll)
|
.deleteAll($0)
|
||||||
.ignoreOutput()
|
try StatusShowAttachmentsToggle
|
||||||
.eraseToAnyPublisher()
|
.filter(ids.contains(StatusShowContentToggle.Columns.statusId))
|
||||||
|
.deleteAll($0)
|
||||||
|
}
|
||||||
|
.ignoreOutput()
|
||||||
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
func append(accounts: [Account], toList list: AccountList) -> AnyPublisher<Never, Error> {
|
func append(accounts: [Account], toList list: AccountList) -> AnyPublisher<Never, Error> {
|
||||||
|
|
|
@ -35,7 +35,8 @@ extension ContextItemsInfo {
|
||||||
|
|
||||||
return .status(
|
return .status(
|
||||||
.init(info: statusInfo),
|
.init(info: statusInfo),
|
||||||
.init(showMoreToggled: statusInfo.showMoreToggled,
|
.init(showContentToggled: statusInfo.showContentToggled,
|
||||||
|
showAttachmentsToggled: statusInfo.showAttachmentsToggled,
|
||||||
isContextParent: statusInfo.record.id == parent.record.id,
|
isContextParent: statusInfo.record.id == parent.record.id,
|
||||||
isReplyInContext: isReplyInContext,
|
isReplyInContext: isReplyInContext,
|
||||||
hasReplyFollowing: hasReplyFollowing))
|
hasReplyFollowing: hasReplyFollowing))
|
||||||
|
|
|
@ -8,8 +8,10 @@ struct StatusInfo: Codable, Hashable, FetchableRecord {
|
||||||
let accountInfo: AccountInfo
|
let accountInfo: AccountInfo
|
||||||
let reblogAccountInfo: AccountInfo?
|
let reblogAccountInfo: AccountInfo?
|
||||||
let reblogRecord: StatusRecord?
|
let reblogRecord: StatusRecord?
|
||||||
let showMoreToggle: StatusShowMoreToggle?
|
let showContentToggle: StatusShowContentToggle?
|
||||||
let reblogShowMoreToggle: StatusShowMoreToggle?
|
let reblogShowContentToggle: StatusShowContentToggle?
|
||||||
|
let showAttachmentsToggle: StatusShowAttachmentsToggle?
|
||||||
|
let reblogShowAttachmentsToggle: StatusShowAttachmentsToggle?
|
||||||
}
|
}
|
||||||
|
|
||||||
extension StatusInfo {
|
extension StatusInfo {
|
||||||
|
@ -18,9 +20,11 @@ extension StatusInfo {
|
||||||
.including(optional: AccountInfo.addingIncludes(StatusRecord.reblogAccount)
|
.including(optional: AccountInfo.addingIncludes(StatusRecord.reblogAccount)
|
||||||
.forKey(CodingKeys.reblogAccountInfo))
|
.forKey(CodingKeys.reblogAccountInfo))
|
||||||
.including(optional: StatusRecord.reblog.forKey(CodingKeys.reblogRecord))
|
.including(optional: StatusRecord.reblog.forKey(CodingKeys.reblogRecord))
|
||||||
.including(optional: StatusRecord.showMoreToggle.forKey(CodingKeys.showMoreToggle))
|
.including(optional: StatusRecord.showContentToggle.forKey(CodingKeys.showContentToggle))
|
||||||
.including(optional: StatusRecord.reblogShowMoreToggle
|
.including(optional: StatusRecord.reblogShowContentToggle.forKey(CodingKeys.reblogShowContentToggle))
|
||||||
.forKey(CodingKeys.reblogShowMoreToggle))
|
.including(optional: StatusRecord.showAttachmentsToggle.forKey(CodingKeys.showAttachmentsToggle))
|
||||||
|
.including(optional: StatusRecord.reblogShowAttachmentsToggle
|
||||||
|
.forKey(CodingKeys.reblogShowAttachmentsToggle))
|
||||||
}
|
}
|
||||||
|
|
||||||
static func request(_ request: QueryInterfaceRequest<StatusRecord>) -> QueryInterfaceRequest<Self> {
|
static func request(_ request: QueryInterfaceRequest<StatusRecord>) -> QueryInterfaceRequest<Self> {
|
||||||
|
@ -31,7 +35,11 @@ extension StatusInfo {
|
||||||
(record.filterableContent + (reblogRecord?.filterableContent ?? [])).joined(separator: " ")
|
(record.filterableContent + (reblogRecord?.filterableContent ?? [])).joined(separator: " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
var showMoreToggled: Bool {
|
var showContentToggled: Bool {
|
||||||
showMoreToggle != nil || reblogShowMoreToggle != nil
|
showContentToggle != nil || reblogShowContentToggle != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var showAttachmentsToggled: Bool {
|
||||||
|
showAttachmentsToggle != nil || reblogShowAttachmentsToggle != nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,11 +92,16 @@ extension StatusRecord {
|
||||||
through: Self.reblogAccount,
|
through: Self.reblogAccount,
|
||||||
using: AccountRecord.moved)
|
using: AccountRecord.moved)
|
||||||
static let reblog = belongsTo(StatusRecord.self)
|
static let reblog = belongsTo(StatusRecord.self)
|
||||||
static let showMoreToggle = hasOne(StatusShowMoreToggle.self)
|
static let showContentToggle = hasOne(StatusShowContentToggle.self)
|
||||||
static let reblogShowMoreToggle = hasOne(
|
static let reblogShowContentToggle = hasOne(
|
||||||
StatusShowMoreToggle.self,
|
StatusShowContentToggle.self,
|
||||||
through: Self.reblog,
|
through: Self.reblog,
|
||||||
using: Self.showMoreToggle)
|
using: Self.showContentToggle)
|
||||||
|
static let showAttachmentsToggle = hasOne(StatusShowAttachmentsToggle.self)
|
||||||
|
static let reblogShowAttachmentsToggle = hasOne(
|
||||||
|
StatusShowAttachmentsToggle.self,
|
||||||
|
through: Self.reblog,
|
||||||
|
using: Self.showAttachmentsToggle)
|
||||||
static let ancestorJoins = hasMany(
|
static let ancestorJoins = hasMany(
|
||||||
StatusAncestorJoin.self,
|
StatusAncestorJoin.self,
|
||||||
using: ForeignKey([StatusAncestorJoin.Columns.parentId]))
|
using: ForeignKey([StatusAncestorJoin.Columns.parentId]))
|
||||||
|
|
25
DB/Sources/DB/Content/StatusShowAttachmentsToggle.swift
Normal file
25
DB/Sources/DB/Content/StatusShowAttachmentsToggle.swift
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright © 2020 Metabolist. All rights reserved.
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import GRDB
|
||||||
|
import Mastodon
|
||||||
|
|
||||||
|
struct StatusShowAttachmentsToggle: Codable, Hashable {
|
||||||
|
let statusId: Status.Id
|
||||||
|
}
|
||||||
|
|
||||||
|
extension StatusShowAttachmentsToggle {
|
||||||
|
enum Columns {
|
||||||
|
static let statusId = Column(StatusShowAttachmentsToggle.CodingKeys.statusId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension StatusShowAttachmentsToggle: FetchableRecord, PersistableRecord {
|
||||||
|
static func databaseJSONDecoder(for column: String) -> JSONDecoder {
|
||||||
|
MastodonDecoder()
|
||||||
|
}
|
||||||
|
|
||||||
|
static func databaseJSONEncoder(for column: String) -> JSONEncoder {
|
||||||
|
MastodonEncoder()
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,17 +4,17 @@ import Foundation
|
||||||
import GRDB
|
import GRDB
|
||||||
import Mastodon
|
import Mastodon
|
||||||
|
|
||||||
struct StatusShowMoreToggle: Codable, Hashable {
|
struct StatusShowContentToggle: Codable, Hashable {
|
||||||
let statusId: Status.Id
|
let statusId: Status.Id
|
||||||
}
|
}
|
||||||
|
|
||||||
extension StatusShowMoreToggle {
|
extension StatusShowContentToggle {
|
||||||
enum Columns {
|
enum Columns {
|
||||||
static let statusId = Column(StatusShowMoreToggle.CodingKeys.statusId)
|
static let statusId = Column(StatusShowContentToggle.CodingKeys.statusId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension StatusShowMoreToggle: FetchableRecord, PersistableRecord {
|
extension StatusShowContentToggle: FetchableRecord, PersistableRecord {
|
||||||
static func databaseJSONDecoder(for column: String) -> JSONDecoder {
|
static func databaseJSONDecoder(for column: String) -> JSONDecoder {
|
||||||
MastodonDecoder()
|
MastodonDecoder()
|
||||||
}
|
}
|
|
@ -35,7 +35,8 @@ extension TimelineItemsInfo {
|
||||||
.map {
|
.map {
|
||||||
CollectionItem.status(
|
CollectionItem.status(
|
||||||
.init(info: $0),
|
.init(info: $0),
|
||||||
.init(showMoreToggled: $0.showMoreToggled))
|
.init(showContentToggled: $0.showContentToggled,
|
||||||
|
showAttachmentsToggled: $0.showAttachmentsToggled))
|
||||||
}
|
}
|
||||||
|
|
||||||
for loadMoreRecord in loadMoreRecords {
|
for loadMoreRecord in loadMoreRecords {
|
||||||
|
@ -58,7 +59,9 @@ extension TimelineItemsInfo {
|
||||||
.map {
|
.map {
|
||||||
CollectionItem.status(
|
CollectionItem.status(
|
||||||
.init(info: $0),
|
.init(info: $0),
|
||||||
.init(showMoreToggled: $0.showMoreToggled, isPinned: true))
|
.init(showContentToggled: $0.showContentToggled,
|
||||||
|
showAttachmentsToggled: $0.showAttachmentsToggled,
|
||||||
|
isPinned: true))
|
||||||
},
|
},
|
||||||
timelineItems]
|
timelineItems]
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,18 +10,21 @@ public enum CollectionItem: Hashable {
|
||||||
|
|
||||||
public extension CollectionItem {
|
public extension CollectionItem {
|
||||||
struct StatusConfiguration: Hashable {
|
struct StatusConfiguration: Hashable {
|
||||||
public let showMoreToggled: Bool
|
public let showContentToggled: Bool
|
||||||
|
public let showAttachmentsToggled: Bool
|
||||||
public let isContextParent: Bool
|
public let isContextParent: Bool
|
||||||
public let isPinned: Bool
|
public let isPinned: Bool
|
||||||
public let isReplyInContext: Bool
|
public let isReplyInContext: Bool
|
||||||
public let hasReplyFollowing: Bool
|
public let hasReplyFollowing: Bool
|
||||||
|
|
||||||
init(showMoreToggled: Bool,
|
init(showContentToggled: Bool,
|
||||||
|
showAttachmentsToggled: Bool,
|
||||||
isContextParent: Bool = false,
|
isContextParent: Bool = false,
|
||||||
isPinned: Bool = false,
|
isPinned: Bool = false,
|
||||||
isReplyInContext: Bool = false,
|
isReplyInContext: Bool = false,
|
||||||
hasReplyFollowing: Bool = false) {
|
hasReplyFollowing: Bool = false) {
|
||||||
self.showMoreToggled = showMoreToggled
|
self.showContentToggled = showContentToggled
|
||||||
|
self.showAttachmentsToggled = showAttachmentsToggled
|
||||||
self.isContextParent = isContextParent
|
self.isContextParent = isContextParent
|
||||||
self.isPinned = isPinned
|
self.isPinned = isPinned
|
||||||
self.isReplyInContext = isReplyInContext
|
self.isReplyInContext = isReplyInContext
|
||||||
|
@ -31,5 +34,5 @@ public extension CollectionItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension CollectionItem.StatusConfiguration {
|
public extension CollectionItem.StatusConfiguration {
|
||||||
static let `default` = Self(showMoreToggled: false)
|
static let `default` = Self(showContentToggled: false, showAttachmentsToggled: false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,20 +30,5 @@ class TableViewDataSource: UITableViewDiffableDataSource<Int, CollectionItemIden
|
||||||
|
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultRowAnimation = .none
|
|
||||||
}
|
|
||||||
|
|
||||||
override func apply(_ snapshot: NSDiffableDataSourceSnapshot<Int, CollectionItemIdentifier>,
|
|
||||||
animatingDifferences: Bool = true,
|
|
||||||
completion: (() -> Void)? = nil) {
|
|
||||||
let differenceExceptShowMoreToggled = self.snapshot().itemIdentifiers.difference(
|
|
||||||
from: snapshot.itemIdentifiers,
|
|
||||||
by: CollectionItemIdentifier.isSameExceptShowMoreToggled(lhs:rhs:))
|
|
||||||
let animated = snapshot.itemIdentifiers.count > 0 && differenceExceptShowMoreToggled.count == 0
|
|
||||||
|
|
||||||
updateQueue.async {
|
|
||||||
super.apply(snapshot, animatingDifferences: animated, completion: completion)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
"add-identity.join" = "Join";
|
"add-identity.join" = "Join";
|
||||||
"add-identity.request-invite" = "Request an invite";
|
"add-identity.request-invite" = "Request an invite";
|
||||||
"add-identity.unable-to-connect-to-instance" = "Unable to connect to instance";
|
"add-identity.unable-to-connect-to-instance" = "Unable to connect to instance";
|
||||||
|
"attachment.sensitive-content" = "Sensitive content";
|
||||||
|
"attachment.media-hidden" = "Media hidden";
|
||||||
"registration.review-terms-of-use-and-privacy-policy-%@" = "Please review %@'s Terms of Use and Privacy Policy to continue";
|
"registration.review-terms-of-use-and-privacy-policy-%@" = "Please review %@'s Terms of Use and Privacy Policy to continue";
|
||||||
"registration.username" = "Username";
|
"registration.username" = "Username";
|
||||||
"registration.email" = "Email";
|
"registration.email" = "Email";
|
||||||
|
|
|
@ -41,8 +41,4 @@ extension AccountListService: CollectionService {
|
||||||
.flatMap { contentDatabase.append(accounts: $0.result, toList: list) }
|
.flatMap { contentDatabase.append(accounts: $0.result, toList: list) }
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func toggleShowMore(id: Status.Id) -> AnyPublisher<Never, Error> {
|
|
||||||
contentDatabase.toggleShowMore(id: id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ public protocol CollectionService {
|
||||||
var title: AnyPublisher<String, Never> { get }
|
var title: AnyPublisher<String, Never> { get }
|
||||||
var navigationService: NavigationService { get }
|
var navigationService: NavigationService { get }
|
||||||
func request(maxId: String?, minId: String?) -> AnyPublisher<Never, Error>
|
func request(maxId: String?, minId: String?) -> AnyPublisher<Never, Error>
|
||||||
func toggleShowMore(id: Status.Id) -> AnyPublisher<Never, Error>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension CollectionService {
|
extension CollectionService {
|
||||||
|
|
|
@ -32,15 +32,11 @@ extension ContextService: CollectionService {
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func toggleShowMore(id: Status.Id) -> AnyPublisher<Never, Error> {
|
public func expand(ids: Set<Status.Id>) -> AnyPublisher<Never, Error> {
|
||||||
contentDatabase.toggleShowMore(id: id)
|
contentDatabase.expand(ids: ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func showMore(ids: Set<Status.Id>) -> AnyPublisher<Never, Error> {
|
public func collapse(ids: Set<Status.Id>) -> AnyPublisher<Never, Error> {
|
||||||
contentDatabase.showMore(ids: ids)
|
contentDatabase.collapse(ids: ids)
|
||||||
}
|
|
||||||
|
|
||||||
public func showLess(ids: Set<Status.Id>) -> AnyPublisher<Never, Error> {
|
|
||||||
contentDatabase.showLess(ids: ids)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,12 @@ public struct StatusService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension StatusService {
|
public extension StatusService {
|
||||||
func toggleShowMore() -> AnyPublisher<Never, Error> {
|
func toggleShowContent() -> AnyPublisher<Never, Error> {
|
||||||
contentDatabase.toggleShowMore(id: status.displayStatus.id)
|
contentDatabase.toggleShowContent(id: status.displayStatus.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func toggleShowAttachments() -> AnyPublisher<Never, Error> {
|
||||||
|
contentDatabase.toggleShowAttachments(id: status.displayStatus.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toggleFavorited() -> AnyPublisher<Never, Error> {
|
func toggleFavorited() -> AnyPublisher<Never, Error> {
|
||||||
|
|
|
@ -44,8 +44,4 @@ extension TimelineService: CollectionService {
|
||||||
.flatMap { contentDatabase.insert(statuses: $0.result, timeline: timeline) }
|
.flatMap { contentDatabase.insert(statuses: $0.result, timeline: timeline) }
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func toggleShowMore(id: Status.Id) -> AnyPublisher<Never, Error> {
|
|
||||||
contentDatabase.toggleShowMore(id: id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,8 +164,8 @@ private extension TableViewController {
|
||||||
.sink { [weak self] in self?.handle(event: $0) }
|
.sink { [weak self] in self?.handle(event: $0) }
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
viewModel.showMoreForAll.receive(on: DispatchQueue.main)
|
viewModel.expandAll.receive(on: DispatchQueue.main)
|
||||||
.sink { [weak self] in self?.set(showMoreForAllState: $0) }
|
.sink { [weak self] in self?.set(expandAllState: $0) }
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
viewModel.loading.receive(on: RunLoop.main).sink { [weak self] in
|
viewModel.loading.receive(on: RunLoop.main).sink { [weak self] in
|
||||||
|
@ -194,7 +194,7 @@ private extension TableViewController {
|
||||||
offsetFromNavigationBar = tableView.rectForRow(at: indexPath).origin.y - navigationBarMaxY
|
offsetFromNavigationBar = tableView.rectForRow(at: indexPath).origin.y - navigationBarMaxY
|
||||||
}
|
}
|
||||||
|
|
||||||
self.dataSource.apply(update.items.snapshot()) { [weak self] in
|
self.dataSource.apply(update.items.snapshot(), animatingDifferences: false) { [weak self] in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
|
||||||
if
|
if
|
||||||
|
@ -241,20 +241,20 @@ private extension TableViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func set(showMoreForAllState: ShowMoreForAllState) {
|
func set(expandAllState: ExpandAllState) {
|
||||||
switch showMoreForAllState {
|
switch expandAllState {
|
||||||
case .hidden:
|
case .hidden:
|
||||||
navigationItem.rightBarButtonItem = nil
|
navigationItem.rightBarButtonItem = nil
|
||||||
case .showMore:
|
case .expand:
|
||||||
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
||||||
title: NSLocalizedString("status.show-more", comment: ""),
|
title: NSLocalizedString("status.show-more", comment: ""),
|
||||||
image: UIImage(systemName: "eye.slash"),
|
image: UIImage(systemName: "eye"),
|
||||||
primaryAction: UIAction { [weak self] _ in self?.viewModel.toggleShowMoreForAll() })
|
primaryAction: UIAction { [weak self] _ in self?.viewModel.toggleExpandAll() })
|
||||||
case .showLess:
|
case .collapse:
|
||||||
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
||||||
title: NSLocalizedString("status.show-less", comment: ""),
|
title: NSLocalizedString("status.show-less", comment: ""),
|
||||||
image: UIImage(systemName: "eye"),
|
image: UIImage(systemName: "eye.slash"),
|
||||||
primaryAction: UIAction { [weak self] _ in self?.viewModel.toggleShowMoreForAll() })
|
primaryAction: UIAction { [weak self] _ in self?.viewModel.toggleExpandAll() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ final public class CollectionItemsViewModel: ObservableObject {
|
||||||
private var viewModelCache = [CollectionItem: (viewModel: CollectionItemViewModel, events: AnyCancellable)]()
|
private var viewModelCache = [CollectionItem: (viewModel: CollectionItemViewModel, events: AnyCancellable)]()
|
||||||
private let eventsSubject = PassthroughSubject<CollectionItemEvent, Never>()
|
private let eventsSubject = PassthroughSubject<CollectionItemEvent, Never>()
|
||||||
private let loadingSubject = PassthroughSubject<Bool, Never>()
|
private let loadingSubject = PassthroughSubject<Bool, Never>()
|
||||||
private let showMoreForAllSubject: CurrentValueSubject<ShowMoreForAllState, Never>
|
private let expandAllSubject: CurrentValueSubject<ExpandAllState, Never>
|
||||||
private var maintainScrollPosition: CollectionItemIdentifier?
|
private var maintainScrollPosition: CollectionItemIdentifier?
|
||||||
private var topVisibleIndexPath = IndexPath(item: 0, section: 0)
|
private var topVisibleIndexPath = IndexPath(item: 0, section: 0)
|
||||||
private var lastSelectedLoadMore: LoadMore?
|
private var lastSelectedLoadMore: LoadMore?
|
||||||
|
@ -24,9 +24,9 @@ final public class CollectionItemsViewModel: ObservableObject {
|
||||||
public init(collectionService: CollectionService, identification: Identification) {
|
public init(collectionService: CollectionService, identification: Identification) {
|
||||||
self.collectionService = collectionService
|
self.collectionService = collectionService
|
||||||
self.identification = identification
|
self.identification = identification
|
||||||
showMoreForAllSubject = CurrentValueSubject(
|
expandAllSubject = CurrentValueSubject(
|
||||||
collectionService is ContextService && !identification.identity.preferences.readingExpandSpoilers
|
collectionService is ContextService && !identification.identity.preferences.readingExpandSpoilers
|
||||||
? .showMore : .hidden)
|
? .expand : .hidden)
|
||||||
|
|
||||||
collectionService.sections
|
collectionService.sections
|
||||||
.handleEvents(receiveOutput: { [weak self] in self?.process(items: $0) })
|
.handleEvents(receiveOutput: { [weak self] in self?.process(items: $0) })
|
||||||
|
@ -52,8 +52,8 @@ extension CollectionItemsViewModel: CollectionViewModel {
|
||||||
|
|
||||||
public var title: AnyPublisher<String, Never> { collectionService.title }
|
public var title: AnyPublisher<String, Never> { collectionService.title }
|
||||||
|
|
||||||
public var showMoreForAll: AnyPublisher<ShowMoreForAllState, Never> {
|
public var expandAll: AnyPublisher<ExpandAllState, Never> {
|
||||||
showMoreForAllSubject.eraseToAnyPublisher()
|
expandAllSubject.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
public var alertItems: AnyPublisher<AlertItem, Never> { $alertItem.compactMap { $0 }.eraseToAnyPublisher() }
|
public var alertItems: AnyPublisher<AlertItem, Never> { $alertItem.compactMap { $0 }.eraseToAnyPublisher() }
|
||||||
|
@ -153,27 +153,27 @@ extension CollectionItemsViewModel: CollectionViewModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func toggleShowMoreForAll() {
|
public func toggleExpandAll() {
|
||||||
let statusIds = Set(items.value.reduce([], +).compactMap { item -> Status.Id? in
|
let statusIds = Set(items.value.reduce([], +).compactMap { item -> Status.Id? in
|
||||||
guard case let .status(status, _) = item else { return nil }
|
guard case let .status(status, _) = item else { return nil }
|
||||||
|
|
||||||
return status.id
|
return status.id
|
||||||
})
|
})
|
||||||
|
|
||||||
switch showMoreForAllSubject.value {
|
switch expandAllSubject.value {
|
||||||
case .hidden:
|
case .hidden:
|
||||||
break
|
break
|
||||||
case .showMore:
|
case .expand:
|
||||||
(collectionService as? ContextService)?.showMore(ids: statusIds)
|
(collectionService as? ContextService)?.expand(ids: statusIds)
|
||||||
.assignErrorsToAlertItem(to: \.alertItem, on: self)
|
.assignErrorsToAlertItem(to: \.alertItem, on: self)
|
||||||
.collect()
|
.collect()
|
||||||
.sink { [weak self] _ in self?.showMoreForAllSubject.send(.showLess) }
|
.sink { [weak self] _ in self?.expandAllSubject.send(.collapse) }
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
case .showLess:
|
case .collapse:
|
||||||
(collectionService as? ContextService)?.showLess(ids: statusIds)
|
(collectionService as? ContextService)?.collapse(ids: statusIds)
|
||||||
.assignErrorsToAlertItem(to: \.alertItem, on: self)
|
.assignErrorsToAlertItem(to: \.alertItem, on: self)
|
||||||
.collect()
|
.collect()
|
||||||
.sink { [weak self] _ in self?.showMoreForAllSubject.send(.showMore) }
|
.sink { [weak self] _ in self?.expandAllSubject.send(.expand) }
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import Foundation
|
||||||
public protocol CollectionViewModel {
|
public protocol CollectionViewModel {
|
||||||
var updates: AnyPublisher<CollectionUpdate, Never> { get }
|
var updates: AnyPublisher<CollectionUpdate, Never> { get }
|
||||||
var title: AnyPublisher<String, Never> { get }
|
var title: AnyPublisher<String, Never> { get }
|
||||||
var showMoreForAll: AnyPublisher<ShowMoreForAllState, Never> { get }
|
var expandAll: AnyPublisher<ExpandAllState, Never> { get }
|
||||||
var alertItems: AnyPublisher<AlertItem, Never> { get }
|
var alertItems: AnyPublisher<AlertItem, Never> { get }
|
||||||
var loading: AnyPublisher<Bool, Never> { get }
|
var loading: AnyPublisher<Bool, Never> { get }
|
||||||
var events: AnyPublisher<CollectionItemEvent, Never> { get }
|
var events: AnyPublisher<CollectionItemEvent, Never> { get }
|
||||||
|
@ -16,5 +16,5 @@ public protocol CollectionViewModel {
|
||||||
func select(indexPath: IndexPath)
|
func select(indexPath: IndexPath)
|
||||||
func canSelect(indexPath: IndexPath) -> Bool
|
func canSelect(indexPath: IndexPath) -> Bool
|
||||||
func viewModel(indexPath: IndexPath) -> CollectionItemViewModel
|
func viewModel(indexPath: IndexPath) -> CollectionItemViewModel
|
||||||
func toggleShowMoreForAll()
|
func toggleExpandAll()
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,17 +29,3 @@ public extension CollectionItemIdentifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension CollectionItemIdentifier {
|
|
||||||
public static func isSameExceptShowMoreToggled(lhs: Self, rhs: Self) -> Bool {
|
|
||||||
guard case let .status(lhsStatus, lhsConfiguration) = lhs.item,
|
|
||||||
case let .status(rhsStatus, rhsConfiguration) = rhs.item,
|
|
||||||
lhsStatus == rhsStatus
|
|
||||||
else { return false }
|
|
||||||
|
|
||||||
return lhsConfiguration.isContextParent == rhsConfiguration.isContextParent
|
|
||||||
&& lhsConfiguration.isPinned == rhsConfiguration.isPinned
|
|
||||||
&& lhsConfiguration.isReplyInContext == rhsConfiguration.isReplyInContext
|
|
||||||
&& lhsConfiguration.hasReplyFollowing == rhsConfiguration.hasReplyFollowing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright © 2020 Metabolist. All rights reserved.
|
// Copyright © 2020 Metabolist. All rights reserved.
|
||||||
|
|
||||||
public enum ShowMoreForAllState {
|
public enum ExpandAllState {
|
||||||
case hidden
|
case hidden
|
||||||
case showMore
|
case expand
|
||||||
case showLess
|
case collapse
|
||||||
}
|
}
|
|
@ -49,8 +49,8 @@ extension ProfileViewModel: CollectionViewModel {
|
||||||
$accountViewModel.compactMap { $0?.accountName }.eraseToAnyPublisher()
|
$accountViewModel.compactMap { $0?.accountName }.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
public var showMoreForAll: AnyPublisher<ShowMoreForAllState, Never> {
|
public var expandAll: AnyPublisher<ExpandAllState, Never> {
|
||||||
collectionViewModel.flatMap(\.showMoreForAll).eraseToAnyPublisher()
|
collectionViewModel.flatMap(\.expandAll).eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
public var alertItems: AnyPublisher<AlertItem, Never> {
|
public var alertItems: AnyPublisher<AlertItem, Never> {
|
||||||
|
@ -101,7 +101,7 @@ extension ProfileViewModel: CollectionViewModel {
|
||||||
collectionViewModel.value.viewModel(indexPath: indexPath)
|
collectionViewModel.value.viewModel(indexPath: indexPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func toggleShowMoreForAll() {
|
public func toggleExpandAll() {
|
||||||
collectionViewModel.value.toggleShowMoreForAll()
|
collectionViewModel.value.toggleExpandAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,16 +48,31 @@ public struct StatusViewModel: CollectionItemViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension StatusViewModel {
|
public extension StatusViewModel {
|
||||||
var shouldShowMore: Bool {
|
var shouldShowContent: Bool {
|
||||||
guard spoilerText != "" else { return true }
|
guard spoilerText != "" else { return true }
|
||||||
|
|
||||||
if identification.identity.preferences.readingExpandSpoilers {
|
if identification.identity.preferences.readingExpandSpoilers {
|
||||||
return !configuration.showMoreToggled
|
return !configuration.showContentToggled
|
||||||
} else {
|
} else {
|
||||||
return configuration.showMoreToggled
|
return configuration.showContentToggled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var shouldShowAttachments: Bool {
|
||||||
|
switch identification.identity.preferences.readingExpandMedia {
|
||||||
|
case .default, .unknown:
|
||||||
|
return !sensitive || configuration.showAttachmentsToggled
|
||||||
|
case .showAll:
|
||||||
|
return !configuration.showAttachmentsToggled
|
||||||
|
case .hideAll:
|
||||||
|
return configuration.showAttachmentsToggled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var shouldShowHideAttachmentsButton: Bool {
|
||||||
|
sensitive || identification.identity.preferences.readingExpandMedia == .hideAll
|
||||||
|
}
|
||||||
|
|
||||||
var accountName: String { "@" + statusService.status.displayStatus.account.acct }
|
var accountName: String { "@" + statusService.status.displayStatus.account.acct }
|
||||||
|
|
||||||
var avatarURL: URL { statusService.status.displayStatus.account.avatar }
|
var avatarURL: URL { statusService.status.displayStatus.account.avatar }
|
||||||
|
@ -107,9 +122,16 @@ public extension StatusViewModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toggleShowMore() {
|
func toggleShowContent() {
|
||||||
eventsSubject.send(
|
eventsSubject.send(
|
||||||
statusService.toggleShowMore()
|
statusService.toggleShowContent()
|
||||||
|
.map { _ in CollectionItemEvent.ignorableOutput }
|
||||||
|
.eraseToAnyPublisher())
|
||||||
|
}
|
||||||
|
|
||||||
|
func toggleShowAttachments() {
|
||||||
|
eventsSubject.send(
|
||||||
|
statusService.toggleShowAttachments()
|
||||||
.map { _ in CollectionItemEvent.ignorableOutput }
|
.map { _ in CollectionItemEvent.ignorableOutput }
|
||||||
.eraseToAnyPublisher())
|
.eraseToAnyPublisher())
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,10 @@ final class StatusAttachmentsView: UIView {
|
||||||
private let containerStackView = UIStackView()
|
private let containerStackView = UIStackView()
|
||||||
private let leftStackView = UIStackView()
|
private let leftStackView = UIStackView()
|
||||||
private let rightStackView = UIStackView()
|
private let rightStackView = UIStackView()
|
||||||
|
private let curtain = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial))
|
||||||
|
private let curtainButton = UIButton(type: .system)
|
||||||
|
private let hideButtonBackground = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial))
|
||||||
|
private let hideButton = UIButton()
|
||||||
private var aspectRatioConstraint: NSLayoutConstraint?
|
private var aspectRatioConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
var viewModel: StatusViewModel? {
|
var viewModel: StatusViewModel? {
|
||||||
|
@ -47,6 +51,15 @@ final class StatusAttachmentsView: UIView {
|
||||||
aspectRatioConstraint = widthAnchor.constraint(equalTo: heightAnchor, multiplier: newAspectRatio)
|
aspectRatioConstraint = widthAnchor.constraint(equalTo: heightAnchor, multiplier: newAspectRatio)
|
||||||
aspectRatioConstraint?.priority = .justBelowMax
|
aspectRatioConstraint?.priority = .justBelowMax
|
||||||
aspectRatioConstraint?.isActive = true
|
aspectRatioConstraint?.isActive = true
|
||||||
|
|
||||||
|
curtain.isHidden = viewModel?.shouldShowAttachments ?? false
|
||||||
|
curtainButton.setTitle(
|
||||||
|
NSLocalizedString((viewModel?.sensitive ?? false)
|
||||||
|
? "attachment.sensitive-content"
|
||||||
|
: "attachment.media-hidden",
|
||||||
|
comment: ""),
|
||||||
|
for: .normal)
|
||||||
|
hideButtonBackground.isHidden = !(viewModel?.shouldShowHideAttachmentsButton ?? false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +76,7 @@ final class StatusAttachmentsView: UIView {
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension StatusAttachmentsView {
|
private extension StatusAttachmentsView {
|
||||||
|
// swiftlint:disable:next function_body_length
|
||||||
func initialSetup() {
|
func initialSetup() {
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
layoutMargins = .zero
|
layoutMargins = .zero
|
||||||
|
@ -81,11 +95,57 @@ private extension StatusAttachmentsView {
|
||||||
containerStackView.addArrangedSubview(leftStackView)
|
containerStackView.addArrangedSubview(leftStackView)
|
||||||
containerStackView.addArrangedSubview(rightStackView)
|
containerStackView.addArrangedSubview(rightStackView)
|
||||||
|
|
||||||
|
let toggleShowAttachmentsAction = UIAction { [weak self] _ in
|
||||||
|
self?.viewModel?.toggleShowAttachments()
|
||||||
|
}
|
||||||
|
|
||||||
|
addSubview(hideButtonBackground)
|
||||||
|
hideButtonBackground.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
hideButtonBackground.clipsToBounds = true
|
||||||
|
hideButtonBackground.layer.cornerRadius = .defaultCornerRadius
|
||||||
|
|
||||||
|
hideButton.addAction(toggleShowAttachmentsAction, for: .touchUpInside)
|
||||||
|
hideButtonBackground.contentView.addSubview(hideButton)
|
||||||
|
hideButton.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
hideButton.setImage(
|
||||||
|
UIImage(systemName: "eye.slash", withConfiguration: UIImage.SymbolConfiguration(scale: .medium)),
|
||||||
|
for: .normal)
|
||||||
|
addSubview(curtain)
|
||||||
|
curtain.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
curtain.contentView.addSubview(curtainButton)
|
||||||
|
|
||||||
|
curtainButton.addAction(toggleShowAttachmentsAction, for: .touchUpInside)
|
||||||
|
curtainButton.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
curtainButton.titleLabel?.font = .preferredFont(forTextStyle: .headline)
|
||||||
|
curtainButton.titleLabel?.adjustsFontForContentSizeCategory = true
|
||||||
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
containerStackView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
|
containerStackView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||||
containerStackView.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
|
containerStackView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||||
containerStackView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor),
|
containerStackView.topAnchor.constraint(equalTo: topAnchor),
|
||||||
containerStackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
|
containerStackView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||||
|
hideButtonBackground.topAnchor.constraint(equalTo: topAnchor, constant: .defaultSpacing),
|
||||||
|
hideButtonBackground.leadingAnchor.constraint(equalTo: leadingAnchor, constant: .defaultSpacing),
|
||||||
|
hideButton.topAnchor.constraint(
|
||||||
|
equalTo: hideButtonBackground.contentView.topAnchor,
|
||||||
|
constant: .compactSpacing),
|
||||||
|
hideButton.leadingAnchor.constraint(
|
||||||
|
equalTo: hideButtonBackground.contentView.leadingAnchor,
|
||||||
|
constant: .compactSpacing),
|
||||||
|
hideButtonBackground.contentView.trailingAnchor.constraint(
|
||||||
|
equalTo: hideButton.trailingAnchor,
|
||||||
|
constant: .compactSpacing),
|
||||||
|
hideButtonBackground.contentView.bottomAnchor.constraint(
|
||||||
|
equalTo: hideButton.bottomAnchor,
|
||||||
|
constant: .compactSpacing),
|
||||||
|
curtain.topAnchor.constraint(equalTo: topAnchor),
|
||||||
|
curtain.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||||
|
curtain.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||||
|
curtain.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||||
|
curtainButton.topAnchor.constraint(equalTo: curtain.contentView.topAnchor),
|
||||||
|
curtainButton.leadingAnchor.constraint(equalTo: curtain.contentView.leadingAnchor),
|
||||||
|
curtainButton.trailingAnchor.constraint(equalTo: curtain.contentView.trailingAnchor),
|
||||||
|
curtainButton.bottomAnchor.constraint(equalTo: curtain.contentView.bottomAnchor)
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ final class StatusView: UIView {
|
||||||
let accountLabel = UILabel()
|
let accountLabel = UILabel()
|
||||||
let timeLabel = UILabel()
|
let timeLabel = UILabel()
|
||||||
let spoilerTextLabel = UILabel()
|
let spoilerTextLabel = UILabel()
|
||||||
let toggleShowMoreButton = UIButton(type: .system)
|
let toggleShowContentButton = UIButton(type: .system)
|
||||||
let contentTextView = TouchFallthroughTextView()
|
let contentTextView = TouchFallthroughTextView()
|
||||||
let attachmentsView = StatusAttachmentsView()
|
let attachmentsView = StatusAttachmentsView()
|
||||||
let cardView = CardView()
|
let cardView = CardView()
|
||||||
|
@ -148,12 +148,12 @@ private extension StatusView {
|
||||||
spoilerTextLabel.adjustsFontForContentSizeCategory = true
|
spoilerTextLabel.adjustsFontForContentSizeCategory = true
|
||||||
mainStackView.addArrangedSubview(spoilerTextLabel)
|
mainStackView.addArrangedSubview(spoilerTextLabel)
|
||||||
|
|
||||||
toggleShowMoreButton.titleLabel?.font = .preferredFont(forTextStyle: .headline)
|
toggleShowContentButton.titleLabel?.font = .preferredFont(forTextStyle: .headline)
|
||||||
toggleShowMoreButton.titleLabel?.adjustsFontForContentSizeCategory = true
|
toggleShowContentButton.titleLabel?.adjustsFontForContentSizeCategory = true
|
||||||
toggleShowMoreButton.addAction(
|
toggleShowContentButton.addAction(
|
||||||
UIAction { [weak self] _ in self?.statusConfiguration.viewModel.toggleShowMore() },
|
UIAction { [weak self] _ in self?.statusConfiguration.viewModel.toggleShowContent() },
|
||||||
for: .touchUpInside)
|
for: .touchUpInside)
|
||||||
mainStackView.addArrangedSubview(toggleShowMoreButton)
|
mainStackView.addArrangedSubview(toggleShowContentButton)
|
||||||
|
|
||||||
contentTextView.adjustsFontForContentSizeCategory = true
|
contentTextView.adjustsFontForContentSizeCategory = true
|
||||||
contentTextView.isScrollEnabled = false
|
contentTextView.isScrollEnabled = false
|
||||||
|
@ -365,14 +365,14 @@ private extension StatusView {
|
||||||
spoilerTextLabel.font = contentFont
|
spoilerTextLabel.font = contentFont
|
||||||
spoilerTextLabel.attributedText = mutableSpoilerText
|
spoilerTextLabel.attributedText = mutableSpoilerText
|
||||||
spoilerTextLabel.isHidden = spoilerTextLabel.text == ""
|
spoilerTextLabel.isHidden = spoilerTextLabel.text == ""
|
||||||
toggleShowMoreButton.setTitle(
|
toggleShowContentButton.setTitle(
|
||||||
viewModel.shouldShowMore
|
viewModel.shouldShowContent
|
||||||
? NSLocalizedString("status.show-less", comment: "")
|
? NSLocalizedString("status.show-less", comment: "")
|
||||||
: NSLocalizedString("status.show-more", comment: ""),
|
: NSLocalizedString("status.show-more", comment: ""),
|
||||||
for: .normal)
|
for: .normal)
|
||||||
toggleShowMoreButton.isHidden = viewModel.spoilerText == ""
|
toggleShowContentButton.isHidden = viewModel.spoilerText == ""
|
||||||
|
|
||||||
contentTextView.isHidden = !viewModel.shouldShowMore
|
contentTextView.isHidden = !viewModel.shouldShowContent
|
||||||
|
|
||||||
nameAccountTimeStackView.axis = isContextParent ? .vertical : .horizontal
|
nameAccountTimeStackView.axis = isContextParent ? .vertical : .horizontal
|
||||||
nameAccountTimeStackView.alignment = isContextParent ? .leading : .fill
|
nameAccountTimeStackView.alignment = isContextParent ? .leading : .fill
|
||||||
|
|
Loading…
Reference in a new issue