import _ from "lodash" ; const DEBUG = process . env . NODE_ENV === "development" ; const DISPLAY_DEBUG_TIME = false ; export const LIMIT_DELTA_TIME = 3 ; const googleGreen = "#009688" ; const googleAquaBlue = "#00BBD3" ; export const crunchyrollOrange = "#F78C25" ; export const chineseSilver = "#CCC" ; const defaultcolorOptions = [ googleGreen , googleAquaBlue , crunchyrollOrange , ] ; export type PlayerStateProp = "controls" | "currentTime" | "defaultMuted" | "defaultPlaybackRate" | "duration" | "ended" | "loop" | "muted" | "paused" | "playbackRate" | "volume" ; export enum Actions { PLAY = "play" , PAUSE = "pause" , READY = "ready" , ENDED = "ended" , TIME_UPDATE = "timeupdate" } export enum States { PLAYING = "playing" , PAUSED = "paused" } export enum BackgroundMessageTypes { REMOTE_UPDATE = "remote_update" , ROOM_CONNECTION = "room_connection" , SKIP_MARKS = "skip_marks" } export interface Marks { animeName : string ; begin : number ; end : number ; episode : number ; id : number ; } export type BackgroundMessage = RemoteUpdateBackgroundMessage | RoomConnectionBackgroundMessage | SkipMarksBackgroundMessage ; interface BackgroundMessageBase { type : BackgroundMessageTypes ; } export interface RemoteUpdateBackgroundMessage extends BackgroundMessageBase { type : BackgroundMessageTypes . REMOTE_UPDATE ; roomState : States ; roomProgress : number ; } export interface RoomConnectionBackgroundMessage extends BackgroundMessageBase { type : BackgroundMessageTypes . ROOM_CONNECTION ; } export interface SkipMarksBackgroundMessage extends BackgroundMessageBase { type : BackgroundMessageTypes . SKIP_MARKS ; marks : Marks ; } export enum WebpageMessageTypes { LOCAL_UPDATE = "local_update" , ROOM_CONNECTION = "room_connection" , CONNECTION = "connection" } export function log ( ... args ) { const date = DISPLAY_DEBUG_TIME ? [ new Date ( ) . toJSON ( ) ] : [ ] ; DEBUG && console . log ( ... date , ... args ) ; return ; } export function getParameterByName ( url , name = "rollTogetherRoom" ) { const queryString = /\?[^#]+(?=#|$)|$/ . exec ( url ) ! [ 0 ] ; const regex = new RegExp ( "(?:[?&]|^)" + name + "=([^&#]*)" ) ; const results = regex . exec ( queryString ) ; if ( _ . isNull ( results ) || results . length < 2 ) { return null ; } return decodeURIComponent ( results [ 1 ] . replace ( /\+/g , " " ) ) ; } export function updateQueryStringParameter ( uri , key , value ) { const re = new RegExp ( "([?&])" + key + "=.*?(&|$)" , "i" ) ; const separator = uri . indexOf ( "?" ) !== - 1 ? "&" : "?" ; if ( uri . match ( re ) ) { return uri . replace ( re , "$1" + key + "=" + value + "$2" ) ; } else { return uri + separator + key + "=" + value ; } } interface StorageData { extensionColor ? : string ; colorOptions ? : string [ ] ; isIntroFeatureActive ? : boolean ; } export function getExtensionColor ( ) { return new Promise ( ( resolve ) => { chrome . storage . sync . get ( { extensionColor : crunchyrollOrange } , function ( data ) { resolve ( data . extensionColor as string ) ; } ) ; } ) ; } export function getColorMenu ( ) { return new Promise ( ( resolve ) => { chrome . storage . sync . get ( { colorOptions : defaultcolorOptions } , function ( data ) { resolve ( data . colorOptions as string [ ] ) ; } ) ; } ) ; } export function getIntroFeatureState ( ) { return new Promise ( ( resolve ) => { chrome . storage . sync . get ( { isIntroFeatureActive : false } , function ( data ) { resolve ( data . isIntroFeatureActive as boolean ) ; } ) ; } ) ; } param obj returns export function getEnumKeys < O extends object , K extends keyof O = keyof O > ( obj ) { return Object . keys ( obj ) . filter ( k => Number . isNaN ( + k ) ) as K [ ] ; } export function getBackgroundWindow ( ) { return chrome . extension . getBackgroundPage ( ) ?. window as BackgroundWindow ; } type GlobalWindow = Window & typeof globalThis ; export type BackgroundWindow = GlobalWindow & BackgroundWindowOverrides ; interface BackgroundWindowOverrides { RollTogetherBackground : RollTogetherBackground ; RollTogetherPopup : RollTogetherPopup ; } export interface RollTogetherBackground { getRoomId : ( tabId : number ) => string | undefined ; createRoom : ( tab : chrome . tabs . Tab ) => void ; disconnectRoom : ( tabId : number ) => void ; } export interface RollTogetherPopup { update ? : ( ) => void ; }