mirror of
https://github.com/PretendoNetwork/juxtaposition-ui.git
synced 2026-08-24 02:05:26 -05:00
Move latest Dev changes into Beta (#49)
* Fixed incorrect handling of message unread notifications. Dependency audit fixes * Updated conversations markAsRead function to match newMessage function * Fixed screenshots not working on desktop * CSS fixes for admin page on mobile. Fixed reporting replies not working * Fixed login page breaking when auth token expired * eslint fixes & account setup on web * Fixed some UI bugs related to posts. Added option to ignore report. Updated text for 3DS screenshot support. Added profanity filter for posts * Added user management page. Added moderation button on profiles on web. Fixed bug where you would get stuck on login at an expired token. Fixed race condition with cookies that would break the admin panel * Added support for reporting posts on desktop * fixed missing check from moderator endpoint * Refactored embeds to be more useful on discord * Fixed user page embeds * Added support for viewing messages on web * Added support for reporting posts on 3DS (WIP - needs more testing). ESLint on a few files * Updated grpc package. Bug fixes on 3DS * Updated grpc package. Bug fixes on 3DS * Fixed ban messages on the mobile site not being displayed. * Updated user pages to show when a user is banned * Added bandwithlost image to web directory * Fixed wrong CDN being used for mii images on web account page
This commit is contained in:
committed by
GitHub
parent
3df8b6748a
commit
7c494d81be
3401
package-lock.json
generated
3401
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/PretendoNetwork/juxt-web#readme",
|
||||
"dependencies": {
|
||||
"@pretendonetwork/grpc": "^1.0.6",
|
||||
"aws-sdk": "^2.1192.0",
|
||||
"body-parser": "^1.19.0",
|
||||
"colors": "^1.4.0",
|
||||
@@ -43,7 +44,6 @@
|
||||
"node-snowflake": "0.0.1",
|
||||
"pako": "^2.0.2",
|
||||
"pngjs": "^6.0.0",
|
||||
"pretendo-grpc": "github:PretendoNetwork/grpc-ts",
|
||||
"sharp": "^0.31.3",
|
||||
"tga": "^1.0.4",
|
||||
"xml2js": "^0.4.23",
|
||||
|
||||
687
src/database.js
687
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
|
||||
};
|
||||
|
||||
@@ -1,136 +1,163 @@
|
||||
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()
|
||||
}
|
||||
|
||||
// Get pid and fetch user data
|
||||
if(request.cookies.access_token) {
|
||||
try {
|
||||
request.user = await util.data.getUserDataFromToken(request.cookies.access_token);
|
||||
}
|
||||
catch(e) {
|
||||
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);
|
||||
|
||||
// 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');
|
||||
request.lang = util.data.processLanguage();
|
||||
if (includes(request, 'juxt')) {
|
||||
request.directory = 'web';
|
||||
} else {
|
||||
request.directory = includes(request, 'portal') ? 'portal' : 'ctr';
|
||||
}
|
||||
// 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
|
||||
});
|
||||
}
|
||||
}
|
||||
return next();
|
||||
}
|
||||
|
||||
// Juxt Website
|
||||
if(includes(request, 'juxt')) {
|
||||
request.lang = util.data.processLanguage();
|
||||
request.token = request.cookies.access_token;
|
||||
request.paramPackData = null;
|
||||
request.directory = 'web';
|
||||
// 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');
|
||||
if (request.path === '/login') {
|
||||
request.lang = util.data.processLanguage();
|
||||
request.token = request.cookies.access_token;
|
||||
request.paramPackData = null;
|
||||
request.directory = 'web';
|
||||
return next();
|
||||
} else {
|
||||
//return response.render('web/login.ejs', {toast: 'Unable to reach the account server. Try again later.', cdnURL: config.CDN_domain,});
|
||||
return response.redirect('/login');
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
// Open access pages
|
||||
if(isStartOfPath(request.path, '/users/') ||
|
||||
// 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) {
|
||||
//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 || request.user.accessLevel == 3;
|
||||
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)) {
|
||||
if (includes(request, 'juxt')) {
|
||||
let banMessage = '';
|
||||
switch (user.account_status) {
|
||||
case 2:
|
||||
banMessage = `${request.user.username} has been banned until: ${ moment(user.ban_lift_date) }. \n\nReason: ${user.ban_reason}. \n\nIf you have any questions contact the developers in the Discord server.`;
|
||||
break;
|
||||
case 3:
|
||||
banMessage = `${request.user.username} has been banned forever. \n\nReason: ${user.ban_reason}. \n\nIf you have any questions contact the developers in the Discord server.`;
|
||||
break;
|
||||
default:
|
||||
banMessage = `${request.user.username} has been banned. \n\nIf you have any questions contact the developers in the Discord server.`;
|
||||
}
|
||||
return response.render('web/login.ejs', {toast: banMessage, cdnURL: config.CDN_domain,});
|
||||
} else {
|
||||
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';
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -1,67 +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, fromPid) {
|
||||
if(this.users[0].pid === fromPid) {
|
||||
this.users[1].read = false;
|
||||
this.markModified('users[1].read');
|
||||
}
|
||||
else {
|
||||
this.users[0].read = false;
|
||||
this.markModified('users[0].read');
|
||||
}
|
||||
this.set('last_updated', moment(new Date()));
|
||||
this.set('message_preview', message);
|
||||
await this.save();
|
||||
}
|
||||
ConversationSchema.methods.newMessage = async function(message, senderPID) {
|
||||
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(pid) {
|
||||
let users = this.get('users');
|
||||
if(users[0].pid === pid)
|
||||
users[0].read = true;
|
||||
else if(users[1].pid === pid)
|
||||
users[1].read = true;
|
||||
this.set('users', users)
|
||||
this.markModified('users');
|
||||
await this.save();
|
||||
}
|
||||
ConversationSchema.methods.markAsRead = async function(receiverPID) {
|
||||
const receiver = this.users.find(user => user.pid === receiverPID);
|
||||
if (receiver) {
|
||||
receiver.read = true;
|
||||
}
|
||||
await this.save();
|
||||
};
|
||||
|
||||
const CONVERSATION = model('CONVERSATION', ConversationSchema);
|
||||
|
||||
module.exports = {
|
||||
ConversationSchema: ConversationSchema,
|
||||
CONVERSATION: CONVERSATION
|
||||
ConversationSchema: ConversationSchema,
|
||||
CONVERSATION: CONVERSATION
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -1,33 +1,35 @@
|
||||
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
|
||||
},
|
||||
note: String,
|
||||
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();
|
||||
ReportSchema.methods.resolve = async function(pid, note) {
|
||||
this.set('resolved', true);
|
||||
this.set('resolved_by', pid);
|
||||
this.set('resolved_at', new Date());
|
||||
this.set('note', note);
|
||||
await this.save();
|
||||
};
|
||||
|
||||
const REPORT = model('REPORT', ReportSchema);
|
||||
|
||||
module.exports = {
|
||||
ReportSchema,
|
||||
REPORT
|
||||
ReportSchema,
|
||||
REPORT
|
||||
};
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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}`);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,57 +1,146 @@
|
||||
const express = require('express');
|
||||
const database = require('../../../../database');
|
||||
const { POST } = require('../../../../models/post');
|
||||
const { SETTINGS } = require('../../../../models/settings');
|
||||
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');
|
||||
router.get('/posts', async function (req, res) {
|
||||
if (!req.moderator) {
|
||||
return res.redirect('/titles/show');
|
||||
}
|
||||
|
||||
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.get('/accounts', async function (req, res) {
|
||||
if (!req.moderator) {
|
||||
return res.redirect('/titles/show');
|
||||
}
|
||||
|
||||
const users = await database.getUsersContent();
|
||||
const userMap = await util.data.getUserHash();
|
||||
res.render(req.directory + '/users.ejs', {
|
||||
lang: req.lang,
|
||||
moment: moment,
|
||||
cdnURL: config.CDN_domain,
|
||||
mii_image_CDN: config.mii_image_CDN,
|
||||
pid: req.pid,
|
||||
moderator: req.moderator,
|
||||
userMap,
|
||||
users
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/accounts/:pid', async function (req, res) {
|
||||
if (!req.moderator) {
|
||||
return res.redirect('/titles/show');
|
||||
}
|
||||
const pnid = await util.data.getUserDataFromPid(req.params.pid).catch((e) => {
|
||||
console.log(e.details);
|
||||
});
|
||||
const userContent = await database.getUserContent(req.params.pid);
|
||||
if (isNaN(req.params.pid) || !pnid || !userContent) {
|
||||
return res.redirect('/404');
|
||||
}
|
||||
const userSettings = await database.getUserSettings(req.params.pid);
|
||||
const posts = await database.getNumberUserPostsByID(req.params.pid, config.post_limit);
|
||||
const communityMap = await util.data.getCommunityHash();
|
||||
|
||||
res.render(req.directory + '/moderate_user.ejs', {
|
||||
lang: req.lang,
|
||||
moment: moment,
|
||||
cdnURL: config.CDN_domain,
|
||||
mii_image_CDN: config.mii_image_CDN,
|
||||
pid: req.pid,
|
||||
moderator: req.moderator,
|
||||
userSettings,
|
||||
userContent,
|
||||
posts,
|
||||
communityMap,
|
||||
pnid
|
||||
});
|
||||
});
|
||||
|
||||
router.post('/accounts/:pid', async (req, res) => {
|
||||
if (!req.moderator) {
|
||||
return res.redirect('/titles/show');
|
||||
}
|
||||
|
||||
const { pid } = req.params;
|
||||
await SETTINGS.findOneAndUpdate({pid: pid}, {
|
||||
account_status: req.body.account_status,
|
||||
ban_lift_date: req.body.ban_lift_date,
|
||||
ban_reason: `${req.user.username} (${req.pid}): ${req.body.ban_reason}`
|
||||
});
|
||||
|
||||
res.json({
|
||||
error: false
|
||||
});
|
||||
});
|
||||
|
||||
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);
|
||||
if (!req.moderator) {
|
||||
return res.sendStatus(401);
|
||||
}
|
||||
|
||||
if(!req.moderator) return res.sendStatus(401);
|
||||
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);
|
||||
}
|
||||
|
||||
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, req.query.reason ? req.query.reason : 'Removed by moderator');
|
||||
|
||||
return res.sendStatus(200);
|
||||
return res.sendStatus(200);
|
||||
});
|
||||
|
||||
router.put('/:reportID', async function (req, res) {
|
||||
if (!req.moderator) {
|
||||
return res.sendStatus(401);
|
||||
}
|
||||
|
||||
const report = await database.getReportById(req.params.reportID);
|
||||
if (!report) {
|
||||
return res.sendStatus(402);
|
||||
}
|
||||
|
||||
await report.resolve(req.pid, req.query.reason);
|
||||
|
||||
return res.sendStatus(200);
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -10,225 +10,238 @@ 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.params.communityID === '0') {
|
||||
console.log(req.paramPackData);
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -5,281 +5,304 @@ 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);
|
||||
const postPNID = await util.data.getUserDataFromPid(post.pid);
|
||||
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,
|
||||
postPNID,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -5,146 +5,155 @@ 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 doc = {
|
||||
'author_name': post.screen_name,
|
||||
'author_url': 'https://juxt.pretendo.network/users/show?pid=' + post.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;
|
||||
|
||||
@@ -3,66 +3,75 @@ 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.cookie('token_type', 'Bearer', { domain : cookieDomain });
|
||||
res.redirect('/');
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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')});
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -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'),
|
||||
|
||||
};
|
||||
691
src/util.js
691
src/util.js
@@ -9,19 +9,19 @@ const { SETTINGS } = require('./models/settings');
|
||||
const { CONTENT } = require('./models/content');
|
||||
const { NOTIFICATION } = require('./models/notifications');
|
||||
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 { AccountDefinition } = require('@pretendonetwork/grpc/account/account_service');
|
||||
const { FriendsDefinition } = require('@pretendonetwork/grpc/friends/friends_service');
|
||||
const { APIDefinition } = require('@pretendonetwork/grpc/api/api_service');
|
||||
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,67 @@ 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
|
||||
})
|
||||
});
|
||||
},
|
||||
refreshLogin: async function(refreshToken) {
|
||||
return await apiClient.login({
|
||||
refreshToken: refreshToken
|
||||
}, {
|
||||
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;
|
||||
|
||||
@@ -371,7 +371,9 @@ header svg {
|
||||
|
||||
.post-content-text {
|
||||
padding: 5px;
|
||||
font-size: 15px
|
||||
font-size: 15px;
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.post header {
|
||||
@@ -892,4 +894,17 @@ menu.tab-header.no-margin {
|
||||
|
||||
.message-post-list .post header {
|
||||
color: #969696;
|
||||
}
|
||||
#report-post-page p {
|
||||
text-align: center;
|
||||
}
|
||||
#report-post-page .report > div {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
#report-post-page .report > .textarea-text {
|
||||
width: 377px;
|
||||
margin: 4px;
|
||||
padding: 4px;
|
||||
}
|
||||
2
src/webfiles/ctr/css/juxt.min.css
vendored
2
src/webfiles/ctr/css/juxt.min.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,381 +1,440 @@
|
||||
/*eslint-env browser*/
|
||||
/*eslint no-var: "off"*/
|
||||
/*eslint @typescript-eslint/explicit-function-return-type: "off"*/
|
||||
var pjax;
|
||||
var updateCheck = setInterval(checkForUpdates, 30000);
|
||||
|
||||
cave.toolbar_setCallback(1, back)
|
||||
cave.toolbar_setCallback(99, back)
|
||||
cave.toolbar_setCallback(2, function() {
|
||||
cave.toolbar_setActiveButton(2);
|
||||
pjax.loadUrl('/feed');
|
||||
})
|
||||
cave.toolbar_setCallback(3, function() {
|
||||
cave.toolbar_setActiveButton(3);
|
||||
pjax.loadUrl('/titles');
|
||||
})
|
||||
cave.toolbar_setCallback(4, function() {
|
||||
cave.toolbar_setActiveButton(4);
|
||||
checkForUpdates();
|
||||
pjax.loadUrl('/news/my_news');
|
||||
})
|
||||
cave.toolbar_setCallback(5, function() {
|
||||
cave.toolbar_setActiveButton(5);
|
||||
pjax.loadUrl('/users/me')
|
||||
})
|
||||
cave.toolbar_setCallback(8, function() {
|
||||
setInterval(checkForUpdates, 30000);
|
||||
|
||||
cave.toolbar_setCallback(1, back);
|
||||
cave.toolbar_setCallback(99, back);
|
||||
cave.toolbar_setCallback(2, function () {
|
||||
cave.toolbar_setActiveButton(2);
|
||||
pjax.loadUrl('/feed');
|
||||
});
|
||||
cave.toolbar_setCallback(3, function () {
|
||||
cave.toolbar_setActiveButton(3);
|
||||
pjax.loadUrl('/titles');
|
||||
});
|
||||
cave.toolbar_setCallback(4, function () {
|
||||
cave.toolbar_setActiveButton(4);
|
||||
checkForUpdates();
|
||||
pjax.loadUrl('/news/my_news');
|
||||
});
|
||||
cave.toolbar_setCallback(5, function () {
|
||||
cave.toolbar_setActiveButton(5);
|
||||
pjax.loadUrl('/users/me');
|
||||
});
|
||||
cave.toolbar_setCallback(8, function () {});
|
||||
|
||||
function initPostModules() {
|
||||
var els = document.querySelectorAll("[data-module-show]");
|
||||
if (!els) return;
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].onclick = postModel;
|
||||
}
|
||||
function postModel(e) {
|
||||
var el = e.currentTarget,
|
||||
show = el.getAttribute("data-module-show"),
|
||||
hide = el.getAttribute("data-module-hide"),
|
||||
header = el.getAttribute("data-header"),
|
||||
sound = el.getAttribute("data-sound"),
|
||||
message = el.getAttribute("data-message"),
|
||||
screenshot = el.getAttribute("data-screenshot");
|
||||
if(sound) cave.snd_playSe(sound);
|
||||
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(screenshot) {
|
||||
var screenshotButton = document.getElementById('screenshot-button');
|
||||
if(!cave.capture_isEnabled()) {
|
||||
classList.add(screenshotButton, 'none');
|
||||
screenshotButton.onclick = null;
|
||||
}
|
||||
}
|
||||
if(message) {
|
||||
cave.toolbar_setWideButtonMessage(message);
|
||||
cave.toolbar_setMode(1);
|
||||
cave.toolbar_setButtonType(1);
|
||||
function tempBk() {
|
||||
document.getElementById("close-modal-button").click();
|
||||
}
|
||||
cave.toolbar_setCallback(1, tempBk);
|
||||
cave.toolbar_setCallback(99, tempBk);
|
||||
cave.toolbar_setCallback(8, function () {
|
||||
cave.toolbar_setMode(0);
|
||||
cave.toolbar_setButtonType(0);
|
||||
document.getElementById("submit").click();
|
||||
});
|
||||
var els = document.querySelectorAll('[data-module-show]');
|
||||
if (!els) return;
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].onclick = postModel;
|
||||
}
|
||||
function postModel(e) {
|
||||
var el = e.currentTarget;
|
||||
var show = el.getAttribute('data-module-show');
|
||||
var hide = el.getAttribute('data-module-hide');
|
||||
var header = el.getAttribute('data-header');
|
||||
var sound = el.getAttribute('data-sound');
|
||||
var message = el.getAttribute('data-message');
|
||||
var screenshot = el.getAttribute('data-screenshot');
|
||||
|
||||
}
|
||||
else {
|
||||
cave.toolbar_setMode(0);
|
||||
cave.toolbar_setButtonType(0);
|
||||
cave.toolbar_setCallback(1, back);
|
||||
cave.toolbar_setCallback(99, back);
|
||||
}
|
||||
cave.transition_end();
|
||||
initNewPost();
|
||||
}
|
||||
if (sound) cave.snd_playSe(sound);
|
||||
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 (screenshot) {
|
||||
var screenshotButton = document.getElementById('screenshot-button');
|
||||
if (!cave.capture_isEnabled()) {
|
||||
classList.add(screenshotButton, 'none');
|
||||
screenshotButton.onclick = null;
|
||||
}
|
||||
}
|
||||
function tempBk() {
|
||||
document.getElementById('close-modal-button').click();
|
||||
}
|
||||
if (message) {
|
||||
cave.toolbar_setWideButtonMessage(message);
|
||||
cave.toolbar_setMode(1);
|
||||
cave.toolbar_setButtonType(1);
|
||||
cave.toolbar_setCallback(1, tempBk);
|
||||
cave.toolbar_setCallback(99, tempBk);
|
||||
cave.toolbar_setCallback(8, function () {
|
||||
cave.toolbar_setMode(0);
|
||||
cave.toolbar_setButtonType(0);
|
||||
document.getElementById('submit').click();
|
||||
});
|
||||
} else {
|
||||
cave.toolbar_setMode(0);
|
||||
cave.toolbar_setButtonType(0);
|
||||
cave.toolbar_setCallback(1, back);
|
||||
cave.toolbar_setCallback(99, back);
|
||||
}
|
||||
cave.transition_end();
|
||||
initNewPost();
|
||||
}
|
||||
}
|
||||
function initMorePosts() {
|
||||
var els = document.querySelectorAll(".load-more[data-href]");
|
||||
if (!els) return;
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].addEventListener("click", function(e) {
|
||||
var el = e.currentTarget;
|
||||
cave.snd_playSe('SE_OLV_OK');
|
||||
GET(el.getAttribute('data-href'), function a(data) {
|
||||
var response = data.responseText;
|
||||
if(response && data.status === 200) {
|
||||
el.parentElement.outerHTML = response;
|
||||
initPosts();
|
||||
initMorePosts();
|
||||
}
|
||||
else
|
||||
el.parentElement.outerHTML = "";
|
||||
})
|
||||
|
||||
});
|
||||
}
|
||||
var els = document.querySelectorAll('.load-more[data-href]');
|
||||
if (!els) return;
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].addEventListener('click', function (e) {
|
||||
var el = e.currentTarget;
|
||||
cave.snd_playSe('SE_OLV_OK');
|
||||
GET(el.getAttribute('data-href'), function a(data) {
|
||||
var response = data.responseText;
|
||||
if (response && data.status === 200) {
|
||||
el.parentElement.outerHTML = response;
|
||||
initPosts();
|
||||
initMorePosts();
|
||||
} else el.parentElement.outerHTML = '';
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
function initPosts() {
|
||||
var els = document.querySelectorAll(".post-content[data-href]");
|
||||
if (!els) return;
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].addEventListener("click", function(e) {
|
||||
pjax.loadUrl(e.currentTarget.getAttribute('data-href'));
|
||||
});
|
||||
}
|
||||
initYeah();
|
||||
initSpoilers();
|
||||
var els = document.querySelectorAll('.post-content[data-href]');
|
||||
if (!els) return;
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].addEventListener('click', function (e) {
|
||||
pjax.loadUrl(e.currentTarget.getAttribute('data-href'));
|
||||
});
|
||||
}
|
||||
initYeah();
|
||||
initSpoilers();
|
||||
}
|
||||
function initYeah() {
|
||||
var els = document.querySelectorAll("button[data-post]");
|
||||
if (!els) return;
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].onclick = yeah;
|
||||
}
|
||||
function yeah(e) {
|
||||
var el = e.currentTarget, id = el.getAttribute("data-post");
|
||||
var parent = document.getElementById(id);
|
||||
var count = document.getElementById("count-" + id);
|
||||
el.disabled = true;
|
||||
var params = "postID=" + id;
|
||||
if(classList.contains(el, 'selected')) {
|
||||
classList.remove(el, 'selected');
|
||||
classList.remove(parent, 'yeah');
|
||||
if(count) count.innerText -= 1;
|
||||
cave.snd_playSe('SE_OLV_CANCEL');
|
||||
|
||||
}
|
||||
else {
|
||||
classList.add(el, 'selected');
|
||||
classList.add(parent, 'yeah');
|
||||
if(count) count.innerText = ++count.innerText;
|
||||
cave.snd_playSe('SE_OLV_MII_ADD');
|
||||
}
|
||||
POST('/posts/empathy', params, function a(data) {
|
||||
var post = JSON.parse(data.responseText);
|
||||
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
|
||||
return cave.error_callErrorViewer(155927);
|
||||
}
|
||||
el.disabled = false;
|
||||
if(count) count.innerText = post.count;
|
||||
});
|
||||
}
|
||||
var els = document.querySelectorAll('button[data-post]');
|
||||
if (!els) return;
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].onclick = yeah;
|
||||
}
|
||||
function yeah(e) {
|
||||
var el = e.currentTarget,
|
||||
id = el.getAttribute('data-post');
|
||||
var parent = document.getElementById(id);
|
||||
var count = document.getElementById('count-' + id);
|
||||
el.disabled = true;
|
||||
var params = 'postID=' + id;
|
||||
if (classList.contains(el, 'selected')) {
|
||||
classList.remove(el, 'selected');
|
||||
classList.remove(parent, 'yeah');
|
||||
if (count) count.innerText -= 1;
|
||||
cave.snd_playSe('SE_OLV_CANCEL');
|
||||
} else {
|
||||
classList.add(el, 'selected');
|
||||
classList.add(parent, 'yeah');
|
||||
if (count) count.innerText = ++count.innerText;
|
||||
cave.snd_playSe('SE_OLV_MII_ADD');
|
||||
}
|
||||
POST('/posts/empathy', params, function a(data) {
|
||||
var post = JSON.parse(data.responseText);
|
||||
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
|
||||
return cave.error_callErrorViewer(155927);
|
||||
}
|
||||
el.disabled = false;
|
||||
if (count) count.innerText = post.count;
|
||||
});
|
||||
}
|
||||
}
|
||||
function initSpoilers() {
|
||||
var els = document.querySelectorAll("button[data-post-id]");
|
||||
if (!els) return;
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].addEventListener("click", function(e) {
|
||||
var el = e.currentTarget;
|
||||
classList.remove(document.getElementById('post-' + el.getAttribute('data-post-id')), 'spoiler');
|
||||
document.getElementById('spoiler-' + el.getAttribute('data-post-id')).outerHTML = '';
|
||||
cave.snd_playSe('SE_OLV_OK');
|
||||
});
|
||||
}
|
||||
var els = document.querySelectorAll('button[data-post-id]');
|
||||
if (!els) return;
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].addEventListener('click', function (e) {
|
||||
var el = e.currentTarget;
|
||||
classList.remove(
|
||||
document.getElementById('post-' + el.getAttribute('data-post-id')),
|
||||
'spoiler'
|
||||
);
|
||||
document.getElementById(
|
||||
'spoiler-' + el.getAttribute('data-post-id')
|
||||
).outerHTML = '';
|
||||
cave.snd_playSe('SE_OLV_OK');
|
||||
});
|
||||
}
|
||||
}
|
||||
function initTabs() {
|
||||
var els = document.querySelectorAll(".tab-button");
|
||||
if (!els) return;
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].onclick = tabs;
|
||||
}
|
||||
function tabs(e) {
|
||||
e.preventDefault();
|
||||
cave.transition_begin();
|
||||
var el = e.currentTarget;
|
||||
var child = el.children[0];
|
||||
var els = document.querySelectorAll('.tab-button');
|
||||
if (!els) return;
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
els[i].onclick = tabs;
|
||||
}
|
||||
function tabs(e) {
|
||||
e.preventDefault();
|
||||
cave.transition_begin();
|
||||
var el = e.currentTarget;
|
||||
var child = el.children[0];
|
||||
|
||||
for(var i = 0; i < els.length; i++) {
|
||||
if(classList.contains(els[i], 'selected'))
|
||||
classList.remove(els[i], 'selected');
|
||||
}
|
||||
classList.add(el, "selected");
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
if (classList.contains(els[i], 'selected'))
|
||||
classList.remove(els[i], 'selected');
|
||||
}
|
||||
classList.add(el, 'selected');
|
||||
|
||||
GET(child.getAttribute('href') + "?pjax=true", function a(data) {
|
||||
var response = data.responseText;
|
||||
if(response && data.status === 200) {
|
||||
document.getElementsByClassName("tab-body")[0].innerHTML = response;
|
||||
pjax.history.push(child.href);
|
||||
initPosts();
|
||||
initMorePosts();
|
||||
cave.transition_end();
|
||||
}
|
||||
})
|
||||
GET(child.getAttribute('href') + '?pjax=true', function a(data) {
|
||||
var response = data.responseText;
|
||||
if (response && data.status === 200) {
|
||||
document.getElementsByClassName('tab-body')[0].innerHTML = response;
|
||||
pjax.history.push(child.href);
|
||||
initPosts();
|
||||
initMorePosts();
|
||||
cave.transition_end();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
function deletePost(post) {
|
||||
var id = post.getAttribute('data-post');
|
||||
if (!id) return;
|
||||
var confirm = cave.dialog_twoButton(
|
||||
'Delete Post',
|
||||
'Are you sure you want to delete your post? This cannot be undone.',
|
||||
'No',
|
||||
'Yes'
|
||||
);
|
||||
if (confirm) {
|
||||
DELETE('/posts/' + id, function a(data) {
|
||||
if (!data || data.status !== 200) {
|
||||
return cave.error_callFreeErrorViewer(
|
||||
'5980030',
|
||||
'Post was not able to be deleted. Please try again later.'
|
||||
);
|
||||
}
|
||||
console.log(data);
|
||||
alert('Post has been deleted.');
|
||||
return (window.location.href = data.responseText);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function reportPost(post) {
|
||||
var id = post.getAttribute('data-post');
|
||||
var button = document.getElementById('report-launcher');
|
||||
var form = document.getElementById('report-form');
|
||||
var formID = document.getElementById('report-post-id');
|
||||
if (!id || !button || !form || !formID) return;
|
||||
|
||||
form.action = '/posts/' + id + '/report';
|
||||
formID.value = id;
|
||||
button.click();
|
||||
}
|
||||
|
||||
function back() {
|
||||
if(!pjax.canGoBack())
|
||||
cave.toolbar_setButtonType(0);
|
||||
else
|
||||
pjax.back();
|
||||
if (!pjax.canGoBack()) cave.toolbar_setButtonType(0);
|
||||
else pjax.back();
|
||||
}
|
||||
|
||||
function stopLoading() {
|
||||
if(window.location.href.indexOf('/titles/show/first') !== -1)
|
||||
return;
|
||||
cave.transition_end();
|
||||
cave.lls_setItem('agree_olv', '1');
|
||||
cave.toolbar_setActiveButton(3);
|
||||
cave.snd_playBgm('BGM_CAVE_MAIN');
|
||||
cave.toolbar_setVisible(true);
|
||||
if (window.location.href.indexOf('/titles/show/first') !== -1) return;
|
||||
cave.transition_end();
|
||||
cave.lls_setItem('agree_olv', '1');
|
||||
cave.toolbar_setActiveButton(3);
|
||||
cave.snd_playBgm('BGM_CAVE_MAIN');
|
||||
cave.toolbar_setVisible(true);
|
||||
}
|
||||
|
||||
function initAll() {
|
||||
initPosts();
|
||||
initMorePosts();
|
||||
initPostModules();
|
||||
initTabs();
|
||||
checkForUpdates();
|
||||
pjax.refresh();
|
||||
initPosts();
|
||||
initMorePosts();
|
||||
initPostModules();
|
||||
initTabs();
|
||||
checkForUpdates();
|
||||
pjax.refresh();
|
||||
}
|
||||
|
||||
var PostStorage = {
|
||||
maxLocalStorageNum: 3,
|
||||
getPosts: function() {
|
||||
return PostStorage.getAll()[0];
|
||||
},
|
||||
getAll: function() {
|
||||
for (var e = {}, t = cave.lls_getCount(), i = new RegExp("^[0-9]+$"), o = 0, n = 0; n < t; n++) {
|
||||
var a = cave.lls_getKeyAt(n);
|
||||
i.test(a) && (e[a] = cave.lls_getItem(a), o += 1)
|
||||
}
|
||||
return [e, o]
|
||||
},
|
||||
getCount: function() {
|
||||
return PostStorage.getAll()[1]
|
||||
},
|
||||
setItem: function(e) {
|
||||
var t = (new Date).getTime();
|
||||
cave.lls_setItem(String(t), e)
|
||||
},
|
||||
removeItem: function(e) {
|
||||
var t = JSON.parse(cave.lls_getItem(e));
|
||||
t && t.screenShotKey && cave.lls_removeItem(t.screenShotKey), cave.lls_removeItem(e)
|
||||
},
|
||||
hasKey: function(e) {
|
||||
for (var t = cave.lls_getCount(), i = 0; i < t; i++)
|
||||
if (e === cave.lls_getKeyAt(i)) return !0;
|
||||
return !1
|
||||
},
|
||||
sweep: function() {
|
||||
var t = PostStorage.getAll(),
|
||||
i = t[0];
|
||||
if (t[1] > 0)
|
||||
for (var o in i) {
|
||||
var n = JSON.parse(cave.lls_getItem(o)).screenShotKey;
|
||||
n && !PostStorage.hasKey(n) && cave.lls_removeItem(o)
|
||||
}
|
||||
}
|
||||
}
|
||||
maxLocalStorageNum: 3,
|
||||
getPosts: function () {
|
||||
return PostStorage.getAll()[0];
|
||||
},
|
||||
getAll: function () {
|
||||
for (
|
||||
var e = {},
|
||||
t = cave.lls_getCount(),
|
||||
i = new RegExp('^[0-9]+$'),
|
||||
o = 0,
|
||||
n = 0;
|
||||
n < t;
|
||||
n++
|
||||
) {
|
||||
var a = cave.lls_getKeyAt(n);
|
||||
i.test(a) && ((e[a] = cave.lls_getItem(a)), (o += 1));
|
||||
}
|
||||
return [e, o];
|
||||
},
|
||||
getCount: function () {
|
||||
return PostStorage.getAll()[1];
|
||||
},
|
||||
setItem: function (e) {
|
||||
var t = new Date().getTime();
|
||||
cave.lls_setItem(String(t), e);
|
||||
},
|
||||
removeItem: function (e) {
|
||||
var t = JSON.parse(cave.lls_getItem(e));
|
||||
t && t.screenShotKey && cave.lls_removeItem(t.screenShotKey),
|
||||
cave.lls_removeItem(e);
|
||||
},
|
||||
hasKey: function (e) {
|
||||
for (var t = cave.lls_getCount(), i = 0; i < t; i++)
|
||||
if (e === cave.lls_getKeyAt(i)) return !0;
|
||||
return !1;
|
||||
},
|
||||
sweep: function () {
|
||||
var t = PostStorage.getAll(),
|
||||
i = t[0];
|
||||
if (t[1] > 0)
|
||||
for (var o in i) {
|
||||
var n = JSON.parse(cave.lls_getItem(o)).screenShotKey;
|
||||
n && !PostStorage.hasKey(n) && cave.lls_removeItem(o);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var classList = {
|
||||
contains: function (el, string) {
|
||||
return el.className.indexOf(string) !== -1;
|
||||
},
|
||||
add: function (el, string) {
|
||||
el.className += ' ' + string;
|
||||
},
|
||||
remove: function (el, string) {
|
||||
el.className = el.className.replace(string, '');
|
||||
}
|
||||
}
|
||||
contains: function (el, string) {
|
||||
return el.className.indexOf(string) !== -1;
|
||||
},
|
||||
add: function (el, string) {
|
||||
el.className += ' ' + string;
|
||||
},
|
||||
remove: function (el, string) {
|
||||
el.className = el.className.replace(string, '');
|
||||
},
|
||||
};
|
||||
function testOffline() {
|
||||
var posts = PostStorage.getAll();
|
||||
var text = JSON.stringify(posts, null,'\t');
|
||||
POST('/test', text, function() {window.alert('sent')});
|
||||
var posts = PostStorage.getAll();
|
||||
var text = JSON.stringify(posts, null, '\t');
|
||||
POST('/test', text, function () {
|
||||
window.alert('sent');
|
||||
});
|
||||
}
|
||||
|
||||
function checkForUpdates() {
|
||||
GET('/notifications.json', function updates(data) {
|
||||
var notificationObj = JSON.parse(data.responseText);
|
||||
var count = notificationObj.message_count + notificationObj.notification_count;
|
||||
cave.toolbar_setNotificationCount(count);
|
||||
});
|
||||
GET('/notifications.json', function updates(data) {
|
||||
var notificationObj = JSON.parse(data.responseText);
|
||||
var count =
|
||||
notificationObj.message_count + notificationObj.notification_count;
|
||||
cave.toolbar_setNotificationCount(count);
|
||||
});
|
||||
}
|
||||
|
||||
function newText() {
|
||||
classList.remove(document.getElementById('memo-sprite'), 'selected');
|
||||
classList.remove(document.getElementById('post-memo'), 'selected');
|
||||
classList.add(document.getElementById('text-sprite'), 'selected');
|
||||
classList.add(document.getElementById('post-text'), 'selected');
|
||||
classList.remove(document.getElementById('memo-sprite'), 'selected');
|
||||
classList.remove(document.getElementById('post-memo'), 'selected');
|
||||
classList.add(document.getElementById('text-sprite'), 'selected');
|
||||
classList.add(document.getElementById('post-text'), 'selected');
|
||||
}
|
||||
function newPainting(reset) {
|
||||
if(reset) cave.memo_clear();
|
||||
classList.remove(document.getElementById('text-sprite'), 'selected');
|
||||
classList.remove(document.getElementById('post-text'), 'selected');
|
||||
classList.add(document.getElementById('memo-sprite'), 'selected');
|
||||
classList.add(document.getElementById('post-memo'), 'selected');
|
||||
cave.memo_open();
|
||||
setTimeout(function () {
|
||||
if(cave.memo_hasValidImage()) {
|
||||
document.getElementById('memo').src = 'data:image/png;base64,' + cave.memo_getImageBmp();
|
||||
document.getElementById('memo-value').value = cave.memo_getImageBmp();
|
||||
}
|
||||
}, 250);
|
||||
if (reset) cave.memo_clear();
|
||||
classList.remove(document.getElementById('text-sprite'), 'selected');
|
||||
classList.remove(document.getElementById('post-text'), 'selected');
|
||||
classList.add(document.getElementById('memo-sprite'), 'selected');
|
||||
classList.add(document.getElementById('post-memo'), 'selected');
|
||||
cave.memo_open();
|
||||
setTimeout(function () {
|
||||
if (cave.memo_hasValidImage()) {
|
||||
document.getElementById('memo').src =
|
||||
'data:image/png;base64,' + cave.memo_getImageBmp();
|
||||
document.getElementById('memo-value').value = cave.memo_getImageBmp();
|
||||
}
|
||||
}, 250);
|
||||
}
|
||||
|
||||
function newScreenshot(topScreen) {
|
||||
var screenshot = topScreen ? cave.capture_getLowerImage();
|
||||
var screenshot = topScreen
|
||||
? cave.capture_getLowerImage()
|
||||
: cave.capture_getUpperImage();
|
||||
}
|
||||
|
||||
function follow(el) {
|
||||
var id = el.getAttribute("data-community-id");
|
||||
var count = document.getElementById("followers");
|
||||
el.disabled = true;
|
||||
var params = "id=" + id;
|
||||
if(classList.contains(el, 'selected')) {
|
||||
classList.remove(el, 'selected');
|
||||
cave.snd_playSe('SE_OLV_CANCEL');
|
||||
}
|
||||
else {
|
||||
classList.add(el, 'selected');
|
||||
cave.snd_playSe('SE_OLV_MII_ADD');
|
||||
}
|
||||
var id = el.getAttribute('data-community-id');
|
||||
var count = document.getElementById('followers');
|
||||
el.disabled = true;
|
||||
var params = 'id=' + id;
|
||||
if (classList.contains(el, 'selected')) {
|
||||
classList.remove(el, 'selected');
|
||||
cave.snd_playSe('SE_OLV_CANCEL');
|
||||
} else {
|
||||
classList.add(el, 'selected');
|
||||
cave.snd_playSe('SE_OLV_MII_ADD');
|
||||
}
|
||||
|
||||
POST(el.getAttribute("data-url"), params, function a(data) {
|
||||
var element = JSON.parse(data.responseText);
|
||||
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 cave.error_callErrorViewer(155927);
|
||||
}
|
||||
el.disabled = false;
|
||||
count.innerText = element.count;
|
||||
});
|
||||
POST(el.getAttribute('data-url'), params, function a(data) {
|
||||
var element = JSON.parse(data.responseText);
|
||||
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 cave.error_callErrorViewer(155927);
|
||||
}
|
||||
el.disabled = false;
|
||||
count.innerText = element.count;
|
||||
});
|
||||
}
|
||||
|
||||
function POST(url, data, callback) {
|
||||
cave.transition_begin()
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if(this.readyState === 4) {
|
||||
cave.transition_end();
|
||||
return callback(this);
|
||||
}
|
||||
}
|
||||
xhttp.open("POST", url, true);
|
||||
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
xhttp.send(data);
|
||||
cave.transition_begin();
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function () {
|
||||
if (this.readyState === 4) {
|
||||
cave.transition_end();
|
||||
return callback(this);
|
||||
}
|
||||
};
|
||||
xhttp.open('POST', url, true);
|
||||
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
||||
xhttp.send(data);
|
||||
}
|
||||
function GET(url, callback) {
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if(this.readyState === 4) {
|
||||
return callback(this);
|
||||
}
|
||||
};
|
||||
xhttp.open("GET", url, true);
|
||||
xhttp.send();
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function () {
|
||||
if (this.readyState === 4) {
|
||||
return callback(this);
|
||||
}
|
||||
};
|
||||
xhttp.open('GET', url, true);
|
||||
xhttp.send();
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
pjax = Pjax.init({
|
||||
elements: "a[data-pjax]",
|
||||
selectors: ["title", "#body"]
|
||||
})
|
||||
console.debug("Pjax initialized.", pjax);
|
||||
initAll();
|
||||
stopLoading();
|
||||
function DELETE(url, callback) {
|
||||
cave.transition_begin();
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState === 4) {
|
||||
cave.transition_end();
|
||||
return callback(this);
|
||||
}
|
||||
};
|
||||
xhttp.open('DELETE', url, true);
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
pjax = Pjax.init({
|
||||
elements: 'a[data-pjax]',
|
||||
selectors: ['title', '#body'],
|
||||
});
|
||||
console.debug('Pjax initialized.', pjax);
|
||||
initAll();
|
||||
stopLoading();
|
||||
});
|
||||
document.addEventListener("PjaxRequest", function(e) {
|
||||
console.log(e);
|
||||
cave.transition_begin();
|
||||
document.addEventListener('PjaxRequest', function (e) {
|
||||
console.log(e);
|
||||
cave.transition_begin();
|
||||
});
|
||||
document.addEventListener("PjaxLoaded", function(e) { console.log(e);});
|
||||
document.addEventListener("PjaxDone", function(e) {
|
||||
initAll();
|
||||
cave.brw_scrollImmediately(0,0);
|
||||
if(pjax.canGoBack())
|
||||
cave.toolbar_setButtonType(1);
|
||||
else
|
||||
cave.toolbar_setButtonType(0);
|
||||
cave.transition_end();
|
||||
document.addEventListener('PjaxLoaded', function (e) {
|
||||
console.log(e);
|
||||
});
|
||||
document.addEventListener('PjaxDone', function (e) {
|
||||
initAll();
|
||||
cave.brw_scrollImmediately(0, 0);
|
||||
if (pjax.canGoBack()) cave.toolbar_setButtonType(1);
|
||||
else cave.toolbar_setButtonType(0);
|
||||
cave.transition_end();
|
||||
});
|
||||
|
||||
2
src/webfiles/ctr/js/juxt.min.js
vendored
2
src/webfiles/ctr/js/juxt.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -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;
|
||||
}
|
||||
@@ -42,7 +42,7 @@
|
||||
</div>
|
||||
<div class="image-selector dropdown">
|
||||
<button id="screenshot-button" type="button" data-toggle="dropdown" class="dropdown-toggle" data-sound="SE_WAVE_BALLOON_OPEN"
|
||||
onclick="window.alert(cave.capture_getLowerImage())">
|
||||
onclick="window.alert('Screenshots are not ready yet. Check back soon!')">
|
||||
<img class="preview-image sprite" src="">
|
||||
</button>
|
||||
<input id="screenshot-value" type="hidden" name="screenshot" value="">
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
data-sound="SE_WAVE_SELECT_TAB" data-module-hide="post"
|
||||
data-module-show="add-post-page" data-header="false" data-screenshot="true"
|
||||
data-message="Reply to <%= post.screen_name %>">Reply +</a>
|
||||
<%}%>
|
||||
<% if(post.pid === pid) {%>
|
||||
<a id="header-communities-button" class="delete header-button right" href="#" data-post="<%=post.id%>" onclick="deletePost(this)">Delete Post</a>
|
||||
<%} else {%>
|
||||
<a id="report-launcher" style="display: none" data-module-hide="post" data-module-show="report-post-page" data-header="false" data-menu="false"></a>
|
||||
<a id="header-communities-button" class="report header-button right" href="#" data-post="<%= post.id %>" onclick="reportPost(this)">Report Post</a>
|
||||
<%}%>
|
||||
</header>
|
||||
<div class="body-content tab2-content" id="post">
|
||||
@@ -23,6 +29,41 @@
|
||||
<% if(((community.allows_comments && community.open) || (community.admins && community.admins.indexOf(pid) !== -1)) && userSettings.pid !== 1000000000 && userSettings.account_status === 0) {%>
|
||||
<%- include('partials/new_post', { pid, lang, id: post.community_id, name: post.screen_name, url: `/posts/${post.id}/new`, show: 'post', message_pid: '' }); %>
|
||||
<%}%>
|
||||
<div id="report-post-page" class="add-post-page official-user-post" style="display: none">
|
||||
<header class="add-post-page-header" id="header">
|
||||
<h1 id="page-title">Report Post</h1>
|
||||
</header>
|
||||
<form method="post" action="/posts/<%=post.id%>/report" id="report-form" class="post" name="report" data-is-own-title="1" data-is-identified="1">
|
||||
<input type="hidden" name="post_id" id="report-post-id" value="<%= post.id %>"/>
|
||||
<div class="add-post-page-content report">
|
||||
<p>
|
||||
You are about to report a post with content which violates the Juxtaposition Code of Conduct.
|
||||
This report will be sent to Pretendo's Juxtaposition administrators and not to the creator of the post.
|
||||
</p>
|
||||
<div>
|
||||
<h4>Violation Type:</h4>
|
||||
<select name="reason" id="report">
|
||||
<option value="0">Spoiler</option>
|
||||
<option value="1">Personal Information</option>
|
||||
<option value="2">Violent Content</option>
|
||||
<option value="3">Inappropriate/Harmful Conduct</option>
|
||||
<option value="4">Hateful/Bullying</option>
|
||||
<option value="5">Advertising</option>
|
||||
<option value="6">Sexually Explicit</option>
|
||||
<option value="7">Piracy</option>
|
||||
<option value="8">Inappropriate Behavior in Game</option>
|
||||
<option value="9">Other</option>
|
||||
</select>
|
||||
</div>
|
||||
<textarea name="message" class="textarea-text" value="" maxlength="280" placeholder="Enter additional comments or information"></textarea>
|
||||
</div>
|
||||
<input type="button" class="olv-modal-close-button fixed-bottom-button left"
|
||||
value="Cancel" data-sound="SE_WAVE_CANCEL"
|
||||
data-module-show="post" data-module-hide="report-post-page"
|
||||
data-header="true" data-menu="true">
|
||||
<input type="submit" class="post-button fixed-bottom-button" value="Submit">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<% var banned = (userContent.account_status < 0 || userContent.account_status > 1 || pnid.accessLevel < 0); %></0>
|
||||
<%- include('partials/head', { title: pnid.mii.name }); %>
|
||||
<body>
|
||||
<div id="body">
|
||||
@@ -7,11 +8,12 @@
|
||||
<h1 id="page-title" class="community">
|
||||
<span>
|
||||
<span class="icon-container">
|
||||
<img src="http://mii.olv.pretendo.cc/mii/<%=pnid.pid%>/normal_face.png" class="icon">
|
||||
<img src="<%if (banned || pnid.deleted) { %><%= cdnURL %>/images/bandwidthlost.png<% } else { %>https://mii.olv.pretendo.cc/mii/<%=pnid.pid%>/normal_face.png<%}%>" class="icon">
|
||||
</span>
|
||||
<span class="community-name">
|
||||
<%= pnid.mii.name %> - @<%= pnid.username %>
|
||||
<% if(banned) { %>Banned User<% } else if(pnid.deleted){%>Deleted User<%} else {%><%= pnid.mii.name %> @<%= pnid.username %><%}%>
|
||||
</span>
|
||||
<%if(!pnid.deleted && !banned) {%>
|
||||
<span class="text">
|
||||
<span>
|
||||
<span class="sprite posts"></span>
|
||||
@@ -22,19 +24,21 @@
|
||||
<span id="followers"><%= userContent.following_users.length - 1 %></span>
|
||||
</span>
|
||||
</span>
|
||||
<% } %>
|
||||
</span>
|
||||
</span>
|
||||
</h1>
|
||||
<%if(pnid.pid === pid) {%>
|
||||
<a id="header-communities-button" class="header-button left" href="/users/me/settings" data-pjax="#body">Settings</a>
|
||||
<%}%>
|
||||
<%if(pnid.pid !== pid) {%>
|
||||
<%if(pnid.pid !== pid && !pnid.deleted && !banned) {%>
|
||||
<button type="button" class="submit follow yeah-button <%if(parentUserContent.followed_users.indexOf(userContent.pid) !== -1){ %>selected<%}%>" onclick="follow(this)" data-sound="SE_WAVE_CHECKBOX_UNCHECK" data-url="/users/follow" data-community-id="<%=pnid.pid%>">
|
||||
<span class="sprite yeah"></span>
|
||||
</button>
|
||||
<%}%>
|
||||
</header>
|
||||
<div class="body-content tab2-content" id="community-post-list">
|
||||
<%if(!pnid.deleted && !banned) {%>
|
||||
<menu class="tab-header user-page no-margin">
|
||||
<li id="tab-header-post" class="tab-button <%if(selection === 0){ %>selected<%}%>">
|
||||
<a href="<%= link %>" data-sound="SE_WAVE_SELECT_TAB">
|
||||
@@ -73,6 +77,7 @@
|
||||
<div class="tab-body post-list">
|
||||
<%- include('partials/' + template, { bundle }); %>
|
||||
</div>
|
||||
<%}%>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable */
|
||||
var scrollPosition, pjax;
|
||||
var updateCheck = setInterval(checkForUpdates, 30000);
|
||||
var inputCheck = setInterval(input, 100);
|
||||
@@ -338,9 +339,11 @@ function reportPost(post) {
|
||||
var id = post.getAttribute('data-post');
|
||||
var button = document.getElementById('report-launcher');
|
||||
var form = document.getElementById('report-form');
|
||||
if(!id || !button || !form) return;
|
||||
var formID = document.getElementById('report-post-id');
|
||||
if(!id || !button || !form || !formID) return;
|
||||
|
||||
form.action = '/posts/' + id + '/report';
|
||||
formID.value = id;
|
||||
console.log(id.replace(/(\d{3})(\d{4})(\d{3})(\d{4})(\d{3})(\d{4})/, "$1-$2-$3-$4-$5-$6"));
|
||||
button.click();
|
||||
}
|
||||
|
||||
2
src/webfiles/portal/js/juxt.min.js
vendored
2
src/webfiles/portal/js/juxt.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -66,7 +66,7 @@
|
||||
<menu class="textarea-menu">
|
||||
<li class="textarea-menu-text">
|
||||
<input type="radio" name="_post_type" value="body" checked data-sound="">
|
||||
<textarea name="body" class="textarea-text" value="" maxlength="280" placeholder="Enter text here..."></textarea>
|
||||
<textarea name="body" class="textarea-text" value="" maxlength="280" placeholder="Enter text here..." onchange="if(wiiuFilter.checkWord(this.value) === -2) { this.value = ''; alert('<%= lang.user_settings.swearing %>');}"></textarea>
|
||||
</li>
|
||||
<li class="textarea-menu-memo">
|
||||
<input type="radio" name="_post_type" value="painting" data-sound="" onclick="newPainting(false)">
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<% if(locals.mainPost === undefined) locals.mainPost = false; %>
|
||||
<div id="post-<%= post.id %>" class="post <%if(reply) {%>reply<%}%> <%if(post.is_spoiler) {%>spoiler<%}%>">
|
||||
<% if(post.removed) {%>
|
||||
<div class="post-body-content removed">
|
||||
@@ -53,7 +54,7 @@
|
||||
</div>
|
||||
<div class="post-buttons">
|
||||
<button type="button" class="submit yeah-button <%if(post.yeahs && post.yeahs.indexOf(userContent.pid) !== -1){ %> selected <%}%>" data-post="<%= post.id %>"></button>
|
||||
<a <%if(!yeah && !reply) {%>href="/posts/<%= post.id %>"<%}%> class="to-permalink-button" data-pjax="#body">
|
||||
<a <%if(!reply) {%>href="/posts/<%= post.id %>"<%}%> class="to-permalink-button" data-pjax="#body">
|
||||
<% if(reply && post.pid !== pid && !moderator) {%>
|
||||
<div>
|
||||
<button type="button" class="submit report" data-post="<%= post.id %>" onclick="reportPost(this)"></button>
|
||||
@@ -64,7 +65,7 @@
|
||||
<button type="button" class="submit remove" data-post="<%= post.id %>" onclick="deletePost(this)"></button>
|
||||
</div>
|
||||
<%}%>
|
||||
<%if(!yeah) {%>
|
||||
<%if(!mainPost) {%>
|
||||
<span class="feeling" id="count-<%= post.id %>"><%=post.empathy_count %></span>
|
||||
<%if(!reply) {%>
|
||||
<span class="reply"><%=post.reply_count %></span>
|
||||
@@ -74,12 +75,13 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%if(yeah && post.yeahs.length > 0) {%>
|
||||
<%if(locals.mainPost && post.yeahs.length > 0) {%>
|
||||
<h6 class="yeah-text"><span class="feeling" id="count-<%= post.id %>"><%=post.empathy_count %></span> people gave this post a yeah.</h6>
|
||||
<div class="yeah-list">
|
||||
<%for(var yeah of post.yeahs) {%>
|
||||
<a href="/users/<%= yeah %>" class="mii-icon-container" data-pjax="#body">
|
||||
<img src="https://mii.olv.pretendo.cc/mii/<%= yeah %>/normal_face.png" class="mii-icon">
|
||||
<% var yeahCount = post.yeahs.length > 10 ? 10 : post.yeahs.length %>
|
||||
<%for(var i = 0; i < yeahCount; i++) {%>
|
||||
<a href="/users/<%= post.yeahs[i] %>" class="mii-icon-container" data-pjax="#body">
|
||||
<img src="https://mii.olv.pretendo.cc/mii/<%= post.yeahs[i] %>/normal_face.png" class="mii-icon">
|
||||
</a>
|
||||
<%}%>
|
||||
</div>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<% if(((community.allows_comments && community.open) || (community.admins && community.admins.indexOf(pid) !== -1)) && userSettings.pid !== 1000000000 && userSettings.account_status === 0) {%>
|
||||
<a id="header-post-button" class="header-button" href="#" data-module-hide="post" data-module-show="add-post-page" data-header="false" data-menu="false">Reply</a>
|
||||
<%}%>
|
||||
<% if(post.pid === pid || moderator) {%>
|
||||
<% if(post.pid === pid) {%>
|
||||
<a id="header-communities-button" class="delete" href="#" data-post="<%=post.id%>" onclick="deletePost(this)">Delete Post</a>
|
||||
<%} else {%>
|
||||
<a id="report-launcher" style="display: none" data-module-hide="post" data-module-show="report-post-page" data-header="false" data-menu="false"></a>
|
||||
@@ -26,7 +26,7 @@
|
||||
</header>
|
||||
<div class="body-content post-list" id="post">
|
||||
<div class="post-wrapper parent">
|
||||
<%- include('partials/post_template', { post: post, mii_image_CDN: mii_image_CDN, lang: lang, reply: false, pid: pid, yeah: true }); %>
|
||||
<%- include('partials/post_template', { post: post, mii_image_CDN: mii_image_CDN, lang: lang, reply: false, pid: pid, mainPost: true }); %>
|
||||
</div>
|
||||
<% replies.forEach(function(post) { %>
|
||||
<%- include('partials/post_template', { post: post, mii_image_CDN: mii_image_CDN, lang: lang, reply: true, pid: pid }); %>
|
||||
@@ -40,7 +40,7 @@
|
||||
<h1 class="page-title">Report Post</h1>
|
||||
</header>
|
||||
<form method="post" action="/posts/<%=post.id%>/report" id="report-form" name="report" data-is-own-title="1" data-is-identified="1">
|
||||
<input type="hidden" name="post_id" value="<%= post.id %>"/>
|
||||
<input type="hidden" name="post_id" id="report-post-id" value="<%= post.id %>"/>
|
||||
<div class="add-post-page-content report">
|
||||
<p>
|
||||
You are about to report a post with content which violates the Juxtaposition Code of Conduct.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<% var banned = (userContent.account_status < 0 || userContent.account_status > 1 || pnid.accessLevel < 0); %></0>
|
||||
<%- include('partials/head', { title: pnid.mii.name }); %>
|
||||
<body>
|
||||
<%- include('partials/nav_bar', { selection: -1, pid: pid }); %>
|
||||
@@ -14,16 +15,16 @@
|
||||
<img src="<%= cdnURL %>/images/banner.png" class="header-banner with-top-button">
|
||||
</div>
|
||||
<div class="community-info info-content with-header-banner">
|
||||
<span class="icon-container"><img src="<%if(pnid.deleted){%><%= cdnURL %>/images/bandwidthlost.png<%}else{%>https://mii.olv.pretendo.cc/mii/<%=pnid.pid%>/normal_face.png<%}%>" class="icon" alt=""></span>
|
||||
<%if(pnid.pid !== pid && !pnid.deleted) {%>
|
||||
<span class="icon-container"><img src="<%if (banned || pnid.deleted) { %><%= cdnURL %>/images/bandwidthlost.png<% } else { %>https://mii.olv.pretendo.cc/mii/<%=pnid.pid%>/normal_face.png<%}%>" class="icon" alt=""></span>
|
||||
<%if(pnid.pid !== pid && !pnid.deleted && !(banned)) {%>
|
||||
<a href="#" class="favorite-button favorite-button-mini button <%if(parentUserContent.followed_users.indexOf(userContent.pid) !== -1){ %>checked<%}%>" onclick="follow(this)" data-sound="SE_WAVE_CHECKBOX_UNCHECK" data-url="/users/follow" data-community-id="<%=pnid.pid%>"></a>
|
||||
<%if(friends.indexOf(pid) !== -1) { /*Is mutual*/%>
|
||||
<a href="/friend_messages/new/<%=userContent.pid%>" class="message-button favorite-button-mini button" data-sound="SE_WAVE_CHECKBOX_UNCHECK"></a>
|
||||
<%}%>
|
||||
<%}%>
|
||||
<span class="title"><%if(pnid.deleted){%>Deleted User<%} else {%><%= pnid.mii.name %><%}%></span>
|
||||
<span class="title"><% if(banned) { %>Banned User<% } else if(pnid.deleted){%>Deleted User<%} else {%><%= pnid.mii.name %><%}%></span>
|
||||
<span class="text">
|
||||
<%if(!pnid.deleted){%>
|
||||
<%if(!pnid.deleted && !(banned)){%>
|
||||
<span>
|
||||
@<%= pnid.username %>
|
||||
</span>
|
||||
@@ -104,7 +105,7 @@
|
||||
<%}%>
|
||||
</span>
|
||||
</div>
|
||||
<%if(!pnid.deleted){%>
|
||||
<%if(!pnid.deleted && !(banned)){%>
|
||||
<menu class="tab-header user-page">
|
||||
<li id="tab-header-post" class="tab-button <%if(selection === 0){ %>selected<%}%>">
|
||||
<a href="<%= link %>" data-sound="SE_WAVE_SELECT_TAB">
|
||||
|
||||
67
src/webfiles/web/css/first_run.css
Normal file
67
src/webfiles/web/css/first_run.css
Normal file
@@ -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%;
|
||||
}
|
||||
}
|
||||
@@ -156,18 +156,20 @@ form.account.register div:last-child {
|
||||
|
||||
#toast {
|
||||
opacity: 0;
|
||||
min-width: 250px;
|
||||
margin-left: -141px;
|
||||
background-color: #A9375B;
|
||||
color: var(--text);
|
||||
text-align: center;
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
left: 50%;
|
||||
bottom: 5em;
|
||||
border-radius: 1em;
|
||||
padding: 1ch;
|
||||
transition: all 0.5s ease;
|
||||
min-width: 250px;
|
||||
background-color: #A9375B;
|
||||
color: var(--text);
|
||||
text-align: center;
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
left: 50%;
|
||||
bottom: 5em;
|
||||
border-radius: 1em;
|
||||
padding: 1ch;
|
||||
transition: all 0.5s ease;
|
||||
transform: translate(-50%);
|
||||
max-width: 80%;
|
||||
white-space: break-spaces;
|
||||
}
|
||||
|
||||
#toast.show {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
2
src/webfiles/web/css/web.min.css
vendored
2
src/webfiles/web/css/web.min.css
vendored
File diff suppressed because one or more lines are too long
@@ -42,11 +42,49 @@
|
||||
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap" rel="stylesheet">
|
||||
|
||||
<link rel="stylesheet" href="/css/login.css">
|
||||
<link rel="stylesheet" href="/css/first_run.css">
|
||||
<script src="/js/pjax.min.js"></script>
|
||||
<script src="/js/web.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="main-body">
|
||||
<link rel="stylesheet" href="/css/login.css">
|
||||
|
||||
<script>
|
||||
var experience = 0;
|
||||
var notifications = false;
|
||||
function selectExperience(type) {
|
||||
document.getElementById('beginner').classList.remove('selected');
|
||||
document.getElementById('intermediate').classList.remove('selected');
|
||||
document.getElementById('expert').classList.remove('selected');
|
||||
switch (type) {
|
||||
case 0:
|
||||
document.getElementById("beginner").classList.add('selected');
|
||||
experience = 0;
|
||||
break;
|
||||
case 1:
|
||||
document.getElementById("intermediate").classList.add('selected');
|
||||
experience = 1;
|
||||
break;
|
||||
case 2:
|
||||
document.getElementById("expert").classList.add('selected');
|
||||
experience = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
function submit() {
|
||||
var xmlhttp = new XMLHttpRequest(); // new HttpRequest instance
|
||||
var theUrl = "/titles/show/newUser";
|
||||
xmlhttp.open("POST", theUrl);
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (this.readyState === 4 && (this.status === 423 || this.status === 404 || this.status === 504)) {
|
||||
alert('Unable to complete setup, the server is likely having issues.\n\nPlease try again later.');
|
||||
}
|
||||
}
|
||||
xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
||||
xmlhttp.send(JSON.stringify({ "experience": experience, "notifications": notifications }));
|
||||
}
|
||||
</script>
|
||||
<div class="wrapper">
|
||||
<div class="account-form-wrapper">
|
||||
<a class="logotype" href="/">
|
||||
@@ -66,8 +104,180 @@
|
||||
</g>
|
||||
</svg>
|
||||
</a>
|
||||
<h2>Account setup is currently only available on the Wii U or 3DS</h2>
|
||||
<h3>You can get started with Pretendo on your console <a href="https://pretendo.network/docs/install/juxt">here.</a></h3>
|
||||
<div id="welcome" class="about-wrapper background" style="display: flex">
|
||||
<h1 class="about-header"><%= lang.setup.welcome %></h1>
|
||||
<div class="about-body">
|
||||
<p>
|
||||
<%= lang.setup.welcome_text %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="button-wrapper">
|
||||
<input type="button" class="post-button fixed-bottom-button"
|
||||
value="<%= lang.global.next %>" data-sound="SE_WAVE_MENU"
|
||||
data-module-show="beta" data-module-hide="welcome"
|
||||
data-header="false" data-menu="false">
|
||||
</div>
|
||||
</div>
|
||||
<div id="beta" class="about-wrapper background">
|
||||
<h1 class="about-header"><%= lang.setup.beta %></h1>
|
||||
<div class="about-body" style="position: relative">
|
||||
<p>
|
||||
<%= lang.setup.beta_text.first %>
|
||||
<br>
|
||||
<b><u><%= lang.setup.beta_text.second %></u></b>
|
||||
<br>
|
||||
<%= lang.setup.beta_text.third %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="button-wrapper">
|
||||
<input type="button" class="fixed-bottom-button left"
|
||||
value="<%= lang.global.back %>" data-sound="SE_WAVE_CANCEL"
|
||||
data-module-show="welcome" data-module-hide="beta"
|
||||
data-header="false" data-menu="false">
|
||||
<input type="button" class="post-button fixed-bottom-button"
|
||||
value="<%= lang.global.next %>" data-sound="SE_WAVE_MENU"
|
||||
data-module-show="about" data-module-hide="beta"
|
||||
data-header="false" data-menu="false">
|
||||
</div>
|
||||
</div>
|
||||
<div id="about" class="about-wrapper background">
|
||||
<h1 class="about-header"><%= lang.setup.info %></h1>
|
||||
<div class="about-body">
|
||||
<p>
|
||||
<%= lang.setup.info_text %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="button-wrapper">
|
||||
<input type="button" class="fixed-bottom-button left"
|
||||
value="<%= lang.global.back %>" data-sound="SE_WAVE_CANCEL"
|
||||
data-module-show="beta" data-module-hide="about"
|
||||
data-header="false" data-menu="false">
|
||||
<input type="button" class="post-button fixed-bottom-button"
|
||||
value="<%= lang.global.next %>" data-sound="SE_WAVE_MENU"
|
||||
data-module-show="manners" data-module-hide="about"
|
||||
data-header="false" data-menu="false">
|
||||
</div>
|
||||
</div>
|
||||
<div id="manners" class="background">
|
||||
<h1 class="about-header"><%= lang.setup.rules %></h1>
|
||||
<div class="about-body" style="position: relative">
|
||||
<p>
|
||||
<%= lang.setup.rules_text.first %>
|
||||
<br><br>
|
||||
<div class="headline">
|
||||
<h2><%= lang.setup.rules_text.second %></h2>
|
||||
</div>
|
||||
<%= lang.setup.rules_text.third %>
|
||||
<br><br>
|
||||
<div class="headline">
|
||||
<h2><%= lang.setup.rules_text.fourth %></h2>
|
||||
</div>
|
||||
<%= lang.setup.rules_text.fifth %>
|
||||
<br><br>
|
||||
<div class="headline">
|
||||
<h2><%= lang.setup.rules_text.sixth %></h2>
|
||||
</div>
|
||||
<%= lang.setup.rules_text.seventh %>
|
||||
<br><br>
|
||||
<div class="headline">
|
||||
<h2><%= lang.setup.rules_text.eighth %></h2>
|
||||
</div>
|
||||
<%= lang.setup.rules_text.ninth %>
|
||||
<br><br>
|
||||
<div class="headline">
|
||||
<h2><%= lang.setup.rules_text.tenth %></h2>
|
||||
</div>
|
||||
<%= lang.setup.rules_text.eleventh %>
|
||||
<br><br>
|
||||
<div class="headline">
|
||||
<h2><%= lang.setup.rules_text.twelfth %></h2>
|
||||
</div>
|
||||
<%= lang.setup.rules_text.thirteenth %>
|
||||
<br><br>
|
||||
</p>
|
||||
</div>
|
||||
<div class="button-wrapper">
|
||||
<input type="button" class="fixed-bottom-button left"
|
||||
value="<%= lang.global.back %>" data-sound="SE_WAVE_CANCEL"
|
||||
data-module-show="about" data-module-hide="manners"
|
||||
data-header="false" data-menu="false">
|
||||
<input type="button" class="post-button fixed-bottom-button"
|
||||
value="<%= lang.global.next %>" data-sound="SE_WAVE_MENU"
|
||||
data-module-show="google-analytics" data-module-hide="manners"
|
||||
data-header="false" data-menu="false">
|
||||
</div>
|
||||
</div>
|
||||
<div id="google-analytics" class="about-wrapper background">
|
||||
<h1 class="about-header"><%= lang.setup.google %></h1>
|
||||
<div class="about-body">
|
||||
<p>
|
||||
<%= lang.setup.google_text %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="button-wrapper">
|
||||
<input type="button" class="fixed-bottom-button left"
|
||||
value="<%= lang.global.back %>" data-sound="SE_WAVE_CANCEL"
|
||||
data-module-show="manners" data-module-hide="google-analytics"
|
||||
data-header="false" data-menu="false">
|
||||
<input type="button" class="post-button fixed-bottom-button"
|
||||
value="<%= lang.global.next %>" data-sound="SE_WAVE_MENU"
|
||||
data-module-show="game-experience" data-module-hide="google-analytics"
|
||||
data-header="false" data-menu="false">
|
||||
</div>
|
||||
</div>
|
||||
<div id="game-experience" class="about-wrapper background">
|
||||
<h1 class="about-header"><%= lang.setup.experience %></h1>
|
||||
<div class="about-body">
|
||||
<p>
|
||||
<%= lang.setup.experience_text.info %>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<ul class="horizontal-list">
|
||||
<li id="beginner" onclick="selectExperience(0)" class="selected"><a href="#"><%= lang.setup.experience_text.beginner %></a></li>
|
||||
<li id="intermediate" onclick="selectExperience(1)"><a href="#"><%= lang.setup.experience_text.intermediate %></a></li>
|
||||
<li id="expert" onclick="selectExperience(2)"><a href="#"><%= lang.setup.experience_text.expert %></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="button-wrapper">
|
||||
<input type="button" class="fixed-bottom-button left"
|
||||
value="<%= lang.global.back %>" data-sound="SE_WAVE_CANCEL"
|
||||
data-module-show="google-analytics" data-module-hide="game-experience"
|
||||
data-header="false" data-menu="false">
|
||||
<input type="button" class="post-button fixed-bottom-button"
|
||||
value="<%= lang.global.next %>" data-sound="SE_WAVE_MENU"
|
||||
data-module-show="ready" data-module-hide="game-experience"
|
||||
data-header="false" data-menu="false">
|
||||
</div>
|
||||
</div>
|
||||
<div id="ready" class="about-wrapper background">
|
||||
<h1 class="about-header"><%= lang.setup.ready %></h1>
|
||||
<div class="about-body">
|
||||
<p>
|
||||
<%= lang.setup.ready_text %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="button-wrapper">
|
||||
<input type="button" class="fixed-bottom-button left"
|
||||
value="<%= lang.global.back %>" data-sound="SE_WAVE_CANCEL"
|
||||
data-module-show="game-experience" data-module-hide="ready"
|
||||
data-header="false" data-menu="false">
|
||||
<input type="button" class="post-button fixed-bottom-button"
|
||||
value="<%= lang.global.next %>" data-sound="GL_OLV_INIT_END"
|
||||
data-module-show="have-fun" data-module-hide="ready"
|
||||
data-header="false" data-menu="false" onclick="submit()">
|
||||
</div>
|
||||
</div>
|
||||
<div id="have-fun" class="about-wrapper background">
|
||||
<h1 class="about-header"></h1>
|
||||
<div class="about-body">
|
||||
<h1 class="about-header"><%= lang.setup.done %></h1>
|
||||
</div>
|
||||
<div class="center">
|
||||
<button class="about-button"
|
||||
onclick="window.location.replace('/titles')"><%= lang.setup.done_button %></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
BIN
src/webfiles/web/images/bandwidthlost.png
Normal file
BIN
src/webfiles/web/images/bandwidthlost.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 112 KiB |
@@ -3,315 +3,345 @@ 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 = '';
|
||||
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;
|
||||
}
|
||||
function reportPost(post) {
|
||||
const id = post.getAttribute('data-post');
|
||||
const button = document.getElementById('report-launcher');
|
||||
const form = document.getElementById('report-form');
|
||||
const formID = document.getElementById('report-post-id');
|
||||
if(!id || !button || !form || !formID) return;
|
||||
|
||||
form.action = '/posts/' + id + '/report';
|
||||
formID.value = id;
|
||||
console.log(id.replace(/(\d{3})(\d{4})(\d{3})(\d{4})(\d{3})(\d{4})/, "$1-$2-$3-$4-$5-$6"));
|
||||
button.click();
|
||||
}
|
||||
2
src/webfiles/web/js/web.min.js
vendored
2
src/webfiles/web/js/web.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -92,10 +92,10 @@
|
||||
let x = document.getElementById("toast");
|
||||
x.innerText = text;
|
||||
x.className = "show";
|
||||
setTimeout(function(){ x.className = x.className.replace("show", ""); }, 3000);
|
||||
setTimeout(function(){ x.className = x.className.replace("show", ""); }, 10000);
|
||||
}
|
||||
<%if(toast) {%>
|
||||
Toast("<%=toast%>");
|
||||
Toast(`<%=toast%>`);
|
||||
<%}%>
|
||||
</script>
|
||||
</body></html>
|
||||
@@ -7,9 +7,32 @@
|
||||
<h2 id="title" class="page-header"><%= userMap.get(user2.pid) %></h2>
|
||||
<%- include('partials/nav_bar', { selection: 3, pid: pid }); %>
|
||||
<div id="toast"></div>
|
||||
<div id="wrapper" style="height: 80%;padding: 2em;text-align:center">
|
||||
<h2>Messages are not quite ready yet. Check back soon!</h2>
|
||||
<div id="wrapper">
|
||||
<div class="body-content message-post-list" id="message-page">
|
||||
<!--<button id="header-post-button" class="header-button" href="#" data-module-hide="message-page" data-module-show="add-post-page" data-header="false" data-menu="false">+</button>-->
|
||||
<% messages.forEach(function(message) { %>
|
||||
<div id="message-<%= message.id %>" class="post scroll <%if(message.pid === pid) {%>my-post<%} else {%>other-post<%}%>">
|
||||
<a href="/users/show?pid=<%= message.pid %>" data-pjax="#body" class="scroll-focus mii-icon-container">
|
||||
<img src="https://pretendo-cdn.b-cdn.net<%= message.mii_face_url.substring(message.mii_face_url.lastIndexOf('/mii')) %>" class="mii-icon">
|
||||
</a>
|
||||
<div class="post-body">
|
||||
<%if(message.screenshot) {%>
|
||||
<img class="message-viewer-bubble-sent-screenshot" src="https://pretendo-cdn.b-cdn.net<%= message.screenshot %>">
|
||||
<%}%>
|
||||
<%if(message.painting) {%>
|
||||
<img class="message-viewer-bubble-sent-memo" src="https://pretendo-cdn.b-cdn.net/paintings/<%=message.pid%>/<%=message.id%>.png">
|
||||
<%}else {%>
|
||||
<p class="post-content"><%= message.body %></p>
|
||||
<%}%>
|
||||
</div>
|
||||
<footer>
|
||||
<span class="timestamp"><%= moment(message.created_at).fromNow()%></span>
|
||||
</footer>
|
||||
</div>
|
||||
<%});%>
|
||||
</div>
|
||||
</div>
|
||||
<img src="" onerror="setTimeout(function() { window.scrollTo(0, 50000); }, 500)">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div id="toast"></div>
|
||||
<div id="wrapper">
|
||||
<% if(conversations.length === 0) {%>
|
||||
<li><p><%= lang.messages.coming_soon %><</p></li>
|
||||
<li style="list-style: none;"><p><%= lang.messages.coming_soon %></p></li>
|
||||
<%} else { %>
|
||||
<ul class="list-content-with-icon-and-text arrow-list" id="news-list-content">
|
||||
<% conversations.forEach(function(conversation) { %>
|
||||
|
||||
168
src/webfiles/web/moderate_user.ejs
Normal file
168
src/webfiles/web/moderate_user.ejs
Normal file
@@ -0,0 +1,168 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Juxt - <%= pnid.mii.name %></title>
|
||||
<%- include('partials/head'); %>
|
||||
<!-- Google / Search Engine Tags -->
|
||||
<meta itemprop="name" content="Juxt - <%= pnid.mii.name %>">
|
||||
<%if(userSettings.profile_comment_visibility){%><meta itemprop="description" content="<%= userSettings.profile_comment%>"> <%}%>
|
||||
<meta itemprop="image" content="https://pretendo-cdn.b-cdn.net/mii/<%= userSettings.pid %>/smile_open_mouth.png">
|
||||
|
||||
<!-- Open Graph Meta Tags -->
|
||||
<meta property="og:title" content="Juxt - <%= pnid.mii.name %>"/>
|
||||
<%if(userSettings.profile_comment_visibility){%><meta property="og:description" content="<%= userSettings.profile_comment%>"/><%}%>
|
||||
<meta property="og:url" content="https://juxt.pretendo.network/users/<%= userSettings.pid %>"/>
|
||||
<meta property="og:image" content="https://pretendo-cdn.b-cdn.net/mii/<%= userSettings.pid %>/smile_open_mouth.png"/>
|
||||
<meta property="og:site_name" content="Juxtaposition"/>
|
||||
|
||||
<!-- Twitter Meta Tags -->
|
||||
<meta name="twitter:card" content="summary_large_image"/>
|
||||
<meta name="twitter:title" content="Juxt - <%= pnid.mii.name %>"/>
|
||||
<%if(userSettings.profile_comment_visibility){%><meta name="twitter:description" content="<%= userSettings.profile_comment%>"/><%}%>
|
||||
<meta name="twitter:site" content="@PretendoNetwork"/>
|
||||
<meta name="twitter:image" content="https://pretendo-cdn.b-cdn.net/mii/<%= userSettings.pid %>/smile_open_mouth.png"/>
|
||||
<meta name="twitter:creator" content="@PretendoNetwork"/>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
<h2 id="title" class="page-header"><%= lang.global.user_page %></h2>
|
||||
<%- include('partials/nav_bar', { selection: -1, pid: pid }); %>
|
||||
<div id="toast"></div>
|
||||
<div id="wrapper">
|
||||
<div class="community-top">
|
||||
<img class="banner" src="https://juxt-web-cdn.b-cdn.net/images/banner.png" alt="">
|
||||
<div class="community-info">
|
||||
<img class="user-icon <%if(pnid.accessLevel > 2) {%>verified<%}%>" src="https://pretendo-cdn.b-cdn.net/mii/<%= userSettings.pid %>/normal_face.png">
|
||||
<h2 class="community-title"><%= pnid.mii.name %> @<%= pnid.username %><%if(pnid.accessLevel >= 2) {%><span class="verified-badge">✓</span><%}%></h2>
|
||||
</div>
|
||||
<h4 class="community-description">
|
||||
<%= userSettings.profile_comment%>
|
||||
<%if(pnid.tierName) {%>
|
||||
<%if(pnid.tierName === 'Mario') {%>
|
||||
<span class="supporter-star mario">|
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 23 23" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-star"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
|
||||
</span>
|
||||
<%} else if(pnid.tierName === 'Super Mario') {%>
|
||||
<span class="supporter-star super">|
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 23 23" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-star"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
|
||||
</span>
|
||||
<%} else if(pnid.tierName === 'Mega Mushroom') {%>
|
||||
<span class="supporter-star mega">|
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 23 23" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-star"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
|
||||
</span>
|
||||
<%}%>
|
||||
<%}%>
|
||||
<%if(pnid.accessLevel === 3) {%>
|
||||
<span class="supporter-star dev">|
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 23 23" fill="rainbow" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-tool">
|
||||
<defs>
|
||||
<linearGradient id="rainbow">
|
||||
<stop offset="16%" stop-color="red" />
|
||||
<stop offset="32%" stop-color="orange" />
|
||||
<stop offset="48%" stop-color="yellow" />
|
||||
<stop offset="64%" stop-color="green" />
|
||||
<stop offset="80%" stop-color="blue" />
|
||||
<stop offset="96%" stop-color="purple" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>
|
||||
</svg>
|
||||
</span>
|
||||
<%}%>
|
||||
<%if(pnid.accessLevel === 2) {%>
|
||||
<span class="supporter-star mega">|
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 23 23" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shield"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
|
||||
</span>
|
||||
<%}%>
|
||||
<%if(pnid.accessLevel === 1) {%>
|
||||
<span class="supporter-star tester">|
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 256 256" fill="none" stroke="currentColor"><path d="M104,32V93.8a8.4,8.4,0,0,1-1.1,4.1l-63.6,106A8,8,0,0,0,46.1,216H209.9a8,8,0,0,0,6.8-12.1l-63.6-106a8.4,8.4,0,0,1-1.1-4.1V32" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="88" y1="32" x2="168" y2="32" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M62.6,165c11.8-8.7,32.1-13.6,65.4,3,35.7,17.9,56.5,10.8,67.9,1.1" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/></svg>
|
||||
</span>
|
||||
<%}%>
|
||||
</h4>
|
||||
<div class="info-boxes-wrapper">
|
||||
<div>
|
||||
<h4><%= lang.user_page.country %></h4>
|
||||
<h4><%=pnid.country%></h4>
|
||||
</div>
|
||||
<div>
|
||||
<h4><%= lang.user_page.birthday %></h4>
|
||||
<h4><%=moment.utc(pnid.birthdate).format("MMM Do")%></h4>
|
||||
</div>
|
||||
<div>
|
||||
<h4><%= lang.user_page.game_experience %></h4>
|
||||
<h4>
|
||||
<%if(userSettings.game_skill === 0) {%>
|
||||
<%= lang.setup.experience_text.beginner %>
|
||||
<%} else if(userSettings.game_skill === 1) {%>
|
||||
<%= lang.setup.experience_text.intermediate %>
|
||||
<%} else if(userSettings.game_skill === 2) {%>
|
||||
<%= lang.setup.experience_text.expert %>
|
||||
<%} else {%>
|
||||
N/A
|
||||
<%}%>
|
||||
</h4>
|
||||
</div>
|
||||
<div>
|
||||
<h4><%= lang.user_page.followers %></h4>
|
||||
<h4 id="user-page-followers-tab" id="followers"><%= userContent.following_users.length %></h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-3 py-5">
|
||||
<div class="mt-5 text-center">
|
||||
<h4 class="text-right">Juxt User Settings</h4>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="col">
|
||||
<label class="labels">Account Status</label>
|
||||
<select class="form-select" aria-label="Account Status" name="account_status" id="account_status">
|
||||
<option value="0" <%if (userSettings.account_status == 0) { %>selected<% } %>>Normal</option>
|
||||
<option value="1" <%if (userSettings.account_status == 1) { %>selected<% } %>>Limited from Posting</option>
|
||||
<option value="2" <%if (userSettings.account_status == 2) { %>selected<% } %>>Temp Ban</option>
|
||||
<option value="3" <%if (userSettings.account_status == 3) { %>selected<% } %>>Permanent Ban</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col">
|
||||
<label for="ban_date">Banned Until:</label>
|
||||
<input type="date" id="ban_lift_date" name="ban_lift_date" value="<%= userSettings.ban_lift_date %>">
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="labels">Ban Reason</label>
|
||||
<input id="ban_reason" type="text" class="form-control" placeholder="Ban reason" style="width: 100%;" value="<%= userSettings.ban_reason %>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-5 text-center">
|
||||
<button class="btn btn-primary profile-button" type="button" onclick="savePNID()">Save User</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const account_status = document.getElementById('account_status');
|
||||
const ban_lift_date = document.getElementById('ban_lift_date');
|
||||
const ban_reason = document.getElementById('ban_reason');
|
||||
|
||||
function savePNID() {
|
||||
fetch('/admin/accounts/<%= userSettings.pid %>', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
account_status: Number(account_status.value),
|
||||
ban_lift_date: ban_lift_date.value,
|
||||
ban_reason: ban_reason.value,
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(({ error }) => {
|
||||
if (!error) {
|
||||
alert('Juxt user data saved')
|
||||
}
|
||||
})
|
||||
.catch(console.log);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -35,7 +35,7 @@
|
||||
<p><%= lang.global.notifications %></p>
|
||||
</a>
|
||||
<%if(moderator){%>
|
||||
<a href="/admin" <% if(selection === 5) {%>class="selected"<%}%>>
|
||||
<a href="/admin/posts" <% if(selection === 5) {%>class="selected"<%}%>>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="40" height="48">
|
||||
<rect x="50.75" y="44.69" width="106.51" height="38.63" rx="8" transform="translate(-14.79 92.28) rotate(-45)" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
|
||||
<rect x="138.75" y="132.69" width="106.51" height="38.63" rx="8" transform="translate(-51.24 180.28) rotate(-45)" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<ul class="list-content-with-icon-and-text arrow-list" id="news-list-content">
|
||||
<%if(bundle.notifications === undefined) {%><li><p><%= lang.notifications.none %></p></li><%}%>
|
||||
<%if(bundle.notifications.length === 0) {%><li style="border-bottom: none;"><p><%= lang.notifications.none %></p></li><%}%>
|
||||
<% for(var notification of bundle.notifications) {%>
|
||||
<% if(notification.type === 'follow') {%>
|
||||
<li>
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
<% if(locals.mainPost === undefined) locals.mainPost = false; %>
|
||||
<% if(locals.moderator === undefined) locals.moderator = false; %>
|
||||
<div class="posts-wrapper" id="<%= post.id %>">
|
||||
<% if(post.removed && !moderator) {%>
|
||||
<div class="post-body-content removed">
|
||||
<h3>Post has been removed.</h3>
|
||||
</div>
|
||||
<%} else {%>
|
||||
<% if (post.removed && moderator) { %>
|
||||
<div class="post-body-content removed">
|
||||
<h3>Post has been removed.</h3>
|
||||
</div>
|
||||
<% } %>
|
||||
<div class="post-user-info-wrapper" id="<%= post.id %>">
|
||||
<img class="user-icon <%if(post.verified) {%>verified<%}%>" src="https://pretendo-cdn.b-cdn.net<%= post.mii_face_url.substring(post.mii_face_url.lastIndexOf('/mii')) %>" data-pjax="/users/show?pid=<%= post.pid %>">
|
||||
<div class="post-meta-wrapper">
|
||||
@@ -15,19 +27,27 @@
|
||||
<h4><%= post.body %></h4>
|
||||
<%}%>
|
||||
<% if(post.screenshot !== '') { %>
|
||||
<img id="<%= post.id %>" class="screenshot" src="https://pretendo-cdn.b-cdn.net/<%= post.screenshot %>">
|
||||
<img id="<%= post.id %>" class="screenshot" src="https://pretendo-cdn.b-cdn.net<%= post.screenshot %>">
|
||||
<%}%>
|
||||
<% if(post.painting !== '') { %>
|
||||
<img id="<%= post.id%>" class="painting" src="https://pretendo-cdn.b-cdn.net/paintings/<%=post.pid%>/<%=post.id%>.png">
|
||||
<%}%>
|
||||
<% if(post.url) { %>
|
||||
<iframe width="760" height="427.5" src="<%= post.url.replace('watch?v=','embed/') %>" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
<iframe width="760" height="427.5" src="<%= post.url.replace('watch?v=','embed/') %>" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
<%}%>
|
||||
</div>
|
||||
<div class="post-buttons-wrapper">
|
||||
<span <%if(userContent !== null) {%> data-post="<%= post.id %>" class="<%if(post.yeahs && post.yeahs.indexOf(userContent.pid) !== -1){ %> selected <%}%> <%}%>"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-heart"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg><h4 id="count-<%= post.id %>"><%= post.empathy_count %></h4></span>
|
||||
<span><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 13 13.311"><g id="Icon_feather-corner-down-right" data-name="Icon feather-corner-down-right" transform="translate(-5.25 -5.25)"><path id="Path_47" data-name="Path 47" d="M22.5,15l3.594,3.594L22.5,22.188" transform="translate(-8.594 -4.688)" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/><path id="Path_48" data-name="Path 48" d="M6,6v5.031a2.875,2.875,0,0,0,2.875,2.875H17.5" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/></g></svg><h4><%= post.reply_count %></h4></span>
|
||||
<span onclick="copyToClipboard('https://juxt.pretendo.network/posts/<%=post.id%>');"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-share-2"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/></svg></span>
|
||||
</div>
|
||||
<% if(reply && post.pid !== pid && !locals.mainPost) {%>
|
||||
<span type="button" class="submit report" data-post="<%= post.id %>" onclick="reportPost(this)"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="#ffffff" viewBox="0 0 256 256"><path stroke="currentColor" stroke-width="4" d="M34.76,42A8,8,0,0,0,32,48V216a8,8,0,0,0,16,0V171.77c26.79-21.16,49.87-9.75,76.45,3.41,16.4,8.11,34.06,16.85,53,16.85,13.93,0,28.54-4.75,43.82-18a8,8,0,0,0,2.76-6V48A8,8,0,0,0,210.76,42c-28,24.23-51.72,12.49-79.21-1.12C103.07,26.76,70.78,10.79,34.76,42ZM208,164.25c-26.79,21.16-49.87,9.74-76.45-3.41-25-12.35-52.81-26.13-83.55-8.4V51.79c26.79-21.16,49.87-9.75,76.45,3.4,25,12.35,52.82,26.13,83.55,8.4Z"></path></svg></span>
|
||||
<%}%>
|
||||
</div>
|
||||
<%}%>
|
||||
</div>
|
||||
<%if(locals.mainPost && !post.removed) {%>
|
||||
<button id="header-communities-button" class="report" href="#" data-post="<%= post.id %>" onclick="reportPost(this)">Report Post</button>
|
||||
<a id="report-launcher" style="display: none" data-module-hide="post" data-module-show="report-post-page" data-header="false" data-menu="false"></a>
|
||||
<%}%>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<%if(!bundle.open) {%><div class="headline"><h2>This community is closed to new posts.</h2></div><%}%>
|
||||
<% if(bundle.numPosts === 0) {%>
|
||||
<% if(bundle.posts.length === 0) {%>
|
||||
<p class="no-posts-text"><%= lang.global.no_posts %></p>
|
||||
<%} else { %>
|
||||
<% bundle.posts.forEach(function(post) { %>
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
<title>Post by <%= post.screen_name %></title>
|
||||
<%- include('partials/head'); %>
|
||||
<!-- Google / Search Engine Tags -->
|
||||
<meta itemprop="name" content="Juxtaposition - Post by <%= post.screen_name %>">
|
||||
<meta itemprop="description" content="<%= community.name %> - <%= post.empathy_count%> Yeahs!">
|
||||
<meta itemprop="name" content="<%= post.screen_name %> (@<%= postPNID.username %>) - <%= community.name %>">
|
||||
<meta itemprop="description" content="<%= post.body %>
|
||||
|
||||
<%= post.reply_count %> 🗨️ <%= post.empathy_count %> ❤️">
|
||||
<% if(post.screenshot !== '') { %>
|
||||
<meta itemprop="image" content="https://pretendo-cdn.b-cdn.net<%= post.screenshot %>">
|
||||
<%} else if(post.painting !== '') { %>
|
||||
@@ -12,25 +14,29 @@
|
||||
<%}%>
|
||||
|
||||
<!-- Open Graph Meta Tags -->
|
||||
<meta property="og:title" content="Juxt - Post by <%= post.screen_name %>"/>
|
||||
<meta property="og:description" content="<%= community.name %> - <%= post.empathy_count%> Yeahs!"/>
|
||||
<meta property="og:title" content="<%= post.screen_name %> (@<%= postPNID.username %>) - <%= community.name %>"/>
|
||||
<meta property="og:description" content="<%= post.body %>
|
||||
|
||||
<%= post.reply_count %> 🗨️ <%= post.empathy_count %> ❤️"/>
|
||||
<meta property="og:url" content="https://juxt.pretendo.cc/posts/<%= post.id %>"/>
|
||||
<% if(post.screenshot !== '') { %>
|
||||
<meta property="og:image" content="https://pretendo-cdn.b-cdn.net/<%= post.screenshot %>"/>
|
||||
<meta property="og:image" content="https://pretendo-cdn.b-cdn.net<%= post.screenshot %>"/>
|
||||
<%} else if(post.painting !== '') { %>
|
||||
<meta property="og:image" content="https://pretendo-cdn.b-cdn.net/paintings/<%= post.pid %>/<%= post.id %>.png"/>
|
||||
<meta property="og:image" content="https://pretendo-cdn.b-cdn.net/paintings/<%= post.pid %>/<%= post.id %>.png"/>
|
||||
<%}%>
|
||||
<meta property="og:site_name" content="Juxtaposition" />
|
||||
<meta property="og:site_name" content="Juxtaposition - Pretendo Network" />
|
||||
|
||||
<!-- Twitter Meta Tags -->
|
||||
<meta name="twitter:card" content="summary_large_image"/>
|
||||
<meta name="twitter:title" content="Juxt - Post by <%= post.screen_name %>"/>
|
||||
<meta name="twitter:description" content="<%= community.name %> - <%= post.empathy_count%> Yeahs!"/>
|
||||
<meta name="twitter:title" content=""<%= post.screen_name %> (@<%= postPNID.username %>) - <%= community.name %>"/>
|
||||
<meta name="twitter:description" content="<%= post.body %>
|
||||
|
||||
<%= post.reply_count %> 🗨️ <%= post.empathy_count %> ❤️"/>
|
||||
<meta name="twitter:site" content="@PretendoNetwork"/>
|
||||
<% if(post.screenshot !== '') { %>
|
||||
<meta name="twitter:image" content="https://pretendo-cdn.b-cdn.net/<%= post.screenshot %>"/>
|
||||
<meta name="twitter:image" content="https://pretendo-cdn.b-cdn.net<%= post.screenshot %>"/>
|
||||
<%} else if(post.painting !== '') { %>
|
||||
<meta name="twitter:image" content="https://pretendo-cdn.b-cdn.net/paintings/<%= post.pid %>/<%= post.id %>.png"/>
|
||||
<meta name="twitter:image" content="https://pretendo-cdn.b-cdn.net/paintings/<%= post.pid %>/<%= post.id %>.png"/>
|
||||
<%}%>
|
||||
<meta name="twitter:creator" content="@PretendoNetwork"/>
|
||||
|
||||
@@ -40,9 +46,9 @@
|
||||
<h2 id="title" class="page-header">Post</h2>
|
||||
<%- include('partials/nav_bar', { selection: 2, pid: pid }); %>
|
||||
<div id="toast"></div>
|
||||
<div class="community-page-post-box">
|
||||
<div class="community-page-post-box" id="post">
|
||||
<div id="wrapper">
|
||||
<%- include('partials/post_template', { post: post, mii_image_CDN: mii_image_CDN, lang: lang, reply: false }); %>
|
||||
<%- include('partials/post_template', { post: post, mii_image_CDN: mii_image_CDN, lang: lang, reply: false, mainPost: true }); %>
|
||||
<span class="replies-line"></span>
|
||||
<% replies.forEach(function(post) { %>
|
||||
<%- include('partials/post_template', { post: post, mii_image_CDN: mii_image_CDN, lang: lang, reply: true }); %>
|
||||
@@ -50,6 +56,41 @@
|
||||
<% }); %>
|
||||
</div>
|
||||
</div>
|
||||
<div id="report-post-page" class="add-post-page official-user-post" style="display: none">
|
||||
<form method="post" action="/posts/<%=post.id%>/report" id="report-form" name="report" data-is-own-title="1" data-is-identified="1">
|
||||
<input type="hidden" name="post_id" id="report-post-id" value="<%= post.id %>"/>
|
||||
<div class="add-post-page-content report">
|
||||
<h2 class="page-title">Report Post</h2>
|
||||
<p>
|
||||
You are about to report a post with content which violates the Juxtaposition Code of Conduct.
|
||||
This report will be sent to Pretendo's Juxtaposition administrators and not to the creator of the post.
|
||||
</p>
|
||||
<div>
|
||||
<h4>Violation Type:</h4>
|
||||
<select name="reason" id="report">
|
||||
<option value="0">Spoiler</option>
|
||||
<option value="1">Personal Information</option>
|
||||
<option value="2">Violent Content</option>
|
||||
<option value="3">Inappropriate/Harmful Conduct</option>
|
||||
<option value="4">Hateful/Bullying</option>
|
||||
<option value="5">Advertising</option>
|
||||
<option value="6">Sexually Explicit</option>
|
||||
<option value="7">Piracy</option>
|
||||
<option value="8">Inappropriate Behavior in Game</option>
|
||||
<option value="9">Other</option>
|
||||
</select>
|
||||
</div>
|
||||
<textarea name="message" class="textarea-text" value="" maxlength="280" placeholder="Enter additional comments or information"></textarea>
|
||||
</div>
|
||||
<div id="button-wrapper">
|
||||
<input type="button" class="olv-modal-close-button fixed-bottom-button left"
|
||||
value="Cancel" data-sound="SE_WAVE_CANCEL"
|
||||
data-module-show="post" data-module-hide="report-post-page"
|
||||
data-header="true" data-menu="true">
|
||||
<input type="submit" class="post-button fixed-bottom-button" value="Submit">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
<%- include('partials/nav_bar', { selection: 5, pid: pid }); %>
|
||||
<div id="toast"></div>
|
||||
<div id="wrapper">
|
||||
<div class="buttons tabs">
|
||||
<a id="post-reports" class="selected" href="/admin/posts">Posts</a>
|
||||
<a id="account-reports" href="/admin/accounts">Accounts</a>
|
||||
</div>
|
||||
<% if(reports.length === 0) {%>
|
||||
<p>No Reports found</p>
|
||||
<%} else { %>
|
||||
@@ -69,6 +73,7 @@
|
||||
<% let post = posts.find((post) => post.id === report.post_id) %>
|
||||
<%- include('partials/post_template', { post: post, mii_image_CDN: mii_image_CDN, lang: lang, reply: false }); %>
|
||||
<button onclick="remove(this)" data-id="<%=report._id%>">Remove Post</button>
|
||||
<button onclick="ignore(this)" data-id="<%=report._id%>">Ignore Report</button>
|
||||
</li>
|
||||
|
||||
<% });} %>
|
||||
@@ -85,7 +90,18 @@
|
||||
method: 'DELETE',
|
||||
})
|
||||
.then(res => res.text())
|
||||
.then(res => console.log(res))
|
||||
.then(res => location.reload())
|
||||
}
|
||||
function ignore(element) {
|
||||
const id = element.getAttribute("data-id");
|
||||
const reason = prompt("Provide explanation for ignoring this report:")
|
||||
if(!id || !reason) return;
|
||||
|
||||
fetch(`/admin/${id}?reason=${reason}`, {
|
||||
method: 'PUT',
|
||||
})
|
||||
.then(res => res.text())
|
||||
.then(res => location.reload())
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -1,27 +1,26 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Juxt - <%= pnid.mii.name %></title>
|
||||
<% var banned = (userContent.account_status < 0 || userContent.account_status > 1 || pnid.accessLevel < 0); %>
|
||||
<%- include('partials/head'); %>
|
||||
<!-- Google / Search Engine Tags -->
|
||||
<meta itemprop="name" content="Juxt - <%= pnid.mii.name %>">
|
||||
<% if(!banned) { %>
|
||||
<title>Juxt - <%= pnid.mii.name %></title>
|
||||
<meta itemprop="name" content="<%= pnid.mii.name %> (@<%= pnid.username %>)">
|
||||
<%if(userSettings.profile_comment_visibility){%><meta itemprop="description" content="<%= userSettings.profile_comment%>"> <%}%>
|
||||
<meta itemprop="image" content="https://pretendo-cdn.b-cdn.net/mii/<%= userSettings.pid %>/smile_open_mouth.png">
|
||||
|
||||
<!-- Open Graph Meta Tags -->
|
||||
<meta property="og:title" content="Juxt - <%= pnid.mii.name %>"/>
|
||||
<meta property="og:title" content="<%= pnid.mii.name %> (@<%= pnid.username %>)"/>
|
||||
<%if(userSettings.profile_comment_visibility){%><meta property="og:description" content="<%= userSettings.profile_comment%>"/><%}%>
|
||||
<meta property="og:url" content="https://juxt.pretendo.network/users/<%= userSettings.pid %>"/>
|
||||
<meta property="og:image" content="https://pretendo-cdn.b-cdn.net/mii/<%= userSettings.pid %>/smile_open_mouth.png"/>
|
||||
<meta property="og:site_name" content="Juxtaposition"/>
|
||||
|
||||
<!-- Twitter Meta Tags -->
|
||||
<meta name="twitter:card" content="summary_large_image"/>
|
||||
<meta name="twitter:title" content="Juxt - <%= pnid.mii.name %>"/>
|
||||
<meta name="twitter:title" content="<%= pnid.mii.name %> (@<%= pnid.username %>)"/>
|
||||
<%if(userSettings.profile_comment_visibility){%><meta name="twitter:description" content="<%= userSettings.profile_comment%>"/><%}%>
|
||||
<meta name="twitter:site" content="@PretendoNetwork"/>
|
||||
<meta name="twitter:image" content="https://pretendo-cdn.b-cdn.net/mii/<%= userSettings.pid %>/smile_open_mouth.png"/>
|
||||
<meta name="twitter:creator" content="@PretendoNetwork"/>
|
||||
|
||||
<% } %>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
@@ -32,9 +31,9 @@
|
||||
<div class="community-top">
|
||||
<img class="banner" src="https://juxt-web-cdn.b-cdn.net/images/banner.png" alt="">
|
||||
<div class="community-info">
|
||||
<img class="user-icon <%if(pnid.accessLevel > 2) {%>verified<%}%>" src="https://pretendo-cdn.b-cdn.net/mii/<%= userSettings.pid %>/normal_face.png">
|
||||
<h2 class="community-title"><%= pnid.mii.name %> @<%= pnid.username %><span class="verified-badge" style="<%if(pnid.accessLevel < 2) {%>display: none;<%}%>">✓</span></h2>
|
||||
<%if(pnid.pid !== pid && pid !== 1000000000) {%>
|
||||
<img class="user-icon <%if(pnid.accessLevel > 2) {%>verified<%}%>" src="<%if (pnid.deleted || banned) { %>https://juxt-web-cdn.b-cdn.net/images/bandwidthlost.png<% } else { %>https://pretendo-cdn.b-cdn.net/mii/<%=pnid.pid%>/normal_face.png<%}%>">
|
||||
<h2 class="community-title"><% if(banned) { %>Banned User<% } else if(pnid.deleted){%>Deleted User<%} else {%><%= pnid.mii.name %> @<%= pnid.username %><%}%><%if(pnid.accessLevel >= 2) {%><span class="verified-badge">✓</span><%}%></h2>
|
||||
<%if(pnid.pid !== pid && pid !== 1000000000 && !pnid.deleted && !banned) {%>
|
||||
<% var following = parentUserContent.followed_users.indexOf(userContent.pid) !== -1; %>
|
||||
<a href="#" class="favorite-button <%if(following){ %>checked<%}%>" onclick="follow(this)" data-sound="SE_WAVE_CHECKBOX_UNCHECK" data-url="/users/follow" data-community-id="<%=pnid.pid%>" data-text="<% if(following){ %><%= lang.user_page.follow_user %><%} else {%><%= lang.user_page.following_user %><%}%>"><% if(following){ %> <%= lang.user_page.following_user %> <%} else {%> <%= lang.user_page.follow_user %> <%}%></a>
|
||||
<%if(following && userContent.followed_users.indexOf(parentUserContent.pid) !== -1) { /*Is mutual*/%>
|
||||
@@ -42,6 +41,7 @@
|
||||
<%}%>
|
||||
<%}%>
|
||||
</div>
|
||||
<% if (!pnid.deleted && !banned) { %>
|
||||
<h4 class="community-description">
|
||||
<!--<%if(userSettings.profile_comment_visibility){%> <%= userSettings.profile_comment%> <%}else {%><%= lang.global.private %><%}%>
|
||||
<%if(pnid.tierName) {%>
|
||||
@@ -124,9 +124,15 @@
|
||||
<h4 id="user-page-download-tab"><a href="/downloadUserData.json">Download</a></h4>
|
||||
</div>
|
||||
<%}%>
|
||||
<% if (moderator && pnid.pid !== pid) { %>
|
||||
<div>
|
||||
<h4 id="user-page-download-tab"><a class="moderate" href="/admin/accounts/<%= pnid.pid %>">Moderate User</a></h4>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
<%- include('partials/' + template, { bundle }); %>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
60
src/webfiles/web/users.ejs
Normal file
60
src/webfiles/web/users.ejs
Normal file
@@ -0,0 +1,60 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<%- include('partials/head'); %>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
<h2 id="title" class="page-header">User Accounts</h2>
|
||||
<%- include('partials/nav_bar', { selection: 5, pid: pid }); %>
|
||||
<div id="toast"></div>
|
||||
<div id="wrapper">
|
||||
<div class="buttons tabs">
|
||||
<a id="post-reports" href="/admin/posts">Posts</a>
|
||||
<a id="account-reports" class="selected" href="/admin/accounts">Accounts</a>
|
||||
</div>
|
||||
<% if(users.length === 0) {%>
|
||||
<p>No Users found</p>
|
||||
<%} else { %>
|
||||
<ul class="list-content-with-icon-and-text arrow-list" id="news-list-content">
|
||||
<% users.forEach(function(user) { %>
|
||||
<li>
|
||||
<div class="hover">
|
||||
<a href="/users/<%= user.pid %>" data-pjax="#body" class="icon-container notify">
|
||||
<img src="https://pretendo-cdn.b-cdn.net/mii/<%= user.pid %>/normal_face.png" class="icon">
|
||||
</a>
|
||||
<a class="body" href="/users/<%= user.pid %>">
|
||||
<span class="text"><span class="nick-name"><%= userMap.get(user.pid) %></span>
|
||||
</a>
|
||||
</div>
|
||||
<button onclick="this.children[0].click()"><a id="account-<%= user.pid %>" href="/admin/accounts/<%=user.pid%>">Manage User</a></button>
|
||||
</li>
|
||||
<% });} %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function remove(element) {
|
||||
const id = element.getAttribute("data-id");
|
||||
const reason = prompt("Provide explanation for removing post:")
|
||||
if(!id || !reason) return;
|
||||
|
||||
fetch(`/admin/${id}?reason=${reason}`, {
|
||||
method: 'DELETE',
|
||||
})
|
||||
.then(res => res.text())
|
||||
.then(res => location.reload())
|
||||
}
|
||||
function ignore(element) {
|
||||
const id = element.getAttribute("data-id");
|
||||
const reason = prompt("Provide explanation for ignoring this report:")
|
||||
if(!id || !reason) return;
|
||||
|
||||
fetch(`/admin/${id}?reason=${reason}`, {
|
||||
method: 'PUT',
|
||||
})
|
||||
.then(res => res.text())
|
||||
.then(res => location.reload())
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user