Last active
April 26, 2025 08:23
-
-
Save lunamoth/9fe3255283371f3c6370159b5dcbee0f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Chzzk Sort by Viewers (Following Live) v1.6 | |
// @name:ko 치지직 팔로잉 라이브 시청자 순 자동 정렬 v1.6 | |
// @namespace http://tampermonkey.net/ | |
// @version 1.6 | |
// @description Automatically sorts by "Most Viewers" on Chzzk Following Live page, hiding the dropdown flicker. | |
// @description:ko 치지직 팔로잉 라이브 페이지의 정렬 순서를 '시청자 많은 순'으로 자동 변경하고, 드롭다운 깜빡임을 숨깁니다. | |
// @author Your Name (or AI) | |
// @match https://chzzk.naver.com/following?tab=LIVE | |
// @grant GM_addStyle | |
// @license MIT | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
const TARGET_SORT_TEXT = "시청자 많은 순"; | |
const DROPDOWN_SELECTOR = "button#live-order"; | |
const OPTION_XPATH = `//button[contains(@class, 'selectbox_option__lsIDs') and normalize-space(.)='${TARGET_SORT_TEXT}']`; | |
// 드롭다운 메뉴 리스트의 ID (button의 aria-controls 값과 일치) | |
const DROPDOWN_LIST_ID = "selectbox-listbox"; | |
const HIDE_STYLE_ID = "chzzk-hide-dropdown-style"; | |
const MAX_MAIN_ATTEMPTS = 40; | |
const CHECK_INTERVAL = 500; | |
const MAX_OPTION_ATTEMPTS = 10; | |
const OPTION_CHECK_INTERVAL = 250; | |
let mainAttemptCount = 0; | |
let scriptExecuted = false; | |
let clickInProgress = false; | |
console.log("[Chzzk Sort Script v1.6] 스크립트 시작 (드롭다운 숨김)"); | |
// --- Helper Function to Hide/Show Dropdown List --- | |
function setDropdownVisibility(visible) { | |
let styleElement = document.getElementById(HIDE_STYLE_ID); | |
if (!visible) { | |
// 숨기기: display: none !important; 스타일 추가 | |
if (!styleElement) { | |
GM_addStyle(` | |
#${DROPDOWN_LIST_ID}.selectbox_layer__Wsk6t { | |
display: none !important; | |
opacity: 0 !important; /* 추가적으로 투명하게 */ | |
visibility: hidden !important; /* 추가적으로 숨김 */ | |
} | |
`); | |
// Add an ID to the added style tag for later removal if needed, though GM_addStyle might not allow this easily. | |
// For simplicity, we'll just add it. Re-adding won't hurt much. | |
} | |
} else { | |
// 보이기: 추가했던 스타일 제거 (주의: GM_addStyle로 추가한 스타일은 직접 제거하기 어려움) | |
// 가장 간단한 방법은 그냥 두는 것입니다. 어차피 클릭 후엔 알아서 닫히므로 큰 문제는 없습니다. | |
// 꼭 필요하다면, 직접 <style> 태그를 만들고 ID를 부여해서 관리해야 합니다. | |
// 여기서는 숨기는 동작만 명시적으로 합니다. | |
console.log("[Chzzk Sort Script] 드롭다운 스타일 복원 시도 (실제로는 복원 로직 생략)"); | |
} | |
} | |
const mainIntervalId = setInterval(() => { | |
if (scriptExecuted) { | |
clearInterval(mainIntervalId); | |
return; | |
} | |
mainAttemptCount++; | |
const dropdownButton = document.querySelector(DROPDOWN_SELECTOR); | |
if (dropdownButton) { | |
const currentSortElement = dropdownButton.querySelector('.selectbox_name__fdZrs'); | |
const currentSort = currentSortElement ? currentSortElement.textContent.trim() : null; | |
const isExpanded = dropdownButton.getAttribute('aria-expanded') === 'true'; | |
if (currentSort === TARGET_SORT_TEXT) { | |
console.log(`[Chzzk Sort Script] 이미 '${TARGET_SORT_TEXT}'으로 정렬됨. 중지.`); | |
scriptExecuted = true; | |
clearInterval(mainIntervalId); | |
return; | |
} | |
if (currentSort && currentSort !== TARGET_SORT_TEXT && !isExpanded && !clickInProgress) { | |
console.log(`[Chzzk Sort Script] '${TARGET_SORT_TEXT}'으로 변경 시작. (드롭다운 숨김)`); | |
clickInProgress = true; | |
setDropdownVisibility(false); // *** 드롭다운 리스트 숨기기 *** | |
// 약간의 지연 후 클릭 (스타일 적용 시간) | |
setTimeout(() => { | |
dropdownButton.click(); // 드롭다운 열기 (숨겨진 상태에서) | |
let optionAttemptCount = 0; | |
const optionCheckIntervalId = setInterval(() => { | |
const sortOption = document.evaluate(OPTION_XPATH, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; | |
if (sortOption) { | |
console.log(`[Chzzk Sort Script] '${TARGET_SORT_TEXT}' 옵션 찾음! 클릭 시도.`); | |
clearInterval(optionCheckIntervalId); | |
sortOption.click(); // 옵션 클릭 (숨겨진 상태에서) | |
scriptExecuted = true; | |
console.log("[Chzzk Sort Script] 정렬 순서 변경 완료."); | |
// 성공 후 정리 | |
// setDropdownVisibility(true); // 스타일 복원 (선택적) | |
clickInProgress = false; | |
clearInterval(mainIntervalId); // 메인 인터벌 중지 | |
} else { | |
optionAttemptCount++; | |
if (optionAttemptCount >= MAX_OPTION_ATTEMPTS) { | |
clearInterval(optionCheckIntervalId); | |
console.error(`[Chzzk Sort Script] '${TARGET_SORT_TEXT}' 옵션을 시간 내에 찾지 못했습니다.`); | |
// 실패 시 정리 | |
// setDropdownVisibility(true); // 스타일 복원 | |
clickInProgress = false; | |
// 실패 시 드롭다운 닫기 시도 | |
if (dropdownButton.getAttribute('aria-expanded') === 'true') { | |
dropdownButton.click(); | |
} | |
} | |
} | |
}, OPTION_CHECK_INTERVAL); | |
}, 50); // 스타일 적용 및 클릭 사이 아주 짧은 지연 | |
} else if (currentSort && currentSort !== TARGET_SORT_TEXT && isExpanded && !clickInProgress) { | |
console.log("[Chzzk Sort Script] 드롭다운이 외부 요인으로 열려있음. 다음 확인까지 대기."); | |
} | |
} else if (mainAttemptCount % 5 === 0) { | |
console.log(`[Chzzk Sort Script] 정렬 버튼(#live-order) 아직 못 찾음. 시도: ${mainAttemptCount}`); | |
} | |
if (mainAttemptCount >= MAX_MAIN_ATTEMPTS && !scriptExecuted) { | |
console.error("[Chzzk Sort Script] 최대 시도 횟수 도달. 중지."); | |
// setDropdownVisibility(true); // 실패 시 스타일 복원 시도 | |
clearInterval(mainIntervalId); | |
} | |
}, CHECK_INTERVAL); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment