Skip to content
Open
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
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Build results
[Bb]in/
[Oo]bj/

# Visual Studio cache/options
.vs/

# NuGet Packages
packages/

# Build artifacts
*.log
UpgradeLog.htm
3 changes: 2 additions & 1 deletion Elpis/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@
</ListView>

</StackPanel>
<Button Grid.Column="1" Name="btnLogout" Margin="5" Content="Logout" VerticalAlignment="Bottom" HorizontalAlignment="left" Style="{DynamicResource MaterialDesignFlatButton}">
<Button Grid.Column="1" Name="btnLogout" Margin="5" Content="Logout" VerticalAlignment="Bottom" HorizontalAlignment="left" Style="{DynamicResource MaterialDesignFlatButton}"
Click="btnLogout_Click">
<Button.ToolTip>
<TextBlock FontSize="14">
Logs out off the current session
Expand Down
164 changes: 87 additions & 77 deletions Elpis/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -839,103 +839,102 @@ private async Task FinalLoad()
// Log.O(ex.ToString());
// }
//#endif
// }
}

_loadingPage.UpdateStatus("Loading core components...");
_loadingPage.UpdateStatus("Loading core components...");

// 1. Create tasks for independent, long-running operations.
// We use Task.Run to ensure they execute on background threads.
try
{
// 1. Create tasks for independent, long-running operations.
// We use Task.Run to ensure they execute on background threads.
try
Task playerInitTask = Task.Run(() =>
{
// 1. Create tasks for independent, long-running operations.
Task playerInitTask = Task.Run(() =>
{
_player = new Player();
// This line could throw an exception if BASS audio engine fails
_player.Initialize(_bassRegEmail, _bassRegKey);
if (_config.Fields.Proxy_Address != string.Empty)
_player.SetProxy(_config.Fields.Proxy_Address, _config.Fields.Proxy_Port,
_config.Fields.Proxy_User, _config.Fields.Proxy_Password);
setOutputDevice(_config.Fields.System_OutputDevice);
});
_player = new Player();
// This line could throw an exception if BASS audio engine fails
_player.Initialize(_bassRegEmail, _bassRegKey);
if (_config.Fields.Proxy_Address != string.Empty)
_player.SetProxy(_config.Fields.Proxy_Address, _config.Fields.Proxy_Port,
_config.Fields.Proxy_User, _config.Fields.Proxy_Password);
setOutputDevice(_config.Fields.System_OutputDevice);
});

Task lastFmLoadTask = Task.Run(() => LoadLastFM());
Task webServerTask = Task.Run(() => StartWebServer());
Task lastFmLoadTask = Task.Run(() => LoadLastFM());
Task webServerTask = Task.Run(() => StartWebServer());

// 2. Await all of them to complete in parallel.
// If any task throws an exception, it will be caught by the catch block below.
await Task.WhenAll(playerInitTask, lastFmLoadTask, webServerTask);
}
catch (Exception ex)
{
// 3. Gracefully handle any startup error from the parallel tasks.
// This replaces the specific try-catch from the original code.
ShowError(ErrorCodes.ENGINE_INIT_ERROR, ex);
return; // Stop further execution if a critical component failed
}
// 2. Await all of them to complete in parallel.
// If any task throws an exception, it will be caught by the catch block below.
await Task.WhenAll(playerInitTask, lastFmLoadTask, webServerTask);
}
catch (Exception ex)
{
// 3. Gracefully handle any startup error from the parallel tasks.
// This replaces the specific try-catch from the original code.
ShowError(ErrorCodes.ENGINE_INIT_ERROR, ex);
return; // Stop further execution if a critical component failed
}

// 4. If all tasks succeeded, continue with the rest of the setup.
_player.AudioFormat = _config.Fields.Pandora_AudioFormat;
_player.SetStationSortOrder(_config.Fields.Pandora_StationSortOrder);
_player.Volume = _config.Fields.Elpis_Volume;
// 4. If all tasks succeeded, continue with the rest of the setup.
_player.AudioFormat = _config.Fields.Pandora_AudioFormat;
_player.SetStationSortOrder(_config.Fields.Pandora_StationSortOrder);
_player.Volume = _config.Fields.Elpis_Volume;

_player.PauseOnLock = _config.Fields.Elpis_PauseOnLock;
_player.MaxPlayed = _config.Fields.Elpis_MaxHistory;
_player.PauseOnLock = _config.Fields.Elpis_PauseOnLock;
_player.MaxPlayed = _config.Fields.Elpis_MaxHistory;

//_player.ForceSSL = _config.Fields.Misc_ForceSSL;
//_player.ForceSSL = _config.Fields.Misc_ForceSSL;


_loadingPage.UpdateStatus("Setting up cache...");
string cachePath = Path.Combine(Config.ElpisAppData, "Cache");
if (!Directory.Exists(cachePath)) Directory.CreateDirectory(cachePath);
_player.ImageCachePath = cachePath;
_loadingPage.UpdateStatus("Setting up cache...");
string cachePath = Path.Combine(Config.ElpisAppData, "Cache");
if (!Directory.Exists(cachePath)) Directory.CreateDirectory(cachePath);
_player.ImageCachePath = cachePath;

// _loadingPage.UpdateStatus("Starting Web Server...");
// _loadingPage.UpdateStatus("Starting Web Server...");

//await Task.Run(StartWebServer); // Start the web server asynchronously
//await Task.Run(StartWebServer); // Start the web server asynchronously

_loadingPage.UpdateStatus("Setting up UI...");
_loadingPage.UpdateStatus("Setting up UI...");

await Dispatcher.InvokeAsync(() =>
{
_keyHost = new HotKeyHost(this);
ConfigureHotKeys();
//SetupJumpListSafe();
SetupNotifyIcon();
mainBar.DataContext = _player; // To bind playstate
SetupPages();
SetupUIEvents();
SetupPageEvents();
//SetupThumbnailToolbarButtonsSafe();
});
await Dispatcher.InvokeAsync(() =>
{
_keyHost = new HotKeyHost(this);
ConfigureHotKeys();
//SetupJumpListSafe();
SetupNotifyIcon();
mainBar.DataContext = _player; // To bind playstate
SetupPages();
SetupUIEvents();
SetupPageEvents();
//SetupThumbnailToolbarButtonsSafe();
});

//this.Dispatch(SetupJumpList);
//this.Dispatch(SetupJumpList);

//this.Dispatch(SetupNotifyIcon);
//this.Dispatch(SetupNotifyIcon);

//this.Dispatch(() => mainBar.DataContext = _player); //To bind playstate
//this.Dispatch(() => mainBar.DataContext = _player); //To bind playstate

//this.Dispatch(SetupPages);
//this.Dispatch(SetupUIEvents);
//this.Dispatch(SetupPageEvents);
//this.Dispatch(SetupPages);
//this.Dispatch(SetupUIEvents);
//this.Dispatch(SetupPageEvents);

//this.Dispatch(SetupThumbnailToolbarButtons);
//this.Dispatch(SetupThumbnailToolbarButtons);

if (_config.Fields.Login_AutoLogin &&
!string.IsNullOrEmpty(_config.Fields.Login_Email) &&
!string.IsNullOrEmpty(_config.Fields.Login_Password))
{
await Task.Run(() => _player.Connect(_config.Fields.Login_Email, _config.Fields.Login_Password));
}
else
{
await Dispatcher.InvokeAsync(() => _loginPage);
}
if (_config.Fields.Login_AutoLogin &&
!string.IsNullOrEmpty(_config.Fields.Login_Email) &&
!string.IsNullOrEmpty(_config.Fields.Login_Password))
{
await Task.Run(() => _player.Connect(_config.Fields.Login_Email, _config.Fields.Login_Password));
}
else
{
await Dispatcher.InvokeAsync(() => ShowPage(_loginPage));
}

await Dispatcher.InvokeAsync(() => mainBar.Volume = _player.Volume);
await Dispatcher.InvokeAsync(() => mainBar.Volume = _player.Volume);

_finalComplete = true;
}
_finalComplete = true;
}

public void ShowPage(UserControl control)
Expand Down Expand Up @@ -1159,15 +1158,15 @@ private async Task LoadLogic()
{
if (!foundNewUpdate)
{
FinalLoad();
await FinalLoad();
}
}
else
{
FinalLoad();
await FinalLoad();
}
#else
FinalLoad();
await FinalLoad();
#endif
}
}
Expand Down Expand Up @@ -2003,6 +2002,17 @@ private void CanExecuteThumbsUpDown(object sender, CanExecuteRoutedEventArgs e)

#endregion

private void btnLogout_Click(object sender, RoutedEventArgs e)
{
// Clear credentials
_config.Fields.Login_Email = string.Empty;
_config.Fields.Login_Password = string.Empty;
_config.SaveConfig();

// Use existing logout logic
_settingsPage_Logout();
}

private void MinimizeButton_Click(object sender, EventArgs e) => WindowState = WindowState.Minimized;

private void CloseButton_Click(object sender, EventArgs e) => Close();
Expand Down
3 changes: 3 additions & 0 deletions Libs/PandoraSharp/Pandora.cs
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,9 @@ public async Task<List<Station>> RefreshStationsAsync()

}

// Add sorted regular stations to localStations
localStations.AddRange(Stations);
// Insert quick mixes at the beginning
localStations.InsertRange(0, quickMixes);
// Also update the public property for other parts of your app
this.Stations = localStations;
Expand Down
10 changes: 3 additions & 7 deletions Libs/PandoraSharp/Station.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,16 @@ public Station(Pandora p, JToken d)
try
{
ArtImage = File.ReadAllBytes(ArtCacheFile);
downloadArt = false;
}
catch (Exception)
{
Log.O("Error retrieving image cache file: " + ArtCacheFile);
downloadArt = true;
}

downloadArt = false;
}

/* if (downloadArt)
if (downloadArt)
{
var value = d.SelectToken("artUrl");
if (value != null)
Expand All @@ -97,7 +96,7 @@ public Station(Pandora p, JToken d)
try
{
ArtImage = PRequest.ByteRequest(ArtUrl);
if (ArtImage.Length > 0)
if (ArtImage.Length > 0 && !_pandora.ImageCachePath.Equals(""))
File.WriteAllBytes(ArtCacheFile, ArtImage);
}
catch (Exception)
Expand All @@ -106,10 +105,7 @@ public Station(Pandora p, JToken d)
}
}
}
//}

}
*/

}

Expand Down