diff --git a/src/database.js b/src/database.js
index 84cbfed..ebdd39a 100644
--- a/src/database.js
+++ b/src/database.js
@@ -16,510 +16,513 @@ let connection;
mongoose.set('strictQuery', true);
async function connect() {
- await mongoose.connect(`${uri}/${database}`, options);
- connection = mongoose.connection;
- connection.on('connected', function () {
- logger.info(`MongoDB connected ${this.name}`);
- });
- connection.on('error', console.error.bind(console, 'connection error:'));
- connection.on('close', () => {
- connection.removeAllListeners();
- });
+ await mongoose.connect(`${uri}/${database}`, options);
+ connection = mongoose.connection;
+ connection.on('connected', function () {
+ logger.info(`MongoDB connected ${this.name}`);
+ });
+ connection.on('error', console.error.bind(console, 'connection error:'));
+ connection.on('close', () => {
+ connection.removeAllListeners();
+ });
}
function verifyConnected() {
- if (!connection) {
- connect();
- }
+ if (!connection) {
+ connect();
+ }
}
async function getCommunities(numberOfCommunities) {
- verifyConnected();
- if(numberOfCommunities === -1)
- return COMMUNITY.find({ parent: null, type: [0,2] });
- else
- return COMMUNITY.find({ parent: null, type: [0,2] }).limit(numberOfCommunities);
+ verifyConnected();
+ if (numberOfCommunities === -1) {
+ return COMMUNITY.find({ parent: null, type: [0,2] });
+ } else {
+ return COMMUNITY.find({ parent: null, type: [0,2] }).limit(numberOfCommunities);
+ }
}
async function getMostPopularCommunities(numberOfCommunities) {
- verifyConnected();
- return COMMUNITY.find({ parent: null, type: 0 }).sort({followers: -1}).limit(numberOfCommunities);
+ verifyConnected();
+ return COMMUNITY.find({ parent: null, type: 0 }).sort({followers: -1}).limit(numberOfCommunities);
}
async function getNewCommunities(numberOfCommunities) {
- verifyConnected();
- return COMMUNITY.find({ parent: null, type: 0 }).sort([['created_at', -1]]).limit(numberOfCommunities);
+ verifyConnected();
+ return COMMUNITY.find({ parent: null, type: 0 }).sort([['created_at', -1]]).limit(numberOfCommunities);
}
async function getSubCommunities(communityID) {
- verifyConnected();
- return COMMUNITY.find({
- parent: communityID
- });
+ verifyConnected();
+ return COMMUNITY.find({
+ parent: communityID
+ });
}
async function getCommunityByTitleID(title_id) {
- verifyConnected();
- return COMMUNITY.findOne({
- title_id: title_id
- });
+ verifyConnected();
+ return COMMUNITY.findOne({
+ title_id: title_id
+ });
}
async function getCommunityByID(community_id) {
- verifyConnected();
- return COMMUNITY.findOne({
- olive_community_id: community_id
- });
+ verifyConnected();
+ return COMMUNITY.findOne({
+ olive_community_id: community_id
+ });
}
async function getTotalPostsByCommunity(community) {
- verifyConnected();
- return POST.find({
- community_id: community.olive_community_id,
- parent: null,
- removed: false
- }).countDocuments();
+ verifyConnected();
+ return POST.find({
+ community_id: community.olive_community_id,
+ parent: null,
+ removed: false
+ }).countDocuments();
}
async function getPostByID(postID) {
- verifyConnected();
- return POST.findOne({
- id: postID
- });
+ verifyConnected();
+ return POST.findOne({
+ id: postID
+ });
}
async function getPostsByUserID(userID) {
- verifyConnected();
- return POST.find({
- pid: userID,
- parent: null,
- removed: false
- });
+ verifyConnected();
+ return POST.find({
+ pid: userID,
+ parent: null,
+ removed: false
+ });
}
async function getPostReplies(postID, number) {
- verifyConnected();
- return POST.find({
- parent: postID,
- removed: false
- }).limit(number);
+ verifyConnected();
+ return POST.find({
+ parent: postID,
+ removed: false
+ }).limit(number);
}
async function getDuplicatePosts(pid, post) {
- verifyConnected();
- return POST.findOne({
- pid: pid,
- body: post.body,
- painting: post.painting,
- screenshot: post.screenshot,
- parent: null,
- removed: false
- });
+ verifyConnected();
+ return POST.findOne({
+ pid: pid,
+ body: post.body,
+ painting: post.painting,
+ screenshot: post.screenshot,
+ parent: null,
+ removed: false
+ });
}
async function getUserPostRepliesAfterTimestamp(post, numberOfPosts) {
- verifyConnected();
- return POST.find({
- parent: post.pid,
- created_at: { $lt: post.created_at },
- message_to_pid: null,
- removed: false
- }).limit(numberOfPosts);
+ verifyConnected();
+ return POST.find({
+ parent: post.pid,
+ created_at: { $lt: post.created_at },
+ message_to_pid: null,
+ removed: false
+ }).limit(numberOfPosts);
}
async function getNumberUserPostsByID(userID, number) {
- verifyConnected();
- return POST.find({
- pid: userID,
- parent: null,
- message_to_pid: null,
- removed: false
- }).sort({ created_at: -1}).limit(number);
+ verifyConnected();
+ return POST.find({
+ pid: userID,
+ parent: null,
+ message_to_pid: null,
+ removed: false
+ }).sort({ created_at: -1}).limit(number);
}
async function getTotalPostsByUserID(userID) {
- verifyConnected();
- return POST.find({
- pid: userID,
- parent: null,
- message_to_pid: null,
- removed: false
- }).countDocuments();
+ verifyConnected();
+ return POST.find({
+ pid: userID,
+ parent: null,
+ message_to_pid: null,
+ removed: false
+ }).countDocuments();
}
async function getHotPostsByCommunity(community, numberOfPosts) {
- verifyConnected();
- return POST.find({
- community_id: community.olive_community_id,
- parent: null,
- removed: false
- }).sort({empathy_count: -1}).limit(numberOfPosts);
+ verifyConnected();
+ return POST.find({
+ community_id: community.olive_community_id,
+ parent: null,
+ removed: false
+ }).sort({empathy_count: -1}).limit(numberOfPosts);
}
async function getNumberNewCommunityPostsByID(community, number) {
- verifyConnected();
- return POST.find({
- community_id: community.olive_community_id,
- parent: null,
- removed: false
- }).sort({ created_at: -1}).limit(number);
+ verifyConnected();
+ return POST.find({
+ community_id: community.olive_community_id,
+ parent: null,
+ removed: false
+ }).sort({ created_at: -1}).limit(number);
}
async function getNumberPopularCommunityPostsByID(community, limit, offset) {
- verifyConnected();
- return POST.find({
- community_id: community.olive_community_id,
- parent: null,
- removed: false
- }).sort({ empathy_count: -1}).skip(offset).limit(limit);
+ verifyConnected();
+ return POST.find({
+ community_id: community.olive_community_id,
+ parent: null,
+ removed: false
+ }).sort({ empathy_count: -1}).skip(offset).limit(limit);
}
async function getNumberVerifiedCommunityPostsByID(community, limit, offset) {
- verifyConnected();
- return POST.find({
- community_id: community.olive_community_id,
- verified: true,
- parent: null,
- removed: false
- }).sort({ created_at: -1}).skip(offset).limit(limit);
+ verifyConnected();
+ return POST.find({
+ community_id: community.olive_community_id,
+ verified: true,
+ parent: null,
+ removed: false
+ }).sort({ created_at: -1}).skip(offset).limit(limit);
}
async function getPostsByCommunity(community, numberOfPosts) {
- verifyConnected();
- return POST.find({
- community_id: community.olive_community_id,
- parent: null,
- removed: false
- }).limit(numberOfPosts);
+ verifyConnected();
+ return POST.find({
+ community_id: community.olive_community_id,
+ parent: null,
+ removed: false
+ }).limit(numberOfPosts);
}
async function getPostsByCommunityKey(community, numberOfPosts, search_key) {
- verifyConnected();
- return POST.find({
- community_id: community.olive_community_id,
- search_key: search_key,
- parent: null,
- removed: false
- }).limit(numberOfPosts);
+ verifyConnected();
+ return POST.find({
+ community_id: community.olive_community_id,
+ search_key: search_key,
+ parent: null,
+ removed: false
+ }).limit(numberOfPosts);
}
async function getNewPostsByCommunity(community, limit, offset) {
- verifyConnected();
- return POST.find({
- community_id: community.olive_community_id,
- parent: null,
- removed: false
- }).sort({ created_at: -1 }).skip(offset).limit(limit);
+ verifyConnected();
+ return POST.find({
+ community_id: community.olive_community_id,
+ parent: null,
+ removed: false
+ }).sort({ created_at: -1 }).skip(offset).limit(limit);
}
async function getAllUserPosts(pid) {
- verifyConnected();
- return POST.find({
- pid: pid,
- message_to_pid: null
- });
+ verifyConnected();
+ return POST.find({
+ pid: pid,
+ message_to_pid: null
+ });
}
async function getRemovedUserPosts(pid) {
- verifyConnected();
- return POST.find({
- pid: pid,
- message_to_pid: null,
- removed: true
- });
+ verifyConnected();
+ return POST.find({
+ pid: pid,
+ message_to_pid: null,
+ removed: true
+ });
}
async function getUserPostsAfterTimestamp(post, numberOfPosts) {
- verifyConnected();
- return POST.find({
- pid: post.pid,
- created_at: { $lt: post.created_at },
- parent: null,
- message_to_pid: null,
- removed: false
- }).limit(numberOfPosts);
+ verifyConnected();
+ return POST.find({
+ pid: post.pid,
+ created_at: { $lt: post.created_at },
+ parent: null,
+ message_to_pid: null,
+ removed: false
+ }).limit(numberOfPosts);
}
async function getUserPostsOffset(pid, limit, offset) {
- verifyConnected();
- return POST.find({
- pid: pid,
- parent: null,
- message_to_pid: null,
- removed: false
- }).skip(offset).limit(limit).sort({ created_at: -1});
+ verifyConnected();
+ return POST.find({
+ pid: pid,
+ parent: null,
+ message_to_pid: null,
+ removed: false
+ }).skip(offset).limit(limit).sort({ created_at: -1});
}
async function getCommunityPostsAfterTimestamp(post, numberOfPosts) {
- verifyConnected();
- return POST.find({
- community_id: post.community_id,
- created_at: { $lt: post.created_at },
- parent: null,
- removed: false
- }).limit(numberOfPosts);
+ verifyConnected();
+ return POST.find({
+ community_id: post.community_id,
+ created_at: { $lt: post.created_at },
+ parent: null,
+ removed: false
+ }).limit(numberOfPosts);
}
async function getEndpoints() {
- verifyConnected();
- return ENDPOINT.find({});
+ verifyConnected();
+ return ENDPOINT.find({});
}
async function getEndPoint(accessLevel) {
- verifyConnected();
- return ENDPOINT.findOne({
- server_access_level: accessLevel
- })
+ verifyConnected();
+ return ENDPOINT.findOne({
+ server_access_level: accessLevel
+ });
}
async function getUsersSettings(numberOfUsers) {
- verifyConnected();
- if(numberOfUsers === -1)
- return SETTINGS.find({});
- else
- return SETTINGS.find({}).limit(numberOfUsers);
+ verifyConnected();
+ if (numberOfUsers === -1) {
+ return SETTINGS.find({});
+ } else {
+ return SETTINGS.find({}).limit(numberOfUsers);
+ }
}
async function getUsersContent(numberOfUsers) {
- verifyConnected();
- if(numberOfUsers === -1)
- return SETTINGS.find({});
- else
- return SETTINGS.find({}).limit(numberOfUsers);
+ verifyConnected();
+ if (numberOfUsers === -1) {
+ return SETTINGS.find({});
+ } else {
+ return SETTINGS.find({}).limit(numberOfUsers);
+ }
}
async function getUserSettings(pid) {
- verifyConnected();
- return SETTINGS.findOne({pid: pid});
+ verifyConnected();
+ return SETTINGS.findOne({pid: pid});
}
async function getUserContent(pid) {
- verifyConnected();
- return CONTENT.findOne({pid: pid});
+ verifyConnected();
+ return CONTENT.findOne({pid: pid});
}
async function getFollowingUsers(content) {
- verifyConnected();
- return SETTINGS.find({
- pid: content.following_users
- });
+ verifyConnected();
+ return SETTINGS.find({
+ pid: content.following_users
+ });
}
async function getFollowedUsers(content) {
- verifyConnected();
- return SETTINGS.find({
- pid: content.followed_users
- });
+ verifyConnected();
+ return SETTINGS.find({
+ pid: content.followed_users
+ });
}
async function getNewsFeed(content, numberOfPosts) {
- verifyConnected();
- return POST.find({
- $or: [
- {pid: content.followed_users},
- {pid: content.pid},
- {community_id: content.followed_communities},
- ],
- parent: null,
- message_to_pid: null,
- removed: false
- }).limit(numberOfPosts).sort({ created_at: -1});
+ verifyConnected();
+ return POST.find({
+ $or: [
+ {pid: content.followed_users},
+ {pid: content.pid},
+ {community_id: content.followed_communities},
+ ],
+ parent: null,
+ message_to_pid: null,
+ removed: false
+ }).limit(numberOfPosts).sort({ created_at: -1});
}
async function getNewsFeedAfterTimestamp(content, numberOfPosts, post) {
- verifyConnected();
- return POST.find({
- $or: [
- {pid: content.followed_users},
- {pid: content.pid},
- {community_id: content.followed_communities},
- ],
- created_at: { $lt: post.created_at },
- parent: null,
- message_to_pid: null,
- removed: false
- }).limit(numberOfPosts).sort({ created_at: -1});
+ verifyConnected();
+ return POST.find({
+ $or: [
+ {pid: content.followed_users},
+ {pid: content.pid},
+ {community_id: content.followed_communities},
+ ],
+ created_at: { $lt: post.created_at },
+ parent: null,
+ message_to_pid: null,
+ removed: false
+ }).limit(numberOfPosts).sort({ created_at: -1});
}
async function getNewsFeedOffset(content, limit, offset) {
- verifyConnected();
- return POST.find({
- $or: [
- {pid: content.followed_users},
- {pid: content.pid},
- {community_id: content.followed_communities},
- ],
- parent: null,
- message_to_pid: null,
- removed: false
- }).skip(offset).limit(limit).sort({ created_at: -1});
+ verifyConnected();
+ return POST.find({
+ $or: [
+ {pid: content.followed_users},
+ {pid: content.pid},
+ {community_id: content.followed_communities},
+ ],
+ parent: null,
+ message_to_pid: null,
+ removed: false
+ }).skip(offset).limit(limit).sort({ created_at: -1});
}
async function getConversations(pid) {
- verifyConnected();
- return CONVERSATION.find({
- "users.pid": pid
- }).sort({ last_updated: -1});
+ verifyConnected();
+ return CONVERSATION.find({
+ 'users.pid': pid
+ }).sort({ last_updated: -1});
}
async function getUnreadConversationCount(pid) {
- verifyConnected();
- return CONVERSATION.find({
- "users": { $elemMatch: {
- 'pid': pid,
- 'read': false
- }}
+ verifyConnected();
+ return CONVERSATION.find({
+ 'users': { $elemMatch: {
+ 'pid': pid,
+ 'read': false
+ }}
- }).countDocuments();
+ }).countDocuments();
}
async function getConversationByID(community_id) {
- verifyConnected();
- return CONVERSATION.findOne({
- type: 3,
- id: community_id
- });
+ verifyConnected();
+ return CONVERSATION.findOne({
+ type: 3,
+ id: community_id
+ });
}
async function getConversationMessages(community_id, limit, offset) {
- verifyConnected();
- return POST.find({
- community_id: community_id,
- parent: null,
- removed: false
- }).sort({created_at: 1}).skip(offset).limit(limit);
+ verifyConnected();
+ return POST.find({
+ community_id: community_id,
+ parent: null,
+ removed: false
+ }).sort({created_at: 1}).skip(offset).limit(limit);
}
async function getConversationByUsers(pids) {
- verifyConnected();
- return CONVERSATION.findOne({
- $and: [
- {'users.pid': pids[0]},
- {'users.pid': pids[1]}
- ]
- });
+ verifyConnected();
+ return CONVERSATION.findOne({
+ $and: [
+ {'users.pid': pids[0]},
+ {'users.pid': pids[1]}
+ ]
+ });
}
async function getLatestMessage(pid, pid2) {
- verifyConnected();
- return POST.findOne({
- $or: [
- {pid: pid, message_to_pid: pid2},
- {pid: pid2, message_to_pid: pid}
- ],
- removed: false
- })
+ verifyConnected();
+ return POST.findOne({
+ $or: [
+ {pid: pid, message_to_pid: pid2},
+ {pid: pid2, message_to_pid: pid}
+ ],
+ removed: false
+ });
}
async function getNotifications(pid, limit, offset) {
- verifyConnected();
- return NOTIFICATION.find({
- pid: pid,
- }).sort({lastUpdated: -1}).skip(offset).limit(limit);
+ verifyConnected();
+ return NOTIFICATION.find({
+ pid: pid,
+ }).sort({lastUpdated: -1}).skip(offset).limit(limit);
}
async function getNotification(pid, type, reference_id) {
- verifyConnected();
- return NOTIFICATION.findOne({
- pid: pid,
- type: type,
- reference_id: reference_id
- })
+ verifyConnected();
+ return NOTIFICATION.findOne({
+ pid: pid,
+ type: type,
+ reference_id: reference_id
+ });
}
async function getLastNotification(pid) {
- verifyConnected();
- return NOTIFICATION.findOne({
- pid: pid
- }).sort({lastUpdated: -1}).limit(1);
+ verifyConnected();
+ return NOTIFICATION.findOne({
+ pid: pid
+ }).sort({lastUpdated: -1}).limit(1);
}
async function getUnreadNotificationCount(pid) {
- verifyConnected();
- return NOTIFICATION.find({
- pid: pid,
- read: false
- }).countDocuments();
+ verifyConnected();
+ return NOTIFICATION.find({
+ pid: pid,
+ read: false
+ }).countDocuments();
}
async function getAllReports(offset, limit) {
- verifyConnected();
- return REPORT.find().sort({created_at: -1}).skip(offset).limit(limit);
+ verifyConnected();
+ return REPORT.find().sort({created_at: -1}).skip(offset).limit(limit);
}
async function getAllOpenReports(offset, limit) {
- verifyConnected();
- return REPORT.find({ resolved: false }).sort({created_at: -1}).skip(offset).limit(limit);
+ verifyConnected();
+ return REPORT.find({ resolved: false }).sort({created_at: -1}).skip(offset).limit(limit);
}
async function getReportsByUser(pid, offset, limit) {
- verifyConnected();
- return REPORT.find({ reported_by: pid }).sort({created_at: -1}).skip(offset).limit(limit);
+ verifyConnected();
+ return REPORT.find({ reported_by: pid }).sort({created_at: -1}).skip(offset).limit(limit);
}
async function getReportsByPost(postID, offset, limit) {
- verifyConnected();
- return REPORT.find({ post_id: postID }).sort({created_at: -1}).skip(offset).limit(limit);
+ verifyConnected();
+ return REPORT.find({ post_id: postID }).sort({created_at: -1}).skip(offset).limit(limit);
}
async function getReportById(id) {
- verifyConnected();
- return REPORT.findById(id);
+ verifyConnected();
+ return REPORT.findById(id);
}
module.exports = {
- connect,
- getCommunities,
- getMostPopularCommunities,
- getNewCommunities,
- getSubCommunities,
- getCommunityByTitleID,
- getCommunityByID,
- getTotalPostsByCommunity,
- getPostsByCommunity,
- getHotPostsByCommunity,
- getNumberNewCommunityPostsByID,
- getNumberPopularCommunityPostsByID,
- getNumberVerifiedCommunityPostsByID,
- getNewPostsByCommunity,
- getPostsByCommunityKey,
- getPostsByUserID,
- getPostReplies,
- getUserPostRepliesAfterTimestamp,
- getNumberUserPostsByID,
- getTotalPostsByUserID,
- getPostByID,
- getDuplicatePosts,
- getEndpoints,
- getEndPoint,
- getUserPostsAfterTimestamp,
- getUserPostsOffset,
- getCommunityPostsAfterTimestamp,
- getNewsFeed,
- getNewsFeedAfterTimestamp,
- getNewsFeedOffset,
- getFollowingUsers,
- getFollowedUsers,
- getConversations,
- getConversationByID,
- getConversationByUsers,
- getConversationMessages,
- getUnreadConversationCount,
- getLatestMessage,
- getUsersSettings,
- getUsersContent,
- getUserSettings,
- getUserContent,
- getNotifications,
- getUnreadNotificationCount,
- getNotification,
- getLastNotification,
- getAllUserPosts,
- getRemovedUserPosts,
- getAllReports,
- getAllOpenReports,
- getReportsByUser,
- getReportsByPost,
- getReportById
+ connect,
+ getCommunities,
+ getMostPopularCommunities,
+ getNewCommunities,
+ getSubCommunities,
+ getCommunityByTitleID,
+ getCommunityByID,
+ getTotalPostsByCommunity,
+ getPostsByCommunity,
+ getHotPostsByCommunity,
+ getNumberNewCommunityPostsByID,
+ getNumberPopularCommunityPostsByID,
+ getNumberVerifiedCommunityPostsByID,
+ getNewPostsByCommunity,
+ getPostsByCommunityKey,
+ getPostsByUserID,
+ getPostReplies,
+ getUserPostRepliesAfterTimestamp,
+ getNumberUserPostsByID,
+ getTotalPostsByUserID,
+ getPostByID,
+ getDuplicatePosts,
+ getEndpoints,
+ getEndPoint,
+ getUserPostsAfterTimestamp,
+ getUserPostsOffset,
+ getCommunityPostsAfterTimestamp,
+ getNewsFeed,
+ getNewsFeedAfterTimestamp,
+ getNewsFeedOffset,
+ getFollowingUsers,
+ getFollowedUsers,
+ getConversations,
+ getConversationByID,
+ getConversationByUsers,
+ getConversationMessages,
+ getUnreadConversationCount,
+ getLatestMessage,
+ getUsersSettings,
+ getUsersContent,
+ getUserSettings,
+ getUserContent,
+ getNotifications,
+ getUnreadNotificationCount,
+ getNotification,
+ getLastNotification,
+ getAllUserPosts,
+ getRemovedUserPosts,
+ getAllReports,
+ getAllOpenReports,
+ getReportsByUser,
+ getReportsByPost,
+ getReportById
};
diff --git a/src/middleware/auth.js b/src/middleware/auth.js
index 5925def..5df34b3 100644
--- a/src/middleware/auth.js
+++ b/src/middleware/auth.js
@@ -1,138 +1,139 @@
const config = require('../../config.json');
const util = require('../util');
-const moment = require("moment/moment");
+const moment = require('moment/moment');
const db = require('../database');
async function auth(request, response, next) {
- // Web files
- if(isStartOfPath(request.path, '/css/') ||
+ // Web files
+ if (isStartOfPath(request.path, '/css/') ||
isStartOfPath(request.path, '/fonts/') ||
isStartOfPath(request.path, '/js/') ||
request.path === '/favicon.ico' ||
isStartOfPath(request.path, '/web/') ||
isStartOfPath(request.path, '/images/') ||
isStartOfPath(request.path, '/image/')) {
- request.lang = util.data.processLanguage();
- if(includes(request, 'juxt'))
- request.directory = 'web';
- else
- request.directory = includes(request, 'portal') ? 'portal' : 'ctr';
- return next()
- }
+ request.lang = util.data.processLanguage();
+ if (includes(request, 'juxt')) {
+ request.directory = 'web';
+ } else {
+ request.directory = includes(request, 'portal') ? 'portal' : 'ctr';
+ }
+ return next();
+ }
- // Get pid and fetch user data
- if(request.cookies.access_token) {
- try {
- request.user = await util.data.getUserDataFromToken(request.cookies.access_token);
- }
- catch(e) {
- response.clearCookie('access_token');
- response.clearCookie('refresh_token');
- return response.render('web/login.ejs', {toast: 'Unable to reach the account server. Try again later.', cdnURL: config.CDN_domain,});
- }
- request.pid = request.user ? request.user.pid : null;
- }
- else if(request.headers["x-nintendo-servicetoken"]) {
- request.pid = request.headers["x-nintendo-servicetoken"] ? await util.data.processServiceToken(request.headers["x-nintendo-servicetoken"]) : null;
- request.user = request.pid ? await util.data.getUserDataFromPid(request.pid) : null;
- }
+ // Get pid and fetch user data
+ if (request.cookies.access_token) {
+ try {
+ request.user = await util.data.getUserDataFromToken(request.cookies.access_token);
+ } catch (e) {
+ response.clearCookie('access_token');
+ response.clearCookie('refresh_token');
+ return response.render('web/login.ejs', {toast: 'Unable to reach the account server. Try again later.', cdnURL: config.CDN_domain,});
+ }
+ request.pid = request.user ? request.user.pid : null;
+ } else if (request.headers['x-nintendo-servicetoken']) {
+ request.pid = request.headers['x-nintendo-servicetoken'] ? await util.data.processServiceToken(request.headers['x-nintendo-servicetoken']) : null;
+ request.user = request.pid ? await util.data.getUserDataFromPid(request.pid) : null;
+ }
- // Set headers
- request.paramPackData = request.headers["x-nintendo-parampack"] ? util.data.decodeParamPack(request.headers["x-nintendo-parampack"]) : null;
- response.header('X-Nintendo-WhiteList', config.whitelist);
+ // Set headers
+ request.paramPackData = request.headers['x-nintendo-parampack'] ? util.data.decodeParamPack(request.headers['x-nintendo-parampack']) : null;
+ response.header('X-Nintendo-WhiteList', config.whitelist);
- // Ban check
- if(request.user) {
+ // Ban check
+ if (request.user) {
if (request.user.serverAccessLevel !== 'test' && request.user.serverAccessLevel !== 'dev') {
response.status(500);
return response.send('No access. Must be tester or dev');
}
- // Set moderator status
- request.moderator = request.user.accessLevel >= 2;
- const user = await db.getUserSettings(request.pid);
- if(user && moment(user.ban_lift_date) <= moment() && user.account_status !== 3) {
- user.account_status = 0;
- await user.save()
- }
- // This includes ban checks for both Juxt specifically and the account server, ideally this should be squashed
- // assuming we support more gradual bans on PNID's
- if(user && (user.account_status < 0 || user.account_status > 1 || request.user.accessLevel < 0))
- {
- response.render(request.directory + '/partials/ban_notification.ejs', {
- user: user,
- moment: moment,
- cdnURL: config.CDN_domain,
- lang: request.lang,
- pid: request.pid
- });
- }
- }
+ // Set moderator status
+ request.moderator = request.user.accessLevel >= 2;
+ const user = await db.getUserSettings(request.pid);
+ if (user && moment(user.ban_lift_date) <= moment() && user.account_status !== 3) {
+ user.account_status = 0;
+ await user.save();
+ }
+ // This includes ban checks for both Juxt specifically and the account server, ideally this should be squashed
+ // assuming we support more gradual bans on PNID's
+ if (user && (user.account_status < 0 || user.account_status > 1 || request.user.accessLevel < 0)) {
+ response.render(request.directory + '/partials/ban_notification.ejs', {
+ user: user,
+ moment: moment,
+ cdnURL: config.CDN_domain,
+ lang: request.lang,
+ pid: request.pid
+ });
+ }
+ }
- // Juxt Website
- if(includes(request, 'juxt')) {
- request.lang = util.data.processLanguage();
- request.token = request.cookies.access_token;
- request.paramPackData = null;
- request.directory = 'web';
+ // Juxt Website
+ if (includes(request, 'juxt')) {
+ request.lang = util.data.processLanguage();
+ request.token = request.cookies.access_token;
+ request.paramPackData = null;
+ request.directory = 'web';
- // Open access pages
- if(isStartOfPath(request.path, '/users/') ||
+ // Open access pages
+ if (isStartOfPath(request.path, '/users/') ||
(isStartOfPath(request.path, '/titles/') && request.path !== '/titles/show') ||
(isStartOfPath(request.path, '/posts/') && !request.path.includes('/empathy'))) {
- if(!request.pid)
- request.pid = 1000000000;
- return next();
- }
- // Login endpoint
- if(request.path === '/login') {
- if(request.pid)
- return response.redirect('/titles/show?src=login');
- return next();
- }
- if(!request.pid)
- return response.redirect('/login');
+ if (!request.pid) {
+ request.pid = 1000000000;
+ }
+ return next();
+ }
+ // Login endpoint
+ if (request.path === '/login') {
+ if (request.pid) {
+ return response.redirect('/titles/show?src=login');
+ }
+ return next();
+ }
+ if (!request.pid) {
+ return response.redirect('/login');
+ }
- return next();
- }
- else {
- // This section includes checks if a user is a developer and adds exceptions for these cases
- if(!request.pid) {
- return response.render('portal/partials/ban_notification.ejs', {
- user: null,
- error: "Unable to parse service token. Are you using a Nintendo Network ID?"
- });
- }
- if(request.user.accessLevel < 3 && !request.paramPackData) {
- return response.render('portal/partials/ban_notification.ejs', {
- user: null,
- error: "Missing auth headers"
- });
- }
- if(!request.user) {
- return response.render('portal/partials/ban_notification.ejs', {
- user: null,
- error: "Unable to fetch user data. Please try again later."
- });
- }
- let userAgent = request.headers['user-agent'];
- if(request.user.accessLevel < 3 && (request.cookies.access_token || (!userAgent.includes('Nintendo WiiU') && !userAgent.includes('Nintendo 3DS'))))
- return response.render('portal/partials/ban_notification.ejs', {
- user: null,
- error: "Invalid authentication method used."
- });
+ return next();
+ } else {
+ // This section includes checks if a user is a developer and adds exceptions for these cases
+ if (!request.pid) {
+ return response.render('portal/partials/ban_notification.ejs', {
+ user: null,
+ error: 'Unable to parse service token. Are you using a Nintendo Network ID?'
+ });
+ }
+ if (request.user.accessLevel < 3 && !request.paramPackData) {
+ return response.render('portal/partials/ban_notification.ejs', {
+ user: null,
+ error: 'Missing auth headers'
+ });
+ }
+ if (!request.user) {
+ return response.render('portal/partials/ban_notification.ejs', {
+ user: null,
+ error: 'Unable to fetch user data. Please try again later.'
+ });
+ }
+ const userAgent = request.headers['user-agent'];
+ if (request.user.accessLevel < 3 && (request.cookies.access_token || (!userAgent.includes('Nintendo WiiU') && !userAgent.includes('Nintendo 3DS')))) {
+ return response.render('portal/partials/ban_notification.ejs', {
+ user: null,
+ error: 'Invalid authentication method used.'
+ });
+ }
- request.lang = util.data.processLanguage(request.paramPackData);
- request.directory = includes(request, 'portal') ? 'portal' : 'ctr';
- return next();
- }
+ request.lang = util.data.processLanguage(request.paramPackData);
+ request.directory = includes(request, 'portal') ? 'portal' : 'ctr';
+ return next();
+ }
}
function isStartOfPath(path, value) {
- return path.indexOf(value) === 0;
+ return path.indexOf(value) === 0;
}
function includes(request, domain) {
- return request.subdomains.findIndex(element => element.includes(domain)) !== -1
+ return request.subdomains.findIndex(element => element.includes(domain)) !== -1;
}
module.exports = auth;
diff --git a/src/middleware/consoleAuth.js b/src/middleware/consoleAuth.js
index 8baf643..5c12252 100644
--- a/src/middleware/consoleAuth.js
+++ b/src/middleware/consoleAuth.js
@@ -1,71 +1,71 @@
const config = require('../../config.json');
const util = require('../util');
-const moment = require("moment/moment");
+const moment = require('moment/moment');
const db = require('../database');
async function auth(request, response, next) {
- // Get pid and fetch user data
- if(request.headers["x-nintendo-servicetoken"]) {
- request.pid = request.headers["x-nintendo-servicetoken"] ? await util.data.processServiceToken(request.headers["x-nintendo-servicetoken"]) : null;
- request.user = request.pid ? await util.data.getUserDataFromPid(request.pid) : null;
- }
+ // Get pid and fetch user data
+ if (request.headers['x-nintendo-servicetoken']) {
+ request.pid = request.headers['x-nintendo-servicetoken'] ? await util.data.processServiceToken(request.headers['x-nintendo-servicetoken']) : null;
+ request.user = request.pid ? await util.data.getUserDataFromPid(request.pid) : null;
+ }
- // Set headers
- request.paramPackData = request.headers["x-nintendo-parampack"] ? util.data.decodeParamPack(request.headers["x-nintendo-parampack"]) : null;
- response.header('X-Nintendo-WhiteList', config.whitelist);
+ // Set headers
+ request.paramPackData = request.headers['x-nintendo-parampack'] ? util.data.decodeParamPack(request.headers['x-nintendo-parampack']) : null;
+ response.header('X-Nintendo-WhiteList', config.whitelist);
- // Ban check
- if(request.user) {
- // Set moderator status
- request.moderator = request.user.accessLevel >= 2;
- const user = await db.getUserSettings(request.pid);
- if(user && moment(user.ban_lift_date) <= moment() && user.account_status !== 3) {
- user.account_status = 0;
- await user.save()
- }
- // This includes ban checks for both Juxt specifically and the account server, ideally this should be squashed
- // assuming we support more gradual bans on PNID's
- if(user && (user.account_status < 0 || user.account_status > 1 || request.user.accessLevel < 0))
- {
- response.render(request.directory + '/partials/ban_notification.ejs', {
- user: user,
- moment: moment,
- cdnURL: config.CDN_domain,
- lang: request.lang,
- pid: request.pid
- });
- }
- }
+ // Ban check
+ if (request.user) {
+ // Set moderator status
+ request.moderator = request.user.accessLevel >= 2;
+ const user = await db.getUserSettings(request.pid);
+ if (user && moment(user.ban_lift_date) <= moment() && user.account_status !== 3) {
+ user.account_status = 0;
+ await user.save();
+ }
+ // This includes ban checks for both Juxt specifically and the account server, ideally this should be squashed
+ // assuming we support more gradual bans on PNID's
+ if (user && (user.account_status < 0 || user.account_status > 1 || request.user.accessLevel < 0)) {
+ response.render(request.directory + '/partials/ban_notification.ejs', {
+ user: user,
+ moment: moment,
+ cdnURL: config.CDN_domain,
+ lang: request.lang,
+ pid: request.pid
+ });
+ }
+ }
- // This section includes checks if a user is a developer and adds exceptions for these cases
- if(!request.pid) {
- return response.render('portal/partials/ban_notification.ejs', {
- user: null,
- error: "Unable to parse service token. Are you using a Nintendo Network ID?"
- });
- }
- if(request.user.accessLevel < 3 && !request.paramPackData) {
- return response.render('portal/partials/ban_notification.ejs', {
- user: null,
- error: "Missing auth headers"
- });
- }
- if(!request.user) {
- return response.render('portal/partials/ban_notification.ejs', {
- user: null,
- error: "Unable to fetch user data. Please try again later."
- });
- }
- let userAgent = request.headers['user-agent'];
- if(request.user.accessLevel < 3 && (request.cookies.access_token || (!userAgent.includes('Nintendo WiiU') && !userAgent.includes('Nintendo 3DS'))))
- return response.render('portal/partials/ban_notification.ejs', {
- user: null,
- error: "Invalid authentication method used."
- });
+ // This section includes checks if a user is a developer and adds exceptions for these cases
+ if (!request.pid) {
+ return response.render('portal/partials/ban_notification.ejs', {
+ user: null,
+ error: 'Unable to parse service token. Are you using a Nintendo Network ID?'
+ });
+ }
+ if (request.user.accessLevel < 3 && !request.paramPackData) {
+ return response.render('portal/partials/ban_notification.ejs', {
+ user: null,
+ error: 'Missing auth headers'
+ });
+ }
+ if (!request.user) {
+ return response.render('portal/partials/ban_notification.ejs', {
+ user: null,
+ error: 'Unable to fetch user data. Please try again later.'
+ });
+ }
+ const userAgent = request.headers['user-agent'];
+ if (request.user.accessLevel < 3 && (request.cookies.access_token || (!userAgent.includes('Nintendo WiiU') && !userAgent.includes('Nintendo 3DS')))) {
+ return response.render('portal/partials/ban_notification.ejs', {
+ user: null,
+ error: 'Invalid authentication method used.'
+ });
+ }
- request.lang = util.data.processLanguage(request.paramPackData);
- request.directory = request.subdomains[1];
- return next();
+ request.lang = util.data.processLanguage(request.paramPackData);
+ request.directory = request.subdomains[1];
+ return next();
}
module.exports = auth;
diff --git a/src/middleware/staticFiles.js b/src/middleware/staticFiles.js
index 3ff02c1..61677bf 100644
--- a/src/middleware/staticFiles.js
+++ b/src/middleware/staticFiles.js
@@ -1,8 +1,8 @@
const util = require('../util');
async function staticFiles(request, response, next) {
- // Web files
- if(isStartOfPath(request.path, '/css/') ||
+ // Web files
+ if (isStartOfPath(request.path, '/css/') ||
isStartOfPath(request.path, '/fonts/') ||
isStartOfPath(request.path, '/js/') ||
request.path === '/favicon.ico' ||
@@ -10,23 +10,23 @@ async function staticFiles(request, response, next) {
isStartOfPath(request.path, '/images/') ||
isStartOfPath(request.path, '/image/')) {
- request.lang = util.data.processLanguage();
+ request.lang = util.data.processLanguage();
- if(request.subdomains.includes('juxt'))
- request.directory = 'web';
- else
- request.directory = request.subdomains[1];
- return next()
- }
- else if(request.path === "/") {
- return response.redirect('/titles/show');
- }
- else
- return response.sendStatus(404);
+ if (request.subdomains.includes('juxt')) {
+ request.directory = 'web';
+ } else {
+ request.directory = request.subdomains[1];
+ }
+ return next();
+ } else if (request.path === '/') {
+ return response.redirect('/titles/show');
+ } else {
+ return response.sendStatus(404);
+ }
}
function isStartOfPath(path, value) {
- return path.indexOf(value) === 0;
+ return path.indexOf(value) === 0;
}
diff --git a/src/middleware/webAuth.js b/src/middleware/webAuth.js
index b861a69..6acf0ca 100644
--- a/src/middleware/webAuth.js
+++ b/src/middleware/webAuth.js
@@ -1,68 +1,69 @@
const config = require('../../config.json');
const util = require('../util');
-const moment = require("moment/moment");
+const moment = require('moment/moment');
const db = require('../database');
async function auth(request, response, next) {
- // Get pid and fetch user data
- request.lang = util.data.processLanguage();
- request.paramPackData = null;
- request.directory = 'web';
- request.token = request.cookies.access_token;
- if(request.cookies.access_token) {
- try {
- request.user = await util.data.getUserDataFromToken(request.token);
- }
- catch(e) {
- console.log(e);
- if(request.path === "/login") {
- return next();
- }
- return response.render('web/login.ejs', {toast: 'Unable to reach the account server. Try again later.', cdnURL: config.CDN_domain,});
- }
- request.pid = request.user ? request.user.pid : null;
- }
+ // Get pid and fetch user data
+ request.lang = util.data.processLanguage();
+ request.paramPackData = null;
+ request.directory = 'web';
+ request.token = request.cookies.access_token;
+ if (request.cookies.access_token) {
+ try {
+ request.user = await util.data.getUserDataFromToken(request.token);
+ } catch (e) {
+ console.log(e);
+ if (request.path === '/login') {
+ return next();
+ }
+ return response.render('web/login.ejs', {toast: 'Unable to reach the account server. Try again later.', cdnURL: config.CDN_domain,});
+ }
+ request.pid = request.user ? request.user.pid : null;
+ }
- // Ban check
- if(request.user) {
- // Set moderator status
- request.moderator = request.user.accessLevel >= 2;
- const user = await db.getUserSettings(request.pid);
- if(user && moment(user.ban_lift_date) <= moment() && user.account_status !== 3) {
- user.account_status = 0;
- await user.save()
- }
- // This includes ban checks for both Juxt specifically and the account server, ideally this should be squashed
- // assuming we support more gradual bans on PNID's
- if(user && (user.account_status < 0 || user.account_status > 1 || request.user.accessLevel < 0))
- {
- return response.render('web/login.ejs', {toast: 'Your account has been suspended. For more information, log into https://pretendo.network/account', cdnURL: config.CDN_domain,});
- }
- }
+ // Ban check
+ if (request.user) {
+ // Set moderator status
+ request.moderator = request.user.accessLevel >= 2;
+ const user = await db.getUserSettings(request.pid);
+ if (user && moment(user.ban_lift_date) <= moment() && user.account_status !== 3) {
+ user.account_status = 0;
+ await user.save();
+ }
+ // This includes ban checks for both Juxt specifically and the account server, ideally this should be squashed
+ // assuming we support more gradual bans on PNID's
+ if (user && (user.account_status < 0 || user.account_status > 1 || request.user.accessLevel < 0)) {
+ return response.render('web/login.ejs', {toast: 'Your account has been suspended. For more information, log into https://pretendo.network/account', cdnURL: config.CDN_domain,});
+ }
+ }
- // Open access pages
- if(isStartOfPath(request.path, '/users/') ||
+ // Open access pages
+ if (isStartOfPath(request.path, '/users/') ||
(isStartOfPath(request.path, '/titles/') && request.path !== '/titles/show') ||
(isStartOfPath(request.path, '/posts/') && !request.path.includes('/empathy'))) {
- if(!request.pid)
- request.pid = 1000000000;
- return next();
- }
- // Login endpoint
- if(request.path === '/login') {
- if(request.pid)
- return response.redirect('/titles/show?src=login');
- return next();
- }
- console.log(request.route);
- if(!request.user && request.path !== '/')
- return response.redirect('/login');
+ if (!request.pid) {
+ request.pid = 1000000000;
+ }
+ return next();
+ }
+ // Login endpoint
+ if (request.path === '/login') {
+ if (request.pid) {
+ return response.redirect('/titles/show?src=login');
+ }
+ return next();
+ }
+ console.log(request.route);
+ if (!request.user && request.path !== '/') {
+ return response.redirect('/login');
+ }
- return next();
+ return next();
}
function isStartOfPath(path, value) {
- return path.indexOf(value) === 0;
+ return path.indexOf(value) === 0;
}
module.exports = auth;
diff --git a/src/models/communities.js b/src/models/communities.js
index 865fa41..349f32e 100644
--- a/src/models/communities.js
+++ b/src/models/communities.js
@@ -1,100 +1,100 @@
const { Schema, model } = require('mongoose');
const CommunitySchema = new Schema({
- platform_id: Number,
- name: String,
- description: String,
- open: {
- type: Boolean,
- default: true
- },
- allows_comments: {
- type: Boolean,
- default: true
- },
- /**
+ platform_id: Number,
+ name: String,
+ description: String,
+ open: {
+ type: Boolean,
+ default: true
+ },
+ allows_comments: {
+ type: Boolean,
+ default: true
+ },
+ /**
* 0: Main Community
* 1: Sub-Community
* 2: Announcement Community
* 3: Private Community
*/
- type: {
- type: Number,
- default: 0
- },
- parent: {
- type: String,
- default: null
- },
- admins: {
- type: [Number],
- default: undefined
- },
- created_at: {
- type: Date,
- default: new Date(),
- },
- empathy_count: {
- type: Number,
- default: 0
- },
- followers: {
- type: Number,
- default: 0
- },
- has_shop_page: {
- type: Number,
- default: 0
- },
- icon: String,
- title_ids: {
- type: [String],
- default: undefined
- },
- title_id: {
- type: [String],
- default: undefined
- },
- community_id: String,
- olive_community_id: String,
- is_recommended: {
- type: Number,
- default: 0
- },
- app_data: String,
+ type: {
+ type: Number,
+ default: 0
+ },
+ parent: {
+ type: String,
+ default: null
+ },
+ admins: {
+ type: [Number],
+ default: undefined
+ },
+ created_at: {
+ type: Date,
+ default: new Date(),
+ },
+ empathy_count: {
+ type: Number,
+ default: 0
+ },
+ followers: {
+ type: Number,
+ default: 0
+ },
+ has_shop_page: {
+ type: Number,
+ default: 0
+ },
+ icon: String,
+ title_ids: {
+ type: [String],
+ default: undefined
+ },
+ title_id: {
+ type: [String],
+ default: undefined
+ },
+ community_id: String,
+ olive_community_id: String,
+ is_recommended: {
+ type: Number,
+ default: 0
+ },
+ app_data: String,
});
CommunitySchema.methods.upEmpathy = async function() {
- const empathy = this.get('empathy_count');
- this.set('empathy_count', empathy + 1);
+ const empathy = this.get('empathy_count');
+ this.set('empathy_count', empathy + 1);
- await this.save();
+ await this.save();
};
CommunitySchema.methods.downEmpathy = async function() {
- const empathy = this.get('empathy_count');
- this.set('empathy_count', empathy - 1);
+ const empathy = this.get('empathy_count');
+ this.set('empathy_count', empathy - 1);
- await this.save();
+ await this.save();
};
CommunitySchema.methods.upFollower = async function() {
- const followers = this.get('followers');
- this.set('followers', followers + 1);
+ const followers = this.get('followers');
+ this.set('followers', followers + 1);
- await this.save();
+ await this.save();
};
CommunitySchema.methods.downFollower = async function() {
- const followers = this.get('followers');
- this.set('followers', followers - 1);
+ const followers = this.get('followers');
+ this.set('followers', followers - 1);
- await this.save();
+ await this.save();
};
const COMMUNITY = model('COMMUNITY', CommunitySchema);
module.exports = {
- CommunitySchema,
- COMMUNITY
+ CommunitySchema,
+ COMMUNITY
};
diff --git a/src/models/content.js b/src/models/content.js
index cae5841..19feb85 100644
--- a/src/models/content.js
+++ b/src/models/content.js
@@ -1,60 +1,60 @@
const { Schema, model } = require('mongoose');
const ContentSchema = new Schema({
- pid: Number,
- followed_communities: {
- type: [String],
- default: [0]
- },
- followed_users: {
- type: [Number],
- default: [0]
- },
- following_users: {
- type: [Number],
- default: [0]
- },
+ pid: Number,
+ followed_communities: {
+ type: [String],
+ default: [0]
+ },
+ followed_users: {
+ type: [Number],
+ default: [0]
+ },
+ following_users: {
+ type: [Number],
+ default: [0]
+ },
});
ContentSchema.methods.addToCommunities = async function(postID) {
- const communities = this.get('followed_communities');
- communities.addToSet(postID);
- await this.save();
-}
+ const communities = this.get('followed_communities');
+ communities.addToSet(postID);
+ await this.save();
+};
ContentSchema.methods.removeFromCommunities = async function(postID) {
- const communities = this.get('followed_communities');
- communities.pull(postID);
- await this.save();
-}
+ const communities = this.get('followed_communities');
+ communities.pull(postID);
+ await this.save();
+};
ContentSchema.methods.addToUsers = async function(postID) {
- const users = this.get('followed_users');
- users.addToSet(postID);
- await this.save();
-}
+ const users = this.get('followed_users');
+ users.addToSet(postID);
+ await this.save();
+};
ContentSchema.methods.removeFromUsers = async function(postID) {
- const users = this.get('followed_users');
- users.pull(postID);
- await this.save();
-}
+ const users = this.get('followed_users');
+ users.pull(postID);
+ await this.save();
+};
ContentSchema.methods.addToFollowers = async function(postID) {
- const users = this.get('following_users');
- users.addToSet(postID);
- await this.save();
-}
+ const users = this.get('following_users');
+ users.addToSet(postID);
+ await this.save();
+};
ContentSchema.methods.removeFromFollowers = async function(postID) {
- const users = this.get('following_users');
- users.pull(postID);
- await this.save();
-}
+ const users = this.get('following_users');
+ users.pull(postID);
+ await this.save();
+};
const CONTENT = model('CONTENT', ContentSchema);
module.exports = {
- ContentSchema,
- CONTENT
+ ContentSchema,
+ CONTENT
};
diff --git a/src/models/conversation.js b/src/models/conversation.js
index 5b7cea9..8911ce7 100644
--- a/src/models/conversation.js
+++ b/src/models/conversation.js
@@ -1,60 +1,60 @@
const { Schema, model } = require('mongoose');
-const moment = require("moment");
+const moment = require('moment');
const snowflake = require('node-snowflake').Snowflake;
const user = new Schema({
- pid: Number,
- official: {
- type: Boolean,
- default: false
- },
- read: {
- type: Boolean,
- default: true
- }
+ pid: Number,
+ official: {
+ type: Boolean,
+ default: false
+ },
+ read: {
+ type: Boolean,
+ default: true
+ }
});
const ConversationSchema = new Schema({
- id: {
- type: String,
- default: snowflake.nextId()
- },
- created_at: {
- type: Date,
- default: new Date(),
- },
- last_updated: {
- type: Date,
- default: new Date(),
- },
- message_preview: {
- type: String,
- default: ""
- },
- users: [user]
+ id: {
+ type: String,
+ default: snowflake.nextId()
+ },
+ created_at: {
+ type: Date,
+ default: new Date(),
+ },
+ last_updated: {
+ type: Date,
+ default: new Date(),
+ },
+ message_preview: {
+ type: String,
+ default: ''
+ },
+ users: [user]
});
ConversationSchema.methods.newMessage = async function(message, senderPID) {
- this.last_updated = new Date();
+ this.last_updated = new Date();
this.message_preview = message;
const sender = this.users.find(user => user.pid === senderPID);
if (sender) {
sender.read = false;
}
await this.save();
-}
+};
ConversationSchema.methods.markAsRead = async function(receiverPID) {
- const receiver = this.users.find(user => user.pid === receiverPID);
+ const receiver = this.users.find(user => user.pid === receiverPID);
if (receiver) {
receiver.read = true;
}
- await this.save();
-}
+ await this.save();
+};
const CONVERSATION = model('CONVERSATION', ConversationSchema);
module.exports = {
- ConversationSchema: ConversationSchema,
- CONVERSATION: CONVERSATION
+ ConversationSchema: ConversationSchema,
+ CONVERSATION: CONVERSATION
};
diff --git a/src/models/endpoint.js b/src/models/endpoint.js
index fe2a94b..7bfe091 100644
--- a/src/models/endpoint.js
+++ b/src/models/endpoint.js
@@ -1,19 +1,19 @@
const { Schema, model } = require('mongoose');
const endpointSchema = new Schema({
- status: Number,
- server_access_level: String,
- topics: Boolean,
- guest_access: Boolean,
- host: String,
- api_host: String,
- portal_host: String,
- n3ds_host: String
+ status: Number,
+ server_access_level: String,
+ topics: Boolean,
+ guest_access: Boolean,
+ host: String,
+ api_host: String,
+ portal_host: String,
+ n3ds_host: String,
});
const ENDPOINT = model('ENDPOINT', endpointSchema);
module.exports = {
- endpointSchema,
- ENDPOINT
+ endpointSchema,
+ ENDPOINT,
};
diff --git a/src/models/notifications.js b/src/models/notifications.js
index 0835463..5e603fe 100644
--- a/src/models/notifications.js
+++ b/src/models/notifications.js
@@ -1,26 +1,26 @@
const { Schema, model } = require('mongoose');
const NotificationSchema = new Schema({
- pid: String,
- type: String,
- link: String,
- objectID: String,
- users: [{
- user: String,
- timestamp: Date
- }],
- read: Boolean,
- lastUpdated: Date
+ pid: String,
+ type: String,
+ link: String,
+ objectID: String,
+ users: [{
+ user: String,
+ timestamp: Date
+ }],
+ read: Boolean,
+ lastUpdated: Date
});
NotificationSchema.methods.markRead = async function() {
- this.set('read', true);
- await this.save();
+ this.set('read', true);
+ await this.save();
};
const NOTIFICATION = model('NOTIFICATION', NotificationSchema);
module.exports = {
- NotificationSchema,
- NOTIFICATION
+ NotificationSchema,
+ NOTIFICATION
};
diff --git a/src/models/post.js b/src/models/post.js
index eb511ed..f83b19f 100644
--- a/src/models/post.js
+++ b/src/models/post.js
@@ -1,122 +1,124 @@
const { Schema, model } = require('mongoose');
const PostSchema = new Schema({
- id: String,
- title_id: String,
- screen_name: String,
- body: String,
- app_data: String,
- painting: String,
- screenshot: String,
- screenshot_length: Number,
- search_key: {
- type: [String],
- default: undefined
- },
- topic_tag: {
- type: String,
- default: undefined
- },
- community_id: {
- type: String,
- default: undefined
- },
- created_at: Date,
- feeling_id: Number,
- is_autopost: {
- type: Number,
- default: 0
- },
- is_community_private_autopost: {
- type: Number,
- default: 0
- },
- is_spoiler: {
- type: Number,
- default: 0
- },
- is_app_jumpable: {
- type: Number,
- default: 0
- },
- empathy_count: {
- type: Number,
- default: 0,
- min: 0
- },
- country_id: {
- type: Number,
- default: 49
- },
- language_id: {
- type: Number,
- default: 1
- },
- mii: String,
- mii_face_url: String,
- pid: Number,
- platform_id: Number,
- region_id: Number,
- parent: String,
- reply_count: {
- type: Number,
- default: 0
- },
- verified: {
- type: Boolean,
- default: false
- },
- message_to_pid: {
- type: String,
- default: null
- },
- removed: {
- type: Boolean,
- default: false
- },
- removed_reason: String,
- removed_by: Number,
- removed_at: Date,
- yeahs: [Number]
+ id: String,
+ title_id: String,
+ screen_name: String,
+ body: String,
+ app_data: String,
+ painting: String,
+ screenshot: String,
+ screenshot_length: Number,
+ search_key: {
+ type: [String],
+ default: undefined
+ },
+ topic_tag: {
+ type: String,
+ default: undefined
+ },
+ community_id: {
+ type: String,
+ default: undefined
+ },
+ created_at: Date,
+ feeling_id: Number,
+ is_autopost: {
+ type: Number,
+ default: 0
+ },
+ is_community_private_autopost: {
+ type: Number,
+ default: 0
+ },
+ is_spoiler: {
+ type: Number,
+ default: 0
+ },
+ is_app_jumpable: {
+ type: Number,
+ default: 0
+ },
+ empathy_count: {
+ type: Number,
+ default: 0,
+ min: 0
+ },
+ country_id: {
+ type: Number,
+ default: 49
+ },
+ language_id: {
+ type: Number,
+ default: 1
+ },
+ mii: String,
+ mii_face_url: String,
+ pid: Number,
+ platform_id: Number,
+ region_id: Number,
+ parent: String,
+ reply_count: {
+ type: Number,
+ default: 0
+ },
+ verified: {
+ type: Boolean,
+ default: false
+ },
+ message_to_pid: {
+ type: String,
+ default: null
+ },
+ removed: {
+ type: Boolean,
+ default: false
+ },
+ removed_reason: String,
+ removed_by: Number,
+ removed_at: Date,
+ yeahs: [Number]
});
PostSchema.methods.upReply = async function() {
- const replyCount = this.get('reply_count');
- if(replyCount + 1 < 0)
- this.set('reply_count', 0);
- else
- this.set('reply_count', replyCount + 1);
+ const replyCount = this.get('reply_count');
+ if (replyCount + 1 < 0) {
+ this.set('reply_count', 0);
+ } else {
+ this.set('reply_count', replyCount + 1);
+ }
- await this.save();
+ await this.save();
};
PostSchema.methods.downReply = async function() {
- const replyCount = this.get('reply_count');
- if(replyCount - 1 < 0)
- this.set('reply_count', 0);
- else
- this.set('reply_count', replyCount - 1);
+ const replyCount = this.get('reply_count');
+ if (replyCount - 1 < 0) {
+ this.set('reply_count', 0);
+ } else {
+ this.set('reply_count', replyCount - 1);
+ }
- await this.save();
+ await this.save();
};
PostSchema.methods.removePost = async function(reason, pid) {
- this.set('removed', true);
- this.set('removed_reason', reason);
- this.set('removed_by', pid);
- this.set('removed_at', new Date())
- await this.save();
+ this.set('removed', true);
+ this.set('removed_reason', reason);
+ this.set('removed_by', pid);
+ this.set('removed_at', new Date());
+ await this.save();
};
PostSchema.methods.unRemove = async function(reason) {
- this.set('removed', false);
- this.set('removed_reason', reason);
- await this.save();
+ this.set('removed', false);
+ this.set('removed_reason', reason);
+ await this.save();
};
const POST = model('POST', PostSchema);
module.exports = {
- PostSchema,
- POST
+ PostSchema,
+ POST
};
diff --git a/src/models/report.js b/src/models/report.js
index 7e1ebca..9544306 100644
--- a/src/models/report.js
+++ b/src/models/report.js
@@ -1,33 +1,33 @@
const { Schema, model } = require('mongoose');
const ReportSchema = new Schema({
- pid: Number,
- reported_by: Number,
- post_id: String,
- reason: Number,
- message: String,
- created_at: {
- type: Date,
- default: new Date()
- },
- resolved: {
- type: Boolean,
- default: false
- },
- resolved_by: Number,
- resolved_at: Date,
+ pid: Number,
+ reported_by: Number,
+ post_id: String,
+ reason: Number,
+ message: String,
+ created_at: {
+ type: Date,
+ default: new Date()
+ },
+ resolved: {
+ type: Boolean,
+ default: false
+ },
+ resolved_by: Number,
+ resolved_at: Date,
});
ReportSchema.methods.resolve = async function(pid) {
- this.set('resolved', true);
- this.set('resolved_by', pid);
- this.set('resolved_at', new Date())
- await this.save();
+ this.set('resolved', true);
+ this.set('resolved_by', pid);
+ this.set('resolved_at', new Date());
+ await this.save();
};
const REPORT = model('REPORT', ReportSchema);
module.exports = {
- ReportSchema,
- REPORT
+ ReportSchema,
+ REPORT
};
diff --git a/src/models/settings.js b/src/models/settings.js
index f23d101..1deea5d 100644
--- a/src/models/settings.js
+++ b/src/models/settings.js
@@ -1,95 +1,95 @@
const { Schema, model } = require('mongoose');
const SettingsSchema = new Schema({
- pid: Number,
- screen_name: String,
- account_status: {
- type: Number,
- default: 0
- },
- ban_lift_date: Date,
- ban_reason: String,
- profile_comment: {
- type: String,
- default: undefined
- },
- profile_comment_visibility: {
- type: Boolean,
- default: true
- },
- game_skill: {
- type: Number,
- default: 0
- },
- game_skill_visibility: {
- type: Boolean,
- default: true
- },
- birthday_visibility: {
- type: Boolean,
- default: false
- },
- relationship_visibility: {
- type: Boolean,
- default: false
- },
- country_visibility: {
- type: Boolean,
- default: false
- },
- profile_favorite_community_visibility: {
- type: Boolean,
- default: true
- },
- receive_notifications: {
- type: Boolean,
- default: true
- }
+ pid: Number,
+ screen_name: String,
+ account_status: {
+ type: Number,
+ default: 0
+ },
+ ban_lift_date: Date,
+ ban_reason: String,
+ profile_comment: {
+ type: String,
+ default: undefined
+ },
+ profile_comment_visibility: {
+ type: Boolean,
+ default: true
+ },
+ game_skill: {
+ type: Number,
+ default: 0
+ },
+ game_skill_visibility: {
+ type: Boolean,
+ default: true
+ },
+ birthday_visibility: {
+ type: Boolean,
+ default: false
+ },
+ relationship_visibility: {
+ type: Boolean,
+ default: false
+ },
+ country_visibility: {
+ type: Boolean,
+ default: false
+ },
+ profile_favorite_community_visibility: {
+ type: Boolean,
+ default: true
+ },
+ receive_notifications: {
+ type: Boolean,
+ default: true
+ }
});
SettingsSchema.methods.updateComment = async function(comment) {
- this.set('profile_comment', comment);
- await this.save();
+ this.set('profile_comment', comment);
+ await this.save();
};
SettingsSchema.methods.updateSkill = async function(skill) {
- this.set('game_skill', skill);
- await this.save();
+ this.set('game_skill', skill);
+ await this.save();
};
SettingsSchema.methods.commentVisible = async function(active) {
- this.set('profile_comment_visibility', active);
- await this.save();
+ this.set('profile_comment_visibility', active);
+ await this.save();
};
SettingsSchema.methods.skillVisible = async function(active) {
- this.set('game_skill_visibility', active);
- await this.save();
+ this.set('game_skill_visibility', active);
+ await this.save();
};
SettingsSchema.methods.birthdayVisible = async function(active) {
- this.set('birthday_visibility', active);
- await this.save();
+ this.set('birthday_visibility', active);
+ await this.save();
};
SettingsSchema.methods.relationshipVisible = async function(active) {
- this.set('relationship_visibility', active);
- await this.save();
+ this.set('relationship_visibility', active);
+ await this.save();
};
SettingsSchema.methods.countryVisible = async function(active) {
- this.set('country_visibility', active);
- await this.save();
+ this.set('country_visibility', active);
+ await this.save();
};
SettingsSchema.methods.favCommunityVisible = async function(active) {
- this.set('profile_favorite_community_visibility', active);
- await this.save();
+ this.set('profile_favorite_community_visibility', active);
+ await this.save();
};
const SETTINGS = model('SETTINGS', SettingsSchema);
module.exports = {
- SettingsSchema,
- SETTINGS
+ SettingsSchema,
+ SETTINGS
};
diff --git a/src/server.js b/src/server.js
index c9eb41f..606da01 100644
--- a/src/server.js
+++ b/src/server.js
@@ -17,18 +17,18 @@ app.set('etag', false);
app.disable('x-powered-by');
app.set('view engine', 'ejs');
app.set('views', __dirname + '/webfiles');
-app.set('trust proxy', 2)
-app.get('/ip', (request, response) => response.send(request.ip))
+app.set('trust proxy', 2);
+app.get('/ip', (request, response) => response.send(request.ip));
// Create router
logger.info('Setting up Middleware');
app.use(morgan('dev'));
-app.enable("trust proxy");
+app.enable('trust proxy');
app.use(express.json());
app.use(express.urlencoded({
- extended: true,
- limit: '1mb',
+ extended: true,
+ limit: '1mb',
}));
app.use(cookieParser());
@@ -41,35 +41,35 @@ app.use(juxt_web);
// 404 handler
logger.info('Creating 404 status handler');
app.use((req, res) => {
- logger.warn(req.protocol + '://' + req.get('host') + req.originalUrl);
- res.render(req.directory + '/error.ejs', {
- code: 404,
- message: "Page not found",
- cdnURL: config.CDN_domain,
- lang: req.lang,
- pid: req.pid
- });
+ logger.warn(req.protocol + '://' + req.get('host') + req.originalUrl);
+ res.render(req.directory + '/error.ejs', {
+ code: 404,
+ message: 'Page not found',
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ pid: req.pid
+ });
});
// non-404 error handler
logger.info('Creating non-404 status handler');
app.use((error, request, response) => {
- const status = error.status || 500;
+ const status = error.status || 500;
- response.status(status);
+ response.status(status);
- response.json({
- app: 'api',
- status,
- error: error.message
- });
+ response.json({
+ app: 'api',
+ status,
+ error: error.message
+ });
});
// Starts the server
logger.info('Starting server');
database.connect().then(() => {
- app.listen(port, () => {
- logger.success(`Server started on port ${port}`);
- });
+ app.listen(port, () => {
+ logger.success(`Server started on port ${port}`);
+ });
});
diff --git a/src/services/juxt-web/routes/admin/admin.js b/src/services/juxt-web/routes/admin/admin.js
index ef3b7f0..a1ea5c3 100644
--- a/src/services/juxt-web/routes/admin/admin.js
+++ b/src/services/juxt-web/routes/admin/admin.js
@@ -3,55 +3,62 @@ const database = require('../../../../database');
const { POST } = require('../../../../models/post');
const util = require('../../../../util');
const moment = require('moment');
-const config = require("../../../../../config.json");
+const config = require('../../../../../config.json');
const router = express.Router();
router.get('/', async function (req, res) {
- if(!req.moderator)
- return res.redirect('/login');
+ if (!req.moderator) {
+ return res.redirect('/login');
+ }
- const reports = await database.getAllOpenReports();
- const communityMap = await util.data.getCommunityHash();
- const userContent = await database.getUserContent(req.pid);
- const userMap = util.data.getUserHash();
- const postIDs = reports.map(obj => obj.post_id);
+ const reports = await database.getAllOpenReports();
+ const communityMap = await util.data.getCommunityHash();
+ const userContent = await database.getUserContent(req.pid);
+ const userMap = util.data.getUserHash();
+ const postIDs = reports.map(obj => obj.post_id);
- const posts = await POST.aggregate([
- { $match: { id: { $in: postIDs } } },
- {$addFields: {
- "__order": { $indexOfArray: [ postIDs, "$id" ] }
- }},
- { $sort: { "__order": 1 } },
- { $project: { index: 0, _id: 0 } }
- ]);
+ const posts = await POST.aggregate([
+ { $match: { id: { $in: postIDs } } },
+ {$addFields: {
+ '__order': { $indexOfArray: [ postIDs, '$id' ] }
+ }},
+ { $sort: { '__order': 1 } },
+ { $project: { index: 0, _id: 0 } }
+ ]);
- res.render(req.directory + '/reports.ejs', {
- lang: req.lang,
- moment: moment,
- cdnURL: config.CDN_domain,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- moderator: req.moderator,
- userMap,
- communityMap,
- userContent,
- reports,
- posts
- });
+ res.render(req.directory + '/reports.ejs', {
+ lang: req.lang,
+ moment: moment,
+ cdnURL: config.CDN_domain,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ moderator: req.moderator,
+ userMap,
+ communityMap,
+ userContent,
+ reports,
+ posts
+ });
});
router.delete('/:reportID', async function (req, res) {
- let report = await database.getReportById(req.params.reportID);
- if(!report) return res.sendStatus(402);
- let post = await database.getPostByID(report.post_id);
- if(!post) return res.sendStatus(404);
+ const report = await database.getReportById(req.params.reportID);
+ if (!report) {
+ return res.sendStatus(402);
+ }
+ const post = await database.getPostByID(report.post_id);
+ if (!post) {
+ return res.sendStatus(404);
+ }
- if(!req.moderator) return res.sendStatus(401);
+ if (!req.moderator) {
+ return res.sendStatus(401);
+ }
- await post.removePost(req.query.reason ? req.query.reason : 'Removed by moderator', req.pid);
- await report.resolve(req.pid);
+ await post.removePost(req.query.reason ? req.query.reason : 'Removed by moderator', req.pid);
+ await report.resolve(req.pid);
- return res.sendStatus(200);
+ return res.sendStatus(200);
});
module.exports = router;
diff --git a/src/services/juxt-web/routes/console/communities.js b/src/services/juxt-web/routes/console/communities.js
index 268822a..a6dd75b 100644
--- a/src/services/juxt-web/routes/console/communities.js
+++ b/src/services/juxt-web/routes/console/communities.js
@@ -10,225 +10,235 @@ const { POST } = require('../../../../models/post');
const { COMMUNITY } = require('../../../../models/communities');
router.get('/', async function (req, res) {
- let newCommunities = await database.getNewCommunities(6);
- let last24Hours = await calculateMostPopularCommunities();
- let popularCommunities = await COMMUNITY.aggregate([
- { $match: { olive_community_id: { $in: last24Hours }, parent: null } },
- {$addFields: {
- index: { $indexOfArray: [ last24Hours, "$olive_community_id" ] }
- }},
- { $sort: { index: 1 } },
- { $limit : 9 },
- { $project: { index: 0, _id: 0 } }
- ]);
- res.render(req.directory + '/communities.ejs', {
- cache: true,
- popularCommunities: popularCommunities,
- newCommunities: newCommunities,
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- moderator: req.moderator
- });
+ const newCommunities = await database.getNewCommunities(6);
+ const last24Hours = await calculateMostPopularCommunities();
+ const popularCommunities = await COMMUNITY.aggregate([
+ { $match: { olive_community_id: { $in: last24Hours }, parent: null } },
+ {$addFields: {
+ index: { $indexOfArray: [ last24Hours, '$olive_community_id' ] }
+ }},
+ { $sort: { index: 1 } },
+ { $limit : 9 },
+ { $project: { index: 0, _id: 0 } }
+ ]);
+ res.render(req.directory + '/communities.ejs', {
+ cache: true,
+ popularCommunities: popularCommunities,
+ newCommunities: newCommunities,
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ moderator: req.moderator
+ });
});
router.get('/all', async function (req, res) {
- let communities = await database.getCommunities(90);
- res.render(req.directory + '/all_communities.ejs', {
- communities: communities,
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- moderator: req.moderator
- });
+ const communities = await database.getCommunities(90);
+ res.render(req.directory + '/all_communities.ejs', {
+ communities: communities,
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ moderator: req.moderator
+ });
});
router.get('/:communityID', async function (req, res) {
- if(req.query.title_id) {
- let community = await database.getCommunityByTitleID(req.query.title_id);
- if(!community) return res.redirect('/404');
- return res.redirect(`/titles/${community.olive_community_id}/new`);
- }
- res.redirect(`/titles/${req.params.communityID}/new`);
+ if (req.query.title_id) {
+ const community = await database.getCommunityByTitleID(req.query.title_id);
+ if (!community) {
+ return res.redirect('/404');
+ }
+ return res.redirect(`/titles/${community.olive_community_id}/new`);
+ }
+ res.redirect(`/titles/${req.params.communityID}/new`);
});
router.get('/:communityID/related', async function (req, res) {
- let userSettings = await database.getUserSettings(req.pid);
- let userContent = await database.getUserContent(req.pid);
- if(!userContent || !userSettings)
- return res.redirect('/404');
- let community = await database.getCommunityByID(req.params.communityID.toString());
- if(!community) return res.render(req.directory + '/error.ejs', {code: 404, message: "Community not Found", pid: req.pid, lang: req.lang, cdnURL: config.CDN_domain });
- let communityMap = await util.data.getCommunityHash();
- let children = await database.getSubCommunities(community.olive_community_id);
- if(!children)
- return res.redirect(`/titles/${community.olive_community_id}/new`);
+ const userSettings = await database.getUserSettings(req.pid);
+ const userContent = await database.getUserContent(req.pid);
+ if (!userContent || !userSettings) {
+ return res.redirect('/404');
+ }
+ const community = await database.getCommunityByID(req.params.communityID.toString());
+ if (!community) {
+ return res.render(req.directory + '/error.ejs', {code: 404, message: 'Community not Found', pid: req.pid, lang: req.lang, cdnURL: config.CDN_domain });
+ }
+ const communityMap = await util.data.getCommunityHash();
+ const children = await database.getSubCommunities(community.olive_community_id);
+ if (!children) {
+ return res.redirect(`/titles/${community.olive_community_id}/new`);
+ }
- res.render(req.directory + '/sub_communities.ejs', {
- selection: 2,
- communityMap,
- community,
- children,
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- moderator: req.moderator
- });
+ res.render(req.directory + '/sub_communities.ejs', {
+ selection: 2,
+ communityMap,
+ community,
+ children,
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ moderator: req.moderator
+ });
});
router.get('/:communityID/:type', async function (req, res) {
- let userSettings = await database.getUserSettings(req.pid);
- let userContent = await database.getUserContent(req.pid);
- if(!userContent || !userSettings)
- return res.redirect('/404');
- let community = await database.getCommunityByID(req.params.communityID.toString());
- if(!community) return res.render(req.directory + '/error.ejs', {code: 404, message: "Community not Found", pid: req.pid, lang: req.lang, cdnURL: config.CDN_domain });
- let communityMap = await util.data.getCommunityHash();
- let children = await database.getSubCommunities(community.olive_community_id);
- if(children.length === 0)
- children = null;
- let posts, type;
+ const userSettings = await database.getUserSettings(req.pid);
+ const userContent = await database.getUserContent(req.pid);
+ if (!userContent || !userSettings) {
+ return res.redirect('/404');
+ }
+ const community = await database.getCommunityByID(req.params.communityID.toString());
+ if (!community) {
+ return res.render(req.directory + '/error.ejs', {code: 404, message: 'Community not Found', pid: req.pid, lang: req.lang, cdnURL: config.CDN_domain });
+ }
+ const communityMap = await util.data.getCommunityHash();
+ let children = await database.getSubCommunities(community.olive_community_id);
+ if (children.length === 0) {
+ children = null;
+ }
+ let posts; let type;
- if(req.params.type === 'hot') {
- posts = await database.getNumberPopularCommunityPostsByID(community, config.post_limit);
- type = 1;
- } else if(req.params.type === 'verified') {
- posts = await database.getNumberVerifiedCommunityPostsByID(community, config.post_limit);
- type = 2;
- } else {
- posts = await database.getNewPostsByCommunity(community, config.post_limit);
- type = 0;
- }
- let numPosts = await database.getTotalPostsByCommunity(community)
+ if (req.params.type === 'hot') {
+ posts = await database.getNumberPopularCommunityPostsByID(community, config.post_limit);
+ type = 1;
+ } else if (req.params.type === 'verified') {
+ posts = await database.getNumberVerifiedCommunityPostsByID(community, config.post_limit);
+ type = 2;
+ } else {
+ posts = await database.getNewPostsByCommunity(community, config.post_limit);
+ type = 0;
+ }
+ const numPosts = await database.getTotalPostsByCommunity(community);
- let bundle = {
- posts,
- open: community.open,
- numPosts,
- communityMap,
- userContent,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- link: `/titles/${req.params.communityID}/${req.params.type}/more?offset=${posts.length}&pjax=true`
- }
+ const bundle = {
+ posts,
+ open: community.open,
+ numPosts,
+ communityMap,
+ userContent,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ link: `/titles/${req.params.communityID}/${req.params.type}/more?offset=${posts.length}&pjax=true`
+ };
- if(req.query.pjax)
- return res.render(req.directory + '/partials/posts_list.ejs', {
- bundle,
- moment,
- lang: req.lang
- });
+ if (req.query.pjax) {
+ return res.render(req.directory + '/partials/posts_list.ejs', {
+ bundle,
+ moment,
+ lang: req.lang
+ });
+ }
- res.render(req.directory + '/community.ejs', {
- // EJS variable and server-side variable
- moment: moment,
- community: community,
- communityMap: communityMap,
- posts: posts,
- totalNumPosts: numPosts,
- userSettings: userSettings,
- userContent: userContent,
- account_server: config.account_server_domain.slice(8),
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- children,
- type,
- bundle,
- template: 'posts_list',
- moderator: req.moderator
- });
+ res.render(req.directory + '/community.ejs', {
+ // EJS variable and server-side variable
+ moment: moment,
+ community: community,
+ communityMap: communityMap,
+ posts: posts,
+ totalNumPosts: numPosts,
+ userSettings: userSettings,
+ userContent: userContent,
+ account_server: config.account_server_domain.slice(8),
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ children,
+ type,
+ bundle,
+ template: 'posts_list',
+ moderator: req.moderator
+ });
});
router.get('/:communityID/:type/more', async function (req, res) {
- let offset = parseInt(req.query.offset);
- let userContent = await database.getUserContent(req.pid);
- let communityMap = await util.data.getCommunityHash();
- let posts;
- let community = await database.getCommunityByID(req.params.communityID)
- if(!community) return res.redirect('/404');
- if(!offset)
- offset = 0;
- switch (req.params.type) {
- case 'popular':
- posts = await database.getNumberPopularCommunityPostsByID(community, config.post_limit, offset);
- break;
- case 'verified':
- posts = await database.getNumberVerifiedCommunityPostsByID(community, config.post_limit, offset);
- break;
- default:
- posts = await database.getNewPostsByCommunity(community, config.post_limit, offset);
- break;
- }
+ let offset = parseInt(req.query.offset);
+ const userContent = await database.getUserContent(req.pid);
+ const communityMap = await util.data.getCommunityHash();
+ let posts;
+ const community = await database.getCommunityByID(req.params.communityID);
+ if (!community) {
+ return res.redirect('/404');
+ }
+ if (!offset) {
+ offset = 0;
+ }
+ switch (req.params.type) {
+ case 'popular':
+ posts = await database.getNumberPopularCommunityPostsByID(community, config.post_limit, offset);
+ break;
+ case 'verified':
+ posts = await database.getNumberVerifiedCommunityPostsByID(community, config.post_limit, offset);
+ break;
+ default:
+ posts = await database.getNewPostsByCommunity(community, config.post_limit, offset);
+ break;
+ }
- let bundle = {
- posts,
- open: true,
- numPosts: posts.length,
- communityMap,
- userContent,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- link: `/titles/${req.params.communityID}/${req.params.type}/more?offset=${offset + posts.length}&pjax=true`
- }
+ const bundle = {
+ posts,
+ open: true,
+ numPosts: posts.length,
+ communityMap,
+ userContent,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ link: `/titles/${req.params.communityID}/${req.params.type}/more?offset=${offset + posts.length}&pjax=true`
+ };
- if(posts.length > 0)
- {
- res.render(req.directory + '/partials/posts_list.ejs', {
- communityMap: communityMap,
- moment: moment,
- database: database,
- bundle,
- account_server: config.account_server_domain.slice(8),
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- moderator: req.moderator
- });
- }
- else
- res.sendStatus(204);
+ if (posts.length > 0) {
+ res.render(req.directory + '/partials/posts_list.ejs', {
+ communityMap: communityMap,
+ moment: moment,
+ database: database,
+ bundle,
+ account_server: config.account_server_domain.slice(8),
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ moderator: req.moderator
+ });
+ } else {
+ res.sendStatus(204);
+ }
});
router.post('/follow', upload.none(), async function (req, res) {
- let community = await database.getCommunityByID(req.body.id);
- let userContent = await database.getUserContent(req.pid);
- if(userContent !== null && userContent.followed_communities.indexOf(community.olive_community_id) === -1)
- {
- community.upFollower();
- userContent.addToCommunities(community.olive_community_id);
- res.send({ status: 200, id: community.olive_community_id, count: community.followers });
- }
- else if(userContent !== null && userContent.followed_communities.indexOf(community.olive_community_id) !== -1)
- {
- community.downFollower();
- userContent.removeFromCommunities(community.olive_community_id);
- res.send({ status: 200, id: community.olive_community_id, count: community.followers });
- }
- else
- res.send({ status: 423, id: community.olive_community_id, count: community.followers });
+ const community = await database.getCommunityByID(req.body.id);
+ const userContent = await database.getUserContent(req.pid);
+ if (userContent !== null && userContent.followed_communities.indexOf(community.olive_community_id) === -1) {
+ community.upFollower();
+ userContent.addToCommunities(community.olive_community_id);
+ res.send({ status: 200, id: community.olive_community_id, count: community.followers });
+ } else if (userContent !== null && userContent.followed_communities.indexOf(community.olive_community_id) !== -1) {
+ community.downFollower();
+ userContent.removeFromCommunities(community.olive_community_id);
+ res.send({ status: 200, id: community.olive_community_id, count: community.followers });
+ } else {
+ res.send({ status: 423, id: community.olive_community_id, count: community.followers });
+ }
});
async function calculateMostPopularCommunities() {
- const now = new Date();
- const last24Hours = new Date(now.getTime() - 24 * 60 * 60 * 1000);
+ const now = new Date();
+ const last24Hours = new Date(now.getTime() - 24 * 60 * 60 * 1000);
- const posts = await POST.find({ created_at: { $gte: last24Hours }, message_to_pid: null }).lean();
+ const posts = await POST.find({ created_at: { $gte: last24Hours }, message_to_pid: null }).lean();
- const communityIds = {};
- for (const post of posts) {
- const communityId = post.community_id;
- communityIds[communityId] = (communityIds[communityId] || 0) + 1;
- }
- return Object.entries(communityIds)
- .sort((a, b) => b[1] - a[1])
- .map((entry) => entry[0]);
+ const communityIds = {};
+ for (const post of posts) {
+ const communityId = post.community_id;
+ communityIds[communityId] = (communityIds[communityId] || 0) + 1;
+ }
+ return Object.entries(communityIds)
+ .sort((a, b) => b[1] - a[1])
+ .map((entry) => entry[0]);
}
module.exports = router;
diff --git a/src/services/juxt-web/routes/console/feed.js b/src/services/juxt-web/routes/console/feed.js
index 0d7af69..0b4ad85 100644
--- a/src/services/juxt-web/routes/console/feed.js
+++ b/src/services/juxt-web/routes/console/feed.js
@@ -6,83 +6,85 @@ const moment = require('moment');
const router = express.Router();
router.get('/', async function (req, res) {
- let userContent = await database.getUserContent(req.pid);
- let communityMap = await util.data.getCommunityHash();
- if(!userContent)
- return res.redirect('/404');
- let posts = await database.getNewsFeed(userContent, config.post_limit);
+ const userContent = await database.getUserContent(req.pid);
+ const communityMap = await util.data.getCommunityHash();
+ if (!userContent) {
+ return res.redirect('/404');
+ }
+ const posts = await database.getNewsFeed(userContent, config.post_limit);
- let bundle = {
- posts,
- open: true,
- communityMap,
- userContent,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- link: `/feed/more?offset=${posts.length}&pjax=true`
- }
+ const bundle = {
+ posts,
+ open: true,
+ communityMap,
+ userContent,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ link: `/feed/more?offset=${posts.length}&pjax=true`
+ };
- if(req.query.pjax)
- return res.render(req.directory + '/partials/posts_list.ejs', {
- bundle,
- moment,
- lang: req.lang
- });
+ if (req.query.pjax) {
+ return res.render(req.directory + '/partials/posts_list.ejs', {
+ bundle,
+ moment,
+ lang: req.lang
+ });
+ }
- res.render(req.directory + '/feed.ejs', {
- moment: moment,
- title: req.lang.global.activity_feed,
- userContent: userContent,
- posts: posts,
- communityMap: communityMap,
- account_server: config.account_server_domain.slice(8),
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- bundle,
- template: 'posts_list',
- moderator: req.moderator
- });
+ res.render(req.directory + '/feed.ejs', {
+ moment: moment,
+ title: req.lang.global.activity_feed,
+ userContent: userContent,
+ posts: posts,
+ communityMap: communityMap,
+ account_server: config.account_server_domain.slice(8),
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ bundle,
+ template: 'posts_list',
+ moderator: req.moderator
+ });
});
router.get('/more', async function (req, res) {
- let offset = parseInt(req.query.offset);
- let userContent = await database.getUserContent(req.pid);
- let communityMap = await util.data.getCommunityHash();
- let posts;
- if(!offset) offset = 0;
- posts = await database.getNewsFeedOffset(userContent, config.post_limit, offset);
+ let offset = parseInt(req.query.offset);
+ const userContent = await database.getUserContent(req.pid);
+ const communityMap = await util.data.getCommunityHash();
+ if (!offset) {
+ offset = 0;
+ }
+ const posts = await database.getNewsFeedOffset(userContent, config.post_limit, offset);
- let bundle = {
- posts,
- numPosts: posts.length,
- open: true,
- communityMap,
- userContent,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- link: `/feed/more?offset=${offset + posts.length}&pjax=true`,
- moderator: req.moderator
- }
+ const bundle = {
+ posts,
+ numPosts: posts.length,
+ open: true,
+ communityMap,
+ userContent,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ link: `/feed/more?offset=${offset + posts.length}&pjax=true`,
+ moderator: req.moderator
+ };
- if(posts.length > 0)
- {
- res.render(req.directory + '/partials/posts_list.ejs', {
- communityMap: communityMap,
- moment: moment,
- database: database,
- bundle,
- account_server: config.account_server_domain.slice(8),
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- moderator: req.moderator
- });
- }
- else
- res.sendStatus(204);
+ if (posts.length > 0) {
+ res.render(req.directory + '/partials/posts_list.ejs', {
+ communityMap: communityMap,
+ moment: moment,
+ database: database,
+ bundle,
+ account_server: config.account_server_domain.slice(8),
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ moderator: req.moderator
+ });
+ } else {
+ res.sendStatus(204);
+ }
});
module.exports = router;
diff --git a/src/services/juxt-web/routes/console/messages.js b/src/services/juxt-web/routes/console/messages.js
index 2b9467f..b2f5637 100644
--- a/src/services/juxt-web/routes/console/messages.js
+++ b/src/services/juxt-web/routes/console/messages.js
@@ -4,220 +4,233 @@ const util = require('../../../../util');
const config = require('../../../../../config.json');
const { POST } = require('../../../../models/post');
const moment = require('moment');
-const {CONVERSATION} = require("../../../../models/conversation");
-const crypto = require("crypto");
+const {CONVERSATION} = require('../../../../models/conversation');
+const crypto = require('crypto');
const snowflake = require('node-snowflake').Snowflake;
const router = express.Router();
router.get('/', async function (req, res) {
- let conversations = await database.getConversations(req.pid);
- let usersMap = await util.data.getUserHash();
- res.render(req.directory + '/messages.ejs', {
- moment: moment,
- pid: req.pid,
- conversations: conversations,
- cdnURL: config.CDN_domain,
- usersMap: usersMap,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- moderator: req.moderator
- });
+ const conversations = await database.getConversations(req.pid);
+ const usersMap = await util.data.getUserHash();
+ res.render(req.directory + '/messages.ejs', {
+ moment: moment,
+ pid: req.pid,
+ conversations: conversations,
+ cdnURL: config.CDN_domain,
+ usersMap: usersMap,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ moderator: req.moderator
+ });
});
router.post('/new', async function (req, res, next) {
- let conversation = await database.getConversationByID(req.body.community_id);
- let user2 = await util.data.getUserDataFromPid(req.body.message_to_pid);
- let postID = await generatePostUID(21);
- let friends = await util.data.getFriends(user2.pid);
- if(req.body.community_id === 0)
- return res.sendStatus(404);
- if(!conversation) {
- if(!user || !user2)
- return res.sendStatus(422)
- let document = {
- id: snowflake.nextId(),
- users: [
- {
- pid: req.pid,
- official: (req.user.accessLevel >= 2),
- read: true
- },
- {
- pid: user2.pid,
- official: (user2.accessLevel >= 2),
- read: false
- },
- ]
- };
- const newConversations = new CONVERSATION(document);
- await newConversations.save();
- conversation = await database.getConversationByID(document.id);
- }
- if(!conversation)
- return res.sendStatus(404);
- if(!friends || friends.indexOf(req.pid) === -1)
- return res.sendStatus(422);
- if(req.body.body === '' && req.body.painting === '' && req.body.screenshot === '') {
- res.status(422);
- return res.redirect(`/friend_messages/${conversation.id}`);
- }
- let painting = "", paintingURI = "", screenshot = null;
- if (req.body._post_type === 'painting' && req.body.painting) {
- painting = req.body.painting.replace(/\0/g, "").trim();
- paintingURI = await util.data.processPainting(painting, true);
- await util.data.uploadCDNAsset('pn-cdn', `paintings/${req.pid}/${postID}.png`, paintingURI, 'public-read');
- }
- if (req.body.screenshot) {
- screenshot = req.body.screenshot.replace(/\0/g, "").trim();
- await util.data.uploadCDNAsset('pn-cdn', `screenshots/${req.pid}/${postID}.jpg`, Buffer.from(screenshot, 'base64'), 'public-read');
- }
+ let conversation = await database.getConversationByID(req.body.community_id);
+ const user2 = await util.data.getUserDataFromPid(req.body.message_to_pid);
+ const postID = await generatePostUID(21);
+ const friends = await util.data.getFriends(user2.pid);
+ if (req.body.community_id === 0) {
+ return res.sendStatus(404);
+ }
+ if (!conversation) {
+ if (!user || !user2) {
+ return res.sendStatus(422);
+ }
+ const document = {
+ id: snowflake.nextId(),
+ users: [
+ {
+ pid: req.pid,
+ official: (req.user.accessLevel >= 2),
+ read: true
+ },
+ {
+ pid: user2.pid,
+ official: (user2.accessLevel >= 2),
+ read: false
+ },
+ ]
+ };
+ const newConversations = new CONVERSATION(document);
+ await newConversations.save();
+ conversation = await database.getConversationByID(document.id);
+ }
+ if (!conversation) {
+ return res.sendStatus(404);
+ }
+ if (!friends || friends.indexOf(req.pid) === -1) {
+ return res.sendStatus(422);
+ }
+ if (req.body.body === '' && req.body.painting === '' && req.body.screenshot === '') {
+ res.status(422);
+ return res.redirect(`/friend_messages/${conversation.id}`);
+ }
+ let painting = ''; let paintingURI = ''; let screenshot = null;
+ if (req.body._post_type === 'painting' && req.body.painting) {
+ painting = req.body.painting.replace(/\0/g, '').trim();
+ paintingURI = await util.data.processPainting(painting, true);
+ await util.data.uploadCDNAsset('pn-cdn', `paintings/${req.pid}/${postID}.png`, paintingURI, 'public-read');
+ }
+ if (req.body.screenshot) {
+ screenshot = req.body.screenshot.replace(/\0/g, '').trim();
+ await util.data.uploadCDNAsset('pn-cdn', `screenshots/${req.pid}/${postID}.jpg`, Buffer.from(screenshot, 'base64'), 'public-read');
+ }
- let miiFace;
- switch (parseInt(req.body.feeling_id)) {
- case 1:
- miiFace = 'smile_open_mouth.png';
- break;
- case 2:
- miiFace = 'wink_left.png';
- break;
- case 3:
- miiFace = 'surprise_open_mouth.png';
- break;
- case 4:
- miiFace = 'frustrated.png';
- break;
- case 5:
- miiFace = 'sorrow.png';
- break;
- default:
- miiFace = 'normal_face.png';
- break;
- }
- let body = req.body.body;
- if(body)
- body = req.body.body.replace(/[^A-Za-z\d\s-_!@#$%^&*(){}‛¨ƒºª«»“”„¿¡←→↑↓√§¶†‡¦–—⇒⇔¤¢€£¥™©®+×÷=±∞ˇ˘˙¸˛˜′″µ°¹²³♭♪•…¬¯‰¼½¾♡♥●◆■▲▼☆★♀♂,./?;:'"\\<>]/g, "");
- if(body.length > 280)
- body = body.substring(0,280);
- const document = {
- community_id: conversation.id,
- screen_name: req.user.mii.name,
- body: body,
- painting: painting,
- screenshot: screenshot ? `/screenshots/${req.pid}/${postID}.jpg`: "",
- country_id: req.paramPackData ? req.paramPackData.country_id : 49,
- created_at: new Date(),
- feeling_id: req.body.feeling_id,
- id: postID,
- is_autopost: 0,
- is_spoiler: (req.body.spoiler) ? 1 : 0,
- is_app_jumpable: req.body.is_app_jumpable,
- language_id: req.body.language_id,
- mii: req.user.mii.data,
- mii_face_url: `https://mii.olv.pretendo.cc/mii/${req.pid}/${miiFace}`,
- pid: req.pid,
- platform_id: req.paramPackData ? req.paramPackData.platform_id : 0,
- region_id: req.paramPackData ? req.paramPackData.region_id : 2,
- verified: (req.user.accessLevel >= 2),
- message_to_pid: req.body.message_to_pid,
- moderator: req.moderator
- };
- let duplicatePost = await database.getDuplicatePosts(req.pid, document);
- if(duplicatePost && req.params.post_id)
- return res.redirect('/posts/' + req.params.post_id);
- const newPost = new POST(document);
- newPost.save();
- res.redirect(`/friend_messages/${conversation.id}`);
- let postPreviewText;
- if(document.painting)
- postPreviewText = 'sent a Drawing'
- else if(document.body.length > 25)
- postPreviewText = document.body.substring(0, 25) + '...';
- else
- postPreviewText = document.body;
- await conversation.newMessage(postPreviewText, user2.pid);
+ let miiFace;
+ switch (parseInt(req.body.feeling_id)) {
+ case 1:
+ miiFace = 'smile_open_mouth.png';
+ break;
+ case 2:
+ miiFace = 'wink_left.png';
+ break;
+ case 3:
+ miiFace = 'surprise_open_mouth.png';
+ break;
+ case 4:
+ miiFace = 'frustrated.png';
+ break;
+ case 5:
+ miiFace = 'sorrow.png';
+ break;
+ default:
+ miiFace = 'normal_face.png';
+ break;
+ }
+ let body = req.body.body;
+ if (body) {
+ body = req.body.body.replace(/[^A-Za-z\d\s-_!@#$%^&*(){}‛¨ƒºª«»“”„¿¡←→↑↓√§¶†‡¦–—⇒⇔¤¢€£¥™©®+×÷=±∞ˇ˘˙¸˛˜′″µ°¹²³♭♪•…¬¯‰¼½¾♡♥●◆■▲▼☆★♀♂,./?;:'"\\<>]/g, '');
+ }
+ if (body.length > 280) {
+ body = body.substring(0,280);
+ }
+ const document = {
+ community_id: conversation.id,
+ screen_name: req.user.mii.name,
+ body: body,
+ painting: painting,
+ screenshot: screenshot ? `/screenshots/${req.pid}/${postID}.jpg`: '',
+ country_id: req.paramPackData ? req.paramPackData.country_id : 49,
+ created_at: new Date(),
+ feeling_id: req.body.feeling_id,
+ id: postID,
+ is_autopost: 0,
+ is_spoiler: (req.body.spoiler) ? 1 : 0,
+ is_app_jumpable: req.body.is_app_jumpable,
+ language_id: req.body.language_id,
+ mii: req.user.mii.data,
+ mii_face_url: `https://mii.olv.pretendo.cc/mii/${req.pid}/${miiFace}`,
+ pid: req.pid,
+ platform_id: req.paramPackData ? req.paramPackData.platform_id : 0,
+ region_id: req.paramPackData ? req.paramPackData.region_id : 2,
+ verified: (req.user.accessLevel >= 2),
+ message_to_pid: req.body.message_to_pid,
+ moderator: req.moderator
+ };
+ const duplicatePost = await database.getDuplicatePosts(req.pid, document);
+ if (duplicatePost && req.params.post_id) {
+ return res.redirect('/posts/' + req.params.post_id);
+ }
+ const newPost = new POST(document);
+ newPost.save();
+ res.redirect(`/friend_messages/${conversation.id}`);
+ let postPreviewText;
+ if (document.painting) {
+ postPreviewText = 'sent a Drawing';
+ } else if (document.body.length > 25) {
+ postPreviewText = document.body.substring(0, 25) + '...';
+ } else {
+ postPreviewText = document.body;
+ }
+ await conversation.newMessage(postPreviewText, user2.pid);
});
router.get('/new/:pid', async function (req, res, next) {
- let user = await util.data.getUserDataFromPid(req.pid);
- let user2 = await util.data.getUserDataFromPid(req.params.pid);
- let friends = await util.data.getFriends(user2.pid);
- if(!req.user || !user2)
- return res.sendStatus(422)
- let conversation = await database.getConversationByUsers([req.pid, user2.pid]);
- if(conversation)
- return res.redirect(`/friend_messages/${conversation.id}`);
- if(!friends || friends.indexOf(req.pid) === -1)
- return res.sendStatus(422);
- let document = {
- id: snowflake.nextId(),
- users: [
- {
- pid: req.user.pid,
- official: (req.user.accessLevel >= 2),
- read: true
- },
- {
- pid: user2.pid,
- official: (user2.accessLevel >= 2),
- read: false
- },
- ]
- };
- const newConversations = new CONVERSATION(document);
- await newConversations.save();
- conversation = await database.getConversationByID(document.id);
- if(!conversation)
- return res.sendStatus(404);
- let body = `${req.user.mii.name} started a new chat!`;
- let newMessage = {
- screen_name: req.user.mii.name,
- body: body,
- created_at: new Date(),
- id: await generatePostUID(21),
- mii: req.user.mii.data,
- mii_face_url: `https://mii.olv.pretendo.cc/mii/${req.pid}/normal_face.png`,
- pid: req.pid,
- verified: (req.user.accessLevel >= 2),
- parent: null,
- community_id: conversation.id,
- message_to_pid: user2.pid
- };
- const newPost = new POST(newMessage);
- newPost.save();
- await conversation.newMessage(`${req.user.mii.name} started a new chat!`, user2.pid);
- res.redirect(`/friend_messages/${conversation.id}`);
+ const user = await util.data.getUserDataFromPid(req.pid);
+ const user2 = await util.data.getUserDataFromPid(req.params.pid);
+ const friends = await util.data.getFriends(user2.pid);
+ if (!req.user || !user2) {
+ return res.sendStatus(422);
+ }
+ let conversation = await database.getConversationByUsers([req.pid, user2.pid]);
+ if (conversation) {
+ return res.redirect(`/friend_messages/${conversation.id}`);
+ }
+ if (!friends || friends.indexOf(req.pid) === -1) {
+ return res.sendStatus(422);
+ }
+ const document = {
+ id: snowflake.nextId(),
+ users: [
+ {
+ pid: req.user.pid,
+ official: (req.user.accessLevel >= 2),
+ read: true
+ },
+ {
+ pid: user2.pid,
+ official: (user2.accessLevel >= 2),
+ read: false
+ },
+ ]
+ };
+ const newConversations = new CONVERSATION(document);
+ await newConversations.save();
+ conversation = await database.getConversationByID(document.id);
+ if (!conversation) {
+ return res.sendStatus(404);
+ }
+ const body = `${req.user.mii.name} started a new chat!`;
+ const newMessage = {
+ screen_name: req.user.mii.name,
+ body: body,
+ created_at: new Date(),
+ id: await generatePostUID(21),
+ mii: req.user.mii.data,
+ mii_face_url: `https://mii.olv.pretendo.cc/mii/${req.pid}/normal_face.png`,
+ pid: req.pid,
+ verified: (req.user.accessLevel >= 2),
+ parent: null,
+ community_id: conversation.id,
+ message_to_pid: user2.pid
+ };
+ const newPost = new POST(newMessage);
+ newPost.save();
+ await conversation.newMessage(`${req.user.mii.name} started a new chat!`, user2.pid);
+ res.redirect(`/friend_messages/${conversation.id}`);
});
router.get('/:message_id', async function (req, res) {
- let conversation = await database.getConversationByID(req.params.message_id.toString());
- if(!conversation) {
- return res.sendStatus(404);
- }
- let user2 = conversation.users[0].pid === req.pid ? conversation.users[1] : conversation.users[0];
- if(req.pid !== conversation.users[0].pid && req.pid !== conversation.users[1].pid)
- res.redirect('/')
- let messages = await database.getConversationMessages(conversation.id, 200, 0);
- let userMap = await util.data.getUserHash();
- res.render(req.directory + '/message_thread.ejs', {
- moment: moment,
- user2: user2,
- conversation: conversation,
- messages: messages,
- userMap: userMap,
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- moderator: req.moderator
- });
- await conversation.markAsRead(req.pid);
+ const conversation = await database.getConversationByID(req.params.message_id.toString());
+ if (!conversation) {
+ return res.sendStatus(404);
+ }
+ const user2 = conversation.users[0].pid === req.pid ? conversation.users[1] : conversation.users[0];
+ if (req.pid !== conversation.users[0].pid && req.pid !== conversation.users[1].pid) {
+ res.redirect('/');
+ }
+ const messages = await database.getConversationMessages(conversation.id, 200, 0);
+ const userMap = await util.data.getUserHash();
+ res.render(req.directory + '/message_thread.ejs', {
+ moment: moment,
+ user2: user2,
+ conversation: conversation,
+ messages: messages,
+ userMap: userMap,
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ moderator: req.moderator
+ });
+ await conversation.markAsRead(req.pid);
});
async function generatePostUID(length) {
- let id = Buffer.from(String.fromCharCode(...crypto.getRandomValues(new Uint8Array(length * 2))), 'binary').toString('base64').replace(/[+/]/g, "").substring(0, length);
- const inuse = await POST.findOne({ id });
- id = (inuse ? await generatePostUID() : id);
- return id;
+ let id = Buffer.from(String.fromCharCode(...crypto.getRandomValues(new Uint8Array(length * 2))), 'binary').toString('base64').replace(/[+/]/g, '').substring(0, length);
+ const inuse = await POST.findOne({ id });
+ id = (inuse ? await generatePostUID() : id);
+ return id;
}
diff --git a/src/services/juxt-web/routes/console/notifications.js b/src/services/juxt-web/routes/console/notifications.js
index 2bd4ead..d7e3eba 100644
--- a/src/services/juxt-web/routes/console/notifications.js
+++ b/src/services/juxt-web/routes/console/notifications.js
@@ -6,62 +6,64 @@ const moment = require('moment');
const router = express.Router();
router.get('/my_news', async function (req, res) {
- let notifications = await database.getNotifications(req.pid, 25, 0);
- let userMap = util.data.getUserHash();
- let bundle = {
- notifications,
- userMap
- }
+ const notifications = await database.getNotifications(req.pid, 25, 0);
+ const userMap = util.data.getUserHash();
+ const bundle = {
+ notifications,
+ userMap
+ };
- if(req.query.pjax)
- return res.render(req.directory + '/partials/notifications.ejs', {
- bundle,
- lang: req.lang,
- moment
- });
+ if (req.query.pjax) {
+ return res.render(req.directory + '/partials/notifications.ejs', {
+ bundle,
+ lang: req.lang,
+ moment
+ });
+ }
- res.render(req.directory + '/notifications.ejs', {
- moment,
- selection: 0,
- bundle,
- cdnURL: config.CDN_domain,
- lang: req.lang,
- pid: req.pid,
- template: 'notifications',
- moderator: req.moderator
- });
- notifications.filter(noti => noti.read === false).forEach(function(notification) {
- notification.markRead();
- });
+ res.render(req.directory + '/notifications.ejs', {
+ moment,
+ selection: 0,
+ bundle,
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ pid: req.pid,
+ template: 'notifications',
+ moderator: req.moderator
+ });
+ notifications.filter(noti => noti.read === false).forEach(function(notification) {
+ notification.markRead();
+ });
});
router.get('/friend_requests', async function (req, res) {
- let requests = (await util.data.getFriendRequests(req.pid)).reverse();
- const now = new Date();
- requests = requests.filter(request => new Date(request.expires * 1000) > new Date(now.getTime() - 29 * 24 * 60 * 60 * 1000))
- let userMap = util.data.getUserHash();
- let bundle = {
- requests: requests ? requests : [],
- userMap
- }
+ let requests = (await util.data.getFriendRequests(req.pid)).reverse();
+ const now = new Date();
+ requests = requests.filter(request => new Date(request.expires * 1000) > new Date(now.getTime() - 29 * 24 * 60 * 60 * 1000));
+ const userMap = util.data.getUserHash();
+ const bundle = {
+ requests: requests ? requests : [],
+ userMap
+ };
- if(req.query.pjax)
- return res.render(req.directory + '/partials/requests.ejs', {
- bundle,
- lang: req.lang,
- moment
- });
+ if (req.query.pjax) {
+ return res.render(req.directory + '/partials/requests.ejs', {
+ bundle,
+ lang: req.lang,
+ moment
+ });
+ }
- res.render(req.directory + '/notifications.ejs', {
- moment,
- selection: 1,
- bundle,
- cdnURL: config.CDN_domain,
- lang: req.lang,
- pid: req.pid,
- template: 'requests',
- moderator: req.moderator
- });
+ res.render(req.directory + '/notifications.ejs', {
+ moment,
+ selection: 1,
+ bundle,
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ pid: req.pid,
+ template: 'requests',
+ moderator: req.moderator
+ });
});
module.exports = router;
diff --git a/src/services/juxt-web/routes/console/posts.js b/src/services/juxt-web/routes/console/posts.js
index f1f644a..09814cd 100644
--- a/src/services/juxt-web/routes/console/posts.js
+++ b/src/services/juxt-web/routes/console/posts.js
@@ -5,281 +5,302 @@ const config = require('../../../../../config.json');
const {POST} = require('../../../../models/post');
const multer = require('multer');
const moment = require('moment');
-const rateLimit = require('express-rate-limit')
-const {REPORT} = require("../../../../models/report");
+const rateLimit = require('express-rate-limit');
+const {REPORT} = require('../../../../models/report');
const upload = multer({dest: 'uploads/'});
-const crypto = require('crypto')
+const crypto = require('crypto');
const router = express.Router();
const postLimit = rateLimit({
- windowMs: 15 * 1000, // 30 seconds
- max: 10, // Limit each IP to 1 request per `window`
- standardHeaders: true,
- legacyHeaders: true,
- message: "New post limit reached. Try again in a minute",
- handler: function (req, res) {
- if (req.params.post_id)
- res.redirect('/posts/' + req.params.post_id.toString());
- else if (req.body.community_id)
- res.redirect('/titles/' + req.body.community_id);
- else {
- res.render(req.directory + '/error.ejs', {
- code: 429,
- message: "Too many new posts have been created.",
- cdnURL: config.CDN_domain,
- lang: req.lang,
- pid: req.pid
- });
- }
- },
-})
+ windowMs: 15 * 1000, // 30 seconds
+ max: 10, // Limit each IP to 1 request per `window`
+ standardHeaders: true,
+ legacyHeaders: true,
+ message: 'New post limit reached. Try again in a minute',
+ handler: function (req, res) {
+ if (req.params.post_id) {
+ res.redirect('/posts/' + req.params.post_id.toString());
+ } else if (req.body.community_id) {
+ res.redirect('/titles/' + req.body.community_id);
+ } else {
+ res.render(req.directory + '/error.ejs', {
+ code: 429,
+ message: 'Too many new posts have been created.',
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ pid: req.pid
+ });
+ }
+ },
+});
const yeahLimit = rateLimit({
- windowMs: 60 * 1000, // 1 minute
- max: 10, // Limit each IP to 60 requests per `window`
- standardHeaders: true,
- legacyHeaders: true,
-})
+ windowMs: 60 * 1000, // 1 minute
+ max: 10, // Limit each IP to 60 requests per `window`
+ standardHeaders: true,
+ legacyHeaders: true,
+});
router.post('/empathy', yeahLimit, async function (req, res) {
- let post = await database.getPostByID(req.body.postID);
- if (!post)
- return res.sendStatus(404);
- if (post.yeahs.indexOf(req.pid) === -1) {
- await POST.updateOne({
- id: post.id,
- yeahs: {
- $ne: req.pid
- }
- },
- {
- $inc: {
- empathy_count: 1
- },
- $push: {
- yeahs: req.pid
- }
- });
- res.send({status: 200, id: post.id, count: post.empathy_count + 1});
- if (req.pid !== post.pid)
- await util.data.newNotification({
- pid: post.pid,
- type: "yeah",
- objectID: post.id,
- userPID: req.pid,
- link: `/posts/${post.id}`
- });
- } else if (post.yeahs.indexOf(req.pid) !== -1) {
- await POST.updateOne({
- id: post.id,
- yeahs: {
- $eq: req.pid
- }
- },
- {
- $inc: {
- empathy_count: -1
- },
- $pull: {
- yeahs: req.pid
- }
- });
- res.send({status: 200, id: post.id, count: post.empathy_count - 1});
- } else
- res.send({status: 423, id: post.id, count: post.empathy_count});
+ const post = await database.getPostByID(req.body.postID);
+ if (!post) {
+ return res.sendStatus(404);
+ }
+ if (post.yeahs.indexOf(req.pid) === -1) {
+ await POST.updateOne({
+ id: post.id,
+ yeahs: {
+ $ne: req.pid
+ }
+ },
+ {
+ $inc: {
+ empathy_count: 1
+ },
+ $push: {
+ yeahs: req.pid
+ }
+ });
+ res.send({status: 200, id: post.id, count: post.empathy_count + 1});
+ if (req.pid !== post.pid) {
+ await util.data.newNotification({
+ pid: post.pid,
+ type: 'yeah',
+ objectID: post.id,
+ userPID: req.pid,
+ link: `/posts/${post.id}`
+ });
+ }
+ } else if (post.yeahs.indexOf(req.pid) !== -1) {
+ await POST.updateOne({
+ id: post.id,
+ yeahs: {
+ $eq: req.pid
+ }
+ },
+ {
+ $inc: {
+ empathy_count: -1
+ },
+ $pull: {
+ yeahs: req.pid
+ }
+ });
+ res.send({status: 200, id: post.id, count: post.empathy_count - 1});
+ } else {
+ res.send({status: 423, id: post.id, count: post.empathy_count});
+ }
});
router.post('/new', postLimit, upload.none(), async function (req, res) {
- await newPost(req, res)
+ await newPost(req, res);
});
router.get('/:post_id', async function (req, res) {
- let userSettings = await database.getUserSettings(req.pid);
- let userContent = await database.getUserContent(req.pid);
- let post = await database.getPostByID(req.params.post_id.toString());
- if (post === null) return res.redirect('/404');
- if (post.parent) {
- post = await database.getPostByID(post.parent);
- if (post === null)
- return res.sendStatus(404);
- return res.redirect(`/posts/${post.id}`);
- }
- let community = await database.getCommunityByID(post.community_id);
- let communityMap = await util.data.getCommunityHash();
- let replies = await database.getPostReplies(req.params.post_id.toString(), 25)
- res.render(req.directory + '/post.ejs', {
- moment: moment,
- userSettings: userSettings,
- userContent: userContent,
- post: post,
- replies: replies,
- community: community,
- communityMap: communityMap,
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- moderator: req.moderator
- });
+ const userSettings = await database.getUserSettings(req.pid);
+ const userContent = await database.getUserContent(req.pid);
+ let post = await database.getPostByID(req.params.post_id.toString());
+ if (post === null) {
+ return res.redirect('/404');
+ }
+ if (post.parent) {
+ post = await database.getPostByID(post.parent);
+ if (post === null) {
+ return res.sendStatus(404);
+ }
+ return res.redirect(`/posts/${post.id}`);
+ }
+ const community = await database.getCommunityByID(post.community_id);
+ const communityMap = await util.data.getCommunityHash();
+ const replies = await database.getPostReplies(req.params.post_id.toString(), 25);
+ res.render(req.directory + '/post.ejs', {
+ moment: moment,
+ userSettings: userSettings,
+ userContent: userContent,
+ post: post,
+ replies: replies,
+ community: community,
+ communityMap: communityMap,
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ moderator: req.moderator
+ });
});
router.delete('/:post_id', async function (req, res) {
- let post = await database.getPostByID(req.params.post_id);
- if(!post) return res.sendStatus(404);
- if(req.pid !== post.pid && !req.moderator) return res.sendStatus(401);
- if(req.moderator && req.pid !== post.pid)
- await post.removePost(req.query.reason ? req.query.reason : 'Removed by moderator', req.pid);
- else
- await post.removePost('User requested removal', req.pid);
+ const post = await database.getPostByID(req.params.post_id);
+ if (!post) {
+ return res.sendStatus(404);
+ }
+ if (req.pid !== post.pid && !req.moderator) {
+ return res.sendStatus(401);
+ }
+ if (req.moderator && req.pid !== post.pid) {
+ await post.removePost(req.query.reason ? req.query.reason : 'Removed by moderator', req.pid);
+ } else {
+ await post.removePost('User requested removal', req.pid);
+ }
- res.statusCode = 200;
- if(post.parent)
- res.send(`/posts/${post.parent}`);
- else
- res.send('/users/me');
+ res.statusCode = 200;
+ if (post.parent) {
+ res.send(`/posts/${post.parent}`);
+ } else {
+ res.send('/users/me');
+ }
});
router.post('/:post_id/new', postLimit, upload.none(), async function (req, res) {
- await newPost(req, res);
+ await newPost(req, res);
});
router.post('/:post_id/report', upload.none(), async function (req, res) {
- const { reason, message, post_id } = req.body;
- const post = await database.getPostByID(post_id);
- if(!reason || !post_id || !post)
- return res.redirect('/404');
+ const { reason, message, post_id } = req.body;
+ const post = await database.getPostByID(post_id);
+ if (!reason || !post_id || !post) {
+ return res.redirect('/404');
+ }
- const reportDoc = {
- pid: post.pid,
- reported_by: req.pid,
- post_id,
- reason,
- message,
- created_at: new Date()
- }
+ const reportDoc = {
+ pid: post.pid,
+ reported_by: req.pid,
+ post_id,
+ reason,
+ message,
+ created_at: new Date()
+ };
- const reportObj = new REPORT(reportDoc);
- await reportObj.save();
+ const reportObj = new REPORT(reportDoc);
+ await reportObj.save();
- return res.redirect(`/posts/${post.id}`);
+ return res.redirect(`/posts/${post.id}`);
});
async function newPost(req, res) {
- let userSettings = await database.getUserSettings(req.pid), parentPost = null, postID = await generatePostUID(21);
- let community = await database.getCommunityByID(req.body.community_id);
- if (!community || !userSettings || !req.user) {
- res.status(403);
- console.log('missing data')
- return res.redirect(`/titles/show`);
- }
- if (req.params.post_id && (req.body.body === '' && req.body.painting === '' && req.body.screenshot === '')) {
- res.status(422);
- return res.redirect('/posts/' + req.params.post_id.toString());
- }
- if (req.params.post_id) {
- parentPost = await database.getPostByID(req.params.post_id.toString());
- if (!parentPost)
- return res.sendStatus(403);
- }
- if (!(community.admins && community.admins.indexOf(req.pid) !== -1 && userSettings.account_status === 0)
+ const userSettings = await database.getUserSettings(req.pid); let parentPost = null; const postID = await generatePostUID(21);
+ const community = await database.getCommunityByID(req.body.community_id);
+ if (!community || !userSettings || !req.user) {
+ res.status(403);
+ console.log('missing data');
+ return res.redirect('/titles/show');
+ }
+ if (req.params.post_id && (req.body.body === '' && req.body.painting === '' && req.body.screenshot === '')) {
+ res.status(422);
+ return res.redirect('/posts/' + req.params.post_id.toString());
+ }
+ if (req.params.post_id) {
+ parentPost = await database.getPostByID(req.params.post_id.toString());
+ if (!parentPost) {
+ return res.sendStatus(403);
+ }
+ }
+ if (!(community.admins && community.admins.indexOf(req.pid) !== -1 && userSettings.account_status === 0)
&& (community.type >= 2) && !(parentPost && community.allows_comments && community.open)) {
- res.status(403);
- return res.redirect(`/titles/${community.olive_community_id}/new`);
- }
+ res.status(403);
+ return res.redirect(`/titles/${community.olive_community_id}/new`);
+ }
- let painting = "", paintingURI = "", screenshot = null;
- if (req.body._post_type === 'painting' && req.body.painting) {
- if(req.body.bmp === 'true')
- painting = await util.data.processPainting(req.body.painting.replace(/\0/g, "").trim(), false);
- else
- painting = req.body.painting;
- paintingURI = await util.data.processPainting(painting, true);
- await util.data.uploadCDNAsset('pn-cdn', `paintings/${req.pid}/${postID}.png`, paintingURI, 'public-read');
- }
- if (req.body.screenshot) {
- screenshot = req.body.screenshot.replace(/\0/g, "").trim();
- await util.data.uploadCDNAsset('pn-cdn', `screenshots/${req.pid}/${postID}.jpg`, Buffer.from(screenshot, 'base64'), 'public-read');
- }
+ let painting = ''; let paintingURI = ''; let screenshot = null;
+ if (req.body._post_type === 'painting' && req.body.painting) {
+ if (req.body.bmp === 'true') {
+ painting = await util.data.processPainting(req.body.painting.replace(/\0/g, '').trim(), false);
+ } else {
+ painting = req.body.painting;
+ }
+ paintingURI = await util.data.processPainting(painting, true);
+ await util.data.uploadCDNAsset('pn-cdn', `paintings/${req.pid}/${postID}.png`, paintingURI, 'public-read');
+ }
+ if (req.body.screenshot) {
+ screenshot = req.body.screenshot.replace(/\0/g, '').trim();
+ await util.data.uploadCDNAsset('pn-cdn', `screenshots/${req.pid}/${postID}.jpg`, Buffer.from(screenshot, 'base64'), 'public-read');
+ }
- let miiFace;
- switch (parseInt(req.body.feeling_id)) {
- case 1:
- miiFace = 'smile_open_mouth.png';
- break;
- case 2:
- miiFace = 'wink_left.png';
- break;
- case 3:
- miiFace = 'surprise_open_mouth.png';
- break;
- case 4:
- miiFace = 'frustrated.png';
- break;
- case 5:
- miiFace = 'sorrow.png';
- break;
- default:
- miiFace = 'normal_face.png';
- break;
- }
- let body = req.body.body;
- if (body)
- body = req.body.body.replace(/[^A-Za-z\d\s-_!@#$%^&*(){}‛¨ƒºª«»“”„¿¡←→↑↓√§¶†‡¦–—⇒⇔¤¢€£¥™©®+×÷=±∞ˇ˘˙¸˛˜′″µ°¹²³♭♪•…¬¯‰¼½¾♡♥●◆■▲▼☆★♀♂,./?;:'"\\<>]/g, "");
- if (body.length > 280)
- body = body.substring(0, 280);
- const document = {
- title_id: community.title_id[0],
- community_id: community.olive_community_id,
- screen_name: userSettings.screen_name,
- body: body,
- painting: painting,
- screenshot: screenshot ? `/screenshots/${req.pid}/${postID}.jpg` : "",
- country_id: req.paramPackData ? req.paramPackData.country_id : 49,
- created_at: new Date(),
- feeling_id: req.body.feeling_id,
- id: postID,
- is_autopost: 0,
- is_spoiler: (req.body.spoiler) ? 1 : 0,
- is_app_jumpable: req.body.is_app_jumpable,
- language_id: req.body.language_id,
- mii: req.user.mii.data,
- mii_face_url: `https://mii.olv.pretendo.cc/mii/${req.user.pid}/${miiFace}`,
- pid: req.pid,
- platform_id: req.paramPackData ? req.paramPackData.platform_id : 0,
- region_id: req.paramPackData ? req.paramPackData.region_id : 2,
- verified: req.moderator,
- parent: parentPost ? parentPost.id : null,
- moderator: req.moderator
- };
- let duplicatePost = await database.getDuplicatePosts(req.pid, document);
- if (duplicatePost && req.params.post_id)
- return res.redirect('/posts/' + req.params.post_id.toString());
- if (document.body === '' && document.painting === '' && document.screenshot === '')
- return res.redirect('/titles/' + community.olive_community_id + '/new');
- const newPost = new POST(document);
- newPost.save();
- if (parentPost) {
- parentPost.reply_count = parentPost.reply_count + 1;
- parentPost.save();
- }
- if (parentPost && (parentPost.pid !== req.user.pid))
- await util.data.newNotification({
- pid: parentPost.pid,
- type: "reply",
- user: req.pid,
- link: `/posts/${parentPost.id}`
- });
- if (parentPost)
- res.redirect('/posts/' + req.params.post_id.toString());
- else
- res.redirect('/titles/' + community.olive_community_id + '/new');
+ let miiFace;
+ switch (parseInt(req.body.feeling_id)) {
+ case 1:
+ miiFace = 'smile_open_mouth.png';
+ break;
+ case 2:
+ miiFace = 'wink_left.png';
+ break;
+ case 3:
+ miiFace = 'surprise_open_mouth.png';
+ break;
+ case 4:
+ miiFace = 'frustrated.png';
+ break;
+ case 5:
+ miiFace = 'sorrow.png';
+ break;
+ default:
+ miiFace = 'normal_face.png';
+ break;
+ }
+ let body = req.body.body;
+ if (body) {
+ body = req.body.body.replace(/[^A-Za-z\d\s-_!@#$%^&*(){}‛¨ƒºª«»“”„¿¡←→↑↓√§¶†‡¦–—⇒⇔¤¢€£¥™©®+×÷=±∞ˇ˘˙¸˛˜′″µ°¹²³♭♪•…¬¯‰¼½¾♡♥●◆■▲▼☆★♀♂,./?;:'"\\<>]/g, '');
+ }
+ if (body.length > 280) {
+ body = body.substring(0, 280);
+ }
+ const document = {
+ title_id: community.title_id[0],
+ community_id: community.olive_community_id,
+ screen_name: userSettings.screen_name,
+ body: body,
+ painting: painting,
+ screenshot: screenshot ? `/screenshots/${req.pid}/${postID}.jpg` : '',
+ country_id: req.paramPackData ? req.paramPackData.country_id : 49,
+ created_at: new Date(),
+ feeling_id: req.body.feeling_id,
+ id: postID,
+ is_autopost: 0,
+ is_spoiler: (req.body.spoiler) ? 1 : 0,
+ is_app_jumpable: req.body.is_app_jumpable,
+ language_id: req.body.language_id,
+ mii: req.user.mii.data,
+ mii_face_url: `https://mii.olv.pretendo.cc/mii/${req.user.pid}/${miiFace}`,
+ pid: req.pid,
+ platform_id: req.paramPackData ? req.paramPackData.platform_id : 0,
+ region_id: req.paramPackData ? req.paramPackData.region_id : 2,
+ verified: req.moderator,
+ parent: parentPost ? parentPost.id : null,
+ moderator: req.moderator
+ };
+ const duplicatePost = await database.getDuplicatePosts(req.pid, document);
+ if (duplicatePost && req.params.post_id) {
+ return res.redirect('/posts/' + req.params.post_id.toString());
+ }
+ if (document.body === '' && document.painting === '' && document.screenshot === '') {
+ return res.redirect('/titles/' + community.olive_community_id + '/new');
+ }
+ const newPost = new POST(document);
+ newPost.save();
+ if (parentPost) {
+ parentPost.reply_count = parentPost.reply_count + 1;
+ parentPost.save();
+ }
+ if (parentPost && (parentPost.pid !== req.user.pid)) {
+ await util.data.newNotification({
+ pid: parentPost.pid,
+ type: 'reply',
+ user: req.pid,
+ link: `/posts/${parentPost.id}`
+ });
+ }
+ if (parentPost) {
+ res.redirect('/posts/' + req.params.post_id.toString());
+ } else {
+ res.redirect('/titles/' + community.olive_community_id + '/new');
+ }
}
async function generatePostUID(length) {
- let id = Buffer.from(String.fromCharCode(...crypto.getRandomValues(new Uint8Array(length * 2))), 'binary').toString('base64').replace(/[+/]/g, "").substring(0, length);
- const inuse = await POST.findOne({id});
- id = (inuse ? await generatePostUID() : id);
- return id;
+ let id = Buffer.from(String.fromCharCode(...crypto.getRandomValues(new Uint8Array(length * 2))), 'binary').toString('base64').replace(/[+/]/g, '').substring(0, length);
+ const inuse = await POST.findOne({id});
+ id = (inuse ? await generatePostUID() : id);
+ return id;
}
diff --git a/src/services/juxt-web/routes/console/show.js b/src/services/juxt-web/routes/console/show.js
index 0e78ab8..0bb076c 100644
--- a/src/services/juxt-web/routes/console/show.js
+++ b/src/services/juxt-web/routes/console/show.js
@@ -5,63 +5,65 @@ const config = require('../../../../../config.json');
const router = express.Router();
router.get('/', async function (req, res) {
- if(req.pid === 1000000000) {
- return res.render(req.directory + '/guest_notice.ejs', {
- cdnURL: config.CDN_domain,
- lang: req.lang,
- moderator: req.moderator
- });
- }
+ if (req.pid === 1000000000) {
+ return res.render(req.directory + '/guest_notice.ejs', {
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ moderator: req.moderator
+ });
+ }
- let user = await database.getUserSettings(req.pid);
- let content = await database.getUserContent(req.pid)
- if(!user || !content) {
- res.render(req.directory + '/first_run.ejs', {
- cdnURL: config.CDN_domain,
- lang: req.lang,
- pid: req.pid,
- moderator: req.moderator
- });
- }
+ const user = await database.getUserSettings(req.pid);
+ const content = await database.getUserContent(req.pid);
+ if (!user || !content) {
+ return res.render(req.directory + '/first_run.ejs', {
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ pid: req.pid,
+ moderator: req.moderator
+ });
+ }
- if(req.query.topic_tag) {
- res.redirect(`/topics?topic_tag=${req.query.topic_tag}`)
- }
- else if(req.query.pid) {
- res.redirect(`/users/${req.query.pid}`)
- }
- else
- res.redirect('/titles')
+ if (req.query.topic_tag) {
+ res.redirect(`/topics?topic_tag=${req.query.topic_tag}`);
+ } else if (req.query.pid) {
+ res.redirect(`/users/${req.query.pid}`);
+ } else {
+ res.redirect('/titles');
+ }
- let usrMii = await database.getUserSettings(req.pid);
- if(req.user.mii.name !== usrMii.screen_name) {
- util.data.setName(req.pid, req.user.mii.name);
- usrMii.screen_name = req.user.mii.name;
- await usrMii.save();
- }
+ const usrMii = await database.getUserSettings(req.pid);
+ if (req.user.mii.name !== usrMii.screen_name) {
+ util.data.setName(req.pid, req.user.mii.name);
+ usrMii.screen_name = req.user.mii.name;
+ await usrMii.save();
+ }
});
router.get('/first', async function (req, res) {
- res.render(req.directory + '/first_run.ejs', {
- cdnURL: config.CDN_domain,
- lang: req.lang,
- moderator: req.moderator
- });
+ res.render(req.directory + '/first_run.ejs', {
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ moderator: req.moderator
+ });
});
router.post('/newUser', async function (req, res) {
- if(req.pid === null)
- return res.sendStatus(401);
+ if (req.pid === null) {
+ return res.sendStatus(401);
+ }
- let user = await database.getUserSettings(req.pid);
- if(user)
- return res.sendStatus(504);
+ const user = await database.getUserSettings(req.pid);
+ if (user) {
+ return res.sendStatus(504);
+ }
- await util.data.create_user(req.pid, req.body.experience, req.body.notifications);
- if(await database.getUserSettings(req.pid) !== null)
- res.sendStatus(200);
- else
- res.sendStatus(504);
+ await util.data.create_user(req.pid, req.body.experience, req.body.notifications);
+ if (await database.getUserSettings(req.pid) !== null) {
+ res.sendStatus(200);
+ } else {
+ res.sendStatus(504);
+ }
});
diff --git a/src/services/juxt-web/routes/console/topics.js b/src/services/juxt-web/routes/console/topics.js
index e4f1d48..ed0ee4e 100644
--- a/src/services/juxt-web/routes/console/topics.js
+++ b/src/services/juxt-web/routes/console/topics.js
@@ -7,83 +7,87 @@ const { POST } = require('../../../../models/post');
const router = express.Router();
router.get('/', async function (req, res) {
- let userContent = await database.getUserContent(req.pid);
- let communityMap = await util.data.getCommunityHash();
- let tag = req.query.topic_tag;
- console.log(tag)
- if(!userContent || !tag)
- return res.redirect('/404');
- let posts = await POST.find({ topic_tag: req.query.topic_tag }).sort({ created_at: -1}).limit(parseInt(req.query.limit));
+ const userContent = await database.getUserContent(req.pid);
+ const communityMap = await util.data.getCommunityHash();
+ const tag = req.query.topic_tag;
+ console.log(tag);
+ if (!userContent || !tag) {
+ return res.redirect('/404');
+ }
+ const posts = await POST.find({ topic_tag: req.query.topic_tag }).sort({ created_at: -1}).limit(parseInt(req.query.limit));
- let bundle = {
- posts,
- open: true,
- communityMap,
- userContent,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- link: `/topics/more?tag=${tag}&offset=${posts.length}&pjax=true`
- }
+ const bundle = {
+ posts,
+ open: true,
+ communityMap,
+ userContent,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ link: `/topics/more?tag=${tag}&offset=${posts.length}&pjax=true`
+ };
- if(req.query.pjax)
- return res.render(req.directory + '/partials/posts_list.ejs', {
- bundle,
- moment,
- lang: req.lang
- });
+ if (req.query.pjax) {
+ return res.render(req.directory + '/partials/posts_list.ejs', {
+ bundle,
+ moment,
+ lang: req.lang
+ });
+ }
- res.render(req.directory + '/feed.ejs', {
- moment: moment,
- title: tag,
- userContent: userContent,
- posts: posts,
- communityMap: communityMap,
- account_server: config.account_server_domain.slice(8),
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- bundle,
- template: 'posts_list',
- moderator: req.moderator
- });
+ res.render(req.directory + '/feed.ejs', {
+ moment: moment,
+ title: tag,
+ userContent: userContent,
+ posts: posts,
+ communityMap: communityMap,
+ account_server: config.account_server_domain.slice(8),
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ bundle,
+ template: 'posts_list',
+ moderator: req.moderator
+ });
});
router.get('/more', async function (req, res) {
- let offset = req.query.offset ? parseInt(req.query.offset) : 0;
- let userContent = await database.getUserContent(req.pid);
- let communityMap = await util.data.getCommunityHash();
- let tag = req.query.topic_tag;
- if(!tag) return res.sendStatus(204);
- let posts = await POST.find({ topic_tag: req.query.topic_tag }).sort({ created_at: -1}).limit(parseInt(req.query.limit));
+ const offset = req.query.offset ? parseInt(req.query.offset) : 0;
+ const userContent = await database.getUserContent(req.pid);
+ const communityMap = await util.data.getCommunityHash();
+ const tag = req.query.topic_tag;
+ if (!tag) {
+ return res.sendStatus(204);
+ }
+ const posts = await POST.find({ topic_tag: req.query.topic_tag }).sort({ created_at: -1}).limit(parseInt(req.query.limit));
- let bundle = {
- posts,
- numPosts: posts.length,
- open: true,
- communityMap,
- userContent,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- link: `/topics/more?tag=${tag}&offset=${posts.length}&pjax=true`
- }
+ const bundle = {
+ posts,
+ numPosts: posts.length,
+ open: true,
+ communityMap,
+ userContent,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ link: `/topics/more?tag=${tag}&offset=${posts.length}&pjax=true`
+ };
- if(posts.length > 0) {
- res.render(req.directory + '/partials/posts_list.ejs', {
- communityMap: communityMap,
- moment: moment,
- database: database,
- bundle,
- account_server: config.account_server_domain.slice(8),
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- moderator: req.moderator
- });
- }
- else
- res.sendStatus(204);
+ if (posts.length > 0) {
+ res.render(req.directory + '/partials/posts_list.ejs', {
+ communityMap: communityMap,
+ moment: moment,
+ database: database,
+ bundle,
+ account_server: config.account_server_domain.slice(8),
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ moderator: req.moderator
+ });
+ } else {
+ res.sendStatus(204);
+ }
});
module.exports = router;
diff --git a/src/services/juxt-web/routes/console/userpage.js b/src/services/juxt-web/routes/console/userpage.js
index d1ea861..e151a08 100644
--- a/src/services/juxt-web/routes/console/userpage.js
+++ b/src/services/juxt-web/routes/console/userpage.js
@@ -6,173 +6,193 @@ const multer = require('multer');
const moment = require('moment');
const upload = multer({ dest: 'uploads/' });
const { POST } = require('../../../../models/post');
-const {SETTINGS} = require("../../../../models/settings");
+const {SETTINGS} = require('../../../../models/settings');
const router = express.Router();
router.get('/menu', async function (req, res) {
- let user = await database.getUserSettings(req.pid);
- res.render('ctr/user_menu.ejs', {
- user: user,
- });
+ const user = await database.getUserSettings(req.pid);
+ res.render('ctr/user_menu.ejs', {
+ user: user,
+ });
});
-router.get('/me', async function (req, res) { await userPage(req, res, req.pid) });
+router.get('/me', async function (req, res) {
+ await userPage(req, res, req.pid);
+});
router.get('/me/settings', async function (req, res) {
- let userSettings = await database.getUserSettings(req.pid);
- let communityMap = await util.data.getCommunityHash();
- res.render(req.directory + '/settings.ejs', {
- communityMap: communityMap,
- moment: moment,
- userSettings: userSettings,
- account_server: config.account_server_domain.slice(8),
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- moderator: req.moderator
- });
+ const userSettings = await database.getUserSettings(req.pid);
+ const communityMap = await util.data.getCommunityHash();
+ res.render(req.directory + '/settings.ejs', {
+ communityMap: communityMap,
+ moment: moment,
+ userSettings: userSettings,
+ account_server: config.account_server_domain.slice(8),
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ moderator: req.moderator
+ });
});
-router.get('/me/:type', async function (req, res) { await userRelations(req, res, req.pid) });
+router.get('/me/:type', async function (req, res) {
+ await userRelations(req, res, req.pid);
+});
router.post('/me/settings', upload.none(), async function (req, res) {
- let userSettings = await database.getUserSettings(req.pid);
+ const userSettings = await database.getUserSettings(req.pid);
- userSettings.country_visibility = !!req.body.country;
- userSettings.birthday_visibility = !!req.body.birthday;
- userSettings.game_skill_visibility = !!req.body.experience;
- userSettings.profile_comment_visibility = !!req.body.comment;
+ userSettings.country_visibility = !!req.body.country;
+ userSettings.birthday_visibility = !!req.body.birthday;
+ userSettings.game_skill_visibility = !!req.body.experience;
+ userSettings.profile_comment_visibility = !!req.body.comment;
- if (req.body.comment)
- userSettings.updateComment(req.body.comment);
- else
- userSettings.updateComment('');
+ if (req.body.comment) {
+ userSettings.updateComment(req.body.comment);
+ } else {
+ userSettings.updateComment('');
+ }
- res.redirect('/users/me');
+ res.redirect('/users/me');
});
router.get('/show', async function (req, res) {
- res.redirect(`/users/${req.query.pid}`);
+ res.redirect(`/users/${req.query.pid}`);
});
-router.get('/:pid/more', async function (req, res) { await morePosts(req, res, req.params.pid) });
-
-router.get('/:pid/yeahs/more', async function (req, res) { await moreYeahPosts(req, res, req.params.pid) });
-
-router.get('/:pid/:type', async function (req, res) { await userRelations(req, res, req.params.pid) });
-
-// TODO: Remove the need for a parameter to toggle the following state
-router.post('/follow', upload.none(), async function (req, res) {
- let userToFollowContent = await database.getUserContent(req.body.id);
- let userContent = await database.getUserContent(req.pid);
- if(userContent !== null && userContent.followed_users.indexOf(userToFollowContent.pid) === -1)
- {
- userToFollowContent.addToFollowers(userContent.pid);
- userContent.addToUsers(userToFollowContent.pid);
- res.send({ status: 200, id: userToFollowContent.pid, count: userToFollowContent.following_users.length - 1 });
- let picked = await database.getNotification(userToFollowContent.pid, 2, userContent.pid);
- //pid, type, reference_id, origin_pid, title, content
- if(picked === null)
- await util.data.newNotification({ pid: userToFollowContent.pid, type: "follow", objectID: req.pid, link: `/users/${req.pid}` });
- }
- else if(userContent !== null && userContent.followed_users.indexOf(userToFollowContent.pid) !== -1)
- {
- userToFollowContent.removeFromFollowers(userContent.pid);
- userContent.removeFromUsers(userToFollowContent.pid);
- res.send({ status: 200, id: userToFollowContent.pid, count: userToFollowContent.following_users.length - 1 });
- }
- else
- res.send({ status: 423, id: userToFollowContent.pid, count: userToFollowContent.following_users.length - 1 });
+router.get('/:pid/more', async function (req, res) {
+ await morePosts(req, res, req.params.pid);
});
-router.get('/:pid', async function (req, res) {
- const userID = req.params.pid;
- if(userID === 'me' || Number(userID) === req.pid)
- return res.redirect('/users/me');
- await userPage(req, res, userID);
+router.get('/:pid/yeahs/more', async function (req, res) {
+ await moreYeahPosts(req, res, req.params.pid);
});
router.get('/:pid/:type', async function (req, res) {
- const userID = req.params.pid;
- if(userID === 'me' || Number(userID) === req.pid)
- return res.redirect('/users/me');
- await userRelations(req, res, userID);
+ await userRelations(req, res, req.params.pid);
+});
+
+// TODO: Remove the need for a parameter to toggle the following state
+router.post('/follow', upload.none(), async function (req, res) {
+ const userToFollowContent = await database.getUserContent(req.body.id);
+ const userContent = await database.getUserContent(req.pid);
+ if (userContent !== null && userContent.followed_users.indexOf(userToFollowContent.pid) === -1) {
+ userToFollowContent.addToFollowers(userContent.pid);
+ userContent.addToUsers(userToFollowContent.pid);
+ res.send({ status: 200, id: userToFollowContent.pid, count: userToFollowContent.following_users.length - 1 });
+ const picked = await database.getNotification(userToFollowContent.pid, 2, userContent.pid);
+ //pid, type, reference_id, origin_pid, title, content
+ if (picked === null) {
+ await util.data.newNotification({ pid: userToFollowContent.pid, type: 'follow', objectID: req.pid, link: `/users/${req.pid}` });
+ }
+ } else if (userContent !== null && userContent.followed_users.indexOf(userToFollowContent.pid) !== -1) {
+ userToFollowContent.removeFromFollowers(userContent.pid);
+ userContent.removeFromUsers(userToFollowContent.pid);
+ res.send({ status: 200, id: userToFollowContent.pid, count: userToFollowContent.following_users.length - 1 });
+ } else {
+ res.send({ status: 423, id: userToFollowContent.pid, count: userToFollowContent.following_users.length - 1 });
+ }
+});
+
+router.get('/:pid', async function (req, res) {
+ const userID = req.params.pid;
+ if (userID === 'me' || Number(userID) === req.pid) {
+ return res.redirect('/users/me');
+ }
+ await userPage(req, res, userID);
+});
+
+router.get('/:pid/:type', async function (req, res) {
+ const userID = req.params.pid;
+ if (userID === 'me' || Number(userID) === req.pid) {
+ return res.redirect('/users/me');
+ }
+ await userRelations(req, res, userID);
});
async function userPage(req, res, userID) {
- let pnid = userID === req.pid ? req.user : await util.data.getUserDataFromPid(userID).catch((e) => {
- console.log(e.details);
- });
- let userContent = await database.getUserContent(userID);
- if(isNaN(userID) || !pnid || !userContent)
- return res.redirect('/404');
- let userSettings = await database.getUserSettings(userID);
- let posts = await database.getNumberUserPostsByID(userID, config.post_limit);
- let numPosts = await database.getTotalPostsByUserID(userID);
- let communityMap = await util.data.getCommunityHash();
- let friends = await util.data.getFriends(userID);
- let parentUserContent;
- if(pnid.pid !== req.pid)
- parentUserContent = await database.getUserContent(req.pid);
+ const pnid = userID === req.pid ? req.user : await util.data.getUserDataFromPid(userID).catch((e) => {
+ console.log(e.details);
+ });
+ const userContent = await database.getUserContent(userID);
+ if (isNaN(userID) || !pnid || !userContent) {
+ return res.redirect('/404');
+ }
+ const userSettings = await database.getUserSettings(userID);
+ const posts = await database.getNumberUserPostsByID(userID, config.post_limit);
+ const numPosts = await database.getTotalPostsByUserID(userID);
+ const communityMap = await util.data.getCommunityHash();
+ let friends = [];
+ try {
+ friends = await util.data.getFriends(userID);
+ } catch (e) {}
- let bundle = {
- posts,
- open: true,
- numPosts,
- communityMap,
- userContent: parentUserContent ? parentUserContent : userContent,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- link: `/users/${userID}/more?offset=${posts.length}&pjax=true`
- }
+ let parentUserContent;
+ if (pnid.pid !== req.pid) {
+ parentUserContent = await database.getUserContent(req.pid);
+ }
- if(req.query.pjax)
- return res.render(req.directory + '/partials/posts_list.ejs', {
- bundle,
- lang: req.lang,
- moment
- });
- let link = (pnid.pid === req.pid) ? '/users/me/' : `/users/${userID}/`;
- res.render(req.directory + '/user_page.ejs', {
- template: 'posts_list',
- selection: 0,
- moment,
- pnid,
- numPosts,
- userContent,
- userSettings,
- bundle,
- account_server: config.account_server_domain.slice(8),
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- link,
- friends,
- parentUserContent,
- moderator: req.moderator
- });
+ const bundle = {
+ posts,
+ open: true,
+ numPosts,
+ communityMap,
+ userContent: parentUserContent ? parentUserContent : userContent,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ link: `/users/${userID}/more?offset=${posts.length}&pjax=true`
+ };
+
+ if (req.query.pjax) {
+ return res.render(req.directory + '/partials/posts_list.ejs', {
+ bundle,
+ lang: req.lang,
+ moment
+ });
+ }
+ const link = (pnid.pid === req.pid) ? '/users/me/' : `/users/${userID}/`;
+ res.render(req.directory + '/user_page.ejs', {
+ template: 'posts_list',
+ selection: 0,
+ moment,
+ pnid,
+ numPosts,
+ userContent,
+ userSettings,
+ bundle,
+ account_server: config.account_server_domain.slice(8),
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ link,
+ friends,
+ parentUserContent,
+ moderator: req.moderator
+ });
}
async function userRelations(req, res, userID) {
- let pnid = userID === req.pid ? req.user : await util.data.getUserDataFromPid(userID);
- let userContent = await database.getUserContent(userID);
- let link = (pnid.pid === req.pid) ? '/users/me/' : `/users/${userID}/`;
- let userSettings = await database.getUserSettings(userID);
- let numPosts = await database.getTotalPostsByUserID(userID);
- let friends = await util.data.getFriends(userID);
- let parentUserContent;
- if(pnid.pid !== req.pid)
- parentUserContent = await database.getUserContent(req.pid);
- if(isNaN(userID) || !pnid)
- return res.redirect('/404');
+ const pnid = userID === req.pid ? req.user : await util.data.getUserDataFromPid(userID);
+ const userContent = await database.getUserContent(userID);
+ const link = (pnid.pid === req.pid) ? '/users/me/' : `/users/${userID}/`;
+ const userSettings = await database.getUserSettings(userID);
+ const numPosts = await database.getTotalPostsByUserID(userID);
+ const friends = await util.data.getFriends(userID);
+ let parentUserContent;
+ if (pnid.pid !== req.pid) {
+ parentUserContent = await database.getUserContent(req.pid);
+ }
+ if (isNaN(userID) || !pnid) {
+ return res.redirect('/404');
+ }
- let followers, communities, communityMap, selection;
+ let followers; let communities; let communityMap; let selection;
- if(req.params.type === 'yeahs') {
- let posts = await POST.find({ yeahs: req.pid, removed: false }).sort({created_at: -1});
- /*let posts = await POST.aggregate([
+ if (req.params.type === 'yeahs') {
+ const posts = await POST.find({ yeahs: req.pid, removed: false }).sort({created_at: -1});
+ /*let posts = await POST.aggregate([
{ $match: { id: { $in: likesArray } } },
{$addFields: {
"__order": { $indexOfArray: [ likesArray, "$id" ] }
@@ -181,180 +201,184 @@ async function userRelations(req, res, userID) {
{ $project: { index: 0, _id: 0 } },
{ $limit: config.post_limit }
]);*/
- let communityMap = await util.data.getCommunityHash();
- let bundle = {
- posts,
- open: true,
- numPosts: posts.length,
- communityMap,
- userContent: parentUserContent ? parentUserContent : userContent,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- link: `/users/${userID}/yeahs/more?offset=${posts.length}&pjax=true`
- }
+ const communityMap = await util.data.getCommunityHash();
+ const bundle = {
+ posts,
+ open: true,
+ numPosts: posts.length,
+ communityMap,
+ userContent: parentUserContent ? parentUserContent : userContent,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ link: `/users/${userID}/yeahs/more?offset=${posts.length}&pjax=true`
+ };
- if(req.query.pjax)
- return res.render(req.directory + '/partials/posts_list.ejs', {
- bundle,
- lang: req.lang,
- moment
- });
- else
- return res.render(req.directory + '/user_page.ejs', {
- template: 'posts_list',
- selection: 4,
- moment,
- pnid,
- numPosts,
- userContent,
- userSettings,
- bundle,
- account_server: config.account_server_domain.slice(8),
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- link,
- friends,
- parentUserContent,
- moderator: req.moderator
- });
- }
+ if (req.query.pjax) {
+ return res.render(req.directory + '/partials/posts_list.ejs', {
+ bundle,
+ lang: req.lang,
+ moment
+ });
+ } else {
+ return res.render(req.directory + '/user_page.ejs', {
+ template: 'posts_list',
+ selection: 4,
+ moment,
+ pnid,
+ numPosts,
+ userContent,
+ userSettings,
+ bundle,
+ account_server: config.account_server_domain.slice(8),
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ link,
+ friends,
+ parentUserContent,
+ moderator: req.moderator
+ });
+ }
+ }
- if(req.params.type === 'friends') {
- followers = await SETTINGS.find({ pid: friends });
- communities = [];
- selection = 2;
- }
- else if(req.params.type === 'followers') {
- followers = await database.getFollowingUsers(userContent);
- communities = [];
- selection = 3;
- }
- else {
- followers = await database.getFollowedUsers(userContent);
- communities = userContent.followed_communities;
- communityMap = await util.data.getCommunityHash();
- selection = 2;
- }
+ if (req.params.type === 'friends') {
+ followers = await SETTINGS.find({ pid: friends });
+ communities = [];
+ selection = 2;
+ } else if (req.params.type === 'followers') {
+ followers = await database.getFollowingUsers(userContent);
+ communities = [];
+ selection = 3;
+ } else {
+ followers = await database.getFollowedUsers(userContent);
+ communities = userContent.followed_communities;
+ communityMap = await util.data.getCommunityHash();
+ selection = 2;
+ }
- if(followers[0] === '0')
- followers.splice(0, 0);
- if(communities[0] === '0')
- communities.splice(0, 1);
+ if (followers[0] === '0') {
+ followers.splice(0, 0);
+ }
+ if (communities[0] === '0') {
+ communities.splice(0, 1);
+ }
- let bundle = {
- followers: followers ? followers : [],
- communities: communities,
- communityMap: communityMap
- }
+ const bundle = {
+ followers: followers ? followers : [],
+ communities: communities,
+ communityMap: communityMap
+ };
- if(req.query.pjax)
- return res.render(req.directory + '/partials/following_list.ejs', {
- bundle,
- });
- res.render(req.directory + '/user_page.ejs', {
- template: 'following_list',
- selection: selection,
- moment,
- pnid,
- numPosts,
- userContent,
- userSettings,
- bundle,
- account_server: config.account_server_domain.slice(8),
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- link,
- parentUserContent,
- moderator: req.moderator
- });
+ if (req.query.pjax) {
+ return res.render(req.directory + '/partials/following_list.ejs', {
+ bundle,
+ });
+ }
+ res.render(req.directory + '/user_page.ejs', {
+ template: 'following_list',
+ selection: selection,
+ moment,
+ pnid,
+ numPosts,
+ userContent,
+ userSettings,
+ bundle,
+ account_server: config.account_server_domain.slice(8),
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ link,
+ parentUserContent,
+ moderator: req.moderator
+ });
}
async function morePosts(req, res, userID) {
- let offset = parseInt(req.query.offset);
- let userContent = await database.getUserContent(req.pid);
- let communityMap = await util.data.getCommunityHash();
- if(!offset) offset = 0;
- let posts = await database.getUserPostsOffset(userID, config.post_limit, offset);
+ let offset = parseInt(req.query.offset);
+ const userContent = await database.getUserContent(req.pid);
+ const communityMap = await util.data.getCommunityHash();
+ if (!offset) {
+ offset = 0;
+ }
+ const posts = await database.getUserPostsOffset(userID, config.post_limit, offset);
- let bundle = {
- posts,
- numPosts: posts.length,
- open: true,
- communityMap,
- userContent,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- link: `/users/${userID}/more?offset=${offset + posts.length}&pjax=true`
- }
+ const bundle = {
+ posts,
+ numPosts: posts.length,
+ open: true,
+ communityMap,
+ userContent,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ link: `/users/${userID}/more?offset=${offset + posts.length}&pjax=true`
+ };
- if(posts.length > 0)
- {
- res.render(req.directory + '/partials/posts_list.ejs', {
- communityMap: communityMap,
- moment: moment,
- database: database,
- bundle,
- account_server: config.account_server_domain.slice(8),
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- moderator: req.moderator
- });
- }
- else
- res.sendStatus(204);
+ if (posts.length > 0) {
+ res.render(req.directory + '/partials/posts_list.ejs', {
+ communityMap: communityMap,
+ moment: moment,
+ database: database,
+ bundle,
+ account_server: config.account_server_domain.slice(8),
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ moderator: req.moderator
+ });
+ } else {
+ res.sendStatus(204);
+ }
}
async function moreYeahPosts(req, res, userID) {
- let offset = parseInt(req.query.offset);
- let parentUserContent = await database.getUserContent(userID);
- let userContent = await database.getUserContent(req.pid);
- let communityMap = await util.data.getCommunityHash();
- if(!offset) offset = 0;
- let likesArray = await userContent.likes.slice().reverse();
- let posts = await POST.aggregate([
- { $match: { id: { $in: likesArray }, removed: false } },
- {$addFields: {
- "__order": { $indexOfArray: [ likesArray, "$id" ] }
- }},
- { $sort: { "__order": 1 } },
- { $project: { index: 0, _id: 0 } },
- { $skip : offset },
- { $limit: config.post_limit }
- ]);
+ let offset = parseInt(req.query.offset);
+ const parentUserContent = await database.getUserContent(userID);
+ const userContent = await database.getUserContent(req.pid);
+ const communityMap = await util.data.getCommunityHash();
+ if (!offset) {
+ offset = 0;
+ }
+ const likesArray = await userContent.likes.slice().reverse();
+ const posts = await POST.aggregate([
+ { $match: { id: { $in: likesArray }, removed: false } },
+ {$addFields: {
+ '__order': { $indexOfArray: [ likesArray, '$id' ] }
+ }},
+ { $sort: { '__order': 1 } },
+ { $project: { index: 0, _id: 0 } },
+ { $skip : offset },
+ { $limit: config.post_limit }
+ ]);
- let bundle = {
- posts: posts.reverse(),
- numPosts: posts.length,
- open: true,
- communityMap,
- userContent,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- link: `/users/${userID}/yeahs/more?offset=${offset + posts.length}&pjax=true`
- }
+ const bundle = {
+ posts: posts.reverse(),
+ numPosts: posts.length,
+ open: true,
+ communityMap,
+ userContent,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ link: `/users/${userID}/yeahs/more?offset=${offset + posts.length}&pjax=true`
+ };
- if(posts.length > 0)
- {
- res.render(req.directory + '/partials/posts_list.ejs', {
- communityMap: communityMap,
- moment: moment,
- database: database,
- bundle,
- account_server: config.account_server_domain.slice(8),
- cdnURL: config.CDN_domain,
- lang: req.lang,
- mii_image_CDN: config.mii_image_CDN,
- pid: req.pid,
- moderator: req.moderator
- });
- }
- else
- res.sendStatus(204);
+ if (posts.length > 0) {
+ res.render(req.directory + '/partials/posts_list.ejs', {
+ communityMap: communityMap,
+ moment: moment,
+ database: database,
+ bundle,
+ account_server: config.account_server_domain.slice(8),
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ mii_image_CDN: config.mii_image_CDN,
+ pid: req.pid,
+ moderator: req.moderator
+ });
+ } else {
+ res.sendStatus(204);
+ }
}
module.exports = router;
diff --git a/src/services/juxt-web/routes/console/web.js b/src/services/juxt-web/routes/console/web.js
index 86410d0..7b4c1df 100644
--- a/src/services/juxt-web/routes/console/web.js
+++ b/src/services/juxt-web/routes/console/web.js
@@ -5,146 +5,156 @@ const { POST } = require('../../../../models/post');
const path = require('path');
router.get('/', function (req, res) {
- res.redirect('/titles/show')
+ res.redirect('/titles/show');
});
router.get('/css/:filename', function (req, res) {
- res.set("Content-Type", "text/css");
- res.sendFile('/css/' + req.params.filename, {root: path.join(__dirname, '../../../../webfiles/' + req.directory)});
+ res.set('Content-Type', 'text/css');
+ res.sendFile('/css/' + req.params.filename, {root: path.join(__dirname, '../../../../webfiles/' + req.directory)});
});
router.get('/js/:filename', function (req, res) {
- res.set("Content-Type", "application/javascript; charset=utf-8");
- res.sendFile('/js/' + req.params.filename, {root: path.join(__dirname, '../../../../webfiles/' + req.directory)});
+ res.set('Content-Type', 'application/javascript; charset=utf-8');
+ res.sendFile('/js/' + req.params.filename, {root: path.join(__dirname, '../../../../webfiles/' + req.directory)});
});
router.get('/images/:filename', function (req, res) {
- res.set("Content-Type", "image/png");
- res.sendFile('/images/' + req.params.filename, {root: path.join(__dirname, '../../../../webfiles/' + req.directory)});
+ res.set('Content-Type', 'image/png');
+ res.sendFile('/images/' + req.params.filename, {root: path.join(__dirname, '../../../../webfiles/' + req.directory)});
});
router.get('/fonts/:filename', function (req, res) {
- res.set("Content-Type", "font/woff");
- res.sendFile('/fonts/' + req.params.filename, {root: path.join(__dirname, '../../../../webfiles/' + req.directory)});
+ res.set('Content-Type', 'font/woff');
+ res.sendFile('/fonts/' + req.params.filename, {root: path.join(__dirname, '../../../../webfiles/' + req.directory)});
});
router.get('/favicon.ico', function (req, res) {
- res.set("Content-Type", "image/x-icon");
- res.sendFile('/images/favicon.ico', {root: path.join(__dirname, '../../../../webfiles/' + req.directory)});
+ res.set('Content-Type', 'image/x-icon');
+ res.sendFile('/images/favicon.ico', {root: path.join(__dirname, '../../../../webfiles/' + req.directory)});
});
router.get('/icons/:image_id.png', async function (req, res) {
- res.set("Content-Type", "image/png");
- let community = await database.getCommunityByID(req.params.image_id.toString());
- if(community !== null && community.browser_icon) {
- if(community.browser_icon.indexOf('data:image/png;base64,') !== -1)
- res.send(Buffer.from(community.browser_icon.replace('data:image/png;base64,',''), 'base64'));
- else
- res.send(Buffer.from(community.browser_icon, 'base64'));
- }
- else {
- let user = await database.getUserSettings(req.params.image_id.toString());
- if(user !== null)
- if(user.pfp_uri.indexOf('data:image/png;base64,') !== -1)
- res.send(Buffer.from(user.pfp_uri.replace('data:image/png;base64,',''), 'base64'));
- else
- res.send(Buffer.from(user.pfp_uri, 'base64'));
- else
- res.sendStatus(404);
- }
+ res.set('Content-Type', 'image/png');
+ const community = await database.getCommunityByID(req.params.image_id.toString());
+ if (community !== null && community.browser_icon) {
+ if (community.browser_icon.indexOf('data:image/png;base64,') !== -1) {
+ res.send(Buffer.from(community.browser_icon.replace('data:image/png;base64,',''), 'base64'));
+ } else {
+ res.send(Buffer.from(community.browser_icon, 'base64'));
+ }
+ } else {
+ const user = await database.getUserSettings(req.params.image_id.toString());
+ if (user !== null) {
+ if (user.pfp_uri.indexOf('data:image/png;base64,') !== -1) {
+ res.send(Buffer.from(user.pfp_uri.replace('data:image/png;base64,',''), 'base64'));
+ } else {
+ res.send(Buffer.from(user.pfp_uri, 'base64'));
+ }
+ } else {
+ res.sendStatus(404);
+ }
+ }
});
router.get('/tip/:image_id.png', async function (req, res) {
- res.set("Content-Type", "image/png");
- let community = await database.getCommunityByID(req.params.image_id.toString());
- if(community !== null) {
- if(community.browser_thumbnail.indexOf('data:image/png;base64,') !== -1)
- res.send(Buffer.from(community.browser_thumbnail.replace('data:image/png;base64,',''), 'base64'));
- else
- res.send(Buffer.from(community.browser_thumbnail, 'base64'));
- }
- else {
- let user = await database.getUserByPID(req.params.image_id.toString());
- if (user !== null)
- if (user.pfp_uri.indexOf('data:image/png;base64,') !== -1)
- res.send(Buffer.from(user.pfp_uri.replace('data:image/png;base64,', ''), 'base64'));
- else
- res.send(Buffer.from(user.pfp_uri, 'base64'));
- else
- res.sendStatus(404);
- }
+ res.set('Content-Type', 'image/png');
+ const community = await database.getCommunityByID(req.params.image_id.toString());
+ if (community !== null) {
+ if (community.browser_thumbnail.indexOf('data:image/png;base64,') !== -1) {
+ res.send(Buffer.from(community.browser_thumbnail.replace('data:image/png;base64,',''), 'base64'));
+ } else {
+ res.send(Buffer.from(community.browser_thumbnail, 'base64'));
+ }
+ } else {
+ const user = await database.getUserByPID(req.params.image_id.toString());
+ if (user !== null) {
+ if (user.pfp_uri.indexOf('data:image/png;base64,') !== -1) {
+ res.send(Buffer.from(user.pfp_uri.replace('data:image/png;base64,', ''), 'base64'));
+ } else {
+ res.send(Buffer.from(user.pfp_uri, 'base64'));
+ }
+ } else {
+ res.sendStatus(404);
+ }
+ }
});
router.get('/banner/:image_id.png', async function (req, res) {
- res.set("Content-Type", "image/png");
- let community = await database.getCommunityByID(req.params.image_id.toString());
- if(community !== null && community.WiiU_browser_header !== undefined)
- if(community.WiiU_browser_header.indexOf('data:image/png;base64,') !== -1)
- res.send(Buffer.from(community.WiiU_browser_header.replace('data:image/png;base64,',''), 'base64'));
- else
- res.send(Buffer.from(community.WiiU_browser_header, 'base64'));
- else
- res.sendStatus(404);
+ res.set('Content-Type', 'image/png');
+ const community = await database.getCommunityByID(req.params.image_id.toString());
+ if (community !== null && community.WiiU_browser_header !== undefined) {
+ if (community.WiiU_browser_header.indexOf('data:image/png;base64,') !== -1) {
+ res.send(Buffer.from(community.WiiU_browser_header.replace('data:image/png;base64,',''), 'base64'));
+ } else {
+ res.send(Buffer.from(community.WiiU_browser_header, 'base64'));
+ }
+ } else {
+ res.sendStatus(404);
+ }
});
router.get('/screenshot/:image_id.png', async function (req, res) {
- res.set("Content-Type", "image/png");
- let post = await database.getPostByID(req.params.image_id.toString());
- if(post !== null && post.screenshot !== '')
- if(post.screenshot.indexOf('data:image/png;base64,') !== -1)
- res.send(Buffer.from(post.screenshot.replace('data:image/png;base64,',''), 'base64'));
- else
- res.send(Buffer.from(post.screenshot, 'base64'));
- else
- res.sendStatus(404);
+ res.set('Content-Type', 'image/png');
+ const post = await database.getPostByID(req.params.image_id.toString());
+ if (post !== null && post.screenshot !== '') {
+ if (post.screenshot.indexOf('data:image/png;base64,') !== -1) {
+ res.send(Buffer.from(post.screenshot.replace('data:image/png;base64,',''), 'base64'));
+ } else {
+ res.send(Buffer.from(post.screenshot, 'base64'));
+ }
+ } else {
+ res.sendStatus(404);
+ }
});
router.get('/drawing/:image_id.png', async function (req, res) {
- res.set("Content-Type", "image/png");
- let post = await database.getPostByID(req.params.image_id.toString());
- if(post !== null && post.painting_uri !== '')
- if(post.painting_uri.indexOf('data:image/png;base64,') !== -1)
- res.send(Buffer.from(post.painting_uri.replace('data:image/png;base64,',''), 'base64'));
- else
- res.send(Buffer.from(post.painting_uri, 'base64'));
- else
- res.sendStatus(404);
+ res.set('Content-Type', 'image/png');
+ const post = await database.getPostByID(req.params.image_id.toString());
+ if (post !== null && post.painting_uri !== '') {
+ if (post.painting_uri.indexOf('data:image/png;base64,') !== -1) {
+ res.send(Buffer.from(post.painting_uri.replace('data:image/png;base64,',''), 'base64'));
+ } else {
+ res.send(Buffer.from(post.painting_uri, 'base64'));
+ }
+ } else {
+ res.sendStatus(404);
+ }
});
router.get('/notifications.json', async function (req, res) {
- let notifications = await database.getUnreadNotificationCount(req.pid);
- let messagesCount = await database.getUnreadConversationCount(req.pid);
- res.send(
- {
- message_count: messagesCount,
- notification_count: notifications,
- }
- )
+ const notifications = await database.getUnreadNotificationCount(req.pid);
+ const messagesCount = await database.getUnreadConversationCount(req.pid);
+ res.send(
+ {
+ message_count: messagesCount,
+ notification_count: notifications,
+ }
+ );
});
router.get('/:post_id/oembed.json', async function (req, res) {
- let post = await database.getPostByID(req.params.post_id.toString());
- let user = await database.getUserByPID(post.pid);
- let doc = {
- "author_name": user.user_id,
- "author_url": "https://portal.olv.pretendo.cc/users/show?pid=" + user.pid,
- }
- res.send(doc)
+ const post = await database.getPostByID(req.params.post_id.toString());
+ const user = await database.getUserByPID(post.pid);
+ const doc = {
+ 'author_name': user.user_id,
+ 'author_url': 'https://portal.olv.pretendo.cc/users/show?pid=' + user.pid,
+ };
+ res.send(doc);
});
router.get('/downloadUserData.json', async function (req, res) {
- res.set("Content-Type", "text/json");
- res.set('Content-Disposition', `attachment; filename="${req.pid}_user_data.json"`);
- let posts = await POST.find({ pid: req.pid })
- let userContent = await database.getUserSettings(req.pid);
- let userSettings = await database.getUserContent(req.pid);
- let doc = {
- "user_content": userContent,
- "user_settings": userSettings,
- "posts": posts,
- }
- res.send(doc)
+ res.set('Content-Type', 'text/json');
+ res.set('Content-Disposition', `attachment; filename="${req.pid}_user_data.json"`);
+ const posts = await POST.find({ pid: req.pid });
+ const userContent = await database.getUserSettings(req.pid);
+ const userSettings = await database.getUserContent(req.pid);
+ const doc = {
+ 'user_content': userContent,
+ 'user_settings': userSettings,
+ 'posts': posts,
+ };
+ res.send(doc);
});
module.exports = router;
diff --git a/src/services/juxt-web/routes/web/login.js b/src/services/juxt-web/routes/web/login.js
index 0474dbb..c5b387b 100644
--- a/src/services/juxt-web/routes/web/login.js
+++ b/src/services/juxt-web/routes/web/login.js
@@ -3,66 +3,74 @@ const router = express.Router();
const parseString = require('xml2js').parseString;
const database = require('../../../../database');
const util = require('../../../../util');
-const config = require("../../../../../config.json");
-const request = require("request");
-const logger = require("../../../../logger");
+const config = require('../../../../../config.json');
+const request = require('request');
+const logger = require('../../../../logger');
router.get('/', async function (req, res) {
- res.render(req.directory + '/login.ejs', {toast: null, cdnURL: config.CDN_domain,});
+ res.render(req.directory + '/login.ejs', {toast: null, cdnURL: config.CDN_domain,});
});
router.post('/', async (req, res) => {
- const { username, password } = req.body;
- const login = await util.data.login(username, password).catch((e) => {
- console.log(e.details);
- switch (e.details) {
- case 'INVALID_ARGUMENT: User not found':
- res.render(req.directory + '/login.ejs', {toast: 'Username was invalid.', cdnURL: config.CDN_domain,});
- break;
- case 'INVALID_ARGUMENT: Password is incorrect':
- res.render(req.directory + '/login.ejs', {toast: 'Password was incorrect.', cdnURL: config.CDN_domain,});
- break;
- default:
- res.render(req.directory + '/login.ejs', {toast: 'Invalid username or password.', cdnURL: config.CDN_domain,});
- break;
- }
- });
- if(!login) return;
+ const { username, password } = req.body;
+ const login = await util.data.login(username, password).catch((e) => {
+ console.log(e.details);
+ switch (e.details) {
+ case 'INVALID_ARGUMENT: User not found':
+ res.render(req.directory + '/login.ejs', {toast: 'Username was invalid.', cdnURL: config.CDN_domain,});
+ break;
+ case 'INVALID_ARGUMENT: Password is incorrect':
+ res.render(req.directory + '/login.ejs', {toast: 'Password was incorrect.', cdnURL: config.CDN_domain,});
+ break;
+ default:
+ res.render(req.directory + '/login.ejs', {toast: 'Invalid username or password.', cdnURL: config.CDN_domain,});
+ break;
+ }
+ });
+ if (!login) {
+ return;
+ }
- const PNID = await util.data.getUserDataFromToken(login.accessToken);
- if(!PNID)
- return res.render(req.directory + '/login.ejs', {toast: 'Invalid username or password.', cdnURL: config.CDN_domain,});
+ const PNID = await util.data.getUserDataFromToken(login.accessToken);
+ if (!PNID) {
+ return res.render(req.directory + '/login.ejs', {toast: 'Invalid username or password.', cdnURL: config.CDN_domain,});
+ }
- const pid = PNID.pid;
+ const pid = PNID.pid;
- let discovery = await database.getEndPoint(PNID.serverAccessLevel);
- let message = '';
- switch (discovery.status) {
- case 3:
- message = "Juxt is currently undergoing maintenance. Please try again later.";
- break;
- case 4:
- message = "Juxt is currently closed. Thank you for your interest.";
- break;
- default:
- message = "Juxt is currently unavailable. Please try again later.";
- break;
- }
- if(discovery.status !== 0) {
- return res.render(req.directory + '/error.ejs', {
- code: 504,
- message: message,
- cdnURL: config.CDN_domain,
- lang: req.lang,
- pid: pid,
- moderator: req.moderator
- });
- }
- let cookieDomain = (req.hostname.indexOf('miiverse') !== -1) ? '.miiverse.cc' : '.pretendo.network';
- let expiration = (req.hostname.indexOf('miiverse') !== -1) ? login.expiresIn * 60 * 60 * 24 : login.expiresIn * 60 * 60
- res.cookie('access_token', login.accessToken, { domain : cookieDomain, maxAge: expiration });
- res.cookie('refresh_token', login.refreshToken, { domain : cookieDomain });
- res.redirect('/');
+ let discovery = await database.getEndPoint(PNID.serverAccessLevel);
+ if (!discovery) {
+ discovery = {
+ status: 5
+ };
+ }
+ let message = '';
+ switch (discovery.status) {
+ case 3:
+ message = 'Juxt is currently undergoing maintenance. Please try again later.';
+ break;
+ case 4:
+ message = 'Juxt is currently closed. Thank you for your interest.';
+ break;
+ default:
+ message = 'Juxt is currently unavailable. Please try again later.';
+ break;
+ }
+ if (discovery.status !== 0) {
+ return res.render(req.directory + '/error.ejs', {
+ code: 504,
+ message: message,
+ cdnURL: config.CDN_domain,
+ lang: req.lang,
+ pid: pid,
+ moderator: req.moderator
+ });
+ }
+ const cookieDomain = (req.hostname.indexOf('miiverse') !== -1) ? '.miiverse.cc' : '.pretendo.network';
+ const expiration = (req.hostname.indexOf('miiverse') !== -1) ? login.expiresIn * 60 * 60 * 24 : login.expiresIn * 60 * 60;
+ res.cookie('access_token', login.accessToken, { domain : cookieDomain, maxAge: expiration });
+ res.cookie('refresh_token', login.refreshToken, { domain : cookieDomain });
+ res.redirect('/');
});
diff --git a/src/services/juxt-web/routes/web/pwa.js b/src/services/juxt-web/routes/web/pwa.js
index 6756caf..bdcad2f 100644
--- a/src/services/juxt-web/routes/web/pwa.js
+++ b/src/services/juxt-web/routes/web/pwa.js
@@ -1,15 +1,15 @@
const express = require('express');
-const path = require("path");
+const path = require('path');
const router = express.Router();
router.get('/icons/:filename', function (req, res) {
- res.set("Content-Type", "image/png");
- res.sendFile('/images/icons/' + req.params.filename, {root: path.join(__dirname, '../../../../webfiles/web')});
+ res.set('Content-Type', 'image/png');
+ res.sendFile('/images/icons/' + req.params.filename, {root: path.join(__dirname, '../../../../webfiles/web')});
});
router.get('/manifest.json', function (req, res) {
- res.set("Content-Type", "text/json");
- res.sendFile('manifest.json', {root: path.join(__dirname, '../../../../webfiles/web')});
+ res.set('Content-Type', 'text/json');
+ res.sendFile('manifest.json', {root: path.join(__dirname, '../../../../webfiles/web')});
});
module.exports = router;
diff --git a/src/services/juxt-web/routes/web/robots.js b/src/services/juxt-web/routes/web/robots.js
index c016aa5..859b545 100644
--- a/src/services/juxt-web/routes/web/robots.js
+++ b/src/services/juxt-web/routes/web/robots.js
@@ -1,10 +1,10 @@
const express = require('express');
-const path = require("path");
+const path = require('path');
const router = express.Router();
router.get('/', function (req, res) {
- res.set("Content-Type", "text/css");
- res.sendFile('robots.txt', {root: path.join(__dirname, '../../../../webfiles/web')});
+ res.set('Content-Type', 'text/css');
+ res.sendFile('robots.txt', {root: path.join(__dirname, '../../../../webfiles/web')});
});
diff --git a/src/translations/index.js b/src/translations/index.js
index 4aecb45..ced482f 100644
--- a/src/translations/index.js
+++ b/src/translations/index.js
@@ -1,14 +1,14 @@
module.exports = {
- JA: require('./ja.json'),
- EN: require('./en.json'),
- FR: require('./fr.json'),
- DE: require('./de.json'),
- IT: require('./it.json'),
- ES: require('./es.json'),
- ZH: require('./zh.json'),
- KO: require('./ko.json'),
- NL: require('./nl.json'),
- PT: require('./pt.json'),
- RU: require('./ru.json'),
+ JA: require('./ja.json'),
+ EN: require('./en.json'),
+ FR: require('./fr.json'),
+ DE: require('./de.json'),
+ IT: require('./it.json'),
+ ES: require('./es.json'),
+ ZH: require('./zh.json'),
+ KO: require('./ko.json'),
+ NL: require('./nl.json'),
+ PT: require('./pt.json'),
+ RU: require('./ru.json'),
};
\ No newline at end of file
diff --git a/src/util.js b/src/util.js
index b1e31f7..9d1dc82 100644
--- a/src/util.js
+++ b/src/util.js
@@ -12,16 +12,16 @@ const { COMMUNITY } = require('./models/communities');
const { AccountDefinition } = require('pretendo-grpc/dist/account/account_service');
const { FriendsDefinition } = require('pretendo-grpc/dist/friends/friends_service');
const { APIDefinition } = require('pretendo-grpc/dist/api/api_service');
-const translations = require('./translations')
+const translations = require('./translations');
const HashMap = require('hashmap');
const TGA = require('tga');
const pako = require('pako');
const PNG = require('pngjs').PNG;
-const bmp = require("bmp-js");
+const bmp = require('bmp-js');
const aws = require('aws-sdk');
const crc32 = require('crc/crc32');
-let communityMap = new HashMap();
-let userMap = new HashMap();
+const communityMap = new HashMap();
+const userMap = new HashMap();
const { ip: friendsIP, port: friendsPort, api_key: friendsKey } = config.grpc.friends;
const friendsChannel = grpc.createChannel(`${friendsIP}:${friendsPort}`);
@@ -36,311 +36,307 @@ const accountClient = grpc.createClient(AccountDefinition, accountChannel);
const spacesEndpoint = new aws.Endpoint('nyc3.digitaloceanspaces.com');
const s3 = new aws.S3({
- endpoint: spacesEndpoint,
- accessKeyId: config.aws.spaces.key,
- secretAccessKey: config.aws.spaces.secret
+ endpoint: spacesEndpoint,
+ accessKeyId: config.aws.spaces.key,
+ secretAccessKey: config.aws.spaces.secret
});
nameCache();
function nameCache() {
- database.connect().then(async e => {
- let communities = await COMMUNITY.find();
- if(communities !== null) {
- for(let i = 0; i < communities.length; i++ ) {
- if(communities[i].title_id !== null) {
- for(let j = 0; j < communities[i].title_id.length; j++) {
- communityMap.set(communities[i].title_id[j], communities[i].name);
- communityMap.set(communities[i].title_id[j] + '-id', communities[i].olive_community_id);
- }
- communityMap.set(communities[i].olive_community_id, communities[i].name);
- }
- }
- logger.success('Created community index of ' + communities.length + ' communities');
- }
- let users = await database.getUsersSettings(-1);
- if(users !== null) {
- for(let i = 0; i < users.length; i++ ) {
- if(users[i].pid !== null) {
- userMap.set(users[i].pid, users[i].screen_name.replace(/[\u{0080}-\u{FFFF}]/gu,""));
- }
- }
- logger.success('Created user index of ' + users.length + ' users')
- }
+ database.connect().then(async e => {
+ const communities = await COMMUNITY.find();
+ if (communities !== null) {
+ for (let i = 0; i < communities.length; i++ ) {
+ if (communities[i].title_id !== null) {
+ for (let j = 0; j < communities[i].title_id.length; j++) {
+ communityMap.set(communities[i].title_id[j], communities[i].name);
+ communityMap.set(communities[i].title_id[j] + '-id', communities[i].olive_community_id);
+ }
+ communityMap.set(communities[i].olive_community_id, communities[i].name);
+ }
+ }
+ logger.success('Created community index of ' + communities.length + ' communities');
+ }
+ const users = await database.getUsersSettings(-1);
+ if (users !== null) {
+ for (let i = 0; i < users.length; i++ ) {
+ if (users[i].pid !== null) {
+ userMap.set(users[i].pid, users[i].screen_name.replace(/[\u{0080}-\u{FFFF}]/gu,''));
+ }
+ }
+ logger.success('Created user index of ' + users.length + ' users');
+ }
- }).catch(error => {
- logger.error(error);
- });
+ }).catch(error => {
+ logger.error(error);
+ });
}
-let methods = {
- create_user: async function(pid, experience, notifications) {
- const pnid = await this.getUserDataFromPid(pid);
- if(!pnid)
- return;
- let newSettings = {
- pid: pid,
- screen_name: pnid.mii.name,
- game_skill: experience,
- receive_notifications: notifications,
- }
- let newContent = {
- pid: pid
- }
- const newSettingsObj = new SETTINGS(newSettings);
- await newSettingsObj.save();
+const methods = {
+ create_user: async function(pid, experience, notifications) {
+ const pnid = await this.getUserDataFromPid(pid);
+ if (!pnid) {
+ return;
+ }
+ const newSettings = {
+ pid: pid,
+ screen_name: pnid.mii.name,
+ game_skill: experience,
+ receive_notifications: notifications,
+ };
+ const newContent = {
+ pid: pid
+ };
+ const newSettingsObj = new SETTINGS(newSettings);
+ await newSettingsObj.save();
- const newContentObj = new CONTENT(newContent);
- await newContentObj.save();
+ const newContentObj = new CONTENT(newContent);
+ await newContentObj.save();
- this.setName(pid, pnid.mii.name);
- },
- decodeParamPack: function (paramPack) {
- /* Decode base64 */
- let dec = Buffer.from(paramPack, "base64").toString("ascii");
- /* Remove starting and ending '/', split into array */
- dec = dec.slice(1, -1).split("\\");
- /* Parameters are in the format [name, val, name, val]. Copy into out{}. */
- const out = {};
- for (let i = 0; i < dec.length; i += 2) {
- out[dec[i].trim()] = dec[i + 1].trim();
- }
- return out;
- },
- processServiceToken: function(encryptedToken) {
- try
- {
- let B64token = Buffer.from(encryptedToken, 'base64');
- let decryptedToken = this.decryptToken(B64token);
- const token = this.unpackToken(decryptedToken);
- return token.pid;
- }
- catch(e)
- {
- console.log(e)
- return null;
- }
+ this.setName(pid, pnid.mii.name);
+ },
+ decodeParamPack: function (paramPack) {
+ /* Decode base64 */
+ let dec = Buffer.from(paramPack, 'base64').toString('ascii');
+ /* Remove starting and ending '/', split into array */
+ dec = dec.slice(1, -1).split('\\');
+ /* Parameters are in the format [name, val, name, val]. Copy into out{}. */
+ const out = {};
+ for (let i = 0; i < dec.length; i += 2) {
+ out[dec[i].trim()] = dec[i + 1].trim();
+ }
+ return out;
+ },
+ processServiceToken: function(encryptedToken) {
+ try {
+ const B64token = Buffer.from(encryptedToken, 'base64');
+ const decryptedToken = this.decryptToken(B64token);
+ const token = this.unpackToken(decryptedToken);
+ return token.pid;
+ } catch (e) {
+ console.log(e);
+ return null;
+ }
- },
- decryptToken: function(token) {
- if (!config.aes_key) {
- throw new Error('Service token AES key not found. Set config.aes_key');
- }
+ },
+ decryptToken: function(token) {
+ if (!config.aes_key) {
+ throw new Error('Service token AES key not found. Set config.aes_key');
+ }
- const iv = Buffer.alloc(16);
- const key = Buffer.from(config.aes_key, 'hex');
+ const iv = Buffer.alloc(16);
+ const key = Buffer.from(config.aes_key, 'hex');
- const expectedChecksum = token.readUint32BE();
- const encryptedBody = token.subarray(4);
+ const expectedChecksum = token.readUint32BE();
+ const encryptedBody = token.subarray(4);
- const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
+ const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
- const decrypted = Buffer.concat([
- decipher.update(encryptedBody),
- decipher.final()
- ]);
+ const decrypted = Buffer.concat([
+ decipher.update(encryptedBody),
+ decipher.final()
+ ]);
- if (expectedChecksum !== crc32(decrypted)) {
- throw new Error('Checksum did not match. Failed decrypt. Are you using the right key?');
- }
+ if (expectedChecksum !== crc32(decrypted)) {
+ throw new Error('Checksum did not match. Failed decrypt. Are you using the right key?');
+ }
- return decrypted;
- },
- unpackToken: function(token) {
- return {
- system_type: token.readUInt8(0x0),
- token_type: token.readUInt8(0x1),
- pid: token.readUInt32LE(0x2),
- expire_time: token.readBigUInt64LE(0x6),
- title_id: token.readBigUInt64LE(0xE),
- access_level: token.readInt8(0x16)
- };
- },
- processPainting: async function (painting, isTGA) {
- if (isTGA) {
- let paintingBuffer = Buffer.from(painting, 'base64');
- let output = '';
- try {
- output = pako.inflate(paintingBuffer);
- } catch (err) {
- console.error(err);
- }
- let tga;
- try {
- tga = new TGA(Buffer.from(output));
- }
- catch (e) {
- console.log(e)
- return null;
- }
- let png = new PNG({
- width: tga.width,
- height: tga.height
- });
- png.data = tga.pixels;
- return PNG.sync.write(png);
- //return `data:image/png;base64,${pngBuffer.toString('base64')}`;
- }
- else {
- let paintingBuffer = Buffer.from(painting, 'base64');
- let bitmap = bmp.decode(paintingBuffer)
- const tga = this.createBMPTgaBuffer(bitmap.width, bitmap.height, bitmap.data, false);
+ return decrypted;
+ },
+ unpackToken: function(token) {
+ return {
+ system_type: token.readUInt8(0x0),
+ token_type: token.readUInt8(0x1),
+ pid: token.readUInt32LE(0x2),
+ expire_time: token.readBigUInt64LE(0x6),
+ title_id: token.readBigUInt64LE(0xE),
+ access_level: token.readInt8(0x16)
+ };
+ },
+ processPainting: async function (painting, isTGA) {
+ if (isTGA) {
+ const paintingBuffer = Buffer.from(painting, 'base64');
+ let output = '';
+ try {
+ output = pako.inflate(paintingBuffer);
+ } catch (err) {
+ console.error(err);
+ }
+ let tga;
+ try {
+ tga = new TGA(Buffer.from(output));
+ } catch (e) {
+ console.log(e);
+ return null;
+ }
+ const png = new PNG({
+ width: tga.width,
+ height: tga.height
+ });
+ png.data = tga.pixels;
+ return PNG.sync.write(png);
+ //return `data:image/png;base64,${pngBuffer.toString('base64')}`;
+ } else {
+ const paintingBuffer = Buffer.from(painting, 'base64');
+ const bitmap = bmp.decode(paintingBuffer);
+ const tga = this.createBMPTgaBuffer(bitmap.width, bitmap.height, bitmap.data, false);
- let output;
- try {
- output = pako.deflate(tga, {level: 6});
- }
- catch (err) {
- console.error(err);
- }
- return new Buffer(output).toString('base64')
- }
- },
- nintendoPasswordHash: function(password, pid) {
- const pidBuffer = Buffer.alloc(4);
- pidBuffer.writeUInt32LE(pid);
+ let output;
+ try {
+ output = pako.deflate(tga, {level: 6});
+ } catch (err) {
+ console.error(err);
+ }
+ return new Buffer(output).toString('base64');
+ }
+ },
+ nintendoPasswordHash: function(password, pid) {
+ const pidBuffer = Buffer.alloc(4);
+ pidBuffer.writeUInt32LE(pid);
- const unpacked = Buffer.concat([
- pidBuffer,
- Buffer.from('\x02\x65\x43\x46'),
- Buffer.from(password)
- ]);
- return crypto.createHash('sha256').update(unpacked).digest().toString('hex');
- },
- getCommunityHash: function() {
- return communityMap;
- },
- getUserHash: function() {
- return userMap;
- },
- refreshCache: function () {
- nameCache();
- },
- setName: function (pid, name) {
- if(!pid || !name)
- return;
- userMap.delete(pid);
- userMap.set(pid, name);
- },
- resizeImage: function (file, width, height) {
- sharp(file)
- .resize({ height: height, width: width })
- .toBuffer()
- .then(data => {
- return data;
- });
- },
- createBMPTgaBuffer: function(width, height, pixels, dontFlipY) {
- var buffer = Buffer.alloc(18 + pixels.length);
- // write header
- buffer.writeInt8(0, 0);
- buffer.writeInt8(0, 1);
- buffer.writeInt8(2, 2);
- buffer.writeInt16LE(0, 3);
- buffer.writeInt16LE(0, 5);
- buffer.writeInt8(0, 7);
- buffer.writeInt16LE(0, 8);
- buffer.writeInt16LE(0, 10);
- buffer.writeInt16LE(width, 12);
- buffer.writeInt16LE(height, 14);
- buffer.writeInt8(32, 16);
- buffer.writeInt8(8, 17);
+ const unpacked = Buffer.concat([
+ pidBuffer,
+ Buffer.from('\x02\x65\x43\x46'),
+ Buffer.from(password)
+ ]);
+ return crypto.createHash('sha256').update(unpacked).digest().toString('hex');
+ },
+ getCommunityHash: function() {
+ return communityMap;
+ },
+ getUserHash: function() {
+ return userMap;
+ },
+ refreshCache: function () {
+ nameCache();
+ },
+ setName: function (pid, name) {
+ if (!pid || !name) {
+ return;
+ }
+ userMap.delete(pid);
+ userMap.set(pid, name);
+ },
+ resizeImage: function (file, width, height) {
+ sharp(file)
+ .resize({ height: height, width: width })
+ .toBuffer()
+ .then(data => {
+ return data;
+ });
+ },
+ createBMPTgaBuffer: function(width, height, pixels, dontFlipY) {
+ const buffer = Buffer.alloc(18 + pixels.length);
+ // write header
+ buffer.writeInt8(0, 0);
+ buffer.writeInt8(0, 1);
+ buffer.writeInt8(2, 2);
+ buffer.writeInt16LE(0, 3);
+ buffer.writeInt16LE(0, 5);
+ buffer.writeInt8(0, 7);
+ buffer.writeInt16LE(0, 8);
+ buffer.writeInt16LE(0, 10);
+ buffer.writeInt16LE(width, 12);
+ buffer.writeInt16LE(height, 14);
+ buffer.writeInt8(32, 16);
+ buffer.writeInt8(8, 17);
- var offset = 18;
- for (var i = 0; i < height; i++) {
- for (var j = 0; j < width; j++) {
- var idx = ((dontFlipY ? i : height - i - 1) * width + j) * 4;
- buffer.writeUInt8(pixels[idx + 1], offset++); // b
- buffer.writeUInt8(pixels[idx + 2], offset++); // g
- buffer.writeUInt8(pixels[idx + 3], offset++); // r
- buffer.writeUInt8(255, offset++); // a
- }
- }
+ let offset = 18;
+ for (let i = 0; i < height; i++) {
+ for (let j = 0; j < width; j++) {
+ const idx = ((dontFlipY ? i : height - i - 1) * width + j) * 4;
+ buffer.writeUInt8(pixels[idx + 1], offset++); // b
+ buffer.writeUInt8(pixels[idx + 2], offset++); // g
+ buffer.writeUInt8(pixels[idx + 3], offset++); // r
+ buffer.writeUInt8(255, offset++); // a
+ }
+ }
- return buffer;
- },
- processLanguage: function (paramPackData) {
- if(!paramPackData)
- return translations.EN;
- switch (paramPackData.language_id) {
- case '0':
- return translations.JA
- case '1':
- return translations.EN
- case '2':
- return translations.FR
- case '3':
- return translations.DE
- case '4':
- return translations.IT
- case '5':
- return translations.ES
- case '6':
- return translations.ZH
- case '7':
- return translations.KO
- case '8':
- return translations.NL
- case '9':
- return translations.PT
- case '10':
- return translations.RU
- case '11':
- return translations.ZH
- default:
- return translations.EN
- }
- },
- uploadCDNAsset: async function(bucket, key, data, acl) {
- const awsPutParams = {
- Body: data,
- Key: key,
- Bucket: bucket,
- ACL: acl
- };
+ return buffer;
+ },
+ processLanguage: function (paramPackData) {
+ if (!paramPackData) {
+ return translations.EN;
+ }
+ switch (paramPackData.language_id) {
+ case '0':
+ return translations.JA;
+ case '1':
+ return translations.EN;
+ case '2':
+ return translations.FR;
+ case '3':
+ return translations.DE;
+ case '4':
+ return translations.IT;
+ case '5':
+ return translations.ES;
+ case '6':
+ return translations.ZH;
+ case '7':
+ return translations.KO;
+ case '8':
+ return translations.NL;
+ case '9':
+ return translations.PT;
+ case '10':
+ return translations.RU;
+ case '11':
+ return translations.ZH;
+ default:
+ return translations.EN;
+ }
+ },
+ uploadCDNAsset: async function(bucket, key, data, acl) {
+ const awsPutParams = {
+ Body: data,
+ Key: key,
+ Bucket: bucket,
+ ACL: acl
+ };
- await s3.putObject(awsPutParams).promise();
- },
- newNotification: async function(notification) {
- const now = new Date();
- if(notification.type === 'follow') {
- // { pid: userToFollowContent.pid, type: "follow", objectID: req.pid, link: `/users/${req.pid}` }
- let existingNotification = await NOTIFICATION.findOne({ pid: notification.pid, objectID: notification.objectID })
- if(existingNotification) {
- existingNotification.lastUpdated = now;
- existingNotification.read = false;
- return await existingNotification.save();
- }
- const last10min = new Date(now.getTime() - 10 * 60 * 1000);
- existingNotification = await NOTIFICATION.findOne({ pid: notification.pid, type: 'follow', lastUpdated: { $gte: last10min } });
- if(existingNotification) {
- existingNotification.users.push({
- user: notification.objectID,
- timeStamp: now
- });
- existingNotification.lastUpdated = now;
- existingNotification.link = notification.link;
- existingNotification.objectID = notification.objectID;
- existingNotification.read = false;
- return await existingNotification.save();
- }
- else {
- let newNotification = new NOTIFICATION({
- pid: notification.pid,
- type: notification.type,
- users: [{
- user: notification.objectID,
- timestamp: now
- }],
- link: notification.link,
- objectID: notification.objectID,
- read: false,
- lastUpdated: now
- });
- await newNotification.save();
- }
- }
- /*else if(notification.type === 'yeah') {
+ await s3.putObject(awsPutParams).promise();
+ },
+ newNotification: async function(notification) {
+ const now = new Date();
+ if (notification.type === 'follow') {
+ // { pid: userToFollowContent.pid, type: "follow", objectID: req.pid, link: `/users/${req.pid}` }
+ let existingNotification = await NOTIFICATION.findOne({ pid: notification.pid, objectID: notification.objectID });
+ if (existingNotification) {
+ existingNotification.lastUpdated = now;
+ existingNotification.read = false;
+ return await existingNotification.save();
+ }
+ const last10min = new Date(now.getTime() - 10 * 60 * 1000);
+ existingNotification = await NOTIFICATION.findOne({ pid: notification.pid, type: 'follow', lastUpdated: { $gte: last10min } });
+ if (existingNotification) {
+ existingNotification.users.push({
+ user: notification.objectID,
+ timeStamp: now
+ });
+ existingNotification.lastUpdated = now;
+ existingNotification.link = notification.link;
+ existingNotification.objectID = notification.objectID;
+ existingNotification.read = false;
+ return await existingNotification.save();
+ } else {
+ const newNotification = new NOTIFICATION({
+ pid: notification.pid,
+ type: notification.type,
+ users: [{
+ user: notification.objectID,
+ timestamp: now
+ }],
+ link: notification.link,
+ objectID: notification.objectID,
+ read: false,
+ lastUpdated: now
+ });
+ await newNotification.save();
+ }
+ }
+ /*else if(notification.type === 'yeah') {
// { pid: userToFollowContent.pid, type: "follow", objectID: req.pid, link: `/users/${req.pid}` }
let existingNotification = await NOTIFICATION.findOne({ pid: notification.pid, objectID: notification.objectID })
if(existingNotification) {
@@ -374,58 +370,58 @@ let methods = {
await newNotification.save();
}
}*/
- },
- getFriends: async function(pid) {
- const pids = await friendsClient.getUserFriendPIDs({
- pid: pid
- }, {
- metadata: grpc.Metadata({
- 'X-API-Key': friendsKey
- })
- });
- return pids.pids;
- },
- getFriendRequests: async function(pid) {
- const requests = await friendsClient.getUserFriendRequestsIncoming({
- pid: pid
- }, {
- metadata: grpc.Metadata({
- 'X-API-Key': friendsKey
- })
- });
- return requests.friendRequests;
- },
- login: async function(username, password) {
- return await apiClient.login({
- username: username,
- password: password,
- grantType: 'password'
- }, {
- metadata: grpc.Metadata({
- 'X-API-Key': apiKey
- })
- });
- },
- getUserDataFromToken: async function(token) {
- return apiClient.getUserData({}, {
- metadata: grpc.Metadata({
- 'X-API-Key': apiKey,
- 'X-Token': token
- })
- });
- },
- getUserDataFromPid: async function(pid) {
- return accountClient.getUserData({
- pid: pid
- }, {
- metadata: grpc.Metadata({
- 'X-API-Key': apiKey
- })
- });
- },
- getPid: async function(token) {
- const user = await this.getUserDataFromToken(token);
- return user.pid;
- }
+ },
+ getFriends: async function(pid) {
+ const pids = await friendsClient.getUserFriendPIDs({
+ pid: pid
+ }, {
+ metadata: grpc.Metadata({
+ 'X-API-Key': friendsKey
+ })
+ });
+ return pids.pids;
+ },
+ getFriendRequests: async function(pid) {
+ const requests = await friendsClient.getUserFriendRequestsIncoming({
+ pid: pid
+ }, {
+ metadata: grpc.Metadata({
+ 'X-API-Key': friendsKey
+ })
+ });
+ return requests.friendRequests;
+ },
+ login: async function(username, password) {
+ return await apiClient.login({
+ username: username,
+ password: password,
+ grantType: 'password'
+ }, {
+ metadata: grpc.Metadata({
+ 'X-API-Key': apiKey
+ })
+ });
+ },
+ getUserDataFromToken: async function(token) {
+ return apiClient.getUserData({}, {
+ metadata: grpc.Metadata({
+ 'X-API-Key': apiKey,
+ 'X-Token': token
+ })
+ });
+ },
+ getUserDataFromPid: async function(pid) {
+ return accountClient.getUserData({
+ pid: pid
+ }, {
+ metadata: grpc.Metadata({
+ 'X-API-Key': apiKey
+ })
+ });
+ },
+ getPid: async function(token) {
+ const user = await this.getUserDataFromToken(token);
+ return user.pid;
+ }
};
exports.data = methods;
diff --git a/src/webfiles/ctr/js/debug.js b/src/webfiles/ctr/js/debug.js
index c28edb4..92cfcd0 100644
--- a/src/webfiles/ctr/js/debug.js
+++ b/src/webfiles/ctr/js/debug.js
@@ -1,277 +1,278 @@
-if (typeof cave !== "undefined") {
- window.addEventListener("error", handleError, true);
+if (typeof cave !== 'undefined') {
+ window.addEventListener('error', handleError, true);
- function handleError(evt) {
- if (evt.message) { // Chrome sometimes provides this
- alert("error: " + evt.message + " at linenumber: " + evt.lineno + " of file: " + evt.filename);
- } else {
- if((evt.srcElement || evt.target).toString().indexOf('HTMLImageElement') !== -1)
- return;
- alert("error: " + evt.type + " from element: " + (evt.srcElement || evt.target));
- }
- }
+ function handleError(evt) {
+ if (evt.message) { // Chrome sometimes provides this
+ alert('error: ' + evt.message + ' at linenumber: ' + evt.lineno + ' of file: ' + evt.filename);
+ } else {
+ if ((evt.srcElement || evt.target).toString().indexOf('HTMLImageElement') !== -1) {
+ return;
+ }
+ alert('error: ' + evt.type + ' from element: ' + (evt.srcElement || evt.target));
+ }
+ }
}
-if (typeof cave === "undefined") {
- window.cave = {
- /**
+if (typeof cave === 'undefined') {
+ window.cave = {
+ /**
* Enables or disabled the back button on the toolbar
* @param enable
*/
- toolbar_enableBackBtnFunc: function (enable) {
- console.log('cave.toolbar_enableBackBtnFunc(enable = ' + enable + ')');
- },
- /**
+ toolbar_enableBackBtnFunc: function (enable) {
+ console.log('cave.toolbar_enableBackBtnFunc(enable = ' + enable + ')');
+ },
+ /**
* Sets the callback function for a given toolbar button
* @param btnType
* @param callback
*/
- toolbar_setCallback: function (btnType, callback) {
- console.log('cave.toolbar_setCallback(btnType = ' + btnType + ', callback = ' + typeof callback + ')');
- },
- /**
+ toolbar_setCallback: function (btnType, callback) {
+ console.log('cave.toolbar_setCallback(btnType = ' + btnType + ', callback = ' + typeof callback + ')');
+ },
+ /**
* Toggles the visibility of the toolbar
* @param visibility
*/
- toolbar_setVisible: function (visibility) {
- console.log('cave.toolbar_setVisible(visibility = ' + visibility + ')');
- },
- /**
+ toolbar_setVisible: function (visibility) {
+ console.log('cave.toolbar_setVisible(visibility = ' + visibility + ')');
+ },
+ /**
* (untested) Appears to set the "corner button" type.
* @param type
*/
- toolbar_setButtonType: function (type) {
- console.log('cave.toolbar_setButtonType(type = ' + type + ')');
- },
- /**
+ toolbar_setButtonType: function (type) {
+ console.log('cave.toolbar_setButtonType(type = ' + type + ')');
+ },
+ /**
* Highlight a button - usually done in a button's own callback function to show that it has been activated.
* @param btnType
*/
- toolbar_setActiveButton: function (btnType) {
- console.log('cave.toolbar_setActiveButton(btnType = ' + btnType + ')');
- },
- /**
+ toolbar_setActiveButton: function (btnType) {
+ console.log('cave.toolbar_setActiveButton(btnType = ' + btnType + ')');
+ },
+ /**
* Open the drawing tool interface.
*/
- memo_open: function () {
- console.log('cave.memo_open()');
- },
- /**
+ memo_open: function () {
+ console.log('cave.memo_open()');
+ },
+ /**
* Clear the current drawing.
*/
- memo_clear: function () {
- console.log('cave.memo_clear()');
- },
- /**
+ memo_clear: function () {
+ console.log('cave.memo_clear()');
+ },
+ /**
* Unknown
* @returns {boolean}
*/
- memo_hasValidImage: function () {
- console.log('cave.memo_hasValidImage()');
- return true;
- },
- /**
+ memo_hasValidImage: function () {
+ console.log('cave.memo_hasValidImage()');
+ return true;
+ },
+ /**
* Returns the drawing as base64 encoded BMP image.
* @returns {string}
*/
- memo_getImageBmp: function () {
- console.log('cave.memo_getImageBmp()');
- return 'Qk1SEwAAAAAAAJIAAAB8AAAAQAEAAHgAAAABAAEAAAAAAMASAAASCwAAEgsAAAIAAAACAAAAAAD/AAD/AAD/AAAAAAAA/0JHUnOPwvUoUbgeFR6F6wEzMzMTZmZmJmZmZgaZmZkJPQrXAyhcjzIAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAP///wD/////////////////////+P/////8f/////////////////////////////////////////////j//////H/////////////////////////////////////////////4//////x/////////////////////////////////////////////+P/////8f////////////////////////////////////////4A///h//////H////////////////////////////////////////4AH//4f/////x////////////////////////////////////////+Hx///H/////8f////////////////////////////////////////j8H//x//////H////////////////////////////////////////4wB//8f/////x////////////////////////////////////////+AAP//D//h//8f////////////////////////////////////////wPh//4//4f//H////////////////////////////////////////8H4f/+P/+H//x/////////////////////////////////////////h/D//j/////8f////////////////////////////////////////4f4f/4//////H/////////////////////////////////////////D/D/+P/////x/////////////////////////////////////////w/w//j/////8f////////////////////////////////////////+H+H/4//////H/////////////////////////////////////////w/g/+P/////x/////////////////////////////////////////8P+H/j//A//8f/////////////////////////////////////////h/h/4//wP//H/////////////////////////////////////////8f8P+P/4B//x//////////////////////////////////////////D/D/j/8Mf/8f/////////////////////////////////////////4f4f4/+HD//H/////////////////////////////////////////+D+H+P/h4//x//////////////////////////////////////////4fwfj/w+H/8f/wB//////////////////////////////////////+H+H4/8Ph//H/wAP//////////////////////////////////////w/w+H+H4P/x/wPA//////////////////////////////////////+H+Hx/h+D/8fwH4H//////////////////////////////////////x/w8f4Pgf/HwP/wf/////////////////////////////////////8P8HH8D4H/x4H/8D//////////////////////////////////////h/wx/A8A/8YP//4H/////////////////////////////////////8f8EfgPEP/EH///B//////////////////////////////////////D/gH4jxj/wH///8H/////////////////////////////////////4f8B+I8Y/8D////g//////////////////////////////////////D/gfCHGH/D/8B/8D/////////////////////////////////////4f8Hwhxx/w/+AP/gf/////////////////////////////////////D/h8cccf///Bg/+D/////////////////////////////////////4f//HHHH///g8H/wf/////////////////////////////////////D//hxhw///w/gf+D/////////////////////////////////////wf/48YeP//4P+D/4f/////////////////////////////////////D/+PCPj//4P/wf/A/////////////////////////////////////w//Dwj4//8H//B/4H////////////////////////////////////+D/x+A+P/+D//4H/h/////////////////////////////////////w/8fgPj//D///g/4D////////////////////////////////////+D/GAAAf/B///+D8AP////////////////////////////////////w/xAAAH/g////wPDD////////////////////////////////////+H8ADAB/w/////BB4f////////////////////////////////////w/Aggwf4f////4A/H////////////////////////////////////+HweA/D4P/////gfh/////////////////////////////////////w4Pgfw8H/////8Hwf///////////////////////////////////+AAAAB+EH//////wAP//////////////////////////////////+AAAAAAAAAf/////8AH//////////////////////////////////gAB+P//gAAAAH////////////////////////////////////////4B///////H4AB////////////////////////////////////////+P//////////4f////////////////////////////////////////j//////////+H////////////////////////////////////////4///////////j////////////////////////////////////////+P//////////4/////////////////////////////////////////j//////////8P////////////////////////////////////////4///////////D////////////////////////////////////////+P//////////x/////////////////////////////////////////j//////////8f////////////////////////////////////////4////wD/////H////////////////////////////////////////+P///4AP////x/////////////////////////////////////////h///wPAH///8f////////////////////////////////////////4f//4H8Af///H//////////////////////////////////////8ADH//wP/+AP//x//////////////////////////////////////8AAB//wH//4B//8YB////////////////////////////////////+D/Af/wP///8B//AAAP///////////////////////////////////j/8H/4H////gH/wHgA/////////////////////////////////8AA//x/8P/////gP8f/8H///////AAAAAAAAP////////////////+AAP/8f+H/////+A/H//x///////wAAAAAAAD////////////////+D////H+D8P///H8Bx//4f//////////////w/////////////////h////x/B/D///x/wEf/8AH///////////////////////////////4////8fB/x///8f/gH//AAP//////////////////////////////+H////HA/8f///H/8B///+B/////////////////////////////8AA////xg//H///x//4f///8H////////////////////////////8AAP///8Q//x///8f//H////h////////////////////////////8D//////Af/4f///H//x////8f///////////////////////////+D//////wP/+P///x//8f////H////////////////////////////D//////8H//j///8f//H////h////////////////////////////h///////H//4////H//x////w////////////////////////////4///////x///////x//8D///gf///////////////////////////+P/////8Af//////////AH//4D////////////////////////////j/////AAH//////////xAP/+AD////////H//////////////////4/////ADj//////////8eB///Af///////w//////////////////+P///wA/4///////////H8H///D///////+H//////////////////h///wA/8P//////////x/gf//w//////g/g//////////////////8P//AP//D//////////8f+B//+P/////4P+P//////////////////D/+AP//w/gAAAAAAAAAH/4H//j/////+H/j//////////////////4P4A///8AAAAAAAAAAAB//gf/4////j/w/////////////////////BgB////gAf///////////+D/+P///4f+P////////////////////4AH///////////////////4H/D////D/h/4D//////////////////Af////////////////////Afg/x//w/AP+A////////////////////////////////////////+Awf8f/+MAB/h/////////////////////////////////////////wAP/D//gA4f8f/////////////////////////////////////////wP/4//8D/D///////////////////////////////////////////+D/+P//A/4///////////////////////////////////////////////j//4f+H//////////////////////////////////////////////4f//H/x///////////////////////////////////////////////H//w/////////////////////////////////////////////////w//8H////////////////////////////////////////////////+P//x/////////////////////////////////////////////////h////////////////////////////////////////////////////8P////////////////////////////////////////////////////D////////////////////////////////////////////////////4////////////////////////////////////////////////////+P////////////////////////////////////////////////////j////////////////////////////////////////////////////4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8=';
- },
- /**
+ memo_getImageBmp: function () {
+ console.log('cave.memo_getImageBmp()');
+ return 'Qk1SEwAAAAAAAJIAAAB8AAAAQAEAAHgAAAABAAEAAAAAAMASAAASCwAAEgsAAAIAAAACAAAAAAD/AAD/AAD/AAAAAAAA/0JHUnOPwvUoUbgeFR6F6wEzMzMTZmZmJmZmZgaZmZkJPQrXAyhcjzIAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAP///wD/////////////////////+P/////8f/////////////////////////////////////////////j//////H/////////////////////////////////////////////4//////x/////////////////////////////////////////////+P/////8f////////////////////////////////////////4A///h//////H////////////////////////////////////////4AH//4f/////x////////////////////////////////////////+Hx///H/////8f////////////////////////////////////////j8H//x//////H////////////////////////////////////////4wB//8f/////x////////////////////////////////////////+AAP//D//h//8f////////////////////////////////////////wPh//4//4f//H////////////////////////////////////////8H4f/+P/+H//x/////////////////////////////////////////h/D//j/////8f////////////////////////////////////////4f4f/4//////H/////////////////////////////////////////D/D/+P/////x/////////////////////////////////////////w/w//j/////8f////////////////////////////////////////+H+H/4//////H/////////////////////////////////////////w/g/+P/////x/////////////////////////////////////////8P+H/j//A//8f/////////////////////////////////////////h/h/4//wP//H/////////////////////////////////////////8f8P+P/4B//x//////////////////////////////////////////D/D/j/8Mf/8f/////////////////////////////////////////4f4f4/+HD//H/////////////////////////////////////////+D+H+P/h4//x//////////////////////////////////////////4fwfj/w+H/8f/wB//////////////////////////////////////+H+H4/8Ph//H/wAP//////////////////////////////////////w/w+H+H4P/x/wPA//////////////////////////////////////+H+Hx/h+D/8fwH4H//////////////////////////////////////x/w8f4Pgf/HwP/wf/////////////////////////////////////8P8HH8D4H/x4H/8D//////////////////////////////////////h/wx/A8A/8YP//4H/////////////////////////////////////8f8EfgPEP/EH///B//////////////////////////////////////D/gH4jxj/wH///8H/////////////////////////////////////4f8B+I8Y/8D////g//////////////////////////////////////D/gfCHGH/D/8B/8D/////////////////////////////////////4f8Hwhxx/w/+AP/gf/////////////////////////////////////D/h8cccf///Bg/+D/////////////////////////////////////4f//HHHH///g8H/wf/////////////////////////////////////D//hxhw///w/gf+D/////////////////////////////////////wf/48YeP//4P+D/4f/////////////////////////////////////D/+PCPj//4P/wf/A/////////////////////////////////////w//Dwj4//8H//B/4H////////////////////////////////////+D/x+A+P/+D//4H/h/////////////////////////////////////w/8fgPj//D///g/4D////////////////////////////////////+D/GAAAf/B///+D8AP////////////////////////////////////w/xAAAH/g////wPDD////////////////////////////////////+H8ADAB/w/////BB4f////////////////////////////////////w/Aggwf4f////4A/H////////////////////////////////////+HweA/D4P/////gfh/////////////////////////////////////w4Pgfw8H/////8Hwf///////////////////////////////////+AAAAB+EH//////wAP//////////////////////////////////+AAAAAAAAAf/////8AH//////////////////////////////////gAB+P//gAAAAH////////////////////////////////////////4B///////H4AB////////////////////////////////////////+P//////////4f////////////////////////////////////////j//////////+H////////////////////////////////////////4///////////j////////////////////////////////////////+P//////////4/////////////////////////////////////////j//////////8P////////////////////////////////////////4///////////D////////////////////////////////////////+P//////////x/////////////////////////////////////////j//////////8f////////////////////////////////////////4////wD/////H////////////////////////////////////////+P///4AP////x/////////////////////////////////////////h///wPAH///8f////////////////////////////////////////4f//4H8Af///H//////////////////////////////////////8ADH//wP/+AP//x//////////////////////////////////////8AAB//wH//4B//8YB////////////////////////////////////+D/Af/wP///8B//AAAP///////////////////////////////////j/8H/4H////gH/wHgA/////////////////////////////////8AA//x/8P/////gP8f/8H///////AAAAAAAAP////////////////+AAP/8f+H/////+A/H//x///////wAAAAAAAD////////////////+D////H+D8P///H8Bx//4f//////////////w/////////////////h////x/B/D///x/wEf/8AH///////////////////////////////4////8fB/x///8f/gH//AAP//////////////////////////////+H////HA/8f///H/8B///+B/////////////////////////////8AA////xg//H///x//4f///8H////////////////////////////8AAP///8Q//x///8f//H////h////////////////////////////8D//////Af/4f///H//x////8f///////////////////////////+D//////wP/+P///x//8f////H////////////////////////////D//////8H//j///8f//H////h////////////////////////////h///////H//4////H//x////w////////////////////////////4///////x///////x//8D///gf///////////////////////////+P/////8Af//////////AH//4D////////////////////////////j/////AAH//////////xAP/+AD////////H//////////////////4/////ADj//////////8eB///Af///////w//////////////////+P///wA/4///////////H8H///D///////+H//////////////////h///wA/8P//////////x/gf//w//////g/g//////////////////8P//AP//D//////////8f+B//+P/////4P+P//////////////////D/+AP//w/gAAAAAAAAAH/4H//j/////+H/j//////////////////4P4A///8AAAAAAAAAAAB//gf/4////j/w/////////////////////BgB////gAf///////////+D/+P///4f+P////////////////////4AH///////////////////4H/D////D/h/4D//////////////////Af////////////////////Afg/x//w/AP+A////////////////////////////////////////+Awf8f/+MAB/h/////////////////////////////////////////wAP/D//gA4f8f/////////////////////////////////////////wP/4//8D/D///////////////////////////////////////////+D/+P//A/4///////////////////////////////////////////////j//4f+H//////////////////////////////////////////////4f//H/x///////////////////////////////////////////////H//w/////////////////////////////////////////////////w//8H////////////////////////////////////////////////+P//x/////////////////////////////////////////////////h////////////////////////////////////////////////////8P////////////////////////////////////////////////////D////////////////////////////////////////////////////4////////////////////////////////////////////////////+P////////////////////////////////////////////////////j////////////////////////////////////////////////////4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8=';
+ },
+ /**
* (untested) Returns the drawing as base64 encoded TGA image.
* @returns {string}
*/
- memo_getImageRawTga: function () {
- console.log('cave.memo_getImageRawTga()');
- return 'Qk1CAAAAAAAAAD4AAAAoAAAAAQAAAAEAAAABAAEAAAAAAAQAAADEDgAAxA4AAAAAAAAAAAAAAAAAAP///wCAAAAAAAAA';
- },
- /**
+ memo_getImageRawTga: function () {
+ console.log('cave.memo_getImageRawTga()');
+ return 'Qk1CAAAAAAAAAD4AAAAoAAAAAQAAAAEAAAABAAEAAAAAAAQAAADEDgAAxA4AAAAAAAAAAAAAAAAAAP///wCAAAAAAAAA';
+ },
+ /**
* Set the current notification count
* @param count
*/
- toolbar_setNotificationCount: function (count) {
- console.log('cave.toolbar_setNotificationCount(' + count + ')');
- },
- /**
+ toolbar_setNotificationCount: function (count) {
+ console.log('cave.toolbar_setNotificationCount(' + count + ')');
+ },
+ /**
* Calls system error viewer with specified error code
* @param errorCode
*/
- error_callErrorViewer: function (errorCode) {
- var fakeMessage = 'Message for error code ' + errorCode;
- alert(errorCode + '\n\n' + fakeMessage);
- },
- /**
+ error_callErrorViewer: function (errorCode) {
+ const fakeMessage = 'Message for error code ' + errorCode;
+ alert(errorCode + '\n\n' + fakeMessage);
+ },
+ /**
* Calls system error viewer with specified error code and message
* @param errorCode
*/
- error_callFreeErrorViewer: function (errorCode, message) {
- alert(errorCode + '\n\n' + message);
- },
- /**
+ error_callFreeErrorViewer: function (errorCode, message) {
+ alert(errorCode + '\n\n' + message);
+ },
+ /**
* Begins transition to new page
*/
- transition_begin: function () {
- console.log('cave.transition_begin()');
- },
- /**
+ transition_begin: function () {
+ console.log('cave.transition_begin()');
+ },
+ /**
* Ends transition to new page
*/
- transition_end: function () {
- console.log('cave.transition_end()');
- },
- /**
+ transition_end: function () {
+ console.log('cave.transition_end()');
+ },
+ /**
* Begins transition to new page without grey screen
*/
- transition_beginWithoutEffect: function () {
- console.log('cave.transition_beginWithoutEffect()');
- },
- /**
+ transition_beginWithoutEffect: function () {
+ console.log('cave.transition_beginWithoutEffect()');
+ },
+ /**
* Ends transition to new page without grey screen
*/
- transition_endWithoutEffect: function () {
- console.log('cave.transition_endWithoutEffect()');
- },
- /**
+ transition_endWithoutEffect: function () {
+ console.log('cave.transition_endWithoutEffect()');
+ },
+ /**
* Session storage of key value pair
* @param key
* @param value
* @returns {undefined}
*/
- ls_setItem: function (key, value) {
- console.log('cave.ls_setItem()');
- // string でないと実機でエラー出るので挙動を合わせる
- // If it is not string, an error will occur on the actual machine, so match the behavior
- for (var i = 0; i < 2; i++) {
- if (typeof arguments[i] !== 'string') {
- console.error('Argument ' + i + ' should be string');
- console.error('JavaScript Extension error. Arguments Count or Argument Type is not mutch. Or , too big arguments.');
- return undefined;
- }
- }
- sessionStorage.setItem(key, value);
- },
- /**
+ ls_setItem: function (key, value) {
+ console.log('cave.ls_setItem()');
+ // string でないと実機でエラー出るので挙動を合わせる
+ // If it is not string, an error will occur on the actual machine, so match the behavior
+ for (let i = 0; i < 2; i++) {
+ if (typeof arguments[i] !== 'string') {
+ console.error('Argument ' + i + ' should be string');
+ console.error('JavaScript Extension error. Arguments Count or Argument Type is not mutch. Or , too big arguments.');
+ return undefined;
+ }
+ }
+ sessionStorage.setItem(key, value);
+ },
+ /**
* Fetches value for key from session storage
* @param key
* @returns {undefined|string}
*/
- ls_getItem: function (key) {
- console.log('cave.ls_getItem()');
- if (typeof key !== 'string') {
- console.error('Argument 0 should be string');
- console.error('JavaScript Extension error. Arguments Count or Argument Type is not mutch. Or , too big arguments.');
- return undefined;
- }
- return sessionStorage.getItem(key);
- },
- /**
+ ls_getItem: function (key) {
+ console.log('cave.ls_getItem()');
+ if (typeof key !== 'string') {
+ console.error('Argument 0 should be string');
+ console.error('JavaScript Extension error. Arguments Count or Argument Type is not mutch. Or , too big arguments.');
+ return undefined;
+ }
+ return sessionStorage.getItem(key);
+ },
+ /**
* Removes value for key from session storage
* @param key
*/
- ls_removeItem: function (key) {
- console.log('cave.ls_removeItem()');
- sessionStorage.removeItem(key);
- },
- /**
+ ls_removeItem: function (key) {
+ console.log('cave.ls_removeItem()');
+ sessionStorage.removeItem(key);
+ },
+ /**
* ゲスト初回起動済みフラグをセットする (Set guest first started flag)
* Puts the applet into guest mode
* @param bool
*/
- ls_setGuestModeLaunched: function (bool) {
- console.log('cave.ls_setGuestModeLaunched( ' + bool + ' )');
- },
- /**
+ ls_setGuestModeLaunched: function (bool) {
+ console.log('cave.ls_setGuestModeLaunched( ' + bool + ' )');
+ },
+ /**
* Sets value for specified key in local storage
* @param key
* @param value
*/
- lls_setItem: function (key, value) {
- console.log('cave.lls_setItem()');
- localStorage.setItem(key, value);
- },
- /**
+ lls_setItem: function (key, value) {
+ console.log('cave.lls_setItem()');
+ localStorage.setItem(key, value);
+ },
+ /**
* Fetches the number of values in local storage
* @returns {number}
*/
- lls_getCount: function () {
- console.log('cave.lls_getCount()');
- return localStorage.length;
- },
- /**
+ lls_getCount: function () {
+ console.log('cave.lls_getCount()');
+ return localStorage.length;
+ },
+ /**
* Fetches value for key from local storage
* @param key
* @returns {string}
*/
- lls_getItem: function (key) {
- console.log('cave.lls_getItem()');
- return localStorage.getItem(key);
- },
- /**
+ lls_getItem: function (key) {
+ console.log('cave.lls_getItem()');
+ return localStorage.getItem(key);
+ },
+ /**
* Removes value for key from local storage
* @param key
*/
- lls_removeItem: function (key) {
- console.log('cave.lls_removeItem()');
- return localStorage.removeItem(key);
- },
- /**
+ lls_removeItem: function (key) {
+ console.log('cave.lls_removeItem()');
+ return localStorage.removeItem(key);
+ },
+ /**
* Returns if key 'custk' has value '1'
* @returns {boolean}
*/
- ls_canUseCachedServiceToken: function () {
- console.log('cave.ls_canUseCachedServiceToken()');
- return sessionStorage.getItem('custk') === '1' ? true : false;
- },
- /**
+ ls_canUseCachedServiceToken: function () {
+ console.log('cave.ls_canUseCachedServiceToken()');
+ return sessionStorage.getItem('custk') === '1' ? true : false;
+ },
+ /**
* Sets 'custk' key to specified value
* @param can_use
*/
- ls_setCanUseCachedServiceToken: function (can_use) {
- console.log('cave.ls_setCanUseCachedServiceToken');
- var flag = can_use ? '1' : '0';
- sessionStorage.setItem('custk', flag);
- },
- /**
+ ls_setCanUseCachedServiceToken: function (can_use) {
+ console.log('cave.ls_setCanUseCachedServiceToken');
+ const flag = can_use ? '1' : '0';
+ sessionStorage.setItem('custk', flag);
+ },
+ /**
* Shows a dialog box with one button
* @param title
* @param message
* @param button_text
* @returns {number}
*/
- dialog_oneButton: function (title, message, button_text) {
- console.log('cave.dialog_oneButton()');
- alert("タイトル:" + title + "\n" + "メッセージ:" + message + "\n\n[ " + button_text + " ]");
- return 0;
- },
- /**
+ dialog_oneButton: function (title, message, button_text) {
+ console.log('cave.dialog_oneButton()');
+ alert('タイトル:' + title + '\n' + 'メッセージ:' + message + '\n\n[ ' + button_text + ' ]');
+ return 0;
+ },
+ /**
* Returns key at specified index
* @param index
* @returns {string}
*/
- lls_getKeyAt: function (index) {
- console.log('cave.lls_getKeyAt index = ' + index);
- return localStorage.key(index);
- },
- /**
+ lls_getKeyAt: function (index) {
+ console.log('cave.lls_getKeyAt index = ' + index);
+ return localStorage.key(index);
+ },
+ /**
* Returns B64 encoded user Mii image with requested expression
* @param expression {number} 0-5
* @returns {string}
*/
- mii_getIconBase64: function (expression) {
- console.log('cave.mii_getIconBase64 expression = ' + expression);
- // 本来表情毎に出し分けるべきだが、とりあえず固定のものを出す
- // Originally, it should be displayed separately for each expression, but for the time being, a fixed one should be displayed
- return 'data:image/png;base64,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';
- },
- /**
+ mii_getIconBase64: function (expression) {
+ console.log('cave.mii_getIconBase64 expression = ' + expression);
+ // 本来表情毎に出し分けるべきだが、とりあえず固定のものを出す
+ // Originally, it should be displayed separately for each expression, but for the time being, a fixed one should be displayed
+ return 'data:image/png;base64,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';
+ },
+ /**
* Returns name of user Mii
* @returns {string}
*/
- mii_getName: function () {
- console.log('cave.mii_getName');
- return 'chris4403';
- },
- /**
+ mii_getName: function () {
+ console.log('cave.mii_getName');
+ return 'chris4403';
+ },
+ /**
* Shows a dialog box with two buttons
* @param title
* @param message
@@ -279,60 +280,60 @@ if (typeof cave === "undefined") {
* @param buttonR_text
* @returns {number}
*/
- dialog_twoButton: function (title, message, buttonL_text, buttonR_text) {
- console.log('cave.dialog_twoButton()');
- var result = confirm("タイトル:" + title + "\n" + "メッセージ:" + message + "\n\n[ " + buttonL_text + " (Cancel) ] [ " + buttonR_text + " (OK) ]");
- return result ? 1 : 0;
- },
+ dialog_twoButton: function (title, message, buttonL_text, buttonR_text) {
+ console.log('cave.dialog_twoButton()');
+ const result = confirm('タイトル:' + title + '\n' + 'メッセージ:' + message + '\n\n[ ' + buttonL_text + ' (Cancel) ] [ ' + buttonR_text + ' (OK) ]');
+ return result ? 1 : 0;
+ },
- brw_scrollImmediately: function (posX, posY) {
- console.log('cave.brw_scrollImmediately(posX=' + posX + ', posY=' + posY + ')');
- window.scroll(posX, posY);
- },
+ brw_scrollImmediately: function (posX, posY) {
+ console.log('cave.brw_scrollImmediately(posX=' + posX + ', posY=' + posY + ')');
+ window.scroll(posX, posY);
+ },
- brw_getScrollTopX: function () {
- console.log('cave.brw_getScrollTopX()');
- return window.pageXOffset;
- },
+ brw_getScrollTopX: function () {
+ console.log('cave.brw_getScrollTopX()');
+ return window.pageXOffset;
+ },
- brw_getScrollTopY: function () {
- console.log('cave.brw_getScrollTopY()');
- return window.pageYOffset;
- },
+ brw_getScrollTopY: function () {
+ console.log('cave.brw_getScrollTopY()');
+ return window.pageYOffset;
+ },
- brw_notifyPageMoving: function () {
- console.log('cave.brw_notifyPageMoving()');
- },
+ brw_notifyPageMoving: function () {
+ console.log('cave.brw_notifyPageMoving()');
+ },
- requestGc: function () {
- console.log('requestGc');
- },
- /**
+ requestGc: function () {
+ console.log('requestGc');
+ },
+ /**
* Exits the app
*/
- exitApp: function () {
- console.log('cave.exitApp()');
- },
- /**
+ exitApp: function () {
+ console.log('cave.exitApp()');
+ },
+ /**
* Returns a JSON string, containing app IDs
* @param minutes
* @returns {string}
*/
- plog_getPlayTitlesFilteredByPlayTime: function (minutes) {
- console.log('cave.plog_getPlayTitlesFilteredByPlayTime(' + minutes + ')');
- return '{"IDs":["0004001000020700"]}'; // Miiスタジオ (Mii studio)
- },
- /**
+ plog_getPlayTitlesFilteredByPlayTime: function (minutes) {
+ console.log('cave.plog_getPlayTitlesFilteredByPlayTime(' + minutes + ')');
+ return '{"IDs":["0004001000020700"]}'; // Miiスタジオ (Mii studio)
+ },
+ /**
* Jumps to user account settings
*/
- jump_toAccount: function () {
- console.log('cave.jump_toAccount()');
- },
- /**
+ jump_toAccount: function () {
+ console.log('cave.jump_toAccount()');
+ },
+ /**
* play (predefined) sound effect
* @param label
*/
- /* Values:
+ /* Values:
SE_OLV_CANCEL
SE_OLV_OK
SE_OLV_OK_SUB
@@ -391,14 +392,14 @@ if (typeof cave === "undefined") {
SE_CTR_SPIDER_InfoOn
SE_CTR_SPIDER_SEL_END
*/
- snd_playSe: function (label) {
- console.log('cave.snd_playSe(' + label + ')');
- },
- /**
+ snd_playSe: function (label) {
+ console.log('cave.snd_playSe(' + label + ')');
+ },
+ /**
* Play (predefined) background music
* @param label
*/
- /* Values:
+ /* Values:
BGM_ACCOUNT_OP
BGM_CAVE_MAIN
BGM_CAVE_MAIN_LOOP
@@ -410,313 +411,317 @@ if (typeof cave === "undefined") {
BGM_CAVE_SYOKAI
BGM_CAVE_SYOKAI2
*/
- snd_playBgm: function (label) {
- console.log('cave.snd_playBgm(' + label + ')');
- },
- /**
+ snd_playBgm: function (label) {
+ console.log('cave.snd_playBgm(' + label + ')');
+ },
+ /**
* Checks if suspended application is running
* @returns {boolean}
*/
- sap_exists: function () {
- console.log('cave.sap_exists()');
- return false;
- },
- /**
+ sap_exists: function () {
+ console.log('cave.sap_exists()');
+ return false;
+ },
+ /**
* Fetches the program ID for the suspended application
* @returns {undefined}
*/
- sap_programId: function () {
- console.log('cave.sap_programId()');
- return undefined;
- },
- /**
+ sap_programId: function () {
+ console.log('cave.sap_programId()');
+ return undefined;
+ },
+ /**
* Captures the lower screen of the suspended app. Returns as a base64 encoded image (todo: clarify format).
*/
- capture_getLowerImage: function () {
- console.log('cave.capture_getLowerImage()');
- },
- /**
+ capture_getLowerImage: function () {
+ console.log('cave.capture_getLowerImage()');
+ },
+ /**
* Captures the left-eye image from the upper screen of the suspended app. Returns as a base64 encoded image (todo: clarify format).
*/
- capture_getUpperImageLeft: function () {
- console.log('cave.capture_getUpperImageLeft()');
- },
- /**
+ capture_getUpperImageLeft: function () {
+ console.log('cave.capture_getUpperImageLeft()');
+ },
+ /**
* Captures the right-eye image from the upper screen of the suspended app. Returns as a base64 encoded image (todo: clarify format)
*/
- capture_getUpperImageRight: function () {
- console.log('cave.capture_getUpperImageRight()');
- },
- /**
+ capture_getUpperImageRight: function () {
+ console.log('cave.capture_getUpperImageRight()');
+ },
+ /**
* (untested) Presumably captures both left and right images from the top screen.
*/
- capture_getUpperImage3D: function () {
- console.log('cave.capture_getUpperImage3D()');
- },
- /**
+ capture_getUpperImage3D: function () {
+ console.log('cave.capture_getUpperImage3D()');
+ },
+ /**
* More advanced version of capture_getUpperImage3D that allows for customisation.
* @param width
* @param height
* @param quality
* @param format
*/
- capture_getLowerImageDetail: function (width, height, quality, format) {
- console.log('cave.capture_getLowerImageDetail(' +
+ capture_getLowerImageDetail: function (width, height, quality, format) {
+ console.log('cave.capture_getLowerImageDetail(' +
[width, height, quality, format].join(', ')
+ ')');
- },
- /**
+ },
+ /**
* More advanced version of capture_getUpperImageLeft that allows for customisation.
* @param width
* @param height
* @param quality
* @param format
*/
- capture_getUpperImageLeftDetail: function (width, height, quality, format) {
- console.log('cave.capture_getUpperImageLeftDetail(' +
+ capture_getUpperImageLeftDetail: function (width, height, quality, format) {
+ console.log('cave.capture_getUpperImageLeftDetail(' +
[width, height, quality, format].join(', ')
+ ')');
- },
- /**
+ },
+ /**
* More advanced version of capture_getUpperImageRight that allows for customisation.
* @param width
* @param height
* @param quality
* @param format
*/
- capture_getUpperImageRightDetail: function (width, height, quality, format) {
- console.log('cave.capture_getUpperImageRightDetail(' +
+ capture_getUpperImageRightDetail: function (width, height, quality, format) {
+ console.log('cave.capture_getUpperImageRightDetail(' +
[width, height, quality, format].join(', ')
+ ')');
- },
- /**
+ },
+ /**
* More advanced version of capture_getUpperImage3D that allows for customisation.
* @param width
* @param height
* @param quality
* @param format
*/
- capture_getUpperImage3DDetail: function (width, height, quality, format) {
- console.log('cave.capture_getUpperImage3DDetail(' +
+ capture_getUpperImage3DDetail: function (width, height, quality, format) {
+ console.log('cave.capture_getUpperImage3DDetail(' +
[width, height, quality, format].join(', ')
+ ')');
- },
- /**
+ },
+ /**
* Unknown
*/
- capture_notifyUpdatedLocalList: function () {
- console.log('cave.capture_notifyUpdatedLocalList()');
- },
- /**
+ capture_notifyUpdatedLocalList: function () {
+ console.log('cave.capture_notifyUpdatedLocalList()');
+ },
+ /**
* Check if the suspended software allows screenshots.
* @returns {boolean}
*/
- capture_isEnabled: function () {
- console.log('cave.capture_isEnabled()');
- return false;
- },
- /**
+ capture_isEnabled: function () {
+ console.log('cave.capture_isEnabled()');
+ return false;
+ },
+ /**
* Same as capture_isEnabled, but instead checks the capture status of a single screen. Set screenIndex to 0 to check the top screen, or 1 to check the lower screen.
* @param screen
* @returns {boolean|boolean}
*/
- capture_isEnabledEx: function (screen) {
- console.log('cave.capture_isEnabledEx(' + screen + ')');
+ capture_isEnabledEx: function (screen) {
+ console.log('cave.capture_isEnabledEx(' + screen + ')');
- // テスト等でスクショの有無を固定したい場合にクッキーで指定できるようにする, 実機ではこの挙動は存在しない
- // If you want to fix the presence or absence of screenshots in tests, etc., make it possible to specify with cookies, this behavior does not exist on the actual device
- var force = Olv.Cookie.get('force_screenshot_for_test');
- if (force === 'true') return true;
- if (force === 'false') return false;
+ // テスト等でスクショの有無を固定したい場合にクッキーで指定できるようにする, 実機ではこの挙動は存在しない
+ // If you want to fix the presence or absence of screenshots in tests, etc., make it possible to specify with cookies, this behavior does not exist on the actual device
+ const force = Olv.Cookie.get('force_screenshot_for_test');
+ if (force === 'true') {
+ return true;
+ }
+ if (force === 'false') {
+ return false;
+ }
- return Math.random() >= 0.5 ? true : false;
- },
+ return Math.random() >= 0.5 ? true : false;
+ },
- boss_regist: function (interval_hour) {
- console.log('cave.boss_regist(' + interval_hour + ')');
- return true;
- },
- boss_registEx: function (interval_hour, count) {
- console.log('cave.boss_regist(' + interval_hour + ',' + count + ')');
- return true;
- },
+ boss_regist: function (interval_hour) {
+ console.log('cave.boss_regist(' + interval_hour + ')');
+ return true;
+ },
+ boss_registEx: function (interval_hour, count) {
+ console.log('cave.boss_regist(' + interval_hour + ',' + count + ')');
+ return true;
+ },
- boss_unregist: function () {
- console.log('cave.boss_unregist()');
- },
+ boss_unregist: function () {
+ console.log('cave.boss_unregist()');
+ },
- boss_isRegisted: function () {
- console.log('cave.boss_isRegisted()');
- return true;
- },
+ boss_isRegisted: function () {
+ console.log('cave.boss_isRegisted()');
+ return true;
+ },
- boss_clearNewArrival: function () {
- console.log('cave.boss_clearNewArrival()');
- },
- lls_clear: function () {
- console.log('cave.lls_clear()');
- localStorage.clear();
- },
- lls_setCaptureImage: function (key, value) {
- console.log('cave.setCaptureImage(' + [key, value].join(', ') + ')');
- localStorage.setItem(key, value);
- return 0;
- },
- lls_getPath: function (key) {
- console.log('cave.getPath(' + key + ')');
- var value = localStorage.getItem(key);
- if (value == 0) {
- return '/img/dummy-image/screenshot-dummy-3ds-low.jpeg';
- } else {
- return '/img/dummy-image/screenshot-dummy-3ds-upper.jpeg';
- }
- },
- /**
+ boss_clearNewArrival: function () {
+ console.log('cave.boss_clearNewArrival()');
+ },
+ lls_clear: function () {
+ console.log('cave.lls_clear()');
+ localStorage.clear();
+ },
+ lls_setCaptureImage: function (key, value) {
+ console.log('cave.setCaptureImage(' + [key, value].join(', ') + ')');
+ localStorage.setItem(key, value);
+ return 0;
+ },
+ lls_getPath: function (key) {
+ console.log('cave.getPath(' + key + ')');
+ const value = localStorage.getItem(key);
+ if (value == 0) {
+ return '/img/dummy-image/screenshot-dummy-3ds-low.jpeg';
+ } else {
+ return '/img/dummy-image/screenshot-dummy-3ds-upper.jpeg';
+ }
+ },
+ /**
* Fetches history from previoys
* @returns {string}
*/
- history_getPrev: function () {
- console.log('cave.history_getPrev()');
- // 直前の履歴項目の URL を返す API だが、
- // とりあえずは referrer で代用しておく。
- // An API that returns the URL of the previous history item, but
- // Substitute with referrer for the time being.
- return document.referrer;
- },
- /**
+ history_getPrev: function () {
+ console.log('cave.history_getPrev()');
+ // 直前の履歴項目の URL を返す API だが、
+ // とりあえずは referrer で代用しておく。
+ // An API that returns the URL of the previous history item, but
+ // Substitute with referrer for the time being.
+ return document.referrer;
+ },
+ /**
* Removes previous entry from history
*/
- history_removePrev: function () {
- console.log('cave.history_removePrev()');
- },
- /**
+ history_removePrev: function () {
+ console.log('cave.history_removePrev()');
+ },
+ /**
* Fetches URL at provided index
* @param backIndex
* @returns {string}
*/
- history_getAt: function (backIndex) {
- console.log('cave.history_getAt(' + backIndex + ')');
- return '';
- },
- /**
+ history_getAt: function (backIndex) {
+ console.log('cave.history_getAt(' + backIndex + ')');
+ return '';
+ },
+ /**
* Removes history at provided index
* @param backIndex
*/
- history_removeAt: function (backIndex) {
- console.log('cave.history_removeAt(' + backIndex + ')');
- },
- /**
+ history_removeAt: function (backIndex) {
+ console.log('cave.history_removeAt(' + backIndex + ')');
+ },
+ /**
* Determines if browser can navigate back
* @returns {number}
*/
- history_getBackCount: function () {
- console.log('cave.history_getBackCount()');
- // 戻ることのできるページ数を返すAPIだが、
- // とりあえずは referrer で代用しておく。
- // API that returns the number of pages that can be returned,
- // Substitute with referrer for the time being.
- return !!document.referrer ? 1 : 0;
- },
+ history_getBackCount: function () {
+ console.log('cave.history_getBackCount()');
+ // 戻ることのできるページ数を返すAPIだが、
+ // とりあえずは referrer で代用しておく。
+ // API that returns the number of pages that can be returned,
+ // Substitute with referrer for the time being.
+ return document.referrer ? 1 : 0;
+ },
- toolbar_setMode: function (mode) {
- console.log('cave.toolbar_setMode(' + mode + ')');
- },
- toolbar_setWideButtonMessage: function (message) {
- console.log('cave.toolbar_setWideButtonMessage(' + message + ')')
- },
- jump_existsWebbrs: function () {
- console.log('jump_existsWebbrs()');
- return true;
- },
- jump_toSystemUpdate: function (type) {
- console.log('jump_toSystemUpdate(' + type + ')')
- },
- jump_toWebbrs: function (url) {
- console.log('cave.jump_toWebbrs(' + url + ')');
- window.location.href = url;
- return true;
- },
- jump_toShop: function (dialog, titleId) {
- console.log('cave.jump_toShop(' + dialog + ', ' + titleId + ')');
- return true;
- },
- jump_getYoutubeVersion: function () {
- console.log('cave.jump_getYoutubeVersion()');
- return -1;
- },
- jump_suspendedToutube: function (query) {
- console.log('cave.jump_suspendedToutube(' + query + ')');
- return 1;
- },
- jump_toYoutube: function (dialog, query) {
- console.log('cave.jump_toYoutube(' + dialog + ', ' + query + ')');
- return 1;
- },
- jump_existsApplication: function (titleId) {
- console.log('jump_existsApplication(' + titleId + ')');
- return true;
- },
- jump_resetParamToApp: function () {
- console.log('jump_resetParamToApp');
- },
- jump_canUseQuery: function (titleId) {
- console.log('jump_canUseQuery(' + titleId + ')');
- return true;
- },
- jump_setModeToApp: function (mode) {
- console.log('jump_setModeToApp(' + mode + ')');
- },
- jump_setDataUTF8ToApp: function (type, data) {
- console.log('jump_setDataUTF8ToApp(' + type + ', ' + data + ')');
- },
- jump_setNumberDataToApp: function (type, data) {
- console.log('jump_setNumberDataToApp(' + type + ', ' + data + ')');
- },
- jump_setBase64DataToApp: function (type, data) {
- console.log('jump_setBase64DataToApp(' + type + ', ' + data + ')');
- },
- jump_toApplication: function (dialog, titleId) {
- console.log('cave.jump_toApplication(' + dialog + ', ' + titleId + ')');
- return true;
- },
- convertTimeToString: function (unixTime) {
- console.log('cave.convertTimeToString(' + unixTime + ')');
- var date = new Date(unixTime * 1000);
- return date.getFullYear() + '-' + this._toDoubleDigits(date.getMonth() + 1) + '-' + this._toDoubleDigits(date.getDate())
+ toolbar_setMode: function (mode) {
+ console.log('cave.toolbar_setMode(' + mode + ')');
+ },
+ toolbar_setWideButtonMessage: function (message) {
+ console.log('cave.toolbar_setWideButtonMessage(' + message + ')');
+ },
+ jump_existsWebbrs: function () {
+ console.log('jump_existsWebbrs()');
+ return true;
+ },
+ jump_toSystemUpdate: function (type) {
+ console.log('jump_toSystemUpdate(' + type + ')');
+ },
+ jump_toWebbrs: function (url) {
+ console.log('cave.jump_toWebbrs(' + url + ')');
+ window.location.href = url;
+ return true;
+ },
+ jump_toShop: function (dialog, titleId) {
+ console.log('cave.jump_toShop(' + dialog + ', ' + titleId + ')');
+ return true;
+ },
+ jump_getYoutubeVersion: function () {
+ console.log('cave.jump_getYoutubeVersion()');
+ return -1;
+ },
+ jump_suspendedToutube: function (query) {
+ console.log('cave.jump_suspendedToutube(' + query + ')');
+ return 1;
+ },
+ jump_toYoutube: function (dialog, query) {
+ console.log('cave.jump_toYoutube(' + dialog + ', ' + query + ')');
+ return 1;
+ },
+ jump_existsApplication: function (titleId) {
+ console.log('jump_existsApplication(' + titleId + ')');
+ return true;
+ },
+ jump_resetParamToApp: function () {
+ console.log('jump_resetParamToApp');
+ },
+ jump_canUseQuery: function (titleId) {
+ console.log('jump_canUseQuery(' + titleId + ')');
+ return true;
+ },
+ jump_setModeToApp: function (mode) {
+ console.log('jump_setModeToApp(' + mode + ')');
+ },
+ jump_setDataUTF8ToApp: function (type, data) {
+ console.log('jump_setDataUTF8ToApp(' + type + ', ' + data + ')');
+ },
+ jump_setNumberDataToApp: function (type, data) {
+ console.log('jump_setNumberDataToApp(' + type + ', ' + data + ')');
+ },
+ jump_setBase64DataToApp: function (type, data) {
+ console.log('jump_setBase64DataToApp(' + type + ', ' + data + ')');
+ },
+ jump_toApplication: function (dialog, titleId) {
+ console.log('cave.jump_toApplication(' + dialog + ', ' + titleId + ')');
+ return true;
+ },
+ convertTimeToString: function (unixTime) {
+ console.log('cave.convertTimeToString(' + unixTime + ')');
+ const date = new Date(unixTime * 1000);
+ return date.getFullYear() + '-' + this._toDoubleDigits(date.getMonth() + 1) + '-' + this._toDoubleDigits(date.getDate())
+ ' ' + this._toDoubleDigits(date.getHours()) + ':' + this._toDoubleDigits(date.getMinutes()) + ':' + this._toDoubleDigits(date.getSeconds());
- },
- _toDoubleDigits: function (num) {
- num += "";
- if (num.length === 1) {
- num = "0" + num;
- }
- return num;
- },
- getLocalTimeSeconds: function () {
- console.log('cave.getLocalTimeSeconds()');
- return parseInt(new Date().getTime() / 1000);
- },
- effect_scrollGuide: function (flag) {
- console.log('cave.effect_scrollGuide( ' + flag + ' )');
- },
- effect_setScrollGuideOffsetPos: function (x, y) {
- console.log('effect_setScrollGuideOffsetPos( x = ' + x + ', y = ' + ' )');
- },
- // キーボードアプレットに入力した文字列が返り値になるので window.prompt でエミュレートする
- // Since the string entered in the keyboard applet will be the return value, emulate it with window.prompt
- swkbd_callFullKeyboard: function (text, maxLength, minLength, isMonospace, isMultiline, isConvertible) {
- console.log('cave.callFullKeyboard( ' + Array.prototype.join.call(arguments, ', ') + ' )');
- return window.prompt('cave.callFullKeyboard', text);
- },
- swkbd_callFullKeyboardWithGuide: function (text, maxLength, minLength, isMonospace, isMultiline, isConvertible, guide) {
- console.log('cave.callFullKeyboardWithGuide( ' + Array.prototype.join.call(arguments, ', ') + ' )');
- return window.prompt('cave.callFullKeyboardWithGuide [' + guide + ']', text);
- },
- viewer_setOnCloseCallback: function (callback) {
- console.log('cave.viewer_setOnCloseCallback(callback = ' + typeof callback + ')');
- },
- home_setEnabled: function (flag) {
- console.log('cave.home_setEnabled', flag);
- },
- };
+ },
+ _toDoubleDigits: function (num) {
+ num += '';
+ if (num.length === 1) {
+ num = '0' + num;
+ }
+ return num;
+ },
+ getLocalTimeSeconds: function () {
+ console.log('cave.getLocalTimeSeconds()');
+ return parseInt(new Date().getTime() / 1000);
+ },
+ effect_scrollGuide: function (flag) {
+ console.log('cave.effect_scrollGuide( ' + flag + ' )');
+ },
+ effect_setScrollGuideOffsetPos: function (x, y) {
+ console.log('effect_setScrollGuideOffsetPos( x = ' + x + ', y = ' + ' )');
+ },
+ // キーボードアプレットに入力した文字列が返り値になるので window.prompt でエミュレートする
+ // Since the string entered in the keyboard applet will be the return value, emulate it with window.prompt
+ swkbd_callFullKeyboard: function (text, maxLength, minLength, isMonospace, isMultiline, isConvertible) {
+ console.log('cave.callFullKeyboard( ' + Array.prototype.join.call(arguments, ', ') + ' )');
+ return window.prompt('cave.callFullKeyboard', text);
+ },
+ swkbd_callFullKeyboardWithGuide: function (text, maxLength, minLength, isMonospace, isMultiline, isConvertible, guide) {
+ console.log('cave.callFullKeyboardWithGuide( ' + Array.prototype.join.call(arguments, ', ') + ' )');
+ return window.prompt('cave.callFullKeyboardWithGuide [' + guide + ']', text);
+ },
+ viewer_setOnCloseCallback: function (callback) {
+ console.log('cave.viewer_setOnCloseCallback(callback = ' + typeof callback + ')');
+ },
+ home_setEnabled: function (flag) {
+ console.log('cave.home_setEnabled', flag);
+ },
+ };
}
\ No newline at end of file
diff --git a/src/webfiles/ctr/js/pjax.js b/src/webfiles/ctr/js/pjax.js
index 1cfc024..4f0dec2 100644
--- a/src/webfiles/ctr/js/pjax.js
+++ b/src/webfiles/ctr/js/pjax.js
@@ -1,84 +1,94 @@
var Pjax = {
- elements: null,
- selectors: null,
- href: null,
- history: [],
- events: {
- PjaxRequest: document.createEvent('Event'),
- PjaxLoaded: document.createEvent('Event'),
- PjaxDone: document.createEvent('Event')
- },
- init: function(init) {
- this.elements = init.elements;
- this.selectors = init.selectors;
- this.href = document.location.href;
+ elements: null,
+ selectors: null,
+ href: null,
+ history: [],
+ events: {
+ PjaxRequest: document.createEvent('Event'),
+ PjaxLoaded: document.createEvent('Event'),
+ PjaxDone: document.createEvent('Event')
+ },
+ init: function(init) {
+ this.elements = init.elements;
+ this.selectors = init.selectors;
+ this.href = document.location.href;
- this.events.PjaxRequest.initEvent('PjaxRequest', true, true);
- this.events.PjaxLoaded.initEvent('PjaxLoaded', true, true);
- this.events.PjaxDone.initEvent('PjaxDone', true, true);
+ this.events.PjaxRequest.initEvent('PjaxRequest', true, true);
+ this.events.PjaxLoaded.initEvent('PjaxLoaded', true, true);
+ this.events.PjaxDone.initEvent('PjaxDone', true, true);
- return this;
- },
- refresh: function() {
- var els = document.querySelectorAll(this.elements);
- if (!els) return;
- console.log(this.elements);
- console.log(els);
- for (var i = 0; i < els.length; i++) {
- els[i].addEventListener("click", function (e) { pageWrapper(e, this) });
- }
- },
- loadUrl: function (url, push) {
- if(!this.elements || !this.selectors) return;
- document.dispatchEvent(Pjax.events.PjaxRequest);
- this.get(url, this.parseDom);
- if(!push && Pjax.href.indexOf(url) === -1)
- Pjax.history.push(Pjax.href);
- console.log(url)
- },
- get: function(url, callback) {
- var xhttp = new XMLHttpRequest();
- xhttp.onreadystatechange = function() {
- if(this.readyState === 4) {
- document.dispatchEvent(Pjax.events.PjaxLoaded);
- this.responseURL = url;
- return callback(this);
- }
- };
- xhttp.open("GET", url, true);
- xhttp.send();
- },
- parseDom: function(data) {
- var response = data.responseText;
- if(response && data.status === 200) {
- var html = document.implementation.createHTMLDocument('');
- html.documentElement.innerHTML = response;
- for(var i = 0; i < Pjax.selectors.length; i++) {
- var newElement = html.querySelector(Pjax.selectors[i]);
- var oldElement = document.querySelector(Pjax.selectors[i]);
- if(!newElement || !oldElement) continue;
- oldElement.outerHTML = newElement.outerHTML;
- }
- console.log(data);
- Pjax.refresh();
- Pjax.href = data.responseURL;
- document.dispatchEvent(Pjax.events.PjaxDone);
- }
- },
- canGoBack: function() {
- return this.history.length >= 1;
- },
- back: function() {
- if(!this.canGoBack())
- return;
- var url = this.history.pop();
- this.loadUrl(url, true);
+ return this;
+ },
+ refresh: function() {
+ const els = document.querySelectorAll(this.elements);
+ if (!els) {
+ return;
+ }
+ console.log(this.elements);
+ console.log(els);
+ for (let i = 0; i < els.length; i++) {
+ els[i].addEventListener('click', function (e) {
+ pageWrapper(e, this);
+ });
+ }
+ },
+ loadUrl: function (url, push) {
+ if (!this.elements || !this.selectors) {
+ return;
+ }
+ document.dispatchEvent(Pjax.events.PjaxRequest);
+ this.get(url, this.parseDom);
+ if (!push && Pjax.href.indexOf(url) === -1) {
+ Pjax.history.push(Pjax.href);
+ }
+ console.log(url);
+ },
+ get: function(url, callback) {
+ const xhttp = new XMLHttpRequest();
+ xhttp.onreadystatechange = function() {
+ if (this.readyState === 4) {
+ document.dispatchEvent(Pjax.events.PjaxLoaded);
+ this.responseURL = url;
+ return callback(this);
+ }
+ };
+ xhttp.open('GET', url, true);
+ xhttp.send();
+ },
+ parseDom: function(data) {
+ const response = data.responseText;
+ if (response && data.status === 200) {
+ const html = document.implementation.createHTMLDocument('');
+ html.documentElement.innerHTML = response;
+ for (let i = 0; i < Pjax.selectors.length; i++) {
+ const newElement = html.querySelector(Pjax.selectors[i]);
+ const oldElement = document.querySelector(Pjax.selectors[i]);
+ if (!newElement || !oldElement) {
+ continue;
+ }
+ oldElement.outerHTML = newElement.outerHTML;
+ }
+ console.log(data);
+ Pjax.refresh();
+ Pjax.href = data.responseURL;
+ document.dispatchEvent(Pjax.events.PjaxDone);
+ }
+ },
+ canGoBack: function() {
+ return this.history.length >= 1;
+ },
+ back: function() {
+ if (!this.canGoBack()) {
+ return;
+ }
+ const url = this.history.pop();
+ this.loadUrl(url, true);
- }
-}
+ }
+};
function pageWrapper(e, element) {
- e.preventDefault();
- Pjax.loadUrl(element.href);
- return false;
+ e.preventDefault();
+ Pjax.loadUrl(element.href);
+ return false;
}
\ No newline at end of file
diff --git a/src/webfiles/portal/js/debug.js b/src/webfiles/portal/js/debug.js
index 8412231..9c1ef2a 100644
--- a/src/webfiles/portal/js/debug.js
+++ b/src/webfiles/portal/js/debug.js
@@ -1,311 +1,325 @@
/*Debugging*/
if (typeof wiiu === 'undefined') {
- window.wiiu = {
- gamepad: {
- update: function () {
- return true;
- },
- hold: 0
- }
- };
+ window.wiiu = {
+ gamepad: {
+ update: function () {
+ return true;
+ },
+ hold: 0
+ }
+ };
}
// ローカル開発用に 各独自 API をエミュレート
// Emulate each proprietary API for local development
if (typeof wiiuBrowser === 'undefined') {
- window.wiiuBrowser = {
- closeApplication: function () {
- alert('アプリケーションは終了しました');
- },
- showLoadingIcon: function (show) {
- console.debug((show ? 'Show' : 'Hide') + ' loading icon');
- },
- endStartUp: function () {
- console.debug('endStartUp');
- },
- lockUserOperation: function (lock) {
- console.debug((lock ? 'Lock' : 'Unlock') + ' user operations');
- },
- lockHomeButtonMenu: function (lock) {
- console.debug((lock ? 'Lock' : 'Unlock') + ' home button menu');
- },
- canHistoryBack: function () {
- // とりあえずトップページなら履歴を戻れないということにしておく。
- return location.pathname !== '/';
- },
- setSwkbdDictionary: function (jsonString) {
- console.debug('Set SWKBD dictionary', JSON.parse(jsonString));
- return (Math.random() < 0.5)
- ? {} : { error: { code: 111222, message: 'Test Error Message' } };
- },
- openTvAreaSetting: function () {
- alert('Tv側の安全フレーム設定画面を開きました');
- },
- jumpToBrowser: function (url) {
- console.debug(url);
- },
- jumpToEshop: function (query) {
- console.debug(query);
- },
- jumpToApplication: function(titleId, flags, communityId, appData, postId) {
- console.debug(titleId);
- }
- };
+ window.wiiuBrowser = {
+ closeApplication: function () {
+ alert('アプリケーションは終了しました');
+ },
+ showLoadingIcon: function (show) {
+ console.debug((show ? 'Show' : 'Hide') + ' loading icon');
+ },
+ endStartUp: function () {
+ console.debug('endStartUp');
+ },
+ lockUserOperation: function (lock) {
+ console.debug((lock ? 'Lock' : 'Unlock') + ' user operations');
+ },
+ lockHomeButtonMenu: function (lock) {
+ console.debug((lock ? 'Lock' : 'Unlock') + ' home button menu');
+ },
+ canHistoryBack: function () {
+ // とりあえずトップページなら履歴を戻れないということにしておく。
+ return location.pathname !== '/';
+ },
+ setSwkbdDictionary: function (jsonString) {
+ console.debug('Set SWKBD dictionary', JSON.parse(jsonString));
+ return (Math.random() < 0.5)
+ ? {} : { error: { code: 111222, message: 'Test Error Message' } };
+ },
+ openTvAreaSetting: function () {
+ alert('Tv側の安全フレーム設定画面を開きました');
+ },
+ jumpToBrowser: function (url) {
+ console.debug(url);
+ },
+ jumpToEshop: function (query) {
+ console.debug(query);
+ },
+ jumpToApplication: function(titleId, flags, communityId, appData, postId) {
+ console.debug(titleId);
+ }
+ };
}
if (typeof wiiuDialog === 'undefined') {
- window.wiiuDialog = {
- alert: function (msg, btnStr) {
- alert(msg + "\n\n[ " + btnStr + " ]");
- },
- confirm: function (msg, lBtnStr, rBtnStr) {
- return confirm(msg + "\n\n[ " + lBtnStr + " (Cancel) ] [ " + rBtnStr + " (OK) ]");
- }
- };
+ window.wiiuDialog = {
+ alert: function (msg, btnStr) {
+ alert(msg + '\n\n[ ' + btnStr + ' ]');
+ },
+ confirm: function (msg, lBtnStr, rBtnStr) {
+ return confirm(msg + '\n\n[ ' + lBtnStr + ' (Cancel) ] [ ' + rBtnStr + ' (OK) ]');
+ }
+ };
}
if (typeof wiiuSound === 'undefined') {
- window.wiiuSound = {
- playSound: function (soundId, device) {
- this.playSoundByName('id ' + soundId, device);
- },
- playSoundByName: function (name, device) {
- console.debug('Play sound ' + name);
- }
- };
+ window.wiiuSound = {
+ playSound: function (soundId, device) {
+ this.playSoundByName('id ' + soundId, device);
+ },
+ playSoundByName: function (name, device) {
+ console.debug('Play sound ' + name);
+ }
+ };
}
if (typeof wiiuDevice === 'undefined') {
- window.wiiuDevice = {
- isDrc: function () {
- return true;
- },
- getSKU: function () {
- return Math.random() < 7 / 8
- ? { amount: 31205621760 }
- : { error: { code: 1112222, message: "Test Error Message" } };
- },
- existsTitle: function () {
- return Math.random() < 1 / 2;
- }
- };
+ window.wiiuDevice = {
+ isDrc: function () {
+ return true;
+ },
+ getSKU: function () {
+ return Math.random() < 7 / 8
+ ? { amount: 31205621760 }
+ : { error: { code: 1112222, message: 'Test Error Message' } };
+ },
+ existsTitle: function () {
+ return Math.random() < 1 / 2;
+ }
+ };
}
if (typeof wiiuSystemSetting === 'undefined') {
- window.wiiuSystemSetting = {
- checkParentalPinCode: function (code) {
- console.debug(code);
- return Math.random() < 0.5 ? {result: true} :{
- error : {
- code : 1112222,
- message : "Test Error Message"
- }
- };
- },
- getRegion: function () {
- return Math.random() < 0.5 ? {
- code: 'JPN'
- } : {
- error: {
- code : 1112222,
- message : "Test Error Message"
- }
- };
- },
- getCountry: function () {
- return Math.random() < 0.5 ? {
- code: 'JP'
- } : {
- error: {
- code : 1112222,
- message : "Test Error Message"
- }
- };
- },
- getLanguage: function () {
- return Math.random() < 0.5 ? {
- code: 'ja'
- } : {
- error: {
- code : 1112222,
- message : "Test Error Message"
- }
- };
- },
- getSpotPassUploadConsoleInfoState: function () {
- return { enable: Math.random() < 0.5 };
- },
- };
+ window.wiiuSystemSetting = {
+ checkParentalPinCode: function (code) {
+ console.debug(code);
+ return Math.random() < 0.5 ? {result: true} :{
+ error : {
+ code : 1112222,
+ message : 'Test Error Message'
+ }
+ };
+ },
+ getRegion: function () {
+ return Math.random() < 0.5 ? {
+ code: 'JPN'
+ } : {
+ error: {
+ code : 1112222,
+ message : 'Test Error Message'
+ }
+ };
+ },
+ getCountry: function () {
+ return Math.random() < 0.5 ? {
+ code: 'JP'
+ } : {
+ error: {
+ code : 1112222,
+ message : 'Test Error Message'
+ }
+ };
+ },
+ getLanguage: function () {
+ return Math.random() < 0.5 ? {
+ code: 'ja'
+ } : {
+ error: {
+ code : 1112222,
+ message : 'Test Error Message'
+ }
+ };
+ },
+ getSpotPassUploadConsoleInfoState: function () {
+ return { enable: Math.random() < 0.5 };
+ },
+ };
}
if (typeof wiiuBOSS === 'undefined') {
- window.wiiuBOSS = {
- isRegisteredBossTask: function () {
- console.debug('wiiuBOSS.isRegisteredBossTask');
- var result = {
- "isRegistered" : true
- };
- return result;
- },
- registerBossTask: function (languageCode) {
- console.debug('wiiuBOSS.registerBossTask');
- //return { "error" : { "code" : 1112222, "message" : "Test Error Message"} };
- return {};
- },
- unregisterBossTask: function () {
- console.debug('wiiuBOSS.unregisterBossTask');
- //return { "error" : { "code" : 1112222, "message" : "Test Error Message"} };
- return {};
- },
- isRegisteredDirectMessageTask: function () {
- console.debug('wiiuBOSS.isRegisteredDirectMessageTask');
- var result = {
- "isRegistered" : true
- };
- return result;
- },
- registerDirectMessageTask: function (languageCode) {
- console.debug('wiiuBOSS.registerDirectMessageTask');
- //return { "error" : { "code" : 1112222, "message" : "Test Error Message"} };
- return {};
- },
- registerDirectMessageTaskEx: function (lifeTime, interval) {
- console.debug('wiiuBOSS.registerDirectMessageTaskEx');
- //return { "error" : { "code" : 1112222, "message" : "Test Error Message"} };
- return {};
- },
- unregisterDirectMessageTask: function () {
- console.debug('wiiuBOSS.unregisterDirectMessageTask');
- //return { "error" : { "code" : 1112222, "message" : "Test Error Message"} };
- return {};
- },
- };
+ window.wiiuBOSS = {
+ isRegisteredBossTask: function () {
+ console.debug('wiiuBOSS.isRegisteredBossTask');
+ const result = {
+ 'isRegistered' : true
+ };
+ return result;
+ },
+ registerBossTask: function (languageCode) {
+ console.debug('wiiuBOSS.registerBossTask');
+ //return { "error" : { "code" : 1112222, "message" : "Test Error Message"} };
+ return {};
+ },
+ unregisterBossTask: function () {
+ console.debug('wiiuBOSS.unregisterBossTask');
+ //return { "error" : { "code" : 1112222, "message" : "Test Error Message"} };
+ return {};
+ },
+ isRegisteredDirectMessageTask: function () {
+ console.debug('wiiuBOSS.isRegisteredDirectMessageTask');
+ const result = {
+ 'isRegistered' : true
+ };
+ return result;
+ },
+ registerDirectMessageTask: function (languageCode) {
+ console.debug('wiiuBOSS.registerDirectMessageTask');
+ //return { "error" : { "code" : 1112222, "message" : "Test Error Message"} };
+ return {};
+ },
+ registerDirectMessageTaskEx: function (lifeTime, interval) {
+ console.debug('wiiuBOSS.registerDirectMessageTaskEx');
+ //return { "error" : { "code" : 1112222, "message" : "Test Error Message"} };
+ return {};
+ },
+ unregisterDirectMessageTask: function () {
+ console.debug('wiiuBOSS.unregisterDirectMessageTask');
+ //return { "error" : { "code" : 1112222, "message" : "Test Error Message"} };
+ return {};
+ },
+ };
}
if (typeof wiiuMainApplication === 'undefined') {
- window.wiiuMainApplication = {
- _images: [
- // JPEG, 850x450, 暖色 warm color
- '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',
- // JPEG, 850x450, 寒色 cool
- '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',
- null
- ],
- _getImage: function () {
- var images = this._images;
- var index = Math.floor(Math.random() * images.length);
+ window.wiiuMainApplication = {
+ _images: [
+ // JPEG, 850x450, 暖色 warm color
+ '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',
+ // JPEG, 850x450, 寒色 cool
+ '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',
+ null
+ ],
+ _getImage: function () {
+ const images = this._images;
+ const index = Math.floor(Math.random() * images.length);
- // テスト等でスクショの有無を固定したい場合にクッキーで指定できるようにする, 実機ではこの挙動は存在しない
- // If you want to fix the presence or absence of screenshots in tests, etc., make it possible to specify with cookies, this behavior does not exist on the actual device
- //var force = Olv.Cookie.get('force_screenshot_for_test');
- //if (force === 'true') index = 0;
- //if (force === 'false') index = 2;
+ // テスト等でスクショの有無を固定したい場合にクッキーで指定できるようにする, 実機ではこの挙動は存在しない
+ // If you want to fix the presence or absence of screenshots in tests, etc., make it possible to specify with cookies, this behavior does not exist on the actual device
+ //var force = Olv.Cookie.get('force_screenshot_for_test');
+ //if (force === 'true') index = 0;
+ //if (force === 'false') index = 2;
- return images[index];
- },
- getScreenShot: function (isTv) { return this._getImage(); },
- getAppData: function () { return null; },
- getExternalImageData: function () { return this._getImage(); },
- getExternalBinaryData: function () { return null; }
- };
+ return images[index];
+ },
+ getScreenShot: function (isTv) {
+ return this._getImage();
+ },
+ getAppData: function () {
+ return null;
+ },
+ getExternalImageData: function () {
+ return this._getImage();
+ },
+ getExternalBinaryData: function () {
+ return null;
+ }
+ };
}
-if (typeof wiiuMemo === "undefined") {
- window.wiiuMemo = {
- _isFinish: true,
- open: function(reset) {
- console.debug('wiiuMemo.open(reset = ' + reset + ')');
- this._isFinish = false;
- var self = this;
- setTimeout(function () { self._isFinish = true; }, 100);
- },
- isFinish: function() {
- console.debug('wiiuMemo.isFinish()')
- console.debug(this._isFinish);
- return this._isFinish;
- },
- reset: function () {
- console.debug('wiiuMemo.reset()');
- },
- getImage: function (isTga) {
- console.debug('wiiuMemo.getImage(isTga = ' + isTga + ')');
- if (isTga) {
- return 'eJzt3FuO0zAUBuDCE8tgKSyL3YNGqFJpk9aX41v8fdK8MHXiy/HvZCR6u32/3f369vv288cfAAAAAAAAAAAAAAAAAAAAAABgK7fbbXQXALr7yr77D8BO5B+wI9kH7Ej2ATuSfcBuHnNP9gE7eM492QekOsqPFXJkxT4D83iXfTPm4ox9AtZVmoEtc2iFLAauLTobZ8tZgFwyD+CVnAMAAAAAAAAAAAAAAAAAAAAAACCH758CduQ7+ICdrZyBq/YbmMOq+ec7pIEIq+aH7AMAAAAAAAAAAAAAAAAAAAAAgFjP32929gPUs6/GS808awVx7KuxSnPPGvFFfdQzb308z21O3Vojno0+J69Uh/ZXW0dzmzrfznaOjHxfKLnu7HVrn7VxNKc12Wdd0qz6bpjSv5SxlIw7Zb5Ks2+VuV+tXmaSegZ/mt+azNxZ7jPR6LksfSdI/WzqWEvm7Yr5dzdTrdT2oVe/c2slp8ZGr8HsSvfvqHmN6lPq+ZpzFreYt1Xrd3StjDh3Sta8tE5KapT/ldRIZF1H3TsiW1plWU0fW9Zur/0wKgdr79m6lt7do2ZP1I5jFy3yq6ZtzjqenW8lfUnpQ23WlrZtVbsj9kTvDIys7dzPl/y8u04N+fcqek4i8yDlTEy5Vu0Yju7TYrwpbaKN3BM75F/q51LruYb8e9ViTqL29dF1ctvUjCt3DKXjftemdc322BMlZ1yr+/doX3Mefvp9rzHsoNdzRUpW5VwrN4+ixpFzz5Sxn7XPuXet6HukZl2v7HvuU6/2OeMrOdNzxyL/Xo04+0vuv3r+lTwHrJINR9eZKfue+9azfUnN5l6zpB1956P2+ab0LO2Vf2efi8jAHiLzYdQYUvv36ffRmX3Wtua6Jf2baT1mMOL54uh+NfkS8dnIa0XvmV5q5mu2rDuTcj61ysDce0Vf82z8O2s9Hzlrm9KXmhyqEXU2zywq/2b2Lg9aZ99RH6LrRAbmia752rV997mSGmlRVyVtVqi16H09o3c1W9q+ti8tfdqjuyudi5bn5Fnb0mtGn9lX1er5Yybq4J+rjKNW1PNf6+f453+PuObZM+antlcW+VwzaxZG1fzKrjKOWqPeDXOvG/3OkZvb6iVfq7Mxsl8j2o82yzqMtsocjMjAd23I0/I9obY/I9qPNHruZ7LSHLRat9TrrjRXM5shA3fOvy+r9z/KivOw6p7hlec/RltxLVfcM8wjMv/Uw9qs42fm6Foi1lM9XIO9ncb8XIea504tsBPvrjxSC+xGvfNIBgK7kn/AzmQgR9QDu/C3YR6pBXYjA7lTC+zI/5HmTh2wKzmItWdno7+rg/GsN7uTgcDu5CCwOxkI7MyzILA7GQjsTAYCO5N9AAAAAAAAAAAAAAAAAAAAAAAAAKzoL3j1Foo=';
- } else {
- return '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';
- }
- }
- };
+if (typeof wiiuMemo === 'undefined') {
+ window.wiiuMemo = {
+ _isFinish: true,
+ open: function(reset) {
+ console.debug('wiiuMemo.open(reset = ' + reset + ')');
+ this._isFinish = false;
+ const self = this;
+ setTimeout(function () {
+ self._isFinish = true;
+ }, 100);
+ },
+ isFinish: function() {
+ console.debug('wiiuMemo.isFinish()');
+ console.debug(this._isFinish);
+ return this._isFinish;
+ },
+ reset: function () {
+ console.debug('wiiuMemo.reset()');
+ },
+ getImage: function (isTga) {
+ console.debug('wiiuMemo.getImage(isTga = ' + isTga + ')');
+ if (isTga) {
+ return 'eJzt3FuO0zAUBuDCE8tgKSyL3YNGqFJpk9aX41v8fdK8MHXiy/HvZCR6u32/3f369vv288cfAAAAAAAAAAAAAAAAAAAAAABgK7fbbXQXALr7yr77D8BO5B+wI9kH7Ej2ATuSfcBuHnNP9gE7eM492QekOsqPFXJkxT4D83iXfTPm4ox9AtZVmoEtc2iFLAauLTobZ8tZgFwyD+CVnAMAAAAAAAAAAAAAAAAAAAAAACCH758CduQ7+ICdrZyBq/YbmMOq+ec7pIEIq+aH7AMAAAAAAAAAAAAAAAAAAAAAgFjP32929gPUs6/GS808awVx7KuxSnPPGvFFfdQzb308z21O3Vojno0+J69Uh/ZXW0dzmzrfznaOjHxfKLnu7HVrn7VxNKc12Wdd0qz6bpjSv5SxlIw7Zb5Ks2+VuV+tXmaSegZ/mt+azNxZ7jPR6LksfSdI/WzqWEvm7Yr5dzdTrdT2oVe/c2slp8ZGr8HsSvfvqHmN6lPq+ZpzFreYt1Xrd3StjDh3Sta8tE5KapT/ldRIZF1H3TsiW1plWU0fW9Zur/0wKgdr79m6lt7do2ZP1I5jFy3yq6ZtzjqenW8lfUnpQ23WlrZtVbsj9kTvDIys7dzPl/y8u04N+fcqek4i8yDlTEy5Vu0Yju7TYrwpbaKN3BM75F/q51LruYb8e9ViTqL29dF1ctvUjCt3DKXjftemdc322BMlZ1yr+/doX3Mefvp9rzHsoNdzRUpW5VwrN4+ixpFzz5Sxn7XPuXet6HukZl2v7HvuU6/2OeMrOdNzxyL/Xo04+0vuv3r+lTwHrJINR9eZKfue+9azfUnN5l6zpB1956P2+ab0LO2Vf2efi8jAHiLzYdQYUvv36ffRmX3Wtua6Jf2baT1mMOL54uh+NfkS8dnIa0XvmV5q5mu2rDuTcj61ysDce0Vf82z8O2s9Hzlrm9KXmhyqEXU2zywq/2b2Lg9aZ99RH6LrRAbmia752rV997mSGmlRVyVtVqi16H09o3c1W9q+ti8tfdqjuyudi5bn5Fnb0mtGn9lX1er5Yybq4J+rjKNW1PNf6+f453+PuObZM+antlcW+VwzaxZG1fzKrjKOWqPeDXOvG/3OkZvb6iVfq7Mxsl8j2o82yzqMtsocjMjAd23I0/I9obY/I9qPNHruZ7LSHLRat9TrrjRXM5shA3fOvy+r9z/KivOw6p7hlec/RltxLVfcM8wjMv/Uw9qs42fm6Foi1lM9XIO9ncb8XIea504tsBPvrjxSC+xGvfNIBgK7kn/AzmQgR9QDu/C3YR6pBXYjA7lTC+zI/5HmTh2wKzmItWdno7+rg/GsN7uTgcDu5CCwOxkI7MyzILA7GQjsTAYCO5N9AAAAAAAAAAAAAAAAAAAAAAAAAKzoL3j1Foo=';
+ } else {
+ return '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';
+ }
+ }
+ };
}
-if (typeof wiiuPDM === "undefined") {
- window.wiiuPDM = {
- getTotalPlayTime: function(titleID) {
- console.debug('wiiuPDM.getTotalPlayTime(' + titleID + ')');
- return { minutes : 0 };
- },
- getTitlesFilteredByPlayTime: function(minutes) {
- console.debug('wiiuPDM.getTitlesFilteredByPlayTime(' + minutes + ')');
- return { IDs : [] };
- }
- }
+if (typeof wiiuPDM === 'undefined') {
+ window.wiiuPDM = {
+ getTotalPlayTime: function(titleID) {
+ console.debug('wiiuPDM.getTotalPlayTime(' + titleID + ')');
+ return { minutes : 0 };
+ },
+ getTitlesFilteredByPlayTime: function(minutes) {
+ console.debug('wiiuPDM.getTitlesFilteredByPlayTime(' + minutes + ')');
+ return { IDs : [] };
+ }
+ };
}
if (typeof wiiuErrorViewer === 'undefined') {
- window.wiiuErrorViewer = {
- openByCode: function (errorCode) {
- var message = 'Message for error code ' + errorCode;
- this.openByCodeAndMessage(errorCode, message);
- },
- openByCodeAndMessage: function (errorCode, errorMessage) {
- alert(errorCode + '\n\n' + errorMessage);
- }
- };
+ window.wiiuErrorViewer = {
+ openByCode: function (errorCode) {
+ const message = 'Message for error code ' + errorCode;
+ this.openByCodeAndMessage(errorCode, message);
+ },
+ openByCodeAndMessage: function (errorCode, errorMessage) {
+ alert(errorCode + '\n\n' + errorMessage);
+ }
+ };
}
if (typeof wiiuFilter === 'undefined') {
- window.wiiuFilter = {
- checkWord: function (message) {
- console.debug('Check words for message: ' + message);
- if (/[0-9]{6}/.test(message)) return -1;
- if (/ng word/i.test(message)) return -2;
- return 0;
- },
- };
+ window.wiiuFilter = {
+ checkWord: function (message) {
+ console.debug('Check words for message: ' + message);
+ if (/[0-9]{6}/.test(message)) {
+ return -1;
+ }
+ if (/ng word/i.test(message)) {
+ return -2;
+ }
+ return 0;
+ },
+ };
}
if (typeof wiiuSessionStorage === 'undefined') {
- window.wiiuSessionStorage = {
- getItem: function (key) {
- return sessionStorage.getItem(key);
- },
- setItem: function (key, value) {
- sessionStorage.setItem(key, value);
- return true;
- },
- removeItem: function (key) {
- sessionStorage.removeItem(key);
- },
- clear: function () {
- sessionStorage.clear();
- },
- key: function (index) {
- return sessionStorage.key(index);
- },
- length: function () {
- return sessionStorage.length;
- },
- };
+ window.wiiuSessionStorage = {
+ getItem: function (key) {
+ return sessionStorage.getItem(key);
+ },
+ setItem: function (key, value) {
+ sessionStorage.setItem(key, value);
+ return true;
+ },
+ removeItem: function (key) {
+ sessionStorage.removeItem(key);
+ },
+ clear: function () {
+ sessionStorage.clear();
+ },
+ key: function (index) {
+ return sessionStorage.key(index);
+ },
+ length: function () {
+ return sessionStorage.length;
+ },
+ };
}
if (typeof wiiuLocalStorage === 'undefined') {
- window.wiiuLocalStorage = {
- getItem: function (key) {
- return localStorage.getItem(key);
- },
- setItem: function (key, value) {
- localStorage.setItem(key, value);
- return true;
- },
- removeItem: function (key) {
- localStorage.removeItem(key);
- },
- clear: function () {
- localStorage.clear();
- },
- key: function (index) {
- return localStorage.key(index);
- },
- length: function () {
- return localStorage.length;
- },
- write: function () {},
- };
+ window.wiiuLocalStorage = {
+ getItem: function (key) {
+ return localStorage.getItem(key);
+ },
+ setItem: function (key, value) {
+ localStorage.setItem(key, value);
+ return true;
+ },
+ removeItem: function (key) {
+ localStorage.removeItem(key);
+ },
+ clear: function () {
+ localStorage.clear();
+ },
+ key: function (index) {
+ return localStorage.key(index);
+ },
+ length: function () {
+ return localStorage.length;
+ },
+ write: function () {},
+ };
}
\ No newline at end of file
diff --git a/src/webfiles/web/css/first_run.css b/src/webfiles/web/css/first_run.css
new file mode 100644
index 0000000..9353860
--- /dev/null
+++ b/src/webfiles/web/css/first_run.css
@@ -0,0 +1,67 @@
+.account-form-wrapper > div {
+ display: none;
+ flex-direction: column;
+ max-width: 700px;
+ padding: 1em;
+}
+.account-form-wrapper .logotype {
+ position: relative;
+ margin: 1em 1em 0 1em;
+ left: 0;
+}
+.account-form-wrapper > div .button-wrapper {
+ display: flex;
+}
+.button-wrapper > *:last-child, button.about-button {
+ background: #673DB6;
+}
+input[type="button"], input[type="button"], button {
+ display: block;
+ border: none;
+ border-radius: 4px;
+ font-family: Poppins, Arial, Helvetica, sans-serif;
+ font-size: 1rem;
+ color: var(--text);
+ padding: 12px 30px;
+ background: #353C6A;
+ margin-top: 18px;
+ cursor: pointer;
+ width: 100%;
+ text-decoration: none;
+ margin: 1em;
+}
+h1 {
+ margin: 5px 0;
+}
+.horizontal-list {
+ display: flex;
+ list-style: none;
+ justify-content: center;
+ flex-wrap: wrap;
+ background: #353C6A;
+ border-radius: 100px;
+ padding: 5px;
+}
+.horizontal-list > li {
+ min-width: 185px;
+ padding: 1em;
+ margin: 5px;
+ text-align: center;
+ border-radius: 25px;
+ cursor: pointer;
+}
+.horizontal-list > li > a {
+ color: white;
+ text-decoration: none;
+}
+.horizontal-list > li.selected {
+ background: #673DB6;
+}
+@media screen and (max-width:730px) {
+ .horizontal-list {
+ border-radius: 25px;
+ }
+ .horizontal-list > li {
+ width: 100%;
+ }
+}
\ No newline at end of file
diff --git a/src/webfiles/web/first_run.ejs b/src/webfiles/web/first_run.ejs
index 65e0cfb..6c52a1a 100644
--- a/src/webfiles/web/first_run.ejs
+++ b/src/webfiles/web/first_run.ejs
@@ -42,11 +42,49 @@
+
+
+
+
+
diff --git a/src/webfiles/web/js/web.js b/src/webfiles/web/js/web.js
index 64fceef..badd5e6 100644
--- a/src/webfiles/web/js/web.js
+++ b/src/webfiles/web/js/web.js
@@ -3,315 +3,333 @@ setInterval(checkForUpdates, 30000);
/* global Pjax */
function initNavBar() {
- let els = document.querySelectorAll("#nav-menu > li");
- if (!els) return;
- for (let i = 0; i < els.length; i++) {
- els[i].addEventListener("click", function(e) {
- let el = e.currentTarget;
- for(let i = 0; i < els.length; i++) {
- if(els[i].classList.contains('selected'))
- els[i].classList.remove('selected');
- }
- el.classList.add("selected");
- });
- }
+ const els = document.querySelectorAll('#nav-menu > li');
+ if (!els) {
+ return;
+ }
+ for (let i = 0; i < els.length; i++) {
+ els[i].addEventListener('click', function(e) {
+ const el = e.currentTarget;
+ for (let i = 0; i < els.length; i++) {
+ if (els[i].classList.contains('selected')) {
+ els[i].classList.remove('selected');
+ }
+ }
+ el.classList.add('selected');
+ });
+ }
}
function initYeah() {
- let els = document.querySelectorAll("span[data-post]");
- if (!els) return;
- for (let i = 0; i < els.length; i++) {
- els[i].removeEventListener('click', yeah);
- els[i].addEventListener("click", yeah);
- }
- function yeah(e) {
- let el = e.currentTarget, id = el.getAttribute("data-post");
- let parent = document.getElementById(id);
- let count = document.getElementById("count-" + id);
- el.disabled = true;
- let params = "postID=" + id;
- if(el.classList.contains('selected')) {
- el.classList.remove('selected');
- parent.classList.remove('yeah');
- count.innerText -= 1;
+ const els = document.querySelectorAll('span[data-post]');
+ if (!els) {
+ return;
+ }
+ for (let i = 0; i < els.length; i++) {
+ els[i].removeEventListener('click', yeah);
+ els[i].addEventListener('click', yeah);
+ }
+ function yeah(e) {
+ const el = e.currentTarget; const id = el.getAttribute('data-post');
+ const parent = document.getElementById(id);
+ const count = document.getElementById('count-' + id);
+ el.disabled = true;
+ const params = 'postID=' + id;
+ if (el.classList.contains('selected')) {
+ el.classList.remove('selected');
+ parent.classList.remove('yeah');
+ count.innerText -= 1;
- }
- else {
- el.classList.add('selected');
- parent.classList.add('yeah');
- count.innerText = ++count.innerText;
- }
+ } else {
+ el.classList.add('selected');
+ parent.classList.add('yeah');
+ count.innerText = ++count.innerText;
+ }
- POST('/posts/empathy', params, function a(data) {
- let post = JSON.parse(data.response);
- if(!post || post.status !== 200) {
- // Apparently there was an actual error code for not being able to yeah a post, who knew!
- // TODO: Find more of these
- Toast(1155927);
- }
- el.disabled = false;
- count.innerText = post.count;
- });
- }
+ POST('/posts/empathy', params, function a(data) {
+ const post = JSON.parse(data.response);
+ if (!post || post.status !== 200) {
+ // Apparently there was an actual error code for not being able to yeah a post, who knew!
+ // TODO: Find more of these
+ Toast(1155927);
+ }
+ el.disabled = false;
+ count.innerText = post.count;
+ });
+ }
}
function initTabs() {
- let els = document.querySelectorAll(".tab-button");
- if (!els) return;
- for (let i = 0; i < els.length; i++) {
- els[i].removeEventListener('click', tabs);
- els[i].addEventListener("click", tabs);
- }
- function tabs(e) {
- e.preventDefault();
- let el = e.currentTarget;
- let child = el.children[0];
+ const els = document.querySelectorAll('.tab-button');
+ if (!els) {
+ return;
+ }
+ for (let i = 0; i < els.length; i++) {
+ els[i].removeEventListener('click', tabs);
+ els[i].addEventListener('click', tabs);
+ }
+ function tabs(e) {
+ e.preventDefault();
+ const el = e.currentTarget;
+ const child = el.children[0];
- for(let i = 0; i < els.length; i++) {
- if(els[i].classList.contains('selected'))
- els[i].classList.remove('selected');
- }
- el.classList.add("selected");
+ for (let i = 0; i < els.length; i++) {
+ if (els[i].classList.contains('selected')) {
+ els[i].classList.remove('selected');
+ }
+ }
+ el.classList.add('selected');
- GET(child.getAttribute('href') + "?pjax=true", function a(data) {
- let response = data.response;
- if(response && data.status === 200) {
- document.getElementsByClassName("tab-body")[0].innerHTML = data.response;
- window.history.pushState({ url: child.href, title: "", scrollPos: [0, 0]}, "", child.href);
- initPosts();
- initMorePosts();
- }
- })
+ GET(child.getAttribute('href') + '?pjax=true', function a(data) {
+ const response = data.response;
+ if (response && data.status === 200) {
+ document.getElementsByClassName('tab-body')[0].innerHTML = data.response;
+ window.history.pushState({ url: child.href, title: '', scrollPos: [0, 0]}, '', child.href);
+ initPosts();
+ initMorePosts();
+ }
+ });
- }
+ }
}
function initPosts() {
- let els = document.querySelectorAll(".post-content[data-href]");
- if (!els) return;
- for (let i = 0; i < els.length; i++) {
- els[i].addEventListener("click", function(e) {
- pjax.loadUrl(e.currentTarget.getAttribute('data-href'));
- });
- }
- initYeah();
- initSpoilers();
+ const els = document.querySelectorAll('.post-content[data-href]');
+ if (!els) {
+ return;
+ }
+ for (let i = 0; i < els.length; i++) {
+ els[i].addEventListener('click', function(e) {
+ pjax.loadUrl(e.currentTarget.getAttribute('data-href'));
+ });
+ }
+ initYeah();
+ initSpoilers();
}
function initMorePosts() {
- let els = document.querySelectorAll("#load-more[data-href]");
- if (!els) return;
- for (let i = 0; i < els.length; i++) {
- els[i].addEventListener("click", function(e) {
- let el = e.currentTarget;
- GET(el.getAttribute('data-href'), function a(data) {
- let response = data.response;
- if(response && data.status === 200) {
- el.parentElement.outerHTML = data.response;
- initPosts();
- initMorePosts();
- }
- else
- el.parentElement.remove();
- })
+ const els = document.querySelectorAll('#load-more[data-href]');
+ if (!els) {
+ return;
+ }
+ for (let i = 0; i < els.length; i++) {
+ els[i].addEventListener('click', function(e) {
+ const el = e.currentTarget;
+ GET(el.getAttribute('data-href'), function a(data) {
+ const response = data.response;
+ if (response && data.status === 200) {
+ el.parentElement.outerHTML = data.response;
+ initPosts();
+ initMorePosts();
+ } else {
+ el.parentElement.remove();
+ }
+ });
- });
- }
+ });
+ }
}
function initPostModules() {
- let els = document.querySelectorAll("[data-module-show]");
- console.log(els)
- if (!els) return;
- for (let i = 0; i < els.length; i++) {
- els[i].addEventListener("click", function(e) {
- let el = e.currentTarget,
- show = el.getAttribute("data-module-show"),
- hide = el.getAttribute("data-module-hide"),
- header = el.getAttribute("data-header"),
- menu = el.getAttribute("data-menu");
- if(!show || !hide) return;
- document.getElementById(hide).style.display = 'none';
- document.getElementById(show).style.display = 'block';
- if(header === 'true')
- document.getElementById("header").style.display = 'block';
- else
- document.getElementById("header").style.display = 'none';
- if(menu === 'true')
- document.getElementById("nav-menu").style.display = 'block';
- else
- document.getElementById("nav-menu").style.display = 'none';
- initNewPost();
- });
- }
+ const els = document.querySelectorAll('[data-module-show]');
+ console.log(els);
+ if (!els) {
+ return;
+ }
+ for (let i = 0; i < els.length; i++) {
+ els[i].addEventListener('click', function(e) {
+ const el = e.currentTarget;
+ const show = el.getAttribute('data-module-show');
+ const hide = el.getAttribute('data-module-hide');
+ const header = el.getAttribute('data-header');
+ const menu = el.getAttribute('data-menu');
+ if (!show || !hide) {
+ return;
+ }
+ document.getElementById(hide).style.display = 'none';
+ document.getElementById(show).style.display = 'block';
+ if (header === 'true') {
+ document.getElementById('header').style.display = 'block';
+ } else {
+ document.getElementById('header').style.display = 'none';
+ }
+ if (menu === 'true') {
+ document.getElementById('nav-menu').style.display = 'block';
+ } else {
+ document.getElementById('nav-menu').style.display = 'none';
+ }
+ initNewPost();
+ });
+ }
}
function initPostEmotion() {
- let els = document.querySelectorAll("input[data-mii-face-url]");
- if (!els) return;
- for (let i = 0; i < els.length; i++) {
- els[i].addEventListener("click", function(e) {
- let el = e.currentTarget;
- document.getElementById("mii-face").src = el.getAttribute('data-mii-face-url');
- });
- }
+ const els = document.querySelectorAll('input[data-mii-face-url]');
+ if (!els) {
+ return;
+ }
+ for (let i = 0; i < els.length; i++) {
+ els[i].addEventListener('click', function(e) {
+ const el = e.currentTarget;
+ document.getElementById('mii-face').src = el.getAttribute('data-mii-face-url');
+ });
+ }
}
function initNewPost() {
- initPostEmotion();
- initScreenShots();
+ initPostEmotion();
+ initScreenShots();
}
function initSpoilers() {
- let els = document.querySelectorAll("button[data-post-id]");
- if (!els) return;
- for (let i = 0; i < els.length; i++) {
- els[i].addEventListener("click", function(e) {
- let el = e.currentTarget;
- document.getElementById('post-' + el.getAttribute('data-post-id')).classList.remove('spoiler');
- el.remove();
- });
- }
+ const els = document.querySelectorAll('button[data-post-id]');
+ if (!els) {
+ return;
+ }
+ for (let i = 0; i < els.length; i++) {
+ els[i].addEventListener('click', function(e) {
+ const el = e.currentTarget;
+ document.getElementById('post-' + el.getAttribute('data-post-id')).classList.remove('spoiler');
+ el.remove();
+ });
+ }
}
function initAll() {
- initNavBar();
- initTabs();
- initPosts();
- initMorePosts();
- initPostModules();
- pjax.refresh();
+ initNavBar();
+ initTabs();
+ initPosts();
+ initMorePosts();
+ initPostModules();
+ pjax.refresh();
}
-console.debug("Document initialized:" + window.location.href);
-document.addEventListener("pjax:send", function() {
- console.debug("Event: pjax:send", arguments);
+console.debug('Document initialized:' + window.location.href);
+document.addEventListener('pjax:send', function() {
+ console.debug('Event: pjax:send', arguments);
});
-document.addEventListener("pjax:complete", function() {
- console.debug("Event: pjax:complete", arguments);
+document.addEventListener('pjax:complete', function() {
+ console.debug('Event: pjax:complete', arguments);
});
-document.addEventListener("pjax:error", function(e) {
- Toast('Error: Unable to load element. \nPlease send the error code and what you were doing in #support');
- console.debug(e);
+document.addEventListener('pjax:error', function(e) {
+ Toast('Error: Unable to load element. \nPlease send the error code and what you were doing in #support');
+ console.debug(e);
});
-document.addEventListener("pjax:success", function() {
- console.debug("Event: pjax:success", arguments);
- initAll();
+document.addEventListener('pjax:success', function() {
+ console.debug('Event: pjax:success', arguments);
+ initAll();
});
-document.addEventListener("DOMContentLoaded", function() {
- pjax = new Pjax({
- elements: "a[data-pjax]" +
- "",
- selectors: ["title", "#body"],
- switches: {"#nav-menu": Pjax.switches.replaceNode, ".tab-body": Pjax.switches.replaceNode}
- })
- console.debug("Pjax initialized.", pjax);
- initAll();
+document.addEventListener('DOMContentLoaded', function() {
+ pjax = new Pjax({
+ elements: 'a[data-pjax]' +
+ '',
+ selectors: ['title', '#body'],
+ switches: {'#nav-menu': Pjax.switches.replaceNode, '.tab-body': Pjax.switches.replaceNode}
+ });
+ console.debug('Pjax initialized.', pjax);
+ initAll();
});
function follow(el) {
- let id = el.getAttribute("data-community-id");
- let count = document.getElementById("followers");
- let oldtext = el.innerText, newtext = el.getAttribute("data-text");
- el.disabled = true;
- let params = "id=" + id;
- if(el.classList.contains('checked')) {
- el.classList.remove('checked');
- }
- else {
- el.classList.add('checked');
- }
- el.setAttribute("data-text", oldtext);
- el.innerText = newtext;
- POST(el.getAttribute("data-url"), params, function a(data) {
- let element = JSON.parse(data.response);
- if(!element || element.status !== 200) {
- // Apparently there was an actual error code for not being able to yeah a post, who knew!
- // TODO: Find more of these
- return Toast('Unable to follow. Please try again later.');
- }
- el.disabled = false;
- count.innerText = element.count;
- });
+ const id = el.getAttribute('data-community-id');
+ const count = document.getElementById('followers');
+ const oldtext = el.innerText; const newtext = el.getAttribute('data-text');
+ el.disabled = true;
+ const params = 'id=' + id;
+ if (el.classList.contains('checked')) {
+ el.classList.remove('checked');
+ } else {
+ el.classList.add('checked');
+ }
+ el.setAttribute('data-text', oldtext);
+ el.innerText = newtext;
+ POST(el.getAttribute('data-url'), params, function a(data) {
+ const element = JSON.parse(data.response);
+ if (!element || element.status !== 200) {
+ // Apparently there was an actual error code for not being able to yeah a post, who knew!
+ // TODO: Find more of these
+ return Toast('Unable to follow. Please try again later.');
+ }
+ el.disabled = false;
+ count.innerText = element.count;
+ });
}
function checkForUpdates() {
- let xhttp = new XMLHttpRequest();
- xhttp.onreadystatechange = function() {
- if (this.readyState === 4 && this.status === 200) {
- let notificationObj = JSON.parse(this.responseText);
- let messages = document.getElementById("message-badge");
- let news = document.getElementById("news-badge");
- /**/
- if(notificationObj.message_count > 0 && notificationObj.message_count < 99) {
- messages.innerHTML = notificationObj.message_count;
- messages.style.display = "unset";
- }
- else if(notificationObj.message_count >= 99) {
- messages.innerHTML = "99+";
- messages.style.display = "unset";
- }
- else {
- messages.innerHTML = "";
- messages.style.display = "none";
- }
- /*Check for Notifications*/
- if(notificationObj.notification_count > 0 && notificationObj.notification_count < 99) {
- news.innerHTML = notificationObj.notification_count;
- news.style.display = "unset";
- }
- else if(notificationObj.notification_count >= 99) {
- news.innerHTML = "99+";
- news.style.display = "unset";
- }
- else {
- news.innerHTML = "";
- news.style.display = "none";
- }
- }
- };
- xhttp.open("GET", "/notifications.json", true);
- xhttp.send();
+ const xhttp = new XMLHttpRequest();
+ xhttp.onreadystatechange = function() {
+ if (this.readyState === 4 && this.status === 200) {
+ const notificationObj = JSON.parse(this.responseText);
+ const messages = document.getElementById('message-badge');
+ const news = document.getElementById('news-badge');
+ /**/
+ if (notificationObj.message_count > 0 && notificationObj.message_count < 99) {
+ messages.innerHTML = notificationObj.message_count;
+ messages.style.display = 'unset';
+ } else if (notificationObj.message_count >= 99) {
+ messages.innerHTML = '99+';
+ messages.style.display = 'unset';
+ } else {
+ messages.innerHTML = '';
+ messages.style.display = 'none';
+ }
+ /*Check for Notifications*/
+ if (notificationObj.notification_count > 0 && notificationObj.notification_count < 99) {
+ news.innerHTML = notificationObj.notification_count;
+ news.style.display = 'unset';
+ } else if (notificationObj.notification_count >= 99) {
+ news.innerHTML = '99+';
+ news.style.display = 'unset';
+ } else {
+ news.innerHTML = '';
+ news.style.display = 'none';
+ }
+ }
+ };
+ xhttp.open('GET', '/notifications.json', true);
+ xhttp.send();
}
function POST(url, data, callback) {
- let xhttp = new XMLHttpRequest();
- xhttp.onreadystatechange = function() {
- if(this.readyState === 4) {
- return callback(this);
- }
- }
- xhttp.open("POST", url, true);
- xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
- xhttp.send(data);
+ const xhttp = new XMLHttpRequest();
+ xhttp.onreadystatechange = function() {
+ if (this.readyState === 4) {
+ return callback(this);
+ }
+ };
+ xhttp.open('POST', url, true);
+ xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
+ xhttp.send(data);
}
function GET(url, callback) {
- let xhttp = new XMLHttpRequest();
- xhttp.onreadystatechange = function() {
- if(this.readyState === 4) {
- return callback(this);
- }
- };
- xhttp.open("GET", url, true);
- xhttp.send();
+ const xhttp = new XMLHttpRequest();
+ xhttp.onreadystatechange = function() {
+ if (this.readyState === 4) {
+ return callback(this);
+ }
+ };
+ xhttp.open('GET', url, true);
+ xhttp.send();
}
window.onscroll = function(ev) {
- if ((window.innerHeight + window.scrollY) >= document.body.scrollHeight) {
- document.getElementById('load-more').click();
- }
+ if ((window.innerHeight + window.scrollY) >= document.body.scrollHeight) {
+ document.getElementById('load-more').click();
+ }
};
function copyToClipboard(text) {
- let inputc = document.getElementsByTagName("header")[0].appendChild(document.createElement("input"));
- inputc.value = text;
- inputc.focus();
- inputc.select();
- document.execCommand('copy');
- inputc.parentNode.removeChild(inputc);
- Toast("Copied to clipboard.");
+ const inputc = document.getElementsByTagName('header')[0].appendChild(document.createElement('input'));
+ inputc.value = text;
+ inputc.focus();
+ inputc.select();
+ document.execCommand('copy');
+ inputc.parentNode.removeChild(inputc);
+ Toast('Copied to clipboard.');
}
function Toast(text) {
- let x = document.getElementById("toast");
- x.innerText = text;
- x.className = "show";
- setTimeout(function(){ x.className = x.className.replace("show", ""); }, 3000);
+ const x = document.getElementById('toast');
+ x.innerText = text;
+ x.className = 'show';
+ setTimeout(function(){
+ x.className = x.className.replace('show', '');
+ }, 3000);
}
function downloadURI(uri, name) {
- let link = document.createElement("a");
- link.download = name;
- link.href = uri;
- document.body.appendChild(link);
- link.click();
- document.body.removeChild(link);
- delete link;
+ const link = document.createElement('a');
+ link.download = name;
+ link.href = uri;
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ delete link;
}
\ No newline at end of file
diff --git a/src/webfiles/web/messages.ejs b/src/webfiles/web/messages.ejs
index f3ab623..606f92b 100644
--- a/src/webfiles/web/messages.ejs
+++ b/src/webfiles/web/messages.ejs
@@ -9,7 +9,7 @@
<% if(conversations.length === 0) {%>
-
<%= lang.messages.coming_soon %><
+
<%= lang.messages.coming_soon %>
<%} else { %>
<% conversations.forEach(function(conversation) { %>
diff --git a/src/webfiles/web/partials/notifications.ejs b/src/webfiles/web/partials/notifications.ejs
index 07375ad..4160c76 100644
--- a/src/webfiles/web/partials/notifications.ejs
+++ b/src/webfiles/web/partials/notifications.ejs
@@ -1,5 +1,5 @@
-<%if(bundle.notifications === undefined) {%><%= lang.notifications.none %>
<%}%>
+<%if(bundle.notifications.length === 0) {%><%= lang.notifications.none %>
<%}%>
<% for(var notification of bundle.notifications) {%>
<% if(notification.type === 'follow') {%>
-
diff --git a/src/webfiles/web/partials/posts_list.ejs b/src/webfiles/web/partials/posts_list.ejs
index 12e0606..352dca5 100644
--- a/src/webfiles/web/partials/posts_list.ejs
+++ b/src/webfiles/web/partials/posts_list.ejs
@@ -1,5 +1,5 @@
<%if(!bundle.open) {%>
This community is closed to new posts.
<%}%>
-<% if(bundle.numPosts === 0) {%>
+<% if(bundle.posts.length === 0) {%>
<%= lang.global.no_posts %>
<%} else { %>
<% bundle.posts.forEach(function(post) { %>