implement login functionality, voting, account storage via windows credential manager, secure credential entry via windows CredUI, autologon on startup, always-on-top button, slight UI adjustments as well
This commit is contained in:
parent
e7569c6588
commit
c99d8ed910
|
@ -5,71 +5,74 @@
|
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:WinPlaza"
|
||||
mc:Ignorable="d"
|
||||
Title="Nightwave.Net" Height="200" Width="480" Background="#FFF0F0F0" ResizeMode="CanMinimize" Deactivated="Window_Deactivated" Activated="Window_Activated" UseLayoutRounding="True" Closing="Window_Closing">
|
||||
<Window.TaskbarItemInfo>
|
||||
<TaskbarItemInfo>
|
||||
<TaskbarItemInfo.ThumbButtonInfos>
|
||||
<ThumbButtonInfo x:Name="tbPlayPause" Description="Play/Stop" Click="TbPlayPause_Click" ImageSource="{DynamicResource tbPlayStop}"/>
|
||||
<ThumbButtonInfo x:Name="tbMute" Description="Mute/Unmute" Click="TbMute_Click" ImageSource="{DynamicResource tbAudible}"/>
|
||||
</TaskbarItemInfo.ThumbButtonInfos>
|
||||
</TaskbarItemInfo>
|
||||
</Window.TaskbarItemInfo>
|
||||
<Grid ClipToBounds="True">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="140*"/>
|
||||
<ColumnDefinition Width="155*"/>
|
||||
<ColumnDefinition Width="155*"/>
|
||||
<ColumnDefinition Width="10*"/>
|
||||
<ColumnDefinition Width="0*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image x:Name="art" Margin="0,0,0,0" Grid.Column="0" />
|
||||
<Label x:Name="lbTitle" Content="リサフランク420 / 現代のコンピュ" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontSize="12" FontWeight="Bold" Grid.ColumnSpan="2" Grid.Column="1"/>
|
||||
<Label x:Name="lbArtist" Content="MACプラス Macintosh Plus" HorizontalAlignment="Left" Margin="10,32,0,0" VerticalAlignment="Top" FontSize="11" Grid.Column="1"/>
|
||||
<Label x:Name="lbAlbum" Content="フローラルの専門店 Floral Shoppe" HorizontalAlignment="Left" Margin="10,54,0,0" VerticalAlignment="Top" FontStyle="Italic" FontSize="10" Grid.Column="1" Grid.ColumnSpan="2"/>
|
||||
<Slider x:Name="slDuration" Margin="10,87,0,0" VerticalAlignment="Top" IsEnabled="False" Grid.ColumnSpan="2" Height="18" Grid.Column="1"/>
|
||||
<Label x:Name="lbElapsed" Content="00:00" HorizontalAlignment="Left" Margin="10,99,0,0" VerticalAlignment="Top" FontStyle="Italic" FontSize="9" Grid.Column="1"/>
|
||||
<Label x:Name="lbTime" Content="00:00" Margin="0,99,9.667,0" VerticalAlignment="Top" HorizontalAlignment="Right" FontStyle="Italic" FontSize="9" Grid.Column="2" Grid.ColumnSpan="2"/>
|
||||
<Label x:Name="lbLike" Content="❤" HorizontalAlignment="Right" Margin="0,36,7.667,0" VerticalAlignment="Top" FontSize="10" Grid.Column="2"/>
|
||||
<Label x:Name="lbLikeCt" Content="0" HorizontalAlignment="Right" Margin="0,35,9.667,0" VerticalAlignment="Top" Grid.Column="2" Grid.ColumnSpan="2"/>
|
||||
<Label x:Name="lbDislike" Content="❌" HorizontalAlignment="Right" Margin="0,52,7.667,0" VerticalAlignment="Top" FontSize="10" Grid.Column="2"/>
|
||||
<Label x:Name="lbDislikeCt" Content="0" HorizontalAlignment="Right" Margin="0,51,9.667,0" VerticalAlignment="Top" Grid.Column="2" Grid.ColumnSpan="2"/>
|
||||
<DockPanel Grid.ColumnSpan="5" Margin="0,0,0,0" Grid.Row="1">
|
||||
<StatusBar x:Name="statusBar" Margin="0,0,0,-2" DockPanel.Dock="Bottom" VerticalAlignment="Bottom" BorderBrush="#FFDFDFDF" BorderThickness="1" Height="28" VerticalContentAlignment="Bottom">
|
||||
<StatusBarItem HorizontalAlignment="Left">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock x:Name="sbListeners" Text="420 listeners" Margin="4,0,0,0"/>
|
||||
<Separator Width="1" Margin="4,2"/>
|
||||
<ToggleButton x:Name="btPlayPause" Content="⏯" VerticalContentAlignment="Center" Checked="BtPlayPause_Click" Unchecked="BtPlayPause_Click" Margin="0,0,4,0" Height="{Binding Width, RelativeSource={RelativeSource Self}}"/>
|
||||
<TextBlock x:Name="sbStatus" Text="Idle.."/>
|
||||
</StackPanel>
|
||||
</StatusBarItem>
|
||||
<StatusBarItem HorizontalAlignment="Right">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock x:Name="sbListeningTimers" Text="00:00 (00:00)" Visibility="Hidden"/>
|
||||
<Button x:Name="sbMute" Content="🔊" Click="SbMute_Click"/>
|
||||
<Separator Width="6" Background="{x:Null}" Foreground="{x:Null}"/>
|
||||
<Slider x:Name="sbVol" Maximum="100" Minimum="0" Value="100" SmallChange="1" LargeChange="5" Width="80" ValueChanged="SbVol_ValueChanged" MouseWheel="SbVol_MouseWheel" Margin="0,0,4,0"/>
|
||||
</StackPanel>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
</DockPanel>
|
||||
<Canvas x:Name="chLeftCvs" Margin="10,0,0,2" Height="10" VerticalAlignment="Bottom" Background="#FFDDDDDD" RenderTransformOrigin="0.5,0.5" Grid.Column="1">
|
||||
<Canvas.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform ScaleY="1" ScaleX="-1"/>
|
||||
<SkewTransform AngleY="0" AngleX="0"/>
|
||||
<RotateTransform Angle="0"/>
|
||||
<TranslateTransform/>
|
||||
</TransformGroup>
|
||||
</Canvas.RenderTransform>
|
||||
<Rectangle x:Name="chLeft" Width="125" Height="10" HorizontalAlignment="Left" Fill="#FF003C49"/>
|
||||
</Canvas>
|
||||
<Canvas x:Name="chRightCvs" Margin="0,0,0,2" Height="10" VerticalAlignment="Bottom" Background="#FFDDDDDD" Grid.Column="2">
|
||||
<Rectangle x:Name="chRight" Width="125" Height="10" Fill="#FF003C49"/>
|
||||
</Canvas>
|
||||
</Grid>
|
||||
Title="Nightwave.Net" Height="206" Width="480" Background="#FFF0F0F0" ResizeMode="CanMinimize" Deactivated="Window_Deactivated" Activated="Window_Activated" UseLayoutRounding="True" Closing="Window_Closing">
|
||||
<Window.TaskbarItemInfo>
|
||||
<TaskbarItemInfo>
|
||||
<TaskbarItemInfo.ThumbButtonInfos>
|
||||
<ThumbButtonInfo x:Name="tbPlayPause" Description="Play/Stop" Click="TbPlayPause_Click" ImageSource="{DynamicResource tbPlayStop}"/>
|
||||
<ThumbButtonInfo x:Name="tbMute" Description="Mute/Unmute" Click="TbMute_Click" ImageSource="{DynamicResource tbAudible}"/>
|
||||
</TaskbarItemInfo.ThumbButtonInfos>
|
||||
</TaskbarItemInfo>
|
||||
</Window.TaskbarItemInfo>
|
||||
<Grid ClipToBounds="True">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="148*"/>
|
||||
<ColumnDefinition Width="163*"/>
|
||||
<ColumnDefinition Width="163*"/>
|
||||
<ColumnDefinition Width="0*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image x:Name="art" Margin="0,0,0,0" Grid.Column="0" Stretch="UniformToFill"/>
|
||||
<Label x:Name="lbTitle" Content="リサフランク420 / 現代のコンピュ" HorizontalAlignment="Left" Margin="2,6,0,0" VerticalAlignment="Top" FontSize="12" FontWeight="Bold" Grid.ColumnSpan="2" Grid.Column="1"/>
|
||||
<Label x:Name="lbArtist" Content="MACプラス Macintosh Plus" HorizontalAlignment="Left" Margin="2,28,0,0" VerticalAlignment="Top" FontSize="11" Grid.Column="1"/>
|
||||
<Label x:Name="lbAlbum" Content="フローラルの専門店 Floral Shoppe" HorizontalAlignment="Left" Margin="2,48,0,0" VerticalAlignment="Top" FontStyle="Italic" FontSize="10" Grid.Column="1" Grid.ColumnSpan="2"/>
|
||||
<Slider x:Name="slDuration" Margin="0,87,0,0" VerticalAlignment="Top" IsEnabled="False" Grid.ColumnSpan="2" Height="18" Grid.Column="1"/>
|
||||
<Label x:Name="lbElapsed" Content="00:00" HorizontalAlignment="Left" Margin="0,99,0,0" VerticalAlignment="Top" FontStyle="Italic" FontSize="9" Grid.Column="1"/>
|
||||
<Label x:Name="lbTime" Content="00:00" Margin="0,99,0,0" VerticalAlignment="Top" HorizontalAlignment="Right" FontStyle="Italic" FontSize="9" Grid.Column="2"/>
|
||||
<Button x:Name="btLike" Content="❤" HorizontalAlignment="Right" Margin="0,40,2,0" Width="20" Height="20" VerticalAlignment="Top" FontSize="9" Grid.Column="2" Click="BtLike_Click"/>
|
||||
<Button x:Name="btDislike" Content="❌" HorizontalAlignment="Right" Margin="0,64,2,0" Width="20" Height="20" VerticalAlignment="Top" FontSize="9" Grid.Column="2" Click="BtDislike_Click"/>
|
||||
<Label x:Name="lbLikeCt" Content="0" HorizontalAlignment="Right" Margin="0,36.5,20,0" VerticalAlignment="Top" Grid.Column="2" Grid.ColumnSpan="2"/>
|
||||
<Label x:Name="lbDislikeCt" Content="0" HorizontalAlignment="Right" Margin="0,60.5,20,0" VerticalAlignment="Top" Grid.Column="2" Grid.ColumnSpan="2"/>
|
||||
<Image x:Name="imLogin" Source="{DynamicResource imUsr}" IsHitTestVisible="False" Panel.ZIndex="1" Width="18" Height="18" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,17,18,0" Grid.Column="2"/>
|
||||
<Button x:Name="btLogin" Content="" HorizontalAlignment="Right" Margin="0,16,16,0" Width="20" Height="20" VerticalAlignment="Top" FontSize="9" Grid.Column="2" Click="BtLogin_Click"/>
|
||||
<DockPanel Grid.ColumnSpan="5" Margin="0,0,0,0" Grid.Row="1">
|
||||
<StatusBar x:Name="statusBar" Margin="0,0,0,-2" DockPanel.Dock="Bottom" VerticalAlignment="Bottom" BorderBrush="#FFDFDFDF" BorderThickness="1" Height="28" VerticalContentAlignment="Bottom">
|
||||
<StatusBarItem HorizontalAlignment="Left">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock x:Name="sbListeners" Text="420 listeners" Margin="4,0,4,0"/>
|
||||
<ToggleButton x:Name="btPlayPause" Content="⏯" VerticalContentAlignment="Center" Checked="BtPlayPause_Click" Unchecked="BtPlayPause_Click" Margin="0,-2,4,-2"/>
|
||||
<TextBlock x:Name="sbStatus" Text="Idle.."/>
|
||||
</StackPanel>
|
||||
</StatusBarItem>
|
||||
<StatusBarItem HorizontalAlignment="Right">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock x:Name="sbListeningTimers" Text="00:00 (00:00)" Visibility="Hidden"/>
|
||||
<ToggleButton x:Name="sbOnTop" Content="📌" Checked="SbOnTop_Click" Margin="0,-2,4,-2"/>
|
||||
<ToggleButton x:Name="sbMute" Content="🔊" Checked="SbMute_Click" Unchecked="SbMute_Click" Margin="0,-2,0,-2"/>
|
||||
<Separator Width="6" Background="{x:Null}" Foreground="{x:Null}"/>
|
||||
<Slider x:Name="sbVol" Maximum="100" Minimum="0" Value="100" SmallChange="1" LargeChange="5" Width="80" ValueChanged="SbVol_ValueChanged" MouseWheel="SbVol_MouseWheel" Margin="0,0,4,0"/>
|
||||
</StackPanel>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
</DockPanel>
|
||||
<Rectangle Height="1" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="0" Margin="0,0,0,10" Fill="#FF003C49" VerticalAlignment="Bottom"/>
|
||||
<Rectangle Width="1" Grid.Column="0" Grid.Row="0" Margin="0,0,0,0" Fill="#FFBFBFBF" HorizontalAlignment="Right"/>
|
||||
<Canvas x:Name="chLeftCvs" Margin="0,0,0,0" Height="10" VerticalAlignment="Bottom" Background="#FFDDDDDD" RenderTransformOrigin="0.5,0.5" Grid.Column="1">
|
||||
<Canvas.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform ScaleY="1" ScaleX="-1"/>
|
||||
<SkewTransform AngleY="0" AngleX="0"/>
|
||||
<RotateTransform Angle="0"/>
|
||||
<TranslateTransform/>
|
||||
</TransformGroup>
|
||||
</Canvas.RenderTransform>
|
||||
<Rectangle x:Name="chLeft" Width="0" Height="10" HorizontalAlignment="Left" Fill="#FF003C49"/>
|
||||
</Canvas>
|
||||
<Canvas x:Name="chRightCvs" Margin="0,0,0,0" Height="10" VerticalAlignment="Bottom" Background="#FFDDDDDD" Grid.Column="2">
|
||||
<Rectangle x:Name="chRight" Width="0" Height="10" Fill="#FF003C49"/>
|
||||
</Canvas>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
|
|
@ -6,6 +6,7 @@ using System.Windows;
|
|||
using System.Windows.Media.Imaging;
|
||||
using libplaza;
|
||||
using ManagedBass;
|
||||
using Meziantou.Framework.Win32;
|
||||
|
||||
namespace WinPlaza {
|
||||
public partial class MainWindow : Window {
|
||||
|
@ -20,6 +21,7 @@ namespace WinPlaza {
|
|||
private Timer tRefresh;
|
||||
private Timer tAudio;
|
||||
private Timer tGfx;
|
||||
private Timer tLogon;
|
||||
private bool AudioInit=false;
|
||||
#endregion
|
||||
#region Delegates
|
||||
|
@ -38,6 +40,18 @@ namespace WinPlaza {
|
|||
Dispatcher.BeginInvoke(new dgtStr(_Status), msg);
|
||||
private void SetTitle(string msg) =>
|
||||
Dispatcher.BeginInvoke(new dgtStr(_Title), msg);
|
||||
private async void dgtFirstLogin() {
|
||||
Credential c=CredentialManager.ReadCredential("Nightwave.NET");
|
||||
if(c is null)
|
||||
return;
|
||||
if(await plaza.Login(c.UserName, c.Password)!=true)
|
||||
return;
|
||||
btLogin.IsEnabled = false;
|
||||
btLogin.Visibility = Visibility.Hidden;
|
||||
imLogin.IsEnabled = false;
|
||||
imLogin.Visibility = Visibility.Hidden;
|
||||
SetStatus($"Logged in as {await plaza.GetUser()}");
|
||||
}
|
||||
private async void dgtRefresh(bool Force = false) {
|
||||
Nightwave.Status s=await plaza.Broadcast(Force);
|
||||
slDuration.Value = s.CalculatedElapsed;
|
||||
|
@ -46,11 +60,13 @@ namespace WinPlaza {
|
|||
lbDislikeCt.Content = s.Dislikes;
|
||||
lbElapsed.Content = $"{(s.CalculatedElapsed / 60).ToString("D")}:{(s.CalculatedElapsed % 60).ToString("D2")}";
|
||||
if(LastArtwork != s.ArtworkUri||Force) {
|
||||
if(tGfx.Enabled)
|
||||
SetStatus("Playing");
|
||||
lbArtist.Content = s.Artist;
|
||||
lbTitle.Content = s.Title;
|
||||
lbAlbum.Content = s.Album;
|
||||
if(btPlayPause.IsChecked == true)
|
||||
SetTitle($"▶ {s.Title} - {s.Artist}");
|
||||
SetTitle($"{s.Title} - {s.Artist}");
|
||||
slDuration.Maximum = s.Duration;
|
||||
lbTime.Content = $"{(s.Duration / 60).ToString("D")}:{(s.Duration % 60).ToString("D2")}";
|
||||
if(LastArtwork != s.ArtworkUri)
|
||||
|
@ -65,7 +81,7 @@ namespace WinPlaza {
|
|||
tAudio.Stop();
|
||||
//tbPlayPause.ImageSource = (BitmapImage)FindResource("tbPlaying");
|
||||
SetStatus("Playing");
|
||||
SetTitle($"▶ {lbTitle.Content} - {lbArtist.Content}");
|
||||
SetTitle($"{lbTitle.Content} - {lbArtist.Content}");
|
||||
tGfx.Start();
|
||||
_ = Bass.ChannelSetSync(BuffCh, SyncFlags.MetadataReceived, 0, MetaSync);
|
||||
_ = Bass.ChannelSetSync(BuffCh, SyncFlags.OggChange, 0, MetaSync);
|
||||
|
@ -105,7 +121,6 @@ namespace WinPlaza {
|
|||
_ = Bass.ChannelStop(BufferReqs);
|
||||
_ = Bass.ChannelStop(BuffCh);
|
||||
tAudio.Stop();
|
||||
//tbPlayPause.ImageSource = (BitmapImage)FindResource("tbStopped");
|
||||
SetStatus("Idle..");
|
||||
SetTitle("Nightwave.Net");
|
||||
}
|
||||
|
@ -123,11 +138,13 @@ namespace WinPlaza {
|
|||
SetStatus(Marshal.PtrToStringAnsi(buf));
|
||||
}
|
||||
private void EvtRefresh(object sender, ElapsedEventArgs e) =>
|
||||
_ = Dispatcher.BeginInvoke(new dgtBool(dgtRefresh), false);
|
||||
Dispatcher.BeginInvoke(new dgtBool(dgtRefresh), false);
|
||||
private async void EvtLogon(object sender, ElapsedEventArgs e) =>
|
||||
await Dispatcher.BeginInvoke(new dgtNoParam(dgtFirstLogin));
|
||||
private void EvtAudio(object sender, ElapsedEventArgs e) =>
|
||||
_ = Dispatcher.BeginInvoke(new dgtNoParam(dgtAud));
|
||||
private void EvtRender(object sender, ElapsedEventArgs e) =>
|
||||
Dispatcher.BeginInvoke(new dgtNoParam(Leveller));
|
||||
private async void EvtRender(object sender, ElapsedEventArgs e) =>
|
||||
await Dispatcher.BeginInvoke(new dgtNoParam(Leveller));
|
||||
private void BtPlayPause_Click(object sender, RoutedEventArgs e) {
|
||||
if(!AudioInit)
|
||||
return;
|
||||
|
@ -153,12 +170,52 @@ namespace WinPlaza {
|
|||
sbVol.Value += e.Delta / 25;
|
||||
e.Handled = true;
|
||||
}
|
||||
private void SbVol_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) =>
|
||||
private void SbVol_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) {
|
||||
if(MuteVol >= 0)
|
||||
sbMute.IsChecked = false;
|
||||
Bass.GlobalStreamVolume = (int)sbVol.Value * 100;
|
||||
}
|
||||
private async void BtLogin_Click(object sender, RoutedEventArgs e) {
|
||||
CredentialResult _c=CredentialManager.PromptForCredentials(messageText:"Please log into your Nightwave Plaza account", captionText:"Log into plaza.one");
|
||||
if(_c is null)
|
||||
return;
|
||||
CredentialManager.WriteCredential("Nightwave.NET", _c.UserName, _c.Password, CredentialPersistence.Enterprise);
|
||||
Credential c=CredentialManager.ReadCredential("Nightwave.NET");
|
||||
if(c is null)
|
||||
throw new Exception("what the fuck");
|
||||
Console.WriteLine($"did login work? {await plaza.Login(c.UserName, c.Password)}");
|
||||
Console.WriteLine($"can validate? {await plaza.CheckSession()}");
|
||||
#if DEBUG
|
||||
Console.WriteLine($"token is {plaza.GetAuthorizationToken()}");
|
||||
#endif
|
||||
btLogin.IsEnabled = false;
|
||||
btLogin.Visibility = Visibility.Hidden;
|
||||
imLogin.IsEnabled = false;
|
||||
imLogin.Visibility = Visibility.Hidden;
|
||||
}
|
||||
private async void BtLike_Click(object sender, RoutedEventArgs e) {
|
||||
if(await plaza.CastVote(Nightwave.Vote.Like))
|
||||
SetStatus("Song liked!");
|
||||
else
|
||||
SetStatus("Something went weird while liking");
|
||||
_ = Dispatcher.BeginInvoke(new dgtBool(dgtRefresh), true);
|
||||
}
|
||||
private async void BtDislike_Click(object sender, RoutedEventArgs e) {
|
||||
if(await plaza.CastVote(Nightwave.Vote.Dislike))
|
||||
SetStatus("Song disliked!");
|
||||
else
|
||||
SetStatus("Something went weird while disliking");
|
||||
_ = Dispatcher.BeginInvoke(new dgtBool(dgtRefresh), true);
|
||||
}
|
||||
private void SbOnTop_Click(object sender, RoutedEventArgs e) {
|
||||
Topmost = sbOnTop.IsChecked == true;
|
||||
if(tGfx.Enabled)
|
||||
tGfx.Interval = 1000.0 / 60.0;
|
||||
}
|
||||
private void TbPlayPause_Click(object sender, EventArgs e) =>
|
||||
btPlayPause.IsChecked = !btPlayPause.IsChecked;
|
||||
private void TbMute_Click(object sender, EventArgs e) =>
|
||||
SbMute_Click(sender, new RoutedEventArgs());
|
||||
sbMute.IsChecked = !sbMute.IsChecked;
|
||||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
|
||||
tRefresh.Stop();
|
||||
if(AudioInit) {
|
||||
|
@ -168,7 +225,7 @@ namespace WinPlaza {
|
|||
}
|
||||
}
|
||||
private void Window_Deactivated(object sender, EventArgs e) {
|
||||
if(tGfx.Enabled)
|
||||
if(tGfx.Enabled && !Topmost)
|
||||
tGfx.Interval = 1000.0 / 25.0;
|
||||
}
|
||||
private void Window_Activated(object sender, EventArgs e) {
|
||||
|
@ -182,6 +239,9 @@ namespace WinPlaza {
|
|||
tRefresh = new Timer(300) { AutoReset = true };
|
||||
tRefresh.Elapsed += EvtRefresh;
|
||||
tRefresh.Start();
|
||||
tLogon = new Timer(1000) { AutoReset = false };
|
||||
tLogon.Elapsed += EvtLogon;
|
||||
tLogon.Start();
|
||||
if(!Bass.Init())
|
||||
sbStatus.Text = "Unable to initialise audio subsystem";
|
||||
else
|
||||
|
@ -195,6 +255,7 @@ namespace WinPlaza {
|
|||
Bass.NetPlaylist = 1;
|
||||
Bass.NetPreBuffer = 0;
|
||||
}
|
||||
|
||||
~MainWindow() {
|
||||
if(AudioInit)
|
||||
_ = Bass.Free();
|
||||
|
@ -202,5 +263,6 @@ namespace WinPlaza {
|
|||
private void _Status(string s) => sbStatus.Text = s;
|
||||
private void _Title(string s) => Title = s;
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -31,7 +31,7 @@
|
|||
<CreateWebPageOnPublish>true</CreateWebPageOnPublish>
|
||||
<WebPage>index.html</WebPage>
|
||||
<OpenBrowserOnPublish>false</OpenBrowserOnPublish>
|
||||
<ApplicationRevision>1</ApplicationRevision>
|
||||
<ApplicationRevision>2</ApplicationRevision>
|
||||
<ApplicationVersion>1.4.0.%2a</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<CreateDesktopShortcut>true</CreateDesktopShortcut>
|
||||
|
@ -73,7 +73,7 @@
|
|||
<GenerateManifests>true</GenerateManifests>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignManifests>false</SignManifests>
|
||||
<SignManifests>true</SignManifests>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject>WinPlaza.App</StartupObject>
|
||||
|
@ -81,6 +81,12 @@
|
|||
<PropertyGroup>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>false</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>SNSigningKey.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ManagedBass, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ManagedBass.2.0.4\lib\net45\ManagedBass.dll</HintPath>
|
||||
|
@ -88,6 +94,9 @@
|
|||
<Reference Include="ManagedBass.Opus, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ManagedBass.Opus.2.0.0\lib\netstandard1.4\ManagedBass.Opus.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Meziantou.Framework.Win32.CredentialManager, Version=1.3.4.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Meziantou.Framework.Win32.CredentialManager.1.3.4\lib\net461\Meziantou.Framework.Win32.CredentialManager.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -140,6 +149,7 @@
|
|||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="SNSigningKey.snk" />
|
||||
<None Include="WinPlaza_TemporaryKey.pfx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
<packages>
|
||||
<package id="ManagedBass" version="2.0.4" targetFramework="net472" />
|
||||
<package id="ManagedBass.Opus" version="2.0.0" targetFramework="net472" />
|
||||
<package id="Meziantou.Framework.Win32.CredentialManager" version="1.3.4" targetFramework="net472" />
|
||||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net472" />
|
||||
</packages>
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
@ -27,12 +28,35 @@ namespace libplaza {
|
|||
[JsonProperty]
|
||||
public PlazaPlayback playback;
|
||||
}
|
||||
public class PlazaUser {
|
||||
public int id;
|
||||
public string username;
|
||||
public string email;
|
||||
public int role;
|
||||
public string created_at;
|
||||
}
|
||||
public class PlazaVote {
|
||||
public string status;
|
||||
public int[] ratings;
|
||||
}
|
||||
public class PlazaLogonResult {
|
||||
public string status;
|
||||
public string username;
|
||||
public string email;
|
||||
public string token;
|
||||
}
|
||||
internal class PlazaInMaintenanceException : Exception { }
|
||||
internal class PlazaUnavailableException : Exception { }
|
||||
public class Nightwave {
|
||||
public int MinRefreshTime=10;
|
||||
private long tsLastRefresh=0;
|
||||
private static HttpClient _hcl=new HttpClient();
|
||||
public enum Vote {
|
||||
Dislike=-1,
|
||||
Neutral,
|
||||
Like,
|
||||
Favourite
|
||||
}
|
||||
public enum BroadcastStatus {
|
||||
OffAir,
|
||||
OnAir
|
||||
|
@ -55,6 +79,7 @@ namespace libplaza {
|
|||
public BroadcastStatus Broadcasting=BroadcastStatus.OffAir;
|
||||
public Nightwave() {
|
||||
_hcl.BaseAddress = new Uri(PlazaApi.ApiBase);
|
||||
_hcl.Timeout = TimeSpan.FromSeconds(2);
|
||||
_hcl.DefaultRequestHeaders.Accept.Clear();
|
||||
_hcl.DefaultRequestHeaders.Accept.Add(
|
||||
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
|
||||
|
@ -77,7 +102,6 @@ namespace libplaza {
|
|||
tsLastRefresh = DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||
return _bc;
|
||||
}
|
||||
|
||||
public async void Update() {
|
||||
try {
|
||||
Status _=await GetNightwaveAsync();
|
||||
|
@ -117,5 +141,56 @@ namespace libplaza {
|
|||
status.CalculatedElapsed = (int)(DateTimeOffset.Now.ToUnixTimeSeconds() - status.ServerTimeOffset - j.playback.updated) + j.playback.position;
|
||||
return status;
|
||||
}
|
||||
public async Task<bool> CastVote(Vote v) {
|
||||
if(!await CheckSession())
|
||||
return false;
|
||||
HttpResponseMessage _r=await _hcl.PostAsync("/vote", new FormUrlEncodedContent(new[] {
|
||||
new KeyValuePair<string, string>("rate", ((int)v).ToString())}));
|
||||
if(!_r.IsSuccessStatusCode)
|
||||
return false;
|
||||
PlazaVote r=JsonConvert.DeserializeObject<PlazaVote>(await _r.Content.ReadAsStringAsync());
|
||||
if(r.status != "success")
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
public async Task<bool> CheckSession(string str) {
|
||||
_=_hcl.DefaultRequestHeaders.Remove("X-Access-Token");
|
||||
_hcl.DefaultRequestHeaders.Add("X-Access-Token", str);
|
||||
return await CheckSession();
|
||||
}
|
||||
public async Task<bool> CheckSession() {
|
||||
if(await GetUser() != null)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
public async Task<string> GetUser() {
|
||||
HttpResponseMessage _r=await _hcl.GetAsync("/user");
|
||||
if(!_r.IsSuccessStatusCode)
|
||||
return null;
|
||||
PlazaUser r=JsonConvert.DeserializeObject<PlazaUser>(await _r.Content.ReadAsStringAsync());
|
||||
if(r.id <= 0)
|
||||
return null;
|
||||
return r.username;
|
||||
}
|
||||
public async Task<bool> Login(string u, string p) => await Login(Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes($"{u}:{p}")));
|
||||
public async Task<bool> Login(string str) {
|
||||
_hcl.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", str);
|
||||
HttpResponseMessage _r=await _hcl.PostAsync("/user/login", null);
|
||||
if(!_r.IsSuccessStatusCode)
|
||||
return false;
|
||||
PlazaLogonResult r=JsonConvert.DeserializeObject<PlazaLogonResult>(await _r.Content.ReadAsStringAsync());
|
||||
if(r.status != "success")
|
||||
return false;
|
||||
_hcl.DefaultRequestHeaders.Add("X-Access-Token", r.token);
|
||||
_=_hcl.DefaultRequestHeaders.Remove("Authorization");
|
||||
return true;
|
||||
}
|
||||
#if DEBUG
|
||||
public string GetAuthorizationToken() {
|
||||
IEnumerator<string> h=_hcl.DefaultRequestHeaders.GetValues("X-Access-Token").GetEnumerator();
|
||||
_ = h.MoveNext();
|
||||
return h.Current;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue