11 İşlemeler 55992529b6 ... 8822f65971

Yazar SHA1 Mesaj Tarih
  serg1557733 8822f65971 fix styles and start private messages 1 yıl önce
  serg1557733 56d606aa80 sw add and register, start working with cashe 1 yıl önce
  serg1557733 2c609fe1be fix messages styles and some bug 1 yıl önce
  serg1557733 f062b9b26e add loading progres button and fix bugs 1 yıl önce
  serg1557733 f8fdbea920 add loading progres spiner first stage 1 yıl önce
  serg1557733 e9d57662c6 fix file sending reducer 1 yıl önce
  serg1557733 07a9bfc27a fix images url for messages 1 yıl önce
  serg1557733 49def55c7b add user names for messages 1 yıl önce
  serg1557733 ec14be119a add notifications for new incoming messages 1 yıl önce
  serg1557733 d2a284b9fd fix url for pwa 1 yıl önce
  serg1557733 30333433fd fix url serwiceworker template and swregistration for pwa 1 yıl önce

+ 39 - 12
backend/app.js

@@ -13,7 +13,7 @@ const Uuid = require('uuid'); //lib for unic id generate
 const fileupload = require('express-fileupload');
 const fs = require('fs');
 
-
+const ORIGIN_URL = process.env.REACT_APP_BASE_URL
 
 const server = http.createServer(app);
 app.use(cors());
@@ -22,9 +22,7 @@ app.use(fileupload())
 app.use(express.static('avatars')); //folder for static files
 
 const io = require("socket.io")(server, {
-    cors: {
-        origin: "http://192.168.0.107:3000" //client endpoint and port
-    }
+    cors: ORIGIN_URL
 });
 const PORT = process.env.PORT || 5000;
 const TOKEN_KEY = process.env.TOKEN_KEY || 'rGH4r@3DKOg06hgj'; 
@@ -56,8 +54,6 @@ const getOneUser = async (userName) => {
     return userInDb;
 }
 app.post('/login', async (req, res) => {
-    
-
     try {
         const {userName,password} = req.body;
         if (!isValidUserName(userName)){
@@ -219,7 +215,7 @@ io.use( async (socket, next) => {
         const userName = user.userName;
         const dbUser = await getOneUser(userName);
 
-        if(dbUser.isBanned){
+        if(dbUser && dbUser.isBanned){
             socket.disconnect();
             return;
         }
@@ -243,9 +239,17 @@ io.on("connection", async (socket) => {
     const userName = socket.user.userName;
     const sockets = await io.fetchSockets();
     const dbUser = await getOneUser(userName);
+    const exist = sockets.find(current => current.user.userName == socket.user.userName)
+    const usersOnline = sockets.map(sock => sock.user)
+
+
+    const usersOnlineID = usersOnline.map(users => Object.values(users)[0])
+    const userSet = new Set(usersOnlineID)
 
+    console.log(userSet)
 
-    io.emit('usersOnline', sockets.map(sock => sock.user)); // send array online users  
+
+    io.emit('usersOnline', usersOnline); // send array online users  
 
     socket.emit('connected', dbUser); //socket.user
   
@@ -255,6 +259,7 @@ io.on("connection", async (socket) => {
 
     const messagesToShow = await Message.find({}).sort({ 'createDate': -1 }).limit(20).populate( {path:'user'});   
     socket.emit('allmessages', messagesToShow.reverse());
+
     socket.on("message", async (data) => {
         const dateNow = Date.now(); // for correct working latest post 
         const post = await Message.findOne({userName}).sort({ 'createDate': -1 })
@@ -295,9 +300,19 @@ io.on("connection", async (socket) => {
     
     try {
         socket.on("disconnect", async () => {
-            const sockets = await io.fetchSockets();
-            io.emit('usersOnline', sockets.map(sock => sock.user));
-            console.log(`user :${socket.user.userName} , disconnected to socket`); 
+
+            const exist = sockets.find(current => current.user.userName == socket.user.userName)
+            const usersOnline = sockets.map(sock => sock.user)
+        
+            const filteredUsersOnline = usersOnline.filter(user => exist.user.id !== user.id)
+        
+           
+           socket.emit('usersOnline', filteredUsersOnline);
+
+            // const sockets = await io.fetchSockets();
+            // io.emit('usersOnline', sockets.map(sock => sock.user));
+             console.log(`user :${socket.user.userName} , disconnected to socket`); 
+
         });
             console.log(`user :${socket.user.userName} , connected to socket`); 
         socket.on("muteUser",async (data) => {
@@ -317,6 +332,13 @@ io.on("connection", async (socket) => {
                     } 
                 // }
            });
+
+        socket.on('privat', (data) => {
+            console.log(data)
+        
+        })
+
+
     
         socket.on("banUser",async (data) => {
             if(!socket.user.isAdmin){
@@ -387,6 +409,12 @@ const start = async () => {
     try {
         await mongoose.connect('mongodb://localhost:27017/chat')
             .then(() => console.log(`DB started`))
+        
+
+        // await mongoose
+        //     .connect('mongodb+srv://serg1557733:1557733@cluster0.p9ltitx.mongodb.net/?retryWrites=true&w=majority')
+        //     .then(() => console.log(`DB started`))
+
         server.listen(PORT, () => {
             console.log(`Server started. Port: ${PORT}`);
         })
@@ -394,5 +422,4 @@ const start = async () => {
         console.log(e);
     }
 }
-
 start();

+ 119 - 0
frontend/public/service-worker.js

@@ -0,0 +1,119 @@
+console.log('start')
+
+const CASH = 'ver-1'
+const urlsToCash = ['index.html', 'offline.html']
+
+const self = this;
+
+self.addEventListener('install', (e) => {
+  console.log('self wait..')
+      e.waitUntil(
+        caches.open(CASH)
+          .then( cache => {
+          console.log('open cash', cache)
+
+          return cache.addAll(urlsToCash)
+          })
+    )
+})
+
+self.addEventListener('fetch', (e) => {
+    e.respondWith(
+        caches.match(e.request)
+            .then(() => {
+                return fetch(e.request)
+                    .catch(() => caches.match('offline.html'))
+            })
+    )
+})
+
+
+self.addEventListener('activate', (e) => {
+    const cacheWersions = [];
+    cacheWersions.push(CASH);
+
+    e.waitUntil(
+        caches.keys().then(cachNames => Promise.all(
+            cachNames.map(cacheName => {
+                    if(!cacheWersions.includes(cacheName)){
+                        return caches.delete(cacheName);
+                    }
+                }
+            )
+        ))
+    )
+
+  
+})
+// /* eslint-disable no-restricted-globals */
+
+// // This service worker can be customized!
+// // See https://developers.google.com/web/tools/workbox/modules
+// // for the list of available Workbox modules, or add any other
+// // code you'd like.
+// // You can also remove this file if you'd prefer not to use a
+// // service worker, and the Workbox build step will be skipped.
+
+// import { clientsClaim } from 'workbox-core';
+// import { ExpirationPlugin } from 'workbox-expiration';
+// import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching';
+// import { registerRoute } from 'workbox-routing';
+// import { StaleWhileRevalidate } from 'workbox-strategies';
+
+// clientsClaim();
+
+// // Precache all of the assets generated by your build process.
+// // Their URLs are injected into the manifest variable below.
+// // This variable must be present somewhere in your service worker file,
+// // even if you decide not to use precaching. See https://cra.link/PWA
+// precacheAndRoute(self.__WB_MANIFEST);
+
+// // Set up App Shell-style routing, so that all navigation requests
+// // are fulfilled with your index.html shell. Learn more at
+// // https://developers.google.com/web/fundamentals/architecture/app-shell
+// const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
+// registerRoute(
+//   // Return false to exempt requests from being fulfilled by index.html.
+//   ({ request, url }) => {
+//     // If this isn't a navigation, skip.
+//     if (request.mode !== 'navigate') {
+//       return false;
+//     } // If this is a URL that starts with /_, skip.
+
+//     if (url.pathname.startsWith('/_')) {
+//       return false;
+//     } // If this looks like a URL for a resource, because it contains // a file extension, skip.
+
+//     if (url.pathname.match(fileExtensionRegexp)) {
+//       return false;
+//     } // Return true to signal that we want to use the handler.
+
+//     return true;
+//   },
+//   createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')
+// );
+
+// // An example runtime caching route for requests that aren't handled by the
+// // precache, in this case same-origin .png requests like those from in public/
+// registerRoute(
+//   // Add in any other file extensions or routing criteria as needed.
+//   ({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), // Customize this strategy as needed, e.g., by changing to CacheFirst.
+//   new StaleWhileRevalidate({
+//     cacheName: 'images',
+//     plugins: [
+//       // Ensure that once this runtime cache reaches a maximum size the
+//       // least-recently used images are removed.
+//       new ExpirationPlugin({ maxEntries: 50 }),
+//     ],
+//   })
+// );
+
+// // This allows the web app to trigger skipWaiting via
+// // registration.waiting.postMessage({type: 'SKIP_WAITING'})
+// self.addEventListener('message', (event) => {
+//   if (event.data && event.data.type === 'SKIP_WAITING') {
+//     self.skipWaiting();
+//   }
+// });
+
+// Any other custom service worker logic can go here.

+ 27 - 6
frontend/src/components/chatPage/ChatPage.jsx

@@ -33,12 +33,26 @@ export const ChatPage = () => {
     const [message, setMessage] = useState({message: ''});
     const [isUserTyping, setUserTyping] = useState([]);
     const [isCamActiv, setisCamActiv] = useState(false);
+    const [showSpinner, setshowSpinner] = useState(false);
+    const [loadingPercentage, setLoadPercentage] = useState(0)
     
     const isTabletorMobile = (window.screen.width < 730);
 
-    const [play] = useSound(getNotif);
+    const [play] = useSound(getNotif, {volume: 0.005});
 
 
+    const axiosConfig =   {
+        headers: {
+            "Content-type": "multipart/form-data"
+          },
+        onUploadProgress: (progress) => {
+        const {loaded, total} = progress;
+        const loadStatus = Math.floor(loaded * 100 / total); 
+        setLoadPercentage(loadStatus)   
+        if(loadStatus == 100) {
+            setshowSpinner(false)
+        }
+    }}
 
     const webcamEventHandler = async () => {
             let stream = null;
@@ -151,20 +165,27 @@ export const ChatPage = () => {
                            
                         }>
                         <Button
+                            disabled={showSpinner}
                             variant="contained" 
                             component="label"
-                            sx = {{
+                            sx = {showSpinner? 
+                                {
+                                minWidth: 'auto'}
+                                :
+                                {
                                 minWidth: 'auto',
                                 backgroundImage:'url(' + imgBtn + ')' ,
                                 backgroundPosition: 'center', 
                                 backgroundRepeat: "no-repeat", 
-                                backgroundSize: '20px 40px'
+                                backgroundSize: '20px 20px'
 
                             }}
+                            style = {{color: 'green'}}
                         >
                         <input
                             onChange={e =>{
-                                dispatch(fileMessage(e.target.files))
+                                setshowSpinner(true)
+                                dispatch(fileMessage({files: e.target.files, axiosConfig}))
                             }}
 
                             type="file"
@@ -172,7 +193,7 @@ export const ChatPage = () => {
                             hidden
                         />
 
-                       
+                       {showSpinner? loadingPercentage : ""}
                         </Button>    
                         <Button
                             variant="contained" 
@@ -188,6 +209,7 @@ export const ChatPage = () => {
 
                             onClick = {() => webcamEventHandler()}
                         >
+                            
                         </Button>          
 
                         <TextareaAutosize
@@ -225,7 +247,6 @@ export const ChatPage = () => {
                             // }}
                         
                         /> 
-
                         <Button 
                             variant="contained" 
                             type='submit'

+ 16 - 5
frontend/src/components/chatPage/chatPage.scss

@@ -1,10 +1,10 @@
-#root {
-    max-height: 90vh;
+// #root {
+//     max-height: 90vh;
 
 
-}
+// }
 .rootContainer {
-    max-height: 90vh;
+    min-height: 90vh;
     max-width: 95%;
     margin: 0 auto;
 }
@@ -24,15 +24,20 @@
 
 .rootMessageForm {
     display: flex;
+    border-radius: 5px;
     flex-grow:2;
+    border: 2px solid grey; 
     max-width: 75%;
     flex-direction: column;                 
 }
 .rootMessageFormMobile {
     margin: 0 auto;
     display: flex;
+    border-radius: 5px;
+
     flex-grow:1;
     max-width: 100%;
+    border: 2px solid grey; 
     height: 90vh;
     flex-direction: column;                 
 }
@@ -59,6 +64,7 @@
 .message {
     padding: 10px;
     margin: 5px 0;
+    max-width: 80%;
     align-self: flex-start;
     border-radius: 10px;
     background-color: rgb(182, 230, 176);
@@ -78,6 +84,7 @@
 .myMessage {
     align-self: flex-end;
     position: relative;
+    max-width: 80%;
     background-color: rgb(240, 231, 136);
     cursor: pointer;
 }
@@ -118,16 +125,18 @@
 .usersBox { 
     align-content: flex-end;
     text-align: center;
-    padding: 20px;
     margin-left: 10px;
     width: 20%;
     overflow: scroll;
     border-radius: 10px;
+    border: 2px solid grey; 
     background-color:rgb(243, 243, 243);
     .online {
         border-radius: 5px;
         padding: 5px;
+        border: 2px solid grey; 
         margin-bottom: 5px;
+        cursor: pointer;
         background-color:rgb(247, 233, 233);
         font-weight: 700;
 
@@ -142,12 +151,14 @@
     overflow: scroll;
     font-size: 11px;
     border-radius: 10px;
+    border: 2px solid grey; 
     background-color:rgb(243, 243, 243);
     transition: all 3s ease-in-out;    
     .online {
         border-radius: 5px;
         text-overflow: ellipsis;
         padding: 5px;
+        border: 2px solid grey;
         margin-bottom: 5px;
         background-color:rgb(247, 233, 233);
         font-weight: 500;

+ 33 - 15
frontend/src/components/chatPage/messageForm/MessegaForm.jsx

@@ -9,7 +9,8 @@ import { StyledAvatar } from './StyledAvatar';
 import { MessageEditorMenu } from '../MessageEditorMenu.jsx';
 import imgBtn from '../../../assets/img/gg.png';
 import useSound from 'use-sound';
-import notifSound from '../../../assets/sendSound.mp3'
+import notifSound from '../../../assets/get.mp3'
+import { useMemo } from 'react';
 
 
 export const MessageForm = () => {
@@ -17,7 +18,7 @@ export const MessageForm = () => {
     const dispatch = useDispatch();
     const socket = useSelector(state => state.getUserSocketReducer.socket)
 
-    const SERVER_URL = process.env.REACT_APP_SERVER_URL|| 'http://192.168.0.107:5000/';
+    const SERVER_URL =process.env.REACT_APP_SERVER_URL
 
     const startMessages = useSelector(state => state.getUserSocketReducer.startMessages)
     const user = useSelector(state => state.getUserSocketReducer.socketUserData)
@@ -31,19 +32,23 @@ export const MessageForm = () => {
     const [isEditiedMessage, setIsEditiedMessage] = useState(false) //need to type in the bottom of message after message was edited
 
     const regYoutube = /http(?:s?):\/\/(?:www\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-\_]*)(&(amp;)?‌​[\w\?‌​=]*)?/; //for youtube video
-    
+    const messages = startMessages.concat(newMessages)  
+
     const [play] = useSound(notifSound);
 
     useEffect(() => {
         if (!isEditing) {
             scrollToBottom((endMessages)) 
-        }
-        if(newMessages.length > 0){
-            newMessages.map(i => console.log('newmessage', i.userName === user.userName))
-        }
-      }, [startMessages, newMessages]);
+        } 
+      }, [startMessages, messages, newMessages]);
            
-    const messages = startMessages.concat(newMessages)  
+    console.log(usersOnline)
+
+    useEffect(()=> {
+        if(newMessages.length > 0 && newMessages[newMessages.length-1].userName !== user.userName){
+           // play()                 
+        }
+    }, [newMessages])
 
     return (             
             <Box className='messageBox'>  
@@ -63,13 +68,18 @@ export const MessageForm = () => {
                         {storeMessageId === item._id ? <MessageEditorMenu />: ""} 
                         <StyledAvatar
 
+                            onClick={() => {
+                                socket.emit('privat', {data: item._id})
+                               
+                            }}
+
                             anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}  
                             variant = {userNamesOnlineSet.has(item.userName)? 'dot' : ''}
                                    
                             >
                             <Avatar 
                                 key={i} 
-                                src= {SERVER_URL + item?.user?.avatar}
+                                src= {SERVER_URL + '/'+ item?.user?.avatar}
                                 sx={
                                     (item.userName === user.userName)
                                     ? 
@@ -84,8 +94,16 @@ export const MessageForm = () => {
                                 {item?.userName.slice(0, 1)}
                             </Avatar>   
 
-                        
+
                         </StyledAvatar>
+                        <span
+                            style={{'alignItems': 'center',
+                                    marginLeft: 5, 
+                                    fontStyle: 'italic', 
+                                    fontWeight: 800
+                                }}
+
+                        > {item.userName}</span>
                         <div 
                             key={i}
                         
@@ -97,6 +115,7 @@ export const MessageForm = () => {
                            <iframe 
                                 width="280" 
                                 height="160" 
+                                style={{'maxWidth': "90%"}}
                                 src={`https://www.youtube.com/embed/`+ (item.text.match(regYoutube)[1])}
                                 title="YouTube video player" 
                                 allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
@@ -104,12 +123,11 @@ export const MessageForm = () => {
                                 
                             </iframe>
                             :
-                           
                             (item.file && item.fileType && item.fileType.split('/')[0] !== 'image') ? 
 
                             <div style={{'display': 'flex', 'alignItems': 'center'}} >
-                          
-                                <a href={SERVER_URL + item.file} download> 
+
+                                <a href={SERVER_URL + '/' +item.file} download> 
                                     <Button
                                         variant="contained" 
                                         component="label"
@@ -136,7 +154,7 @@ export const MessageForm = () => {
                         { 
                             (item.file && item.fileType && item.fileType.split('/')[0] == 'image' ) //need to fix for other type files
                             ? 
-                                <img width={'auto'} height={350} src={ SERVER_URL + item.file} alt={'error load image'}/>
+                                <img width={'auto'} style={{'maxWidth': "90%"}} src={ SERVER_URL + '/' + item.file} alt={'error load image'}/>
                             :
                             ''
                         }

+ 8 - 4
frontend/src/components/chatPage/userInfo/UserInfo.jsx

@@ -34,7 +34,7 @@ export const UserInfo = () => {
             setDisplayType('none')
         }, 4000)
     }
-    const SERVER_URL = process.env.REACT_APP_SERVER_URL|| 'http://192.168.0.107:5000/';
+    const SERVER_URL = process.env.REACT_APP_SERVER_URL
 
     const allUsers = useSelector(state => state.getUserSocketReducer.allUsers)
     const user = useSelector(state => state.getUserSocketReducer.socketUserData)
@@ -63,7 +63,7 @@ export const UserInfo = () => {
                 <Avatar
                     sx={isTabletorMobile ? MOBILE_AVATAR_STYLE : PC_AVATAR_STYLE} //add deleting function after update avatar
                     onClick={() => loadAvatarHandler()}
-                    src={userAvatarUrl ? SERVER_URL + userAvatarUrl : ""}
+                    src={userAvatarUrl ? SERVER_URL +'/'+ userAvatarUrl : ""}
                     >
                 </Avatar>  
                 
@@ -80,7 +80,9 @@ export const UserInfo = () => {
                         allUsers.map((item, key) =>
                             <div 
                                 key={item._id}
-                                className='online'>
+                                className='online'
+                                onClick={() => console.log(item.id)}
+                                >
                                 <div>
                                     {item.userName}
                                 </div>
@@ -137,7 +139,9 @@ export const UserInfo = () => {
                      !isTabletorMobile && usersOnline.map((item, i) =>
                         <div 
                             key={i}
-                            className='online'>  
+                            className='online'                        
+                            onClick={() => console.log(item.id)}
+>  
                                 <div style={{color: item.color}}>
                                     {item.userName}
                                 </div>

+ 23 - 23
frontend/src/reducers/messageReducer.js

@@ -8,11 +8,12 @@ const initialState = {
     editMessage: '',
     messageId: '', 
     files: [],
+    isLoading: false,
+    loadingPercentage: 0,
     ref: null
 }
 
-const POST_FILES_URL = 'http://192.168.0.107:5000/files';
-
+const POST_FILES_URL = process.env.REACT_APP_SERVER_URL+`/files`;
 
 export const sendMessageToSocket = (state, data) => {
              if (!!state.message && state.message.length < 200) {    //remove to other file
@@ -32,8 +33,9 @@ export const editMessageHandler = (state, data) => {
 };
 
 export const fileMessage = createAsyncThunk(
-    'messageReducer/fileMessage',
-    async (files) => {
+    'messageReducer/fileMessageStatus',
+    async (payload) => {
+        const {files, axiosConfig} = payload;
         const token = localStorage.getItem('token')
         try {
             const formData = new FormData();
@@ -45,22 +47,16 @@ export const fileMessage = createAsyncThunk(
                 formData.append('files', files)
             }
             formData.append('token', token)
-            const response = await axios.post(POST_FILES_URL, formData,
-                {
-                    headers: {
-                      "Content-type": "multipart/form-data",
-                    }
-                  });
+            const response = await axios.post(POST_FILES_URL, formData,axiosConfig);
             return await response;
             
         } catch (err) {
-            console.log('error messageReducer thunk', err)
+            console.log('Error messageReducer thunk', err)
                 return err?.message
             
             }
         })
 
-
         
 const messageReducerSlice = createSlice({
     name: 'messageReducer',
@@ -78,18 +74,22 @@ const messageReducerSlice = createSlice({
            
         },
         sendMessage: (state, action) => sendMessageToSocket(state, action.payload),
-        clearMessage: (state) => {state.message = ''},
-        extraReducers: (bilder) => 
-            bilder
-            .addCase(fileMessage.fulfilled, (state, action) => {
-                state.files = action.payload.data?.files
-                
-        })
-            .addCase(fileMessage.rejected, (state, action) => {
-                console.log('post file rejected', action.payload)
-        })
-        
+        clearMessage: (state) => {state.message = ''}
+
     },
+    extraReducers: (bilder) => {
+    bilder
+    .addCase(fileMessage.fulfilled, (state, action) => {
+        console.log('send', action)
+        state.files = action.payload.data?.files
+            
+    })  
+    .addCase(fileMessage.pending, (state, action) => {
+        console.log('pending', fileMessage.pending())
+    })
+    .addCase(fileMessage.rejected, (state, action) => {
+            console.log('post file rejected', action.payload)
+    })}
 });
 
 const {actions, reducer} = messageReducerSlice;

+ 2 - 9
frontend/src/reducers/socketReducer.js

@@ -16,11 +16,10 @@ const initialState = {
     newMessages : []
 }
 
+const SOCKET_URL = process.env.REACT_APP_SERVER_URL;
 
-const SOCKET_URL = 'http://192.168.0.107:5000'; 
 
 const connectToSocket = (event) => {
- 
         try {
             const token = localStorage.getItem('token');
             if(token){
@@ -94,12 +93,6 @@ export const getUserSocketSlice = createSlice({
         getUsersOnline: (state, action) => {state.usersOnline = action.payload},
         getAllUsers: (state, action) => {state.allUsers = action.payload},
         addNewMessage: (state, action) => {state.newMessages.push(action.payload)}, 
-
-        // writing: (state, action) => {
-        //                             state.writing = true;
-        //                             state.usersWriting.push(action.payload)                  
-        //     }
-        
         }
     }
 );
@@ -118,4 +111,4 @@ export const {
     addNewMessage,
     getAllUsers,
     writing
-} = actions;
+    } = actions;

+ 4 - 3
frontend/src/reducers/userDataReducer.js

@@ -15,15 +15,16 @@ const initialState = {
     showUserInfoBox: false,
     avatar: ''
 }
+const SERVER_URL =  process.env.REACT_APP_SERVER_URL
 
-const POST_URL =  process.env.REACT_APP_POST_URL || 'http://192.168.0.107:5000/login';
-const GET_AVATAR_URL =  process.env.REACT_APP_GET_AVATAR_URL || 'http://192.168.0.107:5000/avatar';
-
+const POST_URL =  process.env.REACT_APP_SERVER_URL + '/login';
+const GET_AVATAR_URL = process.env.REACT_APP_SERVER_URL +  '/avatar';
 
 export const getUserData = createAsyncThunk(
     'userData/getUser',
      ( t , thunkAPI) => {
       const userData = thunkAPI.getState().userDataReducer;
+      console.log(POST_URL)
         if(userData.userName){
             if(isValidPayload({...userData}) && isValidUserName({...userData}))
                 try {

+ 62 - 61
frontend/src/service-worker.js

@@ -1,72 +1,73 @@
-// /* eslint-disable no-restricted-globals */
 
-// // This service worker can be customized!
-// // See https://developers.google.com/web/tools/workbox/modules
-// // for the list of available Workbox modules, or add any other
-// // code you'd like.
-// // You can also remove this file if you'd prefer not to use a
-// // service worker, and the Workbox build step will be skipped.
+/* eslint-disable no-restricted-globals */
 
-// import { clientsClaim } from 'workbox-core';
-// import { ExpirationPlugin } from 'workbox-expiration';
-// import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching';
-// import { registerRoute } from 'workbox-routing';
-// import { StaleWhileRevalidate } from 'workbox-strategies';
+// This service worker can be customized!
+// See https://developers.google.com/web/tools/workbox/modules
+// for the list of available Workbox modules, or add any other
+// code you'd like.
+// You can also remove this file if you'd prefer not to use a
+// service worker, and the Workbox build step will be skipped.
 
-// clientsClaim();
+import { clientsClaim } from 'workbox-core';
+import { ExpirationPlugin } from 'workbox-expiration';
+import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching';
+import { registerRoute } from 'workbox-routing';
+import { StaleWhileRevalidate } from 'workbox-strategies';
 
-// // Precache all of the assets generated by your build process.
-// // Their URLs are injected into the manifest variable below.
-// // This variable must be present somewhere in your service worker file,
-// // even if you decide not to use precaching. See https://cra.link/PWA
-// precacheAndRoute(self.__WB_MANIFEST);
+clientsClaim();
 
-// // Set up App Shell-style routing, so that all navigation requests
-// // are fulfilled with your index.html shell. Learn more at
-// // https://developers.google.com/web/fundamentals/architecture/app-shell
-// const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
-// registerRoute(
-//   // Return false to exempt requests from being fulfilled by index.html.
-//   ({ request, url }) => {
-//     // If this isn't a navigation, skip.
-//     if (request.mode !== 'navigate') {
-//       return false;
-//     } // If this is a URL that starts with /_, skip.
+// Precache all of the assets generated by your build process.
+// Their URLs are injected into the manifest variable below.
+// This variable must be present somewhere in your service worker file,
+// even if you decide not to use precaching. See https://cra.link/PWA
+precacheAndRoute(self.__WB_MANIFEST);
 
-//     if (url.pathname.startsWith('/_')) {
-//       return false;
-//     } // If this looks like a URL for a resource, because it contains // a file extension, skip.
+// Set up App Shell-style routing, so that all navigation requests
+// are fulfilled with your index.html shell. Learn more at
+// https://developers.google.com/web/fundamentals/architecture/app-shell
+const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
+registerRoute(
+  // Return false to exempt requests from being fulfilled by index.html.
+  ({ request, url }) => {
+    // If this isn't a navigation, skip.
+    if (request.mode !== 'navigate') {
+      return false;
+    } // If this is a URL that starts with /_, skip.
 
-//     if (url.pathname.match(fileExtensionRegexp)) {
-//       return false;
-//     } // Return true to signal that we want to use the handler.
+    if (url.pathname.startsWith('/_')) {
+      return false;
+    } // If this looks like a URL for a resource, because it contains // a file extension, skip.
 
-//     return true;
-//   },
-//   createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')
-// );
+    if (url.pathname.match(fileExtensionRegexp)) {
+      return false;
+    } // Return true to signal that we want to use the handler.
 
-// // An example runtime caching route for requests that aren't handled by the
-// // precache, in this case same-origin .png requests like those from in public/
-// registerRoute(
-//   // Add in any other file extensions or routing criteria as needed.
-//   ({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), // Customize this strategy as needed, e.g., by changing to CacheFirst.
-//   new StaleWhileRevalidate({
-//     cacheName: 'images',
-//     plugins: [
-//       // Ensure that once this runtime cache reaches a maximum size the
-//       // least-recently used images are removed.
-//       new ExpirationPlugin({ maxEntries: 50 }),
-//     ],
-//   })
-// );
+    return true;
+  },
+  createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')
+);
 
-// // This allows the web app to trigger skipWaiting via
-// // registration.waiting.postMessage({type: 'SKIP_WAITING'})
-// self.addEventListener('message', (event) => {
-//   if (event.data && event.data.type === 'SKIP_WAITING') {
-//     self.skipWaiting();
-//   }
-// });
+// An example runtime caching route for requests that aren't handled by the
+// precache, in this case same-origin .png requests like those from in public/
+registerRoute(
+  // Add in any other file extensions or routing criteria as needed.
+  ({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), // Customize this strategy as needed, e.g., by changing to CacheFirst.
+  new StaleWhileRevalidate({
+    cacheName: 'images',
+    plugins: [
+      // Ensure that once this runtime cache reaches a maximum size the
+      // least-recently used images are removed.
+      new ExpirationPlugin({ maxEntries: 50 }),
+    ],
+  })
+);
 
-// // Any other custom service worker logic can go here.
+// This allows the web app to trigger skipWaiting via
+// registration.waiting.postMessage({type: 'SKIP_WAITING'})
+self.addEventListener('message', (event) => {
+  if (event.data && event.data.type === 'SKIP_WAITING') {
+    self.skipWaiting();
+  }
+});
+
+// Any other custom service worker logic can go here.

+ 25 - 37
frontend/src/serviceWorkerRegistration.js

@@ -9,21 +9,23 @@
 
 // To learn more about the benefits of this model and instructions on how to
 // opt-in, read https://cra.link/PWA
-const isLocalhost = Boolean(
-  window.location.hostname === 'localhost' ||
-    window.location.hostname === '192.168.0.107' ||
-      // [::1] is the IPv6 localhost address.
-      window.location.hostname === '[::1]' ||
-      // 127.0.0.0/8 are considered localhost for IPv4.
-      window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
-  );
-  
+const isLocalhost = true
 
+// Boolean(
+//   window.location.hostname === 'localhost' ||
+//     window.location.hostname === '192.168.0.109' ||
+//       // [::1] is the IPv6 localhost address.
+//       window.location.hostname === '[::1]' ||
+//       // 127.0.0.0/8 are considered localhost for IPv4.
+//       window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
+//   );
+console.log('start sw...')
   export function register(config) {
-    console.log('registering..', navigator)
     if ('serviceWorker' in navigator) {
+      console.log('registering..')
       // The URL constructor is available in all browsers that support SW.
       const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
+      console.log(publicUrl)
       if (publicUrl.origin !== window.location.origin) {
         // Our service worker won't work if PUBLIC_URL is on a different origin
         // from what our page is served on. This might happen if a CDN is used to
@@ -34,22 +36,7 @@ const isLocalhost = Boolean(
       window.addEventListener('load', () => {
         const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
         console.log(swUrl, config)
-        if (isLocalhost) {
-          // This is running on localhost. Let's check if a service worker still exists or not.
-          checkValidServiceWorker(swUrl, config);
-  
-          // Add some additional logging to localhost, pointing developers to the
-          // service worker/PWA documentation.
-          navigator.serviceWorker.ready.then(() => {
-            console.log(
-              'This web app is being served cache-first by a service ' +
-                'worker. To learn more, visit https://cra.link/PWA'
-            );
-          });
-        } else {
-          // Is not localhost. Just register service worker
-          registerValidSW(swUrl, config);
-        }
+        registerValidSW(swUrl, config);
       });
     }
   }
@@ -58,6 +45,7 @@ const isLocalhost = Boolean(
     navigator.serviceWorker
       .register(swUrl)
       .then((registration) => {
+        console.log('registration...')
         registration.onupdatefound = () => {
           const installingWorker = registration.installing;
           if (installingWorker == null) {
@@ -126,14 +114,14 @@ const isLocalhost = Boolean(
       });
   }
   
-  export function unregister() {
-    if ('serviceWorker' in navigator) {
-      navigator.serviceWorker.ready
-        .then((registration) => {
-          registration.unregister();
-        })
-        .catch((error) => {
-          console.error(error.message);
-        });
-    }
-  }
+  // export function unregister() {
+  //   if ('serviceWorker' in navigator) {
+  //     navigator.serviceWorker.ready
+  //       .then((registration) => {
+  //         registration.unregister();
+  //       })
+  //       .catch((error) => {
+  //         console.error(error.message);
+  //       });
+  //   }
+  // }