diff --git a/.DS_Store b/.DS_Store index ec8337d..94170d9 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/final/.DS_Store b/final/.DS_Store new file mode 100644 index 0000000..2153bcb Binary files /dev/null and b/final/.DS_Store differ diff --git a/final/Signup.html b/final/Signup.html new file mode 100644 index 0000000..dc102a6 --- /dev/null +++ b/final/Signup.html @@ -0,0 +1,61 @@ + + + + + + Signup + + + + + + + + + +
+ +

+
+
+
+
+ +
+

Username

+ +

Email

+ +

Password

+ +

+ +

+

Already have an account? Login here

+
+ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/final/css/.DS_Store b/final/css/.DS_Store new file mode 100644 index 0000000..78273c7 Binary files /dev/null and b/final/css/.DS_Store differ diff --git a/final/css/edit-profile.css b/final/css/edit-profile.css new file mode 100644 index 0000000..b7f495b --- /dev/null +++ b/final/css/edit-profile.css @@ -0,0 +1,63 @@ +.change-profile{ + width: 100px; + height: 100px; + margin: 0 auto; + /* background-color:#3e2fae; */ + background-image: url("../imgs/change-profile.png"); + background-size: cover; + border-radius: 15px; +} + +body{ + background-color: #eeeeee; + font-family: 'Josefin Sans', sans-serif; +} + +header{ + display: none; +} +#profilePicInput{ + display: none; +} + +.edit{ + padding-top: 50px; + width: 80vw; + margin: 0 auto; + text-align: left; +} + +.edit p{ + margin-bottom: 10px; + font-size: 1.2em; + text-align: left; + +} + +#usernameInput{ + font-size: 1em; + text-indent: 10px; + border-radius: 10px; + border: 2px solid #f9d861; + width: 100%; + height: 32px; + +} +#statusInput{ + font-size: 1em; + text-indent: 10px; + border-radius: 10px; + border: 2px solid #f9d861; + width: 100%; + height: 32px; +} + + +#profileSaveInput{ + font-size: 1em; + background-color: #f9d861; + width: 100%; + margin-top: 20px; + border-radius: 10px; + height: 36px; +} \ No newline at end of file diff --git a/final/css/groupchat.css b/final/css/groupchat.css new file mode 100644 index 0000000..305ab3b --- /dev/null +++ b/final/css/groupchat.css @@ -0,0 +1,44 @@ +body{ + background-color: #3e2fae; + width: 90vw; + height: 100vh; + margin: 0 auto; +} + +#searchMsg{ + width:100%; + text-indent: 10px; + height: 30px; + background-color: #ffffff; + border-radius: 10px; + border:2px solid #f9d861; + font-family: 'Josefin Sans', sans-serif; + margin-left: 20px; +} + +.flex-box{ + display: flex; + align-items: center; + justify-content: space-around; + margin-top: 5vh; +} + +h2{ + color: white; + font-family: 'Josefin Sans', sans-serif; +} + +h4{ + font-family: 'Josefin Sans', sans-serif; + color: black; + background-color: #f9d861; + border-radius: 10px; + padding: 10px 10px; +} + +a{ + text-decoration: none; +} +a:visited{ + color: black; +} \ No newline at end of file diff --git a/final/css/login.css b/final/css/login.css new file mode 100644 index 0000000..f56fb5b --- /dev/null +++ b/final/css/login.css @@ -0,0 +1,76 @@ +.logo{ + margin: 0 auto; + text-align: center; + margin-top: 80px; + font-family: 'Josefin Sans', sans-serif; +} + +body{ + font-family: 'Josefin Sans', sans-serif; + background-color: #eee; +} + +h1{ + color: #3e2fae; +} + + + +.edit{ + padding-top: 50px; + width: 80vw; + margin: 0 auto; + text-align: left; +} + +.edit p{ + margin-bottom: 10px; + font-size: 1.2em; + text-align: left; + +} +#usernameInput{ + font-size: 1em; + text-indent: 10px; + border-radius: 10px; + border: 2px solid #f9d861; + width: 100%; + height: 32px; + font-family: 'Josefin Sans', sans-serif; + +} +#emailInput{ + font-size: 1em; + text-indent: 10px; + border-radius: 10px; + border: 2px solid #f9d861; + width: 100%; + height: 32px; + font-family: 'Josefin Sans', sans-serif; +} + +#passwordInput{ + font-size: 1em; + text-indent: 10px; + border-radius: 10px; + border: 2px solid #f9d861; + width: 100%; + height: 32px; + font-family: 'Josefin Sans', sans-serif; +} + +#profileSaveInput{ + font-size: 1em; + background-color: #f9d861; + width: 100%; + margin-top: 20px; + border-radius: 10px; + height: 36px; + font-family: 'Josefin Sans', sans-serif; +} + +div .login{ + font-size: 0.8em; + text-align: center; +} + diff --git a/final/css/main.css b/final/css/main.css new file mode 100755 index 0000000..b164ede --- /dev/null +++ b/final/css/main.css @@ -0,0 +1,246 @@ +* { + box-sizing: border-box; +} +body { + + background-color: #c4c4c4; + color:black; + width: 100vw; + margin: 0px; + padding: 0px; + max-height: 100vh; + overflow: hidden; + font-family: 'Josefin Sans', sans-serif; +} + +a{ + text-decoration: none; + color: black; +} + + + #burger ~ nav { + background-color: #3e2fae; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100px; + z-index: 3; + transition: .5s; + transition-delay: .01s; + overflow: hidden; + } + + +nav{ + background-color: #3e2fae; + display: flex; + justify-content: space-around; +} +nav a{ + align-self: center; +} +nav h2{ + margin: 0px; + align-self: center; + color: white; + font-size: 1.4em + +} + + +#profilePic { + width: 200px; + height: 200px; + border-radius: 50%; + background-color: darkgray; + display: flex; + align-items: center; + justify-content: center; +} + +.pfp{ + padding-bottom: 50px; +} + + +.Me { + + color: black; + display: flex; + flex-direction: column; + align-items: flex-end; + justify-content: space-between; + text-align: right; + font-family: 'Josefin Sans', sans-serif; +} + +.Me > .people{ + + color:black; + padding-right: 20px; + font-size: 1em; + margin: 0; + font-family: 'Josefin Sans', sans-serif; +} + + +#chatbox{ + + width: 100%; + height: 90vh; + overflow: auto; + background: #fff; + padding: 5vw; + padding-top: 110px; + + +} + + + +div{ + + display: flex; + justify-content: space-between; + text-align: left; + font-family: 'Josefin Sans', sans-serif;; + +} + +div > span > h4{ + font-size: 10px; + opacity: 50%; + margin:0; + +} + +div > span > h2{ + + font-family: 'Josefin Sans', sans-serif; + font-size: 1em; + margin-bottom: 4px; +} +div:not(.Me) > span > p{ + + margin-top: 5px; + background-color: #f9d861; + -webkit-border-radius: 8px; + -webkit-border-top-left-radius: 0; + -moz-border-radius: 8px; + -moz-border-radius-topleft: 0; + border-radius: 8px; + border-top-left-radius: 0; + padding-left: 15px; + padding-right: 15px; + font-size: 15px; + padding-top: 8px; + padding-bottom: 8px; + +} + +.Me > span > p{ + margin-top: 5px; + text-align: left; + background-color:#3e2fae; + -webkit-border-radius: 8x; + -webkit-border-top-right-radius: 0; + -moz-border-radius: 8px; + -moz-border-radius-topright: 0; + border-radius: 8px; + border-top-right-radius: 0; + padding-left: 15px; + padding-right: 15px; + font-size: 15px; + padding-top: 8px; + padding-bottom: 8px; + color: #fff; + +} + +.Me > span > h2{ + font-family: 'Josefin Sans', sans-serif; +} + +#chatinbox{ + position: absolute; + width:100%; + height: 10%; + background-color: #eee; + padding: 20px; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-around; + + } + +#chatinbox > #newmsg { + width: 88%; + font-size: 1em; + display: flex; + align-items: center; + justify-content: center; + border:2px solid #3e2fae; + font-family: 'Josefin Sans', sans-serif; + margin-right: 10px; + + } +#newmsg { + background-color: white; + border-radius: 10px; + padding-right: 10px; + + +} + +/* #sendBtn { + color:#3e2fae; + border-radius: 50%; + outline: none; + display: flex; + align-items: center; + justify-content: center; + padding-right: 2px; +} */ +header{ + width: 50px; + padding: 10px; + margin: 10px; +} +.center{ + display: flex; + + flex-direction: column; + padding: 0; + + justify-content: center; + align-items: center; + +} + +.center > p{ + background-color: #fff; + padding: 15px; + -webkit-border-radius: 20px; +-moz-border-radius: 20px; +border-radius: 20px; +width: 200px; +} +input{ + display: flex; + justify-content: center; + border: none; + width: 100%; + padding: 10px; +} +#profileSaveInput{ + margin-top: 10px; + padding: 10px; + -webkit-border-radius: 20px; +-moz-border-radius: 20px; +border-radius: 20px; +background-color: rgb(112, 112, 175); +color: white; +} \ No newline at end of file diff --git a/final/css/profile.css b/final/css/profile.css new file mode 100755 index 0000000..6bdee79 --- /dev/null +++ b/final/css/profile.css @@ -0,0 +1,95 @@ +body{ + font-family: 'Josefin Sans', sans-serif; + background-color: #eee; + width: 100vw; + margin: 0; + padding: 0; +} + +header{ + background-color: #3e2fae; + min-height: 45vh; + width: 100vw; + margin:0; + padding: 0; +} +header a img{ + display: block; + padding-top: 5vh; + padding-bottom: 10px; + padding-left: 20px; + padding-right: 20px + + +} +header .profile{ + display: block; + margin: 0 auto; + text-align: center; + padding-top: 20px; +} +header p{ + text-align: center; + color: white; + font-family: 'Josefin Sans', sans-serif; + font-size: 20px; +} + +.input{ + text-align: center; + display: none; +} + +#usernameDisplay{ + text-align: center; + color: white; + font-size: 2em; + font-weight: bold; +} + +#userStatusDisplay{ + text-align: center; + color: white; + font-size: 1em; + +} + +.profile{ + display: flex; + flex-direction: column; + align-items: center; +} + +#userProfilePicDisplay{ + width: 100px; + height: 100px; + border-radius: 15px; +} + +a{ + display: block; + text-decoration: none; + text-align: center; + font-size: 1.5em; +} +a:visited{ + color:black; +} + +.button{ + width: 80vw; + margin: 0 auto; + text-align: left; +} + +button{ + font-size: 0.8em; + background-color: #f9d861; + margin-top: 20px; + border-radius: 10px; + font-family: 'Josefin Sans', sans-serif; + border: 2px solid #f9d861; + width: 100%; + padding: 0; + height: 32px; +} \ No newline at end of file diff --git a/final/css/signup.css b/final/css/signup.css new file mode 100644 index 0000000..6e8966a --- /dev/null +++ b/final/css/signup.css @@ -0,0 +1,87 @@ +.logo{ + margin: 0 auto; + text-align: center; + margin-top: 80px; + font-family: 'Josefin Sans', sans-serif; +} + +body{ + font-family: 'Josefin Sans', sans-serif; + background-color: #eee; +} + +h1{ + color: #3e2fae; +} + + + +.edit{ + padding-top: 50px; + width: 80vw; + margin: 0 auto; + text-align: left; +} + +.edit p{ + margin-bottom: 10px; + font-size: 1.2em; + text-align: left; + +} +#usernameInput{ + font-size: 1em; + text-indent: 10px; + border-radius: 10px; + border: 2px solid #f9d861; + width: 100%; + height: 32px; + font-family: 'Josefin Sans', sans-serif; + +} +#emailInput{ + font-size: 1em; + text-indent: 10px; + border-radius: 10px; + border: 2px solid #f9d861; + width: 100%; + height: 32px; + font-family: 'Josefin Sans', sans-serif; +} + +#passwordInput{ + font-size: 1em; + text-indent: 10px; + border-radius: 10px; + border: 2px solid #f9d861; + width: 100%; + height: 32px; + font-family: 'Josefin Sans', sans-serif; +} + +#profileSaveInput{ + font-size: 1em; + background-color: #f9d861; + width: 100%; + margin-top: 20px; + border-radius: 10px; + height: 36px; + font-family: 'Josefin Sans', sans-serif; +} + +div .login{ + font-size: 0.8em; + text-align: center; +} + +.login > a{ + font-size: 1.2em; + color: #3e2fae; +} + +.profile{ + display: none; +} +a{ + text-decoration: none; +} \ No newline at end of file diff --git a/final/icon192.png b/final/icon192.png new file mode 100644 index 0000000..cd035a3 Binary files /dev/null and b/final/icon192.png differ diff --git a/final/icon512.png b/final/icon512.png new file mode 100644 index 0000000..8f79164 Binary files /dev/null and b/final/icon512.png differ diff --git a/final/imgs/.DS_Store b/final/imgs/.DS_Store new file mode 100644 index 0000000..5cd5f19 Binary files /dev/null and b/final/imgs/.DS_Store differ diff --git a/final/imgs/backbutton.png b/final/imgs/backbutton.png new file mode 100644 index 0000000..4e627ae Binary files /dev/null and b/final/imgs/backbutton.png differ diff --git a/final/imgs/camera.png b/final/imgs/camera.png new file mode 100644 index 0000000..4e355ec Binary files /dev/null and b/final/imgs/camera.png differ diff --git a/final/imgs/change-profile.png b/final/imgs/change-profile.png new file mode 100644 index 0000000..668a6ed Binary files /dev/null and b/final/imgs/change-profile.png differ diff --git a/final/imgs/hamburger.png b/final/imgs/hamburger.png new file mode 100644 index 0000000..ecd61d1 Binary files /dev/null and b/final/imgs/hamburger.png differ diff --git a/final/imgs/icon-transparent.png b/final/imgs/icon-transparent.png new file mode 100644 index 0000000..40f2f99 Binary files /dev/null and b/final/imgs/icon-transparent.png differ diff --git a/final/imgs/profile.png b/final/imgs/profile.png new file mode 100644 index 0000000..b298494 Binary files /dev/null and b/final/imgs/profile.png differ diff --git a/final/imgs/sendbutton.png b/final/imgs/sendbutton.png new file mode 100644 index 0000000..437dc54 Binary files /dev/null and b/final/imgs/sendbutton.png differ diff --git a/final/index.html b/final/index.html new file mode 100755 index 0000000..7e5c57d --- /dev/null +++ b/final/index.html @@ -0,0 +1,74 @@ + + + + + + + Chatmate + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/final/js/.DS_Store b/final/js/.DS_Store new file mode 100644 index 0000000..cd13533 Binary files /dev/null and b/final/js/.DS_Store differ diff --git a/final/js/edit-profile.js b/final/js/edit-profile.js new file mode 100644 index 0000000..5be80ef --- /dev/null +++ b/final/js/edit-profile.js @@ -0,0 +1,52 @@ + +let userName = localStorage.getItem('userName') || "Yucheng"; +let userStatus = localStorage.getItem('userStatus') || "update your profile to display a status"; +let userProfilePic = localStorage.getItem('userProfilePic') || "profile.png" ; +let usernameInput = document.querySelector("#usernameInput"); +let statusInput = document.querySelector("#statusInput"); +let profilePicInput = document.querySelector("#profilePicInput"); +let profileSaveInput = document.querySelector("#profileSaveInput"); +let userProfilePicDisplay = document.querySelector("#userProfilePicDisplay"); + +// setting the input values default +usernameInput.value = localStorage.getItem('userName'); +statusInput.value = localStorage.getItem('userStatus'); +userProfilePicDisplay.value = localStorage.getItem('profilePicInput') + +function saveProfileImageLocally() { + if (profilePicInput.files && profilePicInput.files[0]) { + var reader = new FileReader(); + reader.onload = function(e) { + localStorage.setItem("userProfilePic", reader.result); + } + reader.readAsDataURL(profilePicInput.files[0]); + } +} + +//set button colors when click +/* var count = 1; + function setColor(btn, color) { + var property = document.getElementById("profileSaveInput"); + if (count == 0) { + property.style.backgroundColor = "#f9d861" + count = 1; + } + else { + property.style.backgroundColor = "#3e2fae" + count = 0; + } + } */ + + + +profileSaveInput.addEventListener( 'click', function(e) { + e.preventDefault(); + localStorage.setItem("userName", usernameInput.value); + localStorage.setItem("userStatus", statusInput.value); + + saveProfileImageLocally(); +}); + +usernameDisplay.innerHTML = userName; +userStatusDisplay.innerHTML = userStatus; +userProfilePicDisplay.src = userProfilePic; \ No newline at end of file diff --git a/final/js/firebase-chat-functions.js b/final/js/firebase-chat-functions.js new file mode 100755 index 0000000..fd56646 --- /dev/null +++ b/final/js/firebase-chat-functions.js @@ -0,0 +1,28 @@ +function saveMessageToFirebase(msg) { + db.collection("messages").add(msg) +} + +function getAllMessagesFromFirebase() { + let allMsgs = []; + db.collection("messages").orderBy('dateStamp', 'asc').limit(200).get().then(function(querySnapshot) { + querySnapshot.forEach(function(doc) { + // doc.data() is never undefined for query doc snapshots + allMsgs.push(doc.data()) + }); + }); + + return allMsgs; +} + +function watchFirebaseForChanges(callBack) { + db.collection("messages").orderBy('dateStamp','asc').onSnapshot(function(querySnapshot) { + querySnapshot.docChanges().forEach(function(change) { + if (change.type === "added") { + callBack(change.doc); + } + }); + }); +} + + +//getAllMessagesFromFirebase(); diff --git a/final/js/firebase-config.js b/final/js/firebase-config.js new file mode 100755 index 0000000..166ed82 --- /dev/null +++ b/final/js/firebase-config.js @@ -0,0 +1,12 @@ +var firebaseConfig = { + apiKey: "AIzaSyAbh39Rb-F9_PO8lpAoob_qA1dYUVNYAkg", + authDomain: "dmd-3440-pwa-demo.firebaseapp.com", + databaseURL: "https://dmd-3440-pwa-demo.firebaseio.com", + projectId: "dmd-3440-pwa-demo", + storageBucket: "dmd-3440-pwa-demo.appspot.com", + messagingSenderId: "239477441112", + appId: "1:239477441112:web:0dcd3f94fe067b09ac402d" + }; + // Initialize Firebase + firebase.initializeApp(firebaseConfig); + var db = firebase.firestore(); \ No newline at end of file diff --git a/final/js/main.js b/final/js/main.js new file mode 100755 index 0000000..173f7dc --- /dev/null +++ b/final/js/main.js @@ -0,0 +1,117 @@ + + +// Register a service worker, this one located in serviceworker.js +// A service worker is a piece of code the browser runs behind the scenes. +if ('serviceWorker' in navigator) { + console.log('CLIENT: service worker registration in progress.'); + navigator.serviceWorker.register('sw.js').then(function() { + console.log('CLIENT: service worker registration complete.'); + }, function() { + console.log('CLIENT: service worker registration failure.'); + }); + } else { + console.log('CLIENT: service workers are not supported.'); + } + + + +let allMessages = []; +let chatBox = document.querySelector("#chatbox"); +let inputBox = document.querySelector("#newmsg"); + +// var pictureEndpoint= document.querySelector("#profilePic"); + +// pictureEndpoint.setAttribute("src",localStorage.userProfilePic) + + +let curr_date = new Date(); +let month = curr_date.getMonth() + 1; +let dateStr = month.toString() + "/" + curr_date.getDate().toString() + "/" + curr_date.getFullYear().toString(); + +let curr_time = new Date(); +let timeStr = curr_time.getHours().toString() + ":" + curr_time.getMinutes().toString(); +// document.getElementById("time").innerHTML = timeStr; + +function makeMessage(msg) { + + var stagedMessage = document.createElement("div"); + var inLineContainer = document.createElement("span"); + var name = document.createElement("h2"); + + var message = document.createElement("p"); + var timeStamp = document.createElement("h4"); + + if(msg.sentBy == localStorage.userName){ + stagedMessage.setAttribute("class", "Me"); + } + + inLineContainer.setAttribute("class", "people"); + + + name.innerHTML=msg.sentBy; + timeStamp.innerHTML=msg.timeStr + " " + msg.dateStr; + message.innerHTML=msg.message; + + + inLineContainer.appendChild(name); + inLineContainer.appendChild(timeStamp); + + stagedMessage.appendChild(inLineContainer); + inLineContainer.appendChild(message); + chatBox.appendChild(stagedMessage); + stagedMessage.scrollIntoView(); + //allMessages.push(newMessage); + + + console.log(allMessages); +} + + + + + + +document.querySelector("#sendBtn").addEventListener('click', () => { + let msg = document.querySelector("#newmsg").value; + let src = "notification.mp3" + let audio = new Audio(src); + audio.play(); + + document.querySelector("#newmsg").value = ""; + document.querySelector("#newmsg").focus(); + + + + + let userMsg = { + sentBy: localStorage.userName, + //dateStamp: date_str, + dateStr: month.toString() + "/" + curr_date.getDate().toString() + "/" + curr_date.getFullYear().toString(), + message: msg + + } + if (localStorage.userName != undefined) { + saveMessageToFirebase(userMsg); + } else { + alert("Set a Username"); + } + + + inputBox.value = ""; + inputBox.focus(); + + console.log(new_message); + window.navigator.vibrate(200); + + + //makeMessage("Me", date_str, msg,localStorage.userName); + +}); + + + +watchFirebaseForChanges( + function(msg){ + makeMessage(msg.data()) + } +); \ No newline at end of file diff --git a/final/js/profile.js b/final/js/profile.js new file mode 100755 index 0000000..4ec22f3 --- /dev/null +++ b/final/js/profile.js @@ -0,0 +1,55 @@ + +let userName = localStorage.getItem('userName') || "Yucheng"; +let userStatus = localStorage.getItem('userStatus') || "update your profile to display a status"; +let userProfilePic = localStorage.getItem('userProfilePic') || "profile.png" ; +let usernameInput = document.querySelector("#usernameInput"); +let statusInput = document.querySelector("#statusInput"); +// let emailInput = document.querySelector("#emailInput"); +let profilePicInput = document.querySelector("#profilePicInput"); +let profileSaveInput = document.querySelector("#profileSaveInput"); +let userProfilePicDisplay = document.querySelector("#userProfilePicDisplay"); + +// setting the input values default +usernameInput.value = localStorage.getItem('userName'); +statusInput.value = localStorage.getItem('userStatus'); +userProfilePicDisplay.value = localStorage.getItem('profilePicInput') +// emailInput.value = localStorage.getItem('userEmail'); + +function saveProfileImageLocally() { + if (profilePicInput.files && profilePicInput.files[0]) { + var reader = new FileReader(); + reader.onload = function(e) { + localStorage.setItem("userProfilePic", reader.result); + } + reader.readAsDataURL(profilePicInput.files[0]); + } +} + +//set button colors when click +/* var count = 1; + function setColor(btn, color) { + var property = document.getElementById("profileSaveInput"); + if (count == 0) { + property.style.backgroundColor = "#f9d861" + count = 1; + } + else { + property.style.backgroundColor = "#3e2fae" + count = 0; + } + } */ + + + +profileSaveInput.addEventListener( 'click', function(e) { + e.preventDefault(); + localStorage.setItem("userName", usernameInput.value); + localStorage.setItem("userStatus", statusInput.value); + // localStorage.setItem("userEmail", emailInput.value); + + saveProfileImageLocally(); +}); +usernameDisplay.innerHTML = userName; +userStatusDisplay.innerHTML = userStatus; +// userEmailDisplay.innerHTML = userEmail; +userProfilePicDisplay.src = userProfilePic; \ No newline at end of file diff --git a/final/js/register-sw.js b/final/js/register-sw.js new file mode 100755 index 0000000..2b40a14 --- /dev/null +++ b/final/js/register-sw.js @@ -0,0 +1,12 @@ +// Register a service worker, this one located in serviceworker.js +// A service worker is a piece of code the browser runs behind the scenes. +if ('serviceWorker' in navigator) { + console.log('CLIENT: service worker registration in progress.'); + navigator.serviceWorker.register('sw.js').then(function() { + console.log('CLIENT: service worker registration complete.'); + }, function() { + console.log('CLIENT: service worker registration failure.'); + }); + } else { + console.log('CLIENT: service workers are not supported.'); + } \ No newline at end of file diff --git a/final/js/signup.js b/final/js/signup.js new file mode 100644 index 0000000..922a56a --- /dev/null +++ b/final/js/signup.js @@ -0,0 +1,51 @@ + +let userName = localStorage.getItem('userName') || "Yucheng"; +let userStatus = localStorage.getItem('userStatus') || "update your profile to display a status"; +let userProfilePic = localStorage.getItem('userProfilePic') || "profile.png" ; +let usernameInput = document.querySelector("#usernameInput"); +let emailInput = document.querySelector("#emailInput"); +let profilePicInput = document.querySelector("#profilePicInput"); +let profileSaveInput = document.querySelector("#profileSaveInput"); +let userProfilePicDisplay = document.querySelector("#userProfilePicDisplay"); + +// setting the input values default +usernameInput.value = localStorage.getItem('userName'); +emailInput.value = localStorage.getItem('userEmail'); +userProfilePicDisplay.value = localStorage.getItem('profilePicInput') + +function saveProfileImageLocally() { + if (profilePicInput.files && profilePicInput.files[0]) { + var reader = new FileReader(); + reader.onload = function(e) { + localStorage.setItem("userProfilePic", reader.result); + } + reader.readAsDataURL(profilePicInput.files[0]); + } +} + +//set button colors when click +/* var count = 1; + function setColor(btn, color) { + var property = document.getElementById("profileSaveInput"); + if (count == 0) { + property.style.backgroundColor = "#f9d861" + count = 1; + } + else { + property.style.backgroundColor = "#3e2fae" + count = 0; + } + } */ + + + +profileSaveInput.addEventListener( 'click', function(e) { + e.preventDefault(); + localStorage.setItem("userName", usernameInput.value); + localStorage.setItem("userEmail", emailInput.value); + + saveProfileImageLocally(); +}); +usernameDisplay.innerHTML = userName; +userEmailDisplay.innerHTML = userEmail; +userProfilePicDisplay.src = userProfilePic; \ No newline at end of file diff --git a/final/js/sw.js b/final/js/sw.js new file mode 100755 index 0000000..971588f --- /dev/null +++ b/final/js/sw.js @@ -0,0 +1,200 @@ +console.log('SERVICE WORKER: executing.'); + +/* A version number is useful when updating the worker logic, + allowing you to remove outdated cache entries during the update. +*/ +var version = 'v6::'; + +/* These resources will be downloaded and cached by the service worker + during the installation process. If any resource fails to be downloaded, + then the service worker won't be installed either. +*/ +var offlineFiles = [ + '', + 'whatsapp-icon.png', + 'icon2.png', + 'index.html', + 'main.css', + 'main.js' +]; + +/* The install event fires when the service worker is first installed. + You can use this event to prepare the service worker to be able to serve + files while visitors are offline. +*/ +self.addEventListener("install", function(event) { + console.log('WORKER: install event in progress.'); + /* Using event.waitUntil(p) blocks the installation process on the provided + promise. If the promise is rejected, the service worker won't be installed. + */ + event.waitUntil( + /* The caches built-in is a promise-based API that helps you cache responses, + as well as finding and deleting them. + */ + caches + /* You can open a cache by name, and this method returns a promise. We use + a versioned cache name here so that we can remove old cache entries in + one fell swoop later, when phasing out an older service worker. + */ + .open(version + 'fundamentals') + .then(function(cache) { + /* After the cache is opened, we can fill it with the offline fundamentals. + The method below will add all resources in `offlineFiles` to the + cache, after making requests for them. + */ + return cache.addAll(offlineFiles); + }) + .then(function() { + console.log('WORKER: install completed'); + }) + ); +}); + +/* The fetch event fires whenever a page controlled by this service worker requests + a resource. This isn't limited to `fetch` or even XMLHttpRequest. Instead, it + comprehends even the request for the HTML page on first load, as well as JS and + CSS resources, fonts, any images, etc. +*/ +self.addEventListener("fetch", function(event) { + console.log('WORKER: fetch event in progress.'); + + /* We should only cache GET requests, and deal with the rest of method in the + client-side, by handling failed POST,PUT,PATCH,etc. requests. + */ + if (event.request.method !== 'GET') { + /* If we don't block the event as shown below, then the request will go to + the network as usual. + */ + console.log('WORKER: fetch event ignored.', event.request.method, event.request.url); + return; + } + /* Similar to event.waitUntil in that it blocks the fetch event on a promise. + Fulfillment result will be used as the response, and rejection will end in a + HTTP response indicating failure. + */ + event.respondWith( + caches + /* This method returns a promise that resolves to a cache entry matching + the request. Once the promise is settled, we can then provide a response + to the fetch request. + */ + .match(event.request) + .then(function(cached) { + /* Even if the response is in our cache, we go to the network as well. + This pattern is known for producing "eventually fresh" responses, + where we return cached responses immediately, and meanwhile pull + a network response and store that in the cache. + + Read more: + https://ponyfoo.com/articles/progressive-networking-serviceworker + */ + var networked = fetch(event.request) + // We handle the network request with success and failure scenarios. + .then(fetchedFromNetwork, unableToResolve) + // We should catch errors on the fetchedFromNetwork handler as well. + .catch(unableToResolve); + + /* We return the cached response immediately if there is one, and fall + back to waiting on the network as usual. + */ + console.log('WORKER: fetch event', cached ? '(cached)' : '(network)', event.request.url); + return cached || networked; + + function fetchedFromNetwork(response) { + /* We copy the response before replying to the network request. + This is the response that will be stored on the ServiceWorker cache. + */ + var cacheCopy = response.clone(); + + console.log('WORKER: fetch response from network.', event.request.url); + + caches + // We open a cache to store the response for this request. + .open(version + 'pages') + .then(function add(cache) { + /* We store the response for this request. It'll later become + available to caches.match(event.request) calls, when looking + for cached responses. + */ + return cache.put(event.request, cacheCopy); + }) + .then(function() { + console.log('WORKER: fetch response stored in cache.', event.request.url); + }); + + // Return the response so that the promise is settled in fulfillment. + return response; + } + + /* When this method is called, it means we were unable to produce a response + from either the cache or the network. This is our opportunity to produce + a meaningful response even when all else fails. It's the last chance, so + you probably want to display a "Service Unavailable" view or a generic + error response. + */ + function unableToResolve () { + /* There's a couple of things we can do here. + - Test the Accept header and then return one of the `offlineFiles` + e.g: `return caches.match('/some/cached/image.png')` + - You should also consider the origin. It's easier to decide what + "unavailable" means for requests against your origins than for requests + against a third party, such as an ad provider. + - Generate a Response programmaticaly, as shown below, and return that. + */ + + console.log('WORKER: fetch request failed in both cache and network.'); + + /* Here we're creating a response programmatically. The first parameter is the + response body, and the second one defines the options for the response. + */ + return new Response('

Service Unavailable

', { + status: 503, + statusText: 'Service Unavailable', + headers: new Headers({ + 'Content-Type': 'text/html' + }) + }); + } + }) + ); +}); + +/* The activate event fires after a service worker has been successfully installed. + It is most useful when phasing out an older version of a service worker, as at + this point you know that the new worker was installed correctly. In this example, + we delete old caches that don't match the version in the worker we just finished + installing. +*/ +self.addEventListener("activate", function(event) { + /* Just like with the install event, event.waitUntil blocks activate on a promise. + Activation will fail unless the promise is fulfilled. + */ + console.log('WORKER: activate event in progress.'); + + event.waitUntil( + caches + /* This method returns a promise which will resolve to an array of available + cache keys. + */ + .keys() + .then(function (keys) { + // We return a promise that settles when all outdated caches are deleted. + return Promise.all( + keys + .filter(function (key) { + // Filter by keys that don't start with the latest version prefix. + return !key.startsWith(version); + }) + .map(function (key) { + /* Return a promise that's fulfilled + when each outdated cache is deleted. + */ + return caches.delete(key); + }) + ); + }) + .then(function() { + console.log('WORKER: activate completed.'); + }) + ); +}); \ No newline at end of file diff --git a/final/login.html b/final/login.html new file mode 100644 index 0000000..b51ccc3 --- /dev/null +++ b/final/login.html @@ -0,0 +1,27 @@ + + + + + + Login + + + + + +
+

Username

+ +

Password

+ +

+ +

+
+ + + + \ No newline at end of file diff --git a/final/mainfest.json b/final/mainfest.json new file mode 100755 index 0000000..4513a31 --- /dev/null +++ b/final/mainfest.json @@ -0,0 +1,20 @@ +{ + "short_name": "Chatmate", + "name": "Chatmate", + "icons": [ + { + "src":"icon192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icon512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": "index.html", + "background_color": "#3e2fa", + "theme_color": "#3e2fa", + "display": "fullscreen" + } \ No newline at end of file diff --git a/final/notification.mp3 b/final/notification.mp3 new file mode 100644 index 0000000..d8f9071 Binary files /dev/null and b/final/notification.mp3 differ diff --git a/imgs/.DS_Store b/imgs/.DS_Store index 203c0e1..0ce7aea 100644 Binary files a/imgs/.DS_Store and b/imgs/.DS_Store differ diff --git a/manifest.json b/manifest.json index 8a3c5f5..0f76670 100644 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { - "short_name": "Room of Chat", - "name": "Room of Chat", + "short_name": "Chatmate", + "name": "Chatmate", "icons": [ { "src":"icon192.png",