Something went wrong. Try again.
A slopfork of Sam Henri Gold's Twitter client, reskinned like Tweetie 2 / Twitter for iPhone circa 2012. Personal use.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172import Foundationimport Routing
/// A recognized element of post text.package enum PostEntity: Hashable, Codable, Sendable { case cashtag(String) case hashtag(String) /// The screen name, without its `@`. case mention(String) case url(URL)
/// Where tapping it goes: the URL itself, or an in-app `twitter-client://` route that ``Route/init(url:)`` reads. package var destination: URL? { var components = URLComponents() components.scheme = Route.scheme switch self { case .url(let url): return url case .mention(let screenName): components.host = "user" components.path = "/\(screenName)" case .hashtag(let tag), .cashtag(let tag): components.host = "search" components.queryItems = [URLQueryItem(name: "q", value: tag)] } return components.url }}
/// Inline styling a run of post text carries.package struct PostTextEmphasis: OptionSet, Hashable, Sendable { package let rawValue: UInt8
package init(rawValue: UInt8) { self.rawValue = rawValue }
package static let bold = PostTextEmphasis(rawValue: 1 << 0) package static let italic = PostTextEmphasis(rawValue: 1 << 1)
var presentationIntent: InlinePresentationIntent? { var intent: InlinePresentationIntent = [] if contains(.bold) { intent.insert(.stronglyEmphasized) } if contains(.italic) { intent.insert(.emphasized) } return intent.isEmpty ? nil : intent }}
/// Tags the runs of a typeset string with the entity they render, so callers (and tests) can find mentions, tags and/// links without re-parsing. SwiftUI's `Text` ignores it.package enum PostEntityAttribute: CodableAttributedStringKey { package typealias Value = PostEntity package static let name = "gold.samhenri.twitter.postEntity"}
extension AttributeScopes { package struct PostTextAttributes: AttributeScope { package let postEntity: PostEntityAttribute package let foundation: FoundationAttributes }
package var postText: PostTextAttributes.Type { PostTextAttributes.self }}
extension AttributeDynamicLookup { package subscript<T: AttributedStringKey>( dynamicMember keyPath: KeyPath<AttributeScopes.PostTextAttributes, T> ) -> T { self[T.self] }}