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

Enter confirms subtitle track selection #445

Draft
wants to merge 52 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
35717d1
Enter confirms subtitle track selection
pooky-programs Jun 23, 2024
c691714
Fix re-record playing audio at the same time
killergerbah Jun 24, 2024
2062c94
Extension version 1.3.2
killergerbah Jun 24, 2024
f14bd91
Release Firefox extension 1.3.2
killergerbah Jun 25, 2024
01cf6d0
Fix unext video name detection
killergerbah Jun 29, 2024
be4c1d5
Prevent lone surrogates in file names from breaking AnkiConnect
killergerbah Jun 29, 2024
125003c
Update loc strings
killergerbah Jul 4, 2024
c5abd4b
Update extension references in app to latest version
killergerbah Jul 4, 2024
9dac83f
Fix extension loc not updating on Chrome
killergerbah Jul 4, 2024
bae2032
Disable scroll-wheel to change subtitle position offset
killergerbah Jul 19, 2024
0300caf
Subtitles width percentage setting
killergerbah Jul 20, 2024
039ec32
Pull loc
killergerbah Jul 20, 2024
3cf4b58
Fix test compilation
killergerbah Jul 20, 2024
c83dacb
Fix subtitle container position logic when video is far down page
killergerbah Jul 21, 2024
5ca8416
Fix overlay blocking too much of the video on small screens
killergerbah Jul 21, 2024
b4bdb83
Auto-detect full list of subtitle tracks on netflix
killergerbah Jul 22, 2024
3c54f71
Better handling of concurrent lazy language-specific track requests
killergerbah Jul 23, 2024
e5f9dc8
'Toggle side panel' bind works when side panel is in focus
killergerbah Jul 23, 2024
96a74cb
Support subtitle autodetection on NRK TV
killergerbah Jul 26, 2024
7cfd700
Pass on README
killergerbah Jul 26, 2024
d301c9d
Readme: update dictionaries and regex sections (#477)
artjomsR Aug 4, 2024
03ae88d
Update README (sponsors)
killergerbah Aug 4, 2024
12fad84
Track n anki field values also inherit html markup on update-last-card
killergerbah Aug 4, 2024
f7f4dfa
Use embed URLs for URL field on youtube videos
killergerbah Aug 4, 2024
566e2ac
Blank selection for anki field assignment is more visible
killergerbah Aug 4, 2024
f1904e1
Subtitle end timestamps are not inclusive
killergerbah Aug 4, 2024
699df9e
Subtitle endpoint is exclusive - missed case
killergerbah Aug 4, 2024
a743ab7
Pause-on-hover setting
killergerbah Aug 4, 2024
9c73b5f
Lower z-index on subtitle container
killergerbah Aug 4, 2024
c784e18
Pausing while recording ends current mining command
killergerbah Aug 4, 2024
dd5f49f
Button to clear mining history
killergerbah Aug 5, 2024
be9f649
Use consistent padding on delete-all button in copy history list
killergerbah Aug 8, 2024
f12065c
Fix YT subtitle detection
killergerbah Aug 8, 2024
be59c38
Pull new Japanese strings
killergerbah Aug 8, 2024
053fb65
Hide pause-on-hover setting if extension does not support it
killergerbah Aug 8, 2024
26c6797
Missing extensionSupportsPauseOnHover prop in Popup
killergerbah Aug 8, 2024
f43e8cc
Use correct video ID when building YT embed URL
killergerbah Aug 8, 2024
d852a22
Update readme (sponsors, formatting)
killergerbah Aug 8, 2024
ad722fe
Speculative addition to complete fix for YT subs detection
killergerbah Aug 8, 2024
2cd7338
add default policy if one doesn't exist (#489)
s-cork Aug 9, 2024
00eecd5
Extension version 1.4.1
killergerbah Aug 9, 2024
38405b9
Fix track selector selecting multiple tracks sometimes
killergerbah Aug 9, 2024
e5bdb3b
Extension version 1.4.2
killergerbah Aug 9, 2024
f3c09b9
Update readme (sponsors)
killergerbah Aug 9, 2024
8939a16
Update latest extension version 1.4.2
killergerbah Aug 11, 2024
a14bb14
Release 1.4.2 firefox
killergerbah Aug 11, 2024
a454804
Clamp subtitle container width by window width
killergerbah Aug 11, 2024
07c7ce2
Better defaults for subtitle width
killergerbah Aug 11, 2024
02662f0
VideoPlayer.tsx: Don't newline subtitles. (Help yomitan get the entir…
Viterkim Aug 11, 2024
abe2f67
Update contributors
killergerbah Aug 12, 2024
6248a97
Enter confirms subtitle track selection
pooky-programs Jun 23, 2024
d010acb
Merge branch 'main' of https://github.com/pooky-programs/asbplayer
pooky-programs Aug 12, 2024
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
31 changes: 24 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,15 @@ Suna,
kibo,
[@genericdave](https://github.com/genericdave),
Daniel,
Cristian
Cristian,
Joey Potter,
[@InteractiveNinja](https://github.com/InteractiveNinja),
[@agloo](https://github.com/agloo),
[@Venous771](https://github.com/Venous771),
[@Viterkim](https://github.com/Viterkim),
Julian,
DanglingSabSuu


and to those who have donated privately.

Expand All @@ -63,7 +71,8 @@ Thank you to all those who have contributed to asbplayer:
[@bpwhelan](https://github.com/bpwhelan),
[@pooky-programs](https://github.com/pooky-programs),
[@m-edlund](https://github.com/m-edlund),
[@nekorushi](https://github.com/nekorushi)
[@nekorushi](https://github.com/nekorushi),
[@Viterkim](https://github.com/Viterkim)

Thank you to all those who have translated asbplayer:

Expand All @@ -75,7 +84,7 @@ Thank you to all those who have translated asbplayer:
**Leo Gonzalez** (Spanish),
**Yuri (ganqqwerty)** (Russian)

If you are a non-English native, and would like to help translate asbplayer, join the [Crowdin project](https://crowdin.com/project/asbplayer).
If you are a non-English native, and would like to help translate asbplayer, join the [Crowdin project](https://crowdin.com/project/asbplayer). If your language isn't there, feel free to create an issue to add it on the [issues page](https://github.com/killergerbah/asbplayer/issues).

## Getting Started

Expand All @@ -86,7 +95,7 @@ First, see if you can get started by following one of the [community guides](#co

Otherwise, the following steps for setting up automated Anki flashcards should work for any language:

1. Install and set up a dictionary tool for your target language that allows you to do instant lookups. Popular ones are [Yomitan](https://chromewebstore.google.com/detail/yomitan/likgccmbimhjbgkjambclfkhldnlhbnn) for Japanese and [VocabSieve](https://github.com/FreeLanguageTools/vocabsieve) for European languages.
1. Install and set up a dictionary tool for your target language that allows you to do instant lookups. Popular ones are [Yomitan](https://chromewebstore.google.com/detail/yomitan/likgccmbimhjbgkjambclfkhldnlhbnn) (see [supported languages](https://yomitan.wiki/other/supported-languages/)) and [VocabSieve](https://github.com/FreeLanguageTools/vocabsieve) (tuned for European languages. Works with Asian languages too but doesn't automatically detect word boundaries).
2. Install [Anki](https://apps.ankiweb.net/), and create a deck and note type. More details on [Refold's guide](https://refold.la/roadmap/stage-1/a/anki-setup).
3. Install the [AnkiConnect](https://ankiweb.net/shared/info/2055492159) plugin for Anki.
4. [Configure](https://killergerbah.github.io/asbplayer/?view=settings) asbplayer to create cards via AnkiConnect using your deck and note type.
Expand Down Expand Up @@ -158,7 +167,7 @@ Use <kbd>Ctrl + Shift + F</kbd> to see auto-detected subtitle tracks for streami

- Netflix
- Youtube
- Disney Plus (known issue: subtitles sometimes off by ~5 seconds)
- Disney Plus (known issues: flakey video detection, subtitles sometimes off by ~5 seconds)
- Hulu
- TVer
- Bandai Channel
Expand All @@ -179,8 +188,14 @@ You can replace filtered content similarly by entering a string into the "Subtit

Useful examples of regular expressions:

- `([((]([^()()]|(([((][^()()]+[))])))+[))])` : Remove names enclosed by parenthesis to indicate speakers (i.e. "**(山田)** 元気ですか?")
- `\[.*\]` : Remove indications enclosed by brackets that sound or music that is playing (i.e. "**\[PLAYFUL MUSIC]**")
- `([((]([^()()]|(([((][^()()]+[))])))+[))])` : Remove names enclosed by parenthesis to indicate speakers (e.g. "**(山田)** 元気ですか?")
- `(.*)\n+(?!-)(.*)` : Some subtitles are split in several lines and this regex forces them into a single line. For this filter to work, you must also put `$1 $2` in the "Subtitle regex filter text replacement" field.
- **NB**: When using this regex pattern in combination with other patterns (using the `|` operator, see below), place this pattern at the end. This ensures that all other regex transformations are applied first, and then the results are finally combined into a single line.
- `-?\[.*\]` : Remove indications enclosed by square brackets that sound or music that is playing (e.g. "**\[PLAYFUL MUSIC]**" or "**\-[GASPS]**")
- `^[-\(\)\.\sA-ZAÂÃÀÇÉÊÍÓÔÕÚÑ]+$` : As an alternative to the above, filter out descriptions written in capital letters, but without the square brackets (e.g. "**PLAYFUL MUSIC**"). If your language has additional letters with diacritics, you feel free to add them to this list.
- `[♪♬#~〜]+` : Any combination of symbols on their own that represent playing music (e.g. `♪♬♪`)

Regular expressions can be combined with the character `|` (no spaces needed inbetween). E.g., if you want to use the 2 last regexes from this list, you can use `-?\[.*\]|[♪♬#~〜]+`. You can combine as many regexes as you wish this way.

Learn how to write and test custom regular expressions at [Regex Learn - Playground](https://regexlearn.com/playground).

Expand Down Expand Up @@ -248,6 +263,8 @@ asbplayer can be setup to support one-click mining workflows by integrating with
5. Configure Yomitan to use the same note type you have configured for asbplayer.
6. Using Yomitan's `+` button on asbplayer subtitles will now trigger the flashcard creator with word and definition fields pre-populated by Yomitan.

The proxy is very lightweight, so it's fine to leave it running in the background. On Windows, [RBTray](https://github.com/benbuck/rbtray) can be used to minimise it to the taskbar.

See the proxy's [example configuration file](https://github.com/killergerbah/asbplayer/blob/main/scripts/anki-connect-proxy/.env.example) for how to further configure it.

#### WebSocket interface
Expand Down
20 changes: 10 additions & 10 deletions client/public/extension.json
Original file line number Diff line number Diff line change
@@ -1,48 +1,48 @@
{
"latest": {
"version": "1.2.0",
"url": "https://github.com/killergerbah/asbplayer/releases/tag/v1.2.0"
"version": "1.3.2",
"url": "https://github.com/killergerbah/asbplayer/releases/tag/v1.3.2"
},
"languages": [
{
"code": "en",
"url": "/locales/en.json",
"version": 5
"version": 6
},
{
"code": "es",
"url": "/locales/es.json",
"version": 4
"version": 5
},
{
"code": "ja",
"url": "/locales/ja.json",
"version": 7
"version": 9
},
{
"code": "de",
"url": "/locales/de.json",
"version": 5
"version": 6
},
{
"code": "pl",
"url": "/locales/pl.json",
"version": 5
"version": 6
},
{
"code": "pt_BR",
"url": "/locales/pt_BR.json",
"version": 4
"version": 5
},
{
"code": "zh_CN",
"url": "/locales/zh_CN.json",
"version": 4
"version": 5
},
{
"code": "ru",
"url": "/locales/ru.json",
"version": 3
"version": 4
}
]
}
8 changes: 8 additions & 0 deletions client/public/firefox-extension-updates.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
{
"version": "1.3.1",
"update_link": "https://github.com/killergerbah/asbplayer/releases/download/v1.3.1/asbplayer-extension-1.3.1-firefox.xpi"
},
{
"version": "1.3.2",
"update_link": "https://github.com/killergerbah/asbplayer/releases/download/v1.3.2/asbplayer-extension-1.3.2-firefox.xpi"
},
{
"version": "1.4.2",
"update_link": "https://github.com/killergerbah/asbplayer/releases/download/v1.4.2/asbplayer-extension-1.4.2-firefox.xpi"
}
]
}
Expand Down
43 changes: 31 additions & 12 deletions common/anki/anki.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { AudioClip } from '@project/common/audio-clip';
import { CardModel, Image } from '@project/common';
import { HttpFetcher, Fetcher } from '@project/common';
import { AnkiSettings } from '@project/common/settings';
import { AnkiSettings, AnkiSettingsFieldKey } from '@project/common/settings';
import sanitize from 'sanitize-filename';
import { extractText, sourceString } from '@project/common/util';

declare global {
interface String {
toWellFormed?: () => string;
}
}

const ankiQuerySpecialCharacters = ['"', '*', '_', '\\', ':'];
const alphaNumericCharacters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

Expand Down Expand Up @@ -325,17 +331,10 @@ export class Anki {
if (infoResponse.result.length > 0 && infoResponse.result[0].noteId === lastNoteId) {
const info = infoResponse.result[0];

if (
this.settingsProvider.sentenceField &&
info.fields &&
typeof info.fields[this.settingsProvider.sentenceField]?.value === 'string' &&
typeof params.note.fields[this.settingsProvider.sentenceField] === 'string'
) {
params.note.fields[this.settingsProvider.sentenceField] = inheritHtmlMarkup(
params.note.fields[this.settingsProvider.sentenceField],
info.fields[this.settingsProvider.sentenceField].value
);
}
this._inheritHtmlMarkupFromField('sentenceField', info, params);
this._inheritHtmlMarkupFromField('track1Field', info, params);
this._inheritHtmlMarkupFromField('track2Field', info, params);
this._inheritHtmlMarkupFromField('track3Field', info, params);

await this._executeAction('updateNoteFields', params, ankiConnectUrl);

Expand Down Expand Up @@ -384,6 +383,10 @@ export class Anki {
}

private _sanitizeFileName(name: string) {
if (typeof name.toWellFormed === 'function') {
name = name.toWellFormed();
}

return sanitize(name, { replacement: '_' });
}

Expand All @@ -395,6 +398,22 @@ export class Anki {
);
}

private _inheritHtmlMarkupFromField(fieldKey: AnkiSettingsFieldKey, info: any, params: any) {
const fieldName = this.settingsProvider[fieldKey];

if (
fieldName &&
info.fields &&
typeof info.fields[fieldName]?.value === 'string' &&
typeof params.note.fields[fieldName] === 'string'
) {
params.note.fields[fieldName] = inheritHtmlMarkup(
params.note.fields[fieldName],
info.fields[fieldName].value
);
}
}

private async _executeAction(action: string, params: any, ankiConnectUrl?: string) {
const body: any = {
action: action,
Expand Down
24 changes: 11 additions & 13 deletions common/app/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { createTheme } from '@project/common/theme';
import { AsbplayerSettings, Profile } from '@project/common/settings';
import { humanReadableTime, download, extractText } from '@project/common/util';
import { AudioClip } from '@project/common/audio-clip';
import { AnkiExportMode, ExportParams } from '@project/common/anki';
import { ExportParams } from '@project/common/anki';
import { SubtitleReader } from '@project/common/subtitle-reader';
import { v4 as uuidv4 } from 'uuid';
import clsx from 'clsx';
Expand Down Expand Up @@ -53,7 +53,7 @@ import { useAnki } from '../hooks/use-anki';
import { usePlaybackPreferences } from '../hooks/use-playback-preferences';
import { MiningContext } from '../services/mining-context';

const latestExtensionVersion = '1.2.0';
const latestExtensionVersion = '1.4.2';
const extensionUrl =
'https://chromewebstore.google.com/detail/asbplayer-language-learni/hkledmpjpaehamkiehglnbelcpdflcab';
const mp3WorkerFactory = () => new Worker(new URL('../../audio-clip/mp3-encoder-worker.ts', import.meta.url));
Expand Down Expand Up @@ -228,9 +228,13 @@ function App({ origin, logoUrl, settings, extension, fetcher, onSettingsChanged,
const drawerRatio = videoFrameRef.current ? 0.2 : 0.3;
const minDrawerSize = videoFrameRef.current ? 150 : 300;
const drawerWidth = Math.max(minDrawerSize, width * drawerRatio);
const { copyHistoryItems, refreshCopyHistory, deleteCopyHistoryItem, saveCopyHistoryItem } = useCopyHistory(
settings.miningHistoryStorageLimit
);
const {
copyHistoryItems,
refreshCopyHistory,
deleteCopyHistoryItem,
saveCopyHistoryItem,
deleteAllCopyHistoryItems,
} = useCopyHistory(settings.miningHistoryStorageLimit);
const copyHistoryItemsRef = useRef<CopyHistoryItem[]>([]);
copyHistoryItemsRef.current = copyHistoryItems;
const [copyHistoryOpen, setCopyHistoryOpen] = useState<boolean>(false);
Expand Down Expand Up @@ -518,13 +522,6 @@ function App({ origin, logoUrl, settings, extension, fetcher, onSettingsChanged,
setDisableKeyEvents(ankiDialogOpen);
}, [ankiDialogOpen]);

const handleDeleteCopyHistoryItem = useCallback(
(item: CopyHistoryItem) => {
deleteCopyHistoryItem(item);
},
[deleteCopyHistoryItem]
);

const handleUnloadVideo = useCallback(
(videoFileUrl: string) => {
if (videoFileUrl !== sources.videoFileUrl) {
Expand Down Expand Up @@ -1179,7 +1176,8 @@ function App({ origin, logoUrl, settings, extension, fetcher, onSettingsChanged,
open={effectiveCopyHistoryOpen}
drawerWidth={drawerWidth}
onClose={handleCloseCopyHistory}
onDelete={handleDeleteCopyHistoryItem}
onDelete={deleteCopyHistoryItem}
onDeleteAll={deleteAllCopyHistoryItems}
onClipAudio={handleClipAudio}
onDownloadImage={handleDownloadImage}
onDownloadSectionAsSrt={handleDownloadCopyHistorySectionAsSrt}
Expand Down
1 change: 1 addition & 0 deletions common/app/components/CopyHistory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ interface CopyHistoryProps {
forceShowDownloadOptions?: boolean;
onClose: () => void;
onDelete: (item: CopyHistoryItem) => void;
onDeleteAll: () => void;
onAnki: (item: CopyHistoryItem) => void;
onSelect?: (item: CopyHistoryItem) => void;
onClipAudio: (item: CopyHistoryItem) => void;
Expand Down
24 changes: 22 additions & 2 deletions common/app/components/CopyHistoryList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { makeStyles } from '@material-ui/core/styles';
import { timeDurationDisplay } from '../services/util';
import Button from '@material-ui/core/Button';
import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
import Grid from '@material-ui/core/Grid';
import IconButton from '@material-ui/core/IconButton';
Expand All @@ -10,6 +11,7 @@ import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import Popover from '@material-ui/core/Popover';
import DeleteIcon from '@material-ui/icons/Delete';
import MoreVertIcon from '@material-ui/icons/MoreVert';
import NoteAddIcon from '@material-ui/icons/NoteAdd';
import SaveAltIcon from '@material-ui/icons/SaveAlt';
Expand All @@ -25,6 +27,7 @@ interface CopyHistoryListProps {
items: CopyHistoryItem[];
onClose: () => void;
onDelete: (item: CopyHistoryItem) => void;
onDeleteAll: () => void;
onAnki: (item: CopyHistoryItem) => void;
onSelect?: (item: CopyHistoryItem) => void;
onClipAudio: (item: CopyHistoryItem) => void;
Expand All @@ -34,11 +37,18 @@ interface CopyHistoryListProps {

const useStyles = makeStyles((theme) => ({
listContainer: {
position: 'relative',
display: 'flex',
height: '100%',
flexDirection: 'column',
overflowY: 'auto',
overflowX: 'hidden',
},
list: {
flexGrow: 1,
},
clearButton: {
margin: theme.spacing(2),
},
listItem: {
'&:hover': {
backgroundColor: theme.palette.action.hover,
Expand Down Expand Up @@ -217,6 +227,7 @@ export default function CopyHistoryList({
onClipAudio,
onDownloadImage,
onDelete,
onDeleteAll,
onDownloadSectionAsSrt,
onAnki,
}: CopyHistoryListProps) {
Expand Down Expand Up @@ -336,7 +347,16 @@ export default function CopyHistoryList({

content = (
<div className={classes.listContainer}>
<List>{elements}</List>
<List className={classes.list}>{elements}</List>
<Button
variant="contained"
color="secondary"
className={classes.clearButton}
startIcon={<DeleteIcon />}
onClick={onDeleteAll}
>
{t('copyHistory.deleteAll')}
</Button>
</div>
);
} else {
Expand Down
2 changes: 2 additions & 0 deletions common/app/components/SettingsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ export default function SettingsDialog({
extensionSupportsSidePanel={extension.supportsSidePanel}
extensionSupportsOrderableAnkiFields={extension.supportsOrderableAnkiFields}
extensionSupportsTrackSpecificSettings={extension.supportsTrackSpecificSettings}
extensionSupportsSubtitlesWidthSetting={extension.supportsSubtitlesWidthSetting}
extensionSupportsPauseOnHover={extension.supportsPauseOnHover}
insideApp
chromeKeyBinds={extension.extensionCommands}
onOpenChromeExtensionShortcuts={extension.openShortcuts}
Expand Down
Loading
Loading