Update maximum file size for caching in service worker to 6MB
This commit is contained in:
parent
bcd32a8616
commit
8f93cc5e62
3 changed files with 353 additions and 318 deletions
|
@ -1,55 +1,52 @@
|
||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
import { API_URL } from '../Config'
|
import { API_URL } from '../Config'
|
||||||
import { login, RefreshToken } from './Fetcher'
|
import { RefreshToken } from './Fetcher'
|
||||||
|
|
||||||
import { Preferences } from '@capacitor/preferences'
|
import { Preferences } from '@capacitor/preferences'
|
||||||
|
|
||||||
class ApiManager {
|
class ApiManager {
|
||||||
constructor(){
|
constructor() {
|
||||||
this.customServerURL = API_URL
|
this.customServerURL = API_URL
|
||||||
this.initialized = false
|
this.initialized = false
|
||||||
}
|
}
|
||||||
async init(){
|
async init() {
|
||||||
if(this.initialized){
|
if (this.initialized) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const { value: serverURL } = await Preferences.get({ key: 'customServerUrl' });
|
const { value: serverURL } = await Preferences.get({
|
||||||
|
key: 'customServerUrl',
|
||||||
|
})
|
||||||
|
|
||||||
this.customServerURL = serverURL || this.apiURL
|
this.customServerURL = serverURL || this.apiURL
|
||||||
this.initialized = true
|
this.initialized = true
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
getApiURL(){
|
getApiURL() {
|
||||||
return this.customServerURL
|
return this.customServerURL
|
||||||
}
|
}
|
||||||
updateApiURL(url){
|
updateApiURL(url) {
|
||||||
this.customServerURL = url
|
this.customServerURL = url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const apiManager = new ApiManager()
|
||||||
export const apiManager = new ApiManager();
|
|
||||||
|
|
||||||
|
|
||||||
export function Fetch(url, options) {
|
export function Fetch(url, options) {
|
||||||
|
|
||||||
if (!isTokenValid()) {
|
if (!isTokenValid()) {
|
||||||
// store current location in cookie
|
// store current location in cookie
|
||||||
Cookies.set('ca_redirect', window.location.pathname);
|
Cookies.set('ca_redirect', window.location.pathname)
|
||||||
// Assuming you have a function isTokenValid() that checks token validity
|
// Assuming you have a function isTokenValid() that checks token validity
|
||||||
window.location.href = '/login'; // Redirect to login page
|
window.location.href = '/login' // Redirect to login page
|
||||||
// return Promise.reject("Token is not valid");
|
// return Promise.reject("Token is not valid");
|
||||||
}
|
}
|
||||||
if (!options) {
|
if (!options) {
|
||||||
options = {};
|
options = {}
|
||||||
}
|
}
|
||||||
options.headers = { ...options.headers, ...HEADERS() };
|
options.headers = { ...options.headers, ...HEADERS() }
|
||||||
|
|
||||||
const baseURL = apiManager.getApiURL();
|
const baseURL = apiManager.getApiURL()
|
||||||
|
|
||||||
const fullURL = `${baseURL}${url}`;
|
const fullURL = `${baseURL}${url}`
|
||||||
return fetch(fullURL, options);
|
return fetch(fullURL, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const HEADERS = () => {
|
export const HEADERS = () => {
|
||||||
|
@ -81,8 +78,7 @@ export const isTokenValid = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const refreshAccessToken = () => {
|
export const refreshAccessToken = () => {
|
||||||
RefreshToken()
|
RefreshToken().then(res => {
|
||||||
.then(res => {
|
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
res.json().then(data => {
|
res.json().then(data => {
|
||||||
localStorage.setItem('ca_token', data.token)
|
localStorage.setItem('ca_token', data.token)
|
||||||
|
|
|
@ -1,13 +1,30 @@
|
||||||
import { Box, Button, Card, Checkbox, Divider, FormControl, FormHelperText, FormLabel, IconButton, Input, List, ListItem, Option, Select, Snackbar, Switch, Typography } from '@mui/joy'
|
import { Capacitor } from '@capacitor/core'
|
||||||
|
import { LocalNotifications } from '@capacitor/local-notifications'
|
||||||
|
import { Preferences } from '@capacitor/preferences'
|
||||||
|
import { Close } from '@mui/icons-material'
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
Divider,
|
||||||
|
FormControl,
|
||||||
|
FormHelperText,
|
||||||
|
FormLabel,
|
||||||
|
IconButton,
|
||||||
|
Input,
|
||||||
|
Option,
|
||||||
|
Select,
|
||||||
|
Snackbar,
|
||||||
|
Switch,
|
||||||
|
Typography,
|
||||||
|
} from '@mui/joy'
|
||||||
import React, { useContext, useEffect, useState } from 'react'
|
import React, { useContext, useEffect, useState } from 'react'
|
||||||
import { UserContext } from '../../contexts/UserContext'
|
import { UserContext } from '../../contexts/UserContext'
|
||||||
import { GetUserProfile, UpdateUserDetails } from '../../utils/Fetcher'
|
import {
|
||||||
import { Capacitor } from '@capacitor/core'
|
GetUserProfile,
|
||||||
import { Preferences } from '@capacitor/preferences'
|
UpdateNotificationTarget,
|
||||||
import { LocalNotifications } from '@capacitor/local-notifications'
|
UpdateUserDetails,
|
||||||
import { Close } from '@mui/icons-material'
|
} from '../../utils/Fetcher'
|
||||||
import { PushNotifications } from '@capacitor/push-notifications'
|
|
||||||
import { UpdateNotificationTarget } from '../../utils/Fetcher'
|
|
||||||
|
|
||||||
const NotificationSetting = () => {
|
const NotificationSetting = () => {
|
||||||
const [isSnackbarOpen, setIsSnackbarOpen] = useState(false)
|
const [isSnackbarOpen, setIsSnackbarOpen] = useState(false)
|
||||||
|
@ -23,52 +40,55 @@ const NotificationSetting = () => {
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
const getNotificationPreferences = async () => {
|
const getNotificationPreferences = async () => {
|
||||||
const ret = await Preferences.get({ key: 'notificationPreferences' });
|
const ret = await Preferences.get({ key: 'notificationPreferences' })
|
||||||
return JSON.parse(ret.value);
|
return JSON.parse(ret.value)
|
||||||
};
|
}
|
||||||
const setNotificationPreferences = async (value) => {
|
const setNotificationPreferences = async value => {
|
||||||
if (value.granted === false){
|
if (value.granted === false) {
|
||||||
await Preferences.set({ key: 'notificationPreferences', value: JSON.stringify({ granted: false }) });
|
await Preferences.set({
|
||||||
|
key: 'notificationPreferences',
|
||||||
|
value: JSON.stringify({ granted: false }),
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const currentSettings = await getNotificationPreferences();
|
const currentSettings = await getNotificationPreferences()
|
||||||
await Preferences.set({ key: 'notificationPreferences', value: JSON.stringify({ ...currentSettings, ...value }) });
|
await Preferences.set({
|
||||||
};
|
key: 'notificationPreferences',
|
||||||
|
value: JSON.stringify({ ...currentSettings, ...value }),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const getPushNotificationPreferences = async () => {
|
const getPushNotificationPreferences = async () => {
|
||||||
const ret = await Preferences.get({ key: 'pushNotificationPreferences' });
|
const ret = await Preferences.get({ key: 'pushNotificationPreferences' })
|
||||||
return JSON.parse(ret.value);
|
return JSON.parse(ret.value)
|
||||||
};
|
}
|
||||||
|
|
||||||
|
const setPushNotificationPreferences = async value => {
|
||||||
|
await Preferences.set({
|
||||||
|
key: 'pushNotificationPreferences',
|
||||||
|
value: JSON.stringify(value),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const [deviceNotification, setDeviceNotification] = useState(false)
|
||||||
|
|
||||||
const setPushNotificationPreferences = async (value) => {
|
|
||||||
await Preferences.set({ key: 'pushNotificationPreferences', value: JSON.stringify(value) });
|
|
||||||
};
|
|
||||||
|
|
||||||
const [deviceNotification, setDeviceNotification] = useState(
|
|
||||||
false
|
|
||||||
)
|
|
||||||
|
|
||||||
const [dueNotification, setDueNotification] = useState(true)
|
const [dueNotification, setDueNotification] = useState(true)
|
||||||
const [preDueNotification, setPreDueNotification] = useState(false)
|
const [preDueNotification, setPreDueNotification] = useState(false)
|
||||||
const [naggingNotification, setNaggingNotification] = useState(false)
|
const [naggingNotification, setNaggingNotification] = useState(false)
|
||||||
const [pushNotification, setPushNotification] = useState(
|
const [pushNotification, setPushNotification] = useState(false)
|
||||||
false
|
|
||||||
)
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getNotificationPreferences().then((resp) => {
|
getNotificationPreferences().then(resp => {
|
||||||
setDeviceNotification(resp.granted)
|
setDeviceNotification(resp.granted)
|
||||||
setDueNotification(resp.dueNotification)
|
setDueNotification(resp.dueNotification)
|
||||||
setPreDueNotification(resp.preDueNotification)
|
setPreDueNotification(resp.preDueNotification)
|
||||||
setNaggingNotification(resp.naggingNotification)
|
setNaggingNotification(resp.naggingNotification)
|
||||||
}
|
})
|
||||||
)
|
getPushNotificationPreferences().then(resp => {
|
||||||
getPushNotificationPreferences().then((resp) => {
|
|
||||||
setPushNotification(resp.granted)
|
setPushNotification(resp.granted)
|
||||||
}
|
})
|
||||||
)
|
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const [notificationTarget, setNotificationTarget] = useState(
|
const [notificationTarget, setNotificationTarget] = useState(
|
||||||
userProfile?.notification_target
|
userProfile?.notification_target
|
||||||
? String(userProfile.notification_target.type)
|
? String(userProfile.notification_target.type)
|
||||||
|
@ -126,100 +146,104 @@ const NotificationSetting = () => {
|
||||||
<Typography level='body-md'>Manage your Device Notificaiton</Typography>
|
<Typography level='body-md'>Manage your Device Notificaiton</Typography>
|
||||||
|
|
||||||
<FormControl
|
<FormControl
|
||||||
orientation="horizontal"
|
orientation='horizontal'
|
||||||
sx={{ width: 400, justifyContent: 'space-between' }}
|
sx={{ width: 400, justifyContent: 'space-between' }}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<FormLabel>Device Notification</FormLabel>
|
<FormLabel>Device Notification</FormLabel>
|
||||||
<FormHelperText sx={{ mt: 0 }}>{Capacitor.isNativePlatform()? 'Receive notification on your device when a task is due' : 'This feature is only available on mobile devices'} </FormHelperText>
|
<FormHelperText sx={{ mt: 0 }}>
|
||||||
</div>
|
{Capacitor.isNativePlatform()
|
||||||
<Switch
|
? 'Receive notification on your device when a task is due'
|
||||||
disabled={!Capacitor.isNativePlatform()}
|
: 'This feature is only available on mobile devices'}{' '}
|
||||||
checked={deviceNotification}
|
</FormHelperText>
|
||||||
onClick={(event) =>{
|
</div>
|
||||||
event.preventDefault()
|
<Switch
|
||||||
if (deviceNotification === false){
|
disabled={!Capacitor.isNativePlatform()}
|
||||||
LocalNotifications.requestPermissions().then((resp) => {
|
checked={deviceNotification}
|
||||||
if (resp.display === 'granted') {
|
onClick={event => {
|
||||||
|
event.preventDefault()
|
||||||
setDeviceNotification(true)
|
if (deviceNotification === false) {
|
||||||
setNotificationPreferences({granted: true})
|
LocalNotifications.requestPermissions().then(resp => {
|
||||||
}
|
if (resp.display === 'granted') {
|
||||||
else if (resp.display === 'denied') {
|
setDeviceNotification(true)
|
||||||
setIsSnackbarOpen(true)
|
setNotificationPreferences({ granted: true })
|
||||||
setDeviceNotification(false)
|
} else if (resp.display === 'denied') {
|
||||||
setNotificationPreferences({granted: false})
|
setIsSnackbarOpen(true)
|
||||||
}
|
setDeviceNotification(false)
|
||||||
})
|
setNotificationPreferences({ granted: false })
|
||||||
}
|
}
|
||||||
else{
|
})
|
||||||
setDeviceNotification(false)
|
} else {
|
||||||
}
|
setDeviceNotification(false)
|
||||||
}
|
}
|
||||||
}
|
}}
|
||||||
color={deviceNotification ? 'success' : 'neutral'}
|
color={deviceNotification ? 'success' : 'neutral'}
|
||||||
variant={deviceNotification ? 'solid' : 'outlined'}
|
variant={deviceNotification ? 'solid' : 'outlined'}
|
||||||
endDecorator={deviceNotification ? 'On' : 'Off'}
|
endDecorator={deviceNotification ? 'On' : 'Off'}
|
||||||
slotProps={{
|
slotProps={{
|
||||||
endDecorator: {
|
endDecorator: {
|
||||||
sx: {
|
sx: {
|
||||||
minWidth: 24,
|
minWidth: 24,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
</FormControl>
|
||||||
</FormControl>
|
{deviceNotification && (
|
||||||
{deviceNotification && (
|
<Card>
|
||||||
<Card>
|
{[
|
||||||
{[
|
{
|
||||||
{
|
title: 'Due Date Notification',
|
||||||
'title': 'Due Date Notification',
|
checked: dueNotification,
|
||||||
'checked': dueNotification,
|
set: setDueNotification,
|
||||||
'set': setDueNotification,
|
label: 'Notification when the task is due',
|
||||||
'label': 'Notification when the task is due',
|
property: 'dueNotification',
|
||||||
'property': 'dueNotification',
|
disabled: false,
|
||||||
'disabled': false
|
},
|
||||||
},
|
{
|
||||||
{
|
title: 'Pre-Due Date Notification',
|
||||||
'title': 'Pre-Due Date Notification',
|
checked: preDueNotification,
|
||||||
'checked': preDueNotification,
|
set: setPreDueNotification,
|
||||||
'set': setPreDueNotification,
|
label: 'Notification a few hours before the task is due',
|
||||||
'label': 'Notification a few hours before the task is due',
|
property: 'preDueNotification',
|
||||||
'property': 'preDueNotification',
|
disabled: true,
|
||||||
'disabled': true
|
},
|
||||||
},
|
{
|
||||||
{
|
title: 'Overdue Notification',
|
||||||
'title': 'Overdue Notification',
|
checked: naggingNotification,
|
||||||
'checked': naggingNotification,
|
set: setNaggingNotification,
|
||||||
'set': setNaggingNotification,
|
label: 'Notification when the task is overdue',
|
||||||
'label': 'Notification when the task is overdue',
|
property: 'naggingNotification',
|
||||||
'property': 'naggingNotification',
|
disabled: true,
|
||||||
'disabled': true
|
},
|
||||||
}
|
].map(item => (
|
||||||
]
|
<FormControl
|
||||||
.map(item => (
|
key={item.property}
|
||||||
<FormControl
|
orientation='horizontal'
|
||||||
orientation="horizontal"
|
sx={{ width: 385, justifyContent: 'space-between' }}
|
||||||
sx={{ width: 385, justifyContent: 'space-between' }}
|
>
|
||||||
>
|
<div>
|
||||||
<div>
|
<FormLabel>{item.title}</FormLabel>
|
||||||
<FormLabel>{item.title}</FormLabel>
|
<FormHelperText sx={{ mt: 0 }}>{item.label} </FormHelperText>
|
||||||
<FormHelperText sx={{ mt: 0 }}>{item.label} </FormHelperText>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<Switch checked={item.checked}
|
<Switch
|
||||||
disabled={item.disabled}
|
checked={item.checked}
|
||||||
onClick={() =>{
|
disabled={item.disabled}
|
||||||
setNotificationPreferences({[item.property]: !item.checked})
|
onClick={() => {
|
||||||
item.set(!item.checked)
|
setNotificationPreferences({ [item.property]: !item.checked })
|
||||||
}}
|
item.set(!item.checked)
|
||||||
color={item.checked ? 'success' : ''}
|
}}
|
||||||
variant='solid' endDecorator={item.checked ? 'On' : 'Off'} slotProps={{ endDecorator: { sx: { minWidth: 24 } } }} />
|
color={item.checked ? 'success' : ''}
|
||||||
</FormControl>
|
variant='solid'
|
||||||
))}
|
endDecorator={item.checked ? 'On' : 'Off'}
|
||||||
</Card>
|
slotProps={{ endDecorator: { sx: { minWidth: 24 } } }}
|
||||||
)}
|
/>
|
||||||
{/* <FormControl
|
</FormControl>
|
||||||
|
))}
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
{/* <FormControl
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
sx={{ width: 400, justifyContent: 'space-between' }}
|
sx={{ width: 400, justifyContent: 'space-between' }}
|
||||||
>
|
>
|
||||||
|
@ -267,180 +291,194 @@ const NotificationSetting = () => {
|
||||||
/>
|
/>
|
||||||
</FormControl> */}
|
</FormControl> */}
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant='soft'
|
variant='soft'
|
||||||
color='primary'
|
color='primary'
|
||||||
sx={{
|
sx={{
|
||||||
width: '210px',
|
width: '210px',
|
||||||
mb: 1,
|
mb: 1,
|
||||||
}}
|
}}
|
||||||
|
onClick={() => {
|
||||||
onClick={() => {
|
// schedule a local notification in 5 seconds
|
||||||
// schedule a local notification in 5 seconds
|
LocalNotifications.schedule({
|
||||||
LocalNotifications.schedule({
|
notifications: [
|
||||||
notifications: [
|
{
|
||||||
{
|
title: 'Task Reminder',
|
||||||
title: 'Task Reminder',
|
body: 'You have a task due soon',
|
||||||
body: 'You have a task due soon',
|
id: 1,
|
||||||
id: 1,
|
schedule: { at: new Date(Date.now() + 3000) },
|
||||||
schedule: { at: new Date(Date.now() + 3000) },
|
sound: null,
|
||||||
sound: null,
|
attachments: null,
|
||||||
attachments: null,
|
actionTypeId: '',
|
||||||
actionTypeId: '',
|
extra: null,
|
||||||
extra: null,
|
},
|
||||||
},
|
],
|
||||||
],
|
})
|
||||||
});
|
}}
|
||||||
}
|
>
|
||||||
}>Test Notification </Button>
|
Test Notification{' '}
|
||||||
|
</Button>
|
||||||
<Typography level='h3'>Custom Notification</Typography>
|
<Typography level='h3'>Custom Notification</Typography>
|
||||||
<Divider />
|
<Divider />
|
||||||
<Typography level='body-md'>Notificaiton through other platform like Telegram or Pushover</Typography>
|
|
||||||
|
|
||||||
|
|
||||||
<FormControl
|
|
||||||
orientation="horizontal"
|
|
||||||
sx={{ width: 400, justifyContent: 'space-between' }}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<FormLabel>Custom Notification</FormLabel>
|
|
||||||
<FormHelperText sx={{ mt: 0 }}>Receive notification on other platform</FormHelperText>
|
|
||||||
</div>
|
|
||||||
<Switch
|
|
||||||
checked={chatID !== 0}
|
|
||||||
onClick={(event) =>{
|
|
||||||
event.preventDefault()
|
|
||||||
if (chatID !== 0){
|
|
||||||
setChatID(0)
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
setChatID('')
|
|
||||||
UpdateUserDetails({
|
|
||||||
chatID: Number(0),
|
|
||||||
}).then(resp => {
|
|
||||||
resp.json().then(data => {
|
|
||||||
setUserProfile(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
setNotificationTarget('0')
|
|
||||||
handleSave()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
color={chatID!==0 ? 'success' : 'neutral'}
|
|
||||||
variant={chatID!==0 ? 'solid' : 'outlined'}
|
|
||||||
endDecorator={chatID!==0 ? 'On' : 'Off'}
|
|
||||||
slotProps={{
|
|
||||||
endDecorator: {
|
|
||||||
sx: {
|
|
||||||
minWidth: 24,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
{chatID !== 0&& (
|
|
||||||
<Box
|
|
||||||
|
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
gap: 2,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
|
|
||||||
<Select
|
|
||||||
value={notificationTarget}
|
|
||||||
sx={{ maxWidth: '200px' }}
|
|
||||||
onChange={(e, selected) => setNotificationTarget(selected)}
|
|
||||||
>
|
|
||||||
<Option value='0'>None</Option>
|
|
||||||
<Option value='1'>Telegram</Option>
|
|
||||||
<Option value='2'>Pushover</Option>
|
|
||||||
</Select>
|
|
||||||
{notificationTarget === '1' && (
|
|
||||||
<>
|
|
||||||
<Typography level='body-xs'>
|
|
||||||
You need to initiate a message to the bot in order for the Telegram
|
|
||||||
notification to work{' '}
|
|
||||||
<a
|
|
||||||
style={{
|
|
||||||
textDecoration: 'underline',
|
|
||||||
color: '#0891b2',
|
|
||||||
}}
|
|
||||||
href='https://t.me/DonetickBot'
|
|
||||||
>
|
|
||||||
Click here
|
|
||||||
</a>{' '}
|
|
||||||
to start a chat
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Typography level='body-sm'>Chat ID</Typography>
|
|
||||||
|
|
||||||
<Input
|
|
||||||
value={chatID}
|
|
||||||
onChange={e => setChatID(e.target.value)}
|
|
||||||
placeholder='User ID / Chat ID'
|
|
||||||
sx={{
|
|
||||||
width: '200px',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Typography mt={0} level='body-xs'>
|
|
||||||
If you don't know your Chat ID, start chat with userinfobot and it
|
|
||||||
will send you your Chat ID.{' '}
|
|
||||||
<a
|
|
||||||
style={{
|
|
||||||
textDecoration: 'underline',
|
|
||||||
color: '#0891b2',
|
|
||||||
}}
|
|
||||||
href='https://t.me/userinfobot'
|
|
||||||
>
|
|
||||||
Click here
|
|
||||||
</a>{' '}
|
|
||||||
to start chat with userinfobot{' '}
|
|
||||||
</Typography>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{notificationTarget === '2' && (
|
|
||||||
<>
|
|
||||||
<Typography level='body-sm'>User key</Typography>
|
|
||||||
<Input
|
|
||||||
value={chatID}
|
|
||||||
onChange={e => setChatID(e.target.value)}
|
|
||||||
placeholder='User ID'
|
|
||||||
sx={{
|
|
||||||
width: '200px',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{error && (
|
|
||||||
<Typography color='warning' level='body-sm'>
|
|
||||||
{error}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Button
|
|
||||||
sx={{
|
|
||||||
width: '110px',
|
|
||||||
mb: 1,
|
|
||||||
}}
|
|
||||||
onClick={handleSave}
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
<Snackbar open={isSnackbarOpen} autoHideDuration={8000} onClose={() => setIsSnackbarOpen(false)} endDecorator={<IconButton size='md' onClick={() => setIsSnackbarOpen(false)}><Close/></IconButton>}>
|
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
|
|
||||||
<Typography level='title-md'>Permission Denied</Typography>
|
|
||||||
<Typography level='body-md'>
|
<Typography level='body-md'>
|
||||||
You have denied the permission to receive notification on this device. Please enable it in your device settings
|
Notificaiton through other platform like Telegram or Pushover
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
|
||||||
</Snackbar>
|
<FormControl
|
||||||
|
orientation='horizontal'
|
||||||
|
sx={{ width: 400, justifyContent: 'space-between' }}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<FormLabel>Custom Notification</FormLabel>
|
||||||
|
<FormHelperText sx={{ mt: 0 }}>
|
||||||
|
Receive notification on other platform
|
||||||
|
</FormHelperText>
|
||||||
|
</div>
|
||||||
|
<Switch
|
||||||
|
checked={chatID !== 0}
|
||||||
|
onClick={event => {
|
||||||
|
event.preventDefault()
|
||||||
|
if (chatID !== 0) {
|
||||||
|
setChatID(0)
|
||||||
|
} else {
|
||||||
|
setChatID('')
|
||||||
|
UpdateUserDetails({
|
||||||
|
chatID: Number(0),
|
||||||
|
}).then(resp => {
|
||||||
|
resp.json().then(data => {
|
||||||
|
setUserProfile(data)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
setNotificationTarget('0')
|
||||||
|
handleSave()
|
||||||
|
}}
|
||||||
|
color={chatID !== 0 ? 'success' : 'neutral'}
|
||||||
|
variant={chatID !== 0 ? 'solid' : 'outlined'}
|
||||||
|
endDecorator={chatID !== 0 ? 'On' : 'Off'}
|
||||||
|
slotProps={{
|
||||||
|
endDecorator: {
|
||||||
|
sx: {
|
||||||
|
minWidth: 24,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
{chatID !== 0 && (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: 2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
value={notificationTarget}
|
||||||
|
sx={{ maxWidth: '200px' }}
|
||||||
|
onChange={(e, selected) => setNotificationTarget(selected)}
|
||||||
|
>
|
||||||
|
<Option value='0'>None</Option>
|
||||||
|
<Option value='1'>Telegram</Option>
|
||||||
|
<Option value='2'>Pushover</Option>
|
||||||
|
</Select>
|
||||||
|
{notificationTarget === '1' && (
|
||||||
|
<>
|
||||||
|
<Typography level='body-xs'>
|
||||||
|
You need to initiate a message to the bot in order for the
|
||||||
|
Telegram notification to work{' '}
|
||||||
|
<a
|
||||||
|
style={{
|
||||||
|
textDecoration: 'underline',
|
||||||
|
color: '#0891b2',
|
||||||
|
}}
|
||||||
|
href='https://t.me/DonetickBot'
|
||||||
|
>
|
||||||
|
Click here
|
||||||
|
</a>{' '}
|
||||||
|
to start a chat
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Typography level='body-sm'>Chat ID</Typography>
|
||||||
|
|
||||||
|
<Input
|
||||||
|
value={chatID}
|
||||||
|
onChange={e => setChatID(e.target.value)}
|
||||||
|
placeholder='User ID / Chat ID'
|
||||||
|
sx={{
|
||||||
|
width: '200px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Typography mt={0} level='body-xs'>
|
||||||
|
If you don't know your Chat ID, start chat with userinfobot and
|
||||||
|
it will send you your Chat ID.{' '}
|
||||||
|
<a
|
||||||
|
style={{
|
||||||
|
textDecoration: 'underline',
|
||||||
|
color: '#0891b2',
|
||||||
|
}}
|
||||||
|
href='https://t.me/userinfobot'
|
||||||
|
>
|
||||||
|
Click here
|
||||||
|
</a>{' '}
|
||||||
|
to start chat with userinfobot{' '}
|
||||||
|
</Typography>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{notificationTarget === '2' && (
|
||||||
|
<>
|
||||||
|
<Typography level='body-sm'>User key</Typography>
|
||||||
|
<Input
|
||||||
|
value={chatID}
|
||||||
|
onChange={e => setChatID(e.target.value)}
|
||||||
|
placeholder='User ID'
|
||||||
|
sx={{
|
||||||
|
width: '200px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{error && (
|
||||||
|
<Typography color='warning' level='body-sm'>
|
||||||
|
{error}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Button
|
||||||
|
sx={{
|
||||||
|
width: '110px',
|
||||||
|
mb: 1,
|
||||||
|
}}
|
||||||
|
onClick={handleSave}
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
<Snackbar
|
||||||
|
open={isSnackbarOpen}
|
||||||
|
autoHideDuration={8000}
|
||||||
|
onClose={() => setIsSnackbarOpen(false)}
|
||||||
|
endDecorator={
|
||||||
|
<IconButton size='md' onClick={() => setIsSnackbarOpen(false)}>
|
||||||
|
<Close />
|
||||||
|
</IconButton>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography level='title-md'>Permission Denied</Typography>
|
||||||
|
<Typography level='body-md'>
|
||||||
|
You have denied the permission to receive notification on this
|
||||||
|
device. Please enable it in your device settings
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
</Snackbar>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ export default defineConfig({
|
||||||
workbox: {
|
workbox: {
|
||||||
skipWaiting: true, // Force the waiting service worker to become the active service worker
|
skipWaiting: true, // Force the waiting service worker to become the active service worker
|
||||||
clientsClaim: true, // Take control of uncontrolled clients as soon as the service worker becomes active
|
clientsClaim: true, // Take control of uncontrolled clients as soon as the service worker becomes active
|
||||||
|
maximumFileSizeToCacheInBytes: 6000000, // 6MB
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|
Loading…
Add table
Reference in a new issue