Skip to content

Commit

Permalink
Date Format Tweaks (#675)
Browse files Browse the repository at this point in the history
* Add instructions field to config editboxes

This can be used for default values or placeholder text.

* Allow advanced date format configuration

Instead of using a dropdown we'll allow people to just outright
fully customize the format manually. If left as an empty string,
a default based upon the configured addon locale will be used
appropriate to external references for worldwide date formats.

* Use GetPreferredLocale function elsewhere

Also remove a few bits of code that were listening to locale changes;
this isn't ever going to take off :)

* Clean up unused vars

* Lowercase 'Format' in setting name

* Add safety wrapper for generating date strings

As some date format inputs are invalid ("%N"), a new utility to
format a timestamp/time table to a date string has been added which
will fall back to the default locale-specific date format if an error
occurs during formatting.

* Clarify help text for other characters

* Use securecall for protected calls

This allows the debug locals dump to include the problematic
format string.
  • Loading branch information
Meorawr committed Dec 9, 2022
1 parent c8fc292 commit f6eafd0
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 72 deletions.
2 changes: 2 additions & 0 deletions .luacheckrc
Expand Up @@ -428,6 +428,7 @@ stds.wow = {
"ScrollingEdit_OnLoad",
"ScrollingEdit_OnTextChanged",
"SecondsToClock",
"securecall",
"securecallfunction",
"SecureCmdOptionParse",
"SendChatMessage",
Expand Down Expand Up @@ -567,6 +568,7 @@ stds.wow = {
"LE_PET_JOURNAL_FILTER_NOT_COLLECTED",
"LE_SORT_BY_LEVEL",
"LIST_DELIMITER",
"LOCALE_enGB",
"LOCALIZED_CLASS_NAMES_MALE",
"LUNAR_POWER",
"MAELSTROM",
Expand Down
2 changes: 1 addition & 1 deletion Scripts/mature_dictionary_template.lua
Expand Up @@ -3,7 +3,7 @@ local currentLocale = DEFAULT_LOCALE;

function TRP3_API.utils.resources.getMatureFilterDictionary()

currentLocale = TRP3_API.configuration.getValue("AddonLocale");
currentLocale = TRP3_API.utils.GetPreferredLocale();
if not dictionary[currentLocale] then
currentLocale = DEFAULT_LOCALE;
end
Expand Down
50 changes: 30 additions & 20 deletions totalRP3/Core/Configuration.lua
Expand Up @@ -192,12 +192,14 @@ local function buildConfigurationPage(structure)
if element.configKey then
box:SetScript("OnTextChanged", function(self)
local value = self:GetText();
self.Instructions:SetShown(value == "");
setValue(element.configKey, value);
end);
box:SetText(tostring(getValue(element.configKey)));
end
box:SetNumeric(element.numeric);
box:SetMaxLetters(element.maxLetters or 0);
box.Instructions:SetText(element.instructions or "");
local boxTitle = _G[widget:GetName().."BoxText"];
if boxTitle then
boxTitle:SetText(element.boxTitle);
Expand Down Expand Up @@ -378,16 +380,13 @@ TRP3_API.events.listenToEvent(TRP3_API.events.WORKFLOW_ON_LOAD, function()
tinsert(localeTab, { locale:GetName(), locale:GetCode() });
end

--date format options
local date_option_enum = AddOn_TotalRP3.Enums.DATE_OPTIONS;

registerConfigKey("heavy_profile_alert", true);
registerConfigKey("new_version_alert", true);
registerConfigKey("ui_sounds", true);
registerConfigKey("ui_animations", true);
registerConfigKey("default_color_picker", false);
registerConfigKey("increase_color_contrast", false);
registerConfigKey("date_format", date_option_enum.D_M_Y);
registerConfigKey("date_format", "");

-- Build widgets
TRP3_API.configuration.CONFIG_STRUCTURE_GENERAL = {
Expand Down Expand Up @@ -444,23 +443,34 @@ TRP3_API.events.listenToEvent(TRP3_API.events.WORKFLOW_ON_LOAD, function()
end,
},
{
inherit = "TRP3_ConfigDropDown",
inherit = "TRP3_ConfigEditBox",
title = loc.CO_DATE_FORMAT,
listContent = {
{ date_option_enum.D_M_Y, "%d/%m/%y %H:%M" },
{ date_option_enum.M_D_Y, "%m/%d/%y %H:%M" },
{ date_option_enum.Y_M_D, "%y/%m/%d %H:%M" }
},
listCallback = function(newDateFormat)
local ancientDateFormatValue = getValue("date_format")
if newDateFormat == ancientDateFormatValue then
-- Date isn't changing.
return;
end

setValue("date_format", newDateFormat);
end,
listDefault = date_option_enum.D_M_Y,
configKey = "date_format",
help = (function()
-- Unix timestamp for Mon Jan 2 15:04:05 UTC 2006.
local timestamp = 1136214245;

local specifiers =
{
string.format(loc.CO_DATE_FORMAT_SPEC_a, TRP3_API.Ellyb.ColorManager.CYAN("%a"), TRP3_API.Ellyb.ColorManager.GREEN(date("!%a", timestamp))),
string.format(loc.CO_DATE_FORMAT_SPEC_A, TRP3_API.Ellyb.ColorManager.CYAN("%A"), TRP3_API.Ellyb.ColorManager.GREEN(date("!%A", timestamp))),
string.format(loc.CO_DATE_FORMAT_SPEC_b, TRP3_API.Ellyb.ColorManager.CYAN("%b"), TRP3_API.Ellyb.ColorManager.GREEN(date("!%b", timestamp))),
string.format(loc.CO_DATE_FORMAT_SPEC_B, TRP3_API.Ellyb.ColorManager.CYAN("%B"), TRP3_API.Ellyb.ColorManager.GREEN(date("!%B", timestamp))),
string.format(loc.CO_DATE_FORMAT_SPEC_d, TRP3_API.Ellyb.ColorManager.CYAN("%d"), TRP3_API.Ellyb.ColorManager.GREEN(date("!%d", timestamp))),
string.format(loc.CO_DATE_FORMAT_SPEC_H, TRP3_API.Ellyb.ColorManager.CYAN("%H"), TRP3_API.Ellyb.ColorManager.GREEN(date("!%H", timestamp))),
string.format(loc.CO_DATE_FORMAT_SPEC_I, TRP3_API.Ellyb.ColorManager.CYAN("%I"), TRP3_API.Ellyb.ColorManager.GREEN(date("!%I", timestamp))),
string.format(loc.CO_DATE_FORMAT_SPEC_m, TRP3_API.Ellyb.ColorManager.CYAN("%m"), TRP3_API.Ellyb.ColorManager.GREEN(date("!%m", timestamp))),
string.format(loc.CO_DATE_FORMAT_SPEC_M, TRP3_API.Ellyb.ColorManager.CYAN("%M"), TRP3_API.Ellyb.ColorManager.GREEN(date("!%M", timestamp))),
string.format(loc.CO_DATE_FORMAT_SPEC_p, TRP3_API.Ellyb.ColorManager.CYAN("%p"), TRP3_API.Ellyb.ColorManager.GREEN(date("!%p", timestamp))),
string.format(loc.CO_DATE_FORMAT_SPEC_S, TRP3_API.Ellyb.ColorManager.CYAN("%S"), TRP3_API.Ellyb.ColorManager.GREEN(date("!%S", timestamp))),
string.format(loc.CO_DATE_FORMAT_SPEC_y, TRP3_API.Ellyb.ColorManager.CYAN("%y"), TRP3_API.Ellyb.ColorManager.GREEN(date("!%y", timestamp))),
string.format(loc.CO_DATE_FORMAT_SPEC_Y, TRP3_API.Ellyb.ColorManager.CYAN("%Y"), TRP3_API.Ellyb.ColorManager.GREEN(date("!%Y", timestamp))),
string.format(loc.CO_DATE_FORMAT_SPEC_ESC, TRP3_API.Ellyb.ColorManager.CYAN("%%")),
};

return string.format(loc.CO_DATE_FORMAT_HELP, table.concat(specifiers, "|n"))
end)(),
instructions = Utils.GetDefaultDateFormat(),
}
}
}
Expand Down
7 changes: 0 additions & 7 deletions totalRP3/Core/Enums.lua
Expand Up @@ -44,10 +44,3 @@ AddOn_TotalRP3.Enums.UNIT_TYPE = {
MOUNT = "MOUNT", -- Not a real unit, but used for companion profiles.
NPC = "NPC",
};

-- Configuration --
AddOn_TotalRP3.Enums.DATE_OPTIONS = {
D_M_Y = "D/M/Y",
M_D_Y = "M/D/Y",
Y_M_D = "Y/M/D"
}
65 changes: 62 additions & 3 deletions totalRP3/Core/Utils.lua
Expand Up @@ -1353,6 +1353,65 @@ TRP3_API.utils.Oldgodify = Oldgodify;
-- Settings
--*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

function Utils.getPreferredDateFormat()
return TRP3_API.configuration.getValue("date_format");
end
function Utils.GetDefaultLocale()
return GAME_LOCALE or GetLocale();
end

function Utils.GetPreferredLocale()
-- TODO: Our addon locale setting unfortunately defaults to the client
-- locale and gets sticky - if you install the addon on an esMX client
-- and then change to a ptBR one it'd stay set to esMX. As such, the
-- default fallback will almost always never actually occur.

return TRP3_API.configuration.getValue("AddonLocale") or Utils.GetDefaultLocale();
end

-- Ref: <https://en.wikipedia.org/wiki/Date_format_by_country>
local LOCALIZED_DATE_FORMATS =
{
deDE = "%d/%m/%Y %H:%M",
enGB = "%d/%m/%Y %H:%M",
enUS = "%m/%d/%Y %H:%M",
esES = "%d/%m/%Y %H:%M",
esMX = "%d/%m/%Y %H:%M",
frFR = "%d/%m/%Y %H:%M",
itIT = "%d/%m/%Y %H:%M",
koKR = "%Y-%m-%d %H:%M",
ptBR = "%d/%m/%Y %H:%M",
ptPT = "%d/%m/%Y %H:%M",
ruRU = "%Y-%m-%d %H:%M",
zhCN = "%Y-%m-%d %H:%M",
zhTW = "%Y-%m-%d %H:%M",
};

function Utils.GetDefaultDateFormat()
local locale = Utils.GetPreferredLocale();

if locale == "enUS" and LOCALE_enGB then
locale = "enGB";
end

return LOCALIZED_DATE_FORMATS[locale] or LOCALIZED_DATE_FORMATS.enGB;
end

function Utils.GetPreferredDateFormat()
local format = TRP3_API.configuration.getValue("date_format");

if type(format) ~= "string" or format == "" then
format = Utils.GetDefaultDateFormat();
end

return format;
end

function Utils.GenerateFormattedDateString(time)
local format = Utils.GetPreferredDateFormat();
local result = securecall(date, format, time);

if not result then
format = Utils.GetDefaultDateFormat();
result = date(format, time);
end

return result;
end
18 changes: 17 additions & 1 deletion totalRP3/Locales/Locale.lua
Expand Up @@ -1453,7 +1453,23 @@ If you wish to report %s's profile and you cannot target them you will need to o
- Fixed an issue with chat links that could lead to blocked actions.
]],
CO_DATE_FORMAT = "Date Format",

CO_DATE_FORMAT = "Date format",
CO_DATE_FORMAT_HELP = "Format string used for date/time strings in the addon.|n|nIf left empty, this will display date/time strings in a format appropriate to the configured locale of the addon.|n|nThe following format specifiers are supported:|n|n%1$s|n|nAll other characters are treated literally.",
CO_DATE_FORMAT_SPEC_a = "%1$s: Abbreviated weekday name (%2$s)",
CO_DATE_FORMAT_SPEC_A = "%1$s: Full weekday name (%2$s)",
CO_DATE_FORMAT_SPEC_b = "%1$s: Abbreviated month name (%2$s)",
CO_DATE_FORMAT_SPEC_B = "%1$s: Full month name (%2$s)",
CO_DATE_FORMAT_SPEC_d = "%1$s: Day of the month (%2$s)",
CO_DATE_FORMAT_SPEC_H = "%1$s: Hour using a 24-hour clock (%2$s)",
CO_DATE_FORMAT_SPEC_I = "%1$s: Hour using a 12-hour clock (%2$s)",
CO_DATE_FORMAT_SPEC_m = "%1$s: Month (%2$s)",
CO_DATE_FORMAT_SPEC_M = "%1$s: Minute (%2$s)",
CO_DATE_FORMAT_SPEC_p = "%1$s: Either 'am' or 'pm' (%2$s)",
CO_DATE_FORMAT_SPEC_S = "%1$s: Second (%2$s)",
CO_DATE_FORMAT_SPEC_y = "%1$s: Two-digit year (%2$s)",
CO_DATE_FORMAT_SPEC_Y = "%1$s: Full year (%2$s)",
CO_DATE_FORMAT_SPEC_ESC = "%1$s: The literal character '%%'",
};

-- Use Ellyb to generate the Localization system
Expand Down
39 changes: 2 additions & 37 deletions totalRP3/Modules/Dashboard/StatusPanel.lua
Expand Up @@ -6,7 +6,6 @@ local _, TRP3_API = ...;

-- TRP imports.
local L = TRP3_API.loc;
local Config = TRP3_API.configuration;
local Enums = AddOn_TotalRP3.Enums;
local Events = TRP3_API.events;
local Globals = TRP3_API.globals;
Expand All @@ -29,20 +28,7 @@ TRP3_DashboardStatusPanelMixin = DashboardStatusPanelMixin;

-- Handler called when the frame is loaded.
function DashboardStatusPanelMixin:OnLoad()
Events.registerCallback(Events.WORKFLOW_ON_LOADED, function(...) self:OnWorkflowLoaded(...); end);
end

-- Handler called when addon workflow reaches the loaded state.
function DashboardStatusPanelMixin:OnWorkflowLoaded()
-- Defer registering config handlers to here, since OnLoad is too early.
Config.registerHandler({ "AddonLocale" }, function(...) self:OnLocaleChanged(...); end);

self:LocalizeUI();
end

-- Handler called when the addon locale changes.
function DashboardStatusPanelMixin:OnLocaleChanged()
self:LocalizeUI();
Events.registerCallback(Events.WORKFLOW_ON_LOADED, function() self:LocalizeUI(); end);
end

-- Updates all localization-dependant parts of the UI.
Expand All @@ -59,7 +45,7 @@ TRP3_DashboardStatusMenuMixin = DashboardStatusMenuMixin;

-- Handler called when the menu frame is loaded.
function DashboardStatusMenuMixin:OnLoad()
Events.registerCallback(Events.WORKFLOW_ON_LOADED, function(...) self:OnWorkflowLoaded(...); end);
Events.registerCallback(Events.WORKFLOW_ON_LOADED, function(...) self:InitializeMenu(...); end);
Events.registerCallback(Events.REGISTER_DATA_UPDATED, function(...) self:OnRegisterDataUpdated(...); end);
end

Expand All @@ -68,27 +54,6 @@ function DashboardStatusMenuMixin:OnShow()
self:RefreshMenu();
end

-- Handler called when the addon workflow reaches the loaded state.
function DashboardStatusMenuMixin:OnWorkflowLoaded()
-- Defer registering config handlers to here, since OnLoad is too early.
Config.registerHandler({ "AddonLocale" },
function(...) self:OnLocaleChanged(...); end);

self:InitializeMenu();
end

-- Handler called when the addon locale is changed.
function DashboardStatusMenuMixin:OnLocaleChanged()
if MSA_DROPDOWNMENU_OPEN_MENU == self then
-- Changing the locale will re-initialize the whole menu due to the
-- fact that the individual buttons within will be localized.
self:InitializeMenu();
else
-- Menu isn't open so we don't want to re-initialize.
self:RefreshMenu();
end
end

-- Handler called when register data is updated.
function DashboardStatusMenuMixin:OnRegisterDataUpdated(unitID, _, dataType)
if unitID ~= Globals.player_id then
Expand Down
Expand Up @@ -1020,7 +1020,7 @@ local currentLocale = DEFAULT_LOCALE;

function TRP3_API.utils.resources.getMatureFilterDictionary()

currentLocale = TRP3_API.configuration.getValue("AddonLocale");
currentLocale = TRP3_API.utils.GetPreferredLocale();
if not dictionary[currentLocale] then
currentLocale = DEFAULT_LOCALE;
end
Expand Down
4 changes: 2 additions & 2 deletions totalRP3/Modules/Register/Main/RegisterList.lua
Expand Up @@ -278,7 +278,7 @@ local function decorateCharacterLine(line, characterIndex)
end

if profile.time and profile.zone then
local formatDate = date(Utils.getPreferredDateFormat(), profile.time);
local formatDate = Utils.GenerateFormattedDateString(profile.time);
leftTooltipText = leftTooltipText .. "\n|r" .. loc.REG_LIST_CHAR_TT_DATE:format(formatDate, profile.zone);
end
-- Middle column : relation
Expand All @@ -294,7 +294,7 @@ local function decorateCharacterLine(line, characterIndex)

local timeStr = "";
if profile.time then
timeStr = date(Utils.getPreferredDateFormat(), profile.time);
timeStr = Utils.GenerateFormattedDateString(profile.time);
end
_G[line:GetName().."Time"]:SetText(timeStr);

Expand Down
7 changes: 7 additions & 0 deletions totalRP3/UI/Configuration.xml
Expand Up @@ -91,6 +91,13 @@ https://raw.githubusercontent.com/Meorawr/wow-ui-schema/main/UI.xsd">
<Anchors>
<Anchor point="RIGHT" x="-10" y="0"/>
</Anchors>
<Layers>
<Layer level="BORDER">
<FontString parentKey="Instructions" justifyH="LEFT" justifyV="MIDDLE" inherits="GameFontDisableSmall" setAllPoints="true">
<Color r="0.35" g="0.35" b="0.35"/>
</FontString>
</Layer>
</Layers>
</EditBox>
</Frames>
</Frame>
Expand Down

0 comments on commit f6eafd0

Please sign in to comment.