From 5e4e3ace4f6f738b13b0ccd6dcfb2f6b1b8b7727 Mon Sep 17 00:00:00 2001 From: Soba Date: Tue, 17 Mar 2026 19:25:45 +0300 Subject: [PATCH 1/5] feat: add ControlsSettingsTable module --- lua/wikis/commons/ControlsSettingsTable.lua | 52 ++++++ .../commons/ControlsSettingsTable/Custom.lua | 49 +++++ .../commons/Widget/ControlsSettingsTable.lua | 174 ++++++++++++++++++ stylesheets/commons/ResponsiveTable.scss | 39 +++- 4 files changed, 312 insertions(+), 2 deletions(-) create mode 100644 lua/wikis/commons/ControlsSettingsTable.lua create mode 100644 lua/wikis/commons/ControlsSettingsTable/Custom.lua create mode 100644 lua/wikis/commons/Widget/ControlsSettingsTable.lua diff --git a/lua/wikis/commons/ControlsSettingsTable.lua b/lua/wikis/commons/ControlsSettingsTable.lua new file mode 100644 index 00000000000..56dfe49669c --- /dev/null +++ b/lua/wikis/commons/ControlsSettingsTable.lua @@ -0,0 +1,52 @@ +--- +-- @Liquipedia +-- page=Module:ControlsSettingsTable +-- +-- Please see https://github.com/Liquipedia/Lua-Modules to contribute +-- +local Lua = require('Module:Lua') + +local Arguments = Lua.import('Module:Arguments') +local Class = Lua.import('Module:Class') + +local ControlsSettingsTableWidget = Lua.import('Module:Widget/ControlsSettingsTable') + +local ControlsSettingsTable = Class.new() + +---@param lpdbConfig string[] +---@param columnConfig ColumnConfig[] +---@param frame table +---@return Widget? +function ControlsSettingsTable.create(lpdbConfig, columnConfig, frame) + local args = Arguments.getArgs(frame) + local widget = ControlsSettingsTableWidget(columnConfig, args) + ControlsSettingsTable.saveToLpdb(lpdbConfig, args) + return widget:tryMake() +end + +---@param lpdbConfig string[] +---@param args {[string]: string?} +function ControlsSettingsTable.saveToLpdb(lpdbConfig, args) + local title = mw.title.getCurrentTitle().text + local extradata = ControlsSettingsTable.generateLpdbExtradata(lpdbConfig, args) + mw.ext.LiquipediaDB.lpdb_settings(title, { + name = 'movement', + reference = args.ref, + lastupdated = args.date, + gamesettings = mw.ext.LiquipediaDB.lpdb_create_json(extradata), + type = (args.controller or ''):lower(), + }) +end + +---@param lpdbConfig string[] +---@param args {[string]: string?} +---@return {[string]: string?} +function ControlsSettingsTable.generateLpdbExtradata(lpdbConfig, args) + local result = {} + for _, key in ipairs(lpdbConfig) do + result[key:lower()] = args[key:lower()] + end + return result +end + +return ControlsSettingsTable diff --git a/lua/wikis/commons/ControlsSettingsTable/Custom.lua b/lua/wikis/commons/ControlsSettingsTable/Custom.lua new file mode 100644 index 00000000000..9d5f9aa4812 --- /dev/null +++ b/lua/wikis/commons/ControlsSettingsTable/Custom.lua @@ -0,0 +1,49 @@ +--- +-- @Liquipedia +-- page=Module:ControlsSettingsTable/Custom +-- +-- Please see https://github.com/Liquipedia/Lua-Modules to contribute +-- + +local Lua = require('Module:Lua') + +local Arguments = Lua.import('Module:Arguments') +local Class = Lua.import('Module:Class') + +local ControlsSettingsTable = Lua.import('Module:ControlsSettingsTable') + +local CustomControlsSettingsTable = Class.new(ControlsSettingsTable) + +---@type string[] +local LPDB_CONFIG = {} +--local LPDB_CONFIG = {'Accelerate', 'Brake', 'Steering'} + +---@type ColumnConfig[] +local BASE_COLUMN_CONFIG = {} +--[[ +local BASE_COLUMN_CONFIG = { + {key = 'Steering', title = 'Steering'}, + {keys = {{key = 'Accelerate'}, ' / ', {key = 'Brake'}}, title = 'Accelerate/Brake'} +} +--]] + +---@param args {[string]: string?} +---@return ColumnConfig[] +local function makeColumnConfig(args) + local COLUMN_CONFIG = {} + for _, col in ipairs(BASE_COLUMN_CONFIG) do + table.insert(COLUMN_CONFIG, col) + end + + return COLUMN_CONFIG +end + +---@param frame table +---@return Widget? +function CustomControlsSettingsTable.create(frame) + local args = Arguments.getArgs(frame) + local COLUMN_CONFIG = makeColumnConfig(args) + return ControlsSettingsTable.create(LPDB_CONFIG, COLUMN_CONFIG, frame) +end + +return CustomControlsSettingsTable diff --git a/lua/wikis/commons/Widget/ControlsSettingsTable.lua b/lua/wikis/commons/Widget/ControlsSettingsTable.lua new file mode 100644 index 00000000000..cb0bf45bcdd --- /dev/null +++ b/lua/wikis/commons/Widget/ControlsSettingsTable.lua @@ -0,0 +1,174 @@ +--- +-- @Liquipedia +-- page=Module:Widget/ControlsSettingsTable +-- +-- Please see https://github.com/Liquipedia/Lua-Modules to contribute +-- + +local Lua = require('Module:Lua') + +local Array = Lua.import('Module:Array') +local Class = Lua.import('Module:Class') +local Page = Lua.import('Module:Page') +local String = Lua.import('Module:StringUtils') +local Template = Lua.import('Module:Template') + +local Widget = Lua.import('Module:Widget') +local HtmlWidgets = Lua.import('Module:Widget/Html/All') +local WidgetUtil = Lua.import('Module:Widget/Util') + +local SETTINGS_LINK = 'Control settings' + +---@alias ColumnConfig +---| {key: string, title: string} +---| {keys: ({key: string} | string)[], title: string} +---@alias ColumnValue {title: string, value: fun(data: {[string]: string?}): string?} + +---@class ControlsSettingsTableWidget: Widget +---@field args {[string]: string?} +---@field columnConfig ColumnConfig[] +---@field frame table +local ControlsSettingsTableWidget = Class.new(Widget, + function(self, columnConfig, args, frame) + self.columnConfig = columnConfig + self.args = args + self.frame = frame or mw.getCurrentFrame() + end +) + +---@return Widget? +function ControlsSettingsTableWidget:render() + local header = self:renderHeader() + local footer = self:renderFooter() + local visibleColumns = self:getVisibleColumns() + + return HtmlWidgets.Div{ + classes = {'table-responsive'}, + children = {self:renderTable(header, footer, visibleColumns)} + } +end + +---@return string +function ControlsSettingsTableWidget:renderHeader() + local args = self.args + local frame = self.frame + local header = Page.exists(SETTINGS_LINK) and '[['.. SETTINGS_LINK ..']] ' or SETTINGS_LINK..' ' + if args.ref == 'insidesource' then + header = header .. frame:callParserFunction{ + name = '#tag', + args = { 'ref', Template.safeExpand(frame, 'inside source') } + } + elseif args.ref then + header = header .. frame:callParserFunction{ + name = '#tag', + args = { 'ref', args['ref'] } + } + end + return header .. " ([[List of player control settings|list of]])'''" +end + +---@return string +function ControlsSettingsTableWidget:renderFooter() + local args = self.args + if args.date then + local year, month, day = (args.date):match('(%d+)-(%d+)-(%d+)') + local dayAgo = math.floor((os.time() - os.time{year=year, month=month, day=day}) / 86400) + return 'Last updated on '.. args.date ..' (' .. dayAgo ..' days ago).' + end + return 'No date of last update specified!' +end + +---@return ColumnValue[] +function ControlsSettingsTableWidget:getVisibleColumns() + return Array.flatMap(self.columnConfig, function(config) + local column = self:makeColumn(config) + return String.isNotEmpty(column.value(self.args)) and { column } or {} + end) +end + +---@param config ColumnConfig +---@return ColumnValue +function ControlsSettingsTableWidget:makeColumn(config) + return { + title = config.title, + value = function(data) + if config.keys then + local values = {} + local hasValue = false + for _, item in ipairs(config.keys) do + if type(item) == 'table' then + local formatted = self:formatKeyValue(item.key, data) + table.insert(values, formatted or '-') + if formatted then hasValue = true end + else + table.insert(values, item) + end + end + return hasValue and table.concat(values) or nil + elseif config.key then + return self:formatKeyValue(config.key, data) + end + end + } +end + +---@param key string +---@param data {[string]: string?} +---@return string? +function ControlsSettingsTableWidget:formatKeyValue(key, data) + local keyValue = data[key:lower()] + if not keyValue or String.isEmpty(keyValue) then + return nil + end + if data.controller and data.controller:lower() == 'kbm' then + return '' .. keyValue .. '' + end + return '[[File:' .. self:getImageName(data.controller, keyValue) .. '.svg|' .. key .. '|link=]]' +end + +---@param device string? +---@param key string? +---@return string? +function ControlsSettingsTableWidget:getImageName(device, key) + return Template.safeExpand(self.frame, 'Button translation', {(device or ''):lower(), (key or ''):lower()}) +end + +---@param header string +---@param footer string +---@param visibleColumns ColumnValue[] +---@return Widget +function ControlsSettingsTableWidget:renderTable(header, footer, visibleColumns) + return HtmlWidgets.Table{ + classes = {'wikitable', 'controls-responsive-table'}, + css = {['table-layout'] = 'auto'}, + children = WidgetUtil.collect( + HtmlWidgets.Tr{children = { + HtmlWidgets.Th{ + attributes = {colspan = #self.columnConfig}, + children = header + } + }}, + HtmlWidgets.Tr{children = Array.map(visibleColumns, function(column) + return HtmlWidgets.Th{children = column.title} + end)}, + HtmlWidgets.Tr{children = Array.map(visibleColumns, function(column) + return HtmlWidgets.Td{ + attributes = {['data-label'] = column.title}, + children = column.value(self.args) + } + end)}, + HtmlWidgets.Tr{children = { + HtmlWidgets.Th{ + attributes = {colspan = #self.columnConfig}, + css = { + ['font-size'] = '85%', + padding = '2px', + }, + children = footer + } + }} + ) + } +end + +return ControlsSettingsTableWidget diff --git a/stylesheets/commons/ResponsiveTable.scss b/stylesheets/commons/ResponsiveTable.scss index 4799ebd60ca..a5c51df2a68 100644 --- a/stylesheets/commons/ResponsiveTable.scss +++ b/stylesheets/commons/ResponsiveTable.scss @@ -1,7 +1,42 @@ /******************************************************************************* -Template(s): Rocket League Responsive Table -Author(s): QuadratClown +Template(s): Responsive Table +Author(s): QuadratClown, SobakaPirat *******************************************************************************/ +.controls-responsive-table { + margin: 0; + + td { + text-align: center; + } + + @media screen and ( max-width: 947px ) { + width: 100%; + + tr { + display: block; + } + + tr:nth-child( 2 ) { + display: none; + } + + th, + td { + display: block; + width: 100%; + font-size: 0.8em; + text-align: right; + border-left: 0; + + &::before { + content: attr( data-label ); + float: left; + font-weight: bold; + } + } + } +} + .rl-responsive-table { border-collapse: collapse; margin: 0; From bb43c74d45c3f9f5f0876a4a898c1d2c99792031 Mon Sep 17 00:00:00 2001 From: Soba Date: Thu, 19 Mar 2026 18:55:48 +0300 Subject: [PATCH 2/5] overhaul --- lua/wikis/commons/ControlsSettingsTable.lua | 32 +-- .../commons/ControlsSettingsTable/Custom.lua | 49 ---- lua/wikis/commons/Links/ButtonTranslation.lua | 59 +++++ .../commons/Widget/ControlsSettingsTable.lua | 243 +++++++++--------- 4 files changed, 198 insertions(+), 185 deletions(-) delete mode 100644 lua/wikis/commons/ControlsSettingsTable/Custom.lua create mode 100644 lua/wikis/commons/Links/ButtonTranslation.lua diff --git a/lua/wikis/commons/ControlsSettingsTable.lua b/lua/wikis/commons/ControlsSettingsTable.lua index 56dfe49669c..f36d88ea11f 100644 --- a/lua/wikis/commons/ControlsSettingsTable.lua +++ b/lua/wikis/commons/ControlsSettingsTable.lua @@ -8,27 +8,27 @@ local Lua = require('Module:Lua') local Arguments = Lua.import('Module:Arguments') local Class = Lua.import('Module:Class') +local Info = Lua.import('Module:Info') local ControlsSettingsTableWidget = Lua.import('Module:Widget/ControlsSettingsTable') local ControlsSettingsTable = Class.new() ----@param lpdbConfig string[] ----@param columnConfig ColumnConfig[] ---@param frame table ----@return Widget? -function ControlsSettingsTable.create(lpdbConfig, columnConfig, frame) +---@return Widget +function ControlsSettingsTable.create(frame) local args = Arguments.getArgs(frame) + local columnConfig = Info.controlsSettingsTable local widget = ControlsSettingsTableWidget(columnConfig, args) - ControlsSettingsTable.saveToLpdb(lpdbConfig, args) - return widget:tryMake() + ControlsSettingsTable.saveToLpdb(columnConfig, args) + return widget:render() end ----@param lpdbConfig string[] +---@param columnConfig {keys: string[], title: string} ---@param args {[string]: string?} -function ControlsSettingsTable.saveToLpdb(lpdbConfig, args) +function ControlsSettingsTable.saveToLpdb(columnConfig, args) local title = mw.title.getCurrentTitle().text - local extradata = ControlsSettingsTable.generateLpdbExtradata(lpdbConfig, args) + local extradata = ControlsSettingsTable.generateLpdbExtradata(columnConfig, args) mw.ext.LiquipediaDB.lpdb_settings(title, { name = 'movement', reference = args.ref, @@ -38,15 +38,17 @@ function ControlsSettingsTable.saveToLpdb(lpdbConfig, args) }) end ----@param lpdbConfig string[] +---@param columnConfig {keys: string[], title: string} ---@param args {[string]: string?} ---@return {[string]: string?} -function ControlsSettingsTable.generateLpdbExtradata(lpdbConfig, args) - local result = {} - for _, key in ipairs(lpdbConfig) do - result[key:lower()] = args[key:lower()] +function ControlsSettingsTable.generateLpdbExtradata(columnConfig, args) + local lpdbData = {} + for _, item in ipairs(columnConfig) do + for _, key in ipairs(item.keys) do + lpdbData[key:lower()] = args[key:lower()] + end end - return result + return lpdbData end return ControlsSettingsTable diff --git a/lua/wikis/commons/ControlsSettingsTable/Custom.lua b/lua/wikis/commons/ControlsSettingsTable/Custom.lua deleted file mode 100644 index 9d5f9aa4812..00000000000 --- a/lua/wikis/commons/ControlsSettingsTable/Custom.lua +++ /dev/null @@ -1,49 +0,0 @@ ---- --- @Liquipedia --- page=Module:ControlsSettingsTable/Custom --- --- Please see https://github.com/Liquipedia/Lua-Modules to contribute --- - -local Lua = require('Module:Lua') - -local Arguments = Lua.import('Module:Arguments') -local Class = Lua.import('Module:Class') - -local ControlsSettingsTable = Lua.import('Module:ControlsSettingsTable') - -local CustomControlsSettingsTable = Class.new(ControlsSettingsTable) - ----@type string[] -local LPDB_CONFIG = {} ---local LPDB_CONFIG = {'Accelerate', 'Brake', 'Steering'} - ----@type ColumnConfig[] -local BASE_COLUMN_CONFIG = {} ---[[ -local BASE_COLUMN_CONFIG = { - {key = 'Steering', title = 'Steering'}, - {keys = {{key = 'Accelerate'}, ' / ', {key = 'Brake'}}, title = 'Accelerate/Brake'} -} ---]] - ----@param args {[string]: string?} ----@return ColumnConfig[] -local function makeColumnConfig(args) - local COLUMN_CONFIG = {} - for _, col in ipairs(BASE_COLUMN_CONFIG) do - table.insert(COLUMN_CONFIG, col) - end - - return COLUMN_CONFIG -end - ----@param frame table ----@return Widget? -function CustomControlsSettingsTable.create(frame) - local args = Arguments.getArgs(frame) - local COLUMN_CONFIG = makeColumnConfig(args) - return ControlsSettingsTable.create(LPDB_CONFIG, COLUMN_CONFIG, frame) -end - -return CustomControlsSettingsTable diff --git a/lua/wikis/commons/Links/ButtonTranslation.lua b/lua/wikis/commons/Links/ButtonTranslation.lua new file mode 100644 index 00000000000..a99939dc8bd --- /dev/null +++ b/lua/wikis/commons/Links/ButtonTranslation.lua @@ -0,0 +1,59 @@ +--- +-- @Liquipedia +-- page=Module:Links/ButtonTranslation +-- +-- Please see https://github.com/Liquipedia/Lua-Modules to contribute +-- + +return { + playstation = { + cross = 'PlayStation_button_X.svg', + triangle = 'PlayStation_button_T.svg', + circle = 'PlayStation_button_C.svg', + square = 'PlayStation_button_S.svg', + l1 = 'PlayStation_button_L1.svg', + l2 = 'PlayStation_button_L2.svg', + l3 = 'PlayStation_button_L3.svg', + r1 = 'PlayStation_button_R1.svg', + r2 = 'PlayStation_button_R2.svg', + r3 = 'PlayStation_button_R3.svg', + left_stick = 'PlayStation_button_analog_L.svg', + right_stick = 'PlayStation_button_analog_R.svg', + arrow_up = 'Gamepad_button_arrow_up.svg', + arrow_down = 'Gamepad_button_arrow_down.svg', + arrow_left = 'Gamepad_button_arrow_left.svg', + arrow_right = 'Gamepad_button_arrow_right.svg' + }, + xbox = { + a = 'Xbox_button_A.svg', + y = 'Xbox_button_Y.svg', + b = 'Xbox_button_B.svg', + x = 'Xbox_button_X.svg', + lb = 'Xbox_Left_Bumper.svg', + lt = 'Xbox_Left_Trigger.svg', + rb = 'Xbox_Right_Bumper.svg', + rt = 'Xbox_Right_Trigger.svg', + left_stick = 'Xbox_Left_stick.svg', + right_stick = 'Xbox_Right_stick.svg', + arrow_up = 'Gamepad_button_arrow_up.svg', + arrow_down = 'Gamepad_button_arrow_down.svg', + arrow_left = 'Gamepad_button_arrow_left.svg', + arrow_right = 'Gamepad_button_arrow_right.svg' + }, + switch = { + a = 'Switch_pro_button_A.svg', + y = 'Switch_pro_button_Y.svg', + b = 'Switch_pro_button_B.svg', + x = 'Switch_pro_button_X.svg', + l = 'Switch_pro_button_L.svg', + zl = 'Switch_pro_button_ZL.svg', + r = 'Switch_pro_button_R.svg', + zr = 'Switch_pro_button_ZR.svg', + left_stick = 'PlayStation_button_analog_L.svg', + right_stick = 'PlayStation_button_analog_R.svg', + arrow_up = 'Gamepad_button_arrow_up.svg', + arrow_down = 'Gamepad_button_arrow_down.svg', + arrow_left = 'Gamepad_button_arrow_left.svg', + arrow_right = 'Gamepad_button_arrow_right.svg' + }, +} \ No newline at end of file diff --git a/lua/wikis/commons/Widget/ControlsSettingsTable.lua b/lua/wikis/commons/Widget/ControlsSettingsTable.lua index cb0bf45bcdd..cbe31ab1c56 100644 --- a/lua/wikis/commons/Widget/ControlsSettingsTable.lua +++ b/lua/wikis/commons/Widget/ControlsSettingsTable.lua @@ -8,8 +8,9 @@ local Lua = require('Module:Lua') local Array = Lua.import('Module:Array') +local ButtonTranslation = Lua.import('Module:Links/ButtonTranslation') local Class = Lua.import('Module:Class') -local Page = Lua.import('Module:Page') +local Date = Lua.import('Module:Date/Ext') local String = Lua.import('Module:StringUtils') local Template = Lua.import('Module:Template') @@ -17,16 +18,9 @@ local Widget = Lua.import('Module:Widget') local HtmlWidgets = Lua.import('Module:Widget/Html/All') local WidgetUtil = Lua.import('Module:Widget/Util') -local SETTINGS_LINK = 'Control settings' - ----@alias ColumnConfig ----| {key: string, title: string} ----| {keys: ({key: string} | string)[], title: string} ----@alias ColumnValue {title: string, value: fun(data: {[string]: string?}): string?} - ---@class ControlsSettingsTableWidget: Widget +---@field columnConfig {keys: string[], title: string} ---@field args {[string]: string?} ----@field columnConfig ColumnConfig[] ---@field frame table local ControlsSettingsTableWidget = Class.new(Widget, function(self, columnConfig, args, frame) @@ -36,139 +30,146 @@ local ControlsSettingsTableWidget = Class.new(Widget, end ) ----@return Widget? +---@return Widget function ControlsSettingsTableWidget:render() - local header = self:renderHeader() - local footer = self:renderFooter() - local visibleColumns = self:getVisibleColumns() + return HtmlWidgets.Div{children = {self:renderTable()}} +end - return HtmlWidgets.Div{ - classes = {'table-responsive'}, - children = {self:renderTable(header, footer, visibleColumns)} +---@return Widget +function ControlsSettingsTableWidget:renderTable() + local columns = self:getColumns() + local columnsNumber = #columns + return HtmlWidgets.Table{ + classes = {'wikitable', 'controls-responsive-table'}, + children = WidgetUtil.collect( + self:renderHeader(columnsNumber), + self:renderColumnHeaders(columns), + self:renderDataRow(columns), + self:renderFooter(columnsNumber) + ) } end +---@return {title: string, value: string} +function ControlsSettingsTableWidget:getColumns() + return Array.map(self.columnConfig, function(column) + local buttons = Array.map(column.keys, function(key) + return self:formatToImage(self.args, key) or '-' + end) + local argsEmpty = Array.all(buttons, function(value) + return value == '-' + end) + if argsEmpty then + return nil + end + return { + title = column.title, + value = table.concat(buttons, ' / ') + } + end) +end + +---@param args {[string]: string?} +---@param key string +---@return string? +function ControlsSettingsTableWidget:formatToImage(args, key) + local buttonText = '[[File: ${image} | ${button} | link=]]' + local button = args[key:lower()] + if String.isEmpty(button) then + return nil + end + if args.controller and args.controller:lower() == 'kbm' then + return '' .. button .. '' + end + return String.interpolate(buttonText, {image = self:getImageName(args.controller, button), button = key}) +end + +---@param device string? +---@param key string? ---@return string -function ControlsSettingsTableWidget:renderHeader() - local args = self.args - local frame = self.frame - local header = Page.exists(SETTINGS_LINK) and '[['.. SETTINGS_LINK ..']] ' or SETTINGS_LINK..' ' - if args.ref == 'insidesource' then - header = header .. frame:callParserFunction{ - name = '#tag', - args = { 'ref', Template.safeExpand(frame, 'inside source') } - } - elseif args.ref then - header = header .. frame:callParserFunction{ - name = '#tag', - args = { 'ref', args['ref'] } +function ControlsSettingsTableWidget:getImageName(device, key) + device = (device or ''):lower() + key = (key or ''):lower():gsub(' ', '_') + return ButtonTranslation[device][key] or 'ImageNotFound' +end + +---@param columnsNumber integer +---@return Widget +function ControlsSettingsTableWidget:renderHeader(columnsNumber) + return HtmlWidgets.Tr{children = { + HtmlWidgets.Th{ + attributes = {colspan = columnsNumber}, + children = { + self:makeHeaderText(), + ' ', + HtmlWidgets.Small{children = '([[List of player control settings|list of]])'} + } } - end - return header .. " ([[List of player control settings|list of]])'''" + }} end ---@return string -function ControlsSettingsTableWidget:renderFooter() +function ControlsSettingsTableWidget:makeHeaderText() + local headerText = 'Control settings ${ref}' local args = self.args - if args.date then - local year, month, day = (args.date):match('(%d+)-(%d+)-(%d+)') - local dayAgo = math.floor((os.time() - os.time{year=year, month=month, day=day}) / 86400) - return 'Last updated on '.. args.date ..' (' .. dayAgo ..' days ago).' + local frame = self.frame + local reference = '' + if args.ref == 'insidesource' then + reference = frame:extensionTag('ref', Template.safeExpand(frame, 'inside source')) + elseif args.ref then + reference = frame:extensionTag('ref', args['ref']) end - return 'No date of last update specified!' + return String.interpolate(headerText, {ref = reference}) end ----@return ColumnValue[] -function ControlsSettingsTableWidget:getVisibleColumns() - return Array.flatMap(self.columnConfig, function(config) - local column = self:makeColumn(config) - return String.isNotEmpty(column.value(self.args)) and { column } or {} - end) +---@param columns {title: string, value: string} +---@return Widget +function ControlsSettingsTableWidget:renderColumnHeaders(columns) + return HtmlWidgets.Tr{children = Array.map(columns, function(column) + return HtmlWidgets.Th{children = column.title} + end)} end ----@param config ColumnConfig ----@return ColumnValue -function ControlsSettingsTableWidget:makeColumn(config) - return { - title = config.title, - value = function(data) - if config.keys then - local values = {} - local hasValue = false - for _, item in ipairs(config.keys) do - if type(item) == 'table' then - local formatted = self:formatKeyValue(item.key, data) - table.insert(values, formatted or '-') - if formatted then hasValue = true end - else - table.insert(values, item) - end - end - return hasValue and table.concat(values) or nil - elseif config.key then - return self:formatKeyValue(config.key, data) - end - end - } +---@param columns {title: string, value: string} +---@return Widget +function ControlsSettingsTableWidget:renderDataRow(columns) + return HtmlWidgets.Tr{children = Array.map(columns, function(column) + return HtmlWidgets.Td{ + attributes = {['data-label'] = column.title}, + children = column.value + } + end)} end ----@param key string ----@param data {[string]: string?} ----@return string? -function ControlsSettingsTableWidget:formatKeyValue(key, data) - local keyValue = data[key:lower()] - if not keyValue or String.isEmpty(keyValue) then - return nil - end - if data.controller and data.controller:lower() == 'kbm' then - return '' .. keyValue .. '' - end - return '[[File:' .. self:getImageName(data.controller, keyValue) .. '.svg|' .. key .. '|link=]]' +---@param columnsNumber integer +---@return Widget +function ControlsSettingsTableWidget:renderFooter(columnsNumber) + local footerText = self:makeFooterText() + return HtmlWidgets.Tr{children = { + HtmlWidgets.Th{ + attributes = {colspan = columnsNumber}, + css = {['font-size'] = '85%'}, + children = String.isNotEmpty(footerText) + and {HtmlWidgets.I{children = footerText}} + or {HtmlWidgets.Span{ + classes = {'cinnabar-text'}, + children = {HtmlWidgets.I{children = 'No date of last update specified!'}} + }} + } + }} end ----@param device string? ----@param key string? ---@return string? -function ControlsSettingsTableWidget:getImageName(device, key) - return Template.safeExpand(self.frame, 'Button translation', {(device or ''):lower(), (key or ''):lower()}) -end - ----@param header string ----@param footer string ----@param visibleColumns ColumnValue[] ----@return Widget -function ControlsSettingsTableWidget:renderTable(header, footer, visibleColumns) - return HtmlWidgets.Table{ - classes = {'wikitable', 'controls-responsive-table'}, - css = {['table-layout'] = 'auto'}, - children = WidgetUtil.collect( - HtmlWidgets.Tr{children = { - HtmlWidgets.Th{ - attributes = {colspan = #self.columnConfig}, - children = header - } - }}, - HtmlWidgets.Tr{children = Array.map(visibleColumns, function(column) - return HtmlWidgets.Th{children = column.title} - end)}, - HtmlWidgets.Tr{children = Array.map(visibleColumns, function(column) - return HtmlWidgets.Td{ - attributes = {['data-label'] = column.title}, - children = column.value(self.args) - } - end)}, - HtmlWidgets.Tr{children = { - HtmlWidgets.Th{ - attributes = {colspan = #self.columnConfig}, - css = { - ['font-size'] = '85%', - padding = '2px', - }, - children = footer - } - }} - ) - } +function ControlsSettingsTableWidget:makeFooterText() + local footerText = 'Last updated on ${date} (${daysAgo} days ago).' + local args = self.args + if args.date then + local currentTimestamp = Date.getCurrentTimestamp() + local targetTimestamp = Date.readTimestamp(args.date) + local daysAgo = math.floor((currentTimestamp - targetTimestamp) / 86400) + return String.interpolate(footerText, {date = args.date, daysAgo = daysAgo}) + end + return nil end return ControlsSettingsTableWidget From cfc0485b45e9cfca505684946becba49179b1c2a Mon Sep 17 00:00:00 2001 From: Soba Date: Tue, 24 Mar 2026 18:55:07 +0300 Subject: [PATCH 3/5] Table2 version --- lua/wikis/commons/ControlsSettingsTable.lua | 25 +- lua/wikis/commons/Links/ButtonTranslation.lua | 2 +- .../commons/Widget/ControlsSettingsTable.lua | 229 ++++++++++-------- stylesheets/commons/ResponsiveTable.scss | 41 +--- 4 files changed, 141 insertions(+), 156 deletions(-) diff --git a/lua/wikis/commons/ControlsSettingsTable.lua b/lua/wikis/commons/ControlsSettingsTable.lua index f36d88ea11f..70fb18e7be4 100644 --- a/lua/wikis/commons/ControlsSettingsTable.lua +++ b/lua/wikis/commons/ControlsSettingsTable.lua @@ -7,6 +7,7 @@ local Lua = require('Module:Lua') local Arguments = Lua.import('Module:Arguments') +local Array = Lua.import('Module:Array') local Class = Lua.import('Module:Class') local Info = Lua.import('Module:Info') @@ -18,17 +19,17 @@ local ControlsSettingsTable = Class.new() ---@return Widget function ControlsSettingsTable.create(frame) local args = Arguments.getArgs(frame) - local columnConfig = Info.controlsSettingsTable - local widget = ControlsSettingsTableWidget(columnConfig, args) - ControlsSettingsTable.saveToLpdb(columnConfig, args) + local config = Info.controlsSettingsTable + local widget = ControlsSettingsTableWidget(config, args) + ControlsSettingsTable.saveToLpdb(config, args) return widget:render() end ----@param columnConfig {keys: string[], title: string} +---@param config {keys: string[], title: string} ---@param args {[string]: string?} -function ControlsSettingsTable.saveToLpdb(columnConfig, args) +function ControlsSettingsTable.saveToLpdb(config, args) local title = mw.title.getCurrentTitle().text - local extradata = ControlsSettingsTable.generateLpdbExtradata(columnConfig, args) + local extradata = ControlsSettingsTable.generateLpdbExtradata(config, args) mw.ext.LiquipediaDB.lpdb_settings(title, { name = 'movement', reference = args.ref, @@ -38,16 +39,16 @@ function ControlsSettingsTable.saveToLpdb(columnConfig, args) }) end ----@param columnConfig {keys: string[], title: string} +---@param config {keys: string[], title: string} ---@param args {[string]: string?} ---@return {[string]: string?} -function ControlsSettingsTable.generateLpdbExtradata(columnConfig, args) +function ControlsSettingsTable.generateLpdbExtradata(config, args) local lpdbData = {} - for _, item in ipairs(columnConfig) do - for _, key in ipairs(item.keys) do + Array.forEach(config, function(item) + Array.forEach(item.keys, function(key) lpdbData[key:lower()] = args[key:lower()] - end - end + end) + end) return lpdbData end diff --git a/lua/wikis/commons/Links/ButtonTranslation.lua b/lua/wikis/commons/Links/ButtonTranslation.lua index a99939dc8bd..b3c845d5fa5 100644 --- a/lua/wikis/commons/Links/ButtonTranslation.lua +++ b/lua/wikis/commons/Links/ButtonTranslation.lua @@ -56,4 +56,4 @@ return { arrow_left = 'Gamepad_button_arrow_left.svg', arrow_right = 'Gamepad_button_arrow_right.svg' }, -} \ No newline at end of file +} diff --git a/lua/wikis/commons/Widget/ControlsSettingsTable.lua b/lua/wikis/commons/Widget/ControlsSettingsTable.lua index cbe31ab1c56..b4e32fca802 100644 --- a/lua/wikis/commons/Widget/ControlsSettingsTable.lua +++ b/lua/wikis/commons/Widget/ControlsSettingsTable.lua @@ -11,165 +11,184 @@ local Array = Lua.import('Module:Array') local ButtonTranslation = Lua.import('Module:Links/ButtonTranslation') local Class = Lua.import('Module:Class') local Date = Lua.import('Module:Date/Ext') +local Logic = Lua.import('Module:Logic') local String = Lua.import('Module:StringUtils') -local Template = Lua.import('Module:Template') -local Widget = Lua.import('Module:Widget') local HtmlWidgets = Lua.import('Module:Widget/Html/All') -local WidgetUtil = Lua.import('Module:Widget/Util') +local Dialog = Lua.import('Module:Widget/Basic/Dialog') +local IconFa = Lua.import('Module:Widget/Image/Icon/Fontawesome') +local Image = Lua.import('Module:Widget/Image/Icon/Image') +local TableWidgets = Lua.import('Module:Widget/Table2/All') +local Widget = Lua.import('Module:Widget') + +-- table2 aliases +local Row = TableWidgets.Row +local Cell = TableWidgets.Cell +local CellHeader = TableWidgets.CellHeader +local Table2 = TableWidgets.Table +local TableBody = TableWidgets.TableBody ---@class ControlsSettingsTableWidget: Widget ----@field columnConfig {keys: string[], title: string} +---@field config {keys: string[], title: string} ---@field args {[string]: string?} ----@field frame table local ControlsSettingsTableWidget = Class.new(Widget, - function(self, columnConfig, args, frame) - self.columnConfig = columnConfig + function(self, config, args) + self.config = config self.args = args - self.frame = frame or mw.getCurrentFrame() end ) ---@return Widget function ControlsSettingsTableWidget:render() - return HtmlWidgets.Div{children = {self:renderTable()}} -end - ----@return Widget -function ControlsSettingsTableWidget:renderTable() - local columns = self:getColumns() - local columnsNumber = #columns - return HtmlWidgets.Table{ - classes = {'wikitable', 'controls-responsive-table'}, - children = WidgetUtil.collect( - self:renderHeader(columnsNumber), - self:renderColumnHeaders(columns), - self:renderDataRow(columns), - self:renderFooter(columnsNumber) - ) + local rows = self:getRows() + return Table2{ + title = self:makeHeaderDisplay(), + children = TableBody{children = rows}, + footer = self:makeWarningDisplay(), } end ----@return {title: string, value: string} -function ControlsSettingsTableWidget:getColumns() - return Array.map(self.columnConfig, function(column) - local buttons = Array.map(column.keys, function(key) - return self:formatToImage(self.args, key) or '-' +---@return Widget[] +function ControlsSettingsTableWidget:getRows() + local nonEmptyRows = Array.filter(self.config, function(configRow) + return Array.any(configRow.keys, function(key) + return String.isNotEmpty(self.args[key:lower()]) end) - local argsEmpty = Array.all(buttons, function(value) - return value == '-' + end) + return Array.map(nonEmptyRows, function(configRow) + local buttons = Array.map(configRow.keys, function(key) + return self:makeButtonIcon(self.args, key) or self:makeButtonStubIcon() end) - if argsEmpty then - return nil - end - return { - title = column.title, - value = table.concat(buttons, ' / ') - } + return ControlsSettingsTableWidget:makeRow(configRow.title, buttons) end) end ---@param args {[string]: string?} ---@param key string ----@return string? -function ControlsSettingsTableWidget:formatToImage(args, key) - local buttonText = '[[File: ${image} | ${button} | link=]]' +---@return Widget? +function ControlsSettingsTableWidget:makeButtonIcon(args, key) local button = args[key:lower()] if String.isEmpty(button) then return nil end + ---@cast button string if args.controller and args.controller:lower() == 'kbm' then - return '' .. button .. '' + return HtmlWidgets.Kbd{children = button} end - return String.interpolate(buttonText, {image = self:getImageName(args.controller, button), button = key}) + local imageName = self:getImageName(args.controller, button) + return self:makeImageWidget(imageName, button) end ---@param device string? ----@param key string? +---@param button string? ---@return string -function ControlsSettingsTableWidget:getImageName(device, key) - device = (device or ''):lower() - key = (key or ''):lower():gsub(' ', '_') - return ButtonTranslation[device][key] or 'ImageNotFound' +function ControlsSettingsTableWidget:getImageName(device, button) + device = Logic.nilOr(device, ''):lower() + button = Logic.nilOr(button, ''):lower():gsub(' ', '_') + return ButtonTranslation[device][button] or 'ImageNotFound' end ----@param columnsNumber integer +---@param imageName string +---@param button string ---@return Widget -function ControlsSettingsTableWidget:renderHeader(columnsNumber) - return HtmlWidgets.Tr{children = { - HtmlWidgets.Th{ - attributes = {colspan = columnsNumber}, - children = { - self:makeHeaderText(), - ' ', - HtmlWidgets.Small{children = '([[List of player control settings|list of]])'} - } +function ControlsSettingsTableWidget:makeImageWidget(imageName, button) + return Image{ + imageLight = imageName, + size = 'md', + caption = button, + alt = button, } - }} end ----@return string -function ControlsSettingsTableWidget:makeHeaderText() - local headerText = 'Control settings ${ref}' - local args = self.args - local frame = self.frame - local reference = '' - if args.ref == 'insidesource' then - reference = frame:extensionTag('ref', Template.safeExpand(frame, 'inside source')) - elseif args.ref then - reference = frame:extensionTag('ref', args['ref']) - end - return String.interpolate(headerText, {ref = reference}) +---@return Widget +function ControlsSettingsTableWidget:makeButtonStubIcon() + return IconFa{iconName = 'no', size = 'sm'} end ----@param columns {title: string, value: string} +---@private +---@param title string +---@param value Widget ---@return Widget -function ControlsSettingsTableWidget:renderColumnHeaders(columns) - return HtmlWidgets.Tr{children = Array.map(columns, function(column) - return HtmlWidgets.Th{children = column.title} - end)} +function ControlsSettingsTableWidget:makeRow(title, value) + return Row{ + children = { + CellHeader{children = title, align = 'right'}, + Cell{ + children = HtmlWidgets.Div{ + children = value, + css = {display = 'flex', gap = '6px', ['align-items'] = 'center'} + }, + align = 'left' + } + } + } end ----@param columns {title: string, value: string} ---@return Widget -function ControlsSettingsTableWidget:renderDataRow(columns) - return HtmlWidgets.Tr{children = Array.map(columns, function(column) - return HtmlWidgets.Td{ - attributes = {['data-label'] = column.title}, - children = column.value +function ControlsSettingsTableWidget:makeHeaderDisplay() + return HtmlWidgets.Div{ + css = {['text-align'] = 'center'}, + children = { + 'Control settings', + HtmlWidgets.Span{ + children = self:makeReferenceDisplay(), + css = {['margin-left'] = '10px'} + } } - end)} + } end ----@param columnsNumber integer ----@return Widget -function ControlsSettingsTableWidget:renderFooter(columnsNumber) - local footerText = self:makeFooterText() - return HtmlWidgets.Tr{children = { - HtmlWidgets.Th{ - attributes = {colspan = columnsNumber}, - css = {['font-size'] = '85%'}, - children = String.isNotEmpty(footerText) - and {HtmlWidgets.I{children = footerText}} - or {HtmlWidgets.Span{ - classes = {'cinnabar-text'}, - children = {HtmlWidgets.I{children = 'No date of last update specified!'}} - }} +function ControlsSettingsTableWidget:makeReferenceDisplay() + local timestamp = Date.readTimestamp(self.args.date) + local date = timestamp and Date.formatTimestamp('M j, Y', timestamp) or '?' + return Dialog{ + trigger = IconFa{ + iconName = 'reference', + size = 'sm', + }, + title = 'Reference', + children = HtmlWidgets.Div{ + children = { + self:makeReferenceSource(), + HtmlWidgets.Br{}, + HtmlWidgets.I{ + children = 'Last updated on ' .. date + } + } } - }} + } end ----@return string? -function ControlsSettingsTableWidget:makeFooterText() - local footerText = 'Last updated on ${date} (${daysAgo} days ago).' +---@return string|Widget +function ControlsSettingsTableWidget:makeReferenceSource() local args = self.args - if args.date then - local currentTimestamp = Date.getCurrentTimestamp() - local targetTimestamp = Date.readTimestamp(args.date) - local daysAgo = math.floor((currentTimestamp - targetTimestamp) / 86400) - return String.interpolate(footerText, {date = args.date, daysAgo = daysAgo}) + if args.ref and args.ref:lower():gsub(' ', '') == 'insidesource' then + return HtmlWidgets.Abbr{ + children = 'Inside source', + attributes = {title = 'Liquipedia has gained this information from a trusted inside source'} + } + end + return Logic.nilOr(self.args.ref, '?') +end + +---@return Widget? +function ControlsSettingsTableWidget:makeWarningDisplay() + if Logic.isEmpty(self.args.ref) then + return self:makeWarning('No reference specified!') + elseif Logic.isEmpty(self.args.date) then + return self:makeWarning('No date of last update specified!') end return nil end +---@param text string +---@return Widget +function ControlsSettingsTableWidget:makeWarning(text) + return {HtmlWidgets.Span{ + classes = {'cinnabar-text'}, + children = {HtmlWidgets.I{children = text}}, + css = {['font-size'] = '90%'} + }} +end + return ControlsSettingsTableWidget diff --git a/stylesheets/commons/ResponsiveTable.scss b/stylesheets/commons/ResponsiveTable.scss index a5c51df2a68..402e9e02f9e 100644 --- a/stylesheets/commons/ResponsiveTable.scss +++ b/stylesheets/commons/ResponsiveTable.scss @@ -1,42 +1,7 @@ /******************************************************************************* -Template(s): Responsive Table -Author(s): QuadratClown, SobakaPirat +Template(s): Rocket League Responsive Table +Author(s): QuadratClown *******************************************************************************/ -.controls-responsive-table { - margin: 0; - - td { - text-align: center; - } - - @media screen and ( max-width: 947px ) { - width: 100%; - - tr { - display: block; - } - - tr:nth-child( 2 ) { - display: none; - } - - th, - td { - display: block; - width: 100%; - font-size: 0.8em; - text-align: right; - border-left: 0; - - &::before { - content: attr( data-label ); - float: left; - font-weight: bold; - } - } - } -} - .rl-responsive-table { border-collapse: collapse; margin: 0; @@ -264,4 +229,4 @@ Author(s): QuadratClown, SobakaPirat @media screen and ( max-width: 600px ) { width: 100%; } -} +} \ No newline at end of file From 72a078503ee308ff46a8e3af94cff27c07d1c208 Mon Sep 17 00:00:00 2001 From: Soba Date: Tue, 24 Mar 2026 19:37:00 +0300 Subject: [PATCH 4/5] squash widget --- lua/wikis/commons/ControlsSettingsTable.lua | 204 ++++++++++++++++-- .../commons/Widget/ControlsSettingsTable.lua | 194 ----------------- 2 files changed, 187 insertions(+), 211 deletions(-) delete mode 100644 lua/wikis/commons/Widget/ControlsSettingsTable.lua diff --git a/lua/wikis/commons/ControlsSettingsTable.lua b/lua/wikis/commons/ControlsSettingsTable.lua index 70fb18e7be4..5b8e29c5e31 100644 --- a/lua/wikis/commons/ControlsSettingsTable.lua +++ b/lua/wikis/commons/ControlsSettingsTable.lua @@ -8,48 +8,218 @@ local Lua = require('Module:Lua') local Arguments = Lua.import('Module:Arguments') local Array = Lua.import('Module:Array') +local ButtonTranslation = Lua.import('Module:Links/ButtonTranslation') local Class = Lua.import('Module:Class') +local Date = Lua.import('Module:Date/Ext') local Info = Lua.import('Module:Info') +local Logic = Lua.import('Module:Logic') +local String = Lua.import('Module:StringUtils') -local ControlsSettingsTableWidget = Lua.import('Module:Widget/ControlsSettingsTable') +local HtmlWidgets = Lua.import('Module:Widget/Html/All') +local Dialog = Lua.import('Module:Widget/Basic/Dialog') +local IconFa = Lua.import('Module:Widget/Image/Icon/Fontawesome') +local Image = Lua.import('Module:Widget/Image/Icon/Image') +local TableWidgets = Lua.import('Module:Widget/Table2/All') -local ControlsSettingsTable = Class.new() +-- table2 aliases +local Row = TableWidgets.Row +local Cell = TableWidgets.Cell +local CellHeader = TableWidgets.CellHeader +local Table2 = TableWidgets.Table +local TableBody = TableWidgets.TableBody + +---@class ControlsSettingsTable +---@field config {keys: string[], title: string}[] +---@field args {[string]: string?} +local ControlsSettingsTable = Class.new( + function(self, args, config) + self.args = args + self.config = config + end +) ---@param frame table ---@return Widget function ControlsSettingsTable.create(frame) local args = Arguments.getArgs(frame) local config = Info.controlsSettingsTable - local widget = ControlsSettingsTableWidget(config, args) - ControlsSettingsTable.saveToLpdb(config, args) - return widget:render() + local controlsSettingsTable = ControlsSettingsTable(args, config) + controlsSettingsTable:saveToLpdb() + return controlsSettingsTable:render() end ----@param config {keys: string[], title: string} ----@param args {[string]: string?} -function ControlsSettingsTable.saveToLpdb(config, args) +function ControlsSettingsTable:saveToLpdb() local title = mw.title.getCurrentTitle().text - local extradata = ControlsSettingsTable.generateLpdbExtradata(config, args) + local extradata = self:generateLpdbExtradata() mw.ext.LiquipediaDB.lpdb_settings(title, { name = 'movement', - reference = args.ref, - lastupdated = args.date, + reference = self.args.ref, + lastupdated = self.args.date, gamesettings = mw.ext.LiquipediaDB.lpdb_create_json(extradata), - type = (args.controller or ''):lower(), + type = (self.args.controller or ''):lower(), }) end ----@param config {keys: string[], title: string} ----@param args {[string]: string?} ---@return {[string]: string?} -function ControlsSettingsTable.generateLpdbExtradata(config, args) +function ControlsSettingsTable:generateLpdbExtradata() local lpdbData = {} - Array.forEach(config, function(item) + Array.forEach(self.config, function(item) Array.forEach(item.keys, function(key) - lpdbData[key:lower()] = args[key:lower()] + lpdbData[key:lower()] = self.args[key:lower()] end) end) return lpdbData end +---@return Widget +function ControlsSettingsTable:render() + return Table2{ + children = TableBody{children = self:makeRows()}, + title = self:makeHeaderDisplay(), + footer = self:makeWarningDisplay(), + } +end + +---@return Widget[] +function ControlsSettingsTable:makeRows() + local nonEmptyRows = Array.filter(self.config, function(configRow) + return Array.any(configRow.keys, function(key) + return String.isNotEmpty(self.args[key:lower()]) + end) + end) + return Array.map(nonEmptyRows, function(configRow) + local buttons = Array.map(configRow.keys, function(key) + return self:makeButtonIcon(key) or self:makeButtonStubIcon() + end) + return ControlsSettingsTable:makeRow(configRow.title, buttons) + end) +end + +---@param key string +---@return Widget? +function ControlsSettingsTable:makeButtonIcon(key) + local button = self.args[key:lower()] + if String.isEmpty(button) then + return nil + end + ---@cast button string + if self.args.controller and self.args.controller:lower() == 'kbm' then + return HtmlWidgets.Kbd{children = button} + end + local imageName = self:getImageName(self.args.controller, button) + return self:makeButtonDisplay(imageName, button) +end + +---@param device string? +---@param button string? +---@return string +function ControlsSettingsTable:getImageName(device, button) + device = Logic.nilOr(device, ''):lower() + button = Logic.nilOr(button, ''):lower():gsub(' ', '_') + return ButtonTranslation[device][button] or 'ImageNotFound' +end + +---@param imageName string +---@param button string +---@return Widget +function ControlsSettingsTable:makeButtonDisplay(imageName, button) + return Image{ + imageLight = imageName, + size = 'md', + caption = button, + alt = button, + } +end + +---@return Widget +function ControlsSettingsTable:makeButtonStubIcon() + return IconFa{iconName = 'no', size = 'sm'} +end + +---@param title string +---@param value Widget +---@return Widget +function ControlsSettingsTable:makeRow(title, value) + return Row{ + children = { + CellHeader{children = title, align = 'right'}, + Cell{ + children = HtmlWidgets.Div{ + children = value, + css = {display = 'flex', gap = '6px', ['align-items'] = 'center'} + }, + align = 'left' + } + } + } +end + +---@return Widget +function ControlsSettingsTable:makeHeaderDisplay() + return HtmlWidgets.Div{ + css = {['text-align'] = 'center'}, + children = { + 'Control settings', + HtmlWidgets.Span{ + children = self:makeReferenceDisplay(), + css = {['margin-left'] = '10px'} + } + } + } +end + +---@return Widget +function ControlsSettingsTable:makeReferenceDisplay() + local timestamp = Date.readTimestamp(self.args.date) + local date = timestamp and Date.formatTimestamp('M j, Y', timestamp) or '?' + return Dialog{ + trigger = IconFa{ + iconName = 'reference', + size = 'sm', + }, + title = 'Reference', + children = HtmlWidgets.Div{ + children = { + self:makeReferenceSource(), + HtmlWidgets.Br{}, + HtmlWidgets.I{ + children = 'Last updated on ' .. date + } + } + } + } +end + +---@return string|Widget +function ControlsSettingsTable:makeReferenceSource() + local args = self.args + if args.ref and args.ref:lower():gsub(' ', '') == 'insidesource' then + return HtmlWidgets.Abbr{ + children = 'Inside source', + attributes = {title = 'Liquipedia has gained this information from a trusted inside source'} + } + end + return Logic.nilOr(self.args.ref, '?') +end + +---@return Widget? +function ControlsSettingsTable:makeWarningDisplay() + if Logic.isEmpty(self.args.ref) then + return self:makeWarning('No reference specified!') + elseif Logic.isEmpty(self.args.date) then + return self:makeWarning('No date of last update specified!') + end + return nil +end + +---@param text string +---@return Widget +function ControlsSettingsTable:makeWarning(text) + return {HtmlWidgets.Span{ + classes = {'cinnabar-text'}, + children = {HtmlWidgets.I{children = text}}, + css = {['font-size'] = '90%'} + }} +end + return ControlsSettingsTable diff --git a/lua/wikis/commons/Widget/ControlsSettingsTable.lua b/lua/wikis/commons/Widget/ControlsSettingsTable.lua deleted file mode 100644 index b4e32fca802..00000000000 --- a/lua/wikis/commons/Widget/ControlsSettingsTable.lua +++ /dev/null @@ -1,194 +0,0 @@ ---- --- @Liquipedia --- page=Module:Widget/ControlsSettingsTable --- --- Please see https://github.com/Liquipedia/Lua-Modules to contribute --- - -local Lua = require('Module:Lua') - -local Array = Lua.import('Module:Array') -local ButtonTranslation = Lua.import('Module:Links/ButtonTranslation') -local Class = Lua.import('Module:Class') -local Date = Lua.import('Module:Date/Ext') -local Logic = Lua.import('Module:Logic') -local String = Lua.import('Module:StringUtils') - -local HtmlWidgets = Lua.import('Module:Widget/Html/All') -local Dialog = Lua.import('Module:Widget/Basic/Dialog') -local IconFa = Lua.import('Module:Widget/Image/Icon/Fontawesome') -local Image = Lua.import('Module:Widget/Image/Icon/Image') -local TableWidgets = Lua.import('Module:Widget/Table2/All') -local Widget = Lua.import('Module:Widget') - --- table2 aliases -local Row = TableWidgets.Row -local Cell = TableWidgets.Cell -local CellHeader = TableWidgets.CellHeader -local Table2 = TableWidgets.Table -local TableBody = TableWidgets.TableBody - ----@class ControlsSettingsTableWidget: Widget ----@field config {keys: string[], title: string} ----@field args {[string]: string?} -local ControlsSettingsTableWidget = Class.new(Widget, - function(self, config, args) - self.config = config - self.args = args - end -) - ----@return Widget -function ControlsSettingsTableWidget:render() - local rows = self:getRows() - return Table2{ - title = self:makeHeaderDisplay(), - children = TableBody{children = rows}, - footer = self:makeWarningDisplay(), - } -end - ----@return Widget[] -function ControlsSettingsTableWidget:getRows() - local nonEmptyRows = Array.filter(self.config, function(configRow) - return Array.any(configRow.keys, function(key) - return String.isNotEmpty(self.args[key:lower()]) - end) - end) - return Array.map(nonEmptyRows, function(configRow) - local buttons = Array.map(configRow.keys, function(key) - return self:makeButtonIcon(self.args, key) or self:makeButtonStubIcon() - end) - return ControlsSettingsTableWidget:makeRow(configRow.title, buttons) - end) -end - ----@param args {[string]: string?} ----@param key string ----@return Widget? -function ControlsSettingsTableWidget:makeButtonIcon(args, key) - local button = args[key:lower()] - if String.isEmpty(button) then - return nil - end - ---@cast button string - if args.controller and args.controller:lower() == 'kbm' then - return HtmlWidgets.Kbd{children = button} - end - local imageName = self:getImageName(args.controller, button) - return self:makeImageWidget(imageName, button) -end - ----@param device string? ----@param button string? ----@return string -function ControlsSettingsTableWidget:getImageName(device, button) - device = Logic.nilOr(device, ''):lower() - button = Logic.nilOr(button, ''):lower():gsub(' ', '_') - return ButtonTranslation[device][button] or 'ImageNotFound' -end - ----@param imageName string ----@param button string ----@return Widget -function ControlsSettingsTableWidget:makeImageWidget(imageName, button) - return Image{ - imageLight = imageName, - size = 'md', - caption = button, - alt = button, - } -end - ----@return Widget -function ControlsSettingsTableWidget:makeButtonStubIcon() - return IconFa{iconName = 'no', size = 'sm'} -end - ----@private ----@param title string ----@param value Widget ----@return Widget -function ControlsSettingsTableWidget:makeRow(title, value) - return Row{ - children = { - CellHeader{children = title, align = 'right'}, - Cell{ - children = HtmlWidgets.Div{ - children = value, - css = {display = 'flex', gap = '6px', ['align-items'] = 'center'} - }, - align = 'left' - } - } - } -end - ----@return Widget -function ControlsSettingsTableWidget:makeHeaderDisplay() - return HtmlWidgets.Div{ - css = {['text-align'] = 'center'}, - children = { - 'Control settings', - HtmlWidgets.Span{ - children = self:makeReferenceDisplay(), - css = {['margin-left'] = '10px'} - } - } - } -end - -function ControlsSettingsTableWidget:makeReferenceDisplay() - local timestamp = Date.readTimestamp(self.args.date) - local date = timestamp and Date.formatTimestamp('M j, Y', timestamp) or '?' - return Dialog{ - trigger = IconFa{ - iconName = 'reference', - size = 'sm', - }, - title = 'Reference', - children = HtmlWidgets.Div{ - children = { - self:makeReferenceSource(), - HtmlWidgets.Br{}, - HtmlWidgets.I{ - children = 'Last updated on ' .. date - } - } - } - } -end - ----@return string|Widget -function ControlsSettingsTableWidget:makeReferenceSource() - local args = self.args - if args.ref and args.ref:lower():gsub(' ', '') == 'insidesource' then - return HtmlWidgets.Abbr{ - children = 'Inside source', - attributes = {title = 'Liquipedia has gained this information from a trusted inside source'} - } - end - return Logic.nilOr(self.args.ref, '?') -end - ----@return Widget? -function ControlsSettingsTableWidget:makeWarningDisplay() - if Logic.isEmpty(self.args.ref) then - return self:makeWarning('No reference specified!') - elseif Logic.isEmpty(self.args.date) then - return self:makeWarning('No date of last update specified!') - end - return nil -end - ----@param text string ----@return Widget -function ControlsSettingsTableWidget:makeWarning(text) - return {HtmlWidgets.Span{ - classes = {'cinnabar-text'}, - children = {HtmlWidgets.I{children = text}}, - css = {['font-size'] = '90%'} - }} -end - -return ControlsSettingsTableWidget From 4b5ed354face1e54b939b808d1ca7a6f2ff22c30 Mon Sep 17 00:00:00 2001 From: Soba Date: Tue, 24 Mar 2026 19:44:47 +0300 Subject: [PATCH 5/5] missing eof --- stylesheets/commons/ResponsiveTable.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stylesheets/commons/ResponsiveTable.scss b/stylesheets/commons/ResponsiveTable.scss index 402e9e02f9e..4799ebd60ca 100644 --- a/stylesheets/commons/ResponsiveTable.scss +++ b/stylesheets/commons/ResponsiveTable.scss @@ -229,4 +229,4 @@ Author(s): QuadratClown @media screen and ( max-width: 600px ) { width: 100%; } -} \ No newline at end of file +}