mirror of
https://github.com/Sarsoo/IF.Lastfm.git
synced 2024-10-17 07:13:09 +01:00
UserApi.GetRecentStations
This commit is contained in:
parent
7ab098d5a8
commit
243d4558e2
@ -1,19 +1,33 @@
|
|||||||
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using IF.Lastfm.Core.Api.Enums;
|
using IF.Lastfm.Core.Api.Enums;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace IF.Lastfm.Core.Api.Helpers
|
namespace IF.Lastfm.Core.Api.Helpers
|
||||||
{
|
{
|
||||||
public class PageResponse<T> : IEnumerable<T>
|
public class PageResponse<T> : IEnumerable<T>
|
||||||
{
|
{
|
||||||
|
private int _page = 1;
|
||||||
|
private int _totalPages = 1;
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
public IEnumerable<T> Content { get; set; }
|
public IEnumerable<T> Content { get; set; }
|
||||||
public bool Success { get; set; }
|
public bool Success { get; set; }
|
||||||
public LastFmApiError Error { get; set; }
|
public LastFmApiError Error { get; set; }
|
||||||
|
|
||||||
public int Page { get; set; }
|
public int Page
|
||||||
public int TotalPages { get; set; }
|
{
|
||||||
|
get { return _page; }
|
||||||
|
set { _page = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int TotalPages
|
||||||
|
{
|
||||||
|
get { return _totalPages; }
|
||||||
|
set { _totalPages = value; }
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -72,5 +86,27 @@ public static PageResponse<T> CreateErrorResponse(LastFmApiError error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
public void AddPageInfoFromJToken(JToken attrToken)
|
||||||
|
{
|
||||||
|
if (attrToken == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var page = attrToken.Value<string>("page");
|
||||||
|
Page = !string.IsNullOrWhiteSpace(page) ? Convert.ToInt32(page) : 1;
|
||||||
|
|
||||||
|
var totalPages = attrToken.Value<string>("totalPages");
|
||||||
|
TotalPages = !string.IsNullOrWhiteSpace(totalPages) ? Convert.ToInt32(totalPages) : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// {"@attr": {
|
||||||
|
// "user": "tehrikkit",
|
||||||
|
// "page": "",
|
||||||
|
// "perPage": "",
|
||||||
|
// "totalPages": "",
|
||||||
|
// "total": "15"
|
||||||
|
//}}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,17 +18,7 @@ Task<PageResponse<Album>> GetTopAlbums(LastStatsTimeSpan span,
|
|||||||
Task<PageResponse<Track>> GetRecentScrobbles(string username, DateTime since,
|
Task<PageResponse<Track>> GetRecentScrobbles(string username, DateTime since,
|
||||||
int startIndex = 0,
|
int startIndex = 0,
|
||||||
int endIndex = LastFm.DefaultPageLength);
|
int endIndex = LastFm.DefaultPageLength);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
Task<PageResponse<Station>> GetRecentStations(int pagenumber, int count = LastFm.DefaultPageLength);
|
||||||
*
|
}
|
||||||
* limit (Optional) : The number of results to fetch per page. Defaults to 50. Maximum is 200.
|
|
||||||
user (Required) : The last.fm username to fetch the recent tracks of.
|
|
||||||
page (Optional) : The page number to fetch. Defaults to first page.
|
|
||||||
from (Optional) : Beginning timestamp of a range - only display scrobbles after this time, in UNIX timestamp format (integer number of seconds since 00:00:00, January 1st 1970 UTC). This must be in the UTC time zone.
|
|
||||||
extended (0|1) (Optional) : Includes extended data in each artist, and whether or not the user has loved each track
|
|
||||||
to (Optional) : End timestamp of a range - only display scrobbles before this time, in UNIX timestamp format (integer number of seconds since 00:00:00, January 1st 1970 UTC). This must be in the UTC time zone.
|
|
||||||
api_key (Required) : A Last.fm API key.
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
}
|
}
|
@ -107,12 +107,7 @@ public async Task<PageResponse<Track>> GetRecentScrobbles(string username, DateT
|
|||||||
var pageresponse = PageResponse<Track>.CreateSuccessResponse(tracks);
|
var pageresponse = PageResponse<Track>.CreateSuccessResponse(tracks);
|
||||||
|
|
||||||
var attrToken = jtoken.SelectToken("@attr");
|
var attrToken = jtoken.SelectToken("@attr");
|
||||||
|
pageresponse.AddPageInfoFromJToken(attrToken);
|
||||||
if (attrToken != null)
|
|
||||||
{
|
|
||||||
pageresponse.Page = attrToken.Value<int>("page");
|
|
||||||
pageresponse.TotalPages = attrToken.Value<int>("totalPages");
|
|
||||||
}
|
|
||||||
|
|
||||||
return pageresponse;
|
return pageresponse;
|
||||||
}
|
}
|
||||||
@ -121,5 +116,50 @@ public async Task<PageResponse<Track>> GetRecentScrobbles(string username, DateT
|
|||||||
return PageResponse<Track>.CreateErrorResponse(error);
|
return PageResponse<Track>.CreateErrorResponse(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<PageResponse<Station>> GetRecentStations(int pagenumber, int count = LastFm.DefaultPageLength)
|
||||||
|
{
|
||||||
|
const string apiMethod = "user.getRecentStations";
|
||||||
|
|
||||||
|
var methodParameters = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{"user", Auth.User.Username},
|
||||||
|
{"page", pagenumber.ToString()},
|
||||||
|
{"limit", count.ToString()},
|
||||||
|
{"sk", Auth.User.Token}
|
||||||
|
};
|
||||||
|
|
||||||
|
var apisig = Auth.GenerateMethodSignature(apiMethod, methodParameters);
|
||||||
|
|
||||||
|
var postContent = LastFm.CreatePostBody(apiMethod,
|
||||||
|
Auth.ApiKey,
|
||||||
|
apisig,
|
||||||
|
methodParameters);
|
||||||
|
|
||||||
|
var httpClient = new HttpClient();
|
||||||
|
var lastResponse = await httpClient.PostAsync(LastFm.ApiRoot, postContent);
|
||||||
|
var json = await lastResponse.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
|
LastFmApiError error;
|
||||||
|
if (LastFm.IsResponseValid(json, out error) && lastResponse.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
var jtoken = JsonConvert.DeserializeObject<JToken>(json).SelectToken("recentstations");
|
||||||
|
|
||||||
|
var stationsToken = jtoken.SelectToken("station");
|
||||||
|
|
||||||
|
var stations = stationsToken.Children().Select(Station.ParseJToken).ToList();
|
||||||
|
|
||||||
|
var pageresponse = PageResponse<Station>.CreateSuccessResponse(stations);
|
||||||
|
|
||||||
|
var attrToken = jtoken.SelectToken("@attr");
|
||||||
|
pageresponse.AddPageInfoFromJToken(attrToken);
|
||||||
|
|
||||||
|
return pageresponse;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return PageResponse<Station>.CreateErrorResponse(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -64,6 +64,7 @@
|
|||||||
<Compile Include="Objects\BuyLink.cs" />
|
<Compile Include="Objects\BuyLink.cs" />
|
||||||
<Compile Include="Objects\CountryCode.cs" />
|
<Compile Include="Objects\CountryCode.cs" />
|
||||||
<Compile Include="Objects\Shout.cs" />
|
<Compile Include="Objects\Shout.cs" />
|
||||||
|
<Compile Include="Objects\Station.cs" />
|
||||||
<Compile Include="Objects\Tag.cs" />
|
<Compile Include="Objects\Tag.cs" />
|
||||||
<Compile Include="Objects\Track.cs" />
|
<Compile Include="Objects\Track.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
22
IF.Lastfm.Core/Objects/Station.cs
Normal file
22
IF.Lastfm.Core/Objects/Station.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace IF.Lastfm.Core.Objects
|
||||||
|
{
|
||||||
|
|
||||||
|
public class Station
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public Uri Url { get; set; }
|
||||||
|
|
||||||
|
internal static Station ParseJToken(JToken token)
|
||||||
|
{
|
||||||
|
var s = new Station();
|
||||||
|
|
||||||
|
s.Name = token.Value<string>("name");
|
||||||
|
s.Url = new Uri(token.Value<string>("url"), UriKind.Absolute);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -102,6 +102,9 @@
|
|||||||
<Compile Include="MainPage.xaml.cs">
|
<Compile Include="MainPage.xaml.cs">
|
||||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Pages\UserApi\RecentStations.xaml.cs">
|
||||||
|
<DependentUpon>RecentStations.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Properties\Annotations.cs" />
|
<Compile Include="Properties\Annotations.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Resources\AppResources.Designer.cs">
|
<Compile Include="Resources\AppResources.Designer.cs">
|
||||||
@ -119,6 +122,7 @@
|
|||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="ViewModels\PageProgress.cs" />
|
<Compile Include="ViewModels\PageProgress.cs" />
|
||||||
<Compile Include="ViewModels\TrackApi\ScrobblingTestViewModel.cs" />
|
<Compile Include="ViewModels\TrackApi\ScrobblingTestViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\UserApi\RecentStationsTestViewModel.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ApplicationDefinition Include="App.xaml">
|
<ApplicationDefinition Include="App.xaml">
|
||||||
@ -133,6 +137,10 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Include="Pages\UserApi\RecentStations.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
<Page Include="Pages\UserApi\History.xaml">
|
<Page Include="Pages\UserApi\History.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
<Button Content="Scrobbling" Click="OnScrobblingLinkClick"/>
|
<Button Content="Scrobbling" Click="OnScrobblingLinkClick"/>
|
||||||
<Button Content="History" Click="OnHistoryLinkClick"/>
|
<Button Content="History" Click="OnHistoryLinkClick"/>
|
||||||
|
<Button Content="Recent Stations" Click="OnRecentStationsLinkClick"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
@ -25,5 +25,10 @@ private void OnHistoryLinkClick(object sender, RoutedEventArgs e)
|
|||||||
{
|
{
|
||||||
NavigationService.Navigate(new Uri("/Pages/UserApi/History.xaml", UriKind.Relative));
|
NavigationService.Navigate(new Uri("/Pages/UserApi/History.xaml", UriKind.Relative));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnRecentStationsLinkClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
NavigationService.Navigate(new Uri("/Pages/UserApi/RecentStations.xaml", UriKind.Relative));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,8 +3,6 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Navigation;
|
|
||||||
using IF.Lastfm.Demo.Apollo.TestPages.ViewModels;
|
|
||||||
using IF.Lastfm.Demo.Apollo.ViewModels.UserApi;
|
using IF.Lastfm.Demo.Apollo.ViewModels.UserApi;
|
||||||
using Microsoft.Phone.Controls;
|
using Microsoft.Phone.Controls;
|
||||||
using Microsoft.Phone.Shell;
|
using Microsoft.Phone.Shell;
|
||||||
@ -36,32 +34,14 @@ private async void OnLoaded(object sender, RoutedEventArgs e)
|
|||||||
var element = VisualTreeHelper.GetChild(PageScroller, 0) as FrameworkElement;
|
var element = VisualTreeHelper.GetChild(PageScroller, 0) as FrameworkElement;
|
||||||
if (element != null)
|
if (element != null)
|
||||||
{
|
{
|
||||||
//var group = FindVisualState(element, "ScrollStates");
|
|
||||||
//if (group != null)
|
|
||||||
//{
|
|
||||||
// group.CurrentStateChanging += group_CurrentStateChanging;
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
var vgroup = FindVisualState(element, "VerticalCompression");
|
var vgroup = FindVisualState(element, "VerticalCompression");
|
||||||
if (vgroup != null)
|
if (vgroup != null)
|
||||||
{
|
{
|
||||||
vgroup.CurrentStateChanging += OnScrolled;
|
vgroup.CurrentStateChanging += OnScrolled;
|
||||||
}
|
}
|
||||||
|
|
||||||
//var hgroup = FindVisualState(element, "HorizontalCompression");
|
|
||||||
//if (hgroup != null)
|
|
||||||
//{
|
|
||||||
// hgroup.CurrentStateChanging += hgroup_CurrentStateChanging;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
|
||||||
{
|
|
||||||
base.OnNavigatedTo(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
|
private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.PropertyName == "InProgress")
|
if (e.PropertyName == "InProgress")
|
||||||
@ -92,39 +72,21 @@ private async void OnScrolled(object sender, VisualStateChangedEventArgs visualS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private UIElement FindElementRecursive(FrameworkElement parent, Type targetType)
|
|
||||||
{
|
|
||||||
int childCount = VisualTreeHelper.GetChildrenCount(parent);
|
|
||||||
UIElement returnElement = null;
|
|
||||||
if (childCount > 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < childCount; i++)
|
|
||||||
{
|
|
||||||
Object element = VisualTreeHelper.GetChild(parent, i);
|
|
||||||
if (element.GetType() == targetType)
|
|
||||||
{
|
|
||||||
return element as UIElement;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
returnElement = FindElementRecursive(VisualTreeHelper.GetChild(parent, i) as FrameworkElement,
|
|
||||||
targetType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return returnElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private VisualStateGroup FindVisualState(FrameworkElement element, string name)
|
private VisualStateGroup FindVisualState(FrameworkElement element, string name)
|
||||||
{
|
{
|
||||||
if (element == null)
|
if (element == null)
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
IList groups = VisualStateManager.GetVisualStateGroups(element);
|
IList groups = VisualStateManager.GetVisualStateGroups(element);
|
||||||
foreach (VisualStateGroup group in groups)
|
foreach (VisualStateGroup group in groups)
|
||||||
|
{
|
||||||
if (group.Name == name)
|
if (group.Name == name)
|
||||||
|
{
|
||||||
return group;
|
return group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
118
IF.Lastfm.Demo.Apollo/Pages/UserApi/RecentStations.xaml
Normal file
118
IF.Lastfm.Demo.Apollo/Pages/UserApi/RecentStations.xaml
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<phone:PhoneApplicationPage
|
||||||
|
x:Class="IF.Lastfm.Demo.Apollo.Pages.UserApi.RecentStations"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
|
||||||
|
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
|
||||||
|
xmlns:behaviors="clr-namespace:Cimbalino.Phone.Toolkit.Behaviors;assembly=Cimbalino.Phone.Toolkit"
|
||||||
|
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
|
||||||
|
xmlns:userApi="clr-namespace:IF.Lastfm.Demo.Apollo.ViewModels.UserApi"
|
||||||
|
FontFamily="{StaticResource PhoneFontFamilyNormal}"
|
||||||
|
FontSize="{StaticResource PhoneFontSizeNormal}"
|
||||||
|
Foreground="{StaticResource PhoneForegroundBrush}"
|
||||||
|
SupportedOrientations="Portrait" Orientation="Portrait"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
shell:SystemTray.IsVisible="True"
|
||||||
|
d:DataContext="{d:DesignInstance userApi:RecentStationsTestViewModel, IsDesignTimeCreatable=True}">
|
||||||
|
|
||||||
|
<phone:PhoneApplicationPage.Resources>
|
||||||
|
<Style x:Key="EndlessScrollerTemplate" TargetType="ScrollViewer">
|
||||||
|
<Setter Property="VerticalScrollBarVisibility" Value="Auto" />
|
||||||
|
<Setter Property="HorizontalScrollBarVisibility" Value="Auto" />
|
||||||
|
<Setter Property="Background" Value="Transparent" />
|
||||||
|
<Setter Property="Padding" Value="0" />
|
||||||
|
<Setter Property="BorderThickness" Value="0" />
|
||||||
|
<Setter Property="BorderBrush" Value="Transparent" />
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="ScrollViewer">
|
||||||
|
<Border BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
Background="{TemplateBinding Background}">
|
||||||
|
<VisualStateManager.VisualStateGroups>
|
||||||
|
<VisualStateGroup x:Name="ScrollStates">
|
||||||
|
<VisualStateGroup.Transitions>
|
||||||
|
<VisualTransition GeneratedDuration="00:00:00.5" />
|
||||||
|
</VisualStateGroup.Transitions>
|
||||||
|
<VisualState x:Name="Scrolling">
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="VerticalScrollBar"
|
||||||
|
Storyboard.TargetProperty="Opacity" To="1" Duration="0" />
|
||||||
|
<DoubleAnimation Storyboard.TargetName="HorizontalScrollBar"
|
||||||
|
Storyboard.TargetProperty="Opacity" To="1" Duration="0" />
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
<VisualState x:Name="NotScrolling">
|
||||||
|
</VisualState>
|
||||||
|
</VisualStateGroup>
|
||||||
|
<VisualStateGroup x:Name="VerticalCompression">
|
||||||
|
<VisualState x:Name="NoVerticalCompression" />
|
||||||
|
<VisualState x:Name="CompressionTop" />
|
||||||
|
<VisualState x:Name="CompressionBottom" />
|
||||||
|
</VisualStateGroup>
|
||||||
|
<VisualStateGroup x:Name="HorizontalCompression">
|
||||||
|
<VisualState x:Name="NoHorizontalCompression" />
|
||||||
|
<VisualState x:Name="CompressionLeft" />
|
||||||
|
<VisualState x:Name="CompressionRight" />
|
||||||
|
</VisualStateGroup>
|
||||||
|
</VisualStateManager.VisualStateGroups>
|
||||||
|
<Grid Margin="{TemplateBinding Padding}">
|
||||||
|
<ScrollContentPresenter x:Name="ScrollContentPresenter"
|
||||||
|
Content="{TemplateBinding Content}"
|
||||||
|
ContentTemplate="{TemplateBinding ContentTemplate}" />
|
||||||
|
<ScrollBar x:Name="VerticalScrollBar" IsHitTestVisible="False" Height="Auto" Width="5"
|
||||||
|
HorizontalAlignment="Right" VerticalAlignment="Stretch"
|
||||||
|
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
|
||||||
|
IsTabStop="False" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0"
|
||||||
|
Value="{TemplateBinding VerticalOffset}"
|
||||||
|
Orientation="Vertical" ViewportSize="{TemplateBinding ViewportHeight}" />
|
||||||
|
<ScrollBar x:Name="HorizontalScrollBar" IsHitTestVisible="False" Width="Auto"
|
||||||
|
Height="5"
|
||||||
|
HorizontalAlignment="Stretch" VerticalAlignment="Bottom"
|
||||||
|
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
|
||||||
|
IsTabStop="False" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0"
|
||||||
|
Value="{TemplateBinding HorizontalOffset}"
|
||||||
|
Orientation="Horizontal" ViewportSize="{TemplateBinding ViewportWidth}" />
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</phone:PhoneApplicationPage.Resources>
|
||||||
|
|
||||||
|
<Grid x:Name="LayoutRoot" Background="Transparent">
|
||||||
|
<ScrollViewer x:Name="PageScroller"
|
||||||
|
Style="{StaticResource EndlessScrollerTemplate}"
|
||||||
|
HorizontalScrollBarVisibility="Disabled"
|
||||||
|
VerticalAlignment="Stretch">
|
||||||
|
<StackPanel x:Name="ContentPanel"
|
||||||
|
Margin="12,17,12,0">
|
||||||
|
<TextBlock Text="LASTFM-WP DEMO APP"
|
||||||
|
Style="{StaticResource PhoneTextNormalStyle}"
|
||||||
|
Margin="12,0" />
|
||||||
|
<TextBlock Text="recent stations"
|
||||||
|
Margin="9,-7,0,12"
|
||||||
|
Style="{StaticResource PhoneTextTitle1Style}" />
|
||||||
|
<TextBlock Text="{Binding Auth.User.Username}"
|
||||||
|
Style="{StaticResource PhoneTextNormalStyle}"
|
||||||
|
Margin="12,0" />
|
||||||
|
|
||||||
|
<ItemsControl ItemsSource="{Binding Stations}">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel Margin="0,12">
|
||||||
|
<TextBlock Text="{Binding Name}"
|
||||||
|
Style="{StaticResource PhoneTextLargeStyle}" />
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</StackPanel>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</phone:PhoneApplicationPage>
|
92
IF.Lastfm.Demo.Apollo/Pages/UserApi/RecentStations.xaml.cs
Normal file
92
IF.Lastfm.Demo.Apollo/Pages/UserApi/RecentStations.xaml.cs
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using IF.Lastfm.Demo.Apollo.ViewModels.UserApi;
|
||||||
|
using Microsoft.Phone.Controls;
|
||||||
|
using Microsoft.Phone.Shell;
|
||||||
|
|
||||||
|
namespace IF.Lastfm.Demo.Apollo.Pages.UserApi
|
||||||
|
{
|
||||||
|
public partial class RecentStations : PhoneApplicationPage
|
||||||
|
{
|
||||||
|
private RecentStationsTestViewModel _viewModel;
|
||||||
|
|
||||||
|
public RecentStations()
|
||||||
|
{
|
||||||
|
_viewModel = new RecentStationsTestViewModel();
|
||||||
|
DataContext = _viewModel;
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
_viewModel.PropertyChanged += OnViewModelPropertyChanged;
|
||||||
|
Loaded += OnLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void OnLoaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
await _viewModel.NavigatedTo();
|
||||||
|
await _viewModel.GetRecentStations();
|
||||||
|
|
||||||
|
var element = VisualTreeHelper.GetChild(PageScroller, 0) as FrameworkElement;
|
||||||
|
if (element != null)
|
||||||
|
{
|
||||||
|
var vgroup = FindVisualState(element, "VerticalCompression");
|
||||||
|
if (vgroup != null)
|
||||||
|
{
|
||||||
|
vgroup.CurrentStateChanging += OnScrolled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.PropertyName == "InProgress")
|
||||||
|
{
|
||||||
|
if (_viewModel.InProgress)
|
||||||
|
{
|
||||||
|
SystemTray.ProgressIndicator = new ProgressIndicator
|
||||||
|
{
|
||||||
|
IsVisible = _viewModel.InProgress,
|
||||||
|
IsIndeterminate = _viewModel.InProgress
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SystemTray.ProgressIndicator = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void OnScrolled(object sender, VisualStateChangedEventArgs visualStateChangedEventArgs)
|
||||||
|
{
|
||||||
|
if (PageScroller.VerticalOffset >= PageScroller.ScrollableHeight - 10)
|
||||||
|
{
|
||||||
|
if (!_viewModel.InProgress)
|
||||||
|
{
|
||||||
|
await _viewModel.GetRecentStations();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private VisualStateGroup FindVisualState(FrameworkElement element, string name)
|
||||||
|
{
|
||||||
|
if (element == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var groups = VisualStateManager.GetVisualStateGroups(element);
|
||||||
|
foreach (VisualStateGroup group in groups)
|
||||||
|
{
|
||||||
|
if (group.Name == name)
|
||||||
|
{
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,121 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Cimbalino.Phone.Toolkit.Services;
|
||||||
|
using IF.Lastfm.Core.Api;
|
||||||
|
using IF.Lastfm.Core.Objects;
|
||||||
|
using IF.Lastfm.Demo.Apollo.TestPages.ViewModels;
|
||||||
|
|
||||||
|
namespace IF.Lastfm.Demo.Apollo.ViewModels.UserApi
|
||||||
|
{
|
||||||
|
public class RecentStationsTestViewModel : BaseViewModel
|
||||||
|
{
|
||||||
|
private Auth _auth;
|
||||||
|
private bool _inProgress;
|
||||||
|
private PageProgress _stationPageProgress;
|
||||||
|
private ObservableCollection<Station> _stations;
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
public Auth Auth
|
||||||
|
{
|
||||||
|
get { return _auth; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Equals(value, _auth))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_auth = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool InProgress
|
||||||
|
{
|
||||||
|
get { return _inProgress; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value.Equals(_inProgress))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_inProgress = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableCollection<Station> Stations
|
||||||
|
{
|
||||||
|
get { return _stations; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Equals(value, _stations)) return;
|
||||||
|
_stations = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public RecentStationsTestViewModel()
|
||||||
|
{
|
||||||
|
_stationPageProgress = new PageProgress();
|
||||||
|
Stations = new ObservableCollection<Station>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task NavigatedTo()
|
||||||
|
{
|
||||||
|
await Authenticate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Authenticate()
|
||||||
|
{
|
||||||
|
var appsettings = new ApplicationSettingsService();
|
||||||
|
|
||||||
|
var apikey = appsettings.Get<string>("apikey");
|
||||||
|
var apisecret = appsettings.Get<string>("apisecret");
|
||||||
|
var username = appsettings.Get<string>("username");
|
||||||
|
var pass = appsettings.Get<string>("pass");
|
||||||
|
|
||||||
|
var auth = new Auth(apikey, apisecret);
|
||||||
|
|
||||||
|
InProgress = true;
|
||||||
|
await auth.GetSessionTokenAsync(username, pass);
|
||||||
|
InProgress = false;
|
||||||
|
|
||||||
|
Auth = auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task GetRecentStations()
|
||||||
|
{
|
||||||
|
if (!_stationPageProgress.CanGoToNextPage())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InProgress = true;
|
||||||
|
|
||||||
|
var userApi = new Core.Api.UserApi(Auth);
|
||||||
|
|
||||||
|
var response = await userApi.GetRecentStations(_stationPageProgress.ExpectedPage, 5);
|
||||||
|
|
||||||
|
_stationPageProgress.PageLoaded(response.Success);
|
||||||
|
|
||||||
|
if (response.Success)
|
||||||
|
{
|
||||||
|
foreach (var s in response.Content)
|
||||||
|
{
|
||||||
|
Stations.Add(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_stationPageProgress.TotalPages = response.TotalPages;
|
||||||
|
|
||||||
|
InProgress = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user