using System; using Microsoft.AspNet.SignalR.Client; using System.Net; using System.Linq; using System.Threading.Tasks; using Xamarin.Forms; using XLabs.Forms.Mvvm; using XLabs.Forms.Pages; using XLabs.Forms.Services; using XLabs.Ioc; using XLabs.Platform.Mvvm; using XLabs.Platform.Services; using XLabs.Settings; using XLabs; using XLabs.Enums; namespace ZicMoove { using Data; using Interfaces; using Model; using Pages; using Plugin.Connectivity; using Model.Social.Messaging; using ViewModels.Messaging; using ViewModels.UserProfile; using Pages.UserProfile; using ViewModels.EstimateAndBilling; using Pages.EstimatePages; using ViewModels; using Pages.Chat; using System.Collections.Generic; using Model.Social; using Settings; using Helpers; using Model.Auth; using Plugin.DeviceInfo; using System.Json; using Newtonsoft.Json; using System.Net.Http; using System.Text; using Pages.ClientPages; using Yavsc; using Model.Musical; public partial class App : Application // superclass new in 1.3 { public static IPlatform PlatformSpecificInstance { get; set; } public static string AppName { get; set; } [Obsolete("Instead using this, use new static properties.")] public static App CurrentApp { get { return Current as App; } } private static ExtendedMasterDetailPage masterDetail; public static bool MasterPresented { get { return App.masterDetail.IsPresented; } internal set { masterDetail.IsPresented = value; } } public void Init() { var app = Resolver.Resolve(); if (app == null) { return; } Configure(app); app.Closing += OnClosing; app.Error += OnError; app.Initialize += OnInitialize; app.Resumed += OnAppResumed; app.Rotation += OnRotation; app.Startup += OnStartup; app.Suspended += OnSuspended; MainSettings.UserChanged += MainSettings_UserChanged; SetupHubConnection(); MainSettings_UserChanged(this, null); StartConnexion(); } // omg private void OnError(object sender, EventArgs e) { } // Called on rotation after OnSuspended private void OnClosing(object sender, EventArgs e) { } // FIXME Never called. private void OnInitialize(object sender, EventArgs e) { } // called on app startup, not on rotation private void OnStartup(object sender, EventArgs e) { // TODO special startup pages as // notification details or wizard setup page } private static INavigation Navigation { get { return masterDetail.Detail.Navigation; } } // Called on rotation private void OnSuspended(object sender, EventArgs e) { StopConnection(); int position = 0; DataManager.Instance.AppState.Clear(); foreach (Page page in Navigation.NavigationStack) { DataManager.Instance.AppState.Add( new PageState { Position = position++, PageType = page.GetType().FullName, BindingContext = page.BindingContext }); } DataManager.Instance.AppState.SaveEntity(); } // called on app startup, after OnStartup, not on rotation private void OnAppResumed(object sender, EventArgs e) { StartConnexion(); // TODO restore the navigation stack base.OnResume(); foreach (var pageState in DataManager.Instance.AppState) { if (pageState.PageType != null) { var pageType = Type.GetType(pageState.PageType); if (pageState.BindingContext != null) NavigationService.NavigateTo( pageType, false, pageState.BindingContext); else NavigationService.NavigateTo( pageType, false); } } DataManager.Instance.AppState.Clear(); DataManager.Instance.AppState.SaveEntity(); } // FIXME Not called? private void OnRotation(object sender, EventArgs e) { } public static GenericConfigSettingsMgr ConfigManager { protected set; get; } private void Configure(IXFormsApp app) { ViewFactory.EnableCache = true; ViewFactory.Register( resolver => new DashboardViewModel()); ViewFactory.Register(); ViewFactory.Register(); ViewFactory.Register(); ViewFactory.Register(); ViewFactory.Register(); ViewFactory.Register(); ConfigManager = new GenericConfigSettingsMgr(s => MainSettings.AppSettings.GetValueOrDefault(s, MainSettings.SettingsDefault), null); } public App(IPlatform instance) { // This declaration became obsolete by introduction // of the XLabs App that // refers this instance with // its application context property // and is obtained using the `Resolver` PlatformSpecificInstance = instance; // Xaml InitializeComponent(); // Static properties construction Init(); // Builds the Main page BuildMainPage(); } static BookQueriesPage bQueriesPage; static AccountChooserPage accChooserPage; static ActivityPage homePage; private static UserProfilePage userProfilePage; public static UserProfilePage UserProfilePage { get { return userProfilePage; } } static ChatPage chatPage; static PinPage pinPage; public static async void ShowPage(Page page) { if (page == homePage) { await Navigation.PopToRootAsync(); return; } if (Navigation.NavigationStack.Contains(page)) { if (Navigation.NavigationStack.Last() == page) return; Navigation.RemovePage(page); page.Parent = null; } await Navigation.PushAsync(page); } private void BuildMainPage() { // TODO // in case of App resume, // do not create new BindingContext's, // but use those from the AppState property accChooserPage = new AccountChooserPage(); var bookQueries = new BookQueriesViewModel(); var userprofile = Resolver.Resolve(); bQueriesPage = new BookQueriesPage { Title = "Demandes", Icon = "icon.png", BindingContext = bookQueries }; homePage = new ActivityPage() { Title = "Accueil", Icon = "icon.png" }; homePage.BindingContext = new WorkflowViewModel { BookQueries = bookQueries, UserProfile = userprofile }; userProfilePage = new UserProfilePage { Title = "Profile utilisateur", Icon = "ic_corp_icon.png", BindingContext = userprofile }; chatPage = new ChatPage { Title = "Chat", Icon = "", BindingContext = new ChatViewModel() }; pinPage = new PinPage { Title = Strings.Carte }; // var mainPage = new NavigationPage(bQueriesPage); masterDetail = new ExtendedMasterDetailPage() { Title = "MainPage" }; masterDetail.Master = new DashboardPage { Title = "Bookingstar", BindingContext = new DashboardViewModel() }; masterDetail.Detail = new NavigationPage(homePage); ToolbarItem tiSetts = new ToolbarItem() { // FIXME what for? Priority = 0, Text = "Paramètres", Icon = "ic_corp_icon.png", Command = new Command( () => { ShowPage(userProfilePage); }) }; ToolbarItem tiHome = new ToolbarItem() { Text = "Accueil", Icon = "icon.png", Command = new Command( () => { ShowPage(homePage); }) }; ToolbarItem tiPubChat = new ToolbarItem() { Text = "Chat", Icon = "chat_icon_s.png", Command = new Command( () => { ShowPage(chatPage); } ) }; ToolbarItem tiPinPage = new ToolbarItem() { Text = "Map", Icon = "glyphish_103_map.png", Command = new Command( () => { ShowPage(pinPage); } ) }; masterDetail.ToolbarItems.Add(tiHome); masterDetail.ToolbarItems.Add(tiSetts); masterDetail.ToolbarItems.Add(tiPubChat); masterDetail.ToolbarItems.Add(tiPinPage); this.MainPage = masterDetail; NavigationService = new NavigationService(Navigation); } public static Task DisplayActionSheet(string title, string cancel, string destruction, string[] buttons) { var currentPage = Navigation.NavigationStack.Last(); return currentPage.DisplayActionSheet(title, cancel, destruction, buttons); } public static Task DisplayAlert(string title, string message, string yes = "OK", string no = null) { var currentPage = Navigation.NavigationStack.Last(); if (no == null) { return currentPage.DisplayAlert(title, message, yes).ContinueWith(task => true); } else { return currentPage.DisplayAlert(title, message, yes, no); } } public static INavigationService NavigationService { protected set; get; } public static bool IsConnected { get { return CrossConnectivity.Current.IsConnected; } } private static HubConnection chatHubConnection = null; public static HubConnection ChatHubConnection { get { return chatHubConnection; } } // Start the Hub connection public static async void StartConnexion() { if (CrossConnectivity.Current.IsConnected) try { if (chatHubConnection.State == ConnectionState.Disconnected) await chatHubConnection.Start(); } catch (WebException) { // TODO use webex, set this cx down status somewhere, // & display it & maybe try again later. } catch (Exception) { // TODO use ex } } public void SetupHubConnection() { chatHubConnection = new HubConnection(Constants.SignalRHubsUrl); chatHubConnection.Error += ChatHubConnection_Error; chatHubProxy = chatHubConnection.CreateHubProxy("ChatHub"); chatHubProxy.On("addPV", (n, m) => { var msg = new ChatMessage { Message = m, SenderId = n, Date = DateTime.Now }; DataManager.Instance.PrivateMessages.Add( msg ); DataManager.Instance.PrivateMessages.SaveEntity(); DataManager.Instance.ChatUsers.OnPrivateMessage(msg); }); } public static void StopConnection() { try { if (chatHubConnection.State != ConnectionState.Disconnected) chatHubConnection.Stop(); } catch (WebException) { // TODO use webex, set this cx down status somewhere, // & display it & maybe try again later. } catch (Exception) { // TODO use ex } } private void MainSettings_UserChanged(object sender, EventArgs e) { StopConnection(); if (MainSettings.CurrentUser != null) { var token = MainSettings.CurrentUser.YavscTokens.AccessToken; if (chatHubConnection.Headers.ContainsKey("Authorization")) chatHubConnection.Headers.Remove("Authorization"); chatHubConnection.Headers.Add("Authorization", $"Bearer {token}"); } StartConnexion(); } private void ChatHubConnection_Error(Exception obj) { // TODO log in debug binaries } private static IHubProxy chatHubProxy = null; public static IHubProxy ChatHubProxy { get { return chatHubProxy; } } public static Task HasSomeCloud { get { return CrossConnectivity.Current.IsReachable(Constants.YavscHomeUrl, Constants.CloudTimeout); } } public static async Task PostDeviceInfo() { var info = GetDeviceInfo(); bool updateImages = false; if (!string.IsNullOrWhiteSpace(info.GCMRegistrationId)) { if (MainSettings.CurrentUser != null) { using (var client = UserHelpers.CreateJsonClient()) { try { var stringContent = JsonConvert.SerializeObject(info); HttpContent content = new StringContent( stringContent, Encoding.UTF8, "application/json" ); using (var response = await client.PostAsync(Constants.MobileRegistrationUrl, content)) { if (response.IsSuccessStatusCode) { var rcontent = await response.Content.ReadAsStringAsync(); var jvalue = JsonValue.Parse(rcontent); if (jvalue != null) if (jvalue.ContainsKey("UpdateActivities")) if ((bool)jvalue["UpdateActivities"]) { DataManager.Instance.Activities.Execute(null); updateImages = true; } } } } catch (Exception) { // TODO err reporting } } } } return (updateImages); } public static GCMRegIdDeclaration GetDeviceInfo() { var devinfo = CrossDeviceInfo.Current; DateTime? lupdate = DataManager.Instance.Activities.Count > 0 ? DataManager.Instance.Activities.Aggregate( (a, b) => a.DateModified > b.DateModified ? a : b ).DateModified : (DateTime?)null; return new GCMRegIdDeclaration { DeviceId = devinfo.Id, GCMRegistrationId = MainSettings.GoogleRegId, Model = devinfo.Model, Platform = devinfo.Platform.ToString(), Version = devinfo.Version, LatestActivityUpdate = lupdate }; } public static void ShowBookQuery(BookQuery query) { var page = new BookQueryPage { BindingContext = new BookQueryViewModel(query) }; ShowPage(page); } } }