Introduce "sources" util class
This commit is contained in:
@@ -31,6 +31,8 @@ import { translateExtensionLanguage } from '@/modules/extension/Extensions.utils
|
||||
import { AppRoutes } from '@/modules/core/AppRoute.constants.ts';
|
||||
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
||||
import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx';
|
||||
import { Sources } from '@/modules/source/services/Sources.ts';
|
||||
import { SourceIdInfo } from '@/modules/source/Source.types.ts';
|
||||
|
||||
type SourceLoadingState = { isLoading: boolean; hasResults: boolean; emptySearch: boolean };
|
||||
type SourceToLoadingStateMap = Map<string, SourceLoadingState>;
|
||||
@@ -62,8 +64,8 @@ const compareSourceByName = (
|
||||
};
|
||||
|
||||
const compareSourcesBySearchResult = (
|
||||
sourceA: Pick<SourceType, 'id'>,
|
||||
sourceB: Pick<SourceType, 'id'>,
|
||||
sourceA: SourceIdInfo,
|
||||
sourceB: SourceIdInfo,
|
||||
sourceToFetchedStateMap: SourceToLoadingStateMap,
|
||||
): -1 | 0 | 1 => {
|
||||
const isSourceAFetched = !sourceToFetchedStateMap.get(sourceA.id)?.isLoading;
|
||||
@@ -101,7 +103,7 @@ const SourceSearchPreview = React.memo(
|
||||
}: {
|
||||
source: Pick<SourceType, 'id' | 'displayName' | 'lang'>;
|
||||
onSearchRequestFinished: (
|
||||
source: Pick<SourceType, 'id'>,
|
||||
source: SourceIdInfo,
|
||||
isLoading: boolean,
|
||||
hasResults: boolean,
|
||||
emptySearch: boolean,
|
||||
@@ -217,7 +219,7 @@ export const SearchAll: React.FC = () => {
|
||||
|
||||
const sourcesSortedByName = useMemo(() => [...sources].sort(compareSourceByName), [sources]);
|
||||
const sourcesFilteredByLang = useMemo(
|
||||
() => sourcesSortedByName.filter((source) => shownLangs.includes(source.lang) || Number(source.id) === 0),
|
||||
() => sourcesSortedByName.filter((source) => shownLangs.includes(source.lang) || Sources.isLocalSource(source)),
|
||||
[sourcesSortedByName, shownLangs],
|
||||
);
|
||||
const sourcesFilteredByNsfw = useMemo(
|
||||
@@ -233,7 +235,7 @@ export const SearchAll: React.FC = () => {
|
||||
);
|
||||
|
||||
const updateSourceLoadingState = useCallback(
|
||||
({ id }: Pick<SourceType, 'id'>, isLoading: boolean, hasResults: boolean, emptySearch: boolean) => {
|
||||
({ id }: SourceIdInfo, isLoading: boolean, hasResults: boolean, emptySearch: boolean) => {
|
||||
setSourceToLoadingStateMap((currentMap) => {
|
||||
const mapCopy = new Map(currentMap);
|
||||
mapCopy.set(id, { isLoading, hasResults, emptySearch });
|
||||
|
||||
@@ -153,8 +153,7 @@ function getSourceName(source?: Pick<SourceType, 'id' | 'displayName'> | null):
|
||||
return translate('global.label.unknown');
|
||||
}
|
||||
|
||||
const isLocalSource = Number(source.id) === 0;
|
||||
if (isLocalSource) {
|
||||
if (Sources.isLocalSource(source)) {
|
||||
return translate('source.local_source.title');
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@ import { extractOriginalKey, getMetadataKey } from '@/modules/metadata/Metadata.
|
||||
import { MangaIdInfo } from '@/modules/manga/Manga.types.ts';
|
||||
import { ChapterIdInfo } from '@/modules/chapter/services/Chapters.ts';
|
||||
import { CategoryIdInfo } from '@/modules/category/Category.types.ts';
|
||||
import { SourceType } from '@/lib/graphql/generated/graphql.ts';
|
||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||
import { getMetadataDeleteFunction, getMetadataUpdateFunction } from '@/modules/metadata/services/MetadataUpdater.ts';
|
||||
import { SourceIdInfo } from '@/modules/source/Source.types.ts';
|
||||
|
||||
const getAppKeyPrefixForMigration = (migrationId: number): string => {
|
||||
const appKeyPrefix = METADATA_MIGRATIONS.slice(0, migrationId)
|
||||
@@ -269,7 +269,7 @@ const commitMigratedMetadata = (
|
||||
| (MangaIdInfo & MetadataHolder)
|
||||
| (ChapterIdInfo & MetadataHolder)
|
||||
| (CategoryIdInfo & MetadataHolder)
|
||||
| (Pick<SourceType, 'id'> & MetadataHolder)
|
||||
| (SourceIdInfo & MetadataHolder)
|
||||
| undefined,
|
||||
migratedMetadata: Metadata,
|
||||
useEffectFn: typeof useEffect = (fn: () => void) => fn(),
|
||||
@@ -334,7 +334,7 @@ export const applyMetadataMigrations = (
|
||||
| (MangaIdInfo & MetadataHolder)
|
||||
| (ChapterIdInfo & MetadataHolder)
|
||||
| (CategoryIdInfo & MetadataHolder)
|
||||
| (Pick<SourceType, 'id'> & MetadataHolder),
|
||||
| (SourceIdInfo & MetadataHolder),
|
||||
useEffectFn: typeof useEffect = (fn: () => void) => fn(),
|
||||
): Metadata | undefined => {
|
||||
const meta = { ...(metadataHolder?.meta ?? {}) };
|
||||
|
||||
@@ -19,9 +19,9 @@ import { MangaIdInfo } from '@/modules/manga/Manga.types.ts';
|
||||
|
||||
import { ChapterIdInfo } from '@/modules/chapter/services/Chapters.ts';
|
||||
import { CategoryIdInfo } from '@/modules/category/Category.types.ts';
|
||||
import { SourceType } from '@/lib/graphql/generated/graphql.ts';
|
||||
import { doesMetadataKeyExistIn, getMetadataKey } from '@/modules/metadata/Metadata.utils.ts';
|
||||
import { applyMetadataMigrations } from '@/modules/metadata/services/MetadataMigrations.ts';
|
||||
import { SourceIdInfo } from '@/modules/source/Source.types.ts';
|
||||
|
||||
const getMetadataValueFrom = <Key extends AppMetadataKeys, Value extends AllowedMetadataValueTypes>(
|
||||
metadata: Metadata | undefined,
|
||||
@@ -70,7 +70,7 @@ export function getMetadataFrom<METADATA extends Partial<Metadata<AppMetadataKey
|
||||
): METADATA;
|
||||
export function getMetadataFrom<METADATA extends Partial<Metadata<AppMetadataKeys, AllowedMetadataValueTypes>>>(
|
||||
type: 'source',
|
||||
metadataHolder: Pick<SourceType, 'id'> & MetadataHolder,
|
||||
metadataHolder: SourceIdInfo & MetadataHolder,
|
||||
metadataWithDefaultValues: METADATA,
|
||||
prefixes?: string[],
|
||||
useEffectFn?: typeof useEffect,
|
||||
@@ -82,7 +82,7 @@ export function getMetadataFrom<METADATA extends Partial<Metadata<AppMetadataKey
|
||||
| (MangaIdInfo & MetadataHolder)
|
||||
| (ChapterIdInfo & MetadataHolder)
|
||||
| (CategoryIdInfo & MetadataHolder)
|
||||
| (Pick<SourceType, 'id'> & MetadataHolder),
|
||||
| (SourceIdInfo & MetadataHolder),
|
||||
metadataWithDefaultValues: METADATA,
|
||||
prefixes?: string[],
|
||||
useEffectFn: typeof useEffect = (fn: () => void) => fn(),
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||
import { SourceType } from '@/lib/graphql/generated/graphql.ts';
|
||||
import { ChapterIdInfo } from '@/modules/chapter/services/Chapters.ts';
|
||||
import { CategoryIdInfo } from '@/modules/category/Category.types.ts';
|
||||
import {
|
||||
@@ -21,6 +20,7 @@ import {
|
||||
import { MangaIdInfo } from '@/modules/manga/Manga.types.ts';
|
||||
import { getMetadataKey } from '@/modules/metadata/Metadata.utils.ts';
|
||||
import { convertToGqlMeta } from '@/modules/metadata/services/MetadataConverter.ts';
|
||||
import { SourceIdInfo } from '@/modules/source/Source.types.ts';
|
||||
|
||||
const requestUpdateMetadataValue = async (
|
||||
metadataHolder: GqlMetaHolder,
|
||||
@@ -46,8 +46,7 @@ const requestUpdateMetadataValue = async (
|
||||
await requestManager.setMangaMeta((metadataHolder as MangaIdInfo).id, metadataKey, value).response;
|
||||
break;
|
||||
case 'source':
|
||||
await requestManager.setSourceMeta((metadataHolder as Pick<SourceType, 'id'>).id, metadataKey, value)
|
||||
.response;
|
||||
await requestManager.setSourceMeta((metadataHolder as SourceIdInfo).id, metadataKey, value).response;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`requestUpdateMetadataValue: unknown holderType "${holderType}"`);
|
||||
@@ -95,7 +94,7 @@ export const requestUpdateCategoryMetadata = async (
|
||||
): Promise<void[]> => requestUpdateMetadata(category, 'category', keysToValues, keyPrefixes, isMetadataKey);
|
||||
|
||||
export const requestUpdateSourceMetadata = async (
|
||||
source: Pick<SourceType, 'id'> & GqlMetaHolder,
|
||||
source: SourceIdInfo & GqlMetaHolder,
|
||||
keysToValue: MetadataKeyValuePair[],
|
||||
keyPrefixes?: string[],
|
||||
isMetadataKey?: boolean,
|
||||
@@ -108,7 +107,7 @@ export const getMetadataUpdateFunction = (
|
||||
| (MangaIdInfo & MetadataHolder)
|
||||
| (ChapterIdInfo & MetadataHolder)
|
||||
| (CategoryIdInfo & MetadataHolder)
|
||||
| (Pick<SourceType, 'id'> & MetadataHolder),
|
||||
| (SourceIdInfo & MetadataHolder),
|
||||
): ((keyValuePair: MetadataKeyValuePair[], keyPrefixes?: string[], isMetadataKey?: boolean) => Promise<void[]>) => {
|
||||
switch (type) {
|
||||
case 'global':
|
||||
@@ -135,7 +134,7 @@ export const getMetadataUpdateFunction = (
|
||||
return (...args) =>
|
||||
requestUpdateSourceMetadata(
|
||||
{
|
||||
id: (metadataHolder as Pick<SourceType, 'id'>).id,
|
||||
id: (metadataHolder as SourceIdInfo).id,
|
||||
meta: convertToGqlMeta(metadataHolder.meta),
|
||||
},
|
||||
...args,
|
||||
@@ -168,7 +167,7 @@ export const requestDeleteMetadataValue = async (
|
||||
await requestManager.deleteMangaMeta((metadataHolder as MangaIdInfo).id, metadataKey).response;
|
||||
break;
|
||||
case 'source':
|
||||
await requestManager.deleteSourceMeta((metadataHolder as Pick<SourceType, 'id'>).id, metadataKey).response;
|
||||
await requestManager.deleteSourceMeta((metadataHolder as SourceIdInfo).id, metadataKey).response;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`requestDeleteMetadataValue: unknown holderType "${holderType}"`);
|
||||
@@ -215,7 +214,7 @@ export const requestDeleteCategoryMetadata = async (
|
||||
): Promise<void[]> => requestDeleteMetadata(category, 'category', keys, keyPrefixes, isMetadataKey);
|
||||
|
||||
export const requestDeleteSourceMetadata = async (
|
||||
source: Pick<SourceType, 'id'> & GqlMetaHolder,
|
||||
source: SourceIdInfo & GqlMetaHolder,
|
||||
keys: AppMetadataKeys[],
|
||||
keyPrefixes?: string[],
|
||||
isMetadataKey?: boolean,
|
||||
@@ -228,7 +227,7 @@ export const getMetadataDeleteFunction = (
|
||||
| (MangaIdInfo & MetadataHolder)
|
||||
| (ChapterIdInfo & MetadataHolder)
|
||||
| (CategoryIdInfo & MetadataHolder)
|
||||
| (Pick<SourceType, 'id'> & MetadataHolder),
|
||||
| (SourceIdInfo & MetadataHolder),
|
||||
): ((metadataToDelete: AppMetadataKeys[], keyPrefixes?: string[], isMetadataKey?: boolean) => Promise<void[]>) => {
|
||||
switch (type) {
|
||||
case 'global':
|
||||
@@ -255,7 +254,7 @@ export const getMetadataDeleteFunction = (
|
||||
return (...args) =>
|
||||
requestDeleteSourceMetadata(
|
||||
{
|
||||
id: (metadataHolder as Pick<SourceType, 'id'>).id,
|
||||
id: (metadataHolder as SourceIdInfo).id,
|
||||
meta: convertToGqlMeta(metadataHolder.meta),
|
||||
},
|
||||
...args,
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
GetSourceBrowseQuery,
|
||||
GetSourceSettingsQuery,
|
||||
SourcePreferenceChangeInput,
|
||||
SourceType,
|
||||
} from '@/lib/graphql/generated/graphql.ts';
|
||||
|
||||
export interface IPos {
|
||||
@@ -57,3 +58,5 @@ export type MultiSelectListPreferenceProps = PreferenceProps &
|
||||
|
||||
export type EditTextPreferenceProps = PreferenceProps &
|
||||
ExtractByKeyValue<SourcePreferences, '__typename', 'EditTextPreference'>;
|
||||
|
||||
export type SourceIdInfo = Pick<SourceType, 'id'>;
|
||||
|
||||
@@ -36,21 +36,18 @@ export const SourceCard: React.FC<IProps> = (props: IProps) => {
|
||||
|
||||
const isMobileWidth = MediaQuery.useIsMobileWidth();
|
||||
|
||||
const { source, showSourceRepo } = props;
|
||||
const {
|
||||
source: {
|
||||
id,
|
||||
name,
|
||||
lang,
|
||||
iconUrl,
|
||||
supportsLatest,
|
||||
isNsfw,
|
||||
extension: { repo },
|
||||
},
|
||||
showSourceRepo,
|
||||
} = props;
|
||||
id,
|
||||
name,
|
||||
lang,
|
||||
iconUrl,
|
||||
supportsLatest,
|
||||
isNsfw,
|
||||
extension: { repo },
|
||||
} = source;
|
||||
|
||||
const isLocalSource = Number(id) === 0;
|
||||
const sourceName = isLocalSource ? t('source.local_source.title') : name;
|
||||
const sourceName = Sources.isLocalSource(source) ? t('source.local_source.title') : name;
|
||||
|
||||
return (
|
||||
<Card
|
||||
|
||||
@@ -34,7 +34,6 @@ import {
|
||||
GetSourceBrowseQueryVariables,
|
||||
GetSourceMangasFetchMutation,
|
||||
GetSourceMangasFetchMutationVariables,
|
||||
SourceType,
|
||||
} from '@/lib/graphql/generated/graphql.ts';
|
||||
import { useMetadataServerSettings } from '@/modules/settings/services/ServerSettingsMetadata.ts';
|
||||
import { useLocalStorage, useSessionStorage } from '@/modules/core/hooks/useStorage.tsx';
|
||||
@@ -44,7 +43,7 @@ import { createUpdateSourceMetadata, useGetSourceMetadata } from '@/modules/sour
|
||||
import { makeToast } from '@/modules/core/utils/Toast.ts';
|
||||
import { GET_SOURCE_BROWSE } from '@/lib/graphql/queries/SourceQuery.ts';
|
||||
import { TranslationKey } from '@/Base.types.ts';
|
||||
import { IPos } from '@/modules/source/Source.types.ts';
|
||||
import { IPos, SourceIdInfo } from '@/modules/source/Source.types.ts';
|
||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||
import { EmptyView } from '@/modules/core/components/placeholder/EmptyView.tsx';
|
||||
import { EmptyViewAbsoluteCentered } from '@/modules/core/components/placeholder/EmptyViewAbsoluteCentered.tsx';
|
||||
@@ -53,8 +52,9 @@ import { GridLayout } from '@/modules/core/Core.types.ts';
|
||||
import { AppRoutes } from '@/modules/core/AppRoute.constants.ts';
|
||||
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
||||
import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx';
|
||||
import { Sources } from '@/modules/source/services/Sources.ts';
|
||||
|
||||
const DEFAULT_SOURCE: Pick<SourceType, 'id'> = { id: '-1' };
|
||||
const DEFAULT_SOURCE: SourceIdInfo = { id: '-1' };
|
||||
|
||||
const ContentTypeMenu = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
@@ -332,7 +332,7 @@ export function SourceMangas() {
|
||||
);
|
||||
|
||||
const message = !isLoading ? t(SOURCE_CONTENT_TYPE_TO_ERROR_MSG_KEY[contentType]) : undefined;
|
||||
const isLocalSource = sourceId === '0';
|
||||
const isLocalSource = sourceId === Sources.LOCAL_SOURCE_ID;
|
||||
const messageExtra = isLocalSource ? (
|
||||
<>
|
||||
<span>{t('source.local_source.label.checkout')} </span>
|
||||
|
||||
@@ -26,13 +26,13 @@ import { translateExtensionLanguage } from '@/modules/extension/Extensions.utils
|
||||
import { AppRoutes } from '@/modules/core/AppRoute.constants.ts';
|
||||
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
||||
import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx';
|
||||
import { Sources as SourceService } from '@/modules/source/services/Sources.ts';
|
||||
|
||||
function sourceToLangList(sources: Pick<SourceType, 'id' | 'lang'>[]) {
|
||||
const result = new Set<string>();
|
||||
|
||||
sources.forEach((source) => {
|
||||
const isLocalSource = Number(source.id) === 0;
|
||||
const lang = isLocalSource ? DefaultLanguage.OTHER : source.lang;
|
||||
const lang = SourceService.isLocalSource(source) ? DefaultLanguage.OTHER : source.lang;
|
||||
|
||||
result.add(lang);
|
||||
});
|
||||
@@ -46,8 +46,7 @@ function groupByLang<Source extends Pick<SourceType, 'id' | 'name' | 'lang'>>(
|
||||
const result: Record<string, Source[]> = {};
|
||||
|
||||
sources.forEach((source) => {
|
||||
const isLocalSource = Number(source.id) === 0;
|
||||
const lang = isLocalSource ? DefaultLanguage.OTHER : source.lang;
|
||||
const lang = SourceService.isLocalSource(source) ? DefaultLanguage.OTHER : source.lang;
|
||||
|
||||
result[lang] ??= [];
|
||||
result[lang].push(source);
|
||||
@@ -146,7 +145,7 @@ export function Sources() {
|
||||
.filter((source) => {
|
||||
const isLangOther = lang === DefaultLanguage.OTHER;
|
||||
if (isLangOther) {
|
||||
const isLocalSource = Number(source.id) === 0;
|
||||
const isLocalSource = SourceService.isLocalSource(source);
|
||||
const isLangShown = shownLangs.includes(lang);
|
||||
|
||||
const isLangOtherSourceShown = isLangShown || isLocalSource;
|
||||
|
||||
@@ -10,8 +10,7 @@ import { useEffect, useMemo } from 'react';
|
||||
import { jsonSaveParse } from '@/lib/HelperFunctions.ts';
|
||||
import { requestUpdateSourceMetadata } from '@/modules/metadata/services/MetadataUpdater.ts';
|
||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||
import { SourceType } from '@/lib/graphql/generated/graphql.ts';
|
||||
import { ISourceMetadata, SourceMetadataKeys } from '@/modules/source/Source.types.ts';
|
||||
import { ISourceMetadata, SourceIdInfo, SourceMetadataKeys } from '@/modules/source/Source.types.ts';
|
||||
import { convertFromGqlMeta } from '@/modules/metadata/services/MetadataConverter.ts';
|
||||
import { getMetadataFrom } from '@/modules/metadata/services/MetadataReader.ts';
|
||||
import {
|
||||
@@ -39,10 +38,7 @@ const convertGqlMetadataToAppMetadata = (
|
||||
savedSearches: jsonSaveParse<ISourceMetadata['savedSearches']>(metadata.savedSearches as string) ?? undefined,
|
||||
});
|
||||
|
||||
const getMetadata = (
|
||||
metaHolder: Pick<SourceType, 'id'> & GqlMetaHolder,
|
||||
useEffectFn?: typeof useEffect,
|
||||
): ISourceMetadata =>
|
||||
const getMetadata = (metaHolder: SourceIdInfo & GqlMetaHolder, useEffectFn?: typeof useEffect): ISourceMetadata =>
|
||||
convertGqlMetadataToAppMetadata(
|
||||
getMetadataFrom(
|
||||
'source',
|
||||
@@ -53,10 +49,9 @@ const getMetadata = (
|
||||
),
|
||||
);
|
||||
|
||||
export const getSourceMetadata = (metaHolder: Pick<SourceType, 'id'> & GqlMetaHolder): ISourceMetadata =>
|
||||
getMetadata(metaHolder);
|
||||
export const getSourceMetadata = (metaHolder: SourceIdInfo & GqlMetaHolder): ISourceMetadata => getMetadata(metaHolder);
|
||||
|
||||
export const useGetSourceMetadata = (metaHolder: Pick<SourceType, 'id'> & GqlMetaHolder): ISourceMetadata => {
|
||||
export const useGetSourceMetadata = (metaHolder: SourceIdInfo & GqlMetaHolder): ISourceMetadata => {
|
||||
const metadata = getMetadata(metaHolder, useEffect);
|
||||
return useMemo(() => metadata, [metaHolder]);
|
||||
};
|
||||
@@ -65,7 +60,7 @@ export const updateSourceMetadata = async <
|
||||
MetadataKeys extends SourceMetadataKeys = SourceMetadataKeys,
|
||||
MetadataKey extends MetadataKeys = MetadataKeys,
|
||||
>(
|
||||
source: Pick<SourceType, 'id'> & GqlMetaHolder,
|
||||
source: SourceIdInfo & GqlMetaHolder,
|
||||
metadataKey: MetadataKey,
|
||||
value: ISourceMetadata[MetadataKey],
|
||||
): Promise<void[]> =>
|
||||
@@ -75,7 +70,7 @@ export const updateSourceMetadata = async <
|
||||
|
||||
export const createUpdateSourceMetadata =
|
||||
<Settings extends SourceMetadataKeys>(
|
||||
source: Pick<SourceType, 'id'> & GqlMetaHolder,
|
||||
source: SourceIdInfo & GqlMetaHolder,
|
||||
handleError: (error: any) => void = defaultPromiseErrorHandler('createUpdateSourceMetadata'),
|
||||
): ((...args: OmitFirst<Parameters<typeof updateSourceMetadata<Settings>>>) => Promise<void | void[]>) =>
|
||||
(metadataKey, value) =>
|
||||
|
||||
17
src/modules/source/services/Sources.ts
Normal file
17
src/modules/source/services/Sources.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) Contributors to the Suwayomi project
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { SourceIdInfo } from '@/modules/source/Source.types.ts';
|
||||
|
||||
export class Sources {
|
||||
static readonly LOCAL_SOURCE_ID = '0';
|
||||
|
||||
static isLocalSource(source: SourceIdInfo): boolean {
|
||||
return source.id === Sources.LOCAL_SOURCE_ID;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user