chore: fix most sonarcloud's code smells (#2072)

Fixed all SonarCloud's code smells, except:

* Complete the task associated to this "TODO" comment.
* Remove this commented out code.
* Refactor this function to reduce its Cognitive Complexity from `x` to `y`.
* `x` is deprecated.
* This branch's code block is the same as the block for the branch on line `x`.

Basically, all the smells that didn't involve big features or refactors
have been fixed.
This commit is contained in:
Fernando Fernández 2023-08-16 20:45:10 +02:00
parent 1cec3252af
commit 7336bfdca3
No known key found for this signature in database
GPG Key ID: 44495B839CCFF8CF
33 changed files with 89 additions and 102 deletions

View File

@ -10,7 +10,8 @@
"dbaeumer.vscode-eslint",
"lokalise.i18n-ally",
"ryanluker.vscode-coverage-gutters",
"yoavbls.pretty-ts-errors"
"yoavbls.pretty-ts-errors",
"SonarSource.sonarlint-vscode"
],
"unwantedRecommendations": [
"octref.vetur",

View File

@ -38,5 +38,11 @@
"vue": "html"
},
"vue.autoInsert.dotValue": true,
"vue.server.fullCompletionList": true
"vue.server.fullCompletionList": true,
"sonarlint.output.showAnalyzerLogs": true,
"sonarlint.output.showVerboseLogs": true,
"sonarlint.connectedMode.project": {
"connectionId": "jellyfin-vue",
"projectKey": "jellyfin_jellyfin-vue"
}
}

View File

@ -37,13 +37,13 @@ async function togglePlayed(): Promise<void> {
if (isPlayed.value) {
isPlayed.value = false;
await remote.sdk.newUserApi(getPlaystateApi).markUnplayedItem({
userId: remote.auth.currentUserId || '',
userId: remote.auth.currentUserId ?? '',
itemId: props.item.Id
});
} else {
isPlayed.value = true;
await remote.sdk.newUserApi(getPlaystateApi).markPlayedItem({
userId: remote.auth.currentUserId || '',
userId: remote.auth.currentUserId ?? '',
itemId: props.item.Id
});
}

View File

@ -57,7 +57,7 @@ const tracks = computed(() => {
srcIndex: -1,
type: SubtitleDeliveryMethod.External
},
...(subs || [])
...(subs ?? [])
];
});
</script>

View File

@ -36,7 +36,7 @@ const properties = computed(() => {
props.stream.Width && props.stream.Height
? `${props.stream.Width}x${props.stream.Height}`
: undefined;
const framerate = props.stream.AverageFrameRate || props.stream.RealFrameRate;
const framerate = props.stream.AverageFrameRate ?? props.stream.RealFrameRate;
const language = props.stream.Language
? getLocaleName(props.stream.Language, locale.value)
: undefined;

View File

@ -340,7 +340,7 @@ async function getGenres(parentId: string): Promise<void> {
* Save metadata for the current item
*/
async function saveMetadata(): Promise<void> {
if (!metadata.value || !metadata.value.Id) {
if (!metadata.value?.Id) {
return;
}

View File

@ -140,7 +140,7 @@ async function refreshMetadata(): Promise<void> {
taskManager.startTask({
type: TaskType.LibraryRefresh,
id: props.item.Id || '',
data: props.item.Name || 'ID ' + props.item.Id,
data: props.item.Name ?? `ID ${props.item.Id}`,
progress: 0
});

View File

@ -20,7 +20,7 @@ const router = useRouter();
const searchQuery = computed({
get(): string {
return route.query.q?.toString() || '';
return route.query.q?.toString() ?? '';
},
async set(value) {
await router.replace({

View File

@ -96,7 +96,7 @@ function setControlledSwiper (instance: SwiperType): void {
* See https://github.com/nolimits4web/swiper/issues/2629 and https://github.com/surmon-china/vue-awesome-swiper/issues/483
*/
function onSlideChange(): void {
currentIndex.value = swiperInstance.value?.realIndex || 0;
currentIndex.value = swiperInstance.value?.realIndex ?? 0;
if (swiperInstance.value?.isBeginning || swiperInstance.value?.isEnd) {
swiperInstance.value?.updateSlides();

View File

@ -134,7 +134,7 @@ watch(
const itemData = (
await remote.sdk.newUserApi(getUserLibraryApi).getItem({
userId: remote.auth.currentUserId || '',
userId: remote.auth.currentUserId ?? '',
itemId: id
})
).data;

View File

@ -55,7 +55,7 @@ const { t } = useI18n();
const drawer = inject<Ref<boolean>>('NavigationDrawer');
const transparentLayout = computed(() => {
return route.meta.transparentLayout || false;
return route.meta.transparentLayout ?? false;
});
const drawerItems = computed(() => {
@ -63,7 +63,7 @@ const drawerItems = computed(() => {
if (view.Id) {
return {
icon: getLibraryIcon(view.CollectionType),
title: view.Name || '',
title: view.Name ?? '',
to: `/library/${view.Id}`
};
}

View File

@ -136,7 +136,7 @@ const contentSize = computed(() => {
});
const rootStyles = computed<StyleValue>(() =>
Object.fromEntries([
...Object.entries(contentSize.value || {}).map(([property, value]) => [
...Object.entries(contentSize.value ?? {}).map(([property, value]) => [
property,
`${value}px`
]),

View File

@ -93,14 +93,14 @@ export function getScrollParents(
/**
* Parent.assignedSlot.parentElement find the correct parent if the grid is inside a native web component
*/
parent = parent.assignedSlot?.parentElement || parent.parentElement;
parent = parent.assignedSlot?.parentElement ?? parent.parentElement;
}
const fallback = document.scrollingElement || document.documentElement;
const fallback = document.scrollingElement ?? document.documentElement;
return {
vertical: vertical || fallback,
horizontal: horizontal || fallback
vertical: vertical ?? fallback,
horizontal: horizontal ?? fallback
};
}

View File

@ -69,7 +69,7 @@ onMounted(() => {
if (typeof oldIndex === 'number') {
const item = playbackManager.queue[oldIndex];
if (item && item.Id && typeof e.newIndex === 'number') {
if (item?.Id && typeof e.newIndex === 'number') {
playbackManager.changeItemPosition(item.Id, e.newIndex);
}
}

View File

@ -7,7 +7,7 @@
:is="mediaElementType"
v-show="mediaElementType === 'video' && teleportTarget"
ref="mediaElementRef"
:poster="posterUrl"
:poster="String(posterUrl)"
autoplay
crossorigin="anonymous"
playsinline
@ -99,13 +99,13 @@ const teleportTarget = computed<
}
});
const posterUrl = computed<string>(() =>
const posterUrl = computed(() =>
!isNil(playbackManager.currentItem) &&
playbackManager.currentlyPlayingMediaType === 'Video'
? getImageInfo(playbackManager.currentItem, {
preferBackdrop: true
}).url || ''
: ''
}).url
: undefined
);
/**

View File

@ -141,7 +141,7 @@ const tracks = ref<BaseItemDto[] | null | undefined>();
async function fetch(): Promise<void> {
tracks.value = (
await remote.sdk.newUserApi(getItemsApi).getItems({
userId: remote.auth.currentUserId || '',
userId: remote.auth.currentUserId ?? '',
parentId: props.item.Id,
sortBy: ['SortName'],
sortOrder: [SortOrder.Ascending],

View File

@ -85,15 +85,11 @@ const genres = ref<BaseItemDto[]>([]);
onMounted(async () => {
const { itemId } = route.params as { itemId: string };
const typesQuery = route.query.type;
const typesQuery = route.query.type as BaseItemKind ?? [];
const includeItemTypes = (
typesQuery == undefined
? []
: (typeof typesQuery === 'string'
? [typesQuery]
: typesQuery)
) as BaseItemKind[];
const includeItemTypes: BaseItemKind[] = typeof typesQuery === 'string'
? [typesQuery]
: typesQuery;
loading.value = true;

View File

@ -96,7 +96,7 @@ const homeSections = computed<HomeSection[]>(() => {
latestMediaSections.push({
name: 'latestLibrary',
libraryName: userView.Name,
libraryId: userView.Id || '',
libraryId: userView.Id ?? '',
shape: getShapeFromCollectionType(userView.CollectionType),
type: 'latestmedia'
});

View File

@ -166,7 +166,7 @@ watch(
() => {
if (swiperInstance.value && !isNil(playbackManager.currentItemIndex)) {
swiperInstance.value.slideTo(playbackManager.currentItemIndex);
route.meta.title = playbackManager.currentItem?.Name || '';
route.meta.title = playbackManager.currentItem?.Name ?? '';
}
},
{ immediate: true }
@ -183,7 +183,7 @@ watch(isVisualizing, async () => {
* Handle slide changes
*/
function onSlideChange(): void {
const index = swiperInstance.value?.activeIndex || 0;
const index = swiperInstance.value?.activeIndex ?? 0;
playbackManager.currentItemIndex = index;
}

View File

@ -96,7 +96,7 @@ const memo = reactive(
])
);
const searchQuery = computed(() => route.query?.q?.toString() || '');
const searchQuery = computed(() => route.query?.q?.toString() ?? '');
const items = computed(() => memo.get(searchQuery.value)?.items ?? []);
const people = computed(() => memo.get(searchQuery.value)?.people ?? []);
const movies = computed(() =>
@ -123,7 +123,7 @@ const performDebouncedSearch = useDebounceFn(async (searchTerm: string) => {
const itemSearch =
(
await remote.sdk.newUserApi(getItemsApi).getItemsByUserId({
userId: remote.auth.currentUserId || '',
userId: remote.auth.currentUserId ?? '',
searchTerm,
includeItemTypes: [
BaseItemKind.Movie,

View File

@ -108,7 +108,7 @@ const route = useRoute();
const router = useRouter();
const remote = useRemote();
const api = remote.sdk.oneTimeSetup(
remote.auth.currentServer?.PublicAddress || ''
remote.auth.currentServer?.PublicAddress ?? ''
);
route.meta.title = t('login.login');

View File

@ -125,7 +125,7 @@ const heading = computed(() => {
async function completeWizard(): Promise<void> {
try {
const api = remote.sdk.oneTimeSetup(
remote.auth.currentServer?.PublicAddress || ''
remote.auth.currentServer?.PublicAddress ?? ''
);
await getStartupApi(api).completeWizard();

View File

@ -25,7 +25,7 @@ interface ClientSettingsState {
*/
const navigatorLanguage = useNavigatorLanguage();
const BROWSER_LANGUAGE = computed<string>(() => {
const rawString = navigatorLanguage.language.value || '';
const rawString = navigatorLanguage.language.value ?? '';
/**
* Removes the culture info from the language string, so 'es-ES' is recognised as 'es'
*/

View File

@ -303,7 +303,7 @@ class PlaybackManagerStore {
srcLang: sub.Language ?? undefined,
type: sub.DeliveryMethod ?? SubtitleDeliveryMethod.Drop,
srcIndex: sub.srcIndex,
codec: sub.Codec || undefined
codec: sub.Codec
}));
}
}
@ -466,7 +466,7 @@ class PlaybackManagerStore {
public set currentVolume(newVolume: number) {
newVolume = newVolume > 100 ? 100 : newVolume;
newVolume = newVolume < 0 ? 0 : newVolume;
this.isMuted = newVolume === 0 ? true : false;
this.isMuted = newVolume === 0;
if (this._state.isRemotePlayer) {
this._state.remoteCurrentVolume = newVolume;
@ -747,9 +747,9 @@ class PlaybackManagerStore {
};
public stop = (): void => {
const sessionId = String(this._state.playSessionId || '');
const sessionId = String(this._state.playSessionId ?? '');
const time = Number(this.currentTime);
const itemId = String(this.currentItem?.Id || '');
const itemId = String(this.currentItem?.Id ?? '');
const volume = Number(this.currentVolume);
Object.assign(this._state, this._defaultState);
@ -860,7 +860,7 @@ class PlaybackManagerStore {
if (item) {
return (
await remote.sdk.newUserApi(getMediaInfoApi).getPostedPlaybackInfo({
itemId: item?.Id || '',
itemId: item?.Id ?? '',
userId: remote.auth.currentUserId,
autoOpenLiveStream: true,
playbackInfoDto: { DeviceProfile: playbackProfile },
@ -965,8 +965,8 @@ class PlaybackManagerStore {
mediaSourceId: mediaSource.Id,
deviceId: remote.sdk.deviceInfo.id,
api_key: remote.auth.currentUserToken,
Tag: mediaSource.ETag || '',
LiveStreamId: mediaSource.LiveStreamId || ''
Tag: mediaSource.ETag ?? '',
LiveStreamId: mediaSource.LiveStreamId ?? ''
};
const parameters = new URLSearchParams(directOptions).toString();
@ -1063,42 +1063,42 @@ class PlaybackManagerStore {
src:
getImageInfo(this.currentItem, {
width: 96
}).url || '',
}).url ?? '',
sizes: '96x96'
},
{
src:
getImageInfo(this.currentItem, {
width: 128
}).url || '',
}).url ?? '',
sizes: '128x128'
},
{
src:
getImageInfo(this.currentItem, {
width: 192
}).url || '',
}).url ?? '',
sizes: '192x192'
},
{
src:
getImageInfo(this.currentItem, {
width: 256
}).url || '',
}).url ?? '',
sizes: '256x256'
},
{
src:
getImageInfo(this.currentItem, {
width: 384
}).url || '',
}).url ?? '',
sizes: '384x384'
},
{
src:
getImageInfo(this.currentItem, {
width: 512
}).url || '',
}).url ?? '',
sizes: '512x512'
}
]

View File

@ -192,7 +192,7 @@ class PlayerElementStore {
* If VTT found, applying it
*/
mediaElementRef.value.textTracks[vttIdx].mode = 'showing';
} else if (ass !== undefined && ass.src) {
} else if (ass?.src) {
/**
* If SSA, using Subtitle Opctopus
*/

View File

@ -158,12 +158,10 @@ class TaskManagerStore {
progress
});
}
} else {
if (progress >= 0 && progress < 100) {
taskPayload.progress = progress;
} else if (progress >= 0) {
this.finishTask(data.ItemId);
}
} else if (progress >= 0 && progress < 100) {
taskPayload.progress = progress;
} else if (progress >= 0) {
this.finishTask(data.ItemId);
}
}
};

View File

@ -130,7 +130,7 @@ class UserLibrariesStore {
const userViewsResponse = await remote.sdk
.newUserApi(getUserViewsApi)
.getUserViews({
userId: remote.auth.currentUserId || ''
userId: remote.auth.currentUserId ?? ''
});
this._state.value.views = userViewsResponse.data.Items ?? [];
@ -145,7 +145,7 @@ class UserLibrariesStore {
try {
const audioResumes = (
await remote.sdk.newUserApi(getItemsApi).getResumeItems({
userId: remote.auth.currentUserId || '',
userId: remote.auth.currentUserId ?? '',
fields: [
ItemFields.PrimaryImageAspectRatio,
ItemFields.MediaSources,
@ -174,7 +174,7 @@ class UserLibrariesStore {
try {
const videoResumes = (
await remote.sdk.newUserApi(getItemsApi).getResumeItems({
userId: remote.auth.currentUserId || '',
userId: remote.auth.currentUserId ?? '',
fields: [
ItemFields.PrimaryImageAspectRatio,
ItemFields.MediaSources,
@ -234,7 +234,7 @@ class UserLibrariesStore {
try {
const latestMedia = (
await remote.sdk.newUserApi(getUserLibraryApi).getLatestMedia({
userId: remote.auth.currentUserId || '',
userId: remote.auth.currentUserId ?? '',
fields: [
ItemFields.PrimaryImageAspectRatio,
ItemFields.MediaSources,
@ -262,7 +262,7 @@ class UserLibrariesStore {
try {
const carouselItems = (
await remote.sdk.newUserApi(getUserLibraryApi).getLatestMedia({
userId: remote.auth.currentUserId || '',
userId: remote.auth.currentUserId ?? '',
fields: [
ItemFields.Overview,
ItemFields.PrimaryImageAspectRatio,

View File

@ -116,7 +116,7 @@ export function safariVersion(): number | undefined {
* This works for iOS Safari and desktop Safari, which contain something
* like "Version/13.0" indicating the major Safari or iOS version.
*/
let match = userAgent.match(/Version\/(\d+)/);
let match = /Version\/(\d+)/.exec(userAgent);
if (match) {
return Number.parseInt(match[1], /* Base= */ 10);
@ -126,7 +126,7 @@ export function safariVersion(): number | undefined {
* This works for all other browsers on iOS, which contain something like
* "OS 13_3" indicating the major & minor iOS version.
*/
match = userAgent.match(/OS (\d+)(?:_\d+)?/);
match = /OS (\d+)(?:_\d+)?/.exec(userAgent);
if (match) {
return Number.parseInt(match[1], /* Base= */ 10);

View File

@ -245,7 +245,7 @@ export function getImageInfo(
} else if (isPerson(item)) {
imgType = ImageType.Primary;
imgTag = item.PrimaryImageTag;
} else if (preferThumb && item.ImageTags && item.ImageTags.Thumb) {
} else if (preferThumb && item.ImageTags?.Thumb) {
imgType = ImageType.Thumb;
imgTag = item.ImageTags.Thumb;
} else if (
@ -255,7 +255,7 @@ export function getImageInfo(
) {
imgType = ImageType.Banner;
imgTag = item.ImageTags.Banner;
} else if (preferLogo && item.ImageTags && item.ImageTags.Logo) {
} else if (preferLogo && item.ImageTags?.Logo) {
imgType = ImageType.Logo;
imgTag = item.ImageTags.Logo;
} else if (preferBackdrop && item.BackdropImageTags?.[0]) {
@ -303,11 +303,7 @@ export function getImageInfo(
imgType = ImageType.Backdrop;
imgTag = item.ParentBackdropImageTags[0];
itemId = item.ParentBackdropItemId;
} else if (
item.ImageTags &&
item.ImageTags.Primary &&
(item.Type !== BaseItemKind.Episode || item.ChildCount !== 0)
) {
} else if (item.ImageTags?.Primary && (item.Type !== BaseItemKind.Episode || item.ChildCount !== 0)) {
imgType = ImageType.Primary;
imgTag = item.ImageTags.Primary;
height =
@ -332,15 +328,14 @@ export function getImageInfo(
: undefined;
} else if (
item.Type === BaseItemKind.Season &&
item.ImageTags &&
item.ImageTags.Thumb
item.ImageTags?.Thumb
) {
imgType = ImageType.Thumb;
imgTag = item.ImageTags.Thumb;
} else if (item.BackdropImageTags && item.BackdropImageTags.length > 0) {
imgType = ImageType.Backdrop;
imgTag = item.BackdropImageTags[0];
} else if (item.ImageTags && item.ImageTags.Thumb) {
} else if (item.ImageTags?.Thumb) {
imgType = ImageType.Thumb;
imgTag = item.ImageTags.Thumb;
} else if (item.SeriesThumbImageTag && inheritThumb !== false) {
@ -435,7 +430,7 @@ export function getLogo(
if (tag) {
imgType = ImageType.Logo;
imgTag = tag;
} else if (item.ImageTags && item.ImageTags.Logo) {
} else if (item.ImageTags?.Logo) {
imgType = ImageType.Logo;
imgTag = item.ImageTags.Logo;
} else if (item.ParentLogoImageTag && item.ParentLogoItemId) {
@ -447,7 +442,7 @@ export function getLogo(
if (imgTag && imgType && itemId) {
const remote = useRemote();
url = new URL(remote.sdk.api?.getItemImageUrl(itemId, imgType) || '');
url = new URL(remote.sdk.api?.getItemImageUrl(itemId, imgType) ?? '');
const parameters: Record<string, string> = {
imgTag,

View File

@ -255,10 +255,7 @@ export function canPlay(item: BaseItemDto | undefined): boolean {
* Check if an item can be resumed
*/
export function canResume(item: BaseItemDto): boolean {
return item?.UserData?.PlaybackPositionTicks &&
item.UserData.PlaybackPositionTicks > 0
? true
: false;
return Boolean(item?.UserData?.PlaybackPositionTicks && item.UserData.PlaybackPositionTicks > 0);
}
/**
* Determine if an item can be mark as played

View File

@ -300,7 +300,7 @@ export function getCodecProfiles(
);
}
const globalMaxVideoBitrate = (getGlobalMaxVideoBitrate() || '').toString();
const globalMaxVideoBitrate = (getGlobalMaxVideoBitrate() ?? '').toString();
if (globalMaxVideoBitrate) {
h264CodecProfileConditions.push(

View File

@ -18,9 +18,8 @@ import {
*/
export function hasH264Support(videoTestElement: HTMLVideoElement): boolean {
return !!(
videoTestElement.canPlayType &&
videoTestElement
.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"')
.canPlayType?.('video/mp4; codecs="avc1.42E01E, mp4a.40.2"')
.replace(/no/, '')
);
}
@ -96,9 +95,8 @@ export function hasAv1Support(videoTestElement: HTMLVideoElement): boolean {
}
return !!(
videoTestElement.canPlayType &&
videoTestElement
.canPlayType('video/webm; codecs="av01.0.15M.10"')
.canPlayType?.('video/webm; codecs="av01.0.15M.10"')
.replace(/no/, '')
);
}
@ -124,8 +122,7 @@ function hasVc1Support(videoTestElement: HTMLVideoElement): boolean {
*/
export function hasVp8Support(videoTestElement: HTMLVideoElement): boolean {
return !!(
videoTestElement.canPlayType &&
videoTestElement.canPlayType('video/webm; codecs="vp8"').replace(/no/, '')
videoTestElement.canPlayType?.('video/webm; codecs="vp8"').replace(/no/, '')
);
}
@ -137,8 +134,7 @@ export function hasVp8Support(videoTestElement: HTMLVideoElement): boolean {
*/
export function hasVp9Support(videoTestElement: HTMLVideoElement): boolean {
return !!(
videoTestElement.canPlayType &&
videoTestElement.canPlayType('video/webm; codecs="vp9"').replace(/no/, '')
videoTestElement.canPlayType?.('video/webm; codecs="vp9"').replace(/no/, '')
);
}

View File

@ -63,22 +63,20 @@ export async function updateDisplayPreferences(
displayPreferencesId
);
const newDisplayPreferences = Object.assign(
{},
currentDisplayPreferences,
displayPreferences
);
const newDisplayPreferences = {
...currentDisplayPreferences,
...displayPreferences
};
// If either old or new preferences have custom settings, merge them
if (
currentDisplayPreferences.CustomPrefs !== undefined ||
newDisplayPreferences.CustomPrefs !== undefined
) {
const mergedCustomPrefs = Object.assign(
{},
currentDisplayPreferences.CustomPrefs ?? {},
displayPreferences.CustomPrefs ?? {}
);
const mergedCustomPrefs = {
...currentDisplayPreferences.CustomPrefs,
...displayPreferences.CustomPrefs
};
newDisplayPreferences.CustomPrefs = Object.fromEntries(
Object.entries(mergedCustomPrefs)