Merge pull request #84 from tootsuite/feature/searchAPI
Feature/search api
This commit is contained in:
commit
379884b001
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="17709" systemVersion="20D80" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="17709" systemVersion="20D75" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||||
<entity name="Application" representedClassName=".Application" syncable="YES">
|
<entity name="Application" representedClassName=".Application" syncable="YES">
|
||||||
<attribute name="identifier" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
|
<attribute name="identifier" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
|
||||||
<attribute name="name" attributeType="String"/>
|
<attribute name="name" attributeType="String"/>
|
||||||
|
@ -35,11 +35,11 @@
|
||||||
<relationship name="toot" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Toot" inverseName="emojis" inverseEntity="Toot"/>
|
<relationship name="toot" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Toot" inverseName="emojis" inverseEntity="Toot"/>
|
||||||
</entity>
|
</entity>
|
||||||
<entity name="History" representedClassName=".History" syncable="YES">
|
<entity name="History" representedClassName=".History" syncable="YES">
|
||||||
<attribute name="accounts" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
<attribute name="accounts" optional="YES" attributeType="String"/>
|
||||||
<attribute name="createAt" attributeType="Date" defaultDateTimeInterval="631123200" usesScalarValueType="NO"/>
|
<attribute name="createAt" attributeType="Date" defaultDateTimeInterval="631123200" usesScalarValueType="NO"/>
|
||||||
<attribute name="day" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
<attribute name="day" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||||
<attribute name="identifier" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
|
<attribute name="identifier" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
|
||||||
<attribute name="uses" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
<attribute name="uses" optional="YES" attributeType="String"/>
|
||||||
<relationship name="tag" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Tag" inverseName="histories" inverseEntity="Tag"/>
|
<relationship name="tag" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Tag" inverseName="histories" inverseEntity="Tag"/>
|
||||||
</entity>
|
</entity>
|
||||||
<entity name="HomeTimelineIndex" representedClassName=".HomeTimelineIndex" syncable="YES">
|
<entity name="HomeTimelineIndex" representedClassName=".HomeTimelineIndex" syncable="YES">
|
||||||
|
|
|
@ -14,8 +14,8 @@ public final class History: NSManagedObject {
|
||||||
@NSManaged public private(set) var createAt: Date
|
@NSManaged public private(set) var createAt: Date
|
||||||
|
|
||||||
@NSManaged public private(set) var day: Date
|
@NSManaged public private(set) var day: Date
|
||||||
@NSManaged public private(set) var uses: Int
|
@NSManaged public private(set) var uses: String
|
||||||
@NSManaged public private(set) var accounts: Int
|
@NSManaged public private(set) var accounts: String
|
||||||
|
|
||||||
// many-to-one relationship
|
// many-to-one relationship
|
||||||
@NSManaged public private(set) var tag: Tag
|
@NSManaged public private(set) var tag: Tag
|
||||||
|
@ -43,10 +43,10 @@ public extension History {
|
||||||
public extension History {
|
public extension History {
|
||||||
struct Property {
|
struct Property {
|
||||||
public let day: Date
|
public let day: Date
|
||||||
public let uses: Int
|
public let uses: String
|
||||||
public let accounts: Int
|
public let accounts: String
|
||||||
|
|
||||||
public init(day: Date, uses: Int, accounts: Int) {
|
public init(day: Date, uses: String, accounts: String) {
|
||||||
self.day = day
|
self.day = day
|
||||||
self.uses = uses
|
self.uses = uses
|
||||||
self.accounts = accounts
|
self.accounts = accounts
|
||||||
|
|
|
@ -234,6 +234,12 @@
|
||||||
"private": "Followers only",
|
"private": "Followers only",
|
||||||
"direct": "Only people I mention"
|
"direct": "Only people I mention"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
"searchBar": {
|
||||||
|
"placeholder": "Search hashtags and users",
|
||||||
|
"cancel": "Cancel"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,10 @@
|
||||||
2D32EAAC25CB96DC00C9ED86 /* TimelineMiddleLoaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D32EAAB25CB96DC00C9ED86 /* TimelineMiddleLoaderTableViewCell.swift */; };
|
2D32EAAC25CB96DC00C9ED86 /* TimelineMiddleLoaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D32EAAB25CB96DC00C9ED86 /* TimelineMiddleLoaderTableViewCell.swift */; };
|
||||||
2D32EABA25CB9B0500C9ED86 /* UIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D32EAB925CB9B0500C9ED86 /* UIView.swift */; };
|
2D32EABA25CB9B0500C9ED86 /* UIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D32EAB925CB9B0500C9ED86 /* UIView.swift */; };
|
||||||
2D32EADA25CBCC3300C9ED86 /* PublicTimelineViewModel+LoadMiddleState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D32EAD925CBCC3300C9ED86 /* PublicTimelineViewModel+LoadMiddleState.swift */; };
|
2D32EADA25CBCC3300C9ED86 /* PublicTimelineViewModel+LoadMiddleState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D32EAD925CBCC3300C9ED86 /* PublicTimelineViewModel+LoadMiddleState.swift */; };
|
||||||
|
2D34D9CB261489930081BFC0 /* SearchViewController+recomendView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D34D9CA261489930081BFC0 /* SearchViewController+recomendView.swift */; };
|
||||||
|
2D34D9D126148D9E0081BFC0 /* APIService+Recommend.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D34D9D026148D9E0081BFC0 /* APIService+Recommend.swift */; };
|
||||||
|
2D34D9DB261494120081BFC0 /* APIService+Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D34D9DA261494120081BFC0 /* APIService+Search.swift */; };
|
||||||
|
2D34D9E226149C920081BFC0 /* SearchRecommendTagsCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D34D9E126149C920081BFC0 /* SearchRecommendTagsCollectionViewCell.swift */; };
|
||||||
2D364F7225E66D7500204FDC /* MastodonResendEmailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */; };
|
2D364F7225E66D7500204FDC /* MastodonResendEmailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */; };
|
||||||
2D364F7825E66D8300204FDC /* MastodonResendEmailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */; };
|
2D364F7825E66D8300204FDC /* MastodonResendEmailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */; };
|
||||||
2D38F1C625CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1C525CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift */; };
|
2D38F1C625CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1C525CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift */; };
|
||||||
|
@ -42,7 +46,7 @@
|
||||||
2D38F1FE25CD481700561493 /* StatusProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1FD25CD481700561493 /* StatusProvider.swift */; };
|
2D38F1FE25CD481700561493 /* StatusProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1FD25CD481700561493 /* StatusProvider.swift */; };
|
||||||
2D38F20825CD491300561493 /* DisposeBagCollectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F20725CD491300561493 /* DisposeBagCollectable.swift */; };
|
2D38F20825CD491300561493 /* DisposeBagCollectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F20725CD491300561493 /* DisposeBagCollectable.swift */; };
|
||||||
2D3F9E0425DFA133004262D9 /* UITapGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D3F9E0325DFA133004262D9 /* UITapGestureRecognizer.swift */; };
|
2D3F9E0425DFA133004262D9 /* UITapGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D3F9E0325DFA133004262D9 /* UITapGestureRecognizer.swift */; };
|
||||||
2D42FF6125C8177C004A627A /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = 2D42FF6025C8177C004A627A /* SwiftPackageProductDependency */; };
|
2D42FF6125C8177C004A627A /* ActiveLabel in Frameworks */ = {isa = PBXBuildFile; productRef = 2D42FF6025C8177C004A627A /* ActiveLabel */; };
|
||||||
2D42FF6B25C817D2004A627A /* TootContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF6A25C817D2004A627A /* TootContent.swift */; };
|
2D42FF6B25C817D2004A627A /* TootContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF6A25C817D2004A627A /* TootContent.swift */; };
|
||||||
2D42FF7E25C82218004A627A /* ActionToolBarContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF7D25C82218004A627A /* ActionToolBarContainer.swift */; };
|
2D42FF7E25C82218004A627A /* ActionToolBarContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF7D25C82218004A627A /* ActionToolBarContainer.swift */; };
|
||||||
2D42FF8525C8224F004A627A /* HitTestExpandedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF8425C8224F004A627A /* HitTestExpandedButton.swift */; };
|
2D42FF8525C8224F004A627A /* HitTestExpandedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF8425C8224F004A627A /* HitTestExpandedButton.swift */; };
|
||||||
|
@ -52,18 +56,19 @@
|
||||||
2D571B2F26004EC000540450 /* NavigationBarProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D571B2E26004EC000540450 /* NavigationBarProgressView.swift */; };
|
2D571B2F26004EC000540450 /* NavigationBarProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D571B2E26004EC000540450 /* NavigationBarProgressView.swift */; };
|
||||||
2D59819B25E4A581000FB903 /* MastodonConfirmEmailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D59819A25E4A581000FB903 /* MastodonConfirmEmailViewController.swift */; };
|
2D59819B25E4A581000FB903 /* MastodonConfirmEmailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D59819A25E4A581000FB903 /* MastodonConfirmEmailViewController.swift */; };
|
||||||
2D5981A125E4A593000FB903 /* MastodonConfirmEmailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5981A025E4A593000FB903 /* MastodonConfirmEmailViewModel.swift */; };
|
2D5981A125E4A593000FB903 /* MastodonConfirmEmailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5981A025E4A593000FB903 /* MastodonConfirmEmailViewModel.swift */; };
|
||||||
2D5981BA25E4D7F8000FB903 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = 2D5981B925E4D7F8000FB903 /* SwiftPackageProductDependency */; };
|
2D5981BA25E4D7F8000FB903 /* ThirdPartyMailer in Frameworks */ = {isa = PBXBuildFile; productRef = 2D5981B925E4D7F8000FB903 /* ThirdPartyMailer */; };
|
||||||
2D5A3D0325CF8742002347D6 /* ControlContainableScrollViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A3D0225CF8742002347D6 /* ControlContainableScrollViews.swift */; };
|
2D5A3D0325CF8742002347D6 /* ControlContainableScrollViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A3D0225CF8742002347D6 /* ControlContainableScrollViews.swift */; };
|
||||||
2D5A3D2825CF8BC9002347D6 /* HomeTimelineViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A3D2725CF8BC9002347D6 /* HomeTimelineViewModel+Diffable.swift */; };
|
2D5A3D2825CF8BC9002347D6 /* HomeTimelineViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A3D2725CF8BC9002347D6 /* HomeTimelineViewModel+Diffable.swift */; };
|
||||||
2D5A3D3825CF8D9F002347D6 /* ScrollViewContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A3D3725CF8D9F002347D6 /* ScrollViewContainer.swift */; };
|
2D5A3D3825CF8D9F002347D6 /* ScrollViewContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A3D3725CF8D9F002347D6 /* ScrollViewContainer.swift */; };
|
||||||
2D5A3D6225CFD9CB002347D6 /* HomeTimelineViewController+DebugAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A3D6125CFD9CB002347D6 /* HomeTimelineViewController+DebugAction.swift */; };
|
2D5A3D6225CFD9CB002347D6 /* HomeTimelineViewController+DebugAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A3D6125CFD9CB002347D6 /* HomeTimelineViewController+DebugAction.swift */; };
|
||||||
2D61335825C188A000CAE157 /* APIService+Persist+Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D61335725C188A000CAE157 /* APIService+Persist+Status.swift */; };
|
2D61335825C188A000CAE157 /* APIService+Persist+Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D61335725C188A000CAE157 /* APIService+Persist+Status.swift */; };
|
||||||
2D61335E25C1894B00CAE157 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D61335D25C1894B00CAE157 /* APIService.swift */; };
|
2D61335E25C1894B00CAE157 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D61335D25C1894B00CAE157 /* APIService.swift */; };
|
||||||
2D61336925C18A4F00CAE157 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = 2D61336825C18A4F00CAE157 /* SwiftPackageProductDependency */; };
|
2D61336925C18A4F00CAE157 /* AlamofireNetworkActivityIndicator in Frameworks */ = {isa = PBXBuildFile; productRef = 2D61336825C18A4F00CAE157 /* AlamofireNetworkActivityIndicator */; };
|
||||||
2D650FAB25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D650FAA25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift */; };
|
2D650FAB25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D650FAA25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift */; };
|
||||||
2D694A7425F9EB4E0038ADDC /* ContentWarningOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D694A7325F9EB4E0038ADDC /* ContentWarningOverlayView.swift */; };
|
2D694A7425F9EB4E0038ADDC /* ContentWarningOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D694A7325F9EB4E0038ADDC /* ContentWarningOverlayView.swift */; };
|
||||||
2D69CFF425CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69CFF325CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift */; };
|
2D69CFF425CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69CFF325CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift */; };
|
||||||
2D69D00A25CAA00300C3A1B2 /* APIService+CoreData+Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69D00925CAA00300C3A1B2 /* APIService+CoreData+Status.swift */; };
|
2D69D00A25CAA00300C3A1B2 /* APIService+CoreData+Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69D00925CAA00300C3A1B2 /* APIService+CoreData+Status.swift */; };
|
||||||
|
2D6DE40026141DF600A63F6A /* SearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D6DE3FF26141DF600A63F6A /* SearchViewModel.swift */; };
|
||||||
2D76316525C14BD100929FB9 /* PublicTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76316425C14BD100929FB9 /* PublicTimelineViewController.swift */; };
|
2D76316525C14BD100929FB9 /* PublicTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76316425C14BD100929FB9 /* PublicTimelineViewController.swift */; };
|
||||||
2D76316B25C14D4C00929FB9 /* PublicTimelineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76316A25C14D4C00929FB9 /* PublicTimelineViewModel.swift */; };
|
2D76316B25C14D4C00929FB9 /* PublicTimelineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76316A25C14D4C00929FB9 /* PublicTimelineViewModel.swift */; };
|
||||||
2D76317D25C14DF500929FB9 /* PublicTimelineViewController+StatusProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76317C25C14DF400929FB9 /* PublicTimelineViewController+StatusProvider.swift */; };
|
2D76317D25C14DF500929FB9 /* PublicTimelineViewController+StatusProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76317C25C14DF400929FB9 /* PublicTimelineViewController+StatusProvider.swift */; };
|
||||||
|
@ -81,7 +86,7 @@
|
||||||
2D927F0E25C7E9C9004F19B8 /* History.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D927F0D25C7E9C9004F19B8 /* History.swift */; };
|
2D927F0E25C7E9C9004F19B8 /* History.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D927F0D25C7E9C9004F19B8 /* History.swift */; };
|
||||||
2D927F1425C7EDD9004F19B8 /* Emoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D927F1325C7EDD9004F19B8 /* Emoji.swift */; };
|
2D927F1425C7EDD9004F19B8 /* Emoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D927F1325C7EDD9004F19B8 /* Emoji.swift */; };
|
||||||
2D939AB525EDD8A90076FA61 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D939AB425EDD8A90076FA61 /* String.swift */; };
|
2D939AB525EDD8A90076FA61 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D939AB425EDD8A90076FA61 /* String.swift */; };
|
||||||
2D939AC825EE14620076FA61 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = 2D939AC725EE14620076FA61 /* SwiftPackageProductDependency */; };
|
2D939AC825EE14620076FA61 /* CropViewController in Frameworks */ = {isa = PBXBuildFile; productRef = 2D939AC725EE14620076FA61 /* CropViewController */; };
|
||||||
2D939AE825EE1CF80076FA61 /* MastodonRegisterViewController+Avatar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D939AE725EE1CF80076FA61 /* MastodonRegisterViewController+Avatar.swift */; };
|
2D939AE825EE1CF80076FA61 /* MastodonRegisterViewController+Avatar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D939AE725EE1CF80076FA61 /* MastodonRegisterViewController+Avatar.swift */; };
|
||||||
2DA504692601ADE7008F4E6C /* SawToothView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA504682601ADE7008F4E6C /* SawToothView.swift */; };
|
2DA504692601ADE7008F4E6C /* SawToothView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA504682601ADE7008F4E6C /* SawToothView.swift */; };
|
||||||
2DA6054725F716A2006356F9 /* PlaybackState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA6054625F716A2006356F9 /* PlaybackState.swift */; };
|
2DA6054725F716A2006356F9 /* PlaybackState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA6054625F716A2006356F9 /* PlaybackState.swift */; };
|
||||||
|
@ -95,7 +100,8 @@
|
||||||
2DF75BA725D10E1000694EC8 /* APIService+Favorite.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75BA625D10E1000694EC8 /* APIService+Favorite.swift */; };
|
2DF75BA725D10E1000694EC8 /* APIService+Favorite.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75BA625D10E1000694EC8 /* APIService+Favorite.swift */; };
|
||||||
2DF75BB925D1474100694EC8 /* ManagedObjectObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75BB825D1474100694EC8 /* ManagedObjectObserver.swift */; };
|
2DF75BB925D1474100694EC8 /* ManagedObjectObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75BB825D1474100694EC8 /* ManagedObjectObserver.swift */; };
|
||||||
2DF75BC725D1475D00694EC8 /* ManagedObjectContextObjectsDidChange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75BC625D1475D00694EC8 /* ManagedObjectContextObjectsDidChange.swift */; };
|
2DF75BC725D1475D00694EC8 /* ManagedObjectContextObjectsDidChange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75BC625D1475D00694EC8 /* ManagedObjectContextObjectsDidChange.swift */; };
|
||||||
5D526FE225BE9AC400460CB9 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = 5D526FE125BE9AC400460CB9 /* SwiftPackageProductDependency */; };
|
2DFF41892614A4DC00F776A4 /* UIView+Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF41882614A4DC00F776A4 /* UIView+Constraint.swift */; };
|
||||||
|
5D526FE225BE9AC400460CB9 /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 5D526FE125BE9AC400460CB9 /* MastodonSDK */; };
|
||||||
5DF1054125F886D400D6C0D4 /* ViedeoPlaybackService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1054025F886D400D6C0D4 /* ViedeoPlaybackService.swift */; };
|
5DF1054125F886D400D6C0D4 /* ViedeoPlaybackService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1054025F886D400D6C0D4 /* ViedeoPlaybackService.swift */; };
|
||||||
5DF1054725F8870E00D6C0D4 /* VideoPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1054625F8870E00D6C0D4 /* VideoPlayerViewModel.swift */; };
|
5DF1054725F8870E00D6C0D4 /* VideoPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1054625F8870E00D6C0D4 /* VideoPlayerViewModel.swift */; };
|
||||||
5DF1056425F887CB00D6C0D4 /* AVPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1056325F887CB00D6C0D4 /* AVPlayer.swift */; };
|
5DF1056425F887CB00D6C0D4 /* AVPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1056325F887CB00D6C0D4 /* AVPlayer.swift */; };
|
||||||
|
@ -108,7 +114,7 @@
|
||||||
DB0140A125C40C0600F9F3CF /* MastodonPinBasedAuthenticationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0140A025C40C0600F9F3CF /* MastodonPinBasedAuthenticationViewController.swift */; };
|
DB0140A125C40C0600F9F3CF /* MastodonPinBasedAuthenticationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0140A025C40C0600F9F3CF /* MastodonPinBasedAuthenticationViewController.swift */; };
|
||||||
DB0140A825C40C1500F9F3CF /* MastodonPinBasedAuthenticationViewModelNavigationDelegateShim.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0140A725C40C1500F9F3CF /* MastodonPinBasedAuthenticationViewModelNavigationDelegateShim.swift */; };
|
DB0140A825C40C1500F9F3CF /* MastodonPinBasedAuthenticationViewModelNavigationDelegateShim.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0140A725C40C1500F9F3CF /* MastodonPinBasedAuthenticationViewModelNavigationDelegateShim.swift */; };
|
||||||
DB0140AE25C40C7300F9F3CF /* MastodonPinBasedAuthenticationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0140AD25C40C7300F9F3CF /* MastodonPinBasedAuthenticationViewModel.swift */; };
|
DB0140AE25C40C7300F9F3CF /* MastodonPinBasedAuthenticationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0140AD25C40C7300F9F3CF /* MastodonPinBasedAuthenticationViewModel.swift */; };
|
||||||
DB0140BD25C40D7500F9F3CF /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = DB0140BC25C40D7500F9F3CF /* SwiftPackageProductDependency */; };
|
DB0140BD25C40D7500F9F3CF /* CommonOSLog in Frameworks */ = {isa = PBXBuildFile; productRef = DB0140BC25C40D7500F9F3CF /* CommonOSLog */; };
|
||||||
DB0140CF25C42AEE00F9F3CF /* OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0140CE25C42AEE00F9F3CF /* OSLog.swift */; };
|
DB0140CF25C42AEE00F9F3CF /* OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0140CE25C42AEE00F9F3CF /* OSLog.swift */; };
|
||||||
DB084B5725CBC56C00F898ED /* Toot.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB084B5625CBC56C00F898ED /* Toot.swift */; };
|
DB084B5725CBC56C00F898ED /* Toot.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB084B5625CBC56C00F898ED /* Toot.swift */; };
|
||||||
DB0AC6FC25CD02E600D75117 /* APIService+Instance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */; };
|
DB0AC6FC25CD02E600D75117 /* APIService+Instance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */; };
|
||||||
|
@ -126,7 +132,7 @@
|
||||||
DB2B3AE925E38850007045F9 /* UIViewPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2B3AE825E38850007045F9 /* UIViewPreview.swift */; };
|
DB2B3AE925E38850007045F9 /* UIViewPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2B3AE825E38850007045F9 /* UIViewPreview.swift */; };
|
||||||
DB2F073525E8ECF000957B2D /* AuthenticationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2F073325E8ECF000957B2D /* AuthenticationViewModel.swift */; };
|
DB2F073525E8ECF000957B2D /* AuthenticationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2F073325E8ECF000957B2D /* AuthenticationViewModel.swift */; };
|
||||||
DB2FF510260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2FF50F260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift */; };
|
DB2FF510260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2FF50F260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift */; };
|
||||||
DB3D0FF325BAA61700EAA174 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = DB3D0FF225BAA61700EAA174 /* SwiftPackageProductDependency */; };
|
DB3D0FF325BAA61700EAA174 /* AlamofireImage in Frameworks */ = {isa = PBXBuildFile; productRef = DB3D0FF225BAA61700EAA174 /* AlamofireImage */; };
|
||||||
DB3D100D25BAA75E00EAA174 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DB3D100F25BAA75E00EAA174 /* Localizable.strings */; };
|
DB3D100D25BAA75E00EAA174 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DB3D100F25BAA75E00EAA174 /* Localizable.strings */; };
|
||||||
DB427DD625BAA00100D1B89D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB427DD525BAA00100D1B89D /* AppDelegate.swift */; };
|
DB427DD625BAA00100D1B89D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB427DD525BAA00100D1B89D /* AppDelegate.swift */; };
|
||||||
DB427DD825BAA00100D1B89D /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB427DD725BAA00100D1B89D /* SceneDelegate.swift */; };
|
DB427DD825BAA00100D1B89D /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB427DD725BAA00100D1B89D /* SceneDelegate.swift */; };
|
||||||
|
@ -163,7 +169,7 @@
|
||||||
DB49A63D25FF609300B98345 /* PlayerContainerView+MediaTypeIndicotorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB49A63C25FF609300B98345 /* PlayerContainerView+MediaTypeIndicotorView.swift */; };
|
DB49A63D25FF609300B98345 /* PlayerContainerView+MediaTypeIndicotorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB49A63C25FF609300B98345 /* PlayerContainerView+MediaTypeIndicotorView.swift */; };
|
||||||
DB5086A525CC0B7000C2C187 /* AvatarBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5086A425CC0B7000C2C187 /* AvatarBarButtonItem.swift */; };
|
DB5086A525CC0B7000C2C187 /* AvatarBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5086A425CC0B7000C2C187 /* AvatarBarButtonItem.swift */; };
|
||||||
DB5086AB25CC0BBB00C2C187 /* AvatarConfigurableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5086AA25CC0BBB00C2C187 /* AvatarConfigurableView.swift */; };
|
DB5086AB25CC0BBB00C2C187 /* AvatarConfigurableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5086AA25CC0BBB00C2C187 /* AvatarConfigurableView.swift */; };
|
||||||
DB5086B825CC0D6400C2C187 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = DB5086B725CC0D6400C2C187 /* SwiftPackageProductDependency */; };
|
DB5086B825CC0D6400C2C187 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = DB5086B725CC0D6400C2C187 /* Kingfisher */; };
|
||||||
DB5086BE25CC0D9900C2C187 /* SplashPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5086BD25CC0D9900C2C187 /* SplashPreference.swift */; };
|
DB5086BE25CC0D9900C2C187 /* SplashPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5086BD25CC0D9900C2C187 /* SplashPreference.swift */; };
|
||||||
DB55D33025FB630A0002F825 /* TwitterTextEditor+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB55D32F25FB630A0002F825 /* TwitterTextEditor+String.swift */; };
|
DB55D33025FB630A0002F825 /* TwitterTextEditor+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB55D32F25FB630A0002F825 /* TwitterTextEditor+String.swift */; };
|
||||||
DB59F0FE25EF5D96001F1DAB /* StatusProvider+UITableViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB59F0FD25EF5D96001F1DAB /* StatusProvider+UITableViewDelegate.swift */; };
|
DB59F0FE25EF5D96001F1DAB /* StatusProvider+UITableViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB59F0FD25EF5D96001F1DAB /* StatusProvider+UITableViewDelegate.swift */; };
|
||||||
|
@ -229,7 +235,7 @@
|
||||||
DB98339C25C96DE600AD9700 /* APIService+Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98339B25C96DE600AD9700 /* APIService+Account.swift */; };
|
DB98339C25C96DE600AD9700 /* APIService+Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98339B25C96DE600AD9700 /* APIService+Account.swift */; };
|
||||||
DB9A485C2603010E008B817C /* PHPickerResultLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9A485B2603010E008B817C /* PHPickerResultLoader.swift */; };
|
DB9A485C2603010E008B817C /* PHPickerResultLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9A485B2603010E008B817C /* PHPickerResultLoader.swift */; };
|
||||||
DB9A486C26032AC1008B817C /* AttachmentContainerView+EmptyStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9A486B26032AC1008B817C /* AttachmentContainerView+EmptyStateView.swift */; };
|
DB9A486C26032AC1008B817C /* AttachmentContainerView+EmptyStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9A486B26032AC1008B817C /* AttachmentContainerView+EmptyStateView.swift */; };
|
||||||
DB9A487E2603456B008B817C /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = DB9A487D2603456B008B817C /* SwiftPackageProductDependency */; };
|
DB9A487E2603456B008B817C /* UITextView+Placeholder in Frameworks */ = {isa = PBXBuildFile; productRef = DB9A487D2603456B008B817C /* UITextView+Placeholder */; };
|
||||||
DB9A488426034BD7008B817C /* APIService+Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9A488326034BD7008B817C /* APIService+Status.swift */; };
|
DB9A488426034BD7008B817C /* APIService+Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9A488326034BD7008B817C /* APIService+Status.swift */; };
|
||||||
DB9A488A26034D40008B817C /* ComposeViewModel+PublishState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9A488926034D40008B817C /* ComposeViewModel+PublishState.swift */; };
|
DB9A488A26034D40008B817C /* ComposeViewModel+PublishState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9A488926034D40008B817C /* ComposeViewModel+PublishState.swift */; };
|
||||||
DB9A489026035963008B817C /* APIService+Media.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9A488F26035963008B817C /* APIService+Media.swift */; };
|
DB9A489026035963008B817C /* APIService+Media.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9A488F26035963008B817C /* APIService+Media.swift */; };
|
||||||
|
@ -252,8 +258,8 @@
|
||||||
DBD9149025DF6D8D00903DFD /* APIService+Onboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBD9148F25DF6D8D00903DFD /* APIService+Onboarding.swift */; };
|
DBD9149025DF6D8D00903DFD /* APIService+Onboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBD9148F25DF6D8D00903DFD /* APIService+Onboarding.swift */; };
|
||||||
DBE0821525CD382600FD6BBD /* MastodonRegisterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE0821425CD382600FD6BBD /* MastodonRegisterViewController.swift */; };
|
DBE0821525CD382600FD6BBD /* MastodonRegisterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE0821425CD382600FD6BBD /* MastodonRegisterViewController.swift */; };
|
||||||
DBE0822425CD3F1E00FD6BBD /* MastodonRegisterViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE0822325CD3F1E00FD6BBD /* MastodonRegisterViewModel.swift */; };
|
DBE0822425CD3F1E00FD6BBD /* MastodonRegisterViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE0822325CD3F1E00FD6BBD /* MastodonRegisterViewModel.swift */; };
|
||||||
DBE64A8B260C49D200E6359A /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = DBE64A8A260C49D200E6359A /* SwiftPackageProductDependency */; };
|
DBE64A8B260C49D200E6359A /* TwitterTextEditor in Frameworks */ = {isa = PBXBuildFile; productRef = DBE64A8A260C49D200E6359A /* TwitterTextEditor */; };
|
||||||
DBE64A8C260C49D200E6359A /* BuildFile in Embed Frameworks */ = {isa = PBXBuildFile; productRef = DBE64A8A260C49D200E6359A /* SwiftPackageProductDependency */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
DBE64A8C260C49D200E6359A /* TwitterTextEditor in Embed Frameworks */ = {isa = PBXBuildFile; productRef = DBE64A8A260C49D200E6359A /* TwitterTextEditor */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
@ -301,7 +307,7 @@
|
||||||
dstPath = "";
|
dstPath = "";
|
||||||
dstSubfolderSpec = 10;
|
dstSubfolderSpec = 10;
|
||||||
files = (
|
files = (
|
||||||
DBE64A8C260C49D200E6359A /* BuildFile in Embed Frameworks */,
|
DBE64A8C260C49D200E6359A /* TwitterTextEditor in Embed Frameworks */,
|
||||||
DB89BA0425C10FD0008580ED /* CoreDataStack.framework in Embed Frameworks */,
|
DB89BA0425C10FD0008580ED /* CoreDataStack.framework in Embed Frameworks */,
|
||||||
);
|
);
|
||||||
name = "Embed Frameworks";
|
name = "Embed Frameworks";
|
||||||
|
@ -332,6 +338,10 @@
|
||||||
2D32EAAB25CB96DC00C9ED86 /* TimelineMiddleLoaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineMiddleLoaderTableViewCell.swift; sourceTree = "<group>"; };
|
2D32EAAB25CB96DC00C9ED86 /* TimelineMiddleLoaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineMiddleLoaderTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
2D32EAB925CB9B0500C9ED86 /* UIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIView.swift; sourceTree = "<group>"; };
|
2D32EAB925CB9B0500C9ED86 /* UIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIView.swift; sourceTree = "<group>"; };
|
||||||
2D32EAD925CBCC3300C9ED86 /* PublicTimelineViewModel+LoadMiddleState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PublicTimelineViewModel+LoadMiddleState.swift"; sourceTree = "<group>"; };
|
2D32EAD925CBCC3300C9ED86 /* PublicTimelineViewModel+LoadMiddleState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PublicTimelineViewModel+LoadMiddleState.swift"; sourceTree = "<group>"; };
|
||||||
|
2D34D9CA261489930081BFC0 /* SearchViewController+recomendView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchViewController+recomendView.swift"; sourceTree = "<group>"; };
|
||||||
|
2D34D9D026148D9E0081BFC0 /* APIService+Recommend.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Recommend.swift"; sourceTree = "<group>"; };
|
||||||
|
2D34D9DA261494120081BFC0 /* APIService+Search.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Search.swift"; sourceTree = "<group>"; };
|
||||||
|
2D34D9E126149C920081BFC0 /* SearchRecommendTagsCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchRecommendTagsCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||||
2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewController.swift; sourceTree = "<group>"; };
|
2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewController.swift; sourceTree = "<group>"; };
|
||||||
2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewModel.swift; sourceTree = "<group>"; };
|
2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewModel.swift; sourceTree = "<group>"; };
|
||||||
2D38F1C525CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentOffsetAdjustableTimelineViewControllerDelegate.swift; sourceTree = "<group>"; };
|
2D38F1C525CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentOffsetAdjustableTimelineViewControllerDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
@ -363,6 +373,7 @@
|
||||||
2D694A7325F9EB4E0038ADDC /* ContentWarningOverlayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentWarningOverlayView.swift; sourceTree = "<group>"; };
|
2D694A7325F9EB4E0038ADDC /* ContentWarningOverlayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentWarningOverlayView.swift; sourceTree = "<group>"; };
|
||||||
2D69CFF325CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadMoreConfigurableTableViewContainer.swift; sourceTree = "<group>"; };
|
2D69CFF325CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadMoreConfigurableTableViewContainer.swift; sourceTree = "<group>"; };
|
||||||
2D69D00925CAA00300C3A1B2 /* APIService+CoreData+Status.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "APIService+CoreData+Status.swift"; sourceTree = "<group>"; };
|
2D69D00925CAA00300C3A1B2 /* APIService+CoreData+Status.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "APIService+CoreData+Status.swift"; sourceTree = "<group>"; };
|
||||||
|
2D6DE3FF26141DF600A63F6A /* SearchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchViewModel.swift; sourceTree = "<group>"; };
|
||||||
2D76316425C14BD100929FB9 /* PublicTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicTimelineViewController.swift; sourceTree = "<group>"; };
|
2D76316425C14BD100929FB9 /* PublicTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicTimelineViewController.swift; sourceTree = "<group>"; };
|
||||||
2D76316A25C14D4C00929FB9 /* PublicTimelineViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicTimelineViewModel.swift; sourceTree = "<group>"; };
|
2D76316A25C14D4C00929FB9 /* PublicTimelineViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicTimelineViewModel.swift; sourceTree = "<group>"; };
|
||||||
2D76317C25C14DF400929FB9 /* PublicTimelineViewController+StatusProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PublicTimelineViewController+StatusProvider.swift"; sourceTree = "<group>"; };
|
2D76317C25C14DF400929FB9 /* PublicTimelineViewController+StatusProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PublicTimelineViewController+StatusProvider.swift"; sourceTree = "<group>"; };
|
||||||
|
@ -394,6 +405,7 @@
|
||||||
2DF75BA625D10E1000694EC8 /* APIService+Favorite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Favorite.swift"; sourceTree = "<group>"; };
|
2DF75BA625D10E1000694EC8 /* APIService+Favorite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Favorite.swift"; sourceTree = "<group>"; };
|
||||||
2DF75BB825D1474100694EC8 /* ManagedObjectObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedObjectObserver.swift; sourceTree = "<group>"; };
|
2DF75BB825D1474100694EC8 /* ManagedObjectObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedObjectObserver.swift; sourceTree = "<group>"; };
|
||||||
2DF75BC625D1475D00694EC8 /* ManagedObjectContextObjectsDidChange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedObjectContextObjectsDidChange.swift; sourceTree = "<group>"; };
|
2DF75BC625D1475D00694EC8 /* ManagedObjectContextObjectsDidChange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedObjectContextObjectsDidChange.swift; sourceTree = "<group>"; };
|
||||||
|
2DFF41882614A4DC00F776A4 /* UIView+Constraint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Constraint.swift"; sourceTree = "<group>"; };
|
||||||
2E1F6A67FDF9771D3E064FDC /* Pods-Mastodon.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.debug.xcconfig"; sourceTree = "<group>"; };
|
2E1F6A67FDF9771D3E064FDC /* Pods-Mastodon.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Mastodon_MastodonUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Mastodon_MastodonUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
452147B2903DF38070FE56A2 /* Pods_MastodonTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MastodonTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
452147B2903DF38070FE56A2 /* Pods_MastodonTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MastodonTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
@ -572,17 +584,17 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
DB0140BD25C40D7500F9F3CF /* BuildFile in Frameworks */,
|
DB0140BD25C40D7500F9F3CF /* CommonOSLog in Frameworks */,
|
||||||
DB89BA0325C10FD0008580ED /* CoreDataStack.framework in Frameworks */,
|
DB89BA0325C10FD0008580ED /* CoreDataStack.framework in Frameworks */,
|
||||||
2D42FF6125C8177C004A627A /* BuildFile in Frameworks */,
|
2D42FF6125C8177C004A627A /* ActiveLabel in Frameworks */,
|
||||||
DB9A487E2603456B008B817C /* BuildFile in Frameworks */,
|
DB9A487E2603456B008B817C /* UITextView+Placeholder in Frameworks */,
|
||||||
2D939AC825EE14620076FA61 /* BuildFile in Frameworks */,
|
2D939AC825EE14620076FA61 /* CropViewController in Frameworks */,
|
||||||
5D526FE225BE9AC400460CB9 /* BuildFile in Frameworks */,
|
5D526FE225BE9AC400460CB9 /* MastodonSDK in Frameworks */,
|
||||||
DB5086B825CC0D6400C2C187 /* BuildFile in Frameworks */,
|
DB5086B825CC0D6400C2C187 /* Kingfisher in Frameworks */,
|
||||||
2D61336925C18A4F00CAE157 /* BuildFile in Frameworks */,
|
2D61336925C18A4F00CAE157 /* AlamofireNetworkActivityIndicator in Frameworks */,
|
||||||
DB3D0FF325BAA61700EAA174 /* BuildFile in Frameworks */,
|
DB3D0FF325BAA61700EAA174 /* AlamofireImage in Frameworks */,
|
||||||
DBE64A8B260C49D200E6359A /* BuildFile in Frameworks */,
|
DBE64A8B260C49D200E6359A /* TwitterTextEditor in Frameworks */,
|
||||||
2D5981BA25E4D7F8000FB903 /* BuildFile in Frameworks */,
|
2D5981BA25E4D7F8000FB903 /* ThirdPartyMailer in Frameworks */,
|
||||||
87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */,
|
87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -698,6 +710,14 @@
|
||||||
path = Content;
|
path = Content;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
2D34D9E026149C550081BFC0 /* CollectionViewCell */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
2D34D9E126149C920081BFC0 /* SearchRecommendTagsCollectionViewCell.swift */,
|
||||||
|
);
|
||||||
|
path = CollectionViewCell;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
2D364F7025E66D5B00204FDC /* ResendEmail */ = {
|
2D364F7025E66D5B00204FDC /* ResendEmail */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -1097,6 +1117,8 @@
|
||||||
DB49A62A25FF36C700B98345 /* APIService+CustomEmoji.swift */,
|
DB49A62A25FF36C700B98345 /* APIService+CustomEmoji.swift */,
|
||||||
DB9A488326034BD7008B817C /* APIService+Status.swift */,
|
DB9A488326034BD7008B817C /* APIService+Status.swift */,
|
||||||
DB9A488F26035963008B817C /* APIService+Media.swift */,
|
DB9A488F26035963008B817C /* APIService+Media.swift */,
|
||||||
|
2D34D9D026148D9E0081BFC0 /* APIService+Recommend.swift */,
|
||||||
|
2D34D9DA261494120081BFC0 /* APIService+Search.swift */,
|
||||||
);
|
);
|
||||||
path = APIService;
|
path = APIService;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1342,6 +1364,7 @@
|
||||||
5DF1056325F887CB00D6C0D4 /* AVPlayer.swift */,
|
5DF1056325F887CB00D6C0D4 /* AVPlayer.swift */,
|
||||||
DB47229625F9EFAD00DA7F53 /* NSManagedObjectContext.swift */,
|
DB47229625F9EFAD00DA7F53 /* NSManagedObjectContext.swift */,
|
||||||
2D32EAB925CB9B0500C9ED86 /* UIView.swift */,
|
2D32EAB925CB9B0500C9ED86 /* UIView.swift */,
|
||||||
|
2DFF41882614A4DC00F776A4 /* UIView+Constraint.swift */,
|
||||||
DB8AF55C25C138B7002E6C99 /* UIViewController.swift */,
|
DB8AF55C25C138B7002E6C99 /* UIViewController.swift */,
|
||||||
2D3F9E0325DFA133004262D9 /* UITapGestureRecognizer.swift */,
|
2D3F9E0325DFA133004262D9 /* UITapGestureRecognizer.swift */,
|
||||||
2D84350425FF858100EECE90 /* UIScrollView.swift */,
|
2D84350425FF858100EECE90 /* UIScrollView.swift */,
|
||||||
|
@ -1382,6 +1405,9 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
DB9D6BE825E4F5340051B173 /* SearchViewController.swift */,
|
DB9D6BE825E4F5340051B173 /* SearchViewController.swift */,
|
||||||
|
2D34D9CA261489930081BFC0 /* SearchViewController+recomendView.swift */,
|
||||||
|
2D6DE3FF26141DF600A63F6A /* SearchViewModel.swift */,
|
||||||
|
2D34D9E026149C550081BFC0 /* CollectionViewCell */,
|
||||||
);
|
);
|
||||||
path = Search;
|
path = Search;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1492,16 +1518,16 @@
|
||||||
);
|
);
|
||||||
name = Mastodon;
|
name = Mastodon;
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
DB3D0FF225BAA61700EAA174 /* SwiftPackageProductDependency */,
|
DB3D0FF225BAA61700EAA174 /* AlamofireImage */,
|
||||||
5D526FE125BE9AC400460CB9 /* SwiftPackageProductDependency */,
|
5D526FE125BE9AC400460CB9 /* MastodonSDK */,
|
||||||
2D61336825C18A4F00CAE157 /* SwiftPackageProductDependency */,
|
2D61336825C18A4F00CAE157 /* AlamofireNetworkActivityIndicator */,
|
||||||
2D42FF6025C8177C004A627A /* SwiftPackageProductDependency */,
|
2D42FF6025C8177C004A627A /* ActiveLabel */,
|
||||||
DB0140BC25C40D7500F9F3CF /* SwiftPackageProductDependency */,
|
DB0140BC25C40D7500F9F3CF /* CommonOSLog */,
|
||||||
DB5086B725CC0D6400C2C187 /* SwiftPackageProductDependency */,
|
DB5086B725CC0D6400C2C187 /* Kingfisher */,
|
||||||
2D5981B925E4D7F8000FB903 /* SwiftPackageProductDependency */,
|
2D5981B925E4D7F8000FB903 /* ThirdPartyMailer */,
|
||||||
2D939AC725EE14620076FA61 /* SwiftPackageProductDependency */,
|
2D939AC725EE14620076FA61 /* CropViewController */,
|
||||||
DB9A487D2603456B008B817C /* SwiftPackageProductDependency */,
|
DB9A487D2603456B008B817C /* UITextView+Placeholder */,
|
||||||
DBE64A8A260C49D200E6359A /* SwiftPackageProductDependency */,
|
DBE64A8A260C49D200E6359A /* TwitterTextEditor */,
|
||||||
);
|
);
|
||||||
productName = Mastodon;
|
productName = Mastodon;
|
||||||
productReference = DB427DD225BAA00100D1B89D /* Mastodon.app */;
|
productReference = DB427DD225BAA00100D1B89D /* Mastodon.app */;
|
||||||
|
@ -1624,15 +1650,15 @@
|
||||||
);
|
);
|
||||||
mainGroup = DB427DC925BAA00100D1B89D;
|
mainGroup = DB427DC925BAA00100D1B89D;
|
||||||
packageReferences = (
|
packageReferences = (
|
||||||
DB3D0FF125BAA61700EAA174 /* RemoteSwiftPackageReference */,
|
DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */,
|
||||||
2D61336725C18A4F00CAE157 /* RemoteSwiftPackageReference */,
|
2D61336725C18A4F00CAE157 /* XCRemoteSwiftPackageReference "AlamofireNetworkActivityIndicator" */,
|
||||||
2D42FF5F25C8177C004A627A /* RemoteSwiftPackageReference */,
|
2D42FF5F25C8177C004A627A /* XCRemoteSwiftPackageReference "ActiveLabel" */,
|
||||||
DB0140BB25C40D7500F9F3CF /* RemoteSwiftPackageReference */,
|
DB0140BB25C40D7500F9F3CF /* XCRemoteSwiftPackageReference "CommonOSLog" */,
|
||||||
DB5086B625CC0D6400C2C187 /* RemoteSwiftPackageReference */,
|
DB5086B625CC0D6400C2C187 /* XCRemoteSwiftPackageReference "Kingfisher" */,
|
||||||
2D5981B825E4D7F8000FB903 /* RemoteSwiftPackageReference */,
|
2D5981B825E4D7F8000FB903 /* XCRemoteSwiftPackageReference "ThirdPartyMailer" */,
|
||||||
2D939AC625EE14620076FA61 /* RemoteSwiftPackageReference */,
|
2D939AC625EE14620076FA61 /* XCRemoteSwiftPackageReference "TOCropViewController" */,
|
||||||
DB9A487C2603456B008B817C /* RemoteSwiftPackageReference */,
|
DB9A487C2603456B008B817C /* XCRemoteSwiftPackageReference "UITextView-Placeholder" */,
|
||||||
DBE64A89260C49D200E6359A /* RemoteSwiftPackageReference */,
|
DBE64A89260C49D200E6359A /* XCRemoteSwiftPackageReference "TwitterTextEditor" */,
|
||||||
);
|
);
|
||||||
productRefGroup = DB427DD325BAA00100D1B89D /* Products */;
|
productRefGroup = DB427DD325BAA00100D1B89D /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
|
@ -1863,6 +1889,7 @@
|
||||||
DB59F0FE25EF5D96001F1DAB /* StatusProvider+UITableViewDelegate.swift in Sources */,
|
DB59F0FE25EF5D96001F1DAB /* StatusProvider+UITableViewDelegate.swift in Sources */,
|
||||||
DB68586425E619B700F0A850 /* NSKeyValueObservation.swift in Sources */,
|
DB68586425E619B700F0A850 /* NSKeyValueObservation.swift in Sources */,
|
||||||
2D61335825C188A000CAE157 /* APIService+Persist+Status.swift in Sources */,
|
2D61335825C188A000CAE157 /* APIService+Persist+Status.swift in Sources */,
|
||||||
|
2D34D9DB261494120081BFC0 /* APIService+Search.swift in Sources */,
|
||||||
DB45FAE325CA7181005A8AC7 /* MastodonUser.swift in Sources */,
|
DB45FAE325CA7181005A8AC7 /* MastodonUser.swift in Sources */,
|
||||||
DB2FF510260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift in Sources */,
|
DB2FF510260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift in Sources */,
|
||||||
DB0AC6FC25CD02E600D75117 /* APIService+Instance.swift in Sources */,
|
DB0AC6FC25CD02E600D75117 /* APIService+Instance.swift in Sources */,
|
||||||
|
@ -1923,6 +1950,7 @@
|
||||||
DBC7A672260C897100E57475 /* StatusContentWarningEditorView.swift in Sources */,
|
DBC7A672260C897100E57475 /* StatusContentWarningEditorView.swift in Sources */,
|
||||||
DB59F10E25EF724F001F1DAB /* APIService+Poll.swift in Sources */,
|
DB59F10E25EF724F001F1DAB /* APIService+Poll.swift in Sources */,
|
||||||
DB47229725F9EFAD00DA7F53 /* NSManagedObjectContext.swift in Sources */,
|
DB47229725F9EFAD00DA7F53 /* NSManagedObjectContext.swift in Sources */,
|
||||||
|
2D34D9D126148D9E0081BFC0 /* APIService+Recommend.swift in Sources */,
|
||||||
2D42FF7E25C82218004A627A /* ActionToolBarContainer.swift in Sources */,
|
2D42FF7E25C82218004A627A /* ActionToolBarContainer.swift in Sources */,
|
||||||
DB221B16260C395900AEFE46 /* CustomEmojiPickerInputViewModel.swift in Sources */,
|
DB221B16260C395900AEFE46 /* CustomEmojiPickerInputViewModel.swift in Sources */,
|
||||||
DB0140A125C40C0600F9F3CF /* MastodonPinBasedAuthenticationViewController.swift in Sources */,
|
DB0140A125C40C0600F9F3CF /* MastodonPinBasedAuthenticationViewController.swift in Sources */,
|
||||||
|
@ -1953,6 +1981,7 @@
|
||||||
DB49A63D25FF609300B98345 /* PlayerContainerView+MediaTypeIndicotorView.swift in Sources */,
|
DB49A63D25FF609300B98345 /* PlayerContainerView+MediaTypeIndicotorView.swift in Sources */,
|
||||||
DB0140CF25C42AEE00F9F3CF /* OSLog.swift in Sources */,
|
DB0140CF25C42AEE00F9F3CF /* OSLog.swift in Sources */,
|
||||||
DB44384F25E8C1FA008912A2 /* CALayer.swift in Sources */,
|
DB44384F25E8C1FA008912A2 /* CALayer.swift in Sources */,
|
||||||
|
2D34D9CB261489930081BFC0 /* SearchViewController+recomendView.swift in Sources */,
|
||||||
2D206B8625F5FB0900143C56 /* Double.swift in Sources */,
|
2D206B8625F5FB0900143C56 /* Double.swift in Sources */,
|
||||||
DB9A485C2603010E008B817C /* PHPickerResultLoader.swift in Sources */,
|
DB9A485C2603010E008B817C /* PHPickerResultLoader.swift in Sources */,
|
||||||
2D76319F25C1521200929FB9 /* StatusSection.swift in Sources */,
|
2D76319F25C1521200929FB9 /* StatusSection.swift in Sources */,
|
||||||
|
@ -1971,6 +2000,7 @@
|
||||||
DB98338725C945ED00AD9700 /* Strings.swift in Sources */,
|
DB98338725C945ED00AD9700 /* Strings.swift in Sources */,
|
||||||
DB45FAB625CA5485005A8AC7 /* UIAlertController.swift in Sources */,
|
DB45FAB625CA5485005A8AC7 /* UIAlertController.swift in Sources */,
|
||||||
DBE0821525CD382600FD6BBD /* MastodonRegisterViewController.swift in Sources */,
|
DBE0821525CD382600FD6BBD /* MastodonRegisterViewController.swift in Sources */,
|
||||||
|
2DFF41892614A4DC00F776A4 /* UIView+Constraint.swift in Sources */,
|
||||||
2D5A3D0325CF8742002347D6 /* ControlContainableScrollViews.swift in Sources */,
|
2D5A3D0325CF8742002347D6 /* ControlContainableScrollViews.swift in Sources */,
|
||||||
DB98336B25C9420100AD9700 /* APIService+App.swift in Sources */,
|
DB98336B25C9420100AD9700 /* APIService+App.swift in Sources */,
|
||||||
DBA0A11325FB3FC10079C110 /* ComposeToolbarView.swift in Sources */,
|
DBA0A11325FB3FC10079C110 /* ComposeToolbarView.swift in Sources */,
|
||||||
|
@ -1980,6 +2010,7 @@
|
||||||
DB447697260B439000B66B82 /* CustomEmojiPickerHeaderCollectionReusableView.swift in Sources */,
|
DB447697260B439000B66B82 /* CustomEmojiPickerHeaderCollectionReusableView.swift in Sources */,
|
||||||
DB45FAF925CA80A2005A8AC7 /* APIService+CoreData+MastodonAuthentication.swift in Sources */,
|
DB45FAF925CA80A2005A8AC7 /* APIService+CoreData+MastodonAuthentication.swift in Sources */,
|
||||||
2D04F42525C255B9003F936F /* APIService+PublicTimeline.swift in Sources */,
|
2D04F42525C255B9003F936F /* APIService+PublicTimeline.swift in Sources */,
|
||||||
|
2D34D9E226149C920081BFC0 /* SearchRecommendTagsCollectionViewCell.swift in Sources */,
|
||||||
2D76317D25C14DF500929FB9 /* PublicTimelineViewController+StatusProvider.swift in Sources */,
|
2D76317D25C14DF500929FB9 /* PublicTimelineViewController+StatusProvider.swift in Sources */,
|
||||||
2D206B8025F5F45E00143C56 /* UIImage.swift in Sources */,
|
2D206B8025F5F45E00143C56 /* UIImage.swift in Sources */,
|
||||||
2D5A3D2825CF8BC9002347D6 /* HomeTimelineViewModel+Diffable.swift in Sources */,
|
2D5A3D2825CF8BC9002347D6 /* HomeTimelineViewModel+Diffable.swift in Sources */,
|
||||||
|
@ -2011,6 +2042,7 @@
|
||||||
0FB3D31E25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift in Sources */,
|
0FB3D31E25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift in Sources */,
|
||||||
5DF1057925F88A1D00D6C0D4 /* PlayerContainerView.swift in Sources */,
|
5DF1057925F88A1D00D6C0D4 /* PlayerContainerView.swift in Sources */,
|
||||||
DB45FB0F25CA87D0005A8AC7 /* AuthenticationService.swift in Sources */,
|
DB45FB0F25CA87D0005A8AC7 /* AuthenticationService.swift in Sources */,
|
||||||
|
2D6DE40026141DF600A63F6A /* SearchViewModel.swift in Sources */,
|
||||||
DBCCC71E25F73297007E1AB6 /* APIService+Reblog.swift in Sources */,
|
DBCCC71E25F73297007E1AB6 /* APIService+Reblog.swift in Sources */,
|
||||||
DB789A2B25F9F7AB0071ACA0 /* ComposeRepliedToTootContentCollectionViewCell.swift in Sources */,
|
DB789A2B25F9F7AB0071ACA0 /* ComposeRepliedToTootContentCollectionViewCell.swift in Sources */,
|
||||||
);
|
);
|
||||||
|
@ -2543,7 +2575,7 @@
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCRemoteSwiftPackageReference section */
|
/* Begin XCRemoteSwiftPackageReference section */
|
||||||
2D42FF5F25C8177C004A627A /* RemoteSwiftPackageReference */ = {
|
2D42FF5F25C8177C004A627A /* XCRemoteSwiftPackageReference "ActiveLabel" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/TwidereProject/ActiveLabel.swift";
|
repositoryURL = "https://github.com/TwidereProject/ActiveLabel.swift";
|
||||||
requirement = {
|
requirement = {
|
||||||
|
@ -2551,7 +2583,7 @@
|
||||||
minimumVersion = 4.0.0;
|
minimumVersion = 4.0.0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
2D5981B825E4D7F8000FB903 /* RemoteSwiftPackageReference */ = {
|
2D5981B825E4D7F8000FB903 /* XCRemoteSwiftPackageReference "ThirdPartyMailer" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/vtourraine/ThirdPartyMailer.git";
|
repositoryURL = "https://github.com/vtourraine/ThirdPartyMailer.git";
|
||||||
requirement = {
|
requirement = {
|
||||||
|
@ -2559,7 +2591,7 @@
|
||||||
minimumVersion = 1.7.1;
|
minimumVersion = 1.7.1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
2D61336725C18A4F00CAE157 /* RemoteSwiftPackageReference */ = {
|
2D61336725C18A4F00CAE157 /* XCRemoteSwiftPackageReference "AlamofireNetworkActivityIndicator" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/Alamofire/AlamofireNetworkActivityIndicator";
|
repositoryURL = "https://github.com/Alamofire/AlamofireNetworkActivityIndicator";
|
||||||
requirement = {
|
requirement = {
|
||||||
|
@ -2567,7 +2599,7 @@
|
||||||
minimumVersion = 3.1.0;
|
minimumVersion = 3.1.0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
2D939AC625EE14620076FA61 /* RemoteSwiftPackageReference */ = {
|
2D939AC625EE14620076FA61 /* XCRemoteSwiftPackageReference "TOCropViewController" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/TimOliver/TOCropViewController.git";
|
repositoryURL = "https://github.com/TimOliver/TOCropViewController.git";
|
||||||
requirement = {
|
requirement = {
|
||||||
|
@ -2575,7 +2607,7 @@
|
||||||
minimumVersion = 2.6.0;
|
minimumVersion = 2.6.0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
DB0140BB25C40D7500F9F3CF /* RemoteSwiftPackageReference */ = {
|
DB0140BB25C40D7500F9F3CF /* XCRemoteSwiftPackageReference "CommonOSLog" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/MainasuK/CommonOSLog";
|
repositoryURL = "https://github.com/MainasuK/CommonOSLog";
|
||||||
requirement = {
|
requirement = {
|
||||||
|
@ -2583,7 +2615,7 @@
|
||||||
minimumVersion = 0.1.1;
|
minimumVersion = 0.1.1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
DB3D0FF125BAA61700EAA174 /* RemoteSwiftPackageReference */ = {
|
DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/Alamofire/AlamofireImage.git";
|
repositoryURL = "https://github.com/Alamofire/AlamofireImage.git";
|
||||||
requirement = {
|
requirement = {
|
||||||
|
@ -2591,7 +2623,7 @@
|
||||||
minimumVersion = 4.1.0;
|
minimumVersion = 4.1.0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
DB5086B625CC0D6400C2C187 /* RemoteSwiftPackageReference */ = {
|
DB5086B625CC0D6400C2C187 /* XCRemoteSwiftPackageReference "Kingfisher" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/onevcat/Kingfisher.git";
|
repositoryURL = "https://github.com/onevcat/Kingfisher.git";
|
||||||
requirement = {
|
requirement = {
|
||||||
|
@ -2599,7 +2631,7 @@
|
||||||
minimumVersion = 6.1.0;
|
minimumVersion = 6.1.0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
DB9A487C2603456B008B817C /* RemoteSwiftPackageReference */ = {
|
DB9A487C2603456B008B817C /* XCRemoteSwiftPackageReference "UITextView-Placeholder" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/MainasuK/UITextView-Placeholder";
|
repositoryURL = "https://github.com/MainasuK/UITextView-Placeholder";
|
||||||
requirement = {
|
requirement = {
|
||||||
|
@ -2607,7 +2639,7 @@
|
||||||
minimumVersion = 1.4.1;
|
minimumVersion = 1.4.1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
DBE64A89260C49D200E6359A /* RemoteSwiftPackageReference */ = {
|
DBE64A89260C49D200E6359A /* XCRemoteSwiftPackageReference "TwitterTextEditor" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/MainasuK/TwitterTextEditor";
|
repositoryURL = "https://github.com/MainasuK/TwitterTextEditor";
|
||||||
requirement = {
|
requirement = {
|
||||||
|
@ -2618,53 +2650,53 @@
|
||||||
/* End XCRemoteSwiftPackageReference section */
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
/* Begin XCSwiftPackageProductDependency section */
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
2D42FF6025C8177C004A627A /* SwiftPackageProductDependency */ = {
|
2D42FF6025C8177C004A627A /* ActiveLabel */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = 2D42FF5F25C8177C004A627A /* RemoteSwiftPackageReference */;
|
package = 2D42FF5F25C8177C004A627A /* XCRemoteSwiftPackageReference "ActiveLabel" */;
|
||||||
productName = ActiveLabel;
|
productName = ActiveLabel;
|
||||||
};
|
};
|
||||||
2D5981B925E4D7F8000FB903 /* SwiftPackageProductDependency */ = {
|
2D5981B925E4D7F8000FB903 /* ThirdPartyMailer */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = 2D5981B825E4D7F8000FB903 /* RemoteSwiftPackageReference */;
|
package = 2D5981B825E4D7F8000FB903 /* XCRemoteSwiftPackageReference "ThirdPartyMailer" */;
|
||||||
productName = ThirdPartyMailer;
|
productName = ThirdPartyMailer;
|
||||||
};
|
};
|
||||||
2D61336825C18A4F00CAE157 /* SwiftPackageProductDependency */ = {
|
2D61336825C18A4F00CAE157 /* AlamofireNetworkActivityIndicator */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = 2D61336725C18A4F00CAE157 /* RemoteSwiftPackageReference */;
|
package = 2D61336725C18A4F00CAE157 /* XCRemoteSwiftPackageReference "AlamofireNetworkActivityIndicator" */;
|
||||||
productName = AlamofireNetworkActivityIndicator;
|
productName = AlamofireNetworkActivityIndicator;
|
||||||
};
|
};
|
||||||
2D939AC725EE14620076FA61 /* SwiftPackageProductDependency */ = {
|
2D939AC725EE14620076FA61 /* CropViewController */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = 2D939AC625EE14620076FA61 /* RemoteSwiftPackageReference */;
|
package = 2D939AC625EE14620076FA61 /* XCRemoteSwiftPackageReference "TOCropViewController" */;
|
||||||
productName = CropViewController;
|
productName = CropViewController;
|
||||||
};
|
};
|
||||||
5D526FE125BE9AC400460CB9 /* SwiftPackageProductDependency */ = {
|
5D526FE125BE9AC400460CB9 /* MastodonSDK */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = MastodonSDK;
|
productName = MastodonSDK;
|
||||||
};
|
};
|
||||||
DB0140BC25C40D7500F9F3CF /* SwiftPackageProductDependency */ = {
|
DB0140BC25C40D7500F9F3CF /* CommonOSLog */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = DB0140BB25C40D7500F9F3CF /* RemoteSwiftPackageReference */;
|
package = DB0140BB25C40D7500F9F3CF /* XCRemoteSwiftPackageReference "CommonOSLog" */;
|
||||||
productName = CommonOSLog;
|
productName = CommonOSLog;
|
||||||
};
|
};
|
||||||
DB3D0FF225BAA61700EAA174 /* SwiftPackageProductDependency */ = {
|
DB3D0FF225BAA61700EAA174 /* AlamofireImage */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = DB3D0FF125BAA61700EAA174 /* RemoteSwiftPackageReference */;
|
package = DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */;
|
||||||
productName = AlamofireImage;
|
productName = AlamofireImage;
|
||||||
};
|
};
|
||||||
DB5086B725CC0D6400C2C187 /* SwiftPackageProductDependency */ = {
|
DB5086B725CC0D6400C2C187 /* Kingfisher */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = DB5086B625CC0D6400C2C187 /* RemoteSwiftPackageReference */;
|
package = DB5086B625CC0D6400C2C187 /* XCRemoteSwiftPackageReference "Kingfisher" */;
|
||||||
productName = Kingfisher;
|
productName = Kingfisher;
|
||||||
};
|
};
|
||||||
DB9A487D2603456B008B817C /* SwiftPackageProductDependency */ = {
|
DB9A487D2603456B008B817C /* UITextView+Placeholder */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = DB9A487C2603456B008B817C /* RemoteSwiftPackageReference */;
|
package = DB9A487C2603456B008B817C /* XCRemoteSwiftPackageReference "UITextView-Placeholder" */;
|
||||||
productName = "UITextView+Placeholder";
|
productName = "UITextView+Placeholder";
|
||||||
};
|
};
|
||||||
DBE64A8A260C49D200E6359A /* SwiftPackageProductDependency */ = {
|
DBE64A8A260C49D200E6359A /* TwitterTextEditor */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = DBE64A89260C49D200E6359A /* RemoteSwiftPackageReference */;
|
package = DBE64A89260C49D200E6359A /* XCRemoteSwiftPackageReference "TwitterTextEditor" */;
|
||||||
productName = TwitterTextEditor;
|
productName = TwitterTextEditor;
|
||||||
};
|
};
|
||||||
/* End XCSwiftPackageProductDependency section */
|
/* End XCSwiftPackageProductDependency section */
|
||||||
|
|
|
@ -0,0 +1,271 @@
|
||||||
|
//
|
||||||
|
// UIView+Constraint.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by sxiaojian on 2021/3/31.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
enum Dimension {
|
||||||
|
case width
|
||||||
|
case height
|
||||||
|
|
||||||
|
var layoutAttribute: NSLayoutConstraint.Attribute {
|
||||||
|
switch self {
|
||||||
|
case .width:
|
||||||
|
return .width
|
||||||
|
case .height:
|
||||||
|
return .height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UIView {
|
||||||
|
|
||||||
|
func constrain(toSuperviewEdges: UIEdgeInsets?) {
|
||||||
|
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return}
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
NSLayoutConstraint(item: self,
|
||||||
|
attribute: .leading,
|
||||||
|
relatedBy: .equal,
|
||||||
|
toItem: view,
|
||||||
|
attribute: .leading,
|
||||||
|
multiplier: 1.0,
|
||||||
|
constant: toSuperviewEdges?.left ?? 0.0),
|
||||||
|
NSLayoutConstraint(item: self,
|
||||||
|
attribute: .top,
|
||||||
|
relatedBy: .equal,
|
||||||
|
toItem: view,
|
||||||
|
attribute: .top,
|
||||||
|
multiplier: 1.0,
|
||||||
|
constant: toSuperviewEdges?.top ?? 0.0),
|
||||||
|
NSLayoutConstraint(item: self,
|
||||||
|
attribute: .trailing,
|
||||||
|
relatedBy: .equal,
|
||||||
|
toItem: view,
|
||||||
|
attribute: .trailing,
|
||||||
|
multiplier: 1.0,
|
||||||
|
constant: toSuperviewEdges?.right ?? 0.0),
|
||||||
|
NSLayoutConstraint(item: self,
|
||||||
|
attribute: .bottom,
|
||||||
|
relatedBy: .equal,
|
||||||
|
toItem: view,
|
||||||
|
attribute: .bottom,
|
||||||
|
multiplier: 1.0,
|
||||||
|
constant: toSuperviewEdges?.bottom ?? 0.0)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func constrain(_ constraints: [NSLayoutConstraint?]) {
|
||||||
|
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
NSLayoutConstraint.activate(constraints.compactMap { $0 })
|
||||||
|
}
|
||||||
|
|
||||||
|
func constraint(_ attribute: NSLayoutConstraint.Attribute, toView: UIView, constant: CGFloat?) -> NSLayoutConstraint? {
|
||||||
|
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return nil}
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return NSLayoutConstraint(item: self, attribute: attribute, relatedBy: .equal, toItem: toView, attribute: attribute, multiplier: 1.0, constant: constant ?? 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func constraint(_ attribute: NSLayoutConstraint.Attribute, toView: UIView) -> NSLayoutConstraint? {
|
||||||
|
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return nil}
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return NSLayoutConstraint(item: self, attribute: attribute, relatedBy: .equal, toItem: toView, attribute: attribute, multiplier: 1.0, constant: 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func constraint(_ dimension: Dimension, constant: CGFloat) -> NSLayoutConstraint? {
|
||||||
|
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return nil }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return NSLayoutConstraint(item: self,
|
||||||
|
attribute: dimension.layoutAttribute,
|
||||||
|
relatedBy: .equal,
|
||||||
|
toItem: nil,
|
||||||
|
attribute: .notAnAttribute,
|
||||||
|
multiplier: 1.0,
|
||||||
|
constant: constant)
|
||||||
|
}
|
||||||
|
|
||||||
|
func constraint(toBottom: UIView, constant: CGFloat) -> NSLayoutConstraint? {
|
||||||
|
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return nil }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: toBottom, attribute: .bottom, multiplier: 1.0, constant: constant)
|
||||||
|
}
|
||||||
|
|
||||||
|
func pinToBottom(to: UIView, height: CGFloat) {
|
||||||
|
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
constrain([
|
||||||
|
constraint(.width, toView: to),
|
||||||
|
constraint(toBottom: to, constant: 0.0),
|
||||||
|
constraint(.height, constant: height)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func constraint(toTop: UIView, constant: CGFloat) -> NSLayoutConstraint? {
|
||||||
|
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return nil }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: .equal, toItem: toTop, attribute: .top, multiplier: 1.0, constant: constant)
|
||||||
|
}
|
||||||
|
|
||||||
|
func constraint(toTrailing: UIView, constant: CGFloat) -> NSLayoutConstraint? {
|
||||||
|
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return nil }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return NSLayoutConstraint(item: self, attribute: .leading, relatedBy: .equal, toItem: toTrailing, attribute: .trailing, multiplier: 1.0, constant: constant)
|
||||||
|
}
|
||||||
|
|
||||||
|
func constraint(toLeading: UIView, constant: CGFloat) -> NSLayoutConstraint? {
|
||||||
|
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return nil }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return NSLayoutConstraint(item: self, attribute: .trailing, relatedBy: .equal, toItem: toLeading, attribute: .leading, multiplier: 1.0, constant: constant)
|
||||||
|
}
|
||||||
|
|
||||||
|
func constrainTopCorners(sidePadding: CGFloat, topPadding: CGFloat, topLayoutGuide: UILayoutSupport) {
|
||||||
|
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
constrain([
|
||||||
|
constraint(.leading, toView: view, constant: sidePadding),
|
||||||
|
NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: topLayoutGuide, attribute: .bottom, multiplier: 1.0, constant: topPadding),
|
||||||
|
constraint(.trailing, toView: view, constant: -sidePadding)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func constrainTopCorners(sidePadding: CGFloat, topPadding: CGFloat) {
|
||||||
|
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
constrain([
|
||||||
|
constraint(.leading, toView: view, constant: sidePadding),
|
||||||
|
constraint(.top, toView: view, constant: topPadding),
|
||||||
|
constraint(.trailing, toView: view, constant: -sidePadding)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func constrainTopCorners(height: CGFloat) {
|
||||||
|
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
constrain([
|
||||||
|
constraint(.leading, toView: view),
|
||||||
|
constraint(.top, toView: view),
|
||||||
|
constraint(.trailing, toView: view),
|
||||||
|
constraint(.height, constant: height)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func constrainBottomCorners(sidePadding: CGFloat, bottomPadding: CGFloat) {
|
||||||
|
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
constrain([
|
||||||
|
constraint(.leading, toView: view, constant: sidePadding),
|
||||||
|
constraint(.bottom, toView: view, constant: -bottomPadding),
|
||||||
|
constraint(.trailing, toView: view, constant: -sidePadding)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func constrainBottomCorners(height: CGFloat) {
|
||||||
|
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
constrain([
|
||||||
|
constraint(.leading, toView: view),
|
||||||
|
constraint(.bottom, toView: view),
|
||||||
|
constraint(.trailing, toView: view),
|
||||||
|
constraint(.height, constant: height)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func constrainLeadingCorners() {
|
||||||
|
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
constrain([
|
||||||
|
constraint(.top, toView: view),
|
||||||
|
constraint(.leading, toView: view),
|
||||||
|
constraint(.bottom, toView: view)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func constrainTrailingCorners() {
|
||||||
|
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
constrain([
|
||||||
|
constraint(.top, toView: view),
|
||||||
|
constraint(.trailing, toView: view),
|
||||||
|
constraint(.bottom, toView: view)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func constrainToCenter() {
|
||||||
|
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
constrain([
|
||||||
|
constraint(.centerX, toView: view),
|
||||||
|
constraint(.centerY, toView: view)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func pinTo(viewAbove: UIView, padding: CGFloat = 0.0, height: CGFloat? = nil) {
|
||||||
|
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
constrain([
|
||||||
|
constraint(.width, toView: viewAbove),
|
||||||
|
constraint(toBottom: viewAbove, constant: padding),
|
||||||
|
self.centerXAnchor.constraint(equalTo: viewAbove.centerXAnchor),
|
||||||
|
height != nil ? constraint(.height, constant: height!) : nil
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func pin(toSize: CGSize) {
|
||||||
|
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
constrain([
|
||||||
|
widthAnchor.constraint(equalToConstant: toSize.width),
|
||||||
|
heightAnchor.constraint(equalToConstant: toSize.height)])
|
||||||
|
}
|
||||||
|
|
||||||
|
func pinTopLeft(padding: CGFloat) {
|
||||||
|
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
constrain([
|
||||||
|
leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding),
|
||||||
|
topAnchor.constraint(equalTo: view.topAnchor, constant: padding)])
|
||||||
|
}
|
||||||
|
|
||||||
|
func pinTopRight(padding: CGFloat) {
|
||||||
|
guard let view = superview else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
constrain([
|
||||||
|
view.trailingAnchor.constraint(equalTo: trailingAnchor, constant: padding),
|
||||||
|
topAnchor.constraint(equalTo: view.topAnchor, constant: padding)])
|
||||||
|
}
|
||||||
|
|
||||||
|
func pinTopLeft(toView: UIView, topPadding: CGFloat) {
|
||||||
|
guard superview != nil else { assert(false, "Superview cannot be nil when adding contraints"); return }
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
constrain([
|
||||||
|
leadingAnchor.constraint(equalTo: toView.leadingAnchor),
|
||||||
|
topAnchor.constraint(equalTo: toView.bottomAnchor, constant: topPadding)])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cross-fades between two views by animating their alpha then setting one or the other hidden.
|
||||||
|
/// - parameters:
|
||||||
|
/// - lhs: left view
|
||||||
|
/// - rhs: right view
|
||||||
|
/// - toRight: fade to the right view if true, fade to the left view if false
|
||||||
|
/// - duration: animation duration
|
||||||
|
///
|
||||||
|
static func crossfade(_ lhs: UIView, _ rhs: UIView, toRight: Bool, duration: TimeInterval) {
|
||||||
|
lhs.alpha = toRight ? 1.0 : 0.0
|
||||||
|
rhs.alpha = toRight ? 0.0 : 1.0
|
||||||
|
lhs.isHidden = false
|
||||||
|
rhs.isHidden = false
|
||||||
|
|
||||||
|
UIView.animate(withDuration: duration, animations: {
|
||||||
|
lhs.alpha = toRight ? 0.0 : 1.0
|
||||||
|
rhs.alpha = toRight ? 1.0 : 0.0
|
||||||
|
}, completion: { _ in
|
||||||
|
lhs.isHidden = toRight
|
||||||
|
rhs.isHidden = !toRight
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -369,6 +369,14 @@ internal enum L10n {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
internal enum Search {
|
||||||
|
internal enum Searchbar {
|
||||||
|
/// Cancel
|
||||||
|
internal static let cancel = L10n.tr("Localizable", "Scene.Search.Searchbar.Cancel")
|
||||||
|
/// Search hashtags and users
|
||||||
|
internal static let placeholder = L10n.tr("Localizable", "Scene.Search.Searchbar.Placeholder")
|
||||||
|
}
|
||||||
|
}
|
||||||
internal enum ServerPicker {
|
internal enum ServerPicker {
|
||||||
/// Pick a Server,\nany server.
|
/// Pick a Server,\nany server.
|
||||||
internal static let title = L10n.tr("Localizable", "Scene.ServerPicker.Title")
|
internal static let title = L10n.tr("Localizable", "Scene.ServerPicker.Title")
|
||||||
|
|
|
@ -115,6 +115,8 @@ tap the link to confirm your account.";
|
||||||
"Scene.Register.Input.Username.DuplicatePrompt" = "This username is taken.";
|
"Scene.Register.Input.Username.DuplicatePrompt" = "This username is taken.";
|
||||||
"Scene.Register.Input.Username.Placeholder" = "username";
|
"Scene.Register.Input.Username.Placeholder" = "username";
|
||||||
"Scene.Register.Title" = "Tell us about you.";
|
"Scene.Register.Title" = "Tell us about you.";
|
||||||
|
"Scene.Search.Searchbar.Cancel" = "Cancel";
|
||||||
|
"Scene.Search.Searchbar.Placeholder" = "Search hashtags and users";
|
||||||
"Scene.ServerPicker.Button.Category.All" = "All";
|
"Scene.ServerPicker.Button.Category.All" = "All";
|
||||||
"Scene.ServerPicker.Button.SeeLess" = "See Less";
|
"Scene.ServerPicker.Button.SeeLess" = "See Less";
|
||||||
"Scene.ServerPicker.Button.SeeMore" = "See More";
|
"Scene.ServerPicker.Button.SeeMore" = "See More";
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
//
|
||||||
|
// SearchRecommendTagsCollectionViewCell.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by sxiaojian on 2021/3/31.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SearchRecommendTagsCollectionViewCell: UICollectionViewCell {
|
||||||
|
let backgroundImageView: UIImageView = {
|
||||||
|
let imageView = UIImageView()
|
||||||
|
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
let hashTagTitleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.textColor = .white
|
||||||
|
label.font = .preferredFont(forTextStyle: .caption1)
|
||||||
|
label.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
let peopleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.textColor = .white
|
||||||
|
label.font = .preferredFont(forTextStyle: .body)
|
||||||
|
label.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
let flameIconView: UIImageView = {
|
||||||
|
let imageView = UIImageView()
|
||||||
|
let image = UIImage(systemName: "flame.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .semibold))!.withRenderingMode(.alwaysTemplate)
|
||||||
|
imageView.image = image
|
||||||
|
imageView.tintColor = .white
|
||||||
|
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
override func prepareForReuse() {
|
||||||
|
super.prepareForReuse()
|
||||||
|
}
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: .zero)
|
||||||
|
configure()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
super.init(coder: coder)
|
||||||
|
configure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SearchRecommendTagsCollectionViewCell {
|
||||||
|
private func configure() {
|
||||||
|
contentView.addSubview(backgroundImageView)
|
||||||
|
backgroundImageView.constrain(toSuperviewEdges: nil)
|
||||||
|
|
||||||
|
contentView.addSubview(hashTagTitleLabel)
|
||||||
|
hashTagTitleLabel.pinTopLeft(padding: 16)
|
||||||
|
|
||||||
|
contentView.addSubview(peopleLabel)
|
||||||
|
peopleLabel.constrain([
|
||||||
|
peopleLabel.constraint(toTop: contentView, constant: 46),
|
||||||
|
peopleLabel.constraint(toLeading: contentView, constant: 16)
|
||||||
|
])
|
||||||
|
|
||||||
|
contentView.addSubview(flameIconView)
|
||||||
|
flameIconView.pinTopRight(padding: 16)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
//
|
||||||
|
// SearchViewController+recommendView.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by sxiaojian on 2021/3/31.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
|
||||||
|
extension SearchViewController {
|
||||||
|
func setuprecommendView() {
|
||||||
|
recommendView.register(SearchRecommendTagsCollectionViewCell.self, forCellWithReuseIdentifier: String(describing: SearchRecommendTagsCollectionViewCell.self))
|
||||||
|
recommendView.dataSource = self
|
||||||
|
recommendView.delegate = self
|
||||||
|
}
|
||||||
|
override func viewDidLayoutSubviews() {
|
||||||
|
super.viewDidLayoutSubviews()
|
||||||
|
recommendView.collectionViewLayout.invalidateLayout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SearchViewController: UICollectionViewDelegate {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SearchViewController: UICollectionViewDataSource {
|
||||||
|
func numberOfSections(in collectionView: UICollectionView) -> Int {
|
||||||
|
return (self.viewModel.recommendAccounts.isEmpty ? 0 : 1) + (self.viewModel.recommendHashTags.isEmpty ? 0 : 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
|
switch section {
|
||||||
|
case 0:
|
||||||
|
return viewModel.recommendHashTags.count
|
||||||
|
case 1:
|
||||||
|
return viewModel.recommendAccounts.count
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
|
return UICollectionViewCell()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -2,23 +2,80 @@
|
||||||
// SearchViewController.swift
|
// SearchViewController.swift
|
||||||
// Mastodon
|
// Mastodon
|
||||||
//
|
//
|
||||||
// Created by MainasuK Cirno on 2021-2-23.
|
// Created by sxiaojian on 2021/3/31.
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import Combine
|
||||||
|
|
||||||
final class SearchViewController: UIViewController, NeedsDependency {
|
final class SearchViewController: UIViewController, NeedsDependency {
|
||||||
|
|
||||||
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
|
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
|
||||||
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
|
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
|
||||||
|
|
||||||
|
var disposeBag = Set<AnyCancellable>()
|
||||||
|
private(set) lazy var viewModel = SearchViewModel(context: context)
|
||||||
|
|
||||||
|
let searchBar: UISearchBar = {
|
||||||
|
let searchBar = UISearchBar()
|
||||||
|
searchBar.placeholder = L10n.Scene.Search.Searchbar.placeholder
|
||||||
|
searchBar.tintColor = Asset.Colors.buttonDefault.color
|
||||||
|
searchBar.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
let micImage = UIImage(systemName: "mic.fill")
|
||||||
|
searchBar.setImage(micImage, for: .bookmark, state: .normal)
|
||||||
|
searchBar.showsBookmarkButton = true
|
||||||
|
return searchBar
|
||||||
|
}()
|
||||||
|
|
||||||
|
let recommendView: UICollectionView = {
|
||||||
|
let flowLayout = UICollectionViewFlowLayout()
|
||||||
|
flowLayout.scrollDirection = .horizontal
|
||||||
|
let view = ControlContainableCollectionView(frame: .zero, collectionViewLayout: flowLayout)
|
||||||
|
view.backgroundColor = .clear
|
||||||
|
view.showsHorizontalScrollIndicator = false
|
||||||
|
view.showsVerticalScrollIndicator = false
|
||||||
|
view.layer.masksToBounds = false
|
||||||
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return view
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SearchViewController {
|
extension SearchViewController {
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
searchBar.delegate = self
|
||||||
|
navigationItem.titleView = searchBar
|
||||||
|
navigationItem.hidesBackButton = true
|
||||||
|
viewModel.requestRecommendData()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension SearchViewController: UISearchBarDelegate {
|
||||||
|
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
|
||||||
|
searchBar.setShowsCancelButton(true, animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
|
||||||
|
searchBar.setShowsCancelButton(false, animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
|
||||||
|
searchBar.setShowsCancelButton(false, animated: true)
|
||||||
|
searchBar.text = ""
|
||||||
|
searchBar.resignFirstResponder()
|
||||||
|
}
|
||||||
|
|
||||||
|
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
|
||||||
|
viewModel.searchText.send(searchText)
|
||||||
|
}
|
||||||
|
|
||||||
|
func searchBarBookmarkButtonClicked(_ searchBar: UISearchBar) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SearchViewController {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
//
|
||||||
|
// SearchViewModel.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by sxiaojian on 2021/3/31.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Combine
|
||||||
|
import MastodonSDK
|
||||||
|
import UIKit
|
||||||
|
import OSLog
|
||||||
|
|
||||||
|
final class SearchViewModel {
|
||||||
|
|
||||||
|
var disposeBag = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
// input
|
||||||
|
let context: AppContext
|
||||||
|
|
||||||
|
// output
|
||||||
|
let searchText = CurrentValueSubject<String, Never>("")
|
||||||
|
|
||||||
|
var recommendHashTags = [Mastodon.Entity.Tag]()
|
||||||
|
var recommendAccounts = [Mastodon.Entity.Account]()
|
||||||
|
|
||||||
|
init(context: AppContext) {
|
||||||
|
self.context = context
|
||||||
|
}
|
||||||
|
|
||||||
|
func requestRecommendData() {
|
||||||
|
guard let activeMastodonAuthenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let trendsAPI = context.apiService.recommendTrends(domain: activeMastodonAuthenticationBox.domain, query: Mastodon.API.Trends.Query(limit: 5))
|
||||||
|
|
||||||
|
let accountsAPI = context.apiService.recommendAccount(domain: activeMastodonAuthenticationBox.domain, query: nil, mastodonAuthenticationBox: activeMastodonAuthenticationBox)
|
||||||
|
Publishers.Zip(trendsAPI,accountsAPI)
|
||||||
|
.sink { completion in
|
||||||
|
switch completion {
|
||||||
|
case .failure(let error):
|
||||||
|
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: zip request fail: %s", ((#file as NSString).lastPathComponent), #line, #function, error.localizedDescription)
|
||||||
|
case .finished:
|
||||||
|
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: zip request success", ((#file as NSString).lastPathComponent), #line, #function)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} receiveValue: { [weak self] (tags, accounts) in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.recommendAccounts = accounts.value
|
||||||
|
self.recommendHashTags = tags.value
|
||||||
|
}
|
||||||
|
.store(in: &disposeBag)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
//
|
||||||
|
// APIService+Recommend.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by sxiaojian on 2021/3/31.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import MastodonSDK
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
extension APIService {
|
||||||
|
|
||||||
|
func recommendAccount(
|
||||||
|
domain: String,
|
||||||
|
query: Mastodon.API.Suggestions.Query?,
|
||||||
|
mastodonAuthenticationBox: AuthenticationService.MastodonAuthenticationBox
|
||||||
|
) -> AnyPublisher<Mastodon.Response.Content<[Mastodon.Entity.Account]>, Error> {
|
||||||
|
let authorization = mastodonAuthenticationBox.userAuthorization
|
||||||
|
|
||||||
|
return Mastodon.API.Suggestions.get(session: session, domain: domain, query: query, authorization: authorization)
|
||||||
|
}
|
||||||
|
|
||||||
|
func recommendTrends(
|
||||||
|
domain: String,
|
||||||
|
query: Mastodon.API.Trends.Query?
|
||||||
|
) -> AnyPublisher<Mastodon.Response.Content<[Mastodon.Entity.Tag]>, Error> {
|
||||||
|
return Mastodon.API.Trends.get(session: session, domain: domain, query: query)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// APIService+Search.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by sxiaojian on 2021/3/31.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import MastodonSDK
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
extension APIService {
|
||||||
|
|
||||||
|
func search(
|
||||||
|
domain: String,
|
||||||
|
query: Mastodon.API.Search.Query,
|
||||||
|
mastodonAuthenticationBox: AuthenticationService.MastodonAuthenticationBox
|
||||||
|
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.SearchResult>, Error> {
|
||||||
|
let authorization = mastodonAuthenticationBox.userAuthorization
|
||||||
|
|
||||||
|
return Mastodon.API.Search.search(session: session, domain: domain, query: query, authorization: authorization)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
//
|
||||||
|
// Mastodon+API+Search.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by sxiaojian on 2021/3/31.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension Mastodon.API.Search {
|
||||||
|
static func searchURL(domain: String) -> URL {
|
||||||
|
Mastodon.API.endpointV2URL(domain: domain).appendingPathComponent("search")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Search results
|
||||||
|
///
|
||||||
|
/// Search for content in accounts, statuses and hashtags.
|
||||||
|
///
|
||||||
|
/// Version history:
|
||||||
|
/// 2.4.1 - added, limit hardcoded to 5
|
||||||
|
/// 2.8.0 - add type, limit, offset, min_id, max_id, account_id
|
||||||
|
/// 3.0.0 - add exclude_unreviewed param
|
||||||
|
/// # Reference
|
||||||
|
/// [Document](https://docs.joinmastodon.org/methods/search/)
|
||||||
|
/// - Parameters:
|
||||||
|
/// - session: `URLSession`
|
||||||
|
/// - domain: Mastodon instance domain. e.g. "example.com"
|
||||||
|
/// - query: search query
|
||||||
|
/// - authorization: User token
|
||||||
|
/// - Returns: `AnyPublisher` contains `Accounts,Hashtags,Status` nested in the response
|
||||||
|
public static func search(
|
||||||
|
session: URLSession,
|
||||||
|
domain: String,
|
||||||
|
query: Mastodon.API.Search.Query,
|
||||||
|
authorization: Mastodon.API.OAuth.Authorization
|
||||||
|
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.SearchResult>, Error> {
|
||||||
|
let request = Mastodon.API.get(
|
||||||
|
url: searchURL(domain: domain),
|
||||||
|
query: query,
|
||||||
|
authorization: authorization
|
||||||
|
)
|
||||||
|
return session.dataTaskPublisher(for: request)
|
||||||
|
.tryMap { data, response in
|
||||||
|
let value = try Mastodon.API.decode(type: Mastodon.Entity.SearchResult.self, from: data, response: response)
|
||||||
|
return Mastodon.Response.Content(value: value, response: response)
|
||||||
|
}
|
||||||
|
.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Mastodon.API.Search {
|
||||||
|
public struct Query: Codable, GetQuery {
|
||||||
|
public init(accountID: Mastodon.Entity.Account.ID?, maxID: Mastodon.Entity.Status.ID?, minID: Mastodon.Entity.Status.ID?, type: String?, excludeUnreviewed: Bool?, q: String, resolve: Bool?, limit: Int?, offset: Int?, following: Bool?) {
|
||||||
|
self.accountID = accountID
|
||||||
|
self.maxID = maxID
|
||||||
|
self.minID = minID
|
||||||
|
self.type = type
|
||||||
|
self.excludeUnreviewed = excludeUnreviewed
|
||||||
|
self.q = q
|
||||||
|
self.resolve = resolve
|
||||||
|
self.limit = limit
|
||||||
|
self.offset = offset
|
||||||
|
self.following = following
|
||||||
|
}
|
||||||
|
|
||||||
|
public let accountID: Mastodon.Entity.Account.ID?
|
||||||
|
public let maxID: Mastodon.Entity.Status.ID?
|
||||||
|
public let minID: Mastodon.Entity.Status.ID?
|
||||||
|
public let type: String?
|
||||||
|
public let excludeUnreviewed: Bool? // Filter out unreviewed tags? Defaults to false. Use true when trying to find trending tags.
|
||||||
|
public let q: String
|
||||||
|
public let resolve: Bool? // Attempt WebFinger lookup. Defaults to false.
|
||||||
|
public let limit: Int? // Maximum number of results to load, per type. Defaults to 20. Max 40.
|
||||||
|
public let offset: Int? // Offset in search results. Used for pagination. Defaults to 0.
|
||||||
|
public let following: Bool? // Only include accounts that the user is following. Defaults to false.
|
||||||
|
|
||||||
|
var queryItems: [URLQueryItem]? {
|
||||||
|
var items: [URLQueryItem] = []
|
||||||
|
accountID.flatMap { items.append(URLQueryItem(name: "account_id", value: $0)) }
|
||||||
|
maxID.flatMap { items.append(URLQueryItem(name: "max_id", value: $0)) }
|
||||||
|
minID.flatMap { items.append(URLQueryItem(name: "min_id", value: $0)) }
|
||||||
|
type.flatMap { items.append(URLQueryItem(name: "type", value: $0)) }
|
||||||
|
excludeUnreviewed.flatMap { items.append(URLQueryItem(name: "exclude_unreviewed", value: $0.queryItemValue)) }
|
||||||
|
items.append(URLQueryItem(name: "q", value: q))
|
||||||
|
resolve.flatMap { items.append(URLQueryItem(name: "resolve", value: $0.queryItemValue)) }
|
||||||
|
|
||||||
|
limit.flatMap { items.append(URLQueryItem(name: "limit", value: String($0))) }
|
||||||
|
offset.flatMap { items.append(URLQueryItem(name: "offset", value: String($0))) }
|
||||||
|
following.flatMap { items.append(URLQueryItem(name: "following", value: $0.queryItemValue)) }
|
||||||
|
guard !items.isEmpty else { return nil }
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
//
|
||||||
|
// Mastodon+API+Suggestions.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by sxiaojian on 2021/3/31.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension Mastodon.API.Suggestions {
|
||||||
|
static func suggestionsURL(domain: String) -> URL {
|
||||||
|
Mastodon.API.endpointURL(domain: domain).appendingPathComponent("suggestions")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Follow suggestions
|
||||||
|
///
|
||||||
|
/// Server-generated suggestions on who to follow, based on previous positive interactions.
|
||||||
|
///
|
||||||
|
/// Version history:
|
||||||
|
/// 2.4.3 - added
|
||||||
|
/// # Reference
|
||||||
|
/// [Document](https://docs.joinmastodon.org/methods/accounts/suggestions/)
|
||||||
|
/// - Parameters:
|
||||||
|
/// - session: `URLSession`
|
||||||
|
/// - domain: Mastodon instance domain. e.g. "example.com"
|
||||||
|
/// - query: query
|
||||||
|
/// - authorization: User token.
|
||||||
|
/// - Returns: `AnyPublisher` contains `Accounts` nested in the response
|
||||||
|
public static func get(
|
||||||
|
session: URLSession,
|
||||||
|
domain: String,
|
||||||
|
query: Mastodon.API.Suggestions.Query?,
|
||||||
|
authorization: Mastodon.API.OAuth.Authorization
|
||||||
|
) -> AnyPublisher<Mastodon.Response.Content<[Mastodon.Entity.Account]>, Error> {
|
||||||
|
let request = Mastodon.API.get(
|
||||||
|
url: suggestionsURL(domain: domain),
|
||||||
|
query: query,
|
||||||
|
authorization: authorization
|
||||||
|
)
|
||||||
|
return session.dataTaskPublisher(for: request)
|
||||||
|
.tryMap { data, response in
|
||||||
|
let value = try Mastodon.API.decode(type: [Mastodon.Entity.Account].self, from: data, response: response)
|
||||||
|
return Mastodon.Response.Content(value: value, response: response)
|
||||||
|
}
|
||||||
|
.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Mastodon.API.Suggestions {
|
||||||
|
public struct Query: Codable, GetQuery {
|
||||||
|
public init(limit: Int?) {
|
||||||
|
self.limit = limit
|
||||||
|
}
|
||||||
|
|
||||||
|
public let limit: Int? // Maximum number of results to return. Defaults to 40.
|
||||||
|
|
||||||
|
var queryItems: [URLQueryItem]? {
|
||||||
|
var items: [URLQueryItem] = []
|
||||||
|
limit.flatMap { items.append(URLQueryItem(name: "limit", value: String($0))) }
|
||||||
|
guard !items.isEmpty else { return nil }
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
//
|
||||||
|
// Mastodon+API+Trends.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by sxiaojian on 2021/3/31.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension Mastodon.API.Trends {
|
||||||
|
static func trendsURL(domain: String) -> URL {
|
||||||
|
Mastodon.API.endpointURL(domain: domain).appendingPathComponent("trends")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Trending tags
|
||||||
|
///
|
||||||
|
/// Tags that are being used more frequently within the past week.
|
||||||
|
///
|
||||||
|
/// Version history:
|
||||||
|
/// 3.0.0 - added
|
||||||
|
/// # Reference
|
||||||
|
/// [Document](https://docs.joinmastodon.org/methods/instance/trends/)
|
||||||
|
/// - Parameters:
|
||||||
|
/// - session: `URLSession`
|
||||||
|
/// - domain: Mastodon instance domain. e.g. "example.com"
|
||||||
|
/// - query: query
|
||||||
|
/// - Returns: `AnyPublisher` contains `Hashtags` nested in the response
|
||||||
|
|
||||||
|
public static func get(
|
||||||
|
session: URLSession,
|
||||||
|
domain: String,
|
||||||
|
query: Mastodon.API.Trends.Query?
|
||||||
|
) -> AnyPublisher<Mastodon.Response.Content<[Mastodon.Entity.Tag]>, Error> {
|
||||||
|
let request = Mastodon.API.get(
|
||||||
|
url: trendsURL(domain: domain),
|
||||||
|
query: query,
|
||||||
|
authorization: nil
|
||||||
|
)
|
||||||
|
return session.dataTaskPublisher(for: request)
|
||||||
|
.tryMap { data, response in
|
||||||
|
let value = try Mastodon.API.decode(type: [Mastodon.Entity.Tag].self, from: data, response: response)
|
||||||
|
return Mastodon.Response.Content(value: value, response: response)
|
||||||
|
}
|
||||||
|
.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Mastodon.API.Trends {
|
||||||
|
public struct Query: Codable, GetQuery {
|
||||||
|
public init(limit: Int?) {
|
||||||
|
self.limit = limit
|
||||||
|
}
|
||||||
|
|
||||||
|
public let limit: Int? // Maximum number of results to return. Defaults to 10.
|
||||||
|
|
||||||
|
var queryItems: [URLQueryItem]? {
|
||||||
|
var items: [URLQueryItem] = []
|
||||||
|
limit.flatMap { items.append(URLQueryItem(name: "limit", value: String($0))) }
|
||||||
|
guard !items.isEmpty else { return nil }
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,6 +50,9 @@ extension Mastodon.API {
|
||||||
if let date = fullDatePreciseISO8601Formatter.date(from: string) {
|
if let date = fullDatePreciseISO8601Formatter.date(from: string) {
|
||||||
return date
|
return date
|
||||||
}
|
}
|
||||||
|
if let timestamp = TimeInterval(string) {
|
||||||
|
return Date(timeIntervalSince1970: timestamp)
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -101,6 +104,9 @@ extension Mastodon.API {
|
||||||
public enum Reblog { }
|
public enum Reblog { }
|
||||||
public enum Statuses { }
|
public enum Statuses { }
|
||||||
public enum Timeline { }
|
public enum Timeline { }
|
||||||
|
public enum Search { }
|
||||||
|
public enum Trends { }
|
||||||
|
public enum Suggestions { }
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Mastodon.API {
|
extension Mastodon.API {
|
||||||
|
|
|
@ -19,7 +19,7 @@ extension Mastodon.Entity {
|
||||||
public struct History: Codable {
|
public struct History: Codable {
|
||||||
/// UNIX timestamp on midnight of the given day
|
/// UNIX timestamp on midnight of the given day
|
||||||
public let day: Date
|
public let day: Date
|
||||||
public let uses: Int
|
public let uses: String
|
||||||
public let accounts: Int
|
public let accounts: String
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
//
|
||||||
|
// File.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by sxiaojian on 2021/3/31.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
extension Mastodon.Entity {
|
||||||
|
public struct SearchResult: Codable {
|
||||||
|
let accounts: [Mastodon.Entity.Account]
|
||||||
|
let statuses: [Mastodon.Entity.Status]
|
||||||
|
let hashtags: [Mastodon.Entity.Tag]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue