aboutsummaryrefslogtreecommitdiff
path: root/Timeline/ClientApp/src/user
diff options
context:
space:
mode:
Diffstat (limited to 'Timeline/ClientApp/src/user')
-rw-r--r--Timeline/ClientApp/src/user/ChangeAvatarDialog.tsx11
-rw-r--r--Timeline/ClientApp/src/user/Login.tsx3
-rw-r--r--Timeline/ClientApp/src/user/User.tsx13
-rw-r--r--Timeline/ClientApp/src/user/UserInfoCard.tsx20
-rw-r--r--Timeline/ClientApp/src/user/api.ts5
5 files changed, 27 insertions, 25 deletions
diff --git a/Timeline/ClientApp/src/user/ChangeAvatarDialog.tsx b/Timeline/ClientApp/src/user/ChangeAvatarDialog.tsx
index e082d5a0..f7b25252 100644
--- a/Timeline/ClientApp/src/user/ChangeAvatarDialog.tsx
+++ b/Timeline/ClientApp/src/user/ChangeAvatarDialog.tsx
@@ -11,6 +11,7 @@ import {
import { AxiosError } from 'axios';
import ImageCropper, { Clip, applyClipToImage } from '../common/ImageCropper';
+import { UiLogicError } from '../common';
export interface ChangeAvatarDialogProps {
open: boolean;
@@ -107,11 +108,11 @@ const ChangeAvatarDialog: React.FC<ChangeAvatarDialogProps> = (props) => {
clip.width === 0 ||
file == null
) {
- throw new Error('Invalid state.');
+ throw new UiLogicError();
}
setState('processcrop');
- applyClipToImage(cropImgElement, clip, file.type).then((b) => {
+ void applyClipToImage(cropImgElement, clip, file.type).then((b) => {
setResultBlob(b);
});
}, [cropImgElement, clip, file]);
@@ -130,7 +131,7 @@ const ChangeAvatarDialog: React.FC<ChangeAvatarDialogProps> = (props) => {
const upload = React.useCallback(() => {
if (resultBlob == null) {
- throw new Error('Invalid state.');
+ throw new UiLogicError();
}
setState('uploading');
@@ -147,7 +148,7 @@ const ChangeAvatarDialog: React.FC<ChangeAvatarDialogProps> = (props) => {
const createPreviewRow = (): React.ReactElement => {
if (resultUrl == null) {
- throw new Error('Invalid state.');
+ throw new UiLogicError();
}
return (
<Row className="justify-content-center">
@@ -182,7 +183,7 @@ const ChangeAvatarDialog: React.FC<ChangeAvatarDialogProps> = (props) => {
);
} else if (state === 'crop') {
if (fileUrl == null) {
- throw new Error('Invalid state.');
+ throw new UiLogicError();
}
return (
<>
diff --git a/Timeline/ClientApp/src/user/Login.tsx b/Timeline/ClientApp/src/user/Login.tsx
index fc9364c0..24cd58d0 100644
--- a/Timeline/ClientApp/src/user/Login.tsx
+++ b/Timeline/ClientApp/src/user/Login.tsx
@@ -1,6 +1,7 @@
import React, { Fragment, useState, useEffect } from 'react';
import { useHistory } from 'react-router';
import { useTranslation } from 'react-i18next';
+import { AxiosError } from 'axios';
import AppBar from '../common/AppBar';
@@ -68,7 +69,7 @@ const Login: React.FC = (_) => {
history.goBack();
}
},
- (e) => {
+ (e: AxiosError | Error) => {
setProcess(false);
setError(e.message);
}
diff --git a/Timeline/ClientApp/src/user/User.tsx b/Timeline/ClientApp/src/user/User.tsx
index 7bdd64b7..a281be42 100644
--- a/Timeline/ClientApp/src/user/User.tsx
+++ b/Timeline/ClientApp/src/user/User.tsx
@@ -10,6 +10,7 @@ import ChangeNicknameDialog from './ChangeNicknameDialog';
import ChangeAvatarDialog from './ChangeAvatarDialog';
import TimelinePageTemplate from '../timeline/TimelinePageTemplate';
import { PersonalTimelineManageItem } from './UserInfoCard';
+import { UiLogicError } from '../common';
const User: React.FC = (_) => {
const { username } = useParams<{ username: string }>();
@@ -26,12 +27,16 @@ const User: React.FC = (_) => {
};
if (dialog === 'nickname') {
+ if (user == null) {
+ throw new UiLogicError('Change nickname without login.');
+ }
+
dialogElement = (
<ChangeNicknameDialog
open
close={closeDialogHandler}
onProcess={(newNickname) => {
- const p = changeNickname(user!.token, username, newNickname);
+ const p = changeNickname(user.token, username, newNickname);
return p.then((_) => {
setDataKey(dataKey + 1);
});
@@ -39,11 +44,15 @@ const User: React.FC = (_) => {
/>
);
} else if (dialog === 'avatar') {
+ if (user == null) {
+ throw new UiLogicError('Change avatar without login.');
+ }
+
dialogElement = (
<ChangeAvatarDialog
open
close={closeDialogHandler}
- process={(file) => changeAvatar(user!.token, username, file, file.type)}
+ process={(file) => changeAvatar(user.token, username, file, file.type)}
/>
);
}
diff --git a/Timeline/ClientApp/src/user/UserInfoCard.tsx b/Timeline/ClientApp/src/user/UserInfoCard.tsx
index 280cddce..3f812a8b 100644
--- a/Timeline/ClientApp/src/user/UserInfoCard.tsx
+++ b/Timeline/ClientApp/src/user/UserInfoCard.tsx
@@ -39,6 +39,7 @@ const UserInfoCard: React.FC<UserInfoCardProps> = (props) => {
props.timeline.owner._links.avatar
);
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const containerRef = React.useRef<HTMLDivElement>(null!);
const notifyHeight = React.useCallback((): void => {
@@ -59,17 +60,6 @@ const UserInfoCard: React.FC<UserInfoCardProps> = (props) => {
(): void => setManageDropdownOpen((old) => !old),
[]
);
- const onManageProperty = React.useCallback(
- (): void => onManage!('property'),
- [onManage]
- );
- const onManageAvatar = React.useCallback((): void => onManage!('avatar'), [
- onManage,
- ]);
- const onManageNickname = React.useCallback(
- (): void => onManage!('nickname'),
- [onManage]
- );
return (
<div
@@ -93,19 +83,19 @@ const UserInfoCard: React.FC<UserInfoCardProps> = (props) => {
{t(timelineVisibilityTooltipTranslationMap[props.timeline.visibility])}
</small>
<div className="text-right mt-2">
- {props.onManage != null ? (
+ {onManage != null ? (
<Dropdown isOpen={manageDropdownOpen} toggle={toggleManageDropdown}>
<DropdownToggle outline color="primary">
{t('timeline.manage')}
</DropdownToggle>
<DropdownMenu>
- <DropdownItem onClick={onManageNickname}>
+ <DropdownItem onClick={() => onManage('nickname')}>
{t('timeline.manageItem.nickname')}
</DropdownItem>
- <DropdownItem onClick={onManageAvatar}>
+ <DropdownItem onClick={() => onManage('avatar')}>
{t('timeline.manageItem.avatar')}
</DropdownItem>
- <DropdownItem onClick={onManageProperty}>
+ <DropdownItem onClick={() => onManage('property')}>
{t('timeline.manageItem.property')}
</DropdownItem>
<DropdownItem onClick={props.onMember}>
diff --git a/Timeline/ClientApp/src/user/api.ts b/Timeline/ClientApp/src/user/api.ts
index 184c011f..583370e2 100644
--- a/Timeline/ClientApp/src/user/api.ts
+++ b/Timeline/ClientApp/src/user/api.ts
@@ -60,7 +60,7 @@ export function useOptionalVersionedAvatarUrl(
? undefined
: updateQueryString(
'v',
- avatarVersion == null ? null : avatarVersion + '',
+ avatarVersion == null ? null : avatarVersion.toString(),
url
),
[avatarVersion, url]
@@ -72,7 +72,8 @@ export function useAvatarUrlWithGivenVersion(
url: string
): string {
return React.useMemo(
- () => updateQueryString('v', version == null ? null : version + '', url),
+ () =>
+ updateQueryString('v', version == null ? null : version.toString(), url),
[version, url]
);
}