Работает отображеине и удаление постов с пагинацией
This commit is contained in:
parent
8162b23dd2
commit
9e4b5a06a9
@ -2,9 +2,13 @@ package com.example.nekontakte.core.api;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.example.nekontakte.core.configurations.Constants;
|
||||||
import com.example.nekontakte.posts.api.PostDTO;
|
import com.example.nekontakte.posts.api.PostDTO;
|
||||||
import com.example.nekontakte.posts.model.PostEntity;
|
import com.example.nekontakte.posts.model.PostEntity;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@ -13,8 +17,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
import com.example.nekontakte.posts.service.PostService;
|
import com.example.nekontakte.posts.service.PostService;
|
||||||
import com.example.nekontakte.users.api.UserDTO;
|
|
||||||
import com.example.nekontakte.users.api.UserEditDTO;
|
|
||||||
import com.example.nekontakte.users.service.UserService;
|
import com.example.nekontakte.users.service.UserService;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@ -23,6 +25,7 @@ public class HomeCotroller {
|
|||||||
public static final String URL = "/";
|
public static final String URL = "/";
|
||||||
private static final String PAGE_ATTRIBUTE = "page";
|
private static final String PAGE_ATTRIBUTE = "page";
|
||||||
private static final String POSTS_ATTRIBUTE = "posts";
|
private static final String POSTS_ATTRIBUTE = "posts";
|
||||||
|
private static final String POST_ATTRIBUTE = "post";
|
||||||
private static final String FEED_VIEW = "feed";
|
private static final String FEED_VIEW = "feed";
|
||||||
private static final String SUBS_VIEW = "subs";
|
private static final String SUBS_VIEW = "subs";
|
||||||
private static final String USER_PROFILE_VIEW = "user-profile";
|
private static final String USER_PROFILE_VIEW = "user-profile";
|
||||||
@ -37,14 +40,18 @@ public class HomeCotroller {
|
|||||||
|
|
||||||
@GetMapping("/feed")
|
@GetMapping("/feed")
|
||||||
public String getFeed(@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page, Model model) {
|
public String getFeed(@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page, Model model) {
|
||||||
List<PostEntity> posts = postsService.getAll();
|
Page<PostEntity> pageEntities = postsService.getAll(page, 4);
|
||||||
|
List<PostEntity> posts = pageEntities.getContent();
|
||||||
List<PostDTO> postDTOs = new ArrayList<PostDTO>();
|
List<PostDTO> postDTOs = new ArrayList<PostDTO>();
|
||||||
for (PostEntity postEntity : posts) {
|
for (PostEntity postEntity : posts) {
|
||||||
PostDTO postDTO = PostDTO.createFromEntity(postEntity);
|
PostDTO postDTO = PostDTO.createFromEntity(postEntity);
|
||||||
postDTOs.add(postDTO);
|
postDTOs.add(postDTO);
|
||||||
}
|
}
|
||||||
|
model.addAttribute("totalPages", pageEntities.getTotalPages());
|
||||||
|
model.addAttribute("currentPage", pageEntities.getNumber());
|
||||||
model.addAttribute(PAGE_ATTRIBUTE, page);
|
model.addAttribute(PAGE_ATTRIBUTE, page);
|
||||||
model.addAttribute(POSTS_ATTRIBUTE, postDTOs);
|
model.addAttribute(POSTS_ATTRIBUTE, postDTOs);
|
||||||
|
model.addAttribute(POST_ATTRIBUTE, new PostDTO());
|
||||||
return FEED_VIEW;
|
return FEED_VIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
package com.example.nekontakte.posts.api;
|
|
||||||
|
|
||||||
import com.example.nekontakte.core.api.PageDto;
|
|
||||||
import com.example.nekontakte.core.api.PageDtoMapper;
|
|
||||||
import com.example.nekontakte.core.configurations.Constants;
|
|
||||||
|
|
||||||
import org.apache.coyote.BadRequestException;
|
|
||||||
import org.modelmapper.ModelMapper;
|
|
||||||
import org.springframework.data.domain.PageRequest;
|
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import com.example.nekontakte.posts.model.PostEntity;
|
|
||||||
import com.example.nekontakte.posts.service.PostService;
|
|
||||||
import com.example.nekontakte.users.service.UserService;
|
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping(Constants.API_URL + "/post")
|
|
||||||
public class PostController {
|
|
||||||
|
|
||||||
private final PostService postService;
|
|
||||||
private final ModelMapper modelMapper;
|
|
||||||
|
|
||||||
public PostController(PostService postService, ModelMapper modelMapper, UserService userService) {
|
|
||||||
this.modelMapper = modelMapper;
|
|
||||||
this.postService = postService;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PostEntity toEntity(PostDTO dto) {
|
|
||||||
return modelMapper.map(dto, PostEntity.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private PostDTO toDTO(PostEntity entity) {
|
|
||||||
return modelMapper.map(entity, PostDTO.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping
|
|
||||||
public PageDto<PostDTO> getAll(@RequestParam(name = "pageNumber", defaultValue = "0") Integer pageNumber,
|
|
||||||
@RequestParam(name = "pageSize", defaultValue = "5") Integer pageSize) {
|
|
||||||
PageRequest pageRequest = PageRequest.of(pageNumber, pageSize);
|
|
||||||
return PageDtoMapper.toDto(postService.getAll(pageRequest), this::toDTO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/user/{userId}")
|
|
||||||
public PageDto<PostDTO> getAllByUserId(@PathVariable(name = "userId") Integer userId,
|
|
||||||
@RequestParam(name = "pageNumber", defaultValue = "0") Integer pageNumber,
|
|
||||||
@RequestParam(name = "pageSize", defaultValue = "5") Integer pageSize) {
|
|
||||||
PageRequest pageRequest = PageRequest.of(pageNumber, pageSize);
|
|
||||||
return PageDtoMapper.toDto(postService.getAllByUserId(userId, pageRequest), this::toDTO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/{id}")
|
|
||||||
public PostDTO get(@PathVariable(name = "id") Integer id) {
|
|
||||||
return toDTO(postService.get(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping
|
|
||||||
public PostDTO create(@RequestBody @Valid PostDTO PostDTO) throws BadRequestException {
|
|
||||||
return toDTO(postService.create(toEntity(PostDTO)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PutMapping("/{id}")
|
|
||||||
public PostDTO update(@PathVariable(name = "id") Integer id, @RequestBody PostDTO PostDTO) {
|
|
||||||
return toDTO(postService.update(id, toEntity(PostDTO)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@DeleteMapping("/{id}")
|
|
||||||
public PostDTO delete(@PathVariable(name = "id") Integer id) {
|
|
||||||
return toDTO(postService.delete(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,7 +1,10 @@
|
|||||||
package com.example.nekontakte.posts.api;
|
package com.example.nekontakte.posts.api;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
import com.example.nekontakte.posts.model.PostEntity;
|
import com.example.nekontakte.posts.model.PostEntity;
|
||||||
import com.example.nekontakte.users.api.UserDTO;
|
import com.example.nekontakte.users.api.UserDTO;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
@ -28,11 +31,20 @@ public class PostDTO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Date pubDate;
|
@DateTimeFormat(pattern = "dd-MM-yyyy HH:mm")
|
||||||
|
private LocalDateTime pubDate;
|
||||||
|
|
||||||
private String image;
|
private String image;
|
||||||
|
|
||||||
private String html;
|
private String text;
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
public Integer getId() {
|
public Integer getId() {
|
||||||
return id;
|
return id;
|
||||||
@ -42,11 +54,11 @@ public class PostDTO {
|
|||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getPubDate() {
|
public LocalDateTime getPubDate() {
|
||||||
return pubDate;
|
return pubDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPubDate(Date pubDate) {
|
public void setPubDate(LocalDateTime pubDate) {
|
||||||
this.pubDate = pubDate;
|
this.pubDate = pubDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,14 +70,6 @@ public class PostDTO {
|
|||||||
this.image = image;
|
this.image = image;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHtml() {
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHtml(String html) {
|
|
||||||
this.html = html;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getUserId() {
|
public Integer getUserId() {
|
||||||
return userId;
|
return userId;
|
||||||
}
|
}
|
||||||
@ -78,7 +82,7 @@ public class PostDTO {
|
|||||||
PostDTO post = new PostDTO();
|
PostDTO post = new PostDTO();
|
||||||
post.setId(entity.getId());
|
post.setId(entity.getId());
|
||||||
post.setUserId(entity.getUser().getId());
|
post.setUserId(entity.getUser().getId());
|
||||||
post.setHtml(entity.getHtml());
|
post.setText(entity.getHtml());
|
||||||
post.setImage(entity.getImage());
|
post.setImage(entity.getImage());
|
||||||
post.setPubDate(entity.getPubDate());
|
post.setPubDate(entity.getPubDate());
|
||||||
post.setUserDTO(UserDTO.createFromEntity(entity.getUser()));
|
post.setUserDTO(UserDTO.createFromEntity(entity.getUser()));
|
||||||
|
@ -0,0 +1,83 @@
|
|||||||
|
package com.example.nekontakte.posts.api;
|
||||||
|
|
||||||
|
import com.example.nekontakte.core.configurations.Constants;
|
||||||
|
|
||||||
|
import org.apache.coyote.BadRequestException;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||||
|
|
||||||
|
import com.example.nekontakte.posts.model.PostEntity;
|
||||||
|
import com.example.nekontakte.posts.service.PostService;
|
||||||
|
import com.example.nekontakte.users.service.UserService;
|
||||||
|
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping(PostsController.URL)
|
||||||
|
public class PostsController {
|
||||||
|
public static final String URL = "/posts";
|
||||||
|
private static final String PAGE_ATTRIBUTE = "page";
|
||||||
|
private static final String POST_ATTRIBUTE = "post";
|
||||||
|
|
||||||
|
private final PostService postService;
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
|
public PostsController(PostService postService, UserService userService) {
|
||||||
|
this.userService = userService;
|
||||||
|
this.postService = postService;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PostEntity toEntity(PostDTO dto) {
|
||||||
|
PostEntity entity = new PostEntity();
|
||||||
|
entity.setId(dto.getId());
|
||||||
|
entity.setHtml(dto.getText());
|
||||||
|
entity.setImage(dto.getImage());
|
||||||
|
entity.setPubDate(dto.getPubDate());
|
||||||
|
entity.setUser(userService.get(dto.getUserId()));
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PostDTO toDTO(PostEntity entity) {
|
||||||
|
return PostDTO.createFromEntity(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/create/{username}")
|
||||||
|
public String create(Model model,
|
||||||
|
@PathVariable(name = "username") String username,
|
||||||
|
@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
|
||||||
|
@ModelAttribute(name = POST_ATTRIBUTE) @Valid PostDTO postDTO,
|
||||||
|
RedirectAttributes redirectAttributes) throws BadRequestException {
|
||||||
|
|
||||||
|
postDTO.setUserId(userService.getByUsername(username).getId());
|
||||||
|
|
||||||
|
postService.create(toEntity(postDTO));
|
||||||
|
|
||||||
|
redirectAttributes.addAttribute(PAGE_ATTRIBUTE, page);
|
||||||
|
|
||||||
|
return Constants.REDIRECT_VIEW + "/feed";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/{id}")
|
||||||
|
public PostDTO update(@PathVariable(name = "id") Integer id, @RequestBody PostDTO PostDTO) {
|
||||||
|
return toDTO(postService.update(id, toEntity(PostDTO)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/delete/{id}")
|
||||||
|
public String delete(@PathVariable(name = "id") Integer id,
|
||||||
|
@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
|
||||||
|
RedirectAttributes redirectAttributes,
|
||||||
|
Model model) {
|
||||||
|
postService.delete(id);
|
||||||
|
redirectAttributes.addAttribute(PAGE_ATTRIBUTE, page);
|
||||||
|
return Constants.REDIRECT_VIEW + "/feed";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.example.nekontakte.posts.model;
|
package com.example.nekontakte.posts.model;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@ -21,9 +22,9 @@ public class PostEntity extends BaseEntity {
|
|||||||
@JoinColumn(name = "userId", nullable = false)
|
@JoinColumn(name = "userId", nullable = false)
|
||||||
private UserEntity user;
|
private UserEntity user;
|
||||||
|
|
||||||
@Temporal(value = TemporalType.DATE)
|
@Temporal(value = TemporalType.TIMESTAMP)
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private Date pubDate;
|
private LocalDateTime pubDate;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
private String image;
|
private String image;
|
||||||
@ -42,11 +43,11 @@ public class PostEntity extends BaseEntity {
|
|||||||
this.user = user;
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getPubDate() {
|
public LocalDateTime getPubDate() {
|
||||||
return pubDate;
|
return pubDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPubDate(Date pubDate) {
|
public void setPubDate(LocalDateTime pubDate) {
|
||||||
this.pubDate = pubDate;
|
this.pubDate = pubDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package com.example.nekontakte.posts.repository;
|
|||||||
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||||
|
|
||||||
|
@ -2,13 +2,19 @@ package com.example.nekontakte.posts.service;
|
|||||||
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.data.domain.Sort.Direction;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
import com.example.nekontakte.core.errors.NotFoundException;
|
import com.example.nekontakte.core.errors.NotFoundException;
|
||||||
import com.example.nekontakte.posts.model.PostEntity;
|
import com.example.nekontakte.posts.model.PostEntity;
|
||||||
import com.example.nekontakte.posts.repository.PostRepository;
|
import com.example.nekontakte.posts.repository.PostRepository;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
@ -20,6 +26,15 @@ public class PostService {
|
|||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<PostEntity> getSorted(List<PostEntity> posts) {
|
||||||
|
posts.sort(new Comparator<PostEntity>() {
|
||||||
|
public int compare(PostEntity o1, PostEntity o2) {
|
||||||
|
return o1.getPubDate().compareTo(o2.getPubDate());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return posts;
|
||||||
|
}
|
||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public Page<PostEntity> getAllByUserId(Integer userId, PageRequest pageRequest) {
|
public Page<PostEntity> getAllByUserId(Integer userId, PageRequest pageRequest) {
|
||||||
return repository.findByUserId(userId, pageRequest);
|
return repository.findByUserId(userId, pageRequest);
|
||||||
@ -30,6 +45,12 @@ public class PostService {
|
|||||||
return repository.findByUserId(userId);
|
return repository.findByUserId(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public Page<PostEntity> getAll(Integer pageNumber, Integer pageSize) {
|
||||||
|
PageRequest pageRequest = PageRequest.of(pageNumber, pageSize, Sort.by(Direction.DESC, "pubDate"));
|
||||||
|
return repository.findAll(pageRequest);
|
||||||
|
}
|
||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public Page<PostEntity> getAll(PageRequest pageRequest) {
|
public Page<PostEntity> getAll(PageRequest pageRequest) {
|
||||||
return repository.findAll(pageRequest);
|
return repository.findAll(pageRequest);
|
||||||
@ -49,6 +70,11 @@ public class PostService {
|
|||||||
if (entity.getImage() == null && entity.getHtml() == null) {
|
if (entity.getImage() == null && entity.getHtml() == null) {
|
||||||
throw new org.apache.coyote.BadRequestException("Image or Html must be not null");
|
throw new org.apache.coyote.BadRequestException("Image or Html must be not null");
|
||||||
}
|
}
|
||||||
|
entity.setPubDate(LocalDateTime.now());
|
||||||
|
Random rand = new Random();
|
||||||
|
if (rand.nextBoolean()) {
|
||||||
|
entity.setImage("https://loremflickr.com/240/320?lock=" + Integer.toString(rand.nextInt(0, 1000000)));
|
||||||
|
}
|
||||||
return repository.save(entity);
|
return repository.save(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ public class AdminUserController {
|
|||||||
}
|
}
|
||||||
return Constants.REDIRECT_VIEW + URL;
|
return Constants.REDIRECT_VIEW + URL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/delete/{id}")
|
@PostMapping("/delete/{id}")
|
||||||
public String postDeleteView(
|
public String postDeleteView(
|
||||||
@PathVariable(name = "id") Integer id,
|
@PathVariable(name = "id") Integer id,
|
||||||
|
@ -68,6 +68,9 @@ public class UserService implements UserDetailsService {
|
|||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
String.format("User with username %s is already exists", entity.getUsername()));
|
String.format("User with username %s is already exists", entity.getUsername()));
|
||||||
}
|
}
|
||||||
|
if (entity.getAvatarImg() == null) {
|
||||||
|
entity.setAvatarImg("https://i.pravatar.cc/150?u=" + entity.getUsername());
|
||||||
|
}
|
||||||
return repository.save(entity);
|
return repository.save(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +81,7 @@ public class UserService implements UserDetailsService {
|
|||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
String.format("User with username %s is already exists", entity.getUsername()));
|
String.format("User with username %s is already exists", entity.getUsername()));
|
||||||
}
|
}
|
||||||
|
entity.setAvatarImg("https://i.pravatar.cc/150?u=" + entity.getUsername());
|
||||||
repository.save(entity);
|
repository.save(entity);
|
||||||
return existsentity;
|
return existsentity;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -59,3 +63,69 @@ td form {
|
|||||||
textarea {
|
textarea {
|
||||||
min-height: 1.5em;
|
min-height: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.post-meta {
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter-block {
|
||||||
|
transition: 0.1s;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter-block:hover {
|
||||||
|
background-color: #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-body-img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-body a {
|
||||||
|
color: #4a9cb7;
|
||||||
|
text-decoration: none;
|
||||||
|
background-image: linear-gradient(currentColor, currentColor);
|
||||||
|
background-position: 0% 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 0% 2px;
|
||||||
|
transition: background-size 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-body a:hover {
|
||||||
|
background-size: 100% 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-body-text {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-small {
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username-link {
|
||||||
|
transition: 0.3s;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username-link::before {
|
||||||
|
content: "@";
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username-link::hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.b1 {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
cursor: pointer;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
@ -12,17 +12,21 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<main layout:fragment="content">
|
<main layout:fragment="content">
|
||||||
<div class="container d-flex flex-column w-50 flex-fill">
|
<div
|
||||||
|
class="container d-flex flex-column w-50 flex-fill"
|
||||||
|
sec:authorize="isAuthenticated()"
|
||||||
|
>
|
||||||
<form
|
<form
|
||||||
sec:authorize="isAuthenticated()"
|
|
||||||
method="post"
|
method="post"
|
||||||
th:action="@{/posts/create/{username}(username=${#authentication.name})}"
|
th:action="@{/posts/create/{username}(username=${#authentication.name})}"
|
||||||
class="d-flex flex-column mb-3 mt-2"
|
class="d-flex flex-column mb-3 mt-2"
|
||||||
|
th:object="${post}"
|
||||||
>
|
>
|
||||||
|
<!-- <input type="hidden" th:name="page" th:value="${page}" /> -->
|
||||||
<textarea
|
<textarea
|
||||||
name="postBody"
|
th:field="*{text}"
|
||||||
class="mb-3"
|
required
|
||||||
placeholder="Напишите что-нибудь..."
|
class="mb-3 form-control"
|
||||||
></textarea>
|
></textarea>
|
||||||
<button type="submit" class="btn btn-primary">Опубликовать</button>
|
<button type="submit" class="btn btn-primary">Опубликовать</button>
|
||||||
</form>
|
</form>
|
||||||
@ -39,9 +43,9 @@
|
|||||||
</th:block>
|
</th:block>
|
||||||
<th:block
|
<th:block
|
||||||
th:replace="~{ pagination :: pagination (
|
th:replace="~{ pagination :: pagination (
|
||||||
url=${'admin/users'},
|
url=${'feed'},
|
||||||
totalPages=${totalPages},
|
totalPages=${totalPages},
|
||||||
currentPage=${currentPage}) }"
|
currentPage=${currentPage}) }"
|
||||||
/>
|
/>
|
||||||
</th:block>
|
</th:block>
|
||||||
</div>
|
</div>
|
||||||
|
@ -80,8 +80,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
class="nav-link"
|
class="nav-link"
|
||||||
th:href="@{/me}"
|
th:href="@{/user/{username}(username=${#authentication.name})}"
|
||||||
th:classappend="${activeLink.startsWith('/me') ? 'active' : ''}"
|
|
||||||
>
|
>
|
||||||
Профиль
|
Профиль
|
||||||
</a>
|
</a>
|
||||||
|
@ -1,48 +1,105 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<body>
|
<body>
|
||||||
<div th:fragment="post (post)" class="post mb-2 mb-sm-4 w-100 d-flex flex-column border rounded-2" id="post-${post.id}">
|
<div
|
||||||
<div class="post-header py-1 ps-1 pe-2 d-flex border-bottom justify-content-between align-items-center">
|
th:fragment="post (post)"
|
||||||
<Link to="@{/user/${post.user.username}}"
|
class="post mb-2 mb-sm-4 w-100 d-flex flex-column border rounded-2"
|
||||||
class="hoverable d-flex justify-content-start align-items-center rounded-pill px-1">
|
id="post-${post.id}"
|
||||||
<div class="post-author-avatar-wrapper">
|
>
|
||||||
<img src="#" class="post-author-avatar avatar-small rounded-circle" />
|
<div
|
||||||
</div>
|
class="post-header py-1 ps-1 pe-2 d-flex border-bottom justify-content-between align-items-center"
|
||||||
<div class="post-meta mx-2 d-flex flex-column justify-content-center">
|
>
|
||||||
<div class="post-author-name">
|
<div
|
||||||
[[${post.user.name}]] [[${post.user.surname}]]
|
class="hoverable d-flex justify-content-start align-items-center rounded-pill px-1"
|
||||||
</div>
|
>
|
||||||
<div class="post-publication-datetime">
|
<div class="post-author-avatar-wrapper">
|
||||||
[[${post.pubDate}]]
|
<img
|
||||||
</div>
|
th:src="${post.userDTO.avatarImg}"
|
||||||
</div>
|
class="post-author-avatar avatar-small rounded-circle"
|
||||||
</Link>
|
/>
|
||||||
<div class='d-flex'>
|
</div>
|
||||||
<i class='fs-6 bi bi-pencil' title='Редактировать пост'></i>
|
<div class="post-meta mx-2 d-flex flex-column justify-content-center">
|
||||||
<i class='fs-6 bi bi-trash' title='Удалить пост'></i>
|
<div class="post-author-name d-flex">
|
||||||
</div>
|
<div
|
||||||
</div>
|
class="d-flex me-1"
|
||||||
<div class="post-body">
|
th:unless="${#strings.isEmpty(post.userDTO.name) || #strings.isEmpty(post.userDTO.name)}"
|
||||||
<div th:if="${post.html != null}" class="post-body-text m-2">
|
>
|
||||||
[[${post.html}]]
|
[[${post.userDTO.name}]] [[${post.userDTO.surname}]]
|
||||||
</div>
|
</div>
|
||||||
|
<a
|
||||||
|
th:href="@{/user/{username}(username=${post.userDTO.username})}"
|
||||||
<img th:if="${post.image != null}" src="${post.image}" class="post-body-img img-fluid" />
|
class="username-link"
|
||||||
</div>
|
>
|
||||||
<div class="post-footer py-1 px-2 border-top d-flex">
|
[[${post.userDTO.username}]]
|
||||||
<div class="hoverable counter-block likes-block px-2 me-1 d-flex align-items-center rounded-4">
|
</a>
|
||||||
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
</div>
|
||||||
<g fill="none" fillRule="evenodd">
|
<div
|
||||||
<path d="M0 0h24v24H0z"></path>
|
class="post-publication-datetime"
|
||||||
<path
|
th:text="${#temporals.format(post.pubDate, 'yyyy-MM-dd HH:mm')}"
|
||||||
d="M16 4a5.95 5.95 0 0 0-3.89 1.7l-.12.11-.12-.11A5.96 5.96 0 0 0 7.73 4 5.73 5.73 0 0 0 2 9.72c0 3.08 1.13 4.55 6.18 8.54l2.69 2.1c.66.52 1.6.52 2.26 0l2.36-1.84.94-.74c4.53-3.64 5.57-5.1 5.57-8.06A5.73 5.73 0 0 0 16.27 4zm.27 1.8a3.93 3.93 0 0 1 3.93 3.92v.3c-.08 2.15-1.07 3.33-5.51 6.84l-2.67 2.08a.04.04 0 0 1-.04 0L9.6 17.1l-.87-.7C4.6 13.1 3.8 11.98 3.8 9.73A3.93 3.93 0 0 1 7.73 5.8c1.34 0 2.51.62 3.57 1.92a.9.9 0 0 0 1.4-.01c1.04-1.3 2.2-1.91 3.57-1.91z"
|
></div>
|
||||||
fill="currentColor" fillRule="nonzero"></path>
|
</div>
|
||||||
</g>
|
</div>
|
||||||
</svg>
|
<div sec:authorize="${hasRole('ADMIN')}" class="d-flex">
|
||||||
<span class="count ms-1">734</span>
|
<th:block th:replace="~{::post-actions (${post.id})}"> </th:block>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div
|
||||||
</div>
|
sec:authorize="${hasRole('USER')}"
|
||||||
</body>
|
th:if="${#authentication.name == post.userDTO.username}"
|
||||||
</html>
|
class="d-flex"
|
||||||
|
>
|
||||||
|
<th:block th:replace="~{::post-actions (${post.id})}"> </th:block>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="post-body">
|
||||||
|
<div
|
||||||
|
th:unless="${#strings.isEmpty(post.text)}"
|
||||||
|
class="post-body-text m-2"
|
||||||
|
th:text="${post.text}"
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<img
|
||||||
|
th:if="${post.image != null}"
|
||||||
|
th:src="${post.image}"
|
||||||
|
class="post-body-img img-fluid"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="post-footer py-1 px-2 border-top d-flex">
|
||||||
|
<div
|
||||||
|
class="hoverable counter-block likes-block px-2 me-1 d-flex align-items-center rounded-4"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<g fill="none" fillRule="evenodd">
|
||||||
|
<path d="M0 0h24v24H0z"></path>
|
||||||
|
<path
|
||||||
|
d="M16 4a5.95 5.95 0 0 0-3.89 1.7l-.12.11-.12-.11A5.96 5.96 0 0 0 7.73 4 5.73 5.73 0 0 0 2 9.72c0 3.08 1.13 4.55 6.18 8.54l2.69 2.1c.66.52 1.6.52 2.26 0l2.36-1.84.94-.74c4.53-3.64 5.57-5.1 5.57-8.06A5.73 5.73 0 0 0 16.27 4zm.27 1.8a3.93 3.93 0 0 1 3.93 3.92v.3c-.08 2.15-1.07 3.33-5.51 6.84l-2.67 2.08a.04.04 0 0 1-.04 0L9.6 17.1l-.87-.7C4.6 13.1 3.8 11.98 3.8 9.73A3.93 3.93 0 0 1 7.73 5.8c1.34 0 2.51.62 3.57 1.92a.9.9 0 0 0 1.4-.01c1.04-1.3 2.2-1.91 3.57-1.91z"
|
||||||
|
fill="currentColor"
|
||||||
|
fillRule="nonzero"
|
||||||
|
></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
<span class="count ms-1">734</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<th:block th:fragment="post-actions (postId)">
|
||||||
|
<i
|
||||||
|
class="fs-6 bi bi-pencil me-2 text-warning-emphasis"
|
||||||
|
title="Редактировать пост"
|
||||||
|
></i>
|
||||||
|
<form th:action="@{/posts/delete/{id}(id=${postId})}" method="post">
|
||||||
|
<input type="hidden" th:name="page" th:value="${page}" />
|
||||||
|
<button type="submit" class="b1">
|
||||||
|
<i
|
||||||
|
class="fs-6 bi bi-trash text-danger-emphasis"
|
||||||
|
title="Удалить пост"
|
||||||
|
></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</th:block>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user