Skip to content

Commit

Permalink
fix: Show file counts on inbox rows (#433)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbmorley authored Nov 15, 2022
1 parent 4e19cbb commit e680351
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,36 @@ import SwiftUI

extension Array where Element: Identifiable {

mutating func move(ids: [Element.ID], toOffset offset: Int) {
public mutating func move(ids: [Element.ID], toOffset offset: Int) {
let indexes = ids.compactMap { id in
return firstIndex(where: { $0.id == id })
}
move(fromOffsets: IndexSet(indexes), toOffset: offset)
}

public func applying(_ other: [Element], onInsert: (Element) -> Void, onRemove: (Element) -> Void) -> [Element] {

let enumeratedIds = enumerated().reduce(into: [Element.ID: Int]()) {
$0[$1.1.id] = $1.0
}
var result: [Element] = []
for element in other {
if let current = enumeratedIds[element.id] {
result.append(self[current])
} else {
result.append(element)
onInsert(element)
}
}
let ids = Set(self.map { $0.id })
let otherIds = Set(other.map { $0.id })
let removals = ids.subtracting(otherIds)
for removal in removals {
let index = enumeratedIds[removal]!
onRemove(self[index])
}

return result
}

}
9 changes: 9 additions & 0 deletions core/Sources/FileawayCore/Model/DirectoryViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ public class DirectoryViewModel: ObservableObject, Identifiable, Runnable {
return directoryModel?.type ?? .inbox
}

public var systemImage: String {
switch type {
case .inbox:
return "tray"
case .archive:
return "archivebox"
}
}

public var url: URL {
return directoryModel?.url ?? URL(string: "foo:unknown")!
}
Expand Down
19 changes: 16 additions & 3 deletions core/Sources/FileawayCore/Model/SceneModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,22 @@ public class SceneModel: ObservableObject, Runnable {
}
}
.receive(on: DispatchQueue.main)
.sink { models in
self.inboxes = models.filter { $0.type == .inbox }
self.archives = models.filter { $0.type == .archive }
.sink { (models: [DirectoryViewModel]) in

let newInboxes = models.filter { $0.type == .inbox }
self.inboxes = self.inboxes.applying(newInboxes) { directoryViewModel in
directoryViewModel.start()
} onRemove: { directoryViewModel in
directoryViewModel.stop()
}

let newArchives = models.filter { $0.type == .archive }
self.archives = self.archives.applying(newArchives) { directoryViewModel in
directoryViewModel.start()
} onRemove: { directoryViewModel in
directoryViewModel.stop()
}

}
.store(in: &cancelables)

Expand Down
1 change: 0 additions & 1 deletion core/Sources/FileawayCore/Views/Viewer/DirectoryView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ public struct DirectoryView: View {
.navigationTitle(directoryViewModel.name)
.quickLookPreview($directoryViewModel.previewUrl, in: directoryViewModel.previewUrls)
.focusedValue(\.directoryViewModel, directoryViewModel)
.runs(directoryViewModel)
.id(directoryViewModel.url)
}

Expand Down
49 changes: 49 additions & 0 deletions core/Sources/FileawayCore/Views/Viewer/LocationRow.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) 2018-2022 InSeven Limited
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

import SwiftUI

import FilePicker

struct LocationRow: View {

@Environment(\.applicationModel) private var applicationModel
@ObservedObject var directoryViewModel: DirectoryViewModel

var body: some View {
NavigationLink(value: directoryViewModel.url) {
Label(directoryViewModel.name, systemImage: directoryViewModel.systemImage)
.badge(directoryViewModel.type == .inbox ? directoryViewModel.files.count : 0)
}
.contextMenu {
LocationMenuItems(url: directoryViewModel.url)
}
.swipeActions(edge: .trailing) {
Button(role: .destructive) {
// TODO: Handle the error here!
try! applicationModel.removeLocation(url: directoryViewModel.url)
} label: {
Text("Remove")
}
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import SwiftUI

import FilePicker

public struct SidebarSection: View {
public struct LocationSection: View {

@Environment(\.applicationModel) private var applicationModel

Expand All @@ -34,7 +34,6 @@ public struct SidebarSection: View {

private var title: String
private var type: DirectoryModel.DirectoryType
private var systemImage: String

// TODO: This is nasty
public var models: [DirectoryViewModel] {
Expand All @@ -46,30 +45,16 @@ public struct SidebarSection: View {
}
}

public init(sceneModel: SceneModel, title: String, type: DirectoryModel.DirectoryType, systemImage: String) {
public init(sceneModel: SceneModel, title: String, type: DirectoryModel.DirectoryType) {
self.sceneModel = sceneModel
self.title = title
self.type = type
self.systemImage = systemImage
}

public var body: some View {
Section(title) {
ForEach(models) { inbox in
NavigationLink(value: inbox.url) {
Label(inbox.name, systemImage: systemImage)
}
.contextMenu {
LocationMenuItems(url: inbox.url)
}
.swipeActions(edge: .trailing) {
Button(role: .destructive) {
// TODO: Handle the error here!
try! applicationModel.removeLocation(url: inbox.url)
} label: {
Text("Remove")
}
}
ForEach(models) { directoryViewModel in
LocationRow(directoryViewModel: directoryViewModel)
}
.onDelete { indexSet in
let urls = indexSet.map { models[$0].url }
Expand Down
4 changes: 2 additions & 2 deletions core/Sources/FileawayCore/Views/Viewer/Sidebar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public struct Sidebar: View {

public var body: some View {
List(selection: $sceneModel.section) {
SidebarSection(sceneModel: sceneModel, title: "Inboxes", type: .inbox, systemImage: "tray")
SidebarSection(sceneModel: sceneModel, title: "Archives", type: .archive, systemImage: "archivebox")
LocationSection(sceneModel: sceneModel, title: "Inboxes", type: .inbox)
LocationSection(sceneModel: sceneModel, title: "Archives", type: .archive)
}
.headerProminence(.increased)
#if os(iOS)
Expand Down
4 changes: 0 additions & 4 deletions macos/Fileaway-macOS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
D8F252522923BF5B00CC30AF /* NSItemProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F252512923BF5B00CC30AF /* NSItemProvider.swift */; };
D8F252562923BFA700CC30AF /* DynamicTableRowContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F252552923BFA700CC30AF /* DynamicTableRowContent.swift */; };
D8F252582923BFF600CC30AF /* TableRowContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F252572923BFF600CC30AF /* TableRowContent.swift */; };
D8F2525A2923C3CA00CC30AF /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F252592923C3CA00CC30AF /* Array.swift */; };
D8F2525C2923C6FA00CC30AF /* VariableTypePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F2525B2923C6FA00CC30AF /* VariableTypePicker.swift */; };
D8F8BE0C2588179E0010432F /* CloseKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F8BE0B2588179E0010432F /* CloseKey.swift */; };
D8F8BE12258818450010432F /* WizardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F8BE11258818450010432F /* WizardView.swift */; };
Expand Down Expand Up @@ -100,7 +99,6 @@
D8F252512923BF5B00CC30AF /* NSItemProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSItemProvider.swift; sourceTree = "<group>"; };
D8F252552923BFA700CC30AF /* DynamicTableRowContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicTableRowContent.swift; sourceTree = "<group>"; };
D8F252572923BFF600CC30AF /* TableRowContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableRowContent.swift; sourceTree = "<group>"; };
D8F252592923C3CA00CC30AF /* Array.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Array.swift; sourceTree = "<group>"; };
D8F2525B2923C6FA00CC30AF /* VariableTypePicker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VariableTypePicker.swift; sourceTree = "<group>"; };
D8F8BE0B2588179E0010432F /* CloseKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloseKey.swift; sourceTree = "<group>"; };
D8F8BE11258818450010432F /* WizardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WizardView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -293,7 +291,6 @@
D8F252502923BF4B00CC30AF /* Extensions */ = {
isa = PBXGroup;
children = (
D8F252592923C3CA00CC30AF /* Array.swift */,
D8F252552923BFA700CC30AF /* DynamicTableRowContent.swift */,
D8F252512923BF5B00CC30AF /* NSItemProvider.swift */,
D8F252572923BFF600CC30AF /* TableRowContent.swift */,
Expand Down Expand Up @@ -487,7 +484,6 @@
D82D73D728B4C659006F49F1 /* Wizard.swift in Sources */,
D8C4CC452920FBD80038B06E /* ShowsStackNavigationBar.swift in Sources */,
D8F252562923BFA700CC30AF /* DynamicTableRowContent.swift in Sources */,
D8F2525A2923C3CA00CC30AF /* Array.swift in Sources */,
D8FC534A257BB7A4008FB609 /* LocationsSettingsView.swift in Sources */,
D8D78A922580DD750088890F /* QuickLookPreview.swift in Sources */,
D8F8BE0C2588179E0010432F /* CloseKey.swift in Sources */,
Expand Down

0 comments on commit e680351

Please sign in to comment.