diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index d55d789aa7..5278ba1106 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -134,6 +134,8 @@ D6412B0B24B0D4C600F5412E /* ProfileHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D6412B0A24B0D4C600F5412E /* ProfileHeaderView.xib */; }; D6412B0D24B0D4CF00F5412E /* ProfileHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6412B0C24B0D4CF00F5412E /* ProfileHeaderView.swift */; }; D641C77F213DC78A004B4513 /* InlineTextAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D641C77E213DC78A004B4513 /* InlineTextAttachment.swift */; }; + D6420AEE26BED18B00ED8175 /* PublicTimelineDescriptionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6420AEC26BED18B00ED8175 /* PublicTimelineDescriptionTableViewCell.swift */; }; + D6420AEF26BED18B00ED8175 /* PublicTimelineDescriptionTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D6420AED26BED18B00ED8175 /* PublicTimelineDescriptionTableViewCell.xib */; }; D6434EB3215B1856001A919A /* XCBRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6434EB2215B1856001A919A /* XCBRequest.swift */; }; D646C956213B365700269FB5 /* LargeImageExpandAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D646C955213B365700269FB5 /* LargeImageExpandAnimationController.swift */; }; D646C958213B367000269FB5 /* LargeImageShrinkAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D646C957213B367000269FB5 /* LargeImageShrinkAnimationController.swift */; }; @@ -535,6 +537,8 @@ D6412B0A24B0D4C600F5412E /* ProfileHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ProfileHeaderView.xib; sourceTree = ""; }; D6412B0C24B0D4CF00F5412E /* ProfileHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileHeaderView.swift; sourceTree = ""; }; D641C77E213DC78A004B4513 /* InlineTextAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InlineTextAttachment.swift; sourceTree = ""; }; + D6420AEC26BED18B00ED8175 /* PublicTimelineDescriptionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicTimelineDescriptionTableViewCell.swift; sourceTree = ""; }; + D6420AED26BED18B00ED8175 /* PublicTimelineDescriptionTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PublicTimelineDescriptionTableViewCell.xib; sourceTree = ""; }; D6434EB2215B1856001A919A /* XCBRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCBRequest.swift; sourceTree = ""; }; D646C955213B365700269FB5 /* LargeImageExpandAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageExpandAnimationController.swift; sourceTree = ""; }; D646C957213B367000269FB5 /* LargeImageShrinkAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageShrinkAnimationController.swift; sourceTree = ""; }; @@ -1240,6 +1244,15 @@ path = Notifications; sourceTree = ""; }; + D6420AEB26BED17500ED8175 /* Timeline Description Cell */ = { + isa = PBXGroup; + children = ( + D6420AEC26BED18B00ED8175 /* PublicTimelineDescriptionTableViewCell.swift */, + D6420AED26BED18B00ED8175 /* PublicTimelineDescriptionTableViewCell.xib */, + ); + path = "Timeline Description Cell"; + sourceTree = ""; + }; D646C954213B364600269FB5 /* Transitions */ = { isa = PBXGroup; children = ( @@ -1470,6 +1483,7 @@ D611C2CC232DC5FC00C86A49 /* Hashtag Cell */, D61AC1DA232EA43100C54D2D /* Instance Cell */, D6DEA0DB268400AF00FE896A /* Confirm Load More Cell */, + D6420AEB26BED17500ED8175 /* Timeline Description Cell */, ); path = Views; sourceTree = ""; @@ -1886,6 +1900,7 @@ D6412B0B24B0D4C600F5412E /* ProfileHeaderView.xib in Resources */, D6C82B5725C5F3F20017F1E6 /* ExpandThreadTableViewCell.xib in Resources */, D6D4DDDA212518A200E1C4BB /* LaunchScreen.storyboard in Resources */, + D6420AEF26BED18B00ED8175 /* PublicTimelineDescriptionTableViewCell.xib in Resources */, D6E57FA325C26FAB00341037 /* Localizable.stringsdict in Resources */, D6B053AC23BD2F1400A066FA /* AssetCollectionViewCell.xib in Resources */, D6D4DDD7212518A200E1C4BB /* Assets.xcassets in Resources */, @@ -2147,6 +2162,7 @@ D6538945214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift in Sources */, D6F0B17524A3A1AA001E48C3 /* MainSidebarViewController.swift in Sources */, D622757424EDF1CD00B82A16 /* ComposeAttachmentsList.swift in Sources */, + D6420AEE26BED18B00ED8175 /* PublicTimelineDescriptionTableViewCell.swift in Sources */, D6E0DC8E216EDF1E00369478 /* Previewing.swift in Sources */, D6BED174212667E900F02DA0 /* TimelineStatusTableViewCell.swift in Sources */, D69693F42585941A00F4E116 /* UIWindowSceneDelegate+Close.swift in Sources */, diff --git a/Tusker/Preferences/Preferences.swift b/Tusker/Preferences/Preferences.swift index 2be9db5d28..233d559582 100644 --- a/Tusker/Preferences/Preferences.swift +++ b/Tusker/Preferences/Preferences.swift @@ -67,6 +67,9 @@ class Preferences: Codable, ObservableObject { self.silentActions = try container.decode([String: Permission].self, forKey: .silentActions) self.statusContentType = try container.decode(StatusContentType.self, forKey: .statusContentType) + + self.hasShownLocalTimelineDescription = try container.decodeIfPresent(Bool.self, forKey: .hasShownLocalTimelineDescription) ?? false + self.hasShownFederatedTimelineDescription = try container.decodeIfPresent(Bool.self, forKey: .hasShownFederatedTimelineDescription) ?? false } func encode(to encoder: Encoder) throws { @@ -102,6 +105,9 @@ class Preferences: Codable, ObservableObject { try container.encode(silentActions, forKey: .silentActions) try container.encode(statusContentType, forKey: .statusContentType) + + try container.encode(hasShownLocalTimelineDescription, forKey: .hasShownLocalTimelineDescription) + try container.encode(hasShownFederatedTimelineDescription, forKey: .hasShownFederatedTimelineDescription) } // MARK: Appearance @@ -140,7 +146,11 @@ class Preferences: Codable, ObservableObject { // MARK: Advanced @Published var silentActions: [String: Permission] = [:] @Published var statusContentType: StatusContentType = .plain - + + // MARK: + @Published var hasShownLocalTimelineDescription = false + @Published var hasShownFederatedTimelineDescription = false + private enum CodingKeys: String, CodingKey { case theme case avatarStyle @@ -172,6 +182,9 @@ class Preferences: Codable, ObservableObject { case silentActions case statusContentType + + case hasShownLocalTimelineDescription + case hasShownFederatedTimelineDescription } } diff --git a/Tusker/Screens/Timeline/TimelineTableViewController.swift b/Tusker/Screens/Timeline/TimelineTableViewController.swift index d16df5bd64..96af8f9e6d 100644 --- a/Tusker/Screens/Timeline/TimelineTableViewController.swift +++ b/Tusker/Screens/Timeline/TimelineTableViewController.swift @@ -20,6 +20,7 @@ class TimelineTableViewController: DiffableTimelineLikeTableViewController Bool { switch (lhs, rhs) { @@ -213,6 +280,8 @@ extension TimelineTableViewController { return a == b case (.confirmLoadMore, .confirmLoadMore): return true + case let (.publicTimelineDescription(local: a), .publicTimelineDescription(local: b)): + return a == b default: return false } @@ -225,6 +294,9 @@ extension TimelineTableViewController { hasher.combine(id) case .confirmLoadMore: hasher.combine(1) + case let .publicTimelineDescription(local: local): + hasher.combine(2) + hasher.combine(local) } } } diff --git a/Tusker/Views/Timeline Description Cell/PublicTimelineDescriptionTableViewCell.swift b/Tusker/Views/Timeline Description Cell/PublicTimelineDescriptionTableViewCell.swift new file mode 100644 index 0000000000..6cf2955d43 --- /dev/null +++ b/Tusker/Views/Timeline Description Cell/PublicTimelineDescriptionTableViewCell.swift @@ -0,0 +1,57 @@ +// +// PublicTimelineDescriptionTableViewCell.swift +// PublicTimelineDescriptionTableViewCell +// +// Created by Shadowfacts on 8/7/21. +// Copyright © 2021 Shadowfacts. All rights reserved. +// + +import UIKit + +class PublicTimelineDescriptionTableViewCell: UITableViewCell { + + weak var mastodonController: MastodonController! + + var local = false { + didSet { + updateLabel() + } + } + var didDismiss: (() -> Void)? + + @IBOutlet private weak var descriptionLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + + if #available(iOS 15.0, *) { + contentView.backgroundColor = .tintColor + } else { + contentView.backgroundColor = .systemBlue + } + } + + private func updateLabel() { + let str = NSMutableAttributedString() + let instanceStr = NSAttributedString(string: mastodonController.instanceURL.host!, attributes: [ + .font: UIFont(descriptor: .preferredFontDescriptor(withTextStyle: .body).withSymbolicTraits(.traitBold)!, size: 0) + ]) + if local { + str.append(NSAttributedString(string: "The local timeline shows public posts from only ")) + str.append(instanceStr) + str.append(NSAttributedString(string: ".")) + } else { + str.append(NSAttributedString(string: "The federated timeline shows public posts from all users that ")) + str.append(instanceStr) + str.append(NSAttributedString(string: " knows about.")) + } + descriptionLabel.attributedText = str + } + +} + +extension PublicTimelineDescriptionTableViewCell: SelectableTableViewCell { + func didSelectCell() { + didDismiss?() + } +} diff --git a/Tusker/Views/Timeline Description Cell/PublicTimelineDescriptionTableViewCell.xib b/Tusker/Views/Timeline Description Cell/PublicTimelineDescriptionTableViewCell.xib new file mode 100644 index 0000000000..14311340dd --- /dev/null +++ b/Tusker/Views/Timeline Description Cell/PublicTimelineDescriptionTableViewCell.xib @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +