|
@@ -26,6 +26,14 @@
|
|
.join('&');
|
|
.join('&');
|
|
|
|
|
|
let url = '/article/page?' + query;
|
|
let url = '/article/page?' + query;
|
|
|
|
+
|
|
|
|
+ function selectFeed() {
|
|
|
|
+ if ("${ssIsLogin}" === 'true') {
|
|
|
|
+ return 'your-feed'
|
|
|
|
+ } else {
|
|
|
|
+ return 'global-feed';
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
// 1. feed를 바꾼 경우
|
|
// 1. feed를 바꾼 경우
|
|
// 2. 태그를 클릭한 경우
|
|
// 2. 태그를 클릭한 경우
|
|
@@ -47,7 +55,7 @@
|
|
} else if (clickedTag !== undefined) { // 태그가 클릭된 경우
|
|
} else if (clickedTag !== undefined) { // 태그가 클릭된 경우
|
|
const tags = article.querySelectorAll('.tag');
|
|
const tags = article.querySelectorAll('.tag');
|
|
const tagSet = new Set(Array.from(tags).map(tag => tag.textContent));
|
|
const tagSet = new Set(Array.from(tags).map(tag => tag.textContent));
|
|
-
|
|
|
|
|
|
+
|
|
if (targetFeed.id === 'global-feed' && tagSet.has(clickedTag)) {
|
|
if (targetFeed.id === 'global-feed' && tagSet.has(clickedTag)) {
|
|
display = 'block';
|
|
display = 'block';
|
|
}
|
|
}
|
|
@@ -97,6 +105,7 @@
|
|
targetFeed = unFocusedFeed;
|
|
targetFeed = unFocusedFeed;
|
|
setLoading('on');
|
|
setLoading('on');
|
|
|
|
|
|
|
|
+ // 태그와 게시글 초기화
|
|
tagArray = [];
|
|
tagArray = [];
|
|
articleList = document.querySelector('#article-list');
|
|
articleList = document.querySelector('#article-list');
|
|
while(articleList.firstChild) {
|
|
while(articleList.firstChild) {
|
|
@@ -104,12 +113,11 @@
|
|
}
|
|
}
|
|
|
|
|
|
params['articleId'] = -1;
|
|
params['articleId'] = -1;
|
|
- params['feed'] = unFocusedFeed.id;
|
|
|
|
|
|
+ params['feed'] = targetFeed.id;
|
|
|
|
|
|
query = Object.keys(params)
|
|
query = Object.keys(params)
|
|
.map(key => encodeURIComponent(key) + '=' + encodeURIComponent(params[key]))
|
|
.map(key => encodeURIComponent(key) + '=' + encodeURIComponent(params[key]))
|
|
.join('&');
|
|
.join('&');
|
|
-
|
|
|
|
url = '/article/page?' + query;
|
|
url = '/article/page?' + query;
|
|
|
|
|
|
fetch(url, options)
|
|
fetch(url, options)
|
|
@@ -119,8 +127,7 @@
|
|
username = "${ssUsername}";
|
|
username = "${ssUsername}";
|
|
|
|
|
|
loadArticle(articles);
|
|
loadArticle(articles);
|
|
- document.addEventListener("scroll", nextPageLoad(articles, paging));
|
|
|
|
- // nextPageLoad(articles, paging);
|
|
|
|
|
|
+ nextPageLoad(articles, paging);
|
|
});
|
|
});
|
|
|
|
|
|
filterArticle({ 'clickedFeed': unFocusedFeed.id })
|
|
filterArticle({ 'clickedFeed': unFocusedFeed.id })
|
|
@@ -129,63 +136,68 @@
|
|
}, 2000);
|
|
}, 2000);
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
|
|
+ // 좋아요 버튼
|
|
function favoriteBtn(indexNumber) {
|
|
function favoriteBtn(indexNumber) {
|
|
const favoriteNum = event.target.querySelector('.count').textContent;
|
|
const favoriteNum = event.target.querySelector('.count').textContent;
|
|
|
|
+ const favorite = event.target.querySelector('.favorite-btn');
|
|
let counts = parseInt(favoriteNum);
|
|
let counts = parseInt(favoriteNum);
|
|
let newCounts = counts + 1;
|
|
let newCounts = counts + 1;
|
|
|
|
+ console.log(event.target);
|
|
|
|
|
|
- const favBtn = document.querySelectorAll('.favorite-btn');
|
|
|
|
|
|
+ // 로그인한 경우에만 실행
|
|
if ("${ssIsLogin}" === "true") {
|
|
if ("${ssIsLogin}" === "true") {
|
|
- favBtn.forEach(value => {
|
|
|
|
- if (value.classList.contains(indexNumber)) {
|
|
|
|
- if(event.target.classList.contains('active')){
|
|
|
|
- event.target.querySelector('.count').textContent = counts - 1;
|
|
|
|
-
|
|
|
|
- fetch('/article/' + indexNumber + '/favorite', { method: 'DELETE' })
|
|
|
|
- .then(response => {
|
|
|
|
- if(response.status === 200) {
|
|
|
|
- return value.classList.remove('active');
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- } else {
|
|
|
|
- event.target.querySelector('.count').textContent = newCounts;
|
|
|
|
-
|
|
|
|
- fetch('/article/'+ indexNumber + '/favorite', {
|
|
|
|
- body: JSON.stringify({
|
|
|
|
- articleId: indexNumber,
|
|
|
|
- userId: "${ssId}",
|
|
|
|
- created: new Date()
|
|
|
|
- }),
|
|
|
|
- method: 'POST',
|
|
|
|
- headers: {
|
|
|
|
- "Content-Type": "application/json"
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
- .then(response => {
|
|
|
|
- if(response.status === 201){
|
|
|
|
- return value.classList.add('active');
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
|
|
+ if (event.target.classList.contains('active')) { // 이미 좋아요 버튼을 클릭한 경우
|
|
|
|
+ event.target.querySelector('.count').textContent = counts - 1;
|
|
|
|
+ event.target.classList.remove('active');
|
|
|
|
+
|
|
|
|
+ fetch('/article/' + indexNumber + '/favorite', { method: 'DELETE' })
|
|
|
|
+ .then(response => {
|
|
|
|
+ if (response.status === 200) {
|
|
|
|
+ return ;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ } else { // 좋아요 버튼을 클릭하지 않을 경우
|
|
|
|
+ event.target.querySelector('.count').textContent = newCounts;
|
|
|
|
+ event.target.classList.add('active')
|
|
|
|
+
|
|
|
|
+ fetch('/article/' + indexNumber + '/favorite', {
|
|
|
|
+ body: JSON.stringify({
|
|
|
|
+ articleId: indexNumber,
|
|
|
|
+ userId: "${ssId}",
|
|
|
|
+ created: new Date()
|
|
|
|
+ }),
|
|
|
|
+ method: 'POST',
|
|
|
|
+ headers: {
|
|
|
|
+ "Content-Type": "application/json"
|
|
}
|
|
}
|
|
- }
|
|
|
|
- });
|
|
|
|
|
|
+ })
|
|
|
|
+ .then(response => {
|
|
|
|
+ if (response.status === 201) {
|
|
|
|
+ return ;
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
} else {
|
|
} else {
|
|
location.href = "/user/signin"
|
|
location.href = "/user/signin"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // 태그 정렬 https://curryyou.tistory.com/229
|
|
function getSortedArr(array) {
|
|
function getSortedArr(array) {
|
|
|
|
+ // 출현 빈도 구하기
|
|
const counts = array.reduce((pv, cv) => {
|
|
const counts = array.reduce((pv, cv) => {
|
|
pv[cv] = (pv[cv] || 0) + 1;
|
|
pv[cv] = (pv[cv] || 0) + 1;
|
|
return pv;
|
|
return pv;
|
|
}, {});
|
|
}, {});
|
|
|
|
|
|
|
|
+ // 배열 생성 => [ [ key: 개수 ], [ key: 개수 ], ...]
|
|
const result = [];
|
|
const result = [];
|
|
for (let key in counts) {
|
|
for (let key in counts) {
|
|
result.push([key, counts[key]]);
|
|
result.push([key, counts[key]]);
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ // 빈도별로 정렬
|
|
result.sort((first, second) => {
|
|
result.sort((first, second) => {
|
|
return second[1] - first[1];
|
|
return second[1] - first[1];
|
|
});
|
|
});
|
|
@@ -193,28 +205,23 @@
|
|
return result.slice(0, 10);
|
|
return result.slice(0, 10);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // 클릭한 태그 표시
|
|
function tagFilter(event) {
|
|
function tagFilter(event) {
|
|
let currentValue = document.querySelector('.tag.active');
|
|
let currentValue = document.querySelector('.tag.active');
|
|
|
|
+
|
|
if (currentValue !== null) {
|
|
if (currentValue !== null) {
|
|
- currentValue.classList.remove('active');
|
|
|
|
|
|
+ currentValue.classList.remove('active');
|
|
}
|
|
}
|
|
event.target.classList.add('active');
|
|
event.target.classList.add('active');
|
|
}
|
|
}
|
|
|
|
|
|
- function selectFeed() {
|
|
|
|
- if ("${ssIsLogin}" === 'true') {
|
|
|
|
- return 'your-feed'
|
|
|
|
- } else {
|
|
|
|
- return 'global-feed';
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //게시글 표시
|
|
|
|
|
|
+ // 게시글 및 태그 표시
|
|
function loadArticle(articles) {
|
|
function loadArticle(articles) {
|
|
articles.forEach(article => {
|
|
articles.forEach(article => {
|
|
console.log(JSON.stringify(article))
|
|
console.log(JSON.stringify(article))
|
|
const domParser = new DOMParser();
|
|
const domParser = new DOMParser();
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ // 게시글 정보 표시
|
|
const domStrArticleMeta =
|
|
const domStrArticleMeta =
|
|
`
|
|
`
|
|
<div class="article-meta">
|
|
<div class="article-meta">
|
|
@@ -243,6 +250,7 @@
|
|
divArticleMeta.querySelector('.favorite-btn').classList.add('active');
|
|
divArticleMeta.querySelector('.favorite-btn').classList.add('active');
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // 게시글 내용 및 게시글태그 표시
|
|
const domStrPreviewLink =
|
|
const domStrPreviewLink =
|
|
`
|
|
`
|
|
<a href="/article/\${article.id}" class="preview-link">
|
|
<a href="/article/\${article.id}" class="preview-link">
|
|
@@ -286,9 +294,8 @@
|
|
|
|
|
|
articleList.appendChild(articlePreview);
|
|
articleList.appendChild(articlePreview);
|
|
|
|
|
|
- //태그 배열 생성
|
|
|
|
- let tagsArray = article.tags.split(',')
|
|
|
|
-
|
|
|
|
|
|
+ // 태그 배열 생성
|
|
|
|
+ let tagsArray = article.tags.split(',')
|
|
const tagList = document.querySelector('#tag-list');
|
|
const tagList = document.querySelector('#tag-list');
|
|
|
|
|
|
while(tagList.firstChild) {
|
|
while(tagList.firstChild) {
|
|
@@ -303,7 +310,7 @@
|
|
})
|
|
})
|
|
});
|
|
});
|
|
|
|
|
|
- //태그 정렬
|
|
|
|
|
|
+ // 태그 표시
|
|
const tags = Array.from(tagSet);
|
|
const tags = Array.from(tagSet);
|
|
const tagList = window.document.querySelector('#tag-list');
|
|
const tagList = window.document.querySelector('#tag-list');
|
|
|
|
|
|
@@ -316,6 +323,11 @@
|
|
a.classList.add("tag");
|
|
a.classList.add("tag");
|
|
a.textContent = `\${tagValue} (\${tagCount})`
|
|
a.textContent = `\${tagValue} (\${tagCount})`
|
|
a.onclick = (event) => {
|
|
a.onclick = (event) => {
|
|
|
|
+ // 해당 태그의 토글버튼 생성
|
|
|
|
+ const tagToggle = document.querySelector('#tag-feed');
|
|
|
|
+ tagToggle.textContent = tagValue;
|
|
|
|
+
|
|
|
|
+ // 해당 태그의 게시물 표시
|
|
filterArticle({ 'clickedTag': tagValue });
|
|
filterArticle({ 'clickedTag': tagValue });
|
|
}
|
|
}
|
|
tagList.appendChild(a);
|
|
tagList.appendChild(a);
|
|
@@ -329,18 +341,21 @@
|
|
const articleList = document.querySelector('#article-list');
|
|
const articleList = document.querySelector('#article-list');
|
|
const loading = document.createElement('div');
|
|
const loading = document.createElement('div');
|
|
|
|
|
|
- moreButton.textContent = 'More';
|
|
|
|
|
|
+ moreButton.textContent = '더보기';
|
|
moreButton.classList.add('more-button');
|
|
moreButton.classList.add('more-button');
|
|
loading.setAttribute('id', 'loading');
|
|
loading.setAttribute('id', 'loading');
|
|
articleList.appendChild(moreButton);
|
|
articleList.appendChild(moreButton);
|
|
|
|
+
|
|
|
|
+ // more 버튼 클릭 시 다음페이지 게시물을 가져온다
|
|
moreButton.onclick = () => {
|
|
moreButton.onclick = () => {
|
|
articleList.removeChild(moreButton);
|
|
articleList.removeChild(moreButton);
|
|
articleList.appendChild(loading);
|
|
articleList.appendChild(loading);
|
|
|
|
+
|
|
|
|
+ // 마지막 게시글의 id
|
|
params['articleId'] = articles[articles.length - 1].id;
|
|
params['articleId'] = articles[articles.length - 1].id;
|
|
query = Object.keys(params)
|
|
query = Object.keys(params)
|
|
.map(key => encodeURIComponent(key) + '=' + encodeURIComponent(params[key]))
|
|
.map(key => encodeURIComponent(key) + '=' + encodeURIComponent(params[key]))
|
|
.join('&');
|
|
.join('&');
|
|
-
|
|
|
|
url = '/article/page?' + query;
|
|
url = '/article/page?' + query;
|
|
|
|
|
|
fetch(url, options)
|
|
fetch(url, options)
|
|
@@ -445,6 +460,9 @@
|
|
<a href="javascript:void(0);" onclick="focusFeed()">Global
|
|
<a href="javascript:void(0);" onclick="focusFeed()">Global
|
|
Feed</a>
|
|
Feed</a>
|
|
</li>
|
|
</li>
|
|
|
|
+ <li id="tag-feed" class="nav-item">
|
|
|
|
+ <a href="javascript:void(0);"></a>
|
|
|
|
+ </li>
|
|
</ul>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
|