168 lines
4.9 KiB
Vue
168 lines
4.9 KiB
Vue
<script setup lang="ts">
|
|
import { computed, ref } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
import onKeyboardShortcut from '~/composables/onKeyboardShortcut';
|
|
|
|
import { useModal } from '~/ui/composables/useModal.ts'
|
|
|
|
import Modal from '~/components/ui/Modal.vue'
|
|
import Button from '~/components/ui/Button.vue'
|
|
import Input from '~/components/ui/Input.vue'
|
|
import Layout from '~/components/ui/Layout.vue'
|
|
import Spacer from '~/components/ui/Spacer.vue'
|
|
import Alert from '~/components/ui/Alert.vue';
|
|
import Card from '~/components/ui/Card.vue';
|
|
import Pagination from '~/components/ui/Pagination.vue';
|
|
|
|
import type { Actor, Channel } from '~/types';
|
|
import FileUploadWidget from '~/components/library/FileUploadWidget.vue';
|
|
import type { VueUploadItem } from 'vue-upload-component';
|
|
import ChannelUpload from '~/components/channels/UploadForm.vue';
|
|
import LibraryUpload from '~/components/library/FileUpload.vue';
|
|
import LibraryWidget from '~/components/federation/LibraryWidget.vue'
|
|
|
|
const { t } = useI18n()
|
|
|
|
onKeyboardShortcut('u', () => useModal('upload').toggle())
|
|
|
|
const isOpen = useModal('upload').isOpen
|
|
|
|
type UploadDestination = 'channel' | 'library' | 'podcast'
|
|
|
|
type State =
|
|
{ uploadDestination? : UploadDestination, page: typeof pages[number], files?: string[] }
|
|
|
|
// initial state
|
|
const init = () => ({ page : 'selectDestination' } as const)
|
|
const state = ref<State>(init())
|
|
|
|
const pages = ['selectDestination', 'uploadFiles', 'uploadsInProgress'] as const
|
|
|
|
// Step 1
|
|
const destinationSelected = (destination: UploadDestination) =>
|
|
state.value = {...state.value, uploadDestination:destination, page:'uploadFiles' }
|
|
|
|
// Wait for pablo: If no channel exists, auto-create an empty channel
|
|
|
|
// Step 1.1
|
|
|
|
/*
|
|
- Load the library for the chosen privacy level
|
|
-
|
|
*/
|
|
|
|
// Lade User
|
|
const url="`federation/actors/${object.full_username}/libraries/`"
|
|
|
|
//
|
|
|
|
// Step 2
|
|
const filesSelected = (e: InputEvent)=>{
|
|
state.value = {...state.value, files: [] }
|
|
}
|
|
|
|
const modalTitle = computed(()=>
|
|
({ 'selectDestination' : 'Upload', 'uploadFiles' : 'Select files for upload', 'uploadsInProgress': 'Uploading...'}
|
|
[state.value.page])
|
|
)
|
|
|
|
const channelUpload = ref();
|
|
</script>
|
|
|
|
<template>
|
|
<Modal overPopover
|
|
:title="modalTitle"
|
|
v-model="isOpen"
|
|
>
|
|
|
|
<!-- Alert -->
|
|
|
|
<template #alert v-if="state.page === 'selectDestination'">
|
|
<Alert blue>
|
|
Before uploading, please ensure your files are tagged properly.
|
|
We recommend using Picard for that purpose.
|
|
</Alert>
|
|
</template>
|
|
|
|
<!-- Page content -->
|
|
<!-- Page 1 -->
|
|
|
|
<Layout flex style="place-content:center" v-if="state.page === 'selectDestination'">
|
|
<Card small title="Music"
|
|
icon="bi-upload primary solid"
|
|
@click="destinationSelected('channel')"
|
|
>
|
|
<template #image>
|
|
<i class="bi bi-music-note-beamed solid primary" :class="$style.icon"></i>
|
|
</template>
|
|
{{ "Publish music you make" /* TODO: Translate */ }}
|
|
</Card>
|
|
<Card small title="Podcast"
|
|
icon="bi-upload primary solid"
|
|
@click="destinationSelected('podcast')"
|
|
>
|
|
<template #image>
|
|
<i class="bi bi-mic-fill solid primary" :class="$style.icon"></i>
|
|
</template>
|
|
{{ "Publish podcasts you make" /* TODO: Translate */ }}
|
|
</Card>
|
|
<Card small title="Mix & Share"
|
|
icon="bi-upload"
|
|
@click="destinationSelected('library')"
|
|
>
|
|
<template #image>
|
|
<i class="bi bi-headphones solid secondary raised" :class="$style.icon"></i>
|
|
</template>
|
|
{{ "Host music you listen to" /* TODO: Translate */ }}
|
|
</Card>
|
|
</Layout>
|
|
|
|
<!-- Page 2 -->
|
|
|
|
<Layout stack v-if="state.page === 'uploadFiles'">
|
|
|
|
<!-- -->
|
|
|
|
<ChannelUpload ref="channelUpload" v-if="state.uploadDestination === 'channel'" />
|
|
|
|
<!-- -->
|
|
|
|
<!-- Privacy Slider -->
|
|
<!-- <LibraryUpload v-if="state.uploadDestination === 'library'"
|
|
:library="{uuid: 'string'} /* Get corresponding library from user */">
|
|
</LibraryUpload> -->
|
|
{{ state.files }}
|
|
</Layout>
|
|
|
|
<template #actions>
|
|
<Button secondary
|
|
v-if="state.page !== pages[0]"
|
|
:onClick="() => { state.page = pages[(pages.indexOf(state.page) || 1) - 1] }">
|
|
{{ t('components.channels.UploadModal.button.previous') }}
|
|
</Button>
|
|
<Spacer h grow />
|
|
<Button secondary :onClick="() => { isOpen = false }">
|
|
{{ t('components.channels.UploadModal.button.cancel') }}
|
|
</Button>
|
|
<Spacer size-16 />
|
|
<Button primary v-if="state.page === 'uploadFiles'">
|
|
{{ t('components.channels.UploadModal.button.finishLater') }} /
|
|
{{ t('components.channels.UploadModal.button.update') }}
|
|
</Button>
|
|
<Button v-if="channelUpload" :onClick="() => channelUpload.publish()">
|
|
{{ t('components.channels.UploadModal.button.publish') }}
|
|
</Button>
|
|
</template>
|
|
</Modal>
|
|
</template>
|
|
|
|
<style module>
|
|
.icon {
|
|
font-size:100px;
|
|
padding:28px;
|
|
inset:0;
|
|
display:block;
|
|
text-align: center;
|
|
}
|
|
</style>
|