2011-03-28 21:22:11 +03:00
parent a4c09735f0
commit 00f97e41d6
130 changed files with 13440 additions and 0 deletions
@@ -0,0 +1,79 @@
<UserControl x:Class="WindowsPhone.Recipes.Push.Client.Views.InboxView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tk="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480">
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Views">
<VisualState x:Name="NormalView" />
<VisualState x:Name="ScheduleView">
<Storyboard>
<ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="TileScheduleView" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition Height="120"/>
<RowDefinition Height="120"/>
<RowDefinition Height="60"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel d:LayoutOverrides="Height">
<TextBlock Margin="12,12,0,0" Text="Active Push Pattern" FontSize="24" />
<ListBox ItemsSource="{Binding PushPatterns}"
IsHitTestVisible="False"
SelectedItem="{Binding PushPattern, Mode=TwoWay}"
ItemsPanel="{StaticResource ItemsPanelTemplate}"
ItemContainerStyle="{StaticResource PatternListBoxItemStyle}"
HorizontalAlignment="Center">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"
TextWrapping="Wrap"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextAlignment="Center" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
<StackPanel Grid.Row="1" d:LayoutOverrides="Height">
<TextBlock Margin="12,12,0,0" Text="Counter (if relevant)" FontSize="24" />
<TextBlock Margin="12,12,0,0" Text="{Binding Counter}" Foreground="LightBlue" />
</StackPanel>
<TextBlock Margin="12,12,0,17" Text="Raw Messages (last on top)" Grid.Row="2" d:LayoutOverrides="Height" FontSize="24" />
<ListBox ItemsSource="{Binding RawMessages}" Grid.Row="4" Margin="12,0,12,80"/>
<Border x:Name="TileScheduleView"
Grid.Row="1" Grid.RowSpan="3"
Visibility="Collapsed"
Background="{StaticResource PhoneChromeBrush}">
<StackPanel>
<TextBlock Margin="12,12,0,17" Text="Tile Image (located on server)" Grid.Row="2" d:LayoutOverrides="Height" FontSize="24" />
<ListBox ItemsSource="{Binding ServerImages}"
SelectedItem="{Binding SelectedServerImage, Mode=TwoWay}"
Margin="12,0,12,0" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Content="Schedule" Click="ButtonSchedule_Click" />
<Button Content="Test Now" Click="ButtonTestNow_Click" Grid.Column="1" />
</Grid>
</StackPanel>
</Border>
</Grid>
</UserControl>
@@ -0,0 +1,275 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Collections.ObjectModel;
using System.Threading;
using Microsoft.Phone.Shell;
using Microsoft.Phone.Notification;
using WindowsPhone.Recipes.Push.Client.Services;
using WindowsPhone.Recipes.Push.Client.Controls;
namespace WindowsPhone.Recipes.Push.Client.Views
{
public partial class InboxView : UserControl
{
#region Fields
/// <value>Url of the GetTileImage REST service.</value>
private static readonly string GetTileImageService = App.ServerAddress + "/ImageService/GetTileImage?uri={0}";
private readonly ObservableCollection<string> _rawMessages = new ObservableCollection<string>();
private ShellTileSchedule _tileSchedule;
#endregion
#region Properties
public ObservableCollection<string> RawMessages
{
get { return _rawMessages; }
}
public IEnumerable<string> ServerImages
{
get
{
return new string[]
{
"number0.png",
"number1.png",
"number2.png",
"number3.png",
"number4.png",
"number5.png",
"number6.png",
"number7.png",
"number8.png",
"number9.png"
};
}
}
public string SelectedServerImage
{
get { return (string)GetValue(SelectedServerImageProperty); }
set { SetValue(SelectedServerImageProperty, value); }
}
// Using a DependencyProperty as the backing store for SelectedServerImage. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedServerImageProperty =
DependencyProperty.Register(
"SelectedServerImage",
typeof(string),
typeof(InboxView),
new PropertyMetadata("number0.png"));
public IEnumerable<string> PushPatterns
{
get { return new string[] { "One Time", "Counter", "Ask to Pin", "Custom Tile", "Tile Schedule" }; }
}
public string PushPattern
{
get { return (string)GetValue(PushPatternProperty); }
set { SetValue(PushPatternProperty, value); }
}
// Using a DependencyProperty as the backing store for PushPattern. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PushPatternProperty =
DependencyProperty.Register(
"PushPattern",
typeof(string),
typeof(InboxView),
new PropertyMetadata(null, PushPatternChanged));
private static void PushPatternChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var view = d as InboxView;
if ("Tile Schedule".CompareTo(e.NewValue) == 0)
{
VisualStateManager.GoToState(view, "ScheduleView", false);
}
else
{
VisualStateManager.GoToState(view, "NormalView", false);
}
}
public int Counter
{
get { return (int)GetValue(CounterProperty); }
set { SetValue(CounterProperty, value); }
}
// Using a DependencyProperty as the backing store for Counter. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CounterProperty =
DependencyProperty.Register(
"Counter",
typeof(int),
typeof(InboxView),
new PropertyMetadata(0));
public string TileScheduleParameter
{
get { return (string)GetValue(TileScheduleParameterProperty); }
set { SetValue(TileScheduleParameterProperty, value); }
}
// Using a DependencyProperty as the backing store for TileScheduleParameter. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TileScheduleParameterProperty =
DependencyProperty.Register(
"TileScheduleParameter",
typeof(string),
typeof(InboxView),
new PropertyMetadata("number0.png"));
#endregion
public InboxView()
{
DataContext = this;
InitializeComponent();
Loaded += InboxView_Loaded;
Unloaded += InboxView_Unloaded;
UpdateServerInfo();
}
private void InboxView_Unloaded(object sender, RoutedEventArgs e)
{
UnregisterRawNotification();
}
private void InboxView_Loaded(object sender, RoutedEventArgs e)
{
RegisterRawNotification();
}
private void UpdateServerInfo()
{
try
{
var pushService = new PushServiceClient();
pushService.GetServerInfoCompleted += (s1, e1) =>
{
try
{
pushService.CloseAsync();
if (e1.Result != null)
{
Dispatcher.BeginInvoke(() =>
{
PushPattern = e1.Result.PushPattern;
Counter = e1.Result.Counter;
});
}
}
catch (Exception ex)
{
ex.Show();
}
};
pushService.GetServerInfoAsync();
}
catch (Exception ex)
{
ex.Show();
}
}
private void RegisterRawNotification()
{
var context = PushContext.Current;
if (context != null)
{
context.RawNotification += context_RawNotification;
}
}
private void UnregisterRawNotification()
{
var context = PushContext.Current;
if (context != null)
{
context.RawNotification -= context_RawNotification;
}
}
private void context_RawNotification(object sender, HttpNotificationEventArgs e)
{
try
{
using (var stream = new StreamReader(e.Notification.Body))
{
var rawMessage = stream.ReadToEnd();
_rawMessages.Insert(0, rawMessage);
if ("AskToPin".CompareTo(rawMessage) == 0)
{
AskToPin();
}
UpdateServerInfo();
}
}
catch (Exception ex)
{
ex.Show();
}
}
private void AskToPin()
{
NotificationBox.Show("Important", "Please pin your application to Start Screen so this application can work properly.");
}
private void ButtonSchedule_Click(object sender, RoutedEventArgs e)
{
_tileSchedule = new ShellTileSchedule();
_tileSchedule.Recurrence = UpdateRecurrence.Interval;
_tileSchedule.StartTime = DateTime.Now;
_tileSchedule.Interval = UpdateInterval.EveryHour;
_tileSchedule.RemoteImageUri = new Uri(string.Format(GetTileImageService, TileScheduleParameter));
_tileSchedule.Start();
}
private void ButtonTestNow_Click(object sender, RoutedEventArgs e)
{
try
{
var pushService = new PushServiceClient();
pushService.UpdateTileCompleted += (s1, e1) =>
{
try
{
pushService.CloseAsync();
}
catch (Exception ex)
{
ex.Show();
}
};
pushService.UpdateTileAsync(PushContext.Current.NotificationChannel.ChannelUri, SelectedServerImage);
}
catch (Exception ex)
{
ex.Show();
}
}
}
}
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindowsPhone.Recipes.Push.Client.Views
{
public class LoginEventArgs : EventArgs
{
public Exception Exception { get; private set; }
public LoginEventArgs(Exception exception = null)
{
Exception = exception;
}
}
}
@@ -0,0 +1,16 @@
<UserControl x:Class="WindowsPhone.Recipes.Push.Client.Views.PushSettingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:WindowsPhone.Recipes.Push.Client.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="628" d:DesignWidth="480">
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<my:PushSettingsControl x:Name="settingsControl" />
</Grid>
</UserControl>
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace WindowsPhone.Recipes.Push.Client.Views
{
public partial class PushSettingsView : UserControl
{
public PushSettingsView()
{
InitializeComponent();
}
}
}
@@ -0,0 +1,26 @@
<UserControl x:Class="WindowsPhone.Recipes.Push.Client.Views.UserLoginView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
xmlns:my="clr-namespace:WindowsPhone.Recipes.Push.Client.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480">
<!--ContentPanel - place additional content here-->
<Grid x:Name="LayoutRoot">
<my:ProgressBarWithText x:Name="progress" Margin="0,-40,0,0" Text="Login..." FontSize="24" ShowProgress="True" Visibility="Collapsed" />
<StackPanel x:Name="login" Visibility="Collapsed">
<StackPanel>
<TextBlock Text="User Name" />
<TextBox x:Name="textBoxUserName" Text="{Binding UserName, Mode=TwoWay}" />
</StackPanel>
<Button x:Name="buttonLogin" Content="Login" Click="ButtonLogin_Click" />
</StackPanel>
</Grid>
</UserControl>
@@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO.IsolatedStorage;
using WindowsPhone.Recipes.Push.Client.Services;
using System.Threading;
namespace WindowsPhone.Recipes.Push.Client.Views
{
public partial class UserLoginView : UserControl
{
#region Fields
private readonly IsolatedStorageSettings Settings = IsolatedStorageSettings.ApplicationSettings;
#endregion
#region Properties
public string UserName { get; set; }
#endregion
#region Events
public event EventHandler<LoginEventArgs> Login;
#endregion
public UserLoginView()
{
DataContext = this;
InitializeComponent();
Loaded += UserLoginView_Loaded;
}
private void UserLoginView_Loaded(object sender, RoutedEventArgs e)
{
string userName;
if (!Settings.TryGetValue("LoginPage.UserName", out userName))
{
login.Visibility = Visibility.Visible;
}
else
{
UserName = userName;
InternalLogin();
}
}
private void ButtonLogin_Click(object sender, RoutedEventArgs args)
{
Settings["LoginPage.UserName"] = UserName;
login.Visibility = Visibility.Collapsed;
InternalLogin();
}
private void OnLogin(LoginEventArgs args)
{
if (Login != null)
{
Login(this, args);
}
}
private void InternalLogin()
{
login.Visibility = Visibility.Collapsed;
progress.Visibility = Visibility.Visible;
var pushContext = PushContext.Current;
pushContext.Connect(c => RegisterClient(c.ChannelUri));
}
private void RegisterClient(Uri channelUri)
{
// Register the URI with 3rd party web service.
try
{
var pushService = new PushServiceClient();
pushService.RegisterCompleted += (s, e) =>
{
pushService.CloseAsync();
Completed(e.Error);
};
pushService.RegisterAsync(UserName, channelUri);
}
catch (Exception ex)
{
Completed(ex);
}
}
private void Completed(Exception ex)
{
login.Visibility = Visibility.Visible;
progress.Visibility = Visibility.Collapsed;
Dispatcher.BeginInvoke(() => OnLogin(new LoginEventArgs(ex)));
}
}
}