204 lines
5.9 KiB
C#
204 lines
5.9 KiB
C#
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 <https://www.gnu.org/licenses/>.
|
|
*/
|
|
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<MusicFile> MusicFiles {get;}
|
|
|
|
/// <summary>
|
|
/// Finds music files in the music library folder
|
|
/// </summary>
|
|
/// <returns>ObservableCollection of found files</returns>
|
|
private ObservableCollection<MusicFile> LoadFiles()
|
|
{
|
|
var musicfiles = new ObservableCollection<MusicFile>();
|
|
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;
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Runs when a song is selected in the listbox to start playing it
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Player of the ManagedBass library, used for playback
|
|
/// </summary>
|
|
private MediaPlayer? _player;
|
|
public ReactiveCommand<Unit,Unit> StopMusic { get; }
|
|
|
|
/// <summary>
|
|
/// Stops and disposes of the player
|
|
/// </summary>
|
|
public void Stop()
|
|
{
|
|
_player?.Stop();
|
|
_player?.Dispose();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Used to play/pause playback
|
|
/// </summary>
|
|
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);
|
|
|
|
}
|
|
} |