您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Filter by post, repost, and playlists for a better feed experience
- // ==UserScript==
- // @name SoundCloud Feed Control
- // @version 2.002
- // @license MIT
- // @author nov0id
- // @description Filter by post, repost, and playlists for a better feed experience
- // @match *://soundcloud.com/feed
- // @grant none
- // @namespace https://rainbowlabllc.com/
- // ==/UserScript==
- (function() {
- 'use strict';
- // Function to get setting for the current tab
- function getTabSetting(key, defaultValue) {
- return sessionStorage.getItem(key) !== null
- ? JSON.parse(sessionStorage.getItem(key))
- : defaultValue;
- }
- // Function to set setting for the current tab
- function setTabSetting(key, value) {
- sessionStorage.setItem(key, JSON.stringify(value));
- }
- // Default settings per tab
- const settings = {
- filterPosts: getTabSetting('filterPosts', false),
- filterPlaylists: getTabSetting('filterPlaylists', false),
- filterReposts: getTabSetting('filterReposts', false)
- };
- function createUI() {
- let panel = document.createElement('div');
- panel.id = 'sc-filter-panel';
- panel.innerHTML = `
- <style>
- #sc-filter-panel {
- position: fixed;
- top: 50px;
- left: -200px;
- width: 200px;
- background: rgba(0, 0, 0, 0.6);
- padding: 15px;
- border-radius: 0 10px 10px 0;
- z-index: 9999;
- color: white;
- font-family: 'Segoe UI', sans-serif;
- font-size: 14px;
- transition: right 0.3s ease-in-out, background 0.2s ease-in-out;
- }
- #sc-filter-panel:hover {
- left: 0;
- background: rgba(0, 0, 0, 0.9);
- }
- .sc-filter-slider {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 10px;
- font-weight: normal;
- opacity: 0;
- transition: opacity 0.3s ease-in-out;
- }
- #sc-filter-panel:hover .sc-filter-slider {
- opacity: 1;
- }
- .sc-filter-slider input {
- width: 18px;
- height: 18px;
- }
- .sc-filter-title {
- text-align: center;
- font-size: 16px;
- margin-bottom: 10px;
- font-weight: bold;
- text-transform: uppercase;
- letter-spacing: 1px;
- opacity: 0;
- transition: opacity 0.3s ease-in-out;
- }
- #sc-filter-panel:hover .sc-filter-title {
- opacity: 1;
- }
- </style>
- <div class='sc-filter-title'>Feed Filter</div>
- <div class='sc-filter-slider'>
- <label>Filter Posts</label>
- <input type='checkbox' id='filterPosts' ${settings.filterPosts ? 'checked' : ''}>
- </div>
- <div class='sc-filter-slider'>
- <label>Filter Playlists</label>
- <input type='checkbox' id='filterPlaylists' ${settings.filterPlaylists ? 'checked' : ''}>
- </div>
- <div class='sc-filter-slider'>
- <label>Filter Reposts</label>
- <input type='checkbox' id='filterReposts' ${settings.filterReposts ? 'checked' : ''}>
- </div>
- `;
- document.body.appendChild(panel);
- document.getElementById('filterPosts').addEventListener('change', () => toggleSetting('filterPosts'));
- document.getElementById('filterPlaylists').addEventListener('change', () => toggleSetting('filterPlaylists'));
- document.getElementById('filterReposts').addEventListener('change', () => toggleSetting('filterReposts'));
- }
- function toggleSetting(key) {
- settings[key] = !settings[key];
- setTabSetting(key, settings[key]); // Store setting per tab
- filterFeed();
- }
- function filterFeed() {
- document.querySelectorAll('.soundList__item').forEach((element) => {
- const context = element.querySelector('.sound.streamContext');
- if (context) {
- let label = context.getAttribute('aria-label')?.toLowerCase();
- if (label.includes('reposted') && settings.filterReposts) {
- element.remove();
- } else if (label.includes('playlist') && settings.filterPlaylists) {
- element.remove();
- } else if (!label.includes('playlist') && !label.includes('reposted') && settings.filterPosts) {
- element.remove();
- }
- }
- });
- }
- // Initialize UI and filter logic
- createUI();
- filterFeed();
- // Observe DOM for dynamically added elements
- const observer = new MutationObserver(filterFeed);
- observer.observe(document.body, { childList: true, subtree: true });
- })();