Compare commits
No commits in common. "c5e8534af7aa2b5b66eb15315ca7855253d690b9" and "5d6e3b6d1e596b67e9c9dfc2ea9532422dfecef7" have entirely different histories.
c5e8534af7
...
5d6e3b6d1e
@ -15,8 +15,6 @@ namespace unison
|
||||
{
|
||||
//debug language
|
||||
//unison.Resources.Resources.Culture = CultureInfo.GetCultureInfo("fr-FR");
|
||||
//unison.Resources.Resources.Culture = CultureInfo.GetCultureInfo("es-ES");
|
||||
|
||||
|
||||
base.OnStartup(e);
|
||||
|
||||
|
29
CHANGELOG.md
29
CHANGELOG.md
@ -1,29 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
## v1.2
|
||||
|
||||
*Released: 07/04/2022*
|
||||
|
||||
* New feature: support for custom shortcuts
|
||||
* New feature: MPD stats
|
||||
* Add GitHub repository link in settings
|
||||
* MpcNET NuGet package integration
|
||||
* Update Snapcast from v0.25 to v0.26
|
||||
* Fix: hostname supported for connection
|
||||
* Fix: crash when using invalid IP or Hostname
|
||||
* Fix: crash when no internet connection when using RadioBrowser
|
||||
|
||||
## v1.1
|
||||
|
||||
*Released: 04/10/2021*
|
||||
|
||||
* Radio browser
|
||||
* Mute shortcut
|
||||
* Enter key works in settings textboxes
|
||||
* Share current song by double-clicking
|
||||
|
||||
## v1.0
|
||||
|
||||
*Released: 03/09/2021*
|
||||
|
||||
* First release of unison
|
@ -54,7 +54,7 @@ namespace unison
|
||||
bool _isUpdatingStatus = false;
|
||||
bool _isUpdatingSong = false;
|
||||
|
||||
public IPAddress _ipAddress;
|
||||
bool _invalidIp = false;
|
||||
|
||||
private event EventHandler ConnectionChanged;
|
||||
private event EventHandler StatusChanged;
|
||||
@ -64,10 +64,12 @@ namespace unison
|
||||
private MpcConnection _connection;
|
||||
private MpcConnection _commandConnection;
|
||||
private IPEndPoint _mpdEndpoint;
|
||||
private CancellationTokenSource _cancelToken;
|
||||
private CancellationTokenSource cancelToken;
|
||||
|
||||
public MPDHandler()
|
||||
{
|
||||
cancelToken = new CancellationTokenSource();
|
||||
|
||||
Initialize(null, null);
|
||||
|
||||
_stats = new Statistics();
|
||||
@ -95,7 +97,7 @@ namespace unison
|
||||
|
||||
void OnConnectionChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!_connected)
|
||||
if (!_connected && !_invalidIp)
|
||||
_retryTimer.Start();
|
||||
else
|
||||
_retryTimer.Stop();
|
||||
@ -158,7 +160,7 @@ namespace unison
|
||||
IMpdMessage<T> response = await _commandConnection.SendAsync(command);
|
||||
if (!response.IsResponseValid)
|
||||
{
|
||||
string mpdError = response.Response?.Result?.MpdError;
|
||||
var mpdError = response.Response?.Result?.MpdError;
|
||||
if (mpdError != null && mpdError != "")
|
||||
throw new Exception(mpdError);
|
||||
else
|
||||
@ -183,23 +185,19 @@ namespace unison
|
||||
|
||||
public async void Connect()
|
||||
{
|
||||
_cancelToken = new CancellationTokenSource();
|
||||
CancellationToken token = _cancelToken.Token;
|
||||
|
||||
CancellationToken token = cancelToken.Token;
|
||||
try
|
||||
{
|
||||
_connection = await ConnectInternal(token);
|
||||
_commandConnection = await ConnectInternal(token);
|
||||
}
|
||||
catch (MpcNET.Exceptions.MpcConnectException e)
|
||||
catch(MpcNET.Exceptions.MpcConnectException)
|
||||
{
|
||||
_connected = false;
|
||||
Trace.WriteLine($"Error in connect: {e.Message}");
|
||||
ConnectionChanged?.Invoke(this, EventArgs.Empty);
|
||||
return;
|
||||
_invalidIp = true;
|
||||
}
|
||||
if (_connection != null && _commandConnection != null)
|
||||
{
|
||||
_invalidIp = false;
|
||||
if (_connection.IsConnected && _commandConnection.IsConnected)
|
||||
{
|
||||
_connected = true;
|
||||
@ -209,7 +207,6 @@ namespace unison
|
||||
}
|
||||
else
|
||||
{
|
||||
_connected = false;
|
||||
ConnectionChanged?.Invoke(this, EventArgs.Empty);
|
||||
return;
|
||||
}
|
||||
@ -222,21 +219,16 @@ namespace unison
|
||||
|
||||
private async Task<MpcConnection> ConnectInternal(CancellationToken token)
|
||||
{
|
||||
IPAddress.TryParse(Properties.Settings.Default.mpd_host, out _ipAddress);
|
||||
IPAddress.TryParse(Properties.Settings.Default.mpd_host, out IPAddress ipAddress);
|
||||
|
||||
if (_ipAddress == null)
|
||||
if (ipAddress == null)
|
||||
{
|
||||
IPAddress[] addrList;
|
||||
try
|
||||
{
|
||||
IPAddress[] addrList = Dns.GetHostAddresses(Properties.Settings.Default.mpd_host);
|
||||
addrList = Dns.GetHostAddresses(Properties.Settings.Default.mpd_host);
|
||||
if (addrList.Length > 0)
|
||||
{
|
||||
foreach (IPAddress addr in addrList)
|
||||
{
|
||||
if (addr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
|
||||
_ipAddress = addr;
|
||||
}
|
||||
}
|
||||
ipAddress = addrList[0];
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@ -244,11 +236,11 @@ namespace unison
|
||||
}
|
||||
}
|
||||
|
||||
_mpdEndpoint = new IPEndPoint(_ipAddress, Properties.Settings.Default.mpd_port);
|
||||
_mpdEndpoint = new IPEndPoint(ipAddress, Properties.Settings.Default.mpd_port);
|
||||
MpcConnection connection = new MpcConnection(_mpdEndpoint);
|
||||
await connection.ConnectAsync(token);
|
||||
|
||||
if (!string.IsNullOrEmpty(Properties.Settings.Default.mpd_password))
|
||||
/*if (!string.IsNullOrEmpty(Properties.Settings.Default.mpd_password))
|
||||
{
|
||||
IMpdMessage<string> result = await connection.SendAsync(new PasswordCommand(Properties.Settings.Default.mpd_password));
|
||||
if (!result.IsResponseValid)
|
||||
@ -256,21 +248,19 @@ namespace unison
|
||||
string mpdError = result.Response?.Result?.MpdError;
|
||||
Trace.WriteLine(mpdError);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
public void Disconnected()
|
||||
private void Disconnected()
|
||||
{
|
||||
_connected = false;
|
||||
ConnectionChanged?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
if (_connection != null)
|
||||
_connection = null;
|
||||
|
||||
if (_commandConnection != null)
|
||||
_commandConnection = null;
|
||||
|
||||
ConnectionChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void Loop(CancellationToken token)
|
||||
@ -281,29 +271,24 @@ namespace unison
|
||||
{
|
||||
try
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
if (token.IsCancellationRequested || _connection == null)
|
||||
break;
|
||||
|
||||
IMpdMessage<string> idleChanges = await _connection.SendAsync(new IdleCommand("stored_playlist playlist player mixer output options update"));
|
||||
var idleChanges = await _connection.SendAsync(new IdleCommand("stored_playlist playlist player mixer output options"));
|
||||
|
||||
if (idleChanges.IsResponseValid)
|
||||
await HandleIdleResponseAsync(idleChanges.Response.Content);
|
||||
else
|
||||
{
|
||||
Trace.WriteLine($"Error in Idle connection thread: {idleChanges.Response?.Content}");
|
||||
throw new Exception(idleChanges.Response?.Content);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Trace.WriteLine($"Error in Idle connection thread: {e.Message}");
|
||||
Disconnected();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}, token).ConfigureAwait(false);
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task HandleIdleResponseAsync(string subsystems)
|
||||
@ -381,7 +366,6 @@ namespace unison
|
||||
List<byte> data = new List<byte>();
|
||||
try
|
||||
{
|
||||
bool ReadPictureFailed = true;
|
||||
long totalBinarySize = 9999;
|
||||
long currentSize = 0;
|
||||
|
||||
@ -390,41 +374,18 @@ namespace unison
|
||||
if (_connection == null)
|
||||
return;
|
||||
|
||||
IMpdMessage<MpdBinaryData> albumReq = await _connection.SendAsync(new ReadPictureCommand(path, currentSize));
|
||||
var albumReq = await _connection.SendAsync(new AlbumArtCommand(path, currentSize));
|
||||
if (!albumReq.IsResponseValid)
|
||||
break;
|
||||
|
||||
MpdBinaryData response = albumReq.Response.Content;
|
||||
if (response == null || response.Binary == 0)
|
||||
break;
|
||||
|
||||
ReadPictureFailed = false;
|
||||
totalBinarySize = response.Size;
|
||||
currentSize += response.Binary;
|
||||
data.AddRange(response.Data);
|
||||
}
|
||||
while (currentSize < totalBinarySize && !token.IsCancellationRequested);
|
||||
|
||||
do
|
||||
{
|
||||
if (!ReadPictureFailed)
|
||||
break;
|
||||
if (_connection == null)
|
||||
return;
|
||||
|
||||
IMpdMessage<MpdBinaryData> albumReq = await _connection.SendAsync(new AlbumArtCommand(path, currentSize));
|
||||
if (!albumReq.IsResponseValid)
|
||||
break;
|
||||
|
||||
MpdBinaryData response = albumReq.Response.Content;
|
||||
if (response == null || response.Binary == 0)
|
||||
var response = albumReq.Response.Content;
|
||||
if (response.Binary == 0)
|
||||
break;
|
||||
|
||||
totalBinarySize = response.Size;
|
||||
currentSize += response.Binary;
|
||||
data.AddRange(response.Data);
|
||||
}
|
||||
while (currentSize < totalBinarySize && !token.IsCancellationRequested);
|
||||
} while (currentSize < totalBinarySize && !token.IsCancellationRequested);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -542,6 +503,7 @@ namespace unison
|
||||
|
||||
public void AddSong(string Uri)
|
||||
{
|
||||
Debug.WriteLine("AddCommand path: " + Uri);
|
||||
SendCommand(new AddCommand(Uri));
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ namespace unison
|
||||
{
|
||||
if (Properties.Settings.Default.snapcast_startup)
|
||||
{
|
||||
MPDHandler mpd = (MPDHandler)Application.Current.Properties["mpd"];
|
||||
var mpd = (MPDHandler)Application.Current.Properties["mpd"];
|
||||
if (mpd.IsConnected())
|
||||
LaunchOrExit();
|
||||
}
|
||||
@ -37,10 +37,8 @@ namespace unison
|
||||
{
|
||||
if (!HasStarted && !ForceExit)
|
||||
{
|
||||
MPDHandler mpd = (MPDHandler)Application.Current.Properties["mpd"];
|
||||
|
||||
_snapcast.StartInfo.FileName = Properties.Settings.Default.snapcast_path + @"\snapclient.exe";
|
||||
_snapcast.StartInfo.Arguments = $"--host {mpd._ipAddress}";
|
||||
_snapcast.StartInfo.Arguments = $"--host {Properties.Settings.Default.mpd_host}";
|
||||
_snapcast.StartInfo.CreateNoWindow = !Properties.Settings.Default.snapcast_window;
|
||||
try
|
||||
{
|
||||
|
10
README.md
10
README.md
@ -33,11 +33,17 @@ Through [Radio-Browser](https://www.radio-browser.info), a community database, y
|
||||
|
||||
![Radio stations](Screenshots/screen4.png)
|
||||
|
||||
## Planned features
|
||||
## Caveats
|
||||
|
||||
### Missing features
|
||||
|
||||
* MPD passwords: I don't really see the point, but if asked, I will integrate them.
|
||||
|
||||
### Planned features
|
||||
|
||||
* A complete shuffle system based on set criteria, aka a smart playlist.
|
||||
* Playlist, queue and library management. I use other software to do it, but I will implement them at some point.
|
||||
|
||||
## Translations
|
||||
|
||||
unison is translated in English, French and Spanish. You can contribute if you want!
|
||||
unison is translated in English and French. You can contribute if you want!
|
33
Resources/Resources.Designer.cs
generated
33
Resources/Resources.Designer.cs
generated
@ -196,25 +196,7 @@ namespace unison.Resources {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Please note that since MPD passwords are not secure (they are sent in plain text to the server), there are saved as is in the setting file..
|
||||
/// </summary>
|
||||
public static string Settings_ConnectionPasswordInfo {
|
||||
get {
|
||||
return ResourceManager.GetString("Settings_ConnectionPasswordInfo", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Status:.
|
||||
/// </summary>
|
||||
public static string Settings_ConnectionStatus {
|
||||
get {
|
||||
return ResourceManager.GetString("Settings_ConnectionStatus", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to connected to MPD.
|
||||
/// Looks up a localized string similar to Connected to MPD.
|
||||
/// </summary>
|
||||
public static string Settings_ConnectionStatusConnected {
|
||||
get {
|
||||
@ -223,7 +205,7 @@ namespace unison.Resources {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to connecting....
|
||||
/// Looks up a localized string similar to Connecting....
|
||||
/// </summary>
|
||||
public static string Settings_ConnectionStatusConnecting {
|
||||
get {
|
||||
@ -232,7 +214,7 @@ namespace unison.Resources {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to not connected..
|
||||
/// Looks up a localized string similar to Not connected..
|
||||
/// </summary>
|
||||
public static string Settings_ConnectionStatusOffline {
|
||||
get {
|
||||
@ -276,15 +258,6 @@ namespace unison.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Password.
|
||||
/// </summary>
|
||||
public static string Settings_Password {
|
||||
get {
|
||||
return ResourceManager.GetString("Settings_Password", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Play / pause.
|
||||
/// </summary>
|
||||
|
@ -1,306 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Exit" xml:space="preserve">
|
||||
<value>Salir</value>
|
||||
</data>
|
||||
<data name="Radios" xml:space="preserve">
|
||||
<value>Radios</value>
|
||||
</data>
|
||||
<data name="Radio_Country" xml:space="preserve">
|
||||
<value>Países</value>
|
||||
</data>
|
||||
<data name="Radio_Loading" xml:space="preserve">
|
||||
<value>Cargando estaciones...</value>
|
||||
</data>
|
||||
<data name="Radio_Name" xml:space="preserve">
|
||||
<value>Nombre</value>
|
||||
</data>
|
||||
<data name="Radio_NotFound" xml:space="preserve">
|
||||
<value>¡No estaciones encontradas!</value>
|
||||
</data>
|
||||
<data name="Radio_Reset" xml:space="preserve">
|
||||
<value>Reinicializar</value>
|
||||
</data>
|
||||
<data name="Radio_Search" xml:space="preserve">
|
||||
<value>Búsqueda</value>
|
||||
</data>
|
||||
<data name="Radio_SearchStation" xml:space="preserve">
|
||||
<value>Buscar estación</value>
|
||||
</data>
|
||||
<data name="Radio_Tags" xml:space="preserve">
|
||||
<value>Tags</value>
|
||||
</data>
|
||||
<data name="Settings" xml:space="preserve">
|
||||
<value>Ajustes</value>
|
||||
</data>
|
||||
<data name="Settings_About" xml:space="preserve">
|
||||
<value>Acerca de</value>
|
||||
</data>
|
||||
<data name="Settings_AboutInfo" xml:space="preserve">
|
||||
<value>unison es un software libre. Es construido con las siguientes tecnologías:</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectButton" xml:space="preserve">
|
||||
<value>Conexión</value>
|
||||
</data>
|
||||
<data name="Settings_Connection" xml:space="preserve">
|
||||
<value>Conexión</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectionPasswordInfo" xml:space="preserve">
|
||||
<value>Tenga en cuenta que, dado que las contraseñas de MPD no son seguras (se envían en texto sin formato al servidor), se guardan tal cual en el archivo de configuración.</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectionStatus" xml:space="preserve">
|
||||
<value>Estado:</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectionStatusConnected" xml:space="preserve">
|
||||
<value>conectado a MPD</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectionStatusConnecting" xml:space="preserve">
|
||||
<value>conectando...</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectionStatusOffline" xml:space="preserve">
|
||||
<value>no conectado.</value>
|
||||
</data>
|
||||
<data name="Settings_Host" xml:space="preserve">
|
||||
<value>Host</value>
|
||||
</data>
|
||||
<data name="Settings_License" xml:space="preserve">
|
||||
<value>Licencia</value>
|
||||
</data>
|
||||
<data name="Settings_MadeBy" xml:space="preserve">
|
||||
<value>Creado por</value>
|
||||
</data>
|
||||
<data name="Settings_NextTrack" xml:space="preserve">
|
||||
<value>Pista siguiente</value>
|
||||
</data>
|
||||
<data name="Settings_Password" xml:space="preserve">
|
||||
<value>Contraseña</value>
|
||||
</data>
|
||||
<data name="Settings_PlayPause" xml:space="preserve">
|
||||
<value>Jugar / pausa</value>
|
||||
</data>
|
||||
<data name="Settings_Port" xml:space="preserve">
|
||||
<value>Puerto</value>
|
||||
</data>
|
||||
<data name="Settings_PreviousTrack" xml:space="preserve">
|
||||
<value>Pista precedente</value>
|
||||
</data>
|
||||
<data name="Settings_Shortcuts" xml:space="preserve">
|
||||
<value>Atajos</value>
|
||||
</data>
|
||||
<data name="Settings_ShortcutsInfo" xml:space="preserve">
|
||||
<value>Tenga en cuenta que si no está reconocida la tecla, esto se debe a una limitación en el funcionamiento de las teclas virtuales.</value>
|
||||
</data>
|
||||
<data name="Settings_ShortcutsKey" xml:space="preserve">
|
||||
<value>Entre una tecla...</value>
|
||||
</data>
|
||||
<data name="Settings_ShowWindow" xml:space="preserve">
|
||||
<value>Mostrar ventana</value>
|
||||
</data>
|
||||
<data name="Settings_SnapcastInfo1" xml:space="preserve">
|
||||
<value>Puede cambiar a su propia versión instalada localmente del cliente Snapcast con una ruta</value>
|
||||
</data>
|
||||
<data name="Settings_SnapcastInfo2" xml:space="preserve">
|
||||
<value> absoluta</value>
|
||||
</data>
|
||||
<data name="Settings_SnapcastInfo3" xml:space="preserve">
|
||||
<value>.</value>
|
||||
</data>
|
||||
<data name="Settings_SnapcastLauch" xml:space="preserve">
|
||||
<value>Lanzar al inicio</value>
|
||||
</data>
|
||||
<data name="Settings_SnapcastPath" xml:space="preserve">
|
||||
<value>Ruta del ejecutable</value>
|
||||
</data>
|
||||
<data name="Settings_SnapcastPort" xml:space="preserve">
|
||||
<value>Puerto</value>
|
||||
</data>
|
||||
<data name="Settings_SnapcastResetButton" xml:space="preserve">
|
||||
<value>Reinicializar</value>
|
||||
</data>
|
||||
<data name="Settings_SnapcastWindow" xml:space="preserve">
|
||||
<value>Mostrar ventana de Snapcast</value>
|
||||
</data>
|
||||
<data name="Settings_SourceCode1" xml:space="preserve">
|
||||
<value>Código fuente disponible gratuitamente</value>
|
||||
</data>
|
||||
<data name="Settings_SourceCode2" xml:space="preserve">
|
||||
<value>aquí</value>
|
||||
</data>
|
||||
<data name="Settings_Version" xml:space="preserve">
|
||||
<value>Versión:</value>
|
||||
</data>
|
||||
<data name="Settings_VolumeDown" xml:space="preserve">
|
||||
<value>Bajar volumen</value>
|
||||
</data>
|
||||
<data name="Settings_VolumeMute" xml:space="preserve">
|
||||
<value>Volumen mudo</value>
|
||||
</data>
|
||||
<data name="Settings_VolumeOffset" xml:space="preserve">
|
||||
<value>Intervalo de volumen</value>
|
||||
</data>
|
||||
<data name="Settings_VolumeUp" xml:space="preserve">
|
||||
<value>Subir volumen</value>
|
||||
</data>
|
||||
<data name="ShowWindow" xml:space="preserve">
|
||||
<value>Mostrar ventana</value>
|
||||
</data>
|
||||
<data name="Snapcast_Popup1" xml:space="preserve">
|
||||
<value>Error Snapcast</value>
|
||||
</data>
|
||||
<data name="Snapcast_Popup2" xml:space="preserve">
|
||||
<value>Ruta no válida:</value>
|
||||
</data>
|
||||
<data name="Snapcast_Popup3" xml:space="preserve">
|
||||
<value>Ruta actual:</value>
|
||||
</data>
|
||||
<data name="Snapcast_Popup4" xml:space="preserve">
|
||||
<value>Puede restablecerlo en la configuración si es necesario.</value>
|
||||
</data>
|
||||
<data name="StartSnapcast" xml:space="preserve">
|
||||
<value>Iniciar Snapcast</value>
|
||||
</data>
|
||||
<data name="Stats" xml:space="preserve">
|
||||
<value>Estadísticas</value>
|
||||
</data>
|
||||
<data name="Stats_Albums" xml:space="preserve">
|
||||
<value>Álbumes:</value>
|
||||
</data>
|
||||
<data name="Stats_Artists" xml:space="preserve">
|
||||
<value>Artistas:</value>
|
||||
</data>
|
||||
<data name="Stats_LastDatabaseUpdate" xml:space="preserve">
|
||||
<value>Última actualización de la base de datos:</value>
|
||||
</data>
|
||||
<data name="Stats_Songs" xml:space="preserve">
|
||||
<value>Canciones:</value>
|
||||
</data>
|
||||
<data name="Stats_TotalPlaytime" xml:space="preserve">
|
||||
<value>Tiempo de juego total:</value>
|
||||
</data>
|
||||
<data name="Stats_TotalTimePlayed" xml:space="preserve">
|
||||
<value>Tiempo total jugado:</value>
|
||||
</data>
|
||||
<data name="Stats_Uptime" xml:space="preserve">
|
||||
<value>Tiempo de actividad de MPD:</value>
|
||||
</data>
|
||||
<data name="StopSnapcast" xml:space="preserve">
|
||||
<value>Parar Snapcast</value>
|
||||
</data>
|
||||
</root>
|
@ -133,7 +133,7 @@
|
||||
<value>Nom</value>
|
||||
</data>
|
||||
<data name="Radio_NotFound" xml:space="preserve">
|
||||
<value>Aucune station trouvée !</value>
|
||||
<value>Aucun station trouvée !</value>
|
||||
</data>
|
||||
<data name="Radio_Reset" xml:space="preserve">
|
||||
<value>Réinitialiser</value>
|
||||
@ -162,20 +162,14 @@
|
||||
<data name="Settings_Connection" xml:space="preserve">
|
||||
<value>Connexion</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectionPasswordInfo" xml:space="preserve">
|
||||
<value>Veuillez noter que comme les mots de passe de MPD ne sont pas sécurisés (ils sont envoyés en clair au serveur), ils sont sauvegardés tels quels.</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectionStatus" xml:space="preserve">
|
||||
<value>Statut :</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectionStatusConnected" xml:space="preserve">
|
||||
<value>connecté à MPD</value>
|
||||
<value>Connecté à MPD</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectionStatusConnecting" xml:space="preserve">
|
||||
<value>connexion en cours...</value>
|
||||
<value>Connexion en cours...</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectionStatusOffline" xml:space="preserve">
|
||||
<value>non connecté.</value>
|
||||
<value>Non connecté.</value>
|
||||
</data>
|
||||
<data name="Settings_Host" xml:space="preserve">
|
||||
<value>Hôte</value>
|
||||
@ -189,9 +183,6 @@
|
||||
<data name="Settings_NextTrack" xml:space="preserve">
|
||||
<value>Piste suivante</value>
|
||||
</data>
|
||||
<data name="Settings_Password" xml:space="preserve">
|
||||
<value>Mot de passe</value>
|
||||
</data>
|
||||
<data name="Settings_PlayPause" xml:space="preserve">
|
||||
<value>Jouer / pause</value>
|
||||
</data>
|
||||
|
@ -162,20 +162,14 @@
|
||||
<data name="Settings_Connection" xml:space="preserve">
|
||||
<value>Connection</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectionPasswordInfo" xml:space="preserve">
|
||||
<value>Please note that since MPD passwords are not secure (they are sent in plain text to the server), there are saved as is in the setting file.</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectionStatus" xml:space="preserve">
|
||||
<value>Status:</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectionStatusConnected" xml:space="preserve">
|
||||
<value>connected to MPD</value>
|
||||
<value>Connected to MPD</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectionStatusConnecting" xml:space="preserve">
|
||||
<value>connecting...</value>
|
||||
<value>Connecting...</value>
|
||||
</data>
|
||||
<data name="Settings_ConnectionStatusOffline" xml:space="preserve">
|
||||
<value>not connected.</value>
|
||||
<value>Not connected.</value>
|
||||
</data>
|
||||
<data name="Settings_Host" xml:space="preserve">
|
||||
<value>Host</value>
|
||||
@ -189,9 +183,6 @@
|
||||
<data name="Settings_NextTrack" xml:space="preserve">
|
||||
<value>Next track</value>
|
||||
</data>
|
||||
<data name="Settings_Password" xml:space="preserve">
|
||||
<value>Password</value>
|
||||
</data>
|
||||
<data name="Settings_PlayPause" xml:space="preserve">
|
||||
<value>Play / pause</value>
|
||||
</data>
|
||||
|
@ -90,7 +90,7 @@ namespace unison
|
||||
SongAlbum.Text = _mpd.GetCurrentSong().Album;
|
||||
|
||||
if (_mpd.GetCurrentSong().Date != null)
|
||||
SongAlbum.Text += $" ({_mpd.GetCurrentSong().Date.Split("-")[0]})";
|
||||
SongAlbum.Text += $" ({ _mpd.GetCurrentSong().Date})";
|
||||
|
||||
SongGenre.Text = _mpd.GetCurrentSong().Genre;
|
||||
SongFormat.Text = _mpd.GetCurrentSong().Path.Substring(_mpd.GetCurrentSong().Path.LastIndexOf(".") + 1);
|
||||
|
@ -77,8 +77,6 @@ namespace unison
|
||||
}
|
||||
|
||||
public async void Initialize()
|
||||
{
|
||||
try
|
||||
{
|
||||
List<NameAndCount> Countries = await _radioBrowser.Lists.GetCountriesAsync();
|
||||
CountryList.Items.Add(new CountryListItem { Name = "", Count = 0 });
|
||||
@ -92,12 +90,6 @@ namespace unison
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine("Exception while getting countries in RadioBrowser: " + e.Message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private string CleanString(string str)
|
||||
{
|
||||
|
@ -33,26 +33,20 @@
|
||||
<StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_Host}" TextWrapping="Wrap" Margin="5,0,0,0"/>
|
||||
<TextBox x:Name="MpdHost" KeyDown="ConnectHandler" TextChanged="MpdConnectTextBox" TextWrapping="Wrap" Width="250" Margin="10,2,0,0"/>
|
||||
<TextBox x:Name="MpdHost" KeyDown="ConnectHandler" TextWrapping="Wrap" Width="250" Margin="10,2,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Margin="0,5,0,0">
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_Port}" TextWrapping="Wrap" Margin="5,0,0,0"/>
|
||||
<TextBox x:Name="MpdPort" KeyDown="ConnectHandler" PreviewTextInput="NumberValidationTextBox" MaxLength="5" TextWrapping="Wrap" Width="250" Margin="10,2,0,0"/>
|
||||
<TextBox x:Name="MpdPort" KeyDown="ConnectHandler" MaxLength="5" PreviewTextInput="NumberValidationTextBox" TextWrapping="Wrap" Width="250" Margin="10,2,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Margin="0,5,0,0">
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_Password}" TextWrapping="Wrap" Margin="5,0,0,0"/>
|
||||
<PasswordBox x:Name="MpdPassword" Width="250" Margin="10,2,0,0"/>
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_ConnectionPasswordInfo}" TextWrapping="Wrap" Margin="10,5,0,0" MaxWidth="250" HorizontalAlignment="Left"/>
|
||||
</StackPanel>
|
||||
<!--<StackPanel Margin="0,5,0,0">
|
||||
<TextBlock Text="Password" TextWrapping="Wrap" Margin="5,0,0,0"/>
|
||||
<TextBox x:Name="MpdPassword" TextWrapping="Wrap" Width="250" Margin="10,2,0,0"/>
|
||||
</StackPanel>-->
|
||||
|
||||
<TextBlock TextWrapping="Wrap" Margin="5,10,0,0">
|
||||
<Run Text="{x:Static properties:Resources.Settings_ConnectionStatus}" FontWeight="Bold" />
|
||||
<Run x:Name="ConnectionStatus" Text="{x:Static properties:Resources.Settings_ConnectionStatusOffline}"/>
|
||||
</TextBlock>
|
||||
|
||||
<!--<TextBlock x:Name="ConnectionStatus" Text="{x:Static properties:Resources.Settings_ConnectionStatusOffline}" TextWrapping="Wrap" Margin="5,10,0,0"/>-->
|
||||
<TextBlock x:Name="ConnectionStatus" Text="{x:Static properties:Resources.Settings_ConnectionStatusOffline}" TextWrapping="Wrap" Margin="5,10,0,0"/>
|
||||
<Button x:Name="ConnectButton" Content="{x:Static properties:Resources.Settings_ConnectButton}" Margin="0,10,0,0" Width="120" Click="MPDConnect_Clicked"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
@ -157,7 +151,7 @@
|
||||
</Grid>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_ShortcutsInfo}" TextWrapping="Wrap" MaxWidth="440" TextAlignment="Justify" />
|
||||
<TextBlock Text="{x:Static properties:Resources.Settings_ShortcutsInfo}" TextWrapping="Wrap" Margin="0,2,0,0" MaxWidth="420" />
|
||||
</StackPanel>
|
||||
|
||||
<Button Content="{x:Static properties:Resources.Settings_SnapcastResetButton}" Margin="0,10,0,0" Width="120" Click="ShortcutsReset_Clicked"/>
|
||||
|
@ -37,7 +37,6 @@ namespace unison
|
||||
|
||||
HotkeyHandler _hotkeys = (HotkeyHandler)Application.Current.Properties["hotkeys"];
|
||||
|
||||
|
||||
public Settings()
|
||||
{
|
||||
InitHwnd();
|
||||
@ -53,7 +52,7 @@ namespace unison
|
||||
{
|
||||
MpdHost.Text = Properties.Settings.Default.mpd_host;
|
||||
MpdPort.Text = Properties.Settings.Default.mpd_port.ToString();
|
||||
MpdPassword.Password = Properties.Settings.Default.mpd_password;
|
||||
//MpdPassword.Text = Properties.Settings.Default.mpd_password;
|
||||
SnapcastStartup.IsChecked = Properties.Settings.Default.snapcast_startup;
|
||||
SnapcastWindow.IsChecked = Properties.Settings.Default.snapcast_window;
|
||||
SnapcastPath.Text = Properties.Settings.Default.snapcast_path;
|
||||
@ -63,134 +62,6 @@ namespace unison
|
||||
InitializeShortcuts();
|
||||
}
|
||||
|
||||
public void UpdateConnectionStatus()
|
||||
{
|
||||
MPDHandler mpd = (MPDHandler)Application.Current.Properties["mpd"];
|
||||
if (mpd.IsConnected())
|
||||
{
|
||||
ConnectionStatus.Text = $"{unison.Resources.Resources.Settings_ConnectionStatusConnected} {mpd.GetVersion()}.";
|
||||
ConnectButton.IsEnabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConnectionStatus.Text = unison.Resources.Resources.Settings_ConnectionStatusOffline;
|
||||
ConnectButton.IsEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void NumberValidationTextBox(object sender, TextCompositionEventArgs e)
|
||||
{
|
||||
Regex regex = new Regex("[^0-9]+");
|
||||
e.Handled = regex.IsMatch(e.Text);
|
||||
}
|
||||
|
||||
private void MpdConnectTextBox(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
TextBox textBox = (TextBox)sender;
|
||||
|
||||
if (textBox.Text == Properties.Settings.Default.mpd_host)
|
||||
ConnectButton.IsEnabled = false;
|
||||
else
|
||||
ConnectButton.IsEnabled = true;
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
|
||||
{
|
||||
ProcessStartInfo psi = new(e.Uri.AbsoluteUri);
|
||||
psi.UseShellExecute = true;
|
||||
Process.Start(psi);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void MPDConnect_Clicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!ConnectButton.IsEnabled)
|
||||
return;
|
||||
|
||||
SaveSettings();
|
||||
|
||||
MPDHandler mpd = (MPDHandler)Application.Current.Properties["mpd"];
|
||||
if (mpd.IsConnected())
|
||||
mpd = new MPDHandler();
|
||||
|
||||
ConnectButton.IsEnabled = false;
|
||||
ConnectionStatus.Text = unison.Resources.Resources.Settings_ConnectionStatusConnecting;
|
||||
|
||||
System.Threading.Tasks.Task.Run(() => { mpd.Connect(); });
|
||||
}
|
||||
|
||||
private void SnapcastReset_Clicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SnapcastPath.Text = (string)Application.Current.FindResource("snapcastPath");
|
||||
SnapcastPort.Text = (string)Application.Current.FindResource("snapcastPort");
|
||||
}
|
||||
|
||||
public void UpdateStats()
|
||||
{
|
||||
MPDHandler mpd = (MPDHandler)Application.Current.Properties["mpd"];
|
||||
StatSong.Text = mpd.GetStats().Songs.ToString();
|
||||
StatAlbum.Text = mpd.GetStats().Albums.ToString();
|
||||
StatArtist.Text = mpd.GetStats().Artists.ToString();
|
||||
StatTotalPlaytime.Text = mpd.GetStats().TotalPlaytime.ToString();
|
||||
StatUptime.Text = mpd.GetStats().Uptime.ToString();
|
||||
StatTotalTimePlayed.Text = mpd.GetStats().TotalTimePlayed.ToString();
|
||||
StatDatabaseUpdate.Text = mpd.GetStats().DatabaseUpdate.ToString();
|
||||
}
|
||||
|
||||
private void ConnectHandler(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Return)
|
||||
MPDConnect_Clicked(null, null);
|
||||
}
|
||||
|
||||
private void Window_Closing(object sender, CancelEventArgs e)
|
||||
{
|
||||
e.Cancel = true;
|
||||
SaveSettings();
|
||||
WindowState = WindowState.Minimized;
|
||||
Hide();
|
||||
}
|
||||
|
||||
public void InitHwnd()
|
||||
{
|
||||
WindowInteropHelper helper = new(this);
|
||||
helper.EnsureHandle();
|
||||
}
|
||||
|
||||
public void SaveSettings()
|
||||
{
|
||||
Properties.Settings.Default.mpd_host = MpdHost.Text;
|
||||
Properties.Settings.Default.mpd_port = int.Parse(MpdPort.Text, CultureInfo.InvariantCulture);
|
||||
Properties.Settings.Default.mpd_password = MpdPassword.Password;
|
||||
Properties.Settings.Default.snapcast_startup = (bool)SnapcastStartup.IsChecked;
|
||||
Properties.Settings.Default.snapcast_window = (bool)SnapcastWindow.IsChecked;
|
||||
Properties.Settings.Default.snapcast_path = SnapcastPath.Text;
|
||||
Properties.Settings.Default.snapcast_port = int.Parse(SnapcastPort.Text, CultureInfo.InvariantCulture);
|
||||
Properties.Settings.Default.volume_offset = int.Parse(VolumeOffset.Text, CultureInfo.InvariantCulture);
|
||||
|
||||
Properties.Settings.Default.nextTrack_mod = GetMod(Shortcut_NextTrack);
|
||||
Properties.Settings.Default.nextTrack_vk = GetVk(Shortcut_NextTrack);
|
||||
Properties.Settings.Default.previousTrack_mod = GetMod(Shortcut_PreviousTrack);
|
||||
Properties.Settings.Default.previousTrack_vk = GetVk(Shortcut_PreviousTrack);
|
||||
Properties.Settings.Default.playPause_mod = GetMod(Shortcut_PlayPause);
|
||||
Properties.Settings.Default.playPause_vk = GetVk(Shortcut_PlayPause);
|
||||
Properties.Settings.Default.volumeUp_mod = GetMod(Shortcut_VolumeUp);
|
||||
Properties.Settings.Default.volumeUp_vk = GetVk(Shortcut_VolumeUp);
|
||||
Properties.Settings.Default.volumeDown_mod = GetMod(Shortcut_VolumeDown);
|
||||
Properties.Settings.Default.volumeDown_vk = GetVk(Shortcut_VolumeDown);
|
||||
Properties.Settings.Default.volumeMute_mod = GetMod(Shortcut_VolumeMute);
|
||||
Properties.Settings.Default.volumeMute_vk = GetVk(Shortcut_VolumeMute);
|
||||
Properties.Settings.Default.showWindow_mod = GetMod(Shortcut_ShowWindow);
|
||||
Properties.Settings.Default.showWindow_vk = GetVk(Shortcut_ShowWindow);
|
||||
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
|
||||
|
||||
// Hotkeys
|
||||
|
||||
void InitializeShortcuts()
|
||||
{
|
||||
System.Collections.Generic.IEnumerable<StackPanel> stackPanelCollection = RebindKeyWrapper.Children.OfType<StackPanel>();
|
||||
@ -237,6 +108,55 @@ namespace unison
|
||||
}
|
||||
}
|
||||
|
||||
private void NumberValidationTextBox(object sender, TextCompositionEventArgs e)
|
||||
{
|
||||
Regex regex = new Regex("[^0-9]+");
|
||||
e.Handled = regex.IsMatch(e.Text);
|
||||
}
|
||||
|
||||
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
|
||||
{
|
||||
ProcessStartInfo psi = new(e.Uri.AbsoluteUri);
|
||||
psi.UseShellExecute = true;
|
||||
Process.Start(psi);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
public void UpdateConnectionStatus()
|
||||
{
|
||||
MPDHandler mpd = (MPDHandler)Application.Current.Properties["mpd"];
|
||||
if (mpd.IsConnected())
|
||||
ConnectionStatus.Text = $"{unison.Resources.Resources.Settings_ConnectionStatusConnected} {mpd.GetVersion()}.";
|
||||
else
|
||||
ConnectionStatus.Text = unison.Resources.Resources.Settings_ConnectionStatusOffline;
|
||||
}
|
||||
|
||||
private void MPDConnect_Clicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SaveSettings();
|
||||
ConnectionStatus.Text = unison.Resources.Resources.Settings_ConnectionStatusConnecting;
|
||||
MPDHandler mpd = (MPDHandler)Application.Current.Properties["mpd"];
|
||||
mpd.Connect();
|
||||
}
|
||||
|
||||
private void SnapcastReset_Clicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SnapcastPath.Text = (string)Application.Current.FindResource("snapcastPath");
|
||||
SnapcastPort.Text = (string)Application.Current.FindResource("snapcastPort");
|
||||
}
|
||||
|
||||
public void UpdateStats()
|
||||
{
|
||||
MPDHandler mpd = (MPDHandler)Application.Current.Properties["mpd"];
|
||||
StatSong.Text = mpd.GetStats().Songs.ToString();
|
||||
StatAlbum.Text = mpd.GetStats().Albums.ToString();
|
||||
StatArtist.Text = mpd.GetStats().Artists.ToString();
|
||||
StatTotalPlaytime.Text = mpd.GetStats().TotalPlaytime.ToString();
|
||||
StatUptime.Text = mpd.GetStats().Uptime.ToString();
|
||||
StatTotalTimePlayed.Text = mpd.GetStats().TotalTimePlayed.ToString();
|
||||
StatDatabaseUpdate.Text = mpd.GetStats().DatabaseUpdate.ToString();
|
||||
}
|
||||
|
||||
private void HotkeyChanged()
|
||||
{
|
||||
_hotkeys.RemoveHotkeys();
|
||||
@ -387,5 +307,54 @@ namespace unison
|
||||
TextBlock textBlock = (TextBlock)button.Content;
|
||||
return (uint)(HotkeyHandler.VK)System.Enum.Parse(typeof(HotkeyHandler.VK), textBlock.Text, true);
|
||||
}
|
||||
|
||||
public void SaveSettings()
|
||||
{
|
||||
Properties.Settings.Default.mpd_host = MpdHost.Text;
|
||||
Properties.Settings.Default.mpd_port = int.Parse(MpdPort.Text, CultureInfo.InvariantCulture);
|
||||
//Properties.Settings.Default.mpd_password = MpdPassword.Text;
|
||||
Properties.Settings.Default.snapcast_startup = (bool)SnapcastStartup.IsChecked;
|
||||
Properties.Settings.Default.snapcast_window = (bool)SnapcastWindow.IsChecked;
|
||||
Properties.Settings.Default.snapcast_path = SnapcastPath.Text;
|
||||
Properties.Settings.Default.snapcast_port = int.Parse(SnapcastPort.Text, CultureInfo.InvariantCulture);
|
||||
Properties.Settings.Default.volume_offset = int.Parse(VolumeOffset.Text, CultureInfo.InvariantCulture);
|
||||
|
||||
Properties.Settings.Default.nextTrack_mod = GetMod(Shortcut_NextTrack);
|
||||
Properties.Settings.Default.nextTrack_vk = GetVk(Shortcut_NextTrack);
|
||||
Properties.Settings.Default.previousTrack_mod = GetMod(Shortcut_PreviousTrack);
|
||||
Properties.Settings.Default.previousTrack_vk = GetVk(Shortcut_PreviousTrack);
|
||||
Properties.Settings.Default.playPause_mod = GetMod(Shortcut_PlayPause);
|
||||
Properties.Settings.Default.playPause_vk = GetVk(Shortcut_PlayPause);
|
||||
Properties.Settings.Default.volumeUp_mod = GetMod(Shortcut_VolumeUp);
|
||||
Properties.Settings.Default.volumeUp_vk = GetVk(Shortcut_VolumeUp);
|
||||
Properties.Settings.Default.volumeDown_mod = GetMod(Shortcut_VolumeDown);
|
||||
Properties.Settings.Default.volumeDown_vk = GetVk(Shortcut_VolumeDown);
|
||||
Properties.Settings.Default.volumeMute_mod = GetMod(Shortcut_VolumeMute);
|
||||
Properties.Settings.Default.volumeMute_vk = GetVk(Shortcut_VolumeMute);
|
||||
Properties.Settings.Default.showWindow_mod = GetMod(Shortcut_ShowWindow);
|
||||
Properties.Settings.Default.showWindow_vk = GetVk(Shortcut_ShowWindow);
|
||||
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
|
||||
private void ConnectHandler(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Return)
|
||||
MPDConnect_Clicked(null, null);
|
||||
}
|
||||
|
||||
private void Window_Closing(object sender, CancelEventArgs e)
|
||||
{
|
||||
e.Cancel = true;
|
||||
SaveSettings();
|
||||
WindowState = WindowState.Minimized;
|
||||
Hide();
|
||||
}
|
||||
|
||||
public void InitHwnd()
|
||||
{
|
||||
WindowInteropHelper helper = new(this);
|
||||
helper.EnsureHandle();
|
||||
}
|
||||
}
|
||||
}
|
@ -64,9 +64,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Resources\Resources.es-ES.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\Resources.fr-FR.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
|
Loading…
Reference in New Issue
Block a user