diff --git a/src/Settings.cs b/src/Settings.cs index 240a08f..a7cda4d 100644 --- a/src/Settings.cs +++ b/src/Settings.cs @@ -36,6 +36,7 @@ public class Settings internal const string TimeSpanFlag = $"{Settings.FlagPrefix}t"; internal const string TimeSpanEndFlag = $"{Settings.FlagPrefix}T"; internal const string ListPastFlag = $"{Settings.FlagPrefix}l"; + internal const string ResumeFlag = $"{Settings.FlagPrefix}R"; internal const string ShowStopFlag = $"{Settings.FlagPrefix}S"; internal const string NoProjectName = "No Project"; diff --git a/src/TogglTrack.cs b/src/TogglTrack.cs index e240afc..42b3560 100644 --- a/src/TogglTrack.cs +++ b/src/TogglTrack.cs @@ -1801,7 +1801,7 @@ private async ValueTask> _GetEditResults(CancellationToken token, Q SubTitle = $"Use {Settings.ProjectPrefix} to edit the project for this time entry", IcoPath = "tip.png", AutoCompleteText = $"{query.ActionKeyword} {query.Search} {Settings.ProjectPrefix}", - Score = 1, + Score = 100, Action = _ => { this._context.API.ChangeQuery($"{query.ActionKeyword} {query.Search} {Settings.ProjectPrefix}"); @@ -1827,7 +1827,7 @@ private async ValueTask> _GetEditResults(CancellationToken token, Q SubTitle = $"Use {Settings.ClearDescriptionFlag} to quickly clear the description", IcoPath = "tip.png", AutoCompleteText = $"{query.ActionKeyword} {query.Search} {Settings.ClearDescriptionFlag} ", - Score = 2, + Score = 10, Action = _ => { this._context.API.ChangeQuery($"{query.ActionKeyword} {query.Search} {Settings.ClearDescriptionFlag} "); @@ -1865,8 +1865,9 @@ private async ValueTask> _GetEditResults(CancellationToken token, Q var timeSpanFlags = new string[] { Settings.TimeSpanFlag, Settings.TimeSpanEndFlag }; bool hasTimeSpanFlag = query.SearchTerms.Contains(Settings.TimeSpanFlag); bool hasTimeSpanEndFlag = query.SearchTerms.Contains(Settings.TimeSpanEndFlag); + bool hasResumeFlag = query.SearchTerms.Contains(Settings.ResumeFlag); - if (!hasTimeSpanFlag && !hasTimeSpanEndFlag) + if (!hasTimeSpanFlag && !hasTimeSpanEndFlag && !hasResumeFlag) { results.Add(new Result { @@ -2004,7 +2005,7 @@ private async ValueTask> _GetEditResults(CancellationToken token, Q SubTitle = $"Use {Settings.TimeSpanFlag} after the description to edit the start time", IcoPath = "tip.png", AutoCompleteText = $"{query.ActionKeyword} {query.Search} {Settings.TimeSpanFlag} ", - Score = 10, + Score = 70, Action = _ => { this._context.API.ChangeQuery($"{query.ActionKeyword} {query.Search} {Settings.TimeSpanFlag} "); @@ -2021,7 +2022,7 @@ private async ValueTask> _GetEditResults(CancellationToken token, Q SubTitle = $"Use {Settings.TimeSpanEndFlag} after the description to edit the stop time", IcoPath = "tip.png", AutoCompleteText = $"{query.ActionKeyword} {query.Search} {Settings.TimeSpanEndFlag} ", - Score = 5, + Score = 50, Action = _ => { this._context.API.ChangeQuery($"{query.ActionKeyword} {query.Search} {Settings.TimeSpanEndFlag} "); @@ -2029,12 +2030,29 @@ private async ValueTask> _GetEditResults(CancellationToken token, Q } }); } + + if (!timeEntry.IsRunning && !hasResumeFlag) + { + results.Add(new Result + { + Title = Settings.UsageTipTitle, + SubTitle = $"Use {Settings.ResumeFlag} to resume this time entry", + IcoPath = "tip.png", + AutoCompleteText = $"{query.ActionKeyword} {query.Search} {Settings.ResumeFlag} ", + Score = 30, + Action = _ => + { + this._context.API.ChangeQuery($"{query.ActionKeyword} {query.Search} {Settings.ResumeFlag} "); + return false; + } + }); + } } } else { - // TimeSpanFlag and/or TimeSpanEndFlag is present - int firstFlag = -1; + // TimeSpanFlag and/or TimeSpanEndFlag and/or ResumeFlag is present + int firstFlag = Array.IndexOf(query.SearchTerms, Settings.ResumeFlag); for (int i = 0; i < query.SearchTerms.Length; i++) { if (!timeSpanFlags.Contains(query.SearchTerms[i])) @@ -2046,6 +2064,30 @@ private async ValueTask> _GetEditResults(CancellationToken token, Q break; } + if (hasTimeSpanEndFlag && hasResumeFlag) + { + string sanitisedQuery = new TransformedQuery(query) + .To(Settings.TimeSpanEndFlag) + .RemoveAll(Settings.ResumeFlag) + .ToString(); + + results.Add(new Result + { + Title = "ERROR: Conflicting flags", + SubTitle = $"You may not use both {Settings.TimeSpanEndFlag} and {Settings.ResumeFlag} at the same time.", + IcoPath = "tip-error.png", + AutoCompleteText = $"{query.ActionKeyword} {sanitisedQuery} ", + Score = 300000, + Action = _ => + { + this._context.API.ChangeQuery($"{query.ActionKeyword} {sanitisedQuery} "); + return false; + } + }); + + return results; + } + TimeSpan? startTimeSpan = null; TimeSpan? endTimeSpan = null; TimeSpan newElapsed = timeEntry.Elapsed; @@ -2133,12 +2175,12 @@ out var parsedEndTimeSpan return results; } - } // Remove flags from description string sanitisedDescription = new TransformedQuery(query) .Between(ArgumentIndices.Description, firstFlag) + .RemoveAll(Settings.ResumeFlag) .ToString(TransformedQuery.Escaping.Unescaped); if (this._settings.ShowUsageWarnings && string.IsNullOrEmpty(sanitisedDescription) && !string.IsNullOrEmpty(timeEntry.GetRawDescription())) @@ -2159,7 +2201,14 @@ out var parsedEndTimeSpan } var startTime = (timeEntry.StartDate + startTimeSpan) ?? timeEntry.StartDate; - var stopTime = ((timeEntry.StopDate ?? DateTimeOffset.UtcNow) + endTimeSpan) ?? timeEntry.StopDate; + var stopTime = (!hasResumeFlag) + ? ((timeEntry.StopDate ?? DateTimeOffset.UtcNow) + endTimeSpan) ?? timeEntry.StopDate + : null; + + if (hasResumeFlag) + { + newElapsed = DateTimeOffset.UtcNow.Subtract(startTime); + } results.Add(new Result {