diff --git a/package-lock.json b/package-lock.json
index 937a670..31f6bb0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1216,6 +1216,11 @@
"loader-utils": "^1.1.0"
}
},
+ "@types/classnames": {
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.8.tgz",
+ "integrity": "sha512-3UrLzPnz8u+MMXuJTF++389IfLSQUbl5F3ry9WCxva0BKG5H/oo5NuPRXk+HrpPU1+5pVHSWhnVWRzIaFQ7QuQ=="
+ },
"@types/events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
@@ -1251,12 +1256,34 @@
"integrity": "sha512-/OMMBnjVtDuwX1tg2pkYVSqRIDSmNTnvVvmvP/2xiMAAWf4a5+JozrApCrO4WCAILmXVxfNoQ3E+0HJbNpFVGg==",
"dev": true
},
+ "@types/prop-types": {
+ "version": "15.7.1",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.1.tgz",
+ "integrity": "sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg=="
+ },
"@types/q": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==",
"dev": true
},
+ "@types/react": {
+ "version": "16.8.22",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.22.tgz",
+ "integrity": "sha512-C3O1yVqk4sUXqWyx0wlys76eQfhrQhiDhDlHBrjER76lR2S2Agiid/KpOU9oCqj1dISStscz7xXz1Cg8+sCQeA==",
+ "requires": {
+ "@types/prop-types": "*",
+ "csstype": "^2.2.0"
+ }
+ },
+ "@types/react-dom": {
+ "version": "16.8.4",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.8.4.tgz",
+ "integrity": "sha512-eIRpEW73DCzPIMaNBDP5pPIpK1KXyZwNgfxiVagb5iGiz6da+9A5hslSX6GAQKdO7SayVCS/Fr2kjqprgAvkfA==",
+ "requires": {
+ "@types/react": "*"
+ }
+ },
"@types/tapable": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.2.tgz",
@@ -4085,6 +4112,11 @@
}
}
},
+ "classnames": {
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
+ "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
+ },
"clean-css": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
@@ -4890,6 +4922,11 @@
"cssom": "0.3.x"
}
},
+ "csstype": {
+ "version": "2.6.5",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.5.tgz",
+ "integrity": "sha512-JsTaiksRsel5n7XwqPAfB0l3TFKdpjW/kgAELf9vrb5adGA7UCPLajKK5s3nFrcFm3Rkyp/Qkgl73ENc1UY3cA=="
+ },
"currently-unhandled": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
@@ -7306,8 +7343,7 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"aproba": {
"version": "1.2.0",
@@ -7350,8 +7386,7 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"concat-map": {
"version": "0.0.1",
@@ -7362,8 +7397,7 @@
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"core-util-is": {
"version": "1.0.2",
@@ -7480,8 +7514,7 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"ini": {
"version": "1.3.5",
@@ -7493,7 +7526,6 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -7508,7 +7540,6 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -7516,14 +7547,12 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"minipass": {
"version": "2.2.4",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
@@ -7542,7 +7571,6 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -7623,8 +7651,7 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"object-assign": {
"version": "4.1.1",
@@ -7636,7 +7663,6 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"wrappy": "1"
}
@@ -7722,8 +7748,7 @@
"safe-buffer": {
"version": "5.1.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -7759,7 +7784,6 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -7779,7 +7803,6 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -7823,14 +7846,12 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"yallist": {
"version": "3.0.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
diff --git a/package.json b/package.json
index 9ede333..9a6d3ea 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,10 @@
"not op_mini all"
],
"dependencies": {
+ "@types/classnames": "2.2.8",
+ "@types/react": "16.8.22",
+ "@types/react-dom": "16.8.4",
+ "classnames": "2.2.6",
"react": "16.8.6",
"react-dom": "16.8.6"
},
diff --git a/src/app/app.css b/src/app/app.css
index 1c4d511..1afd019 100644
--- a/src/app/app.css
+++ b/src/app/app.css
@@ -1,27 +1,18 @@
-.app {
- text-align: center;
+body {
+ height: 600px;
+ background-color: #e5eaf0;
+ margin: 0;
+ /*background-color: black;*/
}
-.app-header {
- display: flex;
- min-height: 100vh;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- background-color: #282c34;
- color: #fff;
- font-size: calc(10px + 2vmin);
-}
-
-.app-link {
- color: #61dafb;
-}
-
-@keyframes app-logo-spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
-}
+/*@font-face {*/
+/* font-family: 'HelveticaNeueCyr-Medium';*/
+/* src: url('./src/sourse/fonts/HelveticaNeueCyr-Medium.eot');*/
+/* src: url('sourse/fonts/HelveticaNeueCyr-Medium.eot?#iefix') format('embedded-opentype'),*/
+/* url('./sourse/fonts/HelveticaNeueCyr-Medium.svg#HelveticaNeueCyr-Medium') format('svg'),*/
+/* url('./sourse/fonts/HelveticaNeueCyr-Medium.ttf') format('truetype'),*/
+/* url('./sourse/fonts/HelveticaNeueCyr-Medium.woff') format('woff'),*/
+/* url('./sourse/fonts/HelveticaNeueCyr-Medium.woff2') format('woff2');*/
+/* font-weight: normal;*/
+/* font-style: normal;*/
+/*}*/
diff --git a/src/app/app.jsx b/src/app/app.jsx
index f759eed..b2a7225 100644
--- a/src/app/app.jsx
+++ b/src/app/app.jsx
@@ -1,24 +1,13 @@
import React, { Component } from 'react';
import './app.css';
+import { Main } from '../main/Main';
export class App extends Component {
render() {
return (
);
}
diff --git a/src/article/Article.module.css b/src/article/Article.module.css
new file mode 100644
index 0000000..dbc1994
--- /dev/null
+++ b/src/article/Article.module.css
@@ -0,0 +1,19 @@
+.article {
+ /*background: url("../../../src/background.jpg");*/
+ background-attachment: fixed;
+ background-size: 15%;
+ /*background-repeat: space;*/
+ /*background-color: #FFFFDD;*/
+ margin-left: -40px;
+ height: inherit;
+}
+
+.articleCancelSign {
+ float: right;
+ margin-top: 20px;
+ margin-right: 20px;
+}
+
+.inp {
+ display: none;
+}
diff --git a/src/article/Article.tsx b/src/article/Article.tsx
new file mode 100644
index 0000000..96c900e
--- /dev/null
+++ b/src/article/Article.tsx
@@ -0,0 +1,27 @@
+import React, { Component } from 'react';
+import styles from './Article.module.css';
+
+interface IProps {
+ id: string;
+ openLetters: () => void;
+ letterText: string;
+}
+
+export class Article extends Component {
+ public render() {
+ return (
+
+
this.props.openLetters()}
+ />
+
+
+ {this.props.letterText}
+
+
+ );
+ }
+}
diff --git a/src/functions/Functions.tsx b/src/functions/Functions.tsx
new file mode 100644
index 0000000..9f071e3
--- /dev/null
+++ b/src/functions/Functions.tsx
@@ -0,0 +1,52 @@
+const senders = ['Mom', 'Dad', 'Cat', 'Dog', 'Apple', 'Teacher', 'Homie', 'Mole',
+ 'Hare', 'BB-8', 'Porg', 'Totoro'];
+
+const actions = ['runs', 'waits', 'flies', 'sleeps', 'lays', 'jumps', 'sings',
+ 'writes', 'reads', 'executes', 'exists', 'builds', 'tests'];
+
+const adverbs = ['rapidly', 'at home', 'at school', 'at the university', 'on bed',
+ 'highly', 'alone', 'sadly', 'today'];
+
+const punctuationMarks = ['.', '...', '!', '?', '?!'];
+
+export function getRandomFromRange(minTime: number, maxTime: number) {
+ return Math.random() * (maxTime - minTime) + minTime;
+}
+
+function getRandomInt(minRange: number, maxRange: number) {
+ return Math.trunc(getRandomFromRange(minRange, maxRange));
+}
+
+function genColor() {
+ const n = getRandomInt(0, 255);
+ let res = n.toString(16);
+ while (res.length < 2) {
+ res = `0${res}`;
+ }
+ return res;
+}
+
+export function genLetterText() {
+ const letterLen = getRandomInt(0, 10);
+ let answer = '';
+ for (let i = 0; i < letterLen; i++) {
+ const send = senders[getRandomInt(0, senders.length)];
+ const act = actions[getRandomInt(0, actions.length)];
+ const adv = adverbs[getRandomInt(0, adverbs.length)];
+ const punMark = punctuationMarks[getRandomInt(0, punctuationMarks.length)];
+ answer += `${send} ${act} ${adv}${punMark} `;
+ }
+ const curDate = new Date();
+ const letterDate = `${curDate.getDate()} ${curDate.toLocaleString('ru', { month: 'short' })}`;
+ const senderOne = senders[getRandomInt(0, senders.length)];
+ const colorLetter = `#${genColor()}${genColor()}${genColor()}`;
+ return {
+ deleted: false,
+ letterText: answer,
+ sender: senderOne,
+ date: letterDate,
+ color: colorLetter,
+ chose: false,
+ isVisible: true
+ };
+}
diff --git a/src/header/Header.module.css b/src/header/Header.module.css
new file mode 100644
index 0000000..1333a83
--- /dev/null
+++ b/src/header/Header.module.css
@@ -0,0 +1,61 @@
+.beforeLines {
+ height: 19px;
+ margin-top: 11px;
+ margin-left: 22px;
+}
+
+.oneLine {
+ width: 20px;
+ height: 2px;
+ margin-top: 4px;
+ background-color: #000000;
+}
+
+.darkSide {
+ background-color: #ffffff;
+}
+
+.search {
+ background-color: #ffffff;
+ width: 301px;
+ height: 32px;
+ margin-top: 11px;
+ margin-left: 114px;
+ line-height: 100%;
+}
+
+.searchCancelSign {
+ float: right;
+ background-color: inherit;
+ border: none;
+ padding-right: 15px;
+ margin-top: -25px;
+ /*opacity: 0.15;*/
+}
+
+.searchWord {
+ border: none;
+ display: inline-block;
+ padding-left: 16px;
+ box-sizing: border-box;
+ width: 100%;
+ height: 100%;
+ opacity: 0.5;
+ font-size: 15px;
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
+}
+
+.yandexMail_picture {
+ margin-left: 11px;
+ margin-top: 10px;
+}
+
+.yandexMail_unstressedLink {
+ color: inherit;
+ text-decoration: none;
+}
+
+.highPart {
+ display: inline-block;
+ vertical-align: middle;
+}
diff --git a/src/header/Header.tsx b/src/header/Header.tsx
new file mode 100644
index 0000000..9d775ad
--- /dev/null
+++ b/src/header/Header.tsx
@@ -0,0 +1,65 @@
+import React, { Component } from 'react';
+import cn from 'classnames';
+
+import stylesMain from '../main/Main.module.css';
+import styles from './Header.module.css';
+import logo from '../sourse/YandexMail.png';
+import darkLogo from '../sourse/YandexMail-dark.png';
+
+interface IProps {
+ searchLetters: (a: string) => void;
+ isDark: boolean;
+}
+
+export class Header extends Component {
+ public render() {
+ const { searchLetters, isDark } = this.props;
+ const darkClass = cn({ [stylesMain.blackSide]: isDark });
+ const oneLineDark = cn(styles.oneLine, {
+ [styles.darkSide]: isDark
+ });
+ const searchDark = cn(styles.highPart, styles.search);
+ const searchWordDark = cn(styles.searchWord, {
+ [stylesMain.blackSide]: isDark
+ });
+ const highBefore = cn(styles.highPart, styles.beforeLines);
+ let actualLogo;
+ if (isDark) {
+ actualLogo = darkLogo;
+ } else {
+ actualLogo = logo;
+ }
+
+ return (
+
+ );
+ }
+}
diff --git a/src/index.css b/src/index.css
index 2b6e525..c7a0a15 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,12 +1,12 @@
-body {
- padding: 0;
- margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
- 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-code {
- font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
+@font-face {
+ font-family: 'HelveticaNeueCyr-Medium';
+ src: url('./sourse/fonts/HelveticaNeueCyr-Medium.eot');
+ src: url('./sourse/fonts/HelveticaNeueCyr-Medium.eot?#iefix') format('embedded-opentype'),
+ url('././sourse/fonts/HelveticaNeueCyr-Medium.svg#HelveticaNeueCyr-Medium') format('svg'),
+ url('././sourse/fonts/HelveticaNeueCyr-Medium.ttf') format('truetype'),
+ url('././sourse/fonts/HelveticaNeueCyr-Medium.woff') format('woff'),
+ url('././sourse/fonts/HelveticaNeueCyr-Medium.woff2') format('woff2');
+ font-weight: normal;
+ font-style: normal;
}
diff --git a/src/index.jsx b/src/index.jsx
index ffc72ee..d329b29 100644
--- a/src/index.jsx
+++ b/src/index.jsx
@@ -1,8 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
-
import { App } from './app';
-
import './index.css';
ReactDOM.render(, document.getElementById('root'));
diff --git a/src/letter/ILetter.ts b/src/letter/ILetter.ts
new file mode 100644
index 0000000..f09b9d5
--- /dev/null
+++ b/src/letter/ILetter.ts
@@ -0,0 +1,11 @@
+export interface ILetter {
+ deleted: boolean;
+ letterText: string;
+ sender: string;
+ date: string;
+ color: string;
+ chose: boolean;
+ isVisible: boolean;
+ classS: string;
+ id: number;
+}
diff --git a/src/letter/Letter.module.css b/src/letter/Letter.module.css
new file mode 100644
index 0000000..8ddc1df
--- /dev/null
+++ b/src/letter/Letter.module.css
@@ -0,0 +1,193 @@
+.letter_add {
+ margin-top: 0px;
+ margin-left: -40px;
+ position: relative;
+ z-index: 1;
+ list-style-type: none;
+ transition-duration: 1s;
+ transition-property: margin-top;
+ transition-delay: 0s;
+ transition-timing-function: linear;
+}
+
+.letter_delete {
+ margin-top: -50.36px;
+ z-index: 0;
+ margin-left: -40px;
+ position: relative;
+ transition-duration: 1s;
+ transition-property: margin-top;
+ transition-delay: 0s;
+ transition-timing-function: linear;
+}
+
+.letter_notNew {
+ margin-top: 0;
+ margin-left: -40px;
+ position: relative;
+ z-index: 1;
+}
+
+.letter {
+ margin-top: -50.36px;
+ margin-left: -40px;
+ position: relative;
+ z-index: 1;
+ list-style-type: none;
+}
+
+.letterDate {
+ float: right;
+ margin-right: 20px;
+ font-family: HelveticaNeueCyr-Medium;
+ font-size: 13px;
+ line-height: 28px;
+ text-align: right;
+ color: #9b9b9b;
+ /* margin-top: -30px; */
+}
+
+.letterInnerior {
+ margin: 0;
+ /*width: 900px;*/
+ border-style: solid;
+ border-color: #9b9b9b;
+ border-width: 0 0 0.5px 0;
+ height: 50px;
+ list-style-type: none;
+ background-color: #ffffff;
+}
+
+.letterPart {
+ display: inline-block;
+ vertical-align: middle;
+ margin-bottom: 0px;
+ margin-top: 10px;
+}
+
+.letterSender_pict_wrap {
+ margin-left: 10px;
+ width: 30px;
+ height: 30px;
+ border-radius: 50%;
+ font-size: 25px;
+ font-family: HelveticaNeueCyr-Medium;
+ color: white;
+}
+
+.letterSender_pict {
+ width: inherit;
+ height: inherit;
+ border-radius: 50%;
+ text-align: center;
+}
+
+.letterSender {
+ margin-left: 10px;
+ width: 130px;
+ height: 16px;
+ font-family: HelveticaNeueCyr-Medium;
+ font-size: 13px;
+ font-weight: bold;
+ /*color: #000000;*/
+ overflow: hidden;
+}
+
+.letterText {
+ margin-left: 10px;
+ /* width: 300px; */
+ width: calc(100% - 300px);
+ height: 16px;
+ font-family: HelveticaNeueCyr-Medium;
+ font-size: 13px;
+ font-weight: bold;
+ /*color: #000000;*/
+ overflow: hidden;
+}
+
+.letterUnreadPoint {
+ margin-left: 20px;
+ width: 10px;
+ height: 10px;
+ border-radius: 50%;
+ background-color: #6287bd;
+}
+
+.lettersList {
+ overflow: auto;
+ min-height: 475px;
+ max-height: 475px;
+ margin-block-start: 0;
+ margin-block-end: 0;
+ list-style-type: none;
+}
+
+.selectButton {
+ position: relative;
+ margin-top: -20px;
+ width: 16px;
+ height: 16px;
+ border-radius: 3px;
+ border: solid 1px rgba(0, 0, 0, 0.15);
+ background-color: #ffffff;
+ /*background-color: black;*/
+}
+
+.selectButton:after {
+ margin: -3px 0 0 4px;
+ width: 7px;
+ height: 14px;
+ content: '';
+ position: absolute;
+ border-right: 2px solid;
+ border-bottom: 2px solid;
+ color: #000000;
+ -webkit-transform: scale(0.85) rotate(47deg) skewX(12deg);
+ transform: scale(0.85) rotate(47deg) skewX(12deg);
+ visibility: hidden;
+}
+
+.squareForButton {
+ margin-left: -25px;
+ width: 16px;
+ height: 16px;
+ margin-block-start: 8px;
+ margin-block-end: 0;
+}
+
+.windowLetters {
+ display: inline-block;
+ vertical-align: top;
+ margin: 13px 20px 14px 22px;
+ width: calc(100% - 215px);
+ min-width: 50px;
+ height: 580px;
+ max-height: 1530px;
+ /*max-height: 612px;*/
+ /*overflow: none;*/
+ border-radius: 3px;
+ border-color: #e5eaf0;
+ border-width: 0.5px;
+ border-style: solid;
+ box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.34);
+ background-color: #ffffff;
+ box-sizing: border-box;
+}
+
+.inputButton:checked + .selectButton:after {
+ visibility: inherit;
+}
+
+#label_openArt {
+ display: none;
+}
+
+.not_show {
+ display: none;
+}
+
+.darkSide {
+ background-color: black;
+ border-left-color: #e5eaf0;
+ border-left-width: 0.5px;
+}
diff --git a/src/letter/Letter.tsx b/src/letter/Letter.tsx
new file mode 100644
index 0000000..47c304d
--- /dev/null
+++ b/src/letter/Letter.tsx
@@ -0,0 +1,92 @@
+import React, { Component, RefObject } from 'react';
+import cn from 'classnames';
+import styles from './Letter.module.css';
+
+interface IProps {
+ classS: string;
+ id: number;
+ isDark: boolean;
+ letterChose: (a: number) => void;
+ color: string;
+ openArticle: (a: number) => void;
+ chose: boolean;
+ sender: string;
+ letterText: string;
+ date: string;
+ markNotNew: (a: number) => void;
+}
+
+export class Letter extends Component {
+ public constructor(props: IProps) {
+ super(props);
+ this.markerRef = React.createRef();
+ }
+
+ private markerRef: RefObject;
+
+ public render() {
+ window.setTimeout(() => {
+ if (this.markerRef.current !== null) {
+ if (this.props.classS === 'add') {
+ this.markerRef.current.className = styles.letter_add;
+ window.setTimeout(() => {
+ this.props.markNotNew(this.props.id);
+ }, // .bind(this)
+ 1000);
+ } else if (this.props.classS === 'delete') {
+ this.markerRef.current.className = styles.letter_delete;
+ } else {
+ this.markerRef.current.className = styles.letter_notNew;
+ }
+ }
+ }, // .bind(this)
+ 10
+ );
+
+ const myStyle = { backgroundColor: this.props.color };
+ const darkClass = cn(styles.letterInnerior, {
+ [styles.darkSide]: this.props.isDark
+ });
+ const sqBut = cn(styles.squareForButton, styles.letterPart);
+
+ return (
+
+ this.props.openArticle(this.props.id)}
+ />
+
+
+ );
+ }
+}
diff --git a/src/letterHeader/LetterHeader.module.css b/src/letterHeader/LetterHeader.module.css
new file mode 100644
index 0000000..036cb94
--- /dev/null
+++ b/src/letterHeader/LetterHeader.module.css
@@ -0,0 +1,25 @@
+.header {
+ font-size: 13px;
+ border-style: solid;
+ border-color: #9b9b9b;
+ border-width: 0 0 0.5px 0;
+ margin-block-start: 0;
+ margin-block-end: 0;
+ height: 50px;
+}
+
+.headerButtons {
+ margin-left: 26px;
+ margin-top: -10px;
+ border: none;
+ outline: none;
+ background-color: inherit;
+ font-weight: 500;
+ color: #cccccc;
+}
+
+.headerPart {
+ display: inline-block;
+ margin-top: 18px;
+}
+
diff --git a/src/letterHeader/LetterHeader.tsx b/src/letterHeader/LetterHeader.tsx
new file mode 100644
index 0000000..279e515
--- /dev/null
+++ b/src/letterHeader/LetterHeader.tsx
@@ -0,0 +1,97 @@
+import React, { Component, RefObject } from 'react';
+import cn from 'classnames';
+import styles from '../letter/Letter.module.css';
+import stylesHead from './LetterHeader.module.css';
+
+interface IProps {
+ allLettersChose: (a: boolean) => void;
+ letterAdded: (a: number) => void;
+ lettersDeleted: () => void;
+ changeColor: () => void;
+}
+
+export class LetterHeader extends Component {
+ public constructor(props: IProps) {
+ super(props);
+ this.markerRef = React.createRef();
+ }
+
+ private markerRef: RefObject;
+
+ public render() {
+ const sqBut = cn(styles.squareForButton, stylesHead.headerPart);
+
+ return (
+
+ );
+ }
+}
diff --git a/src/lettersList/LettersList.tsx b/src/lettersList/LettersList.tsx
new file mode 100644
index 0000000..9353733
--- /dev/null
+++ b/src/lettersList/LettersList.tsx
@@ -0,0 +1,76 @@
+import React, { Component } from 'react';
+import cn from 'classnames';
+import { Article } from '../article/Article';
+import { Letter } from '../letter/Letter';
+import { LetterHeader } from '../letterHeader/LetterHeader';
+import { ILetter } from '../letter/ILetter';
+import styles from '../letter/Letter.module.css';
+
+interface IProps {
+ isDark: boolean;
+ openId: number;
+ letters: ILetter[];
+ openLetters: () => void;
+ markNotNew: (a: number) => void;
+ letterChose: (a: number) => void;
+ openArticle: (a: number) => void;
+ letterAdded: (a: number) => void;
+ lettersDeleted: () => void;
+ allLettersChose: (a: boolean) => void;
+ changeColor: () => void;
+}
+
+export class LettersList extends Component {
+ public render() {
+ let code;
+ if (this.props.openId !== -1) {
+ code = (
+ );
+ } else {
+ code = ({
+ this.props.letters.
+ filter(letter => {return letter.isVisible}).
+ slice(0, 100).map(letter => {
+ return (
+
+ );
+ })
+ }
+ );
+ }
+
+ const darkClass = cn(styles.windowLetters, {
+ [styles.darkSide]: this.props.isDark
+ });
+
+ return (
+
+ );
+ }
+}
diff --git a/src/main/Main.module.css b/src/main/Main.module.css
new file mode 100644
index 0000000..bd43295
--- /dev/null
+++ b/src/main/Main.module.css
@@ -0,0 +1,4 @@
+.blackSide {
+ background-color: black;
+ color: white;
+}
diff --git a/src/main/Main.tsx b/src/main/Main.tsx
new file mode 100644
index 0000000..a6ca64d
--- /dev/null
+++ b/src/main/Main.tsx
@@ -0,0 +1,212 @@
+import React, { Component } from 'react';
+import cn from 'classnames';
+import { genLetterText, getRandomFromRange } from '../functions/Functions';
+import { Header } from '../header/Header';
+import { Menu } from '../menu/Menu';
+import { LettersList } from '../lettersList/LettersList';
+import { ILetter } from '../letter/ILetter';
+import styles from './Main.module.css';
+
+interface IState {
+ isDark: boolean;
+ letters: ILetter[];
+ openId: number;
+ template: string;
+}
+
+export class Main extends Component<{}, IState> {
+ public constructor(props: {}) {
+ super(props);
+ this.state = {
+ isDark: false,
+ letters: [],
+ openId: -1,
+ template: ''
+ };
+ this.letterAdded = this.letterAdded.bind(this);
+ this.lettersDeleted = this.lettersDeleted.bind(this);
+ this.letterChose = this.letterChose.bind(this);
+ this.allLettersChose = this.allLettersChose.bind(this);
+ this.openArticle = this.openArticle.bind(this);
+ this.openLetters = this.openLetters.bind(this);
+ this.markNotNew = this.markNotNew.bind(this);
+ this.searchLetters = this.searchLetters.bind(this);
+ this.setLetters = this.setLetters.bind(this);
+ this.changeColor = this.changeColor.bind(this);
+ this.curMin = 10;
+ this.curMax = 60001;
+ this.fiveMin = 30000;
+ this.diff = getRandomFromRange(10, 30000);
+ }
+
+ public openArticle = (index: number) => {
+ this.setState({ openId: index });
+ };
+
+ public openLetters = () => {
+ this.setState({ openId: -1 });
+ };
+
+ public allLettersChose = (status: boolean) => {
+ const newLetters = this.state.letters.map(letter => {
+ if (letter.isVisible) {
+ return { ...letter, chose: status };
+ } else {
+ return letter;
+ }
+ });
+ this.setState({ letters: newLetters });
+ };
+
+ public lettersDeleted = () => {
+ const newLetters = this.state.letters.map(letter => {
+ if (letter.chose) {
+ letter.classS = 'delete';
+ }
+ return letter;
+ });
+ this.setState({ letters: newLetters });
+
+ window.setTimeout(
+ (letters: ILetter[]) => {
+ const lettersS = letters.filter(letter => {
+ return letter.classS !== 'delete';
+ });
+ this.setState({ letters: lettersS });
+ }, // .bind(this)
+ 1300,
+ newLetters
+ );
+ };
+
+ public letterChose = (index: number) => {
+ const newLetters = this.state.letters.map(letter => {
+ if (letter.id !== index) return letter;
+ return { ...letter, chose: !letter.chose };
+ });
+ this.setState({ letters: newLetters });
+ };
+
+ public setLetters = () => {
+ const newLetters = [];
+ for (let j = 0; j < 10000; j += 1000) {
+ console.log(j);
+ for (let i = j; i < j + 999; i++) {
+ const newLetter = genLetterText();
+ newLetters.push({
+ id: i,
+ letterText: newLetter.letterText,
+ sender: newLetter.sender,
+ color: newLetter.color,
+ date: newLetter.date,
+ deleted: newLetter.deleted,
+ classS: 'notNew',
+ chose: newLetter.chose,
+ isVisible: true
+ });
+ }
+ }
+ this.setState({ letters: newLetters });
+ };
+
+ public letterAdded = (index: number) => {
+ const newLetter = genLetterText();
+ this.setState(state => {
+ const newLetterS = {
+ id: index,
+ letterText: newLetter.letterText,
+ sender: newLetter.sender,
+ color: newLetter.color,
+ date: newLetter.date,
+ deleted: newLetter.deleted,
+ classS: 'add',
+ chose: newLetter.chose,
+ isVisible: true
+ };
+ if (!newLetterS.letterText.includes(state.template)) {
+ newLetterS.isVisible = false;
+ }
+ return {
+ letters: [newLetterS, ...state.letters],
+ openId: -1
+ };
+ });
+ let delay = 0;
+ let itsTime = false;
+ let newMax = this.curMax;
+ let currGen = 0;
+ while (!itsTime) {
+ let genDelay = getRandomFromRange(this.curMin, newMax);
+ currGen += genDelay;
+ if (currGen + this.diff >= this.fiveMin) {
+ itsTime = true;
+ } else {
+ newMax = Math.max(0, newMax - genDelay);
+ }
+ delay += genDelay;
+ }
+ this.diff = delay;
+ console.log(delay);
+ window.setTimeout(this.letterAdded, delay + 1000, index + 1);
+ };
+
+ public markNotNew = (id: number) => {
+ const lettersS = this.state.letters;
+ for (let i = 0; i < lettersS.length; i++) {
+ if (lettersS[i].id === id) {
+ lettersS[i].classS = "notNew";
+ }
+ }
+ this.setState({ letters: lettersS });
+ };
+
+ public searchLetters = (template: string) => {
+ const lettersS = this.state.letters;
+ for (let i = 0; i < lettersS.length; i++) {
+ lettersS[i].isVisible =
+ lettersS[i].letterText.includes(template) || lettersS[i].sender.includes(template);
+ }
+ this.setState({ template: template, letters: lettersS });
+ };
+
+ public changeColor = () => {
+ this.setState(state => {
+ return { isDark: !state.isDark };
+ });
+ };
+
+ private readonly curMin: number;
+
+ private readonly curMax: number;
+
+ private readonly fiveMin: number;
+
+ private diff: number;
+
+ public render() {
+ const darkClass = cn({
+ [styles.blackSide]: this.state.isDark
+ });
+ return (
+
+
+
+
+
+
+
+ );
+ }
+}
diff --git a/src/menu/Menu.module.css b/src/menu/Menu.module.css
new file mode 100644
index 0000000..5450d24
--- /dev/null
+++ b/src/menu/Menu.module.css
@@ -0,0 +1,88 @@
+.menu__actions-list_unstressed-link {
+ color: inherit;
+ text-decoration: none;
+}
+
+.menu__actions-list {
+ list-style-type: none;
+ padding-inline-start: 28px;
+}
+
+.menu__navigation {
+ line-height: 22px;
+ padding-left: 10px;
+ margin-left: -28px;
+ font-family: HelveticaNeueCyr-Medium;
+ font-size: 11px;
+ font-weight: 500;
+ color: #707070;
+}
+
+.menu__navigation:hover {
+ border-radius: 3px;
+ background-color: #cdd6e4;
+}
+
+.menu__write-button {
+ width: 147px;
+ height: 32px;
+ border: none;
+ border-radius: 3px;
+ background-color: #6287bd;
+ font-family: HelveticaNeueCyr-Medium;
+ font-size: 12px;
+ font-weight: 500;
+ color: #ffffff;
+}
+
+.menu {
+ display: inline-block;
+ margin-top: 13px;
+ margin-left: 22px;
+ width: 147px;
+}
+
+
+.actionsList_unstressedLink {
+ color: inherit;
+ text-decoration: none;
+}
+
+.actionsList {
+ list-style-type: none;
+ padding-inline-start: 28px;
+}
+
+.navigation {
+ line-height: 22px;
+ padding-left: 10px;
+ margin-left: -28px;
+ font-family: HelveticaNeueCyr-Medium;
+ font-size: 11px;
+ font-weight: 500;
+ color: #707070;
+}
+
+.navigation:hover {
+ border-radius: 3px;
+ background-color: #cdd6e4;
+}
+
+.writeButton {
+ width: 147px;
+ height: 32px;
+ border: none;
+ border-radius: 3px;
+ background-color: #6287bd;
+ font-family: HelveticaNeueCyr-Medium;
+ font-size: 12px;
+ font-weight: 500;
+ color: #ffffff;
+}
+
+.menu {
+ display: inline-block;
+ margin-top: 13px;
+ margin-left: 22px;
+ width: 147px;
+}
diff --git a/src/menu/Menu.tsx b/src/menu/Menu.tsx
new file mode 100644
index 0000000..7d9f885
--- /dev/null
+++ b/src/menu/Menu.tsx
@@ -0,0 +1,34 @@
+import React, { Component } from 'react';
+
+import styles from './Menu.module.css';
+
+export class Menu extends Component {
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts
new file mode 100644
index 0000000..6431bc5
--- /dev/null
+++ b/src/react-app-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/src/sourse/YandexMail-dark.png b/src/sourse/YandexMail-dark.png
new file mode 100644
index 0000000..d63742f
Binary files /dev/null and b/src/sourse/YandexMail-dark.png differ
diff --git a/src/sourse/YandexMail.png b/src/sourse/YandexMail.png
new file mode 100644
index 0000000..90aa921
Binary files /dev/null and b/src/sourse/YandexMail.png differ
diff --git a/src/sourse/background.jpg b/src/sourse/background.jpg
new file mode 100644
index 0000000..d0cc448
Binary files /dev/null and b/src/sourse/background.jpg differ
diff --git a/src/sourse/cat-circle.png b/src/sourse/cat-circle.png
new file mode 100644
index 0000000..9d889a6
Binary files /dev/null and b/src/sourse/cat-circle.png differ
diff --git a/src/sourse/fonts/HelveticaNeueBlackCondensed.svg b/src/sourse/fonts/HelveticaNeueBlackCondensed.svg
new file mode 100644
index 0000000..aed2bac
--- /dev/null
+++ b/src/sourse/fonts/HelveticaNeueBlackCondensed.svg
@@ -0,0 +1,1280 @@
+
+
+
diff --git a/src/sourse/fonts/HelveticaNeueBlackCondensed.ttf b/src/sourse/fonts/HelveticaNeueBlackCondensed.ttf
new file mode 100644
index 0000000..b41c291
Binary files /dev/null and b/src/sourse/fonts/HelveticaNeueBlackCondensed.ttf differ
diff --git a/src/sourse/fonts/HelveticaNeueBlackCondensed.woff b/src/sourse/fonts/HelveticaNeueBlackCondensed.woff
new file mode 100644
index 0000000..6cc8520
Binary files /dev/null and b/src/sourse/fonts/HelveticaNeueBlackCondensed.woff differ
diff --git a/src/sourse/fonts/HelveticaNeueCondensedBlack.eot b/src/sourse/fonts/HelveticaNeueCondensedBlack.eot
new file mode 100644
index 0000000..16af87a
Binary files /dev/null and b/src/sourse/fonts/HelveticaNeueCondensedBlack.eot differ
diff --git a/src/sourse/fonts/HelveticaNeueCondensedBlack.ttf b/src/sourse/fonts/HelveticaNeueCondensedBlack.ttf
new file mode 100644
index 0000000..fab85d9
Binary files /dev/null and b/src/sourse/fonts/HelveticaNeueCondensedBlack.ttf differ
diff --git a/src/sourse/fonts/HelveticaNeueCondensedBlack.woff2 b/src/sourse/fonts/HelveticaNeueCondensedBlack.woff2
new file mode 100644
index 0000000..f60ace4
Binary files /dev/null and b/src/sourse/fonts/HelveticaNeueCondensedBlack.woff2 differ
diff --git a/src/sourse/fonts/HelveticaNeueCyr-Bold.eot b/src/sourse/fonts/HelveticaNeueCyr-Bold.eot
new file mode 100644
index 0000000..a326acf
Binary files /dev/null and b/src/sourse/fonts/HelveticaNeueCyr-Bold.eot differ
diff --git a/src/sourse/fonts/HelveticaNeueCyr-Bold.otf b/src/sourse/fonts/HelveticaNeueCyr-Bold.otf
new file mode 100644
index 0000000..383dca6
Binary files /dev/null and b/src/sourse/fonts/HelveticaNeueCyr-Bold.otf differ
diff --git a/src/sourse/fonts/HelveticaNeueCyr-Bold.svg b/src/sourse/fonts/HelveticaNeueCyr-Bold.svg
new file mode 100644
index 0000000..d27a898
--- /dev/null
+++ b/src/sourse/fonts/HelveticaNeueCyr-Bold.svg
@@ -0,0 +1,939 @@
+
+
+
diff --git a/src/sourse/fonts/HelveticaNeueCyr-Bold.ttf b/src/sourse/fonts/HelveticaNeueCyr-Bold.ttf
new file mode 100644
index 0000000..f246357
Binary files /dev/null and b/src/sourse/fonts/HelveticaNeueCyr-Bold.ttf differ
diff --git a/src/sourse/fonts/HelveticaNeueCyr-Bold.woff b/src/sourse/fonts/HelveticaNeueCyr-Bold.woff
new file mode 100644
index 0000000..7e40ebe
Binary files /dev/null and b/src/sourse/fonts/HelveticaNeueCyr-Bold.woff differ
diff --git a/src/sourse/fonts/HelveticaNeueCyr-Bold.woff2 b/src/sourse/fonts/HelveticaNeueCyr-Bold.woff2
new file mode 100644
index 0000000..c066e26
Binary files /dev/null and b/src/sourse/fonts/HelveticaNeueCyr-Bold.woff2 differ
diff --git a/src/sourse/fonts/HelveticaNeueCyr-Medium.eot b/src/sourse/fonts/HelveticaNeueCyr-Medium.eot
new file mode 100644
index 0000000..5b367eb
Binary files /dev/null and b/src/sourse/fonts/HelveticaNeueCyr-Medium.eot differ
diff --git a/src/sourse/fonts/HelveticaNeueCyr-Medium.otf b/src/sourse/fonts/HelveticaNeueCyr-Medium.otf
new file mode 100644
index 0000000..a2cde16
Binary files /dev/null and b/src/sourse/fonts/HelveticaNeueCyr-Medium.otf differ
diff --git a/src/sourse/fonts/HelveticaNeueCyr-Medium.svg b/src/sourse/fonts/HelveticaNeueCyr-Medium.svg
new file mode 100644
index 0000000..41c4075
--- /dev/null
+++ b/src/sourse/fonts/HelveticaNeueCyr-Medium.svg
@@ -0,0 +1,933 @@
+
+
+
diff --git a/src/sourse/fonts/HelveticaNeueCyr-Medium.ttf b/src/sourse/fonts/HelveticaNeueCyr-Medium.ttf
new file mode 100644
index 0000000..045a1fd
Binary files /dev/null and b/src/sourse/fonts/HelveticaNeueCyr-Medium.ttf differ
diff --git a/src/sourse/fonts/HelveticaNeueCyr-Medium.woff b/src/sourse/fonts/HelveticaNeueCyr-Medium.woff
new file mode 100644
index 0000000..026cc96
Binary files /dev/null and b/src/sourse/fonts/HelveticaNeueCyr-Medium.woff differ
diff --git a/src/sourse/fonts/HelveticaNeueCyr-Medium.woff2 b/src/sourse/fonts/HelveticaNeueCyr-Medium.woff2
new file mode 100644
index 0000000..316cfff
Binary files /dev/null and b/src/sourse/fonts/HelveticaNeueCyr-Medium.woff2 differ
diff --git a/src/sourse/yandexCircle.jpg b/src/sourse/yandexCircle.jpg
new file mode 100644
index 0000000..c8dd3d8
Binary files /dev/null and b/src/sourse/yandexCircle.jpg differ
diff --git a/src/sourse/yandexMailNew.jpg b/src/sourse/yandexMailNew.jpg
new file mode 100644
index 0000000..329d0f5
Binary files /dev/null and b/src/sourse/yandexMailNew.jpg differ
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..0980b23
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "preserve"
+ },
+ "include": [
+ "src"
+ ]
+}