Skip to content

Commit

Permalink
Update up-down game (#2010)
Browse files Browse the repository at this point in the history
* Update result card style

* Fix date

* Add loading indicator class

* Update types

* Return ...

* Add result parsing

* Remove observable

* Update type

* Add result parsing

* Update colors

* Fix positioning

* Add option to vote again

* Cleanup

* Only update time & likes when enabled

* Cleanup

* Make prop optional

* Update logic

* Add id

* Update vote page

* Disable score on empty page

* Allow scrolling

* Update link

* Update wallet page

* Hide header on wallet page
  • Loading branch information
harsh-mn-yral authored Nov 15, 2023
1 parent 8abcfc5 commit 8da9720
Show file tree
Hide file tree
Showing 15 changed files with 429 additions and 221 deletions.
28 changes: 19 additions & 9 deletions packages/experiments/src/components/layout/PlayerLayout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
import { getDb } from '$lib/db'
import { doc, getDoc } from 'firebase/firestore'
import { getMsLeftForResult, getVoteEndTime } from '$lib/utils/countdown'
import type { Readable } from 'svelte/store'
export let index: number
export let post: UpDownPost
Expand All @@ -39,14 +40,20 @@ let watchProgress = {
async function updateLikeDislikeStatus() {
const db = getDb()
const likeDoc = (
await getDoc(doc(db, `ud-videos/${post.id}/likes/${$authState.userId}`))
).data() as LikeRecord
const dislikeDoc = (
await getDoc(doc(db, `ud-videos/${post.id}/dislikes/${$authState.userId}`))
).data() as DislikeRecord
likeDoc && (liked = likeDoc.liked)
dislikeDoc && (disliked = dislikeDoc.disliked)
if (showLikeButton) {
const likeDoc = (
await getDoc(doc(db, `ud-videos/${post.id}/likes/${$authState.userId}`))
).data() as LikeRecord
likeDoc && (liked = likeDoc.liked)
}
if (showDislikeButton) {
const dislikeDoc = (
await getDoc(
doc(db, `ud-videos/${post.id}/dislikes/${$authState.userId}`),
)
).data() as DislikeRecord
dislikeDoc && (disliked = dislikeDoc.disliked)
}
}
$: if ($authState.isLoggedIn) {
Expand Down Expand Up @@ -192,7 +199,10 @@ async function updateStats() {
$: avatarUrl = getDefaultImageUrl(post.ouid)
const endTime = getVoteEndTime(new Date(post.created_at), new Date())
let timeLeft = getMsLeftForResult(endTime, true)
let timeLeft: Readable<string>
if (showTimer) {
timeLeft = getMsLeftForResult(endTime, true)
}
</script>

<player-layout
Expand Down
85 changes: 39 additions & 46 deletions packages/experiments/src/components/up-down/UpDownVote.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ export type UpDownVoteDetails = {
direction: VoteRecord['voteDirection']
voteAmount: number
status: VoteRecord['status']
created_at: number
result_at: number
score: number
result?: VoteRecord['result']
}
</script>
Expand All @@ -23,6 +24,7 @@ import {
onSnapshot,
type Unsubscribe,
limit,
orderBy,
} from 'firebase/firestore'
import UpDownVoteControls from './UpDownVoteControls.svelte'
Expand All @@ -34,14 +36,14 @@ export let post: UpDownPost
export let tutorialStep: number | undefined = undefined
let loading = true
let voteDetails: UpDownVoteDetails | undefined = undefined
let voteDocId: string | undefined = undefined
let unsubscribePost: Unsubscribe | undefined = undefined
let unsubscribeVote: Unsubscribe | undefined = undefined
let unsubscribe: Unsubscribe | undefined = undefined
let postStore = writable<UpDownPost>(post)
let voteDetails = writable<UpDownVoteDetails | undefined>(undefined)
let voteAgain = false
$: if (post.id && !tutorialStep && $authState.isLoggedIn && $authState.userId) {
observeVote()
loadVoteDetails()
}
if (post.id && !tutorialStep) {
Expand All @@ -50,90 +52,81 @@ if (post.id && !tutorialStep) {
async function observePost() {
try {
if (unsubscribePost) return
if (unsubscribe) return
const db = getDb()
const watchRef = doc(db, 'ud-videos' as CollectionName, post.id)
unsubscribePost = onSnapshot(watchRef, (doc) => {
const docRef = doc(db, 'ud-videos' as CollectionName, post.id)
unsubscribe = onSnapshot(docRef, (doc) => {
$postStore = doc.data() as UpDownPost
})
} catch (e) {
console.log('error while observing score', e)
}
}
async function observeVote() {
if (unsubscribeVote) return
async function loadVoteDetails() {
if (voteDetails) return
const db = getDb()
const docRef = await getDocs(
query(
collection(db, 'votes' satisfies CollectionName),
collection(db, 'votes'),
where('videoId', '==', post.id),
where('uid', '==', $authState.userId),
orderBy('created_at', 'desc'),
limit(1),
),
)
if (!docRef.empty) {
const vote = docRef.docs[0].data() as VoteRecord
voteDocId = docRef.docs[0].id
console.log({ voteDocId })
$voteDetails = {
voteDetails = {
score: vote.currentScore,
direction: vote.voteDirection,
created_at: vote.created_at,
result_at: vote.result_at,
status: vote.status,
result: vote.result,
voteAmount: vote.voteAmount,
}
const watchRef = doc(
db,
'votes' satisfies CollectionName,
docRef.docs[0].id,
)
unsubscribeVote = onSnapshot(watchRef, (doc) => {
const d = doc.data() as VoteRecord
$voteDetails = {
direction: d.voteDirection,
created_at: d.created_at,
status: d.status,
result: d.result,
voteAmount: d.voteAmount,
}
})
}
loading = false
}
async function handlePlaceVote(vote: UpDownVoteDetails) {
if (!post) return
const res = await placeVote(
{
videoId: post.id,
videoOid: post.oid,
videoUoid: post.ouid,
videoUid: post.video_uid,
},
vote.voteAmount,
vote.direction,
)
$voteDetails = vote
try {
const res = await placeVote(
{
videoId: post.id,
videoOid: post.oid,
videoUoid: post.ouid,
videoUid: post.video_uid,
},
vote.voteAmount,
vote.direction,
)
voteDetails = vote
} catch (e) {
console.error('Error while placing vote', e)
loading = false
}
}
onDestroy(() => {
unsubscribePost?.()
unsubscribeVote?.()
unsubscribe?.()
})
</script>

<up-down class="pointer-events-none block h-full w-full">
{#if $voteDetails && !tutorialStep}
{#if voteDetails && !tutorialStep && !voteAgain}
<UpDownVoteOutcome
{post}
showVoteAgainButton
disabled={!post || loading}
{voteDocId}
voteDetails={$voteDetails} />
{voteDetails}
on:voteAgain={() => (voteAgain = true)} />
{:else}
<UpDownVoteControls
score={$postStore.score}
postCreatedAt={post.created_at}
{tutorialStep}
disabled={$authState.isLoggedIn ? !post || loading : false}
on:votePlaced={({ detail }) => handlePlaceVote(detail)} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import { createEventDispatcher } from 'svelte'
import type { UpDownVoteDetails } from './UpDownVote.svelte'
import { authState } from '$stores/auth'
import c from 'clsx'
import { getVoteEndTime } from '$lib/utils/countdown'
export let score: number
export let postCreatedAt: number | undefined = undefined
export let disabled = false
export let tutorialStep: number | undefined = undefined
Expand Down Expand Up @@ -34,16 +36,20 @@ function placeVote(direction: 'up' | 'down', voteAmount: number) {
dispatch('votePlaced', {
direction,
score,
voteAmount,
status: 'pending',
created_at: Date.now(),
result_at: getVoteEndTime(
postCreatedAt ? new Date(postCreatedAt) : new Date(),
new Date(),
).getTime(),
})
}
</script>

<div
class={c(
'flex flex-col items-center justify-center gap-3 pt-4 transition-opacity',
'fade-in flex flex-col items-center justify-center gap-3 pt-4 transition-opacity',
disabled || tutorialStep ? 'pointer-events-none' : 'pointer-events-auto',
{
'opacity-50': disabled,
Expand Down
Loading

0 comments on commit 8da9720

Please sign in to comment.