오늘 한 일
1. 로그인 유도 팝업창 어떤 상황에서 띄울 지 아침 회의에서 정함
2. 로그인 전에 다이어리 페이지 접근 하려고 하면 로그인 유도 팝업창 띄우기
3. 음원 활성화 시 play, 비활성화 시 pause 되도록 구현
코드 구현
1) 로그인 전에 다이어리 페이지 접근 하려고 하면 로그인 유도 팝업창 띄우기 → 첫 시도에는 모달창이 켜지는 데 그 뒤에는 켜지지 않음 (Modal이 false가 되어서 안켜지는 것 같음) → RequireLogin.js와 Navigation.js 코드 수정
(미니 프로젝트 할 때 메인 → 로그인 팝업 띄울 때 상황이랑 똑같아서 미니 프로젝트 코드를 참고했다.)
더보기
더보기
// src/components/Navigation.js
import React from "react";
import styled from "styled-components";
import { useHistory } from "react-router-dom";
import RequireLogin from "../components/RequireLogin";
const Navigation = (props) => {
const history = useHistory();
const token = localStorage.getItem("token");
const [diaryModal, setDiaryModal] = React.useState(false);
const diary = () => {
if (!token) {
setDiaryModal(true);
} else {
history.push("/diary");
}
};
return (
<>
<div
style={{
display: "flex",
justifyContent: "space-between",
width: "300px",
backgroundColor: "#dddddd",
margin: "auto",
marginTop: `${props.marginTop ? props.marginTop : ""}`,
padding: "10px",
}}
>
<div
onClick={() => {
history.push("/");
}}
>
<Icon></Icon>홈
</div>
<div
onClick={() => {
history.push("/asmr");
}}
>
<Icon></Icon>ASMR
</div>
<div onClick={diary}>
<Icon></Icon>다이어리
</div>
{diaryModal && (
<RequireLogin
modal={diaryModal}
setDiaryModal={setDiaryModal}
></RequireLogin>
)}
<div
onClick={() => {
history.push("/mypage");
}}
>
<Icon></Icon>마이
</div>
</div>
</>
);
};
const Icon = styled.div`
width: 30px;
height: 30px;
border: 1px dotted black;
margin: auto;
`;
export default Navigation;
// src/components/RequireLogin.js
import { fontWeight, margin, textAlign } from "@mui/system";
import React from "react";
import Modal from "react-modal";
import { history } from "../redux/configureStore";
const RequireLogin = (props) => {
const [modal, setModal] = React.useState(props.modal ? true : false); // 모달창
const modalOff = () => {
setModal(false);
props.setDiaryModal(false);
};
return (
<>
<Modal
isOpen={modal}
ariaHideApp={false}
onRequestClose={modalOff}
style={{
overlay: {
position: "fixed",
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: "rgba(255, 255, 255, 0)",
},
content: {
position: "absolute",
top: "200px",
left: "40%",
width: "20%",
height: "40%",
border: "1px solid #ccc",
background: "#C4C4C4ff",
overflow: "auto",
WebkitOverflowScrolling: "touch",
borderRadius: "30px",
outline: "none",
padding: "0px",
},
}}
>
<div>
<p
style={{
fontSize: "13px",
fontWeight: "700",
textAlign: "center",
margin: "40px 0px 0px 0px",
}}
>
해당 서비스는 로그인 후 이용 가능합니다
</p>
<p
style={{
fontSize: "13px",
fontWeight: "500",
textAlign: "center",
margin: "10px 0px 0px 0px",
}}
>
로그인하러 가시겠습니까?
</p>
</div>
<div
style={{
display: "flex",
alignContent: "flex-end",
position: "absolute",
bottom: "0px",
width: "100%",
}}
>
<button
style={{
width: "100%",
height: "50px",
border: "none",
margin: "0px 1px 0px 0px",
}}
onClick={() => history.push("/login")}
>
예
</button>
<button
style={{ width: "100%", height: "50px", border: "none" }}
onClick={modalOff}
>
아니오
</button>
</div>
</Modal>
</>
);
};
export default RequireLogin;
2) 음원 활성화 시 play, 비활성화 시 pause 되도록 구현
: 음원 활성화 시 재생 / 비활성화 시 정지 기능 구현 할 때 pause가 안되서 질문을 올렸었는데! 아래처럼 답변이 왔다.
- 접점을 만들어 주기 위해서 컴포넌트에 audio 객체를 담을 state를 3개 만들어 줬다.
const [song1, setSong1] = React.useState(new Audio());
const [song2, setSong2] = React.useState(new Audio());
const [song3, setSong3] = React.useState(new Audio());
- 음원 선택 시 활성화 되면 음원 재생
// 음원 선택 시 활성화 되면서 음원 재생
if (!song1.src) {
song1.src = asmrUrl;
song1.loop = true;
song1.play();
} else if (!song2.src) {
song2.src = asmrUrl;
song2.loop = true;
song2.play();
} else if (!song3.src) {
song3.src = asmrUrl;
song3.loop = true;
song3.play();
}
- 음원 다시 한번 더 선택 시 비활성화 되면 음원 정지
// 비활성화 시 음원도 해당 음원 재생 정지
if (song1.src.indexOf(asmrUrl) !== -1) {
song1.pause();
setSong1(new Audio());
} else if (song2.src.indexOf(asmrUrl) !== -1) {
song2.pause();
setSong2(new Audio());
} else if (song3.src.indexOf(asmrUrl) !== -1) {
song3.pause();
setSong3(new Audio());
}
되도록 코드를 변경했다!
전체 코드
더보기
더보기
import React from "react";
import styled from "styled-components";
import { useDispatch, useSelector } from "react-redux";
import { useHistory } from "react-router-dom";
import { actionCreators as asmrActions } from "../redux/modules/asmr";
import AsmrPopUp from "../components/AsmrPopUp";
const Asmr = ({ location }) => {
const [getCategory, setCategory] = React.useState(
location.category ? location.category : "전체"
);
const [sound, setSound] = React.useState([]);
const asmrInfo = useSelector((state) => state.asmr.asmrList);
const [play, setPlay] = React.useState([]);
const [song1, setSong1] = React.useState(new Audio());
const [song2, setSong2] = React.useState(new Audio());
const [song3, setSong3] = React.useState(new Audio());
const history = useHistory();
const dispatch = useDispatch();
const [openModal, setOpenmodal] = React.useState(false);
React.useEffect(() => {
// 1) 카테고리별 활성화 유무
const arr = ["전체", "자연", "공간", "물체"];
arr.forEach((arrItem) => {
if (arrItem !== getCategory) {
// 비활성화
document.getElementById(arrItem).style.color = "black";
}
document.getElementById(getCategory).style.color = "white"; // 활성화
});
// 2) 음원 데이터 유무
if (!asmrInfo) {
dispatch(asmrActions.getAsmrDB());
}
// 3) 음원을 출력하기 전에 카테고리에 맞게 필터링
if (getCategory === "전체") {
const all = asmrInfo.filter((item) => {
if (item.categoryName === "전체") {
return item;
}
});
setSound(all);
} else if (getCategory === "자연") {
const nature = asmrInfo.filter((item) => {
if (item.categoryName === "자연") {
return item;
}
});
setSound(nature);
} else if (getCategory === "공간") {
const place = asmrInfo.filter((item) => {
if (item.categoryName === "공간") {
return item;
}
});
setSound(place);
} else if (getCategory === "물체") {
const object = asmrInfo.filter((item) => {
if (item.categoryName === "물체") {
return item;
}
});
setSound(object);
}
// 4) 카테고리가 바뀌면 활성화된 음원 초기화
setPlay([]);
}, [getCategory]);
const select = (asmrUrl) => {
if (play.includes(asmrUrl)) {
// 비활성화
let arr = [...play];
arr = arr.filter((item) => {
if (asmrUrl !== item) {
return item;
}
});
setPlay(arr);
// 비활성화 시 음원도 해당 음원 재생 정지
if (song1.src.indexOf(asmrUrl) !== -1) {
song1.pause();
setSong1(new Audio());
} else if (song2.src.indexOf(asmrUrl) !== -1) {
song2.pause();
setSong2(new Audio());
} else if (song3.src.indexOf(asmrUrl) !== -1) {
song3.pause();
setSong3(new Audio());
}
// 선택한 음원 비활성화 style
const deleteItem = document.getElementById(asmrUrl);
deleteItem.style.backgroundColor = "gray";
} else {
// 활성화
if (play.length > 2) {
window.alert("음원은 3개까지만 담으실 수 있습니다.");
} else {
const arr = [...play, asmrUrl];
setPlay(arr);
// 음원 선택 시 활성화 되면서 음원 재생
if (!song1.src) {
song1.src = asmrUrl;
song1.loop = true;
song1.play();
} else if (!song2.src) {
song2.src = asmrUrl;
song2.loop = true;
song2.play();
} else if (!song3.src) {
song3.src = asmrUrl;
song3.loop = true;
song3.play();
}
// 선택한 음원 활성화 style
const selectItem = document.getElementById(asmrUrl);
selectItem.style.backgroundColor = "#dddddd";
}
}
};
return (
<>
<div>
{" "}
{/* 나중에 여기로 전체 크기 핸드폰 사이즈로 바꿔야함 */}
<div
onClick={() => {
history.push("/");
}}
>
ASMR 페이지
</div>
<div style={{ display: "flex", margin: "0px 40%" }}>
<Category
id="전체"
onClick={() => {
setCategory("전체");
}}
>
전체
</Category>
<Category
id="자연"
onClick={() => {
setCategory("자연");
}}
>
자연
</Category>
<Category
id="공간"
onClick={() => {
setCategory("공간");
}}
>
공간
</Category>
<Category
id="물체"
onClick={() => {
setCategory("물체");
}}
>
물체
</Category>
</div>
<div style={{ margin: "0px 40%", display: "flex", flexWrap: "wrap" }}>
{sound.map((item) => {
return (
<Sound
id={item.asmrUrl}
key={item.categoryIdx}
onClick={() => {
select(item.asmrUrl);
}}
>
<p>{item.asmrUrl}</p>
<p>{item.title}</p>
</Sound>
);
})}
</div>
{play.length > 0 ? (
<button
onClick={() => {
setOpenmodal(true);
console.log("음원 url 가지고 이동!!!", play);
}}
>
음량 조절 하러 가기
</button>
) : null}
{openModal && <AsmrPopUp play={play} closeModal={setOpenmodal} />}
</div>
</>
);
};
const Category = styled.div`
width: 100px;
height: 50px;
line-height: 50px;
background-color: gray;
`;
const Sound = styled.div`
width: 100px;
height: 100px;
background-color: gray;
margin: 10px;
`;
export default Asmr;
'항해 중 > 8-13주차 실전 프로젝트' 카테고리의 다른 글
[실전 프로젝트] Swiper 기능 만들기 (0) | 2022.01.02 |
---|---|
[실전 프로젝트] 드롭다운 기능 만들기 (0) | 2022.01.02 |
[실전 프로젝트] 음원 재생 시 pause()가 동작 안하는 문제 (0) | 2021.12.30 |
[실전 프로젝트] ASMR 페이지 구현 (0) | 2021.12.30 |
[실전 프로젝트] 다이어리 페이지 마무리, 네비게이션 바 만들기 (0) | 2021.12.29 |
댓글