packages/article-feedback/public/backend.js (149 lines of code) (raw):
function getFeedback(ctx) {
return JSON.parse(ctx.article.extensionProperties.feedback) ?? [];
}
function getGuestFeedback(ctx) {
return JSON.parse(ctx.article.extensionProperties.guestFeedback) ?? [];
}
function getGuestLikes(ctx) {
return Number(JSON.parse(ctx.article.extensionProperties.guestLikes) ?? 0);
}
function isGuest(ctx) {
return ctx.currentUser.login === 'guest';
}
function getUserId(ctx) {
return ctx.currentUser.ringId;
}
function getProjectKey(ctx) {
return ctx.project.key;
}
function updateFeedback(ctx, liked, message) {
const feedback = getFeedback(ctx);
const timestamp = Date.now();
const userId = getUserId(ctx);
feedback.push({userId, liked, message, timestamp});
ctx.article.extensionProperties.feedback = JSON.stringify(feedback);
}
function updateGuestFeedback(ctx, liked, message, name, email) {
const guestFeedback = getGuestFeedback(ctx);
const timestamp = Date.now();
guestFeedback.push({name, email, liked, message, timestamp});
ctx.article.extensionProperties.guestFeedback = JSON.stringify(guestFeedback);
}
function updateGuestLikes(ctx) {
const guestLikes = getGuestLikes(ctx);
ctx.article.extensionProperties.guestLikes = String(guestLikes + 1);
}
function response(ctx, data) {
return ctx.response.json(data);
}
exports.httpHandler = {
endpoints: [
{
scope: 'article',
method: 'GET',
path: 'debug',
handle: function handleDebug(ctx) {
response(ctx, {
feedback: getFeedback(ctx),
guestFeedback: getGuestFeedback(ctx),
guestLikes: getGuestLikes(ctx)
});
}
},
{
scope: 'article',
method: 'GET',
path: 'user',
handle: function handleUser(ctx) {
const feedback = getFeedback(ctx);
const userId = getUserId(ctx);
const userFeedback = feedback.filter(it => it.userId === userId);
const lastUserFeedback = userFeedback[userFeedback.length - 1];
response(ctx, {
liked: lastUserFeedback?.liked ?? undefined,
leftMessage: Boolean(lastUserFeedback?.message),
isGuest: isGuest(ctx)
});
}
},
{
scope: 'article',
method: 'GET',
path: 'project',
handle: function handleProject(ctx) {
response(ctx, {
projectKey: getProjectKey(ctx)
});
}
},
{
scope: 'article',
method: 'POST',
path: 'like',
handle: function handleLike(ctx) {
if (isGuest(ctx)) {
return;
}
updateFeedback(ctx, true);
}
},
{
scope: 'article',
method: 'POST',
path: 'dislike',
handle: function handleDislike(ctx) {
if (isGuest(ctx)) {
return;
}
const message = ctx.request.getParameter('message');
updateFeedback(ctx, false, message);
}
},
{
scope: 'article',
method: 'POST',
path: 'guest-like',
handle: function handleGuestLike(ctx) {
if (!isGuest(ctx)) {
return;
}
updateGuestLikes(ctx);
}
},
{
scope: 'article',
method: 'POST',
path: 'guest-dislike',
handle: function handleGuestDislike(ctx) {
if (!isGuest(ctx)) {
return;
}
const message = ctx.request.getParameter('message');
const name = ctx.request.getParameter('userName');
const email = ctx.request.getParameter('userEmail');
updateGuestFeedback(ctx, false, message, name, email);
}
},
{
scope: 'article',
method: 'GET',
path: 'stat',
handle: function handleStat(ctx) {
const feedback = getFeedback(ctx);
const guestFeedback = getGuestFeedback(ctx);
const guestLikes = getGuestLikes(ctx);
const lastFeedbackOfEachUser = feedback.
sort((a, b) => b.timestamp - a.timestamp).
filter(({userId}, i) => i === feedback.findIndex((it) => it.userId === userId));
const lastFeedbackOfEachGuest = guestFeedback.
sort((a, b) => b.timestamp - a.timestamp).
filter(({email}, i) => !email || i === guestFeedback.findIndex((it) => it.email === email));
const likes = [...lastFeedbackOfEachUser, ...lastFeedbackOfEachGuest].filter(it => it.liked).length;
const dislikes = [...lastFeedbackOfEachUser, ...lastFeedbackOfEachGuest].filter(it => !it.liked).length;
const messages = feedback.filter(it => it.message);
const guestMessages = guestFeedback.filter(it => it.message);
response(ctx, {likes, guestLikes, dislikes, messages, guestMessages});
}
}
]
};