Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add Ability to Hide Unwanted Page Elements #481

Merged
merged 18 commits into from
Apr 30, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG-nightly.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Added a tooltip to show the full message when hovering over replies in chat
- Fixed tooltips of nametag paints appearing even if they are disabled
- Added a "Site Layout" menu where certain features of the Twitch website can be hidden

### Version 3.0.6.1000

Expand Down
28,995 changes: 28,994 additions & 1 deletion public/assets/emoji/emoji.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/assets/svg/icons/IconForSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import GearsIcon from "./GearsIcon.vue";
import HomeIcon from "./HomeIcon.vue";
import PaintIcon from "./PaintIcon.vue";
import PuzzlePieceIcon from "./PuzzlePieceIcon.vue";
import SiteLayoutIcon from "./SiteLayoutIcon.vue";
import TvIcon from "./TvIcon.vue";
import YouTubeIcon from "./YouTubeIcon.vue";

Expand All @@ -29,6 +30,7 @@ const c = {
General: GearsIcon,
Channel: TvIcon,
Compatibility: PuzzlePieceIcon,
"Site Layout": SiteLayoutIcon,

"Enable YouTube": YouTubeIcon,
}[props.name];
Expand Down
8 changes: 8 additions & 0 deletions src/assets/svg/icons/SiteLayoutIcon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" fill="currentColor">
<!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
<path
d="M64 0C28.7 0 0 28.7 0 64V352c0 35.3 28.7 64 64 64H240l-10.7 32H160c-17.7 0-32 14.3-32 32s14.3 32 32 32H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H346.7L336 416H512c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H64zM512 64V352H64V64H512z"
/>
</svg>
</template>
233 changes: 233 additions & 0 deletions src/site/twitch.tv/modules/hidden-elements/HiddenElementsModule.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
<template />

<script setup lang="ts">
import { onMounted, watch } from "vue";
import { declareModule } from "@/composable/useModule";
import { declareConfig } from "@/composable/useSettings";
import { hiddenElementSettings } from "./hiddenElements";

const { markAsReady } = declareModule("hidden-elements", {
name: "Hidden Elements",
depends_on: [],
});

function updateHiddenElements(): void {
hiddenElementSettings.forEach((setting) => {
document.body.classList.toggle(setting.class, setting.isHidden.value);
});
}

onMounted(() => {
updateHiddenElements();

watch(
() => hiddenElementSettings,
() => {
updateHiddenElements();
},
{ deep: true },
);
});

markAsReady();
</script>

<script lang="ts">
/**
* Settings configuration for hidden elements feature
*/
export const config = [
// Chat elements
declareConfig("hide.channel_leaderboard", "TOGGLE", {
path: ["Site Layout", "Chat"],
label: "Hide Channel Leaderboard",
hint: "If checked, the channel leaderboard at the top of chat will be hidden",
defaultValue: false,
}),
declareConfig("hide.chat_input_box", "TOGGLE", {
path: ["Site Layout", "Chat"],
label: "Hide Chat Input Box",
hint: "If checked, the 'Send a message' chatbox will be hidden (WARNING! the 7tv icon will disappear but can be accessed again at the top right of Twitch)",
defaultValue: false,
}),
declareConfig("hide.buttons_below_chatbox", "TOGGLE", {
path: ["Site Layout", "Chat"],
label: "Hide Buttons Below Chatbox",
hint: "If checked, the buttons below the chatbox will be hidden (such as channel points, settings, 'chat', etc.)",
defaultValue: false,
}),
declareConfig("hide.stream_chat_bar", "TOGGLE", {
path: ["Site Layout", "Chat"],
label: "Hide Stream Chat Bar",
hint: "If checked, the bar above chat which says 'Stream Chat' will be hidden",
defaultValue: false,
}),
declareConfig("hide.community_highlights", "TOGGLE", {
path: ["Site Layout", "Chat"],
label: "Hide Community Highlights",
hint: "If checked, community highlights at the top of chat will be hidden (such as hype trains, pinned messages, drops, etc.)",
defaultValue: false,
}),
// Main page elements (Twitch Features)
declareConfig("hide.react_buttons", "TOGGLE", {
path: ["Site Layout", "Twitch Features"],
label: "Hide React Buttons",
hint: "If checked, the 'React' buttons will be hidden",
defaultValue: false,
}),
declareConfig("hide.bits_buttons", "TOGGLE", {
path: ["Site Layout", "Twitch Features"],
label: "Hide Bits Buttons",
hint: "If checked, the 'Bits' related buttons will be hidden",
defaultValue: false,
}),
declareConfig("hide.subscribe_button", "TOGGLE", {
path: ["Site Layout", "Twitch Features"],
label: "Hide Subscribe Button",
hint: "If checked, the 'Subscribe' button will be hidden (includes 'gift a sub' button)",
defaultValue: false,
}),
declareConfig("hide.prime_offers", "TOGGLE", {
path: ["Site Layout", "Twitch Features"],
label: "Hide Prime Offers",
hint: "If checked, the 'Prime Offers' button on the top bar will be hidden",
defaultValue: false,
}),
declareConfig("hide.unfollow_button", "TOGGLE", {
path: ["Site Layout", "Twitch Features"],
label: "Hide Unfollow Button",
hint: "If checked, the 'Unfollow' button will be hidden (under stream and in theater mode)",
defaultValue: false,
}),
declareConfig("hide.live_notification_button", "TOGGLE", {
path: ["Site Layout", "Twitch Features"],
label: "Hide Live Notification Button",
hint: "If checked, the 'Turn notifications off/on' button under the stream will be hidden",
defaultValue: false,
}),
// Side bar elements
declareConfig("hide.recommended_channels", "TOGGLE", {
path: ["Site Layout", "Side Bar"],
label: "Hide Recommended Channels",
hint: "If checked, the 'recommended channels' section of the side bar will be hidden",
defaultValue: false,
}),
declareConfig("hide.viewers_also_watch", "TOGGLE", {
path: ["Site Layout", "Side Bar"],
label: "Hide Viewers Also Watch",
hint: "If checked, the 'viewers also watch' section of the side bar will be hidden",
defaultValue: false,
}),
// Player elements
declareConfig("hide.top_bar_of_stream", "TOGGLE", {
path: ["Site Layout", "Video Player"],
label: "Hide Top Bar of Stream",
hint: "If checked, the top bar of the stream which shows on hover will be hidden",
defaultValue: false,
}),
declareConfig("hide.player_controls", "TOGGLE", {
path: ["Site Layout", "Video Player"],
label: "Hide Player Controls",
hint: "If checked, the controls shown at the bottom of a stream on hover will be hidden",
defaultValue: false,
}),
];
</script>

<style lang="scss">
.seventv-hide-leaderboard {
div[data-test-selector="channel-leaderboard-container"] {
display: none !important;
}
}

.seventv-hide-buttons-below-chatbox {
div[data-test-selector="chat-input-buttons-container"] {
display: none !important;
}
}

.seventv-hide-stream-chat-bar {
button[data-a-target="right-column__toggle-collapse-btn"],
div[class$="stream-chat-header"] {
display: none !important;
}
}

.seventv-hide-react-buttons {
div[class$="theatre-social-panel"]
button[class="ScCoreButton-sc-ocjdkq-0 ScCoreButtonSecondary-sc-ocjdkq-2 ibtYyW bTKXKk"],
div[data-target="channel-header-right"]
button[class="ScCoreButton-sc-ocjdkq-0 ScCoreButtonText-sc-ocjdkq-3 ibtYyW jYfhUy"] {
display: none !important;
}
}

.seventv-hide-bits-buttons {
button[data-a-target="bits-button"],
button[data-a-target="top-nav-get-bits-button"] {
display: none !important;
}
}

.seventv-hide-top-bar-of-stream {
div[class$="top-bar"] {
display: none !important;
}
}

.seventv-hide-player-controls {
div[data-a-target="player-controls"] {
display: none !important;
}
}

.seventv-hide-community-highlights {
div[class="Layout-sc-1xcs6mc-0 kAIqwe"] {
display: none !important;
}
}

.seventv-hide-recommended-channels {
#side-nav > *:nth-child(1) > *:nth-child(1) > *:nth-child(3) {
display: none !important;
}
}

.seventv-hide-viewers-also-watch {
#side-nav > *:nth-child(1) > *:nth-child(1) > *:nth-child(4) {
display: none !important;
}
}

.seventv-hide-prime-offers {
div[class$="top-nav__prime"] {
display: none !important;
}
}

.seventv-hide-unfollow-button {
button[data-test-selector="unfollow-button"] {
display: none !important;
}
}

.seventv-hide-live-notification-button {
button[data-a-target="notifications-toggle"] {
display: none !important;
}
}

.seventv-hide-subscribe-button {
button[data-a-target="subscribed-button"],
button[data-a-target="subscribe-button"] {
display: none !important;
}
}

.seventv-hide-chat-input-box {
div[class$="chat-input__textarea"] {
display: none !important;
}
}
</style>
36 changes: 36 additions & 0 deletions src/site/twitch.tv/modules/hidden-elements/hiddenElements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Ref } from "vue";
import { useConfig } from "@/composable/useSettings";

const hideLeaderboard = useConfig<boolean>("hide.channel_leaderboard");
const hideButtonsBelowChatbox = useConfig<boolean>("hide.buttons_below_chatbox");
const hideStreamChatBar = useConfig<boolean>("hide.stream_chat_bar");
const hideReactButtons = useConfig<boolean>("hide.react_buttons");
const hideBitsButtons = useConfig<boolean>("hide.bits_buttons");
const hideTopBarOfStream = useConfig<boolean>("hide.top_bar_of_stream");
const hidePlayerControls = useConfig<boolean>("hide.player_controls");
const hideCommunityHighlights = useConfig<boolean>("hide.community_highlights");
const hideRecommendedChannels = useConfig<boolean>("hide.recommended_channels");
const hideViewersAlsoWatch = useConfig<boolean>("hide.viewers_also_watch");
const hidePrimeOffers = useConfig<boolean>("hide.prime_offers");
const hideUnfollowButton = useConfig<boolean>("hide.unfollow_button");
const hideLiveNotificationButton = useConfig<boolean>("hide.live_notification_button");
const hideSubscribeButton = useConfig<boolean>("hide.subscribe_button");
const hideChatInputBox = useConfig<boolean>("hide.chat_input_box");

export const hiddenElementSettings: Array<{ class: string; isHidden: Ref<boolean> }> = [
{ class: "seventv-hide-leaderboard", isHidden: hideLeaderboard },
{ class: "seventv-hide-buttons-below-chatbox", isHidden: hideButtonsBelowChatbox },
{ class: "seventv-hide-stream-chat-bar", isHidden: hideStreamChatBar },
{ class: "seventv-hide-react-buttons", isHidden: hideReactButtons },
{ class: "seventv-hide-bits-buttons", isHidden: hideBitsButtons },
{ class: "seventv-hide-top-bar-of-stream", isHidden: hideTopBarOfStream },
{ class: "seventv-hide-player-controls", isHidden: hidePlayerControls },
{ class: "seventv-hide-community-highlights", isHidden: hideCommunityHighlights },
{ class: "seventv-hide-recommended-channels", isHidden: hideRecommendedChannels },
{ class: "seventv-hide-viewers-also-watch", isHidden: hideViewersAlsoWatch },
{ class: "seventv-hide-prime-offers", isHidden: hidePrimeOffers },
{ class: "seventv-hide-unfollow-button", isHidden: hideUnfollowButton },
{ class: "seventv-hide-live-notification-button", isHidden: hideLiveNotificationButton },
{ class: "seventv-hide-subscribe-button", isHidden: hideSubscribeButton },
{ class: "seventv-hide-chat-input-box", isHidden: hideChatInputBox },
];
2 changes: 2 additions & 0 deletions src/types/tw.module.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type ChatInputModuleVue from "@/site/twitch.tv/modules/chat-input/ChatInp
import type ChatVodModuleVue from "@/site/twitch.tv/modules/chat-vod/ChatVodModule.vue";
import type ChatModuleVue from "@/site/twitch.tv/modules/chat/ChatModule.vue";
import type EmoteMenuModuleVue from "@/site/twitch.tv/modules/emote-menu/EmoteMenuModule.vue";
import type HiddenElementsModuleVue from "@/site/twitch.tv/modules/hidden-elements/HiddenElementsModule.vue";
import type ModLogsModule from "@/site/twitch.tv/modules/mod-logs/ModLogsModule.vue";
import type SettingsModuleVue from "@/site/twitch.tv/modules/settings/SettingsModule.vue";
import type SidebarPreviewsModuleVue from "@/site/twitch.tv/modules/sidebar-previews/SidebarPreviewsModule.vue";
Expand All @@ -16,6 +17,7 @@ declare type TwModuleComponentMap = {
"chat-input": typeof ChatInputModuleVue;
"chat-vod": typeof ChatVodModuleVue;
"emote-menu": typeof EmoteMenuModuleVue;
"hidden-elements": typeof HiddenElementsModuleVue;
"mod-logs": typeof ModLogsModule;
"sidebar-previews": typeof SidebarPreviewsModuleVue;
autoclaim: typeof AutoclaimModuleVue;
Expand Down