media-random: reset button if < 20 random tracks left to play

This commit is contained in:
Sattva
2025-05-19 10:34:06 +03:00
parent a3dceed499
commit b7cbe0524f
+160 -114
View File
@@ -15817,21 +15817,20 @@ function LeaPlusLC:RunOnce()
-- Function to show random track listing -- Function to show random track listing
local function ShowRandomList() local function ShowRandomList()
-- If random track is currently playing, stop playback since random track list will be changed
if LastFolder == L["Random"] then if LastFolder == L["Random"] then
stopBtn:Click() stopBtn:Click()
end end
-- Wipe the track listing for random wipe(ListData) -- Start with a clean ListData
wipe(ListData)
-- Set the track list heading
ListData[1] = "|cffffd800" .. L["Random"]
ListData[2] = "|Cffffffaa{" .. L["click here for new selection"] .. "}" -- Must be capital |C
ListData[3] = "|cffffd800"
ListData[4] = "|cffffd800" .. L["Selection of music tracks"] -- Must be lower case |c
-- --- Stage 1: Find available random tracks ---
local attempt = 0 local attempt = 0
local randHash = {} local randHash = {}
local actualTracksFoundInThisPass = 0
local tempFoundTracks = {} -- Store found tracks temporarily
local targetMusicTracks = 45
local categoriesForRandom = {} local categoriesForRandom = {}
for _, catKey in ipairs({L["Zones"], L["Dungeons"], L["Various"], L["NEW"]}) do for _, catKey in ipairs({L["Zones"], L["Dungeons"], L["Various"], L["NEW"]}) do
if not tContains(randomBannedList, catKey) then if not tContains(randomBannedList, catKey) then
@@ -15839,7 +15838,7 @@ function LeaPlusLC:RunOnce()
end end
end end
while #ListData < 50 and attempt < 2000 do while #tempFoundTracks < targetMusicTracks and attempt < 2000 do
attempt = attempt + 1 attempt = attempt + 1
if #categoriesForRandom == 0 then break end if #categoriesForRandom == 0 then break end
local rCategory = categoriesForRandom[random(1, #categoriesForRandom)] local rCategory = categoriesForRandom[random(1, #categoriesForRandom)]
@@ -15849,24 +15848,23 @@ function LeaPlusLC:RunOnce()
local rZoneEntry = ZoneList[rCategory][rZoneIndex] local rZoneEntry = ZoneList[rCategory][rZoneIndex]
if rZoneEntry and rZoneEntry.tracks and #rZoneEntry.tracks > 0 then if rZoneEntry and rZoneEntry.tracks and #rZoneEntry.tracks > 0 then
local actualTracks = {} local playableTracksInZone = {}
for _, trackItem in ipairs(rZoneEntry.tracks) do for _, trackItem in ipairs(rZoneEntry.tracks) do
if type(trackItem) == "string" and strfind(trackItem, "#") and strfind(trackItem:lower(), ".mp3") then if type(trackItem) == "string" and strfind(trackItem, "#") and strfind(trackItem:lower(), ".mp3") then
tinsert(actualTracks, trackItem) tinsert(playableTracksInZone, trackItem)
end end
end end
if #actualTracks > 0 then if #playableTracksInZone > 0 then
local rTrack = actualTracks[random(1, #actualTracks)] local rTrack = playableTracksInZone[random(1, #playableTracksInZone)]
LeaPlusDB["ListenedTracks"] = LeaPlusDB["ListenedTracks"] or {} LeaPlusDB["ListenedTracks"] = LeaPlusDB["ListenedTracks"] or {}
if rTrack and rTrack ~= "" then if rTrack and rTrack ~= "" then
local trackID = GetTrackIDFromPath(rTrack) local trackID = GetTrackIDFromPath(rTrack)
if not LeaPlusDB["ListenedTracks"][trackID] and not randHash[trackID] then if not LeaPlusDB["ListenedTracks"][trackID] and not randHash[trackID] then
local zoneLabel = "|Cffffffaa" .. (rZoneEntry.zone or "Unknown Zone") .. " |r" .. rTrack local zoneLabel = "|Cffffffaa" .. (rZoneEntry.zone or "Unknown Zone") .. " |r" .. rTrack
if not tContains(ListData, zoneLabel) then tinsert(tempFoundTracks, zoneLabel)
tinsert(ListData, zoneLabel) randHash[trackID] = true
randHash[trackID] = true actualTracksFoundInThisPass = actualTracksFoundInThisPass + 1
end
end end
end end
end end
@@ -15874,13 +15872,33 @@ function LeaPlusLC:RunOnce()
end end
end end
-- MODIFICATION HERE: -- --- Stage 2: Construct ListData with headers and messages ---
if #ListData <= 4 then -- Accounts for the 4 header/info lines -- Always add the main headers
tinsert(ListData, "|cff999999(" .. L["You have listened to all available random tracks."] .. ")|r") tinsert(ListData, "|cffffd800" .. L["Random"])
-- Add the clickable "button" text tinsert(ListData, "|Cffffffaa{" .. L["click here for new selection"] .. "}")
local showResetButtonThreshold = 20
if actualTracksFoundInThisPass < showResetButtonThreshold then
-- Less than threshold, show the "few tracks" message and the reset button
tinsert(ListData, "|cff999999(" .. L["Few new random tracks remaining, or all listened."] .. ")|r")
tinsert(ListData, "|cff00ff00[ " .. L["Reset listened history and play new random"] .. " ]|r") tinsert(ListData, "|cff00ff00[ " .. L["Reset listened history and play new random"] .. " ]|r")
end end
-- Always add the separator and "Selection of music tracks" title AFTER potential reset button
tinsert(ListData, "|cffffd800") -- Separator
tinsert(ListData, "|cffffd800" .. L["Selection of music tracks"])
-- Add the found tracks
for _, track in ipairs(tempFoundTracks) do
tinsert(ListData, track)
end
-- If no actual tracks were added (after all headers and potential reset button)
if #tempFoundTracks == 0 then
tinsert(ListData, "|cff999999(" .. L["No unlistened tracks found for random selection."] .. ")|r")
end
UpdateList() UpdateList()
scrollFrame:SetVerticalScroll(0) scrollFrame:SetVerticalScroll(0)
end end
@@ -15910,86 +15928,112 @@ function LeaPlusLC:RunOnce()
button:SetNormalFontObject("GameFontHighlightLeft") button:SetNormalFontObject("GameFontHighlightLeft")
button:SetPoint("TOPLEFT", 246, -62 + -(i - 1) * 16 - 8) button:SetPoint("TOPLEFT", 246, -62 + -(i - 1) * 16 - 8)
-- Create highlight bar texture -- Create highlight bar texture (for hover)
button.t = button:CreateTexture(nil, "BACKGROUND") button.t = button:CreateTexture(nil, "BACKGROUND")
button.t:SetPoint("TOPLEFT", button, 0, 0) button.t:SetPoint("TOPLEFT", button, 0, 0)
button.t:SetSize(516, 16) button.t:SetSize(516, 16)
button.t:SetTexture(0.3, 0.3, 0.0, 0.8) -- Original yellow-ish hover
button.t:SetTexture(0.3, 0.3, 0.0, 0.8)
button.t:SetAlpha(0.7) button.t:SetAlpha(0.7)
button.t:Hide() button.t:Hide()
-- Create last playing highlight bar texture -- Create last playing highlight bar texture (for active track)
button.s = button:CreateTexture(nil, "BACKGROUND") button.s = button:CreateTexture(nil, "BACKGROUND")
button.s:SetPoint("TOPLEFT", button, 0, 0) button.s:SetPoint("TOPLEFT", button, 0, 0)
button.s:SetSize(516, 16) button.s:SetSize(516, 16)
button.s:SetVertexColor(0.3, 0.4, 0.00, 0.6) -- Darker green for active
button.s:SetVertexColor(0.3, 0.4, 0.00, 0.6)
button.s:Hide() button.s:Hide()
button:SetScript("OnEnter", function()
-- Highlight links only
if not string.match(button:GetText() or "", "|c") then
button.t:Show()
end
end)
button:SetScript("OnLeave", function()
button.t:Hide()
end)
button:RegisterForClicks("LeftButtonUp", "RightButtonUp") button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
-- Handler for playing next SoundKit track in playlist -- OnEnter / OnLeave for hover effects
uframe:SetScript("OnEvent", function(self, event, stoppedHandle) button:SetScript("OnEnter", function(self)
if event == "SOUNDKIT_FINISHED" then local currentText = self:GetText() -- Text without engine color codes
-- Do nothing if stopped sound kit handle doesnt match last played track handle local originalData = ListData[self.index] -- Raw data with our color codes
if LastMusicHandle and LastMusicHandle ~= stoppedHandle then
return local isResetButton = false
end if originalData and type(originalData) == "string" then
-- Reset track number if playlist has reached the end -- Check if this is the reset button by its specific color code and structure
if tracknumber == #playlist then if string.match(originalData, "^|cff00ff00%[") then -- Starts with green and opening bracket
tracknumber = 1 isResetButton = true
end
-- Play next track
PlayTrack()
elseif event == "LOADING_SCREEN_DISABLED" then
-- Restart player if it stopped between tracks during loading screen
if playlist and tracknumber and playlist[tracknumber] and not willPlay and not musicHandle then
tracknumber = tracknumber - 1
LibCompat.After(0.1, PlayTrack)
end end
end end
-- Determine if it's a header (more robustly)
local isHeader = false
if originalData and type(originalData) == "string" then
if string.match(originalData, "^|cffffd800") then -- Typical yellow header
isHeader = true
end
end
-- Apply hover:
if isResetButton then
-- Always show hover for the reset button
self.t:Show()
elseif originalData and type(originalData) == "string" and not isHeader then
-- For other strings that are not headers (e.g., tracks, movies, simple zone names for nav)
-- The 'currentText' check might be redundant if originalData string check is good enough
-- and we assume non-color-coded originalData items are hoverable.
self.t:Show()
elseif originalData and type(originalData) == "table" and originalData.zone then
-- For zone navigation items (which are tables), always show hover
self.t:Show()
end
-- Lines that are headers (and not the reset button) will not show the 't' hover.
end) end)
button:SetScript("OnLeave", function(self)
self.t:Hide()
end)
-- Click handler for track, zone and back button
-- Click handler for track, zone and back button -- Click handler for track, zone and back button
button:SetScript("OnClick", function(self, btn) button:SetScript("OnClick", function(self, btn)
if btn == "LeftButton" then if btn == "LeftButton" then
sBox:ClearFocus() sBox:ClearFocus()
local displayedItemText = self:GetText() local originalTrackItemFromListData = ListData[self.index] -- This is the raw data from ListData
local originalTrackItemFromListData = ListData[self.index]
-- Check if the clicked item is our "Reset" button -- 1. HIGHEST PRIORITY: Check for "{click here for new selection}"
if displayedItemText == "[ " .. L["Reset listened history and play new random"] .. " ]" then if originalTrackItemFromListData == "|Cffffffaa{" .. L["click here for new selection"] .. "}" then
LeaPlusDB["ListenedTracks"] = {} -- Wipe the listened tracks history
if LeaPlusLC and LeaPlusLC.Print then -- Ensure Print function is available
LeaPlusLC:Print(L["Listened tracks history reset. Generating new random list."])
else -- Fallback if LeaPlusLC.Print is not defined in this scope for some reason
print(L["Listened tracks history reset. Generating new random list."])
end
ShowRandomList() -- Regenerate and show a new random list
return -- Important: stop further processing for this click
end
if not displayedItemText or strfind(displayedItemText, "|c") then
return
end
if displayedItemText == "|Cffffffaa{" .. L["click here for new selection"] .. "}" then
ShowRandomList() ShowRandomList()
return return
elseif originalTrackItemFromListData and type(originalTrackItemFromListData) == "string" and strfind(originalTrackItemFromListData, "#") then end
-- Playable track
-- 2. NEXT PRIORITY: Check for the "Reset" button
if originalTrackItemFromListData == "|cff00ff00[ " .. L["Reset listened history and play new random"] .. " ]|r" then
LeaPlusDB["ListenedTracks"] = {}
if LeaPlusLC and LeaPlusLC.Print then
LeaPlusLC:Print(L["Listened tracks history reset. Generating new random list."])
else
print(L["Listened tracks history reset. Generating new random list."])
end
ShowRandomList()
return
end
-- 3. NEXT PRIORITY: Check for INFORMATIONAL MESSAGES (non-clickable)
if originalTrackItemFromListData == ("|cff999999(" .. L["Few new random tracks remaining, or all listened."] .. ")|r") or
originalTrackItemFromListData == ("|cff999999(" .. L["No unlistened tracks found for random selection."] .. ")|r") or
originalTrackItemFromListData == ("|cffffffaa{" .. L["enter zone or track name"] .. "}") or
(type(originalTrackItemFromListData) == "string" and (string.match(originalTrackItemFromListData, "^|cffffffaa{.*results}") or string.match(originalTrackItemFromListData, "^|cffffffaa{.*result}"))) then -- Search results count
return -- Do nothing for these lines
end
-- 4. If it's a header (usually starts with a color code in original data) and not handled above, do nothing.
if not originalTrackItemFromListData or
(type(originalTrackItemFromListData) == "string" and
(string.match(originalTrackItemFromListData, "^|cffffd800") ) and -- Main yellow headers
not strfind(originalTrackItemFromListData, "#") and -- Make sure it's not a track
not (strfind(originalTrackItemFromListData, "|r") and not strfind(originalTrackItemFromListData, "^|cff999999")) -- Make sure it's not a movie or our grey info messages
) then
return
end
-- 5. If it's a PLAYABLE TRACK (contains # for duration)
if originalTrackItemFromListData and type(originalTrackItemFromListData) == "string" and strfind(originalTrackItemFromListData, "#") then
-- Playable track logic...
if GetCVar("Sound_EnableAllSound") == "0" then if GetCVar("Sound_EnableAllSound") == "0" then
SetCVar("Sound_EnableAllSound", "1") SetCVar("Sound_EnableAllSound", "1")
end end
@@ -16002,9 +16046,9 @@ function LeaPlusLC:RunOnce()
wipe(playlist) wipe(playlist)
local listDataIndexForClickedItem = 0 local listDataIndexForClickedItem = 0
for i = 1, #ListData do for i_idx = 1, #ListData do
if ListData[i] == originalTrackItemFromListData then if ListData[i_idx] == originalTrackItemFromListData then
listDataIndexForClickedItem = i listDataIndexForClickedItem = i_idx
break break
end end
end end
@@ -16017,14 +16061,14 @@ function LeaPlusLC:RunOnce()
return return
end end
else else
for i = listDataIndexForClickedItem, #ListData do for i_idx = listDataIndexForClickedItem, #ListData do
local item = ListData[i] local item = ListData[i_idx]
if item and type(item) == "string" and strfind(item, "#") then if item and type(item) == "string" and strfind(item, "#") then
tinsert(playlist, item) tinsert(playlist, item)
end end
end end
for i = 1, listDataIndexForClickedItem - 1 do for i_idx = 1, listDataIndexForClickedItem - 1 do
local item = ListData[i] local item = ListData[i_idx]
if item and type(item) == "string" and strfind(item, "#") then if item and type(item) == "string" and strfind(item, "#") then
tinsert(playlist, item) tinsert(playlist, item)
end end
@@ -16039,9 +16083,14 @@ function LeaPlusLC:RunOnce()
LeaPlusLC:LockItem(stopBtn, false) LeaPlusLC:LockItem(stopBtn, false)
if ListData[1] == "|cffffd800" .. L["Random"] then if ListData[1] == "|cffffd800" .. L["Random"] then
TempFolder = L["Random"] TempFolder = L["Random"]
end elseif ListData[1] == "|cffffd800" .. L["Search"] then
if ListData[1] == "|cffffd800" .. L["Search"] then
TempFolder = L["Search"] TempFolder = L["Search"]
else
local currentCategoryHeader = ListData[1]
if currentCategoryHeader and type(currentCategoryHeader) == "string" then
local categoryName = currentCategoryHeader:match("|c%x%x%x%x%x%x%x%x(.-):") or currentCategoryHeader:match("|c%x%x%x%x%x%x%x%x(.*)")
if categoryName then TempFolder = strtrim(categoryName) else TempFolder = "Unknown" end
end
end end
tracknumber = 1 tracknumber = 1
@@ -16054,53 +16103,42 @@ function LeaPlusLC:RunOnce()
uframe:RegisterEvent("LOADING_SCREEN_DISABLED") uframe:RegisterEvent("LOADING_SCREEN_DISABLED")
return return
-- 6. If it's a MOVIE (contains |r but no #, and not one of our special |r lines already handled)
elseif originalTrackItemFromListData and type(originalTrackItemFromListData) == "string" and strfind(originalTrackItemFromListData, "|r") and not strfind(originalTrackItemFromListData, "#") then elseif originalTrackItemFromListData and type(originalTrackItemFromListData) == "string" and strfind(originalTrackItemFromListData, "|r") and not strfind(originalTrackItemFromListData, "#") then
-- MOVIE section (Minimal with "Not Found" message) -- MOVIE section
stopBtn:Click() -- Stop any currently playing music stopBtn:Click()
local displayNamePart, identifierPart = originalTrackItemFromListData:match("^(.-)|r(.*)$") local displayNamePart, identifierPart = originalTrackItemFromListData:match("^(.-)|r(.*)$")
identifierPart = identifierPart and strtrim(identifierPart) or "" identifierPart = identifierPart and strtrim(identifierPart) or ""
displayNamePart = displayNamePart and strtrim(displayNamePart) or L["Unknown Movie"] -- Get display name for message displayNamePart = displayNamePart and strtrim(displayNamePart) or L["Unknown Movie"]
-- Check if the resolved path is empty or our "nil_path_" placeholder
if identifierPart == "" or string.find(identifierPart, "nil_path_") then if identifierPart == "" or string.find(identifierPart, "nil_path_") then
-- Use your addon's standard print function (LeaPlusLC:Print)
-- and try to provide the name of the movie the user clicked on.
LeaPlusLC:Print(string.format(L["Movie not found: %s"], displayNamePart)) LeaPlusLC:Print(string.format(L["Movie not found: %s"], displayNamePart))
return return
end end
local movieVolume = 150
local movieVolume = 150 -- Fixed default volume
if _G.MovieFrame_PlayMovie and _G.MovieFrame then if _G.MovieFrame_PlayMovie and _G.MovieFrame then
_G.MovieFrame_PlayMovie(_G.MovieFrame, identifierPart:gsub("/", "\\"), movieVolume) _G.MovieFrame_PlayMovie(_G.MovieFrame, identifierPart:gsub("/", "\\"), movieVolume)
-- else
-- If MovieFrame_PlayMovie system itself is missing, playback will silently fail here.
-- This is a more fundamental addon issue than a single missing movie.
-- Optionally, you could add a developer-level print here for debugging if MovieFrame isn't loaded.
-- print("Developer: MovieFrame_PlayMovie or MovieFrame is nil.")
end end
return return
-- ... (rest of your OnClick logic for zone navigation, etc.)
else else
-- Zone or other navigation -- 7. Zone or other navigation (simple string or table with .zone)
ZonePage = scrollFrame:GetVerticalScroll() ZonePage = scrollFrame:GetVerticalScroll()
local clickedZoneName = "" local clickedZoneName = ""
if type(originalTrackItemFromListData) == "table" and originalTrackItemFromListData.zone then if type(originalTrackItemFromListData) == "table" and originalTrackItemFromListData.zone then
clickedZoneName = originalTrackItemFromListData.zone clickedZoneName = originalTrackItemFromListData.zone
elseif type(originalTrackItemFromListData) == "string" and not strfind(originalTrackItemFromListData, "|c") then elseif type(originalTrackItemFromListData) == "string" then
clickedZoneName = originalTrackItemFromListData clickedZoneName = originalTrackItemFromListData
end end
if clickedZoneName ~= "" then if clickedZoneName ~= "" then
local foundZone = false local foundZone = false
for q_cat_key, w_category_list in pairs(ZoneList) do for categoryName, categoryContentList in pairs(ZoneList) do
if ZoneList[w_category_list] then if type(categoryContentList) == "table" then
for k_zone_idx, v_zone_entry in pairs(ZoneList[w_category_list]) do for _, zoneEntryInList in ipairs(categoryContentList) do
if v_zone_entry.zone == clickedZoneName then if type(zoneEntryInList) == "table" and zoneEntryInList.zone == clickedZoneName then
TempFolder = v_zone_entry.zone TempFolder = zoneEntryInList.zone
LeaPlusDB["MusicZone"] = v_zone_entry.zone LeaPlusDB["MusicZone"] = zoneEntryInList.zone
ListData = v_zone_entry.tracks ListData = zoneEntryInList.tracks
UpdateList() UpdateList()
scrollFrame:SetVerticalScroll(0) scrollFrame:SetVerticalScroll(0)
foundZone = true foundZone = true
@@ -16108,8 +16146,16 @@ function LeaPlusLC:RunOnce()
end end
end end
end end
if foundZone then if foundZone then break end
break end
if not foundZone then
if ZoneList[clickedZoneName] and type(ZoneList[clickedZoneName]) == "table" then
TempFolder = clickedZoneName
LeaPlusDB["MusicContinent"] = clickedZoneName
ListData = ZoneList[clickedZoneName]
UpdateList()
scrollFrame:SetVerticalScroll(0)
-- foundZone = true -- Not strictly needed here as we'd return anyway
end end
end end
end end