Работает отображеине и удаление постов с пагинацией
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.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.example.nekontakte.core.configurations.Constants;
|
||||
import com.example.nekontakte.posts.api.PostDTO;
|
||||
import com.example.nekontakte.posts.model.PostEntity;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
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 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;
|
||||
|
||||
@Controller
|
||||
@ -23,6 +25,7 @@ public class HomeCotroller {
|
||||
public static final String URL = "/";
|
||||
private static final String PAGE_ATTRIBUTE = "page";
|
||||
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 SUBS_VIEW = "subs";
|
||||
private static final String USER_PROFILE_VIEW = "user-profile";
|
||||
@ -37,14 +40,18 @@ public class HomeCotroller {
|
||||
|
||||
@GetMapping("/feed")
|
||||
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>();
|
||||
for (PostEntity postEntity : posts) {
|
||||
PostDTO postDTO = PostDTO.createFromEntity(postEntity);
|
||||
postDTOs.add(postDTO);
|
||||
}
|
||||
model.addAttribute("totalPages", pageEntities.getTotalPages());
|
||||
model.addAttribute("currentPage", pageEntities.getNumber());
|
||||
model.addAttribute(PAGE_ATTRIBUTE, page);
|
||||
model.addAttribute(POSTS_ATTRIBUTE, postDTOs);
|
||||
model.addAttribute(POST_ATTRIBUTE, new PostDTO());
|
||||
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;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import com.example.nekontakte.posts.model.PostEntity;
|
||||
import com.example.nekontakte.users.api.UserDTO;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
@ -28,11 +31,20 @@ public class PostDTO {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Date pubDate;
|
||||
@DateTimeFormat(pattern = "dd-MM-yyyy HH:mm")
|
||||
private LocalDateTime pubDate;
|
||||
|
||||
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() {
|
||||
return id;
|
||||
@ -42,11 +54,11 @@ public class PostDTO {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Date getPubDate() {
|
||||
public LocalDateTime getPubDate() {
|
||||
return pubDate;
|
||||
}
|
||||
|
||||
public void setPubDate(Date pubDate) {
|
||||
public void setPubDate(LocalDateTime pubDate) {
|
||||
this.pubDate = pubDate;
|
||||
}
|
||||
|
||||
@ -58,14 +70,6 @@ public class PostDTO {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public String getHtml() {
|
||||
return html;
|
||||
}
|
||||
|
||||
public void setHtml(String html) {
|
||||
this.html = html;
|
||||
}
|
||||
|
||||
public Integer getUserId() {
|
||||
return userId;
|
||||
}
|
||||
@ -78,7 +82,7 @@ public class PostDTO {
|
||||
PostDTO post = new PostDTO();
|
||||
post.setId(entity.getId());
|
||||
post.setUserId(entity.getUser().getId());
|
||||
post.setHtml(entity.getHtml());
|
||||
post.setText(entity.getHtml());
|
||||
post.setImage(entity.getImage());
|
||||
post.setPubDate(entity.getPubDate());
|
||||
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;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
@ -21,9 +22,9 @@ public class PostEntity extends BaseEntity {
|
||||
@JoinColumn(name = "userId", nullable = false)
|
||||
private UserEntity user;
|
||||
|
||||
@Temporal(value = TemporalType.DATE)
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
@Column(nullable = false)
|
||||
private Date pubDate;
|
||||
private LocalDateTime pubDate;
|
||||
|
||||
@Column
|
||||
private String image;
|
||||
@ -42,11 +43,11 @@ public class PostEntity extends BaseEntity {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public Date getPubDate() {
|
||||
public LocalDateTime getPubDate() {
|
||||
return pubDate;
|
||||
}
|
||||
|
||||
public void setPubDate(Date pubDate) {
|
||||
public void setPubDate(LocalDateTime 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.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
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.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.example.nekontakte.core.errors.NotFoundException;
|
||||
import com.example.nekontakte.posts.model.PostEntity;
|
||||
import com.example.nekontakte.posts.repository.PostRepository;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
@ -20,6 +26,15 @@ public class PostService {
|
||||
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)
|
||||
public Page<PostEntity> getAllByUserId(Integer userId, PageRequest pageRequest) {
|
||||
return repository.findByUserId(userId, pageRequest);
|
||||
@ -30,6 +45,12 @@ public class PostService {
|
||||
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)
|
||||
public Page<PostEntity> getAll(PageRequest pageRequest) {
|
||||
return repository.findAll(pageRequest);
|
||||
@ -49,6 +70,11 @@ public class PostService {
|
||||
if (entity.getImage() == null && entity.getHtml() == 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);
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,9 @@ public class UserService implements UserDetailsService {
|
||||
throw new IllegalArgumentException(
|
||||
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);
|
||||
}
|
||||
|
||||
@ -78,6 +81,7 @@ public class UserService implements UserDetailsService {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("User with username %s is already exists", entity.getUsername()));
|
||||
}
|
||||
entity.setAvatarImg("https://i.pravatar.cc/150?u=" + entity.getUsername());
|
||||
repository.save(entity);
|
||||
return existsentity;
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
@ -59,3 +63,69 @@ td form {
|
||||
textarea {
|
||||
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>
|
||||
<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
|
||||
sec:authorize="isAuthenticated()"
|
||||
method="post"
|
||||
th:action="@{/posts/create/{username}(username=${#authentication.name})}"
|
||||
class="d-flex flex-column mb-3 mt-2"
|
||||
th:object="${post}"
|
||||
>
|
||||
<!-- <input type="hidden" th:name="page" th:value="${page}" /> -->
|
||||
<textarea
|
||||
name="postBody"
|
||||
class="mb-3"
|
||||
placeholder="Напишите что-нибудь..."
|
||||
th:field="*{text}"
|
||||
required
|
||||
class="mb-3 form-control"
|
||||
></textarea>
|
||||
<button type="submit" class="btn btn-primary">Опубликовать</button>
|
||||
</form>
|
||||
@ -39,9 +43,9 @@
|
||||
</th:block>
|
||||
<th:block
|
||||
th:replace="~{ pagination :: pagination (
|
||||
url=${'admin/users'},
|
||||
totalPages=${totalPages},
|
||||
currentPage=${currentPage}) }"
|
||||
url=${'feed'},
|
||||
totalPages=${totalPages},
|
||||
currentPage=${currentPage}) }"
|
||||
/>
|
||||
</th:block>
|
||||
</div>
|
||||
|
@ -80,8 +80,7 @@
|
||||
</a>
|
||||
<a
|
||||
class="nav-link"
|
||||
th:href="@{/me}"
|
||||
th:classappend="${activeLink.startsWith('/me') ? 'active' : ''}"
|
||||
th:href="@{/user/{username}(username=${#authentication.name})}"
|
||||
>
|
||||
Профиль
|
||||
</a>
|
||||
|
@ -1,48 +1,105 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<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 class="post-header py-1 ps-1 pe-2 d-flex border-bottom justify-content-between align-items-center">
|
||||
<Link to="@{/user/${post.user.username}}"
|
||||
class="hoverable d-flex justify-content-start align-items-center rounded-pill px-1">
|
||||
<div class="post-author-avatar-wrapper">
|
||||
<img src="#" class="post-author-avatar avatar-small rounded-circle" />
|
||||
</div>
|
||||
<div class="post-meta mx-2 d-flex flex-column justify-content-center">
|
||||
<div class="post-author-name">
|
||||
[[${post.user.name}]] [[${post.user.surname}]]
|
||||
</div>
|
||||
<div class="post-publication-datetime">
|
||||
[[${post.pubDate}]]
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
<div class='d-flex'>
|
||||
<i class='fs-6 bi bi-pencil' title='Редактировать пост'></i>
|
||||
<i class='fs-6 bi bi-trash' title='Удалить пост'></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="post-body">
|
||||
<div th:if="${post.html != null}" class="post-body-text m-2">
|
||||
[[${post.html}]]
|
||||
</div>
|
||||
<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
|
||||
class="post-header py-1 ps-1 pe-2 d-flex border-bottom justify-content-between align-items-center"
|
||||
>
|
||||
<div
|
||||
class="hoverable d-flex justify-content-start align-items-center rounded-pill px-1"
|
||||
>
|
||||
<div class="post-author-avatar-wrapper">
|
||||
<img
|
||||
th:src="${post.userDTO.avatarImg}"
|
||||
class="post-author-avatar avatar-small rounded-circle"
|
||||
/>
|
||||
</div>
|
||||
<div class="post-meta mx-2 d-flex flex-column justify-content-center">
|
||||
<div class="post-author-name d-flex">
|
||||
<div
|
||||
class="d-flex me-1"
|
||||
th:unless="${#strings.isEmpty(post.userDTO.name) || #strings.isEmpty(post.userDTO.name)}"
|
||||
>
|
||||
[[${post.userDTO.name}]] [[${post.userDTO.surname}]]
|
||||
</div>
|
||||
<a
|
||||
th:href="@{/user/{username}(username=${post.userDTO.username})}"
|
||||
class="username-link"
|
||||
>
|
||||
[[${post.userDTO.username}]]
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="post-publication-datetime"
|
||||
th:text="${#temporals.format(post.pubDate, 'yyyy-MM-dd HH:mm')}"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div sec:authorize="${hasRole('ADMIN')}" class="d-flex">
|
||||
<th:block th:replace="~{::post-actions (${post.id})}"> </th:block>
|
||||
</div>
|
||||
<div
|
||||
sec:authorize="${hasRole('USER')}"
|
||||
th:if="${#authentication.name == post.userDTO.username}"
|
||||
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}" 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>
|
||||
</body>
|
||||
<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