mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Merge branch 'swiftui' of https://github.com/stuartbreckenridge/NetNewsWire into swiftui
This commit is contained in:
@@ -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) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// CompactNavigationView.swift
|
||||
// CompactSidebarContainerView.swift
|
||||
// Multiplatform iOS
|
||||
//
|
||||
// Created by Stuart Breckenridge on 29/6/20.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// SidebarView.swift
|
||||
// RegularSidebarContainerView.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 6/28/20.
|
||||
|
||||
48
Multiplatform/Shared/Sidebar/SidebarExpandedContainers.swift
Normal file
48
Multiplatform/Shared/Sidebar/SidebarExpandedContainers.swift
Normal 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()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
34
Multiplatform/Shared/Timeline/TimelineContainerView.swift
Normal file
34
Multiplatform/Shared/Timeline/TimelineContainerView.swift
Normal 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())
|
||||
}
|
||||
}
|
||||
17
Multiplatform/Shared/Timeline/TimelineItem.swift
Normal file
17
Multiplatform/Shared/Timeline/TimelineItem.swift
Normal 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
|
||||
|
||||
|
||||
}
|
||||
38
Multiplatform/Shared/Timeline/TimelineModel.swift
Normal file
38
Multiplatform/Shared/Timeline/TimelineModel.swift
Normal 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 {
|
||||
|
||||
|
||||
}
|
||||
21
Multiplatform/Shared/Timeline/TimelineView.swift
Normal file
21
Multiplatform/Shared/Timeline/TimelineView.swift
Normal 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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user