Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 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
10 changes: 8 additions & 2 deletions components/match_ticker/commons/match_ticker.lua
Comment thread
Rathoz marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ local NOW = os.date('%Y-%m-%d %H:%M', os.time(os.date('!*t') --[[@as osdateparam
---@field onlyHighlightOnValue string?
---@field tiers string[]?
---@field tierTypes string[]?
---@field newStyle boolean?

---@class MatchTicker
---@operator call(table): MatchTicker
Expand All @@ -88,8 +89,6 @@ local NOW = os.date('%Y-%m-%d %H:%M', os.time(os.date('!*t') --[[@as osdateparam
---@field matches table[]?
local MatchTicker = Class.new(function(self, args) self:init(args) end)

MatchTicker.DisplayComponents = Lua.import('Module:MatchTicker/DisplayComponents')

---@param args table?
---@return table
function MatchTicker:init(args)
Expand Down Expand Up @@ -124,6 +123,7 @@ function MatchTicker:init(args)
tierTypes = args.tiertypes and Array.filter(
Array.parseCommaSeparatedString(args.tiertypes), FnUtil.curry(Tier.isValid, 1)
) or nil,
newStyle = Logic.readBool(args.newStyle),
}

--min 1 of them has to be set; recent can not be set while any of the others is set
Expand Down Expand Up @@ -164,6 +164,12 @@ function MatchTicker:init(args)
end
config.wrapperClasses = wrapperClasses

if config.newStyle then
MatchTicker.DisplayComponents = Lua.import('Module:MatchTicker/DisplayComponents/New')
else
MatchTicker.DisplayComponents = Lua.import('Module:MatchTicker/DisplayComponents')
end

self.config = config

return self
Expand Down
9 changes: 9 additions & 0 deletions components/match_ticker/commons/match_ticker_custom.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ function CustomMatchTicker.mainPage(frame)
return MatchTicker(args):query():create()
end

---Entry point for display on the main page with the new style
---@param frame Frame?
---@return Html
function CustomMatchTicker.newMainPage(frame)
Comment thread
hjpalpha marked this conversation as resolved.
local args = Arguments.getArgs(frame)
args.newStyle = true
return MatchTicker(args):query():create():addClass('new-match-style')
end

---Entry point for display on player pages
---@param frame Frame?
---@return Html
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ function Versus:create()

return self.root
:node(mw.html.create('div')
:css('line-height', '1.1'):node(upperText or VS)
:addClass('versus-upper'):node(upperText or VS)
):node(mw.html.create('div')
:addClass('versus-lower'):wikitext('(' .. lowerText .. ')')
)
Expand All @@ -123,6 +123,7 @@ function Versus:scores()

local scores, scores2 = {}, {}
local hasSecondScore
local delimiter = '<span>:</span>'

local setWinner = function(score, opponentIndex)
if winner == opponentIndex then
Expand All @@ -135,7 +136,7 @@ function Versus:scores()
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))
table.insert(scores, '<span>' .. setWinner(score ~= -1 and score or 0, opponentIndex) .. '</span>' )

local score2 = tonumber((opponent.extradata or {}).score2) or 0
table.insert(scores2, setWinner(score2, opponentIndex))
Comment thread
Rathoz marked this conversation as resolved.
Outdated
Expand All @@ -145,10 +146,10 @@ function Versus:scores()
end)

if hasSecondScore then
return table.concat(scores, ':'), table.concat(scores2, ':')
return table.concat(scores, delimiter), table.concat(scores2, delimiter)
end

return table.concat(scores, ':')
return table.concat(scores, delimiter)
end

---Display class for matches shown within a match ticker
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
---
Comment thread
hjpalpha marked this conversation as resolved.
-- @Liquipedia
-- wiki=commons
-- page=Module:MatchTicker/DisplayComponents/New
--
-- Please see https://github.com/Liquipedia/Lua-Modules to contribute
--

-- Holds DisplayComponents for the MatchTicker module
-- It contains the new html structure intented to be use for the new Dota2 Main Page (for now)
-- Will most likely be expanded to other games in the future and other pages

local Class = require('Module:Class')
local Countdown = require('Module:Countdown')
local DateExt = require('Module:Date/Ext')
local LeagueIcon = require('Module:LeagueIcon')
local Logic = require('Module:Logic')
local Lua = require('Module:Lua')
local Table = require('Module:Table')
local Timezone = require('Module:Timezone')
local StreamLinks = require('Module:Links/Stream')
local Page = require('Module:Page')
local DefaultMatchTickerDisplayComponents = require('Module:MatchTicker/DisplayComponents')

local HighlightConditions = Lua.import('Module:HighlightConditions')

local OpponentLibraries = require('Module:OpponentLibraries')
local Opponent = OpponentLibraries.Opponent
local OpponentDisplay = OpponentLibraries.OpponentDisplay

local CURRENT_PAGE = mw.title.getCurrentTitle().text
local HIGHLIGHT_CLASS = 'tournament-highlighted-bg'
local TOURNAMENT_DEFAULT_ICON = 'Generic_Tournament_icon.png'

---Display class for matches shown within a match ticker
---@class NewMatchTickerScoreBoard
---@operator call(table): NewMatchTickerScoreBoard
---@field root Html
---@field match table
local ScoreBoard = Class.new(
function(self, match)
self.root = mw.html.create('div'):addClass('match-scoreboard')
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.match2opponents[1], winner == 1, true):addClass('team-left'))
:node(self:versus())
:node(self:opponent(match.match2opponents[2], winner == 2):addClass('team-right'))
end

---@param opponentData table
---@param isWinner boolean
---@param flip boolean?
---@return Html
function ScoreBoard:opponent(opponentData, isWinner, flip)
local opponent = Opponent.fromMatch2Record(opponentData)
---@cast opponent -nil
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 opponentDisplay = mw.html.create('div')
:node(OpponentDisplay.InlineOpponent{
opponent = opponent,
teamStyle = 'short',
flip = flip,
showLink = opponentName:gsub('_', ' ') ~= CURRENT_PAGE
})

if isWinner then
opponentDisplay:addClass('match-winner')
end

return opponentDisplay
end

---@return Html
function ScoreBoard:versus()
return mw.html.create('div')
:addClass('versus')
:node(DefaultMatchTickerDisplayComponents.Versus(self.match):create())
end

---Display class for the details of a match displayed at the bottom of a match ticker
---@class NewMatchTickerDetails
---@operator call(table): NewMatchTickerMatch
---@field root Html
---@field hideTournament 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('div'):addClass('match-details')
self.hideTournament = args.hideTournament
self.onlyHighlightOnValue = args.onlyHighlightOnValue
self.match = args.match
end
)

---@return Html
function Details:create()
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(self:streams())
:node(self:tournament())
:node(self:countdown())
end

---It will display both countdown and date of the match so the user can select which one to show
---@return Html
function Details:countdown()
local match = self.match

local dateString
if Logic.readBool(match.dateexact) then
local timestamp = DateExt.readTimestamp(match.date) + (Timezone.getOffset(match.extradata.timezoneid) or 0)
dateString = DateExt.formatTimestamp('F j, Y - H:i', timestamp) .. ' '
.. (Timezone.getTimezoneString(match.extradata.timezoneid) or (Timezone.getTimezoneString('UTC')))
else
dateString = mw.getContentLanguage():formatDate('F j, Y', match.date) .. (Timezone.getTimezoneString('UTC'))
Comment thread
Nadoxis marked this conversation as resolved.
end

local countdownArgs = {
date = dateString,
finished = match.finished
}

local countdownDisplay = mw.html.create('span')
:addClass('match-countdown')
:node(Countdown._create(countdownArgs))

return countdownDisplay
end

---@return Html?
function Details:streams()
local match = self.match
local links = mw.html.create('div')
:addClass('match-streams')

if Table.isNotEmpty(match.stream) then
local streams = {}

-- Standardize the stream data to always use the platform as key (because of the new format ex: twitch_en_2)
for rawHost, stream in pairs(match.stream) do
local streamParts = mw.text.split(rawHost, '_', true)
if #streamParts == 3 then
local key = StreamLinks.StreamKey(rawHost)
streams[key.platform] = stream
else
streams[rawHost] = stream
end
end

local streamLinks = ''

-- Iterate over the streams and create the different links
for platformName, targetStream in pairs(streams) do
local streamLink = mw.ext.StreamPage.resolve_stream(platformName, targetStream)

if streamLink then
-- Default values
local url = 'Special:Stream/' .. platformName .. '/' .. streamLink
local icon = '<i class="lp-icon lp-icon-21 lp-' .. platformName .. '"></i>'

-- TL.net specific
if platformName == 'stream' then
url = 'https://tl.net/video/streams/' .. streamLink
end

streamLinks = streamLinks .. '[[' .. url .. '|' .. icon .. ']]'
Comment thread
Nadoxis marked this conversation as resolved.
Outdated
end
end

links:wikitext(streamLinks)
Comment thread
Nadoxis marked this conversation as resolved.
Outdated
end

return links
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('match-tournament')
:node(mw.html.create('div')
:addClass('tournament-icon')
:node(mw.html.create('div')
:wikitext(icon)
)
)
:node(mw.html.create('div')
:addClass('tournament-text')
:wikitext(Page.makeInternalLink({}, displayName, match.pagename))
)

end

---Display class for matches shown within a match ticker
---@class NewMatchTickerMatch
---@operator call({config: MatchTickerConfig, match: table}): NewMatchTickerMatch
---@field root Html
---@field config MatchTickerConfig
---@field match table
local Match = Class.new(
function(self, args)
self.root = mw.html.create('div'):addClass('match')
self.config = args.config
self.match = args.match
end
)

---@return Html
function Match:create()
self.root:node(self:standardMatchRow())
self.root:node(self:detailsRow())

return self.root
end
Comment thread
Rathoz marked this conversation as resolved.

---@return Html
function Match:standardMatchRow()
return ScoreBoard(self.match):create()
end

---@return Html
function Match:detailsRow()
return Details{
match = self.match,
hideTournament = self.config.hideTournament,
onlyHighlightOnValue = self.config.onlyHighlightOnValue
}:create()
end

return {
Match = Match,
Details = Details,
ScoreBoard = ScoreBoard,
}
Loading