Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion src/assets/style/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ body[theme="dark"] {
--seventv-background-transparent-2: #131313;
--seventv-background-transparent-3: #111;
--seventv-border-transparent-1: #ffffff1a;
--seventv-background-shade-1: #161616;
--seventv-background-shade-1: #171717;
--seventv-background-shade-2: #131313;
--seventv-background-shade-3: #111;
--seventv-primary: #29b6f6;
Expand Down
31 changes: 24 additions & 7 deletions src/site/global/settings/CategoryDropdown.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="seventv-settings-category" :open="open">
<div class="seventv-settings-category" :in-view="ctx.category === category" :open="open">
<div tabindex="0" class="settings-category-header" @click="onCategoryClick()">
<div class="seventv-settings-category-icon">
<IconForSettings :name="category" />
Expand All @@ -16,7 +16,14 @@
</div>
<div v-if="showSubCategories" class="seventv-settings-category-dropdown seventv-settings-expanded">
<template v-for="s of subCategories" :key="s">
<div v-if="s" class="seventv-settings-subcategory" @click="emit('open-subcategory', s)">
<div
v-if="s"
class="seventv-settings-subcategory"
:class="{
intersect: ctx.intersectingSubcategory === s,
}"
@click="emit('open-subcategory', s)"
>
{{ s }}
</div>
</template>
Expand All @@ -27,6 +34,7 @@
import { ref } from "vue";
import DropdownIcon from "@/assets/svg/icons/DropdownIcon.vue";
import IconForSettings from "@/assets/svg/icons/IconForSettings.vue";
import { useSettingsMenu } from "./Settings";

const props = defineProps<{
category: string;
Expand All @@ -39,6 +47,7 @@ const emit = defineEmits<{
(event: "open-subcategory", subcategory: string): void;
}>();

const ctx = useSettingsMenu();
const open = ref(false);

function onCategoryClick(): void {
Expand All @@ -53,19 +62,20 @@ function onCategoryClick(): void {
margin: 0.5rem;

.settings-category-header {
display: flex;
cursor: pointer;
display: grid;
grid-template-columns: 3rem 1fr 3rem;
border-radius: 0.4rem;
height: 4rem;
padding: 0.5rem;
padding: 0.25rem;
column-gap: 0.5rem;
align-items: center;
font-weight: 600;
font-size: 1.6rem;

&:hover,
&:focus-within {
background-color: hsla(0deg, 0%, 30%, 32%);
background-color: hsla(0deg, 0%, 20%, 10%);
}

svg {
Expand All @@ -74,6 +84,10 @@ function onCategoryClick(): void {
}
}

&[in-view="true"] > .settings-category-header {
background-color: hsla(0deg, 0, 20%, 20%);
}

.seventv-settings-category-icon {
display: flex;
align-items: center;
Expand Down Expand Up @@ -110,10 +124,13 @@ function onCategoryClick(): void {
display: flex;
cursor: pointer;
height: 3rem;
padding: 0.5rem 4rem;
border-radius: 0.4rem;
padding: 0.5rem 3rem;
border-radius: 0.25rem;

&:hover {
background-color: hsla(0deg, 0%, 20%, 20%);
}
&.intersect {
background-color: hsla(0deg, 0%, 30%, 32%);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/site/global/settings/Settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class SettingsMenuContext {

category = "";
scrollpoint = "";
intersectingSubcategory = "";

mappedNodes: Record<string, Record<string, SevenTV.SettingNode[]>> = reactive({
Home: {},
Expand Down
7 changes: 4 additions & 3 deletions src/site/global/settings/SettingsMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
</template>

<script setup lang="ts">
import { inject, ref, watch } from "vue";
import { inject, nextTick, ref, watch } from "vue";
import { useBreakpoints } from "@vueuse/core";
import { SITE_CURRENT_PLATFORM } from "@/common/Constant";
import { useActor } from "@/composable/useActor";
Expand Down Expand Up @@ -136,9 +136,10 @@ function navigateToCategory(name: string, scrollpoint?: string) {
}

ctx.switchView("config");
ctx.scrollpoint = "";
ctx.category = name;

if (scrollpoint) ctx.scrollpoint = scrollpoint;
if (scrollpoint) nextTick(() => (ctx.scrollpoint = scrollpoint));
}

function sortNodes(filter?: string) {
Expand Down Expand Up @@ -226,7 +227,7 @@ watch([settings.nodes, filter], () => sortNodes(filter.value), { immediate: true
max-height: calc(100vh - 10rem);
pointer-events: all;

background: var(--seventv-background-lesser-transparent-1);
background: var(--seventv-background-shade-1);
border-radius: 0.25rem;
outline: 0.1rem solid var(--seventv-border-transparent-1);
}
Expand Down
26 changes: 4 additions & 22 deletions src/site/global/settings/SettingsNode.vue
Original file line number Diff line number Diff line change
@@ -1,20 +1,5 @@
<template>
<div class="seventv-settings-node" tabindex="0" :disabled="node.disabledIf?.()" :grid-mode="node.custom?.gridMode">
<!--
<div class="seventv-settings-node-wrapper">
<div class="seventv-settings-node-items">
<div class="seventv-settings-node-label">
<span class="seventv-settings-node-label-text">
{{ node.label }}
</span>
<div class="seventv-settings-node-label-hint" :tooltip="node.hint">ⓘ</div>
</div>
<div class="seventv-settings-node-component-container">
<component :is="getComponent(node)" :node="node" />
</div>
</div>
</div>
-->
<div class="label">
<div class="title">
{{ node.label }}
Expand All @@ -27,7 +12,7 @@
<component :is="node.custom.component" />
</div>
<div v-else class="control">
<component :is="getComponent(node)" :node="node" />
<component :is="com" :node="node" />
</div>
</div>
</template>
Expand All @@ -40,7 +25,7 @@ import FormSelect from "@/site/global/settings/control/FormSelect.vue";
import FormSlider from "@/site/global/settings/control/FormSlider.vue";
import FormToggle from "@/site/global/settings/control/FormToggle.vue";

defineProps<{
const props = defineProps<{
node: SevenTV.SettingNode<SevenTV.SettingType>;
}>();

Expand All @@ -55,9 +40,7 @@ const standard = {
NONE: undefined,
};

function getComponent(node: SevenTV.SettingNode<SevenTV.SettingType>) {
return standard[node.type] ?? node.custom?.component;
}
const com = standard[props.node.type] ?? props.node.custom?.component;
</script>

<style scoped lang="scss">
Expand All @@ -71,11 +54,10 @@ function getComponent(node: SevenTV.SettingNode<SevenTV.SettingType>) {
"content content";
row-gap: 1rem;
padding: 0.25rem 0;
border-radius: 0.5rem;

transition: background-color 90ms ease-out;
&:hover {
background-color: rgba(0, 0, 0, 25%);
background-color: hsla(0deg, 0%, 0%, 10%);
}

&[disabled="true"] {
Expand Down
54 changes: 14 additions & 40 deletions src/site/global/settings/SettingsViewConfig.vue
Original file line number Diff line number Diff line change
@@ -1,37 +1,31 @@
<template>
<div class="seventv-settings-view-container">
<div v-if="ctx.mappedNodes[ctx.category]" class="seventv-settings-view-container">
<UiScrollable>
<template v-if="ctx.mappedNodes[ctx.category]">
<div
v-for="[s, sn] of Object.entries(ctx.mappedNodes[ctx.category])"
:key="s"
class="seventv-settings-subcategory"
>
<h3 v-if="s" :id="s" ref="subcategoryRefs" class="seventv-settings-subcategory-header">
{{ s }}
</h3>
<template v-for="node of sn" :key="node.key">
<SettingsNode :node="node" />
</template>
</div>
</template>
<div
v-for="[key, nodes] of Object.entries(ctx.mappedNodes[ctx.category])"
:key="key"
class="seventv-settings-subcategory"
>
<SettingsViewConfigCat ref="subCats" :name="key" :nodes="nodes" />
</div>
</UiScrollable>
</div>
</template>

<script setup lang="ts">
import { ref, watch } from "vue";
import { useSettingsMenu } from "./Settings";
import SettingsNode from "./SettingsNode.vue";
import SettingsViewConfigCat from "./SettingsViewConfigCat.vue";
import UiScrollable from "@/ui/UiScrollable.vue";

const ctx = useSettingsMenu();
const subcategoryRefs = ref<HTMLElement[]>([]);
const subCats = ref<InstanceType<typeof SettingsViewConfigCat>[]>([]);

watch(
() => ctx.scrollpoint,
() => {
subcategoryRefs.value.find((r) => r.id == ctx.scrollpoint)?.scrollIntoView();
// handle click on subcategory: scroll into view
subCats.value.find((r) => r.name == ctx.scrollpoint)?.scrollIntoView();
},
);
</script>
Expand All @@ -45,28 +39,8 @@ watch(
flex-grow: 1;
}
}
.seventv-settings-subcategory {
.seventv-settings-subcategory-header {
position: sticky;
top: 0;
background: var(--seventv-background-transparent-1);
backdrop-filter: blur(0.25rem);
z-index: 1;

display: flex;
flex-direction: column;
padding: 1rem;

&:after {
content: "";
width: 100%;
padding-bottom: 0.5rem;
border-bottom: 0.1rem solid hsla(0deg, 0%, 70%, 32%);
}
// box-shadow: 0 0.25rem 0.1rem hsla(0deg, 0%, 0%, 0.25);
}
&:last-child {
margin-bottom: 10rem;
}
.seventv-settings-subcategory:last-child {
margin-bottom: 30%;
}
</style>
66 changes: 66 additions & 0 deletions src/site/global/settings/SettingsViewConfigCat.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<template>
<div ref="catRef" :sticky="sticky" class="seventv-settings-view-subcategory">
<h3 v-if="name" :id="name" ref="subcategoryRefs" class="seventv-settings-subcategory-header">
{{ name }}
</h3>
<template v-for="n of nodes" :key="n.key">
<SettingsNode :node="n" />
</template>
</div>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { useIntersectionObserver } from "@vueuse/core";
import { useSettingsMenu } from "./Settings";
import SettingsNode from "./SettingsNode.vue";

const props = defineProps<{
name: string;
nodes: SevenTV.SettingNode<SevenTV.SettingType, SevenTV.SettingNode.ComponentType>[];
}>();

const ctx = useSettingsMenu();

const sticky = ref(false);
const catRef = ref<HTMLElement>();

// watch for scrolling into view
// this is used to highlight the subcategory in the dropdown
useIntersectionObserver(
catRef,
([entry]) => {
sticky.value = entry.isIntersecting;

if (sticky.value) ctx.intersectingSubcategory = props.name;
},
{
threshold: 0.75,
rootMargin: "0px 0px -50% 0px",
},
);

function scrollIntoView(): void {
catRef.value?.scrollIntoView({ block: "start" });
}

defineExpose({
name: props.name,
scrollIntoView,
});
</script>

<style scoped lang="scss">
.seventv-settings-subcategory-header {
position: sticky;
top: 0;
background: var(--seventv-background-shade-2);
border-bottom: 0.01rem solid var(--seventv-text-color-secondary);
backdrop-filter: blur(0.25rem);
z-index: 1;

display: block;
padding: 0.75rem 1rem;
margin-bottom: 0.5rem;
}
</style>
3 changes: 1 addition & 2 deletions src/site/twitch.tv/modules/settings/SettingsModule.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,10 @@ export const config = [
<style scoped lang="scss">
.settings-menu-enter-active,
.settings-menu-leave-active {
transition: transform 240ms linear, opacity 320ms;
transition: opacity 120ms;
}
.settings-menu-enter-from,
.settings-menu-leave-to {
opacity: 0;
transform: scale(0) translateX(100%) translateY(-100%) skewX(45deg);
}
</style>