Skip to content

Commit

Permalink
Merge pull request #157 from Kibnet/feat/Last-opened-task-tab
Browse files Browse the repository at this point in the history
feat: Добавлена вкладка "Last Opened" с последними открытыми задачами
  • Loading branch information
Kibnet authored May 19, 2024
2 parents 3fa1757 + 898a257 commit 5249686
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 11 deletions.
112 changes: 102 additions & 10 deletions src/Unlimotion.ViewModel/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,23 @@ private void RegisterCommands()
})
.AddToDispose(connectionDisposableList);

this.WhenAnyValue(m => m.AllTasksMode, m => m.UnlockedMode, m => m.CompletedMode, m => m.ArchivedMode, m => m.GraphMode)
this.WhenAnyValue(m => m.CurrentLastCreated)
.Subscribe(m =>
{
if (m != null || CurrentTaskItem == null)
CurrentTaskItem = m?.TaskItem;
})
.AddToDispose(connectionDisposableList);

this.WhenAnyValue(m => m.CurrentLastOpenedItem)
.Subscribe(m =>
{
if (m != null || CurrentTaskItem == null)
CurrentTaskItem = m?.TaskItem;
})
.AddToDispose(connectionDisposableList);

this.WhenAnyValue(m => m.AllTasksMode, m => m.UnlockedMode, m => m.CompletedMode, m => m.ArchivedMode, m => m.GraphMode, m => m.LastCreatedMode, m => m.LastOpenedMode)
.Subscribe((a) => { SelectCurrentTask(); })
.AddToDispose(connectionDisposableList);

Expand All @@ -198,7 +214,8 @@ private async Task Connect()

//Set sort definition
var sortObservable = this.WhenAnyValue(m => m.CurrentSortDefinition).Select(d => d.Comparer);
var sortObservableForUnlocked = this.WhenAnyValue(m => m.CurrentSortDefinitionForUnlocked).Select(d => d.Comparer);
var sortObservableForUnlocked =
this.WhenAnyValue(m => m.CurrentSortDefinitionForUnlocked).Select(d => d.Comparer);

//Set All Tasks Filter
var taskFilter = this.WhenAnyValue(m => m.ShowCompleted, m => m.ShowArchived)
Expand All @@ -208,6 +225,7 @@ bool Predicate(TaskItemViewModel task) =>
task.IsCompleted == false ||
((task.IsCompleted == true) && filters.Item1) ||
((task.IsCompleted == null) && filters.Item2);
return (Func<TaskItemViewModel, bool>)Predicate;
});

Expand All @@ -232,7 +250,9 @@ bool Predicate(TaskItemViewModel task) =>
.AddToDispose(connectionDisposableList);

//Bind Emoji

#region Emoji

taskRepository.Tasks
.Connect()
.AutoRefreshOnObservable(m => m.WhenAny(m => m.Emoji, (c) => c.Value == null))
Expand Down Expand Up @@ -293,6 +313,7 @@ bool Predicate(TaskItemViewModel task)
{
return true;
}
foreach (var item in filter.Where(e => e.ShowTasks))
{
if (string.IsNullOrEmpty(item?.Emoji)) continue;
Expand All @@ -303,6 +324,7 @@ bool Predicate(TaskItemViewModel task)
return false;
}
return (Func<TaskItemViewModel, bool>)Predicate;
});

Expand All @@ -315,8 +337,9 @@ bool Predicate(TaskItemViewModel task)
{
return UnlockedTimeFilter.IsUnlocked(task) &&
(filter.All(e => e.ShowTasks == false) ||
filter.Where(e => e.ShowTasks).Any(item => item.Predicate(task)));
filter.Where(e => e.ShowTasks).Any(item => item.Predicate(task)));
}
return (Func<TaskItemViewModel, bool>)Predicate;
});

Expand All @@ -327,7 +350,8 @@ bool Predicate(TaskItemViewModel task)
ArchivedDateFilter.SetDateTimes(filter.Item1);
});

var archiveDateFilter = this.WhenAnyValue(m => m.ArchivedDateFilter.From, m => m.ArchivedDateFilter.To, m => m.ArchivedDateFilter.IsCustom)
var archiveDateFilter = this.WhenAnyValue(m => m.ArchivedDateFilter.From, m => m.ArchivedDateFilter.To,
m => m.ArchivedDateFilter.IsCustom)
.Select(filter =>
{
bool Predicate(TaskItemViewModel task)
Expand All @@ -341,9 +365,11 @@ bool Predicate(TaskItemViewModel task)
return (Func<TaskItemViewModel, bool>)Predicate;
});

#endregion Emoji

//Bind Roots

#region Roots

var emojiRootFilter = _emojiFilters.ToObservableChangeSet()
Expand All @@ -357,6 +383,7 @@ bool Predicate(TaskItemViewModel task)
{
return task.Parents.Count == 0;
}
foreach (var item in filter.Where(e => e.ShowTasks))
{
if (task.Id == item.Source?.Id)
Expand All @@ -365,6 +392,7 @@ bool Predicate(TaskItemViewModel task)
return false;
}
return (Func<TaskItemViewModel, bool>)Predicate;
});

Expand Down Expand Up @@ -397,10 +425,13 @@ bool Predicate(TaskItemViewModel task)
.AddToDispose(connectionDisposableList);

CurrentItems = _currentItems;

#endregion Roots

//Bind Unlocked

#region Unlocked

taskRepository.Tasks
.Connect()
.AutoRefreshOnObservable(m => m.WhenAnyValue(
Expand Down Expand Up @@ -462,7 +493,8 @@ bool Predicate(TaskItemViewModel task)
CompletedDateFilter.SetDateTimes(filter.Item1);
});

var completedDateFilter = this.WhenAnyValue(m => m.CompletedDateFilter.From, m => m.CompletedDateFilter.To, m => m.CompletedDateFilter.IsCustom)
var completedDateFilter = this.WhenAnyValue(m => m.CompletedDateFilter.From, m => m.CompletedDateFilter.To,
m => m.CompletedDateFilter.IsCustom)
.Select(filter =>
{
bool Predicate(TaskItemViewModel task)
Expand All @@ -476,10 +508,13 @@ bool Predicate(TaskItemViewModel task)
return (Func<TaskItemViewModel, bool>)Predicate;
});

#endregion Unlocked

//Bind Completed

#region Completed

taskRepository.Tasks
.Connect()
.AutoRefreshOnObservable(m => m.WhenAny(m => m.IsCompleted, (c) => c.Value == true))
Expand All @@ -503,10 +538,13 @@ bool Predicate(TaskItemViewModel task)
.AddToDispose(connectionDisposableList);

CompletedItems = _completedItems;

#endregion Completed

//Bind Archived

#region Archived

taskRepository.Tasks
.Connect()
.AutoRefreshOnObservable(m => m.WhenAny(m => m.IsCompleted, (c) => c.Value == null))
Expand Down Expand Up @@ -538,7 +576,8 @@ bool Predicate(TaskItemViewModel task)
LastCreatedDateFilter.SetDateTimes(filter.Item1);
});

var lastCreatedDateFilter = this.WhenAnyValue(m => m.LastCreatedDateFilter.From, m => m.LastCreatedDateFilter.To, m => m.LastCreatedDateFilter.IsCustom)
var lastCreatedDateFilter = this.WhenAnyValue(m => m.LastCreatedDateFilter.From,
m => m.LastCreatedDateFilter.To, m => m.LastCreatedDateFilter.IsCustom)

.Select(filter =>
{
Expand All @@ -553,13 +592,17 @@ bool Predicate(TaskItemViewModel task)
return (Func<TaskItemViewModel, bool>)Predicate;
});

#endregion Archived

//Bind LastCreated

#region LastCreated

taskRepository.Tasks
.Connect()
.AutoRefreshOnObservable(m => m.WhenAny(m => m.IsCanBeCompleted, m => m.IsCompleted, m => m.UnlockedDateTime, (c, d, u) => c.Value && (d.Value == false)))
.AutoRefreshOnObservable(m => m.WhenAny(m => m.IsCanBeCompleted, m => m.IsCompleted,
m => m.UnlockedDateTime, (c, d, u) => c.Value && (d.Value == false)))
.Filter(taskFilter)
.Filter(lastCreatedDateFilter)
.Filter(emojiFilter)
Expand All @@ -580,6 +623,42 @@ bool Predicate(TaskItemViewModel task)
.AddToDispose(connectionDisposableList);

LastCreatedItems = _lastCreatedItems;

#endregion LastCreated

//Bind LastOpened

#region LastOpened

LastOpenedSource
.Connect()
.Reverse()
.Bind(out _lastOpenedItems)
.Subscribe()
.AddToDispose(connectionDisposableList);

LastOpenedItems = _lastOpenedItems;

this.WhenAnyValue(m => m.CurrentTaskItem, m=> m.DetailsAreOpen)
.Subscribe(item =>
{
if (DetailsAreOpen && item.Item1 != null && LastTaskItem != item.Item1)
{
LastTaskItem = item.Item1;
var actions = new TaskWrapperActions
{
ChildSelector = m => m.ContainsTasks.ToObservableChangeSet(),
RemoveAction = RemoveTask,
GetBreadScrumbs = BredScrumbsAlgorithms.FirstTaskParent,
};
var wrapper = new TaskWrapperViewModel(null, item.Item1, actions)
{
SpecialDateTime = DateTimeOffset.Now
};
LastOpenedSource.Add(wrapper);
}
})
.AddToDispose(connectionDisposableList);
#endregion LastCreated

//Bind Current Item Contains
Expand Down Expand Up @@ -688,7 +767,7 @@ bool Predicate(TaskItemViewModel task)

private void SelectCurrentTask()
{
if (AllTasksMode ^ UnlockedMode ^ CompletedMode ^ ArchivedMode ^ GraphMode ^ LastCreatedMode)
if (AllTasksMode ^ UnlockedMode ^ CompletedMode ^ ArchivedMode ^ GraphMode ^ LastCreatedMode ^ LastOpenedMode)
{
if (AllTasksMode)
{
Expand All @@ -708,11 +787,15 @@ private void SelectCurrentTask()
}
else if (GraphMode)
{
CurrentGraphItem = FindTaskWrapperViewModel(CurrentTaskItem, ArchivedItems);
CurrentGraphItem = FindTaskWrapperViewModel(CurrentTaskItem, Graph.Tasks);
}
else if (LastCreatedMode)
{
CurrentItem = FindTaskWrapperViewModel(CurrentTaskItem, CurrentItems);
CurrentLastCreated = FindTaskWrapperViewModel(CurrentTaskItem, LastCreatedItems);
}
else if(LastOpenedMode)
{
CurrentLastOpenedItem = FindTaskWrapperViewModel(CurrentTaskItem, LastOpenedItems);
}
}
}
Expand Down Expand Up @@ -788,6 +871,7 @@ public TaskWrapperViewModel FindTaskWrapperViewModel(TaskItemViewModel taskItemV
public bool GraphMode { get; set; }
public bool SettingsMode { get; set; }
public bool LastCreatedMode { get; set; }
public bool LastOpenedMode { get; set; }

public INotificationManagerWrapper ManagerWrapper { get; }

Expand All @@ -810,12 +894,20 @@ public TaskWrapperViewModel FindTaskWrapperViewModel(TaskItemViewModel taskItemV
private ReadOnlyObservableCollection<TaskWrapperViewModel> _lastCreatedItems;
public ReadOnlyObservableCollection<TaskWrapperViewModel> LastCreatedItems { get; set; }

public ReadOnlyObservableCollection<TaskWrapperViewModel> _lastOpenedItems;
public ReadOnlyObservableCollection<TaskWrapperViewModel> LastOpenedItems { get; set; }

public SourceList<TaskWrapperViewModel> LastOpenedSource { get; set; } = new SourceList<TaskWrapperViewModel>();

public TaskItemViewModel CurrentTaskItem { get; set; }
public TaskItemViewModel LastTaskItem { get; set; }
public TaskWrapperViewModel CurrentItem { get; set; }
public TaskWrapperViewModel CurrentUnlockedItem { get; set; }
public TaskWrapperViewModel CurrentCompletedItem { get; set; }
public TaskWrapperViewModel CurrentArchivedItem { get; set; }
public TaskWrapperViewModel CurrentLastCreated { get; set; }
public TaskWrapperViewModel CurrentGraphItem { get; set; }
public TaskWrapperViewModel CurrentLastOpenedItem { get; set; }

public TaskWrapperViewModel CurrentItemContains { get; private set; }
public TaskWrapperViewModel CurrentItemParents { get; private set; }
Expand Down
1 change: 1 addition & 0 deletions src/Unlimotion.ViewModel/TaskWrapperViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public TaskWrapperViewModel(TaskWrapperViewModel parent, TaskItemViewModel task,

public TaskItemViewModel TaskItem { get; set; }
public TaskWrapperViewModel Parent { get; set; }
public DateTimeOffset? SpecialDateTime { get; set; }

public string BreadScrumbs => _actions.GetBreadScrumbs?.Invoke(this);

Expand Down
31 changes: 30 additions & 1 deletion src/Unlimotion/Views/MainControl.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@
</WrapPanel>
<TreeView Grid.Row="1" AutoScrollToSelectedItem="True"
ItemsSource="{Binding LastCreatedItems}"
SelectedItem="{Binding CurrentItem}"
SelectedItem="{Binding CurrentLastCreated}"
SelectionMode="Single">
<TreeView.ItemTemplate>
<TreeDataTemplate DataType="viewModel:TaskWrapperViewModel" ItemsSource="{Binding SubTasks}">
Expand Down Expand Up @@ -265,6 +265,35 @@
</TreeView>
</Grid>
</TabItem>
<!--Last Opened-->
<TabItem Header="Last Opened" IsSelected="{Binding LastOpenedMode, Mode=OneWayToSource}">
<Grid RowDefinitions="Auto,*">
<WrapPanel Orientation="Horizontal">
</WrapPanel>
<TreeView Grid.Row="1" AutoScrollToSelectedItem="True"
ItemsSource="{Binding LastOpenedItems}"
SelectedItem="{Binding CurrentLastOpenedItem}"
SelectionMode="Single">
<TreeView.ItemTemplate>
<TreeDataTemplate DataType="viewModel:TaskWrapperViewModel" ItemsSource="{Binding SubTasks}">
<Grid DoubleTapped="TaskTree_OnDoubleTapped" Background="Transparent">
<Grid ColumnDefinitions="Auto, Auto, Auto,*" DragDrop.AllowDrop="True" PointerPressed="InputElement_OnPointerPressed">
<CheckBox IsChecked="{Binding TaskItem.IsCompleted}" VerticalAlignment="Center" IsEnabled="{Binding TaskItem.IsCanBeCompleted}" />
<Label Grid.Column="1" Content="{Binding SpecialDateTime, StringFormat={}{0:yyyy.MM.dd HH:mm:ss}}" Foreground="{StaticResource AccentButtonBackground}" FontFamily="Consolas" VerticalAlignment="Center" />
<Label Grid.Column="2" Content="{Binding TaskItem.GetAllEmoji}" VerticalAlignment="Center" />
<Label Grid.Column="3" Content="{Binding TaskItem.Title}" VerticalAlignment="Center" Classes.IsWanted="{Binding TaskItem.Wanted}"/>
</Grid>
<Button Background="#00000000"
Content=""
BorderThickness="0"
HorizontalAlignment="Right"
Command="{Binding RemoveCommand}"/>
</Grid>
</TreeDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</TabItem>
<!--Roadmap-->
<TabItem Header="Roadmap" IsSelected="{Binding GraphMode, Mode=OneWayToSource}">
<views:GraphControl DataContext="{Binding Graph}"/>
Expand Down

0 comments on commit 5249686

Please sign in to comment.