Skip to content

Commit

Permalink
feat: improve recording
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Apr 19, 2021
1 parent cb496df commit 69a2c97
Show file tree
Hide file tree
Showing 5 changed files with 265 additions and 56 deletions.
18 changes: 10 additions & 8 deletions demo/slides.md
Original file line number Diff line number Diff line change
Expand Up @@ -412,25 +412,27 @@ type MaybeRef<T> = Ref<T> | T
In VueUse, we use this helper heavily to support optional reactive arguments
```ts
export function useTimeAgo(
time: Date | number | string | Ref<Date | number | string>,
) {
return computed(() => someFormating(unref(time)))
}
```

```ts{monaco}
import { computed, unref, Ref } from 'vue'
type MaybeRef<T> = Ref<T> | T
export function useTimeAgo(
time: Ref<Date | number | string> | Date | number | string,
time: MaybeRef<Date | number | string>,
) {
return computed(() => someFormating(unref(time)))
}
```

```ts
useTimeAgo(1618478282830) // 5 mins ago

const time = ref('2021-04-29')
useTimeAgo(time) // Today
```

</v-click>


Expand Down
76 changes: 76 additions & 0 deletions packages/vite-slides/client/builtin/DevicesList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<script setup lang="ts">
import { defineProps, onMounted } from 'vue'
import { cameras, microphones, getDevices, currentCamera, currentMic } from '../logic/recording'
onMounted(() => {
getDevices()
})
</script>

<template>
<div class="devices-list text-sm py-2">
<div class="title">
Camera
</div>
<div
class="item"
:class="{ active: currentCamera === 'none' }"
@click="currentCamera = 'none'"
>
<carbon:checkmark class="text-green-500" />
None
</div>
<div
v-for="i of cameras"
:key="i.deviceId"
class="item"
:class="{ active: currentCamera === i.deviceId }"
@click="currentCamera = i.deviceId"
>
<carbon:checkmark class="text-green-500" />
{{ i.label }}
</div>

<div class="title mt-2">
Microphone
</div>
<div
class="item"
:class="{ active: currentMic === 'none' }"
@click="currentMic = 'none'"
>
<carbon:checkmark class="text-green-500" />
None
</div>
<div
v-for="i of microphones"
:key="i.deviceId"
class="item"
:class="{ active: currentMic === i.deviceId }"
@click="currentMic = i.deviceId"
>
<carbon:checkmark class="text-green-500" />
{{ i.label }}
</div>
</div>
</template>

<style lang="postcss">
.devices-list {
@apply select-none;
.item {
@apply flex whitespace-nowrap py-1 px-4 cursor-default hover:(bg-gray-400 bg-opacity-10);
svg {
@apply mr-1 -ml-2;
}
&:not(.active) svg {
@apply opacity-0;
}
}
.title {
@apply text-xs uppercase opacity-50 tracking-widest px-7 py-1;
}
}
</style>
50 changes: 40 additions & 10 deletions packages/vite-slides/client/builtin/SlideControls.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script setup lang="ts">
import { useFullscreen } from '@vueuse/core'
import { computed, ref } from 'vue'
import { onClickOutside, useFullscreen } from '@vueuse/core'
import { computed, onMounted, ref } from 'vue'
import { isDark, toggleDark, useNavigateControls } from '../logic'
import { recorder } from '../logic/recording'
import { recorder, getDevices, currentCamera } from '../logic/recording'
const { isFullscreen, toggle: toggleFullscreen } = useFullscreen(document.body)
const { hasNext, hasPrev, prev, next, current } = useNavigateControls()
Expand All @@ -19,8 +19,21 @@ const editorLink = computed(() => {
const {
recording,
showAvatar,
streamCamera,
toggleRecording,
toggleAvatar,
} = recorder
onMounted(() => {
getDevices()
})
const devicesList = ref()
const showDevicesList = ref(false)
onClickOutside(devicesList, () => {
showDevicesList.value = false
})
</script>

<template>
Expand All @@ -30,19 +43,36 @@ const {
<carbon:edit />
</a>

<button class="icon-btn" :class="{'text-red-500': recording}" @click="toggleRecording">
<carbon:stop-outline v-if="recording" />
<carbon:video v-else />
</button>

<button
v-if="currentCamera !== 'none'"
class="icon-btn"
:class="{'text-blue-500': showAvatar && recording, disabled: !recording}"
@click="showAvatar = !showAvatar"
:class="{'text-green-500': Boolean(showAvatar && streamCamera)}"
@click="toggleAvatar"
>
<carbon:user-avatar />
</button>

<div
ref="devicesList"
class="flex relative"
>
<button class="icon-btn" :class="{'text-red-500': recording}" @click="toggleRecording">
<carbon:stop-outline v-if="recording" />
<carbon:video v-else />
</button>
<button
class="icon-btn !text-sm !px-0"
:class="{disabled:recording}"
@click="showDevicesList = !showDevicesList"
>
<carbon:chevron-up class="opacity-50" />
</button>
<DevicesList
v-if="showDevicesList && !recording"
class="absolute right-0 bottom-10 bg-main rounded shadow z-20"
/>
</div>

<button class="icon-btn" @click="showOverview = !showOverview">
<carbon:apps />
</button>
Expand Down
34 changes: 27 additions & 7 deletions packages/vite-slides/client/builtin/WebCamera.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { useEventListener, useStorage } from '@vueuse/core'
import { computed, ref, watch } from 'vue'
import { recorder } from '../logic/recording'
import { computed, onMounted, ref, watch } from 'vue'
import { recorder, currentCamera } from '../logic/recording'
const size = useStorage('webcam-size', Math.round(Math.min(window.innerHeight, (window.innerWidth) / 8)))
const x = useStorage('webcam-x', window.innerWidth - size.value - 30)
Expand All @@ -27,11 +27,27 @@ const frameStyle = computed(() => ({
height: `${size.value}px`,
}))
const handleStyle = computed(() => ({
width: '14px',
height: '14px',
bottom: `${size.value / 2 * 0.3 - 7}px`,
right: `${size.value / 2 * 0.3 - 7}px`,
cursor: 'nwse-resize',
}))
const frameDown = ref(false)
const handlerDown = ref(false)
let deletaX = 0
let deletaY = 0
function fixPosistion() {
// move back if the camera is outside of the canvas
if (x.value >= window.innerWidth)
x.value = window.innerWidth - size.value - 30
if (y.value >= window.innerHeight)
y.value = window.innerHeight - size.value - 30
}
useEventListener(frame, 'mousedown', (e: MouseEvent) => {
if (frame.value) {
frameDown.value = true
Expand Down Expand Up @@ -62,15 +78,19 @@ useEventListener(window, 'mousemove', (e: MouseEvent) => {
}
if (handlerDown.value && frame.value) {
const box = frame.value.getBoundingClientRect()
size.value = Math.min(e.screenX - box.x, e.screenY - box.y)
size.value = Math.max(10, Math.min(e.clientX - box.x, e.clientY - box.y))
}
})
useEventListener('resize', fixPosistion)
onMounted(fixPosistion)
</script>

<template>
<div
v-if="streamCamera && showAvatar"
class="fixed z-50"
v-if="streamCamera && showAvatar && currentCamera !== 'none'"
class="fixed z-10"
:style="containerStyle"
>
<div
Expand All @@ -90,8 +110,8 @@ useEventListener(window, 'mousemove', (e: MouseEvent) => {

<div
ref="handler"
class="absolute bottom-0 right-0 w-3 h-3 rounded-full bg-gray-400 opacity-0 shadow hover:opacity-100"
style="cursor: nwse-resize"
class="absolute bottom-0 right-0 rounded-full bg-main shadow opacity-0 shadow z-30 hover:opacity-100 dark:(border border-true-gray-700)"
:style="handleStyle"
:class="handlerDown ? '!opacity-100' : ''"
>
</div>
Expand Down

0 comments on commit 69a2c97

Please sign in to comment.