Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(match2): Widgetify dota2's match summary #4914

Merged
merged 18 commits into from
Oct 22, 2024
Merged
12 changes: 9 additions & 3 deletions components/match2/commons/match_summary_base.lua
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ end
---@operator call: MatchSummaryMatch
---@field root Html
---@field headerElement Html?
---@field bodyElement Html?
---@field bodyElement Widget|Html?
---@field commentElement Html?
---@field footerElement Html?
local Match = Class.new(
Expand All @@ -391,10 +391,16 @@ function Match:header(header)
return self
end

---@param body MatchSummaryBody
---@param body MatchSummaryBody|Widget
---@return MatchSummaryMatch
function Match:body(body)
self.bodyElement = body:create()
if type(body.create) == 'function' then
---@cast body MatchSummaryBody
self.bodyElement = body:create()
else
---@cast body Widget
self.bodyElement = body
end
return self
end

Expand Down
20 changes: 17 additions & 3 deletions components/match2/wikis/dota2/match_group_input_custom.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ local Variables = require('Module:Variables')
local MatchGroupInputUtil = Lua.import('Module:MatchGroup/Input/Util')
local MatchGroupUtil = Lua.import('Module:MatchGroup/Util')

local OpponentLibraries = Lua.import('Module:OpponentLibraries')
local Opponent = OpponentLibraries.Opponent

local OPPONENT_CONFIG = {
resolveRedirect = true,
pagifyTeamNames = false,
Expand Down Expand Up @@ -81,7 +84,7 @@ function CustomMatchGroupInput.processMatchWithoutStandalone(MatchParser, match)
end)
local games = MatchFunctions.extractMaps(MatchParser, match, opponents)
match.bestof = MatchGroupInputUtil.getBestOf(match.bestof, games)
match.links = MatchFunctions.getLinks(match, games)
match.links = MatchFunctions.getLinks(match, games, opponents)

local autoScoreFunction = MatchGroupInputUtil.canUseAutoScore(match, games)
and MatchFunctions.calculateMatchScore(games)
Expand Down Expand Up @@ -176,8 +179,9 @@ end

---@param match table
---@param games table[]
---@param opponents table[]
---@return table
function MatchFunctions.getLinks(match, games)
function MatchFunctions.getLinks(match, games, opponents)
---@type table<string, string|table>
local links = MatchGroupInputUtil.getLinks(match)
links.stratz = {}
Expand All @@ -192,6 +196,17 @@ function MatchFunctions.getLinks(match, games)
links.datdota[mapIndex] = 'https://www.datdota.com/matches/' .. map.publisherid
end
)

local isTeamGame = Array.all(opponents, function(opponent)
return opponent.type == Opponent.team
end)
if Logic.readBool(Logic.emptyOr(match.headtohead, Variables.varDefault('headtohead'))) and isTeamGame then
local team1, team2 = string.gsub(opponents[1].name, ' ', '_'), string.gsub(opponents[2].name, ' ', '_')
links.headtohead = tostring(mw.uri.fullUrl('Special:RunQuery/Match_history')) ..
'?pfRunQueryFormName=Match+history&Head_to_head_query%5Bplayer%5D=' .. team1 ..
'&Head_to_head_query%5Bopponent%5D=' .. team2 .. '&wpRunQuery=Run+query'
end

return links
end

Expand All @@ -200,7 +215,6 @@ end
function MatchFunctions.getExtraData(match)
return {
mvp = MatchGroupInputUtil.readMvp(match),
headtohead = Logic.emptyOr(match.headtohead, Variables.varDefault('headtohead')),
casters = MatchGroupInputUtil.readCasters(match, {noSort = true}),
}
end
Expand Down
159 changes: 47 additions & 112 deletions components/match2/wikis/dota2/match_summary.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,21 @@

local CustomMatchSummary = {}

local Array = require('Module:Array')
local DateExt = require('Module:Date/Ext')
local Icon = require('Module:Icon')
local Logic = require('Module:Logic')
local Lua = require('Module:Lua')
local MatchLinks = mw.loadData('Module:MatchLinks')
local Table = require('Module:Table')

local DisplayHelper = Lua.import('Module:MatchGroup/Display/Helper')
local MatchPage = Lua.import('Module:MatchPage')
local MatchSummary = Lua.import('Module:MatchSummary/Base')
local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/All')
local Opponent = Lua.import('Module:Opponent')
local WidgetUtil = Lua.import('Module:Widget/Util')
local HtmlWidgets = Lua.import('Module:Widget/Html/All')

local MAX_NUM_BANS = 7
local NUM_HEROES_PICK = 5
local GREEN_CHECK = Icon.makeIcon{iconName = 'winner', color = 'forest-green-text', size = '110%'}
local NO_CHECK = '[[File:NoCheck.png|link=]]'

---@param args table
---@return Html
Expand All @@ -38,69 +36,35 @@ end
function CustomMatchSummary.addToFooter(match, footer)
footer = MatchSummary.addVodsToFooter(match, footer)

if
Logic.readBool(match.extradata.headtohead) and
match.opponents[1].type == Opponent.team and
match.opponents[2].type == Opponent.team
then
local team1, team2 = string.gsub(match.opponents[1].name, ' ', '_'), string.gsub(match.opponents[2].name, ' ', '_')
match.links.headtohead = tostring(mw.uri.fullUrl('Special:RunQuery/Match_history')) ..
'?pfRunQueryFormName=Match+history&Head_to_head_query%5Bplayer%5D=' .. team1 ..
'&Head_to_head_query%5Bopponent%5D=' .. team2 .. '&wpRunQuery=Run+query'
end

return footer:addLinks(MatchLinks, match.links)
end

---@param match MatchGroupUtilMatch
---@return MatchSummaryBody
function CustomMatchSummary.createBody(match)
local body = MatchSummary.Body()

if match.dateIsExact or match.timestamp ~= DateExt.defaultTimestamp then
-- dateIsExact means we have both date and time. Show countdown
-- if match is not default date, we have a date, so display the date
body:addRow(MatchSummary.Row():addElement(
DisplayHelper.MatchCountdownBlock(match)
))
end

if MatchPage.isEnabledFor(match) then
body.root:node(MatchSummaryWidgets.MatchPageLink{matchId = match.extradata.originalmatchid or match.matchId})
end

-- Iterate each map
for gameIndex, game in ipairs(match.games) do
local rowDisplay = CustomMatchSummary._createGame(game, gameIndex)
body:addRow(rowDisplay)
end

-- Add Match MVP(s)
if Table.isNotEmpty(match.extradata.mvp) then
body.root:node(MatchSummaryWidgets.Mvp{
players = match.extradata.mvp.players,
points = match.extradata.mvp.points,
})
end
-- Original Match Id must be used to match page links if it exists.
-- It can be different from the matchId when shortened brackets are used.
local matchId = match.extradata.originalmatchid or match.matchId

-- Add the Character Bans
local showCountdown = match.timestamp ~= DateExt.defaultTimestamp
local showMatchPage = MatchPage.isEnabledFor(match)
local characterBansData = MatchSummary.buildCharacterBanData(match.games, MAX_NUM_BANS)
body.root:node(MatchSummaryWidgets.CharacterBanTable{
bans = characterBansData,
date = match.date,
})

-- Casters
body:addRow(MatchSummary.makeCastersRow(match.extradata.casters))

return body
local casterRow = MatchSummary.makeCastersRow(match.extradata.casters)

return MatchSummaryWidgets.Body{children = WidgetUtil.collect(
showCountdown and MatchSummaryWidgets.Row{children = DisplayHelper.MatchCountdownBlock(match)} or nil,
showMatchPage and MatchSummaryWidgets.MatchPageLink{matchId = matchId} or nil,
unpack(Array.map(match.games, CustomMatchSummary._createGame)),
MatchSummaryWidgets.Mvp(match.extradata.mvp),
MatchSummaryWidgets.CharacterBanTable{bans = characterBansData, date = match.date},
casterRow and casterRow:create() or nil
)}
end

---@param game MatchGroupUtilGame
---@param gameIndex integer
---@return MatchSummaryRow
function CustomMatchSummary._createGame(game, gameIndex)
local row = MatchSummary.Row()
local extradata = game.extradata or {}

-- TODO: Change to use participant data
Expand All @@ -109,64 +73,35 @@ function CustomMatchSummary._createGame(game, gameIndex)
MatchSummary.buildCharacterList(extradata, 'team2hero', NUM_HEROES_PICK),
}

row:addClass('brkts-popup-body-game')
:css('font-size', '80%')
:css('padding', '4px')

row:addElement(MatchSummaryWidgets.Characters{
flipped = false,
characters = characterData[1],
bg = 'brkts-popup-side-color-' .. (extradata.team1side or ''),
})
row:addElement(CustomMatchSummary._createCheckMark(game.winner == 1))
row:addElement(mw.html.create('div')
:addClass('brkts-popup-body-element-vertical-centered')
:wikitext(CustomMatchSummary._createAbbreviation{
title = Logic.isEmpty(game.length) and ('Game ' .. gameIndex .. ' picks') or 'Match Length',
text = Logic.isEmpty(game.length) and ('Game ' .. gameIndex) or game.length,
})
)
row:addElement(CustomMatchSummary._createCheckMark(game.winner == 2))
row:addElement(MatchSummaryWidgets.Characters{
flipped = true,
characters = characterData[2],
bg = 'brkts-popup-side-color-' .. (extradata.team2side or ''),
})

-- Add Comment
if not Logic.isEmpty(game.comment) then
row:addElement(MatchSummary.Break():create())
local comment = mw.html.create('div')
comment:wikitext(game.comment)
:css('margin', 'auto')
row:addElement(comment)
end

return row
end

---@param isWinner boolean?
---@return Html
function CustomMatchSummary._createCheckMark(isWinner)
local container = mw.html.create('div')
:addClass('brkts-popup-spaced')
:css('line-height', '17px')
:css('margin-left', '1%')
:css('margin-right', '1%')

if Logic.readBool(isWinner) then
container:node(GREEN_CHECK)
else
container:node(NO_CHECK)
end

return container
end

---@param args table
---@return string
function CustomMatchSummary._createAbbreviation(args)
return '<i><abbr title="' .. args.title .. '">' .. args.text .. '</abbr></i>'
-- Map Comment
local comment = Logic.isNotEmpty(game.comment) and {
MatchSummaryWidgets.Break{},
HtmlWidgets.Div{css = {margin = 'auto'}, children = game.comment},
} or {}

return MatchSummaryWidgets.Row{
classes = {'brkts-popup-body-game'},
css = {['font-size'] = '80%', padding = '4px'},
children = {
MatchSummaryWidgets.Characters{
flipped = false,
characters = characterData[1],
bg = 'brkts-popup-side-color-' .. (extradata.team1side or ''),
},
MatchSummaryWidgets.GameWinLossIndicator{winner = game.winner, opponentIndex = 1},
HtmlWidgets.Div{
classes = {'brkts-popup-body-element-vertical-centered'},
children = {Logic.isNotEmpty(game.length) and game.length or ('Game ' .. gameIndex)},
},
MatchSummaryWidgets.GameWinLossIndicator{winner = game.winner, opponentIndex = 2},
MatchSummaryWidgets.Characters{
flipped = true,
characters = characterData[2],
bg = 'brkts-popup-side-color-' .. (extradata.team2side or ''),
},
unpack(comment)
}
}
end

return CustomMatchSummary
4 changes: 4 additions & 0 deletions components/widget/match/summary/widget_match_summary_all.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@ local Widgets = {}

local Lua = require('Module:Lua')

Widgets.Body = Lua.import('Module:Widget/Match/Summary/Body')
Widgets.Break = Lua.import('Module:Widget/Match/Summary/Break')
Widgets.CharacterBanTable = Lua.import('Module:Widget/Match/Summary/CharacterBanTable')
Widgets.Characters = Lua.import('Module:Widget/Match/Summary/Characters')
Widgets.Character = Lua.import('Module:Widget/Match/Summary/Character')
Widgets.GameWinLossIndicator = Lua.import('Module:Widget/Match/Summary/GameWinLossIndicator')
Widgets.MatchPageLink = Lua.import('Module:Widget/Match/Summary/MatchPageLink')
Widgets.Mvp = Lua.import('Module:Widget/Match/Summary/Mvp')
Widgets.Row = Lua.import('Module:Widget/Match/Summary/Row')

return Widgets
31 changes: 31 additions & 0 deletions components/widget/match/summary/widget_match_summary_body.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
-- @Liquipedia
-- wiki=commons
-- page=Module:Widget/Match/Summary/Body
--
-- Please see https://github.com/Liquipedia/Lua-Modules to contribute
--

local Class = require('Module:Class')
local Lua = require('Module:Lua')

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

---@class MatchSummaryBody: Widget
---@operator call(table): MatchSummaryBody
local MatchSummaryBody = Class.new(Widget)
MatchSummaryBody.defaultProps = {
classes = {},
}

---@return Widget
function MatchSummaryBody:render()
return Div{
classes = {'brkts-popup-body', unpack(self.props.classes)},
children = self.props.children,
}
end

return MatchSummaryBody
27 changes: 27 additions & 0 deletions components/widget/match/summary/widget_match_summary_break.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
-- @Liquipedia
-- wiki=commons
-- page=Module:Widget/Match/Summary/Break
--
-- Please see https://github.com/Liquipedia/Lua-Modules to contribute
--

local Class = require('Module:Class')
local Lua = require('Module:Lua')

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

---@class MatchSummaryBreak: Widget
---@operator call(table): MatchSummaryBreak
local MatchSummaryBreak = Class.new(Widget)

---@return Widget
function MatchSummaryBreak:render()
return Div{
classes = {'brkts-popup-break'},
}
end

return MatchSummaryBreak
Loading
Loading