Skip to content

Commit

Permalink
Migrate some apis to rtkq (#384)
Browse files Browse the repository at this point in the history
* Change checkbox to circle

* Add startIcon to input component

* Add series api to rtkq

* Fix series breakdown on dashboard

* Migrate some file apis to rtkq

* Migrate more file apis to rtkq

* Fix eslint

* Remove mainpage refresh event

* Fix signalr

* Change avdump trigger to async/await

* Take avdump result from trigger response
  • Loading branch information
harshithmohan authored Aug 13, 2022
1 parent 872fff1 commit 767e67b
Show file tree
Hide file tree
Showing 22 changed files with 201 additions and 195 deletions.
6 changes: 3 additions & 3 deletions src/components/Input/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useState } from 'react';
import cx from 'classnames';
import { Icon } from '@mdi/react';
import {
mdiCheckboxBlankOutline, mdiCheckboxMarked,
mdiCheckboxBlankCircleOutline, mdiCheckboxMarkedCircleOutline,
} from '@mdi/js';

import TransitionDiv from '../TransitionDiv';
Expand Down Expand Up @@ -43,12 +43,12 @@ function Checkbox({ id, label, isChecked, className, onChange, labelRight, justi
)}
{isChecked && (
<TransitionDiv className="flex text-highlight-1" enterFrom="opacity-50">
<Icon path={mdiCheckboxMarked} size={1} />
<Icon path={mdiCheckboxMarkedCircleOutline} size={1} />
</TransitionDiv>
)}
{!isChecked && (
<TransitionDiv className="flex text-highlight-1" enterFrom="opacity-50">
<Icon path={mdiCheckboxBlankOutline} size={1} />
<Icon path={mdiCheckboxBlankCircleOutline} size={1} />
</TransitionDiv>
)}
{labelRight && (
Expand Down
28 changes: 15 additions & 13 deletions src/components/Input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ type Props = {
center?: boolean;
endIcon?: string;
endIconClick?: (event: any) => void;
startIcon?: string;
};

function Input(props: Props) {
const {
id, label, center, type, placeholder, value, className,
id, label, center, type, placeholder, value, className, startIcon,
autoFocus, disabled, onChange, onKeyPress, endIcon, endIconClick,
} = props;

Expand All @@ -30,18 +31,19 @@ function Input(props: Props) {
<label htmlFor={id}>
{label && <div className="mb-3 font-semibold text-base">{label}</div>}
<div className="relative">
<input
className={cx(['appearance-none bg-background-alt w-full focus:shadow-none focus:outline-none px-3 py-2 rounded transition duration-300 ease-in-out border border-background-border focus:border-primary', center && 'text-center'])}
id={id}
type={type}
placeholder={placeholder ?? ''}
value={value}
onChange={onChange}
onKeyPress={onKeyPress}
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus={autoFocus}
disabled={disabled}
/>
{startIcon && <div className="absolute top-1/2 transform -translate-y-1/2 left-3"><Icon path={startIcon} size={1}/></div>}
<input
className={cx(['appearance-none bg-background-alt w-full focus:shadow-none focus:outline-none px-3 py-2 rounded transition duration-300 ease-in-out border border-background-border focus:border-primary', center && 'text-center', startIcon && 'pl-11'])}
id={id}
type={type}
placeholder={placeholder ?? ''}
value={value}
onChange={onChange}
onKeyPress={onKeyPress}
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus={autoFocus}
disabled={disabled}
/>
{endIcon && <div onClick={endIconClick} className="cursor-pointer absolute top-1/2 transform -translate-y-1/2 right-3 text-highlight-1"><Icon path={endIcon} size={1} horizontal vertical rotate={180}/></div>}
</div>
</label>
Expand Down
30 changes: 0 additions & 30 deletions src/core/api/v3/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,6 @@ function patchFileIgnore(id: string, ignore: boolean = true) {
return ApiRequest(`${id}/Ignore`, 'PATCH', `?value=${ignore}`);
}

// Run a file through AVDump
function postFileAvdump(id: string) {
return ApiRequest(`${id}/AVDump`, 'POST');
}

// Rescan the file.
function postFileRescan(id: string) {
return ApiRequest(`${id}/Rescan`, 'POST');
}

// Rehash the file.
function postFileRehash(id: string) {
return ApiRequest(`${id}/Rehash`, 'POST');
}

// Get Recently Added Files
function getFileRecentLegacy(limit = 50) {
return ApiRequest(`Recent/${limit}`, 'GET');
Expand All @@ -54,33 +39,18 @@ function getFileRecent(pageSize = 50, page = 1) {
return ApiRequest('Recent', 'GET', `?pageSize=${pageSize}&page=${page}`);
}

// Get files marked as ignored.
function getFileIgnored(pageSize = 50, page = 1) {
return ApiRequest('Ignored', 'GET', `?pageSize=${pageSize}&page=${page}`);
}

// Get files with more than one location.
function getFileDuplicates(pageSize = 50, page = 1) {
return ApiRequest('Duplicates', 'GET', `?pageSize=${pageSize}&page=${page}`);
}

// Get Unrecognized Files. Use pageSize and page (index 0) in the query to enable pagination.
function getFileUnrecognized(pageSize = 0, page = 1) {
return ApiRequest('Unrecognized', 'GET', `?pageSize=${pageSize}&page=${page}`);
}

export default {
getFile,
getFileAniDB,
getFileMediaInfo,
patchFileWatched,
patchFileIgnore,
postFileAvdump,
postFileRescan,
postFileRehash,
getFileRecent,
getFileIgnored,
getFileDuplicates,
getFileUnrecognized,
getFileRecentLegacy,
};
5 changes: 0 additions & 5 deletions src/core/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export default {
MAINPAGE_QUEUE_OPERATION: 'EVENT_MAINPAGE_QUEUE_OPERATION',
MAINPAGE_QUEUE_STATUS: 'EVENT_MAINPAGE_QUEUE_STATUS',
MAINPAGE_RECENT_FILES: 'EVENT_MAINPAGE_RECENT_FILES',
MAINPAGE_REFRESH: 'EVENT_MAINPAGE_REFRESH',
// SERVER
SERVER_VERSION: 'EVENT_SERVER_VERSION',
// SETTINGS
Expand All @@ -50,8 +49,4 @@ export default {
WEBUI_UPDATE: 'EVENT_WEBUI_UPDATE',
// LOGS
LOGPAGE_LOAD: 'EVENT_LOGPAGE_LOAD',
// UTILITIES:
UTILITIES_RESCAN: 'EVENT_UTILITIES_RESCAN',
UTILITIES_REHASH: 'EVENT_UTILITIES_REHASH',
UTILITIES_AVDUMP: 'EVENT_UTILITIES_AVDUMP',
};
10 changes: 6 additions & 4 deletions src/core/middlewares/signalr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ const onQueueStateChange = dispatch => (queue, state) => {
const newState = Object.assign({}, { [queue]: state });
dispatch(setQueueStatus(newState));
};
const onQueueCountChange = (dispatch, getState) => (queue, count) => {
const currentQueue = getState().mainpage.queueStatus[queue];
if (queue === 'GeneralQueueCount' && currentQueue > count) dispatch({ type: Events.MAINPAGE_REFRESH });
const onQueueCountChange = dispatch => (queue, count) => {
// TODO: Add auto-reload back
// const currentQueue = getState().mainpage.queueStatus[queue];
// if (queue === 'GeneralQueueCount' && currentQueue > count) dispatch({ type: Events.MAINPAGE_REFRESH });

const newState = Object.assign({}, { [queue]: count });
dispatch(setQueueStatus(newState));
Expand Down Expand Up @@ -64,6 +65,7 @@ const signalRMiddleware = ({
dispatch,
getState,
}) => next => async (action) => {
// TODO: Change this event to something else
// register signalR after the user logged in
if (action.type === Events.MAINPAGE_LOAD) {
if (connectionEvents !== undefined) { return next(action); }
Expand All @@ -87,7 +89,7 @@ const signalRMiddleware = ({

// event handlers, you can use these to dispatch actions to update your Redux store
connectionEvents.on('QueueStateChanged', onQueueStateChange(dispatch));
connectionEvents.on('QueueCountChanged', onQueueCountChange(dispatch, getState));
connectionEvents.on('QueueCountChanged', onQueueCountChange(dispatch));
connectionEvents.on('CommandProcessingStatus', onQueueRefreshState(dispatch));

// re-establish the connection if connection dropped
Expand Down
4 changes: 4 additions & 0 deletions src/core/reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import { externalApi } from './rtkQuery/externalApi';
import { collectionApi } from './rtkQuery/collectionApi';
import { logsApi } from './rtkQuery/logsApi';
import { importFolderApi } from './rtkQuery/importFolderApi';
import { seriesApi } from './rtkQuery/seriesApi';
import { fileApi } from './rtkQuery/fileApi';

const autoUpdate = handleAction(SET_AUTOUPDATE, (state, action) => action.payload, false);

Expand All @@ -45,6 +47,8 @@ const reducers = {
[collectionApi.reducerPath]: collectionApi.reducer,
[logsApi.reducerPath]: logsApi.reducer,
[importFolderApi.reducerPath]: importFolderApi.reducer,
[seriesApi.reducerPath]: seriesApi.reducer,
[fileApi.reducerPath]: fileApi.reducer,
};

export type Reducers = typeof reducers;
Expand Down
4 changes: 3 additions & 1 deletion src/core/rtkQuery/dashboardApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ export const dashboardApi = createApi({
query: () => ({ url: 'SeriesSummary' }),
transformResponse: (response: DashboardSeriesSummaryType) => {
const result = response;
result.Other += result.Special + result.None;
result.Other += (result?.Special ?? 0) + (result?.None ?? 0);
delete result.Special;
delete result.None;
return result;
},
}),
Expand Down
71 changes: 71 additions & 0 deletions src/core/rtkQuery/fileApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

import type { RootState } from '../store';
import type { FileType, AVDumpResultType } from '../types/api/file';
import type { ListResultType, PaginationType } from '../types/api';

export const fileApi = createApi({
reducerPath: 'file',
baseQuery: fetchBaseQuery({
baseUrl: '/api/v3/File/',
prepareHeaders: (headers, { getState }) => {
const apikey = (getState() as RootState).apiSession.apikey;
headers.set('apikey', apikey);
return headers;
},
}),
endpoints: build => ({

// Get ignored files.
getFileIgnored: build.query<ListResultType<Array<FileType>>, PaginationType>({
query: params => ({ url: 'Ignored', params }),
}),

// Get unrecognized files. Shoko.Server.API.v3.Models.Shoko.File.FileDetailed is not relevant here, as there will be no links. Use pageSize and page (index 0) in the query to enable pagination.
getFileUnrecognized: build.query<ListResultType<Array<FileType>>, PaginationType>({
query: params => ({ url: 'Unrecognized', params }),
}),

// Mark or unmark a file as ignored.
putFileIgnore: build.query<void, { fileID: number, value: boolean }>({
query: params => ({
url: `${params.fileID}/Ignore`,
params,
method: 'PUT',
}),
}),

// Run a file through AVDump and return the result.
postFileAVDump: build.query<AVDumpResultType, number>({
query: fileId => ({
url: `${fileId}/AVDump`,
method: 'POST',
}),
}),

// Rescan a file on AniDB.
postFileRescan: build.query<void, number>({
query: fileId => ({
url: `${fileId}/Rescan`,
method: 'POST',
}),
}),

// Rehash a file.
postFileRehash: build.query<void, number>({
query: fileId => ({
url: `${fileId}/Rehash`,
method: 'POST',
}),
}),
}),
});

export const {
useGetFileIgnoredQuery,
useGetFileUnrecognizedQuery,
useLazyPutFileIgnoreQuery,
useLazyPostFileAVDumpQuery,
useLazyPostFileRescanQuery,
useLazyPostFileRehashQuery,
} = fileApi;
29 changes: 29 additions & 0 deletions src/core/rtkQuery/seriesApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

import type { RootState } from '../store';
import type { SeriesAniDBSearchResult } from '../types/api/series';
import type { PaginationType } from '../types/api';

export const seriesApi = createApi({
reducerPath: 'series',
baseQuery: fetchBaseQuery({
baseUrl: '/api/v3/Series/',
prepareHeaders: (headers, { getState }) => {
const apikey = (getState() as RootState).apiSession.apikey;
headers.set('apikey', apikey);
return headers;
},
}),
endpoints: build => ({

// Search the title dump for the given query or directly using the anidb id.
getSeriesAniDBSearch: build.query<Array<SeriesAniDBSearchResult>, { query: string } & PaginationType>({
query: params => ({ url: `AniDB/Search/${params.query}`, params }),
transformResponse: (response: any) => response.List,
}),
}),
});

export const {
useLazyGetSeriesAniDBSearchQuery,
} = seriesApi;
20 changes: 10 additions & 10 deletions src/core/sagas/apiPollingDriver.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
take, cancel, fork, call, put, select, cancelled, delay,
take, cancel, fork, call, put, cancelled, delay,
} from 'redux-saga/effects';
import { toast } from 'react-toastify';

Expand All @@ -26,15 +26,15 @@ function* pollServerStatus() {
function* pollAutoRefresh() {
try {
yield put({ type: SET_AUTOUPDATE, payload: true });
while (true) {
const location = yield select(state => state.router.location.pathname);

if (location === '/main') {
yield put({ type: Events.MAINPAGE_REFRESH, payload: null });
}

yield delay(1500);
}
// while (true) {
// const location = yield select(state => state.router.location.pathname);
//
// if (location === '/main') {
// yield put({ type: Events.MAINPAGE_REFRESH, payload: null });
// }
//
// yield delay(1500);
// }
} finally {
if (yield cancelled()) {
yield put({ type: SET_AUTOUPDATE, payload: false });
Expand Down
44 changes: 0 additions & 44 deletions src/core/sagas/file.ts

This file was deleted.

Loading

0 comments on commit 767e67b

Please sign in to comment.