1
0
forked from PGL/Clyde
This commit is contained in:
Debucquoy Anthony 2024-04-17 21:41:29 +02:00
parent 94be706226
commit 8fa29460ef
Signed by untrusted user: tonitch
GPG Key ID: A78D6421F083D42E
10 changed files with 90 additions and 11 deletions

View File

@ -0,0 +1,8 @@
package ovh.herisson.Clyde.Repositories;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Notification;
interface NotificationRepository extends CrudRepository<Notification, Long> {}

View File

@ -17,6 +17,8 @@ import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.util.JSONPObject; import com.fasterxml.jackson.databind.util.JSONPObject;
import ovh.herisson.Clyde.Repositories.Msg.DiscussionRepository; import ovh.herisson.Clyde.Repositories.Msg.DiscussionRepository;
import ovh.herisson.Clyde.Services.UserService;
import ovh.herisson.Clyde.Tables.Notification;
import ovh.herisson.Clyde.Tables.User; import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.Msg.Discussion; import ovh.herisson.Clyde.Tables.Msg.Discussion;
import ovh.herisson.Clyde.Tables.Msg.Message; import ovh.herisson.Clyde.Tables.Msg.Message;
@ -26,6 +28,8 @@ public class DiscussionService {
@Autowired @Autowired
private DiscussionRepository discRepo; private DiscussionRepository discRepo;
@Autowired
private UserService userServ;
public Discussion create(String name, User author){ public Discussion create(String name, User author){
return discRepo.save(new Discussion(name, author)); return discRepo.save(new Discussion(name, author));
@ -42,6 +46,9 @@ public class DiscussionService {
* Create a message and link it to it's discussion * Create a message and link it to it's discussion
*/ */
public Discussion CreateMessage(Discussion disc, Message msg){ public Discussion CreateMessage(Discussion disc, Message msg){
for(User u: disc.getMembers()){
userServ.Notify(u, new Notification("msg.notification.new", msg.getContent(), "/#/msg"));
}
disc.addMessage(msg); disc.addMessage(msg);
return discRepo.save(disc); return discRepo.save(disc);
} }

View File

@ -0,0 +1,9 @@
package ovh.herisson.Clyde.Services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class NotificationService {
}

View File

@ -3,6 +3,7 @@ package ovh.herisson.Clyde.Services;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Repositories.UserRepository; import ovh.herisson.Clyde.Repositories.UserRepository;
import ovh.herisson.Clyde.Tables.Notification;
import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.User; import ovh.herisson.Clyde.Tables.User;
import java.util.*; import java.util.*;
@ -131,4 +132,10 @@ public class UserService {
public void delete(User user) { public void delete(User user) {
userRepo.delete(user); userRepo.delete(user);
} }
public void Notify(User u, Notification n){
n.setUser(u);
u.getNotifications().add(n);
userRepo.save(u);
}
} }

View File

@ -4,12 +4,17 @@ import java.util.Date;
import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.CreationTimestamp;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.annotation.Nullable;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
@Data @Data
@NoArgsConstructor
@Entity @Entity
public class Notification { public class Notification {
@ -21,11 +26,11 @@ public class Notification {
@Id @Id
private int id; private int id;
private String Subject; private String subject;
private String body; private String body;
private Status status; private Status status = Status.Unread;
private String link; private String link;
@ -34,4 +39,10 @@ public class Notification {
@CreationTimestamp @CreationTimestamp
private Date creation; private Date creation;
public Notification(String subject, @Nullable String body, @Nullable String link){
this.subject = subject;
this.body = body;
this.link = link;
}
} }

View File

@ -2,15 +2,19 @@ package ovh.herisson.Clyde.Tables;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import ovh.herisson.Clyde.Tables.Msg.Discussion; import ovh.herisson.Clyde.Tables.Msg.Discussion;
import ovh.herisson.Clyde.Tables.Msg.Message; import ovh.herisson.Clyde.Tables.Msg.Message;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity @Entity
@Table(name = "Users") @Table(name = "Users")
@NoArgsConstructor
@Data @Data
public class User { public class User {
@Id @Id
@ -24,19 +28,23 @@ public class User {
private String country; private String country;
private Date birthDate; private Date birthDate;
private String profilePictureUrl; private String profilePictureUrl;
private ovh.herisson.Clyde.Tables.Role role; private Role role;
@JsonIgnore
private String password; private String password;
@OneToMany(mappedBy = "user") @JsonIgnore
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Notification> notifications; private List<Notification> notifications;
////// Extension Messagerie ///// ////// Extension Messagerie /////
@JsonIgnore
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL) @OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
private List<Message> msgs; private List<Message> msgs;
/////////////////////////////////
@JsonIgnore
@ManyToMany( mappedBy = "members" ) @ManyToMany( mappedBy = "members" )
private List<Discussion> discussions; private List<Discussion> discussions;
/////////////////////////////////
public User(String lastName, String firstName, String email, String address, public User(String lastName, String firstName, String email, String address,
String country, Date birthDate, String profilePictureUrl, Role role, String password) String country, Date birthDate, String profilePictureUrl, Role role, String password)

View File

@ -52,3 +52,4 @@ Curriculum=curriculum
Credits=Credits Credits=Credits
InscriptionService=I.S. InscriptionService=I.S.
faculty=Faculty faculty=Faculty
msg.notification.new=You have a new message

View File

@ -52,3 +52,4 @@ Curriculum=Cursus
Credits=Credits Credits=Credits
InscriptionService=S.I. InscriptionService=S.I.
faculty=Faculté faculty=Faculté
msg.notification.new=Vous avez un nouveau message!

View File

@ -3,6 +3,7 @@
import { ref } from 'vue' import { ref } from 'vue'
import i18n, { setLang } from './i18n.js' import i18n, { setLang } from './i18n.js'
import { isLogged } from '@/rest/Users.js' import { isLogged } from '@/rest/Users.js'
import { notifications, fetchNotifications, archiveNotification } from '@/rest/notifications.js'
import { appList, currentView } from '@/rest/apps.js' import { appList, currentView } from '@/rest/apps.js'
var prevURL; var prevURL;
@ -14,16 +15,20 @@ window.onhashchange = function() {
} }
const Logged = ref(isLogged()); const Logged = ref(isLogged());
if(Logged){
fetchNotifications();
}
window.addEventListener('hashchange', () => { window.addEventListener('hashchange', () => {
if((location.hash === "#/home" && prevURL === "#/login") || (location.hash === "#/home" && prevURL === "#/profil")){ if((location.hash === "#/home" && prevURL === "#/login") || (location.hash === "#/home" && prevURL === "#/profil")){
window.location.reload(); window.location.reload();
} }
}); });
const home=ref(i18n("app.home")) const home=ref(i18n("app.home"))
const notifications=ref(i18n("app.notifications"))
const settings=ref(i18n("app.settings")) const settings=ref(i18n("app.settings"))
const login=ref(i18n("app.login")) const login=ref(i18n("app.login"))
const active=ref(false) const active=ref(false)
const notification = ref(false)
const apps = ref([]) const apps = ref([])
@ -46,11 +51,14 @@ window.addEventListener('hashchange', () => {
</a></li> </a></li>
<li style="float: right;" title=login> <li style="float: right;" title=login>
<a class="icon" href="#/login"> <a class="icon" href="#/login">
<div class="fa-solid fa-user" :style="Logged ? 'color: orange' : 'haha'" style="margin-top: 7px; margin-bottom: 3px; "></div> <div class="fa-solid fa-user" :style="Logged ? 'color: orange' : ''" style="margin-top: 7px; margin-bottom: 3px; "></div>
</a></li> </a></li>
<li style="float: right;" title=notifications> <li style="float: right;" title=notifications>
<a class="icon" href="#Notifications"> <a class="icon" @click.cancel="notification = !notification">
<div class="fa-solid fa-bell" style="margin-top: 7px; margin-bottom: 3px;"></div> <div class="fa-solid fa-bell" :style="notifications.length != 0 ? 'color:orange': '' " style="margin-top: 7px; margin-bottom: 3px;"></div>
<ul v-if=notification id="notification">
<li v-for="notif in notifications"> {{ i18n(notif.subject) }} - {{ notif.body }}</li>
</ul>
</a></li> </a></li>
<li @click="active=!active" class="option"style="float: right;" title=settings> <li @click="active=!active" class="option"style="float: right;" title=settings>
<a class="icon" > <a class="icon" >
@ -219,8 +227,6 @@ window.addEventListener('hashchange', () => {
background-color: black; background-color: black;
border-radius:6px; border-radius:6px;
color:white; color:white;
transform: translate(0px ,1px);
} }
ul.vertical:hover { ul.vertical:hover {
@ -253,6 +259,15 @@ window.addEventListener('hashchange', () => {
content: url("./assets/angry_clyde.png") content: url("./assets/angry_clyde.png")
} }
#notification{
position: absolute;
top: 61px;
right: 0;
background-color: white;
width: 300px;
height: 600px;
}
</style> </style>
<!-- vim:set noet sts=0 sw=4 ts=2: --> <!-- vim:set noet sts=0 sw=4 ts=2: -->

View File

@ -0,0 +1,12 @@
import { ref } from 'vue'
import { restGet, restPost } from '@/rest/restConsumer.js'
export const notifications = ref({});
export function fetchNotifications(){
restGet("/notifications").then( e => notifications.value = e );
}
export function archiveNotification(id){
restPost("/notifications/" + id).then( e => fetchNotifications() );
}