Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
5a7acab
use anyOf
ElectricalBoy Oct 11, 2025
05a6b9e
parseCommaSeparatedString
ElectricalBoy Oct 11, 2025
3836600
code conciseness
ElectricalBoy Oct 11, 2025
ec8d68c
remove redundant comma
ElectricalBoy Feb 26, 2026
e38deb9
commaSeparatedString
ElectricalBoy Feb 26, 2026
0394c4e
clean up condition building
ElectricalBoy Feb 26, 2026
b46c679
use MGUMatch for processing
ElectricalBoy Feb 26, 2026
f31dd48
type conciseness
ElectricalBoy Feb 26, 2026
302a8cd
type annotation
ElectricalBoy Feb 26, 2026
d4b5221
use standardOpponent
ElectricalBoy Feb 26, 2026
5224d1a
extract matchtable style to separate file
ElectricalBoy Feb 26, 2026
4a9a014
use new table
ElectricalBoy Feb 26, 2026
e9edeb6
use formatPercentage
ElectricalBoy Feb 26, 2026
cee0d63
isDefaultTimestamp
ElectricalBoy Feb 26, 2026
e005e8a
clean up stats
ElectricalBoy Feb 26, 2026
0fa7185
clean up build
ElectricalBoy Feb 26, 2026
f5e767c
update custom
ElectricalBoy Feb 26, 2026
9d10cc0
adjust access modifier
ElectricalBoy Feb 26, 2026
265d8dd
use html entity over code
ElectricalBoy Feb 26, 2026
cce5a9e
slice buildRows
ElectricalBoy Feb 26, 2026
3541efd
clean up GameTable
ElectricalBoy Feb 26, 2026
088e2be
type anno
ElectricalBoy Feb 26, 2026
0fc4eaf
use isMain
ElectricalBoy Feb 26, 2026
1601eea
rewrite charactergametable
ElectricalBoy Feb 26, 2026
5b1ed59
lint
ElectricalBoy Feb 26, 2026
e9c3f4e
adjust matchpage usage
ElectricalBoy Feb 27, 2026
7d1c08b
missing return
ElectricalBoy Feb 28, 2026
8dbb181
indentation
ElectricalBoy Feb 28, 2026
c6f04bd
add missing length display
ElectricalBoy Feb 28, 2026
bd8d2fe
restore notplayed filter
ElectricalBoy Feb 28, 2026
674b2c7
use compact date as default
ElectricalBoy Feb 28, 2026
22c21ee
make length sortable
ElectricalBoy Feb 28, 2026
8d016c3
add patch display
ElectricalBoy Feb 28, 2026
95134e6
adjust background setting
ElectricalBoy Feb 28, 2026
c098966
fix character table mode
ElectricalBoy Feb 28, 2026
c350ab3
adjust deadlock custom
ElectricalBoy Feb 28, 2026
e08559a
adjust dota2 custom
ElectricalBoy Feb 28, 2026
4186681
add character table custom to commons
ElectricalBoy Feb 28, 2026
825be25
type annotation
ElectricalBoy Feb 28, 2026
0902723
update val custom type annotations
ElectricalBoy Feb 28, 2026
80fef4e
organize imports
ElectricalBoy Feb 28, 2026
44687a0
type anno
ElectricalBoy Feb 28, 2026
f01ddda
update val custom impl
ElectricalBoy Feb 28, 2026
0aeeeb5
adjust column config
ElectricalBoy Feb 28, 2026
e3eb6d5
move date default to constructor
ElectricalBoy Feb 28, 2026
2749679
formatRounded
ElectricalBoy Feb 28, 2026
0712e9d
remove unused import
ElectricalBoy Feb 28, 2026
819c560
add hover support
ElectricalBoy Feb 28, 2026
f862710
short button in character table
ElectricalBoy Feb 28, 2026
c9a533b
grayscale for bans
ElectricalBoy Feb 28, 2026
8330acb
use mixin
ElectricalBoy Mar 1, 2026
3b3d8b1
remove unused args
ElectricalBoy Mar 1, 2026
b2fbf2f
cleanup
ElectricalBoy Mar 11, 2026
64be068
suppress sorting in matchpage
ElectricalBoy Mar 11, 2026
7fe90fe
remove row bg
ElectricalBoy Mar 11, 2026
303b2a4
use result indicator
ElectricalBoy Mar 12, 2026
492fee2
update valorant custom
ElectricalBoy Mar 12, 2026
2ceef6d
result indicator
ElectricalBoy Mar 12, 2026
156e45c
alignment
ElectricalBoy Mar 12, 2026
47b71ae
lint
ElectricalBoy Mar 12, 2026
5ba123d
use 'opponent' over 'participant'
ElectricalBoy Mar 12, 2026
f124b2b
max width for result indicator column
ElectricalBoy Mar 12, 2026
12fa36c
remove unused style
ElectricalBoy Mar 13, 2026
aee5c27
make participant header configurable
ElectricalBoy Mar 13, 2026
32e9183
add another result label for h2h mode
ElectricalBoy Mar 13, 2026
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
182 changes: 102 additions & 80 deletions lua/wikis/commons/GameTable.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,143 +9,165 @@ local Lua = require('Module:Lua')

local Array = Lua.import('Module:Array')
local Class = Lua.import('Module:Class')
local DateExt = Lua.import('Module:Date/Ext')
local Game = Lua.import('Module:Game')
local Logic = Lua.import('Module:Logic')
local Operator = Lua.import('Module:Operator')
local VodLink = Lua.import('Module:VodLink')

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

local NOT_PLAYED = 'notplayed'
local SCORE_CONCAT = ' : '
local HtmlWidgets = Lua.import('Module:Widget/Html/All')
local TableWidgets = Lua.import('Module:Widget/Table2/All')
local WinLossIndicator = Lua.import('Module:Widget/Match/Summary/GameWinLossIndicator')
local WidgetUtil = Lua.import('Module:Widget/Util')

---@class GameTableMatch: MatchTableMatch
---@field games match2game[]
local NOT_PLAYED = 'notplayed'
local SCORE_CONCAT = ' : '

---@class GameTable: MatchTable
---@field countGames number
---@operator call(table): GameTable
---@field countGames integer
local GameTable = Class.new(MatchTable, function (self)
self.countGames = 0
end)

---@param game match2game
---@return match2game?
function GameTable:gameFromRecord(game)
if self.countGames == self.config.limit then return nil end
if game.status == NOT_PLAYED or Logic.isEmpty(game.winner) then
return nil
end

return game
end

---@param record table
---@return GameTableMatch?
---@param record match2
---@return MatchTableMatch?
function GameTable:matchFromRecord(record)
if self.countGames == self.config.limit then return nil end
if self.countGames >= self.config.limit then return nil end
local matchRecord = MatchTable.matchFromRecord(self, record)
---@cast matchRecord GameTableMatch
if Logic.isEmpty(record.match2games) then
if not matchRecord then
return
elseif Logic.isEmpty(record.match2games) then
return nil
end

matchRecord.games = {}
--order games from last played to first
Array.forEach(Array.reverse(record.match2games), function (game)
local gameRecord = self:gameFromRecord(game)
if gameRecord then self.countGames = self.countGames + 1 end
table.insert(matchRecord.games, gameRecord)
matchRecord.games = Array.filter(matchRecord.games, function (game)
return self:filterGame(game)
end)

self.countGames = self.countGames + #matchRecord.games

return matchRecord
end

---@param game MatchGroupUtilGame
---@return boolean
function GameTable:filterGame(game)
return game.status ~= NOT_PLAYED and Logic.isNotEmpty(game.winner)
end

---@param vod string?
---@return Html?
---@return Widget?
function GameTable:_displayGameVod(vod)
if not self.config.showVod then return end

local vodNode = mw.html.create('td')
if Logic.isEmpty(vod) then
return vodNode:wikitext('')
if not self.config.showVod then
return
elseif Logic.isEmpty(vod) then
return TableWidgets.Cell{}
end
---@cast vod -nil
return vodNode:node(VodLink.display{vod = vod})
return TableWidgets.Cell{children = VodLink.display{vod = vod}}
end

---@param result MatchTableMatchResult
---@param game match2game
---@return Html?
---@param game MatchGroupUtilGame
---@return Widget[]
function GameTable:_displayGameScore(result, game)
local scores = Array.map(game.opponents, Operator.property('score'))
local toScore = function(opponentRecord)
local isWinner = opponentRecord.id == tonumber(game.winner)
local score = scores[opponentRecord.id] or (isWinner and 1) or 0
return mw.html.create(isWinner and 'b' or nil)
:wikitext(score)
local indexes = result.flipped and {2, 1} or {1, 2}

---@param opponentIndex integer
---@return Widget
local toScore = function(opponentIndex)
local isWinner = opponentIndex == tonumber(game.winner)
local score = scores[opponentIndex] or (isWinner and 1) or 0
return HtmlWidgets.Span{
css = {['font-weight'] = isWinner and 'bold' or nil},
children = score
}
end

return mw.html.create('td')
:addClass('match-table-score')
:node(toScore(result.opponent))
:node(SCORE_CONCAT)
:node(toScore(result.vs))
return {
TableWidgets.Cell{children = MatchTable.getResultIndicator(indexes[game.winner])},
TableWidgets.Cell{children = {
toScore(indexes[1]),
SCORE_CONCAT,
toScore(indexes[2]),
}},
self.config.showOpponent and TableWidgets.Cell{children = WinLossIndicator{
opponentIndex = indexes[2],
winner = game.winner,
}} or nil,
}
end

---@param game match2game
---@param game MatchGroupUtilGame
---@return Html?
function GameTable:_displayGameIconForGame(game)
if not self.config.displayGameIcons then return end

return mw.html.create('td')
:node(Game.icon{game = game.game})
return TableWidgets.Cell{
children = Game.icon{game = game.game}
}
end

---@param match GameTableMatch
---@param game match2game
---@return Html?
---@param match MatchTableMatch
---@param game MatchGroupUtilGame
---@return Widget|Widget[]?
function GameTable:displayGame(match, game)
if not self.config.showResult then
return
elseif Logic.isEmpty(match.result.vs) then
return self:nonStandardMatch(match)
end

return mw.html.create()
:node(self.config.showOpponent and self:_displayOpponent(match.result.opponent, true) or nil)
:node(self:_displayGameScore(match.result, game))
:node(self:_displayOpponent(match.result.vs):css('text-align', 'left'))
return WidgetUtil.collect(
self.config.showOpponent and self:_displayOpponent(match.result.opponent, true) or nil,
self:_displayGameScore(match.result, game),
self:_displayOpponent(match.result.vs)
)
end

---@param match GameTableMatch
---@param game match2game
---@return Html?
---@param match MatchTableMatch
---@param game MatchGroupUtilGame
---@return Widget
function GameTable:gameRow(match, game)
local winner = match.result.opponent.id == tonumber(game.winner) and 1 or 2

return mw.html.create('tr')
:addClass(self:_getBackgroundClass(winner))
:node(self:_displayDate(match))
:node(self:_displayTier(match))
:node(self:_displayType(match))
:node(self:_displayGameIconForGame(game))
:node(self:_displayIcon(match))
:node(self:_displayTournament(match))
:node(self:displayGame(match, game))
:node(self:_displayGameVod(game.vod))
:node(self:_displayMatchPage(match))
return TableWidgets.Row{
children = WidgetUtil.collect(
self:_displayDate(match),
self:displayTier(match),
self:_displayType(match),
self:_displayGameIconForGame(game),
self:_displayIcon(match),
self:_displayTournament(match),
self:displayGame(match, game),
self:_displayGameVod(game.vod),
self:_displayMatchPage(match)
)
}
end

---@param match GameTableMatch
---@return Html?
function GameTable:matchRow(match)
local display = mw.html.create()

Array.forEach(match.games, function(game)
display:node(self:gameRow(match, game))
---@return Widget[]
function GameTable:buildRows()
---@type Widget[]
local rows = {}

local currentYear = math.huge
Array.forEach(self.matches, function(match)
local year = DateExt.getYearOf(match.date)
if self.config.showYearHeaders and year ~= currentYear then
currentYear = year
table.insert(rows, self:_yearRow(year))
end
Array.extendWith(rows, Array.reverse(
Array.map(match.games, function (game)
return self:gameRow(match, game)
end)
))
end)

return display
return rows
end

return GameTable
Loading
Loading