Compare commits
12 Commits
5ee140cdab
...
1f37a5e7eb
Author | SHA1 | Date |
---|---|---|
Shadowfacts | 1f37a5e7eb | |
Shadowfacts | 77c9fac3ce | |
Shadowfacts | a13d5d5a82 | |
Shadowfacts | 23e4541eb7 | |
Shadowfacts | d4b9f71fd3 | |
Shadowfacts | a9edeaf5b9 | |
Shadowfacts | 1f6074e539 | |
Shadowfacts | df7b62e14b | |
Shadowfacts | cacc8a51cc | |
Shadowfacts | 89ca0629b3 | |
Shadowfacts | 360db07ef2 | |
Shadowfacts | f55a870964 |
|
@ -1,4 +1,5 @@
|
|||
Dist.xcconfig
|
||||
Tusker.xcconfig
|
||||
.DS_Store
|
||||
MyPlayground.playground/
|
||||
|
||||
|
|
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -1,5 +1,16 @@
|
|||
# Changelog
|
||||
|
||||
## 2022.1 (53)
|
||||
Features/Improvements:
|
||||
- Apply filters to Trending Posts
|
||||
- Don't reload List timelines if Edit screen is closed without changes
|
||||
|
||||
Bugfixes:
|
||||
- Fix URLs getting pasted as broken attachments in the Compose screen
|
||||
- Fix monspace fonts not adjusting to Dynamic Type setting
|
||||
- Fix crash when activating account from Preferences when My Profile is opened in a separate window
|
||||
- Fix Preferences showing wrong account as current when multiple windows with different accounts are open
|
||||
|
||||
## 2022.1 (52)
|
||||
Features/Improvements:
|
||||
- Save and restore position for all timelines and all accounts
|
||||
|
|
12
README.md
12
README.md
|
@ -4,12 +4,12 @@ Tusker is a WIP iOS app for Mastodon and Pleroma.
|
|||
|
||||
## Installing for Development
|
||||
|
||||
Xcode 11 is required, macOS Mojave or later should work (only macOS Catalina is regularly tested).
|
||||
Requirements:
|
||||
- Xcode 14
|
||||
|
||||
1. Clone the project: `git clone https://git.shadowfacts.net/shadowfacts/Tusker.git`
|
||||
2. Change directory into the project: `cd Tusker`
|
||||
3. Clone the submodules: `git submodule init && git submodule update`
|
||||
4. Open `Tusker.xcworkspace` in Xcode.
|
||||
5. Change the code signing identity to your own.
|
||||
6. Change the bundle identifier to something unique.
|
||||
7. Select a target in the Tusker scheme and build & run.
|
||||
3. Copy the sample xcconfig: `cp Tusker.xcconfig.example Tusker.xcconfig`
|
||||
4. Edit `Tusker.xcconfig` and change the development team ID and the bundle ID prefix to your own.
|
||||
5. Open `Tusker.xcodeproj` in Xcode
|
||||
6. Select a target in the Tusker scheme and build & run.
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
DEVELOPMENT_TEAM = YOUR_TEAM_ID
|
||||
BUNDLE_ID_PREFIX = com.example
|
|
@ -91,9 +91,6 @@
|
|||
D626493D23C1000300612E6E /* AlbumTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D626493B23C1000300612E6E /* AlbumTableViewCell.xib */; };
|
||||
D626493F23C101C500612E6E /* AlbumAssetCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D626493E23C101C500612E6E /* AlbumAssetCollectionViewController.swift */; };
|
||||
D627943223A5466600D38C68 /* SelectableTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627943123A5466600D38C68 /* SelectableTableViewCell.swift */; };
|
||||
D627943523A5525100D38C68 /* StatusActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627943423A5525100D38C68 /* StatusActivity.swift */; };
|
||||
D627943723A552C200D38C68 /* BookmarkStatusActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627943623A552C200D38C68 /* BookmarkStatusActivity.swift */; };
|
||||
D627943923A553B600D38C68 /* UnbookmarkStatusActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627943823A553B600D38C68 /* UnbookmarkStatusActivity.swift */; };
|
||||
D627943B23A55BA600D38C68 /* NavigableTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627943A23A55BA600D38C68 /* NavigableTableViewCell.swift */; };
|
||||
D627944723A6AC9300D38C68 /* BasicTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D627944623A6AC9300D38C68 /* BasicTableViewCell.xib */; };
|
||||
D627944A23A6AD6100D38C68 /* BookmarksTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627944923A6AD6100D38C68 /* BookmarksTableViewController.swift */; };
|
||||
|
@ -127,8 +124,6 @@
|
|||
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 */; };
|
||||
D646C956213B365700269FB5 /* LargeImageExpandAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D646C955213B365700269FB5 /* LargeImageExpandAnimationController.swift */; };
|
||||
D646C958213B367000269FB5 /* LargeImageShrinkAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D646C957213B367000269FB5 /* LargeImageShrinkAnimationController.swift */; };
|
||||
D646C95A213B5D0500269FB5 /* LargeImageInteractionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D646C959213B5D0500269FB5 /* LargeImageInteractionController.swift */; };
|
||||
|
@ -137,11 +132,8 @@
|
|||
D64AAE9526C88C5000FC57FB /* ToastableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64AAE9426C88C5000FC57FB /* ToastableViewController.swift */; };
|
||||
D64AAE9726C88DC400FC57FB /* ToastConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64AAE9626C88DC400FC57FB /* ToastConfiguration.swift */; };
|
||||
D64BC18623C1253A000D0238 /* AssetPreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64BC18523C1253A000D0238 /* AssetPreviewViewController.swift */; };
|
||||
D64BC18823C1640A000D0238 /* PinStatusActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64BC18723C1640A000D0238 /* PinStatusActivity.swift */; };
|
||||
D64BC18A23C16487000D0238 /* UnpinStatusActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64BC18923C16487000D0238 /* UnpinStatusActivity.swift */; };
|
||||
D64BC18F23C18B9D000D0238 /* FollowRequestNotificationTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64BC18D23C18B9D000D0238 /* FollowRequestNotificationTableViewCell.swift */; };
|
||||
D64BC19023C18B9D000D0238 /* FollowRequestNotificationTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D64BC18E23C18B9D000D0238 /* FollowRequestNotificationTableViewCell.xib */; };
|
||||
D64BC19223C271D9000D0238 /* MastodonActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64BC19123C271D9000D0238 /* MastodonActivity.swift */; };
|
||||
D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AAC2128D88B005A6F37 /* LocalData.swift */; };
|
||||
D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */; };
|
||||
D64D8CA92463B494006B0BAA /* MultiThreadDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D8CA82463B494006B0BAA /* MultiThreadDictionary.swift */; };
|
||||
|
@ -187,8 +179,6 @@
|
|||
D68015402401A6BA00D6103B /* ComposingPrefsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D680153F2401A6BA00D6103B /* ComposingPrefsView.swift */; };
|
||||
D68015422401A74600D6103B /* MediaPrefsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68015412401A74600D6103B /* MediaPrefsView.swift */; };
|
||||
D681A29A249AD62D0085E54E /* LargeImageContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D681A299249AD62D0085E54E /* LargeImageContentView.swift */; };
|
||||
D681E4D3246E2AFF0053414F /* MuteConversationActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D681E4D2246E2AFF0053414F /* MuteConversationActivity.swift */; };
|
||||
D681E4D5246E2BC30053414F /* UnmuteConversationActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D681E4D4246E2BC30053414F /* UnmuteConversationActivity.swift */; };
|
||||
D681E4D7246E32290053414F /* StatusActivityItemSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D681E4D6246E32290053414F /* StatusActivityItemSource.swift */; };
|
||||
D681E4D9246E346E0053414F /* AccountActivityItemSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D681E4D8246E346E0053414F /* AccountActivityItemSource.swift */; };
|
||||
D68232F72464F4FD00325FB8 /* ComposeDrawingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68232F62464F4FD00325FB8 /* ComposeDrawingViewController.swift */; };
|
||||
|
@ -245,11 +235,7 @@
|
|||
D6ADB6EE28EA74E8009924AB /* UIView+Configure.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6ADB6ED28EA74E8009924AB /* UIView+Configure.swift */; };
|
||||
D6ADB6F028ED1F25009924AB /* CachedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6ADB6EF28ED1F25009924AB /* CachedImageView.swift */; };
|
||||
D6AEBB3E2321638100E5038B /* UIActivity+Types.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6AEBB3D2321638100E5038B /* UIActivity+Types.swift */; };
|
||||
D6AEBB412321642700E5038B /* SendMesasgeActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6AEBB402321642700E5038B /* SendMesasgeActivity.swift */; };
|
||||
D6AEBB432321685E00E5038B /* OpenInSafariActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6AEBB422321685E00E5038B /* OpenInSafariActivity.swift */; };
|
||||
D6AEBB4523216AF800E5038B /* FollowAccountActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6AEBB4423216AF800E5038B /* FollowAccountActivity.swift */; };
|
||||
D6AEBB4823216B1D00E5038B /* AccountActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6AEBB4723216B1D00E5038B /* AccountActivity.swift */; };
|
||||
D6AEBB4A23216F0400E5038B /* UnfollowAccountActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6AEBB4923216F0400E5038B /* UnfollowAccountActivity.swift */; };
|
||||
D6B053A223BD2C0600A066FA /* AssetPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B053A123BD2C0600A066FA /* AssetPickerViewController.swift */; };
|
||||
D6B053A423BD2C8100A066FA /* AssetCollectionsListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B053A323BD2C8100A066FA /* AssetCollectionsListViewController.swift */; };
|
||||
D6B053A623BD2D0C00A066FA /* AssetCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B053A523BD2D0C00A066FA /* AssetCollectionViewController.swift */; };
|
||||
|
@ -477,9 +463,6 @@
|
|||
D626493B23C1000300612E6E /* AlbumTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AlbumTableViewCell.xib; sourceTree = "<group>"; };
|
||||
D626493E23C101C500612E6E /* AlbumAssetCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumAssetCollectionViewController.swift; sourceTree = "<group>"; };
|
||||
D627943123A5466600D38C68 /* SelectableTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectableTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D627943423A5525100D38C68 /* StatusActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusActivity.swift; sourceTree = "<group>"; };
|
||||
D627943623A552C200D38C68 /* BookmarkStatusActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkStatusActivity.swift; sourceTree = "<group>"; };
|
||||
D627943823A553B600D38C68 /* UnbookmarkStatusActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnbookmarkStatusActivity.swift; sourceTree = "<group>"; };
|
||||
D627943A23A55BA600D38C68 /* NavigableTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigableTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D627944623A6AC9300D38C68 /* BasicTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = BasicTableViewCell.xib; sourceTree = "<group>"; };
|
||||
D627944923A6AD6100D38C68 /* BookmarksTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksTableViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -513,8 +496,6 @@
|
|||
D6412B0A24B0D4C600F5412E /* ProfileHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ProfileHeaderView.xib; sourceTree = "<group>"; };
|
||||
D6412B0C24B0D4CF00F5412E /* ProfileHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileHeaderView.swift; sourceTree = "<group>"; };
|
||||
D641C77E213DC78A004B4513 /* InlineTextAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InlineTextAttachment.swift; sourceTree = "<group>"; };
|
||||
D6420AEC26BED18B00ED8175 /* PublicTimelineDescriptionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicTimelineDescriptionTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D6420AED26BED18B00ED8175 /* PublicTimelineDescriptionTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PublicTimelineDescriptionTableViewCell.xib; sourceTree = "<group>"; };
|
||||
D646C955213B365700269FB5 /* LargeImageExpandAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageExpandAnimationController.swift; sourceTree = "<group>"; };
|
||||
D646C957213B367000269FB5 /* LargeImageShrinkAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageShrinkAnimationController.swift; sourceTree = "<group>"; };
|
||||
D646C959213B5D0500269FB5 /* LargeImageInteractionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageInteractionController.swift; sourceTree = "<group>"; };
|
||||
|
@ -523,11 +504,8 @@
|
|||
D64AAE9426C88C5000FC57FB /* ToastableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastableViewController.swift; sourceTree = "<group>"; };
|
||||
D64AAE9626C88DC400FC57FB /* ToastConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastConfiguration.swift; sourceTree = "<group>"; };
|
||||
D64BC18523C1253A000D0238 /* AssetPreviewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetPreviewViewController.swift; sourceTree = "<group>"; };
|
||||
D64BC18723C1640A000D0238 /* PinStatusActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinStatusActivity.swift; sourceTree = "<group>"; };
|
||||
D64BC18923C16487000D0238 /* UnpinStatusActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnpinStatusActivity.swift; sourceTree = "<group>"; };
|
||||
D64BC18D23C18B9D000D0238 /* FollowRequestNotificationTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowRequestNotificationTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D64BC18E23C18B9D000D0238 /* FollowRequestNotificationTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FollowRequestNotificationTableViewCell.xib; sourceTree = "<group>"; };
|
||||
D64BC19123C271D9000D0238 /* MastodonActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonActivity.swift; sourceTree = "<group>"; };
|
||||
D64D0AAC2128D88B005A6F37 /* LocalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalData.swift; sourceTree = "<group>"; };
|
||||
D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewController.swift; sourceTree = "<group>"; };
|
||||
D64D8CA82463B494006B0BAA /* MultiThreadDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiThreadDictionary.swift; sourceTree = "<group>"; };
|
||||
|
@ -575,8 +553,6 @@
|
|||
D680153F2401A6BA00D6103B /* ComposingPrefsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposingPrefsView.swift; sourceTree = "<group>"; };
|
||||
D68015412401A74600D6103B /* MediaPrefsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPrefsView.swift; sourceTree = "<group>"; };
|
||||
D681A299249AD62D0085E54E /* LargeImageContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageContentView.swift; sourceTree = "<group>"; };
|
||||
D681E4D2246E2AFF0053414F /* MuteConversationActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MuteConversationActivity.swift; sourceTree = "<group>"; };
|
||||
D681E4D4246E2BC30053414F /* UnmuteConversationActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnmuteConversationActivity.swift; sourceTree = "<group>"; };
|
||||
D681E4D6246E32290053414F /* StatusActivityItemSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusActivityItemSource.swift; sourceTree = "<group>"; };
|
||||
D681E4D8246E346E0053414F /* AccountActivityItemSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountActivityItemSource.swift; sourceTree = "<group>"; };
|
||||
D68232F62464F4FD00325FB8 /* ComposeDrawingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeDrawingViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -633,11 +609,7 @@
|
|||
D6ADB6ED28EA74E8009924AB /* UIView+Configure.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Configure.swift"; sourceTree = "<group>"; };
|
||||
D6ADB6EF28ED1F25009924AB /* CachedImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CachedImageView.swift; sourceTree = "<group>"; };
|
||||
D6AEBB3D2321638100E5038B /* UIActivity+Types.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIActivity+Types.swift"; sourceTree = "<group>"; };
|
||||
D6AEBB402321642700E5038B /* SendMesasgeActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendMesasgeActivity.swift; sourceTree = "<group>"; };
|
||||
D6AEBB422321685E00E5038B /* OpenInSafariActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenInSafariActivity.swift; sourceTree = "<group>"; };
|
||||
D6AEBB4423216AF800E5038B /* FollowAccountActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowAccountActivity.swift; sourceTree = "<group>"; };
|
||||
D6AEBB4723216B1D00E5038B /* AccountActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountActivity.swift; sourceTree = "<group>"; };
|
||||
D6AEBB4923216F0400E5038B /* UnfollowAccountActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnfollowAccountActivity.swift; sourceTree = "<group>"; };
|
||||
D6B053A123BD2C0600A066FA /* AssetPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetPickerViewController.swift; sourceTree = "<group>"; };
|
||||
D6B053A323BD2C8100A066FA /* AssetCollectionsListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetCollectionsListViewController.swift; sourceTree = "<group>"; };
|
||||
D6B053A523BD2D0C00A066FA /* AssetCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetCollectionViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -700,6 +672,7 @@
|
|||
D6D4DDF1212518A200E1C4BB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
D6D7069F29466649000827ED /* ScrollingSegmentedControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollingSegmentedControl.swift; sourceTree = "<group>"; };
|
||||
D6D706A62948D4D0000827ED /* TimlineState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimlineState.swift; sourceTree = "<group>"; };
|
||||
D6D706A829498C82000827ED /* Tusker.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Tusker.xcconfig; sourceTree = "<group>"; };
|
||||
D6DD2A3E273C1F4900386A6C /* ComposeAttachmentImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeAttachmentImage.swift; sourceTree = "<group>"; };
|
||||
D6DD2A44273D6C5700386A6C /* GIFImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GIFImageView.swift; sourceTree = "<group>"; };
|
||||
D6DD353C22F28CD000A9563A /* ContentWarningCopyMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentWarningCopyMode.swift; sourceTree = "<group>"; };
|
||||
|
@ -861,20 +834,6 @@
|
|||
path = "Asset Picker";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D627943323A5523800D38C68 /* Status Activities */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D627943423A5525100D38C68 /* StatusActivity.swift */,
|
||||
D627943623A552C200D38C68 /* BookmarkStatusActivity.swift */,
|
||||
D627943823A553B600D38C68 /* UnbookmarkStatusActivity.swift */,
|
||||
D64BC18723C1640A000D0238 /* PinStatusActivity.swift */,
|
||||
D64BC18923C16487000D0238 /* UnpinStatusActivity.swift */,
|
||||
D681E4D2246E2AFF0053414F /* MuteConversationActivity.swift */,
|
||||
D681E4D4246E2BC30053414F /* UnmuteConversationActivity.swift */,
|
||||
);
|
||||
path = "Status Activities";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D627943C23A5635D00D38C68 /* Explore */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1150,15 +1109,6 @@
|
|||
path = Notifications;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D6420AEB26BED17500ED8175 /* Timeline Description Cell */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D6420AEC26BED18B00ED8175 /* PublicTimelineDescriptionTableViewCell.swift */,
|
||||
D6420AED26BED18B00ED8175 /* PublicTimelineDescriptionTableViewCell.xib */,
|
||||
);
|
||||
path = "Timeline Description Cell";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D646C954213B364600269FB5 /* Transitions */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1308,24 +1258,10 @@
|
|||
D681E4D8246E346E0053414F /* AccountActivityItemSource.swift */,
|
||||
D6AEBB3D2321638100E5038B /* UIActivity+Types.swift */,
|
||||
D6AEBB422321685E00E5038B /* OpenInSafariActivity.swift */,
|
||||
D64BC19123C271D9000D0238 /* MastodonActivity.swift */,
|
||||
D6AEBB4623216B0C00E5038B /* Account Activities */,
|
||||
D627943323A5523800D38C68 /* Status Activities */,
|
||||
);
|
||||
path = Activities;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D6AEBB4623216B0C00E5038B /* Account Activities */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D6AEBB4723216B1D00E5038B /* AccountActivity.swift */,
|
||||
D6AEBB402321642700E5038B /* SendMesasgeActivity.swift */,
|
||||
D6AEBB4423216AF800E5038B /* FollowAccountActivity.swift */,
|
||||
D6AEBB4923216F0400E5038B /* UnfollowAccountActivity.swift */,
|
||||
);
|
||||
path = "Account Activities";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D6B053A023BD2BED00A066FA /* Asset Picker */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1389,7 +1325,6 @@
|
|||
D641C78B213DD92F004B4513 /* Profile Header */,
|
||||
D641C78A213DD926004B4513 /* Status */,
|
||||
D64AAE8F26C80DB600FC57FB /* Toast */,
|
||||
D6420AEB26BED17500ED8175 /* Timeline Description Cell */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1436,6 +1371,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
D63CC703290EC472000E19DE /* Dist.xcconfig */,
|
||||
D6D706A829498C82000827ED /* Tusker.xcconfig */,
|
||||
D674A50727F910F300BA03AC /* Pachyderm */,
|
||||
D6BEA243291A0C83002F4D01 /* Duckable */,
|
||||
D6D4DDCE212518A000E1C4BB /* Tusker */,
|
||||
|
@ -1772,7 +1708,6 @@
|
|||
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 */,
|
||||
|
@ -1884,7 +1819,6 @@
|
|||
D68E525D24A3E8F00054355A /* SearchViewController.swift in Sources */,
|
||||
D61F75BB293C183100C0B37F /* HTMLConverter.swift in Sources */,
|
||||
D61F75A5293ABD6F00C0B37F /* EditFilterView.swift in Sources */,
|
||||
D6AEBB412321642700E5038B /* SendMesasgeActivity.swift in Sources */,
|
||||
D6BC9DB1232C61BC002CA326 /* NotificationsPageViewController.swift in Sources */,
|
||||
D6ADB6EC28EA73CB009924AB /* StatusContentContainer.swift in Sources */,
|
||||
D6969E9E240C81B9002843CE /* NSTextAttachment+Emoji.swift in Sources */,
|
||||
|
@ -1916,7 +1850,6 @@
|
|||
D611C2CF232DC61100C86A49 /* HashtagTableViewCell.swift in Sources */,
|
||||
D627944F23A9C99800D38C68 /* EditListAccountsViewController.swift in Sources */,
|
||||
D6945C3423AC6431005C403C /* AddSavedHashtagViewController.swift in Sources */,
|
||||
D627943723A552C200D38C68 /* BookmarkStatusActivity.swift in Sources */,
|
||||
D6F6A552291F098700F496A8 /* RenameListService.swift in Sources */,
|
||||
D68ACE5D279B1ABA001CE8EB /* AssetPickerControlCollectionViewCell.swift in Sources */,
|
||||
D62D2426217ABF63005076CC /* UserActivityType.swift in Sources */,
|
||||
|
@ -1953,11 +1886,9 @@
|
|||
D6A6C10F25B62D2400298D0F /* DiskCache.swift in Sources */,
|
||||
D6B81F3C2560365300F6E31D /* RefreshableViewController.swift in Sources */,
|
||||
D646C958213B367000269FB5 /* LargeImageShrinkAnimationController.swift in Sources */,
|
||||
D64BC18823C1640A000D0238 /* PinStatusActivity.swift in Sources */,
|
||||
D6674AEA23341F7600E8DF94 /* AppShortcutItems.swift in Sources */,
|
||||
D646C956213B365700269FB5 /* LargeImageExpandAnimationController.swift in Sources */,
|
||||
D667E5F82135C3040057A976 /* Mastodon+Equatable.swift in Sources */,
|
||||
D681E4D5246E2BC30053414F /* UnmuteConversationActivity.swift in Sources */,
|
||||
D6B4A4FF2506B81A000C81C1 /* AccountDisplayNameLabel.swift in Sources */,
|
||||
D63D8DF42850FE7A008D95E1 /* ViewTags.swift in Sources */,
|
||||
D61DC84B28F4FD2000B82C6E /* ProfileHeaderCollectionViewCell.swift in Sources */,
|
||||
|
@ -1972,7 +1903,6 @@
|
|||
D6531DEE246B81C9000F9538 /* GifvAttachmentView.swift in Sources */,
|
||||
D673ACCE2919E74200D6F8B0 /* MenuPicker.swift in Sources */,
|
||||
D6370B9C24421FF30092A7FF /* Tusker.xcdatamodeld in Sources */,
|
||||
D6AEBB4823216B1D00E5038B /* AccountActivity.swift in Sources */,
|
||||
04ED00B121481ED800567C53 /* SteppedProgressView.swift in Sources */,
|
||||
D677284C24ECBE9100C732D3 /* ComposeAvatarImageView.swift in Sources */,
|
||||
D6A6C11B25B63CEE00298D0F /* MemoryCache.swift in Sources */,
|
||||
|
@ -1987,7 +1917,6 @@
|
|||
D623A5412635FB3C0095BD04 /* PollOptionView.swift in Sources */,
|
||||
D61F75B1293BD85300C0B37F /* CreateFilterService.swift in Sources */,
|
||||
D65C6BF525478A9C00A6E89C /* BackgroundableViewController.swift in Sources */,
|
||||
D6AEBB4A23216F0400E5038B /* UnfollowAccountActivity.swift in Sources */,
|
||||
D61DC84D28F500D200B82C6E /* ProfileViewController.swift in Sources */,
|
||||
D663626421360D2300C9CBA2 /* AvatarStyle.swift in Sources */,
|
||||
D693A72A25CF8C1E003A14E2 /* ProfileDirectoryViewController.swift in Sources */,
|
||||
|
@ -2005,11 +1934,9 @@
|
|||
D627944A23A6AD6100D38C68 /* BookmarksTableViewController.swift in Sources */,
|
||||
D63CC7102911F1E4000E19DE /* UIScrollView+Top.swift in Sources */,
|
||||
D6F6A557291F4F1600F496A8 /* MuteAccountView.swift in Sources */,
|
||||
D64BC19223C271D9000D0238 /* MastodonActivity.swift in Sources */,
|
||||
D6945C3A23AC75E2005C403C /* FindInstanceViewController.swift in Sources */,
|
||||
D68E6F59253C9969001A1B4C /* MultiSourceEmojiLabel.swift in Sources */,
|
||||
D63F9C6E241D2D85004C03CF /* CompositionAttachment.swift in Sources */,
|
||||
D6AEBB4523216AF800E5038B /* FollowAccountActivity.swift in Sources */,
|
||||
D6EBF01523C55C0900AE061B /* UIApplication+Scenes.swift in Sources */,
|
||||
D6538945214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift in Sources */,
|
||||
D6F0B17524A3A1AA001E48C3 /* MainSidebarViewController.swift in Sources */,
|
||||
|
@ -2018,7 +1945,6 @@
|
|||
D61F75B7293C119700C0B37F /* Filterer.swift in Sources */,
|
||||
D64AAE9526C88C5000FC57FB /* ToastableViewController.swift in Sources */,
|
||||
D6895DE928D962C2006341DA /* TimelineLikeController.swift in Sources */,
|
||||
D6420AEE26BED18B00ED8175 /* PublicTimelineDescriptionTableViewCell.swift in Sources */,
|
||||
D6E0DC8E216EDF1E00369478 /* Previewing.swift in Sources */,
|
||||
D6B93667281D937300237D0E /* MainSidebarMyProfileCollectionViewCell.swift in Sources */,
|
||||
D61F75BD293D099600C0B37F /* Lazy.swift in Sources */,
|
||||
|
@ -2029,7 +1955,6 @@
|
|||
D6DD2A45273D6C5700386A6C /* GIFImageView.swift in Sources */,
|
||||
D61F759029353B4300C0B37F /* FileManager+Size.swift in Sources */,
|
||||
0427033822B30F5F000D31B6 /* BehaviorPrefsView.swift in Sources */,
|
||||
D627943923A553B600D38C68 /* UnbookmarkStatusActivity.swift in Sources */,
|
||||
D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */,
|
||||
D6945C2F23AC47C3005C403C /* SavedDataManager.swift in Sources */,
|
||||
D6C94D892139E6EC00CB5196 /* AttachmentView.swift in Sources */,
|
||||
|
@ -2038,7 +1963,6 @@
|
|||
D6B053AB23BD2F1400A066FA /* AssetCollectionViewCell.swift in Sources */,
|
||||
D622757A24EE21D900B82A16 /* ComposeAttachmentRow.swift in Sources */,
|
||||
D6E4269D2532A3E100C02E1C /* FuzzyMatcher.swift in Sources */,
|
||||
D681E4D3246E2AFF0053414F /* MuteConversationActivity.swift in Sources */,
|
||||
D6969EA0240C8384002843CE /* EmojiLabel.swift in Sources */,
|
||||
D64BC18623C1253A000D0238 /* AssetPreviewViewController.swift in Sources */,
|
||||
D6F6A550291F058600F496A8 /* CreateListService.swift in Sources */,
|
||||
|
@ -2058,7 +1982,6 @@
|
|||
D6D12B58292D5B2C00D528E1 /* StatusActionAccountListViewController.swift in Sources */,
|
||||
D6412B0D24B0D4CF00F5412E /* ProfileHeaderView.swift in Sources */,
|
||||
D641C77F213DC78A004B4513 /* InlineTextAttachment.swift in Sources */,
|
||||
D627943523A5525100D38C68 /* StatusActivity.swift in Sources */,
|
||||
D61A45E628DC0F2F002BE511 /* ConfirmLoadMoreCollectionViewCell.swift in Sources */,
|
||||
D663626C21361C6700C9CBA2 /* Account+Preferences.swift in Sources */,
|
||||
D67895C0246870DE00D4CD9E /* LocalAccountAvatarView.swift in Sources */,
|
||||
|
@ -2124,7 +2047,6 @@
|
|||
D6BEA247291A0F2D002F4D01 /* Duckable+Root.swift in Sources */,
|
||||
04D14BB022B34A2800642648 /* GalleryViewController.swift in Sources */,
|
||||
D6C1B2082545D1EC00DAAA66 /* StatusCardView.swift in Sources */,
|
||||
D64BC18A23C16487000D0238 /* UnpinStatusActivity.swift in Sources */,
|
||||
D64D8CA92463B494006B0BAA /* MultiThreadDictionary.swift in Sources */,
|
||||
D6F6A554291F0D9600F496A8 /* DeleteListService.swift in Sources */,
|
||||
D68E6F5F253C9B2D001A1B4C /* BaseEmojiLabel.swift in Sources */,
|
||||
|
@ -2307,8 +2229,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 52;
|
||||
DEVELOPMENT_TEAM = V4WK9KR9U2;
|
||||
CURRENT_PROJECT_VERSION = 53;
|
||||
INFOPLIST_FILE = Tusker/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
|
@ -2317,7 +2238,7 @@
|
|||
);
|
||||
MARKETING_VERSION = 2022.1;
|
||||
OTHER_CODE_SIGN_FLAGS = "";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = space.vaccor.Tusker;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).Tusker";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
@ -2375,8 +2296,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 52;
|
||||
DEVELOPMENT_TEAM = V4WK9KR9U2;
|
||||
CURRENT_PROJECT_VERSION = 53;
|
||||
INFOPLIST_FILE = OpenInTusker/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.3;
|
||||
|
@ -2386,7 +2306,7 @@
|
|||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2022.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = space.vaccor.Tusker.OpenInTusker;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).Tusker.OpenInTusker";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
@ -2397,6 +2317,7 @@
|
|||
};
|
||||
D6D4DDF2212518A200E1C4BB /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D6D706A829498C82000827ED /* Tusker.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
|
@ -2461,6 +2382,7 @@
|
|||
};
|
||||
D6D4DDF3212518A200E1C4BB /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D6D706A829498C82000827ED /* Tusker.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
|
@ -2525,8 +2447,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 52;
|
||||
DEVELOPMENT_TEAM = V4WK9KR9U2;
|
||||
CURRENT_PROJECT_VERSION = 53;
|
||||
INFOPLIST_FILE = Tusker/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
|
@ -2536,7 +2457,7 @@
|
|||
MARKETING_VERSION = 2022.1;
|
||||
OTHER_CODE_SIGN_FLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = space.vaccor.Tusker;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).Tusker";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
@ -2554,8 +2475,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 52;
|
||||
DEVELOPMENT_TEAM = V4WK9KR9U2;
|
||||
CURRENT_PROJECT_VERSION = 53;
|
||||
INFOPLIST_FILE = Tusker/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
|
@ -2564,7 +2484,7 @@
|
|||
);
|
||||
MARKETING_VERSION = 2022.1;
|
||||
OTHER_CODE_SIGN_FLAGS = "";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = space.vaccor.Tusker;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).Tusker";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
@ -2664,8 +2584,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 52;
|
||||
DEVELOPMENT_TEAM = V4WK9KR9U2;
|
||||
CURRENT_PROJECT_VERSION = 53;
|
||||
INFOPLIST_FILE = OpenInTusker/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.3;
|
||||
|
@ -2675,7 +2594,7 @@
|
|||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2022.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = space.vaccor.Tusker.OpenInTusker;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).Tusker.OpenInTusker";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
@ -2691,8 +2610,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 52;
|
||||
DEVELOPMENT_TEAM = V4WK9KR9U2;
|
||||
CURRENT_PROJECT_VERSION = 53;
|
||||
INFOPLIST_FILE = OpenInTusker/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.3;
|
||||
|
@ -2702,7 +2620,7 @@
|
|||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2022.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = space.vaccor.Tusker.OpenInTusker;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).Tusker.OpenInTusker";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
//
|
||||
// AccountActivity.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 9/5/19.
|
||||
// Copyright © 2019 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class AccountActivity: MastodonActivity {
|
||||
|
||||
override class var activityCategory: UIActivity.Category {
|
||||
return .action
|
||||
}
|
||||
|
||||
var account: AccountMO?
|
||||
|
||||
override func canPerform(withActivityItems activityItems: [Any]) -> Bool {
|
||||
for case is AccountMO in activityItems {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override func prepare(withActivityItems activityItems: [Any]) {
|
||||
for case let account as AccountMO in activityItems {
|
||||
self.account = account
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
//
|
||||
// FollowAccountActivity.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 9/5/19.
|
||||
// Copyright © 2019 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Pachyderm
|
||||
|
||||
class FollowAccountActivity: AccountActivity {
|
||||
|
||||
override var activityType: UIActivity.ActivityType? {
|
||||
return .followAccount
|
||||
}
|
||||
|
||||
override var activityTitle: String? {
|
||||
return NSLocalizedString("Follow", comment: "follow account activity title")
|
||||
}
|
||||
override var activityImage: UIImage? {
|
||||
return UIImage(systemName: "person.badge.plus")
|
||||
}
|
||||
|
||||
override func perform() {
|
||||
guard let account = account else { return }
|
||||
|
||||
UIImpactFeedbackGenerator(style: .medium).impactOccurred()
|
||||
|
||||
let request = Account.follow(account.id)
|
||||
mastodonController.run(request) { (response) in
|
||||
switch response {
|
||||
case .failure(_):
|
||||
// todo: display error message
|
||||
UINotificationFeedbackGenerator().notificationOccurred(.error)
|
||||
fatalError()
|
||||
case let .success(relationship, _):
|
||||
self.mastodonController.persistentContainer.addOrUpdate(relationship: relationship)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
//
|
||||
// SendMesasgeActivity.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 9/5/19.
|
||||
// Copyright © 2019 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SendMessageActivity: AccountActivity {
|
||||
|
||||
override var activityType: UIActivity.ActivityType? {
|
||||
return .sendMessageMentioningAccount
|
||||
}
|
||||
|
||||
override var activityTitle: String? {
|
||||
return NSLocalizedString("Send Message", comment: "send message activity title")
|
||||
}
|
||||
override var activityImage: UIImage? {
|
||||
return UIImage(systemName: "square.and.pencil")
|
||||
}
|
||||
|
||||
override func perform() {
|
||||
activityDidFinish(true)
|
||||
}
|
||||
|
||||
override var activityViewController: UIViewController? {
|
||||
guard let account = account else { return nil }
|
||||
|
||||
let draft = mastodonController.createDraft(mentioningAcct: account.acct)
|
||||
let compose = ComposeHostingController(draft: draft, mastodonController: mastodonController)
|
||||
return UINavigationController(rootViewController: compose)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
//
|
||||
// UnfollowActivity.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 9/5/19.
|
||||
// Copyright © 2019 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Pachyderm
|
||||
|
||||
class UnfollowAccountActivity: AccountActivity {
|
||||
|
||||
override var activityType: UIActivity.ActivityType? {
|
||||
return .unfollowAccount
|
||||
}
|
||||
|
||||
override var activityTitle: String? {
|
||||
return NSLocalizedString("Unfollow", comment: "unfollow account activity title")
|
||||
}
|
||||
override var activityImage: UIImage? {
|
||||
return UIImage(systemName: "person.badge.minus")
|
||||
}
|
||||
|
||||
override func perform() {
|
||||
guard let account = account else { return }
|
||||
|
||||
UIImpactFeedbackGenerator(style: .medium).impactOccurred()
|
||||
|
||||
let request = Account.unfollow(account.id)
|
||||
mastodonController.run(request) { (response) in
|
||||
switch response {
|
||||
case .failure(_):
|
||||
// todo: display error message
|
||||
UINotificationFeedbackGenerator().notificationOccurred(.error)
|
||||
fatalError()
|
||||
case let .success(relationship, _):
|
||||
self.mastodonController.persistentContainer.addOrUpdate(relationship: relationship)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
//
|
||||
// MastodonActivity.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 1/5/20.
|
||||
// Copyright © 2020 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class MastodonActivity: UIActivity {
|
||||
var mastodonController: MastodonController {
|
||||
let scene = UIApplication.shared.activeOrBackgroundScene!
|
||||
return scene.session.mastodonController!
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
//
|
||||
// BookmarkStatusActivity.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 12/14/19.
|
||||
// Copyright © 2019 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Pachyderm
|
||||
|
||||
class BookmarkStatusActivity: StatusActivity {
|
||||
|
||||
override var activityType: UIActivity.ActivityType? {
|
||||
return .bookmarkStatus
|
||||
}
|
||||
|
||||
override var activityTitle: String? {
|
||||
return NSLocalizedString("Bookmark", comment: "bookmark status activity title")
|
||||
}
|
||||
|
||||
override var activityImage: UIImage? {
|
||||
return UIImage(systemName: "bookmark")
|
||||
}
|
||||
|
||||
override func perform() {
|
||||
guard let status = status else { return }
|
||||
|
||||
let request = Status.bookmark(status.id)
|
||||
mastodonController.run(request) { (response) in
|
||||
if case let .success(status, _) = response {
|
||||
self.mastodonController.persistentContainer.addOrUpdate(status: status)
|
||||
} else {
|
||||
// todo: display error message
|
||||
UINotificationFeedbackGenerator().notificationOccurred(.error)
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
//
|
||||
// MuteConversationActivity.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 5/14/20.
|
||||
// Copyright © 2020 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Pachyderm
|
||||
|
||||
class MuteConversationActivity: StatusActivity {
|
||||
override var activityType: UIActivity.ActivityType? {
|
||||
return .muteConversation
|
||||
}
|
||||
|
||||
override var activityTitle: String? {
|
||||
return NSLocalizedString("Mute Conversation", comment: "mute conversation activity title")
|
||||
}
|
||||
|
||||
override var activityImage: UIImage? {
|
||||
return UIImage(systemName: "speaker.slash")
|
||||
}
|
||||
|
||||
override func perform() {
|
||||
guard let status = status else { return }
|
||||
|
||||
let request = Status.muteConversation(status.id)
|
||||
mastodonController.run(request) { (response) in
|
||||
if case let .success(status, _) = response {
|
||||
self.mastodonController.persistentContainer.addOrUpdate(status: status)
|
||||
} else {
|
||||
// todo: display error message
|
||||
UINotificationFeedbackGenerator().notificationOccurred(.error)
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
//
|
||||
// PinStatusActivity.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 1/4/20.
|
||||
// Copyright © 2020 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Pachyderm
|
||||
|
||||
class PinStatusActivity: StatusActivity {
|
||||
override var activityType: UIActivity.ActivityType? {
|
||||
return .pinStatus
|
||||
}
|
||||
|
||||
override var activityTitle: String? {
|
||||
return NSLocalizedString("Pin", comment: "pin status activity title")
|
||||
}
|
||||
|
||||
override var activityImage: UIImage? {
|
||||
return UIImage(systemName: "pin")
|
||||
}
|
||||
|
||||
override func perform() {
|
||||
guard let status = status else { return }
|
||||
|
||||
let request = Status.pin(status.id)
|
||||
mastodonController.run(request) { (response) in
|
||||
if case let .success(status, _) = response {
|
||||
self.mastodonController.persistentContainer.addOrUpdate(status: status)
|
||||
} else {
|
||||
// todo: display error message
|
||||
UINotificationFeedbackGenerator().notificationOccurred(.error)
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
//
|
||||
// StatusActivity.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 12/14/19.
|
||||
// Copyright © 2019 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class StatusActivity: MastodonActivity {
|
||||
|
||||
override class var activityCategory: UIActivity.Category {
|
||||
return .action
|
||||
}
|
||||
|
||||
var status: StatusMO?
|
||||
|
||||
override func canPerform(withActivityItems activityItems: [Any]) -> Bool {
|
||||
for case is StatusMO in activityItems {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override func prepare(withActivityItems activityItems: [Any]) {
|
||||
for case let status as StatusMO in activityItems {
|
||||
self.status = status
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
//
|
||||
// UnbookmarkStatusActivity.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 12/14/19.
|
||||
// Copyright © 2019 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Pachyderm
|
||||
|
||||
class UnbookmarkStatusActivity: StatusActivity {
|
||||
|
||||
override var activityType: UIActivity.ActivityType? {
|
||||
return .unbookmarkStatus
|
||||
}
|
||||
|
||||
override var activityTitle: String? {
|
||||
return NSLocalizedString("Unbookmark", comment: "unbookmark status activity title")
|
||||
}
|
||||
|
||||
override var activityImage: UIImage? {
|
||||
return UIImage(systemName: "bookmark.fill")
|
||||
}
|
||||
|
||||
override func perform() {
|
||||
guard let status = status else { return }
|
||||
|
||||
let request = Status.unbookmark(status.id)
|
||||
mastodonController.run(request) { (response) in
|
||||
if case let .success(status, _) = response {
|
||||
self.mastodonController.persistentContainer.addOrUpdate(status: status)
|
||||
} else {
|
||||
// todo: display error message
|
||||
UINotificationFeedbackGenerator().notificationOccurred(.error)
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
//
|
||||
// UnmuteConversationActivity.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 5/14/20.
|
||||
// Copyright © 2020 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Pachyderm
|
||||
|
||||
class UnmuteConversationActivity: StatusActivity {
|
||||
override var activityType: UIActivity.ActivityType? {
|
||||
return .unmuteConversation
|
||||
}
|
||||
|
||||
override var activityTitle: String? {
|
||||
return NSLocalizedString("Unmute Conversation", comment: "unmute conversation activity title")
|
||||
}
|
||||
|
||||
override var activityImage: UIImage? {
|
||||
return UIImage(systemName: "speaker")
|
||||
}
|
||||
|
||||
override func perform() {
|
||||
guard let status = status else { return }
|
||||
|
||||
let request = Status.unmuteConversation(status.id)
|
||||
mastodonController.run(request) { (response) in
|
||||
if case let .success(status, _) = response {
|
||||
self.mastodonController.persistentContainer.addOrUpdate(status: status)
|
||||
} else {
|
||||
// todo: display error message
|
||||
UINotificationFeedbackGenerator().notificationOccurred(.error)
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
//
|
||||
// UnpinStatusActivity.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 1/4/20.
|
||||
// Copyright © 2020 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Pachyderm
|
||||
|
||||
class UnpinStatusActivity: StatusActivity {
|
||||
override var activityType: UIActivity.ActivityType? {
|
||||
return .unpinStatus
|
||||
}
|
||||
|
||||
override var activityTitle: String? {
|
||||
return NSLocalizedString("Unpin", comment: "unpin status activity title")
|
||||
}
|
||||
|
||||
override var activityImage: UIImage? {
|
||||
return UIImage(systemName: "pin.slash")
|
||||
}
|
||||
|
||||
override func perform() {
|
||||
guard let status = status else { return }
|
||||
|
||||
let request = Status.unpin(status.id)
|
||||
mastodonController.run(request) { (response) in
|
||||
if case let .success(status, _) = response {
|
||||
self.mastodonController.persistentContainer.addOrUpdate(status: status)
|
||||
} else {
|
||||
// todo: display error message
|
||||
UINotificationFeedbackGenerator().notificationOccurred(.error)
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,17 +12,4 @@ extension UIActivity.ActivityType {
|
|||
|
||||
static let openInSafari = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).open_in_safari")
|
||||
|
||||
// Account
|
||||
static let sendMessageMentioningAccount = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).send_message_mentioning_account")
|
||||
static let followAccount = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).follow_account")
|
||||
static let unfollowAccount = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).unfollow_account")
|
||||
|
||||
// Status
|
||||
static let bookmarkStatus = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).bookmark_status")
|
||||
static let unbookmarkStatus = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).unbookmark_status")
|
||||
static let pinStatus = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).pin_status")
|
||||
static let unpinStatus = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).unpin_status")
|
||||
static let muteConversation = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).mute_conversation")
|
||||
static let unmuteConversation = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).unmute_conversation")
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import WebURLFoundationExtras
|
|||
struct HTMLConverter {
|
||||
|
||||
static let defaultFont = UIFont.systemFont(ofSize: 17)
|
||||
static let defaultMonospaceFont = UIFont.monospacedSystemFont(ofSize: 17, weight: .regular)
|
||||
static let defaultColor = UIColor.label
|
||||
static let defaultParagraphStyle: NSParagraphStyle = {
|
||||
let style = NSMutableParagraphStyle()
|
||||
|
@ -23,6 +24,7 @@ struct HTMLConverter {
|
|||
}()
|
||||
|
||||
var font: UIFont = defaultFont
|
||||
var monospaceFont: UIFont = defaultMonospaceFont
|
||||
var color: UIColor = defaultColor
|
||||
var paragraphStyle: NSParagraphStyle = defaultParagraphStyle
|
||||
|
||||
|
@ -90,11 +92,10 @@ struct HTMLConverter {
|
|||
case "del":
|
||||
attributed.addAttribute(.strikethroughStyle, value: NSUnderlineStyle.single.rawValue, range: attributed.fullRange)
|
||||
case "code":
|
||||
// TODO: this probably breaks with dynamic type
|
||||
attributed.addAttribute(.font, value: UIFont.monospacedSystemFont(ofSize: font.pointSize, weight: .regular), range: attributed.fullRange)
|
||||
attributed.addAttribute(.font, value: monospaceFont, range: attributed.fullRange)
|
||||
case "pre":
|
||||
attributed.append(NSAttributedString(string: "\n\n"))
|
||||
attributed.addAttribute(.font, value: UIFont.monospacedSystemFont(ofSize: font.pointSize, weight: .regular), range: attributed.fullRange)
|
||||
attributed.addAttribute(.font, value: monospaceFont, range: attributed.fullRange)
|
||||
case "ol", "ul":
|
||||
attributed.append(NSAttributedString(string: "\n\n"))
|
||||
attributed.trimLeadingCharactersInSet(.whitespacesAndNewlines)
|
||||
|
@ -106,7 +107,7 @@ struct HTMLConverter {
|
|||
let index = (try? node.elementSiblingIndex()) ?? 0
|
||||
// we use the monospace digit font so that the periods of all the list items line up
|
||||
// TODO: this probably breaks with dynamic type
|
||||
bullet = NSAttributedString(string: "\(index + 1).\t", attributes: [.font: UIFont.monospacedDigitSystemFont(ofSize: font.pointSize, weight: .regular), .foregroundColor: color])
|
||||
bullet = NSAttributedString(string: "\(index + 1).\t", attributes: [.font: monospaceFont, .foregroundColor: color])
|
||||
} else if parentTag == "ul" {
|
||||
bullet = NSAttributedString(string: "\u{2022}\t", attributes: [.font: font, .foregroundColor: color])
|
||||
} else {
|
||||
|
|
|
@ -11,13 +11,13 @@ import Foundation
|
|||
private let decoder = PropertyListDecoder()
|
||||
private let encoder = PropertyListEncoder()
|
||||
|
||||
// todo: invalidate cache on underlying data change using KVO?
|
||||
@propertyWrapper
|
||||
public struct LazilyDecoding<Enclosing, Value: Codable> {
|
||||
public struct LazilyDecoding<Enclosing: NSObject, Value: Codable> {
|
||||
|
||||
private let keyPath: ReferenceWritableKeyPath<Enclosing, Data?>
|
||||
private let fallback: Value
|
||||
private var value: Value?
|
||||
private var observation: NSKeyValueObservation?
|
||||
|
||||
init(from keyPath: ReferenceWritableKeyPath<Enclosing, Data?>, fallback: Value) {
|
||||
self.keyPath = keyPath
|
||||
|
@ -39,6 +39,12 @@ public struct LazilyDecoding<Enclosing, Value: Codable> {
|
|||
do {
|
||||
let value = try decoder.decode(Box<Value>.self, from: data)
|
||||
wrapper.value = value.value
|
||||
wrapper.observation = instance.observe(wrapper.keyPath, changeHandler: { instance, _ in
|
||||
var updated = instance[keyPath: storageKeyPath]
|
||||
updated.value = nil
|
||||
updated.observation = nil
|
||||
instance[keyPath: storageKeyPath] = updated
|
||||
})
|
||||
instance[keyPath: storageKeyPath] = wrapper
|
||||
return value.value
|
||||
} catch {
|
||||
|
|
|
@ -165,7 +165,9 @@ struct MainComposeWrappedTextView: UIViewRepresentable {
|
|||
}
|
||||
|
||||
override func paste(_ sender: Any?) {
|
||||
if UIPasteboard.general.contains(pasteboardTypes: CompositionAttachment.readableTypeIdentifiersForItemProvider) {
|
||||
// we deliberately exclude the other CompositionAttachment readable type identifiers, because that's too overzealous with the conversion
|
||||
// and things like URLs end up pasting as attachments
|
||||
if UIPasteboard.general.contains(pasteboardTypes: UIImage.readableTypeIdentifiersForItemProvider) {
|
||||
uiState.delegate?.paste(itemProviders: UIPasteboard.general.itemProviders)
|
||||
} else {
|
||||
super.paste(sender)
|
||||
|
|
|
@ -193,7 +193,6 @@ class ConversationTableViewController: EnhancedTableViewController {
|
|||
let parentIDs = self.getDirectParents(inReplyTo: mainStatusInReplyToID, from: context.ancestors)
|
||||
let parentStatuses = context.ancestors.filter { parentIDs.contains($0.id) }
|
||||
|
||||
// todo: should this really be blindly adding all the descendants?
|
||||
await mastodonController.persistentContainer.addAll(statuses: parentStatuses + context.descendants)
|
||||
self.contextLoaded(mainStatus: mainStatus, context: context, parentIDs: parentIDs)
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ class FeaturedProfileCollectionViewCell: UICollectionViewCell {
|
|||
displayNameLabel.adjustsFontForContentSizeCategory = true
|
||||
|
||||
noteTextView.defaultFont = .preferredFont(forTextStyle: .body)
|
||||
noteTextView.monospaceFont = UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 17, weight: .regular))
|
||||
noteTextView.adjustsFontForContentSizeCategory = true
|
||||
noteTextView.textContainer.lineBreakMode = .byTruncatingTail
|
||||
noteTextView.textContainerInset = UIEdgeInsets(top: 16, left: 4, bottom: 16, right: 4)
|
||||
|
|
|
@ -12,6 +12,7 @@ import Pachyderm
|
|||
class TrendingStatusesViewController: UIViewController {
|
||||
|
||||
weak var mastodonController: MastodonController!
|
||||
let filterer: Filterer
|
||||
|
||||
private var collectionView: UICollectionView {
|
||||
view as! UICollectionView
|
||||
|
@ -22,6 +23,10 @@ class TrendingStatusesViewController: UIViewController {
|
|||
|
||||
init(mastodonController: MastodonController) {
|
||||
self.mastodonController = mastodonController
|
||||
self.filterer = Filterer(mastodonController: mastodonController, context: .public)
|
||||
self.filterer.htmlConverter.font = TimelineStatusCollectionViewCell.contentFont
|
||||
self.filterer.htmlConverter.monospaceFont = TimelineStatusCollectionViewCell.monospaceFont
|
||||
self.filterer.htmlConverter.paragraphStyle = TimelineStatusCollectionViewCell.contentParagraphStyle
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
||||
|
@ -49,7 +54,7 @@ class TrendingStatusesViewController: UIViewController {
|
|||
config.topSeparatorVisibility = .hidden
|
||||
config.bottomSeparatorVisibility = .hidden
|
||||
}
|
||||
if case .status(_, _) = item {
|
||||
if case .status(_, _, _) = item {
|
||||
config.topSeparatorInsets = TimelineStatusCollectionViewCell.separatorInsets
|
||||
config.bottomSeparatorInsets = TimelineStatusCollectionViewCell.separatorInsets
|
||||
}
|
||||
|
@ -64,18 +69,25 @@ class TrendingStatusesViewController: UIViewController {
|
|||
}
|
||||
|
||||
private func createDataSource() -> UICollectionViewDiffableDataSource<Section, Item> {
|
||||
let statusCell = UICollectionView.CellRegistration<TimelineStatusCollectionViewCell, (String, CollapseState)> { [unowned self] cell, indexPath, item in
|
||||
let statusCell = UICollectionView.CellRegistration<TimelineStatusCollectionViewCell, (String, CollapseState, Filterer.Result, NSAttributedString?)> { [unowned self] cell, indexPath, item in
|
||||
cell.delegate = self
|
||||
// TODO: filter these
|
||||
cell.updateUI(statusID: item.0, state: item.1, filterResult: .allow, precomputedContent: nil)
|
||||
cell.updateUI(statusID: item.0, state: item.1, filterResult: item.2, precomputedContent: item.3)
|
||||
}
|
||||
let zeroHeightCell = UICollectionView.CellRegistration<ZeroHeightCollectionViewCell, Void> { _, _, _ in
|
||||
}
|
||||
let loadingCell = UICollectionView.CellRegistration<LoadingCollectionViewCell, Void> { cell, _, _ in
|
||||
cell.indicator.startAnimating()
|
||||
}
|
||||
return UICollectionViewDiffableDataSource(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in
|
||||
return UICollectionViewDiffableDataSource(collectionView: collectionView) { [unowned self] collectionView, indexPath, itemIdentifier in
|
||||
switch itemIdentifier {
|
||||
case .status(id: let id, state: let state):
|
||||
return collectionView.dequeueConfiguredReusableCell(using: statusCell, for: indexPath, item: (id, state))
|
||||
case .status(id: let id, let collapseState, let filterState):
|
||||
let (result, attributedString) = self.filterer.resolve(state: filterState, status: { mastodonController.persistentContainer.status(for: id)! })
|
||||
switch result {
|
||||
case .allow, .warn(_):
|
||||
return collectionView.dequeueConfiguredReusableCell(using: statusCell, for: indexPath, item: (id, collapseState, result, attributedString))
|
||||
case .hide:
|
||||
return collectionView.dequeueConfiguredReusableCell(using: zeroHeightCell, for: indexPath, item: ())
|
||||
}
|
||||
case .loadingIndicator:
|
||||
return collectionView.dequeueConfiguredReusableCell(using: loadingCell, for: indexPath, item: ())
|
||||
}
|
||||
|
@ -115,7 +127,7 @@ class TrendingStatusesViewController: UIViewController {
|
|||
await mastodonController.persistentContainer.addAll(statuses: statuses)
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
||||
snapshot.appendSections([.statuses])
|
||||
snapshot.appendItems(statuses.map { .status(id: $0.id, state: .unknown) })
|
||||
snapshot.appendItems(statuses.map { .status(id: $0.id, collapseState: .unknown, filterState: .unknown) })
|
||||
await dataSource.apply(snapshot)
|
||||
}
|
||||
}
|
||||
|
@ -125,12 +137,12 @@ extension TrendingStatusesViewController {
|
|||
case statuses
|
||||
}
|
||||
enum Item: Hashable {
|
||||
case status(id: String, state: CollapseState)
|
||||
case status(id: String, collapseState: CollapseState, filterState: FilterState)
|
||||
case loadingIndicator
|
||||
|
||||
static func ==(lhs: Item, rhs: Item) -> Bool {
|
||||
switch (lhs, rhs) {
|
||||
case (.status(id: let a, state: _), .status(id: let b, state: _)):
|
||||
case (.status(id: let a, _, _), .status(id: let b, _, _)):
|
||||
return a == b
|
||||
case (.loadingIndicator, .loadingIndicator):
|
||||
return true
|
||||
|
@ -141,7 +153,7 @@ extension TrendingStatusesViewController {
|
|||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
switch self {
|
||||
case .status(id: let id, state: _):
|
||||
case .status(id: let id, _, _):
|
||||
hasher.combine(0)
|
||||
hasher.combine(id)
|
||||
case .loadingIndicator:
|
||||
|
@ -158,7 +170,7 @@ extension TrendingStatusesViewController {
|
|||
}
|
||||
|
||||
var isSelectable: Bool {
|
||||
if case .status(id: _, state: _) = self {
|
||||
if case .status(id: _, _, _) = self {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
|
@ -173,7 +185,7 @@ extension TrendingStatusesViewController: UICollectionViewDelegate {
|
|||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||
guard case .status(id: let id, state: let state) = dataSource.itemIdentifier(for: indexPath) else {
|
||||
guard case .status(id: let id, collapseState: let state, _) = dataSource.itemIdentifier(for: indexPath) else {
|
||||
return
|
||||
}
|
||||
selected(status: id, state: state.copy())
|
||||
|
|
|
@ -12,12 +12,12 @@ import Combine
|
|||
|
||||
class EditListAccountsViewController: EnhancedTableViewController {
|
||||
|
||||
private var list: List
|
||||
let mastodonController: MastodonController
|
||||
|
||||
private var list: List
|
||||
var changedAccounts = false
|
||||
|
||||
var dataSource: DataSource!
|
||||
|
||||
var nextRange: RequestRange?
|
||||
|
||||
var searchResultsController: SearchResultsViewController!
|
||||
|
@ -122,6 +122,7 @@ class EditListAccountsViewController: EnhancedTableViewController {
|
|||
}
|
||||
|
||||
private func addAccount(id: String) async {
|
||||
changedAccounts = true
|
||||
do {
|
||||
let req = List.add(list, accounts: [id])
|
||||
_ = try await mastodonController.run(req)
|
||||
|
@ -137,6 +138,7 @@ class EditListAccountsViewController: EnhancedTableViewController {
|
|||
}
|
||||
|
||||
private func removeAccount(id: String) async {
|
||||
changedAccounts = true
|
||||
do {
|
||||
let request = List.remove(list, accounts: [id])
|
||||
_ = try await mastodonController.run(request)
|
||||
|
|
|
@ -71,12 +71,15 @@ class ListTimelineViewController: TimelineViewController {
|
|||
}
|
||||
|
||||
@objc func editListDoneButtonPressed() {
|
||||
let presented = (presentedViewController as? UINavigationController)?.viewControllers.first as? EditListAccountsViewController
|
||||
|
||||
dismiss(animated: true)
|
||||
|
||||
// TODO: only reload if there were changes
|
||||
Task {
|
||||
applyInitialSnapshot()
|
||||
await controller.loadInitial()
|
||||
if presented?.changedAccounts == true {
|
||||
Task {
|
||||
applyInitialSnapshot()
|
||||
await controller.loadInitial()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -487,7 +487,6 @@ fileprivate extension MainTabBarViewController.Tab {
|
|||
case .explore:
|
||||
return "magnifyingglass"
|
||||
case .myProfile:
|
||||
// todo: use user avatar image
|
||||
return "person"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ class PreferencesNavigationController: UINavigationController {
|
|||
private var isSwitchingAccounts = false
|
||||
|
||||
init(mastodonController: MastodonController) {
|
||||
let view = PreferencesView()
|
||||
let view = PreferencesView(mastodonController: mastodonController)
|
||||
let hostingController = UIHostingController(rootView: view)
|
||||
super.init(rootViewController: hostingController)
|
||||
hostingController.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(donePressed))
|
||||
|
@ -61,29 +61,34 @@ class PreferencesNavigationController: UINavigationController {
|
|||
// when switching accounts shortly after adding a new one, there is an old instance of PreferncesNavigationController still around
|
||||
// which tries to handle the notification but is unable to because it no longer is in a window (and therefore doesn't have a scene delegate)
|
||||
// the propper fix would be to figure out what's leaking instances of this class
|
||||
guard let window = self.view.window,
|
||||
let windowScene = window.windowScene,
|
||||
// todo: my profile can be torn off into a separate window, this doesn't work
|
||||
let sceneDelegate = windowScene.delegate as? MainSceneDelegate else {
|
||||
return
|
||||
guard let windowScene = self.view.window?.windowScene else {
|
||||
return
|
||||
}
|
||||
let account = notification.userInfo!["account"] as! LocalData.UserAccountInfo
|
||||
isSwitchingAccounts = true
|
||||
dismiss(animated: true) { // dismiss preferences
|
||||
sceneDelegate.activateAccount(account, animated: true)
|
||||
if let sceneDelegate = windowScene.delegate as? MainSceneDelegate {
|
||||
isSwitchingAccounts = true
|
||||
dismiss(animated: true) { // dismiss preferences
|
||||
sceneDelegate.activateAccount(account, animated: true)
|
||||
}
|
||||
} else {
|
||||
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: UserActivityManager.mainSceneActivity(accountID: account.id), options: nil)
|
||||
}
|
||||
}
|
||||
|
||||
@objc func userLoggedOut() {
|
||||
guard let window = self.view.window,
|
||||
let windowScene = window.windowScene,
|
||||
// todo: my profile can be torn off into a separate window, this doesn't work
|
||||
let sceneDelegate = windowScene.delegate as? MainSceneDelegate else {
|
||||
return
|
||||
guard let windowScene = self.view.window?.windowScene else {
|
||||
return
|
||||
}
|
||||
isSwitchingAccounts = true
|
||||
dismiss(animated: true) { // dismiss preferences
|
||||
sceneDelegate.logoutCurrent()
|
||||
if let sceneDelegate = windowScene.delegate as? MainSceneDelegate {
|
||||
isSwitchingAccounts = true
|
||||
dismiss(animated: true) { // dismiss preferences
|
||||
sceneDelegate.logoutCurrent()
|
||||
}
|
||||
} else {
|
||||
LocalData.shared.removeAccount(LocalData.shared.getMostRecentAccount()!)
|
||||
let accountID = LocalData.shared.getMostRecentAccount()?.id
|
||||
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: UserActivityManager.mainSceneActivity(accountID: accountID), options: nil)
|
||||
UIApplication.shared.requestSceneSessionDestruction(windowScene.session, options: nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,12 +96,15 @@ class PreferencesNavigationController: UINavigationController {
|
|||
|
||||
extension PreferencesNavigationController: OnboardingViewControllerDelegate {
|
||||
func didFinishOnboarding(account: LocalData.UserAccountInfo) {
|
||||
DispatchQueue.main.async {
|
||||
// todo: my profile can be torn off into a separate window, this will crash
|
||||
let sceneDelegate = self.view.window!.windowScene!.delegate as! MainSceneDelegate
|
||||
self.dismiss(animated: true) { // dismiss instance selector
|
||||
self.dismiss(animated: true) { // dismiss preferences
|
||||
guard let windowScene = self.view.window?.windowScene else {
|
||||
return
|
||||
}
|
||||
self.dismiss(animated: true) { // dismiss instance selector
|
||||
self.dismiss(animated: true) { // dismiss preferences
|
||||
if let sceneDelegate = windowScene.delegate as? MainSceneDelegate {
|
||||
sceneDelegate.activateAccount(account, animated: false)
|
||||
} else {
|
||||
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: UserActivityManager.mainSceneActivity(accountID: account.id), options: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,13 @@
|
|||
import SwiftUI
|
||||
|
||||
struct PreferencesView: View {
|
||||
let mastodonController: MastodonController
|
||||
@ObservedObject var localData = LocalData.shared
|
||||
@State private var showingLogoutConfirmation = false
|
||||
|
||||
init(mastodonController: MastodonController) {
|
||||
self.mastodonController = mastodonController
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
// workaround: the navigation view is provided by MyProfileTableViewController so that it can inject the Done button
|
||||
|
@ -30,7 +35,7 @@ struct PreferencesView: View {
|
|||
.foregroundColor(.primary)
|
||||
}
|
||||
Spacer()
|
||||
if account == self.localData.getMostRecentAccount() {
|
||||
if account == mastodonController.accountInfo! {
|
||||
Image(systemName: "checkmark")
|
||||
.renderingMode(.template)
|
||||
.foregroundColor(.secondary)
|
||||
|
@ -43,7 +48,7 @@ struct PreferencesView: View {
|
|||
}.onDelete { (indices: IndexSet) in
|
||||
var indices = indices
|
||||
var logoutFromCurrent = false
|
||||
if let index = indices.first(where: { localData.accounts[$0] == localData.getMostRecentAccount() }) {
|
||||
if let index = indices.first(where: { localData.accounts[$0] == mastodonController.accountInfo! }) {
|
||||
logoutFromCurrent = true
|
||||
indices.remove(index)
|
||||
}
|
||||
|
@ -102,10 +107,10 @@ struct PreferencesView: View {
|
|||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
struct PreferencesView_Previews : PreviewProvider {
|
||||
static var previews: some View {
|
||||
return PreferencesView()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//#if DEBUG
|
||||
//struct PreferencesView_Previews : PreviewProvider {
|
||||
// static var previews: some View {
|
||||
// return PreferencesView()
|
||||
// }
|
||||
//}
|
||||
//#endif
|
||||
|
|
|
@ -136,8 +136,6 @@ class SearchResultsViewController: EnhancedTableViewController {
|
|||
if let sourceDataSource = source.dataSource {
|
||||
dataSource.apply(sourceDataSource.snapshot())
|
||||
}
|
||||
// todo: check if the search needs to be performed before searching
|
||||
// performSearch(query: currentQuery)
|
||||
}
|
||||
|
||||
func performSearch(query: String?) {
|
||||
|
|
|
@ -42,6 +42,7 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
|
|||
}
|
||||
self.filterer = Filterer(mastodonController: mastodonController, context: filterContext)
|
||||
self.filterer.htmlConverter.font = TimelineStatusCollectionViewCell.contentFont
|
||||
self.filterer.htmlConverter.monospaceFont = TimelineStatusCollectionViewCell.monospaceFont
|
||||
self.filterer.htmlConverter.paragraphStyle = TimelineStatusCollectionViewCell.contentParagraphStyle
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
|
|
@ -46,11 +46,13 @@ class UserActivityManager {
|
|||
}
|
||||
|
||||
// MARK: - Main Scene
|
||||
static func mainSceneActivity(accountID: String) -> NSUserActivity {
|
||||
static func mainSceneActivity(accountID: String?) -> NSUserActivity {
|
||||
let activity = NSUserActivity(type: .mainScene)
|
||||
activity.userInfo = [
|
||||
"accountID": accountID,
|
||||
]
|
||||
if let accountID {
|
||||
activity.userInfo = [
|
||||
"accountID": accountID,
|
||||
]
|
||||
}
|
||||
return activity
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ class ConfirmReblogStatusPreviewView: UIView {
|
|||
|
||||
let contentView = StatusContentTextView()
|
||||
contentView.defaultFont = .preferredFont(forTextStyle: .caption2)
|
||||
contentView.monospaceFont = UIFontMetrics(forTextStyle: .caption2).scaledFont(for: .monospacedSystemFont(ofSize: 17, weight: .regular))
|
||||
contentView.isUserInteractionEnabled = false
|
||||
contentView.isScrollEnabled = false
|
||||
contentView.backgroundColor = nil
|
||||
|
|
|
@ -27,6 +27,10 @@ class ContentTextView: LinkTextView, BaseEmojiLabel {
|
|||
_read { yield htmlConverter.font }
|
||||
_modify { yield &htmlConverter.font }
|
||||
}
|
||||
var monospaceFont: UIFont {
|
||||
_read { yield htmlConverter.monospaceFont }
|
||||
_modify { yield &htmlConverter.monospaceFont }
|
||||
}
|
||||
var defaultColor: UIColor {
|
||||
_read { yield htmlConverter.color }
|
||||
_modify { yield &htmlConverter.color }
|
||||
|
|
|
@ -35,6 +35,7 @@ class InstanceTableViewCell: UITableViewCell {
|
|||
adultLabel.layer.cornerRadius = 0.5 * adultLabel.bounds.height
|
||||
|
||||
descriptionTextView.defaultFont = .preferredFont(forTextStyle: .body)
|
||||
descriptionTextView.monospaceFont = UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 17, weight: .regular))
|
||||
descriptionTextView.adjustsFontForContentSizeCategory = true
|
||||
}
|
||||
|
||||
|
|
|
@ -184,6 +184,7 @@ private class ProfileFieldValueView: UIView {
|
|||
|
||||
textView.isSelectable = false
|
||||
textView.defaultFont = .preferredFont(forTextStyle: .body)
|
||||
textView.monospaceFont = UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 17, weight: .regular))
|
||||
textView.adjustsFontForContentSizeCategory = true
|
||||
textView.setTextFromHtml(field.value)
|
||||
textView.setEmojis(account.emojis, identifier: account.id)
|
||||
|
|
|
@ -82,6 +82,7 @@ class ProfileHeaderView: UIView {
|
|||
relationshipLabel.adjustsFontForContentSizeCategory = true
|
||||
|
||||
noteTextView.defaultFont = .preferredFont(forTextStyle: .body)
|
||||
noteTextView.monospaceFont = UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 17, weight: .regular))
|
||||
noteTextView.adjustsFontForContentSizeCategory = true
|
||||
|
||||
pagesSegmentedControl = ScrollingSegmentedControl(frame: .zero)
|
||||
|
|
|
@ -64,7 +64,8 @@ class ConversationMainStatusTableViewCell: BaseStatusTableViewCell {
|
|||
contentWarningLabel.font = .preferredFont(forTextStyle: .body).withTraits(.traitBold)!
|
||||
contentWarningLabel.adjustsFontForContentSizeCategory = true
|
||||
|
||||
contentTextView.defaultFont = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 18))
|
||||
contentTextView.defaultFont = UIFontMetrics.default.scaledFont(for: .systemFont(ofSize: 18))
|
||||
contentTextView.monospaceFont = UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 18, weight: .regular))
|
||||
contentTextView.adjustsFontForContentSizeCategory = true
|
||||
contentTextView.dataDetectorTypes = [.flightNumber, .address, .shipmentTrackingNumber, .phoneNumber]
|
||||
if #available(iOS 16.0, *) {
|
||||
|
|
|
@ -16,7 +16,8 @@ private let hashtagIcon = UIImage(systemName: "number")
|
|||
class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollectionViewCell {
|
||||
|
||||
static let separatorInsets = NSDirectionalEdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 0)
|
||||
static let contentFont = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 16))
|
||||
static let contentFont = UIFontMetrics.default.scaledFont(for: .systemFont(ofSize: 16))
|
||||
static let monospaceFont = UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 16, weight: .regular))
|
||||
static let contentParagraphStyle = HTMLConverter.defaultParagraphStyle
|
||||
|
||||
// MARK: Subviews
|
||||
|
@ -167,6 +168,7 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
|
|||
|
||||
let contentContainer = StatusContentContainer().configure {
|
||||
$0.contentTextView.defaultFont = TimelineStatusCollectionViewCell.contentFont
|
||||
$0.contentTextView.monospaceFont = TimelineStatusCollectionViewCell.monospaceFont
|
||||
$0.contentTextView.paragraphStyle = TimelineStatusCollectionViewCell.contentParagraphStyle
|
||||
$0.setContentHuggingPriority(.defaultLow, for: .vertical)
|
||||
}
|
||||
|
|
|
@ -85,7 +85,8 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell {
|
|||
]), size: 0)
|
||||
contentWarningLabel.adjustsFontForContentSizeCategory = true
|
||||
|
||||
contentTextView.defaultFont = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 16))
|
||||
contentTextView.defaultFont = UIFontMetrics.default.scaledFont(for: .systemFont(ofSize: 16))
|
||||
contentTextView.monospaceFont = UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 16, weight: .regular))
|
||||
contentTextView.adjustsFontForContentSizeCategory = true
|
||||
|
||||
// todo: double check this on RTL layouts
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
//
|
||||
// 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()
|
||||
|
||||
contentView.backgroundColor = .tintColor
|
||||
}
|
||||
|
||||
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?()
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19150" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19134"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="78" id="KGk-i7-Jjw" customClass="PublicTimelineDescriptionTableViewCell" customModule="Tusker" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="78"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="78"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="N97-CH-58I">
|
||||
<rect key="frame" x="16" y="8" width="288" height="62"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" systemColor="systemBlueColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="N97-CH-58I" secondAttribute="bottom" constant="8" id="2Lg-we-j2c"/>
|
||||
<constraint firstItem="N97-CH-58I" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="8" id="FdS-q9-obT"/>
|
||||
<constraint firstItem="N97-CH-58I" firstAttribute="trailing" secondItem="H2p-sc-9uM" secondAttribute="trailingMargin" id="KqX-Qy-18G"/>
|
||||
<constraint firstItem="N97-CH-58I" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" id="Pqy-8N-OnX"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
|
||||
<connections>
|
||||
<outlet property="descriptionLabel" destination="N97-CH-58I" id="z1W-HD-xy9"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="131.8840579710145" y="121.875"/>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
<resources>
|
||||
<systemColor name="systemBlueColor">
|
||||
<color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
Loading…
Reference in New Issue