From 53a26f89fe578430239e6ec95116f3e251964109 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Tue, 30 Jun 2020 20:23:22 -0500 Subject: [PATCH] Implement scene specific storage for Sidebar expanded state --- .../Sidebar/SidebarExpandedContainers.swift | 48 +++++++++++++++++++ .../Shared/Sidebar/SidebarItem.swift | 13 +++-- .../Shared/Sidebar/SidebarView.swift | 36 ++++++++++++-- NetNewsWire.xcodeproj/project.pbxproj | 10 +++- 4 files changed, 94 insertions(+), 13 deletions(-) create mode 100644 Multiplatform/Shared/Sidebar/SidebarExpandedContainers.swift diff --git a/Multiplatform/Shared/Sidebar/SidebarExpandedContainers.swift b/Multiplatform/Shared/Sidebar/SidebarExpandedContainers.swift new file mode 100644 index 000000000..190135cde --- /dev/null +++ b/Multiplatform/Shared/Sidebar/SidebarExpandedContainers.swift @@ -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() + var objectDidChange = PassthroughSubject() + + 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.self, from: newValue)) ?? Set() + } + } + + 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() + } + } + +} diff --git a/Multiplatform/Shared/Sidebar/SidebarItem.swift b/Multiplatform/Shared/Sidebar/SidebarItem.swift index 796008552..fbeea8841 100644 --- a/Multiplatform/Shared/Sidebar/SidebarItem.swift +++ b/Multiplatform/Shared/Sidebar/SidebarItem.swift @@ -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) } } diff --git a/Multiplatform/Shared/Sidebar/SidebarView.swift b/Multiplatform/Shared/Sidebar/SidebarView.swift index 71a5bd083..5497a18d5 100644 --- a/Multiplatform/Shared/Sidebar/SidebarView.swift +++ b/Multiplatform/Shared/Sidebar/SidebarView.swift @@ -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() + 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 + } } - } diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 2852381f1..b71450964 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -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 = ""; }; 51333D1524685D2E00EB5C91 /* AddRedditFeedWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRedditFeedWindowController.swift; sourceTree = ""; }; 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 = ""; }; 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 = ""; }; 513C5CEB232571C2003D4054 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; @@ -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 = ""; @@ -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 */,