7eb9925865
- Replace .swipeActions with .contextMenu for delete/edit to avoid UICollectionView batch-update assertion when mutating posts during swipe animations. - Extend EditPostView to edit text, language, tags, visibility and schedule (timestamp) for scheduled posts. PostWriter.editPost now preserves unknown properties and rewrites the block surgically. - After composing, fetch the user's own feed with cache-busting headers and merge new posts into the timeline so they appear immediately instead of waiting up to a minute for relay indexing. - Serialize TimelineViewModel mutations with @ObservationIgnored isMutating guard; mark deletedTimestamps as non-observed to prevent duplicate observation triggers. - Stable ForEach ID using feedURL + timestamp to avoid duplicate IDs when multiple feeds post at the same second. - Move NotificationsView summary bar outside the List so its count changes don't conflict with UICollectionView item-count tracking.
65 lines
2.1 KiB
Swift
65 lines
2.1 KiB
Swift
import Foundation
|
||
|
||
public struct OrgSocialProfile: Sendable, Equatable {
|
||
/// Title of the feed (required by spec, optional in the parser).
|
||
public let title: String?
|
||
/// Nickname without spaces (required by spec, optional in the parser).
|
||
public let nick: String?
|
||
/// Short bio.
|
||
public let description: String?
|
||
/// URL to avatar image (JPG or PNG, min 128×128 px).
|
||
public let avatar: URL?
|
||
/// Personal website or profile URLs.
|
||
public let links: [URL]
|
||
/// Free-text location.
|
||
public let location: String?
|
||
/// Birthday in YYYY-MM-DD format.
|
||
public let birthday: String?
|
||
/// ISO 639-1 language codes the user speaks.
|
||
public let languages: [String]
|
||
/// Public URL of this `social.org` file. Not present in the file itself; set by the caller.
|
||
public var feedURL: URL?
|
||
/// RFC 3339 timestamp of the pinned post.
|
||
public let pinned: String?
|
||
/// Accounts this profile follows.
|
||
public let follows: [OrgSocialFollow]
|
||
/// Groups this profile subscribes to.
|
||
public let groups: [OrgSocialGroup]
|
||
/// Contact addresses (email, XMPP, Matrix, ActivityPub, etc.).
|
||
public let contacts: [String]
|
||
/// All posts in the feed, in file order.
|
||
public var posts: [OrgSocialPost]
|
||
|
||
public init(
|
||
title: String? = nil,
|
||
nick: String? = nil,
|
||
description: String? = nil,
|
||
avatar: URL? = nil,
|
||
links: [URL] = [],
|
||
location: String? = nil,
|
||
birthday: String? = nil,
|
||
languages: [String] = [],
|
||
feedURL: URL? = nil,
|
||
pinned: String? = nil,
|
||
follows: [OrgSocialFollow] = [],
|
||
groups: [OrgSocialGroup] = [],
|
||
contacts: [String] = [],
|
||
posts: [OrgSocialPost] = []
|
||
) {
|
||
self.title = title
|
||
self.nick = nick
|
||
self.description = description
|
||
self.avatar = avatar
|
||
self.links = links
|
||
self.location = location
|
||
self.birthday = birthday
|
||
self.languages = languages
|
||
self.feedURL = feedURL
|
||
self.pinned = pinned
|
||
self.follows = follows
|
||
self.groups = groups
|
||
self.contacts = contacts
|
||
self.posts = posts
|
||
}
|
||
}
|