Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 70 additions & 1 deletion Flow.Launcher.Test/Plugins/CalculatorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Reflection;
using Flow.Launcher.Plugin.Calculator;
using Flow.Launcher.Plugin.Calculator.Storage;
using Mages.Core;
using NUnit.Framework;
using NUnit.Framework.Legacy;
Expand All @@ -17,7 +18,8 @@ public class CalculatorPluginTest
DecimalSeparator = DecimalSeparator.UseSystemLocale,
MaxDecimalPlaces = 10,
ShowErrorMessage = false, // Make sure we return the empty results when error occurs
UseThousandsSeparator = true // Default value
UseThousandsSeparator = true, // Default value
EnableHistory = true,
};
private readonly Engine _engine = new(new Configuration
{
Expand All @@ -40,6 +42,14 @@ public CalculatorPluginTest()
if (engineField == null)
Assert.Fail("Could not find static field 'MagesEngine' on Flow.Launcher.Plugin.Calculator.Main");
engineField.SetValue(null, _engine);

SetHistory(new History());
}

[SetUp]
public void SetUp()
{
SetHistory(new History());
}

[Test]
Expand Down Expand Up @@ -80,6 +90,34 @@ public void ThousandsSeparatorTest_LargeNumber()
ClassicAssert.AreEqual("1234567", result);
}

[Test]
public void CalculationHistory_IsStoredWhenEnabled()
{
_settings.EnableHistory = true;

_plugin.Query(new Plugin.Query { Search = "1+1" });
WaitForHistoryDebounce();

ClassicAssert.AreEqual(1, GetHistory().Items.Count);
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
ClassicAssert.AreEqual("1+1", GetHistory().Items[0].Query);
ClassicAssert.AreEqual("2", GetHistory().Items[0].CopyText);
ClassicAssert.IsNotEmpty(GetHistory().Items[0].SubTitle);
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

[Test]
public void CalculationHistory_IsNotReturnedWhenDisabled()
{
_settings.EnableHistory = true;
_plugin.Query(new Plugin.Query { Search = "1+1" });
WaitForHistoryDebounce();

_settings.EnableHistory = false;
var results = _plugin.Query(new Plugin.Query { Search = "2+2" });

ClassicAssert.AreEqual(1, results.Count);
ClassicAssert.AreEqual("4", results[0].Title);
}
Comment thread
Jack251970 marked this conversation as resolved.

// Basic operations
[TestCase(@"1+1", "2")]
[TestCase(@"2-1", "1")]
Expand Down Expand Up @@ -130,5 +168,36 @@ private string GetCalculationResult(string expression)
});
return results.Count > 0 ? results[0].Title : string.Empty;
}

private void WaitForHistoryDebounce()
{
var flushPendingItemMethod = typeof(History).GetMethod("FlushPendingItem", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.That(flushPendingItemMethod, Is.Not.Null,
"Could not find method 'FlushPendingItem' on Flow.Launcher.Plugin.Calculator.Storage.History");

flushPendingItemMethod!.Invoke(GetHistory(), null);
}

private History GetHistory()
{
var historyProperty = typeof(Main).GetProperty("History", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.That(historyProperty, Is.Not.Null,
"Could not find property 'History' on Flow.Launcher.Plugin.Calculator.Main");

var history = historyProperty!.GetValue(_plugin) as History;
Assert.That(history, Is.Not.Null,
"Property 'History' on Flow.Launcher.Plugin.Calculator.Main' was not a calculator History instance");

return history!;
}

private void SetHistory(History history)
{
var historyProperty = typeof(Main).GetProperty("History", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.That(historyProperty, Is.Not.Null,
"Could not find property 'History' on Flow.Launcher.Plugin.Calculator.Main");

historyProperty!.SetValue(_plugin, history);
}
}
}
23 changes: 23 additions & 0 deletions Plugins/Flow.Launcher.Plugin.Calculator/HistoryCreationMode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Flow.Launcher.Localization.Attributes;

namespace Flow.Launcher.Plugin.Calculator
{
/// <summary>
/// Represents the different modes for saving calculator calculations into the history.
/// </summary>
[EnumLocalize]
public enum HistoryCreationMode
{
/// <summary>
/// Saves calculations into the history automatically as the query is typed.
/// </summary>
[EnumLocalizeKey(nameof(Localize.flowlauncher_plugin_calculator_history_creation_mode_on_query))]
OnQuery,

/// <summary>
/// Saves calculations into the history only when the action is executed (e.g. Enter is pressed).
/// </summary>
[EnumLocalizeKey(nameof(Localize.flowlauncher_plugin_calculator_history_creation_mode_on_enter))]
OnEnter
}
}
101 changes: 101 additions & 0 deletions Plugins/Flow.Launcher.Plugin.Calculator/HistoryHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using System;
using System.Globalization;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.Calculator.Storage;

namespace Flow.Launcher.Plugin.Calculator
{
/// <summary>
/// Helper class providing utility methods for formatting relative time strings and creating pending history items.
/// </summary>
internal static class HistoryHelper
{
/// <summary>
/// Formats a DateTime value into a localized relative time string (e.g. "just now", "5 minutes ago").
/// </summary>
/// <param name="context">The plugin init context used to retrieve localized strings.</param>
/// <param name="calculatedAt">The time when the calculation was recorded.</param>
/// <returns>A localized relative time delta string.</returns>
public static string GetTimeDeltaString(PluginInitContext context, DateTime calculatedAt)
{
var now = DateTime.Now;
var timeSpan = now - calculatedAt;

if (timeSpan.TotalSeconds < 0)
{
timeSpan = TimeSpan.Zero;
}

if (timeSpan.TotalSeconds < 60)
{
return context == null ? "just now" : Localize.flowlauncher_plugin_calculator_time_just_now();
}
if (timeSpan.TotalMinutes < 60)
{
var minutes = (int)timeSpan.TotalMinutes;
if (minutes == 1)
{
return context == null ? "1 minute ago" : Localize.flowlauncher_plugin_calculator_time_minute_ago();
}
return context == null ? $"{minutes} minutes ago" : Localize.flowlauncher_plugin_calculator_time_minutes_ago(minutes);
}
if (timeSpan.TotalHours < 24)
{
var hours = (int)timeSpan.TotalHours;
if (hours == 1)
{
return context == null ? "1 hour ago" : Localize.flowlauncher_plugin_calculator_time_hour_ago();
}
return context == null ? $"{hours} hours ago" : Localize.flowlauncher_plugin_calculator_time_hours_ago(hours);
}
if (timeSpan.TotalDays < 30)
{
var days = (int)timeSpan.TotalDays;
if (days == 1)
{
return context == null ? "1 day ago" : Localize.flowlauncher_plugin_calculator_time_day_ago();
}
return context == null ? $"{days} days ago" : Localize.flowlauncher_plugin_calculator_time_days_ago(days);
}
if (timeSpan.TotalDays < 365)
{
var months = (int)(timeSpan.TotalDays / 30);
if (months == 1)
{
return context == null ? "1 month ago" : Localize.flowlauncher_plugin_calculator_time_month_ago();
}
return context == null ? $"{months} months ago" : Localize.flowlauncher_plugin_calculator_time_months_ago(months);
}
var years = (int)(timeSpan.TotalDays / 365);
if (years == 1)
{
return context == null ? "1 year ago" : Localize.flowlauncher_plugin_calculator_time_year_ago();
}
return context == null ? $"{years} years ago" : Localize.flowlauncher_plugin_calculator_time_years_ago(years);
}

/// <summary>
/// Creates a <see cref="PendingHistoryItem"/> representing a calculation that is currently being typed by the user.
/// </summary>
/// <param name="context">The plugin init context.</param>
/// <param name="result">The query result object.</param>
/// <param name="calcResult">The text representation of the calculation result.</param>
/// <param name="expression">The math expression string.</param>
/// <returns>A new <see cref="PendingHistoryItem"/> instance.</returns>
public static PendingHistoryItem CreatePendingHistoryItem(PluginInitContext context, Result result, string calcResult, string expression)
{
var calculatedAt = DateTime.Now;
var copyToClipboard = context == null
? "Copy this number to the clipboard"
: Localize.flowlauncher_plugin_calculator_copy_number_to_clipboard();
var timeDeltaStr = GetTimeDeltaString(context, calculatedAt);
var historySubtitle = context == null
? string.Format(CultureInfo.CurrentCulture, "Calculated {0}", timeDeltaStr)
: Localize.flowlauncher_plugin_calculator_history_subtitle(timeDeltaStr);
var subtitle =
$"{calcResult} - {copyToClipboard}" +
$"\n{historySubtitle}";
return new PendingHistoryItem(result, expression, result.Action, subtitle, calculatedAt);
}
}
}
Comment thread
DavidGBrett marked this conversation as resolved.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 19 additions & 1 deletion Plugins/Flow.Launcher.Plugin.Calculator/Languages/en.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,22 @@
<system:String x:Key="flowlauncher_plugin_calculator_use_thousands_separator">Show thousands separator in results</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_failed_to_copy">Copy failed, please try later</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_show_error_message">Show error message when calculation fails</system:String>
</ResourceDictionary>
<system:String x:Key="flowlauncher_plugin_calculator_enable_history">Enable History</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_history_subtitle">{0}</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_time_just_now">just now</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_time_minute_ago">1 minute ago</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_time_minutes_ago">{0} minutes ago</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_time_hour_ago">1 hour ago</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_time_hours_ago">{0} hours ago</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_time_day_ago">1 day ago</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_time_days_ago">{0} days ago</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_time_month_ago">1 month ago</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_time_months_ago">{0} months ago</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_time_year_ago">1 year ago</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_time_years_ago">{0} years ago</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_history_creation_mode">History save mode</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_history_creation_mode_on_query">Save on query</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_history_creation_mode_on_enter">Save on Enter</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_history_creation_mode_warning">Warning: Due to the plugin's architecture, saving on query may register incomplete calculations in the history while you type.</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_copy_result_to_clipboard">Copy the result of this expression to the clipboard</system:String>
</ResourceDictionary>
8 changes: 7 additions & 1 deletion Plugins/Flow.Launcher.Plugin.Calculator/Languages/pt-br.xaml

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, could you please revert changes in this file?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The recent commit a7efe5d seems intended to revert that but there are still changes showing up for me

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0"?>
<?xml version="1.0"?>
Comment thread
01Dri marked this conversation as resolved.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System;assembly=mscorlib">

<system:String x:Key="flowlauncher_plugin_calculator_plugin_name">Calculadora</system:String>
Expand All @@ -15,4 +15,10 @@
<system:String x:Key="flowlauncher_plugin_calculator_use_thousands_separator">Show thousands separator in results</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_failed_to_copy">Copy failed, please try later</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_show_error_message">Show error message when calculation fails</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_enable_history">Habilitar Histórico</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_history_subtitle">Calculado em {0}</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_history_creation_mode">Modo de salvar no histórico</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_history_creation_mode_on_query">Salvar por query</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_history_creation_mode_on_enter">Salvar por enter</system:String>
<system:String x:Key="flowlauncher_plugin_calculator_history_creation_mode_warning">Aviso: Devido à arquitetura do plugin, salvar por query pode registrar cálculos incompletos no histórico enquanto você digita.</system:String>
</ResourceDictionary>
Loading
Loading