Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
"@phosphor-icons/react": "2.0.10",
"@reduxjs/toolkit": "1.9.5",
"axios": "1.4.0",
"classnames": "^2.3.2",
"clsx": "1.2.1",
"dotenv": "16.0.2",
"react": "18.2.0",
Expand Down Expand Up @@ -60,7 +59,8 @@
"stylelint-config-standard-scss": "9.0.0",
"ts-jest": "28.0.8",
"typescript": "5.1.3",
"vite": "3.0.7"
"vite": "3.0.7",
"vite-plugin-pwa": "0.16.4"
},
"license": "MIT"
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { SVGType } from '@typings/SVG';
import { useGetCSSVars } from '@lib/useGetCSSVars';

export const AvatarSVG: React.FC<SVGType> = ({ width, color }) => {
const currentColor = useGetCSSVars('color', color);
const currentColor = useGetCSSVars('color', color || '');
return (
<>
<svg width={width} height={width} viewBox="0 0 64 65" fill="none" xmlns="http://www.w3.org/2000/svg">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,28 @@ import { Button } from '@components/design-system';
import { BodyNormal } from '@components/design-system/Fonts';

export const ForumCreateForm: React.FC = () => {

const [topic, setTopic] = useState("");
const [topic, setTopic] = useState('');
const [description, setDesc] = useState('');
const createTopic = (e: React.ChangeEvent<HTMLFormElement>) => {
e.preventDefault();
setTopic("");
setTopic('');
createDescription(e);
}
};
const createDescription = (e: React.ChangeEvent<HTMLFormElement>) => {
e.preventDefault();
setDesc("");
}
setDesc('');
};
return (
<form className={ styles.topic__form } onSubmit={ createTopic }>
<div className={ styles.topic__container }>
<form className={styles.topic__form} onSubmit={createTopic}>
<div className={styles.topic__container}>
<label>Название</label>
<input
type='text'
name='topic'
required value={ topic }
onChange={ (e) => setTopic(e.target.value) }
/>
<input type="text" name="topic" required value={topic} onChange={(e) => setTopic(e.target.value)} />
<label>Описание</label>
<textarea
name='description'
required value={ description }
onChange={ (e) => setDesc(e.target.value) }
/>
<textarea name="description" required value={description} onChange={(e) => setDesc(e.target.value)} />
</div>
<Button className={ styles.topic_btn__create } type="submit">
<BodyNormal weight={ 'normal' }>Создать</BodyNormal>
<Button className={styles.topic_btn__create} type="submit">
<BodyNormal weight={'normal'}>Создать</BodyNormal>
</Button>
</form>
)
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { Header } from './components/header';
import { Content } from './components/content';
import { Footer } from './components/footer';

export const ForumComments:React.FC = () => {
export const ForumComments: React.FC = () => {
return (
<ForumLayout>
<div className={ styles.wrapper }>
<div className={styles.wrapper}>
<Header />
<Content />
<Footer />
</div>
</ForumLayout>
)
}
);
};
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import React, { useState } from 'react'
import styles from './Footer.module.scss'
import { Title } from '@components/design-system/Fonts'
import { Button } from '@components/design-system'
import React, { useState } from 'react';
import styles from './Footer.module.scss';
import { Title } from '@components/design-system/Fonts';
import { Button } from '@components/design-system';

export const Footer: React.FC = () => {
const [comment, setComment] = useState<string>('');

export const Footer:React.FC = () => {
const { comment, setComment } = useState('');
return (
<div className={ styles.comment__footer }>
<Title className={ styles.comment_add__title }>Оставить комментарий</Title>
<form className={ styles.comment_add__form }>
<textarea className={ styles.comment__textaria }
name='comment'
required value={ comment }
onChange={ (e) => setComment(e.target.value) }
>
</textarea>
<Button className={ styles.comment_add__btn }>Добавить</Button>
<div className={styles.comment__footer}>
<Title className={styles.comment_add__title}>Оставить комментарий</Title>
<form className={styles.comment_add__form}>
<textarea
className={styles.comment__textaria}
name="comment"
required
value={comment}
onChange={(e) => setComment(e.target.value)}
></textarea>
<Button className={styles.comment_add__btn}>Добавить</Button>
</form>
</div>
);
}
};
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
import React, { useState } from 'react'
import styles from './FullScreen.module.scss'
import classNames from 'classnames'
import React, { useState } from 'react';
import clsx from 'clsx';
import styles from './FullScreen.module.scss';

export const FullScreen: React.FC = () => {
const [isFullscreeen, setFullscreen] = useState(false)
const [isFullscreeen, setFullscreen] = useState(false);

async function eventHandler(event: React.MouseEvent<HTMLDivElement | HTMLButtonElement>) {
if (document.fullscreenElement) {
try {
await document.exitFullscreen()
setFullscreen(false)
await document.exitFullscreen();
setFullscreen(false);
} catch (err) {
throw new Error()
throw new Error();
}
} else {
try {
await document.documentElement.requestFullscreen()
setFullscreen(true)
await document.documentElement.requestFullscreen();
setFullscreen(true);
} catch (err) {
throw new Error()
throw new Error();
}
}
}
return (
<button className={classNames(styles.iconFullScreen, {
[styles.fullScreenActive]: isFullscreeen
})} type='submit' id='toggler' onClick={(e) => eventHandler(e)}></button>
)
}
<button
className={clsx(styles.iconFullScreen, {
[styles.fullScreenActive]: isFullscreeen,
})}
type="submit"
id="toggler"
onClick={(e) => eventHandler(e)}
></button>
);
};
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';
import { TopicsItem } from '../TopicItem'
import { TopicsItem } from '../TopicItem';

export const TopicElements = () => {
const topicsData = [
{ id:1, title: 'Какие игры сейчас популярны', desc: 'Dota, CS, CS:GO', timestamp: '10 янв 2023' },
{ id:2, title: 'Го играть', desc: 'Я бы сыграл в денди', timestamp: '30 июня 2023' },
{ id:3, title: 'Я доделал форум)', desc: 'Почти в дед лайн =)', timestamp: '01 июля 2023' },
{ id: '1', title: 'Какие игры сейчас популярны', desc: 'Dota, CS, CS:GO', timestamp: '10 янв 2023' },
{ id: '2', title: 'Го играть', desc: 'Я бы сыграл в денди', timestamp: '30 июня 2023' },
{ id: '3', title: 'Я доделал форум)', desc: 'Почти в дед лайн =)', timestamp: '01 июля 2023' },
];
return topicsData.map( element => <TopicsItem topics ={ element }/>)
return topicsData.map((element) => <TopicsItem topics={element} />);
};
3 changes: 3 additions & 0 deletions packages/client/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@ import './styles/index.scss';

import App from './App';
import ReactDOM from 'react-dom/client';
import { startServiceWorker } from '@utils/sw/startServiceWorker';

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(<App />);

startServiceWorker();
15 changes: 15 additions & 0 deletions packages/client/src/utils/sw/startServiceWorker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export function startServiceWorker() {
if ('serviceWorker' in navigator) {
window.addEventListener('load', async () => {
const sw = '/src/utils/sw/sw.ts';

try {
const registration = await navigator.serviceWorker.register(sw);

console.log('ServiceWorker registration successful with scope: ', registration.scope);
} catch (error) {
console.log('ServiceWorker registration failed: ', error);
}
});
}
}
108 changes: 108 additions & 0 deletions packages/client/src/utils/sw/sw.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/// <reference lib="webworker" />

const sw = self as unknown as ServiceWorkerGlobalScope & typeof globalThis;

const staticCacheName = 'static-cache-v1';
const dynamicCacheName = 'dynamic-cache-v1';

const assetUrls = [
'/',
'/index.html',
'/src/index.tsx',
'/src/styles/index.scss',
'/src/styles/images/casper.png',
'/src/styles/images/add_msg.png',
'/src/styles/images/auth.png',
'/src/styles/images/error.png',
'/src/styles/images/forum-left-side.svg',
'/src/styles/images/forum.svg',
'/src/styles/images/fullscreen-close.png',
'/src/styles/images/fullscreen-open.png',
'/src/styles/images/fullscreen.png',
'/src/styles/images/Hipe.svg',
'/src/styles/images/leader.svg',
'/src/styles/images/leaders.svg',
'/src/styles/images/leaderVector.png',
'/src/styles/images/like.png',
'/src/styles/images/profile.svg',
'/src/styles/images/progress-bg-pic.svg',
'/src/styles/images/progress-pic.svg',
'/src/styles/images/progress.svg',
'/src/styles/images/start.svg',
'/src/styles/fonts/HeliosExt-Bold.ttf',
'/src/styles/fonts/HeliosExt.ttf',
'/src/styles/fonts/Roboto-Bold.eot',
'/src/styles/fonts/Roboto-Bold.ttf',
'/src/styles/fonts/Roboto-Bold.woff',
'/src/styles/fonts/Roboto-Bold.woff2',
'/src/styles/fonts/Roboto-Regular.eot',
'/src/styles/fonts/Roboto-Regular.ttf',
'/src/styles/fonts/Roboto-Regular.woff',
'/src/styles/fonts/Roboto-Regular.woff2',
];

sw.addEventListener('install', (event) => {
event.waitUntil(addResourcesToCache(assetUrls));
});

sw.addEventListener('activate', async (event) => {
try {
const cacheNames = await caches.keys();

await Promise.all(
cacheNames
.filter((name) => name !== staticCacheName)
.filter((name) => name !== dynamicCacheName)
.map((name) => caches.delete(name))
);
} catch (error) {
console.log(error);
}
});

sw.addEventListener('fetch', (event) => {
const { request } = event;

const url = new URL(request.url);

if (url.origin === location.origin) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Рекомендация: при использовании if стараться оставлять структуру без ветвлений

if () {
  ...
  
  return
}

// else

event.respondWith(cacheFirst(request));
return;
}

// @ts-expect-error - response might be undefined
event.respondWith(networkFirst(request));
});

async function addResourcesToCache(resources: string[]) {
try {
const cache = await caches.open(staticCacheName);
await cache.addAll(resources);
} catch (error) {
console.log(error);
}
}

async function cacheFirst(request: Request) {
const cached = await caches.match(request);

return cached ?? (await fetch(request));
}

async function networkFirst(request: Request) {
const cache = await caches.open(dynamicCacheName);

try {
const response = await fetch(request);

await cache.put(request, response.clone());

return response;
} catch (error) {
console.log(error);

const cached = await caches.match(request);

return cached;
}
}
13 changes: 13 additions & 0 deletions packages/client/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { defineConfig } from 'vite';
import dotenv from 'dotenv';
import react from '@vitejs/plugin-react';
import viteTsconfigPaths from 'vite-tsconfig-paths';
import { VitePWA } from 'vite-plugin-pwa';
dotenv.config();

// https://vitejs.dev/config/
Expand All @@ -17,6 +18,18 @@ export default defineConfig({
react({
jsxRuntime: 'classic', // Add this line
}),
VitePWA({ registerType: 'autoUpdate' }),
viteTsconfigPaths(),
],
build: {
rollupOptions: {
input: {
app: './index.html',
'service-worker': './src/utils/sw/sw.ts',
},
output: {
entryFileNames: (asset) => (asset.name === 'service-worker' ? '[name].js' : 'assets/[name].[hash].js'),
},
},
},
});