mirror of
https://github.com/ragestudio/comty.git
synced 2025-07-11 10:14:16 +00:00
use swappy
This commit is contained in:
parent
7ae3c19e7d
commit
bca40318bd
29
packages/app/src/components/MusicStudio/ReleaseEditor/tabs/Tracks/components/TrackListItem/index.jsx
29
packages/app/src/components/MusicStudio/ReleaseEditor/tabs/Tracks/components/TrackListItem/index.jsx
@ -25,7 +25,7 @@ const TrackListItem = (props) => {
|
|||||||
content: <TrackEditor />,
|
content: <TrackEditor />,
|
||||||
props: {
|
props: {
|
||||||
track: track,
|
track: track,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,24 +33,19 @@ const TrackListItem = (props) => {
|
|||||||
props.onDelete(track.uid)
|
props.onDelete(track.uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Draggable
|
console.log("render")
|
||||||
key={track._id ?? track.id}
|
|
||||||
draggableId={track.id ?? track._id}
|
return (
|
||||||
index={props.index}
|
<div
|
||||||
>
|
|
||||||
{
|
|
||||||
(provided, snapshot) => {
|
|
||||||
return <div
|
|
||||||
className={classnames(
|
className={classnames(
|
||||||
"music-studio-release-editor-tracks-list-item",
|
"music-studio-release-editor-tracks-list-item",
|
||||||
{
|
{
|
||||||
["loading"]: loading,
|
["loading"]: loading,
|
||||||
["failed"]: !!error,
|
["failed"]: !!error,
|
||||||
["disabled"]: props.disabled,
|
["disabled"]: props.disabled,
|
||||||
}
|
},
|
||||||
)}
|
)}
|
||||||
ref={provided.innerRef}
|
data-swapy-item={track.id ?? track._id}
|
||||||
{...provided.draggableProps}
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="music-studio-release-editor-tracks-list-item-progress"
|
className="music-studio-release-editor-tracks-list-item-progress"
|
||||||
@ -63,9 +58,7 @@ const TrackListItem = (props) => {
|
|||||||
<span>{props.index + 1}</span>
|
<span>{props.index + 1}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
{props.uploading.working && <Icons.LoadingOutlined />}
|
||||||
props.uploading.working && <Icons.LoadingOutlined />
|
|
||||||
}
|
|
||||||
|
|
||||||
<Image
|
<Image
|
||||||
src={track.cover}
|
src={track.cover}
|
||||||
@ -99,16 +92,14 @@ const TrackListItem = (props) => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
{...provided.dragHandleProps}
|
data-swapy-handle
|
||||||
className="music-studio-release-editor-tracks-list-item-dragger"
|
className="music-studio-release-editor-tracks-list-item-dragger"
|
||||||
>
|
>
|
||||||
<Icons.MdDragIndicator />
|
<Icons.MdDragIndicator />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
)
|
||||||
}
|
|
||||||
</Draggable>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TrackListItem
|
export default TrackListItem
|
@ -2,6 +2,7 @@ import React from "react"
|
|||||||
import * as antd from "antd"
|
import * as antd from "antd"
|
||||||
import classnames from "classnames"
|
import classnames from "classnames"
|
||||||
import { DragDropContext, Droppable } from "react-beautiful-dnd"
|
import { DragDropContext, Droppable } from "react-beautiful-dnd"
|
||||||
|
import { createSwapy } from "swapy"
|
||||||
|
|
||||||
import TrackManifest from "@cores/player/classes/TrackManifest"
|
import TrackManifest from "@cores/player/classes/TrackManifest"
|
||||||
|
|
||||||
@ -13,6 +14,8 @@ import UploadHint from "./components/UploadHint"
|
|||||||
import "./index.less"
|
import "./index.less"
|
||||||
|
|
||||||
class TracksManager extends React.Component {
|
class TracksManager extends React.Component {
|
||||||
|
swapyRef = React.createRef()
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
list: Array.isArray(this.props.list) ? this.props.list : [],
|
list: Array.isArray(this.props.list) ? this.props.list : [],
|
||||||
pendingUploads: [],
|
pendingUploads: [],
|
||||||
@ -26,6 +29,27 @@ class TracksManager extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.swapyRef.current = createSwapy(
|
||||||
|
document.getElementById("editor-tracks-list"),
|
||||||
|
{
|
||||||
|
animation: "dynamic",
|
||||||
|
dragAxis: "y",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
this.swapyRef.current.onSwapEnd((event) => {
|
||||||
|
console.log("end", event)
|
||||||
|
this.orderTrackList(
|
||||||
|
event.slotItemMap.asArray.map((item) => item.item),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.swapyRef.current.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
findTrackByUid = (uid) => {
|
findTrackByUid = (uid) => {
|
||||||
if (!uid) {
|
if (!uid) {
|
||||||
return false
|
return false
|
||||||
@ -54,7 +78,6 @@ class TracksManager extends React.Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
list: this.state.list.filter((item) => item.uid !== uid),
|
list: this.state.list.filter((item) => item.uid !== uid),
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
modifyTrackByUid = (uid, track) => {
|
modifyTrackByUid = (uid, track) => {
|
||||||
@ -82,7 +105,9 @@ class TracksManager extends React.Component {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
const pendingUpload = this.state.pendingUploads.find((item) => item.uid === uid)
|
const pendingUpload = this.state.pendingUploads.find(
|
||||||
|
(item) => item.uid === uid,
|
||||||
|
)
|
||||||
|
|
||||||
if (!pendingUpload) {
|
if (!pendingUpload) {
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -90,8 +115,8 @@ class TracksManager extends React.Component {
|
|||||||
...this.state.pendingUploads,
|
...this.state.pendingUploads,
|
||||||
{
|
{
|
||||||
uid: uid,
|
uid: uid,
|
||||||
progress: 0
|
progress: 0,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -103,12 +128,16 @@ class TracksManager extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
pendingUploads: this.state.pendingUploads.filter((item) => item.uid !== uid),
|
pendingUploads: this.state.pendingUploads.filter(
|
||||||
|
(item) => item.uid !== uid,
|
||||||
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getUploadProgress = (uid) => {
|
getUploadProgress = (uid) => {
|
||||||
const uploadProgressIndex = this.state.pendingUploads.findIndex((item) => item.uid === uid)
|
const uploadProgressIndex = this.state.pendingUploads.findIndex(
|
||||||
|
(item) => item.uid === uid,
|
||||||
|
)
|
||||||
|
|
||||||
if (uploadProgressIndex === -1) {
|
if (uploadProgressIndex === -1) {
|
||||||
return 0
|
return 0
|
||||||
@ -118,7 +147,9 @@ class TracksManager extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateUploadProgress = (uid, progress) => {
|
updateUploadProgress = (uid, progress) => {
|
||||||
const uploadProgressIndex = this.state.pendingUploads.findIndex((item) => item.uid === uid)
|
const uploadProgressIndex = this.state.pendingUploads.findIndex(
|
||||||
|
(item) => item.uid === uid,
|
||||||
|
)
|
||||||
|
|
||||||
if (uploadProgressIndex === -1) {
|
if (uploadProgressIndex === -1) {
|
||||||
return false
|
return false
|
||||||
@ -147,7 +178,7 @@ class TracksManager extends React.Component {
|
|||||||
const trackManifest = new TrackManifest({
|
const trackManifest = new TrackManifest({
|
||||||
uid: uid,
|
uid: uid,
|
||||||
file: change.file,
|
file: change.file,
|
||||||
onChange: this.modifyTrackByUid
|
onChange: this.modifyTrackByUid,
|
||||||
})
|
})
|
||||||
|
|
||||||
this.addTrackToList(trackManifest)
|
this.addTrackToList(trackManifest)
|
||||||
@ -158,7 +189,9 @@ class TracksManager extends React.Component {
|
|||||||
// remove pending file
|
// remove pending file
|
||||||
this.removeTrackUIDFromPendingUploads(uid)
|
this.removeTrackUIDFromPendingUploads(uid)
|
||||||
|
|
||||||
let trackManifest = this.state.list.find((item) => item.uid === uid)
|
let trackManifest = this.state.list.find(
|
||||||
|
(item) => item.uid === uid,
|
||||||
|
)
|
||||||
|
|
||||||
if (!trackManifest) {
|
if (!trackManifest) {
|
||||||
console.error(`Track with uid [${uid}] not found!`)
|
console.error(`Track with uid [${uid}] not found!`)
|
||||||
@ -195,13 +228,15 @@ class TracksManager extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uploadToStorage = async (req) => {
|
uploadToStorage = async (req) => {
|
||||||
const response = await app.cores.remoteStorage.uploadFile(req.file, {
|
const response = await app.cores.remoteStorage
|
||||||
|
.uploadFile(req.file, {
|
||||||
onProgress: this.handleTrackFileUploadProgress,
|
onProgress: this.handleTrackFileUploadProgress,
|
||||||
service: "b2",
|
service: "b2",
|
||||||
headers: {
|
headers: {
|
||||||
transmux: "a-dash"
|
transmux: "a-dash",
|
||||||
}
|
},
|
||||||
}).catch((error) => {
|
})
|
||||||
|
.catch((error) => {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
antd.message.error(error)
|
antd.message.error(error)
|
||||||
|
|
||||||
@ -219,20 +254,15 @@ class TracksManager extends React.Component {
|
|||||||
this.updateUploadProgress(file.uid, progress)
|
this.updateUploadProgress(file.uid, progress)
|
||||||
}
|
}
|
||||||
|
|
||||||
orderTrackList = (result) => {
|
orderTrackList = (orderedIdsArray) => {
|
||||||
if (!result.destination) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState((prev) => {
|
this.setState((prev) => {
|
||||||
const trackList = [...prev.list]
|
// move all list items by id
|
||||||
|
const orderedIds = orderedIdsArray.map((id) =>
|
||||||
const [removed] = trackList.splice(result.source.index, 1)
|
this.state.list.find((item) => item._id === id),
|
||||||
|
)
|
||||||
trackList.splice(result.destination.index, 0, removed)
|
console.log("orderedIds", orderedIds)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
list: trackList
|
list: orderedIds,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -240,7 +270,8 @@ class TracksManager extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
console.log(`Tracks List >`, this.state.list)
|
console.log(`Tracks List >`, this.state.list)
|
||||||
|
|
||||||
return <div className="music-studio-release-editor-tracks">
|
return (
|
||||||
|
<div className="music-studio-release-editor-tracks">
|
||||||
<antd.Upload
|
<antd.Upload
|
||||||
className="music-studio-tracks-uploader"
|
className="music-studio-tracks-uploader"
|
||||||
onChange={this.handleUploaderStateChange}
|
onChange={this.handleUploaderStateChange}
|
||||||
@ -249,65 +280,58 @@ class TracksManager extends React.Component {
|
|||||||
accept="audio/*"
|
accept="audio/*"
|
||||||
multiple
|
multiple
|
||||||
>
|
>
|
||||||
{
|
{this.state.list.length === 0 ? (
|
||||||
this.state.list.length === 0 ?
|
<UploadHint />
|
||||||
<UploadHint /> : <antd.Button
|
) : (
|
||||||
|
<antd.Button
|
||||||
className="uploadMoreButton"
|
className="uploadMoreButton"
|
||||||
icon={<Icons.FiPlus />}
|
icon={<Icons.FiPlus />}
|
||||||
>
|
>
|
||||||
Add another
|
Add another
|
||||||
</antd.Button>
|
</antd.Button>
|
||||||
}
|
)}
|
||||||
</antd.Upload>
|
</antd.Upload>
|
||||||
|
|
||||||
<DragDropContext
|
|
||||||
onDragEnd={this.orderTrackList}
|
|
||||||
>
|
|
||||||
<Droppable
|
|
||||||
droppableId="droppable"
|
|
||||||
>
|
|
||||||
{(provided, snapshot) => (
|
|
||||||
<div
|
<div
|
||||||
{...provided.droppableProps}
|
id="editor-tracks-list"
|
||||||
ref={provided.innerRef}
|
|
||||||
className="music-studio-release-editor-tracks-list"
|
className="music-studio-release-editor-tracks-list"
|
||||||
>
|
>
|
||||||
{
|
{this.state.list.length === 0 && (
|
||||||
this.state.list.length === 0 && <antd.Result
|
<antd.Result status="info" title="No tracks" />
|
||||||
status="info"
|
)}
|
||||||
title="No tracks"
|
|
||||||
/>
|
{this.state.list.map((track, index) => {
|
||||||
}
|
|
||||||
{
|
|
||||||
this.state.list.map((track, index) => {
|
|
||||||
const progress = this.getUploadProgress(track.uid)
|
const progress = this.getUploadProgress(track.uid)
|
||||||
|
|
||||||
return <TrackListItem
|
return (
|
||||||
|
<div data-swapy-slot={track._id ?? track.uid}>
|
||||||
|
<TrackListItem
|
||||||
index={index}
|
index={index}
|
||||||
track={track}
|
track={track}
|
||||||
onEdit={this.modifyTrackByUid}
|
onEdit={this.modifyTrackByUid}
|
||||||
onDelete={this.removeTrackByUid}
|
onDelete={this.removeTrackByUid}
|
||||||
uploading={{
|
uploading={{
|
||||||
progress: progress,
|
progress: progress,
|
||||||
working: this.state.pendingUploads.find((item) => item.uid === track.uid)
|
working: this.state.pendingUploads.find(
|
||||||
|
(item) => item.uid === track.uid,
|
||||||
|
),
|
||||||
}}
|
}}
|
||||||
disabled={progress > 0}
|
disabled={progress > 0}
|
||||||
/>
|
/>
|
||||||
})
|
|
||||||
}
|
|
||||||
{provided.placeholder}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)
|
||||||
</Droppable>
|
})}
|
||||||
</DragDropContext>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ReleaseTracks = (props) => {
|
const ReleaseTracks = (props) => {
|
||||||
const { state, setState } = props
|
const { state, setState } = props
|
||||||
|
|
||||||
return <div className="music-studio-release-editor-tab">
|
return (
|
||||||
|
<div className="music-studio-release-editor-tab">
|
||||||
<h1>Tracks</h1>
|
<h1>Tracks</h1>
|
||||||
|
|
||||||
<TracksManager
|
<TracksManager
|
||||||
@ -316,11 +340,12 @@ const ReleaseTracks = (props) => {
|
|||||||
onChangeState={(managerState) => {
|
onChangeState={(managerState) => {
|
||||||
setState({
|
setState({
|
||||||
...state,
|
...state,
|
||||||
...managerState
|
...managerState,
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ReleaseTracks
|
export default ReleaseTracks
|
Loading…
x
Reference in New Issue
Block a user