Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
96c13d7
Update README.md
sashaparkes Jun 2, 2025
f697244
altered existing tables and created new table migrations
Shanice598 Jun 3, 2025
3834bf4
Merge pull request #1 from sashaparkes/migrations
A-Schmigiel Jun 3, 2025
41456a4
updated user model and tests
sashaparkes Jun 3, 2025
7c3199f
Merge remote-tracking branch 'origin/main' into sign_up
sashaparkes Jun 3, 2025
3ce1025
pull
A-Schmigiel Jun 3, 2025
e56e6d0
update user model again
sashaparkes Jun 3, 2025
5db70b5
yml fix
Shanice598 Jun 3, 2025
781bcac
Merge pull request #3 from sashaparkes/migrations
A-Schmigiel Jun 3, 2025
2250297
Mid workflow
A-Schmigiel Jun 3, 2025
34bbbd7
Mid workflow
A-Schmigiel Jun 3, 2025
daff4b1
Auth0 taking name details etc
sashaparkes Jun 4, 2025
61e71b2
Notifications Model/Controller/Interface/HTML-- working except for th…
A-Schmigiel Jun 4, 2025
b7101f6
basic settings page
sashaparkes Jun 4, 2025
bb6eee9
settings page
sashaparkes Jun 4, 2025
065999b
settings
sashaparkes Jun 4, 2025
0bfd2c6
Merge pull request #4 from sashaparkes/sign_up
A-Schmigiel Jun 4, 2025
ff069be
friends
HarryMcconville Jun 4, 2025
9c0648c
Merge branch 'main' into notifications
sashaparkes Jun 4, 2025
686c28e
Merge pull request #5 from sashaparkes/notifications
sashaparkes Jun 4, 2025
0855208
Merge pull request #6 from sashaparkes/friend_list
sashaparkes Jun 4, 2025
968fb0c
image uploader updates
sashaparkes Jun 4, 2025
a275311
image uploader
sashaparkes Jun 4, 2025
9563f2c
fixed friends template
HarryMcconville Jun 4, 2025
259c2ad
Updated PostController, Posts index.html, and individual post html, a…
A-Schmigiel Jun 4, 2025
9410fad
Notifications now correctly marking as read when clicked.
A-Schmigiel Jun 4, 2025
ab964d3
image uploader updated
sashaparkes Jun 4, 2025
b072ba0
updated friends page
HarryMcconville Jun 4, 2025
c83931e
Merge pull request #9 from sashaparkes/friend_list
Jordan-Gill Jun 4, 2025
8ac358c
Merge pull request #8 from sashaparkes/notifications
Jordan-Gill Jun 4, 2025
8897fef
Merge pull request #10 from sashaparkes/sign_up
HarryMcconville Jun 4, 2025
f2de4ac
Notifications now (actually) correctly marking as read when clicked.
A-Schmigiel Jun 4, 2025
7319078
adding dsstore
Shanice598 Jun 5, 2025
677bb02
users can comment on posts and like comments MVC's only
Shanice598 Jun 5, 2025
753e3b8
adding controller for comments
Shanice598 Jun 5, 2025
cf12eff
corrected errors for commentlike stuff, small change in user.java
Shanice598 Jun 5, 2025
38de3c7
settings page tests
sashaparkes Jun 5, 2025
3efaeb1
Navbar up and running
A-Schmigiel Jun 5, 2025
80b2a40
Navbar, Notifications, and Posts updates
A-Schmigiel Jun 5, 2025
ff5bbb9
Merge pull request #11 from sashaparkes/usercommentonposts
A-Schmigiel Jun 5, 2025
6a97af7
settings.html fix
A-Schmigiel Jun 5, 2025
e8c1d06
settings.html merge fix
A-Schmigiel Jun 5, 2025
93927cf
Merge pull request #13 from sashaparkes/notifications
Jordan-Gill Jun 5, 2025
eddb8b1
Temporary comment fix :(
A-Schmigiel Jun 5, 2025
bc98908
partway through testing settings page
sashaparkes Jun 5, 2025
753e8e7
Merge pull request #14 from sashaparkes/notifications
Jordan-Gill Jun 5, 2025
47a7611
completed feature tests for settings page
sashaparkes Jun 5, 2025
dd4de01
Friend requests can be accepted/rejected
HarryMcconville Jun 5, 2025
67191c6
added V12 migration to add friends since...
HarryMcconville Jun 5, 2025
27df91b
First commit
Jordan-Gill Jun 5, 2025
d9f1045
changed v12 to v13
HarryMcconville Jun 5, 2025
88ec736
changed name again whoops
HarryMcconville Jun 5, 2025
797a3e4
Merge pull request #15 from sashaparkes/friend_list
A-Schmigiel Jun 5, 2025
ab30d5b
Merge pull request #17 from sashaparkes/user_details_with_post
A-Schmigiel Jun 5, 2025
ccc6c9f
settings page tests without images
sashaparkes Jun 6, 2025
f0e9b24
removed images
sashaparkes Jun 6, 2025
a98b30c
Merge pull request #16 from sashaparkes/testing_user_controller
A-Schmigiel Jun 6, 2025
1506295
added db migration V13
sashaparkes Jun 6, 2025
8e0a4e0
post upload merged with main functionality
sashaparkes Jun 6, 2025
9ab2e0f
deleted images
sashaparkes Jun 6, 2025
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
Binary file added .DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ dependency-reduced-pom.xml
.factorypath
.project
.settings/
application.yml
.DS_Store
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Acebook

https://trello.com/b/VidgaAkH/acebook-engineering-project-2

The application uses:
- `maven` to build the project
- `thymeleaf` for templating
Expand Down
3 changes: 3 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.32</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -102,6 +103,7 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.3.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand All @@ -114,6 +116,7 @@
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.32</version>
</path>
</annotationProcessorPaths>
</configuration>
Expand Down
Binary file added src/.DS_Store
Binary file not shown.
Binary file added src/main/.DS_Store
Binary file not shown.
Binary file added src/main/java/.DS_Store
Binary file not shown.
Binary file added src/main/java/com/.DS_Store
Binary file not shown.
Binary file added src/main/java/com/makersacademy/.DS_Store
Binary file not shown.
Binary file not shown.
24 changes: 24 additions & 0 deletions src/main/java/com/makersacademy/acebook/config/WebConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.makersacademy.acebook.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

// This class customises how the app serves static resources (e.g. images) from the file system
// Resource handlers map URL paths to filesystem directories so static files (e.g. images) can be served via HTTP
// This is required for image storage outside the classpath (src) on uploading

@Configuration
public class WebConfig implements WebMvcConfigurer {

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// Handler for profile images
registry.addResourceHandler("/images/user_profile/**")
.addResourceLocations("file:uploads/user_profile/");

// Handler for post images
registry.addResourceHandler("/uploads/post_images/**")
.addResourceLocations("file:uploads/post_images/");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//package com.makersacademy.acebook.controller;
//
//import com.makersacademy.acebook.dto.CommentRequest;
//import com.makersacademy.acebook.model.Comment;
//import com.makersacademy.acebook.model.Post;
//import com.makersacademy.acebook.model.User;
//import com.makersacademy.acebook.repository.PostRepository;
//import com.makersacademy.acebook.repository.UserRepository;
//import com.makersacademy.acebook.service.CommentService;
//import org.springframework.web.bind.annotation.*;
//
//import java.util.List;
//
//@RestController
//@RequestMapping("/post/comments")
//public class CommentController {
//
// private final CommentService commentService;
// private final PostRepository postRepository;
// private final UserRepository userRepository;
//
// public CommentController(CommentService commentService, PostRepository postRepository, UserRepository userRepository) {
// this.commentService = commentService;
// this.postRepository = postRepository;
// this.userRepository = userRepository;
// }
//
// @GetMapping("/post/{postId}")
// public List<Comment> getCommentsByPost(@PathVariable Long postId) {
// return commentService.getCommentsForPost(postId);
// }
//
// @PostMapping
// public Comment createComment(@RequestBody CommentRequest request) {
// Post post = postRepository.findById(request.getPostId())
// .orElseThrow(() -> new RuntimeException("Post not found"));
// User user = userRepository.findById(request.getUserId())
// .orElseThrow(() -> new RuntimeException("User not found"));
//
// Long commentId = 0L;
// Comment comment = new Comment(commentId);
// comment.setPost(post);
// comment.setUser(user);
// comment.setContent(request.getContent());
//
// return commentService.addComment(comment);
// }
//}
//
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package com.makersacademy.acebook.controller;

import com.makersacademy.acebook.model.Friend;
import com.makersacademy.acebook.model.FriendRequest;
import com.makersacademy.acebook.model.User;
import com.makersacademy.acebook.repository.FriendRepository;
import com.makersacademy.acebook.repository.FriendRequestRepository;
import com.makersacademy.acebook.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import java.sql.Timestamp;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Controller
public class FriendsController {

@Autowired
FriendRequestRepository friendRequestRepository;
@Autowired
FriendRepository friendRepository;
@Autowired
UserRepository userRepository;

@GetMapping("/friends")
public ModelAndView friendList(@AuthenticationPrincipal(expression = "attributes['email']") String email) {
ModelAndView modelAndView = new ModelAndView("friends/friends");

// User!
Optional<User> userOptional = userRepository.findUserByUsername(email);

User currentUser = userOptional.get();
Long userId = currentUser.getId();

// Friends!
List<Friend> friendsList = friendRepository.findAllByMainUserId(userId);

// Objectify!
List<User> friendUsers = new ArrayList<>();
for (Friend friend : friendsList) {
Long friendId = friend.getFriendUserId();
Optional<User> friendUser = userRepository.findById(friendId);
if (friendUser.isPresent()) {
friendUsers.add(friendUser.get());
}
}

// Friend Requests!
List<FriendRequest> pendingRequests = friendRequestRepository.findAllByReceiverIdAndStatus(userId, "pending");

// Objectify!
List<User> requesterUsers = new ArrayList<>();
for (FriendRequest request : pendingRequests) {
Long requesterId = request.getRequesterId();
Optional<User> requesterUser = userRepository.findById(requesterId);
if (requesterUser.isPresent()) {
requesterUsers.add(requesterUser.get());
}
}

modelAndView.addObject("friendUsers", friendUsers);
modelAndView.addObject("requesterUsers", requesterUsers);

return modelAndView;
}

@PostMapping("/friend_request/{requesterId}")
public RedirectView respondToFriendRequest(
@PathVariable Long requesterId,
@RequestParam String decision,
@AuthenticationPrincipal(expression = "attributes['email']") String email) {

// Get User!
Optional<User> userOptional = userRepository.findUserByUsername(email);

User currentUser = userOptional.get();
Long currentUserId = currentUser.getId();

// Get Friend Request!
Optional<FriendRequest> friendRequestOptional = friendRequestRepository
.findByRequesterIdAndReceiverIdAndStatus(requesterId, currentUserId, "pending");


FriendRequest friendRequest = friendRequestOptional.get();

if (decision.equals("accept")) {
friendRequest.setStatus("accepted");
Instant instant = Instant.now();
Timestamp now = Timestamp.from(instant);
friendRequest.setRespondedAt(now);
friendRequestRepository.save(friendRequest);


Friend friendship1 = new Friend();
friendship1.setMainUserId(currentUserId);
friendship1.setFriendUserId(requesterId);
friendship1.setFriendsSince(now);
friendRepository.save(friendship1);

Friend friendship2 = new Friend();
friendship2.setMainUserId(requesterId);
friendship2.setFriendUserId(currentUserId);
friendship2.setFriendsSince(now);
friendRepository.save(friendship2);

} else if (decision.equals("decline")) {
friendRequest.setStatus("rejected");
// friendRequest.setRespondedAt();
friendRequestRepository.save(friendRequest);
}

return new RedirectView("/friends");
}

// @PostMapping("/friends")
// public RedirectView create(@ModelAttribute Friend friend, @AuthenticationPrincipal(expression = "attributes['email']") String email) {
// Optional<User> user = userRepository.findUserByUsername(email);
// if (user.isPresent()) {
// Long id = user.get().getId();
// }
// return new RedirectView("friends/friends");
// }
}

Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

@Controller
public class HomeController {
@RequestMapping(value = "/")
public RedirectView index() {
return new RedirectView("/posts");
public ModelAndView index() {
return new ModelAndView("/landing");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.makersacademy.acebook.controller;

import com.makersacademy.acebook.model.Notification;
import com.makersacademy.acebook.model.User;
import com.makersacademy.acebook.repository.NotificationRepository;
import com.makersacademy.acebook.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.view.RedirectView;

import java.util.*;

@Controller
public class NotificationsController {

@Autowired
NotificationRepository notificationRepository;
@Autowired
UserRepository userRepository;


// Get notifications for current user
@GetMapping("/notifications")
public String index(Model model) {
DefaultOidcUser principal = (DefaultOidcUser) SecurityContextHolder
.getContext()
.getAuthentication()
.getPrincipal();
String username = (String) principal.getAttributes().get("email");
User currentUser = userRepository.findUserByUsername(username).get();

Collection<Notification> notifications = new ArrayList<>();
notifications.addAll(notificationRepository.findByReceivingUserIdOrderByCreatedAtDesc(2L));
Map<Long, String> senderNames = new HashMap<>();
for (Notification notification : notifications) {
Optional<User> sender = userRepository.findById(notification.getSendingUserId());
sender.ifPresent(user -> senderNames.put(notification.getId(), user.getFirst_name()));
}
model.addAttribute("notifications", notifications);
model.addAttribute("senderNames", senderNames);
return "notifications/index";
}


// Mark notification as read, redirect to specific post page
@PostMapping("/notifications")
public RedirectView markAsRead(@ModelAttribute Notification notification, @RequestParam String id) {
Long notificationId = Long.parseLong(id);
Optional<Notification> readNotification = notificationRepository.findById(notificationId);
if (readNotification.isPresent()) {
Notification activeNotification = readNotification.get();
activeNotification.setRead(true);
notificationRepository.save(activeNotification);
String postId = Long.toString(activeNotification.getPostId());
return new RedirectView("/posts/" + postId);
}
else {
return new RedirectView("genericErrorPage");
}
}
}
Loading