diff --git a/Beam/AppDelegate.swift b/Beam/AppDelegate.swift index 94a64ca..7c2d2bf 100644 --- a/Beam/AppDelegate.swift +++ b/Beam/AppDelegate.swift @@ -340,6 +340,7 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { do { var subreddits = try objectContext.fetch(fetchRequest) subreddits.append(try Subreddit.frontpageSubreddit()) + subreddits.append(try Subreddit.popularSubreddit()) subreddits.append(try Subreddit.allSubreddit()) let searchableItems = subreddits.compactMap({ (subreddit) -> CSSearchableItem? in @@ -449,7 +450,7 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { do { let fetchRequest = NSFetchRequest(entityName: Subreddit.entityName()) fetchRequest.sortDescriptors = [NSSortDescriptor(key: "order", ascending: true), NSSortDescriptor(key: "displayName", ascending: true, selector: #selector(NSString.localizedStandardCompare(_:))), NSSortDescriptor(key: "identifier", ascending: true)] - fetchRequest.predicate = NSPredicate(format: "isBookmarked == YES && NOT (identifier IN %@)", [Subreddit.frontpageIdentifier, Subreddit.allIdentifier]) + fetchRequest.predicate = NSPredicate(format: "isBookmarked == YES && NOT (identifier IN %@)", [Subreddit.frontpageIdentifier, Subreddit.popularIdentifier, Subreddit.allIdentifier]) fetchRequest.fetchLimit = 3 subreddits = try objectContext.fetch(fetchRequest) let frontpage = try Subreddit.frontpageSubreddit() @@ -478,12 +479,14 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { self.changeActiveTabContent(AppTabContent.MessagesNavigation) case AppLaunchView.Profile: self.changeActiveTabContent(AppTabContent.ProfileNavigation) - case AppLaunchView.Frontpage, AppLaunchView.All, AppLaunchView.LastVisitedSubreddit: + case AppLaunchView.Frontpage, AppLaunchView.Popular, AppLaunchView.All, AppLaunchView.LastVisitedSubreddit: self.changeActiveTabContent(AppTabContent.SubscriptionsNavigation) var subreddit: Subreddit? do { if appOpenView == AppLaunchView.Frontpage { subreddit = try Subreddit.frontpageSubreddit() + } else if appOpenView == AppLaunchView.Popular { + subreddit = try Subreddit.popularSubreddit() } else if appOpenView == AppLaunchView.All { subreddit = try Subreddit.allSubreddit() } else if appOpenView == AppLaunchView.LastVisitedSubreddit { diff --git a/Beam/Controllers/RedditActivityController.swift b/Beam/Controllers/RedditActivityController.swift index 1b15658..6823362 100644 --- a/Beam/Controllers/RedditActivityController.swift +++ b/Beam/Controllers/RedditActivityController.swift @@ -35,7 +35,7 @@ class RedditActivityController: NSObject { return [Subreddit]() } let fetchRequest = NSFetchRequest(entityName: Subreddit.entityName()) - fetchRequest.predicate = NSPredicate(format: "lastVisitDate != nil && NOT(identifier IN %@)", [Subreddit.allIdentifier, Subreddit.frontpageIdentifier]) + fetchRequest.predicate = NSPredicate(format: "lastVisitDate != nil && NOT(identifier IN %@)", [Subreddit.allIdentifier, Subreddit.popularIdentifier, Subreddit.frontpageIdentifier]) fetchRequest.sortDescriptors = [NSSortDescriptor(key: "lastVisitDate", ascending: false), NSSortDescriptor(key: "displayName", ascending: true, selector: #selector(NSString.localizedStandardCompare(_:)))] fetchRequest.fetchLimit = 5 diff --git a/Beam/In-App Settings/AppLaunchOption.swift b/Beam/In-App Settings/AppLaunchOption.swift index c657459..8df63bf 100644 --- a/Beam/In-App Settings/AppLaunchOption.swift +++ b/Beam/In-App Settings/AppLaunchOption.swift @@ -15,6 +15,7 @@ public enum AppLaunchView: String { case Messages = "messages" case Profile = "profile" case Frontpage = "frontpage" + case Popular = "popular" case All = "All" case LastVisitedSubreddit = "last_visited_subreddit" } @@ -49,6 +50,7 @@ public struct AppLaunchOption: Equatable { "subreddit": [ AppLaunchOption(title: AWKLocalizedString("app-open-option-last-visited-subreddit"), view: AppLaunchView.LastVisitedSubreddit), AppLaunchOption(title: AWKLocalizedString("app-open-option-frontpage"), view: AppLaunchView.Frontpage), + AppLaunchOption(title: AWKLocalizedString("app-open-option-popular"), view: AppLaunchView.Popular), AppLaunchOption(title: AWKLocalizedString("app-open-option-all"), view: AppLaunchView.All) ] ] diff --git a/Beam/Localization/en.lproj/Localizable.strings b/Beam/Localization/en.lproj/Localizable.strings index 209ab10..43ae094 100644 --- a/Beam/Localization/en.lproj/Localizable.strings +++ b/Beam/Localization/en.lproj/Localizable.strings @@ -345,6 +345,8 @@ "frontpage-description" = "All subscriptions combined"; +"popular-description" = "Most popular posts on Reddit"; + "all-description" = "Everything on reddit"; "random-description" = "Gives a random subreddit"; @@ -859,6 +861,9 @@ /* The name for the subreddit "Frontpage" on reddit. PLEASE USE THE REDDIT TERM FOR THIS! */ "subreddit-frontpage" = "Frontpage"; +/* The name for the subreddit "Popular" on reddit. PLEASE USE THE REDDIT TERM FOR THIS! */ +"subreddit-popular" = "Popular"; + /* Multireddits The following strings have a relation to multiredditsA message displayed when the app couldn't download your list of multireddits */ "could-not-fetch-multireddits" = "Could not fetch multireddits"; @@ -1317,6 +1322,8 @@ "app-open-option-frontpage" = "Frontpage"; +"app-open-option-popular" = "Popular"; + "app-open-option-all" = "All"; /* WelcomeThe connect with reddit button on the welcome view */ diff --git a/Beam/Resources/Assets.xcassets/subreddit_icon_popular.imageset/Contents.json b/Beam/Resources/Assets.xcassets/subreddit_icon_popular.imageset/Contents.json new file mode 100644 index 0000000..acb6d77 --- /dev/null +++ b/Beam/Resources/Assets.xcassets/subreddit_icon_popular.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "subreddit_icon_star.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "subreddit_icon_star@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "subreddit_icon_star@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Beam/Resources/Assets.xcassets/subreddit_icon_popular.imageset/subreddit_icon_star.png b/Beam/Resources/Assets.xcassets/subreddit_icon_popular.imageset/subreddit_icon_star.png new file mode 100644 index 0000000..aea5b7c Binary files /dev/null and b/Beam/Resources/Assets.xcassets/subreddit_icon_popular.imageset/subreddit_icon_star.png differ diff --git a/Beam/Resources/Assets.xcassets/subreddit_icon_popular.imageset/subreddit_icon_star@2x.png b/Beam/Resources/Assets.xcassets/subreddit_icon_popular.imageset/subreddit_icon_star@2x.png new file mode 100644 index 0000000..eb882d3 Binary files /dev/null and b/Beam/Resources/Assets.xcassets/subreddit_icon_popular.imageset/subreddit_icon_star@2x.png differ diff --git a/Beam/Resources/Assets.xcassets/subreddit_icon_popular.imageset/subreddit_icon_star@3x.png b/Beam/Resources/Assets.xcassets/subreddit_icon_popular.imageset/subreddit_icon_star@3x.png new file mode 100644 index 0000000..070c0b1 Binary files /dev/null and b/Beam/Resources/Assets.xcassets/subreddit_icon_popular.imageset/subreddit_icon_star@3x.png differ diff --git a/Beam/UI/Search/SubredditListTableViewCell.swift b/Beam/UI/Search/SubredditListTableViewCell.swift index 8b38c0a..b2e3c4a 100644 --- a/Beam/UI/Search/SubredditListTableViewCell.swift +++ b/Beam/UI/Search/SubredditListTableViewCell.swift @@ -44,6 +44,8 @@ class SubredditListTableViewCell: BeamTableViewCell { var subtitle: String? if self.subreddit?.identifier == Subreddit.frontpageIdentifier { subtitle = "\n\(AWKLocalizedString("frontpage-description"))" + } else if self.subreddit?.identifier == Subreddit.popularIdentifier { + subtitle = "\n\(AWKLocalizedString("popular-description"))" } else if self.subreddit?.identifier == Subreddit.allIdentifier { subtitle = "\n\(AWKLocalizedString("all-description"))" } else if self.subreddit?.isUserAuthorized != true { diff --git a/Beam/UI/Subreddits/Media Overview/SubredditMediaOverviewViewController.swift b/Beam/UI/Subreddits/Media Overview/SubredditMediaOverviewViewController.swift index 99518fc..e625eb7 100644 --- a/Beam/UI/Subreddits/Media Overview/SubredditMediaOverviewViewController.swift +++ b/Beam/UI/Subreddits/Media Overview/SubredditMediaOverviewViewController.swift @@ -374,7 +374,7 @@ class SubredditMediaOverviewViewController: BeamViewController, SubredditTabItem toolbar?.toolbarView.delegate = self toolbar?.metadataView.delegate = self - let shouldShowSubreddit = (self.subreddit is Multireddit || self.subreddit?.identifier == Subreddit.frontpageIdentifier || self.subreddit?.identifier == Subreddit.allIdentifier) && UserSettings[.showPostMetadataSubreddit] && UserSettings[.showPostMetadata] + let shouldShowSubreddit = (self.subreddit is Multireddit || self.subreddit?.identifier == Subreddit.frontpageIdentifier || self.subreddit?.identifier == Subreddit.allIdentifier || self.subreddit?.identifier == Subreddit.popularIdentifier) && UserSettings[.showPostMetadataSubreddit] && UserSettings[.showPostMetadata] toolbar?.shouldShowSubreddit = shouldShowSubreddit gallery.bottomView = toolbar diff --git a/Beam/UI/Subreddits/Posts Stream/StreamViewController.swift b/Beam/UI/Subreddits/Posts Stream/StreamViewController.swift index c4e2831..47f13e3 100644 --- a/Beam/UI/Subreddits/Posts Stream/StreamViewController.swift +++ b/Beam/UI/Subreddits/Posts Stream/StreamViewController.swift @@ -350,7 +350,7 @@ class StreamViewController: BeamTableViewController, PostMetadataViewDelegate, B guard let content: [Content] = list?.array as? [Content] else { return [Content]() } - let shouldFilterSubreddits: Bool = subreddit.identifier == Subreddit.allIdentifier || subreddit.identifier == Subreddit.frontpageIdentifier + let shouldFilterSubreddits: Bool = subreddit.identifier == Subreddit.allIdentifier || subreddit.identifier == Subreddit.frontpageIdentifier || subreddit.identifier == Subreddit.popularIdentifier let filteredContent: [Content] = content.filter { (content: Content) -> Bool in var postTitle: String? var subredditName: String? @@ -531,9 +531,9 @@ class StreamViewController: BeamTableViewController, PostMetadataViewDelegate, B return false } if let subreddit = self.visibleSubreddit { - return subreddit is Multireddit || subreddit.identifier == Subreddit.frontpageIdentifier || subreddit.identifier == Subreddit.allIdentifier + return subreddit is Multireddit || subreddit.identifier == Subreddit.frontpageIdentifier || subreddit.identifier == Subreddit.allIdentifier || subreddit.identifier == Subreddit.popularIdentifier } else if let collection = self.collection as? PostCollection { - return collection.subreddit is Multireddit || collection.subreddit?.identifier == Subreddit.frontpageIdentifier || collection.subreddit?.identifier == Subreddit.allIdentifier || self.subreddit == nil + return collection.subreddit is Multireddit || collection.subreddit?.identifier == Subreddit.frontpageIdentifier || collection.subreddit?.identifier == Subreddit.allIdentifier || collection.subreddit?.identifier == Subreddit.popularIdentifier || self.subreddit == nil } return UserSettings[.showPostMetadataSubreddit] } diff --git a/Beam/UI/Subreddits/Subreddit View/Filtering/SubredditFilteringViewController.swift b/Beam/UI/Subreddits/Subreddit View/Filtering/SubredditFilteringViewController.swift index e66a035..d3c476c 100644 --- a/Beam/UI/Subreddits/Subreddit View/Filtering/SubredditFilteringViewController.swift +++ b/Beam/UI/Subreddits/Subreddit View/Filtering/SubredditFilteringViewController.swift @@ -27,7 +27,7 @@ class SubredditFilteringViewController: BeamViewController { fileprivate var keywordsChanged: Bool = false fileprivate var canFilterSubreddits: Bool { - return self.subreddit.identifier == Subreddit.allIdentifier || self.subreddit.identifier == Subreddit.frontpageIdentifier + return self.subreddit.identifier == Subreddit.allIdentifier || self.subreddit.identifier == Subreddit.frontpageIdentifier || self.subreddit.identifier == Subreddit.popularIdentifier } fileprivate var filteringType: SubredditFilteringType = SubredditFilteringType.keywords { diff --git a/Beam/UI/Subreddits/Subreddit View/SubredditStreamViewController.swift b/Beam/UI/Subreddits/Subreddit View/SubredditStreamViewController.swift index 5186d75..5842126 100644 --- a/Beam/UI/Subreddits/Subreddit View/SubredditStreamViewController.swift +++ b/Beam/UI/Subreddits/Subreddit View/SubredditStreamViewController.swift @@ -55,6 +55,8 @@ class SubredditStreamViewController: BeamViewController, SubredditTabItemViewCon subredditName = "Frontpage" } else if self.subreddit?.identifier == Subreddit.allIdentifier { subredditName = "All" + } else if self.subreddit?.identifier == Subreddit.popularIdentifier { + subredditName = "Popular" } else { } diff --git a/Beam/UI/Subscriptions/SubredditPreviewView.swift b/Beam/UI/Subscriptions/SubredditPreviewView.swift index 773e034..038500a 100644 --- a/Beam/UI/Subscriptions/SubredditPreviewView.swift +++ b/Beam/UI/Subscriptions/SubredditPreviewView.swift @@ -21,6 +21,8 @@ final class SubredditPreviewView: BeamView { } if self.subreddit?.identifier == Subreddit.frontpageIdentifier { self.imageView.image = #imageLiteral(resourceName: "subreddit_icon_frontpage") + } else if self.subreddit?.identifier == Subreddit.popularIdentifier { + self.imageView.image = #imageLiteral(resourceName: "subreddit_icon_popular") } else if self.subreddit?.identifier == Subreddit.allIdentifier { self.imageView.image = #imageLiteral(resourceName: "subreddit_icon_all") } else { diff --git a/Beam/UI/Subscriptions/SubredditTableViewCell.swift b/Beam/UI/Subscriptions/SubredditTableViewCell.swift index 9a7ff28..bc42098 100644 --- a/Beam/UI/Subscriptions/SubredditTableViewCell.swift +++ b/Beam/UI/Subscriptions/SubredditTableViewCell.swift @@ -88,7 +88,7 @@ final class SubredditTableViewCell: BeamTableViewCell { guard self.allowPromimentDisplay else { return false } - return self.subreddit?.isBookmarked.boolValue == true || self.subreddit?.identifier == Subreddit.frontpageIdentifier || self.subreddit?.identifier == Subreddit.allIdentifier || self.subreddit is Multireddit + return self.subreddit?.isBookmarked.boolValue == true || self.subreddit?.identifier == Subreddit.frontpageIdentifier || self.subreddit?.identifier == Subreddit.allIdentifier || self.subreddit?.identifier == Subreddit.popularIdentifier || self.subreddit is Multireddit } private var starButtonEnabled: Bool { @@ -126,6 +126,8 @@ final class SubredditTableViewCell: BeamTableViewCell { self.subtitleLabel.text = "\(multireddit.subreddits?.count ?? 0) subreddits" } else if self.subreddit?.identifier == Subreddit.frontpageIdentifier { self.subtitleLabel.text = AWKLocalizedString("frontpage-description") + } else if self.subreddit?.identifier == Subreddit.popularIdentifier { + self.subtitleLabel.text = AWKLocalizedString("popular-description") } else if self.subreddit?.identifier == Subreddit.allIdentifier { self.subtitleLabel.text = AWKLocalizedString("all-description") } else { diff --git a/Snoo/Collection Controller/Queries/SubredditsCollectionQuery.swift b/Snoo/Collection Controller/Queries/SubredditsCollectionQuery.swift index 08e9992..ecc99fd 100644 --- a/Snoo/Collection Controller/Queries/SubredditsCollectionQuery.swift +++ b/Snoo/Collection Controller/Queries/SubredditsCollectionQuery.swift @@ -69,10 +69,10 @@ public final class SubredditsCollectionQuery: CollectionQuery { } let frontpage = try Subreddit.frontpageSubreddit() - + let popular = try Subreddit.popularSubreddit() let all = try Subreddit.allSubreddit() - return try super.prepopulate(context) + [frontpage, all] + return try super.prepopulate(context) + [frontpage, popular, all] } override func contentPredicates() -> [NSPredicate] { diff --git a/Snoo/Core Data/Subreddit.swift b/Snoo/Core Data/Subreddit.swift index 7558a49..62dd6cf 100644 --- a/Snoo/Core Data/Subreddit.swift +++ b/Snoo/Core Data/Subreddit.swift @@ -65,6 +65,10 @@ open class Subreddit: SyncObject { open static var frontpageIdentifier: String { return "snoo-frontpage" } + + open static var popularIdentifier: String { + return "snoo-popular" + } open static var allIdentifier: String { return "snoo-all" @@ -72,7 +76,7 @@ open class Subreddit: SyncObject { open var isPrepopulated: Bool { if let identifier = self.identifier { - return [Subreddit.frontpageIdentifier, Subreddit.allIdentifier].contains(identifier) + return [Subreddit.frontpageIdentifier, Subreddit.allIdentifier, Subreddit.popularIdentifier].contains(identifier) } return false } @@ -95,7 +99,7 @@ open class Subreddit: SyncObject { if let submissionTypeString = self.submissionTypeString, let submissionType = SubredditSubmissionType(rawValue: submissionTypeString) { return submissionType } - if self.identifier == Subreddit.frontpageIdentifier || self.identifier == Subreddit.allIdentifier || self is Multireddit { + if self.identifier == Subreddit.frontpageIdentifier || self.identifier == Subreddit.allIdentifier || self.identifier == Subreddit.popularIdentifier || self is Multireddit { return SubredditSubmissionType.none } //In general subreddits you visit will allow both @@ -206,12 +210,48 @@ open class Subreddit: SyncObject { if let thrownError = thrownError { throw thrownError } - subreddit.title = NSLocalizedString("subreddit-frontpage", comment: "The title used for the frontpage secction on reddit. This is a collection of your subbreddits when logged in") - subreddit.displayName = NSLocalizedString("subreddit-frontpage", comment: "The title used for the frontpage secction on reddit. This is a collection of your subbreddits when logged in") + subreddit.title = NSLocalizedString("subreddit-frontpage", comment: "The title used for the frontpage section on reddit. This is a collection of your subbreddits when logged in") + subreddit.displayName = NSLocalizedString("subreddit-frontpage", comment: "The title used for the frontpage section on reddit. This is a collection of your subbreddits when logged in") subreddit.isBookmarked = NSNumber(value: true as Bool) return subreddit } + + //Returns the popular subreddit. If it doesn't already exist in the context it will be created. This method is always done on the DataController's private context! + open class func popularSubreddit() throws -> Subreddit { + let context: NSManagedObjectContext! = DataController.shared.privateContext + var subreddit: Subreddit! + var thrownError: Error? + context.performAndWait { + do { + if let existingSubreddit = try Subreddit.fetchObjectWithIdentifier(Subreddit.popularIdentifier, context: context) as? Subreddit { + //We already have a all subreddit, update it below + subreddit = existingSubreddit + } else { + //We don't already have a all subreddit, create it and update it below + subreddit = try Subreddit.objectWithIdentifier(Subreddit.popularIdentifier, cache: nil, context: context) as! Subreddit + subreddit.permalink = "/r/popular" + subreddit.sectionName = "" + if subreddit.objectID.isTemporaryID { + subreddit.order = NSNumber(value: 1 as Int) + } + + try context?.obtainPermanentIDs(for: [subreddit]) + } + } catch { + thrownError = error + } + + } + if let thrownError = thrownError { + throw thrownError + } + subreddit.title = NSLocalizedString("subreddit-popular", comment: "The title used for the popular section on reddit. This is a collection of popular subbreddits") + subreddit.displayName = NSLocalizedString("subreddit-popular", comment: "The title used for the popular section on reddit. This is a collection of popular subbreddits") + subreddit.isBookmarked = NSNumber(value: true as Bool) + + return subreddit + } //Returns the /r/all subreddit. If it doesn't already exist in the context it will be created. This method is always done on the DataController's private context! open class func allSubreddit() throws -> Subreddit { @@ -229,7 +269,7 @@ open class Subreddit: SyncObject { subreddit.permalink = "/r/all" subreddit.sectionName = "" if subreddit.objectID.isTemporaryID { - subreddit.order = NSNumber(value: 1 as Int) + subreddit.order = NSNumber(value: 2 as Int) } try context?.obtainPermanentIDs(for: [subreddit]) @@ -243,7 +283,7 @@ open class Subreddit: SyncObject { throw thrownError } subreddit.title = NSLocalizedString("subreddit-all", comment: "The title used for the all section on reddit. This is a collection of all subbreddits") - subreddit.displayName = NSLocalizedString("subreddit-all", comment: "The title used for the all scction on reddit. This is a collection of all subbreddits") + subreddit.displayName = NSLocalizedString("subreddit-all", comment: "The title used for the all section on reddit. This is a collection of all subbreddits") subreddit.isBookmarked = NSNumber(value: true as Bool) return subreddit diff --git a/Snoo/Data Operations/ClearUserRelationsOperation.swift b/Snoo/Data Operations/ClearUserRelationsOperation.swift index b0ab10c..5de9d60 100644 --- a/Snoo/Data Operations/ClearUserRelationsOperation.swift +++ b/Snoo/Data Operations/ClearUserRelationsOperation.swift @@ -58,7 +58,7 @@ final class ClearUserRelationsOperation: DataOperation { fileprivate func predicateForEntityName(_ name: String) -> NSPredicate? { if name == Subreddit.entityName() { - return NSPredicate(format: "NOT (identifier IN %@)", [Subreddit.frontpageIdentifier, Subreddit.allIdentifier]) + return NSPredicate(format: "NOT (identifier IN %@)", [Subreddit.frontpageIdentifier, Subreddit.allIdentifier, Subreddit.popularIdentifier]) } return nil }