offline images

friends list / select
friend distance
This commit is contained in:
2011-04-05 00:40:21 +03:00
parent f79ee0adc2
commit bf599907dc
23 changed files with 1099 additions and 348 deletions
+3 -4
View File
@@ -10,15 +10,14 @@
xmlns:my="clr-namespace:Coding4Fun.Phone.Controls.Converters;assembly=Coding4Fun.Phone.Controls"
xmlns:my1="clr-namespace:Microsoft.Silverlight.Testing.Client;assembly=Microsoft.Silverlight.Testing"
xmlns:Controls="clr-namespace:Coding4Fun.Phone.Controls;assembly=Coding4Fun.Phone.Controls"
xmlns:Views="clr-namespace:MyFriendsAround.WP7.Views">
xmlns:Views="clr-namespace:MyFriendsAround.WP7.Views" xmlns:ImageCacherDemo="clr-namespace:WPImageCaching;assembly=WPImageCaching">
<!--Application Resources-->
<Application.Resources>
<vm:ViewModelLocator x:Key="Locator"
d:IsDataSource="True" />
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
<my:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter1" />
<my1:InvertValueConverter x:Key="InvertValueConverter1" />
<ImageCacherDemo:ImageCacheConverter x:Key="imageCacheConverter" />
</Application.Resources>
<Application.ApplicationLifetimeObjects>
+7 -9
View File
@@ -90,7 +90,7 @@ namespace MyFriendsAround.WP7
{
SaveModel();
//
ViewModelLocator locator = Container.Instance.Resolve<ViewModelLocator>();
ViewModelLocator locator = Container.Instance.Resolve<ViewModelLocator>("ViewModelLocator");
locator.Cleanup();
}
@@ -101,24 +101,22 @@ namespace MyFriendsAround.WP7
MainViewModel mainModel = this.RetrieveFromIsolatedStorage<MainViewModel>();
if (mainModel != null)
{
mainModel.IsLoaded = true;
mainModel.IsBusy = false;
Container.Instance.RegisterInstance<MainViewModel>(mainModel, "MainViewModel");
Container.Instance.RegisterInstance<MainViewModel>(mainModel, Constants.VM_MAIN);
}
else
{
Container.Instance.RegisterInstance<MainViewModel>(new MainViewModel(), "MainViewModel");
Container.Instance.RegisterInstance<MainViewModel>(new MainViewModel(), Constants.VM_MAIN);
}
//
SettingsViewModel settingsModel = this.RetrieveFromIsolatedStorage<SettingsViewModel>();
if (settingsModel != null)
{
settingsModel.IsLoaded = true;
Container.Instance.RegisterInstance<SettingsViewModel>(settingsModel, "SettingsViewModel");
Container.Instance.RegisterInstance<SettingsViewModel>(settingsModel, Constants.VM_SETTINGS);
}
else
{
Container.Instance.RegisterInstance<SettingsViewModel>(new SettingsViewModel(), "SettingsViewModel");
Container.Instance.RegisterInstance<SettingsViewModel>(new SettingsViewModel(), Constants.VM_SETTINGS);
}
}
@@ -126,8 +124,8 @@ namespace MyFriendsAround.WP7
private void SaveModel()
{
this.SaveToIsolatedStorage<MainViewModel>(Container.Instance.Resolve<MainViewModel>("MainViewModel"));
this.SaveToIsolatedStorage<SettingsViewModel>(Container.Instance.Resolve<SettingsViewModel>("SettingsViewModel"));
this.SaveToIsolatedStorage<MainViewModel>(Container.Instance.Resolve<MainViewModel>(Constants.VM_MAIN));
this.SaveToIsolatedStorage<SettingsViewModel>(Container.Instance.Resolve<SettingsViewModel>(Constants.VM_SETTINGS));
}
@@ -0,0 +1,52 @@
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;
using MyFriendsAround.WP7.Utils;
using System.IO;
namespace MyFriendsAround.WP7.Helpers.Converters
{
public class MyImageConverter : IValueConverter
{
private static BitmapImage anonymousBitmap =
new BitmapImage(new Uri("/icons/anonymousIcon.png", UriKind.RelativeOrAbsolute));
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string imageName = value.ToString();
if (!string.IsNullOrEmpty(imageName))
{
string[] res = imageName.Split('?');
byte[] img = IsolatedStorageHelper.LoadFromLocalStorageArray(res[0], "profiles");
if (img != null)
{
BitmapImage bi = new BitmapImage();
using (MemoryStream ms = new MemoryStream(img))
{
bi.SetSource(ms);
}
return bi;
}
}
return anonymousBitmap;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
}
@@ -157,6 +157,7 @@
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="Helpers\Converters\MyImageConverter.cs" />
<Compile Include="Helpers\Navigation\IPageNavigation.cs" />
<Compile Include="Helpers\Navigation\PageNavigation.cs" />
<Compile Include="Service\ILocationService.cs" />
@@ -165,6 +166,8 @@
<Compile Include="Service\LocationService.cs" />
<Compile Include="Service\LocationStatusEventArgs.cs" />
<Compile Include="Utils\ApplicationExtensions.cs" />
<Compile Include="Utils\Constants.cs" />
<Compile Include="Utils\Haversine.cs" />
<Compile Include="Utils\IsolatedStorageHelper.cs" />
<Compile Include="Utils\LittleWatson.cs">
<SubType>Code</SubType>
@@ -280,6 +283,10 @@
<Project>{B55A0F90-2B5A-4C4B-88F4-013AA1629866}</Project>
<Name>Phone7.Fx.Preview</Name>
</ProjectReference>
<ProjectReference Include="..\Libs\WPImageCaching\WPImageCaching.csproj">
<Project>{17158FD9-80FD-49C1-9E3F-C5633602A4D9}</Project>
<Name>WPImageCaching</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
@@ -11,13 +11,13 @@ namespace MyFriendsAround.WP7.Service
public static class ServiceAgent
{
private static int _timeOut = 10;
private static int _timeOut = 15;
public static string baseUrl;
static ServiceAgent()
{
//baseUrl = "http://myfriendsaround.cloudapp.net/myfriends";//live azure
baseUrl = "http://127.0.0.1:82/myfriends";//running in local azure emulator
baseUrl = "http://myfriendsaround.cloudapp.net/myfriends";//live azure
//baseUrl = "http://127.0.0.1:80/myfriends";//running in local azure emulator
//baseUrl = "http://localhost.:55672/myfriends";//for local asp.net mvc use
}
@@ -0,0 +1,21 @@
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace MyFriendsAround.WP7.Utils
{
public class Constants
{
public const string MYPICTURE_FILE_NAME = "myphoto.jpg";
//viewmodels names
public const string VM_MAIN = "MainViewModel";
public const string VM_SETTINGS = "SettingsViewModel";
}
}
@@ -0,0 +1,60 @@
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace MyFriendsAround.WP7.Utils
{
/// <summary>
/// The distance type to return the results in.
/// </summary>
public enum DistanceType { Miles, Kilometers };
/// <summary>
/// Specifies a Latitude / Longitude point.
/// </summary>
public struct Position
{
public double Latitude;
public double Longitude;
}
public class Haversine
{
/// <summary>
/// Returns the distance in miles or kilometers of any two
/// latitude / longitude points.
/// </summary>
/// <param name=”pos1″></param>
/// <param name=”pos2″></param>
/// <param name=”type”></param>
/// <returns></returns>
public static double Distance(Position pos1, Position pos2, DistanceType type)
{
double R = (type == DistanceType.Miles) ? 3960 : 6371;
double dLat = toRadian(pos2.Latitude - pos1.Latitude);
double dLon = toRadian(pos2.Longitude - pos1.Longitude);
double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
Math.Cos(toRadian(pos1.Latitude)) * Math.Cos(toRadian(pos2.Latitude)) *
Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
double c = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)));
double d = R * c;
return d;
}
/// <summary>
/// Convert to Radians.
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
private static double toRadian(double val)
{
return (Math.PI / 180) * val;
}
}
}
@@ -60,7 +60,6 @@ namespace MyFriendsAround.WP7.ViewModel
//
MainLoadCommand = new RelayCommand(() => MainLoad());
PublishLocationCommand = new RelayCommand(() => PublishLocationAction());
DisplayAboutCommand = new RelayCommand(() => DisplayAbout());
NavigateToSettingsCommand = new RelayCommand(() => NavigateToSettings());
RefreshFriendsCommand = new RelayCommand(() => RefreshFriends());
ShowAboutCommand = new RelayCommand(() => ShowAbout());
@@ -73,6 +72,7 @@ namespace MyFriendsAround.WP7.ViewModel
ShowMyLocationCommand = new RelayCommand(() => ShowMyLocation());
MapZoomInCommand = new RelayCommand(() => MapZoomIn());
MapZoomOutCommand = new RelayCommand(() => MapZoomOut());
ShowSelectFriendCommand = new RelayCommand(() => ShowSelectFriend());
if (IsInDesignMode)
{
@@ -93,91 +93,11 @@ namespace MyFriendsAround.WP7.ViewModel
InitGps();
}
private void MapZoomOut()
private void ShowSelectFriend()
{
//
if(MapZoom<22)
{
MapZoom++;
}
}
private void MapZoomIn()
{
//
if (MapZoom >2 )
{
MapZoom--;
}
}
private void InitGps()
{
App.LocationService.LocationChanged += new EventHandler<LocationChangedEventArgs>(LocationService_LocationChanged);
App.LocationService.StatusChanged += new EventHandler<LocationStatusEventArgs>(LocationService_StatusChanged);
App.LocationService.Start();
}
void LocationService_StatusChanged(object sender, LocationStatusEventArgs e)
{
GpsStatus = e.Status;
}
void LocationService_LocationChanged(object sender, LocationChangedEventArgs e)
{
if (e.Location != Location.Unknown)
{
GpsLocation = e.Location;
if (LastBoundRect!= null && LastBoundRect.Intersects(new LocationRect(
new GeoCoordinate(GpsLocation.Latitude, GpsLocation.Longitude),
.5,
.5)))
{
ObservableCollection<PushPinModel> _mynewlocation = new ObservableCollection<PushPinModel>();
_mynewlocation.Add(new PushPinModel()
{
Location = new GeoCoordinate(GpsLocation.Latitude, GpsLocation.Longitude),
PinUserName = "Me"
});
MyLocationPushPins = _mynewlocation;
}
else
{
MyLocationPushPins = new ObservableCollection<PushPinModel>();
}
}
System.Diagnostics.Debug.WriteLine("watcher_PositionChanged + " + DateTime.Now.Second);
}
void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
if (e.Position.Location != GeoCoordinate.Unknown)
{
GpsLocation = new Location(
e.Position.Location.Latitude,
e.Position.Location.Longitude,
e.Position.Timestamp);
if (LastBoundRect!=null && LastBoundRect.Intersects(new LocationRect(e.Position.Location, .5, .5)))
{
ObservableCollection<PushPinModel> _mynewlocation = new ObservableCollection<PushPinModel>();
_mynewlocation.Add(new PushPinModel()
{
Location = new GeoCoordinate(GpsLocation.Latitude, GpsLocation.Longitude),
PinUserName = "Me"
});
MyLocationPushPins = _mynewlocation;
}
else
{
MyLocationPushPins = new ObservableCollection<PushPinModel>();
}
}
System.Diagnostics.Debug.WriteLine("watcher_PositionChanged + " + DateTime.Now.Second);
IsSelectFriend = true;
}
@@ -187,6 +107,8 @@ namespace MyFriendsAround.WP7.ViewModel
#region Properties & Fields
private LocationRect LastBoundRect = null;
private PhotoChooserTask photoChooserTask;
public string ApplicationTitle
@@ -226,133 +148,7 @@ namespace MyFriendsAround.WP7.ViewModel
#endregion
/// <summary>
/// The <see cref="GpsLocation" /> property's name.
/// </summary>
public const string GpsLocationPropertyName = "GpsLocation";
private Location _gpsLocation = Location.Unknown;
/// <summary>
/// Gets the GpsLocation property.
/// </summary>
public Location GpsLocation
{
get
{
return _gpsLocation;
}
set
{
if (_gpsLocation == value)
{
return;
}
_gpsLocation = value;
// Update bindings, no broadcast
RaisePropertyChanged(GpsLocationPropertyName);
}
}
/// <summary>
/// The <see cref="GpsStatus" /> property's name.
/// </summary>
public const string GpsStatusPropertyName = "GpsStatus";
private GeoPositionStatus _gpsStatus = GeoPositionStatus.Disabled;
/// <summary>
/// Gets the GpsStatus property.
/// </summary>
public GeoPositionStatus GpsStatus
{
get
{
return _gpsStatus;
}
set
{
if (_gpsStatus == value)
{
return;
}
_gpsStatus = value;
// Update bindings, no broadcast
RaisePropertyChanged(GpsStatusPropertyName);
}
}
/// <summary>
/// The <see cref="MyPicture" /> property's name.
/// </summary>
public const string MyPicturePropertyName = "MyPicture";
private ImageSource _myPicture = new BitmapImage(new Uri("/icons/anonymousIcon.png", UriKind.RelativeOrAbsolute));
/// <summary>
/// Gets the MyPicture property.
/// </summary>
public ImageSource MyPicture
{
get
{
return _myPicture;
}
set
{
if (_myPicture == value)
{
return;
}
_myPicture = value;
// Update bindings, no broadcast
RaisePropertyChanged(MyPicturePropertyName);
}
}
/// <summary>
/// The <see cref="MyName" /> property's name.
/// </summary>
public const string MyNamePropertyName = "MyName";
private string _myName = "Guest";
/// <summary>
/// Gets the MyName property.
/// </summary>
public string MyName
{
get { return _myName; }
set
{
if (_myName == value)
{
return;
}
var oldValue = _myName;
_myName = value;
// Update bindings, no broadcast
RaisePropertyChanged(MyNamePropertyName);
}
}
#region AppBarText
public string AppBarTextAbout
{
@@ -389,6 +185,220 @@ namespace MyFriendsAround.WP7.ViewModel
get { return "Cancel"; }
}
#endregion
/// <summary>
/// The <see cref="SelectedFriend" /> property's name.
/// </summary>
public const string SelectedFriendPropertyName = "SelectedFriend";
private PushPinModel _SelectedFriend = new PushPinModel()
{
Location = GeoCoordinate.Unknown,
PinUserName = "Guest",
PinImageUrl = string.Empty
};
/// <summary>
/// Gets the SelectedFriend property.
/// </summary>
public PushPinModel SelectedFriend
{
get
{
return _SelectedFriend;
}
set
{
IsSelectFriend = false;
if (_SelectedFriend == value)
{
return;
}
_SelectedFriend = value;
if (_SelectedFriend != null && _SelectedFriend.Location!=GeoCoordinate.Unknown)
MapCenter = _SelectedFriend.Location;
// Update bindings, no broadcast
RaisePropertyChanged(SelectedFriendPropertyName);
}
}
/// <summary>
/// The <see cref="IsSelectFriend" /> property's name.
/// </summary>
public const string IsSelectFriendPropertyName = "IsSelectFriend";
private bool _isSelectFriend = false;
/// <summary>
/// Gets the IsSelectFriend property.
/// </summary>
public bool IsSelectFriend
{
get
{
return _isSelectFriend;
}
set
{
if (_isSelectFriend == value)
{
return;
}
_isSelectFriend = value;
// Update bindings, no broadcast
RaisePropertyChanged(IsSelectFriendPropertyName);
}
}
/// <summary>
/// The <see cref="GpsLocation" /> property's name.
/// </summary>
public const string GpsLocationPropertyName = "GpsLocation";
private Location _gpsLocation = Location.Unknown;
/// <summary>
/// Gets the GpsLocation property.
/// </summary>
public Location GpsLocation
{
get
{
return _gpsLocation;
}
set
{
if (_gpsLocation == value)
{
return;
}
_gpsLocation = value;
// Update bindings, no broadcast
RaisePropertyChanged(GpsLocationPropertyName);
UpdateDistances();
}
}
private void UpdateDistances()
{
foreach (var pushPin in PushPins)
{
pushPin.PinDistance =
(GpsLocation != Location.Unknown)
? Haversine.Distance(
new Position()
{Latitude = pushPin.Location.Latitude, Longitude = pushPin.Location.Longitude},
new Position() {Latitude = GpsLocation.Latitude, Longitude = GpsLocation.Longitude},
DistanceType.Kilometers)
: 0;
}
}
/// <summary>
/// The <see cref="GpsStatus" /> property's name.
/// </summary>
public const string GpsStatusPropertyName = "GpsStatus";
private GeoPositionStatus _gpsStatus = GeoPositionStatus.Disabled;
/// <summary>
/// Gets the GpsStatus property.
/// </summary>
public GeoPositionStatus GpsStatus
{
get
{
return _gpsStatus;
}
set
{
if (_gpsStatus == value)
{
return;
}
_gpsStatus = value;
// Update bindings, no broadcast
RaisePropertyChanged(GpsStatusPropertyName);
}
}
/// <summary>
/// The <see cref="MyPicture" /> property's name.
/// </summary>
public const string MyPicturePropertyName = "MyPicture";
private string _myPicture = Constants.MYPICTURE_FILE_NAME;
/// <summary>
/// Gets the MyPicture property.
/// </summary>
public string MyPicture
{
get
{
return _myPicture;
}
set
{
if (_myPicture == value)
{
return;
}
_myPicture = value;
// Update bindings, no broadcast
RaisePropertyChanged(MyPicturePropertyName);
}
}
/// <summary>
/// The <see cref="MyName" /> property's name.
/// </summary>
public const string MyNamePropertyName = "MyName";
private string _myName = "Guest";
/// <summary>
/// Gets the MyName property.
/// </summary>
public string MyName
{
get { return _myName; }
set
{
if (_myName == value)
{
return;
}
_myName = value;
// Update bindings, no broadcast
RaisePropertyChanged(MyNamePropertyName);
}
}
/// <summary>
/// The <see cref="PushPins" /> property's name.
/// </summary>
@@ -401,6 +411,23 @@ namespace MyFriendsAround.WP7.ViewModel
{
get
{
if (IsInDesignMode)
{
ObservableCollection<PushPinModel> _testlist = new ObservableCollection<PushPinModel>();
_testlist.Add(new PushPinModel()
{
Location = new GeoCoordinate(10, 10),
PinUserName = "User1",
PinImageUrl = "http://www.clker.com/cliparts/b/1/f/a/1195445301811339265dagobert83_female_user_icon.svg.thumb.png"
});
_testlist.Add(new PushPinModel()
{
Location = new GeoCoordinate(20, 20),
PinUserName = "User2",
PinImageUrl = "http://www.spanishseo.org/files/avatar_selection/user.png"
});
return _testlist;
}
return _PushPins;
}
@@ -415,6 +442,8 @@ namespace MyFriendsAround.WP7.ViewModel
// Update bindings, no broadcast
RaisePropertyChanged(PushPinsPropertyName);
//
RefreshVisiblePushPins();
}
}
@@ -427,6 +456,7 @@ namespace MyFriendsAround.WP7.ViewModel
/// <summary>
/// Gets the VisiblePushPins property.
/// </summary>
[JsonIgnore]
public ObservableCollection<PushPinModel> VisiblePushPins
{
get
@@ -581,11 +611,12 @@ namespace MyFriendsAround.WP7.ViewModel
#endregion
#region Commands
public ICommand MainLoadCommand { get; set; }
public ICommand PublishLocationCommand { get; set; }
public ICommand DisplayAboutCommand { get; set; }
public ICommand NavigateToSettingsCommand { get; set; }
public ICommand ShowMyLocationCommand { get; set; }
public ICommand RefreshFriendsCommand { get; set; }
@@ -598,11 +629,75 @@ namespace MyFriendsAround.WP7.ViewModel
public ICommand MapViewChangedCommand { get; set; }
public ICommand MapZoomInCommand { get; set; }
public ICommand MapZoomOutCommand { get; set; }
public ICommand ShowSelectFriendCommand { get; set; }
#endregion
#region Implemented Commands & Methods
private void MapZoomOut()
{
//
if (MapZoom < 22)
{
MapZoom++;
}
}
private void MapZoomIn()
{
//
if (MapZoom > 2)
{
MapZoom--;
}
}
private void InitGps()
{
App.LocationService.LocationChanged += LocationService_LocationChanged;
App.LocationService.StatusChanged += LocationService_StatusChanged;
App.LocationService.Start();
}
private void LocationService_StatusChanged(object sender, LocationStatusEventArgs e)
{
GpsStatus = e.Status;
}
private void LocationService_LocationChanged(object sender, LocationChangedEventArgs e)
{
if (e.Location != Location.Unknown)
{
GpsLocation = e.Location;
if (LastBoundRect != null && LastBoundRect.Intersects(new LocationRect(
new GeoCoordinate(GpsLocation.Latitude, GpsLocation.Longitude),
.5,
.5)))
{
ObservableCollection<PushPinModel> _mynewlocation = new ObservableCollection<PushPinModel>();
_mynewlocation.Add(new PushPinModel()
{
Location = new GeoCoordinate(GpsLocation.Latitude, GpsLocation.Longitude),
PinUserName = "Me"
});
MyLocationPushPins = _mynewlocation;
}
else
{
MyLocationPushPins = new ObservableCollection<PushPinModel>();
}
}
System.Diagnostics.Debug.WriteLine("watcher_PositionChanged + " + DateTime.Now.Second);
}
private void ShowMyLocation()
{
//
@@ -614,32 +709,52 @@ namespace MyFriendsAround.WP7.ViewModel
}
}
private LocationRect LastBoundRect = null;
private void MapViewChanged(LocationRect boundRectangle)
{
LastBoundRect = boundRectangle;
//
RefreshVisiblePushPins();
//
RefreshMyLocation();
}
private void RefreshMyLocation()
{
if (GpsLocation == Location.Unknown ||
LastBoundRect == null ||
!LastBoundRect.Intersects(new LocationRect(
new GeoCoordinate(GpsLocation.Latitude, GpsLocation.Longitude),
.5, .5)))
{
MyLocationPushPins = new ObservableCollection<PushPinModel>();
}
else
{
ObservableCollection<PushPinModel> _mynewlocation = new ObservableCollection<PushPinModel>();
_mynewlocation.Add(new PushPinModel()
{
Location = new GeoCoordinate(GpsLocation.Latitude, GpsLocation.Longitude),
PinUserName = "Me"
});
MyLocationPushPins = _mynewlocation;
}
}
private void RefreshVisiblePushPins()
{
ObservableCollection<PushPinModel> _newVisiblePushPins = new ObservableCollection<PushPinModel>();
//filter visible pushpins
foreach (PushPinModel pushPin in PushPins)
{
if (LastBoundRect!=null && LastBoundRect.Intersects(new LocationRect(
new GeoCoordinate(pushPin.Location.Latitude, pushPin.Location.Longitude),
.5, .5)))
if (LastBoundRect != null && LastBoundRect.Intersects(new LocationRect(
new GeoCoordinate(pushPin.Location.Latitude, pushPin.Location.Longitude),
.5, .5)))
{
_newVisiblePushPins.Add(pushPin);
}
}
VisiblePushPins = _newVisiblePushPins;
//
if (GpsLocation == Location.Unknown ||
LastBoundRect == null ||
!LastBoundRect.Intersects(new LocationRect(
new GeoCoordinate(GpsLocation.Latitude, GpsLocation.Longitude),
.5, .5)))
{
MyLocationPushPins = new ObservableCollection<PushPinModel>();
}
}
public void CropCancel()
@@ -656,38 +771,11 @@ namespace MyFriendsAround.WP7.ViewModel
private void MainLoad()
{
if (IsLoaded)
{
//
ThreadPool.QueueUserWorkItem(LoadMyPicture);
//
IsLoaded = false;
}
}
private void LoadMyPicture(object param) //Background thread
{
Thread.Sleep(500);
byte[] img = IsolatedStorageHelper.LoadFromLocalStorageArray("myphoto.jpg", "profiles");
if (img != null)
{
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
using (MemoryStream ms = new MemoryStream(img))
{
BitmapImage bi = new BitmapImage();
bi.SetSource(ms);
Container.Instance.Resolve<MainViewModel>("MainViewModel").MyPicture = bi;// PictureDecoder.DecodeJpeg(ms);
}
});
}
else
{
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
Container.Instance.Resolve<MainViewModel>("MainViewModel").MyPicture = new BitmapImage(new Uri("/icons/anonymousIcon.png", UriKind.RelativeOrAbsolute));
});
}
//this.MyPicture = Constants.MYPICTURE_FILE_NAME + "?" + DateTime.UtcNow.Ticks;
RaisePropertyChanged(MyPicturePropertyName);
RaisePropertyChanged(MyNamePropertyName);
//
RefreshMyLocation();
}
@@ -731,7 +819,7 @@ namespace MyFriendsAround.WP7.ViewModel
byte[] _imageBytes = new byte[e.ChosenPhoto.Length];
e.ChosenPhoto.Read(_imageBytes, 0, _imageBytes.Length);
//save
IsolatedStorageHelper.SaveToLocalStorage("myphoto.jpg", "profiles", _imageBytes);
IsolatedStorageHelper.SaveToLocalStorage(Constants.MYPICTURE_FILE_NAME, "profiles", _imageBytes);
// Seek back so we can create an image.
e.ChosenPhoto.Seek(0, SeekOrigin.Begin);
@@ -739,7 +827,7 @@ namespace MyFriendsAround.WP7.ViewModel
//var imageSource = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
BitmapImage bi = new BitmapImage();
bi.SetSource(e.ChosenPhoto);
MyPicture = bi;// imageSource;
//MyPicture = bi;// imageSource;
}
}
@@ -779,12 +867,6 @@ namespace MyFriendsAround.WP7.ViewModel
}
private void DisplayAbout()
{
MessageBox.Show("About");
}
private void PopulatePushPins(List<Friend> list)
{
ObservableCollection<PushPinModel> result = new ObservableCollection<PushPinModel>();
@@ -792,14 +874,28 @@ namespace MyFriendsAround.WP7.ViewModel
{
//f.LocationStr
result.Add(new PushPinModel()
{
PinSource = "/ApplicationIcon.png",
Location = new GeoCoordinate(f.Latitude, f.Longitude),
PinUserName = f.FriendName,
PinImageUrl = string.Format("https://myfriendsaround.blob.core.windows.net/profiles/profile_{0}.jpg", f.Id)
{
PinSource = "/ApplicationIcon.png",
Location = new GeoCoordinate(f.Latitude, f.Longitude),
PinUserName = f.FriendName,
PinImageUrl =
string.Format(
"https://myfriendsaround.blob.core.windows.net/profiles/profile_{0}.jpg",
f.Id),
PinLastUpdated = f.LastUpdated,
PinDistance =
(GpsLocation != Location.Unknown)
? Haversine.Distance(
new Position() {Latitude = f.Latitude, Longitude = f.Longitude},
new Position()
{Latitude = GpsLocation.Latitude, Longitude = GpsLocation.Longitude},
DistanceType.Kilometers)
: 0
});
});
PushPins = result;
if (result.Count > 0)
SelectedFriend = PushPins[0];
}
@@ -875,7 +971,7 @@ namespace MyFriendsAround.WP7.ViewModel
else
{
//update also the picture
byte[] img = IsolatedStorageHelper.LoadFromLocalStorageArray("myphoto.jpg", "profiles");
byte[] img = IsolatedStorageHelper.LoadFromLocalStorageArray(Constants.MYPICTURE_FILE_NAME, "profiles");
if (img != null)
{
ServiceAgent.PublishMyPicture(Identification.GetDeviceId(), img, new EventHandler<PublishLocationEventArgs>(PublishMyPictureResult));
@@ -43,7 +43,6 @@ namespace MyFriendsAround.WP7.ViewModel
private string _pinUserName;
public string PinUserName
{
get { return _pinUserName; }
@@ -59,7 +58,6 @@ namespace MyFriendsAround.WP7.ViewModel
private string _pinImageUrl;
public string PinImageUrl
{
get { return _pinImageUrl; }
@@ -73,6 +71,36 @@ namespace MyFriendsAround.WP7.ViewModel
}
}
private DateTime _pinLastUpdated;
public DateTime PinLastUpdated
{
get { return _pinLastUpdated; }
set
{
if (_pinLastUpdated != value)
{
_pinLastUpdated = value;
OnPropertyChanged("PinLastUpdated");
}
}
}
private double _pinDistance;
public double PinDistance
{
get { return Math.Round(_pinDistance, 2); }
set
{
if (_pinDistance != value)
{
_pinDistance = value;
OnPropertyChanged("PinDistance");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
@@ -15,8 +15,6 @@ namespace MyFriendsAround.WP7.ViewModel
public class ViewModelBase : GalaSoft.MvvmLight.ViewModelBase
{
public bool IsLoaded { get; set; }
private object context;
public object Context
{
@@ -15,6 +15,7 @@
*/
using MyFriendsAround.WP7.Helpers.Navigation;
using MyFriendsAround.WP7.Utils;
using NetworkDetection;
namespace MyFriendsAround.WP7.ViewModel
@@ -85,7 +86,7 @@ namespace MyFriendsAround.WP7.ViewModel
{
get
{
MainViewModel mainViewModel = GetViewModel<MainViewModel>("MainViewModel");
MainViewModel mainViewModel = GetViewModel<MainViewModel>(Constants.VM_MAIN);
return mainViewModel;
}
}
@@ -97,7 +98,7 @@ namespace MyFriendsAround.WP7.ViewModel
{
get
{
SettingsViewModel aboutViewModel = GetViewModel<SettingsViewModel>("SettingsViewModel");
SettingsViewModel aboutViewModel = GetViewModel<SettingsViewModel>(Constants.VM_SETTINGS);
return aboutViewModel;
}
}
@@ -108,9 +109,9 @@ namespace MyFriendsAround.WP7.ViewModel
/// </summary>
public void Cleanup()
{
MainViewModel mainViewModel = GetViewModel<MainViewModel>("MainViewModel");
MainViewModel mainViewModel = GetViewModel<MainViewModel>(Constants.VM_MAIN);
mainViewModel.Cleanup();
SettingsViewModel aboutViewModel = GetViewModel<SettingsViewModel>("SettingsViewModel");
SettingsViewModel aboutViewModel = GetViewModel<SettingsViewModel>(Constants.VM_SETTINGS);
aboutViewModel.Cleanup();
}
@@ -118,11 +119,10 @@ namespace MyFriendsAround.WP7.ViewModel
#region Local Helpers
private T GetViewModel<T>(string key) where T : ViewModelBase
public static T GetViewModel<T>(string key) where T : ViewModelBase
{
// Create a new view model
T vm = Container.Instance.Resolve<T>(key);
//Assign the Context from PageNavigation to Context property of the ViewModelBase
vm.Context = vm.PageNav.CurrentContext;
@@ -17,6 +17,7 @@ using Microsoft.Phone.Tasks;
using MyFriendsAround.WP7.Utils;
using MyFriendsAround.WP7.ViewModel;
using NetworkDetection;
using System.Threading;
namespace MyFriendsAround.WP7.Views
{
@@ -53,7 +54,7 @@ namespace MyFriendsAround.WP7.Views
private void NavigateBack()
{
Container.Instance.Resolve<MainViewModel>("MainViewModel").CropCancel();
Container.Instance.Resolve<MainViewModel>(Constants.VM_MAIN).CropCancel();
}
void task_Completed(object sender, PhotoResult e)
@@ -158,12 +159,7 @@ namespace MyFriendsAround.WP7.Views
byte[] _imageBytes = new byte[stream.Length];
stream.Read(_imageBytes, 0, _imageBytes.Length);
//save
IsolatedStorageHelper.SaveToLocalStorage("myphoto.jpg", "profiles", _imageBytes);
//
//BitmapImage bi = new BitmapImage();
//stream.Seek(0, SeekOrigin.Begin);
//bi.SetSource(stream);
Container.Instance.Resolve<MainViewModel>("MainViewModel").MyPicture = wbm;
IsolatedStorageHelper.SaveToLocalStorage(Constants.MYPICTURE_FILE_NAME, "profiles", _imageBytes);
}
}
+113 -36
View File
@@ -18,14 +18,17 @@
d:DesignHeight="768"
shell:SystemTray.IsVisible="True"
DataContext="{Binding Main, Source={StaticResource Locator}}"
d:DataContext="{Binding Main, Source={StaticResource Locator}}"
xmlns:my="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps"
xmlns:Preview="clr-namespace:Phone7.Fx.Preview;assembly=Phone7.Fx.Preview"
xmlns:binding="clr-namespace:Coding4Fun.Phone.Controls.Binding;assembly=Coding4Fun.Phone.Controls"
xmlns:Core="clr-namespace:Microsoft.Phone.Controls.Maps.Core;assembly=Microsoft.Phone.Controls.Maps">
xmlns:Core="clr-namespace:Microsoft.Phone.Controls.Maps.Core;assembly=Microsoft.Phone.Controls.Maps"
xmlns:conv="clr-namespace:MyFriendsAround.WP7.Helpers.Converters">
<!--LayoutRoot contains the root grid where all other page content is placed-->
<phone:PhoneApplicationPage.Resources>
<conv:MyImageConverter x:Key="myImageConverter" />
<ControlTemplate x:Key="PushpinControlTemplate1"
TargetType="my:Pushpin">
<Grid Height="24"
@@ -44,7 +47,7 @@
<Grid Background="{TemplateBinding Background}"
HorizontalAlignment="Left">
<Image x:Name="imgFriend"
Source="{Binding PinImageUrl, Mode=OneWay}"
Source="{Binding PinImageUrl, Mode=OneWay, Converter={StaticResource imageCacheConverter}}"
Margin="2, 2, 2, 24"
Width="48"
Height="48"
@@ -98,22 +101,9 @@
Grid.RowSpan="2"
Margin="0">
<!--<Button Content="Publish"
HorizontalAlignment="Left" Margin="6,0,0,6" Name="btnPublishLocation"
Width="468"
Height="72"
VerticalAlignment="Bottom">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cmd:EventToCommand Command="{Binding PublishLocationCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>-->
<my:Map x:Name="map"
CredentialsProvider="AkCiPfQt9YM0cCkZlltdR3mnFQRkV41l4f-eXFmf3qcBBhBC-EkvD8MuazOkMnE_"
HorizontalAlignment="Stretch"
ZoomBarVisibility="Visible"
Margin="6,0,6,0"
VerticalAlignment="Stretch"
Center="{Binding Path=MapCenter, Mode=TwoWay}"
@@ -151,24 +141,36 @@
<StackPanel HorizontalAlignment="Left"
VerticalAlignment="Stretch">
<Image Source="/icons/appbar.add.rest.png"
Margin="0"
Width="64"
Height="64"
VerticalAlignment="Top"
HorizontalAlignment="Left">
<Image Source="/icons/appbar.add.rest.png"
Margin="0"
Width="64"
Height="64"
VerticalAlignment="Top"
HorizontalAlignment="Left">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<cmd:EventToCommand Command="{Binding MapZoomOutCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
<Image Source="/icons/appbar.minus.rest.png"
Margin="0"
Width="64"
Height="64"
VerticalAlignment="Bottom"
HorizontalAlignment="Left">
<Slider Orientation="Vertical"
Minimum="1"
Maximum="22"
Value="{Binding MapZoom, Mode=TwoWay}"
Height="300">
<!--<i:Interaction.Triggers>
<i:EventTrigger EventName="ValueChanged">
<cmd:EventToCommand Command="{Binding MapZoomChangedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>-->
</Slider>
<Image Source="/icons/appbar.minus.rest.png"
Margin="0"
Width="64"
Height="64"
VerticalAlignment="Bottom"
HorizontalAlignment="Left">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<cmd:EventToCommand Command="{Binding MapZoomInCommand}" />
@@ -186,10 +188,12 @@
<Grid x:Name="TitlePanel"
Grid.Row="0"
Margin="0"
Background="Black"
Background="Transparent"
VerticalAlignment="Top"
HorizontalAlignment="Stretch"
Opacity="0.8">
Opacity="1">
<Rectangle Fill="Black"
Opacity="0.7"></Rectangle>
<TextBlock x:Name="ApplicationTitle"
Margin="12, 12, 0, 0"
Text="{Binding ApplicationTitle}"
@@ -200,13 +204,18 @@
<Grid Width="80"
Height="80"
HorizontalAlignment="Right"
Background="Transparent"
Background="{StaticResource PhoneAccentBrush}"
Opacity="1">
<Image x:Name="imgMine"
Opacity="1"
Source="{Binding MyPicture, Mode=OneWay}"
Margin="0"
Source="{Binding SelectedFriend, Path=SelectedFriend.PinImageUrl, Converter={StaticResource imageCacheConverter}}"
Margin="1"
Stretch="Fill">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<cmd:EventToCommand Command="{Binding ShowSelectFriendCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
<Border Background="{StaticResource PhoneAccentBrush}"
Width="80"
@@ -222,7 +231,7 @@
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="2"
Text="{Binding MyName, Mode=OneWay}"
Text="{Binding SelectedFriend, Path=SelectedFriend.PinUserName}"
Opacity="1" />
</Border>
</Grid>
@@ -239,19 +248,87 @@
</Grid>
<Grid Background="Transparent"
VerticalAlignment="Stretch"
Grid.RowSpan="2"
Visibility="{Binding IsSelectFriend, Converter={StaticResource BooleanToVisibilityConverter1}}">
<Rectangle Fill="Black"
Opacity="0.7">
</Rectangle>
<StackPanel Margin="20"
Opacity="1"
Background="Black"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Width="Auto"
Height="Auto">
<TextBlock Text="Select your friend"
Style="{StaticResource PhoneTextNormalStyle}"
TextAlignment="Center"
FontSize="24"
Padding="10"
Margin="0" />
<ListBox ItemsSource="{Binding PushPins, Mode=OneWay}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Margin="0"
Width="Auto"
Height="675"
Background="Black"
Opacity="1"
SelectedItem="{Binding SelectedFriend, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Stretch"
Margin="4">
<Image Source="{Binding PinImageUrl, Mode=OneWay, Converter={StaticResource imageCacheConverter}}"
Width="96"
Height="96" />
<StackPanel Margin="10, 0,0,0">
<TextBlock Text="{Binding PinUserName}"
FontSize="24" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="Last update:"
FontSize="20">
</TextBlock>
<TextBlock Text="{Binding PinLastUpdated}"
FontSize="20"
Margin="10, 0, 0, 0" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Distance:"
FontSize="20">
</TextBlock>
<TextBlock Text="{Binding PinDistance}"
FontSize="20"
Margin="10, 0, 0, 0" />
<TextBlock Text="Km"
Margin="5, 0, 0, 0"
FontSize="20">
</TextBlock>
</StackPanel>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Grid>
<Preview:BindableApplicationBar x:Name="AppBar"
BarOpacity="0.8">
<Preview:BindableApplicationBarIconButton Command="{Binding ShowMyLocationCommand}"
IconUri="/icons/appbar.location.png"
Text="{Binding AppBarTextMyLocation}"
IsEnabled="{Binding Path=IsBusy, Converter={StaticResource InvertValueConverter1}}" />
Text="{Binding AppBarTextMyLocation}" />
<Preview:BindableApplicationBarIconButton Command="{Binding RefreshFriendsCommand}"
IconUri="/icons/appbar.sync.rest.png"
Text="{Binding AppBarTextRefresh}"
IsEnabled="{Binding Path=IsBusy, Converter={StaticResource InvertValueConverter1}}" />
<Preview:BindableApplicationBarIconButton Command="{Binding PublishLocationCommand}"
IconUri="/icons/appbar.publish.png"
Text="{Binding AppBarTextPublish}" />
Text="{Binding AppBarTextPublish}"
IsEnabled="{Binding Path=IsBusy, Converter={StaticResource InvertValueConverter1}}" />
<Preview:BindableApplicationBarIconButton Command="{Binding NavigateToSettingsCommand}"
IconUri="/icons/appbar.feature.settings.rest.png"
Text="{Binding AppBarTextSettings}" />
@@ -5,7 +5,7 @@
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:binding="clr-namespace:Coding4Fun.Phone.Controls.Binding;assembly=Coding4Fun.Phone.Controls" xmlns:Preview="clr-namespace:Phone7.Fx.Preview;assembly=Phone7.Fx.Preview" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP7" FontFamily="{StaticResource PhoneFontFamilyNormal}"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:binding="clr-namespace:Coding4Fun.Phone.Controls.Binding;assembly=Coding4Fun.Phone.Controls" xmlns:Preview="clr-namespace:Phone7.Fx.Preview;assembly=Phone7.Fx.Preview" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP7" xmlns:conv="clr-namespace:MyFriendsAround.WP7.Helpers.Converters" FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
@@ -13,6 +13,11 @@
mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
shell:SystemTray.IsVisible="True">
<phone:PhoneApplicationPage.Resources>
<conv:MyImageConverter x:Key="myImageConverter" />
</phone:PhoneApplicationPage.Resources>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<cmd:EventToCommand Command="{Binding MainLoadCommand}" />
@@ -47,7 +52,7 @@
<TextBox Height="67"
HorizontalAlignment="Stretch"
Name="txtMyName"
Text="{Binding Path=MyName, Mode=TwoWay}"
Text="{Binding MyName, Mode=TwoWay}"
VerticalAlignment="Top"
binding:TextBoxBinding.UpdateSourceOnChange="True" />
<TextBlock Text="My Picture"
@@ -65,7 +70,8 @@
VerticalAlignment="Stretch"
Stretch="Uniform"
Margin="1"
Source="{Binding MyPicture, Mode=TwoWay}"></Image>
Source="{Binding MyPicture, Mode=OneWay, Converter={StaticResource myImageConverter}}">
</Image>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cmd:EventToCommand
@@ -76,7 +82,7 @@
</StackPanel>
</Grid>
<Preview:BindableApplicationBar x:Name="AppBar"
<!--<Preview:BindableApplicationBar x:Name="AppBar"
BarOpacity="0.8">
<Preview:BindableApplicationBarIconButton Command="{Binding SaveMySettingsCommand}"
IconUri="/Toolkit.Content/ApplicationBar.Check.png"
@@ -85,7 +91,7 @@
<Preview:BindableApplicationBarIconButton Command="{Binding CancelMySettingsCommand}"
IconUri="/Toolkit.Content/ApplicationBar.Cancel.png"
Text="{Binding AppBarTextCancelSettings}" />
</Preview:BindableApplicationBar>
</Preview:BindableApplicationBar>-->
</Grid>