From 6a951c1e65d6780ebd060fb879ae232010ac72f7 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 13:58:22 +0900 Subject: [PATCH 01/28] type annotation --- lua/wikis/commons/MatchSummary/Base.lua | 31 +++++++++++++++---------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/lua/wikis/commons/MatchSummary/Base.lua b/lua/wikis/commons/MatchSummary/Base.lua index c06fd19c3ca..22debcc9fd6 100644 --- a/lua/wikis/commons/MatchSummary/Base.lua +++ b/lua/wikis/commons/MatchSummary/Base.lua @@ -29,6 +29,13 @@ local WidgetUtil = Lua.import('Module:Widget/Util') local MATCH_LINK_PRIORITY = Lua.import('Module:Links/MatchPriorityGroups', {loadData = true}) local TBD = Abbreviation.make{text = 'TBD', title = 'To Be Determined'} +---@class CustomMatchSummaryInterface +---@field createHeader? fun(match: MatchGroupUtilMatch, options: {teamStyle: teamStyle?}?): Widget +---@field createBody? fun(match: MatchGroupUtilMatch): Renderable|Renderable[] +---@field createGame? fun(date: string, game: table, gameIndex: integer): Renderable|Renderable[] +---@field addToFooter? fun(match: MatchGroupUtilMatch, footer: MatchSummaryFooter): MatchSummaryFooter +---@field createMatch? fun(matchData: MatchGroupUtilMatch): MatchSummaryMatch + ---@class MatchSummaryFooter ---@operator call: MatchSummaryFooter ---@field elements (Widget|Html|string|number)[] @@ -100,32 +107,32 @@ end ---@class MatchSummaryMatch ---@operator call: MatchSummaryMatch ---@field root Html ----@field headerElement Widget? ----@field bodyElement Widget[]? ----@field commentElement Widget? +---@field headerElement Renderable? +---@field bodyElement Renderable|Renderable[]? +---@field commentElement Renderable|Renderable[]? ---@field footerElement Widget? ----@field buttonElement Widget? +---@field buttonElement Renderable? local Match = Class.new( function(self) self.root = mw.html.create() end ) ----@param header Widget +---@param header Renderable ---@return MatchSummaryMatch function Match:header(header) self.headerElement = header return self end ----@param body Widget[] +---@param body Renderable|Renderable[] ---@return MatchSummaryMatch function Match:body(body) self.bodyElement = body return self end ----@param comment Widget +---@param comment Renderable ---@return MatchSummaryMatch function Match:comment(comment) self.commentElement = comment @@ -139,7 +146,7 @@ function Match:footer(footer) return self end ----@param button Widget +---@param button Renderable ---@return MatchSummaryMatch function Match:button(button) self.buttonElement = button @@ -165,7 +172,7 @@ local MatchSummary = { } ---Default header function ----@param match table +---@param match MatchGroupUtilMatch ---@param options {teamStyle: teamStyle?}? ---@return Widget function MatchSummary.createDefaultHeader(match, options) @@ -186,7 +193,7 @@ end -- Default body function ---@param match MatchGroupUtilMatch ----@param createGame fun(date: string, game: table, gameIndex: integer): Widget +---@param createGame fun(date: string, game: table, gameIndex: integer): Renderable|Renderable[] ---@return Widget[] function MatchSummary.createDefaultBody(match, createGame) return WidgetUtil.collect( @@ -230,7 +237,7 @@ end ---Default createMatch function for usage in Custom MatchSummary ---@param matchData MatchGroupUtilMatch? ----@param CustomMatchSummary table +---@param CustomMatchSummary CustomMatchSummaryInterface ---@param options {teamStyle: teamStyle?, noScore: boolean?}? ---@return MatchSummaryMatch? function MatchSummary.createMatch(matchData, CustomMatchSummary, options) @@ -270,7 +277,7 @@ function MatchSummary.createMatch(matchData, CustomMatchSummary, options) end ---Default getByMatchId function for usage in Custom MatchSummary ----@param CustomMatchSummary table +---@param CustomMatchSummary CustomMatchSummaryInterface ---@param args table ---@param options {teamStyle:teamStyle?, width: (fun(match: MatchGroupUtilMatch):string?)|string?, noScore:boolean?}? ---@return Widget From bcaef52b25e1ed7d27f1eac66a2f4446322b2115 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 14:00:36 +0900 Subject: [PATCH 02/28] type annotate custom --- lua/wikis/leagueoflegends/MatchSummary.lua | 5 +++-- lua/wikis/rainbowsix/MatchSummary.lua | 1 + lua/wikis/valorant/MatchSummary.lua | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lua/wikis/leagueoflegends/MatchSummary.lua b/lua/wikis/leagueoflegends/MatchSummary.lua index 57db347bed1..7513b107cfa 100644 --- a/lua/wikis/leagueoflegends/MatchSummary.lua +++ b/lua/wikis/leagueoflegends/MatchSummary.lua @@ -5,8 +5,6 @@ -- Please see https://github.com/Liquipedia/Lua-Modules to contribute -- -local CustomMatchSummary = {} - local Lua = require('Module:Lua') local Array = Lua.import('Module:Array') @@ -21,6 +19,9 @@ local MAX_NUM_BANS = 5 local NUM_HEROES_PICK = 5 local STATUS_NOT_PLAYED = 'notplayed' +---@class LoLCustomMatchSummary: CustomMatchSummaryInterface +local CustomMatchSummary = {} + ---@param args table ---@return Widget function CustomMatchSummary.getByMatchId(args) diff --git a/lua/wikis/rainbowsix/MatchSummary.lua b/lua/wikis/rainbowsix/MatchSummary.lua index 94d05bef2eb..f210b934727 100644 --- a/lua/wikis/rainbowsix/MatchSummary.lua +++ b/lua/wikis/rainbowsix/MatchSummary.lua @@ -21,6 +21,7 @@ local ROUND_ICONS = { otdef = '[[File:R6S Para Bellum def logo ot rounds.png|11px|link=]]', } +---@class RainbowsixMatchSummary: CustomMatchSummaryInterface local CustomMatchSummary = {} ---@param args table diff --git a/lua/wikis/valorant/MatchSummary.lua b/lua/wikis/valorant/MatchSummary.lua index c27e59acd9c..f3bbf7417a5 100644 --- a/lua/wikis/valorant/MatchSummary.lua +++ b/lua/wikis/valorant/MatchSummary.lua @@ -16,6 +16,7 @@ local MatchSummary = Lua.import('Module:MatchSummary/Base') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/All') local WidgetUtil = Lua.import('Module:Widget/Util') +---@class ValorantMatchSummary: CustomMatchSummaryInterface local CustomMatchSummary = {} ---@param args table From ff1d40d6d2438766f05da597c581416853e50b88 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 11:52:57 +0900 Subject: [PATCH 03/28] update lol matchsummary to use grid layout --- .../commons/Widget/Match/Summary/All.lua | 2 + .../Widget/Match/Summary/GameContainer.lua | 33 ++++++++ .../commons/Widget/Match/Summary/GameRow.lua | 69 ++++++++++++++++ lua/wikis/leagueoflegends/MatchSummary.lua | 79 ++++++++----------- stylesheets/commons/Brackets.scss | 48 +++++++++++ 5 files changed, 186 insertions(+), 45 deletions(-) create mode 100644 lua/wikis/commons/Widget/Match/Summary/GameContainer.lua create mode 100644 lua/wikis/commons/Widget/Match/Summary/GameRow.lua diff --git a/lua/wikis/commons/Widget/Match/Summary/All.lua b/lua/wikis/commons/Widget/Match/Summary/All.lua index b2250d66eb9..8b12f589b18 100644 --- a/lua/wikis/commons/Widget/Match/Summary/All.lua +++ b/lua/wikis/commons/Widget/Match/Summary/All.lua @@ -21,6 +21,8 @@ Widgets.DetailedScore = Lua.import('Module:Widget/Match/Summary/DetailedScore') Widgets.Footer = Lua.import('Module:Widget/Match/Summary/Footer') Widgets.GameCenter = Lua.import('Module:Widget/Match/Summary/GameCenter') Widgets.GameComment = Lua.import('Module:Widget/Match/Summary/GameComment') +Widgets.GameContainer = Lua.import('Module:Widget/Match/Summary/GameContainer') +Widgets.GameRow = Lua.import('Module:Widget/Match/Summary/GameRow') Widgets.GameTeamWrapper = Lua.import('Module:Widget/Match/Summary/GameTeamWrapper') Widgets.GameWinLossIndicator = Lua.import('Module:Widget/Match/Summary/GameWinLossIndicator') Widgets.MapVeto = Lua.import('Module:Widget/Match/Summary/MapVeto') diff --git a/lua/wikis/commons/Widget/Match/Summary/GameContainer.lua b/lua/wikis/commons/Widget/Match/Summary/GameContainer.lua new file mode 100644 index 00000000000..5cbb45c7327 --- /dev/null +++ b/lua/wikis/commons/Widget/Match/Summary/GameContainer.lua @@ -0,0 +1,33 @@ +--- +-- @Liquipedia +-- page=Module:Widget/Match/Summary/GameContainer +-- +-- Please see https://github.com/Liquipedia/Lua-Modules to contribute +-- + +local Lua = require('Module:Lua') + +local Class = Lua.import('Module:Class') +local Logic = Lua.import('Module:Logic') + +local Widget = Lua.import('Module:Widget') +local HtmlWidgets = Lua.import('Module:Widget/Html/All') + +---@class MatchSummaryGameContainer: Widget +---@operator call(table): MatchSummaryGameContainer +local MatchSummaryGameContainer = Class.new(Widget) + +---@return Widget? +function MatchSummaryGameContainer:render() + if Logic.isEmpty(self.props.children) then + return + end + return HtmlWidgets.Div{ + attributes = Logic.isNotEmpty(self.props.gridLayout) and {['data-grid-layout'] = self.props.gridLayout} or nil, + classes = {'brkts-popup-body-grid'}, + css = self.props.css, + children = self.props.children, + } +end + +return MatchSummaryGameContainer diff --git a/lua/wikis/commons/Widget/Match/Summary/GameRow.lua b/lua/wikis/commons/Widget/Match/Summary/GameRow.lua new file mode 100644 index 00000000000..275290c3899 --- /dev/null +++ b/lua/wikis/commons/Widget/Match/Summary/GameRow.lua @@ -0,0 +1,69 @@ +--- +-- @Liquipedia +-- page=Module:Widget/Match/Summary/GameRow +-- +-- Please see https://github.com/Liquipedia/Lua-Modules to contribute +-- + +local Lua = require('Module:Lua') + +local Class = Lua.import('Module:Class') +local Logic = Lua.import('Module:Logic') + +local Widget = Lua.import('Module:Widget') +local HtmlWidgets = Lua.import('Module:Widget/Html/All') +local GameWinLossIndicator = Lua.import('Module:Widget/Match/Summary/GameWinLossIndicator') + +---@class MatchSummaryGameRowProps +---@field css table? +---@field game MatchGroupUtilGame +---@field gameIndex integer + +---@class MatchSummaryGameRow: Widget +---@operator call(MatchSummaryGameRowProps): MatchSummaryGameRow +---@field props MatchSummaryGameRowProps +local MatchSummaryGameRow = Class.new(Widget) + +---@return Widget? +function MatchSummaryGameRow:render() + local props = self.props + return HtmlWidgets.Div{ + classes = {'brkts-popup-body-grid-row'}, + css = self.props.css, + children = { + GameWinLossIndicator{ + opponentIndex = 1, + winner = props.game.winner, + }, + HtmlWidgets.Div{ + classes = {'brkts-popup-body-grid-detail'}, + children = self:createGameDetail(), + }, + GameWinLossIndicator{ + opponentIndex = 2, + winner = props.game.winner, + }, + self:_renderGameComment() + }, + } +end + +---@protected +---@return Renderable|Renderable[] +function MatchSummaryGameRow:createGameDetail() + error('MatchSummaryGameRow:createGameDetail() cannot be called directly and must be overridden.') +end + +---@private +function MatchSummaryGameRow:_renderGameComment() + local game = self.props.game + if Logic.isEmpty(game.comment) then + return + end + return HtmlWidgets.Div{ + classes = {'brkts-popup-comment'}, + children = game.comment, + } +end + +return MatchSummaryGameRow diff --git a/lua/wikis/leagueoflegends/MatchSummary.lua b/lua/wikis/leagueoflegends/MatchSummary.lua index 7513b107cfa..bd066e70e9c 100644 --- a/lua/wikis/leagueoflegends/MatchSummary.lua +++ b/lua/wikis/leagueoflegends/MatchSummary.lua @@ -8,9 +8,10 @@ local Lua = require('Module:Lua') local Array = Lua.import('Module:Array') -local FnUtil = Lua.import('Module:FnUtil') +local Class = Lua.import('Module:Class') local Logic = Lua.import('Module:Logic') +local HtmlWidgets = Lua.import('Module:Widget/Html/All') local MatchSummary = Lua.import('Module:MatchSummary/Base') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/All') local WidgetUtil = Lua.import('Module:Widget/Util') @@ -22,6 +23,10 @@ local STATUS_NOT_PLAYED = 'notplayed' ---@class LoLCustomMatchSummary: CustomMatchSummaryInterface local CustomMatchSummary = {} +---@class LoLMatchSummaryGameRow: MatchSummaryGameRow +---@operator call(MatchSummaryGameRowProps): LoLMatchSummaryGameRow +local LoLMatchSummaryGameRow = Class.new(MatchSummaryWidgets.GameRow) + ---@param args table ---@return Widget function CustomMatchSummary.getByMatchId(args) @@ -34,20 +39,24 @@ function CustomMatchSummary.createBody(match) local characterBansData = MatchSummary.buildCharacterBanData(match.games, MAX_NUM_BANS) return WidgetUtil.collect( - Array.map(match.games, FnUtil.curry(CustomMatchSummary._createGame, match.date)), + MatchSummaryWidgets.GameContainer{ + gridLayout = 'standard', + children = Array.map(match.games, function (game, gameIndex) + if game.status == STATUS_NOT_PLAYED then + return + end + return LoLMatchSummaryGameRow{game = game, gameIndex = gameIndex} + end) + }, MatchSummaryWidgets.Mvp(match.extradata.mvp), MatchSummaryWidgets.CharacterBanTable{bans = characterBansData, date = match.date} ) end ----@param date string ----@param game MatchGroupUtilGame ----@param gameIndex integer ----@return MatchSummaryRow? -function CustomMatchSummary._createGame(date, game, gameIndex) - if game.status == STATUS_NOT_PLAYED then - return - end +---@return Widget +function LoLMatchSummaryGameRow:createGameDetail() + local props = self.props + local game = props.game local extradata = game.extradata or {} -- TODO: Change to use participant data @@ -56,41 +65,21 @@ function CustomMatchSummary._createGame(date, game, gameIndex) MatchSummary.buildCharacterList(extradata, 'team2champion', NUM_HEROES_PICK), } - return MatchSummaryWidgets.Row{ - classes = {'brkts-popup-body-game'}, - children = WidgetUtil.collect( - MatchSummaryWidgets.Characters{ - css = { - flex = '1 1 33%', - }, - flipped = false, - characters = characterData[1], - bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata.team1side or ''), - date = date, - }, - MatchSummaryWidgets.GameCenter{ - css = { - flex = '1 1 fit-content', - gap = '0.5rem', - }, - children = { - MatchSummaryWidgets.GameWinLossIndicator{winner = game.winner, opponentIndex = 1}, - MatchSummaryWidgets.GameCenter{children = Logic.emptyOr(game.length, 'Game ' .. gameIndex)}, - MatchSummaryWidgets.GameWinLossIndicator{winner = game.winner, opponentIndex = 2}, - } - }, - MatchSummaryWidgets.Characters{ - css = { - flex = '1 1 33%', - }, - flipped = true, - characters = characterData[2], - bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata.team2side or ''), - date = date, - }, - MatchSummaryWidgets.GameComment{children = game.comment} - ) - } + return HtmlWidgets.Div{children = { + MatchSummaryWidgets.Characters{ + flipped = false, + characters = characterData[1], + bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata.team1side or ''), + date = game.date, + }, + Logic.emptyOr(game.length, 'Game ' .. props.gameIndex), + MatchSummaryWidgets.Characters{ + flipped = true, + characters = characterData[2], + bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata.team2side or ''), + date = game.date, + }, + }} end return CustomMatchSummary diff --git a/stylesheets/commons/Brackets.scss b/stylesheets/commons/Brackets.scss index 3e399abfb92..065d0a1cdcc 100644 --- a/stylesheets/commons/Brackets.scss +++ b/stylesheets/commons/Brackets.scss @@ -638,6 +638,54 @@ div.brkts-popup-body-element-thumbs { } } +.brkts-popup-body-grid { + display: grid; + grid-template-columns: min-content auto min-content; + align-items: center; + margin: 0 -0.5rem; + + &[ data-grid-layout="standard" ] { + grid-template-columns: min-content 1fr auto 1fr min-content; + } + + &-row { + display: grid; + grid-column: 1 / -1; + grid-template-columns: subgrid; + gap: 0.5rem; + padding: 0.5rem; + + &:nth-of-type( even ) { + background-color: var( --clr-on-surface-light-primary-4 ); + + .theme--dark & { + background-color: var( --clr-on-surface-dark-primary-4 ); + } + } + + > .brkts-popup-comment { + padding: unset; + grid-column: 1 / -1; + } + } + + &-detail { + display: contents; + white-space: nowrap; + + > div:only-child { + display: grid; + grid-column: 2 / -2; + grid-template-columns: subgrid; + } + + &:empty { + display: block; + grid-column: 2 / -2; + } + } +} + .brkts-champion-icon { gap: 0.125rem; display: flex; From 80ec2432d89148a72be5ab7d8c1840a31aa1639c Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 13:16:24 +0900 Subject: [PATCH 04/28] update valorant match summary --- lua/wikis/valorant/MatchSummary.lua | 46 +++++++++++++++++------------ 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/lua/wikis/valorant/MatchSummary.lua b/lua/wikis/valorant/MatchSummary.lua index f3bbf7417a5..ffcfc7a9801 100644 --- a/lua/wikis/valorant/MatchSummary.lua +++ b/lua/wikis/valorant/MatchSummary.lua @@ -8,17 +8,24 @@ local Lua = require('Module:Lua') local Array = Lua.import('Module:Array') -local FnUtil = Lua.import('Module:FnUtil') +local Class = Lua.import('Module:Class') +local Logic = Lua.import('Module:Logic') local Operator = Lua.import('Module:Operator') local DisplayHelper = Lua.import('Module:MatchGroup/Display/Helper') local MatchSummary = Lua.import('Module:MatchSummary/Base') + +local HtmlWidgets = Lua.import('Module:Widget/Html/All') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/All') local WidgetUtil = Lua.import('Module:Widget/Util') ---@class ValorantMatchSummary: CustomMatchSummaryInterface local CustomMatchSummary = {} +---@class ValorantMatchSummaryGameRow: MatchSummaryGameRow +---@operator call(MatchSummaryGameRowProps): ValorantMatchSummaryGameRow +local ValorantMatchSummaryGameRow = Class.new(MatchSummaryWidgets.GameRow) + ---@param args table ---@return Widget function CustomMatchSummary.getByMatchId(args) @@ -30,22 +37,23 @@ end function CustomMatchSummary.createBody(match) return WidgetUtil.collect( - Array.map(match.games, FnUtil.curry(CustomMatchSummary.createGame, match.date)), + MatchSummaryWidgets.GameContainer{ + gridLayout = 'standard', + children = Array.map(match.games, function (game, gameIndex) + if Logic.isEmpty(game.map) then + return + end + return ValorantMatchSummaryGameRow{game = game, gameIndex = gameIndex} + end) + }, MatchSummaryWidgets.Mvp(match.extradata.mvp), MatchSummaryWidgets.MapVeto(MatchSummary.preProcessMapVeto(match.extradata.mapveto, {game = match.game})) ) end - - ----@param date string ----@param game MatchGroupUtilGame ----@param gameIndex integer ----@return Widget? -function CustomMatchSummary.createGame(date, game, gameIndex) - if not game.map then - return - end +---@return Widget +function ValorantMatchSummaryGameRow:createGameDetail() + local game = self.props.game local function scoreDisplay(oppIdx) return DisplayHelper.MapScore(game.opponents[oppIdx], game.status) @@ -62,12 +70,14 @@ function CustomMatchSummary.createGame(date, game, gameIndex) end local extradata = game.extradata or {} + + ---@param opponentIndex integer + ---@return Widget[] local function makeTeamSection(opponentIndex) local flipped = opponentIndex == 2 local firstSide = flipped and CustomMatchSummary._getOppositeSide(extradata.t1firstside) or extradata.t1firstside local characters = Array.map((game.opponents[opponentIndex] or {}).players or {}, Operator.property('agent')) return { - MatchSummaryWidgets.GameWinLossIndicator{winner = game.winner, opponentIndex = opponentIndex}, MatchSummaryWidgets.Characters{characters = characters, flipped = flipped, hideOnMobile = true}, MatchSummaryWidgets.DetailedScore{ score = scoreDisplay(opponentIndex), @@ -80,14 +90,12 @@ function CustomMatchSummary.createGame(date, game, gameIndex) } end - return MatchSummaryWidgets.Row{ - classes = {'brkts-popup-body-game'}, - children = WidgetUtil.collect( + return HtmlWidgets.Div{ + children = { MatchSummaryWidgets.GameTeamWrapper{children = makeTeamSection(1)}, MatchSummaryWidgets.GameCenter{children = DisplayHelper.Map(game)}, - MatchSummaryWidgets.GameTeamWrapper{children = makeTeamSection(2), flipped = true}, - MatchSummaryWidgets.GameComment{children = game.comment} - ) + MatchSummaryWidgets.GameTeamWrapper{children = makeTeamSection(2), flipped = true} + } } end From b20b06af28bb944174d491a31326d28c9b910deb Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 13:26:05 +0900 Subject: [PATCH 05/28] simplify display containers --- lua/wikis/leagueoflegends/MatchSummary.lua | 7 +++---- lua/wikis/valorant/MatchSummary.lua | 13 +++++-------- stylesheets/commons/Brackets.scss | 4 +--- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/lua/wikis/leagueoflegends/MatchSummary.lua b/lua/wikis/leagueoflegends/MatchSummary.lua index bd066e70e9c..4bc29f93e77 100644 --- a/lua/wikis/leagueoflegends/MatchSummary.lua +++ b/lua/wikis/leagueoflegends/MatchSummary.lua @@ -11,7 +11,6 @@ local Array = Lua.import('Module:Array') local Class = Lua.import('Module:Class') local Logic = Lua.import('Module:Logic') -local HtmlWidgets = Lua.import('Module:Widget/Html/All') local MatchSummary = Lua.import('Module:MatchSummary/Base') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/All') local WidgetUtil = Lua.import('Module:Widget/Util') @@ -53,7 +52,7 @@ function CustomMatchSummary.createBody(match) ) end ----@return Widget +---@return Widget[] function LoLMatchSummaryGameRow:createGameDetail() local props = self.props local game = props.game @@ -65,7 +64,7 @@ function LoLMatchSummaryGameRow:createGameDetail() MatchSummary.buildCharacterList(extradata, 'team2champion', NUM_HEROES_PICK), } - return HtmlWidgets.Div{children = { + return { MatchSummaryWidgets.Characters{ flipped = false, characters = characterData[1], @@ -79,7 +78,7 @@ function LoLMatchSummaryGameRow:createGameDetail() bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata.team2side or ''), date = game.date, }, - }} + } end return CustomMatchSummary diff --git a/lua/wikis/valorant/MatchSummary.lua b/lua/wikis/valorant/MatchSummary.lua index ffcfc7a9801..992bf5ee877 100644 --- a/lua/wikis/valorant/MatchSummary.lua +++ b/lua/wikis/valorant/MatchSummary.lua @@ -15,7 +15,6 @@ local Operator = Lua.import('Module:Operator') local DisplayHelper = Lua.import('Module:MatchGroup/Display/Helper') local MatchSummary = Lua.import('Module:MatchSummary/Base') -local HtmlWidgets = Lua.import('Module:Widget/Html/All') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/All') local WidgetUtil = Lua.import('Module:Widget/Util') @@ -51,7 +50,7 @@ function CustomMatchSummary.createBody(match) ) end ----@return Widget +---@return Widget[] function ValorantMatchSummaryGameRow:createGameDetail() local game = self.props.game @@ -90,12 +89,10 @@ function ValorantMatchSummaryGameRow:createGameDetail() } end - return HtmlWidgets.Div{ - children = { - MatchSummaryWidgets.GameTeamWrapper{children = makeTeamSection(1)}, - MatchSummaryWidgets.GameCenter{children = DisplayHelper.Map(game)}, - MatchSummaryWidgets.GameTeamWrapper{children = makeTeamSection(2), flipped = true} - } + return { + MatchSummaryWidgets.GameTeamWrapper{children = makeTeamSection(1)}, + MatchSummaryWidgets.GameCenter{children = DisplayHelper.Map(game)}, + MatchSummaryWidgets.GameTeamWrapper{children = makeTeamSection(2), flipped = true} } end diff --git a/stylesheets/commons/Brackets.scss b/stylesheets/commons/Brackets.scss index 065d0a1cdcc..6a774a276a4 100644 --- a/stylesheets/commons/Brackets.scss +++ b/stylesheets/commons/Brackets.scss @@ -673,10 +673,8 @@ div.brkts-popup-body-element-thumbs { display: contents; white-space: nowrap; - > div:only-child { - display: grid; + > :only-child { grid-column: 2 / -2; - grid-template-columns: subgrid; } &:empty { From f5b813141a95c85b991513c74b0c7ea9562aa878 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 13:32:33 +0900 Subject: [PATCH 06/28] reorganize imports --- lua/wikis/rainbowsix/MatchSummary.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lua/wikis/rainbowsix/MatchSummary.lua b/lua/wikis/rainbowsix/MatchSummary.lua index f210b934727..ab694d1fd24 100644 --- a/lua/wikis/rainbowsix/MatchSummary.lua +++ b/lua/wikis/rainbowsix/MatchSummary.lua @@ -8,9 +8,11 @@ local Lua = require('Module:Lua') local Array = Lua.import('Module:Array') -local DisplayHelper = Lua.import('Module:MatchGroup/Display/Helper') local FnUtil = Lua.import('Module:FnUtil') + +local DisplayHelper = Lua.import('Module:MatchGroup/Display/Helper') local MatchSummary = Lua.import('Module:MatchSummary/Base') + local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/All') local WidgetUtil = Lua.import('Module:Widget/Util') From da48b1be0081f2073d78b5c9497924406ef7548d Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 13:39:50 +0900 Subject: [PATCH 07/28] update rainbowsix match summary --- lua/wikis/rainbowsix/MatchSummary.lua | 86 ++++++++++++--------------- stylesheets/commons/Brackets.scss | 20 ------- 2 files changed, 39 insertions(+), 67 deletions(-) diff --git a/lua/wikis/rainbowsix/MatchSummary.lua b/lua/wikis/rainbowsix/MatchSummary.lua index ab694d1fd24..1fc8f82c882 100644 --- a/lua/wikis/rainbowsix/MatchSummary.lua +++ b/lua/wikis/rainbowsix/MatchSummary.lua @@ -8,7 +8,8 @@ local Lua = require('Module:Lua') local Array = Lua.import('Module:Array') -local FnUtil = Lua.import('Module:FnUtil') +local Class = Lua.import('Module:Class') +local Logic = Lua.import('Module:Logic') local DisplayHelper = Lua.import('Module:MatchGroup/Display/Helper') local MatchSummary = Lua.import('Module:MatchSummary/Base') @@ -26,6 +27,10 @@ local ROUND_ICONS = { ---@class RainbowsixMatchSummary: CustomMatchSummaryInterface local CustomMatchSummary = {} +---@class RainbowsixMatchSummaryGameRow: MatchSummaryGameRow +---@operator call(MatchSummaryGameRowProps): RainbowsixMatchSummaryGameRow +local RainbowsixMatchSummaryGameRow = Class.new(MatchSummaryWidgets.GameRow) + ---@param args table ---@return Widget function CustomMatchSummary.getByMatchId(args) @@ -45,21 +50,24 @@ function CustomMatchSummary.createBody(match) end) return WidgetUtil.collect( - Array.map(match.games, FnUtil.curry(CustomMatchSummary.createGame, match.date)), + MatchSummaryWidgets.GameContainer{ + gridLayout = 'standard', + children = Array.map(match.games, function (game, gameIndex) + if Logic.isEmpty(game.map) then + return + end + return RainbowsixMatchSummaryGameRow{game = game, gameIndex = gameIndex} + end) + }, MatchSummaryWidgets.Mvp(match.extradata.mvp), MatchSummaryWidgets.MapVeto(MatchSummary.preProcessMapVeto(match.extradata.mapveto, {game = match.game})), MatchSummaryWidgets.CharacterBanTable{bans = characterBansData, date = match.date} ) end ----@param date string ----@param game MatchGroupUtilGame ----@param gameIndex integer ----@return Widget? -function CustomMatchSummary.createGame(date, game, gameIndex) - if not game.map then - return - end +---@return Widget[] +function RainbowsixMatchSummaryGameRow:createGameDetail() + local game = self.props.game local extradata = game.extradata or {} local function scoreDisplay(oppIdx) @@ -81,43 +89,27 @@ function CustomMatchSummary.createGame(date, game, gameIndex) local firstSide = (firstSides.rt or ''):lower() local firstSideOt = (firstSides.ot or ''):lower() - -- Winner/Loser backgrounds - local gameStatusBackground = 'brkts-popup-body-gradient-default' - if game.winner == 1 then - gameStatusBackground = 'brkts-popup-body-gradient-left' - elseif game.winner == 2 then - gameStatusBackground = 'brkts-popup-body-gradient-right' - elseif game.winner == 0 then - gameStatusBackground = 'brkts-popup-body-gradient-draw' - end - - return MatchSummaryWidgets.Row{ - classes = {'brkts-popup-body-game', gameStatusBackground}, - children = WidgetUtil.collect( - MatchSummaryWidgets.GameWinLossIndicator{winner = game.winner, opponentIndex = 1}, - MatchSummaryWidgets.DetailedScore{ - score = scoreDisplay(1), - flipped = false, - partialScores = makePartialScores( - extradata.t1halfs or {}, - firstSide, - firstSideOt - ) - }, - MatchSummaryWidgets.GameCenter{children = DisplayHelper.Map(game), css = {['flex-grow'] = '1'}}, - MatchSummaryWidgets.DetailedScore{ - score = scoreDisplay(2), - flipped = true, - partialScores = makePartialScores( - extradata.t2halfs or {}, - CustomMatchSummary._getOppositeSide(firstSide), - CustomMatchSummary._getOppositeSide(firstSideOt) - ) - }, - MatchSummaryWidgets.GameWinLossIndicator{winner = game.winner, opponentIndex = 2}, - MatchSummaryWidgets.GameComment{children = game.comment} - ) - } + return WidgetUtil.collect( + MatchSummaryWidgets.DetailedScore{ + score = scoreDisplay(1), + flipped = false, + partialScores = makePartialScores( + extradata.t1halfs or {}, + firstSide, + firstSideOt + ) + }, + MatchSummaryWidgets.GameCenter{children = DisplayHelper.Map(game), css = {['flex-grow'] = '1'}}, + MatchSummaryWidgets.DetailedScore{ + score = scoreDisplay(2), + flipped = true, + partialScores = makePartialScores( + extradata.t2halfs or {}, + CustomMatchSummary._getOppositeSide(firstSide), + CustomMatchSummary._getOppositeSide(firstSideOt) + ) + } + ) end ---@param side string diff --git a/stylesheets/commons/Brackets.scss b/stylesheets/commons/Brackets.scss index 6a774a276a4..3d4b8a3d542 100644 --- a/stylesheets/commons/Brackets.scss +++ b/stylesheets/commons/Brackets.scss @@ -973,26 +973,6 @@ div.brkts-popup-body-element-thumbs { } } -.brkts-popup-body-gradient-left { - padding: 4px 0; - background: linear-gradient( to left, var( --clr-cinnabar-background-color, #fbdfdf ) 35%, var( --table-background-color, #ffffff ) 35%, var( --table-background-color, #ffffff ) 65%, var( --clr-forest-background-color, #ddf4dd ) 65% ) !important; -} - -.brkts-popup-body-gradient-right { - padding: 4px 0; - background: linear-gradient( to right, var( --clr-cinnabar-background-color, #fbdfdf ) 35%, var( --table-background-color, #ffffff ) 35%, var( --table-background-color, #ffffff ) 65%, var( --clr-forest-background-color, #ddf4dd ) 65% ) !important; -} - -.brkts-popup-body-gradient-draw { - padding: 4px 0; - background: linear-gradient( to left, var( --clr-pear-background-color, #f9f9c7 ) 35%, var( --table-background-color, #ffffff ) 35%, var( --table-background-color, #ffffff ) 65%, var( --clr-pear-background-color, #f9f9c7 ) 65% ) !important; -} - -.brkts-popup-body-gradient-default { - padding: 4px 0; - background: var( --table-background-color, #ffffff ) !important; -} - .brkts-popup-side-color { img { outline: 0.125rem solid transparent; From 912512a66563aea29e84eb66d847c46b0e52c583 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 13:42:39 +0900 Subject: [PATCH 08/28] use iconimage widget --- lua/wikis/rainbowsix/MatchSummary.lua | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lua/wikis/rainbowsix/MatchSummary.lua b/lua/wikis/rainbowsix/MatchSummary.lua index 1fc8f82c882..5fdd00c100f 100644 --- a/lua/wikis/rainbowsix/MatchSummary.lua +++ b/lua/wikis/rainbowsix/MatchSummary.lua @@ -15,13 +15,26 @@ local DisplayHelper = Lua.import('Module:MatchGroup/Display/Helper') local MatchSummary = Lua.import('Module:MatchSummary/Base') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/All') +local IconImage = Lua.import('Module:Widget/Image/Icon/Image') local WidgetUtil = Lua.import('Module:Widget/Util') local ROUND_ICONS = { - atk = '[[File:R6S Para Bellum atk logo.png|14px|link=]]', - def = '[[File:R6S Para Bellum def logo.png|14px|link=]]', - otatk = '[[File:R6S Para Bellum atk logo ot rounds.png|11px|link=]]', - otdef = '[[File:R6S Para Bellum def logo ot rounds.png|11px|link=]]', + atk = IconImage{ + imageLight = 'R6S Para Bellum atk logo.png', + size = '14px', + }, + def = IconImage{ + imageLight = 'R6S Para Bellum def logo.png', + size = '14px', + }, + otatk = IconImage{ + imageLight = 'R6S Para Bellum atk logo ot rounds.png', + size = '11px', + }, + otdef = IconImage{ + imageLight = 'R6S Para Bellum def logo ot rounds.png', + size = '11px', + }, } ---@class RainbowsixMatchSummary: CustomMatchSummaryInterface From 35461ae14ed16fe01e11ba7f9ac2a374d47236f8 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 14:09:44 +0900 Subject: [PATCH 09/28] type annotate dota2 match summary --- lua/wikis/dota2/MatchSummary.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lua/wikis/dota2/MatchSummary.lua b/lua/wikis/dota2/MatchSummary.lua index 26c10640a66..ee59f197d72 100644 --- a/lua/wikis/dota2/MatchSummary.lua +++ b/lua/wikis/dota2/MatchSummary.lua @@ -5,8 +5,6 @@ -- Please see https://github.com/Liquipedia/Lua-Modules to contribute -- -local CustomMatchSummary = {} - local Lua = require('Module:Lua') local Array = Lua.import('Module:Array') @@ -20,6 +18,9 @@ local MAX_NUM_BANS = 7 local NUM_HEROES_PICK = 5 local STATUS_NOT_PLAYED = 'notplayed' +---@class Dota2CustomMatchSummary: CustomMatchSummaryInterface +local CustomMatchSummary = {} + ---@param args table ---@return Widget function CustomMatchSummary.getByMatchId(args) From 3e3bcd5ad0a488163bb2e10ed1697a5f12d90f09 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 14:12:10 +0900 Subject: [PATCH 10/28] update dota2 match summary --- lua/wikis/dota2/MatchSummary.lua | 58 +++++++++++++++++--------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/lua/wikis/dota2/MatchSummary.lua b/lua/wikis/dota2/MatchSummary.lua index ee59f197d72..481d2e83929 100644 --- a/lua/wikis/dota2/MatchSummary.lua +++ b/lua/wikis/dota2/MatchSummary.lua @@ -8,6 +8,7 @@ local Lua = require('Module:Lua') local Array = Lua.import('Module:Array') +local Class = Lua.import('Module:Class') local Logic = Lua.import('Module:Logic') local MatchSummary = Lua.import('Module:MatchSummary/Base') @@ -21,6 +22,10 @@ local STATUS_NOT_PLAYED = 'notplayed' ---@class Dota2CustomMatchSummary: CustomMatchSummaryInterface local CustomMatchSummary = {} +---@class Dota2MatchSummaryGameRow: MatchSummaryGameRow +---@operator call(MatchSummaryGameRowProps): Dota2MatchSummaryGameRow +local Dota2MatchSummaryGameRow = Class.new(MatchSummaryWidgets.GameRow) + ---@param args table ---@return Widget function CustomMatchSummary.getByMatchId(args) @@ -33,19 +38,24 @@ function CustomMatchSummary.createBody(match) local characterBansData = MatchSummary.buildCharacterBanData(match.games, MAX_NUM_BANS) return WidgetUtil.collect( - Array.map(match.games, CustomMatchSummary._createGame), + MatchSummaryWidgets.GameContainer{ + gridLayout = 'standard', + children = Array.map(match.games, function (game, gameIndex) + if game.status == STATUS_NOT_PLAYED then + return + end + return Dota2MatchSummaryGameRow{game = game, gameIndex = gameIndex} + end) + }, MatchSummaryWidgets.Mvp(match.extradata.mvp), MatchSummaryWidgets.CharacterBanTable{bans = characterBansData, date = match.date} ) end ----@param game MatchGroupUtilGame ----@param gameIndex integer ----@return MatchSummaryRow? -function CustomMatchSummary._createGame(game, gameIndex) - if game.status == STATUS_NOT_PLAYED then - return - end +---@return Widget[] +function Dota2MatchSummaryGameRow:createGameDetail() + local props = self.props + local game = props.game local extradata = game.extradata or {} -- TODO: Change to use participant data @@ -54,25 +64,19 @@ function CustomMatchSummary._createGame(game, gameIndex) MatchSummary.buildCharacterList(extradata, 'team2hero', NUM_HEROES_PICK), } - return MatchSummaryWidgets.Row{ - classes = {'brkts-popup-body-game'}, - children = WidgetUtil.collect( - MatchSummaryWidgets.Characters{ - flipped = false, - characters = characterData[1], - bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata.team1side or ''), - }, - MatchSummaryWidgets.GameWinLossIndicator{winner = game.winner, opponentIndex = 1}, - MatchSummaryWidgets.GameCenter{children = Logic.nilIfEmpty(game.length) or ('Game ' .. gameIndex)}, - MatchSummaryWidgets.GameWinLossIndicator{winner = game.winner, opponentIndex = 2}, - MatchSummaryWidgets.Characters{ - flipped = true, - characters = characterData[2], - bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata.team2side or ''), - }, - MatchSummaryWidgets.GameComment{children = game.comment} - ) - } + return WidgetUtil.collect( + MatchSummaryWidgets.Characters{ + flipped = false, + characters = characterData[1], + bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata.team1side or ''), + }, + Logic.nilIfEmpty(game.length) or ('Game ' .. props.gameIndex), + MatchSummaryWidgets.Characters{ + flipped = true, + characters = characterData[2], + bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata.team2side or ''), + } + ) end return CustomMatchSummary From d37237139877a4699126b19c08c204ab0b4022e1 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 14:17:07 +0900 Subject: [PATCH 11/28] readd alignment rule --- stylesheets/commons/Brackets.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/stylesheets/commons/Brackets.scss b/stylesheets/commons/Brackets.scss index 3d4b8a3d542..7f71e93674e 100644 --- a/stylesheets/commons/Brackets.scss +++ b/stylesheets/commons/Brackets.scss @@ -652,6 +652,7 @@ div.brkts-popup-body-element-thumbs { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; + align-items: center; gap: 0.5rem; padding: 0.5rem; From 6fbc1cd254f030687e642a280996236e703ccd26 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 14:25:26 +0900 Subject: [PATCH 12/28] throw away inline css --- lua/wikis/rainbowsix/MatchSummary.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/wikis/rainbowsix/MatchSummary.lua b/lua/wikis/rainbowsix/MatchSummary.lua index 5fdd00c100f..8b2237251ef 100644 --- a/lua/wikis/rainbowsix/MatchSummary.lua +++ b/lua/wikis/rainbowsix/MatchSummary.lua @@ -112,7 +112,7 @@ function RainbowsixMatchSummaryGameRow:createGameDetail() firstSideOt ) }, - MatchSummaryWidgets.GameCenter{children = DisplayHelper.Map(game), css = {['flex-grow'] = '1'}}, + MatchSummaryWidgets.GameCenter{children = DisplayHelper.Map(game)}, MatchSummaryWidgets.DetailedScore{ score = scoreDisplay(2), flipped = true, From 9bfb5bcb7b04bbd5028dff2ca8a35b875e2b7a28 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 14:35:01 +0900 Subject: [PATCH 13/28] refactor --- .../commons/Widget/Match/Summary/GameRow.lua | 19 +++++++++++++++++++ lua/wikis/rainbowsix/MatchSummary.lua | 11 +++-------- lua/wikis/valorant/MatchSummary.lua | 9 ++------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/lua/wikis/commons/Widget/Match/Summary/GameRow.lua b/lua/wikis/commons/Widget/Match/Summary/GameRow.lua index 275290c3899..d940597496d 100644 --- a/lua/wikis/commons/Widget/Match/Summary/GameRow.lua +++ b/lua/wikis/commons/Widget/Match/Summary/GameRow.lua @@ -10,8 +10,11 @@ local Lua = require('Module:Lua') local Class = Lua.import('Module:Class') local Logic = Lua.import('Module:Logic') +local DisplayHelper = Lua.import('Module:MatchGroup/Display/Helper') + local Widget = Lua.import('Module:Widget') local HtmlWidgets = Lua.import('Module:Widget/Html/All') +local GameCenter = Lua.import('Module:Widget/Match/Summary/GameCenter') local GameWinLossIndicator = Lua.import('Module:Widget/Match/Summary/GameWinLossIndicator') ---@class MatchSummaryGameRowProps @@ -54,6 +57,22 @@ function MatchSummaryGameRow:createGameDetail() error('MatchSummaryGameRow:createGameDetail() cannot be called directly and must be overridden.') end +---@protected +---@param config {noLink: boolean?}? +---@return Widget +function MatchSummaryGameRow:mapDisplay(config) + local game = self.props.game + return GameCenter{children = DisplayHelper.Map(game, config)} +end + +---@protected +---@param opponentIndex integer +---@return string +function MatchSummaryGameRow:scoreDisplay(opponentIndex) + local game = self.props.game + return DisplayHelper.MapScore(game.opponents[opponentIndex], game.status) +end + ---@private function MatchSummaryGameRow:_renderGameComment() local game = self.props.game diff --git a/lua/wikis/rainbowsix/MatchSummary.lua b/lua/wikis/rainbowsix/MatchSummary.lua index 8b2237251ef..23025566b8f 100644 --- a/lua/wikis/rainbowsix/MatchSummary.lua +++ b/lua/wikis/rainbowsix/MatchSummary.lua @@ -11,7 +11,6 @@ local Array = Lua.import('Module:Array') local Class = Lua.import('Module:Class') local Logic = Lua.import('Module:Logic') -local DisplayHelper = Lua.import('Module:MatchGroup/Display/Helper') local MatchSummary = Lua.import('Module:MatchSummary/Base') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/All') @@ -83,10 +82,6 @@ function RainbowsixMatchSummaryGameRow:createGameDetail() local game = self.props.game local extradata = game.extradata or {} - local function scoreDisplay(oppIdx) - return DisplayHelper.MapScore(game.opponents[oppIdx], game.status) - end - local function makePartialScores(halves, firstSide, firstSideOt) local oppositeSide = CustomMatchSummary._getOppositeSide(firstSide) local oppositeSideOt = CustomMatchSummary._getOppositeSide(firstSideOt) @@ -104,7 +99,7 @@ function RainbowsixMatchSummaryGameRow:createGameDetail() return WidgetUtil.collect( MatchSummaryWidgets.DetailedScore{ - score = scoreDisplay(1), + score = self:scoreDisplay(1), flipped = false, partialScores = makePartialScores( extradata.t1halfs or {}, @@ -112,9 +107,9 @@ function RainbowsixMatchSummaryGameRow:createGameDetail() firstSideOt ) }, - MatchSummaryWidgets.GameCenter{children = DisplayHelper.Map(game)}, + self:mapDisplay(), MatchSummaryWidgets.DetailedScore{ - score = scoreDisplay(2), + score = self:scoreDisplay(2), flipped = true, partialScores = makePartialScores( extradata.t2halfs or {}, diff --git a/lua/wikis/valorant/MatchSummary.lua b/lua/wikis/valorant/MatchSummary.lua index 992bf5ee877..86a809c3563 100644 --- a/lua/wikis/valorant/MatchSummary.lua +++ b/lua/wikis/valorant/MatchSummary.lua @@ -12,7 +12,6 @@ local Class = Lua.import('Module:Class') local Logic = Lua.import('Module:Logic') local Operator = Lua.import('Module:Operator') -local DisplayHelper = Lua.import('Module:MatchGroup/Display/Helper') local MatchSummary = Lua.import('Module:MatchSummary/Base') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/All') @@ -54,10 +53,6 @@ end function ValorantMatchSummaryGameRow:createGameDetail() local game = self.props.game - local function scoreDisplay(oppIdx) - return DisplayHelper.MapScore(game.opponents[oppIdx], game.status) - end - local function makePartialScores(halves, firstSide) local oppositeSide = CustomMatchSummary._getOppositeSide(firstSide) return { @@ -79,7 +74,7 @@ function ValorantMatchSummaryGameRow:createGameDetail() return { MatchSummaryWidgets.Characters{characters = characters, flipped = flipped, hideOnMobile = true}, MatchSummaryWidgets.DetailedScore{ - score = scoreDisplay(opponentIndex), + score = self:scoreDisplay(opponentIndex), flipped = flipped, partialScores = makePartialScores( extradata['t' .. opponentIndex .. 'halfs'] or {}, @@ -91,7 +86,7 @@ function ValorantMatchSummaryGameRow:createGameDetail() return { MatchSummaryWidgets.GameTeamWrapper{children = makeTeamSection(1)}, - MatchSummaryWidgets.GameCenter{children = DisplayHelper.Map(game)}, + self:mapDisplay(), MatchSummaryWidgets.GameTeamWrapper{children = makeTeamSection(2), flipped = true} } end From 854a55614b2ee2932fc52884d8d9e28221a201b8 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 15:02:16 +0900 Subject: [PATCH 14/28] refactor length display --- lua/wikis/commons/Widget/Match/Summary/GameRow.lua | 7 +++++++ lua/wikis/dota2/MatchSummary.lua | 3 +-- lua/wikis/leagueoflegends/MatchSummary.lua | 3 +-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lua/wikis/commons/Widget/Match/Summary/GameRow.lua b/lua/wikis/commons/Widget/Match/Summary/GameRow.lua index d940597496d..51552e23711 100644 --- a/lua/wikis/commons/Widget/Match/Summary/GameRow.lua +++ b/lua/wikis/commons/Widget/Match/Summary/GameRow.lua @@ -57,6 +57,13 @@ function MatchSummaryGameRow:createGameDetail() error('MatchSummaryGameRow:createGameDetail() cannot be called directly and must be overridden.') end +---@protected +---@return Widget +function MatchSummaryGameRow:lengthDisplay() + local game = self.props.game + return GameCenter{children = Logic.emptyOr(game.length, 'Game ' .. self.props.gameIndex)} +end + ---@protected ---@param config {noLink: boolean?}? ---@return Widget diff --git a/lua/wikis/dota2/MatchSummary.lua b/lua/wikis/dota2/MatchSummary.lua index 481d2e83929..848c5b14762 100644 --- a/lua/wikis/dota2/MatchSummary.lua +++ b/lua/wikis/dota2/MatchSummary.lua @@ -9,7 +9,6 @@ local Lua = require('Module:Lua') local Array = Lua.import('Module:Array') local Class = Lua.import('Module:Class') -local Logic = Lua.import('Module:Logic') local MatchSummary = Lua.import('Module:MatchSummary/Base') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/All') @@ -70,7 +69,7 @@ function Dota2MatchSummaryGameRow:createGameDetail() characters = characterData[1], bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata.team1side or ''), }, - Logic.nilIfEmpty(game.length) or ('Game ' .. props.gameIndex), + self:lengthDisplay(), MatchSummaryWidgets.Characters{ flipped = true, characters = characterData[2], diff --git a/lua/wikis/leagueoflegends/MatchSummary.lua b/lua/wikis/leagueoflegends/MatchSummary.lua index 4bc29f93e77..297fd5f49d2 100644 --- a/lua/wikis/leagueoflegends/MatchSummary.lua +++ b/lua/wikis/leagueoflegends/MatchSummary.lua @@ -9,7 +9,6 @@ local Lua = require('Module:Lua') local Array = Lua.import('Module:Array') local Class = Lua.import('Module:Class') -local Logic = Lua.import('Module:Logic') local MatchSummary = Lua.import('Module:MatchSummary/Base') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/All') @@ -71,7 +70,7 @@ function LoLMatchSummaryGameRow:createGameDetail() bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata.team1side or ''), date = game.date, }, - Logic.emptyOr(game.length, 'Game ' .. props.gameIndex), + self:lengthDisplay(), MatchSummaryWidgets.Characters{ flipped = true, characters = characterData[2], From d9ddf9a1d60b2161b39052bbdb61e67f28890ac9 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 16:47:06 +0900 Subject: [PATCH 15/28] change selector name --- .../commons/Widget/Match/Summary/GameRow.lua | 2 +- stylesheets/commons/Brackets.scss | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lua/wikis/commons/Widget/Match/Summary/GameRow.lua b/lua/wikis/commons/Widget/Match/Summary/GameRow.lua index 51552e23711..f58d8da7272 100644 --- a/lua/wikis/commons/Widget/Match/Summary/GameRow.lua +++ b/lua/wikis/commons/Widget/Match/Summary/GameRow.lua @@ -39,7 +39,7 @@ function MatchSummaryGameRow:render() winner = props.game.winner, }, HtmlWidgets.Div{ - classes = {'brkts-popup-body-grid-detail'}, + classes = {'brkts-popup-body-grid-row-detail'}, children = self:createGameDetail(), }, GameWinLossIndicator{ diff --git a/stylesheets/commons/Brackets.scss b/stylesheets/commons/Brackets.scss index 7f71e93674e..2c879343b62 100644 --- a/stylesheets/commons/Brackets.scss +++ b/stylesheets/commons/Brackets.scss @@ -668,19 +668,19 @@ div.brkts-popup-body-element-thumbs { padding: unset; grid-column: 1 / -1; } - } - &-detail { - display: contents; - white-space: nowrap; + &-detail { + display: contents; + white-space: nowrap; - > :only-child { - grid-column: 2 / -2; - } + > :only-child { + grid-column: 2 / -2; + } - &:empty { - display: block; - grid-column: 2 / -2; + &:empty { + display: block; + grid-column: 2 / -2; + } } } } From 010e9e441bdd850c3782937cb6549a1a7dd137c2 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 16:55:33 +0900 Subject: [PATCH 16/28] cleanup --- lua/wikis/commons/Widget/Match/Summary/GameRow.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/wikis/commons/Widget/Match/Summary/GameRow.lua b/lua/wikis/commons/Widget/Match/Summary/GameRow.lua index f58d8da7272..2e266ac66d0 100644 --- a/lua/wikis/commons/Widget/Match/Summary/GameRow.lua +++ b/lua/wikis/commons/Widget/Match/Summary/GameRow.lua @@ -32,7 +32,7 @@ function MatchSummaryGameRow:render() local props = self.props return HtmlWidgets.Div{ classes = {'brkts-popup-body-grid-row'}, - css = self.props.css, + css = props.css, children = { GameWinLossIndicator{ opponentIndex = 1, From 3c69dec57e51984413ea56dce805a276be53206e Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 16:55:57 +0900 Subject: [PATCH 17/28] type annotation --- lua/wikis/commons/Widget/Match/Summary/GameRow.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/lua/wikis/commons/Widget/Match/Summary/GameRow.lua b/lua/wikis/commons/Widget/Match/Summary/GameRow.lua index 2e266ac66d0..7425d6e32ea 100644 --- a/lua/wikis/commons/Widget/Match/Summary/GameRow.lua +++ b/lua/wikis/commons/Widget/Match/Summary/GameRow.lua @@ -81,6 +81,7 @@ function MatchSummaryGameRow:scoreDisplay(opponentIndex) end ---@private +---@return Widget? function MatchSummaryGameRow:_renderGameComment() local game = self.props.game if Logic.isEmpty(game.comment) then From 116a41f67e1b03a7016794b3e758ec99594582c6 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Sat, 21 Mar 2026 17:03:25 +0900 Subject: [PATCH 18/28] rename --- lua/wikis/commons/Widget/Match/Summary/All.lua | 2 +- .../{GameContainer.lua => GamesContainer.lua} | 12 ++++++------ lua/wikis/dota2/MatchSummary.lua | 2 +- lua/wikis/leagueoflegends/MatchSummary.lua | 2 +- lua/wikis/rainbowsix/MatchSummary.lua | 2 +- lua/wikis/valorant/MatchSummary.lua | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) rename lua/wikis/commons/Widget/Match/Summary/{GameContainer.lua => GamesContainer.lua} (69%) diff --git a/lua/wikis/commons/Widget/Match/Summary/All.lua b/lua/wikis/commons/Widget/Match/Summary/All.lua index 8b12f589b18..3b46e3c5237 100644 --- a/lua/wikis/commons/Widget/Match/Summary/All.lua +++ b/lua/wikis/commons/Widget/Match/Summary/All.lua @@ -21,7 +21,7 @@ Widgets.DetailedScore = Lua.import('Module:Widget/Match/Summary/DetailedScore') Widgets.Footer = Lua.import('Module:Widget/Match/Summary/Footer') Widgets.GameCenter = Lua.import('Module:Widget/Match/Summary/GameCenter') Widgets.GameComment = Lua.import('Module:Widget/Match/Summary/GameComment') -Widgets.GameContainer = Lua.import('Module:Widget/Match/Summary/GameContainer') +Widgets.GamesContainer = Lua.import('Module:Widget/Match/Summary/GamesContainer') Widgets.GameRow = Lua.import('Module:Widget/Match/Summary/GameRow') Widgets.GameTeamWrapper = Lua.import('Module:Widget/Match/Summary/GameTeamWrapper') Widgets.GameWinLossIndicator = Lua.import('Module:Widget/Match/Summary/GameWinLossIndicator') diff --git a/lua/wikis/commons/Widget/Match/Summary/GameContainer.lua b/lua/wikis/commons/Widget/Match/Summary/GamesContainer.lua similarity index 69% rename from lua/wikis/commons/Widget/Match/Summary/GameContainer.lua rename to lua/wikis/commons/Widget/Match/Summary/GamesContainer.lua index 5cbb45c7327..f385e8348d8 100644 --- a/lua/wikis/commons/Widget/Match/Summary/GameContainer.lua +++ b/lua/wikis/commons/Widget/Match/Summary/GamesContainer.lua @@ -1,6 +1,6 @@ --- -- @Liquipedia --- page=Module:Widget/Match/Summary/GameContainer +-- page=Module:Widget/Match/Summary/GamesContainer -- -- Please see https://github.com/Liquipedia/Lua-Modules to contribute -- @@ -13,12 +13,12 @@ local Logic = Lua.import('Module:Logic') local Widget = Lua.import('Module:Widget') local HtmlWidgets = Lua.import('Module:Widget/Html/All') ----@class MatchSummaryGameContainer: Widget ----@operator call(table): MatchSummaryGameContainer -local MatchSummaryGameContainer = Class.new(Widget) +---@class MatchSummaryGamesContainer: Widget +---@operator call(table): MatchSummaryGamesContainer +local MatchSummaryGamesContainer = Class.new(Widget) ---@return Widget? -function MatchSummaryGameContainer:render() +function MatchSummaryGamesContainer:render() if Logic.isEmpty(self.props.children) then return end @@ -30,4 +30,4 @@ function MatchSummaryGameContainer:render() } end -return MatchSummaryGameContainer +return MatchSummaryGamesContainer diff --git a/lua/wikis/dota2/MatchSummary.lua b/lua/wikis/dota2/MatchSummary.lua index 848c5b14762..6d272cb4a16 100644 --- a/lua/wikis/dota2/MatchSummary.lua +++ b/lua/wikis/dota2/MatchSummary.lua @@ -37,7 +37,7 @@ function CustomMatchSummary.createBody(match) local characterBansData = MatchSummary.buildCharacterBanData(match.games, MAX_NUM_BANS) return WidgetUtil.collect( - MatchSummaryWidgets.GameContainer{ + MatchSummaryWidgets.GamesContainer{ gridLayout = 'standard', children = Array.map(match.games, function (game, gameIndex) if game.status == STATUS_NOT_PLAYED then diff --git a/lua/wikis/leagueoflegends/MatchSummary.lua b/lua/wikis/leagueoflegends/MatchSummary.lua index 297fd5f49d2..ce3dd892eb7 100644 --- a/lua/wikis/leagueoflegends/MatchSummary.lua +++ b/lua/wikis/leagueoflegends/MatchSummary.lua @@ -37,7 +37,7 @@ function CustomMatchSummary.createBody(match) local characterBansData = MatchSummary.buildCharacterBanData(match.games, MAX_NUM_BANS) return WidgetUtil.collect( - MatchSummaryWidgets.GameContainer{ + MatchSummaryWidgets.GamesContainer{ gridLayout = 'standard', children = Array.map(match.games, function (game, gameIndex) if game.status == STATUS_NOT_PLAYED then diff --git a/lua/wikis/rainbowsix/MatchSummary.lua b/lua/wikis/rainbowsix/MatchSummary.lua index 23025566b8f..e217f732e57 100644 --- a/lua/wikis/rainbowsix/MatchSummary.lua +++ b/lua/wikis/rainbowsix/MatchSummary.lua @@ -62,7 +62,7 @@ function CustomMatchSummary.createBody(match) end) return WidgetUtil.collect( - MatchSummaryWidgets.GameContainer{ + MatchSummaryWidgets.GamesContainer{ gridLayout = 'standard', children = Array.map(match.games, function (game, gameIndex) if Logic.isEmpty(game.map) then diff --git a/lua/wikis/valorant/MatchSummary.lua b/lua/wikis/valorant/MatchSummary.lua index 86a809c3563..8c808bbd80d 100644 --- a/lua/wikis/valorant/MatchSummary.lua +++ b/lua/wikis/valorant/MatchSummary.lua @@ -35,7 +35,7 @@ end function CustomMatchSummary.createBody(match) return WidgetUtil.collect( - MatchSummaryWidgets.GameContainer{ + MatchSummaryWidgets.GamesContainer{ gridLayout = 'standard', children = Array.map(match.games, function (game, gameIndex) if Logic.isEmpty(game.map) then From 6ac8c595a777aa98731478764c8f0b41e30d770a Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Wed, 25 Mar 2026 09:23:45 +0900 Subject: [PATCH 19/28] restructure --- .../commons/Widget/Match/Summary/GameRow.lua | 25 ++++-- lua/wikis/dota2/MatchSummary.lua | 33 ++++---- lua/wikis/leagueoflegends/MatchSummary.lua | 35 ++++----- lua/wikis/rainbowsix/MatchSummary.lua | 77 ++++++++++--------- lua/wikis/valorant/MatchSummary.lua | 67 ++++++++-------- stylesheets/commons/Brackets.scss | 16 ++-- 6 files changed, 128 insertions(+), 125 deletions(-) diff --git a/lua/wikis/commons/Widget/Match/Summary/GameRow.lua b/lua/wikis/commons/Widget/Match/Summary/GameRow.lua index 7425d6e32ea..e9f827febb6 100644 --- a/lua/wikis/commons/Widget/Match/Summary/GameRow.lua +++ b/lua/wikis/commons/Widget/Match/Summary/GameRow.lua @@ -40,7 +40,11 @@ function MatchSummaryGameRow:render() }, HtmlWidgets.Div{ classes = {'brkts-popup-body-grid-row-detail'}, - children = self:createGameDetail(), + children = { + GameCenter{children = self:createGameOpponentView(1)}, + GameCenter{children = self:createGameOverview()}, + GameCenter{children = self:createGameOpponentView(2)} + }, }, GameWinLossIndicator{ opponentIndex = 2, @@ -51,25 +55,32 @@ function MatchSummaryGameRow:render() } end +---@protected +---@param opponentIndex integer +---@return Renderable|Renderable[] +function MatchSummaryGameRow:createGameOpponentView(opponentIndex) + error('MatchSummaryGameRow:createGameOpponentView() cannot be called directly and must be overridden.') +end + ---@protected ---@return Renderable|Renderable[] -function MatchSummaryGameRow:createGameDetail() - error('MatchSummaryGameRow:createGameDetail() cannot be called directly and must be overridden.') +function MatchSummaryGameRow:createGameOverview() + error('MatchSummaryGameRow:createGameOverview() cannot be called directly and must be overridden.') end ---@protected ----@return Widget +---@return Renderable? function MatchSummaryGameRow:lengthDisplay() local game = self.props.game - return GameCenter{children = Logic.emptyOr(game.length, 'Game ' .. self.props.gameIndex)} + return Logic.emptyOr(game.length, 'Game ' .. self.props.gameIndex) end ---@protected ---@param config {noLink: boolean?}? ----@return Widget +---@return string function MatchSummaryGameRow:mapDisplay(config) local game = self.props.game - return GameCenter{children = DisplayHelper.Map(game, config)} + return DisplayHelper.Map(game, config) end ---@protected diff --git a/lua/wikis/dota2/MatchSummary.lua b/lua/wikis/dota2/MatchSummary.lua index 6d272cb4a16..fd4296dcfa6 100644 --- a/lua/wikis/dota2/MatchSummary.lua +++ b/lua/wikis/dota2/MatchSummary.lua @@ -51,31 +51,26 @@ function CustomMatchSummary.createBody(match) ) end ----@return Widget[] -function Dota2MatchSummaryGameRow:createGameDetail() +---@param opponentIndex integer +---@return Widget +function Dota2MatchSummaryGameRow:createGameOpponentView(opponentIndex) local props = self.props local game = props.game local extradata = game.extradata or {} - -- TODO: Change to use participant data - local characterData = { - MatchSummary.buildCharacterList(extradata, 'team1hero', NUM_HEROES_PICK), - MatchSummary.buildCharacterList(extradata, 'team2hero', NUM_HEROES_PICK), + return MatchSummaryWidgets.Characters{ + flipped = opponentIndex == 2, + characters = MatchSummary.buildCharacterList( + extradata, 'team' .. opponentIndex .. 'hero', NUM_HEROES_PICK + ), + bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata['team' .. opponentIndex .. 'side'] or ''), + date = game.date, } +end - return WidgetUtil.collect( - MatchSummaryWidgets.Characters{ - flipped = false, - characters = characterData[1], - bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata.team1side or ''), - }, - self:lengthDisplay(), - MatchSummaryWidgets.Characters{ - flipped = true, - characters = characterData[2], - bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata.team2side or ''), - } - ) +---@return Renderable? +function Dota2MatchSummaryGameRow:createGameOverview() + return self:lengthDisplay() end return CustomMatchSummary diff --git a/lua/wikis/leagueoflegends/MatchSummary.lua b/lua/wikis/leagueoflegends/MatchSummary.lua index ce3dd892eb7..a7d1dc07edc 100644 --- a/lua/wikis/leagueoflegends/MatchSummary.lua +++ b/lua/wikis/leagueoflegends/MatchSummary.lua @@ -51,33 +51,26 @@ function CustomMatchSummary.createBody(match) ) end ----@return Widget[] -function LoLMatchSummaryGameRow:createGameDetail() +---@param opponentIndex integer +---@return Widget +function LoLMatchSummaryGameRow:createGameOpponentView(opponentIndex) local props = self.props local game = props.game local extradata = game.extradata or {} - -- TODO: Change to use participant data - local characterData = { - MatchSummary.buildCharacterList(extradata, 'team1champion', NUM_HEROES_PICK), - MatchSummary.buildCharacterList(extradata, 'team2champion', NUM_HEROES_PICK), + return MatchSummaryWidgets.Characters{ + flipped = opponentIndex == 2, + characters = MatchSummary.buildCharacterList( + extradata, 'team' .. opponentIndex .. 'champion', NUM_HEROES_PICK + ), + bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata['team' .. opponentIndex .. 'side'] or ''), + date = game.date, } +end - return { - MatchSummaryWidgets.Characters{ - flipped = false, - characters = characterData[1], - bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata.team1side or ''), - date = game.date, - }, - self:lengthDisplay(), - MatchSummaryWidgets.Characters{ - flipped = true, - characters = characterData[2], - bg = 'brkts-popup-side-color brkts-popup-side-color--' .. (extradata.team2side or ''), - date = game.date, - }, - } +---@return Renderable? +function LoLMatchSummaryGameRow:createGameOverview() + return self:lengthDisplay() end return CustomMatchSummary diff --git a/lua/wikis/rainbowsix/MatchSummary.lua b/lua/wikis/rainbowsix/MatchSummary.lua index e217f732e57..e37adbd6956 100644 --- a/lua/wikis/rainbowsix/MatchSummary.lua +++ b/lua/wikis/rainbowsix/MatchSummary.lua @@ -10,6 +10,7 @@ local Lua = require('Module:Lua') local Array = Lua.import('Module:Array') local Class = Lua.import('Module:Class') local Logic = Lua.import('Module:Logic') +local Table = Lua.import('Module:Table') local MatchSummary = Lua.import('Module:MatchSummary/Base') @@ -77,47 +78,49 @@ function CustomMatchSummary.createBody(match) ) end ----@return Widget[] -function RainbowsixMatchSummaryGameRow:createGameDetail() +---@private +---@param opponentIndex integer +---@return table[] +function RainbowsixMatchSummaryGameRow:_makePartialScores(opponentIndex) local game = self.props.game local extradata = game.extradata or {} + local halves = extradata['t' .. opponentIndex .. 'halfs'] + + ---@type table + local firstSides = Table.mapValues( + extradata.t1firstside or {}, + function (side) + if opponentIndex == 1 then + return side + end + return CustomMatchSummary._getOppositeSide(side:lower()) + end + ) + local firstSide = (firstSides.rt or '') + local firstSideOt = (firstSides.ot or '') + local oppositeSide = CustomMatchSummary._getOppositeSide(firstSide) + local oppositeSideOt = CustomMatchSummary._getOppositeSide(firstSideOt) + return { + {score = halves[firstSide], icon = ROUND_ICONS[firstSide]}, + {score = halves[oppositeSide], icon = ROUND_ICONS[oppositeSide]}, + {score = halves['ot' .. firstSideOt], icon = ROUND_ICONS['ot' .. firstSideOt]}, + {score = halves['ot' .. oppositeSideOt], icon = ROUND_ICONS['ot' .. oppositeSideOt]}, + } +end - local function makePartialScores(halves, firstSide, firstSideOt) - local oppositeSide = CustomMatchSummary._getOppositeSide(firstSide) - local oppositeSideOt = CustomMatchSummary._getOppositeSide(firstSideOt) - return { - {score = halves[firstSide], icon = ROUND_ICONS[firstSide]}, - {score = halves[oppositeSide], icon = ROUND_ICONS[oppositeSide]}, - {score = halves['ot' .. firstSideOt], icon = ROUND_ICONS['ot' .. firstSideOt]}, - {score = halves['ot' .. oppositeSideOt], icon = ROUND_ICONS['ot' .. oppositeSideOt]}, - } - end - - local firstSides = extradata.t1firstside or {} - local firstSide = (firstSides.rt or ''):lower() - local firstSideOt = (firstSides.ot or ''):lower() +---@param opponentIndex integer +---@return Widget +function RainbowsixMatchSummaryGameRow:createGameOpponentView(opponentIndex) + return MatchSummaryWidgets.DetailedScore{ + score = self:scoreDisplay(opponentIndex), + flipped = opponentIndex, + partialScores = self:_makePartialScores(opponentIndex) + } +end - return WidgetUtil.collect( - MatchSummaryWidgets.DetailedScore{ - score = self:scoreDisplay(1), - flipped = false, - partialScores = makePartialScores( - extradata.t1halfs or {}, - firstSide, - firstSideOt - ) - }, - self:mapDisplay(), - MatchSummaryWidgets.DetailedScore{ - score = self:scoreDisplay(2), - flipped = true, - partialScores = makePartialScores( - extradata.t2halfs or {}, - CustomMatchSummary._getOppositeSide(firstSide), - CustomMatchSummary._getOppositeSide(firstSideOt) - ) - } - ) +---@return string +function RainbowsixMatchSummaryGameRow:createGameOverview() + return self:mapDisplay() end ---@param side string diff --git a/lua/wikis/valorant/MatchSummary.lua b/lua/wikis/valorant/MatchSummary.lua index 8c808bbd80d..123e41d6172 100644 --- a/lua/wikis/valorant/MatchSummary.lua +++ b/lua/wikis/valorant/MatchSummary.lua @@ -49,45 +49,44 @@ function CustomMatchSummary.createBody(match) ) end ----@return Widget[] -function ValorantMatchSummaryGameRow:createGameDetail() - local game = self.props.game - - local function makePartialScores(halves, firstSide) - local oppositeSide = CustomMatchSummary._getOppositeSide(firstSide) - return { - {style = 'brkts-valorant-score-color-' .. firstSide, score = halves[firstSide]}, - {style = 'brkts-valorant-score-color-' .. oppositeSide, score = halves[oppositeSide]}, - {style = 'brkts-valorant-score-color-' .. firstSide, score = halves['ot' .. firstSide]}, - {style = 'brkts-valorant-score-color-' .. oppositeSide, score = halves['ot' .. oppositeSide]}, - } - end +---@return string +function ValorantMatchSummaryGameRow:createGameOverview() + return self:mapDisplay() +end +---@private +---@param opponentIndex integer +---@return table[] +function ValorantMatchSummaryGameRow:_makePartialScores(opponentIndex) + local game = self.props.game local extradata = game.extradata or {} - - ---@param opponentIndex integer - ---@return Widget[] - local function makeTeamSection(opponentIndex) - local flipped = opponentIndex == 2 - local firstSide = flipped and CustomMatchSummary._getOppositeSide(extradata.t1firstside) or extradata.t1firstside - local characters = Array.map((game.opponents[opponentIndex] or {}).players or {}, Operator.property('agent')) - return { - MatchSummaryWidgets.Characters{characters = characters, flipped = flipped, hideOnMobile = true}, - MatchSummaryWidgets.DetailedScore{ - score = self:scoreDisplay(opponentIndex), - flipped = flipped, - partialScores = makePartialScores( - extradata['t' .. opponentIndex .. 'halfs'] or {}, - firstSide or '' - ) - } - } + local firstSide = extradata.t1firstside + local oppositeSide = CustomMatchSummary._getOppositeSide(firstSide) + local halves = extradata['t' .. opponentIndex .. 'halfs'] or {} + if opponentIndex == 2 then + firstSide, oppositeSide = oppositeSide, firstSide end + return { + {style = 'brkts-valorant-score-color-' .. firstSide, score = halves[firstSide]}, + {style = 'brkts-valorant-score-color-' .. oppositeSide, score = halves[oppositeSide]}, + {style = 'brkts-valorant-score-color-' .. firstSide, score = halves['ot' .. firstSide]}, + {style = 'brkts-valorant-score-color-' .. oppositeSide, score = halves['ot' .. oppositeSide]}, + } +end +---@param opponentIndex integer +---@return Widget[] +function ValorantMatchSummaryGameRow:createGameOpponentView(opponentIndex) + local game = self.props.game + local flipped = opponentIndex == 2 + local characters = Array.map((game.opponents[opponentIndex] or {}).players or {}, Operator.property('agent')) return { - MatchSummaryWidgets.GameTeamWrapper{children = makeTeamSection(1)}, - self:mapDisplay(), - MatchSummaryWidgets.GameTeamWrapper{children = makeTeamSection(2), flipped = true} + MatchSummaryWidgets.Characters{characters = characters, flipped = flipped, hideOnMobile = true}, + MatchSummaryWidgets.DetailedScore{ + score = self:scoreDisplay(opponentIndex), + flipped = flipped, + partialScores = self:_makePartialScores(opponentIndex) + } } end diff --git a/stylesheets/commons/Brackets.scss b/stylesheets/commons/Brackets.scss index 2c879343b62..3c548233a96 100644 --- a/stylesheets/commons/Brackets.scss +++ b/stylesheets/commons/Brackets.scss @@ -640,14 +640,10 @@ div.brkts-popup-body-element-thumbs { .brkts-popup-body-grid { display: grid; - grid-template-columns: min-content auto min-content; + grid-template-columns: min-content 1fr auto 1fr min-content; align-items: center; margin: 0 -0.5rem; - &[ data-grid-layout="standard" ] { - grid-template-columns: min-content 1fr auto 1fr min-content; - } - &-row { display: grid; grid-column: 1 / -1; @@ -673,8 +669,14 @@ div.brkts-popup-body-element-thumbs { display: contents; white-space: nowrap; - > :only-child { - grid-column: 2 / -2; + > .brkts-popup-spaced:nth-of-type( 1 ) { + flex-direction: row; + justify-content: flex-start; + } + + > .brkts-popup-spaced:nth-last-of-type( 1 ) { + flex-direction: row-reverse; + justify-content: flex-start; } &:empty { From aba09bf08b7e6a07df290bded4c6471b63f82b94 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Wed, 25 Mar 2026 09:32:07 +0900 Subject: [PATCH 20/28] some finishing touches --- lua/wikis/rainbowsix/MatchSummary.lua | 2 +- lua/wikis/valorant/MatchSummary.lua | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lua/wikis/rainbowsix/MatchSummary.lua b/lua/wikis/rainbowsix/MatchSummary.lua index e37adbd6956..d85d830a4d5 100644 --- a/lua/wikis/rainbowsix/MatchSummary.lua +++ b/lua/wikis/rainbowsix/MatchSummary.lua @@ -113,7 +113,7 @@ end function RainbowsixMatchSummaryGameRow:createGameOpponentView(opponentIndex) return MatchSummaryWidgets.DetailedScore{ score = self:scoreDisplay(opponentIndex), - flipped = opponentIndex, + flipped = opponentIndex == 2, partialScores = self:_makePartialScores(opponentIndex) } end diff --git a/lua/wikis/valorant/MatchSummary.lua b/lua/wikis/valorant/MatchSummary.lua index 123e41d6172..2c367cb0d60 100644 --- a/lua/wikis/valorant/MatchSummary.lua +++ b/lua/wikis/valorant/MatchSummary.lua @@ -60,7 +60,7 @@ end function ValorantMatchSummaryGameRow:_makePartialScores(opponentIndex) local game = self.props.game local extradata = game.extradata or {} - local firstSide = extradata.t1firstside + local firstSide = extradata.t1firstside or '' local oppositeSide = CustomMatchSummary._getOppositeSide(firstSide) local halves = extradata['t' .. opponentIndex .. 'halfs'] or {} if opponentIndex == 2 then @@ -93,7 +93,9 @@ end ---@param side string? ---@return string function CustomMatchSummary._getOppositeSide(side) - if side == 'atk' then + if Logic.isEmpty(side) then + return '' + elseif side == 'atk' then return 'def' end return 'atk' From 3ef790a44e41a6301a892f85acf53bdd8c4987ff Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Wed, 25 Mar 2026 09:35:25 +0900 Subject: [PATCH 21/28] code style --- lua/wikis/valorant/MatchSummary.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/lua/wikis/valorant/MatchSummary.lua b/lua/wikis/valorant/MatchSummary.lua index 2c367cb0d60..c424ea688cc 100644 --- a/lua/wikis/valorant/MatchSummary.lua +++ b/lua/wikis/valorant/MatchSummary.lua @@ -33,7 +33,6 @@ end ---@param match MatchGroupUtilMatch ---@return Widget[] function CustomMatchSummary.createBody(match) - return WidgetUtil.collect( MatchSummaryWidgets.GamesContainer{ gridLayout = 'standard', From fd6e0e421c52ff99f1b83c54be5e6473901aba7f Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Wed, 25 Mar 2026 09:41:25 +0900 Subject: [PATCH 22/28] kick unused attribute --- lua/wikis/commons/Widget/Match/Summary/GamesContainer.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/lua/wikis/commons/Widget/Match/Summary/GamesContainer.lua b/lua/wikis/commons/Widget/Match/Summary/GamesContainer.lua index f385e8348d8..bd1523ed339 100644 --- a/lua/wikis/commons/Widget/Match/Summary/GamesContainer.lua +++ b/lua/wikis/commons/Widget/Match/Summary/GamesContainer.lua @@ -23,7 +23,6 @@ function MatchSummaryGamesContainer:render() return end return HtmlWidgets.Div{ - attributes = Logic.isNotEmpty(self.props.gridLayout) and {['data-grid-layout'] = self.props.gridLayout} or nil, classes = {'brkts-popup-body-grid'}, css = self.props.css, children = self.props.children, From e65276eccc96834dc1166e7f912a5e2d62742b66 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Wed, 25 Mar 2026 16:48:26 +0900 Subject: [PATCH 23/28] new detailed score layout --- .../Widget/Match/Summary/DetailedScore.lua | 43 +++++++--------- stylesheets/commons/Brackets.scss | 50 ++++++++++++++----- 2 files changed, 55 insertions(+), 38 deletions(-) diff --git a/lua/wikis/commons/Widget/Match/Summary/DetailedScore.lua b/lua/wikis/commons/Widget/Match/Summary/DetailedScore.lua index 31eeab1ff72..5a3c26f8f5f 100644 --- a/lua/wikis/commons/Widget/Match/Summary/DetailedScore.lua +++ b/lua/wikis/commons/Widget/Match/Summary/DetailedScore.lua @@ -23,40 +23,31 @@ function MatchSummaryDetailedScore:render() local partialScores = Array.map(self.props.partialScores or {}, function(partialScore) local children = {partialScore.score or '', partialScore.icon} - local styles = Array.append({}, - 'brkts-popup-body-match-sidewins', + local styles = Array.extend( + 'brkts-popup-body-detailed-score', partialScore.style, - partialScore.icon and 'brkts-popup-body-match-sidewins-icon' or nil + partialScore.icon and 'brkts-popup-body-detailed-score-icon' or nil ) - return HtmlWidgets.Td{ + return HtmlWidgets.Span{ classes = styles, - children = flipped and Array.reverse(children) or children, + children = children, } end) return HtmlWidgets.Div{ - css = {['text-align'] = 'center', direction = flipped and 'rtl' or 'ltr'}, - children = HtmlWidgets.Table{ - css = {['line-height'] = '28px', float = flipped and 'right' or 'left'}, - children = { - HtmlWidgets.Tr{ - children = { - HtmlWidgets.Td{ - attributes = {rowspan = 2}, - css = {['font-size'] = '16px', width = '24px'}, - children = self.props.score - }, - unpack(Array.filter(partialScores, function(_, i) - return i % 2 == 1 - end)) - } - }, - HtmlWidgets.Tr{ - children = Array.filter(partialScores, function(_, i) - return i % 2 == 0 - end) - } + classes = { + 'brkts-popup-body-detailed-scores-container', + flipped and 'flipped' or nil, + }, + children = { + HtmlWidgets.Div{ + classes = {'brkts-popup-body-detailed-scores-main-score'}, + children = self.props.score + }, + HtmlWidgets.Div{ + classes = {'brkts-popup-body-detailed-scores'}, + children = partialScores } } } diff --git a/stylesheets/commons/Brackets.scss b/stylesheets/commons/Brackets.scss index 3c548233a96..37eaba4fcea 100644 --- a/stylesheets/commons/Brackets.scss +++ b/stylesheets/commons/Brackets.scss @@ -958,20 +958,46 @@ div.brkts-popup-body-element-thumbs { font-weight: bold; } -.brkts-popup-body-match-sidewins { - padding: 0 0 3px 3px; - line-height: 11px; - width: 10px; - font-weight: 800; +.brkts-popup-body-detailed-scores { + display: grid; + grid-template-rows: repeat( 2, 1fr ); + grid-auto-flow: column; + gap: 0.125rem; + align-items: center; - &-icon { - width: 24px; + &-container { + display: flex; + flex-direction: row; + gap: 0.25rem; + justify-content: center; + align-items: center; + text-align: center; - img { - [ data-darkreader-scheme="dark" ] &, - .theme--dark & { - filter: invert( 1 ); - } + &.flipped { + flex-direction: row-reverse; + } + + @at-root .brkts-popup-spaced > & { + display: contents; + } + } + + @at-root .flipped > & { + direction: rtl; + } + + &-main-score { + font-size: 1rem; + width: 1.5rem; + } + + .brkts-popup-body-detailed-score { + font-weight: bolder; + font-size: 0.6875rem; + line-height: 1; + + .theme--dark &-icon > img { + filter: invert( 1 ); } } } From 024aeda02dd3c464ce36f64862b17b927a0a8d25 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Thu, 26 Mar 2026 10:30:18 +0900 Subject: [PATCH 24/28] move flipping to stylesheets --- lua/wikis/rainbowsix/MatchSummary.lua | 1 - lua/wikis/valorant/MatchSummary.lua | 1 - stylesheets/commons/Brackets.scss | 5 +++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lua/wikis/rainbowsix/MatchSummary.lua b/lua/wikis/rainbowsix/MatchSummary.lua index d85d830a4d5..a0487864fce 100644 --- a/lua/wikis/rainbowsix/MatchSummary.lua +++ b/lua/wikis/rainbowsix/MatchSummary.lua @@ -113,7 +113,6 @@ end function RainbowsixMatchSummaryGameRow:createGameOpponentView(opponentIndex) return MatchSummaryWidgets.DetailedScore{ score = self:scoreDisplay(opponentIndex), - flipped = opponentIndex == 2, partialScores = self:_makePartialScores(opponentIndex) } end diff --git a/lua/wikis/valorant/MatchSummary.lua b/lua/wikis/valorant/MatchSummary.lua index c424ea688cc..3ba3cfb2c96 100644 --- a/lua/wikis/valorant/MatchSummary.lua +++ b/lua/wikis/valorant/MatchSummary.lua @@ -83,7 +83,6 @@ function ValorantMatchSummaryGameRow:createGameOpponentView(opponentIndex) MatchSummaryWidgets.Characters{characters = characters, flipped = flipped, hideOnMobile = true}, MatchSummaryWidgets.DetailedScore{ score = self:scoreDisplay(opponentIndex), - flipped = flipped, partialScores = self:_makePartialScores(opponentIndex) } } diff --git a/stylesheets/commons/Brackets.scss b/stylesheets/commons/Brackets.scss index 37eaba4fcea..f67c73538a6 100644 --- a/stylesheets/commons/Brackets.scss +++ b/stylesheets/commons/Brackets.scss @@ -977,12 +977,13 @@ div.brkts-popup-body-element-thumbs { flex-direction: row-reverse; } - @at-root .brkts-popup-spaced > & { + .brkts-popup-spaced > & { display: contents; } } - @at-root .flipped > & { + .flipped > &, + .brkts-popup-spaced:nth-last-of-type( 1 ) > & { direction: rtl; } From dd0c9239a857e90d6be795932ed569b6ae11cf9a Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Thu, 26 Mar 2026 10:36:04 +0900 Subject: [PATCH 25/28] adjust selector --- stylesheets/commons/Brackets.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stylesheets/commons/Brackets.scss b/stylesheets/commons/Brackets.scss index f67c73538a6..7641a434de1 100644 --- a/stylesheets/commons/Brackets.scss +++ b/stylesheets/commons/Brackets.scss @@ -983,7 +983,7 @@ div.brkts-popup-body-element-thumbs { } .flipped > &, - .brkts-popup-spaced:nth-last-of-type( 1 ) > & { + .brkts-popup-spaced:nth-last-of-type( 1 ) & { direction: rtl; } From 3366765e9ad22999f764079a941e1c1a04bf39d2 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Thu, 26 Mar 2026 10:41:53 +0900 Subject: [PATCH 26/28] adjust gap --- stylesheets/commons/Brackets.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stylesheets/commons/Brackets.scss b/stylesheets/commons/Brackets.scss index 7641a434de1..7d9711d5773 100644 --- a/stylesheets/commons/Brackets.scss +++ b/stylesheets/commons/Brackets.scss @@ -962,7 +962,7 @@ div.brkts-popup-body-element-thumbs { display: grid; grid-template-rows: repeat( 2, 1fr ); grid-auto-flow: column; - gap: 0.125rem; + gap: 0.125rem 0.1875rem; align-items: center; &-container { From b1214d28b1f430d94b4c71dc3d348889fa0e78ed Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Thu, 26 Mar 2026 11:42:23 +0900 Subject: [PATCH 27/28] adjust selector for flipping --- stylesheets/commons/Brackets.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stylesheets/commons/Brackets.scss b/stylesheets/commons/Brackets.scss index 7d9711d5773..c4f20b112a1 100644 --- a/stylesheets/commons/Brackets.scss +++ b/stylesheets/commons/Brackets.scss @@ -982,8 +982,8 @@ div.brkts-popup-body-element-thumbs { } } - .flipped > &, - .brkts-popup-spaced:nth-last-of-type( 1 ) & { + &-container.flipped > &, + .brkts-popup-body-grid-row-detail > .brkts-popup-spaced:nth-last-of-type( 1 ) &-container > & { direction: rtl; } From 6c6762bf7cb16bd70eeab9ad39283eb7eda55811 Mon Sep 17 00:00:00 2001 From: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> Date: Thu, 26 Mar 2026 18:27:58 +0900 Subject: [PATCH 28/28] use subgrid instead of contents --- stylesheets/commons/Brackets.scss | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/stylesheets/commons/Brackets.scss b/stylesheets/commons/Brackets.scss index c4f20b112a1..4c845b6306a 100644 --- a/stylesheets/commons/Brackets.scss +++ b/stylesheets/commons/Brackets.scss @@ -666,7 +666,9 @@ div.brkts-popup-body-element-thumbs { } &-detail { - display: contents; + display: grid; + grid-column: 2 / -2; + grid-template-columns: subgrid; white-space: nowrap; > .brkts-popup-spaced:nth-of-type( 1 ) { @@ -678,11 +680,6 @@ div.brkts-popup-body-element-thumbs { flex-direction: row-reverse; justify-content: flex-start; } - - &:empty { - display: block; - grid-column: 2 / -2; - } } } }