Skip to content

Commit

Permalink
UI notification when post mine action is 'none'
Browse files Browse the repository at this point in the history
  • Loading branch information
killergerbah committed Nov 10, 2023
1 parent e945cae commit 32cc2f9
Show file tree
Hide file tree
Showing 13 changed files with 240 additions and 302 deletions.
2 changes: 1 addition & 1 deletion common/app/src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ function App({ origin, logoUrl, settings, extension, fetcher, onSettingsChanged
id,
subtitle,
surroundingSubtitles,
subtitleFileName: subtitleFile?.name,
subtitleFileName: subtitleFile?.name ?? videoFile?.name ?? '',
url,
image,
audio,
Expand Down
18 changes: 15 additions & 3 deletions common/app/src/components/VideoPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,13 @@ export default function VideoPlayer({
switch (postMineAction) {
case PostMineAction.showAnkiDialog:
if (popOut) {
playerChannel.copy(subtitle, surroundingSubtitles, timestamp, PostMineAction.none);
playerChannel.copy(
subtitle,
surroundingSubtitles,
videoFileName ?? '',
timestamp,
PostMineAction.none
);
onAnkiDialogRequest(
videoFileUrl,
videoFileName ?? '',
Expand All @@ -852,11 +858,17 @@ export default function VideoPlayer({
setResumeOnFinishedAnkiDialogRequest(true);
}
} else {
playerChannel.copy(subtitle, surroundingSubtitles, timestamp, PostMineAction.showAnkiDialog);
playerChannel.copy(
subtitle,
surroundingSubtitles,
videoFileName ?? '',
timestamp,
PostMineAction.showAnkiDialog
);
}
break;
default:
playerChannel.copy(subtitle, surroundingSubtitles, timestamp, postMineAction);
playerChannel.copy(subtitle, surroundingSubtitles, videoFileName ?? '', timestamp, postMineAction);
}

setLastMinedRecord({
Expand Down
17 changes: 11 additions & 6 deletions common/app/src/services/player-channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default class PlayerChannel {
private currentTimeCallbacks: ((currentTime: number) => void)[];
private audioTrackSelectedCallbacks: ((id: string) => void)[];
private closeCallbacks: (() => void)[];
private subtitlesCallbacks: ((subtitles: SubtitleModel[]) => void)[];
private subtitlesCallbacks: ((subtitles: SubtitleModel[], subtitleFileName: string) => void)[];
private offsetCallbacks: ((offset: number) => void)[];
private playbackRateCallbacks: ((playbackRate: number) => void)[];
private playModeCallbacks: ((playMode: PlayMode) => void)[];
Expand Down Expand Up @@ -125,7 +125,10 @@ export default class PlayerChannel {
const subtitlesMessage = event.data as SubtitlesToVideoMessage;

for (let callback of that.subtitlesCallbacks) {
callback(subtitlesMessage.value);
callback(
subtitlesMessage.value,
subtitlesMessage.names.length > 0 ? subtitlesMessage.names[0] : ''
);
}
break;
case 'offset':
Expand Down Expand Up @@ -245,7 +248,7 @@ export default class PlayerChannel {
return () => this._remove(callback, this.readyCallbacks);
}

onSubtitles(callback: (subtitles: SubtitleModel[]) => void) {
onSubtitles(callback: (subtitles: SubtitleModel[], subtitleFileName: string) => void) {
this.subtitlesCallbacks.push(callback);
return () => this._remove(callback, this.subtitlesCallbacks);
}
Expand Down Expand Up @@ -368,14 +371,16 @@ export default class PlayerChannel {
copy(
subtitle: SubtitleModel,
surroundingSubtitles: SubtitleModel[],
subtitleFileName: string,
mediaTimestamp: number,
postMineAction: PostMineAction
) {
const message: CopyMessage = {
command: 'copy',
subtitle: subtitle,
surroundingSubtitles: surroundingSubtitles,
postMineAction: postMineAction,
subtitle,
surroundingSubtitles,
subtitleFileName,
postMineAction,
mediaTimestamp,
};

Expand Down
12 changes: 7 additions & 5 deletions common/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ export interface RecordMediaAndForwardSubtitleMessage extends Message, ImageCapt
readonly audioPaddingEnd: number;
readonly imageDelay: number;
readonly playbackRate: number;
readonly ankiSettings?: AnkiSettings;
readonly mediaTimestamp: number;
}

Expand All @@ -114,7 +113,6 @@ export interface StartRecordingMediaMessage extends Message, ImageCaptureParams
readonly imageDelay: number;
readonly url?: string;
readonly subtitleFileName: string;
readonly ankiSettings?: AnkiSettings;
}

export interface StopRecordingMediaMessage extends Message, ImageCaptureParams {
Expand All @@ -127,7 +125,6 @@ export interface StopRecordingMediaMessage extends Message, ImageCaptureParams {
readonly videoDuration: number;
readonly url?: string;
readonly subtitleFileName: string;
readonly ankiSettings?: AnkiSettings;
readonly subtitle?: SubtitleModel;
readonly surroundingSubtitles?: SubtitleModel[];
}
Expand All @@ -136,7 +133,7 @@ export interface Card {
readonly id?: string;
readonly subtitle: SubtitleModel;
readonly surroundingSubtitles: SubtitleModel[];
readonly subtitleFileName?: string;
readonly subtitleFileName: string;
readonly url?: string;
readonly image?: ImageModel;
readonly audio?: AudioModel;
Expand Down Expand Up @@ -173,7 +170,7 @@ export interface TakeScreenshotMessage extends Message {
export interface TakeScreenshotFromExtensionMessage extends Message, ImageCaptureParams {
readonly command: 'take-screenshot';
readonly ankiUiState?: AnkiUiSavedState;
readonly subtitleFileName?: string;
readonly subtitleFileName: string;
readonly mediaTimestamp: number;
}

Expand All @@ -191,6 +188,11 @@ export interface CardUpdatedMessage extends Message {
readonly url?: string;
}

export interface CardSavedMessage extends Message {
readonly command: 'card-saved';
readonly text: string;
}

export interface ScreenshotTakenMessage extends Message {
readonly command: 'screenshot-taken';
readonly ankiUiState?: AnkiUiSavedState;
Expand Down
36 changes: 19 additions & 17 deletions extension/src/background-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,25 +74,27 @@ window.onload = async () => {
break;
case 'copy':
const copyMessage = request.message as CopyMessage;
settings.getSingle('miningHistoryStorageLimit').then((storageLimit) => {
return new CopyHistoryRepository(storageLimit).save({
...copyMessage.subtitle,
id: copyMessage.id ?? uuidv4(),
timestamp: Date.now(),
name:
copyMessage.subtitleFileName?.substring(
settings
.getSingle('miningHistoryStorageLimit')
.then((storageLimit) => {
return new CopyHistoryRepository(storageLimit).save({
...copyMessage.subtitle,
id: copyMessage.id ?? uuidv4(),
timestamp: Date.now(),
name: copyMessage.subtitleFileName.substring(
0,
copyMessage.subtitleFileName.lastIndexOf('.')
) ?? '',
subtitleFileName: copyMessage.subtitleFileName ?? '',
mediaTimestamp: copyMessage.mediaTimestamp,
surroundingSubtitles: copyMessage.surroundingSubtitles,
url: copyMessage.url,
audio: copyMessage.audio,
image: copyMessage.image,
});
});
break;
),
subtitleFileName: copyMessage.subtitleFileName,
mediaTimestamp: copyMessage.mediaTimestamp,
surroundingSubtitles: copyMessage.surroundingSubtitles,
url: copyMessage.url,
audio: copyMessage.audio,
image: copyMessage.image,
});
})
.then(() => sendResponse(true));
return true;
}
}
};
Expand Down
6 changes: 3 additions & 3 deletions extension/src/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ chrome.runtime.onStartup.addListener(startListener);
const tabRegistry = new TabRegistry(settings);
const backgroundPageManager = new BackgroundPageManager(tabRegistry);
const imageCapturer = new ImageCapturer(settings);
const cardPublisher = new CardPublisher(backgroundPageManager);
const cardPublisher = new CardPublisher(backgroundPageManager, settings);

const handlers: CommandHandler[] = [
new VideoHeartbeatHandler(tabRegistry),
new RecordMediaHandler(backgroundPageManager, imageCapturer, cardPublisher),
new RecordMediaHandler(backgroundPageManager, imageCapturer, cardPublisher, settings),
new RerecordMediaHandler(backgroundPageManager, cardPublisher),
new StartRecordingMediaHandler(backgroundPageManager, imageCapturer, cardPublisher),
new StopRecordingMediaHandler(backgroundPageManager, imageCapturer, cardPublisher),
new StopRecordingMediaHandler(backgroundPageManager, imageCapturer, cardPublisher, settings),
new TakeScreenshotHandler(imageCapturer, cardPublisher),
new ToggleSubtitlesHandler(settings, tabRegistry),
new SyncHandler(tabRegistry),
Expand Down
91 changes: 17 additions & 74 deletions extension/src/handlers/video/record-media-handler.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
import ImageCapturer from '../../services/image-capturer';
import { v4 as uuidv4 } from 'uuid';
import {
AudioModel,
Command,
CopyMessage,
ImageModel,
Message,
RecordMediaAndForwardSubtitleMessage,
VideoToExtensionCommand,
ExtensionToVideoCommand,
ShowAnkiUiMessage,
ScreenshotTakenMessage,
PostMineAction,
CardUpdatedMessage,
RecordingFinishedMessage,
updateLastCard,
sourceString,
Card,
SettingsProvider,
} from '@project/common';
import BackgroundPageManager from '../../services/background-page-manager';
import { CardPublisher } from '../../services/card-publisher';
Expand All @@ -24,15 +19,18 @@ export default class RecordMediaHandler {
private readonly _audioRecorder: BackgroundPageManager;
private readonly _imageCapturer: ImageCapturer;
private readonly _cardPublisher: CardPublisher;
private readonly _settingsProvider: SettingsProvider;

constructor(
audioRecorder: BackgroundPageManager,
imageCapturer: ImageCapturer,
cardPublisher: CardPublisher
cardPublisher: CardPublisher,
settingsProvider: SettingsProvider
) {
this._audioRecorder = audioRecorder;
this._imageCapturer = imageCapturer;
this._cardPublisher = cardPublisher;
this._settingsProvider = settingsProvider;
}

get sender() {
Expand All @@ -48,19 +46,18 @@ export default class RecordMediaHandler {
const recordMediaCommand = command as VideoToExtensionCommand<RecordMediaAndForwardSubtitleMessage>;

try {
const itemId = uuidv4();
const subtitle = recordMediaCommand.message.subtitle;
let audioPromise = undefined;
let imagePromise = undefined;
let imageModel: ImageModel | undefined = undefined;
let audioModel: AudioModel | undefined = undefined;
const mp3 = recordMediaCommand.message.ankiSettings?.preferMp3 ?? false;
const preferMp3 = await this._settingsProvider.getSingle('preferMp3');

if (recordMediaCommand.message.record) {
const time =
(subtitle.end - subtitle.start) / recordMediaCommand.message.playbackRate +
recordMediaCommand.message.audioPaddingEnd;
audioPromise = this._audioRecorder.startWithTimeout(time, mp3, {
audioPromise = this._audioRecorder.startWithTimeout(time, preferMp3, {
src: recordMediaCommand.src,
tabId: sender.tab?.id,
});
Expand Down Expand Up @@ -94,7 +91,7 @@ export default class RecordMediaHandler {
const audioBase64 = await audioPromise;
audioModel = {
base64: audioBase64,
extension: mp3 ? 'mp3' : 'webm',
extension: preferMp3 ? 'mp3' : 'webm',
paddingStart: recordMediaCommand.message.audioPaddingStart,
paddingEnd: recordMediaCommand.message.audioPaddingEnd,
playbackRate: recordMediaCommand.message.playbackRate,
Expand All @@ -109,71 +106,17 @@ export default class RecordMediaHandler {
};
}

const message: CopyMessage = {
command: 'copy',
id: itemId,
url: recordMediaCommand.message.url,
subtitle: subtitle,
surroundingSubtitles: recordMediaCommand.message.surroundingSubtitles,
const card: Card = {
image: imageModel,
audio: audioModel,
subtitleFileName: recordMediaCommand.message.subtitleFileName,
mediaTimestamp: recordMediaCommand.message.mediaTimestamp,
...recordMediaCommand.message,
};
this._cardPublisher.publish(message);

if (recordMediaCommand.message.postMineAction == PostMineAction.showAnkiDialog) {
const showAnkiUiCommand: ExtensionToVideoCommand<ShowAnkiUiMessage> = {
sender: 'asbplayer-extension-to-video',
message: {
command: 'show-anki-ui',
id: itemId,
subtitle: message.subtitle,
surroundingSubtitles: message.surroundingSubtitles,
image: message.image,
audio: message.audio,
url: message.url,
subtitleFileName: recordMediaCommand.message.subtitleFileName,
mediaTimestamp: recordMediaCommand.message.mediaTimestamp,
},
src: recordMediaCommand.src,
};

chrome.tabs.sendMessage(senderTab.id!, showAnkiUiCommand);
} else if (recordMediaCommand.message.postMineAction == PostMineAction.updateLastCard) {
if (!recordMediaCommand.message.ankiSettings) {
throw new Error('Cannot update last card because anki settings is undefined');
}

const cardName = await updateLastCard(
recordMediaCommand.message.ankiSettings,
subtitle,
recordMediaCommand.message.surroundingSubtitles,
audioModel,
imageModel,
sourceString(
recordMediaCommand.message.subtitleFileName,
recordMediaCommand.message.mediaTimestamp
),
recordMediaCommand.message.url
);

const cardUpdatedCommand: ExtensionToVideoCommand<CardUpdatedMessage> = {
sender: 'asbplayer-extension-to-video',
message: {
command: 'card-updated',
cardName: `${cardName}`,
subtitle,
surroundingSubtitles: recordMediaCommand.message.surroundingSubtitles,
audio: audioModel,
image: imageModel,
url: recordMediaCommand.message.url,
},
src: recordMediaCommand.src,
};

chrome.tabs.sendMessage(senderTab.id!, cardUpdatedCommand);
}
this._cardPublisher.publish(
card,
recordMediaCommand.message.postMineAction,
senderTab.id!,
recordMediaCommand.src
);
} finally {
if (recordMediaCommand.message.record) {
const recordingFinishedCommand: ExtensionToVideoCommand<RecordingFinishedMessage> = {
Expand Down
Loading

0 comments on commit 32cc2f9

Please sign in to comment.