Implement scene specific storage for Sidebar expanded state

This commit is contained in:
Maurice Parker 2020-06-30 20:23:22 -05:00
parent e593f67429
commit 53a26f89fe
4 changed files with 94 additions and 13 deletions

View File

@ -0,0 +1,48 @@
//
// SidebarExpandedContainers.swift
// NetNewsWire
//
// Created by Maurice Parker on 6/30/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import SwiftUI
import Combine
import Account
final class SidebarExpandedContainers: ObservableObject {
@Published var expandedTable = Set<ContainerIdentifier>()
var objectDidChange = PassthroughSubject<Void, Never>()
var data: Data {
get {
let encoder = PropertyListEncoder()
encoder.outputFormat = .binary
return (try? encoder.encode(expandedTable)) ?? Data()
}
set {
let decoder = PropertyListDecoder()
expandedTable = (try? decoder.decode(Set<ContainerIdentifier>.self, from: newValue)) ?? Set<ContainerIdentifier>()
}
}
subscript(_ containerID: ContainerIdentifier) -> Bool {
get {
if expandedTable.contains(containerID) {
return true
} else {
return false
}
}
set(newValue) {
if newValue {
expandedTable.insert(containerID)
} else {
expandedTable.remove(containerID)
}
objectDidChange.send()
}
}
}

View File

@ -24,7 +24,7 @@ struct SidebarItem: Identifiable {
var id: SidebarItemIdentifier
var represented: Any
var children: [SidebarItem]?
var children: [SidebarItem] = [SidebarItem]()
var unreadCount: Int
@ -37,6 +37,10 @@ struct SidebarItem: Identifiable {
represented as? Feed
}
var containerID: ContainerIdentifier? {
return (represented as? ContainerIdentifiable)?.containerID
}
var representedType: RepresentedType {
switch type(of: represented) {
case is SmartFeed.Type:
@ -55,14 +59,12 @@ struct SidebarItem: Identifiable {
init(_ smartFeedsController: SmartFeedsController) {
self.id = .smartFeedController
self.represented = smartFeedsController
self.children = [SidebarItem]()
self.unreadCount = 0
}
init(_ account: Account) {
self.id = .account(account.accountID)
self.represented = account
self.children = [SidebarItem]()
self.unreadCount = account.unreadCount
}
@ -70,13 +72,10 @@ struct SidebarItem: Identifiable {
self.id = .feed(feed.feedID!)
self.represented = feed
self.unreadCount = unreadCount
if let container = feed as? Container, container.hasAtLeastOneWebFeed() {
self.children = [SidebarItem]()
}
}
mutating func addChild(_ sidebarItem: SidebarItem) {
children?.append(sidebarItem)
children.append(sidebarItem)
}
}

View File

@ -7,17 +7,45 @@
//
import SwiftUI
import Account
struct SidebarView: View {
@SceneStorage("expandedContainers") private var expandedContainerData = Data()
@StateObject private var expandedContainers = SidebarExpandedContainers()
@EnvironmentObject private var sidebarModel: SidebarModel
// @State private var selected = Set<FeedIdentifier>()
var body: some View {
List {
OutlineGroup(sidebarModel.sidebarItems, children: \.children) { sidebarItem in
SidebarItemView(sidebarItem: sidebarItem)
List() {
ForEach(sidebarModel.sidebarItems) { sidebarItem in
if let containerID = sidebarItem.containerID {
DisclosureGroup(isExpanded: $expandedContainers[containerID]) {
ForEach(sidebarItem.children) { sidebarItem in
if let containerID = sidebarItem.containerID {
DisclosureGroup(isExpanded: $expandedContainers[containerID]) {
ForEach(sidebarItem.children) { sidebarItem in
SidebarItemView(sidebarItem: sidebarItem)
}
} label: {
SidebarItemView(sidebarItem: sidebarItem)
}
} else {
SidebarItemView(sidebarItem: sidebarItem)
}
}
} label: {
SidebarItemView(sidebarItem: sidebarItem)
}
}
}
}
.onAppear {
expandedContainers.data = expandedContainerData
}
.onReceive(expandedContainers.objectDidChange) {
expandedContainerData = expandedContainers.data
}
}
}

View File

@ -108,6 +108,8 @@
51333D1724685D2E00EB5C91 /* AddRedditFeedWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51333D1524685D2E00EB5C91 /* AddRedditFeedWindowController.swift */; };
51333D3B2468615D00EB5C91 /* AddRedditFeedSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = 51333D392468615D00EB5C91 /* AddRedditFeedSheet.xib */; };
51333D3C2468615D00EB5C91 /* AddRedditFeedSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = 51333D392468615D00EB5C91 /* AddRedditFeedSheet.xib */; };
51392D1B24AC19A000BE0D35 /* SidebarExpandedContainers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51392D1A24AC19A000BE0D35 /* SidebarExpandedContainers.swift */; };
51392D1C24AC19A000BE0D35 /* SidebarExpandedContainers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51392D1A24AC19A000BE0D35 /* SidebarExpandedContainers.swift */; };
513C5CE9232571C2003D4054 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513C5CE8232571C2003D4054 /* ShareViewController.swift */; };
513C5CEC232571C2003D4054 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 513C5CEA232571C2003D4054 /* MainInterface.storyboard */; };
513C5CF0232571C2003D4054 /* NetNewsWire iOS Share Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 513C5CE6232571C2003D4054 /* NetNewsWire iOS Share Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
@ -1752,6 +1754,7 @@
513228F2233037620033D4ED /* Reachability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reachability.swift; sourceTree = "<group>"; };
51333D1524685D2E00EB5C91 /* AddRedditFeedWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRedditFeedWindowController.swift; sourceTree = "<group>"; };
51333D3A2468615D00EB5C91 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Mac/Base.lproj/AddRedditFeedSheet.xib; sourceTree = SOURCE_ROOT; };
51392D1A24AC19A000BE0D35 /* SidebarExpandedContainers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarExpandedContainers.swift; sourceTree = "<group>"; };
513C5CE6232571C2003D4054 /* NetNewsWire iOS Share Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "NetNewsWire iOS Share Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
513C5CE8232571C2003D4054 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
513C5CEB232571C2003D4054 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
@ -2872,12 +2875,13 @@
children = (
172952AF24AA287100D65E66 /* CompactSidebarContainerView.swift */,
51E499FF24A91FC100B667CB /* RegularSidebarContainerView.swift */,
172199F024AB716900A31D04 /* SidebarToolbar.swift */,
51392D1A24AC19A000BE0D35 /* SidebarExpandedContainers.swift */,
51408B7D24A9EC6F0073CF4E /* SidebarItem.swift */,
51919FAE24AA8EFA00541E64 /* SidebarItemView.swift */,
51E499FC24A9137600B667CB /* SidebarModel.swift */,
172199F024AB716900A31D04 /* SidebarToolbar.swift */,
51919FA524AA64B000541E64 /* SidebarView.swift */,
51919FAB24AA8CCA00541E64 /* UnreadCountView.swift */,
51919FAE24AA8EFA00541E64 /* SidebarItemView.swift */,
);
path = Sidebar;
sourceTree = "<group>";
@ -4711,6 +4715,7 @@
buildActionMask = 2147483647;
files = (
51E4995924A873F900B667CB /* ErrorHandler.swift in Sources */,
51392D1B24AC19A000BE0D35 /* SidebarExpandedContainers.swift in Sources */,
51E4992F24A8676400B667CB /* ArticleArray.swift in Sources */,
51E4994424A8713C00B667CB /* RefreshInterval.swift in Sources */,
51E498F824A8085D00B667CB /* UnreadFeed.swift in Sources */,
@ -4870,6 +4875,7 @@
51E4991824A8090A00B667CB /* CacheCleaner.swift in Sources */,
51E498CD24A8085D00B667CB /* SearchTimelineFeedDelegate.swift in Sources */,
51E4996124A875F400B667CB /* ArticleRenderer.swift in Sources */,
51392D1C24AC19A000BE0D35 /* SidebarExpandedContainers.swift in Sources */,
51C0515F24A77DF800194D5E /* MainApp.swift in Sources */,
1729529524AA1CAA00D65E66 /* GeneralPreferencesView.swift in Sources */,
1729529424AA1CAA00D65E66 /* AdvancedPreferencesView.swift in Sources */,