1. Asmr 페이지, AsmrPopUp 페이지 수정
- 음원 최대 3개에서 최대 4개까지로 변경
- AsmrPopUp 페이지에 예외 처리 추가 (새로고침 시 Asmr 페이지로 이동)
- 음원 삭제 시 가장 처음에 있는 음원이 적용 안되는 문제 해결
(따로따로 있던 delete 함수를 하나의 함수에 담고, 조건문을 사용하여 조건에 맞으면 삭제 되도록 수정했다.) - CSS 수정
- Asmr.js → Inline Style 부분들 styled-component로 변경
- AsmrPopUp.js → Inline Style 부분들 styled-component로 변경 + 기록이 없습니다. 변경
2. service-worker 적용 확인
- 1차 시도
2022.01.09 - [더 알아보기/기능] - PWA를 사용하여 push 알림 설정하기 (React + Node.js)
- 2차 시도
https://gist.github.com/ninanung/3c3520359abed543a2bb8e09e49212e4
- 3차 시도 : 팀원분께서 해결하신 후 알려주셨다.
service-worker.js가 index.html과 다른 폴더에 있으면 연결이 안되는 이슈가 발생 → public 폴더에 담아 주셨다. → Push Companion에서 public key를 받아서 index.html에 key 넣어주고 → console에 찍힌 인증 코드를 Subscription to Send To에 넣어준다. → SEND PUSH MESSAGE를 누르면 알림이 뜬다. (만약, 알림이 안뜬다면 window 상에서 Chrome 알림 설정을 허용 해줘야 한다.
더보기
더보기
더보기
// public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script>
let appServerPublicKey =
"BLWGR4hQ1GAXksMfhmbOSwspsWET47QI-K5defhvsvMrJhQtbobOQqk7QbC03z3T4BMojv8iQF6lIlspdqBZoFA";
let swRegist = null;
let isSubscribed = true;
Notification.requestPermission().then(function (permission) {
// if ("serviceWorker" in navigator) {
if (Notification.permission === "granted") {
navigator.serviceWorker
.register("./sw.js") // 서비스워커 등록 public에 있는 sw.js 의 경로로 등록해줌
.then((regist) => {
swRegist = regist;
test(swRegist);
console.log("권한 승인해서 서비스워커 등록!");
console.log(swRegist);
}); // 권한 허용이 되었다면 실행
}
if (Notification.permission === "denied") {
// 권한 차단 했을경우 실행
console.log("권한 거부했음!");
updateSubscription(null);
return;
}
// }
});
const test = (swRegist) => {
console.log(swRegist);
swRegist = swRegist;
const initPush = (isSubscribed) => {
console.log(swRegist);
// const pushButton = document.getElementById("subscribe");
// pushButton.addEventListener("click", () => {
// console.log(isSubscribed);
// if (isSubscribed) {
// unsubscribe();
// } else {
subscribe();
// }
// }
// );
console.log(swRegist);
swRegist.pushManager.getSubscription().then(function (subscription) {
isSubscribed = !(subscription === null); // null 이면 true 이니 !true 가 false 로 해서 isSubscribed 가 false 라는뜻
updateSubscription(subscription); // updateSubscription 함수로 구독 정보를 전달
if (isSubscribed) {
console.log("User IS subscribed.");
} else {
console.log("User is NOT subscribed.");
}
updateButton();
});
function subscribe() {
let appServerPublicKey =
"BLWGR4hQ1GAXksMfhmbOSwspsWET47QI-K5defhvsvMrJhQtbobOQqk7QbC03z3T4BMojv8iQF6lIlspdqBZoFA"; // 자신의 public key 넣어줘야함
const applicationServerKey =
urlBase64ToUint8Array(appServerPublicKey);
swRegist.pushManager
.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey,
})
.then((subscription) => {
console.log("User is subscribed.");
updateSubscription(subscription);
console.log(subscription);
isSubscribed = true; // 구독정보를 반아온 경우 구독을 정상적으로 한 상황이므로 true로 변경
updateButton();
})
.catch((err) => {
console.log("Failed to subscribe the user: ", err);
updateButton();
});
}
//구독 버튼 상태 갱신
function updateButton() {
// TODO: 알림 권한 거부 처리
if (Notification.permission === "granted") {
// 권한 허용이 되었다면 실행
// new Notification("푸시허용 테스트 알림!!"); // 알림 내용 그대로 보여줌
}
if (Notification.permission === "denied") {
// 권한 차단 했을경우 실행
updateSubscription(null);
return;
}
// const pushButton = document.getElementById("subscribe");
if (isSubscribed) {
// pushButton.textContent = "Disable Push Messaging";
} else {
// pushButton.textContent = "Enable Push Messaging";
}
// pushButton.disabled = false; // true로하면 해당 버튼이 안눌리고 비활성화 된다.
}
// 구독 정보 갱신
function updateSubscription(subscription) {
// TODO: 구독 정보 서버로 전송
// let detailArea = document.getElementById("subscription_detail");
if (subscription) {
console.log(JSON.stringify(subscription));
// detailArea.innerText = JSON.stringify(subscription);
// detailArea.parentElement.classList.remove("hide");
} else {
// detailArea.parentElement.classList.add("hide");
}
}
//알림 구독 취소
function unsubscribe() {
swRegist.pushManager
.getSubscription()
.then((subscription) => {
if (subscription) {
return subscription.unsubscribe();
}
})
.catch((error) => {
console.log("Error unsubscribing", error);
})
.then(() => {
updateSubscription(null);
console.log("User is unsubscribed.");
isSubscribed = false;
updateButton();
});
}
function urlBase64ToUint8Array(base64String) {
var padding = "=".repeat((4 - (base64String.length % 4)) % 4);
var base64 = (base64String + padding)
.replace(/\-/g, "+")
.replace(/_/g, "/");
var rawData = window.atob(base64);
var outputArray = new Uint8Array(rawData.length);
for (var i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
};
initPush();
};
</script>
</body>
</html>
// public/sw.js
window.self.addEventListener('install', pEvent => {
console.log( "서비스워커 설치 함!")
})
// This allows the web app to trigger skipWaiting via
// registration.waiting.postMessage({type: 'SKIP_WAITING'})
window.self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
window.self.skipWaiting();
}
});
// Any other custom service worker logic can go here.
window.self.addEventListener('push', function (event){ // push 이벤트나 service-worker.js 와 접점이 없는거 같다
console.log('Push ' + event.data.text());
const title = 'My PWA!';
const options = {
body: event.data.text()
};
event.waitUntil(window.self.registration.showNotification(title, options)); // showNotification을 통해 푸시 알림을 생성, Promise가 반환되며 waitUntil을 통해 이벤트를 연장 시켜야함
});
window.self.addEventListener('notificationclick', function(event) {
console.log('Push clicked');
event.notification.close();
event.waitUntil(
window.self.clients.openWindow('http://localhost:3000/') // 예시로 일단 로컬호스트로 링크 누르면 가지는걸로 해놨다.
);
});
https://web-push-codelab.glitch.me/
3. S3에 https로 배포하는 과정 - 개떡 같은 정리 양해 바람
- S3에 접속해서 버킷을 만든다. (총 2개를 만들어야 한다.)
- 도메인 이름(ex, zzzapp.co.kr)(가비아에서 구매한 도메인)에 build한 파일을 넣는다.
- www.도메인 이름(ex, www.zzzapp.co.kr)에 build 안한 파일을 넣고 정책 설정 안하고, redirection 설정, 호스팅 이름이 들어가 있다. - Route 53에 도메인을 넣어야 한다. (ex, zzzapp.co.kr을 넣으면 2개의 파일?이 생성된다.) 생성된 4개의 name을 가비아에 넣는다.
- 인증 요청을 보내야 한다. 해당 도메인에 DNS 요청을 보내면 상태가 심사중으로 뜨고, 인증서 id로 record를 하나 더 생성 해줘서 Route 53에 갔을 때 더 생겨 있을 텐데 name을 만들고 나서 조금만 있으면 인증서 발급을 해준다.
- 인증서가 활성화 되면 클라우트 프론트(Cloud Front)에 가서 배포 생성을 한다.
도메인이 S3에 있는 게 자동으로 뜨는 데 build한 파일로 넣어주고 http or https로 선택하고, 인증서 땡겨오고, 대체 도메인에 zzzapp.co.kr을 넣어주고 배포하기를 누르면 배포가 끝난다. - 처음 배포한 사이트에 들어가면 403 에러가 뜨는 데 이건 클라우드 프론트(Cloud Front)에서 redirect 403으로 막혀 있다. (react-router-dom 때문이다.) 이거를 클라우드 프론트(Cloud Front)에 오류 페이지에 403오류 정보를 넣어주고 무효화를 시켜 주면 된다.
배포한 사이트
'항해 중 > 8-13주차 실전 프로젝트' 카테고리의 다른 글
[실전 프로젝트] :hover 이벤트 발생 시 형제 요소 선택해서 스타일 변경하기 (0) | 2022.01.12 |
---|---|
[실전 프로젝트] 페이지마다 컴포넌트 나누기 (0) | 2022.01.11 |
[실전 프로젝트] animation 사용해서 Spinner 만들기(styled-component 자식 요소 선택하는 방법) (0) | 2022.01.07 |
[실전 프로젝트] CSS 작업 + 폰트 적용 (0) | 2022.01.03 |
[실전 프로젝트] Swiper 기능 만들기 (0) | 2022.01.02 |
댓글