Leaguepedia | League of Legends Esports Wiki
Advertisement

Documentation for this module may be created at Module:MatchListAbstract/doc

local util_args = require('Module:ArgsUtil')
local util_cargo = require('Module:CargoUtil')
local util_esports = require('Module:EsportsUtil')
local util_footnote = require('Module:FootnoteUtil')
local util_game = require('Module:GameUtil')
local util_map = require('Module:MapUtil')
local util_html = require('Module:HtmlUtil')
local util_matches = require('Module:MatchesUtil')
local util_table = require('Module:TableUtil')
local util_text = require('Module:TextUtil')
local util_time = require('Module:TimeUtil')
local util_toggle = require('Module:ToggleUtil')
local util_vars = require('Module:VarsUtil')
local m_team = require('Module:Team')
local Champion = require('Module:Champion')
local i18n = require('Module:i18nUtil')
local Phase = require('Module:Phase')
local LCS = require('Module:LuaClassSystem').class


local lang = mw.getLanguage('en')

local TZ = { 'CD', 'You', 'PST', 'CET', 'KST' }
local NORMAL_TZ = { 'PST', 'CET', 'KST' }

local HIDDENCLASS = 'matches-hiddentab'

local TAB_TOGGLES = {
	all = {
		show_attr = '.ml-allw',
		hide_attr = '.ml-btn',
		show_class = 'ml-allw',
		hide_class = 'ml-btn',
		show_id = 'matchlist-show-all',
		hiddenclass = HIDDENCLASS,
	},
	week = {
		show_attr = '.ml-w%s',
		hide_attr = '.ml-btn%s',
		hiddenclass = HIDDENCLASS,
		show_class = 'ml-allw ml-w%s',
		hide_class = 'ml-btn ml-btn%s',
	},
	row = 'ml-allw ml-w%s %s',
	daterange = 'ml-btn ml-btn%s %s',
}

local TZ_TOGGLES = {
	init = 'You',
	order = { 'CD', 'You', 'PST', 'CET', 'KST' },
	attrs = {
		title = {
			CD = i18n.print('Countdown_title'),
			You = i18n.print('You_title'),
			PST = i18n.print('PST_title'),
			CET = i18n.print('CET_title'),
			KST = i18n.print('KST_title')
		},
	}
}

local MATCHLIST_PATCH_TOGGLES = {
	init = 'patch_number',
	order = { 'patch_all', 'patch_number', 'patch_none' },
	showall = 'patch_all',
}

local HASFLEX = false
local HAS_GROUPS = false
local FORCE_ALLOW_PREDICTIONS = false

local h = {}
local p = LCS()

-- will not be overridden in subclasses, just needs to be accessible
p.RS_TOGGLES = {
	hiddenclass = 'matchlist-rs-hidden',
	order = { 'res', 'sch' },
	attrs = {
		id = {
			sch = 'matchlist-show-schedule'
		}
	}
}

p.THIS = {}
p.COLSPAN = 4
p.WIDTHS = { 110, 25, 25, 110 }
p.MATCH_LIST_HAS_PATCH = false
function p:init(args)
	i18n.init('MatchList')
	local matchData = self:getMatchData(util_esports.getOverviewPage(args.page), args)
	return self:makeOutput(matchData, args)
end

-- match cargo
function p:getMatchData(page, args)
	local matchData = self:getAndRunMatchQuery(page, args)
	for i, tab in ipairs(matchData) do
		tab.index = i
		tab.groupList = {}
		for j, row in ipairs(tab) do
			row.index = j
			self:processMatchRow(row, i, j, args, tab)
		end
	end
	matchData.groupList = h.getListOfGroupsFromCargo(page)
	self.THIS = util_matches.determineThis(matchData, args.This)
	return matchData
end

function p:getAndRunMatchQuery(page, args)
	local outergroup = args.outergroup or 'Tab'
	local innergroup = args.innergroup or 'Date'
	local matchResult = util_cargo.queryAndCast(self:makeMatchQuery(page, args))
	return util_cargo.groupResultOrdered(matchResult, outergroup)
end

function p:makeMatchQuery(page, args)
	local query = {
		tables = { 'MatchSchedule=MS', 'TournamentGroups=TG1', 'TournamentGroups=TG2' },
		join = {
			'MS.PageAndTeam1=TG1.PageAndTeam',
			'MS.PageAndTeam2=TG2.PageAndTeam',
		},
		fields = self:makeMatchFields(args),
		where = h.makeMatchWhere(page, args),
		orderBy = 'MS.N_Page ASC, MS.N_TabInPage ASC, MS.N_MatchInTab ASC',
		groupBy = 'MS.MatchId',
	}
	return query
end

function p:makeMatchFields(args)
	local tbl = {
			'MS.Team1',
			'MS.Team2',
			'MS.Team1Final',
			'MS.Team2Final',
			'MS.Player1',
			'MS.Player2',
			'MS.Winner [number]',
			'MS.Team1Score [number]',
			'MS.Team2Score [number]',
			'MS.Patch',
			'MS.DisabledChampions=Disabled',
			'MS.Hotfix',
			'MS.PatchFootnote',
			'MS.FF [number]',
			'MS.Tab',
			'MS.N_TabInPage [number]',
			'MS.MatchId',
			'MS.DateTime_UTC=UTC',
			'MS.DST',
			'MS.HasTime [boolean]',
			'MS.OverviewPage',
			'MS.MatchDay',
			'MS.Stream',
			'MS.IsFlexibleStart [boolean]',
			'MS.BestOf [number]',
			'MS.InitialN_MatchInTab',
			'MS.InitialPageAndTab',
			'MS.Phase',
			'TG1.GroupName=GroupName1',
			'TG2.GroupName=GroupName2',
			'CONCAT(N_Page,"_",N_TabInPage)=PageAndTab',
			'MS.OverrideAllowPredictions [boolean]',
			'MS.OverrideDisallowPredictions [boolean]',
			'MS.MatchId',
			'MS.PatchPage',
			'MS.IsNullified [boolean]',
		}
	if not util_args.castAsBool(args.nofootnotes) then
		util_table.mergeArrays(tbl, { 'MS.Team1Footnote', 'MS.Team2Footnote', 'MS.Footnote' })
	end
	return tbl
end

function h.makeMatchWhere(page, args)
	local tbl = {
		('MS.OverviewPage="%s"'):format(page),
		util_cargo.whereFromArg('MS.Tab="%s"', args.onlytab),
	}
	if args.team then
		local teamlink = m_team.teamlinkname(args.team)
		tbl[#tbl+1] = ('(MS.Team1Final="%s" OR MS.Team2Final="%s")'):format(teamlink, teamlink)
	end
	return util_cargo.concatWhere(tbl)
end

function p:processMatchRow(row, i, j, args, tab)
	h.processDateTime(row, i, j, h.lastRow(tab, j))
	util_esports.setScoreDisplays(row)
	row.innergroup = args.innergroup and row[args.innergroup]
	row.NewDay = h.nextRow(tab, j).MatchDay and h.nextRow(tab, j).MatchDay ~= row.MatchDay
	row.TimestampAttr = h.getTimestampAttr(row, tab, j)
	row.GroupName = h.getRowGroupName(row)
	HAS_GROUPS = HAS_GROUPS or row.Phase
	row.Phase = Phase(row.Phase)
	HASFLEX = HASFLEX or row.IsFlexibleStart
	FORCE_ALLOW_PREDICTIONS = FORCE_ALLOW_PREDICTIONS or row.OverrideAllowPredictions
	self:getAndAddPatchData(row, tab)
end

function h.lastRow(tab, j)
	return tab[j-1] or { NewDay = true }
end

function h.nextRow(tab, j)
	return tab[j+1] or {}
end

function h.processDateTime(row, i, j, lastrow)
	if row.UTC then
		h.processDateTimeKnown(row, i, j, lastrow)
	else
		h.setDatesTBD(row)
	end
end

function h.processDateTimeKnown(row, i, j, lastrow)
	util_time.addTimezonesToRowFromUTC(row)
	for _, tz in ipairs(NORMAL_TZ) do
		row[tz .. '_Time'] = row[tz]:match('(%d%d:%d%d)')
		
		local date = lang:formatDate('D Y-m-d',row[tz])
		row[tz .. '_Date'] = date
		row[tz .. '_isNewDate'] = date ~= lastrow[tz .. '_Date']
	end
	if row.HasTime then
		h.setTimesYou(row, row.UTC, i, j)
	else
		h.setTimesTBD(row)
	end
end

function h.setTimesYou(row, UTC, i, j)
	row.You_Time = util_time.timeInLocal(UTC)
	row.CD_Time = util_time.countdown(UTC, h.getCountdownSettings(row, i, j))
	row.You_Date = util_time.dateInLocal(UTC)
	row.You_Date_Range = util_time.dateInLocalMatches(UTC)
end

function h.getCountdownSettings(row, i, j)
	if row.Stream then
		return {
			options = { 'matches-format', 'no-leading-zeros' },
			data_end = 'toggle',
			default = '<span class="matchlist-streamlink-icon"></span>',
			i = ('%s_%s'):format(i, j)
		}
	else
		return {
			options = { 'matches-format', 'no-leading-zeros' }
		}
	end
end

function h.setTimesTBD(row)
	for _, tz in ipairs(TZ) do
		row[tz .. '_Time'] = 'TBD'
	end
	row.You_Date = 'TBD'
	row.You_Date_Range = 'TBD'
	return
end

function h.setDatesTBD(row)
	for _, tz in ipairs(TZ) do
		row[tz .. '_Date'] = 'TBD'
	end
	row.You_Date = 'TBD'
	row.You_Date_Range = 'TBD'
	h.setTimesTBD(row)
end

function h.getTimestampAttr(row, tab, j)
	if h.lastRow(tab, j).NewDay then
		return util_time.unixNumber(row.UTC)
	else
		return h.lastRow(tab, j).TimestampAttr
	end
end

function h.getRowGroupName(row)
	if row.Team1 == 'TBD' then return row.GroupName2 end
	if row.Team2 == 'TBD' then return row.GroupName1 end
	if row.GroupName1 ~= row.GroupName2 then return nil end
	return row.GroupName1
end

function h.getListOfGroupsFromCargo(page)
	return util_cargo.getOrderedList({
		tables = 'TournamentGroups',
		fields = 'GroupName',
		where = ('OverviewPage="%s"'):format(page),
		orderBy = 'GroupN',
		groupBy = 'GroupName',
	}, 'GroupName')
end

function p:getAndAddPatchData(row, tab)
	-- add patch as a table caption
	util_table.initTable(tab, 'patchinfo', { patches = {}, footnotes = {} })
	if not row.Patch then return true end
	self.MATCH_LIST_HAS_PATCH = true
	local patch = row.Patch
	util_table.initDict(
		tab.patchinfo.patches,
		patch,
		{ patchLink = util_text.intLinkOrText(row.PatchPage, patch), hotfixes = {}, disabled = {}, linked = {} }
	)
	if row.Hotfix then
		util_table.initDict(tab.patchinfo.patches[patch].hotfixes, row.Hotfix)
	end
	if row.PatchFootnote then
		util_table.initDict(tab.patchinfo.footnotes, row.PatchFootnote)
	end
	util_table.mergeArrays(tab.patchinfo.patches[patch].disabled, util_text.split(row.Disabled))
end

-- print
function p:makeOutput(data, args)
	util_footnote.init()
	local output = mw.html.create('div'):attr('id','matchlist')
	if HASFLEX then
		h.printFlexNote(output)
	end
	self:printTogglersAndButtons(output, data.groupList)
	self:printAllTabs(output, data, args)
	util_footnote.printTexts(output)
	return output
end

function p:printTogglersAndButtons(tbl, groupList)
	util_toggle.printSectionToggler(tbl, TAB_TOGGLES.all)
	h.printResultsToggle(tbl)
	h.printTZToggle(tbl)
	self:printPredictionsButton(tbl)
	h.printGroups(tbl, groupList)
	tbl:tag('div')
			:css('clear','left')
			:attr('id', 'matchlist-section-start')
end

function h.printResultsToggle(tbl)
	local div = tbl:tag('div')
		:addClass('toggle-button')
	p.RS_TOGGLES.displays = {
		res = i18n.print('results_init'),
		sch = i18n.print('results')
	}
	util_toggle.printOptionFromListTogglers(div, p.RS_TOGGLES)
end

function h.printTZToggle(tbl)
	local div = tbl:tag('div'):addClass('toggle-button')
	util_toggle.printOptionFromListTogglers(div, TZ_TOGGLES)
end

function p:printPredictionsButton(tbl)
	if self.THIS and #self.THIS == 0 and not FORCE_ALLOW_PREDICTIONS then return end
	local div = tbl:tag('div')
		:addClass('toggle-button')
		:addClass('prediction-action')
		:attr('id', 'matches-prediction-begin')
		:wikitext(i18n.print('launch_predictions'))
end

function h.printGroups(tbl, groupList)
	if not next(groupList) then return end
	if not HAS_GROUPS then return end
	tbl:tag('div')
			:css('clear','left')
	local div = tbl:tag('div')
		:addClass('toggle-button')
	div:tag('span'):wikitext(i18n.print('highlightGroup'))
	util_map.arraySafe(groupList, h.printOneGroup, div)
end

function h.printOneGroup(group, div)
	div:wikitext('|')
	div:tag('div')
		:addClass('group-highlighter')
		:wikitext(group)
		:attr('data-group-highlighter', group)
end

function h.printFlexNote(tbl)
	tbl:wikitext(mw.getCurrentFrame():expandTemplate{title='FlexNotice',args={''}})
end

function p:printAllTabs(output, data, args)
	local div = output:tag('div')
		:attr('id', 'matchlist-content-wrapper')
		:addClass('ml-normal-pred-and-results')
		:addClass(args.tabwrapperclass)
	for i, tab in ipairs(data) do
		self:printTab(div, tab, util_table.keyOf(self.THIS, i))
	end
end

function p:printTab(div, tab, isfocused)
	local innerDiv = div:tag('div')
		:addClass('matchlist-tab-wrapper')
	local tbl = innerDiv:tag('table')
		:addClass('wikitable2')
		:addClass('matchlist')
	self:printPatchCaption(tbl, tab)
	self:printTabHeader(tbl, tab.index, tab.name, isfocused)
	self:printDateRange(
		tbl,
		tab,
		h.getDateRangeToggleClass(tab.index, isfocused)
	)
	util_html.printEmptyWidthRowPX(tbl, self.WIDTHS)
	local toggle_class = h.getRowToggleClass(tab.index, isfocused)
	for k, row in ipairs(tab) do
		self:printFullRow(tbl, row, toggle_class, k == 1)
	end
	h.printPredictionTotals(innerDiv, tab.predictionTotals)
	return
end

function p:printPatchCaption(tbl, tab)
	if not self.MATCH_LIST_HAS_PATCH then return true end
	local caption = tbl:tag('caption')
	-- the toggle here is needed because footnotes are attached only to the parent element, not the spans
	-- since it's impossible to show disabled champions but not patch number,
	-- we don't need to add patch_disabled since that would be showall, and showall is auto added
	h.printPatches(caption, tab.patchinfo)
	util_footnote.tag(caption, tab.patchinfo.footnotes)
end

function h.printPatches(caption, patchinfo)
	local span = caption:tag('span')
		:addClass('matchlist-patches')
	local patchesText = {}
	for _, patch in ipairs(patchinfo.patches) do
		patchesText[#patchesText+1] = h.getOnePatchText(patch, patchinfo["patches"][patch])
	end
	span:wikitext(i18n.print('patchCaption', h.joinPatchesText(patchesText)))
end

function h.joinPatchesText(patches)
	return util_table.concatNonempty(patches, ', ') or i18n.print('tbd')
end

function h.getOnePatchText(patch, patchData)
	local patchSpan = mw.html.create("span")
		:wikitext(patchData.patchLink)
	h.addDisabledText(patchSpan, patchData.disabled)
	return tostring(patchSpan)
end

function h.addDisabledText(patchSpan, disabled)
	if not next(disabled) then return end
	local popup = util_toggle.popupButton(patchSpan)
	popup.button:addClass("matchlist-disabled-button")
	local div = popup.inner:tag("div")
		:wikitext(i18n.print('patchDisabled'))
		:addClass("matchlist-disabled-popup")
	h.getDisabledChampionFlairs(disabled, div)
end

function h.getDisabledChampionFlairs(disabled, div)
	local ul = div:tag("ul")
		:addClass("matchlist-disabled-ul")
	for _, disabledChampion in ipairs(util_table.removeDuplicates(disabled)) do
		ul:tag("li")
			:wikitext(Champion(disabledChampion):flairlink())
			:addClass("matchlist-disabled-li")
	end
end

function p:printTabHeader(tbl, i, name, isfocused)
	local data = mw.clone(TAB_TOGGLES.week)
	util_toggle.prepDataByWeek(data, i)
	data.initshown = isfocused
	util_toggle.printToggleHeader(tbl, self.COLSPAN, name, data)
	return
end

function p:printDateRange(tbl, tab_data, daterowclass)
	local tr = tbl:tag('tr')
		:addClass(daterowclass)
	local td = tr:tag('td')
		:attr('colspan', self.COLSPAN)
	local n = #tab_data
	for _, tz in ipairs(NORMAL_TZ) do
		h.printNormalTZDatesToRangeCell(
			td:tag('span'),
			tz,
			tab_data[1][tz .. '_Date'],
			tab_data[n][tz .. '_Date']
		)
	end
	self:printYouTZDatesToRangeCell(
		td:tag('span'),
		tab_data[1].You_Date_Range,
		tab_data[n].You_Date_Range
	)
end

function h.printNormalTZDatesToRangeCell(span, tz, text1, text2)
	text1 = text1 ~= 'TBD' and lang:formatDate('D j M', text1) or text1
	text2 = text2 ~= 'TBD' and lang:formatDate('D j M', text2) or text2
	span:addClass('matchlist-daterange') -- for css, toggle displays handled through util below
		:wikitext(text1)
	if text2 ~= text1 then
		span:wikitext(' - ')
		span:wikitext(text2)
	end
	util_toggle.oflCellClasses(span, TZ_TOGGLES, tz)
	return
end

function p:printYouTZDatesToRangeCell(span, text1, text2)
	-- this is a special case because we need extra classes for JS to do its thing
	-- because we don't know if the dates are the same or not
	-- given that this is already special, we may as well do You and CD as one instead of splitting
	util_toggle.oflCellClasses(span, TZ_TOGGLES, 'You')
	span:addClass(TZ_TOGGLES.classes.CD) -- manually add this one because it's the same as YOU
	self:printYouTZDatesToRangeData(span, text1, text2)
end

function p:printYouTZDatesToRangeData(span, text1, text2)
	span:addClass('matchlist-daterange')
		:addClass('matchlist-daterange-you')
	span:tag('span')
		:addClass('matchlist-daterange-you-1')
		:wikitext(text1)
	span:tag('span')
		:addClass('matchlist-daterange-you-hyphen')
		:wikitext(' - ')
	span:tag('span')
		:addClass('matchlist-daterange-you-hyphen')
		:wikitext(text2)
end

function h.getDateRangeToggleClass(i, isfocused)
	return TAB_TOGGLES.daterange:format(i, not isfocused and '' or HIDDENCLASS)
end

function h.getRowToggleClass(i, isfocused)
	return TAB_TOGGLES.row:format(i, isfocused and '' or HIDDENCLASS)
end

function p:printFullRow(tbl_tab, row, toggle_class, isfirst)
	self:printDateRow(tbl_tab, row, toggle_class, isfirst)
	local tr = tbl_tab:tag('tr')
		:addClass(toggle_class)
		:addClass('ml-row')
		:attr('data-initial-order', row.InitialN_MatchInTab)
		:attr('data-initial-pageandtab', row.InitialPageAndTab)
	if row.IsNullified then
		tr:addClass('ml-nullified')
	end
	h.addGroupAttr(tr, row)
	h.tagRowIfOver(tr, row)
	h.addDateAttr(tr, row)
	h.addNewDay(tr, row)
	h.addFlexStart(tr, row)
	util_matches.printCustomClass(tr, row)
	self:printTeam1(tr, row)
	self:printMiddle(tr, row)
	self:printTeam2(tr, row)
end

function h.addGroupAttr(tr, row)
	if not row.Phase:isgroups() then return end
	tr:attr('data-group', row.GroupName)
end

function p:printDateRow(tbl, row, toggle_class, isfirst)
	for _, tz in ipairs(NORMAL_TZ) do
		if row[tz .. '_isNewDate'] then
			local tr = tbl:tag('tr')
				:addClass(toggle_class)
			self:printNormalTZDateToRow(tr, tz, row[tz .. '_Date'])
		end
	end
	local tr = tbl:tag('tr')
		:addClass(toggle_class)
	self:printYouTZDateToRow(tr, row.You_Date)
	tr:attr('data-isfirst',util_args.boolToStringYN(isfirst))
	return
end

function p:printNormalTZDateToRow(tr, tz, text)
	tr:addClass('matchlist-date')
	util_toggle.oflCellClasses(tr, TZ_TOGGLES, tz)
	local td = tr:tag('td')
				:attr('colspan', self.COLSPAN)
	td:wikitext(text)
	return
end

function p:printYouTZDateToRow(tr, text)
	tr:addClass('matchlist-date')
		:addClass('matchlist-you-date') -- to select and remove the 'You' rows
		:addClass(TZ_TOGGLES.classes.CD)
	util_toggle.oflCellClasses(tr, TZ_TOGGLES, 'You')
	local td = tr:tag('td')
		:attr('colspan', self.COLSPAN)
	td:wikitext(text)
	return td
end

function h.tagRowIfOver(tr, row)
	if not h.isOver(row) then
		tr:addClass('ml-row-tbd')
			:attr('data-prediction-expire', row.TimestampAttr)
	end
	if row.OverrideAllowPredictions then
		tr:addClass('ml-row-tbd')
			:attr('data-prediction-expire', '9999999999')
		tr:addClass('ml-verify-prediction-expire')
		tr:attr('data-game-id', row.MatchId)
	end
	if row.OverrideDisallowPredictions then
		tr:addClass('ml-row-predictions-disabled')
		tr:attr('data-game-id', row.MatchId)
	end
end

function h.isOver(row)
	return ((row.Team1Score and row.Team2Score) or row.Winner) and not row.OverrideAllowPredictions
end

function h.addDateAttr(tr, row)
	if not row.UTC then return end
	tr:attr('data-date',util_time.strToDateStr(row.UTC))
end

function h.addNewDay(tr, row)
	if not row.NewDay then return end
	tr:addClass('matchlist-newday')
end

function h.addFlexStart(tr, row)
	if not util_args.castAsBool(row.IsFlexibleStart) then return end
	tr:addClass('matchlist-flex')
end

function p:printTeam1(tr, row)
	if (row.Team1 == 'TBD' or not row.Team1) and not row.Player1 then
		tr:addClass('ml-row-unknown-team')
	end
	local td = tr:tag('td')
		:addClass('matchlist-team1')
		:addClass('ml-team')
	util_esports.addTeamHighlighter(td, row.Team1Final)
	h.printWinnerClasses(td, row, 1)
	h.printTeam1Content(td, row)
end

function h.printWinnerClasses(td, row, this)
	if row.Winner == this then
		td:addClass('matchlist-winner-team')
	elseif row.Winner == 0 then
		td:addClass('matchlist-tied-team')
	end
end

function h.printTeam1Content(td, row)
	util_footnote.tag(td, row.Team1Footnote)
	if not row.Player1 then
		td:wikitext(m_team.leftshort(row.Team1, {link=''}))
		return
	end
	td
		:wikitext(util_esports.playerLinked(row.Player1))
		:wikitext(m_team.onlyimageshort(row.Team1))
end

function p:printTeam2(tr, row)
	if (row.Team2 == 'TBD' or not row.Team2)  and not row.Player2 then
		tr:addClass('ml-row-unknown-team')
	end
	local td = tr:tag('td')
		:addClass('matchlist-team2')
		:addClass('ml-team')
	util_esports.addTeamHighlighter(td, row.Team2Final)
	h.printWinnerClasses(td, row, 2)
	h.printTeam2Content(td, row)
end

function h.printTeam2Content(td, row)
	if not row.Player2 then
		td:wikitext(m_team.rightshort(row.Team2, {link=''}))
	else
		td:wikitext(m_team.onlyimageshort(row.Team2))
			:wikitext(util_esports.playerLinked(row.Player2))
	end
	util_footnote.tag(td, h.team2Footnotes(row))
end

function h.team2Footnotes(row)
	local tbl = { row.Team2Footnote, row.Footnote }
	util_table.removeFalseEntries(tbl, 2)
	return tbl
end

function p:printMiddle(tr, row)
	if h.isOver(row) then
		self:printScore(tr, row)
		self:printTime(tr, row, true)
	else
		self:printTime(tr, row)
	end
end

function p:printScore(tr, row, suppresstoggle)
	local td1 = self:printOneScore(tr, row, 1)
	local td2 = self:printOneScore(tr, row, 2)
	if row.Winner == 1 then
		td1:addClass('matchlist-winner-score')
	elseif row.Winner == 2 then
		td2:addClass('matchlist-winner-score')
	elseif row.Winner == 0 then
		td1:addClass('matchlist-tied-score')
		td2:addClass('matchlist-tied-score')
	end
	if not suppresstoggle then
		util_toggle.oflCellClasses(td1, p.RS_TOGGLES, 'res')
		util_toggle.oflCellClasses(td2, p.RS_TOGGLES, 'res')
	end
	return
end

function p:printOneScore(tr, row, n)
	local td = tr:tag('td'):wikitext(self:getOneScore(row, n))
		:addClass('matchlist-score')
	util_esports.addTeamHighlighter(td, row[('Team%sFinal'):format(n)])
	return td
end

function p:getOneScore(row, n)
	return row[('Team%sScoreDisplay'):format(n)]
end

function p:printTime(tr, row, usetoggle)
	local td = tr:tag('td')
		:attr('colspan', self.COLSPAN - 2)
		:addClass('matchlist-time-cell')
		:addClass('plainlinks')
	if usetoggle then
		util_toggle.oflCellClasses(td, p.RS_TOGGLES, 'sch')
	end
	for _, tz in ipairs(TZ) do
		local span = td:tag('span')
		if row.Stream then
			span:wikitext('[', row.Stream, ' ', row[tz .. '_Time'], ']')
		else
			span:wikitext(row[tz .. '_Time'])
		end
		util_toggle.oflCellClasses(span, TZ_TOGGLES, tz)
	end
	return
end

function h.printPredictionTotals(div, totals)
	if not totals then return end
	local inner = div:tag('div')
		:addClass('ml-user-prediction-totals')
	inner:wikitext(('Correct: %s/%s (%s Guessed)'):format(totals.right, totals.over, totals.made))
end

return p
Advertisement