From 468798c4aacf295d4e55ac6a37bee2eccba0d073 Mon Sep 17 00:00:00 2001 From: Sergey Melyukov Date: Mon, 17 Apr 2023 19:08:13 +0300 Subject: [PATCH 01/11] loft photo --- projects/loft-photo/friends.json | 32 ++ projects/loft-photo/images/arrow-left.svg | 4 + projects/loft-photo/images/button.svg | 17 ++ projects/loft-photo/images/chat.svg | 3 + projects/loft-photo/images/exit.svg | 5 + projects/loft-photo/images/heart-red.svg | 3 + projects/loft-photo/images/heart.svg | 3 + projects/loft-photo/images/logo.svg | 11 + projects/loft-photo/images/send.svg | 3 + projects/loft-photo/images/vert1.svg | 22 ++ projects/loft-photo/images/vert2.svg | 22 ++ projects/loft-photo/images/vert3.svg | 22 ++ projects/loft-photo/index.js | 0 projects/loft-photo/layout.html | 64 ++++ projects/loft-photo/model.js | 9 + projects/loft-photo/photos.json | 72 +++++ projects/loft-photo/server/index.js | 91 ++++++ projects/loft-photo/settings.json | 7 + projects/loft-photo/styles.css | 348 ++++++++++++++++++++++ 19 files changed, 738 insertions(+) create mode 100644 projects/loft-photo/friends.json create mode 100644 projects/loft-photo/images/arrow-left.svg create mode 100644 projects/loft-photo/images/button.svg create mode 100644 projects/loft-photo/images/chat.svg create mode 100644 projects/loft-photo/images/exit.svg create mode 100644 projects/loft-photo/images/heart-red.svg create mode 100644 projects/loft-photo/images/heart.svg create mode 100644 projects/loft-photo/images/logo.svg create mode 100644 projects/loft-photo/images/send.svg create mode 100644 projects/loft-photo/images/vert1.svg create mode 100644 projects/loft-photo/images/vert2.svg create mode 100644 projects/loft-photo/images/vert3.svg create mode 100644 projects/loft-photo/index.js create mode 100644 projects/loft-photo/layout.html create mode 100644 projects/loft-photo/model.js create mode 100644 projects/loft-photo/photos.json create mode 100644 projects/loft-photo/server/index.js create mode 100644 projects/loft-photo/settings.json create mode 100644 projects/loft-photo/styles.css diff --git a/projects/loft-photo/friends.json b/projects/loft-photo/friends.json new file mode 100644 index 000000000..b861e0c00 --- /dev/null +++ b/projects/loft-photo/friends.json @@ -0,0 +1,32 @@ +[ + { + "id": 0, + "avatar": "https://via.placeholder.com/100?text=avatar", + "firstName": "Adrian", + "lastName": "Norman" + }, + { + "id": 1, + "avatar": "https://via.placeholder.com/100?text=avatar", + "firstName": "Gail", + "lastName": "Norton" + }, + { + "id": 2, + "avatar": "https://via.placeholder.com/100?text=avatar", + "firstName": "Molina", + "lastName": "Rodgers" + }, + { + "id": 3, + "avatar": "https://via.placeholder.com/100?text=avatar", + "firstName": "Adams", + "lastName": "Parrish" + }, + { + "id": 4, + "avatar": "https://via.placeholder.com/100?text=avatar", + "firstName": "Mercer", + "lastName": "Wiggins" + } +] \ No newline at end of file diff --git a/projects/loft-photo/images/arrow-left.svg b/projects/loft-photo/images/arrow-left.svg new file mode 100644 index 000000000..a4e4c339a --- /dev/null +++ b/projects/loft-photo/images/arrow-left.svg @@ -0,0 +1,4 @@ + + + + diff --git a/projects/loft-photo/images/button.svg b/projects/loft-photo/images/button.svg new file mode 100644 index 000000000..6ce85ea9f --- /dev/null +++ b/projects/loft-photo/images/button.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/projects/loft-photo/images/chat.svg b/projects/loft-photo/images/chat.svg new file mode 100644 index 000000000..fc47d01e1 --- /dev/null +++ b/projects/loft-photo/images/chat.svg @@ -0,0 +1,3 @@ + + + diff --git a/projects/loft-photo/images/exit.svg b/projects/loft-photo/images/exit.svg new file mode 100644 index 000000000..d28c122e1 --- /dev/null +++ b/projects/loft-photo/images/exit.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/projects/loft-photo/images/heart-red.svg b/projects/loft-photo/images/heart-red.svg new file mode 100644 index 000000000..e9985dca6 --- /dev/null +++ b/projects/loft-photo/images/heart-red.svg @@ -0,0 +1,3 @@ + + + diff --git a/projects/loft-photo/images/heart.svg b/projects/loft-photo/images/heart.svg new file mode 100644 index 000000000..4bcdacd80 --- /dev/null +++ b/projects/loft-photo/images/heart.svg @@ -0,0 +1,3 @@ + + + diff --git a/projects/loft-photo/images/logo.svg b/projects/loft-photo/images/logo.svg new file mode 100644 index 000000000..12685673d --- /dev/null +++ b/projects/loft-photo/images/logo.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/projects/loft-photo/images/send.svg b/projects/loft-photo/images/send.svg new file mode 100644 index 000000000..5a55b025c --- /dev/null +++ b/projects/loft-photo/images/send.svg @@ -0,0 +1,3 @@ + + + diff --git a/projects/loft-photo/images/vert1.svg b/projects/loft-photo/images/vert1.svg new file mode 100644 index 000000000..d5d86e658 --- /dev/null +++ b/projects/loft-photo/images/vert1.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/loft-photo/images/vert2.svg b/projects/loft-photo/images/vert2.svg new file mode 100644 index 000000000..0f5e75ed2 --- /dev/null +++ b/projects/loft-photo/images/vert2.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/loft-photo/images/vert3.svg b/projects/loft-photo/images/vert3.svg new file mode 100644 index 000000000..7b481af03 --- /dev/null +++ b/projects/loft-photo/images/vert3.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/loft-photo/index.js b/projects/loft-photo/index.js new file mode 100644 index 000000000..e69de29bb diff --git a/projects/loft-photo/layout.html b/projects/loft-photo/layout.html new file mode 100644 index 000000000..89845cfed --- /dev/null +++ b/projects/loft-photo/layout.html @@ -0,0 +1,64 @@ + + + + + + Loft Photo + + + +
+ + + +
+ + diff --git a/projects/loft-photo/model.js b/projects/loft-photo/model.js new file mode 100644 index 000000000..1e31e33b3 --- /dev/null +++ b/projects/loft-photo/model.js @@ -0,0 +1,9 @@ +// eslint-disable-next-line no-unused-vars +import photosDB from './photos.json'; +// eslint-disable-next-line no-unused-vars +import friendsDB from './friends.json'; + +export default { + getRandomElement(array) {}, + getNextPhoto() {}, +}; diff --git a/projects/loft-photo/photos.json b/projects/loft-photo/photos.json new file mode 100644 index 000000000..a299e6057 --- /dev/null +++ b/projects/loft-photo/photos.json @@ -0,0 +1,72 @@ +{ + "0": [ + { + "id": 10, + "url": "https://via.placeholder.com/360x680?text=photo 1 for Adrian Norman" + }, + { + "id": 11, + "url": "https://via.placeholder.com/360x680?text=photo 2 for Adrian Norman" + }, + { + "id": 12, + "url": "https://via.placeholder.com/360x680?text=photo 3 for Adrian Norman" + } + ], + "1": [ + { + "id": 20, + "url": "https://via.placeholder.com/360x680?text=photo 1 for Gail Norton" + }, + { + "id": 21, + "url": "https://via.placeholder.com/360x680?text=photo 2 for Gail Norton" + }, + { + "id": 22, + "url": "https://via.placeholder.com/360x680?text=photo 3 for Gail Norton" + } + ], + "2": [ + { + "id": 30, + "url": "https://via.placeholder.com/360x680?text=photo 1 for Molina Rodgers" + }, + { + "id": 31, + "url": "https://via.placeholder.com/360x680?text=photo 2 for Molina Rodgers" + }, + { + "id": 32, + "url": "https://via.placeholder.com/360x680?text=photo 3 for Molina Rodgers" + } + ], + "3": [ + { + "id": 40, + "url": "https://via.placeholder.com/360x680?text=photo 1 for Adams Parrish" + }, + { + "id": 41, + "url": "https://via.placeholder.com/360x680?text=photo 2 for Adams Parrish" + }, + { + "id": 42, + "url": "https://via.placeholder.com/360x680?text=photo 3 for Adams Parrish" + } + ], + "4": [ + { + "id": 50, + "url": "https://via.placeholder.com/360x680?text=photo 1 for Mercer Wiggins" + }, + { + "id": 51, + "url": "https://via.placeholder.com/360x680?text=photo 2 for Mercer Wiggins" + }, + { + "id": 52, + "url": "https://via.placeholder.com/360x680?text=photo 3 for Mercer Wiggins" + } + ] +} \ No newline at end of file diff --git a/projects/loft-photo/server/index.js b/projects/loft-photo/server/index.js new file mode 100644 index 000000000..e9057c6c4 --- /dev/null +++ b/projects/loft-photo/server/index.js @@ -0,0 +1,91 @@ +const http = require('node:http'); +const https = require('node:https'); +const url = require('node:url'); + +const DB = { + tokens: new Map(), + likes: new Map(), + comments: new Map(), +}; + +const methods = { + like(req, res, url, vkUser) { + // todo + }, + photoStats(req, res, url, vkUser) { + // todo + }, + postComment(req, res, url, vkUser, body) { + // todo + }, + getComments(req, res, url) { + // todo + }, +}; + +http + .createServer(async (req, res) => { + console.log('➡️ Поступил запрос:', req.method, req.url); + const token = req.headers['vk_token']; + const parsed = new url.URL(req.url, 'http://localhost'); + const vkUser = await getMe(token); + const body = await readBody(req); + const method = parsed.searchParams.get('method'); + const responseData = await methods[method]?.(req, res, parsed, vkUser, body); + + res.end(JSON.stringify(responseData ?? null)); + }) + .listen('8888', () => { + console.log('🚀 Сервер запущен'); + }); + +async function readBody(req) { + if (req.method === 'GET') { + return null; + } + + return new Promise((resolve) => { + let body = ''; + req + .on('data', (chunk) => { + body += chunk; + }) + .on('end', () => resolve(JSON.parse(body))); + }); +} + +async function getVKUser(token) { + const body = await new Promise((resolve, reject) => + https + .get( + `https://api.vk.com/method/users.get?access_token=${token}&fields=photo_50&v=5.120` + ) + .on('response', (res) => { + let body = ''; + + res.setEncoding('utf8'); + res + .on('data', (chunk) => { + body += chunk; + }) + .on('end', () => resolve(JSON.parse(body))); + }) + .on('error', reject) + ); + + return body.response[0]; +} + +async function getMe(token) { + const existing = DB.tokens.get(token); + + if (existing) { + return existing; + } + + const user = getVKUser(token); + + DB.tokens.set(token, user); + + return user; +} diff --git a/projects/loft-photo/settings.json b/projects/loft-photo/settings.json new file mode 100644 index 000000000..3d20b4405 --- /dev/null +++ b/projects/loft-photo/settings.json @@ -0,0 +1,7 @@ +{ + "proxy": { + "/loft-photo/api/": { + "target": "http://localhost:8888" + } + } +} diff --git a/projects/loft-photo/styles.css b/projects/loft-photo/styles.css new file mode 100644 index 000000000..62d5fba21 --- /dev/null +++ b/projects/loft-photo/styles.css @@ -0,0 +1,348 @@ +/* base */ + +body { + font-family: "Roboto Light", Geneva, Arial, Helvetica, sans-serif; +} + +.hidden { + display: none !important; +} + +a { + text-decoration: none; +} + +/* app */ + +#app { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: flex; + + align-items: center; + justify-content: center; +} + +.page { + height: 100%; + width: 360px; + position: relative; +} + +/* page login */ + +.page-login { + display: flex; + justify-content: center; + background: #1C1B1F; +} + +.page-login-button { + border: none; + background: url('images/button.svg'); + width: 219px; + height: 40px; + position: absolute; + bottom: 60px; + margin: 0 auto; +} + +.page-login-logo { + top: 429px; + position: absolute; + gap: 16px; + display: flex; + flex-direction: column; + align-items: center; +} + +.page-login-image { + width: 147px; + height: 24px; + background: url('images/logo.svg'); +} + +.page-login-text { + font-size: 14px; + line-height: 20px; + text-align: center; + width: 237px; + color: #B0B0B0; +} + +.page-login-vert1, .page-login-vert2, .page-login-vert3 { + width: 71px; + height: 333px; + position: absolute; +} + +.page-login-vert1 { + top: 59px; + left: 49px; + background: linear-gradient(180deg, rgba(28, 27, 31, 0) 80%, #1C1B1F 100%), url('images/vert1.svg'); +} + +.page-login-vert2 { + top: 81px; + left: 144px; + background: linear-gradient(180deg, rgba(28, 27, 31, 0) 80%, #1C1B1F 100%), url('images/vert2.svg'); +} + +.page-login-vert3 { + top: 59px; + left: 239px; + background: linear-gradient(180deg, rgba(28, 27, 31, 0) 80%, #1C1B1F 100%), url('images/vert3.svg'); +} + +/* page main */ + +.page-main .component-header { + position: absolute; + display: flex; + height: 80px; + top: 0; + left: 0; + right: 0; + background: rgba(0 0 0 / 25%); + padding: 0 24px; +} + +.page-main .component-header-profile-link { + display: flex; + align-items: center; +} + +.page-main .component-header-photo { + width: 40px; + height: 40px; + border-radius: 50%; + flex-shrink: 0; +} + +.page-main .component-header-name { + margin-left: 8px; + font-weight: 400; + font-size: 16px; + color: white; +} + +.page-main .component-footer { + position: absolute; + display: flex; + height: 80px; + bottom: 0; + left: 0; + right: 0; + background: rgba(0 0 0 / 25%); + padding: 0 24px; +} + +.page-main .component-footer-container { + display: flex; + align-items: center; + width: 100%; +} + +.page-main .component-footer-container-profile-link { + margin-left: auto; +} + +.page-main .component-footer-photo { + width: 40px; + height: 40px; + border-radius: 50%; +} + +.page-main .component-footer-container-social-comments, +.page-main .component-footer-container-social-likes { + color: white; + display: flex; + align-items: center; +} + +.page-main .component-footer-container-social-comments:before, +.page-main .component-footer-container-social-likes:before { + display: inline-block; + content: ''; + width: 20px; + height: 20px; + margin-right: 6px; +} + +.page-main .component-footer-container-social-comments:before { + background: url("images/chat.svg"); +} + +.page-main .component-footer-container-social-likes:before { + background: url("images/heart.svg"); + margin-left: 18px; +} + +.page-main .component-footer-container-social-likes.liked:before { + background: url("images/heart-red.svg"); + margin-left: 18px; +} + +.page-main .component-photo { + height: 100%; + width: 360px; + position: relative; + + background-size: cover; + background-position: center; +} + +.component-comments { + position: fixed; + bottom: 0; + left: 0; + right: 0; + top: 0; + background: rgba(0, 0, 0, 0.4); +} + +.component-comments-container { + position: absolute; + display: flex; + flex-direction: column; + top: 50vh; + bottom: 0; + left: 0; + right: 0; + padding: 16px; + border-radius: 28px 28px 0 0; + background: white; +} + +.component-comments-container-title { + font-size: 14px; + text-align: center; + width: 100%; +} + +.component-comments-container-list { + margin-top: 24px; + flex-grow: 1; + display: flex; + gap: 12px; + flex-direction: column; + overflow-y: auto; + margin-bottom: 14px +} + +.component-comments-container-form { + display: flex; + align-items: center; + gap: 16px; + height: 48px; +} + +.component-comments-container-form-input { + box-sizing: border-box; + border: 1px solid #E0E0E0; + border-radius: 32px; + flex-grow: 1; + height: 48px; +} + +.component-comments-container-form-input, +.component-comments-container-form-input, +.component-comments-container-form-input, +.component-comments-container-form-input { + padding: 14px 16px; +} + +.component-comments-container-form-send { + background: url('images/send.svg'); + width: 40px; + height: 40px; +} + +.component-comment { + display: flex; + gap: 8px +} + +.component-comment-photo { + width: 24px; + height: 24px; + border-radius: 50%; + background-position: center; + background-size: cover; +} + +.component-comment-content { + flex-direction: column; +} + +.component-comment-name { + font-size: 12px; +} + +.component-comment-text { + font-size: 14px; +} + +/* page profile */ + +.page-profile { + margin-top: 52px; +} + +.page-profile-back { + background: url('images/arrow-left.svg'); + width: 24px; + height: 24px; + + position: absolute; + left: 24px; +} + +.page-profile-exit { + background: url('images/exit.svg'); + width: 24px; + height: 24px; + + position: absolute; + right: 24px; +} + +.component-user-photos { + display: flex; + flex-wrap: wrap; + gap: 8px; + padding: 24px 16px 16px 16px; +} + +.component-user-photo { + width: 104px; + height: 104px; + background-size: cover; + background-repeat: no-repeat; + background-position: center; +} + +.page-profile .component-user-info { + display: flex; + flex-direction: column; + align-items: center; +} + +.page-profile .component-user-info-photo { + height: 72px; + width: 72px; + border-radius: 50%; + + background-size: cover; + background-position: center; +} + +.page-profile .component-user-info-name { + font-weight: 400; + font-size: 18px; + line-height: 26px; + margin-top: 8px; +} \ No newline at end of file From 3575fd908e681ec494b1eb62abb6d4694cfa6958 Mon Sep 17 00:00:00 2001 From: lFrodo Date: Sun, 30 Apr 2023 12:12:34 +0300 Subject: [PATCH 02/11] project loft-school#1 --- projects/loft-photo/model.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/projects/loft-photo/model.js b/projects/loft-photo/model.js index 1e31e33b3..07acb92bb 100644 --- a/projects/loft-photo/model.js +++ b/projects/loft-photo/model.js @@ -4,6 +4,17 @@ import photosDB from './photos.json'; import friendsDB from './friends.json'; export default { - getRandomElement(array) {}, - getNextPhoto() {}, + getRandomElement(array) { + if (!array.length) { + return null; + } + const index = Math.round(Math.random() * (array.length - 1)); + return array[index]; + }, + getNextPhoto() { + const friend = this.getRandomElement(friendsDB); + const photos = photosDB.get(friend.id); + const photo = this.getRandomElement(photos); + return { friend, photo }; + }, }; From 3671a42bb65d00fbcee62a55ed52ed32f3664ce9 Mon Sep 17 00:00:00 2001 From: lFrodo Date: Mon, 8 May 2023 12:07:49 +0300 Subject: [PATCH 03/11] loft-photo 3 week --- projects/loft-photo/index.js | 9 +++++++++ projects/loft-photo/pages.js | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 projects/loft-photo/pages.js diff --git a/projects/loft-photo/index.js b/projects/loft-photo/index.js index e69de29bb..a59d6843f 100644 --- a/projects/loft-photo/index.js +++ b/projects/loft-photo/index.js @@ -0,0 +1,9 @@ +import pages from './pages'; +import('./styles.css'); + +const pageNames = ['login', 'main', 'profile']; + +document.addEventListener('click', () => { + const page = model.getRandomElement(pageNames); + pages.openPage(page); +}); diff --git a/projects/loft-photo/pages.js b/projects/loft-photo/pages.js new file mode 100644 index 000000000..33bea0a20 --- /dev/null +++ b/projects/loft-photo/pages.js @@ -0,0 +1,19 @@ +const pagesMap = { + login: '.page-login', + main: '.page-main', + profile: '.page-profile', +}; +let page; +export default { + openPage(name) { + const currentClass = pagesMap[name]; + let element = document.querySelector(currentClass); + page?.classList.add('hidden'); + page = element; + page.classList.remove('hidden'); + }, +}; + +// pages.openPage('main'); // сделать видимым элемент с классом page-main +// pages.openPage('profile'); // сделать видимым элемент с классом page-profile, а page-main скрыть +// pages.openPage('login'); // сделать видимым элемент с классом page-login, а page-profile скрыть From 3696eafddbce3ca1b06f604cf6bda1efcdd218b1 Mon Sep 17 00:00:00 2001 From: lFrodo Date: Sun, 14 May 2023 16:58:51 +0300 Subject: [PATCH 04/11] loft-photo 4 week --- projects/loft-photo/friends.json | 32 ---------- projects/loft-photo/index.js | 10 +-- projects/loft-photo/loginpage | 11 ++++ projects/loft-photo/mainpage.js | 35 +++++++++++ projects/loft-photo/model.js | 103 ++++++++++++++++++++++++++++--- projects/loft-photo/pages.js | 2 +- projects/loft-photo/photos.json | 72 --------------------- webpack.config.js | 3 +- 8 files changed, 148 insertions(+), 120 deletions(-) delete mode 100644 projects/loft-photo/friends.json create mode 100644 projects/loft-photo/loginpage create mode 100644 projects/loft-photo/mainpage.js delete mode 100644 projects/loft-photo/photos.json diff --git a/projects/loft-photo/friends.json b/projects/loft-photo/friends.json deleted file mode 100644 index b861e0c00..000000000 --- a/projects/loft-photo/friends.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "id": 0, - "avatar": "https://via.placeholder.com/100?text=avatar", - "firstName": "Adrian", - "lastName": "Norman" - }, - { - "id": 1, - "avatar": "https://via.placeholder.com/100?text=avatar", - "firstName": "Gail", - "lastName": "Norton" - }, - { - "id": 2, - "avatar": "https://via.placeholder.com/100?text=avatar", - "firstName": "Molina", - "lastName": "Rodgers" - }, - { - "id": 3, - "avatar": "https://via.placeholder.com/100?text=avatar", - "firstName": "Adams", - "lastName": "Parrish" - }, - { - "id": 4, - "avatar": "https://via.placeholder.com/100?text=avatar", - "firstName": "Mercer", - "lastName": "Wiggins" - } -] \ No newline at end of file diff --git a/projects/loft-photo/index.js b/projects/loft-photo/index.js index a59d6843f..da42f6c40 100644 --- a/projects/loft-photo/index.js +++ b/projects/loft-photo/index.js @@ -1,9 +1,9 @@ import pages from './pages'; import('./styles.css'); - +import mainPage from './mainpage'; +import loginPage from './loginPage'; const pageNames = ['login', 'main', 'profile']; -document.addEventListener('click', () => { - const page = model.getRandomElement(pageNames); - pages.openPage(page); -}); +pages.openPage('login'); +loginPage.handleEvents(); +mainPage.handleEvents(); diff --git a/projects/loft-photo/loginpage b/projects/loft-photo/loginpage new file mode 100644 index 000000000..560be273a --- /dev/null +++ b/projects/loft-photo/loginpage @@ -0,0 +1,11 @@ +import model from './model'; +import pages from './pages'; +import mainPage from './mainpage'; + +export default { + handleEvents() { + document + .querySelector('.page-login-button') + .addEventListener('click', async () => {}); + }, +}; diff --git a/projects/loft-photo/mainpage.js b/projects/loft-photo/mainpage.js new file mode 100644 index 000000000..0cb587b26 --- /dev/null +++ b/projects/loft-photo/mainpage.js @@ -0,0 +1,35 @@ +import { doc } from 'prettier'; +import model from './model'; + +export default { + async getNextPhoto() { + const { friend, id, url } = await model.getNextPhoto(); + this.setFriendAndPhoto(friend, id, url); + }, + + setFriendAndPhoto(friend, id, url) { + const photoComp = document.querySelector('.component-photo'); + const headerPhotoComp = document.querySelector('.component-header-photo'); + const headerNameComp = document.querySelector('.component-header-name'); + + headerPhotoComp.style.backgroundImage = `url('${friend.photo_50}')`; + headerNameComp.innerText = `${friend.first_name ?? ''} ${friend.last_name ?? ''}`; + photoComp.style.backgroundImage = `url(${url})`; + }, + + handleEvents() { + let startFrom; + + document.querySelector('.component-photo').addEventListener('touchstart', (e) => { + e.preventDefault(); + startFrom = { y: e.changedTouches[0].pageY }; + }); + document.querySelector('.component-photo').addEventListener('touchend', async (e) => { + e.preventDefault(); + const direction = e.changedTouches[0].pageY - startFrom.y; + if (direction < 0) { + await this.getNextPhoto(); + } + }); + }, +}; diff --git a/projects/loft-photo/model.js b/projects/loft-photo/model.js index 07acb92bb..c163366e8 100644 --- a/projects/loft-photo/model.js +++ b/projects/loft-photo/model.js @@ -1,8 +1,22 @@ -// eslint-disable-next-line no-unused-vars -import photosDB from './photos.json'; -// eslint-disable-next-line no-unused-vars -import friendsDB from './friends.json'; +// VK.init({ +// apiId: 51643234, +// }); +// function auth() { +// return new Promise((resolve, reject) => { +// VK.Auth.login((data) => { +// if (data.session) { +// resolve(); +// } else { +// reject(new Error('Не удалось авторизоваться')); +// } +// }, 2); +// }); +// } + +// auth().then(() => console.log('ok')); +const PERM_FRIENDS = 1; +const PERM_PHOTOS = 1; export default { getRandomElement(array) { if (!array.length) { @@ -11,10 +25,81 @@ export default { const index = Math.round(Math.random() * (array.length - 1)); return array[index]; }, - getNextPhoto() { - const friend = this.getRandomElement(friendsDB); - const photos = photosDB.get(friend.id); - const photo = this.getRandomElement(photos); - return { friend, photo }; + async getNextPhoto() { + const friend = this.getRandomElement(this.friends.item); + const photos = await this.getFriendPhoto(friend.id); + const photo = this.getRandomElement(photos.itens); + const size = this.findSize(photo); + return { friend, id: photo.id, url: size.url }; + }, + findSize(photo) { + const size = photo.sizes.find((size) => size.width >= 360); + // if (!size) { + // return photo.sizes.reduce((biggest, current) => { + // if (current.width > biggest.width) { + // return current; + // } + // return biggest; + // }, photo.sizes[0]); + // } + return size; + }, + + login() { + return new Promise((resolve, reject) => { + VK.init({ + apiId: 51643234, + }); + VK.Auth.login((response) => { + if (response.session) { + resolve(response); + } else { + console.log(response); + reject(response); + } + }, PERM_FRIENDS | PERM_PHOTOS); + }); + }, + + async init() { + this.photoCache = {}; + this.friends = await this.getFriends(); + }, + + callApi(method, params) { + params.v = params.v || 5.12; + return new Promise(resolve, (reject) => { + VK.Api(method, params, (response) => { + if (response.error) { + reject(new Error(response.error.error_msg)); + } else { + resolve(response.response); + } + }); + }); + }, + + getFriends() { + const params = { + fields: ['photo_50', 'photo_100'], + }; + return this.callApi('friends.get', params); + }, + getPhotos(owner) { + const params = { owner_id: owner }; + return this.callApi('photos.getAll', params); + }, + async getFriendPhotos(id) { + const photos = this.photoCache[id]; + + if (photos) { + return photos; + } + + photos = await this.getPhotos(id); + + this.photoCache[id] = photos; + + return photos; }, }; diff --git a/projects/loft-photo/pages.js b/projects/loft-photo/pages.js index 33bea0a20..4b9f49ccc 100644 --- a/projects/loft-photo/pages.js +++ b/projects/loft-photo/pages.js @@ -7,7 +7,7 @@ let page; export default { openPage(name) { const currentClass = pagesMap[name]; - let element = document.querySelector(currentClass); + const element = document.querySelector(currentClass); page?.classList.add('hidden'); page = element; page.classList.remove('hidden'); diff --git a/projects/loft-photo/photos.json b/projects/loft-photo/photos.json deleted file mode 100644 index a299e6057..000000000 --- a/projects/loft-photo/photos.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "0": [ - { - "id": 10, - "url": "https://via.placeholder.com/360x680?text=photo 1 for Adrian Norman" - }, - { - "id": 11, - "url": "https://via.placeholder.com/360x680?text=photo 2 for Adrian Norman" - }, - { - "id": 12, - "url": "https://via.placeholder.com/360x680?text=photo 3 for Adrian Norman" - } - ], - "1": [ - { - "id": 20, - "url": "https://via.placeholder.com/360x680?text=photo 1 for Gail Norton" - }, - { - "id": 21, - "url": "https://via.placeholder.com/360x680?text=photo 2 for Gail Norton" - }, - { - "id": 22, - "url": "https://via.placeholder.com/360x680?text=photo 3 for Gail Norton" - } - ], - "2": [ - { - "id": 30, - "url": "https://via.placeholder.com/360x680?text=photo 1 for Molina Rodgers" - }, - { - "id": 31, - "url": "https://via.placeholder.com/360x680?text=photo 2 for Molina Rodgers" - }, - { - "id": 32, - "url": "https://via.placeholder.com/360x680?text=photo 3 for Molina Rodgers" - } - ], - "3": [ - { - "id": 40, - "url": "https://via.placeholder.com/360x680?text=photo 1 for Adams Parrish" - }, - { - "id": 41, - "url": "https://via.placeholder.com/360x680?text=photo 2 for Adams Parrish" - }, - { - "id": 42, - "url": "https://via.placeholder.com/360x680?text=photo 3 for Adams Parrish" - } - ], - "4": [ - { - "id": 50, - "url": "https://via.placeholder.com/360x680?text=photo 1 for Mercer Wiggins" - }, - { - "id": 51, - "url": "https://via.placeholder.com/360x680?text=photo 2 for Mercer Wiggins" - }, - { - "id": 52, - "url": "https://via.placeholder.com/360x680?text=photo 3 for Mercer Wiggins" - } - ] -} \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index 2c7806598..433fc4470 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -61,7 +61,8 @@ module.exports = { options: { cacheDirectory: true }, }, { - test: /projects\/.+\.html$/, + test: /\.html$/, + include: [path.join(__dirname, 'projects')], use: [{ loader: './scripts/html-inject-loader.js' }, { loader: 'html-loader' }], }, { From 054d21fc85da5e86001de7ef6c06ae12db125942 Mon Sep 17 00:00:00 2001 From: lFrodo Date: Sun, 14 May 2023 17:25:23 +0300 Subject: [PATCH 05/11] corrections 4th week loft-photo --- projects/loft-photo/index.js | 2 +- projects/loft-photo/loginpage | 11 ----------- projects/loft-photo/loginpage.js | 15 +++++++++++++++ projects/loft-photo/model.js | 7 ++++--- 4 files changed, 20 insertions(+), 15 deletions(-) delete mode 100644 projects/loft-photo/loginpage create mode 100644 projects/loft-photo/loginpage.js diff --git a/projects/loft-photo/index.js b/projects/loft-photo/index.js index da42f6c40..119e10dd0 100644 --- a/projects/loft-photo/index.js +++ b/projects/loft-photo/index.js @@ -1,7 +1,7 @@ import pages from './pages'; import('./styles.css'); import mainPage from './mainpage'; -import loginPage from './loginPage'; +import loginPage from './loginpage'; const pageNames = ['login', 'main', 'profile']; pages.openPage('login'); diff --git a/projects/loft-photo/loginpage b/projects/loft-photo/loginpage deleted file mode 100644 index 560be273a..000000000 --- a/projects/loft-photo/loginpage +++ /dev/null @@ -1,11 +0,0 @@ -import model from './model'; -import pages from './pages'; -import mainPage from './mainpage'; - -export default { - handleEvents() { - document - .querySelector('.page-login-button') - .addEventListener('click', async () => {}); - }, -}; diff --git a/projects/loft-photo/loginpage.js b/projects/loft-photo/loginpage.js new file mode 100644 index 000000000..427fddbb2 --- /dev/null +++ b/projects/loft-photo/loginpage.js @@ -0,0 +1,15 @@ +import model from './model'; +import pages from './pages'; +import mainPage from './mainpage'; + +export default { + + handleEvents() { + document.querySelector('.page-login-button').addEventListener('click',async () => { + await model.login(); + await model.init(); + pages.openPage('main'); + await mainPage.getNextPhoto() + }) + }, +}; diff --git a/projects/loft-photo/model.js b/projects/loft-photo/model.js index c163366e8..8de67ae18 100644 --- a/projects/loft-photo/model.js +++ b/projects/loft-photo/model.js @@ -67,9 +67,10 @@ export default { }, callApi(method, params) { - params.v = params.v || 5.12; - return new Promise(resolve, (reject) => { - VK.Api(method, params, (response) => { + params.v = params.v || 5.131; + + return new Promise(resolve, reject => { + VK.api(method, params, (response) => { if (response.error) { reject(new Error(response.error.error_msg)); } else { From ff5e1cf54a1c1d5282000028a9a13fc952188e04 Mon Sep 17 00:00:00 2001 From: lFrodo Date: Fri, 19 May 2023 07:43:58 +0300 Subject: [PATCH 06/11] corrections 4th week --- projects/loft-photo/loginpage.js | 4 +-- projects/loft-photo/mainpage.js | 2 +- projects/loft-photo/model.js | 53 ++++++++++++++++++++------------ 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/projects/loft-photo/loginpage.js b/projects/loft-photo/loginpage.js index 427fddbb2..8b0f939b7 100644 --- a/projects/loft-photo/loginpage.js +++ b/projects/loft-photo/loginpage.js @@ -3,12 +3,12 @@ import pages from './pages'; import mainPage from './mainpage'; export default { - handleEvents() { document.querySelector('.page-login-button').addEventListener('click',async () => { await model.login(); await model.init(); - pages.openPage('main'); + + pages.openPage('main'); await mainPage.getNextPhoto() }) }, diff --git a/projects/loft-photo/mainpage.js b/projects/loft-photo/mainpage.js index 0cb587b26..7dc7b1903 100644 --- a/projects/loft-photo/mainpage.js +++ b/projects/loft-photo/mainpage.js @@ -3,7 +3,7 @@ import model from './model'; export default { async getNextPhoto() { - const { friend, id, url } = await model.getNextPhoto(); + const {friend, id, url} = await model.getNextPhoto(); this.setFriendAndPhoto(friend, id, url); }, diff --git a/projects/loft-photo/model.js b/projects/loft-photo/model.js index 8de67ae18..8fe4da633 100644 --- a/projects/loft-photo/model.js +++ b/projects/loft-photo/model.js @@ -15,24 +15,32 @@ // } // auth().then(() => console.log('ok')); -const PERM_FRIENDS = 1; -const PERM_PHOTOS = 1; +const PERM_FRIENDS = 2; +const PERM_PHOTOS = 4; + export default { - getRandomElement(array) { - if (!array.length) { + + + async getRandomElement(e) { + + + + + if (!e.length) { return null; } - const index = Math.round(Math.random() * (array.length - 1)); - return array[index]; + const index = Math.round(Math.random() * (e.length - 1)); + return e[index]; }, async getNextPhoto() { - const friend = this.getRandomElement(this.friends.item); - const photos = await this.getFriendPhoto(friend.id); - const photo = this.getRandomElement(photos.itens); - const size = this.findSize(photo); + const friend = await this.getRandomElement(this.friends.items); + const photos = await this.getFriendPhotos(friend.id); + const photo = await this.getRandomElement(photos.items); + const size = await this.findSize(photo); return { friend, id: photo.id, url: size.url }; }, findSize(photo) { + const size = photo.sizes.find((size) => size.width >= 360); // if (!size) { // return photo.sizes.reduce((biggest, current) => { @@ -44,7 +52,12 @@ export default { // } return size; }, + async init() { + + this.photoCache = {}; + this.friends = await this.getFriends(); + }, login() { return new Promise((resolve, reject) => { VK.init({ @@ -54,23 +67,19 @@ export default { if (response.session) { resolve(response); } else { - console.log(response); + console.error(response); reject(response); } }, PERM_FRIENDS | PERM_PHOTOS); }); }, - async init() { - this.photoCache = {}; - this.friends = await this.getFriends(); - }, - - callApi(method, params) { + callApi(method, params) { params.v = params.v || 5.131; - return new Promise(resolve, reject => { + return new Promise((resolve, reject) => { VK.api(method, params, (response) => { + if (response.error) { reject(new Error(response.error.error_msg)); } else { @@ -80,27 +89,31 @@ export default { }); }, + getFriends() { const params = { fields: ['photo_50', 'photo_100'], }; + return this.callApi('friends.get', params); }, + getPhotos(owner) { + const params = { owner_id: owner }; return this.callApi('photos.getAll', params); }, async getFriendPhotos(id) { - const photos = this.photoCache[id]; + let photos = this.photoCache[id]; if (photos) { return photos; } - photos = await this.getPhotos(id); this.photoCache[id] = photos; return photos; }, + }; From d09bd6c7e920d530afcb461dada4a5f9e29b61b3 Mon Sep 17 00:00:00 2001 From: lFrodo Date: Thu, 25 May 2023 15:11:30 +0300 Subject: [PATCH 07/11] changes --- projects/loft-photo/loginpage.js | 10 +++++----- projects/loft-photo/mainpage.js | 2 +- projects/loft-photo/model.js | 17 ++--------------- 3 files changed, 8 insertions(+), 21 deletions(-) diff --git a/projects/loft-photo/loginpage.js b/projects/loft-photo/loginpage.js index 8b0f939b7..9c314ed55 100644 --- a/projects/loft-photo/loginpage.js +++ b/projects/loft-photo/loginpage.js @@ -4,12 +4,12 @@ import mainPage from './mainpage'; export default { handleEvents() { - document.querySelector('.page-login-button').addEventListener('click',async () => { + document.querySelector('.page-login-button').addEventListener('click', async () => { await model.login(); await model.init(); - pages.openPage('main'); - await mainPage.getNextPhoto() - }) - }, + pages.openPage('main'); + await mainPage.getNextPhoto(); + }); + }, }; diff --git a/projects/loft-photo/mainpage.js b/projects/loft-photo/mainpage.js index 7dc7b1903..0cb587b26 100644 --- a/projects/loft-photo/mainpage.js +++ b/projects/loft-photo/mainpage.js @@ -3,7 +3,7 @@ import model from './model'; export default { async getNextPhoto() { - const {friend, id, url} = await model.getNextPhoto(); + const { friend, id, url } = await model.getNextPhoto(); this.setFriendAndPhoto(friend, id, url); }, diff --git a/projects/loft-photo/model.js b/projects/loft-photo/model.js index 8fe4da633..0eeb5796d 100644 --- a/projects/loft-photo/model.js +++ b/projects/loft-photo/model.js @@ -19,13 +19,7 @@ const PERM_FRIENDS = 2; const PERM_PHOTOS = 4; export default { - - - async getRandomElement(e) { - - - - + async getRandomElement(e) { if (!e.length) { return null; } @@ -40,7 +34,6 @@ export default { return { friend, id: photo.id, url: size.url }; }, findSize(photo) { - const size = photo.sizes.find((size) => size.width >= 360); // if (!size) { // return photo.sizes.reduce((biggest, current) => { @@ -53,10 +46,8 @@ export default { return size; }, async init() { - this.photoCache = {}; this.friends = await this.getFriends(); - }, login() { return new Promise((resolve, reject) => { @@ -74,12 +65,11 @@ export default { }); }, - callApi(method, params) { + callApi(method, params) { params.v = params.v || 5.131; return new Promise((resolve, reject) => { VK.api(method, params, (response) => { - if (response.error) { reject(new Error(response.error.error_msg)); } else { @@ -89,7 +79,6 @@ export default { }); }, - getFriends() { const params = { fields: ['photo_50', 'photo_100'], @@ -99,7 +88,6 @@ export default { }, getPhotos(owner) { - const params = { owner_id: owner }; return this.callApi('photos.getAll', params); }, @@ -115,5 +103,4 @@ export default { return photos; }, - }; From 576a3cd48246562993622aadc307edca9c5b4680 Mon Sep 17 00:00:00 2001 From: lFrodo Date: Thu, 25 May 2023 16:00:33 +0300 Subject: [PATCH 08/11] 5th week --- projects/loft-photo/index.js | 2 ++ projects/loft-photo/mainpage.js | 20 +++++++++++- projects/loft-photo/model.js | 9 ++++++ projects/loft-photo/profilepage.js | 49 ++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 projects/loft-photo/profilepage.js diff --git a/projects/loft-photo/index.js b/projects/loft-photo/index.js index 119e10dd0..4ab986967 100644 --- a/projects/loft-photo/index.js +++ b/projects/loft-photo/index.js @@ -3,7 +3,9 @@ import('./styles.css'); import mainPage from './mainpage'; import loginPage from './loginpage'; const pageNames = ['login', 'main', 'profile']; +import profilePage from './profilepage'; pages.openPage('login'); loginPage.handleEvents(); mainPage.handleEvents(); +profilePage.handleEvents(); diff --git a/projects/loft-photo/mainpage.js b/projects/loft-photo/mainpage.js index 0cb587b26..f842f246f 100644 --- a/projects/loft-photo/mainpage.js +++ b/projects/loft-photo/mainpage.js @@ -1,5 +1,7 @@ -import { doc } from 'prettier'; + import model from './model'; +import profilePage from './profilepage'; +import pages from './pages'; export default { async getNextPhoto() { @@ -11,10 +13,14 @@ export default { const photoComp = document.querySelector('.component-photo'); const headerPhotoComp = document.querySelector('.component-header-photo'); const headerNameComp = document.querySelector('.component-header-name'); + const footerPhotoComp = document.querySelector('.component-footer-photo'); + + this.friend = friend; headerPhotoComp.style.backgroundImage = `url('${friend.photo_50}')`; headerNameComp.innerText = `${friend.first_name ?? ''} ${friend.last_name ?? ''}`; photoComp.style.backgroundImage = `url(${url})`; + footerPhotoComp.style.backgroundImage = `url('${model.me.photo_50}')`; }, handleEvents() { @@ -31,5 +37,17 @@ export default { await this.getNextPhoto(); } }); + document + .querySelector('.component-header-profile-link') + .addEventListener('click', async () => { + await profilePage.setUser(this.friend); + pages.openPage('profile'); + }); + document + .querySelector('.component-footer-container-profile-link') + .addEventListener('click', async () => { + await profilePage.setUser(model.me); + pages.openPage('profile'); + }); }, }; diff --git a/projects/loft-photo/model.js b/projects/loft-photo/model.js index 0eeb5796d..7313f4117 100644 --- a/projects/loft-photo/model.js +++ b/projects/loft-photo/model.js @@ -48,6 +48,7 @@ export default { async init() { this.photoCache = {}; this.friends = await this.getFriends(); + [this.me] = await this.getUsers(); }, login() { return new Promise((resolve, reject) => { @@ -64,7 +65,15 @@ export default { }, PERM_FRIENDS | PERM_PHOTOS); }); }, + logout() {}, + getUsers(ids) { + const params = { fields: ['photo_50, photo_100'] }; + if (ids) { + params.user_ids = ids; + } + return this.callApi('users.get', params); + }, callApi(method, params) { params.v = params.v || 5.131; diff --git a/projects/loft-photo/profilepage.js b/projects/loft-photo/profilepage.js new file mode 100644 index 000000000..ae98da928 --- /dev/null +++ b/projects/loft-photo/profilepage.js @@ -0,0 +1,49 @@ +import model from './model'; +import mainPage from './mainpage'; +import pages from './pages'; + + +export default { + async setUser(user) { + const photoComp = document.querySelector('.component-user-info-photo'); + const nameComp = document.querySelector('.component-user-info-name'); + const photosComp = document.querySelector('.component-user-photos'); + const photos = await model.getPhotos(user.id); + this.user = user; + photoComp.style.backgroundImage = `url('${user.photo_100}')`; + nameComp.innerText = `${user.first_name ?? ''} ${user.last_name ?? ''}`; + photosComp.innerHTML = ''; + + for (const photo of photos.items) { + const size = model.findSize(photo); + console.log(size); + const element = document.createElement('div'); + element.classList.add('component-user-photo'); + element.dataset.id = photo.id; + element.style.backgroundImage = `url('${size.url}')`; + photosComp.append(element); + } + }, + + handleEvents() { + document + .querySelector('.component-user-photos') + .addEventListener('click', async (e) => { + if (e.target.classList.contains('component-user-photo')) { + const photoId = e.target.dataset.id; + const friendsPhotos = await model.getPhotos(this.user.id); + const photo = friendsPhotos.items.find((photo) => photo.id == photoId); + const size = model.findSize(photo); + mainPage.setFriendAndPhoto(this.user, parseInt(photoId), size.url); + pages.openPage('main'); + } + }); + document.querySelector('.page-profile-back').addEventListener('click', async () => { + await pages.openPage('main'); + }); + document.querySelector('.page-profile-exit').addEventListener('click', async () => { + await model.logout(); + pages.openPage('login'); + }); + }, +}; From 8fa900cac19129f213f86ea335cb5b753e7a1f7f Mon Sep 17 00:00:00 2001 From: lFrodo Date: Tue, 30 May 2023 13:21:52 +0300 Subject: [PATCH 09/11] 6th week loft-photo network --- projects/loft-photo/commentsTemplate.html.hbs | 9 +++ projects/loft-photo/mainpage.js | 69 ++++++++++++++++++- projects/loft-photo/model.js | 43 +++++++++++- projects/loft-photo/profilepage.js | 7 +- projects/loft-photo/server/index.js | 43 ++++++++++-- 5 files changed, 157 insertions(+), 14 deletions(-) create mode 100644 projects/loft-photo/commentsTemplate.html.hbs diff --git a/projects/loft-photo/commentsTemplate.html.hbs b/projects/loft-photo/commentsTemplate.html.hbs new file mode 100644 index 000000000..fd67b84d7 --- /dev/null +++ b/projects/loft-photo/commentsTemplate.html.hbs @@ -0,0 +1,9 @@ +{{#each list}} +
+
+
+
{{name}}
+
{{text}}
+
+
+{{/each}} \ No newline at end of file diff --git a/projects/loft-photo/mainpage.js b/projects/loft-photo/mainpage.js index f842f246f..56c1d891d 100644 --- a/projects/loft-photo/mainpage.js +++ b/projects/loft-photo/mainpage.js @@ -1,26 +1,47 @@ - import model from './model'; import profilePage from './profilepage'; import pages from './pages'; +import commentsTemplate from './commentsTemplate.html.hbs'; + export default { async getNextPhoto() { const { friend, id, url } = await model.getNextPhoto(); - this.setFriendAndPhoto(friend, id, url); + const stats = await model.photoStats(id); + this.setFriendAndPhoto(friend, id, url, stats); }, - setFriendAndPhoto(friend, id, url) { + setFriendAndPhoto(friend, id, url, stats) { const photoComp = document.querySelector('.component-photo'); const headerPhotoComp = document.querySelector('.component-header-photo'); const headerNameComp = document.querySelector('.component-header-name'); const footerPhotoComp = document.querySelector('.component-footer-photo'); this.friend = friend; + this.photoId = id; headerPhotoComp.style.backgroundImage = `url('${friend.photo_50}')`; headerNameComp.innerText = `${friend.first_name ?? ''} ${friend.last_name ?? ''}`; photoComp.style.backgroundImage = `url(${url})`; footerPhotoComp.style.backgroundImage = `url('${model.me.photo_50}')`; + this.setLikes(stats.likes, stats.liked); + this.setComments(stats.comments); + }, + setLikes(total, liked) { + const likes = document.querySelector('.component-footer-container-social-likes'); + likes.innerText = total; + if (liked) { + likes.classList.add('liked'); + } else { + likes.classList.remove('liked'); + } + }, + + setComments(total) { + const comments = document.querySelector( + '.component-footer-container-social-comments' + ); + comments.innerText = total; }, handleEvents() { @@ -49,5 +70,47 @@ export default { await profilePage.setUser(model.me); pages.openPage('profile'); }); + document + .querySelector('.component-footer-container-social-likes') + .addEventListener('click', async () => { + const { likes, liked } = await model.like(this.photoId); + this.setLikes(likes, liked); + }); + document + .querySelector('.component-footer-container-social-comments') + .addEventListener('click', async () => { + document.querySelector('.component-comments').classList.remove('hidden'); + await this.loadComments(this.photoId); + }); + const input = document.querySelector('.component-comments-container-form-input'); + document.querySelector('.component-comments').addEventListener('click', async (e) => { + if (e.target === e.currentTarget) { + document.querySelector('.component-comments').classList.add('hidden'); + } + }); + document + .querySelector('.component-comments-container-form-send') + .addEventListener('click', async () => { + if (input.value.trim().length) { + await model.postComment(this.photoId, input.value.trim()); + input.value = ''; + await this.loadComments(this.photoId); + } + }); + }, + async loadComments(photo) { + const comments = await model.getComments(photo); + const commentsElements = commentsTemplate({ + list: comments.map((comment) => { + return { + name: `${comment.user.first_name ?? ''} ${comment.user.last_name ?? ''}`, + photo: comment.user.photo_50, + text: comment.text, + }; + }), + }); + document.querySelector('.component-comments-container-list').innerHTML = ''; + document.querySelector('.component-comments-container-list').append(commentsElements); + this.setComments(comments.length); }, }; diff --git a/projects/loft-photo/model.js b/projects/loft-photo/model.js index 7313f4117..99cadae65 100644 --- a/projects/loft-photo/model.js +++ b/projects/loft-photo/model.js @@ -53,10 +53,11 @@ export default { login() { return new Promise((resolve, reject) => { VK.init({ - apiId: 51643234, + apiId: 51661177, }); VK.Auth.login((response) => { if (response.session) { + this.token = response.session.sid; resolve(response); } else { console.error(response); @@ -112,4 +113,44 @@ export default { return photos; }, + async callServer(method, queryParams, body) { + queryParams = { + ...queryParams, + method, + }; + const query = Object.entries(queryParams) + .reduce((all, [name, value]) => { + all.push(`${name}=${encodeURIComponent(value)}`); + return all; + }, []) + .join('&'); + const params = { + headers: { + vk_token: this.token, + }, + }; + if (body) { + params.method = 'POST'; + params.body = JSON.stringify(body); + } + + const response = await fetch(`/loft-photo/api/?${query}`, params); + + return response.json(); + }, + async like(photo) { + return this.callServer('like', { photo }); + }, + + async photoStats(photo) { + return this.callServer('photoStats', { photo }); + }, + + async getComments(photo) { + return await this.callServer('getComments', { photo }); + }, + + async postComment(photo, text) { + return await this.callServer('postComment', { photo }, { text }); + }, }; diff --git a/projects/loft-photo/profilepage.js b/projects/loft-photo/profilepage.js index ae98da928..fd70f761d 100644 --- a/projects/loft-photo/profilepage.js +++ b/projects/loft-photo/profilepage.js @@ -2,7 +2,6 @@ import model from './model'; import mainPage from './mainpage'; import pages from './pages'; - export default { async setUser(user) { const photoComp = document.querySelector('.component-user-info-photo'); @@ -16,7 +15,7 @@ export default { for (const photo of photos.items) { const size = model.findSize(photo); - console.log(size); + const element = document.createElement('div'); element.classList.add('component-user-photo'); element.dataset.id = photo.id; @@ -34,7 +33,9 @@ export default { const friendsPhotos = await model.getPhotos(this.user.id); const photo = friendsPhotos.items.find((photo) => photo.id == photoId); const size = model.findSize(photo); - mainPage.setFriendAndPhoto(this.user, parseInt(photoId), size.url); + const stats = await model.photoStats(this.user.id); + mainPage.setFriendAndPhoto(this.user, parseInt(photoId), size.url, stats); + pages.openPage('main'); } }); diff --git a/projects/loft-photo/server/index.js b/projects/loft-photo/server/index.js index e9057c6c4..1ec8bd726 100644 --- a/projects/loft-photo/server/index.js +++ b/projects/loft-photo/server/index.js @@ -10,16 +10,41 @@ const DB = { const methods = { like(req, res, url, vkUser) { - // todo + const photoId = url.searchParams.get('photo'); + let photoLikes = DB.likes.get(photoId); + if (!photoLikes) { + photoLikes = new Map(); + DB.likes.set(photoId, photoLikes); + } + if (photoLikes.get(vkUser.id)) { + photoLikes.delete(vkUser.id); + return { likes: photoLikes.size, liked: false }; + } + photoLikes.set(vkUser.id, true); + return { likes: photoLikes.size, liked: true }; }, photoStats(req, res, url, vkUser) { - // todo + const photoId = url.searchParams.get('photo'); + const photoLikes = DB.likes.get(photoId); + const photoComments = DB.comments.get(photoId); + return { + likes: photoLikes?.size ?? 0, + liked: photoLikes?.has(vkUser.id) ?? false, + comments: photoComments?.length ?? 0, + }; }, postComment(req, res, url, vkUser, body) { - // todo + const photoId = url.searchParams.get('photo'); + let photoComments = DB.comments.get(photoId); + if (!photoComments) { + photoComments = []; + DB.comments.set(photoId, photoComments); + } + photoComments.unshift({ user: vkUser, text: body.text }); }, getComments(req, res, url) { - // todo + const photoId = url.searchParams.get('photo'); + return DB.comments.get(photoId) ?? []; }, }; @@ -30,9 +55,13 @@ http const parsed = new url.URL(req.url, 'http://localhost'); const vkUser = await getMe(token); const body = await readBody(req); - const method = parsed.searchParams.get('method'); - const responseData = await methods[method]?.(req, res, parsed, vkUser, body); - + const responseData = await methods[parsed.searchParams.get('method')]?.( + req, + res, + parsed, + vkUser, + body + ); res.end(JSON.stringify(responseData ?? null)); }) .listen('8888', () => { From 88a264f98b89b3ba951da2e05f95896e4f522357 Mon Sep 17 00:00:00 2001 From: lFrodo Date: Fri, 2 Jun 2023 12:39:33 +0300 Subject: [PATCH 10/11] 7th week loft photo profile features --- projects/loft-photo/layout.html | 5 + projects/loft-photo/mainpage.js | 1 + projects/loft-photo/model.js | 4 +- projects/loft-photo/profilepage.js | 82 +++++- projects/loft-photo/server/index.js | 1 + projects/loft-photo/styles.css | 402 +++++++++++++++------------- 6 files changed, 305 insertions(+), 190 deletions(-) diff --git a/projects/loft-photo/layout.html b/projects/loft-photo/layout.html index 89845cfed..8bb14e8c5 100644 --- a/projects/loft-photo/layout.html +++ b/projects/loft-photo/layout.html @@ -57,7 +57,12 @@ +
+
diff --git a/projects/loft-photo/mainpage.js b/projects/loft-photo/mainpage.js index 56c1d891d..c61d29c54 100644 --- a/projects/loft-photo/mainpage.js +++ b/projects/loft-photo/mainpage.js @@ -62,6 +62,7 @@ export default { .querySelector('.component-header-profile-link') .addEventListener('click', async () => { await profilePage.setUser(this.friend); + pages.openPage('profile'); }); document diff --git a/projects/loft-photo/model.js b/projects/loft-photo/model.js index 99cadae65..d8371043e 100644 --- a/projects/loft-photo/model.js +++ b/projects/loft-photo/model.js @@ -34,6 +34,7 @@ export default { return { friend, id: photo.id, url: size.url }; }, findSize(photo) { + const size = photo.sizes.find((size) => size.width >= 360); // if (!size) { // return photo.sizes.reduce((biggest, current) => { @@ -53,7 +54,7 @@ export default { login() { return new Promise((resolve, reject) => { VK.init({ - apiId: 51661177, + apiId: 51643234, }); VK.Auth.login((response) => { if (response.session) { @@ -143,6 +144,7 @@ export default { }, async photoStats(photo) { + return this.callServer('photoStats', { photo }); }, diff --git a/projects/loft-photo/profilepage.js b/projects/loft-photo/profilepage.js index fd70f761d..682e8656b 100644 --- a/projects/loft-photo/profilepage.js +++ b/projects/loft-photo/profilepage.js @@ -6,16 +6,27 @@ export default { async setUser(user) { const photoComp = document.querySelector('.component-user-info-photo'); const nameComp = document.querySelector('.component-user-info-name'); - const photosComp = document.querySelector('.component-user-photos'); - const photos = await model.getPhotos(user.id); + const photosTab = document.querySelector('.component-profile-node-photos'); + const friendsTab = document.querySelector('.component-profile-node-friends'); + this.user = user; photoComp.style.backgroundImage = `url('${user.photo_100}')`; nameComp.innerText = `${user.first_name ?? ''} ${user.last_name ?? ''}`; - photosComp.innerHTML = ''; + const node = localStorage.getItem('loft-photo-profile-node') ?? '1'; + + if (node === '1') { + photosTab.click(); + } else { + friendsTab.click(); + } + }, + async showPhotos() { + const photosComp = document.querySelector('.component-user-photos'); + const photos = await model.getPhotos(this.user.id); + photosComp.innerHTML = ''; for (const photo of photos.items) { const size = model.findSize(photo); - const element = document.createElement('div'); element.classList.add('component-user-photo'); element.dataset.id = photo.id; @@ -23,6 +34,29 @@ export default { photosComp.append(element); } }, + async showFriends() { + const friendsComp = document.querySelector('.component-user-friends'); + const friends = await model.getFriends(this.user.id); + + friendsComp.innerHTML = ''; + + for (const friend of friends.items) { + const element = document.createElement('div'); + const photoEl = document.createElement('div'); + const nameEl = document.createElement('div'); + + element.classList.add('component-user-friend'); + element.dataset.id = friend.id; + photoEl.classList.add('component-user-friend-photo'); + photoEl.style.backgroundImage = `url(${friend.photo_100})`; + photoEl.dataset.id = friend.id; + nameEl.classList.add('component-user-friend-name'); + nameEl.innerText = `${friend.first_name ?? ''} ${friend.last_name ?? ''}`; + nameEl.dataset.id = friend.id; + element.append(photoEl, nameEl); + friendsComp.append(element); + } + }, handleEvents() { document @@ -33,12 +67,50 @@ export default { const friendsPhotos = await model.getPhotos(this.user.id); const photo = friendsPhotos.items.find((photo) => photo.id == photoId); const size = model.findSize(photo); - const stats = await model.photoStats(this.user.id); + const stats = await model.photoStats(photoId); mainPage.setFriendAndPhoto(this.user, parseInt(photoId), size.url, stats); pages.openPage('main'); } }); + document + .querySelector('.component-profile-node-photos') + .addEventListener('click', (e) => { + const photosComp = document.querySelector('.component-user-photos'); + const friendsComp = document.querySelector('.component-user-friends'); + photosComp.classList.remove('hidden'); + friendsComp.classList.add('hidden'); + + localStorage.setItem('loft-photo-profile-node','1'); + this.showPhotos() + }); + document + .querySelector('.component-profile-node-friends') + .addEventListener('click', (e) => { + const photosComp = document.querySelector('.component-user-photos'); + const friendsComp = document.querySelector('.component-user-friends'); + photosComp.classList.add('hidden'); + friendsComp.classList.remove('hidden'); + + localStorage.setItem('loft-photo-profile-node','1'); + this.showFriends() + }); + document.querySelector('.component-user-friends') + .addEventListener('click',async (e)=>{ + const friendId = e.target.dataset.id + if(friendId){ + const [friend] = await model.getUsers([friendId]); + const friendsPhotos = await model.getPhotos(friendId) + const photo = await model.getRandomElement(friendsPhotos.items) + const size = await model.findSize(photo); + const photoStats = await model.photoStats(photo.id) + mainPage.setFriendAndPhoto(friend,parseInt(photo.id),size.url,photoStats) + pages.openPage('main') + } + + + + }) document.querySelector('.page-profile-back').addEventListener('click', async () => { await pages.openPage('main'); }); diff --git a/projects/loft-photo/server/index.js b/projects/loft-photo/server/index.js index 1ec8bd726..159bedc0c 100644 --- a/projects/loft-photo/server/index.js +++ b/projects/loft-photo/server/index.js @@ -24,6 +24,7 @@ const methods = { return { likes: photoLikes.size, liked: true }; }, photoStats(req, res, url, vkUser) { + const photoId = url.searchParams.get('photo'); const photoLikes = DB.likes.get(photoId); const photoComments = DB.comments.get(photoId); diff --git a/projects/loft-photo/styles.css b/projects/loft-photo/styles.css index 62d5fba21..a4dbc2eeb 100644 --- a/projects/loft-photo/styles.css +++ b/projects/loft-photo/styles.css @@ -1,348 +1,382 @@ /* base */ body { - font-family: "Roboto Light", Geneva, Arial, Helvetica, sans-serif; + font-family: 'Roboto Light', Geneva, Arial, Helvetica, sans-serif; } .hidden { - display: none !important; + display: none !important; } a { - text-decoration: none; + text-decoration: none; } /* app */ #app { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - display: flex; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: flex; - align-items: center; - justify-content: center; + align-items: center; + justify-content: center; } .page { - height: 100%; - width: 360px; - position: relative; + height: 100%; + width: 360px; + position: relative; } /* page login */ .page-login { - display: flex; - justify-content: center; - background: #1C1B1F; + display: flex; + justify-content: center; + background: #1c1b1f; } .page-login-button { - border: none; - background: url('images/button.svg'); - width: 219px; - height: 40px; - position: absolute; - bottom: 60px; - margin: 0 auto; + border: none; + background: url('images/button.svg'); + width: 219px; + height: 40px; + position: absolute; + bottom: 60px; + margin: 0 auto; } .page-login-logo { - top: 429px; - position: absolute; - gap: 16px; - display: flex; - flex-direction: column; - align-items: center; + top: 429px; + position: absolute; + gap: 16px; + display: flex; + flex-direction: column; + align-items: center; } .page-login-image { - width: 147px; - height: 24px; - background: url('images/logo.svg'); + width: 147px; + height: 24px; + background: url('images/logo.svg'); } .page-login-text { - font-size: 14px; - line-height: 20px; - text-align: center; - width: 237px; - color: #B0B0B0; + font-size: 14px; + line-height: 20px; + text-align: center; + width: 237px; + color: #b0b0b0; } -.page-login-vert1, .page-login-vert2, .page-login-vert3 { - width: 71px; - height: 333px; - position: absolute; +.page-login-vert1, +.page-login-vert2, +.page-login-vert3 { + width: 71px; + height: 333px; + position: absolute; } .page-login-vert1 { - top: 59px; - left: 49px; - background: linear-gradient(180deg, rgba(28, 27, 31, 0) 80%, #1C1B1F 100%), url('images/vert1.svg'); + top: 59px; + left: 49px; + background: linear-gradient(180deg, rgba(28, 27, 31, 0) 80%, #1c1b1f 100%), + url('images/vert1.svg'); } .page-login-vert2 { - top: 81px; - left: 144px; - background: linear-gradient(180deg, rgba(28, 27, 31, 0) 80%, #1C1B1F 100%), url('images/vert2.svg'); + top: 81px; + left: 144px; + background: linear-gradient(180deg, rgba(28, 27, 31, 0) 80%, #1c1b1f 100%), + url('images/vert2.svg'); } .page-login-vert3 { - top: 59px; - left: 239px; - background: linear-gradient(180deg, rgba(28, 27, 31, 0) 80%, #1C1B1F 100%), url('images/vert3.svg'); + top: 59px; + left: 239px; + background: linear-gradient(180deg, rgba(28, 27, 31, 0) 80%, #1c1b1f 100%), + url('images/vert3.svg'); } /* page main */ .page-main .component-header { - position: absolute; - display: flex; - height: 80px; - top: 0; - left: 0; - right: 0; - background: rgba(0 0 0 / 25%); - padding: 0 24px; + position: absolute; + display: flex; + height: 80px; + top: 0; + left: 0; + right: 0; + background: rgba(0 0 0 / 25%); + padding: 0 24px; } .page-main .component-header-profile-link { - display: flex; - align-items: center; + display: flex; + align-items: center; } .page-main .component-header-photo { - width: 40px; - height: 40px; - border-radius: 50%; - flex-shrink: 0; + width: 40px; + height: 40px; + border-radius: 50%; + flex-shrink: 0; } .page-main .component-header-name { - margin-left: 8px; - font-weight: 400; - font-size: 16px; - color: white; + margin-left: 8px; + font-weight: 400; + font-size: 16px; + color: white; } .page-main .component-footer { - position: absolute; - display: flex; - height: 80px; - bottom: 0; - left: 0; - right: 0; - background: rgba(0 0 0 / 25%); - padding: 0 24px; + position: absolute; + display: flex; + height: 80px; + bottom: 0; + left: 0; + right: 0; + background: rgba(0 0 0 / 25%); + padding: 0 24px; } .page-main .component-footer-container { - display: flex; - align-items: center; - width: 100%; + display: flex; + align-items: center; + width: 100%; } .page-main .component-footer-container-profile-link { - margin-left: auto; + margin-left: auto; } .page-main .component-footer-photo { - width: 40px; - height: 40px; - border-radius: 50%; + width: 40px; + height: 40px; + border-radius: 50%; } .page-main .component-footer-container-social-comments, .page-main .component-footer-container-social-likes { - color: white; - display: flex; - align-items: center; + color: white; + display: flex; + align-items: center; } .page-main .component-footer-container-social-comments:before, .page-main .component-footer-container-social-likes:before { - display: inline-block; - content: ''; - width: 20px; - height: 20px; - margin-right: 6px; + display: inline-block; + content: ''; + width: 20px; + height: 20px; + margin-right: 6px; } .page-main .component-footer-container-social-comments:before { - background: url("images/chat.svg"); + background: url('images/chat.svg'); } .page-main .component-footer-container-social-likes:before { - background: url("images/heart.svg"); - margin-left: 18px; + background: url('images/heart.svg'); + margin-left: 18px; } .page-main .component-footer-container-social-likes.liked:before { - background: url("images/heart-red.svg"); - margin-left: 18px; + background: url('images/heart-red.svg'); + margin-left: 18px; } .page-main .component-photo { - height: 100%; - width: 360px; - position: relative; + height: 100%; + width: 360px; + position: relative; - background-size: cover; - background-position: center; + background-size: cover; + background-position: center; } .component-comments { - position: fixed; - bottom: 0; - left: 0; - right: 0; - top: 0; - background: rgba(0, 0, 0, 0.4); + position: fixed; + bottom: 0; + left: 0; + right: 0; + top: 0; + background: rgba(0, 0, 0, 0.4); } .component-comments-container { - position: absolute; - display: flex; - flex-direction: column; - top: 50vh; - bottom: 0; - left: 0; - right: 0; - padding: 16px; - border-radius: 28px 28px 0 0; - background: white; + position: absolute; + display: flex; + flex-direction: column; + top: 50vh; + bottom: 0; + left: 0; + right: 0; + padding: 16px; + border-radius: 28px 28px 0 0; + background: white; } .component-comments-container-title { - font-size: 14px; - text-align: center; - width: 100%; + font-size: 14px; + text-align: center; + width: 100%; } .component-comments-container-list { - margin-top: 24px; - flex-grow: 1; - display: flex; - gap: 12px; - flex-direction: column; - overflow-y: auto; - margin-bottom: 14px + margin-top: 24px; + flex-grow: 1; + display: flex; + gap: 12px; + flex-direction: column; + overflow-y: auto; + margin-bottom: 14px; } .component-comments-container-form { - display: flex; - align-items: center; - gap: 16px; - height: 48px; + display: flex; + align-items: center; + gap: 16px; + height: 48px; } .component-comments-container-form-input { - box-sizing: border-box; - border: 1px solid #E0E0E0; - border-radius: 32px; - flex-grow: 1; - height: 48px; + box-sizing: border-box; + border: 1px solid #e0e0e0; + border-radius: 32px; + flex-grow: 1; + height: 48px; } .component-comments-container-form-input, .component-comments-container-form-input, .component-comments-container-form-input, .component-comments-container-form-input { - padding: 14px 16px; + padding: 14px 16px; } .component-comments-container-form-send { - background: url('images/send.svg'); - width: 40px; - height: 40px; + background: url('images/send.svg'); + width: 40px; + height: 40px; } .component-comment { - display: flex; - gap: 8px + display: flex; + gap: 8px; } .component-comment-photo { - width: 24px; - height: 24px; - border-radius: 50%; - background-position: center; - background-size: cover; + width: 24px; + height: 24px; + border-radius: 50%; + background-position: center; + background-size: cover; } .component-comment-content { - flex-direction: column; + flex-direction: column; } .component-comment-name { - font-size: 12px; + font-size: 12px; } .component-comment-text { - font-size: 14px; + font-size: 14px; } /* page profile */ .page-profile { - margin-top: 52px; + margin-top: 52px; } .page-profile-back { - background: url('images/arrow-left.svg'); - width: 24px; - height: 24px; + background: url('images/arrow-left.svg'); + width: 24px; + height: 24px; - position: absolute; - left: 24px; + position: absolute; + left: 24px; } .page-profile-exit { - background: url('images/exit.svg'); - width: 24px; - height: 24px; + background: url('images/exit.svg'); + width: 24px; + height: 24px; - position: absolute; - right: 24px; + position: absolute; + right: 24px; } .component-user-photos { - display: flex; - flex-wrap: wrap; - gap: 8px; - padding: 24px 16px 16px 16px; + display: flex; + flex-wrap: wrap; + gap: 8px; + padding: 24px 16px 16px 16px; } .component-user-photo { - width: 104px; - height: 104px; - background-size: cover; - background-repeat: no-repeat; - background-position: center; + width: 104px; + height: 104px; + background-size: cover; + background-repeat: no-repeat; + background-position: center; } .page-profile .component-user-info { - display: flex; - flex-direction: column; - align-items: center; + display: flex; + flex-direction: column; + align-items: center; } .page-profile .component-user-info-photo { - height: 72px; - width: 72px; - border-radius: 50%; + height: 72px; + width: 72px; + border-radius: 50%; - background-size: cover; - background-position: center; + background-size: cover; + background-position: center; } .page-profile .component-user-info-name { - font-weight: 400; - font-size: 18px; - line-height: 26px; - margin-top: 8px; -} \ No newline at end of file + font-weight: 400; + font-size: 18px; + line-height: 26px; + margin-top: 8px; +} +.component-profile-node { + display: flex; + justify-content: center; + text-decoration: underline; + margin-bottom: 20px; +} +.component-profile-node-photos { + margin-right: 10px; +} +.component-user-friend { + margin-right: 15px; + cursor: pointer; +} +.component-user-friends { + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; +} +.component-user-friend-name { + text-align: center; + width: 100px; + margin-bottom: 20px; +} +.component-user-friend-photo { + width: 100px; + height: 100px; + border-radius: 50%; +} From 32386ea0d410a72d6245c7c98d14e4e88764d8a1 Mon Sep 17 00:00:00 2001 From: lFrodo Date: Fri, 2 Jun 2023 12:40:27 +0300 Subject: [PATCH 11/11] 7th week loft photo profile features --- projects/loft-photo/model.js | 2 -- projects/loft-photo/profilepage.js | 34 ++++++++++++++--------------- projects/loft-photo/server/index.js | 1 - 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/projects/loft-photo/model.js b/projects/loft-photo/model.js index d8371043e..f0431a29b 100644 --- a/projects/loft-photo/model.js +++ b/projects/loft-photo/model.js @@ -34,7 +34,6 @@ export default { return { friend, id: photo.id, url: size.url }; }, findSize(photo) { - const size = photo.sizes.find((size) => size.width >= 360); // if (!size) { // return photo.sizes.reduce((biggest, current) => { @@ -144,7 +143,6 @@ export default { }, async photoStats(photo) { - return this.callServer('photoStats', { photo }); }, diff --git a/projects/loft-photo/profilepage.js b/projects/loft-photo/profilepage.js index 682e8656b..e14ca6a19 100644 --- a/projects/loft-photo/profilepage.js +++ b/projects/loft-photo/profilepage.js @@ -81,10 +81,10 @@ export default { photosComp.classList.remove('hidden'); friendsComp.classList.add('hidden'); - localStorage.setItem('loft-photo-profile-node','1'); - this.showPhotos() + localStorage.setItem('loft-photo-profile-node', '1'); + this.showPhotos(); }); - document + document .querySelector('.component-profile-node-friends') .addEventListener('click', (e) => { const photosComp = document.querySelector('.component-user-photos'); @@ -92,25 +92,23 @@ export default { photosComp.classList.add('hidden'); friendsComp.classList.remove('hidden'); - localStorage.setItem('loft-photo-profile-node','1'); - this.showFriends() + localStorage.setItem('loft-photo-profile-node', '1'); + this.showFriends(); }); - document.querySelector('.component-user-friends') - .addEventListener('click',async (e)=>{ - const friendId = e.target.dataset.id - if(friendId){ + document + .querySelector('.component-user-friends') + .addEventListener('click', async (e) => { + const friendId = e.target.dataset.id; + if (friendId) { const [friend] = await model.getUsers([friendId]); - const friendsPhotos = await model.getPhotos(friendId) - const photo = await model.getRandomElement(friendsPhotos.items) + const friendsPhotos = await model.getPhotos(friendId); + const photo = await model.getRandomElement(friendsPhotos.items); const size = await model.findSize(photo); - const photoStats = await model.photoStats(photo.id) - mainPage.setFriendAndPhoto(friend,parseInt(photo.id),size.url,photoStats) - pages.openPage('main') + const photoStats = await model.photoStats(photo.id); + mainPage.setFriendAndPhoto(friend, parseInt(photo.id), size.url, photoStats); + pages.openPage('main'); } - - - - }) + }); document.querySelector('.page-profile-back').addEventListener('click', async () => { await pages.openPage('main'); }); diff --git a/projects/loft-photo/server/index.js b/projects/loft-photo/server/index.js index 159bedc0c..1ec8bd726 100644 --- a/projects/loft-photo/server/index.js +++ b/projects/loft-photo/server/index.js @@ -24,7 +24,6 @@ const methods = { return { likes: photoLikes.size, liked: true }; }, photoStats(req, res, url, vkUser) { - const photoId = url.searchParams.get('photo'); const photoLikes = DB.likes.get(photoId); const photoComments = DB.comments.get(photoId);