Files
e-party-iOS/yana/APIs/DynamicsModels.swift
edwinQQQ c8ff40cac1 feat: 更新动态相关数据模型及视图组件
- 在DynamicsModels.swift中为动态响应结构和列表数据添加Sendable协议,提升并发安全性。
- 在FeedListFeature.swift中实现动态内容的加载逻辑,集成API请求以获取最新动态。
- 在FeedListView.swift中新增动态内容列表展示,优化用户交互体验。
- 在MeView.swift中添加设置按钮,支持弹出设置视图。
- 在SettingView.swift中新增COS上传测试功能,允许用户测试图片上传至腾讯云COS。
- 在OptimizedDynamicCardView.swift中实现优化的动态卡片组件,提升动态展示效果。
2025-07-22 17:17:21 +08:00

227 lines
5.9 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Foundation
import ComposableArchitecture
// MARK: -
///
struct MomentsLatestResponse: Codable, Equatable, Sendable {
let code: Int
let message: String
let data: MomentsListData?
let timestamp: Int?
}
///
struct MomentsListData: Codable, Equatable, Sendable {
let dynamicList: [MomentsInfo]
let nextDynamicId: Int
}
///
public struct MomentsInfo: Codable, Equatable, Sendable {
let dynamicId: Int
let uid: Int
let nick: String
let avatar: String
let gender: Int
let type: Int
let content: String
let likeCount: Int
let isLike: Bool
let commentCount: Int
let publishTime: Int
let worldId: Int
let squareTop: Int
let topicTop: Int
let newUser: Bool
let defUser: Int
let status: Int
let scene: String
let dynamicResList: [MomentsPicture]?
let userVipInfoVO: UserVipInfo?
// -
let headwearPic: String?
let headwearEffect: String?
let headwearType: Int?
let headwearName: String?
let headwearId: Int?
// -
let experLevelPic: String?
let charmLevelPic: String?
//
let isCustomWord: Bool?
let labelList: [String]?
// IntBool
var isSquareTop: Bool { squareTop != 0 }
var isTopicTop: Bool { topicTop != 0 }
//
var formattedPublishTime: Date {
Date(timeIntervalSince1970: TimeInterval(publishTime) / 1000.0)
}
}
///
struct MomentsPicture: Codable, Equatable, Sendable {
let id: Int
let resUrl: String
let format: String
let width: Int
let height: Int
let resDuration: Int? //
}
/// VIP -
struct UserVipInfo: Codable, Equatable, Sendable {
let vipLevel: Int?
let vipName: String?
let vipIcon: String?
let vipLogo: String?
let nameplateId: Int?
let nameplateUrl: String?
let userCardBG: String?
let expireTime: Int?
let preventKick: Bool?
let preventTrace: Bool?
let preventFollow: Bool?
let micNickColour: String?
let micCircle: String?
let enterRoomEffects: String?
let medalSeat: Int?
let friendNickColour: String?
let visitHide: Bool?
let visitListView: Bool?
let privateChatLimit: Bool?
let roomPicScreen: Bool?
let uploadGifAvatar: Bool?
let enterHide: Bool?
}
// MARK: -
///
enum MomentsContentType: Int, CaseIterable {
case text = 0 //
case picture = 2 //
/// API
static func toAPIParameter(_ types: [MomentsContentType]) -> String {
return types.map { String($0.rawValue) }.joined(separator: ",")
}
}
// MARK: - API
/// API
struct LatestDynamicsRequest: APIRequestProtocol {
typealias Response = MomentsLatestResponse
let endpoint: String = APIEndpoint.latestDynamics.path
let method: HTTPMethod = .GET
let dynamicId: String
let pageSize: Int
let types: [MomentsContentType]
///
/// - Parameters:
/// - dynamicId: ID
/// - pageSize: 20
/// - types:
init(
dynamicId: String = "",
pageSize: Int = 20,
types: [MomentsContentType] = [.text, .picture]
) {
self.dynamicId = dynamicId
self.pageSize = pageSize
self.types = types
}
var queryParameters: [String: String]? {
return [
"dynamicId": dynamicId,
"pageSize": String(pageSize),
"types": MomentsContentType.toAPIParameter(types)
]
}
var bodyParameters: [String: Any]? { nil }
var includeBaseParameters: Bool { true }
// Loading
var shouldShowLoading: Bool { true }
var shouldShowError: Bool { true }
}
// MARK: - API
///
struct PublishFeedRequest: APIRequestProtocol {
typealias Response = PublishFeedResponse
let endpoint: String = APIEndpoint.publishFeed.path
let method: HTTPMethod = .POST
let content: String
let uid: String
let type: String
var pub_sign: String
var queryParameters: [String: String]? { nil }
var bodyParameters: [String: Any]? {
[
"content": content,
"uid": uid,
"type": type,
"pub_sign": pub_sign
]
}
var includeBaseParameters: Bool { true }
var shouldShowLoading: Bool { true }
var shouldShowError: Bool { true }
/// async 线 pub_sign
static func make(content: String, uid: String, type: String = "0") async -> PublishFeedRequest {
let base = await MainActor.run { BaseRequest() }
var mutableBase = base
mutableBase.generateSignature(with: [
"content": content,
"uid": uid,
"type": type
])
return PublishFeedRequest(
content: content,
uid: uid,
type: type,
pub_sign: mutableBase.pubSign
)
}
///
private init(content: String, uid: String, type: String, pub_sign: String) {
self.content = content
self.uid = uid
self.type = type
self.pub_sign = pub_sign
}
}
///
struct PublishFeedResponse: Codable, Equatable {
let code: Int
let message: String
let data: PublishFeedData?
let timestamp: Int?
}
///
struct PublishFeedData: Codable, Equatable {
let dynamicId: Int?
}