Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions lua/wikis/commons/Bracket/Template.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ local MatchGroupCoordinates = Lua.import('Module:MatchGroup/Coordinates')
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 @@ end
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,
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
Expand Up @@ -20,16 +20,16 @@ local MatchGroupUtil = Lua.import('Module:MatchGroup/Util/Custom')
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 @@ local OPPONENT_HEIGHT_PADDING = 4
---@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 @@ function BracketDisplay.Bracket(props)
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 @@ function BracketDisplay.NodeBody(props)
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 @@ function BracketDisplay.Match(props)
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 @@ function BracketDisplay.Match(props)
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 @@ function BracketDisplay.getRunnerUpOpponent(match, bracketResetMatch)
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
Expand Up @@ -42,6 +42,22 @@ function DisplayHelper.addOpponentHighlight(node, opponent)
: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
Expand Up @@ -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 TypeUtil = Lua.import('Module:TypeUtil')
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 @@ local OpponentDisplay = {propTypes = {}, types = {}}
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 @@ function OpponentDisplay.BlockOpponent(props)

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 @@ function OpponentDisplay.BlockOpponent(props)
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 @@ OpponentDisplay.propTypes.BlockLiteral = {

---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 @@ OpponentDisplay.propTypes.BlockScore = {

---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 @@ function OpponentDisplay.InlineScore2(opponent)
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