Skip to content

Commit 749a3e3

Browse files
authored
Merge pull request #927 from concrnt/develop
update
2 parents da8cf4e + 6652c40 commit 749a3e3

4 files changed

Lines changed: 42 additions & 5 deletions

File tree

app/src/App.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { ConcordProvider } from './context/ConcordContext'
77
import { Menu } from './components/Menu/Menu'
88
import { Explorer, Notifications, Settings, TimelinePage, EntityPage, MessagePage, ListPage, Devtool } from './pages'
99

10-
import useSound from 'use-sound'
10+
import { useGuardedSound } from './hooks/useGuardedSound'
1111
import { MobileMenu } from './components/Menu/MobileMenu'
1212
import { useClient } from './context/ClientContext'
1313
import { GlobalActionsProvider } from './context/GlobalActions'
@@ -322,7 +322,10 @@ function App(): JSX.Element {
322322
})
323323
}, [client])
324324

325-
const [playNotification] = useSound(sound.notification, { volume: sound.volume / 100, format: UseSoundFormats })
325+
const [playNotification] = useGuardedSound(sound.notification, {
326+
volume: sound.volume / 100,
327+
format: UseSoundFormats
328+
})
326329
const playNotificationRef = useRef(playNotification)
327330
useEffect(() => {
328331
playNotificationRef.current = playNotification

app/src/components/RealtimeTimeline.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { ErrorBoundary, type FallbackProps } from 'react-error-boundary'
2626
import HeartBrokenIcon from '@mui/icons-material/HeartBroken'
2727
import type { TimelineReader } from '@concrnt/client'
2828
import { useRefWithForceUpdate } from '../hooks/useRefWithForceUpdate'
29-
import useSound from 'use-sound'
29+
import { useGuardedSound } from '../hooks/useGuardedSound'
3030
import { usePreference } from '../context/PreferenceContext'
3131
import { VList, type VListHandle } from 'virtua'
3232
import { useClient } from '../context/ClientContext'
@@ -87,7 +87,7 @@ const timeline = forwardRef((props: RealtimeTimelineProps, ref: ForwardedRef<VLi
8787

8888
const [newArrivals, setNewArrivals] = useState<NewArrivalIcons[]>([])
8989

90-
const [playBubble] = useSound(sound.post, {
90+
const [playBubble] = useGuardedSound(sound.post, {
9191
volume: sound.volume / 100,
9292
interrupt: false,
9393
format: UseSoundFormats

app/src/components/Settings/Theme.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
Box,
3+
Button,
34
Divider,
45
IconButton,
56
ListItemIcon,
@@ -10,6 +11,7 @@ import {
1011
Typography,
1112
useTheme
1213
} from '@mui/material'
14+
import { useSnackbar } from 'notistack'
1315
import { ThemeCreator } from '../ThemeCreator'
1416
import { useEffect, useMemo, useState } from 'react'
1517
import { useTranslation } from 'react-i18next'
@@ -33,6 +35,7 @@ export const ThemeSettings = (): JSX.Element => {
3335
const theme = useTheme<ConcurrentTheme>()
3436
const { t } = useTranslation('', { keyPrefix: 'ui' })
3537
const editorModal = useEditorModal()
38+
const { enqueueSnackbar } = useSnackbar()
3639

3740
const previewTheme: Record<string, ConcurrentTheme> = useMemo(
3841
() => Object.fromEntries(Object.keys(Themes).map((e) => [e, loadConcurrentTheme(e)])),
@@ -95,7 +98,19 @@ export const ThemeSettings = (): JSX.Element => {
9598
</Paper>
9699
</Box>
97100
<Box display="flex" flexDirection="column" gap={1}>
98-
<Typography variant="h3">Select Theme:</Typography>
101+
<Box display="flex" justifyContent="space-between" alignItems="center" flexWrap="wrap" gap={1}>
102+
<Typography variant="h3">Select Theme:</Typography>
103+
<Button
104+
variant="outlined"
105+
startIcon={<DataObjectIcon />}
106+
onClick={() => {
107+
window.navigator.clipboard.writeText(JSON.stringify(customThemes))
108+
enqueueSnackbar('全カスタムテーマをコピーしました')
109+
}}
110+
>
111+
全部コピー
112+
</Button>
113+
</Box>
99114
<Box
100115
sx={{
101116
display: { xs: 'flex', md: 'grid' },

app/src/hooks/useGuardedSound.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import useSound from 'use-sound'
2+
import { useCallback } from 'react'
3+
import { type HookOptions, type PlayOptions, type ReturnedValue } from 'use-sound/dist/types'
4+
5+
// バックグラウンドタブではAudioContextがsuspendされ、howlerがplay要求を
6+
// 内部キューに溜めて復帰時に一斉再生してしまうため、hidden中は再生要求自体を捨てる
7+
export function useGuardedSound(src: string | string[], options?: HookOptions): ReturnedValue {
8+
const [play, exposed] = useSound(src, options)
9+
10+
const guardedPlay = useCallback(
11+
(opts?: PlayOptions): void => {
12+
if (document.hidden) return
13+
play(opts)
14+
},
15+
[play]
16+
)
17+
18+
return [guardedPlay, exposed]
19+
}

0 commit comments

Comments
 (0)