Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change the Elmish music player example to use IStorageProvider instea… #407

Merged
merged 3 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 30 additions & 25 deletions src/Examples/Elmish Examples/Examples.Elmish.MusicPlayer/Dialogs.fs
Original file line number Diff line number Diff line change
@@ -1,34 +1,39 @@
namespace Examples.MusicPlayer


module Dialogs =
open System
open Avalonia.Controls
open Avalonia
open Avalonia.Platform.Storage
open Avalonia.Threading
open System.Collections.Generic

let getMusicFilesDialog (filters: FileDialogFilter seq option) =
let dialog = OpenFileDialog()
let showMusicFilesDialog(provider: IStorageProvider, filters: FilePickerFileType list option) =

let filters =
match filters with
| Some filter -> filter
| None ->
let filter = FileDialogFilter()
filter.Extensions <-
Collections.Generic.List
(seq {
"mp3"
"wav" })
filter.Name <- "Music"
seq { filter }

dialog.AllowMultiple <- true
dialog.Directory <- Environment.GetFolderPath(Environment.SpecialFolder.MyMusic)
dialog.Title <- "Select Your Music Files"
dialog.Filters <- System.Collections.Generic.List(filters)
dialog

let getFolderDialog =
let dialog = OpenFolderDialog()
dialog.Directory <- Environment.GetFolderPath(Environment.SpecialFolder.MyMusic)
dialog.Title <- "Choose where to look up for music"
dialog
let patterns = [ "*.mp3"; "*.wav" ]
let filter = FilePickerFileType("Music", Patterns = patterns)
[ filter ]

let options = FilePickerOpenOptions(AllowMultiple = true, Title = "Select Your Music Files", FileTypeFilter = filters)

async {
let! musicFolder = provider.TryGetWellKnownFolderAsync Platform.Storage.WellKnownFolder.Music |> Async.AwaitTask
options.SuggestedStartLocation <- musicFolder

return!
Dispatcher.UIThread.InvokeAsync<IReadOnlyList<IStorageFile>>
(fun _ -> provider.OpenFilePickerAsync(options)) |> Async.AwaitTask
}

let showMusicFolderDialog(provider: IStorageProvider) =
async {
let! musicFolder = provider.TryGetWellKnownFolderAsync Platform.Storage.WellKnownFolder.Music |> Async.AwaitTask
let options = FolderPickerOpenOptions(Title = "Choose where to look up for music", SuggestedStartLocation = musicFolder)

return!
Dispatcher.UIThread.InvokeAsync<IReadOnlyList<IStorageFolder>>
(fun _ -> provider.OpenFolderPickerAsync(options)) |> Async.AwaitTask

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<PackageReference Include="VideoLAN.LibVLC.Mac" Version="3.1.3.1" />
<ProjectReference Include="..\..\..\Avalonia.FuncUI.Elmish\Avalonia.FuncUI.Elmish.fsproj" />
<ProjectReference Include="..\..\..\Avalonia.FuncUI\Avalonia.FuncUI.fsproj" />
<PackageReference Include="LibVLCSharp" Version="3.4.2" />
<PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.8.1" />
<PackageReference Include="LibVLCSharp" Version="3.8.5" />
<PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.20" />
</ItemGroup>
</Project>
24 changes: 13 additions & 11 deletions src/Examples/Elmish Examples/Examples.Elmish.MusicPlayer/Shell.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ module Shell =
open Avalonia.Controls
open Avalonia.Input
open Avalonia.Layout
open Avalonia.Platform.Storage
open Avalonia.FuncUI.Elmish
open Avalonia.FuncUI.Hosts
open Avalonia.FuncUI.DSL
open LibVLCSharp.Shared
open Examples.MusicPlayer
open System.Collections.Generic

type State =
{ title: string
Expand All @@ -24,8 +26,8 @@ module Shell =
| SetTitle of string
| OpenFiles
| OpenFolder
| AfterSelectFolder of string
| AfterSelectFiles of string array
| AfterSelectFolder of IReadOnlyList<IStorageFolder>
| AfterSelectFiles of IReadOnlyList<IStorageFile>
(* Handle Media Player Events *)
| Playing
| Paused
Expand Down Expand Up @@ -122,15 +124,13 @@ module Shell =
window.Title <- title
{ state with title = title }, Cmd.none
| OpenFiles ->
let dialog = Dialogs.getMusicFilesDialog None
let showDialog window = dialog.ShowAsync(window) |> Async.AwaitTask
state, Cmd.OfAsync.perform showDialog window AfterSelectFiles
let showDialog storageProvider = Dialogs.showMusicFilesDialog (storageProvider, None)
state, Cmd.OfAsync.perform showDialog window.StorageProvider AfterSelectFiles
| OpenFolder ->
let dialog = Dialogs.getFolderDialog
let showDialog window = dialog.ShowAsync(window) |> Async.AwaitTask
state, Cmd.OfAsync.perform showDialog window AfterSelectFolder
| AfterSelectFolder path ->
let songs = Songs.populateFromDirectory path |> Array.toList
let showDialog storageProvider = Dialogs.showMusicFolderDialog storageProvider
state, Cmd.OfAsync.perform showDialog window.StorageProvider AfterSelectFolder
| AfterSelectFolder paths ->
let songs = Songs.populateFromFolders paths |> Array.toList
state, Cmd.map PlaylistMsg (Cmd.ofMsg (Playlist.Msg.AddFiles songs))
| AfterSelectFiles paths ->
let songs = Songs.populateSongs paths |> Array.toList
Expand Down Expand Up @@ -185,8 +185,10 @@ module Shell =
type ShellWindow() as this =
inherit HostWindow()
do
let iconPath = System.IO.Path.Combine("Assets", "Icons", "icon.ico")

base.Title <- "Music Player in F# :)"
base.Icon <- WindowIcon("Assets\Icons\icon.ico")
base.Icon <- WindowIcon(iconPath)
base.Width <- 800.0
base.Height <- 600.0
base.MinWidth <- 526.0
Expand Down
19 changes: 12 additions & 7 deletions src/Examples/Elmish Examples/Examples.Elmish.MusicPlayer/Songs.fs
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
namespace Examples.MusicPlayer


module Songs =
open System
open System.IO
open Types
open Avalonia.Platform.Storage

let populateSongs (paths: string array): Types.SongRecord array =
let populateSongs (paths: IStorageFile seq): Types.SongRecord array =
paths
|> Array.Parallel.map FileInfo
|> Array.Parallel.map (fun info -> info.Name, info.FullName)
|> Array.Parallel.map (fun (name, path) ->
|> Seq.map (fun storageFile ->
{ id = Guid.NewGuid()
name = name
path = path
name = storageFile.Name
path = storageFile.Path.LocalPath
createdAt = DateTime.Now })
|> Array.ofSeq

let populateFromDirectory (path: string): Types.SongRecord array =
match String.IsNullOrEmpty path with
Expand All @@ -29,3 +28,9 @@ module Songs =
name = name
path = path
createdAt = DateTime.Now })

let populateFromFolders(folders: IStorageFolder seq) =
folders
|> Seq.map _.Path.LocalPath
Numpsy marked this conversation as resolved.
Show resolved Hide resolved
|> Seq.map populateFromDirectory
|> Array.concat
Loading