Compare commits
3 Commits
Author | SHA1 | Date |
---|---|---|
al | e9e95f3749 | |
al | de9e8e747e | |
al | e01fbaa9af |
|
@ -299,7 +299,6 @@ function Login({ handleLogin }) {
|
|||
<OwnInput
|
||||
clearable={true}
|
||||
placeholder="请输入手机号"
|
||||
// disabled={true}
|
||||
name="phone_number"
|
||||
type="number"
|
||||
maxLength={11}
|
||||
|
@ -330,7 +329,6 @@ function Login({ handleLogin }) {
|
|||
/> */}
|
||||
<OwnInput
|
||||
placeholder="请输入验证码"
|
||||
// disabled={true}
|
||||
name="veriCode"
|
||||
type="number"
|
||||
onChange={setVeriCode}
|
||||
|
@ -382,7 +380,6 @@ function Login({ handleLogin }) {
|
|||
<OwnInput
|
||||
clearable={true}
|
||||
placeholder="请输入手机号"
|
||||
// disabled={true}
|
||||
name="phone_number"
|
||||
type="number"
|
||||
maxLength={11}
|
||||
|
@ -417,7 +414,6 @@ function Login({ handleLogin }) {
|
|||
<OwnInput
|
||||
clearable={true}
|
||||
placeholder="请输入密码"
|
||||
// disabled={true}
|
||||
name="password"
|
||||
type="password"
|
||||
onChange={(value) => {
|
||||
|
|
|
@ -316,7 +316,6 @@ export default function CreateProfile() {
|
|||
// 新版本
|
||||
// superfan_price_list,
|
||||
};
|
||||
debugger;
|
||||
const _data = await requireAPI(
|
||||
"POST",
|
||||
"/api/zone/create",
|
||||
|
|
|
@ -36,6 +36,7 @@ import requireAPI from "@/utils/requireAPI";
|
|||
import { get } from "@/utils/storeInfo";
|
||||
import UploadImgs from "@/components/UploadImgs";
|
||||
import { multiUploadImage } from "@/utils/upload";
|
||||
import { getVideoBase64 } from "@/utils/tools";
|
||||
const constellations = [
|
||||
{ label: "白羊座", value: "白羊座" },
|
||||
{ label: "金牛座", value: "金牛座" },
|
||||
|
@ -480,41 +481,19 @@ export default function CompleteStreamerInformation() {
|
|||
],
|
||||
}));
|
||||
} else {
|
||||
creatVideoCanvas(file);
|
||||
const url = URL.createObjectURL(file);
|
||||
getVideoBase64(url).then((src) => {
|
||||
setFrameImageUrl(src);
|
||||
setFormData((old) => ({
|
||||
...old,
|
||||
displayVideo: [
|
||||
{
|
||||
url: frameImageUrl,
|
||||
displayVideo: {
|
||||
url: src,
|
||||
file: Array.from(e.target.files),
|
||||
},
|
||||
],
|
||||
}));
|
||||
});
|
||||
}
|
||||
};
|
||||
const creatVideoCanvas = (file) => {
|
||||
if (typeof window == "undefined") return;
|
||||
const videoD = document.getElementById("video_complete");
|
||||
const url = URL.createObjectURL(file);
|
||||
videoD.src = url;
|
||||
videoD.addEventListener("loadeddata", function () {
|
||||
videoD.pause();
|
||||
videoD.currentTime = 1;
|
||||
});
|
||||
videoD.addEventListener("seeked", function () {
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = videoD.videoWidth;
|
||||
canvas.height = videoD.videoHeight;
|
||||
canvas
|
||||
.getContext("2d")
|
||||
.drawImage(videoD, 0, 0, canvas.width, canvas.height);
|
||||
const canvasImg = canvas.toDataURL();
|
||||
setFrameImageUrl(canvasImg);
|
||||
|
||||
// 释放URL对象
|
||||
URL.revokeObjectURL(url);
|
||||
});
|
||||
};
|
||||
//审核中的情况
|
||||
if (isWaitingReview) {
|
||||
return (
|
||||
|
@ -1131,12 +1110,6 @@ export default function CompleteStreamerInformation() {
|
|||
<SpinLoading color="default" />
|
||||
</div>
|
||||
</Mask>
|
||||
<div className="hidden">
|
||||
<video id="video_complete" controls autoPlay name="media">
|
||||
<source />
|
||||
您的浏览器不支持 Video 标签。
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -281,7 +281,7 @@ export default function PersonSpace() {
|
|||
</div>
|
||||
<ul className="flex mt-8">
|
||||
<li
|
||||
className="flex flex-col items-center mr-6"
|
||||
className="flex flex-col items-center mr-4"
|
||||
onClick={() =>
|
||||
setMaskVisible({ visible: true, type: "weChat" })
|
||||
}
|
||||
|
@ -298,7 +298,7 @@ export default function PersonSpace() {
|
|||
placeholder=""
|
||||
/>
|
||||
</div>
|
||||
<p className="text-xs">查看微信</p>
|
||||
<p className="text-xs whitespace-nowrap">查看微信</p>
|
||||
</li>
|
||||
<li
|
||||
className="flex flex-col items-center mr-6"
|
||||
|
@ -318,7 +318,7 @@ export default function PersonSpace() {
|
|||
placeholder=""
|
||||
/>
|
||||
</div>
|
||||
<p className="text-xs">
|
||||
<p className="text-xs whitespace-nowrap">
|
||||
{streamerInfo?.is_ironfanship_unlocked === 1
|
||||
? "已是铁粉"
|
||||
: "成为铁粉"}
|
||||
|
@ -362,7 +362,7 @@ export default function PersonSpace() {
|
|||
placeholder=""
|
||||
/>
|
||||
</div>
|
||||
<p className="text-xs">
|
||||
<p className="text-xs whitespace-nowrap">
|
||||
{streamerInfo?.is_superfanship_unlocked === 1
|
||||
? "尊贵超粉"
|
||||
: "成为超粉"}
|
||||
|
@ -387,7 +387,7 @@ export default function PersonSpace() {
|
|||
placeholder=""
|
||||
/>
|
||||
</div>
|
||||
<p className="text-xs">举报</p>
|
||||
<p className="text-xs whitespace-nowrap">举报</p>
|
||||
</li>
|
||||
{streamerInfo?.visitor_role === 3 && (
|
||||
<li
|
||||
|
@ -406,7 +406,7 @@ export default function PersonSpace() {
|
|||
placeholder=""
|
||||
/>
|
||||
</div>
|
||||
<p className="text-xs">审核未通过</p>
|
||||
<p className="text-xs whitespace-nowrap">审核未通过</p>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
|
|
|
@ -7,6 +7,7 @@ import { faAngleRight, faAngleLeft } from "@fortawesome/free-solid-svg-icons";
|
|||
import UploadImgs from "@/components/UploadImgs";
|
||||
import requireAPI from "@/utils/requireAPI";
|
||||
import { multiUploadImage } from "@/utils/upload";
|
||||
import { getVideoBase64 } from "@/utils/tools";
|
||||
export default function EditStreamerMedia() {
|
||||
const router = useRouter();
|
||||
//保存封面图
|
||||
|
@ -92,14 +93,17 @@ export default function EditStreamerMedia() {
|
|||
},
|
||||
}));
|
||||
} else {
|
||||
creatVideoCanvas(file);
|
||||
const url = URL.createObjectURL(file);
|
||||
getVideoBase64(url).then((src) => {
|
||||
setFrameImageUrl(src);
|
||||
setFormData((old) => ({
|
||||
...old,
|
||||
displayVideo: {
|
||||
url: frameImageUrl,
|
||||
url: src,
|
||||
file: Array.from(e.target.files),
|
||||
},
|
||||
}));
|
||||
});
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
|
@ -189,29 +193,6 @@ export default function EditStreamerMedia() {
|
|||
}
|
||||
};
|
||||
|
||||
const creatVideoCanvas = (file) => {
|
||||
if (typeof window == "undefined") return;
|
||||
const videoD = document.getElementById("video_edit_streamer");
|
||||
const url = URL.createObjectURL(file);
|
||||
videoD.src = url;
|
||||
videoD.addEventListener("loadeddata", function () {
|
||||
videoD.pause();
|
||||
videoD.currentTime = 1;
|
||||
});
|
||||
videoD.addEventListener("seeked", function () {
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = videoD.videoWidth;
|
||||
canvas.height = videoD.videoHeight;
|
||||
canvas
|
||||
.getContext("2d")
|
||||
.drawImage(videoD, 0, 0, canvas.width, canvas.height);
|
||||
const canvasImg = canvas.toDataURL();
|
||||
setFrameImageUrl(canvasImg);
|
||||
|
||||
// 释放URL对象
|
||||
URL.revokeObjectURL(url);
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
setFormData((old) => ({ ...old, imageAssets: oldPhotos }));
|
||||
}, [oldPhotos]);
|
||||
|
@ -364,12 +345,6 @@ export default function EditStreamerMedia() {
|
|||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="hidden">
|
||||
<video id="video_edit_streamer" controls name="media">
|
||||
<source />
|
||||
您的浏览器不支持 Video 标签。
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -34,11 +34,11 @@ export default function AddToHome() {
|
|||
建议您添加<span className="text-primary">铁粉空间</span>
|
||||
到手机桌面
|
||||
</p>
|
||||
<p className="text-[#ffffffb2] text-xs">以便随时关注圈子动态</p>
|
||||
<p className="text-[#ffffffb2] text-xs">以便随时关注空间动态</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="bg-primary px-4 py-2 rounded-full font-bold"
|
||||
className="bg-primary px-4 py-2 rounded-full font-bold whitespace-nowrap"
|
||||
onClick={() => setFirstLogin((old) => ({ ...old, second: true }))}
|
||||
>
|
||||
去添加
|
||||
|
@ -66,7 +66,9 @@ export default function AddToHome() {
|
|||
<Image
|
||||
fit="cover"
|
||||
// src={process.env.NEXT_PUBLIC_WEB_ASSETS_URL+"/icons/nodata.png"}
|
||||
src={process.env.NEXT_PUBLIC_WEB_ASSETS_URL+"/icons/ios_share.png"}
|
||||
src={
|
||||
process.env.NEXT_PUBLIC_WEB_ASSETS_URL + "/icons/ios_share.png"
|
||||
}
|
||||
placeholder=""
|
||||
width={32}
|
||||
height={32}
|
||||
|
@ -76,7 +78,9 @@ export default function AddToHome() {
|
|||
<Image
|
||||
fit="contain"
|
||||
// src={process.env.NEXT_PUBLIC_WEB_ASSETS_URL+"/icons/nodata.png"}
|
||||
src={process.env.NEXT_PUBLIC_WEB_ASSETS_URL+"/images/addToHome.png"}
|
||||
src={
|
||||
process.env.NEXT_PUBLIC_WEB_ASSETS_URL + "/images/addToHome.png"
|
||||
}
|
||||
placeholder=""
|
||||
width={54}
|
||||
height={70}
|
||||
|
|
|
@ -11,9 +11,9 @@ export default function OwnInput({
|
|||
name,
|
||||
placeholder,
|
||||
clearable,
|
||||
disabled,
|
||||
disabled = false,
|
||||
className,
|
||||
inputClassName,
|
||||
inputClassName = "",
|
||||
fontSize,
|
||||
id,
|
||||
}) {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
"use client";
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { DotLoading, Image, Toast, ImageViewer, Modal } from "antd-mobile";
|
||||
import { DotLoading, Image, List, ImageViewer, Modal } from "antd-mobile";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faAdd, faClose, faPlay } from "@fortawesome/free-solid-svg-icons";
|
||||
import { getVideoBase64 } from "@/utils/tools";
|
||||
import { DragDropContext, Draggable, Droppable } from "@hello-pangea/dnd";
|
||||
export default function UploadImgs({
|
||||
assets,
|
||||
getImgs,
|
||||
|
@ -20,7 +22,9 @@ export default function UploadImgs({
|
|||
const [frameImage, setFrameImage] = useState({ src: null, h: 0, w: 0 });
|
||||
useEffect(() => {
|
||||
if (existImages.length > 0) {
|
||||
setFilesUrls(existImages.map((it) => it.url));
|
||||
setFilesUrls(
|
||||
existImages.map((it, index) => ({ url: it.url, id: `${index}` }))
|
||||
);
|
||||
}
|
||||
if (videoSrc) {
|
||||
setVideoUrl(videoSrc);
|
||||
|
@ -37,7 +41,10 @@ export default function UploadImgs({
|
|||
var videoObj = document.createElement("video");
|
||||
const eles = Array.from(e.target.files);
|
||||
if (type == 1) {
|
||||
const newFils = eles.map((it) => URL.createObjectURL(it));
|
||||
const newFils = eles.map((it, index) => ({
|
||||
url: URL.createObjectURL(it),
|
||||
id: "new" + index,
|
||||
}));
|
||||
setFilesUrls((old) => [...old, ...newFils]);
|
||||
} else {
|
||||
videoObj.onloadedmetadata = function (evt) {
|
||||
|
@ -86,7 +93,13 @@ export default function UploadImgs({
|
|||
} else {
|
||||
Modal.show({
|
||||
content: (
|
||||
<video autoPlay>
|
||||
<video
|
||||
autoPlay
|
||||
playsInline
|
||||
controls
|
||||
muted={true}
|
||||
controlslist="nodownload"
|
||||
>
|
||||
<source src={videoUrl} />
|
||||
</video>
|
||||
),
|
||||
|
@ -100,39 +113,67 @@ export default function UploadImgs({
|
|||
};
|
||||
const creatVideoCanvas = (file) => {
|
||||
if (typeof window == "undefined") return;
|
||||
const videoD = document.getElementById("video_upload");
|
||||
// const videoD = document.getElementById("video_upload");
|
||||
const url = URL.createObjectURL(file);
|
||||
videoD.src = url;
|
||||
videoD.addEventListener("loadeddata", function () {
|
||||
videoD.pause();
|
||||
videoD.currentTime = 1;
|
||||
// videoD.src = url;
|
||||
getVideoBase64(url).then((src) => {
|
||||
setFrameImage((old) => ({ ...old, src }));
|
||||
setFilesUrls([{ url: src, id: "0" }]);
|
||||
});
|
||||
videoD.addEventListener("seeked", function () {
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = videoD.videoWidth;
|
||||
canvas.height = videoD.videoHeight;
|
||||
canvas
|
||||
.getContext("2d")
|
||||
.drawImage(videoD, 0, 0, canvas.width, canvas.height);
|
||||
const canvasImg = canvas.toDataURL("image/png");
|
||||
setFrameImage((old) => ({ ...old, src: canvasImg }));
|
||||
setFilesUrls([canvasImg]);
|
||||
// 释放URL对象
|
||||
URL.revokeObjectURL(url);
|
||||
};
|
||||
const reorder = (list, startIndex, endIndex) => {
|
||||
const result = Array.from(list);
|
||||
const [removed] = result.splice(startIndex, 1);
|
||||
result.splice(endIndex, 0, removed);
|
||||
|
||||
return result;
|
||||
};
|
||||
const onDragEnd = (result) => {
|
||||
if (!result.destination) return;
|
||||
const newList = reorder(
|
||||
assets,
|
||||
result.source.index,
|
||||
result.destination.index
|
||||
);
|
||||
getImgs([...newList]);
|
||||
// const newArr=newList.map((it,index)=>({...it,url:it.url||URL.createObjectURL(it)}))
|
||||
const newArr = newList.map((it, index) => {
|
||||
if (it.url) {
|
||||
return { url: it.url, id: `${index}` };
|
||||
} else {
|
||||
return { url: URL.createObjectURL(it), id: `${index}` };
|
||||
}
|
||||
});
|
||||
setFilesUrls(newArr);
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<div className="grid grid-cols-4 gap-1">
|
||||
{filesUrls.map((item, index) => {
|
||||
return (
|
||||
<DragDropContext onDragEnd={onDragEnd}>
|
||||
<Droppable direction="horizontal" droppableId="droppable">
|
||||
{(droppableProvided) => (
|
||||
<div
|
||||
className="mb-2 grid grid-cols-4 gap-1"
|
||||
ref={droppableProvided.innerRef}
|
||||
>
|
||||
{filesUrls.map((item, index) => (
|
||||
<Draggable key={item.id} draggableId={item.id} index={index}>
|
||||
{(provided, snapshot) => (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
style={{
|
||||
...provided.draggableProps.style,
|
||||
opacity: snapshot.isDragging ? 0.8 : 1,
|
||||
}}
|
||||
>
|
||||
<div key={index} className="rounded relative">
|
||||
<div
|
||||
onClick={() => showPhotos(filesUrls, index)}
|
||||
style={{ height: "calc(25vw - 0.75rem)" }}
|
||||
>
|
||||
<Image
|
||||
src={item}
|
||||
src={item.url}
|
||||
width="100%"
|
||||
height="100%"
|
||||
className="rounded"
|
||||
|
@ -155,15 +196,22 @@ export default function UploadImgs({
|
|||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</Draggable>
|
||||
))}
|
||||
{droppableProvided.placeholder}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
</DragDropContext>
|
||||
{loading && (
|
||||
<div className="rounded border-[#ffffff80] text-[#ffffff80] flex flex-col justify-center items-center">
|
||||
<DotLoading />
|
||||
<p>上传中</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="grid grid-cols-4 gap-1">
|
||||
{type == 2 && filesUrls.length > 0 ? null : (
|
||||
<>
|
||||
<label htmlFor="uploadAvatarBtn">
|
||||
|
@ -189,12 +237,6 @@ export default function UploadImgs({
|
|||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="hidden">
|
||||
<video id="video_upload" controls autoPlay name="media">
|
||||
<source />
|
||||
您的浏览器不支持 Video 标签。
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -92,3 +92,62 @@ export function utf8Length(str) {
|
|||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
export function getVideoBase64(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 创建 video 元素
|
||||
const video = document.createElement("video");
|
||||
// 设置跨域属性
|
||||
video.crossOrigin = "anonymous";
|
||||
// 设置视频 URL
|
||||
video.src = url;
|
||||
// 设置视频画面宽度
|
||||
video.width = "90";
|
||||
// 设置视频画面高度
|
||||
video.height = "90";
|
||||
// 设置视频播放位置为第一帧
|
||||
video.currentTime = 1;
|
||||
// 设置预加载方式为自动加载
|
||||
video.preload = "auto";
|
||||
|
||||
// 创建 canvas 元素
|
||||
const canvas = document.createElement("canvas");
|
||||
// 将 canvas 的宽度和高度设置为视频画面的宽度和高度
|
||||
canvas.width = video.width;
|
||||
canvas.height = video.height;
|
||||
|
||||
// 判断是否为 iOS 系统
|
||||
if (/(iPad|iPhone|iPod)/gi.test(navigator.userAgent)) {
|
||||
// 在 iOS 系统中,需要手动触发视频加载,然后设置自动播放和静音属性
|
||||
video.load();
|
||||
// video.autoplay = true;
|
||||
|
||||
// 在 iOS 系统中,监听 loadedmetadata 事件可以保证视频数据已经全部加载完毕
|
||||
}
|
||||
video.muted = true;
|
||||
video.addEventListener("loadeddata", function () {
|
||||
setTimeout(function () {
|
||||
console.log("监听到了listen:", "loadeddata");
|
||||
canvas
|
||||
.getContext("2d")
|
||||
.drawImage(video, 0, 0, canvas.width, canvas.height); //绘制canvas
|
||||
const dataURL = canvas.toDataURL("image/jpeg"); //转换为base64
|
||||
video.setAttribute("poster", dataURL);
|
||||
console.log(dataURL, "dataURL");
|
||||
resolve(dataURL);
|
||||
|
||||
// 清除内存
|
||||
canvas.remove();
|
||||
video.remove();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
// 监听视频事件,在发生错误时 Promise 会 reject
|
||||
video.addEventListener("error", function () {
|
||||
reject(new Error("视频加载错误"));
|
||||
// 清除内存
|
||||
canvas.remove();
|
||||
video.remove();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ export const handleShowVideo = (video) => {
|
|||
{/* <Video as={ReactPlayer} src={video.mp4} /> */}
|
||||
<Player
|
||||
src={video.mp4}
|
||||
controlslist="nodownload"
|
||||
poster={video?.url.src}
|
||||
blurDataURL={video?.url.blurDataURL}
|
||||
autoPlay={true}
|
||||
|
|
Loading…
Reference in New Issue