70 changed files with 1263 additions and 409 deletions
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
importScripts('https://cdn.onesignal.com/sdks/OneSignalSDKWorker.js'); |
@ -1,5 +1,12 @@
@@ -1,5 +1,12 @@
|
||||
import { IPagination } from "@/shared"; |
||||
|
||||
export interface IFetchNotification extends IPagination { |
||||
export interface IFetchNotification extends IPagination {} |
||||
|
||||
} |
||||
export interface ISaveDevicePayload { |
||||
deviceUuid: string; |
||||
notificationUserId: string; |
||||
} |
||||
|
||||
export interface IReadNotificationsPayload { |
||||
ids: number[] |
||||
} |
||||
|
@ -1,14 +1,29 @@
@@ -1,14 +1,29 @@
|
||||
import http from '../http.service' |
||||
import { ApiResponse } from '../http.types' |
||||
import * as Req from './request.interfaces' |
||||
import * as Res from './response.interfaces' |
||||
import http from "../http.service"; |
||||
import { ApiResponse } from "../http.types"; |
||||
import * as Req from "./request.interfaces"; |
||||
import * as Res from "./response.interfaces"; |
||||
|
||||
const fetchNotificationsList = ( |
||||
params: Req.IFetchNotification, |
||||
params: Req.IFetchNotification |
||||
): ApiResponse<Res.INotificationsList> => { |
||||
return http.get<Res.INotificationsList>(`admin/notifications`, { params }) |
||||
} |
||||
return http.get<Res.INotificationsList>(`admin/notifications`, { params }); |
||||
}; |
||||
|
||||
export const saveUserDevice = (payload: Req.ISaveDevicePayload) => { |
||||
return http.post("admin/notifications/device", payload); |
||||
}; |
||||
|
||||
const readAll = () => { |
||||
return http.put<void>("admin/notifications/read", {}); |
||||
}; |
||||
|
||||
const readByIds = (payload: Req.IReadNotificationsPayload) => { |
||||
return http.put<void>("admin/notifications/read-by-ids", payload); |
||||
}; |
||||
|
||||
export const notificApi = { |
||||
fetchNotificationsList |
||||
} |
||||
fetchNotificationsList, |
||||
saveUserDevice, |
||||
readAll, |
||||
readByIds |
||||
}; |
||||
|
@ -1,4 +1,57 @@
@@ -1,4 +1,57 @@
|
||||
import { RouteEnum } from "@/containers/App/router"; |
||||
import { IPushNotification, NotificationKeys } from "@/shared"; |
||||
import { SelectChatId } from "@/store/chats"; |
||||
import { simpleDispatch } from "@/store/store-helpers"; |
||||
|
||||
export const dataNotifications = { |
||||
nameNotification: 'Зробити дизайн мобільн...', |
||||
time: '17:45' |
||||
} |
||||
nameNotification: "Зробити дизайн мобільн...", |
||||
time: "17:45" |
||||
}; |
||||
|
||||
export const notificationActions = ( |
||||
notification: IPushNotification, |
||||
history: any |
||||
) => ({ |
||||
[NotificationKeys.NEW_MESSAGE]: { |
||||
redirect: () => { |
||||
simpleDispatch( |
||||
new SelectChatId({ id: Number(notification.data.chatId) }) |
||||
); |
||||
history.push(`/chats?id=${notification.data.chatId}`); |
||||
} |
||||
}, |
||||
[NotificationKeys.NEW_CHAT_MEMBER]: { |
||||
redirect: () => { |
||||
simpleDispatch( |
||||
new SelectChatId({ id: Number(notification.data.chatId) }) |
||||
); |
||||
history.push(`/chats?id=${notification.data.chatId}`); |
||||
} |
||||
}, |
||||
[NotificationKeys.NEW_TASK]: { |
||||
redirect: () => { |
||||
history.push(RouteEnum.Tasks); |
||||
} |
||||
}, |
||||
[NotificationKeys.NEW_TASK_COMMENT]: { |
||||
redirect: () => { |
||||
history.push(RouteEnum.Tasks, { |
||||
type: NotificationKeys.NEW_TASK_COMMENT, |
||||
taskId: notification.data.taskId |
||||
}); |
||||
} |
||||
}, |
||||
[NotificationKeys.NEW_TASK_FILE]: { |
||||
redirect: () => { |
||||
history.push(RouteEnum.Tasks, { |
||||
type: NotificationKeys.NEW_TASK_COMMENT, |
||||
taskId: notification.data.taskId |
||||
}); |
||||
} |
||||
}, |
||||
[NotificationKeys.TODAY_BIRTHDAY]: { |
||||
redirect: () => { |
||||
history.push(RouteEnum.Contacts, { soonBirthday: true }); |
||||
} |
||||
} |
||||
}); |
||||
|
@ -1,14 +1,13 @@
@@ -1,14 +1,13 @@
|
||||
import React from 'react'; |
||||
import ReactDOM from 'react-dom'; |
||||
import React from "react"; |
||||
import ReactDOM from "react-dom"; |
||||
import App from "./App"; |
||||
import { registerServiceWorker } from "./register-sw"; |
||||
|
||||
|
||||
registerServiceWorker(); |
||||
// registerServiceWorker();
|
||||
|
||||
ReactDOM.render( |
||||
<React.StrictMode> |
||||
<App /> |
||||
</React.StrictMode>, |
||||
document.getElementById('root') |
||||
) |
||||
document.getElementById("root") |
||||
); |
||||
|
@ -1,2 +1,3 @@
@@ -1,2 +1,3 @@
|
||||
export * from "./global-container.service"; |
||||
export * from "./real-time.service"; |
||||
export * from "./notifications.service"; |
||||
|
@ -0,0 +1,140 @@
@@ -0,0 +1,140 @@
|
||||
import { notificApi } from "@/api/notifications/request"; |
||||
import { RouteEnum } from "@/containers/App/router"; |
||||
import { IPushNotification, NotificationKeys } from "@/shared"; |
||||
import { SelectChatId } from "@/store/chats"; |
||||
import { simpleDispatch } from "@/store/store-helpers"; |
||||
import OneSignal from "react-onesignal"; |
||||
|
||||
export const needRedirect = { |
||||
to: null, |
||||
payload: null |
||||
}; |
||||
|
||||
const saveNeedRedirect = ({ to, payload }) => { |
||||
needRedirect.to = to; |
||||
needRedirect.payload = payload; |
||||
}; |
||||
|
||||
export const notificationActions = ( |
||||
notification: IPushNotification, |
||||
tabIndex?: number |
||||
) => ({ |
||||
[NotificationKeys.NEW_MESSAGE]: { |
||||
redirect: () => { |
||||
simpleDispatch( |
||||
new SelectChatId({ id: Number(notification.data.chatId) }) |
||||
); |
||||
saveNeedRedirect({ |
||||
to: `/chats?id=${notification.data.chatId}`, |
||||
payload: null |
||||
}); |
||||
} |
||||
}, |
||||
[NotificationKeys.NEW_CHAT_MEMBER]: { |
||||
redirect: () => { |
||||
simpleDispatch( |
||||
new SelectChatId({ id: Number(notification.data.chatId) }) |
||||
); |
||||
saveNeedRedirect({ |
||||
to: `/chats?id=${notification.data.chatId}`, |
||||
payload: null |
||||
}); |
||||
} |
||||
}, |
||||
[NotificationKeys.NEW_TASK]: { |
||||
redirect: () => { |
||||
saveNeedRedirect({ |
||||
to: RouteEnum.Tasks, |
||||
payload: null |
||||
}); |
||||
} |
||||
}, |
||||
[NotificationKeys.NEW_TASK_COMMENT]: { |
||||
redirect: () => { |
||||
saveNeedRedirect({ |
||||
to: RouteEnum.Tasks, |
||||
payload: { |
||||
type: NotificationKeys.NEW_TASK_COMMENT, |
||||
taskId: notification.data.taskId |
||||
} |
||||
}); |
||||
} |
||||
}, |
||||
[NotificationKeys.NEW_TASK_FILE]: { |
||||
redirect: () => { |
||||
saveNeedRedirect({ |
||||
to: RouteEnum.Tasks, |
||||
payload: { |
||||
type: NotificationKeys.NEW_TASK_FILE, |
||||
taskId: notification.data.taskId |
||||
} |
||||
}); |
||||
} |
||||
}, |
||||
[NotificationKeys.TODAY_BIRTHDAY]: { |
||||
redirect: () => { |
||||
saveNeedRedirect({ |
||||
to: RouteEnum.Contacts, |
||||
payload: { soonBirthday: true } |
||||
}); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
const onOpened = openResult => { |
||||
try { |
||||
const notif: IPushNotification = { |
||||
id: 0, |
||||
title: null, |
||||
content: null, |
||||
createDate: null, |
||||
isRead: false, |
||||
userId: null, |
||||
data: openResult.data as any |
||||
}; |
||||
|
||||
const action = notificationActions(notif)[ |
||||
notif?.data?.type as NotificationKeys |
||||
]; |
||||
|
||||
action?.redirect(); |
||||
} catch (e) { |
||||
console.log(e); |
||||
} |
||||
}; |
||||
|
||||
const runOneSignal = async () => { |
||||
try { |
||||
await OneSignal.init({ |
||||
appId: "8b9066f5-8c3f-49f7-bef4-c5ab621f9d27", |
||||
allowLocalhostAsSecureOrigin: true |
||||
}); |
||||
|
||||
const isPermitted = await OneSignal.getNotificationPermission(); |
||||
|
||||
if (isPermitted !== "granted") await OneSignal.showNativePrompt(); |
||||
|
||||
if (isPermitted) await OneSignal.setSubscription(true); |
||||
|
||||
const userId = await OneSignal.getUserId(); |
||||
|
||||
if (userId) |
||||
await notificApi.saveUserDevice({ |
||||
notificationUserId: userId, |
||||
deviceUuid: userId |
||||
}); |
||||
} catch (e) { |
||||
console.log("ONE SIGNAL RUNNING ERROR", e); |
||||
} |
||||
}; |
||||
|
||||
OneSignal.on("subscriptionChange", async isSubscribed => { |
||||
console.log("SUBSCRIPTION IS CHANGED", isSubscribed); |
||||
await OneSignal.setSubscription(isSubscribed); |
||||
}); |
||||
|
||||
OneSignal.addListenerForNotificationOpened(onOpened); |
||||
|
||||
export const notificationsService = { |
||||
runOneSignal |
||||
}; |
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
export enum NotificationsGroup { |
||||
/** Сповіщення, що відносяться до задач */ |
||||
Tasks = "t", |
||||
|
||||
/** Сповіщення, що відносяться до чатів */ |
||||
Chats = "c", |
||||
|
||||
/** Сповіщення, що не відносяться до жодної з груп */ |
||||
Other = "oth" |
||||
} |
||||
|
||||
export enum NotificationKeys { |
||||
NEW_MESSAGE = "newMessage", |
||||
NEW_TASK = "newTask", |
||||
NEW_CHAT_MEMBER = "newChatMembers", |
||||
TODAY_BIRTHDAY = "todayBirthday", |
||||
NEW_TASK_COMMENT = "newTaskComment", |
||||
NEW_TASK_FILE = "newTaskFile" |
||||
} |
@ -1,4 +1,4 @@
@@ -1,4 +1,4 @@
|
||||
export interface INotification { |
||||
title: string |
||||
message: string |
||||
} |
||||
title: string; |
||||
message: string; |
||||
} |
||||
|
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
import { NotificationsGroup } from "../enums"; |
||||
import { IUser } from "./user.interfaces"; |
||||
|
||||
export interface IPushNotification { |
||||
id: number; |
||||
title: string; |
||||
content: string; |
||||
group?: NotificationsGroup; |
||||
isRead: boolean; |
||||
userId: number; |
||||
user?: IUser; |
||||
createDate: string; |
||||
imageUrl?: string; |
||||
data?: Record<string, string>; |
||||
} |
Loading…
Reference in new issue