This commit is contained in:
Brent Simmons 2021-02-21 18:57:43 -08:00
commit 670996fdc2
58 changed files with 224 additions and 187 deletions

View File

@ -11,10 +11,10 @@ let package = Package(
targets: ["Account"]),
],
dependencies: [
.package(url: "https://github.com/Ranchero-Software/RSCore.git", .upToNextMajor(from: "1.0.0-beta1")),
.package(url: "https://github.com/Ranchero-Software/RSDatabase.git", .upToNextMajor(from: "1.0.0-beta1")),
.package(url: "https://github.com/Ranchero-Software/RSParser.git", .upToNextMajor(from: "2.0.0-beta1")),
.package(url: "https://github.com/Ranchero-Software/RSWeb.git", .upToNextMajor(from: "1.0.0-beta1")),
.package(url: "https://github.com/Ranchero-Software/RSCore.git", .upToNextMajor(from: "1.0.0")),
.package(url: "https://github.com/Ranchero-Software/RSDatabase.git", .upToNextMajor(from: "1.0.0")),
.package(url: "https://github.com/Ranchero-Software/RSParser.git", .upToNextMajor(from: "2.0.0")),
.package(url: "https://github.com/Ranchero-Software/RSWeb.git", .upToNextMajor(from: "1.0.0")),
.package(url: "../Articles", .upToNextMajor(from: "1.0.0")),
.package(url: "../ArticlesDatabase", .upToNextMajor(from: "1.0.0")),
.package(url: "../Secrets", .upToNextMajor(from: "1.0.0")),

View File

@ -9,7 +9,7 @@
import Foundation
import RSWeb
protocol AccountMetadataDelegate: class {
protocol AccountMetadataDelegate: AnyObject {
func valueDidChange(_ accountMetadata: AccountMetadata, key: AccountMetadata.CodingKeys)
}

View File

@ -21,9 +21,7 @@ enum CloudKitAccountZoneError: LocalizedError {
}
final class CloudKitAccountZone: CloudKitZone {
static var zoneID: CKRecordZone.ID {
return CKRecordZone.ID(zoneName: "Account", ownerName: CKCurrentUserDefaultName)
}
var zoneID: CKRecordZone.ID
var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit")
@ -53,6 +51,8 @@ final class CloudKitAccountZone: CloudKitZone {
init(container: CKContainer) {
self.container = container
self.database = container.privateCloudDatabase
self.zoneID = CKRecordZone.ID(zoneName: "Account", ownerName: CKCurrentUserDefaultName)
migrateChangeToken()
}
func importOPML(rootExternalID: String, items: [RSOPMLItem], completion: @escaping (Result<Void, Error>) -> Void) {
@ -91,7 +91,7 @@ final class CloudKitAccountZone: CloudKitZone {
/// Persist a web feed record to iCloud and return the external key
func createWebFeed(url: String, name: String?, editedName: String?, homePageURL: String?, container: Container, completion: @escaping (Result<String, Error>) -> Void) {
let recordID = CKRecord.ID(recordName: url.md5String, zoneID: Self.zoneID)
let recordID = CKRecord.ID(recordName: url.md5String, zoneID: zoneID)
let record = CKRecord(recordType: CloudKitWebFeed.recordType, recordID: recordID)
record[CloudKitWebFeed.Fields.url] = url
record[CloudKitWebFeed.Fields.name] = name
@ -125,7 +125,7 @@ final class CloudKitAccountZone: CloudKitZone {
return
}
let recordID = CKRecord.ID(recordName: externalID, zoneID: Self.zoneID)
let recordID = CKRecord.ID(recordName: externalID, zoneID: zoneID)
let record = CKRecord(recordType: CloudKitWebFeed.recordType, recordID: recordID)
record[CloudKitWebFeed.Fields.editedName] = editedName
@ -252,7 +252,7 @@ final class CloudKitAccountZone: CloudKitZone {
let predicate = NSPredicate(format: "isAccount = \"1\"")
let ckQuery = CKQuery(recordType: CloudKitContainer.recordType, predicate: predicate)
database?.perform(ckQuery, inZoneWith: Self.zoneID) { [weak self] records, error in
database?.perform(ckQuery, inZoneWith: zoneID) { [weak self] records, error in
guard let self = self else { return }
switch CloudKitZoneResult.resolve(error) {
@ -296,7 +296,7 @@ final class CloudKitAccountZone: CloudKitZone {
return
}
let recordID = CKRecord.ID(recordName: externalID, zoneID: Self.zoneID)
let recordID = CKRecord.ID(recordName: externalID, zoneID: zoneID)
let record = CKRecord(recordType: CloudKitContainer.recordType, recordID: recordID)
record[CloudKitContainer.Fields.name] = name

View File

@ -17,9 +17,7 @@ import SyncDatabase
final class CloudKitArticlesZone: CloudKitZone {
static var zoneID: CKRecordZone.ID {
return CKRecordZone.ID(zoneName: "Articles", ownerName: CKCurrentUserDefaultName)
}
var zoneID: CKRecordZone.ID
var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit")
@ -58,6 +56,8 @@ final class CloudKitArticlesZone: CloudKitZone {
init(container: CKContainer) {
self.container = container
self.database = container.privateCloudDatabase
self.zoneID = CKRecordZone.ID(zoneName: "Articles", ownerName: CKCurrentUserDefaultName)
migrateChangeToken()
}
func refreshArticles(completion: @escaping ((Result<Void, Error>) -> Void)) {
@ -124,10 +124,10 @@ final class CloudKitArticlesZone: CloudKitZone {
newRecords.append(self.makeStatusRecord(statusUpdate))
newRecords.append(self.makeArticleRecord(statusUpdate.article!))
case .delete:
deleteRecordIDs.append(CKRecord.ID(recordName: self.statusID(statusUpdate.articleID), zoneID: Self.zoneID))
deleteRecordIDs.append(CKRecord.ID(recordName: self.statusID(statusUpdate.articleID), zoneID: zoneID))
case .statusOnly:
modifyRecords.append(self.makeStatusRecord(statusUpdate))
deleteRecordIDs.append(CKRecord.ID(recordName: self.articleID(statusUpdate.articleID), zoneID: Self.zoneID))
deleteRecordIDs.append(CKRecord.ID(recordName: self.articleID(statusUpdate.articleID), zoneID: zoneID))
}
}
@ -176,7 +176,7 @@ private extension CloudKitArticlesZone {
}
func makeStatusRecord(_ article: Article) -> CKRecord {
let recordID = CKRecord.ID(recordName: statusID(article.articleID), zoneID: Self.zoneID)
let recordID = CKRecord.ID(recordName: statusID(article.articleID), zoneID: zoneID)
let record = CKRecord(recordType: CloudKitArticleStatus.recordType, recordID: recordID)
if let webFeedExternalID = article.webFeed?.externalID {
record[CloudKitArticleStatus.Fields.webFeedExternalID] = webFeedExternalID
@ -187,7 +187,7 @@ private extension CloudKitArticlesZone {
}
func makeStatusRecord(_ statusUpdate: CloudKitArticleStatusUpdate) -> CKRecord {
let recordID = CKRecord.ID(recordName: statusID(statusUpdate.articleID), zoneID: Self.zoneID)
let recordID = CKRecord.ID(recordName: statusID(statusUpdate.articleID), zoneID: zoneID)
let record = CKRecord(recordType: CloudKitArticleStatus.recordType, recordID: recordID)
if let webFeedExternalID = statusUpdate.article?.webFeed?.externalID {
@ -201,10 +201,10 @@ private extension CloudKitArticlesZone {
}
func makeArticleRecord(_ article: Article) -> CKRecord {
let recordID = CKRecord.ID(recordName: articleID(article.articleID), zoneID: Self.zoneID)
let recordID = CKRecord.ID(recordName: articleID(article.articleID), zoneID: zoneID)
let record = CKRecord(recordType: CloudKitArticle.recordType, recordID: recordID)
let articleStatusRecordID = CKRecord.ID(recordName: statusID(article.articleID), zoneID: Self.zoneID)
let articleStatusRecordID = CKRecord.ID(recordName: statusID(article.articleID), zoneID: zoneID)
record[CloudKitArticle.Fields.articleStatus] = CKRecord.Reference(recordID: articleStatusRecordID, action: .deleteSelf)
record[CloudKitArticle.Fields.webFeedURL] = article.webFeed?.url
record[CloudKitArticle.Fields.uniqueID] = article.uniqueID

View File

@ -16,7 +16,7 @@ extension Notification.Name {
public static let ChildrenDidChange = Notification.Name("ChildrenDidChange")
}
public protocol Container: class, ContainerIdentifiable {
public protocol Container: AnyObject, ContainerIdentifiable {
var account: Account? { get }
var topLevelWebFeeds: Set<WebFeed> { get set }

View File

@ -8,7 +8,7 @@
import Foundation
public protocol FeedProviderManagerDelegate: class {
public protocol FeedProviderManagerDelegate: AnyObject {
var activeFeedProviders: [FeedProvider] { get }
}

View File

@ -11,7 +11,7 @@ import RSCore
import OAuthSwift
import Secrets
protocol RedditFeedProviderTokenRefreshOperationDelegate: class {
protocol RedditFeedProviderTokenRefreshOperationDelegate: AnyObject {
var username: String? { get }
var oauthTokenLastRefresh: Date? { get set }
var oauthToken: String { get set }

View File

@ -10,7 +10,7 @@ import Foundation
import RSWeb
import Secrets
protocol FeedlyAPICallerDelegate: class {
protocol FeedlyAPICallerDelegate: AnyObject {
/// Implemented by the `FeedlyAccountDelegate` reauthorize the client with a fresh OAuth token so the client can retry the unauthorized request.
/// Pass `true` to the completion handler if the failing request should be retried with a fresh token or `false` if the unauthorized request should complete with the original failure error.
func reauthorizeFeedlyAPICaller(_ caller: FeedlyAPICaller, completionHandler: @escaping (Bool) -> ())

View File

@ -8,7 +8,7 @@
import Foundation
protocol FeedlyEntryIdentifierProviding: class {
protocol FeedlyEntryIdentifierProviding: AnyObject {
var entryIds: Set<String> { get }
}

View File

@ -10,7 +10,7 @@ import Foundation
import AuthenticationServices
import RSCore
public protocol OAuthAccountAuthorizationOperationDelegate: class {
public protocol OAuthAccountAuthorizationOperationDelegate: AnyObject {
func oauthAccountAuthorizationOperation(_ operation: OAuthAccountAuthorizationOperation, didCreate account: Account)
func oauthAccountAuthorizationOperation(_ operation: OAuthAccountAuthorizationOperation, didFailWith error: Error)
}

View File

@ -40,7 +40,7 @@ public protocol OAuthAcessTokenRefreshRequesting {
}
/// Implemented by concrete types to perform the actual request.
protocol OAuthAccessTokenRefreshing: class {
protocol OAuthAccessTokenRefreshing: AnyObject {
func refreshAccessToken(with refreshToken: String, client: OAuthAuthorizationClient, completion: @escaping (Result<OAuthAuthorizationGrant, Error>) -> ())
}

View File

@ -8,7 +8,7 @@
import Foundation
protocol FeedlyCheckpointOperationDelegate: class {
protocol FeedlyCheckpointOperationDelegate: AnyObject {
func feedlyCheckpointOperationDidReachCheckpoint(_ operation: FeedlyCheckpointOperation)
}

View File

@ -9,7 +9,7 @@
import Foundation
import os.log
protocol FeedlyCollectionProviding: class {
protocol FeedlyCollectionProviding: AnyObject {
var collections: [FeedlyCollection] { get }
}

View File

@ -19,7 +19,7 @@ protocol FeedlyParsedItemProviding {
var parsedEntries: Set<ParsedItem> { get }
}
protocol FeedlyGetStreamContentsOperationDelegate: class {
protocol FeedlyGetStreamContentsOperationDelegate: AnyObject {
func feedlyGetStreamContentsOperation(_ operation: FeedlyGetStreamContentsOperation, didGetContentsOf stream: FeedlyStream)
}

View File

@ -9,7 +9,7 @@
import Foundation
import os.log
protocol FeedlyGetStreamIdsOperationDelegate: class {
protocol FeedlyGetStreamIdsOperationDelegate: AnyObject {
func feedlyGetStreamIdsOperation(_ operation: FeedlyGetStreamIdsOperation, didGet streamIds: FeedlyStreamIds)
}

View File

@ -10,7 +10,7 @@ import Foundation
import RSWeb
import RSCore
protocol FeedlyOperationDelegate: class {
protocol FeedlyOperationDelegate: AnyObject {
func feedlyOperation(_ operation: FeedlyOperation, didFailWith error: Error)
}

View File

@ -9,7 +9,7 @@
import Foundation
import os.log
protocol FeedlyRequestStreamsOperationDelegate: class {
protocol FeedlyRequestStreamsOperationDelegate: AnyObject {
func feedlyRequestStreamsOperation(_ operation: FeedlyRequestStreamsOperation, enqueue collectionStreamOperation: FeedlyGetStreamContentsOperation)
}

View File

@ -8,11 +8,11 @@
import Foundation
protocol FeedlySearchService: class {
protocol FeedlySearchService: AnyObject {
func getFeeds(for query: String, count: Int, locale: String, completion: @escaping (Result<FeedlyFeedsSearchResponse, Error>) -> ())
}
protocol FeedlySearchOperationDelegate: class {
protocol FeedlySearchOperationDelegate: AnyObject {
func feedlySearchOperation(_ operation: FeedlySearchOperation, didGet response: FeedlyFeedsSearchResponse)
}

View File

@ -8,6 +8,6 @@
import Foundation
protocol FeedlyGetCollectionsService: class {
protocol FeedlyGetCollectionsService: AnyObject {
func getCollections(completion: @escaping (Result<[FeedlyCollection], Error>) -> ())
}

View File

@ -8,6 +8,6 @@
import Foundation
protocol FeedlyGetEntriesService: class {
protocol FeedlyGetEntriesService: AnyObject {
func getEntries(for ids: Set<String>, completion: @escaping (Result<[FeedlyEntry], Error>) -> ())
}

View File

@ -8,6 +8,6 @@
import Foundation
protocol FeedlyGetStreamContentsService: class {
protocol FeedlyGetStreamContentsService: AnyObject {
func getStreamContents(for resource: FeedlyResourceId, continuation: String?, newerThan: Date?, unreadOnly: Bool?, completion: @escaping (Result<FeedlyStream, Error>) -> ())
}

View File

@ -8,6 +8,6 @@
import Foundation
protocol FeedlyGetStreamIdsService: class {
protocol FeedlyGetStreamIdsService: AnyObject {
func getStreamIds(for resource: FeedlyResourceId, continuation: String?, newerThan: Date?, unreadOnly: Bool?, completion: @escaping (Result<FeedlyStreamIds, Error>) -> ())
}

View File

@ -30,6 +30,6 @@ enum FeedlyMarkAction: String {
}
}
protocol FeedlyMarkArticlesService: class {
protocol FeedlyMarkArticlesService: AnyObject {
func mark(_ articleIds: Set<String>, as action: FeedlyMarkAction, completion: @escaping (Result<Void, Error>) -> ())
}

View File

@ -10,7 +10,7 @@ import Foundation
import RSWeb
import Articles
protocol WebFeedMetadataDelegate: class {
protocol WebFeedMetadataDelegate: AnyObject {
func valueDidChange(_ feedMetadata: WebFeedMetadata, key: WebFeedMetadata.CodingKeys)
}

View File

@ -10,7 +10,7 @@ import Foundation
import RSWeb
import XCTest
protocol TestTransportMockResponseProviding: class {
protocol TestTransportMockResponseProviding: AnyObject {
func mockResponseFileUrl(for components: URLComponents) -> URL?
}

View File

@ -11,7 +11,7 @@ let package = Package(
targets: ["Articles"]),
],
dependencies: [
.package(url: "https://github.com/Ranchero-Software/RSCore.git", .upToNextMajor(from: "1.0.0-beta1")),
.package(url: "https://github.com/Ranchero-Software/RSCore.git", .upToNextMajor(from: "1.0.0")),
],
targets: [
.target(

View File

@ -13,9 +13,9 @@ let package = Package(
targets: ["ArticlesDatabase"]),
],
dependencies: [
.package(url: "https://github.com/Ranchero-Software/RSCore.git", .upToNextMajor(from: "1.0.0-beta1")),
.package(url: "https://github.com/Ranchero-Software/RSDatabase.git", .upToNextMajor(from: "1.0.0-beta1")),
.package(url: "https://github.com/Ranchero-Software/RSParser.git", .upToNextMajor(from: "2.0.0-beta1")),
.package(url: "https://github.com/Ranchero-Software/RSCore.git", .upToNextMajor(from: "1.0.0")),
.package(url: "https://github.com/Ranchero-Software/RSDatabase.git", .upToNextMajor(from: "1.0.0")),
.package(url: "https://github.com/Ranchero-Software/RSParser.git", .upToNextMajor(from: "2.0.0")),
.package(url: "../Articles", .upToNextMajor(from: "1.0.0")),
],
targets: [

View File

@ -145,19 +145,36 @@ final class ArticlesTable: DatabaseTable {
}
// MARK: - Fetching Articles for Indexer
private func articleSearchInfosQuery(with placeholders: String) -> String {
return """
SELECT
art.articleID,
art.title,
art.contentHTML,
art.contentText,
art.summary,
art.searchRowID,
(SELECT GROUP_CONCAT(name, ' ')
FROM authorsLookup as autL
JOIN authors as aut ON autL.authorID = aut.authorID
WHERE art.articleID = autL.articleID
GROUP BY autl.articleID) as authors
FROM articles as art
WHERE articleID in \(placeholders);
"""
}
func fetchArticleSearchInfos(_ articleIDs: Set<String>, in database: FMDatabase) -> Set<ArticleSearchInfo>? {
let parameters = articleIDs.map { $0 as AnyObject }
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(articleIDs.count))!
let sql = "select articleID, title, contentHTML, contentText, summary, searchRowID from articles where articleID in \(placeholders);";
if let resultSet = database.executeQuery(sql, withArgumentsIn: parameters) {
if let resultSet = database.executeQuery(self.articleSearchInfosQuery(with: placeholders), withArgumentsIn: parameters) {
return resultSet.mapToSet { (row) -> ArticleSearchInfo? in
let articleID = row.string(forColumn: DatabaseKey.articleID)!
let title = row.string(forColumn: DatabaseKey.title)
let contentHTML = row.string(forColumn: DatabaseKey.contentHTML)
let contentText = row.string(forColumn: DatabaseKey.contentText)
let summary = row.string(forColumn: DatabaseKey.summary)
let authorsNames = row.string(forColumn: DatabaseKey.authors)
let searchRowIDObject = row.object(forColumnName: DatabaseKey.searchRowID)
var searchRowID: Int? = nil
@ -165,7 +182,7 @@ final class ArticlesTable: DatabaseTable {
searchRowID = Int(row.longLongInt(forColumn: DatabaseKey.searchRowID))
}
return ArticleSearchInfo(articleID: articleID, title: title, contentHTML: contentHTML, contentText: contentText, summary: summary, searchRowID: searchRowID)
return ArticleSearchInfo(articleID: articleID, title: title, contentHTML: contentHTML, contentText: contentText, summary: summary, authorsNames: authorsNames, searchRowID: searchRowID)
}
}
return nil

View File

@ -20,6 +20,7 @@ final class ArticleSearchInfo: Hashable {
let contentHTML: String?
let contentText: String?
let summary: String?
let authorsNames: String?
let searchRowID: Int?
var preferredText: String {
@ -34,12 +35,19 @@ final class ArticleSearchInfo: Hashable {
lazy var bodyForIndex: String = {
let s = preferredText.rsparser_stringByDecodingHTMLEntities()
return s.strippingHTML().collapsingWhitespace
let sanitizedBody = s.strippingHTML().collapsingWhitespace
if let authorsNames = authorsNames {
return sanitizedBody.appending(" \(authorsNames)")
} else {
return sanitizedBody
}
}()
init(articleID: String, title: String?, contentHTML: String?, contentText: String?, summary: String?, searchRowID: Int?) {
init(articleID: String, title: String?, contentHTML: String?, contentText: String?, summary: String?, authorsNames: String?, searchRowID: Int?) {
self.articleID = articleID
self.title = title
self.authorsNames = authorsNames
self.contentHTML = contentHTML
self.contentText = contentText
self.summary = summary
@ -47,7 +55,13 @@ final class ArticleSearchInfo: Hashable {
}
convenience init(article: Article) {
self.init(articleID: article.articleID, title: article.title, contentHTML: article.contentHTML, contentText: article.contentText, summary: article.summary, searchRowID: nil)
let authorsNames: String?
if let authors = article.authors {
authorsNames = authors.compactMap({ $0.name }).joined(separator: " ")
} else {
authorsNames = nil
}
self.init(articleID: article.articleID, title: article.title, contentHTML: article.contentHTML, contentText: article.contentText, summary: article.summary, authorsNames: authorsNames, searchRowID: nil)
}
// MARK: Hashable
@ -59,7 +73,7 @@ final class ArticleSearchInfo: Hashable {
// MARK: Equatable
static func == (lhs: ArticleSearchInfo, rhs: ArticleSearchInfo) -> Bool {
return lhs.articleID == rhs.articleID && lhs.title == rhs.title && lhs.contentHTML == rhs.contentHTML && lhs.contentText == rhs.contentText && lhs.summary == rhs.summary && lhs.searchRowID == rhs.searchRowID
return lhs.articleID == rhs.articleID && lhs.title == rhs.title && lhs.contentHTML == rhs.contentHTML && lhs.contentText == rhs.contentText && lhs.summary == rhs.summary && lhs.authorsNames == rhs.authorsNames && lhs.searchRowID == rhs.searchRowID
}
}

View File

@ -8,7 +8,7 @@
import AppKit
protocol Inspector: class {
protocol Inspector: AnyObject {
var objects: [Any]? { get set }
var isFallbackInspector: Bool { get } // Can handle nothing-to-inspect or unexpected type of objects.

View File

@ -15,7 +15,7 @@ enum AddFeedWindowControllerType {
case twitterFeed
}
protocol AddFeedWindowControllerDelegate: class {
protocol AddFeedWindowControllerDelegate: AnyObject {
// userEnteredURL will have already been validated and normalized.
func addFeedWindowController(_: AddFeedWindowController, userEnteredURL: URL, userEnteredTitle: String?, container: Container)

View File

@ -12,7 +12,7 @@ import RSCore
import RSWeb
import Articles
protocol DetailWebViewControllerDelegate: class {
protocol DetailWebViewControllerDelegate: AnyObject {
func mouseDidEnter(_: DetailWebViewController, link: String)
func mouseDidExit(_: DetailWebViewController, link: String)
}

View File

@ -62,14 +62,12 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations {
sharingServicePickerDelegate = SharingServicePickerDelegate(self.window)
if #available(macOS 11.0, *) {
DispatchQueue.main.async {
let toolbar = NSToolbar(identifier: "MainWindowToolbar")
toolbar.allowsUserCustomization = true
toolbar.autosavesConfiguration = true
toolbar.displayMode = .iconOnly
toolbar.delegate = self
self.window?.toolbar = toolbar
}
let toolbar = NSToolbar(identifier: "MainWindowToolbar")
toolbar.allowsUserCustomization = true
toolbar.autosavesConfiguration = true
toolbar.displayMode = .iconOnly
toolbar.delegate = self
self.window?.toolbar = toolbar
} else {
if !AppDefaults.shared.showTitleOnMainWindow {
window?.titleVisibility = .hidden

View File

@ -490,10 +490,8 @@ private extension SidebarOutlineDataSource {
return
}
BatchUpdate.shared.start()
replicateFolder(sourceFolder, destinationAccount: destinationAccount) {
sourceAccount.removeFolder(sourceFolder) { result in
BatchUpdate.shared.end()
switch result {
case .success:
break

View File

@ -16,7 +16,7 @@ extension Notification.Name {
static let appleSideBarDefaultIconSizeChanged = Notification.Name("AppleSideBarDefaultIconSizeChanged")
}
protocol SidebarDelegate: class {
protocol SidebarDelegate: AnyObject {
func sidebarSelectionDidChange(_: SidebarViewController, selectedObjects: [AnyObject]?)
func unreadCount(for: AnyObject) -> Int
func sidebarInvalidatedRestorationState(_: SidebarViewController)

View File

@ -10,7 +10,7 @@ import AppKit
import Account
import Articles
protocol TimelineContainerViewControllerDelegate: class {
protocol TimelineContainerViewControllerDelegate: AnyObject {
func timelineSelectionDidChange(_: TimelineContainerViewController, articles: [Article]?, mode: TimelineSourceMode)
func timelineRequestedWebFeedSelection(_: TimelineContainerViewController, webFeed: WebFeed)
func timelineInvalidatedRestorationState(_: TimelineContainerViewController)

View File

@ -12,7 +12,7 @@ import Articles
import Account
import os.log
protocol TimelineDelegate: class {
protocol TimelineDelegate: AnyObject {
func timelineSelectionDidChange(_: TimelineViewController, selectedArticles: [Article]?)
func timelineRequestedWebFeedSelection(_: TimelineViewController, webFeed: WebFeed)
func timelineInvalidatedRestorationState(_: TimelineViewController)

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -18,7 +18,7 @@
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="398" height="135"/>
<rect key="screenRect" x="0.0" y="0.0" width="1792" height="1095"/>
<rect key="screenRect" x="0.0" y="0.0" width="1536" height="935"/>
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="398" height="135"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@ -92,7 +92,7 @@ Gw
<constraint firstItem="9eG-vV-s8c" firstAttribute="top" secondItem="3Kj-Cl-FJQ" secondAttribute="bottom" constant="19" id="VYR-uJ-Qmy"/>
<constraint firstItem="xqo-gP-MPl" firstAttribute="top" secondItem="3Kj-Cl-FJQ" secondAttribute="bottom" constant="19" id="mg9-pV-zid"/>
<constraint firstItem="9eG-vV-s8c" firstAttribute="width" secondItem="xqo-gP-MPl" secondAttribute="width" id="oNb-To-cBK"/>
<constraint firstItem="xqo-gP-MPl" firstAttribute="leading" secondItem="9eG-vV-s8c" secondAttribute="trailing" constant="12" id="p6M-6b-ybu"/>
<constraint firstItem="xqo-gP-MPl" firstAttribute="leading" secondItem="9eG-vV-s8c" secondAttribute="trailing" constant="12" symbolic="YES" id="p6M-6b-ybu"/>
<constraint firstItem="uDK-ji-zlT" firstAttribute="centerX" secondItem="EiT-Mj-1SZ" secondAttribute="centerX" id="uXu-yF-PBG"/>
<constraint firstItem="ySx-qg-WbT" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="14" id="xee-QN-iej"/>
<constraint firstAttribute="trailing" secondItem="80D-3X-rL2" secondAttribute="trailing" constant="20" symbolic="YES" id="xzC-kN-UlB"/>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -19,7 +19,7 @@
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="398" height="205"/>
<rect key="screenRect" x="0.0" y="0.0" width="1792" height="1095"/>
<rect key="screenRect" x="0.0" y="0.0" width="1536" height="935"/>
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="398" height="205"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@ -31,7 +31,10 @@
<rect key="frame" x="199" y="95" width="0.0" height="21"/>
</stackView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xqo-gP-MPl">
<rect key="frame" x="310" y="13" width="75" height="32"/>
<rect key="frame" x="309" y="13" width="76" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="62" id="i5E-OP-URn"/>
</constraints>
<buttonCell key="cell" type="push" title="Create" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="oih-6c-KbS">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -44,7 +47,7 @@ DQ
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9eG-vV-s8c">
<rect key="frame" x="237" y="13" width="76" height="32"/>
<rect key="frame" x="235" y="13" width="76" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="iVd-bO-4LN">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -114,12 +117,13 @@ Gw
<constraint firstItem="80D-3X-rL2" firstAttribute="leading" secondItem="ySx-qg-WbT" secondAttribute="trailing" constant="19" id="Kuc-ym-H5a"/>
<constraint firstItem="3Kj-Cl-FJQ" firstAttribute="leading" secondItem="ySx-qg-WbT" secondAttribute="trailing" constant="19" id="Pwn-uQ-qtc"/>
<constraint firstItem="3Kj-Cl-FJQ" firstAttribute="top" secondItem="80D-3X-rL2" secondAttribute="bottom" constant="8" symbolic="YES" id="Rcn-2y-Jkt"/>
<constraint firstItem="9eG-vV-s8c" firstAttribute="width" secondItem="xqo-gP-MPl" secondAttribute="width" id="RuZ-Jv-xVJ"/>
<constraint firstItem="f9b-FM-i8Q" firstAttribute="bottom" secondItem="6Q7-nI-h5u" secondAttribute="bottom" id="Udo-Yg-xOC"/>
<constraint firstItem="ySx-qg-WbT" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" symbolic="YES" id="cSC-er-N4i"/>
<constraint firstItem="ySx-qg-WbT" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" symbolic="YES" id="dmH-e1-X3W"/>
<constraint firstItem="f9b-FM-i8Q" firstAttribute="top" secondItem="6Q7-nI-h5u" secondAttribute="top" id="neW-V1-13e"/>
<constraint firstItem="f9b-FM-i8Q" firstAttribute="leading" secondItem="MWg-UL-xtj" secondAttribute="trailing" constant="8" symbolic="YES" id="p3J-6S-ITL"/>
<constraint firstItem="xqo-gP-MPl" firstAttribute="leading" secondItem="9eG-vV-s8c" secondAttribute="trailing" constant="11" id="p6M-6b-ybu"/>
<constraint firstItem="xqo-gP-MPl" firstAttribute="leading" secondItem="9eG-vV-s8c" secondAttribute="trailing" constant="12" symbolic="YES" id="p6M-6b-ybu"/>
<constraint firstItem="f9b-FM-i8Q" firstAttribute="baseline" secondItem="MWg-UL-xtj" secondAttribute="baseline" id="pz0-6G-uO5"/>
<constraint firstItem="80D-3X-rL2" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" symbolic="YES" id="qaR-ST-LnB"/>
<constraint firstItem="uDK-ji-zlT" firstAttribute="centerX" secondItem="EiT-Mj-1SZ" secondAttribute="centerX" id="uXu-yF-PBG"/>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -26,7 +26,7 @@
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="433" height="249"/>
<rect key="screenRect" x="0.0" y="0.0" width="1792" height="1095"/>
<rect key="screenRect" x="0.0" y="0.0" width="1536" height="935"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="433" height="249"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@ -97,8 +97,11 @@
</gridCells>
</gridView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9mz-D9-krh">
<rect key="frame" x="347" y="13" width="73" height="32"/>
<buttonCell key="cell" type="push" title="Action" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="IMO-YT-k9Z">
<rect key="frame" x="344" y="13" width="76" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="62" id="KMy-Qk-maN"/>
</constraints>
<buttonCell key="cell" type="push" title="Create" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="IMO-YT-k9Z">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
@ -110,7 +113,7 @@ DQ
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XAM-Hb-0Hw">
<rect key="frame" x="273" y="13" width="76" height="32"/>
<rect key="frame" x="270" y="13" width="76" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="ufs-ar-BAY">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -173,17 +176,14 @@ Gw
</textFieldCell>
</textField>
<progressIndicator hidden="YES" wantsLayer="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="100" displayedWhenStopped="NO" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="B0W-bh-Evv">
<rect key="frame" x="256" y="22" width="16" height="16"/>
<rect key="frame" x="253" y="22" width="16" height="16"/>
<constraints>
<constraint firstAttribute="width" constant="16" id="ggl-Gq-PUV"/>
<constraint firstAttribute="height" constant="16" id="m1z-4y-g41"/>
</constraints>
</progressIndicator>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="zwG-Ag-z8o">
<rect key="frame" x="18" y="23" width="230" height="14"/>
<constraints>
<constraint firstAttribute="width" constant="226" id="jvg-qt-4RV"/>
</constraints>
<rect key="frame" x="78" y="60" width="337" height="14"/>
<textFieldCell key="cell" id="b2G-2g-1KR">
<font key="font" textStyle="subheadline" name=".SFNS-Regular"/>
<color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
@ -192,14 +192,17 @@ Gw
</textField>
</subviews>
<constraints>
<constraint firstItem="9mz-D9-krh" firstAttribute="leading" secondItem="XAM-Hb-0Hw" secondAttribute="trailing" constant="12" symbolic="YES" id="1li-1u-jpf"/>
<constraint firstItem="zwG-Ag-z8o" firstAttribute="leading" secondItem="Uzn-QS-o4p" secondAttribute="leading" id="2gp-cR-WV4"/>
<constraint firstItem="Ssh-Dh-xbg" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" symbolic="YES" id="3dK-9R-7wX"/>
<constraint firstItem="lti-yM-8LV" firstAttribute="leading" secondItem="Ssh-Dh-xbg" secondAttribute="trailing" constant="10" id="8qB-Qh-zBJ"/>
<constraint firstAttribute="trailing" secondItem="zwG-Ag-z8o" secondAttribute="trailing" constant="20" symbolic="YES" id="BVi-6b-iOO"/>
<constraint firstItem="9mz-D9-krh" firstAttribute="leading" secondItem="XAM-Hb-0Hw" secondAttribute="trailing" constant="12" symbolic="YES" id="CC8-HR-FDy"/>
<constraint firstItem="xEl-Ae-5r8" firstAttribute="top" secondItem="lti-yM-8LV" secondAttribute="bottom" constant="5" id="FOT-OS-h0G"/>
<constraint firstAttribute="trailing" secondItem="lti-yM-8LV" secondAttribute="trailing" constant="20" symbolic="YES" id="Hxs-l1-XFt"/>
<constraint firstItem="B0W-bh-Evv" firstAttribute="leading" secondItem="zwG-Ag-z8o" secondAttribute="trailing" constant="10" id="Kyv-Pw-z56"/>
<constraint firstItem="Uzn-QS-o4p" firstAttribute="leading" secondItem="Ssh-Dh-xbg" secondAttribute="trailing" constant="10" id="Lm2-GS-vEg"/>
<constraint firstItem="XAM-Hb-0Hw" firstAttribute="centerY" secondItem="9mz-D9-krh" secondAttribute="centerY" id="M2M-fb-kfR"/>
<constraint firstItem="zwG-Ag-z8o" firstAttribute="top" secondItem="Uzn-QS-o4p" secondAttribute="bottom" constant="-1" id="MII-TX-oBl"/>
<constraint firstItem="pPT-Cj-3vI" firstAttribute="leading" secondItem="xEl-Ae-5r8" secondAttribute="trailing" constant="1" id="NXU-SK-5WO"/>
<constraint firstAttribute="bottom" secondItem="9mz-D9-krh" secondAttribute="bottom" constant="20" id="PK2-Ye-400"/>
<constraint firstItem="pPT-Cj-3vI" firstAttribute="centerY" secondItem="xEl-Ae-5r8" secondAttribute="centerY" id="XKR-hU-WpE"/>
@ -208,14 +211,12 @@ Gw
<constraint firstItem="Ssh-Dh-xbg" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="dDr-Rs-AyZ"/>
<constraint firstAttribute="bottom" secondItem="B0W-bh-Evv" secondAttribute="bottom" constant="22" id="dzj-Jm-8mI"/>
<constraint firstItem="lti-yM-8LV" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="eIn-Pl-krd"/>
<constraint firstItem="zwG-Ag-z8o" firstAttribute="centerY" secondItem="XAM-Hb-0Hw" secondAttribute="centerY" id="ed6-s2-xPp"/>
<constraint firstAttribute="trailing" secondItem="9mz-D9-krh" secondAttribute="trailing" constant="20" id="fVQ-zN-rKd"/>
<constraint firstItem="7Ht-Fn-0Ya" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" id="jlY-Jg-KJR"/>
<constraint firstItem="zBB-JH-huI" firstAttribute="top" secondItem="xEl-Ae-5r8" secondAttribute="bottom" constant="17" id="rbr-SG-72y"/>
<constraint firstItem="7Ht-Fn-0Ya" firstAttribute="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" id="tAZ-Te-w3H"/>
<constraint firstItem="zBB-JH-huI" firstAttribute="leading" secondItem="Ssh-Dh-xbg" secondAttribute="trailing" constant="10" id="wWG-kT-6M7"/>
<constraint firstItem="xEl-Ae-5r8" firstAttribute="leading" secondItem="Ssh-Dh-xbg" secondAttribute="trailing" constant="10" id="zAY-I9-eKa"/>
<constraint firstItem="zwG-Ag-z8o" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" symbolic="YES" id="zDh-um-1B7"/>
</constraints>
</view>
<connections>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -26,7 +26,7 @@
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="433" height="249"/>
<rect key="screenRect" x="0.0" y="0.0" width="1792" height="1095"/>
<rect key="screenRect" x="0.0" y="0.0" width="1536" height="935"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="433" height="249"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@ -97,8 +97,11 @@
</gridCells>
</gridView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9mz-D9-krh">
<rect key="frame" x="347" y="13" width="73" height="32"/>
<buttonCell key="cell" type="push" title="Action" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="IMO-YT-k9Z">
<rect key="frame" x="344" y="13" width="76" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="62" id="hU1-wc-ebZ"/>
</constraints>
<buttonCell key="cell" type="push" title="Create" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="IMO-YT-k9Z">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
@ -110,7 +113,7 @@ DQ
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XAM-Hb-0Hw">
<rect key="frame" x="273" y="13" width="76" height="32"/>
<rect key="frame" x="270" y="13" width="76" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="ufs-ar-BAY">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -173,17 +176,14 @@ Gw
</connections>
</button>
<progressIndicator hidden="YES" wantsLayer="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="100" displayedWhenStopped="NO" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="B0W-bh-Evv">
<rect key="frame" x="256" y="22" width="16" height="16"/>
<rect key="frame" x="253" y="22" width="16" height="16"/>
<constraints>
<constraint firstAttribute="width" constant="16" id="Tcz-vj-cLr"/>
<constraint firstAttribute="height" constant="16" id="slt-7y-Jw0"/>
</constraints>
</progressIndicator>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="sPC-hi-ewD">
<rect key="frame" x="27" y="23" width="223" height="14"/>
<constraints>
<constraint firstAttribute="width" constant="219" id="1jw-Q0-cm5"/>
</constraints>
<rect key="frame" x="78" y="60" width="337" height="14"/>
<textFieldCell key="cell" lineBreakMode="clipping" id="sl9-fG-jwg">
<font key="font" textStyle="subheadline" name=".SFNS-Regular"/>
<color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
@ -197,20 +197,21 @@ Gw
<constraint firstItem="gEK-TH-URn" firstAttribute="top" secondItem="lti-yM-8LV" secondAttribute="bottom" constant="5" id="6gj-jv-thI"/>
<constraint firstAttribute="trailing" secondItem="lti-yM-8LV" secondAttribute="trailing" constant="20" symbolic="YES" id="Bvl-lx-VMh"/>
<constraint firstItem="9mz-D9-krh" firstAttribute="leading" secondItem="XAM-Hb-0Hw" secondAttribute="trailing" constant="12" symbolic="YES" id="CC8-HR-FDy"/>
<constraint firstItem="sPC-hi-ewD" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="29" id="DFv-ba-n2r"/>
<constraint firstItem="lti-yM-8LV" firstAttribute="leading" secondItem="Ssh-Dh-xbg" secondAttribute="trailing" constant="10" id="DGC-SC-Klr"/>
<constraint firstItem="sPC-hi-ewD" firstAttribute="centerY" secondItem="XAM-Hb-0Hw" secondAttribute="centerY" id="GAG-BE-Cdn"/>
<constraint firstItem="Ssh-Dh-xbg" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" symbolic="YES" id="HFJ-XG-KGU"/>
<constraint firstItem="XAM-Hb-0Hw" firstAttribute="centerY" secondItem="9mz-D9-krh" secondAttribute="centerY" id="M2M-fb-kfR"/>
<constraint firstAttribute="bottom" secondItem="9mz-D9-krh" secondAttribute="bottom" constant="20" id="PK2-Ye-400"/>
<constraint firstAttribute="trailing" secondItem="sPC-hi-ewD" secondAttribute="trailing" constant="20" symbolic="YES" id="Q7Z-cX-m74"/>
<constraint firstItem="B0W-bh-Evv" firstAttribute="centerY" secondItem="XAM-Hb-0Hw" secondAttribute="centerY" id="YYi-d9-Ykb"/>
<constraint firstItem="lti-yM-8LV" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="a2m-T4-Cvm"/>
<constraint firstItem="Ssh-Dh-xbg" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="17" id="er0-pf-nSm"/>
<constraint firstItem="XAM-Hb-0Hw" firstAttribute="width" secondItem="9mz-D9-krh" secondAttribute="width" id="f9X-ws-A5r"/>
<constraint firstAttribute="trailing" secondItem="9mz-D9-krh" secondAttribute="trailing" constant="20" id="fVQ-zN-rKd"/>
<constraint firstItem="7Ht-Fn-0Ya" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" id="jlY-Jg-KJR"/>
<constraint firstItem="B0W-bh-Evv" firstAttribute="leading" secondItem="sPC-hi-ewD" secondAttribute="trailing" constant="8" symbolic="YES" id="jvz-NC-C9Q"/>
<constraint firstItem="sPC-hi-ewD" firstAttribute="leading" secondItem="X1Z-v1-T5L" secondAttribute="leading" id="k5v-X1-kV0"/>
<constraint firstItem="MlB-jN-Ybe" firstAttribute="leading" secondItem="gEK-TH-URn" secondAttribute="trailing" constant="-1" id="o73-Mf-NOJ"/>
<constraint firstItem="zBB-JH-huI" firstAttribute="top" secondItem="gEK-TH-URn" secondAttribute="bottom" constant="17" id="rZU-JI-MfQ"/>
<constraint firstItem="sPC-hi-ewD" firstAttribute="top" secondItem="X1Z-v1-T5L" secondAttribute="bottom" constant="8" symbolic="YES" id="reY-pG-5fx"/>
<constraint firstItem="7Ht-Fn-0Ya" firstAttribute="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" constant="16.5" id="tAZ-Te-w3H"/>
<constraint firstItem="XAM-Hb-0Hw" firstAttribute="leading" secondItem="B0W-bh-Evv" secondAttribute="trailing" constant="8" symbolic="YES" id="uTp-NW-oDs"/>
<constraint firstItem="zBB-JH-huI" firstAttribute="leading" secondItem="Ssh-Dh-xbg" secondAttribute="trailing" constant="10" id="uzf-L9-WGW"/>
@ -225,7 +226,7 @@ Gw
</window>
</objects>
<resources>
<image name="accountFeedbin" width="369" height="343"/>
<image name="accountFeedbin" width="25" height="25"/>
<namedColor name="AccentColor">
<color red="0.030999999493360519" green="0.41600000858306885" blue="0.93300002813339233" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -26,7 +26,7 @@
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="433" height="249"/>
<rect key="screenRect" x="0.0" y="0.0" width="1792" height="1095"/>
<rect key="screenRect" x="0.0" y="0.0" width="1536" height="935"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="433" height="249"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@ -97,8 +97,11 @@
</gridCells>
</gridView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9mz-D9-krh">
<rect key="frame" x="347" y="13" width="73" height="32"/>
<buttonCell key="cell" type="push" title="Action" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="IMO-YT-k9Z">
<rect key="frame" x="347" y="13" width="76" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="62" id="stL-0v-emB"/>
</constraints>
<buttonCell key="cell" type="push" title="Create" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="IMO-YT-k9Z">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
@ -122,7 +125,7 @@ Gw
<action selector="cancel:" target="-2" id="WAD-ES-hpq"/>
</connections>
</button>
<progressIndicator hidden="YES" wantsLayer="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="100" displayedWhenStopped="NO" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="B0W-bh-Evv">
<progressIndicator hidden="YES" wantsLayer="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" ambiguous="YES" maxValue="100" displayedWhenStopped="NO" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="B0W-bh-Evv">
<rect key="frame" x="256" y="22" width="16" height="16"/>
<constraints>
<constraint firstAttribute="height" constant="16" id="Cew-Vp-UKw"/>
@ -180,10 +183,7 @@ Gw
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="tFv-QN-zMA">
<rect key="frame" x="20" y="22" width="230" height="14"/>
<constraints>
<constraint firstAttribute="width" constant="226" id="7XO-aQ-XFv"/>
</constraints>
<rect key="frame" x="78" y="60" width="337" height="14"/>
<textFieldCell key="cell" lineBreakMode="clipping" id="yQ5-2h-Y9i">
<font key="font" textStyle="subheadline" name=".SFNS-Regular"/>
<color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
@ -192,9 +192,8 @@ Gw
</textField>
</subviews>
<constraints>
<constraint firstItem="tFv-QN-zMA" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="22" id="0vw-sR-47d"/>
<constraint firstItem="OMB-u7-kzz" firstAttribute="top" secondItem="JSa-LY-zNQ" secondAttribute="bottom" constant="15" id="5YM-1I-eNA"/>
<constraint firstAttribute="bottom" secondItem="tFv-QN-zMA" secondAttribute="bottom" constant="22" id="8K5-dH-2jc"/>
<constraint firstItem="XAM-Hb-0Hw" firstAttribute="width" secondItem="9mz-D9-krh" secondAttribute="width" id="5zb-d0-icM"/>
<constraint firstItem="9mz-D9-krh" firstAttribute="leading" secondItem="XAM-Hb-0Hw" secondAttribute="trailing" constant="12" symbolic="YES" id="CC8-HR-FDy"/>
<constraint firstItem="yqn-od-aLJ" firstAttribute="leading" secondItem="Ssh-Dh-xbg" secondAttribute="trailing" constant="10" id="FVS-Uu-8cX"/>
<constraint firstAttribute="trailing" secondItem="lti-yM-8LV" secondAttribute="trailing" constant="27" id="J9X-fP-LuZ"/>
@ -204,16 +203,18 @@ Gw
<constraint firstAttribute="bottom" secondItem="9mz-D9-krh" secondAttribute="bottom" constant="20" id="PK2-Ye-400"/>
<constraint firstItem="9oE-Gq-qp7" firstAttribute="centerY" secondItem="yqn-od-aLJ" secondAttribute="centerY" id="VJR-Vq-lRi"/>
<constraint firstItem="Ssh-Dh-xbg" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" symbolic="YES" id="XLG-4y-Pfd"/>
<constraint firstItem="tFv-QN-zMA" firstAttribute="top" secondItem="OMB-u7-kzz" secondAttribute="bottom" constant="-1" id="bCa-er-58P"/>
<constraint firstItem="lti-yM-8LV" firstAttribute="leading" secondItem="Ssh-Dh-xbg" secondAttribute="trailing" constant="10" id="eNp-CL-ocA"/>
<constraint firstItem="zBB-JH-huI" firstAttribute="top" secondItem="yqn-od-aLJ" secondAttribute="bottom" constant="17" id="fO2-t2-I4M"/>
<constraint firstAttribute="trailing" secondItem="9mz-D9-krh" secondAttribute="trailing" constant="20" id="fVQ-zN-rKd"/>
<constraint firstAttribute="trailing" secondItem="9mz-D9-krh" secondAttribute="trailing" constant="17" id="fVQ-zN-rKd"/>
<constraint firstItem="7Ht-Fn-0Ya" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" id="jlY-Jg-KJR"/>
<constraint firstItem="OMB-u7-kzz" firstAttribute="leading" secondItem="Ssh-Dh-xbg" secondAttribute="trailing" constant="10" id="jm9-kY-iQy"/>
<constraint firstItem="lti-yM-8LV" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="kLe-eK-uhH"/>
<constraint firstItem="9oE-Gq-qp7" firstAttribute="leading" secondItem="yqn-od-aLJ" secondAttribute="trailing" constant="1" id="ks3-4Y-649"/>
<constraint firstItem="B0W-bh-Evv" firstAttribute="leading" secondItem="tFv-QN-zMA" secondAttribute="trailing" constant="8" symbolic="YES" id="oDj-tr-QWc"/>
<constraint firstItem="7Ht-Fn-0Ya" firstAttribute="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" id="tAZ-Te-w3H"/>
<constraint firstItem="B0W-bh-Evv" firstAttribute="centerY" secondItem="XAM-Hb-0Hw" secondAttribute="centerY" id="uUt-Cg-PFc"/>
<constraint firstAttribute="trailing" secondItem="tFv-QN-zMA" secondAttribute="trailing" constant="20" symbolic="YES" id="vcr-wm-2Jq"/>
<constraint firstItem="tFv-QN-zMA" firstAttribute="leading" secondItem="OMB-u7-kzz" secondAttribute="leading" id="wcq-Wf-8rw"/>
<constraint firstItem="Ssh-Dh-xbg" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="xUF-s0-Ews"/>
</constraints>
</view>
@ -224,7 +225,7 @@ Gw
</window>
</objects>
<resources>
<image name="accountNewsBlur" width="25" height="25"/>
<image name="accountNewsBlur" width="50" height="50"/>
<namedColor name="AccentColor">
<color red="0.030999999493360519" green="0.41600000858306885" blue="0.93300002813339233" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -29,17 +29,17 @@
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="433" height="249"/>
<rect key="screenRect" x="0.0" y="0.0" width="1792" height="1095"/>
<rect key="contentRect" x="196" y="240" width="433" height="275"/>
<rect key="screenRect" x="0.0" y="0.0" width="1536" height="935"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="433" height="249"/>
<rect key="frame" x="0.0" y="0.0" width="433" height="275"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView distribution="fill" orientation="horizontal" alignment="bottom" spacing="19" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7Ht-Fn-0Ya">
<rect key="frame" x="217" y="229" width="0.0" height="0.0"/>
<rect key="frame" x="217" y="255" width="0.0" height="0.0"/>
</stackView>
<gridView xPlacement="trailing" yPlacement="center" rowAlignment="none" rowSpacing="7" columnSpacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="zBB-JH-huI">
<rect key="frame" x="80" y="99" width="270" height="77"/>
<rect key="frame" x="80" y="125" width="270" height="77"/>
<rows>
<gridRow id="DRl-lC-vUc"/>
<gridRow id="eW8-uH-txq"/>
@ -125,8 +125,11 @@
</gridCells>
</gridView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9mz-D9-krh">
<rect key="frame" x="347" y="13" width="73" height="32"/>
<buttonCell key="cell" type="push" title="Action" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="IMO-YT-k9Z">
<rect key="frame" x="347" y="13" width="76" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="62" id="afy-Zh-DIy"/>
</constraints>
<buttonCell key="cell" type="push" title="Create" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="IMO-YT-k9Z">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
@ -158,7 +161,7 @@ Gw
</constraints>
</progressIndicator>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Ssh-Dh-xbg">
<rect key="frame" x="20" y="179" width="50" height="50"/>
<rect key="frame" x="20" y="205" width="50" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="NYV-hM-AYz"/>
<constraint firstAttribute="width" constant="50" id="qWk-4n-LXb"/>
@ -166,7 +169,7 @@ Gw
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" id="y38-YL-woC"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lti-yM-8LV">
<rect key="frame" x="78" y="213" width="337" height="16"/>
<rect key="frame" x="78" y="239" width="337" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Sign in to a Reader API account." id="ras-dj-nP8">
<font key="font" textStyle="headline" name=".SFNS-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -174,7 +177,7 @@ Gw
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="R8e-67-Bwh">
<rect key="frame" x="78" y="193" width="174" height="15"/>
<rect key="frame" x="78" y="219" width="174" height="15"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Don't have a Reader account?" id="ker-hu-FEc">
<font key="font" textStyle="callout" name=".SFNS-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -182,7 +185,7 @@ Gw
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kUQ-aj-Iu6">
<rect key="frame" x="251" y="194" width="99" height="13"/>
<rect key="frame" x="251" y="220" width="99" height="13"/>
<constraints>
<constraint firstAttribute="height" constant="13" id="NOr-5b-kRd"/>
</constraints>
@ -196,7 +199,7 @@ Gw
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="q5z-LG-0Fm">
<rect key="frame" x="78" y="45" width="337" height="39"/>
<rect key="frame" x="78" y="71" width="337" height="39"/>
<constraints>
<constraint firstAttribute="height" constant="39" id="Zv4-mj-po0"/>
<constraint firstAttribute="width" constant="333" id="xsi-I6-XNM"/>
@ -208,10 +211,7 @@ Gw
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Gyz-Mz-v08">
<rect key="frame" x="18" y="23" width="230" height="14"/>
<constraints>
<constraint firstAttribute="width" constant="226" id="0Fh-f0-A3K"/>
</constraints>
<rect key="frame" x="78" y="55" width="337" height="14"/>
<textFieldCell key="cell" id="AGV-EV-VmY">
<font key="font" textStyle="subheadline" name=".SFNS-Regular"/>
<color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
@ -232,15 +232,16 @@ Gw
<constraint firstAttribute="trailing" secondItem="lti-yM-8LV" secondAttribute="trailing" constant="20" symbolic="YES" id="CeA-ET-oeg"/>
<constraint firstItem="Ssh-Dh-xbg" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="EKF-Yq-DxZ"/>
<constraint firstItem="q5z-LG-0Fm" firstAttribute="top" secondItem="zBB-JH-huI" secondAttribute="bottom" constant="15" id="Hdb-dd-lM9"/>
<constraint firstItem="B0W-bh-Evv" firstAttribute="leading" secondItem="Gyz-Mz-v08" secondAttribute="trailing" constant="10" id="IUE-sL-VHF"/>
<constraint firstItem="XAM-Hb-0Hw" firstAttribute="width" secondItem="9mz-D9-krh" secondAttribute="width" multiplier="0.951613" constant="3" id="IN4-Kx-qyK"/>
<constraint firstItem="XAM-Hb-0Hw" firstAttribute="centerY" secondItem="9mz-D9-krh" secondAttribute="centerY" id="M2M-fb-kfR"/>
<constraint firstItem="zBB-JH-huI" firstAttribute="leading" secondItem="R8e-67-Bwh" secondAttribute="leading" id="Mqa-R7-znW"/>
<constraint firstAttribute="bottom" secondItem="9mz-D9-krh" secondAttribute="bottom" constant="20" id="PK2-Ye-400"/>
<constraint firstItem="Gyz-Mz-v08" firstAttribute="top" secondItem="q5z-LG-0Fm" secondAttribute="bottom" constant="2" id="UVQ-eH-uwR"/>
<constraint firstItem="R8e-67-Bwh" firstAttribute="leading" secondItem="Ssh-Dh-xbg" secondAttribute="trailing" constant="10" id="ah8-Mj-rXV"/>
<constraint firstItem="Gyz-Mz-v08" firstAttribute="centerY" secondItem="XAM-Hb-0Hw" secondAttribute="centerY" id="cSM-1G-AUG"/>
<constraint firstAttribute="trailing" secondItem="9mz-D9-krh" secondAttribute="trailing" constant="20" id="fVQ-zN-rKd"/>
<constraint firstAttribute="trailing" secondItem="9mz-D9-krh" secondAttribute="trailing" constant="17" id="fVQ-zN-rKd"/>
<constraint firstItem="7Ht-Fn-0Ya" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" id="jlY-Jg-KJR"/>
<constraint firstItem="Gyz-Mz-v08" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" symbolic="YES" id="p26-D7-Oi8"/>
<constraint firstAttribute="trailing" secondItem="Gyz-Mz-v08" secondAttribute="trailing" constant="20" symbolic="YES" id="nuN-r8-SjW"/>
<constraint firstItem="Gyz-Mz-v08" firstAttribute="leading" secondItem="q5z-LG-0Fm" secondAttribute="leading" id="rTh-Ea-LYf"/>
<constraint firstAttribute="trailing" secondItem="q5z-LG-0Fm" secondAttribute="trailing" constant="20" id="rky-el-9AK"/>
<constraint firstItem="lti-yM-8LV" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="t4L-Nb-T2M"/>
<constraint firstItem="7Ht-Fn-0Ya" firstAttribute="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" id="tAZ-Te-w3H"/>
@ -250,7 +251,7 @@ Gw
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="116.5" y="136.5"/>
<point key="canvasLocation" x="116.5" y="149.5"/>
</window>
</objects>
<resources>

View File

@ -101,7 +101,7 @@ struct AddAccountsView: View {
parent?.dismiss(nil)
}, label: {
Text("Cancel")
.frame(width: 80)
.frame(width: 76)
})
.help("Cancel")
.keyboardShortcut(.cancelAction)
@ -111,7 +111,7 @@ struct AddAccountsView: View {
parent?.dismiss(nil)
}, label: {
Text("Cancel")
.frame(width: 80)
.frame(width: 76)
})
.accessibility(label: Text("Add Account"))
}
@ -121,7 +121,7 @@ struct AddAccountsView: View {
parent?.dismiss(nil)
}, label: {
Text("Continue")
.frame(width: 80)
.frame(width: 76)
})
.help("Add Account")
.keyboardShortcut(.defaultAction)
@ -132,7 +132,7 @@ struct AddAccountsView: View {
parent?.dismiss(nil)
}, label: {
Text("Continue")
.frame(width: 80)
.frame(width: 76)
})
}
}

View File

@ -12,7 +12,7 @@ import AuthenticationServices
import OAuthSwift
import Secrets
protocol ExtensionPointPreferencesEnabler: class {
protocol ExtensionPointPreferencesEnabler: AnyObject {
func enable(_ extensionPointType: ExtensionPoint.Type)
}

View File

@ -12,7 +12,7 @@ import RSCore
import Account
import Articles
protocol SidebarModelDelegate: class {
protocol SidebarModelDelegate: AnyObject {
func unreadCount(for: Feed) -> Int
}

View File

@ -16,7 +16,7 @@ import RSCore
import Account
import Articles
protocol TimelineModelDelegate: class {
protocol TimelineModelDelegate: AnyObject {
var selectedFeedsPublisher: AnyPublisher<[Feed], Never>? { get }
func timelineRequestedWebFeedSelection(_: TimelineModel, webFeed: WebFeed)
}

View File

@ -14,7 +14,7 @@ import Articles
import SafariServices
import MessageUI
protocol WebViewControllerDelegate: class {
protocol WebViewControllerDelegate: AnyObject {
func webViewController(_: WebViewController, articleExtractorButtonStateDidUpdate: ArticleExtractorButtonState)
}

View File

@ -11,7 +11,7 @@ import Combine
import RSCore
import Articles
protocol WebViewControllerDelegate: class {
protocol WebViewControllerDelegate: AnyObject {
func webViewController(_: WebViewController, articleExtractorButtonStateDidUpdate: ArticleExtractorButtonState)
}

View File

@ -6095,8 +6095,8 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/Ranchero-Software/Sparkle-Binary.git";
requirement = {
branch = main;
kind = branch;
kind = upToNextMajorVersion;
minimumVersion = 2.0.0;
};
};
5102AE4324D17E820050839C /* XCRemoteSwiftPackageReference "RSCore" */ = {
@ -6104,7 +6104,7 @@
repositoryURL = "https://github.com/Ranchero-Software/RSCore.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = "1.0.0-beta1";
minimumVersion = 1.0.0;
};
};
510ECA4024D1DCD0001C31A6 /* XCRemoteSwiftPackageReference "RSTree" */ = {
@ -6112,7 +6112,7 @@
repositoryURL = "https://github.com/Ranchero-Software/RSTree.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = "1.0.0-beta1";
minimumVersion = 1.0.0;
};
};
51383A3024D1F90E0027E272 /* XCRemoteSwiftPackageReference "RSWeb" */ = {
@ -6136,7 +6136,7 @@
repositoryURL = "https://github.com/Ranchero-Software/RSDatabase.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = "1.0.0-beta1";
minimumVersion = 1.0.0;
};
};
51B0DF2324D2C7FA000AD99E /* XCRemoteSwiftPackageReference "RSParser" */ = {
@ -6144,7 +6144,7 @@
repositoryURL = "https://github.com/Ranchero-Software/RSParser.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = "2.0.0-beta1";
minimumVersion = 2.0.0;
};
};
/* End XCRemoteSwiftPackageReference section */

View File

@ -60,8 +60,8 @@
"repositoryURL": "https://github.com/Ranchero-Software/RSCore.git",
"state": {
"branch": null,
"revision": "dce76a4070ed24f148bb1673c308962dbdbf01ef",
"version": "1.0.0-beta9"
"revision": "6b2ef2580968905af825c40442dc0ba3126032c0",
"version": "1.0.2"
}
},
{
@ -69,8 +69,8 @@
"repositoryURL": "https://github.com/Ranchero-Software/RSDatabase.git",
"state": {
"branch": null,
"revision": "3aa706f3adfc0b798a2b69cf536461c39db4d269",
"version": "1.0.0-beta1"
"revision": "a6c5f1622320f745cc9a0a910d1bed1e2eaf15e3",
"version": "1.0.0"
}
},
{
@ -78,8 +78,8 @@
"repositoryURL": "https://github.com/Ranchero-Software/RSParser.git",
"state": {
"branch": null,
"revision": "fd9b9c974d551a9c94d970da90a42571d234efd6",
"version": "2.0.0-beta4"
"revision": "a4467cb6ab32d67fa8b09fcef8b234c7f96b7f9c",
"version": "2.0.0"
}
},
{
@ -87,8 +87,8 @@
"repositoryURL": "https://github.com/Ranchero-Software/RSTree.git",
"state": {
"branch": null,
"revision": "979ed0eb610b6d95dc7adcf4620bd44205f512a6",
"version": "1.0.0-beta1"
"revision": "9d051f42cfc4faa991fd79cdb32e4cc8c545e334",
"version": "1.0.0"
}
},
{
@ -104,9 +104,9 @@
"package": "RSSparkle",
"repositoryURL": "https://github.com/Ranchero-Software/Sparkle-Binary.git",
"state": {
"branch": "main",
"branch": null,
"revision": "67cd26321bdf4e77954cf6de7d9e6a20544f2030",
"version": null
"version": "2.0.0"
}
},
{

View File

@ -13,7 +13,7 @@ import Articles
import Account
import RSCore
protocol PseudoFeed: class, Feed, SmallIconProvider, PasteboardWriterOwner {
protocol PseudoFeed: AnyObject, Feed, SmallIconProvider, PasteboardWriterOwner {
}
@ -24,7 +24,7 @@ import Articles
import Account
import RSCore
protocol PseudoFeed: class, Feed, SmallIconProvider {
protocol PseudoFeed: AnyObject, Feed, SmallIconProvider {
}

View File

@ -33,10 +33,10 @@ final class UserNotificationManager: NSObject {
}
@objc func statusesDidChange(_ note: Notification) {
guard let articleIDs = note.userInfo?[Account.UserInfoKey.articleIDs] as? Set<String>, !articleIDs.isEmpty else {
guard let statuses = note.userInfo?[Account.UserInfoKey.statuses] as? Set<ArticleStatus>, !statuses.isEmpty else {
return
}
let identifiers = articleIDs.map { "articleID:\($0)" }
let identifiers = statuses.filter({ $0.read }).map { "articleID:\($0.articleID)" }
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: identifiers)
}

View File

@ -11,7 +11,7 @@ let package = Package(
targets: ["SyncDatabase"]),
],
dependencies: [
.package(url: "https://github.com/Ranchero-Software/RSDatabase.git", .upToNextMajor(from: "1.0.0-beta1")),
.package(url: "https://github.com/Ranchero-Software/RSDatabase.git", .upToNextMajor(from: "1.0.0")),
.package(url: "../Articles", .upToNextMajor(from: "1.0.0")),
],
targets: [

View File

@ -14,7 +14,7 @@ import Articles
import SafariServices
import MessageUI
protocol WebViewControllerDelegate: class {
protocol WebViewControllerDelegate: AnyObject {
func webViewController(_: WebViewController, articleExtractorButtonStateDidUpdate: ArticleExtractorButtonState)
}

View File

@ -11,7 +11,7 @@ import RSCore
import Account
import RSTree
protocol MasterFeedTableViewCellDelegate: class {
protocol MasterFeedTableViewCellDelegate: AnyObject {
func masterFeedTableViewCellDisclosureDidToggle(_ sender: MasterFeedTableViewCell, expanding: Bool)
}

View File

@ -471,13 +471,15 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
}
@objc func userDefaultsDidChange(_ note: Notification) {
if numberOfTextLines != AppDefaults.shared.timelineNumberOfLines || iconSize != AppDefaults.shared.timelineIconSize {
numberOfTextLines = AppDefaults.shared.timelineNumberOfLines
iconSize = AppDefaults.shared.timelineIconSize
resetEstimatedRowHeight()
reloadAllVisibleCells()
DispatchQueue.main.async {
if self.numberOfTextLines != AppDefaults.shared.timelineNumberOfLines || self.iconSize != AppDefaults.shared.timelineIconSize {
self.numberOfTextLines = AppDefaults.shared.timelineNumberOfLines
self.iconSize = AppDefaults.shared.timelineIconSize
self.resetEstimatedRowHeight()
self.reloadAllVisibleCells()
}
self.updateToolbar()
}
updateToolbar()
}
@objc func contentSizeCategoryDidChange(_ note: Notification) {

View File

@ -10,7 +10,7 @@ import UIKit
import Account
import RSCore
protocol ShareFolderPickerControllerDelegate: class {
protocol ShareFolderPickerControllerDelegate: AnyObject {
func shareFolderPickerDidSelect(_ container: ExtensionContainer)
}