Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add hotkey t/p and tooltips #275

Merged
merged 1 commit into from
Apr 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 32 additions & 31 deletions packages/griffith/src/components/Player.tsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,55 @@
import React, {useRef, useEffect, useState, useContext, useMemo} from 'react'
import {css} from 'aphrodite/no-important'
import BigScreen from 'isomorphic-bigscreen'
import {EVENTS, ACTIONS} from 'griffith-message'
import {ACTIONS, EVENTS} from 'griffith-message'
import {ua} from 'griffith-utils'
import {
ProgressDot,
ProgressValue,
PlaybackRate,
PlaySourceMap,
RealQuality,
} from '../types'
import BigScreen from 'isomorphic-bigscreen'
import React, {useContext, useEffect, useMemo, useRef, useState} from 'react'
import {
defaultLocale,
LocaleCode,
PartialLocaleConfigMap,
} from '../constants/locales'
import VideoSourceProvider from '../contexts/VideoSourceProvider'
import LocaleProvider from '../contexts/LocaleProvider'
import {
MessageProvider,
MessageContextValue,
InternalMessageContext,
MessageContextValue,
MessageProvider,
} from '../contexts/MessageContext'
import VideoSourceContext from '../contexts/VideoSourceContext'
import ObjectFitContext, {ObjectFit} from '../contexts/ObjectFitContext'
import PositionProvider from '../contexts/PositionProvider'
import ObjectFitProvider from '../contexts/ObjectFitProvider'
import LocaleProvider from '../contexts/LocaleProvider'
import TranslatedText from './TranslatedText'
import Icon from './Icon'
import * as displayIcons from './icons/display/index'
import Loader from './Loader'
import Video from './Video'
import Controller from './Controller'
import VolumeItem from './items/VolumeItem'
import MinimalTimeline from './MinimalTimeline'
import Layer from './Layer'
import getBufferedTime from '../utils/getBufferedTime'
import PositionProvider from '../contexts/PositionProvider'
import VideoSourceContext from '../contexts/VideoSourceContext'
import VideoSourceProvider from '../contexts/VideoSourceProvider'
import useBoolean from '../hooks/useBoolean'
import useHandler from '../hooks/useHandler'
import useMount from '../hooks/useMount'
import usePrevious from '../hooks/usePrevious'
import {
PlaybackRate,
PlaySourceMap,
ProgressDot,
ProgressValue,
RealQuality,
} from '../types'
import formatDuration from '../utils/formatDuration'
import storage from '../utils/storage'
import getBufferedTime from '../utils/getBufferedTime'
import Pip from '../utils/pip'
import storage from '../utils/storage'
import {
ActionToastOutlet,
ActionToastProvider,
useActionToastDispatch,
} from './ActionToast'
import Controller from './Controller'
import Icon from './Icon'
import * as displayIcons from './icons/display/index'
import VolumeItem from './items/VolumeItem'
import Layer from './Layer'
import Loader from './Loader'
import MinimalTimeline from './MinimalTimeline'
import styles, {hiddenOrShownStyle} from './Player.styles'
import useBoolean from '../hooks/useBoolean'
import useMount from '../hooks/useMount'
import useHandler from '../hooks/useHandler'
import TranslatedText from './TranslatedText'
import usePlayerShortcuts from './usePlayerShortcuts'
import usePrevious from '../hooks/usePrevious'
import Video from './Video'

const CONTROLLER_HIDE_DELAY = 3000

Expand Down Expand Up @@ -476,6 +476,7 @@ const InnerPlayer: React.FC<InnerPlayerProps> = ({
onTogglePlay: handleTogglePlay,
onToggleFullScreen: handleToggleFullScreen,
onTogglePageFullScreen: handleTogglePageFullScreen,
onTogglePip: handleTogglePip,
onVolumeChange: handleVideoVolumeChange,
onSeek: handleSeek,
})
Expand Down
6 changes: 4 additions & 2 deletions packages/griffith/src/components/items/ControllerTooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React, {cloneElement} from 'react'
import {css} from 'aphrodite/no-important'
import React, {cloneElement} from 'react'
import {LocaleConfigKey} from '../../constants/locales'
import {useLocaleText} from '../../contexts/LocaleContext'
import useBoolean from '../../hooks/useBoolean'
import styles from '../Controller.styles'

type Props = {
localeKey: LocaleConfigKey
hotkey?: string
children: React.ReactElement
}

Expand All @@ -18,7 +19,7 @@ const canUseTouch =
*
* `localeKey` 取本地文本,显示为 tooltip,同时设定为 children 的 `aria-label`
*/
const ControllerTooltip: React.FC<Props> = ({localeKey, children}) => {
const ControllerTooltip: React.FC<Props> = ({localeKey, hotkey, children}) => {
const text = useLocaleText(localeKey)
const [isHovered, isHoveredSwitch] = useBoolean()

Expand All @@ -38,6 +39,7 @@ const ControllerTooltip: React.FC<Props> = ({localeKey, children}) => {
)}
>
{text}
{hotkey && ` (${hotkey})`}
</div>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import * as icons from '../icons/controller'
import ControllerTooltip from './ControllerTooltip'
import ControllerButton from './ControllerButton'
import ControllerTooltip from './ControllerTooltip'

const FullScreenButtonItem: React.FC<{
isFullScreen: boolean
Expand All @@ -11,6 +11,7 @@ const FullScreenButtonItem: React.FC<{
localeKey={
isFullScreen ? 'action-exit-fullscreen' : 'action-enter-fullscreen'
}
hotkey="f"
>
<ControllerButton
icon={isFullScreen ? icons.smallscreen : icons.fullscreen}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import * as icons from '../icons/controller'
import ControllerTooltip from './ControllerTooltip'
import ControllerButton from './ControllerButton'
import ControllerTooltip from './ControllerTooltip'

const PageFullScreenButtonItem: React.FC<{
isFullScreen: boolean
Expand All @@ -13,6 +13,7 @@ const PageFullScreenButtonItem: React.FC<{
? 'action-exit-page-fullscreen'
: 'action-enter-page-fullscreen'
}
hotkey="t"
>
<ControllerButton
icon={isFullScreen ? icons.exitPageScreen : icons.enterPageScreen}
Expand Down
7 changes: 5 additions & 2 deletions packages/griffith/src/components/items/PipButtonItem.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React from 'react'
import * as icons from '../icons/controller'
import ControllerTooltip from './ControllerTooltip'
import ControllerButton from './ControllerButton'
import ControllerTooltip from './ControllerTooltip'

const PipButtonItem: React.FC<{
isPip: boolean
onClick: React.HTMLAttributes<HTMLButtonElement>['onClick']
}> = ({isPip, onClick}) => (
<ControllerTooltip localeKey={isPip ? 'action-exit-pip' : 'action-enter-pip'}>
<ControllerTooltip
localeKey={isPip ? 'action-exit-pip' : 'action-enter-pip'}
hotkey="h"
>
<ControllerButton
icon={isPip ? icons.exitPip : icons.pip}
onClick={onClick}
Expand Down
2 changes: 1 addition & 1 deletion packages/griffith/src/components/items/PlayButtonItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const PlayButtonItem: React.FC<{
isPlaying: boolean
onClick: React.HTMLAttributes<HTMLButtonElement>['onClick']
}> = ({isPlaying, onClick}) => (
<ControllerTooltip localeKey={isPlaying ? 'pause' : 'play'}>
<ControllerTooltip localeKey={isPlaying ? 'pause' : 'play'} hotkey="k">
<ControllerButton
icon={isPlaying ? icons.pause : icons.play}
onClick={onClick}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ exports[`FullScreenButtonItem get FullScreenButtonItem component 1`] = `
></path></svg
></span>
</button>
<div class="menu_1a7s4a3-o_O-tooltipContent_me14v4">Exit Fullscreen</div>
<div class="menu_1a7s4a3-o_O-tooltipContent_me14v4">
Exit Fullscreen (f)
</div>
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ exports[`PlayButtonItem get PlayButtonItem component 1`] = `
></path></svg
></span>
</button>
<div class="menu_1a7s4a3-o_O-tooltipContent_me14v4">Pause</div>
<div class="menu_1a7s4a3-o_O-tooltipContent_me14v4">Pause (k)</div>
</div>
</div>

Expand Down
20 changes: 16 additions & 4 deletions packages/griffith/src/components/usePlayerShortcuts.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as displayIcons from './icons/display/index'
import * as controllerIcons from './icons/controller/index'
import {useEffect, useContext} from 'react'
import clamp from 'lodash/clamp'
import {useContext, useEffect} from 'react'
import VideoSourceContext from '../contexts/VideoSourceContext'
import useHandler from '../hooks/useHandler'
import {useActionToastDispatch} from './ActionToast'
import VideoSourceContext from '../contexts/VideoSourceContext'
import * as controllerIcons from './icons/controller/index'
import * as displayIcons from './icons/display/index'

type Options = {
root: HTMLDivElement | null
Expand All @@ -17,6 +17,7 @@ type Options = {
standalone?: boolean
onVolumeChange: (value: number) => void
onTogglePlay: () => void
onTogglePip: () => void
onToggleFullScreen: () => void
onTogglePageFullScreen: () => void
onSeek: (currentTime: number) => void
Expand All @@ -36,6 +37,7 @@ const usePlayerShortcuts = ({
standalone,
onVolumeChange,
onTogglePlay,
onTogglePip,
onToggleFullScreen,
onTogglePageFullScreen,
onSeek,
Expand Down Expand Up @@ -101,6 +103,16 @@ const usePlayerShortcuts = ({
onTogglePlay()
break

case 'p':
case 'P':
onTogglePip()
break

case 't':
case 'T':
onTogglePageFullScreen()
break

case 'f':
case 'F':
onToggleFullScreen()
Expand Down