Skip to content

Commit

Permalink
Subtitles width percentage setting
Browse files Browse the repository at this point in the history
- Allow subtitles to take up more width on the screen. Especially helps
  with mobile UX.
  • Loading branch information
killergerbah committed Jul 20, 2024
1 parent bae2032 commit 0300caf
Show file tree
Hide file tree
Showing 24 changed files with 178 additions and 52 deletions.
1 change: 1 addition & 0 deletions common/app/components/SettingsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export default function SettingsDialog({
extensionSupportsSidePanel={extension.supportsSidePanel}
extensionSupportsOrderableAnkiFields={extension.supportsOrderableAnkiFields}
extensionSupportsTrackSpecificSettings={extension.supportsTrackSpecificSettings}
extensionSupportsSubtitlesWidthSetting={extension.supportsSubtitlesWidthSetting}
insideApp
chromeKeyBinds={extension.extensionCommands}
onOpenChromeExtensionShortcuts={extension.openShortcuts}
Expand Down
14 changes: 8 additions & 6 deletions common/app/components/VideoPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,8 @@ const showingSubtitleHtml = (
(imageBasedSubtitleScaleFactor * (videoRef.current?.width ?? window.screen.availWidth)) /
subtitle.textImage.screen.width;
const width = imageScale * subtitle.textImage.image.width;

return `
<div style="max-width:${width}px;">
<div style="max-width:${width}px;margin:auto;">
<img
style="width:100%;"
alt="subtitle"
Expand Down Expand Up @@ -1294,11 +1293,14 @@ export default function VideoPlayer({
/>
{displaySubtitles && (
<div
style={
subtitleAlignment === 'bottom'
style={{
...(subtitleAlignment === 'bottom'
? { bottom: subtitlePositionOffset }
: { top: subtitlePositionOffset }
}
: { top: subtitlePositionOffset }),
...(subtitleSettings.subtitlesWidth === -1
? {}
: { width: `${subtitleSettings.subtitlesWidth}%` }),
}}
className={classes.subtitleContainer}
>
{showSubtitles.map((subtitle, index) => {
Expand Down
5 changes: 5 additions & 0 deletions common/app/services/chrome-extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ export default class ChromeExtension {

window.addEventListener('message', this.windowEventListener);
}

get supportsSubtitlesWidthSetting() {
return this.installed && gte(this.version, '1.4.0');
}

get supportsOrderableAnkiFields() {
return this.installed && gte(this.version, '1.3.0');
}
Expand Down
2 changes: 2 additions & 0 deletions common/app/services/video-channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ export default class VideoChannel {
subtitleAlignment,
subtitleTracksV2,
subtitlePositionOffset,
subtitlesWidth,
} = settings;
const message: SubtitleSettingsToVideoMessage = {
command: 'subtitleSettings',
Expand All @@ -432,6 +433,7 @@ export default class VideoChannel {
subtitleAlignment,
subtitleTracksV2,
subtitlePositionOffset,
subtitlesWidth,
},
};
this.protocol.postMessage(message);
Expand Down
144 changes: 103 additions & 41 deletions common/components/SettingsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import { makeStyles, useTheme } from '@material-ui/core/styles';
import AddIcon from '@material-ui/icons/Add';
import LockIcon from '@material-ui/icons/Lock';
import Box from '@material-ui/core/Box';
import ClearIcon from '@material-ui/icons/Clear';
import EditIcon from '@material-ui/icons/Edit';
import InfoIcon from '@material-ui/icons/Info';
import UndoIcon from '@material-ui/icons/Undo';
import FormControl from '@material-ui/core/FormControl';
import FormGroup from '@material-ui/core/FormGroup';
import FormLabel from '@material-ui/core/FormLabel';
Expand Down Expand Up @@ -40,7 +42,7 @@ import {
textSubtitleSettingsAreDirty,
textSubtitleSettingsForTrack,
} from '@project/common/settings';
import { computeStyles, download, isNumeric } from '@project/common/util';
import { download, isNumeric } from '@project/common/util';
import { CustomStyle, validateSettings } from '@project/common/settings';
import { useOutsideClickListener } from '@project/common/hooks';
import TagsTextField from './TagsTextField';
Expand All @@ -66,7 +68,6 @@ import { WebSocketClient } from '../web-socket-client/web-socket-client';
import { isFirefox } from '@project/common/browser-detection';
import SubtitleAppearanceTrackSelector from './SubtitleAppearanceTrackSelector';
import SubtitlePreview from './SubtitlePreview';
import UndoIcon from '@material-ui/icons/Undo';

interface StylesProps {
smallScreen: boolean;
Expand Down Expand Up @@ -635,6 +636,7 @@ interface Props {
extensionSupportsSidePanel: boolean;
extensionSupportsOrderableAnkiFields: boolean;
extensionSupportsTrackSpecificSettings: boolean;
extensionSupportsSubtitlesWidthSetting: boolean;
insideApp?: boolean;
settings: AsbplayerSettings;
scrollToId?: string;
Expand All @@ -661,6 +663,7 @@ export default function SettingsForm({
extensionSupportsSidePanel,
extensionSupportsOrderableAnkiFields,
extensionSupportsTrackSpecificSettings,
extensionSupportsSubtitlesWidthSetting,
insideApp,
scrollToId,
chromeKeyBinds,
Expand Down Expand Up @@ -786,6 +789,7 @@ export default function SettingsForm({
subtitlePreview,
subtitlePositionOffset,
subtitleAlignment,
subtitlesWidth,
audioPaddingStart,
audioPaddingEnd,
maxImageWidth,
Expand Down Expand Up @@ -1836,6 +1840,25 @@ export default function SettingsForm({
</TextField>
</div>
)}

{subtitleBlur !== undefined && (
<Tooltip placement="bottom-end" title={t('settings.subtitleBlurDescription')!}>
<LabelWithHoverEffect
control={
<Switch
checked={subtitleBlur}
onChange={(e) => {
handleSubtitleTextSettingChanged('subtitleBlur', e.target.checked);
}}
/>
}
label={t('settings.subtitleBlur')}
labelPlacement="start"
className={classes.switchLabel}
/>
</Tooltip>
)}

{subtitleCustomStyles !== undefined && (
<>
{subtitleCustomStyles.map((customStyle, index) => {
Expand Down Expand Up @@ -1873,48 +1896,12 @@ export default function SettingsForm({
</>
)}

{subtitleBlur !== undefined && (
<Tooltip placement="bottom-end" title={t('settings.subtitleBlurDescription')!}>
<LabelWithHoverEffect
control={
<Switch
checked={subtitleBlur}
onChange={(e) => {
handleSubtitleTextSettingChanged('subtitleBlur', e.target.checked);
}}
/>
}
label={t('settings.subtitleBlur')}
labelPlacement="start"
className={classes.switchLabel}
/>
</Tooltip>
)}
{selectedSubtitleAppearanceTrack === undefined && (
<>
<div className={classes.subtitleSetting}>
<TextField
type="number"
label={t('settings.imageBasedSubtitleScaleFactor')}
placeholder="Inherited"
fullWidth
inputProps={{
min: 0,
max: 1,
step: 0.1,
}}
value={imageBasedSubtitleScaleFactor}
color="secondary"
onChange={(event) =>
handleSettingChanged(
'imageBasedSubtitleScaleFactor',
Number(event.target.value)
)
}
/>
</div>
<div className={classes.subtitleSetting}>
<FormLabel component="legend">{t('settings.subtitleAlignment')}</FormLabel>
<FormLabel className={classes.top} component="legend">
{t('settings.subtitleAlignment')}
</FormLabel>
<RadioGroup row>
<LabelWithHoverEffect
control={
Expand Down Expand Up @@ -1961,6 +1948,81 @@ export default function SettingsForm({
}
/>
</div>
{(!extensionInstalled || extensionSupportsSubtitlesWidthSetting) && (
<div className={classes.subtitleSetting}>
<TextField
className={classes.textField}
color="secondary"
fullWidth
label={t('settings.subtitlesWidth')}
disabled={subtitlesWidth === -1}
value={subtitlesWidth === -1 ? 'auto' : subtitlesWidth}
onChange={(e) => {
const numberValue = Number(e.target.value);

if (
!Number.isNaN(numberValue) &&
numberValue >= 0 &&
numberValue <= 100
) {
handleSettingChanged('subtitlesWidth', numberValue);
}
}}
InputProps={{
endAdornment: (
<>
{subtitlesWidth === -1 && (
<InputAdornment position="end">
<IconButton
onClick={() =>
handleSettingChanged('subtitlesWidth', 100)
}
>
<EditIcon />
</IconButton>
</InputAdornment>
)}
{subtitlesWidth !== -1 && (
<>
<InputAdornment position="end">%</InputAdornment>
<InputAdornment position="end">
<IconButton
onClick={() =>
handleSettingChanged('subtitlesWidth', -1)
}
>
<ClearIcon />
</IconButton>
</InputAdornment>
</>
)}
</>
),
}}
/>
</div>
)}
<div className={classes.subtitleSetting}>
<TextField
type="number"
label={t('settings.imageBasedSubtitleScaleFactor')}
placeholder="Inherited"
fullWidth
inputProps={{
min: 0,
max: 1,
step: 0.1,
}}
value={imageBasedSubtitleScaleFactor}
color="secondary"
onChange={(event) =>
handleSettingChanged(
'imageBasedSubtitleScaleFactor',
Number(event.target.value)
)
}
/>
</div>
</>
)}
</FormGroup>
Expand Down
2 changes: 1 addition & 1 deletion common/components/SubtitleTextImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default function SubtitleTextImage({ subtitle, availableWidth, scale }: P
const width = imageScale * subtitle.textImage.image.width;

return (
<div style={{ maxWidth: width }}>
<div style={{ maxWidth: width, margin: 'auto' }}>
<img style={{ width: '100%' }} alt="subtitle" src={subtitle.textImage.dataUrl} />
</div>
);
Expand Down
1 change: 1 addition & 0 deletions common/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@
"subtitleRegexFilterTextReplacement": "Untertitelfilter Ersetzung",
"subtitleSize": "Untertitelgröße",
"subtitleThickness": "Subtitle Font Thickness",
"subtitlesWidth": "Subtitles Width",
"surroundingSubtitlesCountRadius": "Surrounding Subtitles Count Radius",
"surroundingSubtitlesTimeRadius": "Surrounding Subtitles Time Radius",
"tags": "Schlagwörter",
Expand Down
1 change: 1 addition & 0 deletions common/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@
"subtitleRegexFilterTextReplacement": "Subtitle regex filter text replacement",
"subtitleSize": "Subtitle Size",
"subtitleThickness": "Subtitle Font Thickness",
"subtitlesWidth": "Subtitles Width",
"surroundingSubtitlesCountRadius": "Surrounding Subtitles Count Radius",
"surroundingSubtitlesTimeRadius": "Surrounding Subtitles Time Radius",
"tags": "Tags",
Expand Down
1 change: 1 addition & 0 deletions common/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@
"subtitleRegexFilterTextReplacement": "Texto de reemplazo para el filtro regex",
"subtitleSize": "Tamaño de los subtítulos",
"subtitleThickness": "Grosor de la Fuente de los Subtítulos",
"subtitlesWidth": "Subtitles Width",
"surroundingSubtitlesCountRadius": "Radio de Cantidad de Subtítulos Circundantes",
"surroundingSubtitlesTimeRadius": "Radio Temporal para Subtítulos Circundantes",
"tags": "Etiquetas",
Expand Down
1 change: 1 addition & 0 deletions common/locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@
"subtitleRegexFilterTextReplacement": "字幕の正規表現フィルタの置き換えテキスト",
"subtitleSize": "字幕のサイズ",
"subtitleThickness": "字幕のフォントの太さ",
"subtitlesWidth": "Subtitles Width",
"surroundingSubtitlesCountRadius": "前後に表示される字幕の最大数",
"surroundingSubtitlesTimeRadius": "前後の字幕が表示される範囲(時間)",
"tags": "タグ",
Expand Down
1 change: 1 addition & 0 deletions common/locales/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@
"subtitleRegexFilterTextReplacement": "Zamiana tekstu z filtru Regex napisów",
"subtitleSize": "Wielkość napisów",
"subtitleThickness": "Grubość czcionki napisów",
"subtitlesWidth": "Subtitles Width",
"surroundingSubtitlesCountRadius": "Limit liczby napisów otaczających",
"surroundingSubtitlesTimeRadius": "Limit czasu napisów otaczających",
"tags": "Tagi",
Expand Down
1 change: 1 addition & 0 deletions common/locales/pt_BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@
"subtitleRegexFilterTextReplacement": "Substituição de texto do filtro regex da legenda",
"subtitleSize": "Tamanho da legenda",
"subtitleThickness": "Expessura da fonte da legenda",
"subtitlesWidth": "Subtitles Width",
"surroundingSubtitlesCountRadius": "Raio de contagem de legendas ao redor",
"surroundingSubtitlesTimeRadius": "Raio de tempo das legendas ao redor",
"tags": "Tags",
Expand Down
1 change: 1 addition & 0 deletions common/locales/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@
"subtitleRegexFilterTextReplacement": "Замена текста для фильтра регулярных выражений для субтитров",
"subtitleSize": "Размер субтитров",
"subtitleThickness": "Толщина шрифта субтитров",
"subtitlesWidth": "Subtitles Width",
"surroundingSubtitlesCountRadius": "Радиус количества окружающих субтитров",
"surroundingSubtitlesTimeRadius": "Временной радиус окружающих субтитров",
"tags": "Теги",
Expand Down
1 change: 1 addition & 0 deletions common/locales/zh_CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@
"subtitleRegexFilterTextReplacement": "字幕正则筛选器文本替换",
"subtitleSize": "字幕大小",
"subtitleThickness": "字幕字体厚度",
"subtitlesWidth": "Subtitles Width",
"surroundingSubtitlesCountRadius": "环绕字幕计数半径",
"surroundingSubtitlesTimeRadius": "环绕字幕时间半径",
"tags": "标签",
Expand Down
3 changes: 3 additions & 0 deletions common/settings/settings-import-export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ const settingsSchema = {
},
},
},
subtitlesWidth: {
type: 'number',
},
streamingAppUrl: {
type: 'string',
},
Expand Down
1 change: 1 addition & 0 deletions common/settings/settings-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export const defaultSettings: AsbplayerSettings = {
subtitlePositionOffset: 75,
subtitleAlignment: 'bottom',
subtitleTracksV2: [],
subtitlesWidth: 100,
audioPaddingStart: 0,
audioPaddingEnd: 500,
maxImageWidth: 0,
Expand Down
Loading

0 comments on commit 0300caf

Please sign in to comment.