diff --git a/Multiplatform/Shared/Add/AddWebFeedModel.swift b/Multiplatform/Shared/Add/AddWebFeedModel.swift index 1520d312e..452a61258 100644 --- a/Multiplatform/Shared/Add/AddWebFeedModel.swift +++ b/Multiplatform/Shared/Add/AddWebFeedModel.swift @@ -55,7 +55,7 @@ class AddWebFeedModel: ObservableObject { } func pasteUrlFromPasteboard() { - guard let stringFromPasteboard = urlStringFromPasteboard, stringFromPasteboard.isValidURL else { + guard let stringFromPasteboard = urlStringFromPasteboard, stringFromPasteboard.mayBeURL else { return } providedURL = stringFromPasteboard @@ -97,15 +97,22 @@ class AddWebFeedModel: ObservableObject { showProgressIndicator = true + let normalizedURLString = providedURL.normalizedURL + + guard !normalizedURLString.isEmpty, let url = URL(string: normalizedURLString) else { + showProgressIndicator = false + return + } + let container = containers[selectedFolderIndex] - if account.hasWebFeed(withURL: providedURL) { + if account.hasWebFeed(withURL: normalizedURLString) { addFeedError = .alreadySubscribed showProgressIndicator = false return } - account.createWebFeed(url: providedURL, name: providedName, container: container, completion: { [weak self] result in + account.createWebFeed(url: url.absoluteString, name: providedName, container: container, completion: { [weak self] result in self?.showProgressIndicator = false switch result { case .success(let feed): diff --git a/Multiplatform/Shared/Add/AddWebFeedView.swift b/Multiplatform/Shared/Add/AddWebFeedView.swift index 2ab535457..40fb3754c 100644 --- a/Multiplatform/Shared/Add/AddWebFeedView.swift +++ b/Multiplatform/Shared/Add/AddWebFeedView.swift @@ -96,11 +96,16 @@ struct AddWebFeedView: View { }) .help("Cancel Add Feed") , trailing: - Button("Add", action: { - viewModel.addWebFeed() - }) - .disabled(!viewModel.providedURL.isValidURL) - .help("Add Feed") + HStack(spacing: 12) { + if viewModel.showProgressIndicator == true { + ProgressView() + } + Button("Add", action: { + viewModel.addWebFeed() + }) + .disabled(!viewModel.providedURL.mayBeURL) + .help("Add Feed") + } ) } } @@ -174,7 +179,7 @@ struct AddWebFeedView: View { Button("Add", action: { viewModel.addWebFeed() }) - .disabled(!viewModel.providedURL.isValidURL) + .disabled(!viewModel.providedURL.mayBeURL) .help("Add Feed") }.padding(.trailing, 2) } diff --git a/Multiplatform/Shared/String+URLChecker.swift b/Multiplatform/Shared/String+URLChecker.swift deleted file mode 100644 index c1994b1b1..000000000 --- a/Multiplatform/Shared/String+URLChecker.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// String+URLChecker.swift -// NetNewsWire -// -// Created by Stuart Breckenridge on 3/7/20. -// Copyright © 2020 Ranchero Software. All rights reserved. -// - -import Foundation - -extension String { - - /// Reference: [StackOverflow](https://stackoverflow.com/questions/161738/what-is-the-best-regular-expression-to-check-if-a-string-is-a-valid-url) - var isValidURL: Bool { - let regEx = "^([a-zA-Z0-9\\.\\-]+(\\:[a-zA-Z0-9\\.&%\\$\\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9\\-]+\\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\\:[0-9]+)*(/($|[a-zA-Z0-9\\.\\,\\?\\'\\\\\\+&%\\$#\\=~_\\-]+))*$" - let predicate = NSPredicate(format:"SELF MATCHES %@", argumentArray:[regEx]) - return predicate.evaluate(with: self) - } -} diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index e72cb1305..272ba8500 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -21,8 +21,6 @@ 175942AB24AD533200585066 /* RefreshInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCE4226F4DFA0010922C /* RefreshInterval.swift */; }; 1776E88E24AC5F8A00E78166 /* AppDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1776E88D24AC5F8A00E78166 /* AppDefaults.swift */; }; 1776E88F24AC5F8A00E78166 /* AppDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1776E88D24AC5F8A00E78166 /* AppDefaults.swift */; }; - 17925E1724AF41D000D3A4F6 /* String+URLChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17925E1624AF41D000D3A4F6 /* String+URLChecker.swift */; }; - 17925E1824AF41D000D3A4F6 /* String+URLChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17925E1624AF41D000D3A4F6 /* String+URLChecker.swift */; }; 17930ED424AF10EE00A9BA52 /* AddWebFeedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17930ED324AF10EE00A9BA52 /* AddWebFeedView.swift */; }; 17930ED524AF10EE00A9BA52 /* AddWebFeedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17930ED324AF10EE00A9BA52 /* AddWebFeedView.swift */; }; 179DB1DFBCF9177104B12E0F /* AccountsNewsBlurWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DBBA2B22A659F81EED6F9 /* AccountsNewsBlurWindowController.swift */; }; @@ -1736,7 +1734,6 @@ 1729529A24AA1FD200D65E66 /* MacSearchField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacSearchField.swift; sourceTree = ""; }; 172952AF24AA287100D65E66 /* CompactSidebarContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompactSidebarContainerView.swift; sourceTree = ""; }; 1776E88D24AC5F8A00E78166 /* AppDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDefaults.swift; sourceTree = ""; }; - 17925E1624AF41D000D3A4F6 /* String+URLChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+URLChecker.swift"; sourceTree = ""; }; 17930ED324AF10EE00A9BA52 /* AddWebFeedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddWebFeedView.swift; sourceTree = ""; }; 179DBBA2B22A659F81EED6F9 /* AccountsNewsBlurWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsNewsBlurWindowController.swift; sourceTree = ""; }; 17B223DB24AC24D2001E4592 /* TimelineLayoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineLayoutView.swift; sourceTree = ""; }; @@ -2799,7 +2796,6 @@ 51E499FB24A9135A00B667CB /* Sidebar */, 514E6C0424AD2B0400AC6F6E /* SwiftUI Extensions */, 51919FCB24AB855000541E64 /* Timeline */, - 17925E1624AF41D000D3A4F6 /* String+URLChecker.swift */, ); path = Shared; sourceTree = ""; @@ -4884,7 +4880,6 @@ 514E6C0624AD2B5F00AC6F6E /* Image-Extensions.swift in Sources */, 51E4995624A8734D00B667CB /* TwitterFeedProvider-Extensions.swift in Sources */, 5125E6CA24AE461D002A7562 /* TimelineLayoutView.swift in Sources */, - 17925E1724AF41D000D3A4F6 /* String+URLChecker.swift in Sources */, 51E4996824A8760C00B667CB /* ArticleStyle.swift in Sources */, 51E4990024A808BB00B667CB /* FaviconGenerator.swift in Sources */, 51E4997124A8764C00B667CB /* ActivityType.swift in Sources */, @@ -4964,7 +4959,6 @@ 51E4993424A867E700B667CB /* UserInfoKey.swift in Sources */, 1776E88F24AC5F8A00E78166 /* AppDefaults.swift in Sources */, 1729529724AA1CD000D65E66 /* MacPreferencesView.swift in Sources */, - 17925E1824AF41D000D3A4F6 /* String+URLChecker.swift in Sources */, 51E4994C24A8734C00B667CB /* RedditFeedProvider-Extensions.swift in Sources */, 1729529324AA1CAA00D65E66 /* AccountsPreferencesView.swift in Sources */, 51919FAD24AA8CCA00541E64 /* UnreadCountView.swift in Sources */,