Merge branch 'ios-release' into main
This commit is contained in:
commit
a500166af0
|
@ -48,11 +48,11 @@ final class ArticlesTable: DatabaseTable {
|
|||
// MARK: - Fetching Articles for Feed
|
||||
|
||||
func fetchArticles(_ webFeedID: String) throws -> Set<Article> {
|
||||
return try fetchArticles{ self.fetchArticlesForFeedID(webFeedID, withLimits: true, $0) }
|
||||
return try fetchArticles{ self.fetchArticlesForFeedID(webFeedID, $0) }
|
||||
}
|
||||
|
||||
func fetchArticlesAsync(_ webFeedID: String, _ completion: @escaping ArticleSetResultBlock) {
|
||||
fetchArticlesAsync({ self.fetchArticlesForFeedID(webFeedID, withLimits: true, $0) }, completion)
|
||||
fetchArticlesAsync({ self.fetchArticlesForFeedID(webFeedID, $0) }, completion)
|
||||
}
|
||||
|
||||
func fetchArticles(_ webFeedIDs: Set<String>) throws -> Set<Article> {
|
||||
|
@ -204,7 +204,7 @@ final class ArticlesTable: DatabaseTable {
|
|||
return
|
||||
}
|
||||
|
||||
let fetchedArticles = self.fetchArticlesForFeedID(webFeedID, withLimits: false, database) //4
|
||||
let fetchedArticles = self.fetchArticlesForFeedID(webFeedID, database) //4
|
||||
let fetchedArticlesDictionary = fetchedArticles.dictionary()
|
||||
|
||||
let newArticles = self.findAndSaveNewArticles(incomingArticles, fetchedArticlesDictionary, database) //5
|
||||
|
@ -626,7 +626,7 @@ final class ArticlesTable: DatabaseTable {
|
|||
return
|
||||
}
|
||||
|
||||
let sql = "update statuses set read = true where dateArrived<?;"
|
||||
let sql = "update statuses set read = 1 where dateArrived<?;"
|
||||
let parameters = [self.articleCutoffDate] as [Any]
|
||||
database.executeUpdate(sql, withArgumentsIn: parameters)
|
||||
}
|
||||
|
@ -832,7 +832,7 @@ private extension ArticlesTable {
|
|||
return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters)
|
||||
}
|
||||
|
||||
func fetchArticlesForFeedID(_ webFeedID: String, withLimits: Bool, _ database: FMDatabase) -> Set<Article> {
|
||||
func fetchArticlesForFeedID(_ webFeedID: String, _ database: FMDatabase) -> Set<Article> {
|
||||
return fetchArticlesWithWhereClause(database, whereClause: "articles.feedID = ?", parameters: [webFeedID as AnyObject])
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ function wrapFrames() {
|
|||
document.querySelectorAll("iframe").forEach(element => {
|
||||
if (element.height > 0 || parseInt(element.style.height) > 0)
|
||||
return;
|
||||
|
||||
var wrapper = document.createElement("div");
|
||||
wrapper.classList.add("iframeWrap");
|
||||
element.parentNode.insertBefore(wrapper, element);
|
||||
|
|
|
@ -28,4 +28,13 @@ extension URL {
|
|||
#endif
|
||||
}
|
||||
|
||||
func valueFor(_ parameter: String) -> String? {
|
||||
guard let components = URLComponents(url: self, resolvingAgainstBaseURL: false),
|
||||
let queryItems = components.queryItems,
|
||||
let value = queryItems.first(where: { $0.name == parameter })?.value else {
|
||||
return nil
|
||||
}
|
||||
return value
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -353,6 +353,7 @@ extension WebViewController: WKNavigationDelegate {
|
|||
if MFMailComposeViewController.canSendMail() {
|
||||
let mailComposeViewController = MFMailComposeViewController()
|
||||
mailComposeViewController.setToRecipients([emailAddress])
|
||||
mailComposeViewController.setSubject(url.valueFor("subject") ?? "")
|
||||
mailComposeViewController.mailComposeDelegate = self
|
||||
self.present(mailComposeViewController, animated: true, completion: {})
|
||||
} else {
|
||||
|
|
|
@ -21,12 +21,22 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView {
|
|||
get {
|
||||
if unreadCount > 0 {
|
||||
let unreadLabel = NSLocalizedString("unread", comment: "Unread label for accessiblity")
|
||||
return "\(name) \(unreadCount) \(unreadLabel)"
|
||||
return "\(name) \(unreadCount) \(unreadLabel) \(expandedStateMessage) "
|
||||
} else {
|
||||
return name
|
||||
return "\(name) \(expandedStateMessage) "
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var expandedStateMessage: String {
|
||||
set {}
|
||||
get {
|
||||
if disclosureExpanded {
|
||||
return NSLocalizedString("Expanded", comment: "Disclosure button expanded state for accessibility")
|
||||
}
|
||||
return NSLocalizedString("Collapsed", comment: "Disclosure button collapsed state for accessibility")
|
||||
}
|
||||
}
|
||||
|
||||
var unreadCount: Int {
|
||||
get {
|
||||
|
|
|
@ -599,7 +599,7 @@ extension MasterFeedViewController: UIContextMenuInteractionDelegate {
|
|||
|
||||
var actions = [accountInfoAction, deactivateAction]
|
||||
|
||||
if let markAllAction = self.markAllAsReadAction(account: account) {
|
||||
if let markAllAction = self.markAllAsReadAction(account: account, contentView: interaction.view) {
|
||||
actions.insert(markAllAction, at: 1)
|
||||
}
|
||||
|
||||
|
@ -1135,23 +1135,31 @@ private extension MasterFeedViewController {
|
|||
return markAllAsReadAction(articles: articles, nameForDisplay: feed.nameForDisplay, indexPath: indexPath)
|
||||
}
|
||||
|
||||
func markAllAsReadAction(account: Account) -> UIAction? {
|
||||
func markAllAsReadAction(account: Account, contentView: UIView?) -> UIAction? {
|
||||
guard let fetchedArticles = try? account.fetchArticles(FetchType.unread) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let articles = Array(fetchedArticles)
|
||||
return markAllAsReadAction(articles: articles, nameForDisplay: account.nameForDisplay)
|
||||
return markAllAsReadAction(articles: articles, nameForDisplay: account.nameForDisplay, contentView: contentView)
|
||||
}
|
||||
|
||||
func markAllAsReadAction(articles: [Article], nameForDisplay: String, indexPath: IndexPath? = nil) -> UIAction? {
|
||||
guard articles.canMarkAllAsRead(), let indexPath = indexPath, let contentView = self.tableView.cellForRow(at: indexPath)?.contentView else {
|
||||
guard let indexPath = indexPath,
|
||||
let contentView = self.tableView.cellForRow(at: indexPath)?.contentView else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return markAllAsReadAction(articles: articles, nameForDisplay: nameForDisplay, contentView: contentView)
|
||||
}
|
||||
|
||||
func markAllAsReadAction(articles: [Article], nameForDisplay: String, contentView: UIView?) -> UIAction? {
|
||||
guard articles.canMarkAllAsRead(), let contentView = contentView else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let localizedMenuText = NSLocalizedString("Mark All as Read in “%@”", comment: "Command")
|
||||
let title = NSString.localizedStringWithFormat(localizedMenuText as NSString, nameForDisplay) as String
|
||||
|
||||
let action = UIAction(title: title, image: AppAssets.markAllAsReadImage) { [weak self] action in
|
||||
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView) { [weak self] in
|
||||
self?.coordinator.markAllAsRead(articles)
|
||||
|
|
|
@ -256,8 +256,9 @@ private extension MasterTimelineTableViewCell {
|
|||
}
|
||||
|
||||
func updateAccessiblityLabel() {
|
||||
var label = cellData.read ? "" : "\(NSLocalizedString("Unread", comment: "Unread")), "
|
||||
label += "\(cellData.feedName), \(cellData.title), \(cellData.summary), \(cellData.dateString)"
|
||||
let starredStatus = cellData.starred ? "\(NSLocalizedString("Starred", comment: "Starred article for accessibility")), " : ""
|
||||
let unreadStatus = cellData.read ? "" : "\(NSLocalizedString("Unread", comment: "Unread")), "
|
||||
let label = starredStatus + unreadStatus + "\(cellData.feedName), \(cellData.title), \(cellData.summary), \(cellData.dateString)"
|
||||
accessibilityLabel = label
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,20 @@ class MasterTimelineTitleView: UIView {
|
|||
private lazy var pointerInteraction: UIPointerInteraction = {
|
||||
UIPointerInteraction(delegate: self)
|
||||
}()
|
||||
|
||||
|
||||
override var accessibilityLabel: String? {
|
||||
set { }
|
||||
get {
|
||||
if let name = label.text {
|
||||
let unreadLabel = NSLocalizedString("unread", comment: "Unread label for accessiblity")
|
||||
return "\(name) \(unreadCountView.unreadCount) \(unreadLabel)"
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buttonize() {
|
||||
heightAnchor.constraint(equalToConstant: 40.0).isActive = true
|
||||
accessibilityTraits = .button
|
||||
|
@ -28,6 +41,7 @@ class MasterTimelineTitleView: UIView {
|
|||
}
|
||||
|
||||
func debuttonize() {
|
||||
heightAnchor.constraint(equalToConstant: 40.0).isActive = true
|
||||
accessibilityTraits.remove(.button)
|
||||
if #available(iOS 13.4, *) {
|
||||
removeInteraction(pointerInteraction)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{\rtf1\ansi\ansicpg1252\cocoartf2511
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf2513
|
||||
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
|
||||
{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
|
||||
{\*\expandedcolortbl;;\cssrgb\c0\c0\c0\cname textColor;}
|
||||
|
@ -17,4 +17,4 @@ Under-the-hood magic and CSS stylin\'92s: {\field{\*\fldinst{HYPERLINK "https://
|
|||
\pard\pardeftab720\li355\fi-356\sa60\partightenfactor0
|
||||
\cf2 Help book: {\field{\*\fldinst{HYPERLINK "https://nostodnayr.net/"}}{\fldrslt Ryan Dotson}}\
|
||||
\pard\pardeftab720\li358\fi-359\sa60\partightenfactor0
|
||||
\cf2 And more {\field{\*\fldinst{HYPERLINK "https://github.com/brentsimmons/NetNewsWire/graphs/contributors"}}{\fldrslt contributors}}!}
|
||||
\cf2 And featuring contributions from {\field{\*\fldinst{HYPERLINK "https://blog.rizwan.dev/"}}{\fldrslt Rizwan Mohamed Ibrahim}}, {\field{\*\fldinst{HYPERLINK "https://stuartbreckenridge.com/"}}{\fldrslt Stuart Breckenridge}}, {\field{\*\fldinst{HYPERLINK "https://twitter.com/philviso"}}{\fldrslt Phil Viso}}, and {\field{\*\fldinst{HYPERLINK "https://github.com/Ranchero-Software/NetNewsWire/graphs/contributors"}}{\fldrslt many more}}!}
|
|
@ -35,7 +35,7 @@
|
|||
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
<key>NSExtensionActivationSupportsText</key>
|
||||
<string>1</string>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>NSExtensionJavaScriptPreprocessingFile</key>
|
||||
<string>SafariExt</string>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
// High Level Settings common to both the iOS application and any extensions we bundle with it
|
||||
MARKETING_VERSION = 5.0.1
|
||||
CURRENT_PROJECT_VERSION = 46
|
||||
MARKETING_VERSION = 5.0.3
|
||||
CURRENT_PROJECT_VERSION = 50
|
||||
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon
|
||||
|
|
Loading…
Reference in New Issue