mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-10 19:14:16 +00:00
improve creator
This commit is contained in:
parent
a3f1892e8a
commit
55755364b5
@ -0,0 +1,151 @@
|
|||||||
|
import React from "react"
|
||||||
|
import * as antd from "antd"
|
||||||
|
import { Icons } from "components/Icons"
|
||||||
|
import UploadButton from "components/UploadButton"
|
||||||
|
|
||||||
|
export default (props) => {
|
||||||
|
const [playlistName, setPlaylistName] = React.useState(props.playlist.title)
|
||||||
|
const [playlistDescription, setPlaylistDescription] = React.useState(props.playlist.description)
|
||||||
|
const [playlistThumbnail, setPlaylistThumbnail] = React.useState(props.playlist.thumbnail)
|
||||||
|
const [playlistVisibility, setPlaylistVisibility] = React.useState(props.playlist.visibility)
|
||||||
|
|
||||||
|
const handleTitleOnChange = (event) => {
|
||||||
|
setPlaylistName(event.target.value)
|
||||||
|
|
||||||
|
props.onTitleChange(event.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDescriptionOnChange = (event) => {
|
||||||
|
setPlaylistDescription(event.target.value)
|
||||||
|
|
||||||
|
props.onDescriptionChange(event.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCoverChange = (file) => {
|
||||||
|
setPlaylistThumbnail(file.url)
|
||||||
|
|
||||||
|
props.onPlaylistCoverChange(file.url)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleRemoveCover = () => {
|
||||||
|
setPlaylistThumbnail(null)
|
||||||
|
|
||||||
|
props.onPlaylistCoverChange(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleVisibilityChange = (value) => {
|
||||||
|
setPlaylistVisibility(value)
|
||||||
|
|
||||||
|
props.onVisibilityChange(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div className="playlistCreator_layout_row">
|
||||||
|
<div
|
||||||
|
className="playlistCreator_layout_column"
|
||||||
|
>
|
||||||
|
<div className="field">
|
||||||
|
<div className="field_header">
|
||||||
|
<Icons.MdOutlineMusicNote />
|
||||||
|
<span>Title</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<antd.Input
|
||||||
|
className="inputText"
|
||||||
|
placeholder="Playlist Title"
|
||||||
|
size="large"
|
||||||
|
bordered={false}
|
||||||
|
value={playlistName}
|
||||||
|
onChange={handleTitleOnChange}
|
||||||
|
maxLength={120}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="field">
|
||||||
|
<div className="field_header">
|
||||||
|
<Icons.MdOutlineDescription />
|
||||||
|
<span>Description</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<antd.Input.TextArea
|
||||||
|
className="inputText"
|
||||||
|
placeholder="Description (Support Markdown)"
|
||||||
|
bordered={false}
|
||||||
|
value={playlistDescription}
|
||||||
|
onChange={handleDescriptionOnChange}
|
||||||
|
maxLength={2500}
|
||||||
|
rows={4}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<antd.Divider />
|
||||||
|
|
||||||
|
<div className="field">
|
||||||
|
<div className="field_header">
|
||||||
|
<Icons.Eye />
|
||||||
|
<span>Visibility</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<antd.Select
|
||||||
|
value={playlistVisibility}
|
||||||
|
onChange={handleVisibilityChange}
|
||||||
|
defaultValue={props.playlist.public ? "public" : "private"}
|
||||||
|
>
|
||||||
|
<antd.Select.Option value="public">Public</antd.Select.Option>
|
||||||
|
<antd.Select.Option value="private">Private</antd.Select.Option>
|
||||||
|
</antd.Select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="playlistCreator_layout_column"
|
||||||
|
style={{
|
||||||
|
width: "50%",
|
||||||
|
maxWidth: "300px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="field">
|
||||||
|
<div className="field_header">
|
||||||
|
<Icons.MdImage />
|
||||||
|
<span>Cover</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="coverPreview">
|
||||||
|
<div className="coverPreview_preview">
|
||||||
|
<img src={playlistThumbnail ?? "/assets/no_song.png"} alt="Thumbnail" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="coverPreview_actions">
|
||||||
|
<UploadButton
|
||||||
|
onUploadDone={handleCoverChange}
|
||||||
|
multiple={false}
|
||||||
|
accept="image/*"
|
||||||
|
>
|
||||||
|
Upload cover
|
||||||
|
</UploadButton>
|
||||||
|
|
||||||
|
<antd.Button
|
||||||
|
onClick={handleRemoveCover}
|
||||||
|
disabled={!playlistThumbnail}
|
||||||
|
icon={<Icons.MdClose />}
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
Remove Cover
|
||||||
|
</antd.Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<antd.Divider />
|
||||||
|
|
||||||
|
<div className="field">
|
||||||
|
<antd.Button
|
||||||
|
onClick={props.onDeletePlaylist}
|
||||||
|
icon={<Icons.MdDelete />}
|
||||||
|
danger
|
||||||
|
>
|
||||||
|
Delete Playlist
|
||||||
|
</antd.Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
@ -0,0 +1,323 @@
|
|||||||
|
import React from "react"
|
||||||
|
import * as antd from "antd"
|
||||||
|
import classnames from "classnames"
|
||||||
|
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd"
|
||||||
|
import UploadButton from "components/UploadButton"
|
||||||
|
|
||||||
|
import { Icons } from "components/Icons"
|
||||||
|
|
||||||
|
import "./index.less"
|
||||||
|
|
||||||
|
const UploadHint = (props) => {
|
||||||
|
return <div className="uploadHint">
|
||||||
|
<Icons.MdPlaylistAdd />
|
||||||
|
<p>Upload your tracks</p>
|
||||||
|
<p>Drag and drop your tracks here or click this box to start uploading files.</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const FileItemEditor = (props) => {
|
||||||
|
const [track, setTrack] = React.useState(props.track ?? {})
|
||||||
|
|
||||||
|
const handleChange = (key, value) => {
|
||||||
|
setTrack((oldData) => {
|
||||||
|
return {
|
||||||
|
...oldData,
|
||||||
|
[key]: value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const onClose = () => {
|
||||||
|
if (typeof props.close === "function") {
|
||||||
|
props.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSave = async () => {
|
||||||
|
await props.onSave(track)
|
||||||
|
|
||||||
|
if (typeof props.close === "function") {
|
||||||
|
props.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div className="fileItemEditor">
|
||||||
|
<div className="fileItemEditor_field">
|
||||||
|
<div className="fileItemEditor_field_header">
|
||||||
|
<Icons.MdImage />
|
||||||
|
<span>Thumbnail</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="fileItemEditor_field_thumnail">
|
||||||
|
<img src={track.thumbnail} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="fileItemEditor_actions">
|
||||||
|
<UploadButton
|
||||||
|
accept="image/*"
|
||||||
|
onUploadDone={(file) => handleChange("thumbnail", file.url)}
|
||||||
|
/>
|
||||||
|
{
|
||||||
|
track.thumbnail && <antd.Button
|
||||||
|
icon={<Icons.MdClose />}
|
||||||
|
type="text"
|
||||||
|
onClick={() => handleChange("thumbnail", null)}
|
||||||
|
>
|
||||||
|
Remove
|
||||||
|
</antd.Button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="fileItemEditor_field">
|
||||||
|
<div className="fileItemEditor_field_header">
|
||||||
|
<Icons.MdOutlineMusicNote />
|
||||||
|
<span>Title</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<antd.Input
|
||||||
|
value={track.title}
|
||||||
|
placeholder="Track title"
|
||||||
|
onChange={(e) => handleChange("title", e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="fileItemEditor_field">
|
||||||
|
<div className="fileItemEditor_field_header">
|
||||||
|
<Icons.User />
|
||||||
|
<span>Artist</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<antd.Input
|
||||||
|
value={track.artist}
|
||||||
|
placeholder="Artist"
|
||||||
|
onChange={(e) => handleChange("artist", e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="fileItemEditor_field">
|
||||||
|
<div className="fileItemEditor_field_header">
|
||||||
|
<Icons.MdAlbum />
|
||||||
|
<span>Album</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<antd.Input
|
||||||
|
value={track.album}
|
||||||
|
placeholder="Album"
|
||||||
|
onChange={(e) => handleChange("album", e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="fileItemEditor_field">
|
||||||
|
<div className="fileItemEditor_field_header">
|
||||||
|
<Icons.MdExplicit />
|
||||||
|
<span>Explicit</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<antd.Switch
|
||||||
|
checked={track.explicit}
|
||||||
|
onChange={(value) => handleChange("explicit", value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="fileItemEditor_actions">
|
||||||
|
<antd.Button
|
||||||
|
type="text"
|
||||||
|
icon={<Icons.MdClose />}
|
||||||
|
onClick={onClose}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</antd.Button>
|
||||||
|
|
||||||
|
<antd.Button
|
||||||
|
type="primary"
|
||||||
|
icon={<Icons.MdCheck />}
|
||||||
|
onClick={onSave}
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</antd.Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const FileListItem = (props) => {
|
||||||
|
const isUploading = props.track.status === "uploading"
|
||||||
|
|
||||||
|
return <Draggable key={props.track.uid} draggableId={props.track.uid} index={props.index}>
|
||||||
|
{(provided, snapshot) => {
|
||||||
|
return <div
|
||||||
|
className={classnames(
|
||||||
|
"fileListItem",
|
||||||
|
{
|
||||||
|
["uploading"]: isUploading,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
ref={provided.innerRef}
|
||||||
|
{...provided.draggableProps}
|
||||||
|
>
|
||||||
|
|
||||||
|
{
|
||||||
|
isUploading &&
|
||||||
|
<Icons.LoadingOutlined
|
||||||
|
spin
|
||||||
|
className="fileListItem_loadingIcon"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
|
<div className="fileListItem_cover">
|
||||||
|
<img
|
||||||
|
src={props.track?.thumbnail}
|
||||||
|
alt="Track cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="fileListItem_details">
|
||||||
|
<div className="fileListItem_namings">
|
||||||
|
<h4>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
marginRight: "0.6rem",
|
||||||
|
fontSize: "0.7rem"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.index + 1} -
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{
|
||||||
|
props.track?.title ?? "Unknown title"
|
||||||
|
}
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "0.6rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
{
|
||||||
|
props.track?.artist ?? "Unknown artist"
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span>-</span>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
{
|
||||||
|
props.track?.album ?? "Unknown album"
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="fileListItem_actions">
|
||||||
|
<antd.Button
|
||||||
|
type="primary"
|
||||||
|
icon={<Icons.MdEdit />}
|
||||||
|
onClick={props.onClickEdit}
|
||||||
|
disabled={isUploading}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<antd.Popconfirm
|
||||||
|
title="Delete this track?"
|
||||||
|
description="Are you sure to delete this track?"
|
||||||
|
onConfirm={props.onClickRemove}
|
||||||
|
okText="Yes"
|
||||||
|
cancelText="No"
|
||||||
|
>
|
||||||
|
<antd.Button
|
||||||
|
icon={<Icons.MdDelete />}
|
||||||
|
/>
|
||||||
|
</antd.Popconfirm>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
{...provided.dragHandleProps}
|
||||||
|
className="fileListItem_dragHandle"
|
||||||
|
>
|
||||||
|
<Icons.MdDragIndicator />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}}
|
||||||
|
</Draggable>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (props) => {
|
||||||
|
const onClickEditTrack = (track) => {
|
||||||
|
console.log("Editing track", track)
|
||||||
|
|
||||||
|
app.DrawerController.open("track_editor", FileItemEditor, {
|
||||||
|
type: "drawer",
|
||||||
|
componentProps: {
|
||||||
|
track,
|
||||||
|
onSave: (newTrackData) => {
|
||||||
|
props.handleTrackInfoChange(newTrackData.uid, newTrackData)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div className="tracksUploads">
|
||||||
|
<p>
|
||||||
|
Uploading files that are not permitted by our <a onClick={() => app.setLocation("/terms")}>Terms of Service</a> may result in your account being suspended.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="uploadBox">
|
||||||
|
<antd.Upload
|
||||||
|
className="uploader"
|
||||||
|
customRequest={props.handleUploadTrack}
|
||||||
|
onChange={props.onTrackUploaderChange}
|
||||||
|
accept="audio/*"
|
||||||
|
multiple
|
||||||
|
showUploadList={false}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props.fileList.length === 0 ?
|
||||||
|
<UploadHint /> : <antd.Button
|
||||||
|
className="uploadMoreButton"
|
||||||
|
icon={<Icons.Plus />}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</antd.Upload>
|
||||||
|
|
||||||
|
<div className="fileList_wrapper">
|
||||||
|
<DragDropContext onDragEnd={props.handleTrackDragEnd}>
|
||||||
|
<Droppable droppableId="droppable">
|
||||||
|
{(provided, snapshot) => (
|
||||||
|
<div
|
||||||
|
{...provided.droppableProps}
|
||||||
|
ref={provided.innerRef}
|
||||||
|
className="fileList"
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props.trackList.map((track, index) => {
|
||||||
|
return <FileListItem
|
||||||
|
index={index}
|
||||||
|
track={track}
|
||||||
|
onClickChangeCover={() => {
|
||||||
|
return props.handleTrackCoverChange(track.uid)
|
||||||
|
}}
|
||||||
|
onTitleChange={(event) => {
|
||||||
|
return props.handleTrackInfoChange(track.uid, "title", event.target.value)
|
||||||
|
}}
|
||||||
|
onClickRemove={() => {
|
||||||
|
return props.handleTrackRemove(track.uid)
|
||||||
|
}}
|
||||||
|
onClickEdit={() => {
|
||||||
|
return onClickEditTrack(track)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
{provided.placeholder}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Droppable>
|
||||||
|
</DragDropContext>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
@ -0,0 +1,344 @@
|
|||||||
|
.tracksUploads {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.uploadBox {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
//height: 100%;
|
||||||
|
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
overflow-y: hidden;
|
||||||
|
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
|
.ant-upload {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.uploadMoreButton {
|
||||||
|
width: 100%;
|
||||||
|
height: 30px;
|
||||||
|
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
background-color: transparent;
|
||||||
|
|
||||||
|
outline: 1px solid var(--border-color);
|
||||||
|
|
||||||
|
box-shadow: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
height: 70px;
|
||||||
|
background-color: var(--background-color-accent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-upload-wrapper {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileList_wrapper {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
// add a blur effect on top and bottom to decorate overflown content
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
z-index: 50;
|
||||||
|
content: "";
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
background: linear-gradient(0deg,
|
||||||
|
rgba(255, 255, 255, 0) 0%,
|
||||||
|
var(--background-color-primary) 40%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
background: linear-gradient(180deg,
|
||||||
|
rgba(255, 255, 255, 0) 0%,
|
||||||
|
var(--background-color-primary) 40%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileList {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
max-height: 60vh;
|
||||||
|
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
padding: 15px 0;
|
||||||
|
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
.fileListItem {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
z-index: 49;
|
||||||
|
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
|
background-color: var(--background-color-accent);
|
||||||
|
color: var(--text-color);
|
||||||
|
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
&.uploading {
|
||||||
|
.fileListItem_cover {
|
||||||
|
img {
|
||||||
|
filter: blur(3px);
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileListItem_loadingIcon {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-btn {
|
||||||
|
svg {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileListItem_cover {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
|
||||||
|
object-fit: cover;
|
||||||
|
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileListItem_details {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
margin-left: 20px;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.fileListItem_namings {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileListItem_artist {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileListItem_actions {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.ant-btn {
|
||||||
|
svg {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileListItem_dragHandle {
|
||||||
|
color: var(--text-color);
|
||||||
|
|
||||||
|
svg {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploadHint {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
align-self: center;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
font-size: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileItemEditor {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
|
.fileItemEditor_actions {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
align-self: center;
|
||||||
|
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileItemEditor_field {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.fileItemEditor_field_header {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
//margin-bottom: 10px;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileItemEditor_field_actions {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileItemEditor_field_thumnail {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 15vw;
|
||||||
|
height: 15vw;
|
||||||
|
|
||||||
|
max-width: 330px;
|
||||||
|
max-height: 330px;
|
||||||
|
|
||||||
|
object-fit: cover;
|
||||||
|
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
background-color: black;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -1,14 +1,68 @@
|
|||||||
.playlistCreator {
|
.playlistCreator {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
//justify-content: center;
|
||||||
|
|
||||||
width: 100%;
|
width: 50vw;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
min-width: 800px;
|
||||||
|
|
||||||
transition: all 0.3s ease-in-out;
|
transition: all 0.3s ease-in-out;
|
||||||
|
|
||||||
|
.stepContent {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepActions {
|
||||||
|
position: sticky;
|
||||||
|
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
//justify-content: flex-end;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
background-color: var(--background-color-accent);
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.playlistCreator_layout_row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
|
.playlistCreator_layout_column {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.actions {
|
.actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@ -19,256 +73,80 @@
|
|||||||
gap: 20px;
|
gap: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.inputField {
|
.field {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
flex-direction: row;
|
flex-direction: column;
|
||||||
|
|
||||||
align-self: start;
|
align-self: start;
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-start;
|
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
|
||||||
font-size: 2rem;
|
gap: 10px;
|
||||||
|
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
|
|
||||||
h1,
|
.field_header {
|
||||||
h2,
|
font-size: 1rem;
|
||||||
h3,
|
|
||||||
h4,
|
|
||||||
h5,
|
|
||||||
h6,
|
|
||||||
p,
|
|
||||||
span {
|
|
||||||
color: var(--text-color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.inputText {
|
.inputText {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
color: var(--text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.coverUploader {
|
background-color: transparent;
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.coverPreview {
|
outline: 1px solid var(--border-color);
|
||||||
height: 5vh;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.coverPreview {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
.coverPreview_preview {
|
||||||
|
align-self: center;
|
||||||
|
|
||||||
|
width: 15vw;
|
||||||
|
height: 15vw;
|
||||||
|
|
||||||
|
max-width: 300px;
|
||||||
|
max-height: 300px;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
height: 100%;
|
width: 15vw;
|
||||||
border-radius: 10px;
|
height: 15vw;
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
svg {
|
max-width: 300px;
|
||||||
margin: 0 !important;
|
max-height: 300px;
|
||||||
|
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.files {
|
.coverPreview_actions {
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
border: 1px solid var(--border-color);
|
|
||||||
border-radius: 8px;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
padding: 10px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
|
|
||||||
.ant-upload {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: row;
|
||||||
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-upload-wrapper {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fileList {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.fileListItem {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
display: inline-flex;
|
|
||||||
flex-direction: row;
|
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
border-radius: 8px;
|
|
||||||
|
|
||||||
background-color: var(--background-color-accent);
|
|
||||||
|
|
||||||
border: 1px solid var(--border-color);
|
|
||||||
|
|
||||||
margin-bottom: 10px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.uploading {
|
|
||||||
.fileListItem_cover {
|
|
||||||
img {
|
|
||||||
filter: blur(3px);
|
|
||||||
}
|
|
||||||
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.fileListItem_loadingIcon {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
margin: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-btn {
|
|
||||||
svg {
|
|
||||||
margin: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.fileListItem_title_label {
|
|
||||||
display: inline-flex;
|
|
||||||
flex-direction: row;
|
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fileListItem_cover {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
object-fit: cover;
|
|
||||||
border-radius: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fileListItem_cover_mask {
|
|
||||||
opacity: 0;
|
|
||||||
backdrop-filter: blur(3px);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.fileListItem_cover_mask {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.fileListItem_details {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
margin-left: 10px;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.fileListItem_title {
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.ant-input {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.fileListItem_actions {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
margin-top: 20px;
|
|
||||||
|
|
||||||
margin-left: 10px;
|
|
||||||
|
|
||||||
.ant-btn {
|
|
||||||
svg {
|
|
||||||
margin: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
margin-right: 10px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.fileListItem_dragHandle {
|
|
||||||
svg {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
margin: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.uploadHint {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
align-self: center;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
font-size: 3rem;
|
margin: 0 !important;
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer {
|
.ant-steps-icon {
|
||||||
position: relative;
|
svg {
|
||||||
padding: 10px;
|
margin: 0 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user