From 9e849ccc32df9be4122b5e1a2be98aa95fa1917c Mon Sep 17 00:00:00 2001 From: Shuo Wu Date: Tue, 26 May 2020 22:03:46 -0400 Subject: [PATCH] feat: option to set seconds to jump before recorded time resolves #30 --- extension/_locales/en/messages.json | 9 +++ extension/src/constants.js | 2 + .../Settings/ExportAndImport/index.js | 2 +- .../containers/Settings/Video/index.js | 65 +++++++++++++++++++ .../src/options/containers/Settings/index.js | 13 +++- .../src/ui/services/player/HTML5Player.js | 3 +- extension/src/ui/services/player/Player.js | 9 ++- .../ui/services/player/YoutubeIframePlayer.js | 3 +- 8 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 extension/src/options/containers/Settings/Video/index.js diff --git a/extension/_locales/en/messages.json b/extension/_locales/en/messages.json index 061214d..fb8914f 100644 --- a/extension/_locales/en/messages.json +++ b/extension/_locales/en/messages.json @@ -141,6 +141,15 @@ "options_settings_title": { "message": "Settings" }, + "options_settings_video_title": { + "message": "Video" + }, + "options_settings_video_description": { + "message": "Settings to customize video playback behaviours" + }, + "options_settings_seek_label": { + "message": "Seconds to jump before recoreded time" + }, "options_settings_exportAndImport_title": { "message": "Export and Import" }, diff --git a/extension/src/constants.js b/extension/src/constants.js index 199b50a..49a4f70 100644 --- a/extension/src/constants.js +++ b/extension/src/constants.js @@ -16,6 +16,8 @@ export const NODE_ENV_PLAYGROUND = 'playground'; export const QUERY_AUTO_JUMP = 'yinotetimestamp'; +export const KEY_VIDEO_SEEK_SECONDS = 'video_seek_seconds'; + export const REST_BASE_URL = process.env.NODE_ENV === 'production' ? process.env.REST_BASE_URL_PROD diff --git a/extension/src/options/containers/Settings/ExportAndImport/index.js b/extension/src/options/containers/Settings/ExportAndImport/index.js index ea49781..35c674d 100644 --- a/extension/src/options/containers/Settings/ExportAndImport/index.js +++ b/extension/src/options/containers/Settings/ExportAndImport/index.js @@ -59,7 +59,7 @@ const ExportAndImport = () => { }; return ( - + diff --git a/extension/src/options/containers/Settings/Video/index.js b/extension/src/options/containers/Settings/Video/index.js new file mode 100644 index 0000000..8e61fb5 --- /dev/null +++ b/extension/src/options/containers/Settings/Video/index.js @@ -0,0 +1,65 @@ +import React, { useState, useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Grid, Typography, Divider, Select, MenuItem } from '@material-ui/core'; +import { KEY_VIDEO_SEEK_SECONDS } from '../../../../constants'; + +const Video = () => { + const { t } = useTranslation('options'); + const [seekSecond, setSeekSecond] = useState(0); + + useEffect(() => { + browser.storage.local.get('settings').then(data => { + const settings = data.settings || {}; + setSeekSecond(settings[KEY_VIDEO_SEEK_SECONDS] || 0); + }); + }, []); + + const handleSecondChange = e => { + const { value } = e.target; + browser.storage.local + .get('settings') + .then(data => { + const settings = data.settings || {}; + settings[KEY_VIDEO_SEEK_SECONDS] = value; + return browser.storage.local.set({ settings }); + }) + .then(() => { + setSeekSecond(value); + }); + }; + + return ( + + + + {t('settings.video.title')} + + + + + + + {t('settings.video.description')} + + + + + + + {t('settings.seek.label')} + + + + + + + + ); +}; + +export default Video; diff --git a/extension/src/options/containers/Settings/index.js b/extension/src/options/containers/Settings/index.js index 48961ad..471be17 100644 --- a/extension/src/options/containers/Settings/index.js +++ b/extension/src/options/containers/Settings/index.js @@ -1,6 +1,8 @@ import React, { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { useStoreActions } from 'easy-peasy'; +import { Grid } from '@material-ui/core'; +import Video from './Video'; import ExportAndImport from './ExportAndImport'; const Settings = () => { @@ -13,7 +15,16 @@ const Settings = () => { setTitle(t('settings.title')); }, [setTitle, t]); - return ; + return ( + + + + + + + + ); }; export default Settings; diff --git a/extension/src/ui/services/player/HTML5Player.js b/extension/src/ui/services/player/HTML5Player.js index bb9c97b..65fbf18 100644 --- a/extension/src/ui/services/player/HTML5Player.js +++ b/extension/src/ui/services/player/HTML5Player.js @@ -32,7 +32,8 @@ export default class HTML5Player extends Player { } seek(timestamp) { - this.video.currentTime = timestamp; + const timeToSeek = timestamp - this.seekSeconds; + this.video.currentTime = timeToSeek >= 0 ? timeToSeek : 0; } async getCurrentTime() { diff --git a/extension/src/ui/services/player/Player.js b/extension/src/ui/services/player/Player.js index c1be46f..705fd91 100644 --- a/extension/src/ui/services/player/Player.js +++ b/extension/src/ui/services/player/Player.js @@ -1,5 +1,12 @@ +import { KEY_VIDEO_SEEK_SECONDS } from '../../../constants'; + export default class Player { - constructor(options) {} + constructor() { + browser.storage.local.get('settings').then(data => { + const settings = data.settings || {}; + this.seekSeconds = +settings[KEY_VIDEO_SEEK_SECONDS] || 0; + }); + } getVideoElement() { logger.warn('Method need to be implemented'); diff --git a/extension/src/ui/services/player/YoutubeIframePlayer.js b/extension/src/ui/services/player/YoutubeIframePlayer.js index a23d10b..64a73ac 100644 --- a/extension/src/ui/services/player/YoutubeIframePlayer.js +++ b/extension/src/ui/services/player/YoutubeIframePlayer.js @@ -41,7 +41,8 @@ export default class YoutubeIframePlayer extends Player { } seek(timestamp) { - this.#player.seekTo(timestamp); + const timeToSeek = timestamp - this.seekSeconds; + this.#player.seekTo(timeToSeek >= 0 ? timeToSeek : 0); } async getCurrentTime() {