Skip to content

Commit

Permalink
Sidebar: Add recently visited section
Browse files Browse the repository at this point in the history
  • Loading branch information
Dimillian committed May 19, 2021
1 parent e95b365 commit a0758c4
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 21 deletions.
34 changes: 32 additions & 2 deletions Packages/Backend/Sources/Backend/User/LocalDataStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,34 @@ import Foundation
import SwiftUI

public class LocalDataStore: ObservableObject, PersistentDataStore {
public static let shared = LocalDataStore()

@Published public private(set) var favorites: [SubredditSmall] = [] {
didSet {
persistData(data: SavedData(favorites: favorites))
saveData()
}
}

@Published public private(set) var recentlyVisited: [SubredditSmall] = [] {
didSet {
saveData()
}
}

let persistedDataFilename = "redditOsData"
typealias DataType = SavedData

struct SavedData: Codable {
let favorites: [SubredditSmall]
let recentlyVisited: [SubredditSmall]?
}

public init() {
var favorites = restorePersistedData()?.favorites ?? []
let data = restorePersistedData()
var favorites = data?.favorites ?? []
favorites.sort{ $0.name.lowercased() < $1.name.lowercased() }
self.favorites = favorites
self.recentlyVisited = data?.recentlyVisited ?? []
}

// MARK: - Favorites management
Expand All @@ -27,11 +39,29 @@ public class LocalDataStore: ObservableObject, PersistentDataStore {
}
}

public func add(recent: SubredditSmall) {
guard !recentlyVisited.contains(recent) else {
return
}
var edit = recentlyVisited
edit.insert(recent, at: 0)
if edit.count > 5 {
edit.removeLast()
}
recentlyVisited = edit
}

public func remove(favorite: SubredditSmall) {
favorites.removeAll(where: { $0 == favorite })
}

public func remove(favoriteNamed: String) {
favorites.removeAll(where: { $0.name == favoriteNamed })
}

// MARK: - Private

private func saveData() {
persistData(data: SavedData(favorites: favorites, recentlyVisited: recentlyVisited))
}
}
13 changes: 4 additions & 9 deletions RedditOs/Environements/UIState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,7 @@ class UIState: ObservableObject {
enum Constants {
static let searchTag = "search"
}

init() {
isSearchActive = .constant(false)
isSearchActive = .init(get: {
self.sidebarSelection == Constants.searchTag
}, set: { _ in })
}


@Published var displayToolbarSearchBar = true

@Published var selectedSubreddit: SubredditViewModel?
Expand All @@ -51,7 +44,9 @@ class UIState: ObservableObject {
}
}

var isSearchActive: Binding<Bool>
lazy var isSearchActive: Binding<Bool> = .init(get: {
self.sidebarSelection == Constants.searchTag
}, set: { _ in })

@Published var sidebarSelection: String? = DefaultChannels.hot.rawValue {
didSet {
Expand Down
4 changes: 3 additions & 1 deletion RedditOs/Features/Sidebar/SidebarItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation
import SwiftUI

enum SidebarItem: String, CaseIterable, Identifiable, Equatable {
case home, account, favorites, subscription, multi
case home, account, recentlyVisited, favorites, subscription, multi

var id: String {
rawValue
Expand All @@ -23,6 +23,8 @@ enum SidebarItem: String, CaseIterable, Identifiable, Equatable {
return "Account"
case .favorites:
return "Favorites"
case .recentlyVisited:
return "Recently Visited"
case .subscription:
return "Subscriptions"
case .multi:
Expand Down
13 changes: 10 additions & 3 deletions RedditOs/Features/Sidebar/SidebarView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ struct SidebarView: View {
@EnvironmentObject private var uiState: UIState
@EnvironmentObject private var localData: LocalDataStore
@EnvironmentObject private var currentUser: CurrentUserStore

@AppStorage(SettingsKey.sidebar_enabled_section) var enabledSections = SidebarItem.allCases.map{ $0.rawValue }


@State private var isSearchPopoverPresented = false
@State private var isHovered = false
@State private var isInEditMode = false
Expand All @@ -27,6 +25,7 @@ struct SidebarView: View {
List(selection: $uiState.sidebarSelection) {
mainSection
accountSection
recentlyVisitedSection
favoritesSection
subscriptionSection
multiSection
Expand Down Expand Up @@ -150,6 +149,14 @@ struct SidebarView: View {
.animation(.easeInOut)
}

private var recentlyVisitedSection: some View {
Section(header: Text(SidebarItem.recentlyVisited.title())) {
ForEach(localData.recentlyVisited) { reddit in
SidebarSubredditRow(name: reddit.name, iconURL: reddit.iconImg)
}
}
}

@ViewBuilder
private var subscriptionSection: some View {
if currentUser.user != nil, (!currentUser.subscriptions.isEmpty || currentUser.isRefreshingSubscriptions) {
Expand Down
13 changes: 8 additions & 5 deletions RedditOs/Features/Subreddit/SubredditViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ class SubredditViewModel: ObservableObject {
fetchListings(after: nil)
}
}
@Published var errorLoadingAbout = false

private var postsSearchPublisher: AnyPublisher<ListingResponse<SubredditPost>, Never>?
private var cancellableSet: Set<AnyCancellable> = Set()

init(name: String) {
private let localData: LocalDataStore

init(name: String, localData: LocalDataStore = .shared) {
self.name = name
self.localData = localData

$searchText
.subscribe(on: DispatchQueue.global())
Expand All @@ -58,9 +60,10 @@ class SubredditViewModel: ObservableObject {
func fetchAbout() {
Subreddit.fetchAbout(name: name)
.receive(on: DispatchQueue.main)
.sink { [weak self] holder in
self?.errorLoadingAbout = holder == nil
self?.subreddit = holder?.data
.compactMap{ $0?.data }
.sink { [weak self] subreddit in
self?.subreddit = subreddit
self?.localData.add(recent: SubredditSmall.makeSubredditSmall(with: subreddit))
}
.store(in: &cancellableSet)
}
Expand Down
2 changes: 1 addition & 1 deletion RedditOs/RedditOsApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Backend
@main
struct RedditOsApp: App {
@StateObject private var uiState = UIState()
@StateObject private var localData = LocalDataStore()
@StateObject private var localData = LocalDataStore.shared
private let searchText = QuickSearchState()

@SceneBuilder
Expand Down

0 comments on commit a0758c4

Please sign in to comment.