Skip to content
Open
6 changes: 4 additions & 2 deletions lua/wikis/commons/Bracket/Template.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
---
-- @Liquipedia
-- page=Module:Bracket/Template
Expand All @@ -18,6 +18,8 @@
local MatchGroupUtil = Lua.import('Module:MatchGroup/Util/Custom')
local Opponent = Lua.import('Module:Opponent')

local Html = Lua.import('Module:Widget/Html')

---@class BracketTemplateBracket
---@field bracketDatasById table<string,MatchGroupUtilBracketBracketData>
---@field rootMatchIds string[]
Expand Down Expand Up @@ -57,14 +59,14 @@
function BracketTemplate.BracketContainer(props)
local matchRecords = MatchGroupUtil.fetchMatchRecords(props.bracketId)
Array.forEach(matchRecords, function(match)
match.match2opponents = {{type = Opponent.literal, name = '', match2players = {}}}
match.match2opponents = {Opponent.blank(Opponent.literal)}
end)
local bracket = MatchGroupUtil.makeMatchGroup(matchRecords) --[[@as MatchGroupUtilBracket]]

return BracketDisplay.Bracket({
bracket = bracket,
config = Table.merge(props.config, {
OpponentEntry = function() return mw.html.create('div'):addClass('brkts-opponent-entry') end,
OpponentEntry = function() return Html.Div{classes = {'brkts-opponent-entry'}} end,
Comment thread
ElectricalBoy marked this conversation as resolved.
matchHasDetails = function() return false end,
})
})
Expand Down
50 changes: 13 additions & 37 deletions lua/wikis/commons/MatchGroup/Display/Bracket.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
---
-- @Liquipedia
-- page=Module:MatchGroup/Display/Bracket
Expand All @@ -20,16 +20,16 @@
local WikiSpecific = Lua.import('Module:Brkts/WikiSpecific')

local Opponent = Lua.import('Module:Opponent/Custom')
local OpponentDisplay = Lua.import('Module:OpponentDisplay/Custom')

local BracketOpponentEntry = Lua.import('Module:Widget/Match/Bracket/OpponentEntry')
local MatchInfoIcon = Lua.import('Module:Widget/Match/InfoIcon')

local NON_BREAKING_SPACE = '&nbsp;'
local OPPONENT_HEIGHT_PADDING = 4

---@class BracketConfigOptions
---@field MatchSummaryContainer function?
---@field OpponentEntry function?
---@field OpponentEntry Component<BracketOpponentEntryProps>?
---@field forceShortName boolean?
---@field headerHeight number?
---@field headerMargin number?
Expand Down Expand Up @@ -65,7 +65,7 @@
---@field matchesById table<string, MatchGroupUtilMatch>

---@class BracketDisplayMatchProps
---@field OpponentEntry function
---@field OpponentEntry Component<BracketOpponentEntryProps>
---@field MatchSummaryContainer function
---@field match MatchGroupUtilMatch
---@field forceShortName boolean
Expand Down Expand Up @@ -119,7 +119,7 @@
local propsConfig = props.config or {}
local config = {
MatchSummaryContainer = propsConfig.MatchSummaryContainer or DisplayHelper.DefaultMatchSummaryContainer,
OpponentEntry = propsConfig.OpponentEntry or BracketDisplay.OpponentEntry,
OpponentEntry = propsConfig.OpponentEntry or BracketOpponentEntry,
forceShortName = propsConfig.forceShortName or defaultConfig.forceShortName,
headerHeight = propsConfig.headerHeight or defaultConfig.headerHeight,
headerMargin = propsConfig.headerMargin or defaultConfig.headerMargin,
Expand Down Expand Up @@ -540,11 +540,11 @@
type = 'literal',
name = match.bracketData.qualLoseLiteral or '',
})
qualLoseNode = BracketDisplay.Qualified({
qualLoseNode = BracketDisplay.Qualified{
OpponentEntry = config.OpponentEntry,
height = config.opponentHeight,
opponent = opponent,
})
}
:css('margin-top', config.matchMargin + 6 .. 'px')
:css('margin-bottom', config.matchMargin .. 'px')
end
Expand Down Expand Up @@ -573,15 +573,13 @@
local matchNode = mw.html.create('div'):addClass('brkts-match brkts-match-popup-wrapper')

for ix, opponent in ipairs(props.match.opponents) do
local opponentEntryNode = props.OpponentEntry({
local opponentEntryNode = props.OpponentEntry{
displayType = 'bracket',
forceShortName = props.forceShortName,
height = props.opponentHeight,
opponent = opponent,
})
:addClass(ix == #props.match.opponents and 'brkts-opponent-entry-last' or nil)
:css('height', props.opponentHeight .. 'px')
DisplayHelper.addOpponentHighlight(opponentEntryNode, opponent)
classes = ix == #props.match.opponents and {'brkts-opponent-entry-last'} or nil,
}
matchNode:node(opponentEntryNode)
end

Expand Down Expand Up @@ -610,17 +608,15 @@
end

---Display component for a qualification spot.
---@param props {OpponentEntry: function, height: number, opponent: standardOpponent}
---@param props {OpponentEntry: Component<BracketOpponentEntryProps>, height: number, opponent: standardOpponent}
---@return Html
function BracketDisplay.Qualified(props)
local opponentEntryNode = props.OpponentEntry({
local opponentEntryNode = props.OpponentEntry{
displayType = 'bracket-qualified',
height = props.height,
opponent = props.opponent,
})
:addClass('brkts-opponent-entry-last')
:css('height', props.height .. 'px')
DisplayHelper.addOpponentHighlight(opponentEntryNode, props.opponent)
classes = {'brkts-opponent-entry-last'},
}

return mw.html.create('div'):addClass('brkts-qualified')
:node(opponentEntryNode)
Expand Down Expand Up @@ -816,24 +812,4 @@
end
end

--[[
Display component for an opponent in a bracket match. Shows the name and flag
of the opponent, as well as the opponent's scores.

This is the default opponent entry component. Specific wikis may override this
by passing in a different props.OpponentEntry in the Bracket component.
]]
---@param props {opponent: standardOpponent, displayType: string, forceShortName: boolean?, height: number}
---@return Html
function BracketDisplay.OpponentEntry(props)
local opponentEntry = OpponentDisplay.BracketOpponentEntry(
props.opponent,
{forceShortName = props.forceShortName, showTbd = false}
)
if props.displayType == 'bracket' then
opponentEntry:addScores(props.opponent)
end
return opponentEntry.root
end

return BracketDisplay
16 changes: 16 additions & 0 deletions lua/wikis/commons/MatchGroup/Display/Helper.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
---
-- @Liquipedia
-- page=Module:MatchGroup/Display/Helper
Expand Down Expand Up @@ -42,6 +42,22 @@
:attr('aria-label', Opponent.toName(opponent))
end

---@param props HtmlNodeProps
---@param opponent standardOpponent
---@return HtmlNodeProps
function DisplayHelper.addOpponentHighlightToProps(props, opponent)
if Opponent.isTbd(opponent) then
return props
end
props.classes = props.classes or {}
table.insert(props.classes, 'brkts-opponent-hover')

props.attributes = props.attributes or {}
props.attributes['aria-label'] = Opponent.toName(opponent)

return props
end

-- Expands a header code by making a RPC call.
---@param headerCode string
---@return string[]
Expand Down
137 changes: 9 additions & 128 deletions lua/wikis/commons/OpponentDisplay.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
---
-- @Liquipedia
-- page=Module:OpponentDisplay
Expand All @@ -8,9 +8,7 @@
local Lua = require('Module:Lua')

local Array = Lua.import('Module:Array')
local Class = Lua.import('Module:Class')
local DisplayUtil = Lua.import('Module:DisplayUtil')
local Faction = Lua.import('Module:Faction')
local Logic = Lua.import('Module:Logic')
local Math = Lua.import('Module:MathUtil')
local Table = Lua.import('Module:Table')
Expand All @@ -19,7 +17,7 @@
local Opponent = Lua.import('Module:Opponent')
local PlayerDisplay = Lua.import('Module:Player/Display/Custom')

local HtmlWidgets = Lua.import('Module:Widget/Html/All')
local Html = Lua.import('Module:Widget/Html')
local BlockTeam = Lua.import('Module:Widget/TeamDisplay/Block')
local TeamInline = Lua.import('Module:Widget/TeamDisplay/Inline')

Expand All @@ -31,100 +29,6 @@
OpponentDisplay.types.TeamStyle = TypeUtil.literalUnion('standard', 'short', 'bracket', 'hybrid', 'icon', 'dynamic')
---@alias teamStyle 'standard'|'short'|'bracket'|'hybrid'|'icon'|'dynamic'

---Display component for an opponent entry appearing in a bracket match.
---@class BracketOpponentEntry
---@operator call(...): BracketOpponentEntry
---@field content Html
---@field root Html
OpponentDisplay.BracketOpponentEntry = Class.new(
---@param self self
---@param opponent standardOpponent
---@param options {forceShortName: boolean, showTbd: boolean}
function(self, opponent, options)
self.content = mw.html.create('div'):addClass('brkts-opponent-entry-left')

if opponent.type == Opponent.team then
if options.showTbd ~= false or not Opponent.isTbd(opponent) then
self:createTeam(opponent.template or 'tbd', options)
end
elseif Opponent.typeIsParty(opponent.type) then
self:createPlayers(opponent, options)
elseif opponent.type == Opponent.literal then
self:createLiteral(opponent.name or '')
end

self.root = mw.html.create('div'):addClass('brkts-opponent-entry')
:node(self.content)
end
)

---Creates team display as BracketOpponentEntry
---@param template string
---@param options {forceShortName: boolean}
function OpponentDisplay.BracketOpponentEntry:createTeam(template, options)
options = options or {}
local forceShortName = options.forceShortName

local opponentNode = OpponentDisplay.BlockTeamContainer{
showLink = false,
style = forceShortName and 'short' or 'dynamic',
template = template,
}

self.content:node(opponentNode)
end

---Creates party display as BracketOpponentEntry
---@param opponent standardOpponent
---@param options {showTbd: boolean?}
function OpponentDisplay.BracketOpponentEntry:createPlayers(opponent, options)
local playerNode = OpponentDisplay.BlockPlayers({
opponent = opponent,
overflow = 'ellipsis',
showLink = false,
showTbd = options.showTbd,
})
self.content:node(playerNode)

if opponent.type == Opponent.solo then
self.content:addClass(Faction.bgClass(opponent.players[1].faction))
end
end

---Creates literal display as BracketOpponentEntry
---@param name string
function OpponentDisplay.BracketOpponentEntry:createLiteral(name)
local literal = OpponentDisplay.BlockLiteral({
name = name,
overflow = 'ellipsis',
})
self.content:node(literal)
end

---Adds scores to BracketOpponentEntry
---@param opponent standardOpponent
function OpponentDisplay.BracketOpponentEntry:addScores(opponent)
local score1Node = OpponentDisplay.BracketScore({
isWinner = opponent.placement == 1 or opponent.advances,
scoreText = OpponentDisplay.InlineScore(opponent),
})
self.root:node(score1Node)

local score2Node
if opponent.score2 then
score2Node = OpponentDisplay.BracketScore({
isWinner = opponent.placement2 == 1,
scoreText = OpponentDisplay.InlineScore2(opponent),
})
end
self.root:node(score2Node)

if (opponent.placement2 or opponent.placement or 0) == 1
or opponent.advances then
self.content:addClass('brkts-opponent-win')
end
end

---@class InlineOpponentProps
---@field flip boolean?
---@field opponent standardOpponent
Expand Down Expand Up @@ -211,7 +115,7 @@

if opponent.type == Opponent.team then
if props.showTbd == false and Opponent.isTbd(opponent) then
return HtmlWidgets.Fragment{}
return Html.Fragment{}
end
return OpponentDisplay.BlockTeamContainer{
flip = props.flip,
Expand All @@ -237,9 +141,9 @@
end

---@param props BlockOpponentProps
---@return Widget
---@return VNode
function OpponentDisplay.BlockPlayers(props)
return HtmlWidgets.Div{
return Html.Div{
classes = Array.extend('block-players-wrapper', props.additionalClasses),
children = OpponentDisplay.getBlockPlayerNodes(props)
}
Expand Down Expand Up @@ -302,11 +206,11 @@

---Displays the name of a literal opponent as a block element.
---@param props {flip: boolean?, name: string, overflow: OverflowModes, additionalClasses: string[]?}
---@return Widget
---@return VNode
function OpponentDisplay.BlockLiteral(props)
DisplayUtil.assertPropTypes(props, OpponentDisplay.propTypes.BlockLiteral)

return HtmlWidgets.Div{
return Html.Div{
classes = Array.extend(
'brkts-opponent-block-literal',
props.flip and 'flipped' or nil,
Expand All @@ -325,15 +229,15 @@

---Displays a score within the context of a block element.
---@param props {isWinner: boolean?, scoreText: string|number?, additionalClasses: string[]?}
---@return Widget
---@return VNode
function OpponentDisplay.BlockScore(props)
DisplayUtil.assertPropTypes(props, OpponentDisplay.propTypes.BlockScore)

local scoreText = props.scoreText

return HtmlWidgets.Div{
return Html.Div{
classes = props.additionalClasses,
children = props.isWinner and HtmlWidgets.B{children = scoreText} or scoreText
children = props.isWinner and Html.B{children = scoreText} or scoreText
}
end

Expand Down Expand Up @@ -369,27 +273,4 @@
end
end

OpponentDisplay.propTypes.BracketScore = {
isWinner = 'boolean?',
scoreText = 'any',
}

---Displays a score within the context of a bracket opponent entry.
---@param props {isWinner: boolean?, scoreText: string|number?}
---@return Html
function OpponentDisplay.BracketScore(props)
DisplayUtil.assertPropTypes(props, OpponentDisplay.propTypes.BracketScore)

local scoreText = props.scoreText
if props.isWinner then
scoreText = '<b>' .. scoreText .. '</b>'
end

return mw.html.create('div'):addClass('brkts-opponent-score-outer')
:node(
mw.html.create('div'):addClass('brkts-opponent-score-inner')
:wikitext(scoreText)
)
end

return OpponentDisplay
Loading
Loading