using System; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Reactive; using System.Threading; using DiscordRPC; using ManagedBass; using Ocarina2.Models; using ReactiveUI; namespace Ocarina2.ViewModels; public class MainWindowViewModel : ViewModelBase { /* OCARINA2 Open-source music player and library manager Copyright (C) 2023 Matyáš Caras This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ private readonly Language _l = Language.Load("en_US"); private string _menuOpen; private string _menuFile; private string _menuExit; private string _music; private string _nomusic; private MusicFile? _selectedFile; public MusicFile? SelectedFile { get => _selectedFile; set => this.RaiseAndSetIfChanged(ref _selectedFile, value); } public string MenuOpen { get => _menuOpen; set => this.RaiseAndSetIfChanged(ref _menuOpen, value); } public string Music { get => _music; set => this.RaiseAndSetIfChanged(ref _music, value); } public string MenuExit { get => _menuExit; set => this.RaiseAndSetIfChanged(ref _menuExit, value); } public string MenuFile { get => _menuFile; set => this.RaiseAndSetIfChanged(ref _menuFile, value); } public string NoMusic { get => _nomusic; set => this.RaiseAndSetIfChanged(ref _nomusic, value); } public ObservableCollection MusicFiles {get;} /// /// Finds music files in the music library folder /// /// ObservableCollection of found files private ObservableCollection LoadFiles() { var musicfiles = new ObservableCollection(); if (!Directory.Exists(Environment.GetFolderPath(Environment.SpecialFolder.MyMusic))) return musicfiles; var subfolders = Directory.GetDirectories(Environment.GetFolderPath(Environment.SpecialFolder.MyMusic)); foreach (var folder in subfolders) { // get files in subfolders var f = Directory.GetFiles(folder).Where(f=>f.EndsWith("mp3")).ToList(); //TODO: change to other supported formats foreach (var file in f) { var tfile = TagLib.File.Create(file); musicfiles.Add(new MusicFile(tfile,file)); } } // get directory-level files var files = Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.MyMusic)).Where(f=>f.EndsWith("mp3")).ToList(); //TODO: change to other supported formats foreach (var file in files) { var tfile = TagLib.File.Create(file); musicfiles.Add(new MusicFile(tfile,file)); } return musicfiles; } /// /// Runs when a song is selected in the listbox to start playing it /// public void FileSelected() { if (SelectedFile == null) return; Stop(); try { var t = new Thread(async () => // TODO: toto thread asi neni fajn? { _player = new MediaPlayer(); await _player.LoadAsync(SelectedFile.Path); _player.Play(); App.Client.SetPresence(new RichPresence() { State = _l.RPArtist.Replace("$artist",SelectedFile.Metadata.Tag.FirstAlbumArtist), Details = _l.RPSong.Replace("$song",SelectedFile.Metadata.Tag.Title), Timestamps = new Timestamps { Start = DateTime.Now }, Assets = new Assets { LargeImageKey = "rpcon", LargeImageText = _l.RPIconText } }); }); t.Start(); } catch (Exception e) { Console.WriteLine(e); throw; } } /// /// Player of the ManagedBass library, used for playback /// private MediaPlayer? _player; public ReactiveCommand StopMusic { get; } /// /// Stops and disposes of the player /// public void Stop() { _player?.Stop(); _player?.Dispose(); } /// /// Used to play/pause playback /// public void PlayPause() { if (_player == null) return; if (_player.State == PlaybackState.Playing) { _player.Stop(); } else { _player.Play(); } } public MainWindowViewModel() { _menuOpen = _l.MenuOpen; _menuExit = _l.MenuExit; _menuFile = _l.MenuFile; _music = _l.Music; MusicFiles = LoadFiles(); _nomusic = _l.NoMusic; StopMusic = ReactiveCommand.Create(Stop); } public MainWindowViewModel(Language l) { _l = l; _menuOpen = _l.MenuOpen; _menuExit = _l.MenuExit; _menuFile = _l.MenuFile; _music = _l.Music; _nomusic = _l.NoMusic; MusicFiles = LoadFiles(); StopMusic = ReactiveCommand.Create(Stop); } }