sa2kit 1.6.7 → 1.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/calendar/index.js +334 -399
- package/dist/calendar/index.js.map +1 -1
- package/dist/calendar/index.mjs +241 -306
- package/dist/calendar/index.mjs.map +1 -1
- package/dist/calendar/routes/index.js +21 -21
- package/dist/calendar/routes/index.mjs +1 -1
- package/dist/calendar/server.js +13 -13
- package/dist/calendar/server.mjs +2 -2
- package/dist/chunk-4FOBBWXW.mjs +179 -0
- package/dist/chunk-4FOBBWXW.mjs.map +1 -0
- package/dist/chunk-CDK3DHKM.mjs +634 -0
- package/dist/chunk-CDK3DHKM.mjs.map +1 -0
- package/dist/chunk-G6WRJ2H2.js +187 -0
- package/dist/chunk-G6WRJ2H2.js.map +1 -0
- package/dist/{chunk-6WXOA4BE.mjs → chunk-GVVS4IMM.mjs} +2 -2
- package/dist/chunk-GVVS4IMM.mjs.map +1 -0
- package/dist/chunk-L5PW2YTI.js +647 -0
- package/dist/chunk-L5PW2YTI.js.map +1 -0
- package/dist/{chunk-AXP7KROR.js → chunk-WC5QFO3T.js} +2 -2
- package/dist/chunk-WC5QFO3T.js.map +1 -0
- package/dist/index.js +15 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -6
- package/dist/index.mjs.map +1 -1
- package/dist/mmd/index.js +2 -2
- package/dist/mmd/index.mjs +1 -1
- package/dist/music/index.js +14 -6
- package/dist/music/index.mjs +1 -1
- package/package.json +41 -7
- package/dist/ConfigService-BxK06xP6.d.mts +0 -262
- package/dist/ConfigService-BxK06xP6.d.ts +0 -262
- package/dist/UniversalFileService-BuHN-jrR.d.ts +0 -515
- package/dist/UniversalFileService-CGGzYeeF.d.mts +0 -515
- package/dist/analytics/index.d.mts +0 -1084
- package/dist/analytics/index.d.ts +0 -1084
- package/dist/analytics/server/index.d.mts +0 -499
- package/dist/analytics/server/index.d.ts +0 -499
- package/dist/api/index.d.mts +0 -248
- package/dist/api/index.d.ts +0 -248
- package/dist/audioDetection/index.d.mts +0 -449
- package/dist/audioDetection/index.d.ts +0 -449
- package/dist/auth/client/index.d.mts +0 -153
- package/dist/auth/client/index.d.ts +0 -153
- package/dist/auth/components/index.d.mts +0 -227
- package/dist/auth/components/index.d.ts +0 -227
- package/dist/auth/hooks/index.d.mts +0 -31
- package/dist/auth/hooks/index.d.ts +0 -31
- package/dist/auth/index.d.mts +0 -40
- package/dist/auth/index.d.ts +0 -40
- package/dist/auth/middleware/index.d.mts +0 -75
- package/dist/auth/middleware/index.d.ts +0 -75
- package/dist/auth/routes/index.d.mts +0 -261
- package/dist/auth/routes/index.d.ts +0 -261
- package/dist/auth/schema/index.d.mts +0 -789
- package/dist/auth/schema/index.d.ts +0 -789
- package/dist/auth/services/index.d.mts +0 -48
- package/dist/auth/services/index.d.ts +0 -48
- package/dist/calendar/index.d.mts +0 -1197
- package/dist/calendar/index.d.ts +0 -1197
- package/dist/calendar/routes/index.d.mts +0 -118
- package/dist/calendar/routes/index.d.ts +0 -118
- package/dist/calendar/server.d.mts +0 -1184
- package/dist/calendar/server.d.ts +0 -1184
- package/dist/chunk-6WXOA4BE.mjs.map +0 -1
- package/dist/chunk-AXP7KROR.js.map +0 -1
- package/dist/chunk-GAC4J5GX.js +0 -228
- package/dist/chunk-GAC4J5GX.js.map +0 -1
- package/dist/chunk-IEA55H3G.js +0 -106
- package/dist/chunk-IEA55H3G.js.map +0 -1
- package/dist/chunk-R2F4BXUU.mjs +0 -100
- package/dist/chunk-R2F4BXUU.mjs.map +0 -1
- package/dist/chunk-T6TE7GTY.mjs +0 -218
- package/dist/chunk-T6TE7GTY.mjs.map +0 -1
- package/dist/config/index.d.mts +0 -64
- package/dist/config/index.d.ts +0 -64
- package/dist/config/server/index.d.mts +0 -1533
- package/dist/config/server/index.d.ts +0 -1533
- package/dist/drizzle-auth-service-Bxlovhv8.d.ts +0 -145
- package/dist/drizzle-auth-service-DZY2F1sv.d.mts +0 -145
- package/dist/drizzle-schema-BNhqj2AZ.d.mts +0 -1114
- package/dist/drizzle-schema-BNhqj2AZ.d.ts +0 -1114
- package/dist/enums-Dume-V5Y.d.mts +0 -16
- package/dist/enums-Dume-V5Y.d.ts +0 -16
- package/dist/i18n/index.d.mts +0 -417
- package/dist/i18n/index.d.ts +0 -417
- package/dist/imageCrop/index.d.mts +0 -165
- package/dist/imageCrop/index.d.ts +0 -165
- package/dist/index-DSel44Ke.d.mts +0 -93
- package/dist/index-DSel44Ke.d.ts +0 -93
- package/dist/index.d.mts +0 -671
- package/dist/index.d.ts +0 -671
- package/dist/logger/index.d.mts +0 -125
- package/dist/logger/index.d.ts +0 -125
- package/dist/mmd/admin/index.d.mts +0 -487
- package/dist/mmd/admin/index.d.ts +0 -487
- package/dist/mmd/index.d.mts +0 -599
- package/dist/mmd/index.d.ts +0 -599
- package/dist/mmd/server/index.d.mts +0 -138
- package/dist/mmd/server/index.d.ts +0 -138
- package/dist/music/index.d.mts +0 -79
- package/dist/music/index.d.ts +0 -79
- package/dist/music/server/index.d.mts +0 -1
- package/dist/music/server/index.d.ts +0 -1
- package/dist/request/index.d.mts +0 -51
- package/dist/request/index.d.ts +0 -51
- package/dist/storage/index.d.mts +0 -75
- package/dist/storage/index.d.ts +0 -75
- package/dist/testYourself/admin/index.d.mts +0 -58
- package/dist/testYourself/admin/index.d.ts +0 -58
- package/dist/testYourself/index.d.mts +0 -53
- package/dist/testYourself/index.d.ts +0 -53
- package/dist/testYourself/server/index.d.mts +0 -1029
- package/dist/testYourself/server/index.d.ts +0 -1029
- package/dist/types-B60F7EZZ.d.mts +0 -248
- package/dist/types-B60F7EZZ.d.ts +0 -248
- package/dist/types-BINlP9MK.d.mts +0 -286
- package/dist/types-BINlP9MK.d.ts +0 -286
- package/dist/types-BaZccpvk.d.mts +0 -48
- package/dist/types-BaZccpvk.d.ts +0 -48
- package/dist/types-CK4We_aI.d.mts +0 -270
- package/dist/types-CK4We_aI.d.ts +0 -270
- package/dist/types-CbTsi9CZ.d.mts +0 -31
- package/dist/types-CbTsi9CZ.d.ts +0 -31
- package/dist/types-CroexXnI.d.ts +0 -99
- package/dist/types-DmsXCWvm.d.mts +0 -99
- package/dist/types-Dt0oqeFM.d.mts +0 -70
- package/dist/types-zK6kDzDQ.d.ts +0 -70
- package/dist/universalExport/index.d.mts +0 -235
- package/dist/universalExport/index.d.ts +0 -235
- package/dist/universalExport/server/index.d.mts +0 -1270
- package/dist/universalExport/server/index.d.ts +0 -1270
- package/dist/universalFile/index.d.mts +0 -480
- package/dist/universalFile/index.d.ts +0 -480
- package/dist/universalFile/server/index.d.mts +0 -4516
- package/dist/universalFile/server/index.d.ts +0 -4516
- package/dist/useElectronStorage-Dj0rcorG.d.mts +0 -65
- package/dist/useElectronStorage-DwnNfIhl.d.ts +0 -65
- package/dist/utils/index.d.mts +0 -192
- package/dist/utils/index.d.ts +0 -192
|
@@ -0,0 +1,647 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk2ODO4HEI_js = require('./chunk-2ODO4HEI.js');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var useSWR = require('swr');
|
|
6
|
+
|
|
7
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
10
|
+
var useSWR__default = /*#__PURE__*/_interopDefault(useSWR);
|
|
11
|
+
|
|
12
|
+
function MusicPlayer({
|
|
13
|
+
track,
|
|
14
|
+
onPlay,
|
|
15
|
+
onPause,
|
|
16
|
+
onStop,
|
|
17
|
+
onVolumeChange,
|
|
18
|
+
onSeek,
|
|
19
|
+
initialVolume = 0.7,
|
|
20
|
+
className = "",
|
|
21
|
+
compact = false,
|
|
22
|
+
ultraCompact = false,
|
|
23
|
+
hideVolumeControl = false,
|
|
24
|
+
showTrackInfo = true,
|
|
25
|
+
isPlaying,
|
|
26
|
+
currentTime,
|
|
27
|
+
duration,
|
|
28
|
+
externalVolume
|
|
29
|
+
}) {
|
|
30
|
+
const [volume, setVolume] = React.useState(externalVolume ?? initialVolume);
|
|
31
|
+
const [isLoading, setIsLoading] = React.useState(false);
|
|
32
|
+
const [error, setError] = React.useState();
|
|
33
|
+
const progressRef = React.useRef(null);
|
|
34
|
+
const volumeRef = React.useRef(null);
|
|
35
|
+
const [isDraggingProgress, setIsDraggingProgress] = React.useState(false);
|
|
36
|
+
const [isDraggingVolume, setIsDraggingVolume] = React.useState(false);
|
|
37
|
+
React.useEffect(() => {
|
|
38
|
+
if (externalVolume !== void 0) {
|
|
39
|
+
setVolume(externalVolume);
|
|
40
|
+
}
|
|
41
|
+
}, [externalVolume]);
|
|
42
|
+
const formatTime = (seconds) => {
|
|
43
|
+
if (!seconds || isNaN(seconds)) return "0:00";
|
|
44
|
+
const mins = Math.floor(seconds / 60);
|
|
45
|
+
const secs = Math.floor(seconds % 60);
|
|
46
|
+
return `${mins}:${secs.toString().padStart(2, "0")}`;
|
|
47
|
+
};
|
|
48
|
+
const handlePlay = React.useCallback(() => {
|
|
49
|
+
onPlay?.();
|
|
50
|
+
}, [onPlay]);
|
|
51
|
+
const handlePause = React.useCallback(() => {
|
|
52
|
+
onPause?.();
|
|
53
|
+
}, [onPause]);
|
|
54
|
+
const handleStop = React.useCallback(() => {
|
|
55
|
+
onStop?.();
|
|
56
|
+
}, [onStop]);
|
|
57
|
+
const handleVolumeChange = React.useCallback((newVolume) => {
|
|
58
|
+
const clampedVolume = Math.max(0, Math.min(1, newVolume));
|
|
59
|
+
setVolume(clampedVolume);
|
|
60
|
+
onVolumeChange?.(clampedVolume);
|
|
61
|
+
}, [onVolumeChange]);
|
|
62
|
+
const handleSeek = React.useCallback((time) => {
|
|
63
|
+
if (!duration || isNaN(duration)) return;
|
|
64
|
+
const seekTime = Math.max(0, Math.min(duration, time));
|
|
65
|
+
onSeek?.(seekTime);
|
|
66
|
+
}, [duration, onSeek]);
|
|
67
|
+
const handleProgressMouseDown = React.useCallback((e) => {
|
|
68
|
+
if (!progressRef.current || !duration) return;
|
|
69
|
+
setIsDraggingProgress(true);
|
|
70
|
+
const rect = progressRef.current.getBoundingClientRect();
|
|
71
|
+
const percent = (e.clientX - rect.left) / rect.width;
|
|
72
|
+
const time = percent * duration;
|
|
73
|
+
handleSeek(time);
|
|
74
|
+
}, [duration, handleSeek]);
|
|
75
|
+
const handleVolumeMouseDown = React.useCallback((e) => {
|
|
76
|
+
if (!volumeRef.current) return;
|
|
77
|
+
setIsDraggingVolume(true);
|
|
78
|
+
const rect = volumeRef.current.getBoundingClientRect();
|
|
79
|
+
const percent = (e.clientX - rect.left) / rect.width;
|
|
80
|
+
handleVolumeChange(percent);
|
|
81
|
+
}, [handleVolumeChange]);
|
|
82
|
+
React.useEffect(() => {
|
|
83
|
+
const handleMouseMove = (e) => {
|
|
84
|
+
if (isDraggingProgress && progressRef.current && duration) {
|
|
85
|
+
const rect = progressRef.current.getBoundingClientRect();
|
|
86
|
+
const percent = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
|
|
87
|
+
const time = percent * duration;
|
|
88
|
+
handleSeek(time);
|
|
89
|
+
}
|
|
90
|
+
if (isDraggingVolume && volumeRef.current) {
|
|
91
|
+
const rect = volumeRef.current.getBoundingClientRect();
|
|
92
|
+
const percent = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
|
|
93
|
+
handleVolumeChange(percent);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const handleMouseUp = () => {
|
|
97
|
+
setIsDraggingProgress(false);
|
|
98
|
+
setIsDraggingVolume(false);
|
|
99
|
+
};
|
|
100
|
+
if (isDraggingProgress || isDraggingVolume) {
|
|
101
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
102
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
103
|
+
}
|
|
104
|
+
return () => {
|
|
105
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
106
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
107
|
+
};
|
|
108
|
+
}, [isDraggingProgress, isDraggingVolume, duration, handleSeek, handleVolumeChange]);
|
|
109
|
+
const stopPropagation = React.useCallback((e) => {
|
|
110
|
+
e.preventDefault();
|
|
111
|
+
e.stopPropagation();
|
|
112
|
+
}, []);
|
|
113
|
+
if (ultraCompact) {
|
|
114
|
+
return /* @__PURE__ */ React__default.default.createElement(
|
|
115
|
+
"div",
|
|
116
|
+
{
|
|
117
|
+
className: `flex items-center gap-2 bg-white/90 backdrop-blur-sm rounded-xl p-2 shadow-lg border border-purple-200 ${className}`,
|
|
118
|
+
style: { width: hideVolumeControl ? "120px" : "192px" },
|
|
119
|
+
onClick: stopPropagation,
|
|
120
|
+
onMouseDown: stopPropagation,
|
|
121
|
+
onMouseUp: stopPropagation,
|
|
122
|
+
onTouchStart: stopPropagation,
|
|
123
|
+
onTouchEnd: stopPropagation,
|
|
124
|
+
onPointerDown: stopPropagation,
|
|
125
|
+
onPointerUp: stopPropagation
|
|
126
|
+
},
|
|
127
|
+
/* @__PURE__ */ React__default.default.createElement("div", { className: `flex items-center gap-1 ${hideVolumeControl ? "w-full justify-center" : ""}` }, /* @__PURE__ */ React__default.default.createElement(
|
|
128
|
+
"button",
|
|
129
|
+
{
|
|
130
|
+
onClick: (e) => {
|
|
131
|
+
stopPropagation(e);
|
|
132
|
+
handleStop();
|
|
133
|
+
},
|
|
134
|
+
onMouseDown: stopPropagation,
|
|
135
|
+
onMouseUp: stopPropagation,
|
|
136
|
+
onTouchStart: stopPropagation,
|
|
137
|
+
onTouchEnd: stopPropagation,
|
|
138
|
+
onPointerDown: stopPropagation,
|
|
139
|
+
onPointerUp: stopPropagation,
|
|
140
|
+
className: "w-7 h-7 rounded-lg bg-gray-100 hover:bg-gray-200 border border-gray-300 flex items-center justify-center transition-colors",
|
|
141
|
+
title: "\u505C\u6B62"
|
|
142
|
+
},
|
|
143
|
+
/* @__PURE__ */ React__default.default.createElement("div", { className: "w-2.5 h-2.5 bg-gray-600 rounded-sm" })
|
|
144
|
+
), /* @__PURE__ */ React__default.default.createElement(
|
|
145
|
+
"button",
|
|
146
|
+
{
|
|
147
|
+
onClick: (e) => {
|
|
148
|
+
stopPropagation(e);
|
|
149
|
+
isPlaying ? handlePause() : handlePlay();
|
|
150
|
+
},
|
|
151
|
+
onMouseDown: stopPropagation,
|
|
152
|
+
onMouseUp: stopPropagation,
|
|
153
|
+
onTouchStart: stopPropagation,
|
|
154
|
+
onTouchEnd: stopPropagation,
|
|
155
|
+
onPointerDown: stopPropagation,
|
|
156
|
+
onPointerUp: stopPropagation,
|
|
157
|
+
className: `w-8 h-8 rounded-lg border flex items-center justify-center transition-colors ${isPlaying ? "bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600 text-white border-purple-400" : "bg-gradient-to-r from-green-500 to-blue-500 hover:from-green-600 hover:to-blue-600 text-white border-green-400 cursor-pointer"}`,
|
|
158
|
+
title: isPlaying ? "\u6682\u505C" : "\u64AD\u653E"
|
|
159
|
+
},
|
|
160
|
+
isPlaying ? /* @__PURE__ */ React__default.default.createElement("div", { className: "flex gap-0.5" }, /* @__PURE__ */ React__default.default.createElement("div", { className: "w-1 h-3 bg-white rounded-sm" }), /* @__PURE__ */ React__default.default.createElement("div", { className: "w-1 h-3 bg-white rounded-sm" })) : /* @__PURE__ */ React__default.default.createElement("div", { className: "w-0 h-0 border-l-[6px] border-l-white border-t-[4px] border-t-transparent border-b-[4px] border-b-transparent ml-0.5" })
|
|
161
|
+
)),
|
|
162
|
+
!hideVolumeControl && /* @__PURE__ */ React__default.default.createElement("div", { className: "flex items-center gap-1 flex-1" }, /* @__PURE__ */ React__default.default.createElement("div", { className: "text-gray-500 text-xs" }, "\u{1F50A}"), /* @__PURE__ */ React__default.default.createElement(
|
|
163
|
+
"div",
|
|
164
|
+
{
|
|
165
|
+
ref: volumeRef,
|
|
166
|
+
className: "flex-1 h-2 bg-gray-200 rounded-full cursor-pointer relative",
|
|
167
|
+
onMouseDown: handleVolumeMouseDown,
|
|
168
|
+
onClick: stopPropagation,
|
|
169
|
+
onTouchStart: stopPropagation,
|
|
170
|
+
onTouchEnd: stopPropagation,
|
|
171
|
+
onPointerDown: stopPropagation,
|
|
172
|
+
onPointerUp: stopPropagation
|
|
173
|
+
},
|
|
174
|
+
/* @__PURE__ */ React__default.default.createElement(
|
|
175
|
+
"div",
|
|
176
|
+
{
|
|
177
|
+
className: "h-full bg-gradient-to-r from-purple-400 to-pink-400 rounded-full",
|
|
178
|
+
style: { width: `${volume * 100}%` }
|
|
179
|
+
}
|
|
180
|
+
),
|
|
181
|
+
/* @__PURE__ */ React__default.default.createElement(
|
|
182
|
+
"div",
|
|
183
|
+
{
|
|
184
|
+
className: "absolute top-1/2 w-3 h-3 bg-white border-2 border-purple-400 rounded-full transform -translate-y-1/2 cursor-grab",
|
|
185
|
+
style: { left: `${volume * 100}%`, transform: "translateX(-50%) translateY(-50%)" }
|
|
186
|
+
}
|
|
187
|
+
)
|
|
188
|
+
))
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
return /* @__PURE__ */ React__default.default.createElement(
|
|
192
|
+
"div",
|
|
193
|
+
{
|
|
194
|
+
className: `bg-white/90 backdrop-blur-sm rounded-xl p-4 shadow-lg border border-purple-200 ${className}`,
|
|
195
|
+
style: { width: compact ? "280px" : "320px" },
|
|
196
|
+
onClick: stopPropagation,
|
|
197
|
+
onMouseDown: stopPropagation,
|
|
198
|
+
onMouseUp: stopPropagation,
|
|
199
|
+
onTouchStart: stopPropagation,
|
|
200
|
+
onTouchEnd: stopPropagation,
|
|
201
|
+
onPointerDown: stopPropagation,
|
|
202
|
+
onPointerUp: stopPropagation
|
|
203
|
+
},
|
|
204
|
+
!compact && showTrackInfo && track && /* @__PURE__ */ React__default.default.createElement("div", { className: "mb-3" }, /* @__PURE__ */ React__default.default.createElement("h3", { className: "text-sm font-medium text-gray-800 truncate" }, track.name), /* @__PURE__ */ React__default.default.createElement("p", { className: "text-xs text-gray-500" }, "\u80CC\u666F\u97F3\u4E50")),
|
|
205
|
+
!compact && /* @__PURE__ */ React__default.default.createElement("div", { className: "mb-3" }, /* @__PURE__ */ React__default.default.createElement(
|
|
206
|
+
"div",
|
|
207
|
+
{
|
|
208
|
+
ref: progressRef,
|
|
209
|
+
className: "w-full h-2 bg-gray-200 rounded-full cursor-pointer relative",
|
|
210
|
+
onMouseDown: handleProgressMouseDown,
|
|
211
|
+
onClick: stopPropagation,
|
|
212
|
+
onTouchStart: stopPropagation,
|
|
213
|
+
onTouchEnd: stopPropagation,
|
|
214
|
+
onPointerDown: stopPropagation,
|
|
215
|
+
onPointerUp: stopPropagation
|
|
216
|
+
},
|
|
217
|
+
/* @__PURE__ */ React__default.default.createElement(
|
|
218
|
+
"div",
|
|
219
|
+
{
|
|
220
|
+
className: "h-full bg-gradient-to-r from-purple-400 to-pink-400 rounded-full transition-all duration-100",
|
|
221
|
+
style: { width: duration > 0 ? `${currentTime / duration * 100}%` : "0%" }
|
|
222
|
+
}
|
|
223
|
+
),
|
|
224
|
+
/* @__PURE__ */ React__default.default.createElement(
|
|
225
|
+
"div",
|
|
226
|
+
{
|
|
227
|
+
className: "absolute top-1/2 w-4 h-4 bg-white border-2 border-purple-400 rounded-full transform -translate-y-1/2 cursor-grab",
|
|
228
|
+
style: {
|
|
229
|
+
left: duration > 0 ? `${currentTime / duration * 100}%` : "0%",
|
|
230
|
+
transform: "translateX(-50%) translateY(-50%)"
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
)
|
|
234
|
+
), /* @__PURE__ */ React__default.default.createElement("div", { className: "flex justify-between text-xs text-gray-500 mt-1" }, /* @__PURE__ */ React__default.default.createElement("span", null, formatTime(currentTime)), /* @__PURE__ */ React__default.default.createElement("span", null, formatTime(duration)))),
|
|
235
|
+
/* @__PURE__ */ React__default.default.createElement("div", { className: "flex items-center justify-center gap-3 mb-3" }, /* @__PURE__ */ React__default.default.createElement(
|
|
236
|
+
"button",
|
|
237
|
+
{
|
|
238
|
+
onClick: (e) => {
|
|
239
|
+
stopPropagation(e);
|
|
240
|
+
handleStop();
|
|
241
|
+
},
|
|
242
|
+
onMouseDown: stopPropagation,
|
|
243
|
+
onMouseUp: stopPropagation,
|
|
244
|
+
onTouchStart: stopPropagation,
|
|
245
|
+
onTouchEnd: stopPropagation,
|
|
246
|
+
onPointerDown: stopPropagation,
|
|
247
|
+
onPointerUp: stopPropagation,
|
|
248
|
+
className: "w-10 h-10 rounded-full bg-gray-100 hover:bg-gray-200 border border-gray-300 flex items-center justify-center transition-colors",
|
|
249
|
+
title: "\u505C\u6B62"
|
|
250
|
+
},
|
|
251
|
+
/* @__PURE__ */ React__default.default.createElement("div", { className: "w-4 h-4 bg-gray-600 rounded-sm" })
|
|
252
|
+
), /* @__PURE__ */ React__default.default.createElement(
|
|
253
|
+
"button",
|
|
254
|
+
{
|
|
255
|
+
onClick: (e) => {
|
|
256
|
+
stopPropagation(e);
|
|
257
|
+
isPlaying ? handlePause() : handlePlay();
|
|
258
|
+
},
|
|
259
|
+
onMouseDown: stopPropagation,
|
|
260
|
+
onMouseUp: stopPropagation,
|
|
261
|
+
onTouchStart: stopPropagation,
|
|
262
|
+
onTouchEnd: stopPropagation,
|
|
263
|
+
onPointerDown: stopPropagation,
|
|
264
|
+
onPointerUp: stopPropagation,
|
|
265
|
+
className: `w-12 h-12 rounded-full border-2 flex items-center justify-center transition-colors ${isPlaying ? "bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600 text-white border-purple-400" : "bg-gradient-to-r from-green-500 to-blue-500 hover:from-green-600 hover:to-blue-600 text-white border-green-400 cursor-pointer"}`,
|
|
266
|
+
title: isPlaying ? "\u6682\u505C" : "\u64AD\u653E"
|
|
267
|
+
},
|
|
268
|
+
isLoading ? /* @__PURE__ */ React__default.default.createElement("div", { className: "w-5 h-5 border-2 border-white border-t-transparent rounded-full animate-spin" }) : isPlaying ? /* @__PURE__ */ React__default.default.createElement("div", { className: "flex gap-1" }, /* @__PURE__ */ React__default.default.createElement("div", { className: "w-1.5 h-4 bg-white rounded-sm" }), /* @__PURE__ */ React__default.default.createElement("div", { className: "w-1.5 h-4 bg-white rounded-sm" })) : /* @__PURE__ */ React__default.default.createElement("div", { className: "w-0 h-0 border-l-[10px] border-l-white border-t-[7px] border-t-transparent border-b-[7px] border-b-transparent ml-1" })
|
|
269
|
+
)),
|
|
270
|
+
!hideVolumeControl && /* @__PURE__ */ React__default.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React__default.default.createElement("div", { className: "text-gray-500 text-sm" }, "\u{1F50A}"), /* @__PURE__ */ React__default.default.createElement(
|
|
271
|
+
"div",
|
|
272
|
+
{
|
|
273
|
+
ref: volumeRef,
|
|
274
|
+
className: "flex-1 h-2 bg-gray-200 rounded-full cursor-pointer relative",
|
|
275
|
+
onMouseDown: handleVolumeMouseDown,
|
|
276
|
+
onClick: stopPropagation,
|
|
277
|
+
onTouchStart: stopPropagation,
|
|
278
|
+
onTouchEnd: stopPropagation,
|
|
279
|
+
onPointerDown: stopPropagation,
|
|
280
|
+
onPointerUp: stopPropagation
|
|
281
|
+
},
|
|
282
|
+
/* @__PURE__ */ React__default.default.createElement(
|
|
283
|
+
"div",
|
|
284
|
+
{
|
|
285
|
+
className: "h-full bg-gradient-to-r from-purple-400 to-pink-400 rounded-full",
|
|
286
|
+
style: { width: `${volume * 100}%` }
|
|
287
|
+
}
|
|
288
|
+
),
|
|
289
|
+
/* @__PURE__ */ React__default.default.createElement(
|
|
290
|
+
"div",
|
|
291
|
+
{
|
|
292
|
+
className: "absolute top-1/2 w-4 h-4 bg-white border-2 border-purple-400 rounded-full transform -translate-y-1/2 cursor-grab",
|
|
293
|
+
style: { left: `${volume * 100}%`, transform: "translateX(-50%) translateY(-50%)" }
|
|
294
|
+
}
|
|
295
|
+
)
|
|
296
|
+
), /* @__PURE__ */ React__default.default.createElement("div", { className: "text-xs text-gray-500 w-8 text-right" }, Math.round(volume * 100), "%")),
|
|
297
|
+
error && /* @__PURE__ */ React__default.default.createElement("div", { className: "mt-2 text-xs text-red-500" }, error)
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
function MikutapMusicPlayer({
|
|
301
|
+
track,
|
|
302
|
+
onPlay,
|
|
303
|
+
onPause,
|
|
304
|
+
onSeek,
|
|
305
|
+
className = "",
|
|
306
|
+
isPlaying,
|
|
307
|
+
currentTime,
|
|
308
|
+
duration
|
|
309
|
+
}) {
|
|
310
|
+
const progressRef = React.useRef(null);
|
|
311
|
+
const [isDraggingProgress, setIsDraggingProgress] = React.useState(false);
|
|
312
|
+
const formatTime = (seconds) => {
|
|
313
|
+
if (!seconds || isNaN(seconds)) return "0:00";
|
|
314
|
+
const mins = Math.floor(seconds / 60);
|
|
315
|
+
const secs = Math.floor(seconds % 60);
|
|
316
|
+
return `${mins}:${secs.toString().padStart(2, "0")}`;
|
|
317
|
+
};
|
|
318
|
+
const handlePlay = React.useCallback(() => {
|
|
319
|
+
onPlay?.();
|
|
320
|
+
}, [onPlay]);
|
|
321
|
+
const handlePause = React.useCallback(() => {
|
|
322
|
+
onPause?.();
|
|
323
|
+
}, [onPause]);
|
|
324
|
+
const handleSeek = React.useCallback((time) => {
|
|
325
|
+
if (!duration || isNaN(duration)) return;
|
|
326
|
+
const seekTime = Math.max(0, Math.min(duration, time));
|
|
327
|
+
onSeek?.(seekTime);
|
|
328
|
+
}, [duration, onSeek]);
|
|
329
|
+
const handleProgressMouseDown = React.useCallback((e) => {
|
|
330
|
+
if (!progressRef.current || !duration) return;
|
|
331
|
+
setIsDraggingProgress(true);
|
|
332
|
+
const rect = progressRef.current.getBoundingClientRect();
|
|
333
|
+
const percent = (e.clientX - rect.left) / rect.width;
|
|
334
|
+
const time = percent * duration;
|
|
335
|
+
handleSeek(time);
|
|
336
|
+
}, [duration, handleSeek]);
|
|
337
|
+
React.useEffect(() => {
|
|
338
|
+
const handleMouseMove = (e) => {
|
|
339
|
+
if (isDraggingProgress && progressRef.current && duration) {
|
|
340
|
+
const rect = progressRef.current.getBoundingClientRect();
|
|
341
|
+
const percent = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
|
|
342
|
+
const time = percent * duration;
|
|
343
|
+
handleSeek(time);
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
const handleMouseUp = () => {
|
|
347
|
+
setIsDraggingProgress(false);
|
|
348
|
+
};
|
|
349
|
+
if (isDraggingProgress) {
|
|
350
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
351
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
352
|
+
}
|
|
353
|
+
return () => {
|
|
354
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
355
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
356
|
+
};
|
|
357
|
+
}, [isDraggingProgress, duration, handleSeek]);
|
|
358
|
+
const stopPropagation = React.useCallback((e) => {
|
|
359
|
+
e.preventDefault();
|
|
360
|
+
e.stopPropagation();
|
|
361
|
+
}, []);
|
|
362
|
+
return /* @__PURE__ */ React__default.default.createElement(
|
|
363
|
+
"div",
|
|
364
|
+
{
|
|
365
|
+
className: `bg-gradient-to-r from-purple-900/95 to-pink-900/95 backdrop-blur-sm rounded-2xl p-4 shadow-2xl border border-purple-300/30 ${className}`,
|
|
366
|
+
style: { width: "200px" },
|
|
367
|
+
onClick: stopPropagation,
|
|
368
|
+
onMouseDown: stopPropagation,
|
|
369
|
+
onMouseUp: stopPropagation,
|
|
370
|
+
onTouchStart: stopPropagation,
|
|
371
|
+
onTouchEnd: stopPropagation,
|
|
372
|
+
onPointerDown: stopPropagation,
|
|
373
|
+
onPointerUp: stopPropagation
|
|
374
|
+
},
|
|
375
|
+
track && /* @__PURE__ */ React__default.default.createElement("div", { className: "mb-3 text-center" }, /* @__PURE__ */ React__default.default.createElement("div", { className: "text-white text-sm font-medium truncate mb-1" }, track.name), /* @__PURE__ */ React__default.default.createElement("div", { className: "text-purple-200 text-xs" }, "\u80CC\u666F\u97F3\u4E50")),
|
|
376
|
+
/* @__PURE__ */ React__default.default.createElement("div", { className: "flex justify-center mb-3" }, /* @__PURE__ */ React__default.default.createElement(
|
|
377
|
+
"button",
|
|
378
|
+
{
|
|
379
|
+
onClick: (e) => {
|
|
380
|
+
stopPropagation(e);
|
|
381
|
+
isPlaying ? handlePause() : handlePlay();
|
|
382
|
+
},
|
|
383
|
+
onMouseDown: stopPropagation,
|
|
384
|
+
onMouseUp: stopPropagation,
|
|
385
|
+
onTouchStart: stopPropagation,
|
|
386
|
+
onTouchEnd: stopPropagation,
|
|
387
|
+
onPointerDown: stopPropagation,
|
|
388
|
+
onPointerUp: stopPropagation,
|
|
389
|
+
className: `w-12 h-12 rounded-full border-2 flex items-center justify-center transition-all duration-300 shadow-lg hover:scale-105 ${isPlaying ? "bg-gradient-to-r from-orange-400 to-red-500 hover:from-orange-500 hover:to-red-600 text-white border-orange-300 shadow-orange-500/50" : "bg-gradient-to-r from-green-400 to-emerald-500 hover:from-green-500 hover:to-emerald-600 text-white border-green-300 shadow-green-500/50"}`,
|
|
390
|
+
title: isPlaying ? "\u6682\u505C" : "\u64AD\u653E"
|
|
391
|
+
},
|
|
392
|
+
isPlaying ? /* @__PURE__ */ React__default.default.createElement("div", { className: "flex gap-1" }, /* @__PURE__ */ React__default.default.createElement("div", { className: "w-1.5 h-4 bg-white rounded-sm" }), /* @__PURE__ */ React__default.default.createElement("div", { className: "w-1.5 h-4 bg-white rounded-sm" })) : /* @__PURE__ */ React__default.default.createElement("div", { className: "w-0 h-0 border-l-[10px] border-l-white border-t-[7px] border-t-transparent border-b-[7px] border-b-transparent ml-1" })
|
|
393
|
+
)),
|
|
394
|
+
/* @__PURE__ */ React__default.default.createElement("div", { className: "mb-2" }, /* @__PURE__ */ React__default.default.createElement(
|
|
395
|
+
"div",
|
|
396
|
+
{
|
|
397
|
+
ref: progressRef,
|
|
398
|
+
className: "w-full h-2 bg-white/20 rounded-full cursor-pointer relative overflow-hidden",
|
|
399
|
+
onMouseDown: handleProgressMouseDown,
|
|
400
|
+
onClick: stopPropagation,
|
|
401
|
+
onTouchStart: stopPropagation,
|
|
402
|
+
onTouchEnd: stopPropagation,
|
|
403
|
+
onPointerDown: stopPropagation,
|
|
404
|
+
onPointerUp: stopPropagation
|
|
405
|
+
},
|
|
406
|
+
/* @__PURE__ */ React__default.default.createElement(
|
|
407
|
+
"div",
|
|
408
|
+
{
|
|
409
|
+
className: "h-full bg-gradient-to-r from-cyan-400 to-blue-500 rounded-full transition-all duration-100 shadow-sm",
|
|
410
|
+
style: { width: duration > 0 ? `${currentTime / duration * 100}%` : "0%" }
|
|
411
|
+
}
|
|
412
|
+
),
|
|
413
|
+
/* @__PURE__ */ React__default.default.createElement(
|
|
414
|
+
"div",
|
|
415
|
+
{
|
|
416
|
+
className: "absolute top-1/2 w-3 h-3 bg-white border-2 border-cyan-400 rounded-full transform -translate-y-1/2 cursor-grab shadow-lg",
|
|
417
|
+
style: {
|
|
418
|
+
left: duration > 0 ? `${currentTime / duration * 100}%` : "0%",
|
|
419
|
+
transform: "translateX(-50%) translateY(-50%)"
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
)
|
|
423
|
+
), /* @__PURE__ */ React__default.default.createElement("div", { className: "flex justify-between text-xs text-purple-200 mt-1" }, /* @__PURE__ */ React__default.default.createElement("span", null, formatTime(currentTime)), /* @__PURE__ */ React__default.default.createElement("span", null, formatTime(duration)))),
|
|
424
|
+
/* @__PURE__ */ React__default.default.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ React__default.default.createElement("div", { className: `flex items-center gap-2 text-xs px-3 py-1 rounded-full transition-all duration-300 ${isPlaying ? "bg-orange-500/20 text-orange-200 border border-orange-400/30" : "bg-gray-500/20 text-gray-300 border border-gray-400/30"}` }, /* @__PURE__ */ React__default.default.createElement("div", { className: `w-2 h-2 rounded-full transition-all duration-300 ${isPlaying ? "bg-orange-400 animate-pulse" : "bg-gray-400"}` }), /* @__PURE__ */ React__default.default.createElement("span", null, isPlaying ? "\u64AD\u653E\u4E2D" : "\u5DF2\u6682\u505C")))
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// src/music/adapters/kugou.ts
|
|
429
|
+
var kugouAdapter = {
|
|
430
|
+
parseSearchResult(data) {
|
|
431
|
+
const root = typeof data === "string" ? JSON.parse(data) : data;
|
|
432
|
+
const info = root.data?.data?.info || root.data?.info || root.info || [];
|
|
433
|
+
const total = root.data?.data?.total || root.data?.total || info.length;
|
|
434
|
+
return {
|
|
435
|
+
tracks: info.map((item) => {
|
|
436
|
+
let pic = item.pic || "";
|
|
437
|
+
if (item.trans_param?.union_cover) {
|
|
438
|
+
pic = item.trans_param.union_cover.replace("{size}", "400");
|
|
439
|
+
}
|
|
440
|
+
return {
|
|
441
|
+
id: item.hash || item.id,
|
|
442
|
+
name: item.songname || item.filename || "Unknown",
|
|
443
|
+
artist: item.singername || "Unknown Artist",
|
|
444
|
+
album: item.album_name || item.album || "",
|
|
445
|
+
pic,
|
|
446
|
+
url: item.url,
|
|
447
|
+
lrc: item.lrc,
|
|
448
|
+
source: "kugou",
|
|
449
|
+
isVip: item.privilege >= 8,
|
|
450
|
+
playable: item.status !== 0
|
|
451
|
+
};
|
|
452
|
+
}),
|
|
453
|
+
total
|
|
454
|
+
};
|
|
455
|
+
},
|
|
456
|
+
parseGetSongUrl(data) {
|
|
457
|
+
return data.url?.url || data.url?.backup_url?.[0] || null;
|
|
458
|
+
},
|
|
459
|
+
parseGetLyric(data) {
|
|
460
|
+
const root = typeof data === "string" ? JSON.parse(data) : data;
|
|
461
|
+
return root.lyric || root.lrc || root.data?.lyric || root.data || "";
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
// src/music/adapters/netease.ts
|
|
466
|
+
var neteaseAdapter = {
|
|
467
|
+
parseSearchResult(data) {
|
|
468
|
+
const root = typeof data === "string" ? JSON.parse(data) : data;
|
|
469
|
+
const songs = root.result?.songs || root.songs || (Array.isArray(root) ? root : []);
|
|
470
|
+
return {
|
|
471
|
+
tracks: songs.map((item) => ({
|
|
472
|
+
id: item.id,
|
|
473
|
+
name: item.name,
|
|
474
|
+
artist: Array.isArray(item.artist) ? item.artist.join(", ") : item.artist,
|
|
475
|
+
album: item.album?.name || item.album,
|
|
476
|
+
pic: item.pic || item.album?.picUrl,
|
|
477
|
+
url: item.url,
|
|
478
|
+
lrc: item.lrc,
|
|
479
|
+
source: "netease",
|
|
480
|
+
isVip: item.fee === 1 || item.fee === 4,
|
|
481
|
+
playable: item.noCopyrightRcmd === null
|
|
482
|
+
})),
|
|
483
|
+
total: root.result?.songCount || songs.length
|
|
484
|
+
};
|
|
485
|
+
},
|
|
486
|
+
parseGetSongUrl(data) {
|
|
487
|
+
const root = typeof data === "string" ? JSON.parse(data) : data;
|
|
488
|
+
const item = root.data?.[0] || root[0] || root;
|
|
489
|
+
return item.url || null;
|
|
490
|
+
},
|
|
491
|
+
parseGetLyric(data) {
|
|
492
|
+
const root = typeof data === "string" ? JSON.parse(data) : data;
|
|
493
|
+
return root.lyric || root.lrc || root.data?.lyric || "";
|
|
494
|
+
}
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
// src/music/adapters/tencent.ts
|
|
498
|
+
var tencentAdapter = {
|
|
499
|
+
parseSearchResult(data) {
|
|
500
|
+
const root = typeof data === "string" ? JSON.parse(data) : data;
|
|
501
|
+
const songData = root.data?.data?.song || root.data?.song || root.data || root;
|
|
502
|
+
const list = songData.list || root.songs || [];
|
|
503
|
+
const total = songData.totalnum || root.total || list.length;
|
|
504
|
+
return {
|
|
505
|
+
tracks: list.map((item) => {
|
|
506
|
+
const artist = Array.isArray(item.singer) ? item.singer.map((s) => s.name).join(", ") : item.singer?.[0]?.name || item.artist || "Unknown";
|
|
507
|
+
let pic = item.pic;
|
|
508
|
+
if (!pic && item.album?.mid) {
|
|
509
|
+
pic = `https://y.gtimg.cn/music/photo_new/T002R300x300M000${item.album.mid}.jpg`;
|
|
510
|
+
}
|
|
511
|
+
return {
|
|
512
|
+
id: item.mid || item.id || item.songid,
|
|
513
|
+
name: item.name || item.title || item.songname,
|
|
514
|
+
artist,
|
|
515
|
+
album: item.album?.name || item.albumname || item.album,
|
|
516
|
+
pic: pic || "",
|
|
517
|
+
url: item.url,
|
|
518
|
+
lrc: item.lrc,
|
|
519
|
+
source: "tencent",
|
|
520
|
+
isVip: item.pay?.pay_play === 1,
|
|
521
|
+
playable: item.action?.switch !== 0
|
|
522
|
+
};
|
|
523
|
+
}),
|
|
524
|
+
total
|
|
525
|
+
};
|
|
526
|
+
},
|
|
527
|
+
parseGetSongUrl(data) {
|
|
528
|
+
const root = data;
|
|
529
|
+
const urlData = root.url.url;
|
|
530
|
+
let finalUrl = Object.values(urlData)[0];
|
|
531
|
+
console.log("finalUrl2", finalUrl);
|
|
532
|
+
return finalUrl.startsWith("http") ? finalUrl : `http://${finalUrl}`;
|
|
533
|
+
},
|
|
534
|
+
parseGetLyric(data) {
|
|
535
|
+
const root = typeof data === "string" ? JSON.parse(data) : data;
|
|
536
|
+
return root.lyric || root.lrc || root.data?.lyric || "";
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
// src/music/adapters/xiami.ts
|
|
541
|
+
var xiamiAdapter = {
|
|
542
|
+
parseSearchResult(data) {
|
|
543
|
+
const root = typeof data === "string" ? JSON.parse(data) : data;
|
|
544
|
+
const result = root.data?.result || root.result || root;
|
|
545
|
+
const songs = result.songs || (Array.isArray(root) ? root : []);
|
|
546
|
+
return {
|
|
547
|
+
tracks: songs.map((item) => ({
|
|
548
|
+
id: item.id?.toString() || "",
|
|
549
|
+
name: item.name || "Unknown",
|
|
550
|
+
artist: Array.isArray(item.ar) ? item.ar.map((a) => a.name).join(", ") : item.artist || "Unknown Artist",
|
|
551
|
+
album: item.al?.name || item.album || "",
|
|
552
|
+
pic: item.al?.picUrl || item.pic || "",
|
|
553
|
+
url: item.url,
|
|
554
|
+
lrc: item.lrc,
|
|
555
|
+
source: "xiami",
|
|
556
|
+
// 这里的逻辑参考提供的数据结构
|
|
557
|
+
isVip: item.fee === 1 || item.fee === 8,
|
|
558
|
+
playable: item.copyright !== 0
|
|
559
|
+
})),
|
|
560
|
+
total: result.songCount || songs.length
|
|
561
|
+
};
|
|
562
|
+
},
|
|
563
|
+
parseGetSongUrl(data) {
|
|
564
|
+
const root = typeof data === "string" ? JSON.parse(data) : data;
|
|
565
|
+
const item = root.data?.[0] || root.data || root[0] || root;
|
|
566
|
+
return item.url || null;
|
|
567
|
+
},
|
|
568
|
+
parseGetLyric(data) {
|
|
569
|
+
const root = typeof data === "string" ? JSON.parse(data) : data;
|
|
570
|
+
return root.lyric || root.lrc || root.data?.lyric || root.data || "";
|
|
571
|
+
}
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
// src/music/hooks/useMusic.ts
|
|
575
|
+
var fetcher = (url) => fetch(url).then((res) => res.json());
|
|
576
|
+
var ADAPTERS = {
|
|
577
|
+
kugou: kugouAdapter,
|
|
578
|
+
netease: neteaseAdapter,
|
|
579
|
+
tencent: tencentAdapter,
|
|
580
|
+
xiami: xiamiAdapter
|
|
581
|
+
};
|
|
582
|
+
function useMusic() {
|
|
583
|
+
const [searchOptions, setSearchOptions] = React.useState(null);
|
|
584
|
+
const { data: rawData, error: searchError, isLoading: isSearching } = useSWR__default.default(
|
|
585
|
+
searchOptions ? `/api/music/search?keyword=${encodeURIComponent(searchOptions.keyword)}&source=${searchOptions.source || chunk2ODO4HEI_js.DEFAULT_MUSIC_SOURCE}&limit=${searchOptions.limit || 20}&offset=${searchOptions.offset || 0}${searchOptions.miku ? "&miku=true" : ""}` : null,
|
|
586
|
+
fetcher
|
|
587
|
+
);
|
|
588
|
+
const searchResult = React.useMemo(() => {
|
|
589
|
+
if (!rawData?.data || !searchOptions) return void 0;
|
|
590
|
+
const adapter = ADAPTERS[searchOptions.source || chunk2ODO4HEI_js.DEFAULT_MUSIC_SOURCE];
|
|
591
|
+
if (adapter) {
|
|
592
|
+
return adapter.parseSearchResult(rawData.data);
|
|
593
|
+
}
|
|
594
|
+
return void 0;
|
|
595
|
+
}, [rawData, searchOptions]);
|
|
596
|
+
const search = React.useCallback((options) => {
|
|
597
|
+
setSearchOptions(options);
|
|
598
|
+
}, []);
|
|
599
|
+
const getSongUrl = React.useCallback(async (id, source = chunk2ODO4HEI_js.DEFAULT_MUSIC_SOURCE) => {
|
|
600
|
+
try {
|
|
601
|
+
const res = await fetch(`/api/music/url?id=${id}&source=${source}`);
|
|
602
|
+
const json = await res.json();
|
|
603
|
+
const adapter = ADAPTERS[source];
|
|
604
|
+
console.log("json2", json.data, source, adapter);
|
|
605
|
+
if (adapter && json.data) {
|
|
606
|
+
console.log("getSongUrl2", json.data);
|
|
607
|
+
return adapter.parseGetSongUrl(json.data) || void 0;
|
|
608
|
+
}
|
|
609
|
+
return json.data?.url;
|
|
610
|
+
} catch (err) {
|
|
611
|
+
console.error("[Music] Failed to get song URL:", err);
|
|
612
|
+
return void 0;
|
|
613
|
+
}
|
|
614
|
+
}, []);
|
|
615
|
+
const getLyric = React.useCallback(async (id, source = chunk2ODO4HEI_js.DEFAULT_MUSIC_SOURCE) => {
|
|
616
|
+
try {
|
|
617
|
+
const res = await fetch(`/api/music/lyric?id=${id}&source=${source}`);
|
|
618
|
+
const json = await res.json();
|
|
619
|
+
const adapter = ADAPTERS[source];
|
|
620
|
+
if (adapter && json.data) {
|
|
621
|
+
return adapter.parseGetLyric(json.data);
|
|
622
|
+
}
|
|
623
|
+
return json.data?.lyric;
|
|
624
|
+
} catch (err) {
|
|
625
|
+
console.error("[Music] Failed to get lyric:", err);
|
|
626
|
+
return void 0;
|
|
627
|
+
}
|
|
628
|
+
}, []);
|
|
629
|
+
return {
|
|
630
|
+
search,
|
|
631
|
+
searchResult,
|
|
632
|
+
isSearching,
|
|
633
|
+
searchError,
|
|
634
|
+
getSongUrl,
|
|
635
|
+
getLyric
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
exports.MikutapMusicPlayer = MikutapMusicPlayer;
|
|
640
|
+
exports.MusicPlayer = MusicPlayer;
|
|
641
|
+
exports.kugouAdapter = kugouAdapter;
|
|
642
|
+
exports.neteaseAdapter = neteaseAdapter;
|
|
643
|
+
exports.tencentAdapter = tencentAdapter;
|
|
644
|
+
exports.useMusic = useMusic;
|
|
645
|
+
exports.xiamiAdapter = xiamiAdapter;
|
|
646
|
+
//# sourceMappingURL=chunk-L5PW2YTI.js.map
|
|
647
|
+
//# sourceMappingURL=chunk-L5PW2YTI.js.map
|