Fix/tracking updating score (#682)
* Use SelectSetting for updating track score * Create custom Select component
This commit is contained in:
19
src/components/atoms/Select.tsx
Normal file
19
src/components/atoms/Select.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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 { Select as MuiSelect, SelectVariants } from '@mui/material';
|
||||
|
||||
export const Select = <Value, Variant extends SelectVariants>({
|
||||
children,
|
||||
maxSelectionHeightPx = 250,
|
||||
...props
|
||||
}: React.ComponentProps<typeof MuiSelect<Value, Variant>> & { maxSelectionHeightPx?: number }) => (
|
||||
<MuiSelect<any, any> MenuProps={{ PaperProps: { style: { maxHeight: maxSelectionHeightPx } } }} {...props}>
|
||||
{children}
|
||||
</MuiSelect>
|
||||
);
|
||||
@@ -18,7 +18,7 @@ import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import Slide from '@mui/material/Slide';
|
||||
import Fade from '@mui/material/Fade';
|
||||
import Zoom from '@mui/material/Zoom';
|
||||
import { Divider, FormControl, MenuItem, Select, styled, Tooltip } from '@mui/material';
|
||||
import { Divider, FormControl, MenuItem, styled, Tooltip } from '@mui/material';
|
||||
import ListItem from '@mui/material/ListItem';
|
||||
import ListItemText from '@mui/material/ListItemText';
|
||||
import Collapse from '@mui/material/Collapse';
|
||||
@@ -27,6 +27,7 @@ import { AllowedMetadataValueTypes, ChapterOffset, IReaderSettings, TChapter, TM
|
||||
import { ReaderSettingsOptions } from '@/components/reader/ReaderSettingsOptions';
|
||||
import { useBackButton } from '@/util/useBackButton.ts';
|
||||
import { useSetDefaultBackTo } from '@/components/context/NavbarContext.tsx';
|
||||
import { Select } from '@/components/atoms/Select.tsx';
|
||||
|
||||
const Root = styled('div')({
|
||||
zIndex: 10,
|
||||
@@ -101,8 +102,6 @@ const ChapterNavigation = styled('div')({
|
||||
},
|
||||
});
|
||||
|
||||
const MenuProps = { PaperProps: { style: { maxHeight: 150 } } };
|
||||
|
||||
const OpenDrawerButton = styled(IconButton)(({ theme }) => ({
|
||||
position: 'fixed',
|
||||
top: 0 + 20,
|
||||
@@ -280,7 +279,6 @@ export function ReaderNavBar(props: IProps) {
|
||||
disabled={disableChapterNavButtons || chapter.pageCount === -1}
|
||||
>
|
||||
<Select
|
||||
MenuProps={MenuProps}
|
||||
value={chapter.pageCount > -1 ? `${curPage}` : ''}
|
||||
displayEmpty
|
||||
onChange={({ target: { value: selectedPage } }) => {
|
||||
@@ -315,7 +313,6 @@ export function ReaderNavBar(props: IProps) {
|
||||
disabled={disableChapterNavButtons || chapter.sourceOrder < 1}
|
||||
>
|
||||
<Select
|
||||
MenuProps={MenuProps}
|
||||
value={chapter.sourceOrder >= 1 ? `${chapter.sourceOrder}` : ''}
|
||||
displayEmpty
|
||||
onChange={({ target: { value: selectedChapter } }) => {
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
*/
|
||||
|
||||
import { List, ListItem, ListItemText, Switch } from '@mui/material';
|
||||
import Select from '@mui/material/Select';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { AllowedMetadataValueTypes, IReaderSettings } from '@/typings';
|
||||
import { NumberSetting } from '@/components/settings/NumberSetting.tsx';
|
||||
import { isHorizontalReaderType } from '@/components/reader/Page.tsx';
|
||||
import { Select } from '@/components/atoms/Select.tsx';
|
||||
|
||||
interface IProps extends IReaderSettings {
|
||||
setSettingValue: (key: keyof IReaderSettings, value: AllowedMetadataValueTypes, persist?: boolean) => void;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { List, ListItem, ListItemText, MenuItem, Select } from '@mui/material';
|
||||
import { List, ListItem, ListItemText, MenuItem } from '@mui/material';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useContext, useEffect } from 'react';
|
||||
import { updateMetadataServerSettings, useMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts';
|
||||
@@ -15,6 +15,7 @@ import { makeToast } from '@/components/util/Toast.tsx';
|
||||
import { MutableListSetting } from '@/components/settings/MutableListSetting.tsx';
|
||||
import { NavBarContext, useSetDefaultBackTo } from '@/components/context/NavbarContext.tsx';
|
||||
import { ActiveDevice, DEFAULT_DEVICE } from '@/util/device.ts';
|
||||
import { Select } from '@/components/atoms/Select.tsx';
|
||||
|
||||
export const DeviceSetting = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -75,11 +76,7 @@ export const DeviceSetting = () => {
|
||||
primary={t('settings.device.active_device.label.title')}
|
||||
secondary={t('settings.device.active_device.label.description')}
|
||||
/>
|
||||
<Select
|
||||
MenuProps={{ PaperProps: { style: { maxHeight: 150 } } }}
|
||||
value={activeDevice}
|
||||
onChange={({ target: { value: device } }) => setActiveDevice(device)}
|
||||
>
|
||||
<Select value={activeDevice} onChange={({ target: { value: device } }) => setActiveDevice(device)}>
|
||||
{devices.map((device) => (
|
||||
<MenuItem key={device} value={device}>
|
||||
{device}
|
||||
|
||||
@@ -6,17 +6,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogTitle,
|
||||
FormControl,
|
||||
ListItemText,
|
||||
MenuItem,
|
||||
Select,
|
||||
Stack,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { Button, Dialog, DialogTitle, FormControl, ListItemText, MenuItem, Stack, Typography } from '@mui/material';
|
||||
import DialogContent from '@mui/material/DialogContent';
|
||||
import DialogActions from '@mui/material/DialogActions';
|
||||
import ListItemButton from '@mui/material/ListItemButton';
|
||||
@@ -25,6 +15,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import DialogContentText from '@mui/material/DialogContentText';
|
||||
import InfoIcon from '@mui/icons-material/Info';
|
||||
import { TranslationKey } from '@/typings.ts';
|
||||
import { Select } from '@/components/atoms/Select.tsx';
|
||||
|
||||
export type SelectSettingValueDisplayInfo = {
|
||||
text: TranslationKey | string;
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
} from '@mui/material';
|
||||
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
||||
import PopupState, { bindDialog, bindMenu, bindTrigger } from 'material-ui-popup-state';
|
||||
import { useMemo } from 'react';
|
||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||
import { Trackers, TTrackRecord, UNSET_DATE } from '@/lib/data/Trackers.ts';
|
||||
import { ListPreference } from '@/components/sourceConfiguration/ListPreference.tsx';
|
||||
@@ -37,6 +38,7 @@ import { makeToast } from '@/components/util/Toast.tsx';
|
||||
import { Menu } from '@/components/menu/Menu';
|
||||
import { CARD_STYLING } from '@/components/tracker/constants.ts';
|
||||
import { TypographyMaxLines } from '@/components/atoms/TypographyMaxLines.tsx';
|
||||
import { SelectSetting, SelectSettingValue } from '@/components/settings/SelectSetting.tsx';
|
||||
|
||||
const TrackerActiveLink = ({ children, url }: { children: React.ReactNode; url: string }) => (
|
||||
<Link href={url} rel="noreferrer" target="_blank" underline="none" color="inherit">
|
||||
@@ -198,6 +200,8 @@ const TrackerActiveCardInfoRow = ({ children }: { children: React.ReactNode }) =
|
||||
</Stack>
|
||||
);
|
||||
|
||||
const isUnsetScore = (score: string | number): boolean => !Math.trunc(Number(score));
|
||||
|
||||
export const TrackerActiveCard = ({
|
||||
trackRecord: { tracker, ...trackRecord },
|
||||
onClick,
|
||||
@@ -207,6 +211,20 @@ export const TrackerActiveCard = ({
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const isScoreUnset = isUnsetScore(trackRecord.displayScore);
|
||||
const currentScore = isScoreUnset ? tracker.scores[0] : trackRecord.displayScore;
|
||||
|
||||
const selectSettingValues = useMemo(
|
||||
() =>
|
||||
tracker.scores.map(
|
||||
(score) =>
|
||||
[score, { text: isUnsetScore(score) ? '-' : score }] satisfies SelectSettingValue<
|
||||
TTrackRecord['tracker']['scores'][number]
|
||||
>,
|
||||
),
|
||||
[tracker.scores],
|
||||
);
|
||||
|
||||
const updateTrackerBind = (patch: Parameters<typeof requestManager.updateTrackerBind>[1]) => {
|
||||
requestManager
|
||||
.updateTrackerBind(trackRecord.id, patch)
|
||||
@@ -245,25 +263,12 @@ export const TrackerActiveCard = ({
|
||||
handleUpdate={(lastChapterRead) => updateTrackerBind({ lastChapterRead })}
|
||||
/>
|
||||
<Divider orientation="vertical" flexItem />
|
||||
<NumberSetting
|
||||
settingTitle={t('tracking.track_record.label.score')}
|
||||
dialogTitle={t('manga.label.status')}
|
||||
settingValue={trackRecord.displayScore}
|
||||
value={trackRecord.score ?? 0}
|
||||
minValue={0}
|
||||
maxValue={Number(tracker.scores.slice(-1)[0])}
|
||||
stepSize={Number(
|
||||
(Number(tracker.scores[2] ?? 0) - Number(tracker.scores[1] ?? 0)).toFixed(1),
|
||||
)}
|
||||
valueUnit=""
|
||||
handleUpdate={(newScore) =>
|
||||
updateTrackerBind({
|
||||
scoreString:
|
||||
newScore === 0
|
||||
? tracker.scores[0]
|
||||
: tracker.scores.find((score) => Number(score) === newScore),
|
||||
})
|
||||
}
|
||||
<SelectSetting<string>
|
||||
settingName={t('tracking.track_record.label.score')}
|
||||
defaultValue={tracker.scores[0]}
|
||||
value={currentScore}
|
||||
values={selectSettingValues}
|
||||
handleChange={(score) => updateTrackerBind({ scoreString: score })}
|
||||
/>
|
||||
</TrackerActiveCardInfoRow>
|
||||
<Divider />
|
||||
|
||||
@@ -17,7 +17,7 @@ import ListItem from '@mui/material/ListItem';
|
||||
import ListItemIcon from '@mui/material/ListItemIcon';
|
||||
import ListItemText from '@mui/material/ListItemText';
|
||||
import Switch from '@mui/material/Switch';
|
||||
import { Link, ListItemButton, MenuItem, Select } from '@mui/material';
|
||||
import { Link, ListItemButton, MenuItem } from '@mui/material';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import LanguageIcon from '@mui/icons-material/Language';
|
||||
import CollectionsOutlinedBookmarkIcon from '@mui/icons-material/CollectionsBookmarkOutlined';
|
||||
@@ -37,6 +37,7 @@ import { NavBarContext } from '@/components/context/NavbarContext.tsx';
|
||||
import { NumberSetting } from '@/components/settings/NumberSetting.tsx';
|
||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||
import { makeToast } from '@/components/util/Toast.tsx';
|
||||
import { Select } from '@/components/atoms/Select.tsx';
|
||||
|
||||
export function Settings() {
|
||||
const { t, i18n } = useTranslation();
|
||||
@@ -143,7 +144,6 @@ export function Settings() {
|
||||
}
|
||||
/>
|
||||
<Select
|
||||
MenuProps={{ PaperProps: { style: { maxHeight: 150 } } }}
|
||||
value={i18n.language}
|
||||
onChange={({ target: { value: language } }) => i18n.changeLanguage(language)}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user