Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/57 #39

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion backend/src/db.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { DataSource } from 'typeorm';
import User from './models/user';
import Post from './models/post';
import Comment from './models/comment';
import Playlist from './models/playlist';

import {
MONGODB_HOST,
MONGODB_USER,
Expand All @@ -15,7 +18,8 @@ const db = new DataSource({
username: MONGODB_USER,
password: MONGODB_PASSWORD,
database: MONGODB_DB,
entities: [User, Post],
entities: [User, Post, Comment, Playlist],
synchronize: true,
ssl: true,
authSource: 'admin',
});
Expand Down
20 changes: 20 additions & 0 deletions backend/src/models/comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Entity, ObjectIdColumn, Column, BaseEntity } from 'typeorm';
import mongodb from 'mongodb';
import User from './user';

@Entity()
class Comment extends BaseEntity {
@ObjectIdColumn()
id: typeof mongodb.ObjectId;

@Column()
author: User;

@Column()
bodyText: string;

@Column()
likedBy: mongodb.ObjectId[];
}

export default Comment;
18 changes: 14 additions & 4 deletions backend/src/models/post.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { Entity, ObjectIdColumn, Column, BaseEntity } from 'typeorm';
import {
Entity,
ObjectIdColumn,
Column,
BaseEntity,
ManyToMany,
JoinTable,
} from 'typeorm';
import mongodb from 'mongodb';
import User from './user';

Expand All @@ -10,14 +17,17 @@ class Post extends BaseEntity {
@Column()
author: User;

@Column()
numLikes: number;

@Column()
bodyText: string;

@Column()
musicURL: string;

@Column()
likedBy: mongodb.ObjectId[];

@Column()
comments: mongodb.ObjectId[];
}

export default Post;
172 changes: 160 additions & 12 deletions backend/src/routes/post.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Router from '@koa/router';
import Post from '../models/post';
import User from '../models/user';
import Comment from '../models/comment';
import mongodb from 'mongodb';
import bodyParser from 'koa-bodyparser';

Expand All @@ -22,11 +24,18 @@ router.get('/:postID', async (ctx, next) => {
}
ctx.body = post;
});

router.post('/', async (ctx, next) => {
const post = new Post();
post.id = new mongodb.ObjectId();
post.author = null; //This is dependent on Auth to determine the author
post.numLikes = 0;
const authorID = ctx.state.user.id;
const author = await User.findOneBy(mongodb.ObjectId(authorID));
console.log(
`The Net ID of the author is: ${author.netid}\n They have display name: ${author.displayName}\n`
);
post.author = author;
post.likedBy = [];
post.comments = [];

const requestBody = ctx.request.body as any;
const bodyText = requestBody.bodyText || '';
Expand All @@ -35,33 +44,172 @@ router.post('/', async (ctx, next) => {
post.bodyText = bodyText;
post.musicURL = musicURL;

await post.save();
ctx.body = post;
await Post.create(post);
ctx.body = await post.save();
});
router.post('/:postID/like', async (ctx, next) => {
const post = await Post.findOneBy(mongodb.ObjectId(ctx.params.postID));

const requestBody = ctx.request.body as any;
const username = requestBody.username;
const dir = parseInt(requestBody.dir);

if (post === null) {
console.log(`Could not find post with ID: ${ctx.params.postID}`);
ctx.status = 404;
return;
}
post.numLikes += 1;
await post.save();
// currently, we have no way of identifying based off the request given
// so we will just use the username parameter to identify the user
if (username) {
const user = await User.findOneBy({
username: username,
});
if (user === null) {
console.log(`Could not find user with name: ${username}`);
ctx.status = 404;
return;
}
if (dir === 1) {
console.log(`Num post likes: ${post.likedBy.push(user.id)}`);
} else {
// if they unlike the post, remove them from the likedBy array
// this covers the case where they have not liked the post yet
post.likedBy = post.likedBy.filter((id) => !id.equals(user.id));
}
await post.save();
}
// await Post.save(post);
ctx.body = post;
});
router.post('/:postID/unlike', async (ctx, next) => {
// delete a post by id
router.delete('/:postID', async (ctx, next) => {
const post = await Post.findOneBy(mongodb.ObjectId(ctx.params.postID));
ctx.body = await Post.remove(post);
});
// delete all posts
router.delete('/', async (ctx, next) => {
const post = await Post.find();
ctx.body = await Post.remove(post);
});

//comment-related routes

//Get all comments from a post
router.get('/:postID/comments', async (ctx, next) => {
const post = await Post.findOneBy(mongodb.ObjectId(ctx.params.postID));
if (post === null) {
console.log(`No Post associated with ID: ${ctx.params.postID}`);
ctx.status = 404;
return;
}
const comments = post.comments;

ctx.body = comments;
});

//Get a comment from a specific post.
router.get('/:postID/comments/:commentID', async (ctx, next) => {
const comment = await Comment.findOneBy(
mongodb.ObjectId(ctx.params.commentID)
);
if (comment == null) {
console.log(`No comment associated with ID: ${ctx.params.commendID}`);
ctx.status = 404;
return;
}
post.numLikes -= 1;
ctx.body = comment;
});

//add a comment to a post
// request body should contain bodyText
router.post('/:postID/comments', async (ctx, next) => {
const post = await Post.findOneBy(mongodb.ObjectId(ctx.params.postID));
if (post === null) {
console.log(`No Post associated with ID: ${ctx.params.postID}`);
ctx.status = 404;
return;
}
// Create new comment
const comment = new Comment();
const requestBody = ctx.request.body as any;
const bodyText = requestBody.bodyText || '';

const authorID = ctx.state.user.id;
const author = await User.findOneBy(mongodb.ObjectId(authorID));

comment.id = new mongodb.ObjectId();
comment.author = author;
comment.likedBy = [];
comment.bodyText = bodyText;

await Comment.create(comment);
await comment.save();
post.comments.push(comment.id);
await post.save();
ctx.body = post;

ctx.body = comment;
});

router.delete('/', async (ctx, next) => {
const post = await Post.find();
ctx.body = await Post.remove(post);
//delete a comment
router.delete('/:postID/comments/:commentID', async (ctx, next) => {
const postID = mongodb.ObjectId(ctx.params.postID);
const commentID = mongodb.ObjectId(ctx.params.commentID);

const post = await Post.findOneBy(postID);
if (post === null) {
console.log('Post does not exist');
}
const comment = await Comment.findOneBy(commentID);
if (comment === null) {
console.log('Comment does not exist');
}
// filter comment from post by ID
post.comments = post.comments.filter((id) => !id.equals(commentID));
await post.save();
ctx.body = await Comment.remove(comment);
});

//like or unlike comment.
/*
Request Body Structure:
username: username of the person liking / unliking
dir: 1 if liking, 0 otherwise
*/
router.post('/:postID/comments/:commentID/like', async (ctx, next) => {
const post = await Post.findOneBy(mongodb.ObjectId(ctx.params.postID));
const comment = await Comment.findOneBy(
mongodb.ObjectId(ctx.params.commentID)
);

const requestBody = ctx.request.body as any;
const username = requestBody.username;
const dir = parseInt(requestBody.dir);

if (post === null || comment === null) {
ctx.status = 404;
return;
}
// currently, we have no way of identifying based off the request given
// so we will just use the username parameter to identify the user
if (username) {
const user = await User.findOneBy({
username: username,
});
if (user === null) {
ctx.status = 404;
return;
}
if (dir === 1) {
comment.likedBy.push(user.id);
} else {
// if they unlike the post, remove them from the likedBy array
// this covers the case where they have not liked the post yet
comment.likedBy = comment.likedBy.filter((id) => !id.equals(user.id));
}
await comment.save();
}
ctx.body = comment.likedBy.length;
});

export default router;
3 changes: 2 additions & 1 deletion backend/src/routes/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ router.get('/:username', async (ctx, next) => {

router.put('/:username', async (ctx, next) => {
const user = new User();

/*
Check if user exists set ctx.status to 400 and return before creating
new user.
Expand All @@ -31,7 +32,7 @@ router.put('/:username', async (ctx, next) => {
ctx.status = 400;
} else {
user.username = ctx.params.username;
user.displayname = 'John Doe';
user.displayName = 'John Doe';
await user.save();
ctx.body = user;
}
Expand Down
1 change: 1 addition & 0 deletions ios/Flutter/Debug.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
1 change: 1 addition & 0 deletions ios/Flutter/Release.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
41 changes: 41 additions & 0 deletions ios/Podfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '11.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}

def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end

File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

target 'Runner' do
use_frameworks!
use_modular_headers!

flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end
Loading