mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Merge branch 'main' of https://github.com/Ranchero-Software/NetNewsWire into main
This commit is contained in:
@@ -20,7 +20,7 @@ class FeedFinder {
|
||||
if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), urlComponents.host == "micro.blog" {
|
||||
urlComponents.path = "\(urlComponents.path).json"
|
||||
if let newURLString = urlComponents.url?.absoluteString {
|
||||
let microblogFeedSpecifier = FeedSpecifier(title: nil, urlString: newURLString, source: .HTMLLink)
|
||||
let microblogFeedSpecifier = FeedSpecifier(title: nil, urlString: newURLString, source: .HTMLLink, orderFound: 1)
|
||||
completion(.success(Set([microblogFeedSpecifier])))
|
||||
}
|
||||
} else {
|
||||
@@ -45,7 +45,7 @@ class FeedFinder {
|
||||
}
|
||||
|
||||
if FeedFinder.isFeed(data, url.absoluteString) {
|
||||
let feedSpecifier = FeedSpecifier(title: nil, urlString: url.absoluteString, source: .UserEntered)
|
||||
let feedSpecifier = FeedSpecifier(title: nil, urlString: url.absoluteString, source: .UserEntered, orderFound: 1)
|
||||
completion(.success(Set([feedSpecifier])))
|
||||
return
|
||||
}
|
||||
@@ -120,11 +120,11 @@ private extension FeedFinder {
|
||||
// It’s also fairly common for /index.xml to work.
|
||||
if let url = URL(string: urlString) {
|
||||
let feedURL = url.appendingPathComponent("feed", isDirectory: true)
|
||||
let wordpressFeedSpecifier = FeedSpecifier(title: nil, urlString: feedURL.absoluteString, source: .HTMLLink)
|
||||
let wordpressFeedSpecifier = FeedSpecifier(title: nil, urlString: feedURL.absoluteString, source: .HTMLLink, orderFound: 1)
|
||||
feedSpecifiers.insert(wordpressFeedSpecifier)
|
||||
|
||||
let indexXMLURL = url.appendingPathComponent("index.xml", isDirectory: false)
|
||||
let indexXMLFeedSpecifier = FeedSpecifier(title: nil, urlString: indexXMLURL.absoluteString, source: .HTMLLink)
|
||||
let indexXMLFeedSpecifier = FeedSpecifier(title: nil, urlString: indexXMLURL.absoluteString, source: .HTMLLink, orderFound: 1)
|
||||
feedSpecifiers.insert(indexXMLFeedSpecifier)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ struct FeedSpecifier: Hashable {
|
||||
public let title: String?
|
||||
public let urlString: String
|
||||
public let source: Source
|
||||
public let orderFound: Int
|
||||
public var score: Int {
|
||||
return calculatedScore()
|
||||
}
|
||||
@@ -30,8 +31,9 @@ struct FeedSpecifier: Hashable {
|
||||
|
||||
let mergedTitle = title ?? feedSpecifier.title
|
||||
let mergedSource = source.equalToOrBetterThan(feedSpecifier.source) ? source : feedSpecifier.source
|
||||
let mergedOrderFound = orderFound < feedSpecifier.orderFound ? orderFound : feedSpecifier.orderFound
|
||||
|
||||
return FeedSpecifier(title: mergedTitle, urlString: urlString, source: mergedSource)
|
||||
return FeedSpecifier(title: mergedTitle, urlString: urlString, source: mergedSource, orderFound: mergedOrderFound)
|
||||
}
|
||||
|
||||
public static func bestFeed(in feedSpecifiers: Set<FeedSpecifier>) -> FeedSpecifier? {
|
||||
@@ -69,6 +71,8 @@ private extension FeedSpecifier {
|
||||
score = score + 50
|
||||
}
|
||||
|
||||
score = score - ((orderFound - 1) * 5)
|
||||
|
||||
if urlString.caseInsensitiveContains("comments") {
|
||||
score = score - 10
|
||||
}
|
||||
|
||||
@@ -21,22 +21,24 @@ class HTMLFeedFinder {
|
||||
|
||||
init(parserData: ParserData) {
|
||||
let metadata = RSHTMLMetadataParser.htmlMetadata(with: parserData)
|
||||
|
||||
var orderFound = 0
|
||||
|
||||
for oneFeedLink in metadata.feedLinks {
|
||||
if let oneURLString = oneFeedLink.urlString?.normalizedURL {
|
||||
let oneFeedSpecifier = FeedSpecifier(title: oneFeedLink.title, urlString: oneURLString, source: .HTMLHead)
|
||||
orderFound = orderFound + 1
|
||||
let oneFeedSpecifier = FeedSpecifier(title: oneFeedLink.title, urlString: oneURLString, source: .HTMLHead, orderFound: orderFound)
|
||||
addFeedSpecifier(oneFeedSpecifier)
|
||||
}
|
||||
}
|
||||
|
||||
let bodyLinks = RSHTMLLinkParser.htmlLinks(with: parserData)
|
||||
for oneBodyLink in bodyLinks {
|
||||
|
||||
if linkMightBeFeed(oneBodyLink), let normalizedURL = oneBodyLink.urlString?.normalizedURL {
|
||||
let oneFeedSpecifier = FeedSpecifier(title: oneBodyLink.text, urlString: normalizedURL, source: .HTMLLink)
|
||||
addFeedSpecifier(oneFeedSpecifier)
|
||||
}
|
||||
for oneBodyLink in bodyLinks {
|
||||
if linkMightBeFeed(oneBodyLink), let normalizedURL = oneBodyLink.urlString?.normalizedURL {
|
||||
orderFound = orderFound + 1
|
||||
let oneFeedSpecifier = FeedSpecifier(title: oneBodyLink.text, urlString: normalizedURL, source: .HTMLLink, orderFound: orderFound)
|
||||
addFeedSpecifier(oneFeedSpecifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ final class FeedbinAPICaller: NSObject {
|
||||
private let feedbinBaseURL = URL(string: "https://api.feedbin.com/v2/")!
|
||||
private var transport: Transport!
|
||||
private var suspended = false
|
||||
private var lastBackdateStartTime: Date?
|
||||
|
||||
var credentials: Credentials?
|
||||
weak var accountMetadata: AccountMetadata?
|
||||
@@ -486,10 +487,26 @@ final class FeedbinAPICaller: NSObject {
|
||||
}
|
||||
|
||||
func retrieveEntries(completion: @escaping (Result<([FeedbinEntry]?, String?, Date?, Int?), Error>) -> Void) {
|
||||
|
||||
|
||||
// If this is an initial sync, go and grab the previous 3 months of entries. If not, use the last
|
||||
// article fetch to only get the articles **published** since the last article fetch.
|
||||
//
|
||||
// We do a backdate fetch every launch or every 24 hours. This will help with
|
||||
// getting **updated** articles that normally wouldn't be found with a regular fetch.
|
||||
// https://github.com/Ranchero-Software/NetNewsWire/issues/2549#issuecomment-722341356
|
||||
let since: Date = {
|
||||
if let lastArticleFetch = accountMetadata?.lastArticleFetchStartTime {
|
||||
return lastArticleFetch
|
||||
if let lastBackdateStartTime = lastBackdateStartTime {
|
||||
if lastBackdateStartTime.byAdding(days: 1) < lastArticleFetch {
|
||||
self.lastBackdateStartTime = lastArticleFetch
|
||||
return lastArticleFetch.bySubtracting(days: 1)
|
||||
} else {
|
||||
return lastArticleFetch
|
||||
}
|
||||
} else {
|
||||
self.lastBackdateStartTime = lastArticleFetch
|
||||
return lastArticleFetch.bySubtracting(days: 1)
|
||||
}
|
||||
} else {
|
||||
return Calendar.current.date(byAdding: .month, value: -3, to: Date()) ?? Date()
|
||||
}
|
||||
|
||||
@@ -986,27 +986,22 @@ private extension FeedbinAccountDelegate {
|
||||
}
|
||||
|
||||
func decideBestFeedChoice(account: Account, url: String, name: String?, container: Container, choices: [FeedbinSubscriptionChoice], completion: @escaping (Result<WebFeed, Error>) -> Void) {
|
||||
var orderFound = 0
|
||||
|
||||
let feedSpecifiers: [FeedSpecifier] = choices.map { choice in
|
||||
let source = url == choice.url ? FeedSpecifier.Source.UserEntered : FeedSpecifier.Source.HTMLLink
|
||||
let specifier = FeedSpecifier(title: choice.name, urlString: choice.url, source: source)
|
||||
orderFound = orderFound + 1
|
||||
let specifier = FeedSpecifier(title: choice.name, urlString: choice.url, source: source, orderFound: orderFound)
|
||||
return specifier
|
||||
}
|
||||
|
||||
if let bestSpecifier = FeedSpecifier.bestFeed(in: Set(feedSpecifiers)) {
|
||||
if let bestSubscription = choices.filter({ bestSpecifier.urlString == $0.url }).first {
|
||||
createWebFeed(for: account, url: bestSubscription.url, name: name, container: container, completion: completion)
|
||||
} else {
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(FeedbinAccountDelegateError.invalidParameter))
|
||||
}
|
||||
}
|
||||
createWebFeed(for: account, url: bestSpecifier.urlString, name: name, container: container, completion: completion)
|
||||
} else {
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(FeedbinAccountDelegateError.invalidParameter))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func createFeed( account: Account, subscription sub: FeedbinSubscription, name: String?, container: Container, completion: @escaping (Result<WebFeed, Error>) -> Void) {
|
||||
|
||||
@@ -235,6 +235,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
|
||||
switch result {
|
||||
case .success:
|
||||
DispatchQueue.main.async {
|
||||
folder.externalID = "user/-/label/\(name)"
|
||||
folder.name = name
|
||||
completion(.success(()))
|
||||
}
|
||||
@@ -298,13 +299,18 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
|
||||
}
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
self.caller.deleteTag(folder: folder) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
account.removeFolder(folder)
|
||||
completion(.success(()))
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
if self.variant == .theOldReader {
|
||||
account.removeFolder(folder)
|
||||
completion(.success(()))
|
||||
} else {
|
||||
self.caller.deleteTag(folder: folder) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
account.removeFolder(folder)
|
||||
completion(.success(()))
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -821,30 +827,6 @@ private extension ReaderAPIAccountDelegate {
|
||||
feed.folderRelationship = [folderExternalID: feedExternalID]
|
||||
}
|
||||
}
|
||||
|
||||
func decideBestFeedChoice(account: Account, url: String, name: String?, container: Container, choices: [ReaderAPISubscriptionChoice], completion: @escaping (Result<WebFeed, Error>) -> Void) {
|
||||
|
||||
let feedSpecifiers: [FeedSpecifier] = choices.map { choice in
|
||||
let source = url == choice.url ? FeedSpecifier.Source.UserEntered : FeedSpecifier.Source.HTMLLink
|
||||
let specifier = FeedSpecifier(title: choice.name, urlString: choice.url, source: source)
|
||||
return specifier
|
||||
}
|
||||
|
||||
if let bestSpecifier = FeedSpecifier.bestFeed(in: Set(feedSpecifiers)) {
|
||||
if let bestSubscription = choices.filter({ bestSpecifier.urlString == $0.url }).first {
|
||||
createWebFeed(for: account, url: bestSubscription.url, name: name, container: container, completion: completion)
|
||||
} else {
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(ReaderAPIAccountDelegateError.invalidParameter))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(ReaderAPIAccountDelegateError.invalidParameter))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func createFeed( account: Account, subscription sub: ReaderAPISubscription, name: String?, container: Container, completion: @escaping (Result<WebFeed, Error>) -> Void) {
|
||||
|
||||
@@ -857,7 +839,7 @@ private extension ReaderAPIAccountDelegate {
|
||||
switch result {
|
||||
case .success:
|
||||
if let name = name {
|
||||
account.renameWebFeed(feed, to: name) { result in
|
||||
self.renameWebFeed(for: account, with: feed, to: name) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
self.initialFeedDownload(account: account, feed: feed, completion: completion)
|
||||
|
||||
@@ -49,20 +49,22 @@ final class ReaderAPICaller: NSObject {
|
||||
}
|
||||
|
||||
private var transport: Transport!
|
||||
|
||||
var variant: ReaderAPIVariant = .generic
|
||||
var credentials: Credentials?
|
||||
private let uriComponentAllowed: CharacterSet
|
||||
|
||||
private var accessToken: String?
|
||||
|
||||
weak var accountMetadata: AccountMetadata?
|
||||
|
||||
var variant: ReaderAPIVariant = .generic
|
||||
var credentials: Credentials?
|
||||
|
||||
var server: String? {
|
||||
get {
|
||||
return APIBaseURL?.host
|
||||
return apiBaseURL?.host
|
||||
}
|
||||
}
|
||||
|
||||
private var APIBaseURL: URL? {
|
||||
private var apiBaseURL: URL? {
|
||||
get {
|
||||
switch variant {
|
||||
case .generic, .freshRSS:
|
||||
@@ -77,8 +79,13 @@ final class ReaderAPICaller: NSObject {
|
||||
}
|
||||
|
||||
init(transport: Transport) {
|
||||
super.init()
|
||||
self.transport = transport
|
||||
|
||||
var urlHostAllowed = CharacterSet.urlHostAllowed
|
||||
urlHostAllowed.remove("+")
|
||||
urlHostAllowed.remove("&")
|
||||
uriComponentAllowed = urlHostAllowed
|
||||
super.init()
|
||||
}
|
||||
|
||||
func cancelAll() {
|
||||
@@ -170,7 +177,7 @@ final class ReaderAPICaller: NSObject {
|
||||
|
||||
|
||||
func retrieveTags(completion: @escaping (Result<[ReaderAPITag]?, Error>) -> Void) {
|
||||
guard let baseURL = APIBaseURL else {
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
@@ -199,7 +206,7 @@ final class ReaderAPICaller: NSObject {
|
||||
}
|
||||
|
||||
func renameTag(oldName: String, newName: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
guard let baseURL = APIBaseURL else {
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
@@ -212,8 +219,13 @@ final class ReaderAPICaller: NSObject {
|
||||
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||
request.httpMethod = "POST"
|
||||
|
||||
let oldTagName = "user/-/label/\(oldName)"
|
||||
let newTagName = "user/-/label/\(newName)"
|
||||
guard let encodedOldName = self.encodeForURLPath(oldName), let encodedNewName = self.encodeForURLPath(newName) else {
|
||||
completion(.failure(ReaderAPIAccountDelegateError.invalidParameter))
|
||||
return
|
||||
}
|
||||
|
||||
let oldTagName = "user/-/label/\(encodedOldName)"
|
||||
let newTagName = "user/-/label/\(encodedNewName)"
|
||||
let postData = "T=\(token)&s=\(oldTagName)&dest=\(newTagName)".data(using: String.Encoding.utf8)
|
||||
|
||||
self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in
|
||||
@@ -235,7 +247,7 @@ final class ReaderAPICaller: NSObject {
|
||||
}
|
||||
|
||||
func deleteTag(folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
guard let baseURL = APIBaseURL else {
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
@@ -274,7 +286,7 @@ final class ReaderAPICaller: NSObject {
|
||||
}
|
||||
|
||||
func retrieveSubscriptions(completion: @escaping (Result<[ReaderAPISubscription]?, Error>) -> Void) {
|
||||
guard let baseURL = APIBaseURL else {
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
@@ -302,7 +314,7 @@ final class ReaderAPICaller: NSObject {
|
||||
}
|
||||
|
||||
func createSubscription(url: String, name: String?, folder: Folder?, completion: @escaping (Result<CreateReaderAPISubscriptionResult, Error>) -> Void) {
|
||||
guard let baseURL = APIBaseURL else {
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
@@ -376,10 +388,10 @@ final class ReaderAPICaller: NSObject {
|
||||
request.httpMethod = "POST"
|
||||
|
||||
var postString = "T=\(token)&ac=subscribe&s=\(streamId)"
|
||||
if let folder = folder {
|
||||
postString += "&a=user/-/label/\(folder.nameForDisplay)"
|
||||
if let folderName = self.encodeForURLPath(folder?.nameForDisplay) {
|
||||
postString += "&a=user/-/label/\(folderName)"
|
||||
}
|
||||
if let name = name {
|
||||
if let name = self.encodeForURLPath(name) {
|
||||
postString += "&t=\(name)"
|
||||
}
|
||||
|
||||
@@ -411,7 +423,7 @@ final class ReaderAPICaller: NSObject {
|
||||
}
|
||||
|
||||
func renameSubscription(subscriptionID: String, newName: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
guard let baseURL = APIBaseURL else {
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
@@ -424,7 +436,12 @@ final class ReaderAPICaller: NSObject {
|
||||
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||
request.httpMethod = "POST"
|
||||
|
||||
let postData = "T=\(token)&s=\(subscriptionID)&ac=edit&t=\(newName)".data(using: String.Encoding.utf8)
|
||||
guard let encodedNewName = self.encodeForURLPath(newName) else {
|
||||
completion(.failure(ReaderAPIAccountDelegateError.invalidParameter))
|
||||
return
|
||||
}
|
||||
|
||||
let postData = "T=\(token)&s=\(subscriptionID)&ac=edit&t=\(encodedNewName)".data(using: String.Encoding.utf8)
|
||||
|
||||
self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in
|
||||
switch result {
|
||||
@@ -445,7 +462,7 @@ final class ReaderAPICaller: NSObject {
|
||||
}
|
||||
|
||||
func deleteSubscription(subscriptionID: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
guard let baseURL = APIBaseURL else {
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
@@ -479,7 +496,7 @@ final class ReaderAPICaller: NSObject {
|
||||
|
||||
func createTagging(subscriptionID: String, tagName: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
guard let baseURL = APIBaseURL else {
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
@@ -492,8 +509,12 @@ final class ReaderAPICaller: NSObject {
|
||||
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||
request.httpMethod = "POST"
|
||||
|
||||
let tagName = "user/-/label/\(tagName)"
|
||||
let postData = "T=\(token)&s=\(subscriptionID)&ac=edit&a=\(tagName)".data(using: String.Encoding.utf8)
|
||||
guard let tagName = self.encodeForURLPath(tagName) else {
|
||||
completion(.failure(ReaderAPIAccountDelegateError.invalidParameter))
|
||||
return
|
||||
}
|
||||
|
||||
let postData = "T=\(token)&s=\(subscriptionID)&ac=edit&a=user/-/label/\(tagName)".data(using: String.Encoding.utf8)
|
||||
|
||||
self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in
|
||||
switch result {
|
||||
@@ -514,7 +535,7 @@ final class ReaderAPICaller: NSObject {
|
||||
}
|
||||
|
||||
func deleteTagging(subscriptionID: String, tagName: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
guard let baseURL = APIBaseURL else {
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
@@ -554,7 +575,7 @@ final class ReaderAPICaller: NSObject {
|
||||
return
|
||||
}
|
||||
|
||||
guard let baseURL = APIBaseURL else {
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
@@ -603,7 +624,7 @@ final class ReaderAPICaller: NSObject {
|
||||
}
|
||||
|
||||
func retrieveItemIDs(type: ItemIDType, webFeedID: String? = nil, completion: @escaping ((Result<[String], Error>) -> Void)) {
|
||||
guard let baseURL = APIBaseURL else {
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
@@ -734,6 +755,11 @@ final class ReaderAPICaller: NSObject {
|
||||
|
||||
private extension ReaderAPICaller {
|
||||
|
||||
func encodeForURLPath(_ pathComponent: String?) -> String? {
|
||||
guard let pathComponent = pathComponent else { return nil }
|
||||
return pathComponent.addingPercentEncoding(withAllowedCharacters: uriComponentAllowed)
|
||||
}
|
||||
|
||||
func storeConditionalGet(key: String, headers: [AnyHashable : Any]) {
|
||||
if var conditionalGet = accountMetadata?.conditionalGetInfo {
|
||||
conditionalGet[key] = HTTPConditionalGetInfo(headers: headers)
|
||||
@@ -749,7 +775,7 @@ private extension ReaderAPICaller {
|
||||
}
|
||||
|
||||
private func updateStateToEntries(entries: [String], state: ReaderState, add: Bool, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
guard let baseURL = APIBaseURL else {
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ final class AppDefaults {
|
||||
static let timelineGroupByFeed = "timelineGroupByFeed"
|
||||
static let detailFontSize = "detailFontSize"
|
||||
static let openInBrowserInBackground = "openInBrowserInBackground"
|
||||
static let articleTextSize = "articleTextSize"
|
||||
static let refreshInterval = "refreshInterval"
|
||||
static let addWebFeedAccountID = "addWebFeedAccountID"
|
||||
static let addWebFeedFolderName = "addWebFeedFolderName"
|
||||
@@ -244,6 +245,16 @@ final class AppDefaults {
|
||||
return AppDefaults.bool(for: Key.timelineShowsSeparators)
|
||||
}
|
||||
|
||||
var articleTextSize: ArticleTextSize {
|
||||
get {
|
||||
let rawValue = UserDefaults.standard.integer(forKey: Key.articleTextSize)
|
||||
return ArticleTextSize(rawValue: rawValue) ?? ArticleTextSize.large
|
||||
}
|
||||
set {
|
||||
UserDefaults.standard.set(newValue.rawValue, forKey: Key.articleTextSize)
|
||||
}
|
||||
}
|
||||
|
||||
var refreshInterval: RefreshInterval {
|
||||
get {
|
||||
let rawValue = UserDefaults.standard.integer(forKey: Key.refreshInterval)
|
||||
|
||||
@@ -25,21 +25,115 @@
|
||||
</windowController>
|
||||
<customObject id="Q6y-w1-UqW" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-573" y="41"/>
|
||||
<point key="canvasLocation" x="-573" y="40.5"/>
|
||||
</scene>
|
||||
<!--General-->
|
||||
<scene sceneID="R4l-Wg-k7x">
|
||||
<objects>
|
||||
<viewController title="General" storyboardIdentifier="General" id="iuH-lz-18x" customClass="GeneralPreferencesViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" id="WnV-px-wCT">
|
||||
<rect key="frame" x="0.0" y="0.0" width="506" height="210"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="509" height="247"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<customView horizontalHuggingPriority="1000" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="Ut3-yd-q6G">
|
||||
<rect key="frame" x="36" y="16" width="433" height="178"/>
|
||||
<rect key="frame" x="54" y="16" width="400" height="215"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="pR2-Bf-7Fd">
|
||||
<rect key="frame" x="6" y="194" width="106" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Article Text Size:" id="xQu-QV-91i">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Z6O-Zt-V1g">
|
||||
<rect key="frame" x="115" y="187" width="289" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Medium" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="2" imageScaling="proportionallyDown" inset="2" selectedItem="jMV-2o-5Oh" id="6pw-Vq-tjM">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="Yqo-qR-1qN">
|
||||
<items>
|
||||
<menuItem title="Small" tag="1" id="roB-Mu-Ht7"/>
|
||||
<menuItem title="Medium" state="on" tag="2" id="jMV-2o-5Oh"/>
|
||||
<menuItem title="Large" tag="3" id="ckZ-0Q-rNz"/>
|
||||
<menuItem title="X-Large" tag="4" id="qMe-6g-Vme"/>
|
||||
<menuItem title="XX-Large" tag="5" id="4Pi-2Y-XmV"/>
|
||||
</items>
|
||||
</menu>
|
||||
<connections>
|
||||
<binding destination="mAF-gO-1PI" name="selectedTag" keyPath="values.articleTextSize" id="qgn-ap-aCc">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
<bool key="NSConditionallySetsEnabled" value="NO"/>
|
||||
<integer key="NSMultipleValuesPlaceholder" value="3"/>
|
||||
<integer key="NSNoSelectionPlaceholder" value="3"/>
|
||||
<integer key="NSNotApplicablePlaceholder" value="3"/>
|
||||
<integer key="NSNullPlaceholder" value="3"/>
|
||||
<bool key="NSRaisesForNotApplicableKeys" value="NO"/>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="Tdg-6Y-gvW">
|
||||
<rect key="frame" x="0.0" y="172" width="400" height="5"/>
|
||||
</box>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Wsb-Lr-8Q7">
|
||||
<rect key="frame" x="54" y="141" width="58" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Browser:" id="CgU-dE-Qtb">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ci4-fW-KjU">
|
||||
<rect key="frame" x="115" y="134" width="289" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Safari" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="ObP-qK-qDJ" id="hrm-aT-Rc2" userLabel="Popup">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="j1i-Ev-7rI">
|
||||
<items>
|
||||
<menuItem title="Safari" state="on" id="ObP-qK-qDJ"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="browserPopUpDidChangeValue:" target="iuH-lz-18x" id="vSr-98-LQL"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<button horizontalHuggingPriority="1000" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="Ubm-Pk-l7x">
|
||||
<rect key="frame" x="116" y="107" width="284" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Open web pages in background in browser" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="t0a-LN-rCv">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="mAF-gO-1PI" name="value" keyPath="values.openInBrowserInBackground" id="hKH-w2-y6N">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
<bool key="NSConditionallySetsEnabled" value="NO"/>
|
||||
<integer key="NSMultipleValuesPlaceholder" value="0"/>
|
||||
<integer key="NSNoSelectionPlaceholder" value="0"/>
|
||||
<integer key="NSNotApplicablePlaceholder" value="0"/>
|
||||
<integer key="NSNullPlaceholder" value="0"/>
|
||||
<bool key="NSRaisesForNotApplicableKeys" value="NO"/>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="j0t-Wa-UTL">
|
||||
<rect key="frame" x="135" y="84" width="235" height="16"/>
|
||||
<textFieldCell key="cell" controlSize="small" title="Press the Shift key to do the opposite." id="EMq-9M-zTJ">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="hQy-ng-ijd">
|
||||
<rect key="frame" x="0.0" y="65" width="400" height="5"/>
|
||||
</box>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ucw-vG-yLt">
|
||||
<rect key="frame" x="53" y="157" width="92" height="16"/>
|
||||
<rect key="frame" x="20" y="34" width="92" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Refresh feeds:" id="F7c-lm-g97">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -47,7 +141,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SFF-mL-yc8">
|
||||
<rect key="frame" x="148" y="150" width="289" height="25"/>
|
||||
<rect key="frame" x="115" y="27" width="289" height="25"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="N1a-qV-4Os"/>
|
||||
</constraints>
|
||||
@@ -81,51 +175,8 @@
|
||||
</connections>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Wsb-Lr-8Q7">
|
||||
<rect key="frame" x="87" y="91" width="58" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Browser:" id="CgU-dE-Qtb">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ci4-fW-KjU">
|
||||
<rect key="frame" x="148" y="84" width="289" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Safari" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="ObP-qK-qDJ" id="hrm-aT-Rc2" userLabel="Popup">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="j1i-Ev-7rI">
|
||||
<items>
|
||||
<menuItem title="Safari" state="on" id="ObP-qK-qDJ"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="browserPopUpDidChangeValue:" target="iuH-lz-18x" id="vSr-98-LQL"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<button horizontalHuggingPriority="1000" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="Ubm-Pk-l7x">
|
||||
<rect key="frame" x="149" y="57" width="284" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Open web pages in background in browser" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="t0a-LN-rCv">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="mAF-gO-1PI" name="value" keyPath="values.openInBrowserInBackground" id="hKH-w2-y6N">
|
||||
<dictionary key="options">
|
||||
<bool key="NSAllowsEditingMultipleValuesSelection" value="NO"/>
|
||||
<bool key="NSConditionallySetsEnabled" value="NO"/>
|
||||
<integer key="NSMultipleValuesPlaceholder" value="0"/>
|
||||
<integer key="NSNoSelectionPlaceholder" value="0"/>
|
||||
<integer key="NSNotApplicablePlaceholder" value="0"/>
|
||||
<integer key="NSNullPlaceholder" value="0"/>
|
||||
<bool key="NSRaisesForNotApplicableKeys" value="NO"/>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jVd-Ie-CGX">
|
||||
<rect key="frame" x="77" y="4" width="68" height="16"/>
|
||||
<rect key="frame" x="44" y="4" width="68" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Dock icon:" id="vFc-Nz-RFp">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -133,7 +184,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mwT-nY-TrX">
|
||||
<rect key="frame" x="149" y="3" width="143" height="18"/>
|
||||
<rect key="frame" x="116" y="3" width="143" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Show unread count" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="lh0-G6-9v4">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -142,72 +193,44 @@
|
||||
<action selector="toggleShowingUnreadCount:" target="iuH-lz-18x" id="CfQ-Pv-9d2"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="j0t-Wa-UTL">
|
||||
<rect key="frame" x="168" y="34" width="235" height="16"/>
|
||||
<textFieldCell key="cell" controlSize="small" title="Press the Shift key to do the opposite." id="EMq-9M-zTJ">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ulQ-kB-eNO">
|
||||
<rect key="frame" x="18" y="124" width="127" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Default RSS Reader:" id="Ls3-nS-E6w">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="48p-6Z-Yid">
|
||||
<rect key="frame" x="148" y="118" width="289" height="25"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Fex-Ru-tjJ" id="Xz6-ZO-abi">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="maY-sW-bmj">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="Fex-Ru-tjJ"/>
|
||||
<menuItem title="Item 2" id="IKn-RA-vwL"/>
|
||||
<menuItem title="Item 3" id="n2E-vh-TSH"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="rssReaderPopupDidChangeValue:" target="iuH-lz-18x" id="wH0-4N-Exe"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="Wsb-Lr-8Q7" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Ut3-yd-q6G" secondAttribute="leading" id="17A-5m-ZG0"/>
|
||||
<constraint firstItem="Tdg-6Y-gvW" firstAttribute="top" secondItem="Z6O-Zt-V1g" secondAttribute="bottom" constant="16" id="2iQ-Xt-RLM"/>
|
||||
<constraint firstItem="Z6O-Zt-V1g" firstAttribute="leading" secondItem="pR2-Bf-7Fd" secondAttribute="trailing" constant="8" symbolic="YES" id="2wM-K6-eAF"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="Ubm-Pk-l7x" secondAttribute="trailing" id="3h4-m7-pMW"/>
|
||||
<constraint firstItem="48p-6Z-Yid" firstAttribute="leading" secondItem="ulQ-kB-eNO" secondAttribute="trailing" constant="8" symbolic="YES" id="4hb-gZ-DtU"/>
|
||||
<constraint firstItem="mwT-nY-TrX" firstAttribute="firstBaseline" secondItem="jVd-Ie-CGX" secondAttribute="firstBaseline" id="5nL-J8-5as"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="j0t-Wa-UTL" secondAttribute="trailing" id="7Oh-pf-X12"/>
|
||||
<constraint firstItem="Ubm-Pk-l7x" firstAttribute="leading" secondItem="SFF-mL-yc8" secondAttribute="leading" id="7cy-O4-Zz2"/>
|
||||
<constraint firstItem="Ci4-fW-KjU" firstAttribute="width" secondItem="SFF-mL-yc8" secondAttribute="width" id="AE4-am-IWK"/>
|
||||
<constraint firstItem="Ci4-fW-KjU" firstAttribute="top" secondItem="48p-6Z-Yid" secondAttribute="bottom" constant="14" id="Ay8-21-Xwi"/>
|
||||
<constraint firstItem="mwT-nY-TrX" firstAttribute="top" secondItem="ucw-vG-yLt" secondAttribute="bottom" constant="14" id="CZq-CZ-fC5"/>
|
||||
<constraint firstItem="Ubm-Pk-l7x" firstAttribute="top" secondItem="Ci4-fW-KjU" secondAttribute="bottom" constant="14" id="GNx-7d-yAo"/>
|
||||
<constraint firstItem="Wsb-Lr-8Q7" firstAttribute="trailing" secondItem="jVd-Ie-CGX" secondAttribute="trailing" id="ITg-ay-Y2x"/>
|
||||
<constraint firstItem="Z6O-Zt-V1g" firstAttribute="top" secondItem="Ut3-yd-q6G" secondAttribute="top" constant="4" id="IaE-jL-vMM"/>
|
||||
<constraint firstItem="hQy-ng-ijd" firstAttribute="leading" secondItem="Ut3-yd-q6G" secondAttribute="leading" id="KEI-R5-rzD"/>
|
||||
<constraint firstItem="pR2-Bf-7Fd" firstAttribute="leading" secondItem="Ut3-yd-q6G" secondAttribute="leading" constant="8" id="LRG-HZ-yxh"/>
|
||||
<constraint firstAttribute="trailing" secondItem="SFF-mL-yc8" secondAttribute="trailing" id="N39-Q9-X5Q"/>
|
||||
<constraint firstAttribute="trailing" secondItem="hQy-ng-ijd" secondAttribute="trailing" id="RbT-jK-fBb"/>
|
||||
<constraint firstItem="Ubm-Pk-l7x" firstAttribute="width" secondItem="SFF-mL-yc8" secondAttribute="width" id="TX4-iO-J5E"/>
|
||||
<constraint firstItem="j0t-Wa-UTL" firstAttribute="leading" secondItem="Ubm-Pk-l7x" secondAttribute="leading" constant="19" id="UKq-8p-lyR"/>
|
||||
<constraint firstItem="ulQ-kB-eNO" firstAttribute="leading" secondItem="Ut3-yd-q6G" secondAttribute="leading" constant="20" symbolic="YES" id="X9W-fv-Cho"/>
|
||||
<constraint firstItem="j0t-Wa-UTL" firstAttribute="top" secondItem="Ubm-Pk-l7x" secondAttribute="bottom" constant="8" id="XTw-Ef-FD3"/>
|
||||
<constraint firstItem="48p-6Z-Yid" firstAttribute="width" secondItem="SFF-mL-yc8" secondAttribute="width" id="Yin-Gz-EcF"/>
|
||||
<constraint firstItem="hQy-ng-ijd" firstAttribute="top" secondItem="j0t-Wa-UTL" secondAttribute="bottom" constant="16" id="Zk2-TC-NRS"/>
|
||||
<constraint firstItem="pR2-Bf-7Fd" firstAttribute="firstBaseline" secondItem="Z6O-Zt-V1g" secondAttribute="firstBaseline" id="aO5-iE-L7A"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Z6O-Zt-V1g" secondAttribute="trailing" id="aS9-KA-vSH"/>
|
||||
<constraint firstItem="SFF-mL-yc8" firstAttribute="firstBaseline" secondItem="ucw-vG-yLt" secondAttribute="firstBaseline" id="aqn-St-DJy"/>
|
||||
<constraint firstItem="48p-6Z-Yid" firstAttribute="leading" secondItem="SFF-mL-yc8" secondAttribute="leading" id="cvo-WU-UfZ"/>
|
||||
<constraint firstItem="Tdg-6Y-gvW" firstAttribute="leading" secondItem="Ut3-yd-q6G" secondAttribute="leading" id="b3I-JF-If3"/>
|
||||
<constraint firstItem="jVd-Ie-CGX" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Ut3-yd-q6G" secondAttribute="leading" id="dDb-jw-vca"/>
|
||||
<constraint firstItem="48p-6Z-Yid" firstAttribute="top" secondItem="SFF-mL-yc8" secondAttribute="bottom" constant="12" id="dvh-Bx-K9f"/>
|
||||
<constraint firstItem="SFF-mL-yc8" firstAttribute="top" secondItem="Ut3-yd-q6G" secondAttribute="top" constant="4" id="fXo-df-bJh"/>
|
||||
<constraint firstItem="SFF-mL-yc8" firstAttribute="top" secondItem="hQy-ng-ijd" secondAttribute="bottom" constant="16" id="eM7-OM-Qsz"/>
|
||||
<constraint firstItem="mwT-nY-TrX" firstAttribute="leading" secondItem="Ubm-Pk-l7x" secondAttribute="leading" id="fb7-Og-rSp"/>
|
||||
<constraint firstItem="ulQ-kB-eNO" firstAttribute="centerY" secondItem="48p-6Z-Yid" secondAttribute="centerY" id="gSz-1T-Zp7"/>
|
||||
<constraint firstItem="Ci4-fW-KjU" firstAttribute="top" secondItem="Tdg-6Y-gvW" secondAttribute="bottom" constant="16" id="hXl-1D-lTD"/>
|
||||
<constraint firstAttribute="bottom" secondItem="mwT-nY-TrX" secondAttribute="bottom" constant="4" id="jFE-ye-pSr"/>
|
||||
<constraint firstItem="ucw-vG-yLt" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Ut3-yd-q6G" secondAttribute="leading" id="lDL-JN-ANP"/>
|
||||
<constraint firstItem="mwT-nY-TrX" firstAttribute="top" secondItem="j0t-Wa-UTL" secondAttribute="bottom" constant="14" id="nE9-nH-ueT"/>
|
||||
<constraint firstItem="Z6O-Zt-V1g" firstAttribute="width" secondItem="SFF-mL-yc8" secondAttribute="width" id="noW-Jf-Xbs"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Tdg-6Y-gvW" secondAttribute="trailing" id="qzz-gu-8kO"/>
|
||||
<constraint firstItem="Wsb-Lr-8Q7" firstAttribute="firstBaseline" secondItem="Ci4-fW-KjU" secondAttribute="firstBaseline" id="rPX-je-OG5"/>
|
||||
<constraint firstItem="Ci4-fW-KjU" firstAttribute="leading" secondItem="Wsb-Lr-8Q7" secondAttribute="trailing" constant="8" symbolic="YES" id="rcx-B6-zLP"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="mwT-nY-TrX" secondAttribute="trailing" id="skS-m8-bVR"/>
|
||||
<constraint firstItem="SFF-mL-yc8" firstAttribute="leading" secondItem="ucw-vG-yLt" secondAttribute="trailing" constant="8" symbolic="YES" id="yBm-Dc-lGA"/>
|
||||
<constraint firstAttribute="trailing" secondItem="48p-6Z-Yid" secondAttribute="trailing" id="zQB-Eg-KRJ"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Ci4-fW-KjU" secondAttribute="trailing" id="zbx-Ch-NEt"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
@@ -219,29 +242,29 @@
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="articleTextSizePopup" destination="Z6O-Zt-V1g" id="qNu-i3-fFB"/>
|
||||
<outlet property="defaultBrowserPopup" destination="Ci4-fW-KjU" id="7Nh-nU-Sbc"/>
|
||||
<outlet property="defaultRSSReaderPopup" destination="48p-6Z-Yid" id="qwI-fd-LlN"/>
|
||||
<outlet property="showUnreadCountCheckbox" destination="mwT-nY-TrX" id="ZH9-P5-JkT"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<customObject id="bSQ-tq-wd3" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
<userDefaultsController representsSharedInstance="YES" id="mAF-gO-1PI"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-570" y="395"/>
|
||||
<point key="canvasLocation" x="-568.5" y="438.5"/>
|
||||
</scene>
|
||||
<!--Advanced Preferences View Controller-->
|
||||
<scene sceneID="z1G-rc-sP5">
|
||||
<objects>
|
||||
<viewController storyboardIdentifier="Advanced" id="GNh-Wp-giO" customClass="AdvancedPreferencesViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" id="Hij-7D-6Pw">
|
||||
<rect key="frame" x="0.0" y="0.0" width="450" height="278"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="450" height="290"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="uJD-OF-YVY">
|
||||
<rect key="frame" x="60" y="20" width="330" height="238"/>
|
||||
<rect key="frame" x="60" y="20" width="330" height="250"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="1000" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="EH5-aS-E55">
|
||||
<rect key="frame" x="-2" y="222" width="87" height="16"/>
|
||||
<rect key="frame" x="-2" y="234" width="87" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="App Updates:" id="zqG-X2-E9b">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -249,7 +272,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="T4A-0o-p2w">
|
||||
<rect key="frame" x="89" y="221" width="149" height="18"/>
|
||||
<rect key="frame" x="89" y="233" width="149" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Check automatically" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="dm8-Xy-0Ba">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -259,7 +282,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Q6M-Iz-Ypx">
|
||||
<rect key="frame" x="17" y="194" width="68" height="16"/>
|
||||
<rect key="frame" x="17" y="206" width="68" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Download:" id="6bb-c0-guo">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -267,7 +290,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="QCu-J4-0yV">
|
||||
<rect key="frame" x="89" y="193" width="114" height="18"/>
|
||||
<rect key="frame" x="89" y="205" width="114" height="18"/>
|
||||
<buttonCell key="cell" type="radio" title="Release builds" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="F8M-rS-und">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -277,7 +300,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="CeE-AE-hRG">
|
||||
<rect key="frame" x="89" y="171" width="92" height="18"/>
|
||||
<rect key="frame" x="89" y="183" width="92" height="18"/>
|
||||
<buttonCell key="cell" type="radio" title="Test builds" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="Fuf-rU-D6M">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -287,7 +310,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="MzL-QQ-2oL">
|
||||
<rect key="frame" x="-2" y="116" width="334" height="48"/>
|
||||
<rect key="frame" x="-2" y="128" width="334" height="48"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="330" id="jf8-5e-Eij"/>
|
||||
</constraints>
|
||||
@@ -298,7 +321,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="TKI-a9-bRX">
|
||||
<rect key="frame" x="84" y="81" width="148" height="32"/>
|
||||
<rect key="frame" x="84" y="93" width="148" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Check for Updates" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="AaA-Rr-UYD">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -308,7 +331,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="1000" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="SUN-k3-ZEb">
|
||||
<rect key="frame" x="12" y="40" width="73" height="16"/>
|
||||
<rect key="frame" x="12" y="52" width="73" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Crash logs:" id="qcq-fU-Ks0">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -316,7 +339,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button horizontalHuggingPriority="1000" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="UHg-1l-FlD">
|
||||
<rect key="frame" x="89" y="39" width="142" height="18"/>
|
||||
<rect key="frame" x="89" y="51" width="142" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Send automatically" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="jnc-C5-4oI">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -345,6 +368,12 @@
|
||||
<action selector="showPrivacyPolicy:" target="VX1-M3-K0J" id="s1x-cP-hGd"/>
|
||||
</connections>
|
||||
</button>
|
||||
<box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="UD5-5N-W4F">
|
||||
<rect key="frame" x="0.0" y="77" width="330" height="5"/>
|
||||
</box>
|
||||
<box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="B1Q-jV-3Yl">
|
||||
<rect key="frame" x="0.0" y="33" width="330" height="5"/>
|
||||
</box>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="MzL-QQ-2oL" secondAttribute="trailing" id="04t-Su-3fv"/>
|
||||
@@ -354,6 +383,8 @@
|
||||
<constraint firstItem="TKI-a9-bRX" firstAttribute="leading" secondItem="CeE-AE-hRG" secondAttribute="leading" id="6Sm-VV-Qda"/>
|
||||
<constraint firstItem="EH5-aS-E55" firstAttribute="leading" secondItem="uJD-OF-YVY" secondAttribute="leading" id="6eS-X9-PTK"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="UHg-1l-FlD" secondAttribute="trailing" id="7gl-UP-wqg"/>
|
||||
<constraint firstItem="UD5-5N-W4F" firstAttribute="leading" secondItem="uJD-OF-YVY" secondAttribute="leading" id="98g-T1-9fR"/>
|
||||
<constraint firstItem="B1Q-jV-3Yl" firstAttribute="leading" secondItem="uJD-OF-YVY" secondAttribute="leading" id="Fxs-zN-mlV"/>
|
||||
<constraint firstItem="UHg-1l-FlD" firstAttribute="firstBaseline" secondItem="SUN-k3-ZEb" secondAttribute="firstBaseline" id="MAL-Ip-mEN"/>
|
||||
<constraint firstItem="MzL-QQ-2oL" firstAttribute="leading" secondItem="uJD-OF-YVY" secondAttribute="leading" id="MMt-v0-0gl"/>
|
||||
<constraint firstItem="CeE-AE-hRG" firstAttribute="leading" secondItem="T4A-0o-p2w" secondAttribute="leading" id="NWB-BO-GtL"/>
|
||||
@@ -363,15 +394,19 @@
|
||||
<constraint firstItem="EH5-aS-E55" firstAttribute="top" secondItem="uJD-OF-YVY" secondAttribute="top" id="VDU-as-fdx"/>
|
||||
<constraint firstAttribute="bottom" secondItem="uuc-f2-OFX" secondAttribute="bottom" id="YA7-Xm-cFO"/>
|
||||
<constraint firstItem="Q6M-Iz-Ypx" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="uJD-OF-YVY" secondAttribute="leading" id="Ygv-ha-RLn"/>
|
||||
<constraint firstItem="UD5-5N-W4F" firstAttribute="top" secondItem="TKI-a9-bRX" secondAttribute="bottom" constant="20" symbolic="YES" id="b3Y-RX-O4j"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="TKI-a9-bRX" secondAttribute="trailing" id="bLP-TU-TeL"/>
|
||||
<constraint firstItem="SUN-k3-ZEb" firstAttribute="trailing" secondItem="Q6M-Iz-Ypx" secondAttribute="trailing" id="c23-mt-Mfd"/>
|
||||
<constraint firstAttribute="trailing" secondItem="UD5-5N-W4F" secondAttribute="trailing" id="csy-6Y-uJq"/>
|
||||
<constraint firstItem="SUN-k3-ZEb" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="uJD-OF-YVY" secondAttribute="leading" id="dj1-Uj-ibG"/>
|
||||
<constraint firstItem="MzL-QQ-2oL" firstAttribute="top" secondItem="CeE-AE-hRG" secondAttribute="bottom" constant="8" symbolic="YES" id="emd-u5-hgZ"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="uuc-f2-OFX" secondAttribute="trailing" id="gBp-7A-zG6"/>
|
||||
<constraint firstAttribute="trailing" secondItem="B1Q-jV-3Yl" secondAttribute="trailing" id="h6j-aP-oTs"/>
|
||||
<constraint firstItem="CeE-AE-hRG" firstAttribute="top" secondItem="QCu-J4-0yV" secondAttribute="bottom" constant="6" symbolic="YES" id="hYd-1l-oMg"/>
|
||||
<constraint firstItem="uuc-f2-OFX" firstAttribute="top" secondItem="UHg-1l-FlD" secondAttribute="bottom" constant="20" symbolic="YES" id="jcZ-pH-ABY"/>
|
||||
<constraint firstItem="uuc-f2-OFX" firstAttribute="top" secondItem="UHg-1l-FlD" secondAttribute="bottom" constant="32" id="jcZ-pH-ABY"/>
|
||||
<constraint firstItem="T4A-0o-p2w" firstAttribute="firstBaseline" secondItem="EH5-aS-E55" secondAttribute="firstBaseline" id="jvM-Qd-rbB"/>
|
||||
<constraint firstItem="TKI-a9-bRX" firstAttribute="top" secondItem="MzL-QQ-2oL" secondAttribute="bottom" constant="8" symbolic="YES" id="lIt-NB-IL8"/>
|
||||
<constraint firstItem="B1Q-jV-3Yl" firstAttribute="top" secondItem="UHg-1l-FlD" secondAttribute="bottom" constant="16" id="mlO-QB-xom"/>
|
||||
<constraint firstItem="QCu-J4-0yV" firstAttribute="top" secondItem="T4A-0o-p2w" secondAttribute="bottom" constant="12" id="nBX-kW-ncB"/>
|
||||
<constraint firstItem="T4A-0o-p2w" firstAttribute="leading" secondItem="EH5-aS-E55" secondAttribute="trailing" constant="8" symbolic="YES" id="oNo-Il-411"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="CeE-AE-hRG" secondAttribute="trailing" id="qB6-BG-c3D"/>
|
||||
@@ -407,22 +442,22 @@
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="7UM-iq-OLB" customClass="PreferencesTableViewBackgroundView" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<rect key="frame" x="20" y="44" width="180" height="294"/>
|
||||
<rect key="frame" x="20" y="44" width="180" height="314"/>
|
||||
<subviews>
|
||||
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" hasHorizontalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="PaF-du-r3c">
|
||||
<rect key="frame" x="1" y="0.0" width="178" height="293"/>
|
||||
<clipView key="contentView" ambiguous="YES" id="cil-Gq-akO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="178" height="293"/>
|
||||
<rect key="frame" x="1" y="0.0" width="178" height="313"/>
|
||||
<clipView key="contentView" id="cil-Gq-akO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="178" height="313"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" viewBased="YES" id="aTp-KR-y6b">
|
||||
<rect key="frame" x="0.0" y="0.0" width="207" height="293"/>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" viewBased="YES" id="aTp-KR-y6b">
|
||||
<rect key="frame" x="0.0" y="0.0" width="178" height="313"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn width="175" minWidth="40" maxWidth="1000" id="JSx-yi-vwt">
|
||||
<tableColumn width="146" minWidth="40" maxWidth="1000" id="JSx-yi-vwt">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -435,7 +470,7 @@
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="Cell" id="h2e-5a-qNO">
|
||||
<rect key="frame" x="11" y="1" width="184" height="17"/>
|
||||
<rect key="frame" x="11" y="1" width="155" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="27f-p8-Wnt">
|
||||
@@ -447,7 +482,7 @@
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="lKA-xK-bHU"/>
|
||||
</imageView>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hR2-bm-0wE">
|
||||
<rect key="frame" x="26" y="1" width="154" height="16"/>
|
||||
<rect key="frame" x="26" y="1" width="125" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="CcS-BO-sdv">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -523,7 +558,7 @@
|
||||
<rect key="frame" x="83" y="20" width="117" height="24"/>
|
||||
</customView>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="Y7D-xQ-wep">
|
||||
<rect key="frame" x="208" y="20" width="222" height="318"/>
|
||||
<rect key="frame" x="208" y="20" width="222" height="338"/>
|
||||
</customView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
@@ -578,22 +613,22 @@
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="pjs-G4-byk" customClass="PreferencesTableViewBackgroundView" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<rect key="frame" x="20" y="44" width="180" height="287"/>
|
||||
<rect key="frame" x="20" y="44" width="180" height="307"/>
|
||||
<subviews>
|
||||
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" hasHorizontalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="29T-r2-ckC">
|
||||
<rect key="frame" x="1" y="0.0" width="178" height="286"/>
|
||||
<clipView key="contentView" ambiguous="YES" id="dXw-GY-TP8">
|
||||
<rect key="frame" x="0.0" y="0.0" width="178" height="286"/>
|
||||
<rect key="frame" x="1" y="0.0" width="178" height="306"/>
|
||||
<clipView key="contentView" id="dXw-GY-TP8">
|
||||
<rect key="frame" x="0.0" y="0.0" width="178" height="306"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" viewBased="YES" id="dfn-Vn-oDp">
|
||||
<rect key="frame" x="0.0" y="0.0" width="207" height="286"/>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" viewBased="YES" id="dfn-Vn-oDp">
|
||||
<rect key="frame" x="0.0" y="0.0" width="178" height="306"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn width="175" minWidth="40" maxWidth="1000" id="jBM-96-TEB">
|
||||
<tableColumn width="146" minWidth="40" maxWidth="1000" id="jBM-96-TEB">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -606,7 +641,7 @@
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="Cell" id="xQs-6E-Kpy">
|
||||
<rect key="frame" x="11" y="1" width="184" height="17"/>
|
||||
<rect key="frame" x="11" y="1" width="155" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kmG-vw-CbN">
|
||||
@@ -618,7 +653,7 @@
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="OVD-Jo-TXU"/>
|
||||
</imageView>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6cr-cB-qAN">
|
||||
<rect key="frame" x="26" y="1" width="154" height="16"/>
|
||||
<rect key="frame" x="26" y="1" width="125" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="goO-QG-kk7">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -690,7 +725,7 @@
|
||||
<rect key="frame" x="83" y="20" width="117" height="24"/>
|
||||
</customView>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="N1N-pE-gBL">
|
||||
<rect key="frame" x="208" y="20" width="222" height="311"/>
|
||||
<rect key="frame" x="208" y="20" width="222" height="331"/>
|
||||
</customView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
|
||||
@@ -39,6 +39,14 @@ final class DetailWebViewController: NSViewController, WKUIDelegate {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
private var articleTextSize = AppDefaults.shared.articleTextSize {
|
||||
didSet {
|
||||
if articleTextSize != oldValue {
|
||||
reloadHTML()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !MAC_APP_STORE
|
||||
private var webInspectorEnabled: Bool {
|
||||
@@ -64,7 +72,7 @@ final class DetailWebViewController: NSViewController, WKUIDelegate {
|
||||
// Wrap the webview in a box configured with the same background color that the web view uses
|
||||
let box = NSBox(frame: .zero)
|
||||
box.boxType = .custom
|
||||
box.borderType = .noBorder
|
||||
box.isTransparent = true
|
||||
box.titlePosition = .noTitle
|
||||
box.contentViewMargins = .zero
|
||||
box.fillColor = NSColor(named: "webviewBackgroundColor")!
|
||||
@@ -118,7 +126,7 @@ final class DetailWebViewController: NSViewController, WKUIDelegate {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(webFeedIconDidBecomeAvailable(_:)), name: .WebFeedIconDidBecomeAvailable, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(avatarDidBecomeAvailable(_:)), name: .AvatarDidBecomeAvailable, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil)
|
||||
|
||||
webView.loadFileURL(ArticleRenderer.blank.url, allowingReadAccessTo: ArticleRenderer.blank.baseURL)
|
||||
}
|
||||
@@ -137,6 +145,10 @@ final class DetailWebViewController: NSViewController, WKUIDelegate {
|
||||
reloadArticleImage()
|
||||
}
|
||||
|
||||
@objc func userDefaultsDidChange(_ note: Notification) {
|
||||
self.articleTextSize = AppDefaults.shared.articleTextSize
|
||||
}
|
||||
|
||||
// MARK: Media Functions
|
||||
|
||||
func stopMediaPlayback() {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
body {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 64px;
|
||||
padding-left: 64px;
|
||||
padding-right: 64px;
|
||||
padding-left: 48px;
|
||||
padding-right: 48px;
|
||||
font-family: -apple-system;
|
||||
font-size: 18px;
|
||||
font-size: [[font-size]]px;
|
||||
}
|
||||
|
||||
:root {
|
||||
|
||||
@@ -323,13 +323,16 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations {
|
||||
NSCursor.setHiddenUntilMouseMoves(true)
|
||||
|
||||
// TODO: handle search mode
|
||||
if timelineViewController.canGoToNextUnread() {
|
||||
goToNextUnreadInTimeline()
|
||||
if timelineViewController.canGoToNextUnread(wrappingToTop: false) {
|
||||
goToNextUnreadInTimeline(wrappingToTop: false)
|
||||
}
|
||||
else if sidebarViewController.canGoToNextUnread() {
|
||||
sidebarViewController.goToNextUnread()
|
||||
if timelineViewController.canGoToNextUnread() {
|
||||
goToNextUnreadInTimeline()
|
||||
else if sidebarViewController.canGoToNextUnread(wrappingToTop: true) {
|
||||
sidebarViewController.goToNextUnread(wrappingToTop: true)
|
||||
|
||||
// If we ended up on the same timelineViewController, we may need to wrap
|
||||
// around to the top of its contents.
|
||||
if timelineViewController.canGoToNextUnread(wrappingToTop: true) {
|
||||
goToNextUnreadInTimeline(wrappingToTop: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -995,13 +998,13 @@ private extension MainWindowController {
|
||||
|
||||
// MARK: - Command Validation
|
||||
|
||||
func canGoToNextUnread() -> Bool {
|
||||
func canGoToNextUnread(wrappingToTop wrapping: Bool = false) -> Bool {
|
||||
|
||||
guard let timelineViewController = currentTimelineViewController, let sidebarViewController = sidebarViewController else {
|
||||
return false
|
||||
}
|
||||
// TODO: handle search mode
|
||||
return timelineViewController.canGoToNextUnread() || sidebarViewController.canGoToNextUnread()
|
||||
return timelineViewController.canGoToNextUnread(wrappingToTop: wrapping) || sidebarViewController.canGoToNextUnread(wrappingToTop: wrapping)
|
||||
}
|
||||
|
||||
func canMarkAllAsRead() -> Bool {
|
||||
@@ -1188,14 +1191,14 @@ private extension MainWindowController {
|
||||
|
||||
// MARK: - Misc.
|
||||
|
||||
func goToNextUnreadInTimeline() {
|
||||
func goToNextUnreadInTimeline(wrappingToTop wrapping: Bool) {
|
||||
|
||||
guard let timelineViewController = currentTimelineViewController else {
|
||||
return
|
||||
}
|
||||
|
||||
if timelineViewController.canGoToNextUnread() {
|
||||
timelineViewController.goToNextUnread()
|
||||
if timelineViewController.canGoToNextUnread(wrappingToTop: wrapping) {
|
||||
timelineViewController.goToNextUnread(wrappingToTop: wrapping)
|
||||
makeTimelineViewFirstResponder()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@ import RSCore
|
||||
}
|
||||
|
||||
func sharingServicePicker(_ sharingServicePicker: NSSharingServicePicker, sharingServicesForItems items: [Any], proposedSharingServices proposedServices: [NSSharingService]) -> [NSSharingService] {
|
||||
return proposedServices + SharingServicePickerDelegate.customSharingServices(for: items)
|
||||
let filteredServices = proposedServices.filter { $0.menuItemTitle != "NetNewsWire" }
|
||||
return filteredServices + SharingServicePickerDelegate.customSharingServices(for: items)
|
||||
}
|
||||
|
||||
func sharingServicePicker(_ sharingServicePicker: NSSharingServicePicker, delegateFor sharingService: NSSharingService) -> NSSharingServiceDelegate? {
|
||||
|
||||
@@ -294,15 +294,15 @@ protocol SidebarDelegate: class {
|
||||
|
||||
// MARK: - Navigation
|
||||
|
||||
func canGoToNextUnread() -> Bool {
|
||||
if let _ = nextSelectableRowWithUnreadArticle() {
|
||||
func canGoToNextUnread(wrappingToTop wrapping: Bool = false) -> Bool {
|
||||
if let _ = nextSelectableRowWithUnreadArticle(wrappingToTop: wrapping) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func goToNextUnread() {
|
||||
guard let row = nextSelectableRowWithUnreadArticle() else {
|
||||
func goToNextUnread(wrappingToTop wrapping: Bool = false) {
|
||||
guard let row = nextSelectableRowWithUnreadArticle(wrappingToTop: wrapping) else {
|
||||
assertionFailure("goToNextUnread called before checking if there is a next unread.")
|
||||
return
|
||||
}
|
||||
@@ -685,26 +685,42 @@ private extension SidebarViewController {
|
||||
return false
|
||||
}
|
||||
|
||||
func nextSelectableRowWithUnreadArticle() -> Int? {
|
||||
// Skip group items, because they should never be selected.
|
||||
|
||||
let selectedRow = outlineView.selectedRow
|
||||
let numberOfRows = outlineView.numberOfRows
|
||||
var row = selectedRow + 1
|
||||
|
||||
while (row < numberOfRows) {
|
||||
if rowHasAtLeastOneUnreadArticle(row) && !rowIsGroupItem(row) {
|
||||
return row
|
||||
}
|
||||
row += 1
|
||||
func rowIsExpandedFolder(_ row: Int) -> Bool {
|
||||
if let node = nodeForRow(row), outlineView.isItemExpanded(node) {
|
||||
return true
|
||||
}
|
||||
|
||||
row = 0
|
||||
while (row <= selectedRow) {
|
||||
if rowHasAtLeastOneUnreadArticle(row) && !rowIsGroupItem(row) {
|
||||
return false
|
||||
}
|
||||
|
||||
func shouldSkipRow(_ row: Int) -> Bool {
|
||||
let skipExpandedFolders = UserDefaults.standard.bool(forKey: "JalkutRespectFolderExpansionOnNextUnread")
|
||||
|
||||
// Skip group items, because they should never be selected.
|
||||
// Skip expanded folders only if Jalkut's pref is enabled.
|
||||
if rowIsGroupItem(row) || (skipExpandedFolders && rowIsExpandedFolder(row)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func nextSelectableRowWithUnreadArticle(wrappingToTop wrapping: Bool = false) -> Int? {
|
||||
let numberOfRows = outlineView.numberOfRows
|
||||
let startRow = outlineView.selectedRow + 1
|
||||
|
||||
let orderedRows: [Int]
|
||||
if startRow == numberOfRows {
|
||||
// Last item is selected, so start at the beginning if we allow wrapping
|
||||
orderedRows = wrapping ? Array(0..<numberOfRows) : []
|
||||
} else {
|
||||
// Start at the selection and wrap around to the beginning
|
||||
orderedRows = Array(startRow..<numberOfRows) + (wrapping ? Array(0..<startRow) : [])
|
||||
}
|
||||
|
||||
for row in orderedRows {
|
||||
// Skip group items, because they should never be selected.
|
||||
if rowHasAtLeastOneUnreadArticle(row) && !shouldSkipRow(row) {
|
||||
return row
|
||||
}
|
||||
row += 1
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -10,6 +10,11 @@ import AppKit
|
||||
import Articles
|
||||
import RSCore
|
||||
|
||||
extension Article: PasteboardWriterOwner {
|
||||
public var pasteboardWriter: NSPasteboardWriting {
|
||||
return ArticlePasteboardWriter(article: self)
|
||||
}
|
||||
}
|
||||
|
||||
@objc final class ArticlePasteboardWriter: NSObject, NSPasteboardWriting {
|
||||
|
||||
|
||||
@@ -549,7 +549,7 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
|
||||
tableView.scrollTo(row: ix)
|
||||
}
|
||||
|
||||
func goToNextUnread() {
|
||||
func goToNextUnread(wrappingToTop wrapping: Bool = false) {
|
||||
guard let ix = indexOfNextUnreadArticle() else {
|
||||
return
|
||||
}
|
||||
@@ -558,15 +558,15 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
|
||||
tableView.scrollTo(row: ix)
|
||||
}
|
||||
|
||||
func canGoToNextUnread() -> Bool {
|
||||
guard let _ = indexOfNextUnreadArticle() else {
|
||||
func canGoToNextUnread(wrappingToTop wrapping: Bool = false) -> Bool {
|
||||
guard let _ = indexOfNextUnreadArticle(wrappingToTop: wrapping) else {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func indexOfNextUnreadArticle() -> Int? {
|
||||
return articles.rowOfNextUnreadArticle(tableView.selectedRow)
|
||||
func indexOfNextUnreadArticle(wrappingToTop wrapping: Bool = false) -> Int? {
|
||||
return articles.rowOfNextUnreadArticle(tableView.selectedRow, wrappingToTop: wrapping)
|
||||
}
|
||||
|
||||
func focus() {
|
||||
|
||||
@@ -17,40 +17,14 @@
|
||||
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||
<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="contentRect" x="196" y="240" width="398" height="135"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1792" height="1095"/>
|
||||
<view key="contentView" wantsLayer="YES" misplaced="YES" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="398" height="205"/>
|
||||
<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"/>
|
||||
<subviews>
|
||||
<stackView distribution="fill" orientation="horizontal" alignment="bottom" spacing="19" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uDK-ji-zlT">
|
||||
<rect key="frame" x="127" y="107" width="145" height="38"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ySx-qg-WbT">
|
||||
<rect key="frame" x="0.0" y="0.0" width="36" height="36"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="36" id="BKI-n8-fbR"/>
|
||||
<constraint firstAttribute="height" constant="36" id="NLk-V3-hn9"/>
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="accountCloudKit" id="9RZ-J3-ioX"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="80D-3X-rL2">
|
||||
<rect key="frame" x="53" y="0.0" width="94" height="38"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="iCloud" id="1d2-Mx-TKe">
|
||||
<font key="font" metaFont="system" size="32"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<visibilityPriorities>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
</visibilityPriorities>
|
||||
<customSpacing>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
</customSpacing>
|
||||
<stackView distribution="fill" orientation="horizontal" alignment="bottom" spacing="19" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" ambiguous="YES" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uDK-ji-zlT">
|
||||
<rect key="frame" x="199" y="59" width="0.0" height="16"/>
|
||||
</stackView>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xqo-gP-MPl">
|
||||
<rect key="frame" x="310" y="13" width="75" height="32"/>
|
||||
@@ -78,34 +52,56 @@ Gw
|
||||
<action selector="cancel:" target="-2" id="uDi-hX-dXu"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3Kj-Cl-FJQ">
|
||||
<rect key="frame" x="47" y="56" width="304" height="16"/>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ySx-qg-WbT">
|
||||
<rect key="frame" x="20" y="71" width="50" height="50"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="300" id="xiK-wa-r3v"/>
|
||||
<constraint firstAttribute="width" constant="50" id="LlV-kM-gHE"/>
|
||||
<constraint firstAttribute="height" constant="50" id="MjL-TR-9ey"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" selectable="YES" allowsUndo="NO" title="This account syncs using your iCloud account." id="wfr-Dv-UIF">
|
||||
<font key="font" metaFont="system"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="accountCloudKit" id="9RZ-J3-ioX"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="80D-3X-rL2">
|
||||
<rect key="frame" x="76" y="99" width="304" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Sign in to your iCloud account." id="1d2-Mx-TKe">
|
||||
<font key="font" textStyle="headline" name=".SFNS-Bold"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3Kj-Cl-FJQ">
|
||||
<rect key="frame" x="76" y="59" width="304" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="32" id="ZJN-cn-p1x"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" selectable="YES" allowsUndo="NO" title="This account syncs across your Mac and iOS devices using your iCloud account." id="wfr-Dv-UIF">
|
||||
<font key="font" textStyle="callout" name=".SFNS-Regular"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="9eG-vV-s8c" firstAttribute="top" secondItem="3Kj-Cl-FJQ" secondAttribute="bottom" constant="16" id="BZP-Fw-AVu"/>
|
||||
<constraint firstItem="80D-3X-rL2" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" symbolic="YES" id="4kd-dG-z7L"/>
|
||||
<constraint firstItem="ySx-qg-WbT" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" symbolic="YES" id="9lr-cs-zBS"/>
|
||||
<constraint firstItem="80D-3X-rL2" firstAttribute="leading" secondItem="ySx-qg-WbT" secondAttribute="trailing" constant="8" symbolic="YES" id="Ab3-E3-UxG"/>
|
||||
<constraint firstItem="9eG-vV-s8c" firstAttribute="centerY" secondItem="xqo-gP-MPl" secondAttribute="centerY" id="DLC-C8-enC"/>
|
||||
<constraint firstAttribute="bottom" secondItem="xqo-gP-MPl" secondAttribute="bottom" constant="20" id="HgX-ud-184"/>
|
||||
<constraint firstItem="3Kj-Cl-FJQ" firstAttribute="centerX" secondItem="EiT-Mj-1SZ" secondAttribute="centerX" id="bfd-35-bLi"/>
|
||||
<constraint firstItem="3Kj-Cl-FJQ" firstAttribute="top" secondItem="80D-3X-rL2" secondAttribute="bottom" constant="35" id="gh3-I9-x4r"/>
|
||||
<constraint firstItem="80D-3X-rL2" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="16" id="h30-eN-6VF"/>
|
||||
<constraint firstAttribute="trailing" secondItem="3Kj-Cl-FJQ" secondAttribute="trailing" constant="20" symbolic="YES" id="QS1-QM-lOc"/>
|
||||
<constraint firstItem="3Kj-Cl-FJQ" firstAttribute="leading" secondItem="ySx-qg-WbT" secondAttribute="trailing" constant="8" symbolic="YES" id="Ue2-Kp-nGw"/>
|
||||
<constraint firstItem="3Kj-Cl-FJQ" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="44" id="V0G-KC-FTs"/>
|
||||
<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="xqo-gP-MPl" firstAttribute="leading" secondItem="9eG-vV-s8c" secondAttribute="trailing" constant="11" 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"/>
|
||||
<constraint firstAttribute="trailing" secondItem="xqo-gP-MPl" secondAttribute="trailing" constant="20" id="z4O-vd-ear"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="hpu-h7-p4Z"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="99" y="114.5"/>
|
||||
<point key="canvasLocation" x="99" y="79.5"/>
|
||||
</window>
|
||||
</objects>
|
||||
<resources>
|
||||
|
||||
@@ -20,70 +20,15 @@
|
||||
<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"/>
|
||||
<view key="contentView" wantsLayer="YES" misplaced="YES" id="EiT-Mj-1SZ">
|
||||
<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"/>
|
||||
<subviews>
|
||||
<stackView distribution="fill" orientation="horizontal" alignment="bottom" spacing="19" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uDK-ji-zlT">
|
||||
<rect key="frame" x="93" y="160" width="213" height="38"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ySx-qg-WbT">
|
||||
<rect key="frame" x="0.0" y="0.0" width="36" height="36"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="36" id="BKI-n8-fbR"/>
|
||||
<constraint firstAttribute="height" constant="36" id="NLk-V3-hn9"/>
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="accountLocal" id="9RZ-J3-ioX"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="80D-3X-rL2">
|
||||
<rect key="frame" x="53" y="0.0" width="162" height="38"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="On My Mac" id="1d2-Mx-TKe">
|
||||
<font key="font" metaFont="system" size="32"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<visibilityPriorities>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
</visibilityPriorities>
|
||||
<customSpacing>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
</customSpacing>
|
||||
<rect key="frame" x="199" y="151" width="0.0" height="102"/>
|
||||
</stackView>
|
||||
<stackView distribution="fill" orientation="horizontal" alignment="firstBaseline" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6Q7-nI-h5u">
|
||||
<rect key="frame" x="105" y="104" width="188" height="21"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MWg-UL-xtj">
|
||||
<rect key="frame" x="-2" y="3" width="44" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Name:" id="AVh-ns-LEN">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="f9b-FM-i8Q">
|
||||
<rect key="frame" x="48" y="0.0" width="140" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="140" id="cdf-tS-vno"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="Y12-ua-Bj8">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<visibilityPriorities>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
</visibilityPriorities>
|
||||
<customSpacing>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
</customSpacing>
|
||||
<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"/>
|
||||
@@ -111,29 +56,75 @@ Gw
|
||||
<action selector="cancel:" target="-2" id="uDi-hX-dXu"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3Kj-Cl-FJQ">
|
||||
<rect key="frame" x="87" y="56" width="224" height="32"/>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="80D-3X-rL2">
|
||||
<rect key="frame" x="87" y="169" width="293" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Create a local account on your Mac." id="1d2-Mx-TKe">
|
||||
<font key="font" textStyle="headline" name=".SFNS-Bold"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ySx-qg-WbT">
|
||||
<rect key="frame" x="20" y="135" width="50" height="50"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="220" id="xiK-wa-r3v"/>
|
||||
<constraint firstAttribute="height" constant="50" id="Hzy-OP-e84"/>
|
||||
<constraint firstAttribute="width" constant="50" id="Z8v-O8-FE5"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" selectable="YES" allowsUndo="NO" title="This account stores all of its data on your Mac. It does not sync." id="wfr-Dv-UIF">
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="accountLocal" id="9RZ-J3-ioX"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MWg-UL-xtj">
|
||||
<rect key="frame" x="87" y="98" width="44" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Name:" id="AVh-ns-LEN">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="f9b-FM-i8Q">
|
||||
<rect key="frame" x="137" y="95" width="200" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="200" id="iff-tN-Gkx"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="Y12-ua-Bj8">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3Kj-Cl-FJQ">
|
||||
<rect key="frame" x="87" y="129" width="293" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="32" id="CaZ-mY-r4X"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" selectable="YES" allowsUndo="NO" title="Local accounts store their data on your Mac. They do not sync across your devices." id="wfr-Dv-UIF">
|
||||
<font key="font" textStyle="callout" name=".SFNS-Regular"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="6Q7-nI-h5u" firstAttribute="top" secondItem="80D-3X-rL2" secondAttribute="bottom" constant="35" id="3Sa-lr-BqF"/>
|
||||
<constraint firstItem="9eG-vV-s8c" firstAttribute="top" secondItem="3Kj-Cl-FJQ" secondAttribute="bottom" constant="16" id="BZP-Fw-AVu"/>
|
||||
<constraint firstAttribute="bottom" secondItem="uDK-ji-zlT" secondAttribute="bottom" constant="151" id="14A-2i-FXI"/>
|
||||
<constraint firstItem="f9b-FM-i8Q" firstAttribute="top" secondItem="3Kj-Cl-FJQ" secondAttribute="bottom" constant="13" id="6xW-9w-pGi"/>
|
||||
<constraint firstItem="9eG-vV-s8c" firstAttribute="centerY" secondItem="xqo-gP-MPl" secondAttribute="centerY" id="DLC-C8-enC"/>
|
||||
<constraint firstAttribute="trailing" secondItem="f9b-FM-i8Q" secondAttribute="trailing" constant="61" id="Fgt-dR-DTr"/>
|
||||
<constraint firstAttribute="bottom" secondItem="xqo-gP-MPl" secondAttribute="bottom" constant="20" id="HgX-ud-184"/>
|
||||
<constraint firstItem="uDK-ji-zlT" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="-48" id="JWY-Q9-7sR"/>
|
||||
<constraint firstItem="6Q7-nI-h5u" firstAttribute="centerX" secondItem="EiT-Mj-1SZ" secondAttribute="centerX" id="KYO-G6-21s"/>
|
||||
<constraint firstItem="3Kj-Cl-FJQ" firstAttribute="top" secondItem="6Q7-nI-h5u" secondAttribute="bottom" constant="16" id="baJ-uI-EGJ"/>
|
||||
<constraint firstItem="3Kj-Cl-FJQ" firstAttribute="centerX" secondItem="EiT-Mj-1SZ" secondAttribute="centerX" id="bfd-35-bLi"/>
|
||||
<constraint firstItem="80D-3X-rL2" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="16" id="h30-eN-6VF"/>
|
||||
<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="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="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"/>
|
||||
<constraint firstAttribute="trailing" secondItem="80D-3X-rL2" secondAttribute="trailing" constant="20" symbolic="YES" id="xkO-OB-uR2"/>
|
||||
<constraint firstAttribute="trailing" secondItem="3Kj-Cl-FJQ" secondAttribute="trailing" constant="20" symbolic="YES" id="z0z-oa-qLm"/>
|
||||
<constraint firstAttribute="trailing" secondItem="xqo-gP-MPl" secondAttribute="trailing" constant="20" id="z4O-vd-ear"/>
|
||||
</constraints>
|
||||
</view>
|
||||
|
||||
@@ -23,7 +23,7 @@ class AccountsAddLocalWindowController: NSWindowController {
|
||||
override func windowDidLoad() {
|
||||
super.windowDidLoad()
|
||||
|
||||
localAccountNameTextField.stringValue = Account.defaultLocalAccountName
|
||||
localAccountNameTextField.stringValue = NSLocalizedString("Create a local account on your Mac.", comment: "Account Local")
|
||||
}
|
||||
|
||||
// MARK: API
|
||||
|
||||
@@ -3,15 +3,19 @@
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
|
||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="AccountsFeedWranglerWindowController" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="actionButton" destination="9mz-D9-krh" id="ozu-6Q-9Lb"/>
|
||||
<outlet property="errorMessageLabel" destination="byK-Sd-r7F" id="8zt-9d-dWQ"/>
|
||||
<outlet property="createNewAccountButton" destination="pPT-Cj-3vI" id="KAL-Y7-XQK"/>
|
||||
<outlet property="errorMessageLabel" destination="zwG-Ag-z8o" id="7a1-iJ-URN"/>
|
||||
<outlet property="noAccountTextField" destination="xEl-Ae-5r8" id="dU3-Jv-Aq8"/>
|
||||
<outlet property="passwordTextField" destination="JSa-LY-zNQ" id="5cF-bM-CJE"/>
|
||||
<outlet property="progressIndicator" destination="B0W-bh-Evv" id="Tiq-gx-s3F"/>
|
||||
<outlet property="signInTextField" destination="lti-yM-8LV" id="ZgR-2i-RXB"/>
|
||||
<outlet property="usernameTextField" destination="78p-Cf-f55" id="Gg5-Ce-RJv"/>
|
||||
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
|
||||
</connections>
|
||||
@@ -28,40 +32,13 @@
|
||||
<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="89" y="191" width="256" height="38"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Ssh-Dh-xbg">
|
||||
<rect key="frame" x="0.0" y="0.0" width="36" height="36"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="36" id="Ern-Kk-8LX"/>
|
||||
<constraint firstAttribute="width" constant="36" id="PLS-68-NMc"/>
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="accountFeedWrangler" id="y38-YL-woC"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lti-yM-8LV">
|
||||
<rect key="frame" x="53" y="0.0" width="205" height="38"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Feed Wrangler" id="ras-dj-nP8">
|
||||
<font key="font" metaFont="system" size="32"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<visibilityPriorities>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
</visibilityPriorities>
|
||||
<customSpacing>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
</customSpacing>
|
||||
<rect key="frame" x="217" y="229" width="0.0" height="0.0"/>
|
||||
</stackView>
|
||||
<gridView xPlacement="trailing" yPlacement="center" rowAlignment="none" rowSpacing="12" columnSpacing="14" translatesAutoresizingMaskIntoConstraints="NO" id="zBB-JH-huI">
|
||||
<rect key="frame" x="79" y="60" width="276" height="99"/>
|
||||
<gridView xPlacement="trailing" yPlacement="center" rowAlignment="none" rowSpacing="7" columnSpacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="zBB-JH-huI">
|
||||
<rect key="frame" x="80" y="127" width="270" height="49"/>
|
||||
<rows>
|
||||
<gridRow id="DRl-lC-vUc"/>
|
||||
<gridRow id="eW8-uH-txq"/>
|
||||
<gridRow id="DbI-7g-Xme"/>
|
||||
</rows>
|
||||
<columns>
|
||||
<gridColumn id="fCQ-jY-Mts"/>
|
||||
@@ -70,7 +47,7 @@
|
||||
<gridCells>
|
||||
<gridCell row="DRl-lC-vUc" column="fCQ-jY-Mts" id="4DI-01-jGD">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Zy6-9c-8TI">
|
||||
<rect key="frame" x="23" y="81" width="41" height="16"/>
|
||||
<rect key="frame" x="23" y="31" width="41" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Email:" id="DqN-SV-v35">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -80,11 +57,11 @@
|
||||
</gridCell>
|
||||
<gridCell row="DRl-lC-vUc" column="7CY-bX-6x4" id="Z0b-qS-MUJ">
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="78p-Cf-f55">
|
||||
<rect key="frame" x="76" y="78" width="200" height="21"/>
|
||||
<rect key="frame" x="70" y="28" width="200" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="200" id="Qin-jm-4zt"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="fCk-Tf-q01">
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="me@email.com" drawsBackground="YES" id="fCk-Tf-q01">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -93,7 +70,7 @@
|
||||
</gridCell>
|
||||
<gridCell row="eW8-uH-txq" column="fCQ-jY-Mts" id="Hqa-3w-cQv">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="wEx-TM-rPM">
|
||||
<rect key="frame" x="-2" y="48" width="66" height="16"/>
|
||||
<rect key="frame" x="-2" y="3" width="66" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Password:" id="7g8-Kk-ISg">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -103,11 +80,11 @@
|
||||
</gridCell>
|
||||
<gridCell row="eW8-uH-txq" column="7CY-bX-6x4" id="m16-3v-9pf">
|
||||
<secureTextField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JSa-LY-zNQ">
|
||||
<rect key="frame" x="76" y="45" width="200" height="21"/>
|
||||
<rect key="frame" x="70" y="0.0" width="200" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="200" id="eal-wa-1nU"/>
|
||||
</constraints>
|
||||
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="trK-OG-tBe">
|
||||
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="•••••••••" drawsBackground="YES" usesSingleLineMode="YES" id="trK-OG-tBe">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -117,17 +94,6 @@
|
||||
</secureTextFieldCell>
|
||||
</secureTextField>
|
||||
</gridCell>
|
||||
<gridCell row="DbI-7g-Xme" column="fCQ-jY-Mts" headOfMergedCell="xX0-vn-AId" xPlacement="leading" id="xX0-vn-AId">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="byK-Sd-r7F">
|
||||
<rect key="frame" x="-2" y="9" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" id="0yh-Ab-UTX">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="DbI-7g-Xme" column="7CY-bX-6x4" headOfMergedCell="xX0-vn-AId" id="hk5-St-E4y"/>
|
||||
</gridCells>
|
||||
</gridView>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9mz-D9-krh">
|
||||
@@ -156,22 +122,100 @@ Gw
|
||||
<action selector="cancel:" target="-2" id="WAD-ES-hpq"/>
|
||||
</connections>
|
||||
</button>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Ssh-Dh-xbg">
|
||||
<rect key="frame" x="20" y="179" width="50" height="50"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="50" id="Ern-Kk-8LX"/>
|
||||
<constraint firstAttribute="width" constant="50" id="PLS-68-NMc"/>
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="accountFeedWrangler" 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"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Sign in to your Feed Wrangler account." id="ras-dj-nP8">
|
||||
<font key="font" textStyle="headline" name=".SFNS-Bold"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xEl-Ae-5r8">
|
||||
<rect key="frame" x="78" y="193" width="216" height="15"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Don't have a Feed Wrangler account?" id="DFR-20-sjO">
|
||||
<font key="font" textStyle="callout" name=".SFNS-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="pPT-Cj-3vI">
|
||||
<rect key="frame" x="293" y="193" width="105" height="15"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="105" id="Ez2-gz-Wqf"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="roundRect" title="Create one here." bezelStyle="roundedRect" alignment="center" state="on" imageScaling="proportionallyDown" inset="2" id="tlF-nc-ZOr">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" textStyle="callout" name=".SFNS-Regular"/>
|
||||
</buttonCell>
|
||||
<color key="contentTintColor" name="AccentColor"/>
|
||||
<connections>
|
||||
<action selector="createAccountWithProvider:" target="-2" id="bp5-3n-RLW"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Uzn-QS-o4p">
|
||||
<rect key="frame" x="78" y="73" width="337" height="39"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="39" id="99q-po-zLV"/>
|
||||
<constraint firstAttribute="width" constant="333" id="oSi-jz-DZ8"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" title="Your username and password will be encrypted and stored in Keychain. " id="83j-VH-GgC">
|
||||
<font key="font" textStyle="callout" name=".SFNS-Regular"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</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="209" y="167" width="16" height="16"/>
|
||||
<rect key="frame" x="256" 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>
|
||||
<textFieldCell key="cell" id="b2G-2g-1KR">
|
||||
<font key="font" textStyle="subheadline" name=".SFNS-Regular"/>
|
||||
<color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<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 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="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="zBB-JH-huI" firstAttribute="top" secondItem="B0W-bh-Evv" secondAttribute="bottom" constant="8" id="V7z-a7-OOG"/>
|
||||
<constraint firstItem="9mz-D9-krh" firstAttribute="top" secondItem="zBB-JH-huI" secondAttribute="bottom" constant="20" symbolic="YES" id="Wu3-hp-Vzh"/>
|
||||
<constraint firstItem="zBB-JH-huI" firstAttribute="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" id="aFI-4s-mMv"/>
|
||||
<constraint firstItem="pPT-Cj-3vI" firstAttribute="centerY" secondItem="xEl-Ae-5r8" secondAttribute="centerY" id="XKR-hU-WpE"/>
|
||||
<constraint firstItem="Uzn-QS-o4p" firstAttribute="top" secondItem="JSa-LY-zNQ" secondAttribute="bottom" constant="15" id="Z84-bl-0dI"/>
|
||||
<constraint firstItem="XAM-Hb-0Hw" firstAttribute="leading" secondItem="B0W-bh-Evv" secondAttribute="trailing" constant="8" symbolic="YES" id="afl-Cl-zda"/>
|
||||
<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="B0W-bh-Evv" firstAttribute="top" secondItem="lti-yM-8LV" secondAttribute="bottom" constant="8" id="gq2-tB-pXH"/>
|
||||
<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="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" id="lrN-Gd-iXd"/>
|
||||
<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>
|
||||
@@ -182,5 +226,8 @@ Gw
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="accountFeedWrangler" width="261" height="261"/>
|
||||
<namedColor name="AccentColor">
|
||||
<color red="0.030999999493360519" green="0.41600000858306885" blue="0.93300002813339233" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -12,6 +12,10 @@ import RSWeb
|
||||
import Secrets
|
||||
|
||||
class AccountsFeedWranglerWindowController: NSWindowController {
|
||||
|
||||
@IBOutlet weak var signInTextField: NSTextField!
|
||||
@IBOutlet weak var noAccountTextField: NSTextField!
|
||||
@IBOutlet weak var createNewAccountButton: NSButton!
|
||||
@IBOutlet weak var progressIndicator: NSProgressIndicator!
|
||||
@IBOutlet weak var usernameTextField: NSTextField!
|
||||
@IBOutlet weak var passwordTextField: NSSecureTextField!
|
||||
@@ -30,8 +34,12 @@ class AccountsFeedWranglerWindowController: NSWindowController {
|
||||
if let account = account, let credentials = try? account.retrieveCredentials(type: .basic) {
|
||||
usernameTextField.stringValue = credentials.username
|
||||
actionButton.title = NSLocalizedString("Update", comment: "Update")
|
||||
signInTextField.stringValue = NSLocalizedString("Update your Feed Wrangler account credentials.", comment: "SignIn")
|
||||
noAccountTextField.isHidden = true
|
||||
createNewAccountButton.isHidden = true
|
||||
} else {
|
||||
actionButton.title = NSLocalizedString("Create", comment: "Create")
|
||||
signInTextField.stringValue = NSLocalizedString("Sign in to your Feed Wrangler account.", comment: "SignIn")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,4 +121,9 @@ class AccountsFeedWranglerWindowController: NSWindowController {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func createAccountWithProvider(_ sender: Any) {
|
||||
NSWorkspace.shared.open(URL(string: "https://feedwrangler.net/users/new")!)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,15 +3,19 @@
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
|
||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="AccountsFeedbinWindowController" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="actionButton" destination="9mz-D9-krh" id="ozu-6Q-9Lb"/>
|
||||
<outlet property="errorMessageLabel" destination="byK-Sd-r7F" id="8zt-9d-dWQ"/>
|
||||
<outlet property="createNewAccountButton" destination="MlB-jN-Ybe" id="w6v-BW-0yQ"/>
|
||||
<outlet property="errorMessageLabel" destination="sPC-hi-ewD" id="Lb6-0x-X2t"/>
|
||||
<outlet property="noAccountTextField" destination="gEK-TH-URn" id="Spi-K5-FmU"/>
|
||||
<outlet property="passwordTextField" destination="JSa-LY-zNQ" id="5cF-bM-CJE"/>
|
||||
<outlet property="progressIndicator" destination="B0W-bh-Evv" id="Tiq-gx-s3F"/>
|
||||
<outlet property="signInTextField" destination="lti-yM-8LV" id="xU2-4q-bP7"/>
|
||||
<outlet property="usernameTextField" destination="78p-Cf-f55" id="Gg5-Ce-RJv"/>
|
||||
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
|
||||
</connections>
|
||||
@@ -28,43 +32,13 @@
|
||||
<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="134" y="191" width="166" height="38"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Ssh-Dh-xbg">
|
||||
<rect key="frame" x="0.0" y="0.0" width="36" height="36"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="36" id="Ern-Kk-8LX"/>
|
||||
<constraint firstAttribute="width" constant="36" id="PLS-68-NMc"/>
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="accountFeedbin" id="y38-YL-woC"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lti-yM-8LV">
|
||||
<rect key="frame" x="53" y="0.0" width="115" height="38"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Feedbin" id="ras-dj-nP8">
|
||||
<font key="font" metaFont="system" size="32"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<visibilityPriorities>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
</visibilityPriorities>
|
||||
<customSpacing>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
</customSpacing>
|
||||
<rect key="frame" x="233" y="229" width="0.0" height="0.0"/>
|
||||
</stackView>
|
||||
<gridView xPlacement="trailing" yPlacement="center" rowAlignment="none" rowSpacing="12" columnSpacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="zBB-JH-huI">
|
||||
<rect key="frame" x="82" y="60" width="270" height="99"/>
|
||||
<constraints>
|
||||
<constraint firstItem="byK-Sd-r7F" firstAttribute="width" secondItem="JSa-LY-zNQ" secondAttribute="width" id="ImZ-BU-uKB"/>
|
||||
</constraints>
|
||||
<gridView xPlacement="trailing" yPlacement="center" rowAlignment="none" rowSpacing="7" columnSpacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="zBB-JH-huI">
|
||||
<rect key="frame" x="80" y="127" width="270" height="49"/>
|
||||
<rows>
|
||||
<gridRow id="DRl-lC-vUc"/>
|
||||
<gridRow id="eW8-uH-txq"/>
|
||||
<gridRow id="DbI-7g-Xme"/>
|
||||
</rows>
|
||||
<columns>
|
||||
<gridColumn id="fCQ-jY-Mts"/>
|
||||
@@ -73,7 +47,7 @@
|
||||
<gridCells>
|
||||
<gridCell row="DRl-lC-vUc" column="fCQ-jY-Mts" id="4DI-01-jGD">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Zy6-9c-8TI">
|
||||
<rect key="frame" x="23" y="81" width="41" height="16"/>
|
||||
<rect key="frame" x="23" y="31" width="41" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Email:" id="DqN-SV-v35">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -83,11 +57,11 @@
|
||||
</gridCell>
|
||||
<gridCell row="DRl-lC-vUc" column="7CY-bX-6x4" id="Z0b-qS-MUJ">
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="78p-Cf-f55">
|
||||
<rect key="frame" x="70" y="78" width="200" height="21"/>
|
||||
<rect key="frame" x="70" y="28" width="200" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="200" id="Qin-jm-4zt"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="fCk-Tf-q01">
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="me@email.com" drawsBackground="YES" id="fCk-Tf-q01">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -96,7 +70,7 @@
|
||||
</gridCell>
|
||||
<gridCell row="eW8-uH-txq" column="fCQ-jY-Mts" id="Hqa-3w-cQv">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="wEx-TM-rPM">
|
||||
<rect key="frame" x="-2" y="48" width="66" height="16"/>
|
||||
<rect key="frame" x="-2" y="3" width="66" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Password:" id="7g8-Kk-ISg">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -106,11 +80,11 @@
|
||||
</gridCell>
|
||||
<gridCell row="eW8-uH-txq" column="7CY-bX-6x4" id="m16-3v-9pf">
|
||||
<secureTextField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JSa-LY-zNQ">
|
||||
<rect key="frame" x="70" y="45" width="200" height="21"/>
|
||||
<rect key="frame" x="70" y="0.0" width="200" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="200" id="eal-wa-1nU"/>
|
||||
</constraints>
|
||||
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="trK-OG-tBe">
|
||||
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="•••••••••" drawsBackground="YES" usesSingleLineMode="YES" id="trK-OG-tBe">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -120,17 +94,6 @@
|
||||
</secureTextFieldCell>
|
||||
</secureTextField>
|
||||
</gridCell>
|
||||
<gridCell row="DbI-7g-Xme" column="fCQ-jY-Mts" xPlacement="leading" id="xX0-vn-AId"/>
|
||||
<gridCell row="DbI-7g-Xme" column="7CY-bX-6x4" yPlacement="top" id="hk5-St-E4y">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="byK-Sd-r7F">
|
||||
<rect key="frame" x="68" y="17" width="204" height="16"/>
|
||||
<textFieldCell key="cell" id="0yh-Ab-UTX">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
</gridCells>
|
||||
</gridView>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9mz-D9-krh">
|
||||
@@ -159,22 +122,100 @@ Gw
|
||||
<action selector="cancel:" target="-2" id="WAD-ES-hpq"/>
|
||||
</connections>
|
||||
</button>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Ssh-Dh-xbg">
|
||||
<rect key="frame" x="20" y="182" width="50" height="50"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="50" id="C4r-4y-79Z"/>
|
||||
<constraint firstAttribute="height" constant="50" id="prg-y8-RI9"/>
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="accountFeedbin" 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"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Sign in to your Feedbin account." id="ras-dj-nP8">
|
||||
<font key="font" textStyle="headline" name=".SFNS-Bold"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gEK-TH-URn">
|
||||
<rect key="frame" x="78" y="193" width="179" height="15"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Don't have a Feedbin account?" id="QF5-gl-fjb">
|
||||
<font key="font" textStyle="callout" name=".SFNS-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="X1Z-v1-T5L">
|
||||
<rect key="frame" x="78" y="82" width="337" height="30"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="30" id="NRl-GS-cHS"/>
|
||||
<constraint firstAttribute="width" constant="333" id="cNd-Nt-bdB"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" title="Your username and password will be encrypted and stored in Keychain. " id="HuQ-TS-tS3">
|
||||
<font key="font" textStyle="callout" name=".SFNS-Regular"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MlB-jN-Ybe">
|
||||
<rect key="frame" x="254" y="193" width="105" height="15"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="105" id="fHd-fN-n8G"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="roundRect" title="Create one here." bezelStyle="roundedRect" alignment="center" state="on" imageScaling="proportionallyDown" inset="2" id="fx3-Uk-NVw">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" textStyle="callout" name=".SFNS-Regular"/>
|
||||
</buttonCell>
|
||||
<color key="contentTintColor" name="AccentColor"/>
|
||||
<connections>
|
||||
<action selector="createAccountWithProvider:" target="-2" id="t3r-Jo-xim"/>
|
||||
</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="209" y="167" width="16" height="16"/>
|
||||
<rect key="frame" x="256" 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>
|
||||
<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"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="X1Z-v1-T5L" firstAttribute="top" secondItem="JSa-LY-zNQ" secondAttribute="bottom" constant="15" id="2U1-Zm-vzz"/>
|
||||
<constraint firstItem="gEK-TH-URn" firstAttribute="leading" secondItem="Ssh-Dh-xbg" secondAttribute="trailing" constant="10" id="2UN-2R-QiC"/>
|
||||
<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 firstItem="zBB-JH-huI" firstAttribute="top" secondItem="B0W-bh-Evv" secondAttribute="bottom" constant="8" id="V7z-a7-OOG"/>
|
||||
<constraint firstItem="9mz-D9-krh" firstAttribute="top" secondItem="zBB-JH-huI" secondAttribute="bottom" constant="20" symbolic="YES" id="Wu3-hp-Vzh"/>
|
||||
<constraint firstItem="zBB-JH-huI" firstAttribute="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" id="aFI-4s-mMv"/>
|
||||
<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 firstAttribute="trailing" secondItem="9mz-D9-krh" secondAttribute="trailing" constant="20" id="fVQ-zN-rKd"/>
|
||||
<constraint firstItem="B0W-bh-Evv" firstAttribute="top" secondItem="lti-yM-8LV" secondAttribute="bottom" constant="8" id="gq2-tB-pXH"/>
|
||||
<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="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" id="lrN-Gd-iXd"/>
|
||||
<constraint firstItem="7Ht-Fn-0Ya" firstAttribute="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" id="tAZ-Te-w3H"/>
|
||||
<constraint firstItem="B0W-bh-Evv" firstAttribute="leading" secondItem="sPC-hi-ewD" secondAttribute="trailing" constant="8" symbolic="YES" id="jvz-NC-C9Q"/>
|
||||
<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="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"/>
|
||||
<constraint firstItem="X1Z-v1-T5L" firstAttribute="leading" secondItem="Ssh-Dh-xbg" secondAttribute="trailing" constant="10" id="wEv-sV-yfy"/>
|
||||
<constraint firstItem="MlB-jN-Ybe" firstAttribute="centerY" secondItem="gEK-TH-URn" secondAttribute="centerY" id="xKz-dq-g9H"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
@@ -185,5 +226,8 @@ Gw
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="accountFeedbin" width="369" height="343"/>
|
||||
<namedColor name="AccentColor">
|
||||
<color red="0.030999999493360519" green="0.41600000858306885" blue="0.93300002813339233" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -13,6 +13,9 @@ import Secrets
|
||||
|
||||
class AccountsFeedbinWindowController: NSWindowController {
|
||||
|
||||
@IBOutlet weak var signInTextField: NSTextField!
|
||||
@IBOutlet weak var noAccountTextField: NSTextField!
|
||||
@IBOutlet weak var createNewAccountButton: NSButton!
|
||||
@IBOutlet weak var progressIndicator: NSProgressIndicator!
|
||||
@IBOutlet weak var usernameTextField: NSTextField!
|
||||
@IBOutlet weak var passwordTextField: NSSecureTextField!
|
||||
@@ -31,8 +34,12 @@ class AccountsFeedbinWindowController: NSWindowController {
|
||||
if let account = account, let credentials = try? account.retrieveCredentials(type: .basic) {
|
||||
usernameTextField.stringValue = credentials.username
|
||||
actionButton.title = NSLocalizedString("Update", comment: "Update")
|
||||
signInTextField.stringValue = NSLocalizedString("Update your Feedbin account credentials.", comment: "SignIn")
|
||||
noAccountTextField.isHidden = true
|
||||
createNewAccountButton.isHidden = true
|
||||
} else {
|
||||
actionButton.title = NSLocalizedString("Add Account", comment: "Add Account")
|
||||
actionButton.title = NSLocalizedString("Create", comment: "Add Account")
|
||||
signInTextField.stringValue = NSLocalizedString("Sign in to your Feedbin account.", comment: "SignIn")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,5 +124,10 @@ class AccountsFeedbinWindowController: NSWindowController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@IBAction func createAccountWithProvider(_ sender: Any) {
|
||||
NSWorkspace.shared.open(URL(string: "https://feedbin.com/signup")!)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,15 +3,19 @@
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
|
||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="AccountsNewsBlurWindowController" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="actionButton" destination="9mz-D9-krh" id="ozu-6Q-9Lb"/>
|
||||
<outlet property="errorMessageLabel" destination="byK-Sd-r7F" id="8zt-9d-dWQ"/>
|
||||
<outlet property="createNewAccountButton" destination="9oE-Gq-qp7" id="95R-be-GZr"/>
|
||||
<outlet property="errorMessageLabel" destination="tFv-QN-zMA" id="mcs-9L-T3b"/>
|
||||
<outlet property="noAccountTextField" destination="yqn-od-aLJ" id="3Az-uY-FfZ"/>
|
||||
<outlet property="passwordTextField" destination="JSa-LY-zNQ" id="5cF-bM-CJE"/>
|
||||
<outlet property="progressIndicator" destination="B0W-bh-Evv" id="Tiq-gx-s3F"/>
|
||||
<outlet property="signInTextField" destination="lti-yM-8LV" id="mNk-mt-HZ8"/>
|
||||
<outlet property="usernameTextField" destination="78p-Cf-f55" id="Gg5-Ce-RJv"/>
|
||||
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
|
||||
</connections>
|
||||
@@ -28,40 +32,13 @@
|
||||
<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="123" y="191" width="188" height="38"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Ssh-Dh-xbg">
|
||||
<rect key="frame" x="0.0" y="0.0" width="36" height="36"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="36" id="Ern-Kk-8LX"/>
|
||||
<constraint firstAttribute="width" constant="36" id="PLS-68-NMc"/>
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="accountNewsBlur" id="y38-YL-woC"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lti-yM-8LV">
|
||||
<rect key="frame" x="53" y="0.0" width="137" height="38"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="NewsBlur" id="ras-dj-nP8">
|
||||
<font key="font" metaFont="system" size="32"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<visibilityPriorities>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
</visibilityPriorities>
|
||||
<customSpacing>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
</customSpacing>
|
||||
<rect key="frame" x="217" y="229" width="0.0" height="0.0"/>
|
||||
</stackView>
|
||||
<gridView xPlacement="trailing" yPlacement="center" rowAlignment="none" rowSpacing="12" columnSpacing="14" translatesAutoresizingMaskIntoConstraints="NO" id="zBB-JH-huI">
|
||||
<rect key="frame" x="51" y="60" width="332" height="99"/>
|
||||
<gridView xPlacement="trailing" yPlacement="center" rowAlignment="none" rowSpacing="7" columnSpacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="zBB-JH-huI">
|
||||
<rect key="frame" x="80" y="127" width="326" height="49"/>
|
||||
<rows>
|
||||
<gridRow id="DRl-lC-vUc"/>
|
||||
<gridRow id="eW8-uH-txq"/>
|
||||
<gridRow id="DbI-7g-Xme"/>
|
||||
</rows>
|
||||
<columns>
|
||||
<gridColumn id="fCQ-jY-Mts"/>
|
||||
@@ -70,7 +47,7 @@
|
||||
<gridCells>
|
||||
<gridCell row="DRl-lC-vUc" column="fCQ-jY-Mts" id="4DI-01-jGD">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Zy6-9c-8TI">
|
||||
<rect key="frame" x="-2" y="81" width="122" height="16"/>
|
||||
<rect key="frame" x="-2" y="31" width="122" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Username or Email:" id="DqN-SV-v35">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -80,11 +57,11 @@
|
||||
</gridCell>
|
||||
<gridCell row="DRl-lC-vUc" column="7CY-bX-6x4" id="Z0b-qS-MUJ">
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="78p-Cf-f55">
|
||||
<rect key="frame" x="132" y="78" width="200" height="21"/>
|
||||
<rect key="frame" x="126" y="28" width="200" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="200" id="Qin-jm-4zt"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="fCk-Tf-q01">
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="me@email.com" drawsBackground="YES" id="fCk-Tf-q01">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -93,7 +70,7 @@
|
||||
</gridCell>
|
||||
<gridCell row="eW8-uH-txq" column="fCQ-jY-Mts" id="Hqa-3w-cQv">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="wEx-TM-rPM">
|
||||
<rect key="frame" x="54" y="48" width="66" height="16"/>
|
||||
<rect key="frame" x="54" y="3" width="66" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Password:" id="7g8-Kk-ISg">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -103,11 +80,11 @@
|
||||
</gridCell>
|
||||
<gridCell row="eW8-uH-txq" column="7CY-bX-6x4" id="m16-3v-9pf">
|
||||
<secureTextField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JSa-LY-zNQ">
|
||||
<rect key="frame" x="132" y="45" width="200" height="21"/>
|
||||
<rect key="frame" x="126" y="0.0" width="200" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="200" id="eal-wa-1nU"/>
|
||||
</constraints>
|
||||
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="trK-OG-tBe">
|
||||
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="••••••••" drawsBackground="YES" usesSingleLineMode="YES" id="trK-OG-tBe">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -117,17 +94,6 @@
|
||||
</secureTextFieldCell>
|
||||
</secureTextField>
|
||||
</gridCell>
|
||||
<gridCell row="DbI-7g-Xme" column="fCQ-jY-Mts" headOfMergedCell="xX0-vn-AId" xPlacement="leading" id="xX0-vn-AId">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="byK-Sd-r7F">
|
||||
<rect key="frame" x="-2" y="9" width="104" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" id="0yh-Ab-UTX">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="DbI-7g-Xme" column="7CY-bX-6x4" headOfMergedCell="xX0-vn-AId" id="hk5-St-E4y"/>
|
||||
</gridCells>
|
||||
</gridView>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9mz-D9-krh">
|
||||
@@ -157,21 +123,98 @@ 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="209" y="167" width="16" height="16"/>
|
||||
<rect key="frame" x="256" y="22" width="16" height="16"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="16" id="Cew-Vp-UKw"/>
|
||||
<constraint firstAttribute="width" constant="16" id="P6W-hb-FGm"/>
|
||||
</constraints>
|
||||
</progressIndicator>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Ssh-Dh-xbg">
|
||||
<rect key="frame" x="20" y="179" width="50" height="50"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="50" id="1ou-e3-F9w"/>
|
||||
<constraint firstAttribute="width" constant="50" id="llp-FJ-LQl"/>
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="accountNewsBlur" id="y38-YL-woC"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lti-yM-8LV">
|
||||
<rect key="frame" x="78" y="213" width="330" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Sign in to your NewsBlur account." id="ras-dj-nP8">
|
||||
<font key="font" textStyle="headline" name=".SFNS-Bold"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yqn-od-aLJ">
|
||||
<rect key="frame" x="78" y="193" width="187" height="15"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Don't have a NewsBlur account?" id="fPs-Sh-GEf">
|
||||
<font key="font" textStyle="callout" name=".SFNS-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9oE-Gq-qp7">
|
||||
<rect key="frame" x="264" y="193" width="105" height="15"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="105" id="Z91-fh-Mw5"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="roundRect" title="Create one here." bezelStyle="roundedRect" alignment="center" state="on" imageScaling="proportionallyDown" inset="2" id="moP-jO-Ubz">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
</buttonCell>
|
||||
<color key="contentTintColor" name="AccentColor"/>
|
||||
<connections>
|
||||
<action selector="createAccountWithProvider:" target="-2" id="FMt-SQ-TGa"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OMB-u7-kzz">
|
||||
<rect key="frame" x="78" y="73" width="337" height="39"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="333" id="9Bx-xl-Lf4"/>
|
||||
<constraint firstAttribute="height" constant="39" id="dYs-8A-ml0"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" title="Your username and password will be encrypted and stored in Keychain. " id="VWI-0W-Duk">
|
||||
<font key="font" textStyle="callout" name=".SFNS-Regular"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</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>
|
||||
<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"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</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="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"/>
|
||||
<constraint firstItem="zBB-JH-huI" firstAttribute="leading" secondItem="Ssh-Dh-xbg" secondAttribute="trailing" constant="10" id="KH1-LS-xLd"/>
|
||||
<constraint firstItem="XAM-Hb-0Hw" firstAttribute="centerY" secondItem="9mz-D9-krh" secondAttribute="centerY" id="M2M-fb-kfR"/>
|
||||
<constraint firstItem="yqn-od-aLJ" firstAttribute="top" secondItem="lti-yM-8LV" secondAttribute="bottom" constant="5" id="M9g-aH-poR"/>
|
||||
<constraint firstAttribute="bottom" secondItem="9mz-D9-krh" secondAttribute="bottom" constant="20" id="PK2-Ye-400"/>
|
||||
<constraint firstItem="zBB-JH-huI" firstAttribute="top" secondItem="B0W-bh-Evv" secondAttribute="bottom" constant="8" id="V7z-a7-OOG"/>
|
||||
<constraint firstItem="9mz-D9-krh" firstAttribute="top" secondItem="zBB-JH-huI" secondAttribute="bottom" constant="20" symbolic="YES" id="Wu3-hp-Vzh"/>
|
||||
<constraint firstItem="zBB-JH-huI" firstAttribute="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" id="aFI-4s-mMv"/>
|
||||
<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="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 firstItem="B0W-bh-Evv" firstAttribute="top" secondItem="lti-yM-8LV" secondAttribute="bottom" constant="8" id="gq2-tB-pXH"/>
|
||||
<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="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" id="lrN-Gd-iXd"/>
|
||||
<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 firstItem="Ssh-Dh-xbg" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="20" symbolic="YES" id="xUF-s0-Ews"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
@@ -182,5 +225,8 @@ Gw
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="accountNewsBlur" width="25" height="25"/>
|
||||
<namedColor name="AccentColor">
|
||||
<color red="0.030999999493360519" green="0.41600000858306885" blue="0.93300002813339233" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -12,6 +12,10 @@ import RSWeb
|
||||
import Secrets
|
||||
|
||||
class AccountsNewsBlurWindowController: NSWindowController {
|
||||
|
||||
@IBOutlet weak var signInTextField: NSTextField!
|
||||
@IBOutlet weak var noAccountTextField: NSTextField!
|
||||
@IBOutlet weak var createNewAccountButton: NSButton!
|
||||
@IBOutlet weak var progressIndicator: NSProgressIndicator!
|
||||
@IBOutlet weak var usernameTextField: NSTextField!
|
||||
@IBOutlet weak var passwordTextField: NSSecureTextField!
|
||||
@@ -30,8 +34,12 @@ class AccountsNewsBlurWindowController: NSWindowController {
|
||||
if let account = account, let credentials = try? account.retrieveCredentials(type: .newsBlurBasic) {
|
||||
usernameTextField.stringValue = credentials.username
|
||||
actionButton.title = NSLocalizedString("Update", comment: "Update")
|
||||
signInTextField.stringValue = NSLocalizedString("Update your NewsBlur account credentials.", comment: "SignIn")
|
||||
noAccountTextField.isHidden = true
|
||||
createNewAccountButton.isHidden = true
|
||||
} else {
|
||||
actionButton.title = NSLocalizedString("Create", comment: "Create")
|
||||
signInTextField.stringValue = NSLocalizedString("Sign in to your NewsBlur account.", comment: "SignIn")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,4 +121,9 @@ class AccountsNewsBlurWindowController: NSWindowController {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func createAccountWithProvider(_ sender: Any) {
|
||||
NSWorkspace.shared.open(URL(string: "https://newsblur.com")!)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,10 +45,7 @@ final class AccountsPreferencesViewController: NSViewController {
|
||||
rTable.size.width = tableView.superview!.frame.size.width
|
||||
tableView.frame = rTable
|
||||
|
||||
// Set initial row selection
|
||||
if sortedAccounts.count > 0 {
|
||||
tableView.selectRow(0)
|
||||
}
|
||||
hideController()
|
||||
}
|
||||
|
||||
@IBAction func addAccount(_ sender: Any) {
|
||||
@@ -226,12 +223,11 @@ private extension AccountsPreferencesViewController {
|
||||
|
||||
func showController(_ controller: NSViewController) {
|
||||
hideController()
|
||||
|
||||
|
||||
addChild(controller)
|
||||
controller.view.translatesAutoresizingMaskIntoConstraints = false
|
||||
detailView.addSubview(controller.view)
|
||||
detailView.addFullSizeConstraints(forSubview: controller.view)
|
||||
|
||||
}
|
||||
|
||||
func hideController() {
|
||||
@@ -239,6 +235,27 @@ private extension AccountsPreferencesViewController {
|
||||
children.removeAll()
|
||||
controller.view.removeFromSuperview()
|
||||
}
|
||||
|
||||
if tableView.selectedRow == -1 {
|
||||
var helpText = ""
|
||||
if sortedAccounts.count == 0 {
|
||||
helpText = NSLocalizedString("Add an account by clicking the + button.", comment: "Add Account Explainer")
|
||||
} else {
|
||||
helpText = NSLocalizedString("Select an account or add a new account by clicking the + button.", comment: "Add Account Explainer")
|
||||
}
|
||||
|
||||
let textHostingController = NSHostingController(rootView:
|
||||
AddAccountHelpView(delegate: addAccountDelegate, helpText: helpText))
|
||||
addChild(textHostingController)
|
||||
textHostingController.view.translatesAutoresizingMaskIntoConstraints = false
|
||||
detailView.addSubview(textHostingController.view)
|
||||
detailView.addConstraints([
|
||||
NSLayoutConstraint(item: textHostingController.view, attribute: .top, relatedBy: .equal, toItem: detailView, attribute: .top, multiplier: 1, constant: 1),
|
||||
NSLayoutConstraint(item: textHostingController.view, attribute: .bottom, relatedBy: .equal, toItem: detailView, attribute: .bottom, multiplier: 1, constant: -deleteButton.frame.height),
|
||||
NSLayoutConstraint(item: textHostingController.view, attribute: .width, relatedBy: .equal, toItem: detailView, attribute: .width, multiplier: 1, constant: 1)
|
||||
])
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
|
||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -11,8 +12,9 @@
|
||||
<outlet property="actionButton" destination="9mz-D9-krh" id="ozu-6Q-9Lb"/>
|
||||
<outlet property="apiURLLabel" destination="H6f-t4-SMg" id="1ac-qe-jw2"/>
|
||||
<outlet property="apiURLTextField" destination="d7d-ZV-CcZ" id="Af4-uM-Dgd"/>
|
||||
<outlet property="errorMessageLabel" destination="byK-Sd-r7F" id="8zt-9d-dWQ"/>
|
||||
<outlet property="errorMessageLabel" destination="Gyz-Mz-v08" id="fwM-K9-xnR"/>
|
||||
<outlet property="gridView" destination="zBB-JH-huI" id="ghz-ki-b0V"/>
|
||||
<outlet property="noAccountTextField" destination="R8e-67-Bwh" id="7oG-ro-jcB"/>
|
||||
<outlet property="passwordTextField" destination="JSa-LY-zNQ" id="E9W-0F-69m"/>
|
||||
<outlet property="progressIndicator" destination="B0W-bh-Evv" id="Tiq-gx-s3F"/>
|
||||
<outlet property="titleImageView" destination="Ssh-Dh-xbg" id="8Iy-jf-EYR"/>
|
||||
@@ -28,49 +30,19 @@
|
||||
<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"/>
|
||||
<view key="contentView" misplaced="YES" id="se5-gp-TjO">
|
||||
<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"/>
|
||||
<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="113" y="219" width="208" height="38"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Ssh-Dh-xbg">
|
||||
<rect key="frame" x="0.0" y="0.0" width="36" height="36"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="36" id="Ern-Kk-8LX"/>
|
||||
<constraint firstAttribute="width" constant="36" id="PLS-68-NMc"/>
|
||||
</constraints>
|
||||
<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="53" y="0.0" width="157" height="38"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Reader API" id="ras-dj-nP8">
|
||||
<font key="font" metaFont="system" size="32"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<visibilityPriorities>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
</visibilityPriorities>
|
||||
<customSpacing>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
</customSpacing>
|
||||
<rect key="frame" x="217" y="229" width="0.0" height="0.0"/>
|
||||
</stackView>
|
||||
<gridView xPlacement="trailing" yPlacement="center" rowAlignment="none" rowSpacing="12" columnSpacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="zBB-JH-huI">
|
||||
<rect key="frame" x="82" y="60" width="270" height="127"/>
|
||||
<constraints>
|
||||
<constraint firstItem="byK-Sd-r7F" firstAttribute="width" secondItem="d7d-ZV-CcZ" secondAttribute="width" id="PDt-cC-RvD"/>
|
||||
</constraints>
|
||||
<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"/>
|
||||
<rows>
|
||||
<gridRow id="DRl-lC-vUc"/>
|
||||
<gridRow id="eW8-uH-txq"/>
|
||||
<gridRow id="ebD-On-mOK"/>
|
||||
<gridRow id="DbI-7g-Xme"/>
|
||||
</rows>
|
||||
<columns>
|
||||
<gridColumn id="fCQ-jY-Mts"/>
|
||||
@@ -79,7 +51,7 @@
|
||||
<gridCells>
|
||||
<gridCell row="DRl-lC-vUc" column="fCQ-jY-Mts" id="4DI-01-jGD">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Zy6-9c-8TI">
|
||||
<rect key="frame" x="23" y="109" width="41" height="16"/>
|
||||
<rect key="frame" x="23" y="59" width="41" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Login:" id="DqN-SV-v35">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -89,11 +61,11 @@
|
||||
</gridCell>
|
||||
<gridCell row="DRl-lC-vUc" column="7CY-bX-6x4" id="Z0b-qS-MUJ">
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="78p-Cf-f55">
|
||||
<rect key="frame" x="70" y="106" width="200" height="21"/>
|
||||
<rect key="frame" x="70" y="56" width="200" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="200" id="Qin-jm-4zt"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="fCk-Tf-q01">
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="username" drawsBackground="YES" id="fCk-Tf-q01">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -102,7 +74,7 @@
|
||||
</gridCell>
|
||||
<gridCell row="eW8-uH-txq" column="fCQ-jY-Mts" id="Hqa-3w-cQv">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="wEx-TM-rPM">
|
||||
<rect key="frame" x="-2" y="76" width="66" height="16"/>
|
||||
<rect key="frame" x="-2" y="31" width="66" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Password:" id="7g8-Kk-ISg">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -112,11 +84,11 @@
|
||||
</gridCell>
|
||||
<gridCell row="eW8-uH-txq" column="7CY-bX-6x4" id="m16-3v-9pf">
|
||||
<secureTextField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JSa-LY-zNQ">
|
||||
<rect key="frame" x="70" y="73" width="200" height="21"/>
|
||||
<rect key="frame" x="70" y="28" width="200" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="200" id="eal-wa-1nU"/>
|
||||
</constraints>
|
||||
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="trK-OG-tBe">
|
||||
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="••••••••" drawsBackground="YES" usesSingleLineMode="YES" id="trK-OG-tBe">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -128,7 +100,7 @@
|
||||
</gridCell>
|
||||
<gridCell row="ebD-On-mOK" column="fCQ-jY-Mts" id="xwR-xz-N6h">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="H6f-t4-SMg">
|
||||
<rect key="frame" x="7" y="43" width="57" height="16"/>
|
||||
<rect key="frame" x="7" y="3" width="57" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="API URL:" id="zBm-dZ-EF1">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -138,7 +110,7 @@
|
||||
</gridCell>
|
||||
<gridCell row="ebD-On-mOK" column="7CY-bX-6x4" id="Wd5-Zp-t61">
|
||||
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="d7d-ZV-CcZ" userLabel="API URL Text Field">
|
||||
<rect key="frame" x="70" y="40" width="200" height="21"/>
|
||||
<rect key="frame" x="70" y="0.0" width="200" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="200" id="Mki-bb-tDu"/>
|
||||
</constraints>
|
||||
@@ -149,17 +121,6 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
<gridCell row="DbI-7g-Xme" column="fCQ-jY-Mts" xPlacement="leading" id="xX0-vn-AId"/>
|
||||
<gridCell row="DbI-7g-Xme" column="7CY-bX-6x4" yPlacement="top" id="hk5-St-E4y">
|
||||
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="byK-Sd-r7F">
|
||||
<rect key="frame" x="68" y="12" width="204" height="16"/>
|
||||
<textFieldCell key="cell" id="0yh-Ab-UTX">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</gridCell>
|
||||
</gridCells>
|
||||
</gridView>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9mz-D9-krh">
|
||||
@@ -189,21 +150,100 @@ 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="209" y="195" width="16" height="16"/>
|
||||
<rect key="frame" x="256" y="20" width="16" height="16"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="16" id="QuJ-Kk-QvB"/>
|
||||
<constraint firstAttribute="height" constant="16" id="SbP-MC-kng"/>
|
||||
</constraints>
|
||||
</progressIndicator>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Ssh-Dh-xbg">
|
||||
<rect key="frame" x="20" y="179" width="50" height="50"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="50" id="NYV-hM-AYz"/>
|
||||
<constraint firstAttribute="width" constant="50" id="qWk-4n-LXb"/>
|
||||
</constraints>
|
||||
<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"/>
|
||||
<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"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="R8e-67-Bwh">
|
||||
<rect key="frame" x="78" y="193" 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"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kUQ-aj-Iu6">
|
||||
<rect key="frame" x="251" y="194" width="99" height="13"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="13" id="NOr-5b-kRd"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="roundRect" title="Create one here." bezelStyle="roundedRect" alignment="center" state="on" imageScaling="proportionallyDown" inset="2" id="xY9-Rw-8kx">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
</buttonCell>
|
||||
<color key="contentTintColor" name="AccentColor"/>
|
||||
<connections>
|
||||
<action selector="createAccountWithProvider:" target="-2" id="eQi-od-QJ3"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="q5z-LG-0Fm">
|
||||
<rect key="frame" x="78" y="45" width="337" height="39"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="39" id="Zv4-mj-po0"/>
|
||||
<constraint firstAttribute="width" constant="333" id="xsi-I6-XNM"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" title="Your username and password will be encrypted and stored in Keychain. " id="Ec9-bB-tQz">
|
||||
<font key="font" textStyle="callout" name=".SFNS-Regular"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</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>
|
||||
<textFieldCell key="cell" id="AGV-EV-VmY">
|
||||
<font key="font" textStyle="subheadline" name=".SFNS-Regular"/>
|
||||
<color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="Ssh-Dh-xbg" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" symbolic="YES" id="0Fq-9s-pKG"/>
|
||||
<constraint firstItem="zBB-JH-huI" firstAttribute="top" secondItem="R8e-67-Bwh" secondAttribute="bottom" constant="17" id="2Ve-1M-0xg"/>
|
||||
<constraint firstItem="kUQ-aj-Iu6" firstAttribute="centerY" secondItem="R8e-67-Bwh" secondAttribute="centerY" id="2hZ-w7-Lne"/>
|
||||
<constraint firstItem="lti-yM-8LV" firstAttribute="leading" secondItem="Ssh-Dh-xbg" secondAttribute="trailing" constant="10" id="5a7-jI-SC9"/>
|
||||
<constraint firstAttribute="bottom" secondItem="B0W-bh-Evv" secondAttribute="bottom" constant="20" symbolic="YES" id="7OS-Ie-XXN"/>
|
||||
<constraint firstItem="XAM-Hb-0Hw" firstAttribute="leading" secondItem="B0W-bh-Evv" secondAttribute="trailing" constant="8" symbolic="YES" id="Ame-HX-mdC"/>
|
||||
<constraint firstItem="q5z-LG-0Fm" firstAttribute="leading" secondItem="R8e-67-Bwh" secondAttribute="leading" id="B2k-oM-YfG"/>
|
||||
<constraint firstItem="kUQ-aj-Iu6" firstAttribute="leading" secondItem="R8e-67-Bwh" secondAttribute="trailing" constant="1" id="BWQ-ly-Hcg"/>
|
||||
<constraint firstItem="9mz-D9-krh" firstAttribute="leading" secondItem="XAM-Hb-0Hw" secondAttribute="trailing" constant="12" symbolic="YES" id="CC8-HR-FDy"/>
|
||||
<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="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="zBB-JH-huI" firstAttribute="top" secondItem="B0W-bh-Evv" secondAttribute="bottom" constant="8" id="V7z-a7-OOG"/>
|
||||
<constraint firstItem="9mz-D9-krh" firstAttribute="top" secondItem="zBB-JH-huI" secondAttribute="bottom" constant="20" symbolic="YES" id="Wu3-hp-Vzh"/>
|
||||
<constraint firstItem="zBB-JH-huI" firstAttribute="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" id="aFI-4s-mMv"/>
|
||||
<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 firstItem="B0W-bh-Evv" firstAttribute="top" secondItem="lti-yM-8LV" secondAttribute="bottom" constant="8" id="gq2-tB-pXH"/>
|
||||
<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="centerX" secondItem="se5-gp-TjO" secondAttribute="centerX" id="lrN-Gd-iXd"/>
|
||||
<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="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"/>
|
||||
<constraint firstItem="R8e-67-Bwh" firstAttribute="top" secondItem="lti-yM-8LV" secondAttribute="bottom" constant="5" id="vL5-xO-f7d"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
@@ -212,4 +252,9 @@ Gw
|
||||
<point key="canvasLocation" x="116.5" y="136.5"/>
|
||||
</window>
|
||||
</objects>
|
||||
<resources>
|
||||
<namedColor name="AccentColor">
|
||||
<color red="0.030999999493360519" green="0.41600000858306885" blue="0.93300002813339233" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -23,6 +23,7 @@ class AccountsReaderAPIWindowController: NSWindowController {
|
||||
@IBOutlet weak var passwordTextField: NSSecureTextField!
|
||||
@IBOutlet weak var errorMessageLabel: NSTextField!
|
||||
@IBOutlet weak var actionButton: NSButton!
|
||||
@IBOutlet weak var noAccountTextField: NSTextField!
|
||||
|
||||
var account: Account?
|
||||
var accountType: AccountType?
|
||||
@@ -38,19 +39,23 @@ class AccountsReaderAPIWindowController: NSWindowController {
|
||||
switch accountType {
|
||||
case .freshRSS:
|
||||
titleImageView.image = AppAssets.accountFreshRSS
|
||||
titleLabel.stringValue = NSLocalizedString("FreshRSS", comment: "FreshRSS")
|
||||
titleLabel.stringValue = NSLocalizedString("Sign in to your FreshRSS account.", comment: "FreshRSS")
|
||||
noAccountTextField.stringValue = NSLocalizedString("Don't have a FreshRSS account?", comment: "No FreshRSS")
|
||||
case .inoreader:
|
||||
titleImageView.image = AppAssets.accountInoreader
|
||||
titleLabel.stringValue = NSLocalizedString("InoReader", comment: "InoReader")
|
||||
titleLabel.stringValue = NSLocalizedString("Sign in to your InoReader account.", comment: "InoReader")
|
||||
gridView.row(at: 2).isHidden = true
|
||||
noAccountTextField.stringValue = NSLocalizedString("Don't have an InoReader account?", comment: "No InoReader")
|
||||
case .bazQux:
|
||||
titleImageView.image = AppAssets.accountBazQux
|
||||
titleLabel.stringValue = NSLocalizedString("BazQux", comment: "BazQux")
|
||||
titleLabel.stringValue = NSLocalizedString("Sign in to your BazQux account.", comment: "BazQux")
|
||||
gridView.row(at: 2).isHidden = true
|
||||
noAccountTextField.stringValue = NSLocalizedString("Don't have a BazQux account?", comment: "No BazQux")
|
||||
case .theOldReader:
|
||||
titleImageView.image = AppAssets.accountTheOldReader
|
||||
titleLabel.stringValue = NSLocalizedString("The Old Reader", comment: "The Old Reader")
|
||||
titleLabel.stringValue = NSLocalizedString("Sign in to your The Old Reader account.", comment: "The Old Reader")
|
||||
gridView.row(at: 2).isHidden = true
|
||||
noAccountTextField.stringValue = NSLocalizedString("Don't have a The Old Reader account?", comment: "No OldReader")
|
||||
default:
|
||||
break
|
||||
}
|
||||
@@ -172,5 +177,21 @@ class AccountsReaderAPIWindowController: NSWindowController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@IBAction func createAccountWithProvider(_ sender: Any) {
|
||||
switch accountType {
|
||||
case .freshRSS:
|
||||
NSWorkspace.shared.open(URL(string: "https://freshrss.org")!)
|
||||
case .inoreader:
|
||||
NSWorkspace.shared.open(URL(string: "https://www.inoreader.com")!)
|
||||
case .bazQux:
|
||||
NSWorkspace.shared.open(URL(string: "https://bazqux.com")!)
|
||||
case .theOldReader:
|
||||
NSWorkspace.shared.open(URL(string: "https://theoldreader.com")!)
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
60
Mac/Preferences/Accounts/AddAccountHelpView.swift
Normal file
60
Mac/Preferences/Accounts/AddAccountHelpView.swift
Normal file
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// AddAccountHelpView.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Stuart Breckenridge on 4/11/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Account
|
||||
|
||||
struct AddAccountHelpView: View {
|
||||
|
||||
let accountTypes: [AccountType] = AddAccountSections.allOrdered.sectionContent
|
||||
var delegate: AccountsPreferencesAddAccountDelegate?
|
||||
var helpText: String
|
||||
@State private var hoveringId: String? = nil
|
||||
@State private var iCloudUnavailableError: Bool = false
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
HStack {
|
||||
ForEach(accountTypes, id: \.self) { account in
|
||||
account.image()
|
||||
.resizable()
|
||||
.frame(width: 20, height: 20, alignment: .center)
|
||||
.onTapGesture {
|
||||
if account == .cloudKit && AccountManager.shared.accounts.contains(where: { $0.type == .cloudKit }) {
|
||||
iCloudUnavailableError = true
|
||||
} else {
|
||||
delegate?.presentSheetForAccount(account)
|
||||
}
|
||||
hoveringId = nil
|
||||
}
|
||||
.onHover(perform: { hovering in
|
||||
if hovering {
|
||||
hoveringId = account.localizedAccountName()
|
||||
} else {
|
||||
hoveringId = nil
|
||||
}
|
||||
})
|
||||
.scaleEffect(hoveringId == account.localizedAccountName() ? 1.2 : 1)
|
||||
.shadow(radius: hoveringId == account.localizedAccountName() ? 0.8 : 0)
|
||||
}
|
||||
}
|
||||
|
||||
Text(helpText)
|
||||
.multilineTextAlignment(.center)
|
||||
.padding(.top, 8)
|
||||
|
||||
}
|
||||
.alert(isPresented: $iCloudUnavailableError, content: {
|
||||
Alert(title: Text(NSLocalizedString("Error", comment: "Error")),
|
||||
message: Text(NSLocalizedString("You've already set up an iCloud account.", comment: "Error")),
|
||||
dismissButton: Alert.Button.cancel({
|
||||
iCloudUnavailableError = false
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,12 @@
|
||||
import SwiftUI
|
||||
import Account
|
||||
|
||||
private enum AddAccountSections: Int, CaseIterable {
|
||||
enum AddAccountSections: Int, CaseIterable {
|
||||
case local = 0
|
||||
case icloud
|
||||
case web
|
||||
case selfhosted
|
||||
case allOrdered
|
||||
|
||||
var sectionHeader: String {
|
||||
switch self {
|
||||
@@ -25,6 +26,8 @@ private enum AddAccountSections: Int, CaseIterable {
|
||||
return NSLocalizedString("Web", comment: "Web Account")
|
||||
case .selfhosted:
|
||||
return NSLocalizedString("Self-hosted", comment: "Self hosted Account")
|
||||
case .allOrdered:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +41,8 @@ private enum AddAccountSections: Int, CaseIterable {
|
||||
return NSLocalizedString("Web accounts sync your subscriptions across all your devices.", comment: "Web Account")
|
||||
case .selfhosted:
|
||||
return NSLocalizedString("Self-hosted accounts sync your subscriptions across all your devices.", comment: "Self hosted Account")
|
||||
case .allOrdered:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +56,11 @@ private enum AddAccountSections: Int, CaseIterable {
|
||||
return [.bazQux, .feedbin, .feedly, .feedWrangler, .inoreader, .newsBlur, .theOldReader]
|
||||
case .selfhosted:
|
||||
return [.freshRSS]
|
||||
case .allOrdered:
|
||||
return AddAccountSections.local.sectionContent +
|
||||
AddAccountSections.icloud.sectionContent +
|
||||
AddAccountSections.web.sectionContent +
|
||||
AddAccountSections.selfhosted.sectionContent
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,8 +151,6 @@ struct AddAccountsView: View {
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: 25, height: 25, alignment: .center)
|
||||
.padding(.leading, 4)
|
||||
|
||||
|
||||
Text(account.localizedAccountName())
|
||||
}
|
||||
.tag(account)
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// EnableExtensionPointHelpView.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Stuart Breckenridge on 4/11/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import AppKit
|
||||
import SwiftUI
|
||||
import RSCore
|
||||
|
||||
struct EnableExtensionPointHelpView: View {
|
||||
|
||||
var extensionPoints: [ExtensionPoint.Type] {
|
||||
let types = ExtensionPointManager.shared.availableExtensionPointTypes.filter({ $0 is SendToCommand.Type }) +
|
||||
ExtensionPointManager.shared.availableExtensionPointTypes.filter({ !($0 is SendToCommand.Type) })
|
||||
return types
|
||||
}
|
||||
var helpText: String
|
||||
weak var preferencesController: ExtensionPointPreferencesViewController?
|
||||
|
||||
@State private var hoveringId: String?
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
HStack {
|
||||
ForEach(0..<extensionPoints.count, content: { i in
|
||||
Image(nsImage: extensionPoints[i].image)
|
||||
.resizable()
|
||||
.frame(width: 20, height: 20, alignment: .center)
|
||||
.onTapGesture {
|
||||
preferencesController?.enableExtensionPointFromSelection(extensionPoints[i])
|
||||
hoveringId = nil
|
||||
}
|
||||
.onHover(perform: { hovering in
|
||||
if hovering {
|
||||
hoveringId = extensionPoints[i].title
|
||||
} else {
|
||||
hoveringId = nil
|
||||
}
|
||||
})
|
||||
.scaleEffect(hoveringId == extensionPoints[i].title ? 1.2 : 1)
|
||||
.shadow(radius: hoveringId == extensionPoints[i].title ? 0.8 : 0)
|
||||
})
|
||||
|
||||
if ExtensionPointManager.shared.availableExtensionPointTypes.count == 0 {
|
||||
Image("markUnread")
|
||||
.resizable()
|
||||
.renderingMode(.template)
|
||||
.frame(width: 30, height: 30, alignment: .center)
|
||||
.foregroundColor(.green)
|
||||
}
|
||||
}
|
||||
|
||||
Text(helpText)
|
||||
.multilineTextAlignment(.center)
|
||||
.padding(.top, 8)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,14 +10,17 @@ import AppKit
|
||||
import SwiftUI
|
||||
import RSCore
|
||||
|
||||
|
||||
struct EnableExtensionPointView: View {
|
||||
|
||||
weak var parent: NSHostingController<EnableExtensionPointView>? // required because presentationMode.dismiss() doesn't work
|
||||
weak var enabler: ExtensionPointPreferencesEnabler?
|
||||
@State private var extensionPointTypeName = String(describing: Self.feedProviderExtensionPointTypes.first!)
|
||||
@State private var extensionPointTypeName = String(describing: Self.sendToCommandExtensionPointTypes.first)
|
||||
private var selectedType: ExtensionPoint.Type?
|
||||
|
||||
init(enabler: ExtensionPointPreferencesEnabler?) {
|
||||
init(enabler: ExtensionPointPreferencesEnabler?, selectedType: ExtensionPoint.Type? ) {
|
||||
self.enabler = enabler
|
||||
self.selectedType = selectedType
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
@@ -48,7 +51,7 @@ struct EnableExtensionPointView: View {
|
||||
Text("Cancel")
|
||||
.frame(width: 80)
|
||||
})
|
||||
.accessibility(label: Text("Add Account"))
|
||||
.accessibility(label: Text("Add Extension"))
|
||||
}
|
||||
if #available(OSX 11.0, *) {
|
||||
Button(action: {
|
||||
@@ -58,9 +61,9 @@ struct EnableExtensionPointView: View {
|
||||
Text("Continue")
|
||||
.frame(width: 80)
|
||||
})
|
||||
.help("Add Account")
|
||||
.help("Add Extension")
|
||||
.keyboardShortcut(.defaultAction)
|
||||
|
||||
.disabled(disableContinue())
|
||||
} else {
|
||||
Button(action: {
|
||||
enabler?.enable(typeFromName(extensionPointTypeName))
|
||||
@@ -69,6 +72,7 @@ struct EnableExtensionPointView: View {
|
||||
Text("Continue")
|
||||
.frame(width: 80)
|
||||
})
|
||||
.disabled(disableContinue())
|
||||
}
|
||||
}
|
||||
.padding(.top, 12)
|
||||
@@ -78,6 +82,11 @@ struct EnableExtensionPointView: View {
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.frame(width: 420)
|
||||
.padding()
|
||||
.onAppear {
|
||||
if selectedType != nil {
|
||||
extensionPointTypeName = String(describing: selectedType!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var feedProviderExtensionPoints: some View {
|
||||
@@ -101,13 +110,13 @@ struct EnableExtensionPointView: View {
|
||||
|
||||
Text(extensionPointType.title)
|
||||
}
|
||||
.tag(extensionPointTypeNames)
|
||||
.tag(extensionPointTypeName)
|
||||
})
|
||||
})
|
||||
.pickerStyle(RadioGroupPickerStyle())
|
||||
.offset(x: 7.5, y: 0)
|
||||
|
||||
Text("An extension point that makes websites appear to provide RSS feeds for their content.")
|
||||
Text("An extension that makes websites appear to provide RSS feeds for their content.")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
.padding(.horizontal)
|
||||
@@ -138,13 +147,13 @@ struct EnableExtensionPointView: View {
|
||||
|
||||
Text(extensionPointType.title)
|
||||
}
|
||||
.tag(extensionPointTypeNames)
|
||||
.tag(extensionPointTypeName)
|
||||
})
|
||||
})
|
||||
.pickerStyle(RadioGroupPickerStyle())
|
||||
.offset(x: 7.5, y: 0)
|
||||
|
||||
Text("An extension point that enables a share menu item that passes article data to a third-party application.")
|
||||
Text("An extension that enables a share menu item that passes article data to a third-party application.")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
.padding(.horizontal)
|
||||
@@ -169,4 +178,11 @@ struct EnableExtensionPointView: View {
|
||||
}
|
||||
fatalError()
|
||||
}
|
||||
|
||||
func disableContinue() -> Bool {
|
||||
ExtensionPointManager.shared.availableExtensionPointTypes.count == 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -41,14 +41,17 @@ final class ExtensionPointPreferencesViewController: NSViewController {
|
||||
|
||||
showDefaultView()
|
||||
|
||||
// Set initial row selection
|
||||
if activeExtensionPoints.count > 0 {
|
||||
tableView.selectRow(0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@IBAction func enableExtensionPoints(_ sender: Any) {
|
||||
let controller = NSHostingController(rootView: EnableExtensionPointView(enabler: self))
|
||||
let controller = NSHostingController(rootView: EnableExtensionPointView(enabler: self, selectedType: nil))
|
||||
controller.rootView.parent = controller
|
||||
presentAsSheet(controller)
|
||||
}
|
||||
|
||||
func enableExtensionPointFromSelection(_ selection: ExtensionPoint.Type) {
|
||||
let controller = NSHostingController(rootView: EnableExtensionPointView(enabler: self, selectedType: selection))
|
||||
controller.rootView.parent = controller
|
||||
presentAsSheet(controller)
|
||||
}
|
||||
@@ -179,6 +182,33 @@ private extension ExtensionPointPreferencesViewController {
|
||||
func showDefaultView() {
|
||||
activeExtensionPoints = Array(ExtensionPointManager.shared.activeExtensionPoints.values).sorted(by: { $0.title < $1.title })
|
||||
tableView.reloadData()
|
||||
|
||||
if tableView.selectedRow == -1 {
|
||||
var helpText = ""
|
||||
if ExtensionPointManager.shared.availableExtensionPointTypes.count == 0 {
|
||||
helpText = NSLocalizedString("You've added all available extension points.", comment: "Extension Explainer")
|
||||
}
|
||||
else if activeExtensionPoints.count == 0 {
|
||||
helpText = NSLocalizedString("Add an extension by clicking the + button.", comment: "Extension Explainer")
|
||||
} else {
|
||||
helpText = NSLocalizedString("Select an extension or add a new extension point by clicking the + button.", comment: "Extension Explainer")
|
||||
}
|
||||
|
||||
if let controller = children.first {
|
||||
children.removeAll()
|
||||
controller.view.removeFromSuperview()
|
||||
}
|
||||
|
||||
let textHostingController = NSHostingController(rootView: EnableExtensionPointHelpView(helpText: helpText, preferencesController: self))
|
||||
addChild(textHostingController)
|
||||
textHostingController.view.translatesAutoresizingMaskIntoConstraints = false
|
||||
detailView.addSubview(textHostingController.view)
|
||||
detailView.addConstraints([
|
||||
NSLayoutConstraint(item: textHostingController.view, attribute: .top, relatedBy: .equal, toItem: detailView, attribute: .top, multiplier: 1, constant: 1),
|
||||
NSLayoutConstraint(item: textHostingController.view, attribute: .bottom, relatedBy: .equal, toItem: detailView, attribute: .bottom, multiplier: 1, constant: -deleteButton.frame.height),
|
||||
NSLayoutConstraint(item: textHostingController.view, attribute: .width, relatedBy: .equal, toItem: detailView, attribute: .width, multiplier: 1, constant: 1)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
func showController(_ controller: NSViewController) {
|
||||
@@ -195,6 +225,28 @@ private extension ExtensionPointPreferencesViewController {
|
||||
children.removeAll()
|
||||
controller.view.removeFromSuperview()
|
||||
}
|
||||
|
||||
if tableView.selectedRow == -1 {
|
||||
var helpText = ""
|
||||
if ExtensionPointManager.shared.availableExtensionPointTypes.count == 0 {
|
||||
helpText = NSLocalizedString("You've added all available extension points.", comment: "Extension Explainer")
|
||||
}
|
||||
else if activeExtensionPoints.count == 0 {
|
||||
helpText = NSLocalizedString("Add an extension by clicking the + button.", comment: "Extension Explainer")
|
||||
} else {
|
||||
helpText = NSLocalizedString("Select an extension or add a new extension point by clicking the + button.", comment: "Extension Explainer")
|
||||
}
|
||||
|
||||
let textHostingController = NSHostingController(rootView: EnableExtensionPointHelpView(helpText: helpText, preferencesController: self))
|
||||
addChild(textHostingController)
|
||||
textHostingController.view.translatesAutoresizingMaskIntoConstraints = false
|
||||
detailView.addSubview(textHostingController.view)
|
||||
detailView.addConstraints([
|
||||
NSLayoutConstraint(item: textHostingController.view, attribute: .top, relatedBy: .equal, toItem: detailView, attribute: .top, multiplier: 1, constant: 1),
|
||||
NSLayoutConstraint(item: textHostingController.view, attribute: .bottom, relatedBy: .equal, toItem: detailView, attribute: .bottom, multiplier: 1, constant: -deleteButton.frame.height),
|
||||
NSLayoutConstraint(item: textHostingController.view, attribute: .width, relatedBy: .equal, toItem: detailView, attribute: .width, multiplier: 1, constant: 1)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
func enableOauth1(_ provider: OAuth1SwiftProvider.Type, extensionPointType: ExtensionPoint.Type) {
|
||||
@@ -254,3 +306,5 @@ private extension ExtensionPointPreferencesViewController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,10 +15,8 @@ final class GeneralPreferencesViewController: NSViewController {
|
||||
|
||||
private var userNotificationSettings: UNNotificationSettings?
|
||||
|
||||
@IBOutlet var defaultRSSReaderPopup: NSPopUpButton!
|
||||
@IBOutlet var defaultBrowserPopup: NSPopUpButton!
|
||||
@IBOutlet weak var showUnreadCountCheckbox: NSButton!
|
||||
private var rssReaderInfo = RSSReaderInfo()
|
||||
|
||||
public override init(nibName nibNameOrNil: NSNib.Name?, bundle nibBundleOrNil: Bundle?) {
|
||||
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
|
||||
@@ -44,17 +42,6 @@ final class GeneralPreferencesViewController: NSViewController {
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
@IBAction func rssReaderPopupDidChangeValue(_ sender: Any?) {
|
||||
guard let menuItem = defaultRSSReaderPopup.selectedItem else {
|
||||
return
|
||||
}
|
||||
guard let bundleID = menuItem.representedObject as? String else {
|
||||
return
|
||||
}
|
||||
registerAppWithBundleID(bundleID)
|
||||
updateUI()
|
||||
}
|
||||
|
||||
@IBAction func browserPopUpDidChangeValue(_ sender: Any?) {
|
||||
guard let menuItem = defaultBrowserPopup.selectedItem else {
|
||||
return
|
||||
@@ -115,69 +102,10 @@ private extension GeneralPreferencesViewController {
|
||||
}
|
||||
|
||||
func updateUI() {
|
||||
rssReaderInfo = RSSReaderInfo()
|
||||
updateBrowserPopup()
|
||||
updateRSSReaderPopup()
|
||||
updateHideUnreadCountCheckbox()
|
||||
}
|
||||
|
||||
func updateRSSReaderPopup() {
|
||||
// Top item should always be: NetNewsWire (this app)
|
||||
// Additional items should be sorted alphabetically.
|
||||
// Any older versions of NetNewsWire should be listed as: NetNewsWire (old version)
|
||||
|
||||
let menu = NSMenu(title: "RSS Readers")
|
||||
|
||||
let netNewsWireBundleID = Bundle.main.bundleIdentifier!
|
||||
let thisAppParentheticalComment = NSLocalizedString("(this app)", comment: "Preferences default RSS Reader popup")
|
||||
let thisAppName = "NetNewsWire \(thisAppParentheticalComment)"
|
||||
let netNewsWireMenuItem = NSMenuItem(title: thisAppName, action: nil, keyEquivalent: "")
|
||||
netNewsWireMenuItem.representedObject = netNewsWireBundleID
|
||||
menu.addItem(netNewsWireMenuItem)
|
||||
|
||||
let readersToList = rssReaderInfo.rssReaders.filter { $0.bundleID != netNewsWireBundleID }
|
||||
let sortedReaders = readersToList.sorted { (reader1, reader2) -> Bool in
|
||||
return reader1.nameMinusAppSuffix.localizedStandardCompare(reader2.nameMinusAppSuffix) == .orderedAscending
|
||||
}
|
||||
|
||||
let oldVersionParentheticalComment = NSLocalizedString("(old version)", comment: "Preferences default RSS Reader popup")
|
||||
for rssReader in sortedReaders {
|
||||
var appName = rssReader.nameMinusAppSuffix
|
||||
if appName.contains("NetNewsWire") {
|
||||
appName = "\(appName) \(oldVersionParentheticalComment)"
|
||||
}
|
||||
let menuItem = NSMenuItem(title: appName, action: nil, keyEquivalent: "")
|
||||
menuItem.representedObject = rssReader.bundleID
|
||||
menu.addItem(menuItem)
|
||||
}
|
||||
|
||||
defaultRSSReaderPopup.menu = menu
|
||||
|
||||
func insertAndSelectNoneMenuItem() {
|
||||
let noneTitle = NSLocalizedString("None", comment: "Preferences default RSS Reader popup")
|
||||
let menuItem = NSMenuItem(title: noneTitle, action: nil, keyEquivalent: "")
|
||||
defaultRSSReaderPopup.menu!.insertItem(menuItem, at: 0)
|
||||
defaultRSSReaderPopup.selectItem(at: 0)
|
||||
}
|
||||
|
||||
guard let defaultRSSReaderBundleID = rssReaderInfo.defaultRSSReaderBundleID else {
|
||||
insertAndSelectNoneMenuItem()
|
||||
return
|
||||
}
|
||||
|
||||
for menuItem in defaultRSSReaderPopup.menu!.items {
|
||||
guard let bundleID = menuItem.representedObject as? String else {
|
||||
continue
|
||||
}
|
||||
if bundleID == defaultRSSReaderBundleID {
|
||||
defaultRSSReaderPopup.select(menuItem)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
insertAndSelectNoneMenuItem()
|
||||
}
|
||||
|
||||
func registerAppWithBundleID(_ bundleID: String) {
|
||||
NSWorkspace.shared.setDefaultAppBundleID(forURLScheme: "feed", to: bundleID)
|
||||
NSWorkspace.shared.setDefaultAppBundleID(forURLScheme: "feeds", to: bundleID)
|
||||
@@ -245,74 +173,3 @@ private extension GeneralPreferencesViewController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - RSSReaderInfo
|
||||
|
||||
private struct RSSReaderInfo {
|
||||
|
||||
let defaultRSSReaderBundleID: String?
|
||||
let rssReaders: Set<RSSReader>
|
||||
static let feedURLScheme = "feed:"
|
||||
|
||||
init() {
|
||||
let defaultRSSReaderBundleID = NSWorkspace.shared.defaultAppBundleID(forURLScheme: RSSReaderInfo.feedURLScheme)
|
||||
self.defaultRSSReaderBundleID = defaultRSSReaderBundleID
|
||||
self.rssReaders = RSSReaderInfo.fetchRSSReaders(defaultRSSReaderBundleID)
|
||||
}
|
||||
|
||||
static func fetchRSSReaders(_ defaultRSSReaderBundleID: String?) -> Set<RSSReader> {
|
||||
let rssReaderBundleIDs = NSWorkspace.shared.bundleIDsForApps(forURLScheme: feedURLScheme)
|
||||
|
||||
var rssReaders = Set<RSSReader>()
|
||||
if let defaultRSSReaderBundleID = defaultRSSReaderBundleID, let defaultReader = RSSReader(bundleID: defaultRSSReaderBundleID) {
|
||||
rssReaders.insert(defaultReader)
|
||||
}
|
||||
rssReaderBundleIDs.forEach { (bundleID) in
|
||||
if let reader = RSSReader(bundleID: bundleID) {
|
||||
rssReaders.insert(reader)
|
||||
}
|
||||
}
|
||||
return rssReaders
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - RSSReader
|
||||
|
||||
private struct RSSReader: Hashable {
|
||||
|
||||
let bundleID: String
|
||||
let name: String
|
||||
let nameMinusAppSuffix: String
|
||||
let path: String
|
||||
|
||||
init?(bundleID: String) {
|
||||
guard let path = NSWorkspace.shared.absolutePathForApplication(withBundleIdentifier: bundleID) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.path = path
|
||||
self.bundleID = bundleID
|
||||
|
||||
let name = (path as NSString).lastPathComponent
|
||||
self.name = name
|
||||
if name.hasSuffix(".app") {
|
||||
self.nameMinusAppSuffix = name.stripping(suffix: ".app")
|
||||
}
|
||||
else {
|
||||
self.nameMinusAppSuffix = name
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Hashable
|
||||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(bundleID)
|
||||
}
|
||||
|
||||
// MARK: - Equatable
|
||||
|
||||
static func ==(lhs: RSSReader, rhs: RSSReader) -> Bool {
|
||||
return lhs.bundleID == rhs.bundleID
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "shareExtensionx1.png",
|
||||
"filename" : "Icon-MacOS-32x32@1x.png.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "shareExtensionx2.png",
|
||||
"filename" : "Icon-MacOS-32x32@2x.png.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
|
||||
BIN
Mac/Resources/Assets.xcassets/shareExtension.imageset/Icon-MacOS-32x32@1x.png.png
vendored
Normal file
BIN
Mac/Resources/Assets.xcassets/shareExtension.imageset/Icon-MacOS-32x32@1x.png.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
BIN
Mac/Resources/Assets.xcassets/shareExtension.imageset/Icon-MacOS-32x32@2x.png.png
vendored
Normal file
BIN
Mac/Resources/Assets.xcassets/shareExtension.imageset/Icon-MacOS-32x32@2x.png.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.1 KiB |
@@ -72,6 +72,7 @@ final class AppDefaults: ObservableObject {
|
||||
static let confirmMarkAllAsRead = "confirmMarkAllAsRead"
|
||||
|
||||
// macOS Defaults
|
||||
static let articleTextSize = "articleTextSize"
|
||||
static let openInBrowserInBackground = "openInBrowserInBackground"
|
||||
static let defaultBrowserID = "defaultBrowserID"
|
||||
static let checkForUpdatesAutomatically = "checkForUpdatesAutomatically"
|
||||
@@ -231,6 +232,16 @@ final class AppDefaults: ObservableObject {
|
||||
|
||||
@AppStorage(wrappedValue: false, Key.articleFullscreenEnabled, store: store) var articleFullscreenEnabled: Bool
|
||||
|
||||
@AppStorage(wrappedValue: 3, Key.articleTextSize, store: store) var articleTextSizeTag: Int {
|
||||
didSet {
|
||||
objectWillChange.send()
|
||||
}
|
||||
}
|
||||
|
||||
var articleTextSize: ArticleTextSize {
|
||||
ArticleTextSize(rawValue: articleTextSizeTag) ?? ArticleTextSize.large
|
||||
}
|
||||
|
||||
// MARK: Refresh
|
||||
var lastRefresh: Date? {
|
||||
set {
|
||||
|
||||
@@ -242,7 +242,7 @@ private extension SidebarModel {
|
||||
/// - Parameter articles: An array of `Article`s.
|
||||
/// - Warning: An `UndoManager` is created here as the `Environment`'s undo manager appears to be `nil`.
|
||||
func markAllAsRead(_ articles: [Article]) {
|
||||
guard let undoManager = undoManager ?? UndoManager(),
|
||||
guard let undoManager = undoManager,
|
||||
let markAsReadCommand = MarkStatusCommand(initialArticles: articles, markingRead: true, undoManager: undoManager) else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ import RSCore
|
||||
}
|
||||
|
||||
func sharingServicePicker(_ sharingServicePicker: NSSharingServicePicker, sharingServicesForItems items: [Any], proposedSharingServices proposedServices: [NSSharingService]) -> [NSSharingService] {
|
||||
return proposedServices + SharingServicePickerDelegate.customSharingServices(for: items)
|
||||
let filteredServices = proposedServices.filter { $0.menuItemTitle != "NetNewsWire" }
|
||||
return filteredServices + SharingServicePickerDelegate.customSharingServices(for: items)
|
||||
}
|
||||
|
||||
func sharingServicePicker(_ sharingServicePicker: NSSharingServicePicker, delegateFor sharingService: NSSharingService) -> NSSharingServiceDelegate? {
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
/* Begin PBXBuildFile section */
|
||||
1704053424E5985A00A00787 /* SceneNavigationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1704053324E5985A00A00787 /* SceneNavigationModel.swift */; };
|
||||
1704053524E5985A00A00787 /* SceneNavigationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1704053324E5985A00A00787 /* SceneNavigationModel.swift */; };
|
||||
1710B9132552354E00679C0D /* AddAccountHelpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1710B9122552354E00679C0D /* AddAccountHelpView.swift */; };
|
||||
1710B9142552354E00679C0D /* AddAccountHelpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1710B9122552354E00679C0D /* AddAccountHelpView.swift */; };
|
||||
1710B929255246F900679C0D /* EnableExtensionPointHelpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1710B928255246F900679C0D /* EnableExtensionPointHelpView.swift */; };
|
||||
1710B92A255246F900679C0D /* EnableExtensionPointHelpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1710B928255246F900679C0D /* EnableExtensionPointHelpView.swift */; };
|
||||
1717535624BADF33004498C6 /* GeneralPreferencesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1717535524BADF33004498C6 /* GeneralPreferencesModel.swift */; };
|
||||
171BCB8C24CB08A3006E22D9 /* FixAccountCredentialView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 171BCB8B24CB08A3006E22D9 /* FixAccountCredentialView.swift */; };
|
||||
171BCB8D24CB08A3006E22D9 /* FixAccountCredentialView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 171BCB8B24CB08A3006E22D9 /* FixAccountCredentialView.swift */; };
|
||||
@@ -495,6 +499,12 @@
|
||||
51D5948722668EFA00DFC836 /* MarkStatusCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84702AA31FA27AC0006B8943 /* MarkStatusCommand.swift */; };
|
||||
51D6A5BC23199C85001C27D8 /* MasterTimelineDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51D6A5BB23199C85001C27D8 /* MasterTimelineDataSource.swift */; };
|
||||
51D87EE12311D34700E63F03 /* ActivityType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51D87EE02311D34700E63F03 /* ActivityType.swift */; };
|
||||
51DC07982552083500A3F79F /* ArticleTextSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC07972552083500A3F79F /* ArticleTextSize.swift */; };
|
||||
51DC07992552083500A3F79F /* ArticleTextSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC07972552083500A3F79F /* ArticleTextSize.swift */; };
|
||||
51DC079A2552083500A3F79F /* ArticleTextSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC07972552083500A3F79F /* ArticleTextSize.swift */; };
|
||||
51DC079B2552083500A3F79F /* ArticleTextSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC07972552083500A3F79F /* ArticleTextSize.swift */; };
|
||||
51DC079C2552083500A3F79F /* ArticleTextSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC07972552083500A3F79F /* ArticleTextSize.swift */; };
|
||||
51DC07AC255209E200A3F79F /* ArticleTextSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC07972552083500A3F79F /* ArticleTextSize.swift */; };
|
||||
51DC37072402153E0095D371 /* UpdateSelectionOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC37062402153E0095D371 /* UpdateSelectionOperation.swift */; };
|
||||
51DC37092402F1470095D371 /* MasterFeedDataSourceOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC37082402F1470095D371 /* MasterFeedDataSourceOperation.swift */; };
|
||||
51DC370B2405BC9A0095D371 /* PreloadedWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC370A2405BC9A0095D371 /* PreloadedWebView.swift */; };
|
||||
@@ -1434,6 +1444,8 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1704053324E5985A00A00787 /* SceneNavigationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneNavigationModel.swift; sourceTree = "<group>"; };
|
||||
1710B9122552354E00679C0D /* AddAccountHelpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAccountHelpView.swift; sourceTree = "<group>"; };
|
||||
1710B928255246F900679C0D /* EnableExtensionPointHelpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnableExtensionPointHelpView.swift; sourceTree = "<group>"; };
|
||||
1717535524BADF33004498C6 /* GeneralPreferencesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralPreferencesModel.swift; sourceTree = "<group>"; };
|
||||
171BCB8B24CB08A3006E22D9 /* FixAccountCredentialView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FixAccountCredentialView.swift; sourceTree = "<group>"; };
|
||||
172199C824AB228900A31D04 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
|
||||
@@ -1730,6 +1742,7 @@
|
||||
51CE1C0A23622006005548FC /* RefreshProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefreshProgressView.swift; sourceTree = "<group>"; };
|
||||
51D6A5BB23199C85001C27D8 /* MasterTimelineDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterTimelineDataSource.swift; sourceTree = "<group>"; };
|
||||
51D87EE02311D34700E63F03 /* ActivityType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityType.swift; sourceTree = "<group>"; };
|
||||
51DC07972552083500A3F79F /* ArticleTextSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleTextSize.swift; sourceTree = "<group>"; };
|
||||
51DC37062402153E0095D371 /* UpdateSelectionOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateSelectionOperation.swift; sourceTree = "<group>"; };
|
||||
51DC37082402F1470095D371 /* MasterFeedDataSourceOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterFeedDataSourceOperation.swift; sourceTree = "<group>"; };
|
||||
51DC370A2405BC9A0095D371 /* PreloadedWebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreloadedWebView.swift; sourceTree = "<group>"; };
|
||||
@@ -2304,6 +2317,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5183CFAE254C78C8006B83A5 /* EnableExtensionPointView.swift */,
|
||||
1710B928255246F900679C0D /* EnableExtensionPointHelpView.swift */,
|
||||
515A516D243E7F950089E588 /* ExtensionPointDetail.xib */,
|
||||
515A5170243E802B0089E588 /* ExtensionPointDetailViewController.swift */,
|
||||
515A5147243E64BA0089E588 /* ExtensionPointEnableWindowController.swift */,
|
||||
@@ -2804,11 +2818,12 @@
|
||||
51C452A822650DA100C03939 /* Article Rendering */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
849A977D1ED9EC42007D329B /* ArticleRenderer.swift */,
|
||||
B27EEBDF244D15F2000932E6 /* shared.css */,
|
||||
848362FE2262A30E00DA1D35 /* template.html */,
|
||||
517630032336215100E15FFF /* main.js */,
|
||||
49F40DEF2335B71000552BF4 /* newsfoot.js */,
|
||||
848362FE2262A30E00DA1D35 /* template.html */,
|
||||
B27EEBDF244D15F2000932E6 /* shared.css */,
|
||||
849A977D1ED9EC42007D329B /* ArticleRenderer.swift */,
|
||||
51DC07972552083500A3F79F /* ArticleTextSize.swift */,
|
||||
);
|
||||
path = "Article Rendering";
|
||||
sourceTree = "<group>";
|
||||
@@ -3328,6 +3343,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
178A9F9C2549449F00AB7E9D /* AddAccountsView.swift */,
|
||||
1710B9122552354E00679C0D /* AddAccountHelpView.swift */,
|
||||
84C9FC7222629E1200D921D6 /* AccountsPreferencesViewController.swift */,
|
||||
84C9FC7422629E1200D921D6 /* AccountsDetail.xib */,
|
||||
5144EA2E2279FAB600D19003 /* AccountsDetailViewController.swift */,
|
||||
@@ -4424,6 +4440,7 @@
|
||||
511B149A24E5DC5400C919BD /* RefreshInterval.swift in Sources */,
|
||||
510C418324E5D1B4008226FD /* ExtensionContainersFile.swift in Sources */,
|
||||
510C418524E5D1B4008226FD /* ExtensionContainers.swift in Sources */,
|
||||
51DC07AC255209E200A3F79F /* ArticleTextSize.swift in Sources */,
|
||||
511B149824E5DC2300C919BD /* ShareDefaultContainer.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -4485,6 +4502,7 @@
|
||||
51E4996A24A8762D00B667CB /* ExtractedArticle.swift in Sources */,
|
||||
51919FF124AB864A00541E64 /* TimelineModel.swift in Sources */,
|
||||
5194736E24BBB937001A2939 /* HiddenModifier.swift in Sources */,
|
||||
51DC079B2552083500A3F79F /* ArticleTextSize.swift in Sources */,
|
||||
51E498F124A8085D00B667CB /* StarredFeedDelegate.swift in Sources */,
|
||||
51E498FF24A808BB00B667CB /* SingleFaviconDownloader.swift in Sources */,
|
||||
51E4997224A8784300B667CB /* DefaultFeedsImporter.swift in Sources */,
|
||||
@@ -4668,6 +4686,7 @@
|
||||
51E4992224A8095600B667CB /* URL-Extensions.swift in Sources */,
|
||||
51E4990424A808C300B667CB /* WebFeedIconDownloader.swift in Sources */,
|
||||
51E498CB24A8085D00B667CB /* TodayFeedDelegate.swift in Sources */,
|
||||
51DC079C2552083500A3F79F /* ArticleTextSize.swift in Sources */,
|
||||
51B80F1F24BE531200C6C32D /* SharingServiceView.swift in Sources */,
|
||||
17D232A924AFF10A0005F075 /* AddWebFeedModel.swift in Sources */,
|
||||
51A8005224CC453C00F41F1D /* ReplaySubject.swift in Sources */,
|
||||
@@ -4794,11 +4813,13 @@
|
||||
65ED3FBD235DEF6C0081F399 /* AppDefaults.swift in Sources */,
|
||||
65ED3FBE235DEF6C0081F399 /* Account+Scriptability.swift in Sources */,
|
||||
65ED3FBF235DEF6C0081F399 /* NothingInspectorViewController.swift in Sources */,
|
||||
1710B92A255246F900679C0D /* EnableExtensionPointHelpView.swift in Sources */,
|
||||
65ED3FC0235DEF6C0081F399 /* AppNotifications.swift in Sources */,
|
||||
65ED3FC1235DEF6C0081F399 /* TimelineKeyboardDelegate.swift in Sources */,
|
||||
65ED3FC2235DEF6C0081F399 /* Browser.swift in Sources */,
|
||||
65ED3FC3235DEF6C0081F399 /* DetailWebViewController.swift in Sources */,
|
||||
65ED3FC4235DEF6C0081F399 /* OPMLExporter.swift in Sources */,
|
||||
51DC07992552083500A3F79F /* ArticleTextSize.swift in Sources */,
|
||||
65ED3FC5235DEF6C0081F399 /* MainWindowController.swift in Sources */,
|
||||
65ED3FC6235DEF6C0081F399 /* UnreadFeed.swift in Sources */,
|
||||
65ED3FC8235DEF6C0081F399 /* SidebarCellLayout.swift in Sources */,
|
||||
@@ -4863,6 +4884,7 @@
|
||||
65ED3FF7235DEF6C0081F399 /* SearchFeedDelegate.swift in Sources */,
|
||||
65ED3FF8235DEF6C0081F399 /* ErrorHandler.swift in Sources */,
|
||||
65ED3FF9235DEF6C0081F399 /* ActivityManager.swift in Sources */,
|
||||
1710B9142552354E00679C0D /* AddAccountHelpView.swift in Sources */,
|
||||
65ED3FFA235DEF6C0081F399 /* WebFeedInspectorViewController.swift in Sources */,
|
||||
65ED3FFB235DEF6C0081F399 /* AccountsReaderAPIWindowController.swift in Sources */,
|
||||
65ED3FFC235DEF6C0081F399 /* AccountsAddLocalWindowController.swift in Sources */,
|
||||
@@ -5049,6 +5071,7 @@
|
||||
51C452AE2265104D00C03939 /* ArticleStringFormatter.swift in Sources */,
|
||||
512E08E62268800D00BDCFDD /* FolderTreeControllerDelegate.swift in Sources */,
|
||||
51A9A60A2382FD240033AADF /* PoppableGestureRecognizerDelegate.swift in Sources */,
|
||||
51DC079A2552083500A3F79F /* ArticleTextSize.swift in Sources */,
|
||||
51C4529922650A0000C03939 /* ArticleStylesManager.swift in Sources */,
|
||||
51EF0F802277A8330050506E /* MasterTimelineCellLayout.swift in Sources */,
|
||||
51F85BF722749FA100C787DC /* UIFont-Extensions.swift in Sources */,
|
||||
@@ -5179,6 +5202,7 @@
|
||||
D5907D7F2004AC00005947E5 /* NSApplication+Scriptability.swift in Sources */,
|
||||
8405DD9C22153BD7008CE1BF /* NSView-Extensions.swift in Sources */,
|
||||
849A979F1ED9F130007D329B /* SidebarCell.swift in Sources */,
|
||||
1710B929255246F900679C0D /* EnableExtensionPointHelpView.swift in Sources */,
|
||||
515A50E6243D07A90089E588 /* ExtensionPointManager.swift in Sources */,
|
||||
51E595A5228CC36500FCC42B /* ArticleStatusSyncTimer.swift in Sources */,
|
||||
515A5177243E90200089E588 /* ExtensionPointIdentifer.swift in Sources */,
|
||||
@@ -5223,6 +5247,7 @@
|
||||
5144EA382279FC6200D19003 /* AccountsAddLocalWindowController.swift in Sources */,
|
||||
84AD1EAA2031617300BC20B7 /* PasteboardFolder.swift in Sources */,
|
||||
515A5148243E64BA0089E588 /* ExtensionPointEnableWindowController.swift in Sources */,
|
||||
51DC07982552083500A3F79F /* ArticleTextSize.swift in Sources */,
|
||||
5117715524E1EA0F00A2A836 /* ArticleExtractorButton.swift in Sources */,
|
||||
5103A9F724225E4C00410853 /* AccountsAddCloudKitWindowController.swift in Sources */,
|
||||
5144EA51227B8E4500D19003 /* AccountsFeedbinWindowController.swift in Sources */,
|
||||
@@ -5234,6 +5259,7 @@
|
||||
511B9806237DCAC90028BCAA /* UserInfoKey.swift in Sources */,
|
||||
84C9FC7722629E1200D921D6 /* AdvancedPreferencesViewController.swift in Sources */,
|
||||
849EE72120391F560082A1EA /* SharingServicePickerDelegate.swift in Sources */,
|
||||
1710B9132552354E00679C0D /* AddAccountHelpView.swift in Sources */,
|
||||
5108F6B62375E612001ABC45 /* CacheCleaner.swift in Sources */,
|
||||
849A97981ED9EFAA007D329B /* Node-Extensions.swift in Sources */,
|
||||
849EE70F203919360082A1EA /* AppAssets.swift in Sources */,
|
||||
|
||||
@@ -69,8 +69,8 @@
|
||||
"repositoryURL": "https://github.com/Ranchero-Software/RSParser.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "21d57ffb7ae744cf70bf6ddfb7ad8b7c102e05cf",
|
||||
"version": "2.0.0-beta2"
|
||||
"revision": "a4467cb6ab32d67fa8b09fcef8b234c7f96b7f9c",
|
||||
"version": "2.0.0-beta3"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -52,8 +52,6 @@ extension AccountType {
|
||||
return NSLocalizedString("NewsBlur", comment: "Account name")
|
||||
case .theOldReader:
|
||||
return NSLocalizedString("The Old Reader", comment: "Account name")
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -276,12 +276,7 @@ private extension ArticleRenderer {
|
||||
#else
|
||||
func styleSubstitutions() -> [String: String] {
|
||||
var d = [String: String]()
|
||||
|
||||
if #available(macOS 11.0, *) {
|
||||
let bodyFont = NSFont.preferredFont(forTextStyle: .body)
|
||||
d["font-size"] = String(describing: Int(round(bodyFont.pointSize * 1.33)))
|
||||
}
|
||||
|
||||
d["font-size"] = String(describing: AppDefaults.shared.articleTextSize.fontSize)
|
||||
return d
|
||||
}
|
||||
#endif
|
||||
|
||||
52
Shared/Article Rendering/ArticleTextSize.swift
Normal file
52
Shared/Article Rendering/ArticleTextSize.swift
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// ArticleTextSize.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 11/3/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum ArticleTextSize: Int, CaseIterable, Identifiable {
|
||||
case small = 1
|
||||
case medium = 2
|
||||
case large = 3
|
||||
case xlarge = 4
|
||||
case xxlarge = 5
|
||||
|
||||
#if os(macOS)
|
||||
var fontSize: Int {
|
||||
switch self {
|
||||
case .small:
|
||||
return 14
|
||||
case .medium:
|
||||
return 16
|
||||
case .large:
|
||||
return 18
|
||||
case .xlarge:
|
||||
return 20
|
||||
case .xxlarge:
|
||||
return 22
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
var id: String { description() }
|
||||
|
||||
func description() -> String {
|
||||
switch self {
|
||||
case .small:
|
||||
return NSLocalizedString("Small", comment: "Small")
|
||||
case .medium:
|
||||
return NSLocalizedString("Medium", comment: "Medium")
|
||||
case .large:
|
||||
return NSLocalizedString("Large", comment: "Large")
|
||||
case .xlarge:
|
||||
return NSLocalizedString("X-Large", comment: "X-Large")
|
||||
case .xxlarge:
|
||||
return NSLocalizedString("XX-Large", comment: "XX-Large")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,7 +16,7 @@ extension RedditFeedProvider: ExtensionPoint {
|
||||
static var title = NSLocalizedString("Reddit", comment: "Reddit")
|
||||
static var image = AppAssets.extensionPointReddit
|
||||
static var description: NSAttributedString = {
|
||||
return RedditFeedProvider.makeAttrString("This extension enables you to subscribe to Reddit URL's as if they were RSS feeds. It only works with \(Account.defaultLocalAccountName) or iCloud accounts.")
|
||||
return RedditFeedProvider.makeAttrString("This extension enables you to subscribe to Reddit URLs as if they were RSS feeds. It only works with \(Account.defaultLocalAccountName) or iCloud accounts.")
|
||||
}()
|
||||
|
||||
var extensionPointID: ExtensionPointIdentifer {
|
||||
|
||||
@@ -17,7 +17,7 @@ final class SendToMarsEditCommand: ExtensionPoint, SendToCommand {
|
||||
static var title = NSLocalizedString("MarsEdit", comment: "MarsEdit")
|
||||
static var image = AppAssets.extensionPointMarsEdit
|
||||
static var description: NSAttributedString = {
|
||||
let attrString = SendToMarsEditCommand.makeAttrString("This extension enables share menu functionality to send selected article text to MarsEdit. You need the MarsEdit application for this to work.")
|
||||
let attrString = SendToMarsEditCommand.makeAttrString("This extension enables share menu functionality to send selected article text to MarsEdit. You need the MarsEdit application for this to work.")
|
||||
let range = NSRange(location: 81, length: 8)
|
||||
attrString.beginEditing()
|
||||
attrString.addAttribute(NSAttributedString.Key.link, value: "https://red-sweater.com/marsedit/", range: range)
|
||||
|
||||
@@ -19,7 +19,7 @@ final class SendToMicroBlogCommand: ExtensionPoint, SendToCommand {
|
||||
static var title: String = NSLocalizedString("Micro.blog", comment: "Micro.blog")
|
||||
static var image = AppAssets.extensionPointMicroblog
|
||||
static var description: NSAttributedString = {
|
||||
let attrString = SendToMicroBlogCommand.makeAttrString("This extension enables share menu functionality to send selected article text to Micro.blog. You need the Micro.blog application for this to work.")
|
||||
let attrString = SendToMicroBlogCommand.makeAttrString("This extension enables share menu functionality to send selected article text to Micro.blog. You need the Micro.blog application for this to work.")
|
||||
let range = NSRange(location: 81, length: 10)
|
||||
attrString.beginEditing()
|
||||
attrString.addAttribute(NSAttributedString.Key.link, value: "https://micro.blog", range: range)
|
||||
|
||||
@@ -16,7 +16,7 @@ extension TwitterFeedProvider: ExtensionPoint {
|
||||
static var title = NSLocalizedString("Twitter", comment: "Twitter")
|
||||
static var image = AppAssets.extensionPointTwitter
|
||||
static var description: NSAttributedString = {
|
||||
return TwitterFeedProvider.makeAttrString("This extension enables you to subscribe to Twitter URL's as if they were RSS feeds. It only works with \(Account.defaultLocalAccountName) or iCloud accounts.")
|
||||
return TwitterFeedProvider.makeAttrString("This extension enables you to subscribe to Twitter URLs as if they were RSS feeds. It only works with \(Account.defaultLocalAccountName) or iCloud accounts.")
|
||||
}()
|
||||
|
||||
var extensionPointID: ExtensionPointIdentifer {
|
||||
|
||||
@@ -20,18 +20,21 @@ extension Array where Element == Article {
|
||||
return self[row]
|
||||
}
|
||||
|
||||
func rowOfNextUnreadArticle(_ selectedRow: Int) -> Int? {
|
||||
func orderedRowIndexes(fromIndex startIndex: Int, wrappingToTop wrapping: Bool) -> [Int] {
|
||||
if startIndex >= self.count {
|
||||
// Wrap around to the top if specified
|
||||
return wrapping ? Array<Int>(0..<self.count) : []
|
||||
} else {
|
||||
// Start at the selection and wrap around to the beginning
|
||||
return Array<Int>(startIndex..<self.count) + (wrapping ? Array<Int>(0..<startIndex) : [])
|
||||
}
|
||||
}
|
||||
func rowOfNextUnreadArticle(_ selectedRow: Int, wrappingToTop wrapping: Bool) -> Int? {
|
||||
if isEmpty {
|
||||
return nil
|
||||
}
|
||||
|
||||
var rowIndex = selectedRow
|
||||
while(true) {
|
||||
|
||||
rowIndex = rowIndex + 1
|
||||
if rowIndex >= count {
|
||||
break
|
||||
}
|
||||
for rowIndex in orderedRowIndexes(fromIndex: selectedRow + 1, wrappingToTop: wrapping) {
|
||||
let article = articleAtRow(rowIndex)!
|
||||
if !article.status.read {
|
||||
return rowIndex
|
||||
|
||||
@@ -627,7 +627,7 @@
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="API URL" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="iPv-M2-U8Q">
|
||||
<rect key="frame" x="14" y="11" width="340" height="22"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<textInputTraits key="textInputTraits" textContentType="url"/>
|
||||
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="URL" smartDashesType="no" smartInsertDeleteType="no" smartQuotesType="no" textContentType="url"/>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
|
||||
@@ -82,7 +82,7 @@ class FeedbinAccountViewController: UITableViewController {
|
||||
// When you fill in the email address via auto-complete it adds extra whitespace
|
||||
let trimmedEmail = email.trimmingCharacters(in: .whitespaces)
|
||||
|
||||
guard !AccountManager.shared.duplicateServiceAccount(type: .feedbin, username: trimmedEmail) else {
|
||||
guard account != nil || !AccountManager.shared.duplicateServiceAccount(type: .feedbin, username: trimmedEmail) else {
|
||||
showError(NSLocalizedString("There is already a Feedbin account with that username created.", comment: "Duplicate Error"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ struct AppAssets {
|
||||
}()
|
||||
|
||||
static var masterFolderImage: IconImage = {
|
||||
return IconImage(UIImage(systemName: "folder.fill")!)
|
||||
return IconImage(UIImage(systemName: "folder.fill")!, isSymbol: true)
|
||||
}()
|
||||
|
||||
static var moreImage: UIImage = {
|
||||
@@ -186,7 +186,7 @@ struct AppAssets {
|
||||
}()
|
||||
|
||||
static var searchFeedImage: IconImage = {
|
||||
return IconImage(UIImage(systemName: "magnifyingglass")!)
|
||||
return IconImage(UIImage(systemName: "magnifyingglass")!, isSymbol: true)
|
||||
}()
|
||||
|
||||
static var secondaryAccentColor: UIColor = {
|
||||
|
||||
@@ -52,7 +52,7 @@ final class IconView: UIView {
|
||||
}
|
||||
|
||||
private var isSymbolImage: Bool {
|
||||
return imageView.image?.isSymbolImage ?? false
|
||||
return iconImage?.isSymbol ?? false
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
@@ -75,7 +75,7 @@ final class IconView: UIView {
|
||||
|
||||
override func layoutSubviews() {
|
||||
imageView.setFrameIfNotEqual(rectForImageView())
|
||||
if (iconImage != nil && isVerticalBackgroundExposed && !isSymbolImage) || !isDisconcernable {
|
||||
if !isSymbolImage && ((iconImage != nil && isVerticalBackgroundExposed) || !isDisconcernable) {
|
||||
backgroundColor = AppAssets.iconBackgroundColor
|
||||
} else {
|
||||
backgroundColor = nil
|
||||
|
||||
@@ -18,13 +18,16 @@ extension MasterFeedViewController: UITableViewDropDelegate {
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {
|
||||
guard let destIndexPath = destinationIndexPath,
|
||||
destIndexPath.section > 0,
|
||||
tableView.hasActiveDrag,
|
||||
let destIdentifier = dataSource.itemIdentifier(for: destIndexPath),
|
||||
let destAccount = destIdentifier.account,
|
||||
let destCell = tableView.cellForRow(at: destIndexPath) else {
|
||||
return UITableViewDropProposal(operation: .forbidden)
|
||||
guard let destIndexPath = destinationIndexPath, destIndexPath.section > 0, tableView.hasActiveDrag else {
|
||||
return UITableViewDropProposal(operation: .forbidden)
|
||||
}
|
||||
|
||||
guard let destIdentifier = dataSource.itemIdentifier(for: destIndexPath) else {
|
||||
return UITableViewDropProposal(operation: .move, intent: .insertIntoDestinationIndexPath)
|
||||
}
|
||||
|
||||
guard let destAccount = destIdentifier.account, let destCell = tableView.cellForRow(at: destIndexPath) else {
|
||||
return UITableViewDropProposal(operation: .forbidden)
|
||||
}
|
||||
|
||||
// Validate account specific behaviors...
|
||||
@@ -90,7 +93,8 @@ extension MasterFeedViewController: UITableViewDropDelegate {
|
||||
if let containerID = destIdentifier?.containerID ?? destIdentifier?.parentContainerID {
|
||||
return AccountManager.shared.existingContainer(with: containerID)
|
||||
} else {
|
||||
return nil
|
||||
// If we got here, we are trying to drop on an empty section header. Go and find the Account for this section
|
||||
return coordinator.rootNode.childAtIndex(destIndexPath.section)?.representedObject as? Account
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
@@ -337,8 +337,8 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
|
||||
return proposedDestinationIndexPath
|
||||
}
|
||||
|
||||
// If this is a folder and isn't expanded or doesn't have any entries, let the users drop on it
|
||||
if destNode.representedObject is Folder && (destNode.numberOfChildNodes == 0 || !coordinator.isExpanded(destNode)) {
|
||||
// If this is a folder, let the users drop on it
|
||||
if destNode.representedObject is Folder {
|
||||
return proposedDestinationIndexPath
|
||||
}
|
||||
|
||||
|
||||
@@ -114,11 +114,11 @@ private extension SceneDelegate {
|
||||
DispatchQueue.main.async {
|
||||
switch AppDefaults.userInterfaceColorPalette {
|
||||
case .automatic:
|
||||
self.window!.overrideUserInterfaceStyle = .unspecified
|
||||
self.window?.overrideUserInterfaceStyle = .unspecified
|
||||
case .light:
|
||||
self.window!.overrideUserInterfaceStyle = .light
|
||||
self.window?.overrideUserInterfaceStyle = .light
|
||||
case .dark:
|
||||
self.window!.overrideUserInterfaceStyle = .dark
|
||||
self.window?.overrideUserInterfaceStyle = .dark
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,6 @@ PRODUCT_BUNDLE_IDENTIFIER = $(ORGANIZATION_IDENTIFIER).NetNewsWire-Evergreen
|
||||
PRODUCT_NAME = NetNewsWire
|
||||
|
||||
// Override NetNewsWire_project.xcconfig until we are ready to only target 10.16
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.16
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off
|
||||
SWIFT_VERSION = 5.3
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// High Level Settings common to both the iOS application and any extensions we bundle with it
|
||||
MARKETING_VERSION = 5.0.4
|
||||
CURRENT_PROJECT_VERSION = 53
|
||||
MARKETING_VERSION = 5.0.5
|
||||
CURRENT_PROJECT_VERSION = 56
|
||||
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon
|
||||
|
||||
@@ -3,6 +3,7 @@ MARKETING_VERSION = 5.1.2
|
||||
CURRENT_PROJECT_VERSION = 3016
|
||||
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon
|
||||
COMBINE_HIDPI_IMAGES = YES
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15
|
||||
|
||||
Reference in New Issue
Block a user