From e443579d0a3720e90a65f193b76e3dd849fe1fdc Mon Sep 17 00:00:00 2001 From: Rikard Blixt Date: Mon, 17 Aug 2026 13:28:50 +0000 Subject: [PATCH 1/7] feat(match2): make sets available by default --- .../clashroyale/MatchGroup/Input/Custom.lua | 1 - .../commons/MatchGroup/Input/Starcraft.lua | 1 - lua/wikis/commons/MatchGroup/Input/Util.lua | 10 +++---- lua/wikis/commons/MatchSummary/Base.lua | 26 +++++++++++++++---- .../hearthstone/MatchGroup/Input/Custom.lua | 4 +-- .../stormgate/MatchGroup/Input/Custom.lua | 1 - .../warcraft/MatchGroup/Input/Custom.lua | 1 - 7 files changed, 25 insertions(+), 19 deletions(-) diff --git a/lua/wikis/clashroyale/MatchGroup/Input/Custom.lua b/lua/wikis/clashroyale/MatchGroup/Input/Custom.lua index 81579d99cb0..fc12650126f 100644 --- a/lua/wikis/clashroyale/MatchGroup/Input/Custom.lua +++ b/lua/wikis/clashroyale/MatchGroup/Input/Custom.lua @@ -22,7 +22,6 @@ local Opponent = Lua.import('Module:Opponent/Custom') local CustomMatchGroupInput = {} local MatchFunctions = {} local MapFunctions = { - ADD_SUB_GROUP = true, BREAK_ON_EMPTY = true, } diff --git a/lua/wikis/commons/MatchGroup/Input/Starcraft.lua b/lua/wikis/commons/MatchGroup/Input/Starcraft.lua index dbdf37d0979..479b996ecce 100644 --- a/lua/wikis/commons/MatchGroup/Input/Starcraft.lua +++ b/lua/wikis/commons/MatchGroup/Input/Starcraft.lua @@ -40,7 +40,6 @@ local MatchFunctions = { ---@class StarcraftMapParser: MapParserInterface local MapFunctions = { - ADD_SUB_GROUP = true, BREAK_ON_EMPTY = true, } diff --git a/lua/wikis/commons/MatchGroup/Input/Util.lua b/lua/wikis/commons/MatchGroup/Input/Util.lua index c9f35d36b45..fc9a9de31ad 100644 --- a/lua/wikis/commons/MatchGroup/Input/Util.lua +++ b/lua/wikis/commons/MatchGroup/Input/Util.lua @@ -1221,7 +1221,6 @@ end ---@field getMapBestOf? fun(map: table): integer? ---@field computeOpponentScore? fun(props: table, autoScore?: fun(opponentIndex: integer):integer?): integer?, string? ---@field getGame? fun(match: table, map:table): string? ----@field ADD_SUB_GROUP? boolean ---@field BREAK_ON_EMPTY? boolean ---@field INHERIT_MAP_DATES? boolean @@ -1243,7 +1242,6 @@ end --- - getGame(match, map): string? --- --- Additionally, the Parser may have the following properties: ---- - ADD_SUB_GROUP boolean? --- - BREAK_ON_EMPTY boolean? ---@param match table ---@param opponents MGIParsedOpponent[] @@ -1251,7 +1249,7 @@ end ---@return table[] function MatchGroupInputUtil.standardProcessMaps(match, opponents, Parser) local maps = {} - local subGroup = 0 + local nextSubGroup = 1 local lastDate = match.date for key, mapInput, mapIndex in Table.iter.pairsByPrefix(match, 'map', {requireIndex = true}) do @@ -1270,10 +1268,8 @@ function MatchGroupInputUtil.standardProcessMaps(match, opponents, Parser) Table.mergeInto(map, MatchGroupInputUtil.readDate(dateToUse)) - if Parser.ADD_SUB_GROUP then - subGroup = tonumber(map.subgroup) or (subGroup + 1) - map.subgroup = subGroup - end + map.subgroup = tonumber(map.subgroup) or nextSubGroup + nextSubGroup = map.subgroup + 1 if Parser.getMapName then map.map, map.mapDisplayName = Parser.getMapName(map, mapIndex, match) diff --git a/lua/wikis/commons/MatchSummary/Base.lua b/lua/wikis/commons/MatchSummary/Base.lua index 8793768377b..09cd3867a58 100644 --- a/lua/wikis/commons/MatchSummary/Base.lua +++ b/lua/wikis/commons/MatchSummary/Base.lua @@ -71,14 +71,30 @@ function MatchSummary.createDefaultBody(match, CustomMatchSummary, options) local createGames = CustomMatchSummary.createGames local createGame = CustomMatchSummary.createGame + local GameRow = CustomMatchSummary.GameRow local nodes - if CustomMatchSummary.GameRow then - nodes = MatchSummaryWidgets.GamesContainer{ - children = Array.map(match.games, function(game, gameIndex) - return CustomMatchSummary.GameRow{game = game, gameIndex = gameIndex} + if GameRow then + -- TODO: Move to parse from lpdb step + local sets = MatchGroupUtil.groupBySubgroup(match) + + if #sets > 1 and #sets < #match.games then + nodes = Array.map(sets, function(set) + return MatchSummaryWidgets.GamesContainer{ + gamesSectionName = set.header or ('Set ' .. set.subgroup), + gamesSectionResult = 'TODO', -- TODO: Create Widget for it + children = Array.map(set.games, function(game, gameIndex) + return GameRow{game = game, gameIndex = gameIndex} + end) + } end) - } + else + nodes = MatchSummaryWidgets.GamesContainer{ + children = Array.map(match.games, function(game, gameIndex) + return GameRow{game = game, gameIndex = gameIndex} + end) + } + end elseif createGames then nodes = createGames(match) else diff --git a/lua/wikis/hearthstone/MatchGroup/Input/Custom.lua b/lua/wikis/hearthstone/MatchGroup/Input/Custom.lua index 15ad87e6991..0253dd93654 100644 --- a/lua/wikis/hearthstone/MatchGroup/Input/Custom.lua +++ b/lua/wikis/hearthstone/MatchGroup/Input/Custom.lua @@ -30,9 +30,7 @@ local MatchFunctions = { } ---@class HearthstoneMapParser: MapParserInterface -local MapFunctions = { - ADD_SUB_GROUP = true, -} +local MapFunctions = {} ---@class HearthstoneFfaMatchParser: FfaMatchParserInterface local FfaMatchFunctions = { diff --git a/lua/wikis/stormgate/MatchGroup/Input/Custom.lua b/lua/wikis/stormgate/MatchGroup/Input/Custom.lua index e495d480656..0ae393bdaa1 100644 --- a/lua/wikis/stormgate/MatchGroup/Input/Custom.lua +++ b/lua/wikis/stormgate/MatchGroup/Input/Custom.lua @@ -40,7 +40,6 @@ local MatchFunctions = { }, } local MapFunctions = { - ADD_SUB_GROUP = true, BREAK_ON_EMPTY = true, } diff --git a/lua/wikis/warcraft/MatchGroup/Input/Custom.lua b/lua/wikis/warcraft/MatchGroup/Input/Custom.lua index 240bd9a9e31..9d887fe3d41 100644 --- a/lua/wikis/warcraft/MatchGroup/Input/Custom.lua +++ b/lua/wikis/warcraft/MatchGroup/Input/Custom.lua @@ -48,7 +48,6 @@ local MatchFunctions = { }, } local MapFunctions = { - ADD_SUB_GROUP = true, BREAK_ON_EMPTY = true, } local FfaMatchFunctions = { From 9950803649f4e3a6e65704d78b51029864eee686 Mon Sep 17 00:00:00 2001 From: Rikard Blixt Date: Mon, 17 Aug 2026 14:34:19 +0000 Subject: [PATCH 2/7] calculate in matchFromRecord --- lua/wikis/chess/MatchSummary.lua | 2 -- lua/wikis/commons/MatchGroup/Util.lua | 2 ++ .../commons/MatchGroup/Util/Starcraft.lua | 2 +- lua/wikis/commons/MatchSummary/Base.lua | 6 ++--- lua/wikis/commons/MatchSummary/Starcraft.lua | 13 ++++------- .../hearthstone/MatchGroup/Util/Custom.lua | 3 ++- lua/wikis/hearthstone/MatchSummary.lua | 7 +----- .../stormgate/MatchGroup/Util/Custom.lua | 3 ++- lua/wikis/stormgate/MatchSummary.lua | 22 ++++++++----------- lua/wikis/warcraft/MatchGroup/Util/Custom.lua | 5 +++-- lua/wikis/warcraft/MatchSummary.lua | 18 ++++++--------- 11 files changed, 34 insertions(+), 49 deletions(-) diff --git a/lua/wikis/chess/MatchSummary.lua b/lua/wikis/chess/MatchSummary.lua index af882e4e990..75efefac977 100644 --- a/lua/wikis/chess/MatchSummary.lua +++ b/lua/wikis/chess/MatchSummary.lua @@ -46,8 +46,6 @@ local KING_ICONS = { }, } - - ---@class ChessMatchSummaryGameRowComponentProps: MatchSummaryGameRowComponentProps local GameRowComponentProps = {} diff --git a/lua/wikis/commons/MatchGroup/Util.lua b/lua/wikis/commons/MatchGroup/Util.lua index 5ed56d1294e..b08ad8617f2 100644 --- a/lua/wikis/commons/MatchGroup/Util.lua +++ b/lua/wikis/commons/MatchGroup/Util.lua @@ -285,6 +285,7 @@ MatchGroupUtil.types.Game = TypeUtil.struct({ ---@field shortname string? ---@field status MatchStatus ---@field stream table +---@field submatches MatchGroupUtilSubgroup[] ---@field tickername string? ---@field tournament string? ---@field type string? @@ -611,6 +612,7 @@ function MatchGroupUtil.matchFromRecord(record) } match.phase = MatchGroupUtil.computeMatchPhase(match) + match.submatches = MatchGroupUtil.groupBySubgroup(match) return match end diff --git a/lua/wikis/commons/MatchGroup/Util/Starcraft.lua b/lua/wikis/commons/MatchGroup/Util/Starcraft.lua index 21a8eeb62ab..8490ffa09ec 100644 --- a/lua/wikis/commons/MatchGroup/Util/Starcraft.lua +++ b/lua/wikis/commons/MatchGroup/Util/Starcraft.lua @@ -82,7 +82,7 @@ function StarcraftMatchGroupUtil.matchFromRecord(record) if match.opponentMode == 'team' then -- Compute submatches match.submatches = Array.map( - MatchGroupUtil.groupBySubgroup(match), + match.submatches, FnUtil.curry(StarcraftMatchGroupUtil.constructSubmatch, match) ) end diff --git a/lua/wikis/commons/MatchSummary/Base.lua b/lua/wikis/commons/MatchSummary/Base.lua index 09cd3867a58..b630141e00e 100644 --- a/lua/wikis/commons/MatchSummary/Base.lua +++ b/lua/wikis/commons/MatchSummary/Base.lua @@ -75,9 +75,9 @@ function MatchSummary.createDefaultBody(match, CustomMatchSummary, options) local nodes if GameRow then - -- TODO: Move to parse from lpdb step - local sets = MatchGroupUtil.groupBySubgroup(match) + local sets = match.submatches + -- With one set for all matches, or one game per set, it's redundant to show set level info. if #sets > 1 and #sets < #match.games then nodes = Array.map(sets, function(set) return MatchSummaryWidgets.GamesContainer{ @@ -255,7 +255,7 @@ function MatchSummary.defaultGetByMatchId(CustomMatchSummary, args, options) type(CustomMatchSummary.createGames) == 'function' or CustomMatchSummary.GameRow ), - 'One of createBody or createGame or createGames must be implemented in Module:MatchSummary' + 'One of createBody or createGame or createGames or GameRow must be implemented in Module:MatchSummary' ) options = options or {} diff --git a/lua/wikis/commons/MatchSummary/Starcraft.lua b/lua/wikis/commons/MatchSummary/Starcraft.lua index 1490a3b5fcb..d48c26a6ef6 100644 --- a/lua/wikis/commons/MatchSummary/Starcraft.lua +++ b/lua/wikis/commons/MatchSummary/Starcraft.lua @@ -42,14 +42,9 @@ end function StarcraftMatchSummary.createBody(match) StarcraftMatchSummary.computeOffFactions(match) - local subMatches - if match.opponentMode ~= UNIFORM_MATCH then - subMatches = match.submatches or {} - end - return WidgetUtil.collect( Array.map(match.opponents, StarcraftMatchSummary.advantageOrPenalty), - subMatches and Array.map(subMatches, StarcraftMatchSummary.TeamSubmatch) + match.opponentMode ~= UNIFORM_MATCH and Array.map(match.submatches or {}, StarcraftMatchSummary.TeamSubmatch) or Array.map(match.games, FnUtil.curry(StarcraftMatchSummary.Game, {})), Logic.isNotEmpty(match.vetoes) and MatchSummaryWidgets.Row{ css = {['text-align'] = 'center'}, @@ -110,7 +105,7 @@ end ---@param options {noLink: boolean?, isPartOfSubMatch: boolean?} ---@param game StarcraftMatchGroupUtilGame ----@return MatchSummaryRow +---@return Renderable function StarcraftMatchSummary.Game(options, game) local noLink = options.noLink or (game.map or ''):upper() == TBD @@ -207,7 +202,7 @@ function StarcraftMatchSummary.TeamSubMatchOpponnetRow(submatch) ---@param opponentIndex integer ---@param additionalClasses string[]? - ---@return Widget + ---@return Renderable local createScore = function(opponentIndex, additionalClasses) return OpponentDisplay.BlockScore{ additionalClasses = additionalClasses, @@ -239,7 +234,7 @@ function StarcraftMatchSummary.TeamSubMatchOpponnetRow(submatch) end ---@param veto StarcraftMatchGroupUtilVeto ----@return MatchSummaryRow +---@return Renderable function StarcraftMatchSummary.Veto(veto) local statusIcon = function(opponentIndex) return opponentIndex == veto.by and MAP_VETO_LABEL or nil diff --git a/lua/wikis/hearthstone/MatchGroup/Util/Custom.lua b/lua/wikis/hearthstone/MatchGroup/Util/Custom.lua index 3c418cbcf0b..48e89af8908 100644 --- a/lua/wikis/hearthstone/MatchGroup/Util/Custom.lua +++ b/lua/wikis/hearthstone/MatchGroup/Util/Custom.lua @@ -54,7 +54,7 @@ function CustomMatchGroupUtil.matchFromRecord(record) -- Compute submatches match.submatches = Array.map( - MatchGroupUtil.groupBySubgroup(match), + match.submatches, FnUtil.curry(CustomMatchGroupUtil.constructSubmatch, match) ) @@ -82,6 +82,7 @@ end function CustomMatchGroupUtil.constructSubmatch(match, subgroup) local games = subgroup.games local firstGame = games[1] + ---@type HearthstoneMatchGroupUtilSubmatch local opponents = Table.deepCopy(firstGame.opponents) local isSubmatch = string.find(firstGame.map or '', '^[sS]ubmatch %d+$') if isSubmatch then diff --git a/lua/wikis/hearthstone/MatchSummary.lua b/lua/wikis/hearthstone/MatchSummary.lua index a4f10c05cda..da60b65f1fd 100644 --- a/lua/wikis/hearthstone/MatchSummary.lua +++ b/lua/wikis/hearthstone/MatchSummary.lua @@ -29,13 +29,8 @@ end ---@param match HearthstoneMatchGroupUtilMatch ---@return Renderable[] function CustomMatchSummary.createBody(match) - local submatches - if match.isTeamMatch then - submatches = match.submatches or {} - end - return WidgetUtil.collect( - submatches and Array.map(submatches, CustomMatchSummary.TeamSubmatch) + match.isTeamMatch and Array.map(match.submatches or {}, CustomMatchSummary.TeamSubmatch) or Array.map(match.games, FnUtil.curry(CustomMatchSummary.Game, {isPartOfSubMatch = false})) ) end diff --git a/lua/wikis/stormgate/MatchGroup/Util/Custom.lua b/lua/wikis/stormgate/MatchGroup/Util/Custom.lua index d17e4ef5eae..a2cbd20a360 100644 --- a/lua/wikis/stormgate/MatchGroup/Util/Custom.lua +++ b/lua/wikis/stormgate/MatchGroup/Util/Custom.lua @@ -92,7 +92,7 @@ function CustomMatchGroupUtil.matchFromRecord(record) if not match.isUniformMode then -- Compute submatches match.submatches = Array.map( - MatchGroupUtil.groupBySubgroup(match), + match.submatches, FnUtil.curry(CustomMatchGroupUtil.constructSubmatch, match) ) end @@ -160,6 +160,7 @@ end function CustomMatchGroupUtil.constructSubmatch(match, subgroup) local games = subgroup.games local firstGame = games[1] + ---@type StormgateMatchGroupUtilGameOpponent local opponents = Table.deepCopy(firstGame.opponents) local isSubmatch = String.startsWith(firstGame.map or '', 'Submatch') if isSubmatch then diff --git a/lua/wikis/stormgate/MatchSummary.lua b/lua/wikis/stormgate/MatchSummary.lua index 918214ec3e7..4aa573ca9dd 100644 --- a/lua/wikis/stormgate/MatchSummary.lua +++ b/lua/wikis/stormgate/MatchSummary.lua @@ -41,16 +41,12 @@ end ---@param match StormgateMatchGroupUtilMatch ---@return Widget[] function CustomMatchSummary.createBody(match) - CustomMatchSummary.computeOfffactions(match) + CustomMatchSummary.computeOffFactions(match) local hasHeroes = CustomMatchSummary.hasHeroes(match) - local subMatches - if not match.isUniformMode then - subMatches = match.submatches or {} - end return WidgetUtil.collect( Array.map(match.opponents, CustomMatchSummary.advantageOrPenalty), - subMatches and Array.map(subMatches, CustomMatchSummary.TeamSubmatch) + not match.isUniformMode and Array.map(match.submatches or {}, CustomMatchSummary.TeamSubmatch) or Array.map(match.games, FnUtil.curry(CustomMatchSummary.Game, {hasHeroes = hasHeroes})), Logic.isNotEmpty(match.vetoes) and MatchSummaryWidgets.Row{ css = {['text-align'] = 'center'}, @@ -61,16 +57,16 @@ function CustomMatchSummary.createBody(match) end ---@param match table -function CustomMatchSummary.computeOfffactions(match) +function CustomMatchSummary.computeOffFactions(match) if match.isUniformMode then - CustomMatchSummary.computeMatchOfffactions(match) + CustomMatchSummary.computeMatchOffFactions(match) else - Array.forEach(match.submatches, CustomMatchSummary.computeMatchOfffactions) + Array.forEach(match.submatches, CustomMatchSummary.computeMatchOffFactions) end end ---@param match table -function CustomMatchSummary.computeMatchOfffactions(match) +function CustomMatchSummary.computeMatchOffFactions(match) Array.forEach(match.games, function(game) game.offFactions = {} Array.forEach(game.opponents, function(gameOpponent, opponentIndex) @@ -198,7 +194,7 @@ function CustomMatchSummary.DisplayHeroes(opponent, options) end ---@param submatch StormgateMatchGroupUtilSubmatch ----@return MatchSummaryRow +---@return Renderable function CustomMatchSummary.TeamSubmatch(submatch) return MatchSummaryWidgets.Row{ children = WidgetUtil.collect( @@ -227,7 +223,7 @@ function CustomMatchSummary.TeamSubMatchOpponnetRow(submatch) ---@param opponentIndex integer ---@param additionalClasses string[]? - ---@return Widget + ---@return Renderable local createScore = function(opponentIndex, additionalClasses) return OpponentDisplay.BlockScore{ additionalClasses = additionalClasses, @@ -297,7 +293,7 @@ function CustomMatchSummary._submatchHasDetails(submatch) end ---@param veto StarcraftMatchGroupUtilVeto ----@return MatchSummaryRow +---@return Renderable function CustomMatchSummary.Veto(veto) local statusIcon = function(opponentIndex) return opponentIndex == veto.by and MAP_VETO_LABEL or nil diff --git a/lua/wikis/warcraft/MatchGroup/Util/Custom.lua b/lua/wikis/warcraft/MatchGroup/Util/Custom.lua index 0c3cdd5d826..65065611a84 100644 --- a/lua/wikis/warcraft/MatchGroup/Util/Custom.lua +++ b/lua/wikis/warcraft/MatchGroup/Util/Custom.lua @@ -84,7 +84,7 @@ function CustomMatchGroupUtil.matchFromRecord(record) if match.opponentMode == TEAM_DISPLAY_MODE then -- Compute submatches match.submatches = Array.map( - MatchGroupUtil.groupBySubgroup(match), + match.submatches, FnUtil.curry(CustomMatchGroupUtil.constructSubmatch, match) ) end @@ -153,6 +153,7 @@ end function CustomMatchGroupUtil.constructSubmatch(match, subgroup) local games = subgroup.games local firstGame = games[1] + ---@type WarcraftMatchGroupUtilGameOpponent local opponents = Table.deepCopy(firstGame.opponents) local isSubmatch = String.startsWith(firstGame.map or '', 'Submatch') if isSubmatch then @@ -234,7 +235,7 @@ end ---@param gameOpponent WarcraftMatchGroupUtilGameOpponent ---@param referenceOpponent standardOpponent|WarcraftMatchGroupUtilGameOpponent ---@return string[]? -function CustomMatchGroupUtil.computeOfffactions(gameOpponent, referenceOpponent) +function CustomMatchGroupUtil.computeOffFactions(gameOpponent, referenceOpponent) local gameFactions = {} local hasOfffaction = false for playerIndex, gamePlayer in ipairs(gameOpponent.players) do diff --git a/lua/wikis/warcraft/MatchSummary.lua b/lua/wikis/warcraft/MatchSummary.lua index 09cb75e7c71..765133deaf9 100644 --- a/lua/wikis/warcraft/MatchSummary.lua +++ b/lua/wikis/warcraft/MatchSummary.lua @@ -42,16 +42,12 @@ end ---@param match WarcraftMatchGroupUtilMatch ---@return Widget[] function CustomMatchSummary.createBody(match) - CustomMatchSummary.computeOfffactions(match) + CustomMatchSummary.computeOffFactions(match) local hasHeroes = CustomMatchSummary.hasHeroes(match) - local subMatches - if match.opponentMode ~= UNIFORM_MATCH then - subMatches = match.submatches or {} - end return WidgetUtil.collect( Array.map(match.opponents, CustomMatchSummary.advantageOrPenalty), - subMatches and Array.map(subMatches, CustomMatchSummary.TeamSubmatch) + match.opponentMode ~= UNIFORM_MATCH and Array.map(match.submatches or {}, CustomMatchSummary.TeamSubmatch) or Array.map(match.games, FnUtil.curry(CustomMatchSummary.Game, {hasHeroes = hasHeroes})), Logic.isNotEmpty(match.vetoes) and MatchSummaryWidgets.Row{ css = {['text-align'] = 'center'}, @@ -62,7 +58,7 @@ function CustomMatchSummary.createBody(match) end ---@param match table -function CustomMatchSummary.computeOfffactions(match) +function CustomMatchSummary.computeOffFactions(match) if match.opponentMode == UNIFORM_MATCH then CustomMatchSummary.computeMatchOfffactions(match) else @@ -75,7 +71,7 @@ function CustomMatchSummary.computeMatchOfffactions(match) Array.forEach(match.games, function(game) game.offFactions = {} Array.forEach(game.opponents, function(gameOpponent, opponentIndex) - game.offFactions[opponentIndex] = MatchGroupUtil.computeOfffactions( + game.offFactions[opponentIndex] = MatchGroupUtil.computeOffFactions( gameOpponent, match.opponents[opponentIndex] ) @@ -195,7 +191,7 @@ function CustomMatchSummary.DisplayHeroes(opponent, options) end ---@param submatch WarcraftMatchGroupUtilSubmatch ----@return MatchSummaryRow +---@return Renderable function CustomMatchSummary.TeamSubmatch(submatch) return MatchSummaryWidgets.Row{ children = WidgetUtil.collect( @@ -224,7 +220,7 @@ function CustomMatchSummary.TeamSubMatchOpponnetRow(submatch) ---@param opponentIndex integer ---@param additionalClasses string[]? - ---@return Widget + ---@return Renderable local createScore = function(opponentIndex, additionalClasses) return OpponentDisplay.BlockScore{ additionalClasses = additionalClasses, @@ -296,7 +292,7 @@ function CustomMatchSummary._submatchHasDetails(submatch) end ---@param veto StarcraftMatchGroupUtilVeto ----@return MatchSummaryRow +---@return Renderable function CustomMatchSummary.Veto(veto) local statusIcon = function(opponentIndex) return opponentIndex == veto.by and MAP_VETO_LABEL or nil From 629915ed071ec12018de83b934fe4b3ac6ec7050 Mon Sep 17 00:00:00 2001 From: Rikard Blixt Date: Mon, 17 Aug 2026 14:59:02 +0000 Subject: [PATCH 3/7] set header --- lua/wikis/commons/MatchSummary/Base.lua | 2 +- .../commons/Widget/Match/Summary/All.lua | 1 + .../Widget/Match/Summary/SetHeader.lua | 104 ++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 lua/wikis/commons/Widget/Match/Summary/SetHeader.lua diff --git a/lua/wikis/commons/MatchSummary/Base.lua b/lua/wikis/commons/MatchSummary/Base.lua index b630141e00e..8927b2d8249 100644 --- a/lua/wikis/commons/MatchSummary/Base.lua +++ b/lua/wikis/commons/MatchSummary/Base.lua @@ -82,7 +82,7 @@ function MatchSummary.createDefaultBody(match, CustomMatchSummary, options) nodes = Array.map(sets, function(set) return MatchSummaryWidgets.GamesContainer{ gamesSectionName = set.header or ('Set ' .. set.subgroup), - gamesSectionResult = 'TODO', -- TODO: Create Widget for it + gamesSectionResult = MatchSummaryWidgets.SetHeader{set = set}, children = Array.map(set.games, function(game, gameIndex) return GameRow{game = game, gameIndex = gameIndex} end) diff --git a/lua/wikis/commons/Widget/Match/Summary/All.lua b/lua/wikis/commons/Widget/Match/Summary/All.lua index 3b46e3c5237..3bb23c94331 100644 --- a/lua/wikis/commons/Widget/Match/Summary/All.lua +++ b/lua/wikis/commons/Widget/Match/Summary/All.lua @@ -29,5 +29,6 @@ Widgets.MapVeto = Lua.import('Module:Widget/Match/Summary/MapVeto') Widgets.MatchComment = Lua.import('Module:Widget/Match/Summary/MatchComment') Widgets.Mvp = Lua.import('Module:Widget/Match/Summary/Mvp') Widgets.Row = Lua.import('Module:Widget/Match/Summary/Row') +Widgets.SetHeader = Lua.import('Module:Widget/Match/Summary/SetHeader') return Widgets diff --git a/lua/wikis/commons/Widget/Match/Summary/SetHeader.lua b/lua/wikis/commons/Widget/Match/Summary/SetHeader.lua new file mode 100644 index 00000000000..f70b4cf7e5e --- /dev/null +++ b/lua/wikis/commons/Widget/Match/Summary/SetHeader.lua @@ -0,0 +1,104 @@ +--- +-- @Liquipedia +-- page=Module:Widget/Match/Summary/SetHeader +-- +-- Please see https://github.com/Liquipedia/Lua-Modules to contribute +-- + +local Lua = require('Module:Lua') + +local Array = Lua.import('Module:Array') + +local MatchGroupUtil = Lua.import('Module:MatchGroup/Util') + +local Component = Lua.import('Module:Widget/Component') +local Html = Lua.import('Module:Widget/Html') +local Span = Html.Span +local Div = Html.Div + +local WinLossIndicator = Lua.import('Module:Widget/Match/Summary/GameWinLossIndicator') + +---@class MatchSetHeaderProps +---@field set MatchGroupUtilSubgroup +local MatchHeader = {} + +-- TODO: Move logic elsewhere + +---@param props MatchSetHeaderProps +---@return VNode? +local function MatchSetHeader(props) + local set = props.set + if not set then + return nil + end + + local isStarted = Array.any(set.games, function (game) + return MatchGroupUtil.computeMatchPhase(game) ~= 'upcoming' + end) + local isFinished = Array.all(set.games, function (game) + return MatchGroupUtil.computeMatchPhase(game) == 'finished' + end) + + local scoreLeft, scoreRight = 0, 0 + if isStarted then + Array.forEach(set.games, function(game) + if game.winner == 1 then + scoreLeft = scoreLeft + 1 + elseif game.winner == 2 then + scoreRight = scoreRight + 1 + end + end) + end + + local winner + if isFinished then + if scoreLeft == scoreRight then + winner = 0 + elseif scoreLeft > scoreRight then + winner = 1 + elseif scoreRight > scoreLeft then + winner = 2 + end + end + + return Div{ + classes = {'match-info-header'}, + children = { + Div{ + children = { + WinLossIndicator{winner = winner, opponentIndex = 1} + } + }, + Div{ + classes = {'match-info-header-scoreholder'}, + children = isStarted and { + Span{ + classes = { + 'match-info-header-scoreholder-score', + (winner == 0 or winner == 1) and 'match-info-header-winner' or nil + }, + children = scoreLeft, + }, + Span{ + classes = {'match-info-header-scoreholder-divider'}, + children = ':' + }, + Span{ + classes = { + 'match-info-header-scoreholder-score', + (winner == 0 or winner == 2) and 'match-info-header-winner' or nil + }, + children = scoreRight, + } + } or nil, + }, + Div{ + children = { + WinLossIndicator{winner = winner, opponentIndex = 2} + } + }, + } + } +end + +return Component.component(MatchSetHeader) From 3696ee9a0155d92181344c37c7d748632787ae16 Mon Sep 17 00:00:00 2001 From: Rikard Blixt Date: Mon, 17 Aug 2026 15:09:45 +0000 Subject: [PATCH 4/7] styling --- lua/wikis/commons/Widget/Match/Summary/SetHeader.lua | 2 +- stylesheets/commons/Brackets.scss | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lua/wikis/commons/Widget/Match/Summary/SetHeader.lua b/lua/wikis/commons/Widget/Match/Summary/SetHeader.lua index f70b4cf7e5e..5361c117f5d 100644 --- a/lua/wikis/commons/Widget/Match/Summary/SetHeader.lua +++ b/lua/wikis/commons/Widget/Match/Summary/SetHeader.lua @@ -62,7 +62,7 @@ local function MatchSetHeader(props) end return Div{ - classes = {'match-info-header'}, + classes = {'brkts-popup-body-grid-header-center'}, children = { Div{ children = { diff --git a/stylesheets/commons/Brackets.scss b/stylesheets/commons/Brackets.scss index 4f02a72a10d..1c3c6b19f44 100644 --- a/stylesheets/commons/Brackets.scss +++ b/stylesheets/commons/Brackets.scss @@ -734,6 +734,10 @@ div.brkts-popup-body-element-thumbs { justify-content: center; } } + + &-center { + display: flex; + } } } From 539b8437d821f915ee07c291dcdf65eedddd79df Mon Sep 17 00:00:00 2001 From: Rikard Blixt Date: Tue, 18 Aug 2026 10:56:42 +0000 Subject: [PATCH 5/7] safety check --- lua/wikis/commons/MatchSummary/Base.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/wikis/commons/MatchSummary/Base.lua b/lua/wikis/commons/MatchSummary/Base.lua index 8927b2d8249..d204e301dd2 100644 --- a/lua/wikis/commons/MatchSummary/Base.lua +++ b/lua/wikis/commons/MatchSummary/Base.lua @@ -75,7 +75,7 @@ function MatchSummary.createDefaultBody(match, CustomMatchSummary, options) local nodes if GameRow then - local sets = match.submatches + local sets = match.submatches or {} -- With one set for all matches, or one game per set, it's redundant to show set level info. if #sets > 1 and #sets < #match.games then From 5c354f56ca7cfcd2f1c68558419458be81a442cb Mon Sep 17 00:00:00 2001 From: Rikard Blixt Date: Tue, 18 Aug 2026 11:01:26 +0000 Subject: [PATCH 6/7] lint --- lua/wikis/commons/Widget/Match/Summary/SetHeader.lua | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/lua/wikis/commons/Widget/Match/Summary/SetHeader.lua b/lua/wikis/commons/Widget/Match/Summary/SetHeader.lua index 5361c117f5d..577166b4219 100644 --- a/lua/wikis/commons/Widget/Match/Summary/SetHeader.lua +++ b/lua/wikis/commons/Widget/Match/Summary/SetHeader.lua @@ -18,15 +18,10 @@ local Div = Html.Div local WinLossIndicator = Lua.import('Module:Widget/Match/Summary/GameWinLossIndicator') ----@class MatchSetHeaderProps ----@field set MatchGroupUtilSubgroup -local MatchHeader = {} - --- TODO: Move logic elsewhere - ----@param props MatchSetHeaderProps +---@param props {set: MatchGroupUtilSubgroup} ---@return VNode? local function MatchSetHeader(props) + -- TODO: Move logic elsewhere in the future local set = props.set if not set then return nil From 819c3476dc6a04db5f6015e7a3ce0a62b4139468 Mon Sep 17 00:00:00 2001 From: Rikard Blixt Date: Tue, 18 Aug 2026 11:11:30 +0000 Subject: [PATCH 7/7] fix anno typos --- lua/wikis/hearthstone/MatchGroup/Util/Custom.lua | 2 +- lua/wikis/stormgate/MatchGroup/Util/Custom.lua | 2 +- lua/wikis/warcraft/MatchGroup/Util/Custom.lua | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lua/wikis/hearthstone/MatchGroup/Util/Custom.lua b/lua/wikis/hearthstone/MatchGroup/Util/Custom.lua index 48e89af8908..f2b09266f82 100644 --- a/lua/wikis/hearthstone/MatchGroup/Util/Custom.lua +++ b/lua/wikis/hearthstone/MatchGroup/Util/Custom.lua @@ -82,7 +82,7 @@ end function CustomMatchGroupUtil.constructSubmatch(match, subgroup) local games = subgroup.games local firstGame = games[1] - ---@type HearthstoneMatchGroupUtilSubmatch + ---@type HearthstoneMatchGroupUtilGameOpponent[] local opponents = Table.deepCopy(firstGame.opponents) local isSubmatch = string.find(firstGame.map or '', '^[sS]ubmatch %d+$') if isSubmatch then diff --git a/lua/wikis/stormgate/MatchGroup/Util/Custom.lua b/lua/wikis/stormgate/MatchGroup/Util/Custom.lua index a2cbd20a360..fb580348d8b 100644 --- a/lua/wikis/stormgate/MatchGroup/Util/Custom.lua +++ b/lua/wikis/stormgate/MatchGroup/Util/Custom.lua @@ -160,7 +160,7 @@ end function CustomMatchGroupUtil.constructSubmatch(match, subgroup) local games = subgroup.games local firstGame = games[1] - ---@type StormgateMatchGroupUtilGameOpponent + ---@type StormgateMatchGroupUtilGameOpponent[] local opponents = Table.deepCopy(firstGame.opponents) local isSubmatch = String.startsWith(firstGame.map or '', 'Submatch') if isSubmatch then diff --git a/lua/wikis/warcraft/MatchGroup/Util/Custom.lua b/lua/wikis/warcraft/MatchGroup/Util/Custom.lua index 65065611a84..375b593e04b 100644 --- a/lua/wikis/warcraft/MatchGroup/Util/Custom.lua +++ b/lua/wikis/warcraft/MatchGroup/Util/Custom.lua @@ -153,7 +153,7 @@ end function CustomMatchGroupUtil.constructSubmatch(match, subgroup) local games = subgroup.games local firstGame = games[1] - ---@type WarcraftMatchGroupUtilGameOpponent + ---@type WarcraftMatchGroupUtilGameOpponent[] local opponents = Table.deepCopy(firstGame.opponents) local isSubmatch = String.startsWith(firstGame.map or '', 'Submatch') if isSubmatch then