using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Threading.Tasks; using comal.timesheets.Tasks; using Comal.Classes; using InABox.Clients; using InABox.Configuration; using InABox.Core; using Xamarin.Forms; using Xamarin.Forms.Xaml; using XF.Material.Forms.UI; using XF.Material.Forms.UI.Dialogs; using System.Threading; namespace comal.timesheets { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class TasksList : ContentPage { Color color = Color.FromHex("#15C7C1"); List kanbanSubscriberShells = new List(); List searchList = new List(); int currentCategory = 0; bool searching = false; bool firstLoad = true; bool tapping = false; bool doubleTap = false; public TasksList() { InitializeComponent(); LoadPreferences(); } private void LoadPreferences() { try { if (!App.Current.Properties.ContainsKey("ObserverPreference")) { App.Current.Properties.Add("ObserverPreference", "True"); observerSwitch.IsToggled = true; } else { observerSwitch.IsToggled = Convert.ToBoolean(App.Current.Properties["ObserverPreference"]); } if (!App.Current.Properties.ContainsKey("PromptedOnUsage")) { App.Current.Properties.Add("PromptedOnUsage", "True"); DisplayAlert("One-time Prompt:", "Single Tap to Open Task," + System.Environment.NewLine + "Double Tap to Complete Task", "OK"); } } catch { } } protected override void OnAppearing() { LoadData(); base.OnAppearing(); } private async void LoadData() { try { searchEnt.IsEnabled = false; await Task.Run(() => { kanbanSubscriberShells.Clear(); CoreTable table = new Client().Query( new Filter(x => x.Employee.ID).IsEqualTo(GlobalVariables.EmpID) .And(x => x.Kanban.Closed).IsEqualTo(DateTime.MinValue).And(x => x.Kanban.Category).IsNotEqualTo("Complete"), new Columns ( x => x.Kanban.ID, //0 x => x.Kanban.Number, //1 x => x.Kanban.DueDate, //2 x => x.Kanban.Title, //3 x => x.Kanban.Summary, //4 x => x.Kanban.Category, //5 x => x.Kanban.ManagerLink.Name, //6 x => x.Kanban.Attachments, //7 x => x.Manager, //8 x => x.Assignee, //9 x => x.Kanban.Locked //10 ), new SortOrder(x => x.Kanban.DueDate)); string emptyString = ""; foreach (CoreRow row in table.Rows) { List list = row.Values; if (list[0] == null) { list[0] = Guid.Empty; } //0 if (list[1] == null) { list[1] = emptyString; } //1 if (list[2] == null) { list[2] = DateTime.MinValue; } //2 if (list[3] == null) { list[3] = emptyString; } //3 if (list[4] == null) { list[4] = emptyString; } //4 if (list[5] == null) { list[5] = emptyString; } //5 if (list[6] == null) { list[6] = emptyString; } //6 if (list[7] == null) { list[7] = 0; } //7 if (list[8] == null) { list[8] = false; } //8 if (list[9] == null) { list[9] = false; } //9 if (list[10] == null) { list[10] = false; } //10 KanbanSubscriberShell kanbanSubscriberShell = new KanbanSubscriberShell(); kanbanSubscriberShell.ID = Guid.Parse(list[0].ToString()); kanbanSubscriberShell.Number = list[1].ToString(); kanbanSubscriberShell.DueDate = DateTime.Parse(list[2].ToString()); kanbanSubscriberShell.Title = list[3].ToString(); kanbanSubscriberShell.Summary = list[4].ToString(); kanbanSubscriberShell.Category = ChooseCategory(list[5].ToString()); kanbanSubscriberShell.ManagerName = list[6].ToString(); kanbanSubscriberShell.Attachments = int.Parse(list[7].ToString()); bool manager = Convert.ToBoolean(list[8].ToString()); bool assignee = Convert.ToBoolean(list[9].ToString()); kanbanSubscriberShell.Locked = Convert.ToBoolean(list[10].ToString()); kanbanSubscriberShell.Color = ChooseColour(manager, assignee, kanbanSubscriberShell.DueDate); if (kanbanSubscriberShell.Attachments != 0) { kanbanSubscriberShell.ImagePath = "paperclip.png"; if (Device.RuntimePlatform.Equals(Device.iOS)) kanbanSubscriberShell.ImagePath = "attachments.png"; } if (kanbanSubscriberShell.Color == Color.FromHex("#cb99c9")) { kanbanSubscriberShell.IsObserver = true; } kanbanSubscriberShells.Add(kanbanSubscriberShell); } if (searching) RunSearch(); else { RefreshButtons(kanbanSubscriberShells); DisplayList(kanbanSubscriberShells); } firstLoad = false; }); } catch { } } private List removeObservers(List list) { try { if (App.Current.Properties["ObserverPreference"].Equals("True")) { return list; } else { var sublist = list.Where(x => x.IsObserver == false); List newList = new List(); foreach (KanbanSubscriberShell shell in sublist) { newList.Add(shell); } return newList; } } catch { return new List(); } } private void DisplayList(List list) { try { list = removeObservers(list); Device.BeginInvokeOnMainThread(() => { switch (currentCategory) { case 0: taskListView.ItemsSource = list.Where(x => x.Category == "To Do"); break; case 1: taskListView.ItemsSource = list.Where(x => x.Category == "Current"); break; case 2: taskListView.ItemsSource = list.Where(x => x.Category == "Waiting"); break; } searchEnt.IsEnabled = true; observerSwitch.IsEnabled = true; }); } catch { } } private void RefreshButtons(List list) { try { list = removeObservers(list); Device.BeginInvokeOnMainThread(() => { if (String.Equals(Device.RuntimePlatform, Device.iOS)) { buttonToDo.Text = String.Format("{0} ({1})", "To Do", list.Count(x => x.Category == "To Do")); buttonCurrent.Text = String.Format("{0} ({1})", "Current", list.Count(x => x.Category == "Current")); buttonWaiting.Text = String.Format("{0} ({1})", "Waiting", list.Count(x => x.Category == "Waiting")); } else { buttonToDo.Text = "To Do (" + list.Count(x => x.Category == "To Do") + ")"; buttonCurrent.Text = "Current (" + list.Count(x => x.Category == "Current") + ")"; buttonWaiting.Text = "Waiting (" + list.Count(x => x.Category == "Waiting") + ")"; } }); } catch { } } private string ChooseCategory(string _category) { switch (_category) { case "Open": _category = "To Do"; break; case "In Progress": _category = "Current"; break; default: break; } return _category; } private void AddTask_Clicked(object sender, EventArgs e) { try { AddEditTask addEditTask = new AddEditTask(); Navigation.PushAsync(addEditTask); } catch { } } async void KanbanList_Tapped(object sender, EventArgs e) { try { if (tapping) { doubleTap = true; var selectedTask = taskListView.SelectedItem as KanbanSubscriberShell; if (selectedTask.Locked) { doubleTap = false; DisplayAlert("Alert", "Unable to complete locked task", "Cancel"); return; } string chosenOption = await DisplayActionSheet("Complete Task?", "Cancel", null, "Yes", "No"); switch (chosenOption) { case "Cancel": break; case "No": break; case "Yes": CompleteTask(selectedTask); break; default: break; } doubleTap = false; } else { tapping = true; Timer t = new Timer(TimerCallBack, null, 750, Timeout.Infinite); } } catch { } } private async void CompleteTask(KanbanSubscriberShell shell) { try { kanbanSubscriberShells.Remove(shell); RefreshButtons(kanbanSubscriberShells); DisplayList(kanbanSubscriberShells); await Task.Run(() => { CoreTable table = new Client().Query ( new Filter(x => x.ID).IsEqualTo(shell.ID), new Columns(x => x.ID, x => x.Category) ); Kanban kanban = table.Rows.First().ToObject(); kanban.Category = "Complete"; new Client().Save(kanban, "Completed from mobile device"); }); } catch { } } private async void TimerCallBack(object o) //for single tap { try { tapping = false; if (!doubleTap) { var selectedTask = taskListView.SelectedItem as KanbanSubscriberShell; string loadingMessage = "Loading Task " + selectedTask.Number; if (selectedTask.Attachments != 0) { loadingMessage = loadingMessage + " with " + selectedTask.Attachments + " attached document(s). Please wait for photos to appear."; } Device.BeginInvokeOnMainThread(async () => { using (await MaterialDialog.Instance.LoadingDialogAsync(message: loadingMessage)) { Guid ID = selectedTask.ID; var form = new AddEditTask(ID); await Navigation.PushAsync(form); } }); } } catch { } } private async void SearchEnt_Changed(object sender, EventArgs e) { if (!string.IsNullOrWhiteSpace(searchEnt.Text)) { searching = true; RunSearch(); } else { searching = false; RefreshButtons(kanbanSubscriberShells); DisplayList(kanbanSubscriberShells); } } private async void RunSearch() { try { await Task.Run(() => { searchList.Clear(); var list = kanbanSubscriberShells.Where(x => x.Number.Contains(searchEnt.Text) || x.ManagerName.Contains(searchEnt.Text) || x.ManagerName.Contains(UpperCaseFirst(searchEnt.Text)) || x.Title.Contains(searchEnt.Text) || x.Title.Contains(searchEnt.Text.ToUpper()) || x.Title.Contains(searchEnt.Text.ToLower()) || x.Title.Contains(UpperCaseFirst(searchEnt.Text)) || x.Summary.Contains(searchEnt.Text) || x.Summary.Contains(searchEnt.Text.ToUpper()) || x.Summary.Contains(searchEnt.Text.ToLower()) || x.Summary.Contains(UpperCaseFirst(searchEnt.Text)) || x.DueDate.ToString().Contains(searchEnt.Text) || x.DueDate.ToString().Contains(searchEnt.Text.ToUpper()) || x.DueDate.ToString().Contains(searchEnt.Text.ToLower()) || x.DueDate.ToString().Contains(UpperCaseFirst(searchEnt.Text)) ); foreach (KanbanSubscriberShell shell in list) { searchList.Add(shell); } RefreshButtons(searchList); DisplayList(searchList); }); } catch { } } static String UpperCaseFirst(string s) { char[] a = s.ToCharArray(); a[0] = char.ToUpper(a[0]); return new string(a); } private Color ChooseColour(bool manager, bool employee, DateTime due) { Color color = Color.FromHex("#cb99c9"); //purple / pastel violet if (manager) { if (employee) { color = ColorOnDate(due); } else { color = Color.LightGray; } } else if (employee) { color = ColorOnDate(due); } return color; } private Color ColorOnDate(DateTime due) { Color color = Color.FromHex("#77dd77"); //green / pastel green int result = DateTime.Compare(DateTime.Now, due); if (result < 0) //relationship = "is earlier than"; { int result2 = DateTime.Compare(DateTime.Today.AddDays(+7), due); if (result2 == 0 || result2 > 0) { color = Color.FromHex("#fff8dc"); //cornsilk / light yellow } } if (result > 0)//relationship = "is later than"; { color = Color.FromHex("#f08080"); //light coral / red } if (due == DateTime.Today) //relationship = "is the same time as"; { color = Color.FromHex("#fff8dc"); //cornsilk / light yellow } return color; } private void ButtonToDo_Clicked(object sender, EventArgs e) { currentCategory = 0; if (!searching) DisplayList(kanbanSubscriberShells); else { DisplayList(searchList); } ChangeButtonColour(); } private void ButtonCurrent_Clicked(object sender, EventArgs e) { currentCategory = 1; if (!searching) DisplayList(kanbanSubscriberShells); else { DisplayList(searchList); } ChangeButtonColour(); } private void ButtonWaiting_Clicked(object sender, EventArgs e) { currentCategory = 2; if (!searching) DisplayList(kanbanSubscriberShells); else { DisplayList(searchList); } ChangeButtonColour(); } private void ChangeButtonColour() { switch (currentCategory) { case 0: buttonToDo.BackgroundColor = color; buttonCurrent.BackgroundColor = Color.Default; buttonWaiting.BackgroundColor = Color.Default; break; case 1: buttonToDo.BackgroundColor = Color.Default; buttonCurrent.BackgroundColor = color; buttonWaiting.BackgroundColor = Color.Default; break; case 2: buttonToDo.BackgroundColor = Color.Default; buttonCurrent.BackgroundColor = Color.Default; buttonWaiting.BackgroundColor = color; break; } } private void ObserverSwitch_Toggled(object sender, EventArgs e) { if (firstLoad) return; if (observerSwitch.IsToggled) { if (App.Current.Properties.ContainsKey("ObserverPreference")) { App.Current.Properties["ObserverPreference"] = "True"; } else { App.Current.Properties.Add("ObserverPreference", "True"); } } else { if (App.Current.Properties.ContainsKey("ObserverPreference")) { App.Current.Properties["ObserverPreference"] = "False"; } else { App.Current.Properties.Add("ObserverPreference", "False"); } } if (searching) RunSearch(); else { RefreshButtons(kanbanSubscriberShells); DisplayList(kanbanSubscriberShells); } } } }