run pre-commit on all

This commit is contained in:
Simon
2025-01-06 21:08:51 +07:00
parent cf54f6d7fc
commit bc74bf80f4
58 changed files with 8962 additions and 8942 deletions

View File

@@ -1,226 +1,226 @@
import { useCallback, useEffect, useState } from 'react';
import { VideoType } from '../pages/Home';
import updateWatchedState from '../api/actions/updateWatchedState';
import updateVideoProgressById from '../api/actions/updateVideoProgressById';
import watchedThreshold from '../functions/watchedThreshold';
const getURL = () => {
return window.location.origin;
};
function shiftCurrentTime(contentCurrentTime: number | undefined) {
console.log(contentCurrentTime);
if (contentCurrentTime === undefined) {
return 0;
}
// Shift media back 3 seconds to prevent missing some of the content
if (contentCurrentTime > 5) {
return contentCurrentTime - 3;
} else {
return 0;
}
}
async function castVideoProgress(
player: {
mediaInfo: { contentId: string | string[] };
currentTime: number;
duration: number;
},
video: VideoType | undefined,
) {
if (!video) {
console.log('castVideoProgress: Video to cast not found...');
return;
}
const videoId = video.youtube_id;
if (player.mediaInfo.contentId.includes(videoId)) {
const currentTime = player.currentTime;
const duration = player.duration;
if (currentTime % 10 <= 1.0 && currentTime !== 0 && duration !== 0) {
// Check progress every 10 seconds or else progress is checked a few times a second
await updateVideoProgressById({
youtubeId: videoId,
currentProgress: currentTime,
});
if (!video.player.watched) {
// Check if video is already marked as watched
if (watchedThreshold(currentTime, duration)) {
await updateWatchedState({
id: videoId,
is_watched: true,
});
}
}
}
}
}
async function castVideoPaused(
player: {
currentTime: number;
duration: number;
mediaInfo: { contentId: string | string[] } | null;
},
video: VideoType | undefined,
) {
if (!video) {
console.log('castVideoPaused: Video to cast not found...');
return;
}
const videoId = video?.youtube_id;
const currentTime = player.currentTime;
const duration = player.duration;
if (player.mediaInfo != null) {
if (player.mediaInfo.contentId.includes(videoId)) {
if (currentTime !== 0 && duration !== 0) {
await updateVideoProgressById({
youtubeId: videoId,
currentProgress: currentTime,
});
}
}
}
}
type GoogleCastProps = {
video?: VideoType;
setRefresh?: () => void;
};
const GoogleCast = ({ video, setRefresh }: GoogleCastProps) => {
const [isConnected, setIsConnected] = useState(false);
const setup = useCallback(() => {
const cast = globalThis.cast;
const chrome = globalThis.chrome;
cast.framework.CastContext.getInstance().setOptions({
receiverApplicationId: chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID, // Use built in receiver app on cast device, see https://developers.google.com/cast/docs/styled_receiver if you want to be able to add a theme, splash screen or watermark. Has a $5 one time fee.
autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED,
});
const player = new cast.framework.RemotePlayer();
const playerController = new cast.framework.RemotePlayerController(player);
// Add event listerner to check if a connection to a cast device is initiated
playerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED,
function () {
setIsConnected(player.isConnected);
},
);
playerController.addEventListener(
cast.framework.RemotePlayerEventType.CURRENT_TIME_CHANGED,
function () {
castVideoProgress(player, video);
},
);
playerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_PAUSED_CHANGED,
function () {
castVideoPaused(player, video);
setRefresh?.();
},
);
}, [setRefresh, video]);
const startPlayback = useCallback(() => {
const chrome = globalThis.chrome;
const cast = globalThis.cast;
const castSession = cast.framework.CastContext.getInstance().getCurrentSession();
const mediaUrl = video?.media_url;
const vidThumbUrl = video?.vid_thumb_url;
const contentTitle = video?.title;
const contentId = `${getURL()}${mediaUrl}`;
const contentImage = `${getURL()}${vidThumbUrl}`;
const contentType = 'video/mp4'; // Set content type, only videos right now so it is hard coded
const contentSubtitles = [];
const videoSubtitles = video?.subtitles; // Array of subtitles
if (typeof videoSubtitles !== 'undefined') {
for (let i = 0; i < videoSubtitles.length; i++) {
const subtitle = new chrome.cast.media.Track(i, chrome.cast.media.TrackType.TEXT);
subtitle.trackContentId = videoSubtitles[i].media_url;
subtitle.trackContentType = 'text/vtt';
subtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
subtitle.name = videoSubtitles[i].name;
subtitle.language = videoSubtitles[i].lang;
subtitle.customData = null;
contentSubtitles.push(subtitle);
}
}
const mediaInfo = new chrome.cast.media.MediaInfo(contentId, contentType); // Create MediaInfo var that contains url and content type
// mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED; // Set type of stream, BUFFERED, LIVE, OTHER
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata(); // Create metadata var and add it to MediaInfo
mediaInfo.metadata.title = contentTitle?.replace('&amp;', '&'); // Set the video title
mediaInfo.metadata.images = [new chrome.cast.Image(contentImage)]; // Set the video thumbnail
// mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle();
mediaInfo.tracks = contentSubtitles;
const request = new chrome.cast.media.LoadRequest(mediaInfo); // Create request with the previously set MediaInfo.
// request.queueData = new chrome.cast.media.QueueData(); // See https://developers.google.com/cast/docs/reference/web_sender/chrome.cast.media.QueueData for playlist support.
request.currentTime = shiftCurrentTime(video?.player?.position); // Set video start position based on the browser video position
// request.activeTrackIds = contentActiveSubtitle; // Set active subtitle based on video player
castSession.loadMedia(request).then(
function () {
console.log('media loaded');
},
function (error: { code: string }) {
console.log('Error', error, 'Error code: ' + error.code);
},
); // Send request to cast device
// Do not add videoProgress?.position, this will cause loops!
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [video?.media_url, video?.subtitles, video?.title, video?.vid_thumb_url]);
useEffect(() => {
// @ts-expect-error __onGCastApiAvailable is the google cast window hook ( source: https://developers.google.com/cast/docs/web_sender/integrate )
window['__onGCastApiAvailable'] = function (isAvailable: boolean) {
if (isAvailable) {
setup();
}
};
}, [setup]);
useEffect(() => {
console.log('isConnected', isConnected);
if (isConnected) {
startPlayback();
}
}, [isConnected, startPlayback]);
if (!video) {
return <p>Video for cast not found...</p>;
}
return (
<>
<>
<script
type="text/javascript"
src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"
></script>
{/* @ts-expect-error React does not know what to do with the google-cast-launcher, but it works. */}
<google-cast-launcher id="castbutton"></google-cast-launcher>
</>
</>
);
};
export default GoogleCast;
import { useCallback, useEffect, useState } from 'react';
import { VideoType } from '../pages/Home';
import updateWatchedState from '../api/actions/updateWatchedState';
import updateVideoProgressById from '../api/actions/updateVideoProgressById';
import watchedThreshold from '../functions/watchedThreshold';
const getURL = () => {
return window.location.origin;
};
function shiftCurrentTime(contentCurrentTime: number | undefined) {
console.log(contentCurrentTime);
if (contentCurrentTime === undefined) {
return 0;
}
// Shift media back 3 seconds to prevent missing some of the content
if (contentCurrentTime > 5) {
return contentCurrentTime - 3;
} else {
return 0;
}
}
async function castVideoProgress(
player: {
mediaInfo: { contentId: string | string[] };
currentTime: number;
duration: number;
},
video: VideoType | undefined,
) {
if (!video) {
console.log('castVideoProgress: Video to cast not found...');
return;
}
const videoId = video.youtube_id;
if (player.mediaInfo.contentId.includes(videoId)) {
const currentTime = player.currentTime;
const duration = player.duration;
if (currentTime % 10 <= 1.0 && currentTime !== 0 && duration !== 0) {
// Check progress every 10 seconds or else progress is checked a few times a second
await updateVideoProgressById({
youtubeId: videoId,
currentProgress: currentTime,
});
if (!video.player.watched) {
// Check if video is already marked as watched
if (watchedThreshold(currentTime, duration)) {
await updateWatchedState({
id: videoId,
is_watched: true,
});
}
}
}
}
}
async function castVideoPaused(
player: {
currentTime: number;
duration: number;
mediaInfo: { contentId: string | string[] } | null;
},
video: VideoType | undefined,
) {
if (!video) {
console.log('castVideoPaused: Video to cast not found...');
return;
}
const videoId = video?.youtube_id;
const currentTime = player.currentTime;
const duration = player.duration;
if (player.mediaInfo != null) {
if (player.mediaInfo.contentId.includes(videoId)) {
if (currentTime !== 0 && duration !== 0) {
await updateVideoProgressById({
youtubeId: videoId,
currentProgress: currentTime,
});
}
}
}
}
type GoogleCastProps = {
video?: VideoType;
setRefresh?: () => void;
};
const GoogleCast = ({ video, setRefresh }: GoogleCastProps) => {
const [isConnected, setIsConnected] = useState(false);
const setup = useCallback(() => {
const cast = globalThis.cast;
const chrome = globalThis.chrome;
cast.framework.CastContext.getInstance().setOptions({
receiverApplicationId: chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID, // Use built in receiver app on cast device, see https://developers.google.com/cast/docs/styled_receiver if you want to be able to add a theme, splash screen or watermark. Has a $5 one time fee.
autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED,
});
const player = new cast.framework.RemotePlayer();
const playerController = new cast.framework.RemotePlayerController(player);
// Add event listerner to check if a connection to a cast device is initiated
playerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED,
function () {
setIsConnected(player.isConnected);
},
);
playerController.addEventListener(
cast.framework.RemotePlayerEventType.CURRENT_TIME_CHANGED,
function () {
castVideoProgress(player, video);
},
);
playerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_PAUSED_CHANGED,
function () {
castVideoPaused(player, video);
setRefresh?.();
},
);
}, [setRefresh, video]);
const startPlayback = useCallback(() => {
const chrome = globalThis.chrome;
const cast = globalThis.cast;
const castSession = cast.framework.CastContext.getInstance().getCurrentSession();
const mediaUrl = video?.media_url;
const vidThumbUrl = video?.vid_thumb_url;
const contentTitle = video?.title;
const contentId = `${getURL()}${mediaUrl}`;
const contentImage = `${getURL()}${vidThumbUrl}`;
const contentType = 'video/mp4'; // Set content type, only videos right now so it is hard coded
const contentSubtitles = [];
const videoSubtitles = video?.subtitles; // Array of subtitles
if (typeof videoSubtitles !== 'undefined') {
for (let i = 0; i < videoSubtitles.length; i++) {
const subtitle = new chrome.cast.media.Track(i, chrome.cast.media.TrackType.TEXT);
subtitle.trackContentId = videoSubtitles[i].media_url;
subtitle.trackContentType = 'text/vtt';
subtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
subtitle.name = videoSubtitles[i].name;
subtitle.language = videoSubtitles[i].lang;
subtitle.customData = null;
contentSubtitles.push(subtitle);
}
}
const mediaInfo = new chrome.cast.media.MediaInfo(contentId, contentType); // Create MediaInfo var that contains url and content type
// mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED; // Set type of stream, BUFFERED, LIVE, OTHER
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata(); // Create metadata var and add it to MediaInfo
mediaInfo.metadata.title = contentTitle?.replace('&amp;', '&'); // Set the video title
mediaInfo.metadata.images = [new chrome.cast.Image(contentImage)]; // Set the video thumbnail
// mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle();
mediaInfo.tracks = contentSubtitles;
const request = new chrome.cast.media.LoadRequest(mediaInfo); // Create request with the previously set MediaInfo.
// request.queueData = new chrome.cast.media.QueueData(); // See https://developers.google.com/cast/docs/reference/web_sender/chrome.cast.media.QueueData for playlist support.
request.currentTime = shiftCurrentTime(video?.player?.position); // Set video start position based on the browser video position
// request.activeTrackIds = contentActiveSubtitle; // Set active subtitle based on video player
castSession.loadMedia(request).then(
function () {
console.log('media loaded');
},
function (error: { code: string }) {
console.log('Error', error, 'Error code: ' + error.code);
},
); // Send request to cast device
// Do not add videoProgress?.position, this will cause loops!
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [video?.media_url, video?.subtitles, video?.title, video?.vid_thumb_url]);
useEffect(() => {
// @ts-expect-error __onGCastApiAvailable is the google cast window hook ( source: https://developers.google.com/cast/docs/web_sender/integrate )
window['__onGCastApiAvailable'] = function (isAvailable: boolean) {
if (isAvailable) {
setup();
}
};
}, [setup]);
useEffect(() => {
console.log('isConnected', isConnected);
if (isConnected) {
startPlayback();
}
}, [isConnected, startPlayback]);
if (!video) {
return <p>Video for cast not found...</p>;
}
return (
<>
<>
<script
type="text/javascript"
src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"
></script>
{/* @ts-expect-error React does not know what to do with the google-cast-launcher, but it works. */}
<google-cast-launcher id="castbutton"></google-cast-launcher>
</>
</>
);
};
export default GoogleCast;