Skip to content

Commit

Permalink
feat: add clicks slider in list overview
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Feb 25, 2024
1 parent fc14491 commit 44dde15
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 31 deletions.
62 changes: 62 additions & 0 deletions packages/client/internals/OverviewClicksSlider.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<script setup lang="ts">
import type { ClicksContext } from '@slidev/types'
import type { Ref } from 'vue'
import { computed, defineProps } from 'vue'
const props = defineProps<{
clickContext: [Ref<number>, ClicksContext]
}>()
const total = computed(() => props.clickContext[1].total)
const current = computed({
get() {
return props.clickContext[0].value > total.value ? -1 : props.clickContext[0].value
},
set(value: number) {
// eslint-disable-next-line vue/no-mutating-props
props.clickContext[0].value = value
},
})
const range = computed(() => Array.from({ length: total.value + 1 }, (_, i) => i))
</script>

<template>
<div
class="flex gap-0.5 items-center select-none"
:title="`Clicks in this slide: ${total}`"
>
<div class="flex gap-1 items-center min-w-16">
<carbon:cursor-1 text-sm op50 />
<span v-if="current <= total && current >= 0" text-primary>{{ current }}/</span>
<span op50>{{ total }}</span>
</div>
<div
relative flex-auto h5 flex="~"
@dblclick="current = 999999"
>
<div
v-for="i of range" :key="i"
border="y main" of-hidden relative
:class="[
i === 0 ? 'rounded-l border-l' : '',
i === total ? 'rounded-r border-r' : '',
]"
:style="{ width: `${1 / total * 100}%` }"
>
<div absolute inset-0 z--1 :class=" i <= current ? 'bg-primary' : ''" />
<div
:class="[
+i === +current ? 'text-white font-bold op100' : 'op30',
i === 0 ? 'rounded-l' : '',
i === total ? 'rounded-r' : 'border-r border-main',
]"
w-full h-full text-xs flex items-center justify-center
>
{{ i }}
</div>
</div>
<input v-model="current" absolute inset-0 type="range" :min="0" :max="total" :step="1" z-10 op0>
</div>
</div>
</template>
64 changes: 33 additions & 31 deletions packages/client/pages/overview.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
<script setup lang="ts">
import type { Ref } from 'vue'
import { computed, nextTick, onMounted, reactive, ref } from 'vue'
import { useHead } from '@unhead/vue'
import type { RouteRecordRaw } from 'vue-router'
import type { ClicksContext } from 'packages/types'
import { themeVars } from '../env'
import { rawRoutes } from '../logic/nav'
import { useClicksContextBase } from '../composables/useClicks'
import { useFixedClicks } from '../composables/useClicks'
import { isColorSchemaConfigured, isDark, toggleDark } from '../logic/dark'
import { getSlideClass } from '../utils'
import SlideContainer from '../internals/SlideContainer.vue'
import SlideWrapper from '../internals/SlideWrapper'
import DrawingPreview from '../internals/DrawingPreview.vue'
import IconButton from '../internals/IconButton.vue'
import NoteEditor from '../internals/NoteEditor.vue'
import OverviewClicksSlider from '../internals/OverviewClicksSlider.vue'
const cardWidth = 450
Expand All @@ -27,16 +29,16 @@ const wordCounts = computed(() => rawRoutes.map(route => wordCount(route.meta?.s
const totalWords = computed(() => wordCounts.value.reduce((a, b) => a + b, 0))
const totalClicks = computed(() => rawRoutes.map(route => getSlideClicks(route)).reduce((a, b) => a + b, 0))
const clicksContextMap = new WeakMap<RouteRecordRaw, ClicksContext>()
const clicksContextMap = new WeakMap<RouteRecordRaw, [Ref<number>, ClicksContext]>()
function getClickContext(route: RouteRecordRaw) {
// We create a local clicks context to calculate the total clicks of the slide
if (!clicksContextMap.has(route))
clicksContextMap.set(route, useClicksContextBase(() => 999999, route?.meta?.clicks))
clicksContextMap.set(route, useFixedClicks(route, 9999))
return clicksContextMap.get(route)!
}
function getSlideClicks(route: RouteRecordRaw) {
return route.meta?.clicks || getClickContext(route)?.total
return route.meta?.clicks || getClickContext(route)?.[1]?.total
}
function wordCount(str: string) {
Expand Down Expand Up @@ -133,36 +135,36 @@ onMounted(() => {
<div class="text-3xl op20 mb2">
{{ idx + 1 }}
</div>
</div>
<div class="flex flex-col gap-2 my5">
<div
v-if="getSlideClicks(route)"
class="flex gap-0.5 op50 items-center justify-end"
:title="`Clicks in this slide: ${getSlideClicks(route)}`"
class="border rounded border-main overflow-hidden bg-main select-none h-max"
:style="themeVars"
@dblclick="openSlideInNewTab(route.path)"
>
<carbon:cursor-1 text-sm />
{{ getSlideClicks(route) }}
<SlideContainer
:key="route.path"
:width="cardWidth"
:clicks-disabled="true"
class="pointer-events-none important:[&_*]:select-none"
>
<SlideWrapper
:is="route.component"
v-if="route?.component"
:clicks-context="getClickContext(route)[1]"
:class="getSlideClass(route)"
:route="route"
render-context="overview"
/>
<DrawingPreview :page="+route.path" />
</SlideContainer>
</div>
</div>
<div
class="border rounded border-main overflow-hidden bg-main my5 select-none h-max"
:style="themeVars"
@dblclick="openSlideInNewTab(route.path)"
>
<SlideContainer
:key="route.path"
:width="cardWidth"
:clicks-disabled="true"
class="pointer-events-none important:[&_*]:select-none"
>
<SlideWrapper
:is="route.component"
v-if="route?.component"
:clicks-context="getClickContext(route)"
:class="getSlideClass(route)"
:route="route"
render-context="overview"
/>
<DrawingPreview :page="+route.path" />
</SlideContainer>
<OverviewClicksSlider
v-if="getSlideClicks(route)"
mt-2
:click-context="getClickContext(route)"
class="w-full"
/>
</div>
<div class="py3 mt-0.5 mr--8 ml--4 op0 transition group-hover:op100">
<IconButton
Expand Down

0 comments on commit 44dde15

Please sign in to comment.