Mejora panel de comentaristas con Twitter y swap central

This commit is contained in:
Pandipipas
2026-02-15 11:12:57 +01:00
parent 739ac66aea
commit 461f72f878
6 changed files with 116 additions and 17 deletions
+14 -2
View File
@@ -7,17 +7,29 @@
"type": "string",
"default": ""
},
"leftCommentatorTwitter": {
"type": "string",
"default": ""
},
"rightCommentator": {
"type": "string",
"default": ""
},
"rightCommentatorTwitter": {
"type": "string",
"default": ""
}
},
"required": [
"leftCommentator",
"rightCommentator"
"leftCommentatorTwitter",
"rightCommentator",
"rightCommentatorTwitter"
],
"default": {
"leftCommentator": "",
"rightCommentator": ""
"leftCommentatorTwitter": "",
"rightCommentator": "",
"rightCommentatorTwitter": ""
}
}
@@ -10,30 +10,53 @@ const commentaryStore = useCommentaryStore();
<div class="text-h4">
Commentary
</div>
<QSpace />
<QBtn
flat
dense
icon="swap_horiz"
class="commentary-panel__action-btn"
@click="commentaryStore.swapCommentators"
/>
</div>
<div class="row q-col-gutter-lg">
<div class="col-12 col-md-6">
<div class="commentary-panel__layout">
<div class="commentary-panel__commentator">
<QInput
v-model="commentaryStore.leftCommentator"
label="Commentator"
label="Commentator #1"
dense
class="commentary-panel__field"
>
<template #prepend>
<QIcon name="mic" />
</template>
</QInput>
<QInput
v-model="commentaryStore.leftCommentatorTwitter"
label="@Twitter / Text"
dense
class="commentary-panel__field"
/>
</div>
<div class="col-12 col-md-6">
<QBtn
flat
dense
round
icon="swap_horiz"
class="commentary-panel__swap-btn"
@click="commentaryStore.swapCommentators"
/>
<div class="commentary-panel__commentator">
<QInput
v-model="commentaryStore.rightCommentator"
label="Commentator"
label="Commentator #2"
dense
class="commentary-panel__field"
>
<template #prepend>
<QIcon name="mic" />
</template>
</QInput>
<QInput
v-model="commentaryStore.rightCommentatorTwitter"
label="@Twitter / Text"
dense
class="commentary-panel__field"
/>
@@ -49,6 +72,22 @@ const commentaryStore = useCommentaryStore();
gap: 16px;
}
.commentary-panel__layout {
display: grid;
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
align-items: center;
gap: 12px;
}
.commentary-panel__commentator {
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 4px;
padding: 8px;
display: flex;
flex-direction: column;
gap: 2px;
}
.commentary-panel__field :deep(.q-field__control) {
min-height: 28px;
padding: 0;
@@ -62,19 +101,33 @@ const commentaryStore = useCommentaryStore();
border-bottom: 1px solid rgba(255, 255, 255, 0.34);
}
.commentary-panel__field :deep(.q-field__prepend) {
color: rgba(255, 255, 255, 0.6);
}
.commentary-panel__field :deep(.q-field__native),
.commentary-panel__field :deep(.q-field__input),
.commentary-panel__field :deep(.q-field__label) {
color: rgba(255, 255, 255, 0.92);
}
.commentary-panel__action-btn {
.commentary-panel__swap-btn {
color: #fff;
opacity: 0.85;
}
.commentary-panel__action-btn:hover {
.commentary-panel__swap-btn:hover {
opacity: 1;
text-shadow: 0 0 10px rgba(255, 255, 255, 0.45);
}
@media (max-width: 900px) {
.commentary-panel__layout {
grid-template-columns: 1fr;
}
.commentary-panel__swap-btn {
justify-self: center;
}
}
</style>
@@ -8,14 +8,18 @@ type Commentary = Schemas.Commentary;
const defaultCommentary: Commentary = {
leftCommentator: '',
leftCommentatorTwitter: '',
rightCommentator: '',
rightCommentatorTwitter: '',
};
const normalizeCommentary = (input: unknown): Commentary => {
const candidate = typeof input === 'object' && input !== null ? (input as Record<string, unknown>) : {};
return {
leftCommentator: typeof candidate.leftCommentator === 'string' ? candidate.leftCommentator : '',
leftCommentatorTwitter: typeof candidate.leftCommentatorTwitter === 'string' ? candidate.leftCommentatorTwitter : '',
rightCommentator: typeof candidate.rightCommentator === 'string' ? candidate.rightCommentator : '',
rightCommentatorTwitter: typeof candidate.rightCommentatorTwitter === 'string' ? candidate.rightCommentatorTwitter : '',
};
};
@@ -34,6 +38,16 @@ export const useCommentaryStore = defineStore('commentary', () => {
},
});
const leftCommentatorTwitter = computed({
get: () => commentary.value.leftCommentatorTwitter,
set: (value: string) => {
commentary.value = {
...commentary.value,
leftCommentatorTwitter: value,
};
},
});
const rightCommentator = computed({
get: () => commentary.value.rightCommentator,
set: (value: string) => {
@@ -44,17 +58,31 @@ export const useCommentaryStore = defineStore('commentary', () => {
},
});
const rightCommentatorTwitter = computed({
get: () => commentary.value.rightCommentatorTwitter,
set: (value: string) => {
commentary.value = {
...commentary.value,
rightCommentatorTwitter: value,
};
},
});
const swapCommentators = () => {
commentary.value = {
leftCommentator: commentary.value.rightCommentator,
leftCommentatorTwitter: commentary.value.rightCommentatorTwitter,
rightCommentator: commentary.value.leftCommentator,
rightCommentatorTwitter: commentary.value.leftCommentatorTwitter,
};
};
return {
commentary,
leftCommentator,
leftCommentatorTwitter,
rightCommentator,
rightCommentatorTwitter,
swapCommentators,
};
});
+2
View File
@@ -23,7 +23,9 @@ export const scoreboardReplicant = hasDefault<Schemas.Scoreboard>('scoreboard');
export const commentaryReplicant = nodecg.Replicant<Schemas.Commentary>('commentary', {
defaultValue: {
leftCommentator: '',
leftCommentatorTwitter: '',
rightCommentator: '',
rightCommentatorTwitter: '',
},
persistent: false,
});
+2
View File
@@ -8,7 +8,9 @@ useHead({ title: 'Commentary' });
const defaultCommentary: Schemas.Commentary = {
leftCommentator: '',
leftCommentatorTwitter: '',
rightCommentator: '',
rightCommentatorTwitter: '',
};
const commentary = computed<Schemas.Commentary>(() => commentaryReplicant?.data ?? defaultCommentary);
+2
View File
@@ -8,5 +8,7 @@
export interface Commentary {
leftCommentator: string;
leftCommentatorTwitter: string;
rightCommentator: string;
rightCommentatorTwitter: string;
}