This commit is contained in:
Stuart Breckenridge
2020-07-01 09:52:59 +08:00
11 changed files with 269 additions and 35 deletions

View File

@@ -12,6 +12,7 @@ import Account
final class SceneModel: ObservableObject {
var sidebarModel: SidebarModel?
var timelineModel: TimelineModel?
}
@@ -29,3 +30,12 @@ extension SceneModel: SidebarModelDelegate {
}
}
// MARK: TimelineModelDelegate
extension SceneModel: TimelineModelDelegate {
func timelineRequestedWebFeedSelection(_: TimelineModel, webFeed: WebFeed) {
}
}

View File

@@ -1,5 +1,5 @@
//
// CompactNavigationView.swift
// CompactSidebarContainerView.swift
// Multiplatform iOS
//
// Created by Stuart Breckenridge on 29/6/20.

View File

@@ -1,5 +1,5 @@
//
// SidebarView.swift
// RegularSidebarContainerView.swift
// NetNewsWire
//
// Created by Maurice Parker on 6/28/20.

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,46 @@
//
import SwiftUI
import Account
struct SidebarView: View {
// I had to comment out SceneStorage because it blows up if used on macOS
// @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

@@ -0,0 +1,34 @@
//
// TimelineContainerView.swift
// NetNewsWire
//
// Created by Maurice Parker on 6/30/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import SwiftUI
struct TimelineContainerView: View {
@EnvironmentObject private var sceneModel: SceneModel
@StateObject private var timelineModel = TimelineModel()
@ViewBuilder var body: some View {
TimelineView()
.environmentObject(timelineModel)
.listStyle(SidebarListStyle())
.onAppear {
sceneModel.timelineModel = timelineModel
timelineModel.delegate = sceneModel
timelineModel.rebuildTimelineItems()
}
}
}
struct TimelineContainerView_Previews: PreviewProvider {
static var previews: some View {
TimelineContainerView()
.environmentObject(SceneModel())
}
}

View File

@@ -0,0 +1,17 @@
//
// TimelineItem.swift
// NetNewsWire
//
// Created by Maurice Parker on 6/30/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import SwiftUI
import Articles
struct TimelineItem: Identifiable {
var id: String
}

View File

@@ -0,0 +1,38 @@
//
// TimelineModel.swift
// NetNewsWire
//
// Created by Maurice Parker on 6/30/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import Foundation
import RSCore
import Account
protocol TimelineModelDelegate: class {
func timelineRequestedWebFeedSelection(_: TimelineModel, webFeed: WebFeed)
}
class TimelineModel: ObservableObject {
weak var delegate: TimelineModelDelegate?
@Published var timelineItems = [TimelineItem]()
init() {
}
// MARK: API
func rebuildTimelineItems() {
}
}
// MARK: Private
private extension TimelineModel {
}

View File

@@ -0,0 +1,21 @@
//
// TimelineView.swift
// NetNewsWire
//
// Created by Maurice Parker on 6/30/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import SwiftUI
struct TimelineView: View {
var body: some View {
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
}
}
struct TimelineView_Previews: PreviewProvider {
static var previews: some View {
TimelineView()
}
}