Skip to content

Commit

Permalink
Code refactoring
Browse files Browse the repository at this point in the history
Project structure refactoring, moved library files in dedicated folder to separate them from demo source code
Unified the components base style in separate file and changed base class names
Changed default hardcoded css base icons in favor of fully customizable svg icon or replaceable slot, see #2 for the discussion
  • Loading branch information
Filippo Conti committed Dec 28, 2019
1 parent 514bf2c commit 9fbb2fa
Show file tree
Hide file tree
Showing 13 changed files with 263 additions and 246 deletions.
61 changes: 61 additions & 0 deletions lib/components/RecordAudio.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<template lang="html">
<div
v-if="isSupported"
v-bind:class="{
'vue-record': true,
'vue-record-audio': true,
'active': isRecording,
'paused': isPaused
}"
v-on="{
'mousedown': startRecording,
'mouseleave': stopRecording,
'mouseup': startRecording,
'touchstart': startRecording,
'touchend': startRecording,
'touchcancel': startRecording,
}"
>
<div class="icon-container" :style="backgroundStyle">
<slot>
<svg v-bind="foregroundStyle" viewBox="0 0 24 24">
<path d="M12,2A3,3 0 0,1 15,5V11A3,3 0 0,1 12,14A3,3 0 0,1 9,11V5A3,3 0 0,1 12,2M19,11C19,14.53 16.39,17.44 13,17.93V21H11V17.93C7.61,17.44 5,14.53 5,11H7A5,5 0 0,0 12,16A5,5 0 0,0 17,11H19Z" />
</svg>
</slot>
</div>
</div>
</template>

<script>
const supportedTypes = [
'audio/aac',
'audio/ogg',
'audio/wav',
'audio/webm'
]
import ElementMixin from '../mixins/Element'
export default {
name: 'VueRecordAudio',
mixins: [ElementMixin],
supportedTypes,
props: {
mimeType: {
type: String,
default: 'audio/webm',
validator: v => supportedTypes.includes(v)
}
},
data () {
return {
constraints: {
audio: true,
video: false
}
}
}
}
</script>

<style lang="scss" src="../index.scss"></style>
81 changes: 81 additions & 0 deletions lib/components/RecordVideo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<template lang="html">
<div
v-if="isSupported"
v-on="{
'mousedown': startRecording,
'mouseleave': stopRecording,
'mouseup': startRecording,
'touchstart': startRecording,
'touchend': startRecording,
'touchcancel': startRecording,
}"
class="vue-record vue-video-recorder"
:class="{
'vue-record': true,
'vue-record-video': true,
'active': isRecording,
'paused': isPaused
}"
>
<div class="icon-container" :style="backgroundStyle">
<template v-if="isRecording">
<svg v-bind="foregroundStyle" viewBox="0 0 24 24">
<path fill="#000000" d="M18,18H6V6H18V18Z" />
</svg>
</template>

<template v-else>
<svg v-bind="foregroundStyle" viewBox="0 0 24 24">
<path
fill="#000000"
d="M17,10.5V7A1,1 0 0,0 16,6H4A1,1 0 0,0 3,7V17A1,1 0 0,0 4,18H16A1,1 0 0,0 17,17V13.5L21,17.5V6.5L17,10.5Z"
/>
</svg>
</template>
</div>
</div>
</template>

<script>
const supportedTypes = [
'video/x-msvideo',
'video/ogg',
'video/mpeg',
'video/webm'
]
import ElementMixin from '../mixins/Element'
// <svg style="width:24px;height:24px" viewBox="0 0 24 24">
// <path fill="#000000" d="M14,19H18V5H14M6,19H10V5H6V19Z" />
// </svg>
export default {
name: 'VueRecordVideo',
mixins: [ElementMixin],
props: {
mimeType: {
type: String,
default: 'video/webm',
validator: v => supportedTypes.includes(v)
},
audio: {
type: Boolean,
default: true
},
mode: {
default: 'press'
}
},
computed: {
constraints () {
return {
video: true,
audio: this.audio
}
}
}
}
</script>

<style lang="scss" src="../index.scss"></style>
13 changes: 13 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import VueRecordAudio from './components/RecordAudio'
import VueRecordVideo from './components/RecordVideo'

export {
VueRecordAudio,
VueRecordVideo
}

export default function install(Vue, options = {}) {
Vue.prototype.$VueRecord = options;
Vue.component('VueRecordAudio', VueRecordAudio)
Vue.component('VueRecordVideo', VueRecordVideo)
}
27 changes: 27 additions & 0 deletions lib/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.vue-record {
display: inline-block;
height: 100%;

.icon-container {
display: flex;
justify-content: center;
align-items: center;
}

&.vue-record-audio {}

&.vue-record-video {}
}

// &.active > .icon-container {
// -webkit-animation: pulse 1.25s infinite cubic-bezier(0.66, 0, 0, 1);
// -moz-animation: pulse 1.25s infinite cubic-bezier(0.66, 0, 0, 1);
// animation: pulse 1.25s infinite cubic-bezier(0.66, 0, 0, 1);
// }

// @keyframes pulse {
// to {
// -webkit-transform: scale(0.9);
// transform: scale(0.9);
// }
// }
9 changes: 5 additions & 4 deletions src/components/ElementMixin.js → lib/mixins/Element.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import RecorderMixin from './RecorderMixin'
import RecorderMixin from './Recorder'
import StyleMixin from './Style'

/**
* The element mixin defines the mode behaviour and creates two
* functions to start and stop the recording execution
*/
export default {
mixins: [RecorderMixin],
mixins: [RecorderMixin, StyleMixin],
props: {
mode: {
type: String,
Expand All @@ -14,13 +15,13 @@ export default {
}
},
methods: {
stopRecording () {
stopRecording() {
if (this.mode === 'press') {
return
}
return this.stop()
},
startRecording () {
startRecording() {
if (this.isRecording && this.mode === 'press') {
return this.stop()
}
Expand Down
File renamed without changes.
43 changes: 43 additions & 0 deletions lib/mixins/Style.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export default {
props: {
color: {
type: String,
default: '#000'
},
bgColor: {
type: String,
default: '#eee'
},
padding: {
type: Number,
default: 4
},
size: {
type: [Number, String],
default: 64
},
radius: {
type: Number,
default: 0
},
rounded: Boolean,
},
computed: {
backgroundStyle() {
return {
backgroundColor: this.bgColor,
width: `${this.size}px`,
height: `${this.size}px`,
borderRadius: `${this.radius}px`,
padding: `${this.padding}px`
}
},
foregroundStyle() {
return {
fill: this.color,
width: this.size,
height: this.size,
}
}
}
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"scripts": {
"prepublishOnly": "npm run build",
"serve": "vue-cli-service serve --open",
"build": "vue-cli-service build --target lib --name VueRecord src/components/index.js",
"build": "vue-cli-service build --target lib --name VueRecord lib/index.js",
"build:demo": "vue-cli-service build --dest demo",
"publish:demo": "git subtree push --prefix demo origin gh-pages",
"lint": "vue-cli-service lint"
Expand Down Expand Up @@ -48,4 +48,4 @@
"publishConfig": {
"access": "public"
}
}
}
44 changes: 30 additions & 14 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
<div id="app">
<header class="header">
<div class="navbar-brand">
<img alt="Vue logo" src="./assets/logo.png">
<img alt="Vue logo" src="./assets/logo.png" />
</div>

<div class="navbar-brand-name">
<h1 class="title">Vue Record</h1>
<h2 class="subtitle">
components for MediaRecorder API
</h2>
<h2 class="subtitle">components for MediaRecorder API</h2>
</div>
</header>

Expand All @@ -19,7 +17,10 @@
<div class="column">
<div class="has-text-right">
<h3 class="title is-3">Recording audio files</h3>
<p class="subtitle">Simply <strong>{{recordMode.audio}}</strong> the button to record an audio clip</p>
<p class="subtitle">
Simply
<strong>{{recordMode.audio}}</strong> the button to record an audio clip
</p>
</div>

<div class="record-settings">
Expand All @@ -38,8 +39,12 @@
<div class="column">
<div class="recorded-audio">
<div v-for="(record, index) in recordings" :key="index" class="recorded-item">
<div class="audio-container"><audio :src="record.src" controls /></div>
<div><button @click="removeRecord(index)" class="button is-dark">delete</button></div>
<div class="audio-container">
<audio :src="record.src" controls />
</div>
<div>
<button @click="removeRecord(index)" class="button is-dark">delete</button>
</div>
</div>
</div>
</div>
Expand All @@ -51,7 +56,10 @@
<div class="column">
<div class="has-text-right">
<h3 class="title is-3">Recording video files</h3>
<p class="subtitle">Simply <strong>{{recordMode.video}}</strong> the button to record a video clip</p>
<p class="subtitle">
Simply
<strong>{{recordMode.video}}</strong> the button to record a video clip
</p>
</div>

<div class="record-settings">
Expand Down Expand Up @@ -79,8 +87,12 @@
<footer class="footer">
<div class="content has-text-centered">
<p>
The source code is licensed <a href="https://github.com/codekraft-studio/vue-record/blob/master/LICENSE">MIT</a>.
Made with ♥ by <a href="https://github.com/codekraft-studio">Codekraft Studio</a>.
The source code is licensed
<a
href="https://github.com/codekraft-studio/vue-record/blob/master/LICENSE"
>MIT</a>.
Made with ♥ by
<a href="https://github.com/codekraft-studio">Codekraft Studio</a>.
</p>
</div>
</footer>
Expand Down Expand Up @@ -123,18 +135,21 @@ export default {
</script>

<style lang="scss">
html, body, #app {
html,
body,
#app {
width: 100%;
height: 100%;
}
#app {
display: flex;
flex-direction: column;
main{
main {
height: 100%;
}
strong, a {
strong,
a {
color: #41b883 !important;
}
Expand All @@ -156,14 +171,15 @@ html, body, #app {
}
}
.vue-audio-recorder, .vue-video-recorder {
.vue-record {
margin-right: 16px;
}
.record-settings {
margin-top: 16px;
display: flex;
justify-content: flex-end;
align-items: center;
}
.recorded-audio {
Expand Down
Loading

0 comments on commit 9fbb2fa

Please sign in to comment.