Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
6bc7fd0
add synclevel prop for localstorage scope
Eetwalt Mar 19, 2026
30d25f0
add subtle variant with left-border accent
Eetwalt Mar 19, 2026
ae142d8
add listitem row widget
Eetwalt Mar 19, 2026
f727a06
add list widget with contentswitch tabs
Eetwalt Mar 19, 2026
9ee538b
switch tournament list to new list widget
Eetwalt Mar 19, 2026
e2e68b7
add listitem layout styles
Eetwalt Mar 19, 2026
2ae3c3a
switch tournament list to new list widget
Eetwalt Mar 19, 2026
b6bebb5
remove synclevel prop and disable tab persistence
Eetwalt Mar 19, 2026
e15ec2c
remove defaults
Eetwalt Mar 19, 2026
1bc1ac6
move data fetching to helper
Eetwalt Mar 20, 2026
80cc59b
adjust layout and styles
Eetwalt Mar 20, 2026
b37e13d
adjust styling and spacing
Eetwalt Mar 20, 2026
50f6943
fix layout
Eetwalt Mar 20, 2026
8de7429
try out aoe
Eetwalt Mar 20, 2026
4211ae5
show game icon
Eetwalt Mar 20, 2026
b6757ca
new colors and variants
Eetwalt Mar 20, 2026
cc96348
fix tierpill nil error
Eetwalt Mar 20, 2026
e87da33
fix badges
Eetwalt Mar 20, 2026
9598bf9
implement chips
Eetwalt Mar 20, 2026
ff51b23
add neg margin to chip
Eetwalt Mar 20, 2026
72f42d7
implement collapsible variant
Eetwalt Mar 24, 2026
f75bdf8
test with aoe
Eetwalt Mar 24, 2026
7d874fc
make collapse work with header click
Eetwalt Mar 24, 2026
f860f41
doesnt need the exclude
Eetwalt Mar 24, 2026
8fefb64
add compact mode and placeholder icon
Eetwalt Mar 24, 2026
54a3d0d
update wikis with correct variants
Eetwalt Mar 24, 2026
9d9e026
lose top padding from 2nd and 3rd PhaseCollapsibles
Eetwalt Mar 24, 2026
45b378d
update lol mainpage
Eetwalt Mar 24, 2026
94bdd40
remove padding
Eetwalt Mar 24, 2026
563c2ac
prop annos
Eetwalt Mar 25, 2026
abe7822
css cleanup
Eetwalt Mar 25, 2026
df1a59a
collapsible css fixes
Eetwalt Mar 25, 2026
c163097
single return tierpill approach
Eetwalt Mar 26, 2026
c95ccc9
css fixes
Eetwalt Mar 26, 2026
fe7daa9
move Data out of Widget dir
Eetwalt Mar 26, 2026
f7a9a1a
use WidgetUtil for badgeChildren
Eetwalt Mar 26, 2026
3e87d41
Data improvements
Eetwalt Mar 26, 2026
2e5e9e3
use general collapsible
Eetwalt Mar 26, 2026
88e4065
lint
Eetwalt Mar 26, 2026
fcb42b2
refactor TierPill
Eetwalt Mar 26, 2026
522ca1d
force border color
Eetwalt Mar 26, 2026
1a7b839
refactor List / Sublist to minimize repeated code
Eetwalt Mar 26, 2026
e829ec3
chore: update visual snapshots
Eetwalt Mar 26, 2026
0d41b51
Merge branch 'main' into new-tournament-list
Eetwalt Mar 26, 2026
4c8da08
chore: update visual snapshots
Eetwalt Mar 26, 2026
4e16b11
remove redundant logic check
Eetwalt Mar 27, 2026
da898ca
mobile-first css
Eetwalt Mar 27, 2026
5dea231
replace FILLER with icon test
Eetwalt Mar 27, 2026
02d6a88
add font-sizes for proper icon sizing
Eetwalt Mar 27, 2026
dbd9f52
remove wrapper div from game icon
Eetwalt Mar 27, 2026
1db238d
css fixes
Eetwalt Mar 27, 2026
f3d3e01
update test with new filler
Eetwalt Mar 27, 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
2 changes: 1 addition & 1 deletion lua/spec/league_icon_spec.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
--- Triple Comment to Enable our LLS Plugin
local LeagueIcon = require('Module:LeagueIcon')

local FILLER_EXPECT = '<span class="league-icon-small-image">[[File:Logo filler event.png|link=]]</span>'
local FILLER_EXPECT = '<span class="league-icon-small-image"><i class="fas fa-trophy"></i></span>'
local ICON_DARK_EXPECT = '<span class="league-icon-small-image">[[File:DarkIcon.png|link=||50x50px]]</span>'

local ICON_BOTH_EXPECT =
Expand Down
7 changes: 4 additions & 3 deletions lua/wikis/apexlegends/MainPageLayout/data.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ local Lua = require('Module:Lua')
local MainPageLayoutUtil = Lua.import('Module:MainPageLayout/Util')

local FilterButtonsWidget = Lua.import('Module:Widget/FilterButtons')
local TournamentsTicker = Lua.import('Module:Widget/Tournaments/Ticker')
local TournamentsTicker = Lua.import('Module:Widget/Tournaments/Ticker/List')

local HtmlWidgets = Lua.import('Module:Widget/Html/All')
local Div = HtmlWidgets.Div
Expand Down Expand Up @@ -76,9 +76,10 @@ local CONTENT = {
heading = 'Tournaments',
body = TournamentsTicker{
upcomingDays = 30,
completedDays = 30
completedDays = 30,
tierColorScheme = 'top3',
},
padding = true,
padding = false,
boxid = MainPageLayoutUtil.BoxId.TOURNAMENTS_TICKER,
},
headlines = {
Expand Down
7 changes: 4 additions & 3 deletions lua/wikis/commons/LeagueIcon.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ local Lua = require('Module:Lua')

local LeagueIcon = {}
local Class = Lua.import('Module:Class')
local Icon = Lua.import('Module:Icon')
local Template = Lua.import('Module:Template')
local Logic = Lua.import('Module:Logic')
local String = Lua.import('Module:StringUtils')

local FILLER = '<span class="league-icon-small-image">[[File:Logo filler event.png|link=]]</span>'
local NO_ICON_BUT_ICONDARK_TRACKING_CATEGORY = '[[Category:Pages with only icondark]]'

---@class LeagueIconDisplayArgs
Expand Down Expand Up @@ -56,7 +55,9 @@ function LeagueIcon.display(args)

--if icon and iconDark are not given and can not be retrieved return filler icon
if String.isEmpty(icon) and String.isEmpty(iconDark) then
return FILLER
return tostring(mw.html.create('span')
:addClass('league-icon-small-image')
:node(Icon.makeIcon{iconName = 'firstplace'}))
end

if String.isEmpty(icon) then
Expand Down
149 changes: 149 additions & 0 deletions lua/wikis/commons/TournamentsTicker/Data.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
---
-- @Liquipedia
-- page=Module:TournamentsTicker/Data
--
-- Please see https://github.com/Liquipedia/Lua-Modules to contribute
--

local Lua = require('Module:Lua')

local Array = Lua.import('Module:Array')
local Condition = Lua.import('Module:Condition')
local DateExt = Lua.import('Module:Date/Ext')
local Operator = Lua.import('Module:Operator')

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

local TournamentsTickerData = {}

---@class TournamentsTickerDataProps
---@field upcomingDays number
---@field completedDays number
---@field modifierTier1 number?
---@field modifierTier2 number?
---@field modifierTier3 number?
---@field modifierTier4 number?
---@field modifierTier5 number?
---@field modifierTierMisc number?
---@field modifierTypeQualifier number?

---@class TournamentsTickerDataResult
---@field upcoming StandardTournament[]
---@field ongoing StandardTournament[]
---@field completed StandardTournament[]

---@param props TournamentsTickerDataProps
---@return TournamentsTickerDataResult
function TournamentsTickerData.get(props)
local upcomingDays = props.upcomingDays or 5
local completedDays = props.completedDays or 5

local tierThresholdModifiers = {
[1] = props.modifierTier1,
[2] = props.modifierTier2,
[3] = props.modifierTier3,
[4] = props.modifierTier4,
[5] = props.modifierTier5,
[-1] = props.modifierTierMisc,
}

--- The Tier Type thresholds only affect completed tournaments.
local tierTypeThresholdModifiers = {
['qualifier'] = props.modifierTypeQualifier,
}

local currentTimestamp = DateExt.getCurrentTimestamp()

---@param tournament StandardTournament
---@return boolean
local function isWithinDateRange(tournament)
local modifiedThreshold = tierThresholdModifiers[tournament.liquipediaTier] or 0
local modifiedCompletedThreshold = tierTypeThresholdModifiers[tournament.liquipediaTierType] or modifiedThreshold

if not tournament.startDate then
return false
end

local startDateThreshold = currentTimestamp + DateExt.daysToSeconds(upcomingDays + modifiedThreshold)
local endDateThreshold = currentTimestamp - DateExt.daysToSeconds(completedDays + modifiedCompletedThreshold)

if tournament.phase == 'ONGOING' then
return true
elseif tournament.phase == 'UPCOMING' then
return tournament.startDate.timestamp < startDateThreshold
elseif tournament.phase == 'FINISHED' then
assert(tournament.endDate, 'Tournament without end date: ' .. tournament.pageName)
return tournament.endDate.timestamp > endDateThreshold
end
return false
end

local lpdbFilter = Condition.Tree(Condition.BooleanOperator.all):add{
Condition.Util.anyOf(Condition.ColumnName('status'), {'', 'finished'}),
Condition.Node(Condition.ColumnName('liquipediatiertype'), Condition.Comparator.neq, 'Points')
}

local allTournaments = Tournament.getAllTournaments(lpdbFilter, function(tournament)
return isWithinDateRange(tournament)
end)

---@param a StandardTournament
---@param b StandardTournament
---@param dateProperty 'endDate'|'startDate'
---@param operator fun(a: integer, b: integer): boolean
---@return boolean?
local function sortByDateProperty(a, b, dateProperty, operator)
if not a[dateProperty] and not b[dateProperty] then return nil end
if not a[dateProperty] then return true end
if not b[dateProperty] then return false end
if a[dateProperty].timestamp ~= b[dateProperty].timestamp then
return operator(a[dateProperty].timestamp, b[dateProperty].timestamp)
end
return nil
end

---@param a StandardTournament
---@param b StandardTournament
---@return boolean
local function sortByDate(a, b)
local endDateSort = sortByDateProperty(a, b, 'endDate', Operator.gt)
if endDateSort ~= nil then return endDateSort end
local startDateSort = sortByDateProperty(a, b, 'startDate', Operator.gt)
if startDateSort ~= nil then return startDateSort end
return a.pageName < b.pageName
end

---@param a StandardTournament
---@param b StandardTournament
---@return boolean
local function sortByDateUpcoming(a, b)
local startDateSort = sortByDateProperty(a, b, 'startDate', Operator.gt)
if startDateSort ~= nil then return startDateSort end
local endDateSort = sortByDateProperty(a, b, 'endDate', Operator.gt)
if endDateSort ~= nil then return endDateSort end
return a.pageName < b.pageName
end

---@param phase TournamentPhase
---@return fun(tournament: StandardTournament): boolean
local function filterByPhase(phase)
return function(tournament)
return tournament.phase == phase
end
end

local upcomingTournaments = Array.filter(allTournaments, filterByPhase('UPCOMING'))
local ongoingTournaments = Array.filter(allTournaments, filterByPhase('ONGOING'))
local completedTournaments = Array.filter(allTournaments, filterByPhase('FINISHED'))
table.sort(upcomingTournaments, sortByDateUpcoming)
table.sort(ongoingTournaments, sortByDate)
table.sort(completedTournaments, sortByDate)

return {
upcoming = upcomingTournaments,
ongoing = ongoingTournaments,
completed = completedTournaments,
}
end

return TournamentsTickerData
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
-- @Liquipedia
-- page=Module:Widget/Participants/Team/ChevronToggle
-- page=Module:Widget/GeneralCollapsible/ChevronToggle
--
-- Please see https://github.com/Liquipedia/Lua-Modules to contribute
--
Expand Down
2 changes: 1 addition & 1 deletion lua/wikis/commons/Widget/Participants/Team/Header.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ local Opponent = Lua.import('Module:Opponent/Custom')
local OpponentDisplay = Lua.import('Module:OpponentDisplay/Custom')

local Widget = Lua.import('Module:Widget')
local ChevronToggle = Lua.import('Module:Widget/Participants/Team/ChevronToggle')
local ChevronToggle = Lua.import('Module:Widget/GeneralCollapsible/ChevronToggle')
local WidgetUtil = Lua.import('Module:Widget/Util')
local HtmlWidgets = Lua.import('Module:Widget/Html/All')
local Div = HtmlWidgets.Div
Expand Down
58 changes: 39 additions & 19 deletions lua/wikis/commons/Widget/Tournament/TierPill.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,25 @@ local Lua = require('Module:Lua')
local Class = Lua.import('Module:Class')
local Tier = Lua.import('Module:Tier/Utils')

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

---@class TournamentsTickerPillWidgetProps
---@field tournament StandardTournament
---@field variant 'solid'|'subtle'?
---@field colorScheme 'full'|'top3'?

---@class TournamentsTickerPillWidget: Widget
---@operator call(table): TournamentsTickerPillWidget
---@operator call(TournamentsTickerPillWidgetProps): TournamentsTickerPillWidget
---@field props TournamentsTickerPillWidgetProps
local TournamentsTickerPillWidget = Class.new(Widget)

TournamentsTickerPillWidget.defaultProps = {
variant = 'solid',
colorScheme = 'full',
}

local COLOR_CLASSES = {
[1] = 'tier1',
[2] = 'tier2',
Expand All @@ -41,32 +53,40 @@ function TournamentsTickerPillWidget:render()
return
end

local tierShort, tierTypeShort = Tier.toShortName(tournament.liquipediaTier,tournament.liquipediaTierType)
local subtle = self.props.variant == 'subtle'
local tierShort, tierTypeShort = Tier.toShortName(tournament.liquipediaTier, tournament.liquipediaTierType)

local tierNode, tierTypeNode, colorClass
if tierTypeShort then
local colorClass
if tierTypeShort and not subtle then
colorClass = COLOR_CLASSES[tournament.liquipediaTierType]
tierNode = HtmlWidgets.Div{
classes = {'tournament-badge__chip', 'chip--' .. COLOR_CLASSES[tournament.liquipediaTier]},
children = tierShort,
}
tierTypeNode = HtmlWidgets.Div{
classes = {'tournament-badge__text'},
children = tierTypeShort,
}
else
colorClass = COLOR_CLASSES[tournament.liquipediaTier]
tierNode = HtmlWidgets.Div{
classes = {'tournament-badge__text'},
children = Tier.toName(tournament.liquipediaTier),
}
end

colorClass = colorClass or COLOR_CLASSES.default

local chipText = subtle and Tier.toName(tournament.liquipediaTier) or tierShort
local textContent = tierTypeShort and tierTypeShort or Tier.toName(tournament.liquipediaTier)

return HtmlWidgets.Div{
classes = {'tournament-badge', 'badge--' .. colorClass},
children = {tierNode, tierTypeNode},
classes = WidgetUtil.collect(
'tournament-badge',
'badge--' .. colorClass,
subtle and 'tournament-badge--subtle' or nil,
self.props.colorScheme == 'top3' and 'tournament-badge--top3' or nil
),
children = WidgetUtil.collect(
tierTypeShort and HtmlWidgets.Div{
classes = WidgetUtil.collect(
'tournament-badge__chip',
not subtle and 'chip--' .. COLOR_CLASSES[tournament.liquipediaTier] or nil
),
children = chipText,
} or nil,
HtmlWidgets.Div{
classes = {'tournament-badge__text'},
children = textContent,
}
),
}
end

Expand Down
Loading
Loading