Merge pull request #801 from omnivore-app/recently-read-ios
Enable recently read sorting option on ios
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="20086" systemVersion="21F79" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="20086" systemVersion="21A559" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="Highlight" representedClassName="Highlight" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="annotation" optional="YES" attributeType="String"/>
|
||||
<attribute name="createdAt" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
@ -37,6 +37,7 @@
|
||||
<attribute name="pdfData" optional="YES" attributeType="Binary"/>
|
||||
<attribute name="publishDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="publisherURLString" optional="YES" attributeType="String"/>
|
||||
<attribute name="readAt" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="readingProgress" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="readingProgressAnchor" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="savedAt" attributeType="Date" usesScalarValueType="NO"/>
|
||||
@ -92,7 +93,7 @@
|
||||
</entity>
|
||||
<elements>
|
||||
<element name="Highlight" positionX="27" positionY="225" width="128" height="224"/>
|
||||
<element name="LinkedItem" positionX="-18" positionY="63" width="128" height="449"/>
|
||||
<element name="LinkedItem" positionX="-18" positionY="63" width="128" height="464"/>
|
||||
<element name="LinkedItemLabel" positionX="-36" positionY="18" width="128" height="134"/>
|
||||
<element name="NewsletterEmail" positionX="0" positionY="180" width="128" height="74"/>
|
||||
<element name="Viewer" positionX="45" positionY="234" width="128" height="89"/>
|
||||
|
||||
@ -19,6 +19,7 @@ public struct JSONArticle: Decodable {
|
||||
public let createdAt: Date
|
||||
public let updatedAt: Date
|
||||
public let savedAt: Date
|
||||
public let readAt: Date?
|
||||
public let image: String
|
||||
public let readingProgressPercent: Double
|
||||
public let readingProgressAnchorIndex: Int
|
||||
|
||||
@ -3,9 +3,8 @@ import Foundation
|
||||
public enum LinkedItemSort: String, CaseIterable {
|
||||
case newest
|
||||
case oldest
|
||||
// case recentlyRead
|
||||
case recentlyRead
|
||||
case recentlyPublished
|
||||
// case relevance
|
||||
}
|
||||
|
||||
public extension LinkedItemSort {
|
||||
@ -15,12 +14,10 @@ public extension LinkedItemSort {
|
||||
return "Newest"
|
||||
case .oldest:
|
||||
return "Oldest"
|
||||
// case .recentlyRead:
|
||||
// return "Recently Read"
|
||||
case .recentlyRead:
|
||||
return "Recently Read"
|
||||
case .recentlyPublished:
|
||||
return "Recently Published"
|
||||
// case .relevance:
|
||||
// return "Relevance"
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,23 +27,24 @@ public extension LinkedItemSort {
|
||||
return "sort:saved"
|
||||
case .oldest:
|
||||
return "sort:saved-ASC"
|
||||
// case .recentlyRead:
|
||||
// return "sort:updated"
|
||||
case .recentlyRead:
|
||||
return "sort:read"
|
||||
case .recentlyPublished:
|
||||
return "sort:published"
|
||||
// case .relevance:
|
||||
// return "relevance"
|
||||
}
|
||||
}
|
||||
|
||||
var sortDescriptors: [NSSortDescriptor] {
|
||||
switch self {
|
||||
case .newest /* , .relevance */:
|
||||
case .newest:
|
||||
return [NSSortDescriptor(keyPath: \LinkedItem.savedAt, ascending: false)]
|
||||
case .oldest:
|
||||
return [NSSortDescriptor(keyPath: \LinkedItem.savedAt, ascending: true)]
|
||||
// case .recentlyRead:
|
||||
// return [NSSortDescriptor(keyPath: \LinkedItem.updatedAt, ascending: false)]
|
||||
case .recentlyRead:
|
||||
return [
|
||||
NSSortDescriptor(keyPath: \LinkedItem.readAt, ascending: false),
|
||||
NSSortDescriptor(keyPath: \LinkedItem.savedAt, ascending: false)
|
||||
]
|
||||
case .recentlyPublished:
|
||||
return [NSSortDescriptor(keyPath: \LinkedItem.publishDate, ascending: false)]
|
||||
}
|
||||
|
||||
@ -681,6 +681,7 @@ extension Objects {
|
||||
let pageType: [String: Enums.PageType]
|
||||
let postedByViewer: [String: Bool]
|
||||
let publishedAt: [String: DateTime]
|
||||
let readAt: [String: DateTime]
|
||||
let readingProgressAnchorIndex: [String: Int]
|
||||
let readingProgressPercent: [String: Double]
|
||||
let savedAt: [String: DateTime]
|
||||
@ -793,6 +794,10 @@ extension Objects.Article: Decodable {
|
||||
if let value = try container.decode(DateTime?.self, forKey: codingKey) {
|
||||
map.set(key: field, hash: alias, value: value as Any)
|
||||
}
|
||||
case "readAt":
|
||||
if let value = try container.decode(DateTime?.self, forKey: codingKey) {
|
||||
map.set(key: field, hash: alias, value: value as Any)
|
||||
}
|
||||
case "readingProgressAnchorIndex":
|
||||
if let value = try container.decode(Int?.self, forKey: codingKey) {
|
||||
map.set(key: field, hash: alias, value: value as Any)
|
||||
@ -890,6 +895,7 @@ extension Objects.Article: Decodable {
|
||||
pageType = map["pageType"]
|
||||
postedByViewer = map["postedByViewer"]
|
||||
publishedAt = map["publishedAt"]
|
||||
readAt = map["readAt"]
|
||||
readingProgressAnchorIndex = map["readingProgressAnchorIndex"]
|
||||
readingProgressPercent = map["readingProgressPercent"]
|
||||
savedAt = map["savedAt"]
|
||||
@ -1219,6 +1225,21 @@ extension Fields where TypeLock == Objects.Article {
|
||||
}
|
||||
}
|
||||
|
||||
func readAt() throws -> DateTime? {
|
||||
let field = GraphQLField.leaf(
|
||||
name: "readAt",
|
||||
arguments: []
|
||||
)
|
||||
select(field)
|
||||
|
||||
switch response {
|
||||
case let .decoding(data):
|
||||
return data.readAt[field.alias!]
|
||||
case .mocking:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func readingProgressAnchorIndex() throws -> Int {
|
||||
let field = GraphQLField.leaf(
|
||||
name: "readingProgressAnchorIndex",
|
||||
|
||||
@ -27,7 +27,7 @@ extension DataService {
|
||||
|
||||
func syncLinkReadingProgress(itemID: String, objectID: NSManagedObjectID, readingProgress: Double, anchorIndex: Int) {
|
||||
enum MutationResult {
|
||||
case saved(readingProgress: Double)
|
||||
case saved(readAt: Date?)
|
||||
case error(errorCode: Enums.SaveArticleReadingProgressErrorCode)
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ extension DataService {
|
||||
saveArticleReadingProgressError: .init { .error(errorCode: try $0.errorCodes().first ?? .badData) },
|
||||
saveArticleReadingProgressSuccess: .init {
|
||||
.saved(
|
||||
readingProgress: try $0.updatedArticle(selection: Selection.Article { try $0.readingProgressPercent() })
|
||||
readAt: try $0.updatedArticle(selection: Selection.Article { try $0.readAt()?.value })
|
||||
)
|
||||
}
|
||||
)
|
||||
@ -64,6 +64,9 @@ extension DataService {
|
||||
context.perform {
|
||||
guard let linkedItem = context.object(with: objectID) as? LinkedItem else { return }
|
||||
linkedItem.serverSyncStatus = Int64(syncStatus.rawValue)
|
||||
if let mutationResult = data?.data, case let MutationResult.saved(readAt) = mutationResult {
|
||||
linkedItem.readAt = readAt
|
||||
}
|
||||
|
||||
do {
|
||||
try context.save()
|
||||
|
||||
@ -101,6 +101,7 @@ public extension DataService {
|
||||
title: try $0.title(),
|
||||
createdAt: try $0.createdAt().value ?? Date(),
|
||||
savedAt: try $0.savedAt().value ?? Date(),
|
||||
readAt: try $0.readAt()?.value,
|
||||
updatedAt: try $0.updatedAt().value ?? Date(),
|
||||
state: try $0.state()?.rawValue ?? "SUCCEEDED",
|
||||
readingProgress: try $0.readingProgressPercent(),
|
||||
@ -225,6 +226,7 @@ public extension DataService {
|
||||
linkedItem.author = item.author
|
||||
linkedItem.publishDate = item.publishDate
|
||||
linkedItem.slug = item.slug
|
||||
linkedItem.readAt = item.readAt
|
||||
linkedItem.isArchived = item.isArchived
|
||||
linkedItem.contentReader = item.contentReader
|
||||
linkedItem.serverSyncStatus = Int64(ServerSyncStatus.isNSync.rawValue)
|
||||
|
||||
@ -97,6 +97,7 @@ public extension DataService {
|
||||
title: try $0.title(),
|
||||
createdAt: try $0.createdAt().value ?? Date(),
|
||||
savedAt: try $0.savedAt().value ?? Date(),
|
||||
readAt: try $0.readAt()?.value,
|
||||
updatedAt: try $0.updatedAt().value ?? Date(),
|
||||
state: try $0.state()?.rawValue ?? "SUCCEEDED",
|
||||
readingProgress: try $0.readingProgressPercent(),
|
||||
@ -164,6 +165,7 @@ private let libraryArticleSelection = Selection.Article {
|
||||
title: try $0.title(),
|
||||
createdAt: try $0.createdAt().value ?? Date(),
|
||||
savedAt: try $0.savedAt().value ?? Date(),
|
||||
readAt: try $0.readAt()?.value,
|
||||
updatedAt: try $0.updatedAt().value ?? Date(),
|
||||
state: try $0.state()?.rawValue ?? "SUCCEEDED",
|
||||
readingProgress: try $0.readingProgressPercent(),
|
||||
|
||||
@ -7,6 +7,7 @@ struct InternalLinkedItem {
|
||||
let title: String
|
||||
let createdAt: Date
|
||||
let savedAt: Date
|
||||
let readAt: Date?
|
||||
let updatedAt: Date
|
||||
let state: String
|
||||
var readingProgress: Double
|
||||
@ -42,6 +43,7 @@ struct InternalLinkedItem {
|
||||
linkedItem.createdAt = createdAt
|
||||
linkedItem.savedAt = savedAt
|
||||
linkedItem.updatedAt = updatedAt
|
||||
linkedItem.readAt = readAt
|
||||
linkedItem.state = state
|
||||
linkedItem.readingProgress = readingProgress
|
||||
linkedItem.readingProgressAnchor = Int64(readingProgressAnchor)
|
||||
@ -53,6 +55,7 @@ struct InternalLinkedItem {
|
||||
linkedItem.siteName = siteName
|
||||
linkedItem.author = author
|
||||
linkedItem.publishDate = publishDate
|
||||
linkedItem.readAt = readAt
|
||||
linkedItem.slug = slug
|
||||
linkedItem.isArchived = isArchived
|
||||
linkedItem.contentReader = contentReader
|
||||
@ -99,6 +102,7 @@ extension JSONArticle {
|
||||
title: title,
|
||||
createdAt: createdAt,
|
||||
savedAt: savedAt,
|
||||
readAt: readAt,
|
||||
updatedAt: updatedAt,
|
||||
state: "SUCCEEDED",
|
||||
readingProgress: readingProgressPercent,
|
||||
|
||||
Reference in New Issue
Block a user