feature: add SearchRecommendTagsCollectionViewCell

This commit is contained in:
sunxiaojian 2021-03-31 20:56:11 +08:00
parent 09320bf99c
commit dff874af76
9 changed files with 410 additions and 11 deletions

View File

@ -33,6 +33,7 @@
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 */; };
2D364F7825E66D8300204FDC /* MastodonResendEmailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */; };
2D38F1C625CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1C525CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift */; };
@ -99,6 +100,7 @@
2DF75BA725D10E1000694EC8 /* APIService+Favorite.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75BA625D10E1000694EC8 /* APIService+Favorite.swift */; };
2DF75BB925D1474100694EC8 /* ManagedObjectObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75BB825D1474100694EC8 /* ManagedObjectObserver.swift */; };
2DF75BC725D1475D00694EC8 /* ManagedObjectContextObjectsDidChange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75BC625D1475D00694EC8 /* ManagedObjectContextObjectsDidChange.swift */; };
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 */; };
5DF1054725F8870E00D6C0D4 /* VideoPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1054625F8870E00D6C0D4 /* VideoPlayerViewModel.swift */; };
@ -339,6 +341,7 @@
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>"; };
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>"; };
@ -402,6 +405,7 @@
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>"; };
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>"; };
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; };
@ -706,6 +710,14 @@
path = Content;
sourceTree = "<group>";
};
2D34D9E026149C550081BFC0 /* CollectionViewCell */ = {
isa = PBXGroup;
children = (
2D34D9E126149C920081BFC0 /* SearchRecommendTagsCollectionViewCell.swift */,
);
path = CollectionViewCell;
sourceTree = "<group>";
};
2D364F7025E66D5B00204FDC /* ResendEmail */ = {
isa = PBXGroup;
children = (
@ -1352,6 +1364,7 @@
5DF1056325F887CB00D6C0D4 /* AVPlayer.swift */,
DB47229625F9EFAD00DA7F53 /* NSManagedObjectContext.swift */,
2D32EAB925CB9B0500C9ED86 /* UIView.swift */,
2DFF41882614A4DC00F776A4 /* UIView+Constraint.swift */,
DB8AF55C25C138B7002E6C99 /* UIViewController.swift */,
2D3F9E0325DFA133004262D9 /* UITapGestureRecognizer.swift */,
2D84350425FF858100EECE90 /* UIScrollView.swift */,
@ -1394,6 +1407,7 @@
DB9D6BE825E4F5340051B173 /* SearchViewController.swift */,
2D34D9CA261489930081BFC0 /* SearchViewController+recomendView.swift */,
2D6DE3FF26141DF600A63F6A /* SearchViewModel.swift */,
2D34D9E026149C550081BFC0 /* CollectionViewCell */,
);
path = Search;
sourceTree = "<group>";
@ -1986,6 +2000,7 @@
DB98338725C945ED00AD9700 /* Strings.swift in Sources */,
DB45FAB625CA5485005A8AC7 /* UIAlertController.swift in Sources */,
DBE0821525CD382600FD6BBD /* MastodonRegisterViewController.swift in Sources */,
2DFF41892614A4DC00F776A4 /* UIView+Constraint.swift in Sources */,
2D5A3D0325CF8742002347D6 /* ControlContainableScrollViews.swift in Sources */,
DB98336B25C9420100AD9700 /* APIService+App.swift in Sources */,
DBA0A11325FB3FC10079C110 /* ComposeToolbarView.swift in Sources */,
@ -1995,6 +2010,7 @@
DB447697260B439000B66B82 /* CustomEmojiPickerHeaderCollectionReusableView.swift in Sources */,
DB45FAF925CA80A2005A8AC7 /* APIService+CoreData+MastodonAuthentication.swift in Sources */,
2D04F42525C255B9003F936F /* APIService+PublicTimeline.swift in Sources */,
2D34D9E226149C920081BFC0 /* SearchRecommendTagsCollectionViewCell.swift in Sources */,
2D76317D25C14DF500929FB9 /* PublicTimelineViewController+StatusProvider.swift in Sources */,
2D206B8025F5F45E00143C56 /* UIImage.swift in Sources */,
2D5A3D2825CF8BC9002347D6 /* HomeTimelineViewModel+Diffable.swift in Sources */,

View File

@ -0,0 +1,257 @@
//
// 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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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
})
}
}

View File

@ -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)
}
}

View File

@ -1,5 +1,5 @@
//
// SearchViewController+recomemndView.swift
// SearchViewController+recommendView.swift
// Mastodon
//
// Created by sxiaojian on 2021/3/31.
@ -10,9 +10,14 @@ import UIKit
extension SearchViewController {
func setuprecomemndView() {
recomemndView.dataSource = self
recomemndView.delegate = self
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()
}
}
@ -21,8 +26,19 @@ 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 {
return 0
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 {

View File

@ -27,7 +27,7 @@ final class SearchViewController: UIViewController, NeedsDependency {
return searchBar
}()
let recomemndView: UICollectionView = {
let recommendView: UICollectionView = {
let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .horizontal
let view = ControlContainableCollectionView(frame: .zero, collectionViewLayout: flowLayout)

View File

@ -9,6 +9,7 @@ import Foundation
import Combine
import MastodonSDK
import UIKit
import OSLog
final class SearchViewModel {
@ -25,6 +26,39 @@ final class SearchViewModel {
init(context: AppContext) {
self.context = context
guard let activeMastodonAuthenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else {
return
}
context.apiService.recommendTrends(domain: activeMastodonAuthenticationBox.domain, query: Mastodon.API.Trends.Query(limit: 5))
.sink { completion in
switch completion {
case .failure(let error):
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: recommendTrends fail: %s", ((#file as NSString).lastPathComponent), #line, #function, error.localizedDescription)
case .finished:
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: recommendTrends success", ((#file as NSString).lastPathComponent), #line, #function)
break
}
} receiveValue: { [weak self] tags in
guard let self = self else { return }
self.recommendHashTags = tags.value
}
.store(in: &disposeBag)
context.apiService.recommendAccount(domain: activeMastodonAuthenticationBox.domain, query: nil, mastodonAuthenticationBox: activeMastodonAuthenticationBox)
.sink { completion in
switch completion {
case .failure(let error):
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: recommendAccount fail: %s", ((#file as NSString).lastPathComponent), #line, #function, error.localizedDescription)
case .finished:
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: recommendAccount success", ((#file as NSString).lastPathComponent), #line, #function)
break
}
} receiveValue: { [weak self] accounts in
guard let self = self else { return }
self.recommendAccounts = accounts.value
}
.store(in: &disposeBag)
}
}

View File

@ -13,7 +13,7 @@ extension APIService {
func recommendAccount(
domain: String,
query: Mastodon.API.Suggestions.Query,
query: Mastodon.API.Suggestions.Query?,
mastodonAuthenticationBox: AuthenticationService.MastodonAuthenticationBox
) -> AnyPublisher<Mastodon.Response.Content<[Mastodon.Entity.Account]>, Error> {
let authorization = mastodonAuthenticationBox.userAuthorization
@ -23,7 +23,7 @@ extension APIService {
func recommendTrends(
domain: String,
query: Mastodon.API.Trends.Query
query: Mastodon.API.Trends.Query?
) -> AnyPublisher<Mastodon.Response.Content<[Mastodon.Entity.Tag]>, Error> {
return Mastodon.API.Trends.get(session: session, domain: domain, query: query)
}

View File

@ -31,7 +31,7 @@ extension Mastodon.API.Suggestions {
public static func get(
session: URLSession,
domain: String,
query: Mastodon.API.Suggestions.Query,
query: Mastodon.API.Suggestions.Query?,
authorization: Mastodon.API.OAuth.Authorization
) -> AnyPublisher<Mastodon.Response.Content<[Mastodon.Entity.Account]>, Error> {
let request = Mastodon.API.get(

View File

@ -31,7 +31,7 @@ extension Mastodon.API.Trends {
public static func get(
session: URLSession,
domain: String,
query: Mastodon.API.Trends.Query
query: Mastodon.API.Trends.Query?
) -> AnyPublisher<Mastodon.Response.Content<[Mastodon.Entity.Tag]>, Error> {
let request = Mastodon.API.get(
url: trendsURL(domain: domain),