Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Konstantin-Gromakovskiy committed Nov 27, 2024
1 parent 5e9fbc8 commit 0099ccd
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 87 deletions.
7 changes: 7 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"bootstrap": "^5.3.3",
"globals": "^15.12.0",
"i18next": "^23.16.5",
"lodash.uniqueid": "^4.0.1",
"on-change": "^5.0.1",
"yup": "^1.4.0"
}
}
}
26 changes: 8 additions & 18 deletions src/logic/domParser.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,23 @@
export default (document, addedPosts) => {
export default (document) => {
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(document, 'text/xml');
if (xmlDoc.querySelector('parsererror')) throw new Error('its not rss');
const feed = {};

const channelTitle = xmlDoc.querySelector('channel > title').textContent.replace(/((<!)?\[CDATA\[)| ?(\]\]>?$)/mg, '');
const channelTitle = xmlDoc.querySelector('channel > title').textContent;
const channelDescription = xmlDoc.querySelector('channel > description') ? xmlDoc.querySelector('channel > description').textContent : '';
const channelLink = xmlDoc.querySelector('channel > link').textContent;
feed.title = channelTitle;
feed.description = channelDescription;
feed.link = channelLink;

const items = xmlDoc.querySelectorAll('item');
const itemsArr = Array.from(items);
const newPostsElems = itemsArr;

const posts = newPostsElems.map((item, index) => {
const title = item.querySelector('title');
const description = item.querySelector('description') ? item.querySelector('description').textContent : '';
const link = item.querySelector('link');
const pubDate = item.querySelector('pubDate');
const postId = addedPosts.length + index;
const newPostsElems = Array.from(items);

const posts = newPostsElems.map((item) => {
const post = {
title: title.textContent.replace(/((<!)?\[CDATA\[)| ?(\]\]>?$)/mg, ''),
description: description.replace(/((<!)?\[CDATA\[)| ?(\]\]>?$)/mg, ''),
link: link.textContent,
pubDate: pubDate.textContent,
id: postId,
title: item.querySelector('title').textContent,
description: item.querySelector('description') ? item.querySelector('description').textContent : '',
link: item.querySelector('link').textContent,
pubDate: item.querySelector('pubDate').textContent,
};
return post;
});
Expand Down
129 changes: 62 additions & 67 deletions src/logic/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as yup from 'yup';
import onChange from 'on-change';
import i18next from 'i18next';
import axios from 'axios';
import uniqueId from 'lodash.uniqueid';
import render from './render/mainRender.js';
import resources from '../i18next/resources.js';
import domParser from './domParser.js';
Expand Down Expand Up @@ -37,83 +38,77 @@ const app = () => {
i18n.init({
lng: 'ru',
resources,
})
.then(() => {
const state = onChange(initialState, render(elements, initialState));
}).then(() => {
const state = onChange(initialState, render(elements, initialState));

const interval = (f, timer) => {
setTimeout(() => {
Promise.resolve().then(() => f())
.then(() => interval(f, timer));
}, timer);
};
const reWritePosts = () => {
const interval = () => {
setTimeout(() => {
const addedResources = state.feeds.map((feed) => feed.resource);
if (addedResources.length === 0) return;
const requests = addedResources
.map((resource) => {
const resourceWithProxy = addProxy(resource);
return axios.get(resourceWithProxy)
.then((request) => domParser(request.data, state.posts))
.catch((error) => {
throw error;
});
});
Promise.all(requests).then((results) => {
const allPosts = results.flatMap(({ posts }) => posts);
const allPostsWithId = allPosts
.map((post, index) => ({ ...post, id: state.posts.length + index }));
const newPosts = allPostsWithId
.filter((post) => !state.posts.find((addedPost) => addedPost.link === post.link));
state.posts = [...newPosts, ...state.posts];
})
if (addedResources.length === 0) return interval();
const requests = addedResources.map((resource) => {
const resourceWithProxy = addProxy(resource);
return axios.get(resourceWithProxy)
.then((request) => domParser(request.data))
.catch((error) => {
throw error;
});
});
return Promise.all(requests)
.then((results) => {
const allPosts = results.flatMap(({ posts }) => posts);
const newPosts = allPosts
.filter((post) => !state.posts.find((addedPost) => addedPost.link === post.link));
const newPostsWithId = newPosts.map((post) => ({ ...post, id: uniqueId() }));
state.posts = [...newPostsWithId, ...state.posts];
})
.catch((error) => {
state.errors = i18n.t(error.message);
});
};
})
.then(() => interval());
}, 5000);
};

interval(reWritePosts, 5000);
interval();

elements.form.addEventListener('submit', (event) => {
event.preventDefault();
const formData = new FormData(event.target);
const url = formData.get('url');
const addedResources = state.feeds.map((feed) => feed.resource);
const urlSchema = yup.string().url().notOneOf(addedResources);
elements.form.addEventListener('submit', (event) => {
event.preventDefault();
const formData = new FormData(event.target);
const url = formData.get('url');
const urlSchema = yup.string().url().notOneOf(state.feeds.map((feed) => feed.resource));

urlSchema.validate(url)
.then(() => {
state.processing = 'sending';
state.errors = '';
const urlWithProxy = addProxy(url);
return axios.get(urlWithProxy);
})
.then((response) => {
const { feed, posts } = domParser(response.data, state.posts);
feed.resource = url;
feed.id = state.feeds.length;
state.feeds = [feed, ...state.feeds];
const newPostsWithId = posts
.map((post, index) => ({ ...post, id: state.posts.length + index }));
state.posts = [...newPostsWithId, ...state.posts];
state.processing = 'filling';
})
.catch((error) => {
state.processing = 'editing';
state.errors = error.name === 'ValidationError' ? i18n.t(error.type) : i18n.t(error.message);
});
});
urlSchema.validate(url)
.then(() => {
state.processing = 'sending';
state.errors = '';
const urlWithProxy = addProxy(url);
return axios.get(urlWithProxy);
})
.then((response) => {
const { feed, posts } = domParser(response.data);
feed.resource = url;
feed.id = state.feeds.length;
state.feeds = [feed, ...state.feeds];
const newPostsWithId = posts
.map((post) => ({ ...post, id: uniqueId() }));
state.posts = [...newPostsWithId, ...state.posts];
state.processing = 'filling';
})
.catch((error) => {
state.processing = 'editing';
state.errors = error.name === 'ValidationError' ? i18n.t(error.type) : i18n.t(error.message);
});
});

elements.postsContainer.addEventListener('click', (event) => {
if (!event.target.dataset.id) return;
const postId = Number(event.target.dataset.id);
state.viewedPostId = postId;
elements.postsContainer.addEventListener('click', (event) => {
if (!event.target.dataset.id) return;
const postId = Number(event.target.dataset.id);
state.viewedPostId = postId;

if (event.target.type === 'button') {
state.openedPostId = postId;
}
});
if (event.target.type === 'button') {
state.openedPostId = postId;
}
});
});
};

export default app;
2 changes: 1 addition & 1 deletion src/logic/render/mainRender.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default (elements, state) => (path, value, previousValue) => {
renderReadPost(value, elements.postsContainer);
break;
case 'openedPostId': {
const clickedPost = state.posts.find((post) => post.id === value);
const clickedPost = state.posts.find((post) => Number(post.id) === value);
putPostInModal(clickedPost, elements.modalContainer);
break;
}
Expand Down

0 comments on commit 0099ccd

Please sign in to comment.