diff --git a/lua/wikis/commons/HiddenDataBox.lua b/lua/wikis/commons/HiddenDataBox.lua
index 2054230a6aa..6a231531051 100644
--- a/lua/wikis/commons/HiddenDataBox.lua
+++ b/lua/wikis/commons/HiddenDataBox.lua
@@ -14,7 +14,6 @@ local Game = Lua.import('Module:Game')
local I18n = Lua.import('Module:I18n')
local Info = Lua.import('Module:Info', {loadData = true})
local MatchTicker = Lua.import('Module:MatchTicker')
-local MatchTickerEntityDisplay = Lua.import('Module:MatchTicker/DisplayComponents/Entity')
local Namespace = Lua.import('Module:Namespace')
local ReferenceCleaner = Lua.import('Module:ReferenceCleaner')
local String = Lua.import('Module:StringUtils')
@@ -229,7 +228,7 @@ function HiddenDataBox._matchTicker(supressMatchTicker)
return nil
end
- local result = Logic.tryCatch(
+ return Logic.tryCatch(
function()
local matchTicker = MatchTicker{
tournament = mw.title.getCurrentTitle().prefixedText,
@@ -238,23 +237,14 @@ function HiddenDataBox._matchTicker(supressMatchTicker)
ongoing = true,
hideTournament = true,
queryByParent = false,
+ entityStyle = true,
}
- matchTicker:query()
- return matchTicker
+ return matchTicker:query():create()
end,
function()
return nil
end
)
-
- if not result or not result.matches or #result.matches == 0 then
- return nil
- end
-
- return MatchTickerEntityDisplay.Container{
- config = result.config,
- matches = result.matches,
- }:create()
end
return Class.export(HiddenDataBox, {exports = {'run'}})
diff --git a/lua/wikis/commons/Infobox/League.lua b/lua/wikis/commons/Infobox/League.lua
index 6d81974b88c..d891cbc5b4b 100644
--- a/lua/wikis/commons/Infobox/League.lua
+++ b/lua/wikis/commons/Infobox/League.lua
@@ -355,7 +355,7 @@ function League:_createUpcomingMatches()
return nil
end
- local result = Logic.tryCatch(
+ return Logic.tryCatch(
function()
local matchTicker = MatchTicker{
tournament = self.pagename,
@@ -364,24 +364,14 @@ function League:_createUpcomingMatches()
ongoing = true,
hideTournament = true,
queryByParent = true,
+ entityStyle = true,
}
- matchTicker:query()
- return matchTicker
+ return matchTicker:query():create()
end,
function()
return nil
end
)
-
- if not result or not result.matches or #result.matches == 0 then
- return nil
- end
-
- local EntityDisplay = Lua.import('Module:MatchTicker/DisplayComponents/Entity')
- return EntityDisplay.Container{
- config = result.config,
- matches = result.matches,
- }:create()
end
---@param args table
diff --git a/lua/wikis/commons/Infobox/Person.lua b/lua/wikis/commons/Infobox/Person.lua
index bc3c370b7a1..5730bc24795 100644
--- a/lua/wikis/commons/Infobox/Person.lua
+++ b/lua/wikis/commons/Infobox/Person.lua
@@ -210,7 +210,7 @@ function Person:_createUpcomingMatches()
return nil
end
- local result = Logic.tryCatch(
+ return Logic.tryCatch(
function()
local matchTicker = MatchTicker{
player = self.pagename,
@@ -218,24 +218,14 @@ function Person:_createUpcomingMatches()
upcoming = true,
ongoing = true,
hideTournament = false,
+ entityStyle = true,
}
- matchTicker:query()
- return matchTicker
+ return matchTicker:query():create()
end,
function()
return nil
end
)
-
- if not result or not result.matches or #result.matches == 0 then
- return nil
- end
-
- local EntityDisplay = Lua.import('Module:MatchTicker/DisplayComponents/Entity')
- return EntityDisplay.Container{
- config = result.config,
- matches = result.matches,
- }:create()
end
function Person:_parseArgs()
diff --git a/lua/wikis/commons/Infobox/Team.lua b/lua/wikis/commons/Infobox/Team.lua
index d38395f05b8..53c6793059d 100644
--- a/lua/wikis/commons/Infobox/Team.lua
+++ b/lua/wikis/commons/Infobox/Team.lua
@@ -308,7 +308,7 @@ function Team:_createUpcomingMatches()
return nil
end
- local result = Logic.tryCatch(
+ return Logic.tryCatch(
function()
local matchTicker = MatchTicker{
team = self.pagename,
@@ -316,24 +316,14 @@ function Team:_createUpcomingMatches()
upcoming = true,
ongoing = true,
hideTournament = false,
+ entityStyle = true,
}
- matchTicker:query()
- return matchTicker
+ return matchTicker:query():create()
end,
function()
return nil
end
)
-
- if not result or not result.matches or #result.matches == 0 then
- return nil
- end
-
- local EntityDisplay = Lua.import('Module:MatchTicker/DisplayComponents/Entity')
- return EntityDisplay.Container{
- config = result.config,
- matches = result.matches,
- }:create()
end
---@param location string?
diff --git a/lua/wikis/commons/Infobox/UnofficialWorldChampion.lua b/lua/wikis/commons/Infobox/UnofficialWorldChampion.lua
index 1319654f174..c8a6243f999 100644
--- a/lua/wikis/commons/Infobox/UnofficialWorldChampion.lua
+++ b/lua/wikis/commons/Infobox/UnofficialWorldChampion.lua
@@ -214,7 +214,7 @@ function UnofficialWorldChampion:_createUpcomingMatches()
return nil
end
- local result = Logic.tryCatch(
+ return Logic.tryCatch(
function()
local matchTicker = MatchTicker{
team = currentChampion.template,
@@ -222,24 +222,14 @@ function UnofficialWorldChampion:_createUpcomingMatches()
upcoming = true,
ongoing = true,
hideTournament = false,
+ entityStyle = true,
}
- matchTicker:query()
- return matchTicker
+ return matchTicker:query():create()
end,
function()
return nil
end
)
-
- if not result or not result.matches or #result.matches == 0 then
- return nil
- end
-
- local EntityDisplay = Lua.import('Module:MatchTicker/DisplayComponents/Entity')
- return EntityDisplay.Container{
- config = result.config,
- matches = result.matches,
- }:create()
end
---@param args table
diff --git a/lua/wikis/commons/MatchTicker.lua b/lua/wikis/commons/MatchTicker.lua
index c5090e097a0..7910f2a4834 100644
--- a/lua/wikis/commons/MatchTicker.lua
+++ b/lua/wikis/commons/MatchTicker.lua
@@ -11,6 +11,7 @@ local Array = Lua.import('Module:Array')
local Class = Lua.import('Module:Class')
local FnUtil = Lua.import('Module:FnUtil')
local Game = Lua.import('Module:Game')
+local I18n = Lua.import('Module:I18n')
local Logic = Lua.import('Module:Logic')
local Lpdb = Lua.import('Module:Lpdb')
local Operator = Lua.import('Module:Operator')
@@ -24,6 +25,11 @@ local MatchUtil = Lua.import('Module:Match/Util')
local MatchGroupUtil = Lua.import('Module:MatchGroup/Util/Custom')
local Tournament = Lua.import('Module:Tournament')
+local Html = Lua.import('Module:Widget/Html')
+local MatchCard = Lua.import('Module:Widget/Match/Card')
+local Carousel = Lua.import('Module:Widget/Basic/Carousel')
+local Switch = Lua.import('Module:Widget/Switch')
+
local Condition = Lua.import('Module:Condition')
local ConditionTree = Condition.Tree
local ConditionNode = Condition.Node
@@ -63,36 +69,7 @@ local DEFAULT_LIMIT = 20
local DEFAULT_ORDER = 'date asc, liquipediatier asc, tournament asc'
local DEFAULT_RECENT_ORDER = 'date desc, liquipediatier asc, tournament asc'
local NOW = os.date('%Y-%m-%d %H:%M', os.time(os.date('!*t') --[[@as osdateparam]]))
-
----@class MatchTickerMatchInterface
----@operator call({config: MatchTickerConfig, match: table}): MatchTickerMatchInterface
----@field config MatchTickerConfig
----@field match table
----@field create fun(self: MatchTickerMatchInterface): Widget|Html?
-
----@class MatchTickerContainerInterface
----@operator call({config: MatchTickerConfig, matches: table[]}): MatchTickerContainerInterface
----@field config MatchTickerConfig
----@field matches table[]
----@field create fun(self: MatchTickerContainerInterface): Widget|Html?
-
---- Extract externally if it grows
----@param matchTickerConfig MatchTickerConfig
----@return {Container?: MatchTickerContainerInterface, Match: MatchTickerMatchInterface}
-local MatchTickerDisplayFactory = function (matchTickerConfig)
- assert(not (matchTickerConfig.entityStyle and matchTickerConfig.newStyle),
- "Invalid MatchTicker configuration: 'entityStyle' and 'newStyle' are mutually exclusive. " ..
- "Choose one display mode: use 'entityStyle' for carousel-based entity display, " ..
- "'newStyle' for new-style match cards, or neither for legacy display.")
-
- if matchTickerConfig.entityStyle then
- return Lua.import('Module:MatchTicker/DisplayComponents/Entity')
- elseif matchTickerConfig.newStyle then
- return Lua.import('Module:MatchTicker/DisplayComponents/New')
- else
- return Lua.import('Module:MatchTicker/DisplayComponents')
- end
-end
+local TABLE_OF_CONTENTS = '__TOC__'
---@class MatchTickerConfig
---@field tournaments string[]
@@ -117,8 +94,7 @@ end
---@field tierTypes string[]?
---@field regions string[]?
---@field games string[]?
----@field newStyle boolean?
----@field entityStyle boolean?
+---@field variant 'vertical' | 'horizontal'
---@field featuredOnly boolean?
---@field displayGameIcons boolean?
@@ -174,9 +150,9 @@ function MatchTicker:init(args)
games = args.games and Array.map(Array.parseCommaSeparatedString(args.games), function (game)
return Game.toIdentifier{game=game}
end) or nil,
- newStyle = Logic.readBool(args.newStyle),
featuredOnly = Logic.readBool(args.featuredOnly),
- displayGameIcons = Logic.readBool(args.displayGameIcons)
+ displayGameIcons = Logic.readBool(args.displayGameIcons),
+ variant = Logic.readBool(args.entityStyle) and 'horizontal' or 'vertical',
}
--min 1 of them has to be set; recent can not be set while any of the others is set
@@ -220,8 +196,6 @@ function MatchTicker:init(args)
end
config.wrapperClasses = wrapperClasses
- MatchTicker.DisplayComponents = MatchTickerDisplayFactory(config)
-
self.config = config
return self
@@ -565,43 +539,85 @@ MatchTicker.fetchTournament = FnUtil.memoize(function(tournamentPage)
return Tournament.getTournament(tournamentPage)
end)
----@param header MatchTickerHeader?
----@return Html
-function MatchTicker:create(header)
- if not self.matches and not self.config.showInfoForEmptyResults then
- return mw.html.create()
- end
-
- local wrapper = mw.html.create('div')
+local function HorizontalLayout(matchCards, config)
+ local carousel = Carousel{
+ children = matchCards,
+ itemWidth = '12.5rem',
+ gap = '0.5rem',
+ }
- for _, class in pairs(self.config.wrapperClasses) do
- wrapper:addClass(class)
- end
+ return Html.Div{
+ css = {['margin-bottom'] = '1rem'},
+ children = {
+ Html.Div{
+ classes = {'mw-heading', 'mw-heading2'},
+ children = {
+ Html.H2{
+ css = {border = 'unset'},
+ children = I18n.translate('matchticker-upcoming-matches'),
+ },
+ },
+ },
+ Switch{
+ label = 'Show countdown',
+ switchGroup = 'countdown',
+ storeValue = true,
+ defaultActive = true,
+ css = {margin = '0.75rem 0 1rem'},
+ content = carousel,
+ },
+ Html.Div{
+ css = {['margin-top'] = '1rem'},
+ children = {
+ TABLE_OF_CONTENTS,
+ },
+ },
+ },
+ }
+end
- if header then
- wrapper:node(header:create())
+---@param header Renderable?
+---@return Renderable?
+function MatchTicker:create(header)
+ if not self.matches and not self.config.showInfoForEmptyResults then
+ return
end
- if not self.matches then
- return wrapper:css('text-align', 'center'):wikitext('No Results found.')
+ if not self.matches or #self.matches == 0 then
+ return Html.Div{
+ classes = self.config.wrapperClasses,
+ css = {['text-align'] = 'center'},
+ children = Array.extend({header}, {'No Results found.'}),
+ }
end
- if MatchTicker.DisplayComponents.Container then
- local container = MatchTicker.DisplayComponents.Container{
- config = self.config,
- matches = self.matches
- }:create()
+ local matchCards = Array.map(self.matches, function(match)
+ return MatchCard{
+ match = MatchGroupUtil.matchFromRecord(match),
+ hideTournament = self.config.hideTournament,
+ displayGameIcons = self.config.displayGameIcons,
+ onlyHighlightOnValue = self.config.onlyHighlightOnValue,
+ variant = self.config.variant == 'horizontal' and 'vertical' or nil,
+ gameData = {
+ asGame = match.asGame,
+ gameIds = match.asGameIndexes,
+ map = match.map,
+ mapDisplayName = match.extradata and match.extradata.displayname or nil
+ }
+ }
+ end)
- if container then
- wrapper:node(container)
- end
- else
- Array.forEach(self.matches or {}, function(match)
- wrapper:node(MatchTicker.DisplayComponents.Match{config = self.config, match = match}:create())
- end)
+ if self.config.variant == 'vertical' then
+ return Html.Div{
+ classes = self.config.wrapperClasses,
+ children = Array.extend({header}, matchCards),
+ }
end
- return wrapper
+ return Html.Div{
+ classes = self.config.wrapperClasses,
+ children = Array.extend({header}, HorizontalLayout(matchCards, self.config)),
+ }
end
return MatchTicker
diff --git a/lua/wikis/commons/MatchTicker/Custom.lua b/lua/wikis/commons/MatchTicker/Custom.lua
index 562111bbae3..3522091e544 100644
--- a/lua/wikis/commons/MatchTicker/Custom.lua
+++ b/lua/wikis/commons/MatchTicker/Custom.lua
@@ -12,23 +12,15 @@ local Logic = Lua.import('Module:Logic')
local Table = Lua.import('Module:Table')
local MatchTicker = Lua.import('Module:MatchTicker')
+local InfoboxHeader = Lua.import('Module:Widget/Infobox/Header')
local CustomMatchTicker = {}
---Entry point for display on the main page
---@param frame Frame|table|nil
----@return Html
+---@return Renderable?
function CustomMatchTicker.mainPage(frame)
local args = Arguments.getArgs(frame)
- return MatchTicker(args):query():create()
-end
-
----Entry point for display on the main page with the new style
----@param frame Frame|table|nil
----@return Html?
-function CustomMatchTicker.newMainPage(frame)
- local args = Arguments.getArgs(frame)
- args.newStyle = true
args.tiers = args['filterbuttons-liquipediatier']
if args.tiers == 'curated' then
@@ -41,16 +33,16 @@ function CustomMatchTicker.newMainPage(frame)
args.games = args['filterbuttons-game']
if args.type == 'upcoming' then
- return MatchTicker(Table.merge(args, {ongoing = true, upcoming = true})):query():create():addClass('new-match-style')
+ return MatchTicker(Table.merge(args, {ongoing = true, upcoming = true})):query():create()
elseif args.type == 'recent' then
- return MatchTicker(Table.merge(args, {recent = true})):query():create():addClass('new-match-style')
+ return MatchTicker(Table.merge(args, {recent = true})):query():create()
end
end
---Entry point for display on player pages
---Upcoming and ongoing matches are now automatically displayed via the entity match ticker
---@param frame Frame|table|nil
----@return Html
+---@return Renderable?
function CustomMatchTicker.player(frame)
local args = Arguments.getArgs(frame)
args.player = args.player or mw.title.getCurrentTitle().text
@@ -60,7 +52,7 @@ end
---Displays recent matches for a player or team.
---@param args table
---@param matches {recent: table?}?
----@return Html
+---@return Renderable?
function CustomMatchTicker.recent(args, matches)
matches = matches or {}
@@ -70,16 +62,8 @@ function CustomMatchTicker.recent(args, matches)
args.limit = args.limit or args.recentLimit or 5
return MatchTicker(args):query(matches.recent):create(
- MatchTicker.DisplayComponents.Header('Recent Matches')
+ InfoboxHeader{name = 'Recent Matches', displayButtons = false}
)
end
----@deprecated Use CustomMatchTicker.recent() instead. This function only displays recent matches.
----@param args table
----@param matches {recent: table?}?
----@return Html
-function CustomMatchTicker.participant(args, matches)
- return CustomMatchTicker.recent(args, matches)
-end
-
return CustomMatchTicker
diff --git a/lua/wikis/commons/MatchTicker/DisplayComponents.lua b/lua/wikis/commons/MatchTicker/DisplayComponents.lua
deleted file mode 100644
index 869655bc2ab..00000000000
--- a/lua/wikis/commons/MatchTicker/DisplayComponents.lua
+++ /dev/null
@@ -1,473 +0,0 @@
----
--- @Liquipedia
--- page=Module:MatchTicker/DisplayComponents
---
--- Please see https://github.com/Liquipedia/Lua-Modules to contribute
---
-
--- Holds DisplayComponents for the MatchTicker module
-
-local Lua = require('Module:Lua')
-
-local Abbreviation = Lua.import('Module:Abbreviation')
-local Array = Lua.import('Module:Array')
-local Class = Lua.import('Module:Class')
-local Countdown = Lua.import('Module:Countdown')
-local DateExt = Lua.import('Module:Date/Ext')
-local I18n = Lua.import('Module:I18n')
-local Icon = Lua.import('Module:Icon')
-local LeagueIcon = Lua.import('Module:LeagueIcon')
-local Logic = Lua.import('Module:Logic')
-local Page = Lua.import('Module:Page')
-local Operator = Lua.import('Module:Operator')
-local String = Lua.import('Module:StringUtils')
-local Table = Lua.import('Module:Table')
-local Timezone = Lua.import('Module:Timezone')
-local VodLink = Lua.import('Module:VodLink')
-
-local HighlightConditions = Lua.import('Module:HighlightConditions')
-local DisplayHelper = Lua.import('Module:MatchGroup/Display/Helper')
-
-local Opponent = Lua.import('Module:Opponent/Custom')
-local OpponentDisplay = Lua.import('Module:OpponentDisplay/Custom')
-
-local VS = 'vs'
-local SCORE_STATUS = 'S'
-local CURRENT_PAGE = mw.title.getCurrentTitle().text
-local DEFAULT_BR_MATCH_TEXT = 'Unknown Round'
-local HIGHLIGHT_CLASS = 'tournament-highlighted-bg'
-local WINNER_TO_BG_CLASS = {
- [0] = 'recent-matches-draw',
- 'recent-matches-left',
- 'recent-matches-right',
-}
-local TOURNAMENT_DEFAULT_ICON = 'Generic_Tournament_icon.png'
-local NOW = os.date('%Y-%m-%d %H:%M', os.time(os.date('!*t') --[[@as osdateparam]]))
-local UTC = Timezone.getTimezoneString{timezone = 'UTC'}
-
----Display class for the header of a match ticker
----@class MatchTickerHeader
----@operator call(string|number|nil): MatchTickerHeader
----@field root Html
-local Header = Class.new(
- function(self, text)
- self.root = mw.html.create('div')
- :addClass('infobox-header')
- :wikitext(text)
- end
-)
-
----@param class string?
----@return MatchTickerHeader
-function Header:addClass(class)
- self.root:addClass(class)
- return self
-end
-
----@return Html
-function Header:create()
- return mw.html.create('div'):node(self.root)
-end
-
----Display class for matches shown within a match ticker
----@class MatchTickerVersus
----@operator call(table): MatchTickerVersus
----@field root Html
----@field match table
-local Versus = Class.new(
- function(self, match)
- self.root = mw.html.create('div')
- self.match = match
- end
-)
-
----@return Html
-function Versus:create()
- local bestof = self.match.asGame and self:gameTitle() or self:bestof()
- local scores, scores2 = self:scores()
- local upperText, lowerText
- if #self.match.opponents > 2 then
- -- brackets always have an inherited header matchlists might lack them,
- -- hence use matchIndex to generate a generic one for those cases
- local headerRaw = self.match.match2bracketdata.inheritedheader
- or ('Match ' .. self.match.match2bracketdata.matchIndex)
- upperText = DisplayHelper.expandHeader(headerRaw)[1]
- if self.match.asGame then
- upperText = upperText .. ' - ' .. self:gameTitle() .. self:mapTitle()
- end
- elseif String.isNotEmpty(scores2) then
- upperText = scores2
- lowerText = scores
- elseif bestof then
- upperText = scores or VS
- lowerText = bestof
- elseif scores then
- upperText = scores
- lowerText = VS
- end
- upperText = upperText or VS
-
- if not lowerText then
- return self.root:wikitext(upperText)
- end
-
- return self.root
- :node(mw.html.create('div')
- :addClass('versus-upper'):node(upperText)
- ):node(mw.html.create('div')
- :addClass('versus-lower'):wikitext('(' .. lowerText .. ')')
- )
-end
-
----@return string?
-function Versus:bestof()
- local bestof = tonumber(self.match.bestof) or 0
- if bestof > 0 then
- return Abbreviation.make{text = 'Bo' .. bestof, title = 'Best of ' .. bestof}
- end
-end
-
----@return string
-function Versus:gameTitle()
- if not self.match.asGameIndexes then
- return ''
- end
- return 'Game #' .. (table.concat(self.match.asGameIndexes, '-'))
-end
-
----@return string
-function Versus:mapTitle()
- local mapName = Logic.nilIfEmpty(self.match.map)
- if not mapName then
- return ''
- end
- return ' on ' .. mapName
-end
-
----@return string?
----@return string?
-function Versus:scores()
- if self.match.date > NOW then
- return
- end
-
- local winner = tonumber(self.match.winner)
-
- local scores, scores2 = {}, {}
- local hasSecondScore
- local delimiter = ':'
-
- local setWinner = function(score, opponentIndex)
- if winner == opponentIndex then
- return '' .. score .. ''
- end
- return score
- end
-
- Array.forEach(self.match.opponents or {}, function(opponent, opponentIndex)
- local score = Logic.isNotEmpty(opponent.status) and opponent.status ~= SCORE_STATUS and opponent.status
- or tonumber(opponent.score) or -1
-
- table.insert(scores, '' .. setWinner(score ~= -1 and score or 0, opponentIndex) .. '' )
-
- local score2 = tonumber((opponent.extradata or {}).score2) or 0
- table.insert(scores2, '' .. setWinner(score2, opponentIndex) .. '' )
- if score2 > 0 then
- hasSecondScore = true
- end
- end)
-
- if hasSecondScore then
- return table.concat(scores, delimiter), table.concat(scores2, delimiter)
- end
-
- return table.concat(scores, delimiter)
-end
-
----Display class for matches shown within a match ticker
----@class MatchTickerScoreBoard
----@operator call(table): MatchTickerScoreBoard
----@field root Html
----@field match table
-local ScoreBoard = Class.new(
- function(self, match)
- self.root = mw.html.create('tr')
- self.match = match
- end
-)
-
----@return Html
-function ScoreBoard:create()
- local match = self.match
- local winner = tonumber(match.winner)
-
- return self.root
- :node(self:opponent(match.opponents[1], winner == 1, true):addClass('team-left'))
- :node(self:versus())
- :node(self:opponent(match.opponents[2], winner == 2):addClass('team-right'))
-end
-
----@param opponent table
----@param isWinner boolean
----@param flip boolean?
----@return Html
-function ScoreBoard:opponent(opponent, isWinner, flip)
- if Opponent.isEmpty(opponent) or Opponent.isTbd(opponent) and opponent.type ~= Opponent.literal then
- opponent = Opponent.tbd(Opponent.literal)
- end
-
- local opponentName = Opponent.toName(opponent)
- if not opponentName then
- mw.logObject(opponent, 'Invalid Opponent, Opponent.toName returns nil')
- opponentName = ''
- end
-
- local opponentDispaly = mw.html.create('td')
- :node(OpponentDisplay.InlineOpponent{
- opponent = opponent,
- teamStyle = 'short',
- flip = flip,
- showLink = opponentName:gsub('_', ' ') ~= CURRENT_PAGE
- })
-
- if isWinner then
- opponentDispaly:css('font-weight', 'bold')
- end
-
- return opponentDispaly
-end
-
----@return Html
-function ScoreBoard:versus()
- return mw.html.create('td')
- :addClass('versus')
- :node(Versus(self.match):create())
-end
-
----Display class for matches shown within a match ticker
----@class MatchTickerDetails
----@operator call(table): MatchTickerDetails
----@field root Html
----@field hideTournament boolean
----@field isBrMatch boolean
----@field onlyHighlightOnValue string?
----@field match table
-local Details = Class.new(
- function(self, args)
- assert(args.match, 'No Match passed to MatchTickerDetails class')
- self.root = mw.html.create('tr')
- self.hideTournament = args.hideTournament
- self.isBrMatch = args.isBrMatch
- self.onlyHighlightOnValue = args.onlyHighlightOnValue
- self.match = args.match
- end
-)
-
----@return Html
-function Details:create()
- local matchPageIcon = self:_matchPageIcon()
- local td = mw.html.create('td')
- :addClass('match-filler')
- :node(mw.html.create('div')
- :addClass(matchPageIcon and 'has-matchpage' or nil)
- :node(self:countdown(matchPageIcon))
- :node(self:tournament())
- )
-
- if not self.isBrMatch then
- td:attr('colspan', 3)
- end
-
- local highlightCondition = HighlightConditions.match or HighlightConditions.tournament
-
- if highlightCondition(self.match, {onlyHighlightOnValue = self.onlyHighlightOnValue}) then
- self.root:addClass(HIGHLIGHT_CLASS)
- end
-
- return self.root:node(td)
-end
-
----@return string?
-function Details:_matchPageIcon()
- local matchPage = (self.match.match2bracketdata or {}).matchpage
- if Logic.isEmpty(matchPage) then return end
-
- local display = mw.html.create('div')
- :addClass('btn-secondary btn btn-extrasmall')
- :wikitext(Icon.makeIcon{iconName = 'matchpopup'})
-
- return Page.makeInternalLink(tostring(display), matchPage)
-end
-
----@param matchPageIcon string?
----@return Html
-function Details:countdown(matchPageIcon)
- local match = self.match
-
- local dateString
- if Logic.readBool(match.dateexact) then
- local timestamp = DateExt.readTimestamp(match.date) + (Timezone.getOffset{timezone = match.extradata.timezoneid} or 0)
- dateString = DateExt.formatTimestamp('F j, Y - H:i', timestamp) .. ' '
- .. (Timezone.getTimezoneString{timezone = match.extradata.timezoneid} or UTC)
- else
- dateString = mw.getContentLanguage():formatDate('F j, Y', match.date) .. UTC
- end
-
- local countdownArgs = Table.merge(match.stream or {}, {
- rawcountdown = not Logic.readBool(match.finished),
- rawdatetime = Logic.readBool(match.finished),
- date = dateString,
- finished = match.finished
- })
-
- local countdownDisplay = mw.html.create('span')
- :addClass('match-countdown')
- :node(Countdown.create(countdownArgs))
-
- if Logic.readBool(match.finished) then
- local function makeVod(vod, num)
- if Logic.isEmpty(vod) then
- return nil
- end
- return VodLink.display{
- vod = vod,
- gamenum = num,
- }
- end
-
- local gameVods = Array.map(Array.map(match.match2games or {}, Operator.property('vod')), makeVod)
-
- countdownDisplay:node(makeVod(match.vod))
- Array.forEach(gameVods, function(vod)
- countdownDisplay:node(vod)
- end)
- end
-
- return mw.html.create('div')
- :addClass('match-countdown-wrapper')
- :node(countdownDisplay)
- :node(matchPageIcon)
-end
-
----@return Html?
-function Details:tournament()
- if self.hideTournament then
- return
- end
-
- local match = self.match
-
- local icon = LeagueIcon.display{
- icon = Logic.emptyOr(match.icon, TOURNAMENT_DEFAULT_ICON),
- iconDark = match.icondark,
- link = match.pagename,
- name = match.tournament,
- options = {noTemplate = true},
- }
-
- local displayName = Logic.emptyOr(
- match.tickername,
- match.tournament,
- match.parent:gsub('_', ' ')
- )
-
- return mw.html.create('div')
- :addClass('tournament-flex')
- :node(mw.html.create('div')
- :addClass('tournament-text-flex')
- :wikitext('[[' .. match.pagename .. '|' .. displayName .. ']]')
- )
- :node(mw.html.create('span')
- :node(icon)
- )
-end
-
----Display class for matches shown within a match ticker
----@class MatchTickerMatch: MatchTickerMatchInterface
----@operator call({config: MatchTickerConfig, match: table}): MatchTickerMatch
----@field root Html
-local Match = Class.new(
- function(self, args)
- self.root = mw.html.create('table')
- :addClass('wikitable wikitable-striped infobox_matches_content')
- self.config = args.config
- self.match = args.match
- end
-)
-
----@return Html
-function Match:create()
- local matchDisplay = mw.html.create('table')
- :addClass('wikitable wikitable-striped infobox_matches_content')
-
- local isBrMatch = #self.match.opponents ~= 2
- if isBrMatch then
- matchDisplay:node(self:brMatchRow())
- else
- matchDisplay
- :addClass(WINNER_TO_BG_CLASS[tonumber(self.match.winner)])
- :node(self:standardMatchRow())
- end
-
- matchDisplay:node(self:detailsRow(isBrMatch))
-
- return matchDisplay
-end
-
----@param inheritedHeader string?
----@return string?
-function Match:_expandHeader(inheritedHeader)
- if not inheritedHeader then
- return
- end
-
- local headerArray = mw.text.split(inheritedHeader, '!')
-
- local index = 1
- if String.isEmpty(headerArray[1]) then
- index = 2
- end
-
- local headerInput = 'brkts-header-' .. headerArray[index]
- local expandedHeader = I18n.translate('brkts-header-' .. headerArray[index], {round = headerArray[index + 1]})
- local failedExpandedHeader = '⧼' .. headerInput .. '⧽'
- if Logic.isEmpty(expandedHeader) or failedExpandedHeader == expandedHeader then
- return inheritedHeader
- end
-
- return expandedHeader
-end
-
----@return Html
-function Match:brMatchRow()
- local displayText = self:_expandHeader(self.match.match2bracketdata.inheritedheader)
- or self.match.match2bracketdata.sectionheader or DEFAULT_BR_MATCH_TEXT
-
- return mw.html.create('tr')
- :addClass('versus')
- :tag('td'):wikitext(displayText):done()
-end
-
----@return Html
-function Match:standardMatchRow()
- return ScoreBoard(self.match):create()
-end
-
----@param isBrMatch boolean
----@return Html
-function Match:detailsRow(isBrMatch)
- return Details{
- match = self.match,
- hideTournament = self.config.hideTournament,
- isBrMatch = isBrMatch,
- onlyHighlightOnValue = self.config.onlyHighlightOnValue
- }:create()
-end
-
-return {
- Header = Header,
- Match = Match,
- Details = Details,
- ScoreBoard = ScoreBoard,
- Versus = Versus,
-}
diff --git a/lua/wikis/commons/MatchTicker/DisplayComponents/Entity.lua b/lua/wikis/commons/MatchTicker/DisplayComponents/Entity.lua
deleted file mode 100644
index 2342b042762..00000000000
--- a/lua/wikis/commons/MatchTicker/DisplayComponents/Entity.lua
+++ /dev/null
@@ -1,104 +0,0 @@
----
--- @Liquipedia
--- page=Module:MatchTicker/DisplayComponents/Entity
---
--- Please see https://github.com/Liquipedia/Lua-Modules to contribute
---
-
-local Lua = require('Module:Lua')
-
-local Array = Lua.import('Module:Array')
-local Class = Lua.import('Module:Class')
-local I18n = Lua.import('Module:I18n')
-local MatchGroupUtil = Lua.import('Module:MatchGroup/Util/Custom')
-
-local Carousel = Lua.import('Module:Widget/Basic/Carousel')
-local HtmlWidgets = Lua.import('Module:Widget/Html/All')
-local MatchCard = Lua.import('Module:Widget/Match/Card')
-local Switch = Lua.import('Module:Widget/Switch')
-
-local TABLE_OF_CONTENTS = '__TOC__'
-
----@class EntityMatchTickerMatch: MatchTickerMatchInterface
----@operator call({config: MatchTickerConfig, match: table}): EntityMatchTickerMatch
-local MatchCardEntity = Class.new(
- function(self, args)
- self.config = args.config
- self.match = args.match
- end
-)
-
----@return Widget
-function MatchCardEntity:create()
- return MatchCard{
- match = MatchGroupUtil.matchFromRecord(self.match),
- hideTournament = self.config.hideTournament,
- displayGameIcons = self.config.displayGameIcons,
- onlyHighlightOnValue = self.config.onlyHighlightOnValue,
- variant = 'vertical',
- gameData = {
- asGame = self.match.asGame,
- gameIds = self.match.asGameIndexes,
- map = self.match.map,
- mapDisplayName = self.match.extradata and self.match.extradata.displayname
- }
- }
-end
-
----@class EntityMatchTickerContainer: MatchTickerContainerInterface
----@operator call({config: MatchTickerConfig, matches: table[]}): EntityMatchTickerContainer
-local Container = Class.new(
- function(self, args)
- self.config = args.config
- self.matches = args.matches
- end
-)
-
----@return Widget?
-function Container:create()
- if not self.matches or #self.matches == 0 then
- return nil
- end
-
- local carousel = Carousel{
- children = Array.map(self.matches, function(match)
- return MatchCardEntity{config = self.config, match = match}:create()
- end),
- itemWidth = '12.5rem',
- gap = '0.5rem',
- }
-
- return HtmlWidgets.Div{
- css = {['margin-bottom'] = '1rem'},
- children = {
- HtmlWidgets.Div{
- classes = {'mw-heading', 'mw-heading2'},
- children = {
- HtmlWidgets.H2{
- css = {border = 'unset'},
- children = I18n.translate('matchticker-upcoming-matches'),
- },
- },
- },
- Switch{
- label = 'Show countdown',
- switchGroup = 'countdown',
- storeValue = true,
- defaultActive = true,
- css = {margin = '0.75rem 0 1rem'},
- content = carousel,
- },
- HtmlWidgets.Div{
- css = {['margin-top'] = '1rem'},
- children = {
- TABLE_OF_CONTENTS,
- },
- },
- },
- }
-end
-
-return {
- Match = MatchCardEntity,
- Container = Container,
-}
diff --git a/lua/wikis/commons/MatchTicker/DisplayComponents/New.lua b/lua/wikis/commons/MatchTicker/DisplayComponents/New.lua
deleted file mode 100644
index ec953484cb4..00000000000
--- a/lua/wikis/commons/MatchTicker/DisplayComponents/New.lua
+++ /dev/null
@@ -1,43 +0,0 @@
----
--- @Liquipedia
--- page=Module:MatchTicker/DisplayComponents/New
---
--- Please see https://github.com/Liquipedia/Lua-Modules to contribute
---
-
-local Lua = require('Module:Lua')
-
-local Class = Lua.import('Module:Class')
-local MatchGroupUtil = Lua.import('Module:MatchGroup/Util/Custom')
-
-local MatchCard = Lua.import('Module:Widget/Match/Card')
-
----@class NewMatchTickerMatch: MatchTickerMatchInterface
----@operator call({config: MatchTickerConfig, match: table}): NewMatchTickerMatch
-local Match = Class.new(
- function(self, args)
- self.config = args.config
- self.match = args.match
- end
-)
-
----@return Widget
-function Match:create()
- return MatchCard{
- match = MatchGroupUtil.matchFromRecord(self.match),
- hideTournament = self.config.hideTournament,
- displayGameIcons = self.config.displayGameIcons,
- onlyHighlightOnValue = self.config.onlyHighlightOnValue,
- -- TODO: This is bad, and needs to be refactored, but it's not realistic right now, so works for now
- gameData = {
- asGame = self.match.asGame,
- gameIds = self.match.asGameIndexes,
- map = self.match.map,
- mapDisplayName = self.match.extradata.displayname
- }
- }
-end
-
-return {
- Match = Match,
-}
diff --git a/lua/wikis/commons/Widget/Infobox/Header.lua b/lua/wikis/commons/Widget/Infobox/Header.lua
index bb89a166491..9206e151ce0 100644
--- a/lua/wikis/commons/Widget/Infobox/Header.lua
+++ b/lua/wikis/commons/Widget/Infobox/Header.lua
@@ -24,10 +24,12 @@ local Link = Lua.import('Module:Widget/Basic/Link')
---@field imageText Renderable?
---@field name Renderable?
---@field subHeader Renderable?
+---@field displayButtons boolean?
local Header = {}
-Header.defaultProps = {
+local defaultProps = {
name = mw.title.getCurrentTitle().text,
+ displayButtons = true,
}
---@param props InfoboxHeaderProps
@@ -56,10 +58,10 @@ end
function Header._name(props)
return Div{children = {Div{
classes = {'infobox-header', 'wiki-backgroundcolor-light'},
- children = {
- Header._createInfoboxButtons(),
- props.name,
- }
+ children = WidgetUtil.collect(
+ Header._createInfoboxButtons(props),
+ props.name
+ )
}}}
end
@@ -138,8 +140,11 @@ function Header._makeSizedImage(imageName, size, mode)
}
end
----@return VNode
-function Header._createInfoboxButtons()
+---@return VNode?
+function Header._createInfoboxButtons(props)
+ if not props.displayButtons then
+ return
+ end
local rootFrame
local currentFrame = mw.getCurrentFrame()
while currentFrame ~= nil do
@@ -188,4 +193,4 @@ function Header._makeImageText(text)
return Div{classes = {'infobox-image-text'}, children = {text}}
end
-return Component.component(Header.render, Header.defaultProps)
+return Component.component(Header.render, defaultProps)
diff --git a/lua/wikis/commons/Widget/Match/Ticker/Container.lua b/lua/wikis/commons/Widget/Match/Ticker/Container.lua
index c6bd3614e0b..43a8dd2b7a3 100644
--- a/lua/wikis/commons/Widget/Match/Ticker/Container.lua
+++ b/lua/wikis/commons/Widget/Match/Ticker/Container.lua
@@ -26,7 +26,7 @@ local MatchTickerContainer = Class.new(Widget)
MatchTickerContainer.defaultProps = {
limit = 10,
module = 'MatchTicker/Custom',
- fn = 'newMainPage',
+ fn = 'mainPage',
}
---@return Widget