From 741b34edbe71f734b394eecb2388dda47d4af669 Mon Sep 17 00:00:00 2001 From: Rikard Blixt Date: Mon, 2 Dec 2024 10:18:04 +0100 Subject: [PATCH] refactor(match2): standardize BR display further (#5151) * refactor(match2): standardize BR display further * fix deploy header --- .../match2/commons/match_summary_ffa.lua | 427 ++++++++++++++++++ .../match2/wikis/apexlegends/game_summary.lua | 189 +------- components/match2/wikis/pubg/game_summary.lua | 189 +------- .../match2/wikis/pubg/match_summary.lua | 272 +---------- .../match2/wikis/pubgmobile/game_summary.lua | 189 +------- .../match2/wikis/pubgmobile/match_summary.lua | 272 +---------- 6 files changed, 481 insertions(+), 1057 deletions(-) diff --git a/components/match2/commons/match_summary_ffa.lua b/components/match2/commons/match_summary_ffa.lua index 865d6538d0..9c901ce376 100644 --- a/components/match2/commons/match_summary_ffa.lua +++ b/components/match2/commons/match_summary_ffa.lua @@ -9,12 +9,288 @@ local Array = require('Module:Array') local Date = require('Module:Date/Ext') local FnUtil = require('Module:FnUtil') +local Lua = require('Module:Lua') local Table = require('Module:Table') local Timezone = require('Module:Timezone') local VodLink = require('Module:VodLink') +local OpponentLibraries = require('Module:OpponentLibraries') +local OpponentDisplay = OpponentLibraries.OpponentDisplay + +local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/Ffa/All') +local HtmlWidgets = Lua.import('Module:Widget/Html/All') +local IconWidget = Lua.import('Module:Widget/Image/Icon/Fontawesome') + local MatchSummaryFfa = {} +local PLACEMENT_BG = { + 'cell--gold', + 'cell--silver', + 'cell--bronze', + 'cell--copper', +} + +local STATUS_ICONS = { + -- Normal Status + up = 'standings_up', + stayup = 'standings_stayup', + stay = 'standings_stay', + staydown = 'standings_staydown', + down = 'standings_down', +} + +local MATCH_OVERVIEW_COLUMNS = { + { + class = 'cell--status', + show = function(match) + return Table.isNotEmpty(match.extradata.status) + end, + header = { + value = '', + }, + row = { + class = function (opponent) + return 'bg-' .. (opponent.advanceBg or '') + end, + value = function (opponent, idx) + if not STATUS_ICONS[opponent.placementStatus] then + return + end + return IconWidget{ + iconName = STATUS_ICONS[opponent.placementStatus], + } + end, + }, + }, + { + sortable = true, + sortType = 'rank', + class = 'cell--rank', + icon = 'rank', + header = { + value = 'Rank', + }, + sortVal = { + value = function (opponent, idx) + return opponent.placement ~= -1 and opponent.placement or idx + end, + }, + row = { + value = function (opponent, idx) + local place = opponent.placement ~= -1 and opponent.placement or idx + local placementDisplay = tostring(MatchSummaryWidgets.RankRange{rankStart = place}) + return HtmlWidgets.Fragment{children = { + MatchSummaryWidgets.Trophy{place = place, additionalClasses = {'panel-table__cell-icon'}}, + HtmlWidgets.Span{children = placementDisplay}, + }} + end, + }, + }, + { + sortable = true, + sortType = 'team', + class = 'cell--team', + icon = 'team', + header = { + value = 'Team', + }, + sortVal = { + value = function (opponent, idx) + return opponent.name + end, + }, + row = { + value = function (opponent, idx) + return OpponentDisplay.BlockOpponent{ + opponent = opponent, + showLink = true, + overflow = 'ellipsis', + teamStyle = 'hybrid', + } + end, + }, + }, + { + sortable = true, + sortType = 'total-points', + class = 'cell--total-points', + icon = 'points', + header = { + value = 'Total Points', + mobileValue = 'Pts.', + }, + sortVal = { + value = function (opponent, idx) + return OpponentDisplay.InlineScore(opponent) + end, + }, + row = { + value = function (opponent, idx) + return OpponentDisplay.InlineScore(opponent) + end, + }, + }, +} +local GAME_OVERVIEW_COLUMNS = { + { + class = 'panel-table__cell__game-placement', + icon = 'placement', + header = { + value = 'P', + }, + row = { + class = function (opponent) + return PLACEMENT_BG[opponent.placement] + end, + value = function (opponent) + local placementDisplay + if opponent.status and opponent.status ~= 'S' then + placementDisplay = '-' + else + placementDisplay = tostring(MatchSummaryWidgets.RankRange{rankStart = opponent.placement}) + end + return HtmlWidgets.Fragment{children = { + MatchSummaryWidgets.Trophy{place = opponent.placement, additionalClasses = {'panel-table__cell-icon'}}, + HtmlWidgets.Span{ + classes = {'panel-table__cell-game__text'}, + children = placementDisplay, + } + }} + end, + }, + }, + { + class = 'panel-table__cell__game-kills', + icon = 'kills', + header = { + value = 'K', + }, + row = { + value = function (opponent) + return opponent.scoreBreakdown.kills + end, + }, + }, +} + +local GAME_STANDINGS_COLUMNS = { + { + sortable = true, + sortType = 'rank', + class = 'cell--rank', + icon = 'rank', + header = { + value = 'Rank', + }, + sortVal = { + value = function (opponent, idx) + if opponent.placement == -1 or opponent.status ~= 'S' then + return idx + end + return opponent.placement + end, + }, + row = { + value = function (opponent, idx) + local place = opponent.placement ~= -1 and opponent.placement or idx + local placementDisplay + if opponent.status and opponent.status ~= 'S' then + placementDisplay = '-' + else + placementDisplay = tostring(MatchSummaryWidgets.RankRange{rankStart = place}) + end + return HtmlWidgets.Fragment{children = { + MatchSummaryWidgets.Trophy{place = place, additionalClasses = {'panel-table__cell-icon'}}, + HtmlWidgets.Span{children = placementDisplay}, + }} + end, + }, + }, + { + sortable = true, + sortType = 'team', + class = 'cell--team', + icon = 'team', + header = { + value = 'Team', + }, + sortVal = { + value = function (opponent, idx) + return opponent.name + end, + }, + row = { + value = function (opponent, idx) + return OpponentDisplay.BlockOpponent{ + opponent = opponent, + showLink = true, + overflow = 'ellipsis', + teamStyle = 'hybrid', + } + end, + }, + }, + { + sortable = true, + sortType = 'total-points', + class = 'cell--total-points', + icon = 'points', + header = { + value = 'Total Points', + mobileValue = 'Pts.', + }, + sortVal = { + value = function (opponent, idx) + return opponent.score + end, + }, + row = { + value = function (opponent, idx) + return opponent.score + end, + }, + }, + { + sortable = true, + sortType = 'placements', + class = 'cell--placements', + icon = 'placement', + header = { + value = 'Placement Points', + }, + sortVal = { + value = function (opponent, idx) + return opponent.scoreBreakdown.placePoints + end, + }, + row = { + value = function (opponent, idx) + return opponent.scoreBreakdown.placePoints + end, + }, + }, + { + sortable = true, + sortType = 'kills', + class = 'cell--kills', + icon = 'kills', + header = { + value = 'Kill Points', + }, + sortVal = { + value = function (opponent, idx) + return opponent.scoreBreakdown.killPoints + end, + }, + row = { + value = function (opponent, idx) + return opponent.scoreBreakdown.killPoints + end, + }, + }, +} + + ---Creates a countdown block for a given game ---Attaches any VODs of the game as well ---@param game table @@ -84,4 +360,155 @@ function MatchSummaryFfa.createScoringData(match) } end +---@param match table +---@return MatchSummaryFfaTable +function MatchSummaryFfa.standardMatch(match) + local rows = Array.map(match.opponents, function (opponent, index) + local children = Array.map(MATCH_OVERVIEW_COLUMNS, function(column) + if column.show and not column.show(match) then + return + end + return MatchSummaryWidgets.TableRowCell{ + class = (column.class or '') .. ' ' .. (column.row.class and column.row.class(opponent) or ''), + sortable = column.sortable, + sortType = column.sortType, + sortValue = column.sortVal and column.sortVal.value(opponent, index) or nil, + value = column.row.value(opponent, index), + } + end) + + local gameRowContainer = HtmlWidgets.Div{ + classes = {'panel-table__cell', 'cell--game-container'}, + attributes = { + ['data-js-battle-royale'] = 'game-container' + }, + children = Array.map(opponent.games, function(gameOpponent) + local gameRow = HtmlWidgets.Div{ + classes = {'panel-table__cell', 'cell--game'}, + children = Array.map(GAME_OVERVIEW_COLUMNS, function(column) + if column.show and not column.show(match) then + return + end + return MatchSummaryWidgets.TableRowCell{ + class = (column.class or '') .. ' ' .. (column.row.class and column.row.class(gameOpponent) or ''), + value = column.row.value(gameOpponent), + } + end) + } + return gameRow + end) + } + table.insert(children, gameRowContainer) + return MatchSummaryWidgets.TableRow{children = children} + end) + + local cells = Array.map(MATCH_OVERVIEW_COLUMNS, function(column) + if column.show and not column.show(match) then + return + end + return MatchSummaryWidgets.TableHeaderCell{ + class = column.class, + icon = column.icon, + mobileValue = column.header.mobileValue, + show = column.show, + sortable = column.sortable, + sortType = column.sortType, + value = column.header.value, + } + end) + + table.insert(cells, HtmlWidgets.Div{ + classes = {'panel-table__cell', 'cell--game-container-nav-holder'}, + attributes = { + ['data-js-battle-royale'] = 'game-nav-holder' + }, + children = { + HtmlWidgets.Div{ + classes = {'panel-table__cell', 'cell--game-container'}, + attributes = { + ['data-js-battle-royale'] = 'game-container' + }, + children = Array.map(match.games, function(game, idx) + return HtmlWidgets.Div{ + classes = {'panel-table__cell', 'cell--game'}, + children = { + HtmlWidgets.Div{ + classes = {'panel-table__cell__game-head'}, + children = { + HtmlWidgets.Div{ + classes = {'panel-table__cell__game-title'}, + children = { + MatchSummaryWidgets.CountdownIcon{game = game, additionalClasses = {'panel-table__cell-icon'}}, + HtmlWidgets.Span{ + classes = {'panel-table__cell-text'}, + children = 'Game ' .. idx + } + } + }, + MatchSummaryFfa.gameCountdown(game), + } + }, + HtmlWidgets.Div{ + classes = {'panel-table__cell__game-details'}, + children = Array.map(GAME_OVERVIEW_COLUMNS, function(column) + return MatchSummaryWidgets.TableHeaderCell{ + class = column.class, + icon = column.icon, + mobileValue = column.header.mobileValue, + show = column.show, + value = column.header.value, + } + end) + } + } + } + end) + } + } + }) + + return MatchSummaryWidgets.Table{children = { + MatchSummaryWidgets.TableHeader{children = cells}, + unpack(rows) + }} +end + +---@param game table +---@return MatchSummaryFfaTable +function MatchSummaryFfa.standardGame(game) + local rows = Array.map(game.opponents, function (opponent, index) + local children = Array.map(GAME_STANDINGS_COLUMNS, function(column) + if column.show and not column.show(game) then + return + end + return MatchSummaryWidgets.TableRowCell{ + class = column.class, + sortable = column.sortable, + sortType = column.sortType, + sortValue = column.sortVal and column.sortVal.value(opponent, index) or nil, + value = column.row.value(opponent, index), + } + end) + return MatchSummaryWidgets.TableRow{children = children} + end) + + return MatchSummaryWidgets.Table{children = { + MatchSummaryWidgets.TableHeader{children = Array.map(GAME_STANDINGS_COLUMNS, function(column) + if column.show and not column.show(game) then + return + end + return MatchSummaryWidgets.TableHeaderCell{ + class = column.class, + icon = column.icon, + mobileValue = column.header.mobileValue, + sortable = column.sortable, + sortType = column.sortType, + value = column.header.value, + } + end)}, + unpack(rows) + }} +end + + return MatchSummaryFfa diff --git a/components/match2/wikis/apexlegends/game_summary.lua b/components/match2/wikis/apexlegends/game_summary.lua index ee90af6763..33e1a324ec 100644 --- a/components/match2/wikis/apexlegends/game_summary.lua +++ b/components/match2/wikis/apexlegends/game_summary.lua @@ -15,8 +15,6 @@ local Page = require('Module:Page') local Table = require('Module:Table') local MatchGroupUtil = Lua.import('Module:MatchGroup/Util') -local OpponentLibraries = require('Module:OpponentLibraries') -local OpponentDisplay = OpponentLibraries.OpponentDisplay local SummaryHelper = Lua.import('Module:MatchSummary/Ffa') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/Ffa/All') @@ -26,122 +24,6 @@ local IconWidget = Lua.import('Module:Widget/Image/Icon/Fontawesome') ---@class ApexMatchGroupUtilGame: MatchGroupUtilGame ---@field stream table -local GAME_STANDINGS_COLUMNS = { - { - sortable = true, - sortType = 'rank', - class = 'cell--rank', - icon = 'rank', - header = { - value = 'Rank', - }, - sortVal = { - value = function (opponent, idx) - if opponent.placement == -1 or opponent.status ~= 'S' then - return idx - end - return opponent.placement - end, - }, - row = { - value = function (opponent, idx) - local place = opponent.placement ~= -1 and opponent.placement or idx - local placementDisplay - if opponent.status and opponent.status ~= 'S' then - placementDisplay = '-' - else - placementDisplay = tostring(MatchSummaryWidgets.RankRange{rankStart = place}) - end - return HtmlWidgets.Fragment{children = { - MatchSummaryWidgets.Trophy{place = place, additionalClasses = {'panel-table__cell-icon'}}, - HtmlWidgets.Span{children = placementDisplay}, - }} - end, - }, - }, - { - sortable = true, - sortType = 'team', - class = 'cell--team', - icon = 'team', - header = { - value = 'Team', - }, - sortVal = { - value = function (opponent, idx) - return opponent.name - end, - }, - row = { - value = function (opponent, idx) - return OpponentDisplay.BlockOpponent{ - opponent = opponent, - showLink = true, - overflow = 'ellipsis', - teamStyle = 'hybrid', - } - end, - }, - }, - { - sortable = true, - sortType = 'total-points', - class = 'cell--total-points', - icon = 'points', - header = { - value = 'Total Points', - mobileValue = 'Pts.', - }, - sortVal = { - value = function (opponent, idx) - return opponent.score - end, - }, - row = { - value = function (opponent, idx) - return opponent.score - end, - }, - }, - { - sortable = true, - sortType = 'placements', - class = 'cell--placements', - icon = 'placement', - header = { - value = 'Placement Points', - }, - sortVal = { - value = function (opponent, idx) - return opponent.scoreBreakdown.placePoints - end, - }, - row = { - value = function (opponent, idx) - return opponent.scoreBreakdown.placePoints - end, - }, - }, - { - sortable = true, - sortType = 'kills', - class = 'cell--kills', - icon = 'kills', - header = { - value = 'Kill Points', - }, - sortVal = { - value = function (opponent, idx) - return opponent.scoreBreakdown.killPoints - end, - }, - row = { - value = function (opponent, idx) - return opponent.scoreBreakdown.killPoints - end, - }, - }, -} ---@param props {bracketId: string, matchId: string, gameIdx: integer} ---@return Html function CustomGameSummary.getGameByMatchId(props) @@ -153,7 +35,7 @@ function CustomGameSummary.getGameByMatchId(props) game.stream = match.stream - CustomGameSummary._opponents(match) + CustomGameSummary._opponents(game, match.opponents) local scoringData = SummaryHelper.createScoringData(match) return MatchSummaryWidgets.Tab{ @@ -162,7 +44,7 @@ function CustomGameSummary.getGameByMatchId(props) children = { CustomGameSummary._createGameDetails(game), MatchSummaryWidgets.PointsDistribution{killScore = scoringData.kill, placementScore = scoringData.placement}, - CustomGameSummary._createGameStandings(game) + SummaryHelper.standardGame(game) } } end @@ -193,62 +75,23 @@ function CustomGameSummary._createGameDetails(game) end ---@param game table ----@return Html -function CustomGameSummary._createGameStandings(game) - local rows = Array.map(game.opponents, function (opponent, index) - local children = Array.map(GAME_STANDINGS_COLUMNS, function(column) - if column.show and not column.show(game) then - return - end - return MatchSummaryWidgets.TableRowCell{ - class = column.class, - sortable = column.sortable, - sortType = column.sortType, - sortValue = column.sortVal and column.sortVal.value(opponent, index) or nil, - value = column.row.value(opponent, index), - } - end) - return MatchSummaryWidgets.TableRow{children = children} - end) - - return MatchSummaryWidgets.Table{children = { - MatchSummaryWidgets.TableHeader{children = Array.map(GAME_STANDINGS_COLUMNS, function(column) - if column.show and not column.show(game) then - return - end - return MatchSummaryWidgets.TableHeaderCell{ - class = column.class, - icon = column.icon, - mobileValue = column.header.mobileValue, - sortable = column.sortable, - sortType = column.sortType, - value = column.header.value, - } - end)}, - unpack(rows) - }} -end - -function CustomGameSummary._opponents(match) +---@param matchOpponents table[] +function CustomGameSummary._opponents(game, matchOpponents) -- Add match opponent data to game opponent - Array.forEach(match.games, function (game) - game.opponents = Array.map(game.opponents, - function(gameOpponent, opponentIdx) - local matchOpponent = match.opponents[opponentIdx] - local newGameOpponent = Table.merge(matchOpponent, gameOpponent) - -- These values are only allowed to come from Game and not Match - newGameOpponent.placement = gameOpponent.placement - newGameOpponent.score = gameOpponent.score - newGameOpponent.status = gameOpponent.status - return newGameOpponent - end - ) - end) + game.opponents = Array.map(game.opponents, + function(gameOpponent, opponentIdx) + local matchOpponent = matchOpponents[opponentIdx] + local newGameOpponent = Table.merge(matchOpponent, gameOpponent) + -- These values are only allowed to come from Game and not Match + newGameOpponent.placement = gameOpponent.placement + newGameOpponent.score = gameOpponent.score + newGameOpponent.status = gameOpponent.status + return newGameOpponent + end + ) -- Sort game level based on placement - Array.forEach(match.games, function (game) - Array.sortInPlaceBy(game.opponents, FnUtil.identity, SummaryHelper.placementSortFunction) - end) + Array.sortInPlaceBy(game.opponents, FnUtil.identity, SummaryHelper.placementSortFunction) end return CustomGameSummary diff --git a/components/match2/wikis/pubg/game_summary.lua b/components/match2/wikis/pubg/game_summary.lua index c4094293d0..35713e81bc 100644 --- a/components/match2/wikis/pubg/game_summary.lua +++ b/components/match2/wikis/pubg/game_summary.lua @@ -15,8 +15,6 @@ local Page = require('Module:Page') local Table = require('Module:Table') local MatchGroupUtil = Lua.import('Module:MatchGroup/Util') -local OpponentLibraries = require('Module:OpponentLibraries') -local OpponentDisplay = OpponentLibraries.OpponentDisplay local SummaryHelper = Lua.import('Module:MatchSummary/Ffa') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/Ffa/All') @@ -26,122 +24,6 @@ local IconWidget = Lua.import('Module:Widget/Image/Icon/Fontawesome') ---@class PubgMatchGroupUtilGame: MatchGroupUtilGame ---@field stream table -local GAME_STANDINGS_COLUMNS = { - { - sortable = true, - sortType = 'rank', - class = 'cell--rank', - icon = 'rank', - header = { - value = 'Rank', - }, - sortVal = { - value = function (opponent, idx) - if opponent.placement == -1 or opponent.status ~= 'S' then - return idx - end - return opponent.placement - end, - }, - row = { - value = function (opponent, idx) - local place = opponent.placement ~= -1 and opponent.placement or idx - local placementDisplay - if opponent.status and opponent.status ~= 'S' then - placementDisplay = '-' - else - placementDisplay = tostring(MatchSummaryWidgets.RankRange{rankStart = place}) - end - return HtmlWidgets.Fragment{children = { - MatchSummaryWidgets.Trophy{place = place, additionalClasses = {'panel-table__cell-icon'}}, - HtmlWidgets.Span{children = placementDisplay}, - }} - end, - }, - }, - { - sortable = true, - sortType = 'team', - class = 'cell--team', - icon = 'team', - header = { - value = 'Team', - }, - sortVal = { - value = function (opponent, idx) - return opponent.name - end, - }, - row = { - value = function (opponent, idx) - return OpponentDisplay.BlockOpponent{ - opponent = opponent, - showLink = true, - overflow = 'ellipsis', - teamStyle = 'hybrid', - } - end, - }, - }, - { - sortable = true, - sortType = 'total-points', - class = 'cell--total-points', - icon = 'points', - header = { - value = 'Total Points', - mobileValue = 'Pts.', - }, - sortVal = { - value = function (opponent, idx) - return opponent.score - end, - }, - row = { - value = function (opponent, idx) - return opponent.score - end, - }, - }, - { - sortable = true, - sortType = 'placements', - class = 'cell--placements', - icon = 'placement', - header = { - value = 'Placement Points', - }, - sortVal = { - value = function (opponent, idx) - return opponent.scoreBreakdown.placePoints - end, - }, - row = { - value = function (opponent, idx) - return opponent.scoreBreakdown.placePoints - end, - }, - }, - { - sortable = true, - sortType = 'kills', - class = 'cell--kills', - icon = 'kills', - header = { - value = 'Kill Points', - }, - sortVal = { - value = function (opponent, idx) - return opponent.scoreBreakdown.killPoints - end, - }, - row = { - value = function (opponent, idx) - return opponent.scoreBreakdown.killPoints - end, - }, - }, -} ---@param props {bracketId: string, matchId: string, gameIdx: integer} ---@return Html function CustomGameSummary.getGameByMatchId(props) @@ -153,7 +35,7 @@ function CustomGameSummary.getGameByMatchId(props) game.stream = match.stream - CustomGameSummary._opponents(match) + CustomGameSummary._opponents(game, match.opponents) local scoringData = SummaryHelper.createScoringData(match) return MatchSummaryWidgets.Tab{ @@ -162,7 +44,7 @@ function CustomGameSummary.getGameByMatchId(props) children = { CustomGameSummary._createGameDetails(game), MatchSummaryWidgets.PointsDistribution{killScore = scoringData.kill, placementScore = scoringData.placement}, - CustomGameSummary._createGameStandings(game) + SummaryHelper.standardGame(game) } } end @@ -193,62 +75,23 @@ function CustomGameSummary._createGameDetails(game) end ---@param game table ----@return Html -function CustomGameSummary._createGameStandings(game) - local rows = Array.map(game.opponents, function (opponent, index) - local children = Array.map(GAME_STANDINGS_COLUMNS, function(column) - if column.show and not column.show(game) then - return - end - return MatchSummaryWidgets.TableRowCell{ - class = column.class, - sortable = column.sortable, - sortType = column.sortType, - sortValue = column.sortVal and column.sortVal.value(opponent, index) or nil, - value = column.row.value(opponent, index), - } - end) - return MatchSummaryWidgets.TableRow{children = children} - end) - - return MatchSummaryWidgets.Table{children = { - MatchSummaryWidgets.TableHeader{children = Array.map(GAME_STANDINGS_COLUMNS, function(column) - if column.show and not column.show(game) then - return - end - return MatchSummaryWidgets.TableHeaderCell{ - class = column.class, - icon = column.icon, - mobileValue = column.header.mobileValue, - sortable = column.sortable, - sortType = column.sortType, - value = column.header.value, - } - end)}, - unpack(rows) - }} -end - -function CustomGameSummary._opponents(match) +---@param matchOpponents table[] +function CustomGameSummary._opponents(game, matchOpponents) -- Add match opponent data to game opponent - Array.forEach(match.games, function (game) - game.opponents = Array.map(game.opponents, - function(gameOpponent, opponentIdx) - local matchOpponent = match.opponents[opponentIdx] - local newGameOpponent = Table.merge(matchOpponent, gameOpponent) - -- These values are only allowed to come from Game and not Match - newGameOpponent.placement = gameOpponent.placement - newGameOpponent.score = gameOpponent.score - newGameOpponent.status = gameOpponent.status - return newGameOpponent - end - ) - end) + game.opponents = Array.map(game.opponents, + function(gameOpponent, opponentIdx) + local matchOpponent = matchOpponents[opponentIdx] + local newGameOpponent = Table.merge(matchOpponent, gameOpponent) + -- These values are only allowed to come from Game and not Match + newGameOpponent.placement = gameOpponent.placement + newGameOpponent.score = gameOpponent.score + newGameOpponent.status = gameOpponent.status + return newGameOpponent + end + ) -- Sort game level based on placement - Array.forEach(match.games, function (game) - Array.sortInPlaceBy(game.opponents, FnUtil.identity, SummaryHelper.placementSortFunction) - end) + Array.sortInPlaceBy(game.opponents, FnUtil.identity, SummaryHelper.placementSortFunction) end return CustomGameSummary diff --git a/components/match2/wikis/pubg/match_summary.lua b/components/match2/wikis/pubg/match_summary.lua index 096ffd682d..77063739ca 100644 --- a/components/match2/wikis/pubg/match_summary.lua +++ b/components/match2/wikis/pubg/match_summary.lua @@ -11,170 +11,16 @@ local CustomMatchSummary = {} local Array = require('Module:Array') local FnUtil = require('Module:FnUtil') local Lua = require('Module:Lua') -local Table = require('Module:Table') local MatchGroupUtil = Lua.import('Module:MatchGroup/Util') local SummaryHelper = Lua.import('Module:MatchSummary/Ffa') -local OpponentLibraries = require('Module:OpponentLibraries') -local OpponentDisplay = OpponentLibraries.OpponentDisplay local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/Ffa/All') local HtmlWidgets = Lua.import('Module:Widget/Html/All') -local IconWidget = Lua.import('Module:Widget/Image/Icon/Fontawesome') ----@class PungMatchGroupUtilMatch: MatchGroupUtilMatch +---@class PubgMatchGroupUtilMatch: MatchGroupUtilMatch ---@field games ApexMatchGroupUtilGame[] -local PLACEMENT_BG = { - 'cell--gold', - 'cell--silver', - 'cell--bronze', - 'cell--copper', -} - -local STATUS_ICONS = { - -- Normal Status - up = 'standings_up', - stayup = 'standings_stayup', - stay = 'standings_stay', - staydown = 'standings_staydown', - down = 'standings_down', -} - -local OVERVIEW_COLUMNS = { - { - class = 'cell--status', - show = function(match) - return Table.isNotEmpty(match.extradata.status) - end, - header = { - value = '', - }, - row = { - class = function (opponent) - return 'bg-' .. (opponent.advanceBg or '') - end, - value = function (opponent, idx) - if not STATUS_ICONS[opponent.placementStatus] then - return - end - return IconWidget{ - iconName = STATUS_ICONS[opponent.placementStatus], - } - end, - }, - }, - { - sortable = true, - sortType = 'rank', - class = 'cell--rank', - icon = 'rank', - header = { - value = 'Rank', - }, - sortVal = { - value = function (opponent, idx) - return opponent.placement ~= -1 and opponent.placement or idx - end, - }, - row = { - value = function (opponent, idx) - local place = opponent.placement ~= -1 and opponent.placement or idx - local placementDisplay = tostring(MatchSummaryWidgets.RankRange{rankStart = place}) - return HtmlWidgets.Fragment{children = { - MatchSummaryWidgets.Trophy{place = place, additionalClasses = {'panel-table__cell-icon'}}, - HtmlWidgets.Span{children = placementDisplay}, - }} - end, - }, - }, - { - sortable = true, - sortType = 'team', - class = 'cell--team', - icon = 'team', - header = { - value = 'Team', - }, - sortVal = { - value = function (opponent, idx) - return opponent.name - end, - }, - row = { - value = function (opponent, idx) - return OpponentDisplay.BlockOpponent{ - opponent = opponent, - showLink = true, - overflow = 'ellipsis', - teamStyle = 'hybrid', - } - end, - }, - }, - { - sortable = true, - sortType = 'total-points', - class = 'cell--total-points', - icon = 'points', - header = { - value = 'Total Points', - mobileValue = 'Pts.', - }, - sortVal = { - value = function (opponent, idx) - return OpponentDisplay.InlineScore(opponent) - end, - }, - row = { - value = function (opponent, idx) - return OpponentDisplay.InlineScore(opponent) - end, - }, - }, -} -local GAME_COLUMNS = { - { - class = 'panel-table__cell__game-placement', - icon = 'placement', - header = { - value = 'P', - }, - row = { - class = function (opponent) - return PLACEMENT_BG[opponent.placement] - end, - value = function (opponent) - local placementDisplay - if opponent.status and opponent.status ~= 'S' then - placementDisplay = '-' - else - placementDisplay = tostring(MatchSummaryWidgets.RankRange{rankStart = opponent.placement}) - end - return HtmlWidgets.Fragment{children = { - MatchSummaryWidgets.Trophy{place = opponent.placement, additionalClasses = {'panel-table__cell-icon'}}, - HtmlWidgets.Span{ - classes = {'panel-table__cell-game__text'}, - children = placementDisplay, - } - }} - end, - }, - }, - { - class = 'panel-table__cell__game-kills', - icon = 'kills', - header = { - value = 'K', - }, - row = { - value = function (opponent) - return opponent.scoreBreakdown.kills - end, - }, - }, -} - ---@param props {bracketId: string, matchId: string} ---@return Widget function CustomMatchSummary.getByMatchId(props) @@ -191,12 +37,13 @@ function CustomMatchSummary.getByMatchId(props) children = { CustomMatchSummary._createSchedule(match), MatchSummaryWidgets.PointsDistribution{killScore = scoringData.kill, placementScore = scoringData.placement}, - CustomMatchSummary._createMatchStandings(match) + SummaryHelper.standardMatch(match), } } }} end +---@param match table function CustomMatchSummary._opponents(match) -- Add games opponent data to the match opponent Array.forEach(match.opponents, function (opponent, idx) @@ -244,117 +91,4 @@ function CustomMatchSummary._createSchedule(match) }} end ----@param match table ----@return Html -function CustomMatchSummary._createMatchStandings(match) - local rows = Array.map(match.opponents, function (opponent, index) - local children = Array.map(OVERVIEW_COLUMNS, function(column) - if column.show and not column.show(match) then - return - end - return MatchSummaryWidgets.TableRowCell{ - class = (column.class or '') .. ' ' .. (column.row.class and column.row.class(opponent) or ''), - sortable = column.sortable, - sortType = column.sortType, - sortValue = column.sortVal and column.sortVal.value(opponent, index) or nil, - value = column.row.value(opponent, index), - } - end) - - local gameRowContainer = HtmlWidgets.Div{ - classes = {'panel-table__cell', 'cell--game-container'}, - attributes = { - ['data-js-battle-royale'] = 'game-container' - }, - children = Array.map(opponent.games, function(gameOpponent) - local gameRow = HtmlWidgets.Div{ - classes = {'panel-table__cell', 'cell--game'}, - children = Array.map(GAME_COLUMNS, function(column) - if column.show and not column.show(match) then - return - end - return MatchSummaryWidgets.TableRowCell{ - class = (column.class or '') .. ' ' .. (column.row.class and column.row.class(gameOpponent) or ''), - value = column.row.value(gameOpponent), - } - end) - } - return gameRow - end) - } - table.insert(children, gameRowContainer) - return MatchSummaryWidgets.TableRow{children = children} - end) - - local cells = Array.map(OVERVIEW_COLUMNS, function(column) - if column.show and not column.show(match) then - return - end - return MatchSummaryWidgets.TableHeaderCell{ - class = column.class, - icon = column.icon, - mobileValue = column.header.mobileValue, - show = column.show, - sortable = column.sortable, - sortType = column.sortType, - value = column.header.value, - } - end) - - table.insert(cells, HtmlWidgets.Div{ - classes = {'panel-table__cell', 'cell--game-container-nav-holder'}, - attributes = { - ['data-js-battle-royale'] = 'game-nav-holder' - }, - children = { - HtmlWidgets.Div{ - classes = {'panel-table__cell', 'cell--game-container'}, - attributes = { - ['data-js-battle-royale'] = 'game-container' - }, - children = Array.map(match.games, function(game, idx) - return HtmlWidgets.Div{ - classes = {'panel-table__cell', 'cell--game'}, - children = { - HtmlWidgets.Div{ - classes = {'panel-table__cell__game-head'}, - children = { - HtmlWidgets.Div{ - classes = {'panel-table__cell__game-title'}, - children = { - MatchSummaryWidgets.CountdownIcon{game = game, additionalClasses = {'panel-table__cell-icon'}}, - HtmlWidgets.Span{ - classes = {'panel-table__cell-text'}, - children = 'Game ' .. idx - } - } - }, - SummaryHelper.gameCountdown(game), - } - }, - HtmlWidgets.Div{ - classes = {'panel-table__cell__game-details'}, - children = Array.map(GAME_COLUMNS, function(column) - return MatchSummaryWidgets.TableHeaderCell{ - class = column.class, - icon = column.icon, - mobileValue = column.header.mobileValue, - show = column.show, - value = column.header.value, - } - end) - } - } - } - end) - } - } - }) - - return MatchSummaryWidgets.Table{children = { - MatchSummaryWidgets.TableHeader{children = cells}, - unpack(rows) - }} -end - return CustomMatchSummary diff --git a/components/match2/wikis/pubgmobile/game_summary.lua b/components/match2/wikis/pubgmobile/game_summary.lua index 92663e1ce8..3d3840b8ca 100644 --- a/components/match2/wikis/pubgmobile/game_summary.lua +++ b/components/match2/wikis/pubgmobile/game_summary.lua @@ -15,8 +15,6 @@ local Page = require('Module:Page') local Table = require('Module:Table') local MatchGroupUtil = Lua.import('Module:MatchGroup/Util') -local OpponentLibraries = require('Module:OpponentLibraries') -local OpponentDisplay = OpponentLibraries.OpponentDisplay local SummaryHelper = Lua.import('Module:MatchSummary/Ffa') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/Ffa/All') @@ -26,122 +24,6 @@ local IconWidget = Lua.import('Module:Widget/Image/Icon/Fontawesome') ---@class PubgmMatchGroupUtilGame: MatchGroupUtilGame ---@field stream table -local GAME_STANDINGS_COLUMNS = { - { - sortable = true, - sortType = 'rank', - class = 'cell--rank', - icon = 'rank', - header = { - value = 'Rank', - }, - sortVal = { - value = function (opponent, idx) - if opponent.placement == -1 or opponent.status ~= 'S' then - return idx - end - return opponent.placement - end, - }, - row = { - value = function (opponent, idx) - local place = opponent.placement ~= -1 and opponent.placement or idx - local placementDisplay - if opponent.status and opponent.status ~= 'S' then - placementDisplay = '-' - else - placementDisplay = tostring(MatchSummaryWidgets.RankRange{rankStart = place}) - end - return HtmlWidgets.Fragment{children = { - MatchSummaryWidgets.Trophy{place = place, additionalClasses = {'panel-table__cell-icon'}}, - HtmlWidgets.Span{children = placementDisplay}, - }} - end, - }, - }, - { - sortable = true, - sortType = 'team', - class = 'cell--team', - icon = 'team', - header = { - value = 'Team', - }, - sortVal = { - value = function (opponent, idx) - return opponent.name - end, - }, - row = { - value = function (opponent, idx) - return OpponentDisplay.BlockOpponent{ - opponent = opponent, - showLink = true, - overflow = 'ellipsis', - teamStyle = 'hybrid', - } - end, - }, - }, - { - sortable = true, - sortType = 'total-points', - class = 'cell--total-points', - icon = 'points', - header = { - value = 'Total Points', - mobileValue = 'Pts.', - }, - sortVal = { - value = function (opponent, idx) - return opponent.score - end, - }, - row = { - value = function (opponent, idx) - return opponent.score - end, - }, - }, - { - sortable = true, - sortType = 'placements', - class = 'cell--placements', - icon = 'placement', - header = { - value = 'Placement Points', - }, - sortVal = { - value = function (opponent, idx) - return opponent.scoreBreakdown.placePoints - end, - }, - row = { - value = function (opponent, idx) - return opponent.scoreBreakdown.placePoints - end, - }, - }, - { - sortable = true, - sortType = 'kills', - class = 'cell--kills', - icon = 'kills', - header = { - value = 'Kill Points', - }, - sortVal = { - value = function (opponent, idx) - return opponent.scoreBreakdown.killPoints - end, - }, - row = { - value = function (opponent, idx) - return opponent.scoreBreakdown.killPoints - end, - }, - }, -} ---@param props {bracketId: string, matchId: string, gameIdx: integer} ---@return Html function CustomGameSummary.getGameByMatchId(props) @@ -153,7 +35,7 @@ function CustomGameSummary.getGameByMatchId(props) game.stream = match.stream - CustomGameSummary._opponents(match) + CustomGameSummary._opponents(game, match.opponents) local scoringData = SummaryHelper.createScoringData(match) return MatchSummaryWidgets.Tab{ @@ -162,7 +44,7 @@ function CustomGameSummary.getGameByMatchId(props) children = { CustomGameSummary._createGameDetails(game), MatchSummaryWidgets.PointsDistribution{killScore = scoringData.kill, placementScore = scoringData.placement}, - CustomGameSummary._createGameStandings(game) + SummaryHelper.standardGame(game) } } end @@ -193,62 +75,23 @@ function CustomGameSummary._createGameDetails(game) end ---@param game table ----@return Html -function CustomGameSummary._createGameStandings(game) - local rows = Array.map(game.opponents, function (opponent, index) - local children = Array.map(GAME_STANDINGS_COLUMNS, function(column) - if column.show and not column.show(game) then - return - end - return MatchSummaryWidgets.TableRowCell{ - class = column.class, - sortable = column.sortable, - sortType = column.sortType, - sortValue = column.sortVal and column.sortVal.value(opponent, index) or nil, - value = column.row.value(opponent, index), - } - end) - return MatchSummaryWidgets.TableRow{children = children} - end) - - return MatchSummaryWidgets.Table{children = { - MatchSummaryWidgets.TableHeader{children = Array.map(GAME_STANDINGS_COLUMNS, function(column) - if column.show and not column.show(game) then - return - end - return MatchSummaryWidgets.TableHeaderCell{ - class = column.class, - icon = column.icon, - mobileValue = column.header.mobileValue, - sortable = column.sortable, - sortType = column.sortType, - value = column.header.value, - } - end)}, - unpack(rows) - }} -end - -function CustomGameSummary._opponents(match) +---@param matchOpponents table[] +function CustomGameSummary._opponents(game, matchOpponents) -- Add match opponent data to game opponent - Array.forEach(match.games, function (game) - game.opponents = Array.map(game.opponents, - function(gameOpponent, opponentIdx) - local matchOpponent = match.opponents[opponentIdx] - local newGameOpponent = Table.merge(matchOpponent, gameOpponent) - -- These values are only allowed to come from Game and not Match - newGameOpponent.placement = gameOpponent.placement - newGameOpponent.score = gameOpponent.score - newGameOpponent.status = gameOpponent.status - return newGameOpponent - end - ) - end) + game.opponents = Array.map(game.opponents, + function(gameOpponent, opponentIdx) + local matchOpponent = matchOpponents[opponentIdx] + local newGameOpponent = Table.merge(matchOpponent, gameOpponent) + -- These values are only allowed to come from Game and not Match + newGameOpponent.placement = gameOpponent.placement + newGameOpponent.score = gameOpponent.score + newGameOpponent.status = gameOpponent.status + return newGameOpponent + end + ) -- Sort game level based on placement - Array.forEach(match.games, function (game) - Array.sortInPlaceBy(game.opponents, FnUtil.identity, SummaryHelper.placementSortFunction) - end) + Array.sortInPlaceBy(game.opponents, FnUtil.identity, SummaryHelper.placementSortFunction) end return CustomGameSummary diff --git a/components/match2/wikis/pubgmobile/match_summary.lua b/components/match2/wikis/pubgmobile/match_summary.lua index 4846e93da2..c613b0a2d2 100644 --- a/components/match2/wikis/pubgmobile/match_summary.lua +++ b/components/match2/wikis/pubgmobile/match_summary.lua @@ -11,170 +11,16 @@ local CustomMatchSummary = {} local Array = require('Module:Array') local FnUtil = require('Module:FnUtil') local Lua = require('Module:Lua') -local Table = require('Module:Table') local MatchGroupUtil = Lua.import('Module:MatchGroup/Util') local SummaryHelper = Lua.import('Module:MatchSummary/Ffa') -local OpponentLibraries = require('Module:OpponentLibraries') -local OpponentDisplay = OpponentLibraries.OpponentDisplay local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/Ffa/All') local HtmlWidgets = Lua.import('Module:Widget/Html/All') -local IconWidget = Lua.import('Module:Widget/Image/Icon/Fontawesome') ----@class PungmMatchGroupUtilMatch: MatchGroupUtilMatch +---@class PubgmMatchGroupUtilMatch: MatchGroupUtilMatch ---@field games ApexMatchGroupUtilGame[] -local PLACEMENT_BG = { - 'cell--gold', - 'cell--silver', - 'cell--bronze', - 'cell--copper', -} - -local STATUS_ICONS = { - -- Normal Status - up = 'standings_up', - stayup = 'standings_stayup', - stay = 'standings_stay', - staydown = 'standings_staydown', - down = 'standings_down', -} - -local OVERVIEW_COLUMNS = { - { - class = 'cell--status', - show = function(match) - return Table.isNotEmpty(match.extradata.status) - end, - header = { - value = '', - }, - row = { - class = function (opponent) - return 'bg-' .. (opponent.advanceBg or '') - end, - value = function (opponent, idx) - if not STATUS_ICONS[opponent.placementStatus] then - return - end - return IconWidget{ - iconName = STATUS_ICONS[opponent.placementStatus], - } - end, - }, - }, - { - sortable = true, - sortType = 'rank', - class = 'cell--rank', - icon = 'rank', - header = { - value = 'Rank', - }, - sortVal = { - value = function (opponent, idx) - return opponent.placement ~= -1 and opponent.placement or idx - end, - }, - row = { - value = function (opponent, idx) - local place = opponent.placement ~= -1 and opponent.placement or idx - local placementDisplay = tostring(MatchSummaryWidgets.RankRange{rankStart = place}) - return HtmlWidgets.Fragment{children = { - MatchSummaryWidgets.Trophy{place = place, additionalClasses = {'panel-table__cell-icon'}}, - HtmlWidgets.Span{children = placementDisplay}, - }} - end, - }, - }, - { - sortable = true, - sortType = 'team', - class = 'cell--team', - icon = 'team', - header = { - value = 'Team', - }, - sortVal = { - value = function (opponent, idx) - return opponent.name - end, - }, - row = { - value = function (opponent, idx) - return OpponentDisplay.BlockOpponent{ - opponent = opponent, - showLink = true, - overflow = 'ellipsis', - teamStyle = 'hybrid', - } - end, - }, - }, - { - sortable = true, - sortType = 'total-points', - class = 'cell--total-points', - icon = 'points', - header = { - value = 'Total Points', - mobileValue = 'Pts.', - }, - sortVal = { - value = function (opponent, idx) - return OpponentDisplay.InlineScore(opponent) - end, - }, - row = { - value = function (opponent, idx) - return OpponentDisplay.InlineScore(opponent) - end, - }, - }, -} -local GAME_COLUMNS = { - { - class = 'panel-table__cell__game-placement', - icon = 'placement', - header = { - value = 'P', - }, - row = { - class = function (opponent) - return PLACEMENT_BG[opponent.placement] - end, - value = function (opponent) - local placementDisplay - if opponent.status and opponent.status ~= 'S' then - placementDisplay = '-' - else - placementDisplay = tostring(MatchSummaryWidgets.RankRange{rankStart = opponent.placement}) - end - return HtmlWidgets.Fragment{children = { - MatchSummaryWidgets.Trophy{place = opponent.placement, additionalClasses = {'panel-table__cell-icon'}}, - HtmlWidgets.Span{ - classes = {'panel-table__cell-game__text'}, - children = placementDisplay, - } - }} - end, - }, - }, - { - class = 'panel-table__cell__game-kills', - icon = 'kills', - header = { - value = 'K', - }, - row = { - value = function (opponent) - return opponent.scoreBreakdown.kills - end, - }, - }, -} - ---@param props {bracketId: string, matchId: string} ---@return Widget function CustomMatchSummary.getByMatchId(props) @@ -191,12 +37,13 @@ function CustomMatchSummary.getByMatchId(props) children = { CustomMatchSummary._createSchedule(match), MatchSummaryWidgets.PointsDistribution{killScore = scoringData.kill, placementScore = scoringData.placement}, - CustomMatchSummary._createMatchStandings(match) + SummaryHelper.standardMatch(match), } } }} end +---@param match table function CustomMatchSummary._opponents(match) -- Add games opponent data to the match opponent Array.forEach(match.opponents, function (opponent, idx) @@ -244,117 +91,4 @@ function CustomMatchSummary._createSchedule(match) }} end ----@param match table ----@return Html -function CustomMatchSummary._createMatchStandings(match) - local rows = Array.map(match.opponents, function (opponent, index) - local children = Array.map(OVERVIEW_COLUMNS, function(column) - if column.show and not column.show(match) then - return - end - return MatchSummaryWidgets.TableRowCell{ - class = (column.class or '') .. ' ' .. (column.row.class and column.row.class(opponent) or ''), - sortable = column.sortable, - sortType = column.sortType, - sortValue = column.sortVal and column.sortVal.value(opponent, index) or nil, - value = column.row.value(opponent, index), - } - end) - - local gameRowContainer = HtmlWidgets.Div{ - classes = {'panel-table__cell', 'cell--game-container'}, - attributes = { - ['data-js-battle-royale'] = 'game-container' - }, - children = Array.map(opponent.games, function(gameOpponent) - local gameRow = HtmlWidgets.Div{ - classes = {'panel-table__cell', 'cell--game'}, - children = Array.map(GAME_COLUMNS, function(column) - if column.show and not column.show(match) then - return - end - return MatchSummaryWidgets.TableRowCell{ - class = (column.class or '') .. ' ' .. (column.row.class and column.row.class(gameOpponent) or ''), - value = column.row.value(gameOpponent), - } - end) - } - return gameRow - end) - } - table.insert(children, gameRowContainer) - return MatchSummaryWidgets.TableRow{children = children} - end) - - local cells = Array.map(OVERVIEW_COLUMNS, function(column) - if column.show and not column.show(match) then - return - end - return MatchSummaryWidgets.TableHeaderCell{ - class = column.class, - icon = column.icon, - mobileValue = column.header.mobileValue, - show = column.show, - sortable = column.sortable, - sortType = column.sortType, - value = column.header.value, - } - end) - - table.insert(cells, HtmlWidgets.Div{ - classes = {'panel-table__cell', 'cell--game-container-nav-holder'}, - attributes = { - ['data-js-battle-royale'] = 'game-nav-holder' - }, - children = { - HtmlWidgets.Div{ - classes = {'panel-table__cell', 'cell--game-container'}, - attributes = { - ['data-js-battle-royale'] = 'game-container' - }, - children = Array.map(match.games, function(game, idx) - return HtmlWidgets.Div{ - classes = {'panel-table__cell', 'cell--game'}, - children = { - HtmlWidgets.Div{ - classes = {'panel-table__cell__game-head'}, - children = { - HtmlWidgets.Div{ - classes = {'panel-table__cell__game-title'}, - children = { - MatchSummaryWidgets.CountdownIcon{game = game, additionalClasses = {'panel-table__cell-icon'}}, - HtmlWidgets.Span{ - classes = {'panel-table__cell-text'}, - children = 'Game ' .. idx - } - } - }, - SummaryHelper.gameCountdown(game), - } - }, - HtmlWidgets.Div{ - classes = {'panel-table__cell__game-details'}, - children = Array.map(GAME_COLUMNS, function(column) - return MatchSummaryWidgets.TableHeaderCell{ - class = column.class, - icon = column.icon, - mobileValue = column.header.mobileValue, - show = column.show, - value = column.header.value, - } - end) - } - } - } - end) - } - } - }) - - return MatchSummaryWidgets.Table{children = { - MatchSummaryWidgets.TableHeader{children = cells}, - unpack(rows) - }} -end - return CustomMatchSummary