Skip to content

Commit 4a7c4d9

Browse files
authored
Refactoring to community polls & fixes for quizzes (#3865)
* Refactoring to community polls & fixes for quizzes * Replaced the interactive quiz with a reveal button and small fixes * Replaced the interactive quiz with a reveal button and small fixes * Implemented vote formatting * vote translation fix * Accessibility additions * Fixed local API is_correct typo * Fixed inconsistent indents
1 parent f4cee17 commit 4a7c4d9

File tree

10 files changed

+188
-59
lines changed

10 files changed

+188
-59
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
.vote-count {
2+
padding-bottom: 6px;
3+
font-size: smaller;
4+
}
5+
6+
.empty-circle {
7+
background-color: transparent;
8+
border-radius: 50%;
9+
border-style: solid;
10+
border-width: 2px;
11+
display: block;
12+
float: left;
13+
height: 10px;
14+
left: 5px;
15+
position: relative;
16+
top: 8px;
17+
width: 10px;
18+
}
19+
20+
.filled-circle {
21+
border-radius: 50%;
22+
background-color: black;
23+
float: left;
24+
height: 6px;
25+
left: 2px;
26+
top: 2px;
27+
position: relative;
28+
width: 6px;
29+
}
30+
31+
.option-text {
32+
border-radius: 5px;
33+
border-style: solid;
34+
border-width: 2px;
35+
padding: 5px 25px;
36+
}
37+
38+
.option {
39+
padding-bottom: 10px;
40+
}
41+
42+
.correct-option {
43+
background-color: #78da71;
44+
}
45+
46+
.incorrect-option {
47+
background-color: #dd4e4e;
48+
}
49+
50+
.reveal-answer {
51+
text-align: center;
52+
cursor: pointer;
53+
}
54+
55+
.reveal-answer:hover > .option-text, .reveal-answer:focus > .option-text {
56+
background-color: var(--side-nav-hover-color)
57+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { defineComponent } from 'vue'
2+
import { formatNumber } from '../../helpers/utils'
3+
4+
export default defineComponent({
5+
name: 'FtCommunityPoll',
6+
props: {
7+
data: {
8+
type: Object,
9+
required: true
10+
}
11+
},
12+
data: function () {
13+
return {
14+
revealAnswer: false
15+
}
16+
},
17+
computed: {
18+
formattedVotes: function () {
19+
return formatNumber(this.data.totalVotes)
20+
},
21+
}
22+
})
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<template>
2+
<div class="poll">
3+
<div
4+
class="vote-count"
5+
>
6+
<!-- Format the votes to be split by commas ie. 1000 -> 1,000 -->
7+
{{ $t('Channel.Community.votes', {votes: formattedVotes}) }}
8+
</div>
9+
<div
10+
v-for="(choice, index) in data.content"
11+
:key="index"
12+
>
13+
<div
14+
v-if="data.type === 'quiz'"
15+
class="option quiz-option"
16+
>
17+
<span class="empty-circle">
18+
<span :class="revealAnswer && choice.isCorrect ? 'filled-circle' : ''" />
19+
</span>
20+
<div
21+
class="option-text"
22+
:class="revealAnswer && choice.isCorrect ? 'correct-option' : ''"
23+
>
24+
{{ choice.text }}
25+
</div>
26+
</div>
27+
<div
28+
v-else
29+
class="option poll-option"
30+
>
31+
<span class="empty-circle" />
32+
<div class="option-text">
33+
{{ choice.text }}
34+
</div>
35+
</div>
36+
</div>
37+
<div
38+
v-if="data.type === 'quiz'"
39+
class="reveal-answer option"
40+
tabindex="0"
41+
role="button"
42+
@click="revealAnswer = !revealAnswer"
43+
@keydown.enter.prevent="revealAnswer = !revealAnswer"
44+
@keydown.space.prevent="revealAnswer = !revealAnswer"
45+
>
46+
<div
47+
v-if="!revealAnswer"
48+
class="option-text"
49+
>
50+
<font-awesome-icon :icon="['fas', 'eye']" /> {{ $t('Channel.Community.Reveal Answers') }}
51+
</div>
52+
<div
53+
v-else
54+
class="option-text"
55+
>
56+
<font-awesome-icon :icon="['fas', 'eye-slash']" /> {{ $t('Channel.Community.Hide Answers') }}
57+
</div>
58+
</div>
59+
</div>
60+
</template>
61+
62+
<script src="./ft-community-poll.js" />
63+
<style scoped src="./ft-community-poll.css" />

src/renderer/components/ft-community-post/ft-community-post.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { defineComponent } from 'vue'
22
import FtListVideo from '../ft-list-video/ft-list-video.vue'
33
import FtListPlaylist from '../ft-list-playlist/ft-list-playlist.vue'
4+
import FtCommunityPoll from '../ft-community-poll/ft-community-poll.vue'
45

56
import autolinker from 'autolinker'
67
import VueTinySlider from 'vue-tiny-slider'
@@ -15,6 +16,7 @@ export default defineComponent({
1516
components: {
1617
'ft-list-playlist': FtListPlaylist,
1718
'ft-list-video': FtListVideo,
19+
'ft-community-poll': FtCommunityPoll,
1820
'tiny-slider': VueTinySlider
1921
},
2022
props: {
@@ -37,7 +39,7 @@ export default defineComponent({
3739
postContent: '',
3840
commentCount: '',
3941
isLoading: true,
40-
author: ''
42+
author: '',
4143
}
4244
},
4345
computed: {

src/renderer/components/ft-community-post/ft-community-post.scss

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,6 @@
1313
box-sizing: border-box;
1414
}
1515

16-
.circle {
17-
background-color: transparent;
18-
border-radius: 50%;
19-
border-style: solid;
20-
border-width: 2px;
21-
display: block;
22-
float: left;
23-
height: 10px;
24-
left: 5px;
25-
position: relative;
26-
top: 8px;
27-
width: 10px;
28-
}
29-
30-
.poll-text {
31-
border-radius: 5px;
32-
border-style: solid;
33-
border-width: 2px;
34-
padding: 5px 25px;
35-
}
36-
37-
.poll-option {
38-
padding-bottom: 10px;
39-
}
40-
4116
.communityImage {
4217
height: 100%;
4318
width: 100%;

src/renderer/components/ft-community-post/ft-community-post.vue

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -60,36 +60,9 @@
6060
/>
6161
</div>
6262
<div
63-
v-if="type === 'poll'"
63+
v-if="type === 'poll' || type === 'quiz'"
6464
>
65-
<div
66-
class="poll-count"
67-
>
68-
{{ postContent.totalVotes }}
69-
</div>
70-
<div
71-
v-for="(poll, index) in postContent.content"
72-
:key="index"
73-
>
74-
<div
75-
class="poll-option"
76-
>
77-
<span
78-
class="circle"
79-
/>
80-
<div
81-
class="poll-text"
82-
>
83-
<!-- <img
84-
v-if="poll.image != null && poll.image.length >0"
85-
:src="getBestQualityImage(poll.image)"
86-
class="poll-image"
87-
alt=""
88-
> -->
89-
{{ poll.text }}
90-
</div>
91-
</div>
92-
</div>
65+
<ft-community-poll :data="postContent" />
9366
</div>
9467
<div
9568
v-if="type === 'playlist'"

src/renderer/helpers/api/invidious.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,14 +257,32 @@ function parseInvidiousCommunityAttachments(data) {
257257
}
258258
}
259259

260+
if (data.type === 'quiz') {
261+
return {
262+
type: 'quiz',
263+
totalVotes: data.totalVotes ?? 0,
264+
content: data.choices.map(choice => {
265+
return {
266+
text: choice.text,
267+
isCorrect: choice.isCorrect,
268+
image: choice.image?.map(thumbnail => {
269+
thumbnail.url = youtubeImageUrlToInvidious(thumbnail.url)
270+
return thumbnail
271+
})
272+
}
273+
})
274+
}
275+
}
276+
260277
if (data.type === 'playlist') {
261278
return {
262279
type: data.type,
263280
content: data
264281
}
265282
}
266283

267-
console.error('New Invidious Community Post Type: ' + data.type)
284+
console.error(`Unknown Invidious community post type: ${data.type}`)
285+
console.error(data)
268286
}
269287

270288
/**

src/renderer/helpers/api/local.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -916,17 +916,29 @@ function parseLocalAttachment(attachment) {
916916
} else if (attachment.type === 'Poll') {
917917
return {
918918
type: 'poll',
919-
totalVotes: attachment.total_votes ?? 0,
919+
totalVotes: parseLocalSubscriberCount(attachment.total_votes.text) ?? 0,
920920
content: attachment.choices.map(choice => {
921921
return {
922922
text: choice.text.text,
923923
image: choice.image
924924
}
925925
})
926926
}
927+
} else if (attachment.type === 'Quiz') {
928+
return {
929+
type: 'quiz',
930+
totalVotes: parseLocalSubscriberCount(attachment.total_votes.text) ?? 0,
931+
content: Object.values(attachment.choices).map(choice => {
932+
return {
933+
text: choice.text.text,
934+
isCorrect: choice.is_correct,
935+
image: choice.image
936+
}
937+
})
938+
}
927939
} else {
940+
console.error(`Unknown Local community post type: ${attachment.type}`)
928941
console.error(attachment)
929-
console.error('unknown type')
930942
}
931943
}
932944

src/renderer/main.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ import {
5656
faThumbtack,
5757
faTimes,
5858
faTimesCircle,
59-
faUsers
59+
faUsers,
60+
faEye,
61+
faEyeSlash,
6062
} from '@fortawesome/free-solid-svg-icons'
6163
import {
6264
faBitcoin,
@@ -123,6 +125,8 @@ library.add(
123125
faTimes,
124126
faTimesCircle,
125127
faUsers,
128+
faEye,
129+
faEyeSlash,
126130

127131
// brand icons
128132
faGithub,

static/locales/en-US.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,9 @@ Channel:
590590
Community:
591591
Community: Community
592592
This channel currently does not have any posts: This channel currently does not have any posts
593+
votes: '{votes} votes'
594+
Reveal Answers: Reveal Answers
595+
Hide Answers: Hide Answers
593596
Video:
594597
Mark As Watched: Mark As Watched
595598
Remove From History: Remove From History

0 commit comments

Comments
 (0)