add openhack files
This commit is contained in:
@ -0,0 +1,39 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using Foundation;
|
||||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
public partial class GettingStartedContentViewController : UIViewController
|
||||
{
|
||||
public UIImage Image { get; set; }
|
||||
public int PageIndex { get; set; }
|
||||
|
||||
public GettingStartedContentViewController (IntPtr handle) : base (handle)
|
||||
{
|
||||
}
|
||||
|
||||
public static GettingStartedContentViewController ControllerForPageIndex(int pageIndex)
|
||||
{
|
||||
var imagePath = string.Format($"screen_{pageIndex+1}.png");
|
||||
var image = UIImage.FromBundle(imagePath);
|
||||
var page = (GettingStartedContentViewController)UIStoryboard.FromName("Main", null).InstantiateViewController("gettingStartedContentViewController");
|
||||
page.Image = image;
|
||||
page.PageIndex = pageIndex;
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
public override void ViewDidLoad()
|
||||
{
|
||||
base.ViewDidLoad();
|
||||
|
||||
View.BackgroundColor = UIColor.FromPatternImage(UIImage.FromBundle("background_started.png"));
|
||||
imageView.Image = Image;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
29
MobileApps/MyDriving/MyDriving.iOS/Screens/GettingStartedContentViewController.designer.cs
generated
Normal file
29
MobileApps/MyDriving/MyDriving.iOS/Screens/GettingStartedContentViewController.designer.cs
generated
Normal file
@ -0,0 +1,29 @@
|
||||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
[Register ("GettingStartedContentViewController")]
|
||||
partial class GettingStartedContentViewController
|
||||
{
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIImageView imageView { get; set; }
|
||||
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
if (imageView != null) {
|
||||
imageView.Dispose ();
|
||||
imageView = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using Foundation;
|
||||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
public partial class GettingStartedViewController : UIPageViewController
|
||||
{
|
||||
GettingStartedContentViewController pageOne = (GettingStartedContentViewController)UIStoryboard.FromName("Main", null).InstantiateViewController("gettingStartedContentViewController");
|
||||
|
||||
public GettingStartedViewController (IntPtr handle) : base (handle)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ViewDidLoad()
|
||||
{
|
||||
base.ViewDidLoad();
|
||||
|
||||
AutomaticallyAdjustsScrollViewInsets = false;
|
||||
//self.automaticallyAdjustsScrollViewInsets = false;
|
||||
|
||||
Title = "MyDriving";
|
||||
NavigationItem.SetRightBarButtonItem(new UIBarButtonItem("Dismiss", UIBarButtonItemStyle.Plain, (sender, e) =>
|
||||
{
|
||||
var viewController = UIStoryboard.FromName("Main", null).InstantiateViewController("loginViewController");
|
||||
var appDelegate = (AppDelegate)UIApplication.SharedApplication.Delegate;
|
||||
appDelegate.Window.RootViewController = viewController;
|
||||
}), false);
|
||||
|
||||
pageOne.PageIndex = 0;
|
||||
pageOne.Image = UIImage.FromBundle("screen_1.png");
|
||||
|
||||
SetViewControllers(new UIViewController[] { pageOne }, UIPageViewControllerNavigationDirection.Forward, true, null);
|
||||
DataSource = new PageViewControllerSource();
|
||||
}
|
||||
|
||||
public class PageViewControllerSource : UIPageViewControllerDataSource
|
||||
{
|
||||
public override nint GetPresentationCount(UIPageViewController pageViewController)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public override UIViewController GetPreviousViewController(UIPageViewController pageViewController, UIViewController referenceViewController)
|
||||
{
|
||||
var vc = (GettingStartedContentViewController)referenceViewController;
|
||||
var index = vc.PageIndex;
|
||||
|
||||
if (index == 0)
|
||||
return null;
|
||||
|
||||
return GettingStartedContentViewController.ControllerForPageIndex(index-1);
|
||||
}
|
||||
|
||||
public override UIViewController GetNextViewController(UIPageViewController pageViewController, UIViewController referenceViewController)
|
||||
{
|
||||
var vc = (GettingStartedContentViewController)referenceViewController;
|
||||
var index = vc.PageIndex;
|
||||
|
||||
if (index == 4)
|
||||
return null;
|
||||
|
||||
return GettingStartedContentViewController.ControllerForPageIndex(index+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
21
MobileApps/MyDriving/MyDriving.iOS/Screens/GettingStartedViewController.designer.cs
generated
Normal file
21
MobileApps/MyDriving/MyDriving.iOS/Screens/GettingStartedViewController.designer.cs
generated
Normal file
@ -0,0 +1,21 @@
|
||||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
[Register ("GettingStartedViewController")]
|
||||
partial class GettingStartedViewController
|
||||
{
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using MyDriving.Utils;
|
||||
using MyDriving.ViewModel;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
partial class LoginViewController : UIViewController
|
||||
{
|
||||
bool didAnimate;
|
||||
LoginViewModel viewModel;
|
||||
|
||||
public LoginViewController(IntPtr handle) : base(handle)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ViewDidLoad()
|
||||
{
|
||||
viewModel = new LoginViewModel();
|
||||
//Prepare buttons for fade in animation.
|
||||
btnFacebook.Alpha = 0;
|
||||
btnTwitter.Alpha = 0;
|
||||
btnMicrosoft.Alpha = 0;
|
||||
btnSkipAuth.Alpha = 0;
|
||||
|
||||
btnSkipAuth.Layer.CornerRadius = 4;
|
||||
btnSkipAuth.Layer.MasksToBounds = true;
|
||||
|
||||
#if DEBUG || XTC
|
||||
btnSkipAuth.Hidden = false;
|
||||
#else
|
||||
btnSkipAuth.Hidden = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void ViewDidAppear(bool animated)
|
||||
{
|
||||
base.ViewDidAppear(animated);
|
||||
|
||||
if (didAnimate)
|
||||
return;
|
||||
|
||||
didAnimate = true;
|
||||
btnFacebook.FadeIn(0.3, 0.3f);
|
||||
btnTwitter.FadeIn(0.3, 0.5f);
|
||||
btnMicrosoft.FadeIn(0.3, 0.7f);
|
||||
btnSkipAuth.FadeIn(0.3, 0.9f);
|
||||
}
|
||||
|
||||
async partial void BtnFacebook_TouchUpInside(UIButton sender)
|
||||
{
|
||||
await LoginAsync(LoginAccount.Facebook);
|
||||
}
|
||||
|
||||
async partial void BtnTwitter_TouchUpInside(UIButton sender)
|
||||
{
|
||||
await LoginAsync(LoginAccount.Twitter);
|
||||
}
|
||||
|
||||
async partial void BtnMicrosoft_TouchUpInside(UIButton sender)
|
||||
{
|
||||
await LoginAsync(LoginAccount.Microsoft);
|
||||
}
|
||||
|
||||
async Task LoginAsync(LoginAccount account)
|
||||
{
|
||||
switch (account)
|
||||
{
|
||||
case LoginAccount.Facebook:
|
||||
await viewModel.ExecuteLoginFacebookCommandAsync();
|
||||
break;
|
||||
case LoginAccount.Microsoft:
|
||||
await viewModel.ExecuteLoginMicrosoftCommandAsync();
|
||||
break;
|
||||
case LoginAccount.Twitter:
|
||||
await viewModel.ExecuteLoginTwitterCommandAsync();
|
||||
break;
|
||||
}
|
||||
|
||||
if (viewModel.IsLoggedIn)
|
||||
{
|
||||
//When the first screen of the app is launched after user has logged in, initialize the processor that manages connection to OBD Device and to the IOT Hub
|
||||
Services.OBDDataProcessor.GetProcessor().Initialize(ViewModel.ViewModelBase.StoreManager);
|
||||
|
||||
NavigateToTabs();
|
||||
}
|
||||
}
|
||||
|
||||
partial void BtnSkipAuth_TouchUpInside(UIButton sender)
|
||||
{
|
||||
viewModel.InitFakeUser();
|
||||
NavigateToTabs();
|
||||
}
|
||||
|
||||
void NavigateToTabs()
|
||||
{
|
||||
InvokeOnMainThread(() =>
|
||||
{
|
||||
var app = (AppDelegate) UIApplication.SharedApplication.Delegate;
|
||||
var viewController =
|
||||
UIStoryboard.FromName("Main", null).InstantiateViewController("tabBarController") as
|
||||
UITabBarController;
|
||||
viewController.SelectedIndex = 1;
|
||||
app.Window.RootViewController = viewController;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
81
MobileApps/MyDriving/MyDriving.iOS/Screens/LoginViewController.designer.cs
generated
Normal file
81
MobileApps/MyDriving/MyDriving.iOS/Screens/LoginViewController.designer.cs
generated
Normal file
@ -0,0 +1,81 @@
|
||||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
[Register ("LoginViewController")]
|
||||
partial class LoginViewController
|
||||
{
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIButton btnFacebook { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIButton btnMicrosoft { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIButton btnSkipAuth { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIButton btnTwitter { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIImageView imgLogo { get; set; }
|
||||
|
||||
[Action ("BtnFacebook_TouchUpInside:")]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
partial void BtnFacebook_TouchUpInside (UIKit.UIButton sender);
|
||||
|
||||
[Action ("BtnMicrosoft_TouchUpInside:")]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
partial void BtnMicrosoft_TouchUpInside (UIKit.UIButton sender);
|
||||
|
||||
[Action ("BtnSkipAuth_TouchUpInside:")]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
partial void BtnSkipAuth_TouchUpInside (UIKit.UIButton sender);
|
||||
|
||||
[Action ("BtnTwitter_TouchUpInside:")]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
partial void BtnTwitter_TouchUpInside (UIKit.UIButton sender);
|
||||
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
if (btnFacebook != null) {
|
||||
btnFacebook.Dispose ();
|
||||
btnFacebook = null;
|
||||
}
|
||||
|
||||
if (btnMicrosoft != null) {
|
||||
btnMicrosoft.Dispose ();
|
||||
btnMicrosoft = null;
|
||||
}
|
||||
|
||||
if (btnSkipAuth != null) {
|
||||
btnSkipAuth.Dispose ();
|
||||
btnSkipAuth = null;
|
||||
}
|
||||
|
||||
if (btnTwitter != null) {
|
||||
btnTwitter.Dispose ();
|
||||
btnTwitter = null;
|
||||
}
|
||||
|
||||
if (imgLogo != null) {
|
||||
imgLogo.Dispose ();
|
||||
imgLogo = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using Foundation;
|
||||
using System.Collections.Generic;
|
||||
using UIKit;
|
||||
using System;
|
||||
using MyDriving.ViewModel;
|
||||
using SDWebImage;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
public partial class ProfileTableViewController : UITableViewController
|
||||
{
|
||||
const string StatCellIdentifier = "STAT_CELL_IDENTIFIER";
|
||||
List<DrivingStatistic> data;
|
||||
|
||||
public ProfileTableViewController(IntPtr handle) : base(handle)
|
||||
{
|
||||
}
|
||||
|
||||
public ProfileViewModel ViewModel { get; set; }
|
||||
|
||||
public override void ViewDidLoad()
|
||||
{
|
||||
base.ViewDidLoad();
|
||||
|
||||
ViewModel = new ProfileViewModel();
|
||||
NavigationItem.Title = $"{ViewModel.Settings.UserFirstName} {ViewModel.Settings.UserLastName}";
|
||||
|
||||
var url = ViewModel.Settings.UserProfileUrl;
|
||||
imgAvatar.SetImage(new NSUrl(url));
|
||||
|
||||
imgAvatar.Layer.CornerRadius = imgAvatar.Frame.Width/2;
|
||||
imgAvatar.Layer.BorderWidth = 2;
|
||||
imgAvatar.Layer.BorderColor = "15A9FE".ToUIColor().CGColor;
|
||||
imgAvatar.Layer.MasksToBounds = true;
|
||||
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
public override async void ViewDidAppear(bool animated)
|
||||
{
|
||||
base.ViewDidAppear(animated);
|
||||
await ViewModel.UpdateProfileAsync()
|
||||
.ContinueWith(t => { UpdateUI(); }, scheduler: TaskScheduler.FromCurrentSynchronizationContext());
|
||||
}
|
||||
|
||||
void UpdateUI()
|
||||
{
|
||||
lblDrivingSkills.Text = $"Driving Skills: {ViewModel.DrivingSkillsPlacementBucket.Description}";
|
||||
lblScore.Text = $"Score: {ViewModel.DrivingSkills}%";
|
||||
PercentageView.Value = (ViewModel.DrivingSkills/100f)*360f;
|
||||
data = new List<DrivingStatistic>
|
||||
{
|
||||
new DrivingStatistic {Name = "Total Distance", Value = ViewModel.TotalDistanceDisplay},
|
||||
new DrivingStatistic {Name = "Total Duration", Value = ViewModel.TotalTimeDisplay},
|
||||
new DrivingStatistic {Name = "Max Speed", Value = ViewModel.MaxSpeedDisplay},
|
||||
new DrivingStatistic {Name = "Fuel Consumption", Value = ViewModel.FuelDisplay},
|
||||
new DrivingStatistic {Name = "Hard Stops", Value = ViewModel.HardStops.ToString()},
|
||||
new DrivingStatistic {Name = "Hard Accelerations", Value = ViewModel.HardAccelerations.ToString()},
|
||||
new DrivingStatistic {Name = "Total Trips", Value = ViewModel.TotalTrips.ToString()},
|
||||
};
|
||||
|
||||
TableView.ReloadData();
|
||||
}
|
||||
|
||||
#region UITableViewSource
|
||||
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
|
||||
{
|
||||
return 60;
|
||||
}
|
||||
|
||||
public override nint RowsInSection(UITableView tableView, nint section)
|
||||
{
|
||||
return (data?.Count).GetValueOrDefault();
|
||||
}
|
||||
|
||||
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
|
||||
{
|
||||
var cell = tableView.DequeueReusableCell(StatCellIdentifier) as ProfileStatCell;
|
||||
|
||||
cell.Name = data[indexPath.Row].Name;
|
||||
cell.Value = data[indexPath.Row].Value;
|
||||
|
||||
return cell;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
56
MobileApps/MyDriving/MyDriving.iOS/Screens/ProfileTableViewController.designer.cs
generated
Normal file
56
MobileApps/MyDriving/MyDriving.iOS/Screens/ProfileTableViewController.designer.cs
generated
Normal file
@ -0,0 +1,56 @@
|
||||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
[Register ("ProfileTableViewController")]
|
||||
partial class ProfileTableViewController
|
||||
{
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIImageView imgAvatar { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel lblDrivingSkills { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel lblScore { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
MyDriving.iOS.CustomControls.CirclePercentage PercentageView { get; set; }
|
||||
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
if (imgAvatar != null) {
|
||||
imgAvatar.Dispose ();
|
||||
imgAvatar = null;
|
||||
}
|
||||
|
||||
if (lblDrivingSkills != null) {
|
||||
lblDrivingSkills.Dispose ();
|
||||
lblDrivingSkills = null;
|
||||
}
|
||||
|
||||
if (lblScore != null) {
|
||||
lblScore.Dispose ();
|
||||
lblScore = null;
|
||||
}
|
||||
|
||||
if (PercentageView != null) {
|
||||
PercentageView.Dispose ();
|
||||
PercentageView = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,134 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using System;
|
||||
using Foundation;
|
||||
using UIKit;
|
||||
using MyDriving.Model;
|
||||
using MyDriving.ViewModel;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
public partial class SettingsDetailViewController : UIViewController
|
||||
{
|
||||
public SettingsViewModel ViewModel;
|
||||
|
||||
public SettingsDetailViewController(IntPtr handle) : base(handle)
|
||||
{
|
||||
}
|
||||
|
||||
public string SettingKey { get; set; }
|
||||
public Setting Setting { get; set; }
|
||||
|
||||
public override void ViewDidLoad()
|
||||
{
|
||||
base.ViewDidLoad();
|
||||
|
||||
NavigationItem.Title = Setting.Name;
|
||||
settingsDetailTableView.Source = new SettingsDetailTableViewSource(SettingKey, Setting);
|
||||
|
||||
NSNotificationCenter.DefaultCenter.AddObserver(new NSString("SettingTextFieldChanged"),
|
||||
HandleSettingChangedNotification);
|
||||
}
|
||||
|
||||
void HandleSettingChangedNotification(NSNotification obj)
|
||||
{
|
||||
var dict = (NSDictionary) obj.Object;
|
||||
var row = dict.ObjectForKey(new NSString("Row")) as NSString;
|
||||
var section = dict.ObjectForKey(new NSString("Section")) as NSString;
|
||||
var value = dict.ObjectForKey(new NSString("Value")) as NSString;
|
||||
|
||||
ViewModel.SettingsData[section.ToString()][Int32.Parse(row.ToString())].Value = value.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class SettingsDetailTableViewSource : UITableViewSource
|
||||
{
|
||||
readonly string key;
|
||||
readonly Setting setting;
|
||||
|
||||
public SettingsDetailTableViewSource(string key, Setting setting)
|
||||
{
|
||||
this.setting = setting;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public override string TitleForHeader(UITableView tableView, nint section)
|
||||
{
|
||||
return setting.Name;
|
||||
}
|
||||
|
||||
public override void WillDisplayHeaderView(UITableView tableView, UIView headerView, nint section)
|
||||
{
|
||||
var header = headerView as UITableViewHeaderFooterView;
|
||||
header.TextLabel.TextColor = "5C5C5C".ToUIColor();
|
||||
header.TextLabel.Font = UIFont.FromName("AvenirNext-Medium", 16);
|
||||
header.TextLabel.Text = TitleForHeader(tableView, section);
|
||||
}
|
||||
|
||||
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
|
||||
{
|
||||
if (!setting.IsButton)
|
||||
{
|
||||
setting.Value = setting.PossibleValues[indexPath.Row];
|
||||
|
||||
var cells = tableView.VisibleCells;
|
||||
int i = 0;
|
||||
foreach (var cell in cells)
|
||||
{
|
||||
var value = setting.PossibleValues[i];
|
||||
cell.Accessory = setting.Value != value
|
||||
? UITableViewCellAccessory.None
|
||||
: UITableViewCellAccessory.Checkmark;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
NSNotificationCenter.DefaultCenter.PostNotificationName("RefreshTripUnits", null);
|
||||
NSNotificationCenter.DefaultCenter.PostNotificationName("RefreshSettingsTable", null);
|
||||
}
|
||||
}
|
||||
|
||||
public override nint RowsInSection(UITableView tableview, nint section)
|
||||
{
|
||||
if (!setting.IsTextField)
|
||||
return setting.PossibleValues.Count;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
public override nint NumberOfSections(UITableView tableView)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
|
||||
{
|
||||
if (!setting.IsTextField)
|
||||
{
|
||||
var cell = tableView.DequeueReusableCell("SETTING__DETAIL_VALUE_CELL") as SettingDetailTableViewCell;
|
||||
|
||||
cell.Name = setting.PossibleValues[indexPath.Row];
|
||||
cell.Accessory = UITableViewCellAccessory.None;
|
||||
|
||||
if (cell.Name == setting.Value)
|
||||
cell.Accessory = UITableViewCellAccessory.Checkmark;
|
||||
|
||||
return cell;
|
||||
}
|
||||
else
|
||||
{
|
||||
var cell =
|
||||
tableView.DequeueReusableCell("SETTING_DETAIL_TEXTFIELD_CELL") as
|
||||
SettingDetailTextFieldTableViewCell;
|
||||
|
||||
cell.Row = indexPath.Row.ToString();
|
||||
cell.Section = key;
|
||||
|
||||
cell.Value = setting.Value ?? string.Empty;
|
||||
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
29
MobileApps/MyDriving/MyDriving.iOS/Screens/Settings/SettingsDetailViewController.designer.cs
generated
Normal file
29
MobileApps/MyDriving/MyDriving.iOS/Screens/Settings/SettingsDetailViewController.designer.cs
generated
Normal file
@ -0,0 +1,29 @@
|
||||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
[Register ("SettingsDetailViewController")]
|
||||
partial class SettingsDetailViewController
|
||||
{
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UITableView settingsDetailTableView { get; set; }
|
||||
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
if (settingsDetailTableView != null) {
|
||||
settingsDetailTableView.Dispose ();
|
||||
settingsDetailTableView = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,164 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UIKit;
|
||||
using MyDriving.Model;
|
||||
using MyDriving.ViewModel;
|
||||
|
||||
using HockeyApp;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
partial class SettingsViewController : UIViewController
|
||||
{
|
||||
string[] keys;
|
||||
|
||||
public SettingsViewController(IntPtr handle) : base(handle)
|
||||
{
|
||||
}
|
||||
|
||||
SettingsViewModel ViewModel { get; set; }
|
||||
|
||||
public override void ViewDidLoad()
|
||||
{
|
||||
base.ViewDidLoad();
|
||||
|
||||
// Wire up view model
|
||||
ViewModel = new SettingsViewModel();
|
||||
|
||||
keys = new string[ViewModel.SettingsData.Count];
|
||||
int i = 0;
|
||||
foreach (var grouping in ViewModel.SettingsData)
|
||||
{
|
||||
keys[i] = grouping.Key;
|
||||
i++;
|
||||
}
|
||||
|
||||
// Wire up table source
|
||||
settingsTableView.Source = new SettingsDataSource(ViewModel, keys);
|
||||
|
||||
btnLogout.SetTitle("Leave Feedback", UIControlState.Normal);
|
||||
btnLogout.TouchUpInside += LeaveFeedbackButtonClicked;
|
||||
|
||||
NSNotificationCenter.DefaultCenter.AddObserver(new NSString("RefreshSettingsTable"),
|
||||
HandleReloadTableNotification);
|
||||
}
|
||||
|
||||
public override bool ShouldPerformSegue(string segueIdentifier, NSObject sender)
|
||||
{
|
||||
var cell = (SettingTableViewCell) sender;
|
||||
if (cell.Accessory == UITableViewCellAccessory.None)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
|
||||
{
|
||||
if (segue.Identifier == "settingsDetailSegue")
|
||||
{
|
||||
var controller = segue.DestinationViewController as SettingsDetailViewController;
|
||||
var cell = settingsTableView.IndexPathForCell(sender as UITableViewCell);
|
||||
var row = cell.Row;
|
||||
var section = cell.Section;
|
||||
|
||||
var setting = ViewModel.SettingsData[keys[section]][row];
|
||||
|
||||
settingsTableView.DeselectRow(settingsTableView.IndexPathForSelectedRow, true);
|
||||
|
||||
controller.Setting = setting;
|
||||
controller.ViewModel = ViewModel;
|
||||
controller.SettingKey = keys[cell.Section];
|
||||
}
|
||||
}
|
||||
|
||||
void LeaveFeedbackButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
BITHockeyManager.SharedHockeyManager.FeedbackManager.ShowFeedbackComposeView();
|
||||
}
|
||||
|
||||
void HandleReloadTableNotification(NSNotification obj)
|
||||
{
|
||||
InvokeOnMainThread(delegate { settingsTableView.ReloadData(); });
|
||||
}
|
||||
}
|
||||
|
||||
public class SettingsDataSource : UITableViewSource
|
||||
{
|
||||
readonly Dictionary<string, List<Setting>> data;
|
||||
|
||||
readonly string[] keys;
|
||||
readonly SettingsViewModel viewModel;
|
||||
|
||||
public SettingsDataSource(SettingsViewModel viewModel, string[] keys)
|
||||
{
|
||||
this.viewModel = viewModel;
|
||||
data = viewModel.SettingsData;
|
||||
|
||||
this.keys = keys;
|
||||
}
|
||||
|
||||
public override void WillDisplayHeaderView(UITableView tableView, UIView headerView, nint section)
|
||||
{
|
||||
var header = headerView as UITableViewHeaderFooterView;
|
||||
header.TextLabel.TextColor = "5C5C5C".ToUIColor();
|
||||
header.TextLabel.Font = UIFont.FromName("AvenirNext-Medium", 16);
|
||||
header.TextLabel.Text = TitleForHeader(tableView, section);
|
||||
}
|
||||
|
||||
public override async void RowSelected(UITableView tableView, NSIndexPath indexPath)
|
||||
{
|
||||
var setting = data[keys[indexPath.Section]][indexPath.Row];
|
||||
if (setting.IsButton)
|
||||
{
|
||||
if (setting.ButtonUrl != "Permissions")
|
||||
{
|
||||
await viewModel.ExecuteOpenBrowserCommandAsync(setting.ButtonUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
var url = NSUrl.FromString(UIApplication.OpenSettingsUrlString);
|
||||
UIApplication.SharedApplication.OpenUrl(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override nint NumberOfSections(UITableView tableView)
|
||||
{
|
||||
return keys.Length;
|
||||
}
|
||||
|
||||
public override string TitleForHeader(UITableView tableView, nint section)
|
||||
{
|
||||
return keys[section];
|
||||
}
|
||||
|
||||
public override nint RowsInSection(UITableView tableView, nint section)
|
||||
{
|
||||
return data[keys[section]].Count;
|
||||
}
|
||||
|
||||
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
|
||||
{
|
||||
var cell = tableView.DequeueReusableCell("SETTING_VALUE_CELL") as SettingTableViewCell;
|
||||
|
||||
var setting = data[keys[indexPath.Section]][indexPath.Row];
|
||||
if (setting.IsButton)
|
||||
{
|
||||
cell.Accessory = UITableViewCellAccessory.None;
|
||||
cell.Value = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
cell.Value = !String.IsNullOrEmpty(setting.Value) ? cell.Value = setting.Value : cell.Value = "";
|
||||
}
|
||||
|
||||
cell.Name = setting.Name;
|
||||
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
}
|
38
MobileApps/MyDriving/MyDriving.iOS/Screens/Settings/SettingsViewController.designer.cs
generated
Normal file
38
MobileApps/MyDriving/MyDriving.iOS/Screens/Settings/SettingsViewController.designer.cs
generated
Normal file
@ -0,0 +1,38 @@
|
||||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
[Register ("SettingsViewController")]
|
||||
partial class SettingsViewController
|
||||
{
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIButton btnLogout { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UITableView settingsTableView { get; set; }
|
||||
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
if (btnLogout != null) {
|
||||
btnLogout.Dispose ();
|
||||
btnLogout = null;
|
||||
}
|
||||
|
||||
if (settingsTableView != null) {
|
||||
settingsTableView.Dispose ();
|
||||
settingsTableView = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using System;
|
||||
using UIKit;
|
||||
using CoreGraphics;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
partial class TabBarController : UITabBarController
|
||||
{
|
||||
public TabBarController(IntPtr handle) : base(handle)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ViewDidLoad()
|
||||
{
|
||||
base.ViewDidLoad();
|
||||
SetupTabChangeAnimation();
|
||||
}
|
||||
|
||||
void SetupTabChangeAnimation()
|
||||
{
|
||||
ShouldSelectViewController = (tabController, controller) =>
|
||||
{
|
||||
if (SelectedViewController == null || controller == SelectedViewController)
|
||||
return true;
|
||||
|
||||
var fromView = SelectedViewController.View;
|
||||
var toView = controller.View;
|
||||
|
||||
var destFrame = fromView.Frame;
|
||||
const float offset = 25;
|
||||
|
||||
//Position toView off screen
|
||||
fromView.Superview.AddSubview(toView);
|
||||
toView.Frame = new CGRect(offset, destFrame.Y, destFrame.Width, destFrame.Height);
|
||||
|
||||
UIView.Animate(0.2,
|
||||
() => { toView.Frame = new CGRect(0, destFrame.Y, destFrame.Width, destFrame.Height); }, () =>
|
||||
{
|
||||
fromView.RemoveFromSuperview();
|
||||
SelectedViewController = controller;
|
||||
});
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
21
MobileApps/MyDriving/MyDriving.iOS/Screens/TabBarController.designer.cs
generated
Normal file
21
MobileApps/MyDriving/MyDriving.iOS/Screens/TabBarController.designer.cs
generated
Normal file
@ -0,0 +1,21 @@
|
||||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
[Register ("TabBarController")]
|
||||
partial class TabBarController
|
||||
{
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,442 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using CoreAnimation;
|
||||
using CoreLocation;
|
||||
using Foundation;
|
||||
using MapKit;
|
||||
using UIKit;
|
||||
using MyDriving.DataObjects;
|
||||
using MyDriving.ViewModel;
|
||||
using Plugin.Permissions;
|
||||
using Plugin.Permissions.Abstractions;
|
||||
using MyDriving.Utils;
|
||||
using Microsoft.WindowsAzure.MobileServices;
|
||||
using MyDriving.iOS.Helpers;
|
||||
using MyDriving.AzureClient;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
partial class CurrentTripViewController : UIViewController
|
||||
{
|
||||
CarAnnotation currentLocationAnnotation;
|
||||
TripMapViewDelegate mapDelegate;
|
||||
List<CLLocationCoordinate2D> route;
|
||||
|
||||
public CurrentTripViewController(IntPtr handle) : base(handle)
|
||||
{
|
||||
}
|
||||
|
||||
public CurrentTripViewModel CurrentTripViewModel { get; set; }
|
||||
public PastTripsDetailViewModel PastTripsDetailViewModel { get; set; }
|
||||
|
||||
public override async void ViewDidLoad()
|
||||
{
|
||||
base.ViewDidLoad();
|
||||
|
||||
NavigationItem.RightBarButtonItem = null;
|
||||
|
||||
if (PastTripsDetailViewModel == null)
|
||||
await ConfigureCurrentTripUserInterface();
|
||||
else
|
||||
await ConfigurePastTripUserInterface();
|
||||
}
|
||||
|
||||
public override async void ViewDidAppear(bool animated)
|
||||
{
|
||||
base.ViewDidAppear(animated);
|
||||
PopRecordButtonAnimation();
|
||||
|
||||
if (CurrentTripViewModel != null)
|
||||
{
|
||||
await CurrentTripViewModel.ExecuteStartTrackingTripCommandAsync().ContinueWith(async (task) =>
|
||||
{
|
||||
// If we don't have permission from the user, prompt a dialog requesting permission.
|
||||
await PromptPermissionsChangeDialog();
|
||||
});
|
||||
|
||||
if (!CurrentTripViewModel.Geolocator.IsGeolocationEnabled)
|
||||
{
|
||||
tripMapView.Camera.CenterCoordinate = new CLLocationCoordinate2D(47.6204, -122.3491);
|
||||
tripMapView.Camera.Altitude = 5000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Current Trip User Interface Logic
|
||||
|
||||
async Task ConfigureCurrentTripUserInterface()
|
||||
{
|
||||
// Configure map
|
||||
mapDelegate = new TripMapViewDelegate(true);
|
||||
tripMapView.Delegate = mapDelegate;
|
||||
tripMapView.ShowsUserLocation = false;
|
||||
tripMapView.Camera.Altitude = 5000;
|
||||
|
||||
// Setup record button
|
||||
recordButton.Hidden = false;
|
||||
recordButton.Layer.CornerRadius = recordButton.Frame.Width/2;
|
||||
recordButton.Layer.MasksToBounds = true;
|
||||
recordButton.Layer.BorderColor = UIColor.White.CGColor;
|
||||
recordButton.Layer.BorderWidth = 0;
|
||||
recordButton.TouchUpInside += RecordButton_TouchUpInside;
|
||||
|
||||
// Hide slider
|
||||
tripSlider.Hidden = true;
|
||||
wayPointA.Hidden = true;
|
||||
wayPointB.Hidden = true;
|
||||
|
||||
UpdateRecordButton(false);
|
||||
tripInfoView.Alpha = 0;
|
||||
ResetTripInfoView();
|
||||
|
||||
CurrentTripViewModel = new CurrentTripViewModel();
|
||||
CurrentTripViewModel.Geolocator.PositionChanged += Geolocator_PositionChanged;
|
||||
|
||||
}
|
||||
|
||||
void AnimateTripInfoView()
|
||||
{
|
||||
tripInfoView.FadeIn(0.3, 0);
|
||||
}
|
||||
|
||||
void ResetMapViewState()
|
||||
{
|
||||
InvokeOnMainThread(() =>
|
||||
{
|
||||
route = null;
|
||||
tripMapView.RemoveAnnotations(tripMapView.Annotations);
|
||||
|
||||
if (tripMapView.Overlays != null && tripMapView.Overlays.Length > 0)
|
||||
{
|
||||
tripMapView.RemoveOverlays(tripMapView.Overlays[0]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ResetTripInfoView()
|
||||
{
|
||||
labelOneValue.Text = "N/A";
|
||||
labelTwoValue.Text = "0";
|
||||
labelThreeValue.Text = "0:00";
|
||||
labelFourValue.Text = "N/A";
|
||||
}
|
||||
|
||||
void UpdateRecordButton(bool isRecording)
|
||||
{
|
||||
//Corner Radius
|
||||
var radiusAnimation = CABasicAnimation.FromKeyPath("cornerRadius");
|
||||
radiusAnimation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseIn);
|
||||
radiusAnimation.From = NSNumber.FromNFloat(recordButton.Layer.CornerRadius);
|
||||
|
||||
//Border Thickness
|
||||
var borderAnimation = CABasicAnimation.FromKeyPath("borderWidth");
|
||||
borderAnimation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseIn);
|
||||
radiusAnimation.From = NSNumber.FromNFloat(recordButton.Layer.BorderWidth);
|
||||
|
||||
//Animation Group
|
||||
var animationGroup = CAAnimationGroup.CreateAnimation();
|
||||
animationGroup.Animations = new CAAnimation[] {radiusAnimation, borderAnimation};
|
||||
animationGroup.Duration = 0.6;
|
||||
animationGroup.FillMode = CAFillMode.Forwards;
|
||||
|
||||
recordButton.Layer.CornerRadius = isRecording ? 4 : recordButton.Frame.Width/2;
|
||||
recordButton.Layer.BorderWidth = isRecording ? 2 : 3;
|
||||
|
||||
recordButton.Layer.AddAnimation(animationGroup, "borderChanges");
|
||||
}
|
||||
|
||||
async Task PromptPermissionsChangeDialog()
|
||||
{
|
||||
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
|
||||
if (status == PermissionStatus.Denied)
|
||||
{
|
||||
InvokeOnMainThread(() =>
|
||||
{
|
||||
var alertController = UIAlertController.Create("Location Permission Denied",
|
||||
"Tracking your location is required to record trips. Visit the Settings app to change the permission status.",
|
||||
UIAlertControllerStyle.Alert);
|
||||
alertController.AddAction(UIAlertAction.Create("Change Permission", UIAlertActionStyle.Default,
|
||||
obj =>
|
||||
{
|
||||
var url = NSUrl.FromString(UIApplication.OpenSettingsUrlString);
|
||||
UIApplication.SharedApplication.OpenUrl(url);
|
||||
}));
|
||||
|
||||
alertController.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Cancel, null));
|
||||
|
||||
PresentViewController(alertController, true, null);
|
||||
|
||||
tripMapView.Camera.CenterCoordinate = new CLLocationCoordinate2D(47.6204, -122.3491);
|
||||
tripMapView.Camera.Altitude = 5000;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async void RecordButton_TouchUpInside(object sender, EventArgs e)
|
||||
{
|
||||
if (!CurrentTripViewModel.Geolocator.IsGeolocationEnabled)
|
||||
{
|
||||
Acr.UserDialogs.UserDialogs.Instance.Alert(
|
||||
"Please ensure that geolocation is enabled and permissions are allowed for MyDriving to start a recording.",
|
||||
"Geolocation Disabled", "OK");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CurrentTripViewModel.IsRecording)
|
||||
{
|
||||
if (!await CurrentTripViewModel.StartRecordingTrip())
|
||||
return;
|
||||
|
||||
UpdateRecordButton(true);
|
||||
ResetTripInfoView();
|
||||
AnimateTripInfoView();
|
||||
|
||||
if (CurrentTripViewModel.CurrentTrip.HasSimulatedOBDData)
|
||||
NavigationItem.Title = "Current Trip (Sim OBD)";
|
||||
|
||||
var endpoint = "A";
|
||||
var annotation = new WaypointAnnotation(CurrentTripViewModel.CurrentPosition.ToCoordinate(), endpoint);
|
||||
tripMapView.AddAnnotation(annotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (await CurrentTripViewModel.StopRecordingTrip())
|
||||
{
|
||||
ResetMapViewState();
|
||||
InvokeOnMainThread(delegate
|
||||
{
|
||||
mapDelegate = new TripMapViewDelegate(true);
|
||||
tripMapView.Delegate = mapDelegate;
|
||||
});
|
||||
|
||||
UpdateRecordButton(false);
|
||||
tripInfoView.Alpha = 0;
|
||||
NavigationItem.Title = "Current Trip";
|
||||
|
||||
await CurrentTripViewModel.SaveRecordingTripAsync();
|
||||
|
||||
var vc =
|
||||
Storyboard.InstantiateViewController("tripSummaryViewController") as TripSummaryViewController;
|
||||
vc.ViewModel = CurrentTripViewModel;
|
||||
PresentModalViewController(vc, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Geolocator_PositionChanged(object sender, Plugin.Geolocator.Abstractions.PositionEventArgs e)
|
||||
{
|
||||
var coordinate = e.Position.ToCoordinate();
|
||||
UpdateCarAnnotationPosition(coordinate);
|
||||
|
||||
if (CurrentTripViewModel.IsRecording)
|
||||
{
|
||||
// Update trip information
|
||||
labelOneValue.Text = CurrentTripViewModel.FuelConsumption;
|
||||
labelOneTitle.Text = CurrentTripViewModel.FuelConsumptionUnits;
|
||||
labelThreeValue.Text = CurrentTripViewModel.ElapsedTime;
|
||||
labelTwoValue.Text = CurrentTripViewModel.CurrentTrip.Distance.ToString("F");
|
||||
labelTwoTitle.Text =
|
||||
CultureInfo.CurrentCulture.TextInfo.ToTitleCase(CurrentTripViewModel.CurrentTrip.Units.ToLower());
|
||||
labelFourValue.Text = CurrentTripViewModel.EngineLoad;
|
||||
|
||||
// If we already haven't starting tracking route yet, start that.
|
||||
if (route == null)
|
||||
StartTrackingRoute(coordinate);
|
||||
// Draw from last known coordinate to new coordinate.
|
||||
else
|
||||
DrawNewRouteWaypoint(coordinate);
|
||||
}
|
||||
}
|
||||
|
||||
void StartTrackingRoute(CLLocationCoordinate2D coordinate)
|
||||
{
|
||||
route = new List<CLLocationCoordinate2D>();
|
||||
|
||||
var count = CurrentTripViewModel.CurrentTrip.Points.Count;
|
||||
if (count == 0)
|
||||
{
|
||||
route.Add(coordinate);
|
||||
}
|
||||
else
|
||||
{
|
||||
var firstPoint = CurrentTripViewModel.CurrentTrip.Points?[0];
|
||||
var firstCoordinate = new CLLocationCoordinate2D(firstPoint.Latitude, firstPoint.Longitude);
|
||||
route.Add(firstCoordinate);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Past Trip User Interface Logic
|
||||
|
||||
async Task ConfigurePastTripUserInterface()
|
||||
{
|
||||
NavigationItem.Title = PastTripsDetailViewModel.Title;
|
||||
sliderView.Hidden = false;
|
||||
tripSlider.Hidden = false;
|
||||
|
||||
wayPointA.Layer.CornerRadius = wayPointA.Frame.Width / 2;
|
||||
wayPointA.Layer.BorderWidth = 2;
|
||||
wayPointA.Layer.BorderColor = UIColor.White.CGColor;
|
||||
|
||||
wayPointB.Layer.CornerRadius = wayPointB.Frame.Width / 2;
|
||||
wayPointB.Layer.BorderWidth = 2;
|
||||
wayPointB.Layer.BorderColor = UIColor.White.CGColor;
|
||||
|
||||
var success = await PastTripsDetailViewModel.ExecuteLoadTripCommandAsync(PastTripsDetailViewModel.Trip.Id);
|
||||
|
||||
if(!success)
|
||||
{
|
||||
NavigationController.PopViewController(true);
|
||||
return;
|
||||
}
|
||||
// Setup map
|
||||
mapDelegate = new TripMapViewDelegate(false);
|
||||
tripMapView.Delegate = mapDelegate;
|
||||
tripMapView.ShowsUserLocation = false;
|
||||
|
||||
if (PastTripsDetailViewModel.Trip == null || PastTripsDetailViewModel.Trip.Points == null || PastTripsDetailViewModel.Trip.Points.Count == 0)
|
||||
return;
|
||||
|
||||
var coordinateCount = PastTripsDetailViewModel.Trip.Points.Count;
|
||||
// Draw endpoints
|
||||
var startEndpoint = new WaypointAnnotation(PastTripsDetailViewModel.Trip.Points[0].ToCoordinate(), "A");
|
||||
tripMapView.AddAnnotation(startEndpoint);
|
||||
|
||||
var endEndpoint =
|
||||
new WaypointAnnotation(PastTripsDetailViewModel.Trip.Points[coordinateCount - 1].ToCoordinate(), "B");
|
||||
tripMapView.AddAnnotation(endEndpoint);
|
||||
|
||||
// Draw route
|
||||
tripMapView.DrawRoute(PastTripsDetailViewModel.Trip.Points.ToCoordinateArray());
|
||||
|
||||
// Draw car
|
||||
var carCoordinate = PastTripsDetailViewModel.Trip.Points[0];
|
||||
currentLocationAnnotation = new CarAnnotation(carCoordinate.ToCoordinate(), UIColor.Blue);
|
||||
tripMapView.AddAnnotation(currentLocationAnnotation);
|
||||
|
||||
// Configure slider area
|
||||
ConfigureSlider();
|
||||
ConfigureWayPointButtons();
|
||||
ConfigurePoiAnnotations();
|
||||
recordButton.Hidden = true;
|
||||
|
||||
tripMapView.SetVisibleMapRect(
|
||||
MKPolyline.FromCoordinates(PastTripsDetailViewModel.Trip.Points.ToCoordinateArray()).BoundingMapRect,
|
||||
new UIEdgeInsets(25, 25, 25, 25), false);
|
||||
|
||||
tripMapView.CenterCoordinate = carCoordinate.ToCoordinate();
|
||||
UpdateTripStatistics(carCoordinate);
|
||||
NSNotificationCenter.DefaultCenter.AddObserver(new NSString("RefreshTripUnits"), HandleTripUnitsChanged);
|
||||
}
|
||||
|
||||
void HandleTripUnitsChanged(NSNotification obj)
|
||||
{
|
||||
UpdateTripStatistics(PastTripsDetailViewModel.CurrentPosition);
|
||||
}
|
||||
|
||||
void UpdateTripStatistics(TripPoint point)
|
||||
{
|
||||
PastTripsDetailViewModel.CurrentPosition = point;
|
||||
labelOneTitle.Text = PastTripsDetailViewModel.FuelConsumptionUnits;
|
||||
labelOneValue.Text = PastTripsDetailViewModel.FuelConsumption;
|
||||
|
||||
labelTwoTitle.Text = PastTripsDetailViewModel.DistanceUnits;
|
||||
labelTwoValue.Text = PastTripsDetailViewModel.Distance;
|
||||
|
||||
labelThreeTitle.Text = "Elapsed Time";
|
||||
labelThreeValue.Text = PastTripsDetailViewModel.ElapsedTime;
|
||||
|
||||
labelFourTitle.Text = PastTripsDetailViewModel.SpeedUnits;
|
||||
labelFourValue.Text = PastTripsDetailViewModel.Speed;
|
||||
}
|
||||
|
||||
void ConfigureSlider()
|
||||
{
|
||||
tripSlider.MinValue = 0;
|
||||
tripSlider.MaxValue = PastTripsDetailViewModel.Trip.Points.Count - 1;
|
||||
tripSlider.Value = 0;
|
||||
|
||||
tripSlider.ValueChanged += TripSlider_ValueChanged;
|
||||
}
|
||||
|
||||
void ConfigureWayPointButtons()
|
||||
{
|
||||
startTimeLabel.Hidden = false;
|
||||
endTimeLabel.Hidden = false;
|
||||
|
||||
startTimeLabel.Text = PastTripsDetailViewModel.Trip.StartTimeDisplay;
|
||||
endTimeLabel.Text = PastTripsDetailViewModel.Trip.EndTimeDisplay;
|
||||
|
||||
wayPointA.TouchUpInside += delegate
|
||||
{
|
||||
tripSlider.Value = 0;
|
||||
TripSlider_ValueChanged(this, null);
|
||||
};
|
||||
|
||||
wayPointB.TouchUpInside += delegate
|
||||
{
|
||||
tripSlider.Value = tripSlider.MaxValue;
|
||||
TripSlider_ValueChanged(this, null);
|
||||
};
|
||||
}
|
||||
|
||||
void ConfigurePoiAnnotations()
|
||||
{
|
||||
foreach (var poi in PastTripsDetailViewModel.POIs)
|
||||
{
|
||||
var poiAnnotation = new PoiAnnotation(poi, poi.ToCoordinate());
|
||||
tripMapView.AddAnnotation(poiAnnotation);
|
||||
}
|
||||
}
|
||||
|
||||
void TripSlider_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
var value = (int) tripSlider.Value;
|
||||
var tripPoint = PastTripsDetailViewModel.Trip.Points[value];
|
||||
UpdateCarAnnotationPosition(tripPoint.ToCoordinate());
|
||||
|
||||
UpdateTripStatistics(tripPoint);
|
||||
}
|
||||
|
||||
void PopRecordButtonAnimation()
|
||||
{
|
||||
if (recordButton.Hidden && PastTripsDetailViewModel == null)
|
||||
recordButton.Pop(0.5, 0, 1);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Shared User Interface Logic
|
||||
|
||||
void UpdateCarAnnotationPosition(CLLocationCoordinate2D coordinate)
|
||||
{
|
||||
if (currentLocationAnnotation != null)
|
||||
tripMapView.RemoveAnnotation(currentLocationAnnotation);
|
||||
|
||||
var color = CurrentTripViewModel != null && CurrentTripViewModel.IsRecording ? UIColor.Red : UIColor.Blue;
|
||||
currentLocationAnnotation = new CarAnnotation(coordinate, color);
|
||||
|
||||
tripMapView.AddAnnotation(currentLocationAnnotation);
|
||||
tripMapView.Camera.CenterCoordinate = coordinate;
|
||||
}
|
||||
|
||||
void DrawNewRouteWaypoint(CLLocationCoordinate2D coordinate)
|
||||
{
|
||||
route.Add(coordinate);
|
||||
|
||||
if (tripMapView.Overlays != null)
|
||||
tripMapView.RemoveOverlays(tripMapView.Overlays);
|
||||
|
||||
tripMapView.DrawRoute(route.ToArray());
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
173
MobileApps/MyDriving/MyDriving.iOS/Screens/Trips/CurrentTripViewController.designer.cs
generated
Normal file
173
MobileApps/MyDriving/MyDriving.iOS/Screens/Trips/CurrentTripViewController.designer.cs
generated
Normal file
@ -0,0 +1,173 @@
|
||||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
[Register ("CurrentTripViewController")]
|
||||
partial class CurrentTripViewController
|
||||
{
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel endTimeLabel { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelFourTitle { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelFourValue { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelOneTitle { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelOneValue { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelThreeTitle { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelThreeValue { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelTwoTitle { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelTwoValue { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIButton recordButton { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIView sliderView { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel startTimeLabel { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIView tripInfoView { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
MyDriving.iOS.TripMapView tripMapView { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UISlider tripSlider { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIButton wayPointA { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIButton wayPointB { get; set; }
|
||||
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
if (endTimeLabel != null) {
|
||||
endTimeLabel.Dispose ();
|
||||
endTimeLabel = null;
|
||||
}
|
||||
|
||||
if (labelFourTitle != null) {
|
||||
labelFourTitle.Dispose ();
|
||||
labelFourTitle = null;
|
||||
}
|
||||
|
||||
if (labelFourValue != null) {
|
||||
labelFourValue.Dispose ();
|
||||
labelFourValue = null;
|
||||
}
|
||||
|
||||
if (labelOneTitle != null) {
|
||||
labelOneTitle.Dispose ();
|
||||
labelOneTitle = null;
|
||||
}
|
||||
|
||||
if (labelOneValue != null) {
|
||||
labelOneValue.Dispose ();
|
||||
labelOneValue = null;
|
||||
}
|
||||
|
||||
if (labelThreeTitle != null) {
|
||||
labelThreeTitle.Dispose ();
|
||||
labelThreeTitle = null;
|
||||
}
|
||||
|
||||
if (labelThreeValue != null) {
|
||||
labelThreeValue.Dispose ();
|
||||
labelThreeValue = null;
|
||||
}
|
||||
|
||||
if (labelTwoTitle != null) {
|
||||
labelTwoTitle.Dispose ();
|
||||
labelTwoTitle = null;
|
||||
}
|
||||
|
||||
if (labelTwoValue != null) {
|
||||
labelTwoValue.Dispose ();
|
||||
labelTwoValue = null;
|
||||
}
|
||||
|
||||
if (recordButton != null) {
|
||||
recordButton.Dispose ();
|
||||
recordButton = null;
|
||||
}
|
||||
|
||||
if (sliderView != null) {
|
||||
sliderView.Dispose ();
|
||||
sliderView = null;
|
||||
}
|
||||
|
||||
if (startTimeLabel != null) {
|
||||
startTimeLabel.Dispose ();
|
||||
startTimeLabel = null;
|
||||
}
|
||||
|
||||
if (tripInfoView != null) {
|
||||
tripInfoView.Dispose ();
|
||||
tripInfoView = null;
|
||||
}
|
||||
|
||||
if (tripMapView != null) {
|
||||
tripMapView.Dispose ();
|
||||
tripMapView = null;
|
||||
}
|
||||
|
||||
if (tripSlider != null) {
|
||||
tripSlider.Dispose ();
|
||||
tripSlider = null;
|
||||
}
|
||||
|
||||
if (wayPointA != null) {
|
||||
wayPointA.Dispose ();
|
||||
wayPointA = null;
|
||||
}
|
||||
|
||||
if (wayPointB != null) {
|
||||
wayPointB.Dispose ();
|
||||
wayPointB = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
public partial class TripSummaryViewController : UIViewController
|
||||
{
|
||||
public TripSummaryViewController(IntPtr handle) : base(handle)
|
||||
{
|
||||
}
|
||||
|
||||
public ViewModel.CurrentTripViewModel ViewModel { get; set; }
|
||||
|
||||
public override void ViewDidLoad()
|
||||
{
|
||||
lblDateTime.Text = $"{DateTime.Now.ToString("M")} {DateTime.Now.ToString("t")}";
|
||||
lblDistance.Text = ViewModel.TripSummary.TotalDistanceDisplay;
|
||||
lblDuration.Text = ViewModel.TripSummary.TotalTimeDisplay;
|
||||
lblFuelConsumed.Text = ViewModel.TripSummary.FuelDisplay;
|
||||
lblTopSpeed.Text = ViewModel.TripSummary.MaxSpeedDisplay;
|
||||
|
||||
lblDistance.Alpha = 0;
|
||||
lblDuration.Alpha = 0;
|
||||
lblTopSpeed.Alpha = 0;
|
||||
lblFuelConsumed.Alpha = 0;
|
||||
lblTopSpeed.Alpha = 0;
|
||||
}
|
||||
|
||||
public override void ViewDidAppear(bool animated)
|
||||
{
|
||||
base.ViewDidAppear(animated);
|
||||
|
||||
lblDistance.FadeIn(0.4, 0.1f);
|
||||
lblDuration.FadeIn(0.4, 0.2f);
|
||||
lblTopSpeed.FadeIn(0.4, 0.3f);
|
||||
lblFuelConsumed.FadeIn(0.4, 0.4f);
|
||||
lblTopSpeed.FadeIn(0.4, 0.5f);
|
||||
}
|
||||
|
||||
async partial void BtnClose_TouchUpInside(UIButton sender)
|
||||
{
|
||||
await DismissViewControllerAsync(true);
|
||||
}
|
||||
}
|
||||
}
|
78
MobileApps/MyDriving/MyDriving.iOS/Screens/Trips/TripSummaryViewController.designer.cs
generated
Normal file
78
MobileApps/MyDriving/MyDriving.iOS/Screens/Trips/TripSummaryViewController.designer.cs
generated
Normal file
@ -0,0 +1,78 @@
|
||||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
[Register ("TripSummaryViewController")]
|
||||
partial class TripSummaryViewController
|
||||
{
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIButton btnClose { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel lblDateTime { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel lblDistance { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel lblDuration { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel lblFuelConsumed { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel lblTopSpeed { get; set; }
|
||||
|
||||
[Action ("BtnClose_TouchUpInside:")]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
partial void BtnClose_TouchUpInside (UIKit.UIButton sender);
|
||||
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
if (btnClose != null) {
|
||||
btnClose.Dispose ();
|
||||
btnClose = null;
|
||||
}
|
||||
|
||||
if (lblDateTime != null) {
|
||||
lblDateTime.Dispose ();
|
||||
lblDateTime = null;
|
||||
}
|
||||
|
||||
if (lblDistance != null) {
|
||||
lblDistance.Dispose ();
|
||||
lblDistance = null;
|
||||
}
|
||||
|
||||
if (lblDuration != null) {
|
||||
lblDuration.Dispose ();
|
||||
lblDuration = null;
|
||||
}
|
||||
|
||||
if (lblFuelConsumed != null) {
|
||||
lblFuelConsumed.Dispose ();
|
||||
lblFuelConsumed = null;
|
||||
}
|
||||
|
||||
if (lblTopSpeed != null) {
|
||||
lblTopSpeed.Dispose ();
|
||||
lblTopSpeed = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,152 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using System;
|
||||
using CoreGraphics;
|
||||
using Foundation;
|
||||
using ObjCRuntime;
|
||||
using UIKit;
|
||||
using MyDriving.ViewModel;
|
||||
using SDWebImage;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
public partial class TripsTableViewController : UITableViewController
|
||||
{
|
||||
const string TripCellWithImageIdentifier = "TRIP_CELL_WITHIMAGE_IDENTIFIER";
|
||||
const string TripCellIdentifier = "TRIP_CELL_IDENTIFIER";
|
||||
const string PastTripSegueIdentifier = "pastTripSegue";
|
||||
|
||||
public TripsTableViewController(IntPtr handle) : base(handle)
|
||||
{
|
||||
}
|
||||
|
||||
public PastTripsViewModel ViewModel { get; set; }
|
||||
|
||||
public override async void ViewDidLoad()
|
||||
{
|
||||
base.ViewDidLoad();
|
||||
|
||||
ViewModel = new PastTripsViewModel();
|
||||
await ViewModel.ExecuteLoadPastTripsCommandAsync();
|
||||
|
||||
TableView.ReloadData();
|
||||
TableView.TableFooterView = new UIView(new CGRect(0, 0, 0, 0));
|
||||
|
||||
RefreshControl.AddTarget(this, new Selector("RefreshSource"), UIControlEvent.ValueChanged);
|
||||
NSNotificationCenter.DefaultCenter.AddObserver(new NSString("RefreshPastTripsTable"),
|
||||
HandleReloadTableNotification);
|
||||
}
|
||||
|
||||
public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
|
||||
{
|
||||
if (segue.Identifier == PastTripSegueIdentifier)
|
||||
{
|
||||
var controller = segue.DestinationViewController as CurrentTripViewController;
|
||||
var indexPath = TableView.IndexPathForCell(sender as UITableViewCell);
|
||||
var trip = ViewModel.Trips[indexPath.Row];
|
||||
|
||||
controller.PastTripsDetailViewModel = new PastTripsDetailViewModel(trip);
|
||||
}
|
||||
}
|
||||
|
||||
[Export("RefreshSource")]
|
||||
async void RefreshControl_ValueChanged()
|
||||
{
|
||||
await ViewModel.ExecuteLoadPastTripsCommandAsync();
|
||||
|
||||
InvokeOnMainThread(delegate
|
||||
{
|
||||
TableView.ReloadData();
|
||||
RefreshControl.EndRefreshing();
|
||||
});
|
||||
}
|
||||
|
||||
async void HandleReloadTableNotification(NSNotification obj)
|
||||
{
|
||||
await ViewModel.ExecuteLoadPastTripsCommandAsync();
|
||||
|
||||
InvokeOnMainThread(delegate { TableView.ReloadData(); });
|
||||
}
|
||||
|
||||
#region UITableViewSource
|
||||
|
||||
public override nint RowsInSection(UITableView tableView, nint section)
|
||||
{
|
||||
return ViewModel.Trips.Count;
|
||||
}
|
||||
|
||||
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
|
||||
{
|
||||
if (ViewModel.CanLoadMore && !ViewModel.IsBusy && ViewModel.Trips.Count > 0 && indexPath.Row == ViewModel.Trips.Count - 1)
|
||||
{
|
||||
ViewModel.ExecuteLoadMorePastTripsCommandAsync().ContinueWith((t) =>
|
||||
{
|
||||
InvokeOnMainThread(delegate { TableView.ReloadData(); });
|
||||
}, scheduler: System.Threading.Tasks.TaskScheduler.Current);
|
||||
}
|
||||
|
||||
var trip = ViewModel.Trips[indexPath.Row];
|
||||
if (string.IsNullOrEmpty(trip.MainPhotoUrl))
|
||||
{
|
||||
var cell = tableView.DequeueReusableCell(TripCellIdentifier) as TripTableViewCell;
|
||||
|
||||
if (cell == null)
|
||||
{
|
||||
cell = new TripTableViewCell(new NSString(TripCellIdentifier));
|
||||
}
|
||||
|
||||
cell.LocationName = trip.Name;
|
||||
cell.TimeAgo = trip.TimeAgo;
|
||||
cell.Distance = trip.TotalDistance;
|
||||
|
||||
return cell;
|
||||
}
|
||||
else
|
||||
{
|
||||
var cell = tableView.DequeueReusableCell(TripCellWithImageIdentifier) as TripTableViewCellWithImage;
|
||||
|
||||
if (cell == null)
|
||||
{
|
||||
cell = new TripTableViewCellWithImage(new NSString(TripCellWithImageIdentifier));
|
||||
}
|
||||
|
||||
cell.DisplayImage.SetImage(new NSUrl(trip.MainPhotoUrl));
|
||||
cell.LocationName = trip.Name;
|
||||
cell.TimeAgo = trip.TimeAgo;
|
||||
cell.Distance = trip.TotalDistance;
|
||||
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
|
||||
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
|
||||
{
|
||||
var trip = ViewModel.Trips[indexPath.Row];
|
||||
if (string.IsNullOrEmpty(trip.MainPhotoUrl))
|
||||
return 70;
|
||||
else
|
||||
return 221;
|
||||
}
|
||||
|
||||
public override bool CanEditRow(UITableView tableView, NSIndexPath indexPath)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override async void CommitEditingStyle(UITableView tableView, UITableViewCellEditingStyle editingStyle,
|
||||
NSIndexPath indexPath)
|
||||
{
|
||||
switch (editingStyle)
|
||||
{
|
||||
case UITableViewCellEditingStyle.Delete:
|
||||
var trip = ViewModel.Trips[indexPath.Row];
|
||||
if(await ViewModel.ExecuteDeleteTripCommand(trip))
|
||||
tableView.DeleteRows(new[] {indexPath}, UITableViewRowAnimation.Automatic);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
21
MobileApps/MyDriving/MyDriving.iOS/Screens/Trips/TripsTableViewController.designer.cs
generated
Normal file
21
MobileApps/MyDriving/MyDriving.iOS/Screens/Trips/TripsTableViewController.designer.cs
generated
Normal file
@ -0,0 +1,21 @@
|
||||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
[Register ("TripsTableViewController")]
|
||||
partial class TripsTableViewController
|
||||
{
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user