mirror of
https://github.com/anatolykopyl/movieroom-front.git
synced 2026-03-26 12:55:20 +00:00
Direct file upload
This commit is contained in:
@@ -1,5 +1,18 @@
|
||||
import api from '@/api/index';
|
||||
|
||||
export default (magnet:String) => api.post('/room', {
|
||||
magnet,
|
||||
export default (movie: String | File) => {
|
||||
if (typeof movie === 'string') {
|
||||
return api.post('/roomMagnet', {
|
||||
magnet: movie,
|
||||
}).then((response) => response.data);
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', movie as Blob);
|
||||
|
||||
return api.post('/roomFile', formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
}).then((response) => response.data);
|
||||
};
|
||||
|
||||
39
src/components/Spinner.vue
Normal file
39
src/components/Spinner.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<svg class="spinner" viewBox="0 0 50 50">
|
||||
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.spinner {
|
||||
animation: rotate 2s linear infinite;
|
||||
|
||||
& .path {
|
||||
stroke: currentColor;
|
||||
stroke-linecap: round;
|
||||
animation: dash 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dash {
|
||||
0% {
|
||||
stroke-dasharray: 1, 150;
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
50% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -35;
|
||||
}
|
||||
100% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -124;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,6 @@
|
||||
export interface Room {
|
||||
id: string;
|
||||
magnet: string;
|
||||
magnet?: string;
|
||||
createdAt: Date;
|
||||
movie?: string;
|
||||
filename?: string;
|
||||
|
||||
@@ -12,13 +12,13 @@ html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
button, input[type="text"], textarea {
|
||||
button, input[type="text"], input[type="file"], textarea {
|
||||
padding: 8px 12px;
|
||||
background: none;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
button, a {
|
||||
button, a, input[type="file"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -29,3 +29,13 @@ h1 {
|
||||
h2 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.secondary {
|
||||
color: #818181;
|
||||
}
|
||||
|
||||
::file-selector-button {
|
||||
background: none;
|
||||
border: 1px solid black;
|
||||
font-family: 'EB Garamond', serif;
|
||||
}
|
||||
@@ -1,16 +1,29 @@
|
||||
<template>
|
||||
<div class="home">
|
||||
<form @submit.prevent>
|
||||
<input
|
||||
type="file"
|
||||
placeholder="file"
|
||||
@change="handleFile"
|
||||
accept="video/mp4"
|
||||
>
|
||||
|
||||
<div class="secondary">or</div>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
v-model="magnet"
|
||||
placeholder="magnet link"
|
||||
>
|
||||
|
||||
<div class="submit">
|
||||
<button
|
||||
@click="submit"
|
||||
>
|
||||
create room
|
||||
</button>
|
||||
<Spinner v-if="waiting" class="spinner" />
|
||||
</div>
|
||||
</form>
|
||||
<a href="https://nutbread.github.io/t2m/">convert .torrent file to a magnet link</a>
|
||||
</div>
|
||||
@@ -19,21 +32,40 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import createRoom from '@/api/createRoom';
|
||||
import Spinner from '@/components/Spinner.vue';
|
||||
|
||||
import { Room } from '@/interfaces';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Home',
|
||||
components: {
|
||||
Spinner,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
magnet: '',
|
||||
file: undefined as File | undefined,
|
||||
waiting: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async submit() {
|
||||
const room: Room = await createRoom(this.magnet);
|
||||
this.waiting = true;
|
||||
let room: Room;
|
||||
if (this.file) {
|
||||
room = await createRoom(this.file);
|
||||
} else {
|
||||
room = await createRoom(this.magnet);
|
||||
}
|
||||
this.waiting = false;
|
||||
this.$router.push({ name: 'Room', params: { id: room.id } });
|
||||
},
|
||||
handleFile(event: Event) {
|
||||
const element = (event.target as HTMLInputElement);
|
||||
if (element.files) {
|
||||
[this.file] = element.files;
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -43,7 +75,26 @@ form {
|
||||
margin-bottom: 32px;
|
||||
|
||||
> * {
|
||||
margin: 0 8px;
|
||||
display: block;
|
||||
margin: 8px 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.submit {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
position: absolute;
|
||||
right: -48px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -63,8 +63,10 @@ export default defineComponent({
|
||||
clearInterval(this.positionInterval);
|
||||
},
|
||||
methods: {
|
||||
onDownloaded() {
|
||||
this.room.downloaded = true;
|
||||
async onDownloaded() {
|
||||
if (!this.room.downloaded) {
|
||||
this.room = await getRoom(this.id);
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
const element = this.$refs.video as HTMLVideoElement;
|
||||
this.positionInterval = setInterval(async () => {
|
||||
|
||||
Reference in New Issue
Block a user