mirror of
https://github.com/metabolist/metatext.git
synced 2025-01-03 10:38:41 +00:00
Featured tags data
This commit is contained in:
parent
2eddf8c558
commit
a51d9aafae
13 changed files with 142 additions and 3 deletions
|
@ -56,6 +56,7 @@ extension AccountRecord {
|
|||
static let moved = belongsTo(AccountRecord.self)
|
||||
static let relationship = hasOne(Relationship.self)
|
||||
static let identityProofs = hasMany(IdentityProofRecord.self)
|
||||
static let featuredTags = hasMany(FeaturedTagRecord.self)
|
||||
static let pinnedStatusJoins = hasMany(AccountPinnedStatusJoin.self)
|
||||
.order(AccountPinnedStatusJoin.Columns.index)
|
||||
static let pinnedStatuses = hasMany(
|
||||
|
|
|
@ -57,6 +57,15 @@ extension ContentDatabase {
|
|||
t.primaryKey(["accountId", "provider"], onConflict: .replace)
|
||||
}
|
||||
|
||||
try db.create(table: "featuredTagRecord") { t in
|
||||
t.column("id", .text).primaryKey(onConflict: .replace)
|
||||
t.column("name", .text).notNull()
|
||||
t.column("url", .text).notNull()
|
||||
t.column("statusesCount", .integer).notNull()
|
||||
t.column("lastStatusAt", .date).notNull()
|
||||
t.column("accountId", .text).notNull().references("accountRecord", onDelete: .cascade)
|
||||
}
|
||||
|
||||
try db.create(table: "statusRecord") { t in
|
||||
t.column("id", .text).primaryKey(onConflict: .replace)
|
||||
t.column("uri", .text).notNull()
|
||||
|
|
|
@ -284,6 +284,23 @@ public extension ContentDatabase {
|
|||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
func insert(featuredTags: [FeaturedTag], id: Account.Id) -> AnyPublisher<Never, Error> {
|
||||
databaseWriter.writePublisher {
|
||||
for featuredTag in featuredTags {
|
||||
try FeaturedTagRecord(
|
||||
id: featuredTag.id,
|
||||
name: featuredTag.name,
|
||||
url: featuredTag.url,
|
||||
statusesCount: featuredTag.statusesCount,
|
||||
lastStatusAt: featuredTag.lastStatusAt,
|
||||
accountId: id)
|
||||
.save($0)
|
||||
}
|
||||
}
|
||||
.ignoreOutput()
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
func insert(relationships: [Relationship]) -> AnyPublisher<Never, Error> {
|
||||
databaseWriter.writePublisher {
|
||||
for relationship in relationships {
|
||||
|
|
25
DB/Sources/DB/Content/FeaturedTagRecord.swift
Normal file
25
DB/Sources/DB/Content/FeaturedTagRecord.swift
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import GRDB
|
||||
import Mastodon
|
||||
|
||||
struct FeaturedTagRecord: ContentDatabaseRecord, Hashable {
|
||||
let id: FeaturedTag.Id
|
||||
let name: String
|
||||
let url: URL
|
||||
let statusesCount: Int
|
||||
let lastStatusAt: Date
|
||||
let accountId: Account.Id
|
||||
}
|
||||
|
||||
extension FeaturedTagRecord {
|
||||
enum Columns {
|
||||
static let id = Column(CodingKeys.id)
|
||||
static let name = Column(CodingKeys.name)
|
||||
static let url = Column(CodingKeys.url)
|
||||
static let statusesCount = Column(CodingKeys.statusesCount)
|
||||
static let lastStatusAt = Column(CodingKeys.lastStatusAt)
|
||||
static let accountId = Column(CodingKeys.accountId)
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ struct ProfileInfo: Codable, Hashable, FetchableRecord {
|
|||
let accountInfo: AccountInfo
|
||||
let relationship: Relationship?
|
||||
let identityProofRecords: [IdentityProofRecord]
|
||||
let featuredTagRecords: [FeaturedTagRecord]
|
||||
}
|
||||
|
||||
extension ProfileInfo {
|
||||
|
@ -15,6 +16,7 @@ extension ProfileInfo {
|
|||
AccountInfo.addingIncludes(request)
|
||||
.including(optional: AccountRecord.relationship.forKey(CodingKeys.relationship))
|
||||
.including(all: AccountRecord.identityProofs.forKey(CodingKeys.identityProofRecords))
|
||||
.including(all: AccountRecord.featuredTags.forKey(CodingKeys.featuredTagRecords))
|
||||
}
|
||||
|
||||
static func request(_ request: QueryInterfaceRequest<AccountRecord>) -> QueryInterfaceRequest<Self> {
|
||||
|
|
|
@ -7,11 +7,13 @@ public struct Profile: Codable, Hashable {
|
|||
public let account: Account
|
||||
public let relationship: Relationship?
|
||||
public let identityProofs: [IdentityProof]
|
||||
public let featuredTags: [FeaturedTag]
|
||||
|
||||
public init(account: Account) {
|
||||
self.account = account
|
||||
self.relationship = nil
|
||||
self.identityProofs = []
|
||||
self.featuredTags = []
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,5 +22,6 @@ extension Profile {
|
|||
account = Account(info: info.accountInfo)
|
||||
relationship = info.relationship
|
||||
identityProofs = info.identityProofRecords.map(IdentityProof.init(record:))
|
||||
featuredTags = info.featuredTagRecords.map(FeaturedTag.init(record:))
|
||||
}
|
||||
}
|
||||
|
|
16
DB/Sources/DB/Extensions/FeaturedTag+Extensions.swift
Normal file
16
DB/Sources/DB/Extensions/FeaturedTag+Extensions.swift
Normal file
|
@ -0,0 +1,16 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import GRDB
|
||||
import Mastodon
|
||||
|
||||
extension FeaturedTag {
|
||||
init(record: FeaturedTagRecord) {
|
||||
self.init(
|
||||
id: record.id,
|
||||
name: record.name,
|
||||
url: record.url,
|
||||
statusesCount: record.statusesCount,
|
||||
lastStatusAt: record.lastStatusAt)
|
||||
}
|
||||
}
|
23
Mastodon/Sources/Mastodon/Entities/FeaturedTag.swift
Normal file
23
Mastodon/Sources/Mastodon/Entities/FeaturedTag.swift
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct FeaturedTag: Codable, Hashable {
|
||||
public let id: Id
|
||||
public let name: String
|
||||
public let url: URL
|
||||
public let statusesCount: Int
|
||||
public let lastStatusAt: Date
|
||||
|
||||
public init(id: FeaturedTag.Id, name: String, url: URL, statusesCount: Int, lastStatusAt: Date) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.url = url
|
||||
self.statusesCount = statusesCount
|
||||
self.lastStatusAt = lastStatusAt
|
||||
}
|
||||
}
|
||||
|
||||
public extension FeaturedTag {
|
||||
typealias Id = String
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import HTTP
|
||||
import Mastodon
|
||||
|
||||
public enum FeaturedTagsEndpoint {
|
||||
case featuredTags(id: Account.Id)
|
||||
}
|
||||
|
||||
extension FeaturedTagsEndpoint: Endpoint {
|
||||
public typealias ResultType = [FeaturedTag]
|
||||
|
||||
public var context: [String] {
|
||||
switch self {
|
||||
case .featuredTags:
|
||||
return defaultContext + ["accounts"]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public var pathComponentsInContext: [String] {
|
||||
switch self {
|
||||
case let .featuredTags(id):
|
||||
return [id, "featured_tags"]
|
||||
}
|
||||
}
|
||||
|
||||
public var method: HTTPMethod {
|
||||
switch self {
|
||||
case .featuredTags:
|
||||
return .get
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ public struct AccountService {
|
|||
public let account: Account
|
||||
public let relationship: Relationship?
|
||||
public let identityProofs: [IdentityProof]
|
||||
public let featuredTags: [FeaturedTag]
|
||||
public let navigationService: NavigationService
|
||||
|
||||
private let mastodonAPIClient: MastodonAPIClient
|
||||
|
@ -18,11 +19,13 @@ public struct AccountService {
|
|||
public init(account: Account,
|
||||
relationship: Relationship? = nil,
|
||||
identityProofs: [IdentityProof] = [],
|
||||
featuredTags: [FeaturedTag] = [],
|
||||
mastodonAPIClient: MastodonAPIClient,
|
||||
contentDatabase: ContentDatabase) {
|
||||
self.account = account
|
||||
self.relationship = relationship
|
||||
self.identityProofs = identityProofs
|
||||
self.featuredTags = featuredTags
|
||||
navigationService = NavigationService(mastodonAPIClient: mastodonAPIClient, contentDatabase: contentDatabase)
|
||||
self.mastodonAPIClient = mastodonAPIClient
|
||||
self.contentDatabase = contentDatabase
|
||||
|
|
|
@ -103,7 +103,6 @@ public extension EmojiPickerService {
|
|||
promise(.failure(error))
|
||||
}
|
||||
}
|
||||
.print()
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ public struct ProfileService {
|
|||
account: $0.account,
|
||||
relationship: $0.relationship,
|
||||
identityProofs: $0.identityProofs,
|
||||
featuredTags: $0.featuredTags,
|
||||
mastodonAPIClient: mastodonAPIClient,
|
||||
contentDatabase: contentDatabase)
|
||||
}
|
||||
|
@ -65,14 +66,17 @@ public extension ProfileService {
|
|||
}
|
||||
|
||||
func fetchProfile() -> AnyPublisher<Never, Error> {
|
||||
Publishers.Merge3(
|
||||
Publishers.Merge4(
|
||||
mastodonAPIClient.request(AccountEndpoint.accounts(id: id))
|
||||
.flatMap { contentDatabase.insert(accounts: [$0]) },
|
||||
mastodonAPIClient.request(RelationshipsEndpoint.relationships(ids: [id]))
|
||||
.flatMap { contentDatabase.insert(relationships: $0) },
|
||||
mastodonAPIClient.request(IdentityProofsEndpoint.identityProofs(id: id))
|
||||
.catch { _ in Empty() }
|
||||
.flatMap { contentDatabase.insert(identityProofs: $0, id: id) })
|
||||
.flatMap { contentDatabase.insert(identityProofs: $0, id: id) },
|
||||
mastodonAPIClient.request(FeaturedTagsEndpoint.featuredTags(id: id))
|
||||
.catch { _ in Empty() }
|
||||
.flatMap { contentDatabase.insert(featuredTags: $0, id: id) })
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,8 @@ public extension AccountViewModel {
|
|||
|
||||
var identityProofs: [IdentityProof] { accountService.identityProofs }
|
||||
|
||||
var featuredTags: [FeaturedTag] { accountService.featuredTags }
|
||||
|
||||
var fields: [Account.Field] { accountService.account.fields }
|
||||
|
||||
var note: NSAttributedString { accountService.account.note.attributed }
|
||||
|
|
Loading…
Reference in a new issue