Skip to content

Commit

Permalink
Add a Welcome View
Browse files Browse the repository at this point in the history
  • Loading branch information
Desbeers committed Aug 26, 2023
1 parent 4721efd commit ec230de
Show file tree
Hide file tree
Showing 14 changed files with 459 additions and 115 deletions.
39 changes: 34 additions & 5 deletions Chord Provider.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
/* Begin PBXBuildFile section */
D7A9B7C12A93BE5E007FD0A3 /* SwiftlyChordUtilities in Frameworks */ = {isa = PBXBuildFile; productRef = D7A9B7C02A93BE5E007FD0A3 /* SwiftlyChordUtilities */; };
D7A9B7C32A93BE8C007FD0A3 /* SwiftlyChordUtilities in Frameworks */ = {isa = PBXBuildFile; productRef = D7A9B7C22A93BE8C007FD0A3 /* SwiftlyChordUtilities */; };
D7AB1E812A98C284009BC9FB /* DocumentKit in Frameworks */ = {isa = PBXBuildFile; platformFilter = ios; productRef = D7AB1E802A98C284009BC9FB /* DocumentKit */; };
D7AB1E832A98E155009BC9FB /* OnboardingView (iPadOS).swift in Sources */ = {isa = PBXBuildFile; fileRef = D7AB1E822A98E155009BC9FB /* OnboardingView (iPadOS).swift */; platformFilter = ios; };
D7D39C4F2A9A13DA004EAE5F /* Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D39C4E2A9A13DA004EAE5F /* Status.swift */; };
D7D39C512A9A19A1004EAE5F /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D39C502A9A19A1004EAE5F /* WelcomeView.swift */; };
D7F13FBC2A6460B7002D875D /* Song+Section+Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F13F852A6460B7002D875D /* Song+Section+Line.swift */; };
D7F13FBD2A6460B7002D875D /* Song.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F13F862A6460B7002D875D /* Song.swift */; };
D7F13FBE2A6460B7002D875D /* Song+Chord.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F13F872A6460B7002D875D /* Song+Chord.swift */; };
Expand All @@ -20,7 +24,7 @@
D7F13FC42A6460B7002D875D /* ExportDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F13F8E2A6460B7002D875D /* ExportDocument.swift */; };
D7F13FC52A6460B7002D875D /* ExportSong.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F13F8F2A6460B7002D875D /* ExportSong.swift */; };
D7F13FC62A6460B7002D875D /* WindowManagement (macOS).swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F13F912A6460B7002D875D /* WindowManagement (macOS).swift */; platformFilters = (macos, ); };
D7F13FC72A6460B7002D875D /* FileBrowser (macOS).swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F13F922A6460B7002D875D /* FileBrowser (macOS).swift */; platformFilters = (macos, ); };
D7F13FC72A6460B7002D875D /* FileBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F13F922A6460B7002D875D /* FileBrowser.swift */; };
D7F13FC82A6460B7002D875D /* FileBrowserView (macOS).swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F13F942A6460B7002D875D /* FileBrowserView (macOS).swift */; platformFilters = (macos, ); };
D7F13FCB2A6460B7002D875D /* Credits.html in Resources */ = {isa = PBXBuildFile; fileRef = D7F13F992A6460B7002D875D /* Credits.html */; platformFilters = (macos, ); };
D7F13FCD2A6460B7002D875D /* ChordProviderApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F13F9C2A6460B7002D875D /* ChordProviderApp.swift */; };
Expand Down Expand Up @@ -50,7 +54,7 @@
D7F13FE62A6460B7002D875D /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F13FB92A6460B7002D875D /* ContentView.swift */; };
D7F13FE72A6460B7002D875D /* ExportSongView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F13FBA2A6460B7002D875D /* ExportSongView.swift */; };
D7F13FE82A6460B7002D875D /* AudioPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F13FBB2A6460B7002D875D /* AudioPlayerView.swift */; };
D7F13FEE2A646110002D875D /* SwiftlyFolderUtilities in Frameworks */ = {isa = PBXBuildFile; platformFilters = (macos, ); productRef = D7F13FED2A646110002D875D /* SwiftlyFolderUtilities */; };
D7F13FEE2A646110002D875D /* SwiftlyFolderUtilities in Frameworks */ = {isa = PBXBuildFile; productRef = D7F13FED2A646110002D875D /* SwiftlyFolderUtilities */; };
D7F13FF12A646129002D875D /* HighlightedTextEditor in Frameworks */ = {isa = PBXBuildFile; platformFilters = (ios, macos, ); productRef = D7F13FF02A646129002D875D /* HighlightedTextEditor */; };
D7F13FF92A646356002D875D /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D7F13FF82A646356002D875D /* Quartz.framework */; platformFilters = (macos, ); };
D7F140062A646356002D875D /* QLExtension (macOS).appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D7F13FF62A646356002D875D /* QLExtension (macOS).appex */; platformFilters = (macos, ); settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
Expand Down Expand Up @@ -94,6 +98,9 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
D7AB1E822A98E155009BC9FB /* OnboardingView (iPadOS).swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OnboardingView (iPadOS).swift"; sourceTree = "<group>"; };
D7D39C4E2A9A13DA004EAE5F /* Status.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Status.swift; sourceTree = "<group>"; };
D7D39C502A9A19A1004EAE5F /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = "<group>"; };
D7F13F6F2A645FEC002D875D /* Chord Provider.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Chord Provider.app"; sourceTree = BUILT_PRODUCTS_DIR; };
D7F13F7A2A645FED002D875D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D7F13F7B2A645FED002D875D /* ChordProvider.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ChordProvider.entitlements; sourceTree = "<group>"; };
Expand All @@ -108,7 +115,7 @@
D7F13F8E2A6460B7002D875D /* ExportDocument.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExportDocument.swift; sourceTree = "<group>"; };
D7F13F8F2A6460B7002D875D /* ExportSong.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExportSong.swift; sourceTree = "<group>"; };
D7F13F912A6460B7002D875D /* WindowManagement (macOS).swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "WindowManagement (macOS).swift"; sourceTree = "<group>"; };
D7F13F922A6460B7002D875D /* FileBrowser (macOS).swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FileBrowser (macOS).swift"; sourceTree = "<group>"; };
D7F13F922A6460B7002D875D /* FileBrowser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileBrowser.swift; sourceTree = "<group>"; };
D7F13F942A6460B7002D875D /* FileBrowserView (macOS).swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FileBrowserView (macOS).swift"; sourceTree = "<group>"; };
D7F13F962A6460B7002D875D /* QLExtension.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = QLExtension.entitlements; sourceTree = "<group>"; };
D7F13F972A6460B7002D875D /* PreviewProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreviewProvider.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -152,6 +159,7 @@
files = (
D7F13FEE2A646110002D875D /* SwiftlyFolderUtilities in Frameworks */,
D7F13FF12A646129002D875D /* HighlightedTextEditor in Frameworks */,
D7AB1E812A98C284009BC9FB /* DocumentKit in Frameworks */,
D7A9B7C12A93BE5E007FD0A3 /* SwiftlyChordUtilities in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -229,7 +237,6 @@
children = (
D7F13F952A6460B7002D875D /* QLExtension */,
D7F13F912A6460B7002D875D /* WindowManagement (macOS).swift */,
D7F13F922A6460B7002D875D /* FileBrowser (macOS).swift */,
D7F13F942A6460B7002D875D /* FileBrowserView (macOS).swift */,
D7F13F992A6460B7002D875D /* Credits.html */,
);
Expand All @@ -251,9 +258,11 @@
children = (
D7F13F9C2A6460B7002D875D /* ChordProviderApp.swift */,
D7F13F9F2A6460B7002D875D /* SceneState.swift */,
D7F13F922A6460B7002D875D /* FileBrowser.swift */,
D7F13F9D2A6460B7002D875D /* ChordProDocument.swift */,
D7F13FA02A6460B7002D875D /* Aliasses.swift */,
D7F13FA12A6460B7002D875D /* Debouncer.swift */,
D7D39C4E2A9A13DA004EAE5F /* Status.swift */,
D7F13F9E2A6460B7002D875D /* Assets.xcassets */,
D7F13F7A2A645FED002D875D /* Info.plist */,
D7F13F7B2A645FED002D875D /* ChordProvider.entitlements */,
Expand All @@ -277,6 +286,7 @@
isa = PBXGroup;
children = (
D7F13FA92A6460B7002D875D /* LaunchScreen (iPadOS).storyboard */,
D7AB1E822A98E155009BC9FB /* OnboardingView (iPadOS).swift */,
);
path = iPadOS;
sourceTree = "<group>";
Expand All @@ -295,6 +305,7 @@
D7F13FB62A6460B7002D875D /* PrintSongView.swift */,
D7F13FAC2A6460B7002D875D /* ShareSongView.swift */,
D7F13FBA2A6460B7002D875D /* ExportSongView.swift */,
D7D39C502A9A19A1004EAE5F /* WelcomeView.swift */,
);
path = Views;
sourceTree = "<group>";
Expand Down Expand Up @@ -343,6 +354,7 @@
D7F13FED2A646110002D875D /* SwiftlyFolderUtilities */,
D7F13FF02A646129002D875D /* HighlightedTextEditor */,
D7A9B7C02A93BE5E007FD0A3 /* SwiftlyChordUtilities */,
D7AB1E802A98C284009BC9FB /* DocumentKit */,
);
productName = "Chord Provider";
productReference = D7F13F6F2A645FEC002D875D /* Chord Provider.app */;
Expand Down Expand Up @@ -399,6 +411,7 @@
D7F13FEC2A646110002D875D /* XCRemoteSwiftPackageReference "SwiftlyFolderUtilities" */,
D7F13FEF2A646129002D875D /* XCRemoteSwiftPackageReference "HighlightedTextEditor" */,
D7A9B7BF2A93BE5E007FD0A3 /* XCRemoteSwiftPackageReference "SwiftlyChordUtilities" */,
D7AB1E7F2A98C283009BC9FB /* XCRemoteSwiftPackageReference "DocumentKit" */,
);
productRefGroup = D7F13F702A645FEC002D875D /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -487,6 +500,7 @@
D7F13FD72A6460B7002D875D /* ChordPro+Directive.swift in Sources */,
D7F13FC62A6460B7002D875D /* WindowManagement (macOS).swift in Sources */,
D7F13FDF2A6460B7002D875D /* EditorView.swift in Sources */,
D7D39C4F2A9A13DA004EAE5F /* Status.swift in Sources */,
D7F13FE62A6460B7002D875D /* ContentView.swift in Sources */,
D7F13FE32A6460B7002D875D /* PrintSongView.swift in Sources */,
D7F13FE72A6460B7002D875D /* ExportSongView.swift in Sources */,
Expand All @@ -500,11 +514,13 @@
D7F13FD02A6460B7002D875D /* SceneState.swift in Sources */,
D7F13FE82A6460B7002D875D /* AudioPlayerView.swift in Sources */,
D7F13FD32A6460B7002D875D /* ChordPro.swift in Sources */,
D7AB1E832A98E155009BC9FB /* OnboardingView (iPadOS).swift in Sources */,
D7F13FC02A6460B7002D875D /* Song+Section.swift in Sources */,
D7F13FC52A6460B7002D875D /* ExportSong.swift in Sources */,
D7F13FC72A6460B7002D875D /* FileBrowser (macOS).swift in Sources */,
D7F13FC72A6460B7002D875D /* FileBrowser.swift in Sources */,
D7F13FD12A6460B7002D875D /* Aliasses.swift in Sources */,
D7F13FDD2A6460B7002D875D /* EditorView+rules.swift in Sources */,
D7D39C512A9A19A1004EAE5F /* WelcomeView.swift in Sources */,
D7F13FE52A6460B7002D875D /* SongView.swift in Sources */,
D7F13FC32A6460B7002D875D /* ExportSong+render.swift in Sources */,
D7F13FCD2A6460B7002D875D /* ChordProviderApp.swift in Sources */,
Expand Down Expand Up @@ -855,6 +871,14 @@
kind = branch;
};
};
D7AB1E7F2A98C283009BC9FB /* XCRemoteSwiftPackageReference "DocumentKit" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/danielsaidi/DocumentKit.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.1.1;
};
};
D7F13FEC2A646110002D875D /* XCRemoteSwiftPackageReference "SwiftlyFolderUtilities" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/Desbeers/SwiftlyFolderUtilities";
Expand Down Expand Up @@ -884,6 +908,11 @@
package = D7A9B7BF2A93BE5E007FD0A3 /* XCRemoteSwiftPackageReference "SwiftlyChordUtilities" */;
productName = SwiftlyChordUtilities;
};
D7AB1E802A98C284009BC9FB /* DocumentKit */ = {
isa = XCSwiftPackageProductDependency;
package = D7AB1E7F2A98C283009BC9FB /* XCRemoteSwiftPackageReference "DocumentKit" */;
productName = DocumentKit;
};
D7F13FED2A646110002D875D /* SwiftlyFolderUtilities */ = {
isa = XCSwiftPackageProductDependency;
package = D7F13FEC2A646110002D875D /* XCRemoteSwiftPackageReference "SwiftlyFolderUtilities" */;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
{
"pins" : [
{
"identity" : "documentkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/danielsaidi/DocumentKit.git",
"state" : {
"revision" : "440d46690b7acab270d1b09b9653e0ab22087498",
"version" : "0.1.1"
}
},
{
"identity" : "highlightedtexteditor",
"kind" : "remoteSourceControl",
Expand All @@ -24,7 +33,7 @@
"location" : "https://github.com/Desbeers/SwiftlyFolderUtilities",
"state" : {
"branch" : "main",
"revision" : "80453733969d5650904928290ec02f2d3d65f934"
"revision" : "4a249ab028faaae49928d653a1799d561083fedc"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion Chord Provider/Export/ExportSong+render.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// ExportSong+render.swift
// Chord Provider
//
// Created by Nick Berendsen on 15/07/2023.
// © 2023 Nick Berendsen
//

import SwiftUI
Expand Down
26 changes: 23 additions & 3 deletions Chord Provider/General/ChordProviderApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,22 @@
//

import SwiftUI

import SwiftlyFolderUtilities
#if os(iOS)
import DocumentKit
#endif
/// SwiftUI `Scene` for Chord Provider
@main struct ChordProviderApp: App {

/// The ``FileBrowser``
@StateObject var fileBrowser: FileBrowser = .shared
/// The welcome view setting
@AppStorage("hideWelcome") var hideWelcome: Bool = true

#if os(macOS)

// MARK: macOS

/// The ``FileBrowser``
@StateObject var fileBrowser = FileBrowser()
/// AppKit app delegate
@NSApplicationDelegateAdaptor private var appDelegate: AppDelegate
/// The body of the `Scene`
Expand All @@ -39,6 +45,7 @@ import SwiftUI
/// The actual 'song' window
DocumentGroup(newDocument: ChordProDocument()) { file in
ContentView(document: file.$document, file: file.fileURL)
.environmentObject(fileBrowser)
/// Give the scene access to the document.
.focusedSceneValue(\.document, file.$document)
.onDisappear {
Expand Down Expand Up @@ -108,6 +115,18 @@ import SwiftUI
ContentView(document: file.$document, file: file.fileURL)
/// Give the scene access to the document.
.focusedSceneValue(\.document, file.$document)
.environmentObject(fileBrowser)
.task {
if hideWelcome == false {
UserDefaults.standard.resetDocumentGroupOnboardingState(for: "welcome")
}
}
}
.additionalNavigationBarButtonItems(
leading: [.onboarding]
)
.onboardingSheet(id: "welcome") {
OnboardingView()
}
}
#endif
Expand All @@ -119,6 +138,7 @@ import SwiftUI
var body: some Scene {
DocumentGroup(newDocument: ChordProDocument()) { file in
ContentView(document: file.$document, file: file.fileURL)
.environmentObject(fileBrowser)
/// Give the scene access to the document.
.focusedSceneValue(\.document, file.$document)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,30 @@ import SwiftlyFolderUtilities

/// The observable FileBrowser for Chord Provider
class FileBrowser: ObservableObject {

static let shared = FileBrowser()

/// The list of songs
@Published var songList: [SongItem] = []
/// The list of artists
@Published var artistList: [ArtistItem] = []
/// Bool if a folder is selected
@Published var folder: Bool = true
/// The name of the folder bookmark
static let bookmark: String = "SongsFolder"
/// The Class to monitor the songs folder
let folderMonitor = FolderMonitor()
/// The optional songs folder
@Published var songsFolder: URL?
/// The status
@Published var status: Status = .unknown
/// Init the FileBrowser
#if os(macOS)
/// The list of open windows
@Published var openWindows: [NSWindow.WindowItem] = []
/// The MenuBarExtra window
/// - Note: Needed to close the MenuBarExtra when selecting a song
var menuBarExtraWindow: NSWindow?
/// The Class to monitor the songs folder
let folderMonitor = FolderMonitor()
/// Init the FileBrowser
init() {
#endif
private init() {
folderMonitor.folderDidChange = {
Task {
await self.getFiles()
Expand Down Expand Up @@ -75,13 +82,14 @@ extension FileBrowser {
// MARK: Functions

/// Get the song files from the user selected folder
@MainActor
func getFiles() async {
@MainActor func getFiles() async {
do {
/// The found songs
var songs = [SongItem]()
/// Get a list of all files
try await FolderBookmark.action(bookmark: FileBrowser.bookmark) { persistentURL in
songsFolder = persistentURL
status = .ready
folderMonitor.addRecursiveURL(persistentURL)
if let items = FileManager.default.enumerator(at: persistentURL, includingPropertiesForKeys: nil) {
while let item = items.nextObject() as? URL {
Expand All @@ -92,23 +100,22 @@ extension FileBrowser {
}
}
}
/// Use the Dictionary(grouping:) function so that all the artists are grouped together.
let grouped = Dictionary(grouping: songs) { (occurrence: SongItem) -> String in
occurrence.artist
}
/// We now map over the dictionary and create our artist objects.
/// Then we want to sort them so that they are in the correct order.
artistList = grouped.map { artist -> ArtistItem in
ArtistItem(name: artist.key, songs: artist.value)
}
.sorted { $0.name < $1.name }
songList = songs.sorted { $0.title < $1.title }
}
/// Use the Dictionary(grouping:) function so that all the artists are grouped together.
let grouped = Dictionary(grouping: songs) { (occurrence: SongItem) -> String in
occurrence.artist
}
/// We now map over the dictionary and create our artist objects.
/// Then we want to sort them so that they are in the correct order.
artistList = grouped.map { artist -> ArtistItem in
ArtistItem(name: artist.key, songs: artist.value)
}
.sorted { $0.name < $1.name }
songList = songs.sorted { $0.title < $1.title }
folder = true
} catch {
/// There is no folder selected
folder = false
print(error.localizedDescription)
songsFolder = nil
status = .noFolder
}
}

Expand Down
Loading

0 comments on commit ec230de

Please sign in to comment.