001project_wildgrowth/ios/WildGrowth/WildGrowth/NoteModels.swift

336 lines
11 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
// MARK: -
enum NoteType: String, Codable {
case highlight = "highlight"
case thought = "thought"
case comment = "comment" //
}
// MARK: - ID
extension Note {
/// ID
static let systemUserId = "00000000-0000-0000-0000-000000000000"
///
var isSystemNote: Bool {
return userId == Note.systemUserId
}
}
// MARK: - Phase 1: Notebook
struct Notebook: Identifiable, Codable, Hashable {
let id: String
let userId: String
let title: String
let description: String?
let coverImage: String?
let noteCount: Int? //
let createdAt: Date
let updatedAt: Date
enum CodingKeys: String, CodingKey {
case id
case userId = "user_id"
case title, description
case coverImage = "cover_image"
case noteCount = "note_count"
case createdAt = "created_at"
case updatedAt = "updated_at"
}
//
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(String.self, forKey: .id)
userId = try container.decode(String.self, forKey: .userId)
title = try container.decode(String.self, forKey: .title)
description = try container.decodeIfPresent(String.self, forKey: .description)
coverImage = try container.decodeIfPresent(String.self, forKey: .coverImage)
noteCount = try container.decodeIfPresent(Int.self, forKey: .noteCount)
//
let createdAtString = try container.decode(String.self, forKey: .createdAt)
guard let createdAtDate = ISO8601DateFormatters.date(from: createdAtString) else {
throw DecodingError.dataCorruptedError(
forKey: .createdAt,
in: container,
debugDescription: "Invalid date format: \(createdAtString)"
)
}
createdAt = createdAtDate
let updatedAtString = try container.decode(String.self, forKey: .updatedAt)
guard let updatedAtDate = ISO8601DateFormatters.date(from: updatedAtString) else {
throw DecodingError.dataCorruptedError(
forKey: .updatedAt,
in: container,
debugDescription: "Invalid date format: \(updatedAtString)"
)
}
updatedAt = updatedAtDate
}
}
// MARK: - Phase 1: Note
struct Note: Identifiable, Codable {
let id: String
let userId: String
//
let notebookId: String? // IDnil
let parentId: String? // IDnil
let order: Int // 0, 1, 2...
let level: Int // 0=, 1=, 2=
//
let courseId: String?
let nodeId: String?
let startIndex: Int? // null
let length: Int? // null
let type: NoteType
let content: String? // 线
let quotedText: String? // null
//
let userName: String?
let courseTitle: String?
let nodeTitle: String?
let style: String?
// Date
let createdAt: Date
let updatedAt: Date
enum CodingKeys: String, CodingKey {
case id
case userId = "user_id"
case userName = "user_name"
//
case notebookId = "notebook_id"
case parentId = "parent_id"
case order, level
//
case courseId = "course_id"
case nodeId = "node_id"
case startIndex = "start_index"
case length, type, content
case quotedText = "quoted_text"
case style
case createdAt = "created_at"
case updatedAt = "updated_at"
case courseTitle = "course_title"
case nodeTitle = "node_title"
}
//
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(String.self, forKey: .id)
userId = try container.decode(String.self, forKey: .userId)
userName = try container.decodeIfPresent(String.self, forKey: .userName)
//
notebookId = try container.decodeIfPresent(String.self, forKey: .notebookId)
parentId = try container.decodeIfPresent(String.self, forKey: .parentId)
order = try container.decodeIfPresent(Int.self, forKey: .order) ?? 0
level = try container.decodeIfPresent(Int.self, forKey: .level) ?? 0
//
courseId = try container.decodeIfPresent(String.self, forKey: .courseId)
nodeId = try container.decodeIfPresent(String.self, forKey: .nodeId)
startIndex = try container.decodeIfPresent(Int.self, forKey: .startIndex)
length = try container.decodeIfPresent(Int.self, forKey: .length)
quotedText = try container.decodeIfPresent(String.self, forKey: .quotedText)
type = try container.decode(NoteType.self, forKey: .type)
content = try container.decodeIfPresent(String.self, forKey: .content)
style = try container.decodeIfPresent(String.self, forKey: .style)
courseTitle = try container.decodeIfPresent(String.self, forKey: .courseTitle)
nodeTitle = try container.decodeIfPresent(String.self, forKey: .nodeTitle)
//
let createdAtString = try container.decode(String.self, forKey: .createdAt)
guard let createdAtDate = ISO8601DateFormatters.date(from: createdAtString) else {
throw DecodingError.dataCorruptedError(
forKey: .createdAt,
in: container,
debugDescription: "Invalid date format: \(createdAtString)"
)
}
createdAt = createdAtDate
let updatedAtString = try container.decode(String.self, forKey: .updatedAt)
guard let updatedAtDate = ISO8601DateFormatters.date(from: updatedAtString) else {
throw DecodingError.dataCorruptedError(
forKey: .updatedAt,
in: container,
debugDescription: "Invalid date format: \(updatedAtString)"
)
}
updatedAt = updatedAtDate
}
// MARK: - 便 Note
init(
id: String,
userId: String,
userName: String?,
notebookId: String? = nil,
parentId: String? = nil,
order: Int = 0,
level: Int = 0,
courseId: String? = nil,
nodeId: String? = nil,
startIndex: Int? = nil,
length: Int? = nil,
type: NoteType,
content: String?,
quotedText: String? = nil,
style: String? = nil,
createdAt: Date,
updatedAt: Date,
courseTitle: String? = nil,
nodeTitle: String? = nil
) {
self.id = id
self.userId = userId
self.userName = userName
self.notebookId = notebookId
self.parentId = parentId
self.order = order
self.level = level
self.courseId = courseId
self.nodeId = nodeId
self.startIndex = startIndex
self.length = length
self.type = type
self.content = content
self.quotedText = quotedText
self.style = style
self.createdAt = createdAt
self.updatedAt = updatedAt
self.courseTitle = courseTitle
self.nodeTitle = nodeTitle
}
}
// MARK: - Phase 1: Notebook API
struct NotebookListResponse: Codable {
let success: Bool
let data: NotebookListData
}
struct NotebookListData: Codable {
let notebooks: [Notebook]
let total: Int
}
struct NotebookResponse: Codable {
let success: Bool
let data: NotebookData
}
struct NotebookData: Codable {
let notebook: Notebook
}
// MARK: - API
struct NoteListResponse: Codable {
let success: Bool
let data: NoteListData
}
struct NoteListData: Codable {
let notes: [Note]
let total: Int
}
struct NoteResponse: Codable {
let success: Bool
let data: Note
}
// MARK: - Phase 1:
struct CreateNotebookRequest: Codable {
let title: String
let description: String?
let coverImage: String?
enum CodingKeys: String, CodingKey {
case title, description
case coverImage = "cover_image"
}
}
// MARK: - Phase 1:
struct UpdateNotebookRequest: Codable {
let title: String?
let description: String?
let coverImage: String?
enum CodingKeys: String, CodingKey {
case title, description
case coverImage = "cover_image"
}
}
// MARK: - Phase 1:
struct CreateNoteRequest: Codable {
//
let notebookId: String?
let parentId: String?
let order: Int?
let level: Int?
//
let courseId: String?
let nodeId: String?
let startIndex: Int? // NSRange.location
let length: Int? // NSRange.length
let type: String // "highlight" or "thought"
let quotedText: String? // null
let content: String? // 线
let style: String? //
enum CodingKeys: String, CodingKey {
case notebookId = "notebook_id"
case parentId = "parent_id"
case order, level
case courseId = "course_id"
case nodeId = "node_id"
case startIndex = "start_index"
case length, type
case quotedText = "quoted_text"
case content, style
}
}
// MARK: - Phase 1:
struct UpdateNoteRequest: Codable {
//
let parentId: String?
let order: Int?
let level: Int?
//
let content: String?
let quotedText: String?
let startIndex: Int?
let length: Int?
let style: String?
enum CodingKeys: String, CodingKey {
case parentId = "parent_id"
case order, level
case content
case quotedText = "quoted_text"
case startIndex = "start_index"
case length, style
}
}