Skip to content

Commit

Permalink
chore: provide debug info about notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
leaftail1880 committed Nov 30, 2024
1 parent d29f25b commit cce62dd
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 75 deletions.
7 changes: 7 additions & 0 deletions src/models/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,13 @@ export class ThemeStore {
},
}
}

get destructiveButton() {
return {
style: { backgroundColor: this.colors.errorContainer },
labelStyle: { color: this.colors.onErrorContainer },
}
}
}

export const Theme = new ThemeStore()
17 changes: 3 additions & 14 deletions src/screens/login/out.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,16 @@ import { Theme } from '~models/theme'
import { API } from '~services/net-school/api'
import { Spacings } from '../../utils/Spacings'

function logout() {
runInAction(() => {
API.logOut()
})
function logOut() {
runInAction(() => API.logOut())
}

export default observer(function LogoutScreen() {
return (
<View style={{ flex: 1, backgroundColor: Theme.colors.background }}>
<Header title="Выход"></Header>
<View style={styles.container}>
<Button
onPress={logout}
style={{
backgroundColor: Theme.colors.errorContainer,
}}
labelStyle={{
fontSize: 16,
color: Theme.colors.onErrorContainer,
}}
>
<Button onPress={logOut} {...Theme.destructiveButton}>
Выйти
</Button>
<Text style={styles.subtitle}>
Expand Down
100 changes: 98 additions & 2 deletions src/screens/settings/notifications/Notifications.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,48 @@
import notifee from '@notifee/react-native'
import { StackScreenProps } from '@react-navigation/stack'
import { observer } from 'mobx-react-lite'
import { ScrollView } from 'react-native'
import { List } from 'react-native-paper'
import { useEffect, useRef, useState } from 'react'
import { Linking, ScrollView, View } from 'react-native'
import { Button, HelperText, List, Text } from 'react-native-paper'
import SwitchSetting from '~components/SwitchSetting'
import { Settings } from '~models/settings'
import { Theme } from '~models/theme'
import {
checkForNewMarksAndNotify,
MarksNotificationStore,
} from '~services/notifications/marks'
import { Spacings } from '~utils/Spacings'
import { SettingsRoutes } from '../navigation'

function usePromise<T>(promise: () => Promise<T>) {
const [state, setState] = useState<T | undefined>(undefined)

const interval = useRef<number | undefined | NodeJS.Timeout>()
useEffect(() => {
clearInterval(interval.current)
interval.current = setInterval(() => {
promise().then(e => {
if (state !== e) setState(e)
})
}, 2000)
})

return state
}

export default observer(function Notifications(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
props: StackScreenProps<SettingsRoutes>,
) {
const batteryOptimizations = !!usePromise(() =>
notifee.isBatteryOptimizationEnabled(),
)
const powerManager = !!usePromise(() =>
notifee.getPowerManagerInfo().then(e => e.activity),
)

const [logs, setLogs] = useState(false)

return (
<ScrollView>
<List.Section title="Общие">
Expand All @@ -32,6 +65,69 @@ export default observer(function Notifications(
disabled={!Settings.notificationsEnabled}
/>
</List.Section>
<View style={{ padding: Spacings.s2, gap: Spacings.s2 }}>
{(batteryOptimizations || powerManager) && (
<HelperText type="error">Уведомления могут не работать</HelperText>
)}
<Warning
enabled={batteryOptimizations}
label="Оптимизация батареи"
description="Включена оптимизация батареи. Система выключит приложение и уведомления перестанут работать"
onPress={notifee.openBatteryOptimizationSettings}
/>
{powerManager && (
<Warning
enabled={false}
label="Менеджер питания"
description="Включен менеджер питания. Система выключит приложение и уведомления перестанут работать."
onPress={notifee.openPowerManagerSettings}
/>
)}
<Button mode="elevated" onPress={Linking.openSettings}>
Системные настройки приложения
</Button>
<Button mode="elevated" onPress={checkForNewMarksAndNotify}>
Проверить наличие новых оценок
</Button>
<Button mode="elevated" onPress={() => setLogs(!logs)}>
Логи уведомлений об оценках
</Button>
{logs && (
<Button
mode="elevated"
onPress={() => MarksNotificationStore.clearLogs()}
>
Очистить логи
</Button>
)}
</View>
{logs && (
<Text style={{ padding: Spacings.s1 }} selectable>
{MarksNotificationStore.logs.join('\n')}
</Text>
)}
</ScrollView>
)
})

const Warning = observer(function Warning(props: {
enabled: boolean
onPress: VoidFunction
description: string
label: string
}) {
return (
<>
<Button
mode="elevated"
{...(props.enabled ? Theme.destructiveButton : {})}
onPress={props.onPress}
>
{props.label}
</Button>
{props.enabled && (
<HelperText type="error">{props.description}</HelperText>
)}
</>
)
})
29 changes: 15 additions & 14 deletions src/services/notifications/lesson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
setBackgroundInterval,
} from '~utils/backgroundIntervals'

export const NotificationStore = new (class {
export const LessonNotifStore = new (class {
constructor() {
makeAutoObservable(this)
}
Expand All @@ -26,12 +26,12 @@ export const NotificationStore = new (class {

currentLesson: undefined | string = undefined

async remove(id = NotificationStore.id) {
async remove(id = LessonNotifStore.id) {
if (!id) return

await notifee.cancelDisplayedNotification(id)
runInAction(() => {
if (NotificationStore.id) NotificationStore.id = undefined
if (LessonNotifStore.id) LessonNotifStore.id = undefined
})
}
})()
Expand All @@ -52,21 +52,21 @@ export async function setupLessonChannel(enabled: boolean) {

if (!enabled) {
return runInAction(() => {
NotificationStore.remove(NotificationStore.id || oldNotification?.id)
LessonNotifStore.remove(LessonNotifStore.id || oldNotification?.id)
})
}

runInAction(() => {
NotificationStore.lessonChannelId = lessonChannelId
if (oldNotification?.id) NotificationStore.id = oldNotification.id
LessonNotifStore.lessonChannelId = lessonChannelId
if (oldNotification?.id) LessonNotifStore.id = oldNotification.id
})
}

let currentLessonInterval: ReturnType<typeof setBackgroundInterval>
autorun(function notificationFromDiary() {
if (currentLessonInterval) clearBackgroundInterval(currentLessonInterval)
if (!Settings.notificationsEnabled || !NotificationStore.lessonChannelId) {
return NotificationStore.remove()
if (!Settings.notificationsEnabled || !LessonNotifStore.lessonChannelId) {
return LessonNotifStore.remove()
}

const { result } = DiaryStore
Expand Down Expand Up @@ -94,7 +94,7 @@ autorun(function notificationFromDiary() {
}

// Nothing to show
NotificationStore.remove()
LessonNotifStore.remove()
}),
1000,
)
Expand Down Expand Up @@ -155,17 +155,18 @@ async function showNotification(
body += `Прошло ${elapsed} мин, осталось ${remaining}`
}

// notifee.registerForegroundService(() => new Promise(() => {}))
const notificationId = await notifee.displayNotification({
...(NotificationStore.id ? { id: NotificationStore.id } : {}),
...(LessonNotifStore.id ? { id: LessonNotifStore.id } : {}),
title,
body,
android: {
channelId: NotificationStore.lessonChannelId,
channelId: LessonNotifStore.lessonChannelId,
ongoing: true,
smallIcon: 'notification_icon',

// only alert when lesson notification
onlyAlertOnce: NotificationStore.currentLesson === lessonId,
onlyAlertOnce: LessonNotifStore.currentLesson === lessonId,

progress:
state === LessonState.going
Expand All @@ -180,7 +181,7 @@ async function showNotification(
})

runInAction(() => {
NotificationStore.id = notificationId
NotificationStore.currentLesson = lessonId
LessonNotifStore.id = notificationId
LessonNotifStore.currentLesson = lessonId
})
}
Loading

0 comments on commit cce62dd

Please sign in to comment.